gimp/app/widgets/gimpviewablebox.c
Michael Natterer 8f991c5950 app: make the brush, pattern etc selecing boxes more compact
by integrating their label instead of requiring one externally. This
way we get rid of some more labels in the tool options. Also clean up
tool options further (add more spin scales, and some general
reordering and spacing cleanup).
2010-11-02 14:05:47 +01:00

566 lines
20 KiB
C

/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995-1999 Spencer Kimball and Peter Mattis
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <gtk/gtk.h>
#include "libgimpwidgets/gimpwidgets.h"
#include "widgets-types.h"
#include "config/gimpconfig-utils.h"
#include "core/gimp.h"
#include "core/gimpcontainer.h"
#include "core/gimpcontext.h"
#include "core/gimpdatafactory.h"
#include "gimpcontainerentry.h"
#include "gimpdialogfactory.h"
#include "gimppropwidgets.h"
#include "gimpview.h"
#include "gimpviewablebutton.h"
#include "gimpviewablebox.h"
#include "gimpviewrenderergradient.h"
#include "gimp-intl.h"
/* local function prototypes */
static GtkWidget * gimp_viewable_box_new (GimpContainer *container,
GimpContext *context,
const gchar *label,
gint spacing,
GimpViewType view_type,
GimpViewType button_view_size,
GimpViewSize view_size,
const gchar *dialog_identifier,
const gchar *dialog_stock_id,
const gchar *dialog_tooltip);
static GtkWidget * view_props_connect (GtkWidget *box,
GimpContext *context,
const gchar *view_type_prop,
const gchar *view_size_prop);
static void gimp_gradient_box_reverse_notify (GObject *object,
GParamSpec *pspec,
GimpView *view);
/* brush boxes */
static GtkWidget *
brush_box_new (GimpContainer *container,
GimpContext *context,
const gchar *label,
gint spacing,
GimpViewType view_type,
GimpViewSize view_size)
{
if (! container)
container = gimp_data_factory_get_container (context->gimp->brush_factory);
return gimp_viewable_box_new (container, context, label, spacing,
view_type, GIMP_VIEW_SIZE_SMALL, view_size,
"gimp-brush-grid|gimp-brush-list",
GIMP_STOCK_BRUSH,
_("Open the brush selection dialog"));
}
GtkWidget *
gimp_brush_box_new (GimpContainer *container,
GimpContext *context,
const gchar *label,
gint spacing)
{
g_return_val_if_fail (container == NULL || GIMP_IS_CONTAINER (container),
NULL);
g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
return brush_box_new (container, context, label, spacing,
GIMP_VIEW_TYPE_GRID, GIMP_VIEW_SIZE_SMALL);
}
GtkWidget *
gimp_prop_brush_box_new (GimpContainer *container,
GimpContext *context,
const gchar *label,
gint spacing,
const gchar *view_type_prop,
const gchar *view_size_prop)
{
GimpViewType view_type;
GimpViewSize view_size;
g_return_val_if_fail (container == NULL || GIMP_IS_CONTAINER (container),
NULL);
g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
g_object_get (context,
view_type_prop, &view_type,
view_size_prop, &view_size,
NULL);
return view_props_connect (brush_box_new (container, context, label, spacing,
view_type, view_size),
context,
view_type_prop, view_size_prop);
}
/* dynamics boxes */
static GtkWidget *
dynamics_box_new (GimpContainer *container,
GimpContext *context,
const gchar *label,
gint spacing,
GimpViewSize view_size)
{
if (! container)
container = gimp_data_factory_get_container (context->gimp->dynamics_factory);
return gimp_viewable_box_new (container, context, label, spacing,
GIMP_VIEW_TYPE_LIST, GIMP_VIEW_SIZE_SMALL, view_size,
"gimp-dynamics-list",
GIMP_STOCK_DYNAMICS,
_("Open the dynamics selection dialog"));
}
GtkWidget *
gimp_dynamics_box_new (GimpContainer *container,
GimpContext *context,
const gchar *label,
gint spacing)
{
g_return_val_if_fail (container == NULL || GIMP_IS_CONTAINER (container),
NULL);
g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
return dynamics_box_new (container, context, label, spacing,
GIMP_VIEW_SIZE_SMALL);
}
GtkWidget *
gimp_prop_dynamics_box_new (GimpContainer *container,
GimpContext *context,
const gchar *label,
gint spacing,
const gchar *view_type_prop,
const gchar *view_size_prop)
{
GimpViewType view_type;
GimpViewSize view_size;
g_return_val_if_fail (container == NULL || GIMP_IS_CONTAINER (container),
NULL);
g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
g_object_get (context,
view_type_prop, &view_type,
view_size_prop, &view_size,
NULL);
return view_props_connect (dynamics_box_new (container, context, label,
spacing, view_size),
context,
view_type_prop, view_size_prop);
}
/* pattern boxes */
static GtkWidget *
pattern_box_new (GimpContainer *container,
GimpContext *context,
const gchar *label,
gint spacing,
GimpViewType view_type,
GimpViewSize view_size)
{
if (! container)
container = gimp_data_factory_get_container (context->gimp->pattern_factory);
return gimp_viewable_box_new (container, context, label, spacing,
view_type, GIMP_VIEW_SIZE_SMALL, view_size,
"gimp-pattern-grid|gimp-pattern-list",
GIMP_STOCK_PATTERN,
_("Open the pattern selection dialog"));
}
GtkWidget *
gimp_pattern_box_new (GimpContainer *container,
GimpContext *context,
const gchar *label,
gint spacing)
{
g_return_val_if_fail (container == NULL || GIMP_IS_CONTAINER (container),
NULL);
g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
return pattern_box_new (container, context, label, spacing,
GIMP_VIEW_TYPE_GRID, GIMP_VIEW_SIZE_SMALL);
}
GtkWidget *
gimp_prop_pattern_box_new (GimpContainer *container,
GimpContext *context,
const gchar *label,
gint spacing,
const gchar *view_type_prop,
const gchar *view_size_prop)
{
GimpViewType view_type;
GimpViewSize view_size;
g_return_val_if_fail (container == NULL || GIMP_IS_CONTAINER (container),
NULL);
g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
g_object_get (context,
view_type_prop, &view_type,
view_size_prop, &view_size,
NULL);
return view_props_connect (pattern_box_new (container, context, label, spacing,
view_type, view_size),
context,
view_type_prop, view_size_prop);
}
/* gradient boxes */
static GtkWidget *
gradient_box_new (GimpContainer *container,
GimpContext *context,
const gchar *label,
gint spacing,
GimpViewType view_type,
GimpViewSize view_size,
const gchar *reverse_prop)
{
GtkWidget *hbox;
GtkWidget *button;
GList *children;
if (! container)
container = gimp_data_factory_get_container (context->gimp->gradient_factory);
hbox = gimp_viewable_box_new (container, context, label, spacing,
view_type, GIMP_VIEW_SIZE_LARGE, view_size,
"gimp-gradient-list|gimp-gradient-grid",
GIMP_STOCK_GRADIENT,
_("Open the gradient selection dialog"));
children = gtk_container_get_children (GTK_CONTAINER (hbox));
button = children->data;
g_list_free (children);
GIMP_VIEWABLE_BUTTON (button)->button_view_size = GIMP_VIEW_SIZE_SMALL;
if (reverse_prop)
{
GtkWidget *toggle;
GtkWidget *view;
GtkWidget *image;
gchar *signal_name;
toggle = gimp_prop_check_button_new (G_OBJECT (context), reverse_prop,
NULL);
gtk_box_pack_start (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
gtk_widget_show (toggle);
gimp_help_set_help_data (toggle, _("Reverse"), NULL);
image = gtk_image_new_from_stock (GIMP_STOCK_FLIP_HORIZONTAL,
GTK_ICON_SIZE_MENU);
gtk_container_add (GTK_CONTAINER (toggle), image);
gtk_widget_show (image);
view = gtk_bin_get_child (GTK_BIN (button));
signal_name = g_strconcat ("notify::", reverse_prop, NULL);
g_signal_connect_object (context, signal_name,
G_CALLBACK (gimp_gradient_box_reverse_notify),
G_OBJECT (view), 0);
g_free (signal_name);
gimp_gradient_box_reverse_notify (G_OBJECT (context),
NULL,
GIMP_VIEW (view));
}
return hbox;
}
GtkWidget *
gimp_gradient_box_new (GimpContainer *container,
GimpContext *context,
const gchar *label,
gint spacing,
const gchar *reverse_prop)
{
g_return_val_if_fail (container == NULL || GIMP_IS_CONTAINER (container),
NULL);
g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
return gradient_box_new (container, context, label, spacing,
GIMP_VIEW_TYPE_LIST, GIMP_VIEW_SIZE_LARGE,
reverse_prop);
}
GtkWidget *
gimp_prop_gradient_box_new (GimpContainer *container,
GimpContext *context,
const gchar *label,
gint spacing,
const gchar *view_type_prop,
const gchar *view_size_prop,
const gchar *reverse_prop)
{
GimpViewType view_type;
GimpViewSize view_size;
g_return_val_if_fail (container == NULL || GIMP_IS_CONTAINER (container),
NULL);
g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
g_object_get (context,
view_type_prop, &view_type,
view_size_prop, &view_size,
NULL);
return view_props_connect (gradient_box_new (container, context, label, spacing,
view_type, view_size,
reverse_prop),
context,
view_type_prop, view_size_prop);
}
/* palette boxes */
static GtkWidget *
palette_box_new (GimpContainer *container,
GimpContext *context,
const gchar *label,
gint spacing,
GimpViewType view_type,
GimpViewSize view_size)
{
if (! container)
container = gimp_data_factory_get_container (context->gimp->palette_factory);
return gimp_viewable_box_new (container, context, label, spacing,
view_type, GIMP_VIEW_SIZE_MEDIUM, view_size,
"gimp-palette-list|gimp-palette-grid",
GIMP_STOCK_PALETTE,
_("Open the palette selection dialog"));
}
GtkWidget *
gimp_palette_box_new (GimpContainer *container,
GimpContext *context,
const gchar *label,
gint spacing)
{
g_return_val_if_fail (container == NULL || GIMP_IS_CONTAINER (container),
NULL);
g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
return palette_box_new (container, context, label, spacing,
GIMP_VIEW_TYPE_LIST, GIMP_VIEW_SIZE_MEDIUM);
}
GtkWidget *
gimp_prop_palette_box_new (GimpContainer *container,
GimpContext *context,
const gchar *label,
gint spacing,
const gchar *view_type_prop,
const gchar *view_size_prop)
{
GimpViewType view_type;
GimpViewSize view_size;
g_return_val_if_fail (container == NULL || GIMP_IS_CONTAINER (container),
NULL);
g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
g_object_get (context,
view_type_prop, &view_type,
view_size_prop, &view_size,
NULL);
return view_props_connect (palette_box_new (container, context, label, spacing,
view_type, view_size),
context,
view_type_prop, view_size_prop);
}
/* font boxes */
static GtkWidget *
font_box_new (GimpContainer *container,
GimpContext *context,
const gchar *label,
gint spacing,
GimpViewType view_type,
GimpViewSize view_size)
{
if (! container)
container = context->gimp->fonts;
return gimp_viewable_box_new (container, context, label, spacing,
view_type, GIMP_VIEW_SIZE_SMALL, view_size,
"gimp-font-list|gimp-font-grid",
GIMP_STOCK_FONT,
_("Open the font selection dialog"));
}
GtkWidget *
gimp_font_box_new (GimpContainer *container,
GimpContext *context,
const gchar *label,
gint spacing)
{
g_return_val_if_fail (container == NULL || GIMP_IS_CONTAINER (container),
NULL);
g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
return font_box_new (container, context, label, spacing,
GIMP_VIEW_TYPE_LIST, GIMP_VIEW_SIZE_SMALL);
}
GtkWidget *
gimp_prop_font_box_new (GimpContainer *container,
GimpContext *context,
const gchar *label,
gint spacing,
const gchar *view_type_prop,
const gchar *view_size_prop)
{
GimpViewType view_type;
GimpViewSize view_size;
g_return_val_if_fail (container == NULL || GIMP_IS_CONTAINER (container),
NULL);
g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
g_object_get (context,
view_type_prop, &view_type,
view_size_prop, &view_size,
NULL);
return view_props_connect (font_box_new (container, context, label, spacing,
view_type, view_size),
context,
view_type_prop, view_size_prop);
}
/* private functions */
static GtkWidget *
gimp_viewable_box_new (GimpContainer *container,
GimpContext *context,
const gchar *label,
gint spacing,
GimpViewType view_type,
GimpViewType button_view_size,
GimpViewSize view_size,
const gchar *dialog_identifier,
const gchar *dialog_stock_id,
const gchar *dialog_tooltip)
{
GtkWidget *hbox;
GtkWidget *button;
GtkWidget *vbox;
GtkWidget *l;
GtkWidget *entry;
hbox = gtk_hbox_new (FALSE, spacing);
button = gimp_viewable_button_new (container, context,
view_type, button_view_size, view_size, 1,
gimp_dialog_factory_get_singleton (),
dialog_identifier,
dialog_stock_id,
dialog_tooltip);
g_object_set_data (G_OBJECT (hbox), "viewable-button", button);
gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
gtk_widget_show (button);
vbox = gtk_vbox_new (FALSE, 0);
gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0);
gtk_widget_show (vbox);
if (label)
{
l = gtk_label_new_with_mnemonic (label);
gtk_misc_set_alignment (GTK_MISC (l), 0.0, 0.5);
gtk_box_pack_start (GTK_BOX (vbox), l, FALSE, FALSE, 0);
gtk_widget_show (l);
}
entry = gimp_container_entry_new (container, context, view_size, 1);
/* set a silly smally size request on the entry to disable
* GtkEntry's minimal width of 150 pixels.
*/
gtk_widget_set_size_request (entry, 10, -1);
gtk_box_pack_start (GTK_BOX (vbox), entry, label ? FALSE: TRUE, FALSE, 0);
gtk_widget_show (entry);
return hbox;
}
static GtkWidget *
view_props_connect (GtkWidget *box,
GimpContext *context,
const gchar *view_type_prop,
const gchar *view_size_prop)
{
GtkWidget *button = g_object_get_data (G_OBJECT (box), "viewable-button");
gimp_config_connect_full (G_OBJECT (context), G_OBJECT (button),
view_type_prop, "popup-view-type");
gimp_config_connect_full (G_OBJECT (context), G_OBJECT (button),
view_size_prop, "popup-view-size");
return box;
}
static void
gimp_gradient_box_reverse_notify (GObject *object,
GParamSpec *pspec,
GimpView *view)
{
GimpViewRendererGradient *rendergrad;
gboolean reverse;
rendergrad = GIMP_VIEW_RENDERER_GRADIENT (view->renderer);
g_object_get (object, "gradient-reverse", &reverse, NULL);
gimp_view_renderer_gradient_set_reverse (rendergrad, reverse);
}