From 4d5b43a75e274f16ed115df12dd8f41109006e56 Mon Sep 17 00:00:00 2001 From: Damien Leone Date: Wed, 22 Oct 2008 14:22:48 +0200 Subject: [PATCH] awful.menu: import Signed-off-by: Julien Danjou --- icons/submenu.png | Bin 0 -> 481 bytes lib/awful/init.lua.in | 1 + lib/awful/menu.lua.in | 208 ++++++++++++++++++++++++++++++++++++++++ lib/awful/widget.lua.in | 13 ++- themes/default.in | 7 ++ 5 files changed, 226 insertions(+), 3 deletions(-) create mode 100644 icons/submenu.png create mode 100644 lib/awful/menu.lua.in diff --git a/icons/submenu.png b/icons/submenu.png new file mode 100644 index 0000000000000000000000000000000000000000..391ccf78bafdbd62c38039199e5616625c5af975 GIT binary patch literal 481 zcmV<70UrK|P)P000>X1^@s6#OZ}&00004b3#c}2nYxW zd_ zq9zMXs?9*9*c^>wkN}&6cYt^I!gdD)6n4KBDNaD)-rzXf)6U+{&Uw!d0}#K*j_<;D zAg=3PipZ`Ph_R^gwr$(v@%SSWiCiZVi8~Q-*H(ZZ(`+_191c?~7RRdkIvfs97tLLj zrHF_iBE;iy%H^`7s?Wf&FUUNpRElb~+E>*_;LsOjo=he~yym_eXfy3Jk*_ zpU=Oy+wHDpSyw>7)9uP;vu>l&Fnhh;EfDdv@#%D$TCHZO>H~1#=@CvQlT<2|zN$U} zN1k5BXf#TxRB}}HWjdXn{I&Q>WH1=ms@finMrZ35Ux@(cKyXt4Sp3v`Ikw>Y{ddSG XA0~pugqa}Y00000NkvXXu0mjf2{OuI literal 0 HcmV?d00001 diff --git a/lib/awful/init.lua.in b/lib/awful/init.lua.in index 4dbc566a..8346637a 100644 --- a/lib/awful/init.lua.in +++ b/lib/awful/init.lua.in @@ -16,6 +16,7 @@ local tag = require("awful.tag") local titlebar = require("awful.titlebar") local util = require("awful.util") local widget = require("awful.widget") +local menu = require("awful.menu") local ipairs = ipairs local unpack = unpack diff --git a/lib/awful/menu.lua.in b/lib/awful/menu.lua.in new file mode 100644 index 00000000..52d69f41 --- /dev/null +++ b/lib/awful/menu.lua.in @@ -0,0 +1,208 @@ +--------------------------------------------------------------------------- +-- @author Damien Leone <damien.leone@gmail.com> +-- @copyright 2008 Damien Leone +-- @release @AWESOME_VERSION@ +--------------------------------------------------------------------------- + +-- Grab environment we need +local table = table +local type = type +local wibox = wibox +local image = image +local string = string +local widget = widget +local button = button +local capi = { screen = screen, mouse = mouse } +local util = require("awful.util") +local awbeautiful = require("awful.beautiful") + +--- Menu module for awful +module("awful.menu") + +-- Table containing all currently opened menus +local menus = {} + +-- Theme table +local theme + +local function load_theme() + local beautiful + beautiful = awbeautiful.get() + + theme = {} + theme.fg_focus = beautiful.menu_fg_focus or beautiful.fg_focus + theme.bg_focus = beautiful.menu_bg_focus or beautiful.bg_focus + theme.fg_normal = beautiful.menu_fg_normal or beautiful.fg_normal + theme.bg_normal = beautiful.menu_bg_normal or beautiful.bg_normal + + theme.submenu_icon = beautiful.menu_submenu_icon or "@AWESOME_ICON_PATH@/submenu.png" + + theme.menu_height = beautiful.menu_height or 15 + theme.menu_width = beautiful.menu_width or 100 + + theme.border = beautiful.menu_border_color or beautiful.border_normal + theme.border_width = beautiful.menu_border_width or beautiful.border_width +end + +local function mouse_enter(w) + w.fg = theme.fg_focus + w.bg = theme.bg_focus +end + +local function mouse_leave(w) + w.fg = theme.fg_normal + w.bg = theme.bg_normal +end + +local function destroy(data) + if data then + -- Remove items from screen + for i = 1, #data.items do + data.items[i].screen = nil + end + + -- Clean memory, dirty but I'm lazy + for i = 1, #data.items do + table.remove(data.items) + end + + destroy(data.child) + + -- Remove menu from menus table + menus[data.id] = nil + end +end + +local function get_parents(data) + local p_data = data + + -- Get the elder parent so when you kill + -- it he will destroy the whole family + while p_data.parent do + p_data = p_data.parent + end + + return p_data +end + +local function exec(data, action, num) + if type(action[2]) == "table" then + destroy(data.child) + data.child = new(action[1], action[2], data, num) + elseif type(action[2]) == "string" then + destroy(get_parents(data)) + util.spawn(action[2]) + end +end + +local function add_item(data, num, item_info) + local item = wibox({ + name = data.id .. "item" .. num, + position = "floating", + fg = theme.fg_normal, + bg = theme.bg_normal, + border_color = theme.border, + border_width = theme.border_width + }) + + -- Create bindings + local bindings = { + button({}, 1, function () exec(data, item_info, num) end), + button({}, 3, function () destroy(data) end) + } + + -- Create the item icon widget + local icon = nil + if item_info[3] then + icon = widget({ type = "imagebox", name = "icon", align = "left" }) + icon.image = image(item_info[3]) + icon:buttons(bindings) + + function icon.mouse_enter() mouse_enter(item) end + function icon.mouse_leave() mouse_leave(item) end + end + + -- Create the item label widget + local label = widget({ + type = "textbox", + name = data.id .. "label" .. num, + align = "flex" + }) + label.text = string.format(" %s", item_info[1]) + label:buttons(bindings) + + function label.mouse_enter() mouse_enter(item) end + function label.mouse_leave() mouse_leave(item) end + + -- Create the submenu icon widget + local submenu = nil + if type(item_info[2]) == "table" then + submenu = widget({ type = "imagebox", name = "submenu", align = "right" }) + submenu.image = image(theme.submenu_icon) + submenu:buttons(bindings) + + function submenu.mouse_enter() mouse_enter(item) end + function submenu.mouse_leave() mouse_leave(item) end + end + + -- Add widgets to the wibox + item.widgets = {icon, label, submenu} + + item:geometry({ + width = theme.menu_width, + height = theme.menu_height, + x = data.x, + y = data.y + theme.menu_height*(num - 1) + }) + + item.ontop = true + item.screen = data.screen + + return item +end + +--- Open a menu popup +-- @param id Menu id, string naming your menu, only one menu with the same id can be displayed on screen at the same time +-- @param items Table containing the displayed items, each element is a tab containing: item name, tiggered action or submenu table, item icon (optional) +-- @param parent Specify the parent menu if we want to open a submenu, this value should never be set by the user +-- @param num Specify the parent's clicked item number if we want to open a submenu, this value should never be set by the user +function new(id, items, parent, num) + -- Load config only one time + if not theme then + load_theme() + end + + -- Close the menu if it was already opened + if menus[id] then + destroy(menus[id]) + end + + -- Create a table to store our menu informations + local data = {} + data.id = id + data.screen = capi.mouse.screen + data.nb_items = #items + data.items = {} + data.child = nil + + if parent then + data.x = parent.x + theme.menu_width + theme.border_width + data.y = parent.y + theme.menu_height*(num - 1) + data.parent = parent + else + local m_coords = capi.mouse.coords() + data.x = m_coords.x + data.y = m_coords.y + data.parent = nil + end + + -- Create items + for i = 1, data.nb_items do + table.insert(data.items, add_item(data, i, items[i])) + end + + -- Add menu to menus table + menus[id] = data + + return data +end diff --git a/lib/awful/widget.lua.in b/lib/awful/widget.lua.in index cfd45c26..a0c241c8 100644 --- a/lib/awful/widget.lua.in +++ b/lib/awful/widget.lua.in @@ -19,6 +19,7 @@ local capi = local util = require("awful.util") local hooks = require("awful.hooks") local beautiful = require("awful.beautiful") +local menu = require("awful.menu") --- Widget module for awful module("awful.widget") @@ -372,13 +373,19 @@ end --- Create a button widget which will launch a command. -- @param args Standard widget table arguments, plus image for the image path --- and command for the command to run on click. +-- and command for the command to run on click, or either menu to create menu. -- @return A launcher widget. function launcher(args) - if not args.command then return end + if not args.command and not args.menu then return end local w = button(args) local b = w:buttons() - b[#b + 1] = capi.button({}, 1, nil, function () util.spawn(args.command) end) + + if args.command then + b[#b + 1] = capi.button({}, 1, nil, function () util.spawn(args.command) end) + elseif args.menu then + b[#b + 1] = capi.button({}, 1, nil, function () menu.new(args.menu[1], args.menu[2]) end) + end + w:buttons(b) return w end diff --git a/themes/default.in b/themes/default.in index 31ce622c..0fa64ae9 100644 --- a/themes/default.in +++ b/themes/default.in @@ -25,6 +25,13 @@ border_marked = #91231c # Example: #taglist_bg_focus = #ff0000 +# Variables set for theming menu +# menu_[bg|fg]_[normal|focus] +# menu_[border_color|border_width] +# menu_submenu_icon = @AWESOME_ICONS_PATH@/submenu.png +menu_height = 15 +menu_width = 100 + # Display the taglist squares taglist_squares = true