Commit 4959c598 authored by Marcel Rieger's avatar Marcel Rieger
Browse files

Add fast menus in the Dialog view.

parent ae1bc078
......@@ -111,6 +111,10 @@ var DummyDialogView = vispa.ExtensionView.Dialog.extend({
callback: function() {
alert("Test!");
}
}).addMenuEntry("test2", {
callback: function() {
alert("Foo bar!");
}
});
},
......
......@@ -105,3 +105,7 @@ nav > .navbar-nav > li.active > a > b.caret {
border-top-color: transparent !important;
border-bottom-color: transparent !important;
}
.vispa-zeroheight {
height: 0px !important;
}
......@@ -406,7 +406,7 @@
top: @menu-bar-height;
}
.vispa-fastmenu {
.vispa-fastmenu.vispa-fastmenu-centerview {
position: absolute;
top: 0px;
right: 0px;
......@@ -416,14 +416,26 @@
box-shadow: inset 0px -1px 0px #b8b8b8;
background-color: #fff;
overflow-y: visible;
overflow-x: visible;
overflow-x: hidden;
}
.vispa-fastmenu.vispa-fastmenu-dialogview {
width: 100%;
height: @menu-bar-height;
padding: 0px 8px;
box-shadow: inset 0px -1px 0px #e5e5e5;
overflow-y: visible;
overflow-x: hidden;
transition: height 100ms;
-webkit-transition: height 100ms;
}
.vispa-fastmenu.highlight {
background-color: rgba(red(@color-primary), green(@color-primary), blue(@color-primary), 0.5);
}
.vispa-fastmenu.accept {
background-color: rgba(red(@color-success), green(@color-success), blue(@color-success), 0.5);
}
.vispa-fastmenu-entry {
float: left;
height: 100%;
......
......@@ -4,6 +4,6 @@
<img data-bind="loader-img" />
</div>
</div>
<div class="vispa-fastmenu"></div>
<div class="vispa-fastmenu vispa-fastmenu-centerview"></div>
<div class="vispa-centerview-content"></div>
</div>
<div class="dropdown vispa-dialogview-dropdownmenu">
<i class="glyphicon glyphicon-cog" data-toggle="dropdown"></i>
<ul class="dropdown-menu" role="menu">
<li class="divider"></li>
<li>
<a href="#" id="close">
<i class="glyphicon glyphicon-remove"></i>
<span>Close</span>
</a>
</li>
</ul>
</div>
<div class="modal-header">
<button type="button" class="close" aria-hidden="true">
&times;
</button>
<h4 class="modal-title">
<div class="dropdown vispa-dialogview-dropdownmenu">
<i class="glyphicon glyphicon-cog" data-toggle="dropdown"></i>
<ul class="dropdown-menu" role="menu">
<li class="divider"></li>
<li>
<a href="#" id="close">
<i class="glyphicon glyphicon-remove"></i>
<span>Close</span>
</a>
</li>
</ul>
</div>
<i class="glyphicon" id="icon"></i>
<i class="glyphicon" id="icon"></i>
<span id="label"></span>
</h4>
</div>
<span id="label"></span>
<div class="modal-header" style="padding: 0px; border: 0px; min-height: 0px;">
<div class="vispa-fastmenu vispa-fastmenu-dialogview vispa-zeroheight"></div>
</div>
\ No newline at end of file
......@@ -282,6 +282,7 @@ extensionClasses.ExtensionView.Center = extensionClasses.ExtensionView.Base.exte
distance: 20,
helper: "clone",
cursor: "move",
cursorAt: { left: 0, top: 0 },
start: function(event, ui) {
self._toggleFastMenu(true);
var label = $("<span class='label label-default'>")
......@@ -387,8 +388,6 @@ extensionClasses.ExtensionView.Center = extensionClasses.ExtensionView.Base.exte
self.pushPreferences();
}
});
window.foobar = nodes.fastMenu;
});
// tab
......@@ -478,7 +477,7 @@ extensionClasses.ExtensionView.Center = extensionClasses.ExtensionView.Base.exte
_updateFastMenuEntries: function() {
var self = this;
// before looping over the entries, make sure the templates is loaded
// before looping over the entries, make sure the templates are loaded
var paths = ["fastmenu/entry.html", "fastmenu/basicmenu.html", "fastmenu/splitmenu.html", "fastmenu/group.html"];
var dfds = $.map(paths, function(path) {
return vispa.getTemplate("html/index/" + path);
......
......@@ -9,6 +9,15 @@ extensionClasses.ExtensionView.Dialog = extensionClasses.ExtensionView.Base.exte
this._icon = null;
},
applyPreferences: function() {
this._super();
// fastMenuEntries
this._updateFastMenuEntries();
return this;
},
setIcon: function(icon) {
this._nodes.icon.removeClass().empty();
......@@ -131,26 +140,6 @@ extensionClasses.ExtensionView.Dialog = extensionClasses.ExtensionView.Base.exte
if (!workspace)
return this;
var $header = $(Dialog.tmpl.header);
var $body = $(Dialog.tmpl.body);
var $footer = $(Dialog.tmpl.footer);
// use a dialog
this._dialog = Dialog.dialog({
context: workspace.getMessageContext(),
target: workspace.nodes.views.dialog.content,
header: $header,
body: $body,
footer: $footer,
wrapHeader: false,
wrapBody: false,
wrapFooter: false,
show: false,
beforeClose: function(callback) {
self._close(callback);
}
});
var dfds = [
vispa.getTemplate("html/index/dialogview/header.html"),
vispa.getTemplate("html/index/dialogview/body.html"),
......@@ -158,7 +147,26 @@ extensionClasses.ExtensionView.Dialog = extensionClasses.ExtensionView.Base.exte
vispa.getTemplate("html/index/submenu.html")
];
$.when.apply($, dfds).then(function(headerTmpl, bodyTmpl, menuEntryTmpl, subMenuTmpl) {
$(headerTmpl).appendTo($header.find("h4"));
var $header = $(headerTmpl);
var $body = $(Dialog.tmpl.body);
var $footer = $(Dialog.tmpl.footer);
// use a dialog
self._dialog = Dialog.dialog({
context: workspace.getMessageContext(),
target: workspace.nodes.views.dialog.content,
header: $header,
body: $body,
footer: $footer,
wrapHeader: false,
wrapBody: false,
wrapFooter: false,
show: false,
beforeClose: function(callback) {
self._close(callback);
}
});
$(bodyTmpl).appendTo($body)
.render({}, {
"loader-img": {
......@@ -176,7 +184,7 @@ extensionClasses.ExtensionView.Dialog = extensionClasses.ExtensionView.Base.exte
self._nodes.modal = $(".vispa-modal", $body).first();
self._nodes.footer = $footer;
self._nodes.menu = $(".vispa-dialogview-dropdownmenu > ul", $header);
// self._nodes.fastMenu = $("<div>").appendTo($header);
self._nodes.fastMenu = $(".vispa-fastmenu-dialogview", $header);
// menu entries
var _addEntry = function(entry, target) {
......@@ -198,24 +206,25 @@ extensionClasses.ExtensionView.Dialog = extensionClasses.ExtensionView.Base.exte
}
}
});
// if (entry.allowShortcut !== false)
// _entry.draggable({
// distance: 20,
// helper: "clone",
// cursor: "move",
// start: function(event, ui) {
// self._toggleFastMenu(true);
// var label = $("<span class='label label-default'>")
// .html(entry.label).css("font-size", 14);
// ui.helper.empty().append(label);
// },
// stop: function() {
// var fastEntries = self.getPreference("fastMenuEntries");
// self._toggleFastMenu();
// $(".vispa-centerview-tab-icon a", nodes.tab).first().dropdown("toggle");
// }
// }).addClass("draggable-fastmenu-" + self.getId())
// .data("entry", entry.id);
if (entry.allowShortcut !== false)
_entry.draggable({
distance: 20,
helper: "clone",
cursor: "move",
cursorAt: { left: 0, top: 0 },
start: function(event, ui) {
self._toggleFastMenu(true);
var label = $("<span class='label label-default'>")
.html(entry.label).css("font-size", 14);
ui.helper.empty().append(label);
},
stop: function() {
var fastEntries = self.getPreference("fastMenuEntries");
self._toggleFastMenu();
$(".vispa-dialogview-dropdownmenu > i", self._nodes.header).dropdown("toggle");
}
}).addClass("draggable-fastmenu-" + self.getId())
.data("entry", entry.id);
if (isSub) {
var target = $("ul.dropdown-menu", _entry).first();
$.each(entry.children.concat().reverse(), function(i, entry) {
......@@ -231,13 +240,296 @@ extensionClasses.ExtensionView.Dialog = extensionClasses.ExtensionView.Base.exte
event.preventDefault();
});
// the fast menu becomes droppable and sortable
var deletable = function(event) {
// height(header + tabs) = 90
var offset = 90;
return event.clientY > 2.5 * offset;
}
self._nodes.fastMenu.droppable({
accept: function(node) {
if (!node.hasClass("draggable-fastmenu-" + self.getId()))
return false;
var entries = self.getPreference("fastMenuEntries");
return !~entries.indexOf(node.data("entry"));
},
activeClass: "highlight",
hoverClass: "accept",
drop: function(event, ui) {
self._addFastMenuEntry(ui.draggable.data("entry"));
}
}).sortable({
axis: "x",
distance: 20,
cursor: "move",
forcePlaceholderSize: true,
sort: function(event, ui) {
ui.item
.toggleClass("deletable", deletable(event))
.toggleClass("keepable", !deletable(event));
},
stop: function(event, ui) {
if (deletable(event)) {
self._removeFastMenuEntry(ui.item.data("entryId"));
return;
}
ui.item
.toggleClass("deletable", false)
.toggleClass("keepable", false);
// get the new order and snyc it with the config
// if there is more than one child
var children = self._nodes.fastMenu.children();
if (children.length < 2)
return;
var ids = self._preferences.fastMenuEntries;
ids.length = 0;
children.each(function(i, child) {
ids.push($(child).data("entryId"));
});
self.pushPreferences();
}
});
// finally, setup, show and render
self.setup();
self.show();
self.render(self._nodes.content, $footer);
self.applyPreferences();
});
return this;
},
_updateFastMenuEntries: function() {
var self = this;
// before looping over the entries, make sure the templates are loaded
var paths = ["fastmenu/entry.html", "fastmenu/basicmenu.html", "fastmenu/splitmenu.html", "fastmenu/group.html"];
var dfds = $.map(paths, function(path) {
return vispa.getTemplate("html/index/" + path);
});
$.when.apply($, dfds).then(function() {
self.__removeFastMenuEntries();
self.__addFastMenuEntries();
});
return this;
},
_toggleFastMenu: function(visible) {
var nChildren = this._nodes.fastMenu.children().length;
visible = visible == undefined ? !!nChildren : visible;
this._nodes.fastMenu.toggleClass("vispa-zeroheight", !visible);
return this;
},
__addFastMenuEntries: function() {
// only DOM manipulation
var self = this;
var fastEntries = this.getPreference("fastMenuEntries");
$.each(fastEntries, function(i, id) {
self.__addFastMenuEntry(id);
});
this._toggleFastMenu();
return this;
},
_addFastMenuEntry: function(id) {
var fastEntries = this.getPreference("fastMenuEntries");
if (~fastEntries.indexOf(id))
return this;
fastEntries.push(id);
this.pushPreferences();
return this;
},
__addFastMenuEntry: function(id) {
// only DOM manipulation
var self = this;
var entry = this.getMenuEntry(id);
if (!entry)
return this;
if (!$.isArray(entry.children))
vispa.getTemplate("html/index/fastmenu/entry.html", function(err, tmpl) {
$(tmpl).render(entry, {
icon: {
class: function() {
return entry.iconClass;
}
}
}).appendTo(self._nodes.fastMenu)
.data("entryId", id)
.find(".fastmenu-orig").first()
.attr("id", "fastmenu-" + id)
.addClass(entry.buttonClass)
.click(function(event) {
event.preventDefault();
entry.callback.call(self);
});
});
else {
var _addEntry = function(entry, target) {
var isSub = $.isArray(entry.children);
var tmpl = isSub ? self._tmpl.submenuTmpl : self._tmpl.menuEntryTmpl;
var _entry = $(tmpl).prependTo(target).render(entry, {
icon: {
class: function() {return entry.iconClass;},
},
link: {
action: function(data) {
// bind the click event
$(data.element).click(function(event) {
if (!$(this).parent().hasClass("disabled") && !isSub)
entry.callback.call(self);
else
event.stopPropagation();
event.preventDefault();
}).attr("id", "fastmenu-" + entry.id);
}
}
});
if (isSub) {
var target = $("ul.dropdown-menu", _entry).first();
$.each(entry.children, function(i, entry) {
_addEntry(entry, target);
});
}
};
if (entry.childrenStyle == "split") {
vispa.getTemplate("html/index/fastmenu/splitmenu.html", function(err, tmpl) {
var _entry = $(tmpl).render(entry, {
icon: {
class: function() {
return entry.iconClass;
}
}
}).appendTo(self._nodes.fastMenu)
.data("entryId", id);
$(".fastmenu-orig", _entry).first()
.attr("id", "fastmenu-" + id)
.addClass(entry.buttonClass)
.click(function(event) {
entry.callback.call(self);
event.preventDefault();
}).next()
.addClass(entry.buttonClass)
.click(function(event) {
event.preventDefault();
});
var target = $("ul.dropdown-menu", _entry);
$.each(entry.children, function(i, entry) {
_addEntry(entry, target);
});
});
} else if (entry.childrenStyle == "group") {
vispa.getTemplate("html/index/fastmenu/group.html", function(err, tmpl) {
var data = $.map(entry.children, function(entry) {
return {btn: entry};
});
var _entry = $(tmpl).appendTo(self._nodes.fastMenu)
.data("entryId", id);
$(".btn-group", _entry).first().render(entry.children, {
icon: {
class: function(data) {
return this.iconClass;
}
},
btn: {
action: function(data) {
var _self = this;
$(data.element).addClass(this.buttonClass)
.attr("id", "fastmenu-" + this.id)
.click(function(event) {
event.preventDefault();
_self.callback.call(self);
});
}
}
});
});
} else {
vispa.getTemplate("html/index/fastmenu/basicmenu.html", function(err, tmpl) {
var _entry = $(tmpl).render(entry, {
icon: {
class: function() {
return entry.iconClass;
}
}
}).appendTo(self._nodes.fastMenu)
.data("entryId", id);
$(".fastmenu-orig", _entry).first()
.addClass(entry.buttonClass)
.click(function(event) {
event.preventDefault();
});
var target = $("ul.dropdown-menu", _entry);
$.each(entry.children, function(i, entry) {
_addEntry(entry, target);
});
});
}
}
return this;
},
__removeFastMenuEntries: function() {
// only DOM manipulation
var self = this;
var fastEntries = this.getPreference("fastMenuEntries");
$.each(fastEntries, function(i, id) {
self.__removeFastMenuEntry(id);
});
return this;
},
_removeFastMenuEntry: function(id) {
var fastEntries = this.getPreference("fastMenuEntries");
var idx = fastEntries.indexOf(id);
if (!~idx)
return this;
this.__removeFastMenuEntry(id);
fastEntries.splice(idx, 1);
this.pushPreferences();
return this;
},
__removeFastMenuEntry: function(id) {
var node = this._getFastMenuEntryNode(id);
if (node)
node.remove();
return this;
},
_getFastMenuEntryNode: function(id) {
var children = this._nodes.fastMenu.children();
var node = null;
children.each(function(i, child) {
if (node == null && $(child).data("entryId") == id)
node = $(child);
});
return node;
}
});
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment