diff options
author | Aylur <[email protected]> | 2024-05-19 02:39:53 +0200 |
---|---|---|
committer | Aylur <[email protected]> | 2024-05-19 02:39:53 +0200 |
commit | 1425b396b08f0e91d45bbd0f92b1309115c7c870 (patch) | |
tree | 8af1a899a14d8a01a9ef50e248c077b48aed25bc /lua/astal/widget.lua |
init 0.1.0
Diffstat (limited to 'lua/astal/widget.lua')
-rw-r--r-- | lua/astal/widget.lua | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/lua/astal/widget.lua b/lua/astal/widget.lua new file mode 100644 index 0000000..ade000e --- /dev/null +++ b/lua/astal/widget.lua @@ -0,0 +1,123 @@ +local lgi = require("lgi") +local Astal = lgi.require("Astal", "0.1") +local Gtk = lgi.require("Gtk", "3.0") +local GObject = lgi.require("GObject", "2.0") +local Binding = require("astal.binding") + +local function filter(tbl, fn) + local copy = {} + for key, value in pairs(tbl) do + if fn(value, key) then + copy[key] = value + end + end + return copy +end + +Gtk.Widget._attribute.css = { + get = Astal.widget_get_css, + set = Astal.widget_set_css, +} + +Gtk.Widget._attribute.class_name = { + get = function(self) + local result = "" + local strings = Astal.widget_set_class_names(self) + for i, str in ipairs(strings) do + result = result .. str + if i < #strings then + result = result .. " " + end + end + return result + end, + set = function(self, class_name) + local names = {} + for word in class_name:gmatch("%S+") do + table.insert(names, word) + end + Astal.widget_set_class_names(self, names) + end, +} + +Gtk.Widget._attribute.cursor = { + get = Astal.widget_get_cursor, + set = Astal.widget_set_cursor, +} + +Astal.Box._attribute.children = { + get = Astal.Box.get_children, + set = Astal.Box.set_children, +} + +local function astalify(ctor) + function ctor:hook(object, signalOrCallback, callback) + if type(object.subscribe) == "function" then + local unsub = object.subscribe(function(...) + signalOrCallback(self, ...) + end) + self.on_destroy = unsub + return + end + local id = object["on_" .. signalOrCallback](function(_, ...) + callback(self, ...) + end) + self.on_destroy = function() + GObject.signal_handler_disconnect(object, id) + end + end + + return function(tbl) + local bindings = {} + local setup = tbl.setup + + local visible + if type(tbl.visible) == "boolean" then + visible = tbl.visible + else + visible = true + end + + local props = filter(tbl, function(_, key) + return key ~= "visible" and key ~= "setup" + end) + + for prop, value in pairs(props) do + if getmetatable(value) == Binding then + bindings[prop] = value + props[prop] = value:get() + end + end + + local widget = ctor(props) + + for prop, binding in pairs(bindings) do + widget.on_destroy = binding:subscribe(function(v) + widget[prop] = v + end) + end + + widget.visible = visible + if type(setup) == "function" then + setup(widget) + end + return widget + end +end + +local Widget = { + astalify = astalify, + Box = astalify(Astal.Box), + Button = astalify(Astal.Button), + CenterBox = astalify(Astal.CenterBox), + Label = astalify(Gtk.Label), + Icon = astalify(Astal.Icon), + Window = astalify(Astal.Window), + EventBox = astalify(Astal.EventBox), +} + +return setmetatable(Widget, { + __call = function(_, ctor) + return astalify(ctor) + end, +}) |