comparison browser_side/card_game.py @ 38:7bea2ae0c4fb

Tarot game: center_panel layout + chien can now be showed + fixed click event inheritance + card selection first draft
author Goffi <goffi@goffi.org>
date Thu, 19 May 2011 02:00:59 +0200
parents b306aa090438
children 305e81c7a32c
comparison
equal deleted inserted replaced
37:b306aa090438 38:7bea2ae0c4fb
22 import pyjd # this is dummy in pyjs 22 import pyjd # this is dummy in pyjs
23 from pyjamas.ui.AbsolutePanel import AbsolutePanel 23 from pyjamas.ui.AbsolutePanel import AbsolutePanel
24 from pyjamas.ui.VerticalPanel import VerticalPanel 24 from pyjamas.ui.VerticalPanel import VerticalPanel
25 from pyjamas.ui.HorizontalPanel import HorizontalPanel 25 from pyjamas.ui.HorizontalPanel import HorizontalPanel
26 from pyjamas.ui.DockPanel import DockPanel 26 from pyjamas.ui.DockPanel import DockPanel
27 from pyjamas.ui.SimplePanel import SimplePanel
27 from pyjamas.ui.DialogBox import DialogBox 28 from pyjamas.ui.DialogBox import DialogBox
28 from pyjamas.ui.ListBox import ListBox 29 from pyjamas.ui.ListBox import ListBox
29 from pyjamas.ui.Image import Image 30 from pyjamas.ui.Image import Image
30 from pyjamas.ui.Label import Label 31 from pyjamas.ui.Label import Label
31 from pyjamas.ui.Button import Button 32 from pyjamas.ui.Button import Button
33 from pyjamas.ui.ClickListener import ClickHandler
34 from pyjamas.ui.MouseListener import MouseHandler
32 from pyjamas.ui import HasAlignment 35 from pyjamas.ui import HasAlignment
36 from pyjamas import Window
37 from pyjamas import DOM
33 38
34 from pyjamas.dnd import makeDraggable 39 from pyjamas.dnd import makeDraggable
35 from pyjamas.ui.DragWidget import DragWidget, DragContainer 40 from pyjamas.ui.DragWidget import DragWidget, DragContainer
36 from jid import JID 41 from jid import JID
37 from tools import html_sanitize 42 from tools import html_sanitize
41 46
42 47
43 48
44 CARD_WIDTH = 74 49 CARD_WIDTH = 74
45 CARD_HEIGHT = 136 50 CARD_HEIGHT = 136
51 CARD_DELTA_Y = 10
46 MIN_WIDTH = 950 #Minimum size of the panel 52 MIN_WIDTH = 950 #Minimum size of the panel
47 MIN_HEIGHT = 500 53 MIN_HEIGHT = 500
48 54
49 class ContratChooser(DialogBox): 55 class ContratChooser(DialogBox):
50 56
74 80
75 def onChoose(self): 81 def onChoose(self):
76 self.hide() 82 self.hide()
77 self._parent.contratSelected(self.contrats_list.getSelectedItemText()[0]) 83 self._parent.contratSelected(self.contrats_list.getSelectedItemText()[0])
78 84
79 class CardWidget(TarotCard, Image): 85 class CardWidget(TarotCard, Image, MouseHandler):
80 """This class is used to represent a card, graphically and logically""" 86 """This class is used to represent a card, graphically and logically"""
81 87
82 def __init__(self, file): 88 def __init__(self, parent, file):
83 """@param file: path of the PNG file""" 89 """@param file: path of the PNG file"""
90 self._parent = parent
84 Image.__init__(self,file) 91 Image.__init__(self,file)
85 root_name = file[file.rfind("/")+1:-4] 92 root_name = file[file.rfind("/")+1:-4]
86 suit,value = root_name.split('_') 93 suit,value = root_name.split('_')
87 TarotCard.__init__(self, (suit, value)) 94 TarotCard.__init__(self, (suit, value))
88 print "Carte:",suit, value #, self.bout 95 MouseHandler.__init__(self)
89 96 self.addMouseListener(self)
90 def draw(self, dc, x, y): 97
91 """Draw the card on the device context 98 def onMouseEnter(self, sender):
92 @param dc: device context 99 if self._parent.state == "ecart":
93 @param x: abscissa 100 DOM.setStyleAttribute(self.getElement(), "top", "0px")
94 @param y: ordinate""" 101
95 pass 102 def onMouseLeave(self, sender):
96 #dc.DrawBitmap(self.bitmap, x, y, True) 103 DOM.setStyleAttribute(self.getElement(), "top", "%dpx" % CARD_DELTA_Y)
97 104
98 class CardPanel(DockPanel): 105 class CardPanel(DockPanel, ClickHandler):
99 106
100 def __init__(self, parent, referee, players, player_nick): 107 def __init__(self, parent, referee, players, player_nick):
108 DockPanel.__init__(self)
109 ClickHandler.__init__(self)
101 self._parent = parent 110 self._parent = parent
102 self._autoplay = None #XXX: use 0 to activate fake play, None else 111 self._autoplay = None #XXX: use 0 to activate fake play, None else
103 self.referee = referee 112 self.referee = referee
104 self.players = players 113 self.players = players
105 self.played = {} 114 self.played = {}
118 self.selected = [] #Card choosed by the player (e.g. during ecart) 127 self.selected = [] #Card choosed by the player (e.g. during ecart)
119 self.hand_size = 13 #number of cards in a hand 128 self.hand_size = 13 #number of cards in a hand
120 self.hand = [] 129 self.hand = []
121 self.to_show = [] 130 self.to_show = []
122 self.state = None 131 self.state = None
123 DockPanel.__init__(self) 132 self.setSize("%dpx" % MIN_WIDTH, "%dpx" % MIN_HEIGHT)
124 self.setSize("%spx" % MIN_WIDTH, "%spx" % MIN_HEIGHT)
125 self.setStyleName("cardPanel") 133 self.setStyleName("cardPanel")
126 134
135 # Now we set up the layout
127 _label = Label(self.top_nick) 136 _label = Label(self.top_nick)
128 _label.setStyleName('cardGamePlayerNick') 137 _label.setStyleName('cardGamePlayerNick')
129 self.add(_label, DockPanel.NORTH) 138 self.add(_label, DockPanel.NORTH)
130 self.setCellWidth(_label, '100%') 139 self.setCellWidth(_label, '100%')
131 self.setCellHorizontalAlignment(_label, HasAlignment.ALIGN_CENTER) 140 self.setCellHorizontalAlignment(_label, HasAlignment.ALIGN_CENTER)
132 141
142
133 self.hand_panel = AbsolutePanel() 143 self.hand_panel = AbsolutePanel()
134 self.add(self.hand_panel, DockPanel.SOUTH) 144 self.add(self.hand_panel, DockPanel.SOUTH)
135 self.setCellWidth(self.hand_panel, '100%') 145 self.setCellWidth(self.hand_panel, '100%')
136 self.setCellHorizontalAlignment(self.hand_panel, HasAlignment.ALIGN_CENTER) 146 self.setCellHorizontalAlignment(self.hand_panel, HasAlignment.ALIGN_CENTER)
137 147
139 _label = Label(self.left_nick) 149 _label = Label(self.left_nick)
140 _label.setStyleName('cardGamePlayerNick') 150 _label.setStyleName('cardGamePlayerNick')
141 self.add(_label, DockPanel.WEST) 151 self.add(_label, DockPanel.WEST)
142 self.setCellHeight(_label, '100%') 152 self.setCellHeight(_label, '100%')
143 self.setCellVerticalAlignment(_label, HasAlignment.ALIGN_MIDDLE) 153 self.setCellVerticalAlignment(_label, HasAlignment.ALIGN_MIDDLE)
154
144 155
145 _label = Label(self.right_nick) 156 _label = Label(self.right_nick)
146 _label.setStyleName('cardGamePlayerNick') 157 _label.setStyleName('cardGamePlayerNick')
147 self.add(_label, DockPanel.EAST) 158 self.add(_label, DockPanel.EAST)
148 self.setCellHeight(_label, '100%') 159 self.setCellHeight(_label, '100%')
149 self.setCellHorizontalAlignment(_label, HasAlignment.ALIGN_RIGHT) 160 self.setCellHorizontalAlignment(_label, HasAlignment.ALIGN_RIGHT)
150 self.setCellVerticalAlignment(_label, HasAlignment.ALIGN_MIDDLE) 161 self.setCellVerticalAlignment(_label, HasAlignment.ALIGN_MIDDLE)
151 162
163
152 self.center_panel = DockPanel() 164 self.center_panel = DockPanel()
165 self.inner_left = SimplePanel()
166 self.center_panel.add(self.inner_left, DockPanel.WEST)
167 self.center_panel.setCellHeight(self.inner_left, '100%')
168 self.center_panel.setCellHorizontalAlignment(self.inner_left, HasAlignment.ALIGN_RIGHT)
169 self.center_panel.setCellVerticalAlignment(self.inner_left, HasAlignment.ALIGN_MIDDLE)
170
171 self.inner_right = SimplePanel()
172 self.center_panel.add(self.inner_right, DockPanel.EAST)
173 self.center_panel.setCellHeight(self.inner_right, '100%')
174 self.center_panel.setCellVerticalAlignment(self.inner_right, HasAlignment.ALIGN_MIDDLE)
175
176 self.inner_top = SimplePanel()
177 self.center_panel.add(self.inner_top, DockPanel.NORTH)
178 self.center_panel.setCellWidth(self.inner_top, '100%')
179 self.center_panel.setCellHorizontalAlignment(self.inner_top, HasAlignment.ALIGN_CENTER)
180 self.center_panel.setCellVerticalAlignment(self.inner_top, HasAlignment.ALIGN_BOTTOM)
181
182 self.inner_bottom = SimplePanel()
183 self.center_panel.add(self.inner_bottom, DockPanel.SOUTH)
184 self.center_panel.setCellWidth(self.inner_bottom, '100%')
185 self.center_panel.setCellHorizontalAlignment(self.inner_bottom, HasAlignment.ALIGN_CENTER)
186 self.center_panel.setCellVerticalAlignment(self.inner_bottom, HasAlignment.ALIGN_TOP)
187
188 self.inner_center = SimplePanel()
189 self.center_panel.add(self.inner_center, DockPanel.CENTER)
190 self.center_panel.setCellHorizontalAlignment(self.inner_center, HasAlignment.ALIGN_CENTER)
191 self.center_panel.setCellVerticalAlignment(self.inner_center, HasAlignment.ALIGN_MIDDLE)
192
153 self.add(self.center_panel, DockPanel.CENTER) 193 self.add(self.center_panel, DockPanel.CENTER)
154 self.setCellWidth(self.center_panel, '100%') 194 self.setCellWidth(self.center_panel, '100%')
195 self.setCellHeight(self.center_panel, '100%')
196 self.setCellVerticalAlignment(self.center_panel, HasAlignment.ALIGN_MIDDLE)
197 self.setCellHorizontalAlignment(self.center_panel, HasAlignment.ALIGN_CENTER)
155 198
156 199
157 """for side in zip(['left', 'top', 'right'], 200 """for side in zip(['left', 'top', 'right'],
158 [DockPanel.WEST, DockPanel.NORTH, DockPanel.EAST]): 201 [DockPanel.WEST, DockPanel.NORTH, DockPanel.EAST]):
159 _nick = getattr(self, "%s_nick" % side[0]) 202 _nick = getattr(self, "%s_nick" % side[0])
161 _label.setStyleName('cardGamePlayerNick') 204 _label.setStyleName('cardGamePlayerNick')
162 self.add(_label, side[1])""" 205 self.add(_label, side[1])"""
163 self.loadCards() 206 self.loadCards()
164 self.mouse_over_card = None #contain the card to highlight 207 self.mouse_over_card = None #contain the card to highlight
165 self.visible_size = CARD_WIDTH/2 #number of pixels visible for cards 208 self.visible_size = CARD_WIDTH/2 #number of pixels visible for cards
209 self.addClickListener(self)
166 210
167 211
168 def loadCards(self, dir): 212 def loadCards(self, dir):
169 """Load all the cards in memory 213 """Load all the cards in memory
170 @param dir: directory where the PNG files are""" 214 @param dir: directory where the PNG files are"""
171 def _getTarotCardsPathsCb(paths): 215 def _getTarotCardsPathsCb(paths):
172 for file in paths: 216 for file in paths:
173 card = CardWidget(file) 217 card = CardWidget(self, file)
174 self.cards[(card.suit, card.value)]=card 218 self.cards[(card.suit, card.value)]=card
175 self.deck.append(card) 219 self.deck.append(card)
176 self._parent.host.bridge.call('tarotGameReady', None, self.player_nick, self.referee) 220 self._parent.host.bridge.call('tarotGameReady', None, self.player_nick, self.referee)
177 self.cards={} 221 self.cards={}
178 self.deck=[] 222 self.deck=[]
181 self.cards["coeur"]={} #heart 225 self.cards["coeur"]={} #heart
182 self.cards["carreau"]={} #diamond 226 self.cards["carreau"]={} #diamond
183 self.cards["trefle"]={} #club 227 self.cards["trefle"]={} #club
184 self._parent.host.bridge.call('getTarotCardsPaths', _getTarotCardsPathsCb) 228 self._parent.host.bridge.call('getTarotCardsPaths', _getTarotCardsPathsCb)
185 229
230 def onClick(self, sender):
231 if self.state == "chien":
232 self.to_show = []
233 self.state = "wait"
234 self.updateToShow()
235 elif self.state == "wait_for_ecart":
236 self.state = "ecart"
237 self.hand.extend(self.to_show)
238 self.hand.sort()
239 self.to_show = []
240 self.updateToShow()
241 self.updateHand()
242
186 def tarotGameNew(self, hand): 243 def tarotGameNew(self, hand):
187 """Start a new game, with given hand""" 244 """Start a new game, with given hand"""
188 for suit, value in hand: 245 for suit, value in hand:
189 self.hand.append(self.cards[(suit, value)]) 246 self.hand.append(self.cards[(suit, value)])
190 self.hand.sort() 247 self.hand.sort()
192 self.updateHand() 249 self.updateHand()
193 250
194 def updateHand(self): 251 def updateHand(self):
195 """Show the cards in the hand in the hand_panel (SOUTH panel)""" 252 """Show the cards in the hand in the hand_panel (SOUTH panel)"""
196 self.hand_panel.clear() 253 self.hand_panel.clear()
197 self.hand_panel.setSize("%spx" % (self.visible_size * (len(self.hand)+1)), "%spx" % (CARD_HEIGHT + 10)) 254 self.hand_panel.setSize("%dpx" % (self.visible_size * (len(self.hand)+1)), "%dpx" % (CARD_HEIGHT + CARD_DELTA_Y + 10))
198 x_pos = 0 255 x_pos = 0
199 y_pos = 0 256 y_pos = CARD_DELTA_Y
200 for card in self.hand: 257 for card in self.hand:
201 self.hand_panel.add(card, x_pos, y_pos) 258 self.hand_panel.add(card, x_pos, y_pos)
202 x_pos+=self.visible_size 259 x_pos+=self.visible_size
203 260
261 def updateToShow(self):
262 """Show cards in the center panel"""
263 if not self.to_show:
264 _widget = self.inner_center.getWidget()
265 if _widget:
266 self.inner_center.remove(_widget)
267 return
268 panel = AbsolutePanel()
269 panel.setSize("%dpx" % ((CARD_WIDTH + 5) * len(self.to_show) - 5), "%dpx" % (CARD_HEIGHT))
270 x_pos = 0
271 y_pos = 0
272 for card in self.to_show:
273 panel.add(card, x_pos, y_pos)
274 x_pos+=CARD_WIDTH + 5
275 self.inner_center.setWidget(panel)
276
277
204 def tarotGameChooseContrat(self, xml_data): 278 def tarotGameChooseContrat(self, xml_data):
205 """Called when the player as to select his contrat 279 """Called when the player as to select his contrat
206 @param xml_data: SàT xml representation of the form""" 280 @param xml_data: SàT xml representation of the form"""
207 #for the moment we cheat a little bit and make our own dialog box 281 #for the moment we cheat a little bit and make our own dialog box
208 #but XMLUI must be user ASAP, as in other frontends 282 #but XMLUI must be user ASAP, as in other frontends
211 285
212 def contratSelected(self, contrat): 286 def contratSelected(self, contrat):
213 """Must be called when the contrat is selected 287 """Must be called when the contrat is selected
214 @param contrat: one of the valid contrat value""" 288 @param contrat: one of the valid contrat value"""
215 print "Contrat choosed:", contrat 289 print "Contrat choosed:", contrat
216 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 290 self._parent.host.bridge.call('tarotGameContratChoosed', None, self.player_nick, self.referee, contrat or 'Passe')
217 291
292
293
294 def tarotGameShowCards(self, game_stage, cards, data):
295 """Display cards in the middle of the game (to show for e.g. chien ou poignée)"""
296 self.to_show = []
297 for suit, value in cards:
298 self.to_show.append(self.cards[(suit, value)])
299 self.updateToShow()
300 if game_stage == "chien" and data['attaquant'] == self.player_nick:
301 self.state = "wait_for_ecart"
302 else:
303 self.state = "chien"
304