From 1d2f4a102ed4fe4c536a76d03b91c19001f48ec6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20D=C3=A9saulniers?= Date: Wed, 14 Feb 2018 17:04:06 -0500 Subject: [PATCH] menu_iterator: generic menu creator function A simple example usage is given over on the amh project~[1] [1]: https://github.com/sim590/amh/blob/dcf101c8ef74921de513c0b1dee294606fc6befe/exec/mpv.lua#L32 --- util/menu_iterator.lua | 75 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 74 insertions(+), 1 deletion(-) diff --git a/util/menu_iterator.lua b/util/menu_iterator.lua index 071f16f..913482a 100644 --- a/util/menu_iterator.lua +++ b/util/menu_iterator.lua @@ -10,6 +10,7 @@ -- Menu iterator using naughty.notify local naughty = require("naughty") +local util = require("lain.util") local state = { cid = nil } @@ -63,4 +64,76 @@ local function iterate(menu, timeout, icon) }).id end -return { iterate = iterate } +-- Generates a menu compatible with the iterate function argument and suitable +-- for the following cases: +-- * all possible choices individually. +-- * all possible choices are all the possible subsets of the set of individual +-- choices (the powerset) +-- +-- The following describes the function arguments: +-- * args: an array containing the following members: +-- * choices: the list of choices from which to generate the menu +-- * name: the displayed name of the menu (in the form "name: choices") +-- * selected_cb: the callback to execute for each selected choice. Takes +-- the choice as a string argument. The function +-- menu_iterator.naughty_destroy_callback will handle nil +-- callbacks. It is then fine to pass nil callbacks. +-- * rejected_cb: the callback to execute for each rejected choice (in the +-- set of possible choices, but not selected). Takes the +-- choice as a string argument. The function +-- menu_iterator.naughty_destroy_callback will handle nil +-- callbacks. It is then fine to pass nil callbacks. +-- * extra_choices: an array of pairs { choice_text, cb } for extra choices to +-- be added to the menu. The function +-- menu_iterator.naughty_destroy_callback will handle nil +-- callbacks. It is then fine to pass nil callbacks. +-- * combination: the combination of choice to generate. Possible choices +-- are "powerset" and "single" (the default). +local function menu(args) + local choices = assert(args.choices or args[1]) + local name = assert(args.name or args[2]) + local selected_cb = args.selected_cb + local rejected_cb = args.rejected_cb + local extra_choices = args.extra_choices or {} + + local ch_combinations = args.combination == "powerset" and helpers.powerset(choices) or helpers.trivial_partition_set(choices) + for _,c in pairs(extra_choices) do + ch_combinations = awful.util.table.join(ch_combinations, {{c[1]}}) + end + + local m = {} + for _,c in pairs(ch_combinations) do + if #c > 0 then + local cbs = {} + -- selected choices + for _,ch in pairs(c) do + if awful.util.table.hasitem(choices, ch) then + cbs[#cbs + 1] = selected_cb and function() selected_cb(ch) end or nil + end + end + + -- rejected choices + for _,ch in pairs(choices) do + if not awful.util.table.hasitem(c, ch) and awful.util.table.hasitem(choices, ch) then + cbs[#cbs + 1] = rejected_cb and function() rejected_cb(ch) end or nil + end + end + + -- add user extra choices (like the choice "None" for e.g.) + for _,x in pairs(extra_choices) do + if x[1] == c[1] then + cbs[#cbs + 1] = x[2] + end + end + + m[#m + 1] = { name .. ": " .. table.concat(c, " + "), cbs } + end + end + + return m +end + +return { + iterate = iterate, + menu = menu +}