wxruby3-shapes 0.9.0.pre.beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.yardopts +12 -0
- data/CREDITS.md +18 -0
- data/INSTALL.md +39 -0
- data/LICENSE +21 -0
- data/README.md +118 -0
- data/assets/screenshot.png +0 -0
- data/bin/wx-shapes +9 -0
- data/lib/wx/shapes/arrow_base.rb +86 -0
- data/lib/wx/shapes/arrows/circle_arrow.rb +39 -0
- data/lib/wx/shapes/arrows/diamond_arrow.rb +33 -0
- data/lib/wx/shapes/arrows/open_arrow.rb +56 -0
- data/lib/wx/shapes/arrows/solid_arrow.rb +69 -0
- data/lib/wx/shapes/art/shape_canvas/page.xpm +73 -0
- data/lib/wx/shapes/auto_layout.rb +358 -0
- data/lib/wx/shapes/base.rb +33 -0
- data/lib/wx/shapes/canvas_history.rb +84 -0
- data/lib/wx/shapes/connection_point.rb +238 -0
- data/lib/wx/shapes/core.rb +19 -0
- data/lib/wx/shapes/diagram.rb +659 -0
- data/lib/wx/shapes/events.rb +389 -0
- data/lib/wx/shapes/printout.rb +136 -0
- data/lib/wx/shapes/serializable.rb +440 -0
- data/lib/wx/shapes/serialize/core.rb +40 -0
- data/lib/wx/shapes/serialize/id.rb +82 -0
- data/lib/wx/shapes/serialize/wx.rb +104 -0
- data/lib/wx/shapes/serializer/json.rb +258 -0
- data/lib/wx/shapes/serializer/yaml.rb +125 -0
- data/lib/wx/shapes/shape.rb +2129 -0
- data/lib/wx/shapes/shape_canvas.rb +3285 -0
- data/lib/wx/shapes/shape_data_object.rb +43 -0
- data/lib/wx/shapes/shape_handle.rb +287 -0
- data/lib/wx/shapes/shape_list.rb +161 -0
- data/lib/wx/shapes/shapes/bitmap_shape.rb +257 -0
- data/lib/wx/shapes/shapes/circle_shape.rb +136 -0
- data/lib/wx/shapes/shapes/control_shape.rb +483 -0
- data/lib/wx/shapes/shapes/curve_shape.rb +231 -0
- data/lib/wx/shapes/shapes/diamond_shape.rb +62 -0
- data/lib/wx/shapes/shapes/edit_text_shape.rb +317 -0
- data/lib/wx/shapes/shapes/ellipse_shape.rb +106 -0
- data/lib/wx/shapes/shapes/flex_grid_shape.rb +78 -0
- data/lib/wx/shapes/shapes/grid_shape.rb +404 -0
- data/lib/wx/shapes/shapes/line_shape.rb +907 -0
- data/lib/wx/shapes/shapes/multi_sel_rect.rb +214 -0
- data/lib/wx/shapes/shapes/ortho_shape.rb +357 -0
- data/lib/wx/shapes/shapes/polygon_shape.rb +294 -0
- data/lib/wx/shapes/shapes/rect_shape.rb +378 -0
- data/lib/wx/shapes/shapes/round_ortho_shape.rb +131 -0
- data/lib/wx/shapes/shapes/round_rect_shape.rb +142 -0
- data/lib/wx/shapes/shapes/square_shape.rb +119 -0
- data/lib/wx/shapes/shapes/text_shape.rb +324 -0
- data/lib/wx/shapes/thumbnail.rb +234 -0
- data/lib/wx/shapes/version.rb +12 -0
- data/lib/wx/shapes/wx.rb +29 -0
- data/lib/wx/shapes.rb +18 -0
- data/lib/wx/wx-shapes/base.rb +87 -0
- data/lib/wx/wx-shapes/cmd/sampler.rb +58 -0
- data/lib/wx/wx-shapes/cmd/test.rb +27 -0
- data/rakelib/yard/templates/default/fulldoc/html/css/wxruby3.css +7 -0
- data/rakelib/yard/templates/default/layout/html/setup.rb +5 -0
- data/rakelib/yard/yard/relative_markdown_links/version.rb +8 -0
- data/rakelib/yard/yard/relative_markdown_links.rb +39 -0
- data/rakelib/yard/yard-custom-templates.rb +2 -0
- data/rakelib/yard/yard-relative_markdown_links.rb +4 -0
- data/samples/demo/art/AlignBottom.xpm +35 -0
- data/samples/demo/art/AlignCenter.xpm +35 -0
- data/samples/demo/art/AlignLeft.xpm +35 -0
- data/samples/demo/art/AlignMiddle.xpm +35 -0
- data/samples/demo/art/AlignRight.xpm +35 -0
- data/samples/demo/art/AlignTop.xpm +35 -0
- data/samples/demo/art/Bitmap.xpm +25 -0
- data/samples/demo/art/Circle.xpm +22 -0
- data/samples/demo/art/Curve.xpm +21 -0
- data/samples/demo/art/Diamond.xpm +22 -0
- data/samples/demo/art/EditText.xpm +21 -0
- data/samples/demo/art/Ellipse.xpm +22 -0
- data/samples/demo/art/FixedRect.xpm +22 -0
- data/samples/demo/art/FlexGrid.xpm +22 -0
- data/samples/demo/art/GC.xpm +23 -0
- data/samples/demo/art/Grid.xpm +22 -0
- data/samples/demo/art/Line.xpm +21 -0
- data/samples/demo/art/NoSource.xpm +69 -0
- data/samples/demo/art/OrthoLine.xpm +21 -0
- data/samples/demo/art/Rect.xpm +22 -0
- data/samples/demo/art/RoundOrthoLine.xpm +21 -0
- data/samples/demo/art/RoundRect.xpm +22 -0
- data/samples/demo/art/Shadow.xpm +23 -0
- data/samples/demo/art/StandAloneLine.xpm +22 -0
- data/samples/demo/art/Text.xpm +21 -0
- data/samples/demo/art/Tool.xpm +23 -0
- data/samples/demo/art/sample.xpm +251 -0
- data/samples/demo/demo.rb +658 -0
- data/samples/demo/frame_canvas.rb +422 -0
- data/samples/demo/images/motyl.bmp +0 -0
- data/samples/demo/images/motyl2.bmp +0 -0
- data/samples/sample1/art/sample.xpm +251 -0
- data/samples/sample1/sample.rb +263 -0
- data/samples/sample2/art/sample.xpm +251 -0
- data/samples/sample2/sample.rb +133 -0
- data/samples/sample2/sample_canvas.rb +35 -0
- data/samples/sample2/sample_shape.rb +108 -0
- data/samples/sample3/art/sample.xpm +251 -0
- data/samples/sample3/sample.rb +281 -0
- data/samples/sample4/art/sample.xpm +251 -0
- data/samples/sample4/sample.rb +180 -0
- data/tests/art/motyl.bmp +0 -0
- data/tests/lib/wxapp_runner.rb +64 -0
- data/tests/serializer_tests.rb +521 -0
- data/tests/test_grid_shapes.rb +42 -0
- data/tests/test_serialize.rb +7 -0
- data/tests/test_serialize_yaml.rb +17 -0
- metadata +242 -0
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
# Wx::SF::PolygonShape - polygon shape class
|
|
2
|
+
# Copyright (c) M.J.N. Corino, The Netherlands
|
|
3
|
+
|
|
4
|
+
require 'wx/shapes/shapes/rect_shape'
|
|
5
|
+
|
|
6
|
+
module Wx::SF
|
|
7
|
+
|
|
8
|
+
# Class extends the Wx::SF::RectShape and encapsulates general polygon shape
|
|
9
|
+
# defined by a set of its vertices. The class can be used as it is or as a base class
|
|
10
|
+
# for shapes with more complex form and functionality.
|
|
11
|
+
# @see Wx::SF::DiamondShape
|
|
12
|
+
class PolygonShape < RectShape
|
|
13
|
+
|
|
14
|
+
# default values
|
|
15
|
+
module DEFAULT
|
|
16
|
+
# Default value of Wx::SF::PolygonShape @connect_to_vertex data member.
|
|
17
|
+
VERTEXCONNECTIONS = true
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
property :connect_to_vertex, :vertices
|
|
21
|
+
|
|
22
|
+
# @overload initialize()
|
|
23
|
+
# Default constructor.
|
|
24
|
+
# @overload initialize(pos, size, diagram)
|
|
25
|
+
# User constructor.
|
|
26
|
+
# @param [Array<Wx::RealPoint>] pts Array of the polygon vertices
|
|
27
|
+
# @param [Wx::RealPoint] pos Initial position
|
|
28
|
+
# @param [Wx::SF::Diagram] diagram parent diagram
|
|
29
|
+
def initialize(*args)
|
|
30
|
+
@connect_to_vertex = DEFAULT::VERTEXCONNECTIONS
|
|
31
|
+
@vertices = []
|
|
32
|
+
if args.empty?
|
|
33
|
+
super
|
|
34
|
+
else
|
|
35
|
+
pts, pos, diagram = args
|
|
36
|
+
super(pos,Wx::RealPoint.new(1,1), diagram)
|
|
37
|
+
set_vertices(pts)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Set connecting mode.
|
|
42
|
+
# @param [Boolean] enable Set this parameter to true if you want to connect
|
|
43
|
+
# line shapes to the polygon's vertices, otherwise the lines will be connected
|
|
44
|
+
# to the nearest point of the shape's border.
|
|
45
|
+
def set_connect_to_vertex(enable)
|
|
46
|
+
@connect_to_vertex = enable
|
|
47
|
+
end
|
|
48
|
+
alias :connect_to_vertex= :set_connect_to_vertex
|
|
49
|
+
|
|
50
|
+
# Get status of connecting mode.
|
|
51
|
+
# @return [Boolean] true if the line shapes will be connected to the polygon's vertices
|
|
52
|
+
def is_connected_to_vertex
|
|
53
|
+
@connect_to_vertex
|
|
54
|
+
end
|
|
55
|
+
alias :connected_to_vertex? :is_connected_to_vertex
|
|
56
|
+
alias :get_connect_to_vertex :is_connected_to_vertex
|
|
57
|
+
|
|
58
|
+
# Set the poly vertices which define its form.
|
|
59
|
+
# @param [Array<Wx::RealPoint>] pts Array of the vertices
|
|
60
|
+
def set_vertices(pts)
|
|
61
|
+
::Kernel.raise ArgumentError, 'Expected an array of Wx::RealPoint' unless pts.all? { |pt| pt.is_a?(Wx::RealPoint) }
|
|
62
|
+
@vertices = pts.collect { |pt| pt.dup }
|
|
63
|
+
normalize_vertices
|
|
64
|
+
fit_bounding_box_to_vertices
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# Get the poly vertices. Serialization only.
|
|
68
|
+
# @return [Array<Wx::RealPoint>]
|
|
69
|
+
def get_vertices
|
|
70
|
+
@vertices
|
|
71
|
+
end
|
|
72
|
+
private :get_vertices
|
|
73
|
+
|
|
74
|
+
# Resize the rectangle to bound all child shapes. The function can be overridden if necessary.
|
|
75
|
+
def fit_to_children
|
|
76
|
+
super
|
|
77
|
+
fit_vertices_to_bounding_box
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# Get intersection point of the shape border and a line leading from
|
|
81
|
+
# 'start' point to 'end' point. The function can be overridden if necessary.
|
|
82
|
+
# @param [Wx::RealPoint] start Starting point of the virtual intersection line
|
|
83
|
+
# @param [Wx::RealPoint] end_pt Ending point of the virtual intersection line
|
|
84
|
+
# @return [Wx::RealPoint] Intersection point
|
|
85
|
+
def get_border_point(start, end_pt)
|
|
86
|
+
# HINT: override it for custom actions ...
|
|
87
|
+
start = start.to_real_point; end_pt.to_real_point
|
|
88
|
+
return get_center if @vertices.empty?
|
|
89
|
+
|
|
90
|
+
pts = get_translated_vertices
|
|
91
|
+
intersection = start
|
|
92
|
+
|
|
93
|
+
if @connect_to_vertex
|
|
94
|
+
intersection = pts.shift
|
|
95
|
+
min_dist = intersection.distance_to(end_pt)
|
|
96
|
+
pts.each do |pt|
|
|
97
|
+
tmp_min_dist = pt.distance_to(end_pt)
|
|
98
|
+
if tmp_min_dist < min_dist
|
|
99
|
+
min_dist = tmp_min_dist
|
|
100
|
+
intersection = pt
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
intersection
|
|
105
|
+
else
|
|
106
|
+
success = false
|
|
107
|
+
pts.each_with_index do |pt, i|
|
|
108
|
+
if tmp_intersection = Wx::SF::Shape.lines_intersection(pt, pts[(i+1) % pts.size], start, end_pt)
|
|
109
|
+
if !success
|
|
110
|
+
min_dist = intersection.distance_to(end_pt)
|
|
111
|
+
intersection = tmp_intersection
|
|
112
|
+
else
|
|
113
|
+
tmp_min_dist = intersection.distance_to(end_pt)
|
|
114
|
+
if tmp_min_dist < min_dist
|
|
115
|
+
min_dist = tmp_min_dist
|
|
116
|
+
intersection = tmp_intersection
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
success = true
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
success ? intersection : get_center
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
# Event handler called during dragging of the shape handle.
|
|
128
|
+
# The function can be overridden if necessary.
|
|
129
|
+
#
|
|
130
|
+
# The function is called by the framework (by the shape canvas).
|
|
131
|
+
# @param [Shape::Handle] handle Reference to dragged handle
|
|
132
|
+
def on_handle(handle)
|
|
133
|
+
super
|
|
134
|
+
fit_vertices_to_bounding_box
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
protected
|
|
138
|
+
|
|
139
|
+
# Scale the rectangle size for this shape.
|
|
140
|
+
# @param [Float] x Horizontal scale factor
|
|
141
|
+
# @param [Float] y Vertical scale factor
|
|
142
|
+
def scale_rectangle(x, y)
|
|
143
|
+
rect_size.x *= x
|
|
144
|
+
rect_size.y *= y
|
|
145
|
+
|
|
146
|
+
fit_vertices_to_bounding_box
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
# Move all vertices so the polygon's relative bounding box position
|
|
150
|
+
# will be located in the origin.
|
|
151
|
+
def normalize_vertices
|
|
152
|
+
# move all vertices so the polygon's relative bounding box will be located in the origin
|
|
153
|
+
|
|
154
|
+
minx, miny, _, _ = get_extents
|
|
155
|
+
|
|
156
|
+
dx = minx*(-1)
|
|
157
|
+
dy = miny*(-1)
|
|
158
|
+
|
|
159
|
+
@vertices.each do |pt|
|
|
160
|
+
pt.x += dx
|
|
161
|
+
pt.y += dy
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
# Scale polygon's vertices to fit into the rectangle bounding the polygon.
|
|
166
|
+
def fit_vertices_to_bounding_box
|
|
167
|
+
minx, miny, maxx, maxy = get_extents
|
|
168
|
+
|
|
169
|
+
sx = rect_size.x/(maxx - minx)
|
|
170
|
+
sy = rect_size.y/(maxy - miny)
|
|
171
|
+
|
|
172
|
+
@vertices.each do |pt|
|
|
173
|
+
pt.x *= sx
|
|
174
|
+
pt.y *= sy
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
# Scale the bounding rectangle to fit all polygons vertices.
|
|
179
|
+
def fit_bounding_box_to_vertices
|
|
180
|
+
minx, miny, maxx, maxy = get_extents
|
|
181
|
+
|
|
182
|
+
rect_size.x = maxx - minx
|
|
183
|
+
rect_size.y = maxy - miny
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
# Get polygon extents.
|
|
187
|
+
# @return [Array(Float,Float,Float,Float)] Positions of the left, top, right and bottom side of polygon's bounding box
|
|
188
|
+
def get_extents
|
|
189
|
+
return [0.0,0.0,0.0,0.0] if @vertices.empty?
|
|
190
|
+
|
|
191
|
+
@vertices.inject(nil) do |exts, pt|
|
|
192
|
+
if exts
|
|
193
|
+
exts[0] = pt.x if pt.x < exts[0]
|
|
194
|
+
exts[1] = pt.y if pt.y < exts[1]
|
|
195
|
+
exts[2] = pt.x if pt.x > exts[2]
|
|
196
|
+
exts[3] = pt.y if pt.y > exts[3]
|
|
197
|
+
else
|
|
198
|
+
exts = [pt.x, pt.y, pt.x, pt.y]
|
|
199
|
+
end
|
|
200
|
+
exts
|
|
201
|
+
end
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
# Get absolute positions of the polygon's vertices.
|
|
205
|
+
# @return [Array<Wx::RealPoint>] pts Array of translated polygon's vertices
|
|
206
|
+
def get_translated_vertices
|
|
207
|
+
abs_pos = get_absolute_position
|
|
208
|
+
@vertices.collect { |pt| abs_pos + pt }
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
# Get absolute positions of the polygon's vertices.
|
|
212
|
+
# @return [Array<Wx::Point>] pts Array of translated polygon's vertices
|
|
213
|
+
def get_translated_vertice_points
|
|
214
|
+
abs_pos = get_absolute_position.to_point
|
|
215
|
+
@vertices.collect { |pt| abs_pos + pt.to_point }
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
# Draw the polygon shape.
|
|
219
|
+
# @param [Wx::DC] dc Reference to the device context where the shape will be drawn to
|
|
220
|
+
def draw_polygon_shape(dc)
|
|
221
|
+
pts = get_translated_vertice_points
|
|
222
|
+
dc.draw_polygon(pts)
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
# Draw the shape in the normal way. The function can be overridden if necessary.
|
|
226
|
+
# @param [Wx::DC] dc Reference to device context where the shape will be drawn to
|
|
227
|
+
def draw_normal(dc)
|
|
228
|
+
# HINT: overload it for custom actions...
|
|
229
|
+
|
|
230
|
+
dc.with_pen(@border) do
|
|
231
|
+
dc.with_brush(@fill) do
|
|
232
|
+
draw_polygon_shape(dc)
|
|
233
|
+
end
|
|
234
|
+
end
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
# Draw the shape in the hover mode (the mouse cursor is above the shape).
|
|
238
|
+
# The function can be overridden if necessary.
|
|
239
|
+
# @param [Wx::DC] dc Reference to device context where the shape will be drawn to
|
|
240
|
+
def draw_hover(dc)
|
|
241
|
+
# HINT: overload it for custom actions...
|
|
242
|
+
|
|
243
|
+
dc.with_pen(Wx::Pen.new(get_hover_colour, 1)) do
|
|
244
|
+
dc.with_brush(@fill) do
|
|
245
|
+
draw_polygon_shape(dc)
|
|
246
|
+
end
|
|
247
|
+
end
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
# Draw the shape in the highlighted mode (another shape is dragged over this
|
|
251
|
+
# shape and this shape will accept the dragged one if it will be dropped on it).
|
|
252
|
+
# The function can be overridden if necessary.
|
|
253
|
+
# @param [Wx::DC] dc Reference to device context where the shape will be drawn to
|
|
254
|
+
def draw_highlighted(dc)
|
|
255
|
+
# HINT: overload it for custom actions...
|
|
256
|
+
|
|
257
|
+
dc.with_pen(Wx::Pen.new(get_hover_colour, 2)) do
|
|
258
|
+
dc.with_brush(@fill) do
|
|
259
|
+
draw_polygon_shape(dc)
|
|
260
|
+
end
|
|
261
|
+
end
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
# Draw shadow under the shape. The function can be overridden if necessary.
|
|
265
|
+
# @param [Wx::DC] dc Reference to device context where the shadow will be drawn to
|
|
266
|
+
def draw_shadow(dc)
|
|
267
|
+
# HINT: overload it for custom actions...
|
|
268
|
+
|
|
269
|
+
if @fill.get_style != Wx::BrushStyle::BRUSHSTYLE_TRANSPARENT
|
|
270
|
+
dc.with_pen(Wx::TRANSPARENT_PEN) do
|
|
271
|
+
dc.with_brush(get_parent_canvas.get_shadow_fill) do
|
|
272
|
+
offset = get_parent_canvas.get_shadow_offset
|
|
273
|
+
|
|
274
|
+
move_by(offset)
|
|
275
|
+
draw_polygon_shape(dc)
|
|
276
|
+
move_by(-offset.x, -offset.y)
|
|
277
|
+
end
|
|
278
|
+
end
|
|
279
|
+
end
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
# Deserialize attributes and recalculate rectangle size afterwards.
|
|
283
|
+
# @param [Hash] data
|
|
284
|
+
# @return [self]
|
|
285
|
+
def from_serialized(data)
|
|
286
|
+
super
|
|
287
|
+
normalize_vertices
|
|
288
|
+
fit_vertices_to_bounding_box
|
|
289
|
+
self
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
end
|
|
293
|
+
|
|
294
|
+
end
|
|
@@ -0,0 +1,378 @@
|
|
|
1
|
+
# Wx::SF::RectShape - rectangle shape class
|
|
2
|
+
# Copyright (c) M.J.N. Corino, The Netherlands
|
|
3
|
+
|
|
4
|
+
module Wx::SF
|
|
5
|
+
|
|
6
|
+
class RectShape < Shape
|
|
7
|
+
|
|
8
|
+
# default values
|
|
9
|
+
module DEFAULT
|
|
10
|
+
# Default value of RectShape @rect_size data member.
|
|
11
|
+
SIZE = Wx::RealPoint.new(100, 50)
|
|
12
|
+
# Default value of RectShape @fill data member.
|
|
13
|
+
FILL = Wx::Brush.new(Wx::WHITE) if Wx::App.is_main_loop_running
|
|
14
|
+
Wx.add_delayed_constant(self, :FILL) { Wx::Brush.new(Wx::WHITE) }
|
|
15
|
+
# Default value of RectShape @border data member.
|
|
16
|
+
BORDER = Wx::Pen.new(Wx::BLACK) if Wx::App.is_main_loop_running
|
|
17
|
+
Wx.add_delayed_constant(self, :BORDER) { Wx::Pen.new(Wx::BLACK) }
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
property :rect_size, :fill, :border
|
|
21
|
+
|
|
22
|
+
# @overload initialize()
|
|
23
|
+
# Default constructor.
|
|
24
|
+
# @overload initialize(pos, size, diagram)
|
|
25
|
+
# User constructor.
|
|
26
|
+
# @param [Wx::RealPoint] pos Initial position
|
|
27
|
+
# @param [Wx::RealPoint] size Initial size
|
|
28
|
+
# @param [Wx::SF::Diagram] diagram parent diagram
|
|
29
|
+
def initialize(*args)
|
|
30
|
+
size = nil
|
|
31
|
+
if args.empty?
|
|
32
|
+
super
|
|
33
|
+
else
|
|
34
|
+
pos, size, diagram = args
|
|
35
|
+
super(pos, diagram)
|
|
36
|
+
end
|
|
37
|
+
@rect_size = size ? size.to_real_point : DEFAULT::SIZE.dup
|
|
38
|
+
@fill = DEFAULT::FILL
|
|
39
|
+
@border = DEFAULT::BORDER
|
|
40
|
+
@prev_size = @prev_position = Wx::RealPoint
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Set rectangle's fill style.
|
|
44
|
+
# @param [Wx::Brush] brush Reference to a brush object
|
|
45
|
+
def set_fill(brush)
|
|
46
|
+
@fill = brush
|
|
47
|
+
end
|
|
48
|
+
alias :fill= :set_fill
|
|
49
|
+
|
|
50
|
+
# Get current fill style.
|
|
51
|
+
# @return [Wx::Brush] Current brush
|
|
52
|
+
def get_fill
|
|
53
|
+
@fill
|
|
54
|
+
end
|
|
55
|
+
alias :fill :get_fill
|
|
56
|
+
|
|
57
|
+
# Set rectangle's border style.
|
|
58
|
+
# @param [Wx::Pen] pen Reference to a pen object
|
|
59
|
+
def set_border(pen)
|
|
60
|
+
@border = pen
|
|
61
|
+
end
|
|
62
|
+
alias :border= :set_border
|
|
63
|
+
|
|
64
|
+
# Get current border style.
|
|
65
|
+
# @return [Wx::Pen] Current pen
|
|
66
|
+
def get_border
|
|
67
|
+
@border
|
|
68
|
+
end
|
|
69
|
+
alias :border :get_border
|
|
70
|
+
|
|
71
|
+
# Set the rectangle size.
|
|
72
|
+
# @overload set_rect_size(x, y)
|
|
73
|
+
# @param [Float] x Horizontal size
|
|
74
|
+
# @param [Float] y Vertical size
|
|
75
|
+
# @overload set_rect_size(size)
|
|
76
|
+
# @param [Wx::RealPoint] size New size
|
|
77
|
+
def set_rect_size(arg1, arg2 = nil)
|
|
78
|
+
@rect_size = arg2 ? Wx::RealPoint.new(arg1.to_f, arg2.to_f) : arg1.to_real_point
|
|
79
|
+
end
|
|
80
|
+
alias :rect_size= :set_rect_size
|
|
81
|
+
|
|
82
|
+
# Get the rectangle size.
|
|
83
|
+
# @return [Wx::RealPoint] Current size
|
|
84
|
+
def get_rect_size
|
|
85
|
+
@rect_size
|
|
86
|
+
end
|
|
87
|
+
alias :rect_size :get_rect_size
|
|
88
|
+
|
|
89
|
+
# Get shape's bounding box. The function can be overridden if necessary.
|
|
90
|
+
# @return [Wx::Rect] Bounding rectangle
|
|
91
|
+
def get_bounding_box
|
|
92
|
+
apos = get_absolute_position
|
|
93
|
+
Wx::Rect.new([apos.x.to_i, apos.y.to_i], [@rect_size.x.to_i, @rect_size.y.to_i])
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# Get intersection point of the shape border and a line leading from
|
|
97
|
+
# 'start' point to 'end' point. The function can be overridden if necessary.
|
|
98
|
+
# @param [Wx::RealPoint] start Starting point of the virtual intersection line
|
|
99
|
+
# @param [Wx::RealPoint] end_pt Ending point of the virtual intersection line
|
|
100
|
+
# @return [Wx::RealPoint] Intersection point
|
|
101
|
+
def get_border_point(start, end_pt)
|
|
102
|
+
# HINT: override it for custom actions ...
|
|
103
|
+
start = start.to_real_point; end_pt.to_real_point
|
|
104
|
+
|
|
105
|
+
# the function calculates intersection of line leading from the shape center to
|
|
106
|
+
# given point with the shape's bounding box
|
|
107
|
+
bb_rct = get_bounding_box
|
|
108
|
+
|
|
109
|
+
intersection = Shape.lines_intersection(bb_rct.top_left.to_real,
|
|
110
|
+
Wx::RealPoint.new(bb_rct.top_right.x + 1.0, bb_rct.top_right.y.to_f),
|
|
111
|
+
start, end_pt)
|
|
112
|
+
intersection ||= Shape.lines_intersection(Wx::RealPoint.new(bb_rct.top_right.x + 1.0, bb_rct.top_right.y.to_f),
|
|
113
|
+
Wx::RealPoint.new(bb_rct.bottom_right.x + 1.0, bb_rct.bottom_right.y + 1.0),
|
|
114
|
+
start, end_pt)
|
|
115
|
+
intersection ||= Shape.lines_intersection(Wx::RealPoint.new(bb_rct.bottom_right.x + 1.0, bb_rct.bottom_right.y + 1.0),
|
|
116
|
+
Wx::RealPoint.new(bb_rct.bottom_left.x.to_f, bb_rct.bottom_left.y + 1.0),
|
|
117
|
+
start, end_pt)
|
|
118
|
+
intersection ||= Shape.lines_intersection(Wx::RealPoint.new(bb_rct.bottom_left.x.to_f, bb_rct.bottom_left.y + 1),
|
|
119
|
+
bb_rct.top_left.to_real,
|
|
120
|
+
start, end_pt)
|
|
121
|
+
intersection || get_center
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
# Function called by the framework responsible for creation of shape handles
|
|
125
|
+
# at the creation time. The function can be overridden if necessary.
|
|
126
|
+
def create_handles
|
|
127
|
+
# HINT: overload it for custom actions...
|
|
128
|
+
|
|
129
|
+
add_handle(Shape::Handle::TYPE::LEFTTOP)
|
|
130
|
+
add_handle(Shape::Handle::TYPE::TOP)
|
|
131
|
+
add_handle(Shape::Handle::TYPE::RIGHTTOP)
|
|
132
|
+
add_handle(Shape::Handle::TYPE::RIGHT)
|
|
133
|
+
add_handle(Shape::Handle::TYPE::RIGHTBOTTOM)
|
|
134
|
+
add_handle(Shape::Handle::TYPE::BOTTOM)
|
|
135
|
+
add_handle(Shape::Handle::TYPE::LEFTBOTTOM)
|
|
136
|
+
add_handle(Shape::Handle::TYPE::LEFT)
|
|
137
|
+
add_handle(Shape::Handle::TYPE::LEFTTOP)
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
# Event handler called during dragging of the shape handle.
|
|
141
|
+
# The function can be overridden if necessary.
|
|
142
|
+
#
|
|
143
|
+
# The function is called by the framework (by the shape canvas).
|
|
144
|
+
# @param [Shape::Handle] handle Reference to dragged handle
|
|
145
|
+
def on_handle(handle)
|
|
146
|
+
# HINT: overload it for custom actions...
|
|
147
|
+
do_on_handle(handle)
|
|
148
|
+
|
|
149
|
+
super
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
# Event handler called when the user started to drag the shape handle.
|
|
153
|
+
# The function can be overridden if necessary.
|
|
154
|
+
#
|
|
155
|
+
# The function is called by the framework (by the shape canvas).
|
|
156
|
+
# @param [Shape::Handle] handle Reference to dragged handle
|
|
157
|
+
def on_begin_handle(handle)
|
|
158
|
+
do_begin_handle
|
|
159
|
+
super
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
# Resize the shape to bound all child shapes. The function can be overridden if necessary.
|
|
163
|
+
def fit_to_children
|
|
164
|
+
# HINT: overload it for custom actions...
|
|
165
|
+
|
|
166
|
+
# get bounding box of the shape and children set be inside it
|
|
167
|
+
ch_bb = get_bounding_box
|
|
168
|
+
shp_bb = ch_bb.dup
|
|
169
|
+
|
|
170
|
+
@child_shapes.each do |child|
|
|
171
|
+
if child.has_style?(STYLE::ALWAYS_INSIDE)
|
|
172
|
+
child.get_complete_bounding_box(ch_bb, BBMODE::SELF | BBMODE::CHILDREN)
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
unless ch_bb.empty?
|
|
177
|
+
unless shp_bb.contains?(ch_bb)
|
|
178
|
+
dx = ch_bb.left - shp_bb.left
|
|
179
|
+
dy = ch_bb.top - shp_bb.top
|
|
180
|
+
|
|
181
|
+
# resize parent shape
|
|
182
|
+
shp_bb.union!(ch_bb)
|
|
183
|
+
move_to(shp_bb.get_position.x, shp_bb.get_position.y)
|
|
184
|
+
@rect_size = Wx::RealPoint.new(shp_bb.get_size.x.to_f, shp_bb.get_size.y.to_f)
|
|
185
|
+
if has_style?(STYLE::EMIT_EVENTS)
|
|
186
|
+
evt = ShapeEvent.new(EVT_SF_SHAPE_SIZE_CHANGED, id)
|
|
187
|
+
evt.set_shape(self)
|
|
188
|
+
get_parent_canvas.get_event_handler.process_event(evt)
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
# move its "1st level" children if necessary
|
|
192
|
+
if dx < 0 || dy < 0
|
|
193
|
+
@child_shapes.each do |child|
|
|
194
|
+
child.move_by(dx.to_i.abs, 0) if dx < 0
|
|
195
|
+
child.move_by(0, dy.to_i.abs) if dy < 0
|
|
196
|
+
end
|
|
197
|
+
end
|
|
198
|
+
end
|
|
199
|
+
end
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
# Scale the shape size by in both directions. The function can be overridden if necessary
|
|
203
|
+
# (new implementation should call default one ore scale shape's children manualy if neccesary).
|
|
204
|
+
# @param [Float] x Horizontal scale factor
|
|
205
|
+
# @param [Float] y Vertical scale factor
|
|
206
|
+
# @param [Boolean] children true if the shape's children should be scaled as well, otherwise the shape will be updated after scaling via update() function.
|
|
207
|
+
def scale(x, y, children = WITHCHILDREN)
|
|
208
|
+
# HINT: overload it for custom actions...
|
|
209
|
+
if x > 0 && y > 0
|
|
210
|
+
scale_rectangle(x, y)
|
|
211
|
+
|
|
212
|
+
# call default function implementation (needed for scaling of shape's children)
|
|
213
|
+
super
|
|
214
|
+
end
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
protected
|
|
218
|
+
|
|
219
|
+
# Handle action at handle drag beginning
|
|
220
|
+
def do_begin_handle
|
|
221
|
+
@prev_position = @relative_position.dup
|
|
222
|
+
@prev_size = @rect_size.dup
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
# Scale the rectangle size for this shape.
|
|
226
|
+
# @param [Float] x Horizontal scale factor
|
|
227
|
+
# @param [Float] y Vertical scale factor
|
|
228
|
+
def scale_rectangle(x, y)
|
|
229
|
+
set_rect_size(@rect_size.x * x, @rect_size.y * y)
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
# Handle's shape specific actions on handling handle events.
|
|
233
|
+
# The function can be overridden if necessary.
|
|
234
|
+
# @param [Shape::Handle] handle Reference to dragged handle
|
|
235
|
+
# @see #on_handle
|
|
236
|
+
def do_on_handle(handle)
|
|
237
|
+
case handle.type
|
|
238
|
+
when Shape::Handle::TYPE::LEFT
|
|
239
|
+
on_left_handle(handle)
|
|
240
|
+
|
|
241
|
+
when Shape::Handle::TYPE::LEFTTOP
|
|
242
|
+
on_left_handle(handle)
|
|
243
|
+
on_top_handle(handle)
|
|
244
|
+
|
|
245
|
+
when Shape::Handle::TYPE::LEFTBOTTOM
|
|
246
|
+
on_left_handle(handle)
|
|
247
|
+
on_bottom_handle(handle)
|
|
248
|
+
|
|
249
|
+
when Shape::Handle::TYPE::RIGHT
|
|
250
|
+
on_right_handle(handle)
|
|
251
|
+
|
|
252
|
+
when Shape::Handle::TYPE::RIGHTTOP
|
|
253
|
+
on_right_handle(handle)
|
|
254
|
+
on_top_handle(handle)
|
|
255
|
+
|
|
256
|
+
when Shape::Handle::TYPE::RIGHTBOTTOM
|
|
257
|
+
on_right_handle(handle)
|
|
258
|
+
on_bottom_handle(handle)
|
|
259
|
+
|
|
260
|
+
when Shape::Handle::TYPE::TOP
|
|
261
|
+
on_top_handle(handle)
|
|
262
|
+
|
|
263
|
+
when Shape::Handle::TYPE::BOTTOM
|
|
264
|
+
on_bottom_handle(handle)
|
|
265
|
+
end
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
# Draw the shape in the normal way. The function can be overridden if necessary.
|
|
269
|
+
# @param [Wx::DC] dc Reference to device context where the shape will be drawn to
|
|
270
|
+
def draw_normal(dc)
|
|
271
|
+
# HINT: overload it for custom actions...
|
|
272
|
+
|
|
273
|
+
dc.with_pen(@border) do
|
|
274
|
+
dc.with_brush(@fill) do
|
|
275
|
+
dc.draw_rectangle(get_absolute_position.to_point, @rect_size.to_size)
|
|
276
|
+
end
|
|
277
|
+
end
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
# Draw the shape in the hover mode (the mouse cursor is above the shape).
|
|
281
|
+
# The function can be overridden if necessary.
|
|
282
|
+
# @param [Wx::DC] dc Reference to device context where the shape will be drawn to
|
|
283
|
+
def draw_hover(dc)
|
|
284
|
+
# HINT: overload it for custom actions...
|
|
285
|
+
|
|
286
|
+
dc.with_pen(Wx::Pen.new(@hover_color, 1)) do
|
|
287
|
+
dc.with_brush(@fill) do
|
|
288
|
+
dc.draw_rectangle(get_absolute_position.to_point, @rect_size.to_size)
|
|
289
|
+
end
|
|
290
|
+
end
|
|
291
|
+
end
|
|
292
|
+
|
|
293
|
+
# Draw the shape in the highlighted mode (another shape is dragged over this
|
|
294
|
+
# shape and this shape will accept the dragged one if it will be dropped on it).
|
|
295
|
+
# The function can be overridden if necessary.
|
|
296
|
+
# @param [Wx::DC] dc Reference to device context where the shape will be drawn to
|
|
297
|
+
def draw_highlighted(dc)
|
|
298
|
+
# HINT: overload it for custom actions...
|
|
299
|
+
|
|
300
|
+
dc.with_pen(Wx::Pen.new(@hover_color, 2)) do
|
|
301
|
+
dc.with_brush(@fill) do
|
|
302
|
+
dc.draw_rectangle(get_absolute_position.to_point, @rect_size.to_size)
|
|
303
|
+
end
|
|
304
|
+
end
|
|
305
|
+
end
|
|
306
|
+
|
|
307
|
+
# Draw shadow under the shape. The function can be overridden if necessary.
|
|
308
|
+
# @param [Wx::DC] dc Reference to device context where the shadow will be drawn to
|
|
309
|
+
def draw_shadow(dc)
|
|
310
|
+
# HINT: overload it for custom actions...
|
|
311
|
+
|
|
312
|
+
if @fill.style != Wx::BrushStyle::BRUSHSTYLE_TRANSPARENT
|
|
313
|
+
dc.with_pen(Wx::TRANSPARENT_PEN) do
|
|
314
|
+
dc.with_brush(get_parent_canvas.get_shadow_fill) do
|
|
315
|
+
dc.draw_rectangle((get_absolute_position + get_parent_canvas.get_shadow_offset).to_point, @rect_size.to_size)
|
|
316
|
+
end
|
|
317
|
+
end
|
|
318
|
+
end
|
|
319
|
+
end
|
|
320
|
+
|
|
321
|
+
# Event handler called during dragging of the right shape handle.
|
|
322
|
+
# The function can be overridden if necessary.
|
|
323
|
+
# @param [Shape::Handle] handle Reference to dragged shape handle
|
|
324
|
+
def on_right_handle(handle)
|
|
325
|
+
# HINT: overload it for custom actions...
|
|
326
|
+
|
|
327
|
+
@rect_size.x += handle.get_delta.x
|
|
328
|
+
end
|
|
329
|
+
|
|
330
|
+
# Event handler called during dragging of the left shape handle.
|
|
331
|
+
# The function can be overridden if necessary.
|
|
332
|
+
# @param [Shape::Handle] handle Reference to dragged shape handle
|
|
333
|
+
def on_left_handle(handle)
|
|
334
|
+
# HINT: overload it for custom actions...
|
|
335
|
+
|
|
336
|
+
dx = handle.get_delta.x.to_f
|
|
337
|
+
|
|
338
|
+
# update position of children
|
|
339
|
+
unless has_style?(STYLE::LOCK_CHILDREN)
|
|
340
|
+
@child_shapes.each do |child|
|
|
341
|
+
child.move_by(-dx, 0) if child.get_h_align == HALIGN::NONE
|
|
342
|
+
end
|
|
343
|
+
end
|
|
344
|
+
# update position and size of the shape
|
|
345
|
+
@rect_size.x -= dx
|
|
346
|
+
@relative_position.x += dx
|
|
347
|
+
end
|
|
348
|
+
|
|
349
|
+
# Event handler called during dragging of the top shape handle.
|
|
350
|
+
# The function can be overridden if necessary.
|
|
351
|
+
# @param [Shape::Handle] handle Reference to dragged shape handle
|
|
352
|
+
def on_top_handle(handle)
|
|
353
|
+
# HINT: overload it for custom actions...
|
|
354
|
+
|
|
355
|
+
dy = handle.get_delta.y.to_f
|
|
356
|
+
|
|
357
|
+
# update position of children
|
|
358
|
+
unless has_style?(STYLE::LOCK_CHILDREN)
|
|
359
|
+
@child_shapes.each do |child|
|
|
360
|
+
child.move_by(0, -dy) if child.get_v_align == VALIGN::NONE
|
|
361
|
+
end
|
|
362
|
+
end
|
|
363
|
+
# update position and size of the shape
|
|
364
|
+
@rect_size.y -= dy
|
|
365
|
+
@relative_position.y += dy
|
|
366
|
+
end
|
|
367
|
+
|
|
368
|
+
# Event handler called during dragging of the bottom shape handle.
|
|
369
|
+
# The function can be overridden if necessary.
|
|
370
|
+
# @param [Shape::Handle] handle Reference to dragged shape handle
|
|
371
|
+
def on_bottom_handle(handle)
|
|
372
|
+
# HINT: overload it for custom actions...
|
|
373
|
+
|
|
374
|
+
@rect_size.y += handle.get_delta.y
|
|
375
|
+
end
|
|
376
|
+
end
|
|
377
|
+
|
|
378
|
+
end
|