wxruby3-shapes 0.9.0.pre.beta.3 → 0.9.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/INSTALL.md +5 -7
- data/README.md +38 -6
- data/assets/logo.svg +339 -0
- data/assets/logo.xpm +60 -0
- data/assets/screenshot.png +0 -0
- data/assets/social.png +0 -0
- data/bin/wx-shapes +1 -1
- data/lib/wx/shapes/arrow_base.rb +4 -11
- data/lib/wx/shapes/arrows/circle_arrow.rb +22 -11
- data/lib/wx/shapes/arrows/circle_prong_arrow.rb +48 -0
- data/lib/wx/shapes/arrows/cross_bar_arrow.rb +57 -0
- data/lib/wx/shapes/arrows/cross_bar_circle_arrow.rb +56 -0
- data/lib/wx/shapes/arrows/cross_bar_prong_arrow.rb +49 -0
- data/lib/wx/shapes/arrows/crossed_circle.rb +46 -0
- data/lib/wx/shapes/arrows/cup_arrow.rb +65 -0
- data/lib/wx/shapes/arrows/diamond_arrow.rb +8 -13
- data/lib/wx/shapes/arrows/double_cross_bar_arrow.rb +27 -0
- data/lib/wx/shapes/arrows/filled_arrow.rb +60 -0
- data/lib/wx/shapes/arrows/line_arrow.rb +67 -0
- data/lib/wx/shapes/arrows/open_arrow.rb +22 -23
- data/lib/wx/shapes/arrows/prong_arrow.rb +42 -0
- data/lib/wx/shapes/arrows/solid_arrow.rb +21 -35
- data/lib/wx/shapes/arrows/square_arrow.rb +37 -0
- data/lib/wx/shapes/auto_layout.rb +2 -2
- data/lib/wx/shapes/base.rb +1 -1
- data/lib/wx/shapes/canvas_history.rb +20 -0
- data/lib/wx/shapes/connection_point.rb +10 -6
- data/lib/wx/shapes/diagram.rb +98 -78
- data/lib/wx/shapes/events.rb +8 -8
- data/lib/wx/shapes/printout.rb +3 -16
- data/lib/wx/shapes/serializable.rb +2 -436
- data/lib/wx/shapes/serialize/wx.rb +30 -18
- data/lib/wx/shapes/shape.rb +211 -168
- data/lib/wx/shapes/shape_canvas.rb +728 -267
- data/lib/wx/shapes/shape_data_object.rb +99 -18
- data/lib/wx/shapes/shape_handle.rb +18 -11
- data/lib/wx/shapes/shape_list.rb +34 -67
- data/lib/wx/shapes/shapes/bitmap_shape.rb +23 -24
- data/lib/wx/shapes/shapes/box_shape.rb +389 -0
- data/lib/wx/shapes/shapes/circle_shape.rb +19 -22
- data/lib/wx/shapes/shapes/control_shape.rb +77 -41
- data/lib/wx/shapes/shapes/curve_shape.rb +38 -31
- data/lib/wx/shapes/shapes/diamond_shape.rb +7 -17
- data/lib/wx/shapes/shapes/edit_text_shape.rb +6 -9
- data/lib/wx/shapes/shapes/ellipse_shape.rb +12 -15
- data/lib/wx/shapes/shapes/flex_grid_shape.rb +58 -33
- data/lib/wx/shapes/shapes/grid_shape.rb +259 -161
- data/lib/wx/shapes/shapes/line_shape.rb +155 -161
- data/lib/wx/shapes/shapes/manager_shape.rb +77 -0
- data/lib/wx/shapes/shapes/multi_sel_rect.rb +8 -8
- data/lib/wx/shapes/shapes/ortho_shape.rb +31 -36
- data/lib/wx/shapes/shapes/polygon_shape.rb +23 -29
- data/lib/wx/shapes/shapes/rect_shape.rb +95 -53
- data/lib/wx/shapes/shapes/round_ortho_shape.rb +6 -8
- data/lib/wx/shapes/shapes/round_rect_shape.rb +20 -24
- data/lib/wx/shapes/shapes/square_shape.rb +14 -17
- data/lib/wx/shapes/shapes/text_shape.rb +95 -53
- data/lib/wx/shapes/version.rb +1 -1
- data/lib/wx/shapes/wx.rb +16 -7
- data/lib/wx/wx-shapes/cmd/test.rb +1 -1
- data/samples/demo/arrows.json +1 -0
- data/samples/demo/arrows.yaml +793 -0
- data/samples/demo/art/HBox.xpm +22 -0
- data/samples/demo/art/VBox.xpm +22 -0
- data/samples/demo/art/logo.xpm +60 -0
- data/samples/demo/class.json +1 -0
- data/samples/demo/class.yaml +5631 -0
- data/samples/demo/demo.rb +301 -91
- data/samples/demo/dialogs.rb +1405 -0
- data/samples/demo/erd.json +1 -0
- data/samples/demo/erd.yaml +4072 -0
- data/samples/demo/frame_canvas.rb +409 -33
- data/samples/sample1/art/logo.xpm +60 -0
- data/samples/sample1/sample.rb +11 -11
- data/samples/sample2/art/logo.xpm +60 -0
- data/samples/sample2/sample.rb +2 -2
- data/samples/sample2/sample_shape.rb +15 -15
- data/samples/sample3/art/logo.xpm +60 -0
- data/samples/sample3/sample.rb +3 -3
- data/samples/sample4/art/logo.xpm +60 -0
- data/samples/sample4/sample.rb +2 -2
- data/tests/lib/wxapp_runner.rb +4 -0
- data/tests/serializer_tests.rb +8 -441
- data/tests/test_grid_shapes.rb +2 -2
- data/tests/test_serialize_xml.rb +17 -0
- data/tests/test_serialize_yaml.rb +2 -2
- metadata +78 -28
- data/lib/wx/shapes/serialize/core.rb +0 -40
- data/lib/wx/shapes/serialize/id.rb +0 -82
- data/lib/wx/shapes/serializer/json.rb +0 -258
- data/lib/wx/shapes/serializer/yaml.rb +0 -125
- data/samples/demo/art/sample.xpm +0 -251
- data/samples/sample1/art/sample.xpm +0 -251
- data/samples/sample2/art/sample.xpm +0 -251
- data/samples/sample3/art/sample.xpm +0 -251
- data/samples/sample4/art/sample.xpm +0 -251
@@ -50,7 +50,7 @@ module Wx::SF
|
|
50
50
|
# @see Wx::SF::Diagram
|
51
51
|
class ShapeCanvas < Wx::ScrolledWindow
|
52
52
|
|
53
|
-
# Working modes
|
53
|
+
# Working modes
|
54
54
|
class MODE < Wx::Enum
|
55
55
|
# The shape canvas is in ready state (no operation is pending)
|
56
56
|
READY = self.new(0)
|
@@ -192,37 +192,56 @@ module Wx::SF
|
|
192
192
|
|
193
193
|
# Default values
|
194
194
|
module DEFAULT
|
195
|
-
|
196
|
-
|
197
|
-
|
195
|
+
class << self
|
196
|
+
# Default value of Wx::SF::CanvasSettings @background_color data member
|
197
|
+
def background_color; @bgcolor ||= Wx::Colour.new(240, 240, 240); end
|
198
|
+
# Default value of Wx::SF::CanvasSettings @common_hover_color data member
|
199
|
+
def hover_color; @hvrcolor ||= Wx::Colour.new(120, 120, 255); end
|
200
|
+
# Default value of Wx::SF::CanvasSettings @common_border_pen data member
|
201
|
+
def border_pen; @border_pen ||= Wx::BLACK_PEN.dup; end
|
202
|
+
# Default value of Wx::SF::CanvasSettings @common_fill_brush data member
|
203
|
+
def fill_brush; @fill_brush ||= Wx::WHITE_BRUSH.dup; end
|
204
|
+
# Default value of Wx::SF::CanvasSettings @common_line_pen data member
|
205
|
+
def line_pen; @line_pen ||= border_pen; end
|
206
|
+
# Default value of Wx::SF::CanvasSettings @common_arrow_fill data member
|
207
|
+
def arrow_fill; @arrow_fill ||= fill_brush; end
|
208
|
+
# Default value of Wx::SF::CanvasSettings @common_text_color data member
|
209
|
+
def text_color; @text_color ||= Wx::BLACK.dup; end
|
210
|
+
# Default value of Wx::SF::CanvasSettings @common_text_fill data member
|
211
|
+
def text_fill; @text_fill ||= Wx::TRANSPARENT_BRUSH.dup; end
|
212
|
+
# Default value of Wx::SF::CanvasSettings @common_text_border data member
|
213
|
+
def text_border; @text_border ||= Wx::TRANSPARENT_PEN.dup; end
|
214
|
+
# Default value of Wx::SF::CanvasSettings @common_text_font data member
|
215
|
+
def text_font; begin; @text_font = Wx::SWISS_FONT.dup; @text_font.point_size = 12; end unless @text_font; @text_font; end
|
216
|
+
# Default value of Wx::SF::CanvasSettings @common_control_fill data member
|
217
|
+
def control_fill; @ctrl_fill ||= Wx::TRANSPARENT_BRUSH.dup; end
|
218
|
+
# Default value of Wx::SF::CanvasSettings @common_control_border data member
|
219
|
+
def control_border; @ctrl_border ||= Wx::TRANSPARENT_PEN.dup; end
|
220
|
+
# Default value of Wx::SF::CanvasSettings @common_control_mod_fill data member
|
221
|
+
def control_mod_fill; @ctrl_mod_fill ||= Wx::Brush.new(Wx::BLUE, Wx::BrushStyle::BRUSHSTYLE_BDIAGONAL_HATCH); end
|
222
|
+
# Default value of Wx::SF::CanvasSettings @common_control_mod_border data member
|
223
|
+
def control_mod_border; @ctrl_mod_border ||= Wx::Pen.new(Wx::BLUE, 1, Wx::PenStyle::PENSTYLE_SOLID); end
|
224
|
+
# Default value of Wx::SF::CanvasSettings @grid_color data member
|
225
|
+
def grid_color; @gridcolor ||= Wx::Colour.new(200, 200, 200); end
|
226
|
+
# Default value of Wx::SF::CanvasSettings @gradient_from data member
|
227
|
+
def gradient_from; @gradcolor_from ||= Wx::Colour.new(240, 240, 240); end
|
228
|
+
# Default value of Wx::SF::CanvasSettings @gradient_to data member
|
229
|
+
def gradient_to; @gradcolor_to ||= Wx::Colour.new(200, 200, 255); end
|
230
|
+
# Default shadow colour
|
231
|
+
def shadow_color; @shadowcolor ||= Wx::Colour.new(150, 150, 150, 128); end
|
232
|
+
# Default value of Wx::SF::CanvasSettings @shadow_fill data member
|
233
|
+
def shadow_brush; @shadowbrush ||= Wx::Brush.new(shadow_color, Wx::BrushStyle::BRUSHSTYLE_SOLID); end
|
234
|
+
end
|
198
235
|
# Default value of Wx::SF::CanvasSettings @grid_size data member
|
199
|
-
GRIDSIZE =
|
236
|
+
GRIDSIZE = 10
|
200
237
|
# Default value of Wx::SF::CanvasSettings @grid_line_mult data member
|
201
238
|
GRIDLINEMULT = 1
|
202
|
-
# Default value of Wx::SF::CanvasSettings @grid_color data member
|
203
|
-
GRIDCOLOR = Wx::Colour.new(200, 200, 200) if Wx::App.is_main_loop_running
|
204
|
-
Wx.add_delayed_constant(self, :GRIDCOLOR) { Wx::Colour.new(200, 200, 200) }
|
205
239
|
# Default value of Wx::SF::CanvasSettings @grid_style data member
|
206
240
|
GRIDSTYLE = Wx::PenStyle::PENSTYLE_SOLID
|
207
|
-
# Default value of Wx::SF::CanvasSettings @common_hover_color data member
|
208
|
-
HOVERCOLOR = Wx::Colour.new(120, 120, 255) if Wx::App.is_main_loop_running
|
209
|
-
Wx.add_delayed_constant(self, :HOVERCOLOR) { Wx::Colour.new(120, 120, 255) }
|
210
|
-
# Default value of Wx::SF::CanvasSettings @gradient_from data member
|
211
|
-
GRADIENT_FROM = Wx::Colour.new(240, 240, 240) if Wx::App.is_main_loop_running
|
212
|
-
Wx.add_delayed_constant(self, :GRADIENT_FROM) { Wx::Colour.new(240, 240, 240) }
|
213
|
-
# Default value of Wx::SF::CanvasSettings @gradient_to data member
|
214
|
-
GRADIENT_TO = Wx::Colour.new(200, 200, 255) if Wx::App.is_main_loop_running
|
215
|
-
Wx.add_delayed_constant(self, :GRADIENT_TO) { Wx::Colour.new(200, 200, 255) }
|
216
241
|
# Default value of Wx::SF::CanvasSettings @style data member
|
217
242
|
CANVAS_STYLE = STYLE::DEFAULT_CANVAS_STYLE
|
218
243
|
# Default value of Wx::SF::CanvasSettings @shadow_offset data member
|
219
244
|
SHADOWOFFSET = Wx::RealPoint.new(4, 4)
|
220
|
-
# Default shadow colour
|
221
|
-
SHADOWCOLOR = Wx::Colour.new(150, 150, 150, 128) if Wx::App.is_main_loop_running
|
222
|
-
Wx.add_delayed_constant(self, :SHADOWCOLOR) { Wx::Colour.new(150, 150, 150, 128) }
|
223
|
-
# Default value of Wx::SF::CanvasSettings @shadow_fill data member
|
224
|
-
SHADOWBRUSH = Wx::Brush.new(SHADOWCOLOR.call, Wx::BrushStyle::BRUSHSTYLE_SOLID) if Wx::App.is_main_loop_running
|
225
|
-
Wx.add_delayed_constant(self, :SHADOWBRUSH) { Wx::Brush.new(Wx::Colour.new(150, 150, 150, 128), Wx::BrushStyle::BRUSHSTYLE_SOLID) }
|
226
245
|
# Default value of Wx::SF::CanvasSettings @print_h_align data member
|
227
246
|
PRINT_HALIGN = HALIGN::CENTER
|
228
247
|
# Default value of Wx::SF::CanvasSettings @print_v_align data member
|
@@ -318,7 +337,7 @@ module Wx::SF
|
|
318
337
|
end
|
319
338
|
end
|
320
339
|
|
321
|
-
include Serializable
|
340
|
+
include FIRM::Serializable
|
322
341
|
|
323
342
|
property :version_info
|
324
343
|
|
@@ -350,36 +369,68 @@ module Wx::SF
|
|
350
369
|
# Auxiliary serializable class encapsulating the canvas properties.
|
351
370
|
class Settings
|
352
371
|
|
353
|
-
include Serializable
|
372
|
+
include FIRM::Serializable
|
354
373
|
|
355
374
|
include DEFAULT
|
356
375
|
|
357
|
-
property :scale, :min_scale, :max_scale, :background_color,
|
358
|
-
:
|
376
|
+
property :scale, :min_scale, :max_scale, :background_color,
|
377
|
+
:common_hover_color, :common_border_pen, :common_fill_brush, :common_line_pen,
|
378
|
+
:common_arrow_fill, :common_text_color, :common_text_fill, :common_text_border, :common_text_font,
|
379
|
+
:common_control_fill, :common_control_border, :common_control_mod_fill, :common_control_mod_border,
|
380
|
+
:grid_line_mult, :grid_color, :grid_style,
|
359
381
|
:gradient_from, :gradient_to, :style, :shadow_offset, :shadow_fill,
|
360
382
|
:print_h_align, :print_v_align, :print_mode
|
383
|
+
property grid_size: ->(obj, *val) {
|
384
|
+
unless val.empty?
|
385
|
+
obj.grid_size = Wx::Size === val.first ? val.first.x : val.first
|
386
|
+
end
|
387
|
+
obj.grid_size
|
388
|
+
}
|
361
389
|
|
362
390
|
def initialize
|
363
391
|
@scale = 1.0
|
364
392
|
@min_scale = SCALE_MIN
|
365
393
|
@max_scale = SCALE_MAX
|
366
|
-
@background_color =
|
367
|
-
|
368
|
-
|
394
|
+
@background_color = DEFAULT.background_color
|
395
|
+
|
396
|
+
# common shape property
|
397
|
+
@common_hover_color = DEFAULT.hover_color
|
398
|
+
# common rect shape properties
|
399
|
+
@common_border_pen = DEFAULT.border_pen
|
400
|
+
@common_fill_brush = DEFAULT.fill_brush
|
401
|
+
# common line shape property
|
402
|
+
@common_line_pen = DEFAULT.line_pen
|
403
|
+
# common arrow property
|
404
|
+
@common_arrow_fill = DEFAULT.arrow_fill
|
405
|
+
# common text shape properties (fill and border overrule common rect properties)
|
406
|
+
@common_text_color = DEFAULT.text_color
|
407
|
+
@common_text_fill = DEFAULT.text_fill
|
408
|
+
@common_text_border = DEFAULT.text_border
|
409
|
+
@common_text_font = DEFAULT.text_font
|
410
|
+
# common control shape properties
|
411
|
+
@common_control_fill = DEFAULT.control_fill
|
412
|
+
@common_control_border = DEFAULT.control_border
|
413
|
+
@common_control_mod_fill = DEFAULT.control_mod_fill
|
414
|
+
@common_control_mod_border = DEFAULT.control_mod_border
|
415
|
+
|
416
|
+
@grid_size = GRIDSIZE
|
369
417
|
@grid_line_mult = GRIDLINEMULT
|
370
|
-
@grid_color =
|
418
|
+
@grid_color = DEFAULT.grid_color
|
371
419
|
@grid_style = GRIDSTYLE
|
372
|
-
@gradient_from =
|
373
|
-
@gradient_to =
|
420
|
+
@gradient_from = DEFAULT.gradient_from
|
421
|
+
@gradient_to = DEFAULT.gradient_to
|
374
422
|
@style = CANVAS_STYLE
|
375
423
|
@shadow_offset = SHADOWOFFSET.dup
|
376
|
-
@shadow_fill =
|
424
|
+
@shadow_fill = DEFAULT.shadow_brush
|
377
425
|
@print_h_align = PRINT_HALIGN
|
378
426
|
@print_v_align = PRINT_VALIGN
|
379
427
|
@print_mode = PRINT_MODE
|
380
428
|
end
|
381
429
|
|
382
|
-
attr_accessor :scale, :min_scale, :max_scale, :background_color,
|
430
|
+
attr_accessor :scale, :min_scale, :max_scale, :background_color,
|
431
|
+
:common_hover_color, :common_border_pen, :common_fill_brush, :common_line_pen,
|
432
|
+
:common_arrow_fill, :common_text_color, :common_text_fill, :common_text_border, :common_text_font,
|
433
|
+
:common_control_fill, :common_control_border, :common_control_mod_fill, :common_control_mod_border,
|
383
434
|
:grid_size, :grid_line_mult, :grid_color, :grid_style,
|
384
435
|
:gradient_from, :gradient_to, :style, :shadow_offset, :shadow_fill,
|
385
436
|
:print_h_align, :print_v_align, :print_mode
|
@@ -441,7 +492,7 @@ module Wx::SF
|
|
441
492
|
|
442
493
|
save_canvas_state
|
443
494
|
end
|
444
|
-
|
495
|
+
|
445
496
|
# set up event handlers
|
446
497
|
evt_paint :_on_paint
|
447
498
|
evt_erase_background :_on_erase_background
|
@@ -480,7 +531,6 @@ module Wx::SF
|
|
480
531
|
|
481
532
|
# initialize selection rectangle
|
482
533
|
@shp_selection = MultiSelRect.new
|
483
|
-
@shp_selection.send(:set_id, nil)
|
484
534
|
@shp_selection.create_handles
|
485
535
|
@shp_selection.select(true)
|
486
536
|
@shp_selection.show(false)
|
@@ -488,7 +538,6 @@ module Wx::SF
|
|
488
538
|
|
489
539
|
# initialize multi-edit rectangle
|
490
540
|
@shp_multi_edit = MultiSelRect.new
|
491
|
-
@shp_multi_edit.send(:set_id, nil)
|
492
541
|
@shp_multi_edit.create_handles
|
493
542
|
@shp_multi_edit.select(true)
|
494
543
|
@shp_multi_edit.show(false)
|
@@ -523,29 +572,61 @@ module Wx::SF
|
|
523
572
|
# Load serialized canvas content (diagrams).
|
524
573
|
# @overload load_canvas(file)
|
525
574
|
# @param [String] file Full file name
|
575
|
+
# @param [Symbol,nil] format specifies the serialization format to use;
|
576
|
+
# determined from file extension if not specified defaulting to :json for unknown extensions
|
526
577
|
# @return [self]
|
527
578
|
# @overload load_canvas(io)
|
528
579
|
# @param [IO] io IO object
|
580
|
+
# @param [Symbol,nil] format specifies the serialization format to use (by default :json)
|
529
581
|
# @return [self]
|
530
|
-
def load_canvas(io)
|
582
|
+
def load_canvas(io, format: nil)
|
531
583
|
# get IO stream to read from
|
532
|
-
ios = io.is_a?(::String)
|
584
|
+
ios = if io.is_a?(::String)
|
585
|
+
format ||= case File.extname(io)
|
586
|
+
when '.json' then :json
|
587
|
+
when '.yaml', '.yml' then :yaml
|
588
|
+
when '.xml' then :xml
|
589
|
+
else
|
590
|
+
:json
|
591
|
+
end
|
592
|
+
File.open(io, 'r')
|
593
|
+
else
|
594
|
+
format ||= :json
|
595
|
+
io
|
596
|
+
end
|
597
|
+
old_diagram = @diagram
|
598
|
+
old_settings = @settings
|
533
599
|
begin
|
534
|
-
|
535
|
-
|
600
|
+
begin
|
601
|
+
_, @settings, diagram = FIRM.deserialize(ios, format: format)
|
602
|
+
rescue SFException
|
603
|
+
::Kernel.raise
|
604
|
+
rescue ::Exception
|
605
|
+
$stderr.puts "#{$!}\n#{$!.backtrace.join("\n")}\n"
|
606
|
+
::Kernel.raise SFException, "Failed to load canvas: #{$!.message}"
|
607
|
+
ensure
|
608
|
+
ShapeCanvas.reset_compat_loading
|
609
|
+
ios.close if io.is_a?(::String) && ios
|
610
|
+
end
|
611
|
+
set_diagram(diagram)
|
612
|
+
clear_canvas_history
|
613
|
+
save_canvas_state
|
614
|
+
set_scale(@settings.scale)
|
615
|
+
update_virtual_size
|
616
|
+
refresh(false)
|
617
|
+
rescue Exception
|
618
|
+
$stderr.puts "#{$!}\n#{$!.backtrace.join("\n")}\n"
|
619
|
+
# restore previous state
|
620
|
+
@settings = old_settings
|
621
|
+
set_diagram(old_diagram)
|
622
|
+
clear_canvas_history
|
623
|
+
save_canvas_state
|
624
|
+
set_scale(@settings.scale)
|
625
|
+
update_virtual_size
|
626
|
+
refresh(false)
|
627
|
+
# propagate exception
|
536
628
|
::Kernel.raise
|
537
|
-
|
538
|
-
::Kernel.raise SFException, "Failed to load canvas: #{$!.message}"
|
539
|
-
ensure
|
540
|
-
ShapeCanvas.reset_compat_loading
|
541
|
-
ios.close if io.is_a?(::String) && ios
|
542
|
-
end
|
543
|
-
set_diagram(diagram)
|
544
|
-
clear_canvas_history
|
545
|
-
save_canvas_state
|
546
|
-
set_scale(@settings.scale)
|
547
|
-
update_virtual_size
|
548
|
-
refresh(false)
|
629
|
+
end
|
549
630
|
|
550
631
|
@diagram.set_modified(false)
|
551
632
|
|
@@ -556,18 +637,33 @@ module Wx::SF
|
|
556
637
|
# @overload save_canvas(file, compact: true)
|
557
638
|
# @param [String] file Full file name
|
558
639
|
# @param [Boolean] compact specifies whether to write content in compact mode (true) or not (false)
|
640
|
+
# @param [Symbol,nil] format specifies the serialization format to use;
|
641
|
+
# determined from file extension if not specified defaulting to :json for unknown extensions
|
559
642
|
# @return [self]
|
560
643
|
# @overload save_canvas(io, compact: true)
|
561
644
|
# @param [IO] io IO object
|
562
645
|
# @param [Boolean] compact specifies whether to write content in compact mode (true) or not (false)
|
646
|
+
# @param [Symbol,nil] format specifies the serialization format to use (by default :json)
|
563
647
|
# @return [self]
|
564
|
-
def save_canvas(io, compact: true)
|
648
|
+
def save_canvas(io, compact: true, format: nil)
|
565
649
|
return self unless @diagram
|
566
650
|
# get IO stream to write to
|
567
|
-
ios = io.is_a?(::String)
|
651
|
+
ios = if io.is_a?(::String)
|
652
|
+
format ||= case File.extname(io)
|
653
|
+
when '.json' then :json
|
654
|
+
when '.yaml', '.yml' then :yaml
|
655
|
+
when '.xml' then :xml
|
656
|
+
else
|
657
|
+
:json
|
658
|
+
end
|
659
|
+
Tempfile.new(File.basename(io, '.*'))
|
660
|
+
else
|
661
|
+
format ||= :json
|
662
|
+
io
|
663
|
+
end
|
568
664
|
# write canvas data to temp file
|
569
665
|
begin
|
570
|
-
[Version.new, @settings, @diagram].serialize(ios, pretty: !compact)
|
666
|
+
[Version.new, @settings, @diagram].serialize(ios, pretty: !compact, format: format)
|
571
667
|
rescue SFException
|
572
668
|
::Kernel.raise
|
573
669
|
rescue Exception
|
@@ -636,7 +732,7 @@ module Wx::SF
|
|
636
732
|
bmp_bb.width = (bmp_bb.width * scale).to_i
|
637
733
|
bmp_bb.height = (bmp_bb.height * scale).to_i
|
638
734
|
|
639
|
-
bmp_bb.inflate!(@settings.grid_size * scale)
|
735
|
+
bmp_bb.inflate!(Wx::Size.new(@settings.grid_size, @settings.grid_size) * scale)
|
640
736
|
|
641
737
|
outbmp = Wx::Bitmap.new(bmp_bb.width, bmp_bb.height)
|
642
738
|
Wx::MemoryDC.draw_on(outbmp) do |mdc|
|
@@ -681,12 +777,12 @@ module Wx::SF
|
|
681
777
|
nil
|
682
778
|
end
|
683
779
|
|
684
|
-
def _start_interactive_connection(lpos,
|
780
|
+
def _start_interactive_connection(lpos, src_shape, cpt)
|
685
781
|
if @new_line_shape
|
686
782
|
@working_mode = MODE::CREATECONNECTION
|
687
783
|
@new_line_shape.send(:set_line_mode, LineShape::LINEMODE::UNDERCONSTRUCTION)
|
688
784
|
|
689
|
-
@new_line_shape.
|
785
|
+
@new_line_shape.set_src_shape(src_shape)
|
690
786
|
|
691
787
|
# switch on the "under-construction" mode
|
692
788
|
@new_line_shape.send(:set_unfinished_point, lpos)
|
@@ -732,7 +828,7 @@ module Wx::SF
|
|
732
828
|
case args.first
|
733
829
|
when Wx::SF::LineShape
|
734
830
|
shape = args.shift
|
735
|
-
shape_klass = shape.class
|
831
|
+
shape_klass = shape.class
|
736
832
|
if args.first.is_a?(Wx::SF::ConnectionPoint)
|
737
833
|
connection_point = args.shift
|
738
834
|
end
|
@@ -740,7 +836,7 @@ module Wx::SF
|
|
740
836
|
when ::Class
|
741
837
|
shape_info = args.shift
|
742
838
|
pos = args.shift.to_point
|
743
|
-
shape_klass = shape_info
|
839
|
+
shape_klass = shape_info
|
744
840
|
end
|
745
841
|
::Kernel.raise ArgumentError, "Invalid arguments #{args}" unless args.empty?
|
746
842
|
return ERRCODE::INVALID_INPUT unless pos
|
@@ -756,7 +852,7 @@ module Wx::SF
|
|
756
852
|
else
|
757
853
|
@new_line_shape = @diagram.add_shape(shape, nil, Wx::DEFAULT_POSITION, INITIALIZE, DONT_SAVE_STATE)
|
758
854
|
end
|
759
|
-
return _start_interactive_connection(lpos, connection_point.get_parent_shape
|
855
|
+
return _start_interactive_connection(lpos, connection_point.get_parent_shape, connection_point)
|
760
856
|
|
761
857
|
else
|
762
858
|
|
@@ -768,7 +864,7 @@ module Wx::SF
|
|
768
864
|
end
|
769
865
|
|
770
866
|
# start the connection's creation process if possible
|
771
|
-
if shape_under
|
867
|
+
if shape_under && shape_under.is_connection_accepted(shape_klass)
|
772
868
|
if shape && @diagram.contains?(shape)
|
773
869
|
@new_line_shape = shape
|
774
870
|
else
|
@@ -779,7 +875,7 @@ module Wx::SF
|
|
779
875
|
end
|
780
876
|
@new_line_shape = (err == ERRCODE::OK ? shape : nil)
|
781
877
|
end
|
782
|
-
return _start_interactive_connection(lpos, shape_under
|
878
|
+
return _start_interactive_connection(lpos, shape_under, shape_under.get_nearest_connection_point(lpos.to_real))
|
783
879
|
else
|
784
880
|
return ERRCODE::NOT_ACCEPTED
|
785
881
|
end
|
@@ -806,7 +902,7 @@ module Wx::SF
|
|
806
902
|
def select_all
|
807
903
|
return unless @diagram
|
808
904
|
|
809
|
-
shapes = @diagram.
|
905
|
+
shapes = @diagram.get_all_shapes
|
810
906
|
|
811
907
|
unless shapes.empty?
|
812
908
|
shapes.each { |shape| shape.select(true) }
|
@@ -826,7 +922,7 @@ module Wx::SF
|
|
826
922
|
def deselect_all
|
827
923
|
return unless @diagram
|
828
924
|
|
829
|
-
@diagram.
|
925
|
+
@diagram.get_all_shapes.each { |shape| shape.select(false) }
|
830
926
|
|
831
927
|
@shp_multi_edit.show(false)
|
832
928
|
end
|
@@ -835,7 +931,7 @@ module Wx::SF
|
|
835
931
|
def hide_all_handles
|
836
932
|
return unless @diagram
|
837
933
|
|
838
|
-
@diagram.
|
934
|
+
@diagram.get_all_shapes.each { |shape| shape.show_handles(false) }
|
839
935
|
end
|
840
936
|
|
841
937
|
# Repaint the shape canvas.
|
@@ -888,7 +984,7 @@ module Wx::SF
|
|
888
984
|
def show_shadows(show, style)
|
889
985
|
return unless @diagram
|
890
986
|
|
891
|
-
shapes = @diagram.
|
987
|
+
shapes = @diagram.get_all_shapes
|
892
988
|
|
893
989
|
shapes.each do |shape|
|
894
990
|
shape.remove_style(Shape::STYLE::SHOW_SHADOW) if show
|
@@ -979,6 +1075,7 @@ module Wx::SF
|
|
979
1075
|
|
980
1076
|
unless lst_selection.empty?
|
981
1077
|
data_obj = Wx::SF::ShapeDataObject.new(lst_selection)
|
1078
|
+
|
982
1079
|
clipboard.place(data_obj)
|
983
1080
|
|
984
1081
|
restore_prev_positions
|
@@ -1018,15 +1115,14 @@ module Wx::SF
|
|
1018
1115
|
data_obj = Wx::SF::ShapeDataObject.new
|
1019
1116
|
if clipboard.fetch(data_obj)
|
1020
1117
|
|
1021
|
-
|
1022
|
-
new_shapes = Wx::SF::Serializable.deserialize(data_obj.get_data_here)
|
1118
|
+
new_shapes = data_obj.get_as_shapes
|
1023
1119
|
# add new shapes to diagram and remove those that are not accepted
|
1024
1120
|
new_shapes.select! do |shape|
|
1025
1121
|
ERRCODE::OK == @diagram.add_shape(shape, nil, shape.get_relative_position, INITIALIZE, DONT_SAVE_STATE)
|
1026
1122
|
end
|
1027
1123
|
|
1028
1124
|
# verify newly added shapes (may remove shapes from list)
|
1029
|
-
@diagram.send(:
|
1125
|
+
@diagram.send(:on_import, new_shapes)
|
1030
1126
|
|
1031
1127
|
update_virtual_size # update for new shapes
|
1032
1128
|
|
@@ -1082,8 +1178,8 @@ module Wx::SF
|
|
1082
1178
|
return false unless has_style?(STYLE::CLIPBOARD)
|
1083
1179
|
|
1084
1180
|
Wx::Clipboard.open do |clipboard|
|
1085
|
-
return clipboard.supported?(Wx::
|
1086
|
-
end
|
1181
|
+
return clipboard.supported?(Wx::SF::ShapeDataObject::DataFormatID)
|
1182
|
+
end rescue false
|
1087
1183
|
end
|
1088
1184
|
alias :can_paste? :can_paste
|
1089
1185
|
|
@@ -1128,13 +1224,24 @@ module Wx::SF
|
|
1128
1224
|
# @param [String,nil] state to restore
|
1129
1225
|
def restore_canvas_state(state)
|
1130
1226
|
return unless state
|
1131
|
-
set_diagram(
|
1227
|
+
set_diagram(FIRM.deserialize(state))
|
1132
1228
|
update_virtual_size
|
1133
1229
|
@diagram.set_modified
|
1134
1230
|
refresh(false)
|
1135
1231
|
end
|
1136
1232
|
protected :restore_canvas_state
|
1137
1233
|
|
1234
|
+
# Restores current last saved canvas state.
|
1235
|
+
def restore_current_state
|
1236
|
+
return unless has_style?(STYLE::UNDOREDO)
|
1237
|
+
|
1238
|
+
clear_temporaries
|
1239
|
+
|
1240
|
+
restore_canvas_state(@canvas_history.current_state)
|
1241
|
+
@shp_multi_edit.show(false)
|
1242
|
+
end
|
1243
|
+
protected :restore_current_state
|
1244
|
+
|
1138
1245
|
# @!group Print methods
|
1139
1246
|
|
1140
1247
|
# Print current canvas content.
|
@@ -1247,12 +1354,12 @@ module Wx::SF
|
|
1247
1354
|
# @return [Wx::Rect] Device position
|
1248
1355
|
def lp2dp(arg)
|
1249
1356
|
if arg.is_a?(Wx::Rect)
|
1250
|
-
x, y =
|
1357
|
+
x, y = calc_scrolled_position(arg.x, arg.y)
|
1251
1358
|
Wx::Rect.new((x*@settings.scale).to_i, (y*@settings.scale).to_i,
|
1252
1359
|
(arg.width*@settings.scale).to_i, (arg.height*@settings.scale).to_i)
|
1253
1360
|
else
|
1254
1361
|
arg = arg.to_point
|
1255
|
-
x, y =
|
1362
|
+
x, y = calc_scrolled_position(arg.x, arg.y)
|
1256
1363
|
Wx::Point.new((x*@settings.scale).to_i, (y*@settings.scale).to_i)
|
1257
1364
|
end
|
1258
1365
|
end
|
@@ -1281,7 +1388,7 @@ module Wx::SF
|
|
1281
1388
|
top_shape ||= shape
|
1282
1389
|
if shape.selected?
|
1283
1390
|
sel_shape ||= shape
|
1284
|
-
|
1391
|
+
elsif !shape.has_selected_parent?
|
1285
1392
|
unsel_shape ||= shape
|
1286
1393
|
end
|
1287
1394
|
end
|
@@ -1343,7 +1450,7 @@ module Wx::SF
|
|
1343
1450
|
end
|
1344
1451
|
|
1345
1452
|
# ... then test normal handles
|
1346
|
-
@diagram.
|
1453
|
+
@diagram.get_all_shapes.each do |shape|
|
1347
1454
|
# iterate through all shape's handles
|
1348
1455
|
if shape.has_style?(Shape::STYLE::SIZE_CHANGE)
|
1349
1456
|
shape.handles.each do |handle|
|
@@ -1381,7 +1488,7 @@ module Wx::SF
|
|
1381
1488
|
return selection unless @diagram
|
1382
1489
|
|
1383
1490
|
selection.clear
|
1384
|
-
@diagram.
|
1491
|
+
@diagram.get_all_shapes.each do |shape|
|
1385
1492
|
selection << shape if shape.selected?
|
1386
1493
|
end
|
1387
1494
|
selection
|
@@ -1393,7 +1500,7 @@ module Wx::SF
|
|
1393
1500
|
virt_rct = nil
|
1394
1501
|
if @diagram
|
1395
1502
|
# calculate total bounding box (includes all shapes)
|
1396
|
-
@diagram.
|
1503
|
+
@diagram.get_all_shapes.each_with_index do |shape, ix|
|
1397
1504
|
if ix == 0
|
1398
1505
|
virt_rct = shape.get_bounding_box
|
1399
1506
|
else
|
@@ -1407,14 +1514,14 @@ module Wx::SF
|
|
1407
1514
|
# Get bounding box of all selected shapes.
|
1408
1515
|
# @return [Wx::Rect] Selection bounding box
|
1409
1516
|
def get_selection_bb
|
1410
|
-
bb_rct =
|
1517
|
+
bb_rct = nil
|
1411
1518
|
# get selected shapes
|
1412
1519
|
get_selected_shapes.each do |shape|
|
1413
|
-
shape.get_complete_bounding_box(
|
1414
|
-
|
1415
|
-
|
1520
|
+
bb_rct = shape.get_complete_bounding_box(bb_rct,
|
1521
|
+
Shape::BBMODE::SELF | Shape::BBMODE::CHILDREN |
|
1522
|
+
Shape::BBMODE::CONNECTIONS | Shape::BBMODE::SHADOW)
|
1416
1523
|
end
|
1417
|
-
bb_rct
|
1524
|
+
bb_rct || Wx::Rect.new
|
1418
1525
|
end
|
1419
1526
|
|
1420
1527
|
# Align selected shapes in given directions.
|
@@ -1438,7 +1545,7 @@ module Wx::SF
|
|
1438
1545
|
shape_bb = shape.get_bounding_box
|
1439
1546
|
|
1440
1547
|
if cnt == 0
|
1441
|
-
min_pos = pos
|
1548
|
+
min_pos = pos.dup
|
1442
1549
|
max_pos = Wx::RealPoint.new(pos.x + shape_bb.width, pos.y + shape_bb.height)
|
1443
1550
|
else
|
1444
1551
|
min_pos.x = pos.x if pos.x < min_pos.x
|
@@ -1543,14 +1650,18 @@ module Wx::SF
|
|
1543
1650
|
def set_canvas_colour(col)
|
1544
1651
|
@settings.background_color = col
|
1545
1652
|
end
|
1653
|
+
alias :set_canvas_color :set_canvas_colour
|
1546
1654
|
alias :canvas_colour= :set_canvas_colour
|
1655
|
+
alias :canvas_color= :set_canvas_colour
|
1547
1656
|
|
1548
1657
|
# Get canvas background color.
|
1549
1658
|
# @return [Wx::Colour] Background color
|
1550
1659
|
def get_canvas_colour
|
1551
1660
|
@settings.background_color
|
1552
1661
|
end
|
1662
|
+
alias :get_canvas_color :get_canvas_colour
|
1553
1663
|
alias :canvas_colour :get_canvas_colour
|
1664
|
+
alias :canvas_color :get_canvas_colour
|
1554
1665
|
|
1555
1666
|
# Set starting gradient color.
|
1556
1667
|
# @param [Wx::Colour] col Color
|
@@ -1580,17 +1691,18 @@ module Wx::SF
|
|
1580
1691
|
end
|
1581
1692
|
alias :gradient_to :get_gradient_to
|
1582
1693
|
|
1583
|
-
# Get grid size.
|
1584
|
-
# @return [
|
1694
|
+
# Get grid size (px).
|
1695
|
+
# @return [Integer] Grid size
|
1585
1696
|
def get_grid_size
|
1586
1697
|
@settings.grid_size
|
1587
1698
|
end
|
1588
1699
|
alias :grid_size :get_grid_size
|
1589
1700
|
|
1590
|
-
# Set grid size.
|
1591
|
-
# @param [
|
1592
|
-
def set_grid_size(
|
1593
|
-
|
1701
|
+
# Set grid size (px).
|
1702
|
+
# @param [Integer] sz Grid size
|
1703
|
+
def set_grid_size(sz)
|
1704
|
+
raise ArgumentError, 'Grid size must be integer > 0' if sz.to_i <= 0
|
1705
|
+
@settings.grid_size = sz.to_i
|
1594
1706
|
end
|
1595
1707
|
alias :grid_size= :set_grid_size
|
1596
1708
|
|
@@ -1616,14 +1728,18 @@ module Wx::SF
|
|
1616
1728
|
def set_grid_colour(col)
|
1617
1729
|
@settings.grid_color = col
|
1618
1730
|
end
|
1731
|
+
alias :set_grid_color :set_grid_colour
|
1619
1732
|
alias :grid_colour= :set_grid_colour
|
1733
|
+
alias :grid_color= :set_grid_colour
|
1620
1734
|
|
1621
1735
|
# Get grid color.
|
1622
1736
|
# @return [Wx::Colour] Grid color
|
1623
1737
|
def get_grid_colour
|
1624
1738
|
@settings.grid_color
|
1625
1739
|
end
|
1740
|
+
alias :get_grid_color :get_grid_colour
|
1626
1741
|
alias :grid_colour :get_grid_colour
|
1742
|
+
alias :grid_color :get_grid_colour
|
1627
1743
|
|
1628
1744
|
# Set grid line style.
|
1629
1745
|
# @param [Wx::PenStyle] style Line style
|
@@ -1654,9 +1770,19 @@ module Wx::SF
|
|
1654
1770
|
alias :shadow_offset :get_shadow_offset
|
1655
1771
|
|
1656
1772
|
# Set shadow fill (used for shadows of non-text shapes only).
|
1657
|
-
# @
|
1658
|
-
|
1659
|
-
|
1773
|
+
# @overload set_shadow_fill(brush)
|
1774
|
+
# @param [Wx::Brush] brush
|
1775
|
+
# @overload set_shadow_fill(color, style=Wx::BrushStyle::BRUSHSTYLE_SOLID)
|
1776
|
+
# @param [Wx::Colour,Symbol,String] color brush color
|
1777
|
+
# @param [Wx::BrushStyle] style
|
1778
|
+
# @overload set_shadow_fill(stipple_bitmap)
|
1779
|
+
# @param [Wx::Bitmap] stipple_bitmap
|
1780
|
+
def set_shadow_fill(*args)
|
1781
|
+
@settings.shadow_fill = if args.size == 1 && Wx::Brush === args.first
|
1782
|
+
args.first
|
1783
|
+
else
|
1784
|
+
Wx::Brush.new(*args)
|
1785
|
+
end
|
1660
1786
|
end
|
1661
1787
|
alias :shadow_fill= :set_shadow_fill
|
1662
1788
|
|
@@ -1811,23 +1937,304 @@ module Wx::SF
|
|
1811
1937
|
alias :mode :get_mode
|
1812
1938
|
|
1813
1939
|
# Set default hover color.
|
1814
|
-
# @param [Wx::Colour] col Hover color.
|
1940
|
+
# @param [Wx::Colour,Symbol,String] col Hover color.
|
1815
1941
|
def set_hover_colour(col)
|
1816
|
-
|
1817
|
-
|
1818
|
-
@settings.common_hover_color = col
|
1819
|
-
|
1820
|
-
# update Hover color in all existing shapes
|
1821
|
-
@diagram.get_shapes.each { |shape| shape.set_hover_colour(col) }
|
1942
|
+
@settings.common_hover_color = Wx::Colour === col ? col : Wx::Colour.new(col)
|
1822
1943
|
end
|
1944
|
+
alias :set_hover_color :set_hover_colour
|
1823
1945
|
alias :hover_colour= :set_hover_colour
|
1946
|
+
alias :hover_color= :set_hover_colour
|
1824
1947
|
|
1825
1948
|
# Get default hover colour.
|
1826
1949
|
# @return [Wx::Colour] Hover colour
|
1827
1950
|
def get_hover_colour
|
1828
1951
|
@settings.common_hover_color
|
1829
1952
|
end
|
1953
|
+
alias :get_hover_color :get_hover_colour
|
1830
1954
|
alias :hover_colour :get_hover_colour
|
1955
|
+
alias :hover_color :get_hover_colour
|
1956
|
+
|
1957
|
+
# Set default fill brush.
|
1958
|
+
# @overload set_fill_brush(brush)
|
1959
|
+
# @param [Wx::Brush] brush
|
1960
|
+
# @overload set_fill_brush(color, style=Wx::BrushStyle::BRUSHSTYLE_SOLID)
|
1961
|
+
# @param [Wx::Colour,Symbol,String] color brush color
|
1962
|
+
# @param [Wx::BrushStyle] style
|
1963
|
+
# @overload set_fill_brush(stipple_bitmap)
|
1964
|
+
# @param [Wx::Bitmap] stipple_bitmap
|
1965
|
+
def set_fill_brush(*args)
|
1966
|
+
@settings.common_fill_brush = if args.size == 1 && Wx::Brush === args.first
|
1967
|
+
args.first
|
1968
|
+
else
|
1969
|
+
Wx::Brush.new(*args)
|
1970
|
+
end
|
1971
|
+
end
|
1972
|
+
alias :fill_brush= :set_fill_brush
|
1973
|
+
|
1974
|
+
# Get default fill brush.
|
1975
|
+
# @return [Wx::Brush] Fill brush
|
1976
|
+
def get_fill_brush
|
1977
|
+
@settings.common_fill_brush
|
1978
|
+
end
|
1979
|
+
alias :fill_brush :get_fill_brush
|
1980
|
+
|
1981
|
+
# Set default border pen.
|
1982
|
+
# @overload set_border_pen(pen)
|
1983
|
+
# @param [Wx::Pen] pen
|
1984
|
+
# @overload set_border_pen(color, width=1, style=Wx::PenStyle::PENSTYLE_SOLID)
|
1985
|
+
# @param [Wx::Colour,String,Symbol] color
|
1986
|
+
# @param [Integer] width
|
1987
|
+
# @param [Wx::PenStyle] style
|
1988
|
+
def set_border_pen(*args)
|
1989
|
+
@settings.common_border_pen = if args.size == 1 && Wx::Pen === args.first
|
1990
|
+
args.first
|
1991
|
+
else
|
1992
|
+
Wx::Pen.new(*args)
|
1993
|
+
end
|
1994
|
+
end
|
1995
|
+
alias :border_pen= :set_border_pen
|
1996
|
+
|
1997
|
+
# Get default border pen.
|
1998
|
+
# @return [Wx::Pen]
|
1999
|
+
def get_border_pen
|
2000
|
+
@settings.common_border_pen
|
2001
|
+
end
|
2002
|
+
alias :border_pen :get_border_pen
|
2003
|
+
|
2004
|
+
# Set default line pen.
|
2005
|
+
# @overload set_line_pen(pen)
|
2006
|
+
# @param [Wx::Pen] pen
|
2007
|
+
# @overload set_line_pen(color, width=1, style=Wx::PenStyle::PENSTYLE_SOLID)
|
2008
|
+
# @param [Wx::Colour,String,Symbol] color
|
2009
|
+
# @param [Integer] width
|
2010
|
+
# @param [Wx::PenStyle] style
|
2011
|
+
def set_line_pen(*args)
|
2012
|
+
@settings.common_line_pen = if args.size == 1 && Wx::Pen === args.first
|
2013
|
+
args.first
|
2014
|
+
else
|
2015
|
+
Wx::Pen.new(*args)
|
2016
|
+
end
|
2017
|
+
end
|
2018
|
+
alias :line_pen= :set_line_pen
|
2019
|
+
|
2020
|
+
# Get default line pen.
|
2021
|
+
# @return [Wx::Pen]
|
2022
|
+
def get_line_pen
|
2023
|
+
@settings.common_line_pen
|
2024
|
+
end
|
2025
|
+
alias :line_pen :get_line_pen
|
2026
|
+
|
2027
|
+
# Set default arrow fill brush.
|
2028
|
+
# @overload set_arrow_fill(brush)
|
2029
|
+
# @param [Wx::Brush] brush
|
2030
|
+
# @overload set_arrow_fill(color, style=Wx::BrushStyle::BRUSHSTYLE_SOLID)
|
2031
|
+
# @param [Wx::Colour,Symbol,String] color brush color
|
2032
|
+
# @param [Wx::BrushStyle] style
|
2033
|
+
# @overload set_arrow_fill(stipple_bitmap)
|
2034
|
+
# @param [Wx::Bitmap] stipple_bitmap
|
2035
|
+
def set_arrow_fill(*args)
|
2036
|
+
@settings.common_arrow_fill = if args.size == 1 && Wx::Brush === args.first
|
2037
|
+
args.first
|
2038
|
+
else
|
2039
|
+
Wx::Brush.new(*args)
|
2040
|
+
end
|
2041
|
+
end
|
2042
|
+
alias :arrow_fill= :set_arrow_fill
|
2043
|
+
|
2044
|
+
# Get default arrow fill brush.
|
2045
|
+
# @return [Wx::Brush] Fill brush
|
2046
|
+
def get_arrow_fill
|
2047
|
+
@settings.common_arrow_fill
|
2048
|
+
end
|
2049
|
+
alias :arrow_fill :get_arrow_fill
|
2050
|
+
|
2051
|
+
# Set default text color.
|
2052
|
+
# @param [Wx::Colour,Symbol,String] col text color.
|
2053
|
+
def set_text_colour(col)
|
2054
|
+
@settings.common_text_color = Wx::Colour === col ? col : Wx::Colour.new(col)
|
2055
|
+
end
|
2056
|
+
alias :set_text_color= :set_text_colour
|
2057
|
+
alias :text_colour= :set_text_colour
|
2058
|
+
alias :text_color= :set_text_colour
|
2059
|
+
|
2060
|
+
# Get default text colour.
|
2061
|
+
# @return [Wx::Colour] text colour
|
2062
|
+
def get_text_colour
|
2063
|
+
@settings.common_text_color
|
2064
|
+
end
|
2065
|
+
alias :get_text_color :get_text_colour
|
2066
|
+
alias :text_colour :get_text_colour
|
2067
|
+
alias :text_color :get_text_colour
|
2068
|
+
|
2069
|
+
# Set default text fill brush.
|
2070
|
+
# @overload set_text_fill(brush)
|
2071
|
+
# @param [Wx::Brush] brush
|
2072
|
+
# @overload set_text_fill(color, style=Wx::BrushStyle::BRUSHSTYLE_SOLID)
|
2073
|
+
# @param [Wx::Colour,Symbol,String] color brush color
|
2074
|
+
# @param [Wx::BrushStyle] style
|
2075
|
+
# @overload set_text_fill(stipple_bitmap)
|
2076
|
+
# @param [Wx::Bitmap] stipple_bitmap
|
2077
|
+
def set_text_fill(*args)
|
2078
|
+
@settings.common_text_fill = if args.size == 1 && Wx::Brush === args.first
|
2079
|
+
args.first
|
2080
|
+
else
|
2081
|
+
Wx::Brush.new(*args)
|
2082
|
+
end
|
2083
|
+
end
|
2084
|
+
alias :text_fill= :set_text_fill
|
2085
|
+
|
2086
|
+
# Get default text fill brush.
|
2087
|
+
# @return [Wx::Brush] Fill brush
|
2088
|
+
def get_text_fill
|
2089
|
+
@settings.common_text_fill
|
2090
|
+
end
|
2091
|
+
alias :text_fill :get_text_fill
|
2092
|
+
|
2093
|
+
# Set default text border.
|
2094
|
+
# @overload set_text_border(pen)
|
2095
|
+
# @param [Wx::Pen] pen
|
2096
|
+
# @overload set_text_border(color, width=1, style=Wx::PenStyle::PENSTYLE_SOLID)
|
2097
|
+
# @param [Wx::Colour,String,Symbol] color
|
2098
|
+
# @param [Integer] width
|
2099
|
+
# @param [Wx::PenStyle] style
|
2100
|
+
def set_text_border(*args)
|
2101
|
+
@settings.common_text_border = if args.size == 1 && Wx::Pen === args.first
|
2102
|
+
args.first
|
2103
|
+
else
|
2104
|
+
Wx::Pen.new(*args)
|
2105
|
+
end
|
2106
|
+
end
|
2107
|
+
alias :text_border= :set_text_border
|
2108
|
+
|
2109
|
+
# Get default text border.
|
2110
|
+
# @return [Wx::Pen]
|
2111
|
+
def get_text_border
|
2112
|
+
@settings.common_text_border
|
2113
|
+
end
|
2114
|
+
alias :text_border :get_text_border
|
2115
|
+
|
2116
|
+
# Set default text font.
|
2117
|
+
# @overload set_text_font(font)
|
2118
|
+
# @param [Wx::Font] font
|
2119
|
+
# @overload set_text_font(font_info)
|
2120
|
+
# @param [Wx::FontInfo] font_info
|
2121
|
+
# @overload set_text_font(pointSize, family, style, weight, underline=false, faceName=(''), encoding=Wx::FontEncoding::FONTENCODING_DEFAULT)
|
2122
|
+
# @param pointSize [Integer] Size in points. See {Wx::Font#initialize}.
|
2123
|
+
# @param family [Wx::FontFamily] The font family. See {Wx::Font#initialize}.
|
2124
|
+
# @param style [Wx::FontStyle] One of {Wx::FontStyle::FONTSTYLE_NORMAL}, {Wx::FontStyle::FONTSTYLE_SLANT} and {Wx::FontStyle::FONTSTYLE_ITALIC}. See {Wx::Font#initialize}.
|
2125
|
+
# @param weight [Wx::FontWeight] Font weight. One of the {Wx::FontWeight} enumeration values. See {Wx::Font#initialize}.
|
2126
|
+
# @param underline [Boolean] The value can be true or false. See {Wx::Font#initialize}.
|
2127
|
+
# @param faceName [String] An optional string specifying the face name to be used. See {Wx::Font#initialize}.
|
2128
|
+
# @param encoding [Wx::FontEncoding] An encoding which may be one of the enumeration values of {Wx::FontEncoding}. See {Wx::Font#initialize}.
|
2129
|
+
def set_text_font(*args)
|
2130
|
+
@settings.common_text_font = if args.size == 1 && Wx::Font === args.first
|
2131
|
+
args.first
|
2132
|
+
else
|
2133
|
+
Wx::Font.new(*args)
|
2134
|
+
end
|
2135
|
+
end
|
2136
|
+
alias :text_font= :set_text_font
|
2137
|
+
|
2138
|
+
# Get default text font.
|
2139
|
+
# @return [Wx::Font]
|
2140
|
+
def get_text_font
|
2141
|
+
@settings.common_text_font
|
2142
|
+
end
|
2143
|
+
alias :text_font :get_text_font
|
2144
|
+
|
2145
|
+
# Set default control fill brush.
|
2146
|
+
# @overload set_control_fill(brush)
|
2147
|
+
# @param [Wx::Brush] brush
|
2148
|
+
# @overload set_control_fill(color, style=Wx::BrushStyle::BRUSHSTYLE_SOLID)
|
2149
|
+
# @param [Wx::Colour,Symbol,String] color brush color
|
2150
|
+
# @param [Wx::BrushStyle] style
|
2151
|
+
# @overload set_control_fill(stipple_bitmap)
|
2152
|
+
# @param [Wx::Bitmap] stipple_bitmap
|
2153
|
+
def set_control_fill(*args)
|
2154
|
+
@settings.common_control_fill = if args.size == 1 && Wx::Brush === args.first
|
2155
|
+
args.first
|
2156
|
+
else
|
2157
|
+
Wx::Brush.new(*args)
|
2158
|
+
end
|
2159
|
+
end
|
2160
|
+
alias :control_fill= :set_control_fill
|
2161
|
+
|
2162
|
+
# Get default control fill brush.
|
2163
|
+
# @return [Wx::Brush] Fill brush
|
2164
|
+
def get_control_fill
|
2165
|
+
@settings.common_control_fill
|
2166
|
+
end
|
2167
|
+
alias :control_fill :get_control_fill
|
2168
|
+
|
2169
|
+
# Set default control border.
|
2170
|
+
# @overload set_control_border(pen)
|
2171
|
+
# @param [Wx::Pen] pen
|
2172
|
+
# @overload set_control_border(color, width=1, style=Wx::PenStyle::PENSTYLE_SOLID)
|
2173
|
+
# @param [Wx::Colour,String,Symbol] color
|
2174
|
+
# @param [Integer] width
|
2175
|
+
# @param [Wx::PenStyle] style
|
2176
|
+
def set_control_border(*args)
|
2177
|
+
@settings.common_control_border = if args.size == 1 && Wx::Pen === args.first
|
2178
|
+
args.first
|
2179
|
+
else
|
2180
|
+
Wx::Pen.new(*args)
|
2181
|
+
end
|
2182
|
+
end
|
2183
|
+
alias :control_border= :set_control_border
|
2184
|
+
|
2185
|
+
# Get default control border.
|
2186
|
+
# @return [Wx::Pen]
|
2187
|
+
def get_control_border
|
2188
|
+
@settings.common_control_border
|
2189
|
+
end
|
2190
|
+
alias :control_border :get_control_border
|
2191
|
+
|
2192
|
+
# Set default control modification fill brush.
|
2193
|
+
# @overload set_control_mod_fill(brush)
|
2194
|
+
# @param [Wx::Brush] brush
|
2195
|
+
# @overload set_control_mod_fill(color, style=Wx::BrushStyle::BRUSHSTYLE_SOLID)
|
2196
|
+
# @param [Wx::Colour,Symbol,String] color brush color
|
2197
|
+
# @param [Wx::BrushStyle] style
|
2198
|
+
# @overload set_control_mod_fill(stipple_bitmap)
|
2199
|
+
# @param [Wx::Bitmap] stipple_bitmap
|
2200
|
+
def set_control_mod_fill(*args)
|
2201
|
+
@settings.common_control_mod_fill = if args.size == 1 && Wx::Brush === args.first
|
2202
|
+
args.first
|
2203
|
+
else
|
2204
|
+
Wx::Brush.new(*args)
|
2205
|
+
end
|
2206
|
+
end
|
2207
|
+
alias :control_mod_fill= :set_control_mod_fill
|
2208
|
+
|
2209
|
+
# Get default control modification fill brush.
|
2210
|
+
# @return [Wx::Brush] Fill brush
|
2211
|
+
def get_control_mod_fill
|
2212
|
+
@settings.common_control_mod_fill
|
2213
|
+
end
|
2214
|
+
alias :control_mod_fill :get_control_mod_fill
|
2215
|
+
|
2216
|
+
# Set default control modification border.
|
2217
|
+
# @overload set_control_mod_border(pen)
|
2218
|
+
# @param [Wx::Pen] pen
|
2219
|
+
# @overload set_control_mod_border(color, width=1, style=Wx::PenStyle::PENSTYLE_SOLID)
|
2220
|
+
# @param [Wx::Colour,String,Symbol] color
|
2221
|
+
# @param [Integer] width
|
2222
|
+
# @param [Wx::PenStyle] style
|
2223
|
+
def set_control_mod_border(*args)
|
2224
|
+
@settings.common_control_mod_border = if args.size == 1 && Wx::Pen === args.first
|
2225
|
+
args.first
|
2226
|
+
else
|
2227
|
+
Wx::Pen.new(*args)
|
2228
|
+
end
|
2229
|
+
end
|
2230
|
+
alias :control_mod_border= :set_control_mod_border
|
2231
|
+
|
2232
|
+
# Get default control modification border.
|
2233
|
+
# @return [Wx::Pen]
|
2234
|
+
def get_control_mod_border
|
2235
|
+
@settings.common_control_mod_border
|
2236
|
+
end
|
2237
|
+
alias :control_mod_border :get_control_mod_border
|
1831
2238
|
|
1832
2239
|
# Get canvas history manager.
|
1833
2240
|
# @return [Wx::SF::CanvasHistory] the canvas history manager
|
@@ -1843,8 +2250,8 @@ module Wx::SF
|
|
1843
2250
|
def fit_position_to_grid(pos)
|
1844
2251
|
pos = pos.to_point
|
1845
2252
|
if has_style?(STYLE::GRID_USE)
|
1846
|
-
Wx::Point.new(pos.x / @settings.grid_size
|
1847
|
-
pos.y / @settings.grid_size
|
2253
|
+
Wx::Point.new(pos.x / @settings.grid_size * @settings.grid_size,
|
2254
|
+
pos.y / @settings.grid_size * @settings.grid_size)
|
1848
2255
|
else
|
1849
2256
|
pos
|
1850
2257
|
end
|
@@ -1905,7 +2312,7 @@ module Wx::SF
|
|
1905
2312
|
|
1906
2313
|
move_shapes_from_negatives
|
1907
2314
|
end
|
1908
|
-
|
2315
|
+
|
1909
2316
|
# Validate selection (remove redundantly selected shapes etc...).
|
1910
2317
|
# @param [Array<Wx::SF::Shape>] selection List of selected shapes that should be validated
|
1911
2318
|
def validate_selection(selection)
|
@@ -1931,6 +2338,40 @@ module Wx::SF
|
|
1931
2338
|
end
|
1932
2339
|
end
|
1933
2340
|
|
2341
|
+
# Draws shapes intersecting the update region
|
2342
|
+
def draw_shape_updates(dc, upd_rct, lst_to_draw, exclude_selected = false)
|
2343
|
+
lst_selected = exclude_selected ? [] : nil
|
2344
|
+
lst_lines_to_draw = []
|
2345
|
+
# draw unselected non line-based shapes first...
|
2346
|
+
lst_to_draw.each do |shape|
|
2347
|
+
if exclude_selected && (shape.selected? || shape.has_selected_parent?)
|
2348
|
+
lst_selected << shape
|
2349
|
+
else
|
2350
|
+
if !shape.is_a?(LineShape) || shape.stand_alone?
|
2351
|
+
if shape.intersects?(upd_rct)
|
2352
|
+
parent_shape = shape.get_parent_shape
|
2353
|
+
if parent_shape
|
2354
|
+
shape.draw(dc, WITHOUTCHILDREN) if !parent_shape.is_a?(LineShape) || parent_shape.stand_alone?
|
2355
|
+
else
|
2356
|
+
shape.draw(dc, WITHOUTCHILDREN)
|
2357
|
+
end
|
2358
|
+
end
|
2359
|
+
else
|
2360
|
+
lst_lines_to_draw << shape
|
2361
|
+
end
|
2362
|
+
end
|
2363
|
+
end
|
2364
|
+
|
2365
|
+
# ... and draw connections
|
2366
|
+
bb_rct = nil
|
2367
|
+
lst_lines_to_draw.each do |line|
|
2368
|
+
bb_rct = line.get_complete_bounding_box(bb_rct, Shape::BBMODE::SELF | Shape::BBMODE::CHILDREN | Shape::BBMODE::SHADOW)
|
2369
|
+
line.draw(dc, line.get_line_mode == LineShape::LINEMODE::READY) if bb_rct.intersects(upd_rct)
|
2370
|
+
end
|
2371
|
+
lst_selected
|
2372
|
+
end
|
2373
|
+
private :draw_shape_updates
|
2374
|
+
|
1934
2375
|
# Function responsible for drawing of the canvas's content to given DC. The default
|
1935
2376
|
# implementation draws actual objects managed by assigned diagram manager.
|
1936
2377
|
# @param [Wx::DC] dc device context where the shapes will be drawn to
|
@@ -1940,12 +2381,6 @@ module Wx::SF
|
|
1940
2381
|
return unless @diagram
|
1941
2382
|
|
1942
2383
|
if from_paint
|
1943
|
-
# wxRect updRct
|
1944
|
-
bb_rct = Wx::Rect.new
|
1945
|
-
#
|
1946
|
-
# ShapeList m_lstToDraw
|
1947
|
-
lst_lines_to_draw = []
|
1948
|
-
|
1949
2384
|
# get all existing shapes
|
1950
2385
|
lst_to_draw = @diagram.get_shapes(Shape, Shape::SEARCHMODE::DFS)
|
1951
2386
|
|
@@ -1964,51 +2399,13 @@ module Wx::SF
|
|
1964
2399
|
upd_rct ||= Wx::Rect.new
|
1965
2400
|
|
1966
2401
|
if @working_mode == MODE::SHAPEMOVE
|
1967
|
-
# draw unselected
|
1968
|
-
lst_to_draw
|
1969
|
-
parent_shape = shape.get_parent_shape
|
1970
|
-
|
1971
|
-
if !shape.is_a?(LineShape) || shape.stand_alone?
|
1972
|
-
if shape.intersects?(upd_rct)
|
1973
|
-
if parent_shape
|
1974
|
-
shape.draw(dc, WITHOUTCHILDREN) if !parent_shape.is_a?(LineShape) || parent_shape.stand_alone?
|
1975
|
-
else
|
1976
|
-
shape.draw(dc, WITHOUTCHILDREN)
|
1977
|
-
end
|
1978
|
-
end
|
1979
|
-
else
|
1980
|
-
lst_lines_to_draw << shape
|
1981
|
-
end
|
1982
|
-
end
|
2402
|
+
# draw unselected shapes first and filter and return selected shapes
|
2403
|
+
lst_selected = draw_shape_updates(dc, upd_rct, lst_to_draw, true)
|
1983
2404
|
|
1984
|
-
# ... and draw
|
1985
|
-
|
1986
|
-
line.get_complete_bounding_box(bb_rct, Shape::BBMODE::SELF | Shape::BBMODE::CHILDREN | Shape::BBMODE::SHADOW)
|
1987
|
-
line.draw(dc, line.get_line_mode == LineShape::LINEMODE::READY) if bb_rct.intersects(upd_rct)
|
1988
|
-
end
|
2405
|
+
# ... and now draw the selected shapes being moved
|
2406
|
+
draw_shape_updates(dc, upd_rct, lst_selected)
|
1989
2407
|
else
|
1990
|
-
|
1991
|
-
lst_to_draw.each do |shape|
|
1992
|
-
parent_shape = shape.get_parent_shape
|
1993
|
-
|
1994
|
-
if !shape.is_a?(LineShape) || shape.stand_alone?
|
1995
|
-
if shape.intersects?(upd_rct)
|
1996
|
-
if parent_shape
|
1997
|
-
shape.draw(dc, WITHOUTCHILDREN) if !parent_shape.is_a?(LineShape) || shape.stand_alone?
|
1998
|
-
else
|
1999
|
-
shape.draw(dc, WITHOUTCHILDREN)
|
2000
|
-
end
|
2001
|
-
end
|
2002
|
-
else
|
2003
|
-
lst_lines_to_draw << shape
|
2004
|
-
end
|
2005
|
-
end
|
2006
|
-
|
2007
|
-
# draw connections
|
2008
|
-
lst_lines_to_draw.each do |line|
|
2009
|
-
line.get_complete_bounding_box(bb_rct, Shape::BBMODE::SELF | Shape::BBMODE::CHILDREN)
|
2010
|
-
line.draw(dc, line.get_line_mode == LineShape::LINEMODE::READY) if bb_rct.intersects(upd_rct)
|
2011
|
-
end
|
2408
|
+
draw_shape_updates(dc, upd_rct, lst_to_draw)
|
2012
2409
|
end
|
2013
2410
|
|
2014
2411
|
# draw multiselection if necessary
|
@@ -2035,7 +2432,7 @@ module Wx::SF
|
|
2035
2432
|
def draw_background(dc, _from_paint)
|
2036
2433
|
# erase background
|
2037
2434
|
if has_style?(STYLE::GRADIENT_BACKGROUND)
|
2038
|
-
bcg_size = @settings.grid_size
|
2435
|
+
bcg_size = get_virtual_size.to_size + @settings.grid_size
|
2039
2436
|
if @settings.scale != 1.0
|
2040
2437
|
dc.gradient_fill_linear(Wx::Rect.new([0, 0], [(bcg_size.x/@settings.scale).to_i, (bcg_size.y/@settings.scale).to_i]),
|
2041
2438
|
@settings.gradient_from, @settings.gradient_to, Wx::SOUTH)
|
@@ -2050,10 +2447,10 @@ module Wx::SF
|
|
2050
2447
|
|
2051
2448
|
# show grid
|
2052
2449
|
if has_style?(STYLE::GRID_SHOW)
|
2053
|
-
linedist = @settings.grid_size
|
2450
|
+
linedist = @settings.grid_size * @settings.grid_line_mult
|
2054
2451
|
|
2055
2452
|
if (linedist * @settings.scale) > 3.0
|
2056
|
-
grid_rct = Wx::Rect.new([0, 0], @settings.grid_size
|
2453
|
+
grid_rct = Wx::Rect.new([0, 0], get_virtual_size.to_size + @settings.grid_size)
|
2057
2454
|
max_x = (grid_rct.right/@settings.scale).to_i
|
2058
2455
|
max_y = (grid_rct.bottom/@settings.scale).to_i
|
2059
2456
|
|
@@ -2100,11 +2497,11 @@ module Wx::SF
|
|
2100
2497
|
|
2101
2498
|
_notify_canvas_change(CHANGE::FOCUS)
|
2102
2499
|
set_focus
|
2103
|
-
|
2500
|
+
|
2104
2501
|
lpos = dp2lp(event.get_position)
|
2105
|
-
|
2502
|
+
|
2106
2503
|
@can_save_state_on_mouse_up = false
|
2107
|
-
|
2504
|
+
|
2108
2505
|
case @working_mode
|
2109
2506
|
when MODE::READY
|
2110
2507
|
@selected_handle = get_topmost_handle_at_position(lpos)
|
@@ -2129,6 +2526,10 @@ module Wx::SF
|
|
2129
2526
|
# perform selection
|
2130
2527
|
lst_selection = get_selected_shapes
|
2131
2528
|
|
2529
|
+
if @selection_mode == SELECTIONMODE::NORMAL
|
2530
|
+
save_canvas_state if @canvas_history.empty?
|
2531
|
+
end
|
2532
|
+
|
2132
2533
|
# cancel previous selections if necessary...
|
2133
2534
|
if @selection_mode == SELECTIONMODE::NORMAL && (selected_top_shape.nil? || !lst_selection.include?(selected_top_shape))
|
2134
2535
|
deselect_all
|
@@ -2159,7 +2560,7 @@ module Wx::SF
|
|
2159
2560
|
|
2160
2561
|
# inform also connections assigned to the shape and its children
|
2161
2562
|
lst_connections.clear
|
2162
|
-
append_assigned_connections(shape, lst_connections
|
2563
|
+
append_assigned_connections(shape, lst_connections)
|
2163
2564
|
|
2164
2565
|
lst_connections.each do |line|
|
2165
2566
|
line.send(:_on_begin_drag, fit_pos)
|
@@ -2196,6 +2597,7 @@ module Wx::SF
|
|
2196
2597
|
# update canvas
|
2197
2598
|
invalidate_visible_rect
|
2198
2599
|
else
|
2600
|
+
save_canvas_state if @canvas_history.empty?
|
2199
2601
|
if @selected_handle.get_parent_shape == @shp_multi_edit
|
2200
2602
|
if has_style?(STYLE::MULTI_SIZE_CHANGE)
|
2201
2603
|
@working_mode = MODE::MULTIHANDLEMOVE
|
@@ -2229,28 +2631,28 @@ module Wx::SF
|
|
2229
2631
|
end
|
2230
2632
|
# finish connection's creation process if possible
|
2231
2633
|
if shape_under && !event.control_down
|
2232
|
-
if @new_line_shape.
|
2233
|
-
|
2634
|
+
if @new_line_shape.get_trg_shape.nil? && (shape_under != @new_line_shape) &&
|
2635
|
+
(shape_under.is_connection_accepted(@new_line_shape.class))
|
2234
2636
|
# find out whether the target shape can be connected to the source shape
|
2235
|
-
source_shape = @
|
2637
|
+
source_shape = @new_line_shape.get_src_shape
|
2236
2638
|
|
2237
2639
|
if source_shape &&
|
2238
2640
|
shape_under.is_src_neighbour_accepted(source_shape.class) &&
|
2239
2641
|
source_shape.is_trg_neighbour_accepted(shape_under.class)
|
2240
|
-
@new_line_shape.
|
2642
|
+
@new_line_shape.set_trg_shape(shape_under)
|
2241
2643
|
@new_line_shape.set_ending_connection_point(shape_under.get_nearest_connection_point(lpos.to_real))
|
2242
2644
|
|
2243
2645
|
# inform user that the line is completed
|
2244
2646
|
case on_pre_connection_finished(@new_line_shape)
|
2245
2647
|
when PRECON_FINISH_STATE::OK
|
2246
2648
|
when PRECON_FINISH_STATE::FAILED_AND_CANCEL_LINE
|
2247
|
-
@new_line_shape.
|
2649
|
+
@new_line_shape.set_trg_shape(nil)
|
2248
2650
|
@diagram.remove_shape(@new_line_shape)
|
2249
2651
|
@working_mode = MODE::READY
|
2250
2652
|
@new_line_shape = nil
|
2251
2653
|
return
|
2252
2654
|
when PRECON_FINISH_STATE::FAILED_AND_CONTINUE_EDIT
|
2253
|
-
@new_line_shape.
|
2655
|
+
@new_line_shape.set_trg_shape(nil)
|
2254
2656
|
return
|
2255
2657
|
end
|
2256
2658
|
@new_line_shape.create_handles
|
@@ -2270,7 +2672,7 @@ module Wx::SF
|
|
2270
2672
|
end
|
2271
2673
|
end
|
2272
2674
|
else
|
2273
|
-
if @new_line_shape.
|
2675
|
+
if @new_line_shape.get_src_shape
|
2274
2676
|
fit_pos = fit_position_to_grid(lpos)
|
2275
2677
|
@new_line_shape.get_control_points << Wx::RealPoint.new(fit_pos.x, fit_pos.y)
|
2276
2678
|
end
|
@@ -2280,7 +2682,7 @@ module Wx::SF
|
|
2280
2682
|
else
|
2281
2683
|
@working_mode = MODE::READY
|
2282
2684
|
end
|
2283
|
-
|
2685
|
+
|
2284
2686
|
refresh_invalidated_rect
|
2285
2687
|
end
|
2286
2688
|
|
@@ -2327,7 +2729,7 @@ module Wx::SF
|
|
2327
2729
|
def on_left_up(event)
|
2328
2730
|
# HINT: override it for custom actions...
|
2329
2731
|
lpos = dp2lp(event.get_position)
|
2330
|
-
|
2732
|
+
|
2331
2733
|
case @working_mode
|
2332
2734
|
when MODE::MULTIHANDLEMOVE, MODE::HANDLEMOVE
|
2333
2735
|
# resize parent shape to fit all its children if necessary
|
@@ -2343,17 +2745,21 @@ module Wx::SF
|
|
2343
2745
|
line.send(:set_line_mode, LineShape::LINEMODE::READY)
|
2344
2746
|
|
2345
2747
|
parent_shape = get_shape_under_cursor
|
2748
|
+
# propagate request for interactive connection if requested
|
2749
|
+
while parent_shape && parent_shape.has_style?(Shape::STYLE::PROPAGATE_INTERACTIVE_CONNECTION)
|
2750
|
+
parent_shape = parent_shape.get_parent_shape
|
2751
|
+
end
|
2346
2752
|
|
2347
2753
|
if parent_shape && (parent_shape != line) && (parent_shape.is_connection_accepted(line.class))
|
2348
2754
|
if @selected_handle.get_type == Shape::Handle::TYPE::LINESTART
|
2349
|
-
trg_shape =
|
2755
|
+
trg_shape = line.get_trg_shape
|
2350
2756
|
if trg_shape && parent_shape.is_trg_neighbour_accepted(trg_shape.class)
|
2351
|
-
line.
|
2757
|
+
line.set_src_shape(parent_shape)
|
2352
2758
|
end
|
2353
2759
|
else
|
2354
|
-
src_shape =
|
2760
|
+
src_shape = line.get_src_shape
|
2355
2761
|
if src_shape && parent_shape.is_src_neighbour_accepted(src_shape.class)
|
2356
|
-
line.
|
2762
|
+
line.set_trg_shape(parent_shape)
|
2357
2763
|
end
|
2358
2764
|
end
|
2359
2765
|
end
|
@@ -2362,29 +2768,29 @@ module Wx::SF
|
|
2362
2768
|
@selected_handle.send(:_on_end_drag, lpos)
|
2363
2769
|
|
2364
2770
|
@selected_handle = nil
|
2365
|
-
save_canvas_state if @can_save_state_on_mouse_up
|
2771
|
+
save_canvas_state if @can_save_state_on_mouse_up
|
2366
2772
|
|
2367
2773
|
when MODE::SHAPEMOVE
|
2368
2774
|
lst_selection = get_selected_shapes
|
2369
|
-
|
2775
|
+
|
2370
2776
|
lst_selection.each do |shape|
|
2371
2777
|
# notify shape
|
2372
2778
|
shape.send(:_on_end_drag, lpos)
|
2373
2779
|
# reparent based on new position
|
2374
|
-
|
2780
|
+
reparent_dropped_shape(shape, lpos)
|
2375
2781
|
end
|
2376
|
-
|
2782
|
+
|
2377
2783
|
if lst_selection.size>1
|
2378
2784
|
@shp_multi_edit.show(true)
|
2379
2785
|
@shp_multi_edit.show_handles(true)
|
2380
2786
|
else
|
2381
2787
|
@shp_multi_edit.show(false)
|
2382
2788
|
end
|
2383
|
-
|
2789
|
+
|
2384
2790
|
move_shapes_from_negatives
|
2385
2791
|
|
2386
2792
|
save_canvas_state if @can_save_state_on_mouse_up
|
2387
|
-
|
2793
|
+
|
2388
2794
|
when MODE::MULTISELECTION
|
2389
2795
|
lst_selection = get_selected_shapes
|
2390
2796
|
|
@@ -2416,7 +2822,7 @@ module Wx::SF
|
|
2416
2822
|
|
2417
2823
|
@shp_selection.show(false)
|
2418
2824
|
end
|
2419
|
-
|
2825
|
+
|
2420
2826
|
if @working_mode != MODE::CREATECONNECTION
|
2421
2827
|
# update canvas
|
2422
2828
|
@working_mode = MODE::READY
|
@@ -2442,19 +2848,22 @@ module Wx::SF
|
|
2442
2848
|
|
2443
2849
|
_notify_canvas_change(CHANGE::FOCUS)
|
2444
2850
|
set_focus
|
2445
|
-
|
2851
|
+
|
2446
2852
|
lpos = dp2lp(event.get_position)
|
2447
|
-
|
2853
|
+
|
2448
2854
|
if @working_mode == MODE::READY
|
2449
2855
|
deselect_all
|
2450
|
-
|
2856
|
+
|
2451
2857
|
shape = get_shape_under_cursor
|
2858
|
+
while shape && shape.has_style?(Shape::STYLE::PROPAGATE_SELECTION)
|
2859
|
+
shape = shape.get_parent_shape
|
2860
|
+
end
|
2452
2861
|
if shape
|
2453
2862
|
shape.select(true)
|
2454
2863
|
shape.on_right_click(lpos)
|
2455
2864
|
end
|
2456
2865
|
end
|
2457
|
-
|
2866
|
+
|
2458
2867
|
refresh(false)
|
2459
2868
|
end
|
2460
2869
|
|
@@ -2472,9 +2881,9 @@ module Wx::SF
|
|
2472
2881
|
|
2473
2882
|
_notify_canvas_change(CHANGE::FOCUS)
|
2474
2883
|
set_focus
|
2475
|
-
|
2884
|
+
|
2476
2885
|
lpos = dp2lp(event.get_position)
|
2477
|
-
|
2886
|
+
|
2478
2887
|
if @working_mode == MODE::READY
|
2479
2888
|
shape = get_shape_under_cursor
|
2480
2889
|
shape.on_right_double_click(lpos) if shape
|
@@ -2508,9 +2917,9 @@ module Wx::SF
|
|
2508
2917
|
def on_mouse_move(event)
|
2509
2918
|
# HINT: override it for custom actions...
|
2510
2919
|
return unless @diagram
|
2511
|
-
|
2920
|
+
|
2512
2921
|
lpos = dp2lp(event.get_position)
|
2513
|
-
|
2922
|
+
|
2514
2923
|
case @working_mode
|
2515
2924
|
when MODE::READY, MODE::CREATECONNECTION
|
2516
2925
|
unless event.dragging
|
@@ -2522,16 +2931,12 @@ module Wx::SF
|
|
2522
2931
|
|
2523
2932
|
# update unfinished line if any
|
2524
2933
|
if @new_line_shape
|
2525
|
-
line_rct =
|
2526
|
-
upd_line_rct = Wx::Rect.new
|
2527
|
-
@new_line_shape.get_complete_bounding_box(line_rct, Shape::BBMODE::SELF | Shape::BBMODE::CHILDREN)
|
2934
|
+
line_rct = @new_line_shape.get_complete_bounding_box(nil, Shape::BBMODE::SELF | Shape::BBMODE::CHILDREN)
|
2528
2935
|
|
2529
2936
|
@new_line_shape.send(:set_unfinished_point, fit_position_to_grid(lpos))
|
2530
2937
|
@new_line_shape.update
|
2531
2938
|
|
2532
|
-
@new_line_shape.get_complete_bounding_box(
|
2533
|
-
|
2534
|
-
line_rct.union!(upd_line_rct)
|
2939
|
+
line_rct = @new_line_shape.get_complete_bounding_box(line_rct, Shape::BBMODE::SELF | Shape::BBMODE::CHILDREN)
|
2535
2940
|
|
2536
2941
|
invalidate_rect(line_rct)
|
2537
2942
|
end
|
@@ -2552,8 +2957,8 @@ module Wx::SF
|
|
2552
2957
|
unless @working_mode == MODE::MULTIHANDLEMOVE
|
2553
2958
|
if event.dragging
|
2554
2959
|
if has_style?(STYLE::GRID_USE)
|
2555
|
-
return if (event.get_position.x - @prev_mouse_pos.x).abs < @settings.grid_size
|
2556
|
-
(event.get_position.y - @prev_mouse_pos.y).abs < @settings.grid_size
|
2960
|
+
return if (event.get_position.x - @prev_mouse_pos.x).abs < @settings.grid_size &&
|
2961
|
+
(event.get_position.y - @prev_mouse_pos.y).abs < @settings.grid_size
|
2557
2962
|
end
|
2558
2963
|
@prev_mouse_pos = event.get_position
|
2559
2964
|
|
@@ -2572,7 +2977,7 @@ module Wx::SF
|
|
2572
2977
|
# move also connections assigned to this shape and its children
|
2573
2978
|
lst_connections.clear
|
2574
2979
|
|
2575
|
-
append_assigned_connections(shape, lst_connections
|
2980
|
+
append_assigned_connections(shape, lst_connections)
|
2576
2981
|
|
2577
2982
|
lst_connections.each { |line| line.send(:_on_dragging, fit_position_to_grid(lpos)) }
|
2578
2983
|
|
@@ -2607,7 +3012,7 @@ module Wx::SF
|
|
2607
3012
|
|
2608
3013
|
invalidate_visible_rect
|
2609
3014
|
end
|
2610
|
-
|
3015
|
+
|
2611
3016
|
refresh_invalidated_rect
|
2612
3017
|
end
|
2613
3018
|
|
@@ -2621,18 +3026,17 @@ module Wx::SF
|
|
2621
3026
|
# @param [Wx::MouseEvent] event Mouse event
|
2622
3027
|
def on_mouse_wheel(event)
|
2623
3028
|
# HINT: override it for custom actions...
|
2624
|
-
|
2625
3029
|
if event.control_down
|
2626
3030
|
scale = get_scale
|
2627
|
-
scale +=
|
3031
|
+
scale += event.get_wheel_rotation.to_f/(event.get_wheel_delta*10)
|
2628
3032
|
|
2629
3033
|
scale = @settings.min_scale if scale < @settings.min_scale
|
2630
3034
|
scale = @settings.max_scale if scale > @settings.max_scale
|
2631
|
-
|
3035
|
+
|
2632
3036
|
set_scale(scale)
|
2633
3037
|
refresh(false)
|
2634
3038
|
end
|
2635
|
-
|
3039
|
+
|
2636
3040
|
event.skip
|
2637
3041
|
end
|
2638
3042
|
|
@@ -2650,7 +3054,7 @@ module Wx::SF
|
|
2650
3054
|
return unless @diagram
|
2651
3055
|
|
2652
3056
|
lst_selection = get_selected_shapes
|
2653
|
-
|
3057
|
+
|
2654
3058
|
case event.get_key_code
|
2655
3059
|
when Wx::K_DELETE
|
2656
3060
|
# send event to selected shapes
|
@@ -2684,6 +3088,13 @@ module Wx::SF
|
|
2684
3088
|
line.send(:set_line_mode, LineShape::LINEMODE::READY)
|
2685
3089
|
@selected_handle = nil
|
2686
3090
|
end
|
3091
|
+
restore_current_state
|
3092
|
+
|
3093
|
+
when MODE::MULTIHANDLEMOVE
|
3094
|
+
restore_current_state
|
3095
|
+
|
3096
|
+
when MODE::SHAPEMOVE
|
3097
|
+
restore_current_state
|
2687
3098
|
|
2688
3099
|
else
|
2689
3100
|
# send event to selected shapes
|
@@ -2696,16 +3107,16 @@ module Wx::SF
|
|
2696
3107
|
lst_connections = []
|
2697
3108
|
lst_selection.each do |shape|
|
2698
3109
|
shape.send(:_on_key, event.get_key_code)
|
2699
|
-
|
3110
|
+
|
2700
3111
|
# inform also connections assigned to this shape
|
2701
3112
|
lst_connections.clear
|
2702
|
-
append_assigned_connections(shape, lst_connections
|
2703
|
-
|
3113
|
+
append_assigned_connections(shape, lst_connections)
|
3114
|
+
|
2704
3115
|
lst_connections.each do |line|
|
2705
3116
|
line.send(:_on_key, event.get_key_code) unless line.selected?
|
2706
3117
|
end
|
2707
3118
|
end
|
2708
|
-
|
3119
|
+
|
2709
3120
|
# send the event to multiedit ctrl if displayed
|
2710
3121
|
@shp_multi_edit.send(:_on_key, event.get_key_code) if @shp_multi_edit.visible?
|
2711
3122
|
|
@@ -2727,9 +3138,9 @@ module Wx::SF
|
|
2727
3138
|
# @see Wx::SF::ShapeTextEvent
|
2728
3139
|
def on_text_change(shape)
|
2729
3140
|
# HINT: override it for custom actions...
|
2730
|
-
|
3141
|
+
|
2731
3142
|
# ... standard implementation generates the Wx::SF::EVT_SF_TEXT_CHANGE event.
|
2732
|
-
id = shape ? shape.
|
3143
|
+
id = shape ? shape.object_id : nil
|
2733
3144
|
|
2734
3145
|
event = ShapeTextEvent.new(Wx::SF::EVT_SF_TEXT_CHANGE, id)
|
2735
3146
|
event.set_shape(shape)
|
@@ -2745,9 +3156,9 @@ module Wx::SF
|
|
2745
3156
|
# @see Wx::SF::ShapeEvent
|
2746
3157
|
def on_connection_finished(connection)
|
2747
3158
|
# HINT: override to perform user-defined actions...
|
2748
|
-
|
3159
|
+
|
2749
3160
|
# ... standard implementation generates the Wx::SF::EVT_SF_LINE_DONE event.
|
2750
|
-
id = connection ? connection.
|
3161
|
+
id = connection ? connection.object_id : -1
|
2751
3162
|
|
2752
3163
|
event = ShapeEvent.new(Wx::SF::EVT_SF_LINE_DONE, id)
|
2753
3164
|
event.set_shape(connection)
|
@@ -2766,10 +3177,10 @@ module Wx::SF
|
|
2766
3177
|
# @see Wx::SF::ShapeEvent
|
2767
3178
|
def on_pre_connection_finished(connection)
|
2768
3179
|
# HINT: override to perform user-defined actions...
|
2769
|
-
|
3180
|
+
|
2770
3181
|
# ... standard implementation generates the Wx::SF::EVT_SF_LINE_DONE event.
|
2771
|
-
id = connection ? connection.
|
2772
|
-
|
3182
|
+
id = connection ? connection.object_id : -1
|
3183
|
+
|
2773
3184
|
event = ShapeEvent.new(Wx::SF::EVT_SF_LINE_BEFORE_DONE, id)
|
2774
3185
|
event.set_shape(connection)
|
2775
3186
|
process_event(event)
|
@@ -2792,10 +3203,10 @@ module Wx::SF
|
|
2792
3203
|
# @see Wx::SF::ShapeDropEvent
|
2793
3204
|
def on_drop(x, y, deflt, dropped)
|
2794
3205
|
# HINT: override it for custom actions...
|
2795
|
-
|
3206
|
+
|
2796
3207
|
# ... standard implementation generates the Wx::SF::EVT_SF_ON_DROP event.
|
2797
3208
|
return unless has_style?(STYLE::DND)
|
2798
|
-
|
3209
|
+
|
2799
3210
|
# create the drop event and process it
|
2800
3211
|
event = ShapeDropEvent.new(Wx::SF::EVT_SF_ON_DROP, x, y, self, deflt, Wx::ID_ANY)
|
2801
3212
|
event.set_dropped_shapes(dropped)
|
@@ -2812,10 +3223,10 @@ module Wx::SF
|
|
2812
3223
|
# @see Wx::SF::ShapePasteEvent
|
2813
3224
|
def on_paste(pasted)
|
2814
3225
|
# HINT: override it for custom actions...
|
2815
|
-
|
3226
|
+
|
2816
3227
|
# ... standard implementation generates the Wx::SF::EVT_SF_ON_PASTE event.
|
2817
3228
|
return unless has_style?(STYLE::CLIPBOARD)
|
2818
|
-
|
3229
|
+
|
2819
3230
|
# create the drop event and process it
|
2820
3231
|
event = ShapePasteEvent.new(Wx::SF::EVT_SF_ON_PASTE, self, Wx::ID_ANY)
|
2821
3232
|
event.set_pasted_shapes(pasted)
|
@@ -2842,12 +3253,14 @@ module Wx::SF
|
|
2842
3253
|
# @param [Array<Wx::SF::Shape>] selection
|
2843
3254
|
# @param [Boolean] storeprevpos
|
2844
3255
|
def validate_selection_for_clipboard(selection, storeprevpos)
|
2845
|
-
|
3256
|
+
# first remove any shapes not eligible for copying
|
3257
|
+
selection.reject! do |shape|
|
3258
|
+
do_reject = false
|
2846
3259
|
if shape.get_parent_shape
|
2847
3260
|
# remove child shapes without parent in the selection and without STYLE::PARENT_CHANGE style
|
2848
3261
|
# defined from the selection
|
2849
3262
|
if !shape.has_style?(Shape::STYLE::PARENT_CHANGE) && !selection.include?(shape.get_parent_shape)
|
2850
|
-
|
3263
|
+
do_reject = true
|
2851
3264
|
else
|
2852
3265
|
# convert relative position to absolute position if the shape is copied
|
2853
3266
|
# without its parent
|
@@ -2856,32 +3269,49 @@ module Wx::SF
|
|
2856
3269
|
shape.set_relative_position(shape.get_absolute_position)
|
2857
3270
|
end
|
2858
3271
|
end
|
3272
|
+
elsif LineShape === shape && !shape.stand_alone?
|
3273
|
+
# remove any stand alone LineShape for which the source or target shape are not included in the selection
|
3274
|
+
# (or any of it's child shapes)
|
3275
|
+
unless (selection.include?(shape.get_src_shape) ||
|
3276
|
+
selection.any? { |selshp| selshp.include_child_shape?(shape.get_src_shape, true) }) &&
|
3277
|
+
(selection.include?(shape.get_trg_shape) ||
|
3278
|
+
selection.any? { |selshp| selshp.include_child_shape?(shape.get_trg_shape, true) })
|
3279
|
+
do_reject = true
|
3280
|
+
end
|
2859
3281
|
end
|
2860
|
-
|
2861
|
-
|
3282
|
+
do_reject
|
3283
|
+
end
|
3284
|
+
|
3285
|
+
# now append all connections for which source AND target are included in the selection
|
3286
|
+
selection.each do |shape|
|
3287
|
+
append_assigned_connections(shape, selection, children_only: false, complete_only: true)
|
2862
3288
|
end
|
2863
3289
|
end
|
2864
3290
|
|
2865
|
-
#
|
2866
|
-
# @param [Wx::SF::Shape] shape
|
2867
|
-
# @param [Array<Wx::SF::Shape>] selection
|
2868
|
-
# @param [Boolean]
|
2869
|
-
|
3291
|
+
# Append connections assigned to shapes in given list to this list as well
|
3292
|
+
# @param [Wx::SF::Shape] shape shape
|
3293
|
+
# @param [Array<Wx::SF::Shape>] selection selected shapes
|
3294
|
+
# @param [Boolean] children_only appends connections from child shapes only
|
3295
|
+
# @param [Boolean] complete_only append complete (src and trg shapes in selection) only
|
3296
|
+
def append_assigned_connections(shape, selection, children_only: true, complete_only: false)
|
2870
3297
|
# add connections assigned to copied topmost shapes and their children to the copy list
|
2871
3298
|
lst_children = shape.get_child_shapes(ANY, RECURSIVE)
|
2872
|
-
|
3299
|
+
|
2873
3300
|
# get connections assigned to the parent shape
|
2874
|
-
lst_connections = @diagram.get_assigned_connections(shape, LineShape, Shape::CONNECTMODE::BOTH) unless
|
3301
|
+
lst_connections = @diagram.get_assigned_connections(shape, LineShape, Shape::CONNECTMODE::BOTH) unless children_only
|
2875
3302
|
lst_connections ||= []
|
2876
|
-
# get connections assigned to its child shape
|
3303
|
+
# get connections assigned to its child shape(s)
|
2877
3304
|
lst_children.each do |child|
|
2878
|
-
# get connections assigned to the child shape
|
3305
|
+
# get connections assigned to the child shape(s)
|
2879
3306
|
@diagram.get_assigned_connections(child, LineShape, Shape::CONNECTMODE::BOTH, lst_connections)
|
2880
3307
|
end
|
2881
|
-
|
3308
|
+
|
2882
3309
|
# insert connections to the copy list
|
2883
3310
|
lst_connections.each do |line|
|
2884
|
-
selection << line unless selection.include?(line)
|
3311
|
+
selection << line unless selection.include?(line) ||
|
3312
|
+
(complete_only &&
|
3313
|
+
!(selection.include?(line.get_src_shape) &&
|
3314
|
+
selection.include?(line.get_trg_shape)))
|
2885
3315
|
end
|
2886
3316
|
end
|
2887
3317
|
|
@@ -2897,7 +3327,7 @@ module Wx::SF
|
|
2897
3327
|
end
|
2898
3328
|
end
|
2899
3329
|
|
2900
|
-
# Clear all temporary containers
|
3330
|
+
# Clear all temporary containers
|
2901
3331
|
def clear_temporaries
|
2902
3332
|
@current_shapes.clear
|
2903
3333
|
@new_line_shape = nil
|
@@ -2909,19 +3339,42 @@ module Wx::SF
|
|
2909
3339
|
# Assign give shape to parent at given location (if exists)
|
2910
3340
|
# @param [Wx::SF::Shape] shape
|
2911
3341
|
# @param [Wx::Point] parentpos
|
2912
|
-
def
|
3342
|
+
def reparent_dropped_shape(shape, parentpos)
|
2913
3343
|
return unless @diagram
|
2914
|
-
# is shape dropped into accepting shape?
|
2915
|
-
parent_shape = get_shape_at_position(parentpos, 1, SEARCHMODE::UNSELECTED)
|
2916
|
-
|
2917
|
-
parent_shape = nil if parent_shape && !parent_shape.is_child_accepted(shape.class)
|
2918
3344
|
|
2919
|
-
# set new parent
|
3345
|
+
# set new parent if possible
|
2920
3346
|
if shape.has_style?(Shape::STYLE::PARENT_CHANGE) && !shape.is_a?(LineShape)
|
3347
|
+
# is shape dropped into accepting shape?
|
3348
|
+
|
3349
|
+
# get all shapes at drop position in reversed z-order
|
3350
|
+
shapes_at_pos = get_shapes_at_position(parentpos).reverse
|
3351
|
+
# see if we can find a non-LineShape drop target
|
3352
|
+
parent_shape = shapes_at_pos.find do |s|
|
3353
|
+
# consider non-LineShapes that are unselected and not the dropped shape itself or one of it's (grand-)children
|
3354
|
+
!s.is_a?(Wx::SF::LineShape) && !s.selected? && shape != s && !shape.include_child_shape?(s)
|
3355
|
+
end
|
3356
|
+
# if none found consider line shapes
|
3357
|
+
parent_shape = shapes_at_pos.find do |s|
|
3358
|
+
# consider LineShapes that are unselected and not the dropped shape itself or one of it's (grand-)children
|
3359
|
+
s.is_a?(Wx::SF::LineShape) && !s.selected? && shape != s && !shape.include_child_shape?(s)
|
3360
|
+
end unless parent_shape
|
3361
|
+
# In case the matching shape does not accept the dropped child and has style PROPAGATE_DROPPING
|
3362
|
+
# see if this shape has a parent that does also matches the position and DOES accept the child.
|
3363
|
+
# This allows dropping shapes onto child shapes inside a (container) shapes like
|
3364
|
+
# grids and/or boxes.
|
3365
|
+
while parent_shape && !parent_shape.is_child_accepted(shape.class)
|
3366
|
+
parent_shape = parent_shape.has_style?(Shape::STYLE::PROPAGATE_DROPPING) ? parent_shape.parent_shape : nil
|
3367
|
+
parent_shape = nil if parent_shape && !parent_shape.get_bounding_box.contains?(parentpos)
|
3368
|
+
end
|
3369
|
+
# parent_shape = nil if parent_shape && !parent_shape.is_child_accepted(shape.class)
|
3370
|
+
|
2921
3371
|
prev_parent = shape.get_parent_shape
|
2922
|
-
|
3372
|
+
|
2923
3373
|
if parent_shape
|
2924
|
-
|
3374
|
+
# in rare cases (where childs are expanded to fill a parent and have PROPAGATE_SELECTION)
|
3375
|
+
# the matched drop parent may actually a child of the shape being dropped
|
3376
|
+
# guard against that (since that would lead to illegal circular references)
|
3377
|
+
if parent_shape != shape && !shape.include_child_shape?(parent_shape, true)
|
2925
3378
|
# update relative position to new parent
|
2926
3379
|
apos = shape.get_absolute_position - parent_shape.get_absolute_position
|
2927
3380
|
shape.set_relative_position(apos)
|
@@ -2938,9 +3391,9 @@ module Wx::SF
|
|
2938
3391
|
@diagram.reparent_shape(shape, parent_shape)
|
2939
3392
|
end
|
2940
3393
|
end
|
2941
|
-
|
3394
|
+
|
2942
3395
|
prev_parent.update if prev_parent
|
2943
|
-
parent_shape.update if parent_shape
|
3396
|
+
parent_shape.update if parent_shape && parent_shape != prev_parent
|
2944
3397
|
end
|
2945
3398
|
end
|
2946
3399
|
|
@@ -3003,7 +3456,7 @@ module Wx::SF
|
|
3003
3456
|
else
|
3004
3457
|
@working_mode = MODE::READY
|
3005
3458
|
end
|
3006
|
-
|
3459
|
+
|
3007
3460
|
event.skip
|
3008
3461
|
end
|
3009
3462
|
|
@@ -3011,16 +3464,16 @@ module Wx::SF
|
|
3011
3464
|
# @param [Wx::MouseEvent] event Mouse event
|
3012
3465
|
def _on_enter_window(event)
|
3013
3466
|
@prev_mouse_pos = event.get_position
|
3014
|
-
|
3467
|
+
|
3015
3468
|
lpos = dp2lp(event.get_position)
|
3016
|
-
|
3469
|
+
|
3017
3470
|
case @working_mode
|
3018
3471
|
when MODE::MULTISELECTION
|
3019
3472
|
unless event.left_is_down
|
3020
3473
|
update_multiedit_size
|
3021
3474
|
@shp_multi_edit.show(false)
|
3022
3475
|
@working_mode = MODE::READY
|
3023
|
-
|
3476
|
+
|
3024
3477
|
invalidate_visible_rect
|
3025
3478
|
end
|
3026
3479
|
|
@@ -3030,13 +3483,13 @@ module Wx::SF
|
|
3030
3483
|
if @selected_handle.get_parent_shape.is_a?(LineShape)
|
3031
3484
|
@selected_handle.get_parent_shape.send(:set_line_mode, LineShape::LINEMODE::READY)
|
3032
3485
|
end
|
3033
|
-
|
3486
|
+
|
3034
3487
|
@selected_handle.send(:_on_end_drag, lpos)
|
3035
|
-
|
3488
|
+
|
3036
3489
|
save_canvas_state
|
3037
3490
|
@working_mode = MODE::READY
|
3038
3491
|
@selected_handle = nil
|
3039
|
-
|
3492
|
+
|
3040
3493
|
invalidate_visible_rect
|
3041
3494
|
end
|
3042
3495
|
end
|
@@ -3045,10 +3498,10 @@ module Wx::SF
|
|
3045
3498
|
unless event.left_is_down
|
3046
3499
|
if @selected_handle
|
3047
3500
|
@selected_handle.send(:_on_end_drag, lpos)
|
3048
|
-
|
3501
|
+
|
3049
3502
|
save_canvas_state
|
3050
3503
|
@working_mode = MODE::READY
|
3051
|
-
|
3504
|
+
|
3052
3505
|
invalidate_visible_rect
|
3053
3506
|
end
|
3054
3507
|
end
|
@@ -3056,26 +3509,26 @@ module Wx::SF
|
|
3056
3509
|
when MODE::SHAPEMOVE
|
3057
3510
|
unless event.left_is_down
|
3058
3511
|
lst_selection = get_selected_shapes
|
3059
|
-
|
3512
|
+
|
3060
3513
|
move_shapes_from_negatives
|
3061
3514
|
update_virtual_size
|
3062
|
-
|
3515
|
+
|
3063
3516
|
if lst_selection.size > 1
|
3064
3517
|
update_multiedit_size
|
3065
3518
|
@shp_multi_edit.show(true)
|
3066
3519
|
@shp_multi_edit.show_handles(true)
|
3067
3520
|
end
|
3068
|
-
|
3521
|
+
|
3069
3522
|
lst_selection.each { |shape| shape.send(:_on_end_drag, lpos) }
|
3070
3523
|
|
3071
3524
|
@working_mode = MODE::READY
|
3072
|
-
|
3525
|
+
|
3073
3526
|
invalidate_visible_rect
|
3074
3527
|
end
|
3075
3528
|
end
|
3076
|
-
|
3529
|
+
|
3077
3530
|
refresh_invalidated_rect
|
3078
|
-
|
3531
|
+
|
3079
3532
|
event.skip
|
3080
3533
|
end
|
3081
3534
|
|
@@ -3086,9 +3539,9 @@ module Wx::SF
|
|
3086
3539
|
|
3087
3540
|
event.skip
|
3088
3541
|
end
|
3089
|
-
|
3542
|
+
|
3090
3543
|
# original private event handlers
|
3091
|
-
|
3544
|
+
|
3092
3545
|
# Original private event handler called when the canvas is clicked by
|
3093
3546
|
# left mouse button. The handler calls user-overridable event handler function
|
3094
3547
|
# and skips the event for next possible processing.
|
@@ -3204,7 +3657,7 @@ module Wx::SF
|
|
3204
3657
|
# @see Wx::SF::CanvasDropTarget
|
3205
3658
|
def _on_drop(x, y, deflt, data)
|
3206
3659
|
if data && Wx::SF::ShapeDataObject === data
|
3207
|
-
lst_new_content =
|
3660
|
+
lst_new_content = data.get_as_shapes
|
3208
3661
|
if lst_new_content && !lst_new_content.empty?
|
3209
3662
|
lst_parents_to_update = []
|
3210
3663
|
lpos = dp2lp(Wx::Point.new(x, y))
|
@@ -3217,12 +3670,20 @@ module Wx::SF
|
|
3217
3670
|
end
|
3218
3671
|
|
3219
3672
|
parent = @diagram.get_shape_at_position(lpos, 1, SEARCHMODE::UNSELECTED)
|
3673
|
+
# In case the located shape does not accept ANY children and has style PROPAGATE_DROPPING
|
3674
|
+
# see if this shape has a parent that does also match the position and DOES accept children.
|
3675
|
+
# This allows dropping shapes onto child shapes inside a (container) shapes like
|
3676
|
+
# grids and/or boxes.
|
3677
|
+
while parent&.does_not_accept_children?
|
3678
|
+
parent = parent.has_style?(Shape::STYLE::PROPAGATE_DROPPING) ? parent.parent_shape : nil
|
3679
|
+
parent = nil if parent && !parent.get_bounding_box.contains?(lpos)
|
3680
|
+
end
|
3220
3681
|
|
3221
3682
|
# add each shape to diagram keeping only those that are accepted
|
3222
3683
|
lst_new_content.select! do |shape|
|
3223
3684
|
shape.move_by(dx, dy)
|
3224
3685
|
# do not reparent connection lines
|
3225
|
-
rc = if shape.is_a?(LineShape) && !shape.stand_alone?
|
3686
|
+
rc = if (shape.is_a?(LineShape) && !shape.stand_alone?) || parent.nil?
|
3226
3687
|
@diagram.add_shape(shape,
|
3227
3688
|
nil,
|
3228
3689
|
lp2dp(shape.get_absolute_position.to_point),
|
@@ -3239,7 +3700,7 @@ module Wx::SF
|
|
3239
3700
|
end
|
3240
3701
|
|
3241
3702
|
# verify newly added shapes (may remove shapes from list)
|
3242
|
-
@diagram.send(:
|
3703
|
+
@diagram.send(:on_import, lst_new_content)
|
3243
3704
|
|
3244
3705
|
update_virtual_size # update for new shapes
|
3245
3706
|
|
@@ -3266,7 +3727,7 @@ module Wx::SF
|
|
3266
3727
|
end
|
3267
3728
|
end
|
3268
3729
|
end
|
3269
|
-
|
3730
|
+
|
3270
3731
|
end
|
3271
3732
|
|
3272
3733
|
def _notify_canvas_change(change, *args)
|