Class: Clogs::Drawable

Inherits:
Shoes::Linkable
  • Object
show all
Defined in:
lib/clogs/drawable.rb

Overview

Base class for every Clogs peer: the display-side half of a Shoes drawable.

Lacci owns the Shoes-side object and tells us about it through three events (parent, prop_change, destroy). We own pixels: where the thing sits, how big it is, and what it looks like.

The layout contract is two passes:

measure(available_width) -> sets @width / @height
paint(painter, ox, oy)   -> draws, and records absolute geometry so that
                          mouse hit-testing has something to test

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(properties) ⇒ Drawable

Returns a new instance of Drawable.



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/clogs/drawable.rb', line 29

def initialize(properties)
  @styles = {}
  properties.each { |k, v| @styles[k.to_s] = v }
  @shoes_linkable_id = @styles.delete("shoes_linkable_id")
  @children = []
  @x = @y = 0
  @width = @height = 0

  super(linkable_id: @shoes_linkable_id)

  bind_shoes_event(event_name: "parent", target: @shoes_linkable_id) do |new_parent_id|
    new_parent = DisplayService.instance.query_display_drawable_for(new_parent_id, nil_ok: true)
    set_parent(new_parent) unless new_parent == @parent
  end

  bind_shoes_event(event_name: "prop_change", target: @shoes_linkable_id) do |changes|
    changes.each { |k, v| @styles[k.to_s] = v }
    properties_changed(changes)
  end

  bind_shoes_event(event_name: "destroy", target: @shoes_linkable_id) do
    destroy_self
  end
end

Instance Attribute Details

#abs_xObject (readonly)

Returns the value of attribute abs_x.



19
20
21
# File 'lib/clogs/drawable.rb', line 19

def abs_x
  @abs_x
end

#abs_yObject (readonly)

Returns the value of attribute abs_y.



19
20
21
# File 'lib/clogs/drawable.rb', line 19

def abs_y
  @abs_y
end

#childrenObject (readonly)

Returns the value of attribute children.



19
20
21
# File 'lib/clogs/drawable.rb', line 19

def children
  @children
end

#heightObject (readonly)

Returns the value of attribute height.



19
20
21
# File 'lib/clogs/drawable.rb', line 19

def height
  @height
end

#parentObject

Returns the value of attribute parent.



18
19
20
# File 'lib/clogs/drawable.rb', line 18

def parent
  @parent
end

#shoes_linkable_idObject (readonly)

Returns the value of attribute shoes_linkable_id.



19
20
21
# File 'lib/clogs/drawable.rb', line 19

def shoes_linkable_id
  @shoes_linkable_id
end

#stylesObject (readonly)

Returns the value of attribute styles.



19
20
21
# File 'lib/clogs/drawable.rb', line 19

def styles
  @styles
end

#widthObject (readonly)

Returns the value of attribute width.



19
20
21
# File 'lib/clogs/drawable.rb', line 19

def width
  @width
end

#xObject

Returns the value of attribute x.



18
19
20
# File 'lib/clogs/drawable.rb', line 18

def x
  @x
end

#yObject

Returns the value of attribute y.



18
19
20
# File 'lib/clogs/drawable.rb', line 18

def y
  @y
end

Class Method Details

.for_shoes_class(name) ⇒ Object

Peer class lookup by Shoes class name, e.g. "Shoes::Button" -> Clogs::Button.



23
24
25
26
# File 'lib/clogs/drawable.rb', line 23

def for_shoes_class(name)
  short = name.split("::").last
  Clogs.const_get(short) if Clogs.const_defined?(short, false)
end

Instance Method Details

#add_child(child) ⇒ Object



70
71
72
# File 'lib/clogs/drawable.rb', line 70

def add_child(child)
  @children << child unless @children.include?(child)
end

#appObject

The owning Clogs::App, found by walking up the tree.



79
80
81
# File 'lib/clogs/drawable.rb', line 79

def app
  @app ||= @parent&.app
end

#clickable?Boolean

In Shoes any drawable can carry a click handler, so every peer is a candidate; the topmost one under the pointer wins.

Returns:

  • (Boolean)


150
151
152
# File 'lib/clogs/drawable.rb', line 150

def clickable?
  true
end

#contains?(px, py) ⇒ Boolean

---- events -------------------------------------------------------

Returns:

  • (Boolean)


137
138
139
140
141
# File 'lib/clogs/drawable.rb', line 137

def contains?(px, py)
  return false if @abs_x.nil? || hidden?

  px >= @abs_x && px < @abs_x + @width && py >= @abs_y && py < @abs_y + @height
end

#destroy_selfObject



58
59
60
61
# File 'lib/clogs/drawable.rb', line 58

def destroy_self
  set_parent(nil)
  needs_layout!
end

#draw(_painter, _x, _y) ⇒ Object



133
# File 'lib/clogs/drawable.rb', line 133

def draw(_painter, _x, _y); end

#each_peer(&block) ⇒ Object

Depth-first list of visible peers in paint order, for hit testing.



175
176
177
178
179
180
# File 'lib/clogs/drawable.rb', line 175

def each_peer(&block)
  return if hidden?

  block.call(self)
  @children.each { |c| c.each_peer(&block) }
end

#focus_gainedObject



166
# File 'lib/clogs/drawable.rb', line 166

def focus_gained; end

#focus_lostObject



168
# File 'lib/clogs/drawable.rb', line 168

def focus_lost; end

#focusable?Boolean

Overridden by controls that want the keyboard.

Returns:

  • (Boolean)


144
145
146
# File 'lib/clogs/drawable.rb', line 144

def focusable?
  false
end

#hidden?Boolean

Returns:

  • (Boolean)


97
98
99
# File 'lib/clogs/drawable.rb', line 97

def hidden?
  !!style(:hidden)
end

#marginObject



107
108
109
# File 'lib/clogs/drawable.rb', line 107

def margin
  @margin ||= Style.margins(@styles)
end

#measure(available_width) ⇒ Object

Subclasses override. Must set @width and @height.



122
123
124
125
# File 'lib/clogs/drawable.rb', line 122

def measure(available_width)
  @width = requested_width(available_width) || 0
  @height = requested_height(available_width) || 0
end

#needs_layout!Object



83
84
85
# File 'lib/clogs/drawable.rb', line 83

def needs_layout!
  app&.needs_layout!
end

#notify(event_name, *args) ⇒ Object



170
171
172
# File 'lib/clogs/drawable.rb', line 170

def notify(event_name, *args)
  send_shoes_event(*args, event_name: event_name, target: @shoes_linkable_id)
end

#on_click(_x, _y, _button) ⇒ Object



154
# File 'lib/clogs/drawable.rb', line 154

def on_click(_x, _y, _button); end

#on_key(_event) ⇒ Object



162
163
164
# File 'lib/clogs/drawable.rb', line 162

def on_key(_event)
  false
end

#on_mouse_move(_x, _y) ⇒ Object



160
# File 'lib/clogs/drawable.rb', line 160

def on_mouse_move(_x, _y); end

#on_release(x, y, button) ⇒ Object



156
157
158
# File 'lib/clogs/drawable.rb', line 156

def on_release(x, y, button)
  notify("click", button, x.round, y.round) if contains?(x, y)
end

#paint(painter, ox, oy) ⇒ Object



127
128
129
130
131
# File 'lib/clogs/drawable.rb', line 127

def paint(painter, ox, oy)
  @abs_x = ox + @x
  @abs_y = oy + @y
  draw(painter, @abs_x, @abs_y)
end

#positioned?Boolean

A drawable with an explicit left/top is taken out of the normal flow and placed at those coordinates within its slot, exactly as in Shoes.

Returns:

  • (Boolean)


103
104
105
# File 'lib/clogs/drawable.rb', line 103

def positioned?
  !style(:left).nil? && !style(:top).nil?
end

#properties_changed(_changes) ⇒ Object



54
55
56
# File 'lib/clogs/drawable.rb', line 54

def properties_changed(_changes)
  needs_layout!
end

#redraw!Object



87
88
89
# File 'lib/clogs/drawable.rb', line 87

def redraw!
  app&.redraw!
end

#remove_child(child) ⇒ Object



74
75
76
# File 'lib/clogs/drawable.rb', line 74

def remove_child(child)
  @children.delete(child)
end

#requested_height(available) ⇒ Object



115
116
117
# File 'lib/clogs/drawable.rb', line 115

def requested_height(available)
  Style.dimension(style(:height), available)
end

#requested_width(available) ⇒ Object



111
112
113
# File 'lib/clogs/drawable.rb', line 111

def requested_width(available)
  Style.dimension(style(:width), available)
end

#set_parent(new_parent) ⇒ Object



63
64
65
66
67
68
# File 'lib/clogs/drawable.rb', line 63

def set_parent(new_parent)
  @parent&.remove_child(self)
  new_parent&.add_child(self)
  @parent = new_parent
  needs_layout!
end

#style(name) ⇒ Object

---- styles -------------------------------------------------------



93
94
95
# File 'lib/clogs/drawable.rb', line 93

def style(name)
  @styles[name.to_s]
end