[genius] Tue Feb 02 13:30:44 2010 Jiri (George) Lebl <jirka 5z com>
- From: George Lebl <jirka src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [genius] Tue Feb 02 13:30:44 2010 Jiri (George) Lebl <jirka 5z com>
- Date: Tue, 2 Feb 2010 19:32:42 +0000 (UTC)
commit eea7eba557c226ff953b321229d55b89cd846b4f
Author: Jiri (George) Lebl <jirka 5z com>
Date: Tue Feb 2 13:30:48 2010 -0600
Tue Feb 02 13:30:44 2010 Jiri (George) Lebl <jirka 5z com>
* src/graphing.c: Allow changing variable names. Either in the GUI
or using the new parameter LinePlotVariableNames.
* help/C/gel-function-list.xml: document the new parameter
ChangeLog | 7 +
NEWS | 3 +-
help/C/gel-function-list.xml | 27 +-
src/graphing.c | 963 +++++++++++++++++++++++++++++++++++-------
4 files changed, 831 insertions(+), 169 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 6b232ea..7f62397 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+Tue Feb 02 13:30:44 2010 Jiri (George) Lebl <jirka 5z com>
+
+ * src/graphing.c: Allow changing variable names. Either in the GUI
+ or using the new parameter LinePlotVariableNames.
+
+ * help/C/gel-function-list.xml: document the new parameter
+
Tue Feb 02 10:32:53 2010 Jiri (George) Lebl <jirka 5z com>
* src/graphing.c, help/C/gel-function-list.xml: Add SlopefieldTicks
diff --git a/NEWS b/NEWS
index e3e4bf8..2577b57 100644
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,7 @@
Changes to 1.0.10
-* Add SlopefieldTicks and VectorfieldTicks parameters
+* Allow changing variable names for all 2D plotting functions
+* Add SlopefieldTicks, VectorfieldTicks, and LinePlotVariableNames parameters
* Add AskButtons interactive function
* Allow comparisons (== and !=) with null, treating it as an empty matrix
diff --git a/help/C/gel-function-list.xml b/help/C/gel-function-list.xml
index a8d1b56..c0c59cd 100644
--- a/help/C/gel-function-list.xml
+++ b/help/C/gel-function-list.xml
@@ -572,26 +572,37 @@ except possibly user interface events are processed.</para>
</listitem>
</varlistentry>
- <varlistentry id="gel-function-LinePlotWindow">
- <term>LinePlotWindow</term>
+ <varlistentry id="gel-function-LinePlotDrawLegends">
+ <term>LinePlotDrawLegends</term>
<listitem>
- <synopsis>LinePlotWindow = [x1,x2,y1,y2]</synopsis>
- <para>Sets the limits for <link linkend="genius-gel-function-list-plotting">line plotting
+ <synopsis>LinePlotDrawLegends = true</synopsis>
+ <para>Tells genius to draw the legends for <link linkend="genius-gel-function-list-plotting">line plotting
functions</link> such as <link linkend="gel-function-LinePlot"><function>LinePlot</function></link>.
</para>
</listitem>
</varlistentry>
- <varlistentry id="gel-function-LinePlotDrawLegends">
- <term>LinePlotDrawLegends</term>
+ <varlistentry id="gel-function-LinePlotVariableNames">
+ <term>LinePlotVariableNames</term>
<listitem>
- <synopsis>LinePlotDrawLegends = true</synopsis>
- <para>Tells genius to draw the legends for <link linkend="genius-gel-function-list-plotting">line plotting
+ <synopsis>LinePlotVariableNames = ["x","y","z","t"]</synopsis>
+ <para>Tells genius which variable names are used as default names for <link linkend="genius-gel-function-list-plotting">line plotting
+ functions</link> such as <link linkend="gel-function-LinePlot"><function>LinePlot</function></link> and friends.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="gel-function-LinePlotWindow">
+ <term>LinePlotWindow</term>
+ <listitem>
+ <synopsis>LinePlotWindow = [x1,x2,y1,y2]</synopsis>
+ <para>Sets the limits for <link linkend="genius-gel-function-list-plotting">line plotting
functions</link> such as <link linkend="gel-function-LinePlot"><function>LinePlot</function></link>.
</para>
</listitem>
</varlistentry>
+
<varlistentry id="gel-function-MaxDigits">
<term>MaxDigits</term>
<listitem>
diff --git a/src/graphing.c b/src/graphing.c
index 74ce7ed..46784ce 100644
--- a/src/graphing.c
+++ b/src/graphing.c
@@ -95,8 +95,11 @@ static GtkPlotData *slopefield_data = NULL;
static GtkPlotData *vectorfield_data = NULL;
static GtkWidget *plot_entries[MAXFUNC] = { NULL };
+static GtkWidget *plot_y_labels[MAXFUNC] = { NULL };
static GtkWidget *plot_entries_status[MAXFUNC] = { NULL };
+static GtkWidget *lineplot_info_label = NULL;
+
static GtkWidget *parametric_entry_x = NULL;
static GtkWidget *parametric_entry_y = NULL;
static GtkWidget *parametric_entry_z = NULL;
@@ -104,17 +107,43 @@ static GtkWidget *parametric_status_x = NULL;
static GtkWidget *parametric_status_y = NULL;
static GtkWidget *parametric_status_z = NULL;
+static GtkWidget *parametric_info_label = NULL;
+static GtkWidget *parametric_x_label = NULL;
+static GtkWidget *parametric_y_label = NULL;
+static GtkWidget *parametric_z_label = NULL;
+static GtkWidget *parametric_trange_label = NULL;
+
static GtkWidget *slopefield_entry = NULL;
static GtkWidget *slopefield_status = NULL;
+static GtkWidget *slopefield_info_label = NULL;
+static GtkWidget *slopefield_der_label = NULL;
static GtkWidget *solver_x_sb = NULL;
static GtkWidget *solver_y_sb = NULL;
+static GtkWidget *solver_xinc_label = NULL;
+static GtkWidget *solver_tinc_label = NULL;
+static GtkWidget *solver_tlen_label = NULL;
+static GtkWidget *solver_x_pt_label = NULL;
+static GtkWidget *solver_y_pt_label = NULL;
+
static GtkWidget *vectorfield_entry_x = NULL;
static GtkWidget *vectorfield_status_x = NULL;
static GtkWidget *vectorfield_entry_y = NULL;
static GtkWidget *vectorfield_status_y = NULL;
+static GtkWidget *vectorfield_info_label = NULL;
+static GtkWidget *vectorfield_xder_label = NULL;
+static GtkWidget *vectorfield_yder_label = NULL;
+
+static GtkWidget *lineplot_x_range_label = NULL;
+static GtkWidget *lineplot_y_range_label = NULL;
+
+static char *lp_x_name = NULL;
+static char *lp_y_name = NULL;
+static char *lp_z_name = NULL;
+static char *lp_t_name = NULL;
+
static GSList *solutions_list = NULL;
static double spinx1 = -10;
@@ -253,7 +282,8 @@ static gboolean whack_window_after_plot = FALSE;
static void plot_axis (void);
/* lineplots */
-static void plot_functions (gboolean do_window_present);
+static void plot_functions (gboolean do_window_present,
+ gboolean from_gui);
/* surfaces */
static void plot_surface_functions (gboolean do_window_present);
@@ -265,14 +295,18 @@ static void slopefield_draw_solution (double x, double y, double dx);
static void vectorfield_draw_solution (double x, double y, double dt, double tlen);
static GtkWidget *
-create_range_spinboxes (const char *title, double *val1, GtkWidget **w1,
+create_range_spinboxes (const char *title, GtkWidget **titlew,
+ double *val1, GtkWidget **w1,
double min1, double max1, double step1,
- const char *totitle, double *val2, GtkWidget **w2,
+ const char *totitle, GtkWidget **totitlew,
+ double *val2, GtkWidget **w2,
double min2, double max2, double step2,
const char *bytitle, double *by, GtkWidget **wb,
double minby, double maxby, double stepby,
GCallback activate_callback);
+static void set_lineplot_labels (void);
+
#define WIDTH 640
#define HEIGHT 480
#define ASPECT ((double)HEIGHT/(double)WIDTH)
@@ -290,6 +324,56 @@ enum {
RESPONSE_CLEAR
};
+static gboolean
+is_letter_or_underscore (char l)
+{
+ if ((l >= 'a' && l <= 'z') ||
+ (l >= 'A' && l <= 'Z') ||
+ l == '_')
+ return TRUE;
+ else
+ return FALSE;
+}
+
+static gboolean
+is_letter_underscore_or_number (char l)
+{
+ if ((l >= 'a' && l <= 'z') ||
+ (l >= 'A' && l <= 'Z') ||
+ (l >= '0' && l <= '9') ||
+ l == '_')
+ return TRUE;
+ else
+ return FALSE;
+}
+
+static gboolean
+is_identifier (const char *e)
+{
+ int i;
+ if ( ! is_letter_or_underscore (e[0]))
+ return FALSE;
+ for (i = 1; e[i] != '\0'; i++) {
+ if ( ! is_letter_underscore_or_number (e[i]))
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
+static void
+init_var_names (void)
+{
+ /* this means we have already initialized */
+ if (lp_x_name != NULL)
+ return;
+
+ lp_x_name = g_strdup ("x");
+ lp_y_name = g_strdup ("y");
+ lp_z_name = g_strdup ("z");
+ lp_t_name = g_strdup ("t");
+}
+
static void
color_alloc (GdkColor *color)
{
@@ -630,7 +714,7 @@ graph_window_response (GtkWidget *w, int response, gpointer data)
}
static void
-print_entry_activate (GtkWidget *entry, gpointer data)
+ok_dialog_entry_activate (GtkWidget *entry, gpointer data)
{
gtk_dialog_response (GTK_DIALOG (data), GTK_RESPONSE_OK);
}
@@ -672,7 +756,7 @@ plot_print_cb (void)
cmd = gtk_entry_new ();
g_signal_connect (G_OBJECT (cmd), "activate",
- G_CALLBACK (print_entry_activate), req);
+ G_CALLBACK (ok_dialog_entry_activate), req);
gtk_box_pack_start (GTK_BOX (hbox), cmd, TRUE, TRUE, 0);
gtk_entry_set_text (GTK_ENTRY (cmd), last_cmd);
@@ -1612,9 +1696,11 @@ solver_cb (GtkWidget *item, gpointer data)
else
inc = 1;
- w = create_range_spinboxes (_("X increment:"), &solver_xinc, NULL,
+ w = create_range_spinboxes (_("X increment:"),
+ &solver_xinc_label,
+ &solver_xinc, NULL,
0, G_MAXDOUBLE, inc,
- NULL, NULL, NULL, 0, 0, 0,
+ NULL, NULL, NULL, NULL, 0, 0, 0,
NULL, NULL, NULL, 0, 0, 0,
solver_entry_activate);
gtk_box_pack_start (GTK_BOX (box), w, FALSE, FALSE, 0);
@@ -1632,9 +1718,13 @@ solver_cb (GtkWidget *item, gpointer data)
else
inc = 1;
- w = create_range_spinboxes (_("T increment:"), &solver_tinc, NULL,
+ w = create_range_spinboxes (_("T increment:"),
+ &solver_tinc_label,
+ &solver_tinc, NULL,
0, G_MAXDOUBLE, inc,
- _("T interval length:"), &solver_tlen, NULL,
+ _("T interval length:"),
+ &solver_tlen_label,
+ &solver_tlen, NULL,
0, G_MAXDOUBLE, 1,
NULL, NULL, NULL, 0, 0, 0,
solver_entry_activate);
@@ -1646,16 +1736,22 @@ solver_cb (GtkWidget *item, gpointer data)
if (solver_y < ploty1 || solver_y > ploty2)
solver_y = ploty1 + (ploty2-ploty1)/2;
- w = create_range_spinboxes (_("Point x:"), &solver_x,
+ w = create_range_spinboxes (_("Point x:"),
+ &solver_x_pt_label,
+ &solver_x,
&solver_x_sb,
-G_MAXDOUBLE, G_MAXDOUBLE, 1,
- _("y:"), &solver_y,
+ _("y:"),
+ &solver_y_pt_label,
+ &solver_y,
&solver_y_sb,
-G_MAXDOUBLE, G_MAXDOUBLE, 1,
NULL, NULL, NULL, 0, 0, 0,
solver_entry_activate);
gtk_box_pack_start (GTK_BOX (box), w, FALSE, FALSE, 0);
+ set_lineplot_labels ();
+
gtk_widget_show_all (solver_dialog);
}
@@ -2872,6 +2968,26 @@ make_matrix_from_limits (void)
return n;
}
+static GelETree *
+make_matrix_from_lp_varnames (void)
+{
+ GelETree *n;
+ GelMatrixW *m;
+ /*make us a new empty node*/
+ GEL_GET_NEW_NODE (n);
+ n->type = GEL_MATRIX_NODE;
+ m = n->mat.matrix = gel_matrixw_new ();
+ n->mat.quoted = FALSE;
+ gel_matrixw_set_size (m, 4, 1);
+
+ gel_matrixw_set_index (m, 0, 0) = gel_makenum_string (lp_x_name);
+ gel_matrixw_set_index (m, 1, 0) = gel_makenum_string (lp_y_name);
+ gel_matrixw_set_index (m, 2, 0) = gel_makenum_string (lp_z_name);
+ gel_matrixw_set_index (m, 3, 0) = gel_makenum_string (lp_t_name);
+
+ return n;
+}
+
static gboolean
get_limits_from_matrix_surf (GelETree *m, double *x1, double *x2, double *y1, double *y2, double *z1, double *z2)
{
@@ -3427,6 +3543,8 @@ vectorfield_draw_solution (double x, double y, double dt, double tlen)
static void
replot_fields (void)
{
+ init_var_names ();
+
if (slopefield_func != NULL) {
get_slopefield_points ();
if (plot_points_num > 0) {
@@ -3462,10 +3580,19 @@ replot_fields (void)
gtk_plot_flux_show_scale (GTK_PLOT_FLUX (slopefield_data), FALSE);
- label = label_func (-1, slopefield_func, "x,y", slopefield_name);
+ tmp = g_strdup_printf ("%s,%s",
+ lp_x_name,
+ lp_y_name);
+ label = label_func (-1, slopefield_func, tmp, slopefield_name);
+ g_free (tmp);
/* FIXME: gtkextra is broken (adding the " ")
* and I don't feel like fixing it */
- tmp = g_strconcat ("dy/dx = ", label, " ", NULL);
+ /* add dy/dx = */
+ tmp = g_strconcat ("d",
+ lp_y_name,
+ "/d",
+ lp_x_name,
+ " = ", label, " ", NULL);
g_free (label);
gtk_plot_data_set_legend (slopefield_data, tmp);
g_free (tmp);
@@ -3519,11 +3646,25 @@ replot_fields (void)
gtk_plot_flux_show_scale (GTK_PLOT_FLUX (vectorfield_data), FALSE);
- l1 = label_func (-1, vectorfield_func_x, "x,y", vectorfield_name_x);
- l2 = label_func (-1, vectorfield_func_y, "x,y", vectorfield_name_y);
+ tmp = g_strdup_printf ("%s,%s",
+ lp_x_name,
+ lp_y_name);
+ l1 = label_func (-1, vectorfield_func_x, tmp, vectorfield_name_x);
+ l2 = label_func (-1, vectorfield_func_y, tmp, vectorfield_name_y);
+ g_free (tmp);
/* FIXME: gtkextra is broken (adding the " ")
* and I don't feel like fixing it */
- tmp = g_strconcat ("dx/dt = ", l1, ", dy/dt = ", l2, " ", NULL);
+ /*tmp = g_strconcat ("dx/dt = ", l1, ", dy/dt = ", l2, " ", NULL);*/
+ tmp = g_strconcat ("d",
+ lp_x_name,
+ "/d",
+ lp_t_name,
+ " = ", l1, ", d",
+ lp_y_name,
+ "/d",
+ lp_t_name,
+ " = ", l2,
+ " ", NULL);
g_free (l1);
g_free (l2);
gtk_plot_data_set_legend (vectorfield_data, tmp);
@@ -3562,7 +3703,8 @@ init_plot_ctx (void)
}
static void
-plot_functions (gboolean do_window_present)
+plot_functions (gboolean do_window_present,
+ gboolean from_gui)
{
char *colors[] = {
"darkblue",
@@ -3581,6 +3723,8 @@ plot_functions (gboolean do_window_present)
int i;
int color_i;
+ init_var_names ();
+
ensure_window (do_window_present);
if (plot_canvas != NULL /* sanity */)
@@ -3646,7 +3790,9 @@ plot_functions (gboolean do_window_present)
GDK_JOIN_ROUND,
2, &color);
- label = label_func (i, plot_func[i], "x", plot_func_name[i]);
+ label = label_func (i, plot_func[i],
+ lp_x_name,
+ plot_func_name[i]);
gtk_plot_data_set_legend (line_data[i], label);
g_free (label);
}
@@ -3842,9 +3988,11 @@ entry_activate (void)
}
static GtkWidget *
-create_range_spinboxes (const char *title, double *val1, GtkWidget **w1,
+create_range_spinboxes (const char *title, GtkWidget **titlew,
+ double *val1, GtkWidget **w1,
double min1, double max1, double step1,
- const char *totitle, double *val2, GtkWidget **w2,
+ const char *totitle, GtkWidget **totitlew,
+ double *val2, GtkWidget **w2,
double min2, double max2, double step2,
const char *bytitle, double *by, GtkWidget **wb,
double minby, double maxby, double stepby,
@@ -3855,6 +4003,13 @@ create_range_spinboxes (const char *title, double *val1, GtkWidget **w1,
b = gtk_hbox_new (FALSE, GENIUS_PAD);
w = gtk_label_new(title);
+ if (titlew != NULL) {
+ *titlew = w;
+ g_signal_connect (G_OBJECT (w),
+ "destroy",
+ G_CALLBACK (gtk_widget_destroyed),
+ titlew);
+ }
gtk_box_pack_start (GTK_BOX (b), w, FALSE, FALSE, 0);
adj = (GtkAdjustment *)gtk_adjustment_new (*val1,
min1,
@@ -3881,6 +4036,13 @@ create_range_spinboxes (const char *title, double *val1, GtkWidget **w1,
if (val2 != NULL) {
w = gtk_label_new (totitle);
+ if (totitlew != NULL) {
+ *totitlew = w;
+ g_signal_connect (G_OBJECT (w),
+ "destroy",
+ G_CALLBACK (gtk_widget_destroyed),
+ totitlew);
+ }
gtk_box_pack_start (GTK_BOX (b), w, FALSE, FALSE, 0);
adj = (GtkAdjustment *)gtk_adjustment_new (*val2,
min2,
@@ -3968,15 +4130,25 @@ create_int_spinbox (const char *title, int *val, int min, int max)
static GtkWidget *
create_expression_box (const char *label,
+ GtkWidget **labelw,
GtkWidget **entry,
GtkWidget **status)
{
GtkWidget *b;
+ GtkWidget *l;
b = gtk_hbox_new (FALSE, GENIUS_PAD);
- gtk_box_pack_start (GTK_BOX (b),
- gtk_label_new (label), FALSE, FALSE, 0);
+ l = gtk_label_new (label);
+ if (labelw != NULL) {
+ *labelw = l;
+ g_signal_connect (G_OBJECT (l),
+ "destroy",
+ G_CALLBACK (gtk_widget_destroyed),
+ labelw);
+ }
+
+ gtk_box_pack_start (GTK_BOX (b), l, FALSE, FALSE, 0);
*entry = gtk_entry_new ();
g_signal_connect (G_OBJECT (*entry), "activate",
@@ -3988,6 +4160,28 @@ create_expression_box (const char *label,
return b;
}
+static GtkWidget *
+create_simple_expression_box (const char *label,
+ GtkWidget **labelw,
+ GtkWidget **entry)
+{
+ GtkWidget *b;
+ GtkWidget *l;
+
+ b = gtk_hbox_new (FALSE, GENIUS_PAD);
+
+ l = gtk_label_new (label);
+ if (labelw != NULL)
+ *labelw = l;
+
+ gtk_box_pack_start (GTK_BOX (b), l, FALSE, FALSE, 0);
+
+ *entry = gtk_entry_new ();
+ gtk_box_pack_start (GTK_BOX (b), *entry, TRUE, TRUE, 0);
+
+ return b;
+}
+
/*option callback*/
static void
optioncb (GtkWidget * widget, int *data)
@@ -3998,13 +4192,339 @@ optioncb (GtkWidget * widget, int *data)
*data = FALSE;
}
+static void
+set_lineplot_labels (void)
+{
+ char *s;
+
+ if (slopefield_info_label != NULL) {
+ s = g_strdup_printf (_("Type in function name or expression involving "
+ "the %s and %s variables (or the %s variable which will be %s=%s+i%s) "
+ "that gives the slope "
+ "at the point (%s,%s)."),
+ lp_x_name,
+ lp_y_name,
+ lp_z_name,
+ lp_z_name,
+ lp_x_name,
+ lp_y_name,
+ lp_x_name,
+ lp_y_name);
+ gtk_label_set_text (GTK_LABEL (slopefield_info_label), s);
+ g_free (s);
+ }
+
+ if (slopefield_der_label != NULL) {
+ s = g_strdup_printf ("d%s/d%s=",
+ lp_y_name,
+ lp_x_name);
+ gtk_label_set_text (GTK_LABEL (slopefield_der_label), s);
+ g_free (s);
+ }
+
+ if (lineplot_x_range_label != NULL) {
+ s = g_strdup_printf (_("%s from:"),
+ lp_x_name);
+ gtk_label_set_text (GTK_LABEL (lineplot_x_range_label), s);
+ g_free (s);
+ }
+
+ if (lineplot_y_range_label != NULL) {
+ s = g_strdup_printf (_("%s from:"),
+ lp_y_name);
+ gtk_label_set_text (GTK_LABEL (lineplot_y_range_label), s);
+ g_free (s);
+ }
+
+ if (solver_xinc_label != NULL) {
+ s = g_strdup_printf (_("%s increment:"),
+ lp_x_name);
+ gtk_label_set_text (GTK_LABEL (solver_xinc_label), s);
+ g_free (s);
+ }
+
+ if (solver_tinc_label != NULL) {
+ s = g_strdup_printf (_("%s increment:"),
+ lp_t_name);
+ gtk_label_set_text (GTK_LABEL (solver_tinc_label), s);
+ g_free (s);
+ }
+
+ if (solver_tlen_label != NULL) {
+ s = g_strdup_printf (_("%s interval length:"),
+ lp_t_name);
+ gtk_label_set_text (GTK_LABEL (solver_tlen_label), s);
+ g_free (s);
+ }
+
+ if (solver_x_pt_label != NULL) {
+ s = g_strdup_printf (_("Point %s:"),
+ lp_x_name);
+ gtk_label_set_text (GTK_LABEL (solver_x_pt_label), s);
+ g_free (s);
+ }
+
+ if (solver_y_pt_label != NULL) {
+ s = g_strdup_printf ("%s:",
+ lp_y_name);
+ gtk_label_set_text (GTK_LABEL (solver_y_pt_label), s);
+ g_free (s);
+ }
+ if (vectorfield_info_label != NULL) {
+ s = g_strdup_printf (_("Type in function names or expressions involving "
+ "the %s and %s variables (or the %s variable which will be %s=%s+i%s) "
+ "that give the d%s/d%s and d%s/d%s of the autonomous system to be plotted "
+ "at the point (%s,%s)."),
+ lp_x_name,
+ lp_y_name,
+ lp_z_name,
+ lp_z_name,
+ lp_x_name,
+ lp_y_name,
+ lp_x_name,
+ lp_t_name,
+ lp_y_name,
+ lp_t_name,
+ lp_x_name,
+ lp_y_name);
+ gtk_label_set_text (GTK_LABEL (vectorfield_info_label), s);
+ g_free (s);
+ }
+
+ if (vectorfield_xder_label != NULL) {
+ s = g_strdup_printf ("d%s/d%s=",
+ lp_x_name,
+ lp_t_name);
+ gtk_label_set_text (GTK_LABEL (vectorfield_xder_label), s);
+ g_free (s);
+ }
+ if (vectorfield_yder_label != NULL) {
+ s = g_strdup_printf ("d%s/d%s=",
+ lp_y_name,
+ lp_t_name);
+ gtk_label_set_text (GTK_LABEL (vectorfield_yder_label), s);
+ g_free (s);
+ }
+
+ if (lineplot_info_label != NULL) {
+ s = g_strdup_printf (_("Type in function names or expressions involving "
+ "the %s variable in the boxes below to graph "
+ "them"), lp_x_name);
+ gtk_label_set_text (GTK_LABEL (lineplot_info_label), s);
+ g_free (s);
+ }
+
+ if (plot_y_labels[0] != NULL) {
+ int i;
+ s = g_strdup_printf ("%s=", lp_y_name);
+ for (i = 0; i < MAXFUNC; i++) {
+ gtk_label_set_text (GTK_LABEL (plot_y_labels[i]), s);
+ }
+ g_free (s);
+ }
+
+ if (parametric_info_label != NULL) {
+ s = g_strdup_printf (_("Type in function names or expressions involving "
+ "the %s variable in the boxes below to graph "
+ "them. Either fill in both boxes with %s= and %s= "
+ "in front of them giving the %s and %s coordinates "
+ "separately, or alternatively fill in the %s= box "
+ "giving %s and %s as the real and imaginary part of "
+ "a complex number."),
+ lp_t_name,
+ lp_x_name,
+ lp_y_name,
+ lp_x_name,
+ lp_y_name,
+ lp_z_name,
+ lp_x_name,
+ lp_y_name);
+ gtk_label_set_text (GTK_LABEL (parametric_info_label), s);
+ g_free (s);
+ }
+
+ if (parametric_x_label != NULL) {
+ s = g_strdup_printf ("%s=",
+ lp_x_name);
+ gtk_label_set_text (GTK_LABEL (parametric_x_label), s);
+ g_free (s);
+ }
+
+ if (parametric_y_label != NULL) {
+ s = g_strdup_printf ("%s=",
+ lp_y_name);
+ gtk_label_set_text (GTK_LABEL (parametric_y_label), s);
+ g_free (s);
+ }
+
+ if (parametric_z_label != NULL) {
+ s = g_strdup_printf ("%s=",
+ lp_z_name);
+ gtk_label_set_text (GTK_LABEL (parametric_z_label), s);
+ g_free (s);
+ }
+
+ if (parametric_trange_label != NULL) {
+ s = g_strdup_printf (_("Parameter %s from:"),
+ lp_t_name);
+ gtk_label_set_text (GTK_LABEL (parametric_trange_label), s);
+ g_free (s);
+ }
+}
+
+static char *
+get_varname_from_entry (GtkEntry *e, const char *def, gboolean *ex)
+{
+ char *str = g_strdup (gtk_entry_get_text (GTK_ENTRY (e)));
+ if (ve_string_empty (str)) {
+ g_free (str);
+ *ex = TRUE;
+ return g_strdup (def);
+ }
+
+ if ( ! is_identifier (str))
+ *ex = TRUE;
+
+ str = g_strcanon (str,
+ G_CSET_a_2_z G_CSET_A_2_Z G_CSET_DIGITS "_",
+ '_');
+ if (str[0] >= '0' && str[0] <= '9') {
+ *ex = TRUE;
+ str[0] = '_';
+ }
+
+ return str;
+}
+
+static void
+change_lineplot_varnames (GtkWidget *button, gpointer data)
+{
+ GtkWidget *req = NULL;
+ GtkWidget *b, *l;
+ GtkWidget *xe;
+ GtkWidget *ye;
+ GtkWidget *ze;
+ GtkWidget *te;
+ GtkWidget *errlabel;
+ GtkSizeGroup *sg;
+
+ req = gtk_dialog_new_with_buttons
+ (_("Change variable names") /* title */,
+ GTK_WINDOW (graph_window) /* parent */,
+ GTK_DIALOG_MODAL /* flags */,
+ GTK_STOCK_OK,
+ GTK_RESPONSE_OK,
+ GTK_STOCK_CANCEL,
+ GTK_RESPONSE_CANCEL,
+ NULL);
+
+ gtk_dialog_set_default_response (GTK_DIALOG (req),
+ GTK_RESPONSE_OK);
+
+ gtk_dialog_set_has_separator (GTK_DIALOG (req), FALSE);
+
+ sg = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
+
+ errlabel = gtk_label_new (_("Some values were illegal"));
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (req)->vbox),
+ errlabel, FALSE, FALSE, 0);
+
+ b = create_simple_expression_box (_("independent variable (x):"),
+ &l, &xe);
+ gtk_misc_set_alignment (GTK_MISC (l), 0.0, 0.5);
+ gtk_size_group_add_widget (sg, l);
+ gtk_entry_set_text (GTK_ENTRY (xe), lp_x_name);
+ g_signal_connect (G_OBJECT (xe), "activate",
+ G_CALLBACK (ok_dialog_entry_activate), req);
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (req)->vbox),
+ b, FALSE, FALSE, 0);
+
+ b = create_simple_expression_box (_("dependent variable (y):"),
+ &l, &ye);
+ gtk_misc_set_alignment (GTK_MISC (l), 0.0, 0.5);
+ gtk_size_group_add_widget (sg, l);
+ gtk_entry_set_text (GTK_ENTRY (ye), lp_y_name);
+ g_signal_connect (G_OBJECT (ye), "activate",
+ G_CALLBACK (ok_dialog_entry_activate), req);
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (req)->vbox),
+ b, FALSE, FALSE, 0);
+
+ b = create_simple_expression_box (_("complex variable (z = x+iy):"),
+ &l, &ze);
+ gtk_misc_set_alignment (GTK_MISC (l), 0.0, 0.5);
+ gtk_size_group_add_widget (sg, l);
+ gtk_entry_set_text (GTK_ENTRY (ze), lp_z_name);
+ g_signal_connect (G_OBJECT (ze), "activate",
+ G_CALLBACK (ok_dialog_entry_activate), req);
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (req)->vbox),
+ b, FALSE, FALSE, 0);
+
+ b = create_simple_expression_box (_("parameter variable (t):"),
+ &l, &te);
+ gtk_misc_set_alignment (GTK_MISC (l), 0.0, 0.5);
+ gtk_size_group_add_widget (sg, l);
+ gtk_entry_set_text (GTK_ENTRY (te), lp_t_name);
+ g_signal_connect (G_OBJECT (te), "activate",
+ G_CALLBACK (ok_dialog_entry_activate), req);
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (req)->vbox),
+ b, FALSE, FALSE, 0);
+
+ gtk_widget_show_all (req);
+ gtk_widget_hide (errlabel);
+
+run_dialog_again:
+
+ if (gtk_dialog_run (GTK_DIALOG (req)) == GTK_RESPONSE_OK) {
+ gboolean ex = FALSE;
+ char *xn, *yn, *zn, *tn;
+
+ xn = get_varname_from_entry (GTK_ENTRY (xe), "x", &ex);
+ yn = get_varname_from_entry (GTK_ENTRY (ye), "y", &ex);
+ zn = get_varname_from_entry (GTK_ENTRY (ze), "z", &ex);
+ tn = get_varname_from_entry (GTK_ENTRY (te), "t", &ex);
+ if (strcmp (xn, yn) == 0 ||
+ strcmp (xn, zn) == 0 ||
+ strcmp (xn, tn) == 0 ||
+ strcmp (yn, zn) == 0 ||
+ strcmp (yn, tn) == 0 ||
+ strcmp (zn, tn) == 0)
+ ex = TRUE;
+ if (ex) {
+ gtk_entry_set_text (GTK_ENTRY (xe), xn);
+ gtk_entry_set_text (GTK_ENTRY (ye), yn);
+ gtk_entry_set_text (GTK_ENTRY (ze), zn);
+ gtk_entry_set_text (GTK_ENTRY (te), tn);
+ g_free (xn);
+ g_free (yn);
+ g_free (zn);
+ g_free (tn);
+ gtk_widget_show (errlabel);
+ goto run_dialog_again;
+ }
+
+ g_free (lp_x_name);
+ g_free (lp_y_name);
+ g_free (lp_z_name);
+ g_free (lp_t_name);
+ lp_x_name = xn;
+ lp_y_name = yn;
+ lp_z_name = zn;
+ lp_t_name = tn;
+ }
+ gtk_widget_destroy (req);
+
+ set_lineplot_labels ();
+}
+
static GtkWidget *
create_lineplot_box (void)
{
GtkWidget *mainbox, *frame;
- GtkWidget *box, *b, *fb, *w;
+ GtkWidget *box, *hbox, *b, *fb, *w;
+ char *s;
int i;
+ init_var_names ();
mainbox = gtk_vbox_new (FALSE, GENIUS_PAD);
gtk_container_set_border_width (GTK_CONTAINER (mainbox), GENIUS_PAD);
@@ -4017,13 +4537,15 @@ create_lineplot_box (void)
*/
box = gtk_vbox_new (FALSE, GENIUS_PAD);
gtk_container_set_border_width (GTK_CONTAINER (box), GENIUS_PAD);
- w = gtk_label_new (_("Type in function names or expressions involving "
- "the x variable in the boxes below to graph "
- "them"));
- gtk_misc_set_alignment (GTK_MISC (w), 0.0, 0.5);
- gtk_label_set_line_wrap (GTK_LABEL (w), TRUE);
- gtk_widget_set_size_request (w, 610, -1);
- gtk_box_pack_start (GTK_BOX (box), w, FALSE, FALSE, 0);
+ lineplot_info_label = gtk_label_new ("");
+ gtk_misc_set_alignment (GTK_MISC (lineplot_info_label), 0.0, 0.5);
+ gtk_label_set_line_wrap (GTK_LABEL (lineplot_info_label), TRUE);
+ gtk_widget_set_size_request (lineplot_info_label, 610, -1);
+ gtk_box_pack_start (GTK_BOX (box), lineplot_info_label, FALSE, FALSE, 0);
+ g_signal_connect (G_OBJECT (lineplot_info_label),
+ "destroy",
+ G_CALLBACK (gtk_widget_destroyed),
+ &lineplot_info_label);
fb = box;
@@ -4047,6 +4569,7 @@ create_lineplot_box (void)
for (i = 0; i < MAXFUNC; i++) {
b = create_expression_box ("y=",
+ &(plot_y_labels[i]),
&(plot_entries[i]),
&(plot_entries_status[i]));
gtk_box_pack_start (GTK_BOX (fb), b, FALSE, FALSE, 0);
@@ -4062,26 +4585,26 @@ create_lineplot_box (void)
box = gtk_vbox_new (FALSE, GENIUS_PAD);
gtk_container_set_border_width (GTK_CONTAINER (box), GENIUS_PAD);
- w = gtk_label_new (_("Type in function names or expressions involving "
- "the t variable in the boxes below to graph "
- "them. Either fill in both boxes with x= and y= "
- "in front of them giving the x and y coordinates "
- "separately, or alternatively fill in the z= box "
- "giving x and y as the real and imaginary part of "
- "a complex number."));
- gtk_misc_set_alignment (GTK_MISC (w), 0.0, 0.5);
- gtk_label_set_line_wrap (GTK_LABEL (w), TRUE);
- gtk_widget_set_size_request (w, 610, -1);
- gtk_box_pack_start (GTK_BOX (box), w, FALSE, FALSE, 0);
+ parametric_info_label = gtk_label_new ("");
+ gtk_misc_set_alignment (GTK_MISC (parametric_info_label), 0.0, 0.5);
+ gtk_label_set_line_wrap (GTK_LABEL (parametric_info_label), TRUE);
+ gtk_widget_set_size_request (parametric_info_label, 610, -1);
+ gtk_box_pack_start (GTK_BOX (box), parametric_info_label, FALSE, FALSE, 0);
+ g_signal_connect (G_OBJECT (parametric_info_label),
+ "destroy",
+ G_CALLBACK (gtk_widget_destroyed),
+ ¶metric_info_label);
/* x */
b = create_expression_box ("x=",
+ ¶metric_x_label,
¶metric_entry_x,
¶metric_status_x);
gtk_box_pack_start (GTK_BOX (box), b, FALSE, FALSE, 0);
/* y */
b = create_expression_box ("y=",
+ ¶metric_y_label,
¶metric_entry_y,
¶metric_status_y);
gtk_box_pack_start (GTK_BOX (box), b, FALSE, FALSE, 0);
@@ -4092,6 +4615,7 @@ create_lineplot_box (void)
/* z */
b = create_expression_box ("z=",
+ ¶metric_z_label,
¶metric_entry_z,
¶metric_status_z);
gtk_box_pack_start (GTK_BOX (box), b, FALSE, FALSE, 0);
@@ -4100,9 +4624,13 @@ create_lineplot_box (void)
gtk_box_pack_start (GTK_BOX (box), gtk_label_new (""), FALSE, FALSE, 0);
/* t range */
- b = create_range_spinboxes (_("Parameter t from:"), &spint1, NULL,
+ b = create_range_spinboxes (_("Parameter t from:"),
+ ¶metric_trange_label,
+ &spint1, NULL,
-G_MAXDOUBLE, G_MAXDOUBLE, 1,
- _("to:"), &spint2, NULL,
+ _("to:"),
+ NULL,
+ &spint2, NULL,
-G_MAXDOUBLE, G_MAXDOUBLE, 1,
_("by:"), &spintinc, NULL,
-G_MAXDOUBLE, G_MAXDOUBLE, 1,
@@ -4119,17 +4647,20 @@ create_lineplot_box (void)
box = gtk_vbox_new (FALSE, GENIUS_PAD);
gtk_container_set_border_width (GTK_CONTAINER (box), GENIUS_PAD);
- w = gtk_label_new (_("Type in function name or expression involving "
- "the x and y variables (or the z variable which will be z=x+iy) "
- "that gives the slope "
- "at the point (x,y)."));
- gtk_misc_set_alignment (GTK_MISC (w), 0.0, 0.5);
- gtk_label_set_line_wrap (GTK_LABEL (w), TRUE);
- gtk_widget_set_size_request (w, 610, -1);
- gtk_box_pack_start (GTK_BOX (box), w, FALSE, FALSE, 0);
+
+ slopefield_info_label = gtk_label_new ("");
+ gtk_misc_set_alignment (GTK_MISC (slopefield_info_label), 0.0, 0.5);
+ gtk_label_set_line_wrap (GTK_LABEL (slopefield_info_label), TRUE);
+ gtk_widget_set_size_request (slopefield_info_label, 610, -1);
+ gtk_box_pack_start (GTK_BOX (box), slopefield_info_label, FALSE, FALSE, 0);
+ g_signal_connect (G_OBJECT (slopefield_info_label),
+ "destroy",
+ G_CALLBACK (gtk_widget_destroyed),
+ &slopefield_info_label);
/* dy/dx */
b = create_expression_box ("dy/dx=",
+ &slopefield_der_label,
&slopefield_entry,
&slopefield_status);
gtk_box_pack_start (GTK_BOX (box), b, FALSE, FALSE, 0);
@@ -4152,23 +4683,27 @@ create_lineplot_box (void)
box = gtk_vbox_new (FALSE, GENIUS_PAD);
gtk_container_set_border_width (GTK_CONTAINER (box), GENIUS_PAD);
- w = gtk_label_new (_("Type in function names or expressions involving "
- "the x and y variables (or the z variable which will be z=x+iy) "
- "that give the dx/dt and dy/dt of the autonomous system to be plotted "
- "at the point (x,y)."));
- gtk_misc_set_alignment (GTK_MISC (w), 0.0, 0.5);
- gtk_label_set_line_wrap (GTK_LABEL (w), TRUE);
- gtk_widget_set_size_request (w, 610, -1);
- gtk_box_pack_start (GTK_BOX (box), w, FALSE, FALSE, 0);
+ vectorfield_info_label = gtk_label_new ("");
+
+ gtk_misc_set_alignment (GTK_MISC (vectorfield_info_label), 0.0, 0.5);
+ gtk_label_set_line_wrap (GTK_LABEL (vectorfield_info_label), TRUE);
+ gtk_widget_set_size_request (vectorfield_info_label, 610, -1);
+ gtk_box_pack_start (GTK_BOX (box), vectorfield_info_label, FALSE, FALSE, 0);
+ g_signal_connect (G_OBJECT (vectorfield_info_label),
+ "destroy",
+ G_CALLBACK (gtk_widget_destroyed),
+ &vectorfield_info_label);
/* dx/dt */
b = create_expression_box ("dx/dt=",
+ &vectorfield_xder_label,
&vectorfield_entry_x,
&vectorfield_status_x);
gtk_box_pack_start (GTK_BOX (box), b, FALSE, FALSE, 0);
/* dy/dt */
b = create_expression_box ("dy/dt=",
+ &vectorfield_yder_label,
&vectorfield_entry_y,
&vectorfield_status_y);
gtk_box_pack_start (GTK_BOX (box), b, FALSE, FALSE, 0);
@@ -4198,15 +4733,27 @@ create_lineplot_box (void)
* Below notebook
*/
+ hbox = gtk_hbox_new (FALSE, GENIUS_PAD);
+ gtk_box_pack_start (GTK_BOX (mainbox), hbox, FALSE, FALSE, 0);
+
+ /* draw legend? */
w = gtk_check_button_new_with_mnemonic (_("_Draw legend"));
- gtk_box_pack_start (GTK_BOX (mainbox), w, FALSE, FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (hbox), w, FALSE, FALSE, 0);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w),
lineplot_draw_legends_cb);
g_signal_connect (G_OBJECT (w), "toggled",
G_CALLBACK (optioncb),
(gpointer)&lineplot_draw_legends_cb);
+ /* change varnames */
+ b = gtk_button_new_with_label (_("Change variable names..."));
+ gtk_box_pack_end (GTK_BOX (hbox), b, FALSE, FALSE, 0);
+ g_signal_connect (G_OBJECT (b), "clicked",
+ G_CALLBACK (change_lineplot_varnames), NULL);
+
+
+ /* plot window */
frame = gtk_frame_new (_("Plot Window"));
gtk_box_pack_start (GTK_BOX (mainbox), frame, FALSE, FALSE, 0);
box = gtk_vbox_new (FALSE, GENIUS_PAD);
@@ -4216,9 +4763,10 @@ create_lineplot_box (void)
/*
* X range
*/
- b = create_range_spinboxes (_("X from:"), &spinx1, NULL,
+ b = create_range_spinboxes (_("X from:"), &lineplot_x_range_label,
+ &spinx1, NULL,
-G_MAXDOUBLE, G_MAXDOUBLE, 1,
- _("to:"), &spinx2, NULL,
+ _("to:"), NULL, &spinx2, NULL,
-G_MAXDOUBLE, G_MAXDOUBLE, 1,
NULL, NULL, NULL, 0, 0, 0,
entry_activate);
@@ -4227,14 +4775,18 @@ create_lineplot_box (void)
/*
* Y range
*/
- b = create_range_spinboxes (_("Y from:"), &spiny1, NULL,
+ b = create_range_spinboxes (_("Y from:"), &lineplot_y_range_label,
+ &spiny1, NULL,
-G_MAXDOUBLE, G_MAXDOUBLE, 1,
- _("to:"), &spiny2, NULL,
+ _("to:"), NULL, &spiny2, NULL,
-G_MAXDOUBLE, G_MAXDOUBLE, 1,
NULL, NULL, NULL, 0, 0, 0,
entry_activate);
gtk_box_pack_start (GTK_BOX(box), b, FALSE, FALSE, 0);
+ /* set labels correclty */
+ set_lineplot_labels ();
+
return mainbox;
}
@@ -4282,9 +4834,9 @@ create_surface_box (void)
/*
* X range
*/
- b = create_range_spinboxes (_("X from:"), &surf_spinx1, NULL,
+ b = create_range_spinboxes (_("X from:"), NULL, &surf_spinx1, NULL,
-G_MAXDOUBLE, G_MAXDOUBLE, 1,
- _("to:"), &surf_spinx2, NULL,
+ _("to:"), NULL, &surf_spinx2, NULL,
-G_MAXDOUBLE, G_MAXDOUBLE, 1,
NULL, NULL, NULL, 0, 0, 0,
entry_activate);
@@ -4293,9 +4845,9 @@ create_surface_box (void)
/*
* Y range
*/
- b = create_range_spinboxes (_("Y from:"), &surf_spiny1, NULL,
+ b = create_range_spinboxes (_("Y from:"), NULL, &surf_spiny1, NULL,
-G_MAXDOUBLE, G_MAXDOUBLE, 1,
- _("to:"), &surf_spiny2, NULL,
+ _("to:"), NULL, &surf_spiny2, NULL,
-G_MAXDOUBLE, G_MAXDOUBLE, 1,
NULL, NULL, NULL, 0, 0, 0,
entry_activate);
@@ -4304,9 +4856,9 @@ create_surface_box (void)
/*
* Z range
*/
- b = create_range_spinboxes (_("Z from:"), &surf_spinz1, NULL,
+ b = create_range_spinboxes (_("Z from:"), NULL, &surf_spinz1, NULL,
-G_MAXDOUBLE, G_MAXDOUBLE, 1,
- _("to:"), &surf_spinz2, NULL,
+ _("to:"), NULL, &surf_spinz2, NULL,
-G_MAXDOUBLE, G_MAXDOUBLE, 1,
NULL, NULL, NULL, 0, 0, 0,
entry_activate);
@@ -4331,42 +4883,6 @@ create_plot_dialog (void)
return plot_notebook;
}
-static gboolean
-is_letter_or_underscore (char l)
-{
- if ((l >= 'a' && l <= 'z') ||
- (l >= 'A' && l <= 'Z') ||
- l == '_')
- return TRUE;
- else
- return FALSE;
-}
-
-static gboolean
-is_letter_underscore_or_number (char l)
-{
- if ((l >= 'a' && l <= 'z') ||
- (l >= 'A' && l <= 'Z') ||
- (l >= '0' && l <= '9') ||
- l == '_')
- return TRUE;
- else
- return FALSE;
-}
-
-static gboolean
-is_identifier (const char *e)
-{
- int i;
- if ( ! is_letter_or_underscore (e[0]))
- return FALSE;
- for (i = 1; e[i] != '\0'; i++) {
- if ( ! is_letter_underscore_or_number (e[i]))
- return FALSE;
- }
- return TRUE;
-}
-
static GelEFunc *
function_from_expression (const char *e, const char *var, gboolean *ex)
{
@@ -4419,7 +4935,11 @@ function_from_expression (const char *e, const char *var, gboolean *ex)
}
static GelEFunc *
-function_from_expression2 (const char *e, gboolean *ex)
+function_from_expression2 (const char *e,
+ const char *xname,
+ const char *yname,
+ const char *zname,
+ gboolean *ex)
{
GelEFunc *f = NULL;
GelETree *value;
@@ -4431,9 +4951,9 @@ function_from_expression2 (const char *e, gboolean *ex)
ce = g_strstrip (g_strdup (e));
if (is_identifier (ce) &&
- strcmp (ce, "x") != 0 &&
- strcmp (ce, "y") != 0 &&
- strcmp (ce, "z") != 0) {
+ strcmp (ce, xname) != 0 &&
+ strcmp (ce, yname) != 0 &&
+ strcmp (ce, zname) != 0) {
f = d_lookup_global (d_intern (ce));
g_free (ce);
if (f != NULL) {
@@ -4458,30 +4978,30 @@ function_from_expression2 (const char *e, gboolean *ex)
gel_got_eof = FALSE;
/* FIXME: funcbody? I think it must be done. */
- got_x = gel_eval_find_identifier (value, d_intern ("x"), TRUE /*funcbody*/);
- got_y = gel_eval_find_identifier (value, d_intern ("y"), TRUE /*funcbody*/);
- got_z = gel_eval_find_identifier (value, d_intern ("z"), TRUE /*funcbody*/);
+ got_x = gel_eval_find_identifier (value, d_intern (xname), TRUE /*funcbody*/);
+ got_y = gel_eval_find_identifier (value, d_intern (yname), TRUE /*funcbody*/);
+ got_z = gel_eval_find_identifier (value, d_intern (zname), TRUE /*funcbody*/);
/* FIXME: if "x" or "y" or "z" not used try to evaluate and if it returns a function use that */
if (value != NULL) {
if ( ! got_x && ! got_y && got_z) {
f = d_makeufunc (NULL /* id */,
value,
- g_slist_append (NULL, d_intern ("z")),
+ g_slist_append (NULL, d_intern (zname)),
1,
NULL /* extra_dict */);
} else if ( ! got_z) {
- GSList *l = g_slist_append (NULL, d_intern ("x"));
- l = g_slist_append (l, d_intern ("y"));
+ GSList *l = g_slist_append (NULL, d_intern (xname));
+ l = g_slist_append (l, d_intern (yname));
f = d_makeufunc (NULL /* id */,
value,
l,
2,
NULL /* extra_dict */);
} else {
- GSList *l = g_slist_append (NULL, d_intern ("x"));
- l = g_slist_append (l, d_intern ("y"));
- l = g_slist_append (l, d_intern ("z"));
+ GSList *l = g_slist_append (NULL, d_intern (xname));
+ l = g_slist_append (l, d_intern (yname));
+ l = g_slist_append (l, d_intern (zname));
f = d_makeufunc (NULL /* id */,
value,
l,
@@ -4526,11 +5046,14 @@ get_func_from_entry (GtkWidget *entry, GtkWidget *status,
static GelEFunc *
get_func_from_entry2 (GtkWidget *entry, GtkWidget *status,
+ const char *xname,
+ const char *yname,
+ const char *zname,
gboolean *ex)
{
GelEFunc *f;
const char *str = gtk_entry_get_text (GTK_ENTRY (entry));
- f = function_from_expression2 (str, ex);
+ f = function_from_expression2 (str, xname, yname, zname, ex);
if (f != NULL) {
gtk_image_set_from_stock
(GTK_IMAGE (status),
@@ -4569,7 +5092,8 @@ surface_from_dialog (void)
genius_setup.error_box = TRUE;
ex = FALSE;
- func = get_func_from_entry2 (surface_entry, surface_entry_status, &ex);
+ func = get_func_from_entry2 (surface_entry, surface_entry_status,
+ "x", "y", "z", &ex);
if (func == NULL) {
error_to_print = _("No functions to plot or no functions "
@@ -4723,7 +5247,7 @@ plot_from_dialog_lineplot (void)
gboolean ex = FALSE;
f = get_func_from_entry (plot_entries[i],
plot_entries_status[i],
- "x",
+ lp_x_name,
&ex);
if (f != NULL) {
func[i] = f;
@@ -4783,7 +5307,8 @@ plot_from_dialog_lineplot (void)
}
}
- plot_functions (TRUE /* do_window_present */);
+ plot_functions (TRUE /* do_window_present */,
+ TRUE /* from_gui */);
if (gel_interrupted)
gel_interrupted = FALSE;
@@ -4817,7 +5342,7 @@ plot_from_dialog_parametric (void)
double x1, x2, y1, y2;
gboolean last_info;
gboolean last_error;
- const char *error_to_print = NULL;
+ char *error_to_print = NULL;
gboolean exx = FALSE;
gboolean exy = FALSE;
gboolean exz = FALSE;
@@ -4831,31 +5356,32 @@ plot_from_dialog_parametric (void)
funcpx = get_func_from_entry (parametric_entry_x,
parametric_status_x,
- "t",
+ lp_t_name,
&exx);
funcpy = get_func_from_entry (parametric_entry_y,
parametric_status_y,
- "t",
+ lp_t_name,
&exy);
funcpz = get_func_from_entry (parametric_entry_z,
parametric_status_z,
- "t",
+ lp_t_name,
&exz);
if (((funcpx || exx) || (funcpy || exy)) && (funcpz || exz)) {
- error_to_print = _("Only specify x and y, or z, not all at once.");
+ error_to_print = g_strdup_printf (_("Only specify %s and %s, or %s, not all at once."), lp_x_name, lp_y_name, lp_z_name);
goto whack_copied_funcs;
}
if ( ! ( (funcpz == NULL && funcpx != NULL && funcpy != NULL) ||
(funcpz != NULL && funcpx == NULL && funcpy == NULL))) {
- error_to_print = _("No functions to plot or no functions "
- "could be parsed");
+ error_to_print = g_strdup (_("No functions to plot or no functions "
+ "could be parsed"));
goto whack_copied_funcs;
}
if (spint1 >= spint2 ||
spintinc <= 0.0) {
- error_to_print = _("Invalid t range");
+ error_to_print = g_strdup_printf (_("Invalid %s range"),
+ lp_t_name);
goto whack_copied_funcs;
}
@@ -4877,12 +5403,14 @@ plot_from_dialog_parametric (void)
}
if (x1 == x2) {
- error_to_print = _("Invalid X range");
+ error_to_print = g_strdup_printf (_("Invalid %s range"),
+ lp_x_name);
goto whack_copied_funcs;
}
if (y1 == y2) {
- error_to_print = _("Invalid Y range");
+ error_to_print = g_strdup_printf (_("Invalid %s range"),
+ lp_y_name);
goto whack_copied_funcs;
}
@@ -4909,7 +5437,8 @@ plot_from_dialog_parametric (void)
NULL);
}
- plot_functions (TRUE /* do_window_present */);
+ plot_functions (TRUE /* do_window_present */,
+ TRUE /* from_gui */);
if (gel_interrupted)
gel_interrupted = FALSE;
@@ -4932,8 +5461,10 @@ whack_copied_funcs:
genius_setup.info_box = last_info;
genius_setup.error_box = last_error;
- if (error_to_print != NULL)
+ if (error_to_print != NULL) {
genius_display_error (plot_dialog, error_to_print);
+ g_free (error_to_print);
+ }
}
static void
@@ -4943,7 +5474,7 @@ plot_from_dialog_slopefield (void)
double x1, x2, y1, y2;
gboolean last_info;
gboolean last_error;
- const char *error_to_print = NULL;
+ char *error_to_print = NULL;
gboolean ex = FALSE;
plot_mode = MODE_LINEPLOT_SLOPEFIELD;
@@ -4953,12 +5484,18 @@ plot_from_dialog_slopefield (void)
genius_setup.info_box = TRUE;
genius_setup.error_box = TRUE;
+ init_var_names ();
+
ex = FALSE;
- funcp = get_func_from_entry2 (slopefield_entry, slopefield_status, &ex);
+ funcp = get_func_from_entry2 (slopefield_entry, slopefield_status,
+ lp_x_name,
+ lp_y_name,
+ lp_z_name,
+ &ex);
if (funcp == NULL) {
- error_to_print = _("No functions to plot or no functions "
- "could be parsed");
+ error_to_print = g_strdup(_("No functions to plot or no functions "
+ "could be parsed"));
goto whack_copied_funcs;
}
@@ -4980,12 +5517,14 @@ plot_from_dialog_slopefield (void)
}
if (x1 == x2) {
- error_to_print = _("Invalid X range");
+ error_to_print = g_strdup_printf (_("Invalid %s range"),
+ lp_x_name);
goto whack_copied_funcs;
}
if (y1 == y2) {
- error_to_print = _("Invalid Y range");
+ error_to_print = g_strdup_printf (_("Invalid %s range"),
+ lp_y_name);
goto whack_copied_funcs;
}
@@ -5002,7 +5541,8 @@ plot_from_dialog_slopefield (void)
slopefield_func = funcp;
slopefield_name = g_strdup (gtk_entry_get_text (GTK_ENTRY (slopefield_entry)));
- plot_functions (TRUE /* do_window_present */);
+ plot_functions (TRUE /* do_window_present */,
+ TRUE /* from_gui */);
if (gel_interrupted)
gel_interrupted = FALSE;
@@ -5021,8 +5561,10 @@ whack_copied_funcs:
genius_setup.info_box = last_info;
genius_setup.error_box = last_error;
- if (error_to_print != NULL)
+ if (error_to_print != NULL) {
genius_display_error (plot_dialog, error_to_print);
+ g_free (error_to_print);
+ }
}
static void
@@ -5033,7 +5575,7 @@ plot_from_dialog_vectorfield (void)
double x1, x2, y1, y2;
gboolean last_info;
gboolean last_error;
- const char *error_to_print = NULL;
+ char *error_to_print = NULL;
gboolean ex = FALSE;
plot_mode = MODE_LINEPLOT_VECTORFIELD;
@@ -5047,13 +5589,17 @@ plot_from_dialog_vectorfield (void)
vectorfield_normalize_arrow_length_cb;
ex = FALSE;
- funcpx = get_func_from_entry2 (vectorfield_entry_x, vectorfield_status_x, &ex);
+ funcpx = get_func_from_entry2 (vectorfield_entry_x,
+ vectorfield_status_x,
+ lp_x_name, lp_y_name, lp_z_name, &ex);
ex = FALSE;
- funcpy = get_func_from_entry2 (vectorfield_entry_y, vectorfield_status_y, &ex);
+ funcpy = get_func_from_entry2 (vectorfield_entry_y,
+ vectorfield_status_y,
+ lp_x_name, lp_y_name, lp_z_name, &ex);
if (funcpx == NULL || funcpy == NULL) {
- error_to_print = _("No functions to plot or no functions "
- "could be parsed");
+ error_to_print = g_strdup (_("No functions to plot or no functions "
+ "could be parsed"));
goto whack_copied_funcs;
}
@@ -5075,12 +5621,14 @@ plot_from_dialog_vectorfield (void)
}
if (x1 == x2) {
- error_to_print = _("Invalid X range");
+ error_to_print = g_strdup_printf (_("Invalid %s range"),
+ lp_x_name);
goto whack_copied_funcs;
}
if (y1 == y2) {
- error_to_print = _("Invalid Y range");
+ error_to_print = g_strdup_printf (_("Invalid %s range"),
+ lp_y_name);
goto whack_copied_funcs;
}
@@ -5099,7 +5647,8 @@ plot_from_dialog_vectorfield (void)
vectorfield_name_x = g_strdup (gtk_entry_get_text (GTK_ENTRY (vectorfield_entry_x)));
vectorfield_name_y = g_strdup (gtk_entry_get_text (GTK_ENTRY (vectorfield_entry_y)));
- plot_functions (TRUE /* do_window_present */);
+ plot_functions (TRUE /* do_window_present */,
+ TRUE /* from_gui */);
if (gel_interrupted)
gel_interrupted = FALSE;
@@ -5120,8 +5669,10 @@ whack_copied_funcs:
genius_setup.info_box = last_info;
genius_setup.error_box = last_error;
- if (error_to_print != NULL)
+ if (error_to_print != NULL) {
genius_display_error (plot_dialog, error_to_print);
+ g_free (error_to_print);
+ }
}
static void
@@ -5549,7 +6100,8 @@ SlopefieldPlot_op (GelCtx *ctx, GelETree * * a, int *exception)
plotHtick = plot_sf_Htick;
plot_mode = MODE_LINEPLOT_SLOPEFIELD;
- plot_functions (FALSE /* do_window_present */);
+ plot_functions (FALSE /* do_window_present */,
+ FALSE /* from gui */);
if (gel_interrupted)
return NULL;
@@ -5668,7 +6220,8 @@ VectorfieldPlot_op (GelCtx *ctx, GelETree * * a, int *exception)
plotHtick = plot_vf_Htick;
plot_mode = MODE_LINEPLOT_VECTORFIELD;
- plot_functions (FALSE /* do_window_present */);
+ plot_functions (FALSE /* do_window_present */,
+ FALSE /* from_gui */);
if (gel_interrupted)
return NULL;
@@ -5785,7 +6338,8 @@ LinePlot_op (GelCtx *ctx, GelETree * * a, int *exception)
reset_ploty2 = ploty2 = y2;
plot_mode = MODE_LINEPLOT;
- plot_functions (FALSE /* do_window_present */);
+ plot_functions (FALSE /* do_window_present */,
+ FALSE /* from_gui */);
if G_UNLIKELY (gel_interrupted)
return NULL;
@@ -5928,7 +6482,8 @@ LinePlotParametric_op (GelCtx *ctx, GelETree * * a, int *exception)
plottinc = tinc;
plot_mode = MODE_LINEPLOT_PARAMETRIC;
- plot_functions (FALSE /* do_window_present */);
+ plot_functions (FALSE /* do_window_present */,
+ FALSE /* from_gui */ );
if G_UNLIKELY (gel_interrupted)
return NULL;
@@ -6067,7 +6622,8 @@ LinePlotCParametric_op (GelCtx *ctx, GelETree * * a, int *exception)
plottinc = tinc;
plot_mode = MODE_LINEPLOT_PARAMETRIC;
- plot_functions (FALSE /* do_window_present */);
+ plot_functions (FALSE /* do_window_present */,
+ FALSE /* from_gui */);
if G_UNLIKELY (gel_interrupted)
return NULL;
@@ -6094,7 +6650,8 @@ LinePlotClear_op (GelCtx *ctx, GelETree * * a, int *exception)
/* This will just clear the window */
plot_mode = MODE_LINEPLOT;
- plot_functions (FALSE /* do_window_present */);
+ plot_functions (FALSE /* do_window_present */,
+ FALSE /* from_gui */);
if G_UNLIKELY (gel_interrupted)
return NULL;
@@ -6611,7 +7168,6 @@ static GelETree *
set_SlopefieldTicks (GelETree * a)
{
int v, h;
- gboolean update = FALSE;
if G_UNLIKELY (plot_in_progress != 0) {
gel_errorout (_("%s: Plotting in progress, cannot call %s"),
@@ -6638,7 +7194,6 @@ static GelETree *
set_VectorfieldTicks (GelETree * a)
{
int v, h;
- gboolean update = FALSE;
if G_UNLIKELY (plot_in_progress != 0) {
gel_errorout (_("%s: Plotting in progress, cannot call %s"),
@@ -6662,6 +7217,93 @@ get_VectorfieldTicks (void)
}
static GelETree *
+set_LinePlotVariableNames (GelETree * a)
+{
+ GelETree *t;
+ char *sx, *sy, *sz, *st;
+
+ if G_UNLIKELY (plot_in_progress != 0) {
+ gel_errorout (_("%s: Plotting in progress, cannot call %s"),
+ "set_LinePlotVariableNames", "set_LinePlotVariableNames");
+ return NULL;
+ }
+
+ if (a->type != GEL_MATRIX_NODE ||
+ gel_matrixw_elements (a->mat.matrix) != 4) {
+ gel_errorout (_("Variable names not given in a 4-vector"));
+ return NULL;
+ }
+
+ t = gel_matrixw_vindex (a->mat.matrix, 0);
+ if (t->type == GEL_IDENTIFIER_NODE) {
+ sx = t->id.id->token;
+ } else if (t->type == GEL_STRING_NODE) {
+ sx = t->str.str;
+ } else {
+ gel_errorout (_("Variable names should be strings"));
+ return NULL;
+ }
+ t = gel_matrixw_vindex (a->mat.matrix, 1);
+ if (t->type == GEL_IDENTIFIER_NODE) {
+ sy = t->id.id->token;
+ } else if (t->type == GEL_STRING_NODE) {
+ sy = t->str.str;
+ } else {
+ gel_errorout (_("Variable names should be strings"));
+ return NULL;
+ }
+ t = gel_matrixw_vindex (a->mat.matrix, 2);
+ if (t->type == GEL_IDENTIFIER_NODE) {
+ sz = t->id.id->token;
+ } else if (t->type == GEL_STRING_NODE) {
+ sz = t->str.str;
+ } else {
+ gel_errorout (_("Variable names should be strings"));
+ return NULL;
+ }
+ t = gel_matrixw_vindex (a->mat.matrix, 3);
+ if (t->type == GEL_IDENTIFIER_NODE) {
+ st = t->id.id->token;
+ } else if (t->type == GEL_STRING_NODE) {
+ st = t->str.str;
+ } else {
+ gel_errorout (_("Variable names should be strings"));
+ return NULL;
+ }
+ if ( ! is_identifier (sx) ||
+ ! is_identifier (sy) ||
+ ! is_identifier (sz) ||
+ ! is_identifier (st)) {
+ gel_errorout (_("Variable names must be valid identifiers"));
+ return NULL;
+ }
+ if (strcmp (sx, sy) == 0 ||
+ strcmp (sx, sz) == 0 ||
+ strcmp (sx, st) == 0 ||
+ strcmp (sy, sz) == 0 ||
+ strcmp (sy, st) == 0 ||
+ strcmp (sz, st) == 0) {
+ gel_errorout (_("Variable names must be mutually distinct"));
+ return NULL;
+ }
+
+ lp_x_name = g_strdup (sx);
+ lp_y_name = g_strdup (sy);
+ lp_z_name = g_strdup (sz);
+ lp_t_name = g_strdup (st);
+
+ set_lineplot_labels ();
+
+ return make_matrix_from_lp_varnames ();
+}
+
+static GelETree *
+get_LinePlotVariableNames (void)
+{
+ return make_matrix_from_lp_varnames ();
+}
+
+static GelETree *
set_VectorfieldNormalized (GelETree * a)
{
if G_UNLIKELY (plot_in_progress != 0) {
@@ -6748,6 +7390,7 @@ gel_add_graph_functions (void)
PARAMETER (SlopefieldTicks, N_("Number of slopefield ticks as a vector [vertical,horizontal]."));
PARAMETER (VectorfieldTicks, N_("Number of vectorfield ticks as a vector [vertical,horizontal]."));
+ PARAMETER (LinePlotVariableNames, N_("Default names used by all 2D plot functions. Should be a 4 vector of strings or identifiers [x,y,z,t]."));
PARAMETER (VectorfieldNormalized, N_("Normalize vectorfields if true. That is, only show direction and not magnitude."));
PARAMETER (LinePlotDrawLegends, N_("If to draw legends or not on line plots."));
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]