summaryrefslogtreecommitdiff
path: root/src/widget/widget.vala
blob: de5ba0097dd1df9bf930714411a072e5fcb80edc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
namespace Astal {
private class Css {
    private static HashTable<Gtk.Widget, Gtk.CssProvider> _providers;
    public static HashTable<Gtk.Widget, Gtk.CssProvider> providers {
        get {
            if (_providers == null) {
                _providers = new HashTable<Gtk.Widget, Gtk.CssProvider>(
                    (w) => (uint)w,
                    (a, b) => a == b);
            }

            return _providers;
        }
    }
}

private void remove_provider(Gtk.Widget widget) {
    var providers = Css.providers;

    if (providers.contains(widget)) {
        var p = providers.get(widget);
        widget.get_style_context().remove_provider(p);
        providers.remove(widget);
        p.dispose();
    }
}

public void widget_set_css(Gtk.Widget widget, string css) {
    var providers = Css.providers;

    if (providers.contains(widget)) {
        remove_provider(widget);
    } else {
        widget.destroy.connect(() => {
            remove_provider(widget);
        });
    }

    var style = !css.contains("{") || !css.contains("}")
        ? "* { ".concat(css, "}") : css;

    var p = new Gtk.CssProvider();
    widget.get_style_context()
        .add_provider(p, Gtk.STYLE_PROVIDER_PRIORITY_USER);

    try {
        p.load_from_data(style, style.length);
        providers.set(widget, p);
    } catch (Error err) {
        warning(err.message);
    }
}

public string widget_get_css(Gtk.Widget widget) {
    var providers = Css.providers;

    if (providers.contains(widget))
        return providers.get(widget).to_string();

    return "";
}

public void widget_set_class_names(Gtk.Widget widget, string[] class_names) {
    foreach (var name in widget_get_class_names(widget))
        widget_toggle_class_name(widget, name, false);

    foreach (var name in class_names)
        widget_toggle_class_name(widget, name, true);
}

public List<weak string> widget_get_class_names(Gtk.Widget widget) {
    return widget.get_style_context().list_classes();
}

public void widget_toggle_class_name(
    Gtk.Widget widget,
    string class_name,
    bool condition = true
) {
    var c = widget.get_style_context();
    if (condition)
        c.add_class(class_name);
    else
        c.remove_class(class_name);
}

private class Cursor {
    private static HashTable<Gtk.Widget, string> _cursors;
    public static HashTable<Gtk.Widget, string> cursors {
        get {
            if (_cursors == null) {
                _cursors = new HashTable<Gtk.Widget, string>(
                    (w) => (uint)w,
                    (a, b) => a == b);
            }
            return _cursors;
        }
    }
}

private void widget_setup_cursor(Gtk.Widget widget) {
    widget.add_events(Gdk.EventMask.ENTER_NOTIFY_MASK);
    widget.add_events(Gdk.EventMask.LEAVE_NOTIFY_MASK);
    widget.enter_notify_event.connect(() => {
        widget.get_window().set_cursor(
            new Gdk.Cursor.from_name(
                Gdk.Display.get_default(),
                Cursor.cursors.get(widget)));
        return false;
    });
    widget.leave_notify_event.connect(() => {
        widget.get_window().set_cursor(
            new Gdk.Cursor.from_name(
                Gdk.Display.get_default(),
                "default"));
        return false;
    });
    widget.destroy.connect(() => {
        if (Cursor.cursors.contains(widget))
            Cursor.cursors.remove(widget);
    });
}

public void widget_set_cursor(Gtk.Widget widget, string cursor) {
    if (!Cursor.cursors.contains(widget))
        widget_setup_cursor(widget);

    Cursor.cursors.set(widget, cursor);
}

public string widget_get_cursor(Gtk.Widget widget) {
    return Cursor.cursors.get(widget);
}
}