Update connect/disconnect action states.
[kaya.git] / lib / board / pool.rb
blobaabbc0b027bd3c68c90806979c838ba2b7a5cbe7
1 # Copyright (c) 2009 Paolo Capriotti <p.capriotti@gmail.com>
2
3 # This program is free software; you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation; either version 2 of the License, or
6 # (at your option) any later version.
8 require 'item'
9 require 'board/redrawable'
11 class Pool < Qt::GraphicsItemGroup
12   BACKGROUND_ZVALUE = -10
13   
14   include Observable
15   include ItemUtils
16   include TaggableSquares
17   include Redrawable
18   
19   attr_reader :rect, :scene, :items, :theme
20   attr_reader :animator, :unit
21   square_tag :premove_src, :premove, :target => :extra
22   
23   def initialize(scene, theme, game)
24     super(nil, scene)
25     @scene = scene
26     @scene.add_clickable_element(self)
27     
28     @theme = theme
29     @game = game
30     
31     @items = []
32     @extra = ExtraItemContainer.new(self)
33     @size = Point.new(3, 5)
34     
35     @type_values = Hash.new(-1)
36     if @game.respond_to? :types
37       @game.types.each_with_index do |type, index|
38         @type_values[type] = index
39       end
40     end
41     
42     @animator = PoolAnimator.new(self)
43     @flipped = false
44   end
45   
46   def square_tag_container
47     @extra
48   end
49   
50   def flip(value)
51     @flipped = value
52   end
53   
54   def flipped?
55     @flipped
56   end
57   
58   def redraw
59     @items.each_with_index do |item, index|
60       item.reload(index)
61     end
62     
63     @extra.redraw
64   end
66   def set_geometry(rect)
67     @rect = rect
68     
69     self.pos = @rect.top_left.to_f
70     
71     side = (@rect.width / @size.x).floor
72     @unit = Qt::Point.new(side, side)
73     redraw
74   end
75   
76   def add_piece(index, piece, opts = {})
77     opts = opts.merge :name => piece,
78                       :reloader => piece_reloader(piece)
79     item = create_item(opts)
80     items.insert(index, item)
81     item.reload(index) if opts.fetch(:load, true)
82     item
83   end
84   
85   def remove_item(index, *args)
86     item = items.delete_at(index)
87     unless item.nil? or args.include?(:keep)
88       destroy_item item
89     end
90     item
91   end
92   
93   def on_click(pos)
94     
95   end
96   
97   def on_drag(pos)
98     index = to_logical(pos)
99     item = items[index]
100     if item
101       fire :drag => { :index => index,
102                       :item => item }
103     end
104   end
105   
106   def on_drop(old_pos, pos, data)
107     if data[:item]
108       fire :drop => data
109     end
110   end
111   
112   def to_logical(p)
113     y = p.y.to_f
114     if @flipped
115       y = rect.height - y
116     end
117     result = Point.new((p.x.to_f / @unit.x).floor,
118                        (y / @unit.y).floor)
119     y = result.y
120     x = y % 2 == 0 ? result.x : @size.x - result.x - 1
121     x + y * @size.x
122   end
123   
124   def to_real(index)
125     x = index % @size.x
126     y = index / @size.x
127     x = @size.x - x - 1 if y % 2 == 1
128     
129     rx = x * @unit.x
130     ry = if @flipped
131       rect.height - (y + 1) * @unit.y
132     else
133       y * @unit.y
134     end
135     
136     Qt::PointF.new(rx, ry)
137   end
138   
139   def compare(piece1, piece2)
140     [piece1.color.to_s, @type_values[piece1.type], piece1.type.to_s] <=>
141     [piece2.color.to_s, @type_values[piece2.type], piece2.type.to_s]
142   end
143   
144   class ExtraItemContainer
145     include ItemBag
146     include ItemUtils
147     
148     attr_reader :items
149     
150     def initialize(pool)
151       @pool = pool
152       @items = { }
153     end
154     
155     def redraw
156       @items.each do |key, item|
157         item.reload(key)
158       end
159     end
160     
161     def item_parent
162       @pool
163     end
164     
165     def scene
166       @pool.scene
167     end
168   end