wxruby3-shapes 0.9.0.pre.beta.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (112) hide show
  1. checksums.yaml +7 -0
  2. data/.yardopts +12 -0
  3. data/CREDITS.md +18 -0
  4. data/INSTALL.md +39 -0
  5. data/LICENSE +21 -0
  6. data/README.md +118 -0
  7. data/assets/screenshot.png +0 -0
  8. data/bin/wx-shapes +9 -0
  9. data/lib/wx/shapes/arrow_base.rb +86 -0
  10. data/lib/wx/shapes/arrows/circle_arrow.rb +39 -0
  11. data/lib/wx/shapes/arrows/diamond_arrow.rb +33 -0
  12. data/lib/wx/shapes/arrows/open_arrow.rb +56 -0
  13. data/lib/wx/shapes/arrows/solid_arrow.rb +69 -0
  14. data/lib/wx/shapes/art/shape_canvas/page.xpm +73 -0
  15. data/lib/wx/shapes/auto_layout.rb +358 -0
  16. data/lib/wx/shapes/base.rb +33 -0
  17. data/lib/wx/shapes/canvas_history.rb +84 -0
  18. data/lib/wx/shapes/connection_point.rb +238 -0
  19. data/lib/wx/shapes/core.rb +19 -0
  20. data/lib/wx/shapes/diagram.rb +659 -0
  21. data/lib/wx/shapes/events.rb +389 -0
  22. data/lib/wx/shapes/printout.rb +136 -0
  23. data/lib/wx/shapes/serializable.rb +440 -0
  24. data/lib/wx/shapes/serialize/core.rb +40 -0
  25. data/lib/wx/shapes/serialize/id.rb +82 -0
  26. data/lib/wx/shapes/serialize/wx.rb +104 -0
  27. data/lib/wx/shapes/serializer/json.rb +258 -0
  28. data/lib/wx/shapes/serializer/yaml.rb +125 -0
  29. data/lib/wx/shapes/shape.rb +2129 -0
  30. data/lib/wx/shapes/shape_canvas.rb +3285 -0
  31. data/lib/wx/shapes/shape_data_object.rb +43 -0
  32. data/lib/wx/shapes/shape_handle.rb +287 -0
  33. data/lib/wx/shapes/shape_list.rb +161 -0
  34. data/lib/wx/shapes/shapes/bitmap_shape.rb +257 -0
  35. data/lib/wx/shapes/shapes/circle_shape.rb +136 -0
  36. data/lib/wx/shapes/shapes/control_shape.rb +483 -0
  37. data/lib/wx/shapes/shapes/curve_shape.rb +231 -0
  38. data/lib/wx/shapes/shapes/diamond_shape.rb +62 -0
  39. data/lib/wx/shapes/shapes/edit_text_shape.rb +317 -0
  40. data/lib/wx/shapes/shapes/ellipse_shape.rb +106 -0
  41. data/lib/wx/shapes/shapes/flex_grid_shape.rb +78 -0
  42. data/lib/wx/shapes/shapes/grid_shape.rb +404 -0
  43. data/lib/wx/shapes/shapes/line_shape.rb +907 -0
  44. data/lib/wx/shapes/shapes/multi_sel_rect.rb +214 -0
  45. data/lib/wx/shapes/shapes/ortho_shape.rb +357 -0
  46. data/lib/wx/shapes/shapes/polygon_shape.rb +294 -0
  47. data/lib/wx/shapes/shapes/rect_shape.rb +378 -0
  48. data/lib/wx/shapes/shapes/round_ortho_shape.rb +131 -0
  49. data/lib/wx/shapes/shapes/round_rect_shape.rb +142 -0
  50. data/lib/wx/shapes/shapes/square_shape.rb +119 -0
  51. data/lib/wx/shapes/shapes/text_shape.rb +324 -0
  52. data/lib/wx/shapes/thumbnail.rb +234 -0
  53. data/lib/wx/shapes/version.rb +12 -0
  54. data/lib/wx/shapes/wx.rb +29 -0
  55. data/lib/wx/shapes.rb +18 -0
  56. data/lib/wx/wx-shapes/base.rb +87 -0
  57. data/lib/wx/wx-shapes/cmd/sampler.rb +58 -0
  58. data/lib/wx/wx-shapes/cmd/test.rb +27 -0
  59. data/rakelib/yard/templates/default/fulldoc/html/css/wxruby3.css +7 -0
  60. data/rakelib/yard/templates/default/layout/html/setup.rb +5 -0
  61. data/rakelib/yard/yard/relative_markdown_links/version.rb +8 -0
  62. data/rakelib/yard/yard/relative_markdown_links.rb +39 -0
  63. data/rakelib/yard/yard-custom-templates.rb +2 -0
  64. data/rakelib/yard/yard-relative_markdown_links.rb +4 -0
  65. data/samples/demo/art/AlignBottom.xpm +35 -0
  66. data/samples/demo/art/AlignCenter.xpm +35 -0
  67. data/samples/demo/art/AlignLeft.xpm +35 -0
  68. data/samples/demo/art/AlignMiddle.xpm +35 -0
  69. data/samples/demo/art/AlignRight.xpm +35 -0
  70. data/samples/demo/art/AlignTop.xpm +35 -0
  71. data/samples/demo/art/Bitmap.xpm +25 -0
  72. data/samples/demo/art/Circle.xpm +22 -0
  73. data/samples/demo/art/Curve.xpm +21 -0
  74. data/samples/demo/art/Diamond.xpm +22 -0
  75. data/samples/demo/art/EditText.xpm +21 -0
  76. data/samples/demo/art/Ellipse.xpm +22 -0
  77. data/samples/demo/art/FixedRect.xpm +22 -0
  78. data/samples/demo/art/FlexGrid.xpm +22 -0
  79. data/samples/demo/art/GC.xpm +23 -0
  80. data/samples/demo/art/Grid.xpm +22 -0
  81. data/samples/demo/art/Line.xpm +21 -0
  82. data/samples/demo/art/NoSource.xpm +69 -0
  83. data/samples/demo/art/OrthoLine.xpm +21 -0
  84. data/samples/demo/art/Rect.xpm +22 -0
  85. data/samples/demo/art/RoundOrthoLine.xpm +21 -0
  86. data/samples/demo/art/RoundRect.xpm +22 -0
  87. data/samples/demo/art/Shadow.xpm +23 -0
  88. data/samples/demo/art/StandAloneLine.xpm +22 -0
  89. data/samples/demo/art/Text.xpm +21 -0
  90. data/samples/demo/art/Tool.xpm +23 -0
  91. data/samples/demo/art/sample.xpm +251 -0
  92. data/samples/demo/demo.rb +658 -0
  93. data/samples/demo/frame_canvas.rb +422 -0
  94. data/samples/demo/images/motyl.bmp +0 -0
  95. data/samples/demo/images/motyl2.bmp +0 -0
  96. data/samples/sample1/art/sample.xpm +251 -0
  97. data/samples/sample1/sample.rb +263 -0
  98. data/samples/sample2/art/sample.xpm +251 -0
  99. data/samples/sample2/sample.rb +133 -0
  100. data/samples/sample2/sample_canvas.rb +35 -0
  101. data/samples/sample2/sample_shape.rb +108 -0
  102. data/samples/sample3/art/sample.xpm +251 -0
  103. data/samples/sample3/sample.rb +281 -0
  104. data/samples/sample4/art/sample.xpm +251 -0
  105. data/samples/sample4/sample.rb +180 -0
  106. data/tests/art/motyl.bmp +0 -0
  107. data/tests/lib/wxapp_runner.rb +64 -0
  108. data/tests/serializer_tests.rb +521 -0
  109. data/tests/test_grid_shapes.rb +42 -0
  110. data/tests/test_serialize.rb +7 -0
  111. data/tests/test_serialize_yaml.rb +17 -0
  112. metadata +242 -0
@@ -0,0 +1,62 @@
1
+ # Wx::SF::DiamondShape - Diamond shape class
2
+ # Copyright (c) M.J.N. Corino, The Netherlands
3
+
4
+ require 'wx/shapes/shapes/polygon_shape'
5
+
6
+ module Wx::SF
7
+
8
+ class DiamondShape < PolygonShape
9
+
10
+ class << self
11
+ def diamond
12
+ @diamond ||= [Wx::RealPoint.new(0,25), Wx::RealPoint.new(50,0), Wx::RealPoint.new(100, 25), Wx::RealPoint.new(50, 50)]
13
+ end
14
+ end
15
+
16
+ # do not serialize because the vertices are assigned fixed in ctor
17
+ excludes :vertices
18
+
19
+ # @overload initialize()
20
+ # Default constructor.
21
+ # @overload initialize(pos, size, diagram)
22
+ # User constructor.
23
+ # @param [Wx::RealPoint] pos Initial position
24
+ # @param [Wx::SF::Diagram] diagram parent diagram
25
+ def initialize(*args)
26
+ if args.empty?
27
+ super
28
+ set_vertices(DiamondShape.diamond)
29
+ else
30
+ super(DiamondShape.diamond, *args)
31
+ end
32
+ end
33
+
34
+ # Test whether the given point is inside the shape. The function
35
+ # can be overridden if necessary.
36
+ # @param [Wx::Point] pos Examined point
37
+ # @return [Boolean] true if the point is inside the shape area, otherwise false
38
+ def contains?(pos)
39
+ bb_rct = get_bounding_box
40
+ return false unless bb_rct.contains?(pos)
41
+
42
+ center = get_center
43
+ k = (bb_rct.height/2).to_f/(bb_rct.width/2).to_f
44
+
45
+ if pos.x <= center.x
46
+ # test left-top quadrant
47
+ return true if (pos.y <= center.y) && (pos.y >= (center.y - (pos.x - bb_rct.left)*k))
48
+ # test left-bottom quadrant
49
+ return true if (pos.y >= center.y) && (pos.y <= (center.y + (pos.x - bb_rct.left)*k))
50
+ else
51
+ # test right-top quadrant
52
+ return true if (pos.y <= center.y) && (pos.y >= (bb_rct.top + (pos.x - center.x)*k))
53
+ # test left-bottom quadrant
54
+ return true if (pos.y >= center.y) && (pos.y <= (bb_rct.bottom - (pos.x - center.x)*k))
55
+ end
56
+
57
+ false
58
+ end
59
+
60
+ end
61
+
62
+ end
@@ -0,0 +1,317 @@
1
+ # Wx::SF::EditTextShape - edit text shape class
2
+ # Copyright (c) M.J.N. Corino, The Netherlands
3
+
4
+ require 'wx/shapes/shapes/text_shape'
5
+
6
+ module Wx::SF
7
+
8
+ CANCEL_TEXT_CHANGES = false
9
+ APPLY_TEXT_CHANGES = true
10
+
11
+ class ContentCtrl < Wx::TextCtrl
12
+
13
+ # Constructor.
14
+ # @param [Wx::Window] parent Pointer to the parent window
15
+ # @param [Integer] id ID of the text control window
16
+ # @param [Wx::SF::EditTextShape] parent_shape Pointer to the parent editable text shape
17
+ # @param [String] content Initial content of the text control
18
+ # @param [Wx::Point] pos Initial position
19
+ # @param [Wx::Size] size Initial size
20
+ # @param [Integer] style Window style
21
+ def initialize(parent, id, parent_shape, content, pos, size, style)
22
+ super(parent, id, content, pos, size, Wx::TE_PROCESS_ENTER | Wx::TE_PROCESS_TAB | Wx::NO_BORDER | style)
23
+ @parent = parent
24
+ @parent_shape = parent_shape
25
+ @prev_content = content
26
+
27
+ evt_kill_focus :on_kill_focus
28
+ evt_key_down :on_key_down
29
+
30
+ set_insertion_point_end
31
+ if @parent_shape
32
+ # update the font size in accordance to the canvas scale
33
+ font = @parent_shape.get_font
34
+ font.set_point_size((font.get_point_size * @parent_shape.get_parent_canvas.get_scale).to_i)
35
+
36
+ set_font(font)
37
+ set_background_colour(Wx::Colour.new(200, 200, 200))
38
+ set_focus
39
+ end
40
+ end
41
+
42
+ # Finish the editing process/
43
+ # @param [Boolean] apply If true then changes made in edited text will be applied on text shape, otherwise it will be canceled
44
+ def quit(apply = APPLY_TEXT_CHANGES)
45
+ self.hide
46
+
47
+ if @parent_shape
48
+ @parent_shape.send(:set_text_ctrl, nil)
49
+ @parent_shape.set_style(@parent_shape.send(:get_current_state))
50
+
51
+ # save canvas state if the textctrl content has changed...
52
+ if apply && @prev_content != get_value
53
+ @parent_shape.set_text(get_value)
54
+ @prev_content = get_value
55
+
56
+ # inform parent shape canvas about text change...
57
+ @parent_shape.get_parent_canvas.on_text_change(@parent_shape)
58
+ @parent_shape.get_parent_canvas.save_canvas_state
59
+ end
60
+
61
+ @parent_shape.update
62
+ @parent_shape.get_parent_canvas.refresh
63
+ end
64
+
65
+ self.destroy
66
+ end
67
+
68
+ protected
69
+
70
+ # Event handler called if the text control lost the focus.
71
+ # @param [Wx::FocusEvent] _event Reference to the event class instance
72
+ def on_kill_focus(_event)
73
+ # noop
74
+ end
75
+
76
+ # Event handler called if the key was pressed in the text control.
77
+ # @param [Wx::KeyEvent] event Reference to the event class instance
78
+ def on_key_down(event)
79
+ case event.get_key_code
80
+ when Wx::K_ESCAPE
81
+ quit(CANCEL_TEXT_CHANGES)
82
+ when Wx::K_TAB
83
+ quit(APPLY_TEXT_CHANGES)
84
+ when Wx::K_RETURN
85
+ # enter new line if SHIFT key was pressed together with the ENTER key
86
+ if Wx::get_key_state(Wx::K_SHIFT)
87
+ event.skip
88
+ else
89
+ quit(APPLY_TEXT_CHANGES)
90
+ end
91
+ else
92
+ event.skip
93
+ end
94
+ end
95
+
96
+ end
97
+
98
+ # Auxiliary class providing necessary functionality needed for dialog-based
99
+ # modification of a content of the text shape.
100
+ # @see EditTextShape
101
+ class DetachedContentCtrl < Wx::Dialog
102
+
103
+ # Constructor.
104
+ # @param [Wx::Window] parent Pointer to the parent window
105
+ # @param [Integer] id ID of the text control window
106
+ # @param [String] title Dialog's title
107
+ # @param [Wx::Point] pos Initial position
108
+ # @param [Wx::Size] size Initial size
109
+ # @param [Integer] style Window style
110
+ def initialize(parent, id = Wx::ID_ANY, title = 'Edit content',
111
+ pos = Wx::DEFAULT_POSITION, size = Wx::DEFAULT_SIZE,
112
+ style = Wx::DEFAULT_DIALOG_STYLE|Wx::RESIZE_BORDER)
113
+ set_size_hints(Wx::Size.new(-1,-1), Wx::DEFAULT_SIZE)
114
+
115
+ main_sizer = Wx::VBoxSizer.new
116
+
117
+ @text = Wx::TextCtrl.new(self, Wx::ID_ANY, '', Wx::DEFAULT_POSITION, [350,100], Wx::TE_MULTILINE)
118
+ @text.set_min_size([350,100])
119
+
120
+ main_sizer.add(@text, 1, Wx::ALL|Wx::EXPAND, 5)
121
+
122
+ button_sizer = Wx::StdDialogButtonSizer.new
123
+ button_sizer_ok = Wx::Button.new(self, Wx::ID_OK)
124
+ button_sizer.add_button(button_sizer_ok)
125
+ button_sizer_cancel = Wx::Button.new(self, Wx::ID_CANCEL)
126
+ button_sizer.add_button(button_sizer_cancel)
127
+ button_sizer.realize
128
+ main_sizer.add(button_sizer, 0, Wx::ALIGN_RIGHT|Wx::BOTTOM|Wx::RIGHT, 5)
129
+
130
+ set_sizer(main_sizer)
131
+ layout
132
+ main_sizer.fit(self)
133
+
134
+ centre(Wx::BOTH)
135
+ end
136
+
137
+ # Set content of dialog's text edit control.
138
+ # @param [String] txt Text content
139
+ def set_content(txt)
140
+ @text.set_value(txt)
141
+ end
142
+
143
+ # Get content of dialog's text edit control.
144
+ # @return [String] Edited text
145
+ def get_content
146
+ @text.get_value
147
+ end
148
+
149
+ end
150
+
151
+ # Class encapsulating the editable text shape. It extends the basic text shape.
152
+ # @see Wx::SF::TextShape
153
+ class EditTextShape < TextShape
154
+
155
+ class EDITTYPE < Wx::Enum
156
+ INPLACE = self.new(0)
157
+ DIALOG = self.new(1)
158
+ DISABLED = self.new(1)
159
+ end
160
+
161
+ # Default values
162
+ module DEFAULT
163
+ # Default value of EditTextShape @force_multiline data member
164
+ FORCE_MULTILINE = false
165
+ # Default value of EditTextShape @edit_type data member
166
+ EDIT_TYPE = EDITTYPE::INPLACE
167
+ end
168
+
169
+ property :force_multiline, :edit_type
170
+
171
+ # @overload initialize()
172
+ # Default constructor.
173
+ # @overload initialize(pos, txt, diagram)
174
+ # User constructor.
175
+ # @param [Wx::RealPoint] pos Initial position
176
+ # @param [String] txt Initial content
177
+ # @param [Wx::SF::Diagram] diagram parent diagram
178
+ def initialize(*args)
179
+ super
180
+ @text_ctrl = nil
181
+ @force_multiline = DEFAULT::FORCE_MULTILINE
182
+ @edit_type = DEFAULT::EDIT_TYPE
183
+ @current_state = 0
184
+ end
185
+
186
+ attr_reader :force_multiline
187
+
188
+ # Set way how the text shape's content can be edited.
189
+ # @param [EDITTYPE] type Edit control type
190
+ # @see EDITTYPE
191
+ def set_edit_type(type)
192
+ @edit_type = type
193
+ end
194
+ alias :edit_type= :set_edit_type
195
+
196
+ # Get current type of text shape's edit control.
197
+ # @return [EDITTYPE] Type of edit control
198
+ # @see EDITTYPE
199
+ def get_edit_type
200
+ @edit_type
201
+ end
202
+ alias :edit_type :get_edit_type
203
+
204
+ # Get assigned text control allowing user to change the
205
+ # shape's content directly in the canvas.
206
+ # @return [ContentCtrl] instance of wxSFContentCtrl class
207
+ def get_text_ctrl
208
+ @text_ctrl
209
+ end
210
+ alias :text_ctrl :get_text_ctrl
211
+
212
+ def set_text_ctrl(txt_ctrl)
213
+ @text_ctrl = txt_ctrl
214
+ end
215
+ private :set_text_ctrl
216
+
217
+ # Switch the shape to a label editing mode.
218
+ def edit_label
219
+ if get_parent_canvas
220
+ shp_pos = get_absolute_position
221
+ scale = get_parent_canvas.get_scale
222
+ dx, dy = get_parent_canvas.calc_unscrolled_position(0, 0)
223
+
224
+ case @edit_type
225
+ when EDITTYPE::INPLACE
226
+ shp_bb = get_bounding_box
227
+ style = 0
228
+ style = Wx::TE_MULTILINE if @force_multiline || @text.index("\n")
229
+
230
+ # set minimal control size
231
+ shp_bb.set_width(50) if @text == '' || (style == Wx::TE_MULTILINE && shp_bb.width < 50)
232
+
233
+ @current_state = get_style
234
+ remove_style(STYLE::SIZE_CHANGE)
235
+
236
+ @text_ctrl = ContentCtrl.new(get_parent_canvas, Wx::ID_ANY, self, @text,
237
+ [((shp_pos.x * scale) - dx).to_i, ((shp_pos.y * scale) - dy).to_i],
238
+ [(shp_bb.width * scale).to_i, (shp_bb.height * scale).to_i], style)
239
+
240
+ when EDITTYPE::DIALOG
241
+ prev_text = get_text
242
+
243
+ DetachedContentCtrl(get_parent_canvas) do |text_dlg|
244
+ text_dlg.set_content(prev_text)
245
+
246
+ if text_dlg.show_modal == Wx::ID_OK
247
+ if text_dlg.get_content != prev_text
248
+ set_text(text_dlg.get_content)
249
+
250
+ get_parent_canvas.on_text_change(self)
251
+ get_parent_canvas.save_canvas_state
252
+
253
+ update
254
+ get_parent_canvas.refresh(false)
255
+ end
256
+ end
257
+ end
258
+ end
259
+ end
260
+ end
261
+
262
+ # Force the edit text control to be multiline
263
+ # @param [Boolean] multiline If true then the associated text control will be always multiline
264
+ def set_force_multiline(multiline)
265
+ @force_multiline = multiline
266
+ end
267
+ alias :force_multiline= :set_force_multiline
268
+
269
+ # Event handler called when the shape was double-clicked.
270
+ # The function can be overridden if necessary.
271
+ # @param [Wx::Point] pos Mouse position.
272
+ def on_left_double_click(pos)
273
+ # HINT: override it if necessary...
274
+ edit_label
275
+ end
276
+
277
+ # Event handler called when any key is pressed (in the shape canvas).
278
+ # The function can be overridden if necessary.
279
+ #
280
+ # The function is called by the framework (by the shape canvas).
281
+ # @param [Integer] key The key code
282
+ # @return [Boolean] The function must return true if the default event routine should be called
283
+ # as well, otherwise false
284
+ # @see Shape#on_key
285
+ def on_key(key)
286
+ # HINT: override it if necessary...
287
+ if key == Wx::K_F2
288
+ edit_label if active? && visible?
289
+ end
290
+ super
291
+ end
292
+
293
+ protected
294
+
295
+ # Event handler called by ShapeCanvas to request,report canvas changes.
296
+ # @param [ShapeCanvas::CHANGE] change change type indicator
297
+ # @param [Array] _args any additional arguments
298
+ # @return [Boolean,nil]
299
+ def _on_canvas(change, *_args)
300
+ if change == ShapeCanvas::CHANGE::FOCUS
301
+ text_ctrl = get_text_ctrl
302
+ text_ctrl.quit(APPLY_TEXT_CHANGES) if text_ctrl
303
+ end
304
+ super
305
+ end
306
+
307
+ private
308
+
309
+ # Return cached state
310
+ # @return [Integer]
311
+ def get_current_state
312
+ @current_state
313
+ end
314
+
315
+ end
316
+
317
+ end
@@ -0,0 +1,106 @@
1
+ # Wx::SF::EllipseShape - ellipse shape class
2
+ # Copyright (c) M.J.N. Corino, The Netherlands
3
+
4
+ module Wx::SF
5
+
6
+ # Class encapsulating the ellipse shape. It extends the basic rectangular shape.
7
+ class EllipseShape < RectShape
8
+
9
+ # @overload initialize()
10
+ # Default constructor.
11
+ # @overload initialize(pos, size, diagram)
12
+ # User constructor.
13
+ # @param [Wx::RealPoint] pos Initial position
14
+ # @param [Wx::RealPoint] size Initial size
15
+ # @param [Wx::SF::Diagram] diagram parent diagram
16
+ def initialize(*args)
17
+ super
18
+ end
19
+
20
+ # Test whether the given point is inside the shape. The function
21
+ # can be overridden if necessary.
22
+ # @param [Wx::Point] pos Examined point
23
+ # @return [Boolean] true if the point is inside the shape area, otherwise false
24
+ def contains?(pos)
25
+ a = get_rect_size.x/2
26
+ b = get_rect_size.y/2
27
+ apos = get_absolute_position
28
+
29
+ m = apos.x + a
30
+ n = apos.y + b
31
+
32
+ pos = pos.to_point
33
+ (((pos.x - m)*(pos.x - m))/(a*a) + ((pos.y - n)*(pos.y - n))/(b*b)) < 1
34
+ end
35
+
36
+ # Get intersection point of the shape border and a line leading from
37
+ # 'start' point to 'end_pt' point. The function can be overridden if necessary.
38
+ # @param [Wx::RealPoint] start Starting point of the virtual intersection line
39
+ # @param [Wx::RealPoint] end_pt Ending point of the virtual intersection line
40
+ # @return [Wx::RealPoint] Intersection point
41
+ def get_border_point(start, end_pt)
42
+ start = start.to_real_point; end_pt.to_real_point
43
+ dist = start.distance_to(end_pt)
44
+ center = get_absolute_position + [@rect_size.x/2, @rect_size.y/2]
45
+
46
+ if dist != 0.0
47
+ src_dx = @rect_size.x/2*(end_pt.x-start.x)/dist - (start.x-center.x)
48
+ src_dy = @rect_size.y/2*(end_pt.y-start.y)/dist - (start.y-center.y)
49
+
50
+ Wx::RealPoint.new(start.x + src_dx, start.y + src_dy)
51
+ else
52
+ center
53
+ end
54
+ end
55
+
56
+ protected
57
+
58
+ # Draw the shape in the normal way. The function can be overridden if necessary.
59
+ # @param [Wx::DC] dc Reference to device context where the shape will be drawn to
60
+ def draw_normal(dc)
61
+ dc.with_pen(@border) do
62
+ dc.with_brush(@fill) do
63
+ dc.draw_ellipse(get_absolute_position.to_point, @rect_size.to_size)
64
+ end
65
+ end
66
+ end
67
+
68
+ # Draw the shape in the hover mode (the mouse cursor is above the shape).
69
+ # The function can be overridden if necessary.
70
+ # @param [Wx::DC] dc Reference to device context where the shape will be drawn to
71
+ def draw_hover(dc)
72
+ dc.with_pen(Wx::Pen.new(@hover_color, 1)) do
73
+ dc.with_brush(@fill) do
74
+ dc.draw_ellipse(get_absolute_position.to_point, @rect_size.to_size)
75
+ end
76
+ end
77
+ end
78
+
79
+ # Draw the shape in the highlighted mode (another shape is dragged over this
80
+ # shape and this shape will accept the dragged one if it will be dropped on it).
81
+ # The function can be overridden if necessary.
82
+ # @param [Wx::DC] dc Reference to device context where the shape will be drawn to
83
+ def draw_highlighted(dc)
84
+ dc.with_pen(Wx::Pen.new(@hover_color, 2)) do
85
+ dc.with_brush(@fill) do
86
+ dc.draw_ellipse(get_absolute_position.to_point, @rect_size.to_size)
87
+ end
88
+ end
89
+ end
90
+
91
+ # Draw shadow under the shape. The function can be overridden if necessary.
92
+ # @param [Wx::DC] dc Reference to device context where the shadow will be drawn to
93
+ def draw_shadow(dc)
94
+ if @fill.style != Wx::BrushStyle::BRUSHSTYLE_TRANSPARENT
95
+ dc.with_pen(Wx::TRANSPARENT_PEN) do
96
+ dc.with_brush(get_parent_canvas.get_shadow_fill) do
97
+ dc.draw_ellipse((get_absolute_position + get_parent_canvas.get_shadow_offset).to_point,
98
+ @rect_size.to_size)
99
+ end
100
+ end
101
+ end
102
+ end
103
+
104
+ end
105
+
106
+ end
@@ -0,0 +1,78 @@
1
+ # Wx::SF::FlexGridShape - flexible grid shape class
2
+ # Copyright (c) M.J.N. Corino, The Netherlands
3
+
4
+ require 'wx/shapes/shapes/grid_shape'
5
+
6
+ module Wx::SF
7
+
8
+ # Class encapsulates a rectangular shape derived from {GridShape} class which acts as a flexible grid-based
9
+ # container able to manage other assigned child shapes (it can control their position). The managed
10
+ # shapes are aligned into defined grid with a behaviour similar to classic Wx::FlexGridSizer class.
11
+ class FlexGridShape < GridShape
12
+
13
+
14
+ # @overload initialize()
15
+ # Default constructor.
16
+ # @overload initialize(pos, size, rows, cols, cell_space, diagram)
17
+ # User constructor.
18
+ # @param [Wx::RealPoint] pos Initial position
19
+ # @param [Wx::RealPoint] size Initial size
20
+ # @param [Integer] cols Number of grid rows
21
+ # @param [Integer] rows Number of grid columns
22
+ # @param [Integer] cell_space Additional space between managed shapes
23
+ # @param [Wx::SF::Diagram] diagram parent diagram
24
+ def initialize(*args)
25
+ super
26
+ end
27
+
28
+ # Do layout of assigned child shapes
29
+ def do_children_layout
30
+ return if @cols == 0 || @rows == 0
31
+
32
+ # initialize size arrays
33
+ row_sizes = ::Array.new(@rows, 0)
34
+ col_sizes = ::Array.new(@cols, 0)
35
+
36
+ # prepare a storage for processed shapes pointers
37
+ grid_shapes = ::Array.new(@cells.size)
38
+
39
+ # get maximum size of all managed (child) shapes per row and column
40
+ @cells.each_with_index do |id, i|
41
+ if id
42
+ col = (i % @cols)
43
+ row = (i / @cols)
44
+
45
+ grid_shapes[i] = shape = @child_shapes[id]
46
+ curr_rect = shape.get_bounding_box
47
+
48
+ # update maximum rows and columns sizes
49
+ col_sizes[col] = curr_rect.width if (shape.get_h_align != HALIGN::EXPAND) && (curr_rect.width > col_sizes[col])
50
+ row_sizes[row] = curr_rect.height if (shape.get_v_align != VALIGN::EXPAND) && (curr_rect.height > row_sizes[row])
51
+ end
52
+ end
53
+
54
+ total_x = total_y = 0
55
+
56
+ # put managed shapes to appropriate positions
57
+ grid_shapes.each_with_index do |shape, i|
58
+ if shape
59
+ col = (i % @cols)
60
+ row = (i / @cols)
61
+ if col == 0
62
+ total_x = 0
63
+ total_y += row_sizes[row-1] if row > 0
64
+ else
65
+ total_x += col_sizes[col-1]
66
+ end
67
+
68
+ fit_shape_to_rect(shape,
69
+ Wx::Rect.new(total_x + (col+1)*@cell_space,
70
+ total_y + (row+1)*@cell_space,
71
+ col_sizes[col], row_sizes[row]))
72
+ end
73
+ end
74
+ end
75
+
76
+ end
77
+
78
+ end