From 958f0fcb437be76c2b420e84b138c944ae47847a Mon Sep 17 00:00:00 2001 From: Gerard J. Cerchio Date: Wed, 28 Nov 2007 00:54:37 +0000 Subject: Initial import --- (limited to 'boardwidget.py') diff --git a/boardwidget.py b/boardwidget.py new file mode 100755 index 0000000..373a898 --- /dev/null +++ b/boardwidget.py @@ -0,0 +1,231 @@ +import logging +import cairo +import gobject +import gtk + +import game + + +logger = logging.getLogger('PlayGo-activity.gridwidget') + + +class BoardWidget(gtk.EventBox): + "Gtk widget for drawing the graphical board.""" + + __gsignals__ = { + 'insert-requested': (gobject.SIGNAL_RUN_FIRST, None, [int]), + } + + def __init__( self, aBoard ): + + gtk.EventBox.__init__( self ) + + self.output = gtk.DrawingArea() + self.set_property('child', self.output) + + self.output.connect('expose-event', self.expose_cb) + self.add_events(gtk.gdk.POINTER_MOTION_MASK) + + self.connect('button-release-event', self.__class__.button_release_cb) + self.connect('motion-notify-event', self.__class__.motion_cb) + + self.drawCoords = 1 + self.columns = aBoard.size + self.rows = aBoard.size + self.lastUnit = 0 + self.myBoard = aBoard + + self.lastColor = 1 + + # get the bitmap for genuine simulated wooden board + input = open("./images/board.gif") + imagebuf = input.read() + pixbufloader = gtk.gdk.PixbufLoader() + pixbufloader.write(imagebuf) + pixbufloader.close() + self.pixBoard = pixbufloader.get_pixbuf() + + # get the bitmap for genuine simulated white stone + input = open("./images/white.gif") + imagebuf = input.read() + pixbufloader = gtk.gdk.PixbufLoader() + pixbufloader.write(imagebuf) + pixbufloader.close() + self.pixWhite = pixbufloader.get_pixbuf() + + # get the bitmap for genuine simulated black stone + input = open("./images/black.gif") + imagebuf = input.read() + pixbufloader = gtk.gdk.PixbufLoader() + pixbufloader.write(imagebuf) + pixbufloader.close() + self.pixBlack = pixbufloader.get_pixbuf() + + def check_coord (self, i, j): + return i >= 0 and i < self.rows and j >= 0 and j < self.columns + + def insert(self, column, value): + """Return: + None : no winner + 0, 1: player 0/1 wins the game + """ + discs = [row[column] for row in self.grid] + + if -1 not in discs: + raise ValueError('Column is full') + + row = self.rows - list(reversed(discs)).index(-1) - 1 + self.grid[row][column] = value + + return self.check_winner(row, column, value) + + + def draw_background(self, rect, unit, ctx): + + ct = gtk.gdk.CairoContext(ctx) + ct.set_source_pixbuf(self.pixBoard,0,0) + ctx.paint() + ctx.stroke() + + + def draw_lines(self, rect, unit, ctx): + + # single width balck lines + ctx.set_line_width(1) + ctx.set_source_rgba(0, 0, 0, 1) + + for i in xrange(self.rows + 1): + ctx.move_to( unit, i * unit) + ctx.line_to(self.columns * unit, i * unit ) + + for i in xrange(self.columns + 1): + ctx.move_to(i * unit, unit ) + ctx.line_to(i * unit, self.rows * unit) + + ctx.stroke() + + # star point coords per board size + if self.columns == 19 : + seq = [ 4, 10, 16 ] + elif self.columns == 13 : + seq = [ 4, 7, 10 ] + elif self.columns == 9 : + seq = [ 3, 7 ] + # set the middle singleton + ctx.arc( unit * 5, unit * 5, 3, 0, -1e-10) + ctx.fill_preserve() + ctx.stroke() + + # stroke in the star points + #TODO: adjust size for teeny boards + for x in seq : + for y in seq : + ctx.arc( unit * x, unit * y, 3, 0, -1e-10) + ctx.fill_preserve() + ctx.stroke() + + + + def draw_stone(self, x, y, color, unit, ctx): + + x = x + 1 + y = y + 1 + ct = gtk.gdk.CairoContext(ctx) + if color == 0 : + ct.set_source_pixbuf(self.pixBlackSized, unit*x - unit/2, unit*y - unit/2, ) + else : + ct.set_source_pixbuf(self.pixWhiteSized, unit*x - unit/2, unit*y - unit/2, ) + + ctx.paint() + + def draw_stones( self, ctx ): + + for x in xrange(self.rows): + for y in xrange(self.columns): + + point = self.myBoard.getPoint( x, y ) + + if ( point == 1 ) : + self.draw_stone( x, y, 1, self.lastUnit, ctx ) + elif ( point == 2 ) : + self.draw_stone( x, y, 0, self.lastUnit, ctx ) + + ctx.stroke() + + def get_mouse_event_col(self, event): + + unit, x0, y0 = self.get_coordinates(self.get_allocation()) + col = ( event.x - x0 ) / unit + row = ( event.y - y0 ) / unit + return int(row), int(col) + + def motion_cb(self, event): + + col = self.get_mouse_event_col(event) + + def button_release_cb(self, event): + + self.motion_cb(event) + row, col = self.get_mouse_event_col(event) + + self.myBoard.setPointi( col, row, self.lastColor ) + if self.lastColor == 1: + self.lastColor = 2 + else : + self.lastColor = 1 + + self.window.invalidate_rect(self.get_allocation(), True) + #self.emit('insert-requested', col) + + def queue_draw(self): + self.output.queue_draw() + + def get_coordinates(self, rect): + """Returns tuple (unit size, origin x, origin y) suitable for drawing + a grid within @rect.""" + + if rect.height / float(self.rows) < rect.width / float(self.columns): + # wide + unit = rect.height / float(self.rows) + x0 = rect.x + (rect.width - self.columns * unit) / 2.0 + y0 = rect.y + else: + # narrow + unit = rect.width / float(self.columns) + x0 = rect.x + y0 = rect.y + (rect.height - self.rows * unit) / 2.0 + + # now shrink the size for a 1 unit boarder + unit = unit - unit / self.rows + + return unit, x0, y0 + + def draw(self, rect, ctx): + """Draw a grid using the cairo context @ctx within the rectangle + @rect.""" + + ctx.save() + ctx.set_line_cap(cairo.LINE_CAP_ROUND) + unit, x0, y0 = self.get_coordinates(rect) + + # I could not find the resize event so... + if self.lastUnit != unit : + self.pixBlackSized = self.pixBlack.scale_simple( int(unit), int(unit), gtk.gdk.INTERP_BILINEAR ) + self.pixWhiteSized = self.pixWhite.scale_simple( int(unit), int(unit), gtk.gdk.INTERP_BILINEAR ) + self.lastUnit = unit +# bx, by = self.pixBoard.get_size() +# if rect.height > by : +# self.pixBoard = self.pixBoard.scaleSimple( bx, by, gtk.gdk.INTERP_BILINEAR ) + + ctx.translate( x0, y0 ) + self.draw_background( rect, unit, ctx ) + self.draw_lines( rect, unit, ctx ) + self.draw_stones( ctx ) + ctx.restore() + + + def expose_cb(self, widget, event): + + ctx = widget.window.cairo_create() + rect = self.get_allocation() + self.draw(rect, ctx) -- cgit v0.9.1