summaryrefslogtreecommitdiff
path: root/lib/astal/gtk3/src/widget/widget.vala
diff options
context:
space:
mode:
authorAylur <[email protected]>2024-10-14 16:45:03 +0000
committerAylur <[email protected]>2024-10-14 16:45:03 +0000
commit9fab13452a26ed55c01047d4225f699f43bba20d (patch)
tree8dc3097994e8664572c3a94a62257604bdaa1f8d /lib/astal/gtk3/src/widget/widget.vala
parent6a8c41cd1d5e218d0dacffb836fdd7d4ec6333dd (diff)
feat: Astal3
Diffstat (limited to 'lib/astal/gtk3/src/widget/widget.vala')
-rw-r--r--lib/astal/gtk3/src/widget/widget.vala157
1 files changed, 157 insertions, 0 deletions
diff --git a/lib/astal/gtk3/src/widget/widget.vala b/lib/astal/gtk3/src/widget/widget.vala
new file mode 100644
index 0000000..2506bc8
--- /dev/null
+++ b/lib/astal/gtk3/src/widget/widget.vala
@@ -0,0 +1,157 @@
+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);
+}
+
+private class ClickThrough {
+ private static HashTable<Gtk.Widget, bool> _click_through;
+ public static HashTable<Gtk.Widget, bool> click_through {
+ get {
+ if (_click_through == null) {
+ _click_through = new HashTable<Gtk.Widget, bool>(
+ (w) => (uint)w,
+ (a, b) => a == b);
+ }
+ return _click_through;
+ }
+ }
+}
+
+public void widget_set_click_through(Gtk.Widget widget, bool click_through) {
+ ClickThrough.click_through.set(widget, click_through);
+ widget.input_shape_combine_region(click_through ? new Cairo.Region() : null);
+}
+
+public bool widget_get_click_through(Gtk.Widget widget) {
+ return ClickThrough.click_through.get(widget);
+}
+}