-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
e7e2354
commit 1ebdfca
Showing
4 changed files
with
221 additions
and
94 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
139 changes: 45 additions & 94 deletions
139
rabbithole/components/widgets/common/elements-popup.lua
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,110 +1,61 @@ | ||
local Widget = require("elements-base-ui") -- Make sure the path is correct0 | ||
-- This is a popup container that holds a widget. This is going to be used as | ||
-- the container for the dropdown terminal, dropdown file manager, and quick notes. | ||
-- The popup container is a wibox that drops down from the top of the screen. | ||
-- It is used to hold widgets that are toggled on and off. | ||
|
||
local gears = require("gears") | ||
local wibox = require("wibox") | ||
local awful = require("awful") | ||
local Animations = require("rabbithole.components.widgets.themeEngines.elements-animations") -- Make sure the path is correct | ||
|
||
--[[ Usage: | ||
local my_popup = Popup({ | ||
width = 200, | ||
height = 100, | ||
bg = "#ffffff", | ||
border_color = "#000000", | ||
border_width = 1, | ||
position = "bottom_right", | ||
animation = "slide_in", | ||
animation_duration = 250 | ||
}) | ||
-- Add content to the popup | ||
my_popup.popup:setup { | ||
{ | ||
{ | ||
text = "This is a popup!", | ||
align = "center", | ||
valign = "center", | ||
widget = wibox.widget.textbox | ||
}, | ||
margins = 10, | ||
widget = wibox.container.margin | ||
}, | ||
widget = wibox.container.background | ||
} | ||
local wibox = require("wibox") | ||
local dpi = require("beautiful").xresources.apply_dpi | ||
|
||
-- Show the popup | ||
my_popup:show() | ||
|
||
-- You can use a timer or any event to hide the popup after | ||
local DropdownContainer = {} | ||
DropdownContainer.__index = DropdownContainer | ||
|
||
]] | ||
|
||
local Popup = class(Widget) | ||
function DropdownContainer:new(program, args) | ||
setmetatable({}, self) | ||
|
||
function Popup:init(args) | ||
args = args or {} | ||
self.width = args.width or 200 | ||
self.height = args.height or 100 | ||
self.bg = args.bg or "#ffffff" | ||
self.border_color = args.border_color or "#000000" | ||
self.border_width = args.border_width or 1 | ||
self.position = args.position or "bottom_right" | ||
self.animation = args.animation or "slide_in" | ||
self.animation_duration = args.animation_duration or 250 | ||
self.program = program | ||
self.args = args | ||
self.visible = false | ||
self:setup() | ||
|
||
-- Create a wibox for the popup | ||
self.popup = wibox({ | ||
ontop = true, | ||
visible = false, | ||
width = self.width, | ||
height = self.height, | ||
bg = self.bg, | ||
border_color = self.border_color, | ||
border_width = self.border_width, | ||
shape = gears.shape.rounded_rect | ||
}) | ||
|
||
-- Set the position of the popup | ||
self:set_position(self.position) | ||
|
||
-- Initialize the animations class | ||
self.animations = Animations() | ||
return self | ||
end | ||
|
||
function Popup:set_position(position) | ||
local s = awful.screen.focused() | ||
local x, y | ||
|
||
if position == "bottom_right" then | ||
x = s.geometry.x + s.geometry.width - self.width | ||
y = s.geometry.y + s.geometry.height - self.height | ||
-- Add other positions here | ||
else | ||
x = s.geometry.x + s.geometry.width / 2 - self.width / 2 | ||
y = s.geometry.y + s.geometry.height / 2 - self.height / 2 | ||
end | ||
|
||
self.popup.x = x | ||
self.popup.y = y | ||
-- Popup dropdown container wrapper | ||
function DropdownContainer:create() | ||
self.popup = awful.popup { | ||
widget = { | ||
{ | ||
{ | ||
self.program, -- Replace with your terminal emulator's command | ||
widget = wibox.widget.textbox | ||
}, | ||
margins = dpi(4), | ||
widget = wibox.container.margin | ||
}, | ||
widget = wibox.container.background | ||
}, | ||
visible = false, | ||
ontop = true, | ||
shape = function(cr, width, height) | ||
gears.shape.rounded_rect(cr, width, height, dpi(6)) | ||
end, | ||
} | ||
end | ||
|
||
function Popup:show() | ||
if not self.popup.visible then | ||
self.popup.visible = true | ||
if self.animation == "slide_in" then | ||
self.animations:slideIn(self.popup, self.animation_duration, self.position) | ||
end | ||
end | ||
-- toggle visibility | ||
function DropdownContainer:toggle() | ||
self.visible = not self.visible | ||
self.popup.visible = self.visible | ||
end | ||
|
||
function Popup:hide() | ||
if self.popup.visible then | ||
if self.animation == "slide_in" then | ||
self.animations:slideOut(self.popup, self.animation_duration, self.position, function() | ||
self.popup.visible = false | ||
end) | ||
else | ||
self.popup.visible = false | ||
end | ||
end | ||
-- initialist the popup | ||
function DropdownContainer:setup() | ||
self:create() | ||
self:toggle() | ||
end | ||
|
||
return DropdownContainer |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,168 @@ | ||
--[[ | ||
Licensed under GNU General Public License v2 | ||
* (c) 2016, Luca CPZ | ||
* (c) 2015, unknown | ||
--]] | ||
|
||
local awful = require("awful") | ||
local capi = { client = client } | ||
local math = math | ||
local string = string | ||
local pairs = pairs | ||
local screen = screen | ||
local setmetatable = setmetatable | ||
|
||
-- Quake-like Dropdown application spawn | ||
local quake = {} | ||
|
||
-- If you have a rule like "awful.client.setslave" for your terminals, | ||
-- ensure you use an exception for QuakeDD. Otherwise, you may | ||
-- run into problems with focus. | ||
|
||
function quake:display() | ||
if self.followtag then self.screen = awful.screen.focused() end | ||
|
||
-- First, we locate the client | ||
local client = nil | ||
local i = 0 | ||
for c in awful.client.iterate(function (c) | ||
-- c.name may be changed! | ||
return c.instance == self.name | ||
end) | ||
do | ||
i = i + 1 | ||
if i == 1 then | ||
client = c | ||
else | ||
-- Additional matching clients, let's remove the sticky bit | ||
-- which may persist between awesome restarts. We don't close | ||
-- them as they may be valuable. They will just turn into | ||
-- normal clients. | ||
c.sticky = false | ||
c.ontop = false | ||
c.above = false | ||
end | ||
end | ||
|
||
if not client and not self.visible then return end | ||
|
||
if not client then | ||
-- The client does not exist, we spawn it | ||
cmd = string.format("%s %s %s", self.app, | ||
string.format(self.argname, self.name), self.extra) | ||
awful.spawn(cmd, { tag = self.screen.selected_tag }) | ||
return | ||
end | ||
|
||
-- Set geometry | ||
client.floating = true | ||
client.border_width = self.border | ||
client.size_hints_honor = false | ||
client:geometry(self.geometry[self.screen.index] or self:compute_size()) | ||
|
||
-- Set not sticky and on top | ||
client.sticky = false | ||
client.ontop = true | ||
client.above = true | ||
client.skip_taskbar = true | ||
|
||
-- Additional user settings | ||
if self.settings then self.settings(client) end | ||
|
||
-- Toggle display | ||
if self.visible then | ||
client.hidden = false | ||
client:raise() | ||
self.last_tag = self.screen.selected_tag | ||
client:tags({self.screen.selected_tag}) | ||
capi.client.focus = client | ||
else | ||
client.hidden = true | ||
local ctags = client:tags() | ||
for i, t in pairs(ctags) do | ||
ctags[i] = nil | ||
end | ||
client:tags(ctags) | ||
end | ||
|
||
return client | ||
end | ||
|
||
function quake:compute_size() | ||
-- skip if we already have a geometry for this screen | ||
if not self.geometry[self.screen.index] then | ||
local geom | ||
if not self.overlap then | ||
geom = screen[self.screen.index].workarea | ||
else | ||
geom = screen[self.screen.index].geometry | ||
end | ||
local width, height = self.width, self.height | ||
if width <= 1 then width = math.floor(geom.width * width) - 2 * self.border end | ||
if height <= 1 then height = math.floor(geom.height * height) end | ||
local x, y | ||
if self.horiz == "left" then x = geom.x | ||
elseif self.horiz == "right" then x = geom.width + geom.x - width | ||
else x = geom.x + (geom.width - width)/2 end | ||
if self.vert == "top" then y = geom.y | ||
elseif self.vert == "bottom" then y = geom.height + geom.y - height | ||
else y = geom.y + (geom.height - height)/2 end | ||
self.geometry[self.screen.index] = { x = x, y = y, width = width, height = height } | ||
end | ||
return self.geometry[self.screen.index] | ||
end | ||
|
||
function quake:new(config) | ||
local conf = config or {} | ||
|
||
conf.app = conf.app or "xterm" -- application to spawn | ||
conf.name = conf.name or "QuakeDD" -- window name | ||
conf.argname = conf.argname or "-name %s" -- how to specify window name | ||
conf.extra = conf.extra or "" -- extra arguments | ||
conf.border = conf.border or 1 -- client border width | ||
conf.visible = conf.visible or false -- initially not visible | ||
conf.followtag = conf.followtag or false -- spawn on currently focused screen | ||
conf.overlap = conf.overlap or false -- overlap wibox | ||
conf.screen = conf.screen or awful.screen.focused() | ||
conf.settings = conf.settings | ||
|
||
-- If width or height <= 1 this is a proportion of the workspace | ||
conf.height = conf.height or 0.25 -- height | ||
conf.width = conf.width or 1 -- width | ||
conf.vert = conf.vert or "top" -- top, bottom or center | ||
conf.horiz = conf.horiz or "left" -- left, right or center | ||
conf.geometry = {} -- internal use | ||
|
||
local dropdown = setmetatable(conf, { __index = quake }) | ||
|
||
capi.client.connect_signal("manage", function(c) | ||
if c.instance == dropdown.name and c.screen == dropdown.screen then | ||
dropdown:display() | ||
end | ||
end) | ||
capi.client.connect_signal("unmanage", function(c) | ||
if c.instance == dropdown.name and c.screen == dropdown.screen then | ||
dropdown.visible = false | ||
end | ||
end) | ||
|
||
return dropdown | ||
end | ||
|
||
function quake:toggle() | ||
if self.followtag then self.screen = awful.screen.focused() end | ||
local current_tag = self.screen.selected_tag | ||
if current_tag and self.last_tag ~= current_tag and self.visible then | ||
local c=self:display() | ||
if c then | ||
c:move_to_tag(current_tag) | ||
end | ||
else | ||
self.visible = not self.visible | ||
self:display() | ||
end | ||
end | ||
|
||
return setmetatable(quake, { __call = function(_, ...) return quake:new(...) end }) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters