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.
- checksums.yaml +4 -4
- data/INSTALL.md +5 -7
- data/README.md +38 -6
- data/assets/logo.svg +339 -0
- data/assets/logo.xpm +60 -0
- data/assets/screenshot.png +0 -0
- data/assets/social.png +0 -0
- data/bin/wx-shapes +1 -1
- data/lib/wx/shapes/arrow_base.rb +4 -11
- data/lib/wx/shapes/arrows/circle_arrow.rb +22 -11
- data/lib/wx/shapes/arrows/circle_prong_arrow.rb +48 -0
- data/lib/wx/shapes/arrows/cross_bar_arrow.rb +57 -0
- data/lib/wx/shapes/arrows/cross_bar_circle_arrow.rb +56 -0
- data/lib/wx/shapes/arrows/cross_bar_prong_arrow.rb +49 -0
- data/lib/wx/shapes/arrows/crossed_circle.rb +46 -0
- data/lib/wx/shapes/arrows/cup_arrow.rb +65 -0
- data/lib/wx/shapes/arrows/diamond_arrow.rb +8 -13
- data/lib/wx/shapes/arrows/double_cross_bar_arrow.rb +27 -0
- data/lib/wx/shapes/arrows/filled_arrow.rb +60 -0
- data/lib/wx/shapes/arrows/line_arrow.rb +67 -0
- data/lib/wx/shapes/arrows/open_arrow.rb +22 -23
- data/lib/wx/shapes/arrows/prong_arrow.rb +42 -0
- data/lib/wx/shapes/arrows/solid_arrow.rb +21 -35
- data/lib/wx/shapes/arrows/square_arrow.rb +37 -0
- data/lib/wx/shapes/auto_layout.rb +2 -2
- data/lib/wx/shapes/base.rb +1 -1
- data/lib/wx/shapes/canvas_history.rb +20 -0
- data/lib/wx/shapes/connection_point.rb +10 -6
- data/lib/wx/shapes/diagram.rb +98 -78
- data/lib/wx/shapes/events.rb +8 -8
- data/lib/wx/shapes/printout.rb +3 -16
- data/lib/wx/shapes/serializable.rb +2 -436
- data/lib/wx/shapes/serialize/wx.rb +30 -18
- data/lib/wx/shapes/shape.rb +211 -168
- data/lib/wx/shapes/shape_canvas.rb +728 -267
- data/lib/wx/shapes/shape_data_object.rb +99 -18
- data/lib/wx/shapes/shape_handle.rb +18 -11
- data/lib/wx/shapes/shape_list.rb +34 -67
- data/lib/wx/shapes/shapes/bitmap_shape.rb +23 -24
- data/lib/wx/shapes/shapes/box_shape.rb +389 -0
- data/lib/wx/shapes/shapes/circle_shape.rb +19 -22
- data/lib/wx/shapes/shapes/control_shape.rb +77 -41
- data/lib/wx/shapes/shapes/curve_shape.rb +38 -31
- data/lib/wx/shapes/shapes/diamond_shape.rb +7 -17
- data/lib/wx/shapes/shapes/edit_text_shape.rb +6 -9
- data/lib/wx/shapes/shapes/ellipse_shape.rb +12 -15
- data/lib/wx/shapes/shapes/flex_grid_shape.rb +58 -33
- data/lib/wx/shapes/shapes/grid_shape.rb +259 -161
- data/lib/wx/shapes/shapes/line_shape.rb +155 -161
- data/lib/wx/shapes/shapes/manager_shape.rb +77 -0
- data/lib/wx/shapes/shapes/multi_sel_rect.rb +8 -8
- data/lib/wx/shapes/shapes/ortho_shape.rb +31 -36
- data/lib/wx/shapes/shapes/polygon_shape.rb +23 -29
- data/lib/wx/shapes/shapes/rect_shape.rb +95 -53
- data/lib/wx/shapes/shapes/round_ortho_shape.rb +6 -8
- data/lib/wx/shapes/shapes/round_rect_shape.rb +20 -24
- data/lib/wx/shapes/shapes/square_shape.rb +14 -17
- data/lib/wx/shapes/shapes/text_shape.rb +95 -53
- data/lib/wx/shapes/version.rb +1 -1
- data/lib/wx/shapes/wx.rb +16 -7
- data/lib/wx/wx-shapes/cmd/test.rb +1 -1
- data/samples/demo/arrows.json +1 -0
- data/samples/demo/arrows.yaml +793 -0
- data/samples/demo/art/HBox.xpm +22 -0
- data/samples/demo/art/VBox.xpm +22 -0
- data/samples/demo/art/logo.xpm +60 -0
- data/samples/demo/class.json +1 -0
- data/samples/demo/class.yaml +5631 -0
- data/samples/demo/demo.rb +301 -91
- data/samples/demo/dialogs.rb +1405 -0
- data/samples/demo/erd.json +1 -0
- data/samples/demo/erd.yaml +4072 -0
- data/samples/demo/frame_canvas.rb +409 -33
- data/samples/sample1/art/logo.xpm +60 -0
- data/samples/sample1/sample.rb +11 -11
- data/samples/sample2/art/logo.xpm +60 -0
- data/samples/sample2/sample.rb +2 -2
- data/samples/sample2/sample_shape.rb +15 -15
- data/samples/sample3/art/logo.xpm +60 -0
- data/samples/sample3/sample.rb +3 -3
- data/samples/sample4/art/logo.xpm +60 -0
- data/samples/sample4/sample.rb +2 -2
- data/tests/lib/wxapp_runner.rb +4 -0
- data/tests/serializer_tests.rb +8 -441
- data/tests/test_grid_shapes.rb +2 -2
- data/tests/test_serialize_xml.rb +17 -0
- data/tests/test_serialize_yaml.rb +2 -2
- metadata +78 -28
- data/lib/wx/shapes/serialize/core.rb +0 -40
- data/lib/wx/shapes/serialize/id.rb +0 -82
- data/lib/wx/shapes/serializer/json.rb +0 -258
- data/lib/wx/shapes/serializer/yaml.rb +0 -125
- data/samples/demo/art/sample.xpm +0 -251
- data/samples/sample1/art/sample.xpm +0 -251
- data/samples/sample2/art/sample.xpm +0 -251
- data/samples/sample3/art/sample.xpm +0 -251
- data/samples/sample4/art/sample.xpm +0 -251
data/samples/demo/demo.rb
CHANGED
@@ -1,7 +1,9 @@
|
|
1
1
|
# Wx::SF - Demo ThumbFrame, MainFrame and App
|
2
2
|
# Copyright (c) M.J.N. Corino, The Netherlands
|
3
3
|
|
4
|
+
require 'nokogiri'
|
4
5
|
require 'wx/shapes'
|
6
|
+
require 'wx/mdap'
|
5
7
|
require_relative './frame_canvas'
|
6
8
|
|
7
9
|
class ThumbFrame < Wx::Frame
|
@@ -9,6 +11,8 @@ class ThumbFrame < Wx::Frame
|
|
9
11
|
def initialize(parent, title: 'Thumbnail', size: Wx::Size.new( 200,150 ), style: Wx::CAPTION|Wx::FRAME_FLOAT_ON_PARENT|Wx::FRAME_TOOL_WINDOW|Wx::RESIZE_BORDER|Wx::TAB_TRAVERSAL)
|
10
12
|
super
|
11
13
|
|
14
|
+
set_icon(Wx::Icon(:logo))
|
15
|
+
|
12
16
|
set_size_hints(Wx::DEFAULT_SIZE)
|
13
17
|
|
14
18
|
main_sizer = Wx::VBoxSizer.new
|
@@ -44,6 +48,8 @@ class MainFrame < Wx::Frame
|
|
44
48
|
GRID = self.new(14)
|
45
49
|
FLEXGRID = self.new(15)
|
46
50
|
STANDALONELINE = self.new(16)
|
51
|
+
VBOX = self.new(17)
|
52
|
+
HBOX = self.new(18)
|
47
53
|
end
|
48
54
|
|
49
55
|
module ID
|
@@ -52,12 +58,20 @@ class MainFrame < Wx::Frame
|
|
52
58
|
# menu IDs
|
53
59
|
#---------------------------------------------------------------#
|
54
60
|
M_SAVEASBITMAP = self.next_id
|
61
|
+
M_SHAPE_LIST = self.next_id
|
62
|
+
M_GRID_COLUMNS = self.next_id
|
63
|
+
M_GRIDCOLS_1 = self.next_id
|
64
|
+
M_GRIDCOLS_2 = self.next_id
|
65
|
+
M_GRIDCOLS_3 = self.next_id
|
66
|
+
M_GRIDCOLS_4 = self.next_id
|
67
|
+
M_GRIDCOLS_5 = self.next_id
|
68
|
+
M_GRIDCOLS_CUSTOM = self.next_id
|
69
|
+
M_GRIDCOLS_NR = self.next_id
|
55
70
|
|
56
71
|
# tool IDs
|
57
72
|
#---------------------------------------------------------------#
|
58
73
|
T_FIRST_TOOLMARKER = self.next_id
|
59
|
-
|
60
|
-
T_SHADOW = self.next_id
|
74
|
+
T_SETTINGS = self.next_id
|
61
75
|
T_GC = self.next_id
|
62
76
|
T_TOOL = self.next_id
|
63
77
|
T_RECTSHP = self.next_id
|
@@ -71,6 +85,8 @@ class MainFrame < Wx::Frame
|
|
71
85
|
T_BITMAPSHP = self.next_id
|
72
86
|
T_GRIDSHP = self.next_id
|
73
87
|
T_FLEXGRIDSHP = self.next_id
|
88
|
+
T_VBOXSHP = self.next_id
|
89
|
+
T_HBOXSHP = self.next_id
|
74
90
|
T_LINESHP = self.next_id
|
75
91
|
T_STANDALONELINESHP = self.next_id
|
76
92
|
T_CURVESHP = self.next_id
|
@@ -92,44 +108,165 @@ class MainFrame < Wx::Frame
|
|
92
108
|
#---------------------------------------------------------------#
|
93
109
|
T_COLORPICKER = self.next_id(M_AUTOLAYOUT_LAST) + 1
|
94
110
|
end
|
95
|
-
|
111
|
+
|
112
|
+
FILE_MASK = 'JSON files (*.json)|*.json|YAML files (*.yaml,*.yml)|*.yaml;*.yml|XML files (*.xml)|*.xml'
|
113
|
+
if Wx::PLATFORM == 'WXMSW'
|
114
|
+
FILE_MASK << '|All files (*.*)|*.*'
|
115
|
+
else
|
116
|
+
FILE_MASK << '|All files (*)|*'
|
117
|
+
end
|
118
|
+
|
119
|
+
class DiagramFileDialog < Wx::FileDialogCustomizeHook
|
120
|
+
|
121
|
+
FORMATS = %w[json yaml xml]
|
122
|
+
|
123
|
+
def initialize(dlg, compact: nil)
|
124
|
+
super()
|
125
|
+
@format = nil
|
126
|
+
@compact = compact.nil? ? nil : !!compact
|
127
|
+
@choice = nil
|
128
|
+
@checkbox = nil
|
129
|
+
@dialog = dlg
|
130
|
+
@dialog.set_customize_hook(self)
|
131
|
+
end
|
132
|
+
|
133
|
+
attr_reader :format, :compact
|
134
|
+
|
135
|
+
def add_custom_controls(customizer)
|
136
|
+
customizer.add_static_text('Format:')
|
137
|
+
@choice = customizer.add_choice(FORMATS)
|
138
|
+
unless @compact.nil?
|
139
|
+
@checkbox = customizer.add_check_box('Compact content')
|
140
|
+
@checkbox.set_value(true)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
def get_filter_index
|
145
|
+
if Wx::PLATFORM == 'WXGTK'
|
146
|
+
@dialog.get_filter_index
|
147
|
+
else
|
148
|
+
@dialog.get_currently_selected_filter_index
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
def update_custom_controls
|
153
|
+
if get_filter_index<0 || get_filter_index >= FORMATS.size
|
154
|
+
@choice.enable(true)
|
155
|
+
else
|
156
|
+
@choice.enable(false)
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
def transfer_data_from_custom_controls
|
161
|
+
@format = case @choice.get_selection
|
162
|
+
when Wx::NOT_FOUND then nil
|
163
|
+
else
|
164
|
+
FORMATS[@choice.get_selection].to_sym
|
165
|
+
end
|
166
|
+
@compact = @checkbox.get_value if @checkbox
|
167
|
+
@dialog = nil
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
96
171
|
def initialize(parent, title: 'wxShapeFramework Demo Application', style: Wx::CLOSE_BOX|Wx::DEFAULT_FRAME_STYLE|Wx::RESIZE_BORDER|Wx::TAB_TRAVERSAL)
|
97
172
|
super
|
98
173
|
|
99
|
-
set_icon(Wx::Icon(:
|
174
|
+
set_icon(Wx::Icon(:logo))
|
100
175
|
|
101
176
|
setup_frame
|
102
177
|
|
103
|
-
@file_menu
|
104
|
-
|
105
|
-
@file_menu.append
|
178
|
+
mi = Wx::MenuItem.new(@file_menu, Wx::ID_NEW, "&New\tCtrl+N", "New chart")
|
179
|
+
mi.set_bitmap(Wx::ArtProvider.get_bitmap(Wx::ART_NEW, Wx::ART_MENU))
|
180
|
+
@file_menu.append mi
|
181
|
+
mi = Wx::MenuItem.new(@file_menu, Wx::ID_OPEN, "&Open\tCtrl+O", "Load a chart from file")
|
182
|
+
mi.set_bitmap(Wx::ArtProvider.get_bitmap(Wx::ART_FILE_OPEN, Wx::ART_MENU))
|
183
|
+
@file_menu.append mi
|
184
|
+
mi = Wx::MenuItem.new(@file_menu, Wx::ID_SAVE, "&Save as...\tCtrl+Shift+S", "Save the chart to file")
|
185
|
+
mi.set_bitmap(Wx::ArtProvider.get_bitmap(Wx::ART_FILE_SAVE, Wx::ART_MENU))
|
186
|
+
@file_menu.append mi
|
106
187
|
@file_menu.append_separator
|
107
188
|
@file_menu.append(ID::M_SAVEASBITMAP, "&Export to image...", "Export the chart to BMP file", Wx::ITEM_NORMAL)
|
108
189
|
@file_menu.append_separator
|
109
|
-
@file_menu
|
110
|
-
|
190
|
+
mi = Wx::MenuItem.new(@file_menu, Wx::ID_PRINT, "&Print...\tCtrl+P", "Open print dialog")
|
191
|
+
mi.set_bitmap(Wx::ArtProvider.get_bitmap(Wx::ART_PRINT, Wx::ART_MENU))
|
192
|
+
@file_menu.append mi
|
193
|
+
mi = Wx::MenuItem.new(@file_menu, Wx::ID_PREVIEW, "Print pre&view...\tAlt+P", "Open print preview window")
|
194
|
+
mi.set_bitmap(Wx::ArtProvider.get_bitmap(Wx::ART_FIND, Wx::ART_MENU))
|
195
|
+
@file_menu.append mi
|
111
196
|
@file_menu.append(Wx::ID_PAGE_SETUP, "Pa&ge setup...", "Set print page properties", Wx::ITEM_NORMAL)
|
112
197
|
@file_menu.append_separator
|
113
|
-
@file_menu
|
114
|
-
|
115
|
-
@
|
116
|
-
|
198
|
+
mi = Wx::MenuItem.new(@file_menu, Wx::ID_EXIT, "E&xit\tAlt+X", "Close application")
|
199
|
+
mi.set_bitmap(Wx::ArtProvider.get_bitmap(Wx::ART_QUIT, Wx::ART_MENU))
|
200
|
+
@file_menu.append mi
|
201
|
+
|
202
|
+
mi = Wx::MenuItem.new(@edit_menu, Wx::ID_UNDO, "&Undo\tCtrl+Z", "Discard previous action")
|
203
|
+
mi.set_bitmap(Wx::ArtProvider.get_bitmap(Wx::ART_UNDO, Wx::ART_MENU))
|
204
|
+
@edit_menu.append mi
|
205
|
+
mi = Wx::MenuItem.new(@edit_menu, Wx::ID_REDO, "&Redo\tCtrl+Y", "Re-do previously discarded action")
|
206
|
+
mi.set_bitmap(Wx::ArtProvider.get_bitmap(Wx::ART_REDO, Wx::ART_MENU))
|
207
|
+
@edit_menu.append mi
|
117
208
|
@edit_menu.append_separator
|
118
|
-
@edit_menu
|
209
|
+
mi = Wx::MenuItem.new(@edit_menu, Wx::ID_SELECTALL, "Select &all\tCtrl+A", "Select all shapes")
|
210
|
+
mi.set_bitmap(Wx::ArtProvider.get_bitmap(Wx::MDAP::ART_SELECT_ALL, Wx::MDAP::ART_MATERIAL_DESIGN_OUTLINED,
|
211
|
+
Wx::ArtProvider.get_native_size_hint(Wx::ART_MENU)))
|
212
|
+
@edit_menu.append mi
|
119
213
|
@edit_menu.append_separator
|
120
|
-
@edit_menu
|
121
|
-
|
122
|
-
@edit_menu.append
|
214
|
+
mi = Wx::MenuItem.new(@edit_menu, Wx::ID_COPY, "&Copy\tCtrl+C", "Copy shapes to the clipboard")
|
215
|
+
mi.set_bitmap(Wx::ArtProvider.get_bitmap(Wx::ART_COPY, Wx::ART_MENU))
|
216
|
+
@edit_menu.append mi
|
217
|
+
mi = Wx::MenuItem.new(@edit_menu, Wx::ID_CUT, "Cu&t\tCtrl+X", "Cut shapes to the clipboard")
|
218
|
+
mi.set_bitmap(Wx::ArtProvider.get_bitmap(Wx::ART_CUT, Wx::ART_MENU))
|
219
|
+
@edit_menu.append mi
|
220
|
+
mi = Wx::MenuItem.new(@edit_menu, Wx::ID_PASTE, "&Paste\tCtrl+V", "Paste shapes to the canvas")
|
221
|
+
mi.set_bitmap(Wx::ArtProvider.get_bitmap(Wx::ART_PASTE, Wx::ART_MENU))
|
222
|
+
@edit_menu.append mi
|
223
|
+
|
224
|
+
submenu = Wx::Menu.new
|
225
|
+
submenu.append_radio_item(ID::T_TOOL, 'Design tool', 'Design tool')
|
226
|
+
submenu.append_radio_item(ID::T_RECTSHP, 'Rectangle', 'Rectangle')
|
227
|
+
submenu.append_radio_item(ID::T_SQUARESHP, 'Square', 'Square')
|
228
|
+
submenu.append_radio_item(ID::T_RNDRECTSHP, 'RoundRect', 'Rounded ractangle')
|
229
|
+
submenu.append_radio_item(ID::T_ELLIPSESHP, 'Ellipse', 'Ellipse')
|
230
|
+
submenu.append_radio_item(ID::T_CIRCLESHP, 'Circle', 'Circle')
|
231
|
+
submenu.append_radio_item(ID::T_DIAMONDSHP, 'Diamond', 'Diamond')
|
232
|
+
submenu.append_radio_item(ID::T_TEXTSHP, 'Text', 'Text')
|
233
|
+
submenu.append_radio_item(ID::T_EDITTEXTSHP, 'Editable Text', 'Editable Text')
|
234
|
+
submenu.append_radio_item(ID::T_BITMAPSHP, 'Bitmap', 'Bitmap')
|
235
|
+
submenu.append_radio_item(ID::T_GRIDSHP, 'Grid', 'Grid')
|
236
|
+
submenu.append_radio_item(ID::T_FLEXGRIDSHP, 'Flexible Grid', 'Flexible Grid')
|
237
|
+
submenu.append_radio_item(ID::T_VBOXSHP, 'Vertical Box', 'Vertical Box')
|
238
|
+
submenu.append_radio_item(ID::T_HBOXSHP, 'Horizontal Box', 'Horizontal Box')
|
239
|
+
submenu.append_radio_item(ID::T_LINESHP, 'Line', 'Connector Line')
|
240
|
+
submenu.append_radio_item(ID::T_CURVESHP, 'Curved Line', 'Curved Connector Line')
|
241
|
+
submenu.append_radio_item(ID::T_ORTHOSHP, 'Orthogonal Line', 'Orthogonal Connector Line')
|
242
|
+
submenu.append_radio_item(ID::T_RNDORTHOSHP, 'Rounded Orthogonal Line', 'Rounded Orthogonal Connector Line')
|
243
|
+
submenu.append_radio_item(ID::T_STANDALONELINESHP, 'Standalone Line', 'Standalone Line')
|
244
|
+
mi = Wx::MenuItem.new(@shape_menu, ID::M_SHAPE_LIST, 'Select shape', 'Select shape', Wx::ITEM_NORMAL, submenu)
|
245
|
+
@shape_menu.append(mi)
|
246
|
+
@shape_menu.append_separator
|
247
|
+
submenu = Wx::Menu.new
|
248
|
+
submenu.append_radio_item(ID::M_GRIDCOLS_1, '1 column', '1 column')
|
249
|
+
submenu.append_radio_item(ID::M_GRIDCOLS_2, '2 columns', '2 columns')
|
250
|
+
mi = submenu.append_radio_item(ID::M_GRIDCOLS_3, '3 columns', '3 columns')
|
251
|
+
mi.check(true)
|
252
|
+
submenu.append_radio_item(ID::M_GRIDCOLS_4, '4 columns', '4 columns')
|
253
|
+
submenu.append_radio_item(ID::M_GRIDCOLS_5, '5 columns', '5 columns')
|
254
|
+
@mi_gridcols_custom = submenu.append_radio_item(ID::M_GRIDCOLS_CUSTOM, 'Custom', 'Enter custom column number')
|
255
|
+
@mi_gridcol_nr = submenu.append(ID::M_GRIDCOLS_NR, 'Number of grid columns (3)', 'Select to change nr. of grid columns')
|
256
|
+
@mi_gridcol_nr.enable(false)
|
257
|
+
mi = Wx::MenuItem.new(@shape_menu, ID::M_GRID_COLUMNS, 'Set grid columns', 'Select number of grid columns', Wx::ITEM_NORMAL, submenu)
|
258
|
+
@shape_menu.append(mi)
|
123
259
|
|
124
260
|
Wx::SF::AutoLayout.layout_algorithms.each_with_index do |la_name, i|
|
125
261
|
@auto_layout_menu.append(ID::M_AUTOLAYOUT_FIRST + i, la_name)
|
126
262
|
end
|
127
|
-
|
128
|
-
@help_menu.append(Wx::ID_ABOUT, '&About...', 'About application...', Wx::ITEM_NORMAL)
|
129
263
|
|
130
|
-
|
131
|
-
|
132
|
-
@
|
264
|
+
mi = Wx::MenuItem.new(@help_menu, Wx::ID_ABOUT, '&About...', 'About application...')
|
265
|
+
mi.set_bitmap(Wx::ArtProvider.get_bitmap(Wx::ART_INFORMATION, Wx::ART_MENU))
|
266
|
+
@help_menu.append mi
|
267
|
+
|
268
|
+
# set shape canvas and associate it with a new, empty, diagram
|
269
|
+
@shape_canvas = FrameCanvas.new(Wx::SF::Diagram.new, @canvas_panel, Wx::ID_ANY)
|
133
270
|
@canvas_sizer.add(@shape_canvas, 1, Wx::EXPAND, 0)
|
134
271
|
@canvas_panel.layout
|
135
272
|
# enable using Wx::GraphicsContext by default
|
@@ -141,16 +278,7 @@ class MainFrame < Wx::Frame
|
|
141
278
|
@thumb_frm.thumbnail.set_canvas(@shape_canvas)
|
142
279
|
@thumb_frm.show
|
143
280
|
|
144
|
-
|
145
|
-
if Wx::PLATFORM == 'WXMSW'
|
146
|
-
@cpicker = Wx::ColourPickerCtrl.new(@tool_bar, ID::T_COLORPICKER, Wx::Colour.new(120, 120, 255), Wx::DEFAULT_POSITION, Wx::Size.new(22, 22))
|
147
|
-
else
|
148
|
-
@cpicker = Wx::ColourPickerCtrl.new(@tool_bar, ID::T_COLORPICKER, Wx::Colour.new(120, 120, 255), Wx::DEFAULT_POSITION, Wx::Size.new(28, 28))
|
149
|
-
end
|
150
|
-
@cpicker.set_tool_tip('Set hover color')
|
151
|
-
|
152
|
-
# add m_pToolBar tools
|
153
|
-
@tool_bar.set_tool_bitmap_size([16, 15])
|
281
|
+
# add tool_bar tools
|
154
282
|
@tool_bar.add_tool(Wx::ID_NEW, 'New', Wx::ArtProvider.get_bitmap(Wx::ART_NEW, Wx::ART_MENU), 'New diagram')
|
155
283
|
@tool_bar.add_tool(Wx::ID_OPEN, 'Load', Wx::ArtProvider.get_bitmap(Wx::ART_FILE_OPEN, Wx::ART_MENU), 'Open file...')
|
156
284
|
@tool_bar.add_tool(Wx::ID_SAVE, 'Save', Wx::ArtProvider.get_bitmap(Wx::ART_FILE_SAVE, Wx::ART_MENU), 'Save file...')
|
@@ -165,13 +293,11 @@ class MainFrame < Wx::Frame
|
|
165
293
|
@tool_bar.add_tool(Wx::ID_UNDO, 'Undo', Wx::ArtProvider.get_bitmap(Wx::ART_UNDO, Wx::ART_MENU), 'Undo')
|
166
294
|
@tool_bar.add_tool(Wx::ID_REDO, 'Redo', Wx::ArtProvider.get_bitmap(Wx::ART_REDO, Wx::ART_MENU), 'Redo')
|
167
295
|
@tool_bar.add_separator
|
168
|
-
@tool_bar.
|
169
|
-
@tool_bar.add_check_tool(ID::T_SHADOW, 'Shadows', Wx::Bitmap(:Shadow), Wx::NULL_BITMAP, 'Show/hide shadows')
|
170
|
-
@tool_bar.add_check_tool(ID::T_GC, 'Enhanced graphics context', Wx::Bitmap(:GC), Wx::NULL_BITMAP, 'Use enhanced graphics context (Wx::GraphicsContext)')
|
296
|
+
@tool_bar.add_tool(ID::T_SETTINGS, 'Settings', Wx::ArtProvider.get_bitmap(Wx::ART_HELP_SETTINGS, Wx::ART_MENU), 'Settings')
|
171
297
|
@tool_bar.add_separator
|
172
298
|
@tool_bar.add_radio_tool(ID::T_TOOL, 'Tool', Wx::Bitmap(:Tool), Wx::NULL_BITMAP, 'Design tool')
|
173
299
|
@tool_bar.add_radio_tool(ID::T_RECTSHP, 'Rectangle', Wx::Bitmap(:Rect), Wx::NULL_BITMAP, 'Rectangle')
|
174
|
-
@tool_bar.add_radio_tool(ID::T_SQUARESHP, '
|
300
|
+
@tool_bar.add_radio_tool(ID::T_SQUARESHP, 'Square', Wx::Bitmap(:FixedRect), Wx::NULL_BITMAP, 'Square')
|
175
301
|
@tool_bar.add_radio_tool(ID::T_RNDRECTSHP, 'RoundRect', Wx::Bitmap(:RoundRect), Wx::NULL_BITMAP, 'Rounded rectangle')
|
176
302
|
@tool_bar.add_radio_tool(ID::T_ELLIPSESHP, 'Ellipse', Wx::Bitmap(:Ellipse), Wx::NULL_BITMAP, 'Ellipse')
|
177
303
|
@tool_bar.add_radio_tool(ID::T_CIRCLESHP, 'Circle', Wx::Bitmap(:Circle), Wx::NULL_BITMAP, 'Circle')
|
@@ -181,6 +307,8 @@ class MainFrame < Wx::Frame
|
|
181
307
|
@tool_bar.add_radio_tool(ID::T_BITMAPSHP, 'Bitmap', Wx::Bitmap(:Bitmap), Wx::NULL_BITMAP, 'Bitmap')
|
182
308
|
@tool_bar.add_radio_tool(ID::T_GRIDSHP, 'Grid shape', Wx::Bitmap(:Grid), Wx::NULL_BITMAP, 'Grid shape')
|
183
309
|
@tool_bar.add_radio_tool(ID::T_FLEXGRIDSHP, 'Flexible grid shape', Wx::Bitmap(:FlexGrid), Wx::NULL_BITMAP, 'Flexible grid shape')
|
310
|
+
@tool_bar.add_radio_tool(ID::T_VBOXSHP, 'Vertical Box shape', Wx::Bitmap(:VBox), Wx::NULL_BITMAP, 'Vertical Box shape')
|
311
|
+
@tool_bar.add_radio_tool(ID::T_HBOXSHP, 'Horizontal Box shape', Wx::Bitmap(:HBox), Wx::NULL_BITMAP, 'Horizontal Box shape')
|
184
312
|
@tool_bar.add_radio_tool(ID::T_LINESHP, 'Line', Wx::Bitmap(:Line), Wx::NULL_BITMAP, 'Polyline connection')
|
185
313
|
@tool_bar.add_radio_tool(ID::T_CURVESHP, 'Curve', Wx::Bitmap(:Curve), Wx::NULL_BITMAP, 'Curve connection')
|
186
314
|
@tool_bar.add_radio_tool(ID::T_ORTHOSHP, 'Ortho line', Wx::Bitmap(:OrthoLine), Wx::NULL_BITMAP, 'Orthogonal connection')
|
@@ -193,17 +321,17 @@ class MainFrame < Wx::Frame
|
|
193
321
|
@tool_bar.add_tool(ID::T_ALIGN_BOTTOM, 'Align bottom', Wx::Bitmap(:AlignBottom), 'Align selected shapes to the bottom')
|
194
322
|
@tool_bar.add_tool(ID::T_ALIGN_MIDDLE, 'Align middle', Wx::Bitmap(:AlignMiddle), 'Align selected shapes to the middle')
|
195
323
|
@tool_bar.add_tool(ID::T_ALIGN_CENTER, 'Align center', Wx::Bitmap(:AlignCenter), 'Align selected shapes to the center')
|
196
|
-
@tool_bar.add_separator
|
197
|
-
@tool_bar.add_control(@cpicker)
|
198
324
|
@tool_bar.realize
|
199
325
|
|
200
326
|
@status_bar.set_status_text('Ready')
|
201
327
|
|
202
328
|
# initialize data members
|
203
329
|
@tool_mode = MODE::DESIGN
|
330
|
+
@grid_columns = 3
|
204
331
|
@show_grid = true
|
205
332
|
@show_shadows = false
|
206
333
|
|
334
|
+
set_size([1280, 800])
|
207
335
|
centre
|
208
336
|
|
209
337
|
# setup event handlers
|
@@ -226,6 +354,7 @@ class MainFrame < Wx::Frame
|
|
226
354
|
evt_menu_range(ID::M_AUTOLAYOUT_FIRST, ID::M_AUTOLAYOUT_LAST, :on_auto_layout)
|
227
355
|
evt_command_scroll(Wx::ID_ZOOM_FIT, :on_slider)
|
228
356
|
evt_tool_range(ID::T_FIRST_TOOLMARKER, ID::T_LAST_TOOLMARKER, :on_tool)
|
357
|
+
evt_menu_range(ID::M_GRIDCOLS_1, ID::M_GRIDCOLS_NR, :on_grid_columns)
|
229
358
|
evt_colourpicker_changed(ID::T_COLORPICKER, :on_hover_color)
|
230
359
|
evt_update_ui(Wx::ID_COPY, :on_update_copy)
|
231
360
|
evt_update_ui(Wx::ID_CUT, :on_update_cut)
|
@@ -234,19 +363,21 @@ class MainFrame < Wx::Frame
|
|
234
363
|
evt_update_ui(Wx::ID_REDO, :on_update_redo)
|
235
364
|
evt_update_ui_range(ID::T_FIRST_TOOLMARKER, ID::T_LAST_TOOLMARKER, :on_update_tool)
|
236
365
|
evt_update_ui_range(ID::M_AUTOLAYOUT_FIRST, ID::M_AUTOLAYOUT_LAST, :on_update_auto_layout)
|
366
|
+
evt_update_ui(@mi_gridcol_nr, :on_update_gridcol_nr)
|
237
367
|
evt_idle(:on_idle)
|
238
368
|
end
|
239
369
|
|
240
370
|
attr_accessor :tool_mode, :show_grid, :show_shadows
|
241
371
|
|
242
|
-
attr_reader :zoom_slider
|
372
|
+
attr_reader :grid_columns, :zoom_slider
|
373
|
+
|
374
|
+
def diagram
|
375
|
+
@shape_canvas&.diagram
|
376
|
+
end
|
377
|
+
private :diagram
|
243
378
|
|
244
379
|
def setup_frame
|
245
|
-
|
246
|
-
set_size_hints([1024,700])
|
247
|
-
else
|
248
|
-
set_size_hints([1100,700])
|
249
|
-
end
|
380
|
+
set_size_hints([1024, 640])
|
250
381
|
|
251
382
|
@menu_bar = Wx::MenuBar.new(0)
|
252
383
|
@file_menu = Wx::Menu.new
|
@@ -254,7 +385,10 @@ class MainFrame < Wx::Frame
|
|
254
385
|
|
255
386
|
@edit_menu = Wx::Menu.new
|
256
387
|
@menu_bar.append(@edit_menu, "&Edit")
|
257
|
-
|
388
|
+
|
389
|
+
@shape_menu = Wx::Menu.new
|
390
|
+
@menu_bar.append(@shape_menu, "&Shapes")
|
391
|
+
|
258
392
|
@auto_layout_menu = Wx::Menu.new
|
259
393
|
@menu_bar.append(@auto_layout_menu, "&AutoLayout")
|
260
394
|
|
@@ -262,22 +396,28 @@ class MainFrame < Wx::Frame
|
|
262
396
|
@menu_bar.append(@help_menu, "&Help")
|
263
397
|
|
264
398
|
set_menu_bar(@menu_bar)
|
265
|
-
|
266
|
-
@tool_bar = create_tool_bar(Wx::TB_HORIZONTAL, Wx::ID_ANY)
|
267
|
-
@tool_bar.realize
|
268
|
-
|
399
|
+
|
269
400
|
@status_bar = create_status_bar(1, Wx::STB_SIZEGRIP, Wx::ID_ANY)
|
270
|
-
main_sizer = Wx::FlexGridSizer.new(
|
401
|
+
main_sizer = Wx::FlexGridSizer.new(3, 1, 0, 0)
|
271
402
|
main_sizer.add_growable_col(0)
|
272
|
-
main_sizer.add_growable_row(
|
403
|
+
main_sizer.add_growable_row(1)
|
273
404
|
main_sizer.set_flexible_direction(Wx::BOTH)
|
274
405
|
main_sizer.set_non_flexible_grow_mode(Wx::FLEX_GROWMODE_SPECIFIED)
|
275
|
-
|
406
|
+
|
407
|
+
tool_bar_panel = Wx::Panel.new(self, Wx::ID_ANY)
|
408
|
+
tool_bar_sizer = Wx::VBoxSizer.new
|
409
|
+
@tool_bar = Wx::ToolBar.new(tool_bar_panel, style: Wx::TB_HORIZONTAL | Wx::NO_BORDER | Wx::TB_FLAT)
|
410
|
+
@tool_bar.realize
|
411
|
+
tool_bar_sizer.add(@tool_bar, 0, Wx::EXPAND)
|
412
|
+
tool_bar_panel.sizer = tool_bar_sizer
|
413
|
+
tool_bar_panel.layout
|
414
|
+
main_sizer.add(tool_bar_panel, 0, Wx::EXPAND, 5)
|
415
|
+
|
276
416
|
@canvas_panel = Wx::Panel.new(self, Wx::ID_ANY, style: Wx::TAB_TRAVERSAL)
|
277
417
|
@canvas_panel.set_extra_style(Wx::WS_EX_BLOCK_EVENTS)
|
278
418
|
|
279
419
|
@canvas_sizer = Wx::VBoxSizer.new
|
280
|
-
|
420
|
+
|
281
421
|
@canvas_panel.set_sizer(@canvas_sizer)
|
282
422
|
@canvas_panel.layout
|
283
423
|
@canvas_sizer.fit(@canvas_panel)
|
@@ -299,8 +439,8 @@ class MainFrame < Wx::Frame
|
|
299
439
|
protected
|
300
440
|
|
301
441
|
def clean_up
|
302
|
-
|
303
|
-
|
442
|
+
diagram.set_shape_canvas(nil)
|
443
|
+
diagram.clear
|
304
444
|
|
305
445
|
@thumb_frm.hide
|
306
446
|
@thumb_frm.thumbnail.set_canvas(nil)
|
@@ -314,7 +454,7 @@ class MainFrame < Wx::Frame
|
|
314
454
|
end
|
315
455
|
|
316
456
|
def on_idle(_event)
|
317
|
-
if
|
457
|
+
if diagram.is_modified
|
318
458
|
set_title('wxRuby ShapeFramework Demo (diagram is modified)')
|
319
459
|
else
|
320
460
|
set_title('wxRuby ShapeFramework Demo')
|
@@ -329,7 +469,7 @@ class MainFrame < Wx::Frame
|
|
329
469
|
def on_new(_event)
|
330
470
|
if Wx.message_box('Current chart will be lost. Do you want to proceed?',
|
331
471
|
'wxRuby ShapeFramework', Wx::YES_NO | Wx::ICON_QUESTION) == Wx::YES
|
332
|
-
|
472
|
+
diagram.clear
|
333
473
|
|
334
474
|
@shape_canvas.clear_canvas_history
|
335
475
|
@shape_canvas.save_canvas_state
|
@@ -339,24 +479,79 @@ class MainFrame < Wx::Frame
|
|
339
479
|
end
|
340
480
|
|
341
481
|
def on_save(_event)
|
342
|
-
Wx
|
482
|
+
Wx.FileDialog(self, 'Save canvas to file...', __dir__, '', FILE_MASK, Wx::FD_SAVE) do |dlg|
|
483
|
+
dlg.set_filter_index(0)
|
484
|
+
dlg_hook = DiagramFileDialog.new(dlg, compact: true)
|
343
485
|
if dlg.show_modal == Wx::ID_OK
|
344
|
-
|
345
|
-
|
346
|
-
|
486
|
+
check_overwrite = Wx::PLATFORM != 'WXOSX'
|
487
|
+
begin
|
488
|
+
path = dlg.get_path.dup
|
489
|
+
selected_filter = dlg.get_filter_index
|
490
|
+
ext = File.extname(path)
|
491
|
+
if ext == '.' && !(Wx::PLATFORM == 'WXOSX' && File.exist?(path))
|
492
|
+
ext = ''
|
493
|
+
path = File.join(File.dirname(path), File.basename(path, '.*'))
|
494
|
+
check_overwrite = true
|
495
|
+
end
|
496
|
+
if ext.empty?
|
497
|
+
format = if selected_filter < 0 || selected_filter >= DiagramFileDialog::FORMATS.size
|
498
|
+
dlg_hook.format || :json
|
499
|
+
else
|
500
|
+
DiagramFileDialog::FORMATS[selected_filter].to_sym
|
501
|
+
end
|
502
|
+
if selected_filter < DiagramFileDialog::FORMATS.size && !(Wx::PLATFORM == 'WXOSX' && File.exist?(path))
|
503
|
+
# determine extension to provide
|
504
|
+
case format
|
505
|
+
when :json then path << '.json'
|
506
|
+
when :yaml then path << '.yaml'
|
507
|
+
when :xml then path << '.xml'
|
508
|
+
end
|
509
|
+
check_overwrite = true
|
510
|
+
end
|
511
|
+
else
|
512
|
+
format = case File.extname(dlg.get_path)
|
513
|
+
when '.json' then :json
|
514
|
+
when '.yaml', '.yml' then :yaml
|
515
|
+
when '.xml' then :xml
|
516
|
+
else
|
517
|
+
if selected_filter < 0 || selected_filter >= DiagramFileDialog::FORMATS.size
|
518
|
+
dlg_hook.format || :json
|
519
|
+
else
|
520
|
+
DiagramFileDialog::FORMATS[selected_filter].to_sym
|
521
|
+
end
|
522
|
+
end
|
523
|
+
end
|
524
|
+
if !check_overwrite || !File.exist?(path) ||
|
525
|
+
Wx.message_box("File '#{File.basename(path)}' already exists in folder '#{File.dirname(path)}'.\nDo you want to overwrite it?", 'Confirm', Wx::YES_NO) == Wx::YES
|
526
|
+
@shape_canvas.save_canvas(path, compact: dlg_hook.compact, format: format)
|
527
|
+
|
528
|
+
Wx.MessageDialog(self, "The chart has been saved to '#{path}'.", 'wxRuby ShapeFramework', Wx::OK | Wx::ICON_INFORMATION)
|
529
|
+
end
|
530
|
+
rescue Exception => ex
|
531
|
+
Wx.MessageDialog(self, "Failed to save the chart: #{ex.message}", 'wxRuby ShapeFramework', Wx::OK | Wx::ICON_ERROR)
|
532
|
+
end
|
347
533
|
end
|
348
534
|
end
|
349
535
|
end
|
350
536
|
|
351
537
|
def on_load(_event)
|
352
|
-
Wx
|
538
|
+
Wx.FileDialog(self, 'Load canvas from file...', __dir__, '', FILE_MASK, Wx::FD_OPEN | Wx::FD_FILE_MUST_EXIST) do |dlg|
|
539
|
+
dlg_hook = DiagramFileDialog.new(dlg)
|
353
540
|
if dlg.show_modal == Wx::ID_OK
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
541
|
+
begin
|
542
|
+
format = case File.extname(dlg.get_path)
|
543
|
+
when '.json' then :json
|
544
|
+
when '.yaml', '.yml' then :yaml
|
545
|
+
when '.xml' then :xml
|
546
|
+
else
|
547
|
+
dlg_hook.format || :json
|
548
|
+
end
|
549
|
+
@shape_canvas.load_canvas(dlg.get_path, format: format)
|
550
|
+
|
551
|
+
@zoom_slider.set_value((@shape_canvas.get_scale*50).to_i)
|
552
|
+
rescue Exception => ex
|
553
|
+
Wx.MessageDialog(self, "Failed to load the chart: #{ex.message}", 'wxRuby ShapeFramework', Wx::OK | Wx::ICON_ERROR)
|
554
|
+
end
|
360
555
|
end
|
361
556
|
end
|
362
557
|
end
|
@@ -448,30 +643,14 @@ class MainFrame < Wx::Frame
|
|
448
643
|
@shape_canvas.abort_interactive_connection if @shape_canvas.get_mode == Wx::SF::ShapeCanvas::MODE::CREATECONNECTION
|
449
644
|
|
450
645
|
case event.get_id
|
451
|
-
when ID::
|
452
|
-
@
|
453
|
-
if @show_grid
|
454
|
-
@shape_canvas.add_style(Wx::SF::ShapeCanvas::STYLE::GRID_SHOW)
|
455
|
-
@shape_canvas.add_style(Wx::SF::ShapeCanvas::STYLE::GRID_USE)
|
456
|
-
else
|
457
|
-
@shape_canvas.remove_style(Wx::SF::ShapeCanvas::STYLE::GRID_SHOW)
|
458
|
-
@shape_canvas.remove_style(Wx::SF::ShapeCanvas::STYLE::GRID_USE)
|
459
|
-
end
|
460
|
-
@shape_canvas.refresh(false)
|
461
|
-
|
462
|
-
when ID::T_SHADOW
|
463
|
-
@show_shadows = !@show_shadows
|
464
|
-
|
465
|
-
@shape_canvas.show_shadows(@show_shadows, Wx::SF::ShapeCanvas::SHADOWMODE::ALL)
|
466
|
-
# also shadows for topmost shapes only are allowed:
|
467
|
-
# @shape_canvas.show_shadows(@show_shadows, Wx::SF::ShapeCanvas::SHADOWMODE::TOPMOST)
|
468
|
-
@shape_canvas.refresh(false)
|
646
|
+
when ID::T_SETTINGS
|
647
|
+
Dialogs::WXSFPreferencesDialog(self, @shape_canvas)
|
469
648
|
|
470
649
|
when ID::T_GC
|
471
650
|
if Wx.has_feature?(:USE_GRAPHICS_CONTEXT)
|
472
651
|
Wx::SF::ShapeCanvas.enable_gc(!Wx::SF::ShapeCanvas.gc_enabled?)
|
473
652
|
# update all shapes in the manager
|
474
|
-
|
653
|
+
diagram.update_all
|
475
654
|
# refresh shape canvas
|
476
655
|
@shape_canvas.refresh(false)
|
477
656
|
else
|
@@ -508,6 +687,12 @@ class MainFrame < Wx::Frame
|
|
508
687
|
when ID::T_FLEXGRIDSHP
|
509
688
|
@tool_mode = MODE::FLEXGRID
|
510
689
|
|
690
|
+
when ID::T_VBOXSHP
|
691
|
+
@tool_mode = MODE::VBOX
|
692
|
+
|
693
|
+
when ID::T_HBOXSHP
|
694
|
+
@tool_mode = MODE::HBOX
|
695
|
+
|
511
696
|
when ID::T_LINESHP
|
512
697
|
@tool_mode = MODE::LINE
|
513
698
|
|
@@ -552,6 +737,16 @@ class MainFrame < Wx::Frame
|
|
552
737
|
end
|
553
738
|
end
|
554
739
|
|
740
|
+
def on_grid_columns(event)
|
741
|
+
if event.get_id == ID::M_GRIDCOLS_CUSTOM || event.get_id == ID::M_GRIDCOLS_NR
|
742
|
+
n = Wx.get_number_from_user('Enter custom grid column number.', 'Nr. of columns:',
|
743
|
+
'Grid columns', @grid_columns, 1, 100, self)
|
744
|
+
@grid_columns = n unless n <= 0
|
745
|
+
else
|
746
|
+
@grid_columns = 1 + event.get_id-ID::M_GRIDCOLS_1
|
747
|
+
end
|
748
|
+
end
|
749
|
+
|
555
750
|
def on_hover_color(event)
|
556
751
|
@shape_canvas.set_hover_colour(event.get_colour)
|
557
752
|
end
|
@@ -578,9 +773,6 @@ class MainFrame < Wx::Frame
|
|
578
773
|
|
579
774
|
def on_update_tool(event)
|
580
775
|
case event.get_id
|
581
|
-
when ID::T_GRID
|
582
|
-
event.check(@show_grid)
|
583
|
-
|
584
776
|
when ID::T_GC
|
585
777
|
event.check(Wx::SF::ShapeCanvas.gc_enabled?)
|
586
778
|
|
@@ -614,6 +806,12 @@ class MainFrame < Wx::Frame
|
|
614
806
|
when ID::T_FLEXGRIDSHP
|
615
807
|
event.check(@tool_mode == MODE::FLEXGRID)
|
616
808
|
|
809
|
+
when ID::T_VBOXSHP
|
810
|
+
event.check(@tool_mode == MODE::VBOX)
|
811
|
+
|
812
|
+
when ID::T_HBOXSHP
|
813
|
+
event.check(@tool_mode == MODE::HBOX)
|
814
|
+
|
617
815
|
when ID::T_LINESHP
|
618
816
|
event.check(@tool_mode == MODE::LINE)
|
619
817
|
|
@@ -649,10 +847,22 @@ class MainFrame < Wx::Frame
|
|
649
847
|
end
|
650
848
|
|
651
849
|
def on_update_auto_layout(event)
|
652
|
-
event.enable(
|
850
|
+
event.enable(!diagram.empty?)
|
851
|
+
end
|
852
|
+
|
853
|
+
def on_update_gridcol_nr(_event)
|
854
|
+
@mi_gridcol_nr.enable(@mi_gridcols_custom.checked?)
|
855
|
+
@mi_gridcol_nr.set_item_label("Number of grid columns (#{@grid_columns})")
|
653
856
|
end
|
857
|
+
|
858
|
+
end
|
859
|
+
|
860
|
+
if Wx::PLATFORM == 'WXOSX' && !Wx.const_defined?(:OSX_FILEDIALOG_ALWAYS_SHOW_TYPES)
|
861
|
+
Wx::OSX_FILEDIALOG_ALWAYS_SHOW_TYPES = 'osx.openfiledialog.always-show-types'
|
654
862
|
end
|
655
863
|
|
656
864
|
Wx::App.run do
|
865
|
+
Wx::SystemOptions.set_option(Wx::OSX_FILEDIALOG_ALWAYS_SHOW_TYPES, 1) if Wx::PLATFORM == 'WXOSX'
|
866
|
+
Wx::ArtProvider.push(Wx::MDAP::MaterialDesignArtProvider.new)
|
657
867
|
MainFrame.new(nil).show
|
658
868
|
end
|