65 lines
1.7 KiB
Ruby
65 lines
1.7 KiB
Ruby
class WindowBlock < Node
|
|
attr_accessor :children, :direction, :size, :x, :y, :width, :height
|
|
|
|
def initialize(direction = :horizontal)
|
|
@children = []
|
|
@direction = direction
|
|
super()
|
|
end
|
|
|
|
def add_node(node)
|
|
@children << node
|
|
end
|
|
|
|
def each_leaf(&block)
|
|
@children.each { |child| child.each_leaf(&block) }
|
|
end
|
|
|
|
def each_node(&block)
|
|
block.call(self)
|
|
@children.each { |child| child.each_node(&block) if child.is_a? WindowBlock }
|
|
end
|
|
|
|
def compute_geometry!
|
|
return if @children.empty?
|
|
|
|
horizontal = @direction == :horizontal
|
|
total_percent = @children.map { |c| c.size.to_i > 0 ? c.size.to_i : 0 }.sum
|
|
flex_count = @children.count { |c| c.size.to_i <= 0 }
|
|
total_space = horizontal ? @width : @height
|
|
total_percent = [total_percent, 100].min
|
|
remaining_percent = 100 - total_percent
|
|
flex_percent = flex_count > 0 ? remaining_percent / flex_count : 0
|
|
pos = horizontal ? @x : @y
|
|
|
|
@children.each do |child|
|
|
percent = child.size.to_i > 0 ? child.size.to_i : flex_percent
|
|
child_size = (total_space * percent) / 100.0
|
|
if horizontal
|
|
child.x = pos
|
|
child.y = @y
|
|
child.width = child_size
|
|
child.height = @height
|
|
else
|
|
child.x = @x
|
|
child.y = pos
|
|
child.width = @width
|
|
child.height = child_size
|
|
end
|
|
child.compute_geometry! if child.is_a?(WindowBlock)
|
|
child.apply_geometry! if child.is_a?(Window)
|
|
pos += child_size
|
|
end
|
|
end
|
|
end
|
|
|
|
class RootWindowBlock < WindowBlock
|
|
def initialize(workspace)
|
|
super(:horizontal)
|
|
@x = workspace.x
|
|
@y = workspace.y
|
|
@width = workspace.width
|
|
@height = workspace.height
|
|
end
|
|
end
|