def __init__ (self, row, col):
self.pos = (row, col)
+# exception when a word number is not found in the grid
+class NoNumberException (Exception):
+ def __init__ (self, num):
+ self.num = num
+
# exception when no words are present in the grid
class NoWordsException (Exception):
def __init__ (self):
return clues
+ # getting an across word at a number (note that the grid should be
+ # frozen for calling this otherwise a FrozenGridException will be raised)
+ def get_word_across_at_num (self, num):
+ # assert that the grid is frozen
+ self.assert_frozen_grid ()
+
+ # traverse the grid
+ for row in range (self.rows):
+ for col in range (self.cols):
+ if self.data[row][col].numbered == num:
+ word = self.get_word_across (row, col)
+ return word
+
+ # if number is not found
+ raise NoNumberException (num)
+
+ # getting a down word at a number (note that the grid should be frozen
+ # for calling this otherwise a FrozenGridException will be raised)
+ def get_word_down_at_num (self, num):
+ # assert that the grid is frozen
+ self.assert_frozen_grid ()
+
+ # traverse the grid
+ for row in range (self.rows):
+ for col in range (self.cols):
+ if self.data[row][col].numbered == num:
+ word = self.get_word_down (row, col)
+ return word
+
+ # if number is not found
+ raise NoNumberException (num)
+
+ # getting the position of a number on the grid (note that the grid should
+ # be frozen for calling this otherwise a FrozenGridException will be raised)
+ def get_position_of_num (self, num):
+ # assert that the grid is frozen
+ self.assert_frozen_grid ()
+
+ # traverse the grid
+ for row in range (self.rows):
+ for col in range (self.cols):
+ if self.data[row][col].numbered == num:
+ return (row, col)
+
+ # if number is not found
+ raise NoNumberException (num)
+
# getting a down word at a position
def get_word_down (self, row, col):
# if index is out of bounds
self.gtk_main_quit ()
- # callback for puzzle grid mouse button release event
- def on_puzzlegrid_button_press_event (self, drawarea, event):
- # set the focus on the puzzle grid
- if self.puzzle:
- self.window.set_focus (drawarea)
+ # function to set the selected row/col based on the number clicked
+ # on the clues list and also set the typing mode
+ def set_selection_of_num (self, num, across = True):
+ # get the row, col of the word
+ row, col = self.puzzle.get_position_of_num (num)
+
+ # set the selected row and column
+ self.selected_row = row
+ self.selected_col = col
+ # set typing mode to across
+ if across is True:
+ self.typing_mode = self.ACROSS
+ else:
+ self.typing_mode = self.DOWN
- col = int (event.x / 30)
- row = int (event.y / 30)
+ # update the puzzle grid
+ puzgrid = self.ui.get_object ("puzzlegrid")
- if col < self.puzzle.cols and row < self.puzzle.rows:
- if (self.puzzle.data[row][col].occupied_across is True or
- self.puzzle.data[row][col].occupied_down is True):
- self.selected_col = col
- self.selected_row = row
- drawarea.queue_draw ()
+ # set focus to the puzzle grid
+ self.window.set_focus (puzgrid)
+
+ puzgrid.queue_draw ()
+
+ # callback for tree view "across" being activated
+ # activated - when double clicked or enter pressed
+ def on_tree_clues_across_row_activated (self, view, path, column):
+ # get the across list object
+ across_list = self.ui.get_object ("clues_across")
+ # get the number of the across word
+ anum = int (across_list.get_value (across_list.get_iter (path), 0))
+
+ self.set_selection_of_num (anum)
return False
+ # callback for tree view "down" being activated
+ # activated - when double clicked or enter pressed
+ def on_tree_clues_down_row_activated (self, view, path, column):
+ # get the down list object
+ down_list = self.ui.get_object ("clues_down")
+ # get the number of the down word
+ dnum = int (down_list.get_value (down_list.get_iter (path), 0))
+
+ self.set_selection_of_num (dnum, False)
+
# moving the current selection in grid by one up or down
def move_selection_updown (self, step):
# increase or reduce the row by step until an occupied grid is found
# reset selection
else:
self.selected_col = old_sel_col
+ elif self.typing_mode == self.DOWN:
+ # prevent deleting characters when there is a gap
+ old_sel_row = self.selected_row
+ self.move_selection_updown (-1)
+ # only if there is no block inbetween delete
+ if abs (self.selected_row - old_sel_row) <= 1:
+ self.puzzle.data[self.selected_row][self.selected_col].guess = None
+ # reset selection
+ else:
+ self.selected_row = old_sel_row
+
+ # callback for puzzle grid mouse button release event
+ def on_puzzlegrid_button_press_event (self, drawarea, event):
+ # set the focus on the puzzle grid
+ if self.puzzle:
+ self.window.set_focus (drawarea)
+
+ col = int (event.x / 30)
+ row = int (event.y / 30)
+
+ if col < self.puzzle.cols and row < self.puzzle.rows:
+ if (self.puzzle.data[row][col].occupied_across is True or
+ self.puzzle.data[row][col].occupied_down is True):
+ self.selected_col = col
+ self.selected_row = row
+ drawarea.queue_draw ()
+
+ return False
# callback for puzzle grid key release event
def on_puzzlegrid_key_press_event (self, drawarea, event):
if self.puzzle:
- key = gtk.gdk.keyval_name (event.keyval)
+ key = gtk.gdk.keyval_name (event.keyval).lower ()
- if event.state == gtk.gdk.SHIFT_MASK and key == "Up":
+ if event.state == gtk.gdk.SHIFT_MASK and key == "up":
# reduce the row by 1 until you find an occupied grid and not a
# black block
self.move_selection_updown (-1)
self.typing_mode = self.DOWN
drawarea.queue_draw ()
- elif event.state == gtk.gdk.SHIFT_MASK and key == "Down":
+ elif event.state == gtk.gdk.SHIFT_MASK and key == "down":
# increase the row by 1 until you find an occupied grid and not a
# black block
self.move_selection_updown (1)
self.typing_mode = self.DOWN
drawarea.queue_draw ()
- elif event.state == gtk.gdk.SHIFT_MASK and key == "Right":
+ elif event.state == gtk.gdk.SHIFT_MASK and key == "right":
# increase the column by 1 until you find an occupied grid and not
# a black block
self.move_selection_across (1)
self.typing_mode = self.ACROSS
drawarea.queue_draw ()
- elif event.state == gtk.gdk.SHIFT_MASK and key == "Left":
+ elif event.state == gtk.gdk.SHIFT_MASK and key == "left":
# decrease the column by 1 until you find an occupied grid and not
# a black block
self.move_selection_across (-1)
self.set_guess (key)
drawarea.queue_draw ()
# if it is the delete key then delete character at selected row/col
- elif key == "Delete":
+ elif key == "delete" or key == "space":
self.puzzle.data[self.selected_row][self.selected_col].guess = None
drawarea.queue_draw ()
# if it is backspace key then delete character at previous row/col
# size the area
drawarea.set_size_request (self.puzzle.cols*30+2, self.puzzle.rows*30+2)
- #numlayout = gtk.PrintContext().create_pango_layout ()
- #numlayout.set_font_description (pango.FontDescription ("Sans 8"))
ctx = drawarea.window.cairo_create ()
ctx.set_line_width (1.5)
</columns>
</object>
<object class="GtkWindow" id="mainwindow">
- <property name="width_request">640</property>
- <property name="height_request">480</property>
+ <property name="width_request">720</property>
+ <property name="height_request">500</property>
<property name="visible">True</property>
<property name="title" translatable="yes">GetAClue player</property>
<property name="default_width">640</property>
</packing>
</child>
<child>
- <object class="GtkHBox" id="hbox1">
+ <object class="GtkHPaned" id="hpaned1">
<property name="visible">True</property>
+ <property name="can_focus">True</property>
<child>
<object class="GtkScrolledWindow" id="scrolledwindow3">
+ <property name="width_request">420</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hscrollbar_policy">automatic</property>
</child>
</object>
<packing>
- <property name="position">0</property>
+ <property name="resize">False</property>
+ <property name="shrink">True</property>
</packing>
</child>
<child>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="position">180</property>
+ <property name="position_set">True</property>
<child>
<object class="GtkScrolledWindow" id="scrolledwindow1">
<property name="visible">True</property>
<child>
<object class="GtkTreeView" id="tree_clues_across">
<property name="width_request">80</property>
- <property name="height_request">150</property>
+ <property name="height_request">250</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="model">clues_across</property>
<property name="headers_clickable">False</property>
<property name="search_column">0</property>
+ <signal name="row_activated" handler="on_tree_clues_across_row_activated"/>
<child>
<object class="GtkTreeViewColumn" id="number">
<property name="title">Number</property>
<child>
<object class="GtkTreeView" id="tree_clues_down">
<property name="width_request">80</property>
- <property name="height_request">150</property>
+ <property name="height_request">250</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="model">clues_down</property>
<property name="headers_clickable">False</property>
<property name="search_column">0</property>
+ <signal name="row_activated" handler="on_tree_clues_down_row_activated"/>
<child>
<object class="GtkTreeViewColumn" id="downnum">
<property name="title">Number</property>
</child>
</object>
<packing>
- <property name="position">1</property>
+ <property name="resize">True</property>
+ <property name="shrink">True</property>
</packing>
</child>
</object>