From 350edf3c909ce7926dc84411190cca003f6ac2e9 Mon Sep 17 00:00:00 2001 From: Harishankar Date: Wed, 6 May 2020 15:24:10 +0530 Subject: [PATCH] Enhanced word entry and grid movement in puzzle player Enhanced the word entry to have up/down and across movement on entry of letters and also to handle space, backspace and delete characters. Also made clicking a clue in the list of clues to point to the correct word and orientation --- wordblox.h | 69 +++++++++++++++++++++++++ wordblox_player.c | 114 ++++++++++++++++++++++++++++++++++++++++-- wordblox_player.glade | 8 ++- 3 files changed, 184 insertions(+), 7 deletions(-) diff --git a/wordblox.h b/wordblox.h index f7a3ce4..e27d37c 100644 --- a/wordblox.h +++ b/wordblox.h @@ -69,6 +69,7 @@ typedef struct { char char_ans[MAX_PUZZLE_SIZE][MAX_PUZZLE_SIZE]; int cur_row; int cur_col; + enum ORIENTATION current_movement; } MainPlayerData; /* compute the hash of a password */ @@ -290,6 +291,46 @@ void reset_color () { printf ("\x1B[0m"); } +/* check if the prev row has a block or not */ +bool prev_row_block (Puzzle *p, int r, int c) +{ + if (r == 0) + return true; + if (p->chars[r-1][c] == '#') + return true; + return false; +} + +/* check if the next row has a block or not */ +bool next_row_block (Puzzle *p, int r, int c) +{ + if (r == p->grid_size-1) + return true; + if (p->chars[r+1][c] == '#') + return true; + return false; +} + +/* check if the prev col has a block or not */ +bool prev_col_block (Puzzle *p, int r, int c) +{ + if (c == 0) + return true; + if (p->chars[r][c-1] == '#') + return true; + return false; +} + +/* check if the next col has a block or not */ +bool next_col_block (Puzzle *p, int r, int c) +{ + if (c == p->grid_size - 1) + return true; + if (p->chars[r][c+1] == '#') + return true; + return false; +} + /* check if previous row is blank or not */ bool prev_row_blank (Puzzle *p, int r, int c) { @@ -319,6 +360,34 @@ bool next_col_blank (Puzzle *p, int r, int c) return false; } +/* set the current row/col to the beginning of word index (across or down) */ +void set_selection_to_word_start (MainPlayerData *app_data, + enum ORIENTATION orient, int word_index) +{ + for (int i = 0; i < app_data->puzzle.grid_size; i ++) + { + for (int j = 0; j < app_data->puzzle.grid_size; j ++) + { + if (orient == ACROSS && + app_data->puzzle.start_across_word[i][j] == word_index) + { + app_data->current_movement = ACROSS; + app_data->cur_row = i; + app_data->cur_col = j; + break; + } + else if (orient == DOWN && + app_data->puzzle.start_down_word[i][j] == word_index) + { + app_data->current_movement = DOWN; + app_data->cur_row = i; + app_data->cur_col = j; + break; + } + } + } +} + /* unfreeze the grid - make editing possible to change words */ void unfreeze_puzzle (Puzzle *p) { diff --git a/wordblox_player.c b/wordblox_player.c index 46a41fd..8e7299b 100644 --- a/wordblox_player.c +++ b/wordblox_player.c @@ -50,6 +50,49 @@ void update_clue_items () } } +/* 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) @@ -66,6 +109,24 @@ gboolean on_puzzle_area_button_press_event (GtkWidget *widget, { 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; } } } @@ -73,9 +134,7 @@ gboolean on_puzzle_area_button_press_event (GtkWidget *widget, 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; } @@ -89,13 +148,18 @@ gboolean on_puzzle_area_key_press_event (GtkWidget *widget, 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] = ' '; @@ -209,6 +273,40 @@ gboolean on_puzzle_area_key_press_event (GtkWidget *widget, } } + /* 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); @@ -222,11 +320,12 @@ gboolean on_puzzle_area_draw (GtkWidget *widget, cairo_t *cr, gpointer data) /* if a puzzle is loaded */ if (app_data.is_loaded == true) { - GdkRGBA colorfore, colorback, colorblue, colorbacksel; + GdkRGBA colorfore, colorback, colorblue, colorbacksel1, colorbacksel2; gdk_rgba_parse (&colorfore, "#000000"); gdk_rgba_parse (&colorback, "#ffffff"); gdk_rgba_parse (&colorblue, "#0000dd"); - gdk_rgba_parse (&colorbacksel, "#ffffaa"); + gdk_rgba_parse (&colorbacksel1, "#ffffaa"); + gdk_rgba_parse (&colorbacksel2, "#aaffff"); cairo_set_line_width (cr, 3); /* set the size of the drawing area */ @@ -269,7 +368,12 @@ gboolean on_puzzle_area_draw (GtkWidget *widget, cairo_t *cr, gpointer data) /* if it is a current selection then set the background to yellow */ if (app_data.cur_row == i && app_data.cur_col == j) - gdk_cairo_set_source_rgba (cr, &colorbacksel); + { + if (app_data.current_movement == ACROSS) + gdk_cairo_set_source_rgba (cr, &colorbacksel1); + else + gdk_cairo_set_source_rgba (cr, &colorbacksel2); + } cairo_rectangle (cr, j*GRID_PIXELS+5, i*GRID_PIXELS+5, GRID_PIXELS, GRID_PIXELS); diff --git a/wordblox_player.glade b/wordblox_player.glade index 7c1bc92..3f30d95 100644 --- a/wordblox_player.glade +++ b/wordblox_player.glade @@ -192,7 +192,9 @@ 0 False - + + + @@ -241,7 +243,9 @@ 0 False - + + + -- 2.20.1