Merge pull request #33 from Nooo37/tag-preview-feature
Add tag preview widget
This commit is contained in:
commit
5d9252e1c8
|
@ -12,5 +12,8 @@
|
|||
- Signals
|
||||
- [Playerctl](signals/pctl.md)
|
||||
|
||||
- Widgets
|
||||
- [Tag Preview](widgets/tag_preview.md)
|
||||
|
||||
- Extra
|
||||
- [Theme Variable Template](theme.md)
|
||||
|
|
|
@ -51,4 +51,15 @@ theme.mstab_tabbar_style = "default" -- style of the tabbar ("default", "
|
|||
theme.tabbar_color_close = "#f9929b" -- chnges the color of the close button
|
||||
theme.tabbar_color_min = "#fbdf90" -- chnges the color of the minimize button
|
||||
theme.tabbar_color_float = "#ccaced" -- chnges the color of the float button
|
||||
|
||||
-- tag preview widget
|
||||
theme.tag_preview_widget_border_radius = 0 -- Border radius of the widget (With AA)
|
||||
theme.tag_preview_client_border_radius = 0 -- Border radius of each client in the widget (With AA)
|
||||
theme.tag_preview_client_opacity = 0.5 -- Opacity of each client
|
||||
theme.tag_preview_client_bg = "#000000" -- The bg color of each client
|
||||
theme.tag_preview_client_border_color = "#ffffff" -- The border color of each client
|
||||
theme.tag_preview_client_border_width = 3 -- The border width of each client
|
||||
theme.tag_preview_widget_bg = "#000000" -- The bg color of the widget
|
||||
theme.tag_preview_widget_border_color = "#ffffff" -- The border color of the widget
|
||||
theme.tag_preview_widget_border_width = 3 -- The border width of the widget
|
||||
```
|
||||
|
|
|
@ -0,0 +1,137 @@
|
|||
## 🔍 Tag Preview <!-- {docsify-ignore} -->
|
||||
|
||||
This is a popup widget that will show a preview of a specified tag that illustrates the position, size, content, and icon of all clients.
|
||||
|
||||
![](https://imgur.com/3nYe1e8.gif)
|
||||
|
||||
*gif by [javacafe](https://github.com/JavaCafe01)*
|
||||
|
||||
### Usage
|
||||
|
||||
To enable:
|
||||
|
||||
```lua
|
||||
bling.widget.tag_preview.enable {
|
||||
show_client_content = false, -- Whether or not to show the client content
|
||||
x = 10, -- The x-coord of the popup
|
||||
y = 10, -- The y-coord of the popup
|
||||
scale = 0.25 -- The scale of the previews compared to the screen
|
||||
}
|
||||
```
|
||||
|
||||
Here are the signals available:
|
||||
|
||||
```lua
|
||||
-- bling::tag_preview::update -- first line is the signal
|
||||
-- t (tag) -- indented lines are function parameters
|
||||
-- bling::tag_preview::visibility
|
||||
-- s (screen)
|
||||
-- v (boolean)
|
||||
```
|
||||
|
||||
By default, the widget is not visible. You must implement when it will update and when it will show.
|
||||
|
||||
### Example Implementation
|
||||
|
||||
We can trigger the widget to show the specific tag when hovering over it in the taglist. The code shown below is the example taglist from the [AwesomeWM docs](https://awesomewm.org/doc/api/classes/awful.widget.taglist.html). Basically, we are going to update the widget and toggle it through the taglist's `create_callback`. (The bling addons are commented)
|
||||
```lua
|
||||
s.mytaglist = awful.widget.taglist {
|
||||
screen = s,
|
||||
filter = awful.widget.taglist.filter.all,
|
||||
style = {
|
||||
shape = gears.shape.powerline
|
||||
},
|
||||
layout = {
|
||||
spacing = -12,
|
||||
spacing_widget = {
|
||||
color = '#dddddd',
|
||||
shape = gears.shape.powerline,
|
||||
widget = wibox.widget.separator,
|
||||
},
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
},
|
||||
widget_template = {
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
id = 'index_role',
|
||||
widget = wibox.widget.textbox,
|
||||
},
|
||||
margins = 4,
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
bg = '#dddddd',
|
||||
shape = gears.shape.circle,
|
||||
widget = wibox.container.background,
|
||||
},
|
||||
{
|
||||
{
|
||||
id = 'icon_role',
|
||||
widget = wibox.widget.imagebox,
|
||||
},
|
||||
margins = 2,
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
{
|
||||
id = 'text_role',
|
||||
widget = wibox.widget.textbox,
|
||||
},
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
left = 18,
|
||||
right = 18,
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
id = 'background_role',
|
||||
widget = wibox.container.background,
|
||||
-- Add support for hover colors and an index label
|
||||
create_callback = function(self, c3, index, objects) --luacheck: no unused args
|
||||
self:get_children_by_id('index_role')[1].markup = '<b> '..index..' </b>'
|
||||
self:connect_signal('mouse::enter', function()
|
||||
|
||||
-- BLING: Only show widget when there are clients in the tag
|
||||
if #c3:clients() > 0 then
|
||||
-- BLING: Update the widget with the new tag
|
||||
awesome.emit_signal("bling::tag_preview::update", c3)
|
||||
-- BLING: Show the widget
|
||||
awesome.emit_signal("bling::tag_preview::visibility", mouse.screen, true)
|
||||
end
|
||||
|
||||
if self.bg ~= '#ff0000' then
|
||||
self.backup = self.bg
|
||||
self.has_backup = true
|
||||
end
|
||||
self.bg = '#ff0000'
|
||||
end)
|
||||
self:connect_signal('mouse::leave', function()
|
||||
|
||||
-- BLING: Turn the widget off
|
||||
awesome.emit_signal("bling::tag_preview::visibility", mouse.screen, false)
|
||||
|
||||
if self.has_backup then self.bg = self.backup end
|
||||
end)
|
||||
end,
|
||||
update_callback = function(self, c3, index, objects) --luacheck: no unused args
|
||||
self:get_children_by_id('index_role')[1].markup = '<b> '..index..' </b>'
|
||||
end,
|
||||
},
|
||||
buttons = taglist_buttons
|
||||
}
|
||||
```
|
||||
|
||||
### Theme Variables
|
||||
```lua
|
||||
theme.tag_preview_widget_border_radius = 0 -- Border radius of the widget (With AA)
|
||||
theme.tag_preview_client_border_radius = 0 -- Border radius of each client in the widget (With AA)
|
||||
theme.tag_preview_client_opacity = 0.5 -- Opacity of each client
|
||||
theme.tag_preview_client_bg = "#000000" -- The bg color of each client
|
||||
theme.tag_preview_client_border_color = "#ffffff" -- The border color of each client
|
||||
theme.tag_preview_client_border_width = 3 -- The border width of each client
|
||||
theme.tag_preview_widget_bg = "#000000" -- The bg color of the widget
|
||||
theme.tag_preview_widget_border_color = "#ffffff" -- The border color of the widget
|
||||
theme.tag_preview_widget_border_width = 3 -- The border width of the widget
|
||||
```
|
||||
|
||||
NOTE: I recommend to only use the widget border radius theme variable when not using shadows with a compositor, as anti-aliased rounding with the outer widgets made with AwesomeWM rely on the actual bg being transparent. If you want rounding with shadows on the widget, use a compositor like [jonaburg's fork](https://github.com/jonaburg/picom).
|
3
init.lua
3
init.lua
|
@ -5,5 +5,6 @@
|
|||
layout = require(... .. ".layout"),
|
||||
module = require(... .. ".module"),
|
||||
helpers = require(... .. ".helpers"),
|
||||
signal = require(... .. ".signal")
|
||||
signal = require(... .. ".signal"),
|
||||
widget = require(... .. ".widget")
|
||||
}
|
||||
|
|
|
@ -4,8 +4,7 @@ This file has all theme variables of the bling module.
|
|||
Every variable has a small comment on what it does.
|
||||
You might just want to copy that whole part into your theme.lua and start adjusting from there.
|
||||
|
||||
--]]
|
||||
|
||||
--]] -- LuaFormatter off
|
||||
|
||||
-- window swallowing
|
||||
theme.dont_swallow_classname_list = {"firefox", "Gimp"} -- list of class names that should not be swallowed
|
||||
|
@ -53,3 +52,14 @@ theme.tabbar_color_close = "#f9929b" -- chnges the color of the close but
|
|||
theme.tabbar_color_min = "#fbdf90" -- chnges the color of the minimize button
|
||||
theme.tabbar_color_float = "#ccaced" -- chnges the color of the float button
|
||||
|
||||
-- tag preview widget
|
||||
theme.tag_preview_widget_border_radius = 0 -- Border radius of the widget (With AA)
|
||||
theme.tag_preview_client_border_radius = 0 -- Border radius of each client in the widget (With AA)
|
||||
theme.tag_preview_client_opacity = 0.5 -- Opacity of each client
|
||||
theme.tag_preview_client_bg = "#000000" -- The bg color of each client
|
||||
theme.tag_preview_client_border_color = "#ffffff" -- The border color of each client
|
||||
theme.tag_preview_client_border_width = 3 -- The border width of each client
|
||||
theme.tag_preview_widget_bg = "#000000" -- The bg color of the widget
|
||||
theme.tag_preview_widget_border_color = "#ffffff" -- The border color of the widget
|
||||
theme.tag_preview_widget_border_width = 3 -- The border width of the widget
|
||||
-- LuaFormatter on
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
return {tag_preview = require(... .. ".tag_preview")}
|
|
@ -0,0 +1,180 @@
|
|||
-- bling::tag_preview::update -- first line is the signal
|
||||
-- t (tag) -- indented lines are function parameters
|
||||
-- bling::tag_preview::visibility
|
||||
-- s (screen)
|
||||
-- v (boolean)
|
||||
--
|
||||
local awful = require("awful")
|
||||
local wibox = require("wibox")
|
||||
local helpers = require(tostring(...):match(".*bling") .. ".helpers")
|
||||
local gears = require("gears")
|
||||
local beautiful = require("beautiful")
|
||||
local dpi = beautiful.xresources.apply_dpi
|
||||
local cairo = require("lgi").cairo
|
||||
|
||||
local function draw_widget(tag_preview_box, t, tag_preview_image, scale,
|
||||
prev_screen_width, prev_screen_height, screen_radius,
|
||||
client_radius, client_opacity, client_bg,
|
||||
client_border_color, client_border_width, widget_bg,
|
||||
widget_border_color, widget_border_width)
|
||||
|
||||
local client_list = wibox.layout.manual()
|
||||
client_list.forced_height = prev_screen_height
|
||||
client_list.forced_width = prev_screen_width
|
||||
for i, c in ipairs(t:clients()) do
|
||||
|
||||
local img_box = wibox.widget {
|
||||
image = gears.surface.load(c.icon),
|
||||
resize = true,
|
||||
forced_height = 100 * scale,
|
||||
forced_width = 100 * scale,
|
||||
widget = wibox.widget.imagebox
|
||||
}
|
||||
|
||||
if tag_preview_image then
|
||||
if c.prev_content or t.selected then
|
||||
local content
|
||||
if t.selected then
|
||||
content = gears.surface(c.content)
|
||||
else
|
||||
content = gears.surface(c.prev_content)
|
||||
end
|
||||
local cr = cairo.Context(content)
|
||||
local x, y, w, h = cr:clip_extents()
|
||||
local img = cairo.ImageSurface.create(cairo.Format.ARGB32,
|
||||
w - x, h - y)
|
||||
cr = cairo.Context(img)
|
||||
cr:set_source_surface(content, 0, 0)
|
||||
cr.operator = cairo.Operator.SOURCE
|
||||
cr:paint()
|
||||
|
||||
img_box = wibox.widget {
|
||||
image = gears.surface.load(img),
|
||||
resize = true,
|
||||
opacity = client_opacity,
|
||||
forced_height = math.floor(c.height * scale),
|
||||
forced_width = math.floor(c.width * scale),
|
||||
widget = wibox.widget.imagebox
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
local client_box = wibox.widget {
|
||||
{
|
||||
nil,
|
||||
{
|
||||
nil,
|
||||
img_box,
|
||||
nil,
|
||||
expand = "outside",
|
||||
layout = wibox.layout.align.horizontal
|
||||
},
|
||||
nil,
|
||||
expand = "outside",
|
||||
widget = wibox.layout.align.vertical
|
||||
},
|
||||
forced_height = math.floor(c.height * scale),
|
||||
forced_width = math.floor(c.width * scale),
|
||||
bg = client_bg,
|
||||
border_color = client_border_color,
|
||||
border_width = client_border_width,
|
||||
shape = helpers.shape.rrect(client_radius),
|
||||
widget = wibox.container.background
|
||||
}
|
||||
|
||||
client_box.point = {
|
||||
x = math.floor(c.x * scale),
|
||||
y = math.floor(c.y * scale)
|
||||
}
|
||||
|
||||
client_list:add(client_box)
|
||||
|
||||
end
|
||||
|
||||
tag_preview_box:setup{
|
||||
{
|
||||
{
|
||||
{
|
||||
client_list,
|
||||
forced_height = prev_screen_height,
|
||||
forced_width = prev_screen_width,
|
||||
bg = widget_bg,
|
||||
widget = wibox.container.background
|
||||
},
|
||||
layout = wibox.layout.align.horizontal
|
||||
},
|
||||
layout = wibox.layout.align.vertical
|
||||
},
|
||||
bg = widget_bg,
|
||||
border_width = widget_border_width,
|
||||
border_color = widget_border_color,
|
||||
shape = helpers.shape.rrect(screen_radius),
|
||||
widget = wibox.container.background
|
||||
}
|
||||
end
|
||||
|
||||
local enable = function(opts)
|
||||
local tag_preview_image = false
|
||||
local widget_x = dpi(20)
|
||||
local widget_y = dpi(20)
|
||||
local screen_radius = beautiful.tag_preview_widget_border_radius or dpi(0)
|
||||
local client_radius = beautiful.tag_preview_client_border_radius or dpi(0)
|
||||
local client_opacity = beautiful.tag_preview_client_opacity or 0.5
|
||||
local client_bg = beautiful.tag_preview_client_bg or "#000000"
|
||||
local client_border_color = beautiful.tag_preview_client_border_color or
|
||||
"#ffffff"
|
||||
local client_border_width = beautiful.tag_preview_client_border_width or
|
||||
dpi(3)
|
||||
local widget_bg = beautiful.tag_preview_widget_bg or "#000000"
|
||||
local widget_border_color = beautiful.tag_preview_widget_border_color or
|
||||
"#ffffff"
|
||||
local widget_border_width = beautiful.tag_preview_widget_border_width or
|
||||
dpi(3)
|
||||
|
||||
local scale = 0.2
|
||||
|
||||
if opts then
|
||||
tag_preview_image = opts.show_client_content or tag_preview_image
|
||||
widget_x = opts.x or widget_x
|
||||
widget_y = opts.y or widget_y
|
||||
scale = opts.scale or scale
|
||||
end
|
||||
|
||||
local prev_screen_width = math.floor(
|
||||
awful.screen.focused().geometry.width * scale)
|
||||
local prev_screen_height = math.floor(
|
||||
awful.screen.focused().geometry.height *
|
||||
scale)
|
||||
|
||||
local tag_preview_box = wibox({
|
||||
visible = false,
|
||||
ontop = true,
|
||||
width = prev_screen_width,
|
||||
height = prev_screen_height,
|
||||
input_passthrough = true,
|
||||
bg = "#00000000",
|
||||
x = widget_x,
|
||||
y = widget_y
|
||||
})
|
||||
|
||||
tag.connect_signal("property::selected", function(t)
|
||||
for _, c in ipairs(t:clients()) do
|
||||
c.prev_content = gears.surface.duplicate_surface(c.content)
|
||||
end
|
||||
end)
|
||||
|
||||
awesome.connect_signal("bling::tag_preview::update", function(t)
|
||||
draw_widget(tag_preview_box, t, tag_preview_image, scale,
|
||||
prev_screen_width, prev_screen_height, screen_radius,
|
||||
client_radius, client_opacity, client_bg,
|
||||
client_border_color, client_border_width, widget_bg,
|
||||
widget_border_color, widget_border_width)
|
||||
end)
|
||||
|
||||
awesome.connect_signal("bling::tag_preview::visibility", function(s, v)
|
||||
tag_preview_box.screen = s
|
||||
tag_preview_box.visible = v
|
||||
end)
|
||||
end
|
||||
|
||||
return {enable = enable}
|
Loading…
Reference in New Issue