/* formulas.c
* geg, a GTK+ Equation Grapher
* David Bryant 1998
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif /* HAVE_CONFIG_H */
#include "formulas.h"
#include "log.h"
#include "prefs.h"
#include "colors.h"
/* global data */
extern struct_prefs prefs;
extern misc_colors m_colors;
/* locally global data */
static gchar **formulas = NULL;
static int nformulas = 0;
static GtkWidget *wi = NULL;
static GtkStyle *style;
static void close_event(GtkWidget *widget, gpointer data);
static void remove_event(GtkWidget *widget, gpointer data);
static void really_remove_event(gpointer data, gpointer user_data);
void
remove_all_event(GtkWidget *widget, gpointer data)
{
int i;
for(i = 0; i < nformulas; i++)
g_free(formulas[i]);
if(formulas)
g_free(formulas);
formulas = NULL;
nformulas = 0;
}
/* formula_foreach, calls the supplied function for each formula in the
* array of formulas, called by go_event in app.c
*/
void
formula_foreach(FormulaFunc func)
{
int i;
for(i = 0; i < nformulas; i++)
func(formulas[i], i);
}
/* formula_forall,
*/
void formula_forall(FormulaAllFunc func,
gdouble x1, gdouble x2,
gdouble y1, gdouble y2)
{
func(formulas, nformulas, x1, x2, y1, y2);
}
/* formula_add,
*/
gint
formula_add(FormulaFunc func, gchar *formula)
{
if(*formula == '\0') /* check for a real formula */
return(FALSE);
if(nformulas >= prefs.maxform) {
write_log(NULL, "Maximum Formulas");
return(FALSE);
}
write_log(NULL, formula);
if(!func(formula, nformulas)) {
write_log(NULL, "Parse Error!");
return(FALSE);
}
/* add the formula to the list */
formulas = (gchar **)g_realloc(formulas, ++nformulas * sizeof(gchar **));
formulas[nformulas - 1] = g_strdup(formula);
return(TRUE);
}
/* delete_event, deletes the window, not sure if it would be GTK+ approved
*/
static gint
delete_event(GtkWidget *widget, GdkEvent *event, gpointer data)
{
gtk_widget_destroy(wi);
wi = NULL;
gtk_style_unref(style);
return(TRUE);
}
/* close_event, closes the 'erase' dialog, it is called by the 'Cancel'
* and the 'Ok' button
*/
static void
close_event(GtkWidget *widget, gpointer data)
{
gtk_widget_destroy(wi);
wi = NULL;
gtk_style_unref(style);
}
/* erase_event, brings up the 'erase' dialog, it is called by the 'erase'
* toolbar button in the main dialog
*/
void
erase_event(GtkWidget *widget, gpointer data)
{
int i;
GtkWidget *temp_bu, *fr, *li;
GtkSignalFunc refresh_graph;
if(wi && wi->window) {
gtk_widget_map(wi);
gdk_window_raise(wi->window);
return;
}
refresh_graph = (GtkSignalFunc)data;
wi = gtk_dialog_new();
gtk_signal_connect(GTK_OBJECT(wi), "delete_event",
GTK_SIGNAL_FUNC(delete_event), NULL);
gtk_window_set_wmclass(GTK_WINDOW(wi), "erase", "geg");
gtk_window_set_title(GTK_WINDOW(wi), "Erase");
gtk_window_set_policy(GTK_WINDOW(wi), FALSE, TRUE, FALSE);
gtk_window_position(GTK_WINDOW(wi), GTK_WIN_POS_MOUSE);
gtk_container_border_width(GTK_CONTAINER(GTK_DIALOG(wi)->vbox), 5);
/* the list to delete functions from */
fr = gtk_frame_new("Select functions to erase:");
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(wi)->vbox), fr, TRUE, TRUE, 0);
li = gtk_clist_new(1); /* only want 1 column */
/* gtk_clist_set_reorderable(GTK_CLIST(li), TRUE); */
/* style stuff */
style = gtk_style_copy(gtk_widget_get_style(widget));
style->bg[GTK_STATE_PRELIGHT] = *m_colors.back;
gtk_widget_set_style(li, style);
gtk_clist_set_selection_mode(GTK_CLIST(li), GTK_SELECTION_MULTIPLE);
/* add the formulas to the list */
for(i = 0; i < nformulas; i++) {
gtk_clist_append(GTK_CLIST(li), &formulas[i]);
gtk_clist_set_foreground(GTK_CLIST(li), i, function_color(i));
gtk_clist_set_background(GTK_CLIST(li), i, m_colors.back);
}
/* make the list a bit bigger than the default size */
gtk_widget_set_usize(li, 200, 200);
gtk_container_add(GTK_CONTAINER(fr), li);
gtk_widget_show(li);
gtk_widget_show(fr);
/* Ok button */
temp_bu = gtk_button_new_with_label("Ok");
gtk_signal_connect(GTK_OBJECT(temp_bu), "clicked",
GTK_SIGNAL_FUNC(remove_event), li);
gtk_signal_connect(GTK_OBJECT(temp_bu), "clicked",
GTK_SIGNAL_FUNC(refresh_graph), NULL);
gtk_signal_connect(GTK_OBJECT(temp_bu), "clicked",
GTK_SIGNAL_FUNC(close_event), NULL);
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(wi)->action_area), temp_bu,
TRUE, TRUE, 0);
gtk_widget_show(temp_bu);
/* Cancel button */
temp_bu = gtk_button_new_with_label("Cancel");
gtk_signal_connect(GTK_OBJECT(temp_bu), "clicked",
GTK_SIGNAL_FUNC(close_event), NULL);
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(wi)->action_area), temp_bu,
TRUE, TRUE, 0);
gtk_widget_show(temp_bu);
gtk_grab_add(wi);
gtk_widget_show(wi);
/* how do I do this ? */
/* gdk_window_set_decorations(wi->window, GDK_DECOR_BORDER); */
}
/* really_remove_event, called for each item in the glist in remove_event */
static void
really_remove_event(gpointer data, gpointer user_data)
{
gint i = 0;
gchar *text;
gtk_clist_get_text((GtkCList *)user_data, (gint)data, 0, &text);
while(strcmp(text, formulas[i++]));
g_free(formulas[--i]);
nformulas--;
/* the next part shuffles the order if we didn't delete the last one */
/* this disturbs the order, ideally this should not happen... maybe later */
if(i != nformulas)
formulas[i] = formulas[nformulas];
formulas = (gchar **)g_realloc(formulas, nformulas * sizeof(gchar **));
}
/* remove_event, called from the 'ok' button in the 'erase' dialog. it
* passes a pointer to the CList, which has selected entries which we
* wish to delete
*/
static void
remove_event(GtkWidget *widget, gpointer data)
{
GtkCList *clist;
GList *glist; /* glib doubly linked list */
clist = GTK_CLIST((GtkWidget *)data);
glist = clist->selection;
if(glist)
write_log(NULL, "Erase Formulas");
g_list_foreach(glist, (GFunc)really_remove_event, clist);
}
syntax highlighted by Code2HTML, v. 0.9.1