info-dialog.c 11.8 KB
Newer Older
Elliot Lee's avatar
Elliot Lee committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/* The GIMP -- an image manipulation program
 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (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
 * along with this program; if not, write to the Free Software
16
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Elliot Lee's avatar
Elliot Lee committed
17
 */
18
19
#include "config.h"

Elliot Lee's avatar
Elliot Lee committed
20
21
22
23
24
#include <string.h>
#include "appenv.h"
#include "gimprc.h"
#include "info_dialog.h"
#include "interface.h"
25
#include "session.h"
Elliot Lee's avatar
Elliot Lee committed
26

27
#include "libgimp/gimpintl.h"
28
#include "libgimp/gimpsizeentry.h"
29

Elliot Lee's avatar
Elliot Lee committed
30
/*  static functions  */
31
32
33
34
static void info_field_new (InfoDialog *, InfoFieldType, char *, GtkWidget *,
			    GtkObject *, void *, GtkSignalFunc, gpointer);
static void update_field   (InfoField *);
static gint info_dialog_delete_callback (GtkWidget *, GdkEvent *, gpointer);
Elliot Lee's avatar
Elliot Lee committed
35

36
static void
37
info_field_new (InfoDialog    *idialog,
38
		InfoFieldType  field_type,
39
		gchar         *title,
40
41
42
		GtkWidget     *widget,
		GtkObject     *obj,
		void          *value_ptr,
43
44
		GtkSignalFunc  callback,
		gpointer       client_data)
Elliot Lee's avatar
Elliot Lee committed
45
46
47
{
  GtkWidget *label;
  InfoField *field;
48
  gint       row;
Elliot Lee's avatar
Elliot Lee committed
49

50
  field = g_new (InfoField, 1);
Elliot Lee's avatar
Elliot Lee committed
51

52
53
54
  row = idialog->nfields + 1;
  gtk_table_resize (GTK_TABLE (idialog->info_table), 2, row);

55
  label = gtk_label_new (title);
56
  gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
57
  gtk_table_attach (GTK_TABLE (idialog->info_table), label,
Michael Natterer's avatar
Michael Natterer committed
58
59
		    0, 1, row - 1, row,
		    GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
60
  gtk_widget_show (label);
Elliot Lee's avatar
Elliot Lee committed
61

62
  gtk_table_attach_defaults (GTK_TABLE (idialog->info_table), widget,
63
			     1, 2, row - 1, row);
64
  gtk_widget_show (widget);
Elliot Lee's avatar
Elliot Lee committed
65

66
67
  gtk_table_set_col_spacing (GTK_TABLE (idialog->info_table), 0, 6);
  gtk_table_set_row_spacings (GTK_TABLE (idialog->info_table), 2);
Elliot Lee's avatar
Elliot Lee committed
68

69
70
71
72
73
74
  field->field_type = field_type;
  if (obj == NULL)
    field->obj = GTK_OBJECT (widget);
  else
    field->obj = obj;
  field->value_ptr = value_ptr;
75
76
77
  field->callback = callback;
  field->client_data = client_data;

78
79
80
  idialog->field_list =
    g_slist_prepend (idialog->field_list, (void *) field);
  idialog->nfields++;
Elliot Lee's avatar
Elliot Lee committed
81
82
83
84
85
86
}

static void
update_field (InfoField *field)
{
  gchar *old_text;
87
88
  gint   num;
  gint   i;
Elliot Lee's avatar
Elliot Lee committed
89

90
91
  if (field->value_ptr == NULL)
    return;
Elliot Lee's avatar
Elliot Lee committed
92

93
94
95
96
  if (field->field_type != INFO_LABEL)
    gtk_signal_handler_block_by_data (GTK_OBJECT (field->obj),
				      field->client_data);

97
  switch (field->field_type)
Elliot Lee's avatar
Elliot Lee committed
98
    {
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
    case INFO_LABEL:
      gtk_label_get (GTK_LABEL (field->obj), &old_text);
      if (strcmp (old_text, (gchar*) field->value_ptr))
	gtk_label_set_text (GTK_LABEL (field->obj), (gchar*) field->value_ptr);
      break;

    case INFO_ENTRY:
      old_text = gtk_entry_get_text (GTK_ENTRY (field->obj));
      if (strcmp (old_text, (gchar*) field->value_ptr))
	gtk_entry_set_text (GTK_ENTRY (field->obj), (gchar*) field->value_ptr);
      break;

    case INFO_SCALE:
    case INFO_SPINBUTTON:
      gtk_adjustment_set_value (GTK_ADJUSTMENT (field->obj),
114
				*((gdouble*) field->value_ptr));
115
116
117
118
      break;

    case INFO_SIZEENTRY:
      num = GIMP_SIZE_ENTRY (field->obj)->number_of_fields;
119
      for (i = 0; i < num; i++)
120
	gimp_size_entry_set_refval (GIMP_SIZE_ENTRY (field->obj), i,
121
				    ((gdouble*) field->value_ptr)[i]);
122
123
124
      break;

    default:
125
      g_warning ("Unknown info_dialog field type.");
126
      break;
Elliot Lee's avatar
Elliot Lee committed
127
    }
128
129
130
131

  if (field->field_type != INFO_LABEL)
    gtk_signal_handler_unblock_by_data (GTK_OBJECT (field->obj),
					field->client_data);
Elliot Lee's avatar
Elliot Lee committed
132
133
}

134
static gint
135
136
137
info_dialog_delete_callback (GtkWidget *widget,
			     GdkEvent  *event,
			     gpointer   data)
138
{
139
  info_dialog_popdown ((InfoDialog *) data);
140
141
142
143

  return TRUE;
}

144
static InfoDialog *
145
146
147
148
info_dialog_new_extended (gchar        *title,
			  GimpHelpFunc  help_func,
			  gpointer      help_data,
			  gboolean      in_notebook)
Elliot Lee's avatar
Elliot Lee committed
149
{
150
151
152
153
  InfoDialog *idialog;
  GtkWidget  *shell;
  GtkWidget  *vbox;
  GtkWidget  *info_table;
154
  GtkWidget  *info_notebook;
Elliot Lee's avatar
Elliot Lee committed
155

156
  idialog = g_new (InfoDialog, 1);
Elliot Lee's avatar
Elliot Lee committed
157
  idialog->field_list = NULL;
158
  idialog->nfields    = 0;
Elliot Lee's avatar
Elliot Lee committed
159
160

  shell = gtk_dialog_new ();
161
  gtk_window_set_wmclass (GTK_WINDOW (shell), "info_dialog", "Gimp");
162
  gtk_window_set_title (GTK_WINDOW (shell), title);
163
  session_set_window_geometry (shell, &info_dialog_session_info, FALSE );
Elliot Lee's avatar
Elliot Lee committed
164
165
166
167
168

  gtk_signal_connect (GTK_OBJECT (shell), "delete_event",
		      GTK_SIGNAL_FUNC (info_dialog_delete_callback),
		      idialog);

169
170
  vbox = gtk_vbox_new (FALSE, 0);
  gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
171
  gtk_container_add (GTK_CONTAINER (GTK_DIALOG (shell)->vbox), vbox);
Elliot Lee's avatar
Elliot Lee committed
172

173
  info_table = gtk_table_new (2, 0, FALSE);
174

175
  if (in_notebook)
176
    {
177
178
179
180
181
      info_notebook = gtk_notebook_new ();
      gtk_notebook_append_page (GTK_NOTEBOOK (info_notebook),
				info_table,
				gtk_label_new (_("General")));
      gtk_box_pack_start (GTK_BOX (vbox), info_notebook, FALSE, FALSE, 0);
182
183
184
185
    }
  else
    {
      info_notebook = NULL;
186
      gtk_box_pack_start (GTK_BOX (vbox), info_table, FALSE, FALSE, 0);
187
    }
Elliot Lee's avatar
Elliot Lee committed
188
189
190

  idialog->shell = shell;
  idialog->vbox = vbox;
191
  idialog->info_table = info_table;
192
  idialog->info_notebook = info_notebook;
193
194

  if (in_notebook)
195
    gtk_widget_show (idialog->info_notebook);
Elliot Lee's avatar
Elliot Lee committed
196

197
  gtk_widget_show (idialog->info_table);
Elliot Lee's avatar
Elliot Lee committed
198
199
  gtk_widget_show (idialog->vbox);

200
201
202
  /*  Connect the "F1" help key  */
  gimp_help_connect_help_accel (idialog->shell, help_func, help_data);

Elliot Lee's avatar
Elliot Lee committed
203
204
205
  return idialog;
}

206
207
208
/*  public functions  */

InfoDialog *
209
210
211
info_dialog_notebook_new (gchar        *title,
			  GimpHelpFunc  help_func,
			  gpointer      help_data)
212
{
213
  return info_dialog_new_extended (title, help_func, help_data, TRUE);
214
215
216
}

InfoDialog *
217
218
219
info_dialog_new (gchar        *title,
		 GimpHelpFunc  help_func,
		 gpointer      help_data)
220
{
221
  return info_dialog_new_extended (title, help_func, help_data, FALSE);
222
223
}

Elliot Lee's avatar
Elliot Lee committed
224
225
226
void
info_dialog_free (InfoDialog *idialog)
{
227
  GSList *list;
Elliot Lee's avatar
Elliot Lee committed
228

229
  g_return_if_fail (idialog != NULL);
Elliot Lee's avatar
Elliot Lee committed
230
231

  /*  Free each item in the field list  */
232
233
  for (list = idialog->field_list; list; list = g_slist_next (list))
    g_free (list->data);
Elliot Lee's avatar
Elliot Lee committed
234
235

  /*  Free the actual field linked list  */
236
  g_slist_free (idialog->field_list);
Elliot Lee's avatar
Elliot Lee committed
237

238
  session_get_window_info (idialog->shell, &info_dialog_session_info);
239

Elliot Lee's avatar
Elliot Lee committed
240
241
242
243
244
245
246
  /*  Destroy the associated widgets  */
  gtk_widget_destroy (idialog->shell);

  /*  Free the info dialog memory  */
  g_free (idialog);
}

247
248
249
void
info_dialog_popup (InfoDialog *idialog)
{
250
  if (! idialog)
251
252
    return;

253
  if (! GTK_WIDGET_VISIBLE (idialog->shell))
254
255
256
257
258
259
260
    gtk_widget_show (idialog->shell);

}

void
info_dialog_popdown (InfoDialog *idialog)
{
261
  if (! idialog)
262
263
264
265
266
267
268
269
270
271
272
    return;
  
  if (GTK_WIDGET_VISIBLE (idialog->shell))
    gtk_widget_hide (idialog->shell);
}

void
info_dialog_update (InfoDialog *idialog)
{
  GSList *list;

273
  if (! idialog)
274
275
    return;

276
277
  for (list = idialog->field_list; list; list = g_slist_next (list))
    update_field ((InfoField *) list->data);
278
279
}

280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
GtkWidget *
info_dialog_add_label (InfoDialog    *idialog,
		       char          *title,
		       char          *text_ptr)
{
  GtkWidget *label;

  g_return_val_if_fail (idialog != NULL, NULL);

  label = gtk_label_new (text_ptr);
  gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);

  info_field_new (idialog, INFO_LABEL, title, label, NULL, (void*) text_ptr,
		  NULL, NULL);

  return label;
}

GtkWidget *
info_dialog_add_entry (InfoDialog    *idialog,
300
301
302
303
		       char          *title,
		       char          *text_ptr,
		       GtkSignalFunc  callback,
		       gpointer       data)
Elliot Lee's avatar
Elliot Lee committed
304
{
305
  GtkWidget *entry;
Elliot Lee's avatar
Elliot Lee committed
306

307
  g_return_val_if_fail (idialog != NULL, NULL);
Elliot Lee's avatar
Elliot Lee committed
308

309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
  entry = gtk_entry_new ();
  gtk_widget_set_usize (entry, 50, 0);
  gtk_entry_set_text (GTK_ENTRY (entry), text_ptr ? text_ptr : "");

  if (callback)
    gtk_signal_connect (GTK_OBJECT (entry), "changed",
			GTK_SIGNAL_FUNC (callback), data);

  info_field_new (idialog, INFO_ENTRY, title, entry, NULL, (void*) text_ptr,
		  callback, data);

  return entry;
}

GtkWidget *
info_dialog_add_scale   (InfoDialog    *idialog,
325
326
			 gchar         *title,
			 gdouble       *value_ptr,
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
			 gfloat         lower,
			 gfloat         upper,
			 gfloat         step_increment,
			 gfloat         page_increment,
			 gfloat         page_size,
			 gint           digits,
			 GtkSignalFunc  callback,
			 gpointer       data)
{
  GtkObject *adjustment;
  GtkWidget *scale;

  g_return_val_if_fail (idialog != NULL, NULL);

  adjustment = gtk_adjustment_new (value_ptr ? *value_ptr : 0, lower, upper,
				   step_increment, page_increment, page_size);
  scale = gtk_hscale_new (GTK_ADJUSTMENT (adjustment));

  if (digits >= 0)
    gtk_scale_set_digits (GTK_SCALE (scale), MAX (digits, 6));
  else
    gtk_scale_set_draw_value (GTK_SCALE (scale), FALSE);

  if (callback)
    gtk_signal_connect (GTK_OBJECT (adjustment), "value_changed",
			GTK_SIGNAL_FUNC (callback), data);

  info_field_new (idialog, INFO_SCALE, title, scale, adjustment,
		  (void*) value_ptr, callback, data);

  return scale;
}

GtkWidget *
info_dialog_add_spinbutton (InfoDialog    *idialog,
			    gchar         *title,
363
			    gdouble       *value_ptr,
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
			    gfloat         lower,
			    gfloat         upper,
			    gfloat         step_increment,
			    gfloat         page_increment,
			    gfloat         page_size,
			    gfloat         climb_rate,
			    gint           digits,
			    GtkSignalFunc  callback,
			    gpointer       data)
{
  GtkWidget *alignment;
  GtkObject *adjustment;
  GtkWidget *spinbutton;

  g_return_val_if_fail (idialog != NULL, NULL);

  alignment = gtk_alignment_new (0.0, 0.5, 0.0, 1.0);

  adjustment = gtk_adjustment_new (value_ptr ? *value_ptr : 0, lower, upper,
				   step_increment, page_increment, page_size);
  spinbutton = gtk_spin_button_new (GTK_ADJUSTMENT (adjustment),
Michael Natterer's avatar
Michael Natterer committed
385
				    climb_rate, MAX (MIN (digits, 6), 0));
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
  gtk_spin_button_set_shadow_type (GTK_SPIN_BUTTON (spinbutton),
				   GTK_SHADOW_NONE);
  gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbutton), TRUE);
  gtk_widget_set_usize (spinbutton, 75, 0);

  if (callback)
    gtk_signal_connect (GTK_OBJECT (adjustment), "value_changed",
			GTK_SIGNAL_FUNC (callback), data);

  gtk_container_add (GTK_CONTAINER (alignment), spinbutton);
  gtk_widget_show (spinbutton);

  info_field_new (idialog, INFO_SPINBUTTON, title, alignment, adjustment,
		  (void*) value_ptr, callback, data);

  return spinbutton;
}

GtkWidget *
info_dialog_add_sizeentry (InfoDialog      *idialog,
			   gchar           *title,
407
			   gdouble         *value_ptr,
408
409
410
411
			   gint             nfields,
			   GUnit            unit,
			   gchar           *unit_format,
			   gboolean         menu_show_pixels,
Michael Natterer's avatar
Michael Natterer committed
412
			   gboolean         menu_show_percent,
413
414
415
416
417
418
419
			   gboolean         show_refval,
			   GimpSizeEntryUP  update_policy,
			   GtkSignalFunc    callback,
			   gpointer         data)
{
  GtkWidget *alignment;
  GtkWidget *sizeentry;
420
  gint       i;
421
422
423
424
425
426

  g_return_val_if_fail (idialog != NULL, NULL);

  alignment = gtk_alignment_new (0.0, 0.5, 0.0, 1.0);

  sizeentry = gimp_size_entry_new (nfields, unit, unit_format,
Michael Natterer's avatar
Michael Natterer committed
427
428
				   menu_show_pixels, menu_show_percent,
				   show_refval, 75,
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
				   update_policy);
  if (value_ptr)
    for (i = 0; i < nfields; i++)
      gimp_size_entry_set_refval (GIMP_SIZE_ENTRY (sizeentry), i, value_ptr[i]);

  if (callback)
    gtk_signal_connect (GTK_OBJECT (sizeentry), "value_changed",
			GTK_SIGNAL_FUNC (callback), data);

  gtk_container_add (GTK_CONTAINER (alignment), sizeentry);
  gtk_widget_show (sizeentry);

  info_field_new (idialog, INFO_SIZEENTRY, title, alignment,
		  GTK_OBJECT (sizeentry),
		  (void*) value_ptr, callback, data);

  return sizeentry;
Elliot Lee's avatar
Elliot Lee committed
446
}