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
         
     |