Class: Wx::SF::ControlShape

Inherits:
RectShape show all
Defined in:
lib/wx/shapes/shapes/control_shape.rb

Overview

Class encapsulates a special shape able to manage assigned GUI controls (widgets). The GUI control’s position and size can by modified via parent control shape. User can also specify how events incoming from the managed GUI control are processed.

Note that the managed controls use a shape canvas as their parent window so these shapes cannot be used without existing and properly initialized shape canvas. Moreover, managed GUI controls are not serialized in any way internally so it is completely up to the user to provide this functionality if needed.

Defined Under Namespace

Modules: DEFAULT Classes: EVTPROCESSING, EventSink

Instance Method Summary collapse

Methods inherited from RectShape

#create_handles, #do_begin_handle, #do_on_handle, #draw_highlighted, #draw_hover, #draw_normal, #draw_shadow, #get_border_point, #get_bounding_box, #get_rect_size, #on_bottom_handle, #on_left_handle, #on_right_handle, #on_top_handle, #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, #on_child_dropped, #on_dragging, #on_import, #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_children, #select, #selected?, #set_custom_dock_point, #set_diagram, #set_h_align, #set_h_border, #set_hover_colour, #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, control: nil, diagram: nil) ⇒ ControlShape

Constructor.

Parameters:

  • pos (Wx::RealPoint) (defaults to: Shape::DEFAULT::POSITION)

    Initial position

  • size (Wx::RealPoint) (defaults to: RectShape::DEFAULT::SIZE)

    Initial size

  • control (Wx::Window) (defaults to: nil)

    managed GUI control

  • diagram (Wx::SF::Diagram) (defaults to: nil)

    parent diagram



142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
# File 'lib/wx/shapes/shapes/control_shape.rb', line 142

def initialize(pos = Shape::DEFAULT::POSITION, size = RectShape::DEFAULT::SIZE, control: nil, diagram: nil)
  super(pos, size, diagram: diagram)
  set_control(control)
  add_style(Shape::STYLE::PROCESS_DEL)
  @process_events = DEFAULT::PROCESSEVENTS
  @mod_fill = nil
  @mod_border = nil
  @control_offset = DEFAULT::CONTROLOFFSET

  @event_sink = EventSink.new(self)

  @prev_parent = nil
  @prev_style = 0
  @prev_fill = nil
  @prev_border = nil
end

Instance Method Details

#_on_canvas(change, *args) ⇒ Boolean? (protected)

Event handler called by ShapeCanvas to request,report canvas changes.

Parameters:

Returns:

  • (Boolean, nil)


481
482
483
484
485
486
487
488
489
490
491
# File 'lib/wx/shapes/shapes/control_shape.rb', line 481

def _on_canvas(change, *args)
  case change
  when ShapeCanvas::CHANGE::SET_SCALE
    msg = args.shift
    msg << 'rescaling control (GUI) shapes not supported'
    return false
  when ShapeCanvas::CHANGE::VIRTUAL_SIZE
    self.update
  end
  super
end

#fit_to_childrenObject

Resize the shape to bound all child shapes. The function can be overridden if necessary.



370
371
372
373
374
375
376
377
378
379
380
381
382
# File 'lib/wx/shapes/shapes/control_shape.rb', line 370

def fit_to_children
  bb_rct = get_bounding_box

  ctrl_rct = if @control
               Wx::Rect.new(@control.position, @control.size)
             else
               bb_rct
             end

  super

  update_shape if bb_rct.intersects(ctrl_rct) && !bb_rct.contains(ctrl_rct)
end

#get_borderWx::Pen Also known as: border

Get current border style.

Returns:



214
215
216
# File 'lib/wx/shapes/shapes/control_shape.rb', line 214

def get_border
  @border || (@diagram&.shape_canvas ? @diagram.shape_canvas.control_border : DEFAULT.ctrl_border)
end

#get_controlWx::Window

Get managed GUI control.

Returns:

  • (Wx::Window)

    the GUI control



221
222
223
# File 'lib/wx/shapes/shapes/control_shape.rb', line 221

def get_control
  @control
end

#get_control_offsetInteger

Get control shape’s offset (a gap between the shape’s border and managed GUI control).

Returns:

  • (Integer)

    Offset size



290
291
292
# File 'lib/wx/shapes/shapes/control_shape.rb', line 290

def get_control_offset
  @control_offset
end

#get_event_processingEVTPROCESSING

Get the way how GUI control’s events are processed.

Returns:

See Also:



235
236
237
# File 'lib/wx/shapes/shapes/control_shape.rb', line 235

def get_event_processing
  @process_events
end

#get_fillWx::Brush Also known as: fill

Get current fill style.

Returns:



207
208
209
# File 'lib/wx/shapes/shapes/control_shape.rb', line 207

def get_fill
  @fill || (@diagram&.shape_canvas ? @diagram.shape_canvas.control_fill : DEFAULT.ctrl_fill)
end

#get_mod_borderWx::Pen

Get control shape’s border style used during its modification.

Returns:



278
279
280
# File 'lib/wx/shapes/shapes/control_shape.rb', line 278

def get_mod_border
  @mod_border || (@diagram&.shape_canvas ? @diagram.shape_canvas.control_mod_border : DEFAULT.mod_border)
end

#get_mod_fillWx::Brush

Get control shape’s background style used during its modification.

Returns:



257
258
259
# File 'lib/wx/shapes/shapes/control_shape.rb', line 257

def get_mod_fill
  @mod_fill || (@diagram&.shape_canvas ? @diagram.shape_canvas.control_mod_fill : DEFAULT.mod_fill)
end

#move_by(x, y) ⇒ Object

Move the shape by the given offset. The function can be overridden if necessary.

Parameters:

  • x (Float)

    X offset

  • y (Float)

    Y offset



358
359
360
361
# File 'lib/wx/shapes/shapes/control_shape.rb', line 358

def move_by(x, y)
  super
  update_control
end

#move_to(x, y) ⇒ Object

Move the shape to the given absolute position. The function can be overridden if necessary.

Parameters:

  • x (Float)

    X coordinate

  • y (Float)

    Y coordinate



350
351
352
353
# File 'lib/wx/shapes/shapes/control_shape.rb', line 350

def move_to(x, y)
  super
  update_control
end

#on_begin_drag(pos) ⇒ Object

See Also:



390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
# File 'lib/wx/shapes/shapes/control_shape.rb', line 390

def on_begin_drag(pos)
  @prev_fill = @fill
  @fill = get_mod_fill
  canvas = get_parent_canvas
  if canvas
    @prev_style = canvas.get_style
    canvas.remove_style(ShapeCanvas::STYLE::DND)
  end
  if @control
    @control.hide
    @control.disconnect(Wx::ID_ANY, Wx::ID_ANY, Wx::EVT_SIZE)
  end

  super
end

#on_begin_handle(handle) ⇒ Object

Event handler called when the user started to drag the shape handle. The function can be overridden if necessary.

The function is called by the framework (by the shape canvas).

Parameters:



431
432
433
434
435
436
437
438
439
440
441
442
443
444
# File 'lib/wx/shapes/shapes/control_shape.rb', line 431

def on_begin_handle(handle)
  @prev_border = @border
  @border = get_mod_border
  @prev_fill = @fill
  @fill = get_mod_fill
  
  if @control
    @control.hide
    @control.disconnect(Wx::ID_ANY, Wx::ID_ANY, Wx::EVT_SIZE)
  end

  # call default handler
  super
end

#on_end_drag(pos) ⇒ Object

Event handler called at the end of the shape dragging process. The function can be overridden if necessary.

The function is called by the framework (by the shape canvas).

Parameters:

See Also:



412
413
414
415
416
417
418
419
420
421
422
423
424
# File 'lib/wx/shapes/shapes/control_shape.rb', line 412

def on_end_drag(pos)
  @fill = @prev_fill
  canvas = get_parent_canvas
  canvas.set_style(@prev_style) if canvas
  update_control
  if @control
    @control.evt_size { |evt| @event_sink._on_size(evt) }
    @control.show
    @control.set_focus
  end

  super
end

#on_end_handle(handle) ⇒ Object

Parameters:



461
462
463
464
465
466
467
468
469
470
471
472
473
# File 'lib/wx/shapes/shapes/control_shape.rb', line 461

def on_end_handle(handle)
  @border = @prev_border
  @fill = @prev_fill
  
  if @control
    @control.show
    @control.set_focus
    @control.evt_size { |evt| @event_sink._on_size(evt) }
  end

  # call default handler
  super
end

#on_handle(handle) ⇒ Object

Parameters:



451
452
453
454
# File 'lib/wx/shapes/shapes/control_shape.rb', line 451

def on_handle(handle)
  super
  update_control
end

#scale(x, y, children: WITHCHILDREN) ⇒ Object

(new implementation should call default one ore scale shape’s children manually if necessary).

Parameters:

  • x (Float)

    Horizontal scale factor

  • y (Float)

    Vertical scale factor

  • children (defaults to: WITHCHILDREN)

    true if the shape’s children should be scaled as well, otherwise the shape will be updated after scaling via update() function.



342
343
344
345
# File 'lib/wx/shapes/shapes/control_shape.rb', line 342

def scale(x, y, children: WITHCHILDREN)
  super
  update_control
end

#set_control(ctrl, fit = FIT_SHAPE_TO_CONTROL) ⇒ Object

Set managed GUI control.

Parameters:

  • ctrl (Wx::Window)

    existing manager GUI control

  • fit (Boolean) (defaults to: FIT_SHAPE_TO_CONTROL)

    true if the control shape should be resized in accordance to the given GUI control



162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
# File 'lib/wx/shapes/shapes/control_shape.rb', line 162

def set_control(ctrl, fit = FIT_SHAPE_TO_CONTROL)
  if @control
    @control.disconnect(Wx::ID_ANY, Wx::ID_ANY, Wx::EVT_LEFT_DOWN)
    @control.disconnect(Wx::ID_ANY, Wx::ID_ANY, Wx::EVT_RIGHT_DOWN)
    @control.disconnect(Wx::ID_ANY, Wx::ID_ANY, Wx::EVT_LEFT_UP)
    @control.disconnect(Wx::ID_ANY, Wx::ID_ANY, Wx::EVT_RIGHT_UP)
    @control.disconnect(Wx::ID_ANY, Wx::ID_ANY, Wx::EVT_LEFT_DCLICK)
    @control.disconnect(Wx::ID_ANY, Wx::ID_ANY, Wx::EVT_RIGHT_DCLICK)
    @control.disconnect(Wx::ID_ANY, Wx::ID_ANY, Wx::EVT_MOTION)
    @control.disconnect(Wx::ID_ANY, Wx::ID_ANY, Wx::EVT_KEY_DOWN)
    @control.disconnect(Wx::ID_ANY, Wx::ID_ANY, Wx::EVT_SIZE)
    @control.hide
    @control.reparent(@prev_parent)
  end

  @control = ctrl
  
  if @control
    @prev_parent = ctrl.get_parent
    if @diagram
      canvas = @diagram.get_shape_canvas

      # reparent GUI control if necessary
      @control.reparent(canvas) if canvas && canvas != @prev_parent

      # redirect mouse events to the event sink for their delayed processing
      @control.evt_left_down { |evt| @event_sink._on_mouse_button(evt) }
      @control.evt_right_down { |evt| @event_sink._on_mouse_button(evt) }
      @control.evt_left_up { |evt| @event_sink._on_mouse_button(evt) }
      @control.evt_right_up { |evt| @event_sink._on_mouse_button(evt) }
      @control.evt_left_dclick { |evt| @event_sink._on_mouse_button(evt) }
      @control.evt_right_dclick { |evt| @event_sink._on_mouse_button(evt) }
      @control.evt_motion { |evt| @event_sink._on_mouse_move(evt) }
      @control.evt_key_down { |evt| @event_sink._on_key_down(evt) }
      @control.evt_size { |evt| @event_sink._on_size(evt) }
    end

    update_shape if fit

    update_control
  end
end

#set_control_offset(offset) ⇒ Object

Set control shape’s offset (a gap between the shape’s border and managed GUI control).

Parameters:

  • offset (Integer)

    Offset size



284
285
286
# File 'lib/wx/shapes/shapes/control_shape.rb', line 284

def set_control_offset(offset)
  @control_offset = offset
end

#set_event_processing(mask) ⇒ Object

Set the way how GUI control’s events are processed.

Parameters:

See Also:



228
229
230
# File 'lib/wx/shapes/shapes/control_shape.rb', line 228

def set_event_processing(mask)
  @process_events = mask
end

#set_mod_border(pen) ⇒ Object #set_mod_border(color, width = 1, style = Wx::PenStyle::PENSTYLE_SOLID) ⇒ Object

Set control shape’s border style used during its modification.

Overloads:

  • #set_mod_border(pen) ⇒ Object

    Parameters:

  • #set_mod_border(color, width = 1, style = Wx::PenStyle::PENSTYLE_SOLID) ⇒ Object

    Parameters:

    • color (Wx::Colour, String, Symbol)
    • width (Integer) (defaults to: 1)
    • style (Wx::PenStyle) (defaults to: Wx::PenStyle::PENSTYLE_SOLID)


268
269
270
271
272
273
274
# File 'lib/wx/shapes/shapes/control_shape.rb', line 268

def set_mod_border(pen)
  @mod_border = if args.size == 1 && Wx::Pen === args.first
                  args.first
                else
                  Wx::Pen.new(*args)
                end
end

#set_mod_fill(brush) ⇒ Object #set_mod_fill(color, style = Wx::BrushStyle::BRUSHSTYLE_SOLID) ⇒ Object #set_mod_fill(stipple_bitmap) ⇒ Object

Set control shape’s background style used during its modification.

Overloads:

  • #set_mod_fill(brush) ⇒ Object

    Parameters:

  • #set_mod_fill(color, style = Wx::BrushStyle::BRUSHSTYLE_SOLID) ⇒ Object

    Parameters:

    • color (Wx::Colour, Symbol, String)

      brush color

    • style (Wx::BrushStyle) (defaults to: Wx::BrushStyle::BRUSHSTYLE_SOLID)
  • #set_mod_fill(stipple_bitmap) ⇒ Object

    Parameters:

    • stipple_bitmap (Wx::Bitmap)


247
248
249
250
251
252
253
# File 'lib/wx/shapes/shapes/control_shape.rb', line 247

def set_mod_fill(*args)
  @mod_fill = if args.size == 1 && Wx::Brush === args.first
                args.first
              else
                Wx::Brush.new(*args)
              end
end

#set_parent_shape(parent) ⇒ Object Also known as: parent_shape=

Set parent shape object

Parameters:



331
332
333
334
# File 'lib/wx/shapes/shapes/control_shape.rb', line 331

def set_parent_shape(parent)
  super
  update
end

#update(recurse = true) ⇒ Object

Update shape (align all child shapes an resize it to fit them)



364
365
366
367
# File 'lib/wx/shapes/shapes/control_shape.rb', line 364

def update(recurse = true)
  super
  update_control
end

#update_controlObject

Update size and position of the managed control according to the parent shape.



295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
# File 'lib/wx/shapes/shapes/control_shape.rb', line 295

def update_control
  if @control
    min_bb = @control.get_min_size
    rct_bb = get_bounding_box.deflate!(@control_offset, @control_offset)

    if rct_bb.width < min_bb.width
      rct_bb.width = min_bb.width
      @rect_size.x = min_bb.width + 2*@control_offset
    end
    if rct_bb.height < min_bb.height
      rct_bb.height = min_bb.height
      @rect_size.y = min_bb.height + 2*@control_offset
    end

    x, y = get_parent_canvas.calc_unscrolled_position(0, 0)

    # set the control's dimensions and position according to the parent control shape
    @control.set_size([rct_bb.width, rct_bb.height])
    @control.move(rct_bb.left - x, rct_bb.top - y)
  end
end

#update_shapeObject

Update size of the shape position according to the managed control.



318
319
320
321
322
323
324
325
326
327
# File 'lib/wx/shapes/shapes/control_shape.rb', line 318

def update_shape
  if @control
    ctrl_size = @control.size

    @rect_size.x = ctrl_size.x + 2*@control_offset
    @rect_size.y = ctrl_size.y + 2*@control_offset

    get_parent_canvas.refresh(false)
  end
end