I am making an implemintation of conway's game of life using c and wanted to make the game highlight the cell the mouse in hovering over but i can't seem to be able to catch mouse movements even though i used ALL_MOUSE_EVENTS
and MOUSE_MOVED
flags
here is the input handling code :
void handle_mouse_input(){
MEVENT event;
if(nc_getmouse(&event) != OK) return ;
if(event.x >= Play_Start_X && event.x <= Play_End_X && event.y == Play_Y){
Pause = !Pause;
}else if(event.x >= Exit_Start_X && event.x <= Exit_End_X && event.y == Exit_Y){
quit();
}else if(event.x >= State_Start_X && event.y >= State_Start_Y && event.x <= State_End_X && event.y <= State_End_Y){
lock_state();
cell_state new_state = alive;
unsigned x = ((event.x - State_Start_X) / 2) + X_Indent , y = event.y - State_Start_Y + Y_Indent;
if(lookup_cell_state(Board , x , y , false) == alive){
new_state = dead;
}
set_cell(Board , x , y , new_state);
unlock_state();
}else if(event.x >= Reset_Start_X && event.x <= Reset_End_X && event.y == Reset_Y){
reset_board(Board);
}
}
//the purpose of making the function of this type is to be used with pthreads
void *handle_input(void *arg){
if(stdscr == NULL) pthread_exit(NULL);
keypad(stdscr , true);
mousemask(ALL_MOUSE_EVENTS | REPORT_MOUSE_POSITION , NULL);
mouseinterval(0);
noecho();
int ch = 0;
while(1){
pthread_mutex_lock(&IO_Mutex);
ch = getch();
pthread_mutex_unlock(&IO_Mutex);
if(ch == ERR){
continue;
}
if(ch == KEY_MOUSE){
handle_mouse_input();
}else{
handle_keyboard_input(ch);
}
flushinp();
};
return NULL;
}
I am running this on windows terminal
note : i am testing if i catch the mouse movement using a debugger thats why i didn't write an if statement to check for bstate yet
i found a solution(kind of)
here is the new code:
void handle_mouse_input(int ch){
MEVENT event;
static int Last_X = -1 , Last_Y = -1;
if(getmouse(&event) != OK) return ;
if(event.x != Last_X || event.y != Last_Y){
unhighlight_exit_button();
unhighlight_play_pause_button();
unhighlight_reset_button();
unhighlight_cells();
if(event.x >= Play_Start_X && event.x <= Play_End_X && event.y == Play_Y){
highlight_play_pause_button();
}else if(event.x >= Exit_Start_X && event.x <= Exit_End_X && event.y == Exit_Y){
highlight_exit_button();
}else if(event.x >= State_Start_X && event.y >= State_Start_Y && event.x <= State_End_X && event.y <= State_End_Y ){
unsigned x = (event.x - State_Start_X) / 2 , y = event.y - State_Start_Y;
highlight_cell(x , y);
render_state(Board , stdscr , State_Start_X , State_Start_Y , State_End_X , State_End_Y);
refresh();
}else if(event.x >= Reset_Start_X && event.x <= Reset_End_X && event.y == Reset_Y){
highlight_reset_button();
}
}
Last_X = event.x;
Last_Y = event.y;
if(ch != KEY_MOUSE) return ;
if(event.x >= Play_Start_X && event.x <= Play_End_X && event.y == Play_Y){
Pause = !Pause;
}else if(event.x >= Exit_Start_X && event.x <= Exit_End_X && event.y == Exit_Y){
quit();
}else if(event.x >= State_Start_X && event.y >= State_Start_Y && event.x <= State_End_X && event.y <= State_End_Y ){
lock_state();
cell_state new_state = alive;
unsigned x = ((event.x - State_Start_X) / 2) + X_Indent , y = event.y - State_Start_Y + Y_Indent;
if(lookup_cell_state(Board , x , y , false) == alive){
new_state = dead;
}
set_cell(Board , x , y , new_state);
unlock_state();
render_state(Board , stdscr , State_Start_X , State_Start_Y , State_End_X , State_End_Y);
refresh();
}else if(event.x >= Reset_Start_X && event.x <= Reset_End_X && event.y == Reset_Y){
reset_board(Board);
}
}
//the purpose of making the function of this type is to be used with pthreads
void *handle_input(void *arg){
if(stdscr == NULL) return NULL;
int ch = 0;
ch = getch();
handle_mouse_input(ch);
if(ch == ERR){
return NULL;
}
if(ch != KEY_MOUSE){
handle_keyboard_input(ch);
}
flushinp();
return NULL;
}
even though the windows terminal won't report movement , the position of the mouse is always updated even if no new event happens , so i handle the mouse input even if a mouse event didn't happen get the mouse event check its position to know which cell or button it is hovering over then check if a mouse event has happened
you can also implement a function that detects mouse movement by getting the new mouse position then comparing it to older the position
eg:
bool mouse_moved(int *new_x , int *new_y){
static int x = -1 , y = -1;
if(new_x == NULL || new_y == NULL) return false;
MEVENT event;
nc_getmouse(&event);
*new_x = -1;
*new_y = -1;
if(event.x != x || event.y != y){
*new_x = x = event.x;
*new_y = y = event.y;
return true;
}
return false
}
EDIT : turns out this only works with pdcurses