# HG changeset patch # User Goffi # Date 1305763259 -7200 # Node ID 7bea2ae0c4fb1ede66e50bf0b2fa9d56757686bd # Parent b306aa090438ed44f1e95f8fb184839aac9ba835 Tarot game: center_panel layout + chien can now be showed + fixed click event inheritance + card selection first draft diff -r b306aa090438 -r 7bea2ae0c4fb browser_side/card_game.py --- a/browser_side/card_game.py Wed May 18 01:45:28 2011 +0200 +++ b/browser_side/card_game.py Thu May 19 02:00:59 2011 +0200 @@ -24,12 +24,17 @@ from pyjamas.ui.VerticalPanel import VerticalPanel from pyjamas.ui.HorizontalPanel import HorizontalPanel from pyjamas.ui.DockPanel import DockPanel +from pyjamas.ui.SimplePanel import SimplePanel from pyjamas.ui.DialogBox import DialogBox from pyjamas.ui.ListBox import ListBox from pyjamas.ui.Image import Image from pyjamas.ui.Label import Label from pyjamas.ui.Button import Button +from pyjamas.ui.ClickListener import ClickHandler +from pyjamas.ui.MouseListener import MouseHandler from pyjamas.ui import HasAlignment +from pyjamas import Window +from pyjamas import DOM from pyjamas.dnd import makeDraggable from pyjamas.ui.DragWidget import DragWidget, DragContainer @@ -43,6 +48,7 @@ CARD_WIDTH = 74 CARD_HEIGHT = 136 +CARD_DELTA_Y = 10 MIN_WIDTH = 950 #Minimum size of the panel MIN_HEIGHT = 500 @@ -76,28 +82,31 @@ self.hide() self._parent.contratSelected(self.contrats_list.getSelectedItemText()[0]) -class CardWidget(TarotCard, Image): +class CardWidget(TarotCard, Image, MouseHandler): """This class is used to represent a card, graphically and logically""" - def __init__(self, file): + def __init__(self, parent, file): """@param file: path of the PNG file""" + self._parent = parent Image.__init__(self,file) root_name = file[file.rfind("/")+1:-4] suit,value = root_name.split('_') TarotCard.__init__(self, (suit, value)) - print "Carte:",suit, value #, self.bout + MouseHandler.__init__(self) + self.addMouseListener(self) - def draw(self, dc, x, y): - """Draw the card on the device context - @param dc: device context - @param x: abscissa - @param y: ordinate""" - pass - #dc.DrawBitmap(self.bitmap, x, y, True) + def onMouseEnter(self, sender): + if self._parent.state == "ecart": + DOM.setStyleAttribute(self.getElement(), "top", "0px") -class CardPanel(DockPanel): + def onMouseLeave(self, sender): + DOM.setStyleAttribute(self.getElement(), "top", "%dpx" % CARD_DELTA_Y) + +class CardPanel(DockPanel, ClickHandler): def __init__(self, parent, referee, players, player_nick): + DockPanel.__init__(self) + ClickHandler.__init__(self) self._parent = parent self._autoplay = None #XXX: use 0 to activate fake play, None else self.referee = referee @@ -120,16 +129,17 @@ self.hand = [] self.to_show = [] self.state = None - DockPanel.__init__(self) - self.setSize("%spx" % MIN_WIDTH, "%spx" % MIN_HEIGHT) + self.setSize("%dpx" % MIN_WIDTH, "%dpx" % MIN_HEIGHT) self.setStyleName("cardPanel") + # Now we set up the layout _label = Label(self.top_nick) _label.setStyleName('cardGamePlayerNick') self.add(_label, DockPanel.NORTH) self.setCellWidth(_label, '100%') self.setCellHorizontalAlignment(_label, HasAlignment.ALIGN_CENTER) + self.hand_panel = AbsolutePanel() self.add(self.hand_panel, DockPanel.SOUTH) self.setCellWidth(self.hand_panel, '100%') @@ -142,6 +152,7 @@ self.setCellHeight(_label, '100%') self.setCellVerticalAlignment(_label, HasAlignment.ALIGN_MIDDLE) + _label = Label(self.right_nick) _label.setStyleName('cardGamePlayerNick') self.add(_label, DockPanel.EAST) @@ -149,9 +160,41 @@ self.setCellHorizontalAlignment(_label, HasAlignment.ALIGN_RIGHT) self.setCellVerticalAlignment(_label, HasAlignment.ALIGN_MIDDLE) + self.center_panel = DockPanel() + self.inner_left = SimplePanel() + self.center_panel.add(self.inner_left, DockPanel.WEST) + self.center_panel.setCellHeight(self.inner_left, '100%') + self.center_panel.setCellHorizontalAlignment(self.inner_left, HasAlignment.ALIGN_RIGHT) + self.center_panel.setCellVerticalAlignment(self.inner_left, HasAlignment.ALIGN_MIDDLE) + + self.inner_right = SimplePanel() + self.center_panel.add(self.inner_right, DockPanel.EAST) + self.center_panel.setCellHeight(self.inner_right, '100%') + self.center_panel.setCellVerticalAlignment(self.inner_right, HasAlignment.ALIGN_MIDDLE) + + self.inner_top = SimplePanel() + self.center_panel.add(self.inner_top, DockPanel.NORTH) + self.center_panel.setCellWidth(self.inner_top, '100%') + self.center_panel.setCellHorizontalAlignment(self.inner_top, HasAlignment.ALIGN_CENTER) + self.center_panel.setCellVerticalAlignment(self.inner_top, HasAlignment.ALIGN_BOTTOM) + + self.inner_bottom = SimplePanel() + self.center_panel.add(self.inner_bottom, DockPanel.SOUTH) + self.center_panel.setCellWidth(self.inner_bottom, '100%') + self.center_panel.setCellHorizontalAlignment(self.inner_bottom, HasAlignment.ALIGN_CENTER) + self.center_panel.setCellVerticalAlignment(self.inner_bottom, HasAlignment.ALIGN_TOP) + + self.inner_center = SimplePanel() + self.center_panel.add(self.inner_center, DockPanel.CENTER) + self.center_panel.setCellHorizontalAlignment(self.inner_center, HasAlignment.ALIGN_CENTER) + self.center_panel.setCellVerticalAlignment(self.inner_center, HasAlignment.ALIGN_MIDDLE) + self.add(self.center_panel, DockPanel.CENTER) self.setCellWidth(self.center_panel, '100%') + self.setCellHeight(self.center_panel, '100%') + self.setCellVerticalAlignment(self.center_panel, HasAlignment.ALIGN_MIDDLE) + self.setCellHorizontalAlignment(self.center_panel, HasAlignment.ALIGN_CENTER) """for side in zip(['left', 'top', 'right'], @@ -163,6 +206,7 @@ self.loadCards() self.mouse_over_card = None #contain the card to highlight self.visible_size = CARD_WIDTH/2 #number of pixels visible for cards + self.addClickListener(self) def loadCards(self, dir): @@ -170,7 +214,7 @@ @param dir: directory where the PNG files are""" def _getTarotCardsPathsCb(paths): for file in paths: - card = CardWidget(file) + card = CardWidget(self, file) self.cards[(card.suit, card.value)]=card self.deck.append(card) self._parent.host.bridge.call('tarotGameReady', None, self.player_nick, self.referee) @@ -183,6 +227,19 @@ self.cards["trefle"]={} #club self._parent.host.bridge.call('getTarotCardsPaths', _getTarotCardsPathsCb) + def onClick(self, sender): + if self.state == "chien": + self.to_show = [] + self.state = "wait" + self.updateToShow() + elif self.state == "wait_for_ecart": + self.state = "ecart" + self.hand.extend(self.to_show) + self.hand.sort() + self.to_show = [] + self.updateToShow() + self.updateHand() + def tarotGameNew(self, hand): """Start a new game, with given hand""" for suit, value in hand: @@ -194,13 +251,30 @@ def updateHand(self): """Show the cards in the hand in the hand_panel (SOUTH panel)""" self.hand_panel.clear() - self.hand_panel.setSize("%spx" % (self.visible_size * (len(self.hand)+1)), "%spx" % (CARD_HEIGHT + 10)) + self.hand_panel.setSize("%dpx" % (self.visible_size * (len(self.hand)+1)), "%dpx" % (CARD_HEIGHT + CARD_DELTA_Y + 10)) x_pos = 0 - y_pos = 0 + y_pos = CARD_DELTA_Y for card in self.hand: self.hand_panel.add(card, x_pos, y_pos) x_pos+=self.visible_size - + + def updateToShow(self): + """Show cards in the center panel""" + if not self.to_show: + _widget = self.inner_center.getWidget() + if _widget: + self.inner_center.remove(_widget) + return + panel = AbsolutePanel() + panel.setSize("%dpx" % ((CARD_WIDTH + 5) * len(self.to_show) - 5), "%dpx" % (CARD_HEIGHT)) + x_pos = 0 + y_pos = 0 + for card in self.to_show: + panel.add(card, x_pos, y_pos) + x_pos+=CARD_WIDTH + 5 + self.inner_center.setWidget(panel) + + def tarotGameChooseContrat(self, xml_data): """Called when the player as to select his contrat @param xml_data: SàT xml representation of the form""" @@ -213,5 +287,18 @@ """Must be called when the contrat is selected @param contrat: one of the valid contrat value""" print "Contrat choosed:", contrat - self._parent.host.bridge.call('tarotGameContratChoosed', None, self.player_nick, self.referee, contrat or 'Passe') #FIXME: must use roomID ! cf quick_card_game for same issue + self._parent.host.bridge.call('tarotGameContratChoosed', None, self.player_nick, self.referee, contrat or 'Passe') + + + def tarotGameShowCards(self, game_stage, cards, data): + """Display cards in the middle of the game (to show for e.g. chien ou poignée)""" + self.to_show = [] + for suit, value in cards: + self.to_show.append(self.cards[(suit, value)]) + self.updateToShow() + if game_stage == "chien" and data['attaquant'] == self.player_nick: + self.state = "wait_for_ecart" + else: + self.state = "chien" + diff -r b306aa090438 -r 7bea2ae0c4fb browser_side/panels.py --- a/browser_side/panels.py Wed May 18 01:45:28 2011 +0200 +++ b/browser_side/panels.py Thu May 19 02:00:59 2011 +0200 @@ -495,6 +495,16 @@ self.setStyleName('chatPanel') self.addClickListener(self) + def doDetachChildren(self): + #We need to force the use of a panel subclass method here, + #for the same reason as doAttachChildren + ScrollPanelWrapper.doDetachChildren(self) + + def doAttachChildren(self): + #We need to force the use of a panel subclass method here, else + #the event will not propagate to children + ScrollPanelWrapper.doAttachChildren(self) + def onClick(self, sender, event): self.host.select(self) diff -r b306aa090438 -r 7bea2ae0c4fb libervia.py --- a/libervia.py Wed May 18 01:45:28 2011 +0200 +++ b/libervia.py Thu May 19 02:00:59 2011 +0200 @@ -109,6 +109,8 @@ def select(self, widget): """Define the selected widget""" if self.selected: + if self.selected == widget: + return self.selected.removeStyleName('selected_widget') self.selected = widget if widget: @@ -170,7 +172,8 @@ elif name == 'tarotGameStarted': self._tarotGameStartedCb(*args) elif name == 'tarotGameNew' or \ - name == 'tarotGameChooseContrat': + name == 'tarotGameChooseContrat' or \ + name == 'tarotGameShowCards': self._tarotGameGenericCb(name, args[0], args[1:]) def _getProfileJidCB(self, jid): diff -r b306aa090438 -r 7bea2ae0c4fb libervia.tac --- a/libervia.tac Wed May 18 01:45:28 2011 +0200 +++ b/libervia.tac Thu May 19 02:00:59 2011 +0200 @@ -362,7 +362,7 @@ self.bridge.register("connected", self.signal_handler.connected) self.bridge.register("connectionError", self.signal_handler.connectionError) for signal_name in ['presenceUpdate', 'personalEvent', 'newMessage', 'roomJoined', 'roomUserJoined', 'roomUserLeft', 'tarotGameStarted', 'tarotGameNew', - 'tarotGameChooseContrat']: + 'tarotGameChooseContrat', 'tarotGameShowCards']: self.bridge.register(signal_name, self.signal_handler.getGenericCb(signal_name)) root.putChild('json_signal_api', self.signal_handler) root.putChild('json_api', MethodHandler(self))