Explorar o código

[core] Add ko context-menu binding

It shows a custom context menu when the right button is click on the bound element.
Johan Ahlen %!s(int64=9) %!d(string=hai) anos
pai
achega
2bddb30

+ 90 - 0
desktop/core/src/desktop/static/desktop/css/hue3.css

@@ -2273,3 +2273,93 @@ body {
   box-shadow: none;
   border-bottom: 1px solid #DDD;
 }
+
+.hue-context-menu {
+  display: none;
+  position: fixed;
+  margin: 2px 4px 6px 4px;
+  z-index: 10000;
+  padding: 6px 1px;
+  list-style: none;
+  font-size: 13px;
+  opacity: 0;
+
+  border-radius: 2px;
+  background-color: #FFF;
+  -webkit-box-shadow: 0 2px 8px rgba(0,0,0,.18);
+  box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.18), 0 2px 8px 0 rgba(0, 0, 0, 0.13);
+  transition: opacity .3s;
+}
+
+.hue-contex-menu > li {
+  min-width: 170px;
+  color: #e5e5e5;
+}
+
+.hue-context-menu > li > a {
+  display: block;
+  position: relative;
+  clear: both;
+  height: 22px;
+  line-height: 22px;
+  vertical-align: middle;
+  padding: 6px 16px 6px 38px;
+
+  color: #333;
+  text-decoration: none;
+  font-weight: 400;
+  white-space: nowrap;
+  transition: background-color .3s;
+}
+
+.hue-context-menu > li > .disabled {
+  display: block;
+  position: relative;
+  clear: both;
+  height: 22px;
+  line-height: 22px;
+  vertical-align: middle;
+  padding: 6px 16px 6px 38px;
+
+  color: #CCC;
+  text-decoration: none;
+  font-weight: 400;
+  white-space: nowrap;
+}
+
+.hue-context-menu > li > a:hover {
+  background-color: #DBE8F1;
+}
+
+.hue-context-menu > li > .disabled > i {
+  position: absolute;
+  height: 22px;
+  left: 13px;
+  right: auto;
+  top: 6px;
+
+  color: #CCC;
+  font-size: 17px;
+  line-height: 22px;
+  vertical-align: middle;
+}
+
+.hue-context-menu > li > a > i {
+  position: absolute;
+  top: 6px;
+  left: 13px;
+  right: auto;
+  line-height: 22px;
+  height: 24px;
+
+  color: #555;
+  font-size: 17px;
+  vertical-align: middle;
+}
+
+.hue-context-menu > .divider {
+  height: 1px;
+  margin: 9px 0;
+  overflow: hidden;
+  background-color: #e5e5e5;
+}

+ 73 - 0
desktop/core/src/desktop/static/desktop/js/ko.hue-bindings.js

@@ -152,6 +152,79 @@
     }
   };
 
+  /**
+   * This binding can be used to show a custom context menu on right-click,
+   * It assumes that the context menu is nested within the bound element and
+   * the selector for the menu has to be supplied as a parameter.
+   *
+   * Example:
+   *
+   * <div data-bind="contextMenu: '.hue-context-menu'>
+   *   <ul class="hue-context-menu">...</ul>
+   * </div>
+   * 
+   */
+  ko.bindingHandlers.contextMenu = {
+    init: function (element, valueAccessor) {
+      var $element = $(element);
+      var $menu = $element.find(valueAccessor());
+      var active = false;
+
+      element.addEventListener("contextmenu", function(e) {
+        if(document.selection && document.selection.empty) {
+          document.selection.empty();
+        } else if(window.getSelection) {
+          var sel = window.getSelection();
+          sel.removeAllRanges();
+        }
+        $menu.css('top', 0);
+        $menu.css('left', 0);
+        $menu.css('opacity', 0);
+        $menu.show();
+        var menuWidth = $menu.outerWidth(true)
+        if (event.clientX + menuWidth > $(window).width()) {
+          $menu.css('left', event.clientX - menuWidth);
+        } else {
+          $menu.css('left', event.clientX);
+        }
+
+        var menuHeight = $menu.outerHeight(true);
+        if (event.clientY + menuHeight > $(window).height()) {
+          $menu.css('top', $(window).height() - menuHeight);
+        } else {
+          $menu.css('top', event.clientY);
+        }
+        $menu.css('opacity', 1);
+        active = true;
+        huePubSub.publish('contextmenu-active', element);
+        e.preventDefault();
+        e.stopPropagation();
+      });
+
+      var hideMenu = function () {
+        if (active) {
+          $menu.css('opacity', 0);
+          window.setTimeout(function () {
+            $menu.hide();
+          }, 300);
+          active = false;
+        }
+      }
+
+      huePubSub.subscribe('contextmenu-active', function (origin) {
+        if (origin !== element) {
+          hideMenu();
+        }
+      })
+      document.addEventListener("contextmenu", function (event) {
+        hideMenu();
+      })
+      $menu.click(hideMenu)
+      $element.click(hideMenu);
+      $(document).click(hideMenu);
+    }
+  };
+
   ko.bindingHandlers.multiClick = {
     init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
       var clickHandlerFunction = valueAccessor().click;