summaryrefslogtreecommitdiff
path: root/src/gtkext
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2014-11-01 20:31:29 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2014-11-01 20:31:29 (GMT)
commit67c0fe6eddda7ac5ff591ec972425095209d75ff (patch)
treed2f923845545c9b7f94968e9b9ded7539f3dbb7b /src/gtkext
parent085fef16a819cb321fd38e7e0926d3cca863777a (diff)
Moved the caret with mouse and keyboard.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@417 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/gtkext')
-rw-r--r--src/gtkext/gtkbufferview-int.h4
-rw-r--r--src/gtkext/gtkbufferview.c178
-rw-r--r--src/gtkext/gtkviewpanel-int.h4
-rw-r--r--src/gtkext/gtkviewpanel.c72
4 files changed, 213 insertions, 45 deletions
diff --git a/src/gtkext/gtkbufferview-int.h b/src/gtkext/gtkbufferview-int.h
index 64d3b0e..4f82757 100644
--- a/src/gtkext/gtkbufferview-int.h
+++ b/src/gtkext/gtkbufferview-int.h
@@ -45,7 +45,7 @@ struct _GtkBufferView
gint left_text; /* Début d'impression du code */
GdkRectangle caret; /* Emplacement du curseur */
- vmpa_t caret_addr; /* Position mémoire du curseur */
+ const vmpa2t *caret_addr; /* Position mémoire du curseur */
guint caret_timer; /* Identifiant du chronomètre */
bool show_caret; /* Bascule entre les affichages*/
@@ -58,7 +58,7 @@ struct _GtkBufferViewClass
/* Signaux */
- void (* caret_moved) (GtkBufferView *, vmpa_t);
+ void (* caret_moved) (GtkBufferView *, const vmpa2t *);
};
diff --git a/src/gtkext/gtkbufferview.c b/src/gtkext/gtkbufferview.c
index d5780ed..8b9b83b 100644
--- a/src/gtkext/gtkbufferview.c
+++ b/src/gtkext/gtkbufferview.c
@@ -55,6 +55,9 @@ static gboolean gtk_buffer_view_key_press(GtkWidget *, GdkEventKey *);
/* Indique les dimensions de travail du composant d'affichage. */
static void gtk_buffer_view_compute_requested_size(GtkBufferView *, gint *, gint *);
+/* Détermine la taille des bonds lors de défilements. */
+static void gtk_buffer_view_compute_scroll_inc(GtkBufferView *, gint, GtkOrientation, gdouble *, gdouble *);
+
/* Indique la position d'affichage d'une adresse donnée. */
static bool gtk_buffer_view_get_address_coordinates(const GtkBufferView *, const vmpa2t *, gint *, gint *);
@@ -66,6 +69,9 @@ static void gtk_buffer_view_cache_glance(GtkBufferView *, cairo_t *, const GtkAl
/* ------------------------------ ANIMATION DU CURSEUR ------------------------------ */
+/* Déplace le curseur en effaçant son éventuelle position. */
+static void gtk_buffer_view_relocate_caret(GtkBufferView *, const GdkRectangle *, const vmpa2t *);
+
/* Redémarre l'affichage du curseur à l'emplacement courant. */
static void restart_caret_blinking(GtkBufferView *);
@@ -109,6 +115,7 @@ static void gtk_buffer_view_class_init(GtkBufferViewClass *class)
widget_class->key_press_event = gtk_buffer_view_key_press;
panel_class->compute_size = (compute_requested_size)gtk_buffer_view_compute_requested_size;
+ panel_class->compute_inc = (compute_scroll_inc)gtk_buffer_view_compute_scroll_inc;
panel_class->get_coordinates = (get_addr_coordinates_fc)gtk_buffer_view_get_address_coordinates;
g_signal_new("caret-moved",
@@ -205,14 +212,16 @@ static gboolean gtk_buffer_view_focus(GtkWidget *widget, GtkDirectionType direct
static gboolean gtk_buffer_view_button_press(GtkWidget *widget, GdkEventButton *event)
{
GtkBufferView *view; /* Autre version du composant */
+ GtkViewPanel *pview; /* Autre version du composant */
gint real_x; /* Abscisse absolue réelle */
gint real_y; /* Ordonnée absolue réelle */
size_t index; /* Indice de ligne de tampon */
GBufferLine *line; /* Ligne à la position courante*/
- vmpa_t addr; /* Position mémoire associée */
+ const vmpa2t *addr; /* Position mémoire associée */
GdkRectangle new; /* Nouvel emplacement calculé */
view = GTK_BUFFER_VIEW(widget);
+ pview = GTK_VIEW_PANEL(widget);
gtk_widget_grab_focus(widget);
@@ -230,6 +239,11 @@ static gboolean gtk_buffer_view_button_press(GtkWidget *widget, GdkEventButton *
if (line == NULL) return FALSE;
+
+ printf(" [init ] %p - line = %p (y=%d)\n", view->buffer_view, line, real_y);
+
+
+
if (real_x < view->left_margin)
{
@@ -241,28 +255,8 @@ static gboolean gtk_buffer_view_button_press(GtkWidget *widget, GdkEventButton *
}
else
{
- return FALSE;
- /*
- addr = g_buffer_view_compute_caret(view->buffer_view, line, index, real_x, &new);
- if (addr == VMPA_INVALID) return FALSE;
- */
-
- gtk_buffer_view_compute_relative_coords(view, &view->caret.x, &view->caret.y);
-
- printf(" mouse --old-- :: (%d ; %d)\n",
- view->caret.x, view->caret.y);
-
- printf(" mouse --new-- :: (%d ; %d)\n",
- new.x, new.y);
-
- gtk_widget_queue_draw_area(GTK_WIDGET(view), view->caret.x, view->caret.y,
- view->caret.width, view->caret.height);
-
- view->caret = new;
- view->caret_addr = addr;
-
- restart_caret_blinking(view);
-
+ addr = g_buffer_view_compute_caret(view->buffer_view, line, index, real_x, pview->display, &new);
+ gtk_buffer_view_relocate_caret(view, &new, addr);
}
return FALSE;
@@ -343,7 +337,6 @@ static gboolean gtk_buffer_view_draw(GtkWidget *widget, cairo_t *cr)
gint fake_y; /* Ordonnée virtuelle */
view = GTK_BUFFER_VIEW(widget);
- widget = GTK_WIDGET(view);
pview = GTK_VIEW_PANEL(widget);
window = gtk_widget_get_window(widget);
@@ -384,6 +377,14 @@ static gboolean gtk_buffer_view_draw(GtkWidget *widget, cairo_t *cr)
}
+ /* Curseur clignotant ? */
+
+ if (gtk_widget_is_focus(widget))
+ {
+ view->show_caret = !view->show_caret;
+ gtk_buffer_view_refresh_caret(view);
+ }
+
cairo_restore(cr);
return TRUE;
@@ -407,32 +408,78 @@ static gboolean gtk_buffer_view_draw(GtkWidget *widget, cairo_t *cr)
static gboolean gtk_buffer_view_key_press(GtkWidget *widget, GdkEventKey *event)
{
gboolean result; /* Suites à renvoyer */
+
+ GtkBufferView *view; /* Autre version du composant */
+ GtkViewPanel *pview; /* Autre version du composant */
+
+
bool ctrl; /* Statut de la touche Contrôle*/
+
+ GdkRectangle area;
+
+ const vmpa2t *addr;
+
+
result = FALSE;
+
+
+ view = GTK_BUFFER_VIEW(widget);
+ pview = GTK_VIEW_PANEL(widget);
+
+
+ area = view->caret;
+
+
ctrl = (event->state & GDK_CONTROL_MASK);
switch (event->keyval)
{
case GDK_KEY_Left:
+ printf("LEFT\n");
+ addr = g_buffer_view_move_caret(view->buffer_view, &area, ctrl, GDK_SCROLL_LEFT, pview->display);
+ gtk_buffer_view_relocate_caret(view, &area, view->caret_addr);
result = TRUE;
break;
+
case GDK_KEY_Up:
+ printf("UP\n");
+ addr = g_buffer_view_move_caret(view->buffer_view, &area, ctrl, GDK_SCROLL_UP, pview->display);
+ gtk_buffer_view_relocate_caret(view, &area, view->caret_addr);
result = TRUE;
break;
+
case GDK_KEY_Right:
+ printf("RIGHT\n");
+ addr = g_buffer_view_move_caret(view->buffer_view, &area, ctrl, GDK_SCROLL_RIGHT, pview->display);
+ gtk_buffer_view_relocate_caret(view, &area, view->caret_addr);
result = TRUE;
break;
+
case GDK_KEY_Down:
+ printf("DOWN\n");
+ addr = g_buffer_view_move_caret(view->buffer_view, &area, ctrl, GDK_SCROLL_DOWN, pview->display);
+ gtk_buffer_view_relocate_caret(view, &area, view->caret_addr);
result = TRUE;
break;
+
+ default:
+ addr = NULL;
+ break;
+
}
printf("ctrl ? %d -- keyval = %d -->> %d\n", ctrl, event->keyval, result);
+ if (addr != NULL) gtk_view_panel_scroll_to_address(pview, addr);
+
+
+ printf("\n");
+
+
return result;
}
@@ -466,6 +513,38 @@ static void gtk_buffer_view_compute_requested_size(GtkBufferView *view, gint *wi
}
+/******************************************************************************
+* *
+* Paramètres : panel = composant GTK d'affichage à mettre à jour. *
+* size = taille de l'espace dans la direction donnée. *
+* orientation = indication sur le défilement à traiter. *
+* step = valeur d'un petit pas de défilement. [OUT] *
+* page = valeur d'un grand pas de défilement. [OUT] *
+* *
+* Description : Détermine la taille des bonds lors de défilements. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void gtk_buffer_view_compute_scroll_inc(GtkBufferView *view, gint size, GtkOrientation orientation, gdouble *step, gdouble *page)
+{
+ if (orientation == GTK_ORIENTATION_VERTICAL)
+ {
+ *step = 17; // FIXME g_buffer_view_get_line_height(view->buffer_view);
+ *page = *step * 10;
+ }
+
+ else
+ GTK_VIEW_PANEL_CLASS(gtk_buffer_view_parent_class)->compute_inc(GTK_VIEW_PANEL(view),
+ size, orientation, step, page);
+
+}
+
+
+
@@ -633,10 +712,43 @@ void gtk_buffer_view_compute_relative_coords(GtkBufferView *view, gint *x, gint
/******************************************************************************
* *
* Paramètres : view = composant GTK à manipuler. *
+* area = emplacement pour le dessin d'un curseur. *
+* addr = position dans la mémoire représentée du curseur. *
+* *
+* Description : Déplace le curseur en effaçant son éventuelle position. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void gtk_buffer_view_relocate_caret(GtkBufferView *view, const GdkRectangle *area, const vmpa2t *addr)
+{
+ if (view->caret_addr != NULL)
+ {
+ gtk_buffer_view_compute_relative_coords(view, &view->caret.x, &view->caret.y);
+
+ gtk_widget_queue_draw_area(GTK_WIDGET(view), view->caret.x, view->caret.y,
+ view->caret.width, view->caret.height);
+
+ }
+
+ view->caret = *area;
+ view->caret_addr = addr;
+
+ restart_caret_blinking(view);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : view = composant GTK à manipuler. *
* *
* Description : Redémarre l'affichage du curseur à l'emplacement courant. *
* *
-* Retour : TRUE pour poursuivre les basculements automatiques. *
+* Retour : - *
* *
* Remarques : - *
* *
@@ -644,16 +756,20 @@ void gtk_buffer_view_compute_relative_coords(GtkBufferView *view, gint *x, gint
static void restart_caret_blinking(GtkBufferView *view)
{
- if (view->caret_addr == VMPA_INVALID)
- return;
-
if (view->caret_timer != 0)
+ {
g_source_remove(view->caret_timer);
+ view->caret_timer = 0;
+ }
+
+ if (view->caret_addr != NULL)
+ {
+ view->show_caret = false;
+ gtk_buffer_view_refresh_caret(view);
- view->caret_timer = g_timeout_add_seconds(1, (GSourceFunc)gtk_buffer_view_refresh_caret, view);
+ view->caret_timer = g_timeout_add_seconds(1, (GSourceFunc)gtk_buffer_view_refresh_caret, view);
- view->show_caret = false;
- gtk_buffer_view_refresh_caret(view);
+ }
g_signal_emit_by_name(view, "caret-moved", view->caret_addr);
diff --git a/src/gtkext/gtkviewpanel-int.h b/src/gtkext/gtkviewpanel-int.h
index 49b5195..f33499d 100644
--- a/src/gtkext/gtkviewpanel-int.h
+++ b/src/gtkext/gtkviewpanel-int.h
@@ -36,6 +36,9 @@
/* Indique les dimensions de travail du composant d'affichage. */
typedef void (* compute_requested_size) (GtkViewPanel *, gint *, gint *);
+/* Détermine la taille des bonds lors de défilements. */
+typedef void (* compute_scroll_inc) (GtkViewPanel *, gint, GtkOrientation, gdouble *, gdouble *);
+
/* Prend acte de l'association d'un binaire chargé. */
typedef void (* attach_binary_fc) (GtkViewPanel *, GLoadedBinary *);
@@ -82,6 +85,7 @@ struct _GtkViewPanelClass
GtkFixedClass parent; /* A laisser en premier */
compute_requested_size compute_size; /* Calcul de la taille requise */
+ compute_scroll_inc compute_inc; /* Calcul des bonds */
get_addr_coordinates_fc get_coordinates;/* Conversion adresse <-> pos. */
};
diff --git a/src/gtkext/gtkviewpanel.c b/src/gtkext/gtkviewpanel.c
index 27799b5..8e41fa1 100644
--- a/src/gtkext/gtkviewpanel.c
+++ b/src/gtkext/gtkviewpanel.c
@@ -53,6 +53,9 @@ static void gtk_view_panel_size_allocate(GtkWidget *, GtkAllocation *);
/* Met à jour l'affichage du composant d'affichage. */
static gboolean gtk_view_panel_draw(GtkWidget *, cairo_t *);
+/* Détermine la taille des bonds lors de défilements. */
+static void gtk_view_panel_compute_scroll_inc(GtkViewPanel *, gint, GtkOrientation, gdouble *, gdouble *);
+
/* Détermine la taille allouée pour le contenu. */
static void gtk_view_panel_compute_allocation(GtkViewPanel *, GtkAllocation *);
@@ -94,9 +97,11 @@ static void gtk_view_panel_class_init(GtkViewPanelClass *class)
{
GObjectClass *gobject_class; /* Plus haut niveau équivalent */
GtkWidgetClass *widget_class; /* Classe de haut niveau */
+ GtkViewPanelClass *panel_class; /* Classe de lus bas niveau */
gobject_class = G_OBJECT_CLASS(class);
widget_class = GTK_WIDGET_CLASS(class);
+ panel_class = GTK_VIEW_PANEL_CLASS(class);
gobject_class->set_property = gtk_view_panel_set_property;
gobject_class->get_property = gtk_view_panel_get_property;
@@ -112,6 +117,8 @@ static void gtk_view_panel_class_init(GtkViewPanelClass *class)
widget_class->size_allocate = gtk_view_panel_size_allocate;
widget_class->draw = gtk_view_panel_draw;
+ panel_class->compute_inc = gtk_view_panel_compute_scroll_inc;
+
}
@@ -365,6 +372,30 @@ static gboolean gtk_view_panel_draw(GtkWidget *widget, cairo_t *cr)
/******************************************************************************
* *
+* Paramètres : panel = composant GTK d'affichage à mettre à jour. *
+* size = taille de l'espace dans la direction donnée. *
+* orientation = indication sur le défilement à traiter. *
+* step = valeur d'un petit pas de défilement. [OUT] *
+* page = valeur d'un grand pas de défilement. [OUT] *
+* *
+* Description : Détermine la taille des bonds lors de défilements. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void gtk_view_panel_compute_scroll_inc(GtkViewPanel *panel, gint size, GtkOrientation orientation, gdouble *step, gdouble *page)
+{
+ *step = size * 0.1;
+ *page = size * 0.9;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : panel = composant GTK à consulter. *
* alloc = emplacement à déterminer. [OUT] *
* *
@@ -521,6 +552,8 @@ static void gtk_view_panel_update_adjustment(GtkViewPanel *panel, GtkOrientation
GtkAdjustment *adj; /* Ajustement à manipuler */
gint req; /* Dimension requise */
gint allocated; /* Dimension allouée */
+ gdouble step_inc; /* Pas de défilement */
+ gdouble page_inc; /* ENjambée de défilement */
gtk_view_panel_compute_allocation(panel, &allocation);
@@ -541,10 +574,12 @@ static void gtk_view_panel_update_adjustment(GtkViewPanel *panel, GtkOrientation
}
+ GTK_VIEW_PANEL_GET_CLASS(panel)->compute_inc(panel, allocated, orientation, &step_inc, &page_inc);
+
gtk_adjustment_configure(adj, gtk_adjustment_get_value(adj),
0, MAX(req, allocated),
- allocated * 0.1,
- allocated * 0.9,
+ step_inc,
+ page_inc,
allocated);
}
@@ -736,8 +771,9 @@ void gtk_view_panel_scroll_to_address(GtkViewPanel *panel, const vmpa2t *addr)
gint y; /* Ordonnée à garantir */
GtkWidget *viewport; /* Parent avec défilement */
GtkAdjustment *adj; /* Défilement à mettre à jour */
- double limit; /* Limite à ne pas dépasser */
-
+ gdouble step_inc; /* Valeur d'un petit pas */
+ gdouble page_size; /* Taille de l'affichage */
+ double value; /* Valeur courante */
/*
if (panel->define != NULL)
@@ -749,21 +785,33 @@ void gtk_view_panel_scroll_to_address(GtkViewPanel *panel, const vmpa2t *addr)
{
viewport = gtk_widget_get_parent(GTK_WIDGET(panel));
+ /* Eventuel défilement horizontal */
+
g_object_get(G_OBJECT(viewport), "hadjustment", &adj, NULL);
- limit = gtk_adjustment_get_upper(adj) - gtk_adjustment_get_page_size(adj);
- if (x > limit)
- x = limit;
+ step_inc = gtk_adjustment_get_step_increment(adj);
+ page_size = gtk_adjustment_get_page_size(adj);
+ value = gtk_adjustment_get_value(adj);
- gtk_adjustment_set_value(adj, x);
+ if (x < value)
+ gtk_adjustment_set_value(adj, x);
+
+ else if ((x + step_inc) > (value + page_size))
+ gtk_adjustment_set_value(adj, x + step_inc - page_size);
+
+ /* Eventuel défilement vertical */
g_object_get(G_OBJECT(viewport), "vadjustment", &adj, NULL);
- limit = gtk_adjustment_get_upper(adj) - gtk_adjustment_get_page_size(adj);
- if (y > limit)
- y = limit;
+ step_inc = gtk_adjustment_get_step_increment(adj);
+ page_size = gtk_adjustment_get_page_size(adj);
+ value = gtk_adjustment_get_value(adj);
+
+ if (y < value)
+ gtk_adjustment_set_value(adj, y);
- gtk_adjustment_set_value(adj, y);
+ else if ((y + step_inc) > (value + page_size))
+ gtk_adjustment_set_value(adj, y + step_inc - page_size);
}