wxruby3-shapes 0.9.0.pre.beta.3 → 0.9.6
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 +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
|