~ubuntu-branches/ubuntu/hoary/gimp/hoary

« back to all changes in this revision

Viewing changes to plug-ins/winicon/icodialog.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher
  • Date: 2005-04-04 14:51:23 UTC
  • Revision ID: james.westby@ubuntu.com-20050404145123-9py049eeelfymur8
Tags: upstream-2.2.2
ImportĀ upstreamĀ versionĀ 2.2.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* The GIMP -- an image manipulation program
 
2
 * Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
 
3
 *
 
4
 * GIMP Plug-in for Windows Icon files.
 
5
 * Copyright (C) 2002 Christian Kreibich <christian@whoop.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 2 of the License, or
 
10
 * (at your option) any later version.
 
11
 *
 
12
 * This program is distributed in the hope that it will be useful,
 
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
 * GNU General Public License for more details.
 
16
 *
 
17
 * You should have received a copy of the GNU General Public License
 
18
 * along with this program; if not, write to the Free Software
 
19
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
20
 */
 
21
 
 
22
#include <config.h>
 
23
 
 
24
#include <stdio.h>
 
25
 
 
26
#include <libgimp/gimp.h>
 
27
#include <libgimp/gimpui.h>
 
28
 
 
29
#define ICO_DBG
 
30
 
 
31
#include "icodialog.h"
 
32
#include "main.h"
 
33
 
 
34
#include "libgimp/stdplugins-intl.h"
 
35
 
 
36
 
 
37
static GtkWidget *ico_preview_new             (gint32     layer);
 
38
static void       ico_fill_preview_with_thumb (GtkWidget *widget,
 
39
                                               gint32     drawable_ID);
 
40
static void       combo_bpp_changed           (GtkWidget *combo,
 
41
                                               GObject   *hbox);
 
42
 
 
43
 
 
44
static GtkWidget *
 
45
ico_preview_new (gint32 layer)
 
46
{
 
47
  GtkWidget *icon_preview;
 
48
 
 
49
  icon_preview = gimp_preview_area_new ();
 
50
  ico_fill_preview_with_thumb (icon_preview, layer);
 
51
 
 
52
  return icon_preview;
 
53
}
 
54
 
 
55
 
 
56
static void
 
57
ico_fill_preview_with_thumb (GtkWidget *widget,
 
58
                             gint32     drawable_ID)
 
59
{
 
60
  guchar *drawable_data;
 
61
  gint    bpp;
 
62
  gint    width;
 
63
  gint    height;
 
64
 
 
65
  width  = gimp_drawable_width (drawable_ID);
 
66
  height = gimp_drawable_height (drawable_ID);
 
67
  bpp    = 0; /* Only returned */
 
68
 
 
69
  if (width > 128)
 
70
    width = 128;
 
71
  if (height > 128)
 
72
    height = 128;
 
73
 
 
74
  drawable_data =
 
75
    gimp_drawable_get_thumbnail_data (drawable_ID, &width, &height, &bpp);
 
76
 
 
77
  if (width < 1 || height < 1)
 
78
    return;
 
79
 
 
80
  gtk_widget_set_size_request (widget, width, height);
 
81
  GIMP_PREVIEW_AREA (widget)->width = width;
 
82
  GIMP_PREVIEW_AREA (widget)->height = height;
 
83
 
 
84
  gimp_preview_area_draw (GIMP_PREVIEW_AREA (widget),
 
85
                          0, 0, width, height,
 
86
                          gimp_drawable_type (drawable_ID),
 
87
                          drawable_data,
 
88
                          bpp * width);
 
89
 
 
90
  g_free (drawable_data);
 
91
}
 
92
 
 
93
 
 
94
/* This function creates and returns an hbox for an icon,
 
95
   which then gets added to the dialog's main vbox. */
 
96
static GtkWidget *
 
97
ico_create_icon_hbox (GtkWidget *icon_preview,
 
98
                      gint32     layer,
 
99
                      gint       layer_num)
 
100
{
 
101
  GtkWidget *hbox;
 
102
  GtkWidget *alignment;
 
103
  GtkWidget *combo;
 
104
 
 
105
  hbox = gtk_hbox_new (FALSE, 6);
 
106
 
 
107
  alignment = gtk_alignment_new (0.5, 0.5, 0, 0);
 
108
  gtk_box_pack_start (GTK_BOX (hbox), alignment, FALSE, FALSE, 0);
 
109
  gtk_widget_show (alignment);
 
110
 
 
111
  /* To make life easier for the callbacks, we store the
 
112
     layer's ID and stacking number with the hbox. */
 
113
 
 
114
  g_object_set_data (G_OBJECT (hbox),
 
115
                     "icon_layer", GINT_TO_POINTER (layer));
 
116
  g_object_set_data (G_OBJECT (hbox),
 
117
                     "icon_layer_num", GINT_TO_POINTER (layer_num));
 
118
 
 
119
  g_object_set_data (G_OBJECT (hbox), "icon_preview", icon_preview);
 
120
  gtk_container_add (GTK_CONTAINER (alignment), icon_preview);
 
121
  gtk_widget_show (icon_preview);
 
122
 
 
123
  combo = gimp_int_combo_box_new (_("1 bpp, 1-bit alpha, 2-slot palette"),   1,
 
124
                                  _("4 bpp, 1-bit alpha, 16-slot palette"),  4,
 
125
                                  _("8 bpp, 1-bit alpha, 256-slot palette"), 8,
 
126
                                  _("32 bpp, 8-bit alpha, no palette"),      32,
 
127
                                  NULL);
 
128
  gimp_int_combo_box_set_active (GIMP_INT_COMBO_BOX (combo), 32);
 
129
 
 
130
  g_signal_connect (combo, "changed",
 
131
                    G_CALLBACK (combo_bpp_changed),
 
132
                    hbox);
 
133
 
 
134
  g_object_set_data (G_OBJECT (hbox), "icon_menu", combo);
 
135
  gtk_box_pack_start (GTK_BOX (hbox), combo, TRUE, TRUE, 0);
 
136
  gtk_widget_show (combo);
 
137
 
 
138
  return hbox;
 
139
}
 
140
 
 
141
 
 
142
GtkWidget *
 
143
ico_specs_dialog_new (gint num_layers)
 
144
{
 
145
  GtkWidget *dialog;
 
146
  GtkWidget *vbox;
 
147
  GtkWidget *frame;
 
148
  GtkWidget *scrolledwindow;
 
149
  gint      *icon_depths, i;
 
150
 
 
151
  dialog = gimp_dialog_new (_("GIMP Windows Icon Plugin"), "winicon",
 
152
                             NULL, 0,
 
153
                             gimp_standard_help_func, "plug-in-winicon",
 
154
                             GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
 
155
                             GTK_STOCK_OK,     GTK_RESPONSE_OK,
 
156
                             NULL);
 
157
 
 
158
  /* We store an array that holds each icon's requested bit depth
 
159
     with the dialog. It's queried when the dialog is closed so the
 
160
     save routine knows what colormaps etc to generate in the saved
 
161
     file. We store twice the number necessary because in the second
 
162
     set, the color depths that are automatically suggested are stored
 
163
     for later comparison.
 
164
  */
 
165
 
 
166
  icon_depths = g_new (gint, 2 * num_layers);
 
167
  for (i = 0; i < 2 * num_layers; i++)
 
168
    icon_depths[i] = 32;
 
169
 
 
170
  g_object_set_data (G_OBJECT (dialog), "icon_depths", icon_depths);
 
171
 
 
172
  frame = gimp_frame_new (_("Icon details"));
 
173
  gtk_container_set_border_width (GTK_CONTAINER (frame), 12);
 
174
  gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), frame,
 
175
                      TRUE, TRUE, 0);
 
176
  gtk_widget_show (frame);
 
177
 
 
178
  scrolledwindow = gtk_scrolled_window_new (NULL, NULL);
 
179
  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow),
 
180
                                  GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
 
181
  gtk_container_add (GTK_CONTAINER (frame), scrolledwindow);
 
182
  gtk_widget_show (scrolledwindow);
 
183
 
 
184
  vbox = gtk_vbox_new (FALSE, 6);
 
185
  gtk_container_set_border_width (GTK_CONTAINER (vbox), 6);
 
186
  g_object_set_data (G_OBJECT (dialog), "icons_vbox", vbox);
 
187
  gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolledwindow),
 
188
                                         vbox);
 
189
  gtk_widget_show (vbox);
 
190
 
 
191
  return dialog;
 
192
}
 
193
 
 
194
static GtkWidget *
 
195
ico_specs_dialog_get_layer_preview (GtkWidget *dialog,
 
196
                                    gint32     layer)
 
197
{
 
198
  GtkWidget *preview;
 
199
  GtkWidget *icon_hbox;
 
200
  gchar      key[MAXLEN];
 
201
 
 
202
  g_snprintf (key, MAXLEN, "layer_%i_hbox", layer);
 
203
  icon_hbox = g_object_get_data (G_OBJECT (dialog), key);
 
204
 
 
205
  if (!icon_hbox)
 
206
    {
 
207
      D(("Something's wrong -- couldn't look up hbox by layer ID\n"));
 
208
      return NULL;
 
209
    }
 
210
 
 
211
  preview = g_object_get_data (G_OBJECT (icon_hbox), "icon_preview");
 
212
 
 
213
  if (!icon_hbox)
 
214
    {
 
215
      D(("Something's wrong -- couldn't look up preview from hbox\n"));
 
216
      return NULL;
 
217
    }
 
218
 
 
219
  return preview;
 
220
}
 
221
 
 
222
 
 
223
void
 
224
ico_specs_dialog_add_icon (GtkWidget *dialog,
 
225
                           gint32     layer,
 
226
                           gint       layer_num)
 
227
{
 
228
  GtkWidget *vbox;
 
229
  GtkWidget *hbox;
 
230
  GtkWidget *preview;
 
231
  gchar      key[MAXLEN];
 
232
 
 
233
  vbox = g_object_get_data (G_OBJECT (dialog), "icons_vbox");
 
234
 
 
235
  preview = ico_preview_new (layer);
 
236
  hbox = ico_create_icon_hbox (preview, layer, layer_num);
 
237
  gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
 
238
  gtk_widget_show (hbox);
 
239
 
 
240
  /* Let's make the hbox accessible through the layer ID */
 
241
  g_snprintf (key, MAXLEN, "layer_%i_hbox", layer);
 
242
  g_object_set_data (G_OBJECT (dialog), key, hbox);
 
243
}
 
244
 
 
245
 
 
246
void
 
247
ico_specs_dialog_update_icon_preview (GtkWidget *dialog,
 
248
                                      gint32     layer,
 
249
                                      gint       bpp)
 
250
{
 
251
  GtkWidget    *preview;
 
252
  GimpPixelRgn  src_pixel_rgn, dst_pixel_rgn;
 
253
  gint32        tmp_image;
 
254
  gint32        tmp_layer;
 
255
  gint          w, h;
 
256
  guchar       *buffer;
 
257
  gboolean      result;
 
258
  GimpDrawable *drawable = gimp_drawable_get (layer);
 
259
  GimpDrawable *tmp;
 
260
 
 
261
  tmp_image = gimp_image_new (gimp_drawable_width (layer),
 
262
                              gimp_drawable_height (layer),
 
263
                              GIMP_RGB);
 
264
 
 
265
  w = gimp_drawable_width (layer);
 
266
  h = gimp_drawable_height (layer);
 
267
 
 
268
  tmp_layer = gimp_layer_new (tmp_image, "temporary", w, h,
 
269
                              GIMP_RGBA_IMAGE, 100, GIMP_NORMAL_MODE);
 
270
  gimp_image_add_layer (tmp_image, tmp_layer, 0);
 
271
 
 
272
  tmp = gimp_drawable_get (tmp_layer);
 
273
 
 
274
  gimp_pixel_rgn_init (&src_pixel_rgn, drawable, 0, 0, w, h, FALSE, FALSE);
 
275
  gimp_pixel_rgn_init (&dst_pixel_rgn, tmp,      0, 0, w, h, TRUE, FALSE);
 
276
 
 
277
  buffer = g_malloc (w * h * 4);
 
278
  gimp_pixel_rgn_get_rect (&src_pixel_rgn, buffer, 0, 0, w, h);
 
279
  gimp_pixel_rgn_set_rect (&dst_pixel_rgn, buffer, 0, 0, w, h);
 
280
 
 
281
  gimp_drawable_detach (tmp);
 
282
  gimp_drawable_detach (drawable);
 
283
 
 
284
  if (bpp < 32)
 
285
    {
 
286
      result = gimp_image_convert_indexed (tmp_image,
 
287
                                           GIMP_FS_DITHER,
 
288
                                           GIMP_MAKE_PALETTE,
 
289
                                           1 << bpp,
 
290
                                           TRUE,
 
291
                                           FALSE,
 
292
                                           "dummy");
 
293
    }
 
294
 
 
295
  gimp_image_delete (tmp_image);
 
296
 
 
297
  preview = ico_specs_dialog_get_layer_preview (dialog, layer);
 
298
  ico_fill_preview_with_thumb (preview, tmp_layer);
 
299
  gtk_widget_queue_draw (preview);
 
300
 
 
301
  g_free (buffer);
 
302
}
 
303
 
 
304
static void
 
305
combo_bpp_changed (GtkWidget *combo,
 
306
                   GObject   *hbox)
 
307
{
 
308
  GtkWidget *dialog = gtk_widget_get_toplevel (combo);
 
309
  gint32     layer;
 
310
  gint       layer_num;
 
311
  gint       bpp;
 
312
  gint      *icon_depths;
 
313
 
 
314
  gimp_int_combo_box_get_active (GIMP_INT_COMBO_BOX (combo), &bpp);
 
315
 
 
316
  icon_depths = g_object_get_data (G_OBJECT (dialog), "icon_depths");
 
317
  if (! icon_depths)
 
318
    {
 
319
      D(("Something's wrong -- can't get icon_depths array from dialog\n"));
 
320
      return;
 
321
    }
 
322
 
 
323
  layer     = GPOINTER_TO_INT (g_object_get_data (hbox, "icon_layer"));
 
324
  layer_num = GPOINTER_TO_INT (g_object_get_data (hbox, "icon_layer_num"));
 
325
 
 
326
  /* Update vector entry for later when we're actually saving,
 
327
     and update the preview right away ... */
 
328
  icon_depths[layer_num] = bpp;
 
329
  ico_specs_dialog_update_icon_preview (dialog, layer, bpp);
 
330
}