From: <umg...@us...> - 2006-12-01 15:21:25
|
Revision: 351 http://svn.sourceforge.net/pybridge/?rev=351&view=rev Author: umgangee Date: 2006-12-01 07:21:18 -0800 (Fri, 01 Dec 2006) Log Message: ----------- Changed play of cards by single-clicking to double-clicking, as a confirmation check. Modified Paths: -------------- trunk/pybridge/pybridge/ui/cardarea.py Modified: trunk/pybridge/pybridge/ui/cardarea.py =================================================================== --- trunk/pybridge/pybridge/ui/cardarea.py 2006-10-09 17:44:51 UTC (rev 350) +++ trunk/pybridge/pybridge/ui/cardarea.py 2006-12-01 15:21:18 UTC (rev 351) @@ -66,8 +66,8 @@ self.trick = None self.set_seat_mapping(Seat.South) - self.connect('button_release_event', self.button_release) - self.add_events(gtk.gdk.BUTTON_PRESS_MASK | gtk.gdk.BUTTON_RELEASE_MASK) + self.connect('button_press_event', self.button_press) + self.add_events(gtk.gdk.BUTTON_PRESS_MASK) def draw_card(self, context, pos_x, pos_y, card): @@ -270,8 +270,8 @@ def set_turn(self, turn): """Sets the turn indicator. - The turn indicator is displayed as a rounded rectangle around - the hand matching the specified seat. + The hand of the player on turn is drawn opaque; + the other hands are drawn translucent. @param turn: a member of Seat, or None. """ @@ -282,25 +282,10 @@ opacity = (seat is turn) and 1 or 0.5 self.update_item('hand-%s' % seat, opacity=opacity) -# # TODO: select colours that don't clash with the background. -# # TODO: one colour if user can play card from hand, another if not. -# width = self.hands[turn]['surface'].get_width() + 20 -# height = self.hands[turn]['surface'].get_height() + 20 -# surface, context = self.new_surface(width, height) -# context.set_source_rgb(0.3, 0.6, 0) # Green. -# context.paint_with_alpha(0.5) -# -# xy = self.items['hand-%s' % turn]['xy'] # Use same xy as hand. -# -# if id in self.items: -# self.update_item(id, source=surface, xy=xy) -# else: -# self.add_item(id, surface, xy, -1) - - def button_release(self, widget, event): + def button_press(self, widget, event): """Determines if a card was clicked: if so, calls card_selected.""" - if event.button == 1: + if event.button == 1 and event.type == gtk.gdk._2BUTTON_PRESS: found_hand = False # Determine the hand which was clicked. This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <umg...@us...> - 2007-04-01 17:39:18
|
Revision: 381 http://svn.sourceforge.net/pybridge/?rev=381&view=rev Author: umgangee Date: 2007-04-01 10:39:19 -0700 (Sun, 01 Apr 2007) Log Message: ----------- Change Player references to Direction type. Modified Paths: -------------- trunk/pybridge/pybridge/ui/cardarea.py Modified: trunk/pybridge/pybridge/ui/cardarea.py =================================================================== --- trunk/pybridge/pybridge/ui/cardarea.py 2007-04-01 17:37:24 UTC (rev 380) +++ trunk/pybridge/pybridge/ui/cardarea.py 2007-04-01 17:39:19 UTC (rev 381) @@ -25,7 +25,7 @@ from canvas import CairoCanvas from pybridge.bridge.card import Card -from pybridge.bridge.symbols import Player, Rank, Suit +from pybridge.bridge.symbols import Direction, Rank, Suit # The order in which card graphics are expected in card mask. CARD_MASK_RANKS = [Rank.Ace, Rank.Two, Rank.Three, Rank.Four, Rank.Five, @@ -64,7 +64,7 @@ self.hands = {} self.trick = None - self.set_player_mapping(Player.South) + self.set_player_mapping(Direction.South) self.connect('button_press_event', self.button_press) self.add_events(gtk.gdk.BUTTON_PRESS_MASK) @@ -98,7 +98,7 @@ infrequently and multiple calls to draw_card() are expensive. @param hand: a list of Card objects. - @param player: a member of Player. + @param player: a member of Direction. @param facedown: if True, cards are drawn face-down. @param omit: a list of elements of hand not to draw. """ @@ -218,13 +218,13 @@ self.add_item(id, surface, xy[player], 2) - def set_player_mapping(self, focus=Player.South): + def set_player_mapping(self, focus=Direction.South): """Sets the mapping between players at table and positions of hands. - @param focus: the Player to be drawn "closest" to the observer. + @param focus: the Direction to be drawn "closest" to the observer. """ - # Assumes Player elements are ordered clockwise from North. - order = Player[focus.index:] + Player[:focus.index] + # Assumes Direction elements are ordered clockwise from North. + order = Direction[focus.index:] + Direction[:focus.index] for player, attr in zip(order, ('BOTTOM', 'LEFT', 'TOP', 'RIGHT')): setattr(self, attr, player) # TODO: set player labels. @@ -240,9 +240,9 @@ self.LEFT : (0.425, 0.5), self.RIGHT : (0.575, 0.5), } if trick: - # The order of play is the leader, then clockwise around Player. + # The order of play is the leader, then clockwise around Direction. leader = trick[0] - order = Player[leader.index:] + Player[:leader.index] + order = Direction[leader.index:] + Direction[:leader.index] for i, player in enumerate(order): id = 'trick-%s' % player old_card = self.trick and self.trick[1].get(player) or None @@ -272,14 +272,15 @@ The hand of the player on turn is drawn opaque; the other hands are drawn translucent. - @param turn: a member of Player, or None. + @param turn: the position of the turn indicator. + @type turn: Direction or None """ if turn is None: return - for player in Player: - opacity = (player is turn) and 1 or 0.5 - self.update_item('hand-%s' % player, opacity=opacity) + for position in Direction: + opacity = (position is turn) and 1 or 0.5 + self.update_item('hand-%s' % position, opacity=opacity) def button_press(self, widget, event): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <umg...@us...> - 2007-04-07 20:56:12
|
Revision: 407 http://svn.sourceforge.net/pybridge/?rev=407&view=rev Author: umgangee Date: 2007-04-07 13:56:08 -0700 (Sat, 07 Apr 2007) Log Message: ----------- Show position title in player name labels, change "is" to "==" for comparison with elements of Direction. Modified Paths: -------------- trunk/pybridge/pybridge/ui/cardarea.py Modified: trunk/pybridge/pybridge/ui/cardarea.py =================================================================== --- trunk/pybridge/pybridge/ui/cardarea.py 2007-04-06 20:07:59 UTC (rev 406) +++ trunk/pybridge/pybridge/ui/cardarea.py 2007-04-07 20:56:08 UTC (rev 407) @@ -36,19 +36,22 @@ # The red-black-red-black ordering convention. RED_BLACK = [Suit.Diamond, Suit.Club, Suit.Heart, Suit.Spade] +DIRECTION_SYMBOLS = {Direction.North : _('North'), Direction.East : _('East'), + Direction.South : _('South'), Direction.West : _('West') } + class CardArea(CairoCanvas): - """This widget. - - This widget uses Cairo and requires >= GTK 2.8. + """This widget displays a graphical view of card hands and tricks. + + Requirements: Cairo (>=1.0), PyGTK (>= 2.8). """ # Load card mask. card_mask_path = env.find_pixmap('bonded.png') card_mask = cairo.ImageSurface.create_from_png(card_mask_path) - + font_description = pango.FontDescription('Sans Bold 10') - + border_x = border_y = 10 card_width = card_mask.get_width() / 13 card_height = card_mask.get_height() / 5 @@ -58,14 +61,14 @@ def __init__(self): super(CardArea, self).__init__() # Initialise parent. - + # To receive card clicked events, override this with external method. self.on_card_clicked = lambda card, player: True - + self.hands = {} self.trick = None self.set_player_mapping(Direction.South) - + self.connect('button_press_event', self.button_press) self.add_events(gtk.gdk.BUTTON_PRESS_MASK) @@ -83,7 +86,7 @@ src_y = CARD_MASK_SUITS.index(card.suit) * self.card_height else: # Draw a face-down card. src_x, src_y = self.card_width*2, self.card_height*4 - + context.rectangle(pos_x, pos_y, self.card_width, self.card_height) context.clip() context.set_source_surface(self.card_mask, pos_x-src_x, pos_y-src_y) @@ -102,7 +105,7 @@ @param facedown: if True, cards are drawn face-down. @param omit: a list of elements of hand not to draw. """ - + # TODO: coords should be dict (card : (pos_x, pos_y)), but this breaks when hashing. def get_coords_for_hand(): coords = [] @@ -123,19 +126,19 @@ else: # LEFT or RIGHT. if facedown is True: # Wrap cards to a 4x4 grid. for index, card in enumerate(hand): - adjust = player is self.RIGHT and index == 12 and 3 + adjust = player == self.RIGHT and index == 12 and 3 pos_x = ((index % 4) + adjust) * self.spacing_x pos_y = (index / 4) * self.spacing_y coords.append((card, pos_x, pos_y)) else: longest = max([len(cards) for cards in suits.values()]) for index, card in enumerate(hand): - adjust = player is self.RIGHT and longest - len(suits[card.suit]) + adjust = player == self.RIGHT and longest - len(suits[card.suit]) pos_x = (suits[card.suit].index(card) + adjust) * self.spacing_x pos_y = RED_BLACK.index(card.suit) * self.spacing_y coords.append((card, pos_x, pos_y)) return coords - + if facedown is False: # Split hand into suits. suits = dict([(suit, []) for suit in Suit]) @@ -148,29 +151,29 @@ hand = [] for suit in RED_BLACK: hand.extend(suits[suit]) - + saved = self.hands.get(player) if saved and saved['hand'] == hand: # If hand has been set previously, do not recalculate coords. coords = saved['coords'] else: coords = get_coords_for_hand() - + # Determine dimensions of hand. width = max([x for card, x, y in coords]) + self.card_width height = max([y for card, x, y in coords]) + self.card_height surface, context = self.new_surface(width, height) - + # Draw cards to surface. visible = [(i, card) for i, card in enumerate(hand) if card not in omit] for i, card in visible: pos_x, pos_y = coords[i][1:] self.draw_card(context, pos_x, pos_y, card) - + # Save self.hands[player] = {'hand' : hand, 'visible' : visible, 'surface' : surface, 'coords' : coords, } - + id = 'hand-%s' % player # Identifier for this item. if id in self.items: self.update_item(id, source=surface) @@ -180,25 +183,26 @@ self.add_item(id, surface, xy[player], 0) - def set_player_name(self, player, name=None): + def set_player_name(self, position, name=None): """ + @param position: the position of the player. @param name: the name of the player, or None. """ - id = 'player-%s' % player + id = 'player-%s' % position if name is None or id in self.items: self.remove_item(id) return - + layout = pango.Layout(self.create_pango_context()) layout.set_font_description(self.font_description) - layout.set_text(name) + layout.set_text('%s: %s' % (DIRECTION_SYMBOLS[position], name)) # Create an ImageSurface respective to dimensions of text. width, height = layout.get_pixel_size() width += 8; height += 4 surface, context = self.new_surface(width, height) context = pangocairo.CairoContext(context) - + # Draw background box, text to ImageSurface. context.set_line_width(4) context.rectangle(0, 0, width, height) @@ -209,19 +213,19 @@ context.move_to(4, 2) context.set_source_rgb(1, 1, 1) context.show_layout(layout) - + if id in self.items: self.update_item(id, source=surface) else: - xy = {self.TOP : (0.5, 0.15), self.BOTTOM : (0.5, 0.85), - self.LEFT : (0.15, 0.6), self.RIGHT : (0.85, 0.6), } - self.add_item(id, surface, xy[player], 2) + xy = {self.TOP : (0.5, 0.2), self.BOTTOM : (0.5, 0.9), + self.LEFT : (0.125, 0.625), self.RIGHT : (0.875, 0.625), } + self.add_item(id, surface, xy[position], 2) def set_player_mapping(self, focus=Direction.South): """Sets the mapping between players at table and positions of hands. - @param focus: the Direction to be drawn "closest" to the observer. + @param focus: the position to be drawn "closest" to the observer. """ # Assumes Direction elements are ordered clockwise from North. order = Direction[focus.index:] + Direction[:focus.index] @@ -238,7 +242,7 @@ """ xy = {self.TOP : (0.5, 0.425), self.BOTTOM : (0.5, 0.575), self.LEFT : (0.425, 0.5), self.RIGHT : (0.575, 0.5), } - + if trick: # The order of play is the leader, then clockwise around Direction. leader = trick[0] @@ -258,11 +262,11 @@ surface, context = self.new_surface(self.card_width, self.card_height) self.draw_card(context, 0, 0, new_card) self.update_item(id, surface, z_index=i+1) - + elif self.trick: # Remove all cards from previous trick. for player in self.trick[1]: self.remove_item('trick-%s' % player) - + self.trick = trick # Save trick and return. @@ -271,13 +275,13 @@ The hand of the player on turn is drawn opaque; the other hands are drawn translucent. - + @param turn: the position of the turn indicator. @type turn: Direction or None """ if turn is None: return - + for position in Direction: opacity = (position is turn) and 1 or 0.5 self.update_item('hand-%s' % position, opacity=opacity) @@ -287,7 +291,7 @@ """Determines if a card was clicked: if so, calls card_selected.""" if event.button == 1 and event.type == gtk.gdk._2BUTTON_PRESS: found_hand = False - + # Determine the hand which was clicked. for player in self.hands: card_coords = self.hands[player]['coords'] @@ -297,7 +301,7 @@ (hand_y <= event.y <= hand_y + surface.get_height()): found_hand = True break - + if found_hand: # Determine the card in hand which was clicked. pos_x, pos_y = event.x - hand_x, event.y - hand_y @@ -308,6 +312,6 @@ (y <= pos_y <= y + self.card_height): self.on_card_clicked(card, player) break - + return True # Expected to return True. This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <umg...@us...> - 2007-04-09 15:33:31
|
Revision: 411 http://svn.sourceforge.net/pybridge/?rev=411&view=rev Author: umgangee Date: 2007-04-09 08:33:32 -0700 (Mon, 09 Apr 2007) Log Message: ----------- Use a dict to store card coords. Add hand-click event. Disable turn notifier for now. Modified Paths: -------------- trunk/pybridge/pybridge/ui/cardarea.py Modified: trunk/pybridge/pybridge/ui/cardarea.py =================================================================== --- trunk/pybridge/pybridge/ui/cardarea.py 2007-04-09 15:31:52 UTC (rev 410) +++ trunk/pybridge/pybridge/ui/cardarea.py 2007-04-09 15:33:32 UTC (rev 411) @@ -62,11 +62,13 @@ def __init__(self): super(CardArea, self).__init__() # Initialise parent. - # To receive card clicked events, override this with external method. - self.on_card_clicked = lambda card, player: True + # To receive these events, override with external method. + self.on_card_clicked = lambda card, position: True + self.on_hand_clicked = lambda position: True self.hands = {} self.trick = None + self.players = {} self.set_player_mapping(Direction.South) self.connect('button_press_event', self.button_press) @@ -106,15 +108,14 @@ @param omit: a list of elements of hand not to draw. """ - # TODO: coords should be dict (card : (pos_x, pos_y)), but this breaks when hashing. def get_coords_for_hand(): - coords = [] + coords = {} if player in (self.TOP, self.BOTTOM): pos_y = 0 if facedown is True: # Draw cards in one continuous row. for index, card in enumerate(hand): pos_x = index * self.spacing_x - coords.append((card, pos_x, pos_y)) + coords[card] = (pos_x, pos_y) else: # Insert a space between each suit. spaces = len([1 for suitcards in suits.values() if len(suitcards) > 0]) - 1 for index, card in enumerate(hand): @@ -122,21 +123,21 @@ insert = len([1 for suit, suitcards in suits.items() if len(suitcards) > 0 and RED_BLACK.index(card.suit) > RED_BLACK.index(suit)]) pos_x = (index + insert) * self.spacing_x - coords.append((card, pos_x, pos_y)) + coords[card] = (pos_x, pos_y) else: # LEFT or RIGHT. if facedown is True: # Wrap cards to a 4x4 grid. for index, card in enumerate(hand): adjust = player == self.RIGHT and index == 12 and 3 pos_x = ((index % 4) + adjust) * self.spacing_x pos_y = (index / 4) * self.spacing_y - coords.append((card, pos_x, pos_y)) + coords[card] = (pos_x, pos_y) else: longest = max([len(cards) for cards in suits.values()]) for index, card in enumerate(hand): adjust = player == self.RIGHT and longest - len(suits[card.suit]) pos_x = (suits[card.suit].index(card) + adjust) * self.spacing_x pos_y = RED_BLACK.index(card.suit) * self.spacing_y - coords.append((card, pos_x, pos_y)) + coords[card] = (pos_x, pos_y) return coords if facedown is False: @@ -160,14 +161,14 @@ coords = get_coords_for_hand() # Determine dimensions of hand. - width = max([x for card, x, y in coords]) + self.card_width - height = max([y for card, x, y in coords]) + self.card_height + width = max([x for x, y in coords.values()]) + self.card_width + height = max([y for x, y in coords.values()]) + self.card_height surface, context = self.new_surface(width, height) # Draw cards to surface. visible = [(i, card) for i, card in enumerate(hand) if card not in omit] for i, card in visible: - pos_x, pos_y = coords[i][1:] + pos_x, pos_y = coords[card] self.draw_card(context, pos_x, pos_y, card) # Save @@ -189,14 +190,21 @@ @param position: the position of the player. @param name: the name of the player, or None. """ + self.players[position] = None + + # If no name specified, show hand at position as translucent. + opacity = (name is None) and 0.5 or 1 + self.update_item('hand-%s' % position, opacity=opacity) + id = 'player-%s' % position - if name is None or id in self.items: - self.remove_item(id) - return layout = pango.Layout(self.create_pango_context()) layout.set_font_description(self.font_description) - layout.set_text('%s: %s' % (DIRECTION_SYMBOLS[position], name)) + if name is None: + layout.set_text('%s' % DIRECTION_SYMBOLS[position]) + else: + layout.set_text('%s: %s' % (DIRECTION_SYMBOLS[position], name)) + # Create an ImageSurface respective to dimensions of text. width, height = layout.get_pixel_size() width += 8; height += 4 @@ -270,47 +278,32 @@ self.trick = trick # Save trick and return. - def set_turn(self, turn): - """Sets the turn indicator. - - The hand of the player on turn is drawn opaque; - the other hands are drawn translucent. - - @param turn: the position of the turn indicator. - @type turn: Direction or None - """ - if turn is None: - return - - for position in Direction: - opacity = (position is turn) and 1 or 0.5 - self.update_item('hand-%s' % position, opacity=opacity) - - def button_press(self, widget, event): - """Determines if a card was clicked: if so, calls card_selected.""" + """Determines if a card was clicked: if so, calls on_card_selected.""" if event.button == 1 and event.type == gtk.gdk._2BUTTON_PRESS: found_hand = False # Determine the hand which was clicked. - for player in self.hands: - card_coords = self.hands[player]['coords'] - surface = self.hands[player]['surface'] - hand_x, hand_y = self.items['hand-%s' % player]['area'][0:2] + for position in self.hands: + card_coords = self.hands[position]['coords'] + surface = self.hands[position]['surface'] + hand_x, hand_y = self.items['hand-%s' % position]['area'][0:2] if (hand_x <= event.x <= hand_x + surface.get_width()) and \ (hand_y <= event.y <= hand_y + surface.get_height()): found_hand = True break if found_hand: + self.on_hand_clicked(position) + # Determine the card in hand which was clicked. pos_x, pos_y = event.x - hand_x, event.y - hand_y # Iterate through visible cards backwards. - for i, card in self.hands[player]['visible'][::-1]: - x, y = card_coords[i][1:] + for i, card in self.hands[position]['visible'][::-1]: + x, y = card_coords[card] if (x <= pos_x <= x + self.card_width) and \ (y <= pos_y <= y + self.card_height): - self.on_card_clicked(card, player) + self.on_card_clicked(card, position) break return True # Expected to return True. This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |