gimptooloptionseditor.c 19.5 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
G_DEFINE_TYPE_WITH_CODE (GimpToolOptionsEditor, gimp_tool_options_editor,
                         GIMP_TYPE_EDITOR,
108
                         G_ADD_PRIVATE (GimpToolOptionsEditor)
109
                         G_IMPLEMENT_INTERFACE (GIMP_TYPE_DOCKED,
110
                                                gimp_tool_options_editor_docked_iface_init))
111

112
#define parent_class gimp_tool_options_editor_parent_class
113

114

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

120
  object_class->constructed  = gimp_tool_options_editor_constructed;
121
  object_class->dispose      = gimp_tool_options_editor_dispose;
122 123 124 125 126 127 128 129 130
  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));
131
}
132

133 134 135 136 137 138 139 140
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;
}

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

146
  editor->p = gimp_tool_options_editor_get_instance_private (editor);
147

148 149 150 151 152 153 154
  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);

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

165 166
  editor->p->scrolled_window = gtk_scrolled_window_new (NULL, NULL);
  scrolled_window = GTK_SCROLLED_WINDOW (editor->p->scrolled_window);
167 168

  gtk_scrolled_window_set_policy (scrolled_window,
169 170
                                  GTK_POLICY_AUTOMATIC,
                                  GTK_POLICY_AUTOMATIC);
171
  gtk_scrolled_window_set_overlay_scrolling (scrolled_window, FALSE);
172

173 174
  gtk_box_pack_start (GTK_BOX (editor), editor->p->scrolled_window,
                      TRUE, TRUE, 0);
175
  gtk_widget_show (editor->p->scrolled_window);
176

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

static void
184
gimp_tool_options_editor_constructed (GObject *object)
185
{
186 187
  GimpToolOptionsEditor *editor = GIMP_TOOL_OPTIONS_EDITOR (object);
  GimpContext           *user_context;
188

189
  G_OBJECT_CLASS (parent_class)->constructed (object);
190

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

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

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

218
  editor->p->reset_button =
219 220 221 222 223
    gimp_editor_add_action_button (GIMP_EDITOR (editor), "tool-options",
                                   "tool-options-reset",
                                   "tool-options-reset-all",
                                   GDK_SHIFT_MASK,
                                   NULL);
224

225 226 227 228 229 230 231 232 233 234
  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);
235 236
}

237 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
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);
}

263 264 265 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
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;
    }
}

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

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

318
  return view;
319
}
320

321 322 323 324 325 326
static gchar *
gimp_tool_options_editor_get_title (GimpDocked *docked)
{
  GimpToolOptionsEditor *editor = GIMP_TOOL_OPTIONS_EDITOR (docked);
  GimpContext           *context;
  GimpToolInfo          *tool_info;
327

328
  context = gimp_get_user_context (editor->p->gimp);
329

330
  tool_info = gimp_context_get_tool (context);
331

332
  return tool_info ? g_strdup (tool_info->label) : NULL;
333 334
}

335 336 337 338 339 340 341 342 343
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;
}

344 345 346

/*  public functions  */

347 348 349
GtkWidget *
gimp_tool_options_editor_new (Gimp            *gimp,
                              GimpMenuFactory *menu_factory)
350
{
351 352
  g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
  g_return_val_if_fail (GIMP_IS_MENU_FACTORY (menu_factory), NULL);
353

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

362 363 364 365 366 367 368
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;
}
369 370 371

/*  private functions  */

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

379 380 381 382
  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));
383

384 385 386 387 388 389 390
  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);
391 392 393 394 395 396
}

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

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

static void
gimp_tool_options_editor_delete_clicked (GtkWidget             *widget,
                                         GimpToolOptionsEditor *editor)
{
422
  gimp_tool_options_editor_menu_popup (editor, widget,
423
                                       "/tool-options-popup/Delete");
424
}
425

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

436
  context = gimp_get_user_context (editor->p->gimp);
437

438
  gimp_context_set_tool (context, GIMP_TOOL_INFO (viewable));
439 440 441
}

static void
442 443 444
gimp_tool_options_editor_tool_changed (GimpContext           *context,
                                       GimpToolInfo          *tool_info,
                                       GimpToolOptionsEditor *editor)
445
{
446 447
  GimpContainer *presets;
  GtkWidget     *options_gui;
448

449
  if (tool_info && tool_info->tool_options == editor->p->visible_tool_options)
450 451
    return;

452
  if (editor->p->visible_tool_options)
453
    {
454
      presets = editor->p->visible_tool_options->tool_info->presets;
455 456 457

      if (presets)
        g_signal_handlers_disconnect_by_func (presets,
458
                                              gimp_tool_options_editor_presets_update,
459 460
                                              editor);

461
      options_gui = gimp_tools_get_tool_options_gui (editor->p->visible_tool_options);
462 463 464 465

      if (options_gui)
        gtk_widget_hide (options_gui);

466
      editor->p->visible_tool_options = NULL;
467 468 469 470
    }

  if (tool_info && tool_info->tool_options)
    {
471
      presets = tool_info->presets;
472 473

      if (presets)
474 475 476 477 478 479 480 481 482 483 484
        {
          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);
        }
485

486
      options_gui = gimp_tools_get_tool_options_gui (tool_info->tool_options);
487

488
      if (! gtk_widget_get_parent (options_gui))
489
        gtk_box_pack_start (GTK_BOX (editor->p->options_vbox), options_gui,
490
                            FALSE, FALSE, 0);
491

492 493
      gtk_widget_show (options_gui);

494
      editor->p->visible_tool_options = tool_info->tool_options;
495

496
      gimp_help_set_help_data (editor->p->scrolled_window, NULL,
497
                               tool_info->help_id);
498

499 500
      gimp_tool_options_editor_presets_update (editor);
    }
501

502 503
  if (editor->p->title_label != NULL)
    {
504 505 506 507
      gchar *title;

      title = gimp_docked_get_title (GIMP_DOCKED (editor));
      gtk_label_set_text (GTK_LABEL (editor->p->title_label), title);
508 509 510
      g_free (title);
    }

511
  gimp_docked_title_changed (GIMP_DOCKED (editor));
512 513
}

514
static void
515
gimp_tool_options_editor_presets_update (GimpToolOptionsEditor *editor)
516
{
517 518 519 520 521
  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;
522

523
  if (tool_info->presets)
524 525 526 527
    {
      save_sensitive  = TRUE;
      reset_sensitive = TRUE;

528
      if (! gimp_container_is_empty (tool_info->presets))
529 530 531 532 533
        {
          restore_sensitive = TRUE;
          delete_sensitive  = TRUE;
        }
    }
534

535 536 537 538
  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);
539
}