Update connect/disconnect action states.
[kaya.git] / lib / board / board.rb
blob588ec252ceb27cc8f59e67e3cf5d0253cf0a894e
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 'board/square_tag.rb'
9 require 'observer'
10 require 'board/point_converter.rb'
11 require 'item'
12 require 'board/item_bag'
13 require 'board/redrawable'
15 class Board < Qt::GraphicsItemGroup
16   include TaggableSquares
17   include Observable
18   include PointConverter
19   include ItemBag
20   include ItemUtils
21   include Redrawable
22   
23   PREMOVE_ZVALUE = -2
24   SELECTION_ZVALUE = -1
26   attr_reader :scene, :items, :unit, :rect, :theme
27   square_tag :selection, :selection, :z => SELECTION_ZVALUE
28   square_tag :last_move_src, :highlight
29   square_tag :last_move_dst, :highlight
30   square_tag :premove_src, :premove, :z => PREMOVE_ZVALUE
31   square_tag :premove_dst, :premove, :z => PREMOVE_ZVALUE
33   def initialize(scene, theme, game)
34     super(nil, scene)
35     @scene = scene
36     @scene.add_clickable_element(self)
37     @theme = theme
38     @items = {}
39     
40     @game = game
41     
42     @flipped = false
43   end
44   
45   def flipped?
46     @flipped
47   end
48   
49   def flip(value)
50     @flipped = value
51   end
52   
53   def redraw
54     @items.each do |key, item|
55       item.reload(key)
56     end
57   end
58   
59   def reset(board = nil)
60     # create pieces
61     if board
62       board.to_enum(:each_square).map do |p|
63         add_piece(p, board[p], :load => false) if board[p]
64       end
65     end
66     
67     # create background item
68     add_item :background,
69              :reloader => background_reloader,
70              :z => BACKGROUND_ZVALUE
71              
72     redraw if @unit
73   end
74   
75   def set_geometry(rect)
76     @rect = rect
77     side = [@rect.width / @game.size.x, @rect.height / @game.size.y].min.floor
78     @unit = Qt::Point.new(side, side)
79     self.pos = @rect.top_left.to_f
80     redraw
81   end
82   
83   def add_piece(p, piece, opts = {})
84     opts = opts.merge :name => piece,
85                       :reloader => piece_reloader(piece)
86     item = add_item(p, opts)
87     item.reload(p) if opts.fetch(:load, true)
88     item
89   end
90   
91   def create_piece(piece, opts = {})
92     opts = opts.merge :name => piece,
93                       :reloader => piece_reloader(piece)
94     item = create_item(opts)
95     item.reload(Qt::PointF.new(0, 0))
96     item
97   end
98   
99   def on_click(pos)
100     p = to_logical(pos)
101     fire :click => p
102   end
103   
104   def on_drag(pos)
105     p = to_logical(pos)
106     item = items[p]
107     if item
108       fire :drag => { :src => p, 
109                       :item => item,
110                       :size => @unit }
111     end
112   end
113   
114   def on_drop(old_pos, pos, data)
115     if data[:item]
116       src = if old_pos
117         to_logical(old_pos)
118       end
119       dst = if pos
120         to_logical(pos)
121       end
122       fire :drop => data.merge(:src => src, :dst => dst)
123     end
124   end
125   
126   def highlight(move)
127     if move
128       self.last_move_src = move.src
129       self.last_move_dst = move.dst
130     else
131       self.last_move_src = nil
132       self.last_move_dst = nil
133     end
134   end
135   
136   def premove(src, dst)
137     self.premove_src = src
138     self.premove_dst = dst
139   end
140   
141   def cancel_premove
142     premove(nil, nil)
143   end