-- AWMTK isn't exactly a toolkit as much as it is -- an addon on top of awesome's native widget capabilities. -- What it provides primarily is the ability to sub-theme -- various parts of the ui. -- Features: -- - Many new non-standard beautiful variables, -- - Hierarchic defaults, -- - Quick widget generators, -- - Variable prefix generators (like titlebar_bg_normal, etc), -- - Nightmares, -- - Why does this exist, -- - Please don't use it. local beautiful = require("beautiful") local wibox = require("wibox") local awful = require("awful") local gears = require("gears") local awmtk = {} --Global class names local classes = { "container_", "button_", "inputbox_", "textbox_", "icon_" } -- Utility functions local get_child_by_id = function(widget,id,limit) local children = {} local function _get_child(widget,id) for k,v in pairs(widget) do if type(v) == "table" then if v.id == id then children[#children+1] = v end _get_child(v,id) end end end _get_child({widget},id) return children end local function key_union(...) local tables = {...} local keys_lookup = {} local keys = {} for _,v in pairs(tables) do for k,whocareslol in pairs(v) do if not keys_lookup[k] then keys_lookup[k] = k table.insert(keys,k) end end end return keys end -- Preprocessable boilerplates local preprocess = {} preprocess.button = function(style) return function(widget,args,callbacks) local args = args or {} local callbacks = callbacks or {} local new_widget = style.button_widget(style) local background = get_child_by_id(new_widget,"widget_background")[1] for k,v in pairs(args) do background[k] = v end local container = get_child_by_id(new_widget,"widget_container")[1] container[#container+1] = widget new_widget = wibox.widget(new_widget) awmtk.connect_buttons(new_widget,callbacks) return new_widget end end preprocess.icon = function(style) return function(widget,args,callbacks) local args = args or {} local callbacks = callbacks or {} local new_widget = style.icon_widget(style) local background = get_child_by_id(new_widget,"widget_background")[1] for k,v in pairs(args) do background[k] = v end local container = get_child_by_id(new_widget,"widget_container")[1] container[#container+1] = widget new_widget = wibox.widget(new_widget) awmtk.connect_buttons(new_widget,callbacks) return new_widget end end preprocess.inputbox = function(style) return function(ps1,args,prompt_args) local args = args or {} local new_widget = style.inputbox_widget(style,ps1) local background = get_child_by_id(new_widget,"widget_background")[1] for k,v in pairs(args) do background[k] = v end new_widget = wibox.widget(new_widget) local textbox = new_widget:get_children_by_id("widget_prompt")[1] awmtk.connect_buttons(new_widget,{function() if prompt_args.pre_callback then prompt_args.pre_callback(textbox) end local prompt_options = { textbox = textbox, } for k,v in pairs(prompt_args) do if k ~= "textbox" then prompt_options[k] = v end end prompt_options.exe_callback = function(input) prompt_args.exe_callback(input,textbox) textbox:set_markup_silently(ps1) end awful.prompt.run(prompt_options) end}) return new_widget end end preprocess.container = function(style) return function(widget,args) local args = args or {} local new_widget = style.container_widget(style) local background = get_child_by_id(new_widget,"widget_background")[1] for k,v in pairs(args) do background[k] = v end local container = get_child_by_id(new_widget,"widget_container")[1] container[#container+1] = widget new_widget = wibox.widget(new_widget) return new_widget end end preprocess.shape = function(style) return function(cr, width, height) gears.shape.rounded_rect(cr, width, height, style.rounding) end end preprocess.container_shape = function(style) return function(cr, width, height) gears.shape.rounded_rect(cr, width, height, style.container_rounding or style.rounding) end end preprocess.button_shape = function(style) return function(cr, width, height) gears.shape.rounded_rect(cr, width, height, style.button_rounding or style.rounding) end end preprocess.icon_shape = function(style) return function(cr, width, height) gears.shape.rounded_rect(cr, width, height, style.icon_rounding or style.rounding) end end preprocess.inputbox_shape = function(style) return function(cr, width, height) gears.shape.rounded_rect(cr, width, height, style.inputbox_rounding or style.rounding) end end -- AWMTK functions awmtk.connect_buttons = function(new_widget,callbacks) new_widget:buttons ( awful.util.table.join( (callbacks[1] and awful.button({},1,callbacks[1],callbacks.release_1)), (callbacks[2] and awful.button({},2,callbacks[2],callbacks.release_2)), (callbacks[3] and awful.button({},3,callbacks[3],callbacks.release_3)) ) ) return new_widget end awmtk._create_preprocess_style = function(style,prefix) -- We use this function to force templates to favor prefix values new_style = setmetatable({}, { __index = function(t,k) if type(k) == "string" and style[prefix..k] then return style[prefix..k] end return style[k] end }) return new_style end awmtk.create_prefix = function(style,prefix,index) -- Create a prefix for new widgets to use local keys = index for _,k in pairs(keys) do style[prefix..k] = style[prefix..k] or style[k] end return style end awmtk.style = function(parent,delta,prefix) local new_style = setmetatable({},{ __index = function(t,k) return rawget(t,k) or delta[k] or parent[k] end }) if prefix then new_style = awmtk.create_prefix(new_style,prefix,key_union(parent,delta)) end local _new_style = awmtk._create_preprocess_style(new_style,prefix) _new_style.button_shape = preprocess.button_shape(_new_style) _new_style.icon_shape = preprocess.icon_shape(_new_style) _new_style.container_shape = preprocess.container_shape(_new_style) _new_style.inputbox_shape = preprocess.inputbox_shape(_new_style) new_style.button = preprocess.button(_new_style) new_style.icon = preprocess.icon(_new_style) new_style.container = preprocess.container(_new_style) new_style.inputbox = preprocess.inputbox(_new_style) return new_style end -- Default variables table defaults = setmetatable({},{ __index = beautiful }) defaults.bg_normal = defaults.bg_normal defaults.bg_focus = defaults.bg_focus defaults.bg_urgent = defaults.bg_urgent defaults.bg_marked = defaults.bg_marked defaults.fg_normal = defaults.fg_normal defaults.fg_focus = defaults.fg_focus defaults.fg_urgent = defaults.fg_urgent defaults.fg_marked = defaults.fg_marked defaults.border_width = defaults.border_width defaults.border_normal = defaults.border_normal defaults.border_focus = defaults.border_focus defaults.border_marked = defaults.border_marked defaults.shape_border_width = defaults.shape_border_width or 0 defaults.shape_border_color = defaults.shape_border_color or defaults.bg_normal -- Extra variables defaults.inner_margin = defaults.inner_margin or 5 defaults.rounding = defaults.rounding or 0 -- Generate classes variables local new_defaults = {} for _,class in pairs(classes) do for parameter,value in pairs(defaults) do new_defaults[class..parameter] = ( defaults[class..parameter] or value ) end end for parameter,value in pairs(defaults) do new_defaults[parameter] = value end defaults = setmetatable(new_defaults,{ __index = beautiful }) --make icons look less weird defaults.icon_inner_margin = beautiful.icon_inner_margin or 0 --add spacing for lists defaults.container_spacing = defaults.container_spacing or 2 defaults.container_spacing_vertical = defaults.container_spacing_vertical or defaults.container_spacing defaults.container_spacing_horizontal = defaults.container_spacing_horizontal or defaults.container_spacing --add button size defaults defaults.button_size = 20 defaults.button_height = defaults.button_size defaults.button_width = defaults.button_size --add icon size defaults defaults.icon_size = 20 defaults.icon_height = defaults.icon_size defaults.icon_width = defaults.icon_size -- Templates for quick widget generation defaults.button_widget = defaults.button_widget or function(style) return { { id = "widget_container", widget = wibox.container.margin, margins = style.button_inner_margin, }, bg = style.button_bg_normal, id = "widget_background", widget = wibox.container.background, shape = style.button_shape, shape_border_width = style.button_shape_border_width, shape_border_color = style.button_shape_border_color, fg = style.button_fg_normal } end defaults.icon_widget = defaults.icon_widget or function(style) return { { id = "widget_container", widget = wibox.container.margin, margins = style.icon_inner_margin, }, bg = style.icon_bg_normal, id = "widget_background", widget = wibox.container.background, shape = style.icon_shape, shape_border_width = style.icon_shape_border_width, shape_border_color = style.icon_shape_border_color, fg = style.icon_fg_normal } end defaults.container_widget = defaults.container_widget or function(style) return { { id = "widget_container", widget = wibox.container.margin, margins = style.container_inner_margin, }, bg = style.container_bg_normal, id = "widget_background", widget = wibox.container.background, shape = style.container_shape, shape_border_width = style.container_shape_border_width, shape_border_color = style.container_shape_border_color, fg = style.container_fg_normal } end defaults.inputbox_widget = defaults.inputbox_widget or function(style,prompt) return { { { id = "widget_prompt", markup = prompt or "", widget = wibox.widget.textbox, fg = style.inputbox_fg_normal }, id = "widget_container", widget = wibox.container.margin, margins = style.inputbox_inner_margin, }, bg = style.inputbox_bg_normal, id = "widget_background", widget = wibox.container.background, shape = style.inputbox_shape, shape_border_width = style.inputbox_shape_border_width, shape_border_color = style.inputbox_shape_border_color } end defaults.button_shape = defaults.button_shape or preprocess.button_shape(defaults) defaults.icon_shape = defaults.icon_shape or preprocess.icon_shape(defaults) defaults.container_shape = defaults.container_shape or preprocess.container_shape(defaults) defaults.button = preprocess.button(defaults) defaults.icon = preprocess.icon(defaults) defaults.container = preprocess.container(defaults) defaults.inputbox = preprocess.inputbox(defaults) awmtk.defaults = defaults awmtk.preprocess = preprocess awmtk.utils = { key_union = key_union, get_child_by_id = get_child_by_id } return awmtk