humble beginnings
|
@ -1,3 +1,4 @@
|
|||
-- RenoTK (formerly AWMTK2) - Template/Granular styling library for Reno
|
||||
local wibox = require("wibox")
|
||||
local awful = require("awful")
|
||||
local gears = require("gears")
|
||||
|
@ -63,18 +64,14 @@ awmtk.build_templates = function(templates,style)
|
|||
return new_templates
|
||||
end
|
||||
|
||||
awmtk.merge = function(base,overrides)
|
||||
for k,v in pairs(overrides) do
|
||||
base[k] = v
|
||||
end
|
||||
return base
|
||||
end
|
||||
awmtk.merge = gears.table.join
|
||||
-- }}}
|
||||
|
||||
|
||||
-- {{{ Default style
|
||||
|
||||
-- Default style
|
||||
-- Prototype style
|
||||
-- Notice that it's not awmtk.default style - it's used as a base for default.
|
||||
awmtk.proto_style = {
|
||||
base = setmetatable({
|
||||
-- { Backgrounds
|
||||
|
@ -88,13 +85,13 @@ awmtk.proto_style = {
|
|||
-- Borders for popups
|
||||
shape_border_width = beautiful.shape_border_width or 0,
|
||||
shape_border_color = beautiful.shape_border_color or beautiful.bg_normal,
|
||||
-- }
|
||||
-- { Callbacks
|
||||
-- a tiny bit more complex thing to account for more extensibility
|
||||
-- the stub functions do nothing - you should implement functionality inside theme
|
||||
onpress = function() end,
|
||||
onrelease = function() end,
|
||||
-- }
|
||||
-- }
|
||||
-- { Shapes
|
||||
margins = 5,
|
||||
spacing = 5,
|
||||
|
@ -140,6 +137,10 @@ awmtk.proto_style.popup = awmtk.create_delta("popup", {
|
|||
awmtk.proto_style.titlebar = awmtk.create_delta("titlebar", {
|
||||
margins = 1
|
||||
}, awmtk.proto_style,awmtk.proto_style.base)
|
||||
|
||||
awmtk.proto_style.wibar = awmtk.create_delta("wibar", {
|
||||
margins = 1
|
||||
}, awmtk.proto_style,awmtk.proto_style.base)
|
||||
-- }}}
|
||||
|
||||
-- {{{ Generic templates
|
||||
|
@ -154,8 +155,8 @@ awmtk.proto_templates = {
|
|||
return awmtk.merge({
|
||||
{
|
||||
layout,
|
||||
margins = (options and options.margins) or style.container.margins,
|
||||
widget = wibox.container.margin
|
||||
margins = style.container.margins,
|
||||
layout = wibox.container.margin
|
||||
},
|
||||
bgimage = style.container.bgimage,
|
||||
bg = style.container.bg_normal,
|
||||
|
@ -173,8 +174,8 @@ awmtk.proto_templates = {
|
|||
return awmtk.merge({
|
||||
{
|
||||
layout,
|
||||
margins = (options and options.margins) or style.button.margins,
|
||||
widget = wibox.container.margin
|
||||
margins = style.button.margins,
|
||||
layout = wibox.container.margin
|
||||
},
|
||||
bgimage = style.button.bgimage,
|
||||
bg = style.button.bg_normal,
|
||||
|
@ -223,13 +224,14 @@ awmtk.proto_templates = {
|
|||
article = function(style)
|
||||
-- Article is a template that combines 3 common pieces of a full item:
|
||||
-- Icon, name and description. Designed to be placed within a container
|
||||
-- or a button.
|
||||
-- or a button. Also supports usage in tasklist via _id suffixes.
|
||||
return function(options)
|
||||
return awmtk.merge({
|
||||
(options.icon and {
|
||||
{
|
||||
{
|
||||
image = options.icon,
|
||||
id = options.icon_id,
|
||||
resize = options.resize,
|
||||
widget = wibox.widget.imagebox
|
||||
},
|
||||
|
@ -247,16 +249,18 @@ awmtk.proto_templates = {
|
|||
{
|
||||
{
|
||||
markup = options.title or "",
|
||||
id = options.title_id,
|
||||
widget = wibox.widget.textbox,
|
||||
font = options.font or style.article.font,
|
||||
font = style.article.font,
|
||||
align = options.font_align or
|
||||
style.article.font_align,
|
||||
valign = "center"
|
||||
},
|
||||
(options.description and {
|
||||
markup = options.description,
|
||||
markup = options.description or "",
|
||||
id = options.desc_id,
|
||||
widget = wibox.widget.textbox,
|
||||
font = options.small_font or style.article.small_font,
|
||||
font = style.article.small_font,
|
||||
align = options.small_font_align or
|
||||
style.article.small_font_align,
|
||||
valign = "center"
|
||||
|
@ -277,8 +281,8 @@ awmtk.proto_templates = {
|
|||
return awmtk.merge({
|
||||
widget = {
|
||||
widget,
|
||||
margins = (options and options.margins) or style.popup.margins,
|
||||
widget = wibox.container.margin
|
||||
margins = style.popup.margins,
|
||||
layout = wibox.container.margin
|
||||
},
|
||||
bgimage = style.popup.bgimage,
|
||||
shape = style.popup.shape,
|
||||
|
@ -293,21 +297,53 @@ awmtk.proto_templates = {
|
|||
-- titlebars. The decision to make it a separate class was due to
|
||||
-- the fact that much customization is done through default theme table
|
||||
return function(layout,options)
|
||||
-- If there's one thing that fascinates me, it's how much weird
|
||||
-- bugs i manage to uncover by some sort of miraculous accident.
|
||||
-- This one fixes a race condition in margins+(left/right/bottom/top) configuration scenario
|
||||
local margins = style.titlebar.margins
|
||||
if (style.titlebar.left or
|
||||
style.titlebar.right or
|
||||
style.titlebar.bottom or
|
||||
style.titlebar.top) then
|
||||
margins = nil
|
||||
end
|
||||
return awmtk.merge({
|
||||
layout,
|
||||
margins = (options and options.margins) or
|
||||
style.titlebar.margins,
|
||||
widget = wibox.container.margin,
|
||||
margins = margins,
|
||||
layout = wibox.container.margin,
|
||||
left = style.titlebar.left,
|
||||
right = style.titlebar.right,
|
||||
bottom = style.titlebar.bottom,
|
||||
top = style.titlebar.top
|
||||
},options or {})
|
||||
end
|
||||
end,
|
||||
|
||||
wibar = function(style)
|
||||
-- Just you regular old wibar, but as a style template.
|
||||
return function(layout,options)
|
||||
local margins = style.wibar.margins
|
||||
if (style.wibar.left or
|
||||
style.wibar.right or
|
||||
style.wibar.bottom or
|
||||
style.wibar.top) then
|
||||
margins = nil
|
||||
end
|
||||
return awmtk.merge({
|
||||
layout,
|
||||
margins = margins,
|
||||
layout = wibox.container.margin,
|
||||
left = style.wibar.left,
|
||||
right = style.wibar.right,
|
||||
bottom = style.wibar.bottom,
|
||||
top = style.wibar.top
|
||||
},options or {})
|
||||
end
|
||||
end,
|
||||
}
|
||||
|
||||
-- yes
|
||||
-- Last but not least - we export a default template lib and default style.
|
||||
-- This is done in order to allow overriding default style behaviour from theme
|
||||
awmtk.default = awmtk.create_style("default",awmtk.proto_style,{})
|
||||
awmtk.templates = awmtk.create_template_lib("templates",awmtk.proto_templates,{})
|
||||
-- }}}
|
||||
|
|
|
@ -0,0 +1,118 @@
|
|||
-- JSON layout builder
|
||||
local json = require("dkjson")
|
||||
local gears = require("gears")
|
||||
local wibox = require("wibox")
|
||||
local awful = require("awful")
|
||||
|
||||
local builtins = {
|
||||
h_spacer = function(o)
|
||||
return {
|
||||
forced_width = o.size or 3,
|
||||
widget = wibox.container.background
|
||||
}
|
||||
end,
|
||||
v_spacer = function(o)
|
||||
return {
|
||||
forced_height = o.size or 3,
|
||||
widget = wibox.container.background
|
||||
}
|
||||
end
|
||||
-- Insert your other builtins here
|
||||
}
|
||||
-- Load a bunch of builtins from awful.titlebar
|
||||
for _,name in pairs({
|
||||
"titlewidget","iconwidget","floatingbutton",
|
||||
"maximizedbutton","minimizebutton","closebutton",
|
||||
"ontopbutton","stickybutton"
|
||||
}) do
|
||||
builtins[name] = function(o)
|
||||
o.widget = awful.titlebar.widget[name](o.client)
|
||||
return o
|
||||
end
|
||||
end
|
||||
|
||||
return function(description,opts)
|
||||
local style = opts.style or {}
|
||||
local c = opts.client
|
||||
local s = opts.screen
|
||||
local buttons = opts.buttons
|
||||
-- Build a layout given a JSON description, a style and client
|
||||
-- (if applicable)
|
||||
local layout = {}
|
||||
local test,err = json.decode(description)
|
||||
if not test then
|
||||
error("Builder failure: "..err)
|
||||
end
|
||||
local function inner_builder(struct)
|
||||
if struct.widget then -- External widget descriptions
|
||||
return require(struct.widget)(gears.table.join({
|
||||
layout = (struct.layout and inner_builder(struct.layout)), client = (struct.client and c),
|
||||
screen = (struct.screen and s)
|
||||
},struct.options or {}))
|
||||
elseif struct.list then -- List descriptions
|
||||
local list = {
|
||||
layout = wibox.layout.fixed[(
|
||||
(struct.vertical and "vertical") or
|
||||
"horizontal"
|
||||
)],
|
||||
spacing = style.spacing
|
||||
}
|
||||
for k,v in pairs(struct.list) do
|
||||
if v.draggable then
|
||||
list.buttons = buttons
|
||||
else
|
||||
table.insert(list,inner_builder(v))
|
||||
end
|
||||
end
|
||||
return list
|
||||
elseif struct.align then -- Align structure descriptions
|
||||
local orient = (
|
||||
(struct.vertical and "vertical") or
|
||||
"horizontal"
|
||||
)
|
||||
local list = {
|
||||
{
|
||||
layout = wibox.layout.fixed[orient],
|
||||
spacing = style.spacing
|
||||
},{
|
||||
layout = wibox.layout.flex[orient],
|
||||
spacing = style.spacing
|
||||
},{
|
||||
-- Simulating "spacing" parameter
|
||||
widget = builtins[(struct.vertical and "v_spacer") or
|
||||
"h_spacer"]({size = style.spacing}),
|
||||
layout = wibox.layout.fixed[orient],
|
||||
spacing = style.spacing
|
||||
},
|
||||
layout = wibox.layout.align[orient]
|
||||
}
|
||||
for k,v in pairs({"left","center","right"}) do
|
||||
for _,obj in pairs(struct.align[v]) do
|
||||
if obj.draggable then
|
||||
list[k].buttons = buttons
|
||||
else
|
||||
table.insert(list[k],inner_builder(obj))
|
||||
end
|
||||
end
|
||||
end
|
||||
-- Part of simulating "spacing" parameter
|
||||
table.insert(list[1],builtins[(struct.vertical and "v_spacer") or
|
||||
"h_spacer"]({size = style.spacing}))
|
||||
|
||||
return list
|
||||
elseif struct.builtin then -- Builtin widget descriptions
|
||||
if not builtins[struct.builtin] then
|
||||
error("Builtin not defined: "..struct.builtin)
|
||||
end
|
||||
return builtins[struct.builtin](gears.table.join({
|
||||
client = (struct.client and c)
|
||||
},struct.options or {}))
|
||||
end
|
||||
-- If this gets interpreted it's safe to say none of the constructions
|
||||
-- above got matched.
|
||||
print("Object where the error occured: ")
|
||||
gears.debug.dump(struct)
|
||||
error("Builder error: invalid object description")
|
||||
end
|
||||
return inner_builder(test,layout),test.context_options
|
||||
end
|
|
@ -1,26 +1,51 @@
|
|||
local awmtk2 = require("awmtk2")
|
||||
local gears = require("gears")
|
||||
local awmtk2 = require("awmtk2")
|
||||
local wibox = require("wibox")
|
||||
local awful = require("awful")
|
||||
local beautiful = require("beautiful")
|
||||
local builder = require("builder")
|
||||
local mbarutils = require("menubar").utils
|
||||
|
||||
-- {{{ Global widgets
|
||||
local runmenu = require("widgets.dismal")({})
|
||||
|
||||
local function read_file(fname)
|
||||
local fhandler = io.open(fname,"r")
|
||||
if fhandler then
|
||||
local data = fhandler:read("*a")
|
||||
fhandler:close()
|
||||
return data
|
||||
end
|
||||
end
|
||||
-- {{{ Placeholder Icons
|
||||
client.connect_signal("request::titlebars",function(c)
|
||||
if (not c.icon) and beautiful.icon_default then
|
||||
local icon = gears.surface(beautiful.icon_default)
|
||||
if icon then
|
||||
c.icon = icon._native
|
||||
end
|
||||
end
|
||||
end)
|
||||
-- }}}
|
||||
|
||||
-- {{{ Titlebars
|
||||
-- {{{ Global widgets
|
||||
local runmenu = require("widgets.dismal")({
|
||||
x = 0,
|
||||
y = 26
|
||||
})
|
||||
-- }}}
|
||||
|
||||
do -- {{{ Titlebars
|
||||
local titlebar_config = {}
|
||||
local style = awmtk2.create_style("titlebar",awmtk2.default,{})
|
||||
style.titlebar_top = awmtk2.create_delta("titlebar_top", {},
|
||||
(beautiful.widgets and beautiful.widgets.titlebar) or {}, style.titlebar)
|
||||
style.titlebar_left = awmtk2.create_delta("titlebar_left", {},
|
||||
(beautiful.widgets and beautiful.widgets.titlebar) or {}, style.titlebar)
|
||||
style.titlebar_right = awmtk2.create_delta("titlebar_right", {},
|
||||
(beautiful.widgets and beautiful.widgets.titlebar) or {}, style.titlebar)
|
||||
style.titlebar_bottom = awmtk2.create_delta("titlebar_bottom", {},
|
||||
(beautiful.widgets and beautiful.widgets.titlebar) or {}, style.titlebar)
|
||||
for k,v in pairs({"titlebar_top","titlebar_left","titlebar_right","titlebar_bottom"}) do
|
||||
-- Create styles for each titlebar
|
||||
style[v] = awmtk2.create_delta(v, {},
|
||||
(beautiful.widgets and beautiful.widgets.titlebar) or {},
|
||||
style.titlebar)
|
||||
-- Load in json layouts for titlebars
|
||||
titlebar_config[v] = read_file(root_path.."/themes/"..global.theme.."/config/"..v..".json")
|
||||
end
|
||||
local templates = awmtk2.create_template_lib("titlebar",awmtk2.templates,{})
|
||||
local t = awmtk2.build_templates(templates,style)
|
||||
-- Add titlebars to normal windows
|
||||
table.insert(awful.rules.rules,
|
||||
{ rule_any = {type = { "normal", "dialog" }
|
||||
}, properties = { titlebars_enabled = true }
|
||||
|
@ -37,112 +62,72 @@ client.connect_signal("request::titlebars",function(c)
|
|||
awful.mouse.client.resize(c)
|
||||
end)
|
||||
)
|
||||
|
||||
for k,v in pairs({"titlebar_top","titlebar_bottom","titlebar_left","titlebar_right"}) do
|
||||
local contents = { widget = wibox.container.background }
|
||||
if titlebar_config[v] then
|
||||
contents = builder(titlebar_config[v],{
|
||||
client = c,
|
||||
style = style[v],
|
||||
buttons = buttons
|
||||
})
|
||||
end
|
||||
awful.titlebar(c,{
|
||||
size = style.titlebar_top.size or 16,
|
||||
bg_normal = style.titlebar_top.bg_normal,
|
||||
bg_focus = style.titlebar_top.bg_focus,
|
||||
bgimage_normal = style.titlebar_top.bgimage_normal,
|
||||
bgimage_focus = style.titlebar_top.bgimage_focus,
|
||||
fg_normal = style.titlebar_top.fg_normal,
|
||||
fg_focus = style.titlebar_top.fg_focus,
|
||||
font = style.titlebar_top.font
|
||||
}):setup(t.titlebar({
|
||||
{ -- Left
|
||||
awful.titlebar.widget.iconwidget(c),
|
||||
buttons = buttons,
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
},
|
||||
{ -- Middle
|
||||
{ -- Title
|
||||
align = "center",
|
||||
widget = awful.titlebar.widget.titlewidget(c)
|
||||
},
|
||||
buttons = buttons,
|
||||
layout = wibox.layout.flex.horizontal
|
||||
},
|
||||
{ -- Right
|
||||
awful.titlebar.widget.floatingbutton (c),
|
||||
awful.titlebar.widget.maximizedbutton(c),
|
||||
awful.titlebar.widget.stickybutton (c),
|
||||
awful.titlebar.widget.ontopbutton (c),
|
||||
awful.titlebar.widget.closebutton (c),
|
||||
layout = wibox.layout.fixed.horizontal()
|
||||
},
|
||||
layout = wibox.layout.align.horizontal
|
||||
}))
|
||||
awful.titlebar(c,{
|
||||
size = style.titlebar_right.size or 0,
|
||||
position = "right",
|
||||
bg_normal = style.titlebar_right.bg_normal,
|
||||
bg_focus = style.titlebar_right.bg_focus,
|
||||
bgimage_normal = style.titlebar_right.bgimage_normal,
|
||||
bgimage_focus = style.titlebar_right.bgimage_focus,
|
||||
fg_normal = style.titlebar_right.fg_normal,
|
||||
fg_focus = style.titlebar_right.fg_focus,
|
||||
font = style.titlebar_right.font
|
||||
}):setup(t.titlebar({widget = wibox.container.background}))
|
||||
awful.titlebar(c,{
|
||||
size = style.titlebar_bottom.size or 0,
|
||||
position = "bottom",
|
||||
bg_normal = style.titlebar_bottom.bg_normal,
|
||||
bg_focus = style.titlebar_bottom.bg_focus,
|
||||
bgimage_normal = style.titlebar_bottom.bgimage_normal,
|
||||
bgimage_focus = style.titlebar_bottom.bgimage_focus,
|
||||
fg_normal = style.titlebar_bottom.fg_normal,
|
||||
fg_focus = style.titlebar_bottom.fg_focus,
|
||||
font = style.titlebar_bottom.font
|
||||
}):setup(t.titlebar({widget = wibox.container.background}))
|
||||
awful.titlebar(c,{
|
||||
size = style.titlebar_left.size or 0,
|
||||
position = "left",
|
||||
bg_normal = style.titlebar_left.bg_normal,
|
||||
bg_focus = style.titlebar_left.bg_focus,
|
||||
bgimage_normal = style.titlebar_left.bgimage_normal,
|
||||
bgimage_focus = style.titlebar_left.bgimage_focus,
|
||||
fg_normal = style.titlebar_left.fg_normal,
|
||||
fg_focus = style.titlebar_left.fg_focus,
|
||||
font = style.titlebar_left.font
|
||||
}):setup(t.titlebar({widget = wibox.container.background}))
|
||||
size = style[v].size or 0,
|
||||
position = v:gsub("titlebar_",""),
|
||||
bg_normal = style[v].bg_normal,
|
||||
bg_focus = style[v].bg_focus,
|
||||
bgimage_normal = style[v].bgimage_normal,
|
||||
bgimage_focus = style[v].bgimage_focus,
|
||||
fg_normal = style[v].fg_normal,
|
||||
fg_focus = style[v].fg_focus,
|
||||
font = style[v].font
|
||||
}):setup(t.titlebar(contents))
|
||||
end
|
||||
end)
|
||||
--}}}
|
||||
end --}}}
|
||||
|
||||
do --{{{ Screen
|
||||
local wibar_config = {}
|
||||
local style = awmtk2.create_style("wibar",awmtk2.default,{})
|
||||
for k,v in pairs({"wibar_top","wibar_bottom","wibar_left","wibar_right"}) do
|
||||
style[v] = awmtk2.create_delta(v, {},
|
||||
(beautiful.widgets and beautiful.widgets.wibar) or {},
|
||||
style.wibar)
|
||||
wibar_config[v] = read_file(root_path.."/themes/"..global.theme.."/config/"..v..".json")
|
||||
end
|
||||
local templates = awmtk2.create_template_lib("wibar",awmtk2.templates,{})
|
||||
local t = awmtk2.build_templates(templates,style)
|
||||
|
||||
--{{{ Screen
|
||||
awful.screen.connect_for_each_screen(function(s)
|
||||
-- Top bar
|
||||
s.topbar = awful.wibar({
|
||||
position = "top",
|
||||
screen = s,
|
||||
visible = false
|
||||
for k,v in pairs({"wibar_top","wibar_bottom","wibar_left","wibar_right"}) do
|
||||
local contents = { widget = wibox.container.background }
|
||||
if wibar_config[v] then
|
||||
contents = builder(wibar_config[v],{
|
||||
client = c,
|
||||
style = style[v],
|
||||
buttons = buttons,
|
||||
screen = s
|
||||
})
|
||||
s.topbar:setup {
|
||||
layout = wibox.layout.flex.horizontal
|
||||
}
|
||||
-- Bottom bar
|
||||
s.bottombar = awful.wibar({
|
||||
position = "bottom",
|
||||
s[v] = awful.wibar({
|
||||
-- There really isn't a better way to do this. I wish there was.
|
||||
position = v:gsub("wibar_",""),
|
||||
screen = s,
|
||||
visible = false
|
||||
visible = true,
|
||||
stretch = style[v].stretch or true,
|
||||
ontop = style[v].ontop or true,
|
||||
width = style[v].width,
|
||||
height = style[v].height,
|
||||
border_width = style[v].border_width,
|
||||
border_color = style[v].border_color,
|
||||
opacity = style[v].opacity or 1,
|
||||
shape = style[v].shape,
|
||||
bg = style[v].bg,
|
||||
bgimage = style[v].bgimage,
|
||||
fg = style[v].fg,
|
||||
input_passthrough = style[v].input_passthrough
|
||||
})
|
||||
s.bottombar:setup {
|
||||
layout = wibox.layout.flex.horizontal
|
||||
}
|
||||
-- Left bar
|
||||
s.leftbar = awful.wibar({
|
||||
position = "left",
|
||||
screen = s,
|
||||
visible = false
|
||||
})
|
||||
s.leftbar:setup {
|
||||
layout = wibox.layout.flex.horizontal
|
||||
}
|
||||
-- Right bar
|
||||
s.rightbar = awful.wibar({
|
||||
position = "right",
|
||||
screen = s,
|
||||
visible = false
|
||||
})
|
||||
s.rightbar:setup {
|
||||
layout = wibox.layout.flex.horizontal
|
||||
}
|
||||
s[v]:setup(t.wibar(contents))
|
||||
end
|
||||
end
|
||||
end)
|
||||
end -- }}}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
-- Global settings
|
||||
global = {}
|
||||
global.terminal = "xfce4-terminal" --Mod+Enter (spawn terminal)
|
||||
global.terminal = os.getenv("HOME").."/.local/bin/st" --Mod+Enter (spawn terminal)
|
||||
global.browser = "prime-run librewolf" --Mod+Shift+Enter (spawn browser)
|
||||
global.modkey = "Mod4" -- Default modifier key
|
||||
global.theme = "reno98"
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
{
|
||||
"align": {
|
||||
"left": [
|
||||
{
|
||||
"builtin": "iconwidget",
|
||||
"client": true
|
||||
}
|
||||
],
|
||||
"center": [
|
||||
{
|
||||
"draggable": true
|
||||
},
|
||||
{
|
||||
"builtin": "titlewidget",
|
||||
"client" : true,
|
||||
"options": {
|
||||
"align": "left"
|
||||
}
|
||||
}
|
||||
],
|
||||
"right": [
|
||||
{
|
||||
"builtin": "minimizebutton",
|
||||
"client": true
|
||||
},
|
||||
{
|
||||
"builtin": "maximizedbutton",
|
||||
"client": true
|
||||
},
|
||||
{
|
||||
"builtin": "closebutton",
|
||||
"client": true
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"align": {
|
||||
"left": [
|
||||
{ "widget": "widgets.base.base" }
|
||||
],
|
||||
"center": [
|
||||
|
||||
],
|
||||
"right": [
|
||||
{ "widget": "widgets.base.clock" }
|
||||
]
|
||||
}
|
||||
}
|
|
@ -126,6 +126,24 @@ theme.awesome_icon = theme_assets.awesome_icon(
|
|||
-- from /usr/share/icons and /usr/share/icons/hicolor will be used.
|
||||
theme.icon_theme = nil
|
||||
|
||||
theme.widgets = {
|
||||
default = {
|
||||
titlebar = {
|
||||
margins = 2,
|
||||
spacing = 1
|
||||
},
|
||||
wibar = {
|
||||
height = 24,
|
||||
margins = 2,
|
||||
width = 60
|
||||
}
|
||||
},
|
||||
titlebar = {
|
||||
titlebar_top = {
|
||||
size = 24
|
||||
}
|
||||
}
|
||||
}
|
||||
return theme
|
||||
|
||||
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
{
|
||||
"align": {
|
||||
"left": [
|
||||
{
|
||||
"builtin": "iconwidget",
|
||||
"client": true
|
||||
}
|
||||
],
|
||||
"center": [
|
||||
{
|
||||
"draggable": true
|
||||
},
|
||||
{
|
||||
"builtin": "titlewidget",
|
||||
"client" : true,
|
||||
"options": {
|
||||
"align": "left"
|
||||
}
|
||||
}
|
||||
],
|
||||
"right": [
|
||||
{
|
||||
"builtin": "minimizebutton",
|
||||
"client": true
|
||||
},
|
||||
{
|
||||
"builtin": "maximizedbutton",
|
||||
"client": true
|
||||
},
|
||||
{
|
||||
"builtin": "closebutton",
|
||||
"client": true
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"align": {
|
||||
"left": [
|
||||
{
|
||||
"widget": "widgets.tasklist",
|
||||
"screen": true,
|
||||
}
|
||||
],
|
||||
"center": [
|
||||
|
||||
],
|
||||
"right": [
|
||||
|
||||
]
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"align": {
|
||||
"left": [
|
||||
{ "widget": "widgets.base.base" }
|
||||
],
|
||||
"center": [
|
||||
|
||||
],
|
||||
"right": [
|
||||
{ "widget": "widgets.base.subpanel",
|
||||
"layout": {
|
||||
"list": [
|
||||
{ "widget": "widgets.base.clock" }
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
|
@ -4,7 +4,7 @@ local dpi = xresources.apply_dpi
|
|||
local gears = require("gears")
|
||||
|
||||
local gfs = require("gears.filesystem")
|
||||
local themes_path = gfs.get_themes_dir()
|
||||
local themes_path = root_path.."/themes/"
|
||||
|
||||
local theme = {}
|
||||
|
||||
|
@ -13,7 +13,7 @@ theme.font = "Liberation Sans 8"
|
|||
theme.bg_normal = "#c0c0c0"
|
||||
theme.bg_focus = "#808080"
|
||||
theme.bg_urgent = "#FFEDCC"
|
||||
theme.bg_minimize = "#dfdfdf"
|
||||
theme.bg_minimize = "#efefef"
|
||||
theme.bg_highlight_shadow = "#000000FF"
|
||||
theme.bg_highlight_light = "#FFFFFFFF"
|
||||
theme.bg_highlight_outline = "#808080FF"
|
||||
|
@ -52,56 +52,55 @@ theme.taglist_squares_sel = theme_assets.taglist_squares_sel(
|
|||
theme.taglist_squares_unsel = theme_assets.taglist_squares_unsel(
|
||||
taglist_square_size, theme.fg_normal
|
||||
)
|
||||
theme.menu_submenu_icon = themes_path.."default/submenu.png"
|
||||
theme.menu_height = dpi(15)
|
||||
theme.menu_width = dpi(100)
|
||||
|
||||
-- Define the image to load
|
||||
theme.titlebar_close_button_normal = themes_path.."default/titlebar/close_normal.png"
|
||||
theme.titlebar_close_button_focus = themes_path.."default/titlebar/close_focus.png"
|
||||
theme.titlebar_close_button_normal = themes_path.."reno98/titlebar/close_normal.png"
|
||||
theme.titlebar_close_button_focus = themes_path.."reno98/titlebar/close_focus.png"
|
||||
|
||||
theme.titlebar_minimize_button_normal = themes_path.."default/titlebar/minimize_normal.png"
|
||||
theme.titlebar_minimize_button_focus = themes_path.."default/titlebar/minimize_focus.png"
|
||||
theme.titlebar_minimize_button_normal = themes_path.."reno98/titlebar/minimize_normal.png"
|
||||
theme.titlebar_minimize_button_focus = themes_path.."reno98/titlebar/minimize_focus.png"
|
||||
|
||||
theme.titlebar_ontop_button_normal_inactive = themes_path.."default/titlebar/ontop_normal_inactive.png"
|
||||
theme.titlebar_ontop_button_focus_inactive = themes_path.."default/titlebar/ontop_focus_inactive.png"
|
||||
theme.titlebar_ontop_button_normal_active = themes_path.."default/titlebar/ontop_normal_active.png"
|
||||
theme.titlebar_ontop_button_focus_active = themes_path.."default/titlebar/ontop_focus_active.png"
|
||||
theme.titlebar_ontop_button_normal_inactive = themes_path.."reno98/titlebar/ontop_normal_inactive.png"
|
||||
theme.titlebar_ontop_button_focus_inactive = themes_path.."reno98/titlebar/ontop_focus_inactive.png"
|
||||
theme.titlebar_ontop_button_normal_active = themes_path.."reno98/titlebar/ontop_normal_active.png"
|
||||
theme.titlebar_ontop_button_focus_active = themes_path.."reno98/titlebar/ontop_focus_active.png"
|
||||
|
||||
theme.titlebar_sticky_button_normal_inactive = themes_path.."default/titlebar/sticky_normal_inactive.png"
|
||||
theme.titlebar_sticky_button_focus_inactive = themes_path.."default/titlebar/sticky_focus_inactive.png"
|
||||
theme.titlebar_sticky_button_normal_active = themes_path.."default/titlebar/sticky_normal_active.png"
|
||||
theme.titlebar_sticky_button_focus_active = themes_path.."default/titlebar/sticky_focus_active.png"
|
||||
theme.titlebar_sticky_button_normal_inactive = themes_path.."reno98/titlebar/sticky_normal_inactive.png"
|
||||
theme.titlebar_sticky_button_focus_inactive = themes_path.."reno98/titlebar/sticky_focus_inactive.png"
|
||||
theme.titlebar_sticky_button_normal_active = themes_path.."reno98/titlebar/sticky_normal_active.png"
|
||||
theme.titlebar_sticky_button_focus_active = themes_path.."reno98/titlebar/sticky_focus_active.png"
|
||||
|
||||
theme.titlebar_floating_button_normal_inactive = themes_path.."default/titlebar/floating_normal_inactive.png"
|
||||
theme.titlebar_floating_button_focus_inactive = themes_path.."default/titlebar/floating_focus_inactive.png"
|
||||
theme.titlebar_floating_button_normal_active = themes_path.."default/titlebar/floating_normal_active.png"
|
||||
theme.titlebar_floating_button_focus_active = themes_path.."default/titlebar/floating_focus_active.png"
|
||||
theme.titlebar_floating_button_normal_inactive = themes_path.."reno98/titlebar/floating_normal_inactive.png"
|
||||
theme.titlebar_floating_button_focus_inactive = themes_path.."reno98/titlebar/floating_focus_inactive.png"
|
||||
theme.titlebar_floating_button_normal_active = themes_path.."reno98/titlebar/floating_normal_active.png"
|
||||
theme.titlebar_floating_button_focus_active = themes_path.."reno98/titlebar/floating_focus_active.png"
|
||||
|
||||
theme.titlebar_maximized_button_normal_inactive = themes_path.."default/titlebar/maximized_normal_inactive.png"
|
||||
theme.titlebar_maximized_button_focus_inactive = themes_path.."default/titlebar/maximized_focus_inactive.png"
|
||||
theme.titlebar_maximized_button_normal_active = themes_path.."default/titlebar/maximized_normal_active.png"
|
||||
theme.titlebar_maximized_button_focus_active = themes_path.."default/titlebar/maximized_focus_active.png"
|
||||
theme.titlebar_maximized_button_normal_inactive = themes_path.."reno98/titlebar/maximized_normal_inactive.png"
|
||||
theme.titlebar_maximized_button_focus_inactive = themes_path.."reno98/titlebar/maximized_focus_inactive.png"
|
||||
theme.titlebar_maximized_button_normal_active = themes_path.."reno98/titlebar/maximized_normal_active.png"
|
||||
theme.titlebar_maximized_button_focus_active = themes_path.."reno98/titlebar/maximized_focus_active.png"
|
||||
|
||||
theme.wallpaper = themes_path.."default/background.png"
|
||||
theme.wallpaper = themes_path.."reno98/background.png"
|
||||
|
||||
-- You can use your own layout icons like this:
|
||||
theme.layout_fairh = themes_path.."default/layouts/fairhw.png"
|
||||
theme.layout_fairv = themes_path.."default/layouts/fairvw.png"
|
||||
theme.layout_floating = themes_path.."default/layouts/floatingw.png"
|
||||
theme.layout_magnifier = themes_path.."default/layouts/magnifierw.png"
|
||||
theme.layout_max = themes_path.."default/layouts/maxw.png"
|
||||
theme.layout_fullscreen = themes_path.."default/layouts/fullscreenw.png"
|
||||
theme.layout_tilebottom = themes_path.."default/layouts/tilebottomw.png"
|
||||
theme.layout_tileleft = themes_path.."default/layouts/tileleftw.png"
|
||||
theme.layout_tile = themes_path.."default/layouts/tilew.png"
|
||||
theme.layout_tiletop = themes_path.."default/layouts/tiletopw.png"
|
||||
theme.layout_spiral = themes_path.."default/layouts/spiralw.png"
|
||||
theme.layout_dwindle = themes_path.."default/layouts/dwindlew.png"
|
||||
theme.layout_cornernw = themes_path.."default/layouts/cornernww.png"
|
||||
theme.layout_cornerne = themes_path.."default/layouts/cornernew.png"
|
||||
theme.layout_cornersw = themes_path.."default/layouts/cornersww.png"
|
||||
theme.layout_cornerse = themes_path.."default/layouts/cornersew.png"
|
||||
theme.layout_fairh = themes_path.."reno98/layouts/fairhw.png"
|
||||
theme.layout_fairv = themes_path.."reno98/layouts/fairvw.png"
|
||||
theme.layout_floating = themes_path.."reno98/layouts/floatingw.png"
|
||||
theme.layout_magnifier = themes_path.."reno98/layouts/magnifierw.png"
|
||||
theme.layout_max = themes_path.."reno98/layouts/maxw.png"
|
||||
theme.layout_fullscreen = themes_path.."reno98/layouts/fullscreenw.png"
|
||||
theme.layout_tilebottom = themes_path.."reno98/layouts/tilebottomw.png"
|
||||
theme.layout_tileleft = themes_path.."reno98/layouts/tileleftw.png"
|
||||
theme.layout_tile = themes_path.."reno98/layouts/tilew.png"
|
||||
theme.layout_tiletop = themes_path.."reno98/layouts/tiletopw.png"
|
||||
theme.layout_spiral = themes_path.."reno98/layouts/spiralw.png"
|
||||
theme.layout_dwindle = themes_path.."reno98/layouts/dwindlew.png"
|
||||
theme.layout_cornernw = themes_path.."reno98/layouts/cornernww.png"
|
||||
theme.layout_cornerne = themes_path.."reno98/layouts/cornernew.png"
|
||||
theme.layout_cornersw = themes_path.."reno98/layouts/cornersww.png"
|
||||
theme.layout_cornerse = themes_path.."reno98/layouts/cornersew.png"
|
||||
|
||||
-- Generate Awesome icon:
|
||||
theme.awesome_icon = theme_assets.awesome_icon(
|
||||
|
@ -283,7 +282,10 @@ end
|
|||
---theme.bgimage_outset
|
||||
-- Define the icon theme for application icons. If not set then the icons
|
||||
-- from /usr/share/icons and /usr/share/icons/hicolor will be used.
|
||||
theme.icon_theme = nil
|
||||
theme.icon_theme = "Chicago95"
|
||||
|
||||
-- Default icon for clients
|
||||
theme.icon_default = "/usr/share/icons/Chicago95/apps/22/terminal.png"
|
||||
|
||||
theme.widgets = {
|
||||
default = {
|
||||
|
@ -315,9 +317,33 @@ theme.widgets = {
|
|||
},
|
||||
titlebar = {
|
||||
bgimage = theme.bgimage_outset,
|
||||
margins = 4,
|
||||
left = 5,
|
||||
right = 5
|
||||
--margins = 5,
|
||||
left = 4,
|
||||
right = 5,
|
||||
top = 4,
|
||||
bottom = 3,
|
||||
spacing = 1
|
||||
},
|
||||
wibar = {
|
||||
height = 26,
|
||||
width = 60,
|
||||
margins = 3,
|
||||
shape = function(cr,width,height)
|
||||
return gears.shape.rounded_rect(cr,width,height,0)
|
||||
end,
|
||||
bgimage = theme.bgimage_outset
|
||||
}
|
||||
},
|
||||
clock = {
|
||||
container = {
|
||||
bgimage = function() end,
|
||||
margins = 0
|
||||
}
|
||||
},
|
||||
subpanel = {
|
||||
container = {
|
||||
bgimage = theme.bgimage_inset,
|
||||
bg = theme.bgimage_normal
|
||||
}
|
||||
},
|
||||
dismal = {
|
||||
|
@ -328,6 +354,16 @@ theme.widgets = {
|
|||
height = 34
|
||||
}
|
||||
},
|
||||
tasklist = {
|
||||
button = {
|
||||
width = 140,
|
||||
height = 50,
|
||||
bgimage_focus = theme.bgimage_inset,
|
||||
bgimage_normal = theme.bgimage_outset,
|
||||
bgimage_urgent = theme.bgimage_outset,
|
||||
bgimage_minimize = theme.bgimage_outset
|
||||
}
|
||||
},
|
||||
titlebar = {
|
||||
titlebar_top = {
|
||||
bgimage_normal = theme.titlebar_bgimage_top,
|
||||
|
@ -336,7 +372,7 @@ theme.widgets = {
|
|||
bg_normal = theme.titlebar_bg_normal,
|
||||
fg_focus = "#FAFAFA",
|
||||
fg_normal = theme.fg_normal,
|
||||
size = 24
|
||||
size = 22,
|
||||
},
|
||||
titlebar_left = {
|
||||
bgimage_normal = theme.titlebar_bgimage_left,
|
||||
|
|
Before Width: | Height: | Size: 966 B After Width: | Height: | Size: 369 B |
Before Width: | Height: | Size: 966 B After Width: | Height: | Size: 369 B |
Before Width: | Height: | Size: 480 B After Width: | Height: | Size: 217 B |
Before Width: | Height: | Size: 452 B After Width: | Height: | Size: 206 B |
Before Width: | Height: | Size: 480 B After Width: | Height: | Size: 217 B |
Before Width: | Height: | Size: 452 B After Width: | Height: | Size: 206 B |
Before Width: | Height: | Size: 234 B After Width: | Height: | Size: 190 B |
Before Width: | Height: | Size: 225 B After Width: | Height: | Size: 190 B |
|
@ -0,0 +1,14 @@
|
|||
-- Base for widgets
|
||||
local awmtk2 = require("awmtk2")
|
||||
local wibox = require("wibox")
|
||||
local gears = require("gears")
|
||||
local awful = require("awful")
|
||||
local beautiful = require("beautiful")
|
||||
|
||||
return function(args)
|
||||
local style = awmtk2.create_style("base",awmtk2.default,args.style)
|
||||
local templates = awmtk2.create_template_lib("base",awmtk2.templates,args.templates)
|
||||
local t = awmtk2.build_templates(templates,style)
|
||||
local widget = wibox.widget(t.container(t.textbox({markup = "Why are you loading this widget bruh"})))
|
||||
return widget
|
||||
end
|
|
@ -0,0 +1,43 @@
|
|||
-- wibox.widget.textclock but with awmtk2 templates.
|
||||
local awmtk2 = require("awmtk2")
|
||||
local wibox = require("wibox")
|
||||
local gears = require("gears")
|
||||
local awful = require("awful")
|
||||
local beautiful = require("beautiful")
|
||||
local glib = require("lgi").GLib
|
||||
local DateTime = glib.DateTime
|
||||
local TimeZone = glib.TimeZone
|
||||
|
||||
return function(args)
|
||||
local style = awmtk2.create_style("clock",awmtk2.default,args.style)
|
||||
local templates = awmtk2.create_template_lib("clock",awmtk2.templates,args.templates)
|
||||
local t = awmtk2.build_templates(templates,style)
|
||||
-- Don't mind me just stealing default library code
|
||||
local format = args.format or "%a %b %d, %H:%M"
|
||||
local refresh = args.refresh or 60
|
||||
local tzid = args.tzid
|
||||
local timezone = (tzid and TimeZone.new(tzid)) or TimeZone.new_local()
|
||||
|
||||
-- Seriously, was it so hard to add a font parameter for textclock?
|
||||
-- Do you actually expect of nobody to change the font to something like
|
||||
-- idk, 7-segment display? Goddamnit awesome. I trusted you.
|
||||
local widget = wibox.widget(t.container(t.textbox({
|
||||
id = "clocktext"
|
||||
})))
|
||||
local textbox = widget:get_children_by_id("clocktext")[1]
|
||||
widget.clocktimer = gears.timer {
|
||||
timeout = refresh,
|
||||
call_now = true,
|
||||
autostart = true,
|
||||
callback = function()
|
||||
local str = DateTime.new_now(timezone):format(format)
|
||||
if str == nil then
|
||||
require("gears.debug").print_warning("clock: "
|
||||
.. "g_date_time_format() failed for format "
|
||||
.. "'" .. format .. "'")
|
||||
end
|
||||
textbox:set_markup(str)
|
||||
end
|
||||
}
|
||||
return widget
|
||||
end
|
|
@ -0,0 +1,14 @@
|
|||
-- For those rare occasions when you want to group widgets in a panel
|
||||
local awmtk2 = require("awmtk2")
|
||||
local wibox = require("wibox")
|
||||
local gears = require("gears")
|
||||
local awful = require("awful")
|
||||
local beautiful = require("beautiful")
|
||||
|
||||
return function(args)
|
||||
local style = awmtk2.create_style("subpanel",awmtk2.default,args.style)
|
||||
local templates = awmtk2.create_template_lib("subpanel",awmtk2.templates,args.templates)
|
||||
local t = awmtk2.build_templates(templates,style)
|
||||
local widget = wibox.widget(t.container(args.layout))
|
||||
return widget
|
||||
end
|
|
@ -96,6 +96,8 @@ return function(args)
|
|||
awful.key({ global.modkey }, "r", function()
|
||||
results_list:reset()
|
||||
launchpad.visible = true
|
||||
launchpad.x = args.x or 0
|
||||
launchpad.y = args.y or 0
|
||||
if launchpad.visible then
|
||||
awful.prompt.run {
|
||||
prompt = "<b>Run: </b>",
|
||||
|
|
|
@ -0,0 +1,122 @@
|
|||
local awful = require("awful")
|
||||
local wibox = require("wibox")
|
||||
local gears = require("gears")
|
||||
local awmtk2 = require("awmtk2")
|
||||
local tasklist_buttons = gears.table.join(
|
||||
awful.button({}, 1, function(c)
|
||||
if c == client.focus then
|
||||
c.minimized = true
|
||||
else
|
||||
c:emit_signal(
|
||||
"request::activate",
|
||||
"tasklist",
|
||||
{raise = true}
|
||||
)
|
||||
end
|
||||
end),
|
||||
awful.button({}, 4, function()
|
||||
awful.client.focus.byidx(1)
|
||||
end),
|
||||
awful.button({}, 5, function()
|
||||
awful.client.focus.byidx(-1)
|
||||
end)
|
||||
)
|
||||
|
||||
return function(args)
|
||||
local style = awmtk2.create_style("tasklist", awmtk2.default, args.style)
|
||||
local templates = awmtk2.create_template_lib("tasklist", awmtk2.templates, args.templates)
|
||||
local t = awmtk2.build_templates(templates,style)
|
||||
local button = t.button({
|
||||
{
|
||||
{
|
||||
id = "clienticon",
|
||||
widget = awful.widget.clienticon
|
||||
},
|
||||
(not args.vertical) and t.textbox({
|
||||
id = "text_role"
|
||||
}),
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
strategy="exact",
|
||||
width = style.button.width,
|
||||
height = style.button.height,
|
||||
id = "constraint_task"
|
||||
},{
|
||||
create_callback = function(self, c, index, objects)
|
||||
self:get_children_by_id('clienticon')[1].client = c
|
||||
-- If for some ungodly reason you enabled the behaviour of the original awesomewm, this script will just stop after setting the client icon.
|
||||
if self.id == "background_role" then
|
||||
return
|
||||
end
|
||||
local textbox = self:get_children_by_id("text_role")[1] or {}
|
||||
-- Apparently the original system for changing bgimage is
|
||||
-- 1) broken
|
||||
-- 2) uses deprecated functions (nice code practices awesomewm)
|
||||
-- Solution: write my own. I blame material design for all this.
|
||||
-- (P.S: Not to bullshit you, check it yourself - replicatable
|
||||
-- by adding theme.tasklist_bg_image_normal or
|
||||
-- theme.tasklist_bg_image_focus in current beautiful theme.)
|
||||
local onfocus = function()
|
||||
self.bgimage = style.button.bgimage_focus
|
||||
self.bg = style.button.bg_focus
|
||||
self.shape = style.button.shape_focus
|
||||
self.shape_border_width = style.button.shape_border_width_focus
|
||||
self.shape_border_color = style.button.shape_border_color_focus
|
||||
textbox.font = style.textbox.font_focus
|
||||
end
|
||||
local onunfocus = function()
|
||||
self.bgimage = style.button.bgimage_normal
|
||||
self.bg = style.button.bg_normal
|
||||
self.shape = style.button.shape_normal
|
||||
self.shape_border_width = style.button.shape_border_width_normal
|
||||
self.shape_border_color = style.button.shape_border_color_normal
|
||||
textbox.font = style.textbox.font_normal
|
||||
end
|
||||
local onurgent = function()
|
||||
if not c.urgent then return end
|
||||
self.bgimage = style.button.bgimage_urgent
|
||||
self.bg = style.button.bg_urgent
|
||||
self.shape = style.button.shape_urgent
|
||||
self.shape_border_width = style.button.shape_border_width_urgent
|
||||
self.shape_border_color = style.button.shape_border_color_urgent
|
||||
textbox.font = style.textbox.font_urgent
|
||||
end
|
||||
local onminimize = function()
|
||||
if not c.minimized then return end
|
||||
self.bgimage = style.button.bgimage_minimize
|
||||
self.bg = style.button.bg_minimize
|
||||
self.shape = style.button.shape_minimize
|
||||
self.shape_border_width = style.button.shape_border_width_minimize
|
||||
self.shape_border_color = style.button.shape_border_color_minimize
|
||||
textbox.font = style.textbox.font_minimize
|
||||
end
|
||||
c:connect_signal("focus",onfocus)
|
||||
c:connect_signal("unfocus",onunfocus)
|
||||
c:connect_signal("property::urgent",onurgent)
|
||||
c:connect_signal("property::minimized",onminimize)
|
||||
onfocus()
|
||||
end,
|
||||
-- Uncomment this only, and **ONLY** if you actually need it.
|
||||
--id = "background_role"
|
||||
})
|
||||
return awful.widget.tasklist {
|
||||
screen = args.screen,
|
||||
filter = awful.widget.tasklist.filter.currenttags,
|
||||
buttons = tasklist_buttons,
|
||||
layout = {
|
||||
-- basically we just map every property of this to beautiful.tasklist.base
|
||||
spacing = style.base.spacing,
|
||||
spacing_widget = style.base.spacing_widget,
|
||||
-- Now THIS is shit racing
|
||||
layout = (
|
||||
(args.vertical and style.base.layout_vertical) or
|
||||
style.base.layout_horizontal
|
||||
) or (
|
||||
(args.vertical and wibox.layout.fixed.vertical) or
|
||||
wibox.layout.fixed.horizontal
|
||||
)
|
||||
},
|
||||
widget_template = button
|
||||
}
|
||||
end
|