summaryrefslogtreecommitdiff
path: root/src/glibext/gcodebuffer.c
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/gcodebuffer.c
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/gcodebuffer.c')
-rw-r--r--src/glibext/gcodebuffer.c180
1 files changed, 175 insertions, 5 deletions
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);
}