|
1 "use strict"; |
|
2 |
|
3 define(['jquery', 'underscore', 'requtils', 'renderer/miniframe'], function ($, _, requtils, MiniFrame) { |
|
4 |
|
5 var Utils = requtils.getUtils(); |
|
6 |
|
7 /* Scene Begin */ |
|
8 |
|
9 var Scene = function(_renkan) { |
|
10 this.renkan = _renkan; |
|
11 this.$ = $(".Rk-Render"); |
|
12 this.representations = []; |
|
13 this.$.html(this.template(_renkan)); |
|
14 this.onStatusChange(); |
|
15 this.canvas_$ = this.$.find(".Rk-Canvas"); |
|
16 this.labels_$ = this.$.find(".Rk-Labels"); |
|
17 this.editor_$ = this.$.find(".Rk-Editor"); |
|
18 this.notif_$ = this.$.find(".Rk-Notifications"); |
|
19 paper.setup(this.canvas_$[0]); |
|
20 this.scale = 1; |
|
21 this.initialScale = 1; |
|
22 this.offset = paper.view.center; |
|
23 this.totalScroll = 0; |
|
24 this.mouse_down = false; |
|
25 this.click_target = null; |
|
26 this.selected_target = null; |
|
27 this.edge_layer = new paper.Layer(); |
|
28 this.node_layer = new paper.Layer(); |
|
29 this.buttons_layer = new paper.Layer(); |
|
30 this.delete_list = []; |
|
31 |
|
32 if (_renkan.options.show_minimap) { |
|
33 this.minimap = { |
|
34 background_layer: new paper.Layer(), |
|
35 edge_layer: new paper.Layer(), |
|
36 node_layer: new paper.Layer(), |
|
37 node_group: new paper.Group(), |
|
38 size: new paper.Size( _renkan.options.minimap_width, _renkan.options.minimap_height ) |
|
39 }; |
|
40 |
|
41 this.minimap.background_layer.activate(); |
|
42 this.minimap.topleft = paper.view.bounds.bottomRight.subtract(this.minimap.size); |
|
43 this.minimap.rectangle = new paper.Path.Rectangle(this.minimap.topleft.subtract([2,2]), this.minimap.size.add([4,4])); |
|
44 this.minimap.rectangle.fillColor = _renkan.options.minimap_background_color; |
|
45 this.minimap.rectangle.strokeColor = _renkan.options.minimap_border_color; |
|
46 this.minimap.rectangle.strokeWidth = 4; |
|
47 this.minimap.offset = new paper.Point(this.minimap.size.divide(2)); |
|
48 this.minimap.scale = .1; |
|
49 |
|
50 this.minimap.node_layer.activate(); |
|
51 this.minimap.cliprectangle = new paper.Path.Rectangle(this.minimap.topleft, this.minimap.size); |
|
52 this.minimap.node_group.addChild(this.minimap.cliprectangle); |
|
53 this.minimap.node_group.clipped = true; |
|
54 this.minimap.miniframe = new paper.Path.Rectangle(this.minimap.topleft, this.minimap.size); |
|
55 this.minimap.node_group.addChild(this.minimap.miniframe); |
|
56 this.minimap.miniframe.fillColor = '#c0c0ff'; |
|
57 this.minimap.miniframe.opacity = .3; |
|
58 this.minimap.miniframe.strokeColor = '#000080'; |
|
59 this.minimap.miniframe.strokeWidth = 3; |
|
60 this.minimap.miniframe.__representation = new MiniFrame(this, null); |
|
61 } |
|
62 |
|
63 this.throttledPaperDraw = _(function() { |
|
64 paper.view.draw(); |
|
65 }).throttle(100); |
|
66 |
|
67 this.bundles = []; |
|
68 this.click_mode = false; |
|
69 |
|
70 var _this = this, |
|
71 _allowScroll = true, |
|
72 _originalScale = 1, |
|
73 _zooming = false, |
|
74 _lastTapX = 0, |
|
75 _lastTapY = 0; |
|
76 |
|
77 this.image_cache = {}; |
|
78 this.icon_cache = {}; |
|
79 |
|
80 ['edit', 'remove', 'link', 'enlarge', 'shrink', 'revert' ].forEach(function(imgname) { |
|
81 var img = new Image(); |
|
82 img.src = _renkan.options.static_url + 'img/' + imgname + '.png'; |
|
83 _this.icon_cache[imgname] = img; |
|
84 }); |
|
85 |
|
86 var throttledMouseMove = _.throttle(function(_event, _isTouch) { |
|
87 _this.onMouseMove(_event, _isTouch); |
|
88 }, Utils._MOUSEMOVE_RATE); |
|
89 |
|
90 this.canvas_$.on({ |
|
91 mousedown: function(_event) { |
|
92 _event.preventDefault(); |
|
93 _this.onMouseDown(_event, false); |
|
94 }, |
|
95 mousemove: function(_event) { |
|
96 _event.preventDefault(); |
|
97 throttledMouseMove(_event, false); |
|
98 }, |
|
99 mouseup: function(_event) { |
|
100 _event.preventDefault(); |
|
101 _this.onMouseUp(_event, false); |
|
102 }, |
|
103 mousewheel: function(_event, _delta) { |
|
104 if(_renkan.options.zoom_on_scroll) { |
|
105 _event.preventDefault(); |
|
106 if (_allowScroll) { |
|
107 _this.onScroll(_event, _delta); |
|
108 } |
|
109 } |
|
110 }, |
|
111 touchstart: function(_event) { |
|
112 _event.preventDefault(); |
|
113 var _touches = _event.originalEvent.touches[0]; |
|
114 if ( |
|
115 _renkan.options.allow_double_click |
|
116 && new Date() - _lastTap < Utils._DOUBLETAP_DELAY |
|
117 && ( Math.pow(_lastTapX - _touches.pageX, 2) + Math.pow(_lastTapY - _touches.pageY, 2) < Utils._DOUBLETAP_DISTANCE ) |
|
118 ) { |
|
119 _lastTap = 0; |
|
120 _this.onDoubleClick(_touches); |
|
121 } else { |
|
122 _lastTap = new Date(); |
|
123 _lastTapX = _touches.pageX; |
|
124 _lastTapY = _touches.pageY; |
|
125 _originalScale = _this.scale; |
|
126 _zooming = false; |
|
127 _this.onMouseDown(_touches, true); |
|
128 } |
|
129 }, |
|
130 touchmove: function(_event) { |
|
131 _event.preventDefault(); |
|
132 _lastTap = 0; |
|
133 if (_event.originalEvent.touches.length == 1) { |
|
134 _this.onMouseMove(_event.originalEvent.touches[0], true); |
|
135 } else { |
|
136 if (!_zooming) { |
|
137 _this.onMouseUp(_event.originalEvent.touches[0], true); |
|
138 _this.click_target = null; |
|
139 _this.is_dragging = false; |
|
140 _zooming = true; |
|
141 } |
|
142 if (_event.originalEvent.scale === "undefined") { |
|
143 return; |
|
144 } |
|
145 var _newScale = _event.originalEvent.scale * _originalScale, |
|
146 _scaleRatio = _newScale / _this.scale, |
|
147 _newOffset = new paper.Point([ |
|
148 _this.canvas_$.width(), |
|
149 _this.canvas_$.height() |
|
150 ]).multiply( .5 * ( 1 - _scaleRatio ) ).add(_this.offset.multiply( _scaleRatio )); |
|
151 _this.setScale(_newScale, _newOffset); |
|
152 } |
|
153 }, |
|
154 touchend: function(_event) { |
|
155 _event.preventDefault(); |
|
156 _this.onMouseUp(_event.originalEvent.changedTouches[0], true); |
|
157 }, |
|
158 dblclick: function(_event) { |
|
159 _event.preventDefault(); |
|
160 if (_renkan.options.allow_double_click) { |
|
161 _this.onDoubleClick(_event); |
|
162 } |
|
163 }, |
|
164 mouseleave: function(_event) { |
|
165 _event.preventDefault(); |
|
166 _this.onMouseUp(_event, false); |
|
167 _this.click_target = null; |
|
168 _this.is_dragging = false; |
|
169 }, |
|
170 dragover: function(_event) { |
|
171 _event.preventDefault(); |
|
172 }, |
|
173 dragenter: function(_event) { |
|
174 _event.preventDefault(); |
|
175 _allowScroll = false; |
|
176 }, |
|
177 dragleave: function(_event) { |
|
178 _event.preventDefault(); |
|
179 _allowScroll = true; |
|
180 }, |
|
181 drop: function(_event) { |
|
182 _event.preventDefault(); |
|
183 _allowScroll = true; |
|
184 var res = {}; |
|
185 _(_event.originalEvent.dataTransfer.types).each(function(t) { |
|
186 try { |
|
187 res[t] = _event.originalEvent.dataTransfer.getData(t); |
|
188 } catch(e) {} |
|
189 }); |
|
190 var text = _event.originalEvent.dataTransfer.getData("Text"); |
|
191 if (typeof text === "string") { |
|
192 switch(text[0]) { |
|
193 case "{": |
|
194 case "[": |
|
195 try { |
|
196 var data = JSON.parse(text); |
|
197 _(res).extend(data); |
|
198 } |
|
199 catch(e) { |
|
200 if (!res["text/plain"]) { |
|
201 res["text/plain"] = text; |
|
202 } |
|
203 } |
|
204 break; |
|
205 case "<": |
|
206 if (!res["text/html"]) { |
|
207 res["text/html"] = text; |
|
208 } |
|
209 break; |
|
210 default: |
|
211 if (!res["text/plain"]) { |
|
212 res["text/plain"] = text; |
|
213 } |
|
214 } |
|
215 } |
|
216 var url = _event.originalEvent.dataTransfer.getData("URL"); |
|
217 if (url && !res["text/uri-list"]) { |
|
218 res["text/uri-list"] = url; |
|
219 } |
|
220 _this.dropData(res, _event.originalEvent); |
|
221 } |
|
222 }); |
|
223 |
|
224 var bindClick = function(selector, fname) { |
|
225 _this.$.find(selector).click(function(evt) { |
|
226 _this[fname](evt); |
|
227 return false; |
|
228 }); |
|
229 }; |
|
230 |
|
231 bindClick(".Rk-ZoomOut", "zoomOut"); |
|
232 bindClick(".Rk-ZoomIn", "zoomIn"); |
|
233 bindClick(".Rk-ZoomFit", "autoScale"); |
|
234 this.$.find(".Rk-ZoomSave").click( function() { |
|
235 // Save scale and offset point |
|
236 _this.renkan.project.addView( { zoom_level:_this.scale, offset_x:_this.offset.x, offset_y:_this.offset.y } ); |
|
237 }); |
|
238 this.$.find(".Rk-ZoomSetSaved").click( function() { |
|
239 var view = _this.renkan.project.get("views").last(); |
|
240 if(view){ |
|
241 _this.setScale(view.get("zoom_level"), new paper.Point(view.get("offset_x"), view.get("offset_y"))); |
|
242 } |
|
243 }); |
|
244 if(this.renkan.read_only && !isNaN(parseInt(this.renkan.options.default_view))){ |
|
245 this.$.find(".Rk-ZoomSetSaved").show(); |
|
246 } |
|
247 this.$.find(".Rk-CurrentUser").mouseenter( |
|
248 function() { _this.$.find(".Rk-UserList").slideDown(); } |
|
249 ); |
|
250 this.$.find(".Rk-Users").mouseleave( |
|
251 function() { _this.$.find(".Rk-UserList").slideUp(); } |
|
252 ); |
|
253 bindClick(".Rk-FullScreen-Button", "fullScreen"); |
|
254 bindClick(".Rk-AddNode-Button", "addNodeBtn"); |
|
255 bindClick(".Rk-AddEdge-Button", "addEdgeBtn"); |
|
256 bindClick(".Rk-Save-Button", "save"); |
|
257 bindClick(".Rk-Open-Button", "open"); |
|
258 this.$.find(".Rk-Bookmarklet-Button") |
|
259 .attr("href","javascript:" + Utils._BOOKMARKLET_CODE(_renkan)) |
|
260 .click(function(){ |
|
261 _this.notif_$ |
|
262 .text(_renkan.translate("Drag this button to your bookmark bar. When on a third-party website, click it to enable drag-and-drop from the website to Renkan.")) |
|
263 .fadeIn() |
|
264 .delay(5000) |
|
265 .fadeOut(); |
|
266 return false; |
|
267 }); |
|
268 this.$.find(".Rk-TopBar-Button").mouseover(function() { |
|
269 $(this).find(".Rk-TopBar-Tooltip").show(); |
|
270 }).mouseout(function() { |
|
271 $(this).find(".Rk-TopBar-Tooltip").hide(); |
|
272 }); |
|
273 bindClick(".Rk-Fold-Bins", "foldBins"); |
|
274 |
|
275 paper.view.onResize = function(_event) { |
|
276 // Because of paper bug which does not calculate the good height (and width a fortiori) |
|
277 // We have to update manually the canvas's height |
|
278 paper.view._viewSize.height = _event.size.height = _this.canvas_$.parent().height(); |
|
279 |
|
280 if (_this.minimap) { |
|
281 _this.minimap.topleft = paper.view.bounds.bottomRight.subtract(_this.minimap.size); |
|
282 _this.minimap.rectangle.fitBounds(_this.minimap.topleft.subtract([2,2]), _this.minimap.size.add([4,4])); |
|
283 _this.minimap.cliprectangle.fitBounds(_this.minimap.topleft, _this.minimap.size); |
|
284 } |
|
285 _this.redraw(); |
|
286 }; |
|
287 |
|
288 var _thRedraw = _.throttle(function() { |
|
289 _this.redraw(); |
|
290 },50); |
|
291 |
|
292 this.addRepresentations("Node", this.renkan.project.get("nodes")); |
|
293 this.addRepresentations("Edge", this.renkan.project.get("edges")); |
|
294 this.renkan.project.on("change:title", function() { |
|
295 _this.$.find(".Rk-PadTitle").val(_renkan.project.get("title")); |
|
296 }); |
|
297 |
|
298 this.$.find(".Rk-PadTitle").on("keyup input paste", function() { |
|
299 _renkan.project.set({"title": $(this).val()}); |
|
300 }); |
|
301 |
|
302 var _thRedrawUsers = _.throttle(function() { |
|
303 _this.redrawUsers(); |
|
304 }, 100); |
|
305 |
|
306 _thRedrawUsers(); |
|
307 |
|
308 // register model events |
|
309 this.renkan.project.on("add:users remove:users", _thRedrawUsers); |
|
310 |
|
311 this.renkan.project.on("add:views remove:views", function(_node) { |
|
312 if(_this.renkan.project.get('views').length > 0) { |
|
313 _this.$.find(".Rk-ZoomSetSaved").show(); |
|
314 } |
|
315 else { |
|
316 _this.$.find(".Rk-ZoomSetSaved").hide(); |
|
317 } |
|
318 }); |
|
319 |
|
320 this.renkan.project.on("add:nodes", function(_node) { |
|
321 _this.addRepresentation("Node", _node); |
|
322 _thRedraw(); |
|
323 }); |
|
324 this.renkan.project.on("add:edges", function(_edge) { |
|
325 _this.addRepresentation("Edge", _edge); |
|
326 _thRedraw(); |
|
327 }); |
|
328 this.renkan.project.on("change:title", function(_model, _title) { |
|
329 var el = _this.$.find(".Rk-PadTitle"); |
|
330 if (el.is("input")) { |
|
331 if (el.val() !== _title) { |
|
332 el.val(_title); |
|
333 } |
|
334 } else { |
|
335 el.text(_title); |
|
336 } |
|
337 }); |
|
338 |
|
339 if (_renkan.options.size_bug_fix) { |
|
340 var _delay = ( |
|
341 typeof _renkan.options.size_bug_fix === "number" |
|
342 ? _renkan.options.size_bug_fix |
|
343 : 500 |
|
344 ); |
|
345 window.setTimeout( |
|
346 function() { |
|
347 _this.fixSize(true); |
|
348 }, |
|
349 _delay |
|
350 ); |
|
351 } |
|
352 |
|
353 if (_renkan.options.force_resize) { |
|
354 $(window).resize(function() { |
|
355 _this.fixSize(false); |
|
356 }); |
|
357 } |
|
358 |
|
359 if (_renkan.options.show_user_list && _renkan.options.user_color_editable) { |
|
360 var $cpwrapper = this.$.find(".Rk-Users .Rk-Edit-ColorPicker-Wrapper"), |
|
361 $cplist = this.$.find(".Rk-Users .Rk-Edit-ColorPicker"); |
|
362 |
|
363 $cpwrapper.hover( |
|
364 function(_e) { |
|
365 if (_this.isEditable()) { |
|
366 _e.preventDefault(); |
|
367 $cplist.show(); |
|
368 } |
|
369 }, |
|
370 function(_e) { |
|
371 _e.preventDefault(); |
|
372 $cplist.hide(); |
|
373 } |
|
374 ); |
|
375 |
|
376 $cplist.find("li").mouseenter( |
|
377 function(_e) { |
|
378 if (_this.isEditable()) { |
|
379 _e.preventDefault(); |
|
380 _this.$.find(".Rk-CurrentUser-Color").css("background", $(this).attr("data-color")); |
|
381 } |
|
382 } |
|
383 ); |
|
384 } |
|
385 |
|
386 if (_renkan.options.show_search_field) { |
|
387 |
|
388 var lastval = ''; |
|
389 |
|
390 this.$.find(".Rk-GraphSearch-Field").on("keyup change paste input", function() { |
|
391 var $this = $(this), |
|
392 val = $this.val(); |
|
393 if (val === lastval) { |
|
394 return; |
|
395 } |
|
396 lastval = val; |
|
397 if (val.length < 2) { |
|
398 _renkan.project.get("nodes").each(function(n) { |
|
399 _this.getRepresentationByModel(n).unhighlight(); |
|
400 }); |
|
401 } else { |
|
402 var rxs = Utils.regexpFromTextOrArray(val); |
|
403 _renkan.project.get("nodes").each(function(n) { |
|
404 if (rxs.test(n.get("title")) || rxs.test(n.get("description"))) { |
|
405 _this.getRepresentationByModel(n).highlight(rxs); |
|
406 } else { |
|
407 _this.getRepresentationByModel(n).unhighlight(); |
|
408 } |
|
409 }); |
|
410 } |
|
411 }); |
|
412 } |
|
413 |
|
414 this.redraw(); |
|
415 |
|
416 window.setInterval(function() { |
|
417 var _now = new Date().valueOf(); |
|
418 _this.delete_list.forEach(function(d) { |
|
419 if (_now >= d.time) { |
|
420 var el = _renkan.project.get("nodes").findWhere({"delete_scheduled":d.id}); |
|
421 if (el) { |
|
422 project.removeNode(el); |
|
423 } |
|
424 el = _renkan.project.get("edges").findWhere({"delete_scheduled":d.id}); |
|
425 if (el) { |
|
426 project.removeEdge(el); |
|
427 } |
|
428 } |
|
429 }); |
|
430 _this.delete_list = _this.delete_list.filter(function(d) { |
|
431 return _renkan.project.get("nodes").findWhere({"delete_scheduled":d.id}) || _renkan.project.get("edges").findWhere({"delete_scheduled":d.id}); |
|
432 }); |
|
433 }, 500); |
|
434 |
|
435 if (this.minimap) { |
|
436 window.setInterval(function() { |
|
437 _this.rescaleMinimap(); |
|
438 }, 2000); |
|
439 } |
|
440 |
|
441 }; |
|
442 |
|
443 _(Scene.prototype).extend({ |
|
444 template: _.template( |
|
445 '<% if (options.show_top_bar) { %><div class="Rk-TopBar"><% if (!options.editor_mode) { %><h2 class="Rk-PadTitle"><%- project.get("title") || translate("Untitled project")%></h2>' |
|
446 + '<% } else { %><input type="text" class="Rk-PadTitle" value="<%- project.get("title") || "" %>" placeholder="<%-translate("Untitled project")%>" /><% } %>' |
|
447 + '<% if (options.show_user_list) { %><div class="Rk-Users"><div class="Rk-CurrentUser"><div class="Rk-Edit-ColorPicker-Wrapper"><span class="Rk-CurrentUser-Color"><% if (options.user_color_editable) { %><span class="Rk-Edit-ColorTip"></span><% } %></span>' |
|
448 + '<% if (options.user_color_editable) { print(colorPicker) } %></div><span class="Rk-CurrentUser-Name"><unknown user></span></div><ul class="Rk-UserList"></ul></div><% } %>' |
|
449 + '<% if (options.home_button_url) {%><div class="Rk-TopBar-Separator"></div><a class="Rk-TopBar-Button Rk-Home-Button" href="<%- options.home_button_url %>"><div class="Rk-TopBar-Tooltip"><div class="Rk-TopBar-Tooltip-Contents">' |
|
450 + '<%- translate(options.home_button_title) %></div></div></a><% } %>' |
|
451 + '<% if (options.show_fullscreen_button) { %><div class="Rk-TopBar-Separator"></div><div class="Rk-TopBar-Button Rk-FullScreen-Button"><div class="Rk-TopBar-Tooltip"><div class="Rk-TopBar-Tooltip-Contents"><%-translate("Full Screen")%></div></div></div><% } %>' |
|
452 + '<% if (options.editor_mode) { %>' |
|
453 + '<% if (options.show_addnode_button) { %><div class="Rk-TopBar-Separator"></div><div class="Rk-TopBar-Button Rk-AddNode-Button"><div class="Rk-TopBar-Tooltip">' |
|
454 + '<div class="Rk-TopBar-Tooltip-Contents"><%-translate("Add Node")%></div></div></div><% } %>' |
|
455 + '<% if (options.show_addedge_button) { %><div class="Rk-TopBar-Separator"></div><div class="Rk-TopBar-Button Rk-AddEdge-Button"><div class="Rk-TopBar-Tooltip">' |
|
456 + '<div class="Rk-TopBar-Tooltip-Contents"><%-translate("Add Edge")%></div></div></div><% } %>' |
|
457 + '<% if (options.show_save_button) { %><div class="Rk-TopBar-Separator"></div><div class="Rk-TopBar-Button Rk-Save-Button"><div class="Rk-TopBar-Tooltip"><div class="Rk-TopBar-Tooltip-Contents"> </div></div></div><% } %>' |
|
458 + '<% if (options.show_open_button) { %><div class="Rk-TopBar-Separator"></div><div class="Rk-TopBar-Button Rk-Open-Button"><div class="Rk-TopBar-Tooltip"><div class="Rk-TopBar-Tooltip-Contents"><%-translate("Open Project")%></div></div></div><% } %>' |
|
459 + '<% if (options.show_bookmarklet) { %><div class="Rk-TopBar-Separator"></div><a class="Rk-TopBar-Button Rk-Bookmarklet-Button" href="#"><div class="Rk-TopBar-Tooltip"><div class="Rk-TopBar-Tooltip-Contents">' |
|
460 + '<%-translate("Renkan \'Drag-to-Add\' bookmarklet")%></div></div></a><% } %>' |
|
461 + '<div class="Rk-TopBar-Separator"></div><% }; if (options.show_search_field) { %>' |
|
462 + '<form action="#" class="Rk-GraphSearch-Form"><input type="search" class="Rk-GraphSearch-Field" placeholder="<%- translate("Search in graph") %>" /></form><div class="Rk-TopBar-Separator"></div><% } %></div><% } %>' |
|
463 + '<div class="Rk-Editing-Space<% if (!options.show_top_bar) { %> Rk-Editing-Space-Full<% } %>">' |
|
464 + '<div class="Rk-Labels"></div><canvas class="Rk-Canvas" resize></canvas><div class="Rk-Notifications"></div><div class="Rk-Editor">' |
|
465 + '<% if (options.show_bins) { %><div class="Rk-Fold-Bins">«</div><% } %>' |
|
466 + '<div class="Rk-ZoomButtons"><div class="Rk-ZoomIn" title="<%-translate("Zoom In")%>"></div><div class="Rk-ZoomFit" title="<%-translate("Zoom Fit")%>"></div><div class="Rk-ZoomOut" title="<%-translate("Zoom Out")%>"></div>' |
|
467 + '<% if (options.editor_mode) { %><div class="Rk-ZoomSave" title="<%-translate("Zoom Save")%>"></div><% } %>' |
|
468 + '<% if (options.editor_mode || !isNaN(parseInt(options.default_view))) { %><div class="Rk-ZoomSetSaved" title="<%-translate("View saved zoom")%>"></div><% } %></div>' |
|
469 + '</div></div>' |
|
470 ), |
|
471 fixSize: function(_autoscale) { |
|
472 var w = this.$.width(), |
|
473 h = this.$.height(); |
|
474 if (this.renkan.options.show_top_bar) { |
|
475 h -= this.$.find(".Rk-TopBar").height(); |
|
476 } |
|
477 this.canvas_$.attr({ |
|
478 width: w, |
|
479 height: h |
|
480 }); |
|
481 |
|
482 paper.view.viewSize = new paper.Size([w, h]); |
|
483 |
|
484 if (_autoscale) { |
|
485 // If _autoscale, we get the initial view (zoom+offset) set in the project datas. |
|
486 if(this.renkan.read_only && !isNaN(parseInt(this.renkan.options.default_view))){ |
|
487 this.autoScale(this.renkan.project.get("views")[parseInt(this.renkan.options.default_view)]); |
|
488 } |
|
489 else{ |
|
490 this.autoScale(); |
|
491 } |
|
492 } |
|
493 }, |
|
494 drawSector: function(_repr, _inR, _outR, _startAngle, _endAngle, _padding, _imgname, _caption) { |
|
495 var _options = this.renkan.options, |
|
496 _startRads = _startAngle * Math.PI / 180, |
|
497 _endRads = _endAngle * Math.PI / 180, |
|
498 _img = this.icon_cache[_imgname], |
|
499 _startdx = - Math.sin(_startRads), |
|
500 _startdy = Math.cos(_startRads), |
|
501 _startXIn = Math.cos(_startRads) * _inR + _padding * _startdx, |
|
502 _startYIn = Math.sin(_startRads) * _inR + _padding * _startdy, |
|
503 _startXOut = Math.cos(_startRads) * _outR + _padding * _startdx, |
|
504 _startYOut = Math.sin(_startRads) * _outR + _padding * _startdy, |
|
505 _enddx = - Math.sin(_endRads), |
|
506 _enddy = Math.cos(_endRads), |
|
507 _endXIn = Math.cos(_endRads) * _inR - _padding * _enddx, |
|
508 _endYIn = Math.sin(_endRads) * _inR - _padding * _enddy, |
|
509 _endXOut = Math.cos(_endRads) * _outR - _padding * _enddx, |
|
510 _endYOut = Math.sin(_endRads) * _outR - _padding * _enddy, |
|
511 _centerR = (_inR + _outR)/2, |
|
512 _centerRads = (_startRads + _endRads) / 2, |
|
513 _centerX = Math.cos(_centerRads) * _centerR, |
|
514 _centerY = Math.sin(_centerRads) * _centerR, |
|
515 _centerXIn = Math.cos(_centerRads) * _inR, |
|
516 _centerXOut = Math.cos(_centerRads) * _outR, |
|
517 _centerYIn = Math.sin(_centerRads) * _inR, |
|
518 _centerYOut = Math.sin(_centerRads) * _outR, |
|
519 _textX = Math.cos(_centerRads) * (_outR + 3), |
|
520 _textY = Math.sin(_centerRads) * (_outR + _options.buttons_label_font_size) + _options.buttons_label_font_size / 2; |
|
521 this.buttons_layer.activate(); |
|
522 var _path = new paper.Path(); |
|
523 _path.add([_startXIn, _startYIn]); |
|
524 _path.arcTo([_centerXIn, _centerYIn], [_endXIn, _endYIn]); |
|
525 _path.lineTo([_endXOut, _endYOut]); |
|
526 _path.arcTo([_centerXOut, _centerYOut], [_startXOut, _startYOut]); |
|
527 _path.fillColor = _options.buttons_background; |
|
528 _path.opacity = .5; |
|
529 _path.closed = true; |
|
530 _path.__representation = _repr; |
|
531 var _text = new paper.PointText(_textX,_textY); |
|
532 _text.characterStyle = { |
|
533 fontSize: _options.buttons_label_font_size, |
|
534 fillColor: _options.buttons_label_color |
|
535 }; |
|
536 if (_textX > 2) { |
|
537 _text.paragraphStyle.justification = 'left'; |
|
538 } else if (_textX < -2) { |
|
539 _text.paragraphStyle.justification = 'right'; |
|
540 } else { |
|
541 _text.paragraphStyle.justification = 'center'; |
|
542 } |
|
543 _text.visible = false; |
|
544 var _visible = false, |
|
545 _restPos = new paper.Point(-200, -200), |
|
546 _grp = new paper.Group([_path, _text]), |
|
547 _delta = _grp.position, |
|
548 _imgdelta = new paper.Point([_centerX, _centerY]), |
|
549 _currentPos = new paper.Point(0,0); |
|
550 _text.content = _caption; |
|
551 _grp.visible = false; |
|
552 _grp.position = _restPos; |
|
553 var _res = { |
|
554 show: function() { |
|
555 _visible = true; |
|
556 _grp.position = _currentPos.add(_delta); |
|
557 _grp.visible = true; |
|
558 }, |
|
559 moveTo: function(_point) { |
|
560 _currentPos = _point; |
|
561 if (_visible) { |
|
562 _grp.position = _point.add(_delta); |
|
563 } |
|
564 }, |
|
565 hide: function() { |
|
566 _visible = false; |
|
567 _grp.visible = false; |
|
568 _grp.position = _restPos; |
|
569 }, |
|
570 select: function() { |
|
571 _path.opacity = .8; |
|
572 _text.visible = true; |
|
573 }, |
|
574 unselect: function() { |
|
575 _path.opacity = .5; |
|
576 _text.visible = false; |
|
577 }, |
|
578 destroy: function() { |
|
579 _grp.remove(); |
|
580 } |
|
581 }; |
|
582 var showImage = function() { |
|
583 var _raster = new paper.Raster(_img); |
|
584 _raster.position = _imgdelta.add(_grp.position).subtract(_delta); |
|
585 _raster.locked = true; // Disable mouse events on icon |
|
586 _grp.addChild(_raster); |
|
587 }; |
|
588 if (_img.width) { |
|
589 showImage(); |
|
590 } else { |
|
591 $(_img).on("load",showImage); |
|
592 } |
|
593 |
|
594 return _res; |
|
595 }, |
|
596 addToBundles: function(_edgeRepr) { |
|
597 var _bundle = _(this.bundles).find(function(_bundle) { |
|
598 return ( |
|
599 ( _bundle.from === _edgeRepr.from_representation && _bundle.to === _edgeRepr.to_representation ) |
|
600 || ( _bundle.from === _edgeRepr.to_representation && _bundle.to === _edgeRepr.from_representation ) |
|
601 ); |
|
602 }); |
|
603 if (typeof _bundle !== "undefined") { |
|
604 _bundle.edges.push(_edgeRepr); |
|
605 } else { |
|
606 _bundle = { |
|
607 from: _edgeRepr.from_representation, |
|
608 to: _edgeRepr.to_representation, |
|
609 edges: [ _edgeRepr ], |
|
610 getPosition: function(_er) { |
|
611 var _dir = (_er.from_representation === this.from) ? 1 : -1; |
|
612 return _dir * ( _(this.edges).indexOf(_er) - (this.edges.length - 1) / 2 ); |
|
613 } |
|
614 }; |
|
615 this.bundles.push(_bundle); |
|
616 } |
|
617 return _bundle; |
|
618 }, |
|
619 isEditable: function() { |
|
620 return (this.renkan.options.editor_mode && !this.renkan.read_only); |
|
621 }, |
|
622 onStatusChange: function() { |
|
623 var savebtn = this.$.find(".Rk-Save-Button"), |
|
624 tip = savebtn.find(".Rk-TopBar-Tooltip-Contents"); |
|
625 if (this.renkan.read_only) { |
|
626 savebtn.removeClass("disabled Rk-Save-Online").addClass("Rk-Save-ReadOnly"); |
|
627 tip.text(this.renkan.translate("Connection lost")); |
|
628 } else { |
|
629 if (this.renkan.options.snapshot_mode) { |
|
630 savebtn.removeClass("Rk-Save-ReadOnly Rk-Save-Online"); |
|
631 tip.text(this.renkan.translate("Save Project")); |
|
632 } else { |
|
633 savebtn.removeClass("disabled Rk-Save-ReadOnly").addClass("Rk-Save-Online"); |
|
634 tip.text(this.renkan.translate("Auto-save enabled")); |
|
635 } |
|
636 } |
|
637 this.redrawUsers(); |
|
638 }, |
|
639 setScale: function(_newScale, _offset) { |
|
640 if ((_newScale/this.initialScale) > Utils._MIN_SCALE && (_newScale/this.initialScale) < Utils._MAX_SCALE) { |
|
641 this.scale = _newScale; |
|
642 if (_offset) { |
|
643 this.offset = _offset; |
|
644 } |
|
645 this.redraw(); |
|
646 } |
|
647 }, |
|
648 autoScale: function(force_view) { |
|
649 var nodes = this.renkan.project.get("nodes"); |
|
650 if (nodes.length > 1) { |
|
651 var _xx = nodes.map(function(_node) { return _node.get("position").x; }), |
|
652 _yy = nodes.map(function(_node) { return _node.get("position").y; }), |
|
653 _minx = Math.min.apply(Math, _xx), |
|
654 _miny = Math.min.apply(Math, _yy), |
|
655 _maxx = Math.max.apply(Math, _xx), |
|
656 _maxy = Math.max.apply(Math, _yy); |
|
657 var _scale = Math.min( (paper.view.size.width - 2 * this.renkan.options.autoscale_padding) / (_maxx - _minx), (paper.view.size.height - 2 * this.renkan.options.autoscale_padding) / (_maxy - _miny)); |
|
658 this.initialScale = _scale; |
|
659 // Override calculated scale if asked |
|
660 if((typeof force_view !== "undefined") && parseFloat(force_view.zoom_level)>0 && parseFloat(force_view.offset_x)>0 && parseFloat(force_view.offset_y)>0){ |
|
661 this.setScale(parseFloat(force_view.zoom_level), new paper.Point(parseFloat(force_view.offset_x), parseFloat(force_view.offset_y))); |
|
662 } |
|
663 else{ |
|
664 this.setScale(_scale, paper.view.center.subtract(new paper.Point([(_maxx + _minx) / 2, (_maxy + _miny) / 2]).multiply(_scale))); |
|
665 } |
|
666 } |
|
667 if (nodes.length === 1) { |
|
668 this.setScale(1, paper.view.center.subtract(new paper.Point([nodes.at(0).get("position").x, nodes.at(0).get("position").y]))); |
|
669 } |
|
670 }, |
|
671 redrawMiniframe: function() { |
|
672 var topleft = this.toMinimapCoords(this.toModelCoords(new paper.Point([0,0]))), |
|
673 bottomright = this.toMinimapCoords(this.toModelCoords(paper.view.bounds.bottomRight)); |
|
674 this.minimap.miniframe.fitBounds(topleft, bottomright); |
|
675 }, |
|
676 rescaleMinimap: function() { |
|
677 var nodes = this.renkan.project.get("nodes"); |
|
678 if (nodes.length > 1) { |
|
679 var _xx = nodes.map(function(_node) { return _node.get("position").x; }), |
|
680 _yy = nodes.map(function(_node) { return _node.get("position").y; }), |
|
681 _minx = Math.min.apply(Math, _xx), |
|
682 _miny = Math.min.apply(Math, _yy), |
|
683 _maxx = Math.max.apply(Math, _xx), |
|
684 _maxy = Math.max.apply(Math, _yy); |
|
685 var _scale = Math.min( |
|
686 this.scale * .8 * this.renkan.options.minimap_width / paper.view.bounds.width, |
|
687 this.scale * .8 * this.renkan.options.minimap_height / paper.view.bounds.height, |
|
688 ( this.renkan.options.minimap_width - 2 * this.renkan.options.minimap_padding ) / (_maxx - _minx), |
|
689 ( this.renkan.options.minimap_height - 2 * this.renkan.options.minimap_padding ) / (_maxy - _miny) |
|
690 ); |
|
691 this.minimap.offset = this.minimap.size.divide(2).subtract(new paper.Point([(_maxx + _minx) / 2, (_maxy + _miny) / 2]).multiply(_scale)); |
|
692 this.minimap.scale = _scale; |
|
693 } |
|
694 if (nodes.length === 1) { |
|
695 this.minimap.scale = .1; |
|
696 this.minimap.offset = this.minimap.size.divide(2).subtract(new paper.Point([nodes.at(0).get("position").x, nodes.at(0).get("position").y]).multiply(this.minimap.scale)); |
|
697 } |
|
698 this.redraw(); |
|
699 }, |
|
700 toPaperCoords: function(_point) { |
|
701 return _point.multiply(this.scale).add(this.offset); |
|
702 }, |
|
703 toMinimapCoords: function(_point) { |
|
704 return _point.multiply(this.minimap.scale).add(this.minimap.offset).add(this.minimap.topleft); |
|
705 }, |
|
706 toModelCoords: function(_point) { |
|
707 return _point.subtract(this.offset).divide(this.scale); |
|
708 }, |
|
709 addRepresentation: function(_type, _model) { |
|
710 var r = requtils.getRenderer()[_type]; |
|
711 var _repr = new r(this, _model); |
|
712 this.representations.push(_repr); |
|
713 return _repr; |
|
714 }, |
|
715 addRepresentations: function(_type, _collection) { |
|
716 var _this = this; |
|
717 _collection.forEach(function(_model) { |
|
718 _this.addRepresentation(_type, _model); |
|
719 }); |
|
720 }, |
|
721 userTemplate: _.template( |
|
722 '<li class="Rk-User"><span class="Rk-UserColor" style="background:<%=background%>;"></span><%=name%></li>' |
|
723 ), |
|
724 redrawUsers: function() { |
|
725 if (!this.renkan.options.show_user_list) { |
|
726 return; |
|
727 } |
|
728 var allUsers = [].concat((this.renkan.project.current_user_list || {}).models || [], (this.renkan.project.get("users") || {}).models || []), |
|
729 ulistHtml = '', |
|
730 $userpanel = this.$.find(".Rk-Users"), |
|
731 $name = $userpanel.find(".Rk-CurrentUser-Name"), |
|
732 $cpitems = $userpanel.find(".Rk-Edit-ColorPicker li"), |
|
733 $colorsquare = $userpanel.find(".Rk-CurrentUser-Color"), |
|
734 _this = this; |
|
735 $name.off("click").text(this.renkan.translate("<unknown user>")); |
|
736 $cpitems.off("mouseleave click"); |
|
737 allUsers.forEach(function(_user) { |
|
738 if (_user.get("_id") === _this.renkan.current_user) { |
|
739 $name.text(_user.get("title")); |
|
740 $colorsquare.css("background", _user.get("color")); |
|
741 if (_this.isEditable()) { |
|
742 |
|
743 if (_this.renkan.options.user_name_editable) { |
|
744 $name.click(function() { |
|
745 var $this = $(this), |
|
746 $input = $('<input>').val(_user.get("title")).blur(function() { |
|
747 _user.set("title", $(this).val()); |
|
748 _this.redrawUsers(); |
|
749 _this.redraw(); |
|
750 }); |
|
751 $this.empty().html($input); |
|
752 $input.select(); |
|
753 }); |
|
754 } |
|
755 |
|
756 if (_this.renkan.options.user_color_editable) { |
|
757 $cpitems.click( |
|
758 function(_e) { |
|
759 _e.preventDefault(); |
|
760 if (_this.isEditable()) { |
|
761 _user.set("color", $(this).attr("data-color")); |
|
762 } |
|
763 $(this).parent().hide(); |
|
764 } |
|
765 ).mouseleave(function() { |
|
766 $colorsquare.css("background", _user.get("color")); |
|
767 }); |
|
768 } |
|
769 } |
|
770 |
|
771 } else { |
|
772 ulistHtml += _this.userTemplate({ |
|
773 name: _user.get("title"), |
|
774 background: _user.get("color") |
|
775 }); |
|
776 } |
|
777 }); |
|
778 $userpanel.find(".Rk-UserList").html(ulistHtml); |
|
779 }, |
|
780 removeRepresentation: function(_representation) { |
|
781 _representation.destroy(); |
|
782 this.representations = _(this.representations).reject( |
|
783 function(_repr) { |
|
784 return _repr == _representation; |
|
785 } |
|
786 ); |
|
787 }, |
|
788 getRepresentationByModel: function(_model) { |
|
789 if (!_model) { |
|
790 return undefined; |
|
791 } |
|
792 return _(this.representations).find(function(_repr) { |
|
793 return _repr.model === _model; |
|
794 }); |
|
795 }, |
|
796 removeRepresentationsOfType: function(_type) { |
|
797 var _representations = _(this.representations).filter(function(_repr) { |
|
798 return _repr.type == _type; |
|
799 }), |
|
800 _this = this; |
|
801 _(_representations).each(function(_repr) { |
|
802 _this.removeRepresentation(_repr); |
|
803 }); |
|
804 }, |
|
805 highlightModel: function(_model) { |
|
806 var _repr = this.getRepresentationByModel(_model); |
|
807 if (_repr) { |
|
808 _repr.highlight(); |
|
809 } |
|
810 }, |
|
811 unhighlightAll: function(_model) { |
|
812 _(this.representations).each(function(_repr) { |
|
813 _repr.unhighlight(); |
|
814 }); |
|
815 }, |
|
816 unselectAll: function(_model) { |
|
817 _(this.representations).each(function(_repr) { |
|
818 _repr.unselect(); |
|
819 }); |
|
820 }, |
|
821 redraw: function() { |
|
822 _(this.representations).each(function(_representation) { |
|
823 _representation.redraw(true); |
|
824 }); |
|
825 if (this.minimap) { |
|
826 this.redrawMiniframe(); |
|
827 } |
|
828 paper.view.draw(); |
|
829 }, |
|
830 addTempEdge: function(_from, _point) { |
|
831 var _tmpEdge = this.addRepresentation("TempEdge",null); |
|
832 _tmpEdge.end_pos = _point; |
|
833 _tmpEdge.from_representation = _from; |
|
834 _tmpEdge.redraw(); |
|
835 this.click_target = _tmpEdge; |
|
836 }, |
|
837 findTarget: function(_hitResult) { |
|
838 if (_hitResult && typeof _hitResult.item.__representation !== "undefined") { |
|
839 var _newTarget = _hitResult.item.__representation; |
|
840 if (this.selected_target !== _hitResult.item.__representation) { |
|
841 if (this.selected_target) { |
|
842 this.selected_target.unselect(_newTarget); |
|
843 } |
|
844 _newTarget.select(this.selected_target); |
|
845 this.selected_target = _newTarget; |
|
846 } |
|
847 } else { |
|
848 if (this.selected_target) { |
|
849 this.selected_target.unselect(); |
|
850 } |
|
851 this.selected_target = null; |
|
852 } |
|
853 }, |
|
854 paperShift: function(_delta) { |
|
855 this.offset = this.offset.add(_delta); |
|
856 this.redraw(); |
|
857 }, |
|
858 onMouseMove: function(_event) { |
|
859 var _off = this.canvas_$.offset(), |
|
860 _point = new paper.Point([ |
|
861 _event.pageX - _off.left, |
|
862 _event.pageY - _off.top |
|
863 ]), |
|
864 _delta = _point.subtract(this.last_point); |
|
865 this.last_point = _point; |
|
866 if (!this.is_dragging && this.mouse_down && _delta.length > Utils._MIN_DRAG_DISTANCE) { |
|
867 this.is_dragging = true; |
|
868 } |
|
869 var _hitResult = paper.project.hitTest(_point); |
|
870 if (this.is_dragging) { |
|
871 if (this.click_target && typeof this.click_target.paperShift === "function") { |
|
872 this.click_target.paperShift(_delta); |
|
873 } else { |
|
874 this.paperShift(_delta); |
|
875 } |
|
876 } else { |
|
877 this.findTarget(_hitResult); |
|
878 } |
|
879 paper.view.draw(); |
|
880 }, |
|
881 onMouseDown: function(_event, _isTouch) { |
|
882 var _off = this.canvas_$.offset(), |
|
883 _point = new paper.Point([ |
|
884 _event.pageX - _off.left, |
|
885 _event.pageY - _off.top |
|
886 ]); |
|
887 this.last_point = _point; |
|
888 this.mouse_down = true; |
|
889 if (!this.click_target || this.click_target.type !== "Temp-edge") { |
|
890 this.removeRepresentationsOfType("editor"); |
|
891 this.is_dragging = false; |
|
892 var _hitResult = paper.project.hitTest(_point); |
|
893 if (_hitResult && typeof _hitResult.item.__representation !== "undefined") { |
|
894 this.click_target = _hitResult.item.__representation; |
|
895 this.click_target.mousedown(_event, _isTouch); |
|
896 } else { |
|
897 this.click_target = null; |
|
898 if (this.isEditable() && this.click_mode === Utils._CLICKMODE_ADDNODE) { |
|
899 var _coords = this.toModelCoords(_point), |
|
900 _data = { |
|
901 id: Utils.getUID('node'), |
|
902 created_by: this.renkan.current_user, |
|
903 position: { |
|
904 x: _coords.x, |
|
905 y: _coords.y |
|
906 } |
|
907 }; |
|
908 _node = this.renkan.project.addNode(_data); |
|
909 this.getRepresentationByModel(_node).openEditor(); |
|
910 } |
|
911 } |
|
912 } |
|
913 if (this.click_mode) { |
|
914 if (this.isEditable() && this.click_mode === Utils._CLICKMODE_STARTEDGE && this.click_target && this.click_target.type === "Node") { |
|
915 this.removeRepresentationsOfType("editor"); |
|
916 this.addTempEdge(this.click_target, _point); |
|
917 this.click_mode = Utils._CLICKMODE_ENDEDGE; |
|
918 this.notif_$.fadeOut(function() { |
|
919 $(this).html(this.renkan.translate("Click on a second node to complete the edge")).fadeIn(); |
|
920 }); |
|
921 } else { |
|
922 this.notif_$.hide(); |
|
923 this.click_mode = false; |
|
924 } |
|
925 } |
|
926 paper.view.draw(); |
|
927 }, |
|
928 onMouseUp: function(_event, _isTouch) { |
|
929 this.mouse_down = false; |
|
930 if (this.click_target) { |
|
931 var _off = this.canvas_$.offset(); |
|
932 this.click_target.mouseup( |
|
933 { |
|
934 point: new paper.Point([ |
|
935 _event.pageX - _off.left, |
|
936 _event.pageY - _off.top |
|
937 ]) |
|
938 }, |
|
939 _isTouch |
|
940 ); |
|
941 } else { |
|
942 this.click_target = null; |
|
943 this.is_dragging = false; |
|
944 if (_isTouch) { |
|
945 this.unselectAll(); |
|
946 } |
|
947 } |
|
948 paper.view.draw(); |
|
949 }, |
|
950 onScroll: function(_event, _scrolldelta) { |
|
951 this.totalScroll += _scrolldelta; |
|
952 if (Math.abs(this.totalScroll) >= 1) { |
|
953 var _off = this.canvas_$.offset(), |
|
954 _delta = new paper.Point([ |
|
955 _event.pageX - _off.left, |
|
956 _event.pageY - _off.top |
|
957 ]).subtract(this.offset).multiply( Math.SQRT2 - 1 ); |
|
958 if (this.totalScroll > 0) { |
|
959 this.setScale( this.scale * Math.SQRT2, this.offset.subtract(_delta) ); |
|
960 } else { |
|
961 this.setScale( this.scale * Math.SQRT1_2, this.offset.add(_delta.divide(Math.SQRT2))); |
|
962 } |
|
963 this.totalScroll = 0; |
|
964 } |
|
965 }, |
|
966 onDoubleClick: function(_event) { |
|
967 if (!this.isEditable()) { |
|
968 return; |
|
969 } |
|
970 var _off = this.canvas_$.offset(), |
|
971 _point = new paper.Point([ |
|
972 _event.pageX - _off.left, |
|
973 _event.pageY - _off.top |
|
974 ]); |
|
975 var _hitResult = paper.project.hitTest(_point); |
|
976 if (this.isEditable() && (!_hitResult || typeof _hitResult.item.__representation === "undefined")) { |
|
977 var _coords = this.toModelCoords(_point), |
|
978 _data = { |
|
979 id: Utils.getUID('node'), |
|
980 created_by: this.renkan.current_user, |
|
981 position: { |
|
982 x: _coords.x, |
|
983 y: _coords.y |
|
984 } |
|
985 }, |
|
986 _node = this.renkan.project.addNode(_data); |
|
987 this.getRepresentationByModel(_node).openEditor(); |
|
988 } |
|
989 paper.view.draw(); |
|
990 }, |
|
991 defaultDropHandler: function(_data) { |
|
992 var newNode = {}; |
|
993 switch(_data["text/x-iri-specific-site"]) { |
|
994 case "twitter": |
|
995 var snippet = $('<div>').html(_data["text/x-iri-selected-html"]), |
|
996 tweetdiv = snippet.find(".tweet"); |
|
997 newNode.title = this.renkan.translate("Tweet by ") + tweetdiv.attr("data-name"); |
|
998 newNode.uri = "http://twitter.com/" + tweetdiv.attr("data-screen-name") + "/status/" + tweetdiv.attr("data-tweet-id"); |
|
999 newNode.image = tweetdiv.find(".avatar").attr("src"); |
|
1000 newNode.description = tweetdiv.find(".js-tweet-text:first").text(); |
|
1001 break; |
|
1002 case "google": |
|
1003 var snippet = $('<div>').html(_data["text/x-iri-selected-html"]); |
|
1004 newNode.title = snippet.find("h3:first").text().trim(); |
|
1005 newNode.uri = snippet.find("h3 a").attr("href"); |
|
1006 newNode.description = snippet.find(".st:first").text().trim(); |
|
1007 break; |
|
1008 case undefined: |
|
1009 default: |
|
1010 if (_data["text/x-iri-source-uri"]) { |
|
1011 newNode.uri = _data["text/x-iri-source-uri"]; |
|
1012 } |
|
1013 if (_data["text/plain"] || _data["text/x-iri-selected-text"]) { |
|
1014 newNode.description = (_data["text/plain"] || _data["text/x-iri-selected-text"]).replace(/[\s\n]+/gm,' ').trim(); |
|
1015 } |
|
1016 if (_data["text/html"] || _data["text/x-iri-selected-html"]) { |
|
1017 var snippet = $('<div>').html(_data["text/html"] || _data["text/x-iri-selected-html"]); |
|
1018 var _svgimgs = snippet.find("image"); |
|
1019 if (_svgimgs.length) { |
|
1020 newNode.image = _svgimgs.attr("xlink:href"); |
|
1021 } |
|
1022 var _svgpaths = snippet.find("path"); |
|
1023 if (_svgpaths.length) { |
|
1024 newNode.clipPath = _svgpaths.attr("d"); |
|
1025 } |
|
1026 var _imgs = snippet.find("img"); |
|
1027 if (_imgs.length) { |
|
1028 newNode.image = _imgs[0].src; |
|
1029 } |
|
1030 var _as = snippet.find("a"); |
|
1031 if (_as.length) { |
|
1032 newNode.uri = _as[0].href; |
|
1033 } |
|
1034 newNode.title = snippet.find("[title]").attr("title") || newNode.title; |
|
1035 newNode.description = snippet.text().replace(/[\s\n]+/gm,' ').trim(); |
|
1036 } |
|
1037 if (_data["text/uri-list"]) { |
|
1038 newNode.uri = _data["text/uri-list"]; |
|
1039 } |
|
1040 if (_data["text/x-moz-url"] && !newNode.title) { |
|
1041 newNode.title = (_data["text/x-moz-url"].split("\n")[1] || "").trim(); |
|
1042 if (newNode.title === newNode.uri) { |
|
1043 newNode.title = false; |
|
1044 } |
|
1045 } |
|
1046 if (_data["text/x-iri-source-title"] && !newNode.title) { |
|
1047 newNode.title = _data["text/x-iri-source-title"]; |
|
1048 } |
|
1049 if (_data["text/html"] || _data["text/x-iri-selected-html"]) { |
|
1050 var snippet = $('<div>').html(_data["text/html"] || _data["text/x-iri-selected-html"]); |
|
1051 newNode.image = snippet.find("[data-image]").attr("data-image") || newNode.image; |
|
1052 newNode.uri = snippet.find("[data-uri]").attr("data-uri") || newNode.uri; |
|
1053 newNode.title = snippet.find("[data-title]").attr("data-title") || newNode.title; |
|
1054 newNode.description = snippet.find("[data-description]").attr("data-description") || newNode.description; |
|
1055 newNode.clipPath = snippet.find("[data-clip-path]").attr("data-clip-path") || newNode.clipPath; |
|
1056 } |
|
1057 } |
|
1058 |
|
1059 if(typeof this.renkan.options.drop_enhancer === "function"){ |
|
1060 newNode = this.renkan.options.drop_enhancer(newNode, _data); |
|
1061 } |
|
1062 return newNode; |
|
1063 |
|
1064 }, |
|
1065 dropData: function(_data, _event) { |
|
1066 if (!this.isEditable()) { |
|
1067 return; |
|
1068 } |
|
1069 if (_data["text/json"] || _data["application/json"]) { |
|
1070 try { |
|
1071 var jsondata = JSON.parse(_data["text/json"] || _data["application/json"]); |
|
1072 _(_data).extend(jsondata); |
|
1073 } |
|
1074 catch(e) {} |
|
1075 } |
|
1076 |
|
1077 var newNode = (typeof this.renkan.options.drop_handler === "undefined")?this.defaultDropHandler(_data):this.renkan.options.drop_handler(_data); |
|
1078 |
|
1079 if (!newNode.title) { |
|
1080 newNode.title = this.renkan.translate("Dragged resource"); |
|
1081 } |
|
1082 var fields = ["title", "description", "uri", "image"]; |
|
1083 for (var i = 0; i < fields.length; i++) { |
|
1084 var f = fields[i]; |
|
1085 if (_data["text/x-iri-" + f] || _data[f]) { |
|
1086 newNode[f] = _data["text/x-iri-" + f] || _data[f]; |
|
1087 } |
|
1088 if (newNode[f] === "none" || newNode[f] === "null") { |
|
1089 newNode[f] = undefined; |
|
1090 } |
|
1091 } |
|
1092 var _off = this.canvas_$.offset(), |
|
1093 _point = new paper.Point([ |
|
1094 _event.pageX - _off.left, |
|
1095 _event.pageY - _off.top |
|
1096 ]), |
|
1097 _coords = this.toModelCoords(_point), |
|
1098 _nodedata = { |
|
1099 id: Utils.getUID('node'), |
|
1100 created_by: this.renkan.current_user, |
|
1101 uri: newNode.uri || "", |
|
1102 title: newNode.title || "", |
|
1103 description: newNode.description || "", |
|
1104 image: newNode.image || "", |
|
1105 color: newNode.color || undefined, |
|
1106 clip_path: newNode.clipPath || undefined, |
|
1107 position: { |
|
1108 x: _coords.x, |
|
1109 y: _coords.y |
|
1110 } |
|
1111 }; |
|
1112 var _node = this.renkan.project.addNode(_nodedata), |
|
1113 _repr = this.getRepresentationByModel(_node); |
|
1114 if (_event.type === "drop") { |
|
1115 _repr.openEditor(); |
|
1116 } |
|
1117 }, |
|
1118 fullScreen: function() { |
|
1119 var _isFull = document.fullScreen || document.mozFullScreen || document.webkitIsFullScreen, |
|
1120 _el = this.renkan.$[0], |
|
1121 _requestMethods = ["requestFullScreen","mozRequestFullScreen","webkitRequestFullScreen"], |
|
1122 _cancelMethods = ["cancelFullScreen","mozCancelFullScreen","webkitCancelFullScreen"]; |
|
1123 if (_isFull) { |
|
1124 for (var i = 0; i < _cancelMethods.length; i++) { |
|
1125 if (typeof document[_cancelMethods[i]] === "function") { |
|
1126 document[_cancelMethods[i]](); |
|
1127 break; |
|
1128 } |
|
1129 } |
|
1130 } else { |
|
1131 for (var i = 0; i < _requestMethods.length; i++) { |
|
1132 if (typeof _el[_requestMethods[i]] === "function") { |
|
1133 _el[_requestMethods[i]](); |
|
1134 break; |
|
1135 } |
|
1136 } |
|
1137 } |
|
1138 }, |
|
1139 zoomOut: function() { |
|
1140 var _newScale = this.scale * Math.SQRT1_2, |
|
1141 _offset = new paper.Point([ |
|
1142 this.canvas_$.width(), |
|
1143 this.canvas_$.height() |
|
1144 ]).multiply( .5 * ( 1 - Math.SQRT1_2 ) ).add(this.offset.multiply( Math.SQRT1_2 )); |
|
1145 this.setScale( _newScale, _offset ); |
|
1146 }, |
|
1147 zoomIn: function() { |
|
1148 var _newScale = this.scale * Math.SQRT2, |
|
1149 _offset = new paper.Point([ |
|
1150 this.canvas_$.width(), |
|
1151 this.canvas_$.height() |
|
1152 ]).multiply( .5 * ( 1 - Math.SQRT2 ) ).add(this.offset.multiply( Math.SQRT2 )); |
|
1153 this.setScale( _newScale, _offset ); |
|
1154 }, |
|
1155 addNodeBtn: function() { |
|
1156 if (this.click_mode === Utils._CLICKMODE_ADDNODE) { |
|
1157 this.click_mode = false; |
|
1158 this.notif_$.hide(); |
|
1159 } else { |
|
1160 this.click_mode = Utils._CLICKMODE_ADDNODE; |
|
1161 this.notif_$.text(this.renkan.translate("Click on the background canvas to add a node")).fadeIn(); |
|
1162 } |
|
1163 return false; |
|
1164 }, |
|
1165 addEdgeBtn: function() { |
|
1166 if (this.click_mode === Utils._CLICKMODE_STARTEDGE || this.click_mode === Utils._CLICKMODE_ENDEDGE) { |
|
1167 this.click_mode = false; |
|
1168 this.notif_$.hide(); |
|
1169 } else { |
|
1170 this.click_mode = Utils._CLICKMODE_STARTEDGE; |
|
1171 this.notif_$.text(this.renkan.translate("Click on a first node to start the edge")).fadeIn(); |
|
1172 } |
|
1173 return false; |
|
1174 }, |
|
1175 foldBins: function() { |
|
1176 var foldBinsButton = this.$.find(".Rk-Fold-Bins"), |
|
1177 bins = this.renkan.$.find(".Rk-Bins"); |
|
1178 if (bins.offset().left < 0) { |
|
1179 bins.animate({left: 0},250); |
|
1180 var _this = this; |
|
1181 this.$.animate({left: 300},250,function() { |
|
1182 var w = _this.$.width(); |
|
1183 paper.view.viewSize = new paper.Size([w, _this.canvas_$.height()]); |
|
1184 }); |
|
1185 foldBinsButton.html("«"); |
|
1186 } else { |
|
1187 bins.animate({left: -300},250); |
|
1188 var _this = this; |
|
1189 this.$.animate({left: 0},250,function() { |
|
1190 var w = _this.$.width(); |
|
1191 paper.view.viewSize = new paper.Size([w, _this.canvas_$.height()]); |
|
1192 }); |
|
1193 foldBinsButton.html("»"); |
|
1194 } |
|
1195 }, |
|
1196 save: function() { }, |
|
1197 open: function() { } |
|
1198 }); |
|
1199 |
|
1200 /* Scene End */ |
|
1201 |
|
1202 return Scene; |
|
1203 |
|
1204 }); |