static GbSliderChild * gb_slider_get_child (GbSlider *self, GtkWidget *widget) { GbSliderPrivate *priv = gb_slider_get_instance_private (self); gsize i; g_assert (GB_IS_SLIDER (self)); g_assert (GTK_IS_WIDGET (widget)); g_assert (gtk_widget_get_parent (widget) == GTK_WIDGET (self)); for (i = 0; i < priv->children->len; i++) { GbSliderChild *child; child = g_ptr_array_index (priv->children, i); if (child->widget == widget) return child; } g_assert_not_reached (); return NULL; }
static void gb_slider_unrealize (GtkWidget *widget) { GbSlider *self = (GbSlider *)widget; GbSliderPrivate *priv = gb_slider_get_instance_private (self); gsize i; g_assert (GB_IS_SLIDER (self)); for (i = 0; i < priv->children->len; i++) { GbSliderChild *child; child = g_ptr_array_index (priv->children, i); if (child->window != NULL) { gtk_widget_set_parent_window (child->widget, NULL); gtk_widget_unregister_window (widget, child->window); gdk_window_destroy (child->window); child->window = NULL; } } GTK_WIDGET_CLASS (gb_slider_parent_class)->unrealize (widget); }
static void gb_slider_realize (GtkWidget *widget) { GbSlider *self = (GbSlider *)widget; GbSliderPrivate *priv = gb_slider_get_instance_private (self); GdkWindow *window; gsize i; g_assert (GB_IS_SLIDER (self)); gtk_widget_set_realized (widget, TRUE); window = gtk_widget_get_parent_window (widget); gtk_widget_set_window (widget, window); g_object_ref (window); for (i = 0; i < priv->children->len; i++) { GbSliderChild *child; child = g_ptr_array_index (priv->children, i); if (child->window == NULL) child->window = gb_slider_create_child_window (self, child); } }
static void gb_slider_remove (GtkContainer *container, GtkWidget *widget) { GbSlider *self = (GbSlider *)container; GbSliderPrivate *priv = gb_slider_get_instance_private (self); GbSliderChild *child; gsize i; g_assert (GB_IS_SLIDER (self)); g_assert (GTK_IS_WIDGET (widget)); for (i = 0; i < priv->children->len; i++) { child = g_ptr_array_index (priv->children, i); if (child->widget == widget) { gtk_widget_unparent (widget); g_ptr_array_remove_index (priv->children, i); gtk_widget_queue_resize (GTK_WIDGET (self)); break; } } }
static GdkWindow * gb_slider_create_child_window (GbSlider *self, GbSliderChild *child) { GtkWidget *widget = (GtkWidget *)self; GdkWindow *window; GtkAllocation allocation; GdkWindowAttr attributes; gint attributes_mask; g_assert (GB_IS_SLIDER (self)); g_assert (child != NULL); gb_slider_compute_child_allocation (self, child, &allocation, NULL); attributes.window_type = GDK_WINDOW_CHILD; attributes.wclass = GDK_INPUT_OUTPUT; attributes.width = allocation.width; attributes.height = allocation.height; attributes.x = allocation.x; attributes.y = allocation.y; attributes.visual = gtk_widget_get_visual (widget); attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL; attributes.event_mask = gtk_widget_get_events (widget) | GDK_EXPOSURE_MASK; window = gdk_window_new (gtk_widget_get_window (widget), &attributes, attributes_mask); gtk_widget_register_window (widget, window); gtk_widget_set_parent_window (child->widget, window); return window; }
static void gb_slider_get_preferred_width (GtkWidget *widget, gint *min_width, gint *nat_width) { GbSlider *self = (GbSlider *)widget; GbSliderPrivate *priv = gb_slider_get_instance_private (self); gint real_min_width = 0; gint real_nat_width = 0; gsize i; g_assert (GB_IS_SLIDER (self)); for (i = 0; i < priv->children->len; i++) { GbSliderChild *child; gint child_min_width = 0; gint child_nat_width = 0; child = g_ptr_array_index (priv->children, i); if ((child->position == GB_SLIDER_NONE) && gtk_widget_get_visible (child->widget)) { gtk_widget_get_preferred_width (child->widget, &child_min_width, &child_nat_width); real_min_width = MAX (real_min_width, child_min_width); real_nat_width = MAX (real_nat_width, child_nat_width); } } *min_width = real_min_width; *nat_width = real_nat_width; }
GbSliderPosition gb_slider_get_position (GbSlider *self) { GbSliderPrivate *priv = gb_slider_get_instance_private (self); g_return_val_if_fail (GB_IS_SLIDER (self), GB_SLIDER_NONE); return priv->position; }
static GbSliderPosition gb_slider_child_get_position (GbSlider *self, GtkWidget *widget) { GbSliderChild *child; g_assert (GB_IS_SLIDER (self)); g_assert (GTK_IS_WIDGET (widget)); child = gb_slider_get_child (self, widget); return child->position; }
static void clicked_cb (GtkButton *button, GbSlider *slider) { GbSliderPosition position; g_assert (GTK_IS_BUTTON (button)); g_assert (GB_IS_SLIDER (slider)); position = gb_slider_get_position (slider) == GB_SLIDER_NONE ? GB_SLIDER_BOTTOM : GB_SLIDER_NONE; gb_slider_set_position (slider, position); gtk_widget_grab_focus (GTK_WIDGET (entry)); }
static void gb_slider_size_allocate (GtkWidget *widget, GtkAllocation *allocation) { GbSlider *self = (GbSlider *)widget; GbSliderPrivate *priv = gb_slider_get_instance_private (self); gsize i; g_assert (GB_IS_SLIDER (self)); g_assert (allocation != NULL); gtk_widget_set_allocation (widget, allocation); for (i = 0; i < priv->children->len; i++) { GbSliderChild *child = g_ptr_array_index (priv->children, i); if (gtk_widget_get_mapped (widget)) { if (gtk_widget_get_visible (child->widget)) gdk_window_show (child->window); else gdk_window_hide (child->window); } if (gtk_widget_get_realized (child->widget)) { GtkAllocation window_allocation; GtkAllocation child_allocation; gb_slider_compute_child_allocation (self, child, &window_allocation, &child_allocation); gdk_window_move_resize (child->window, window_allocation.x, window_allocation.y, window_allocation.width, window_allocation.height); gtk_widget_size_allocate (child->widget, &child_allocation); } } }
static void gb_slider_forall (GtkContainer *container, gboolean include_internals, GtkCallback callback, gpointer callback_data) { GbSlider *self = (GbSlider *)container; GbSliderPrivate *priv = gb_slider_get_instance_private (self); gsize i; g_assert (GB_IS_SLIDER (self)); for (i = 0; i < priv->children->len; i++) { GbSliderChild *child; child = g_ptr_array_index (priv->children, i); callback (child->widget, callback_data); } }
static void gb_slider_unmap (GtkWidget *widget) { GbSlider *self = (GbSlider *)widget; GbSliderPrivate *priv = gb_slider_get_instance_private (self); gsize i; g_assert (GB_IS_SLIDER (self)); for (i = 0; i < priv->children->len; i++) { GbSliderChild *child; child = g_ptr_array_index (priv->children, i); if ((child->window != NULL) && gdk_window_is_visible (child->window)) gdk_window_hide (child->window); } GTK_WIDGET_CLASS (gb_slider_parent_class)->unmap (widget); }
static void gb_slider_child_set_position (GbSlider *self, GtkWidget *widget, GbSliderPosition position) { GbSliderChild *child; g_assert (GB_IS_SLIDER (self)); g_assert (GTK_IS_WIDGET (widget)); g_assert (position >= GB_SLIDER_NONE); g_assert (position <= GB_SLIDER_LEFT); child = gb_slider_get_child (self, widget); if (position != child->position) { child->position = position; gtk_container_child_notify (GTK_CONTAINER (self), widget, "position"); gtk_widget_queue_resize (GTK_WIDGET (self)); } }
static void gb_slider_add (GtkContainer *container, GtkWidget *widget) { GbSlider *self = (GbSlider *)container; GbSliderPrivate *priv = gb_slider_get_instance_private (self); GbSliderChild *child; g_assert (GB_IS_SLIDER (self)); g_assert (GTK_IS_WIDGET (widget)); child = g_slice_new0 (GbSliderChild); child->position = GB_SLIDER_NONE; child->widget = g_object_ref (widget); g_ptr_array_add (priv->children, child); gtk_widget_set_parent (widget, GTK_WIDGET (self)); if (gtk_widget_get_realized (GTK_WIDGET (self))) child->window = gb_slider_create_child_window (self, child); }
void gb_slider_set_position (GbSlider *self, GbSliderPosition position) { GbSliderPrivate *priv = gb_slider_get_instance_private (self); g_return_if_fail (GB_IS_SLIDER (self)); g_return_if_fail (position >= GB_SLIDER_NONE); g_return_if_fail (position <= GB_SLIDER_LEFT); if (priv->position != position) { GdkFrameClock *frame_clock; EggAnimation *anim; gdouble v_value; gdouble h_value; priv->position = position; if (priv->h_anim) egg_animation_stop (priv->h_anim); ide_clear_weak_pointer (&priv->h_anim); if (priv->v_anim) egg_animation_stop (priv->v_anim); ide_clear_weak_pointer (&priv->v_anim); switch (position) { case GB_SLIDER_NONE: h_value = 0.0; v_value = 0.0; break; case GB_SLIDER_TOP: h_value = 0.0; v_value = 1.0; break; case GB_SLIDER_RIGHT: h_value = -1.0; v_value = 0.0; break; case GB_SLIDER_BOTTOM: h_value = 0.0; v_value = -1.0; break; case GB_SLIDER_LEFT: h_value = 1.0; v_value = 0.0; break; default: g_assert_not_reached (); break; } frame_clock = gtk_widget_get_frame_clock (GTK_WIDGET (self)); anim = egg_object_animate (priv->h_adj, ANIMATION_MODE, ANIMATION_DURATION, frame_clock, "value", h_value, NULL); ide_set_weak_pointer (&priv->h_anim, anim); anim = egg_object_animate (priv->v_adj, ANIMATION_MODE, ANIMATION_DURATION, frame_clock, "value", v_value, NULL); ide_set_weak_pointer (&priv->v_anim, anim); g_object_notify_by_pspec (G_OBJECT (self), gParamSpecs [PROP_POSITION]); gtk_widget_queue_resize (GTK_WIDGET (self)); } }
static void gb_slider_compute_margin (GbSlider *self, gint *x_margin, gint *y_margin) { GbSliderPrivate *priv = gb_slider_get_instance_private (self); gdouble x_ratio; gdouble y_ratio; gsize i; gint real_top_margin = 0; gint real_bottom_margin = 0; gint real_left_margin = 0; gint real_right_margin = 0; g_assert (GB_IS_SLIDER (self)); for (i = 0; i < priv->children->len; i++) { GbSliderChild *child; gint margin; child = g_ptr_array_index (priv->children, i); switch (child->position) { case GB_SLIDER_NONE: break; case GB_SLIDER_BOTTOM: gtk_widget_get_preferred_height (child->widget, NULL, &margin); real_bottom_margin = MAX (real_bottom_margin, margin); break; case GB_SLIDER_TOP: gtk_widget_get_preferred_height (child->widget, NULL, &margin); real_top_margin = MAX (real_top_margin, margin); break; case GB_SLIDER_LEFT: gtk_widget_get_preferred_width (child->widget, NULL, &margin); real_left_margin = MAX (real_left_margin, margin); break; case GB_SLIDER_RIGHT: gtk_widget_get_preferred_width (child->widget, NULL, &margin); real_right_margin = MAX (real_right_margin, margin); break; default: g_assert_not_reached (); break; } } x_ratio = gtk_adjustment_get_value (priv->h_adj); y_ratio = gtk_adjustment_get_value (priv->v_adj); if (x_ratio < 0.0) *x_margin = x_ratio * real_left_margin; else if (x_ratio > 0.0) *x_margin = x_ratio * real_right_margin; else *x_margin = 0.0; if (y_ratio < 0.0) *y_margin = y_ratio * real_bottom_margin; else if (y_ratio > 0.0) *y_margin = y_ratio * real_top_margin; else *y_margin = 0.0; }
static void gb_slider_compute_child_allocation (GbSlider *self, GbSliderChild *child, GtkAllocation *window_allocation, GtkAllocation *child_allocation) { GtkAllocation real_window_allocation; GtkAllocation real_child_allocation; gint nat_height; gint nat_width; gint x_margin; gint y_margin; g_assert (GB_IS_SLIDER (self)); g_assert (child != NULL); g_assert (GTK_IS_WIDGET (child->widget)); gtk_widget_get_allocation (GTK_WIDGET (self), &real_window_allocation); gb_slider_compute_margin (self, &x_margin, &y_margin); if (child->position == GB_SLIDER_NONE) { real_child_allocation.y = y_margin; real_child_allocation.x = 0; real_child_allocation.width = real_window_allocation.width; real_child_allocation.height = real_window_allocation.height; } else if (child->position == GB_SLIDER_TOP) { gtk_widget_get_preferred_height (child->widget, NULL, &nat_height); real_child_allocation.y = -nat_height; real_child_allocation.x = 0; real_child_allocation.height = nat_height; real_child_allocation.width = real_window_allocation.width; } else if (child->position == GB_SLIDER_BOTTOM) { gtk_widget_get_preferred_height (child->widget, NULL, &nat_height); real_window_allocation.y += real_window_allocation.height + y_margin; real_window_allocation.height = nat_height; real_child_allocation.y = 0; real_child_allocation.x = 0; real_child_allocation.height = nat_height; real_child_allocation.width = real_window_allocation.width; } else if (child->position == GB_SLIDER_RIGHT) { gtk_widget_get_preferred_width (child->widget, NULL, &nat_width); real_child_allocation.y = 0; real_child_allocation.x = real_window_allocation.width; real_child_allocation.height = real_window_allocation.height; real_child_allocation.width = nat_width; } else if (child->position == GB_SLIDER_LEFT) { gtk_widget_get_preferred_width (child->widget, NULL, &nat_width); real_child_allocation.y = 0; real_child_allocation.x = -nat_width; real_child_allocation.height = real_window_allocation.height; real_child_allocation.width = nat_width; } if (window_allocation) *window_allocation = real_window_allocation; if (child_allocation) *child_allocation = real_child_allocation; }