Class: Teek::UI::Var

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

Overview

A reactive Tcl variable, wrapped for Ruby - Tk's own native -textvariable/-variable machinery, done properly instead of the hand-rolled "VAR_NAME constant + manual set_variable/get_variable" pattern this replaces. Widgets bound to the same Var stay in sync with each other for free (that part is entirely Tk's doing); this class adds typed Ruby access and an on_change callback on top.

Its Tcl variable name is allocated at build time (see WidgetDSL#var)

  • a plain string, no interpreter needed - so widgets can capture it as a -variable/-textvariable option before realize even happens. The variable itself, its initial value, and its change trace only become real at #realize.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, initial) ⇒ Var

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 Var.



24
25
26
27
28
29
# File 'lib/teek/ui/var.rb', line 24

def initialize(name, initial)
  @name = name
  @initial = initial
  @on_change_callbacks = []
  @app = nil
end

Instance Attribute Details

#nameString (readonly)

Returns the Tcl variable name.

Returns:

  • (String)

    the Tcl variable name



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

def name
  @name
end

Instance Method Details

#on_change {|value| ... } ⇒ self

Register a callback fired whenever the value changes, regardless of whether Ruby (#value=) or a bound widget caused it. Queues regardless of build/realize phase - there's only ever one underlying Tcl trace per Var, wired once at realize, so callbacks added later just join the same list.

Yields:

  • (value)

    the new, coerced value

Returns:

  • (self)


52
53
54
55
# File 'lib/teek/ui/var.rb', line 52

def on_change(&block)
  @on_change_callbacks << block
  self
end

#realize(app) ⇒ Object

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.

Create the backing Tcl variable, set its initial value, and wire the change trace. Called once by Session#realize, before the widget tree realizes, so bound widgets display the initial value from the moment they're created rather than starting blank.



62
63
64
65
66
67
# File 'lib/teek/ui/var.rb', line 62

def realize(app)
  @app = app
  @app.set_variable(@name, to_tcl(@initial))
  cb_id = @app.register_callback(proc { |*| notify_change })
  @app.tcl_eval("trace add variable #{@name} write {ruby_callback #{cb_id}}")
end

#valueObject

The current value, coerced to match the initial value's type (Integer/Float/Boolean pass through typed; anything else is a String).

Raises:



34
35
36
37
# File 'lib/teek/ui/var.rb', line 34

def value
  raise_unless_realized!
  coerce(@app.get_variable(@name))
end

#value=(new_value) ⇒ Object

Raises:



40
41
42
43
# File 'lib/teek/ui/var.rb', line 40

def value=(new_value)
  raise_unless_realized!
  @app.set_variable(@name, to_tcl(new_value))
end