From 35748d35b241f386bf43e3a490adadbed78ac6be Mon Sep 17 00:00:00 2001 From: Přemysl Janouch Date: Tue, 15 Feb 2011 17:45:37 +0100 Subject: Remove the dependency on LdCanvas. GDK grabbing doesn't work on Windows, though. --- liblogdiag/ld-library-toolbar.c | 237 ++++++++++++++-------------------------- liblogdiag/ld-library-toolbar.h | 3 - liblogdiag/liblogdiag.h | 1 + src/ld-window-main.c | 2 - 4 files changed, 86 insertions(+), 157 deletions(-) diff --git a/liblogdiag/ld-library-toolbar.c b/liblogdiag/ld-library-toolbar.c index 295589e..8acb898 100644 --- a/liblogdiag/ld-library-toolbar.c +++ b/liblogdiag/ld-library-toolbar.c @@ -56,30 +56,18 @@ struct _SymbolMenuData gint menu_width; gint menu_height; - gint menu_y; -}; - -enum -{ - VIEW_HANDLER_EXPOSE, - VIEW_HANDLER_MOTION_NOTIFY, - VIEW_HANDLER_BUTTON_PRESS, - VIEW_HANDLER_BUTTON_RELEASE, - VIEW_HANDLER_COUNT }; /* * LdLibraryToolbarPrivate: * @library: a library object assigned as a model. - * @view: a view widget for showing symbol menus. - * @view_handlers: signal handlers that hook the view. + * @popup_window: a popup window. * @symbol_menu: data related to menus. */ struct _LdLibraryToolbarPrivate { LdLibrary *library; - LdDiagramView *view; - gulong view_handlers[VIEW_HANDLER_COUNT]; + GtkWidget *popup_window; SymbolMenuData symbol_menu; }; @@ -87,7 +75,6 @@ enum { PROP_0, PROP_LIBRARY, - PROP_VIEW }; static void ld_library_toolbar_get_property (GObject *object, guint property_id, @@ -95,6 +82,7 @@ static void ld_library_toolbar_get_property (GObject *object, guint property_id, static void ld_library_toolbar_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); static void ld_library_toolbar_dispose (GObject *gobject); +static void ld_library_toolbar_finalize (GObject *gobject); static void reload_library (LdLibraryToolbar *self); static void load_category_cb (gpointer data, gpointer user_data); @@ -106,16 +94,13 @@ static void emit_symbol_signal (LdLibraryToolbar *self, static void on_category_toggle (GtkToggleButton *toggle_button, gpointer user_data); -static inline void block_view_handlers (LdLibraryToolbar *self); -static inline void unblock_view_handlers (LdLibraryToolbar *self); -static inline void disconnect_view_handlers (LdLibraryToolbar *self); -static gboolean on_view_exposed (GtkWidget *widget, +static gboolean on_popup_exposed (GtkWidget *widget, GdkEventExpose *event, gpointer user_data); -static gboolean on_view_motion_notify (GtkWidget *widget, +static gboolean on_popup_motion_notify (GtkWidget *widget, GdkEventMotion *event, gpointer user_data); -static gboolean on_view_button_press (GtkWidget *widget, +static gboolean on_popup_button_press (GtkWidget *widget, GdkEventButton *event, gpointer user_data); -static gboolean on_view_button_release (GtkWidget *widget, +static gboolean on_popup_button_release (GtkWidget *widget, GdkEventButton *event, gpointer user_data); @@ -134,6 +119,7 @@ ld_library_toolbar_class_init (LdLibraryToolbarClass *klass) object_class->get_property = ld_library_toolbar_get_property; object_class->set_property = ld_library_toolbar_set_property; object_class->dispose = ld_library_toolbar_dispose; + object_class->finalize = ld_library_toolbar_finalize; /** * LdLibraryToolbar:library: @@ -145,16 +131,6 @@ ld_library_toolbar_class_init (LdLibraryToolbarClass *klass) LD_TYPE_LIBRARY, G_PARAM_READWRITE); g_object_class_install_property (object_class, PROP_LIBRARY, pspec); -/** - * LdLibraryToolbar:view: - * - * The #LdDiagramView widget misused for showing symbol menus. - */ - pspec = g_param_spec_object ("view", "View", - "The view widget misused for showing symbol menus.", - LD_TYPE_DIAGRAM_VIEW, G_PARAM_READWRITE); - g_object_class_install_property (object_class, PROP_VIEW, pspec); - /** * LdLibraryToolbar::symbol-chosen: * @self: an #LdLibraryToolbar object. @@ -208,6 +184,18 @@ ld_library_toolbar_init (LdLibraryToolbar *self) { self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, LD_TYPE_LIBRARY_TOOLBAR, LdLibraryToolbarPrivate); + + self->priv->popup_window = gtk_window_new (GTK_WINDOW_POPUP); + gtk_window_set_resizable (GTK_WINDOW (self->priv->popup_window), FALSE); + + g_signal_connect (self->priv->popup_window, "expose-event", + G_CALLBACK (on_popup_exposed), self); + g_signal_connect (self->priv->popup_window, "motion-notify-event", + G_CALLBACK (on_popup_motion_notify), self); + g_signal_connect (self->priv->popup_window, "button-press-event", + G_CALLBACK (on_popup_button_press), self); + g_signal_connect (self->priv->popup_window, "button-release-event", + G_CALLBACK (on_popup_button_release), self); } static void @@ -216,14 +204,24 @@ ld_library_toolbar_dispose (GObject *gobject) LdLibraryToolbar *self; self = LD_LIBRARY_TOOLBAR (gobject); - ld_library_toolbar_set_library (self, NULL); - ld_library_toolbar_set_view (self, NULL); /* Chain up to the parent class. */ G_OBJECT_CLASS (ld_library_toolbar_parent_class)->dispose (gobject); } +static void +ld_library_toolbar_finalize (GObject *gobject) +{ + LdLibraryToolbar *self; + + self = LD_LIBRARY_TOOLBAR (gobject); + gtk_widget_destroy (self->priv->popup_window); + + /* Chain up to the parent class. */ + G_OBJECT_CLASS (ld_library_toolbar_parent_class)->finalize (gobject); +} + static void ld_library_toolbar_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) @@ -236,9 +234,6 @@ ld_library_toolbar_get_property (GObject *object, guint property_id, case PROP_LIBRARY: g_value_set_object (value, ld_library_toolbar_get_library (self)); break; - case PROP_VIEW: - g_value_set_object (value, ld_library_toolbar_get_view (self)); - break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } @@ -257,10 +252,6 @@ ld_library_toolbar_set_property (GObject *object, guint property_id, ld_library_toolbar_set_library (self, LD_LIBRARY (g_value_get_object (value))); break; - case PROP_VIEW: - ld_library_toolbar_set_view (self, - LD_DIAGRAM_VIEW (g_value_get_object (value))); - break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } @@ -325,62 +316,6 @@ ld_library_toolbar_get_library (LdLibraryToolbar *self) return self->priv->library; } -/** - * ld_library_toolbar_set_view: - * @self: an #LdLibraryToolbar object. - * @view: (allow-none): the widget to be assigned to the toolbar. - * - * Assign an #LdDiagramView widget to the toolbar. - */ -void -ld_library_toolbar_set_view (LdLibraryToolbar *self, LdDiagramView *view) -{ - g_return_if_fail (LD_IS_LIBRARY_TOOLBAR (self)); - g_return_if_fail (LD_IS_DIAGRAM_VIEW (view) || view == NULL); - - if (self->priv->view) - { - disconnect_view_handlers (self); - g_object_unref (self->priv->view); - } - - self->priv->view = view; - - if (view) - { - self->priv->view_handlers[VIEW_HANDLER_EXPOSE] - = g_signal_connect (view, "expose-event", - G_CALLBACK (on_view_exposed), self); - self->priv->view_handlers[VIEW_HANDLER_MOTION_NOTIFY] - = g_signal_connect (view, "motion-notify-event", - G_CALLBACK (on_view_motion_notify), self); - self->priv->view_handlers[VIEW_HANDLER_BUTTON_PRESS] - = g_signal_connect (view, "button-press-event", - G_CALLBACK (on_view_button_press), self); - self->priv->view_handlers[VIEW_HANDLER_BUTTON_RELEASE] - = g_signal_connect (view, "button-release-event", - G_CALLBACK (on_view_button_release), self); - - block_view_handlers (self); - g_object_ref (view); - } - g_object_notify (G_OBJECT (self), "view"); -} - -/** - * ld_library_toolbar_get_view: - * @self: an #LdLibraryToolbar object. - * - * Return value: (transfer none): the #LdDiagramView widget - * assigned to the toolbar. - */ -LdDiagramView * -ld_library_toolbar_get_view (LdLibraryToolbar *self) -{ - g_return_val_if_fail (LD_IS_LIBRARY_TOOLBAR (self), NULL); - return self->priv->view; -} - static void reload_library (LdLibraryToolbar *self) { @@ -439,7 +374,7 @@ load_category_cb (gpointer data, gpointer user_data) gtk_container_add (GTK_CONTAINER (button), img); gtk_container_add (GTK_CONTAINER (item), button); - /* Don't steal focus from the view. */ + /* Don't steal focus. */ g_object_set (button, "can-focus", FALSE, NULL); /* Assign the category to the toggle button. */ @@ -493,13 +428,9 @@ recolor_pixbuf (GdkPixbuf *pbuf, GdkColor *color) static void redraw_symbol_menu (LdLibraryToolbar *self) { - SymbolMenuData *data; - g_return_if_fail (LD_IS_LIBRARY_TOOLBAR (self)); - data = &self->priv->symbol_menu; - gtk_widget_queue_draw_area (GTK_WIDGET (self->priv->view), - 0, data->menu_y - 1, data->menu_width + 2, data->menu_height + 2); + gtk_widget_queue_draw (GTK_WIDGET (self->priv->popup_window)); } static void @@ -541,7 +472,7 @@ on_category_toggle (GtkToggleButton *toggle_button, gpointer user_data) { gint i; - block_view_handlers (self); + gtk_widget_hide (self->priv->popup_window); g_object_unref (data->active_button); data->active_button = NULL; @@ -559,7 +490,10 @@ on_category_toggle (GtkToggleButton *toggle_button, gpointer user_data) g_free (data->items); data->items = NULL; - gtk_grab_remove (GTK_WIDGET (self->priv->view)); + gdk_pointer_ungrab (GDK_CURRENT_TIME); + gdk_keyboard_ungrab (GDK_CURRENT_TIME); + + gtk_grab_remove (GTK_WIDGET (self->priv->popup_window)); } else { @@ -567,14 +501,6 @@ on_category_toggle (GtkToggleButton *toggle_button, gpointer user_data) SymbolMenuItem *item; gint x, y, menu_width; - g_return_if_fail (gtk_widget_translate_coordinates (GTK_WIDGET - (toggle_button), GTK_WIDGET (priv->view), 0, 0, &x, &y)); - - data->menu_y = y; - data->menu_height = GTK_WIDGET (toggle_button)->allocation.height; - - unblock_view_handlers (self); - data->active_button = toggle_button; g_object_ref (data->active_button); @@ -585,8 +511,10 @@ on_category_toggle (GtkToggleButton *toggle_button, gpointer user_data) data->items = g_new (SymbolMenuItem, data->n_items); data->active_item = -1; - item = data->items; menu_width = 0; + data->menu_height = GTK_WIDGET (toggle_button)->allocation.height; + + item = data->items; for (symbol_iter = children; symbol_iter; symbol_iter = symbol_iter->next) { @@ -616,28 +544,36 @@ on_category_toggle (GtkToggleButton *toggle_button, gpointer user_data) } data->menu_width = menu_width; - gtk_grab_add (GTK_WIDGET (self->priv->view)); + if (!gtk_widget_get_has_window (GTK_WIDGET (toggle_button))) + { + x = GTK_WIDGET (toggle_button)->allocation.x; + y = GTK_WIDGET (toggle_button)->allocation.y; + } + else + x = y = 0; + + gdk_window_get_root_coords + (GTK_WIDGET (toggle_button)->window, x, y, &x, &y); + + gtk_widget_show (self->priv->popup_window); + gtk_widget_set_size_request (self->priv->popup_window, + data->menu_width, data->menu_height); + gtk_window_move (GTK_WINDOW (self->priv->popup_window), + x + GTK_WIDGET (toggle_button)->allocation.width, y); + + gdk_pointer_grab (self->priv->popup_window->window, TRUE, + GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + | GDK_POINTER_MOTION_MASK, NULL, NULL, GDK_CURRENT_TIME); + gdk_keyboard_grab (self->priv->popup_window->window, + TRUE, GDK_CURRENT_TIME); + + gtk_grab_add (GTK_WIDGET (self->priv->popup_window)); } redraw_symbol_menu (self); } -#define DEFINE_VIEW_HANDLER_FUNC(name) \ -static inline void \ -name ## _view_handlers (LdLibraryToolbar *self) \ -{ \ - gint i; \ - g_return_if_fail (LD_IS_DIAGRAM_VIEW (self->priv->view)); \ - for (i = 0; i < VIEW_HANDLER_COUNT; i++) \ - g_signal_handler_ ## name (self->priv->view, \ - self->priv->view_handlers[i]); \ -} - -DEFINE_VIEW_HANDLER_FUNC (block) -DEFINE_VIEW_HANDLER_FUNC (unblock) -DEFINE_VIEW_HANDLER_FUNC (disconnect) - static gboolean -on_view_exposed (GtkWidget *widget, GdkEventExpose *event, gpointer user_data) +on_popup_exposed (GtkWidget *widget, GdkEventExpose *event, gpointer user_data) { cairo_t *cr; LdLibraryToolbar *self; @@ -651,7 +587,7 @@ on_view_exposed (GtkWidget *widget, GdkEventExpose *event, gpointer user_data) /* Draw some border. */ cairo_set_line_width (cr, 1); - cairo_rectangle (cr, 0, data->menu_y, data->menu_width, data->menu_height); + cairo_rectangle (cr, 0, 0, data->menu_width, data->menu_height); cairo_set_source_rgb (cr, 1, 1, 1); cairo_fill (cr); @@ -662,8 +598,8 @@ on_view_exposed (GtkWidget *widget, GdkEventExpose *event, gpointer user_data) if (i) { - cairo_move_to (cr, x - 0.5, data->menu_y + 1); - cairo_line_to (cr, x - 0.5, data->menu_y + data->menu_height); + cairo_move_to (cr, x - 0.5, 1); + cairo_line_to (cr, x - 0.5, data->menu_height); cairo_set_source_rgb (cr, 0.5, 0.5, 0.5); cairo_stroke (cr); } @@ -671,7 +607,7 @@ on_view_exposed (GtkWidget *widget, GdkEventExpose *event, gpointer user_data) item = data->items + i; cairo_save (cr); - cairo_rectangle (cr, x, data->menu_y, item->width, data->menu_height); + cairo_rectangle (cr, x, 0, item->width, data->menu_height); cairo_clip (cr); if (i == data->active_item) @@ -680,8 +616,7 @@ on_view_exposed (GtkWidget *widget, GdkEventExpose *event, gpointer user_data) cairo_paint (cr); } - cairo_translate (cr, x + item->dx, - data->menu_y + data->menu_height * 0.5); + cairo_translate (cr, x + item->dx, data->menu_height * 0.5); cairo_scale (cr, item->scale, item->scale); cairo_set_source_rgb (cr, 0, 0, 0); @@ -692,17 +627,16 @@ on_view_exposed (GtkWidget *widget, GdkEventExpose *event, gpointer user_data) x += item->width; } - cairo_rectangle (cr, 0.5, data->menu_y + 0.5, - data->menu_width, data->menu_height); + cairo_rectangle (cr, 0.5, 0.5, data->menu_width - 1, data->menu_height - 1); cairo_set_source_rgb (cr, 0, 0, 0); cairo_stroke (cr); cairo_destroy (cr); - return FALSE; + return TRUE; } static gboolean -on_view_motion_notify (GtkWidget *widget, GdkEventMotion *event, +on_popup_motion_notify (GtkWidget *widget, GdkEventMotion *event, gpointer user_data) { LdLibraryToolbar *self; @@ -713,9 +647,8 @@ on_view_motion_notify (GtkWidget *widget, GdkEventMotion *event, data = &self->priv->symbol_menu; if (widget->window != event->window - || event->x < 0 || event->y < data->menu_y - || event->y >= data->menu_y + data->menu_height) - goto on_view_motion_notify_end; + || event->x < 0 || event->y < 0 || event->y >= data->menu_height) + goto on_popup_motion_notify_end; for (x = i = 0; i < data->n_items; i++) { @@ -727,7 +660,7 @@ on_view_motion_notify (GtkWidget *widget, GdkEventMotion *event, } } -on_view_motion_notify_end: +on_popup_motion_notify_end: if (data->active_item != at_cursor) { emit_symbol_signal (self, LD_LIBRARY_TOOLBAR_GET_CLASS (self) @@ -739,11 +672,11 @@ on_view_motion_notify_end: } data->active_item = at_cursor; redraw_symbol_menu (self); - return FALSE; + return TRUE; } static gboolean -on_view_button_press (GtkWidget *widget, GdkEventButton *event, +on_popup_button_press (GtkWidget *widget, GdkEventButton *event, gpointer user_data) { LdLibraryToolbar *self; @@ -753,18 +686,18 @@ on_view_button_press (GtkWidget *widget, GdkEventButton *event, data = &self->priv->symbol_menu; /* If the event occured elsewhere, cancel the menu and put the event - * back into the queue. + * back into the queue. This is for quicker switching between categories. */ if (widget->window != event->window && data->active_button) { gtk_toggle_button_set_active (data->active_button, FALSE); gdk_event_put ((GdkEvent *) event); } - return FALSE; + return TRUE; } static gboolean -on_view_button_release (GtkWidget *widget, GdkEventButton *event, +on_popup_button_release (GtkWidget *widget, GdkEventButton *event, gpointer user_data) { LdLibraryToolbar *self; @@ -774,7 +707,7 @@ on_view_button_release (GtkWidget *widget, GdkEventButton *event, data = &self->priv->symbol_menu; if (event->button != 1) - return FALSE; + return TRUE; emit_symbol_signal (self, LD_LIBRARY_TOOLBAR_GET_CLASS (self) ->symbol_chosen_signal, -1); @@ -783,5 +716,5 @@ on_view_button_release (GtkWidget *widget, GdkEventButton *event, if (data->active_button) gtk_toggle_button_set_active (data->active_button, FALSE); - return FALSE; + return TRUE; } diff --git a/liblogdiag/ld-library-toolbar.h b/liblogdiag/ld-library-toolbar.h index b1dc77a..01b329d 100644 --- a/liblogdiag/ld-library-toolbar.h +++ b/liblogdiag/ld-library-toolbar.h @@ -59,9 +59,6 @@ GtkWidget *ld_library_toolbar_new (void); void ld_library_toolbar_set_library (LdLibraryToolbar *self, LdLibrary *library); LdLibrary *ld_library_toolbar_get_library (LdLibraryToolbar *self); -void ld_library_toolbar_set_view (LdLibraryToolbar *self, - LdDiagramView *view); -LdDiagramView *ld_library_toolbar_get_view (LdLibraryToolbar *self); G_END_DECLS diff --git a/liblogdiag/liblogdiag.h b/liblogdiag/liblogdiag.h index 2ec48bc..d045d02 100644 --- a/liblogdiag/liblogdiag.h +++ b/liblogdiag/liblogdiag.h @@ -20,6 +20,7 @@ #include "ld-symbol.h" #include "ld-symbol-category.h" #include "ld-library.h" +#include "ld-library-toolbar.h" #include "ld-undo-action.h" #include "ld-diagram-object.h" diff --git a/src/ld-window-main.c b/src/ld-window-main.c index 22278ab..03a4165 100644 --- a/src/ld-window-main.c +++ b/src/ld-window-main.c @@ -333,8 +333,6 @@ ld_window_main_init (LdWindowMain *self) ld_library_toolbar_set_library (LD_LIBRARY_TOOLBAR (priv->library_toolbar), priv->library); - ld_library_toolbar_set_view (LD_LIBRARY_TOOLBAR (priv->library_toolbar), - priv->view); g_signal_connect_after (priv->library_toolbar, "symbol-selected", G_CALLBACK (on_symbol_selected), self); -- cgit v1.2.3-70-g09d2