gimptooloptionseditor.c 19.6 KB
Newer Older
1
/* GIMP - The GNU Image Manipulation Program
2 3
 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
 *
4 5 6
 * gimptooloptionseditor.c
 * Copyright (C) 2003 Michael Natterer <mitch@gimp.org>
 *
7
 * This program is free software: you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation; either version 3 of the License, or
10 11 12 13 14 15 16 17
 * (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
18
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
19 20 21 22
 */

#include "config.h"

23
#include <gegl.h>
24 25
#include <gtk/gtk.h>

26
#include "libgimpwidgets/gimpwidgets.h"
27

28
#include "widgets-types.h"
29

30
#include "core/gimp.h"
31
#include "core/gimpcontext.h"
32
#include "core/gimplist.h"
33
#include "core/gimptoolinfo.h"
34
#include "core/gimptooloptions.h"
35

36
#include "gimpdnd.h"
37
#include "gimpdocked.h"
38 39
#include "gimphelp-ids.h"
#include "gimpmenufactory.h"
40
#include "gimppropwidgets.h"
41
#include "gimpview.h"
42
#include "gimpviewrenderer.h"
43
#include "gimptooloptionseditor.h"
44
#include "gimpuimanager.h"
45
#include "gimpwidgets-utils.h"
46

47
#include "gimp-intl.h"
48

49 50 51 52 53
enum
{
  PROP_0,
  PROP_GIMP,
};
54

55 56 57 58 59 60
struct _GimpToolOptionsEditorPrivate
{
  Gimp            *gimp;

  GtkWidget       *scrolled_window;
  GtkWidget       *options_vbox;
61
  GtkWidget       *title_label;
62 63 64 65 66 67 68 69 70 71 72

  GtkWidget       *save_button;
  GtkWidget       *restore_button;
  GtkWidget       *delete_button;
  GtkWidget       *reset_button;

  GimpToolOptions *visible_tool_options;
};


static void        gimp_tool_options_editor_docked_iface_init (GimpDockedInterface   *iface);
73
static void        gimp_tool_options_editor_constructed       (GObject               *object);
74
static void        gimp_tool_options_editor_dispose           (GObject               *object);
75 76 77 78 79 80 81 82
static void        gimp_tool_options_editor_set_property      (GObject               *object,
                                                               guint                  property_id,
                                                               const GValue          *value,
                                                               GParamSpec            *pspec);
static void        gimp_tool_options_editor_get_property      (GObject               *object,
                                                               guint                  property_id,
                                                               GValue                *value,
                                                               GParamSpec            *pspec);
83

84 85 86 87
static GtkWidget * gimp_tool_options_editor_get_preview       (GimpDocked            *docked,
                                                               GimpContext           *context,
                                                               GtkIconSize            size);
static gchar     * gimp_tool_options_editor_get_title         (GimpDocked            *docked);
88
static gboolean    gimp_tool_options_editor_get_prefer_icon   (GimpDocked            *docked);
89 90 91 92 93 94 95 96 97 98 99 100 101 102
static void        gimp_tool_options_editor_save_clicked      (GtkWidget             *widget,
                                                               GimpToolOptionsEditor *editor);
static void        gimp_tool_options_editor_restore_clicked   (GtkWidget             *widget,
                                                               GimpToolOptionsEditor *editor);
static void        gimp_tool_options_editor_delete_clicked    (GtkWidget             *widget,
                                                               GimpToolOptionsEditor *editor);
static void        gimp_tool_options_editor_drop_tool         (GtkWidget             *widget,
                                                               gint                   x,
                                                               gint                   y,
                                                               GimpViewable          *viewable,
                                                               gpointer               data);
static void        gimp_tool_options_editor_tool_changed      (GimpContext           *context,
                                                               GimpToolInfo          *tool_info,
                                                               GimpToolOptionsEditor *editor);
103
static void        gimp_tool_options_editor_presets_update    (GimpToolOptionsEditor *editor);
104

105

106 107 108
G_DEFINE_TYPE_WITH_CODE (GimpToolOptionsEditor, gimp_tool_options_editor,
                         GIMP_TYPE_EDITOR,
                         G_IMPLEMENT_INTERFACE (GIMP_TYPE_DOCKED,
109
                                                gimp_tool_options_editor_docked_iface_init))
110

111
#define parent_class gimp_tool_options_editor_parent_class
112

113

114 115 116
static void
gimp_tool_options_editor_class_init (GimpToolOptionsEditorClass *klass)
{
117
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
118

119
  object_class->constructed  = gimp_tool_options_editor_constructed;
120
  object_class->dispose      = gimp_tool_options_editor_dispose;
121 122 123 124 125 126 127 128 129
  object_class->set_property = gimp_tool_options_editor_set_property;
  object_class->get_property = gimp_tool_options_editor_get_property;

  g_object_class_install_property (object_class, PROP_GIMP,
                                   g_param_spec_object ("gimp",
                                                        NULL, NULL,
                                                        GIMP_TYPE_GIMP,
                                                        GIMP_PARAM_READWRITE |
                                                        G_PARAM_CONSTRUCT_ONLY));
130 131

  g_type_class_add_private (klass, sizeof (GimpToolOptionsEditorPrivate));
132
}
133

134 135 136 137 138 139 140 141
static void
gimp_tool_options_editor_docked_iface_init (GimpDockedInterface *docked_iface)
{
  docked_iface->get_preview     = gimp_tool_options_editor_get_preview;
  docked_iface->get_title       = gimp_tool_options_editor_get_title;
  docked_iface->get_prefer_icon = gimp_tool_options_editor_get_prefer_icon;
}

142 143 144
static void
gimp_tool_options_editor_init (GimpToolOptionsEditor *editor)
{
145
  GtkScrolledWindow *scrolled_window;
146

147 148 149 150
  editor->p = G_TYPE_INSTANCE_GET_PRIVATE (editor,
                                           GIMP_TYPE_TOOL_OPTIONS_EDITOR,
                                           GimpToolOptionsEditorPrivate);

151 152 153 154 155 156 157
  gtk_widget_set_size_request (GTK_WIDGET (editor), -1, 200);

  gimp_dnd_viewable_dest_add (GTK_WIDGET (editor),
                              GIMP_TYPE_TOOL_INFO,
                              gimp_tool_options_editor_drop_tool,
                              editor);

158 159
  /*  The label containing the tool options title */
  editor->p->title_label = gtk_label_new (NULL);
160
  gtk_label_set_xalign (GTK_LABEL (editor->p->title_label), 0.0);
161 162 163
  gimp_label_set_attributes (GTK_LABEL (editor->p->title_label),
                             PANGO_ATTR_WEIGHT, PANGO_WEIGHT_BOLD,
                             -1);
164 165
  gtk_box_pack_start (GTK_BOX (editor), editor->p->title_label,
                      FALSE, FALSE, 0);
166 167
  gtk_widget_show (editor->p->title_label);

168 169
  editor->p->scrolled_window = gtk_scrolled_window_new (NULL, NULL);
  scrolled_window = GTK_SCROLLED_WINDOW (editor->p->scrolled_window);
170 171

  gtk_scrolled_window_set_policy (scrolled_window,
172 173
                                  GTK_POLICY_AUTOMATIC,
                                  GTK_POLICY_AUTOMATIC);
174
  gtk_scrolled_window_set_overlay_scrolling (scrolled_window, FALSE);
175

176 177
  gtk_box_pack_start (GTK_BOX (editor), editor->p->scrolled_window,
                      TRUE, TRUE, 0);
178
  gtk_widget_show (editor->p->scrolled_window);
179

180
  /*  The vbox containing the tool options  */
181
  editor->p->options_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
182
  gtk_container_add (GTK_CONTAINER (scrolled_window), editor->p->options_vbox);
183
  gtk_widget_show (editor->p->options_vbox);
184 185 186
}

static void
187
gimp_tool_options_editor_constructed (GObject *object)
188
{
189 190
  GimpToolOptionsEditor *editor = GIMP_TOOL_OPTIONS_EDITOR (object);
  GimpContext           *user_context;
191

192
  G_OBJECT_CLASS (parent_class)->constructed (object);
193

194
  editor->p->save_button =
195 196
    gimp_editor_add_button (GIMP_EDITOR (editor),
                            GIMP_ICON_DOCUMENT_SAVE,
197
                            _("Save Tool Preset..."),
198 199
                            GIMP_HELP_TOOL_OPTIONS_SAVE,
                            G_CALLBACK (gimp_tool_options_editor_save_clicked),
200
                            NULL,
201
                            editor);
202

203
  editor->p->restore_button =
204 205
    gimp_editor_add_button (GIMP_EDITOR (editor),
                            GIMP_ICON_DOCUMENT_REVERT,
206
                            _("Restore Tool Preset..."),
207 208
                            GIMP_HELP_TOOL_OPTIONS_RESTORE,
                            G_CALLBACK (gimp_tool_options_editor_restore_clicked),
209
                            NULL,
210
                            editor);
211

212
  editor->p->delete_button =
213 214
    gimp_editor_add_button (GIMP_EDITOR (editor),
                            GIMP_ICON_EDIT_DELETE,
215
                            _("Delete Tool Preset..."),
216 217 218 219 220
                            GIMP_HELP_TOOL_OPTIONS_DELETE,
                            G_CALLBACK (gimp_tool_options_editor_delete_clicked),
                            NULL,
                            editor);

221
  editor->p->reset_button =
222 223 224 225 226
    gimp_editor_add_action_button (GIMP_EDITOR (editor), "tool-options",
                                   "tool-options-reset",
                                   "tool-options-reset-all",
                                   GDK_SHIFT_MASK,
                                   NULL);
227

228 229 230 231 232 233 234 235 236 237
  user_context = gimp_get_user_context (editor->p->gimp);

  g_signal_connect_object (user_context, "tool-changed",
                           G_CALLBACK (gimp_tool_options_editor_tool_changed),
                           editor,
                           0);

  gimp_tool_options_editor_tool_changed (user_context,
                                         gimp_context_get_tool (user_context),
                                         editor);
238 239
}

240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265
static void
gimp_tool_options_editor_dispose (GObject *object)
{
  GimpToolOptionsEditor *editor = GIMP_TOOL_OPTIONS_EDITOR (object);

  if (editor->p->options_vbox)
    {
      GList *options;
      GList *list;

      options =
        gtk_container_get_children (GTK_CONTAINER (editor->p->options_vbox));

      for (list = options; list; list = g_list_next (list))
        {
          gtk_container_remove (GTK_CONTAINER (editor->p->options_vbox),
                                GTK_WIDGET (list->data));
        }

      g_list_free (options);
      editor->p->options_vbox = NULL;
    }

  G_OBJECT_CLASS (parent_class)->dispose (object);
}

266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305
static void
gimp_tool_options_editor_set_property (GObject      *object,
                                       guint         property_id,
                                       const GValue *value,
                                       GParamSpec   *pspec)
{
  GimpToolOptionsEditor *editor = GIMP_TOOL_OPTIONS_EDITOR (object);

  switch (property_id)
    {
    case PROP_GIMP:
      editor->p->gimp = g_value_get_object (value);
      break;

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
      break;
    }
}

static void
gimp_tool_options_editor_get_property (GObject    *object,
                                       guint       property_id,
                                       GValue     *value,
                                       GParamSpec *pspec)
{
  GimpToolOptionsEditor *editor = GIMP_TOOL_OPTIONS_EDITOR (object);

  switch (property_id)
    {
    case PROP_GIMP:
      g_value_set_object (value, editor->p->gimp);
      break;

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
      break;
    }
}

306 307 308 309 310
static GtkWidget *
gimp_tool_options_editor_get_preview (GimpDocked   *docked,
                                      GimpContext  *context,
                                      GtkIconSize   size)
{
311 312 313
  GtkWidget *view;
  gint       width;
  gint       height;
314

315
  gtk_icon_size_lookup (size, &width, &height);
316
  view = gimp_prop_view_new (G_OBJECT (context), "tool", context, height);
317
  GIMP_VIEW (view)->renderer->size = -1;
318 319
  gimp_view_renderer_set_size_full (GIMP_VIEW (view)->renderer,
                                    width, height, 0);
320

321
  return view;
322
}
323

324 325 326 327 328 329
static gchar *
gimp_tool_options_editor_get_title (GimpDocked *docked)
{
  GimpToolOptionsEditor *editor = GIMP_TOOL_OPTIONS_EDITOR (docked);
  GimpContext           *context;
  GimpToolInfo          *tool_info;
330

331
  context = gimp_get_user_context (editor->p->gimp);
332

333
  tool_info = gimp_context_get_tool (context);
334

335
  return tool_info ? g_strdup (tool_info->label) : NULL;
336 337
}

338 339 340 341 342 343 344 345 346
static gboolean
gimp_tool_options_editor_get_prefer_icon (GimpDocked *docked)
{
  /* We support get_preview() for tab tyles, but we prefer to show our
   * icon
   */
  return TRUE;
}

347 348 349

/*  public functions  */

350 351 352
GtkWidget *
gimp_tool_options_editor_new (Gimp            *gimp,
                              GimpMenuFactory *menu_factory)
353
{
354 355
  g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
  g_return_val_if_fail (GIMP_IS_MENU_FACTORY (menu_factory), NULL);
356

357 358 359 360 361 362
  return g_object_new (GIMP_TYPE_TOOL_OPTIONS_EDITOR,
                       "gimp",            gimp,
                       "menu-factory",    menu_factory,
                       "menu-identifier", "<ToolOptions>",
                       "ui-path",         "/tool-options-popup",
                       NULL);
363
}
364

365 366 367 368 369 370 371
GimpToolOptions *
gimp_tool_options_editor_get_tool_options (GimpToolOptionsEditor *editor)
{
  g_return_val_if_fail (GIMP_IS_TOOL_OPTIONS_EDITOR (editor), NULL);

  return editor->p->visible_tool_options;
}
372 373 374

/*  private functions  */

375 376 377 378 379
static void
gimp_tool_options_editor_menu_popup (GimpToolOptionsEditor *editor,
                                     GtkWidget             *button,
                                     const gchar           *path)
{
380 381
  GimpEditor *gimp_editor = GIMP_EDITOR (editor);

382 383 384 385
  gtk_ui_manager_get_widget (GTK_UI_MANAGER (gimp_editor_get_ui_manager (gimp_editor)),
                             gimp_editor_get_ui_path (gimp_editor));
  gimp_ui_manager_update (gimp_editor_get_ui_manager (gimp_editor),
                          gimp_editor_get_popup_data (gimp_editor));
386

387 388 389 390 391 392 393
  gimp_ui_manager_ui_popup_at_widget (gimp_editor_get_ui_manager (gimp_editor),
                                      path,
                                      button,
                                      GDK_GRAVITY_WEST,
                                      GDK_GRAVITY_NORTH_EAST,
                                      NULL,
                                      NULL, NULL);
394 395 396 397 398 399
}

static void
gimp_tool_options_editor_save_clicked (GtkWidget             *widget,
                                       GimpToolOptionsEditor *editor)
{
400
  if (gtk_widget_get_sensitive (editor->p->restore_button) /* evil but correct */)
401
    {
402
      gimp_tool_options_editor_menu_popup (editor, widget,
403
                                           "/tool-options-popup/Save");
404 405 406
    }
  else
    {
407
      gimp_ui_manager_activate_action (gimp_editor_get_ui_manager (GIMP_EDITOR (editor)),
408
                                       "tool-options",
409
                                       "tool-options-save-new-preset");
410
    }
411 412 413
}

static void
414 415
gimp_tool_options_editor_restore_clicked (GtkWidget             *widget,
                                          GimpToolOptionsEditor *editor)
416
{
417
  gimp_tool_options_editor_menu_popup (editor, widget,
418
                                       "/tool-options-popup/Restore");
419 420 421 422 423 424
}

static void
gimp_tool_options_editor_delete_clicked (GtkWidget             *widget,
                                         GimpToolOptionsEditor *editor)
{
425
  gimp_tool_options_editor_menu_popup (editor, widget,
426
                                       "/tool-options-popup/Delete");
427
}
428

429 430
static void
gimp_tool_options_editor_drop_tool (GtkWidget    *widget,
431 432
                                    gint          x,
                                    gint          y,
433 434 435 436 437
                                    GimpViewable *viewable,
                                    gpointer      data)
{
  GimpToolOptionsEditor *editor = GIMP_TOOL_OPTIONS_EDITOR (data);
  GimpContext           *context;
438

439
  context = gimp_get_user_context (editor->p->gimp);
440

441
  gimp_context_set_tool (context, GIMP_TOOL_INFO (viewable));
442 443 444
}

static void
445 446 447
gimp_tool_options_editor_tool_changed (GimpContext           *context,
                                       GimpToolInfo          *tool_info,
                                       GimpToolOptionsEditor *editor)
448
{
449 450
  GimpContainer *presets;
  GtkWidget     *options_gui;
451

452
  if (tool_info && tool_info->tool_options == editor->p->visible_tool_options)
453 454
    return;

455
  if (editor->p->visible_tool_options)
456
    {
457
      presets = editor->p->visible_tool_options->tool_info->presets;
458 459 460

      if (presets)
        g_signal_handlers_disconnect_by_func (presets,
461
                                              gimp_tool_options_editor_presets_update,
462 463
                                              editor);

464
      options_gui = gimp_tools_get_tool_options_gui (editor->p->visible_tool_options);
465 466 467 468

      if (options_gui)
        gtk_widget_hide (options_gui);

469
      editor->p->visible_tool_options = NULL;
470 471 472 473
    }

  if (tool_info && tool_info->tool_options)
    {
474
      presets = tool_info->presets;
475 476

      if (presets)
477 478 479 480 481 482 483 484 485 486 487
        {
          g_signal_connect_object (presets, "add",
                                   G_CALLBACK (gimp_tool_options_editor_presets_update),
                                   G_OBJECT (editor), G_CONNECT_SWAPPED);
          g_signal_connect_object (presets, "remove",
                                   G_CALLBACK (gimp_tool_options_editor_presets_update),
                                   G_OBJECT (editor), G_CONNECT_SWAPPED);
          g_signal_connect_object (presets, "thaw",
                                   G_CALLBACK (gimp_tool_options_editor_presets_update),
                                   G_OBJECT (editor), G_CONNECT_SWAPPED);
        }
488

489
      options_gui = gimp_tools_get_tool_options_gui (tool_info->tool_options);
490

491
      if (! gtk_widget_get_parent (options_gui))
492
        gtk_box_pack_start (GTK_BOX (editor->p->options_vbox), options_gui,
493
                            FALSE, FALSE, 0);
494

495 496
      gtk_widget_show (options_gui);

497
      editor->p->visible_tool_options = tool_info->tool_options;
498

499
      gimp_help_set_help_data (editor->p->scrolled_window, NULL,
500
                               tool_info->help_id);
501

502 503
      gimp_tool_options_editor_presets_update (editor);
    }
504

505 506
  if (editor->p->title_label != NULL)
    {
507 508 509 510
      gchar *title;

      title = gimp_docked_get_title (GIMP_DOCKED (editor));
      gtk_label_set_text (GTK_LABEL (editor->p->title_label), title);
511 512 513
      g_free (title);
    }

514
  gimp_docked_title_changed (GIMP_DOCKED (editor));
515 516
}

517
static void
518
gimp_tool_options_editor_presets_update (GimpToolOptionsEditor *editor)
519
{
520 521 522 523 524
  GimpToolInfo *tool_info         = editor->p->visible_tool_options->tool_info;
  gboolean      save_sensitive    = FALSE;
  gboolean      restore_sensitive = FALSE;
  gboolean      delete_sensitive  = FALSE;
  gboolean      reset_sensitive   = FALSE;
525

526
  if (tool_info->presets)
527 528 529 530
    {
      save_sensitive  = TRUE;
      reset_sensitive = TRUE;

531
      if (! gimp_container_is_empty (tool_info->presets))
532 533 534 535 536
        {
          restore_sensitive = TRUE;
          delete_sensitive  = TRUE;
        }
    }
537

538 539 540 541
  gtk_widget_set_sensitive (editor->p->save_button,    save_sensitive);
  gtk_widget_set_sensitive (editor->p->restore_button, restore_sensitive);
  gtk_widget_set_sensitive (editor->p->delete_button,  delete_sensitive);
  gtk_widget_set_sensitive (editor->p->reset_button,   reset_sensitive);
542
}