summaryrefslogtreecommitdiff
path: root/src/gui/panels/panel.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/panels/panel.c')
-rw-r--r--src/gui/panels/panel.c929
1 files changed, 542 insertions, 387 deletions
diff --git a/src/gui/panels/panel.c b/src/gui/panels/panel.c
index 01307cb..8af8672 100644
--- a/src/gui/panels/panel.c
+++ b/src/gui/panels/panel.c
@@ -25,6 +25,7 @@
#include "panel.h"
+#include <assert.h>
#include <ctype.h>
#include <string.h>
#include <sys/param.h>
@@ -38,6 +39,7 @@
#include "regedit.h"
#include "strings.h"
#include "symbols.h"
+#include "../../common/extstr.h"
#include "../../gtkext/easygtk.h"
#include "../../gtkext/gtkdockable-int.h"
#include "../../gtkext/gtkdockstation.h"
@@ -80,7 +82,7 @@ static GtkWidget *gtk_panel_item_get_widget(GPanelItem *);
/* Crée un nouveau noeud pour un panneau particulier. */
-static panel_node *create_simple_panel_node_for_item(GPanelItem *, const char *, size_t);
+//static panel_node *create_simple_panel_node_for_item(GPanelItem *, const char *, size_t);
/* Prépare une nouvelle sous-division pour deux panneaux. */
static void switch_panel_node_into_paned(panel_node *, bool, bool);
@@ -88,41 +90,34 @@ static void switch_panel_node_into_paned(panel_node *, bool, bool);
/* Met en place un nouveau noeud dans une division. */
static void attach_panel_node_to_paned(panel_node *, panel_node *, bool);
-/* Valorise la correspondance entre un noeud et un chemin. */
-static int compute_panel_node_matching_score(const panel_node *, const char *);
-/* Calcule la longueur du plus court chemin vers un 'M'. */
-static size_t _compute_panel_node_main_level(const panel_node *);
-/* Recherche le noeud constituant la branche principale. */
-static panel_node *find_main_panel_node_branch(panel_node *, panel_node *);
-/* Place au bon endroit un panneau donné. */
-static void insert_item_as_panel_node(GPanelItem *, panel_node *, const char *, size_t);
+/* Crée un nouveau noeud pour un panneau particulier. */
+static panel_node *create_simple_panel_node_for_item(GPanelItem *, const char *);
-/* Met à jour l'affichage suite à un changement hiérarchique. */
-static void rebuild_panels_interface(const panel_node *);
-/* ---------------------- REAJUSTEMENT AUTOMATIQUE DE L'ESPACE ---------------------- */
+/* Obtient la désignation d'un élément hiérarchie des noeuds. */
+static char *get_panel_node_path(const panel_node *);
+/* Détermine la plus grande longueur commune entre éléments. */
+static size_t compute_path_common_length(const panel_node *, const char *);
-/* Part réservée aux parties principales (en %) */
-#define MAIN_PART_PERCENT 70
+/* Détermine la plus grande profondeur d'un noeud de panneaux. */
+static unsigned int compute_deepest_depth(const panel_node *);
-/* Part minimale des petits composants (en %) */
-#define MIN_PART_PERCENT 20
+/* Place au bon endroit un panneau donné. */
+static void insert_item_as_panel_node(GPanelItem *, panel_node *, const char *, size_t);
+/* Tente de mettre la main sur une station d'accueil. */
+static panel_node *find_node_for_station(panel_node *, GtkWidget *);
-/* Met à jour l'affichage suite à un changement hiérarchique. */
-static void auto_resize_panels(GtkWidget *, GdkRectangle *, gpointer);
+/* Efface de l'organisation un noeud donné en place. */
+static void delete_panel_node(panel_node *);
-/* S'enquiert de la taille idéale pour un noeud. */
-static void get_panel_node_size_request(const panel_node *, GtkRequisition *);
-/* Impose une taille accordée à un noeud. */
-static void set_panel_node_size_request(const panel_node *, const GtkRequisition *);
@@ -167,6 +162,8 @@ static void g_panel_item_init(GPanelItem *item)
{
DL_LIST_ITEM_INIT(&item->link);
+ item->personality = PIP_INVALID;
+
}
@@ -239,7 +236,8 @@ void g_panel_item_init_ext(GPanelItem *item, GObject *ref, const char *name, con
/******************************************************************************
* *
-* Paramètres : ref = espace de référencement global. *
+* Paramètres : personality = nature du panneau à mettre en place. *
+* ref = espace de référencement global. *
* name = nom associé à l'élément. *
* lname = description longue du panneau. *
* widget = composant à présenter à l'affichage. *
@@ -253,12 +251,15 @@ void g_panel_item_init_ext(GPanelItem *item, GObject *ref, const char *name, con
* *
******************************************************************************/
-GEditorItem *g_panel_item_new(GObject *ref, const char *name, const char *lname, GtkWidget *widget, const char *path)
+GEditorItem *g_panel_item_new(PanelItemPersonality personality, GObject *ref, const char *name, const char *lname, GtkWidget *widget, const char *path)
{
GPanelItem *result; /* Structure à retourner */
result = g_object_new(G_TYPE_PANEL_ITEM, NULL);
+ assert(personality > PIP_INVALID && personality < PIP_COUNT);
+ result->personality = personality;
+
g_panel_item_init_ext(result, ref, name, lname, widget, path);
return G_EDITOR_ITEM(result);
@@ -325,6 +326,44 @@ static GtkWidget *gtk_panel_item_get_widget(GPanelItem *item)
/******************************************************************************
* *
+* Paramètres : item = instance GTK à consulter. *
+* *
+* Description : Fournit une indication sur la personnalité du panneau. *
+* *
+* Retour : Identifiant lié à la nature du panneau. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+PanelItemPersonality gtk_panel_item_get_personality(const GPanelItem *item)
+{
+ return item->personality;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : item = instance GTK dont l'interface est à consulter. *
+* *
+* Description : Indique la définition d'un éventuel raccourci clavier. *
+* *
+* Retour : Description d'un raccourci ou NULL si aucun de défini. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+const char *gtk_panel_item_get_key_bindings(const GPanelItem *item)
+{
+ return G_PANEL_ITEM_GET_CLASS(item)->bindings;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : name = désignation courte servant de clef. *
* *
* Description : Recherche un panneau à partir de son nom court. *
@@ -364,16 +403,95 @@ GPanelItem *g_panel_item_get(const char *name)
* *
******************************************************************************/
+static void dump_tree(GtkWidget *root, unsigned int level)
+{
+ unsigned int i;
+ GList *list;
+ GList *iter;
+
+ if (strcmp(G_OBJECT_TYPE_NAME(G_OBJECT(root)), "GtkButton") == 0)
+ return;
+
+ for (i = 0; i < level; i++)
+ fprintf(stderr, " ");
+
+ fprintf(stderr, "%s (%p)\n", G_OBJECT_TYPE_NAME(G_OBJECT(root)), root);
+
+ if (GTK_IS_CONTAINER(root))
+ {
+ list = gtk_container_get_children(GTK_CONTAINER(root));
+
+ for (iter = list; iter != NULL; iter = g_list_next(iter))
+ dump_tree(GTK_WIDGET(iter->data), level + 1);
+
+ }
+
+}
+
+
+void dump_node(panel_node *node, unsigned int level)
+{
+ unsigned i;
+
+ for (i = 0; i < level; i++)
+ fprintf(stderr, " ");
+
+ fprintf(stderr, "%p %p -- widget %p -- '%s'\n", node->parent, node, node->station,
+ IS_SIMPLE_NODE(node) ? node->path : "-");
+
+ if (!IS_SIMPLE_NODE(node))
+ {
+ dump_node(node->first, level + 1);
+ dump_node(node->second, level + 1);
+ }
+
+
+}
+
+
+
void g_panel_item_dock(GPanelItem *item)
{
+ assert(!item->docked);
+
+ fprintf(stderr, "\n---------\n\n");
+
/* Tout est à faire... */
if (_nodes == NULL)
{
- _nodes = create_simple_panel_node_for_item(item, item->path, 0);
- gtk_container_add(GTK_CONTAINER(_support), _nodes->station);
+ _nodes = create_simple_panel_node_for_item(item, item->path);
+ gtk_container_add(GTK_CONTAINER(_support), _nodes->widget);
}
else insert_item_as_panel_node(item, _nodes, item->path, 0);
+ item->docked = true;
+
+
+
+ dump_tree(_support, 0);
+ fprintf(stderr, "\n");
+ dump_node(_nodes, 0);
+
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : item = composant d'affichage à consulter. *
+* *
+* Description : Indique si le composant repose sur un support de l'éditeur. *
+* *
+* Retour : true si le composant est bien incrusté quelque part. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_panel_item_is_docked(const GPanelItem *item)
+{
+ return item->docked;
+
}
@@ -391,12 +509,25 @@ void g_panel_item_dock(GPanelItem *item)
void g_panel_item_undock(GPanelItem *item)
{
- GtkWidget *station; /* Base du remplacement */
+ GtkWidget *station; /* Support courant */
+ panel_node *node; /* Noeud à supprimer */
- station = gtk_widget_get_parent(G_EDITOR_ITEM(item)->widget); /* NoteBook */
- station = gtk_widget_get_parent(station); /* DockStation */
+ assert(item->docked);
- gtk_dock_panel_remove_widget(GTK_DOCK_STATION(station), G_EDITOR_ITEM(item)->widget);
+ gtk_dockable_decompose(GTK_DOCKABLE(item), &station);
+
+ gtk_dock_station_remove_dockable(GTK_DOCK_STATION(station), GTK_DOCKABLE(item));
+
+ if (gtk_notebook_get_n_pages(GTK_NOTEBOOK(station)) == 0)
+ {
+ node = find_node_for_station(_nodes, station);
+ assert(node != NULL);
+
+ delete_panel_node(node);
+
+ }
+
+ item->docked = false;
}
@@ -427,7 +558,7 @@ GtkWidget *init_panels2(GCallback handler, gpointer data)
result = gtk_event_box_new();
gtk_widget_show(result);
- g_signal_connect(result, "size-allocate", G_CALLBACK(auto_resize_panels), NULL);
+ //g_signal_connect(result, "size-allocate", G_CALLBACK(auto_resize_panels), NULL);
_support = result;
_handler = handler;
@@ -454,10 +585,10 @@ void load_main_panels(GObject *ref)
{
GPanelItem *item; /* Panneau de base à charger */
- item = create_regedit_panel(ref);
+ item = create_log_panel(ref);
g_panel_item_dock(item);
- item = create_log_panel(ref);
+ item = create_regedit_panel(ref);
g_panel_item_dock(item);
item = create_symbols_panel(ref);
@@ -478,54 +609,49 @@ void load_main_panels(GObject *ref)
}
-
-/* ---------------------------------------------------------------------------------- */
-/* MECANISMES DE PLACEMENT DES PANNEAUX */
-/* ---------------------------------------------------------------------------------- */
-
-
/******************************************************************************
* *
-* Paramètres : item = composant à présenter à l'affichage. *
-* path = partie du chemin représentée ici. *
-* depth = profondeur du chemin utilisé. *
+* Paramètres : handle = routine à appeler pour chaque panneau. *
+* data = données fournies pour accompagner cet appel. *
* *
-* Description : Crée un nouveau noeud pour un panneau particulier. *
+* Description : Effectue le parcours de tous les panneaux chargés. *
* *
-* Retour : Structure d'accueil mise en place. *
+* Retour : true si le parcours a été total, false sinon. *
* *
* Remarques : - *
* *
******************************************************************************/
-static panel_node *create_simple_panel_node_for_item(GPanelItem *item, const char *path, size_t depth)
+bool browse_all_item_panels(handle_panel_item_fc handle, void *data)
{
- panel_node *result; /* Structure à retourner */
- GtkWidget *station; /* Premier support concentré */
-
- result = (panel_node *)calloc(1, sizeof(panel_node));
-
- result->path = strdup(path);
- result->depth = depth;
+ bool result; /* Résultat à renvoyer */
+ GPanelItem *iter; /* Boucle de parcours */
- result->simple = true;
+ result = true;
- station = gtk_dock_station_new();
- g_signal_connect(station, "switch-widget", _handler, _data);
- gtk_widget_show(station);
+ panels_list_for_each(iter, _panels_list)
+ {
+ result = handle(iter, data);
- result->station = station;
+ if (!result) break;
- gtk_dock_station_add_dockable(GTK_DOCK_STATION(station), GTK_DOCKABLE(item));
+ }
return result;
}
+
+/* ---------------------------------------------------------------------------------- */
+/* MECANISMES DE PLACEMENT DES PANNEAUX */
+/* ---------------------------------------------------------------------------------- */
+
+
+
/******************************************************************************
* *
-* Paramètres : item = composant à présenter à l'affichage. *
+* Paramètres : node = noeud à diviser. *
* horiz = indique le type d'orientation désiré. *
* first = indication sur l'emplacement à utiliser. *
* *
@@ -537,51 +663,98 @@ static panel_node *create_simple_panel_node_for_item(GPanelItem *item, const cha
* *
******************************************************************************/
-static void switch_panel_node_into_paned(panel_node *current, bool horiz, bool first)
+static void switch_panel_node_into_paned(panel_node *node, bool horiz, bool first)
{
- panel_node *moved; /* Noeud descendu d'un étage */
GtkWidget *widget; /* Composant à traiter */
+ panel_node *parent; /* Lien de parenté à conserver */
+ panel_node *moved; /* Noeud descendu d'un étage */
+
+ /* Décroche graphiquement le support */
+
+ widget = node->widget;
+
+ g_object_ref(G_OBJECT(widget));
+ gtk_container_remove(GTK_CONTAINER(gtk_widget_get_parent(widget)), widget);
/* Descend l'élément actuel */
+ parent = node->parent;
+
moved = (panel_node *)calloc(1, sizeof(panel_node));
- memcpy(moved, current, sizeof(panel_node));
- moved->parent = current;
+ memcpy(moved, node, sizeof(panel_node));
- widget = GET_PANEL_NODE_WIDGET(current);
+ if (!IS_SIMPLE_NODE(moved))
+ {
+ moved->first->parent = moved;
+ moved->second->parent = moved;
+ }
- g_object_ref(G_OBJECT(widget));
- gtk_container_remove(GTK_CONTAINER(gtk_widget_get_parent(widget)), widget);
+ /* Création du nouveau niveau intermédiaire */
- if (first)
- current->first = moved;
+ if (horiz)
+ node->paned = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL);
else
- current->second = moved;
+ node->paned = gtk_paned_new(GTK_ORIENTATION_VERTICAL);
- /* Achève la transformation */
+ gtk_widget_show(node->paned);
- current->path = NULL;
+ if (parent == NULL)
+ attach_panel_node_to_paned(parent, node, true);
+ else
+ attach_panel_node_to_paned(parent, node, parent->first == node);
- current->simple = false;
- current->station = NULL;
- if (horiz)
- current->paned = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL);
- else
- current->paned = gtk_paned_new(GTK_ORIENTATION_VERTICAL);
- gtk_widget_show(current->paned);
+ /* Premier ajustement */
- /* Replace le composant d'origine */
+ void split_paned_support(GtkWidget *support, GdkRectangle *alloc, gpointer data)
+ {
+ GtkOrientation orientation;
+ gint position;
- if (first)
- gtk_paned_add1(GTK_PANED(current->paned), widget);
- else
- gtk_paned_add2(GTK_PANED(current->paned), widget);
+ orientation = gtk_orientable_get_orientation(GTK_ORIENTABLE(support));
+
+ if (orientation == GTK_ORIENTATION_HORIZONTAL)
+ position = alloc->width / 2;
+ else
+ position = alloc->height / 2;
+
+ /*
+ if (position < 50)
+ position *= 2;
+ */
+
+ gtk_paned_set_position(GTK_PANED(support), position);
+
+ fprintf(stderr, "widget size is currently %dx%d\n", alloc->width, alloc->height);
+
+
+ fprintf(stderr, "position = %d\n", position);
+
+ fprintf(stderr, "---\n");
+
+
+ g_signal_handlers_disconnect_by_func(support, G_CALLBACK(split_paned_support), NULL);
+
+ }
+
+ //g_signal_connect(current->paned, "size-allocate", G_CALLBACK(split_paned_support), NULL);
+
+ static int __counter = 0;
+
+
+
+ if (++__counter == 4)
+ gtk_paned_set_position(GTK_PANED(node->paned), 100);
+
+
+
+
+ /* Replace le composant d'origine */
- g_object_unref(G_OBJECT(widget));
+ attach_panel_node_to_paned(node, moved, first);
}
@@ -602,67 +775,143 @@ static void switch_panel_node_into_paned(panel_node *current, bool horiz, bool f
static void attach_panel_node_to_paned(panel_node *parent, panel_node *node, bool first)
{
- GtkWidget *widget; /* Composant à traiter */
+ node->parent = parent;
+
+ /* On se trouve à la racine... */
- /* Raccordement hiérarchique */
+ if (parent == NULL)
+ gtk_container_add(GTK_CONTAINER(_support), node->widget);
- if (first)
- parent->first = node;
else
- parent->second = node;
+ {
+ /* Raccordement hiérarchique */
- node->parent = parent;
+ if (first)
+ parent->first = node;
+ else
+ parent->second = node;
- /* Raccordement graphique */
+ /* Raccordement graphique */
- widget = GET_PANEL_NODE_WIDGET(node);
+ assert(!IS_SIMPLE_NODE(parent));
- if (first)
- gtk_paned_add1(GTK_PANED(parent->paned), widget);
- else
- gtk_paned_add2(GTK_PANED(parent->paned), widget);
+ if (first)
+ gtk_paned_pack1(GTK_PANED(parent->paned), node->widget, TRUE, FALSE);
+ else
+ gtk_paned_pack2(GTK_PANED(parent->paned), node->widget, TRUE, FALSE);
+
+ }
}
+
+
+
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+
+
+
+
+
+
+
+
/******************************************************************************
* *
-* Paramètres : node = noeud d'où lancer les recherches. *
-* target = identifiant de la position visée. *
+* Paramètres : item = composant à présenter à l'affichage. *
+* path = partie du chemin représentée ici. *
* *
-* Description : Valorise la correspondance entre un noeud et un chemin. *
+* Description : Crée un nouveau noeud pour un panneau particulier. *
* *
-* Retour : Bilan de l'évaluation. *
+* Retour : Structure d'accueil mise en place. *
* *
* Remarques : - *
* *
******************************************************************************/
-static int compute_panel_node_matching_score(const panel_node *node, const char *target)
+static panel_node *create_simple_panel_node_for_item(GPanelItem *item, const char *path)
{
- int result; /* Bilan à retourner */
- size_t len; /* Longueur de comparaison */
- size_t i; /* Boucle de parcours */
+ panel_node *result; /* Structure à retourner */
+ GtkWidget *station; /* Premier support concentré */
- if (node->simple)
- {
- result = 0;
+ /* Partie graphique */
- len = strlen(node->path);
- len = MIN(len, strlen(target));
+ station = gtk_dock_station_new();
+ g_signal_connect(station, "switch-widget", _handler, _data);
+ gtk_widget_show(station);
- for (i = 0; i < len; i++)
- {
- if (node->path[i] != target[i]) break;
- else result++;
- }
+ gtk_dock_station_add_dockable(GTK_DOCK_STATION(station), GTK_DOCKABLE(item));
- }
+ /* Partie invisible */
+
+ result = (panel_node *)calloc(1, sizeof(panel_node));
+
+ result->station = station;
+
+ result->path = strdup(path);
+
+ return result;
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/******************************************************************************
+* *
+* Paramètres : node = noeud dont la désignation est à obtenir. *
+* *
+* Description : Obtient la désignation d'un élément hiérarchie des noeuds. *
+* *
+* Retour : Chaîne construite à libérer de la mémoire après usage. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static char *get_panel_node_path(const panel_node *node)
+{
+ char *result; /* Valeur à retourner */
+ char *extra; /* Complément à ajouter */
+
+ if (IS_SIMPLE_NODE(node))
+ result = strdup(node->path);
else
{
- result = compute_panel_node_matching_score(node->first, target);
- result = MAX(result, compute_panel_node_matching_score(node->second, target));
+ result = get_panel_node_path(node->first);
+
+ extra = get_panel_node_path(node->second);
+ result = stradd(result, "-");
+ result = stradd(result, extra);
+ free(extra);
+
+ result = strprep(result, "(");
+ result = stradd(result, ")");
+
+
}
return result;
@@ -673,8 +922,9 @@ static int compute_panel_node_matching_score(const panel_node *node, const char
/******************************************************************************
* *
* Paramètres : node = noeud d'où lancer les recherches. *
+* target = identifiant de la position visée. *
* *
-* Description : Calcule la longueur du plus court chemin vers un 'M'. *
+* Description : Détermine la plus grande longueur commune entre éléments. *
* *
* Retour : Bilan de l'évaluation. *
* *
@@ -682,23 +932,34 @@ static int compute_panel_node_matching_score(const panel_node *node, const char
* *
******************************************************************************/
-static size_t _compute_panel_node_main_level(const panel_node *node)
+static size_t compute_path_common_length(const panel_node *node, const char *target)
{
- size_t result; /* Plus petit chemin à renvoyer*/
+ size_t result; /* Taille à retourner */
+ size_t len; /* Longueur de comparaison */
+ size_t common1; /* Tron common avec le côté #1 */
+ size_t common2; /* Tron common avec le côté #2 */
- if (node->simple)
+ if (IS_SIMPLE_NODE(node))
{
- result = strcspn(&node->path[node->depth], "M");
+ len = MIN(strlen(node->path), strlen(target));
- if (node->path[node->depth + result] == '\0')
- result = SIZE_MAX;
+ /**
+ * Il n'y a pas forcément de base commune entre deux branches,
+ * donc on parcourt les chemins depuis leur base respective.
+ */
+ for (result = 0; result < len; result++)
+ if (node->path[result] != target[result])
+ break;
}
else
{
- result = _compute_panel_node_main_level(node->first);
- result = MIN(result, _compute_panel_node_main_level(node->second));
+ common1 = compute_path_common_length(node->first, target);
+ common2 = compute_path_common_length(node->second, target);
+
+ result = MAX(common1, common2);
+
}
return result;
@@ -708,31 +969,33 @@ static size_t _compute_panel_node_main_level(const panel_node *node)
/******************************************************************************
* *
-* Paramètres : a = première branche à analyser. *
-* b = seconde branche à analyser. *
+* Paramètres : node = noeud d'où lancer les mesures. *
* *
-* Description : Recherche le noeud constituant la branche principale. *
+* Description : Détermine la plus grande profondeur d'un noeud de panneaux. *
* *
-* Retour : Branche principale ou NULL si aucune n'est idéale. *
+* Retour : Valeur strictement positive. *
* *
* Remarques : - *
* *
******************************************************************************/
-static panel_node *find_main_panel_node_branch(panel_node *a, panel_node *b)
+static unsigned int compute_deepest_depth(const panel_node *node)
{
- panel_node *result; /* Trouvaille à remonter */
- size_t main_a; /* Proximité du 'M' côté a */
- size_t main_b; /* Proximité du 'M' côté b */
-
- main_a = _compute_panel_node_main_level(a);
- main_b = _compute_panel_node_main_level(b);
+ unsigned int result; /* Profondeur à renvoyer */
+ unsigned int depth1; /* Profondeur du côté #1 */
+ unsigned int depth2; /* Profondeur du côté #2 */
- if (main_a == SIZE_MAX && main_b == SIZE_MAX)
- result = NULL;
+ if (IS_SIMPLE_NODE(node))
+ result = 1;
else
- result = (main_a < main_b ? a : b);
+ {
+ depth1 = compute_deepest_depth(node->first);
+ depth2 = compute_deepest_depth(node->second);
+
+ result = MAX(depth1, depth2);
+
+ }
return result;
@@ -741,10 +1004,10 @@ static panel_node *find_main_panel_node_branch(panel_node *a, panel_node *b)
/******************************************************************************
* *
-* Paramètres : item = composant à présenter à l'affichage. *
-* node = point d'insertion courant. *
-* path = partie du chemin représentée ici. *
-* depth = profondeur du chemin utilisé. *
+* Paramètres : item = composant à présenter à l'affichage. *
+* node = point d'insertion courant. *
+* path = partie du chemin représentée ici. *
+* consumed = profondeur du chemin utilisé. *
* *
* Description : Place au bon endroit un panneau donné. *
* *
@@ -754,58 +1017,47 @@ static panel_node *find_main_panel_node_branch(panel_node *a, panel_node *b)
* *
******************************************************************************/
-static void insert_item_as_panel_node(GPanelItem *item, panel_node *node, const char *path, size_t depth)
+static void insert_item_as_panel_node(GPanelItem *item, panel_node *node, const char *path, size_t consumed)
{
char div; /* Division demandée */
bool horiz; /* Traduction en composant */
bool first; /* Point d'insertion */
panel_node *new; /* Nouveau noeud créé */
- int score1; /* Score de la 1ère branche */
- int score2; /* Score de la 2nde branche */
- panel_node *support; /* Noeud d'accueil désigné */
+ size_t common1; /* Tron common avec le côté #1 */
+ size_t common2; /* Tron common avec le côté #2 */
- if (node->simple)
- {
- /* Si on est sur la bonne voie... */
- if (compute_panel_node_matching_score(node, path) > 0)
- {
- /* Le parcours s'arrête ici ! */
- if (strcmp(node->path, path) == 0)
- gtk_dock_station_add_dockable(GTK_DOCK_STATION(node->station), GTK_DOCKABLE(item));
- /* On ne peut aller plus loin, on doit diviser... */
- else
- {
- div = toupper(path[depth]);
- first = (div == 'E' || div == 'S');
- horiz = (div == 'W' || div == 'E');
-
- switch_panel_node_into_paned(node, horiz, first);
-
- new = create_simple_panel_node_for_item(item, path, depth);
+ fprintf(stderr, "=== INSERTING '%s' (%zu)... -> '%s'\n", path, consumed,
+ IS_SIMPLE_NODE(node) ? node->path : "-");
- attach_panel_node_to_paned(node, new, !first);
- rebuild_panels_interface(node);
- }
-
- }
+ if (IS_SIMPLE_NODE(node))
+ {
+ /* Le parcours s'arrête ici ! */
+ if (strcmp(node->path, path) == 0)
+ gtk_dock_station_add_dockable(GTK_DOCK_STATION(node->station), GTK_DOCKABLE(item));
/* On ne peut aller plus loin, on doit diviser... */
else
{
- div = toupper(path[depth]);
- first = (div == 'E' || div == 'S');
+ div = toupper(path[consumed]);
+ first = (div == 'W' || div == 'N');
horiz = (div == 'W' || div == 'E');
- switch_panel_node_into_paned(node, horiz, first);
+ fprintf(stderr, "---%%<--- first=%d horiz=%d\n", first, horiz);
- new = create_simple_panel_node_for_item(item, path, depth);
+ fprintf(stderr, "--- cutting %p\n", node->station);
- attach_panel_node_to_paned(node, new, !first);
+ switch_panel_node_into_paned(node, horiz, !first);
- rebuild_panels_interface(node);
+ new = create_simple_panel_node_for_item(item, path);
+
+ attach_panel_node_to_paned(node, new, first);
+
+
+ fprintf(stderr, "1# [%p] widget = %p --- split :: %p // %p\n",
+ node, node->station, node->first, node->second);
}
@@ -815,62 +1067,44 @@ static void insert_item_as_panel_node(GPanelItem *item, panel_node *node, const
else
{
- score1 = compute_panel_node_matching_score(node->first, path);
- score2 = compute_panel_node_matching_score(node->second, path);
+ common1 = compute_path_common_length(node->first, path);
+ common2 = compute_path_common_length(node->second, path);
+
+
+ fprintf(stderr, " - L1 :: %zu <-> '%s'\n", common1, get_panel_node_path(node->first));
+ fprintf(stderr, " - L2 :: %zu <-> '%s'\n", common2, get_panel_node_path(node->second));
+
/* Si une descente est possible... */
- if (score1 > 0 || score2 > 0)
+ if (common1 > 0 || common2 > 0)
{
- if (node->first->simple || node->second->simple)
- depth++;
-
- if (score1 > score2)
- insert_item_as_panel_node(item, node->first, path, depth);
+ if (common1 > common2)
+ insert_item_as_panel_node(item, node->first, path, common1);
else
- insert_item_as_panel_node(item, node->second, path, depth);
+ insert_item_as_panel_node(item, node->second, path, common2);
}
/* Sinon, on doit diviser qqch... */
else
{
- /* Si l'élément doit passer en force */
- if (isupper(path[depth]))
- {
- div = path[depth];
- first = (div == 'E' || div == 'S');
- horiz = (div == 'W' || div == 'E');
-
- switch_panel_node_into_paned(node, horiz, first);
-
- new = create_simple_panel_node_for_item(item, path, depth);
-
- attach_panel_node_to_paned(node, new, !first);
-
- rebuild_panels_interface(node);
-
- }
-
- else
- {
- support = find_main_panel_node_branch(node->first, node->second);
- if (support == NULL)
- support = node->first;
+ div = toupper(path[consumed]);
+ first = (div == 'W' || div == 'N');
+ horiz = (div == 'W' || div == 'E');
- div = toupper(path[depth]);
- first = (div == 'E' || div == 'S');
- horiz = (div == 'W' || div == 'E');
+ fprintf(stderr, "---%%<--- first=%d horiz=%d\n", first, horiz);
- switch_panel_node_into_paned(support, horiz, first);
+ switch_panel_node_into_paned(node, horiz, !first);
- new = create_simple_panel_node_for_item(item, path, depth);
+ new = create_simple_panel_node_for_item(item, path);
- attach_panel_node_to_paned(support, new, !first);
+ attach_panel_node_to_paned(node, new, first);
- rebuild_panels_interface(support);
- }
+ fprintf(stderr, "2# [%p] split :: %p-%p // %p-%p\n", node,
+ node->first, node->first->widget,
+ node->second, node->second->widget);
}
@@ -881,55 +1115,42 @@ static void insert_item_as_panel_node(GPanelItem *item, panel_node *node, const
/******************************************************************************
* *
-* Paramètres : current = point de départ de la réorganisation graphique. *
+* Paramètres : node = point de départ des recherches locales. *
* *
-* Description : Met à jour l'affichage suite à un changement hiérarchique. *
+* Description : Tente de mettre la main sur une station d'accueil. *
* *
-* Retour : - *
+* Retour : Eventuel noeud trouvé ou NULL. *
* *
* Remarques : - *
* *
******************************************************************************/
-static void rebuild_panels_interface(const panel_node *current)
+static panel_node *find_node_for_station(panel_node *node, GtkWidget *station)
{
- GtkWidget *widget; /* Composant à traiter */
- panel_node *parent; /* Raccourci confortable */
-
- widget = GET_PANEL_NODE_WIDGET(current);
+ panel_node *result; /* Bilan à remonter */
- /* On se trouve à la racine... */
- if (current->parent == NULL)
- gtk_container_add(GTK_CONTAINER(_support), widget);
+ if (IS_SIMPLE_NODE(node))
+ result = (node->station == station ? node : NULL);
- /* Sinon, une sous-division ne peut venir que d'une division... */
else
{
- /* BUG_ON(parent->simple) */
-
- parent = current->parent;
+ result = find_node_for_station(node->first, station);
- if (current == parent->first)
- gtk_paned_add1(GTK_PANED(parent->paned), widget);
- else
- gtk_paned_add2(GTK_PANED(parent->paned), widget);
+ if (result == NULL)
+ result = find_node_for_station(node->second, station);
}
-}
-
-
+ return result;
-/* ---------------------------------------------------------------------------------- */
-/* REAJUSTEMENT AUTOMATIQUE DE L'ESPACE */
-/* ---------------------------------------------------------------------------------- */
+}
/******************************************************************************
* *
-* Paramètres : current = point de départ de la réorganisation graphique. *
+* Paramètres : node = noeud à supprimer de l'arbre des noeuds. *
* *
-* Description : Met à jour l'affichage suite à un changement hiérarchique. *
+* Description : Efface de l'organisation un noeud donné en place. *
* *
* Retour : - *
* *
@@ -937,77 +1158,91 @@ static void rebuild_panels_interface(const panel_node *current)
* *
******************************************************************************/
-static void auto_resize_panels(GtkWidget *support, GdkRectangle *alloc, gpointer data)
+static void delete_panel_node(panel_node *node)
{
- GtkRequisition available; /* Taille disponible */
+ panel_node *parent; /* Noeud parent à transformer */
+ GtkWidget *widget; /* Composant à traiter */
+ panel_node *grandparent; /* Noeud supérieur au parent */
+ panel_node *remaining; /* Noeud restant */
- //g_signal_handlers_disconnect_by_func(support, G_CALLBACK(auto_resize_panels), NULL);
+ assert(IS_SIMPLE_NODE(node));
- available.width = alloc->width;
- available.height = alloc->height;
+ parent = node->parent;
- set_panel_node_size_request(_nodes, &available);
+ /* Destruction du noeud */
- //g_signal_connect(support, "size-allocate", G_CALLBACK(auto_resize_panels), NULL);
+ widget = node->station;
+ gtk_container_remove(GTK_CONTAINER(gtk_widget_get_parent(widget)), widget);
-}
+ free(node->path);
+ free(node);
-/******************************************************************************
-* *
-* Paramètres : node = noeud à consulter. *
-* req = taille demandée par le noeud. [OUT] *
-* *
-* Description : S'enquiert de la taille idéale pour un noeud. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
+ /* Suppression du niveau intermédiaire */
-static void get_panel_node_size_request(const panel_node *node, GtkRequisition *req)
-{
- gint handle_size; /* Taille de la séparation */
- GtkRequisition tmp; /* Stockage temporaire */
+ if (parent != NULL)
+ {
+ remaining = (node == parent->first ? parent->second : parent->first);
- if (node->simple)
- gtk_widget_get_preferred_size(node->station, NULL, req);
+ /* Décroche graphiquement le support */
- else
- {
- gtk_widget_style_get(node->paned, "handle-size", &handle_size, NULL);
+ widget = remaining->widget;
- if (HAS_H_ORIENTATION(node->paned))
- {
- req->width = handle_size;
- req->height = 0;
- }
- else
+ g_object_ref(G_OBJECT(widget));
+ gtk_container_remove(GTK_CONTAINER(parent->paned), widget);
+
+ /* Supprime le composant graphique intermédiaire */
+
+ gtk_container_remove(GTK_CONTAINER(gtk_widget_get_parent(parent->paned)), parent->paned);
+
+ /* Réinsère la partie restante */
+
+ grandparent = parent->parent;
+
+ memcpy(parent, remaining, sizeof(panel_node));
+
+ if (!IS_SIMPLE_NODE(parent))
{
- req->width = 0;
- req->height = handle_size;
+ parent->first->parent = parent;
+ parent->second->parent = parent;
}
- get_panel_node_size_request(node->first, &tmp);
- req->width += tmp.width;
- req->height += tmp.height;
+ free(remaining);
- get_panel_node_size_request(node->second, &tmp);
- req->width += tmp.width;
- req->height += tmp.height;
+ if (grandparent == NULL)
+ attach_panel_node_to_paned(grandparent, parent, true);
+ else
+ attach_panel_node_to_paned(grandparent, parent, grandparent->first == parent);
}
}
+
+
+
+
+
+
+
+
+
+
+
+
+#if 1
+
+
+#include "../../core/params.h"
+
+
+
/******************************************************************************
* *
-* Paramètres : node = noeud à consulter. *
-* space = taille disponible pour le noeud. *
+* Paramètres : current = point de départ de la réorganisation graphique. *
* *
-* Description : Impose une taille accordée à un noeud. *
+* Description : Met à jour l'affichage suite à un changement hiérarchique. *
* *
* Retour : - *
* *
@@ -1015,125 +1250,45 @@ static void get_panel_node_size_request(const panel_node *node, GtkRequisition *
* *
******************************************************************************/
-static void set_panel_node_size_request(const panel_node *node, const GtkRequisition *space)
+void save_panel_nodes(void)
{
- GtkRequisition first_req; /* Taille demandée par n°1 */
- GtkRequisition second_req; /* Taille demandée par n°2 */
- gint handle_size; /* Taille de la séparation */
- panel_node *main_node; /* Branche principale */
- gint position; /* Position de la séparation */
- bool can_lower; /* Diminution possible ? */
- bool can_upper; /* Augmentation possible ? */
- GtkAllocation allocation; /* Taille allouée */
-
- /* Pour les cas simple, GTK gère très bien... */
- if (node->simple) return;
-
- get_panel_node_size_request(node->first, &first_req);
- get_panel_node_size_request(node->second, &second_req);
- gtk_widget_style_get(node->paned, "handle-size", &handle_size, NULL);
- /**
- * Définitions des bornes dans chacun des cas.
- */
+ fprintf(stderr, "Passage avec %p\n", _nodes);
- main_node = find_main_panel_node_branch(node->first, node->second);
-
- /* Le premier noeud est le principal... */
- if (node->first == main_node)
+ return;
+ void store_handle_position(panel_node *node, GGenConfig *config)
{
- if (HAS_H_ORIENTATION(node->paned))
- position = (space->width * MAIN_PART_PERCENT) / 100;
- else
- position = (space->height * MAIN_PART_PERCENT) / 100;
- can_lower = false;
- can_upper = true;
+ size_t i;
- }
+ for (i = 0; i < 0/*node->depth*/; i++)
+ fprintf(stderr, " ");
- /* Le second noeud est le principal... */
- else if (node->second == main_node)
- {
- if (HAS_H_ORIENTATION(node->paned))
- position = space->width - (space->width * MAIN_PART_PERCENT) / 100;
- else
- position = space->height - (space->height * MAIN_PART_PERCENT) / 100;
- can_lower = true;
- can_upper = false;
+ ///fprintf(stderr, "[%s] %s\n", node->path, node->simple ? "[+]" : ">>");
- }
- /* Les éléments sont quelconques... */
- else
- {
- if (HAS_H_ORIENTATION(node->paned))
- position = space->width / 2;
- else
- position = space->height / 2;
-
- can_lower = true;
- can_upper = true;
-
- }
-
- /**
- * Calcul des valeurs applicables et mise en application.
- */
-
- /* Correctifs éventuels pour les petits composants */
- if (node->first == main_node)
- {
- if (HAS_H_ORIENTATION(node->paned))
- second_req.width = MAX(second_req.width, (space->width * MIN_PART_PERCENT) / 100);
- else
- second_req.height = MAX(second_req.height, (space->height * MIN_PART_PERCENT) / 100);
- }
- else if (node->second == main_node)
- {
- if (HAS_H_ORIENTATION(node->paned))
- first_req.width = MAX(first_req.width, (space->width * MIN_PART_PERCENT) / 100);
- else
- first_req.height = MAX(first_req.height, (space->height * MIN_PART_PERCENT) / 100);
- }
+ if (0/*!node->simple*/)
+ {
+ store_handle_position(node->first, config);
+ store_handle_position(node->second, config);
+ }
- /* Une partie principale arrive en premier */
- if (!can_lower && can_upper)
- {
- if (HAS_H_ORIENTATION(node->paned))
- position = MAX(position, space->width - second_req.width - handle_size);
- else
- position = MAX(position, space->height - second_req.height - handle_size);
- }
- /* Une partie principale arrive en second */
- else if (can_lower && !can_upper)
- {
- if (HAS_H_ORIENTATION(node->paned))
- position = MIN(position, second_req.width + handle_size);
- else
- position = MIN(position, second_req.height + handle_size);
}
- /* Chacun pour soit ! */
- else
- {
+ //get_main_configuration()
- /* TODO */;
+ store_handle_position(_nodes, NULL);
+ fflush(NULL);
- }
- gtk_paned_set_position(GTK_PANED(node->paned), position);
+}
- gtk_widget_get_allocation(GET_PANEL_NODE_WIDGET(node->first), &allocation);
- set_panel_node_size_request(node->first, ALLOC_2_REQ(&allocation));
+#endif
- gtk_widget_get_allocation(GET_PANEL_NODE_WIDGET(node->second), &allocation);
- set_panel_node_size_request(node->second, ALLOC_2_REQ(&allocation));
-}