static void gtk_color_swatch_measure (GtkCssGadget *gadget, GtkOrientation orientation, int for_size, int *minimum, int *natural, int *minimum_baseline, int *natural_baseline, gpointer unused) { GtkWidget *widget; GtkColorSwatch *swatch; gint w, h, min; widget = gtk_css_gadget_get_owner (gadget); swatch = GTK_COLOR_SWATCH (widget); gtk_css_gadget_get_preferred_size (swatch->priv->overlay_gadget, orientation, -1, minimum, natural, NULL, NULL); gtk_widget_get_size_request (widget, &w, &h); if (orientation == GTK_ORIENTATION_HORIZONTAL) min = w < 0 ? 48 : w; else min = h < 0 ? 32 : h; *minimum = MAX (*minimum, min); *natural = MAX (*natural, min); }
static gboolean swatch_button_press (GtkWidget *widget, GdkEventButton *event) { GtkColorSwatch *swatch = GTK_COLOR_SWATCH (widget); gtk_widget_grab_focus (widget); if (gdk_event_triggers_context_menu ((GdkEvent *) event) && swatch->priv->has_color) { do_popup (widget, event); return TRUE; } else if (event->type == GDK_2BUTTON_PRESS && event->button == GDK_BUTTON_PRIMARY) { g_signal_emit (swatch, signals[ACTIVATE], 0); return TRUE; } else if (event->button == GDK_BUTTON_PRIMARY) { return TRUE; } return FALSE; }
static void swatch_realize (GtkWidget *widget) { GtkColorSwatch *swatch = GTK_COLOR_SWATCH (widget); GtkAllocation allocation; GdkWindow *window; GdkWindowAttr attributes; gint attributes_mask; gtk_widget_get_allocation (widget, &allocation); gtk_widget_set_realized (widget, TRUE); attributes.window_type = GDK_WINDOW_CHILD; attributes.x = allocation.x; attributes.y = allocation.y; attributes.width = allocation.width; attributes.height = allocation.height; attributes.wclass = GDK_INPUT_ONLY; attributes.event_mask = gtk_widget_get_events (widget); attributes.event_mask |= GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_TOUCH_MASK; attributes_mask = GDK_WA_X | GDK_WA_Y; window = gtk_widget_get_parent_window (widget); gtk_widget_set_window (widget, window); g_object_ref (window); swatch->priv->event_window = gdk_window_new (window, &attributes, attributes_mask); gtk_widget_register_window (widget, swatch->priv->event_window); }
static gboolean swatch_key_press (GtkWidget *widget, GdkEventKey *event) { GtkColorSwatch *swatch = GTK_COLOR_SWATCH (widget); if (event->keyval == GDK_KEY_space || event->keyval == GDK_KEY_Return || event->keyval == GDK_KEY_ISO_Enter|| event->keyval == GDK_KEY_KP_Enter || event->keyval == GDK_KEY_KP_Space) { if (swatch->priv->has_color && swatch->priv->selectable && (gtk_widget_get_state_flags (widget) & GTK_STATE_FLAG_SELECTED) == 0) gtk_widget_set_state_flags (widget, GTK_STATE_FLAG_SELECTED, FALSE); else g_signal_emit (swatch, signals[ACTIVATE], 0); return TRUE; } if (GTK_WIDGET_CLASS (gtk_color_swatch_parent_class)->key_press_event (widget, event)) return TRUE; return FALSE; }
static void gtk_color_swatch_allocate (GtkCssGadget *gadget, const GtkAllocation *allocation, int baseline, GtkAllocation *out_clip, gpointer unused) { GtkColorSwatch *swatch; GtkAllocation overlay_alloc; gint overlay_width, overlay_height; swatch = GTK_COLOR_SWATCH (gtk_css_gadget_get_owner (gadget)); gtk_css_gadget_get_preferred_size (swatch->priv->overlay_gadget, GTK_ORIENTATION_HORIZONTAL, -1, &overlay_width, NULL, NULL, NULL); gtk_css_gadget_get_preferred_size (swatch->priv->overlay_gadget, GTK_ORIENTATION_VERTICAL, -1, &overlay_height, NULL, NULL, NULL); overlay_alloc.x = allocation->x + (allocation->width - overlay_width) / 2; overlay_alloc.y = allocation->y + (allocation->height - overlay_height) / 2; overlay_alloc.width = overlay_width; overlay_alloc.height = overlay_height; gtk_css_gadget_allocate (swatch->priv->overlay_gadget, &overlay_alloc, baseline, out_clip); }
static gboolean swatch_touch (GtkWidget *widget, GdkEventTouch *event) { GtkColorSwatch *swatch = GTK_COLOR_SWATCH (widget); if (!swatch->priv->press_and_hold) { gint drag_threshold; g_object_get (gtk_widget_get_settings (widget), "gtk-dnd-drag-threshold", &drag_threshold, NULL); swatch->priv->press_and_hold = gtk_press_and_hold_new (); g_object_set (swatch->priv->press_and_hold, "drag-threshold", drag_threshold, "hold-time", 1000, NULL); g_signal_connect (swatch->priv->press_and_hold, "hold", G_CALLBACK (hold_action), swatch); g_signal_connect (swatch->priv->press_and_hold, "tap", G_CALLBACK (tap_action), swatch); } gtk_press_and_hold_process_event (swatch->priv->press_and_hold, (GdkEvent *)event); return TRUE; }
static void swatch_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { GtkColorSwatch *swatch = GTK_COLOR_SWATCH (object); GdkRGBA color; switch (prop_id) { case PROP_RGBA: gtk_color_swatch_get_rgba (swatch, &color); g_value_set_boxed (value, &color); break; case PROP_SELECTABLE: g_value_set_boolean (value, gtk_color_swatch_get_selectable (swatch)); break; case PROP_HAS_MENU: g_value_set_boolean (value, swatch->priv->has_menu); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } }
static void swatch_state_flags_changed (GtkWidget *widget, GtkStateFlags previous_state) { GtkColorSwatch *swatch = GTK_COLOR_SWATCH (widget); gtk_css_node_set_state (swatch->priv->overlay_node, gtk_widget_get_state_flags (widget)); }
static gboolean swatch_draw (GtkWidget *widget, cairo_t *cr) { gtk_css_gadget_draw (GTK_COLOR_SWATCH (widget)->priv->gadget, cr); return FALSE; }
static void swatch_finalize (GObject *object) { GtkColorSwatch *swatch = GTK_COLOR_SWATCH (object); g_free (swatch->priv->icon); G_OBJECT_CLASS (gtk_color_swatch_parent_class)->finalize (object); }
static void swatch_drag_begin (GtkWidget *widget, GdkDragContext *context) { GtkColorSwatch *swatch = GTK_COLOR_SWATCH (widget); GdkRGBA color; gtk_color_swatch_get_rgba (swatch, &color); drag_set_color_icon (context, &color); }
static void swatch_unmap (GtkWidget *widget) { GtkColorSwatch *swatch = GTK_COLOR_SWATCH (widget); if (swatch->priv->event_window) gdk_window_hide (swatch->priv->event_window); GTK_WIDGET_CLASS (gtk_color_swatch_parent_class)->unmap (widget); }
static gboolean swatch_leave_notify (GtkWidget *widget, GdkEventCrossing *event) { GtkColorSwatch *swatch = GTK_COLOR_SWATCH (widget); swatch->priv->contains_pointer = FALSE; gtk_widget_unset_state_flags (widget, GTK_STATE_FLAG_PRELIGHT); return FALSE; }
static void swatch_get_preferred_height (GtkWidget *widget, gint *minimum, gint *natural) { gtk_css_gadget_get_preferred_size (GTK_COLOR_SWATCH (widget)->priv->gadget, GTK_ORIENTATION_VERTICAL, -1, minimum, natural, NULL, NULL); }
static void gtk_color_editor_set_use_alpha (GtkColorEditor *editor, gboolean use_alpha) { if (editor->priv->use_alpha != use_alpha) { editor->priv->use_alpha = use_alpha; gtk_widget_set_visible (editor->priv->a_slider, use_alpha); gtk_color_swatch_set_use_alpha (GTK_COLOR_SWATCH (editor->priv->swatch), use_alpha); } }
static void swatch_state_flags_changed (GtkWidget *widget, GtkStateFlags previous_state) { GtkColorSwatch *swatch = GTK_COLOR_SWATCH (widget); gtk_css_node_set_state (gtk_css_gadget_get_node (swatch->priv->gadget), gtk_widget_get_state_flags (widget)); gtk_css_node_set_state (gtk_css_gadget_get_node (swatch->priv->overlay_gadget), gtk_widget_get_state_flags (widget)); GTK_WIDGET_CLASS (gtk_color_swatch_parent_class)->state_flags_changed (widget, previous_state); }
static void swatch_finalize (GObject *object) { GtkColorSwatch *swatch = GTK_COLOR_SWATCH (object); g_free (swatch->priv->icon); g_object_unref (swatch->priv->long_press_gesture); g_object_unref (swatch->priv->multipress_gesture); G_OBJECT_CLASS (gtk_color_swatch_parent_class)->finalize (object); }
static gboolean swatch_button_release (GtkWidget *widget, GdkEventButton *event) { GtkColorSwatch *swatch = GTK_COLOR_SWATCH (widget); if (event->button == GDK_BUTTON_PRIMARY && swatch->priv->contains_pointer) return swatch_primary_action (swatch); return FALSE; }
static void swatch_unrealize (GtkWidget *widget) { GtkColorSwatch *swatch = GTK_COLOR_SWATCH (widget); if (swatch->priv->event_window) { gtk_widget_unregister_window (widget, swatch->priv->event_window); gdk_window_destroy (swatch->priv->event_window); swatch->priv->event_window = NULL; } GTK_WIDGET_CLASS (gtk_color_swatch_parent_class)->unrealize (widget); }
static void swatch_size_allocate (GtkWidget *widget, GtkAllocation *allocation) { GtkColorSwatch *swatch = GTK_COLOR_SWATCH (widget); gtk_widget_set_allocation (widget, allocation); if (gtk_widget_get_realized (widget)) gdk_window_move_resize (swatch->priv->event_window, allocation->x, allocation->y, allocation->width, allocation->height); }
static void swatch_dispose (GObject *object) { GtkColorSwatch *swatch = GTK_COLOR_SWATCH (object); if (swatch->priv->popover) { gtk_widget_destroy (swatch->priv->popover); swatch->priv->popover = NULL; } g_clear_object (&swatch->priv->long_press_gesture); g_clear_object (&swatch->priv->multipress_gesture); G_OBJECT_CLASS (gtk_color_swatch_parent_class)->dispose (object); }
static void hsv_changed (GtkColorEditor *editor) { GdkRGBA color; gdouble h, s, v, a; h = gtk_adjustment_get_value (editor->priv->h_adj); s = gtk_adjustment_get_value (editor->priv->s_adj); v = gtk_adjustment_get_value (editor->priv->v_adj); a = gtk_adjustment_get_value (editor->priv->a_adj); gtk_hsv_to_rgb (h, s, v, &color.red, &color.green, &color.blue); color.alpha = a; gtk_color_swatch_set_rgba (GTK_COLOR_SWATCH (editor->priv->swatch), &color); gtk_color_scale_set_rgba (GTK_COLOR_SCALE (editor->priv->a_slider), &color); entry_set_rgba (editor, &color); g_object_notify (G_OBJECT (editor), "rgba"); }
static void swatch_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { GtkColorSwatch *swatch = GTK_COLOR_SWATCH (object); switch (prop_id) { case PROP_RGBA: gtk_color_swatch_set_rgba (swatch, g_value_get_boxed (value)); break; case PROP_SELECTABLE: gtk_color_swatch_set_selectable (swatch, g_value_get_boolean (value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } }
static void swatch_drag_data_get (GtkWidget *widget, GdkDragContext *context, GtkSelectionData *selection_data, guint info, guint time) { GtkColorSwatch *swatch = GTK_COLOR_SWATCH (widget); guint16 vals[4]; GdkRGBA color; gtk_color_swatch_get_rgba (swatch, &color); vals[0] = color.red * 0xffff; vals[1] = color.green * 0xffff; vals[2] = color.blue * 0xffff; vals[3] = color.alpha * 0xffff; gtk_selection_data_set (selection_data, gdk_atom_intern_static_string ("application/x-color"), 16, (guchar *)vals, 8); }
static void swatch_drag_data_received (GtkWidget *widget, GdkDragContext *context, gint x, gint y, GtkSelectionData *selection_data, guint info, guint time) { gint length; guint16 *vals; GdkRGBA color; length = gtk_selection_data_get_length (selection_data); if (length < 0) return; /* We accept drops with the wrong format, since the KDE color * chooser incorrectly drops application/x-color with format 8. */ if (length != 8) { g_warning ("Received invalid color data\n"); return; } vals = (guint16 *) gtk_selection_data_get_data (selection_data); color.red = (gdouble)vals[0] / 0xffff; color.green = (gdouble)vals[1] / 0xffff; color.blue = (gdouble)vals[2] / 0xffff; color.alpha = (gdouble)vals[3] / 0xffff; gtk_color_swatch_set_rgba (GTK_COLOR_SWATCH (widget), &color); }
static gboolean gtk_color_swatch_render_overlay (GtkCssGadget *gadget, cairo_t *cr, int x, int y, int width, int height, gpointer data) { GtkWidget *widget; GtkColorSwatch *swatch; GtkStyleContext *context; GtkStateFlags state; GtkIconTheme *theme; GtkIconInfo *icon_info = NULL; gint scale; widget = gtk_css_gadget_get_owner (gadget); swatch = GTK_COLOR_SWATCH (widget); theme = gtk_icon_theme_get_default (); context = gtk_widget_get_style_context (widget); state = gtk_style_context_get_state (context); scale = gtk_widget_get_scale_factor (widget); if (swatch->priv->icon) { icon_info = gtk_icon_theme_lookup_icon_for_scale (theme, swatch->priv->icon, PIXBUF_SIZE, scale, GTK_ICON_LOOKUP_GENERIC_FALLBACK | GTK_ICON_LOOKUP_USE_BUILTIN); } else if ((state & GTK_STATE_FLAG_SELECTED) != 0) { GIcon *gicon; gicon = g_themed_icon_new ("object-select-symbolic"); /* fallback for themes that don't have object-select-symbolic */ g_themed_icon_append_name (G_THEMED_ICON (gicon), "gtk-apply"); icon_info = gtk_icon_theme_lookup_by_gicon_for_scale (theme, gicon, PIXBUF_SIZE, scale, GTK_ICON_LOOKUP_USE_BUILTIN); g_object_unref (gicon); } /* now draw the overlay image */ if (icon_info != NULL) { GdkPixbuf *pixbuf; pixbuf = gtk_icon_info_load_symbolic_for_context (icon_info, context, NULL, NULL); if (pixbuf != NULL) { cairo_surface_t *surface; surface = gdk_cairo_surface_create_from_pixbuf (pixbuf, scale, gtk_widget_get_window (widget)); gtk_render_icon_surface (context, cr, surface, x, y); cairo_surface_destroy (surface); g_object_unref (pixbuf); } g_object_unref (icon_info); } return FALSE; }
static gboolean swatch_popup_menu (GtkWidget *widget) { do_popup (GTK_COLOR_SWATCH (widget)); return TRUE; }
static gboolean gtk_color_swatch_render (GtkCssGadget *gadget, cairo_t *cr, int x, int y, int width, int height, gpointer data) { GtkWidget *widget; GtkColorSwatch *swatch; GtkStyleContext *context; widget = gtk_css_gadget_get_owner (gadget); swatch = GTK_COLOR_SWATCH (widget); context = gtk_widget_get_style_context (widget); if (swatch->priv->has_color) { cairo_pattern_t *pattern; cairo_matrix_t matrix; gtk_render_content_path (context, cr, x, y, width, height); if (swatch->priv->use_alpha) { cairo_save (cr); cairo_clip_preserve (cr); cairo_set_source_rgb (cr, 0.33, 0.33, 0.33); cairo_fill_preserve (cr); pattern = _gtk_color_chooser_get_checkered_pattern (); cairo_matrix_init_scale (&matrix, 0.125, 0.125); cairo_pattern_set_matrix (pattern, &matrix); cairo_set_source_rgb (cr, 0.66, 0.66, 0.66); cairo_mask (cr, pattern); cairo_pattern_destroy (pattern); cairo_restore (cr); gdk_cairo_set_source_rgba (cr, &swatch->priv->color); } else { cairo_set_source_rgb (cr, swatch->priv->color.red, swatch->priv->color.green, swatch->priv->color.blue); } cairo_fill (cr); } gtk_render_frame (context, cr, x, y, width, height); gtk_css_gadget_draw (swatch->priv->overlay_gadget, cr); return gtk_widget_has_visible_focus (widget); }
static void gtk_color_editor_init (GtkColorEditor *editor) { GtkWidget *grid; GtkWidget *slider; GtkWidget *entry; GtkWidget *swatch; GtkAdjustment *h_adj, *s_adj, *v_adj, *a_adj; AtkObject *atk_obj; GdkRGBA transparent = { 0, 0, 0, 0 }; editor->priv = G_TYPE_INSTANCE_GET_PRIVATE (editor, GTK_TYPE_COLOR_EDITOR, GtkColorEditorPrivate); editor->priv->use_alpha = TRUE; editor->priv->h_adj = h_adj = gtk_adjustment_new (0, 0, 1, 0.01, 0.1, 0); editor->priv->s_adj = s_adj = gtk_adjustment_new (0, 0, 1, 0.01, 0.1, 0); editor->priv->v_adj = v_adj = gtk_adjustment_new (0, 0, 1, 0.01, 0.1, 0); editor->priv->a_adj = a_adj = gtk_adjustment_new (0, 0, 1, 0.01, 0.1, 0); g_object_ref_sink (h_adj); g_object_ref_sink (s_adj); g_object_ref_sink (v_adj); g_object_ref_sink (a_adj); g_signal_connect_swapped (h_adj, "value-changed", G_CALLBACK (hsv_changed), editor); g_signal_connect_swapped (s_adj, "value-changed", G_CALLBACK (hsv_changed), editor); g_signal_connect_swapped (v_adj, "value-changed", G_CALLBACK (hsv_changed), editor); g_signal_connect_swapped (a_adj, "value-changed", G_CALLBACK (hsv_changed), editor); gtk_widget_push_composite_child (); /* Construct the main UI */ editor->priv->swatch = swatch = gtk_color_swatch_new (); gtk_color_swatch_set_selectable (GTK_COLOR_SWATCH (editor->priv->swatch), FALSE); gtk_widget_set_events (swatch, gtk_widget_get_events (swatch) & ~(GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK)); gtk_widget_set_can_focus (swatch, FALSE); editor->priv->entry = entry = gtk_entry_new (); atk_obj = gtk_widget_get_accessible (entry); atk_object_set_role (atk_obj, ATK_ROLE_ENTRY); atk_object_set_name (atk_obj, _("Color Name")); g_signal_connect (entry, "activate", G_CALLBACK (entry_apply), editor); g_signal_connect (entry, "notify::text", G_CALLBACK (entry_text_changed), editor); g_signal_connect (entry, "focus-out-event", G_CALLBACK (entry_focus_out), editor); editor->priv->h_slider = slider = gtk_color_scale_new (h_adj, GTK_COLOR_SCALE_HUE); gtk_orientable_set_orientation (GTK_ORIENTABLE (slider), GTK_ORIENTATION_VERTICAL); if (gtk_widget_get_direction (slider) == GTK_TEXT_DIR_RTL) gtk_style_context_add_class (gtk_widget_get_style_context (slider), GTK_STYLE_CLASS_SCALE_HAS_MARKS_ABOVE); else gtk_style_context_add_class (gtk_widget_get_style_context (slider), GTK_STYLE_CLASS_SCALE_HAS_MARKS_BELOW); editor->priv->sv_plane = gtk_color_plane_new (h_adj, s_adj, v_adj); gtk_widget_set_size_request (editor->priv->sv_plane, 300, 300); editor->priv->a_slider = slider = gtk_color_scale_new (a_adj, GTK_COLOR_SCALE_ALPHA); gtk_orientable_set_orientation (GTK_ORIENTABLE (slider), GTK_ORIENTATION_HORIZONTAL); gtk_style_context_add_class (gtk_widget_get_style_context (slider), GTK_STYLE_CLASS_SCALE_HAS_MARKS_ABOVE); editor->priv->grid = grid = gtk_grid_new (); gtk_grid_set_row_spacing (GTK_GRID (grid), 12); gtk_grid_set_column_spacing (GTK_GRID (grid), 12); gtk_grid_attach (GTK_GRID (grid), editor->priv->swatch, 1, 0, 1, 1); gtk_grid_attach (GTK_GRID (grid), editor->priv->entry, 2, 0, 1, 1); gtk_grid_attach (GTK_GRID (grid), editor->priv->h_slider, 0, 1, 1, 1); gtk_grid_attach (GTK_GRID (grid), editor->priv->sv_plane, 1, 1, 2, 1); gtk_grid_attach (GTK_GRID (grid), editor->priv->a_slider, 1, 2, 2, 1); /* This extra margin is necessary so we have room to the sides * to place the popups as desired */ gtk_widget_set_margin_left (grid, 30); gtk_widget_set_margin_right (grid, 30); editor->priv->overlay = gtk_overlay_new (); gtk_widget_override_background_color (editor->priv->overlay, 0, &transparent); gtk_container_add (GTK_CONTAINER (editor->priv->overlay), grid); /* Construct the sv popup */ editor->priv->s_entry = entry = gtk_spin_button_new (scaled_adjustment (s_adj, 100), 1, 0); atk_obj = gtk_widget_get_accessible (entry); atk_object_set_name (atk_obj, C_("Color channel", "Saturation")); atk_object_set_role (atk_obj, ATK_ROLE_ENTRY); g_signal_connect (entry, "key-press-event", G_CALLBACK (popup_key_press), editor); editor->priv->v_entry = entry = gtk_spin_button_new (scaled_adjustment (v_adj, 100), 1, 0); atk_obj = gtk_widget_get_accessible (entry); atk_object_set_name (atk_obj, C_("Color channel", "Value")); atk_object_set_role (atk_obj, ATK_ROLE_ENTRY); g_signal_connect (entry, "key-press-event", G_CALLBACK (popup_key_press), editor); grid = gtk_grid_new (); gtk_grid_set_row_spacing (GTK_GRID (grid), 6); gtk_grid_set_column_spacing (GTK_GRID (grid), 6); gtk_grid_attach (GTK_GRID (grid), gtk_label_new (C_("Color channel", "S")), 0, 0, 1, 1); gtk_grid_attach (GTK_GRID (grid), editor->priv->s_entry, 1, 0, 1, 1); gtk_grid_attach (GTK_GRID (grid), gtk_label_new (C_("Color channel", "V")), 0, 1, 1, 1); gtk_grid_attach (GTK_GRID (grid), editor->priv->v_entry, 1, 1, 1, 1); editor->priv->sv_popup = create_popup (editor, editor->priv->sv_plane, grid); /* Construct the h popup */ editor->priv->h_entry = entry = gtk_spin_button_new (scaled_adjustment (h_adj, 100), 1, 0); atk_obj = gtk_widget_get_accessible (entry); atk_object_set_name (atk_obj, C_("Color channel", "Hue")); atk_object_set_role (atk_obj, ATK_ROLE_ENTRY); g_signal_connect (entry, "key-press-event", G_CALLBACK (popup_key_press), editor); grid = gtk_grid_new (); gtk_grid_set_column_spacing (GTK_GRID (grid), 6); gtk_grid_attach (GTK_GRID (grid), gtk_label_new (C_("Color channel", "H")), 0, 0, 1, 1); gtk_grid_attach (GTK_GRID (grid), editor->priv->h_entry, 1, 0, 1, 1); editor->priv->h_popup = create_popup (editor, editor->priv->h_slider, grid); /* Construct the a popup */ editor->priv->a_entry = entry = gtk_spin_button_new (scaled_adjustment (a_adj, 100), 1, 0); atk_obj = gtk_widget_get_accessible (entry); atk_object_set_name (atk_obj, C_("Color channel", "Alpha")); atk_object_set_role (atk_obj, ATK_ROLE_ENTRY); g_signal_connect (entry, "key-press-event", G_CALLBACK (popup_key_press), editor); grid = gtk_grid_new (); gtk_grid_set_column_spacing (GTK_GRID (grid), 6); gtk_grid_attach (GTK_GRID (grid), gtk_label_new (C_("Color channel", "A")), 0, 0, 1, 1); gtk_grid_attach (GTK_GRID (grid), editor->priv->a_entry, 1, 0, 1, 1); editor->priv->a_popup = create_popup (editor, editor->priv->a_slider, grid); /* Hook up popup positioning */ g_signal_connect (editor->priv->overlay, "get-child-position", G_CALLBACK (get_child_position), editor); g_signal_connect (editor, "notify::visible", G_CALLBACK (dismiss_current_popup), NULL); gtk_widget_show_all (editor->priv->overlay); gtk_container_add (GTK_CONTAINER (editor), editor->priv->overlay); gtk_widget_pop_composite_child (); }