From ff512593da0267f244fb4b2e92004486f6c21f9f Mon Sep 17 00:00:00 2001 From: grayTerminal-sh Date: Wed, 22 Jul 2026 08:03:24 +0200 Subject: [PATCH] feat: comeback workspace button --- include/views/main_window.h | 24 +++++ src/core/application.c | 43 ++++++++ src/views/main_window.c | 104 +++++++++++++++++++ src/widgets/workspace.c | 193 ++++++++++++++++++++++++++++++++++++ 4 files changed, 364 insertions(+) diff --git a/include/views/main_window.h b/include/views/main_window.h index 3d04ef9..184a291 100644 --- a/include/views/main_window.h +++ b/include/views/main_window.h @@ -49,6 +49,15 @@ typedef void (*MainWindowImportEvidenceCallback)( gpointer user_data ); +/** + * @brief Callback appelé lorsque l'utilisateur revient au graphe. + * + * @param user_data Données utilisateur associées au callback. + */ +typedef void (*MainWindowShowGraphCallback)( + gpointer user_data +); + /** * @brief Callback appelé lorsqu'une preuve est sélectionnée. * @@ -432,6 +441,21 @@ void main_window_set_import_evidence_callback( gpointer user_data ); +/** + * @brief Définit le callback du bouton « Revenir au graphe ». + * + * MainWindow transmet uniquement la demande au contrôleur. + * + * @param main_window Fenêtre principale. + * @param callback Fonction appelée lors du clic, ou NULL. + * @param user_data Données transmises au callback. + */ +void main_window_set_show_graph_callback( + MainWindow *main_window, + MainWindowShowGraphCallback callback, + gpointer user_data +); + /** * @brief Active ou désactive l'action d'import d'une preuve. * diff --git a/src/core/application.c b/src/core/application.c index 644390a..47d33ac 100644 --- a/src/core/application.c +++ b/src/core/application.c @@ -4421,6 +4421,43 @@ static void application_on_reset_graph_layout_confirmed( ); } +/** + * @brief Demande confirmation avant toute suppression de position. + */ +static void application_on_show_graph_requested( + gpointer user_data +) +{ + Application *application = + user_data; + + if (application == NULL || + application->main_window == NULL || + application->graph_model == NULL) + { + return; + } + + application_set_selected_evidence_identifier( + application, + NULL + ); + + /* + * Passer NULL restaure l'état principal du Workspace. Quand le graphe + * est prêt, workspace_show_default() affiche automatiquement le canvas. + */ + main_window_set_selected_evidence( + application->main_window, + NULL + ); + + main_window_set_status( + application->main_window, + "Graphe de l'enquête affiché." + ); +} + /** * @brief Demande confirmation avant toute suppression de position. */ @@ -4557,6 +4594,12 @@ static void application_on_activate( application ); + main_window_set_show_graph_callback( + application->main_window, + application_on_show_graph_requested, + application + ); + main_window_set_new_investigation_callback( application->main_window, application_on_new_investigation_requested, diff --git a/src/views/main_window.c b/src/views/main_window.c index 5dbb59a..97faeac 100644 --- a/src/views/main_window.c +++ b/src/views/main_window.c @@ -59,6 +59,7 @@ struct MainWindow GtkWidget *new_investigation_button; GtkWidget *open_investigation_button; GtkWidget *import_evidence_button; + GtkWidget *show_graph_button; GtkWidget *content_paned; GtkWidget *main_paned; GtkWidget *status_label; @@ -86,6 +87,12 @@ struct MainWindow gpointer import_evidence_user_data; + MainWindowShowGraphCallback + show_graph_callback; + + gpointer + show_graph_user_data; + MainWindowVerifyEvidenceCallback verify_evidence_callback; @@ -190,6 +197,33 @@ static void main_window_on_import_evidence_clicked( ); } +/** + * @brief Transmet la demande de fermeture au contrôleur. + * + * @param button Bouton ayant reçu le clic. + * @param user_data Pointeur vers MainWindow. + */ +static void main_window_on_show_graph_clicked( + GtkButton *button, + gpointer user_data +) +{ + MainWindow *main_window = + user_data; + + (void) button; + + if (main_window == NULL || + main_window->show_graph_callback == NULL) + { + return; + } + + main_window->show_graph_callback( + main_window->show_graph_user_data + ); +} + /** * @brief Transmet la demande de fermeture au contrôleur. * @@ -436,6 +470,12 @@ MainWindow *main_window_new( "Importer une preuve" ); + main_window->show_graph_button = + main_window_create_action_button( + "go-previous-symbolic", + "Revenir au graphe" + ); + main_window->quit_button = main_window_create_action_button( "application-exit-symbolic", @@ -461,6 +501,11 @@ MainWindow *main_window_new( FALSE ); + gtk_widget_set_sensitive( + main_window->show_graph_button, + FALSE + ); + gtk_box_append( GTK_BOX(main_window->action_bar), main_window->new_investigation_button @@ -476,6 +521,11 @@ MainWindow *main_window_new( main_window->import_evidence_button ); + gtk_box_append( + GTK_BOX(main_window->action_bar), + main_window->show_graph_button + ); + gtk_box_append( GTK_BOX(main_window->action_bar), action_spacer @@ -513,6 +563,15 @@ MainWindow *main_window_new( main_window ); + g_signal_connect( + main_window->show_graph_button, + "clicked", + G_CALLBACK( + main_window_on_show_graph_clicked + ), + main_window + ); + g_signal_connect( main_window->quit_button, "clicked", @@ -937,6 +996,11 @@ void main_window_set_graph_loading( return; } + gtk_widget_set_sensitive( + main_window->show_graph_button, + FALSE + ); + workspace_set_graph_loading( main_window->workspace ); @@ -958,6 +1022,11 @@ void main_window_set_graph( graph_model, graph_layout ); + + gtk_widget_set_sensitive( + main_window->show_graph_button, + graph_model != NULL + ); } void main_window_set_graph_error( @@ -970,6 +1039,11 @@ void main_window_set_graph_error( return; } + gtk_widget_set_sensitive( + main_window->show_graph_button, + FALSE + ); + workspace_set_graph_error( main_window->workspace, message @@ -985,6 +1059,11 @@ void main_window_clear_graph( return; } + gtk_widget_set_sensitive( + main_window->show_graph_button, + FALSE + ); + workspace_clear_graph( main_window->workspace ); @@ -1113,6 +1192,24 @@ void main_window_set_import_evidence_callback( user_data; } +void main_window_set_show_graph_callback( + MainWindow *main_window, + MainWindowShowGraphCallback callback, + gpointer user_data +) +{ + if (main_window == NULL) + { + return; + } + + main_window->show_graph_callback = + callback; + + main_window->show_graph_user_data = + user_data; +} + void main_window_set_import_evidence_enabled( MainWindow *main_window, gboolean enabled @@ -1324,6 +1421,12 @@ void main_window_free( main_window->reset_graph_layout_user_data = NULL; + main_window->show_graph_callback = + NULL; + + main_window->show_graph_user_data = + NULL; + main_window_clear_graph( main_window ); @@ -1354,3 +1457,4 @@ void main_window_free( main_window ); } + diff --git a/src/widgets/workspace.c b/src/widgets/workspace.c index 9de20ad..e4cf2e9 100644 --- a/src/widgets/workspace.c +++ b/src/widgets/workspace.c @@ -49,6 +49,8 @@ struct Workspace GtkWidget *graph_view_page; GtkWidget *graph_toolbar; GtkWidget *reset_graph_layout_button; + GtkWidget *graph_help_button; + GtkWidget *graph_help_popover; InvestigationGraphView *graph_view; EntityDetailsPanel *entity_details_panel; @@ -1174,6 +1176,175 @@ Workspace *workspace_new(void) TRUE ); + workspace->graph_help_button = + gtk_menu_button_new(); + + workspace->graph_help_popover = + gtk_popover_new(); + + GtkWidget *graph_help_content = + gtk_box_new( + GTK_ORIENTATION_VERTICAL, + 8 + ); + + GtkWidget *graph_help_title = + gtk_label_new( + "Commandes du graphe" + ); + + GtkWidget *graph_help_text = + gtk_label_new( + "• Clic : sélectionner un nœud\n" + "• Glisser un nœud : le déplacer\n" + "• Maj + glisser : déplacer la vue\n" + "• Ctrl + molette : zoomer\n" + "• Pincement : zoomer" + ); + + if (workspace->graph_help_button == NULL || + workspace->graph_help_popover == NULL || + graph_help_content == NULL || + graph_help_title == NULL || + graph_help_text == NULL) + { + workspace_free( + workspace + ); + + return NULL; + } + + gtk_menu_button_set_label( + GTK_MENU_BUTTON( + workspace->graph_help_button + ), + "?" + ); + + gtk_widget_add_css_class( + workspace->graph_help_button, + "flat" + ); + + gtk_widget_set_tooltip_text( + workspace->graph_help_button, + "Afficher les commandes du graphe" + ); + + gtk_widget_set_can_target( + workspace->graph_help_button, + TRUE + ); + + gtk_widget_set_halign( + workspace->graph_help_button, + GTK_ALIGN_END + ); + + gtk_widget_set_valign( + workspace->graph_help_button, + GTK_ALIGN_START + ); + + gtk_widget_set_margin_end( + workspace->graph_help_button, + 12 + ); + + gtk_widget_set_margin_top( + workspace->graph_help_button, + 12 + ); + + gtk_widget_set_margin_start( + graph_help_content, + 16 + ); + + gtk_widget_set_margin_end( + graph_help_content, + 16 + ); + + gtk_widget_set_margin_top( + graph_help_content, + 14 + ); + + gtk_widget_set_margin_bottom( + graph_help_content, + 14 + ); + + gtk_label_set_xalign( + GTK_LABEL( + graph_help_title + ), + 0.0F + ); + + gtk_widget_add_css_class( + graph_help_title, + "heading" + ); + + gtk_label_set_xalign( + GTK_LABEL( + graph_help_text + ), + 0.0F + ); + + gtk_label_set_wrap( + GTK_LABEL( + graph_help_text + ), + TRUE + ); + + gtk_label_set_wrap_mode( + GTK_LABEL( + graph_help_text + ), + PANGO_WRAP_WORD_CHAR + ); + + gtk_label_set_max_width_chars( + GTK_LABEL( + graph_help_text + ), + 44 + ); + + gtk_box_append( + GTK_BOX( + graph_help_content + ), + graph_help_title + ); + + gtk_box_append( + GTK_BOX( + graph_help_content + ), + graph_help_text + ); + + gtk_popover_set_child( + GTK_POPOVER( + workspace->graph_help_popover + ), + graph_help_content + ); + + gtk_menu_button_set_popover( + GTK_MENU_BUTTON( + workspace->graph_help_button + ), + workspace->graph_help_popover + ); + gtk_overlay_add_overlay( GTK_OVERLAY( workspace->graph_view_page @@ -1193,6 +1364,22 @@ Workspace *workspace_new(void) TRUE ); + gtk_overlay_add_overlay( + GTK_OVERLAY( + workspace->graph_view_page + ), + workspace->graph_help_button + ); + + gtk_overlay_set_clip_overlay( + GTK_OVERLAY( + workspace->graph_view_page + ), + workspace->graph_help_button, + TRUE + ); + + gtk_stack_add_named( GTK_STACK(workspace->stack), workspace->graph_view_page, @@ -2022,6 +2209,12 @@ void workspace_free(Workspace *workspace) workspace->reset_graph_layout_button = NULL; + workspace->graph_help_button = + NULL; + + workspace->graph_help_popover = + NULL; + g_clear_pointer( &workspace->selected_evidence_identifier, g_free