Mercurial > libervia-web
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 |