summaryrefslogtreecommitdiff
path: root/src/glibext
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2013-06-02 13:01:31 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2013-06-02 13:01:31 (GMT)
commitc23e671df7621ad85f590eee14e6fa7c7e71a526 (patch)
tree4cc2220c58cb416bff9d5b929fdf7e2c34b123f2 /src/glibext
parentd80df591b6104c98d21e1db5143610fb84e35941 (diff)
Saved some progress about edition views.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@348 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/glibext')
-rw-r--r--src/glibext/gbufferline.c65
-rw-r--r--src/glibext/gbufferline.h5
-rw-r--r--src/glibext/gbuffersegment.c51
-rw-r--r--src/glibext/gbuffersegment.h3
-rw-r--r--src/glibext/gcodebuffer.c180
-rw-r--r--src/glibext/gcodebuffer.h8
6 files changed, 294 insertions, 18 deletions
diff --git a/src/glibext/gbufferline.c b/src/glibext/gbufferline.c
index 95d6126..18f8a2a 100644
--- a/src/glibext/gbufferline.c
+++ b/src/glibext/gbufferline.c
@@ -61,7 +61,7 @@ static gint get_column_width(buffer_line_column *);
static void add_segment_to_column(buffer_line_column *, GBufferSegment *);
/* Donne le segment d'une colonne présent à une abscisse donnée. */
-static GBufferSegment *get_segment_at(const buffer_line_column *, gint);
+static GBufferSegment *get_segment_at(const buffer_line_column *, gint *, bool);
/* Met en surbrillance des segments similaires. */
GSList *highlight_all_same_segments(const buffer_line_column *, GSList *, const GBufferSegment *);
@@ -194,7 +194,8 @@ static void add_segment_to_column(buffer_line_column *column, GBufferSegment *se
/******************************************************************************
* *
* Paramètres : column = colonne de ligne de texte à consulter. *
-* x = position de recherche à ajuster. *
+* x = position de recherche à ajuster. [OUT] *
+* force = accepte les segments en bordure au pire. *
* *
* Description : Donne le segment d'une colonne présent à une abscisse donnée.*
* *
@@ -204,7 +205,7 @@ static void add_segment_to_column(buffer_line_column *column, GBufferSegment *se
* *
******************************************************************************/
-static GBufferSegment *get_segment_at(const buffer_line_column *column, gint x)
+static GBufferSegment *get_segment_at(const buffer_line_column *column, gint *x, bool force)
{
GBufferSegment *result; /* Trouvaille à retourner */
size_t i; /* Boucle de parcours */
@@ -216,11 +217,11 @@ static GBufferSegment *get_segment_at(const buffer_line_column *column, gint x)
{
width = g_buffer_segment_get_width(column->segments[i]);
- if (width <= x)
- x -= width;
+ if (width > *x || ((i + 1) == column->count && force))
+ result = column->segments[i];
else
- result = column->segments[i];
+ *x -= width;
}
@@ -552,7 +553,8 @@ void g_buffer_line_add_segment(GBufferLine *line, BufferLineColumn index, GBuffe
* *
* Paramètres : line = ligne à venir consulter. *
* max_widths = largeurs de colonne à respecter. *
-* x = position à la colonne visée par la procédure. *
+* x = position à la colonne visée. [OUT] *
+* force = accepte les segments en bordure au pire. *
* *
* Description : Donne le segment présent à une abscisse donnée. *
* *
@@ -562,7 +564,7 @@ void g_buffer_line_add_segment(GBufferLine *line, BufferLineColumn index, GBuffe
* *
******************************************************************************/
-GBufferSegment *g_buffer_line_get_segment_at(const GBufferLine *line, const gint max_widths[BLC_COUNT], gint x)
+GBufferSegment *g_buffer_line_get_segment_at(const GBufferLine *line, const gint max_widths[BLC_COUNT], gint *x, bool force)
{
GBufferSegment *result; /* Trouvaille à retourner */
BufferLineColumn i; /* Boucle de parcours */
@@ -570,11 +572,22 @@ GBufferSegment *g_buffer_line_get_segment_at(const GBufferLine *line, const gint
result = NULL;
for (i = BLC_ADDRESS; i < BLC_COUNT; i++)
- if (x < max_widths[i]) break;
- else x -= (max_widths[i] + COL_MARGIN);
+ {
+ /* FIXME : addr/code */
+
+ if (*x < max_widths[i]) break;
+ else *x -= (max_widths[i] + COL_MARGIN);
+
+ }
+
+ if (i == BLC_COUNT && force)
+ {
+ i = BLC_COUNT - 1;
+ *x += (max_widths[i] + COL_MARGIN);
+ }
if (i < BLC_COUNT)
- result = get_segment_at(&line->columns[i], x);
+ result = get_segment_at(&line->columns[i], x, force);
return result;
@@ -583,6 +596,36 @@ GBufferSegment *g_buffer_line_get_segment_at(const GBufferLine *line, const gint
/******************************************************************************
* *
+* Paramètres : line = ligne à venir consulter. *
+* caret = position du curseur à faire évoluer. *
+* ctrl = indique la demande d'un parcours rapide. *
+* dir = direction du parcours. *
+* addr = indique si les positions doivent être affichées. *
+* code = indique si le code binaire doit être affiché. *
+* *
+* Description : Déplace le curseur au sein d'une vue de tampon. *
+* *
+* Retour : true si un déplacement a été effectué, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_buffer_line_move_caret(const GBufferLine *line, GdkRectangle *caret, bool ctrl, GdkScrollDirection dir, bool addr, bool code)
+{
+
+ caret->x += (dir == GDK_SCROLL_RIGHT ? 10 : -10);
+
+ return true;
+
+
+ return false;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : line = ligne à venir consulter. *
* list = liste de segments identiques à constituer. *
* ref = segment de référence à comparer avec tous les autres. *
diff --git a/src/glibext/gbufferline.h b/src/glibext/gbufferline.h
index 6eb4e27..2a46b5a 100644
--- a/src/glibext/gbufferline.h
+++ b/src/glibext/gbufferline.h
@@ -129,8 +129,11 @@ vmpa_t g_buffer_line_get_address(const GBufferLine *);
/* Ajoute un fragment de texte à une colonne de ligne. */
void g_buffer_line_add_segment(GBufferLine *, BufferLineColumn, GBufferSegment *) __attribute__ ((deprecated));
+/* Déplace le curseur au sein d'une vue de tampon. */
+bool g_buffer_line_move_caret(const GBufferLine *, GdkRectangle *, bool, GdkScrollDirection, bool, bool);
+
/* Donne le segment présent à une abscisse donnée. */
-GBufferSegment *g_buffer_line_get_segment_at(const GBufferLine *, const gint [BLC_COUNT], gint);
+GBufferSegment *g_buffer_line_get_segment_at(const GBufferLine *, const gint [BLC_COUNT], gint *, bool);
/* Met en surbrillance des segments similaires. */
GSList *g_buffer_line_highlight_all_same_segments(const GBufferLine *, GSList *, const GBufferSegment *);
diff --git a/src/glibext/gbuffersegment.c b/src/glibext/gbuffersegment.c
index 861c7cb..031075c 100644
--- a/src/glibext/gbuffersegment.c
+++ b/src/glibext/gbuffersegment.c
@@ -478,6 +478,57 @@ gint g_buffer_segment_get_width(const GBufferSegment *segment)
/******************************************************************************
* *
+* Paramètres : segment = fragment de texte à consulter. *
+* x = position horizontale au niveau du segment. *
+* *
+* Description : Fournit la position idéale pour un marqueur. *
+* *
+* Retour : Position dans le segment donné. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+gint g_buffer_segment_get_caret_position(const GBufferSegment *segment, gint x)
+{
+ gint result; /* Position à retourner */
+ gint width; /* Largeur du segment */
+ gint char_width; /* Largeur de police fixe */
+
+ width = g_buffer_segment_get_width(segment);
+
+ printf("(seg) x=%d width=%d\n", x, width);
+
+ if (x <= 0)
+ result = 0;
+
+ else if (x >= width)
+ result = width;
+
+ else
+ {
+ if (strlen(segment->text) != segment->glyphs->num_glyphs)
+ {
+
+ printf("STOP ::: %d vs %d\n", strlen(segment->text), segment->glyphs->num_glyphs);
+ exit(0);
+ }
+
+ char_width = width / segment->glyphs->num_glyphs;
+
+ result = (x / char_width) * char_width;
+ if ((x % char_width) > (char_width / 2))
+ result += char_width;
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : segment = fragment de texte à manipuler. *
* *
* Description : (Re)charge les couleurs à partir de la liste d'attributs. *
diff --git a/src/glibext/gbuffersegment.h b/src/glibext/gbuffersegment.h
index 96011bb..bc0d512 100644
--- a/src/glibext/gbuffersegment.h
+++ b/src/glibext/gbuffersegment.h
@@ -86,6 +86,9 @@ const char *g_buffer_segment_get_text(const GBufferSegment *);
/* Fournit la quantité de pixels requise pour l'impression. */
gint g_buffer_segment_get_width(const GBufferSegment *);
+/* Fournit la position idéale pour un marqueur. */
+gint g_buffer_segment_get_caret_position(const GBufferSegment *, gint);
+
/* (Re)charge les couleurs à partir de la liste d'attributs. */
void g_buffer_segment_cache_colors(GBufferSegment *);
diff --git a/src/glibext/gcodebuffer.c b/src/glibext/gcodebuffer.c
index e81966e..920b17c 100644
--- a/src/glibext/gcodebuffer.c
+++ b/src/glibext/gcodebuffer.c
@@ -123,7 +123,7 @@ static void g_code_buffer_class_init(GCodeBufferClass *);
static void g_code_buffer_init(GCodeBuffer *);
/* Convertit une adresse en indice de ligne. */
-static size_t _g_code_buffer_get_index_from_address(GCodeBuffer *, vmpa_t, bool);
+static size_t _g_code_buffer_get_index_from_address(const GCodeBuffer *, vmpa_t, bool);
/* Convertit une adresse en indice de ligne. */
static size_t g_code_buffer_get_index_from_address(GCodeBuffer *, vmpa_t, bool);
@@ -411,7 +411,7 @@ GCodeBuffer *g_code_buffer_new(BufferLineColumn main)
* *
******************************************************************************/
-static size_t _g_code_buffer_get_index_from_address(GCodeBuffer *buffer, vmpa_t addr, bool first)
+static size_t _g_code_buffer_get_index_from_address(const GCodeBuffer *buffer, vmpa_t addr, bool first)
{
size_t result; /* Indice à retourner */
@@ -1053,6 +1053,172 @@ void g_buffer_view_get_size(GBufferView *view, gint *width, gint *height, bool a
/******************************************************************************
* *
+* Paramètres : view = vue de tampon à mettre à jour. *
+* x = abscisse de la zone principale à traiter. *
+* y = ordonnée de la zone principale à traiter. *
+* caret = position du curseur à construire. [OUT] *
+* *
+* Description : Calcule la position idéale de curseur pour un point donné. *
+* *
+* Retour : Adresse si une a pu être déterminée, VMPA_INVALID sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+vmpa_t g_buffer_view_compute_caret(GBufferView *view, gint x, gint y, GdkRectangle *caret)
+{
+ size_t index; /* Indice de la ligne trouvée */
+ GBufferLine *line; /* Ligne sous le pointeur */
+ gint tmp_x; /* Copie de travail modifiable */
+ GBufferSegment *segment; /* Segment visé par le pointeur*/
+ size_t first; /* Première ligne intégrée */
+
+ line = g_buffer_view_find_line_at(view, y, &index);
+ if (line == NULL) return VMPA_INVALID;
+
+ tmp_x = x;
+
+ tmp_x -= view->left_text;
+ if (tmp_x < 0) return VMPA_INVALID;
+
+ segment = g_buffer_line_get_segment_at(line, view->max_widths, &tmp_x, true);
+ if (segment == NULL) printf("no segment\n");
+ if (segment == NULL) return VMPA_INVALID;
+
+ caret->x = (x - tmp_x) + g_buffer_segment_get_caret_position(segment, tmp_x);
+
+ first = g_code_buffer_get_index_from_address(view->buffer, view->start, true);
+ caret->y = (index - first) * view->line_height;
+
+ caret->width = 2;
+ caret->height = view->line_height;
+
+ return g_buffer_line_get_address(line);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : view = vue de tampon à mettre à jour. *
+* caret = position du curseur à faire évoluer. *
+* ctrl = indique la demande d'un parcours rapide. *
+* dir = direction du parcours. *
+* addr = indique si les positions doivent être affichées. *
+* code = indique si le code binaire doit être affiché. *
+* *
+* Description : Déplace le curseur au sein d'une vue de tampon. *
+* *
+* Retour : Adresse si une a pu être déterminée, VMPA_INVALID sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+vmpa_t g_buffer_view_move_caret(GBufferView *view, GdkRectangle *caret, bool ctrl, GdkScrollDirection dir, bool addr, bool code)
+{
+ bool result; /* Actualisation à renvoyer */
+ bool computed; /* Récursivité pris en compte */
+ gint lheight; /* Hauteur d'une ligne */
+ gint left_pos; /* Retour à la ligne */
+ gint right_pos; /* Position d'extrème droite */
+ BufferLineColumn i; /* Boucle de parcours */
+ size_t first; /* Première ligne intégrée */
+ size_t last; /* Dernière ligne intégrée */
+ GBufferLine *line; /* Ligne sous le pointeur */
+
+ result = VMPA_INVALID;
+ computed = false;
+
+ switch (dir)
+ {
+ case GDK_SCROLL_UP:
+ case GDK_SCROLL_DOWN:
+ lheight = g_buffer_view_get_line_height(view);
+ break;
+ case GDK_SCROLL_LEFT:
+ case GDK_SCROLL_RIGHT:
+ left_pos = view->left_text;
+ if (addr) left_pos += view->max_widths[BLC_ADDRESS] + COL_MARGIN;
+ if (code) left_pos += view->max_widths[BLC_BINARY] + COL_MARGIN;
+ right_pos = left_pos;
+ for (i = BLC_ASSEMBLY_HEAD; i < BLC_COUNT; i++)
+ right_pos += view->max_widths[i] + COL_MARGIN;
+ break;
+ }
+
+ first = g_code_buffer_get_index_from_address(view->buffer, view->start, true);
+ last = g_code_buffer_get_index_from_address(view->buffer, view->end, false);
+
+ switch (dir)
+ {
+ case GDK_SCROLL_UP:
+ result = (caret->y >= (first * lheight));
+ if (result)
+ caret->y -= lheight;
+ break;
+
+ case GDK_SCROLL_DOWN:
+ result = ((caret->y + lheight) < (last * lheight));
+ if (result)
+ caret->y += lheight;
+ break;
+
+ case GDK_SCROLL_LEFT:
+ line = g_buffer_view_find_line_at(view, caret->y, NULL);
+ if (line == NULL) break;
+
+ result = g_buffer_line_move_caret(line, caret, ctrl, GDK_SCROLL_LEFT, addr, code);
+
+ if (caret->x < left_pos)
+ {
+ caret->x = right_pos;
+
+ result = g_buffer_view_move_caret(view, caret, ctrl, GDK_SCROLL_UP, addr, code);
+
+ if (result == VMPA_INVALID)
+ caret->x = left_pos;
+ else
+ computed = true;
+
+ }
+
+ break;
+
+ case GDK_SCROLL_RIGHT:
+ line = g_buffer_view_find_line_at(view, caret->y, NULL);
+ if (line == NULL) break;
+
+ result = g_buffer_line_move_caret(line, caret, ctrl, GDK_SCROLL_RIGHT, addr, code);
+
+ if (!result)
+ {
+ caret->x = left_pos;
+
+ result = g_buffer_view_move_caret(view, caret, ctrl, GDK_SCROLL_DOWN, addr, code);
+
+ if (result == VMPA_INVALID)
+ caret->x = right_pos;
+ else
+ computed = true;
+
+ }
+
+ break;
+
+ }
+
+ if (result && !computed)
+ result = g_buffer_view_compute_caret(view, caret->x, caret->y, caret);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : view = vue de tampon à mettre à jour. *
* *
* Description : Supprime toute mise en évidence de segments. *
@@ -1110,7 +1276,7 @@ void g_buffer_view_highlight_segments(GBufferView *view, gint x, gint y)
size_t last; /* Dernière ligne intégrée */
size_t i; /* Boucle de parcours */
- line = g_buffer_view_find_line_at(view, y);
+ line = g_buffer_view_find_line_at(view, y, NULL);
if (line == NULL) return;
@@ -1127,7 +1293,7 @@ void g_buffer_view_highlight_segments(GBufferView *view, gint x, gint y)
x -= view->left_text;
if (x < 0) return;
- segment = g_buffer_line_get_segment_at(line, view->max_widths, x);
+ segment = g_buffer_line_get_segment_at(line, view->max_widths, &x, false);
printf(" ... seg @%d ? %p\n", x, segment);
if (segment == NULL) return;
@@ -1259,6 +1425,7 @@ void g_buffer_view_draw(const GBufferView *view, const GdkEventExpose *event, Gd
* *
* Paramètres : view = visualisation à consulter. *
* y = ordonnée comprise dans la ligne recherchée. *
+* idx = indice de la ligne trouvée ou NULL. [OUT] *
* *
* Description : Fournit la ligne présente à une ordonnée donnée. *
* *
@@ -1268,7 +1435,7 @@ void g_buffer_view_draw(const GBufferView *view, const GdkEventExpose *event, Gd
* *
******************************************************************************/
-GBufferLine *g_buffer_view_find_line_at(GBufferView *view, gint y)
+GBufferLine *g_buffer_view_find_line_at(GBufferView *view, gint y, size_t *idx)
{
gint lheight; /* Hauteur d'une ligne */
size_t index; /* Indice attendu */
@@ -1276,6 +1443,9 @@ GBufferLine *g_buffer_view_find_line_at(GBufferView *view, gint y)
lheight = g_buffer_view_get_line_height(view);
index = y / lheight;
+ if (idx != NULL)
+ *idx = index;
+
return (index < view->buffer->used ? view->buffer->lines[index] : NULL);
}
diff --git a/src/glibext/gcodebuffer.h b/src/glibext/gcodebuffer.h
index fc4bc66..4ae5c58 100644
--- a/src/glibext/gcodebuffer.h
+++ b/src/glibext/gcodebuffer.h
@@ -124,6 +124,12 @@ gint g_buffer_view_get_line_height(GBufferView *);
/* Fournit les dimensions requises par une visualisation. */
void g_buffer_view_get_size(GBufferView *, gint *, gint *, bool, bool);
+/* Calcule la position idéale de curseur pour un point donné. */
+vmpa_t g_buffer_view_compute_caret(GBufferView *, gint, gint, GdkRectangle *);
+
+/* Déplace le curseur au sein d'une vue de tampon. */
+vmpa_t g_buffer_view_move_caret(GBufferView *, GdkRectangle *, bool, GdkScrollDirection, bool, bool);
+
/* Supprime toute mise en évidence de segments. */
bool g_buffer_view_unhighlight_segments(GBufferView *);
@@ -137,7 +143,7 @@ void g_buffer_view_define_extra_drawing(GBufferView *, buffer_line_draw_fc, void
void g_buffer_view_draw(const GBufferView *, const GdkEventExpose *, GdkGC *, gint, gint, bool, bool);
/* Fournit la ligne présente à une ordonnée donnée. */
-GBufferLine *g_buffer_view_find_line_at(GBufferView *, gint);
+GBufferLine *g_buffer_view_find_line_at(GBufferView *, gint, size_t *);
/* Indique la position d'affichage d'une adresse donnée. */
bool g_buffer_view_get_address_coordinates(GBufferView *, vmpa_t, gint *, gint *);