wxruby3-shapes 0.9.0.pre.beta.3 → 0.9.6
Sign up to get free protection for your applications and to get access to all the features.
- 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)
|