+GtkWidget *main_window;
+GtkListStore *across_store;
+GtkListStore *down_store;
+
+MainPlayerData app_data;
+
+/* update the clue items store */
+void update_clue_items ()
+{
+ gtk_list_store_clear (across_store);
+ gtk_list_store_clear (down_store);
+
+ /* if the puzzle is loaded */
+ if (app_data.is_loaded == true)
+ {
+ /* iterate through the puzzle grid and gte the clues */
+ for (int i = 0; i < app_data.puzzle.grid_size; i ++)
+ {
+ for (int j = 0; j < app_data.puzzle.grid_size; j ++)
+ {
+ /* if it is the start of an across word */
+ if (app_data.puzzle.start_across_word[i][j] != -1)
+ {
+ GtkTreeIter iter;
+
+ gtk_list_store_append (across_store, &iter);
+ gtk_list_store_set (across_store, &iter, 0,
+ app_data.puzzle.start_across_word[i][j],
+ 1, app_data.puzzle.clue_across[i][j],
+ -1);
+ }
+ /* if it is the start of a down word */
+ if (app_data.puzzle.start_down_word[i][j] != -1)
+ {
+ GtkTreeIter iter;
+ gtk_list_store_append (down_store, &iter);
+ gtk_list_store_set (down_store, &iter, 0,
+ app_data.puzzle.start_down_word[i][j],
+ 1, app_data.puzzle.clue_down[i][j],
+ -1);
+ }
+ }
+ }
+ }
+}
+
+/* slot for handling list down selection changed */
+gboolean on_down_list_selection_changed (GtkTreeSelection *sel,
+ GtkDrawingArea *area)
+{
+ GtkTreeIter iter;
+ GtkTreeModel* mod;
+
+ if (gtk_tree_selection_get_selected (sel, &mod, &iter))
+ {
+ guint sel_word_index;
+ gtk_tree_model_get (mod, &iter, 0, &sel_word_index, -1);
+ set_selection_to_word_start (&app_data, DOWN, sel_word_index);
+ }
+
+ gtk_widget_queue_draw_area (GTK_WIDGET(area), 0, 0,
+ app_data.puzzle.grid_size*GRID_PIXELS+10,
+ app_data.puzzle.grid_size*GRID_PIXELS+10);
+
+ return FALSE;
+
+}
+/* slot for handling list across selection changed */
+gboolean on_across_list_selection_changed (GtkTreeSelection *sel,
+ GtkDrawingArea *area)
+{
+ GtkTreeIter iter;
+ GtkTreeModel* mod;
+
+ if (gtk_tree_selection_get_selected (sel, &mod, &iter))
+ {
+ guint sel_word_index;
+ gtk_tree_model_get (mod, &iter, 0, &sel_word_index, -1);
+ set_selection_to_word_start (&app_data, ACROSS, sel_word_index);
+ }
+
+ gtk_widget_queue_draw_area (GTK_WIDGET(area), 0, 0,
+ app_data.puzzle.grid_size*GRID_PIXELS+10,
+ app_data.puzzle.grid_size*GRID_PIXELS+10);
+
+ return FALSE;
+
+}
+
+/* slot for handling mouse button event for puzzle drawing area */
+gboolean on_puzzle_area_button_press_event (GtkWidget *widget,
+ GdkEventButton *event, gpointer data)
+{
+ /* if it is solution mode, then don't do anything but reset it to
+ non solution mode */
+ if (app_data.solution_revealed == true)
+ {
+ app_data.solution_revealed = false;
+ gtk_widget_queue_draw_area (widget, 0, 0,
+ app_data.puzzle.grid_size*GRID_PIXELS+10,
+ app_data.puzzle.grid_size*GRID_PIXELS+10);
+ return FALSE;
+ }
+
+ /* Depending on the type of button handle the movement */
+ if (event->type == GDK_BUTTON_PRESS && event->button == 1)
+ {
+ int col = (event->x - 5) / GRID_PIXELS;
+ int row = (event->y - 5) / GRID_PIXELS;
+
+ if (app_data.puzzle.chars[row][col] != '#')
+ {
+ if (row < app_data.puzzle.grid_size &&
+ col < app_data.puzzle.grid_size)
+ {
+ app_data.cur_row = row;
+ app_data.cur_col = col;
+
+ /* if it is a start of both across and down word, then
+ toggle the movement on clicking it */
+ if (app_data.puzzle.start_across_word[row][col] != -1 &&
+ app_data.puzzle.start_down_word[row][col] != -1)
+ {
+ if (app_data.current_movement == ACROSS)
+ app_data.current_movement = DOWN;
+ else
+ app_data.current_movement = ACROSS;
+ }
+ /* if it is only start of across word, make the current
+ movement across */
+ else if (app_data.puzzle.start_across_word[row][col] != -1)
+ app_data.current_movement = ACROSS;
+ /* else down movement */
+ else if (app_data.puzzle.start_down_word[row][col] != -1)
+ app_data.current_movement = DOWN;
+ }
+ }
+ }
+
+ gtk_widget_queue_draw_area (widget, 0, 0,
+ app_data.puzzle.grid_size*GRID_PIXELS+10,
+ app_data.puzzle.grid_size*GRID_PIXELS+10);
+
+ return FALSE;
+}
+
+/* slot for handling key press event for puzzle drawing area */
+gboolean on_puzzle_area_key_press_event (GtkWidget *widget,
+ GdkEventKey *event, gpointer data)
+{
+ /* respond to key events only if the puzzle is loaded */
+ if (app_data.is_loaded == true)
+ {
+ /* if the solution is revealed, don't respond to key events except
+ to return to the non-solution mode */
+ if (app_data.solution_revealed == true)
+ {
+ app_data.solution_revealed = false;
+ gtk_widget_queue_draw_area (widget, 0, 0,
+ app_data.puzzle.grid_size*GRID_PIXELS+10,
+ app_data.puzzle.grid_size*GRID_PIXELS+10);
+ return FALSE;
+ }
+
+ switch (event->keyval)
+ {
+ case GDK_KEY_Down : move_current_row (&app_data, DIR_FORWARD);
+ app_data.current_movement = DOWN;
+ break;
+ case GDK_KEY_Up : move_current_row (&app_data, DIR_BACK);
+ app_data.current_movement = DOWN;
+ break;
+ case GDK_KEY_Right: move_current_col (&app_data, DIR_FORWARD);
+ app_data.current_movement = ACROSS;
+ break;
+ case GDK_KEY_Left : move_current_col (&app_data, DIR_BACK);
+ app_data.current_movement = ACROSS;
+ break;
+ case GDK_KEY_BackSpace:
+ case GDK_KEY_Delete:
+ case GDK_KEY_space:
+ app_data.char_ans[app_data.cur_row][app_data.cur_col] = ' ';
+ break;
+ case GDK_KEY_a :
+ case GDK_KEY_A :
+ app_data.char_ans[app_data.cur_row][app_data.cur_col] = 'A';
+ break;
+ case GDK_KEY_b :
+ case GDK_KEY_B :
+ app_data.char_ans[app_data.cur_row][app_data.cur_col] = 'B';
+ break;
+ case GDK_KEY_c :
+ case GDK_KEY_C :
+ app_data.char_ans[app_data.cur_row][app_data.cur_col] = 'C';
+ break;
+ case GDK_KEY_d :
+ case GDK_KEY_D :
+ app_data.char_ans[app_data.cur_row][app_data.cur_col] = 'D';
+ break;
+ case GDK_KEY_e :
+ case GDK_KEY_E :
+ app_data.char_ans[app_data.cur_row][app_data.cur_col] = 'E';
+ break;
+ case GDK_KEY_f :
+ case GDK_KEY_F :
+ app_data.char_ans[app_data.cur_row][app_data.cur_col] = 'F';
+ break;
+ case GDK_KEY_g :
+ case GDK_KEY_G :
+ app_data.char_ans[app_data.cur_row][app_data.cur_col] = 'G';
+ break;
+ case GDK_KEY_h :
+ case GDK_KEY_H :
+ app_data.char_ans[app_data.cur_row][app_data.cur_col] = 'H';
+ break;
+ case GDK_KEY_i :
+ case GDK_KEY_I :
+ app_data.char_ans[app_data.cur_row][app_data.cur_col] = 'I';
+ break;
+ case GDK_KEY_j :
+ case GDK_KEY_J :
+ app_data.char_ans[app_data.cur_row][app_data.cur_col] = 'J';
+ break;
+ case GDK_KEY_k :
+ case GDK_KEY_K :
+ app_data.char_ans[app_data.cur_row][app_data.cur_col] = 'K';
+ break;
+ case GDK_KEY_l :
+ case GDK_KEY_L :
+ app_data.char_ans[app_data.cur_row][app_data.cur_col] = 'L';
+ break;
+ case GDK_KEY_m :
+ case GDK_KEY_M :
+ app_data.char_ans[app_data.cur_row][app_data.cur_col] = 'M';
+ break;
+ case GDK_KEY_n :
+ case GDK_KEY_N :
+ app_data.char_ans[app_data.cur_row][app_data.cur_col] = 'N';
+ break;
+ case GDK_KEY_o :
+ case GDK_KEY_O :
+ app_data.char_ans[app_data.cur_row][app_data.cur_col] = 'O';
+ break;
+ case GDK_KEY_p :
+ case GDK_KEY_P :
+ app_data.char_ans[app_data.cur_row][app_data.cur_col] = 'P';
+ break;
+ case GDK_KEY_q :
+ case GDK_KEY_Q :
+ app_data.char_ans[app_data.cur_row][app_data.cur_col] = 'Q';
+ break;
+ case GDK_KEY_r :
+ case GDK_KEY_R :
+ app_data.char_ans[app_data.cur_row][app_data.cur_col] = 'R';
+ break;
+ case GDK_KEY_s :
+ case GDK_KEY_S :
+ app_data.char_ans[app_data.cur_row][app_data.cur_col] = 'S';
+ break;
+ case GDK_KEY_t :
+ case GDK_KEY_T :
+ app_data.char_ans[app_data.cur_row][app_data.cur_col] = 'T';
+ break;
+ case GDK_KEY_u :
+ case GDK_KEY_U :
+ app_data.char_ans[app_data.cur_row][app_data.cur_col] = 'U';
+ break;
+ case GDK_KEY_v :
+ case GDK_KEY_V :
+ app_data.char_ans[app_data.cur_row][app_data.cur_col] = 'V';
+ break;
+ case GDK_KEY_w :
+ case GDK_KEY_W :
+ app_data.char_ans[app_data.cur_row][app_data.cur_col] = 'W';
+ break;
+ case GDK_KEY_x :
+ case GDK_KEY_X :
+ app_data.char_ans[app_data.cur_row][app_data.cur_col] = 'X';
+ break;
+ case GDK_KEY_y :
+ case GDK_KEY_Y :
+ app_data.char_ans[app_data.cur_row][app_data.cur_col] = 'Y';
+ break;
+ case GDK_KEY_z :
+ case GDK_KEY_Z :
+ app_data.char_ans[app_data.cur_row][app_data.cur_col] = 'Z';
+ break;
+ default : return FALSE;
+
+ }
+ }
+
+ /* move the selection pointer to next row/col as per the current
+ movement orientation if it is not a key left right up or down */
+ if (event->keyval != GDK_KEY_Down && event->keyval != GDK_KEY_Up &&
+ event->keyval != GDK_KEY_Left && event->keyval != GDK_KEY_Right
+ && event->keyval != GDK_KEY_Delete)
+ {
+ /* if the current movement is an across movement */
+ if (app_data.current_movement == ACROSS)
+ {
+ /* if the next column is not blocking move the col */
+ if (event->keyval != GDK_KEY_BackSpace &&
+ next_col_block (&app_data.puzzle, app_data.cur_row,
+ app_data.cur_col) == false)
+ move_current_col (&app_data, DIR_FORWARD);
+ else if (event->keyval == GDK_KEY_BackSpace &&
+ prev_col_block (&app_data.puzzle, app_data.cur_row,
+ app_data.cur_col) == false)
+ move_current_col (&app_data, DIR_BACK);
+ }
+ /* current movement is a up/down movement */
+ else
+ {
+ if (event->keyval != GDK_KEY_BackSpace &&
+ next_row_block (&app_data.puzzle,
+ app_data.cur_row, app_data.cur_col) == false)
+ move_current_row (&app_data, DIR_FORWARD);
+ else if (event->keyval == GDK_KEY_BackSpace &&
+ prev_row_block (&app_data.puzzle,
+ app_data.cur_row, app_data.cur_col) == false)
+ move_current_row (&app_data, DIR_BACK);
+ }
+ }
+
+
+ gtk_widget_queue_draw_area (widget, 0, 0,
+ app_data.puzzle.grid_size*GRID_PIXELS+10,
+ app_data.puzzle.grid_size*GRID_PIXELS+10);
+
+ return FALSE;
+}