Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Add a model for checkboxes (using node.attr.is_selected field).

  • Loading branch information...
commit 6ebd40615dedfc2ba643b71d31fc8dd1ad2484cb 1 parent 99fa699
Michael Uvarov authored December 20, 2012
24  priv/css_src/relatio.css
@@ -180,22 +180,29 @@ a {
180 180
   margin-left: 14pt;
181 181
 }
182 182
 
  183
+.cb-block ul {
  184
+    /* Cancel margin for a content block with a header checkbox. */
  185
+    margin-left: 0px;
  186
+}
  187
+
  188
+.cb-block {
  189
+    /* Specify margin for a whole block with a header checkbox. */
  190
+    margin-left: 20px;
  191
+}
  192
+
183 193
 
184 194
 /* http://stackoverflow.com/questions/8573574/cancelling-text-align-justify-for-certain-parts-of-text */
185 195
 .active-block .header-closed {
186 196
   display: none;
187 197
 }
188  
-.header-closed {
  198
+.active-block .header-opened, 
  199
+.header-closed, 
  200
+.header-group {
189 201
   /* cancel justify */
190 202
   text-justify: none;
191 203
   display: inline-block;
192 204
 }
193 205
 
194  
-.active-block .header-opened {
195  
-  /* cancel justify */
196  
-  text-justify: none;
197  
-  display: inline-block;
198  
-}
199 206
 .header-opened {
200 207
   display: none;
201 208
 }
@@ -422,7 +429,6 @@ body.world li {
422 429
 .checkbox:before {
423 430
     font-size: 16pt;
424 431
     position: relative;
425  
-    left: -6pt;
426 432
     content: "\2610"; // ☐
427 433
 }
428 434
 .checkbox.selected:before {
@@ -433,6 +439,10 @@ body.world li {
433 439
     color: white;
434 440
 }
435 441
 
  442
+.hovered-group-cb .checkbox {
  443
+    color: white;
  444
+}
  445
+
436 446
 body.shift-pressed .checkbox.will-be-selected {
437 447
     color: white;
438 448
 }
51  priv/html/index.html
@@ -88,30 +88,39 @@
88 88
             Application <span class="application-name">ApplicationName</span>
89 89
         </div>
90 90
 
91  
-        <div id="modules" class="sub-block active-block">
  91
+        <div id="modules" class="sub-block active-block cb-block">
92 92
             <div class="sub-block-header">
  93
+              <span class="header-group">
  94
+                <span class="checkbox group-checkbox"></span>
93 95
                 <a tabindex="0" class="header-closed">Modules&hellip;</a>
94 96
                 <a tabindex="0" class="header-opened">Modules:</a>
95  
-                <span class="module-count header-count-info"
96  
-                    title="Total module count">
97  
-                </span>
  97
+              </span>
  98
+              <span class="module-count header-count-info"
  99
+                  title="Total module count">
  100
+              </span>
98 101
             </div>
99 102
             <div id="module-list" class="content-block"></div>
100 103
         </div>
101 104
 
102  
-        <div id="directions-out" class="sub-block active-block">
  105
+        <div id="directions-out" class="sub-block active-block cb-block">
103 106
             <div class="sub-block-header">
  107
+              <span class="header-group">
  108
+                <span class="checkbox group-checkbox"></span>
104 109
                 <a tabindex="0" class="header-closed">Calls to&hellip;</a>
105 110
                 <a tabindex="0" class="header-opened">Calls to:</a>
106  
-                <span class="direction-out-count header-count-info"></span>
  111
+              </span>
  112
+              <span class="direction-out-count header-count-info"></span>
107 113
             </div>
108 114
             <div id="directions-list-out" class="content-block"></div>
109 115
         </div>
110 116
 
111  
-        <div id="directions-in" class="sub-block active-block">
  117
+        <div id="directions-in" class="sub-block active-block cb-block">
112 118
             <div class="sub-block-header">
113  
-                <a tabindex="0" class="header-closed">Called from&hellip;</a>
114  
-                <a tabindex="0" class="header-opened">Called from:</a>
  119
+                <span class="header-group">
  120
+                  <span class="checkbox group-checkbox"></span>
  121
+                  <a tabindex="0" class="header-closed">Called from&hellip;</a>
  122
+                  <a tabindex="0" class="header-opened">Called from:</a>
  123
+                </span>
115 124
                 <span class="direction-in-count header-count-info"></span>
116 125
             </div>
117 126
             <div id="directions-list-in" class="content-block"></div>
@@ -121,20 +130,26 @@
121 130
     <input type="text" id="search-field" />
122 131
     <div id="search-pane" class="pane">
123 132
         <div id="search-results">
124  
-            <div id="applications" class="sub-block active-block">
125  
-                <div class="sub-block-header">
126  
-                    <a tabindex="0" class="header-closed">Applications&hellip;</a>
127  
-                    <a tabindex="0" class="header-opened">Applications:</a>
128  
-                    <span class="application-count header-count-info"></span>
129  
-                </div>
130  
-                <div id="application-list" class="content-block"></div>
  133
+            <div id="applications" class="sub-block active-block cb-block">
  134
+              <div class="sub-block-header">
  135
+                <span class="header-group">
  136
+                  <span class="checkbox group-checkbox"></span>
  137
+                  <a tabindex="0" class="header-closed">Applications&hellip;</a>
  138
+                  <a tabindex="0" class="header-opened">Applications:</a>
  139
+                </span>
  140
+                <span class="application-count header-count-info"></span>
  141
+              </div>
  142
+              <div id="application-list" class="content-block"></div>
131 143
             </div>
132 144
 
133  
-            <div id="modules" class="sub-block active-block">
  145
+            <div id="modules" class="sub-block active-block cb-block">
134 146
                 <div class="sub-block-header">
  147
+                  <span class="header-group">
  148
+                    <span class="checkbox group-checkbox"></span>
135 149
                     <a tabindex="0" class="header-closed">Modules&hellip;</a>
136 150
                     <a tabindex="0" class="header-opened">Modules:</a>
137  
-                    <span class="module-count header-count-info"></span>
  151
+                  </span>
  152
+                  <span class="module-count header-count-info"></span>
138 153
                 </div>
139 154
                 <div id="module-list" class="content-block"></div>
140 155
             </div>
19  priv/js_src/relatio.js
@@ -34,12 +34,18 @@ sigma.publicPrototype.borderNodes = function(onlyVisibleNodes) {
34 34
    return {"top": topNode, "bottom": bottomNode, "left": leftNode, "right": rightNode};
35 35
 }
36 36
 
37  
-
38 37
 sigma.publicPrototype.getNodeById = function(nid) {
39 38
     var nodes = this.getNodes([nid]);
40 39
     return nodes[0];
41 40
 }
42 41
 
  42
+sigma.publicPrototype.forAllNodes = function(fun, nids) {
  43
+  var graph = this._core.graph;
  44
+  return nids.every(function(nid) {
  45
+    return fun(graph.nodesIndex[nid]);
  46
+  });
  47
+}
  48
+
43 49
 sigma.publicPrototype.function2moduleNode = function(functionNode) {
44 50
   var moduleNode;
45 51
   var fid = functionNode.id;
@@ -348,6 +354,7 @@ sigma.publicPrototype.optimalScale = function(rightPanelSize) {
348 354
 
349 355
 
350 356
 sigma.publicPrototype.saveCurrentPosition = function() {
  357
+    var si = this;
351 358
     var n0 = si.getNodeById('zero');
352 359
     var n1 = si.getNodeById('one');
353 360
     var m = si._core.mousecaptor;
@@ -368,6 +375,7 @@ sigma.publicPrototype.saveCurrentPosition = function() {
368 375
 
369 376
 
370 377
 sigma.publicPrototype.setPosition = function(pos) {
  378
+  var si = this;
371 379
   n0 = si.getNodeById('zero');
372 380
   n1 = si.getNodeById('one');
373 381
 
@@ -658,6 +666,15 @@ var Tip = function(si)
658 666
   };
659 667
 };
660 668
 
  669
+$.fn.dataArray = function(key) {
  670
+    var arr = [];
  671
+    for (var i = 0; i < this.length; i++) {
  672
+      var val = $(this[i]).data(key);
  673
+      if (val)
  674
+        arr.push(val);
  675
+    }
  676
+    return arr;
  677
+}
661 678
 
662 679
 /* JSP (scrollbars) EXTENSIONS FOR jQuery */
663 680
 $.fn.activateAutoResizeMonitor = function() {
155  priv/js_src/relatio.world.js
... ...
@@ -1,3 +1,60 @@
  1
+sigma.publicPrototype.applicationIds2modulesIds = function(app_ids) {
  2
+  var mod_node_ids = [];
  3
+  this.iterEdges(function(e) {
  4
+      if (e.attr.edge_type == "am" && ~app_ids.indexOf(e.target)) {
  5
+          mod_node_ids.push(e.source);
  6
+      }
  7
+  });
  8
+  return mod_node_ids;
  9
+}
  10
+
  11
+sigma.publicPrototype.moduleIds2moduleIds = function(ids) {
  12
+  var module_node_ids = [];
  13
+  this.iterEdges(function(e) {
  14
+      if (!e.attr.edge_type) // call edge
  15
+      {
  16
+        if (~ids.indexOf(e.target))
  17
+          module_node_ids.push(e.source);
  18
+        else if (~ids.indexOf(e.source))
  19
+          module_node_ids.push(e.target);
  20
+      }
  21
+  });
  22
+  return module_node_ids;
  23
+}
  24
+
  25
+sigma.publicPrototype.moduleIds2applicationIds = function(module_ids) {
  26
+  var app_ids = [];
  27
+  this.iterEdges(function(e) {
  28
+      if (e.attr.edge_type == "am" && ~module_ids.indexOf(e.source)) 
  29
+        app_ids.push(e.target);
  30
+  });
  31
+  return app_ids;
  32
+}
  33
+
  34
+sigma.publicPrototype.selectNodes = function(nids, is_selected) {
  35
+  var si = this;
  36
+  si.iterNodes(function(n) {
  37
+      n.attr.is_selected = is_selected;
  38
+      if (n.attr.node_type == "app")
  39
+       si.selectNodes(si.applicationIds2modulesIds([n.id]), is_selected);
  40
+  }, nids);
  41
+}
  42
+
  43
+sigma.publicPrototype.isSelectedNode = function(n) {
  44
+  var si = this;
  45
+  switch (n.attr.node_type) {
  46
+    case "app":
  47
+      var module_nids = si.applicationIds2modulesIds([n.id]);
  48
+      return si.forAllNodes(function(n) { return n.attr.is_selected; }, 
  49
+                            module_nids);
  50
+      break;
  51
+    default:
  52
+      return n.attr.is_selected;
  53
+  }
  54
+}
  55
+      
  56
+
  57
+
1 58
 relatio.initWorld = function() {
2 59
   var keyCodes = relatio.keyBoard.keyCodes,
3 60
       charCodes = relatio.keyBoard.charCodes;
@@ -130,7 +187,10 @@ relatio.initWorld = function() {
130 187
     if (add_cb)
131 188
     {
132 189
         var cb = $("<span class='checkbox'></span>");
133  
-        elem.append(cb);
  190
+        cb.data("node_id", nid);
  191
+        if (si.isSelectedNode(node))
  192
+            cb.addClass("selected");
  193
+        elem.append(cb, " ");
134 194
     }
135 195
     elem.append(a);
136 196
     return elem;
@@ -158,29 +218,40 @@ relatio.initWorld = function() {
158 218
     var last1 = 0; // older
159 219
     var last2 = 0; // newer
160 220
 
161  
-    cbs.click(function(e) {
  221
+    cbs.mousedown(function(e) {
162 222
       // This fucuses are neaded to make chromium happy!
163  
-      // This browser tries to select the next.
164  
-      $(cbs[0]).next().focus();
  223
+      // This browser tries to select text beetween the two elements.
165 224
       $(this).next().focus();
  225
+    });
  226
+
  227
+    cbs.click(function(e) {
  228
+      // Set a focus on a link.
  229
+      var t = $(this);
  230
+      t.next().focus();
166 231
       var cur = cbs.index(this);
167 232
       if (last2 != cur) {
168 233
         last1 = last2;
169 234
         last2 = cur;
170 235
       }
  236
+      var is_selected = !t.hasClass("selected");
  237
+      var node_ids;
171 238
       if (e.shiftKey) {
172 239
         var min = Math.min(last1, cur);
173 240
         var max = Math.max(last1, cur);
174 241
         var sel = cbs.slice(min, max+1);
175  
-        if ($(this).hasClass("selected"))
176  
-          sel.removeClass("selected");
177  
-        else
  242
+        if (is_selected)
178 243
           sel.addClass("selected");
  244
+        else
  245
+          sel.removeClass("selected");
  246
+        node_ids = sel.dataArray("node_id");
179 247
       }
180 248
       else
181 249
       {
182  
-        $(this).toggleClass("selected");
  250
+        t.toggleClass("selected");
  251
+        node_ids = [t.data("node_id")];
183 252
       }
  253
+      // Change `is_selected` attribute for each node.
  254
+      si.selectNodes(node_ids, is_selected);
184 255
       return false;
185 256
     });
186 257
 
@@ -201,38 +272,6 @@ relatio.initWorld = function() {
201 272
     return ul;
202 273
   }
203 274
 
204  
-  var applicationIds2modulesIds = function(si, app_ids) {
205  
-    var mod_node_ids = [];
206  
-    si.iterEdges(function(e) {
207  
-        if (e.attr.edge_type == "am" && ~app_ids.indexOf(e.target)) {
208  
-            mod_node_ids.push(e.source);
209  
-        }
210  
-    });
211  
-    return mod_node_ids;
212  
-  }
213  
-
214  
-  var moduleIds2moduleIds = function(si, ids) {
215  
-    var module_node_ids = [];
216  
-    si.iterEdges(function(e) {
217  
-        if (!e.attr.edge_type) // call edge
218  
-        {
219  
-          if (~ids.indexOf(e.target))
220  
-            module_node_ids.push(e.source);
221  
-          else if (~ids.indexOf(e.source))
222  
-            module_node_ids.push(e.target);
223  
-        }
224  
-    });
225  
-    return module_node_ids;
226  
-  }
227  
-
228  
-  var moduleIds2applicationIds = function(si, module_ids) {
229  
-    var app_ids = [];
230  
-    si.iterEdges(function(e) {
231  
-        if (e.attr.edge_type == "am" && ~module_ids.indexOf(e.source)) 
232  
-          app_ids.push(e.target);
233  
-    });
234  
-    return app_ids;
235  
-  }
236 275
 
237 276
   // This function will be called, if a node was clicked.
238 277
   var activateNode = function(event) { 
@@ -271,7 +310,7 @@ relatio.initWorld = function() {
271 310
         // Change a current set of nodes
272 311
         current_node_id = node.id;
273 312
         // Get brothers of the function node.
274  
-        current_node_ids = applicationIds2modulesIds(si, [parent_node.id]);
  313
+        current_node_ids = si.applicationIds2modulesIds([parent_node.id]);
275 314
         break;
276 315
 
277 316
       case "app":
@@ -313,7 +352,7 @@ relatio.initWorld = function() {
313 352
         var application_node_ids = ids.concat(donor_node_ids)
314 353
                                       .concat(rcpnt_node_ids);
315 354
         visible_node_ids = module_node_ids.concat(application_node_ids)
316  
-            .concat(moduleIds2moduleIds(si, module_node_ids));
  355
+            .concat(si.moduleIds2moduleIds(module_node_ids));
317 356
         break;
318 357
 
319 358
 
@@ -332,7 +371,7 @@ relatio.initWorld = function() {
332 371
         });
333 372
         var module_ids = ids.concat(donor_node_ids).concat(rcpnt_node_ids);
334 373
         visible_node_ids = module_ids
335  
-                         .concat(moduleIds2applicationIds(si, module_ids));
  374
+                         .concat(si.moduleIds2applicationIds(module_ids));
336 375
     }
337 376
 
338 377
     // Pane root element
@@ -1017,6 +1056,36 @@ relatio.initWorld = function() {
1017 1056
   // - directly redraw labels (2)
1018 1057
   si.draw(-1, 1, 2);
1019 1058
 
  1059
+  $(".group-checkbox").click(function(e) {
  1060
+      var cur   = $(this);
  1061
+      var block = cur.parents(".sub-block:first");
  1062
+      var cbs   = $(".checkbox", block);
  1063
+      var is_selected = !cur.hasClass("selected");
  1064
+      if (is_selected)
  1065
+          cbs.addClass("selected");
  1066
+      else
  1067
+          cbs.removeClass("selected");
  1068
+      si.selectNodes(cbs.dataArray("node_id"), is_selected);
  1069
+      return false;
  1070
+  });
  1071
+
  1072
+  $(".group-checkbox").on("mouseover mouseout", function(e) {
  1073
+      var cur = $(this);
  1074
+      var blk = cur.parents(".sub-block:first");
  1075
+
  1076
+      switch (e.type) {
  1077
+        case "mouseover":
  1078
+          blk.addClass("hovered-group-cb");
  1079
+          break;
  1080
+
  1081
+        case "mouseout":
  1082
+          blk.removeClass("hovered-group-cb");
  1083
+          break;
  1084
+      }
  1085
+      return false;
  1086
+  });
  1087
+
  1088
+
1020 1089
   $(document).on("keydown keyup", function(e) {
1021 1090
     if (e.keyCode == keyCodes.SHIFT) {
1022 1091
       switch (e.type) {

0 notes on commit 6ebd406

Please sign in to comment.
Something went wrong with that request. Please try again.