diff options
Diffstat (limited to 'src/gtkext')
-rw-r--r-- | src/gtkext/gtkbufferview-int.h | 9 | ||||
-rw-r--r-- | src/gtkext/gtkbufferview.c | 313 | ||||
-rw-r--r-- | src/gtkext/gtkextstatusbar.c | 12 | ||||
-rw-r--r-- | src/gtkext/gtkextstatusbar.h | 6 | ||||
-rw-r--r-- | src/gtkext/gtkviewpanel.c | 1 |
5 files changed, 332 insertions, 9 deletions
diff --git a/src/gtkext/gtkbufferview-int.h b/src/gtkext/gtkbufferview-int.h index 5d5a407..f57e78a 100644 --- a/src/gtkext/gtkbufferview-int.h +++ b/src/gtkext/gtkbufferview-int.h @@ -44,6 +44,11 @@ struct _GtkBufferView gint left_margin; /* Marge gauche + espace */ gint left_text; /* Début d'impression du code */ + GdkRectangle caret; /* Emplacement du curseur */ + vmpa_t caret_addr; /* Position mémoire du curseur */ + guint caret_timer; /* Identifiant du chronomètre */ + bool show_caret; /* Bascule entre les affichages*/ + }; /* Composant d'affichage de tampon de lignes (classe) */ @@ -51,6 +56,10 @@ struct _GtkBufferViewClass { GtkViewPanelClass parent; /* A laisser en premier */ + /* Signaux */ + + void (* caret_moved) (GtkBufferView *, vmpa_t); + }; diff --git a/src/gtkext/gtkbufferview.c b/src/gtkext/gtkbufferview.c index 62a861a..6556eb8 100644 --- a/src/gtkext/gtkbufferview.c +++ b/src/gtkext/gtkbufferview.c @@ -24,6 +24,12 @@ #include "gtkbufferview-int.h" +#include <gdk/gdkkeysyms.h> + + +#include "../glibext/chrysamarshal.h" + + /* -------------------------- INTERACTION DIRECTE AVEC GTK -------------------------- */ @@ -34,6 +40,12 @@ static void gtk_buffer_view_class_init(GtkBufferViewClass *); /* Procède à l'initialisation de l'afficheur de tampons. */ static void gtk_buffer_view_init(GtkBufferView *); +/* Intègre le focus dans le rendu du composant. */ +static gboolean gtk_buffer_view_focus(GtkWidget *, GtkDirectionType); + +/* Assure la gestion des clics de souris sur le composant. */ +static gboolean gtk_buffer_view_button_press(GtkWidget *, GdkEventButton *); + /* Fournit la taille de composant requise pour un plein rendu. */ static void gtk_buffer_view_size_request(GtkWidget *, GtkRequisition *); @@ -43,6 +55,9 @@ static void gtk_buffer_view_size_allocate(GtkWidget *, GtkAllocation *); /* Met à jour l'affichage de la visualisation de code buffer. */ static gboolean gtk_buffer_view_expose(GtkWidget *, GdkEventExpose *); +/* Prend en compte une frappe de touche sur le composant. */ +static gboolean gtk_buffer_view_key_press(GtkWidget *, GdkEventKey *); + /* Indique la position d'affichage d'une adresse donnée. */ static bool gtk_buffer_view_get_address_coordinates(const GtkBufferView *, vmpa_t, gint *, gint *); @@ -54,6 +69,17 @@ static void gtk_buffer_view_cache_glance(GtkBufferView *, cairo_t *, const GtkAl +/* ------------------------------ ANIMATION DU CURSEUR ------------------------------ */ + + +/* Redémarre l'affichage du curseur à l'emplacement courant. */ +static void restart_caret_blinking(GtkBufferView *); + +/* Bascule et relance l'affichage du curseur. */ +static gboolean gtk_buffer_view_refresh_caret(GtkBufferView *); + + + /* ---------------------------------------------------------------------------------- */ /* INTERACTION DIRECTE AVEC GTK */ /* ---------------------------------------------------------------------------------- */ @@ -81,9 +107,20 @@ static void gtk_buffer_view_class_init(GtkBufferViewClass *class) widget_class = GTK_WIDGET_CLASS(class); + widget_class->focus = gtk_buffer_view_focus; + widget_class->button_press_event = gtk_buffer_view_button_press; widget_class->size_request = gtk_buffer_view_size_request; widget_class->size_allocate = gtk_buffer_view_size_allocate; widget_class->expose_event = gtk_buffer_view_expose; + widget_class->key_press_event = gtk_buffer_view_key_press; + + g_signal_new("caret-moved", + GTK_TYPE_BUFFER_VIEW, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(GtkBufferViewClass, caret_moved), + NULL, NULL, + g_cclosure_user_marshal_VOID__UINT64, + G_TYPE_NONE, 1, G_TYPE_UINT64); } @@ -110,6 +147,108 @@ static void gtk_buffer_view_init(GtkBufferView *view) viewpanel->scroll = (scroll_fc)gtk_buffer_view_scroll; viewpanel->cache_glance = (cache_glance_fc)gtk_buffer_view_cache_glance; + view->caret.x = 10; + view->caret.y = 10; + view->caret.width = 100; + view->caret.height = 100; + +} + + +/****************************************************************************** +* * +* Paramètres : widget = composant GTK visé par l'opération. * +* dir = sens de l'opération : perte ou gain de focus. * +* * +* Description : Intègre le focus dans le rendu du composant. * +* * +* Retour : FALSE pour poursuivre la propagation de l'événement. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static gboolean gtk_buffer_view_focus(GtkWidget *widget, GtkDirectionType direction) +{ + GtkBufferView *view; /* Autre version du composant */ + gboolean has_focus; /* Etat courant */ + + view = GTK_BUFFER_VIEW(widget); + has_focus = gtk_widget_is_focus(widget); + + if (has_focus) + restart_caret_blinking(view); + + else if (view->caret_timer != 0) + { + g_source_remove(view->caret_timer); + view->caret_timer = 0; + + view->show_caret = true; + gtk_buffer_view_refresh_caret(view); + + } + + return TRUE; + +} + + +/****************************************************************************** +* * +* Paramètres : widget = composant GTK visé par l'opération. * +* event = informations liées à l'événement. * +* * +* Description : Assure la gestion des clics de souris sur le composant. * +* * +* Retour : FALSE pour poursuivre la propagation de l'événement. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static gboolean gtk_buffer_view_button_press(GtkWidget *widget, GdkEventButton *event) +{ + GtkBufferView *view; /* Autre version du composant */ + gint real_x; /* Abscisse absolue réelle */ + gint real_y; /* Ordonnée absolue réelle */ + vmpa_t addr; /* Position mémoire associée */ + GdkRectangle new; /* Nouvel emplacement calculé */ + + view = GTK_BUFFER_VIEW(widget); + + gtk_widget_grab_focus(widget); + + real_x = event->x; + real_y = event->y; + gtk_buffer_view_compute_real_coord(view, &real_x, &real_y); + + printf(" mouse :: (%g ; %g) -> (%d ; %d)\n", + event->x, event->y, + real_x, real_y); + + addr = g_buffer_view_compute_caret(view->buffer_view, real_x, real_y, &new); + + if (addr != VMPA_INVALID) + { + //gtk_buffer_view_compute_fake_coord(view, &view->caret.x, &view->caret.y); + + + printf(" mouse --old-- :: (%d ; %d)\n", + 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 = new; + view->caret_addr = addr; + + restart_caret_blinking(view); + + } + + return FALSE; + } @@ -341,6 +480,53 @@ static gboolean gtk_buffer_view_expose(GtkWidget *widget, GdkEventExpose *event) /****************************************************************************** * * +* Paramètres : widget = composant visé par l'opération. * +* event = informations liées à l'événement. * +* * +* Description : Prend en compte une frappe de touche sur le composant. * +* * +* Retour : FALSE pour poursuivre la propagation de l'événement. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static gboolean gtk_buffer_view_key_press(GtkWidget *widget, GdkEventKey *event) +{ + gboolean result; /* Suites à renvoyer */ + bool ctrl; /* Statut de la touche Contrôle*/ + + result = FALSE; + + ctrl = (event->state & GDK_CONTROL_MASK); + + switch (event->keyval) + { + case GDK_KEY_Left: + result = TRUE; + break; + case GDK_KEY_Up: + result = TRUE; + break; + case GDK_KEY_Right: + result = TRUE; + break; + case GDK_KEY_Down: + result = TRUE; + break; + } + + + printf("ctrl ? %d -- keyval = %d -->> %d\n", ctrl, event->keyval, result); + + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : view = composant GTK à consulter. * * addr = adresse à présenter à l'écran. * * x = position horizontale au sein du composant. [OUT] * @@ -480,3 +666,130 @@ GBufferView *gtk_buffer_view_get_buffer(const GtkBufferView *view) return view->buffer_view; } + + + + + +/* ---------------------------------------------------------------------------------- */ +/* CONVERSIONS DE COORDONNEES */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : view = composant GTK à consulter. * +* x = abscisse à ajuster. [OUT] * +* x = ordonnée à ajuster. [OUT] * +* * +* Description : Transcrit les coordonnées absolues en coordonnées à l'écran. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void gtk_buffer_view_compute_relative_coords(GtkBufferView *view, gint *x, gint *y) +{ + if (x != NULL && GTK_VIEW_PANEL(view)->hadjustment != NULL) + *x -= gtk_adjustment_get_value(GTK_VIEW_PANEL(view)->hadjustment); + + if (y != NULL && GTK_VIEW_PANEL(view)->vadjustment != NULL) + *y -= gtk_adjustment_get_value(GTK_VIEW_PANEL(view)->vadjustment); + +} + + + + + +/* ---------------------------------------------------------------------------------- */ +/* ANIMATION DU CURSEUR */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : view = composant GTK à manipuler. * +* * +* Description : Redémarre l'affichage du curseur à l'emplacement courant. * +* * +* Retour : TRUE pour poursuivre les basculements automatiques. * +* * +* Remarques : - * +* * +******************************************************************************/ + +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 = 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); + +} + + +/****************************************************************************** +* * +* Paramètres : view = composant GTK à manipuler. * +* * +* Description : Bascule et relance l'affichage du curseur. * +* * +* Retour : TRUE pour poursuivre les basculements automatiques. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static gboolean gtk_buffer_view_refresh_caret(GtkBufferView *view) +{ + GtkWidget *widget; /* Autre version du composant */ + GdkRectangle area; /* Région adaptée à traiter */ + GdkDrawable *drawable; /* Surface de dessin */ + GtkStyle *style; /* Style associé au composant */ + GtkStateType state; /* Etat du composant */ + GdkGC *gc; /* Contexte graphique */ + + widget = GTK_WIDGET(view); + + area = view->caret; + gtk_buffer_view_compute_relative_coords(view, &area.x, &area.y); + + /* Réinitialisation de la surface */ + if (view->show_caret) + { + view->show_caret = false; + gtk_widget_queue_draw_area(widget, area.x, area.y, area.width, area.height); + } + + /* Dessin */ + else + { + view->show_caret = true; + + drawable = GDK_DRAWABLE(widget->window); + state = gtk_widget_get_state(widget); + style = gtk_widget_get_style(widget); + + gc = gdk_gc_new(drawable); + gdk_gc_set_foreground(gc, &style->text[state]); + + gdk_draw_rectangle(drawable, gc, TRUE, area.x, area.y, area.width, area.height); + + gdk_gc_destroy(gc); + + } + + return TRUE; + +} diff --git a/src/gtkext/gtkextstatusbar.c b/src/gtkext/gtkextstatusbar.c index dfb08d7..47fc154 100644 --- a/src/gtkext/gtkextstatusbar.c +++ b/src/gtkext/gtkextstatusbar.c @@ -124,7 +124,7 @@ guint gtk_extended_status_bar_push(GtkExtStatusBar *bar, const gchar *message, g { guint result; /* Identifiant à retourner */ - gdk_threads_enter(); + //gdk_threads_enter(); result = gtk_statusbar_push(GTK_STATUSBAR(bar), bar->context, message); @@ -145,8 +145,8 @@ guint gtk_extended_status_bar_push(GtkExtStatusBar *bar, const gchar *message, g } else gtk_widget_hide(GTK_WIDGET(bar->progress)); - gdk_flush(); - gdk_threads_leave(); + //gdk_flush(); + //gdk_threads_leave(); return result; @@ -210,7 +210,7 @@ void gtk_extended_status_bar_remove(GtkExtStatusBar *bar, guint id) { size_t i; /* Boucle de parcours */ - gdk_threads_enter(); + //gdk_threads_enter(); gtk_statusbar_remove(GTK_STATUSBAR(bar), bar->context, id); @@ -234,7 +234,7 @@ void gtk_extended_status_bar_remove(GtkExtStatusBar *bar, guint id) else gtk_widget_hide(GTK_WIDGET(bar->progress)); - gdk_flush(); - gdk_threads_leave(); + //gdk_flush(); + //gdk_threads_leave(); } diff --git a/src/gtkext/gtkextstatusbar.h b/src/gtkext/gtkextstatusbar.h index 4cba821..b5fe210 100644 --- a/src/gtkext/gtkextstatusbar.h +++ b/src/gtkext/gtkextstatusbar.h @@ -34,9 +34,9 @@ G_BEGIN_DECLS #define GTK_TYPE_EXT_STATUS_BAR (gtk_extended_status_bar_get_type()) -#define GTK_EXT_STATUS_BAR(obj) GTK_CHECK_CAST(obj, gtk_extended_status_bar_get_type (), GtkExtStatusBar) -#define GTK_EXT_STATUS_BAR_CLASS(klass) GTK_CHECK_CLASS_CAST(klass, gtk_extended_status_bar_get_type(), GtkExtStatusBarClass) -#define GTK_IS_EXT_STATUS_BAR(obj) GTK_CHECK_TYPE(obj, gtk_extended_status_bar_get_type()) +#define GTK_EXT_STATUS_BAR(obj) (G_TYPE_CHECK_INSTANCE_CAST(obj, gtk_extended_status_bar_get_type (), GtkExtStatusBar)) +#define GTK_IS_EXT_STATUS_BAR(obj) (G_TYPE_CHECK_INSTANCE_TYPE(obj, gtk_extended_status_bar_get_type())) +#define GTK_EXT_STATUS_BAR_CLASS(klass) (G_LOADED_BINARY_GET_CLASS(klass, gtk_extended_status_bar_get_type(), GtkExtStatusBarClass)) typedef struct _GtkExtStatusBar GtkExtStatusBar; diff --git a/src/gtkext/gtkviewpanel.c b/src/gtkext/gtkviewpanel.c index 6d10009..ef1f94d 100644 --- a/src/gtkext/gtkviewpanel.c +++ b/src/gtkext/gtkviewpanel.c @@ -105,6 +105,7 @@ static void gtk_view_panel_class_init(GtkViewPanelClass *class) static void gtk_view_panel_init(GtkViewPanel *panel) { gtk_widget_set_has_window(GTK_WIDGET(panel), TRUE); + gtk_widget_set_can_focus(GTK_WIDGET(panel), TRUE); } |