Replace old state handling implementation by something 'better'
While **much** more complex and slower for regular menus, it has advantages: * Better performance scaling when state count grow * Prevent most accidental unsupported state colors * Prevent a big if elseif elseif... switch copy pasted in all item_styles * Make it easier to register new states As for the 'bloated' created by this commit, it will be moved when I will fix issue #12
This commit is contained in:
parent
9148c48dd1
commit
b6ba3ad383
92
base.lua
92
base.lua
|
@ -27,13 +27,13 @@ local module = {
|
||||||
LEAVE = 1001,
|
LEAVE = 1001,
|
||||||
},
|
},
|
||||||
item_flags = {
|
item_flags = {
|
||||||
NONE = 0 ,
|
NONE = 999999 ,
|
||||||
SELECTED = 1 , -- Single item selected [[FOCUS]]
|
DISABLED = 1 , -- Cannot be interacted with
|
||||||
HOVERED = 2 , -- Mouse hover
|
URGENT = 2 , -- Need attention
|
||||||
PRESSED = 3 , -- Mouse pressed
|
SELECTED = 3 , -- Single item selected [[FOCUS]]
|
||||||
URGENT = 4 , -- Need attention
|
PRESSED = 4 , -- Mouse pressed
|
||||||
USED = 5 , -- Common flag
|
HOVERED = 5 , -- Mouse hover
|
||||||
DISABLED = 6 , -- Cannot be interacted with
|
USED = 6 , -- Common flag
|
||||||
CHECKED = 7 , -- When checkbox isn't enough
|
CHECKED = 7 , -- When checkbox isn't enough
|
||||||
ALTERNATE = 8 ,
|
ALTERNATE = 8 ,
|
||||||
HIGHLIGHT = 9 ,
|
HIGHLIGHT = 9 ,
|
||||||
|
@ -50,8 +50,69 @@ local module = {
|
||||||
USR8 = 108,
|
USR8 = 108,
|
||||||
USR9 = 109,
|
USR9 = 109,
|
||||||
USR10 = 110,
|
USR10 = 110,
|
||||||
|
},
|
||||||
|
colors_by_id = {}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
-- Do some magic to cache the highest state
|
||||||
|
local function return_data(tab, key)
|
||||||
|
return tab._real_table[key]
|
||||||
|
end
|
||||||
|
local function change_data(tab, key,value)
|
||||||
|
if not value and key == rawget(tab,"_current_key") then
|
||||||
|
-- Loop the array to find a new current_key
|
||||||
|
local win = math.huge
|
||||||
|
for k,v in pairs(tab._real_table) do
|
||||||
|
if k < win and k ~= key then
|
||||||
|
win = k
|
||||||
|
end
|
||||||
|
end
|
||||||
|
rawset(tab,"_current_key",win ~= math.huge and win or nil)
|
||||||
|
elseif value and (rawget(tab,"_current_key") or math.huge) > key then
|
||||||
|
rawset(tab,"_current_key",key)
|
||||||
|
end
|
||||||
|
tab._real_table[key] = value
|
||||||
|
end
|
||||||
|
local function init_state()
|
||||||
|
local mt = {__newindex = change_data,__index=return_data}
|
||||||
|
return setmetatable({_real_table={}},mt)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Util to help match colors to states
|
||||||
|
local theme_colors = {}
|
||||||
|
local function register_color(state_id,name,beautiful_name,allow_fallback)
|
||||||
|
theme_colors[name] = {id=state_id,beautiful_name=beautiful_name,fallback=allow_fallback}
|
||||||
|
module.colors_by_id[state_id] = name
|
||||||
|
end
|
||||||
|
local function setup_colors(data,args)
|
||||||
|
local priv = data._internal.private_data
|
||||||
|
for k,v in pairs(theme_colors) do
|
||||||
|
priv["fg_"..k] = args["fg_"..k] or beautiful["menu_fg_"..v.beautiful_name] or beautiful["fg_"..v.beautiful_name] or (v.fallback and "#ff0000")
|
||||||
|
priv["bg_"..k] = args["bg_"..k] or beautiful["menu_bg_"..v.beautiful_name] or beautiful["bg_"..v.beautiful_name] or (v.fallback and "#00ff00")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
register_color(module.item_flags.DISABLED , "disabled" , "disabled" , true )
|
||||||
|
register_color(module.item_flags.URGENT , "urgent" , "urgent" , true )
|
||||||
|
register_color(module.item_flags.SELECTED , "focus" , "focus" , true )
|
||||||
|
register_color(module.item_flags.PRESSED , "pressed" , "pressed" , true )
|
||||||
|
register_color(module.item_flags.HOVERED , "hover" , "hover" , true )
|
||||||
|
register_color(module.item_flags.USED , "used" , "used" , true )
|
||||||
|
register_color(module.item_flags.CHECKED , "checked" , "checked" , true )
|
||||||
|
register_color(module.item_flags.ALTERNATE , "alternate" , "alternate" , true )
|
||||||
|
register_color(module.item_flags.HIGHLIGHT , "highlight" , "highlight" , true )
|
||||||
|
-- register_color(item_flags.HEADER , ""
|
||||||
|
-- register_color(item_flags.USR1 , ""
|
||||||
|
-- register_color(item_flags.USR2 , ""
|
||||||
|
-- register_color(item_flags.USR3 , ""
|
||||||
|
-- register_color(item_flags.USR4 , ""
|
||||||
|
-- register_color(item_flags.USR5 , ""
|
||||||
|
-- register_color(item_flags.USR6 , ""
|
||||||
|
-- register_color(item_flags.USR7 , ""
|
||||||
|
-- register_color(item_flags.USR8 , ""
|
||||||
|
-- register_color(item_flags.USR9 , ""
|
||||||
|
-- register_color(item_flags.USR10 , ""
|
||||||
|
|
||||||
|
|
||||||
local function filter(data)
|
local function filter(data)
|
||||||
if not data.filter == false then
|
if not data.filter == false then
|
||||||
|
@ -172,7 +233,7 @@ local function add_item(data,args)
|
||||||
item_layout = args.item_layout or nil ,
|
item_layout = args.item_layout or nil ,
|
||||||
selected = false ,
|
selected = false ,
|
||||||
overlay = args.overlay or data.overlay or nil ,
|
overlay = args.overlay or data.overlay or nil ,
|
||||||
state = {} ,
|
state = init_state() ,
|
||||||
},
|
},
|
||||||
force_private = {
|
force_private = {
|
||||||
visible = true,
|
visible = true,
|
||||||
|
@ -301,14 +362,14 @@ local function new(args)
|
||||||
-- Default settings
|
-- Default settings
|
||||||
bg = args.bg or beautiful.menu_bg_normal or beautiful.bg_normal or "#000000",
|
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",
|
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",
|
-- bg_focus = args.bg_focus or beautiful.menu_bg_focus or beautiful.bg_focus or "#ffffff",
|
||||||
fg_focus = args.fg_focus or beautiful.menu_fg_focus or beautiful.fg_focus or "#000000",
|
-- fg_focus = args.fg_focus or beautiful.menu_fg_focus or beautiful.fg_focus or "#000000",
|
||||||
bg_alternate = args.bg_alternate or beautiful.menu_bg_alternate or beautiful.bg_alternate or beautiful.bg_normal,
|
-- bg_alternate = args.bg_alternate or beautiful.menu_bg_alternate or beautiful.bg_alternate or beautiful.bg_normal,
|
||||||
bg_highlight = args.bg_highlight or beautiful.menu_bg_highlight or beautiful.bg_highlight or beautiful.bg_normal,
|
-- bg_highlight = args.bg_highlight or beautiful.menu_bg_highlight or beautiful.bg_highlight or beautiful.bg_normal,
|
||||||
bg_header = args.bg_header or beautiful.menu_bg_header or beautiful.fg_normal,
|
bg_header = args.bg_header or beautiful.menu_bg_header or beautiful.fg_normal,
|
||||||
bg_prefix = args.bg_prefix or nil,
|
bg_prefix = args.bg_prefix or nil,
|
||||||
bg_hover = args.bg_hover or nil,
|
-- bg_hover = args.bg_hover or nil,
|
||||||
fg_hover = args.fg_hover or nil,
|
-- fg_hover = args.fg_hover or nil,
|
||||||
border_color = args.border_color or beautiful.menu_border_color or beautiful.border_color or "#333333",
|
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,
|
border_width = args.border_width or beautiful.menu_border_width or beautiful.border_width or 3,
|
||||||
separator_color = args.separator_color or beautiful.menu_separator_color or args.border_color or beautiful.menu_border_color or beautiful.border_color or "#333333",
|
separator_color = args.separator_color or beautiful.menu_separator_color or args.border_color or beautiful.menu_border_color or beautiful.border_color or "#333333",
|
||||||
|
@ -372,6 +433,7 @@ local function new(args)
|
||||||
})
|
})
|
||||||
internal.get_map,internal.set_map,internal.private_data = get_map,set_map,private_data
|
internal.get_map,internal.set_map,internal.private_data = get_map,set_map,private_data
|
||||||
data.add_item,data.add_widget,data.add_embeded_menu,data._internal,data.add_key_binding = add_item,add_widget,add_embeded_menu,internal,add_key_binding
|
data.add_item,data.add_widget,data.add_embeded_menu,data._internal,data.add_key_binding = add_item,add_widget,add_embeded_menu,internal,add_key_binding
|
||||||
|
setup_colors(data,args)
|
||||||
set_map.parent_geometry = function(value)
|
set_map.parent_geometry = function(value)
|
||||||
private_data.parent_geometry = value
|
private_data.parent_geometry = value
|
||||||
if data._internal.get_direction then
|
if data._internal.get_direction then
|
||||||
|
|
|
@ -86,8 +86,8 @@ end
|
||||||
function module:setup_hover(item,data)
|
function module:setup_hover(item,data)
|
||||||
item._internal.set_map.hover = function(value)
|
item._internal.set_map.hover = function(value)
|
||||||
local item_style = item.item_style or data.item_style
|
local item_style = item.item_style or data.item_style
|
||||||
item.state[2] = value and true or nil
|
item.state[5] = value and true or nil
|
||||||
item_style(data,item,{value and 2--[[HOVER]] or nil,item.selected and 1 or nil})
|
item_style(data,item,{})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -115,14 +115,18 @@ local function draw(data,item,args)
|
||||||
item.widget.next_color = hcode[next_idx]
|
item.widget.next_color = hcode[next_idx]
|
||||||
|
|
||||||
local state = item.state or {}
|
local state = item.state or {}
|
||||||
|
local current_state = state._current_key or nil
|
||||||
|
local state_name = base.colors_by_id[current_state]
|
||||||
|
|
||||||
local prev_item = get_prev(data,item)
|
local prev_item = get_prev(data,item)
|
||||||
if state[base.item_flags.SELECTED] or (item._tmp_menu) then
|
if current_state == base.item_flags.SELECTED or (item._tmp_menu) then
|
||||||
if prev_item and prev_item.widget.next_color ~= (args.color or data.bg_focus) then
|
if prev_item and prev_item.widget.next_color ~= (args.color or data.bg_focus) then
|
||||||
prev_item.widget.next_color = args.color or data.bg_focus
|
prev_item.widget.next_color = args.color or data.bg_focus
|
||||||
prev_item.widget:emit_signal("widget::updated")
|
prev_item.widget:emit_signal("widget::updated")
|
||||||
end
|
end
|
||||||
item.widget:set_bg(args.color or data.bg_focus)
|
item.widget:set_bg(args.color or data.bg_focus)
|
||||||
|
elseif state_name then --TODO untested, most likely broken
|
||||||
|
item.widget:set_bg(args.color or item["bg_"..state_name] or data["bg_"..state_name])
|
||||||
else
|
else
|
||||||
if prev_item and prev_item.widget.next_color ~= hcode[color_idx] then
|
if prev_item and prev_item.widget.next_color ~= hcode[color_idx] then
|
||||||
prev_item.widget.next_color = hcode[color_idx]
|
prev_item.widget.next_color = hcode[color_idx]
|
||||||
|
|
|
@ -81,11 +81,13 @@ local function draw(data,item,args)
|
||||||
end
|
end
|
||||||
|
|
||||||
local state = item.state or {}
|
local state = item.state or {}
|
||||||
|
local current_state = state._current_key or nil
|
||||||
|
local state_name = base.colors_by_id[current_state]
|
||||||
|
|
||||||
if state[base.item_flags.SELECTED] or (item._tmp_menu) then
|
if current_state == base.item_flags.SELECTED or (item._tmp_menu) then
|
||||||
item.widget:set_bg(args.color or data.bg_focus)
|
item.widget:set_bg(args.color or data.bg_focus)
|
||||||
elseif state[base.item_flags.HOVERED] then
|
elseif state_name then
|
||||||
item.widget:set_bg(args.color or data.bg_hover)
|
item.widget:set_bg(args.color or item["bg_"..state_name] or data["bg_"..state_name])
|
||||||
else
|
else
|
||||||
item.widget:set_bg(args.color or nil)
|
item.widget:set_bg(args.color or nil)
|
||||||
end
|
end
|
||||||
|
|
|
@ -42,11 +42,12 @@ local function draw(data,item,args)
|
||||||
item.widget.draw = suffix_draw
|
item.widget.draw = suffix_draw
|
||||||
|
|
||||||
local state = item.state or {}
|
local state = item.state or {}
|
||||||
|
local current_state = state._current_key or nil
|
||||||
if state[base.item_flags.SELECTED] or (item._tmp_menu) then
|
local state_name = base.colors_by_id[current_state]
|
||||||
item.widget:set_bg(args.color or data.bg_focus)
|
if current_state == base.item_flags.SELECTED or (item._tmp_menu) then
|
||||||
elseif state[base.item_flags.HOVERED] then
|
item.widget:set_bg(args.color or item.bg_focus or data.bg_focus)
|
||||||
item.widget:set_bg(args.color or data.bg_hover)
|
elseif state_name then
|
||||||
|
item.widget:set_bg(args.color or item["bg_"..state_name] or data["bg_"..state_name])
|
||||||
else
|
else
|
||||||
item.widget:set_bg(args.color or nil)
|
item.widget:set_bg(args.color or nil)
|
||||||
end
|
end
|
||||||
|
|
|
@ -30,9 +30,13 @@ local function draw(data,item,args)
|
||||||
end
|
end
|
||||||
|
|
||||||
local state = item.state or {}
|
local state = item.state or {}
|
||||||
|
local current_state = state._current_key or nil
|
||||||
|
local state_name = base.colors_by_id[current_state]
|
||||||
|
|
||||||
if state[base.item_flags.SELECTED] or (item._tmp_menu) then
|
if current_state == base.item_flags.SELECTED or (item._tmp_menu) then
|
||||||
item.widget:set_bg(args.color or data.bg_focus)
|
item.widget:set_bg(args.color or data.bg_focus)
|
||||||
|
elseif state_name then
|
||||||
|
item.widget:set_bg(args.color or item["bg_"..state_name] or data["bg_"..state_name])
|
||||||
else
|
else
|
||||||
item.widget:set_bg(args.color or nil)
|
item.widget:set_bg(args.color or nil)
|
||||||
end
|
end
|
||||||
|
|
|
@ -60,8 +60,10 @@ local function draw(data,item,args)
|
||||||
end
|
end
|
||||||
|
|
||||||
local state = item.state or {}
|
local state = item.state or {}
|
||||||
|
-- local current_state = state._current_key or nil --TODO
|
||||||
|
-- local state_name = base.colors_by_id[current_state]
|
||||||
|
|
||||||
if state[base.item_flags.SELECTED] or (item._tmp_menu) then
|
if current_state == base.item_flags.SELECTED or (item._tmp_menu) then
|
||||||
item.widget:set_bg(focussed[ih])
|
item.widget:set_bg(focussed[ih])
|
||||||
elseif col then
|
elseif col then
|
||||||
item.widget:set_bg(alt[col][ih])
|
item.widget:set_bg(alt[col][ih])
|
||||||
|
|
|
@ -60,9 +60,13 @@ local function draw(data,item,args)
|
||||||
end
|
end
|
||||||
|
|
||||||
local state = item.state or {}
|
local state = item.state or {}
|
||||||
|
local current_state = state._current_key or nil
|
||||||
|
local state_name = base.colors_by_id[current_state]
|
||||||
|
|
||||||
if state[base.item_flags.SELECTED] or (item._tmp_menu) then
|
if current_state == base.item_flags.SELECTED or (item._tmp_menu) then
|
||||||
item.widget:set_bg(focussed[ih])
|
item.widget:set_bg(focussed[ih])
|
||||||
|
elseif state_name then --TODO incomplete
|
||||||
|
item.widget:set_bg(args.color or item["bg_"..state_name] or data["bg_"..state_name])
|
||||||
else
|
else
|
||||||
item.widget:set_bg(default[ih])
|
item.widget:set_bg(default[ih])
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue