diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2014-11-01 20:31:29 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2014-11-01 20:31:29 (GMT) |
commit | 67c0fe6eddda7ac5ff591ec972425095209d75ff (patch) | |
tree | d2f923845545c9b7f94968e9b9ded7539f3dbb7b /src/gtkext | |
parent | 085fef16a819cb321fd38e7e0926d3cca863777a (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.h | 4 | ||||
-rw-r--r-- | src/gtkext/gtkbufferview.c | 178 | ||||
-rw-r--r-- | src/gtkext/gtkviewpanel-int.h | 4 | ||||
-rw-r--r-- | src/gtkext/gtkviewpanel.c | 72 |
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); } |