// // PropertyListPanel.cs // // Author: // Mike Becker // // Copyright (c) 2019 Mike Becker // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . using System; using System.Collections.Generic; using MBS.Framework; using MBS.Framework.UserInterface; using MBS.Framework.UserInterface.Controls; using MBS.Framework.UserInterface.Controls.ListView; namespace UniversalEditor.UserInterface.Panels { public class PropertyPanelProperty { public class PropertyPanelPropertyCollection : System.Collections.ObjectModel.Collection { } public string Name { get; set; } = String.Empty; public object Value { get; set; } = null; public Type DataType { get; set; } = null; public PropertyPanelProperty.PropertyPanelPropertyCollection Properties { get; } = new PropertyPanelPropertyCollection(); public PropertyPanelProperty(string name, Type dataType = null, object value = null, PropertyPanelProperty[] properties = null) { Name = name; DataType = dataType; Value = value; if (properties != null) { for (int i = 0; i < properties.Length; i++) { Properties.Add(properties[i]); } } } } public class PropertyPanelClass { public class PropertyPanelClassCollection : System.Collections.ObjectModel.Collection { } public string Name { get; set; } = null; public PropertyPanelProperty.PropertyPanelPropertyCollection Properties { get; } = new PropertyPanelProperty.PropertyPanelPropertyCollection(); public PropertyPanelClass(string name, PropertyPanelProperty[] properties = null) { Name = name; if (properties != null) { for (int i = 0; i < properties.Length; i++) { Properties.Add(properties[i]); } } } } public class PropertyPanelObject : ISupportsExtraData { public class PropertyPanelObjectCollection : System.Collections.ObjectModel.Collection { private PropertyListPanel _parent = null; internal PropertyPanelObjectCollection(PropertyListPanel parent) { _parent = parent; } protected override void ClearItems() { base.ClearItems(); _parent?.ClearPropertyPanelObjects(); } protected override void InsertItem(int index, PropertyPanelObject item) { base.InsertItem(index, item); _parent?.AddPropertyPanelObject(item); } protected override void RemoveItem(int index) { _parent?.RemovePropertyPanelObject(this[index]); base.RemoveItem(index); } } public string Name { get; } = null; public PropertyPanelClass ObjectClass { get; } = null; public PropertyPanelProperty.PropertyPanelPropertyCollection Properties { get; } = new PropertyPanelProperty.PropertyPanelPropertyCollection(); public PropertyPanelObject(string name, PropertyPanelClass clas) { Name = name; ObjectClass = clas; } #region ISupportsExtraData members private Dictionary _ExtraData = new Dictionary(); public T GetExtraData(string key, T defaultValue = default(T)) { if (_ExtraData.ContainsKey(key)) return (T)_ExtraData[key]; return defaultValue; } public object GetExtraData(string key, object defaultValue = null) { return GetExtraData(key, defaultValue); } public void SetExtraData(string key, T value) { _ExtraData[key] = value; } public void SetExtraData(string key, object value) { SetExtraData(key, value); } #endregion } [ContainerLayout("~/Panels/PropertyList/PropertyListPanel.glade")] partial class PropertyListPanel : Panel { internal ComboBox cboObject; private SplitContainer scDescriptionCommands; private ListViewControl lvPropertyGrid; public PropertyPanelObject.PropertyPanelObjectCollection Objects { get; private set; } = null; public static readonly Guid ID = new Guid("{c935e3af-e5c6-4b3e-a3a4-e16ba229a91d}"); protected override void OnEditorChanged(EditorChangedEventArgs e) { base.OnEditorChanged(e); Objects.Clear(); Editor editor = ((EditorWindow)ParentWindow).GetCurrentEditor(); if (editor == null) return; foreach (PropertyPanelObject obj in editor.PropertiesPanel.Objects) { Objects.Add(obj); } cboObject.Visible = editor.PropertiesPanel.ShowObjectSelector; } public PropertyListPanel() { Objects = new PropertyPanelObject.PropertyPanelObjectCollection(this); } [EventHandler(nameof(cboObject), nameof(ComboBox.KeyDown))] void cboObject_KeyDown(object sender, MBS.Framework.UserInterface.Input.Keyboard.KeyEventArgs e) { // this don't work, Gtk blocks keyboard input (probably cause it's technically a text box) if (e.Key == MBS.Framework.UserInterface.Input.Keyboard.KeyboardKey.Enter) { if (cboObject.Model != null) { TreeModelRow row = cboObject.Model.Find(cboObject.Text); if (row != null) { cboObject.SelectedItem = row; } } } } internal void ClearPropertyPanelObjects() { (cboObject.Model as DefaultTreeModel).Rows.Clear(); } internal void AddPropertyPanelObject(PropertyPanelObject item) { TreeModelRow row = new TreeModelRow(new TreeModelRowColumn[] { new TreeModelRowColumn((cboObject.Model as DefaultTreeModel).Columns[0], item.Name), new TreeModelRowColumn((cboObject.Model as DefaultTreeModel).Columns[1], item.ObjectClass?.Name) }); row.SetExtraData("obj", item); _rowsByObject[item] = row; (cboObject.Model as DefaultTreeModel).Rows.Add(row); } private Dictionary _rowsByObject = new Dictionary(); internal void RemovePropertyPanelObject(PropertyPanelObject item) { if (!_rowsByObject.ContainsKey(item)) return; (cboObject.Model as DefaultTreeModel).Rows.Remove(_rowsByObject[item]); } internal void RefreshList() { (cboObject.Model as DefaultTreeModel).Rows.Clear(); for (int i = 0; i < Objects.Count; i++) { AddPropertyPanelObject(Objects[i]); } } private PropertyPanelObject _SelectedObject = null; public PropertyPanelObject SelectedObject { get { return _SelectedObject; } set { _SelectedObject = value; lvPropertyGrid.Model.Rows.Clear(); if (_SelectedObject != null) { if (SelectedObject.ObjectClass != null) { for (int i = 0; i < SelectedObject.ObjectClass.Properties.Count; i++) { AddPropertyPanelProperty(SelectedObject.ObjectClass.Properties[i]); } } for (int i = 0; i < SelectedObject.Properties.Count; i++) { AddPropertyPanelProperty(SelectedObject.Properties[i]); } } } } private void AddPropertyPanelProperty(PropertyPanelProperty property, TreeModelRow parentRow = null) { TreeModelRow row = new TreeModelRow(new TreeModelRowColumn[] { new TreeModelRowColumn(lvPropertyGrid.Model.Columns[0], property.Name), new TreeModelRowColumn(lvPropertyGrid.Model.Columns[1], property.Value == null ? String.Empty : property.Value.ToString()) }); for (int i = 0; i < property.Properties.Count; i++) { AddPropertyPanelProperty(property.Properties[i], row); } if (parentRow != null) { parentRow.Rows.Add(row); } else { lvPropertyGrid.Model.Rows.Add(row); } } [EventHandler(nameof(cboObject), nameof(ComboBox.Changed))] void cboObject_Changed(object sender, EventArgs e) { SelectedObject = cboObject.SelectedItem?.GetExtraData("obj"); } [EventHandler(nameof(lvPropertyGrid), nameof(ListViewControl.SelectionChanged))] private void lvPropertyGrid_SelectionChanged(object sender, EventArgs e) { } } }