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.
Files changed (112) hide show
  1. checksums.yaml +7 -0
  2. data/.yardopts +12 -0
  3. data/CREDITS.md +18 -0
  4. data/INSTALL.md +39 -0
  5. data/LICENSE +21 -0
  6. data/README.md +118 -0
  7. data/assets/screenshot.png +0 -0
  8. data/bin/wx-shapes +9 -0
  9. data/lib/wx/shapes/arrow_base.rb +86 -0
  10. data/lib/wx/shapes/arrows/circle_arrow.rb +39 -0
  11. data/lib/wx/shapes/arrows/diamond_arrow.rb +33 -0
  12. data/lib/wx/shapes/arrows/open_arrow.rb +56 -0
  13. data/lib/wx/shapes/arrows/solid_arrow.rb +69 -0
  14. data/lib/wx/shapes/art/shape_canvas/page.xpm +73 -0
  15. data/lib/wx/shapes/auto_layout.rb +358 -0
  16. data/lib/wx/shapes/base.rb +33 -0
  17. data/lib/wx/shapes/canvas_history.rb +84 -0
  18. data/lib/wx/shapes/connection_point.rb +238 -0
  19. data/lib/wx/shapes/core.rb +19 -0
  20. data/lib/wx/shapes/diagram.rb +659 -0
  21. data/lib/wx/shapes/events.rb +389 -0
  22. data/lib/wx/shapes/printout.rb +136 -0
  23. data/lib/wx/shapes/serializable.rb +440 -0
  24. data/lib/wx/shapes/serialize/core.rb +40 -0
  25. data/lib/wx/shapes/serialize/id.rb +82 -0
  26. data/lib/wx/shapes/serialize/wx.rb +104 -0
  27. data/lib/wx/shapes/serializer/json.rb +258 -0
  28. data/lib/wx/shapes/serializer/yaml.rb +125 -0
  29. data/lib/wx/shapes/shape.rb +2129 -0
  30. data/lib/wx/shapes/shape_canvas.rb +3285 -0
  31. data/lib/wx/shapes/shape_data_object.rb +43 -0
  32. data/lib/wx/shapes/shape_handle.rb +287 -0
  33. data/lib/wx/shapes/shape_list.rb +161 -0
  34. data/lib/wx/shapes/shapes/bitmap_shape.rb +257 -0
  35. data/lib/wx/shapes/shapes/circle_shape.rb +136 -0
  36. data/lib/wx/shapes/shapes/control_shape.rb +483 -0
  37. data/lib/wx/shapes/shapes/curve_shape.rb +231 -0
  38. data/lib/wx/shapes/shapes/diamond_shape.rb +62 -0
  39. data/lib/wx/shapes/shapes/edit_text_shape.rb +317 -0
  40. data/lib/wx/shapes/shapes/ellipse_shape.rb +106 -0
  41. data/lib/wx/shapes/shapes/flex_grid_shape.rb +78 -0
  42. data/lib/wx/shapes/shapes/grid_shape.rb +404 -0
  43. data/lib/wx/shapes/shapes/line_shape.rb +907 -0
  44. data/lib/wx/shapes/shapes/multi_sel_rect.rb +214 -0
  45. data/lib/wx/shapes/shapes/ortho_shape.rb +357 -0
  46. data/lib/wx/shapes/shapes/polygon_shape.rb +294 -0
  47. data/lib/wx/shapes/shapes/rect_shape.rb +378 -0
  48. data/lib/wx/shapes/shapes/round_ortho_shape.rb +131 -0
  49. data/lib/wx/shapes/shapes/round_rect_shape.rb +142 -0
  50. data/lib/wx/shapes/shapes/square_shape.rb +119 -0
  51. data/lib/wx/shapes/shapes/text_shape.rb +324 -0
  52. data/lib/wx/shapes/thumbnail.rb +234 -0
  53. data/lib/wx/shapes/version.rb +12 -0
  54. data/lib/wx/shapes/wx.rb +29 -0
  55. data/lib/wx/shapes.rb +18 -0
  56. data/lib/wx/wx-shapes/base.rb +87 -0
  57. data/lib/wx/wx-shapes/cmd/sampler.rb +58 -0
  58. data/lib/wx/wx-shapes/cmd/test.rb +27 -0
  59. data/rakelib/yard/templates/default/fulldoc/html/css/wxruby3.css +7 -0
  60. data/rakelib/yard/templates/default/layout/html/setup.rb +5 -0
  61. data/rakelib/yard/yard/relative_markdown_links/version.rb +8 -0
  62. data/rakelib/yard/yard/relative_markdown_links.rb +39 -0
  63. data/rakelib/yard/yard-custom-templates.rb +2 -0
  64. data/rakelib/yard/yard-relative_markdown_links.rb +4 -0
  65. data/samples/demo/art/AlignBottom.xpm +35 -0
  66. data/samples/demo/art/AlignCenter.xpm +35 -0
  67. data/samples/demo/art/AlignLeft.xpm +35 -0
  68. data/samples/demo/art/AlignMiddle.xpm +35 -0
  69. data/samples/demo/art/AlignRight.xpm +35 -0
  70. data/samples/demo/art/AlignTop.xpm +35 -0
  71. data/samples/demo/art/Bitmap.xpm +25 -0
  72. data/samples/demo/art/Circle.xpm +22 -0
  73. data/samples/demo/art/Curve.xpm +21 -0
  74. data/samples/demo/art/Diamond.xpm +22 -0
  75. data/samples/demo/art/EditText.xpm +21 -0
  76. data/samples/demo/art/Ellipse.xpm +22 -0
  77. data/samples/demo/art/FixedRect.xpm +22 -0
  78. data/samples/demo/art/FlexGrid.xpm +22 -0
  79. data/samples/demo/art/GC.xpm +23 -0
  80. data/samples/demo/art/Grid.xpm +22 -0
  81. data/samples/demo/art/Line.xpm +21 -0
  82. data/samples/demo/art/NoSource.xpm +69 -0
  83. data/samples/demo/art/OrthoLine.xpm +21 -0
  84. data/samples/demo/art/Rect.xpm +22 -0
  85. data/samples/demo/art/RoundOrthoLine.xpm +21 -0
  86. data/samples/demo/art/RoundRect.xpm +22 -0
  87. data/samples/demo/art/Shadow.xpm +23 -0
  88. data/samples/demo/art/StandAloneLine.xpm +22 -0
  89. data/samples/demo/art/Text.xpm +21 -0
  90. data/samples/demo/art/Tool.xpm +23 -0
  91. data/samples/demo/art/sample.xpm +251 -0
  92. data/samples/demo/demo.rb +658 -0
  93. data/samples/demo/frame_canvas.rb +422 -0
  94. data/samples/demo/images/motyl.bmp +0 -0
  95. data/samples/demo/images/motyl2.bmp +0 -0
  96. data/samples/sample1/art/sample.xpm +251 -0
  97. data/samples/sample1/sample.rb +263 -0
  98. data/samples/sample2/art/sample.xpm +251 -0
  99. data/samples/sample2/sample.rb +133 -0
  100. data/samples/sample2/sample_canvas.rb +35 -0
  101. data/samples/sample2/sample_shape.rb +108 -0
  102. data/samples/sample3/art/sample.xpm +251 -0
  103. data/samples/sample3/sample.rb +281 -0
  104. data/samples/sample4/art/sample.xpm +251 -0
  105. data/samples/sample4/sample.rb +180 -0
  106. data/tests/art/motyl.bmp +0 -0
  107. data/tests/lib/wxapp_runner.rb +64 -0
  108. data/tests/serializer_tests.rb +521 -0
  109. data/tests/test_grid_shapes.rb +42 -0
  110. data/tests/test_serialize.rb +7 -0
  111. data/tests/test_serialize_yaml.rb +17 -0
  112. metadata +242 -0
@@ -0,0 +1,658 @@
1
+ # Wx::SF - Demo ThumbFrame, MainFrame and App
2
+ # Copyright (c) M.J.N. Corino, The Netherlands
3
+
4
+ require 'wx/shapes'
5
+ require_relative './frame_canvas'
6
+
7
+ class ThumbFrame < Wx::Frame
8
+
9
+ 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
+ super
11
+
12
+ set_size_hints(Wx::DEFAULT_SIZE)
13
+
14
+ main_sizer = Wx::VBoxSizer.new
15
+
16
+ @thumbnail = Wx::SF::Thumbnail.new(self)
17
+ main_sizer.add(@thumbnail, 1, Wx::EXPAND, 0)
18
+
19
+ set_sizer(main_sizer)
20
+ layout
21
+ end
22
+
23
+ attr_reader :thumbnail
24
+
25
+ end
26
+
27
+ class MainFrame < Wx::Frame
28
+
29
+ class MODE < Wx::Enum
30
+ DESIGN = self.new(0)
31
+ RECT = self.new(1)
32
+ FIXEDRECT = self.new(2)
33
+ ROUNDRECT = self.new(3)
34
+ ELLIPSE = self.new(4)
35
+ CIRCLE = self.new(5)
36
+ DIAMOND = self.new(6)
37
+ TEXT = self.new(7)
38
+ EDITTEXT = self.new(8)
39
+ BITMAP = self.new(9)
40
+ LINE = self.new(10)
41
+ CURVE = self.new(11)
42
+ ORTHOLINE = self.new(12)
43
+ ROUNDORTHOLINE = self.new(13)
44
+ GRID = self.new(14)
45
+ FLEXGRID = self.new(15)
46
+ STANDALONELINE = self.new(16)
47
+ end
48
+
49
+ module ID
50
+ include Wx::IDHelper
51
+
52
+ # menu IDs
53
+ #---------------------------------------------------------------#
54
+ M_SAVEASBITMAP = self.next_id
55
+
56
+ # tool IDs
57
+ #---------------------------------------------------------------#
58
+ T_FIRST_TOOLMARKER = self.next_id
59
+ T_GRID = self.next_id
60
+ T_SHADOW = self.next_id
61
+ T_GC = self.next_id
62
+ T_TOOL = self.next_id
63
+ T_RECTSHP = self.next_id
64
+ T_SQUARESHP = self.next_id
65
+ T_RNDRECTSHP = self.next_id
66
+ T_ELLIPSESHP = self.next_id
67
+ T_CIRCLESHP = self.next_id
68
+ T_DIAMONDSHP = self.next_id
69
+ T_TEXTSHP = self.next_id
70
+ T_EDITTEXTSHP = self.next_id
71
+ T_BITMAPSHP = self.next_id
72
+ T_GRIDSHP = self.next_id
73
+ T_FLEXGRIDSHP = self.next_id
74
+ T_LINESHP = self.next_id
75
+ T_STANDALONELINESHP = self.next_id
76
+ T_CURVESHP = self.next_id
77
+ T_ORTHOSHP = self.next_id
78
+ T_RNDORTHOSHP = self.next_id
79
+ T_ALIGN_LEFT = self.next_id
80
+ T_ALIGN_RIGHT = self.next_id
81
+ T_ALIGN_TOP = self.next_id
82
+ T_ALIGN_BOTTOM = self.next_id
83
+ T_ALIGN_MIDDLE = self.next_id
84
+ T_ALIGN_CENTER = self.next_id
85
+
86
+ T_LAST_TOOLMARKER = self.next_id
87
+
88
+ M_AUTOLAYOUT_FIRST = self.next_id
89
+ M_AUTOLAYOUT_LAST = M_AUTOLAYOUT_FIRST + 100
90
+
91
+ # other controls
92
+ #---------------------------------------------------------------#
93
+ T_COLORPICKER = self.next_id(M_AUTOLAYOUT_LAST) + 1
94
+ end
95
+
96
+ def initialize(parent, title: 'wxShapeFramework Demo Application', style: Wx::CLOSE_BOX|Wx::DEFAULT_FRAME_STYLE|Wx::RESIZE_BORDER|Wx::TAB_TRAVERSAL)
97
+ super
98
+
99
+ set_icon(Wx::Icon(:sample))
100
+
101
+ setup_frame
102
+
103
+ @file_menu.append(Wx::ID_NEW, "&New\tCtrl+N", "New chart", Wx::ITEM_NORMAL)
104
+ @file_menu.append(Wx::ID_OPEN, "&Open\tCtrl+O", "Load a chart from file", Wx::ITEM_NORMAL)
105
+ @file_menu.append(Wx::ID_SAVE, "&Save as...\tCtrl+Shift+S", "Save the chart to file", Wx::ITEM_NORMAL)
106
+ @file_menu.append_separator
107
+ @file_menu.append(ID::M_SAVEASBITMAP, "&Export to image...", "Export the chart to BMP file", Wx::ITEM_NORMAL)
108
+ @file_menu.append_separator
109
+ @file_menu.append(Wx::ID_PRINT, "&Print...\tCtrl+P", "Open print dialog", Wx::ITEM_NORMAL)
110
+ @file_menu.append(Wx::ID_PREVIEW, "Print pre&view...\tAlt+P", "Open print preview window", Wx::ITEM_NORMAL)
111
+ @file_menu.append(Wx::ID_PAGE_SETUP, "Pa&ge setup...", "Set print page properties", Wx::ITEM_NORMAL)
112
+ @file_menu.append_separator
113
+ @file_menu.append(Wx::ID_EXIT, "E&xit\tAlt+X", "Close application", Wx::ITEM_NORMAL)
114
+
115
+ @edit_menu.append(Wx::ID_UNDO, "&Undo\tCtrl+Z", "Discard previous action", Wx::ITEM_NORMAL)
116
+ @edit_menu.append(Wx::ID_REDO, "&Redo\tCtrl+Y", "Re-do previously discarded action", Wx::ITEM_NORMAL)
117
+ @edit_menu.append_separator
118
+ @edit_menu.append(Wx::ID_SELECTALL, "Select &all\tCtrl+A", "Select all shapes", Wx::ITEM_NORMAL)
119
+ @edit_menu.append_separator
120
+ @edit_menu.append(Wx::ID_COPY, "&Copy\tCtrl+C", "Copy shapes to the clipboard", Wx::ITEM_NORMAL)
121
+ @edit_menu.append(Wx::ID_CUT, "Cu&t\tCtrl+X", "Cut shapes to the clipboard", Wx::ITEM_NORMAL)
122
+ @edit_menu.append(Wx::ID_PASTE, "&Paste\tCtrl+V", "Paste shapes to the canvas", Wx::ITEM_NORMAL)
123
+
124
+ Wx::SF::AutoLayout.layout_algorithms.each_with_index do |la_name, i|
125
+ @auto_layout_menu.append(ID::M_AUTOLAYOUT_FIRST + i, la_name)
126
+ end
127
+
128
+ @help_menu.append(Wx::ID_ABOUT, '&About...', 'About application...', Wx::ITEM_NORMAL)
129
+
130
+ # set shape canvas and associate it with diagram
131
+ @diagram = Wx::SF::Diagram.new
132
+ @shape_canvas = FrameCanvas.new(@diagram, @canvas_panel, Wx::ID_ANY)
133
+ @canvas_sizer.add(@shape_canvas, 1, Wx::EXPAND, 0)
134
+ @canvas_panel.layout
135
+ # enable using Wx::GraphicsContext by default
136
+ # (effective only if wxUSE_GRAPHICS_CONTEXT if set to 1 for wxRuby)
137
+ Wx::SF::ShapeCanvas::enable_gc
138
+
139
+ # create and show canvas thumbnail
140
+ @thumb_frm = ThumbFrame.new(self)
141
+ @thumb_frm.thumbnail.set_canvas(@shape_canvas)
142
+ @thumb_frm.show
143
+
144
+ # create colour picker
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])
154
+ @tool_bar.add_tool(Wx::ID_NEW, 'New', Wx::ArtProvider.get_bitmap(Wx::ART_NEW, Wx::ART_MENU), 'New diagram')
155
+ @tool_bar.add_tool(Wx::ID_OPEN, 'Load', Wx::ArtProvider.get_bitmap(Wx::ART_FILE_OPEN, Wx::ART_MENU), 'Open file...')
156
+ @tool_bar.add_tool(Wx::ID_SAVE, 'Save', Wx::ArtProvider.get_bitmap(Wx::ART_FILE_SAVE, Wx::ART_MENU), 'Save file...')
157
+ @tool_bar.add_separator
158
+ @tool_bar.add_tool(Wx::ID_PRINT, 'Print', Wx::ArtProvider.get_bitmap(Wx::ART_PRINT, Wx::ART_MENU), 'Print...')
159
+ @tool_bar.add_tool(Wx::ID_PREVIEW, 'Preview', Wx::ArtProvider.get_bitmap(Wx::ART_FIND, Wx::ART_MENU), 'Print preview...')
160
+ @tool_bar.add_separator
161
+ @tool_bar.add_tool(Wx::ID_COPY, 'Copy', Wx::ArtProvider.get_bitmap(Wx::ART_COPY, Wx::ART_MENU), 'Copy to clipboard')
162
+ @tool_bar.add_tool(Wx::ID_CUT, 'Cut', Wx::ArtProvider.get_bitmap(Wx::ART_CUT, Wx::ART_MENU), 'Cut to clipboard')
163
+ @tool_bar.add_tool(Wx::ID_PASTE, 'Paste', Wx::ArtProvider.get_bitmap(Wx::ART_PASTE, Wx::ART_MENU), 'Paste from clipboard')
164
+ @tool_bar.add_separator
165
+ @tool_bar.add_tool(Wx::ID_UNDO, 'Undo', Wx::ArtProvider.get_bitmap(Wx::ART_UNDO, Wx::ART_MENU), 'Undo')
166
+ @tool_bar.add_tool(Wx::ID_REDO, 'Redo', Wx::ArtProvider.get_bitmap(Wx::ART_REDO, Wx::ART_MENU), 'Redo')
167
+ @tool_bar.add_separator
168
+ @tool_bar.add_check_tool(ID::T_GRID, 'Grid', Wx::Bitmap(:Grid), Wx::NULL_BITMAP, 'Show/hide grid')
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)')
171
+ @tool_bar.add_separator
172
+ @tool_bar.add_radio_tool(ID::T_TOOL, 'Tool', Wx::Bitmap(:Tool), Wx::NULL_BITMAP, 'Design tool')
173
+ @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, 'Fixed rectangle', Wx::Bitmap(:FixedRect), Wx::NULL_BITMAP, 'Fixed rectangle')
175
+ @tool_bar.add_radio_tool(ID::T_RNDRECTSHP, 'RoundRect', Wx::Bitmap(:RoundRect), Wx::NULL_BITMAP, 'Rounded rectangle')
176
+ @tool_bar.add_radio_tool(ID::T_ELLIPSESHP, 'Ellipse', Wx::Bitmap(:Ellipse), Wx::NULL_BITMAP, 'Ellipse')
177
+ @tool_bar.add_radio_tool(ID::T_CIRCLESHP, 'Circle', Wx::Bitmap(:Circle), Wx::NULL_BITMAP, 'Circle')
178
+ @tool_bar.add_radio_tool(ID::T_DIAMONDSHP, 'Diamond', Wx::Bitmap(:Diamond), Wx::NULL_BITMAP, 'Diamond')
179
+ @tool_bar.add_radio_tool(ID::T_TEXTSHP, 'Text', Wx::Bitmap(:Text), Wx::NULL_BITMAP, 'Text')
180
+ @tool_bar.add_radio_tool(ID::T_EDITTEXTSHP, 'Editable text', Wx::Bitmap(:EditText), Wx::NULL_BITMAP, 'Editable text')
181
+ @tool_bar.add_radio_tool(ID::T_BITMAPSHP, 'Bitmap', Wx::Bitmap(:Bitmap), Wx::NULL_BITMAP, 'Bitmap')
182
+ @tool_bar.add_radio_tool(ID::T_GRIDSHP, 'Grid shape', Wx::Bitmap(:Grid), Wx::NULL_BITMAP, 'Grid shape')
183
+ @tool_bar.add_radio_tool(ID::T_FLEXGRIDSHP, 'Flexible grid shape', Wx::Bitmap(:FlexGrid), Wx::NULL_BITMAP, 'Flexible grid shape')
184
+ @tool_bar.add_radio_tool(ID::T_LINESHP, 'Line', Wx::Bitmap(:Line), Wx::NULL_BITMAP, 'Polyline connection')
185
+ @tool_bar.add_radio_tool(ID::T_CURVESHP, 'Curve', Wx::Bitmap(:Curve), Wx::NULL_BITMAP, 'Curve connection')
186
+ @tool_bar.add_radio_tool(ID::T_ORTHOSHP, 'Ortho line', Wx::Bitmap(:OrthoLine), Wx::NULL_BITMAP, 'Orthogonal connection')
187
+ @tool_bar.add_radio_tool(ID::T_RNDORTHOSHP, 'Rounded ortho line', Wx::Bitmap(:RoundOrthoLine), Wx::NULL_BITMAP, 'Rounded orthogonal connection')
188
+ @tool_bar.add_radio_tool(ID::T_STANDALONELINESHP, 'Stand alone line', Wx::Bitmap(:StandAloneLine), Wx::NULL_BITMAP, 'Stand alone line')
189
+ @tool_bar.add_separator
190
+ @tool_bar.add_tool(ID::T_ALIGN_LEFT, 'Align left', Wx::Bitmap(:AlignLeft), 'Align selected shapes to the left')
191
+ @tool_bar.add_tool(ID::T_ALIGN_RIGHT, 'Align right', Wx::Bitmap(:AlignRight), 'Align selected shapes to the right')
192
+ @tool_bar.add_tool(ID::T_ALIGN_TOP, 'Align top', Wx::Bitmap(:AlignTop), 'Align selected shapes to the top')
193
+ @tool_bar.add_tool(ID::T_ALIGN_BOTTOM, 'Align bottom', Wx::Bitmap(:AlignBottom), 'Align selected shapes to the bottom')
194
+ @tool_bar.add_tool(ID::T_ALIGN_MIDDLE, 'Align middle', Wx::Bitmap(:AlignMiddle), 'Align selected shapes to the middle')
195
+ @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
+ @tool_bar.realize
199
+
200
+ @status_bar.set_status_text('Ready')
201
+
202
+ # initialize data members
203
+ @tool_mode = MODE::DESIGN
204
+ @show_grid = true
205
+ @show_shadows = false
206
+
207
+ centre
208
+
209
+ # setup event handlers
210
+ evt_close(:on_close)
211
+ evt_menu(Wx::ID_EXIT, :on_exit)
212
+ evt_menu(Wx::ID_NEW, :on_new)
213
+ evt_menu(Wx::ID_OPEN, :on_load)
214
+ evt_menu(Wx::ID_SAVE, :on_save)
215
+ evt_menu(Wx::ID_UNDO, :on_undo)
216
+ evt_menu(Wx::ID_REDO, :on_redo)
217
+ evt_menu(Wx::ID_COPY, :on_copy)
218
+ evt_menu(Wx::ID_CUT, :on_cut)
219
+ evt_menu(Wx::ID_PASTE, :on_paste)
220
+ evt_menu(Wx::ID_ABOUT, :on_about)
221
+ evt_menu(Wx::ID_SELECTALL, :on_select_all)
222
+ evt_menu(ID::M_SAVEASBITMAP, :on_export_to_bmp)
223
+ evt_menu(Wx::ID_PRINT, :on_print)
224
+ evt_menu(Wx::ID_PREVIEW, :on_print_preview)
225
+ evt_menu(Wx::ID_PAGE_SETUP, :on_page_setup)
226
+ evt_menu_range(ID::M_AUTOLAYOUT_FIRST, ID::M_AUTOLAYOUT_LAST, :on_auto_layout)
227
+ evt_command_scroll(Wx::ID_ZOOM_FIT, :on_slider)
228
+ evt_tool_range(ID::T_FIRST_TOOLMARKER, ID::T_LAST_TOOLMARKER, :on_tool)
229
+ evt_colourpicker_changed(ID::T_COLORPICKER, :on_hover_color)
230
+ evt_update_ui(Wx::ID_COPY, :on_update_copy)
231
+ evt_update_ui(Wx::ID_CUT, :on_update_cut)
232
+ evt_update_ui(Wx::ID_PASTE, :on_update_paste)
233
+ evt_update_ui(Wx::ID_UNDO, :on_update_undo)
234
+ evt_update_ui(Wx::ID_REDO, :on_update_redo)
235
+ evt_update_ui_range(ID::T_FIRST_TOOLMARKER, ID::T_LAST_TOOLMARKER, :on_update_tool)
236
+ evt_update_ui_range(ID::M_AUTOLAYOUT_FIRST, ID::M_AUTOLAYOUT_LAST, :on_update_auto_layout)
237
+ evt_idle(:on_idle)
238
+ end
239
+
240
+ attr_accessor :tool_mode, :show_grid, :show_shadows
241
+
242
+ attr_reader :zoom_slider
243
+
244
+ def setup_frame
245
+ if Wx::PLATFORM == 'WXMSW'
246
+ set_size_hints([1024,700])
247
+ else
248
+ set_size_hints([1100,700])
249
+ end
250
+
251
+ @menu_bar = Wx::MenuBar.new(0)
252
+ @file_menu = Wx::Menu.new
253
+ @menu_bar.append(@file_menu, "&File")
254
+
255
+ @edit_menu = Wx::Menu.new
256
+ @menu_bar.append(@edit_menu, "&Edit")
257
+
258
+ @auto_layout_menu = Wx::Menu.new
259
+ @menu_bar.append(@auto_layout_menu, "&AutoLayout")
260
+
261
+ @help_menu = Wx::Menu.new
262
+ @menu_bar.append(@help_menu, "&Help")
263
+
264
+ set_menu_bar(@menu_bar)
265
+
266
+ @tool_bar = create_tool_bar(Wx::TB_HORIZONTAL, Wx::ID_ANY)
267
+ @tool_bar.realize
268
+
269
+ @status_bar = create_status_bar(1, Wx::STB_SIZEGRIP, Wx::ID_ANY)
270
+ main_sizer = Wx::FlexGridSizer.new(2, 1, 0, 0)
271
+ main_sizer.add_growable_col(0)
272
+ main_sizer.add_growable_row(0)
273
+ main_sizer.set_flexible_direction(Wx::BOTH)
274
+ main_sizer.set_non_flexible_grow_mode(Wx::FLEX_GROWMODE_SPECIFIED)
275
+
276
+ @canvas_panel = Wx::Panel.new(self, Wx::ID_ANY, style: Wx::TAB_TRAVERSAL)
277
+ @canvas_panel.set_extra_style(Wx::WS_EX_BLOCK_EVENTS)
278
+
279
+ @canvas_sizer = Wx::VBoxSizer.new
280
+
281
+ @canvas_panel.set_sizer(@canvas_sizer)
282
+ @canvas_panel.layout
283
+ @canvas_sizer.fit(@canvas_panel)
284
+ main_sizer.add(@canvas_panel, 1, Wx::EXPAND, 5)
285
+
286
+ @zoom_slider = Wx::Slider.new(self, Wx::ID_ZOOM_FIT, 50, 2, 99, Wx::DEFAULT_POSITION, Wx::DEFAULT_SIZE, Wx::SL_HORIZONTAL)
287
+ @zoom_slider.set_background_colour(Wx::SystemSettings.get_colour(Wx::SYS_COLOUR_BTNFACE))
288
+ @zoom_slider.set_tool_tip("Set canvas scale")
289
+
290
+ main_sizer.add(@zoom_slider, 0, Wx::EXPAND, 5)
291
+
292
+ set_sizer(main_sizer)
293
+ layout
294
+
295
+ centre(Wx::BOTH)
296
+ end
297
+ private :setup_frame
298
+
299
+ protected
300
+
301
+ def clean_up
302
+ @diagram.set_shape_canvas(nil)
303
+ @diagram.clear
304
+
305
+ @thumb_frm.hide
306
+ @thumb_frm.thumbnail.set_canvas(nil)
307
+
308
+ destroy
309
+ end
310
+
311
+ # common events
312
+ def on_close(_event)
313
+ clean_up
314
+ end
315
+
316
+ def on_idle(_event)
317
+ if @diagram.is_modified
318
+ set_title('wxRuby ShapeFramework Demo (diagram is modified)')
319
+ else
320
+ set_title('wxRuby ShapeFramework Demo')
321
+ end
322
+ end
323
+
324
+ # menu event handlers
325
+ def on_exit(_event)
326
+ clean_up
327
+ end
328
+
329
+ def on_new(_event)
330
+ if Wx.message_box('Current chart will be lost. Do you want to proceed?',
331
+ 'wxRuby ShapeFramework', Wx::YES_NO | Wx::ICON_QUESTION) == Wx::YES
332
+ @diagram.clear
333
+
334
+ @shape_canvas.clear_canvas_history
335
+ @shape_canvas.save_canvas_state
336
+
337
+ @shape_canvas.refresh
338
+ end
339
+ end
340
+
341
+ def on_save(_event)
342
+ Wx::FileDialog(self, 'Save canvas to file...', Dir.getwd, '', 'JSON Files (*.json)|*.json', Wx::FD_SAVE | Wx::FD_OVERWRITE_PROMPT) do |dlg|
343
+ if dlg.show_modal == Wx::ID_OK
344
+ @shape_canvas.save_canvas(dlg.get_path)
345
+
346
+ Wx.message_box("The chart has been saved to '#{dlg.get_path}'.", 'wxRuby ShapeFramework')
347
+ end
348
+ end
349
+ end
350
+
351
+ def on_load(_event)
352
+ Wx::FileDialog(self, 'Load canvas from file...', Dir.getwd, '', 'JSON Files (*.json)|*.json', Wx::FD_OPEN | Wx::FD_FILE_MUST_EXIST) do |dlg|
353
+ if dlg.show_modal == Wx::ID_OK
354
+ @shape_canvas.load_canvas(dlg.get_path)
355
+ @diagram = @shape_canvas.get_diagram
356
+
357
+ @zoom_slider.set_value((@shape_canvas.get_scale*50).to_i)
358
+
359
+ @cpicker.set_colour(@shape_canvas.get_hover_colour)
360
+ end
361
+ end
362
+ end
363
+
364
+ def on_undo(_event)
365
+ @shape_canvas.undo
366
+ end
367
+
368
+ def on_redo(_event)
369
+ @shape_canvas.redo
370
+ end
371
+
372
+ def on_copy(_event)
373
+ @shape_canvas.copy
374
+ end
375
+
376
+ def on_cut(_event)
377
+ @shape_canvas.cut
378
+ end
379
+
380
+ def on_paste(_event)
381
+ @shape_canvas.paste
382
+ end
383
+
384
+ def on_about(_event)
385
+ Wx.message_box("wxRuby SF Demonstration Application\n" +
386
+ "wxRuby ShapeFramework version number: #{Wx::SF::VERSION}\n" +
387
+ "Martin Corino (c) 2023\n" +
388
+ "(original Michal Bliznak (c) 2007 - 2013)",
389
+ 'wxRuby ShapeFramework')
390
+ end
391
+
392
+ def on_select_all(_event)
393
+ @shape_canvas.select_all
394
+ end
395
+
396
+ def on_export_to_bmp(_event)
397
+ Wx::FileDialog(self, 'Export canvas to image...', Dir.getwd, '',
398
+ 'BMP Files (*.bmp)|*.bmp|GIF Files (*.gif)|(*.gif)|XPM Files (*.xpm)|*.xpm|PNG Files (*.png)|*.png|JPEG Files (*.jpg;*.jpeg)|*.jpg;*.jpeg', Wx::FD_SAVE) do |dlg|
399
+ if dlg.show_modal == Wx::ID_OK
400
+ type = Wx::BitmapType::BITMAP_TYPE_ANY
401
+
402
+ case dlg.get_filter_index
403
+ when 0
404
+ type = Wx::BitmapType::BITMAP_TYPE_BMP
405
+ when 1
406
+ type = Wx::BitmapType::BITMAP_TYPE_GIF
407
+ when 2
408
+ type = Wx::BitmapType::BITMAP_TYPE_XPM
409
+ when 3
410
+ type = Wx::BitmapType::BITMAP_TYPE_PNG
411
+ when 4
412
+ type = Wx::BitmapType::BITMAP_TYPE_JPEG
413
+ end
414
+
415
+ if @shape_canvas.save_canvas_to_image(dlg.get_path, type: type, background: Wx::SF::WITH_BACKGROUND)
416
+ Wx.message_box("The image has been saved to '#{dlg.get_path}'.", 'wxRuby SF Demonstration Application')
417
+ else
418
+ Wx.message_box("Unable to save image to '#{dlg.get_path}'.", 'wxRuby SF Demonstration Application', Wx::OK | Wx::ICON_ERROR)
419
+ end
420
+ end
421
+ end
422
+ end
423
+
424
+ def on_print(_event)
425
+ @shape_canvas.print
426
+ end
427
+
428
+ def on_print_preview(_event)
429
+ @shape_canvas.print_preview
430
+ end
431
+
432
+ def on_page_setup(_event)
433
+ @shape_canvas.page_setup
434
+ end
435
+
436
+ def on_auto_layout(event)
437
+ Wx::SF::AutoLayout.layout(@shape_canvas, @auto_layout_menu.get_label(event.get_id))
438
+ @shape_canvas.save_canvas_state
439
+ end
440
+
441
+ # toolbar event handlers
442
+ def on_slider(_event)
443
+ @shape_canvas.set_scale(@zoom_slider.get_value.to_f/50)
444
+ @shape_canvas.refresh(false)
445
+ end
446
+
447
+ def on_tool(event)
448
+ @shape_canvas.abort_interactive_connection if @shape_canvas.get_mode == Wx::SF::ShapeCanvas::MODE::CREATECONNECTION
449
+
450
+ case event.get_id
451
+ when ID::T_GRID
452
+ @show_grid = !@show_grid
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)
469
+
470
+ when ID::T_GC
471
+ if Wx.has_feature?(:USE_GRAPHICS_CONTEXT)
472
+ Wx::SF::ShapeCanvas.enable_gc(!Wx::SF::ShapeCanvas.gc_enabled?)
473
+ # update all shapes in the manager
474
+ @diagram.update_all
475
+ # refresh shape canvas
476
+ @shape_canvas.refresh(false)
477
+ else
478
+ Wx.message_box('Could not enable enhanced graphics context due to wxUSE_GRAPHICS_CONTEXT=0', 'wxRuby ShapeFramework', Wx::OK | Wx::ICON_WARNING)
479
+ end
480
+
481
+ when ID::T_BITMAPSHP
482
+ @tool_mode = MODE::BITMAP
483
+
484
+ when ID::T_CIRCLESHP
485
+ @tool_mode = MODE::CIRCLE
486
+
487
+ when ID::T_CURVESHP
488
+ @tool_mode = MODE::CURVE
489
+
490
+ when ID::T_ORTHOSHP
491
+ @tool_mode = MODE::ORTHOLINE
492
+
493
+ when ID::T_RNDORTHOSHP
494
+ @tool_mode = MODE::ROUNDORTHOLINE
495
+
496
+ when ID::T_DIAMONDSHP
497
+ @tool_mode = MODE::DIAMOND
498
+
499
+ when ID::T_EDITTEXTSHP
500
+ @tool_mode = MODE::EDITTEXT
501
+
502
+ when ID::T_ELLIPSESHP
503
+ @tool_mode = MODE::ELLIPSE
504
+
505
+ when ID::T_GRIDSHP
506
+ @tool_mode = MODE::GRID
507
+
508
+ when ID::T_FLEXGRIDSHP
509
+ @tool_mode = MODE::FLEXGRID
510
+
511
+ when ID::T_LINESHP
512
+ @tool_mode = MODE::LINE
513
+
514
+ when ID::T_STANDALONELINESHP
515
+ @tool_mode = MODE::STANDALONELINE
516
+
517
+ when ID::T_RECTSHP
518
+ @tool_mode = MODE::RECT
519
+
520
+ when ID::T_RNDRECTSHP
521
+ @tool_mode = MODE::ROUNDRECT
522
+
523
+ when ID::T_SQUARESHP
524
+ @tool_mode = MODE::FIXEDRECT
525
+
526
+ when ID::T_TEXTSHP
527
+ @tool_mode = MODE::TEXT
528
+
529
+ when ID::T_TOOL
530
+ @tool_mode = MODE::DESIGN
531
+
532
+ when ID::T_ALIGN_LEFT
533
+ @shape_canvas.align_selected(Wx::SF::ShapeCanvas::HALIGN::LEFT, Wx::SF::ShapeCanvas::VALIGN::NONE)
534
+
535
+ when ID::T_ALIGN_RIGHT
536
+ @shape_canvas.align_selected(Wx::SF::ShapeCanvas::HALIGN::RIGHT, Wx::SF::ShapeCanvas::VALIGN::NONE)
537
+
538
+ when ID::T_ALIGN_CENTER
539
+ @shape_canvas.align_selected(Wx::SF::ShapeCanvas::HALIGN::CENTER, Wx::SF::ShapeCanvas::VALIGN::NONE)
540
+
541
+ when ID::T_ALIGN_TOP
542
+ @shape_canvas.align_selected(Wx::SF::ShapeCanvas::HALIGN::NONE, Wx::SF::ShapeCanvas::VALIGN::TOP)
543
+
544
+ when ID::T_ALIGN_BOTTOM
545
+ @shape_canvas.align_selected(Wx::SF::ShapeCanvas::HALIGN::NONE, Wx::SF::ShapeCanvas::VALIGN::BOTTOM)
546
+
547
+ when ID::T_ALIGN_MIDDLE
548
+ @shape_canvas.align_selected(Wx::SF::ShapeCanvas::HALIGN::NONE, Wx::SF::ShapeCanvas::VALIGN::MIDDLE)
549
+
550
+ else
551
+ event.skip
552
+ end
553
+ end
554
+
555
+ def on_hover_color(event)
556
+ @shape_canvas.set_hover_colour(event.get_colour)
557
+ end
558
+
559
+ def on_update_copy(event)
560
+ event.enable(@shape_canvas.can_copy?) if @shape_canvas
561
+ end
562
+
563
+ def on_update_cut(event)
564
+ event.enable(@shape_canvas.can_cut?) if @shape_canvas
565
+ end
566
+
567
+ def on_update_paste(event)
568
+ event.enable(@shape_canvas.can_paste?) if @shape_canvas
569
+ end
570
+
571
+ def on_update_undo(event)
572
+ event.enable(@shape_canvas.can_undo?) if @shape_canvas
573
+ end
574
+
575
+ def on_update_redo(event)
576
+ event.enable(@shape_canvas.can_redo?) if @shape_canvas
577
+ end
578
+
579
+ def on_update_tool(event)
580
+ case event.get_id
581
+ when ID::T_GRID
582
+ event.check(@show_grid)
583
+
584
+ when ID::T_GC
585
+ event.check(Wx::SF::ShapeCanvas.gc_enabled?)
586
+
587
+ when ID::T_BITMAPSHP
588
+ event.check(@tool_mode == MODE::BITMAP)
589
+
590
+ when ID::T_CIRCLESHP
591
+ event.check(@tool_mode == MODE::CIRCLE)
592
+
593
+ when ID::T_CURVESHP
594
+ event.check(@tool_mode == MODE::CURVE)
595
+
596
+ when ID::T_ORTHOSHP
597
+ event.check(@tool_mode == MODE::ORTHOLINE)
598
+
599
+ when ID::T_RNDORTHOSHP
600
+ event.check(@tool_mode == MODE::ROUNDORTHOLINE)
601
+
602
+ when ID::T_DIAMONDSHP
603
+ event.check(@tool_mode == MODE::DIAMOND)
604
+
605
+ when ID::T_EDITTEXTSHP
606
+ event.check(@tool_mode == MODE::EDITTEXT)
607
+
608
+ when ID::T_ELLIPSESHP
609
+ event.check(@tool_mode == MODE::ELLIPSE)
610
+
611
+ when ID::T_GRIDSHP
612
+ event.check(@tool_mode == MODE::GRID)
613
+
614
+ when ID::T_FLEXGRIDSHP
615
+ event.check(@tool_mode == MODE::FLEXGRID)
616
+
617
+ when ID::T_LINESHP
618
+ event.check(@tool_mode == MODE::LINE)
619
+
620
+ when ID::T_STANDALONELINESHP
621
+ event.check(@tool_mode == MODE::STANDALONELINE)
622
+
623
+ when ID::T_RECTSHP
624
+ event.check(@tool_mode == MODE::RECT)
625
+
626
+ when ID::T_RNDRECTSHP
627
+ event.check(@tool_mode == MODE::ROUNDRECT)
628
+
629
+ when ID::T_SQUARESHP
630
+ event.check(@tool_mode == MODE::FIXEDRECT)
631
+
632
+ when ID::T_TEXTSHP
633
+ event.check(@tool_mode == MODE::TEXT)
634
+
635
+ when ID::T_TOOL
636
+ event.check(@tool_mode == MODE::DESIGN)
637
+
638
+ when ID::T_ALIGN_RIGHT,
639
+ ID::T_ALIGN_LEFT,
640
+ ID::T_ALIGN_TOP,
641
+ ID::T_ALIGN_BOTTOM,
642
+ ID::T_ALIGN_MIDDLE,
643
+ ID::T_ALIGN_CENTER
644
+ event.enable(@shape_canvas.can_align_selected) if @shape_canvas
645
+
646
+ else
647
+ event.skip
648
+ end
649
+ end
650
+
651
+ def on_update_auto_layout(event)
652
+ event.enable(!@diagram.empty?)
653
+ end
654
+ end
655
+
656
+ Wx::App.run do
657
+ MainFrame.new(nil).show
658
+ end