-- This file is part of Reno desktop. -- -- Reno desktop is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. -- -- Reno desktop is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License along with Reno desktop. If not, see . -- POLYMENU - brutal deluxe -- This isn't in the widgets folder because it's too meta to be there local awful = require("awful") local gears = require("gears") local menubar_utils = require("menubar.utils") local wibox = require("wibox") local awmtk2 = require("awmtk2") local function position_popup(popup,widget,style) -- Position the popup somewhere nearby our original widget popup:move_next_to(mouse.current_wibox) -- Figure out the geometry of the base widget local widget_geo for k,v in pairs(mouse.current_widgets or {}) do if (widget == v) and mouse.current_widget_geometries then widget_geo = mouse.current_widget_geometries[k] end end -- Align y coordinate of the popup to the button if widget_geo then local wibox_geo = mouse.current_wibox:geometry() if popup.current_anchor == "front" then popup.y = widget_geo.y + wibox_geo.y - style.popup.margins else popup.y = widget_geo.y + wibox_geo.y + style.popup.margins + widget_geo.height - popup:geometry().height end end -- Finally, make widget visible popup.visible = true end return function(args) -- A way to communicate that all widgets in menu got closed args.on_close = args.on_close or function() end local style = awmtk2.create_style("menu", awmtk2.default, args.style) local templates = awmtk2.create_template_lib("menu", awmtk2.templates, args.templates) local t = awmtk2.build_templates(templates,style) local function menu_builder(element,layer,root_layer) local new_element = wibox.widget(t.button(t.article({ icon = element[3], resize = true, title = element[1] }),{ forced_width = style.button.forced_width, forced_height = style.button.forced_height })) local onpress = function(widget) style.button.onrelease(widget) widget:emit_signal("cascade::kill") if root_layer.focused then root_layer.focused:emit_signal("cascade::kill") end end if type(element[2]) == "string" then new_element:connect_signal("button::press",style.button.onpress) new_element:connect_signal("button::press",function(widget) awful.spawn(element[2]) end) new_element:connect_signal("button::release",onpress) elseif type(element[2]) == "function" then new_element:connect_signal("button::press",style.button.onpress) new_element:connect_signal("button::press",element[2]) new_element:connect_signal("button::release",onpress) elseif type(element[2]) == "table" then local layout = { spacing = style.base.spacing, layout = wibox.layout.fixed.vertical } for k,v in pairs(element[2]) do table.insert(layout,menu_builder(v,layout,root_layer)) end local next_layer = awful.popup(t.popup(layout,{ visible = false, ontop = true, preferred_positions = {"right","left"}, preferred_anchors = {"front","back"}, })) local function open_layer(widget) if layer.focused == widget and next_layer.visible then return end if layer.focused then layer.focused:emit_signal("cascade::close") end layer.focused = widget position_popup(next_layer, new_element, style) end local onclose = function() style.button.onrelease(new_element) if layout.focused then layout.focused:emit_signal("cascade::close") end next_layer.visible = false end new_element:connect_signal("cascade::close",onclose) new_element:connect_signal("cascade::kill",onclose) -- that sweet "just move the mouse 4head" navigation if style.base.menu_slide then new_element:connect_signal("mouse::enter",open_layer) new_element:connect_signal("mouse::enter",style.button.onpress) else new_element:connect_signal("button::press",style.button.onpress) new_element:connect_signal("button::press",open_layer) end end return new_element end local root_layer = { layout = wibox.layout.fixed.vertical, id = "menu_root", spacing = style.base.spacing } for k,v in pairs(args.items) do table.insert(root_layer,menu_builder(v,root_layer,root_layer)) end return root_layer end