Panel::Panel (workspace::PanelManager& panelManager ,Gdl::DockItem& dockItem ,const gchar* longName ,const gchar* stockID) : panelManager_(panelManager) , dockItem_(dockItem) , panelBar_(*this, stockID) { // Set dockItems long-name property Glib::Value<std::string> val; val.init(val.value_type()); val.set(longName); g_object_set_property (G_OBJECT (dockItem.gobj()), "long-name", val.gobj()); /* Set the grip handle */ GdlDockItemGrip *grip = GDL_DOCK_ITEM_GRIP( gdl_dock_item_get_grip(dockItem.gobj())); gdl_dock_item_grip_show_handle(grip); gdl_dock_item_grip_set_label(grip, ((Widget&)panelBar_).gobj()); //gdl_dock_item_grip_set_cursor_type(grip, GDK_LEFT_PTR); /* Set up the panel body */ // Add this panel's container to the DockItem dockItem.add((Gtk::Widget&)*this); /* Connect the signals */ dockItem.signal_hide().connect( sigc::mem_fun(*this, &Panel::on_item_hidden)); dockItem.show(); }
static void gdl_dock_item_grip_unmap (GtkWidget *widget) { GdlDockItemGrip *grip = GDL_DOCK_ITEM_GRIP (widget); if (grip->title_window) gdk_window_hide (grip->title_window); GTK_WIDGET_CLASS (parent_class)->unmap (widget); }
static void gdl_dock_item_grip_unrealize (GtkWidget *widget) { GdlDockItemGrip *grip = GDL_DOCK_ITEM_GRIP (widget); if (grip->title_window) { gdk_window_set_user_data (grip->title_window, NULL); gdk_window_destroy (grip->title_window); grip->title_window = NULL; } GTK_WIDGET_CLASS (parent_class)->unrealize (widget); }
static void gdl_dock_item_grip_item_notify (GObject *master, GParamSpec *pspec, gpointer data) { GdlDockItemGrip *grip; gboolean cursor; grip = GDL_DOCK_ITEM_GRIP (data); if (strcmp (pspec->name, "stock-id") == 0) { if (grip->_priv->icon_pixbuf) { g_object_unref (grip->_priv->icon_pixbuf); grip->_priv->icon_pixbuf = NULL; } grip->_priv->icon_pixbuf_valid = FALSE; ensure_title_and_icon_pixbuf (grip); } else if (strcmp (pspec->name, "long-name") == 0) { g_free (grip->_priv->title); g_object_unref (grip->_priv->title_layout); grip->_priv->title_layout = NULL; grip->_priv->title = NULL; ensure_title_and_icon_pixbuf (grip); gtk_widget_queue_draw (GTK_WIDGET (grip)); } else if (strcmp (pspec->name, "behavior") == 0) { cursor = FALSE; if (grip->_priv->close_button) { if (GDL_DOCK_ITEM_CANT_CLOSE (grip->item)) { gtk_widget_hide (GTK_WIDGET (grip->_priv->close_button)); } else { gtk_widget_show (GTK_WIDGET (grip->_priv->close_button)); cursor = TRUE; } } if (grip->_priv->iconify_button) { if (GDL_DOCK_ITEM_CANT_ICONIFY (grip->item)) { gtk_widget_hide (GTK_WIDGET (grip->_priv->iconify_button)); } else { gtk_widget_show (GTK_WIDGET (grip->_priv->iconify_button)); cursor = TRUE; } } if (grip->title_window && !cursor) gdk_window_set_cursor (grip->title_window, NULL); } }
Panel::~Panel() { ///////////////////////////////////////////////////////TICKET #195 : violation of policy, dtors must not do any work ///////////////////////////////////////////////////////TICKET #172 : observed as a reason for crashes when closing the GUI. It was invoked after end of main, when the GUI was already gone. #if false /////////////////////////////////////////////////TICKET #937 : disabled for GTK-3 transition. TODO investigate why this logic existed... /* Detach the panel bar */ GdlDockItemGrip *grip = GDL_DOCK_ITEM_GRIP( gdl_dock_item_get_grip(dockItem_.gobj())); gtk_container_remove (GTK_CONTAINER(grip), ((Widget&)panelBar_).gobj()); /* Remove this panel's container from the DockItem */ dockItem_.remove((Gtk::Widget&)*this); #endif /////////////////////////////////////////////////TICKET #937 : (End)disabled for GTK-3 transition. }
static void gdl_dock_item_grip_realize (GtkWidget *widget) { GdlDockItemGrip *grip = GDL_DOCK_ITEM_GRIP (widget); GTK_WIDGET_CLASS (parent_class)->realize (widget); if (!grip->title_window) { GdkWindowAttr attributes; GdkRectangle area; GdkCursor *cursor; ensure_title_and_icon_pixbuf (grip); gdl_dock_item_grip_get_title_area (grip, &area); attributes.x = area.x; attributes.y = area.y; attributes.width = area.width; attributes.height = area.height; attributes.window_type = GDK_WINDOW_TEMP; attributes.wclass = GDK_INPUT_ONLY; attributes.override_redirect = TRUE; attributes.event_mask = (GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_BUTTON_MOTION_MASK | gtk_widget_get_events (widget)); grip->title_window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes, (GDK_WA_X | GDK_WA_Y | GDK_WA_NOREDIR)); gdk_window_set_user_data (grip->title_window, widget); if (GDL_DOCK_ITEM_CANT_CLOSE (grip->item)) cursor = NULL; else if (GDL_DOCK_ITEM_CANT_ICONIFY (grip->item)) cursor = NULL; else cursor = gdk_cursor_new_for_display (gtk_widget_get_display (widget), GDK_HAND2); gdk_window_set_cursor (grip->title_window, cursor); if (cursor) gdk_cursor_unref (cursor); } }
static void gdl_dock_item_grip_forall (GtkContainer *container, gboolean include_internals, GtkCallback callback, gpointer callback_data) { GdlDockItemGrip *grip; g_return_if_fail (GDL_IS_DOCK_ITEM_GRIP (container)); grip = GDL_DOCK_ITEM_GRIP (container); if (include_internals) { (* callback) (grip->_priv->close_button, callback_data); (* callback) (grip->_priv->iconify_button, callback_data); } }
static void gdl_dock_item_grip_size_request (GtkWidget *widget, GtkRequisition *requisition) { GtkRequisition child_requisition; GtkContainer *container; GdlDockItemGrip *grip; gint layout_height; g_return_if_fail (GDL_IS_DOCK_ITEM_GRIP (widget)); g_return_if_fail (requisition != NULL); container = GTK_CONTAINER (widget); grip = GDL_DOCK_ITEM_GRIP (widget); requisition->width = container->border_width * 2 + ALIGN_BORDER; requisition->height = container->border_width * 2; ensure_title_and_icon_pixbuf (grip); pango_layout_get_pixel_size (grip->_priv->title_layout, NULL, &layout_height); gtk_widget_size_request (grip->_priv->close_button, &child_requisition); requisition->width += child_requisition.width; layout_height = MAX (layout_height, child_requisition.height); gtk_widget_size_request (grip->_priv->iconify_button, &child_requisition); requisition->width += child_requisition.width; layout_height = MAX (layout_height, child_requisition.height); requisition->height += layout_height; if (grip->_priv->icon_pixbuf) { requisition->width += gdk_pixbuf_get_width (grip->_priv->icon_pixbuf) + 1; } }
static void gdl_dock_item_grip_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { GdlDockItemGrip *grip; g_return_if_fail (GDL_IS_DOCK_ITEM_GRIP (object)); grip = GDL_DOCK_ITEM_GRIP (object); switch (prop_id) { case PROP_ITEM: grip->item = g_value_get_object (value); if (grip->item) { g_signal_connect (grip->item, "notify::long_name", G_CALLBACK (gdl_dock_item_grip_item_notify), grip); g_signal_connect (grip->item, "notify::stock_id", G_CALLBACK (gdl_dock_item_grip_item_notify), grip); g_signal_connect (grip->item, "notify::behavior", G_CALLBACK (gdl_dock_item_grip_item_notify), grip); if (!GDL_DOCK_ITEM_CANT_CLOSE (grip->item) && grip->_priv->close_button) gtk_widget_show (grip->_priv->close_button); if (!GDL_DOCK_ITEM_CANT_ICONIFY (grip->item) && grip->_priv->iconify_button) gtk_widget_show (grip->_priv->iconify_button); } break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } }
static void gdl_dock_item_grip_destroy (GtkObject *object) { GdlDockItemGrip *grip = GDL_DOCK_ITEM_GRIP (object); if (grip->_priv) { GdlDockItemGripPrivate *priv = grip->_priv; if (priv->title_layout) { g_object_unref (priv->title_layout); priv->title_layout = NULL; } g_free (priv->title); priv->title = NULL; if (priv->icon_pixbuf) { g_object_unref (priv->icon_pixbuf); priv->icon_pixbuf = NULL; } if (priv->tooltips) { g_object_unref (priv->tooltips); priv->tooltips = NULL; } if (grip->item) g_signal_handlers_disconnect_by_func (grip->item, gdl_dock_item_grip_item_notify, grip); grip->item = NULL; grip->_priv = NULL; g_free (priv); } GDL_CALL_PARENT (GTK_OBJECT_CLASS, destroy, (object)); }
static void gdl_dock_item_grip_size_allocate (GtkWidget *widget, GtkAllocation *allocation) { GdlDockItemGrip *grip; GtkContainer *container; GtkRequisition button_requisition = { 0, }; GtkAllocation child_allocation; g_return_if_fail (GDL_IS_DOCK_ITEM_GRIP (widget)); g_return_if_fail (allocation != NULL); grip = GDL_DOCK_ITEM_GRIP (widget); container = GTK_CONTAINER (widget); GTK_WIDGET_CLASS (parent_class)->size_allocate (widget, allocation); if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) child_allocation.x = allocation->x + container->border_width + ALIGN_BORDER; else child_allocation.x = allocation->x + allocation->width - container->border_width; child_allocation.y = allocation->y + container->border_width; gtk_widget_size_request (grip->_priv->close_button, &button_requisition); if (gtk_widget_get_direction (widget) != GTK_TEXT_DIR_RTL) child_allocation.x -= button_requisition.width; child_allocation.width = button_requisition.width; child_allocation.height = button_requisition.height; gtk_widget_size_allocate (grip->_priv->close_button, &child_allocation); if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) child_allocation.x += button_requisition.width; gtk_widget_size_request (grip->_priv->iconify_button, &button_requisition); if (gtk_widget_get_direction (widget) != GTK_TEXT_DIR_RTL) child_allocation.x -= button_requisition.width; child_allocation.width = button_requisition.width; child_allocation.height = button_requisition.height; gtk_widget_size_allocate (grip->_priv->iconify_button, &child_allocation); if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) child_allocation.x += button_requisition.width; if (grip->title_window) { GdkRectangle area; /* set layout text */ ensure_title_and_icon_pixbuf (grip); pango_layout_set_text (grip->_priv->title_layout, grip->_priv->title, -1); gdl_dock_item_grip_get_title_area (grip, &area); gdk_window_move_resize (grip->title_window, area.x, area.y, area.width, area.height); if (grip->_priv->icon_pixbuf) area.width -= gdk_pixbuf_get_width (grip->_priv->icon_pixbuf) + 1; /* ellipsize title if it doesn't fit the title area */ ellipsize_layout (grip->_priv->title_layout, area.width); } }
static gint gdl_dock_item_grip_expose (GtkWidget *widget, GdkEventExpose *event) { GdlDockItemGrip *grip; GdkRectangle title_area; GdkRectangle expose_area; GtkStyle *bg_style; gint layout_width; gint layout_height; gint text_x; gint text_y; gboolean item_or_child_has_focus; grip = GDL_DOCK_ITEM_GRIP (widget); gdl_dock_item_grip_get_title_area (grip, &title_area); /* draw background, highlight it if the dock item or any of its * descendants have focus */ bg_style = (gdl_dock_item_or_child_has_focus (grip->item) ? gtk_widget_get_style (widget)->dark_gc[widget->state] : gtk_widget_get_style (widget)->mid_gc[widget->state]); gdk_draw_rectangle (GDK_DRAWABLE (widget->window), bg_style, TRUE, 1, 0, widget->allocation.width - 1, widget->allocation.height); if (grip->_priv->icon_pixbuf) { GdkRectangle pixbuf_rect; pixbuf_rect.width = gdk_pixbuf_get_width (grip->_priv->icon_pixbuf); pixbuf_rect.height = gdk_pixbuf_get_height (grip->_priv->icon_pixbuf); if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) { pixbuf_rect.x = title_area.x + title_area.width - pixbuf_rect.width; } else { pixbuf_rect.x = title_area.x; title_area.x += pixbuf_rect.width + 1; } /* shrink title area by the pixbuf width plus a 1px spacing */ title_area.width -= pixbuf_rect.width + 1; pixbuf_rect.y = title_area.y + (title_area.height - pixbuf_rect.height) / 2; if (gdk_rectangle_intersect (&event->area, &pixbuf_rect, &expose_area)) { GdkGC *gc; GtkStyle *style; style = gtk_widget_get_style (widget); gc = style->bg_gc[widget->state]; gdk_draw_pixbuf (GDK_DRAWABLE (widget->window), gc, grip->_priv->icon_pixbuf, 0, 0, pixbuf_rect.x, pixbuf_rect.y, pixbuf_rect.width, pixbuf_rect.height, GDK_RGB_DITHER_NONE, 0, 0); } } if (gdk_rectangle_intersect (&title_area, &event->area, &expose_area)) { pango_layout_get_pixel_size (grip->_priv->title_layout, &layout_width, &layout_height); if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) text_x = title_area.x + title_area.width - layout_width; else text_x = title_area.x; text_y = title_area.y + (title_area.height - layout_height) / 2; gtk_paint_layout (widget->style, widget->window, widget->state, TRUE, &expose_area, widget, NULL, text_x, text_y, grip->_priv->title_layout); } return GTK_WIDGET_CLASS (parent_class)->expose_event (widget, event); }