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.
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