diff options
author | Walter Bender <walter.bender@gmail.com> | 2012-04-04 15:51:05 (GMT) |
---|---|---|
committer | Walter Bender <walter.bender@gmail.com> | 2012-04-04 15:51:05 (GMT) |
commit | a5699078a4308510670dd94960633925cce6eb7e (patch) | |
tree | 8c9a6bf86e8d285cf5298af1dae9100919f34c74 | |
parent | 3b7958ea6f7474a1606ff916034b592cce2b16e4 (diff) |
enable dragging
-rw-r--r-- | game.py | 45 | ||||
-rw-r--r-- | sprites.py | 22 |
2 files changed, 54 insertions, 13 deletions
@@ -45,14 +45,22 @@ class Game(): self._parent = parent self._canvas.set_flags(gtk.CAN_FOCUS) - self._canvas.add_events(gtk.gdk.BUTTON_PRESS_MASK) self._canvas.connect("expose-event", self._expose_cb) + self._canvas.add_events(gtk.gdk.BUTTON_PRESS_MASK) self._canvas.connect("button-press-event", self._button_press_cb) + self._canvas.add_events(gtk.gdk.BUTTON_RELEASE_MASK) + self._canvas.connect('button-release-event', self._button_release_cb) + self._canvas.add_events(gtk.gdk.POINTER_MOTION_MASK) + self._canvas.connect("motion-notify-event", self._mouse_move_cb) self._width = gtk.gdk.screen_width() self._height = gtk.gdk.screen_height() - GRID_CELL_SIZE self._scale = self._width / 1200. + self.press = None + self.dragpos = [0, 0] + self.startpos = [0, 0] + self._dot_cache = {} self._xo_cache = {} @@ -139,17 +147,35 @@ class Game(): def _button_press_cb(self, win, event): win.grab_focus() x, y = map(int, event.get_coords()) + self.dragpos = [x, y] spr = self._sprites.find_sprite((x, y)) + self.startpos = spr.get_xy() + self.press = spr if spr == None: return - if type(spr.type) == int: - self.i = spr.type - _logger.debug('%d' % (self.i)) - self._new_surface() - else: - _logger.debug(type(spr.type)) + def _mouse_move_cb(self, win, event): + """ Drag a rule with the mouse. """ + if self.press is None: + self.dragpos = [0, 0] + return True + win.grab_focus() + x, y = map(int, event.get_coords()) + dx = x - self.dragpos[0] + dy = y - self.dragpos[1] + self.press.move_relative((dx, dy)) + self.dragpos = [x, y] + + def _button_release_cb(self, win, event): + if self.press == None: + return True + if _distance(self.press.get_xy(), self.startpos) < 20: + if type(self.press.type) == int: + self.i = self.press.type + self._new_surface() + self.press.move(self.startpos) + self.press = None def _new_surface(self): self.colors[0] = colors[self.i][0] @@ -342,3 +368,8 @@ def _zone(dv, dh): if dv > 48: zone += 1 return zone + + +def _distance(pos1, pos2): + return sqrt((pos1[0] - pos2[0]) * (pos1[0] - pos2[0]) + \ + (pos1[1] - pos2[1]) * (pos1[1] - pos2[1])) @@ -120,18 +120,22 @@ class Sprites: else: self.list.insert(i, spr) + def find_in_list(self, spr): + if spr in self.list: + return True + return False + def remove_from_list(self, spr): ''' Remove a sprite from the list. ''' if spr in self.list: self.list.remove(spr) - def find_sprite(self, pos, inverse=False): + def find_sprite(self, pos, region=False): ''' Search based on (x, y) position. Return the 'top/first' one. ''' list = self.list[:] - if not inverse: - list.reverse() + list.reverse() for spr in list: - if spr.hit(pos): + if spr.hit(pos, readpixel=not region): return spr return None @@ -346,7 +350,7 @@ class Sprite: if len(self.labels) > 0: self.draw_label(cr) - def hit(self, pos): + def hit(self, pos, readpixel=False): ''' Is (x, y) on top of the sprite? ''' x, y = pos if x < self.rect.x: @@ -357,7 +361,13 @@ class Sprite: return False if y > self.rect.y + self.rect.height: return False - return True + if readpixel: + r, g, b, a = self.get_pixel(pos) + if r == g == b == a == 0: + return False + if a == -1: + return False + return self._sprites.find_in_list(self) def draw_label(self, cr): ''' Draw the label based on its attributes ''' |