diff --git a/css/general.css b/css/general.css index f1b08356..0cbea7c9 100644 --- a/css/general.css +++ b/css/general.css @@ -664,6 +664,18 @@ padding: 0; background-color: var(--color-menu_separator); } + li.menu_separator.has_label { + margin-top: 12px; + margin-bottom: 6px; + } + li.menu_separator.has_label > label { + background-color: var(--color-bright_ui); + color: color-mix(in srgb, var(--color-bright_ui_text) 70%, transparent); + margin-top: -12px; + margin-left: 12px; + padding: 0 5px; + height: 20px; + } .contextMenu li.highlighted { animation: menu_item_highlight 1s infinite ease-in-out; } diff --git a/js/interface/actions.js b/js/interface/actions.js index 7cd6c8a5..8804495b 100644 --- a/js/interface/actions.js +++ b/js/interface/actions.js @@ -1,10 +1,5 @@ var Toolbars, BarItems, Toolbox; //Bars -class MenuSeparator { - constructor() { - this.menu_node = Interface.createElement('li', {class: 'menu_separator'}); - } -} class BarItem { constructor(id, data) { this.id = id; diff --git a/js/interface/menu.js b/js/interface/menu.js index 0677df73..236fad42 100644 --- a/js/interface/menu.js +++ b/js/interface/menu.js @@ -1,5 +1,15 @@ var open_menu = null; - +class MenuSeparator { + constructor(id, label) { + this.id = id || ''; + this.menu_node = Interface.createElement('li', {class: 'menu_separator', menu_separator_id: id}); + if (label) { + label = tl(label); + this.menu_node.append(Interface.createElement('label', {}, label)); + this.menu_node.classList.add('has_label'); + } + } +} function handleMenuOverflow(node) { node = node.get(0); if (!node) return; @@ -275,7 +285,12 @@ class Menu { let scope_context = context; var entry; if (s === '_') { - entry = new MenuSeparator().menu_node + s = new MenuSeparator(); + } else if (typeof s == 'string' && s.startsWith('#')) { + s = new MenuSeparator(s.substring(1)); + } + if (s instanceof MenuSeparator) { + entry = s.menu_node; var last = parent.children().last() if (last.length && !last.hasClass('menu_separator')) { parent.append(entry) @@ -542,21 +557,38 @@ class Menu { if (this.structure instanceof Array == false) return; if (path === undefined) path = ''; if (typeof path !== 'string') path = path.toString(); - var track = path.split('.') + let track = path.split('.') function traverse(arr, layer) { - if (track.length === layer || track[layer] === '' || !isNaN(parseInt(track[layer]))) { - var index = arr.length; + if (track.length === layer || !track[layer] === '' || !isNaN(parseInt(track[layer])) || (track[layer][0] == '#')) { + let index = arr.length; if (track[layer] !== '' && track.length !== layer) { - index = parseInt(track[layer]) + if (track[layer].startsWith('#')) { + // Group Anchor + let group = track[layer].substring(1); + let group_match = false; + index = 0; + for (let item of arr) { + if (item instanceof MenuSeparator) { + if (item.id == group) { + group_match = true; + } else if (group_match && item.id != group) { + break; + } + } + index++; + } + } else { + index = parseInt(track[layer]) + } } arr.splice(index, 0, action) } else { - for (var i = 0; i < arr.length; i++) { - var item = arr[i] + for (let i = 0; i < arr.length; i++) { + let item = arr[i] if (item.children instanceof Array && item.id === track[layer] && layer < 20) { - traverse(item.children, layer+1) - i = 1000 + traverse(item.children, layer+1); + break; } } }