Class: Clogs::Drawable
- Inherits:
-
Shoes::Linkable
- Object
- Shoes::Linkable
- Clogs::Drawable
- 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
Direct Known Subclasses
App, ArtDrawable, Control, Image, Para, Slot, SlotDecoration, SubscriptionItem, TextDrawable, Video
Instance Attribute Summary collapse
-
#abs_x ⇒ Object
readonly
Returns the value of attribute abs_x.
-
#abs_y ⇒ Object
readonly
Returns the value of attribute abs_y.
-
#children ⇒ Object
readonly
Returns the value of attribute children.
-
#height ⇒ Object
readonly
Returns the value of attribute height.
-
#parent ⇒ Object
Returns the value of attribute parent.
-
#shoes_linkable_id ⇒ Object
readonly
Returns the value of attribute shoes_linkable_id.
-
#styles ⇒ Object
readonly
Returns the value of attribute styles.
-
#width ⇒ Object
readonly
Returns the value of attribute width.
-
#x ⇒ Object
Returns the value of attribute x.
-
#y ⇒ Object
Returns the value of attribute y.
Class Method Summary collapse
-
.for_shoes_class(name) ⇒ Object
Peer class lookup by Shoes class name, e.g.
Instance Method Summary collapse
- #add_child(child) ⇒ Object
-
#app ⇒ Object
The owning Clogs::App, found by walking up the tree.
-
#clickable? ⇒ Boolean
In Shoes any drawable can carry a click handler, so every peer is a candidate; the topmost one under the pointer wins.
-
#contains?(px, py) ⇒ Boolean
---- events -------------------------------------------------------.
- #destroy_self ⇒ Object
- #draw(_painter, _x, _y) ⇒ Object
-
#each_peer(&block) ⇒ Object
Depth-first list of visible peers in paint order, for hit testing.
- #focus_gained ⇒ Object
- #focus_lost ⇒ Object
-
#focusable? ⇒ Boolean
Overridden by controls that want the keyboard.
- #hidden? ⇒ Boolean
-
#initialize(properties) ⇒ Drawable
constructor
A new instance of Drawable.
- #margin ⇒ Object
-
#measure(available_width) ⇒ Object
Subclasses override.
- #needs_layout! ⇒ Object
- #notify(event_name, *args) ⇒ Object
- #on_click(_x, _y, _button) ⇒ Object
- #on_key(_event) ⇒ Object
- #on_mouse_move(_x, _y) ⇒ Object
- #on_release(x, y, button) ⇒ Object
- #paint(painter, ox, oy) ⇒ Object
-
#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.
- #properties_changed(_changes) ⇒ Object
- #redraw! ⇒ Object
- #remove_child(child) ⇒ Object
- #requested_height(available) ⇒ Object
- #requested_width(available) ⇒ Object
- #set_parent(new_parent) ⇒ Object
-
#style(name) ⇒ Object
---- styles -------------------------------------------------------.
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_x ⇒ Object (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_y ⇒ Object (readonly)
Returns the value of attribute abs_y.
19 20 21 |
# File 'lib/clogs/drawable.rb', line 19 def abs_y @abs_y end |
#children ⇒ Object (readonly)
Returns the value of attribute children.
19 20 21 |
# File 'lib/clogs/drawable.rb', line 19 def children @children end |
#height ⇒ Object (readonly)
Returns the value of attribute height.
19 20 21 |
# File 'lib/clogs/drawable.rb', line 19 def height @height end |
#parent ⇒ Object
Returns the value of attribute parent.
18 19 20 |
# File 'lib/clogs/drawable.rb', line 18 def parent @parent end |
#shoes_linkable_id ⇒ Object (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 |
#styles ⇒ Object (readonly)
Returns the value of attribute styles.
19 20 21 |
# File 'lib/clogs/drawable.rb', line 19 def styles @styles end |
#width ⇒ Object (readonly)
Returns the value of attribute width.
19 20 21 |
# File 'lib/clogs/drawable.rb', line 19 def width @width end |
#x ⇒ Object
Returns the value of attribute x.
18 19 20 |
# File 'lib/clogs/drawable.rb', line 18 def x @x end |
#y ⇒ Object
Returns the value of attribute y.
18 19 20 |
# File 'lib/clogs/drawable.rb', line 18 def y @y end |
Class Method Details
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 |
#app ⇒ Object
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.
150 151 152 |
# File 'lib/clogs/drawable.rb', line 150 def clickable? true end |
#contains?(px, py) ⇒ Boolean
---- events -------------------------------------------------------
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_self ⇒ Object
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_gained ⇒ Object
166 |
# File 'lib/clogs/drawable.rb', line 166 def focus_gained; end |
#focus_lost ⇒ Object
168 |
# File 'lib/clogs/drawable.rb', line 168 def focus_lost; end |
#focusable? ⇒ Boolean
Overridden by controls that want the keyboard.
144 145 146 |
# File 'lib/clogs/drawable.rb', line 144 def focusable? false end |
#hidden? ⇒ Boolean
97 98 99 |
# File 'lib/clogs/drawable.rb', line 97 def hidden? !!style(:hidden) end |
#margin ⇒ Object
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, ); 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, ) notify("click", , 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.
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 |