First commit
This is Radical, a new menu implementation for AwesomeWM. It make it easy to abstract look and behavior or various types of menu with object oriented abstractions. While slower, this make it easier to maintain and extend.
This commit is contained in:
commit
88d7ad2ff1
|
@ -0,0 +1,319 @@
|
|||
local setmetatable = setmetatable
|
||||
local pairs,ipairs = pairs, ipairs
|
||||
local type,string = type,string
|
||||
local print,unpack = print, unpack
|
||||
local beautiful = require( "beautiful" )
|
||||
local util = require( "awful.util" )
|
||||
local object = require( "radical.object" )
|
||||
local item_style = require( "radical.item_style" )
|
||||
|
||||
local capi = { mouse = mouse, screen = screen , keygrabber = keygrabber }
|
||||
|
||||
local module = {
|
||||
arrow_type = {
|
||||
NONE = 0,
|
||||
PRETTY = 1,
|
||||
CENTERED = 2,
|
||||
}}
|
||||
|
||||
function filter(data)
|
||||
local fs,visible_counter = data.filter_string:lower(),0
|
||||
for k,v in pairs(data.items) do
|
||||
local tmp = v[1]._filter_out
|
||||
v[1]._filter_out = (v[1].text:lower():find(fs) == nil)-- or (fs ~= "")
|
||||
if tmp ~= v[1]._filter_out then
|
||||
v[1].widget:emit_signal("widget::updated")
|
||||
end
|
||||
if not v[1]._filter_out then
|
||||
visible_counter = visible_counter + v[1].height
|
||||
end
|
||||
end
|
||||
data._total_item_height = visible_counter
|
||||
local w,h = data._internal.layout:fit()
|
||||
data.height = h
|
||||
end
|
||||
|
||||
------------------------------------KEYBOARD HANDLING-----------------------------------
|
||||
local function activateKeyboard(data)
|
||||
if not data then return end
|
||||
if not data or grabKeyboard == true then return end
|
||||
if (not (data.keyboardnav == false)) and data.visible == true then
|
||||
capi.keygrabber.run(function(mod, key, event)
|
||||
for k,v in pairs(data._internal.filter_hooks or {}) do --TODO modkeys
|
||||
if k.key == "Mod4" and (key == "End" or key == "Super_L") then
|
||||
local found = false
|
||||
for k3,v3 in ipairs(mod) do
|
||||
if v3 == "Mod4" and event == k.event then
|
||||
local retval,self = v(data,mod)
|
||||
if self and type(self) == "table" then
|
||||
data = self
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if k.key == key and k.event == event then
|
||||
local retval, self = v(data,mod)
|
||||
if self and type(self) == "table" then
|
||||
data = self
|
||||
end
|
||||
return retval
|
||||
end
|
||||
end
|
||||
if event == "release" then
|
||||
return true
|
||||
end
|
||||
|
||||
if (key == 'Return') and data._current_item and data._current_item.button1 then
|
||||
data._current_item.button1()
|
||||
data.visible = false
|
||||
elseif key == 'Escape' or (key == 'Tab' and data.filter_string == "") then
|
||||
data.visible = false
|
||||
capi.keygrabber.stop()
|
||||
elseif (key == 'BackSpace') and data.filter_string ~= "" and data.filter == true then
|
||||
data.filter_string = data.filter_string:sub(1,-2)
|
||||
filter(data)
|
||||
-- data:filter(data.filter_string:lower())
|
||||
-- if getFilterWidget() ~= nil then
|
||||
-- getFilterWidget().textbox:set_markup(getFilterWidget().textbox._layout.text:sub(1,-2))
|
||||
-- end
|
||||
elseif data.filter == true and key:len() == 1 then
|
||||
data.filter_string = data.filter_string .. key:lower()
|
||||
-- local fw = getFilterWidget()
|
||||
-- if fw ~= nil then
|
||||
-- fw.textbox:set_markup(fw.textbox._layout.text .. key:lower())
|
||||
-- if data.settings.autoresize and fw.textbox._layout:get_pixel_extents().width > data.settings.itemWidth then
|
||||
-- data.settings.itemWidth = fw.textbox._layout:get_pixel_extents().width + 40
|
||||
-- data.hasChanged = true
|
||||
-- data:set_coords()
|
||||
-- end
|
||||
-- end
|
||||
filter(data)
|
||||
else
|
||||
data.visible = false
|
||||
capi.keygrabber.stop()
|
||||
end
|
||||
return true
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
---------------------------------ITEM HANDLING----------------------------------
|
||||
function add_item(data,args)
|
||||
local args = args or {}
|
||||
local item,set_map,get_map,private_data = object({
|
||||
private_data = {
|
||||
text = args.text or "" ,
|
||||
height = args.height or beautiful.menu_height or 30 ,
|
||||
icon = args.icon or nil ,
|
||||
prefix = args.prefix or "" ,
|
||||
suffix = args.suffix or "" ,
|
||||
bg = args.bg or nil ,
|
||||
fg = args.fg or data.fg or beautiful.menu_fg_normal or beautiful.fg_normal,
|
||||
fg_focus = args.fg_focus or data.fg_focus or beautiful.menu_fg_focus or beautiful.fg_focus ,
|
||||
bg_focus = args.bg_focus or data.bg_focus or beautiful.menu_bg_focus or beautiful.bg_focus ,
|
||||
sub_menu_m = (args.sub_menu and type(args.sub_menu) == "table" and args.sub_menu.is_menu) and args.sub_menu or nil,
|
||||
sub_menu_f = (args.sub_menu and type(args.sub_menu) == "function") and args.sub_menu or nil,
|
||||
selected = false,
|
||||
},
|
||||
force_private = {
|
||||
visible = true,
|
||||
selected = true,
|
||||
},
|
||||
get_map = {
|
||||
y = function() return (args.y and args.y >= 0) and args.y or data.height - (data.margins.top or data.border_width) - data.item_height end, --Hack around missing :fit call for last item
|
||||
},
|
||||
autogen_getmap = true,
|
||||
autogen_setmap = true,
|
||||
autogen_signals = true,
|
||||
})
|
||||
item._private_data = private_data
|
||||
|
||||
for i=1,10 do
|
||||
item["button"..i] = args["button"..i]
|
||||
end
|
||||
|
||||
set_map.selected = function(value)
|
||||
private_data.selected = value
|
||||
if value == false then
|
||||
data.item_style(data,item,false,false)
|
||||
return
|
||||
end
|
||||
if data._current_item and data._current_item ~= item then
|
||||
if data._current_item._tmp_menu then
|
||||
data._current_item._tmp_menu.visible = false
|
||||
data._current_item._tmp_menu = nil
|
||||
data._tmp_menu = nil
|
||||
end
|
||||
data._current_item.selected = false
|
||||
end
|
||||
if (private_data.sub_menu_f or private_data.sub_menu_m)and data._current_item ~= item then
|
||||
local sub_menu = private_data.sub_menu_m or private_data.sub_menu_f()
|
||||
sub_menu.arrow_type = module.arrow_type.NONE
|
||||
sub_menu.parent_item = item
|
||||
sub_menu.parent_geometry = data
|
||||
sub_menu.visible = true
|
||||
item._tmp_menu = sub_menu
|
||||
data._tmp_menu = sub_menu
|
||||
end
|
||||
data.item_style(data,item,true,false)
|
||||
data._current_item = item
|
||||
end
|
||||
|
||||
data._internal.items[#data._internal.items+1] = {}
|
||||
data._internal.items[#data._internal.items][1] = item
|
||||
data._internal.setup_item(data,item,args)
|
||||
if args.selected == true then
|
||||
item.selected = true
|
||||
end
|
||||
return item
|
||||
end
|
||||
|
||||
|
||||
|
||||
---------------------------------MENU HANDLING----------------------------------
|
||||
local function new(args)
|
||||
local internal,args = args.internal or {},args or {}
|
||||
if not internal.items then internal.items = {} end
|
||||
|
||||
-- All the magic in the universe
|
||||
local data,set_map,get_map,private_data = object({
|
||||
private_data = {
|
||||
-- Default settings
|
||||
bg = args.bg or beautiful.menu_bg_normal or beautiful.bg_normal or "#000000",
|
||||
fg = args.fg or beautiful.menu_fg_normal or beautiful.fg_normal or "#ffffff",
|
||||
bg_focus = args.bg_focus or beautiful.menu_bg_focus or beautiful.bg_focus or "#ffffff",
|
||||
fg_forcus = args.fg_focus or beautiful.menu_fg_focus or beautiful.fg_focus or "#000000",
|
||||
border_color = args.border_color or beautiful.menu_border_color or beautiful.border_color or "#333333",
|
||||
border_width = args.border_width or beautiful.menu_border_width or beautiful.border_width or 3,
|
||||
item_height = args.item_height or beautiful.menu_height or 30,
|
||||
width = args.width or beautiful.menu_width or 130,
|
||||
default_width = args.width or beautiful.menu_width or 130,
|
||||
auto_resize = args.auto_resize or true,
|
||||
parent_geometry = args.parent or nil,
|
||||
arrow_type = args.arrow_type or beautiful.menu_arrow_type or module.arrow_type.PRETTY,
|
||||
visible = args.visible or false,
|
||||
direction = args.direction or "top",
|
||||
has_changed = false,
|
||||
row = args.row or nil,
|
||||
column = args.column or nil,
|
||||
layout = args.layout or nil,
|
||||
screen = args.screen or nil,
|
||||
style = args.style or nil,
|
||||
item_style = args.item_style or item_style.basic,
|
||||
filter = args.filter or true,
|
||||
show_filter = args.show_filter or false,
|
||||
filter_string = args.filter_string or "",
|
||||
suffix_widget = args.suffix_widget or nil,
|
||||
prefix_widget = args.prefix_widget or nil,
|
||||
fkeys_prefix = args.fkeys_prefix or false,
|
||||
},
|
||||
get_map = {
|
||||
is_menu = function() return true end,
|
||||
margin = function() return {left=0,bottom=0,right=0,left=0} end,
|
||||
items = function() return internal.items end,
|
||||
rowcount = function() return #internal.items end,
|
||||
columncount = function() return (#internal.items > 0) and #(internal.items[1]) or 0 end,
|
||||
},
|
||||
set_map = {
|
||||
auto_resize = function(val) private_data[""] = val end,
|
||||
},
|
||||
force_private = {
|
||||
parent = true,
|
||||
visible = true,
|
||||
},
|
||||
always_handle = {
|
||||
width = true,
|
||||
height = true,
|
||||
},
|
||||
autogen_getmap = true,
|
||||
autogen_setmap = true,
|
||||
autogen_signals = true,
|
||||
})
|
||||
internal.get_map,internal.set_map,internal.private_data = get_map,set_map,private_data
|
||||
data.add_item,data._internal = add_item,internal
|
||||
|
||||
set_map.parent_geometry = function(value)
|
||||
private_data.parent_geometry = value
|
||||
if data._internal.get_direction then
|
||||
data.direction = data._internal.get_direction(data)
|
||||
end
|
||||
if data._internal.set_position then
|
||||
data._internal.set_position(data)
|
||||
end
|
||||
end
|
||||
|
||||
set_map.visible = function(value)
|
||||
if internal.has_changed and data.style then
|
||||
data.style(data,{arrow_x=20,margin=internal.margin})
|
||||
end
|
||||
if not internal.parent_geometry and data._internal.set_position then
|
||||
internal.set_position(data)
|
||||
end
|
||||
if internal.set_visible then
|
||||
internal:set_visible(value)
|
||||
end
|
||||
private_data.visible = value
|
||||
if value and not capi.keygrabber.isrunning() then
|
||||
activateKeyboard(data)
|
||||
elseif data.parent_geometry and not data.parent_geometry.is_menu then
|
||||
capi.keygrabber.stop()
|
||||
end
|
||||
end
|
||||
|
||||
set_map.layout = function(value)
|
||||
if value then
|
||||
value:setup_key_hooks(data)
|
||||
end
|
||||
private_data.layout = value
|
||||
end
|
||||
|
||||
-- set_map.auto_resize = function(value)
|
||||
-- for k,v in ipairs(internal.items) do
|
||||
-- TODO check all items size, ajustthe fit and global width
|
||||
-- end
|
||||
-- end
|
||||
|
||||
get_map.current_index = function()
|
||||
if data._current_item then
|
||||
for k,v in ipairs(internal.items) do --rows
|
||||
for k2,v2 in ipairs(v) do --columns
|
||||
if data._current_item == v2 then
|
||||
return k,k2 --row, column as row is expected in most configurations
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
get_map.previous_item = function() return (internal.items[(data.current_index or 0)-1] or internal.items[data.rowcount])[1] end
|
||||
get_map.next_item = function() return ((internal.items[(data.current_index or 0)+1]or{})[1] or internal.items[1][1]) end
|
||||
|
||||
--Repaint when appearance properties change
|
||||
for k,v in ipairs({"bg","fg","border_color","border_width","item_height","width","arrow_type"}) do
|
||||
data:connect_signal(v.."::changed",function()
|
||||
if data.visible and data.style then
|
||||
-- data.style(data,{arrow_x=20,margin=internal.margin})
|
||||
else
|
||||
data.has_changed = true
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
function data:add_key_hook(mod, key, event, func)
|
||||
if key and event and func then
|
||||
internal.filter_hooks = internal.filter_hooks or {}
|
||||
internal.filter_hooks[{key = key, event = event, mod = mod}] = func
|
||||
end
|
||||
end
|
||||
|
||||
if private_data.layout then
|
||||
private_data.layout:setup_key_hooks(data)
|
||||
end
|
||||
|
||||
data._internal.setup_drawable(data)
|
||||
|
||||
return data
|
||||
end
|
||||
return setmetatable(module, { __call = function(_, ...) return new(...) end })
|
||||
-- kate: space-indent on; indent-width 2; replace-tabs on;
|
|
@ -0,0 +1,23 @@
|
|||
local setmetatable = setmetatable
|
||||
local context = require("radical.context")
|
||||
local base = require("radical.base")
|
||||
local capi = { mouse = mouse, screen = screen }
|
||||
|
||||
local function set_position(data)
|
||||
local s = data.screen or capi.mouse.screen
|
||||
local geom = capi.screen[s].geometry
|
||||
data.wibox.x = geom.x + (geom.width/2) - data.width/2
|
||||
data.wibox.y = geom.y + (geom.height/2) - data.height/2
|
||||
end
|
||||
|
||||
local function new(args)
|
||||
local args = args or {}
|
||||
args.internal = args.internal or {}
|
||||
args.arrow_type = base.arrow_type.NONE
|
||||
args.internal.set_position = args.internal.set_position or set_position
|
||||
local ret = context(args)
|
||||
return ret
|
||||
end
|
||||
|
||||
return setmetatable({}, { __call = function(_, ...) return new(...) end })
|
||||
-- kate: space-indent on; indent-width 2; replace-tabs on;
|
|
@ -0,0 +1,248 @@
|
|||
local base = require( "radical.base" )
|
||||
local print = print
|
||||
local unpack = unpack
|
||||
local debug = debug
|
||||
local setmetatable = setmetatable
|
||||
local color = require( "gears.color" )
|
||||
local wibox = require( "wibox" )
|
||||
local beautiful = require( "beautiful" )
|
||||
local cairo = require( "lgi" ).cairo
|
||||
local awful = require( "awful" )
|
||||
local util = require( "awful.util" )
|
||||
local button = require( "awful.button" )
|
||||
local layout = require( "radical.layout" )
|
||||
local arrow_style = require( "radical.style.arrow" )
|
||||
|
||||
local capi,module = { mouse = mouse , screen = screen , keygrabber = keygrabber },{}
|
||||
|
||||
local function get_direction(data)
|
||||
local parent_geometry = data.parent_geometry --Local cache to avoid always calling the object hooks
|
||||
if not parent_geometry or not parent_geometry.drawable then return "bottom" end
|
||||
local drawable_geom = parent_geometry.drawable.drawable.geometry(parent_geometry.drawable.drawable)
|
||||
if parent_geometry.y+parent_geometry.height < drawable_geom.height then --Vertical wibox
|
||||
if drawable_geom.x > capi.screen[capi.mouse.screen].geometry.width - (drawable_geom.x+drawable_geom.width) then
|
||||
return "right"
|
||||
else
|
||||
return "left"
|
||||
end
|
||||
else --Horizontal wibox
|
||||
if drawable_geom.y > capi.screen[capi.mouse.screen].geometry.height - (drawable_geom.y+drawable_geom.height) then
|
||||
return "bottom"
|
||||
else
|
||||
return "top"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function set_position(self)
|
||||
local ret,parent = {x=self.wibox.x,y=self.wibox.y},self.parent_geometry
|
||||
if parent and parent.is_menu then
|
||||
if parent.direction == "right" then
|
||||
ret={x=parent.x-self.width,y=parent.y+(self.parent_item.y)}
|
||||
else
|
||||
ret={x=parent.x+parent.width,y=parent.y+(self.parent_item.y)}
|
||||
if ret.y+self.height > capi.screen[capi.mouse.screen].geometry.height then
|
||||
ret.y = ret.y - self.height + self.item_height
|
||||
end
|
||||
end
|
||||
elseif parent then
|
||||
local drawable_geom = parent.drawable.drawable.geometry(parent.drawable.drawable)
|
||||
if (self.direction == "left") or (self.direction == "right") then
|
||||
ret = {x=drawable_geom.x+((self.direction == "right") and - self.wibox.width or drawable_geom.width),y=drawable_geom.y+parent.y+((self.arrow_type ~= base.arrow_type.NONE) and parent.height/2-(self.arrow_x or 20)-6 or 0)}
|
||||
else
|
||||
ret = {x=drawable_geom.x+parent.x-((self.arrow_type ~= base.arrow_type.NONE) and (self._arrow_x or 20)+11-parent.width/2 or 0),y=(self.direction == "bottom") and drawable_geom.y-self.wibox.height or drawable_geom.y+drawable_geom.height}
|
||||
end
|
||||
elseif not self.parent_geometry then --Use mouse position to set position --TODO it is called too often
|
||||
ret = capi.mouse.coords()
|
||||
local draw = awful.mouse.wibox_under_pointer and awful.mouse.wibox_under_pointer() or awful.mouse.drawin_under_pointer and awful.mouse.drawin_under_pointer()
|
||||
if draw then
|
||||
local geometry = draw.geometry(draw)
|
||||
if self.direction == "top" or self.direction == "bottom" then
|
||||
ret.x = ret.x - (self.arrow_x or 20) - 13
|
||||
ret.y = geometry.y+geometry.height
|
||||
if ret.y+self.height > capi.screen[capi.mouse.screen].geometry.height then
|
||||
self.direction = "bottom"
|
||||
ret.y = geometry.y-self.height
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
self.wibox.x = ret.x
|
||||
self.wibox.y = ret.y - 2*(self.wibox.border_width or 0)
|
||||
end
|
||||
|
||||
local function setup_drawable(data)
|
||||
local internal = data._internal
|
||||
local get_map,set_map,private_data = internal.get_map,internal.set_map,internal.private_data
|
||||
|
||||
--Init
|
||||
internal.w = wibox({})
|
||||
internal.margin = wibox.layout.margin()
|
||||
if not data.layout then
|
||||
data.layout = layout.vertical
|
||||
end
|
||||
internal.layout = data.layout(data)
|
||||
internal.w.visible = false
|
||||
internal.w.ontop = true
|
||||
internal.margin:set_widget(internal.layout)
|
||||
internal.w:set_widget(internal.margin)
|
||||
|
||||
--Getters
|
||||
get_map.wibox = function() return internal.w end
|
||||
get_map.x = function() return internal.w.x end
|
||||
get_map.y = function() return internal.w.y end
|
||||
get_map.width = function() return internal.w.width end
|
||||
get_map.height = function() return internal.w.height end
|
||||
get_map.visible = function() return internal.w.visible end
|
||||
get_map.direction = function() return private_data.direction end
|
||||
get_map.margins = function()
|
||||
local ret = {left=data.border_width,right=data.border_width,top=data.style.margins.TOP,bottom=data.style.margins.BOTTOM}
|
||||
if data.arrow_type ~= base.arrow_type.NONE then
|
||||
ret[data.direction] = ret[data.direction]+13
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
--Setters
|
||||
set_map.direction = function(value)
|
||||
if private_data.direction ~= value and (value == "top" or value == "bottom" or value == "left" or value == "right") then
|
||||
private_data.direction = value
|
||||
local fit_w,fit_h = internal.layout:fit()
|
||||
data.height = fit_h
|
||||
data.width = fit_w
|
||||
end
|
||||
end
|
||||
set_map.x = function(value) internal.w.x = value end
|
||||
set_map.y = function(value) internal.w.y = value end
|
||||
set_map.width = function(value)
|
||||
local need_update = internal.w.width == (value + 2*data.border_width)
|
||||
local margins = data.margins
|
||||
internal.w.width = value + data.margins.left + data.margins.right
|
||||
if need_update then
|
||||
data.style(data)
|
||||
end
|
||||
end
|
||||
set_map.height = function(value)
|
||||
local margins = data.margins
|
||||
local need_update = (internal.w.height ~= (value + margins.top + margins.bottom))
|
||||
internal.w.height = value + margins.top + margins.bottom
|
||||
if need_update then
|
||||
data.style(data)
|
||||
internal.set_position(data)
|
||||
end
|
||||
end
|
||||
function internal:set_visible(value)
|
||||
internal.w.visible = value
|
||||
end
|
||||
end
|
||||
|
||||
local function setup_item(data,item,args)
|
||||
--Create the background
|
||||
item.widget = wibox.widget.background()
|
||||
data.item_style(data,item,false,false)
|
||||
item.widget:set_fg(item._private_data.fg)
|
||||
|
||||
--Event handling
|
||||
item.widget:connect_signal("mouse::enter", function() item.selected = true end)
|
||||
item.widget:connect_signal("mouse::leave", function() item.selected = false end)
|
||||
data._internal.layout:add(item)
|
||||
local buttons = {}
|
||||
for i=1,10 do
|
||||
if args["button"..i] then
|
||||
buttons[#buttons+1] = button({},i,args["button"..i])
|
||||
end
|
||||
end
|
||||
if not buttons[3] then --Hide on right click
|
||||
buttons[#buttons+1] = button({},3,function()
|
||||
data.visible = false
|
||||
if data.parent_geometry and data.parent_geometry.is_menu then
|
||||
data.parent_geometry.visible = false
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
--Be sure to always hide sub menus, even when data.visible is set manually
|
||||
data:connect_signal("visible::changed",function(_,vis)
|
||||
if data._tmp_menu and data.visible == false then
|
||||
data._tmp_menu.visible = false
|
||||
end
|
||||
end)
|
||||
item.widget:buttons( util.table.join(unpack(buttons)))
|
||||
|
||||
--Create the main item layout
|
||||
local l,la,lr = wibox.layout.fixed.horizontal(),wibox.layout.align.horizontal(),wibox.layout.fixed.horizontal()
|
||||
local m = wibox.layout.margin(la)
|
||||
m:set_margins (0)
|
||||
m:set_left ( data.item_style.margins.LEFT )
|
||||
m:set_right ( data.item_style.margins.RIGHT )
|
||||
m:set_top ( data.item_style.margins.TOP )
|
||||
m:set_bottom( data.item_style.margins.BOTTOM )
|
||||
local text_w = wibox.widget.textbox()
|
||||
item._private_data._fit = wibox.widget.background.fit
|
||||
m.fit = function(...)
|
||||
if item.visible == false or item._filter_out == true then
|
||||
return 0,0
|
||||
end
|
||||
return data._internal.layout.item_fit(data,item,...)
|
||||
end
|
||||
|
||||
if data.fkeys_prefix == true then
|
||||
local pref = wibox.widget.textbox()
|
||||
pref.draw = function(self,w, cr, width, height)
|
||||
cr:set_source(color(beautiful.fg_normal))
|
||||
cr:paint()
|
||||
wibox.widget.textbox.draw(self,w, cr, width, height)
|
||||
end
|
||||
pref:set_markup("<span fgcolor='".. beautiful.bg_normal .."'><tt><b>F11</b></tt></span>")
|
||||
l:add(pref)
|
||||
m:set_left ( 0 )
|
||||
end
|
||||
|
||||
if args.prefix_widget then
|
||||
l:add(args.prefix_widget)
|
||||
end
|
||||
|
||||
if args.icon then
|
||||
local icon = wibox.widget.imagebox()
|
||||
icon:set_image(args.icon)
|
||||
l:add(icon)
|
||||
end
|
||||
text_w:set_markup(item._private_data.text)
|
||||
l:add(text_w)
|
||||
if item._private_data.sub_menu_f or item._private_data.sub_menu_m then
|
||||
local subArrow = wibox.widget.imagebox() --TODO, make global
|
||||
subArrow.fit = function(box, w, h) return subArrow._image:get_width(),item.height end
|
||||
subArrow:set_image( beautiful.menu_submenu_icon )
|
||||
lr:add(subArrow)
|
||||
item.widget.fit = function(box,w,h,...)
|
||||
args.y = data.height-h-data.margins.top
|
||||
return wibox.widget.background.fit(box,w,h,...)
|
||||
end
|
||||
end
|
||||
if args.suffix_widget then
|
||||
lr:add(args.suffix_widget)
|
||||
end
|
||||
la:set_left(l)
|
||||
la:set_right(lr)
|
||||
item.widget:set_widget(m)
|
||||
local fit_w,fit_h = data._internal.layout:fit()
|
||||
data.height = fit_h
|
||||
-- data.width = fit_w
|
||||
data.style(data)
|
||||
end
|
||||
|
||||
|
||||
local function new(args)
|
||||
local args = args or {}
|
||||
args.internal = args.internal or {}
|
||||
args.internal.get_direction = args.internal.get_direction or get_direction
|
||||
args.internal.set_position = args.internal.set_position or set_position
|
||||
args.internal.setup_drawable = args.internal.setup_drawable or setup_drawable
|
||||
args.internal.setup_item = args.internal.setup_item or setup_item
|
||||
args.style = args.style or arrow_style
|
||||
local ret = base(args)
|
||||
return ret
|
||||
end
|
||||
|
||||
return setmetatable(module, { __call = function(_, ...) return new(...) end })
|
||||
-- kate: space-indent on; indent-width 2; replace-tabs on;
|
|
@ -0,0 +1,10 @@
|
|||
return {
|
||||
layout = require( "radical.layout" ),
|
||||
object = require( "radical.object" ),
|
||||
base = require( "radical.base" ),
|
||||
radial = require( "radical.radial" ),
|
||||
context = require( "radical.context" ),
|
||||
box = require( "radical.box" ),
|
||||
style = require( "radical.style" ),
|
||||
item_style = require( "radical.item_style" ),
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
local setmetatable = setmetatable
|
||||
local print = print
|
||||
|
||||
local module = {
|
||||
margins = {
|
||||
TOP = 2,
|
||||
BOTTOM = 2,
|
||||
RIGHT = 2,
|
||||
LEFT = 4
|
||||
}
|
||||
}
|
||||
|
||||
local function draw(data,item,is_focussed,is_pressed)
|
||||
if is_focussed then
|
||||
item.widget:set_bg(data.bg_focus)
|
||||
else
|
||||
item.widget:set_bg(data.bg)
|
||||
end
|
||||
end
|
||||
|
||||
return setmetatable(module, { __call = function(_, ...) return draw(...) end })
|
||||
-- kate: space-indent on; indent-width 2; replace-tabs on;
|
|
@ -0,0 +1,47 @@
|
|||
local setmetatable = setmetatable
|
||||
local color = require( "gears.color" )
|
||||
local cairo = require( "lgi" ).cairo
|
||||
local print = print
|
||||
|
||||
local module = {
|
||||
margins = {
|
||||
TOP = 2,
|
||||
BOTTOM = 2,
|
||||
RIGHT = 0,
|
||||
LEFT = 4
|
||||
}
|
||||
}
|
||||
|
||||
local focussed,default = nil, nil
|
||||
|
||||
local function gen(item_height,bg_color,border_color)
|
||||
local img = cairo.ImageSurface(cairo.Format.ARGB32, 800,item_height)
|
||||
local cr = cairo.Context(img)
|
||||
cr:set_source( color(bg_color) )
|
||||
cr:paint()
|
||||
cr:set_source( color(border_color) )
|
||||
cr:rectangle(0,item_height-1,800,1)
|
||||
cr:fill()
|
||||
return cairo.Pattern.create_for_surface(img)
|
||||
end
|
||||
|
||||
local function draw(data,item,is_focussed,is_pressed)
|
||||
local ih = data.item_height
|
||||
if not focussed or not focussed[ih] then
|
||||
if not focussed then
|
||||
focussed,default={},{}
|
||||
end
|
||||
local bc = data.border_color
|
||||
focussed[ih] = gen(ih,data.bg_focus,bc)
|
||||
default [ih] = gen(ih,data.bg,bc)
|
||||
end
|
||||
|
||||
if is_focussed then
|
||||
item.widget:set_bg(focussed[ih])
|
||||
else
|
||||
item.widget:set_bg(default[ih])
|
||||
end
|
||||
end
|
||||
|
||||
return setmetatable(module, { __call = function(_, ...) return draw(...) end })
|
||||
-- kate: space-indent on; indent-width 2; replace-tabs on;
|
|
@ -0,0 +1,5 @@
|
|||
return {
|
||||
basic = require("radical.item_style.basic"),
|
||||
classic = require("radical.item_style.classic"),
|
||||
rounded = require("radical.item_style.rounded"),
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
local setmetatable = setmetatable
|
||||
local math = math
|
||||
local color = require( "gears.color" )
|
||||
local cairo = require( "lgi" ).cairo
|
||||
local print = print
|
||||
|
||||
local module = {
|
||||
margins = {
|
||||
TOP = 4,
|
||||
BOTTOM = 4,
|
||||
RIGHT = 4,
|
||||
LEFT = 4
|
||||
}
|
||||
}
|
||||
|
||||
local focussed,default = nil, nil
|
||||
|
||||
local function gen(item_height,bg_color,border_color)
|
||||
local img = cairo.ImageSurface(cairo.Format.ARGB32, item_height,item_height)
|
||||
local cr = cairo.Context(img)
|
||||
local rad = corner_radius or 3
|
||||
cr:set_source(color(bg_color))
|
||||
cr:arc(rad,rad,rad,0,2*math.pi)
|
||||
cr:arc(item_height-rad,rad,rad,0,2*math.pi)
|
||||
cr:arc(rad,item_height-rad,rad,0,2*math.pi)
|
||||
cr:arc(item_height-rad,item_height-rad,rad,0,2*math.pi)
|
||||
cr:fill()
|
||||
cr:rectangle(0,rad, item_height, item_height-2*rad)
|
||||
cr:rectangle(rad,0, item_height-2*rad, item_height)
|
||||
cr:fill()
|
||||
return cairo.Pattern.create_for_surface(img)
|
||||
end
|
||||
|
||||
local function draw(data,item,is_focussed,is_pressed)
|
||||
local ih = data.item_height
|
||||
if not focussed or not focussed[ih] then
|
||||
if not focussed then
|
||||
focussed,default={},{}
|
||||
end
|
||||
local bc = data.border_color
|
||||
focussed[ih] = gen(ih,data.bg_focus,bc)
|
||||
default [ih] = gen(ih,data.bg,bc)
|
||||
end
|
||||
|
||||
if is_focussed then
|
||||
item.widget:set_bg(focussed[ih])
|
||||
else
|
||||
item.widget:set_bg(default[ih])
|
||||
end
|
||||
end
|
||||
|
||||
return setmetatable(module, { __call = function(_, ...) return draw(...) end })
|
||||
-- kate: space-indent on; indent-width 2; replace-tabs on;
|
|
@ -0,0 +1,86 @@
|
|||
local setmetatable = setmetatable
|
||||
local print = print
|
||||
local ipairs = ipairs
|
||||
local math = math
|
||||
local wibox = require( "wibox" )
|
||||
|
||||
local module = {}
|
||||
|
||||
local function left(data)
|
||||
data.next_item.selected = true
|
||||
end
|
||||
|
||||
local function right(data)
|
||||
data.previous_item.selected = true
|
||||
end
|
||||
|
||||
local function up(data)
|
||||
local idx,rc,col = data.current_index,data.rowcount,data.column
|
||||
idx = idx-col
|
||||
if idx <= 0 then
|
||||
idx = rc + idx + 1
|
||||
end
|
||||
data.items[idx][1].selected = true
|
||||
end
|
||||
|
||||
local function down(data)
|
||||
local idx,rc,col = data.current_index,data.rowcount,data.column
|
||||
idx = idx+col
|
||||
if idx > rc then
|
||||
idx = idx - rc - 1
|
||||
end
|
||||
data.items[idx][1].selected = true
|
||||
end
|
||||
|
||||
function module:setup_key_hooks(data)
|
||||
data:add_key_hook({}, "Up" , "press", up )
|
||||
data:add_key_hook({}, "&" , "press", up )
|
||||
data:add_key_hook({}, "Down" , "press", down )
|
||||
data:add_key_hook({}, "KP_Enter", "press", down )
|
||||
data:add_key_hook({}, "Left" , "press", left )
|
||||
data:add_key_hook({}, "\"" , "press", left )
|
||||
data:add_key_hook({}, "Right" , "press", right )
|
||||
data:add_key_hook({}, "#" , "press", right )
|
||||
end
|
||||
|
||||
--Get preferred item geometry
|
||||
local function item_fit(data,item,...)
|
||||
return data.item_height, data.item_height
|
||||
end
|
||||
|
||||
local function new(data)
|
||||
local counter = 0
|
||||
local mode = data.column ~= nil
|
||||
local rows = {}
|
||||
local l = wibox.layout.fixed[mode and "horizontal" or "vertical"]()
|
||||
local constraint = mode and data.column or data.row or 2
|
||||
for i=1,constraint do
|
||||
local l2 = wibox.layout.fixed[mode and "vertical" or "horizontal"]()
|
||||
print("adding",(mode and "vertical" or "horizontal"))
|
||||
l:add(l2)
|
||||
rows[#rows+1] = l2
|
||||
end
|
||||
l.fit = function(a1,a2,a3)
|
||||
local r1,r2 = data.item_height*math.ceil(data.rowcount/constraint),data.item_height*constraint
|
||||
print("geo",(mode and r2 or r1),(mode and r1 or r2))
|
||||
return (mode and r2 or r1),(mode and r1 or r2)
|
||||
end
|
||||
l.add = function(l,item)
|
||||
for k,v in ipairs(rows) do
|
||||
v:reset()
|
||||
end
|
||||
local rc = data.rowcount+1
|
||||
for i=1,rc do
|
||||
-- local r = math.ceil(i/math.ceil(rc/constraint))
|
||||
-- if r == math.inf or r == 0 then r =1 end
|
||||
rows[((i-1)%constraint)+1]:add((rc == i and item.widget or data.items[i][1].widget))
|
||||
end
|
||||
return true
|
||||
end
|
||||
--TODO only load the layouts when draw() is called
|
||||
l.item_fit = item_fit
|
||||
return l
|
||||
end
|
||||
|
||||
return setmetatable(module, { __call = function(_, ...) return new(...) end })
|
||||
-- kate: space-indent on; indent-width 2; replace-tabs on;
|
|
@ -0,0 +1,67 @@
|
|||
local setmetatable = setmetatable
|
||||
local print = print
|
||||
local wibox = require( "wibox" )
|
||||
|
||||
local module = {}
|
||||
|
||||
local function left(data)
|
||||
if data._current_item._tmp_menu then
|
||||
data = data._current_item._tmp_menu
|
||||
data.items[1][1].selected = true
|
||||
return true,data
|
||||
end
|
||||
end
|
||||
|
||||
local function right(data)
|
||||
if data.parent_geometry.is_menu then
|
||||
for k,v in ipairs(data.items) do
|
||||
if v[1]._tmp_menu == data or v[1].sub_menu_m == data then
|
||||
v[1].selected = true
|
||||
end
|
||||
end
|
||||
data.visible = false
|
||||
data = data.parent_geometry
|
||||
return true,data
|
||||
end
|
||||
end
|
||||
|
||||
local function up(data)
|
||||
data.previous_item.selected = true
|
||||
end
|
||||
|
||||
local function down(data)
|
||||
data.next_item.selected = true
|
||||
end
|
||||
|
||||
function module:setup_key_hooks(data)
|
||||
data:add_key_hook({}, "Up" , "press", up )
|
||||
data:add_key_hook({}, "&" , "press", up )
|
||||
data:add_key_hook({}, "Down" , "press", down )
|
||||
data:add_key_hook({}, "KP_Enter", "press", down )
|
||||
data:add_key_hook({}, "Left" , "press", left )
|
||||
data:add_key_hook({}, "\"" , "press", left )
|
||||
data:add_key_hook({}, "Right" , "press", right )
|
||||
data:add_key_hook({}, "#" , "press", right )
|
||||
end
|
||||
|
||||
--Get preferred item geometry
|
||||
local function item_fit(data,item,...)
|
||||
local w, h = item._private_data._fit(...)
|
||||
return 70, item._private_data.height or h
|
||||
end
|
||||
|
||||
local function new(data)
|
||||
local l = wibox.layout.fixed.horizontal()
|
||||
l.fit = function(a1,a2,a3)
|
||||
local result,r2 = wibox.layout.fixed.fit(a1,99999,99999)
|
||||
return data.rowcount*data.default_width,data.item_height
|
||||
end
|
||||
l.add = function(l,item)
|
||||
return wibox.layout.fixed.add(l,item.widget)
|
||||
end
|
||||
l.item_fit = item_fit
|
||||
return l
|
||||
end
|
||||
|
||||
return setmetatable(module, { __call = function(_, ...) return new(...) end })
|
||||
-- kate: space-indent on; indent-width 2; replace-tabs on;
|
|
@ -0,0 +1,5 @@
|
|||
return {
|
||||
vertical = require( "radical.layout.vertical" ),
|
||||
horizontal = require( "radical.layout.horizontal" ),
|
||||
grid = require( "radical.layout.grid" ),
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
local setmetatable = setmetatable
|
||||
local print = print
|
||||
local beautiful = require("beautiful")
|
||||
local wibox = require( "wibox" )
|
||||
|
||||
local module = {}
|
||||
|
||||
local function left(data)
|
||||
if data._current_item._tmp_menu then
|
||||
data = data._current_item._tmp_menu
|
||||
data.items[1][1].selected = true
|
||||
return true,data
|
||||
end
|
||||
end
|
||||
|
||||
local function right(data)
|
||||
if data.parent_geometry.is_menu then
|
||||
for k,v in ipairs(data.items) do
|
||||
if v[1]._tmp_menu == data or v[1].sub_menu_m == data then
|
||||
v[1].selected = true
|
||||
end
|
||||
end
|
||||
data.visible = false
|
||||
data = data.parent_geometry
|
||||
return true,data
|
||||
end
|
||||
end
|
||||
|
||||
local function up(data)
|
||||
data.previous_item.selected = true
|
||||
end
|
||||
|
||||
local function down(data)
|
||||
data.next_item.selected = true
|
||||
end
|
||||
|
||||
function module:setup_key_hooks(data)
|
||||
data:add_key_hook({}, "Up" , "press", up )
|
||||
data:add_key_hook({}, "&" , "press", up )
|
||||
data:add_key_hook({}, "Down" , "press", down )
|
||||
data:add_key_hook({}, "KP_Enter", "press", down )
|
||||
data:add_key_hook({}, "Left" , "press", left )
|
||||
data:add_key_hook({}, "\"" , "press", left )
|
||||
data:add_key_hook({}, "Right" , "press", right )
|
||||
data:add_key_hook({}, "#" , "press", right )
|
||||
end
|
||||
|
||||
--Get preferred item geometry
|
||||
local function item_fit(data,item,...)
|
||||
local w, h = item._private_data._fit(...)
|
||||
return w, item._private_data.height or h
|
||||
end
|
||||
|
||||
local function new(data)
|
||||
local l,real_l = wibox.layout.fixed.vertical(),nil
|
||||
local filter_tb = nil
|
||||
if data.show_filter then
|
||||
real_l = wibox.layout.fixed.vertical()
|
||||
real_l:add(l)
|
||||
filter_tb = wibox.widget.textbox()
|
||||
local bg = wibox.widget.background()
|
||||
bg:set_bg(beautiful.bg_highlight)
|
||||
bg:set_widget(filter_tb)
|
||||
filter_tb:set_markup("<b>Filter:</b>")
|
||||
filter_tb.fit = function(tb,width,height)
|
||||
return width,data.item_height
|
||||
end
|
||||
data:connect_signal("filter_string::changed",function()
|
||||
filter_tb:set_markup("<b>Filter:</b> "..data.filter_string)
|
||||
end)
|
||||
real_l:add(bg)
|
||||
else
|
||||
real_l = l
|
||||
end
|
||||
real_l.fit = function(a1,a2,a3)
|
||||
local result,r2 = wibox.layout.fixed.fit(a1,99999,99999)
|
||||
local total = data._total_item_height
|
||||
return data.default_width, (total and total > 0 and total or data.rowcount*data.item_height) + (filter_tb and data.item_height or 0)
|
||||
end
|
||||
real_l.add = function(real_l,item)
|
||||
return wibox.layout.fixed.add(l,item.widget)
|
||||
end
|
||||
real_l.item_fit = item_fit
|
||||
return real_l
|
||||
end
|
||||
|
||||
return setmetatable(module, { __call = function(_, ...) return new(...) end })
|
||||
-- kate: space-indent on; indent-width 2; replace-tabs on;
|
|
@ -0,0 +1,73 @@
|
|||
local setmetatable = setmetatable
|
||||
local table = table
|
||||
local rawset = rawset
|
||||
local rawget = rawget
|
||||
local pairs = pairs
|
||||
|
||||
local function setup_object(args)
|
||||
local data,args,private_data,signals = {},args or {},private_data or {},{}
|
||||
local get_map,set_map,private_data = args.get_map or {},args.set_map or {},args.private_data or {}
|
||||
|
||||
function data:connect_signal(name,func)
|
||||
signals[name] = signals[name] or {}
|
||||
table.insert(signals[name],func)
|
||||
end
|
||||
|
||||
function data:remove_signal(name,func)
|
||||
for k,v in pairs(signals[name] or {}) do
|
||||
if v == func then
|
||||
signals[name][k] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function data:emit_signal(name,...)
|
||||
for k,v in pairs(signals[name] or {}) do
|
||||
v(data,...)
|
||||
end
|
||||
end
|
||||
|
||||
function data:add_autosignal_field(name)
|
||||
args.force_private = args.force_private or {}
|
||||
table.insert(args.force_private,name)
|
||||
end
|
||||
|
||||
local function return_data(tab, key)
|
||||
if get_map[key] ~= nil then
|
||||
return get_map[key]()
|
||||
elseif args.autogen_getmap == true and private_data[key] ~= nil then
|
||||
return private_data[key]
|
||||
elseif args.other_get_callback then
|
||||
local to_return = args.other_get_callback(key)
|
||||
if to_return then return to_return end
|
||||
end
|
||||
return rawget(tab,key)
|
||||
end
|
||||
|
||||
local function auto_signal(key)
|
||||
if args.autogen_signals == true then
|
||||
data:emit_signal(key.."::changed")
|
||||
end
|
||||
end
|
||||
|
||||
local function catch_changes(tab, key,value)
|
||||
if set_map[key] == false then
|
||||
--print("This is not a setter",debug.traceback()) --In some case, it may be called "normally", having this print is only good for debug
|
||||
elseif (data[key] ~= value or (args.always_handle ~= nil and args.always_handle[key] == true)) and set_map[key] ~= nil then
|
||||
set_map[key](value)
|
||||
auto_signal(key)
|
||||
elseif (args.force_private or {})[key] == true or (args.autogen_setmap and (private_data[key] ~= nil)) then
|
||||
private_data[key] = value
|
||||
auto_signal(key)
|
||||
elseif set_map[key] == nil then
|
||||
rawset(data,key,value)
|
||||
end
|
||||
if args.auto_signal_changed == true then
|
||||
data:emit_signal("changed")
|
||||
end
|
||||
end
|
||||
|
||||
setmetatable(data, { __index = return_data, __newindex = catch_changes, __len = function() return #data + #private_data end, })
|
||||
return data,set_map,get_map,private_data
|
||||
end
|
||||
return setmetatable({}, { __call = function(_, ...) return setup_object(...) end })
|
|
@ -0,0 +1,108 @@
|
|||
local setmetatable = setmetatable
|
||||
local beautiful = require( "beautiful" )
|
||||
local color = require( "gears.color" )
|
||||
local cairo = require( "lgi" ).cairo
|
||||
local base = require( "radical.base" )
|
||||
|
||||
local module = {
|
||||
margins = {
|
||||
BOTTOM = 10,
|
||||
TOP = 10,
|
||||
LEFT = 0 ,
|
||||
RIGHT = 0 ,
|
||||
}
|
||||
}
|
||||
|
||||
local function rotate(img, geometry, angle,swap_size)
|
||||
geometry = swap_size and {width = geometry.height, height=geometry.width} or geometry
|
||||
local matrix,pattern,img2 = cairo.Matrix(),cairo.Pattern.create_for_surface(img),cairo.ImageSurface(cairo.Format.ARGB32, geometry.width, geometry.height)
|
||||
cairo.Matrix.init_rotate(matrix,angle)
|
||||
matrix:translate((angle == math.pi/2) and 0 or -geometry.width, (angle == 3*(math.pi/2)) and 0 or -geometry.height)
|
||||
pattern:set_matrix(matrix)
|
||||
local cr2 = cairo.Context(img2)
|
||||
cr2:set_source(pattern)
|
||||
cr2:paint()
|
||||
return img2
|
||||
end
|
||||
|
||||
local function do_gen_menu_top(data, width, height, radius,padding,args)
|
||||
local img = cairo.ImageSurface(cairo.Format.ARGB32, width,height)
|
||||
local cr = cairo.Context(img)
|
||||
local no_arrow = data.arrow_type == base.arrow_type.NONE
|
||||
local top_padding = (data.arrow_type == base.arrow_type.NONE) and 0 or 13
|
||||
cr:set_operator(cairo.Operator.SOURCE)
|
||||
cr:set_source( color(args.bg) )
|
||||
cr:paint()
|
||||
cr:set_source( color(args.fg) )
|
||||
cr:rectangle(10, top_padding+padding, width - 20 +1 , 10)
|
||||
if not no_arrow then
|
||||
for i=1,13 do
|
||||
cr:rectangle((data._arrow_x or 20) + 13 - i, i+padding , 2*i , 1)
|
||||
end
|
||||
end
|
||||
cr:rectangle(padding or 0,no_arrow and 10 or 23, width-2*padding, height-33 + (no_arrow and 13 or 0))
|
||||
cr:rectangle(10+padding-1,height-10, width-20, 10-padding)
|
||||
cr:fill()
|
||||
cr:arc(10,10+top_padding,(radius-padding),0,2*math.pi)
|
||||
cr:arc(width-10, 10+top_padding + (pdding or 0),(radius-padding),0,2*math.pi)
|
||||
cr:arc(10,height-(radius-padding)-padding,(radius-padding),0,2*math.pi)
|
||||
cr:arc(width-10,height-(radius-padding)-padding,(radius-padding),0,2*math.pi)
|
||||
cr:fill()
|
||||
return img
|
||||
end
|
||||
|
||||
local function set_direction(data,direction)
|
||||
local geometry = (direction == "left" or direction == "right") and {width = data.wibox.height, height = data.wibox.width} or {height = data.wibox.height, width = data.wibox.width}
|
||||
local top_clip_surface = do_gen_menu_top(data,geometry.width,geometry.height,10,data.border_width,{bg=beautiful.fg_normal or "#0000ff",fg=beautiful.bg_normal or "#00ffff"})
|
||||
local top_bounding_surface = do_gen_menu_top(data,geometry.width,geometry.height,10,0,{bg="#00000000",fg="#ffffffff"})
|
||||
|
||||
local arr_margin,angle,mar_func = (data.arrow_type == base.arrow_type.NONE) and 0 or 13,0
|
||||
if direction == "bottom" then
|
||||
angle,swap = math.pi,false
|
||||
elseif direction == "left" then
|
||||
angle,swap = math.pi/2,true
|
||||
elseif direction == "right" then
|
||||
angle,swap = 3*math.pi/2,true
|
||||
end
|
||||
if angle ~= 0 then
|
||||
top_bounding_surface = rotate(top_bounding_surface,geometry,angle,swap)
|
||||
top_clip_surface = rotate(top_clip_surface,geometry,angle,swap)
|
||||
end
|
||||
data.wibox.shape_bounding = top_bounding_surface._native
|
||||
data.wibox:set_bg(cairo.Pattern.create_for_surface(top_clip_surface))
|
||||
end
|
||||
|
||||
local function draw(data,args)
|
||||
local args = args or {}
|
||||
local direction = data.direction or "top"
|
||||
|
||||
--BEGIN set_arrow, this used to be a function, but was only called once
|
||||
local at = data.arrow_type
|
||||
if at == base.arrow_type.PRETTY or not at then
|
||||
if direction == "left" then
|
||||
data._arrow_x = data.wibox.height -20 - (data.arrow_x or 20)
|
||||
elseif direction == "right" then
|
||||
--TODO
|
||||
elseif direction == "bottom" then
|
||||
data._arrow_x = data.wibox.width -20 - (data.arrow_x or 20)
|
||||
elseif direction == "top" then
|
||||
--TODO
|
||||
end
|
||||
elseif at == base.arrow_type.CENTERED then
|
||||
data._arrow_x = data.wibox.width/2 - 13
|
||||
end
|
||||
--END set_arrow
|
||||
|
||||
set_direction(data,direction)
|
||||
data._internal.set_position(data)
|
||||
|
||||
local margins = data.margins
|
||||
local margin = data._internal.margin
|
||||
for k,v in pairs(margins) do
|
||||
margin["set_"..k](margin,v)
|
||||
end
|
||||
return w,w2
|
||||
end
|
||||
|
||||
return setmetatable(module, { __call = function(_, ...) return draw(...) end })
|
||||
-- kate: space-indent on; indent-width 2; replace-tabs on;
|
|
@ -0,0 +1,20 @@
|
|||
local setmetatable = setmetatable
|
||||
local base = require( "radical.base" )
|
||||
|
||||
local module = {
|
||||
margins = {
|
||||
TOP = 0 ,
|
||||
BOTTOM = 0 ,
|
||||
LEFT = 0 ,
|
||||
BOTTOM = 0 ,
|
||||
}
|
||||
}
|
||||
|
||||
local function draw(data)
|
||||
data.arrow_type = base.arrow_type.NONE
|
||||
data.wibox.border_width = 1
|
||||
data.wibox.border_color = data.border_color
|
||||
end
|
||||
|
||||
return setmetatable(module, { __call = function(_, ...) return draw(...) end })
|
||||
-- kate: space-indent on; indent-width 2; replace-tabs on;
|
|
@ -0,0 +1,4 @@
|
|||
return {
|
||||
arrow = require( "radical.style.arrow" ),
|
||||
classic = require( "radical.style.classic" ),
|
||||
}
|
Loading…
Reference in New Issue