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.
Files changed (97) hide show
  1. checksums.yaml +4 -4
  2. data/INSTALL.md +5 -7
  3. data/README.md +38 -6
  4. data/assets/logo.svg +339 -0
  5. data/assets/logo.xpm +60 -0
  6. data/assets/screenshot.png +0 -0
  7. data/assets/social.png +0 -0
  8. data/bin/wx-shapes +1 -1
  9. data/lib/wx/shapes/arrow_base.rb +4 -11
  10. data/lib/wx/shapes/arrows/circle_arrow.rb +22 -11
  11. data/lib/wx/shapes/arrows/circle_prong_arrow.rb +48 -0
  12. data/lib/wx/shapes/arrows/cross_bar_arrow.rb +57 -0
  13. data/lib/wx/shapes/arrows/cross_bar_circle_arrow.rb +56 -0
  14. data/lib/wx/shapes/arrows/cross_bar_prong_arrow.rb +49 -0
  15. data/lib/wx/shapes/arrows/crossed_circle.rb +46 -0
  16. data/lib/wx/shapes/arrows/cup_arrow.rb +65 -0
  17. data/lib/wx/shapes/arrows/diamond_arrow.rb +8 -13
  18. data/lib/wx/shapes/arrows/double_cross_bar_arrow.rb +27 -0
  19. data/lib/wx/shapes/arrows/filled_arrow.rb +60 -0
  20. data/lib/wx/shapes/arrows/line_arrow.rb +67 -0
  21. data/lib/wx/shapes/arrows/open_arrow.rb +22 -23
  22. data/lib/wx/shapes/arrows/prong_arrow.rb +42 -0
  23. data/lib/wx/shapes/arrows/solid_arrow.rb +21 -35
  24. data/lib/wx/shapes/arrows/square_arrow.rb +37 -0
  25. data/lib/wx/shapes/auto_layout.rb +2 -2
  26. data/lib/wx/shapes/base.rb +1 -1
  27. data/lib/wx/shapes/canvas_history.rb +20 -0
  28. data/lib/wx/shapes/connection_point.rb +10 -6
  29. data/lib/wx/shapes/diagram.rb +98 -78
  30. data/lib/wx/shapes/events.rb +8 -8
  31. data/lib/wx/shapes/printout.rb +3 -16
  32. data/lib/wx/shapes/serializable.rb +2 -436
  33. data/lib/wx/shapes/serialize/wx.rb +30 -18
  34. data/lib/wx/shapes/shape.rb +211 -168
  35. data/lib/wx/shapes/shape_canvas.rb +728 -267
  36. data/lib/wx/shapes/shape_data_object.rb +99 -18
  37. data/lib/wx/shapes/shape_handle.rb +18 -11
  38. data/lib/wx/shapes/shape_list.rb +34 -67
  39. data/lib/wx/shapes/shapes/bitmap_shape.rb +23 -24
  40. data/lib/wx/shapes/shapes/box_shape.rb +389 -0
  41. data/lib/wx/shapes/shapes/circle_shape.rb +19 -22
  42. data/lib/wx/shapes/shapes/control_shape.rb +77 -41
  43. data/lib/wx/shapes/shapes/curve_shape.rb +38 -31
  44. data/lib/wx/shapes/shapes/diamond_shape.rb +7 -17
  45. data/lib/wx/shapes/shapes/edit_text_shape.rb +6 -9
  46. data/lib/wx/shapes/shapes/ellipse_shape.rb +12 -15
  47. data/lib/wx/shapes/shapes/flex_grid_shape.rb +58 -33
  48. data/lib/wx/shapes/shapes/grid_shape.rb +259 -161
  49. data/lib/wx/shapes/shapes/line_shape.rb +155 -161
  50. data/lib/wx/shapes/shapes/manager_shape.rb +77 -0
  51. data/lib/wx/shapes/shapes/multi_sel_rect.rb +8 -8
  52. data/lib/wx/shapes/shapes/ortho_shape.rb +31 -36
  53. data/lib/wx/shapes/shapes/polygon_shape.rb +23 -29
  54. data/lib/wx/shapes/shapes/rect_shape.rb +95 -53
  55. data/lib/wx/shapes/shapes/round_ortho_shape.rb +6 -8
  56. data/lib/wx/shapes/shapes/round_rect_shape.rb +20 -24
  57. data/lib/wx/shapes/shapes/square_shape.rb +14 -17
  58. data/lib/wx/shapes/shapes/text_shape.rb +95 -53
  59. data/lib/wx/shapes/version.rb +1 -1
  60. data/lib/wx/shapes/wx.rb +16 -7
  61. data/lib/wx/wx-shapes/cmd/test.rb +1 -1
  62. data/samples/demo/arrows.json +1 -0
  63. data/samples/demo/arrows.yaml +793 -0
  64. data/samples/demo/art/HBox.xpm +22 -0
  65. data/samples/demo/art/VBox.xpm +22 -0
  66. data/samples/demo/art/logo.xpm +60 -0
  67. data/samples/demo/class.json +1 -0
  68. data/samples/demo/class.yaml +5631 -0
  69. data/samples/demo/demo.rb +301 -91
  70. data/samples/demo/dialogs.rb +1405 -0
  71. data/samples/demo/erd.json +1 -0
  72. data/samples/demo/erd.yaml +4072 -0
  73. data/samples/demo/frame_canvas.rb +409 -33
  74. data/samples/sample1/art/logo.xpm +60 -0
  75. data/samples/sample1/sample.rb +11 -11
  76. data/samples/sample2/art/logo.xpm +60 -0
  77. data/samples/sample2/sample.rb +2 -2
  78. data/samples/sample2/sample_shape.rb +15 -15
  79. data/samples/sample3/art/logo.xpm +60 -0
  80. data/samples/sample3/sample.rb +3 -3
  81. data/samples/sample4/art/logo.xpm +60 -0
  82. data/samples/sample4/sample.rb +2 -2
  83. data/tests/lib/wxapp_runner.rb +4 -0
  84. data/tests/serializer_tests.rb +8 -441
  85. data/tests/test_grid_shapes.rb +2 -2
  86. data/tests/test_serialize_xml.rb +17 -0
  87. data/tests/test_serialize_yaml.rb +2 -2
  88. metadata +78 -28
  89. data/lib/wx/shapes/serialize/core.rb +0 -40
  90. data/lib/wx/shapes/serialize/id.rb +0 -82
  91. data/lib/wx/shapes/serializer/json.rb +0 -258
  92. data/lib/wx/shapes/serializer/yaml.rb +0 -125
  93. data/samples/demo/art/sample.xpm +0 -251
  94. data/samples/sample1/art/sample.xpm +0 -251
  95. data/samples/sample2/art/sample.xpm +0 -251
  96. data/samples/sample3/art/sample.xpm +0 -251
  97. data/samples/sample4/art/sample.xpm +0 -251
@@ -4,9 +4,9 @@
4
4
  module Wx::SF
5
5
 
6
6
  # Class encapsulating data object used during clipboard operations with shapes.
7
- class ShapeDataObject < Wx::DataObjectSimpleBase
7
+ class ShapeDataObject < Wx::DataObject
8
8
 
9
- DataFormatID = 'ShapeFrameWorkDataFormat1_0'
9
+ DataFormatID = Wx::DataFormat.new('ShapeFrameWorkDataFormat1_0')
10
10
 
11
11
  # @overload initialize()
12
12
  # Default constructor
@@ -14,30 +14,111 @@ module Wx::SF
14
14
  # User constructor
15
15
  # @param [Array<Wx::SF::Shape>] selection List of shapes which should be stored in the data object
16
16
  def initialize(selection = nil)
17
- super(Wx::DataFormat.new(DataFormatID))
18
- @data = selection ? selection.serialize : ''
17
+ unless selection.nil? || (selection.is_a?(Array) && selection.all? { |e| e.is_a?(Shape) })
18
+ raise SFException, 'Expected nil or Array<Wx::SF::Shape>'
19
+ end
20
+ super()
21
+ @shapes = selection
22
+ @data = nil
23
+ @format = DataFormatID.get_type
19
24
  end
20
25
 
21
- # Returns size of the data object
22
- # @return [Integer]
23
- def _get_data_size
24
- @data.bytesize
26
+ def get_as_text
27
+ if @format == DataFormatID.get_type
28
+ @data ||= (@shapes ? @shapes.serialize(format: :yaml) : nil)
29
+ end
30
+ @data || ''
25
31
  end
26
32
 
27
- # Exports data from data object.
28
- # @return [Boolean] true on success, otherwise false
29
- def _get_data
30
- @data
33
+ def get_as_shapes
34
+ if @format == Wx::DataFormatId::DF_TEXT || @format == Wx::DataFormatId::DF_UNICODETEXT
35
+ @shapes ||= (@data && @data.size>0 ? FIRM.deserialize(@data, format: :yaml) : nil)
36
+ end
37
+ @shapes || []
31
38
  end
32
39
 
33
- # Function should inport data from data object from given buffer.
34
- # @param [String] buf External input data buffer
35
- # @return [Boolean] true on success, otherwise false
36
- def _set_data(buf)
37
- @data = buf ? buf : ''
38
- true
40
+ # List all the formats that we support. By default, the first is
41
+ # treated as the 'preferred' format; this can be overridden by
42
+ # providing a get_preferred format.
43
+ def get_all_formats(direction)
44
+ [ DataFormatID, Wx::DF_TEXT, Wx::DF_UNICODETEXT ]
39
45
  end
40
46
 
47
+ # Do setting the data
48
+ def set_data(format, the_data)
49
+ case format.get_type
50
+ when DataFormatID.get_type
51
+ @shapes = if the_data.size > 0
52
+ begin
53
+ FIRM.deserialize(the_data, format: :yaml)
54
+ rescue Exception
55
+ $stderr.puts "#{$!}\n#{$!.backtrace.join("\n")}"
56
+ return false
57
+ end
58
+ else
59
+ nil
60
+ end
61
+ @data = nil
62
+ @format = format.get_type
63
+ true
64
+ when Wx::DataFormatId::DF_TEXT, Wx::DataFormatId::DF_UNICODETEXT
65
+ @data = the_data
66
+ @shapes = nil
67
+ @format = format.get_type
68
+ true
69
+ else
70
+ false
71
+ end
72
+ end
73
+
74
+ def get_data_size(format)
75
+ case format.get_type
76
+ when Wx::DataFormatId::DF_TEXT, Wx::DataFormatId::DF_UNICODETEXT
77
+ @data ? @data.size : 0
78
+ when DataFormatID.get_type
79
+ get_as_text.bytesize
80
+ else
81
+ 0
82
+ end
83
+ end
84
+
85
+ # Do getting the data
86
+ def get_data_here(format)
87
+ case format.get_type
88
+ when Wx::DataFormatId::DF_TEXT, Wx::DataFormatId::DF_UNICODETEXT
89
+ @data
90
+ when DataFormatID.get_type
91
+ begin
92
+ get_as_text
93
+ rescue Exception
94
+ $stderr.puts "#{$!}\n#{$!.backtrace.join("\n")}"
95
+ nil
96
+ end
97
+ else
98
+ nil
99
+ end
100
+ end
101
+
102
+ # # Returns size of the data object
103
+ # # @return [Integer]
104
+ # def _get_data_size
105
+ # @data.bytesize
106
+ # end
107
+ #
108
+ # # Exports data from data object.
109
+ # # @return [Boolean] true on success, otherwise false
110
+ # def _get_data
111
+ # @data
112
+ # end
113
+ #
114
+ # # Function should inport data from data object from given buffer.
115
+ # # @param [String] buf External input data buffer
116
+ # # @return [Boolean] true on success, otherwise false
117
+ # def _set_data(buf)
118
+ # @data = buf ? buf : ''
119
+ # true
120
+ # end
121
+
41
122
  end
42
123
 
43
124
  end
@@ -26,6 +26,16 @@ module Wx::SF
26
26
  UNDEF = self.new(11)
27
27
  end
28
28
 
29
+ class << self
30
+ def handle_brush
31
+ if ShapeCanvas.gc_enabled?
32
+ @gc_brush ||= Wx::Brush.new(Wx::Colour.new(0, 0, 0, 128))
33
+ else
34
+ @dc_brush ||= Wx::BLACK_BRUSH.dup
35
+ end
36
+ end
37
+ end
38
+
29
39
  # Constructor
30
40
  # @param [Wx::Shape] parent Parent shape
31
41
  # @param [TYPE] type Handle type
@@ -131,17 +141,14 @@ module Wx::SF
131
141
  # @param [Wx::DC] dc Device context where the handle will be drawn
132
142
  def draw_normal(dc)
133
143
  dc.with_pen(Wx::PLATFORM == 'WXGTK' ? Wx::TRANSPARENT_PEN : Wx::BLACK_PEN) do
134
- if ShapeCanvas::gc_enabled?
135
- dc.brush = Wx::Brush.new(Wx::Colour.new(0, 0, 0, 128))
136
- else
137
- dc.brush = Wx::BLACK_BRUSH
138
- # dc.logical_function = Wx::RasterOperationMode::INVERT
139
- end
144
+ dc.with_brush(Handle.handle_brush) do
145
+ # unless ShapeCanvas::gc_enabled?
146
+ # dc.logical_function = Wx::RasterOperationMode::INVERT
147
+ # end
140
148
 
141
- dc.draw_rectangle(handle_rect)
142
- # dc.logical_function = Wx::RasterOperationMode::COPY
143
-
144
- dc.brush = Wx::NULL_BRUSH
149
+ dc.draw_rectangle(handle_rect)
150
+ # dc.logical_function = Wx::RasterOperationMode::COPY
151
+ end
145
152
  end
146
153
  end
147
154
 
@@ -161,7 +168,7 @@ module Wx::SF
161
168
 
162
169
  # Set parent shape.
163
170
  # @param [Wx::Shape] parent parent shape to set
164
- def parent_shape=(parent)
171
+ def set_parent_shape(parent)
165
172
  @parent_shape = parent
166
173
  end
167
174
 
@@ -2,13 +2,14 @@
2
2
  # Copyright (c) M.J.N. Corino, The Netherlands
3
3
 
4
4
  require 'wx/shapes/serializable'
5
+ require 'set'
5
6
 
6
7
  module Wx::SF
7
8
 
8
9
  # This class implements an indexed container for unique, non-nil, shapes (no duplicates).
9
10
  class ShapeList
10
11
 
11
- include Serializable
12
+ include FIRM::Serializable
12
13
  include ::Enumerable
13
14
 
14
15
  property :list
@@ -19,19 +20,15 @@ module Wx::SF
19
20
  if enum
20
21
  if enum.is_a?(ShapeList)
21
22
  @list = enum.instance_variable_get('@list').dup
22
- @index = enum.instance_variable_get('@index').dup
23
23
  elsif enum.is_a?(::Enumerable)
24
- @list = []
25
- @index = {}
24
+ @list = ::Set.new
26
25
  enum.each { |elem| self << elem }
27
26
  else
28
- @list = []
29
- @index = {}
27
+ @list = ::Set.new
30
28
  self << enum
31
29
  end
32
30
  else
33
- @list = []
34
- @index = {}
31
+ @list = ::Set.new
35
32
  end
36
33
  end
37
34
 
@@ -42,17 +39,21 @@ module Wx::SF
42
39
  # @yieldparam [Shape] shape
43
40
  # @return [self]
44
41
  def each(&block)
45
- @list.each(&block)
46
- self
42
+ if block_given?
43
+ @list.each(&block)
44
+ self
45
+ else
46
+ @list.each
47
+ end
47
48
  end
48
49
 
49
50
  # Recursively collects shapes and returns collection.
50
51
  # @param [Array<Shape>] collection container to return collected shapes in
51
52
  def all(collection = [])
52
- @list.inject(collection) { |list, shape| shape.instance_variable_get('@child_shapes').all(list << shape) }
53
+ @list.inject(collection.concat(@list.to_a)) { |list, shape| shape.instance_variable_get('@child_shapes').all(list) }
53
54
  end
54
55
 
55
- # Returns true if the no shapes are contained, false otherwise.
56
+ # Returns true if no shapes are contained, false otherwise.
56
57
  # @return [Boolean]
57
58
  def empty?
58
59
  @list.empty?
@@ -62,97 +63,63 @@ module Wx::SF
62
63
  # @return [self]
63
64
  def clear
64
65
  @list.clear
65
- @index.clear
66
66
  self
67
67
  end
68
68
 
69
69
  # Appends a new shape to the list if not yet in list.
70
+ # Does *not* perform a recursive check.
70
71
  # @param [Shape] shape shape to add
71
72
  # @return [self]
72
73
  def append(shape)
73
- unless @index.has_key?(check_elem(shape).id)
74
+ unless @list.include?(check_elem(shape))
74
75
  @list << shape
75
- @index[shape.id] = shape
76
76
  end
77
77
  self
78
78
  end
79
79
  alias :push :append
80
80
  alias :<< :append
81
81
 
82
- # Removes the first shape from the list (if any) and returns that.
83
- # @return [Shape,nil] removed shape or nil if list empty
84
- def shift
85
- return nil if @list.empty?
86
- @index.delete(@list.shift.id)
87
- end
88
-
89
- # Removes the last shape from the list (if any) and returns that.
90
- # @return [Shape,nil] removed shape or nil if list empty
91
- def pop
92
- return nil if @list.empty?
93
- @index.delete(@list.pop.id)
94
- end
95
-
96
- # Removes a shape matching the key given from the list and returns that.
97
- # @param [Shape,Serializable::ID] key shape or shape ID to match
82
+ # Removes the given shape from the list and returns that.
83
+ # @param [Shape] shape shape to match
98
84
  # @return [Shape,nil] removed shape or nil if none matched
99
- def delete(key)
100
- if key.is_a?(Shape)
101
- return @list.delete(key) if @index.delete(key.id)
102
- elsif key.is_a?(Serializable::ID)
103
- return @list.delete(@index.delete(key)) if @index.has_key?(key)
85
+ def delete(shape)
86
+ if @list.include?(check_elem(shape))
87
+ @list.delete(shape)
88
+ shape
89
+ else
90
+ nil
104
91
  end
105
- nil
106
92
  end
107
93
 
108
- # Returns true if a shape matches the given key or false if no shape matches.
109
- # @param [Shape,Serializable::ID] key shape or shape ID to match
94
+ # Returns true if the given shape is included in the list.
95
+ # Performs a recursive search in case :recursive is true.
96
+ # @param [Shape] shape shape to match
110
97
  # @param [Boolean] recursive pass true to search recursively, false for non-recursive
111
98
  # @return [Boolean]
112
- def include?(key, recursive = false)
113
- found = if key.is_a?(Serializable::ID)
114
- @index.has_key?(key)
115
- else
116
- @list.include?(key)
117
- end
118
- found || (recursive && @list.any? { |child| child.instance_variable_get('@child_shapes').include?(key, recursive) })
119
- end
120
-
121
- # Returns the shape matching the given key or nil if no shape matches.
122
- # Does not modify the list.
123
- # @param [Integer,Serializable::ID] key shape list index or shape ID to match
124
- # @param [Boolean] recursive pass true to search recursively, false for non-recursive
125
- # @return [Shape,nil] matched shape or nil if none matched
126
- def get(key, recursive = false)
127
- shape = if key.is_a?(Serializable::ID)
128
- @index[key]
129
- else
130
- @list.at(key.to_i)
131
- end
132
- shape || (recursive && @list.find { |child| child.get(key, recursive) })
99
+ def include?(shape, recursive = false)
100
+ found = @list.include?(check_elem(shape))
101
+ found || (recursive && @list.any? { |child| child.include_child_shape?(shape, recursive) })
133
102
  end
134
- alias :[] :get
135
103
 
136
104
  private
137
105
 
138
- # Get shape array. Serialization only.
139
- # @return [Array<Shape>]
106
+ # Get shape set. Serialization only.
107
+ # @return [Set<Shape>]
140
108
  def get_list
141
109
  @list
142
110
  end
143
111
 
144
- # Set shape array from deserialization.
145
- # @param [Array<Shape>] list
112
+ # Set shape set from deserialization.
113
+ # @param [Set<Shape>] list
146
114
  def set_list(list)
147
115
  @list = list
148
- @list.each { |shape| @index[shape.id] = shape }
149
116
  end
150
117
 
151
118
  # Check intended list item
152
119
  # @param [Shape] shape intended list item
153
120
  # @return [Shape] checked shape
154
121
  def check_elem(shape)
155
- ::Kernel.raise TypeError, 'Expected a Wx::SF::Shape' unless shape.is_a?(Wx::SF::Shape)
122
+ ::Kernel.raise TypeError, "Expected a Wx::SF::Shape, got #{shape}" unless shape.is_a?(Wx::SF::Shape)
156
123
  shape
157
124
  end
158
125
 
@@ -13,32 +13,22 @@ module Wx::SF
13
13
 
14
14
  property :can_scale, :bitmap
15
15
 
16
- # @overload initialize()
17
- # Default constructor.
18
- # @overload initialize(pos, bmp_path, diagram)
19
- # User constructor.
20
- # @param [Wx::RealPoint] pos Initial position
21
- # @param [String] bmp_path Bitmap path
22
- # @param [Wx::SF::Diagram] diagram parent diagram
23
- def initialize(*args)
16
+ # Constructor.
17
+ # @param [Wx::RealPoint,Wx::Point] pos Initial position
18
+ # @param [String] bmp_path Bitmap path
19
+ # @param [Wx::SF::Diagram] diagram parent diagram
20
+ def initialize(pos = Shape::DEFAULT::POSITION, bmp_path = nil, diagram: nil)
21
+ super(pos, diagram: diagram)
24
22
  @bitmap = Wx::NULL_BITMAP
25
23
  @art_path = @art_section = nil
26
- if args.empty?
27
- super
28
- @bitmap_path = nil
29
- @original_bitmap = @bitmap = nil
30
- @bitmap_type = nil
31
- else
32
- pos, bmp_path, diagram = args
33
- super(pos, RectShape::DEFAULT::SIZE.dup, diagram)
34
- create_from_file(bmp_path)
35
- end
24
+ @bitmap_path = bmp_path
25
+ create_from_file(bmp_path) if bmp_path
36
26
  @rescale_in_progress = false
37
27
  @can_scale = true
38
28
  end
39
29
 
40
- # Get full name of a source BMP file.
41
- # @return [String] String containing full file name
30
+ # Get full name of a source BMP file (if set).
31
+ # @return [String,nil] String containing full file name
42
32
  def get_bitmap_path
43
33
  @bitmap_path
44
34
  end
@@ -80,7 +70,16 @@ module Wx::SF
80
70
  success = @bitmap.load_file(path, type ? type : Wx::BITMAP_TYPE_ANY)
81
71
  if success
82
72
  p = Pathname.new(art_path)
83
- @art_path = p.relative? ? art_path : p.relative_path_from(Dir.getwd).to_s
73
+ if Wx::PLATFORM == 'WXMSW'
74
+ # take possibility of different drive into account
75
+ @art_path = if p.relative? || art_path[0] != Dir.getwd[0]
76
+ art_path
77
+ else
78
+ p.relative_path_from(Dir.getwd).to_s
79
+ end
80
+ else
81
+ @art_path = p.relative? ? art_path : p.relative_path_from(Dir.getwd).to_s
82
+ end
84
83
  @art_section = art_section
85
84
  end
86
85
  else
@@ -143,7 +142,7 @@ module Wx::SF
143
142
  def do_begin_handle
144
143
  if @can_scale
145
144
  @rescale_in_progress = true
146
- @prev_pos = get_absolute_position
145
+ @prev_pos = get_absolute_position.dup
147
146
  end
148
147
  end
149
148
 
@@ -197,7 +196,7 @@ module Wx::SF
197
196
  _draw_bitmap(dc, get_absolute_position.to_point)
198
197
 
199
198
  dc.with_brush(Wx::TRANSPARENT_BRUSH) do
200
- dc.with_pen(Wx::Pen.new(@hover_color, 1)) do
199
+ dc.with_pen(Wx::Pen.new(hover_colour, 1)) do
201
200
  dc.draw_rectangle(get_absolute_position.to_point, @rect_size.to_size)
202
201
  end
203
202
  end
@@ -210,7 +209,7 @@ module Wx::SF
210
209
  _draw_bitmap(dc, get_absolute_position.to_point)
211
210
 
212
211
  dc.with_brush(Wx::TRANSPARENT_BRUSH) do
213
- dc.with_pen(Wx::Pen.new(@hover_color, 2)) do
212
+ dc.with_pen(Wx::Pen.new(hover_colour, 2)) do
214
213
  dc.draw_rectangle(get_absolute_position.to_point, @rect_size.to_size)
215
214
  end
216
215
  end