| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181 |
- /*
- * Copyright (c) 2012-2025 Daniele Bartolini et al.
- * SPDX-License-Identifier: GPL-3.0-or-later
- */
- using Gtk;
- namespace Crown
- {
- public class ComboBoxMap : Gtk.ComboBox, Property
- {
- // Data
- public bool _stop_emit;
- public bool _inconsistent;
- public Gtk.ListStore _store;
- public Gtk.TreeModelFilter _filter;
- // Signals
- public signal void value_changed();
- public void set_inconsistent(bool inconsistent)
- {
- if (_inconsistent != inconsistent) {
- _inconsistent = inconsistent;
- _filter.refilter();
- if (_inconsistent) {
- _stop_emit = true;
- this.set_active_id(INCONSISTENT_ID);
- _stop_emit = false;
- }
- }
- }
- public bool is_inconsistent()
- {
- return _inconsistent;
- }
- public Value? generic_value()
- {
- return this.value;
- }
- public void set_generic_value(Value? val)
- {
- this.value = (string)val;
- }
- public string? value
- {
- get
- {
- return this.get_active_id();
- }
- set
- {
- _stop_emit = true;
- _filter.refilter();
- bool success = this.set_active_id((string)value);
- _stop_emit = false;
- set_inconsistent(!success);
- }
- }
- public bool filter_visible_func(Gtk.TreeModel model, Gtk.TreeIter iter)
- {
- Value id_val;
- model.get_value(iter, 0, out id_val);
- if (!_inconsistent && (string)id_val == INCONSISTENT_ID)
- return false;
- return true;
- }
- public ComboBoxMap(int default_id = 0, string[]? labels = null, string[]? ids = null)
- {
- // Data
- _stop_emit = false;
- _inconsistent = false;
- _store = new Gtk.ListStore(2
- , typeof(string) // ID
- , typeof(string) // Label
- );
- _filter = new Gtk.TreeModelFilter(_store, null);
- _filter.set_visible_func(filter_visible_func);
- this.model = _filter;
- this.id_column = 0;
- this.entry_text_column = 1;
- Gtk.CellRendererText renderer = new Gtk.CellRendererText();
- this.pack_start(renderer, true);
- this.add_attribute(renderer, "text", 1);
- insert_special_values();
- if (labels != null) {
- Gtk.TreeIter iter;
- for (int ii = 0; ii < ids.length; ++ii) {
- unowned string? id = ids != null ? ids[ii] : null;
- _store.insert_with_values(out iter, -1, 0, id, 1, labels[ii], -1);
- }
- if (ids != null && default_id < ids.length)
- this.value = ids[default_id];
- }
- // Widgets
- this.changed.connect(on_changed);
- this.scroll_event.connect(on_scroll);
- }
- public void append(string? id, string label)
- {
- Gtk.TreeIter iter;
- _store.insert_with_values(out iter, -1, 0, id, 1, label, -1);
- }
- public void clear()
- {
- _stop_emit = true;
- _store.clear();
- insert_special_values();
- _inconsistent = false;
- _stop_emit = false;
- }
- public string any_valid_id()
- {
- string some_id = INCONSISTENT_ID;
- if (_store.iter_n_children(null) > 1u) {
- _store.foreach((model, path, iter) => {
- Value id_val;
- model.get_value(iter, 0, out id_val);
- if ((string)id_val != INCONSISTENT_ID) {
- some_id = (string)id_val;
- return true;
- }
- return false;
- });
- }
- return some_id;
- }
- private void on_changed()
- {
- if (_inconsistent && this.get_active_id() == INCONSISTENT_ID)
- return;
- if (!_stop_emit) {
- if (_inconsistent) {
- _inconsistent = false;
- _filter.refilter();
- }
- value_changed();
- }
- }
- private bool on_scroll(Gdk.EventScroll ev)
- {
- GLib.Signal.stop_emission_by_name(this, "scroll-event");
- return Gdk.EVENT_PROPAGATE;
- }
- private void insert_special_values()
- {
- assert(_store.iter_n_children(null) == 0u);
- // Insert the "inconsistent" ID and label.
- Gtk.TreeIter iter;
- _store.insert_with_values(out iter, -1, 0, INCONSISTENT_ID, 1, INCONSISTENT_LABEL, -1);
- }
- }
- } /* namespace Crown */
|