mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-11-25 01:13:25 +01:00
f430b66d3b
classes are now uppercase and in their own files. lowercase classes are deprecated.
Interfaces are now actual interfaces that should be implemented instead of creating and returning an ai Object every time
(cherry picked from commit 5e3c67a5cf
)
195 lines
4.5 KiB
TypeScript
195 lines
4.5 KiB
TypeScript
/**
|
|
* eGroupWare egw_action framework - JS Menu abstraction
|
|
*
|
|
* @link http://www.egroupware.org
|
|
* @author Andreas Stöckel <as@stylite.de>
|
|
* @copyright 2011 by Andreas Stöckel
|
|
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
|
* @package egw_action
|
|
* @version $Id$
|
|
*/
|
|
|
|
|
|
import {egwMenuItem} from "./egw_menu";
|
|
|
|
/**
|
|
*
|
|
* @param {type} _structure
|
|
*/
|
|
export class egwMenuImpl
|
|
{
|
|
readonly dhtmlxmenu:any;
|
|
constructor(_structure)
|
|
{
|
|
//Create a new dhtmlxmenu object
|
|
// @ts-ignore //origin not easily ts compatible --> soon to be replaced by shoelace anyway
|
|
this.dhtmlxmenu = new dhtmlXMenuObject();
|
|
this.dhtmlxmenu.setSkin("egw");
|
|
this.dhtmlxmenu.renderAsContextMenu();
|
|
// TODO: Keyboard navigation of the menu
|
|
|
|
|
|
//Attach the simple click handler
|
|
this.dhtmlxmenu.attachEvent("onClick", (id) => {
|
|
if (id)
|
|
{
|
|
const elem = this.dhtmlxmenu.getUserData(id, 'egw_menu');
|
|
|
|
if (elem && elem.onClick)
|
|
{
|
|
if (elem.checkbox)
|
|
{
|
|
this.dhtmlxmenu.setContextMenuHideAllMode(false);
|
|
}
|
|
|
|
const res = elem.onClick(elem);
|
|
|
|
if (elem.checkbox && (res === false || res === true))
|
|
{
|
|
const checked = res;
|
|
if (elem.groupIndex != 0)
|
|
{
|
|
this.dhtmlxmenu.setRadioChecked(id, checked);
|
|
} else
|
|
{
|
|
this.dhtmlxmenu.setCheckboxState(id, checked);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
//Attach the radiobutton click handler
|
|
this.dhtmlxmenu.attachEvent("onRadioClick", (group, idChecked, idClicked) => {
|
|
if (idClicked)
|
|
{
|
|
const elem = this.dhtmlxmenu.getUserData(idClicked, 'egw_menu');
|
|
if (elem)
|
|
{
|
|
elem.set_checked(true);
|
|
}
|
|
}
|
|
|
|
return true;
|
|
});
|
|
|
|
//Attach the radiobutton click handler
|
|
this.dhtmlxmenu.attachEvent("onCheckboxClick", (id, state) => {
|
|
if (id)
|
|
{
|
|
const elem = this.dhtmlxmenu.getUserData(id, 'egw_menu');
|
|
if (elem)
|
|
{
|
|
elem.set_checked(!state);
|
|
}
|
|
}
|
|
|
|
return true;
|
|
});
|
|
|
|
|
|
//Translate the given structure to the dhtmlx object structure
|
|
this._translateStructure(_structure, this.dhtmlxmenu.topId, 0);
|
|
|
|
// Add disableIfNoEPL class to the relevant action's DOM
|
|
for (const i in this.dhtmlxmenu.idPull)
|
|
{
|
|
if (this.dhtmlxmenu.userData[i + '_egw_menu'] &&
|
|
this.dhtmlxmenu.userData[i + '_egw_menu']['data'] &&
|
|
this.dhtmlxmenu.userData[i + '_egw_menu']['data']['disableIfNoEPL'])
|
|
{
|
|
this.dhtmlxmenu.idPull[i].className += ' disableIfNoEPL';
|
|
}
|
|
}
|
|
}
|
|
|
|
private _translateStructure(_structure:egwMenuItem[], _parentId: string, _idCnt: number)
|
|
{
|
|
//Initialize the counter which we will use to generate unique id's for all
|
|
//dhtmlx menu objects
|
|
let counter: number = 0;
|
|
let last_id = null;
|
|
|
|
_structure.forEach((elem: egwMenuItem, i: number) =>
|
|
{
|
|
const id = elem.id || 'elem_' + (_idCnt + counter);
|
|
|
|
counter++;
|
|
|
|
//Check whether this element is a separator
|
|
if (elem.caption == '-' && last_id != null)
|
|
{
|
|
//Add the separator next to last_id with the id "id"
|
|
this.dhtmlxmenu.addNewSeparator(last_id, id);
|
|
} else
|
|
{
|
|
if (elem.checkbox && elem.groupIndex === 0)
|
|
{
|
|
//Add checkbox
|
|
this.dhtmlxmenu.addCheckbox("child", _parentId, i, id,
|
|
elem.caption, elem.checked, !elem.enabled);
|
|
} else if (elem.checkbox && elem.groupIndex > 0)
|
|
{
|
|
//Add radiobox
|
|
elem._dhtmlx_grpid = "grp_" + _idCnt + '_' + elem.groupIndex;
|
|
this.dhtmlxmenu.addRadioButton("child", _parentId, i, id,
|
|
elem.caption, elem._dhtmlx_grpid, elem.checked, !elem.enabled);
|
|
} else
|
|
{
|
|
let caption = elem.caption;
|
|
if (elem.default)
|
|
caption = "<b>" + caption + "</b>";
|
|
this.dhtmlxmenu.addNewChild(_parentId, i, id, caption, !elem.enabled,
|
|
elem.iconUrl, elem.iconUrl);
|
|
}
|
|
|
|
if (elem.shortcutCaption != null)
|
|
{
|
|
this.dhtmlxmenu.setHotKey(id, elem.shortcutCaption);
|
|
}
|
|
|
|
if (elem.children.length > 0)
|
|
{
|
|
counter += this._translateStructure(elem.children, id, (_idCnt + counter));
|
|
}
|
|
}
|
|
|
|
//Set the actual egw menu as user data element
|
|
this.dhtmlxmenu.setUserData(id, 'egw_menu', elem);
|
|
|
|
// Set the tooltip if one has been set
|
|
if (elem.hint)
|
|
{
|
|
this.dhtmlxmenu.setTooltip(id, elem.hint);
|
|
}
|
|
|
|
last_id = id;
|
|
})
|
|
|
|
return counter;
|
|
};
|
|
|
|
public showAt(_x, _y, _onHide)
|
|
{
|
|
if (_onHide)
|
|
{
|
|
this.dhtmlxmenu.attachEvent("onHide", (id) => {
|
|
if (id === null)
|
|
{
|
|
_onHide();
|
|
}
|
|
});
|
|
}
|
|
|
|
window.setTimeout(() => {
|
|
this.dhtmlxmenu.showContextMenu(_x, _y);
|
|
// TODO: Get keyboard focus
|
|
}, 0);
|
|
};
|
|
|
|
public hide()
|
|
{
|
|
this.dhtmlxmenu.hide();
|
|
};
|
|
|
|
} |