X-Git-Url: https://git.decadent.org.uk/gitweb/?a=blobdiff_plain;f=ioncore%2Fioncore_menudb.lua;h=62cf04a7622ca95d81861f43c3c313d00487e17d;hb=3102bb90c325d9b29ac304d8f3ea0a17df564fc8;hp=98d86a2c4b2a8041ae74f4191820126486250347;hpb=803afbc1cd633f6c025bcd9537e9b7e9aedadd0d;p=ion3.git diff --git a/ioncore/ioncore_menudb.lua b/ioncore/ioncore_menudb.lua index 98d86a2..62cf04a 100644 --- a/ioncore/ioncore_menudb.lua +++ b/ioncore/ioncore_menudb.lua @@ -1,12 +1,9 @@ -- -- ion/ioncore/ioncore_menudb.lua -- Routines for defining menus. -- --- Copyright (c) Tuomo Valkonen 2004-2007. +-- Copyright (c) Tuomo Valkonen 2004-2008. -- --- Ion is free software; you can redistribute it and/or modify it under --- the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. +-- See the included file LICENSE for details. -- local ioncore=_G.ioncore @@ -48,11 +45,12 @@ end -- of menu entries. function ioncore.defctxmenu(ctx, ...) local tab, add - if #arg>1 and type(arg[1])=="string" then - tab=arg[2] - tab.label=ioncore.gettext(arg[1]) + local a1, a2 = ... + if a2 and type(a1)=="string" then + tab=a2 + tab.label=ioncore.gettext(a1) else - tab=arg[1] + tab=a1 end ioncore.defmenu("ctxmenu-"..ctx, tab) end @@ -63,34 +61,47 @@ function ioncore.getctxmenu(name) return menus["ctxmenu-"..name] end - -function ioncore.evalmenu(menu, args) +function ioncore.evalmenu(menu, ...) if type(menu)=="string" then - return ioncore.evalmenu(menus[menu], args) + return ioncore.evalmenu(menus[menu], ...) elseif type(menu)=="function" then - if args then - return menu(unpack(args)) - else - return menu() - end + return menu(...) elseif type(menu)=="table" then return menu end end - --DOC -- Use this function to define normal menu entries. The string \var{name} --- is the string shown in the visual representation of menu, and the --- parameter \var{cmd} and \var{guard} are similar to those of --- \fnref{ioncore.defbindings}. -function ioncore.menuentry(name, cmd, guard) +-- is the string shown in the visual representation of menu. The +-- parameter \var{cmd} and \var{guard_or_opts} (when string) are similar +-- to those of \fnref{ioncore.defbindings}. If \var{guard_or_opts} is +-- a table, it may contains the \var{guard} field, and the \var{priority} +-- field, for controlling positioning of entries in context menus. +-- (The default priority is 1 for most entries, and -1 for auto-generated +-- submenus.) +function ioncore.menuentry(name, cmd, guard_or_opts) + local guard + local opts + + if type(guard_or_opts)=="string" then + guard=guard_or_opts + elseif type(guard_or_opts)=="table" then + opts=guard_or_opts + guard=opts.guard + end + local fn, gfn=ioncore.compile_cmd(cmd, guard) if fn then - return {name=ioncore.gettext(name), func=fn, guard_func=gfn} + return table.append({ + name=ioncore.gettext(name), + func=fn, + guard_func=gfn, + }, opts or {}) end end + --DOC -- Use this function to define menu entries for submenus. The parameter -- \fnref{sub_or_name} is either a table of menu entries or the name @@ -100,17 +111,12 @@ end -- \var{options.noautoexpand} that will cause \fnref{mod_query.query_menu} -- to not automatically expand this submenu. function ioncore.submenu(name, sub_or_name, options) - if not options then - options={} - end - return { - name=ioncore.gettext(name), - submenu_fn=function() - return ioncore.evalmenu(sub_or_name) - end, - initial=options.initial, - noautoexpand=options.noautoexpand, - } + return table.append({ + name=ioncore.gettext(name), + submenu_fn=function() + return ioncore.evalmenu (sub_or_name) + end, + }, options or {}) end @@ -175,11 +181,16 @@ local function focuslist(do_act) end if do_act then + -- Windows with activity first ioncore.activity_i(iter_act) end + -- The ones that have been focused in their lifetime ioncore.focushistory_i(iter_foc) + -- And then the rest + ioncore.clientwin_i(iter_foc) + return entries end @@ -250,7 +261,7 @@ local function receive_styles(str) local styles={} local stylemenu={} - for look in string.gfind(data, "(look[-_][^\n]*)%.lua\n") do + for look in string.gmatch(data, "(look[-_][^\n]*)%.lua\n") do if not found[look] then found[look]=true table.insert(styles, look) @@ -329,7 +340,7 @@ local function modeparts(mode) end -local function get_ctxmenu(reg, sub, is_par) +local function get_ctxmenu(reg, sub) local m={} local function cp(m2) @@ -355,11 +366,7 @@ local function get_ctxmenu(reg, sub, is_par) local function add_ctxmenu(m2, use_label) if m2 then - if is_par then - m2=cp(m2) - end - - m=table.icat(m, m2) + m=table.icat(m, cp(m2)) m.label=(use_label and m2.label) or m.label end end @@ -381,23 +388,53 @@ local function get_ctxmenu(reg, sub, is_par) return m end + +local function sortmenu(m) + local v=1/2 + + for _, e in ipairs(m) do + e.priority=(e.priority or 1)+v + v=v/2 + end + + table.sort(m, function(e1, e2) return e1.priority > e2.priority end) + + return m +end + + function menus.ctxmenu(reg, sub) - local m=get_ctxmenu(reg, sub, false); + local m, r, s + + if obj_is(sub, "WGroup") then + sub=(sub:bottom() or sub) + end - sub=reg - reg=reg:manager() + -- First, stuff between reg (inclusive) and sub_or_chld (inclusive) + -- at the top level in the menu. + r=(sub or reg) + while r and s~=reg do + local mm=get_ctxmenu(r, s) + m=((m and table.icat(mm, m)) or mm) + s=r + r=r:manager() + end + + m=(m or {}) - while reg do - local mm = get_ctxmenu(reg, sub, true) + -- Then stuff below reg (exclusive) as submenus + while r do + local mm = get_ctxmenu(r, s) if #mm>0 then local nm=mm.label or obj_typename(reg) - table.insert(m, ioncore.submenu(nm, mm)) + local tmp=ioncore.submenu(nm, sortmenu(mm), {priority=-1}) + table.insert(m, tmp) end - sub=reg - reg=reg:manager() + s=r + r=r:manager() end - return m + return sortmenu(m) end -- }}}