blob: c9972a90dd50eed26c8687c01b6bb05912672f03 [file] [log] [blame]
Steven Burrows9edc7e02016-08-29 11:52:07 +01001/*
2 * Copyright 2016-present Open Networking Laboratory
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17/*
18 ONOS GUI -- Topology Select Module.
19 */
20
21(function () {
22 'use strict';
23
Steven Burrowsaf96a212016-12-28 12:57:02 +000024 var t2rs;
25
Steven Burrows9edc7e02016-08-29 11:52:07 +010026 // internal state
Steven Burrowsaf96a212016-12-28 12:57:02 +000027 var consumeClick,
28 zoomer,
29 previousNearestLink; // previous link to mouse position
30
31 function init(svg, _zoomer_) {
32 zoomer = _zoomer_;
33 svg.on('mousemove', mouseMoveHandler);
34 svg.on('click', mouseClickHandler);
35 }
Steven Burrows9edc7e02016-08-29 11:52:07 +010036
Steven Burrowsdfa52b02016-09-02 13:50:43 +010037 function selectObject(obj) {}
Steven Burrows9edc7e02016-08-29 11:52:07 +010038
39 function clickConsumed(x) {
40 var cc = consumeClick;
Steven Burrowsdfa52b02016-09-02 13:50:43 +010041 consumeClick = Boolean(x);
Steven Burrows9edc7e02016-08-29 11:52:07 +010042 return cc;
43 }
44
Steven Burrowsaf96a212016-12-28 12:57:02 +000045 function mouseClickHandler() {
46
47 if (!d3.event.shiftKey) {
48 t2rs.deselectLink();
49 }
50
51 if (!clickConsumed()) {
52 if (previousNearestLink) {
53 previousNearestLink.select();
54 }
55 }
56
57 }
58
59 // Select Links
60 function mouseMoveHandler() {
61 var mp = getLogicalMousePosition(this),
62 link = computeNearestLink(mp);
63
64 // link.enhance();
65 if (link) {
66 if (previousNearestLink && previousNearestLink !== link) {
67 previousNearestLink.unenhance();
68 }
69 link.enhance();
70 } else if (previousNearestLink) {
71 previousNearestLink.unenhance();
72 }
73
74 previousNearestLink = link;
75 }
76
77 function getLogicalMousePosition(container) {
78 var m = d3.mouse(container),
79 sc = zoomer.scale(),
80 tr = zoomer.translate(),
81 mx = (m[0] - tr[0]) / sc,
82 my = (m[1] - tr[1]) / sc;
83 return { x: mx, y: my };
84 }
85
86 function sq(x) {
87 return x * x;
88 }
89
90 function mdist(p, m) {
91 return Math.sqrt(sq(p.x - m.x) + sq(p.y - m.y));
92 }
93
94 function prox(dist) {
95 return dist / zoomer.scale();
96 }
97
98 function computeNearestLink(mouse) {
99 var proximity = prox(30),
100 nearest = null,
101 minDist;
102
103 function pdrop(line, mouse) {
104 var x1 = line.x1,
105 y1 = line.y1,
106 x2 = line.x2,
107 y2 = line.y2,
108 x3 = mouse.x,
109 y3 = mouse.y,
110 k = ((y2 - y1) * (x3 - x1) - (x2 - x1) * (y3 - y1)) /
111 (sq(y2 - y1) + sq(x2 - x1)),
112 x4 = x3 - k * (y2 - y1),
113 y4 = y3 + k * (x2 - x1);
114 return { x: x4, y: y4 };
115 }
116
117 function lineHit(line, p, m) {
118 if (p.x < line.x1 && p.x < line.x2) return false;
119 if (p.x > line.x1 && p.x > line.x2) return false;
120 if (p.y < line.y1 && p.y < line.y2) return false;
121 if (p.y > line.y1 && p.y > line.y2) return false;
122 // line intersects, but are we close enough?
123 return mdist(p, m) <= proximity;
124 }
125
126 var links = t2rs.regionLinks();
127
128 if (links.length) {
129 minDist = proximity * 2;
130
131 links.forEach(function (d) {
132 var line = d.get('position'),
133 point,
134 hit,
135 dist;
136
137 // TODO: Reinstate when showHost() is implemented
138 // if (!api.showHosts() && d.type() === 'hostLink') {
139 // return; // skip hidden host links
140 // }
141
142 if (line) {
143 point = pdrop(line, mouse);
144 hit = lineHit(line, point, mouse);
145 if (hit) {
146 dist = mdist(point, mouse);
147 if (dist < minDist) {
148 minDist = dist;
149 nearest = d;
150 }
151 }
152 }
153 });
154 }
155
156 return nearest;
157 }
158
Steven Burrows9edc7e02016-08-29 11:52:07 +0100159 angular.module('ovTopo2')
Steven Burrowsdfa52b02016-09-02 13:50:43 +0100160 .factory('Topo2SelectService', [
Steven Burrowsaf96a212016-12-28 12:57:02 +0000161 'Topo2RegionService',
162 function (_t2rs_) {
163
164 t2rs = _t2rs_;
Steven Burrows9edc7e02016-08-29 11:52:07 +0100165
166 return {
Steven Burrowsaf96a212016-12-28 12:57:02 +0000167 init: init,
Steven Burrows9edc7e02016-08-29 11:52:07 +0100168 selectObject: selectObject,
169 clickConsumed: clickConsumed
170 };
171 }
172 ]);
173
174})();