--
-- 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
-- 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
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
-- \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
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
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)
end
-local function get_ctxmenu(reg, sub, is_par)
+local function get_ctxmenu(reg, sub)
local m={}
local function cp(m2)
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
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
-- }}}