Class: GlimR::Layout
- Defined in:
- lib/glimr/widgets/layout.rb
Overview
A Layout is a Widget that layouts its child widgets.
Layouts come in two breeds: the horizontal layout and the vertical layout. A horizontal layout (or HLayout) arranges its children in a row, while a vertical layout (a.k.a. VLayout) arranges them in a column.
A layout has two alignment attributes, the #align and the #valign. Align determines where to put the children on the horizontal axis, and valign does the same on the vertical axis.
Align value :left aligns the left border of the layouted widgets and pushes them to the left border of the layout. Using :right as align does the same, except for the right border. The :center align aligns the centerline of the widgets with the layout’s centerline. The default align is :left.
Valign takes three values as well: :top, :bottom, and :middle. The default is :top, and aligns the top border of the widgets with the top border of the layout. To align to the bottom border, use :bottom. The :middle valign aligns the vertical midpoint of the widgets with the layout’s vertical midpoint.
Item spacing controls the amount of space between the layouted widgets. The default item spacing is 2.
A Layout fits its children by default and doesn’t expand to maximum width or height.
Constant Summary
Constants included from Layoutable
Instance Attribute Summary collapse
-
#direction ⇒ Object
Returns the value of attribute direction.
-
#item_spacing ⇒ Object
Returns the value of attribute item_spacing.
Attributes inherited from Widget
Attributes included from Layoutable
Attributes inherited from Model
#geometry, #material, #shader, #texture, #transform
Attributes inherited from SceneObject
#children, #drawables, #mtime, #parent, #viewport
Attributes included from EventListener
#event_listeners, #listener_count
Instance Method Summary collapse
- #calculate_free_height ⇒ Object
- #calculate_free_width ⇒ Object
- #children_change ⇒ Object
- #default_config ⇒ Object
-
#fit_height! ⇒ Object
If direction is horizontal, sets height equal to the largest child + padding.
-
#fit_width! ⇒ Object
If direction is vertical, sets width equal to the largest child + padding.
- #free_height ⇒ Object
- #free_width ⇒ Object
-
#horiz_tile(objs) ⇒ Object
Horizontally tile objects inside self.
- #layout ⇒ Object
-
#vert_tile(objs) ⇒ Object
Vertically tile objects inside self.
Methods inherited from Widget
#activate, #blur, #click, #focus, for, #initialize, #key_down, #key_up, #lock, #mouse_down, #mouse_move, #mouse_out, #mouse_over, #mouse_up, #unlock
Methods included from Layoutable
#attach, #constant_size?, #detach, #expand!, #expand?, #expand_height, #expand_to_max_height!, #expand_to_max_width!, #expand_width, #fit_to_children!, #full_depth, #full_height, #full_width, #initialize, #inner_depth, #inner_height, #inner_width, #inspect, #layoutable_children, #margin, #margin=, #max_height=, #max_width=, #min_height=, #min_width=, #padding, #padding=, #parent=, #size_changing, size_changing_accessor, #tell_children_of_size_change, #x=, #y=
Methods inherited from Model
#absolute_transform, #apply, #initialize, #inspect, #pop_state, #push_state
Methods inherited from SceneObject
#<<, #absolute_geometry, #absolute_material, #absolute_shader, #absolute_texture, #absolute_transform, #absolute_transform_for_drawing, #add_drawables, #apply, #attach, #clone, #detach, #detach_self, #initialize, #inspect, #pop_state, #push_state, #remove_drawables, #render, #replace_node, #root, #touch!, #visible
Methods included from Configurable
Methods included from EventListener
#add_event_listener, #decrement_listener_count, #dispatch_event, #event_root, #increment_listener_count, #initialize, #method_missing, #multicast_event, #process_event, #remove_event_listener
Constructor Details
This class inherits a constructor from GlimR::Widget
Dynamic Method Handling
This class handles dynamic methods through the method_missing method in the class GlimR::EventListener
Instance Attribute Details
#direction ⇒ Object
Returns the value of attribute direction.
39 40 41 |
# File 'lib/glimr/widgets/layout.rb', line 39 def direction @direction end |
#item_spacing ⇒ Object
Returns the value of attribute item_spacing.
39 40 41 |
# File 'lib/glimr/widgets/layout.rb', line 39 def item_spacing @item_spacing end |
Instance Method Details
#calculate_free_height ⇒ Object
185 186 187 188 189 190 191 192 193 194 195 196 197 |
# File 'lib/glimr/widgets/layout.rb', line 185 def calculate_free_height return inner_height if @direction == :horizontal objs = layoutable_children fit_height_objs, constant_height_objs = objs.partition{|o| o.} if fit_height_objs.empty? 0.0 else const_height = constant_height_objs.inject(0){|cw, o| cw + o.full_height } + (objs.size - 1) * @item_spacing [0.0, (inner_height - const_height) / fit_height_objs.size].max end end |
#calculate_free_width ⇒ Object
171 172 173 174 175 176 177 178 179 180 181 182 183 |
# File 'lib/glimr/widgets/layout.rb', line 171 def calculate_free_width return inner_width if @direction == :vertical objs = layoutable_children fit_width_objs, constant_width_objs = objs.partition{|o| o. } if fit_width_objs.empty? 0.0 else const_width = constant_width_objs.inject(0){|cw, o| cw + o.full_width } + (objs.size - 1) * @item_spacing [0.0, (inner_width - const_width) / fit_width_objs.size].max end end |
#children_change ⇒ Object
49 50 51 52 |
# File 'lib/glimr/widgets/layout.rb', line 49 def children_change @free_width = @free_height = nil layout end |
#default_config ⇒ Object
41 42 43 44 45 46 47 |
# File 'lib/glimr/widgets/layout.rb', line 41 def default_config super.merge( :item_spacing => 2, :direction => :horizontal, :fit_children => true ) end |
#fit_height! ⇒ Object
If direction is horizontal, sets height equal to the largest child + padding. If direction is vertical, sets height to sum of children heights + padding + item spacing.
65 66 67 68 69 70 |
# File 'lib/glimr/widgets/layout.rb', line 65 def fit_height! return super if direction == :horizontal self.height = layoutable_children.inject(padding_top+padding_left-item_spacing){|s,c| s + c.full_height + item_spacing } unless layoutable_children.empty? end |
#fit_width! ⇒ Object
If direction is vertical, sets width equal to the largest child + padding. If direction is horizontal, sets width to sum of children widths + padding + item spacing.
56 57 58 59 60 61 |
# File 'lib/glimr/widgets/layout.rb', line 56 def fit_width! return super if direction == :vertical self.width = layoutable_children.inject(padding_left+padding_right-item_spacing){|s,c| s + c.full_width + item_spacing } unless layoutable_children.empty? end |
#free_height ⇒ Object
167 168 169 |
# File 'lib/glimr/widgets/layout.rb', line 167 def free_height @free_height ||= calculate_free_height end |
#free_width ⇒ Object
163 164 165 |
# File 'lib/glimr/widgets/layout.rb', line 163 def free_width @free_width ||= calculate_free_width end |
#horiz_tile(objs) ⇒ Object
Horizontally tile objects inside self.
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
# File 'lib/glimr/widgets/layout.rb', line 106 def horiz_tile(objs) objs_width = objs.inject(-@item_spacing){|s,o| s + o.full_width + @item_spacing } x = case @align when :left @padding_left when :right @padding_left + inner_width - objs_width when :center, :middle @padding_left + (inner_width - objs_width) / 2 end ih = inner_height objs.each{|obj| obj.x = x + obj.margin_left obj.y = case @valign when :top @padding_top when :bottom @padding_top + ih - obj.full_height when :center, :middle @padding_top + (ih - obj.full_height) / 2 end obj.z = 1 x += obj.full_width + @item_spacing } end |
#layout ⇒ Object
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/glimr/widgets/layout.rb', line 72 def layout return if @layouting c = layoutable_children return if c.empty? @layouting = true size_changing do @free_width = @free_height = nil @id ||= 0 @id += 1 c.each{|ch| ch.width = free_width-ch.margin_left-ch.margin_right if ch. ch.height = free_height-ch.margin_top-ch.margin_bottom if ch. } fit_to_children! if fit_children? if @direction == :horizontal horiz_tile(c) else vert_tile(c) end end @layouting = false end |
#vert_tile(objs) ⇒ Object
Vertically tile objects inside self.
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 |
# File 'lib/glimr/widgets/layout.rb', line 135 def vert_tile(objs) objs_height = objs.inject(-@item_spacing){|s,o| s + o.full_height + @item_spacing } y = case @align when :left @padding_top when :right @padding_top + inner_height - objs_height when :center, :middle @padding_top + (inner_height - objs_height) / 2 end iw = inner_width objs.each{|obj| obj.y = y + obj.margin_top obj.x = case @align when :left @padding_left when :right @padding_left + iw - obj.full_width when :center, :middle @padding_left + (iw - obj.full_width) / 2 end obj.z = 1 y += obj.full_height + @item_spacing } end |