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,131 @@
|
|
|
1
|
+
# Wx::SF::RoundOrthoLineShape - rounded orthogonal line shape class
|
|
2
|
+
# Copyright (c) M.J.N. Corino, The Netherlands
|
|
3
|
+
|
|
4
|
+
require 'wx/shapes/shapes/ortho_shape'
|
|
5
|
+
|
|
6
|
+
module Wx::SF
|
|
7
|
+
|
|
8
|
+
# Rounded orthogonal line shape. The class extends OrthoLineShape class and allows
|
|
9
|
+
# user to create connection line orthogonal to base axis with round corners.
|
|
10
|
+
class RoundOrthoLineShape < OrthoLineShape
|
|
11
|
+
|
|
12
|
+
MAX_RADIUS = 7
|
|
13
|
+
|
|
14
|
+
property :max_radius
|
|
15
|
+
|
|
16
|
+
# @overload initialize()
|
|
17
|
+
# default constructor
|
|
18
|
+
# @overload initialize(src, trg, path, manager)
|
|
19
|
+
# @param [Wx::SF::Serializable::ID] src ID of the source shape
|
|
20
|
+
# @param [Wx::SF::Serializable::ID] trg ID of the target shape
|
|
21
|
+
# @param [Array<Wx::RealPoint>] path List of the line control points (can be empty)
|
|
22
|
+
# @param [Diagram] diagram containing diagram
|
|
23
|
+
def initialize(*args)
|
|
24
|
+
super
|
|
25
|
+
@max_radius = MAX_RADIUS
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Access (set/get) maximum radius.
|
|
29
|
+
attr_accessor :max_radius
|
|
30
|
+
|
|
31
|
+
protected
|
|
32
|
+
|
|
33
|
+
# Draw one orthogonal line segment.
|
|
34
|
+
# @param [Wx::DC] dc Device context
|
|
35
|
+
# @param [Wx::RealPoint] src Starting point of the ortho line segment
|
|
36
|
+
# @param [Wx::RealPoint] trg Ending point of the ortho line segment
|
|
37
|
+
# @param [SEGMENTCPS] cps Connection points used by the line segment
|
|
38
|
+
def draw_line_segment(dc, src, trg, cps)
|
|
39
|
+
if (trg.x == src.x) || (trg.y == src.y)
|
|
40
|
+
dc.draw_line(src.to_point, trg.to_point)
|
|
41
|
+
return
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
direction = get_segment_direction(src, trg, cps)
|
|
45
|
+
src_pt = src.to_point
|
|
46
|
+
trg_pt = trg.to_point
|
|
47
|
+
|
|
48
|
+
dx = trg.x - src.x
|
|
49
|
+
dy = trg.y - src.y
|
|
50
|
+
kx = dx < 0 ? -1 : 1
|
|
51
|
+
ky = dy < 0 ? 1 : -1
|
|
52
|
+
|
|
53
|
+
pt_center = Wx::RealPoint.new((src.x + trg.x)/2, (src.y + trg.y)/2)
|
|
54
|
+
|
|
55
|
+
dc.with_brush(Wx::TRANSPARENT_BRUSH) do
|
|
56
|
+
|
|
57
|
+
if is_two_segment(cps)
|
|
58
|
+
if direction < 1.0
|
|
59
|
+
r = (dy * @max_radius/100).abs
|
|
60
|
+
r = @max_radius if r > @max_radius
|
|
61
|
+
|
|
62
|
+
dc.draw_line(src_pt.x, src_pt.y, (trg.x - r * kx).to_i, src_pt.y)
|
|
63
|
+
dc.draw_line(trg_pt.x, (src.y - r * ky).to_i, trg_pt.x, trg_pt.y)
|
|
64
|
+
|
|
65
|
+
if r > 0
|
|
66
|
+
if (ky > 0 && kx > 0) || (ky < 0 && kx < 0)
|
|
67
|
+
dc.draw_arc((trg.x - r * kx).to_i, src_pt.y, trg_pt.x, (src.y - r * ky).to_i, (trg.x - r * kx).to_i, (src.y - r * ky).to_i)
|
|
68
|
+
else
|
|
69
|
+
dc.draw_arc(trg_pt.x, (src.y - r * ky).to_i, (trg.x - r * kx).to_i, src_pt.y, (trg.x - r * kx).to_i, (src.y - r * ky).to_i)
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
else
|
|
73
|
+
r = (dx * @max_radius/100).abs
|
|
74
|
+
r = @max_radius if r > @max_radius
|
|
75
|
+
|
|
76
|
+
dc.draw_line(src_pt.x, src_pt.y, src_pt.x, (trg.y + r * ky).to_i)
|
|
77
|
+
dc.draw_line((src.x + r * kx).to_i, trg_pt.y, trg_pt.x, trg_pt.y)
|
|
78
|
+
|
|
79
|
+
if r > 0
|
|
80
|
+
if (ky > 0 && kx > 0) || (ky < 0 && kx < 0)
|
|
81
|
+
dc.draw_arc((src.x + r * kx).to_i, trg_pt.y, src_pt.x, (trg.y + r * ky).to_i, (src.x + r * kx).to_i, (trg.y + r * ky).to_i)
|
|
82
|
+
else
|
|
83
|
+
dc.draw_arc(src_pt.x, (trg.y + r * ky).to_i, (src.x + r * kx).to_i, trg_pt.y, (src.x + r * kx).to_i, (trg.y + r * ky).to_i)
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
else
|
|
89
|
+
if direction < 1
|
|
90
|
+
r = (dy * @max_radius/100).abs
|
|
91
|
+
r = @max_radius if r > @max_radius
|
|
92
|
+
|
|
93
|
+
dc.draw_line(src_pt.x, src_pt.y, (pt_center.x - r * kx).to_i, src_pt.y)
|
|
94
|
+
dc.draw_line(pt_center.x.to_i, (src.y - r * ky).to_i, pt_center.x.to_i, (trg.y + r * ky).to_i)
|
|
95
|
+
dc.draw_line((pt_center.x + r * kx).to_i, trg_pt.y, trg_pt.x, trg_pt.y)
|
|
96
|
+
|
|
97
|
+
if r > 0
|
|
98
|
+
if (ky > 0 && kx > 0) || (ky < 0 && kx < 0)
|
|
99
|
+
dc.draw_arc((pt_center.x - r * kx).to_i, src_pt.y, pt_center.x.to_i, (src.y - r * ky).to_i, (pt_center.x - r * kx).to_i, (src.y - r * ky).to_i)
|
|
100
|
+
dc.draw_arc((pt_center.x + r * kx).to_i, trg_pt.y, pt_center.x.to_i, (trg.y + r * ky).to_i, (pt_center.x + r * kx).to_i, (trg.y + r * ky).to_i)
|
|
101
|
+
else
|
|
102
|
+
dc.draw_arc(pt_center.x.to_i, (src.y - r * ky).to_i, (pt_center.x - r * kx).to_i, src_pt.y, (pt_center.x - r * kx).to_i, (src.y - r * ky).to_i)
|
|
103
|
+
dc.draw_arc(pt_center.x.to_i, (trg.y + r * ky).to_i, (pt_center.x + r * kx).to_i, trg_pt.y, (pt_center.x + r * kx).to_i, (trg.y + r * ky).to_i)
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
else
|
|
107
|
+
r = (dx * @max_radius/100).abs
|
|
108
|
+
r = @max_radius if r > @max_radius
|
|
109
|
+
|
|
110
|
+
dc.draw_line(src_pt.x, src_pt.y, src_pt.x, (pt_center.y + r * ky).to_i)
|
|
111
|
+
dc.draw_line((src.x + r * kx).to_i, pt_center.y.to_i, (trg.x - r * kx).to_i, pt_center.y.to_i)
|
|
112
|
+
dc.draw_line(trg_pt.x, (pt_center.y - r * ky).to_i, trg_pt.x, trg_pt.y)
|
|
113
|
+
|
|
114
|
+
if r > 0
|
|
115
|
+
if (ky > 0 && kx > 0) || (ky < 0 && kx < 0)
|
|
116
|
+
dc.draw_arc((src.x + r * kx).to_i, pt_center.y.to_i, src_pt.x, (pt_center.y + r * ky).to_i, (src.x + r * kx).to_i, (pt_center.y + r * ky).to_i)
|
|
117
|
+
dc.draw_arc((trg.x - r * kx).to_i, pt_center.y.to_i, trg_pt.x, (pt_center.y - r * ky).to_i, (trg.x - r * kx).to_i, (pt_center.y - r * ky).to_i)
|
|
118
|
+
else
|
|
119
|
+
dc.draw_arc(src_pt.x, (pt_center.y + r * ky).to_i, (src.x + r * kx).to_i, pt_center.y.to_i, (src.x + r * kx).to_i, (pt_center.y + r * ky).to_i)
|
|
120
|
+
dc.draw_arc(trg_pt.x, (pt_center.y - r * ky).to_i, (trg.x - r * kx).to_i, pt_center.y.to_i, (trg.x - r * kx).to_i, (pt_center.y - r * ky).to_i)
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
end
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
# Wx::SF::RoundRectShape - rounded rectangle shape class
|
|
2
|
+
# Copyright (c) M.J.N. Corino, The Netherlands
|
|
3
|
+
|
|
4
|
+
module Wx::SF
|
|
5
|
+
|
|
6
|
+
# Class encapsulating rounded rectangle. It extends the basic rectangular shape.
|
|
7
|
+
class RoundRectShape < RectShape
|
|
8
|
+
|
|
9
|
+
RADIUS = 20
|
|
10
|
+
|
|
11
|
+
property :radius
|
|
12
|
+
|
|
13
|
+
# @overload initialize()
|
|
14
|
+
# Default constructor.
|
|
15
|
+
# @overload initialize(pos, size, diagram)
|
|
16
|
+
# User constructor.
|
|
17
|
+
# @param [Wx::RealPoint] pos Initial position
|
|
18
|
+
# @param [Wx::RealPoint] size Initial size
|
|
19
|
+
# @param [Float] radius Corner radius
|
|
20
|
+
# @param [Wx::SF::Diagram] diagram parent diagram
|
|
21
|
+
def initialize(*args)
|
|
22
|
+
if args.empty?
|
|
23
|
+
super
|
|
24
|
+
@radius = RADIUS
|
|
25
|
+
else
|
|
26
|
+
pos, size, @radius, diagram = args
|
|
27
|
+
super(pos, size, diagram)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Access (get/set) radius.
|
|
32
|
+
attr_accessor :radius
|
|
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
|
+
return super if @radius == 0.0
|
|
40
|
+
|
|
41
|
+
pos = pos.to_point
|
|
42
|
+
# get original bounding box
|
|
43
|
+
shp_bb = get_bounding_box
|
|
44
|
+
|
|
45
|
+
# calculate modified boxes
|
|
46
|
+
hr = shp_bb.deflate(0, @radius.to_i)
|
|
47
|
+
vr = shp_bb.deflate(@radius.to_i, 0)
|
|
48
|
+
|
|
49
|
+
# test whether given position is inside body rect or rounded corners
|
|
50
|
+
if hr.contains?(pos)
|
|
51
|
+
return true
|
|
52
|
+
elsif vr.contains?(pos)
|
|
53
|
+
return true
|
|
54
|
+
elsif in_circle?(pos, shp_bb.top_left + [@radius, @radius.to_i])
|
|
55
|
+
return true
|
|
56
|
+
elsif in_circle?(pos, shp_bb.bottom_left + [@radius.to_i, -@radius.to_i])
|
|
57
|
+
return true
|
|
58
|
+
elsif in_circle?(pos, shp_bb.top_right + [-@radius.to_i, @radius.to_i])
|
|
59
|
+
return true
|
|
60
|
+
elsif in_circle?(pos, shp_bb.bottom_right + [-@radius.to_i, -@radius.to_i])
|
|
61
|
+
return true
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
return false
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
protected
|
|
68
|
+
|
|
69
|
+
# Draw the shape in the normal way. 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_normal(dc)
|
|
72
|
+
if @radius == 0.0
|
|
73
|
+
super
|
|
74
|
+
return
|
|
75
|
+
end
|
|
76
|
+
dc.with_pen(@border) do
|
|
77
|
+
dc.with_brush(@fill) do
|
|
78
|
+
dc.draw_rounded_rectangle(get_absolute_position.to_point, @rect_size.to_size, @radius)
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# Draw the shape in the hover mode (the mouse cursor is above the shape).
|
|
84
|
+
# The function can be overridden if necessary.
|
|
85
|
+
# @param [Wx::DC] dc Reference to device context where the shape will be drawn to
|
|
86
|
+
def draw_hover(dc)
|
|
87
|
+
if @radius == 0.0
|
|
88
|
+
super
|
|
89
|
+
return
|
|
90
|
+
end
|
|
91
|
+
dc.with_pen(Wx::Pen.new(@hover_color, 1)) do
|
|
92
|
+
dc.with_brush(@fill) do
|
|
93
|
+
dc.draw_rounded_rectangle(get_absolute_position.to_point, @rect_size.to_size, @radius)
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# Draw the shape in the highlighted mode (another shape is dragged over this
|
|
99
|
+
# shape and this shape will accept the dragged one if it will be dropped on it).
|
|
100
|
+
# The function can be overridden if necessary.
|
|
101
|
+
# @param [Wx::DC] dc Reference to device context where the shape will be drawn to
|
|
102
|
+
def draw_highlighted(dc)
|
|
103
|
+
if @radius == 0.0
|
|
104
|
+
super
|
|
105
|
+
return
|
|
106
|
+
end
|
|
107
|
+
dc.with_pen(Wx::Pen.new(@hover_color, 2)) do
|
|
108
|
+
dc.with_brush(@fill) do
|
|
109
|
+
dc.draw_rounded_rectangle(get_absolute_position.to_point, @rect_size.to_size, @radius)
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# Draw shadow under the shape. The function can be overridden if necessary.
|
|
115
|
+
# @param [Wx::DC] dc Reference to device context where the shadow will be drawn to
|
|
116
|
+
def draw_shadow(dc)
|
|
117
|
+
if @radius == 0.0
|
|
118
|
+
super
|
|
119
|
+
return
|
|
120
|
+
end
|
|
121
|
+
if @fill.style != Wx::BrushStyle::BRUSHSTYLE_TRANSPARENT
|
|
122
|
+
dc.with_pen(Wx::TRANSPARENT_PEN) do
|
|
123
|
+
dc.with_brush(get_parent_canvas.get_shadow_fill) do
|
|
124
|
+
dc.draw_rounded_rectangle((get_absolute_position + get_parent_canvas.get_shadow_offset).to_point,
|
|
125
|
+
@rect_size.to_size, @radius)
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
# Auxiliary function. Checks whether the point is inside a circle with given center. The circle's radius
|
|
132
|
+
# is the rounded rect corner radius.
|
|
133
|
+
# @param [Wx::Point] pos Examined point
|
|
134
|
+
# @param [Wx::Point] center Circle center
|
|
135
|
+
# @return [Boolean]
|
|
136
|
+
def in_circle?(pos, center)
|
|
137
|
+
center.to_real_point.distance_to(pos.to_real_point) <= @radius
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
end
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# Wx::SF::SquareShape - square 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 SquareShape < RectShape
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
# @overload initialize()
|
|
12
|
+
# Default constructor.
|
|
13
|
+
# @overload initialize(pos, size, diagram)
|
|
14
|
+
# User constructor.
|
|
15
|
+
# @param [Wx::RealPoint] pos Initial position
|
|
16
|
+
# @param [Float] size Initial size
|
|
17
|
+
# @param [Wx::SF::Diagram] diagram parent diagram
|
|
18
|
+
def initialize(*args)
|
|
19
|
+
if args.empty?
|
|
20
|
+
super
|
|
21
|
+
set_rect_size(100,100)
|
|
22
|
+
else
|
|
23
|
+
pos, sz, diagram = args
|
|
24
|
+
super(pos, Wx::RealPoint.new(sz, sz), diagram)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Get shape's center. Default implementation does nothing. The function can be overridden if necessary.
|
|
29
|
+
# @return [Wx::RealPoint] Center point
|
|
30
|
+
def get_center
|
|
31
|
+
# Optimize
|
|
32
|
+
get_absolute_position + [@rect_size.x/2, @rect_size.y/2]
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
protected
|
|
36
|
+
|
|
37
|
+
# Scale the rectangle size for this shape.
|
|
38
|
+
# @param [Float] x Horizontal scale factor
|
|
39
|
+
# @param [Float] y Vertical scale factor
|
|
40
|
+
def scale_rectangle(x, y)
|
|
41
|
+
if x == 1.0
|
|
42
|
+
s = y
|
|
43
|
+
elsif y == 1.0
|
|
44
|
+
s = x
|
|
45
|
+
elsif x >= y
|
|
46
|
+
s = x
|
|
47
|
+
else
|
|
48
|
+
s = y
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
set_rect_size(@rect_size.x * s, @rect_size.y * s)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Handle's shape specific actions on handling handle events.
|
|
55
|
+
# The function can be overridden if necessary.
|
|
56
|
+
# @param [Shape::Handle] handle Reference to dragged handle
|
|
57
|
+
# @see #on_handle
|
|
58
|
+
def do_on_handle(handle)
|
|
59
|
+
prev_size = @rect_size.dup
|
|
60
|
+
|
|
61
|
+
# perform standard operations
|
|
62
|
+
case handle.type
|
|
63
|
+
when Shape::Handle::TYPE::LEFTTOP,
|
|
64
|
+
Shape::Handle::TYPE::LEFT,
|
|
65
|
+
Shape::Handle::TYPE::LEFTBOTTOM
|
|
66
|
+
on_left_handle(handle)
|
|
67
|
+
when Shape::Handle::TYPE::RIGHTTOP,
|
|
68
|
+
Shape::Handle::TYPE::RIGHT,
|
|
69
|
+
Shape::Handle::TYPE::RIGHTBOTTOM
|
|
70
|
+
on_right_handle(handle)
|
|
71
|
+
when Shape::Handle::TYPE::TOP
|
|
72
|
+
on_top_handle(handle)
|
|
73
|
+
when Shape::Handle::TYPE::BOTTOM
|
|
74
|
+
on_bottom_handle(handle)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# calculate common size and some auxiliary values
|
|
78
|
+
if (prev_size.x < @rect_size.x) || (prev_size.y < @rect_size.y)
|
|
79
|
+
if @rect_size.x >= @rect_size.y
|
|
80
|
+
maxsize = @rect_size.x
|
|
81
|
+
else
|
|
82
|
+
maxsize = @rect_size.y
|
|
83
|
+
end
|
|
84
|
+
else
|
|
85
|
+
if @rect_size.x <= @rect_size.y
|
|
86
|
+
maxsize = @rect_size.x
|
|
87
|
+
else
|
|
88
|
+
maxsize = @rect_size.y
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
dx = maxsize - @rect_size.x
|
|
93
|
+
dy = maxsize - @rect_size.y
|
|
94
|
+
|
|
95
|
+
# normalize rect sizes
|
|
96
|
+
@rect_size.x = @rect_size.y = maxsize
|
|
97
|
+
|
|
98
|
+
# move rect if necessary
|
|
99
|
+
case handle.type
|
|
100
|
+
when Shape::Handle::TYPE::LEFT
|
|
101
|
+
move_by(-dx, -dy / 2)
|
|
102
|
+
when Shape::Handle::TYPE::LEFTTOP
|
|
103
|
+
move_by(-dx, -dy)
|
|
104
|
+
when Shape::Handle::TYPE::LEFTBOTTOM
|
|
105
|
+
move_by(-dx, 0)
|
|
106
|
+
when Shape::Handle::TYPE::RIGHT
|
|
107
|
+
move_by(0, -dy / 2)
|
|
108
|
+
when Shape::Handle::TYPE::RIGHTTOP
|
|
109
|
+
move_by(0, -dy)
|
|
110
|
+
when Shape::Handle::TYPE::TOP
|
|
111
|
+
move_by(-dx / 2, -dy)
|
|
112
|
+
when Shape::Handle::TYPE::BOTTOM
|
|
113
|
+
move_by(-dx / 2, 0)
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
end
|
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
# Wx::SF::TextShape - text 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 TextShape < RectShape
|
|
9
|
+
|
|
10
|
+
# default values
|
|
11
|
+
module DEFAULT
|
|
12
|
+
# Default value of TextShape @font data member.
|
|
13
|
+
FONT = Wx::SWISS_FONT if Wx::App.is_main_loop_running
|
|
14
|
+
Wx.add_delayed_constant(self, :FONT) { Wx::SWISS_FONT }
|
|
15
|
+
# Default value of TextShape @text_color data member.
|
|
16
|
+
TEXTCOLOR = Wx::BLACK if Wx::App.is_main_loop_running
|
|
17
|
+
Wx.add_delayed_constant(self, :TEXTCOLOR) { Wx::BLACK }
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
property :font, :text_colour, :text
|
|
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 [String] txt Text content
|
|
28
|
+
# @param [Wx::SF::Diagram] diagram parent diagram
|
|
29
|
+
def initialize(*args)
|
|
30
|
+
txt = nil
|
|
31
|
+
if args.empty?
|
|
32
|
+
super
|
|
33
|
+
else
|
|
34
|
+
pos, txt, diagram = args
|
|
35
|
+
super(pos, Wx::RealPoint.new, diagram)
|
|
36
|
+
end
|
|
37
|
+
@font = DEFAULT::FONT
|
|
38
|
+
@font.set_point_size(12)
|
|
39
|
+
|
|
40
|
+
@line_height = 12
|
|
41
|
+
|
|
42
|
+
@text_color = DEFAULT::TEXTCOLOR
|
|
43
|
+
@text = txt || 'Text'
|
|
44
|
+
|
|
45
|
+
@fill = Wx::TRANSPARENT_BRUSH
|
|
46
|
+
@border = Wx::TRANSPARENT_PEN
|
|
47
|
+
@rect_size = Wx::RealPoint.new
|
|
48
|
+
|
|
49
|
+
update_rect_size
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Set text font.
|
|
53
|
+
# @param [Wx::Font] font Font
|
|
54
|
+
def set_font(font)
|
|
55
|
+
@font = font
|
|
56
|
+
update_rect_size
|
|
57
|
+
end
|
|
58
|
+
alias :font= :set_font
|
|
59
|
+
|
|
60
|
+
# Get text font.
|
|
61
|
+
# @return [Wx::Font] Font
|
|
62
|
+
def get_font
|
|
63
|
+
@font
|
|
64
|
+
end
|
|
65
|
+
alias :font :get_font
|
|
66
|
+
|
|
67
|
+
# Set text.
|
|
68
|
+
# @param [String] txt Text content
|
|
69
|
+
def set_text(txt)
|
|
70
|
+
@text = txt
|
|
71
|
+
update_rect_size
|
|
72
|
+
end
|
|
73
|
+
alias :text= :set_text
|
|
74
|
+
|
|
75
|
+
# Get text.
|
|
76
|
+
# @return [String] Current text content
|
|
77
|
+
def get_text
|
|
78
|
+
@text
|
|
79
|
+
end
|
|
80
|
+
alias :text :get_text
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
# Set text color.
|
|
84
|
+
# @param [Wx::Colour] col Text color
|
|
85
|
+
def set_text_colour(col)
|
|
86
|
+
@text_color = col
|
|
87
|
+
end
|
|
88
|
+
alias :text_colour= :set_text_colour
|
|
89
|
+
|
|
90
|
+
# Get text color.
|
|
91
|
+
# @return [Wx::Colour] Current text color
|
|
92
|
+
def get_text_colour
|
|
93
|
+
@text_color
|
|
94
|
+
end
|
|
95
|
+
alias :text_colour :get_text_colour
|
|
96
|
+
|
|
97
|
+
# Update shape (align all child shapes and resize it to fit them)
|
|
98
|
+
def update
|
|
99
|
+
update_rect_size
|
|
100
|
+
super
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# Returns size of current text using current font.
|
|
104
|
+
# @return [Wx::Size]
|
|
105
|
+
def get_text_extent
|
|
106
|
+
w = -1
|
|
107
|
+
h = -1
|
|
108
|
+
if get_parent_canvas
|
|
109
|
+
if ShapeCanvas.gc_enabled?
|
|
110
|
+
Wx::GraphicsContext.draw_on(get_parent_canvas) do |gc|
|
|
111
|
+
# calculate text extent
|
|
112
|
+
hd = -1
|
|
113
|
+
e = 0
|
|
114
|
+
|
|
115
|
+
gc.set_font(@font, Wx::BLACK)
|
|
116
|
+
|
|
117
|
+
# we must use split string to inspect all lines of possible multiline text
|
|
118
|
+
h = 0
|
|
119
|
+
@text.split("\n").each do |line|
|
|
120
|
+
wd, hd, d, e = gc.get_text_extent(line)
|
|
121
|
+
h += (hd + e).to_i
|
|
122
|
+
w = (wd + d).to_i if (wd + d) > w
|
|
123
|
+
end
|
|
124
|
+
@line_height = (hd + e).to_i
|
|
125
|
+
|
|
126
|
+
gc.set_font(Wx::NULL_FONT, Wx::BLACK)
|
|
127
|
+
end
|
|
128
|
+
else
|
|
129
|
+
get_parent_canvas.paint do |dc|
|
|
130
|
+
dc.set_font(@font)
|
|
131
|
+
w, h, @line_height = dc.get_multi_line_text_extent(@text)
|
|
132
|
+
dc.set_font(Wx::NULL_FONT)
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
else
|
|
136
|
+
w = @rect_size.x.to_i
|
|
137
|
+
h = @rect_size.y.to_i
|
|
138
|
+
@line_height = (@rect_size.y/@text.split("\n").size).to_i
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
Wx::Size.new(w, h)
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
# Updates rectangle size for this shape.
|
|
145
|
+
def update_rect_size
|
|
146
|
+
tsize = get_text_extent
|
|
147
|
+
|
|
148
|
+
if tsize.is_fully_specified
|
|
149
|
+
tsize.width = 1 if tsize.width <= 0
|
|
150
|
+
tsize.height = 1 if tsize.height <= 0
|
|
151
|
+
|
|
152
|
+
@rect_size.x = tsize.width.to_f
|
|
153
|
+
@rect_size.y = tsize.height.to_f
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
protected
|
|
158
|
+
|
|
159
|
+
# Scale the rectangle size for this shape.
|
|
160
|
+
# @param [Float] x Horizontal scale factor
|
|
161
|
+
# @param [Float] y Vertical scale factor
|
|
162
|
+
def scale_rectangle(x, y)
|
|
163
|
+
s = 1.0
|
|
164
|
+
|
|
165
|
+
if x == 1.0
|
|
166
|
+
s = y
|
|
167
|
+
elsif y == 1.0
|
|
168
|
+
s = x
|
|
169
|
+
elsif x >= y
|
|
170
|
+
s = x
|
|
171
|
+
else
|
|
172
|
+
s = y
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
size = @font.get_point_size * s
|
|
176
|
+
size = 5 if size < 5
|
|
177
|
+
|
|
178
|
+
@font.set_point_size(size)
|
|
179
|
+
update_rect_size
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
# Handle's shape specific actions on handling handle events.
|
|
183
|
+
# The function can be overridden if necessary.
|
|
184
|
+
# @param [Shape::Handle] handle Reference to dragged handle
|
|
185
|
+
# @see #on_handle
|
|
186
|
+
def do_on_handle(handle)
|
|
187
|
+
# HINT: overload it for custom actions...
|
|
188
|
+
prev_size = get_rect_size
|
|
189
|
+
|
|
190
|
+
# perform standard operations
|
|
191
|
+
case handle.get_type
|
|
192
|
+
when Shape::Handle::TYPE::LEFT
|
|
193
|
+
on_left_handle(handle)
|
|
194
|
+
when Shape::Handle::TYPE::RIGHT
|
|
195
|
+
on_right_handle(handle)
|
|
196
|
+
when Shape::Handle::TYPE::TOP
|
|
197
|
+
on_top_handle(handle)
|
|
198
|
+
when Shape::Handle::TYPE::BOTTOM
|
|
199
|
+
on_bottom_handle(handle)
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
new_size = @rect_size
|
|
203
|
+
|
|
204
|
+
sx = new_size.x / prev_size.x
|
|
205
|
+
sy = new_size.y / prev_size.y
|
|
206
|
+
scale(sx, sy)
|
|
207
|
+
|
|
208
|
+
case handle.get_type
|
|
209
|
+
when Shape::Handle::TYPE::LEFT
|
|
210
|
+
dx = @rect_size.x - prev_size.x
|
|
211
|
+
move_by(-dx, 0)
|
|
212
|
+
@child_shapes.each { |shape| shape.move_by(-dx, 0) }
|
|
213
|
+
|
|
214
|
+
when Shape::Handle::TYPE::TOP
|
|
215
|
+
dy = @rect_size.y - prev_size.y
|
|
216
|
+
move_by(0, -dy)
|
|
217
|
+
@child_shapes.each { |shape| shape.move_by(0, -dy) }
|
|
218
|
+
end
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
# Draw the shape in the normal way. The function can be overridden if necessary.
|
|
222
|
+
# @param [Wx::DC] dc Reference to device context where the shape will be drawn to
|
|
223
|
+
def draw_normal(dc)
|
|
224
|
+
super
|
|
225
|
+
draw_text_content(dc)
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
# Draw the shape in the hover mode (the mouse cursor is above the shape).
|
|
229
|
+
# The function can be overridden if necessary.
|
|
230
|
+
# @param [Wx::DC] dc Reference to device context where the shape will be drawn to
|
|
231
|
+
def draw_hover(dc)
|
|
232
|
+
super
|
|
233
|
+
draw_text_content(dc)
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
# Draw the shape in the highlighted mode (another shape is dragged over this
|
|
237
|
+
# shape and this shape will accept the dragged one if it will be dropped on it).
|
|
238
|
+
# The function can be overridden if neccessary.
|
|
239
|
+
# @param [Wx::DC] dc Reference to device context where the shape will be drawn to
|
|
240
|
+
def draw_highlighted(dc)
|
|
241
|
+
super
|
|
242
|
+
draw_text_content(dc)
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
# Draw shadow under the shape. The function can be overridden if necessary.
|
|
246
|
+
# @param [Wx::DC] dc Reference to device context where the shadow will be drawn to
|
|
247
|
+
def draw_shadow(dc)
|
|
248
|
+
# HINT: overload it for custom actions...
|
|
249
|
+
|
|
250
|
+
curr_color = @text_color
|
|
251
|
+
@text_color = get_parent_canvas.get_shadow_fill.get_colour
|
|
252
|
+
offset = get_parent_canvas.get_shadow_offset
|
|
253
|
+
|
|
254
|
+
move_by(offset)
|
|
255
|
+
draw_text_content(dc)
|
|
256
|
+
move_by(-offset.x, -offset.y)
|
|
257
|
+
|
|
258
|
+
@text_color = curr_color
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
# Event handler called during dragging of the left shape handle.
|
|
262
|
+
# The function can be overridden if necessary.
|
|
263
|
+
# @param [Shape::Handle] handle Reference to dragged shape handle
|
|
264
|
+
def on_left_handle(handle)
|
|
265
|
+
# HINT: overload it for custom actions...
|
|
266
|
+
|
|
267
|
+
@rect_size.x -= (handle.get_position.x - get_absolute_position.x)
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
# Event handler called during dragging of the top shape handle.
|
|
271
|
+
# The function can be overridden if necessary.
|
|
272
|
+
# @param [Shape::Handle]handle Reference to dragged shape handle
|
|
273
|
+
def on_top_handle(handle)
|
|
274
|
+
# HINT: overload it for custom actions...
|
|
275
|
+
|
|
276
|
+
@rect_size.y -= (handle.get_position.y - get_absolute_position.y)
|
|
277
|
+
end
|
|
278
|
+
|
|
279
|
+
# Event handler called during dragging of the right shape handle.
|
|
280
|
+
# The function can be overridden if neccessary.
|
|
281
|
+
# @param [Shape::Handle] handle Reference to dragged shape handle
|
|
282
|
+
def on_right_handle(handle)
|
|
283
|
+
# HINT: overload it for custom actions...
|
|
284
|
+
|
|
285
|
+
@rect_size.x = (handle.get_position.x - get_absolute_position.x)
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
# Event handler called during dragging of the bottom shape handle.
|
|
289
|
+
# The function can be overridden if neccessary.
|
|
290
|
+
# @param [Shape::Handle] handle Reference to dragged shape handle
|
|
291
|
+
def on_bottom_handle(handle)
|
|
292
|
+
# HINT: overload it for custom actions...
|
|
293
|
+
|
|
294
|
+
@rect_size.y = (handle.get_position.y - get_absolute_position.y)
|
|
295
|
+
end
|
|
296
|
+
|
|
297
|
+
# Draw text shape.
|
|
298
|
+
# @param [Wx::DC] dc Device context where the text shape will be drawn to
|
|
299
|
+
def draw_text_content(dc)
|
|
300
|
+
dc.with_brush(@fill) do
|
|
301
|
+
dc.set_background_mode(Wx::BrushStyle::BRUSHSTYLE_TRANSPARENT)
|
|
302
|
+
dc.set_text_foreground(@text_color)
|
|
303
|
+
dc.with_font(@font) do
|
|
304
|
+
pos = get_absolute_position
|
|
305
|
+
# draw all text lines
|
|
306
|
+
@text.split("\n").each_with_index do |line, i|
|
|
307
|
+
dc.draw_text(line, pos.x.to_i, pos.y.to_i + i*@line_height)
|
|
308
|
+
end
|
|
309
|
+
end
|
|
310
|
+
end
|
|
311
|
+
end
|
|
312
|
+
|
|
313
|
+
# Deserialize attributes and recalculate rectangle size afterwards.
|
|
314
|
+
# @param [Hash] data
|
|
315
|
+
# @return [self]
|
|
316
|
+
def from_serialized(data)
|
|
317
|
+
super
|
|
318
|
+
update_rect_size
|
|
319
|
+
self
|
|
320
|
+
end
|
|
321
|
+
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
end
|