mirror of
https://github.com/lrsjng/h5ai.git
synced 2025-08-08 14:56:35 +02:00
Add contextmenu.
This commit is contained in:
@@ -1,31 +0,0 @@
|
||||
|
||||
#view .context-menu {
|
||||
|
||||
display: block;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
background-color: @col-widget-back;
|
||||
border: @border-widget;
|
||||
color: #999;
|
||||
z-index: 10;
|
||||
|
||||
ul {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
text-align: left;
|
||||
|
||||
li {
|
||||
padding: 8px 12px 10px 12px;
|
||||
white-space: nowrap;
|
||||
border-top: @border-widget-sep;
|
||||
.transition(all 0.2s ease-in-out);
|
||||
|
||||
&:hover {
|
||||
color: @col-hover;
|
||||
background-color: @col-widget-back-hover;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
76
src/_h5ai/client/css/inc/contextmenu.less
Normal file
76
src/_h5ai/client/css/inc/contextmenu.less
Normal file
@@ -0,0 +1,76 @@
|
||||
|
||||
.cm-overlay {
|
||||
display: none;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
overflow: hidden;
|
||||
z-index: 200;
|
||||
// background: rgba(0,0,0,0.1);
|
||||
// background: rgba(255,255,255,0.6);
|
||||
}
|
||||
|
||||
|
||||
.cm-panel {
|
||||
display: block;
|
||||
position: absolute;
|
||||
left: 100px;
|
||||
top: 100px;
|
||||
background: #fff;
|
||||
color: @col;
|
||||
z-index: 10;
|
||||
box-shadow: 0 0 20px 0 rgba(0,0,0,0.2);
|
||||
overflow: auto;
|
||||
min-width: 200px;
|
||||
|
||||
ul {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
text-align: left;
|
||||
|
||||
.cm-label {
|
||||
padding: 8px 16px;
|
||||
white-space: nowrap;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.cm-entry {
|
||||
padding: 8px 16px;
|
||||
white-space: nowrap;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
color: @col-hover;
|
||||
background: rgba(0,0,0,0.05);
|
||||
}
|
||||
|
||||
.cm-icon {
|
||||
position: relative;
|
||||
top: -2px;
|
||||
|
||||
img {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
&.no-icon {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.cm-text {
|
||||
margin: 0 0 0 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.cm-sep {
|
||||
height: 1px;
|
||||
margin: 8px 0;
|
||||
padding: 0;
|
||||
border-top: 1px solid rgba(0,0,0,0.08);
|
||||
}
|
||||
}
|
||||
}
|
@@ -22,7 +22,7 @@
|
||||
@import "inc/view-details";
|
||||
@import "inc/view-icons";
|
||||
@import "inc/view-grid";
|
||||
// @import "inc/context-menu";
|
||||
@import "inc/contextmenu";
|
||||
@import "inc/fallback";
|
||||
|
||||
@import "inc/responsive";
|
||||
|
173
src/_h5ai/client/js/inc/ext/contextmenu.js
Normal file
173
src/_h5ai/client/js/inc/ext/contextmenu.js
Normal file
@@ -0,0 +1,173 @@
|
||||
modulejs.define('ext/contextmenu', ['$', '_', 'core/resource'], function ($, _, resource) {
|
||||
|
||||
|
||||
var templateOverlay = '<div class="cm-overlay"/>';
|
||||
var templatePanel = '<div class="cm-panel"><ul/></div>';
|
||||
var templateSep = '<li class="cm-sep"/>';
|
||||
var templateEntry = '<li class="cm-entry"><span class="cm-icon"><img/></span><span class="cm-text"/></li>';
|
||||
var templateLabel = '<li class="cm-label"><span class="cm-text"/></li>';
|
||||
|
||||
|
||||
function createOverlay(callback) {
|
||||
|
||||
var $overlay = $(templateOverlay);
|
||||
|
||||
$overlay
|
||||
.on('click contextmenu', function (ev) {
|
||||
|
||||
ev.stopPropagation();
|
||||
ev.preventDefault();
|
||||
|
||||
var cmId = $(ev.target).closest('.cm-entry').data('cm-id');
|
||||
|
||||
if (ev.target === $overlay[0] || cmId !== undefined) {
|
||||
$overlay.remove();
|
||||
callback(cmId);
|
||||
}
|
||||
});
|
||||
|
||||
return $overlay;
|
||||
}
|
||||
|
||||
function createPanel(menu) {
|
||||
|
||||
var $panel = $(templatePanel);
|
||||
var $ul = $panel.find('ul');
|
||||
var $li;
|
||||
|
||||
_.each(menu, function (entry) {
|
||||
|
||||
if (entry.type === '-') {
|
||||
$(templateSep).appendTo($ul);
|
||||
}
|
||||
|
||||
else if (entry.type === 'l') {
|
||||
$(templateLabel)
|
||||
.find('.cm-text').text(entry.text).end()
|
||||
.appendTo($ul);
|
||||
}
|
||||
|
||||
else if (entry.type === 'e') {
|
||||
$li = $(templateEntry)
|
||||
.data('cm-id', entry.id)
|
||||
.find('.cm-text').text(entry.text).end()
|
||||
.appendTo($ul);
|
||||
|
||||
if (entry.icon) {
|
||||
$li.find('.cm-icon img').attr('src', resource.icon(entry.icon));
|
||||
} else {
|
||||
$li.find('.cm-icon').addClass('no-icon');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return $panel;
|
||||
}
|
||||
|
||||
function positionPanel($overlay, $panel, x, y) {
|
||||
|
||||
var margin = 4;
|
||||
|
||||
$panel.css({
|
||||
left: 0,
|
||||
top: 0,
|
||||
opacity: 0
|
||||
});
|
||||
$overlay.show();
|
||||
|
||||
var overlayOffset = $overlay.offset();
|
||||
var overlayLeft = overlayOffset.left;
|
||||
var overlayTop = overlayOffset.top;
|
||||
var overlayWidth = $overlay.outerWidth(true);
|
||||
var overlayHeight = $overlay.outerHeight(true);
|
||||
|
||||
var panelOffset = $panel.offset();
|
||||
var panelLeft = panelOffset.left;
|
||||
var panelTop = panelOffset.top;
|
||||
var panelWidth = $panel.outerWidth(true);
|
||||
var panelHeight = $panel.outerHeight(true);
|
||||
|
||||
var posLeft = x;
|
||||
var posTop = y;
|
||||
|
||||
if (panelWidth > overlayWidth - 2 * margin) {
|
||||
posLeft = margin;
|
||||
panelWidth = overlayWidth - 2 * margin;
|
||||
}
|
||||
|
||||
if (panelHeight > overlayHeight - 2 * margin) {
|
||||
posTop = margin;
|
||||
panelHeight = overlayHeight - 2 * margin;
|
||||
}
|
||||
|
||||
if (posLeft < overlayLeft + margin) {
|
||||
posLeft = overlayLeft + margin;
|
||||
}
|
||||
|
||||
if (posLeft + panelWidth > overlayLeft + overlayWidth - margin) {
|
||||
posLeft = overlayLeft + overlayWidth - margin - panelWidth;
|
||||
}
|
||||
|
||||
if (posTop < overlayTop + margin) {
|
||||
posTop = overlayTop + margin;
|
||||
}
|
||||
|
||||
if (posTop + panelHeight > overlayTop + overlayHeight - margin) {
|
||||
posTop = overlayTop + overlayHeight - margin - panelHeight;
|
||||
}
|
||||
|
||||
$panel.css({
|
||||
left: posLeft,
|
||||
top: posTop,
|
||||
width: panelWidth,
|
||||
height: panelHeight,
|
||||
opacity: 1
|
||||
});
|
||||
}
|
||||
|
||||
function showMenuAt(x, y, menu, callback) {
|
||||
|
||||
var $overlay = createOverlay(callback);
|
||||
var $panel = createPanel(menu);
|
||||
$overlay.append($panel).appendTo('body');
|
||||
positionPanel($overlay, $panel, x, y);
|
||||
}
|
||||
|
||||
function init() {
|
||||
|
||||
$(document).on('contextmenu', function (ev) {
|
||||
|
||||
ev.stopPropagation();
|
||||
ev.preventDefault();
|
||||
$(ev.target).trigger($.Event('h5ai-contextmenu', {
|
||||
originalEvent: ev,
|
||||
showMenu: function (menu, callback) {
|
||||
|
||||
showMenuAt(ev.pageX, ev.pageY, menu, callback);
|
||||
}
|
||||
}));
|
||||
});
|
||||
|
||||
// var menu = [
|
||||
// {type: 'e', id: 'e1', text: 'testing context menus'},
|
||||
// {type: 'e', id: 'e2', text: 'another entry'},
|
||||
// {type: 'e', id: 'e3', text: 'one with icon', icon: 'folder'},
|
||||
// {type: '-'},
|
||||
// {type: 'e', id: 'e4', text: 'one with icon', icon: 'x'},
|
||||
// {type: 'e', id: 'e5', text: 'one with icon', icon: 'img'}
|
||||
// ];
|
||||
// var callback = function (res) {
|
||||
|
||||
// window.console.log('>> CB-RESULT >> ' + res);
|
||||
// };
|
||||
|
||||
// $(document).on('h5ai-contextmenu', '#items .item.folder', function (ev) {
|
||||
|
||||
// window.console.log('CM', ev);
|
||||
// ev.showMenu(menu, callback);
|
||||
// });
|
||||
}
|
||||
|
||||
|
||||
init();
|
||||
});
|
Reference in New Issue
Block a user