| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371 |
- /*
- * Copyright (c) 2012-2025 Daniele Bartolini et al.
- * SPDX-License-Identifier: GPL-3.0-or-later
- */
- namespace Crown
- {
- public class PropertyGrid : Gtk.Grid
- {
- public Database? _db;
- public Guid _id;
- public Guid _component_id;
- public int _rows;
- public double _order;
- public bool _visible;
- public Gee.HashMap<string, InputField> _widgets;
- public Gee.HashMap<InputField, PropertyDefinition?> _definitions;
- public PropertyGrid(Database? db = null)
- {
- this.row_spacing = 4;
- this.row_homogeneous = true;
- this.column_spacing = 12;
- // Data
- _db = db;
- _id = GUID_ZERO;
- _component_id = GUID_ZERO;
- _rows = 0;
- _order = 0.0;
- _visible = true;
- _widgets = new Gee.HashMap<string, InputField>();
- _definitions = new Gee.HashMap<InputField, PropertyDefinition?>();
- }
- public PropertyGrid.from_object_type(StringId64 type, Database db)
- {
- this.row_spacing = 4;
- this.row_homogeneous = true;
- this.column_spacing = 12;
- // Data
- _db = db;
- _id = GUID_ZERO;
- _component_id = GUID_ZERO;
- _rows = 0;
- _order = db.object_type_info(type).ui_order;
- _visible = true;
- _widgets = new Gee.HashMap<string, InputField>();
- _definitions = new Gee.HashMap<InputField, PropertyDefinition?>();
- add_object_type(db.object_definition(type));
- }
- public Gtk.Widget add_row(string label, Gtk.Widget w)
- {
- Gtk.Label l = new Gtk.Label(label);
- l.width_chars = 13;
- l.xalign = 1.0f;
- l.yalign = 0.5f;
- w.hexpand = true;
- this.attach(l, 0, (int)_rows);
- this.attach(w, 1, (int)_rows);
- ++_rows;
- return l;
- }
- public void add_object_type(PropertyDefinition[] properties)
- {
- foreach (PropertyDefinition def in properties) {
- // Create input field.
- InputField? p = null;
- switch (def.type) {
- case PropertyType.BOOL:
- p = new InputBool();
- break;
- case PropertyType.DOUBLE:
- if (def.editor == PropertyEditorType.ANGLE)
- p = new InputAngle((double)def.deffault, (double)def.min, (double)def.max);
- else
- p = new InputDouble((double)def.deffault, (double)def.min, (double)def.max);
- break;
- case PropertyType.STRING:
- if (def.editor == PropertyEditorType.ENUM)
- p = new InputEnum((string)def.deffault, def.enum_labels, def.enum_values);
- else if (def.editor == PropertyEditorType.RESOURCE)
- p = new InputResource(def.resource_type, _db);
- else
- p = new InputString();
- break;
- case PropertyType.GUID:
- p = new InputString();
- break;
- case PropertyType.VECTOR3:
- if (def.editor == PropertyEditorType.COLOR)
- p = new InputColor3();
- else
- p = new InputVector3((Vector3)def.deffault, (Vector3)def.min, (Vector3)def.max);
- break;
- case PropertyType.QUATERNION:
- p = new InputQuaternion();
- break;
- case PropertyType.OBJECTS_SET:
- continue;
- default:
- case PropertyType.NULL:
- assert(false);
- break;
- }
- p.value_changed.connect(on_property_value_changed);
- _widgets[def.name] = p;
- _definitions[p] = def;
- if (!def.hidden)
- add_row(def.label, p);
- }
- }
- public void on_property_value_changed(InputField p)
- {
- if (p.is_inconsistent())
- return;
- PropertyDefinition def = _definitions[p];
- bool changed = false;
- if (def.type == PropertyType.BOOL) {
- if (_db.object_type(_id) == OBJECT_TYPE_UNIT) {
- Unit u = Unit(_db, _id);
- if (u.get_component_property_bool(_component_id, def.name, (bool)def.deffault) != p.union_value()) {
- u.set_component_property_bool(_component_id, def.name, (bool)p.union_value());
- changed = true;
- }
- } else {
- if (_db.get_property_bool(_id, def.name, (bool)def.deffault) != p.union_value()) {
- _db.set_property_bool(_id, def.name, (bool)p.union_value());
- changed = true;
- }
- }
- } else if (def.type == PropertyType.DOUBLE) {
- if (_db.object_type(_id) == OBJECT_TYPE_UNIT) {
- Unit u = Unit(_db, _id);
- if (u.get_component_property_double(_component_id, def.name, (double)def.deffault) != p.union_value()) {
- u.set_component_property_double(_component_id, def.name, (double)p.union_value());
- changed = true;
- }
- } else {
- if (_db.get_property_double(_id, def.name, (double)def.deffault) != p.union_value()) {
- _db.set_property_double(_id, def.name, (double)p.union_value());
- changed = true;
- }
- }
- } else if (def.type == PropertyType.STRING) {
- if (_db.object_type(_id) == OBJECT_TYPE_UNIT) {
- Unit u = Unit(_db, _id);
- if (u.get_component_property_string(_component_id, def.name, (string)def.deffault) != (string)p.union_value()) {
- u.set_component_property_string(_component_id, def.name, (string)p.union_value());
- changed = true;
- }
- } else {
- if (_db.get_property_string(_id, def.name, (string)def.deffault) != (string)p.union_value()) {
- _db.set_property_string(_id, def.name, (string)p.union_value());
- changed = true;
- }
- }
- } else if (def.type == PropertyType.GUID) {
- if (_db.object_type(_id) == OBJECT_TYPE_UNIT) {
- Unit u = Unit(_db, _id);
- if (Guid.equal_func(u.get_component_property_guid(_component_id, def.name, (Guid)def.deffault), Guid.parse((string)p.union_value())) == false) {
- u.set_component_property_guid(_component_id, def.name, Guid.parse((string)p.union_value()));
- changed = true;
- }
- } else {
- if (Guid.equal_func(_db.get_property_guid(_id, def.name, (Guid)def.deffault), Guid.parse((string)p.union_value())) == false) {
- _db.set_property_guid(_id, def.name, Guid.parse((string)p.union_value()));
- changed = true;
- }
- }
- } else if (def.type == PropertyType.VECTOR3) {
- if (_db.object_type(_id) == OBJECT_TYPE_UNIT) {
- Unit u = Unit(_db, _id);
- if (Vector3.equal_func(u.get_component_property_vector3(_component_id, def.name, (Vector3)def.deffault), (Vector3)p.union_value()) == false) {
- u.set_component_property_vector3(_component_id, def.name, (Vector3)p.union_value());
- changed = true;
- }
- } else {
- if (Vector3.equal_func(_db.get_property_vector3(_id, def.name, (Vector3)def.deffault), (Vector3)p.union_value()) == false) {
- _db.set_property_vector3(_id, def.name, (Vector3)p.union_value());
- changed = true;
- }
- }
- } else if (def.type == PropertyType.QUATERNION) {
- if (_db.object_type(_id) == OBJECT_TYPE_UNIT) {
- Unit u = Unit(_db, _id);
- if (Quaternion.equal_func(u.get_component_property_quaternion(_component_id, def.name, (Quaternion)def.deffault), (Quaternion)p.union_value()) == false) {
- u.set_component_property_quaternion(_component_id, def.name, (Quaternion)p.union_value());
- changed = true;
- }
- } else {
- if (Quaternion.equal_func(_db.get_property_quaternion(_id, def.name, (Quaternion)def.deffault), (Quaternion)p.union_value()) == false) {
- _db.set_property_quaternion(_id, def.name, (Quaternion)p.union_value());
- changed = true;
- }
- }
- } else {
- loge("Unknown property type");
- }
- foreach (var e in _definitions) {
- PropertyDefinition other_def = e.value;
- if (other_def.enum_property == def.name) {
- if (other_def.enum_callback != null)
- other_def.enum_callback(p, (InputEnum)_widgets[other_def.name], _db._project);
- if (other_def.resource_callback != null)
- other_def.resource_callback(p, (InputResource)_widgets[other_def.name], _db._project);
- }
- }
- if (changed)
- _db.add_restore_point(ActionType.CHANGE_OBJECTS, new Guid?[] { _id });
- }
- public virtual void update()
- {
- foreach (var e in _definitions) {
- InputField p = e.key;
- PropertyDefinition def = e.value;
- if (def.type == PropertyType.BOOL) {
- if (_db.object_type(_id) == OBJECT_TYPE_UNIT) {
- Unit u = Unit(_db, _id);
- p.set_union_value(u.get_component_property_bool(_component_id, def.name, (bool)def.deffault));
- } else {
- p.set_union_value(_db.get_property_bool(_id, def.name, (bool)def.deffault));
- }
- } else if (def.type == PropertyType.DOUBLE) {
- if (_db.object_type(_id) == OBJECT_TYPE_UNIT) {
- Unit u = Unit(_db, _id);
- p.set_union_value(u.get_component_property_double(_component_id, def.name, (double)def.deffault));
- } else {
- p.set_union_value(_db.get_property_double(_id, def.name, (double)def.deffault));
- }
- } else if (def.type == PropertyType.STRING) {
- if (_db.object_type(_id) == OBJECT_TYPE_UNIT) {
- Unit u = Unit(_db, _id);
- p.set_union_value(u.get_component_property_string(_component_id, def.name, (string)def.deffault));
- } else {
- p.set_union_value(_db.get_property_string(_id, def.name, (string)def.deffault));
- }
- } else if (def.type == PropertyType.GUID) {
- if (_db.object_type(_id) == OBJECT_TYPE_UNIT) {
- Unit u = Unit(_db, _id);
- p.set_union_value(u.get_component_property_guid(_component_id, def.name, (Guid)def.deffault));
- } else {
- p.set_union_value(_db.get_property_guid(_id, def.name, (Guid)def.deffault));
- }
- } else if (def.type == PropertyType.VECTOR3) {
- if (_db.object_type(_id) == OBJECT_TYPE_UNIT) {
- Unit u = Unit(_db, _id);
- p.set_union_value(u.get_component_property_vector3(_component_id, def.name, (Vector3)def.deffault));
- } else {
- p.set_union_value(_db.get_property_vector3(_id, def.name, (Vector3)def.deffault));
- }
- } else if (def.type == PropertyType.QUATERNION) {
- if (_db.object_type(_id) == OBJECT_TYPE_UNIT) {
- Unit u = Unit(_db, _id);
- p.set_union_value(u.get_component_property_quaternion(_component_id, def.name, (Quaternion)def.deffault));
- } else {
- p.set_union_value(_db.get_property_quaternion(_id, def.name, (Quaternion)def.deffault));
- }
- } else {
- loge("Unknown property value type");
- }
- }
- }
- }
- public class PropertyGridSet : Gtk.Box
- {
- public Gtk.ListBox _list_box;
- public PropertyGridSet()
- {
- Object(orientation: Gtk.Orientation.VERTICAL, spacing: 0);
- _list_box = new Gtk.ListBox();
- _list_box.selection_mode = Gtk.SelectionMode.NONE;
- _list_box.margin_bottom
- = this.margin_end
- = this.margin_start
- = this.margin_top
- = 12
- ;
- _list_box.set_sort_func(sort_function);
- _list_box.set_filter_func(filter_function);
- this.pack_start(_list_box);
- }
- public static int sort_function(Gtk.ListBoxRow row1, Gtk.ListBoxRow row2)
- {
- Expander e1 = (Expander)row1.get_child();
- Expander e2 = (Expander)row2.get_child();
- double order = ((PropertyGrid)e1._child)._order - ((PropertyGrid)e2._child)._order;
- return (int)order;
- }
- public static bool filter_function(Gtk.ListBoxRow row)
- {
- Expander e = (Expander)row.get_child();
- return ((PropertyGrid)e._child)._visible;
- }
- public Expander add_property_grid(PropertyGrid cv, string label)
- {
- Gtk.Label l = new Gtk.Label(null);
- l.set_markup("<b>%s</b>".printf(label));
- l.xalign = 0.0f;
- l.yalign = 0.5f;
- Expander e = new Expander();
- e.custom_header = l;
- e.expanded = true;
- e.add(cv);
- Gtk.ListBoxRow row = new Gtk.ListBoxRow();
- row.can_focus = false;
- row.add(e);
- _list_box.add(row);
- return e;
- }
- public Expander add_property_grid_optional(PropertyGrid cv, string label, InputBool InputBool)
- {
- Gtk.Label l = new Gtk.Label(null);
- l.set_markup("<b>%s</b>".printf(label));
- l.xalign = 0.0f;
- l.yalign = 0.5f;
- Gtk.Box b = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 6);
- b.pack_start(InputBool, false, false);
- b.pack_start(l, false, false);
- Expander e = new Expander();
- e.custom_header = b;
- e.expanded = true;
- e.add(cv);
- Gtk.ListBoxRow row = new Gtk.ListBoxRow();
- row.can_focus = false;
- row.add(e);
- _list_box.add(row);
- return e;
- }
- }
- } /* namespace Crown */
|