dino/main/src/ui/util/label_hybrid.vala

194 lines
4.7 KiB
Vala

using Gee;
using Gtk;
namespace Dino.Ui.Util {
public class LabelHybrid : Widget {
public Stack stack = new Stack();
public Label label = new Label("") { max_width_chars=1, ellipsize=Pango.EllipsizeMode.END };
protected Button button = new Button() { has_frame=false };
internal virtual void init(Widget widget) {
this.layout_manager = new BinLayout();
stack.set_parent(this);
button.child = label;
stack.add_named(button, "label");
stack.add_named(widget, "widget");
button.clicked.connect(() => {
show_widget();
});
}
public void show_widget() {
stack.visible_child_name = "widget";
stack.get_child_by_name("widget").grab_focus();
}
public void show_label() {
stack.visible_child_name = "label";
}
public override void dispose() {
stack.unparent();
}
}
public class EntryLabelHybrid : LabelHybrid {
public string text {
get { return entry.text; }
set {
entry.text = value.dup();
update_label();
}
}
public bool visibility {
get { return entry.visibility; }
set { entry.visibility = value; }
}
public float xalign {
get { return label.xalign; }
set {
label.xalign = value;
entry.set_alignment(value);
}
}
private Entry? entry_;
public Entry entry {
get {
if (entry_ == null) {
entry_ = new Entry();
init(entry_);
}
return entry_;
}
set { entry_ = value; }
}
public EntryLabelHybrid.wrap(Entry e) {
init(e);
}
internal override void init(Widget widget) {
Entry? e = widget as Entry;
if (e == null) return;
entry = e;
base.init(entry);
update_label();
var key_events = new EventControllerKey();
key_events.key_released.connect(on_key_released);
entry.add_controller(key_events);
entry.changed.connect(update_label);
var focus_events = new EventControllerFocus();
focus_events.leave.connect(update_label);
entry.add_controller(focus_events);
}
private void on_key_released(uint keyval) {
if (keyval == Gdk.Key.Return) {
show_label();
}
}
private void on_focus_leave() {
show_label();
}
private void update_label() {
if (visibility) {
label.label = entry.text;
} else {
string filler = "";
for (int i = 0; i < entry.text.length; i++) filler += entry.get_invisible_char().to_string();
label.label = filler;
}
}
}
public class ComboBoxTextLabelHybrid : LabelHybrid {
public int active {
get { return combobox.active; }
set { combobox.active = value; }
}
public float xalign {
get { return label.xalign; }
set { label.xalign = value; }
}
private ComboBoxText combobox_;
public ComboBoxText combobox {
get {
if (combobox_ == null) {
combobox_ = new ComboBoxText();
init(combobox_);
}
return combobox_;
}
set { combobox_ = combobox; }
}
public ComboBoxTextLabelHybrid.wrap(ComboBoxText cb) {
combobox_ = cb;
init(cb);
}
public void append(string id, string text) { combobox.append(id, text); }
public string get_active_text() { return combobox.get_active_text(); }
internal override void init(Widget widget) {
ComboBoxText? combobox = widget as ComboBoxText; if (combobox == null) return;
base.init(combobox);
update_label();
combobox.changed.connect(() => {
update_label();
show_label();
});
button.clicked.connect(() => {
combobox.popup();
});
var focus_events = new EventControllerFocus();
focus_events.leave.connect(on_focus_leave);
combobox.add_controller(focus_events);
}
private void on_focus_leave() {
update_label();
show_label();
}
private void update_label() {
label.label = combobox.get_active_text();
}
}
public class LabelHybridGroup {
private Gee.List<LabelHybrid> hybrids = new ArrayList<LabelHybrid>();
public void add(LabelHybrid hybrid) {
hybrids.add(hybrid);
hybrid.notify["visible-child-name"].connect(() => {
if (hybrid.stack.visible_child_name == "label") return;
foreach (LabelHybrid h in hybrids) {
if (h != hybrid) {
h.stack.set_visible_child_name("label");
}
}
});
}
}
}