gimpbrushselect.c 7.38 KB
Newer Older
1 2 3 4 5
/* LIBGIMP - The GIMP Library
 * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
 *
 * gimpbrushselect.c
 *
6
 * This library is free software: you can redistribute it and/or
7 8
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
9
 * version 3 of the License, or (at your option) any later version.
10 11 12 13 14 15 16
 *
 * This library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
17
 * License along with this library.  If not, see
18
 * <https://www.gnu.org/licenses/>.
19 20 21 22 23 24 25
 */

#include "config.h"

#include "gimp.h"


26
typedef struct
27 28 29 30 31 32 33 34 35 36 37 38 39
{
  gchar                *brush_callback;
  guint                 idle_id;
  gchar                *brush_name;
  gdouble               opacity;
  gint                  spacing;
  gint                  paint_mode;
  gint                  width;
  gint                  height;
  guchar               *brush_mask_data;
  GimpRunBrushCallback  callback;
  gboolean              closing;
  gpointer              data;
40
  GDestroyNotify        data_destroy;
41
} GimpBrushData;
42 43 44 45


/*  local function prototypes  */

46
static void             gimp_brush_data_free (GimpBrushData        *data);
47

48 49 50 51
static GimpValueArray * gimp_temp_brush_run  (GimpProcedure        *procedure,
                                              const GimpValueArray *args,
                                              gpointer              run_data);
static gboolean         gimp_temp_brush_idle (GimpBrushData        *data);
52 53 54 55 56


/*  public functions  */

const gchar *
57
gimp_brush_select_new (const gchar          *title,
58 59 60
                       const gchar          *brush_name,
                       gdouble               opacity,
                       gint                  spacing,
61
                       GimpLayerMode         paint_mode,
62
                       GimpRunBrushCallback  callback,
63 64
                       gpointer              data,
                       GDestroyNotify        data_destroy)
65
{
66
  GimpPlugIn    *plug_in = gimp_get_plug_in ();
67
  GimpProcedure *procedure;
68
  gchar         *brush_callback;
69 70
  GimpBrushData *brush_data;

71
  brush_callback = gimp_pdb_temp_procedure_name (gimp_get_pdb ());
72

73 74 75 76 77 78 79
  brush_data = g_slice_new0 (GimpBrushData);

  brush_data->brush_callback = brush_callback;
  brush_data->callback       = callback;
  brush_data->data           = data;
  brush_data->data_destroy   = data_destroy;

80 81
  procedure = gimp_procedure_new (plug_in,
                                  brush_callback,
82
                                  GIMP_PDB_PROC_TYPE_TEMPORARY,
83 84 85 86 87
                                  gimp_temp_brush_run,
                                  brush_data,
                                  (GDestroyNotify)
                                  gimp_brush_data_free);

88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 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
  GIMP_PROC_ARG_STRING (procedure, "brush-name",
                        "Brush name",
                        "The brush name",
                        NULL,
                        G_PARAM_READWRITE);

  GIMP_PROC_ARG_DOUBLE (procedure, "opacity",
                        "Opacity",
                        NULL,
                        0.0, 1.0, 1.0,
                        G_PARAM_READWRITE);

  GIMP_PROC_ARG_INT (procedure, "spacing",
                     "Spacing",
                     NULL,
                     -1, 1000, 20,
                     G_PARAM_READWRITE);

  GIMP_PROC_ARG_ENUM (procedure, "paint-mode",
                      "Paint mode",
                      NULL,
                      GIMP_TYPE_LAYER_MODE,
                      GIMP_LAYER_MODE_NORMAL,
                      G_PARAM_READWRITE);

  GIMP_PROC_ARG_INT (procedure, "mask-width",
                     "Brush width",
                     NULL,
                     0, 10000, 0,
                     G_PARAM_READWRITE);

  GIMP_PROC_ARG_INT (procedure, "mask-height",
                     "Brush height",
                     NULL,
                     0, 10000, 0,
                     G_PARAM_READWRITE);

  GIMP_PROC_ARG_INT (procedure, "mask-len",
                     "Mask length",
                     "Length of brush mask data",
                     0, G_MAXINT, 0,
                     G_PARAM_READWRITE);

  GIMP_PROC_ARG_UINT8_ARRAY (procedure, "mask-data",
                             "Mask data",
                             "The brush mask data",
                             G_PARAM_READWRITE);

  GIMP_PROC_ARG_BOOLEAN (procedure, "closing",
                         "Closing",
                         "If the dialog was closing",
                         FALSE,
                         G_PARAM_READWRITE);
141 142 143

  gimp_plug_in_add_temp_procedure (plug_in, procedure);
  g_object_unref (procedure);
144 145 146 147

  if (gimp_brushes_popup (brush_callback, title, brush_name,
                          opacity, spacing, paint_mode))
    {
148
      /* Allow callbacks to be watched */
149
      gimp_plug_in_extension_enable (plug_in);
150 151 152 153

      return brush_callback;
    }

154
  gimp_plug_in_remove_temp_procedure (plug_in, brush_callback);
155 156 157 158 159 160 161

  return NULL;
}

void
gimp_brush_select_destroy (const gchar *brush_callback)
{
162
  GimpPlugIn *plug_in = gimp_get_plug_in ();
163 164 165

  g_return_if_fail (brush_callback != NULL);

166
  gimp_plug_in_remove_temp_procedure (plug_in, brush_callback);
167 168 169 170 171
}


/*  private functions  */

172 173 174
static void
gimp_brush_data_free (GimpBrushData *data)
{
175 176 177 178
  if (data->idle_id)
    g_source_remove (data->idle_id);

  if (data->brush_callback)
179 180 181 182
    {
      gimp_brushes_close_popup (data->brush_callback);
      g_free (data->brush_callback);
    }
183 184 185 186 187 188 189

  g_free (data->brush_name);
  g_free (data->brush_mask_data);

  if (data->data_destroy)
    data->data_destroy (data->data);

190 191 192
  g_slice_free (GimpBrushData, data);
}

193
static GimpValueArray *
194 195 196
gimp_temp_brush_run (GimpProcedure        *procedure,
                     const GimpValueArray *args,
                     gpointer              run_data)
197 198 199 200 201 202
{
  GimpBrushData *data = run_data;

  g_free (data->brush_name);
  g_free (data->brush_mask_data);

203 204 205 206 207 208 209 210
  data->brush_name      = GIMP_VALUES_DUP_STRING      (args, 0);
  data->opacity         = GIMP_VALUES_GET_DOUBLE      (args, 1);
  data->spacing         = GIMP_VALUES_GET_INT         (args, 2);
  data->paint_mode      = GIMP_VALUES_GET_ENUM        (args, 3);
  data->width           = GIMP_VALUES_GET_INT         (args, 4);
  data->height          = GIMP_VALUES_GET_INT         (args, 5);
  data->brush_mask_data = GIMP_VALUES_DUP_UINT8_ARRAY (args, 7);
  data->closing         = GIMP_VALUES_GET_BOOLEAN     (args, 8);
211 212

  if (! data->idle_id)
213
    data->idle_id = g_idle_add ((GSourceFunc) gimp_temp_brush_idle, data);
214 215 216 217

  return gimp_procedure_new_return_values (procedure, GIMP_PDB_SUCCESS, NULL);
}

218
static gboolean
219
gimp_temp_brush_idle (GimpBrushData *data)
220
{
221 222 223 224 225 226 227 228 229 230 231 232 233 234
  data->idle_id = 0;

  if (data->callback)
    data->callback (data->brush_name,
                    data->opacity,
                    data->spacing,
                    data->paint_mode,
                    data->width,
                    data->height,
                    data->brush_mask_data,
                    data->closing,
                    data->data);

  if (data->closing)
235
    {
236
      gchar *brush_callback = data->brush_callback;
237

238
      data->brush_callback = NULL;
239
      gimp_brush_select_destroy (brush_callback);
240
      g_free (brush_callback);
241 242
    }

243
  return G_SOURCE_REMOVE;
244
}