2
* Copyright (C) 2008-2011 Robert Ancell
4
* This program is free software: you can redistribute it and/or modify it under
5
* the terms of the GNU General Public License as published by the Free Software
6
* Foundation, either version 2 of the License, or (at your option) any later
7
* version. See http://www.gnu.org/copyleft/gpl.html the full text of the
11
#include <glib/gi18n.h>
12
#include <gdk/gdkkeysyms.h>
14
#include "math-variable-popup.h"
21
struct MathVariablePopupPrivate
23
MathEquation *equation;
26
GtkWidget *variable_name_entry;
27
GtkWidget *add_variable_button;
30
G_DEFINE_TYPE (MathVariablePopup, math_variable_popup, GTK_TYPE_WINDOW);
33
math_variable_popup_new(MathEquation *equation)
35
return g_object_new(math_variable_popup_get_type(), "equation", equation, NULL);
40
variable_focus_out_event_cb(GtkWidget *widget, GdkEventFocus *event, MathVariablePopup *popup)
42
gtk_widget_destroy(widget);
47
insert_variable_cb(GtkWidget *widget, MathVariablePopup *popup)
51
name = g_object_get_data(G_OBJECT(widget), "variable_name");
52
math_equation_insert(popup->priv->equation, name);
54
gtk_widget_destroy(gtk_widget_get_toplevel(widget));
59
variable_name_key_press_cb(GtkWidget *widget, GdkEventKey *event, MathVariablePopup *popup)
61
/* Can't have whitespace in names, so replace with underscores */
62
if (event->keyval == GDK_KEY_space || event->keyval == GDK_KEY_KP_Space)
63
event->keyval = GDK_KEY_underscore;
70
variable_name_changed_cb(GtkWidget *widget, MathVariablePopup *popup)
72
const gchar *text = gtk_entry_get_text(GTK_ENTRY(popup->priv->variable_name_entry));
73
gtk_widget_set_sensitive(popup->priv->add_variable_button, text[0] != '\0');
78
add_variable_cb(GtkWidget *widget, MathVariablePopup *popup)
83
name = gtk_entry_get_text(GTK_ENTRY(popup->priv->variable_name_entry));
87
if (math_equation_get_number(popup->priv->equation, &z))
88
math_variables_set(math_equation_get_variables(popup->priv->equation), name, &z);
89
else if (math_equation_is_result(popup->priv->equation))
90
math_variables_set(math_equation_get_variables(popup->priv->equation), name, math_equation_get_answer(popup->priv->equation));
92
g_warning("Can't add variable %s, the display is not a number", name);
94
gtk_widget_destroy(gtk_widget_get_toplevel(widget));
99
save_variable_cb(GtkWidget *widget, MathVariablePopup *popup)
104
name = g_object_get_data(G_OBJECT(widget), "variable_name");
105
if (math_equation_get_number(popup->priv->equation, &z))
106
math_variables_set(math_equation_get_variables(popup->priv->equation), name, &z);
107
else if (math_equation_is_result(popup->priv->equation))
108
math_variables_set(math_equation_get_variables(popup->priv->equation), name, math_equation_get_answer(popup->priv->equation));
110
g_warning("Can't save variable %s, the display is not a number", name);
112
gtk_widget_destroy(gtk_widget_get_toplevel(widget));
117
delete_variable_cb(GtkWidget *widget, MathVariablePopup *popup)
121
name = g_object_get_data(G_OBJECT(widget), "variable_name");
122
math_variables_delete(math_equation_get_variables(popup->priv->equation), name);
124
gtk_widget_destroy(gtk_widget_get_toplevel(widget));
129
make_variable_entry(MathVariablePopup *popup, const gchar *name, const MPNumber *value, gboolean writable)
131
GtkWidget *hbox, *button, *label;
134
hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6);
138
gchar *value_text = mp_serializer_to_string(math_equation_get_serializer(popup->priv->equation), value);
139
text = g_strdup_printf("<b>%s</b> = %s", name, value_text);
143
text = g_strdup_printf("<b>%s</b>", name);
145
button = gtk_button_new();
146
g_object_set_data(G_OBJECT(button), "variable_name", g_strdup(name)); // FIXME: These will all leak memory
147
g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(insert_variable_cb), popup);
148
gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE);
149
gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
150
gtk_widget_show(button);
152
label = gtk_label_new(text);
154
gtk_label_set_use_markup(GTK_LABEL(label), TRUE);
155
gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
156
gtk_container_add(GTK_CONTAINER(button), label);
157
gtk_widget_show(label);
163
button = gtk_button_new();
164
g_object_set_data(G_OBJECT(button), "variable_name", g_strdup(name));
165
image = gtk_image_new_from_stock(GTK_STOCK_SAVE, GTK_ICON_SIZE_BUTTON);
166
gtk_container_add(GTK_CONTAINER(button), image);
167
gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, TRUE, 0);
168
g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(save_variable_cb), popup);
169
gtk_widget_show(image);
170
gtk_widget_show(button);
172
button = gtk_button_new();
173
g_object_set_data(G_OBJECT(button), "variable_name", g_strdup(name));
174
image = gtk_image_new_from_stock(GTK_STOCK_DELETE, GTK_ICON_SIZE_BUTTON);
175
gtk_container_add(GTK_CONTAINER(button), image);
176
gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, TRUE, 0);
177
g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(delete_variable_cb), popup);
178
gtk_widget_show(image);
179
gtk_widget_show(button);
187
math_variable_popup_set_property(GObject *object,
192
MathVariablePopup *self;
195
GtkWidget *entry, *image;
197
self = MATH_VARIABLE_POPUP(object);
201
self->priv->equation = g_value_get_object(value);
203
names = math_variables_get_names(math_equation_get_variables(self->priv->equation));
204
for (i = 0; names[i]; i++) {
207
value = math_variables_get(math_equation_get_variables(self->priv->equation), names[i]);
208
entry = make_variable_entry(self, names[i], value, TRUE);
209
gtk_widget_show(entry);
210
gtk_box_pack_start(GTK_BOX(self->priv->vbox), entry, FALSE, TRUE, 0);
214
entry = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6);
215
gtk_widget_show(entry);
217
// TODO: Show greyed "variable name" text to give user a hint how to use
218
self->priv->variable_name_entry = gtk_entry_new();
219
g_signal_connect(G_OBJECT(self->priv->variable_name_entry), "key-press-event", G_CALLBACK(variable_name_key_press_cb), self);
220
g_signal_connect(G_OBJECT(self->priv->variable_name_entry), "changed", G_CALLBACK(variable_name_changed_cb), self);
221
g_signal_connect(G_OBJECT(self->priv->variable_name_entry), "activate", G_CALLBACK(add_variable_cb), self);
222
gtk_box_pack_start(GTK_BOX(entry), self->priv->variable_name_entry, TRUE, TRUE, 0);
223
gtk_widget_show(self->priv->variable_name_entry);
225
self->priv->add_variable_button = gtk_button_new();
226
gtk_widget_set_sensitive(self->priv->add_variable_button, FALSE);
227
g_signal_connect(G_OBJECT(self->priv->add_variable_button), "clicked", G_CALLBACK(add_variable_cb), self);
228
image = gtk_image_new_from_stock(GTK_STOCK_ADD, GTK_ICON_SIZE_BUTTON);
229
gtk_container_add(GTK_CONTAINER(self->priv->add_variable_button), image);
230
gtk_box_pack_start(GTK_BOX(entry), self->priv->add_variable_button, FALSE, TRUE, 0);
231
gtk_widget_show(image);
232
gtk_widget_show(self->priv->add_variable_button);
233
gtk_box_pack_end(GTK_BOX(self->priv->vbox), entry, FALSE, TRUE, 0);
235
entry = make_variable_entry(self, "rand", NULL, FALSE);
236
gtk_widget_show(entry);
237
gtk_box_pack_end(GTK_BOX(self->priv->vbox), entry, FALSE, TRUE, 0);
239
entry = make_variable_entry(self, "ans", math_equation_get_answer(self->priv->equation), FALSE);
240
gtk_widget_show(entry);
241
gtk_box_pack_end(GTK_BOX(self->priv->vbox), entry, FALSE, TRUE, 0);
244
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
251
math_variable_popup_get_property(GObject *object,
256
MathVariablePopup *self;
258
self = MATH_VARIABLE_POPUP(object);
262
g_value_set_object(value, self->priv->equation);
265
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
272
math_variable_popup_class_init(MathVariablePopupClass *klass)
274
GObjectClass *object_class = G_OBJECT_CLASS(klass);
276
object_class->get_property = math_variable_popup_get_property;
277
object_class->set_property = math_variable_popup_set_property;
279
g_type_class_add_private(klass, sizeof(MathVariablePopupPrivate));
281
g_object_class_install_property(object_class,
283
g_param_spec_object("equation",
285
"Equation being controlled",
286
math_equation_get_type(),
287
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
292
math_variable_popup_init(MathVariablePopup *popup)
294
popup->priv = G_TYPE_INSTANCE_GET_PRIVATE(popup, math_variable_popup_get_type(), MathVariablePopupPrivate);
296
gtk_window_set_decorated(GTK_WINDOW(popup), FALSE);
297
gtk_window_set_skip_taskbar_hint(GTK_WINDOW(popup), TRUE);
299
gtk_container_set_border_width(GTK_CONTAINER(popup), 6);
301
/* Destroy this window when it loses focus */
302
g_signal_connect(G_OBJECT(popup), "focus-out-event", G_CALLBACK(variable_focus_out_event_cb), popup);
304
popup->priv->vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 6);
305
gtk_box_set_homogeneous(GTK_BOX(popup->priv->vbox), TRUE);
306
gtk_container_add(GTK_CONTAINER(popup), popup->priv->vbox);
307
gtk_widget_show(popup->priv->vbox);