Support the modification of individual items withing a menu bar

This commit is contained in:
Nariman Jelveh 2024-06-12 19:18:24 -07:00
parent cdff12e4e0
commit 72641c66a2
6 changed files with 103 additions and 10 deletions

View File

@ -678,6 +678,26 @@ class UI extends EventListener {
this.#postMessageWithObject('setMenubar', spec);
}
disableMenuItem = function(item_id) {
this.#postMessageWithObject('disableMenuItem', {id: item_id});
}
enableMenuItem = function(item_id) {
this.#postMessageWithObject('enableMenuItem', {id: item_id});
}
setMenuItemIcon = function(item_id, icon) {
this.#postMessageWithObject('setMenuItemIcon', {id: item_id, icon: icon});
}
setMenuItemIconActive = function(item_id, icon) {
this.#postMessageWithObject('setMenuItemIconActive', {id: item_id, icon: icon});
}
setMenuItemChecked = function(item_id, checked) {
this.#postMessageWithObject('setMenuItemChecked', {id: item_id, checked: checked});
}
contextMenu = function(spec) {
this.#postMessageWithObject('contextMenu', spec);
}

View File

@ -393,7 +393,6 @@ window.addEventListener('message', async (event) => {
// get parent window
const el_window = window.window_for_app_instance(event.data.appInstanceID);
let items = value.items ?? [];
const sanitize_items = items => {
return items.map(item => {
@ -432,6 +431,36 @@ window.addEventListener('message', async (event) => {
$(target_iframe).get(0).focus({preventScroll:true});
}
// --------------------------------------------------------
// disableMenuItem
// --------------------------------------------------------
else if(event.data.msg === 'disableMenuItem'){
set_menu_item_prop(window.menubars[event.data.appInstanceID], event.data.value.id, 'disabled', true);
}
// --------------------------------------------------------
// enableMenuItem
// --------------------------------------------------------
else if(event.data.msg === 'enableMenuItem'){
set_menu_item_prop(window.menubars[event.data.appInstanceID], event.data.value.id, 'disabled', false);
}
//--------------------------------------------------------
// setMenuItemIcon
//--------------------------------------------------------
else if(event.data.msg === 'setMenuItemIcon'){
set_menu_item_prop(window.menubars[event.data.appInstanceID], event.data.value.id, 'icon', event.data.value.icon);
}
//--------------------------------------------------------
// setMenuItemIconActive
//--------------------------------------------------------
else if(event.data.msg === 'setMenuItemIconActive'){
set_menu_item_prop(window.menubars[event.data.appInstanceID], event.data.value.id, 'icon_active', event.data.value.icon_active);
}
//--------------------------------------------------------
// setMenuItemChecked
//--------------------------------------------------------
else if(event.data.msg === 'setMenuItemChecked'){
set_menu_item_prop(window.menubars[event.data.appInstanceID], event.data.value.id, 'checked', event.data.value.checked);
}
//--------------------------------------------------------
// setMenubar
//--------------------------------------------------------
@ -452,6 +481,9 @@ window.addEventListener('message', async (event) => {
e.preventDefault();
});
if(!window.menubars[event.data.appInstanceID])
window.menubars[event.data.appInstanceID] = value.items;
const sanitize_items = items => {
return items.map(item => {
// Check if the item is just '-'
@ -461,6 +493,10 @@ window.addEventListener('message', async (event) => {
// Otherwise, proceed as before
return {
html: item.label,
disabled: item.disabled,
checked: item.checked,
icon: item.icon ? `<img style="width: 15px; height: 15px; position: absolute; top: 4px; left: 6px;" src="${html_encode(item.icon)}" />` : undefined,
icon_active: item.icon_active ? `<img style="width: 15px; height: 15px; position: absolute; top: 4px; left: 6px;" src="${html_encode(item.icon_active)}" />` : undefined,
action: item.action,
items: item.items ? sanitize_items(item.items) : undefined
};
@ -489,8 +525,8 @@ window.addEventListener('message', async (event) => {
// Open the context menu
const ctxMenu = UIContextMenu({
delay,
parent_element,
delay: delay,
parent_element: parent_element,
position: {top: pos.top + 30, left: pos.left},
css: {
'box-shadow': '0px 2px 6px #00000059'
@ -517,9 +553,13 @@ window.addEventListener('message', async (event) => {
const item = items[i];
const label = html_encode(item.label);
const el_item = $(`<div class="window-menubar-item"><span>${label}</span></div>`);
const parent_element = el_item.parent()[0];
const parent_element = el_item.get(0);
el_item.on('mousedown', (e) => {
// check if it has has-open-context-menu class
if ( el_item.hasClass('has-open-contextmenu') ) {
return;
}
if ( state_open ) {
state_open = false;
current && current.cancel({ meta: 'menubar' });
@ -563,7 +603,7 @@ window.addEventListener('message', async (event) => {
menubar_buttons.push(el_item);
}
};
add_items($menubar, value.items);
add_items($menubar, window.menubars[event.data.appInstanceID]);
}
//--------------------------------------------------------
// setWindowWidth

View File

@ -21,7 +21,6 @@ function UIContextMenu(options){
$('.window-active .window-app-iframe').css('pointer-events', 'none');
const menu_id = window.global_element_id++;
let h = '';
h += `<div
id="context-menu-${menu_id}"
@ -42,8 +41,13 @@ function UIContextMenu(options){
class="context-menu-item ${options.items[i].disabled ? ' context-menu-item-disabled' : ''}"
>`;
// icon
h += `<span class="context-menu-item-icon">${options.items[i].icon ?? ''}</span>`;
h += `<span class="context-menu-item-icon-active">${options.items[i].icon_active ?? (options.items[i].icon ?? '')}</span>`;
if(options.items[i].checked === true){
h += `<span class="context-menu-item-icon">✓</span>`;
h += `<span class="context-menu-item-icon-active">✓</span>`;
}else{
h += `<span class="context-menu-item-icon">${options.items[i].icon ?? ''}</span>`;
h += `<span class="context-menu-item-icon-active">${options.items[i].icon_active ?? (options.items[i].icon ?? '')}</span>`;
}
// label
h += `<span class="contextmenu-label">${options.items[i].html}</span>`;
h += `<span class="contextmenu-label-active">${options.items[i].html_active ?? options.items[i].html}</span>`;
@ -275,7 +279,11 @@ function UIContextMenu(options){
if(options.parent_element){
$(options.parent_element).parent().removeClass('children-have-open-contextmenu');
$(options.parent_element).css('overflow', 'scroll');
// if the parent element is not a window, make it scrollable again
if (!$(options.parent_element).hasClass('window-body')) {
$(options.parent_element).css('overflow', 'scroll');
}
$(options.parent_element).removeClass('has-open-contextmenu');
if($(options.parent_element).hasClass('taskbar-item')){
window.make_taskbar_sortable()

View File

@ -2807,16 +2807,25 @@ $.fn.close = async function(options) {
$(this).each(async function() {
const el_iframe = $(this).find('.window-app-iframe');
const app_uses_sdk = el_iframe.length > 0 && el_iframe.attr('data-appUsesSDK') === 'true';
// tell child app that this window is about to close, get its response
if(app_uses_sdk){
// get appInstanceID
const appInstanceID = el_iframe.closest('.window').attr('data-element_uuid');
// tell child app that this window is about to close, get its response
if(!options.bypass_iframe_messaging){
const resp = await window.sendWindowWillCloseMsg(el_iframe.get(0));
if(!resp.msg){
return false;
}
}
// remove the menubar from the window.menubars array
if(appInstanceID){
delete window.menubars[appInstanceID];
window.app_instance_ids.delete(appInstanceID);
}
}
if ( this.on_before_exit ) {
if ( ! await this.on_before_exit() ) return false;
}

View File

@ -26,6 +26,7 @@ window.progress_tracker = [];
window.upload_item_global_id = 0;
window.app_instance_ids = new Set();
window.menubars = [];
window.download_progress = [];
window.download_item_global_id = 0;

View File

@ -3587,3 +3587,18 @@ window.check_password_strength = (password) => {
report: criteria_report,
};
}
window.set_menu_item_prop = (items, item_id, prop, val) => {
// iterate over items
for (const item of items) {
// find the item with the given item_id
if (item.id === item_id) {
// set the property value
item[prop] = val;
break;
}
else if(item.items){
set_menu_item_prop(item.items, item_id, prop, val);
}
}
};