This repository has been archived on 2024-12-14. You can view files and clone it, but cannot push or open issues or pull requests.
Files
OCRudoku/src/menus/selection_menu.c
Lilian1024 421fd8324e
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
feat: added loaded path reconsitution
2024-12-08 01:34:36 +01:00

797 lines
23 KiB
C

#define _GNU_SOURCE
#include "selection_menu.h"
#include "global.h"
#include "result_menu.h"
#include "../utils/Application/ApplicationUtils.h"
#include "../utils/EZ_UI/EZ_manager.h"
#include "../utils/Rendering/RenderingUtils.h"
#include "../utils/EZ_UI/elements/EZ_image.h"
#include "../utils/EZ_UI/elements/EZ_button.h"
#include "../utils/EZ_UI/elements/EZ_text.h"
#include "../utils/EZ_UI/elements/EZ_list.h"
#include "../utils/EZ_UI/elements/EZ_select_zone.h"
#include "../utils/Application/ApplicationUtils.h"
#include "../utils/Image/ImageUtils.h"
#include "../utils/AI/neural_utils.h"
#include <unistd.h>
#include <math.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_ttf.h>
#include <stdio.h>
#include <string.h>
#include "EZ_drag_select.h"
EZ_DRAWABLE* selection_menu_drawables[17];
EZ_INTERACTIBLE* selection_menu_interactibles[8];
size_t selection_menu_objects_len = 17;
void* selection_menu_objects[17];
int auto_split_grid;
int auto_split_words;
size_t grid_index;
pixel_cluster** cluster_splitting;
size_t linkage_length;
size_t* array_length;
pixel_cluster* manual_grid;
size_t manual_grid_len;
int grid_x, grid_y;
char** grid;
pixel_cluster** manual_words;
size_t words_nb = 0;
size_t* word_len;
char** words;
int loaded_list = 0;
EZ_select_zone** words_select_zones;
EZ_MENU selection_menu;
void unload_selection_menu(void)
{
for (size_t i = 0; i < selection_menu_objects_len; i++)
{
free(selection_menu_objects[i]);
}
if (!loaded_list)
return;
EZ_list_clear((EZ_list*)selection_menu_objects[14]);
for (size_t i = 0; i < words_nb; i++)
{
free(words_select_zones[i]);
}
words_nb = 0;
loaded_list = 0;
}
void selection_menu_process_events(SDL_Window* window, SDL_Renderer* renderer, SDL_Event* event, EZ_MENU* current_menu) //exectuted each frame with all avaliable events
{
for (size_t i = 0; i < current_menu->interactible_elements_len; i++)
{
EZ_INTERACTIBLE* inter = current_menu->interactible_elements[i];
if (inter->enable)
inter->process_interaction(window, renderer, event, inter, inter->process_data);
}
}
void home_button_action1(EZ_button* tmp)
{
(void)tmp;
EZ_list_clear((EZ_list*)selection_menu_objects[14]);
if (loaded_list)
{
for (size_t i = 0; i < words_nb; i++) //free words select zones
{
free(words_select_zones[i]);
}
loaded_list = 0;
}
auto_split_words = -1;
EZ_select_menu(0);
}
void clear_button_action(EZ_button* tmp)
{
(void)tmp;
EZ_list_clear((EZ_list*)selection_menu_objects[14]);
if (!loaded_list)
return;
for (size_t i = 0; i < words_nb; i++)
{
free(words_select_zones[i]);
}
auto_split_words = -1;
loaded_list = 0;
}
SDL_Rect from_surface_to_image_rect(anchore_point image, SDL_Surface* surface, SDL_Rect surface_rect)
{
SDL_Rect image_rect = anchore_to_rect(main_window, image);
double xp = (double)surface_rect.x / (double)surface->w;
double yp = (double)surface_rect.y / (double)surface->h;
double wp = (double)surface_rect.w / (double)surface->w;
double hp = (double)surface_rect.h / (double)surface->h;
int x = round((double)xp * (double)image_rect.w);
int y = round((double)yp * (double)image_rect.h);
int w = round((double)wp * (double)image_rect.w);
int h = round((double)hp * (double)image_rect.h);
return (SDL_Rect) {
image_rect.x + x,
image_rect.y + y,
w,
h
};
}
SDL_Rect from_image_rect_to_surface(anchore_point image, SDL_Rect selection, SDL_Surface* surface)
{
SDL_Rect image_rect = anchore_to_rect(main_window, image);
SDL_Rect select_rect = {
selection.x - image_rect.x,
selection.y - image_rect.y,
selection.w,
selection.h
};
double xp = (double)select_rect.x / (double)image_rect.w;
double yp = (double)select_rect.y / (double)image_rect.h;
double wp = (double)select_rect.w / (double)image_rect.w;
double hp = (double)select_rect.h / (double)image_rect.h;
int x = round((double)xp * (double)surface->w);
int y = round((double)yp * (double)surface->h);
int w = round((double)wp * (double)surface->w);
int h = round((double)hp * (double)surface->h);
return (SDL_Rect) {
x,
y,
w,
h
};
}
void grid_selection_end(EZ_drag_select* tmp)
{
(void)tmp;
auto_split_grid = 0;
EZ_drag_select* Drag=((EZ_drag_select*)selection_menu_objects[10]);
Drag->interactible_select.enable=0;
size_t link_len;
size_t* arr_len;
SDL_Rect search_rect = from_image_rect_to_surface(selection_menu.drawable_elements[0]->dst_anchore, to_positive_rect(Drag->selected_zone), loaded_image);
pixel_cluster** tmp_clusters = get_main_linkages(loaded_image, search_rect, &link_len, &arr_len);
size_t res = get_grid_cluster(link_len,arr_len);
manual_grid = tmp_clusters[res];
manual_grid_len = arr_len[res];
for (size_t i = 0; i < link_len; i++)
{
if (i == res)
continue;
free(tmp_clusters[i]);
}
free(arr_len);
free(tmp_clusters);
SDL_Rect GridRect = get_grid_rect(manual_grid, manual_grid_len);
selection_menu.drawable_elements[10]->dst_anchore = rect_to_anchore(from_surface_to_image_rect(selection_menu.drawable_elements[0]->dst_anchore, loaded_image, GridRect));
selection_menu.drawable_elements[10]->visible = 1;
((EZ_image*)selection_menu_objects[11])->drawable_image.dst_anchore= Drag->drawable_drag.dst_anchore;
((EZ_image*)selection_menu_objects[10])->drawable_image.visible=1;
}
void word_selection_end(EZ_drag_select* tmp)
{
(void)tmp;
EZ_drag_select* Drag=((EZ_drag_select*)selection_menu_objects[12]);
Drag->interactible_select.enable=0;
size_t link_len;
size_t* arr_len;
SDL_Rect search_rect = from_image_rect_to_surface(selection_menu.drawable_elements[0]->dst_anchore, to_positive_rect(Drag->selected_zone), loaded_image);
pixel_cluster** tmp_clusters = get_main_linkages(loaded_image, search_rect, &link_len, &arr_len);
size_t prev_len;
if (auto_split_words == 0)
{
prev_len = words_nb;
words_nb += link_len;
manual_words = realloc(manual_words, words_nb * sizeof(pixel_cluster*));
memcpy(manual_words + prev_len, tmp_clusters, link_len);
word_len = realloc(word_len, words_nb * sizeof(pixel_cluster*));
memcpy(word_len + prev_len, arr_len, link_len);
words_select_zones = realloc(words_select_zones, words_nb * sizeof(EZ_image*));
}
else
{
prev_len = 0;
words_nb = link_len;
manual_words = tmp_clusters;
word_len = arr_len;
words_select_zones = calloc(link_len, sizeof(EZ_image*));
}
for (size_t w = 0; w < link_len; w++)
{
SDL_Rect WordRect = get_grid_rect(tmp_clusters[w], arr_len[w]);
words_select_zones[w + prev_len] = EZ_create_select_zone(rect_to_anchore(from_surface_to_image_rect(selection_menu.drawable_elements[0]->dst_anchore, loaded_image, WordRect)), (SDL_Color){255, 255, 0, 255});
words_select_zones[w + prev_len]->drawable_select_zone.visible = 1;
EZ_list_element* element = malloc(sizeof(EZ_list_element));
element->drawable_element = &words_select_zones[w + prev_len]->drawable_select_zone;
element->interactible_element = NULL;
EZ_list_add_element((EZ_list*)selection_menu_objects[14], element);
}
if (auto_split_words == 0)
{
free(arr_len);
free(tmp_clusters);
}
loaded_list = 1;
auto_split_words = 0;
}
void button_action_Grid(EZ_button* tmp)
{
(void)tmp;
((EZ_image*)selection_menu_objects[11])->drawable_image.visible=0;
((EZ_drag_select*)selection_menu_objects[10])->interactible_select.enable=1;
}
void button_action_Word(EZ_button* tmp)
{
(void)tmp;
((EZ_image*)selection_menu_objects[13])->drawable_image.visible=0;
((EZ_drag_select*)selection_menu_objects[12])->interactible_select.enable=1;
}
void button_action_switch_result(EZ_button* tmp)
{
(void)tmp;
size_t i = 0;
size_t last_slash;
while (loaded_image_path[i] != '\0')
{
if (loaded_image_path[i] == '/')
last_slash = i;
i++;
}
char* spliting_path = combine_path(application_directory, "splitting");
if (auto_split_grid && auto_split_words > 0)
export_main_linkages(loaded_image, cluster_splitting, linkage_length, array_length, spliting_path, &grid_x, &grid_y); //Save letter's images
else
{
if (auto_split_grid)
{
export_main_grid_cluster(loaded_image, cluster_splitting[grid_index], array_length[grid_index], spliting_path, &grid_x, &grid_y);
}
else
{
export_main_grid_cluster(loaded_image, manual_grid, manual_grid_len, spliting_path, &grid_x, &grid_y);
}
if (auto_split_words)
{
char* words_path = export_prepare_words_dir(spliting_path);
for (size_t i = 0; i < words_nb; i++)
{
if (i == grid_index)
continue;
export_word_cluster(loaded_image, cluster_splitting[i], array_length[i], (i > grid_index ? i-1 : i), words_path);
}
}else
{
export_main_words_cluster(loaded_image, manual_words, words_nb, word_len, spliting_path);
}
}
grid = calloc(grid_x, sizeof(char*));
char* image_path = calloc(last_slash + 2, sizeof(char));
memcpy(image_path, loaded_image_path, last_slash+1);
image_path[last_slash + 2] = '\0';
size_t name_len = strlen(loaded_image_path) - last_slash;
char* file_name = calloc(name_len + 1, sizeof(char));
memcpy(file_name, loaded_image_path + last_slash + 1, name_len);
file_name[name_len] = '\0';
char* new_path;
asprintf(&new_path, "%sexamples/gridImages/%s", image_path, file_name);
char* path;
asprintf(&path, "%snetwork.csv", application_directory);
//neural_network network;
//load_neural_network(&network, read_file(path)); //Load neural network
char* grid_path;
asprintf(&grid_path, "%s/grid", spliting_path); //get grid directory path
for (int x = 0; x < grid_x; x++)
{
grid[x] = calloc(grid_y, sizeof(char));
for (int y = 0; y < grid_y; y++)
{
/*char* file;
asprintf(&file, "%s/grid_%i_%i.png", grid_path, x, y); //get image path for each letter in grid
size_t len;
double* image = image_to_bool_array(file, &len);*/
//network_set_input_double(&network, image);
//process_network(&network); //process network to get the character
//grid[x][y] = get_network_char_prediction(&network, network.nb_input / 26); //save character in the array
}
}
words_nb = linkage_length - 1;
word_len = calloc(words_nb, sizeof(size_t));
words = calloc(words_nb, sizeof(char*));
char* words_path;
asprintf(&words_path, "%s/words", spliting_path); //get words directory path
for (size_t x = 0; x < words_nb + 1; x++) //for each words
{
if (x == grid_index)
continue;
size_t wi = x > grid_index ? x-1 : x;
word_len[wi] = array_length[x];
words[wi] = calloc(word_len[wi], sizeof(char));
for (size_t i = 0; i < word_len[wi]; i++) //for each letter in the word
{
/*char* file;
asprintf(&file, "%s/word_%li_letter_%li.png", words_path, wi, i); //get letter's path
size_t len;
double* image = image_to_bool_array(file, &len);*/
//network_set_input_double(&network, image);
//process_network(&network); //process network to get the character
//words[wi][i] = get_network_char_prediction(&network, network.nb_input / 26); //save character in the array
}
}
EZ_list_clear((EZ_list*)selection_menu_objects[14]);
if (loaded_list)
{
for (size_t i = 0; i < words_nb; i++) //free words select zones
{
free(words_select_zones[i]);
}
loaded_list = 0;
words_nb = 0;
}
auto_split_words = -1;
EZ_select_menu(2);
result_menu_enter();
}
void selection_menu_enter(void)
{
EZ_drag_select* drag_grid=((EZ_drag_select*)selection_menu_objects[10]);
EZ_drag_select* drag_word=((EZ_drag_select*)selection_menu_objects[12]);
EZ_image* img = (EZ_image*)selection_menu_objects[0];
EZ_edit_image(img, loaded_image, main_renderer, 1);
drag_grid->drag_anchore = img->drawable_image.dst_anchore;
drag_grid->interactible_select.anchore = img->drawable_image.dst_anchore;
drag_word->drag_anchore = img->drawable_image.dst_anchore;
drag_word->interactible_select.anchore = img->drawable_image.dst_anchore;
auto_split_grid = 1;
auto_split_words = 1;
cluster_splitting= get_main_linkages(loaded_image, get_surface_full_rect(loaded_image), &linkage_length, &array_length);
grid_index = get_grid_cluster(linkage_length,array_length);
words_nb = linkage_length - 1;
SDL_Rect GridRect = get_grid_rect(cluster_splitting[grid_index], array_length[grid_index]);
selection_menu.drawable_elements[10]->dst_anchore = rect_to_anchore(from_surface_to_image_rect(selection_menu.drawable_elements[0]->dst_anchore, loaded_image, GridRect));
selection_menu.drawable_elements[10]->visible = 1;
words_select_zones = calloc(words_nb, sizeof(EZ_image*));
for (size_t w = 0; w < linkage_length; w++)
{
if (w == grid_index)
continue;
size_t wi = w > grid_index ? w-1 : w;
SDL_Rect WordRect = get_grid_rect(cluster_splitting[w], array_length[w]);
//words_select_zones[wi] = EZ_create_image_file(combine_path(application_directory, "resources/SelectImageBlue.png"), main_renderer, rect_to_anchore(from_surface_to_image_rect(selection_menu.drawable_elements[0]->dst_anchore, loaded_image, WordRect)), 0);
words_select_zones[wi] = EZ_create_select_zone(rect_to_anchore(from_surface_to_image_rect(selection_menu.drawable_elements[0]->dst_anchore, loaded_image, WordRect)), (SDL_Color){255, 255, 0, 255});
words_select_zones[wi]->drawable_select_zone.visible = 1;
EZ_list_element* element = malloc(sizeof(EZ_list_element));
element->drawable_element = &words_select_zones[wi]->drawable_select_zone;
element->interactible_element = NULL;
EZ_list_add_element((EZ_list*)selection_menu_objects[14], element);
}
loaded_list = 1;
}
void load_selection_menu(SDL_Renderer* renderer)
{
selection_menu.drawable_elements = selection_menu_drawables;
selection_menu.drawable_elements_len = 17;
selection_menu.interactible_elements = selection_menu_interactibles;
selection_menu.interactible_elements_len = 8;
SDL_Color back_col = {255, 255, 255, 255};
selection_menu.background_color = back_col;
selection_menu.process_event = &selection_menu_process_events;
selection_menu.unload_menu = &unload_selection_menu;
//Image
anchore_point main_img_anchore = {
0.2,
0.8,
0.2,
0.8,
0,
0,
0,
0,
0.0
};
EZ_image* main_img = EZ_create_image_file(combine_path(application_directory, "resources/Upload.png"), renderer, main_img_anchore,1 );
selection_menu.drawable_elements[0] = &main_img->drawable_image;
selection_menu_objects[0] = (void*)main_img;
// Grid
EZ_drag_select* main_grid =EZ_create_drag_select(combine_path(application_directory, "resources/SelectImageBlue.png"),renderer, main_img_anchore);
main_grid->interactible_select.enable=0;
selection_menu.drawable_elements[10]= &main_grid->drawable_drag;
selection_menu.interactible_elements[4]= &main_grid->interactible_select;
selection_menu_objects[10]= (void*) main_grid;
main_grid->on_end_selecting= &grid_selection_end;
// word
EZ_drag_select* word_grid =EZ_create_drag_select(combine_path(application_directory, "resources/SelectImageYellow.png"),renderer, main_img_anchore);
word_grid->interactible_select.enable=0;
selection_menu.drawable_elements[12]= &word_grid->drawable_drag;
selection_menu.interactible_elements[5]= &word_grid->interactible_select;
selection_menu_objects[12]= (void*) word_grid;
word_grid->on_end_selecting= &word_selection_end;
anchore_point grid_selection_anchore = {
0,
0,
0,
0,
0,
0,
0,
0,
0.0
};
EZ_image* grid_select_image= EZ_create_image_file(combine_path(application_directory, "resources/SelectImageBlue.png"), renderer, grid_selection_anchore, 0);
selection_menu.drawable_elements[11] = &grid_select_image->drawable_image;
selection_menu_objects[11]= (void*) grid_select_image;
anchore_point word_selection_anchore = {
0,
0,
0,
0,
0,
0,
0,
0,
0.0
};
EZ_image* word_select_image= EZ_create_image_file(combine_path(application_directory, "resources/SelectImageYellow.png"), renderer, word_selection_anchore, 0);
selection_menu.drawable_elements[13] = &word_select_image->drawable_image;
selection_menu_objects[13]= (void*) word_select_image;
//Button
anchore_point solve_butt_anchore = {
0.4,
0.6,
0.9,
1,
0,
0,
0,
0,
0.0
};
EZ_button* main_butt = EZ_create_button(combine_path(application_directory, "resources/button.png"), renderer, solve_butt_anchore);
main_butt->on_button_up = &button_action_switch_result;
selection_menu.drawable_elements[1] = &main_butt->drawable_button;
selection_menu.interactible_elements[0] = &main_butt->interactible_button;
selection_menu_objects[1] = (void*)main_butt;
anchore_point Grid_anchore = {
0.05,
0.25,
0.3,
0.4,
0,
0,
0,
0,
0.0
};
EZ_button* Grid = EZ_create_button(combine_path(application_directory, "resources/button.png"), renderer, Grid_anchore);
Grid->on_button_up = &button_action_Grid;
selection_menu.drawable_elements[2] = &Grid->drawable_button;
selection_menu.interactible_elements[1] = &Grid->interactible_button;
selection_menu_objects[2] = (void*)Grid;
anchore_point Word_anchore = {
0.05,
0.25,
0.4,
0.5,
0,
0,
0,
0,
0.0
};
EZ_button* Word = EZ_create_button(combine_path(application_directory, "resources/button.png"), renderer, Word_anchore);
Word->on_button_up = &button_action_Word;
selection_menu.drawable_elements[3] = &Word->drawable_button;
selection_menu.interactible_elements[2] = &Word->interactible_button;
selection_menu_objects[3] = (void*)Word;
anchore_point home_butt_anchore = {
0,
0.2,
0,
0.1,
0,
0,
0,
0,
0.0
};
EZ_button* home_butt = EZ_create_button(combine_path(application_directory, "resources/button.png"), renderer, home_butt_anchore);
home_butt->on_button_up = &home_button_action1;
selection_menu.drawable_elements[8] = &home_butt->drawable_button;
selection_menu.interactible_elements[3] = &home_butt->interactible_button;
selection_menu_objects[8] = (void*)home_butt;
anchore_point clear_butt_anchore = {
0.05,
0.25,
0.5,
0.6,
0,
0,
0,
0,
0.0
};
EZ_button* clear_butt = EZ_create_button(combine_path(application_directory, "resources/button.png"), renderer, clear_butt_anchore);
clear_butt->on_button_up = &clear_button_action;
selection_menu.drawable_elements[15] = &clear_butt->drawable_button;
selection_menu.interactible_elements[7] = &clear_butt->interactible_button;
selection_menu_objects[15] = (void*)clear_butt;
//Text
anchore_point main_text_anchore = {
0.4,
0.6,
0.9,
1,
0,
0,
0,
0,
0.0
};
SDL_Color color = {255, 255, 255, 255};
SDL_Color color1 = {0,0,0,0};
EZ_text* main_text = EZ_create_text("Solve", main_font, color, renderer, main_text_anchore, 1);
selection_menu.drawable_elements[4] = &main_text->drawable_text;
selection_menu_objects[4] = (void*)main_text;
anchore_point NAME_anchore= {
0.4,
0.6,
0.0,
0.1,
0,
0,
0,
0,
0.0
};
EZ_text* Name= EZ_create_text("Select elements", main_font, color1, renderer, NAME_anchore, 1);
selection_menu.drawable_elements[5]= &Name->drawable_text;
selection_menu_objects[5]= (void*)Name;
anchore_point Select_Grid_anchore= {
0.1,
0.2,
0.3,
0.4,
0,
0,
0,
0,
0.0
};
SDL_Color grid_color = {
61,
161,
255,
255
};
EZ_text* Select_Grid= EZ_create_text("Select Grid", main_font, grid_color, renderer, Select_Grid_anchore, 1);
selection_menu.drawable_elements[6]= &Select_Grid->drawable_text;
selection_menu_objects[6]= (void*)Select_Grid;
anchore_point Select_Word_anchore= {
0.1,
0.2,
0.4,
0.5,
0,
0,
0,
0,
0.0
};
SDL_Color word_color = {
255,
255,
107,
255
};
EZ_text* Select_Word= EZ_create_text("Select Word", main_font, word_color, renderer, Select_Word_anchore, 1);
selection_menu.drawable_elements[7]= &Select_Word->drawable_text;
selection_menu_objects[7]= (void*)Select_Word;
anchore_point home_text_anchore = {
0.05,
0.15,
0,
0.1,
0,
0,
0,
0,
0.0
};
EZ_text* home_text = EZ_create_text("Home", main_font, color, renderer, home_text_anchore, 1);
selection_menu.drawable_elements[9] = &home_text->drawable_text;
selection_menu_objects[9] = (void*)home_text;
anchore_point Word_List_Anchore= {
0.05,
0.25,
0.55,
0.7,
0,
0,
0,
0,
0.0
};
EZ_list* word_list = EZ_create_list(Word_List_Anchore);
selection_menu.drawable_elements[14] = &word_list->drawable_list;
selection_menu.interactible_elements[6] = &word_list->interactible_list;
selection_menu_objects[14] = (void*)word_list;
anchore_point Clear_Word_anchore= {
0.1,
0.2,
0.5,
0.6,
0,
0,
0,
0,
0.0
};
SDL_Color clear_color = {
255,
107,
107,
255
};
EZ_text* Clear_Word= EZ_create_text("Clear Words", main_font, clear_color, renderer, Clear_Word_anchore, 1);
selection_menu.drawable_elements[16]= &Clear_Word->drawable_text;
selection_menu_objects[16]= (void*)Clear_Word;
}