mirror of
https://github.com/HeyPuter/puter.git
synced 2025-02-02 23:28:39 +08:00
Implement the contextMenu
API for Puter.js
This commit is contained in:
parent
cf8a07286a
commit
a81f461b54
@ -89,8 +89,8 @@ export class Hydrator {
|
||||
) {
|
||||
const { id } = value;
|
||||
return (...args) => {
|
||||
console.log('sending message', { $SCOPE, id, args });
|
||||
console.log('target', this.target);
|
||||
// console.log('sending message', { $SCOPE, id, args });
|
||||
// console.log('target', this.target);
|
||||
this.target.postMessage({ $SCOPE, id, args }, '*');
|
||||
};
|
||||
} else if (Array.isArray(value)) {
|
||||
|
@ -429,6 +429,25 @@ class UI extends EventListener {
|
||||
this.#lastBroadcastValue.set(name, data);
|
||||
}
|
||||
});
|
||||
|
||||
// We need to send the mouse position to the host environment
|
||||
// This is important since a lot of UI elements depend on the mouse position (e.g. ContextMenus, Tooltips, etc.)
|
||||
// and the host environment needs to know the mouse position to show these elements correctly.
|
||||
// The host environment can't just get the mouse position since when the mouse is over an iframe it
|
||||
// will not be able to get the mouse position. So we need to send the mouse position to the host environment.
|
||||
document.addEventListener('mousemove', async (event)=>{
|
||||
// Get the mouse position from the event object
|
||||
this.mouseX = event.clientX;
|
||||
this.mouseY = event.clientY;
|
||||
|
||||
// send the mouse position to the host environment
|
||||
this.messageTarget?.postMessage({
|
||||
msg: "mouseMoved",
|
||||
appInstanceID: this.appInstanceID,
|
||||
x: this.mouseX,
|
||||
y: this.mouseY,
|
||||
}, '*');
|
||||
});
|
||||
}
|
||||
|
||||
onWindowClose = function(callback) {
|
||||
@ -659,6 +678,10 @@ class UI extends EventListener {
|
||||
this.#postMessageWithObject('setMenubar', spec);
|
||||
}
|
||||
|
||||
contextMenu = function(spec) {
|
||||
this.#postMessageWithObject('contextMenu', spec);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asynchronously extracts entries from DataTransferItems, like files and directories.
|
||||
*
|
||||
|
69
src/IPC.js
69
src/IPC.js
@ -355,6 +355,75 @@ window.addEventListener('message', async (event) => {
|
||||
}, '*');
|
||||
}
|
||||
//--------------------------------------------------------
|
||||
// mouseMoved
|
||||
//--------------------------------------------------------
|
||||
else if(event.data.msg === 'mouseMoved'){
|
||||
// Auth
|
||||
if(!window.is_auth() && !(await UIWindowSignup({referrer: app_name})))
|
||||
return;
|
||||
|
||||
// get x and y and sanitize
|
||||
let x = parseInt(event.data.x);
|
||||
let y = parseInt(event.data.y);
|
||||
|
||||
// get parent window
|
||||
const el_window = window.window_for_app_instance(event.data.appInstanceID);
|
||||
|
||||
// get window position
|
||||
const window_position = $(el_window).position();
|
||||
|
||||
// update mouse position
|
||||
update_mouse_position(x + window_position.left, y + window_position.top + 25);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// contextMenu
|
||||
//--------------------------------------------------------
|
||||
else if(event.data.msg === 'contextMenu'){
|
||||
// Auth
|
||||
if(!window.is_auth() && !(await UIWindowSignup({referrer: app_name})))
|
||||
return;
|
||||
|
||||
const hydrator = puter.util.rpc.getHydrator({
|
||||
target: target_iframe.contentWindow,
|
||||
});
|
||||
let value = hydrator.hydrate(event.data.value);
|
||||
|
||||
// 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 => {
|
||||
// Check if the item is just '-'
|
||||
if (item === '-') {
|
||||
return '-';
|
||||
}
|
||||
// Otherwise, proceed as before
|
||||
return {
|
||||
html: item.label,
|
||||
onClick: () => {
|
||||
if (item.action !== undefined) {
|
||||
console.log('item.action', item.action);
|
||||
item.action();
|
||||
}
|
||||
},
|
||||
items: item.items ? sanitize_items(item.items) : undefined
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
items = sanitize_items(items);
|
||||
|
||||
// Open context menu
|
||||
UIContextMenu({
|
||||
items: items,
|
||||
});
|
||||
|
||||
$(target_iframe).get(0).focus({preventScroll:true});
|
||||
}
|
||||
//--------------------------------------------------------
|
||||
// setMenubar
|
||||
//--------------------------------------------------------
|
||||
else if(event.data.msg === 'setMenubar') {
|
||||
|
131
src/initgui.js
131
src/initgui.js
@ -1841,68 +1841,7 @@ window.initgui = async function(){
|
||||
|
||||
// update mouse position coordinates
|
||||
$(document).mousemove(function(event){
|
||||
window.mouseX = event.clientX;
|
||||
window.mouseY = event.clientY;
|
||||
|
||||
// mouse in top-left corner of screen
|
||||
if((window.mouseX < 150 && window.mouseY < window.toolbar_height + 20) || (window.mouseX < 20 && window.mouseY < 150))
|
||||
window.current_active_snap_zone = 'nw';
|
||||
// mouse in left edge of screen
|
||||
else if(window.mouseX < 20 && window.mouseY >= 150 && window.mouseY < window.desktop_height - 150)
|
||||
window.current_active_snap_zone = 'w';
|
||||
// mouse in bottom-left corner of screen
|
||||
else if(window.mouseX < 20 && window.mouseY > window.desktop_height - 150)
|
||||
window.current_active_snap_zone = 'sw';
|
||||
// mouse in right edge of screen
|
||||
else if(window.mouseX > window.desktop_width - 20 && window.mouseY >= 150 && window.mouseY < window.desktop_height - 150)
|
||||
window.current_active_snap_zone = 'e';
|
||||
// mouse in top-right corner of screen
|
||||
else if((window.mouseX > window.desktop_width - 150 && window.mouseY < window.toolbar_height + 20) || (window.mouseX > window.desktop_width - 20 && window.mouseY < 150))
|
||||
window.current_active_snap_zone = 'ne';
|
||||
// mouse in bottom-right corner of screen
|
||||
else if(window.mouseX > window.desktop_width - 20 && window.mouseY >= window.desktop_height - 150)
|
||||
window.current_active_snap_zone = 'se';
|
||||
// mouse in top edge of screen
|
||||
else if(window.mouseY < window.toolbar_height + 20 && window.mouseX >= 150 && window.mouseX < window.desktop_width - 150)
|
||||
window.current_active_snap_zone = 'n';
|
||||
// not in any snap zone
|
||||
else
|
||||
window.current_active_snap_zone = undefined;
|
||||
|
||||
// mouseover_window
|
||||
var windows = document.getElementsByClassName("window");
|
||||
let active_win;
|
||||
if(windows.length > 0){
|
||||
let highest_window_zindex = 0;
|
||||
for(let i=0; i<windows.length; i++){
|
||||
const rect = windows[i].getBoundingClientRect();
|
||||
if( window.mouseX > rect.x && window.mouseX < (rect.x + rect.width) && window.mouseY > rect.y && window.mouseY < (rect.y + rect.height)){
|
||||
if(parseInt($(windows[i]).css('z-index')) >= highest_window_zindex){
|
||||
active_win = windows[i];
|
||||
highest_window_zindex = parseInt($(windows[i]).css('z-index'));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
window.mouseover_window = active_win;
|
||||
|
||||
// mouseover_item_container
|
||||
var item_containers = document.getElementsByClassName("item-container");
|
||||
let active_ic;
|
||||
if(item_containers.length > 0){
|
||||
let highest_window_zindex = 0;
|
||||
for(let i=0; i<item_containers.length; i++){
|
||||
const rect = item_containers[i].getBoundingClientRect();
|
||||
if( window.mouseX > rect.x && window.mouseX < (rect.x + rect.width) && window.mouseY > rect.y && window.mouseY < (rect.y + rect.height)){
|
||||
let active_container_zindex = parseInt($(item_containers[i]).closest('.window').css('z-index'));
|
||||
if( !isNaN(active_container_zindex) && active_container_zindex >= highest_window_zindex){
|
||||
active_ic = item_containers[i];
|
||||
highest_window_zindex = active_container_zindex;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
window.mouseover_item_container = active_ic;
|
||||
update_mouse_position(event.clientX, event.clientY);
|
||||
});
|
||||
|
||||
//--------------------------------------------------------
|
||||
@ -2139,4 +2078,70 @@ $(document).on('contextmenu', '.disable-context-menu', function(e){
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
window.update_mouse_position = function(x, y){
|
||||
window.mouseX = x;
|
||||
window.mouseY = y;
|
||||
|
||||
// mouse in top-left corner of screen
|
||||
if((window.mouseX < 150 && window.mouseY < window.toolbar_height + 20) || (window.mouseX < 20 && window.mouseY < 150))
|
||||
window.current_active_snap_zone = 'nw';
|
||||
// mouse in left edge of screen
|
||||
else if(window.mouseX < 20 && window.mouseY >= 150 && window.mouseY < window.desktop_height - 150)
|
||||
window.current_active_snap_zone = 'w';
|
||||
// mouse in bottom-left corner of screen
|
||||
else if(window.mouseX < 20 && window.mouseY > window.desktop_height - 150)
|
||||
window.current_active_snap_zone = 'sw';
|
||||
// mouse in right edge of screen
|
||||
else if(window.mouseX > window.desktop_width - 20 && window.mouseY >= 150 && window.mouseY < window.desktop_height - 150)
|
||||
window.current_active_snap_zone = 'e';
|
||||
// mouse in top-right corner of screen
|
||||
else if((window.mouseX > window.desktop_width - 150 && window.mouseY < window.toolbar_height + 20) || (window.mouseX > window.desktop_width - 20 && window.mouseY < 150))
|
||||
window.current_active_snap_zone = 'ne';
|
||||
// mouse in bottom-right corner of screen
|
||||
else if(window.mouseX > window.desktop_width - 20 && window.mouseY >= window.desktop_height - 150)
|
||||
window.current_active_snap_zone = 'se';
|
||||
// mouse in top edge of screen
|
||||
else if(window.mouseY < window.toolbar_height + 20 && window.mouseX >= 150 && window.mouseX < window.desktop_width - 150)
|
||||
window.current_active_snap_zone = 'n';
|
||||
// not in any snap zone
|
||||
else
|
||||
window.current_active_snap_zone = undefined;
|
||||
|
||||
// mouseover_window
|
||||
var windows = document.getElementsByClassName("window");
|
||||
let active_win;
|
||||
if(windows.length > 0){
|
||||
let highest_window_zindex = 0;
|
||||
for(let i=0; i<windows.length; i++){
|
||||
const rect = windows[i].getBoundingClientRect();
|
||||
if( window.mouseX > rect.x && window.mouseX < (rect.x + rect.width) && window.mouseY > rect.y && window.mouseY < (rect.y + rect.height)){
|
||||
if(parseInt($(windows[i]).css('z-index')) >= highest_window_zindex){
|
||||
active_win = windows[i];
|
||||
highest_window_zindex = parseInt($(windows[i]).css('z-index'));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
window.mouseover_window = active_win;
|
||||
|
||||
// mouseover_item_container
|
||||
var item_containers = document.getElementsByClassName("item-container");
|
||||
let active_ic;
|
||||
if(item_containers.length > 0){
|
||||
let highest_window_zindex = 0;
|
||||
for(let i=0; i<item_containers.length; i++){
|
||||
const rect = item_containers[i].getBoundingClientRect();
|
||||
if( window.mouseX > rect.x && window.mouseX < (rect.x + rect.width) && window.mouseY > rect.y && window.mouseY < (rect.y + rect.height)){
|
||||
let active_container_zindex = parseInt($(item_containers[i]).closest('.window').css('z-index'));
|
||||
if( !isNaN(active_container_zindex) && active_container_zindex >= highest_window_zindex){
|
||||
active_ic = item_containers[i];
|
||||
highest_window_zindex = active_container_zindex;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
window.mouseover_item_container = active_ic;
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user