feat(widget): create workspace
This commit is contained in:
parent
d16e0229c4
commit
b1f931d8f2
5 changed files with 360 additions and 19 deletions
153
docs/tickets/closed/TICKET-006.md
Normal file
153
docs/tickets/closed/TICKET-006.md
Normal file
|
|
@ -0,0 +1,153 @@
|
||||||
|
# Ticket #006
|
||||||
|
|
||||||
|
## Titre
|
||||||
|
|
||||||
|
Créer le module `Workspace`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Objectif
|
||||||
|
|
||||||
|
Créer un composant graphique représentant la zone principale de travail de Labfy Investigation.
|
||||||
|
|
||||||
|
Le module doit être indépendant du reste de l'interface afin de pouvoir évoluer sans modifier `MainWindow`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Responsabilités
|
||||||
|
|
||||||
|
Le module `Workspace` doit :
|
||||||
|
|
||||||
|
- créer la zone centrale de l'application ;
|
||||||
|
- afficher une page d'accueil lorsqu'aucune enquête n'est ouverte ;
|
||||||
|
- fournir un widget racine réutilisable ;
|
||||||
|
- gérer uniquement son interface graphique.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Hors périmètre
|
||||||
|
|
||||||
|
Ce ticket ne doit pas :
|
||||||
|
|
||||||
|
- afficher les preuves ;
|
||||||
|
- afficher les entités ;
|
||||||
|
- afficher un PDF ;
|
||||||
|
- afficher une image ;
|
||||||
|
- communiquer avec SQLite ;
|
||||||
|
- charger une enquête.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
```text
|
||||||
|
MainWindow
|
||||||
|
├── Sidebar
|
||||||
|
├── Workspace
|
||||||
|
└── StatusBar
|
||||||
|
```
|
||||||
|
|
||||||
|
Le module appartient à la couche **Widgets**.
|
||||||
|
|
||||||
|
Aucune logique métier.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Fichiers concernés
|
||||||
|
|
||||||
|
```text
|
||||||
|
include/widgets/workspace.h
|
||||||
|
src/widgets/workspace.c
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Interface publique
|
||||||
|
|
||||||
|
```c
|
||||||
|
Workspace *workspace_new(void);
|
||||||
|
|
||||||
|
GtkWidget *workspace_get_widget(
|
||||||
|
const Workspace *workspace
|
||||||
|
);
|
||||||
|
|
||||||
|
void workspace_free(
|
||||||
|
Workspace *workspace
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Interface graphique attendue
|
||||||
|
|
||||||
|
```text
|
||||||
|
+-------------------------------------------------------------+
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
| Labfy Investigation |
|
||||||
|
| |
|
||||||
|
| Aucune enquête ouverte |
|
||||||
|
| |
|
||||||
|
| Sélectionnez ou créez une enquête |
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
+-------------------------------------------------------------+
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Évolutions prévues
|
||||||
|
|
||||||
|
Cette zone accueillera plus tard :
|
||||||
|
|
||||||
|
- visualiseur d'image ;
|
||||||
|
- lecteur PDF ;
|
||||||
|
- chronologie ;
|
||||||
|
- fiche personne ;
|
||||||
|
- fiche IBAN ;
|
||||||
|
- fiche email ;
|
||||||
|
- fiche téléphone ;
|
||||||
|
- rapports ;
|
||||||
|
- cartes ;
|
||||||
|
- résultats OSINT.
|
||||||
|
|
||||||
|
Le module doit donc rester générique.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Contraintes
|
||||||
|
|
||||||
|
- GTK4 uniquement ;
|
||||||
|
- structure opaque ;
|
||||||
|
- aucune variable globale ;
|
||||||
|
- documentation Doxygen ;
|
||||||
|
- C17 ;
|
||||||
|
- compilation sans warning.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Critères d'acceptation
|
||||||
|
|
||||||
|
- [ ] Le projet compile.
|
||||||
|
- [ ] Le Workspace apparaît dans MainWindow.
|
||||||
|
- [ ] Le texte d'accueil est centré.
|
||||||
|
- [ ] Sidebar et Workspace sont totalement indépendants.
|
||||||
|
- [ ] Aucun warning.
|
||||||
|
- [ ] Aucun Gtk-CRITICAL.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Tests
|
||||||
|
|
||||||
|
- lancement ;
|
||||||
|
- redimensionnement de la fenêtre ;
|
||||||
|
- fermeture ;
|
||||||
|
- vérification visuelle.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Commit attendu
|
||||||
|
|
||||||
|
```text
|
||||||
|
feat(widget): create workspace
|
||||||
|
```
|
||||||
49
labfy-investigation/include/widgets/workspace.h
Normal file
49
labfy-investigation/include/widgets/workspace.h
Normal file
|
|
@ -0,0 +1,49 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* @file workspace.h
|
||||||
|
* @brief Interface publique de la zone principale de travail.
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#ifndef LABFY_INVESTIGATION_WORKSPACE_H
|
||||||
|
#define LABFY_INVESTIGATION_WORKSPACE_H
|
||||||
|
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Représentation opaque de la zone de travail.
|
||||||
|
*
|
||||||
|
* La structure réelle est définie dans workspace.c.
|
||||||
|
* Les autres modules manipulent uniquement un pointeur vers Workspace.
|
||||||
|
*/
|
||||||
|
typedef struct Workspace Workspace;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Crée une nouvelle zone de travail.
|
||||||
|
*
|
||||||
|
* @return Une nouvelle zone de travail, ou NULL en cas d'échec.
|
||||||
|
*/
|
||||||
|
Workspace *workspace_new(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Retourne le widget GTK racine de la zone de travail.
|
||||||
|
*
|
||||||
|
* Le widget retourné appartient au module Workspace et ne doit pas être
|
||||||
|
* détruit directement par le code appelant.
|
||||||
|
*
|
||||||
|
* @param workspace Zone de travail à consulter.
|
||||||
|
*
|
||||||
|
* @return Le widget racine, ou NULL si workspace est NULL.
|
||||||
|
*/
|
||||||
|
GtkWidget *workspace_get_widget(
|
||||||
|
const Workspace *workspace
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Libère la structure d'encapsulation de la zone de travail.
|
||||||
|
*
|
||||||
|
* Cette fonction accepte NULL.
|
||||||
|
*
|
||||||
|
* @param workspace Zone de travail à libérer.
|
||||||
|
*/
|
||||||
|
void workspace_free(Workspace *workspace);
|
||||||
|
|
||||||
|
#endif
|
||||||
Binary file not shown.
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
#include "views/main_window.h"
|
#include "views/main_window.h"
|
||||||
#include "widgets/sidebar.h"
|
#include "widgets/sidebar.h"
|
||||||
|
#include "widgets/workspace.h"
|
||||||
|
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
|
||||||
|
|
@ -35,7 +36,7 @@ struct MainWindow
|
||||||
GtkWindow *window;
|
GtkWindow *window;
|
||||||
GtkWidget *main_box;
|
GtkWidget *main_box;
|
||||||
GtkWidget *main_paned;
|
GtkWidget *main_paned;
|
||||||
GtkWidget *workspace;
|
Workspace *workspace;
|
||||||
GtkWidget *status_label;
|
GtkWidget *status_label;
|
||||||
Sidebar *sidebar;
|
Sidebar *sidebar;
|
||||||
};
|
};
|
||||||
|
|
@ -44,6 +45,7 @@ MainWindow *main_window_new(GtkApplication *application)
|
||||||
{
|
{
|
||||||
MainWindow *main_window = NULL;
|
MainWindow *main_window = NULL;
|
||||||
GtkWidget *sidebar_widget = NULL;
|
GtkWidget *sidebar_widget = NULL;
|
||||||
|
GtkWidget *workspace_widget = NULL;
|
||||||
|
|
||||||
if (application == NULL)
|
if (application == NULL)
|
||||||
{
|
{
|
||||||
|
|
@ -125,25 +127,24 @@ MainWindow *main_window_new(GtkApplication *application)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
main_window->workspace = workspace_new();
|
||||||
* La zone de travail est encore vide.
|
|
||||||
* Elle accueillera plus tard les pages de l'application.
|
if (main_window->workspace == NULL)
|
||||||
*/
|
{
|
||||||
main_window->workspace = gtk_box_new(
|
main_window_free(main_window);
|
||||||
GTK_ORIENTATION_VERTICAL,
|
return NULL;
|
||||||
0
|
}
|
||||||
);
|
|
||||||
|
workspace_widget = workspace_get_widget(
|
||||||
gtk_widget_set_hexpand(
|
main_window->workspace
|
||||||
main_window->workspace,
|
|
||||||
TRUE
|
|
||||||
);
|
|
||||||
|
|
||||||
gtk_widget_set_vexpand(
|
|
||||||
main_window->workspace,
|
|
||||||
TRUE
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (workspace_widget == NULL)
|
||||||
|
{
|
||||||
|
main_window_free(main_window);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Placement des deux composants dans GtkPaned.
|
* Placement des deux composants dans GtkPaned.
|
||||||
*/
|
*/
|
||||||
|
|
@ -154,7 +155,7 @@ MainWindow *main_window_new(GtkApplication *application)
|
||||||
|
|
||||||
gtk_paned_set_end_child(
|
gtk_paned_set_end_child(
|
||||||
GTK_PANED(main_window->main_paned),
|
GTK_PANED(main_window->main_paned),
|
||||||
main_window->workspace
|
workspace_widget
|
||||||
);
|
);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -280,6 +281,7 @@ void main_window_free(MainWindow *main_window)
|
||||||
*
|
*
|
||||||
* Les widgets GTK, eux, restent gérés par GTK.
|
* Les widgets GTK, eux, restent gérés par GTK.
|
||||||
*/
|
*/
|
||||||
|
workspace_free(main_window->workspace);
|
||||||
sidebar_free(main_window->sidebar);
|
sidebar_free(main_window->sidebar);
|
||||||
|
|
||||||
g_free(main_window);
|
g_free(main_window);
|
||||||
|
|
|
||||||
137
labfy-investigation/src/widgets/workspace.c
Normal file
137
labfy-investigation/src/widgets/workspace.c
Normal file
|
|
@ -0,0 +1,137 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* @file workspace.c
|
||||||
|
* @brief Implémentation de la zone principale de travail.
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#include "widgets/workspace.h"
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @struct Workspace
|
||||||
|
* @brief Représentation interne de la zone de travail.
|
||||||
|
*
|
||||||
|
* Cette structure reste privée au module. Les autres fichiers utilisent
|
||||||
|
* uniquement le type opaque déclaré dans workspace.h.
|
||||||
|
*/
|
||||||
|
struct Workspace
|
||||||
|
{
|
||||||
|
GtkWidget *root_widget;
|
||||||
|
GtkWidget *welcome_box;
|
||||||
|
GtkWidget *title_label;
|
||||||
|
GtkWidget *status_label;
|
||||||
|
GtkWidget *instruction_label;
|
||||||
|
};
|
||||||
|
|
||||||
|
Workspace *workspace_new(void)
|
||||||
|
{
|
||||||
|
Workspace *workspace = NULL;
|
||||||
|
|
||||||
|
workspace = g_new0(Workspace, 1);
|
||||||
|
|
||||||
|
workspace->root_widget = gtk_box_new(
|
||||||
|
GTK_ORIENTATION_VERTICAL,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
|
||||||
|
if (workspace->root_widget == NULL)
|
||||||
|
{
|
||||||
|
workspace_free(workspace);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
gtk_widget_set_hexpand(
|
||||||
|
workspace->root_widget,
|
||||||
|
TRUE
|
||||||
|
);
|
||||||
|
|
||||||
|
gtk_widget_set_vexpand(
|
||||||
|
workspace->root_widget,
|
||||||
|
TRUE
|
||||||
|
);
|
||||||
|
|
||||||
|
workspace->welcome_box = gtk_box_new(
|
||||||
|
GTK_ORIENTATION_VERTICAL,
|
||||||
|
12
|
||||||
|
);
|
||||||
|
|
||||||
|
if (workspace->welcome_box == NULL)
|
||||||
|
{
|
||||||
|
workspace_free(workspace);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Le conteneur d'accueil est centré horizontalement et verticalement
|
||||||
|
* dans l'espace disponible.
|
||||||
|
*/
|
||||||
|
gtk_widget_set_halign(
|
||||||
|
workspace->welcome_box,
|
||||||
|
GTK_ALIGN_CENTER
|
||||||
|
);
|
||||||
|
|
||||||
|
gtk_widget_set_valign(
|
||||||
|
workspace->welcome_box,
|
||||||
|
GTK_ALIGN_CENTER
|
||||||
|
);
|
||||||
|
|
||||||
|
workspace->title_label = gtk_label_new(
|
||||||
|
"Labfy Investigation"
|
||||||
|
);
|
||||||
|
|
||||||
|
workspace->status_label = gtk_label_new(
|
||||||
|
"Aucune enquête ouverte"
|
||||||
|
);
|
||||||
|
|
||||||
|
workspace->instruction_label = gtk_label_new(
|
||||||
|
"Sélectionnez ou créez une enquête"
|
||||||
|
);
|
||||||
|
|
||||||
|
gtk_box_append(
|
||||||
|
GTK_BOX(workspace->welcome_box),
|
||||||
|
workspace->title_label
|
||||||
|
);
|
||||||
|
|
||||||
|
gtk_box_append(
|
||||||
|
GTK_BOX(workspace->welcome_box),
|
||||||
|
workspace->status_label
|
||||||
|
);
|
||||||
|
|
||||||
|
gtk_box_append(
|
||||||
|
GTK_BOX(workspace->welcome_box),
|
||||||
|
workspace->instruction_label
|
||||||
|
);
|
||||||
|
|
||||||
|
gtk_box_append(
|
||||||
|
GTK_BOX(workspace->root_widget),
|
||||||
|
workspace->welcome_box
|
||||||
|
);
|
||||||
|
|
||||||
|
return workspace;
|
||||||
|
}
|
||||||
|
|
||||||
|
GtkWidget *workspace_get_widget(
|
||||||
|
const Workspace *workspace
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (workspace == NULL)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return workspace->root_widget;
|
||||||
|
}
|
||||||
|
|
||||||
|
void workspace_free(Workspace *workspace)
|
||||||
|
{
|
||||||
|
if (workspace == NULL)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Les widgets GTK sont intégrés dans l'arbre de widgets de MainWindow.
|
||||||
|
* GTK gère donc leur destruction.
|
||||||
|
*/
|
||||||
|
g_free(workspace);
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue