atome 0.5.7.5.4 → 0.5.7.5.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (99) hide show
  1. checksums.yaml +4 -4
  2. data/documentation/deep learning/basic_infos.txt +5 -0
  3. data/lib/atome/genesis/atomes.rb +12 -0
  4. data/lib/atome/genesis/particles/event.rb +141 -97
  5. data/lib/atome/genesis/particles/identity.rb +2 -1
  6. data/lib/atome/genesis/particles/spatial.rb +25 -0
  7. data/lib/atome/genesis/particles/utility.rb +13 -5
  8. data/lib/atome/utilities/essentials.rb +5 -2
  9. data/lib/atome/version.rb +1 -1
  10. data/lib/molecules/intuition/tools.rb +1 -1
  11. data/lib/molecules/intuition/utilities.rb +3 -0
  12. data/lib/platform_specific/opal/extensions/object.rb +3 -1
  13. data/lib/platform_specific/wasm/atome_wasm_extensions.rb +2 -1
  14. data/lib/renderers/html/event.rb +20 -6
  15. data/lib/renderers/html/html.rb +753 -446
  16. data/lib/renderers/html/identity.rb +33 -6
  17. data/lib/renderers/html/spatial.rb +27 -0
  18. data/lib/renderers/html/utility.rb +4 -0
  19. data/vendor/assets/application/examples/audio.rb +25 -9
  20. data/vendor/assets/application/examples/calendar.rb +186 -0
  21. data/vendor/assets/application/examples/drop.rb +1 -0
  22. data/vendor/assets/application/examples/editor.rb +139 -0
  23. data/vendor/assets/application/examples/inspector.rb +129 -0
  24. data/vendor/assets/application/examples/keyboard.rb +20 -10
  25. data/vendor/assets/application/examples/map.rb +42 -0
  26. data/vendor/assets/application/examples/meteo.rb +8 -0
  27. data/vendor/assets/application/examples/midi.rb +4 -0
  28. data/vendor/assets/application/examples/on_resize.rb +14 -0
  29. data/vendor/assets/application/examples/over.rb +0 -1
  30. data/vendor/assets/application/examples/overflow.rb +20 -5
  31. data/vendor/assets/application/examples/particles.rb +1 -1
  32. data/vendor/assets/application/examples/preset.rb +1 -1
  33. data/vendor/assets/application/examples/resize.rb +11 -0
  34. data/vendor/assets/application/examples/tick.rb +10 -0
  35. data/vendor/assets/application/examples/tools.rb +6 -1
  36. data/vendor/assets/application/examples/touch.rb +2 -14
  37. data/vendor/assets/application/examples/trigger_abstraction.rb +165 -0
  38. data/vendor/assets/application/examples/vr.rb +3 -0
  39. data/vendor/assets/src/css/codemirror.min.css +472 -0
  40. data/vendor/assets/src/css/fonts/tui/icon.eot +0 -0
  41. data/vendor/assets/src/css/fonts/tui/icon.svg +17 -0
  42. data/vendor/assets/src/css/fonts/tui/icon.ttf +0 -0
  43. data/vendor/assets/src/css/fonts/tui/icon.woff +0 -0
  44. data/vendor/assets/src/css/fonts/tui/noto.woff +72 -0
  45. data/vendor/assets/src/css/images/leaflet/layers-2x.png +0 -0
  46. data/vendor/assets/src/css/images/leaflet/layers.png +0 -0
  47. data/vendor/assets/src/css/images/leaflet/marker-icon-2x.png +0 -0
  48. data/vendor/assets/src/css/images/leaflet/marker-icon.png +0 -0
  49. data/vendor/assets/src/css/images/leaflet/marker-shadow.png +0 -0
  50. data/vendor/assets/src/css/images/tui/ic-arrow-line-left.png +0 -0
  51. data/vendor/assets/src/css/images/tui/ic-arrow-line-left@2x.png +0 -0
  52. data/vendor/assets/src/css/images/tui/ic-arrow-line-left@3x.png +0 -0
  53. data/vendor/assets/src/css/images/tui/ic-arrow-line-right.png +0 -0
  54. data/vendor/assets/src/css/images/tui/ic-arrow-line-right@2x.png +0 -0
  55. data/vendor/assets/src/css/images/tui/ic-arrow-line-right@3x.png +0 -0
  56. data/vendor/assets/src/css/images/tui/ic-traveltime-w.png +0 -0
  57. data/vendor/assets/src/css/images/tui/ic-view-day.png +0 -0
  58. data/vendor/assets/src/css/images/tui/ic-view-day@2x.png +0 -0
  59. data/vendor/assets/src/css/images/tui/ic-view-day@3x.png +0 -0
  60. data/vendor/assets/src/css/images/tui/ic-view-month.png +0 -0
  61. data/vendor/assets/src/css/images/tui/ic-view-month@2x.png +0 -0
  62. data/vendor/assets/src/css/images/tui/ic-view-month@3x.png +0 -0
  63. data/vendor/assets/src/css/images/tui/ic-view-week.png +0 -0
  64. data/vendor/assets/src/css/images/tui/ic-view-week@2x.png +0 -0
  65. data/vendor/assets/src/css/images/tui/ic-view-week@3x.png +0 -0
  66. data/vendor/assets/src/css/images/tui/icon.png +0 -0
  67. data/vendor/assets/src/css/images/tui/img-bi.png +0 -0
  68. data/vendor/assets/src/css/images/tui/img-bi@2x.png +0 -0
  69. data/vendor/assets/src/css/images/tui/img-bi@3x.png +0 -0
  70. data/vendor/assets/src/css/leaflet.css +664 -0
  71. data/vendor/assets/src/css/monokai.min.css +127 -0
  72. data/vendor/assets/src/css/style.css +1 -1
  73. data/vendor/assets/src/css/toastui-calendar.min.css +6 -0
  74. data/vendor/assets/src/index.html +12 -1
  75. data/vendor/assets/src/index_opal.html +16 -1
  76. data/vendor/assets/src/index_server.html +11 -1
  77. data/vendor/assets/src/index_server_wasm.html +10 -1
  78. data/vendor/assets/src/index_wasm.html +12 -1
  79. data/vendor/assets/src/js/atome/specific/tauri.js +32 -0
  80. data/vendor/assets/src/js/atome/utilities/importmap.js +9 -0
  81. data/vendor/assets/src/js/atome/utilities/three_module.js +88 -0
  82. data/vendor/assets/src/js/test.js +42 -0
  83. data/vendor/assets/src/js/third_parties/Three/build/three.cjs +54216 -0
  84. data/vendor/assets/src/js/third_parties/Three/build/three.module.min.js +6 -0
  85. data/vendor/assets/src/js/third_parties/Three/build/three.webgpu.min.js +6 -0
  86. data/vendor/assets/src/js/third_parties/Three/jsm/controls/OrbitControls.js +1532 -0
  87. data/vendor/assets/src/js/third_parties/codemirror.min.js +1 -0
  88. data/vendor/assets/src/js/third_parties/leaflet.js +6 -0
  89. data/vendor/assets/src/js/third_parties/leaflet.js.map +1 -0
  90. data/vendor/assets/src/js/third_parties/ruby.min.js +1 -0
  91. data/vendor/assets/src/js/third_parties/toastui-calendar.min.js +9 -0
  92. data/vendor/assets/src/medias/images/puydesancy.jpg +0 -0
  93. data/vendor/assets/src-tauri/Cargo.toml +6 -5
  94. data/vendor/assets/src-tauri/Info.plist +12 -0
  95. data/vendor/assets/src-tauri/src/main.rs +32 -3
  96. data/vendor/assets/src-tauri/src/midi.rs +25 -0
  97. data/vendor/assets/src-tauri/tauri.conf.json +4 -4
  98. metadata +60 -3
  99. data/vendor/assets/src/js/third_parties/three.min.js +0 -6
@@ -4,8 +4,6 @@
4
4
 
5
5
  class HTML
6
6
 
7
-
8
-
9
7
  def self.locate(selector, base_element = JS.global[:document][:body])
10
8
  return base_element if selector.empty?
11
9
 
@@ -41,8 +39,6 @@ class HTML
41
39
  @element
42
40
  end
43
41
 
44
-
45
-
46
42
  def hypertext(params)
47
43
  current_div = JS.global[:document].getElementById(@id.to_s)
48
44
  current_div[:innerHTML] = params
@@ -200,6 +196,26 @@ class HTML
200
196
  hash_result
201
197
  end
202
198
 
199
+ def markup(new_tag, _usr_bloc)
200
+ element_id = @id.to_s
201
+ js_code = <<~JAVASCRIPT
202
+ let element = document.getElementById('#{element_id}');
203
+ if (!element) {
204
+ console.error(`Element with id "${'#{element_id}'}" not found.`);
205
+ return;
206
+ }
207
+ let newElement = document.createElement('#{new_tag}');
208
+
209
+ newElement.style.cssText = element.style.cssText;
210
+ Array.from(element.attributes).forEach(attr => {
211
+ newElement.setAttribute(attr.name, attr.value);
212
+ });
213
+ newElement.innerHTML = element.innerHTML;
214
+ element.parentNode.replaceChild(newElement, element);
215
+ JAVASCRIPT
216
+ JS.eval(js_code)
217
+ end
218
+
203
219
  def hyperedit(params, usr_bloc)
204
220
  html_object = JS.global[:document].getElementById(params.to_s)
205
221
  particles_from_style = {}
@@ -264,6 +280,163 @@ class HTML
264
280
  @websocket.close
265
281
  end
266
282
 
283
+ # map
284
+ def location(loc_found)
285
+ if loc_found[:longitude] && loc_found[:latitude]
286
+ long_f = loc_found[:longitude]
287
+ lat_f = loc_found[:latitude]
288
+ js_code = <<~JAVASCRIPT
289
+ const locatorElement = document.getElementById('#{@id}');
290
+ if (!locatorElement._leaflet_map) {
291
+ const map = L.map('#{@id}').setView([51.505, -0.09], 2); // Centrer initialement sur une position par défaut
292
+ L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
293
+ attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
294
+ }).addTo(map);
295
+ locatorElement._leaflet_map = map;
296
+
297
+ if ('#{long_f}' === 'auto' || '#{lat_f}' === 'auto') {
298
+ function onLocationFound(e) {
299
+ const radius = e.accuracy / 2;
300
+ const locationMarker = L.marker(e.latlng).addTo(map)
301
+ .bindPopup(`You are within ${radius} meters from this point`).openPopup();
302
+
303
+ // Ajouter un ID au marqueur
304
+ locationMarker._icon.id = '#{@id}_locator';
305
+
306
+ locationMarker.on('click', function() {
307
+ alert(`You clicked the location marker at ${e.latlng.toString()}`);
308
+ });
309
+
310
+ const locationCircle = L.circle(e.latlng, radius).addTo(map);
311
+ map.setView(e.latlng, map.getZoom()); // Centrer la carte sur la position trouvée en conservant le zoom actuel
312
+ }
313
+
314
+ function onLocationError(e) {
315
+ console.log(e.message);
316
+ }
317
+
318
+ map.on('locationfound', onLocationFound);
319
+ map.on('locationerror', onLocationError);
320
+
321
+ map.locate({ setView: true }); // Tenter de localiser l'utilisateur sans modifier le zoom
322
+ } else {
323
+ const lat = parseFloat('#{lat_f}');
324
+ const long = parseFloat('#{long_f}');
325
+ map.setView([lat, long], map.getZoom()); // Centrer la carte sur les coordonnées fournies en conservant le zoom actuel
326
+
327
+ const locationMarker = L.marker([lat, long]).addTo(map)
328
+ .bindPopup('This is your point').openPopup();
329
+
330
+ // Ajouter un ID au marqueur
331
+ locationMarker._icon.id = '#{@id}_locator';
332
+
333
+ locationMarker.on('click', function() {
334
+ alert(`You clicked the location marker at [${lat}, ${long}]`);
335
+ });
336
+ }
337
+
338
+ // Ecouter l'événement 'load' de la carte pour rafraîchir l'écran et afficher une alerte
339
+ map.whenReady(function() {
340
+ map.invalidateSize();
341
+ // important setimout re-center the view else the view is incorrect (map.invalidateSize() refresh the view)
342
+ setTimeout(function() {
343
+ map.invalidateSize();
344
+ }, 0001);
345
+ });
346
+ } else {
347
+ const map = locatorElement._leaflet_map;
348
+ if ('#{long_f}' !== 'auto' && '#{lat_f}' !== 'auto') {
349
+ const lat = parseFloat('#{lat_f}');
350
+ const long = parseFloat('#{long_f}');
351
+ map.setView([lat, long], map.getZoom()); // Centrer la carte sur les coordonnées fournies en conservant le zoom actuel
352
+
353
+ const locationMarker = L.marker([lat, long]).addTo(map)
354
+ .bindPopup('This is your point').openPopup();
355
+
356
+ // Ajouter un ID au marqueur
357
+ locationMarker._icon.id = '#{@id}_locator';
358
+
359
+ locationMarker.on('click', function() {
360
+ alert(`You clicked the location marker at [${lat}, ${long}]`);
361
+ });
362
+ }
363
+
364
+ // Ecouter l'événement 'load' de la carte pour rafraîchir l'écran et afficher une alerte
365
+ map.whenReady(function() {
366
+
367
+ setTimeout(function() {
368
+ map.invalidateSize();
369
+ }, 0001);
370
+ });
371
+ }
372
+
373
+ // Ecouter l'événement de redimensionnement de la fenêtre pour réinitialiser la taille de la carte et la vue
374
+ window.addEventListener('resize', () => {
375
+ const map = locatorElement._leaflet_map;
376
+ setTimeout(function() {
377
+ map.invalidateSize();
378
+ }, 0001);
379
+ });
380
+
381
+
382
+
383
+ JAVASCRIPT
384
+ JS.eval(js_code)
385
+
386
+ end
387
+ end
388
+
389
+ def map_zoom(params)
390
+ js_code = <<~JAVASCRIPT
391
+ const locatorElement = document.getElementById('#{@id}');
392
+ const map = locatorElement._leaflet_map;
393
+ map.setZoom(#{params});
394
+ JAVASCRIPT
395
+ JS.eval(js_code)
396
+ end
397
+
398
+ def map_pan(params)
399
+ left_found = params[:left] || 0
400
+ top_found = params[:top] || 0
401
+ js_code = <<~JAVASCRIPT
402
+ const locatorElement = document.getElementById('#{@id}');
403
+ const map = locatorElement._leaflet_map;
404
+ map.panBy([#{left_found}, #{top_found}], { animate: true });
405
+ JAVASCRIPT
406
+ JS.eval(js_code)
407
+ end
408
+
409
+ # meteo
410
+ def meteo_helper(data)
411
+ grab(@id).instance_variable_get('@meteo_code')[:meteo].call(data)
412
+ end
413
+
414
+ def meteo(location)
415
+ js_code = <<~JAVASCRIPT
416
+ const url = 'https://api.openweathermap.org/data/2.5/weather?q=#{location},fr&appid=c21a75b667d6f7abb81f118dcf8d4611&units=metric';
417
+ async function fetchWeather() {
418
+ try {
419
+ let response = await fetch(url);
420
+
421
+ if (!response.ok) {
422
+ throw new Error('Erreur HTTP ! statut : ' + response.status);
423
+ }
424
+
425
+ let data = await response.json();
426
+
427
+
428
+ let jsonString = JSON.stringify(data);
429
+ atomeJsToRuby("grab('#{@id}').html.meteo_helper("+jsonString+")");
430
+ } catch (error) {
431
+ console.log('Error getting meteo : ' + error.message);
432
+ }
433
+ }
434
+
435
+ fetchWeather();
436
+ JAVASCRIPT
437
+ JS.eval(js_code)
438
+ end
439
+
267
440
  def attr(attribute, value)
268
441
  @element.setAttribute(attribute.to_s, value.to_s)
269
442
  self
@@ -290,6 +463,39 @@ class HTML
290
463
  delete(id) unless element_to_delete.inspect == 'null'
291
464
  end
292
465
 
466
+ def editor(id)
467
+ check_double(id)
468
+ editor_id = "#{id}_editor"
469
+ check_double(editor_id)
470
+ markup_found = @original_atome.markup || :textarea
471
+ @element_type = markup_found.to_s
472
+ @element = JS.global[:document].createElement(@element_type)
473
+ JS.global[:document][:body].appendChild(@element)
474
+ add_class('atome')
475
+ id(id)
476
+ self
477
+ end
478
+
479
+ # def editor(id)
480
+ # check_double(id)
481
+ # editor_id = "#{id}_editor"
482
+ # check_double(editor_id)
483
+ # markup_found = @original_atome.markup || :div
484
+ # @element_type = markup_found.to_s
485
+ # @element = JS.global[:document].createElement(@element_type)
486
+ # @element.setAttribute('style', 'font-size: 12px;')
487
+ #
488
+ # JS.global[:document][:body].appendChild(@element)
489
+ # add_class('atome')
490
+ # id(id)
491
+ # textarea = JS.global[:document].createElement('textarea')
492
+ # textarea.setAttribute('id', editor_id)
493
+ # wait 0.1 do
494
+ # @element.appendChild(textarea)
495
+ # end
496
+ # self
497
+ # end
498
+
293
499
  def shape(id)
294
500
  # we remove any element if the id already exist
295
501
  check_double(id)
@@ -373,6 +579,49 @@ class HTML
373
579
  self
374
580
  end
375
581
 
582
+ def vr(id)
583
+ # we remove any element if the id already exist
584
+ check_double(id)
585
+ markup_found = @original_atome.markup || :div
586
+ @element_type = markup_found.to_s
587
+ @element = JS.global[:document].createElement(@element_type)
588
+ JS.global[:document][:body].appendChild(@element)
589
+ add_class('atome')
590
+ self.id(id)
591
+
592
+ self
593
+ end
594
+
595
+ def vr_path(objet_path)
596
+ js_code = <<~JAVASCRIPT
597
+ initWithParam('#{objet_path}', '#{@id}', 'method', 'params');
598
+ JAVASCRIPT
599
+
600
+ JS.eval(js_code)
601
+ # tags = <<~HTML
602
+ # <a-scene embedded>
603
+ # <a-sky src="#{objet_path}" rotation="0 -130 0"></a-sky>
604
+ # <a-text font="kelsonsans" value="Puy de Sancy, France" width="6" position="-2.5 0.25 -1.5" rotation="0 15 0"></a-text>
605
+ # <!-- Hotspot -->
606
+ # <a-sphere id="clickable" color="#FF0000" radius="0.1" position="0 1 -2"
607
+ # event-set__mouseenter="_event: mouseenter; color: green"
608
+ # event-set__mouseleave="_event: mouseleave; color: red"></a-sphere>
609
+ # <!-- Camera with cursor to detect clicks -->
610
+ # </a-scene>
611
+ # HTML
612
+ # @element[:innerHTML] = tags
613
+ #
614
+ # # Ajouter un écouteur d'événement pour le hotspot
615
+ # cursor = JS.global[:document].getElementById('cursor')
616
+ # cursor.addEventListener('click', -> {
617
+ # target = cursor.components.cursor.intersectedEl
618
+ # if target && target.id == 'clickable'
619
+ # alert :yes
620
+ # end
621
+ # })
622
+
623
+ end
624
+
376
625
  def www(id)
377
626
  # we remove any element if the id already exist
378
627
  check_double(id)
@@ -607,7 +856,9 @@ class HTML
607
856
 
608
857
  def delete(id_to_delete)
609
858
  element_to_delete = JS.global[:document].getElementById(id_to_delete.to_s)
610
- element_to_delete.remove if element_to_delete
859
+ return unless element_to_delete.to_s != 'null'
860
+ return unless element_to_delete
861
+ element_to_delete.remove
611
862
  end
612
863
 
613
864
  def append(child_id_found)
@@ -618,7 +869,6 @@ class HTML
618
869
 
619
870
  # events handlers
620
871
  def on(property, _option)
621
- bloc = @original_atome.instance_variable_get('@on_code')[:view_resize]
622
872
  property = property.to_s
623
873
 
624
874
  if property.start_with?('media:')
@@ -628,6 +878,7 @@ class HTML
628
878
  mql = JS.global[:window].matchMedia(media_query)
629
879
 
630
880
  event_handler = ->(event) do
881
+ bloc = @original_atome.instance_variable_get('@on_code')[:view_resize]
631
882
  proc_content = bloc.call({ matches: event[:matches] }) if event_validation(bloc)
632
883
  if proc_content.instance_of? Hash
633
884
  proc_content.each do |k, v|
@@ -640,18 +891,27 @@ class HTML
640
891
  mql.addListener(event_handler)
641
892
 
642
893
  elsif property == 'resize'
643
- event_handler = ->(event) do
644
- width = JS.global[:window][:innerWidth]
645
- height = JS.global[:window][:innerHeight]
646
- proc_content = bloc.call({ width: width, height: height }) if event_validation(bloc)
647
- if proc_content.instance_of? Hash
648
- proc_content.each do |k, v|
649
- @original_atome.send(k, v)
894
+ unless @on_resize_already_set
895
+ event_handler = ->(event) do
896
+ width = JS.global[:window][:innerWidth]
897
+ height = JS.global[:window][:innerHeight]
898
+ blocs = @original_atome.instance_variable_get('@on_code')[:view_resize]
899
+ blocs.each do |bloc|
900
+ proc_content = bloc.call({ width: width, height: height }) if event_validation(bloc)
901
+ if proc_content.instance_of? Hash
902
+ proc_content.each do |k, v|
903
+ @original_atome.send(k, v)
904
+ end
905
+ end
650
906
  end
651
907
  end
652
- end
653
908
 
654
- JS.global[:window].addEventListener('resize', event_handler)
909
+ JS.global[:window].addEventListener('resize', event_handler)
910
+ end
911
+ @on_resize_already_set = true
912
+ elsif property == 'remove'
913
+ alert 'ok'
914
+ @original_atome.instance_variable_get('@on_code')[:view_resize] = []
655
915
  else
656
916
  event_handler = ->(event) do
657
917
  proc_content = bloc.call(event) if event_validation(bloc)
@@ -733,14 +993,13 @@ class HTML
733
993
  end
734
994
  end
735
995
 
736
- def drag_code(params=nil)
737
- #FIXME : this method is an ugly patch when refreshing an atome twice, else it crash
738
- # and lose it's drag
739
- drag_move(params)
740
- end
996
+ # def drag_code(params = nil)
997
+ # # FIXME : this method is an ugly patch when refreshing an atome twice, else it crash
998
+ # # and lose it's drag
999
+ # drag_move(params)
1000
+ # end
741
1001
 
742
1002
  def event(action, variance, option = nil)
743
- # puts " remove 'if option', if unable ti unbind# : #{action} _ #{variance}"
744
1003
  send("#{action}_#{variance}", option)
745
1004
  end
746
1005
 
@@ -749,210 +1008,260 @@ class HTML
749
1008
  @original_atome.top(restricted_y)
750
1009
  end
751
1010
 
752
- def drag_remove(option)
1011
+ def drag_move(_option)
753
1012
 
754
- @draggable = nil
755
- interact = JS.eval("return interact('##{@id}')")
1013
+ unless @drag_move_already_set
1014
+ # the condition below prevent drag accumulation
1015
+ interact = JS.eval("return interact('##{@id}')")
1016
+
1017
+ unless @draggable
1018
+ interact.draggable({
1019
+ drag: true,
1020
+ inertia: { resistance: 12,
1021
+ minSpeed: 200,
1022
+ endSpeed: 100 },
1023
+ })
1024
+ unless @first_drag
1025
+ interact.on('dragmove') do |native_event|
1026
+ drag_moves = @original_atome.instance_variable_get('@drag_code')[:move]
1027
+
1028
+ # the use of Native is only for Opal (look at lib/platform_specific/atome_wasm_extensions.rb for more infos)
1029
+ event = Native(native_event)
1030
+ # we use .call instead of instance_eval because instance_eval bring the current object as context
1031
+ # and it's lead to a problem of context and force the use of grab(:view) when suing atome method such as shape ,
1032
+ # group etc..
1033
+ drag_moves.each do |drag_move|
1034
+ proc_content = drag_move.call(event) if event_validation(drag_move)
1035
+ if proc_content.instance_of? Hash
1036
+ proc_content.each do |k, v|
1037
+ @original_atome.send(k, v)
1038
+ end
1039
+ end
1040
+ end
756
1041
 
757
- case option
758
- when :start
759
- @drag_start = ''
760
- when :end, :stop
761
- @drag_end = ''
762
- when :move
763
- interact.draggable(false)
764
- # interact.unset
765
- @drag_move = nil
766
-
767
- when :locked
768
- @drag_locked = ''
769
- when :restrict
770
- @drag_restrict = ''
771
- else
772
- # to remove all interact event ( touch, drag, scale, ... uncomment below)
773
- @drag_start = ''
774
- @drag_end = ''
775
- @drag_locked = ''
776
- @drag_restrict = ''
777
- @drag_move = nil
778
- interact.draggable(false)
779
- # interact.unset
1042
+ Universe.allow_tool_operations = false
1043
+ dx = event[:dx]
1044
+ dy = event[:dy]
1045
+ x = (@original_atome.left || 0) + dx.to_f
1046
+ y = (@original_atome.top || 0) + dy.to_f
1047
+ @original_atome.left(x)
1048
+ @original_atome.top(y)
1049
+ end
1050
+
1051
+ end
1052
+ end
1053
+ @first_drag = true
1054
+ @draggable = true
1055
+ end
1056
+ @drag_move_already_set = true
1057
+
1058
+ end
1059
+
1060
+ def drag_restrict(option)
1061
+
1062
+ unless @drag_restrict_already_set
1063
+ interact = JS.eval("return interact('##{@id}')")
1064
+ interact.draggable({
1065
+ drag: true,
1066
+ inertia: { resistance: 12,
1067
+ minSpeed: 200,
1068
+ endSpeed: 100 },
1069
+ })
1070
+
1071
+ if option.instance_of? Hash
1072
+ max_left = grab(:view).to_px(:width)
1073
+ max_top = grab(:view).to_px(:height)
1074
+ min_left = 0
1075
+ min_top = 0
1076
+
1077
+ if option[:max]
1078
+ max_left = option[:max][:left] || max_left
1079
+ max_top = option[:max][:top] || max_top
1080
+ else
1081
+ max_left
1082
+ max_top
1083
+ end
1084
+ if option[:min]
1085
+ min_left = option[:min][:left] || min_left
1086
+ min_top = option[:min][:top] || min_top
1087
+ else
1088
+ min_left
1089
+ min_top
1090
+ end
1091
+ else
1092
+ parent_found = grab(option)
1093
+ min_left = parent_found.left
1094
+ min_top = parent_found.top
1095
+ parent_width = parent_found.compute({ particle: :width })[:value]
1096
+ parent_height = parent_found.compute({ particle: :height })[:value]
1097
+ original_width = @original_atome.width
1098
+ original_height = @original_atome.height
1099
+ max_left = min_left + parent_width - original_width
1100
+ max_top = min_top + parent_height - original_height
1101
+ end
1102
+
1103
+ interact.on('dragmove') do |native_event|
1104
+ drag_moves = @original_atome.instance_variable_get('@drag_code')[:restrict]
1105
+
1106
+ # the use of Native is only for Opal (look at lib/platform_specific/atome_wasm_extensions.rb for more infos)
1107
+ event = Native(native_event)
1108
+ # we use .call instead of instance_eval because instance_eval bring the current object as context
1109
+ # and it's lead to a problem of context and force the use of grab(:view) when suing atome method such as shape ,
1110
+ # group etc..
1111
+ drag_moves.each do |drag_move|
1112
+ proc_content = drag_move.call(event) if event_validation(drag_move)
1113
+ if proc_content.instance_of? Hash
1114
+ proc_content.each do |k, v|
1115
+ @original_atome.send(k, v)
1116
+ end
1117
+ end
1118
+ end
1119
+
1120
+ dx = event[:dx]
1121
+ dy = event[:dy]
1122
+ x = (@original_atome.left || 0) + dx.to_f
1123
+ y = (@original_atome.top || 0) + dy.to_f
1124
+ restricted_x = [[x, min_left].max, max_left].min
1125
+ restricted_y = [[y, min_top].max, max_top].min
1126
+ restrict_movement(restricted_x, restricted_y)
1127
+ end
780
1128
  end
1129
+ @drag_restrict_already_set = true
781
1130
 
782
1131
  end
783
1132
 
784
1133
  def drag_start(_option)
785
- interact = JS.eval("return interact('##{@id}')")
786
- @drag_start = @original_atome.instance_variable_get('@drag_code')[:start]
787
- interact.on('dragstart') do |native_event|
788
- event = Native(native_event)
789
- # we use .call instead of instance_eval because instance_eval bring the current object as context
790
- # and it's lead to a problem of context and force the use of grab(:view) when suing atome method such as shape ,
791
- # group etc..
792
- proc_content = @drag_start.call(event) if event_validation(@drag_start)
793
- if proc_content.instance_of? Hash
794
- proc_content.each do |k, v|
795
- @original_atome.send(k, v)
1134
+ unless @drag_start_already_set
1135
+ interact = JS.eval("return interact('##{@id}')")
1136
+ interact.on('dragstart') do |native_event|
1137
+ drag_starts = @original_atome.instance_variable_get('@drag_code')[:start]
1138
+ event = Native(native_event)
1139
+ # we use .call instead of instance_eval because instance_eval bring the current object as context
1140
+ # and it's lead to a problem of context and force the use of grab(:view) when suing atome method such as shape ,
1141
+ # group etc..
1142
+ drag_starts.each do |drag_start|
1143
+ proc_content = drag_start.call(event) if event_validation(drag_start)
1144
+ if proc_content.instance_of? Hash
1145
+ proc_content.each do |k, v|
1146
+ @original_atome.send(k, v)
1147
+ end
1148
+ end
796
1149
  end
797
1150
  end
798
1151
  end
1152
+ @drag_start_already_set = true
799
1153
  end
800
1154
 
801
1155
  def drag_end(_option)
802
- interact = JS.eval("return interact('##{@id}')")
803
- @drag_end = @original_atome.instance_variable_get('@drag_code')[:end]
804
- interact.on('dragend') do |native_event|
805
- event = Native(native_event)
806
- # we use .call instead of instance_eval because instance_eval bring the current object as context
807
- # and it's lead to a problem of context and force the use of grab(:view) when suing atome method such as shape ,
808
- # group etc..
809
- proc_content = @drag_end.call(event) if event_validation(@drag_end)
810
- if proc_content.instance_of? Hash
811
- proc_content.each do |k, v|
812
- @original_atome.send(k, v)
1156
+
1157
+ unless @drag_end_already_set
1158
+ interact = JS.eval("return interact('##{@id}')")
1159
+ interact.on('dragend') do |native_event|
1160
+ drag_ends = @original_atome.instance_variable_get('@drag_code')[:end]
1161
+ event = Native(native_event)
1162
+ # we use .call instead of instance_eval because instance_eval bring the current object as context
1163
+ # and it's lead to a problem of context and force the use of grab(:view) when suing atome method such as shape ,
1164
+ # group etc..
1165
+ drag_ends.each do |drag_end|
1166
+ proc_content = drag_end.call(event) if event_validation(drag_end)
1167
+ if proc_content.instance_of? Hash
1168
+ proc_content.each do |k, v|
1169
+ @original_atome.send(k, v)
1170
+ end
1171
+ end
813
1172
  end
1173
+
814
1174
  end
815
1175
  end
816
- end
1176
+ @drag_end_already_set = true
817
1177
 
818
- def drag_move(_option)
819
- # the condition below prevent drag accumulation
820
- interact = JS.eval("return interact('##{@id}')")
1178
+ end
821
1179
 
822
- unless @draggable
1180
+ def drag_locked(_option)
1181
+ unless @drag_locked_already_set
1182
+ interact = JS.eval("return interact('##{@id}')")
823
1183
  interact.draggable({
824
1184
  drag: true,
825
1185
  inertia: { resistance: 12,
826
1186
  minSpeed: 200,
827
- endSpeed: 100 },
1187
+ endSpeed: 100 }
828
1188
  })
829
- @drag_move = @original_atome.instance_variable_get('@drag_code')[:move]
830
- unless @first_drag
831
- interact.on('dragmove') do |native_event|
832
- # the use of Native is only for Opal (look at lib/platform_specific/atome_wasm_extensions.rb for more infos)
833
- event = Native(native_event)
834
- # we use .call instead of instance_eval because instance_eval bring the current object as context
835
- # and it's lead to a problem of context and force the use of grab(:view) when suing atome method such as shape ,
836
- # group etc..
837
- proc_content = @drag_move.call(event) if event_validation(@drag_move)
1189
+
1190
+ interact.on('dragmove') do |native_event|
1191
+ drag_locks = @original_atome.instance_variable_get('@drag_code')[:locked]
1192
+ # the use of Native is only for Opal (look at lib/platform_specific/atome_wasm_extensions.rb for more infos)
1193
+ event = Native(native_event)
1194
+ # we use .call instead of instance_eval because instance_eval bring the current object as context
1195
+ # and it's lead to a problem of context and force the use of grab(:view) when suing atome method such as shape ,
1196
+ # group etc..
1197
+ drag_locks.each do |drag_lock|
1198
+ proc_content = drag_lock.call(event) if event_validation(drag_lock)
838
1199
  if proc_content.instance_of? Hash
839
1200
  proc_content.each do |k, v|
840
1201
  @original_atome.send(k, v)
841
1202
  end
842
1203
  end
843
- Universe.allow_tool_operations = false
844
- dx = event[:dx]
845
- dy = event[:dy]
846
- x = (@original_atome.left || 0) + dx.to_f
847
- y = (@original_atome.top || 0) + dy.to_f
848
- @original_atome.left(x)
849
- @original_atome.top(y)
850
1204
  end
851
-
852
1205
  end
853
1206
  end
854
- @first_drag = true
855
- @draggable = true
1207
+ @drag_locked_already_set = true
1208
+
856
1209
  end
857
1210
 
858
- def drag_restrict(option)
1211
+ def remove_this_drag(option)
1212
+ @original_atome.instance_variable_get('@drag_code')[option] = [] if @original_atome.instance_variable_get('@drag_code')
1213
+ end
1214
+
1215
+ def drag_remove(_opt)
1216
+
859
1217
  interact = JS.eval("return interact('##{@id}')")
860
- interact.draggable({
861
- drag: true,
862
- inertia: { resistance: 12,
863
- minSpeed: 200,
864
- endSpeed: 100 },
865
- })
866
-
867
- @drag_move = @original_atome.instance_variable_get('@drag_code')[:restrict]
868
- if option.instance_of? Hash
869
- max_left = grab(:view).to_px(:width)
870
- max_top = grab(:view).to_px(:height)
871
- min_left = 0
872
- min_top = 0
873
-
874
- if option[:max]
875
- max_left = option[:max][:left] || max_left
876
- max_top = option[:max][:top] || max_top
877
- else
878
- max_left
879
- max_top
880
- end
881
- if option[:min]
882
- min_left = option[:min][:left] || min_left
883
- min_top = option[:min][:top] || min_top
884
- else
885
- min_left
886
- min_top
887
- end
1218
+ if @original_atome.instance_variable_get('@drag_code')
1219
+ options = @original_atome.instance_variable_get('@drag_code')[:remove]
888
1220
  else
889
- parent_found = grab(option)
890
- min_left = parent_found.left
891
- min_top = parent_found.top
892
- parent_width = parent_found.compute({ particle: :width })[:value]
893
- parent_height = parent_found.compute({ particle: :height })[:value]
894
- original_width = @original_atome.width
895
- original_height = @original_atome.height
896
- max_left = min_left + parent_width - original_width
897
- max_top = min_top + parent_height - original_height
898
- end
899
-
900
- interact.on('dragmove') do |native_event|
901
- # the use of Native is only for Opal (look at lib/platform_specific/atome_wasm_extensions.rb for more infos)
902
- event = Native(native_event)
903
- # we use .call instead of instance_eval because instance_eval bring the current object as context
904
- # and it's lead to a problem of context and force the use of grab(:view) when suing atome method such as shape ,
905
- # group etc..
906
- proc_content = @drag_move.call(event) if event_validation(@drag_move)
907
- if proc_content.instance_of? Hash
908
- proc_content.each do |k, v|
909
- @original_atome.send(k, v)
910
- end
911
- end
912
- dx = event[:dx]
913
- dy = event[:dy]
914
- x = (@original_atome.left || 0) + dx.to_f
915
- y = (@original_atome.top || 0) + dy.to_f
916
- restricted_x = [[x, min_left].max, max_left].min
917
- restricted_y = [[y, min_top].max, max_top].min
918
- restrict_movement(restricted_x, restricted_y)
1221
+ options = false
919
1222
  end
920
- end
921
1223
 
922
- def drag_locked(_option)
923
- interact = JS.eval("return interact('##{@id}')")
924
- interact.draggable({
925
- drag: true,
926
- inertia: { resistance: 12,
927
- minSpeed: 200,
928
- endSpeed: 100 }
929
- })
930
-
931
- @drag_lock = @original_atome.instance_variable_get('@drag_code')[:locked]
932
- interact.on('dragmove') do |native_event|
933
- # the use of Native is only for Opal (look at lib/platform_specific/atome_wasm_extensions.rb for more infos)
934
- event = Native(native_event)
935
- # we use .call instead of instance_eval because instance_eval bring the current object as context
936
- # and it's lead to a problem of context and force the use of grab(:view) when suing atome method such as shape ,
937
- # group etc..
938
- proc_content = @drag_lock.call(event) if event_validation(@drag_lock)
939
- if proc_content.instance_of? Hash
940
- proc_content.each do |k, v|
941
- @original_atome.send(k, v)
1224
+ options.each do |option|
1225
+ if option.instance_of? Array
1226
+ option.each do |opt|
1227
+ remove_this_drag(opt)
942
1228
  end
1229
+ return false
1230
+ end
1231
+ @element[:style][:cursor] = 'default'
1232
+
1233
+ @draggable = nil
1234
+ case option
1235
+ when :start
1236
+ remove_this_drag(:start)
1237
+ when :end, :stop
1238
+ remove_this_drag(:end)
1239
+ remove_this_drag(:stop)
1240
+ when :move
1241
+ remove_this_drag(:move)
1242
+ when :locked
1243
+ remove_this_drag(:locked)
1244
+ when :restrict
1245
+ remove_this_drag(:restrict)
1246
+ else
1247
+ interact.draggable(false)
1248
+
943
1249
  end
944
1250
  end
1251
+
945
1252
  end
946
1253
 
947
- def drop_action(native_event, bloc)
1254
+ def drop_common(method, native_event)
948
1255
  event = Native(native_event)
949
1256
  draggable_element = event[:relatedTarget][:id].to_s
950
1257
  dropzone_element = event[:target][:id].to_s
951
1258
  # we use .call instead of instance_eval because instance_eval bring the current object as context
952
1259
  # and it's lead to a problem of context and force the use of grab(:view) when suing atome method such as shape ,
953
1260
  # group etc..
954
- proc_content = bloc.call({ source: draggable_element, destination: dropzone_element }) if event_validation(bloc)
955
- if proc_content.instance_of? Hash
1261
+ proc_contents = @original_atome.instance_variable_get('@drop_code')[method]
1262
+ proc_contents.each do |proc_content|
1263
+ proc_content = proc_content.call({ source: draggable_element, destination: dropzone_element }) if event_validation(proc_content)
1264
+ return unless proc_content.instance_of? Hash
956
1265
  proc_content.each do |k, v|
957
1266
  @original_atome.send(k, v)
958
1267
  end
@@ -960,97 +1269,108 @@ class HTML
960
1269
  end
961
1270
 
962
1271
  def drop_activate(_option)
963
- interact = JS.eval("return interact('##{@id}')")
964
- @drop_activate = @original_atome.instance_variable_get('@drop_code')[:activate]
965
-
966
- interact.dropzone({
967
- accept: nil, # Accept any element
968
- overlap: 0.75,
969
- ondropactivate: lambda do |native_event|
970
- drop_action(native_event, @drop_activate) if event_validation(@drop_activate)
971
- end
972
- })
973
- end
1272
+ unless @drop_activate_already_set
1273
+ interact = JS.eval("return interact('##{@id}')")
1274
+ interact.dropzone({
1275
+ accept: nil, # Accept any element
1276
+ overlap: 0.75,
1277
+ ondropactivate: lambda do |native_event|
1278
+ drop_common(:activate, native_event)
1279
+ end
1280
+ })
1281
+ end
974
1282
 
975
- def drop_deactivate(_option)
976
- interact = JS.eval("return interact('##{@id}')")
977
- @drop_deactivate = @original_atome.instance_variable_get('@drop_code')[:deactivate]
978
- interact.dropzone({
979
- # accept: nil, # Accept any element
980
- # FIXME : remove because os an opal bug since 1.8 reactivate when opal will be debbuged
981
- ondropdeactivate: lambda do |native_event|
982
- drop_action(native_event, @drop_deactivate) if event_validation(@drop_deactivate)
983
- end
984
- })
1283
+ @drop_activate_already_set = true
985
1284
  end
986
1285
 
987
1286
  def drop_dropped(_option)
988
- @drop_dropped = @original_atome.instance_variable_get('@drop_code')[:dropped]
989
- interact = JS.eval("return interact('##{@id}')")
990
- interact.dropzone({
991
- # accept: nil, # Accept any element
992
- overlap: 0.75,
993
- # FIXME : remove because os an opal bug since 1.8 reactivate when opal will be debbuged
994
- ondrop: lambda do |native_event|
995
- drop_action(native_event, @drop_dropped) if event_validation(@drop_dropped)
996
- end
997
- })
1287
+ unless @drop_dropped_already_set
1288
+ interact = JS.eval("return interact('##{@id}')")
1289
+ interact.dropzone({
1290
+ overlap: 0.75,
1291
+ # FIXME : remove because os an opal bug since 1.8 reactivate when opal will be debbuged
1292
+ ondrop: lambda do |native_event|
1293
+ drop_common(:dropped, native_event)
1294
+ end
1295
+ })
1296
+
1297
+ end
1298
+ @drop_dropped_already_set = true
998
1299
  end
999
1300
 
1000
1301
  def drop_enter(_option)
1001
- interact = JS.eval("return interact('##{@id}')")
1302
+ unless @drop_enter_already_set
1303
+ interact = JS.eval("return interact('##{@id}')")
1304
+ interact.dropzone({
1305
+ overlap: 0.001,
1306
+ # FIXME : remove because os an opal bug since 1.8 reactivate when opal will be debbuged
1307
+ ondragenter: lambda do |native_event|
1308
+ drop_common(:enter, native_event)
1309
+ end
1310
+ })
1311
+ end
1312
+ @drop_enter_already_set = true
1313
+ end
1314
+
1315
+ def drop_leave(_option)
1316
+ unless @drop_leave_already_set
1317
+ interact = JS.eval("return interact('##{@id}')")
1318
+ interact.dropzone({
1319
+ # FIXME : remove because os an opal bug since 1.8 reactivate when opal will be debbuged
1320
+ ondragleave: lambda do |native_event|
1321
+ drop_common(:leave, native_event)
1322
+ end
1323
+ })
1324
+ end
1002
1325
 
1003
- @drop_enter = @original_atome.instance_variable_get('@drop_code')[:enter]
1326
+ @drop_leave_already_set = true
1004
1327
 
1005
- interact.dropzone({
1006
- overlap: 0.001,
1007
- # FIXME : remove because os an opal bug since 1.8 reactivate when opal will be debbuged
1008
- ondragenter: lambda do |native_event|
1009
- drop_action(native_event, @drop_enter) if event_validation(@drop_enter)
1010
- end
1011
- })
1012
1328
  end
1013
1329
 
1014
- def drop_leave(_option)
1015
- interact = JS.eval("return interact('##{@id}')")
1016
- @drop_leave = @original_atome.instance_variable_get('@drop_code')[:leave]
1330
+ def drop_deactivate(_option)
1331
+ unless @drop_remove_already_set
1017
1332
 
1018
- interact.dropzone({
1019
- # FIXME : remove because os an opal bug since 1.8 reactivate when opal will be debbuged
1020
- ondragleave: lambda do |native_event|
1021
- drop_action(native_event, @drop_leave) if event_validation(@drop_enter)
1022
- end
1023
- })
1333
+ interact = JS.eval("return interact('##{@id}')")
1334
+ interact.dropzone({
1335
+ # accept: nil, # Accept any element
1336
+ # FIXME : remove because os an opal bug since 1.8 reactivate when opal will be debbuged
1337
+ ondropdeactivate: lambda do |native_event|
1338
+ drop_common(:deactivate, native_event)
1339
+ end
1340
+ })
1024
1341
 
1342
+ end
1343
+ @drop_remove_already_set = true
1025
1344
  end
1026
1345
 
1027
1346
  def drop_remove(option)
1028
1347
  case option
1029
1348
  when :activate
1030
- @drop_activate = ''
1349
+ @original_atome.instance_variable_get('@drop_code')[:activate] = []
1031
1350
  when :deactivate
1032
- @drop_deactivate = ''
1351
+ @original_atome.instance_variable_get('@drop_code')[:deactivate] = []
1033
1352
  when :dropped
1034
- @drop_dropped = ''
1353
+ @original_atome.instance_variable_get('@drop_code')[:dropped] = []
1035
1354
  when :enter
1036
- @drop_enter = ''
1355
+ @original_atome.instance_variable_get('@drop_code')[:enter] = []
1037
1356
  when :leave
1038
- @drop_leave = ''
1357
+ @original_atome.instance_variable_get('@drop_code')[:leave] = []
1039
1358
  else
1040
- # to remove all interact event ( touch, drag, scale, ... uncomment below)
1041
- # interact.unset
1042
- @drop_activate = ''
1043
- @drop_deactivate = ''
1044
- @drop_dropped = ''
1045
- @drop_enter = ''
1046
- @drop_leave = ''
1047
-
1359
+ drop_remove(:activate)
1360
+ drop_remove(:deactivate)
1361
+ drop_remove(:dropped)
1362
+ drop_remove(:enter)
1363
+ drop_remove(:leave)
1048
1364
  end
1049
1365
 
1050
1366
  end
1051
1367
 
1052
1368
  def resize(params, options)
1053
1369
  interact = JS.eval("return interact('##{@id}')")
1370
+
1371
+ # Désactiver explicitement le déplacement
1372
+ # interact.draggable(false)
1373
+
1054
1374
  if params == :remove
1055
1375
  @resize = ''
1056
1376
  interact.resizable(false)
@@ -1060,6 +1380,7 @@ class HTML
1060
1380
  max_width = options[:max][:width] || 3000
1061
1381
  max_height = options[:max][:height] || 3000
1062
1382
  @resize = @original_atome.instance_variable_get('@resize_code')[:resize]
1383
+
1063
1384
  interact.resizable({
1064
1385
  edges: { left: true, right: true, top: true, bottom: true },
1065
1386
  inertia: true,
@@ -1067,12 +1388,8 @@ class HTML
1067
1388
  listeners: {
1068
1389
  move: lambda do |native_event|
1069
1390
  Universe.allow_tool_operations = false
1070
- # if @resize.is_a?(Proc)
1391
+
1071
1392
  event = Native(native_event)
1072
- # we use .call instead of instance_eval because instance_eval bring the current object as context
1073
- # and it's lead to a problem of context and force the use of grab(:view) when suing atome method such as shape ,
1074
- # group etc..
1075
- # @resize.call(event) if event_validation(@resize)
1076
1393
  proc_content = @resize.call(event) if event_validation(@resize)
1077
1394
  if proc_content.instance_of? Hash
1078
1395
  proc_content.each do |k, v|
@@ -1084,18 +1401,19 @@ class HTML
1084
1401
  y = (@element[:offsetTop].to_i || 0)
1085
1402
  width = event[:rect][:width]
1086
1403
  height = event[:rect][:height]
1404
+
1087
1405
  # Translate when resizing from any corner
1088
1406
  x += event[:deltaRect][:left].to_f
1089
1407
  y += event[:deltaRect][:top].to_f
1408
+
1090
1409
  @original_atome.width width.to_i if width.to_i.between?(min_width, max_width)
1091
1410
  @original_atome.height height.to_i if height.to_i.between?(min_height, max_height)
1092
1411
  @original_atome.left(x)
1093
1412
  @original_atome.top(y)
1094
- end
1095
- # end
1413
+ end,
1096
1414
  },
1097
-
1098
1415
  })
1416
+
1099
1417
  end
1100
1418
 
1101
1419
  end
@@ -1121,87 +1439,112 @@ class HTML
1121
1439
  end
1122
1440
 
1123
1441
  def over_over(_option)
1124
- interact = JS.eval("return interact('##{@id}')")
1125
- @over_over = @original_atome.over_code[:over]
1126
- interact.on('mouseover') do |native_event|
1127
- JS.global[:myRubyMouseOverCallback] = Proc.new { @original_atome.over_code[:over].call }
1442
+ return if @over_over_already_set
1443
+ @element.addEventListener('mouseover') do |native_event|
1444
+ over_options = @original_atome.instance_variable_get('@over_code')[:flyover]
1128
1445
  event = Native(native_event)
1129
- # we use .call instead of instance_eval because instance_eval bring the current object as context
1130
- # and it's lead to a problem of context and force the use of grab(:view) when suing atome method such as shape ,
1131
- # group etc..
1132
-
1133
- proc_content = @over_over.call(event) if event_validation(@over_over)
1134
- if proc_content.instance_of? Hash
1135
- proc_content.each do |k, v|
1136
- @original_atome.send(k, v)
1446
+ over_options.each do |over_option|
1447
+ proc_content = over_option.call(event) if event_validation(over_option)
1448
+ if proc_content.instance_of? Hash
1449
+ proc_content.each do |k, v|
1450
+ @original_atome.send(k, v)
1451
+ end
1137
1452
  end
1138
1453
  end
1139
1454
  end
1455
+ @over_over_already_set = true
1456
+ # unless @over_over_already_set
1457
+ # interact = JS.eval("return interact('##{@id}')")
1458
+ # over_overs = @original_atome.instance_variable_get('@over_code')[:flyover]
1459
+ # # return unless over_overs
1460
+ # over_overs.each do |over_over|
1461
+ # interact.on('mouseover') do |native_event|
1462
+ # over_over_event = Native(native_event)
1463
+ # # we use .call instead of instance_eval because instance_eval bring the current object as context
1464
+ # # and it's lead to a problem of context and force the use of grab(:view) when suing atome method such as shape ,
1465
+ # # group etc..
1466
+ #
1467
+ # proc_content = over_over.call(over_over_event) if event_validation(over_over)
1468
+ # if proc_content.instance_of? Hash
1469
+ # proc_content.each do |k, v|
1470
+ # @original_atome.send(k, v)
1471
+ # end
1472
+ # end
1473
+ # end
1474
+ # end
1475
+ # end
1476
+ # @over_over_already_set = true
1140
1477
  end
1141
1478
 
1142
1479
  def over_enter(_option)
1143
- @over_enter = @original_atome.instance_variable_get('@over_code')[:enter]
1144
- return unless @over_enter
1145
-
1146
- @over_enter_callback = lambda do |event|
1147
- # we use .call instead of instance_eval because instance_eval bring the current object as context
1148
- # and it's lead to a problem of context and force the use of grab(:view) when suing atome method such as shape ,
1149
- # group etc..
1150
- proc_content = @over_enter.call(event) if event_validation(@over_enter)
1151
- if proc_content.instance_of? Hash
1152
- proc_content.each do |k, v|
1153
- @original_atome.send(k, v)
1480
+ return if @over_enter_already_set
1481
+ @element.addEventListener('mouseenter') do |native_event|
1482
+ over_options = @original_atome.instance_variable_get('@over_code')[:enter]
1483
+ event = Native(native_event)
1484
+ over_options.each do |over_option|
1485
+ proc_content = over_option.call(event) if event_validation(over_option)
1486
+ if proc_content.instance_of? Hash
1487
+ proc_content.each do |k, v|
1488
+ @original_atome.send(k, v)
1489
+ end
1154
1490
  end
1155
1491
  end
1156
1492
  end
1157
- @element.addEventListener('mouseenter', @over_enter_callback)
1493
+ @over_enter_already_set = true
1494
+ # unless @over_enter_already_set
1495
+ # over_enters = @original_atome.instance_variable_get('@over_code')[:enter]
1496
+ # # return unless over_enters
1497
+ #
1498
+ # over_enters.each do |over_enter|
1499
+ # @over_enter_callback = lambda do |event|
1500
+ # # we use .call instead of instance_eval because instance_eval bring the current object as context
1501
+ # # and it's lead to a problem of context and force the use of grab(:view) when suing atome method such as shape ,
1502
+ # # group etc..
1503
+ # proc_content = over_enter.call(event) if event_validation(over_enter)
1504
+ # if proc_content.instance_of? Hash
1505
+ # proc_content.each do |k, v|
1506
+ # @original_atome.send(k, v)
1507
+ # end
1508
+ # end
1509
+ # end
1510
+ # @element.addEventListener('mouseenter', @over_enter_callback)
1511
+ #
1512
+ # end
1513
+ #
1514
+ # end
1515
+ # @over_enter_already_set = true
1158
1516
 
1159
1517
  end
1160
1518
 
1161
1519
  def over_leave(_option)
1162
-
1163
- @over_leave = @original_atome.instance_variable_get('@over_code')[:leave]
1164
- return unless @over_leave
1165
-
1166
- @over_leave_callback = lambda do |event|
1167
-
1168
- # we use .call instead of instance_eval because instance_eval bring the current object as context
1169
- # and it's lead to a problem of context and force the use of grab(:view) when suing atome method such as shape ,
1170
- # group etc..
1171
- proc_content = @over_leave.call(event) if event_validation(@over_leave)
1172
- if proc_content.instance_of? Hash
1173
- proc_content.each do |k, v|
1174
- @original_atome.send(k, v)
1520
+ return if @over_leave_already_set
1521
+ @element.addEventListener('mouseleave') do |native_event|
1522
+ over_leaves = @original_atome.instance_variable_get('@over_code')[:leave]
1523
+ event = Native(native_event)
1524
+ over_leaves.each do |over_leave|
1525
+ proc_content = over_leave.call(event) if event_validation(over_leave)
1526
+ if proc_content.instance_of? Hash
1527
+ proc_content.each do |k, v|
1528
+ @original_atome.send(k, v)
1529
+ end
1175
1530
  end
1176
1531
  end
1177
1532
  end
1178
- @element.addEventListener('mouseleave', @over_leave_callback)
1179
-
1533
+ @over_leave_already_set = true
1180
1534
  end
1181
1535
 
1182
1536
  def over_remove(option)
1183
1537
  case option
1184
1538
  when :enter
1185
- if @over_enter_callback
1186
- # Remove the event listener using the same lambda
1187
- @element.removeEventListener('mouseenter', @over_enter_callback)
1188
- @over_enter_callback = nil
1189
- @over_enter = nil
1190
- end
1539
+ @original_atome.instance_variable_get('@over_code')[:enter] = []
1191
1540
  when :leave
1192
- @element.removeEventListener('mouseleave', @over_leave_callback)
1193
- @over_leave_callback = nil
1194
- @over_leave = nil
1541
+ @original_atome.instance_variable_get('@over_code')[:leave] = []
1195
1542
  when :over
1196
- @over_over = ''
1543
+ @original_atome.instance_variable_get('@over_code')[:flyover] = []
1197
1544
  else
1198
- @element.removeEventListener('mouseenter', @over_enter_callback)
1199
- @over_enter_callback = nil
1200
- @over_enter = nil
1201
- @element.removeEventListener('mouseleave', @over_leave_callback)
1202
- @over_leave_callback = nil
1203
- @over_leave = nil
1204
- @over_over = ''
1545
+ over_remove(:enter)
1546
+ over_remove(:leave)
1547
+ over_remove(:over)
1205
1548
  end
1206
1549
  end
1207
1550
 
@@ -1209,155 +1552,119 @@ class HTML
1209
1552
  action_proc.is_a?(Proc) && (!Universe.edit_mode || @original_atome.tag[:system])
1210
1553
  end
1211
1554
 
1212
- def touch_down(_option)
1213
- @element[:style][:cursor] = 'pointer'
1214
- @touch_down = @original_atome.instance_variable_get('@touch_code')[:down]
1215
- interact = JS.eval("return interact('##{@id}')")
1216
- # unless @touch_removed[:down]
1217
- interact.on('down') do |native_event|
1218
- @touch_down_event = Native(native_event)
1219
- # we use .call instead of instance_eval because instance_eval bring the current object as context
1220
- # and it's lead to a problem of context and force the use of grab(:view) when suing atome method such as shape ,
1221
- # group etc..
1222
- proc_content = @touch_down.call(@touch_down_event) if event_validation(@touch_down)
1223
- if proc_content.instance_of? Hash
1224
- proc_content.each do |k, v|
1225
- @original_atome.send(k, v)
1226
- end
1227
- end
1228
- # end
1229
- # end
1230
- end
1231
- end
1232
-
1233
- def touch_tap(_option)
1234
- @element[:style][:cursor] = 'pointer'
1235
- interact = JS.eval("return interact('##{@id}')")
1236
- @touch_tap = @original_atome.instance_variable_get('@touch_code')[:tap]
1237
- # unless @touch_removed[:tap]
1238
- interact.on('tap') do |native_event|
1239
-
1240
- @touch_tap_event = Native(native_event)
1241
- # we use .call instead of instance_eval because instance_eval bring the current object as context
1242
- # and it's lead to a problem of context and force the use of grab(:view) when suing atome method such as shape ,
1243
- # group etc..
1244
- proc_content = @touch_tap.call(@touch_tap_event) if event_validation(@touch_tap)
1245
- if proc_content.instance_of? Hash
1246
- proc_content.each do |k, v|
1247
- # alert "(#{@original_atome.id}, #{k}, #{v}, #{_option})"
1248
- @original_atome.send(k, v)
1249
- end
1250
- end
1251
- end
1252
- # end
1253
- end
1555
+ def setup_touch_event(event_type, _option)
1556
+ instance_variable = "@touch_#{event_type}_already_set"
1557
+ unless instance_variable_get(instance_variable)
1558
+ @element[:style][:cursor] = 'pointer'
1559
+ interact = JS.eval("return interact('##{@id}')")
1560
+ interact.on(event_type) do |native_event|
1561
+ touch_event = Native(native_event)
1562
+ touch_needed = @original_atome.instance_variable_get('@touch_code')[event_type.to_sym]
1254
1563
 
1255
- def touch_up(_option)
1256
- @element[:style][:cursor] = 'pointer'
1257
- interact = JS.eval("return interact('##{@id}')")
1258
- @touch_up = @original_atome.instance_variable_get('@touch_code')[:up]
1259
- # unless @touch_removed[:up]
1260
- interact.on('up') do |native_event|
1261
- @touch_up_event = Native(native_event)
1262
- # we use .call instead of instance_eval because instance_eval bring the current object as context
1263
- # and it's lead to a problem of context and force the use of grab(:view) when suing atome method such as shape ,
1264
- # group etc..
1265
- proc_content = @touch_up.call(@touch_up_event) if event_validation(@touch_up)
1266
- if proc_content.instance_of? Hash
1267
- proc_content.each do |k, v|
1268
- @original_atome.send(k, v)
1269
- end
1270
- end
1271
- end
1272
- end
1273
-
1274
- def touch_double(_option)
1275
- @element[:style][:cursor] = 'pointer'
1276
- interact = JS.eval("return interact('##{@id}')")
1277
- @touch_double = @original_atome.instance_variable_get('@touch_code')[:double]
1278
- # unless @touch_removed[:double]
1279
- interact.on('doubletap') do |native_event|
1280
- @touch_double_event = Native(native_event)
1281
- # we use .call instead of instance_eval because instance_eval bring the current object as context
1282
- # and it's lead to a problem of context and force the use of grab(:view) when suing atome method such as shape ,
1283
- # group etc..
1284
- proc_content = @touch_double.call(@touch_double_event) if event_validation(@touch_double)
1285
- if proc_content.instance_of? Hash
1286
- proc_content.each do |k, v|
1287
- @original_atome.send(k, v)
1564
+ touch_needed.each do |proc_found|
1565
+ proc_content = proc_found.call(touch_event) if event_validation(proc_found)
1566
+ if proc_content.instance_of? Hash
1567
+ proc_content.each do |k, v|
1568
+ @original_atome.send(k, v)
1569
+ end
1570
+ end
1288
1571
  end
1289
1572
  end
1290
1573
  end
1291
-
1292
- end
1293
-
1294
- def touch_long(_option)
1295
- @element[:style][:cursor] = 'pointer'
1296
- @touch_long = @original_atome.instance_variable_get('@touch_code')[:long]
1297
- interact = JS.eval("return interact('##{@id}')")
1298
- # unless @touch_removed[:long]
1299
- interact.on('hold') do |native_event|
1300
- @touch_long_event = Native(native_event)
1301
- # we use .call instead of instance_eval because instance_eval bring the current object as context
1302
- # and it's lead to a problem of context and force the use of grab(:view) when suing atome method such as shape ,
1303
- # group etc..
1304
- proc_content = @touch_long.call(@touch_long_event) if event_validation(@touch_long)
1305
- if proc_content.instance_of? Hash
1306
- proc_content.each do |k, v|
1307
- @original_atome.send(k, v)
1308
- end
1309
- end
1574
+ instance_variable_set(instance_variable, true)
1575
+ end
1576
+
1577
+ def touch_down(option)
1578
+ setup_touch_event('down', option)
1579
+ end
1580
+
1581
+ def touch_up(option)
1582
+ setup_touch_event('up', option)
1583
+ end
1584
+
1585
+ def touch_tap(option)
1586
+ setup_touch_event('tap', option)
1587
+ end
1588
+
1589
+ def touch_double(option)
1590
+ setup_touch_event('doubletap', option)
1591
+ end
1592
+
1593
+ def touch_long(option)
1594
+ setup_touch_event('hold', option)
1595
+ end
1596
+
1597
+ # def touch_double(_option)
1598
+ # @element[:style][:cursor] = 'pointer'
1599
+ # interact = JS.eval("return interact('##{@id}')")
1600
+ # @touch_double = @original_atome.instance_variable_get('@touch_code')[:double]
1601
+ # # unless @touch_removed[:double]
1602
+ # interact.on('doubletap') do |native_event|
1603
+ # # we use an instance variable below instead of a local variable to be able to kill the event
1604
+ # @touch_double_event = Native(native_event)
1605
+ # # we use .call instead of instance_eval because instance_eval bring the current object as context
1606
+ # # and it's lead to a problem of context and force the use of grab(:view) when suing atome method such as shape ,
1607
+ # # group etc..
1608
+ # proc_content = @touch_double.call(@touch_double_event) if event_validation(@touch_double)
1609
+ # if proc_content.instance_of? Hash
1610
+ # proc_content.each do |k, v|
1611
+ # @original_atome.send(k, v)
1612
+ # end
1613
+ # end
1614
+ # end
1615
+ #
1616
+ # end
1617
+
1618
+ # def touch_long(_option)
1619
+ # @element[:style][:cursor] = 'pointer'
1620
+ # @touch_long = @original_atome.instance_variable_get('@touch_code')[:long]
1621
+ # interact = JS.eval("return interact('##{@id}')")
1622
+ # # unless @touch_removed[:long]
1623
+ # interact.on('hold') do |native_event|
1624
+ # @touch_long_event = Native(native_event)
1625
+ # # we use .call instead of instance_eval because instance_eval bring the current object as context
1626
+ # # and it's lead to a problem of context and force the use of grab(:view) when suing atome method such as shape ,
1627
+ # # group etc..
1628
+ # proc_content = @touch_long.call(@touch_long_event) if event_validation(@touch_long)
1629
+ # if proc_content.instance_of? Hash
1630
+ # proc_content.each do |k, v|
1631
+ # @original_atome.send(k, v)
1632
+ # end
1633
+ # end
1634
+ # end
1635
+ # end
1636
+ def remove_this_touch(option)
1637
+ @original_atome.instance_variable_get('@touch_code')[option] = [] if @original_atome.instance_variable_get('@touch_code')
1638
+ end
1639
+
1640
+ def touch_remove(_opt)
1641
+ if @original_atome.instance_variable_get('@touch_code')
1642
+ option = @original_atome.instance_variable_get('@touch_code')[:remove]
1643
+ else
1644
+ option = false
1310
1645
  end
1311
- end
1312
1646
 
1313
- def touch_remove(option)
1314
1647
  @element[:style][:cursor] = 'default'
1315
1648
  case option
1316
1649
  when :double
1317
- @touch_double = ''
1318
- @touch_removed[:double] = true
1319
- @touch_double_event= nil
1650
+ remove_this_touch(:double)
1320
1651
  when :down
1321
- @touch_down = ''
1322
- @touch_removed[:down] = true
1323
- @touch_down_event= nil
1652
+ remove_this_touch(:down)
1324
1653
  when :long
1325
- @touch_removed[:long] = true
1326
- @touch_long = ''
1327
- @touch_long_event= nil
1654
+ remove_this_touch(:long)
1328
1655
  when :tap
1329
- @touch_removed[:tap] = true
1330
- @touch_tap = ''
1331
- @touch_removed[:touch] = true
1332
- @touch_touch = ''
1333
- @touch_tap_event= nil
1334
-
1656
+ remove_this_touch(:tap)
1335
1657
  when :touch
1336
- @touch_removed[:tap] = true
1337
- @touch_tap = ''
1338
- @touch_removed[:touch] = true
1339
- @touch_touch = ''
1340
- @touch_tap_event= nil
1341
-
1658
+ remove_this_touch(:touch)
1342
1659
  when :up
1343
- @touch_removed[:up] = true
1344
- @touch_up = ''
1345
- @touch_up_event= nil
1660
+ remove_this_touch(:up)
1346
1661
  else
1347
- touch_remove(:double)
1348
- @touch_double_event= nil
1349
-
1350
- touch_remove(:down)
1351
- @touch_down_event= nil
1352
-
1353
- touch_remove(:long)
1354
- @touch_long_event= nil
1355
-
1356
- touch_remove(:tap)
1357
- touch_remove(:touch)
1358
- @touch_tap_event= nil
1359
- touch_remove(:up)
1360
- @touch_up_event= nil
1662
+ remove_this_touch(:double)
1663
+ remove_this_touch(:down)
1664
+ remove_this_touch(:long)
1665
+ remove_this_touch(:touch)
1666
+ remove_this_touch(:double)
1667
+ remove_this_touch(:up)
1361
1668
  end
1362
1669
 
1363
1670
  end
@@ -1740,12 +2047,12 @@ class HTML
1740
2047
 
1741
2048
  apply_centering(@center_options, @parent)
1742
2049
 
1743
- if @center_options[:dynamic]
1744
- event_handler = ->(event) do
1745
- apply_centering(@center_options, @parent)
1746
- end
1747
- JS.global[:window].addEventListener('resize', event_handler)
2050
+ return unless @center_options[:dynamic]
2051
+ event_handler = ->(event) do
2052
+ apply_centering(@center_options, @parent)
1748
2053
  end
2054
+ JS.global[:window].addEventListener('resize', event_handler)
2055
+
1749
2056
  end
1750
2057
 
1751
2058
  def record_audio(params)
@@ -1780,10 +2087,10 @@ class HTML
1780
2087
  @original_atome.left(x_position)
1781
2088
  end
1782
2089
 
1783
- if options[:y]
1784
- y_position = calculate_position(options[:y], parent.to_px(:height), @original_atome.to_px(:height))
1785
- @original_atome.top(y_position)
1786
- end
2090
+ return unless options[:y]
2091
+ y_position = calculate_position(options[:y], parent.to_px(:height), @original_atome.to_px(:height))
2092
+ @original_atome.top(y_position)
2093
+
1787
2094
  end
1788
2095
 
1789
2096
  def calculate_position(option, parent_dimension, self_dimension)