gimptoolbox-color-area.c 9.81 KB
Newer Older
1
/* GIMP - The GNU Image Manipulation Program
Elliot Lee's avatar
Elliot Lee committed
2 3
 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
 *
4
 * This program is free software: you can redistribute it and/or modify
Elliot Lee's avatar
Elliot Lee committed
5
 * it under the terms of the GNU General Public License as published by
6
 * the Free Software Foundation; either version 3 of the License, or
Elliot Lee's avatar
Elliot Lee committed
7 8 9 10 11 12 13 14
 * (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
15
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
Elliot Lee's avatar
Elliot Lee committed
16
 */
17

Sven Neumann's avatar
Sven Neumann committed
18 19
#include "config.h"

20
#include <gegl.h>
Sven Neumann's avatar
Sven Neumann committed
21 22
#include <gtk/gtk.h>

23
#include "libgimpwidgets/gimpwidgets.h"
24

25
#include "widgets-types.h"
Sven Neumann's avatar
Sven Neumann committed
26

27 28
#include "config/gimpguiconfig.h"

29
#include "core/gimp.h"
30 31
#include "core/gimpcontext.h"

32
#include "gimpcolordialog.h"
33
#include "gimpdialogfactory.h"
34
#include "gimpfgbgeditor.h"
35
#include "gimpsessioninfo.h"
36 37
#include "gimptoolbox.h"
#include "gimptoolbox-color-area.h"
38

39
#include "gimp-intl.h"
40 41


42
/*  local function prototypes  */
Michael Natterer's avatar
Michael Natterer committed
43

44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
static void   color_area_foreground_changed (GimpContext          *context,
                                             const GimpRGB        *color,
                                             GimpColorDialog      *dialog);
static void   color_area_background_changed (GimpContext          *context,
                                             const GimpRGB        *color,
                                             GimpColorDialog      *dialog);

static void   color_area_dialog_update      (GimpColorDialog      *dialog,
                                             const GimpRGB        *color,
                                             GimpColorDialogState  state,
                                             GimpContext          *context);

static void   color_area_color_clicked      (GimpFgBgEditor       *editor,
                                             GimpActiveColor       active_color,
                                             GimpContext          *context);
Michael Natterer's avatar
Michael Natterer committed
59

Elliot Lee's avatar
Elliot Lee committed
60

61 62
/*  local variables  */

63 64
static GtkWidget       *color_area          = NULL;
static GtkWidget       *color_dialog        = NULL;
65
static gboolean         color_dialog_active = FALSE;
66
static GimpActiveColor  edit_color          = GIMP_ACTIVE_COLOR_FOREGROUND;
67 68
static GimpRGB          revert_fg;
static GimpRGB          revert_bg;
69

Elliot Lee's avatar
Elliot Lee committed
70

Michael Natterer's avatar
Michael Natterer committed
71 72 73
/*  public functions  */

GtkWidget *
74 75
gimp_toolbox_color_area_create (GimpToolbox *toolbox,
                                gint         width,
76
                                gint         height)
Michael Natterer's avatar
Michael Natterer committed
77
{
78 79 80 81
  GimpContext *context;

  g_return_val_if_fail (GIMP_IS_TOOLBOX (toolbox), NULL);

82
  context = gimp_toolbox_get_context (toolbox);
Michael Natterer's avatar
Michael Natterer committed
83

84
  color_area = gimp_fg_bg_editor_new (context);
85
  gtk_widget_set_size_request (color_area, width, height);
86
  gtk_widget_add_events (color_area,
87
                         GDK_ENTER_NOTIFY_MASK |
88
                         GDK_LEAVE_NOTIFY_MASK);
Michael Natterer's avatar
Michael Natterer committed
89

90
  gimp_help_set_help_data
91
    (color_area, _("Foreground & background colors.\n"
92 93 94 95
                   "The black and white squares reset colors.\n"
                   "The arrows swap colors.\n"
                   "Click to open the color selection dialog."), NULL);

96
  g_signal_connect (color_area, "color-clicked",
97 98
                    G_CALLBACK (color_area_color_clicked),
                    context);
Michael Natterer's avatar
Michael Natterer committed
99 100 101 102 103 104 105

  return color_area;
}


/*  private functions  */

106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
static void
color_area_foreground_changed (GimpContext     *context,
                               const GimpRGB   *color,
                               GimpColorDialog *dialog)
{
  if (edit_color == GIMP_ACTIVE_COLOR_FOREGROUND)
    {
      g_signal_handlers_block_by_func (dialog,
                                       color_area_dialog_update,
                                       context);

      /* FIXME this should use GimpColorDialog API */
      gimp_color_selection_set_color (GIMP_COLOR_SELECTION (dialog->selection),
                                      color);

      g_signal_handlers_unblock_by_func (dialog,
                                         color_area_dialog_update,
                                         context);
    }
}

static void
color_area_background_changed (GimpContext     *context,
                               const GimpRGB   *color,
                               GimpColorDialog *dialog)
{
  if (edit_color == GIMP_ACTIVE_COLOR_BACKGROUND)
    {
      g_signal_handlers_block_by_func (dialog,
                                       color_area_dialog_update,
                                       context);

      /* FIXME this should use GimpColorDialog API */
      gimp_color_selection_set_color (GIMP_COLOR_SELECTION (dialog->selection),
                                      color);

      g_signal_handlers_unblock_by_func (dialog,
                                         color_area_dialog_update,
                                         context);
    }
}

Elliot Lee's avatar
Elliot Lee committed
148
static void
149 150 151 152
color_area_dialog_update (GimpColorDialog      *dialog,
                          const GimpRGB        *color,
                          GimpColorDialogState  state,
                          GimpContext          *context)
Elliot Lee's avatar
Elliot Lee committed
153
{
154
  switch (state)
Elliot Lee's avatar
Elliot Lee committed
155
    {
156 157 158 159 160 161 162
    case GIMP_COLOR_DIALOG_OK:
      gtk_widget_hide (color_dialog);
      color_dialog_active = FALSE;
      /* Fallthrough */

    case GIMP_COLOR_DIALOG_UPDATE:
      if (edit_color == GIMP_ACTIVE_COLOR_FOREGROUND)
163 164 165 166 167 168 169 170 171 172 173
        {
          g_signal_handlers_block_by_func (context,
                                           color_area_foreground_changed,
                                           dialog);

          gimp_context_set_foreground (context, color);

          g_signal_handlers_unblock_by_func (context,
                                             color_area_foreground_changed,
                                             dialog);
        }
174
      else
175 176 177 178 179 180 181 182 183 184 185
        {
          g_signal_handlers_block_by_func (context,
                                           color_area_foreground_changed,
                                           dialog);

          gimp_context_set_background (context, color);

          g_signal_handlers_unblock_by_func (context,
                                             color_area_foreground_changed,
                                             dialog);
        }
186 187 188 189 190 191 192 193
      break;

    case GIMP_COLOR_DIALOG_CANCEL:
      gtk_widget_hide (color_dialog);
      color_dialog_active = FALSE;
      gimp_context_set_foreground (context, &revert_fg);
      gimp_context_set_background (context, &revert_bg);
      break;
Elliot Lee's avatar
Elliot Lee committed
194 195 196 197
    }
}

static void
198 199 200
color_area_color_clicked (GimpFgBgEditor  *editor,
                          GimpActiveColor  active_color,
                          GimpContext     *context)
Elliot Lee's avatar
Elliot Lee committed
201
{
202 203
  GimpRGB      color;
  const gchar *title;
204

205
  if (! color_dialog_active)
Elliot Lee's avatar
Elliot Lee committed
206
    {
Michael Natterer's avatar
Michael Natterer committed
207 208
      gimp_context_get_foreground (context, &revert_fg);
      gimp_context_get_background (context, &revert_bg);
Elliot Lee's avatar
Elliot Lee committed
209
    }
210

211 212 213 214 215
  if (active_color == GIMP_ACTIVE_COLOR_FOREGROUND)
    {
      gimp_context_get_foreground (context, &color);
      title = _("Change Foreground Color");
    }
Elliot Lee's avatar
Elliot Lee committed
216
  else
217 218 219 220
    {
      gimp_context_get_background (context, &color);
      title = _("Change Background Color");
    }
221

222
  edit_color = active_color;
Elliot Lee's avatar
Elliot Lee committed
223

224
  if (! color_dialog)
Elliot Lee's avatar
Elliot Lee committed
225
    {
226 227
      color_dialog = gimp_color_dialog_new (NULL, context,
                                            NULL, NULL, NULL,
228
                                            GTK_WIDGET (editor),
229
                                            gimp_dialog_factory_get_singleton (),
230
                                            "gimp-toolbox-color-dialog",
231
                                            &color,
232 233
                                            TRUE, FALSE);

234 235 236 237 238 239 240 241 242 243
      g_signal_connect_object (color_dialog, "update",
                               G_CALLBACK (color_area_dialog_update),
                               G_OBJECT (context), 0);

      g_signal_connect_object (context, "foreground-changed",
                               G_CALLBACK (color_area_foreground_changed),
                               G_OBJECT (color_dialog), 0);
      g_signal_connect_object (context, "background-changed",
                               G_CALLBACK (color_area_background_changed),
                               G_OBJECT (color_dialog), 0);
Elliot Lee's avatar
Elliot Lee committed
244
    }
245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276
  else if (! gtk_widget_get_visible (color_dialog))
    {
      /*  See https://gitlab.gnome.org/GNOME/gimp/issues/1093
       *
       *  We correctly position all newly created dialog via
       *  gimp_dialog_factory_add_dialog(), but the color dialog is
       *  special, it's never destroyed but created only once per
       *  session. On re-showing, whatever window managing magic kicks
       *  in and the dialog sometimes goes where it shouldn't.
       *
       *  The code below belongs into GimpDialogFactory, perhaps a new
       *  function gimp_dialog_factory_position_dialog() and does the
       *  same positioning logic as add_dialog().
       */
      GimpDialogFactory *dialog_factory = gimp_dialog_factory_get_singleton ();
      GimpSessionInfo   *info;

      info = gimp_dialog_factory_find_session_info (dialog_factory,
                                                    "gimp-toolbox-color-dialog");

      if (gimp_session_info_get_widget (info) == color_dialog)
        {
          GdkMonitor    *monitor = gimp_widget_get_monitor (GTK_WIDGET (editor));
          GimpGuiConfig *gui_config;

          gui_config = GIMP_GUI_CONFIG (context->gimp->config);

          gimp_session_info_apply_geometry (info,
                                            monitor,
                                            gui_config->restore_monitor);
        }
    }
277

278 279 280 281 282
  gtk_window_set_title (GTK_WINDOW (color_dialog), title);
  gimp_color_dialog_set_color (GIMP_COLOR_DIALOG (color_dialog), &color);

  gtk_window_present (GTK_WINDOW (color_dialog));
  color_dialog_active = TRUE;
Elliot Lee's avatar
Elliot Lee committed
283
}