]> git.decadent.org.uk Git - ion3.git/blobdiff - ioncore/ioncore_menudb.lua
[svn-upgrade] Integrating new upstream version, ion3 (20070318)
[ion3.git] / ioncore / ioncore_menudb.lua
index 98d86a2c4b2a8041ae74f4191820126486250347..42860548298e9712d6f302b8560e3d6bab1c7052 100644 (file)
@@ -63,34 +63,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 +113,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 +183,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
 
@@ -329,7 +342,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 +368,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 +390,49 @@ local function get_ctxmenu(reg, sub, is_par)
     return m
 end
 
-function menus.ctxmenu(reg, sub)
-    local m=get_ctxmenu(reg, sub, false);
+
+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_or_chld)
+    local m, r, s
     
-    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_chld 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
 
 -- }}}