| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246 |
- /*
- * Copyright (c) 2012-2026 Daniele Bartolini et al.
- * SPDX-License-Identifier: GPL-3.0-or-later
- */
- namespace Crown
- {
- // Returns true if the item should be filtered out
- public bool user_filter(string type, string name)
- {
- return (type == OBJECT_TYPE_UNIT || type == OBJECT_TYPE_SOUND) && !name.has_prefix("core/");
- }
- public delegate bool UserFilter(string type, string name);
- public class ResourceChooser : Gtk.Box
- {
- // Data
- public Project _project;
- public Gtk.ListStore _list_store;
- public Gtk.Stack? _editor_stack;
- public RuntimeInstance? _resource_preview;
- public unowned UserFilter _user_filter;
- public string _name;
- // Widgets
- public EntrySearch _filter_entry;
- public Gtk.EventControllerKey _filter_entry_controller_key;
- public Gtk.TreeModelFilter _tree_filter;
- public Gtk.TreeModelSort _tree_sort;
- public Gtk.TreeView _tree_view;
- public Gtk.GestureMultiPress _tree_view_gesture_click;
- public Gtk.TreeSelection _tree_selection;
- public Gtk.ScrolledWindow _scrolled_window;
- // Signals
- public signal void resource_selected(string type, string name);
- public ResourceChooser(Project? project
- , ProjectStore project_store
- , Gtk.Stack? editor_stack = null
- , RuntimeInstance? resource_preview = null
- )
- {
- Object(orientation: Gtk.Orientation.VERTICAL, spacing: 0);
- // Data
- _project = project;
- _list_store = project_store._list_store;
- _editor_stack = editor_stack;
- _resource_preview = resource_preview;
- _user_filter = user_filter;
- // Widgets
- _filter_entry = new EntrySearch();
- _filter_entry.set_placeholder_text("Search...");
- _filter_entry.search_changed.connect(on_filter_entry_text_changed);
- _filter_entry_controller_key = new Gtk.EventControllerKey(_filter_entry);
- _filter_entry_controller_key.key_pressed.connect(on_filter_entry_key_pressed);
- _tree_filter = new Gtk.TreeModelFilter(_list_store, null);
- _tree_filter.set_visible_func((model, iter) => {
- Value type;
- Value name;
- model.get_value(iter, ProjectStore.Column.TYPE, out type);
- model.get_value(iter, ProjectStore.Column.NAME, out name);
- string type_str = (string)type;
- string name_str = (string)name;
- return type_str != null
- && name_str != null
- && _user_filter(type_str, name_str)
- && (_filter_entry.text.length == 0 || name_str.index_of(_filter_entry.text) > -1)
- ;
- });
- _tree_sort = new Gtk.TreeModelSort.with_model(_tree_filter);
- _tree_sort.set_default_sort_func((model, iter_a, iter_b) => {
- Value id_a;
- Value id_b;
- model.get_value(iter_a, ProjectStore.Column.NAME, out id_a);
- model.get_value(iter_b, ProjectStore.Column.NAME, out id_b);
- return strcmp((string)id_a, (string)id_b);
- });
- _tree_view = new Gtk.TreeView();
- _tree_view.insert_column_with_attributes(-1
- , "Name"
- , new Gtk.CellRendererText()
- , "text"
- , ProjectStore.Column.NAME
- , null
- );
- #if 0
- // For debugging.
- _tree_view.insert_column_with_attributes(-1
- , "Type"
- , new Gtk.CellRendererText()
- , "text"
- , ProjectStore.Column.TYPE
- , null
- );
- #endif
- _tree_view.model = _tree_sort;
- _tree_view.headers_visible = false;
- _tree_view.can_focus = false;
- _tree_view.row_activated.connect(on_row_activated);
- _tree_view_gesture_click = new Gtk.GestureMultiPress(_tree_view);
- _tree_view_gesture_click.set_button(0);
- _tree_view_gesture_click.released.connect(on_button_released);
- _tree_selection = _tree_view.get_selection();
- _tree_selection.set_mode(Gtk.SelectionMode.BROWSE);
- _tree_selection.changed.connect(on_tree_selection_changed);
- _scrolled_window = new Gtk.ScrolledWindow(null, null);
- _scrolled_window.add(_tree_view);
- _scrolled_window.set_size_request(300, 400);
- this.pack_start(_filter_entry, false, true, 0);
- if (_editor_stack != null)
- this.pack_start(_editor_stack, true, true, 0);
- this.pack_start(_scrolled_window, true, true, 0);
- this.unmap.connect(on_unmap);
- }
- public void on_row_activated(Gtk.TreePath path, Gtk.TreeViewColumn column)
- {
- Gtk.TreePath filter_path = _tree_sort.convert_path_to_child_path(path);
- Gtk.TreePath child_path = _tree_filter.convert_path_to_child_path(filter_path);
- Gtk.TreeIter iter;
- if (_list_store.get_iter(out iter, child_path)) {
- Value name;
- Value type;
- _list_store.get_value(iter, ProjectStore.Column.NAME, out name);
- _list_store.get_value(iter, ProjectStore.Column.TYPE, out type);
- _name = (string)name;
- resource_selected((string)type, (string)name);
- }
- }
- public void on_button_released(int n_press, double x, double y)
- {
- uint button = _tree_view_gesture_click.get_current_button();
- if (button == Gdk.BUTTON_PRIMARY) {
- int bx;
- int by;
- Gtk.TreePath path;
- _tree_view.convert_widget_to_bin_window_coords((int)x, (int)y, out bx, out by);
- if (_tree_view.get_path_at_pos(bx, by, out path, null, null, null)) {
- if (_tree_view.get_selection().path_is_selected(path)) {
- Gtk.TreePath filter_path = _tree_sort.convert_path_to_child_path(path);
- Gtk.TreePath child_path = _tree_filter.convert_path_to_child_path(filter_path);
- Gtk.TreeIter iter;
- if (_list_store.get_iter(out iter, child_path)) {
- Value name;
- Value type;
- _list_store.get_value(iter, ProjectStore.Column.NAME, out name);
- _list_store.get_value(iter, ProjectStore.Column.TYPE, out type);
- _name = (string)name;
- resource_selected((string)type, (string)name);
- }
- }
- }
- }
- }
- public void on_unmap()
- {
- _filter_entry.text = "";
- }
- public void on_filter_entry_text_changed()
- {
- _tree_selection.changed.disconnect(on_tree_selection_changed);
- _tree_filter.refilter();
- _tree_selection.changed.connect(on_tree_selection_changed);
- _tree_view.set_cursor(new Gtk.TreePath.first(), null, false);
- }
- public bool on_filter_entry_key_pressed(uint keyval, uint keycode, Gdk.ModifierType state)
- {
- Gtk.TreeModel model;
- Gtk.TreeIter iter;
- bool selected = _tree_selection.get_selected(out model, out iter);
- if (keyval == Gdk.Key.Down) {
- if (selected && model.iter_next(ref iter)) {
- _tree_selection.select_iter(iter);
- _tree_view.scroll_to_cell(model.get_path(iter), null, true, 1.0f, 0.0f);
- }
- return Gdk.EVENT_STOP;
- } else if (keyval == Gdk.Key.Up) {
- if (selected && model.iter_previous(ref iter)) {
- _tree_selection.select_iter(iter);
- _tree_view.scroll_to_cell(model.get_path(iter), null, true, 1.0f, 0.0f);
- }
- return Gdk.EVENT_STOP;
- } else if (keyval == Gdk.Key.Return) {
- if (selected) {
- Value name;
- Value type;
- model.get_value(iter, ProjectStore.Column.NAME, out name);
- model.get_value(iter, ProjectStore.Column.TYPE, out type);
- _name = (string)name;
- resource_selected((string)type, (string)name);
- }
- return Gdk.EVENT_STOP;
- }
- return Gdk.EVENT_PROPAGATE;
- }
- public void on_tree_selection_changed()
- {
- if (_editor_stack != null) {
- Gtk.TreeModel model;
- Gtk.TreeIter iter;
- if (_tree_selection.get_selected(out model, out iter)) {
- Value name;
- Value type;
- model.get_value(iter, ProjectStore.Column.NAME, out name);
- model.get_value(iter, ProjectStore.Column.TYPE, out type);
- _resource_preview.send_script(UnitPreviewApi.set_preview_resource((string)type, (string)name));
- _resource_preview.send(DeviceApi.frame());
- }
- }
- }
- public void set_type_filter(owned UserFilter filter)
- {
- _user_filter = filter;
- _tree_filter.refilter();
- }
- }
- } /* namespace Crown */
|