From 7b8ebbc75177f389cadb3db6c37d16dfa9f7024d Mon Sep 17 00:00:00 2001 From: Paolo Capriotti Date: Sun, 21 Jun 2009 10:48:10 +0200 Subject: [PATCH] Reimplement click handling in scene. --- lib/board/board.rb | 56 ++++++++++-------------- lib/board/pool.rb | 94 ++++++++++++++++++++++------------------- lib/board/scene.rb | 21 +++++++++ lib/item.rb | 17 ++++++-- lib/mainwindow.rb | 5 ++- lib/themes/layouts/cool/cool.rb | 2 +- 6 files changed, 112 insertions(+), 83 deletions(-) rewrite lib/board/pool.rb (71%) create mode 100644 lib/board/scene.rb diff --git a/lib/board/board.rb b/lib/board/board.rb index 49621ab..0b5e0af 100644 --- a/lib/board/board.rb +++ b/lib/board/board.rb @@ -12,8 +12,9 @@ class Board < Qt::GraphicsItemGroup include Observable include PointConverter include ItemBag + include ItemUtils - attr_reader :scene, :items, :state, :unit, :theme + attr_reader :scene, :items, :state, :unit, :rect, :theme attr_accessor :movable square_tag :selection square_tag :last_move_src, :highlight @@ -22,6 +23,7 @@ class Board < Qt::GraphicsItemGroup def initialize(scene, theme, game, state, field) super(nil, scene) @scene = scene + @scene.add_element(self) @theme = theme @items = {} @@ -68,13 +70,14 @@ class Board < Qt::GraphicsItemGroup end def set_geometry(rect) + @rect = rect board = @state.board - side = [rect.width / board.size.x, rect.height / board.size.y].min.floor + side = [@rect.width / board.size.x, @rect.height / board.size.y].min.floor @unit = Qt::PointF.new(side, side) - base = Qt::PointF.new(((rect.width - side * board.size.x) / 2.0).to_i, - ((rect.height - side * board.size.y) / 2.0).to_i) + base = Qt::PointF.new(((@rect.width - side * board.size.x) / 2.0).to_i, + ((@rect.height - side * board.size.y) / 2.0).to_i) - self.pos = base + rect.top_left + self.pos = base + @rect.top_left redraw end @@ -85,36 +88,21 @@ class Board < Qt::GraphicsItemGroup add_item p, @theme.pieces.pixmap(piece, @unit), opts end - def create_item(key, pix, opts = {}) - name = opts[:name] || key.to_s - item = Item.new(name, pix, self, scene) - item.pos = opts[:pos] || Qt::PointF.new(0, 0) - item.z_value = opts[:z] || 0 - item.visible = false if opts[:hidden] - item - end - - def destroy_item(item) - scene.remove_item item - end - - def mousePressEvent(e) - if e.button == Qt::LeftButton - p = to_logical(e.pos) - - if selection - move = @game.policy.new_move(@state, selection, p) - validate = @game.validator.new(@state) - if validate[move] - perform! move - fire :new_move => { :move => move, :state => @state.dup } - end - - self.selection = nil - elsif @game.policy.movable?(@state, p) and - @movable[@state, p] - self.selection = p + def on_click(pos) + p = to_logical(pos) + + if selection + move = @game.policy.new_move(@state, selection, p) + validate = @game.validator.new(@state) + if validate[move] + perform! move + fire :new_move => { :move => move, :state => @state.dup } end + + self.selection = nil + elsif @game.policy.movable?(@state, p) and + @movable[@state, p] + self.selection = p end end diff --git a/lib/board/pool.rb b/lib/board/pool.rb dissimilarity index 71% index 7fa3ddd..40ccf75 100644 --- a/lib/board/pool.rb +++ b/lib/board/pool.rb @@ -1,43 +1,51 @@ -require 'item' - -class Pool < Qt::GraphicsItemGroup - BACKGROUND_ZVALUE = -10 - - include Observable - include ItemBag - - attr_reader :layout_item - attr_reader :items - - def initialize(scene, theme, game, pool, field) - super(nil, scene) - @scene = scene - @theme = theme - @game = game - @pool = pool - @field = field - - @items = {} - end - - def set_geometry(rect) - self.pos = rect.top_left -# unit = Qt::PointF.new(rect.width, rect.height) -# add_item :background, -# @theme.pieces.pixmap(@game.piece.new(:black, :promoted_rook), unit), -# :z => BACKGROUND_ZVALUE - end - - def create_item(key, pix, opts = {}) - name = opts[:name] || key.to_s - item = Item.new(name, pix, self, scene) - item.pos = opts[:pos] || Qt::PointF.new(0, 0) - item.z_value = opts[:z] || 0 - item.visible = false if opts[:hidden] - item - end - - def destroy_item(item) - scene.remove_item item - end -end +require 'item' + +class Pool < Qt::GraphicsItemGroup + BACKGROUND_ZVALUE = -10 + + include Observable + include ItemUtils + + attr_reader :rect + attr_reader :scene + + def initialize(scene, theme, game, field) + super(nil, scene) + @scene = scene + @scene.add_element(self) + + @theme = theme + @game = game + @field = field + + @items = [] + @size = Point.new(3, 5) + end + + def redraw + end + + def set_geometry(rect) + @rect = rect + + self.pos = @rect.top_left + + @unit = (@rect.width / @size.x).floor + redraw + end + + def add_piece(piece) + + end + + def to_logical(p) + end + + def to_real(index) + x = index % @size.x + y = index / @size.x + x = @size.x - x - 1 if y % 2 == 1 + + Qt::PointF.new(x * @unit, y * @unit) + end +end diff --git a/lib/board/scene.rb b/lib/board/scene.rb new file mode 100644 index 0000000..62065ce --- /dev/null +++ b/lib/board/scene.rb @@ -0,0 +1,21 @@ +class Scene < Qt::GraphicsScene + def initialize + super + + @elements = [] + end + + def add_element(element) + @elements << element + end + + def mousePressEvent(e) + if e.button == Qt::LeftButton + @elements.each do |element| + if element.rect.contains(e.scene_pos) + element.on_click(e.scene_pos - element.rect.top_left) + end + end + end + end +end diff --git a/lib/item.rb b/lib/item.rb index c90d92c..2393f28 100644 --- a/lib/item.rb +++ b/lib/item.rb @@ -21,8 +21,19 @@ class Item < Qt::GraphicsPixmapItem @opacity = value update end +end + +module ItemUtils + def create_item(key, pix, opts = {}) + name = opts[:name] || key.to_s + item = Item.new(name, pix, self, scene) + item.pos = opts[:pos] || Qt::PointF.new(0, 0) + item.z_value = opts[:z] || 0 + item.visible = false if opts[:hidden] + item + end - def remove - scene.remove_item self + def destroy_item(item) + scene.remove_item item end -end +end \ No newline at end of file diff --git a/lib/mainwindow.rb b/lib/mainwindow.rb index d8c374e..54b84e6 100644 --- a/lib/mainwindow.rb +++ b/lib/mainwindow.rb @@ -2,6 +2,7 @@ require 'qtutils' require 'board/board' require 'board/pool' require 'board/table' +require 'board/scene' require 'history' require 'controller' @@ -50,7 +51,7 @@ private theme.layout = @loader.get_matching(nil, game, ['layout'], game.keywords || []) - scene = Qt::GraphicsScene.new + scene = Scene.new state = game.state.new.tap {|s| s.setup } @@ -58,7 +59,7 @@ private @board = Board.new(scene, theme, game, state, field) if game.respond_to? :pool @pools = game.players.inject({}) do |res, player| - res[player] = Pool.new(scene, theme, game, state.pool(player), field) + res[player] = Pool.new(scene, theme, game, field) res end end diff --git a/lib/themes/layouts/cool/cool.rb b/lib/themes/layouts/cool/cool.rb index a6c5e96..209054d 100644 --- a/lib/themes/layouts/cool/cool.rb +++ b/lib/themes/layouts/cool/cool.rb @@ -46,4 +46,4 @@ class CoolLayout end end end -end \ No newline at end of file +end -- 2.11.4.GIT