diff --git a/HaRepacker/Converter/BooleanToVisibilityConverter.cs b/HaRepacker/Converter/BooleanToVisibilityConverter.cs new file mode 100644 index 00000000..37434229 --- /dev/null +++ b/HaRepacker/Converter/BooleanToVisibilityConverter.cs @@ -0,0 +1,34 @@ +using HaRepacker.GUI.Controls; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Data; +using System.Windows; + +namespace HaRepacker.Converter { + + /// + /// Boolean to System.Windows.Visiblity converter. + /// If true, return Visiblity.Collapsed + /// otherelse return Visibility.Visible + /// + public class BooleanToVisibilityConverter : IValueConverter { + + public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { + bool res = (bool)value; + + if (res) + return Visibility.Collapsed; + + return Visibility.Visible; + } + + public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { + Visibility visibility = (Visibility)value; + + return visibility == Visibility.Collapsed ? true: false; + } + } +} diff --git a/HaRepacker/GUI/OptionsForm.Designer.cs b/HaRepacker/GUI/OptionsForm.Designer.cs index 8ac69513..499a004f 100644 --- a/HaRepacker/GUI/OptionsForm.Designer.cs +++ b/HaRepacker/GUI/OptionsForm.Designer.cs @@ -46,14 +46,8 @@ private void InitializeComponent() this.themeColor__comboBox = new System.Windows.Forms.ComboBox(); this.label3 = new System.Windows.Forms.Label(); this.panel1 = new System.Windows.Forms.Panel(); - this.panel2 = new System.Windows.Forms.Panel(); - this.label4 = new System.Windows.Forms.Label(); this.label5 = new System.Windows.Forms.Label(); - this.openAI_apiKey_textBox = new System.Windows.Forms.TextBox(); - this.label6 = new System.Windows.Forms.Label(); - this.linkLabel1 = new System.Windows.Forms.LinkLabel(); this.panel1.SuspendLayout(); - this.panel2.SuspendLayout(); this.SuspendLayout(); // // sortBox @@ -166,47 +160,15 @@ private void InitializeComponent() resources.ApplyResources(this.panel1, "panel1"); this.panel1.Name = "panel1"; // - // panel2 - // - this.panel2.Controls.Add(this.linkLabel1); - this.panel2.Controls.Add(this.label6); - this.panel2.Controls.Add(this.openAI_apiKey_textBox); - this.panel2.Controls.Add(this.label4); - resources.ApplyResources(this.panel2, "panel2"); - this.panel2.Name = "panel2"; - // - // label4 - // - resources.ApplyResources(this.label4, "label4"); - this.label4.Name = "label4"; - // // label5 // resources.ApplyResources(this.label5, "label5"); this.label5.Name = "label5"; // - // openAI_apiKey_textBox - // - resources.ApplyResources(this.openAI_apiKey_textBox, "openAI_apiKey_textBox"); - this.openAI_apiKey_textBox.Name = "openAI_apiKey_textBox"; - // - // label6 - // - resources.ApplyResources(this.label6, "label6"); - this.label6.Name = "label6"; - // - // linkLabel1 - // - resources.ApplyResources(this.linkLabel1, "linkLabel1"); - this.linkLabel1.Name = "linkLabel1"; - this.linkLabel1.TabStop = true; - this.linkLabel1.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabel1_LinkClicked); - // // OptionsForm // resources.ApplyResources(this, "$this"); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.Controls.Add(this.panel2); this.Controls.Add(this.panel1); this.Controls.Add(this.cancelButton); this.Controls.Add(this.okButton); @@ -214,8 +176,6 @@ private void InitializeComponent() this.Name = "OptionsForm"; this.panel1.ResumeLayout(false); this.panel1.PerformLayout(); - this.panel2.ResumeLayout(false); - this.panel2.PerformLayout(); this.ResumeLayout(false); } @@ -239,10 +199,5 @@ private void InitializeComponent() private System.Windows.Forms.Label label3; private System.Windows.Forms.Panel panel1; private System.Windows.Forms.Label label5; - private System.Windows.Forms.Panel panel2; - private System.Windows.Forms.LinkLabel linkLabel1; - private System.Windows.Forms.Label label6; - private System.Windows.Forms.TextBox openAI_apiKey_textBox; - private System.Windows.Forms.Label label4; } } \ No newline at end of file diff --git a/HaRepacker/GUI/OptionsForm.cs b/HaRepacker/GUI/OptionsForm.cs index 9269b90b..5cdfe207 100644 --- a/HaRepacker/GUI/OptionsForm.cs +++ b/HaRepacker/GUI/OptionsForm.cs @@ -32,9 +32,6 @@ public OptionsForm() // Theme color themeColor__comboBox.SelectedIndex = Program.ConfigurationManager.UserSettings.ThemeColor; - - // API Key - openAI_apiKey_textBox.Text = Program.ConfigurationManager.ApplicationSettings.OpenAI_ApiKey; } @@ -80,9 +77,6 @@ private void okButton_Click(object sender, EventArgs e) Program.ConfigurationManager.UserSettings.LineBreakType = (LineBreak)lineBreakBox.SelectedIndex; Program.ConfigurationManager.UserSettings.ThemeColor = themeColor__comboBox.SelectedIndex; - // APi key - Program.ConfigurationManager.ApplicationSettings.OpenAI_ApiKey = openAI_apiKey_textBox.Text; - Program.ConfigurationManager.Save(); Close(); } diff --git a/HaRepacker/GUI/OptionsForm.resx b/HaRepacker/GUI/OptionsForm.resx index cd446233..92d827cb 100644 --- a/HaRepacker/GUI/OptionsForm.resx +++ b/HaRepacker/GUI/OptionsForm.resx @@ -160,7 +160,7 @@ 19 - Autoload related Wz (Map.wz, Map001.wz, Map002.wz) + Auto-load related Wz (Map.wz, Map001.wz, Map002.wz) loadRelated @@ -175,7 +175,7 @@ 6 - 4, 399 + 2, 289 157, 33 @@ -196,10 +196,10 @@ $this - 3 + 2 - 163, 399 + 161, 289 157, 33 @@ -220,7 +220,7 @@ $this - 2 + 1 True @@ -550,135 +550,6 @@ $this - 1 - - - NoControl - - - 42, 48 - - - 243, 18 - - - 0 - - - https://platform.openai.com/account/api-keys - - - linkLabel1 - - - System.Windows.Forms.LinkLabel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - panel2 - - - 0 - - - True - - - NoControl - - - 6, 26 - - - 85, 13 - - - 21 - - - OpenAI API key - - - label6 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - panel2 - - - 1 - - - 97, 23 - - - 214, 22 - - - 1 - - - openAI_apiKey_textBox - - - System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - panel2 - - - 2 - - - Segoe UI, 9.75pt, style=Bold - - - NoControl - - - 3, 3 - - - 38, 13 - - - 0 - - - AI - - - label4 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - panel2 - - - 3 - - - 0, 292 - - - 323, 75 - - - 21 - - - panel2 - - - System.Windows.Forms.Panel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - 0 @@ -688,14 +559,11 @@ 6, 13 - 323, 435 + 323, 327 Segoe UI, 8pt - - NoControl - CenterParent diff --git a/HaRepacker/GUI/Panels/MainPanel.xaml b/HaRepacker/GUI/Panels/MainPanel.xaml index ac2c012a..43a69d82 100644 --- a/HaRepacker/GUI/Panels/MainPanel.xaml +++ b/HaRepacker/GUI/Panels/MainPanel.xaml @@ -3,15 +3,20 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:sys="clr-namespace:System;assembly=mscorlib" + + xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms" + xmlns:local="clr-namespace:HaRepacker" - + xmlns:converter="clr-namespace:HaRepacker.Converter" xmlns:sharedLib="clr-namespace:HaSharedLibrary.GUI;assembly=HaSharedLibrary" + xmlns:guiControls="clr-namespace:HaRepacker.GUI.Controls" xmlns:localgui ="clr-namespace:HaRepacker.GUI" xmlns:localSubPanels ="clr-namespace:HaRepacker.GUI.Panels.SubPanels" - xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms" + + xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit" mc:Ignorable="d" - d:DesignHeight="661" d:DesignWidth="1599"> @@ -61,6 +66,8 @@ + + + + + + @@ -141,6 +176,7 @@ + @@ -226,13 +262,12 @@ - - + @@ -241,30 +276,26 @@ - - - - - + - + - + - + - + - + - + @@ -281,6 +312,7 @@ + @@ -292,8 +324,32 @@ DoubleClick="DataTree_DoubleClick"/> + + + + + + + + + + + + + + + + - @@ -338,7 +394,6 @@ - @@ -346,15 +401,7 @@ - - - - - - + @@ -363,8 +410,6 @@ - - @@ -431,7 +476,4 @@ - - - diff --git a/HaRepacker/GUI/Panels/MainPanel.xaml.cs b/HaRepacker/GUI/Panels/MainPanel.xaml.cs index 3f4a5044..27efbd6a 100644 --- a/HaRepacker/GUI/Panels/MainPanel.xaml.cs +++ b/HaRepacker/GUI/Panels/MainPanel.xaml.cs @@ -35,6 +35,10 @@ using System.Net; using HaRepacker.GUI.Panels.SubPanels; using HaRepacker.GUI.Controls; +using Newtonsoft.Json.Linq; +using Xceed.Wpf.Toolkit.Core; +using System.Diagnostics; +using Microsoft.Xna.Framework.Graphics; namespace HaRepacker.GUI.Panels { @@ -54,6 +58,12 @@ public MainForm MainForm get { return _mainForm; } private set { } } + + // Data binding + private MainPanelPropertyItems _bindingPropertyItem = new MainPanelPropertyItems(); + //private MainPanelPropertyItemInterface _bindingPropertyItemReadOnly = new MainPanelPropertyItems_ReadOnly(); + + // Etc private readonly static List clipboard = new List(); private readonly UndoRedoManager undoRedoMan; @@ -90,14 +100,9 @@ public MainPanel(MainForm mainForm) DataTree.ForeColor = System.Drawing.Color.White; } - nameBox.Header = "Name"; - textPropBox.Header = "Value"; - textPropBox.ButtonClicked += applyChangesButton_Click; - - vectorPanel.ButtonClicked += VectorPanel_ButtonClicked; - - textPropBox.Visibility = Visibility.Collapsed; - //nameBox.Visibility = Visibility.Collapsed; + // data binding stuff + propertyGrid.DataContext = _bindingPropertyItem; + _bindingPropertyItem.PropertyChanged += propertyGrid_PropertyChanged_1; // Storyboard System.Windows.Media.Animation.Storyboard sbb = (System.Windows.Media.Animation.Storyboard)(this.FindResource("Storyboard_Find_FadeIn")); @@ -120,8 +125,8 @@ public MainPanel(MainForm mainForm) private void MainPanelXAML_Loaded(object sender, RoutedEventArgs e) { - this.fieldLimitPanel1.SetTextboxOnFieldLimitChange(textPropBox); - this.fieldTypePanel.SetTextboxOnFieldTypeChange(textPropBox); + this.fieldLimitPanel1.FieldLimitChanged += FieldLimitPanel1_FieldLimitChanged; + //this.fieldTypePanel.SetTextboxOnFieldTypeChange(textPropBox); } #region Exported Fields @@ -144,9 +149,10 @@ private void DataTree_AfterSelect(object sender, System.Windows.Forms.TreeViewEv { return; } - ShowObjectValue((WzObject)DataTree.SelectedNode.Tag); - selectionLabel.Text = string.Format(Properties.Resources.SelectionType, ((WzNode)DataTree.SelectedNode).GetTypeName()); + + _bindingPropertyItem.WzFileType = ((WzNode)DataTree.SelectedNode).GetTypeName(); + //selectionLabel.Text = string.Format(Properties.Resources.SelectionType, ((WzNode)DataTree.SelectedNode).GetTypeName()); } /// @@ -702,124 +708,6 @@ private void nextLoopTime_comboBox_SelectedIndexChanged(object sender, EventArgs #endregion #region Buttons - private void nameBox_ButtonClicked(object sender, EventArgs e) - { - if (DataTree.SelectedNode == null) return; - if (DataTree.SelectedNode.Tag is WzFile) - { - ((WzFile)DataTree.SelectedNode.Tag).Header.Copyright = nameBox.Text; - ((WzFile)DataTree.SelectedNode.Tag).Header.RecalculateFileStart(); - } - else if (WzNode.CanNodeBeInserted((WzNode)DataTree.SelectedNode.Parent, nameBox.Text)) - { - string text = nameBox.Text; - ((WzNode)DataTree.SelectedNode).ChangeName(text); - nameBox.Text = text; - nameBox.ApplyButtonEnabled = false; - } - else - Warning.Error(Properties.Resources.MainNodeExists); - - } - - /// - /// On vector panel 'apply' button clicked - /// - /// - /// - private void VectorPanel_ButtonClicked(object sender, EventArgs e) - { - applyChangesButton_Click(null, null); - } - - private void applyChangesButton_Click(object sender, EventArgs e) - { - if (DataTree.SelectedNode == null) - return; - - string setText = textPropBox.Text; - - WzObject obj = (WzObject)DataTree.SelectedNode.Tag; - if (obj is WzImageProperty imageProperty) - { - imageProperty.ParentImage.Changed = true; - } - - if (obj is WzVectorProperty vectorProperty) - { - vectorProperty.X.Value = vectorPanel.X; - vectorProperty.Y.Value = vectorPanel.Y; - } - else if (obj is WzStringProperty stringProperty) - { - if (!stringProperty.IsSpineAtlasResources) - { - stringProperty.Value = setText; - } else - { - throw new NotSupportedException("Usage of textBoxProp for spine WzStringProperty."); - } - } - else if (obj is WzFloatProperty floatProperty) - { - float val; - if (!float.TryParse(setText, out val)) - { - Warning.Error(string.Format(Properties.Resources.MainConversionError, setText)); - return; - } - floatProperty.Value = val; - } - else if (obj is WzIntProperty intProperty) - { - int val; - if (!int.TryParse(setText, out val)) - { - Warning.Error(string.Format(Properties.Resources.MainConversionError, setText)); - return; - } - intProperty.Value = val; - } - else if (obj is WzLongProperty longProperty) - { - long val; - if (!long.TryParse(setText, out val)) - { - Warning.Error(string.Format(Properties.Resources.MainConversionError, setText)); - return; - } - longProperty.Value = val; - } - else if (obj is WzDoubleProperty doubleProperty) - { - double val; - if (!double.TryParse(setText, out val)) - { - Warning.Error(string.Format(Properties.Resources.MainConversionError, setText)); - return; - } - doubleProperty.Value = val; - } - else if (obj is WzShortProperty shortProperty) - { - short val; - if (!short.TryParse(setText, out val)) - { - Warning.Error(string.Format(Properties.Resources.MainConversionError, setText)); - return; - } - shortProperty.Value = val; - } - else if (obj is WzUOLProperty UOLProperty) - { - UOLProperty.Value = setText; - } - else if (obj is WzLuaProperty) - { - throw new NotSupportedException("Moved to TextEditor_SaveButtonClicked()"); - } - } - /// /// On texteditor save button clicked /// @@ -830,12 +718,16 @@ private void TextEditor_SaveButtonClicked(object sender, EventArgs e) if (DataTree.SelectedNode == null) return; + WzNode node = (WzNode)DataTree.SelectedNode; WzObject obj = (WzObject)DataTree.SelectedNode.Tag; if (obj is WzLuaProperty luaProp) { string setText = textEditor.textEditor.Text; byte[] encBytes = luaProp.EncodeDecode(Encoding.ASCII.GetBytes(setText)); luaProp.Value = encBytes; + + // highlight node to the user + node.ChangedNodeProperty(); } else if (obj is WzStringProperty stringProp) { @@ -844,167 +736,17 @@ private void TextEditor_SaveButtonClicked(object sender, EventArgs e) string setText = textEditor.textEditor.Text; stringProp.Value = setText; - /* } - else - { - throw new NotSupportedException("Usage of TextEditor for non-spine WzStringProperty."); - }*/ - } - } - - /// - /// More option -- Shows ContextMenuStrip - /// - /// - /// - private void button_MoreOption_Click(object sender, RoutedEventArgs e) - { - Button clickSrc = (Button)sender; - - clickSrc.ContextMenu.IsOpen = true; - // System.Windows.Forms.ContextMenuStrip contextMenu = new System.Windows.Forms.ContextMenuStrip(); - // contextMenu.Show(clickSrc, 0, 0); - } - - /// - /// Menu item for animation. Appears when clicking on the "..." button - /// - /// - /// - private void MenuItem_Animate_Click(object sender, RoutedEventArgs e) - { - StartAnimateSelectedCanvas(); - } - - /// - /// Save the image animation into a JPG file - /// - /// - /// - private void MenuItem_saveImageAnimation_Click(object sender, RoutedEventArgs e) - { - WzObject seletedWzObject = (WzObject)DataTree.SelectedNode.Tag; - - if (!AnimationBuilder.IsValidAnimationWzObject(seletedWzObject)) - return; - - // Check executing process architecture - /*AssemblyName executingAssemblyName = Assembly.GetExecutingAssembly().GetName(); - var assemblyArchitecture = executingAssemblyName.ProcessorArchitecture; - if (assemblyArchitecture == ProcessorArchitecture.None) - { - System.Windows.Forms.MessageBox.Show(HaRepacker.Properties.Resources.ExecutingAssemblyError, HaRepacker.Properties.Resources.Warning, System.Windows.Forms.MessageBoxButtons.OK); - return; - }*/ - - System.Windows.Forms.SaveFileDialog dialog = new System.Windows.Forms.SaveFileDialog() - { - Title = HaRepacker.Properties.Resources.SelectOutApng, - Filter = string.Format("{0}|*.png", HaRepacker.Properties.Resources.ApngFilter) - }; - if (dialog.ShowDialog() != System.Windows.Forms.DialogResult.OK) - return; - - AnimationBuilder.ExtractAnimation((WzSubProperty)seletedWzObject, dialog.FileName, Program.ConfigurationManager.UserSettings.UseApngIncompatibilityFrame); - } - /// - /// - /// - /// - /// - private void MenuItem_changeImage_Click(object sender, RoutedEventArgs e) - { - if (DataTree.SelectedNode.Tag is WzCanvasProperty) // only allow button click if its an image property - { - System.Windows.Forms.OpenFileDialog dialog = new System.Windows.Forms.OpenFileDialog() - { - Title = "Select an image", - Filter = "Supported Image Formats (*.png;*.bmp;*.jpg;*.gif;*.jpeg;*.tif;*.tiff)|*.png;*.bmp;*.jpg;*.gif;*.jpeg;*.tif;*.tiff" - }; - if (dialog.ShowDialog() != System.Windows.Forms.DialogResult.OK) - return; - - byte[] bitmapBytes = null; - try { - using (System.Drawing.Bitmap originalBitmap = new System.Drawing.Bitmap(dialog.FileName)) { - using (MemoryStream ms = new MemoryStream()) { - originalBitmap.Save(ms, originalBitmap.RawFormat); - bitmapBytes = ms.ToArray(); - } - } - } - catch { - Warning.Error(Properties.Resources.MainImageLoadError); - return; - } - //List actions = new List(); // Undo action - - if (bitmapBytes != null) { - MemoryStream ms = new MemoryStream(bitmapBytes); // dont close this - System.Drawing.Bitmap newBitmap = new System.Drawing.Bitmap(ms); - - ChangeCanvasPropBoxImage(newBitmap); - } - } - } - - /// - /// Changes the displayed image in 'canvasPropBox' with a user defined input. - /// - /// - /// - public void ChangeCanvasPropBoxImage(Bitmap bmp) - { - if (DataTree.SelectedNode.Tag is WzCanvasProperty property) - { - WzNode parentCanvasNode = (WzNode)DataTree.SelectedNode; - - WzCanvasProperty selectedWzCanvas = property; - - if (selectedWzCanvas.ContainsInlinkProperty()) // if its an inlink property, remove that before updating base image. - { - selectedWzCanvas.RemoveProperty(selectedWzCanvas[WzCanvasProperty.InlinkPropertyName]); - - WzNode childInlinkNode = WzNode.GetChildNode(parentCanvasNode, WzCanvasProperty.InlinkPropertyName); - - // Add undo actions - //actions.Add(UndoRedoManager.ObjectRemoved((WzNode)parentCanvasNode, childInlinkNode)); - childInlinkNode.DeleteWzNode(); // Delete '_inlink' node - - // TODO: changing _Inlink image crashes - // Mob2.wz/9400121/hit/0 - } - else if (selectedWzCanvas.ContainsOutlinkProperty()) // if its an inlink property, remove that before updating base image. - { - selectedWzCanvas.RemoveProperty(selectedWzCanvas[WzCanvasProperty.OutlinkPropertyName]); - - WzNode childInlinkNode = WzNode.GetChildNode(parentCanvasNode, WzCanvasProperty.OutlinkPropertyName); - - // Add undo actions - //actions.Add(UndoRedoManager.ObjectRemoved((WzNode)parentCanvasNode, childInlinkNode)); - childInlinkNode.DeleteWzNode(); // Delete '_inlink' node - } - - selectedWzCanvas.PngProperty.SetImage(bmp); - - canvasPropBox.SetIsLoading(true); - try { - canvasPropBox.BindingPropertyItem.Bitmap = bmp; - canvasPropBox.BindingPropertyItem.BitmapBackup = bmp; - } - finally { - canvasPropBox.SetIsLoading(false); - } - - // flag changed for saving updates - // and also node foreground color - parentCanvasNode.ChangedNodeProperty(); - - // Add undo actions - //UndoRedoMan.AddUndoBatch(actions); + // highlight node to the user + node.ChangedNodeProperty(); + /* } + else + { + throw new NotSupportedException("Usage of TextEditor for non-spine WzStringProperty."); + }*/ } } + #endregion #region Batch Edit /// @@ -1325,6 +1067,20 @@ private void UpscaleImageNodesRecursively(WzNode node, Dictionary + /// More option -- Shows ContextMenuStrip + /// + /// + /// + private void button_MoreOption_Click(object sender, RoutedEventArgs e) { + Button clickSrc = (Button)sender; + + clickSrc.ContextMenu.IsOpen = true; + // System.Windows.Forms.ContextMenuStrip contextMenu = new System.Windows.Forms.ContextMenuStrip(); + // contextMenu.Show(clickSrc, 0, 0); + } + /// /// /// @@ -1484,38 +1240,171 @@ private void menuItem_ExportFile_Click(object sender, RoutedEventArgs e) } } } - #endregion - #region Drag and Drop Image - private bool bDragEnterActive = false; /// - /// Scroll viewer drag enter + /// Menu item for animation. Appears when clicking on the "..." button /// /// /// - private void canvasPropBox_DragEnter(object sender, DragEventArgs e) - { - System.Diagnostics.Debug.WriteLine("Drag Enter"); - if (!bDragEnterActive) - { - bDragEnterActive = true; - } + private void MenuItem_Animate_Click(object sender, RoutedEventArgs e) { + StartAnimateSelectedCanvas(); } /// - /// Scroll viewer drag leave + /// Save the image animation into a JPG file /// /// /// - private void canvasPropBox_DragLeave(object sender, DragEventArgs e) - { - System.Diagnostics.Debug.WriteLine("Drag Leave"); + private void MenuItem_saveImageAnimation_Click(object sender, RoutedEventArgs e) { + WzObject seletedWzObject = (WzObject)DataTree.SelectedNode.Tag; - bDragEnterActive = false; - } - /// - /// Scroll viewer drag drop - /// + if (!AnimationBuilder.IsValidAnimationWzObject(seletedWzObject)) + return; + + // Check executing process architecture + /*AssemblyName executingAssemblyName = Assembly.GetExecutingAssembly().GetName(); + var assemblyArchitecture = executingAssemblyName.ProcessorArchitecture; + if (assemblyArchitecture == ProcessorArchitecture.None) + { + System.Windows.Forms.MessageBox.Show(HaRepacker.Properties.Resources.ExecutingAssemblyError, HaRepacker.Properties.Resources.Warning, System.Windows.Forms.MessageBoxButtons.OK); + return; + }*/ + + System.Windows.Forms.SaveFileDialog dialog = new System.Windows.Forms.SaveFileDialog() { + Title = HaRepacker.Properties.Resources.SelectOutApng, + Filter = string.Format("{0}|*.png", HaRepacker.Properties.Resources.ApngFilter) + }; + if (dialog.ShowDialog() != System.Windows.Forms.DialogResult.OK) + return; + + AnimationBuilder.ExtractAnimation((WzSubProperty)seletedWzObject, dialog.FileName, Program.ConfigurationManager.UserSettings.UseApngIncompatibilityFrame); + } + + /// + /// + /// + /// + /// + private void MenuItem_changeImage_Click(object sender, RoutedEventArgs e) { + if (DataTree.SelectedNode.Tag is WzCanvasProperty) // only allow button click if its an image property + { + System.Windows.Forms.OpenFileDialog dialog = new System.Windows.Forms.OpenFileDialog() { + Title = "Select an image", + Filter = "Supported Image Formats (*.png;*.bmp;*.jpg;*.gif;*.jpeg;*.tif;*.tiff)|*.png;*.bmp;*.jpg;*.gif;*.jpeg;*.tif;*.tiff" + }; + if (dialog.ShowDialog() != System.Windows.Forms.DialogResult.OK) + return; + + byte[] bitmapBytes = null; + try { + using (System.Drawing.Bitmap originalBitmap = new System.Drawing.Bitmap(dialog.FileName)) { + using (MemoryStream ms = new MemoryStream()) { + originalBitmap.Save(ms, originalBitmap.RawFormat); + bitmapBytes = ms.ToArray(); + } + } + } + catch { + Warning.Error(Properties.Resources.MainImageLoadError); + return; + } + //List actions = new List(); // Undo action + + if (bitmapBytes != null) { + MemoryStream ms = new MemoryStream(bitmapBytes); // dont close this + System.Drawing.Bitmap newBitmap = new System.Drawing.Bitmap(ms); + + ChangeCanvasPropBoxImage(newBitmap); + } + } + } + + /// + /// Changes the displayed image in 'canvasPropBox' with a user defined input. + /// + /// + /// + public void ChangeCanvasPropBoxImage(Bitmap bmp) { + if (DataTree.SelectedNode.Tag is WzCanvasProperty property) { + WzNode parentCanvasNode = (WzNode)DataTree.SelectedNode; + + WzCanvasProperty selectedWzCanvas = property; + + if (selectedWzCanvas.ContainsInlinkProperty()) // if its an inlink property, remove that before updating base image. + { + selectedWzCanvas.RemoveProperty(selectedWzCanvas[WzCanvasProperty.InlinkPropertyName]); + + WzNode childInlinkNode = WzNode.GetChildNode(parentCanvasNode, WzCanvasProperty.InlinkPropertyName); + + // Add undo actions + //actions.Add(UndoRedoManager.ObjectRemoved((WzNode)parentCanvasNode, childInlinkNode)); + childInlinkNode.DeleteWzNode(); // Delete '_inlink' node + + // TODO: changing _Inlink image crashes + // Mob2.wz/9400121/hit/0 + } + else if (selectedWzCanvas.ContainsOutlinkProperty()) // if its an inlink property, remove that before updating base image. + { + selectedWzCanvas.RemoveProperty(selectedWzCanvas[WzCanvasProperty.OutlinkPropertyName]); + + WzNode childInlinkNode = WzNode.GetChildNode(parentCanvasNode, WzCanvasProperty.OutlinkPropertyName); + + // Add undo actions + //actions.Add(UndoRedoManager.ObjectRemoved((WzNode)parentCanvasNode, childInlinkNode)); + childInlinkNode.DeleteWzNode(); // Delete '_inlink' node + } + + selectedWzCanvas.PngProperty.SetImage(bmp); + + canvasPropBox.SetIsLoading(true); + try { + canvasPropBox.BindingPropertyItem.Bitmap = bmp; + canvasPropBox.BindingPropertyItem.BitmapBackup = bmp; + } + finally { + canvasPropBox.SetIsLoading(false); + } + + // flag changed for saving updates + // and also node foreground color + parentCanvasNode.ChangedNodeProperty(); + + // Add undo actions + //UndoRedoMan.AddUndoBatch(actions); + } + } + #endregion + + #region Drag and Drop Image + private bool bDragEnterActive = false; + /// + /// Scroll viewer drag enter + /// + /// + /// + private void canvasPropBox_DragEnter(object sender, DragEventArgs e) + { + System.Diagnostics.Debug.WriteLine("Drag Enter"); + if (!bDragEnterActive) + { + bDragEnterActive = true; + } + } + + /// + /// Scroll viewer drag leave + /// + /// + /// + private void canvasPropBox_DragLeave(object sender, DragEventArgs e) + { + System.Diagnostics.Debug.WriteLine("Drag Leave"); + + bDragEnterActive = false; + } + /// + /// Scroll viewer drag drop + /// /// /// private void canvasPropBox_Drop(object sender, DragEventArgs e) @@ -1700,327 +1589,312 @@ private void ShowObjectValue(WzObject obj) if (obj.WzFileParent != null && obj.WzFileParent.IsUnloaded) // this WZ is already unloaded from memory, dont attempt to display it (when the user clicks "reload" button while selection is on that) return; - mp3Player.SoundProperty = null; - nameBox.Text = obj is WzFile file ? file.Header.Copyright : obj.Name; - nameBox.ApplyButtonEnabled = false; + isLoading = true; - toolStripStatusLabel_additionalInfo.Text = "-"; // Reset additional info to default - if (isSelectingWzMapFieldLimit) // previously already selected. update again - { - isSelectingWzMapFieldLimit = false; - } + try { + mp3Player.SoundProperty = null; - // Canvas animation - if (DataTree.SelectedNodes.Count <= 1) - menuItem_Animate.Visibility = Visibility.Collapsed; // set invisible regardless if none of the nodes are selected. - else - { - bool bIsAllCanvas = true; - // check if everything selected is WzUOLProperty and WzCanvasProperty - foreach (WzNode tree in DataTree.SelectedNodes) + // Set file name binding + _bindingPropertyItem.WzFileName = obj.Name; + + toolStripStatusLabel_additionalInfo.Text = "-"; // Reset additional info to default + if (isSelectingWzMapFieldLimit) // previously already selected. update again { - WzObject wzobj = (WzObject)tree.Tag; - if (!(wzobj is WzUOLProperty) && !(wzobj is WzCanvasProperty)) - { - bIsAllCanvas = false; - break; - } + isSelectingWzMapFieldLimit = false; } - menuItem_Animate.Visibility = bIsAllCanvas ? Visibility.Visible : Visibility.Collapsed; - } - - // Set default layout collapsed state - mp3Player.Visibility = Visibility.Collapsed; - // Button collapsed state - menuItem_changeImage.Visibility = Visibility.Collapsed; - menuItem_saveImage.Visibility = Visibility.Collapsed; - menuItem_changeSound.Visibility = Visibility.Collapsed; - menuItem_saveSound.Visibility = Visibility.Collapsed; - menuItem_exportFile.Visibility = Visibility.Collapsed; - - // Canvas collapsed state - canvasPropBox.Visibility = Visibility.Collapsed; - - // Value - textPropBox.Visibility = Visibility.Collapsed; - - // Field limit panel Map.wz/../fieldLimit - fieldLimitPanelHost.Visibility = Visibility.Collapsed; - // fieldType panel Map.wz/../fieldType - fieldTypePanel.Visibility = Visibility.Collapsed; - - // Vector panel - vectorPanel.Visibility = Visibility.Collapsed; - - // Avalon Text editor - textEditor.Visibility = Visibility.Collapsed; - - // vars - bool bIsWzLuaProperty = obj is WzLuaProperty; - bool bIsWzSoundProperty = obj is WzBinaryProperty; - bool bIsWzStringProperty = obj is WzStringProperty; - bool bIsWzIntProperty = obj is WzIntProperty; - bool bIsWzLongProperty = obj is WzLongProperty; - bool bIsWzDoubleProperty = obj is WzDoubleProperty; - bool bIsWzFloatProperty = obj is WzFloatProperty; - bool bIsWzShortProperty = obj is WzShortProperty; - - bool bAnimateMoreButton = false; // The button to animate when there is more option under button_MoreOption - - // Set layout visibility - if (obj is WzFile || obj is WzDirectory || obj is WzImage || obj is WzNullProperty || obj is WzSubProperty || obj is WzConvexProperty) - { - /*if (obj is WzSubProperty) { // detect String.wz/Npc.img/ directory for AI related tools - if (obj.Parent.Name == "Npc.img") - { - WzObject wzObj = obj.GetTopMostWzDirectory(); - if (wzObj.Name == "String.wz" || (wzObj.Name.StartsWith("String") && wzObj.Name.EndsWith(".wz"))) - { + // Canvas animation + if (DataTree.SelectedNodes.Count <= 1) + menuItem_Animate.Visibility = Visibility.Collapsed; // set invisible regardless if none of the nodes are selected. + else { + bool bIsAllCanvas = true; + // check if everything selected is WzUOLProperty and WzCanvasProperty + foreach (WzNode tree in DataTree.SelectedNodes) { + WzObject wzobj = (WzObject)tree.Tag; + if (!(wzobj is WzUOLProperty) && !(wzobj is WzCanvasProperty)) { + bIsAllCanvas = false; + break; } } - }*/ - } - else if (obj is WzCanvasProperty canvasProp) - { - bAnimateMoreButton = true; // flag - - menuItem_changeImage.Visibility = Visibility.Visible; - menuItem_saveImage.Visibility = Visibility.Visible; + menuItem_Animate.Visibility = bIsAllCanvas ? Visibility.Visible : Visibility.Collapsed; + } - // Image - if (canvasProp.ContainsInlinkProperty() || canvasProp.ContainsOutlinkProperty()) { - System.Drawing.Image img = canvasProp.GetLinkedWzCanvasBitmap(); - if (img != null) { - canvasPropBox.BindingPropertyItem.Bitmap = (System.Drawing.Bitmap)img; - canvasPropBox.BindingPropertyItem.BitmapBackup = (System.Drawing.Bitmap)img; + // Set default layout collapsed state + mp3Player.Visibility = Visibility.Collapsed; + + // Button collapsed state + menuItem_changeImage.Visibility = Visibility.Collapsed; + menuItem_saveImage.Visibility = Visibility.Collapsed; + menuItem_changeSound.Visibility = Visibility.Collapsed; + menuItem_saveSound.Visibility = Visibility.Collapsed; + menuItem_exportFile.Visibility = Visibility.Collapsed; + + // Canvas collapsed state + canvasPropBox.Visibility = Visibility.Collapsed; + + // Value` + _bindingPropertyItem.WzFileValue = string.Empty; + _bindingPropertyItem.ChangeReadOnlyAttribute(true, _bindingPropertyItem, o => o.IsWzValueReadOnly, o => o.WzFileValue); + + // Field limit panel Map.wz/../fieldLimit + fieldLimitPanelHost.Visibility = Visibility.Collapsed; + // fieldType panel Map.wz/../fieldType + fieldTypePanel.Visibility = Visibility.Collapsed; + + // Vector panel + //_bindingPropertyItem.XYVector = new NotifyPointF(0, 0); + _bindingPropertyItem.ChangeReadOnlyAttribute(true, _bindingPropertyItem, o => o.IsXYPanelReadOnly, o => o.XYVector); + + // Avalon Text editor + textEditor.Visibility = Visibility.Collapsed; + + // vars + bool bIsWzFile = obj is WzFile file; + bool bIsWzDirectory = obj is WzDirectory; + bool bIsWzImage = obj is WzImage; + bool bIsWzLuaProperty = obj is WzLuaProperty; + bool bIsWzSoundProperty = obj is WzBinaryProperty; + bool bIsWzStringProperty = obj is WzStringProperty; + bool bIsWzIntProperty = obj is WzIntProperty; + bool bIsWzLongProperty = obj is WzLongProperty; + bool bIsWzDoubleProperty = obj is WzDoubleProperty; + bool bIsWzFloatProperty = obj is WzFloatProperty; + bool bIsWzShortProperty = obj is WzShortProperty; + bool bIsWzNullProperty = obj is WzNullProperty; + bool bIsWzSubProperty = obj is WzSubProperty; + bool bIsWzConvexProperty = obj is WzConvexProperty; + + bool bAnimateMoreButton = false; // The button to animate when there is more option under button_MoreOption + + // Set layout visibility + if (bIsWzFile || bIsWzDirectory || bIsWzImage || bIsWzNullProperty || bIsWzSubProperty || bIsWzConvexProperty) { + /*if (obj is WzSubProperty) { // detect String.wz/Npc.img/ directory for AI related tools + if (obj.Parent.Name == "Npc.img") + { + WzObject wzObj = obj.GetTopMostWzDirectory(); + if (wzObj.Name == "String.wz" || (wzObj.Name.StartsWith("String") && wzObj.Name.EndsWith(".wz"))) + { + } + } + }*/ + + if (bIsWzFile) { + _bindingPropertyItem.WzFileValue = (obj as WzFile).Header.Copyright; + _bindingPropertyItem.ChangeReadOnlyAttribute(false, _bindingPropertyItem, o => o.IsWzValueReadOnly, o => o.WzFileValue); // dont allow user to change fieldLimit manually } } - else { - Bitmap bmp = canvasProp.GetLinkedWzCanvasBitmap(); - canvasPropBox.BindingPropertyItem.Bitmap = bmp; - canvasPropBox.BindingPropertyItem.BitmapBackup = bmp; + else if (obj is WzCanvasProperty canvasProp) { + bAnimateMoreButton = true; // flag + + menuItem_changeImage.Visibility = Visibility.Visible; + menuItem_saveImage.Visibility = Visibility.Visible; + + // Image + if (canvasProp.ContainsInlinkProperty() || canvasProp.ContainsOutlinkProperty()) { + System.Drawing.Image img = canvasProp.GetLinkedWzCanvasBitmap(); + if (img != null) { + canvasPropBox.BindingPropertyItem.Bitmap = (System.Drawing.Bitmap)img; + canvasPropBox.BindingPropertyItem.BitmapBackup = (System.Drawing.Bitmap)img; + } + } + else { + Bitmap bmp = canvasProp.GetLinkedWzCanvasBitmap(); + canvasPropBox.BindingPropertyItem.Bitmap = bmp; + canvasPropBox.BindingPropertyItem.BitmapBackup = bmp; + } + SetImageRenderView(canvasProp); } - SetImageRenderView(canvasProp); - } - else if (obj is WzUOLProperty uolProperty) - { - bAnimateMoreButton = true; // flag + else if (obj is WzUOLProperty uolProperty) { + bAnimateMoreButton = true; // flag - // Image - WzObject linkValue = uolProperty.LinkValue; - if (linkValue is WzCanvasProperty canvasUOL) - { - canvasPropBox.Visibility = Visibility.Visible; + // Image + WzObject linkValue = uolProperty.LinkValue; + if (linkValue is WzCanvasProperty canvasUOL) { + canvasPropBox.Visibility = Visibility.Visible; + + Bitmap bmp = canvasUOL.GetLinkedWzCanvasBitmap(); + canvasPropBox.BindingPropertyItem.Bitmap = bmp; // in any event that the WzCanvasProperty is an '_inlink' or '_outlink' + canvasPropBox.BindingPropertyItem.BitmapBackup = bmp; // in any event that the WzCanvasProperty is an '_inlink' or '_outlink' + + menuItem_saveImage.Visibility = Visibility.Visible; // dont show change image, as its a UOL - Bitmap bmp = canvasUOL.GetLinkedWzCanvasBitmap(); - canvasPropBox.BindingPropertyItem.Bitmap = bmp; // in any event that the WzCanvasProperty is an '_inlink' or '_outlink' - canvasPropBox.BindingPropertyItem.BitmapBackup = bmp; // in any event that the WzCanvasProperty is an '_inlink' or '_outlink' + SetImageRenderView(canvasUOL); + } + else if (linkValue is WzBinaryProperty binProperty) // Sound, used rarely in wz. i.e Sound.wz/Rune/1/Destroy + { + mp3Player.Visibility = Visibility.Visible; + mp3Player.SoundProperty = binProperty; - menuItem_saveImage.Visibility = Visibility.Visible; // dont show change image, as its a UOL + menuItem_changeSound.Visibility = Visibility.Visible; + menuItem_saveSound.Visibility = Visibility.Visible; + } - SetImageRenderView(canvasUOL); + // Value + // set wz file value binding + _bindingPropertyItem.WzFileValue = obj.ToString(); + _bindingPropertyItem.ChangeReadOnlyAttribute(false, _bindingPropertyItem, o => o.IsWzValueReadOnly, o => o.WzFileValue); // can be changed } - else if (linkValue is WzBinaryProperty binProperty) // Sound, used rarely in wz. i.e Sound.wz/Rune/1/Destroy - { + else if (bIsWzSoundProperty) { + bAnimateMoreButton = true; // flag + mp3Player.Visibility = Visibility.Visible; - mp3Player.SoundProperty = binProperty; + mp3Player.SoundProperty = (WzBinaryProperty)obj; menuItem_changeSound.Visibility = Visibility.Visible; menuItem_saveSound.Visibility = Visibility.Visible; } + else if (bIsWzLuaProperty) { + textEditor.Visibility = Visibility.Visible; + textEditor.SetHighlightingDefinitionIndex(2); // javascript - // Value - textPropBox.Visibility = Visibility.Visible; - textPropBox.ApplyButtonEnabled = false; // reset to disabled mode when changed - textPropBox.Text = obj.ToString(); - } - else if (bIsWzSoundProperty) - { - bAnimateMoreButton = true; // flag + textEditor.textEditor.Text = obj.ToString(); + } + else if (bIsWzStringProperty || bIsWzIntProperty || bIsWzLongProperty || bIsWzDoubleProperty || bIsWzFloatProperty || bIsWzShortProperty) { + // If text is a string property, expand the textbox + if (bIsWzStringProperty) { + WzStringProperty stringObj = (WzStringProperty)obj; - mp3Player.Visibility = Visibility.Visible; - mp3Player.SoundProperty = (WzBinaryProperty)obj; + if (stringObj.IsSpineAtlasResources) // spine related resource + { + bAnimateMoreButton = true; + menuItem_exportFile.Visibility = Visibility.Visible; - menuItem_changeSound.Visibility = Visibility.Visible; - menuItem_saveSound.Visibility = Visibility.Visible; - } - else if (bIsWzLuaProperty) - { - textEditor.Visibility = Visibility.Visible; - textEditor.SetHighlightingDefinitionIndex(2); // javascript + textEditor.Visibility = Visibility.Visible; + textEditor.SetHighlightingDefinitionIndex(20); // json + textEditor.textEditor.Text = obj.ToString(); - textEditor.textEditor.Text = obj.ToString(); - } - else if (bIsWzStringProperty || bIsWzIntProperty || bIsWzLongProperty || bIsWzDoubleProperty || bIsWzFloatProperty || bIsWzShortProperty) - { - // If text is a string property, expand the textbox - if (bIsWzStringProperty) - { - WzStringProperty stringObj = (WzStringProperty)obj; - if (stringObj.IsSpineAtlasResources) // spine related resource - { - bAnimateMoreButton = true; - menuItem_exportFile.Visibility = Visibility.Visible; + string path_title = stringObj.Parent?.FullPath ?? "Animate"; - textEditor.Visibility = Visibility.Visible; - textEditor.SetHighlightingDefinitionIndex(20); // json - textEditor.textEditor.Text = obj.ToString(); + Thread thread = new Thread(() => { + try { + WzSpineAnimationItem item = new WzSpineAnimationItem(stringObj); + // Create xna window + SpineAnimationWindow Window = new SpineAnimationWindow(item, path_title); + Window.Run(); + } + catch (Exception e) { + Warning.Error("Error initialising/ rendering spine object. " + e.ToString()); + } + }); + thread.Start(); + thread.Join(); + } + else if (stringObj.Name.EndsWith(".json")) // Map001.wz/Back/BM3_3.img/spine/skeleton.json + { + bAnimateMoreButton = true; + menuItem_exportFile.Visibility = Visibility.Visible; - string path_title = stringObj.Parent?.FullPath ?? "Animate"; + textEditor.Visibility = Visibility.Visible; + textEditor.SetHighlightingDefinitionIndex(20); // json + textEditor.textEditor.Text = obj.ToString(); + } + else { + // Value + _bindingPropertyItem.WzFileValue = obj.ToString(); + _bindingPropertyItem.ChangeReadOnlyAttribute(false, _bindingPropertyItem, o => o.IsWzValueReadOnly, o => o.WzFileValue); // can be changed - Thread thread = new Thread(() => - { - try + if (stringObj.Name == PORTAL_NAME_OBJ_NAME) // Portal type name display - "pn" = portal name { - WzSpineAnimationItem item = new WzSpineAnimationItem(stringObj); - - // Create xna window - SpineAnimationWindow Window = new SpineAnimationWindow(item, path_title); - Window.Run(); + if (MapleLib.WzLib.WzStructure.Data.Tables.PortalTypeNames.ContainsKey(obj.GetString())) { + toolStripStatusLabel_additionalInfo.Text = + string.Format(Properties.Resources.MainAdditionalInfo_PortalType, MapleLib.WzLib.WzStructure.Data.Tables.PortalTypeNames[obj.GetString()]); + } + else { + toolStripStatusLabel_additionalInfo.Text = string.Format(Properties.Resources.MainAdditionalInfo_PortalType, obj.GetString()); + } } - catch (Exception e) - { - Warning.Error("Error initialising/ rendering spine object. " + e.ToString()); + else { + //textPropBox.AcceptsReturn = true; + // TODO } - }); - thread.Start(); - thread.Join(); - } - else if (stringObj.Name.EndsWith(".json")) // Map001.wz/Back/BM3_3.img/spine/skeleton.json - { - bAnimateMoreButton = true; - menuItem_exportFile.Visibility = Visibility.Visible; - - textEditor.Visibility = Visibility.Visible; - textEditor.SetHighlightingDefinitionIndex(20); // json - textEditor.textEditor.Text = obj.ToString(); + } } - else - { - // Value - textPropBox.Visibility = Visibility.Visible; - textPropBox.Text = obj.ToString(); - textPropBox.ApplyButtonEnabled = false; // reset to disabled mode when changed - - if (stringObj.Name == PORTAL_NAME_OBJ_NAME) // Portal type name display - "pn" = portal name + else if (bIsWzLongProperty || bIsWzIntProperty || bIsWzShortProperty) { + // field limit UI + if (obj.Name == FIELD_LIMIT_OBJ_NAME) // fieldLimit { - if (MapleLib.WzLib.WzStructure.Data.Tables.PortalTypeNames.ContainsKey(obj.GetString())) + isSelectingWzMapFieldLimit = true; + + ulong value_ = 0; + if (bIsWzLongProperty) // use uLong for field limit { - toolStripStatusLabel_additionalInfo.Text = - string.Format(Properties.Resources.MainAdditionalInfo_PortalType, MapleLib.WzLib.WzStructure.Data.Tables.PortalTypeNames[obj.GetString()]); + value_ = (ulong)((WzLongProperty)obj).GetLong(); } - else - { - toolStripStatusLabel_additionalInfo.Text = string.Format(Properties.Resources.MainAdditionalInfo_PortalType, obj.GetString()); + else if (bIsWzIntProperty) { + value_ = (ulong)((WzIntProperty)obj).GetLong(); + } + else if (bIsWzShortProperty) { + value_ = (ulong)((WzShortProperty)obj).GetLong(); } - } - else - { - textPropBox.AcceptsReturn = true; - } - } - } - else if (bIsWzLongProperty || bIsWzIntProperty || bIsWzShortProperty) - { - textPropBox.Visibility = Visibility.Visible; - textPropBox.AcceptsReturn = false; - textPropBox.ApplyButtonEnabled = false; // reset to disabled mode when changed - // field limit UI - if (obj.Name == FIELD_LIMIT_OBJ_NAME) // fieldLimit - { - isSelectingWzMapFieldLimit = true; + fieldLimitPanel1.UpdateFieldLimitCheckboxes(value_); - ulong value_ = 0; - if (bIsWzLongProperty) // use uLong for field limit - { - value_ = (ulong)((WzLongProperty)obj).GetLong(); - } - else if (bIsWzIntProperty) - { - value_ = (ulong)((WzIntProperty)obj).GetLong(); + _bindingPropertyItem.WzFileValue = value_.ToString(); + _bindingPropertyItem.ChangeReadOnlyAttribute(true, _bindingPropertyItem, o => o.IsWzValueReadOnly, o => o.WzFileValue); // dont allow user to change fieldLimit manually + + // Set visibility + fieldLimitPanelHost.Visibility = Visibility.Visible; } - else if (bIsWzShortProperty) - { - value_ = (ulong)((WzShortProperty)obj).GetLong(); + else { + long value_ = 0; // long for others, in the case of negative value + if (bIsWzLongProperty) { + value_ = ((WzLongProperty)obj).GetLong(); + } + else if (bIsWzIntProperty) { + value_ = ((WzIntProperty)obj).GetLong(); + } + else if (bIsWzShortProperty) { + value_ = ((WzShortProperty)obj).GetLong(); + } + _bindingPropertyItem.WzFileValue = value_.ToString(); + _bindingPropertyItem.ChangeReadOnlyAttribute(false, _bindingPropertyItem, o => o.IsWzValueReadOnly, o => o.WzFileValue); // can be changed } + } + else if (bIsWzDoubleProperty || bIsWzFloatProperty) { + _bindingPropertyItem.ChangeReadOnlyAttribute(false, _bindingPropertyItem, o => o.IsWzValueReadOnly, o => o.WzFileValue); // can be changed - fieldLimitPanel1.UpdateFieldLimitCheckboxes(value_); - - // Set visibility - fieldLimitPanelHost.Visibility = Visibility.Visible; - } - else - { - long value_ = 0; // long for others, in the case of negative value - if (bIsWzLongProperty) - { - value_ = ((WzLongProperty)obj).GetLong(); + if (bIsWzFloatProperty) { + _bindingPropertyItem.WzFileValue = ((WzFloatProperty)obj).GetFloat().ToString(); } - else if (bIsWzIntProperty) - { - value_ = ((WzIntProperty)obj).GetLong(); + else if (bIsWzDoubleProperty) { + _bindingPropertyItem.WzFileValue = ((WzDoubleProperty)obj).GetDouble().ToString(); } - else if (bIsWzShortProperty) - { - value_ = ((WzShortProperty)obj).GetLong(); - } - textPropBox.Text = value_.ToString(); } - } - else if (bIsWzDoubleProperty || bIsWzFloatProperty) - { - textPropBox.Visibility = Visibility.Visible; - textPropBox.AcceptsReturn = false; - textPropBox.ApplyButtonEnabled = false; // reset to disabled mode when changed - - if (bIsWzFloatProperty) - { - textPropBox.Text = ((WzFloatProperty)obj).GetFloat().ToString(); - } - else if (bIsWzDoubleProperty) - { - textPropBox.Text = ((WzDoubleProperty)obj).GetDouble().ToString(); + else { + //textPropBox.AcceptsReturn = false; + // TODO } } - else - { - textPropBox.AcceptsReturn = false; - } - } - else if (obj is WzVectorProperty property) - { - vectorPanel.Visibility = Visibility.Visible; + else if (obj is WzVectorProperty property) { + _bindingPropertyItem.XYVector.X = property.X.Value; + _bindingPropertyItem.XYVector.Y = property.Y.Value; - vectorPanel.X = property.X.Value; - vectorPanel.Y = property.Y.Value; - } - else - { - } + _bindingPropertyItem.ChangeReadOnlyAttribute(false, _bindingPropertyItem, o => o.IsXYPanelReadOnly, o => o.XYVector); + } + else { + } - // Animation button - if (AnimationBuilder.IsValidAnimationWzObject(obj)) - { - bAnimateMoreButton = true; // flag + // Animation button + if (AnimationBuilder.IsValidAnimationWzObject(obj)) { + bAnimateMoreButton = true; // flag - menuItem_saveImageAnimation.Visibility = Visibility.Visible; - } - else - { - menuItem_saveImageAnimation.Visibility = Visibility.Collapsed; - } + menuItem_saveImageAnimation.Visibility = Visibility.Visible; + } + else { + menuItem_saveImageAnimation.Visibility = Visibility.Collapsed; + } - // Storyboard hint - button_MoreOption.Visibility = bAnimateMoreButton ? Visibility.Visible : Visibility.Collapsed; - if (bAnimateMoreButton) - { - System.Windows.Media.Animation.Storyboard storyboard_moreAnimation = (System.Windows.Media.Animation.Storyboard)(this.FindResource("Storyboard_TreeviewItemSelectedAnimation")); - storyboard_moreAnimation.Begin(); + // Storyboard hint + button_MoreOption.Visibility = bAnimateMoreButton ? Visibility.Visible : Visibility.Collapsed; + if (bAnimateMoreButton) { + System.Windows.Media.Animation.Storyboard storyboard_moreAnimation = (System.Windows.Media.Animation.Storyboard)(this.FindResource("Storyboard_TreeviewItemSelectedAnimation")); + storyboard_moreAnimation.Begin(); + } + } finally { + isLoading = false; } } @@ -2057,6 +1931,168 @@ private void SetImageRenderView(WzCanvasProperty canvas) } #endregion + #region Property Item + /// + /// On property item selection changed + /// + /// + /// + private void propertyGrid_PropertyChanged_1(object sender, System.ComponentModel.PropertyChangedEventArgs e) { + if (isLoading) { + return; + } + switch (e.PropertyName) { + case "WzFileType": { // does nothing + break; + } + case "WzFileName": { + if (DataTree.SelectedNode == null) + return; + + string setText = _bindingPropertyItem.WzFileName; + + WzNode node = (WzNode)DataTree.SelectedNode; + + if (node.Tag is WzFile) { + + } + else if (WzNode.CanNodeBeInserted((WzNode)node.Parent, setText)) { + node.ChangeName(setText); + } + else + Warning.Error(Properties.Resources.MainNodeExists); + break; + } + case "XYVector": + case "WzFileValue": { + if (DataTree.SelectedNode == null) + return; + + string setText = _bindingPropertyItem.WzFileValue; + + bool bChangedNode = false; + + WzNode node = (WzNode) DataTree.SelectedNode; + WzObject obj = (WzObject)DataTree.SelectedNode.Tag; + + bool bIsWzFile = obj is WzFile file; + bool bIsWzDirectory = obj is WzDirectory; + bool bIsWzImage = obj is WzImage; + bool bIsWzLuaProperty = obj is WzLuaProperty; + bool bIsWzSoundProperty = obj is WzBinaryProperty; + bool bIsWzStringProperty = obj is WzStringProperty; + bool bIsWzIntProperty = obj is WzIntProperty; + bool bIsWzLongProperty = obj is WzLongProperty; + bool bIsWzDoubleProperty = obj is WzDoubleProperty; + bool bIsWzFloatProperty = obj is WzFloatProperty; + bool bIsWzShortProperty = obj is WzShortProperty; + bool bIsWzNullProperty = obj is WzNullProperty; + bool bIsWzSubProperty = obj is WzSubProperty; + bool bIsWzConvexProperty = obj is WzConvexProperty; + + + if (bIsWzFile) { + ((WzFile)node.Tag).Header.Copyright = setText; + ((WzFile)node.Tag).Header.RecalculateFileStart(); + + bChangedNode = true; + } + else if (obj is WzVectorProperty vectorProperty) { + vectorProperty.X.Value = (int) _bindingPropertyItem.XYVector.X; + vectorProperty.Y.Value = (int) _bindingPropertyItem.XYVector.Y; + + bChangedNode = true; + } + else if (obj is WzStringProperty stringProperty) { + if (!stringProperty.IsSpineAtlasResources) { + stringProperty.Value = setText; + + bChangedNode = true; + } + else { + throw new NotSupportedException("Usage of textBoxProp for spine WzStringProperty."); + } + } + else if (obj is WzFloatProperty floatProperty) { + float val; + if (!float.TryParse(setText, out val)) { + Warning.Error(string.Format(Properties.Resources.MainConversionError, setText)); + return; + } + floatProperty.Value = val; + + bChangedNode = true; + } + else if (obj is WzIntProperty intProperty) { + int val; + if (!int.TryParse(setText, out val)) { + Warning.Error(string.Format(Properties.Resources.MainConversionError, setText)); + return; + } + intProperty.Value = val; + + bChangedNode = true; + } + else if (obj is WzLongProperty longProperty) { + long val; + if (!long.TryParse(setText, out val)) { + Warning.Error(string.Format(Properties.Resources.MainConversionError, setText)); + return; + } + longProperty.Value = val; + + bChangedNode = true; + } + else if (obj is WzDoubleProperty doubleProperty) { + double val; + if (!double.TryParse(setText, out val)) { + Warning.Error(string.Format(Properties.Resources.MainConversionError, setText)); + return; + } + doubleProperty.Value = val; + + bChangedNode = true; + } + else if (obj is WzShortProperty shortProperty) { + short val; + if (!short.TryParse(setText, out val)) { + Warning.Error(string.Format(Properties.Resources.MainConversionError, setText)); + return; + } + shortProperty.Value = val; + + bChangedNode = true; + } + else if (obj is WzUOLProperty UOLProperty) { + UOLProperty.Value = setText; + + bChangedNode = true; + } + else if (obj is WzLuaProperty) { + throw new NotSupportedException("Moved to TextEditor_SaveButtonClicked()"); + } + + if (bChangedNode) { + node.ChangedNodeProperty(); + } + break; + } + default: { + break; + } + } + } + + /// + /// On field limit checkboxes changes, update the PropertyItem values accordingly + /// + /// + /// + private void FieldLimitPanel1_FieldLimitChanged(object sender, FieldLimitChangedEventArgs e) { + _bindingPropertyItem.WzFileValue = e.FieldLimit.ToString(); + } + #endregion + #region Search /// @@ -2288,6 +2324,5 @@ private void findBox_TextChanged(object sender, TextChangedEventArgs e) searchidx = 0; } #endregion - } -} +} \ No newline at end of file diff --git a/HaRepacker/GUI/Panels/MainPanelPropertyItems.cs b/HaRepacker/GUI/Panels/MainPanelPropertyItems.cs new file mode 100644 index 00000000..11b54089 --- /dev/null +++ b/HaRepacker/GUI/Panels/MainPanelPropertyItems.cs @@ -0,0 +1,175 @@ +using HaRepacker.Converter; +using HaRepacker.GUI.Controls; +using Newtonsoft.Json.Linq; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Text; +using System.Threading.Tasks; + +namespace HaRepacker.GUI.Panels { + + /// + /// For property items with WZ value that can be edited. + /// + public class MainPanelPropertyItems : INotifyPropertyChanged { + + private const string CATEGORY_DISPLAY = "Property"; + + public MainPanelPropertyItems() { + _XYVector.PropertyChanged += (sender, args) => OnPropertyChanged(nameof(XYVector)); + } + + private string _wzFileType = ""; + [ReadOnly(true)] // This makes the Name property read-only + [Category(CATEGORY_DISPLAY)] + [Description("The file type currently being selected")] + [DisplayName("WZ file type")] + public string WzFileType { + get => _wzFileType; + set { + if (_wzFileType != value) { + _wzFileType = value; + OnPropertyChanged(nameof(WzFileType)); + } + } + } + + private string _wzFileName = ""; + [ReadOnly(false)] // This makes the Name property read-only + [Category(CATEGORY_DISPLAY)] + [Description("The name of the file currently being selected")] + [DisplayName("WZ file name")] + public string WzFileName { + get => _wzFileName; + set { + if (_wzFileName != value) { + _wzFileName = value; + OnPropertyChanged(nameof(WzFileName)); + } + } + } + + private string _wzFileValue = ""; + [ReadOnly(false)]// This makes the Name property read-only + [Category(CATEGORY_DISPLAY)] + [Description("The value of the file currently being selected")] + [DisplayName("WZ value")] + public string WzFileValue { + get => _wzFileValue; + set { + if (_wzFileValue != value) { + _wzFileValue = value; + OnPropertyChanged(nameof(WzFileValue)); + } + } + } + private bool _bIsWzValueReadOnly = true; + [ReadOnly(true)]// This makes the Name property read-only + [Browsable(false)] + public bool IsWzValueReadOnly { + get => _bIsWzValueReadOnly; + set { + if (_bIsWzValueReadOnly != value) { + _bIsWzValueReadOnly = value; + OnPropertyChanged(nameof(IsWzValueReadOnly)); + } + } + } + + private NotifyPointF _XYVector = new NotifyPointF(0,0); + [Category(CATEGORY_DISPLAY)] + [Description("The X,Y values.")] + [DisplayName("X Y")] + [TypeConverter(typeof(PointFConverter))] + [Editor(typeof(PointFEditor), typeof(PointFEditor))] + [ReadOnly(true)]// This makes the Name property read-only + public NotifyPointF XYVector { + get => _XYVector; + set { + if (_XYVector != value) { + if (_XYVector != null) { + _XYVector.PropertyChanged -= (sender, args) => OnPropertyChanged(nameof(XYVector)); + } + _XYVector = value; + if (_XYVector != null) { + _XYVector.PropertyChanged += (sender, args) => OnPropertyChanged(nameof(XYVector)); + } + OnPropertyChanged(nameof(XYVector)); + } + } + } + private bool _bIsXYPanelReadOnly = true; + [ReadOnly(true)]// This makes the Name property read-only + [Browsable(false)] + public bool IsXYPanelReadOnly { + get => _bIsXYPanelReadOnly; + set { + if (_bIsXYPanelReadOnly != value) { + _bIsXYPanelReadOnly = value; + OnPropertyChanged(nameof(IsXYPanelReadOnly)); + } + } + } + + + /// + /// Updates the read-only attribute of a parameter and sets a boolean property + /// + /// True to set as read-only, false otherwise + /// Name of the parameter to update + /// The type containing the property + /// The object containing the property + /// A lambda expression to select the property + public void ChangeReadOnlyAttribute(bool bSet, T obj, Expression> boolPropertyReadOnlySelector, Expression> setPropertySelector) { + // changing attribute does not update the UI state + string setPropertyName = GetPropertyName(setPropertySelector); + PropertyDescriptor descriptor = TypeDescriptor.GetProperties(typeof(T))[setPropertyName]; + ReadOnlyAttribute attribute = (ReadOnlyAttribute)descriptor.Attributes[typeof(ReadOnlyAttribute)]; + + FieldInfo isReadOnlyField = typeof(ReadOnlyAttribute).GetField("isReadOnly", BindingFlags.NonPublic | BindingFlags.Instance); + //System.Diagnostics.Debug.WriteLine("From: " +attribute.IsReadOnly); + isReadOnlyField.SetValue(attribute, bSet); + //System.Diagnostics.Debug.WriteLine("To: " + attribute.IsReadOnly); + + BrowsableAttribute browsableAttribute = (BrowsableAttribute)descriptor.Attributes[typeof(BrowsableAttribute)]; + FieldInfo isBrowsableField = typeof(BrowsableAttribute).GetField("browsable", BindingFlags.NonPublic | BindingFlags.Instance); + isBrowsableField.SetValue(browsableAttribute, !bSet); + + // Get the property + PropertyInfo propInfo = ((MemberExpression)boolPropertyReadOnlySelector.Body).Member as PropertyInfo; + + // Update the boolean property + propInfo.SetValue(obj, bSet); + + // Note: OnPropertyChanged is called within the property setter, so we don't need to call it here + } + + private string GetPropertyName(Expression> propertySelector) { + if (propertySelector.Body is MemberExpression memberExpression) { + return memberExpression.Member.Name; + } + else if (propertySelector.Body is UnaryExpression unaryExpression) { + return ((MemberExpression)unaryExpression.Operand).Member.Name; + } + + throw new ArgumentException("Invalid property selector", nameof(propertySelector)); + } + + #region Events + + public event PropertyChangedEventHandler PropertyChanged; + /// + /// On property changed + /// + /// + protected virtual void OnPropertyChanged(string propertyName) { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + #endregion + } +} diff --git a/HaRepacker/GUI/Panels/SubPanels/ImageRenderViewer.xaml b/HaRepacker/GUI/Panels/SubPanels/ImageRenderViewer.xaml index 284c1fe6..4960779d 100644 --- a/HaRepacker/GUI/Panels/SubPanels/ImageRenderViewer.xaml +++ b/HaRepacker/GUI/Panels/SubPanels/ImageRenderViewer.xaml @@ -316,7 +316,7 @@ - + + + + + + + + + + + + + @@ -497,23 +552,29 @@ - - + + - - + + - - + + - - + + - - + + - - + + + + + + + + @@ -532,7 +593,7 @@ - + - + - -