12/08/2018, 15:07

Context Menus Trong Gojs

Giới Thiệu Đã bao giờ bạn thực hiện các sự kiện click mouse, right click mouse hay hover mouse trên các của chính mình chưa? Đã là 1 dev thì k ai k biết tới các event đó. Sau đây mình xin giới thiệu tới các bạn 1 trong các event đó là right click Hay còn được gọi là context menus. Ở đây mình ...

Giới Thiệu

Đã bao giờ bạn thực hiện các sự kiện click mouse, right click mouse hay hover mouse trên các của chính mình chưa?

Đã là 1 dev thì k ai k biết tới các event đó. Sau đây mình xin giới thiệu tới các bạn 1 trong các event đó là right click Hay còn được gọi là context menus. Ở đây mình sẽ thực hiện trong seri tìm hiểu gojs của mình.

Mở đầu:

Như những phần trước mình đã giới thiệu. Gojs là 1 framework mạnh hỗ trợ thiết kế giao diện người dùng được tích hợp nhiều chức năng hay và phổ biến 1 trong số đó là context menus. Vơi context menus của gojs mỗi lần bạn right click vào phần giao diện gojs sẽ show ra 1 menus nhỏ cho phép bạn thực hiện các thao tác trên đó ví dụ như gọi 1 function thực hiện delete 1 node trong đó chẳng hạn hoặc như các thao tác trên windown như là copy, paste, cut, v..v..

Sau đây mình sẽ thực hiện 1 đoạn code để gọi ra context menu trong giao diện gojs

  function changeColor(e, obj) {
    diagram.startTransaction("changed color");
    // get the context menu that holds the button that was clicked
    var contextmenu = obj.part;
    // get the node data to which the Node is data bound
    var nodedata = contextmenu.data;
    // compute the next color for the node
    var newcolor = "lightblue";
    switch (nodedata.color) {
      case "lightblue": newcolor = "lightgreen"; break;
      case "lightgreen": newcolor = "lightyellow"; break;
      case "lightyellow": newcolor = "orange"; break;
      case "orange": newcolor = "lightblue"; break;
    }
    // modify the node data
    // this evaluates data Bindings and records changes in the UndoManager
    diagram.model.setDataProperty(nodedata, "color", newcolor);
    diagram.commitTransaction("changed color");
  }
  
    // this is a normal Node template that also has a contextMenu defined for it
  diagram.nodeTemplate =
    $(go.Node, "Auto",
      $(go.Shape, "RoundedRectangle",
        { fill: "white" },
        new go.Binding("fill", "color")),
      $(go.TextBlock, { margin: 5 },
        new go.Binding("text", "key")),
      {
        contextMenu:     // define a context menu for each node
          $(go.Adornment, "Vertical",  // that has one button
            $("ContextMenuButton",
              $(go.TextBlock, "Change Color"),
              { click: changeColor })
            // more ContextMenuButtons would go here
          )  // end Adornment
      }
    );

  // also define a context menu for the diagram's background
  diagram.contextMenu =
    $(go.Adornment, "Vertical",
      $("ContextMenuButton",
        $(go.TextBlock, "Undo"),
        { click: function(e, obj) { e.diagram.commandHandler.undo(); } },
        new go.Binding("visible", "", function(o) {
                                          return o.diagram.commandHandler.canUndo();
                                        }).ofObject()),
      $("ContextMenuButton",
        $(go.TextBlock, "Redo"),
        { click: function(e, obj) { e.diagram.commandHandler.redo(); } },
        new go.Binding("visible", "", function(o) {
                                          return o.diagram.commandHandler.canRedo();
                                        }).ofObject()),
      // no binding, always visible button:
      $("ContextMenuButton",
        $(go.TextBlock, "New Node"),
        { click: function(e, obj) {
          var diagram = e.diagram;
          diagram.startTransaction('new node');
          var data = {};
          diagram.model.addNodeData(data);
          part = diagram.findPartForData(data);
          part.location = diagram.toolManager.contextMenuTool.mouseDownPoint;
          diagram.commitTransaction('new node');
        } })
    );

  diagram.initialContentAlignment = go.Spot.Center;

  var nodeDataArray = [
    { key: "Alpha", color: "lightyellow" },
    { key: "Beta", color: "orange" }
  ];
  var linkDataArray = [
    { from: "Alpha", to: "Beta" }
  ];
  diagram.model = new go.GraphLinksModel(nodeDataArray, linkDataArray);
  diagram.undoManager.isEnabled = true;

Kết quả

Mình xin phép giải thích 1 chút về đoạn code trên

      {
        contextMenu:     // define a context menu for each node
          $(go.Adornment, "Vertical",  // that has one button
            $("ContextMenuButton",
              $(go.TextBlock, "Change Color"),
              { click: changeColor })
            // more ContextMenuButtons would go here
          )  // end Adornment
      }

như chú thích ở bên. việc gọi contextMenu sẽ gọi ra function mặc định của gojs có sẵn trong thực viện gojs nhằm định nghĩa 1 context menu mặc định tiếp theo:

            $("ContextMenuButton",
              $(go.TextBlock, "Change Color"),
              { click: changeColor })

sẽ tạo ra 1 button khi right click. button này click sẽ gọi tới function changeColor đã được định nghĩa ở trên

        $(go.TextBlock, "Undo"),
        { click: function(e, obj) { e.diagram.commandHandler.undo(); } },
        new go.Binding("visible", "", function(o) {
                                          return o.diagram.commandHandler.canUndo();
                                        }).ofObject()),
      $("ContextMenuButton",
        $(go.TextBlock, "Redo"),
        { click: function(e, obj) { e.diagram.commandHandler.redo(); } },
        new go.Binding("visible", "", function(o) {
                                          return o.diagram.commandHandler.canRedo();
                                        }).ofObject()),

phần này sẽ định nghĩa 2 function cho phép bạn undo và redo sau khi đã thực hiện các function khi right click

      $("ContextMenuButton",
        $(go.TextBlock, "New Node"),
        { click: function(e, obj) {
          var diagram = e.diagram;
          diagram.startTransaction('new node');
          var data = {};
          diagram.model.addNodeData(data);
          part = diagram.findPartForData(data);
          part.location = diagram.toolManager.contextMenuTool.mouseDownPoint;
          diagram.commitTransaction('new node');
        } })

function này chịu trách nhiệm khi bạn right click sẽ show ra button "New Node" Có tác vụ thêm 1 node mới vào giao diện gojs

Vậy câu hỏi đặt ra ở đây là khi right click thì menu context sẽ show ra cả 2 button changeColor và New Node luôn hay sao? Thật ra k phải như vậy. Change Color được định nghĩa ở trong 1 node. nên chỉ khi right click vào 1 node thì mới xuất hện context menus change color này thôi Còn New Node lại được định nghĩa trong 1 diagram. Vì thế khi right click vào diagram gojs thì nó sẽ xuất hiện và thực hiện new node mới

Custom context menus

Tuy nhiên với những người có gu thẩm mỹ cao thì với 1 context menus như thế này sẽ khá tệ vậy tai sao chúng ta không thực hiện thêm 1 vài động tác nhỏ để context menus của chúng ta lung linh hơn 1 tí nhỉ? It ra cũng gần ngang ngửa windown chứ             </div>
            
            <div class=

0