Пример #1
0
static void
gtk_color_editor_init (GtkColorEditor *editor)
{
  GdkRGBA transparent = { 0, 0, 0, 0 };

  editor->priv = G_TYPE_INSTANCE_GET_PRIVATE (editor,
                                              GTK_TYPE_COLOR_EDITOR,
                                              GtkColorEditorPrivate);
  editor->priv->use_alpha = TRUE;

  g_type_ensure (GTK_TYPE_COLOR_SCALE);
  g_type_ensure (GTK_TYPE_COLOR_PLANE);
  g_type_ensure (GTK_TYPE_COLOR_SWATCH);
  gtk_widget_init_template (GTK_WIDGET (editor));

  /* Some post processing is needed in code to set this up */
  gtk_widget_set_events (editor->priv->swatch,
			 gtk_widget_get_events (editor->priv->swatch)
                                 & ~(GDK_BUTTON_PRESS_MASK
                                     | GDK_BUTTON_RELEASE_MASK
                                     | GDK_KEY_PRESS_MASK
                                     | GDK_KEY_RELEASE_MASK));

  if (gtk_widget_get_direction (editor->priv->h_slider) == GTK_TEXT_DIR_RTL)
    gtk_style_context_add_class (gtk_widget_get_style_context (editor->priv->h_slider),
                                 GTK_STYLE_CLASS_SCALE_HAS_MARKS_ABOVE);
  else
    gtk_style_context_add_class (gtk_widget_get_style_context (editor->priv->h_slider),
                                 GTK_STYLE_CLASS_SCALE_HAS_MARKS_BELOW);

  gtk_widget_override_background_color (editor->priv->overlay, 0, &transparent);

  /* Create the scaled popup adjustments manually here because connecting user data is not
   * supported by template GtkBuilder xml (it would be possible to set this up in the xml
   * but require 4 separate callbacks and would be rather ugly).
   */
  gtk_spin_button_set_adjustment (GTK_SPIN_BUTTON (editor->priv->h_entry), scaled_adjustment (editor->priv->h_adj, 100));
  gtk_spin_button_set_adjustment (GTK_SPIN_BUTTON (editor->priv->s_entry), scaled_adjustment (editor->priv->s_adj, 100));
  gtk_spin_button_set_adjustment (GTK_SPIN_BUTTON (editor->priv->v_entry), scaled_adjustment (editor->priv->v_adj, 100));
  gtk_spin_button_set_adjustment (GTK_SPIN_BUTTON (editor->priv->a_entry), scaled_adjustment (editor->priv->a_adj, 100));

  /* This can be setup in the .ui file, but requires work in Glade otherwise it cannot be edited there */
  gtk_overlay_add_overlay (GTK_OVERLAY (editor->priv->overlay), editor->priv->sv_popup);
  gtk_overlay_add_overlay (GTK_OVERLAY (editor->priv->overlay), editor->priv->h_popup);
  gtk_overlay_add_overlay (GTK_OVERLAY (editor->priv->overlay), editor->priv->a_popup);
}
Пример #2
0
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 ();
}