finished application laucnher and bluetooth widget

This commit is contained in:
Rene Kievits
2022-11-27 10:58:27 +01:00
parent c6341f84e7
commit 10f56a7273
77 changed files with 2379 additions and 4938 deletions

View File

@@ -8,16 +8,15 @@
---------------------------------------------------------------------------
local setmetatable = setmetatable
local abutton = require("awful.button")
local beautiful = require("beautiful")
local gtable = require("gears.table")
local base = require("wibox.widget.base")
local gstring = require("gears.string")
local keygrabber = require("awful.keygrabber")
local wtemplate = require("wibox.template")
local akeygrabber = require("awful.keygrabber")
local akey = require("awful.key")
local textbox = require("wibox.widget.textbox")
local capi =
{
local capi = {
selection = selection,
mousegrabber = mousegrabber,
mouse = mouse,
@@ -31,8 +30,7 @@ local function text_with_cursor(text, cursor_pos, self)
local cursor_fg = beautiful.inputbox_cursor_fg or "#313131"
local cursor_bg = beautiful.inputbox_cursor_bg or "#0dccfc"
local text_color = beautiful.inputbox_fg or "#ffffff"
local placeholder_text = beautiful.inputbox_placeholder_text or "Type here..."
local placeholder_text = self.hint_text or ""
local placeholder_fg = beautiful.inputbox_placeholder_fg or "#777777"
local highlight_bg = beautiful.inputbox_highlight_bg or "#35ffe4"
local highlight_fg = beautiful.inputbox_highlight_fg or "#000000"
@@ -41,16 +39,17 @@ local function text_with_cursor(text, cursor_pos, self)
return "<span foreground='" .. placeholder_fg .. "'>" .. placeholder_text .. "</span>"
end
local offset = 0
if text:sub(cursor_pos - 1, cursor_pos - 1) == -1 then
offset = 1
end
if #text < cursor_pos then
char = " "
spacer = ""
text_start = gstring.xml_escape(text)
text_end = ""
else
local offset = 0
if #text:sub(cursor_pos, cursor_pos) == -1 then
offset = 1
end
char = gstring.xml_escape(text:sub(cursor_pos, cursor_pos + offset))
spacer = " "
text_start = gstring.xml_escape(text:sub(1, cursor_pos - 1))
@@ -64,14 +63,12 @@ local function text_with_cursor(text, cursor_pos, self)
self._private.highlight.cur_pos_end))
local text_end_highlight = gstring.xml_escape(text:sub(self._private.highlight.cur_pos_end + 1))
return "<span foreground='" .. text_color .. "'>" .. text_start_highlight .. "</span>" ..
return text_start_highlight ..
"<span foreground='" .. highlight_fg .. "' background='" .. highlight_bg .. "'>" ..
text_highlighted ..
"</span>" .. "<span foreground='" .. text_color .. "'>" .. text_end_highlight .. "</span>"
text_highlighted .. "</span>" .. text_end_highlight
else
return "<span foreground='" .. text_color .. "'>" .. text_start .. "</span>" ..
"<span background='" .. cursor_bg .. "' foreground='" .. cursor_fg .. "'>" ..
char .. "</span>" .. "<span foreground='" .. text_color .. "'>" .. text_end .. spacer .. "</span>"
return text_start .. "<span background='" .. cursor_bg .. "' foreground='" .. cursor_fg .. "'>" ..
char .. "</span>" .. text_end .. spacer
end
end
@@ -91,99 +88,6 @@ end
inputbox.set_widget = base.set_widget_common
function inputbox:set_widget_template(widget_template)
self._private.widget_template = widget_template
self:set_widget(widget_template)
end
function inputbox:get_widget()
return self._private.widget
end
function inputbox:get_children()
return { self._private.widget }
end
function inputbox:set_children(children)
self:set_widget(children[1])
end
function inputbox:reset()
self._private.widget_template = nil
self:set_widget(nil)
end
--- The inputbox border color
--
-- @DOC_awful_widget_inputbox_border_color_EXAMPLE@
--
-- @property border_color
-- @tparam[opt=gears.color] string border_color
-- @see gears.color
-- @propemits true false
-- @propbeautiful
function inputbox:set_border_color(v)
self._private.border_color = v
self:emit_signal("property::border_color", v)
end
--- The inputbox border width
--
-- @DOC_awful_widget_inputbox_border_width_EXAMPLE@
--
-- @property border_width
-- @tparam[opt=0] number|nil border_width
-- @negativeallowed false
-- @propertyunit pixel
-- @propemits true false
-- @propbeautiful
function inputbox:set_border_width(v)
self._private.border_width = v
self:emit_signal("property::border_width", v)
end
--- The inputbox background color
--
-- @DOC_awful_widget_inputbox_bg_EXAMPLE@
--
-- @property bg
-- @tparam[opt=gears.color] string foreground
-- @see gears.color
-- @propemits true false
-- @propbeautiful
function inputbox:set_bg(v)
self._private.bg = v
self:emit_signal("property::bg", v)
end
--- The text foreground color
--
-- @DOC_awful_widget_inputbox_fg_EXAMPLE@
--
-- @property string
-- @tparam[opt=gears.color] string foreground
-- @see gears.color
-- @propemits true false
-- @propbeautiful
function inputbox:set_fg(v)
self._private.fg = v
self:emit_signal("property::fg", v)
end
--- The shape of the inputbox
--
-- @DOC_awful_widget_inputbox_shape_EXAMPLE@
--
-- @property shape
-- @tparam[opt=gears.shape.rectangle] shape|nil shape
-- @see gears.shape
-- @propemits true false
-- @propbeautiful
function inputbox:set_shape(v)
self._private.shape = v
self:emit_signal("property::shape", v)
end
--- Clears the current text
function inputbox:clear()
self:set_text("")
@@ -195,35 +99,23 @@ end
function inputbox:set_text(text)
self._private.text = text
self.markup = text_with_cursor(self:get_text(), #self:get_text(), self)
self:emit_signal("property::text", text)
end
--- Stop the keygrabber and mousegrabber
function inputbox:stop()
if (not self.akeygrabber) or (not self.akeygrabber.is_running) then return end
self:emit_signal("stopped")
keygrabber.stop()
capi.mousegrabber.stop()
self.akeygrabber.stop()
end
function inputbox:focus()
keygrabber.stop()
if not keygrabber.is_running then
if (not self.akeygrabber) or (not self.akeygrabber.is_running) then
akeygrabber.stop()
self:run()
end
-- Stops the mousegrabber when not clicked on the widget
--[[ capi.mousegrabber.run(
function(m)
if m.buttons[1] then
if capi.mouse.current_wibox ~= self:get_widget().widget then
self:emit_signal("keygrabber::stop", "")
return false
end
end
return true
end, "left_ptr"
) ]]
self:connect_signal("button::press", function()
if capi.mouse.current_widget ~= self then
self:emit_signal("keygrabber::stop", "")
@@ -231,226 +123,293 @@ function inputbox:focus()
end)
end
--[[ local function widget_update(text, cursor_pos, widget)
text = text or ""
cursor_pos = cursor_pos or 1
widget:set_text(text)
widget:emit_signal("property::markup", text)
end ]]
--- Init the inputbox and start the keygrabber
function inputbox:run()
if not self._private.text then self._private.text = "" end
-- Init the cursor position, but causes on refocus the cursor to move to the left
local cursor_pos = #self:get_text() + 1
self:emit_signal("started")
-- Init and reset(when refocused) the highlight
self._private.highlight = {}
-- Emitted when the keygrabber is stopped
self:connect_signal("cancel", function()
self:stop()
self:emit_signal("stopped")
end)
-- Emitted when the keygrabber should submit the text
self:connect_signal("submit", function(text)
self:stop()
self:emit_signal("stopped", text)
end)
self:emit_signal("key_pressed", "B", "A")
keygrabber.run(function(mod, key, event)
local mod_keys = {}
for _, v in ipairs(mod) do
mod_keys[v] = true
end
if not (event == "press") then return end
--Escape cases
-- Just quit and leave the text as is
if (not mod_keys.Control) and (key == "Escape") then
self:emit_signal("cancel")
elseif (not mod_keys.Control and key == "KP_Enter") or (not mod_keys.Control and key == "Return") then
self:emit_signal("submit", self:get_text())
self:set_text("")
end
-- All shift, control or key cases
if mod_keys.Shift then
if key == "Left" then
if cursor_pos > 1 then
if not self._private.highlight.cur_pos_start then
self._private.highlight.cur_pos_start = cursor_pos - 1
end
if not self._private.highlight.cur_pos_end then
self._private.highlight.cur_pos_end = cursor_pos
end
if self._private.highlight.cur_pos_start < cursor_pos then
self._private.highlight.cur_pos_end = self._private.highlight.cur_pos_end - 1
else
self._private.highlight.cur_pos_start = self._private.highlight.cur_pos_start - 1
end
cursor_pos = cursor_pos - 1
end
elseif key == "Right" then
if #self._private.text >= cursor_pos then
if not self._private.highlight.cur_pos_end then
self._private.highlight.cur_pos_end = cursor_pos - 1
end
if not self._private.highlight.cur_pos_start then
self._private.highlight.cur_pos_start = cursor_pos
end
if self._private.highlight.cur_pos_end <= cursor_pos then
self._private.highlight.cur_pos_end = self._private.highlight.cur_pos_end + 1
else
self._private.highlight.cur_pos_start = self._private.highlight.cur_pos_start + 1
end
cursor_pos = cursor_pos + 1
if cursor_pos > #self._private.text + 1 then
self._private.highlight = {}
end
end
self.akeygrabber = akeygrabber {
autostart = true,
start_callback = function()
self:emit_signal("started")
end,
stop_callback = function(_, stop_key)
if stop_key == "Return" then
self:emit_signal("submit", self:get_text(), stop_key)
-- Only reset text on enter as on escape you might want to continue later
self:set_text("")
else
self:emit_signal("stopped", stop_key)
end
end,
stop_key = { "Escape", "Return" },
keybindings = {
--lShift, rShift = #50, #62
--lControl, rControl = #37, #105
akey {
modifiers = { "Shift" },
key = "Left", -- left
on_press = function()
if cursor_pos > 1 then
local offset = (self._private.text:sub(cursor_pos - 1, cursor_pos - 1):wlen() == -1) and 1 or 0
if not self._private.highlight.cur_pos_start then
self._private.highlight.cur_pos_start = cursor_pos - 1
end
if not self._private.highlight.cur_pos_end then
self._private.highlight.cur_pos_end = cursor_pos
end
if self._private.highlight.cur_pos_start < cursor_pos then
self._private.highlight.cur_pos_end = self._private.highlight.cur_pos_end - 1
else
self._private.highlight.cur_pos_start = self._private.highlight.cur_pos_start
end
cursor_pos = cursor_pos - 1
end
if cursor_pos < 1 then
cursor_pos = 1
elseif cursor_pos > #self._private.text + 1 then
cursor_pos = #self._private.text + 1
end
self.markup = text_with_cursor(self:get_text(), cursor_pos, self)
self:emit_signal("inputbox::key_pressed", "Shift", "Left")
end
},
akey {
modifiers = { "Shift" },
key = "Right", -- right
on_press = function()
if #self._private.text >= cursor_pos then
if not self._private.highlight.cur_pos_end then
self._private.highlight.cur_pos_end = cursor_pos - 1
end
if not self._private.highlight.cur_pos_start then
self._private.highlight.cur_pos_start = cursor_pos
end
if self._private.highlight.cur_pos_end <= cursor_pos then
self._private.highlight.cur_pos_end = self._private.highlight.cur_pos_end + 1
else
self._private.highlight.cur_pos_start = self._private.highlight.cur_pos_start + 1
end
cursor_pos = cursor_pos + 1
if cursor_pos > #self._private.text + 1 then
self._private.highlight = {}
end
end
if cursor_pos < 1 then
cursor_pos = 1
elseif cursor_pos > #self._private.text + 1 then
cursor_pos = #self._private.text + 1
end
self.markup = text_with_cursor(self:get_text(), cursor_pos, self)
self:emit_signal("inputbox::key_pressed", "Shift", "Right")
end
},
akey {
modifiers = { "Control" },
key = "a", -- a
on_press = function()
-- Mark the entire text
self._private.highlight = {
cur_pos_start = 1,
cur_pos_end = #self._private.text
}
self.markup = text_with_cursor(self:get_text(), cursor_pos, self)
self:emit_signal("inputbox::key_pressed", "Control", "a")
end
},
akey {
modifiers = { "Control" },
key = "v", -- v
on_press = function()
local sel = capi.selection()
if sel then
sel = sel:gsub("\n", "")
if self._private.highlight and self._private.highlight.cur_pos_start and
self._private.highlight.cur_pos_end then
-- insert the text into the selected part
local text_start = self._private.text:sub(1, self._private.highlight.cur_pos_start - 1)
local text_end = self._private.text:sub(self._private.highlight.cur_pos_end + 1)
self:set_text(text_start .. sel .. text_end)
self._private.highlight = {}
cursor_pos = #text_start + #sel + 1
else
self:set_text(self._private.text:sub(1, cursor_pos - 1) ..
sel .. self._private.text:sub(cursor_pos))
cursor_pos = cursor_pos + #sel
end
end
self.markup = text_with_cursor(self:get_text(), cursor_pos, self)
self:emit_signal("inputbox::key_pressed", "Control", "v")
end
},
akey {
modifiers = { "Control" },
key = "c", -- c
on_press = function()
--TODO
end
},
akey {
modifiers = { "Control" },
key = "x", -- x
on_press = function()
--TODO
end
},
akey {
modifiers = { "Control" },
key = "Left", -- left
on_press = function()
-- Find all spaces
local spaces = {}
local t, i = self._private.text, 0
while t:find("%s") do
i = t:find("%s")
table.insert(spaces, i)
t = t:sub(1, i - 1) .. "-" .. t:sub(i + 1)
end
local cp = 1
for _, v in ipairs(spaces) do
if (v < cursor_pos) then
cp = v
end
end
cursor_pos = cp
if cursor_pos < 1 then
cursor_pos = 1
elseif cursor_pos > #self._private.text + 1 then
cursor_pos = #self._private.text + 1
end
self.markup = text_with_cursor(self:get_text(), cursor_pos, self)
self:emit_signal("inputbox::key_pressed", "Control", "Left")
end
},
akey {
modifiers = { "Control" },
key = "Right", -- right
on_press = function()
local next_space = self._private.text:sub(cursor_pos):find("%s")
if next_space then
cursor_pos = cursor_pos + next_space
else
cursor_pos = #self._private.text + 1
end
if cursor_pos < 1 then
cursor_pos = 1
elseif cursor_pos > #self._private.text + 1 then
cursor_pos = #self._private.text + 1
end
self.markup = text_with_cursor(self:get_text(), cursor_pos, self)
self:emit_signal("inputbox::key_pressed", "Control", "Right")
end
},
akey {
modifiers = {},
key = "BackSpace", --BackSpace
on_press = function()
-- If text is highlighted delete that, else just delete the character to the left
if self._private.highlight and self._private.highlight.cur_pos_start and
self._private.highlight.cur_pos_end then
local text_start = self._private.text:sub(1, self._private.highlight.cur_pos_start - 1)
local text_end = self._private.text:sub(self._private.highlight.cur_pos_end + 1)
self:set_text(text_start .. text_end)
self._private.highlight = {}
cursor_pos = #text_start + 1
else
if cursor_pos > 1 then
local offset = (self._private.text:sub(cursor_pos - 1, cursor_pos - 1):wlen() == -1) and 1 or
0
self:set_text(self._private.text:sub(1, cursor_pos - 2 - offset) ..
self._private.text:sub(cursor_pos))
cursor_pos = cursor_pos - 1 - offset
end
end
self.markup = text_with_cursor(self:get_text(), cursor_pos, self)
self:emit_signal("inputbox::key_pressed", nil, "BackSpace")
end
},
akey {
modifiers = {},
key = "Delete", --delete
on_press = function()
-- If text is highlighted delete that, else just delete the character to the right
if self._private.highlight and self._private.highlight.cur_pos_start and
self._private.highlight.cur_pos_end then
local text_start = self._private.text:sub(1, self._private.highlight.cur_pos_start - 1)
local text_end = self._private.text:sub(self._private.highlight.cur_pos_end + 1)
self:set_text(text_start .. text_end)
self._private.highlight = {}
cursor_pos = #text_start + 1
else
if cursor_pos <= #self._private.text then
self:set_text(self._private.text:sub(1, cursor_pos - 1) ..
self._private.text:sub(cursor_pos + 1))
end
end
self.markup = text_with_cursor(self:get_text(), cursor_pos, self)
self:emit_signal("inputbox::key_pressed", nil, "Delete")
end
},
akey {
modifiers = {},
key = "Left", --left
on_press = function()
-- Move cursor ro the left
if cursor_pos > 1 then
cursor_pos = cursor_pos - 1
end
self._private.highlight = {}
end
},
akey {
modifiers = {},
key = "Right", --right
on_press = function()
-- Move cursor to the right
if cursor_pos <= #self._private.text then
cursor_pos = cursor_pos + 1
end
self._private.highlight = {}
end
},
--self.keybindings
},
keypressed_callback = function(_, modifiers, key)
if modifiers[1] == "Shift" then
if key:wlen() == 1 then
self:set_text(self._private.text:sub(1, cursor_pos - 1) ..
string.upper(key) .. self._private.text:sub(cursor_pos))
cursor_pos = cursor_pos + 1
cursor_pos = cursor_pos + #key
end
end
elseif mod_keys.Control then
if key == "a" then
-- Mark the entire text
self._private.highlight = {
cur_pos_start = 1,
cur_pos_end = #self._private.text
}
elseif key == "c" then
-- TODO: Copy the highlighted text when the selection setter gets implemented
elseif key == "v" then
local sel = capi.selection()
if sel then
sel = sel:gsub("\n", "")
if self._private.highlight and self._private.highlight.cur_pos_start and
self._private.highlight.cur_pos_end then
-- insert the text into the selected part
local text_start = self._private.text:sub(1, self._private.highlight.cur_pos_start - 1)
local text_end = self._private.text:sub(self._private.highlight.cur_pos_end + 1)
self:set_text(text_start .. sel .. text_end)
self._private.highlight = {}
cursor_pos = #text_start + #sel + 1
else
self:set_text(self._private.text:sub(1, cursor_pos - 1) ..
sel .. self._private.text:sub(cursor_pos))
cursor_pos = cursor_pos + #sel
end
end
elseif key == "x" then
--TODO: "cut". Copy selected then clear text, this requires to add the c function first.
self._private.highlight = {}
elseif key == "Left" then
-- Find all spaces
local spaces = {}
local t, i = self._private.text, 0
while t:find("%s") do
i = t:find("%s")
table.insert(spaces, i)
t = t:sub(1, i - 1) .. "-" .. t:sub(i + 1)
end
local cp = 1
for _, v in ipairs(spaces) do
if (v < cursor_pos) then
cp = v
end
end
cursor_pos = cp
elseif key == "Right" then
local next_space = self._private.text:sub(cursor_pos):find("%s")
if next_space then
cursor_pos = cursor_pos + next_space
else
cursor_pos = #self._private.text + 1
end
end
else
if key == "BackSpace" then
-- If text is highlighted delete that, else just delete the character to the left
if self._private.highlight and self._private.highlight.cur_pos_start and
self._private.highlight.cur_pos_end then
local text_start = self._private.text:sub(1, self._private.highlight.cur_pos_start - 1)
local text_end = self._private.text:sub(self._private.highlight.cur_pos_end + 1)
self:set_text(text_start .. text_end)
self._private.highlight = {}
cursor_pos = #text_start + 1
else
if cursor_pos > 1 then
self:set_text(self._private.text:sub(1, cursor_pos - 2) ..
self._private.text:sub(cursor_pos))
cursor_pos = cursor_pos - 1
end
end
elseif key == "Delete" then
-- If text is highlighted delete that, else just delete the character to the right
if self._private.highlight and self._private.highlight.cur_pos_start and
self._private.highlight.cur_pos_end then
local text_start = self._private.text:sub(1, self._private.highlight.cur_pos_start - 1)
local text_end = self._private.text:sub(self._private.highlight.cur_pos_end + 1)
self:set_text(text_start .. text_end)
self._private.highlight = {}
cursor_pos = #text_start + 1
else
if cursor_pos <= #self._private.text then
self:set_text(self._private.text:sub(1, cursor_pos - 1) ..
self._private.text:sub(cursor_pos + 1))
end
end
elseif key == "Left" then
-- Move cursor ro the left
if cursor_pos > 1 then
cursor_pos = cursor_pos - 1
end
self._private.highlight = {}
elseif key == "Right" then
-- Move cursor to the right
if cursor_pos <= #self._private.text then
cursor_pos = cursor_pos + 1
end
self._private.highlight = {}
else
-- Print every alphanumeric key
-- It seems like gears.xmlescape doesn't support non alphanumeric characters
elseif modifiers[1] == "Mod2" or "" then
if key:wlen() == 1 then
self:set_text(self._private.text:sub(1, cursor_pos - 1) ..
key .. self._private.text:sub(cursor_pos))
cursor_pos = cursor_pos + 1
cursor_pos = cursor_pos + #key
end
end
-- Make sure the cursor cannot go out of bounds
if cursor_pos < 1 then
cursor_pos = 1
elseif cursor_pos > #self._private.text + 1 then
cursor_pos = #self._private.text + 1
end
self.markup = text_with_cursor(self:get_text(), cursor_pos, self)
self:emit_signal("inputbox::key_pressed", modifiers, key)
end
-- Update cycle
self:get_widget():update {
text = text_with_cursor(self:get_text(), cursor_pos, self)
}
-- using self:emit_signal... results in nil tables beeing send
awesome.emit_signal("inputbox::key_pressed", mod_keys, key)
end)
}
end
--- Creates a new inputbox widget
@@ -467,51 +426,16 @@ end
-- @treturn awful.widget.inputbox The inputbox widget.
-- @constructorfct awful.widget.inputbox
function inputbox.new(args)
-- directly pass a possible default text(this is not meant to be a hint)
local w = textbox()
local w = base.make_widget(nil, nil, { enable_properties = true })
--gtable.crush(w, args)
gtable.crush(w, inputbox, true)
w:set_widget(wtemplate.make_from_value(args.widget_template))
w.keybindings = args.keybindings or {}
w.hint_text = args.hint_text
w:buttons(
gtable.join {
abutton({}, 1, function()
w:focus()
end),
abutton({}, 3, function()
-- TODO: Figure out how to paste with highlighted support
-- Maybe with a signal?
end)
}
)
-- Change the cursor to "xterm" on hover over
local old_cursor, old_wibox
w:connect_signal(
"mouse::enter",
function()
local wid = capi.mouse.current_wibox
if wid then
old_cursor, old_wibox = wid.cursor, wid
wid.cursor = "xterm"
end
end
)
-- Change the cursor back once leaving the widget
w:connect_signal(
"mouse::leave",
function()
old_wibox.cursor = old_cursor
old_wibox = nil
end
)
-- Initialize the text and placeholder with a first update
w:get_widget():update {
text = text_with_cursor("", 1, w)
}
w.markup = args.text or text_with_cursor("", 1, w)
return w
end

View File

@@ -0,0 +1,163 @@
local base = require("wibox.widget.base")
local gtable = require("gears.table")
local gcolor = require("gears.color")
local dpi = require("beautiful").xresources.apply_dpi
local wibox = require("wibox")
local gshape = require("gears.shape")
local rubato = require("src.lib.rubato")
local abutton = require("awful.button")
local toggle_widget = { mt = {} }
function toggle_widget:layout(_, width, height)
if self._private.widget then
return { base.place_widget_at(self._private.widget, 0, 0, width, height) }
end
end
function toggle_widget:fit(context, width, height)
local w, h = 0, 0
if self._private.widget then
w, h = base.fit_widget(self, context, self._private.widget, width, height)
end
return w, h
end
toggle_widget.set_widget = base.set_widget_common
function toggle_widget:get_widget()
return self._private.widget
end
function toggle_widget:set_enabled()
self.active = true
self.toggle_button.border_color = self.color
self.newcolor = self.color
self.rubato_timed.target = 39
end
function toggle_widget:set_disabled()
self.active = not self.active
self.toggle_button.border_color = Theme_config.dnd.border_disabled
self.newcolor = Theme_config.dnd.disabled
self.rubato_timed.target = 5
end
function toggle_widget:toggle_animation(pos, color)
if pos > 39 then return end
return function(_, _, cr, width, height)
cr:set_source(gcolor(Theme_config.dnd.bg))
cr:paint()
cr:set_source(gcolor(color))
cr:move_to(pos, 0)
local x = pos
local y = 5
local newwidth = width / 2 - 10
local newheight = height - 10
local radius = height / 6.0
local degrees = math.pi / 180.0
cr:new_sub_path()
cr:arc(x + newwidth - radius, y + radius, radius, -90 * degrees, 0 * degrees)
cr:arc(x + newwidth - radius, y + newheight - radius, radius, 0 * degrees, 90 * degrees)
cr:arc(x + radius, y + newheight - radius, radius, 90 * degrees, 180 * degrees)
cr:arc(x + radius, y + radius, radius, 180 * degrees, 270 * degrees)
cr:close_path()
cr:fill()
end
end
function toggle_widget.new(args)
args = args or {}
local ret = base.make_widget(nil, nil, {
enable_properties = true,
})
gtable.crush(ret, toggle_widget, true)
ret.newcolor = Theme_config.dnd.disabled
ret.color = args.color
ret.toggle_button = wibox.widget {
{
widget = wibox.widget {
fit = function(_, width, height)
return width, height
end,
draw = ret:toggle_animation(0, ret.newcolor),
},
id = "background",
},
active = false,
widget = wibox.container.background,
bg = Theme_config.dnd.bg,
border_color = Theme_config.dnd.border_disabled,
border_width = dpi(2),
forced_height = args.size,
forced_width = args.size * 2,
shape = function(cr, width, height)
gshape.rounded_rect(cr, width, height, dpi(10))
end,
}
ret.rubato_timed = rubato.timed {
duration = 0.2,
pos = 5,
subscribed = function(pos)
ret.toggle_button:get_children_by_id("background")[1].draw = ret:toggle_animation(pos, ret.newcolor)
ret.toggle_button:emit_signal("widget::redraw_needed")
end
}
ret:set_widget(wibox.widget {
{
{
args.text and {
text = args.text,
valign = "center",
align = "center",
widget = wibox.widget.textbox,
id = "clearall"
} or nil,
ret.toggle_button,
spacing = args.text and dpi(10) or dpi(0),
layout = wibox.layout.fixed.horizontal,
id = "layout12"
},
id = "background4",
fg = args.fg,
shape = function(cr, width, height)
gshape.rounded_rect(cr, width, height, dpi(12))
end,
widget = wibox.container.background
},
id = "place",
widget = wibox.container.place,
valign = "bottom",
halign = "right",
})
ret.toggle_button:buttons(
gtable.join(
abutton({}, 1, function()
if ret.active then
ret:set_disabled()
else
ret:set_enabled()
end
ret:emit_signal("dnd::toggle", ret.active)
end
)
)
)
return ret
end
function toggle_widget.mt:__call(...)
return toggle_widget.new(...)
end
return setmetatable(toggle_widget, toggle_widget.mt)