changeset 37:b306aa090438

Tarot game: game launching (first hand showed), and contract selection
author Goffi <goffi@goffi.org>
date Wed, 18 May 2011 01:45:28 +0200
parents 1d406077b49b
children 7bea2ae0c4fb
files browser_side/card_game.py browser_side/panels.py libervia.py libervia.tac public/libervia.css
diffstat 5 files changed, 145 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/browser_side/card_game.py	Tue May 17 01:33:12 2011 +0200
+++ b/browser_side/card_game.py	Wed May 18 01:45:28 2011 +0200
@@ -21,7 +21,15 @@
 
 import pyjd # this is dummy in pyjs
 from pyjamas.ui.AbsolutePanel import AbsolutePanel
+from pyjamas.ui.VerticalPanel import VerticalPanel
+from pyjamas.ui.HorizontalPanel import HorizontalPanel
+from pyjamas.ui.DockPanel import DockPanel
+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 import HasAlignment
 
 from pyjamas.dnd import makeDraggable
 from pyjamas.ui.DragWidget import DragWidget, DragContainer
@@ -38,6 +46,35 @@
 MIN_WIDTH = 950 #Minimum size of the panel
 MIN_HEIGHT = 500
 
+class ContratChooser(DialogBox):
+
+    def __init__(self, parent):
+        """
+        Dialog asking to choose the contrat
+        """
+        self._parent = parent
+        DialogBox.__init__(self, modal=False, centered=True)
+
+        content = VerticalPanel()
+        content.setWidth('100%')
+        self.contrats_list = ListBox()
+        self.contrats_list.setVisibleItemCount(5)
+        self.contrats_list.setWidth("100%")
+        self.contrats_list.setStyleName('contratsChooser')
+        for contrat in ['Passe', 'Petite', 'Garde', 'Garde Sans', 'Garde Contre']:
+            self.contrats_list.addItem(contrat)
+        self.contrats_list.setSelectedIndex(0)
+        content.add(self.contrats_list)
+        button_panel = HorizontalPanel()
+        self.choose_button = Button("Choose", self.onChoose)
+        button_panel.add(self.choose_button)
+        content.add(button_panel)
+        self.setHTML("Please select your contrat")
+        self.setWidget(content)	
+    
+    def onChoose(self):
+        self.hide()
+        self._parent.contratSelected(self.contrats_list.getSelectedItemText()[0])
 
 class CardWidget(TarotCard, Image):
     """This class is used to represent a card, graphically and logically"""
@@ -58,7 +95,7 @@
         pass
         #dc.DrawBitmap(self.bitmap, x, y, True)
 
-class CardPanel(AbsolutePanel):
+class CardPanel(DockPanel):
 
     def __init__(self, parent, referee, players, player_nick):
         self._parent = parent
@@ -83,22 +120,60 @@
         self.hand = []
         self.to_show = []
         self.state = None
-        AbsolutePanel.__init__(self)
+        DockPanel.__init__(self)
         self.setSize("%spx" % MIN_WIDTH, "%spx" % MIN_HEIGHT)
         self.setStyleName("cardPanel")
+        
+        _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%')
+        self.setCellHorizontalAlignment(self.hand_panel, HasAlignment.ALIGN_CENTER)
+
+
+        _label = Label(self.left_nick)
+        _label.setStyleName('cardGamePlayerNick')
+        self.add(_label, DockPanel.WEST)
+        self.setCellHeight(_label, '100%')
+        self.setCellVerticalAlignment(_label, HasAlignment.ALIGN_MIDDLE) 
+
+        _label = Label(self.right_nick)
+        _label.setStyleName('cardGamePlayerNick')
+        self.add(_label, DockPanel.EAST)
+        self.setCellHeight(_label, '100%')
+        self.setCellHorizontalAlignment(_label, HasAlignment.ALIGN_RIGHT) 
+        self.setCellVerticalAlignment(_label, HasAlignment.ALIGN_MIDDLE) 
+        
+        self.center_panel = DockPanel()
+        self.add(self.center_panel, DockPanel.CENTER)
+        self.setCellWidth(self.center_panel, '100%')
+
+
+        """for side in zip(['left', 'top', 'right'],
+                        [DockPanel.WEST, DockPanel.NORTH, DockPanel.EAST]):
+            _nick = getattr(self, "%s_nick" % side[0])
+            _label = Label(_nick)
+            _label.setStyleName('cardGamePlayerNick')
+            self.add(_label, side[1])"""
         self.loadCards()
         self.mouse_over_card = None #contain the card to highlight
         self.visible_size = CARD_WIDTH/2 #number of pixels visible for cards
 
-    def _getTarotCardsPathsCb(self, paths):
-        for file in paths:
-            card = CardWidget(file)
-            self.cards[(card.suit, card.value)]=card
-            self.deck.append(card)
 
     def loadCards(self, dir):
         """Load all the cards in memory
         @param dir: directory where the PNG files are"""
+        def _getTarotCardsPathsCb(paths):
+            for file in paths:
+                card = CardWidget(file)
+                self.cards[(card.suit, card.value)]=card
+                self.deck.append(card)
+            self._parent.host.bridge.call('tarotGameReady', None, self.player_nick, self.referee)
         self.cards={}
         self.deck=[]
         self.cards["atout"]={} #As Tarot is a french game, it's more handy & logical to keep french names
@@ -106,5 +181,37 @@
         self.cards["coeur"]={} #heart
         self.cards["carreau"]={} #diamond
         self.cards["trefle"]={} #club
-        self._parent.host.bridge.call('getTarotCardsPaths', self._getTarotCardsPathsCb)
+        self._parent.host.bridge.call('getTarotCardsPaths', _getTarotCardsPathsCb)
+
+    def tarotGameNew(self, hand):
+        """Start a new game, with given hand"""
+        for suit, value in hand:
+            self.hand.append(self.cards[(suit, value)])
+        self.hand.sort()
+        self.state = "init"
+        self.updateHand()
 
+    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))
+        x_pos = 0
+        y_pos = 0
+        for card in self.hand:
+            self.hand_panel.add(card, x_pos, y_pos)
+            x_pos+=self.visible_size
+    
+    def tarotGameChooseContrat(self, xml_data):
+        """Called when the player as to select his contrat
+        @param xml_data: SàT xml representation of the form"""
+        #for the moment we cheat a little bit and make our own dialog box
+        #but XMLUI must be user ASAP, as in other frontends
+        contrat_chooser = ContratChooser(self)
+        contrat_chooser.show()
+
+    def contratSelected(self, contrat):
+        """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
+
--- a/browser_side/panels.py	Tue May 17 01:33:12 2011 +0200
+++ b/browser_side/panels.py	Wed May 18 01:45:28 2011 +0200
@@ -24,7 +24,6 @@
 from pyjamas.ui.FlowPanel import FlowPanel
 from pyjamas.ui.AbsolutePanel import AbsolutePanel
 from pyjamas.ui.VerticalPanel import VerticalPanel
-from pyjamas.ui.DockPanel import DockPanel
 from pyjamas.ui.HorizontalPanel import HorizontalPanel
 from pyjamas.ui.ScrollPanel import ScrollPanel
 from pyjamas.ui.TabPanel import TabPanel
@@ -563,6 +562,12 @@
             self.tarot_panel = CardPanel(self, referee, players, self.nick)
             self.vpanel.insert(self.tarot_panel, 1)
             self.vpanel.setCellHeight(self.tarot_panel, self.tarot_panel.getHeight())
+    
+    def getGame(self, game_type):
+        """Return class managing the game type"""
+        #TODO: check that the game is launched, and manage errors
+        if game_type=="Tarot":
+            return self.tarot_panel 
 
 class MainDiscussionPanel(HorizontalPanel):
     
--- a/libervia.py	Tue May 17 01:33:12 2011 +0200
+++ b/libervia.py	Wed May 18 01:45:28 2011 +0200
@@ -66,7 +66,7 @@
     def __init__(self):
         LiberviaJsonProxy.__init__(self, "/json_api",
                         ["getContacts", "sendMessage", "sendMblog", "getMblogNodes", "getProfileJid", "getHistory",
-                         "getPresenceStatus", "getRoomJoined", "launchTarotGame", "getTarotCardsPaths"])
+                         "getPresenceStatus", "getRoomJoined", "launchTarotGame", "getTarotCardsPaths", "tarotGameReady", "tarotGameContratChoosed"])
 
 class BridgeSignals(LiberviaJsonProxy):
     def __init__(self):
@@ -169,6 +169,9 @@
             self._roomUserLeftCb(*args)
         elif name == 'tarotGameStarted':
             self._tarotGameStartedCb(*args)
+        elif name == 'tarotGameNew' or \
+             name == 'tarotGameChooseContrat':
+            self._tarotGameGenericCb(name, args[0], args[1:])
 
     def _getProfileJidCB(self, jid):
         self.whoami = JID(jid)
@@ -177,8 +180,6 @@
         #and the rooms where we are
         self.bridge.call('getRoomJoined', self._getRoomJoinedCB)
 
-
-
     ## Signals callbacks ##
 
     def _personalEventCb(self, sender, event_type, data, profile):
@@ -240,6 +241,11 @@
             if isinstance(panel,ChatPanel) and panel.type == 'group' and panel.target.bare == room_jid:
                 panel.startGame("Tarot", referee, players)
 
+    def _tarotGameGenericCb(self, event_name, room_jid, args):
+        for panel in self.mpanels + self.other_panels:
+            if isinstance(panel,ChatPanel) and panel.type == 'group' and panel.target.bare == room_jid:
+                getattr(panel.getGame("Tarot"), event_name)(*args) 
+
     def _getPresenceStatusCB(self, presence_data):
         for entity in presence_data:
             for resource in presence_data[entity]:
--- a/libervia.tac	Tue May 17 01:33:12 2011 +0200
+++ b/libervia.tac	Wed May 18 01:45:28 2011 +0200
@@ -128,7 +128,15 @@
         """Give the path of all the tarot cards"""
         return map(lambda x: x[len(LIBERVIA_DIR):],glob.glob(os.path.join(LIBERVIA_DIR,CARDS_DIR,'*_*.png')));
 
+    def jsonrpc_tarotGameReady(self, player, referee):
+        """Tell to the server that we are ready to start the game"""
+        profile = self.session.sat_profile
+        self.sat_host.bridge.tarotGameReady(player, referee)
 
+    def jsonrpc_tarotGameContratChoosed(self, player_nick, referee, contrat):
+        """Tell to the server that we are ready to start the game"""
+        profile = self.session.sat_profile
+        self.sat_host.bridge.tarotGameContratChoosed(player_nick, referee, contrat, profile)
 
 class Register(jsonrpc.JSONRPC):
     """This class manage the registration procedure with SàT
@@ -353,7 +361,8 @@
             sys.exit(1)
         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']:
+        for signal_name in ['presenceUpdate', 'personalEvent', 'newMessage', 'roomJoined', 'roomUserJoined', 'roomUserLeft', 'tarotGameStarted', 'tarotGameNew',
+                            'tarotGameChooseContrat']:
             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))
--- a/public/libervia.css	Tue May 17 01:33:12 2011 +0200
+++ b/public/libervia.css	Wed May 18 01:45:28 2011 +0200
@@ -291,10 +291,14 @@
 /* Games */
 
 .cardPanel {
-    background: green;
+    background: #02FE03;
     margin: 0 auto;
 }
 
+.cardGamePlayerNick {
+    font-weight: bold;
+}
+
 /* Drag and drop */
 
 .dragover {