pieces.py :  » Game-2D-3D » PyScrabble » pyscrabble-1.6.2 » pyscrabble » gui » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Game 2D 3D » PyScrabble 
PyScrabble » pyscrabble 1.6.2 » pyscrabble » gui » pieces.py
import gtk
from pyscrabble.game.pieces import *
from pyscrabble.constants import *
from pyscrabble import lookup
from pyscrabble.gtkconstants import *
from pyscrabble import manager
from pyscrabble import gtkutil
from pyscrabble import util

# Class representing a Tile on the Gameboard            
class GameTile(gtk.Button, Tile):
    '''
    GameTiles represent Tiles on the Game board.
    '''
    
    DIR_NONE = 0
    DIR_HORIZ = 1
    DIR_VERT = 2
    
    def __init__(self, x, y, parent):
        '''
        Constructor.
        
        @param x: X Position
        @param y: Y Position
        @param parent: GameFrame class
        '''
        self.board = parent #callback to the parent widget
        
        gtk.Button.__init__(self)
        Tile.__init__(self)
        self.set_size_request(TILE_WIDTH, TILE_HEIGHT)
        self.findStyle(x,y)
        
        self.x = x
        self.y = y
        self.direction = GameTile.DIR_NONE
        self.fixed = False
        self.start = False
        
        self.handler_id = 0
        self.source_handler_id = 0
        self.key_press_handler = 0
        self.active = False
        self.deactivate()
        
        self.connect("button-release-event", self.buttonRelease_cb)
        self.connect("button-press-event", self.buttonPress_cb)
    
    def clone(self):
        '''
        Clone this Tile
        
        @return: Cloned Tile
        '''
        
        g = GameTile(self.x,self.y,self.parent)
        g.putLetter( self.getLetter() )
        return g
    
    def activate(self):
        '''
        Activate this tile.
        
        Allow letters to be dragged onto it.
        '''
        self.deactivate()
            
        if (self.getLetter() == None):
            self.handler_id = self.connect("drag_data_received", self.letterDragged);
        self.drag_dest_set(gtk.DEST_DEFAULT_MOTION | gtk.DEST_DEFAULT_HIGHLIGHT | gtk.DEST_DEFAULT_DROP, [( "image/x-xpixmap", 0, 81 )], gtk.gdk.ACTION_COPY)
        self.active = True
    
    def deactivate(self):
        '''
        Deactivate this tile.
        
        Disallow letters to be dragged onto it.
        '''
        if (self.handler_is_connected(self.handler_id)):
            self.disconnect(self.handler_id)
        
        if (self.handler_is_connected(self.source_handler_id)):
            self.disconnect(self.source_handler_id)
            
        self.drag_dest_unset()
        self.drag_source_unset()
        self.active = False
    
    def dragLetter(self, widget, context, selection, targetType, eventTime):
        '''
        Drag data callback.
        
        @param widget:
        @param context:
        @param selection:
        @param targetType:
        @param eventTime:
        '''
        #print 'dragging tile gameletter %s' % widget.getLetter().getLetter()
        s = widget.getLetter().getLetter()
        selection.set(selection.target, 8, '%s:%s:%s' % (s, str(widget.getLetter().getScore()), str(int(widget.getLetter().isBlank()))))
    
    # Callback when a GameLetter is dragged onto this GameTile
    def letterDragged(self, widget, context, x, y, selection, targetType, eventType):
        '''
        Callback when a GameLetter is dragged onto this Tile.
        
        Callback to the GameFrame to let it know that a letter has been dropped
        
        @param widget:
        @param context:
        @param x:
        @param y:
        @param selection:
        @param targetType:
        @param eventType:
        '''
        #print 'set letter called in tile %d,%d' % (self.x,self.y)
        
        # Kill typing
        self.get_parent().clearArrows()
        
        
        c = context.get_source_widget()
        if c == self: # Ignore if we drag onto ourselves
            return
        
        self.setLetter(c, c.getLetter().getLetter(), c.getLetter().getScore(), c.getLetter().isBlank())
    
    def setLetter(self, widget, letter, score, isBlank, showBlank=True):
        '''
        Set letter on this Tile
        
        @param widget: Widget that was dragged
        @param letter: Letter value
        @param score: Score value
        '''
        refresh = True
        
        # If we have a letter on here there are two cases
        # 1.) A GameTile is being dragged.  If so, we need to remove the old game tile (widget) and put its letter here
        # 2.) A Letter is being dragged.  If so, we need to remove the old letter and put it back in the rack and put the letter here
        #print 'SetLetter called on %s %s %d,%d with %s %s' % ( str(id(self)), str(self),self.x,self.y, str(widget.__class__), str(widget) )
        #print 'SetLetter %s %s %s %s' % ( str(letter), str(score), str(isBlank), str(showBlank) )
        if self.getLetter() is not None and widget is not None:
            if isinstance(widget, GameTile):
                refresh = False
                self.board.removeMove(widget, widget.x, widget.y, refresh=False)
                self.board.removeMove(self, self.x, self.y, refresh=False)
                letter,score = widget.getLetter().getLetter(), widget.getLetter().getScore()
                widget.setLetter( self.getLetter(), self.getLetter().getLetter(), self.getLetter().getScore(), self.getLetter().isBlank() )
            if isinstance(widget, GameLetter):
                self.board.removeMove(self, self.x, self.y, refresh=False)
                widget.copyLetter( self.getLetter() )
                refresh = False
        
        else:
            if isinstance(widget, GameTile):
                self.board.removeMove(widget,widget.x,widget.y)
                refresh = False
        
        l = Letter(letter,score)    
        l.setIsBlank( isBlank )
        if l.isBlank() and showBlank:
            l.setLetter("")
        self.putLetter( l, showBlank )
        #print '%s %s %s put on %s %d,%d' % (str(l.getLetter()), str(l.getScore()), str(l.isBlank()), str(id(self)), self.x,self.y)
        self.board.registerMove(self, self.x, self.y, refresh, widget)
        
        self.source_handler_id = self.connect("drag_data_get", self.dragLetter)
        self.drag_source_set(gtk.gdk.BUTTON1_MASK, [( "image/x-xpixmap", 0, 81 )], gtk.gdk.ACTION_COPY)
        
        o = manager.OptionManager()
        if o.get_default_bool_option(USE_COLOR_NEW_TILE, True):
            self.setBackground(o.get_default_option(COLOR_NEW_TILE, DEFAULT_NEW_TILE))
        
    def putLetter(self, letter, showBlank=False):
        '''
        Put a Letter on the tie.
        
        @param letter:
        @param showBlank: True to show blank value
        '''
        o = manager.OptionManager()
        color = None
        if o.get_default_bool_option(USE_COLOR_LETTER, True):
            color = o.get_default_option(COLOR_LETTER, TILE_COLORS[TILE_LETTER])
        else:
            color = TILE_COLORS[TILE_LETTER]
        
        self.setStyle( TILE_LETTER, color )
        self.set_label( letter, showBlank )
        Tile.setLetter(self, letter)
        
    
    def findStyle(self, x, y):
        '''
        Get the style for this Tile based on the x,y position
        
        @param x:
        @param y:
        '''
        
        
        pos = (x+1, y+1)
        if ( pos in DOUBLE_LETTERS ):
            self.setStyle(TILE_DOUBLE_LETTER, TILE_COLORS[TILE_DOUBLE_LETTER])
            self.board.tileTips.set_tip(self, _('Double Letter Score'))
        elif ( pos in TRIPLE_LETTERS ):
            self.setStyle(TILE_TRIPLE_LETTER, TILE_COLORS[TILE_TRIPLE_LETTER])
            self.board.tileTips.set_tip(self, _('Triple Letter Score'))
        elif ( pos in DOUBLE_WORDS ):
            self.setStyle(TILE_DOUBLE_WORD, TILE_COLORS[TILE_DOUBLE_WORD])
            self.board.tileTips.set_tip(self, _('Double Word Score'))
        elif ( pos in TRIPLE_WORDS ):
            self.setStyle(TILE_TRIPLE_WORD, TILE_COLORS[TILE_TRIPLE_WORD])
            self.board.tileTips.set_tip(self, _('Triple Word Score'))
        elif ( pos in CENTER ):
            if self.board.gameOptions[OPTION_CENTER_TILE]:
                self.setStyle(TILE_DOUBLE_WORD, TILE_COLORS[TILE_DOUBLE_WORD])
                self.board.tileTips.set_tip(self, _('Double Word Score'))
            else:
                self.setStyle(TILE_CENTER, TILE_COLORS[TILE_CENTER])
        else:
            o = manager.OptionManager()
            if o.get_default_bool_option(USE_COLOR_NORMAL_TILE, True):
                self.setStyle(TILE_NORMAL, o.get_default_option(COLOR_NORMAL_TILE, TILE_COLORS[TILE_NORMAL]))
            else:
                self.setStyle(TILE_NORMAL, TILE_COLORS[TILE_NORMAL])
        
    def setBackground(self, color):
        '''
        Set backround color
        
        @param color 
        '''
        self.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(color))
        self.modify_bg(gtk.STATE_PRELIGHT, gtk.gdk.color_parse(color))
        
    
    def setStyle(self, style, color):
        '''
        Set the style on this Tile
        
        @param style:
        @param color
        '''
        
        Tile.setStyle(self,style)
        
        self.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(color) )
        self.modify_bg(gtk.STATE_PRELIGHT, gtk.gdk.color_parse(color) )

    
    def __repr__(self):
        '''
        Print the Letter on the Tile
        '''
        
        return self.getLetter()
    
    def set_label(self, letter, showBlank=False):
        '''
        Set the Letter/score label on the Tile
        
        @param letter: Letter
        @see: L{pyscrabble.game.pieces.Letter}
        '''
        widget = self.get_child()
        if (widget is not None):
            self.remove(widget)
        widget = gtk.Label()
            
        l = letter.getLetter()
        s = str(letter.getScore())
        o = manager.OptionManager()
        if letter.isBlank():
            if showBlank:
                l = ""
            if o.get_default_bool_option(USE_COLOR_BLANK_TILE, True):
                l = """<span foreground="%s">%s</span>""" % (o.get_default_option(COLOR_BLANK_TILE, DEFAULT_BLANK_TILE), l)
                s = """<span foreground="%s">%s</span>""" % (o.get_default_option(COLOR_BLANK_TILE, DEFAULT_BLANK_TILE), s)
        else:
            if o.get_default_bool_option(USE_COLOR_TEXT, True):
                l = """<span foreground="%s">%s</span>""" % (o.get_default_option(COLOR_TEXT, DEFAULT_COLOR_TEXT), l)
                s = """<span foreground="%s">%s</span>""" % (o.get_default_option(COLOR_TEXT, DEFAULT_COLOR_TEXT), s)
        
        if o.get_default_bool_option(OPTION_TEXT_BOLD, False):
            l = """<span weight="bold">%s</span>""" % l
            s = """<span weight="bold">%s</span>""" % s
            
        if len(str(letter.getScore())) == 2:
            widget.set_markup("""%s <sub><span size="xx-small">%s</span></sub>""" % (l, s))
        else:
            widget.set_markup("""%s <sub><span size="x-small">%s</span></sub>""" % (l, s))
        self.add(widget)
        self.show_all()
    
    def refresh(self):
        '''
        Refresh tile color
        
        @return: True if the tile is active
        '''
        o = manager.OptionManager()
        if self.getLetter() is not None:
            self.set_label( self.getLetter() )
            
            if self.handler_is_connected(self.handler_id):
                if ( o.get_default_bool_option(USE_COLOR_NEW_TILE, True) ):
                    self.setBackground( o.get_default_option(COLOR_NEW_TILE, DEFAULT_NEW_TILE) )
                    return
                    
            if o.get_default_bool_option(USE_COLOR_LETTER, True):
                self.setBackground( o.get_default_option(COLOR_LETTER, TILE_COLORS[TILE_LETTER]) )
            else:
                self.setBackground( TILE_COLORS[TILE_LETTER] )
        else:
            if self.getStyle() is TILE_NORMAL:
                if o.get_default_bool_option(USE_COLOR_NORMAL_TILE, True):
                    self.setBackground( o.get_default_option(COLOR_NORMAL_TILE, TILE_COLORS[TILE_NORMAL]) )
                else:
                    self.setBackground( TILE_COLORS[TILE_NORMAL] )
        
    
    def buttonPress_cb(self, widget, event):
        '''
        Button press event
        
        @param widget: widget
        @param event: event info
        '''
        if event.type == gtk.gdk._2BUTTON_PRESS:
            if self.getLetter() is not None:
                if self.handler_is_connected(self.handler_id):
                    self.board.removeMove(self, self.x, self.y)
                    self.board.refreshLetterBox()
            return True
            
        if event.button == 1 and self.getLetter() is None and event.type not in (gtk.gdk._2BUTTON_PRESS, gtk.gdk._3BUTTON_PRESS):
            if self.board.isCurrentTurn() == True:
                
                if self.fixed:
                    return False
                
                self.direction = self.direction + 1
                if self.direction > GameTile.DIR_VERT:
                    self.direction = GameTile.DIR_NONE
                    
                self.handleArrow(self.getArrow(self.direction))
                
        return False
        
    
    def getArrow(self, direction):
        '''
        Get arrow from direction import 
        
        @param direction:
        '''
        if direction == GameTile.DIR_HORIZ:
            return gtk.Arrow(gtk.ARROW_RIGHT, gtk.SHADOW_OUT)
        if direction == GameTile.DIR_VERT:
            return gtk.Arrow(gtk.ARROW_DOWN, gtk.SHADOW_OUT)
            
        return None
    
    def handleArrow(self, arrow):
        '''
        Place an arrow on the board
        
        @param arrow:
        '''
        dir = self.direction
        self.get_parent().clearArrows()
        self.direction = dir
        
        if arrow is not None:
            box = gtk.HBox(False, 0)
            arrow.set_size_request(10,10)
            arrow.set_padding(0.0, 0.0)
            box.pack_start(arrow, False, False, 0)
            self.add(box)
            self.key_press_handler = self.connect("key-press-event", self.keyPress_cb, self.direction)
        self.show_all()
        
    
    def buttonRelease_cb(self, widget, event):
        '''
        Button release event
        
        @param widget: Widget
        @param event: Event info
        '''
        
        if event.button == 3:
            
            menu = gtk.Menu()
            
            if widget.getLetter() is not None:
            
                board = widget.get_parent()
                moves = board.getMovesAtXY(widget.x,widget.y)
                
                if len(moves) > 0:
                    item = gtk.ImageMenuItem(stock_id=STOCK_DEFINE)
                    menu.append(item)
                    
                    l = manager.LettersManager()
                    
                    meta = l.getMeta( self.board.getGameOption(OPTION_RULES) )
                    site = meta['lookup']
                    submenu = gtk.Menu()
                    for move in moves:
                        word = move.getWord()
                        i = gtk.MenuItem(word)
                        i.connect("activate", util.showUrl, '%s%s' % (site,word.lower()))
                        submenu.append(i)
                        
                    item.set_submenu(submenu)
                 
            if len(menu.get_children()) > 0:
                menu.show_all()
                menu.popup(None, None, None, 1, event.time)
    
    def removeArrow(self):
        '''
        Remove arrow
        '''
        if self.getLetter() is None:
            x = self.get_child()
            if x is not None:
                self.remove(x)
                self.direction = GameTile.DIR_NONE
                self.fixed = False
        if self.handler_is_connected(self.key_press_handler):
            self.disconnect(self.key_press_handler)     
        
    def keyPress_cb(self, widget, event, direction):
        '''
        Key press
        
        @param widget:
        @param event:
        @param direction:
        '''
        val = event.keyval
        board = self.get_parent()
        
        if val == gtk.keysyms.Escape:
            self.removeArrow()
            self.direction = GameTile.DIR_NONE
            self.fixed = False
            return True
        
        if val in (gtk.keysyms.BackSpace, gtk.keysyms.Delete):
            
            # Handle edges
            if direction == GameTile.DIR_HORIZ:
                if self.x == 14 and self.getLetter() is not None:
                    self.board.removeLetter(self.x,self.y)
                    tile = board.get(self.x,self.y)
                    board.set_focus_child(tile)
                    tile.grab_focus()
                    tile.direction = direction
                    tile.fixed = True
                    tile.handleArrow( self.getArrow(direction) )
                    return True
            if direction == GameTile.DIR_VERT and self.getLetter() is not None:
                if self.y == 14:
                    self.board.removeLetter(self.x,self.y)
                    tile = board.get(self.x,self.y)
                    board.set_focus_child(tile)
                    tile.grab_focus()
                    tile.direction = direction
                    tile.fixed = True
                    tile.handleArrow( self.getArrow(direction) )
                    return True
            
            tile = None
            if direction == GameTile.DIR_HORIZ:
                x = self.x - 1
                while x >= 0:
                    if self.board.hasOnboardMove(x, self.y):
                        tile = board.get(x, self.y)
                        break
                    x = x - 1
            if direction == GameTile.DIR_VERT:
                y = self.y -1
                while y >= 0:
                    if self.board.hasOnboardMove(self.x, y):
                        tile = board.get(self.x, y)
                        break
                    y = y - 1
            if tile is not None:
                self.board.removeLetter(tile.x,tile.y)
                tile = board.get(tile.x,tile.y)
                board.set_focus_child(tile)
                tile.grab_focus()
                tile.direction = direction
                if self.board.getNumOnBoardMoves() == 0:
                    tile.fixed = False
                else:
                    tile.fixed = True
                tile.handleArrow( self.getArrow(direction) )
                self.removeArrow()
            return True
        
        if val == gtk.keysyms.Return:
            self.board.sendCurrentMove()
            self.get_parent().clearArrows()
            return True
        
        if val in range(gtk.keysyms.a, gtk.keysyms.z+1):
            val = val - 32
                
        if val in range(gtk.keysyms.A, gtk.keysyms.Z+1):
            ch = chr(val)
            
            if direction == GameTile.DIR_HORIZ:
                if self.x == 14 and self.getLetter() is not None:
                    gtk.gdk.beep()
            if direction == GameTile.DIR_VERT and self.getLetter() is not None:
                if self.y == 14:
                    gtk.gdk.beep()
            
            tile = None
            if direction == GameTile.DIR_HORIZ:
                num = min(14 - self.x, 6)
                for x in range(1,num+1):
                    t = board.get(self.x + x, self.y)
                    if t.getLetter() is None:
                        tile = t
                        break
            if direction == GameTile.DIR_VERT:
                num = min(14 - self.y, 6)
                for x in range(1,num+1):
                    t = board.get(self.x, self.y+x)
                    if t.getLetter() is None:
                        tile = t
                        break
            
            placed = self.board.placeLetter(str(ch), self.x, self.y)
            if tile is not None:
                if placed:
                    board.set_focus_child(t)
                    t.grab_focus()
                    t.direction = direction
                    t.handleArrow( self.getArrow(direction) )
                    tile.fixed = True  
                    self.removeArrow()
            
            return True
        return False
            
        
        




# Class representing a Letter tile
class GameLetter(gtk.ToggleButton, Letter):
    '''
    The GameLetter represents the Letters that are used to make words.
    
    They are dragged onto specific GameTiles on the GameBoard.
    '''
    
    def __init__(self, letter, letterBox):
        '''
        Constructor.
        
        Initialize the letter
        
        @param letter: Letter
        '''
        gtk.ToggleButton.__init__(self)
        Letter.__init__(self, letter.getLetter(), letter.getScore())
        self.set_size_request(TILE_WIDTH, TILE_HEIGHT)
        
        
        self.letterBox = letterBox
        
        self.setBackground()
        
        self.set_label(letter)
        
        self.handlerId = 0
        self.destHandlerId = 0
        
        self.activate()

    def setBackground(self):
        '''
        Set background color according to preference
        '''
        o = manager.OptionManager()
        color = None
        if o.get_default_bool_option(USE_COLOR_LETTER, True):
            color = o.get_default_option(COLOR_LETTER, TILE_COLORS[TILE_LETTER])
        else:
            color = TILE_COLORS[TILE_LETTER]
        
        color = gtk.gdk.color_parse(color)
        self.modify_bg(gtk.STATE_NORMAL, color )
        self.modify_bg(gtk.STATE_ACTIVE, color )
        self.modify_bg(gtk.STATE_PRELIGHT, color )
    
    def getLetter(self):
        '''
        Return the Letter object that this object represents
        
        @return: Letter
        '''
        
        return self.clone()
    
    def copyLetter(self, letter):
        '''
        Copy a letter onto this Letter
        
        @param letter: Letter
        '''
        
        s = letter.getLetter()
        if letter.isBlank():
            s = ""
        
        self.setLetter(s)
        self.setScore( letter.getScore() )
        self.setIsBlank(letter.isBlank())
        self.set_label(letter)
    
    def dragLetter(self, widget, context, selection, targetType, eventTime):
        '''
        Drag data callback.
        
        @param widget:
        @param context:
        @param selection:
        @param targetType:
        @param eventTime:
        '''
        #print 'dragging gameletter %s' % widget.getLetter().getLetter()
        selection.set(selection.target, 8, '%s:%s:%s' % (widget.getLetter().getLetter(), str(widget.getLetter().getScore()), str(int(widget.getLetter().isBlank()))))
    
    def letterDragged(self, widget, context, x, y, selection, targetType, eventType):
        '''
        Callback when a widget is dragged onto this letter.
        
        @param widget:
        @param context:
        @param x:
        @param y:
        @param selection:
        @param targetType:
        @param eventType:
        '''
        letter = context.get_source_widget()
        
        if isinstance(letter, GameTile): # Swap from Board to Tile
            tile = letter
            tmp = self.clone()
            tile.board.removeMove(tile,tile.x,tile.y, refresh=False)
            self.copyLetter( tile.getLetter() )
            tile.setLetter( None, tmp.getLetter(), tmp.getScore(), tmp.isBlank() )
            return
        
        if isinstance(letter, GameLetter):
            
            if id(letter) == id(self): # ignore if widget is dragged onto itself
                return
            
            o = manager.OptionManager()
            opt = o.get_default_option(OPTION_SWAP, OPTION_LETTER_SWAP)
            
            if opt == OPTION_LETTER_INSERT:
                letters = self.letterBox.get_children()
                self.letterBox.foreach(lambda w: self.letterBox.remove(w))
                letters = [ l for l in letters if id(l) != id(letter) ]
                for l in letters:
                    if id(l) == id(widget):
                        self.letterBox.pack_start(letter, False, False, 0)
                    self.letterBox.pack_start(l, False, False, 0)
            
            if opt == OPTION_LETTER_SWAP:
                l = self.getLetter().clone()
                self.copyLetter(letter.getLetter())
                letter.copyLetter(l)
    
    def activate(self):
        '''
        Activate this letter.
        
        Allow the Letter to be dragged.
        '''
        
        self.deactivate()
        
        self.handlerId = self.connect("drag_data_get", self.dragLetter)
        self.drag_source_set(gtk.gdk.BUTTON1_MASK, [( "image/x-xpixmap", 0, 81 )], gtk.gdk.ACTION_COPY)
        
        self.destHandlerId = self.connect("drag_data_received", self.letterDragged);
        self.drag_dest_set(gtk.DEST_DEFAULT_MOTION | gtk.DEST_DEFAULT_HIGHLIGHT | gtk.DEST_DEFAULT_DROP, [( "image/x-xpixmap", 0, 81 )], gtk.gdk.ACTION_COPY)
        return True
    
    def deactivate(self):
        '''
        Deactivate this letter.
        
        Disallow the Letter to be dragged.
        '''
        
        if (self.handler_is_connected(self.handlerId)):
            self.disconnect(self.handlerId)
        if (self.handler_is_connected(self.destHandlerId)):
            self.disconnect(self.destHandlerId)
        self.drag_source_unset()
        self.drag_dest_unset()
        return True
    
    def refresh(self):
        '''
        Refresh colors on this tile
        '''
        
        self.set_label( self.getLetter() )
        self.setBackground()
        
    
    def set_label(self, letter):
        '''
        Set the Letter/score label on the Tile
        
        @param letter: Letter
        @see: L{pyscrabble.game.pieces.Letter}
        '''
        widget = self.get_child()
        if (widget == None):
            widget = gtk.Label()
        else:
            self.remove(widget)
        
        l = letter.getLetter()
        s = str(letter.getScore())
        o = manager.OptionManager()
        if letter.isBlank():
            l = ""
            if o.get_default_bool_option(USE_COLOR_BLANK_TILE, True):
                l = """<span foreground="%s">%s</span>""" % (o.get_default_option(COLOR_BLANK_TILE, DEFAULT_BLANK_TILE), l)
                s = """<span foreground="%s">%s</span>""" % (o.get_default_option(COLOR_BLANK_TILE, DEFAULT_BLANK_TILE), s)
        else:
            if o.get_default_bool_option(USE_COLOR_TEXT, True):
                l = """<span foreground="%s">%s</span>""" % (o.get_default_option(COLOR_TEXT, DEFAULT_COLOR_TEXT), l)
                s = """<span foreground="%s">%s</span>""" % (o.get_default_option(COLOR_TEXT, DEFAULT_COLOR_TEXT), s)
        
        if o.get_default_bool_option(OPTION_TEXT_BOLD, False):
            l = """<span weight="bold">%s</span>""" % l
            s = """<span weight="bold">%s</span>""" % s
        
        if len(str(letter.getScore())) == 2:
            widget.set_markup("""%s <sub><span size="xx-small">%s</span></sub>""" % (l, s))
        else:
            widget.set_markup("""%s <sub><span size="x-small">%s</span></sub>""" % (l, s))
        
        self.add(widget)
        self.show_all()

        
        
       
# Class representing the GUI Game Board
class GameBoard(gtk.Table):
    '''
    The GameBoard class is the widget responsible for holding the tiles on the Board.  It is basically a
    gtk.Table on steroids that allows access to elements based on their x,y position.
    '''
    
    
    def __init__(self):
        '''
        Constructor
        '''
        
        gtk.Table.__init__(self,rows=15, columns=15, homogeneous = True)
        self.tiles = {} # Hold a reference to all tiles
        self.empty = True
    
    def activate(self):
        '''
        Activate each tile on the board
        
        @see: {pyscrabble.gui.pieces.GameTile}
        '''
        
        for tile in self.tiles.values():
            tile.activate()
    
    def deactivate(self):
        '''
        Deactivate each tile on the board
        
        @see: {pyscrabble.gui.pieces.GameTile}
        '''
        
        for tile in self.tiles.values():
            tile.deactivate()
    
    def put(self, widget, x, y):
        '''
        Add a widget to the board
        
        @param widget: Widget
        @param x: X position
        @param y: Y position
        '''
        
        # If there is a tile in the space, destroy it
        if (self.tiles.has_key((x,y))):
            self.tiles[(x,y)].destroy()

        self.attach(widget, x, x+1, y, y+1)
        self.tiles[(x,y)] = widget
    
    def hasMove(self, move):
        '''
        Check to see if the board has this move.
        
        @param move: Move
        '''
        
        for l, x, y in move.getTiles():
            if self.tiles.has_key( (x,y) ):
                if (self.tiles[(x,y)].getLetter() != l):
                    return False
            elif not self.tiles.has_key( (x,y) ):
                return False
        
        return True
        
    
    def putLetter(self, letter, x, y, set_bg):
        '''
        Put a Letter on a Tile on the board
        
        This is different from addinganewWidgettotheboard. import 
        
        This assumes that a GameTile already exists at (x,y) and that
        we are going to change the Letter on that Tile
        
        @param letter: Letter
        @param x: x position
        @param y: y position
        @param set_bg: True to set COLOR_RECENT_TILE as background color
        @see: L{pyscrabble.gui.pieces.GameTile}
        @see: L{pyscrabble.game.pieces.Letter}
        '''
        
        self.empty = False
        self.tiles[(x,y)].putLetter(letter)
        self.tiles[(x,y)].deactivate()
        
        if set_bg:
            o = manager.OptionManager()
            self.tiles[(x,y)].setBackground(o.get_default_option(COLOR_RECENT_TILE, DEFAULT_RECENT_TILE))
    
    def moveTouching(self, move, onBoard):
        '''
        Check if this move is touching another on the board
        
        @param move: Move
        @param onBoard: Tiles on board
        @return: True if this move is touching another move, or if there are no other moves on the board
        '''
        
        #if self.isEmpty():
        #    return True
        
        for letter, x, y in move.getTiles():
            
            _l, _x, _y = self.getNextHorizontalLetter(x, y)
            if self.hasNextHorizontalLetter(x,y) and not onBoard.hasLetterAt(_x,_y):
                return True
            
            _l, _x, _y = self.getNextVerticalLetter(x, y)
            if self.hasNextVerticalLetter(x,y) and not onBoard.hasLetterAt(_x,_y):
                return True
            
            _l, _x, _y = self.getPreviousHorizontalLetter(x, y)
            if self.hasPreviousHorizontalLetter(x,y) and not onBoard.hasLetterAt(_x,_y):
                return True
            
            _l, _x, _y = self.getPreviousVerticalLetter(x, y)
            if self.hasPreviousVerticalLetter(x,y) and not onBoard.hasLetterAt(_x,_y):
                return True
        
        return False
        
    
    def isEmpty(self):
        '''
        Check if the board is empty
        
        @return: True if the board is empty
        '''
        return self.empty
    
    def getTilesAtX(self, _x):
        '''
        Return all tiles that have C{_x} in common
        
        @param _x: X position
        @return: A List of all tiles that have C{_x} in common
        '''
        
        list = []
        for x,y in self.tiles.keys():
            if x == _x:
                if (self.tiles.has_key((x, y))):
                    if self.tiles[(x, y)].getLetter() != None:
                        list.append( (self.tiles[x,y], x, y) )
        
        return list
    
    def getTilesAtY(self, _y):
        '''
        Return all tiles that have C{_y} in common
        
        @param _y: Y position
        @return: A List of all tiles that have C{_y} in common
        '''
        
        list = []
        for x,y in self.tiles.keys():
            if y == _y:
                if (self.tiles.has_key((x, y))):
                    if self.tiles[(x, y)].getLetter() != None:
                        list.append( (self.tiles[x,y], x, y) )
        
        return list
        
    
    def get(self, x, y):
        '''
        Get a Tile at this (x,y) position or None if a Tile is not there
        
        @param x: X position
        @param y: Y position
        @return: GameTile at this (x,y) position or None
        '''
        
        if (self.tiles.has_key((x,y))):
            return self.tiles[(x,y)]
        else:
            return None
    
    def hasNextHorizontalLetter(self, x, y):
        '''
        Check if there is a Letter on the Tile at (x+1,y)
        
        @param x: X position
        @param y: Y position
        @return: True if there is a Letter on the Tile at (x+1, y)
        '''
        
        if (self.tiles.has_key((x+1, y))):
            if self.tiles[(x+1, y)].getLetter() != None:
                return True
        return False
    
    def hasNextVerticalLetter(self, x, y):
        '''
        Check if there is a Letter on the Tile at (x,y+1)
        
        @param x: X position
        @param y: Y position
        @return: True if there is a Letter on the Tile at (x, y+1)
        '''
        
        if (self.tiles.has_key((x, y+1))):
            if self.tiles[(x, y+1)].getLetter() != None:
                return True
        return False
    
    def getNextVerticalLetter(self, x, y):
        '''
        Return the Letter on the Tile at (x,y+1)
        
        @param x: X position
        @param y: Y position
        @return: True if there is a Letter on the Tile at (x, y+1) or None
        '''
        
        if (self.tiles.has_key((x, y+1))):
            return (self.tiles[(x, y+1)], x, y+1)
        else:
            return None,None,None
    
    def getNextHorizontalLetter(self, x, y):
        '''
        Return the Letter on the Tile at (x+1,y)
        
        @param x: X position
        @param y: Y position
        @return: True if there is a Letter on the Tile at (x+1,y) or None
        '''
        
        if (self.tiles.has_key((x+1, y))):
            return (self.tiles[(x+1, y)], x+1, y)
        else:
            return None,None,None
    
    def hasPreviousHorizontalLetter(self, x, y):
        '''
        Check if there is a Letter on the Tile at (x-1,y)
        
        @param x: X position
        @param y: Y position
        @return: True if there is a Letter on the Tile at (x-1, y)
        '''
        
        if (self.tiles.has_key((x-1, y))):
            if self.tiles[(x-1, y)].getLetter() != None:
                return True
        return False
    
    def hasPreviousVerticalLetter(self, x, y):
        '''
        Check if there is a Letter on the Tile at (x,y-1)
        
        @param x: X position
        @param y: Y position
        @return: True if there is a Letter on the Tile at (x, y-1)
        '''
        
        if (self.tiles.has_key((x, y-1))):
            if self.tiles[(x, y-1)].getLetter() != None:
                return True
        return False
    
    def getPreviousVerticalLetter(self, x, y):
        '''
        Return the Letter on the Tile at (x,y-1)
        
        @param x: X position
        @param y: Y position
        @return: True if there is a Letter on the Tile at (x, y-1) or None
        '''
        
        if (self.tiles.has_key((x, y-1))):
            return (self.tiles[(x, y-1)], x, y-1)
        else:
            return None,None,None
    
    def getPreviousHorizontalLetter(self, x, y):
        '''
        Return the Letter on the Tile at (x-1,y)
        
        @param x: X position
        @param y: Y position
        @return: True if there is a Letter on the Tile at (x-1,y) or None
        '''
        
        if (self.tiles.has_key((x-1, y))):
            return (self.tiles[(x-1, y)], x-1, y)
        else:
            return None,None,None
    
    def isEmpty(self):
        '''
        Check whether the board has any moves on it
        
        @return True if the board has no moves
        '''
        return self.empty
    
    def getMovesAtXY(self, x, y):
        '''
        Get moves at X and Y positions
        
        @param x:
        @param y:
        '''
        moves = []
        
        h = Move()
        v = Move()
        h.addMove( self.get(x,y).getLetter(), x, y)
        v.addMove( self.get(x,y).getLetter(), x, y)
        
        _x = x
        _y = y
        while self.hasNextHorizontalLetter(_x, _y):
            item, _x, _y = self.getNextHorizontalLetter(_x, _y)
            h.addMove(item.getLetter(), _x, _y)
        
        _x = x
        _y = y
        while self.hasPreviousHorizontalLetter(_x, _y):
            item, _x, _y = self.getPreviousHorizontalLetter(_x, _y)
            h.addMove(item.getLetter(), _x, _y)
        
        h.sort()
        if h.length() > 1:
            moves.append(h)
        
        
        _x = x
        _y = y
        while self.hasNextVerticalLetter(_x, _y):
            item, _x, _y = self.getNextVerticalLetter(_x, _y)
            v.addMove(item.getLetter(), _x, _y)
        
        _x = x
        _y = y
        while self.hasPreviousVerticalLetter(_x, _y):
            item, _x, _y = self.getPreviousVerticalLetter(_x, _y)
            v.addMove(item.getLetter(), _x, _y)
        
        v.sort()
        if v.length() > 1:
            moves.append(v)
        
        return moves
    
    def clearRecentMove(self, move):
        '''
        Set recent move tiles to normal
        
        @param move: Move tiles
        '''
        for letter,x,y in move.getTiles():
            self.tiles[(x,y)].refresh()
    
    def refresh(self):
        '''
        Refresh the board
        '''

        for tile in self.tiles.itervalues():
            tile.refresh()
    
    def clearArrows(self):
        '''
        Remove arrows
        '''
        for tile in self.tiles.itervalues():
            tile.removeArrow()
        
        
        
        
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.