diff --git a/justcheckers/game/board.py b/justcheckers/game/board.py
index 2a0ef98..7a772b3 100644
--- a/justcheckers/game/board.py
+++ b/justcheckers/game/board.py
@@ -313,17 +313,13 @@ class Board(object):
# TODO: Implement the suicide game setup.
pass
- # /**
- # * Returns a string to represent the board state. This string is formatted
- # * for use as a simple board display in the command window.
- # *
- # * Legend ## - White space which the piece can not move on to. __ -
- # * An empty space. LP - A light pawn. LK - A light king. DP - A dark pawn.
- # * DK - A dark king.
- # *
- # * @return A string representing the current board state.
- # */
def __str__(self):
+ """
+ Override __str__ to get back an elegant unicode representation of the board.
+
+ :returns: A text representation of the current state of the board.
+ """
+ # TODO Fix up string building setup. Separate into smaller component functions.
# Prepare for output with a nice looking to banner.
output = " "
@@ -350,7 +346,7 @@ class Board(object):
else:
output = u'{}{} '.format(output, row + 1)
- # // Get current row's state.
+ # Get current row's state.
for col in xrange(0, self.board_size):
output = output + output_atom[self._board[row][col]]
diff --git a/justcheckers/ui/game_screen_landscape.xml b/justcheckers/ui/game_screen_landscape.xml
deleted file mode 100644
index 7de7b5d..0000000
--- a/justcheckers/ui/game_screen_landscape.xml
+++ /dev/null
@@ -1,405 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/justcheckers/ui/game_screen_portrait.xml b/justcheckers/ui/game_screen_portrait.xml
deleted file mode 100644
index 8b82aed..0000000
--- a/justcheckers/ui/game_screen_portrait.xml
+++ /dev/null
@@ -1,407 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/justcheckers/ui/game_view.py b/justcheckers/ui/game_view.py
new file mode 100644
index 0000000..ab5d36f
--- /dev/null
+++ b/justcheckers/ui/game_view.py
@@ -0,0 +1,128 @@
+#
+# Copyright (c) 2014 Dorian Pula
+#
+# justCheckers is free software: you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation, either version 3 of the License,
+# or (at your option) any later version.
+#
+# justCheckers 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with justCheckers. If not, see .
+#
+# Please share and enjoy!
+#
+
+from PySide import QtGui
+
+from PySide.QtOpenGL import QGLWidget
+from OpenGL.GL import *
+from OpenGL.GLUT import *
+from OpenGL.GLU import *
+
+
+# TODO Borrowed from: http://biospud.blogspot.ca/2012/02/proof-of-concept-opengl-program-in.html
+def override(interface_class):
+ """
+ Method to implement Java-like derived class method override annotation.
+ Courtesy of mkorpela's answer at
+ http://stackoverflow.com/questions/1167617/in-python-how-do-i-indicate-im-overriding-a-method
+ """
+ def override(method):
+ assert(method.__name__ in dir(interface_class))
+ return method
+ return override
+
+
+# Install freeglut3 for the example.
+class SphereTestGLWidget(QGLWidget):
+ "GUI rectangle that displays a teapot"
+ @override(QGLWidget)
+ def initializeGL(self):
+ "runs once, after OpenGL context is created"
+ glEnable(GL_DEPTH_TEST)
+ glClearColor(1,1,1,0) # white background
+ glShadeModel(GL_SMOOTH)
+ glEnable(GL_COLOR_MATERIAL)
+ glMaterialfv(GL_FRONT, GL_SPECULAR, [1.0, 1.0, 1.0, 1.0])
+ glMaterialfv(GL_FRONT, GL_SHININESS, [50.0])
+ glLightfv(GL_LIGHT0, GL_POSITION, [1.0, 1.0, 1.0, 0.0])
+ glLightfv(GL_LIGHT0, GL_DIFFUSE, [1.0, 1.0, 1.0, 1.0])
+ glLightfv(GL_LIGHT0, GL_SPECULAR, [1.0, 1.0, 1.0, 1.0])
+ glLightModelfv(GL_LIGHT_MODEL_AMBIENT, [1.0, 1.0, 1.0, 0.0])
+ glEnable(GL_LIGHTING)
+ glEnable(GL_LIGHT0)
+ self.orientCamera()
+ glutInit()
+ gluLookAt(0, 0, -10, # camera
+ 0, 0, 0, # focus
+ 0, 1, 0) # up vector
+
+ @override(QGLWidget)
+ def paintGL(self):
+ "runs every time an image update is needed"
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
+ self.paintTeapot()
+
+ @override(QGLWidget)
+ def resizeGL(self, w, h):
+ "runs every time the window changes size"
+ glViewport(0, 0, w, h)
+ self.orientCamera()
+
+ def orientCamera(self):
+ "update projection matrix, especially when aspect ratio changes"
+ glPushAttrib(GL_TRANSFORM_BIT) # remember current GL_MATRIX_MODE
+ glMatrixMode(GL_PROJECTION)
+ glLoadIdentity()
+ gluPerspective (60.0, self.width()/float(self.height()), 1.0, 10.0)
+ glPopAttrib() # restore GL_MATRIX_MODE
+
+ def paintTeapot(self):
+ glPushAttrib(GL_POLYGON_BIT) # remember current GL_FRONT_FACE indictor
+ glFrontFace(GL_CW) # teapot polygon vertex order is opposite to modern convention
+ glColor3f(0.2,0.2,0.5) # paint it blue
+ glutSolidTeapot(3.0) # thank you GLUT tool kit
+ glPopAttrib() # restore GL_FRONT_FACE
+
+
+class GameBoardWidget(QGLWidget):
+ def __init__(self, parent):
+ QGLWidget.__init__(self, parent)
+
+
+class GameView(QtGui.QWidget):
+ """Info viewer for the game's license, etc."""
+
+ # TODO Setup functional testing with PySide.QtTest
+
+ def __init__(self):
+ super(GameView, self).__init__()
+ self.setup_components()
+
+ def setup_components(self):
+
+ self.game_board = SphereTestGLWidget(self)
+
+ exit_button = QtGui.QPushButton('Back to Menu', self)
+ exit_button.setFixedHeight(50)
+ exit_button.clicked.connect(self.switch_to_menu_view)
+
+ widget_layout = QtGui.QVBoxLayout(self)
+ widget_layout.addWidget(self.game_board)
+
+ # TODO Add in number of captured pieces and whose turn it is.
+
+ button_row = QtGui.QHBoxLayout(self)
+ button_row.addWidget(exit_button)
+
+ widget_layout.addLayout(button_row)
+
+ self.setLayout(widget_layout)
+
+ def switch_to_menu_view(self):
+ self.parentWidget().setCurrentIndex(0)
diff --git a/justcheckers/ui/menu_view.py b/justcheckers/ui/menu_view.py
index de5c1cc..eba3cf9 100644
--- a/justcheckers/ui/menu_view.py
+++ b/justcheckers/ui/menu_view.py
@@ -36,7 +36,9 @@ class MainMenuView(QtGui.QWidget):
"""Setup the components that make up the widget."""
self.init_justcheckers_logo()
- self.new_game = self.create_menu_button('&New Game')
+ self.new_game = self.create_menu_button('&New Game', enabled=True)
+ self.new_game.clicked.connect(self.switch_to_game_view)
+
self.open_game = self.create_menu_button('&Open Game')
self.save_game = self.create_menu_button('&Save Game')
@@ -83,5 +85,9 @@ class MainMenuView(QtGui.QWidget):
"""Exits the application."""
QtCore.QCoreApplication.instance().exit()
+ # TODO Remove magic numbers
def switch_to_about_view(self):
self.parentWidget().setCurrentIndex(1)
+
+ def switch_to_game_view(self):
+ self.parentWidget().setCurrentIndex(2)
diff --git a/justcheckers/ui/window.py b/justcheckers/ui/window.py
index 883e267..7d16bb1 100644
--- a/justcheckers/ui/window.py
+++ b/justcheckers/ui/window.py
@@ -20,6 +20,7 @@
from PySide import QtGui
+from justcheckers.ui.game_view import GameView
from justcheckers.ui.info_view import InfoView
from justcheckers.ui.menu_view import MainMenuView
from justcheckers.ui import util
@@ -50,6 +51,7 @@ class DesktopGameWindow(QtGui.QMainWindow):
self.view_stack = QtGui.QStackedWidget()
self.view_stack.addWidget(MainMenuView())
self.view_stack.addWidget(InfoView())
+ self.view_stack.addWidget(GameView())
self.setCentralWidget(self.view_stack)
def center(self):
diff --git a/requirements.txt b/requirements.txt
index aa30fc3..001bb95 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -3,6 +3,7 @@
# User interface
PySide==1.2.2
Markdown==2.4.1
+PyOpenGL
# Core logic
enum34==0.9.19