using Microsoft.Win32;
using Ollama;
using RDTKEditor.AIAssistant;
using RDTKEditor.Models;
using RhythmBase.Components;
using RhythmBase.Events;
using SkiaSharp;
using SkiaSharp.Views.Desktop;
using System.ComponentModel;
using System.Reflection;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;
namespace RDTKEditor
{
///
/// Interaction logic for MainWindow.xaml
///
public partial class MainWindow : Window
{
private readonly Assistant Assistant = new(Assistant.Qwen_3);
private SKSizeI _vsScale = new(1600, 900);
private readonly RDTKView viewModel = new();
private readonly List _selectedEvents = [];
internal readonly Dictionary _eventPanel = [];
public MainWindow()
{
InitializeComponent();
viewModel.Level = RDLevel.Default;
viewModel.Level.Add(new Comment() { Beat = new RDBeat(1,2.33f) });
viewModel.Level.Add(new Comment() { Beat = new RDBeat(1,4f),Y=1 });
foreach (var item in viewModel.Level)
{
var time = item.Beat.BeatOnly;
Label label = new();
label.Content = time;
label.Background = new SolidColorBrush(Colors.Red);
if (time ==1)
{
label.Margin = new Thickness(0, 0, 0, 0);
}else
{
label.Margin = new Thickness(time*10, item.Y*30, 0, 0);
}
timelineCanvas.Children.Add(label);
}
}
private void OpenFile(object sender, RoutedEventArgs e)
{
OpenFileDialog openFileDialog = new()
{
Filter = "关卡文件|*.rdlevel|关卡压缩包 (*.rdzip)|*.rdzip"
};
if (openFileDialog.ShowDialog() == true)
{
string filename = openFileDialog.FileName;
viewModel.UpdateLevelByPath(filename);
}
}
private void SaveFile(object sender, RoutedEventArgs e)
{
OpenFileDialog openFileDialog = new()
{
Filter = "Text files (*.txt)|*.txt|All files (*.*)|*.*"
};
if (openFileDialog.ShowDialog() == true)
{
string filename = openFileDialog.FileName;
viewModel.SaveLevelByPath(filename);
}
}
private void Exit(object sender, RoutedEventArgs e)
{
Application.Current.Shutdown();
}
private void About(object sender, RoutedEventArgs e)
{
if (_selectedEvents.Count == 0)
{
MessageBox.Show("请先选择一个事件。", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
return;
}
if (_selectedEvents.Count == 1)
{
OnUpdateEventProperties(_selectedEvents[0], GetProperties(_selectedEvents[0]));
}
else
{
}
private RDTKProperty[] GetProperties(BaseEvent e)
{
return [
new RDTKProperty()
{
Verifier = new RDTKPropertyVerifierDefault(),
Name = "类型",
Value = e.Type.ToString(),
Type = RDPropertyType.String,
},
..e.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance).Select(p => GetProperty(p,e)).ToArray()
];
}
private RDTKProperty GetProperty(PropertyInfo property, object obj)
{
switch (property.PropertyType.Name)
{
case "Boolean":
return new()
{
Verifier = new RDTKPropertyVerifierBool(),
Name = property.Name,
Value = property.GetValue(obj)?.ToString() ?? "false",
Type = RDPropertyType.Bool,
};
case "Enum":
return new()
{
Verifier = new RDTKPropertyVerifierEnum(property.PropertyType),
Name = property.Name,
Value = property.GetValue(obj)?.ToString() ?? "null",
Type = RDPropertyType.Enum,
};
case "String":
return new()
{
Verifier = new RDTKPropertyVerifierDefault(),
Name = property.Name,
Value = property.GetValue(obj)?.ToString() ?? "null",
Type = RDPropertyType.String,
};
case "Int32":
return new()
{
Verifier = new RDTKPropertyVerifierDefault(),
Name = property.Name,
Value = property.GetValue(obj)?.ToString() ?? "null",
Type = RDPropertyType.Integer,
};
case "Single":
return new()
{
Verifier = new RDTKPropertyVerifierDefault(),
Name = property.Name,
Value = property.GetValue(obj)?.ToString() ?? "null",
Type = RDPropertyType.Float,
};
case "RDColor":
return new()
{
Verifier = new RDTKPropertyVerifierDefault(),
Name = property.Name,
Value = property.GetValue(obj)?.ToString() ?? "null",
Type = RDPropertyType.Color,
};
}
return new()
{
Verifier = new RDTKPropertyVerifierDefault(),
Name = property.Name,
Value = property.GetValue(obj)?.ToString() ?? "null",
Type = RDPropertyType.String,
};
}
private readonly List selectedEvents = new();
internal void OnUpdateEventProperties(RDTKProperty[] properties)
{
ItemProperties.Items.Clear();
StackPanel[] panel = new StackPanel[properties.Length];
if (_eventPanel.ContainsKey(baseEvent.GetType()))
{
}
else
{
foreach (var property in properties)
{
StackPanel stackPanel = property.Type switch
{
RDPropertyType.Bool => new()
{
Orientation = Orientation.Horizontal,
FlowDirection = FlowDirection.LeftToRight,
Children =
{
new Label(){Content = property.Name},
new CheckBox() { IsChecked = bool.Parse( property.Value), }
},
},
RDPropertyType.Enum => new()
{
AllowDrop = true,
Orientation = Orientation.Horizontal,
FlowDirection = FlowDirection.LeftToRight,
Children =
{
new Label(){Content = property.Name},
new ComboBox()
{
ItemsSource = Enum.GetValues(((RDTKPropertyVerifierEnum)property.Verifier).EnumType),
SelectedValue = property.Value,
}
},
},
RDPropertyType.String => new()
{
AllowDrop = true,
Orientation = Orientation.Horizontal,
FlowDirection = FlowDirection.LeftToRight,
Children =
{
new Label(){Content = property.Name},
new TextBox() { Text = property.Value, }
},
},
RDPropertyType.Integer => new()
{
AllowDrop = true,
Orientation = Orientation.Horizontal,
FlowDirection = FlowDirection.LeftToRight,
Children =
{
new Label(){Content = property.Name},
new TextBox() { Text = property.Value, }
},
},
RDPropertyType.Float => new()
{
AllowDrop = true,
Orientation = Orientation.Horizontal,
FlowDirection = FlowDirection.LeftToRight,
Children =
{
new Label(){Content = property.Name},
new TextBox() { Text = property.Value, }
},
},
RDPropertyType.Color => new()
{
AllowDrop = true,
Orientation = Orientation.Horizontal,
FlowDirection = FlowDirection.LeftToRight,
Children =
{
new Label(){Content = property.Name},
new TextBox() { Text = property.Value, }
},
},
_ => new()
{
Orientation = Orientation.Horizontal,
Children =
{
new Label(){Content = property.Name},
new TextBox() { Text = property.Value, }
},
},
RDPropertyType.Color => new()
{
AllowDrop = true,
Orientation = Orientation.Horizontal,
FlowDirection = FlowDirection.LeftToRight,
Children =
{
new Label(){Content = property.Name},
new TextBox() { Text = property.Value, }
},
},
_ => new()
{
Orientation = Orientation.Horizontal,
Children =
{
new Label(){Content = property.Name},
new Label(){Content = property.Value}
}
},
};
foreach (var child in stackPanel.Children)
{
switch (child)
{
case CheckBox checkBox:
checkBox.Checked += (sender, e) =>
{
property.OnChanged("true");
};
checkBox.Unchecked += (sender, e) =>
{
property.OnChanged("false");
};
break;
case TextBox textBox:
textBox.TextChanged += (sender, e) =>
{
property.OnChanged(textBox.Text);
};
break;
case ComboBox comboBox:
comboBox.SelectionChanged += (sender, e) =>
{
property.OnChanged(comboBox.SelectedValue);
};
break;
default:
break;
}
}
ItemProperties.Items.Add(stackPanel);
property.PropertyChanged += (e, s) => UpdateEvent();
}
}
}
private void UpdateEvent()
{
if (_selectedEvents.Count == 0)
return;
else if (_selectedEvents.Count == 1){
var e = _selectedEvents[0];
foreach (var property in ItemProperties.Items)
{
if (property is StackPanel stackPanel)
{
foreach (var child in stackPanel.Children)
{
switch (child)
{
case CheckBox checkBox:
e.GetType().GetProperty(stackPanel.Name)?.SetValue(e, checkBox.IsChecked);
break;
case TextBox textBox:
e.GetType().GetProperty(stackPanel.Name)?.SetValue(e, textBox.Text);
break;
case ComboBox comboBox:
e.GetType().GetProperty(stackPanel.Name)?.SetValue(e, comboBox.SelectedValue);
break;
default:
break;
}
}
}
}
}
else
{
}
}
private void UpdateTimeLine()
{
Rectangle rectangle = new()
{
Width = 100,
Height = 100,
};
timelineCanvas.Children.Add(rectangle);
}
/*private void mainUI_PaintSurface(object sender, SkiaSharp.Views.Desktop.SKPaintSurfaceEventArgs e)
{
var sfc = e.Surface;
var cvs = sfc.Canvas;
cvs.Clear(SKColors.Black);
cvs.DrawLine(0, 0, 1600, 900, new()
{
Color = SKColors.Red,
});
}*/
private void mainUI_PaintSurface(object sender, SKPaintSurfaceEventArgs e)
{
var sfc = e.Surface;
var cvs = sfc.Canvas;
var info = e.Info;
cvs.Clear(SKColors.Black);
SKPoint scale = new((float)info.Width / _vsScale.Width, (float)info.Height / _vsScale.Height);
cvs.Save();
cvs.Scale(scale);
Draw(cvs);
cvs.Restore();
}
private void Draw(SKCanvas canvas)
{
// 以 1600x900 为基准绘制
canvas.DrawLine(0, 0, _vsScale.Width, _vsScale.Height, new SKPaint
{
Color = SKColors.Red,
StrokeWidth = 3,
IsStroke = true,
});
canvas.DrawLine(0, _vsScale.Height, _vsScale.Width, 0, new SKPaint
{
Color = SKColors.White,
StrokeWidth = 3,
IsStroke = true,
});
}
private void CheckBox_Checked(object sender, RoutedEventArgs e)
{
MessageBox.Show("已确认");
}
private async void AIAssistantButton_Click(object sender, RoutedEventArgs e)
{
string input = AIAssistantText.Text;
if (string.IsNullOrEmpty(input))
return;
Message responce = await Assistant.Chat.SendAsync(input);
AIAssistantText.Text = responce.Content;
}
}
public class MainViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler? PropertyChanged;
private bool _isButtonEnabled = true;
public bool IsButtonEnabled
{
get => _isButtonEnabled;
set
{
_isButtonEnabled = value;
}
}
}
}