Class: Wx::SF::GridShape
- Includes:
- ManagerShape
- Defined in:
- lib/wx/shapes/shapes/grid_shape.rb
Overview
Class encapsulates a rectangular shape derived from Wx::SF::RectShape class which acts as a grid-based container able to manage other assigned child shapes (it can control their position). The managed shapes are aligned into defined grid with a behaviour similar to classic Wx::GridSizer class.
Direct Known Subclasses
Defined Under Namespace
Modules: DEFAULT
Instance Attribute Summary collapse
-
#max_rows ⇒ Object
readonly
Returns the value of attribute max_rows.
Class Method Summary collapse
-
.get_min_size ⇒ Wx::Size
(also: min_size)
Returns the minimum size for empty grids.
-
.set_min_size(arg1, arg2 = nil) ⇒ Object
(also: min_size=)
Sets the minimum size for empty grids.
Instance Method Summary collapse
-
#append_to_grid(shape) ⇒ Object
Append given shape to the grid at the last managed position.
-
#clear_cell(row, col) ⇒ Boolean
Clear the cell at given row and column index Note that this function doesn’t remove managed (child) shapes from the parent grid shape (they are still its child shapes but aren’t managed anymore).
-
#clear_grid ⇒ Object
Clear information about managed shapes and set number of rows to 1 (number of columns does not change).
-
#do_children_layout ⇒ Object
protected
Do layout of assigned child shapes.
-
#each_cell(&block) ⇒ Object
Iterate all cells.
- #find_cell(child_rect) ⇒ Object protected
-
#fit_to_children ⇒ Object
Resize the shape to bound all child shapes.
-
#get_cell_count ⇒ Integer
(also: #cell_count)
Get number of available grid cells.
-
#get_cell_space ⇒ Integer
(also: #cell_space)
Get space between grid cells (managed shapes).
-
#get_dimensions ⇒ Array(Integer,Integer)
Get grid dimensions.
-
#get_managed_shape(*args) ⇒ Object
Get managed shape specified by lexicographic cell index.
-
#get_max_child_size ⇒ Wx::Size
protected
returns maximum size of all managed (child) shapes.
-
#initialize(pos = Shape::DEFAULT::POSITION, size = RectShape::DEFAULT::SIZE, cols: DEFAULT::COLUMNS, max_rows: 0, cell_space: DEFAULT::CELLSPACE, diagram: nil) ⇒ GridShape
constructor
Constructor.
-
#insert_to_grid(*args) ⇒ Object
Insert given shape to the grid at the given position.
-
#on_child_dropped(_pos, child) ⇒ Object
Event handler called when any shape is dropped above this shape (and the dropped shape is accepted as a child of this shape).
-
#on_import ⇒ Object
protected
called after the shape has been newly imported/pasted/dropped checks the cells for stale links.
- #position_child_cell(child) ⇒ Object protected
-
#remove_from_grid(shape) ⇒ Shape?
Remove given shape from the grid.
-
#set_cell_space(cellspace) ⇒ Object
(also: #cell_space=)
Set space between grid cells (managed shapes).
-
#set_dimensions(rows, cols) ⇒ Object
Set grid dimensions.
-
#set_max_rows(num) ⇒ Integer
(also: #max_rows=)
Sets the maximum number of rows for the grid (by default there this value is 0 == no maximum).
-
#update(recurse = true) ⇒ Object
Update shape (align all child shapes and resize it to fit them).
-
#update_rows ⇒ Object
protected
update row count.
Methods included from ManagerShape
#do_alignment, #fit_shape_to_rect, #is_manager
Methods inherited from RectShape
#create_handles, #do_begin_handle, #do_on_handle, #draw_highlighted, #draw_hover, #draw_normal, #draw_shadow, #get_border, #get_border_point, #get_bounding_box, #get_fill, #get_rect_size, #on_begin_handle, #on_bottom_handle, #on_handle, #on_left_handle, #on_right_handle, #on_top_handle, #scale, #scale_rectangle, #set_border, #set_fill, #set_rect_size
Methods inherited from Shape
#accept_child, #accept_connection, #accept_currently_dragged_shapes, #accept_src_neighbour, #accept_trg_neighbour, #activate, #active?, #add_child_shape, #add_connection_point, #add_handle, #add_style, #ancestor?, #clear_accepted_childs, #clear_accepted_connections, #clear_accepted_src_neighbours, #clear_accepted_trg_neighbours, component, component_shapes, #contains?, #contains_style, #create_handles, #descendant?, #do_alignment, #does_not_accept_children?, #draw, #draw_highlighted, #draw_hover, #draw_normal, #draw_selected, #draw_shadow, #get_absolute_position, #get_accepted_children, #get_accepted_connections, #get_accepted_src_neighbours, #get_accepted_trg_neighbours, #get_assigned_connections, #get_border_point, #get_bounding_box, #get_center, #get_child_shapes, #get_children, #get_children_recursively, #get_complete_bounding_box, #get_connection_point, #get_connection_points, #get_custom_dock_point, #get_diagram, #get_grand_parent_shape, #get_h_align, #get_h_border, #get_handle, #get_handles, #get_hover_colour, #get_nearest_connection_point, #get_neighbours, #get_parent_absolute_position, #get_parent_canvas, #get_parent_shape, #get_relative_position, #get_shape_canvas, #get_style, #get_user_data, #get_v_align, #get_v_border, #has_children, #has_selected_parent?, #include_child_shape?, #inside?, #inspect, #intersects?, #is_child_accepted, #is_connection_accepted, #is_managed, #is_manager, #is_src_neighbour_accepted, #is_trg_neighbour_accepted, lines_intersection, #lines_intersection, #move_by, #move_to, #on_begin_drag, #on_begin_handle, #on_dragging, #on_end_drag, #on_end_handle, #on_handle, #on_key, #on_left_click, #on_left_double_click, #on_mouse_enter, #on_mouse_leave, #on_mouse_over, #on_right_click, #on_right_double_click, #refresh, #refresh_rect, #remove_connection_point, #remove_handle, #remove_style, #scale, #scale_children, #select, #selected?, #set_custom_dock_point, #set_diagram, #set_h_align, #set_h_border, #set_hover_colour, #set_parent_shape, #set_relative_position, #set_style, #set_user_data, #set_v_align, #set_v_border, #show, #show_handles, #to_s, #visible?
Constructor Details
#initialize(pos = Shape::DEFAULT::POSITION, size = RectShape::DEFAULT::SIZE, cols: DEFAULT::COLUMNS, max_rows: 0, cell_space: DEFAULT::CELLSPACE, diagram: nil) ⇒ GridShape
Constructor.
60 61 62 63 64 65 66 67 68 69 |
# File 'lib/wx/shapes/shapes/grid_shape.rb', line 60 def initialize(pos = Shape::DEFAULT::POSITION, size = RectShape::DEFAULT::SIZE, cols: DEFAULT::COLUMNS, max_rows: 0, cell_space: DEFAULT::CELLSPACE, diagram: nil) super(pos, size, diagram: diagram) @cols = [1, cols.to_i].max # at least one column @max_rows = [0, max_rows.to_i].max # no or >=1 max rows @cell_space = [0, cell_space.to_i].max @rows = 1 @cells = [] remove_style(Shape::STYLE::SIZE_CHANGE) end |
Instance Attribute Details
#max_rows ⇒ Object (readonly)
Returns the value of attribute max_rows.
71 72 73 |
# File 'lib/wx/shapes/shapes/grid_shape.rb', line 71 def max_rows @max_rows end |
Class Method Details
.get_min_size ⇒ Wx::Size Also known as: min_size
Returns the minimum size for empty grids
28 29 30 |
# File 'lib/wx/shapes/shapes/grid_shape.rb', line 28 def get_min_size @min_size ||= Wx::Size.new(20, 20) end |
.set_min_size(sz) ⇒ Object .set_min_size(w, h) ⇒ Object Also known as: min_size=
Sets the minimum size for empty grids
39 40 41 42 43 44 45 46 |
# File 'lib/wx/shapes/shapes/grid_shape.rb', line 39 def set_min_size(arg1, arg2 = nil) @min_size = if arg2.nil? raise ArgumentError, 'Expected Wx::Size' unless Wx::Size === arg1 arg1 else Wx::Size.new(arg1, arg2) end end |
Instance Method Details
#append_to_grid(shape) ⇒ Object
Append given shape to the grid at the last managed position.
188 189 190 191 192 193 |
# File 'lib/wx/shapes/shapes/grid_shape.rb', line 188 def append_to_grid(shape) row = @cells.size / @cols col = @cells.size - row*@cols insert_to_grid(row, col, shape) end |
#clear_cell(row, col) ⇒ Boolean
Clear the cell at given row and column index Note that this function doesn’t remove managed (child) shapes from the parent grid shape (they are still its child shapes but aren’t managed anymore).
155 156 157 158 159 160 161 162 |
# File 'lib/wx/shapes/shapes/grid_shape.rb', line 155 def clear_cell(row, col) if row>=0 && row<@rows && col>=0 && col<@cols @cells[row*@cols + col] = nil true else false end end |
#clear_grid ⇒ Object
Clear information about managed shapes and set number of rows to 1 (number of columns does not change).
Note that this function doesn’t remove managed (child) shapes from the parent grid shape (they are still its child shapes but aren’t managed anymore).
181 182 183 184 |
# File 'lib/wx/shapes/shapes/grid_shape.rb', line 181 def clear_grid @rows = 1 @cells = [] end |
#do_children_layout ⇒ Object (protected)
Do layout of assigned child shapes
366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 |
# File 'lib/wx/shapes/shapes/grid_shape.rb', line 366 def do_children_layout return if @cols == 0 || @rows == 0 max_size = get_max_child_size @cells.each_with_index do |shape, i| if shape col = (i % @cols) row = (i / @cols) fit_shape_to_rect(shape, Wx::Rect.new(col*max_size.width + (col+1)*@cell_space, row*max_size.height + (row+1)*@cell_space, max_size.width, max_size.height)) end end end |
#each_cell ⇒ Enumerator #each_cell {|row, col, shape| ... } ⇒ Object
Iterate all cells. If a block is given passes row, col and shape (if any) for each cell to block. Returns Enumerator if no block given.
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 |
# File 'lib/wx/shapes/shapes/grid_shape.rb', line 131 def each_cell(&block) if block @rows.times do |row| @cols.times do |col| block.call(row, col, @cells[row*@cols + col]) end end else ::Enumerator.new do |y| @rows.times do |row| @cols.times do |col| y << [row, col, @cells[row*@cols + col]] end end end end end |
#find_cell(child_rect) ⇒ Object (protected)
412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 |
# File 'lib/wx/shapes/shapes/grid_shape.rb', line 412 def find_cell(child_rect) max_size = get_max_child_size child_centre = child_rect.get_position child_centre.x += child_rect.width/2 child_centre.y += child_rect.height/2 # find the cell index where the new or dragged child is positioned above and in front of offset = get_bounding_box.top_left cell_count.times.find do |cell| col = (cell % @cols) row = (cell / @cols) cell_rct = Wx::Rect.new(col*max_size.width + (col+1)*@cell_space, row*max_size.height + (row+1)*@cell_space, max_size.width, max_size.height).offset!(offset) child_centre.x <= cell_rct.right && child_centre.y <= cell_rct.bottom end end |
#fit_to_children ⇒ Object
Resize the shape to bound all child shapes. The function can be overridden if necessary.
331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 |
# File 'lib/wx/shapes/shapes/grid_shape.rb', line 331 def fit_to_children # get bounding box of the shape and children set to be inside it abs_pos = get_absolute_position ch_bb = Wx::Rect.new(abs_pos.to_point, [0, 0]) @child_shapes.each do |child| ch_bb = child.get_complete_bounding_box(ch_bb, BBMODE::SELF | BBMODE::CHILDREN) if child.has_style?(STYLE::ALWAYS_INSIDE) end if @child_shapes.empty? # do not let the empty grid shape 'disappear' due to zero sizes... ch_bb.size = GridShape.min_size - @cell_space end @rect_size = Wx::RealPoint.new(ch_bb.width + @cell_space, ch_bb.height + @cell_space) end |
#get_cell_count ⇒ Integer Also known as: cell_count
Get number of available grid cells
103 104 105 |
# File 'lib/wx/shapes/shapes/grid_shape.rb', line 103 def get_cell_count @rows * @cols end |
#get_cell_space ⇒ Integer Also known as: cell_space
Get space between grid cells (managed shapes).
117 118 119 |
# File 'lib/wx/shapes/shapes/grid_shape.rb', line 117 def get_cell_space @cell_space end |
#get_dimensions ⇒ Array(Integer,Integer)
Get grid dimensions.
97 98 99 |
# File 'lib/wx/shapes/shapes/grid_shape.rb', line 97 def get_dimensions [@rows, @cols] end |
#get_managed_shape(index) ⇒ Shape? #get_managed_shape(row, col) ⇒ Shape?
Get managed shape specified by lexicographic cell index.
172 173 174 175 |
# File 'lib/wx/shapes/shapes/grid_shape.rb', line 172 def get_managed_shape(*args) index = args.size == 1 ? args.first : (args[0]*@cols)+args[1] @cells[index] end |
#get_max_child_size ⇒ Wx::Size (protected)
returns maximum size of all managed (child) shapes
402 403 404 405 406 407 408 409 410 |
# File 'lib/wx/shapes/shapes/grid_shape.rb', line 402 def get_max_child_size @child_shapes.inject(Wx::Size.new(0, 0)) do |max_size, shape| child_rect = shape.get_bounding_box max_size.set_width(child_rect.width) if shape.get_h_align != HALIGN::EXPAND && child_rect.width > max_size.width max_size.set_height(child_rect.height) if shape.get_v_align != VALIGN::EXPAND && child_rect.height > max_size.height max_size end end |
#insert_to_grid(row, col, shape) ⇒ Boolean #insert_to_grid(index, shape) ⇒ Boolean
Insert given shape to the grid at the given position. In case a shape is inserted in a cell already occupied the cells at that position and following will be shifted to the next lexicographic position. A maximum row setting may prevent a new shape of being inserted.
215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 |
# File 'lib/wx/shapes/shapes/grid_shape.rb', line 215 def insert_to_grid(*args) if args.size > 2 row, col, shape = args if shape && shape.is_a?(Shape) && is_child_accepted(shape.class) # protect duplicated occurrences return false if @cells.index(shape) # protect unbounded horizontal index (grid can grow in a vertical direction only) return false if col >= @cols # protect maximum rows index = row * @cols + col return false if @max_rows > 0 && (row >= @max_rows || # cannot insert beyond max_rows (@cells[index] && @cells.size >= (@max_rows * @cols))) # cannot grow beyond max_rows # add the shape to the children list if necessary unless @child_shapes.include?(shape) if @diagram @diagram.reparent_shape(shape, self) else shape.set_parent_shape(self) end end if @cells[index] @cells.insert(row * @cols + col, shape) else @cells[index] = shape end # adjust row count update_rows return true end else index, shape = args if shape && shape.is_a?(Shape) && is_child_accepted(shape.class) # protect duplicated occurrences return false if @cells.index(shape) # protect unbounded index max_size = @cols * @max_rows return false if index < 0 || (@max_rows > 0 && (index >= max_size || # cannot insert beyond max_rows (@cells[index] && @cells.size >= (@cols * @max_rows)))) # cannot grow beyond max_rows # add the shape to the children list if necessary unless @child_shapes.include?(shape) if @diagram @diagram.reparent_shape(shape, self) else shape.set_parent_shape(self) end end if @cells[index] @cells.insert(index, shape) else @cells[index] = shape end # adjust row count update_rows return true end end false end |
#on_child_dropped(_pos, child) ⇒ Object
Event handler called when any shape is dropped above this shape (and the dropped shape is accepted as a child of this shape). The function can be overridden if necessary.
The function is called by the framework (by the shape canvas).
354 355 356 357 358 359 360 361 |
# File 'lib/wx/shapes/shapes/grid_shape.rb', line 354 def on_child_dropped(_pos, child) # see if we can match the position of the new child with the position of another # (previously assigned) managed shape if child && !child.is_a?(LineShape) # insert child based on it's current (possibly dropped) position position_child_cell(child) end end |
#on_import ⇒ Object (protected)
called after the shape has been newly imported/pasted/dropped checks the cells for stale links
385 386 387 388 389 390 |
# File 'lib/wx/shapes/shapes/grid_shape.rb', line 385 def on_import # check for existence of non-included shapes @cells.delete_if do |shape| shape && !@child_shapes.include?(shape) end end |
#position_child_cell(child) ⇒ Object (protected)
429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 |
# File 'lib/wx/shapes/shapes/grid_shape.rb', line 429 def position_child_cell(child) crct = child.get_bounding_box # see if the child already had a cell in this grid (moving a child) child_index = @cells.index(child) # if the child intersects this box shape we look # for the cell it should go into (if any) if @cells.size>0 && intersects?(crct) # find the cell index where the new child is positioned above and in front of index = find_cell(crct) # now see where to put the new/moved child if index # found a matching cell? # if the child being inserted already had a slot if child_index # if the newly found index equals the existing index there is nothing to do return if child_index == index # else clear the child's current cell; this provides support for reordering child shapes by dragging @cells[child_index] = nil end # insert/move the child unless insert_to_grid(index, child) # if failed to insert (max rows exceeded?) restore the child to it's previous cell if child_index @cells[child_index] = child else # or make the child a toplevel shape # move relative to current parent (if any) child.move_by(child.get_parent_shape.get_absolute_position) if child.get_parent_shape diagram.reparent_shape(child, nil) end end return # done end end # otherwise append # clear the child's current cell if already part of grid @cells[child_index] = nil if child_index # append unless append_to_grid(child) # if failed to append (max rows exceeded?) restore the child to it's previous cell if child_index @cells[child_index] = child else # or make the child a toplevel shape # move relative to current parent (if any) child.move_by(child.get_parent_shape.get_absolute_position) if child.get_parent_shape diagram.reparent_shape(child, nil) end end end |
#remove_from_grid(shape) ⇒ Shape?
Note this does not remove the shape as a child shape.
Remove given shape from the grid. Shifts any occupied cells beyond the cell containing the given shape to the previous lexicographic position.
292 293 294 295 296 297 298 299 300 301 302 |
# File 'lib/wx/shapes/shapes/grid_shape.rb', line 292 def remove_from_grid(shape) if @cells.delete(shape) # remove trailing empty cells @cells.pop until @cells.last # update row count @rows = @cells.size / @cols @rows += 1 if (@cells.size % @cols) > 0 return shape end nil end |
#set_cell_space(cellspace) ⇒ Object Also known as: cell_space=
Set space between grid cells (managed shapes).
110 111 112 |
# File 'lib/wx/shapes/shapes/grid_shape.rb', line 110 def set_cell_space(cellspace) @cell_space = cellspace end |
#set_dimensions(rows, cols) ⇒ Object
Set grid dimensions.
86 87 88 89 90 91 92 93 |
# File 'lib/wx/shapes/shapes/grid_shape.rb', line 86 def set_dimensions(rows, cols) return if (new_size = rows * cols) == 0 @rows = rows @cols = cols @cells.slice!(0, new_size) if new_size < @cells.size end |
#set_max_rows(num) ⇒ Integer Also known as: max_rows=
Sets the maximum number of rows for the grid (by default there this value is 0 == no maximum). In case the number of already managed cells exceeds the new maximum no change is made.
76 77 78 79 80 |
# File 'lib/wx/shapes/shapes/grid_shape.rb', line 76 def set_max_rows(num) # only change as long as this does not invalidate already managed cells @max_rows = num unless (num * @cols) < @cells.size @max_rows end |
#update(recurse = true) ⇒ Object
Update shape (align all child shapes and resize it to fit them)
305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 |
# File 'lib/wx/shapes/shapes/grid_shape.rb', line 305 def update(recurse= true) # check for existence of de-assigned shapes @cells.delete_if do |shape| shape && !@child_shapes.include?(shape) end # check whether all child shapes are present in the cells array... @child_shapes.each do |child| unless @cells.include?(child) # see if we can match the position of the new child with the position of another # (previously assigned) managed shape position_child_cell(child) end end # do self-alignment do_alignment # fit the shape to its children fit_to_children unless has_style?(STYLE::NO_FIT_TO_CHILDREN) # do it recursively on all parent shapes get_parent_shape.update(recurse) if recurse && get_parent_shape end |
#update_rows ⇒ Object (protected)
update row count
393 394 395 396 397 398 |
# File 'lib/wx/shapes/shapes/grid_shape.rb', line 393 def update_rows # remove trailing empty cells (if any) @cells.pop until @cells.last @rows = @cells.size / @cols @rows += 1 if (@cells.size % @cols) > 0 end |