123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315 |
- ## $Id$
- ## ______ __ ___
- ## | ___| |.-----.--.--.| | .---.-.--.--.
- ## | ___| || -__|_ _|| |_| _ | | |
- ## |__| |__||_____|__.__||_____|___._|___ |
- ## |_____|
- ## Copyright (C) 2004 Ingo Ruhnke <grumbel@gmx.de>
- ##
- ## This program is free software: you can redistribute it and/or modify
- ## it under the terms of the GNU General Public License as published by
- ## the Free Software Foundation, either version 3 of the License, or
- ## (at your option) any later version.
- ##
- ## This program is distributed in the hope that it will be useful,
- ## but WITHOUT ANY WARRANTY; without even the implied warranty of
- ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ## GNU General Public License for more details.
- ##
- ## You should have received a copy of the GNU General Public License
- ## along with this program. If not, see <http://www.gnu.org/licenses/>.
- require "sexpr.rb"
- # Helper class that holds all necesarry paramter to handle layouting,
- # could also extend Component instead
- class LayoutComponent
- attr_reader :component, :name, :size,:expand, :fill, :padding
- # use nil for width and height if it should be determined
- # automatically
- def initialize(component, child, params)
- @component = component
- @child = child
- @name = params[:name]
- @size = params[:size]
- @expand = params[:expand]
- @fill = params[:fill]
- @padding = params[:padding]
- end
- def get(name)
- if @child then
- return @child.get(name)
- else
- return nil
- end
- end
-
- def set_pos(x, y)
- if @component then
- @component.set_position(x, y)
- end
- end
-
- def set_size(width, height)
- if @component then
- @component.set_size(width, height)
- end
- if @child then
- @child.set_size(width, height)
- end
- end
- # Rearanges the layout to fit the current size
- def layout()
- if @child then
- return @child.layout()
- end
- end
- def LayoutComponent.create_from_sexpr(rect, sexpr, parent)
- create(sexpr.car().value(), rect, sexpr.cdr(), parent)
- end
-
- def LayoutComponent.create(type, rect, sexpr, parent)
- # puts "Create: #{type}"
- case type
- when :vbox
- return LayoutBox.new(type, rect, sexpr, parent)
- when :hbox
- return LayoutBox.new(type, rect, sexpr, parent)
- when :panel
- panel = Panel.new(rect, parent)
- return LayoutComponent.new(panel,
- LayoutBox.new(sexpr.get_value([:layout, '_'], :vbox),
- CL_Rect.new(0, 0, rect.get_width(), rect.get_height()),
- sexpr, panel),
- :name => sexpr.get_value([:name, '_'], nil),
- :size => sexpr.get_value([:size, '_'], nil),
- :expand => sexpr.get_value([:expand, '_'], true),
- :fill => sexpr.get_value([:fill, '_'], true),
- :padding => sexpr.get_value([:padding, '_'], 0))
- when :tab
- return TabComponent.new(rect, sexpr, parent)
- else
- return LayoutComponent.new(create_raw(type, rect, sexpr, parent),
- nil,
- :name => sexpr.get_value([:name, '_'], nil),
- :size => sexpr.get_value([:size, '_'], nil),
- :expand => sexpr.get_value([:expand, '_'], true),
- :fill => sexpr.get_value([:fill, '_'], true),
- :padding => sexpr.get_value([:padding, '_'], 0))
- end
- end
- def LayoutComponent.create_raw(type, rect, sexpr, parent)
- case type
- when :editormap
- return EditorMapComponent.new(rect, parent)
-
- when :menubar
- return CL_Menu.new_from_spec(sexpr.get_value(['spec', '_'], []),
- parent)
- when :button
- return CL_Button.new(rect,
- sexpr.get_value(['label', '_'], []),
- parent)
- when :label
- return CL_Label.new(CL_Point.new(rect.top, rect.left),
- sexpr.get_value(['label', '_'], []),
- parent)
- when :listbox
- return CL_ListBox.new(rect, parent)
-
- when :inputbox
- return CL_InputBox.new(rect, parent)
- when :radiobutton
- return CL_RadioButton.new(CL_Point.new(rect.left, rect.top),
- sexpr.get_value(['label', '_'], []),
- parent)
- when :radiogroup
- return CL_RadioGroup.new()
- when :checkbox
- return CL_CheckBox.new(CL_Point.new(rect.left, rect.top),
- sexpr.get_value(['label', '_'], []),
- parent)
- when :buttonpanel
- return ButtonPanel.new_from_spec(rect.left, rect.top, rect.get_width(), rect.get_height(), true,
- sexpr.get_value([:spec, '_'], []), parent)
- when :tileselector
- return TileSelector.new(rect, parent)
-
- when :objectselector
- return ObjectSelector.new(rect,
- sexpr.get_value([:objectwidth, '_'], 42),
- sexpr.get_value([:objectheight, '_'], 42),
- parent)
- when :minimap
- @minimap = Minimap.new(nil, rect, parent)
-
- else
- raise "Unknonwn Component type '#{type.inspect}'"
- end
- end
- end
- class TabComponent < LayoutComponent
- def initialize(rect, sexpr, parent)
- super(nil, nil,
- :name => sexpr.get_value([:name, '_'], nil),
- :size => sexpr.get_value([:size, '_'], nil),
- :expand => sexpr.get_value([:expand, '_'], true),
- :fill => sexpr.get_value([:fill, '_'], true),
- :padding => sexpr.get_value([:padding, '_'], 0))
-
- @childs = []
- sexpr.get(:components, SExpression.new()).each_pair() { |name, value|
- @childs.push(LayoutComponent.create(name, CL_Rect.new(0, 0, 256, 256), value, parent))
- }
- end
- def get(name)
- @childs.each() { |i|
- if i.name == name then
- return i
- end
- }
- return nil
- end
-
- def set_pos(x, y)
- @childs.each() { |i| i.set_pos(x, y) }
- end
-
- def set_size(width, height)
- @childs.each() { |i| i.set_size(width, height) }
- end
- # Rearanges the layout to fit the current size
- def layout()
- @childs.each() { |i| i.layout() }
- end
- end
- class LayoutBox < LayoutComponent
- def initialize(type, rect, sexpr, parent)
- super(nil, nil,
- :name => sexpr.get_value([:name, '_'], nil),
- :size => sexpr.get_value([:size, '_'], nil),
- :expand => sexpr.get_value([:expand, '_'], true),
- :fill => sexpr.get_value([:fill, '_'], true),
- :padding => sexpr.get_value([:padding, '_'], 0))
- @type = type # :vbox or :hbox
- @x = rect.left
- @y = rect.top
- @width = rect.get_width()
- @height = rect.get_height()
- @parent = parent
- @components = []
- @homogenus = false
- sexpr.get(:components, SExpression.new()).each_pair() { |name, value|
- @components.push(LayoutComponent.create(name, CL_Rect.new(0, 0, 256, 256), value, @parent))
- }
- layout()
- end
- def get(name)
- @components.each() { |i|
- if i.name == name then
- return i
- else
- a = i.get(name)
- if a then return a end
- end
- }
- return nil
- end
- def add(type, spec)
- @components.push([type, spec, nil])
- end
-
- def set_pos(x, y)
- @x = x
- @y = y
- layout()
- end
- def set_size(width, height)
- @width = width
- @height = height
- layout()
- end
- def layout()
- x = @x
- y = @y
- len = 0
- num = 0
- @components.each() { |component|
- if component.size then
- len += component.size
- else
- num += 1
- end
- }
- if @type == :vbox
- avlen = (@height - len) / num
-
- @components.each() { |component|
- component.set_pos(x + component.padding, y + component.padding)
- if component.size then
- component.set_size(@width - component.padding*2, component.size - component.padding*2)
- y += component.size
- else
- component.set_size(@width - component.padding*2, avlen - component.padding*2)
- y += avlen
- end
- }
- elsif @type == :hbox
- avlen = (@width - len) / num
-
- @components.each() { |component|
- component.set_pos(x + component.padding, y + component.padding)
- if component.size then
- component.set_size(component.size - component.padding*2, @height - component.padding*2)
- x += component.size
- else
- component.set_size(avlen - component.padding*2, @height - component.padding*2)
- x += avlen
- end
- }
- else
- raise "LayoutBox: Unknown type #{type}"
- end
- end
- end
- ## EOF ##
|