452410627514265538c31ae052adb98653fd4018
[getaclue.git] / player_mainwindow.py
1 # Get A Clue (C) 2010 V. Harishankar
2 # Crossword puzzle maker program
3 # Licensed under the GNU GPL v3
4
5 # Main window class for GetAClue player
6
7 import cPickle
8 import pygtk
9 pygtk.require20 ()
10 import gtk
11 import pango
12 import crosswordpuzzle
13
14 class MainWindow:
15 def gtk_main_quit (self, *args):
16 gtk.main_quit ()
17
18 # callback for puzzle grid mouse button release event
19 def on_puzzlegrid_button_release_event (self, drawarea, event):
20 self.window.set_focus (drawarea)
21 return True
22
23 # moving the current selection in grid by one up or down
24 def move_selection_updown (self, step):
25 # increase or reduce the row by step until an occupied grid is found
26 # black block
27 last_occupied_row = self.selected_row
28 while True:
29 self.selected_row += step
30 if self.selected_row < 0 or self.selected_row >= self.puzzle.rows:
31 self.selected_row = last_occupied_row
32 break
33 if (self.puzzle.data[self.selected_row][self.selected_col].occupied_across is True
34 or self.puzzle.data[self.selected_row][self.selected_col].occupied_down is True):
35 break
36
37 # moving the current selection in grid by one across either way
38 def move_selection_across (self, step):
39 # increase or reduce the row by step until an occupied grid is found
40 # black block
41 last_occupied_col = self.selected_col
42 while True:
43 self.selected_col += step
44 if self.selected_col < 0 or self.selected_col >= self.puzzle.cols:
45 self.selected_col = last_occupied_col
46 break
47 if (self.puzzle.data[self.selected_row][self.selected_col].occupied_across is True
48 or self.puzzle.data[self.selected_row][self.selected_col].occupied_down is True):
49 break
50
51 # callback for puzzle grid key release event
52 def on_puzzlegrid_key_press_event (self, drawarea, event):
53 key = gtk.gdk.keyval_name (event.keyval)
54
55 if event.state == gtk.gdk.SHIFT_MASK and key == "Up":
56 # reduce the row by 1 until you find an occupied grid and not a
57 # black block
58 self.move_selection_updown (-1)
59 drawarea.queue_draw ()
60 elif event.state == gtk.gdk.SHIFT_MASK and key == "Down":
61 # increase the row by 1 until you find an occupied grid and not a
62 # black block
63 self.move_selection_updown (1)
64 drawarea.queue_draw ()
65 elif event.state == gtk.gdk.SHIFT_MASK and key == "Right":
66 # increase the column by 1 until you find an occupied grid and not
67 # a black block
68 self.move_selection_across (1)
69 drawarea.queue_draw ()
70 elif event.state == gtk.gdk.SHIFT_MASK and key == "Left":
71 # decrease the column by 1 until you find an occupied grid and not
72 # a black block
73 self.move_selection_across (-1)
74 drawarea.queue_draw ()
75 return False
76
77 # puzzle grid focus in event
78 def on_puzzlegrid_focus_out_event (self, drawarea, event):
79 col = drawarea.window.get_colormap ().alloc_color (gtk.gdk.Color ("gray"))
80 drawarea.window.set_background (col)
81
82 return False
83
84 # puzzle grid focus out event
85 def on_puzzlegrid_focus_in_event (self, drawarea, event):
86 col = drawarea.window.get_colormap ().alloc_color (gtk.gdk.Color ("white"))
87 drawarea.window.set_background (col)
88 return False
89
90 # callback for drawing the puzzle grid
91 def on_puzzlegrid_expose_event (self, drawarea, event):
92 # if puzzle is loaded
93 if self.puzzle:
94 # size the area
95 drawarea.set_size_request (self.puzzle.cols*30+2, self.puzzle.rows*30+2)
96
97 #numlayout = gtk.PrintContext().create_pango_layout ()
98 #numlayout.set_font_description (pango.FontDescription ("Sans 8"))
99 ctx = drawarea.window.cairo_create ()
100 ctx.set_line_width (1.5)
101
102 # run through the grid
103 for row in range (self.puzzle.rows):
104 for col in range (self.puzzle.cols):
105 # (re)set foreground color
106 ctx.set_source_rgb (0, 0, 0)
107 # if the area is not occupied
108 if (self.puzzle.data[row][col].occupied_across is False and
109 self.puzzle.data[row][col].occupied_down is False):
110 ctx.rectangle (col*30, row*30, 30, 30)
111 ctx.fill ()
112 else:
113 # if selected row/column
114 if row == self.selected_row and col == self.selected_col:
115 ctx.set_source_rgb (1, 1, 0.6)
116 ctx.rectangle (col*30,row*30, 30, 30)
117 ctx.fill ()
118 else:
119 ctx.set_source_rgb (1, 1, 1)
120 ctx.rectangle (col*30, row*30, 30, 30)
121 ctx.fill ()
122 ctx.set_source_rgb (0, 0, 0)
123 ctx.rectangle (col*30, row*30, 30, 30)
124 ctx.stroke ()
125
126 # if numbered
127 if self.puzzle.data[row][col].numbered <> 0:
128 ctx.set_source_rgb (0, 0, 0)
129 ctx.select_font_face ("Sans 7")
130 ctx.move_to (col*30+2, row*30+10)
131 ctx.show_text (str(self.puzzle.data[row][col].numbered))
132
133 return False
134
135 def load_clues (self):
136 # get the clues list store objects
137 across = self.ui.get_object ("clues_across")
138 down = self.ui.get_object ("clues_down")
139 across.clear ()
140 down.clear ()
141
142 # if puzzle is loaded
143 if self.puzzle:
144 clues_across = self.puzzle.get_clues_across ()
145 clues_down = self.puzzle.get_clues_down ()
146 # insert the numbers and the clues for across
147 for word, clue in clues_across:
148 across.append ([str(self.puzzle.data[word[1]][word[2]].numbered),
149 clue])
150 # insert the numbers and the clues for down
151 for word, clue in clues_down:
152 down.append ([ str(self.puzzle.data[word[1]][word[2]].numbered),
153 clue])
154
155 def open_file (self, file):
156 self.puzzle = cPickle.load (open (file, "rb"))
157 self.selected_row = 0
158 self.selected_col = 0
159 self.window.set_title ("GetAClue player - " + file)
160 self.load_clues ()
161
162 def __init__ (self, file_to_play = None):
163 # load the user interface
164 self.ui = gtk.Builder ()
165 self.ui.add_from_file ("playerwindow.glade")
166
167 # window object
168 self.window = self.ui.get_object ("mainwindow")
169 self.window.show ()
170
171 # set the cell renderer
172 cell = gtk.CellRendererText ()
173 tree_acol1 = self.ui.get_object ("tree_clues_across").get_column (0)
174 tree_acol2 = self.ui.get_object ("tree_clues_across").get_column (1)
175 tree_acol1.pack_start (cell)
176 tree_acol1.add_attribute (cell, "text", 0)
177 tree_acol2.pack_start (cell)
178 tree_acol2.add_attribute (cell, "text", 1)
179
180 tree_down = self.ui.get_object ("tree_clues_down")
181 tree_dcol1 = self.ui.get_object ("tree_clues_down").get_column (0)
182 tree_dcol2 = self.ui.get_object ("tree_clues_down").get_column (1)
183 tree_dcol1.pack_start (cell)
184 tree_dcol1.add_attribute (cell, "text", 0)
185 tree_dcol2.pack_start (cell)
186 tree_dcol2.add_attribute (cell, "text", 1)
187
188 # connect the signals
189 self.ui.connect_signals (self)
190
191 # set the puzzle to None
192 self.puzzle = None
193
194 # open the file if it is set
195 if file_to_play:
196 self.open_file (file_to_play)
197
198 gtk.main ()
199
200