PIKApp/plug-ins/common/file-gih.c

897 lines
29 KiB
C

/* Plug-in to load and export .gih (PIKA Brush Pipe) files.
*
* Copyright (C) 1999 Tor Lillqvist
* Copyright (C) 2000 Jens Lautenbacher, Sven Neumann
*
* 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 3 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, see <https://www.gnu.org/licenses/>.
*/
/* Example of how to call file_gih_save from script-fu:
(let ((ranks (cons-array 1 'byte)))
(aset ranks 0 12)
(file-gih-save 1
img
drawable
"foo.gih"
"foo.gih"
100
"test brush"
125
125
3
4
1
ranks
1
'("random")))
*/
#include "config.h"
#include <libpika/pika.h>
#include <libpika/pikaui.h>
#include <libpikabase/pikaparasiteio.h>
#include "libpika/stdplugins-intl.h"
#define SAVE_PROC "file-gih-save"
#define PLUG_IN_BINARY "file-gih"
#define PLUG_IN_ROLE "pika-file-gih"
/* Parameters applicable each time we export a gih, exported in the
* main pika application between invocations of this plug-in.
*/
typedef struct
{
gchar description[256];
gint spacing;
} BrushInfo;
typedef struct
{
PikaOrientationType orientation;
PikaImage *image;
PikaLayer *toplayer;
gint nguides;
gint32 *guides;
gint *value;
GtkWidget *count_label; /* Corresponding count adjustment, */
gint *count; /* cols or rows */
gint *other_count; /* and the other one */
GtkAdjustment *ncells;
GtkAdjustment *rank0;
GtkWidget *warning_label;
GtkWidget *rank_entry[PIKA_PIXPIPE_MAXDIM];
GtkWidget *mode_entry[PIKA_PIXPIPE_MAXDIM];
} SizeAdjustmentData;
typedef struct _Gih Gih;
typedef struct _GihClass GihClass;
struct _Gih
{
PikaPlugIn parent_instance;
};
struct _GihClass
{
PikaPlugInClass parent_class;
};
#define GIH_TYPE (gih_get_type ())
#define GIH (obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIH_TYPE, Gih))
GType gih_get_type (void) G_GNUC_CONST;
static GList * gih_query_procedures (PikaPlugIn *plug_in);
static PikaProcedure * gih_create_procedure (PikaPlugIn *plug_in,
const gchar *name);
static PikaValueArray * gih_save (PikaProcedure *procedure,
PikaRunMode run_mode,
PikaImage *image,
gint n_drawables,
PikaDrawable **drawables,
GFile *file,
const PikaValueArray *args,
gpointer run_data);
static gboolean gih_save_dialog (PikaImage *image);
G_DEFINE_TYPE (Gih, gih, PIKA_TYPE_PLUG_IN)
PIKA_MAIN (GIH_TYPE)
DEFINE_STD_SET_I18N
static BrushInfo info =
{
"PIKA Brush Pipe",
20
};
static gint num_layers = 0;
static PikaPixPipeParams gihparams = { 0, };
static const gchar * const selection_modes[] = { "incremental",
"angular",
"random",
"velocity",
"pressure",
"xtilt",
"ytilt" };
static void
gih_class_init (GihClass *klass)
{
PikaPlugInClass *plug_in_class = PIKA_PLUG_IN_CLASS (klass);
plug_in_class->query_procedures = gih_query_procedures;
plug_in_class->create_procedure = gih_create_procedure;
plug_in_class->set_i18n = STD_SET_I18N;
}
static void
gih_init (Gih *gih)
{
}
static GList *
gih_query_procedures (PikaPlugIn *plug_in)
{
return g_list_append (NULL, g_strdup (SAVE_PROC));
}
static PikaProcedure *
gih_create_procedure (PikaPlugIn *plug_in,
const gchar *name)
{
PikaProcedure *procedure = NULL;
if (! strcmp (name, SAVE_PROC))
{
procedure = pika_save_procedure_new (plug_in, name,
PIKA_PDB_PROC_TYPE_PLUGIN,
gih_save, NULL, NULL);
pika_procedure_set_image_types (procedure, "RGB*, GRAY*");
pika_procedure_set_menu_label (procedure, _("PIKA brush (animated)"));
pika_procedure_set_icon_name (procedure, PIKA_ICON_BRUSH);
pika_procedure_set_documentation (procedure,
"exports images in PIKA brush pipe "
"format",
"This plug-in exports an image in "
"the PIKA brush pipe format. For a "
"colored brush pipe, RGBA layers are "
"used, otherwise the layers should be "
"grayscale masks. The image can be "
"multi-layered, and additionally the "
"layers can be divided into a "
"rectangular array of brushes.",
SAVE_PROC);
pika_procedure_set_attribution (procedure,
"Tor Lillqvist",
"Tor Lillqvist",
"1999");
pika_file_procedure_set_mime_types (PIKA_FILE_PROCEDURE (procedure),
"image/x-pika-gih");
pika_file_procedure_set_extensions (PIKA_FILE_PROCEDURE (procedure),
"gih");
pika_file_procedure_set_handles_remote (PIKA_FILE_PROCEDURE (procedure),
TRUE);
PIKA_PROC_ARG_INT (procedure, "spacing",
"Spacing",
"Spacing of the brush",
1, 1000, 10,
PIKA_PARAM_READWRITE);
PIKA_PROC_ARG_STRING (procedure, "description",
"Description",
"Short description of the gihtern",
"PIKA Gihtern",
PIKA_PARAM_READWRITE);
PIKA_PROC_ARG_INT (procedure, "cell-width",
"Cell width",
"Width of the brush cells",
1, 1000, 10,
PIKA_PARAM_READWRITE);
PIKA_PROC_ARG_INT (procedure, "cell-height",
"Cell height",
"Height of the brush cells",
1, 1000, 10,
PIKA_PARAM_READWRITE);
PIKA_PROC_ARG_INT (procedure, "display-cols",
"Display columns",
"Display column number",
1, 1000, 1,
PIKA_PARAM_READWRITE);
PIKA_PROC_ARG_INT (procedure, "display-rows",
"Display rows",
"Display row number",
1, 1000, 1,
PIKA_PARAM_READWRITE);
PIKA_PROC_ARG_BYTES (procedure, "rank",
"Rank",
"Ranks of the dimensions",
PIKA_PARAM_READWRITE);
PIKA_PROC_ARG_INT (procedure, "dimension-2",
"Dimension 2",
"Dimension of the brush pipe (same as dimension)",
1, 4, 1,
PIKA_PARAM_READWRITE);
PIKA_PROC_ARG_STRV (procedure, "sel",
"Sel",
"Selection modes",
PIKA_PARAM_READWRITE);
}
return procedure;
}
static PikaValueArray *
gih_save (PikaProcedure *procedure,
PikaRunMode run_mode,
PikaImage *image,
gint n_drawables,
PikaDrawable **drawables,
GFile *file,
const PikaValueArray *args,
gpointer run_data)
{
PikaPDBStatusType status = PIKA_PDB_SUCCESS;
PikaExportReturn export = PIKA_EXPORT_CANCEL;
PikaParasite *parasite;
PikaImage *orig_image;
GError *error = NULL;
gint i;
GBytes *rank_bytes;
orig_image = image;
switch (run_mode)
{
case PIKA_RUN_INTERACTIVE:
case PIKA_RUN_WITH_LAST_VALS:
pika_ui_init (PLUG_IN_BINARY);
export = pika_export_image (&image, &n_drawables, &drawables, "GIH",
PIKA_EXPORT_CAN_HANDLE_RGB |
PIKA_EXPORT_CAN_HANDLE_GRAY |
PIKA_EXPORT_CAN_HANDLE_ALPHA |
PIKA_EXPORT_CAN_HANDLE_LAYERS);
if (export == PIKA_EXPORT_CANCEL)
return pika_procedure_new_return_values (procedure,
PIKA_PDB_CANCEL,
NULL);
/* Possibly retrieve data */
pika_get_data (SAVE_PROC, &info);
parasite = pika_image_get_parasite (orig_image,
"pika-brush-pipe-name");
if (parasite)
{
gchar *parasite_data;
guint32 parasite_size;
parasite_data = (gchar *) pika_parasite_get_data (parasite, &parasite_size);
g_strlcpy (info.description, parasite_data,
MIN (sizeof (info.description), parasite_size));
pika_parasite_free (parasite);
}
else
{
gchar *name = g_path_get_basename (pika_file_get_utf8_name (file));
if (g_str_has_suffix (name, ".gih"))
name[strlen (name) - 4] = '\0';
if (strlen (name))
g_strlcpy (info.description, name, sizeof (info.description));
g_free (name);
}
parasite = pika_image_get_parasite (orig_image,
"pika-brush-pipe-spacing");
if (parasite)
{
gchar *parasite_data;
guint32 parasite_size;
parasite_data = (gchar *) pika_parasite_get_data (parasite, &parasite_size);
parasite_data = g_strndup (parasite_data, parasite_size);
info.spacing = atoi (parasite_data);
pika_parasite_free (parasite);
g_free (parasite_data);
}
break;
default:
break;
}
g_free (pika_image_get_layers (image, &num_layers));
pika_pixpipe_params_init (&gihparams);
switch (run_mode)
{
case PIKA_RUN_INTERACTIVE:
gihparams.ncells = (num_layers * gihparams.rows * gihparams.cols);
gihparams.cellwidth = pika_image_get_width (image) / gihparams.cols;
gihparams.cellheight = pika_image_get_height (image) / gihparams.rows;
parasite = pika_image_get_parasite (orig_image,
"pika-brush-pipe-parameters");
if (parasite)
{
gchar *parasite_data;
guint32 parasite_size;
parasite_data = (gchar *) pika_parasite_get_data (parasite, &parasite_size);
parasite_data = g_strndup (parasite_data, parasite_size);
pika_pixpipe_params_parse (parasite_data, &gihparams);
pika_parasite_free (parasite);
g_free (parasite_data);
}
/* Force default rank to same as number of cells if there is
* just one dim
*/
if (gihparams.dim == 1)
gihparams.rank[0] = gihparams.ncells;
if (! gih_save_dialog (image))
{
status = PIKA_PDB_CANCEL;
goto out;
}
break;
case PIKA_RUN_NONINTERACTIVE:
info.spacing = PIKA_VALUES_GET_INT (args, 0);
g_strlcpy (info.description,
PIKA_VALUES_GET_STRING (args, 1),
sizeof (info.description));
gihparams.cellwidth = PIKA_VALUES_GET_INT (args, 2);
gihparams.cellheight = PIKA_VALUES_GET_INT (args, 3);
gihparams.cols = PIKA_VALUES_GET_INT (args, 4);
gihparams.rows = PIKA_VALUES_GET_INT (args, 5);
rank_bytes = PIKA_VALUES_GET_BYTES (args, 6);
gihparams.dim = g_bytes_get_size (rank_bytes);
gihparams.ncells = 1;
if (PIKA_VALUES_GET_INT (args, 7) != gihparams.dim)
{
status = PIKA_PDB_CALLING_ERROR;
}
else
{
const guint8 *rank = g_bytes_get_data (rank_bytes, NULL);
const gchar **sel = PIKA_VALUES_GET_STRV (args, 8);
for (i = 0; i < gihparams.dim; i++)
{
gihparams.rank[i] = rank[i];
gihparams.selection[i] = g_strdup (sel[i]);
gihparams.ncells *= gihparams.rank[i];
}
}
break;
case PIKA_RUN_WITH_LAST_VALS:
parasite = pika_image_get_parasite (orig_image,
"pika-brush-pipe-parameters");
if (parasite)
{
gchar *parasite_data;
guint32 parasite_size;
parasite_data = (gchar *) pika_parasite_get_data (parasite, &parasite_size);
parasite_data = g_strndup (parasite_data, parasite_size);
pika_pixpipe_params_parse (parasite_data, &gihparams);
pika_parasite_free (parasite);
g_free (parasite_data);
}
break;
}
if (status == PIKA_PDB_SUCCESS)
{
PikaValueArray *save_retvals;
gchar spacing[8];
gchar *paramstring;
PikaValueArray *args;
paramstring = pika_pixpipe_params_build (&gihparams);
args = pika_value_array_new_from_types (NULL,
PIKA_TYPE_RUN_MODE, PIKA_RUN_NONINTERACTIVE,
PIKA_TYPE_IMAGE, image,
G_TYPE_INT, n_drawables,
PIKA_TYPE_OBJECT_ARRAY, NULL,
G_TYPE_FILE, file,
G_TYPE_INT, info.spacing,
G_TYPE_STRING, info.description,
G_TYPE_STRING, paramstring,
G_TYPE_NONE);
pika_value_set_object_array (pika_value_array_index (args, 3),
PIKA_TYPE_ITEM, (GObject **) drawables, n_drawables);
save_retvals = pika_pdb_run_procedure_array (pika_get_pdb (),
"file-gih-save-internal",
args);
pika_value_array_unref (args);
if (PIKA_VALUES_GET_ENUM (save_retvals, 0) == PIKA_PDB_SUCCESS)
{
pika_set_data (SAVE_PROC, &info, sizeof (info));
parasite = pika_parasite_new ("pika-brush-pipe-name",
PIKA_PARASITE_PERSISTENT,
strlen (info.description) + 1,
info.description);
pika_image_attach_parasite (orig_image, parasite);
pika_parasite_free (parasite);
g_snprintf (spacing, sizeof (spacing), "%d",
info.spacing);
parasite = pika_parasite_new ("pika-brush-pipe-spacing",
PIKA_PARASITE_PERSISTENT,
strlen (spacing) + 1, spacing);
pika_image_attach_parasite (orig_image, parasite);
pika_parasite_free (parasite);
parasite = pika_parasite_new ("pika-brush-pipe-parameters",
PIKA_PARASITE_PERSISTENT,
strlen (paramstring) + 1,
paramstring);
pika_image_attach_parasite (orig_image, parasite);
pika_parasite_free (parasite);
}
else
{
g_set_error (&error, 0, 0,
"Running procedure 'file-gih-save-internal' "
"failed: %s",
pika_pdb_get_last_error (pika_get_pdb ()));
status = PIKA_PDB_EXECUTION_ERROR;
}
g_free (paramstring);
}
pika_pixpipe_params_free (&gihparams);
out:
if (export == PIKA_EXPORT_EXPORT)
{
pika_image_delete (image);
g_free (drawables);
}
return pika_procedure_new_return_values (procedure, status, error);
}
/* save routines */
static void
size_adjustment_callback (GtkAdjustment *adjustment,
SizeAdjustmentData *adj)
{
gint i;
gint size;
gint newn;
gchar buf[10];
for (i = 0; i < adj->nguides; i++)
pika_image_delete_guide (adj->image, adj->guides[i]);
g_free (adj->guides);
adj->guides = NULL;
pika_displays_flush ();
*(adj->value) = gtk_adjustment_get_value (adjustment);
if (adj->orientation == PIKA_ORIENTATION_VERTICAL)
{
size = pika_image_get_width (adj->image);
newn = size / *(adj->value);
adj->nguides = newn - 1;
adj->guides = g_new (gint32, adj->nguides);
for (i = 0; i < adj->nguides; i++)
adj->guides[i] = pika_image_add_vguide (adj->image,
*(adj->value) * (i+1));
}
else
{
size = pika_image_get_height (adj->image);
newn = size / *(adj->value);
adj->nguides = newn - 1;
adj->guides = g_new (gint32, adj->nguides);
for (i = 0; i < adj->nguides; i++)
adj->guides[i] = pika_image_add_hguide (adj->image,
*(adj->value) * (i+1));
}
pika_displays_flush ();
g_snprintf (buf, sizeof (buf), "%2d", newn);
gtk_label_set_text (GTK_LABEL (adj->count_label), buf);
*(adj->count) = newn;
gtk_widget_set_visible (GTK_WIDGET (adj->warning_label),
newn * *(adj->value) != size);
if (adj->ncells != NULL)
gtk_adjustment_set_value (adj->ncells,
*(adj->other_count) * *(adj->count));
if (adj->rank0 != NULL)
gtk_adjustment_set_value (adj->rank0,
*(adj->other_count) * *(adj->count));
}
static void
entry_callback (GtkWidget *widget,
gpointer data)
{
if (data == info.description)
g_strlcpy (info.description, gtk_entry_get_text (GTK_ENTRY (widget)),
sizeof (info.description));
}
static void
cb_callback (GtkWidget *widget,
gpointer data)
{
gint index;
index = gtk_combo_box_get_active (GTK_COMBO_BOX (widget));
*((const gchar **) data) = selection_modes [index];
}
static void
dim_callback (GtkAdjustment *adjustment,
SizeAdjustmentData *data)
{
gint i;
gihparams.dim = RINT (gtk_adjustment_get_value (adjustment));
for (i = 0; i < PIKA_PIXPIPE_MAXDIM; i++)
{
gtk_widget_set_sensitive (data->rank_entry[i], i < gihparams.dim);
gtk_widget_set_sensitive (data->mode_entry[i], i < gihparams.dim);
}
}
static gboolean
gih_save_dialog (PikaImage *image)
{
GtkWidget *dialog;
GtkWidget *grid;
GtkWidget *dimgrid;
GtkWidget *label;
GtkAdjustment *adjustment;
GtkWidget *spinbutton;
GtkWidget *entry;
GtkWidget *box;
GtkWidget *cb;
gint i;
gchar buffer[100];
SizeAdjustmentData cellw_adjust;
SizeAdjustmentData cellh_adjust;
GList *layers;
gboolean run;
dialog = pika_export_dialog_new (_("Brush Pipe"), PLUG_IN_BINARY, SAVE_PROC);
/* The main grid */
grid = gtk_grid_new ();
gtk_grid_set_row_spacing (GTK_GRID (grid), 6);
gtk_grid_set_column_spacing (GTK_GRID (grid), 6);
gtk_container_set_border_width (GTK_CONTAINER (grid), 12);
gtk_box_pack_start (GTK_BOX (pika_export_dialog_get_content_area (dialog)),
grid, TRUE, TRUE, 0);
gtk_widget_show (grid);
/*
* Description: ___________
*/
entry = gtk_entry_new ();
gtk_widget_set_size_request (entry, 200, -1);
gtk_entry_set_text (GTK_ENTRY (entry), info.description);
pika_grid_attach_aligned (GTK_GRID (grid), 0, 0,
_("_Description:"), 0.0, 0.5,
entry, 1);
g_signal_connect (entry, "changed",
G_CALLBACK (entry_callback),
info.description);
/*
* Spacing: __
*/
adjustment = gtk_adjustment_new (info.spacing, 1, 1000, 1, 10, 0);
spinbutton = pika_spin_button_new (adjustment, 1.0, 0);
gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbutton), TRUE);
pika_grid_attach_aligned (GTK_GRID (grid), 0, 1,
_("_Spacing (percent):"), 0.0, 0.5,
spinbutton, 1);
g_signal_connect (adjustment, "value-changed",
G_CALLBACK (pika_int_adjustment_update),
&info.spacing);
/*
* Cell size: __ x __ pixels
*/
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
adjustment = gtk_adjustment_new (gihparams.cellwidth,
2, pika_image_get_width (image), 1, 10, 0);
spinbutton = pika_spin_button_new (adjustment, 1.0, 0);
gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbutton), TRUE);
gtk_box_pack_start (GTK_BOX (box), spinbutton, FALSE, FALSE, 0);
gtk_widget_show (spinbutton);
layers = pika_image_list_layers (image);
cellw_adjust.orientation = PIKA_ORIENTATION_VERTICAL;
cellw_adjust.image = image;
cellw_adjust.toplayer = g_list_last (layers)->data;
cellw_adjust.nguides = 0;
cellw_adjust.guides = NULL;
cellw_adjust.value = &gihparams.cellwidth;
g_signal_connect (adjustment, "value-changed",
G_CALLBACK (size_adjustment_callback),
&cellw_adjust);
label = gtk_label_new ("x");
gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 0);
gtk_widget_show (label);
adjustment = gtk_adjustment_new (gihparams.cellheight,
2, pika_image_get_height (image), 1, 10, 0);
spinbutton = pika_spin_button_new (adjustment, 1.0, 0);
gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbutton), TRUE);
gtk_box_pack_start (GTK_BOX (box), spinbutton, FALSE, FALSE, 0);
gtk_widget_show (spinbutton);
cellh_adjust.orientation = PIKA_ORIENTATION_HORIZONTAL;
cellh_adjust.image = image;
cellh_adjust.toplayer = g_list_last (layers)->data;
cellh_adjust.nguides = 0;
cellh_adjust.guides = NULL;
cellh_adjust.value = &gihparams.cellheight;
g_signal_connect (adjustment, "value-changed",
G_CALLBACK (size_adjustment_callback),
&cellh_adjust);
label = gtk_label_new ( _("Pixels"));
gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 0);
gtk_widget_show (label);
pika_grid_attach_aligned (GTK_GRID (grid), 0, 2,
_("Ce_ll size:"), 0.0, 0.5,
box, 1);
g_list_free (layers);
/*
* Number of cells: ___
*/
adjustment = gtk_adjustment_new (gihparams.ncells, 1, 1000, 1, 10, 0);
spinbutton = pika_spin_button_new (adjustment, 1.0, 0);
gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbutton), TRUE);
pika_grid_attach_aligned (GTK_GRID (grid), 0, 3,
_("_Number of cells:"), 0.0, 0.5,
spinbutton, 1);
g_signal_connect (adjustment, "value-changed",
G_CALLBACK (pika_int_adjustment_update),
&gihparams.ncells);
if (gihparams.dim == 1)
cellw_adjust.ncells = cellh_adjust.ncells = adjustment;
else
cellw_adjust.ncells = cellh_adjust.ncells = NULL;
/*
* Display as: __ rows x __ cols
*/
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
g_snprintf (buffer, sizeof (buffer), "%2d", gihparams.rows);
label = gtk_label_new (buffer);
gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 0);
cellh_adjust.count_label = label;
cellh_adjust.count = &gihparams.rows;
cellh_adjust.other_count = &gihparams.cols;
gtk_widget_show (label);
label = gtk_label_new (_(" Rows of "));
gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 0);
gtk_widget_show (label);
g_snprintf (buffer, sizeof (buffer), "%2d", gihparams.cols);
label = gtk_label_new (buffer);
gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 0);
cellw_adjust.count_label = label;
cellw_adjust.count = &gihparams.cols;
cellw_adjust.other_count = &gihparams.rows;
gtk_widget_show (label);
label = gtk_label_new (_(" Columns on each layer"));
gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 0);
gtk_widget_show (label);
label = gtk_label_new (_(" (Width Mismatch!) "));
gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 0);
cellw_adjust.warning_label = label;
label = gtk_label_new (_(" (Height Mismatch!) "));
gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 0);
cellh_adjust.warning_label = label;
pika_grid_attach_aligned (GTK_GRID (grid), 0, 4,
_("Display as:"), 0.0, 0.5,
box, 1);
/*
* Dimension: ___
*/
adjustment = gtk_adjustment_new (gihparams.dim,
1, PIKA_PIXPIPE_MAXDIM, 1, 1, 0);
spinbutton = pika_spin_button_new (adjustment, 1.0, 0);
gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbutton), TRUE);
pika_grid_attach_aligned (GTK_GRID (grid), 0, 5,
_("Di_mension:"), 0.0, 0.5,
spinbutton, 1);
g_signal_connect (adjustment, "value-changed",
G_CALLBACK (dim_callback),
&cellw_adjust);
/*
* Ranks / Selection: ______ ______ ______ ______ ______
*/
dimgrid = gtk_grid_new ();
gtk_grid_set_column_spacing (GTK_GRID (dimgrid), 4);
for (i = 0; i < PIKA_PIXPIPE_MAXDIM; i++)
{
gsize j;
adjustment = gtk_adjustment_new (gihparams.rank[i], 1, 100, 1, 1, 0);
spinbutton = pika_spin_button_new (adjustment, 1.0, 0);
gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbutton), TRUE);
gtk_grid_attach (GTK_GRID (dimgrid), spinbutton, 0, i, 1, 1);
gtk_widget_show (spinbutton);
if (i >= gihparams.dim)
gtk_widget_set_sensitive (spinbutton, FALSE);
g_signal_connect (adjustment, "value-changed",
G_CALLBACK (pika_int_adjustment_update),
&gihparams.rank[i]);
cellw_adjust.rank_entry[i] = cellh_adjust.rank_entry[i] = spinbutton;
if (i == 0)
{
if (gihparams.dim == 1)
cellw_adjust.rank0 = cellh_adjust.rank0 = adjustment;
else
cellw_adjust.rank0 = cellh_adjust.rank0 = NULL;
}
cb = gtk_combo_box_text_new ();
for (j = 0; j < G_N_ELEMENTS (selection_modes); j++)
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (cb),
selection_modes[j]);
gtk_combo_box_set_active (GTK_COMBO_BOX (cb), 2); /* random */
if (gihparams.selection[i])
for (j = 0; j < G_N_ELEMENTS (selection_modes); j++)
if (!strcmp (gihparams.selection[i], selection_modes[j]))
{
gtk_combo_box_set_active (GTK_COMBO_BOX (cb), j);
break;
}
gtk_grid_attach (GTK_GRID (dimgrid), cb, 1, i, 1, 1);
gtk_widget_show (cb);
if (i >= gihparams.dim)
gtk_widget_set_sensitive (cb, FALSE);
g_signal_connect (GTK_COMBO_BOX (cb), "changed",
G_CALLBACK (cb_callback),
&gihparams.selection[i]);
cellw_adjust.mode_entry[i] = cellh_adjust.mode_entry[i] = cb;
}
pika_grid_attach_aligned (GTK_GRID (grid), 0, 6,
_("Ranks:"), 0.0, 0.0,
dimgrid, 1);
gtk_widget_show (dialog);
run = (pika_dialog_run (PIKA_DIALOG (dialog)) == GTK_RESPONSE_OK);
if (run)
{
gint i;
for (i = 0; i < PIKA_PIXPIPE_MAXDIM; i++)
gihparams.selection[i] = g_strdup (gihparams.selection[i]);
/* Fix up bogus values */
gihparams.ncells = MIN (gihparams.ncells,
num_layers * gihparams.rows * gihparams.cols);
}
gtk_widget_destroy (dialog);
for (i = 0; i < cellw_adjust.nguides; i++)
pika_image_delete_guide (image, cellw_adjust.guides[i]);
for (i = 0; i < cellh_adjust.nguides; i++)
pika_image_delete_guide (image, cellh_adjust.guides[i]);
return run;
}