gimptooldialog.c 6.3 KB
Newer Older
1
/* GIMP - The GNU Image Manipulation Program
2 3
 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
 *
4 5
 * gimptooldialog.c
 * Copyright (C) 2003  Sven Neumann <sven@gimp.org>
6
 *
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 26 27
#include <gtk/gtk.h>

#include "libgimpwidgets/gimpwidgets.h"

28
#include "display-types.h"
29 30 31 32

#include "core/gimpobject.h"
#include "core/gimptoolinfo.h"

33 34
#include "widgets/gimpdialogfactory.h"

35
#include "gimpdisplayshell.h"
36
#include "gimptooldialog.h"
37 38


39 40 41 42 43 44 45
typedef struct _GimpToolDialogPrivate GimpToolDialogPrivate;

struct _GimpToolDialogPrivate
{
  GimpDisplayShell *shell;
};

46
#define GET_PRIVATE(dialog) ((GimpToolDialogPrivate *) gimp_tool_dialog_get_instance_private ((GimpToolDialog *) (dialog)))
47 48


49 50
static void   gimp_tool_dialog_dispose     (GObject          *object);

51 52 53 54
static void   gimp_tool_dialog_shell_unmap (GimpDisplayShell *shell,
                                            GimpToolDialog   *dialog);


55 56
G_DEFINE_TYPE_WITH_PRIVATE (GimpToolDialog, gimp_tool_dialog,
                            GIMP_TYPE_VIEWABLE_DIALOG)
57

58

59 60 61 62 63 64 65
static void
gimp_tool_dialog_class_init (GimpToolDialogClass *klass)
{
  GObjectClass *object_class = G_OBJECT_CLASS (klass);

  object_class->dispose = gimp_tool_dialog_dispose;

66
  gtk_widget_class_set_css_name (GTK_WIDGET_CLASS (klass), "GimpToolDialog");
67 68 69 70 71 72 73
}

static void
gimp_tool_dialog_init (GimpToolDialog *dialog)
{
}

74 75 76 77 78 79 80 81 82 83 84 85 86 87
static void
gimp_tool_dialog_dispose (GObject *object)
{
  GimpToolDialogPrivate *private = GET_PRIVATE (object);

  if (private->shell)
    {
      g_object_remove_weak_pointer (G_OBJECT (private->shell),
                                    (gpointer) &private->shell);
      private->shell = NULL;
    }

  G_OBJECT_CLASS (gimp_tool_dialog_parent_class)->dispose (object);
}
88

89

90 91 92
/**
 * gimp_tool_dialog_new:
 * @tool_info: a #GimpToolInfo
Michael Natterer's avatar
Michael Natterer committed
93 94 95 96
 * @desc:      a string to use in the dialog header or %NULL to use the help
 *             field from #GimpToolInfo
 * @...:       a %NULL-terminated valist of button parameters as described in
 *             gtk_dialog_new_with_buttons().
97 98 99 100 101 102 103
 *
 * This function conveniently creates a #GimpViewableDialog using the
 * information stored in @tool_info. It also registers the tool with
 * the "toplevel" dialog factory.
 *
 * Return value: a new #GimpViewableDialog
 **/
104
GtkWidget *
105
gimp_tool_dialog_new (GimpToolInfo *tool_info,
106
                      GdkMonitor   *monitor,
107 108 109 110
                      const gchar  *title,
                      const gchar  *description,
                      const gchar  *icon_name,
                      const gchar  *help_id,
111 112
                      ...)
{
113 114 115
  GtkWidget *dialog;
  gchar     *identifier;
  va_list    args;
116
  gboolean   use_header_bar;
117 118 119

  g_return_val_if_fail (GIMP_IS_TOOL_INFO (tool_info), NULL);

120
  if (! title)
121
    title = tool_info->label;
122 123

  if (! description)
124
    description = tool_info->tooltip;
125 126 127 128 129 130

  if (! help_id)
    help_id = tool_info->help_id;

  if (! icon_name)
    icon_name = gimp_viewable_get_icon_name (GIMP_VIEWABLE (tool_info));
131

132 133 134 135
  g_object_get (gtk_settings_get_default (),
                "gtk-dialogs-use-header", &use_header_bar,
                NULL);

136
  dialog = g_object_new (GIMP_TYPE_TOOL_DIALOG,
137 138 139 140 141 142 143 144
                         "title",          title,
                         "role",           gimp_object_get_name (tool_info),
                         "description",    description,
                         "icon-name",      icon_name,
                         "help-func",      gimp_standard_help_func,
                         "help-id",        help_id,
                         "use-header-bar", use_header_bar,
                          NULL);
145

146
  va_start (args, help_id);
147
  gimp_dialog_add_buttons_valist (GIMP_DIALOG (dialog), args);
148 149
  va_end (args);

150
  identifier = g_strconcat (gimp_object_get_name (tool_info), "-dialog", NULL);
151

152
  gimp_dialog_factory_add_foreign (gimp_dialog_factory_get_singleton (),
153
                                   identifier,
154 155
                                   dialog,
                                   monitor);
156 157 158 159 160

  g_free (identifier);

  return dialog;
}
161 162 163 164 165 166 167 168

void
gimp_tool_dialog_set_shell (GimpToolDialog   *tool_dialog,
                            GimpDisplayShell *shell)
{
  GimpToolDialogPrivate *private = GET_PRIVATE (tool_dialog);

  g_return_if_fail (GIMP_IS_TOOL_DIALOG (tool_dialog));
169
  g_return_if_fail (shell == NULL || GIMP_IS_DISPLAY_SHELL (shell));
170 171 172 173 174 175

  if (shell == private->shell)
    return;

  if (private->shell)
    {
176 177
      g_object_remove_weak_pointer (G_OBJECT (private->shell),
                                    (gpointer) &private->shell);
178 179 180
      g_signal_handlers_disconnect_by_func (private->shell,
                                            gimp_tool_dialog_shell_unmap,
                                            tool_dialog);
181 182

      gtk_window_set_transient_for (GTK_WINDOW (tool_dialog), NULL);
183 184 185 186 187 188
    }

  private->shell = shell;

  if (private->shell)
    {
189 190 191 192
      GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET (shell));

      gtk_window_set_transient_for (GTK_WINDOW (tool_dialog),
                                    GTK_WINDOW (toplevel));
193 194 195 196

      g_signal_connect_object (private->shell, "unmap",
                               G_CALLBACK (gimp_tool_dialog_shell_unmap),
                               tool_dialog, 0);
197 198
      g_object_add_weak_pointer (G_OBJECT (private->shell),
                                 (gpointer) &private->shell);
199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214
    }
}


/*  private functions  */

static void
gimp_tool_dialog_shell_unmap (GimpDisplayShell *shell,
                              GimpToolDialog   *dialog)
{
  /*  the dialog being mapped while the shell is being unmapped
   *  happens when switching images in GimpImageWindow
   */
  if (gtk_widget_get_mapped (GTK_WIDGET (dialog)))
    g_signal_emit_by_name (dialog, "close");
}