summaryrefslogtreecommitdiff
path: root/lua/astal/widget.lua
diff options
context:
space:
mode:
Diffstat (limited to 'lua/astal/widget.lua')
-rw-r--r--lua/astal/widget.lua123
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,
+})