Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement conditional container #3648

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
109 changes: 109 additions & 0 deletions lib/wibox/container/conditional.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
---------------------------------------------------------------------------
-- A simple container that will hide its child widget based a
-- boolean state variable.
--
--@DOC_wibox_container_conditional_comparison_EXAMPLE@
--
-- @author Lucas Schwiderski
-- @copyright 2022 Lucas Schwiderski
-- @containermod wibox.container.conditional
-- @supermodule wibox.widget.base
---------------------------------------------------------------------------

local base = require("wibox.widget.base")
local gtable = require("gears.table")
local gobject = require("gears.object")

local conditional = { mt = {} }


function conditional:fit(context, width, height)
if not self._private.state then
return 0, 0
end

return base.fit_widget(self, context, self._private.widget, width, height)
end


function conditional:layout(_, width, height)
if not self._private.state then
return {}
end

return { base.place_widget_at(self._private.widget, 0, 0, width, height) }
end


--- The conditional state.
--
-- The child widget is shown or hidden based on this state.
--
-- @property state
-- @tparam boolean state
-- @propemits true false

function conditional:set_state(state)
state = not (not state)

if self._private.state == state then
return
end

self._private.state = state

self:emit_signal("widget::layout_changed")
self:emit_signal("property::state", state)
end

function conditional:get_state()
return self._private.state
end


--- The widget to be displayed based on the state.
-- @property widget
-- @tparam widget widget
-- @propemits true false
-- @interface container

conditional.set_widget = base.set_widget_common
function conditional:get_widget()
return self._private.widget
end


function conditional:set_children(widgets)
self:set_widget(widgets[1])
end

function conditional:get_children()
return { self._private.widget }
end


local function new(widget, state)
local ret = base.make_widget(nil, nil, { enable_properties = true})

gtable.crush(ret, conditional, true)
ret.widget_name = gobject.modulename(2)

ret._private.widget = widget

if type(state) == "boolean" then
ret._private.state = state
else
ret._private.state = true
end

return ret
end


function conditional.mt:__call(...)
return new(...)
end

return setmetatable(conditional, conditional.mt)

-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
1 change: 1 addition & 0 deletions lib/wibox/container/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ return setmetatable({
arcchart = require("wibox.container.arcchart");
place = require("wibox.container.place");
tile = require("wibox.container.tile");
conditional = require("wibox.container.conditional");
}, {__call = function(_, args) return base.make_widget_declarative(args) end})

-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
48 changes: 48 additions & 0 deletions spec/wibox/container/conditional_spec.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
---------------------------------------------------------------------------
-- @author Lucas Schwiderski
-- @copyright 2022 Lucas Schwiderski
---------------------------------------------------------------------------

local conditional = require("wibox.container.conditional")
local utils = require("wibox.test_utils")
local base = require("wibox.widget.base")
local p = require("wibox.widget.base").place_widget_at

describe("wibox.container.conditional", function()
it("implements the common API", function()
utils.test_container(conditional())
end)

describe("constructor", function()
it("applies arguments", function()
local inner = base.empty_widget()
local state = false
local widget = conditional(inner, state)

assert.is.equal(inner, widget.widget)
assert.is.equal(state, widget.state)
end)

it("defaults to state == true", function()
local widget = conditional()
assert.is_true(widget.state)
end)
end)

it("hides the child widget when state == false", function()
local inner = utils.widget_stub(10, 10)
local widget = conditional(inner)

assert.widget_fit(widget, { 10, 10 }, { 10, 10 })
assert.widget_layout(widget, { 10, 10 }, {
p(inner, 0, 0, 10, 10),
})

widget.state = false

assert.widget_fit(widget, { 10, 10 }, { 0, 0 })
assert.widget_layout(widget, { 0, 0 }, {})
end)
end)

-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
62 changes: 62 additions & 0 deletions tests/examples/wibox/container/conditional/comparison.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
--DOC_HIDE_START --DOC_GEN_IMAGE
local parent = ...
local wibox = require("wibox")
local beautiful = require("beautiful")

parent.spacing = 10

parent:add(wibox.widget {
layout = wibox.layout.fixed.vertical,
spacing = 2,
{
markup = "state == <b>true</b>",
widget = wibox.widget.textbox
},
--DOC_HIDE_END
{
{
{
text = "Hello, World!",
widget = wibox.widget.textbox,
},
state = true,
widget = wibox.container.conditional,
},
bg = beautiful.bg_normal,
widget = wibox.container.background,
},
--DOC_HIDE_START
})

parent:add(wibox.widget {
layout = wibox.layout.fixed.vertical,
spacing = 2,
{
markup = "state == <b>false</b>",
widget = wibox.widget.textbox
},
--DOC_HIDE_END
{
{ --DOC_HIDE
{
{
text = "Hello, World!",
widget = wibox.widget.textbox,
},
state = false,
widget = wibox.container.conditional,
},
--DOC_HIDE_START
strategy = "min",
width = 100,
height = 18,
widget = wibox.container.constraint,
},
--DOC_HIDE_END
bg = beautiful.bg_normal,
widget = wibox.container.background,
},
--DOC_HIDE_START
})

-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80