PIKApp/plug-ins/fractal-explorer/fractal-explorer-dialogs.c

1897 lines
58 KiB
C

/**********************************************************************
PIKA - Photo and Image Kooker Application
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 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/>.
*********************************************************************/
#include "config.h"
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <glib/gstdio.h>
#include <libpika/pika.h>
#include <libpika/pikaui.h>
#include "fractal-explorer.h"
#include "fractal-explorer-dialogs.h"
#include "libpika/stdplugins-intl.h"
#define ZOOM_UNDO_SIZE 100
static gint n_gradient_samples = 0;
static gdouble *gradient_samples = NULL;
static PikaGradient *gradient = NULL;
static gboolean ready_now = FALSE;
static gchar *tpath = NULL;
static GtkWidget *cmap_preview;
static GtkWidget *maindlg;
static explorer_vals_t zooms[ZOOM_UNDO_SIZE];
static gint zoomindex = 0;
static gint zoommax = 0;
static gint oldxpos = -1;
static gint oldypos = -1;
static gdouble x_press = -1.0;
static gdouble y_press = -1.0;
static explorer_vals_t standardvals =
{
0,
-2.0,
2.0,
-1.5,
1.5,
50.0,
-0.75,
-0.2,
0,
1.0,
1.0,
1.0,
1,
1,
0,
0,
0,
0,
1,
256,
0
};
/**********************************************************************
FORWARD DECLARATIONS
*********************************************************************/
static void update_preview (PikaProcedureConfig *config);
static void load_file_chooser_response (GtkFileChooser *chooser,
gint response_id,
gpointer data);
static void save_file_chooser_response (GtkFileChooser *chooser,
gint response_id,
gpointer data);
static void create_load_file_chooser (GtkWidget *widget,
GtkWidget *dialog);
static void create_save_file_chooser (GtkWidget *widget,
GtkWidget *dialog);
static void cmap_preview_size_allocate (GtkWidget *widget,
GtkAllocation *allocation,
PikaProcedureConfig *config);
/**********************************************************************
CALLBACKS
*********************************************************************/
static void
update_preview (PikaProcedureConfig *config)
{
set_cmap_preview (config);
dialog_update_preview (config);
}
static void
dialog_redraw_callback (GtkWidget *widget,
gpointer data)
{
PikaProcedureConfig *config = (PikaProcedureConfig *) data;
gint alwaysprev = wvals.alwayspreview;
wvals.alwayspreview = TRUE;
set_cmap_preview (config);
dialog_update_preview (config);
wvals.alwayspreview = alwaysprev;
}
static void
dialog_undo_zoom_callback (GtkWidget *widget,
gpointer data)
{
PikaProcedureConfig *config = (PikaProcedureConfig *) data;
if (zoomindex > 0)
{
g_object_get (config,
"xmin", &wvals.xmin,
"xmax", &wvals.xmax,
"ymin", &wvals.ymin,
"ymax", &wvals.ymax,
NULL);
zooms[zoomindex] = wvals;
zoomindex--;
wvals = zooms[zoomindex];
g_object_set (config,
"xmin", wvals.xmin,
"xmax", wvals.xmax,
"ymin", wvals.ymin,
"ymax", wvals.ymax,
NULL);
set_cmap_preview (config);
dialog_update_preview (config);
}
}
static void
dialog_redo_zoom_callback (GtkWidget *widget,
gpointer data)
{
PikaProcedureConfig *config = (PikaProcedureConfig *) data;
if (zoomindex < zoommax)
{
zoomindex++;
wvals = zooms[zoomindex];
g_object_set (config,
"xmin", wvals.xmin,
"xmax", wvals.xmax,
"ymin", wvals.ymin,
"ymax", wvals.ymax,
NULL);
set_cmap_preview (config);
dialog_update_preview (config);
}
}
static void
dialog_step_in_callback (GtkWidget *widget,
gpointer data)
{
PikaProcedureConfig *config = (PikaProcedureConfig *) data;
gdouble xdifferenz;
gdouble ydifferenz;
gdouble xmin;
gdouble xmax;
gdouble ymin;
gdouble ymax;
g_object_get (config,
"xmin", &xmin,
"xmax", &xmax,
"ymin", &ymin,
"ymax", &ymax,
NULL);
if (zoomindex < ZOOM_UNDO_SIZE - 1)
{
g_object_get (config,
"xmin", &wvals.xmin,
"xmax", &wvals.xmax,
"ymin", &wvals.ymin,
"ymax", &wvals.ymax,
NULL);
zooms[zoomindex] = wvals;
zoomindex++;
}
zoommax = zoomindex;
xdifferenz = xmax - xmin;
ydifferenz = ymax - ymin;
xmin += 1.0 / 6.0 * xdifferenz;
ymin += 1.0 / 6.0 * ydifferenz;
xmax -= 1.0 / 6.0 * xdifferenz;
ymax -= 1.0 / 6.0 * ydifferenz;
wvals.xmin = xmin;
wvals.xmax = xmax;
wvals.ymin = ymin;
wvals.ymax = ymax;
zooms[zoomindex] = wvals;
g_object_set (config,
"xmin", xmin,
"xmax", xmax,
"ymin", ymin,
"ymax", ymax,
NULL);
set_cmap_preview (config);
dialog_update_preview (config);
}
static void
dialog_step_out_callback (GtkWidget *widget,
gpointer data)
{
PikaProcedureConfig *config = (PikaProcedureConfig *) data;
gdouble xdifferenz;
gdouble ydifferenz;
gdouble xmin;
gdouble xmax;
gdouble ymin;
gdouble ymax;
g_object_get (config,
"xmin", &xmin,
"xmax", &xmax,
"ymin", &ymin,
"ymax", &ymax,
NULL);
if (zoomindex < ZOOM_UNDO_SIZE - 1)
{
g_object_get (config,
"xmin", &wvals.xmin,
"xmax", &wvals.xmax,
"ymin", &wvals.ymin,
"ymax", &wvals.ymax,
NULL);
zooms[zoomindex] = wvals;
zoomindex++;
}
zoommax = zoomindex;
xdifferenz = xmax - xmin;
ydifferenz = ymax - ymin;
xmin -= 1.0 / 4.0 * xdifferenz;
ymin -= 1.0 / 4.0 * ydifferenz;
xmax += 1.0 / 4.0 * xdifferenz;
ymax += 1.0 / 4.0 * ydifferenz;
wvals.xmin = xmin;
wvals.xmax = xmax;
wvals.ymin = ymin;
wvals.ymax = ymax;
zooms[zoomindex] = wvals;
g_object_set (config,
"xmin", xmin,
"xmax", xmax,
"ymin", ymin,
"ymax", ymax,
NULL);
set_cmap_preview (config);
dialog_update_preview (config);
}
static void
explorer_toggle_update (GtkWidget *widget,
gpointer data)
{
pika_toggle_button_update (widget, data);
set_cmap_preview (wvals.config);
dialog_update_preview (wvals.config);
}
static void
explorer_radio_update (GtkWidget *widget,
gpointer data)
{
gboolean c_sensitive;
gint fractal_type;
fractal_type =
pika_procedure_config_get_choice_id (wvals.config, "fractal-type");
switch (fractal_type)
{
case TYPE_MANDELBROT:
case TYPE_SIERPINSKI:
c_sensitive = FALSE;
break;
default:
c_sensitive = TRUE;
break;
}
pika_procedure_dialog_set_sensitive (PIKA_PROCEDURE_DIALOG (maindlg),
"cx",
c_sensitive, NULL, NULL, FALSE);
pika_procedure_dialog_set_sensitive (PIKA_PROCEDURE_DIALOG (maindlg),
"cy",
c_sensitive, NULL, NULL, FALSE);
set_cmap_preview (wvals.config);
dialog_update_preview (wvals.config);
}
static void
explorer_number_of_colors_callback (PikaProcedureConfig *config)
{
gint n_colors;
g_object_get (config,
"n-colors", &n_colors,
NULL);
g_free (gradient_samples);
if (! gradient)
gradient = pika_context_get_gradient ();
pika_gradient_get_uniform_samples (gradient,
n_colors,
FALSE,
&n_gradient_samples,
&gradient_samples);
set_cmap_preview (config);
dialog_update_preview (config);
}
/* Same signature as all PikaResourceSelectButton */
static void
explorer_gradient_select_callback (gpointer data, /* config */
PikaGradient *gradient,
gboolean dialog_closing)
{
PikaProcedureConfig *config = (PikaProcedureConfig *) data;
gint n_colors;
gint color_mode;
g_object_get (config,
"n-colors", &n_colors,
"color-mode", &color_mode,
NULL);
g_free (gradient_samples);
pika_gradient_get_uniform_samples (gradient,
n_colors,
FALSE,
&n_gradient_samples,
&gradient_samples);
if (color_mode == 1)
{
set_cmap_preview (config);
dialog_update_preview (config);
}
}
static void
preview_draw_crosshair (gint px,
gint py)
{
gint x, y;
guchar *p_ul;
p_ul = wint.wimage + 3 * (preview_width * py + 0);
for (x = 0; x < preview_width; x++)
{
p_ul[0] ^= 254;
p_ul[1] ^= 254;
p_ul[2] ^= 254;
p_ul += 3;
}
p_ul = wint.wimage + 3 * (preview_width * 0 + px);
for (y = 0; y < preview_height; y++)
{
p_ul[0] ^= 254;
p_ul[1] ^= 254;
p_ul[2] ^= 254;
p_ul += 3 * preview_width;
}
}
static void
preview_redraw (void)
{
pika_preview_area_draw (PIKA_PREVIEW_AREA (wint.preview),
0, 0, preview_width, preview_height,
PIKA_RGB_IMAGE,
wint.wimage, preview_width * 3);
gtk_widget_queue_draw (wint.preview);
}
static gboolean
preview_button_press_event (GtkWidget *widget,
GdkEventButton *event)
{
if (event->button == 1)
{
x_press = event->x;
y_press = event->y;
xbild = preview_width;
ybild = preview_height;
xdiff = (xmax - xmin) / xbild;
ydiff = (ymax - ymin) / ybild;
preview_draw_crosshair (x_press, y_press);
preview_redraw ();
}
return TRUE;
}
static gboolean
preview_motion_notify_event (GtkWidget *widget,
GdkEventButton *event)
{
if (oldypos != -1)
{
preview_draw_crosshair (oldxpos, oldypos);
}
oldxpos = event->x;
oldypos = event->y;
if ((oldxpos >= 0.0) &&
(oldypos >= 0.0) &&
(oldxpos < preview_width) &&
(oldypos < preview_height))
{
preview_draw_crosshair (oldxpos, oldypos);
}
else
{
oldypos = -1;
oldxpos = -1;
}
preview_redraw ();
return TRUE;
}
static gboolean
preview_leave_notify_event (GtkWidget *widget,
GdkEventButton *event)
{
if (oldypos != -1)
{
preview_draw_crosshair (oldxpos, oldypos);
}
oldxpos = -1;
oldypos = -1;
preview_redraw ();
gdk_window_set_cursor (gtk_widget_get_window (maindlg), NULL);
return TRUE;
}
static gboolean
preview_enter_notify_event (GtkWidget *widget,
GdkEventButton *event)
{
static GdkCursor *cursor = NULL;
if (! cursor)
{
GdkDisplay *display = gtk_widget_get_display (maindlg);
cursor = gdk_cursor_new_for_display (display, GDK_TCROSS);
}
gdk_window_set_cursor (gtk_widget_get_window (maindlg), cursor);
return TRUE;
}
static gboolean
preview_button_release_event (GtkWidget *widget,
GdkEventButton *event,
gpointer data)
{
PikaProcedureConfig *config = (PikaProcedureConfig *) data;
gdouble l_xmin;
gdouble l_xmax;
gdouble l_ymin;
gdouble l_ymax;
gdouble xmin;
gdouble xmax;
gdouble ymin;
gdouble ymax;
g_object_get (config,
"xmin", &xmin,
"xmax", &xmax,
"ymin", &ymin,
"ymax", &ymax,
NULL);
if (event->button == 1)
{
gdouble x_release, y_release;
x_release = event->x;
y_release = event->y;
if ((x_press >= 0.0) && (y_press >= 0.0) &&
(x_release >= 0.0) && (y_release >= 0.0) &&
(x_press < preview_width) && (y_press < preview_height) &&
(x_release < preview_width) && (y_release < preview_height))
{
l_xmin = (xmin + (xmax -xmin) * (x_press / preview_width));
l_xmax = (xmin + (xmax - xmin) * (x_release / preview_width));
l_ymin = (ymin + (ymax - ymin) * (y_press / preview_height));
l_ymax = (ymin + (ymax - ymin) * (y_release / preview_height));
if (zoomindex < ZOOM_UNDO_SIZE - 1)
{
wvals.xmin = l_xmin;
wvals.xmax = l_xmax;
wvals.ymin = l_ymin;
wvals.ymax = l_ymax;
zooms[zoomindex] = wvals;
zoomindex++;
}
zoommax = zoomindex;
g_object_set (config,
"xmin", l_xmin,
"xmax", l_xmax,
"ymin", l_ymin,
"ymax", l_ymax,
NULL);
dialog_update_preview (config);
oldypos = oldxpos = -1;
}
}
return TRUE;
}
/**********************************************************************
FUNCTION: explorer_dialog
*********************************************************************/
gint
explorer_dialog (PikaProcedure *procedure,
PikaProcedureConfig *config)
{
GtkWidget *dialog;
GtkWidget *top_hbox;
GtkWidget *left_vbox;
GtkWidget *vbox;
GtkWidget *bbox;
GtkWidget *frame;
GtkWidget *toggle;
GtkWidget *hbox;
GtkWidget *button;
GtkWidget *gradient_button;
gchar *path;
PikaGradient *gradient;
GtkListStore *store;
gint n_colors;
pika_ui_init (PLUG_IN_BINARY);
path = pika_pikarc_query ("fractalexplorer-path");
if (path)
{
fractalexplorer_path = g_filename_from_utf8 (path, -1, NULL, NULL, NULL);
g_free (path);
}
else
{
GFile *pikarc = pika_directory_file ("pikarc", NULL);
gchar *full_path = pika_config_build_data_path ("fractalexplorer");
gchar *esc_path = g_strescape (full_path, NULL);
g_free (full_path);
g_message (_("No %s in pikarc:\n"
"You need to add an entry like\n"
"(%s \"%s\")\n"
"to your %s file."),
"fractalexplorer-path",
"fractalexplorer-path",
esc_path, pika_file_get_utf8_name (pikarc));
g_object_unref (pikarc);
g_free (esc_path);
}
wint.wimage = g_new (guchar, preview_width * preview_height * 3);
dialog = maindlg = pika_procedure_dialog_new (procedure,
PIKA_PROCEDURE_CONFIG (config),
_("Fractal Explorer"));
top_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
gtk_widget_set_vexpand (top_hbox, FALSE);
gtk_container_set_border_width (GTK_CONTAINER (top_hbox), 12);
gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))),
top_hbox, FALSE, FALSE, 0);
gtk_widget_show (top_hbox);
left_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
gtk_widget_show (left_vbox);
/* Preview */
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
gtk_box_pack_start (GTK_BOX (left_vbox), vbox, FALSE, FALSE, 0);
gtk_widget_show (vbox);
frame = gtk_frame_new (NULL);
gtk_widget_set_halign (frame, GTK_ALIGN_START);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
gtk_widget_show (frame);
wint.preview = pika_preview_area_new ();
gtk_widget_set_size_request (wint.preview, preview_width, preview_height);
gtk_container_add (GTK_CONTAINER (frame), wint.preview);
g_signal_connect (wint.preview, "button-press-event",
G_CALLBACK (preview_button_press_event),
NULL);
g_signal_connect (wint.preview, "button-release-event",
G_CALLBACK (preview_button_release_event),
config);
g_signal_connect (wint.preview, "motion-notify-event",
G_CALLBACK (preview_motion_notify_event),
NULL);
g_signal_connect (wint.preview, "leave-notify-event",
G_CALLBACK (preview_leave_notify_event),
NULL);
g_signal_connect (wint.preview, "enter-notify-event",
G_CALLBACK (preview_enter_notify_event),
NULL);
gtk_widget_set_events (wint.preview, (GDK_BUTTON_PRESS_MASK |
GDK_BUTTON_RELEASE_MASK |
GDK_POINTER_MOTION_MASK |
GDK_LEAVE_NOTIFY_MASK |
GDK_ENTER_NOTIFY_MASK));
gtk_widget_show (wint.preview);
toggle = gtk_check_button_new_with_mnemonic (_("Re_altime preview"));
gtk_box_pack_start (GTK_BOX (vbox), toggle, FALSE, FALSE, 0);
g_signal_connect (toggle, "toggled",
G_CALLBACK (explorer_toggle_update),
&wvals.alwayspreview);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
wvals.alwayspreview);
gtk_widget_show (toggle);
pika_help_set_help_data (toggle, _("If enabled the preview will "
"be redrawn automatically"), NULL);
button = gtk_button_new_with_mnemonic (_("R_edraw preview"));
gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
g_signal_connect (button, "clicked",
G_CALLBACK (dialog_redraw_callback),
config);
gtk_widget_show (button);
/* Zoom Options */
frame = pika_frame_new (_("Zoom"));
gtk_box_pack_start (GTK_BOX (left_vbox), frame, FALSE, FALSE, 0);
gtk_widget_show (frame);
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
gtk_container_add (GTK_CONTAINER (frame), vbox);
gtk_widget_show (vbox);
bbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
gtk_box_set_homogeneous (GTK_BOX (bbox), TRUE);
gtk_box_pack_start (GTK_BOX (vbox), bbox, FALSE, FALSE, 0);
gtk_widget_show (bbox);
button = gtk_button_new_with_mnemonic (_("Zoom _In"));
gtk_box_pack_start (GTK_BOX (bbox), button, TRUE, TRUE, 0);
gtk_widget_show (button);
g_signal_connect (button, "clicked",
G_CALLBACK (dialog_step_in_callback),
config);
button = gtk_button_new_with_mnemonic (_("Zoom _Out"));
gtk_box_pack_start (GTK_BOX (bbox), button, TRUE, TRUE, 0);
gtk_widget_show (button);
g_signal_connect (button, "clicked",
G_CALLBACK (dialog_step_out_callback),
config);
bbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
gtk_box_set_homogeneous (GTK_BOX (bbox), TRUE);
gtk_box_pack_start (GTK_BOX (vbox), bbox, FALSE, FALSE, 0);
gtk_widget_show (bbox);
button = gtk_button_new_with_mnemonic (_("_Undo"));
gtk_box_pack_start (GTK_BOX (bbox), button, TRUE, TRUE, 0);
gtk_widget_show (button);
pika_help_set_help_data (button, _("Undo last zoom change"), NULL);
g_signal_connect (button, "clicked",
G_CALLBACK (dialog_undo_zoom_callback),
config);
button = gtk_button_new_with_mnemonic (_("_Redo"));
gtk_box_pack_start (GTK_BOX (bbox), button, TRUE, TRUE, 0);
gtk_widget_show (button);
pika_help_set_help_data (button, _("Redo last zoom change"), NULL);
g_signal_connect (button, "clicked",
G_CALLBACK (dialog_redo_zoom_callback),
config);
/* Create notebook */
pika_procedure_dialog_get_label (PIKA_PROCEDURE_DIALOG (dialog),
"parameter-tab", _("_Parameters"), FALSE, TRUE);
pika_procedure_dialog_get_label (PIKA_PROCEDURE_DIALOG (dialog),
"color-tab", _("_Colors"), FALSE, TRUE);
pika_procedure_dialog_get_label (PIKA_PROCEDURE_DIALOG (dialog),
"fractal-tab", _("_Fractals"), FALSE, TRUE);
/* "Parameters" page */
pika_procedure_dialog_get_scale_entry (PIKA_PROCEDURE_DIALOG (dialog),
"xmin", 1.0);
pika_procedure_dialog_get_scale_entry (PIKA_PROCEDURE_DIALOG (dialog),
"xmax", 1.0);
pika_procedure_dialog_get_scale_entry (PIKA_PROCEDURE_DIALOG (dialog),
"ymin", 1.0);
pika_procedure_dialog_get_scale_entry (PIKA_PROCEDURE_DIALOG (dialog),
"ymax", 1.0);
pika_procedure_dialog_get_scale_entry (PIKA_PROCEDURE_DIALOG (dialog),
"iter", 1.0);
pika_procedure_dialog_get_scale_entry (PIKA_PROCEDURE_DIALOG (dialog),
"cx", 1.0);
pika_procedure_dialog_get_scale_entry (PIKA_PROCEDURE_DIALOG (dialog),
"cy", 1.0);
pika_procedure_dialog_get_label (PIKA_PROCEDURE_DIALOG (dialog),
"parameter-input-label", _("Fractal Parameters"),
FALSE, FALSE);
pika_procedure_dialog_fill_box (PIKA_PROCEDURE_DIALOG (dialog),
"parameter-input-box",
"xmin", "xmax", "ymin", "ymax",
"iter", "cx", "cy",
NULL);
pika_procedure_dialog_fill_frame (PIKA_PROCEDURE_DIALOG (dialog),
"parameter-input-frame",
"parameter-input-label", FALSE,
"parameter-input-box");
pika_procedure_dialog_get_label (PIKA_PROCEDURE_DIALOG (dialog),
"parameter-type-label", _("Fractal Type"),
FALSE, FALSE);
pika_procedure_dialog_fill_box (PIKA_PROCEDURE_DIALOG (dialog),
"parameter-type-box",
"fractal-type",
NULL);
pika_procedure_dialog_fill_frame (PIKA_PROCEDURE_DIALOG (dialog),
"parameter-type-frame",
"parameter-type-label", FALSE,
"parameter-type-box");
vbox = pika_procedure_dialog_fill_box (PIKA_PROCEDURE_DIALOG (dialog),
"parameter-box",
"parameter-input-frame",
"parameter-type-frame",
NULL);
bbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
gtk_widget_set_margin_top (bbox, 12);
gtk_box_set_homogeneous (GTK_BOX (bbox), TRUE);
gtk_box_pack_start (GTK_BOX (vbox), bbox, TRUE, TRUE, 2);
gtk_box_reorder_child (GTK_BOX (vbox), bbox, 1);
gtk_widget_set_visible (bbox, TRUE);
button = gtk_button_new_with_mnemonic (_("_Open"));
gtk_box_pack_start (GTK_BOX (bbox), button, TRUE, TRUE, 0);
g_signal_connect (button, "clicked",
G_CALLBACK (create_load_file_chooser),
dialog);
gtk_widget_set_visible (button, TRUE);
pika_help_set_help_data (button, _("Load a fractal from file"), NULL);
button = gtk_button_new_with_mnemonic (_("_Save"));
gtk_box_pack_start (GTK_BOX (bbox), button, TRUE, TRUE, 0);
g_signal_connect (button, "clicked",
G_CALLBACK (create_save_file_chooser),
dialog);
gtk_widget_set_visible (button, TRUE);
pika_help_set_help_data (button, _("Save active fractal to file"), NULL);
g_signal_connect (config, "notify::xmin",
G_CALLBACK (update_preview),
config);
g_signal_connect (config, "notify::xmax",
G_CALLBACK (update_preview),
config);
g_signal_connect (config, "notify::ymin",
G_CALLBACK (update_preview),
config);
g_signal_connect (config, "notify::ymax",
G_CALLBACK (update_preview),
config);
g_signal_connect (config, "notify::iter",
G_CALLBACK (update_preview),
config);
g_signal_connect (config, "notify::cx",
G_CALLBACK (update_preview),
config);
g_signal_connect (config, "notify::cy",
G_CALLBACK (update_preview),
config);
g_signal_connect (config, "notify::fractal-type",
G_CALLBACK (explorer_radio_update),
config);
explorer_radio_update (NULL, NULL);
/* Colors Page */
pika_procedure_dialog_get_scale_entry (PIKA_PROCEDURE_DIALOG (dialog),
"n-colors", 1.0);
pika_procedure_dialog_get_label (PIKA_PROCEDURE_DIALOG (dialog),
"num-colors-label", _("Number of Colors"),
FALSE, FALSE);
pika_procedure_dialog_fill_box (PIKA_PROCEDURE_DIALOG (dialog),
"num-colors-box",
"n-colors",
"use-loglog-smoothing",
NULL);
pika_procedure_dialog_fill_frame (PIKA_PROCEDURE_DIALOG (dialog),
"num-colors-frame",
"num-colors-label", FALSE,
"num-colors-box");
pika_procedure_dialog_get_scale_entry (PIKA_PROCEDURE_DIALOG (dialog),
"red-stretch", 1.0);
pika_procedure_dialog_get_scale_entry (PIKA_PROCEDURE_DIALOG (dialog),
"green-stretch", 1.0);
pika_procedure_dialog_get_scale_entry (PIKA_PROCEDURE_DIALOG (dialog),
"blue-stretch", 1.0);
pika_procedure_dialog_get_label (PIKA_PROCEDURE_DIALOG (dialog),
"color-density-label", _("Color Density"),
FALSE, FALSE);
pika_procedure_dialog_fill_box (PIKA_PROCEDURE_DIALOG (dialog),
"color-density-box",
"red-stretch",
"green-stretch",
"blue-stretch",
NULL);
pika_procedure_dialog_fill_frame (PIKA_PROCEDURE_DIALOG (dialog),
"color-density-frame",
"color-density-label", FALSE,
"color-density-box");
pika_procedure_dialog_get_label (PIKA_PROCEDURE_DIALOG (dialog),
"color-function-label", _("Color Function"),
FALSE, FALSE);
pika_procedure_dialog_get_label (PIKA_PROCEDURE_DIALOG (dialog),
"red-function-label", _("Red"),
FALSE, FALSE);
pika_procedure_dialog_fill_box (PIKA_PROCEDURE_DIALOG (dialog),
"red-function-box",
"red-mode",
"red-invert",
NULL);
pika_procedure_dialog_fill_frame (PIKA_PROCEDURE_DIALOG (dialog),
"red-function-frame",
"red-function-label", FALSE,
"red-function-box");
pika_procedure_dialog_get_label (PIKA_PROCEDURE_DIALOG (dialog),
"green-function-label", _("Green"),
FALSE, FALSE);
pika_procedure_dialog_fill_box (PIKA_PROCEDURE_DIALOG (dialog),
"green-function-box",
"green-mode",
"green-invert",
NULL);
pika_procedure_dialog_fill_frame (PIKA_PROCEDURE_DIALOG (dialog),
"green-function-frame",
"green-function-label", FALSE,
"green-function-box");
pika_procedure_dialog_get_label (PIKA_PROCEDURE_DIALOG (dialog),
"blue-function-label", _("Blue"),
FALSE, FALSE);
pika_procedure_dialog_fill_box (PIKA_PROCEDURE_DIALOG (dialog),
"blue-function-box",
"blue-mode",
"blue-invert",
NULL);
pika_procedure_dialog_fill_frame (PIKA_PROCEDURE_DIALOG (dialog),
"blue-function-frame",
"blue-function-label", FALSE,
"blue-function-box");
hbox = pika_procedure_dialog_fill_box (PIKA_PROCEDURE_DIALOG (dialog),
"function-hbox",
"red-function-frame",
"green-function-frame",
"blue-function-frame",
NULL);
gtk_orientable_set_orientation (GTK_ORIENTABLE (hbox),
GTK_ORIENTATION_HORIZONTAL);
pika_procedure_dialog_fill_frame (PIKA_PROCEDURE_DIALOG (dialog),
"color-function-frame",
"color-function-label", FALSE,
"function-hbox");
store = pika_int_store_new (_("As specified above"), 0,
_("Apply active gradient to final image"), 1,
NULL);
pika_procedure_dialog_get_int_radio (PIKA_PROCEDURE_DIALOG (dialog),
"color-mode", PIKA_INT_STORE (store));
hbox = pika_procedure_dialog_fill_box (PIKA_PROCEDURE_DIALOG (dialog),
"color-mode-hbox",
"color-mode",
NULL);
gtk_orientable_set_orientation (GTK_ORIENTABLE (hbox),
GTK_ORIENTATION_HORIZONTAL);
g_object_get (config,
"n-colors", &n_colors,
NULL);
gradient = pika_context_get_gradient ();
pika_gradient_get_uniform_samples (gradient,
n_colors, FALSE,
&n_gradient_samples,
&gradient_samples);
gradient_button = pika_gradient_chooser_new (_("FractalExplorer Gradient"),
NULL, PIKA_RESOURCE (gradient));
g_signal_connect (gradient_button, "resource-set",
G_CALLBACK (explorer_gradient_select_callback), config);
gtk_box_pack_start (GTK_BOX (hbox), gradient_button, TRUE, TRUE, 0);
gtk_widget_set_visible (gradient_button, TRUE);
vbox = pika_procedure_dialog_fill_box (PIKA_PROCEDURE_DIALOG (dialog),
"color-box",
"num-colors-frame",
"color-density-frame",
"color-function-frame",
"color-mode-hbox",
NULL);
cmap_preview = pika_preview_area_new ();
gtk_widget_set_halign (cmap_preview, GTK_ALIGN_CENTER);
gtk_widget_set_valign (cmap_preview, GTK_ALIGN_CENTER);
gtk_widget_set_size_request (cmap_preview, 32, 32);
gtk_box_pack_start (GTK_BOX (vbox), cmap_preview, TRUE, TRUE, 0);
g_signal_connect (cmap_preview, "size-allocate",
G_CALLBACK (cmap_preview_size_allocate), config);
gtk_widget_set_visible (cmap_preview, TRUE);
g_signal_connect (config, "notify::n-colors",
G_CALLBACK (explorer_number_of_colors_callback),
config);
g_signal_connect (config, "notify::use-loglog-smoothing",
G_CALLBACK (update_preview),
config);
g_signal_connect (config, "notify::red-stretch",
G_CALLBACK (update_preview),
config);
g_signal_connect (config, "notify::blue-stretch",
G_CALLBACK (update_preview),
config);
g_signal_connect (config, "notify::green-stretch",
G_CALLBACK (update_preview),
config);
g_signal_connect (config, "notify::red-mode",
G_CALLBACK (update_preview),
config);
g_signal_connect (config, "notify::green-mode",
G_CALLBACK (update_preview),
config);
g_signal_connect (config, "notify::blue-mode",
G_CALLBACK (update_preview),
config);
g_signal_connect (config, "notify::red-invert",
G_CALLBACK (update_preview),
config);
g_signal_connect (config, "notify::green-invert",
G_CALLBACK (update_preview),
config);
g_signal_connect (config, "notify::blue-invert",
G_CALLBACK (update_preview),
config);
g_signal_connect (config, "notify::color-mode",
G_CALLBACK (update_preview),
config);
/* Fractal Presets */
pika_procedure_dialog_get_label (PIKA_PROCEDURE_DIALOG (dialog),
"preset-label", _("Presets"),
FALSE, FALSE);
vbox = pika_procedure_dialog_fill_box (PIKA_PROCEDURE_DIALOG (dialog),
"fractal-box",
"preset-label",
NULL);
frame = add_objects_list ();
gtk_box_pack_start (GTK_BOX (vbox), frame, TRUE, TRUE, 2);
gtk_widget_set_visible (frame, TRUE);
/* Creating layout */
pika_procedure_dialog_fill_notebook (PIKA_PROCEDURE_DIALOG (dialog),
"main-notebook",
"parameter-tab", "parameter-box",
"color-tab", "color-box",
"fractal-tab", "fractal-box",
NULL);
top_hbox = pika_procedure_dialog_fill_box (PIKA_PROCEDURE_DIALOG (dialog),
"top-hbox",
"main-notebook",
NULL);
gtk_orientable_set_orientation (GTK_ORIENTABLE (top_hbox),
GTK_ORIENTATION_HORIZONTAL);
gtk_widget_set_vexpand (top_hbox, FALSE);
gtk_container_set_border_width (GTK_CONTAINER (top_hbox), 12);
gtk_box_pack_start (GTK_BOX (top_hbox), left_vbox, FALSE, FALSE, 0);
gtk_box_reorder_child (GTK_BOX (top_hbox), left_vbox, 0);
pika_procedure_dialog_fill (PIKA_PROCEDURE_DIALOG (dialog), "top-hbox", NULL);
gtk_widget_show (dialog);
ready_now = TRUE;
set_cmap_preview (config);
dialog_update_preview (config);
wint.run = pika_procedure_dialog_run (PIKA_PROCEDURE_DIALOG (dialog));
gtk_widget_destroy (dialog);
g_free (wint.wimage);
return wint.run;
}
/**********************************************************************
FUNCTION: dialog_update_preview
*********************************************************************/
void
dialog_update_preview (PikaProcedureConfig *config)
{
gint ycoord;
guchar *p_ul;
if (NULL == wint.preview)
return;
if (ready_now && wvals.alwayspreview)
{
g_object_get (config,
"xmin", &xmin,
"xmax", &xmax,
"ymin", &ymin,
"ymax", &ymax,
NULL);
xbild = preview_width;
ybild = preview_height;
xdiff = (xmax - xmin) / xbild;
ydiff = (ymax - ymin) / ybild;
p_ul = wint.wimage;
for (ycoord = 0; ycoord < preview_height; ycoord++)
{
explorer_render_row (NULL,
p_ul,
ycoord,
preview_width,
3,
config);
p_ul += preview_width * 3;
}
preview_redraw ();
}
}
/**********************************************************************
FUNCTION: cmap_preview_size_allocate()
*********************************************************************/
static void
cmap_preview_size_allocate (GtkWidget *widget,
GtkAllocation *allocation,
PikaProcedureConfig *config)
{
gint i;
gint x;
gint y;
gint j;
gint n_colors;
guchar *b;
PikaPreviewArea *preview = PIKA_PREVIEW_AREA (widget);
g_object_get (config,
"n-colors", &n_colors,
NULL);
b = g_new (guchar, allocation->width * allocation->height * 3);
for (y = 0; y < allocation->height; y++)
{
for (x = 0; x < allocation->width; x++)
{
i = x + (y / 4) * allocation->width;
if (i > n_colors)
{
for (j = 0; j < 3; j++)
b[(y*allocation->width + x) * 3 + j] = 0;
}
else
{
b[(y*allocation->width + x) * 3] = colormap[i].r;
b[(y*allocation->width + x) * 3 + 1] = colormap[i].g;
b[(y*allocation->width + x) * 3 + 2] = colormap[i].b;
}
}
}
pika_preview_area_draw (preview,
0, 0, allocation->width, allocation->height,
PIKA_RGB_IMAGE, b, allocation->width*3);
gtk_widget_queue_draw (cmap_preview);
g_free (b);
}
/**********************************************************************
FUNCTION: set_cmap_preview()
*********************************************************************/
void
set_cmap_preview (PikaProcedureConfig *config)
{
gint xsize;
gint ysize;
gint n_colors;
g_object_get (config,
"n-colors", &n_colors,
NULL);
if (NULL == cmap_preview)
return;
make_color_map (config);
for (ysize = 1; ysize * ysize * ysize < n_colors; ysize++)
/**/;
xsize = n_colors / ysize;
while (xsize * ysize < n_colors)
xsize++;
gtk_widget_set_size_request (cmap_preview, xsize, ysize * 4);
}
/**********************************************************************
FUNCTION: make_color_map()
*********************************************************************/
void
make_color_map (PikaProcedureConfig *config)
{
gint i;
gint r;
gint gr;
gint bl;
gdouble redstretch;
gdouble greenstretch;
gdouble bluestretch;
gdouble pi = atan (1) * 4;
gint n_colors;
gint color_mode;
gint red_mode;
gint green_mode;
gint blue_mode;
gboolean red_invert;
gboolean green_invert;
gboolean blue_invert;
g_object_get (config,
"n-colors", &n_colors,
"red-stretch", &redstretch,
"green-stretch", &greenstretch,
"blue-stretch", &bluestretch,
"color-mode", &color_mode,
"red-invert", &red_invert,
"green-invert", &green_invert,
"blue-invert", &blue_invert,
NULL);
red_mode = pika_procedure_config_get_choice_id (config, "red-mode");
green_mode = pika_procedure_config_get_choice_id (config, "green-mode");
blue_mode = pika_procedure_config_get_choice_id (config, "blue-mode");
/* get gradient samples if they don't exist -- fixes gradient color
* mode for noninteractive use (bug #103470).
*/
if (gradient_samples == NULL)
{
PikaGradient *gradient = pika_context_get_gradient ();
pika_gradient_get_uniform_samples (gradient,
n_colors,
FALSE,
&n_gradient_samples,
&gradient_samples);
}
redstretch *= 127.5;
greenstretch *= 127.5;
bluestretch *= 127.5;
for (i = 0; i < n_colors; i++)
if (color_mode == 1)
{
colormap[i].r = (guchar)(gradient_samples[i * 4] * 255.9);
colormap[i].g = (guchar)(gradient_samples[i * 4 + 1] * 255.9);
colormap[i].b = (guchar)(gradient_samples[i * 4 + 2] * 255.9);
}
else
{
double x = (i*2.0) / n_colors;
r = gr = bl = 0;
switch (red_mode)
{
case SINUS:
r = (int) redstretch *(1.0 + sin((x - 1) * pi));
break;
case COSINUS:
r = (int) redstretch *(1.0 + cos((x - 1) * pi));
break;
case NONE:
r = (int)(redstretch *(x));
break;
default:
break;
}
switch (green_mode)
{
case SINUS:
gr = (int) greenstretch *(1.0 + sin((x - 1) * pi));
break;
case COSINUS:
gr = (int) greenstretch *(1.0 + cos((x - 1) * pi));
break;
case NONE:
gr = (int)(greenstretch *(x));
break;
default:
break;
}
switch (blue_mode)
{
case SINUS:
bl = (int) bluestretch * (1.0 + sin ((x - 1) * pi));
break;
case COSINUS:
bl = (int) bluestretch * (1.0 + cos ((x - 1) * pi));
break;
case NONE:
bl = (int) (bluestretch * x);
break;
default:
break;
}
r = MIN (r, 255);
gr = MIN (gr, 255);
bl = MIN (bl, 255);
if (red_invert)
r = 255 - r;
if (green_invert)
gr = 255 - gr;
if (green_invert)
bl = 255 - bl;
colormap[i].r = r;
colormap[i].g = gr;
colormap[i].b = bl;
}
}
/**********************************************************************
FUNCTION: save_options
*********************************************************************/
static void
save_options (FILE * fp)
{
gchar buf[64];
gint fractal_type;
gint red_mode;
gint green_mode;
gint blue_mode;
gint xmin;
gint xmax;
gint ymin;
gint ymax;
gint iter;
gint cx;
gint cy;
gdouble red_stretch;
gdouble green_stretch;
gdouble blue_stretch;
gboolean red_invert;
gboolean green_invert;
gboolean blue_invert;
gint color_mode;
g_object_get (wvals.config,
"xmin", &xmin,
"xmax", &xmax,
"ymin", &ymin,
"ymax", &ymax,
"iter", &iter,
"cx", &cx,
"cy", &cy,
"red-stretch", &red_stretch,
"green-stretch", &green_stretch,
"blue-stretch", &blue_stretch,
"color-mode", &color_mode,
"red_invert", &red_invert,
"green_invert", &green_invert,
"blue_invert", &blue_invert,
NULL);
fractal_type =
pika_procedure_config_get_choice_id (wvals.config, "fractal-type");
red_mode = pika_procedure_config_get_choice_id (wvals.config, "red-mode");
green_mode = pika_procedure_config_get_choice_id (wvals.config, "green-mode");
blue_mode = pika_procedure_config_get_choice_id (wvals.config, "blue-mode");
/* Save options */
fprintf (fp, "fractaltype: %i\n", fractal_type);
g_ascii_dtostr (buf, sizeof (buf), xmin);
fprintf (fp, "xmin: %s\n", buf);
g_ascii_dtostr (buf, sizeof (buf), xmax);
fprintf (fp, "xmax: %s\n", buf);
g_ascii_dtostr (buf, sizeof (buf), ymin);
fprintf (fp, "ymin: %s\n", buf);
g_ascii_dtostr (buf, sizeof (buf), ymax);
fprintf (fp, "ymax: %s\n", buf);
g_ascii_dtostr (buf, sizeof (buf), iter);
fprintf (fp, "iter: %s\n", buf);
g_ascii_dtostr (buf, sizeof (buf), cx);
fprintf (fp, "cx: %s\n", buf);
g_ascii_dtostr (buf, sizeof (buf), cy);
fprintf (fp, "cy: %s\n", buf);
g_ascii_dtostr (buf, sizeof (buf), red_stretch * 128.0);
fprintf (fp, "redstretch: %s\n", buf);
g_ascii_dtostr (buf, sizeof (buf), green_stretch * 128.0);
fprintf (fp, "greenstretch: %s\n", buf);
g_ascii_dtostr (buf, sizeof (buf), blue_stretch * 128.0);
fprintf (fp, "bluestretch: %s\n", buf);
fprintf (fp, "redmode: %i\n", red_mode);
fprintf (fp, "greenmode: %i\n", green_mode);
fprintf (fp, "bluemode: %i\n", blue_mode);
fprintf (fp, "redinvert: %i\n", red_invert);
fprintf (fp, "greeninvert: %i\n", green_invert);
fprintf (fp, "blueinvert: %i\n", blue_invert);
fprintf (fp, "colormode: %i\n", color_mode);
fputs ("#**********************************************************************\n", fp);
fprintf(fp, "<EOF>\n");
fputs ("#**********************************************************************\n", fp);
}
static void
save_callback (void)
{
FILE *fp;
const gchar *savename = filename;
fp = g_fopen (savename, "wt+");
if (!fp)
{
g_message (_("Could not open '%s' for writing: %s"),
pika_filename_to_utf8 (savename), g_strerror (errno));
return;
}
/* Write header out */
fputs (FRACTAL_HEADER, fp);
fputs ("#**********************************************************************\n", fp);
fputs ("# This is a data file for the Fractal Explorer plug-in for PIKA *\n", fp);
fputs ("#**********************************************************************\n", fp);
save_options (fp);
if (ferror (fp))
g_message (_("Could not write '%s': %s"),
pika_filename_to_utf8 (savename), g_strerror (ferror (fp)));
fclose (fp);
}
static void
save_file_chooser_response (GtkFileChooser *chooser,
gint response_id,
gpointer data)
{
if (response_id == GTK_RESPONSE_OK)
{
filename = gtk_file_chooser_get_filename (chooser);
save_callback ();
}
gtk_widget_destroy (GTK_WIDGET (chooser));
}
static void
file_chooser_set_default_folder (GtkFileChooser *chooser)
{
GList *path_list;
gchar *dir;
if (! fractalexplorer_path)
return;
path_list = pika_path_parse (fractalexplorer_path, 256, FALSE, NULL);
dir = pika_path_get_user_writable_dir (path_list);
if (! dir)
dir = g_strdup (pika_directory ());
gtk_file_chooser_set_current_folder (chooser, dir);
g_free (dir);
pika_path_free (path_list);
}
static void
load_file_chooser_response (GtkFileChooser *chooser,
gint response_id,
gpointer data)
{
PikaProcedureConfig *config = (PikaProcedureConfig *) data;
if (response_id == GTK_RESPONSE_OK)
{
filename = gtk_file_chooser_get_filename (chooser);
if (g_file_test (filename, G_FILE_TEST_IS_REGULAR))
{
explorer_load ();
}
gtk_widget_show (maindlg);
set_cmap_preview (config);
dialog_update_preview (config);
}
gtk_widget_destroy (GTK_WIDGET (chooser));
}
static void
create_load_file_chooser (GtkWidget *widget,
GtkWidget *dialog)
{
static GtkWidget *window = NULL;
PikaProcedureConfig *config;
g_object_get (PIKA_PROCEDURE_DIALOG (dialog),
"config", &config,
NULL);
if (!window)
{
window =
gtk_file_chooser_dialog_new (_("Load Fractal Parameters"),
GTK_WINDOW (dialog),
GTK_FILE_CHOOSER_ACTION_OPEN,
_("_Cancel"), GTK_RESPONSE_CANCEL,
_("_Open"), GTK_RESPONSE_OK,
NULL);
gtk_dialog_set_default_response (GTK_DIALOG (window), GTK_RESPONSE_OK);
pika_dialog_set_alternative_button_order (GTK_DIALOG (window),
GTK_RESPONSE_OK,
GTK_RESPONSE_CANCEL,
-1);
file_chooser_set_default_folder (GTK_FILE_CHOOSER (window));
g_signal_connect (window, "destroy",
G_CALLBACK (gtk_widget_destroyed),
&window);
g_signal_connect (window, "response",
G_CALLBACK (load_file_chooser_response),
config);
}
gtk_window_present (GTK_WINDOW (window));
}
static void
create_save_file_chooser (GtkWidget *widget,
GtkWidget *dialog)
{
static GtkWidget *window = NULL;
if (! window)
{
window =
gtk_file_chooser_dialog_new (_("Save Fractal Parameters"),
GTK_WINDOW (dialog),
GTK_FILE_CHOOSER_ACTION_SAVE,
_("_Cancel"), GTK_RESPONSE_CANCEL,
_("_Save"), GTK_RESPONSE_OK,
NULL);
pika_dialog_set_alternative_button_order (GTK_DIALOG (window),
GTK_RESPONSE_OK,
GTK_RESPONSE_CANCEL,
-1);
gtk_dialog_set_default_response (GTK_DIALOG (window), GTK_RESPONSE_OK);
gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (window),
TRUE);
g_signal_connect (window, "destroy",
G_CALLBACK (gtk_widget_destroyed),
&window);
g_signal_connect (window, "response",
G_CALLBACK (save_file_chooser_response),
window);
}
if (tpath)
{
gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (window), tpath);
}
else
{
file_chooser_set_default_folder (GTK_FILE_CHOOSER (window));
}
gtk_window_present (GTK_WINDOW (window));
}
gchar*
get_line (gchar *buf,
gint s,
FILE *from,
gint init)
{
gint slen;
gchar *ret;
if (init)
line_no = 1;
else
line_no++;
do
{
ret = fgets (buf, s, from);
}
while (!ferror (from) && buf[0] == '#');
slen = strlen (buf);
/* The last newline is a pain */
if (slen > 0)
buf[slen - 1] = '\0';
if (ferror (from))
{
g_warning ("Error reading file");
return NULL;
}
return ret;
}
gint
load_options (fractalexplorerOBJ *xxx,
FILE *fp)
{
gchar load_buf[MAX_LOAD_LINE];
gchar str_buf[MAX_LOAD_LINE];
gchar opt_buf[MAX_LOAD_LINE];
/* default values */
xxx->opts = standardvals;
xxx->opts.gradinvert = FALSE;
get_line (load_buf, MAX_LOAD_LINE, fp, 0);
while (!feof (fp) && strcmp (load_buf, "<EOF>"))
{
/* Get option name */
sscanf (load_buf, "%255s %255s", str_buf, opt_buf);
if (!strcmp (str_buf, "fractaltype:"))
{
gint sp = 0;
sp = atoi (opt_buf);
if (sp < 0)
return -1;
xxx->opts.fractaltype = sp;
}
else if (!strcmp (str_buf, "xmin:"))
{
xxx->opts.xmin = g_ascii_strtod (opt_buf, NULL);
}
else if (!strcmp (str_buf, "xmax:"))
{
xxx->opts.xmax = g_ascii_strtod (opt_buf, NULL);
}
else if (!strcmp(str_buf, "ymin:"))
{
xxx->opts.ymin = g_ascii_strtod (opt_buf, NULL);
}
else if (!strcmp (str_buf, "ymax:"))
{
xxx->opts.ymax = g_ascii_strtod (opt_buf, NULL);
}
else if (!strcmp(str_buf, "redstretch:"))
{
gdouble sp = g_ascii_strtod (opt_buf, NULL);
xxx->opts.redstretch = sp / 128.0;
}
else if (!strcmp(str_buf, "greenstretch:"))
{
gdouble sp = g_ascii_strtod (opt_buf, NULL);
xxx->opts.greenstretch = sp / 128.0;
}
else if (!strcmp (str_buf, "bluestretch:"))
{
gdouble sp = g_ascii_strtod (opt_buf, NULL);
xxx->opts.bluestretch = sp / 128.0;
}
else if (!strcmp (str_buf, "iter:"))
{
xxx->opts.iter = g_ascii_strtod (opt_buf, NULL);
}
else if (!strcmp(str_buf, "cx:"))
{
xxx->opts.cx = g_ascii_strtod (opt_buf, NULL);
}
else if (!strcmp (str_buf, "cy:"))
{
xxx->opts.cy = g_ascii_strtod (opt_buf, NULL);
}
else if (!strcmp(str_buf, "redmode:"))
{
xxx->opts.redmode = atoi (opt_buf);
}
else if (!strcmp(str_buf, "greenmode:"))
{
xxx->opts.greenmode = atoi (opt_buf);
}
else if (!strcmp(str_buf, "bluemode:"))
{
xxx->opts.bluemode = atoi (opt_buf);
}
else if (!strcmp (str_buf, "redinvert:"))
{
xxx->opts.redinvert = atoi (opt_buf);
}
else if (!strcmp (str_buf, "greeninvert:"))
{
xxx->opts.greeninvert = atoi (opt_buf);
}
else if (!strcmp(str_buf, "blueinvert:"))
{
xxx->opts.blueinvert = atoi (opt_buf);
}
else if (!strcmp (str_buf, "colormode:"))
{
xxx->opts.colormode = atoi (opt_buf);
}
get_line (load_buf, MAX_LOAD_LINE, fp, 0);
}
return 0;
}
void
explorer_load (void)
{
FILE *fp;
gchar load_buf[MAX_LOAD_LINE];
g_assert (filename != NULL);
fp = g_fopen (filename, "rt");
if (!fp)
{
g_message (_("Could not open '%s' for reading: %s"),
pika_filename_to_utf8 (filename), g_strerror (errno));
return;
}
get_line (load_buf, MAX_LOAD_LINE, fp, 1);
if (strncmp (FRACTAL_HEADER, load_buf, strlen (load_buf)))
{
g_message (_("'%s' is not a FractalExplorer file"),
pika_filename_to_utf8 (filename));
fclose (fp);
return;
}
if (load_options (current_obj, fp))
{
g_message (_("'%s' is corrupt. Line %d Option section incorrect"),
pika_filename_to_utf8 (filename), line_no);
fclose (fp);
return;
}
g_object_set (wvals.config,
"xmin", current_obj->opts.xmin,
"xmax", current_obj->opts.xmax,
"ymin", current_obj->opts.ymin,
"ymax", current_obj->opts.ymax,
"iter", current_obj->opts.iter,
"cx", current_obj->opts.cx,
"cy", current_obj->opts.cy,
"red-stretch", current_obj->opts.redstretch,
"green-stretch", current_obj->opts.greenstretch,
"blue-stretch", current_obj->opts.bluestretch,
"color-mode", current_obj->opts.colormode,
"red-invert", current_obj->opts.redinvert,
"green-invert", current_obj->opts.greeninvert,
"blue-invert", current_obj->opts.blueinvert,
NULL);
switch (current_obj->opts.fractaltype)
{
case 0:
g_object_set (wvals.config, "fractal-type", "mandelbrot", NULL);
break;
case 1:
g_object_set (wvals.config, "fractal-type", "julia", NULL);
break;
case 2:
g_object_set (wvals.config, "fractal-type", "barnsley-1", NULL);
break;
case 3:
g_object_set (wvals.config, "fractal-type", "barnsley-2", NULL);
break;
case 4:
g_object_set (wvals.config, "fractal-type", "barnsley-3", NULL);
break;
case 5:
g_object_set (wvals.config, "fractal-type", "spider", NULL);
break;
case 6:
g_object_set (wvals.config, "fractal-type", "man-o-war", NULL);
break;
case 7:
g_object_set (wvals.config, "fractal-type", "lambda", NULL);
break;
case 8:
g_object_set (wvals.config, "fractal-type", "sierpinski", NULL);
break;
default:
break;
}
switch (current_obj->opts.redmode)
{
case 0:
g_object_set (wvals.config, "red-mode", "red-sin", NULL);
break;
case 1:
g_object_set (wvals.config, "red-mode", "red-cos", NULL);
break;
case 2:
g_object_set (wvals.config, "red-mode", "red-none", NULL);
break;
default:
break;
}
switch (current_obj->opts.greenmode)
{
case 0:
g_object_set (wvals.config, "green-mode", "green-sin", NULL);
break;
case 1:
g_object_set (wvals.config, "green-mode", "green-cos", NULL);
break;
case 2:
g_object_set (wvals.config, "green-mode", "green-none", NULL);
break;
default:
break;
}
switch (current_obj->opts.bluemode)
{
case 0:
g_object_set (wvals.config, "blue-mode", "blue-sin", NULL);
break;
case 1:
g_object_set (wvals.config, "blue-mode", "blue-cos", NULL);
break;
case 2:
g_object_set (wvals.config, "blue-mode", "blue-none", NULL);
break;
default:
break;
}
fclose (fp);
}