mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-07-30 22:32:07 +00:00
Add right-click menu to reorder or unpin favs
Right-clicking a fav tile now opens a small context menu with Move left, Move right, and Unpin, instead of relying on drag-only reorder. - speeddial.js: oncontextmenu handler, the menu build/position/dismiss logic, and an Escape-key close. - style.css: .ctx-menu/.ctx-item styling. - ActionRegistry: reorder_favourites persists the new bar order to AppConfig. - SpeedDialDialog: routes the new reorder_favourites command from the page.
This commit is contained in:
@@ -273,10 +273,65 @@ function renderFav() {
|
||||
tile.title = a.title;
|
||||
tile.setAttribute("aria-label", actionLabel(a, ACTIONS));
|
||||
tile.onclick = function () { sel = { zone: "fav", i: i }; run(a); };
|
||||
tile.oncontextmenu = function (ev) {
|
||||
ev.preventDefault();
|
||||
// why: selecting shows the eyebrow, which grows the launcher - resize so the popup
|
||||
// isn't clipped (mirrors arrow-nav). requestResize no-ops when height is unchanged.
|
||||
sel = { zone: "fav", i: i }; render({ resize: true });
|
||||
showFavMenu(ev.clientX, ev.clientY, id);
|
||||
};
|
||||
favEl.appendChild(tile);
|
||||
});
|
||||
}
|
||||
|
||||
// ---- favourite context menu (right-click a tile) -----------------------------
|
||||
var favMenuEl = null;
|
||||
|
||||
function hideFavMenu() { if (favMenuEl) favMenuEl.hidden = true; }
|
||||
|
||||
function addFavMenuItem(label, enabled, fn) {
|
||||
var item = document.createElement("button");
|
||||
item.className = "ctx-item";
|
||||
item.textContent = label;
|
||||
item.disabled = !enabled;
|
||||
item.onclick = function () { hideFavMenu(); fn(); };
|
||||
favMenuEl.appendChild(item);
|
||||
}
|
||||
|
||||
// One reused menu node (Move left/right + Unpin), positioned at the cursor and clamped
|
||||
// to the viewport. Native browser context menus can't add items, so we roll our own tiny one.
|
||||
function showFavMenu(x, y, id) {
|
||||
if (!favMenuEl) {
|
||||
favMenuEl = document.createElement("div");
|
||||
favMenuEl.className = "ctx-menu";
|
||||
document.body.appendChild(favMenuEl);
|
||||
}
|
||||
favMenuEl.innerHTML = "";
|
||||
var favs = currentVisibleFavs();
|
||||
var vi = favs.indexOf(id);
|
||||
addFavMenuItem("Move left", vi > 0, function () { moveFav(id, -1); });
|
||||
addFavMenuItem("Move right", vi >= 0 && vi < favs.length - 1, function () { moveFav(id, 1); });
|
||||
addFavMenuItem("Unpin", true, function () { toggleFav(id); });
|
||||
favMenuEl.hidden = false;
|
||||
favMenuEl.style.left = Math.max(0, Math.min(x, window.innerWidth - favMenuEl.offsetWidth - 4)) + "px";
|
||||
favMenuEl.style.top = Math.max(0, Math.min(y, window.innerHeight - favMenuEl.offsetHeight - 4)) + "px";
|
||||
}
|
||||
|
||||
// Swap a favourite with its visible neighbour (dir -1/+1) and persist the new order. Swapping
|
||||
// by id inside FAVS (not the visible slice) keeps any hidden pins (no live action) in place.
|
||||
function moveFav(id, dir) {
|
||||
var favs = currentVisibleFavs();
|
||||
var vi = favs.indexOf(id);
|
||||
var ni = vi + dir;
|
||||
if (vi === -1 || ni < 0 || ni >= favs.length) return;
|
||||
var a = FAVS.indexOf(id), b = FAVS.indexOf(favs[ni]);
|
||||
if (a === -1 || b === -1) return;
|
||||
FAVS[a] = favs[ni]; FAVS[b] = id;
|
||||
SendMessage({ command: "reorder_favourites", ids: FAVS.slice() });
|
||||
sel = { zone: "fav", i: ni };
|
||||
render({ resize: true });
|
||||
}
|
||||
|
||||
// Name of the selected favourite, shown above the bar; hidden unless a fav is selected.
|
||||
function updateFavEyebrow(favs) {
|
||||
if (!eyeEl) return;
|
||||
@@ -432,7 +487,12 @@ function OnInit() {
|
||||
query = qEl.value; sel = { zone: "list", i: 0 }; syncClearButton(); render({ resize: true, resetScroll: true });
|
||||
});
|
||||
|
||||
// why: dismiss the fav context menu on any click/scroll away from it (capture scroll to catch nested scrollers).
|
||||
document.addEventListener("click", hideFavMenu);
|
||||
document.addEventListener("scroll", hideFavMenu, true);
|
||||
|
||||
document.addEventListener("keydown", function (e) {
|
||||
if (favMenuEl && !favMenuEl.hidden && e.key === "Escape") { e.preventDefault(); hideFavMenu(); return; }
|
||||
var arr = filterActions(ACTIONS, query);
|
||||
var favs = currentVisibleFavs();
|
||||
// why: Up/Down always navigate; Left/Right only navigate the fav bar. In the list zone,
|
||||
|
||||
@@ -55,6 +55,32 @@ body {
|
||||
border: 1px solid var(--speed-tile-border, #d8d8d8);
|
||||
}
|
||||
.fav-tile.sel { outline: 2px solid var(--main-color, var(--orca-accent, #009688)); outline-offset: 2px; }
|
||||
.ctx-menu {
|
||||
position: fixed;
|
||||
z-index: 10;
|
||||
min-width: 120px;
|
||||
padding: 4px;
|
||||
background: var(--panel, var(--orca-bg, #fff));
|
||||
border: 1px solid var(--border, var(--orca-border, #ddd));
|
||||
border-radius: 7px;
|
||||
box-shadow: 0 4px 16px rgba(0,0,0,.18);
|
||||
}
|
||||
.ctx-menu[hidden] { display: none; }
|
||||
.ctx-item {
|
||||
display: block;
|
||||
width: 100%;
|
||||
padding: 6px 10px;
|
||||
border: 0;
|
||||
border-radius: 5px;
|
||||
background: transparent;
|
||||
color: var(--text, var(--orca-fg, #1b1c1e));
|
||||
font: inherit;
|
||||
text-align: left;
|
||||
cursor: pointer;
|
||||
}
|
||||
.ctx-item:hover { background: var(--row-hover, rgba(127,127,127,.16)); }
|
||||
.ctx-item:disabled { opacity: .4; cursor: default; }
|
||||
.ctx-item:disabled:hover { background: transparent; }
|
||||
.dial-head { flex: 0 0 auto; padding: 8px; }
|
||||
.plugin-search {
|
||||
display: flex;
|
||||
|
||||
Reference in New Issue
Block a user