Class: Teek::UI::WidgetType Private

Inherits:
Object
  • Object
show all
Defined in:
lib/teek/ui/widget_type.rb

Overview

This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.

A single widget/node type's own metadata: what it draws, how it's built and arranged, what it validates - self-contained enough that WidgetDSL (the builder), Realizer, and Validator can each treat a registered type as the sole source of truth for it, dispatched by node type via WidgetTypes.

Leaf defaults cover the common case, so a real widget is a ~5-line descriptor: +WidgetType.new(type: :divider, tk_command: 'ttk::separator')+ is a complete, working leaf widget. A container, or a widget needing bespoke DSL methods/realize setup, overrides +dsl:+/+post_create:+.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(type:, tk_command:, leaf: true, natively_scrollable: false, arranged: true, scroll_default: :auto_scroll, bind_option: nil, flow: nil, arrange: nil, custom_children: nil, custom_create: nil, validator: nil, dsl: nil, post_create: nil, addressing: WidgetAddressing) ⇒ WidgetType

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns a new instance of WidgetType.

Parameters:

  • type (Symbol)

    the node type this describes, e.g. :divider

  • tk_command (String)

    the Tk widget-creation command, e.g. 'ttk::separator' - documentary only for a type that also sets custom_create:, since that hook bypasses the generic widget-creation call this would otherwise drive

  • leaf (Boolean) (defaults to: true)

    true for a childless widget (the default); false for a container that holds a DSL subtree

  • natively_scrollable (Boolean) (defaults to: false)

    whether this widget already speaks Tk's -yscrollcommand/-xscrollcommand protocol - see Realizer#auto_scrollable?, which consults this for a registered type

  • scroll_default (Symbol) (defaults to: :auto_scroll)

    which Teek::UI global default reader this type's own auto-scrollable wrapping falls back to when neither the widget's own scroll: nor the session's app-wide override says otherwise - :auto_scroll (the default) for most natively-scrollable types, :auto_scroll_canvas for canvas specifically. Only meaningful alongside natively_scrollable: true - see Realizer#resolve_scroll.

  • arranged (Boolean) (defaults to: true)

    whether a geometry manager (pack/grid) should place this node inside its parent - true (the default) for almost everything; false for a type placed some other way entirely, e.g. a toplevel window (placed by the window manager, not its nominal parent) or a tab/pane (placed by its own container's add command) - see Realizer#unarranged?, which consults this for a registered type

  • bind_option (Symbol, nil) (defaults to: nil)

    the Tk option bind: plugs a Var into for this widget (+:textvariable+/+:variable+/...) - nil (the default) means this widget doesn't support bind:

  • flow (Hash, nil) (defaults to: nil)

    flow-packing config for a column/row- style container (side/main_pad/cross_pad/main_fill/cross_fill/ anchor) - nil (the default) means this type isn't flow-arranged. A convenience over arrange: for exactly this shape: giving flow: computes an arrange: that delegates to Realizer#arrange_flow with this data, so most flow containers never need to touch arrange: directly.

  • arrange (#call, nil) (defaults to: nil)

    ->(realizer, node, children) { ... }, replaces the realizer's generic "pack every child plainly" default arrangement for this type entirely - e.g. real Tk grid placement (row/col/span/stretch) for a :grid-shaped type. Since the logic usually needs realizer-private helpers (gap/align computation, error formatting, ...), the callable is typically a thin adapter delegating back via realizer.send(:some_private_method, ...) rather than reimplementing arrangement from scratch - see Realizer#arrange_grid for an example. nil (the default, unless flow: computed one) means the generic pack default applies.

  • custom_children (#call, nil) (defaults to: nil)

    ->(realizer, node, path) { ... }, replaces the realizer's generic "create every child normally" step for this type, once its OWN widget has already been created the normal way - e.g. :scrollable's children live inside an embedded canvas+viewport it builds itself, not directly under its own path. nil (the default) means children realize normally.

  • custom_create (#call, nil) (defaults to: nil)

    ->(realizer, node, parent_path) { ... }, replaces the realizer's ENTIRE per-node create/link handling for this type - no generic widget-creation call, no #post_create, no #arrange/custom_children, no normal link processing (events/close-handler/child recursion) either. For a type whose realize model doesn't share ANY of that machinery at all - e.g. :menu_bar/:context_menu, realized via Realizer#create_menu_tree's own bespoke traversal, using Teek::App#menu rather than a generic widget-creation command. nil (the default) means this type goes through the normal create/link two-pass path.

  • validator (#call, nil) (defaults to: nil)

    a (node, parent, document, errors) callable checking this type's own contract - a REFERENCE to an already-written validator (e.g. an existing WidgetValidators-style module), not duplicated logic. Composed into Teek::UI::WidgetValidators automatically at Teek::UI::WidgetTypes.register time, so Validator needs no separate awareness of descriptors at all.

  • dsl (Proc, nil) (defaults to: nil)

    ->(mod) { ... }, called once at Teek::UI::WidgetTypes.register time (and replayed for any subscriber that joins later - see Teek::UI::WidgetTypes.on_register) to define this type's ui.<type> method(s) on the builder module. Defaults to the leaf/container-appropriate +append_leaf+/+append_container+ call - pass ->(mod) { } (a genuine no-op) for a type reachable only via a bespoke, hand-written top-level method with a different signature (e.g. #tab/#pane/#split, or #menu_bar/#context_menu), so the registry doesn't shadow it with a same-named generic method.

  • post_create (#call, nil) (defaults to: nil)

    ->(app, node, path, parent_path) { ... }, run right after the generic widget-creation command at realize - see Teek::UI::WindowRealize/TabRealize/PaneRealize for real examples. Defaults to a no-op. Not called at all for a type that sets custom_create:, since that hook bypasses this entire step.

  • addressing (#new, nil) (defaults to: WidgetAddressing)

    a class - +->(node) { ... }+-shaped via .new - knowing how to read/write THIS type's live state (+#virtual_path+, #configure). Handle resolves this per node from the registry, with no type-specific knowledge of its own - a plugin/custom widget type gets correct addressing purely by registering its own addressing: here. Defaults to Teek::UI::WidgetAddressing (an ordinary Tk widget with its own path) - see MenuEntryAddressing for a type with none of its own.



113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# File 'lib/teek/ui/widget_type.rb', line 113

def initialize(type:, tk_command:, leaf: true, natively_scrollable: false, arranged: true,
                scroll_default: :auto_scroll, bind_option: nil, flow: nil, arrange: nil,
                custom_children: nil, custom_create: nil, validator: nil, dsl: nil, post_create: nil,
                addressing: WidgetAddressing)
  @type = type.to_sym
  @tk_command = tk_command
  @leaf = leaf
  @natively_scrollable = natively_scrollable
  @arranged = arranged
  @scroll_default = scroll_default
  @bind_option = bind_option
  @flow = flow
  @arrange = arrange || (flow && ->(realizer, node, children) { realizer.send(:arrange_flow, node, children, flow) })
  @custom_children = custom_children
  @custom_create = custom_create
  @validator = validator
  @dsl = dsl || default_dsl
  @addressing = addressing
  @post_create = post_create
end

Instance Attribute Details

#addressingObject (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



21
22
23
# File 'lib/teek/ui/widget_type.rb', line 21

def addressing
  @addressing
end

#bind_optionObject (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



21
22
23
# File 'lib/teek/ui/widget_type.rb', line 21

def bind_option
  @bind_option
end

#flowObject (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



21
22
23
# File 'lib/teek/ui/widget_type.rb', line 21

def flow
  @flow
end

#tk_commandObject (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



21
22
23
# File 'lib/teek/ui/widget_type.rb', line 21

def tk_command
  @tk_command
end

#typeObject (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



21
22
23
# File 'lib/teek/ui/widget_type.rb', line 21

def type
  @type
end

#validatorObject (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



21
22
23
# File 'lib/teek/ui/widget_type.rb', line 21

def validator
  @validator
end

Instance Method Details

#arrange(realizer, node, children) ⇒ void

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

This method returns an undefined value.

Runs this type's custom arrangement strategy.

Parameters:

  • realizer (Realizer)
  • node (Node)
  • children (Array<Node>)

    this node's arrangeable children



170
171
172
# File 'lib/teek/ui/widget_type.rb', line 170

def arrange(realizer, node, children)
  @arrange.call(realizer, node, children)
end

#arrange?Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns whether this type replaces the generic arrangement.

Returns:

  • (Boolean)

    whether this type replaces the generic arrangement



161
162
163
# File 'lib/teek/ui/widget_type.rb', line 161

def arrange?
  !@arrange.nil?
end

#arranged?Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns:

  • (Boolean)


156
157
158
# File 'lib/teek/ui/widget_type.rb', line 156

def arranged?
  @arranged
end

#container?Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns:

  • (Boolean)


140
141
142
# File 'lib/teek/ui/widget_type.rb', line 140

def container?
  !@leaf
end

#custom_children(realizer, node, path) ⇒ void

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

This method returns an undefined value.

Runs this type's custom child-creation strategy, once its own widget already exists at path.

Parameters:



185
186
187
# File 'lib/teek/ui/widget_type.rb', line 185

def custom_children(realizer, node, path)
  @custom_children.call(realizer, node, path)
end

#custom_children?Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns whether this type replaces generic child creation.

Returns:

  • (Boolean)

    whether this type replaces generic child creation



175
176
177
# File 'lib/teek/ui/widget_type.rb', line 175

def custom_children?
  !@custom_children.nil?
end

#custom_create(realizer, node, parent_path) ⇒ void

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

This method returns an undefined value.

Runs this type's entire create/link replacement.

Parameters:



199
200
201
# File 'lib/teek/ui/widget_type.rb', line 199

def custom_create(realizer, node, parent_path)
  @custom_create.call(realizer, node, parent_path)
end

#custom_create?Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns whether this type replaces the entire create/link handling.

Returns:

  • (Boolean)

    whether this type replaces the entire create/link handling



190
191
192
# File 'lib/teek/ui/widget_type.rb', line 190

def custom_create?
  !@custom_create.nil?
end

#define_dsl_method!(mod) ⇒ void

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

This method returns an undefined value.

Defines this type's ui.<type> method(s) on mod (the Teek::UI::WidgetDSL module) - see Teek::UI::WidgetTypes.on_register, which drives this.

Parameters:

  • mod (Module)


207
208
209
# File 'lib/teek/ui/widget_type.rb', line 207

def define_dsl_method!(mod)
  @dsl.call(mod)
end

#global_scroll_defaultBoolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns the current value of this type's own Teek::UI global scroll-default reader (+scroll_default:+).

Returns:

  • (Boolean)

    the current value of this type's own Teek::UI global scroll-default reader (+scroll_default:+)



151
152
153
# File 'lib/teek/ui/widget_type.rb', line 151

def global_scroll_default
  Teek::UI.public_send(@scroll_default)
end

#leaf?Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns:

  • (Boolean)


135
136
137
# File 'lib/teek/ui/widget_type.rb', line 135

def leaf?
  @leaf
end

#natively_scrollable?Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns:

  • (Boolean)


145
146
147
# File 'lib/teek/ui/widget_type.rb', line 145

def natively_scrollable?
  @natively_scrollable
end

#post_create(app, node, path, parent_path) ⇒ void

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

This method returns an undefined value.

Runs this type's post-creation realize setup, if any - a no-op unless post_create: was given.

Parameters:

  • app (Teek::App)
  • node (Node)
  • path (String)
  • parent_path (String)


218
219
220
# File 'lib/teek/ui/widget_type.rb', line 218

def post_create(app, node, path, parent_path)
  @post_create&.call(app, node, path, parent_path)
end