mirror of https://github.com/GNOME/gimp.git
1090 lines
34 KiB
C
1090 lines
34 KiB
C
/* gap_arr_dialog.c
|
|
* 1998.June.29 hof (Wolfgang Hofer)
|
|
*
|
|
* GAP ... Gimp Animation Plugins
|
|
*
|
|
* This is the common GTK Dialog for most of the GAP Functions.
|
|
* (it replaces the older gap_sld_dialog module)
|
|
*
|
|
* - p_array_dialog Dialog Window with one or more rows
|
|
* each row can contain one of the following GAP widgets:
|
|
* - float pair widget
|
|
* (horizontal slidebar combined with a float input field)
|
|
* - int pair widget
|
|
* (horizontal slidebar combined with a int input field)
|
|
* - Toggle Button widget
|
|
* - Textentry widget
|
|
* - Float entry widget
|
|
* - Int entry widget
|
|
*
|
|
*
|
|
*/
|
|
/* 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
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
*/
|
|
|
|
/* revision history:
|
|
* gimp 1.1.17b; 2000/01/26 hof: bugfix gimp_help_init
|
|
* use gimp_scale_entry_new for WGT_FLT_PAIR, WGT_INT_PAIR
|
|
* gimp 1.1.17a; 2000/02/20 hof: use gimp_help_set_help_data for tooltips
|
|
* gimp 1.1.13b; 1999/12/04 hof: some cosmetic gtk fixes
|
|
* changed border_width spacing and Buttons in action area
|
|
* to same style as used in dialogs of the gimp 1.1.13 main dialogs
|
|
* gimp 1.1.11b; 1999/11/20 hof: some cosmetic gtk fixes:
|
|
* - allow X-expansion (useful for the scale widgets)
|
|
* - use a hbox on WGT_INT_PAIR and WGT_FLT_PAIR
|
|
* (reduces the waste of horizontal space
|
|
* when used together with other widget types in the table)
|
|
* gimp 1.1.5.1; 1999/05/08 hof: call fileselect in gtk+1.2 style
|
|
* version 0.96.03; 1998/08/15 hof: p_arr_gtk_init
|
|
* version 0.96.01; 1998/07/09 hof: Bugfix: gtk_init should be called only
|
|
* once in a plugin process
|
|
* version 0.96.00; 1998/07/09 hof: 1.st release
|
|
* (re-implementation of gap_sld_dialog.c)
|
|
*/
|
|
|
|
#include <config.h>
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <sys/types.h>
|
|
|
|
/* GIMP includes */
|
|
#include "gtk/gtk.h"
|
|
#include "libgimp/gimp.h"
|
|
#include "libgimp/gimpui.h"
|
|
#include "libgimp/stdplugins-intl.h"
|
|
#include "libgimp/gimp.h"
|
|
|
|
/* private includes */
|
|
#include "gap_arr_dialog.h"
|
|
|
|
typedef void (*t_entry_cb_func) (GtkWidget *widget, t_arr_arg *arr_ptr);
|
|
|
|
typedef struct
|
|
{
|
|
t_arr_arg *arr_ptr;
|
|
gint radio_index;
|
|
} t_radio_arg;
|
|
|
|
typedef struct {
|
|
GtkWidget *dlg;
|
|
gint run;
|
|
} t_arr_interface;
|
|
|
|
|
|
static gint g_first_call = TRUE;
|
|
|
|
static t_arr_interface g_arrint =
|
|
{
|
|
NULL, /* dlg */
|
|
FALSE /* run */
|
|
};
|
|
|
|
|
|
extern int gap_debug; /* ==0 ... dont print debug infos */
|
|
|
|
/* Declare local functions.
|
|
*/
|
|
|
|
static void arr_close_callback (GtkWidget *widget, gpointer data);
|
|
static void but_array_callback (GtkWidget *widget, gpointer data);
|
|
|
|
static void entry_create_value (char *title, GtkTable *table, int row, t_arr_arg *arr_ptr,
|
|
t_entry_cb_func entry_update_cb, char *init_txt);
|
|
static void label_create_value (char *title, GtkTable *table, int row, t_arr_arg *arr_ptr,
|
|
gfloat align);
|
|
static void text_entry_update_cb (GtkWidget *widget, t_arr_arg *arr_ptr);
|
|
static void text_create_value (char *title, GtkTable *table, int row, t_arr_arg *arr_ptr);
|
|
static void filesel_close_cb (GtkWidget *widget, t_arr_arg *arr_ptr);
|
|
static void filesel_ok_cb (GtkWidget *widget, t_arr_arg *arr_ptr);
|
|
static void filesel_open_cb (GtkWidget *widget, t_arr_arg *arr_ptr);
|
|
static void filesel_create_value (char *title, GtkTable *table, int row, t_arr_arg *arr_ptr);
|
|
|
|
static void int_entry_update_cb (GtkWidget *widget, t_arr_arg *arr_ptr);
|
|
static void int_create_value (char *title, GtkTable *table, int row, t_arr_arg *arr_ptr);
|
|
static void flt_entry_update_cb (GtkWidget *widget, t_arr_arg *arr_ptr);
|
|
static void flt_create_value (char *title, GtkTable *table, int row, t_arr_arg *arr_ptr);
|
|
|
|
static void toggle_update_cb (GtkWidget *widget, t_arr_arg *arr_ptr);
|
|
static void toggle_create_value (char *title, GtkTable *table, int row, t_arr_arg *arr_ptr);
|
|
|
|
static void radio_update_cb (GtkWidget *widget, t_radio_arg *radio_ptr);
|
|
static void radio_create_value (char *title, GtkTable *table, int row, t_arr_arg *arr_ptr);
|
|
static void optionmenu_create_value (char *title, GtkTable *table, int row, t_arr_arg *arr_ptr);
|
|
|
|
static void pair_int_create_value (gchar *title, GtkTable *table, gint row, t_arr_arg *arr_ptr);
|
|
static void pair_flt_create_value (gchar *title, GtkTable *table, gint row, t_arr_arg *arr_ptr);
|
|
|
|
|
|
gint
|
|
p_arr_gtk_init(gint flag)
|
|
{
|
|
gint l_prev_value;
|
|
|
|
l_prev_value = g_first_call;
|
|
if(flag == TRUE) g_first_call = TRUE;
|
|
else g_first_call = FALSE;
|
|
|
|
return (l_prev_value);
|
|
|
|
}
|
|
|
|
|
|
static void
|
|
arr_close_callback (GtkWidget *widget,
|
|
gpointer data)
|
|
{
|
|
gtk_widget_destroy (GTK_WIDGET (g_arrint.dlg)); /* close & destroy dialog window */
|
|
gtk_main_quit ();
|
|
}
|
|
|
|
static void
|
|
but_array_callback (GtkWidget *widget,
|
|
gpointer data)
|
|
{
|
|
g_arrint.run = *((gint *)data); /* set returnvalue according to button */
|
|
gtk_widget_destroy (GTK_WIDGET (g_arrint.dlg)); /* close & destroy dialog window */
|
|
gtk_main_quit ();
|
|
}
|
|
|
|
|
|
static void
|
|
entry_create_value(char *title, GtkTable *table, int row, t_arr_arg *arr_ptr,
|
|
t_entry_cb_func entry_update_cb, char *init_txt)
|
|
{
|
|
GtkWidget *entry;
|
|
GtkWidget *label;
|
|
|
|
|
|
label = gtk_label_new(title);
|
|
gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5);
|
|
gtk_table_attach(table, label, 0, 1, row, row + 1, GTK_FILL, GTK_FILL, 0, 0);
|
|
gtk_widget_show(label);
|
|
|
|
entry = gtk_entry_new();
|
|
gtk_widget_set_usize(entry, arr_ptr->entry_width, 0);
|
|
gtk_entry_set_text(GTK_ENTRY(entry), init_txt);
|
|
gtk_signal_connect(GTK_OBJECT(entry), "changed",
|
|
(GtkSignalFunc) entry_update_cb,
|
|
arr_ptr);
|
|
gtk_table_attach(GTK_TABLE(table), entry, 1, 2, row, row + 1, GTK_FILL, GTK_FILL | GTK_EXPAND, 4, 0);
|
|
if(arr_ptr->help_txt != NULL)
|
|
{
|
|
gimp_help_set_help_data(entry, arr_ptr->help_txt,NULL);
|
|
}
|
|
gtk_widget_show(entry);
|
|
|
|
arr_ptr->text_entry = entry;
|
|
}
|
|
|
|
|
|
/* --------------------------
|
|
* LABEL
|
|
* --------------------------
|
|
*/
|
|
|
|
static void
|
|
label_create_value(char *title, GtkTable *table, int row, t_arr_arg *arr_ptr, gfloat align)
|
|
{
|
|
GtkWidget *label;
|
|
GtkWidget *hbox;
|
|
|
|
label = gtk_label_new(title);
|
|
gtk_misc_set_alignment(GTK_MISC(label), align, 0.5);
|
|
|
|
if(align != 0.5)
|
|
{
|
|
hbox = gtk_hbox_new (FALSE, 2);
|
|
gtk_widget_show (hbox);
|
|
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
|
|
gtk_table_attach(table, hbox, 0, 3, row, row + 1, GTK_FILL, GTK_FILL, 4, 0);
|
|
}
|
|
else
|
|
{
|
|
gtk_table_attach(table, label, 0, 3, row, row + 1, GTK_FILL, GTK_FILL, 4, 0);
|
|
}
|
|
|
|
gtk_widget_show(label);
|
|
}
|
|
|
|
/* --------------------------
|
|
* FILESEL
|
|
* --------------------------
|
|
*/
|
|
static void
|
|
filesel_close_cb(GtkWidget *widget, t_arr_arg *arr_ptr)
|
|
{
|
|
if(arr_ptr->text_filesel == NULL) return; /* filesel is already open */
|
|
|
|
gtk_widget_destroy(GTK_WIDGET(arr_ptr->text_filesel));
|
|
arr_ptr->text_filesel = NULL;
|
|
}
|
|
static void
|
|
filesel_ok_cb(GtkWidget *widget, t_arr_arg *arr_ptr)
|
|
{
|
|
const gchar *filename;
|
|
|
|
if(arr_ptr->text_filesel == NULL) return; /* filesel is already open */
|
|
|
|
filename = gtk_file_selection_get_filename (GTK_FILE_SELECTION (arr_ptr->text_filesel));
|
|
strncpy(arr_ptr->text_buf_ret, filename, arr_ptr->text_buf_len -1);
|
|
|
|
gtk_entry_set_text(GTK_ENTRY(arr_ptr->text_entry), filename);
|
|
|
|
filesel_close_cb(widget, arr_ptr);
|
|
}
|
|
|
|
static void
|
|
filesel_open_cb(GtkWidget *widget, t_arr_arg *arr_ptr)
|
|
{
|
|
GtkWidget *filesel;
|
|
|
|
if(arr_ptr->text_filesel != NULL) return; /* filesel is already open */
|
|
|
|
filesel = gtk_file_selection_new (arr_ptr->label_txt);
|
|
arr_ptr->text_filesel = filesel;
|
|
|
|
gtk_window_set_position (GTK_WINDOW (filesel), GTK_WIN_POS_MOUSE);
|
|
|
|
gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (filesel)->ok_button),
|
|
"clicked", (GtkSignalFunc) filesel_ok_cb,
|
|
arr_ptr);
|
|
gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (filesel)->cancel_button),
|
|
"clicked", (GtkSignalFunc) filesel_close_cb,
|
|
arr_ptr);
|
|
|
|
/* "destroy" has to be the last signal,
|
|
* (otherwise the other callbacks are never called)
|
|
*/
|
|
gtk_signal_connect (GTK_OBJECT (filesel), "destroy",
|
|
(GtkSignalFunc) filesel_close_cb,
|
|
arr_ptr);
|
|
gtk_file_selection_set_filename (GTK_FILE_SELECTION (filesel),
|
|
arr_ptr->text_buf_ret);
|
|
gtk_widget_show (filesel);
|
|
}
|
|
|
|
|
|
static void
|
|
filesel_create_value(char *title, GtkTable *table, int row, t_arr_arg *arr_ptr)
|
|
{
|
|
GtkWidget *button;
|
|
|
|
entry_create_value(title, table, row, arr_ptr, text_entry_update_cb, arr_ptr->text_buf_ret);
|
|
arr_ptr->text_filesel = NULL;
|
|
|
|
/* Button to invoke filebrowser */
|
|
button = gtk_button_new_with_label ( _("File-Browser"));
|
|
gtk_signal_connect (GTK_OBJECT (button), "clicked",
|
|
(GtkSignalFunc) filesel_open_cb,
|
|
arr_ptr);
|
|
gtk_table_attach( GTK_TABLE(table), button, 2, 3, row, row +1,
|
|
0, 0, 0, 0 );
|
|
gtk_widget_show (button);
|
|
|
|
}
|
|
|
|
/* --------------------------
|
|
* TEXT
|
|
* --------------------------
|
|
*/
|
|
static void
|
|
text_entry_update_cb(GtkWidget *widget, t_arr_arg *arr_ptr)
|
|
{
|
|
if((arr_ptr->widget_type != WGT_TEXT)
|
|
&& (arr_ptr->widget_type != WGT_FILESEL))
|
|
{
|
|
return;
|
|
}
|
|
|
|
strncpy(arr_ptr->text_buf_ret,
|
|
gtk_entry_get_text(GTK_ENTRY(widget)),
|
|
arr_ptr->text_buf_len -1);
|
|
arr_ptr->text_buf_ret[arr_ptr->text_buf_len -1] = '\0';
|
|
}
|
|
|
|
static void
|
|
text_create_value(char *title, GtkTable *table, int row, t_arr_arg *arr_ptr)
|
|
{
|
|
entry_create_value(title, table, row, arr_ptr, text_entry_update_cb, arr_ptr->text_buf_ret);
|
|
}
|
|
|
|
|
|
/* --------------------------
|
|
* INT
|
|
* --------------------------
|
|
*/
|
|
|
|
static void
|
|
int_entry_update_cb(GtkWidget *widget, t_arr_arg *arr_ptr)
|
|
{
|
|
if(arr_ptr->widget_type != WGT_INT) return;
|
|
|
|
arr_ptr->int_ret = atol(gtk_entry_get_text(GTK_ENTRY(widget)));
|
|
}
|
|
|
|
static void
|
|
int_create_value(char *title, GtkTable *table, int row, t_arr_arg *arr_ptr)
|
|
{
|
|
char *buf;
|
|
|
|
buf = g_strdup_printf("%d", arr_ptr->int_ret);
|
|
entry_create_value(title, table, row, arr_ptr, int_entry_update_cb, buf);
|
|
g_free(buf);
|
|
}
|
|
|
|
/* --------------------------
|
|
* FLOAT
|
|
* --------------------------
|
|
*/
|
|
|
|
static void
|
|
flt_entry_update_cb(GtkWidget *widget, t_arr_arg *arr_ptr)
|
|
{
|
|
if(arr_ptr->widget_type != WGT_FLT) return;
|
|
|
|
arr_ptr->flt_ret = atof(gtk_entry_get_text(GTK_ENTRY(widget)));
|
|
}
|
|
|
|
static void
|
|
flt_create_value(char *title, GtkTable *table, int row, t_arr_arg *arr_ptr)
|
|
{
|
|
char *buf;
|
|
char *fmt;
|
|
|
|
/* fmt should result something like "%.2f" */
|
|
fmt = g_strdup_printf("%%.%df", arr_ptr->flt_digits);
|
|
buf = g_strdup_printf(fmt, arr_ptr->flt_ret);
|
|
entry_create_value(title, table, row, arr_ptr, flt_entry_update_cb, buf);
|
|
g_free(fmt);
|
|
g_free(buf);
|
|
}
|
|
|
|
/* --------------------------
|
|
* TOGGLE
|
|
* --------------------------
|
|
*/
|
|
|
|
static void
|
|
toggle_update_cb (GtkWidget *widget, t_arr_arg *arr_ptr)
|
|
{
|
|
if(arr_ptr->widget_type !=WGT_TOGGLE) return;
|
|
|
|
if (GTK_TOGGLE_BUTTON (widget)->active)
|
|
{
|
|
arr_ptr->int_ret = 1;
|
|
}
|
|
else
|
|
{
|
|
arr_ptr->int_ret = 0;
|
|
}
|
|
}
|
|
|
|
static void
|
|
toggle_create_value(char *title, GtkTable *table, int row, t_arr_arg *arr_ptr)
|
|
{
|
|
GtkWidget *check_button;
|
|
GtkWidget *label;
|
|
char *l_togg_txt;
|
|
|
|
|
|
label = gtk_label_new(title);
|
|
gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5);
|
|
gtk_table_attach(table, label, 0, 1, row, row + 1, GTK_FILL, GTK_FILL, 0, 0);
|
|
gtk_widget_show(label);
|
|
|
|
/* (make sure there is only 0 or 1) */
|
|
if(arr_ptr->int_ret != 0) arr_ptr->int_ret = 1;
|
|
|
|
if(arr_ptr->togg_label == NULL) l_togg_txt = " ";
|
|
else l_togg_txt = arr_ptr->togg_label;
|
|
/* check button */
|
|
check_button = gtk_check_button_new_with_label (l_togg_txt);
|
|
gtk_table_attach ( GTK_TABLE (table), check_button, 1, 3, row, row+1, GTK_FILL, 0, 0, 0);
|
|
gtk_signal_connect (GTK_OBJECT (check_button), "toggled",
|
|
(GtkSignalFunc) toggle_update_cb,
|
|
arr_ptr);
|
|
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_button),
|
|
arr_ptr->int_ret);
|
|
if(arr_ptr->help_txt != NULL)
|
|
{
|
|
gimp_help_set_help_data(check_button, arr_ptr->help_txt,NULL);
|
|
}
|
|
gtk_widget_show (check_button);
|
|
}
|
|
|
|
|
|
/* --------------------------
|
|
* RADIO
|
|
* --------------------------
|
|
*/
|
|
|
|
static void
|
|
radio_update_cb (GtkWidget *widget, t_radio_arg *radio_ptr)
|
|
{
|
|
if(radio_ptr->arr_ptr == NULL) return;
|
|
if((radio_ptr->arr_ptr->widget_type != WGT_RADIO)
|
|
&& (radio_ptr->arr_ptr->widget_type != WGT_OPTIONMENU))
|
|
{
|
|
return;
|
|
}
|
|
|
|
radio_ptr->arr_ptr->int_ret = radio_ptr->radio_index;
|
|
radio_ptr->arr_ptr->radio_ret = radio_ptr->radio_index;
|
|
}
|
|
|
|
static void
|
|
radio_create_value(char *title, GtkTable *table, int row, t_arr_arg *arr_ptr)
|
|
{
|
|
GtkWidget *label;
|
|
GtkWidget *radio_table;
|
|
GtkWidget *radio_button;
|
|
GSList *radio_group = NULL;
|
|
gint l_idy;
|
|
char *l_radio_txt;
|
|
char *l_radio_help_txt;
|
|
gint l_radio_pressed;
|
|
|
|
t_radio_arg *radio_ptr;
|
|
|
|
|
|
label = gtk_label_new(title);
|
|
gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.0);
|
|
gtk_table_attach( GTK_TABLE (table), label, 0, 1, row, row+1, GTK_FILL, GTK_FILL, 0, 0);
|
|
gtk_widget_show(label);
|
|
|
|
/* radio_table */
|
|
radio_table = gtk_table_new (arr_ptr->radio_argc, 2, FALSE);
|
|
|
|
|
|
for(l_idy=0; l_idy < arr_ptr->radio_argc; l_idy++)
|
|
{
|
|
radio_ptr = g_malloc0(sizeof(t_radio_arg));
|
|
radio_ptr->arr_ptr = arr_ptr;
|
|
radio_ptr->radio_index = l_idy;
|
|
|
|
if(arr_ptr->radio_ret == l_idy) l_radio_pressed = TRUE;
|
|
else l_radio_pressed = FALSE;
|
|
|
|
l_radio_txt = "null";
|
|
if (arr_ptr->radio_argv != NULL)
|
|
{
|
|
if (arr_ptr->radio_argv[l_idy] != NULL)
|
|
l_radio_txt = arr_ptr->radio_argv[l_idy];
|
|
}
|
|
|
|
l_radio_help_txt = arr_ptr->help_txt;
|
|
if (arr_ptr->radio_help_argv != NULL)
|
|
{
|
|
if (arr_ptr->radio_help_argv[l_idy] != NULL)
|
|
l_radio_help_txt = arr_ptr->radio_help_argv[l_idy];
|
|
}
|
|
|
|
if(gap_debug) printf("radio_create_value: %02d %s\n", l_idy, l_radio_txt);
|
|
|
|
radio_button = gtk_radio_button_new_with_label ( radio_group, l_radio_txt );
|
|
radio_group = gtk_radio_button_group ( GTK_RADIO_BUTTON (radio_button) );
|
|
gtk_table_attach ( GTK_TABLE (radio_table), radio_button, 0, 2, l_idy, l_idy+1, GTK_FILL | GTK_EXPAND, 0, 0, 0);
|
|
|
|
gtk_signal_connect ( GTK_OBJECT (radio_button), "toggled",
|
|
(GtkSignalFunc) radio_update_cb,
|
|
radio_ptr);
|
|
|
|
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio_button),
|
|
l_radio_pressed);
|
|
if(l_radio_help_txt != NULL)
|
|
{
|
|
gimp_help_set_help_data(radio_button, l_radio_help_txt, NULL);
|
|
}
|
|
gtk_widget_show (radio_button);
|
|
}
|
|
|
|
|
|
/* attach radio_table */
|
|
gtk_table_attach ( GTK_TABLE (table), radio_table, 1, 3, row, row+1, GTK_FILL | GTK_EXPAND, 0, 0, 0);
|
|
gtk_widget_show (radio_table);
|
|
}
|
|
|
|
|
|
/* --------------------------
|
|
* OPTIONMENU
|
|
* --------------------------
|
|
*/
|
|
|
|
/* optionmenus share callback and data structure with WGT_RADIO */
|
|
static void
|
|
optionmenu_create_value(char *title, GtkTable *table, int row, t_arr_arg *arr_ptr)
|
|
{
|
|
GtkWidget *label;
|
|
GtkWidget *option_menu;
|
|
GtkWidget *menu;
|
|
GtkWidget *menu_item;
|
|
gint l_idx;
|
|
gint l_idy;
|
|
char *l_radio_txt;
|
|
gint l_radio_pressed;
|
|
|
|
t_radio_arg *l_menu_ptr;
|
|
|
|
/* label */
|
|
label = gtk_label_new(title);
|
|
gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5);
|
|
gtk_table_attach( GTK_TABLE (table), label, 0, 1, row, row+1, GTK_FILL, GTK_FILL, 0, 0);
|
|
gtk_widget_show(label);
|
|
|
|
/* optionmenu */
|
|
option_menu = gtk_option_menu_new();
|
|
gtk_table_attach(GTK_TABLE(table), option_menu, 1, 2, row, row +1,
|
|
GTK_FILL, GTK_FILL, 0, 0);
|
|
gtk_widget_show(option_menu);
|
|
|
|
if(arr_ptr->help_txt != NULL)
|
|
{
|
|
gimp_help_set_help_data(option_menu, arr_ptr->help_txt, NULL);
|
|
}
|
|
|
|
/* menu (filled with items in loop) */
|
|
menu = gtk_menu_new ();
|
|
|
|
/* outer loop is done to ensure that the initial "pressed" value
|
|
* is the first entry in the optionmenu
|
|
*/
|
|
for(l_idx=0; l_idx < 2; l_idx++)
|
|
{
|
|
for(l_idy=0; l_idy < arr_ptr->radio_argc; l_idy++)
|
|
{
|
|
if(arr_ptr->radio_ret == l_idy) l_radio_pressed = TRUE;
|
|
else l_radio_pressed = FALSE;
|
|
|
|
if( ((l_radio_pressed == TRUE) && (l_idx == 0))
|
|
|| ((l_radio_pressed == FALSE) && (l_idx == 1)))
|
|
{
|
|
l_radio_txt = "null";
|
|
if (arr_ptr->radio_argv != NULL)
|
|
{
|
|
if (arr_ptr->radio_argv[l_idy] != NULL)
|
|
l_radio_txt = arr_ptr->radio_argv[l_idy];
|
|
}
|
|
l_menu_ptr = g_malloc0(sizeof(t_radio_arg));
|
|
l_menu_ptr->radio_index = l_idy;
|
|
l_menu_ptr->arr_ptr = arr_ptr;
|
|
|
|
|
|
menu_item = gtk_menu_item_new_with_label (l_radio_txt);
|
|
gtk_container_add (GTK_CONTAINER (menu), menu_item);
|
|
|
|
gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
|
|
(GtkSignalFunc) radio_update_cb,
|
|
l_menu_ptr);
|
|
gtk_widget_show (menu_item);
|
|
}
|
|
}
|
|
}
|
|
|
|
gtk_option_menu_set_menu(GTK_OPTION_MENU(option_menu), menu);
|
|
gtk_widget_show(option_menu);
|
|
|
|
}
|
|
|
|
|
|
/* --------------------------
|
|
* FLT_PAIR
|
|
* --------------------------
|
|
*/
|
|
|
|
static void
|
|
pair_flt_create_value(gchar *title, GtkTable *table, gint row, t_arr_arg *arr_ptr)
|
|
{
|
|
GtkObject *adj;
|
|
gfloat umin, umax;
|
|
|
|
if(arr_ptr->constraint)
|
|
{
|
|
umin = arr_ptr->flt_min;
|
|
umax = arr_ptr->flt_max;
|
|
}
|
|
else
|
|
{
|
|
umin = arr_ptr->umin;
|
|
umax = arr_ptr->umax;
|
|
}
|
|
|
|
|
|
adj =
|
|
gimp_scale_entry_new( GTK_TABLE (table), 0, row, /* table col, row */
|
|
title, /* label text */
|
|
arr_ptr->scale_width, /* scalesize */
|
|
arr_ptr->entry_width, /* entrysize */
|
|
(gfloat)arr_ptr->flt_ret, /* init value */
|
|
(gfloat)arr_ptr->flt_min, /* lower, */
|
|
(gfloat)arr_ptr->flt_max, /* upper */
|
|
arr_ptr->flt_step, /* step */
|
|
arr_ptr->pagestep, /* pagestep */
|
|
arr_ptr->flt_digits, /* digits */
|
|
arr_ptr->constraint, /* constrain */
|
|
umin, umax, /* lower, upper (unconstrained) */
|
|
arr_ptr->help_txt, /* tooltip */
|
|
NULL); /* privatetip */
|
|
|
|
gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
|
|
GTK_SIGNAL_FUNC (gimp_double_adjustment_update),
|
|
&arr_ptr->flt_ret);
|
|
}
|
|
|
|
/* --------------------------
|
|
* INT_PAIR
|
|
* --------------------------
|
|
*/
|
|
|
|
static void
|
|
pair_int_create_value(gchar *title, GtkTable *table, gint row, t_arr_arg *arr_ptr)
|
|
{
|
|
GtkObject *adj;
|
|
gfloat umin, umax;
|
|
|
|
if(arr_ptr->constraint)
|
|
{
|
|
umin = (gfloat)arr_ptr->int_min;
|
|
umax = (gfloat)arr_ptr->int_max;
|
|
}
|
|
else
|
|
{
|
|
umin = arr_ptr->umin;
|
|
umax = arr_ptr->umax;
|
|
}
|
|
|
|
adj =
|
|
gimp_scale_entry_new( GTK_TABLE (table), 0, row, /* table col, row */
|
|
title, /* label text */
|
|
arr_ptr->scale_width, /* scalesize */
|
|
arr_ptr->entry_width, /* entrysize */
|
|
(gfloat)arr_ptr->int_ret, /* init value */
|
|
(gfloat)arr_ptr->int_min, /* lower, */
|
|
(gfloat)arr_ptr->int_max, /* upper */
|
|
arr_ptr->int_step, /* step */
|
|
arr_ptr->pagestep, /* pagestep */
|
|
0, /* digits */
|
|
arr_ptr->constraint, /* constrain */
|
|
umin, umax, /* lower, upper (unconstrained) */
|
|
arr_ptr->help_txt, /* tooltip */
|
|
NULL); /* privatetip */
|
|
|
|
gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
|
|
GTK_SIGNAL_FUNC (gimp_int_adjustment_update),
|
|
&arr_ptr->int_ret);
|
|
|
|
}
|
|
|
|
|
|
/* ============================================================================
|
|
* p_array_std_dialog
|
|
*
|
|
* GTK dialog window that has argc rows.
|
|
* each row contains the widget(s) as defined in argv[row]
|
|
*
|
|
* The Dialog has an Action Area with OK and CANCEL Buttons.
|
|
* ============================================================================
|
|
*/
|
|
gint p_array_std_dialog(char *title_txt,
|
|
char *frame_txt,
|
|
int argc,
|
|
t_arr_arg argv[],
|
|
int b_argc,
|
|
t_but_arg b_argv[],
|
|
gint b_def_val)
|
|
{
|
|
GtkWidget *hbbox;
|
|
GtkWidget *button;
|
|
GtkWidget *frame;
|
|
GtkWidget *table;
|
|
gchar **l_argsv;
|
|
gint l_argsc;
|
|
gint l_idx;
|
|
gint l_ok_value;
|
|
char *l_label_txt;
|
|
t_arr_arg *arr_ptr;
|
|
|
|
g_arrint.run = b_def_val; /* prepare default retcode (if window is closed without button) */
|
|
l_ok_value = 0;
|
|
table = NULL;
|
|
|
|
if((argc > 0) && (argv == NULL))
|
|
{
|
|
printf("p_array_std_dialog: calling error (widget array == NULL)\n");
|
|
return (g_arrint.run);
|
|
}
|
|
if((b_argc > 0) && (b_argv == NULL))
|
|
{
|
|
printf("p_array_std_dialog: calling error (button array == NULL)\n");
|
|
return (g_arrint.run);
|
|
}
|
|
|
|
/* gtk init (only once in a plugin-process) */
|
|
if (g_first_call == TRUE)
|
|
{
|
|
l_argsc = 1;
|
|
l_argsv = g_new (gchar *, 1);
|
|
l_argsv[0] = g_strdup ("gap_std_dialog");
|
|
gtk_init (&l_argsc, &l_argsv);
|
|
g_first_call = FALSE;
|
|
}
|
|
|
|
/* Initialize Tooltips */
|
|
gimp_help_init ();
|
|
|
|
/* dialog */
|
|
g_arrint.dlg = gtk_dialog_new ();
|
|
gtk_window_set_title (GTK_WINDOW (g_arrint.dlg), title_txt);
|
|
gtk_window_set_position (GTK_WINDOW (g_arrint.dlg), GTK_WIN_POS_MOUSE);
|
|
gtk_signal_connect (GTK_OBJECT (g_arrint.dlg), "destroy",
|
|
(GtkSignalFunc) arr_close_callback,
|
|
NULL);
|
|
|
|
gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (g_arrint.dlg)->action_area), 2);
|
|
gtk_box_set_homogeneous (GTK_BOX (GTK_DIALOG (g_arrint.dlg)->action_area), FALSE);
|
|
hbbox = gtk_hbutton_box_new ();
|
|
gtk_button_box_set_spacing (GTK_BUTTON_BOX (hbbox), 4);
|
|
gtk_box_pack_end (GTK_BOX (GTK_DIALOG (g_arrint.dlg)->action_area), hbbox, FALSE, FALSE, 0);
|
|
gtk_widget_show (hbbox);
|
|
|
|
/* Action area */
|
|
for(l_idx = 0; l_idx < b_argc; l_idx++)
|
|
{
|
|
|
|
if(b_argv[l_idx].but_txt == NULL) button = gtk_button_new_from_stock ( GTK_STOCK_OK);
|
|
else button = gtk_button_new_from_stock (b_argv[l_idx].but_txt);
|
|
GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
|
|
gtk_signal_connect (GTK_OBJECT (button), "clicked",
|
|
(GtkSignalFunc) but_array_callback,
|
|
&b_argv[l_idx].but_val);
|
|
gtk_box_pack_start (GTK_BOX (hbbox), button, FALSE, FALSE, 0);
|
|
if( b_argv[l_idx].but_val == b_def_val ) gtk_widget_grab_default (button);
|
|
gtk_widget_show (button);
|
|
|
|
}
|
|
|
|
if(b_argc < 1)
|
|
{
|
|
/* if no buttons are specified use one CLOSE button per default */
|
|
button = gtk_button_new_from_stock ( GTK_STOCK_CLOSE);
|
|
GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
|
|
gtk_signal_connect (GTK_OBJECT (button), "clicked",
|
|
(GtkSignalFunc) but_array_callback,
|
|
&l_ok_value);
|
|
gtk_box_pack_start (GTK_BOX (hbbox), button, TRUE, TRUE, 0);
|
|
gtk_widget_grab_default (button);
|
|
gtk_widget_show (button);
|
|
}
|
|
|
|
/* parameter settings */
|
|
if (frame_txt == NULL) frame = gtk_frame_new ( _("Enter Values"));
|
|
else frame = gtk_frame_new (frame_txt);
|
|
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN);
|
|
gtk_container_set_border_width (GTK_CONTAINER (frame), 6);
|
|
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (g_arrint.dlg)->vbox), frame, TRUE, TRUE, 0);
|
|
|
|
if(argc > 0)
|
|
{
|
|
/* table (one row per argv) */
|
|
table = gtk_table_new (argc +1, 3, FALSE);
|
|
gtk_table_set_col_spacings (GTK_TABLE (table), 4);
|
|
gtk_table_set_row_spacings (GTK_TABLE (table), 2);
|
|
gtk_container_set_border_width (GTK_CONTAINER (table), 4);
|
|
gtk_container_add (GTK_CONTAINER (frame), table);
|
|
|
|
for(l_idx = 0; l_idx < argc; l_idx++)
|
|
{
|
|
arr_ptr = &argv[l_idx];
|
|
|
|
if(arr_ptr->label_txt == NULL) l_label_txt = _("Value:");
|
|
else l_label_txt = arr_ptr->label_txt;
|
|
|
|
switch(arr_ptr->widget_type)
|
|
{
|
|
case WGT_FLT_PAIR:
|
|
pair_flt_create_value(l_label_txt, GTK_TABLE(table), (l_idx + 1), arr_ptr);
|
|
break;
|
|
case WGT_INT_PAIR:
|
|
pair_int_create_value(l_label_txt, GTK_TABLE(table), (l_idx + 1), arr_ptr);
|
|
break;
|
|
case WGT_TOGGLE:
|
|
toggle_create_value(l_label_txt, GTK_TABLE(table), (l_idx + 1), arr_ptr);
|
|
break;
|
|
case WGT_RADIO:
|
|
radio_create_value(l_label_txt, GTK_TABLE(table), (l_idx + 1), arr_ptr);
|
|
break;
|
|
case WGT_OPTIONMENU:
|
|
optionmenu_create_value(l_label_txt, GTK_TABLE(table), (l_idx + 1), arr_ptr);
|
|
break;
|
|
case WGT_FILESEL:
|
|
filesel_create_value(l_label_txt, GTK_TABLE(table), (l_idx + 1), arr_ptr);
|
|
break;
|
|
case WGT_TEXT:
|
|
text_create_value(l_label_txt, GTK_TABLE(table), (l_idx + 1), arr_ptr);
|
|
break;
|
|
case WGT_INT:
|
|
int_create_value(l_label_txt, GTK_TABLE(table), (l_idx + 1), arr_ptr);
|
|
break;
|
|
case WGT_FLT:
|
|
flt_create_value(l_label_txt, GTK_TABLE(table), (l_idx + 1), arr_ptr);
|
|
break;
|
|
case WGT_LABEL:
|
|
label_create_value(l_label_txt, GTK_TABLE(table), (l_idx + 1), arr_ptr, 0.5);
|
|
break;
|
|
case WGT_LABEL_LEFT:
|
|
label_create_value(l_label_txt, GTK_TABLE(table), (l_idx + 1), arr_ptr, 0.0);
|
|
break;
|
|
case WGT_LABEL_RIGHT:
|
|
label_create_value(l_label_txt, GTK_TABLE(table), (l_idx + 1), arr_ptr, 1.0);
|
|
break;
|
|
case WGT_ACT_BUTTON:
|
|
printf ("WGT_ACT_BUTTON not implemented yet, widget type ignored\n");
|
|
break;
|
|
default: /* undefined widget type */
|
|
printf ("Unknown widget type %d ignored\n", arr_ptr->widget_type);
|
|
break;
|
|
|
|
} /* end switch */
|
|
} /* end for */
|
|
}
|
|
|
|
gtk_widget_show (frame);
|
|
if(argc > 0) { gtk_widget_show (table); }
|
|
gtk_widget_show (g_arrint.dlg);
|
|
|
|
gtk_main ();
|
|
gdk_flush ();
|
|
|
|
if(gap_debug)
|
|
{
|
|
/* for debugging: print results to stdout */
|
|
for(l_idx = 0; l_idx < argc; l_idx++)
|
|
{
|
|
arr_ptr = &argv[l_idx];
|
|
|
|
if(arr_ptr->label_txt == NULL) l_label_txt = _("Value: ");
|
|
else l_label_txt = arr_ptr->label_txt;
|
|
arr_ptr = &argv[l_idx];
|
|
|
|
printf("%02d ", l_idx);
|
|
|
|
switch(arr_ptr->widget_type)
|
|
{
|
|
case WGT_FLT_PAIR:
|
|
case WGT_FLT:
|
|
printf("FLT %s : %f\n", l_label_txt, arr_ptr->flt_ret);
|
|
break;
|
|
case WGT_INT_PAIR:
|
|
case WGT_INT:
|
|
case WGT_TOGGLE:
|
|
printf("INT %s : %d\n", l_label_txt, arr_ptr->int_ret);
|
|
break;
|
|
case WGT_TEXT:
|
|
case WGT_FILESEL:
|
|
printf("TEXT %s : %s\n", l_label_txt, arr_ptr->text_buf_ret);
|
|
break;
|
|
case WGT_RADIO:
|
|
case WGT_OPTIONMENU:
|
|
printf("RADIO/OPTIONMENU %s : %d\n", l_label_txt, arr_ptr->radio_ret);
|
|
break;
|
|
default:
|
|
printf("\n");
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
return (g_arrint.run);
|
|
} /* end p_array_dialog */
|
|
|
|
|
|
|
|
void p_init_arr_arg (t_arr_arg *arr_ptr,
|
|
gint widget_type)
|
|
{
|
|
arr_ptr->label_txt = NULL;
|
|
arr_ptr->help_txt = NULL;
|
|
arr_ptr->togg_label = NULL;
|
|
arr_ptr->entry_width = 60;
|
|
arr_ptr->scale_width = 200;
|
|
arr_ptr->constraint = TRUE;
|
|
arr_ptr->has_default = FALSE;
|
|
arr_ptr->text_entry = NULL;
|
|
|
|
switch(widget_type)
|
|
{
|
|
case WGT_LABEL:
|
|
case WGT_LABEL_LEFT:
|
|
case WGT_LABEL_RIGHT:
|
|
arr_ptr->widget_type = widget_type;
|
|
break;
|
|
case WGT_INT_PAIR:
|
|
case WGT_INT:
|
|
arr_ptr->widget_type = widget_type;
|
|
arr_ptr->umin = (gfloat)G_MININT;
|
|
arr_ptr->umax = (gfloat)G_MAXINT;
|
|
arr_ptr->int_min = 0;
|
|
arr_ptr->int_max = 100;
|
|
arr_ptr->int_step = 1;
|
|
arr_ptr->pagestep = 10.0;
|
|
arr_ptr->int_default = 0;
|
|
arr_ptr->int_ret = 0;
|
|
break;
|
|
case WGT_FLT_PAIR:
|
|
case WGT_FLT:
|
|
arr_ptr->widget_type = widget_type;
|
|
arr_ptr->flt_digits = 2;
|
|
arr_ptr->umin = G_MINFLOAT;
|
|
arr_ptr->umax = G_MAXFLOAT;
|
|
arr_ptr->flt_min = 0.0;
|
|
arr_ptr->flt_max = 100.0;
|
|
arr_ptr->flt_step = 0.1;
|
|
arr_ptr->pagestep = 10.0;
|
|
arr_ptr->flt_default = 0.0;
|
|
arr_ptr->flt_ret = 0.0;
|
|
break;
|
|
case WGT_TOGGLE:
|
|
arr_ptr->widget_type = widget_type;
|
|
arr_ptr->int_default = 0;
|
|
arr_ptr->int_ret = 0;
|
|
break;
|
|
case WGT_RADIO:
|
|
case WGT_OPTIONMENU:
|
|
arr_ptr->widget_type = widget_type;
|
|
arr_ptr->radio_argc = 0;
|
|
arr_ptr->radio_default = 0;
|
|
arr_ptr->radio_ret = 0;
|
|
arr_ptr->radio_argv = NULL;
|
|
arr_ptr->radio_help_argv = NULL;
|
|
break;
|
|
case WGT_TEXT:
|
|
case WGT_FILESEL:
|
|
arr_ptr->widget_type = widget_type;
|
|
arr_ptr->text_buf_len = 0;
|
|
arr_ptr->text_buf_default = NULL;
|
|
arr_ptr->text_buf_ret = NULL;
|
|
arr_ptr->text_filesel = NULL;
|
|
break;
|
|
case WGT_ACT_BUTTON:
|
|
arr_ptr->widget_type = widget_type;
|
|
arr_ptr->action_functon = NULL;
|
|
arr_ptr->action_data = NULL;
|
|
break;
|
|
default: /* Calling error: undefined widget type */
|
|
arr_ptr->widget_type = WGT_LABEL;
|
|
break;
|
|
|
|
}
|
|
|
|
} /* end p_init_arr_arg */
|
|
|
|
/* ============================================================================
|
|
* simplified calls of p_array_std_dialog
|
|
* ============================================================================
|
|
*/
|
|
|
|
|
|
gint p_array_dialog(char *title_txt,
|
|
char *frame_txt,
|
|
int argc,
|
|
t_arr_arg argv[])
|
|
{
|
|
static t_but_arg b_argv[2];
|
|
|
|
b_argv[0].but_txt = GTK_STOCK_OK;
|
|
b_argv[0].but_val = TRUE;
|
|
b_argv[1].but_txt = GTK_STOCK_CANCEL;
|
|
b_argv[1].but_val = FALSE;
|
|
|
|
return( p_array_std_dialog(title_txt,
|
|
frame_txt,
|
|
argc, argv, /* widget array */
|
|
2, b_argv, /* button array */
|
|
FALSE)
|
|
); /* ret value for window close */
|
|
}
|
|
|
|
/* ============================================================================
|
|
* p_buttons_dialog
|
|
* dialog window wit 1 upto n buttons
|
|
* return: the value aassigned with the pressed button.
|
|
* (If window closed by windowmanager return b_def_val)
|
|
* ============================================================================
|
|
*/
|
|
|
|
|
|
gint p_buttons_dialog(char *title_txt,
|
|
char *msg_txt,
|
|
int b_argc,
|
|
t_but_arg b_argv[],
|
|
gint b_def_val)
|
|
{
|
|
static t_arr_arg argv[1];
|
|
char *frame_txt;
|
|
|
|
if(b_argc == 1) frame_txt = _("Press Button");
|
|
else frame_txt = _("Select");
|
|
|
|
p_init_arr_arg(&argv[0], WGT_LABEL);
|
|
argv[0].label_txt = msg_txt;
|
|
|
|
return( p_array_std_dialog(title_txt,
|
|
frame_txt,
|
|
1, argv,
|
|
b_argc, b_argv,
|
|
b_def_val)
|
|
); /* ret value for window close */
|
|
|
|
} /* end p_buttons_dialog */
|
|
|
|
|
|
|
|
/* ============================================================================
|
|
* p_slider_dialog
|
|
* simplified call of p_array_dialog, using an array with one value.
|
|
*
|
|
* return the value of the (only) entryfield
|
|
* or -1 in case of Error or cancel
|
|
* ============================================================================
|
|
*/
|
|
|
|
long p_slider_dialog(char *title, char *frame, char *label, char *tooltip,
|
|
long min, long max, long curr, long constraint)
|
|
{
|
|
static t_arr_arg argv[1];
|
|
|
|
p_init_arr_arg(&argv[0], WGT_INT_PAIR);
|
|
argv[0].label_txt = label;
|
|
argv[0].help_txt = tooltip;
|
|
argv[0].constraint = constraint;
|
|
argv[0].entry_width = 45;
|
|
argv[0].scale_width = 130;
|
|
argv[0].int_min = (gint)min;
|
|
argv[0].int_max = (gint)max;
|
|
argv[0].int_step = 1;
|
|
argv[0].int_ret = (gint)curr;
|
|
|
|
if(TRUE == p_array_dialog(title, frame, 1, argv))
|
|
{ return (long)(argv[0].int_ret);
|
|
}
|
|
else return -1;
|
|
} /* end p_slider_dialog */
|