Mercurial > libervia-web
view 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 |
line wrap: on
line source
#!/usr/bin/python # -*- coding: utf-8 -*- """ Libervia: a Salut à Toi frontend Copyright (C) 2011 Jérôme Poisson (goffi@goffi.org) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. """ 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.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 from jid import JID from tools import html_sanitize from datetime import datetime from time import time from games import TarotCard CARD_WIDTH = 74 CARD_HEIGHT = 136 CARD_DELTA_Y = 10 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, MouseHandler): """This class is used to represent a card, graphically and logically""" 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)) MouseHandler.__init__(self) self.addMouseListener(self) def onMouseEnter(self, sender): if self._parent.state == "ecart": DOM.setStyleAttribute(self.getElement(), "top", "0px") 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 self.players = players self.played = {} for player in players: self.played[player] = None self.player_nick = player_nick self.bottom_nick = self.player_nick idx = self.players.index(self.player_nick) idx = (idx + 1) % len(self.players) self.right_nick = self.players[idx] idx = (idx + 1) % len(self.players) self.top_nick = self.players[idx] idx = (idx + 1) % len(self.players) self.left_nick = self.players[idx] self.bottom_nick = player_nick self.selected = [] #Card choosed by the player (e.g. during ecart) self.hand_size = 13 #number of cards in a hand self.hand = [] self.to_show = [] self.state = None 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%') 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.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'], [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 self.addClickListener(self) 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(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) self.cards={} self.deck=[] self.cards["atout"]={} #As Tarot is a french game, it's more handy & logical to keep french names self.cards["pique"]={} #spade self.cards["coeur"]={} #heart self.cards["carreau"]={} #diamond 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: 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("%dpx" % (self.visible_size * (len(self.hand)+1)), "%dpx" % (CARD_HEIGHT + CARD_DELTA_Y + 10)) x_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""" #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') 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"