diff options
Diffstat (limited to 'src/math-display.c')
-rw-r--r-- | src/math-display.c | 229 |
1 files changed, 161 insertions, 68 deletions
diff --git a/src/math-display.c b/src/math-display.c index b809695..6718665 100644 --- a/src/math-display.c +++ b/src/math-display.c @@ -1,19 +1,11 @@ -/* Copyright (c) 2008-2009 Robert Ancell +/* + * Copyright (C) 2008-2011 Robert Ancell * - * 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 2, 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, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. + * 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 2 of the License, or (at your option) any later + * version. See http://www.gnu.org/copyleft/gpl.html the full text of the + * license. */ #include <string.h> @@ -37,23 +29,26 @@ struct MathDisplayPrivate /* Buffer that shows errors etc */ GtkTextBuffer *info_buffer; + + /* Spinner widget that shows if we're calculating a response */ + GtkWidget *spinner; }; -G_DEFINE_TYPE (MathDisplay, math_display, GTK_TYPE_VBOX); +G_DEFINE_TYPE (MathDisplay, math_display, GTK_TYPE_VIEWPORT); #define GET_WIDGET(ui, name) GTK_WIDGET(gtk_builder_get_object(ui, name)) MathDisplay * math_display_new() { - return g_object_new (math_display_get_type(), "equation", math_equation_new(), NULL); + return g_object_new(math_display_get_type(), "equation", math_equation_new(), NULL); } MathDisplay * math_display_new_with_equation(MathEquation *equation) { - return g_object_new (math_display_get_type(), "equation", equation, NULL); + return g_object_new(math_display_get_type(), "equation", equation, NULL); } @@ -69,24 +64,77 @@ display_key_press_cb(GtkWidget *widget, GdkEventKey *event, MathDisplay *display { int state; guint32 c; + guint new_keyval = 0; + + /* Treat keypad keys as numbers even when numlock is off */ + switch(event->keyval) + { + case GDK_KEY_KP_Insert: + new_keyval = GDK_KEY_0; + break; + case GDK_KEY_KP_End: + new_keyval = GDK_KEY_1; + break; + case GDK_KEY_KP_Down: + new_keyval = GDK_KEY_2; + break; + case GDK_KEY_KP_Page_Down: + new_keyval = GDK_KEY_3; + break; + case GDK_KEY_KP_Left: + new_keyval = GDK_KEY_4; + break; + case GDK_KEY_KP_Begin: /* This is apparently what "5" does when numlock is off. */ + new_keyval = GDK_KEY_5; + break; + case GDK_KEY_KP_Right: + new_keyval = GDK_KEY_6; + break; + case GDK_KEY_KP_Home: + new_keyval = GDK_KEY_7; + break; + case GDK_KEY_KP_Up: + new_keyval = GDK_KEY_8; + break; + case GDK_KEY_KP_Page_Up: + new_keyval = GDK_KEY_9; + break; + } + + if (new_keyval) { + gboolean result; + GdkEvent *new_event; + + new_event = gdk_event_copy((GdkEvent *)event); + ((GdkEventKey *)new_event)->keyval = new_keyval; + g_signal_emit_by_name(widget, "key-press-event", new_event, &result); + gdk_event_free(new_event); + return result; + } state = event->state & (GDK_CONTROL_MASK | GDK_MOD1_MASK); c = gdk_keyval_to_unicode(event->keyval); /* Solve on enter */ - if (event->keyval == GDK_Return || event->keyval == GDK_KP_Enter) { + if (event->keyval == GDK_KEY_Return || event->keyval == GDK_KEY_KP_Enter) { math_equation_solve(display->priv->equation); return TRUE; } /* Clear on escape */ - if ((event->keyval == GDK_Escape && state == 0) || - (event->keyval == GDK_BackSpace && state == GDK_CONTROL_MASK) || - (event->keyval == GDK_Delete && state == GDK_SHIFT_MASK)) { + if ((event->keyval == GDK_KEY_Escape && state == 0) || + (event->keyval == GDK_KEY_BackSpace && state == GDK_CONTROL_MASK) || + (event->keyval == GDK_KEY_Delete && state == GDK_SHIFT_MASK)) { math_equation_clear(display->priv->equation); return TRUE; } + /* Numeric keypad will often insert '.' regardless of locale */ + if (event->keyval == GDK_KEY_KP_Decimal) { + math_equation_insert_numeric_point(display->priv->equation); + return TRUE; + } + /* Substitute */ if (state == 0) { if (c == '*') { @@ -107,34 +155,34 @@ display_key_press_cb(GtkWidget *widget, GdkEventKey *event, MathDisplay *display if (state == GDK_CONTROL_MASK) { switch(event->keyval) { - case GDK_bracketleft: + case GDK_KEY_bracketleft: math_equation_insert(display->priv->equation, "⌈"); return TRUE; - case GDK_bracketright: + case GDK_KEY_bracketright: math_equation_insert(display->priv->equation, "⌉"); return TRUE; - case GDK_e: + case GDK_KEY_e: math_equation_insert_exponent(display->priv->equation); return TRUE; - case GDK_f: + case GDK_KEY_f: math_equation_factorize(display->priv->equation); return TRUE; - case GDK_i: + case GDK_KEY_i: math_equation_insert(display->priv->equation, "⁻¹"); return TRUE; - case GDK_p: + case GDK_KEY_p: math_equation_insert(display->priv->equation, "π"); return TRUE; - case GDK_r: + case GDK_KEY_r: math_equation_insert(display->priv->equation, "√"); return TRUE; - case GDK_u: + case GDK_KEY_u: math_equation_insert(display->priv->equation, "µ"); return TRUE; - case GDK_minus: + case GDK_KEY_minus: math_equation_insert(display->priv->equation, "⁻"); return TRUE; - case GDK_apostrophe: + case GDK_KEY_apostrophe: math_equation_insert(display->priv->equation, "°"); return TRUE; } @@ -142,10 +190,10 @@ display_key_press_cb(GtkWidget *widget, GdkEventKey *event, MathDisplay *display if (state == GDK_MOD1_MASK) { switch(event->keyval) { - case GDK_bracketleft: + case GDK_KEY_bracketleft: math_equation_insert(display->priv->equation, "⌊"); return TRUE; - case GDK_bracketright: + case GDK_KEY_bracketright: math_equation_insert(display->priv->equation, "⌋"); return TRUE; } @@ -154,34 +202,44 @@ display_key_press_cb(GtkWidget *widget, GdkEventKey *event, MathDisplay *display if (state == GDK_CONTROL_MASK || math_equation_get_number_mode(display->priv->equation) == SUPERSCRIPT) { switch(event->keyval) { - case GDK_0: + case GDK_KEY_0: + case GDK_KEY_KP_0: math_equation_insert(display->priv->equation, "⁰"); return TRUE; - case GDK_1: + case GDK_KEY_1: + case GDK_KEY_KP_1: math_equation_insert(display->priv->equation, "¹"); return TRUE; - case GDK_2: + case GDK_KEY_2: + case GDK_KEY_KP_2: math_equation_insert(display->priv->equation, "²"); return TRUE; - case GDK_3: + case GDK_KEY_3: + case GDK_KEY_KP_3: math_equation_insert(display->priv->equation, "³"); return TRUE; - case GDK_4: + case GDK_KEY_4: + case GDK_KEY_KP_4: math_equation_insert(display->priv->equation, "⁴"); return TRUE; - case GDK_5: + case GDK_KEY_5: + case GDK_KEY_KP_5: math_equation_insert(display->priv->equation, "⁵"); return TRUE; - case GDK_6: + case GDK_KEY_6: + case GDK_KEY_KP_6: math_equation_insert(display->priv->equation, "⁶"); return TRUE; - case GDK_7: + case GDK_KEY_7: + case GDK_KEY_KP_7: math_equation_insert(display->priv->equation, "⁷"); return TRUE; - case GDK_8: + case GDK_KEY_8: + case GDK_KEY_KP_8: math_equation_insert(display->priv->equation, "⁸"); return TRUE; - case GDK_9: + case GDK_KEY_9: + case GDK_KEY_KP_9: math_equation_insert(display->priv->equation, "⁹"); return TRUE; } @@ -189,34 +247,44 @@ display_key_press_cb(GtkWidget *widget, GdkEventKey *event, MathDisplay *display else if (state == GDK_MOD1_MASK || math_equation_get_number_mode(display->priv->equation) == SUBSCRIPT) { switch(event->keyval) { - case GDK_0: + case GDK_KEY_0: + case GDK_KEY_KP_0: math_equation_insert(display->priv->equation, "₀"); return TRUE; - case GDK_1: + case GDK_KEY_1: + case GDK_KEY_KP_1: math_equation_insert(display->priv->equation, "₁"); return TRUE; - case GDK_2: + case GDK_KEY_2: + case GDK_KEY_KP_2: math_equation_insert(display->priv->equation, "₂"); return TRUE; - case GDK_3: + case GDK_KEY_3: + case GDK_KEY_KP_3: math_equation_insert(display->priv->equation, "₃"); return TRUE; - case GDK_4: + case GDK_KEY_4: + case GDK_KEY_KP_4: math_equation_insert(display->priv->equation, "₄"); return TRUE; - case GDK_5: + case GDK_KEY_5: + case GDK_KEY_KP_5: math_equation_insert(display->priv->equation, "₅"); return TRUE; - case GDK_6: + case GDK_KEY_6: + case GDK_KEY_KP_6: math_equation_insert(display->priv->equation, "₆"); return TRUE; - case GDK_7: + case GDK_KEY_7: + case GDK_KEY_KP_7: math_equation_insert(display->priv->equation, "₇"); return TRUE; - case GDK_8: + case GDK_KEY_8: + case GDK_KEY_KP_8: math_equation_insert(display->priv->equation, "₈"); return TRUE; - case GDK_9: + case GDK_KEY_9: + case GDK_KEY_KP_9: math_equation_insert(display->priv->equation, "₉"); return TRUE; } @@ -239,14 +307,27 @@ static void status_changed_cb(MathEquation *equation, GParamSpec *spec, MathDisplay *display) { gtk_text_buffer_set_text(display->priv->info_buffer, math_equation_get_status(equation), -1); + if (math_equation_in_solve(equation) && !gtk_widget_get_visible(display->priv->spinner)) { + gtk_widget_show(display->priv->spinner); + gtk_spinner_start(GTK_SPINNER(display->priv->spinner)); + } + else if (!math_equation_in_solve(equation) && gtk_widget_get_visible(display->priv->spinner)) { + gtk_widget_hide(display->priv->spinner); + gtk_spinner_stop(GTK_SPINNER(display->priv->spinner)); + } } static void create_gui(MathDisplay *display) { - GtkWidget *info_view; + GtkWidget *info_view, *info_box, *main_box; PangoFontDescription *font_desc; + int i; + GtkStyle *style; + + main_box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); + gtk_container_add(GTK_CONTAINER(display), main_box); g_signal_connect(display, "key-press-event", G_CALLBACK(key_press_cb), display); @@ -267,7 +348,10 @@ create_gui(MathDisplay *display) atk_object_set_role(gtk_widget_get_accessible(display->priv->text_view), ATK_ROLE_EDITBAR); //FIXME:<property name="AtkObject::accessible-description" translatable="yes" comments="Accessible description for the area in which results are displayed">Result Region</property> g_signal_connect(display->priv->text_view, "key-press-event", G_CALLBACK(display_key_press_cb), display); - gtk_box_pack_start(GTK_BOX(display), display->priv->text_view, TRUE, TRUE, 0); + gtk_box_pack_start(GTK_BOX(main_box), display->priv->text_view, TRUE, TRUE, 0); + + info_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6); + gtk_box_pack_start(GTK_BOX(main_box), info_box, FALSE, TRUE, 0); info_view = gtk_text_view_new(); gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(info_view), GTK_WRAP_WORD); @@ -277,11 +361,20 @@ create_gui(MathDisplay *display) gtk_text_view_set_justification(GTK_TEXT_VIEW(info_view), GTK_JUSTIFY_RIGHT); /* TEMP: Disabled for now as GTK+ doesn't properly render a right aligned right margin, see bug #482688 */ /*gtk_text_view_set_right_margin(GTK_TEXT_VIEW(info_view), 6);*/ - gtk_box_pack_start(GTK_BOX(display), info_view, FALSE, TRUE, 0); + gtk_box_pack_start(GTK_BOX(info_box), info_view, TRUE, TRUE, 0); display->priv->info_buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(info_view)); + display->priv->spinner = gtk_spinner_new(); + gtk_box_pack_end(GTK_BOX(info_box), display->priv->spinner, FALSE, FALSE, 0); + style = gtk_widget_get_style(info_view); + for (i = 0; i < 5; i++) { + gtk_widget_modify_bg(GTK_WIDGET(display), i, &style->base[i]); + } + + gtk_widget_show(info_box); gtk_widget_show(info_view); gtk_widget_show(display->priv->text_view); + gtk_widget_show(main_box); g_signal_connect(display->priv->equation, "notify::status", G_CALLBACK(status_changed_cb), display); status_changed_cb(display->priv->equation, NULL, display); @@ -296,15 +389,15 @@ math_display_set_property(GObject *object, { MathDisplay *self; - self = MATH_DISPLAY (object); + self = MATH_DISPLAY(object); switch (prop_id) { case PROP_EQUATION: - self->priv->equation = g_value_get_object (value); + self->priv->equation = g_value_get_object(value); create_gui(self); break; default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; } } @@ -318,28 +411,28 @@ math_display_get_property(GObject *object, { MathDisplay *self; - self = MATH_DISPLAY (object); + self = MATH_DISPLAY(object); switch (prop_id) { case PROP_EQUATION: - g_value_set_object (value, self->priv->equation); + g_value_set_object(value, self->priv->equation); break; default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; } } static void -math_display_class_init (MathDisplayClass *klass) +math_display_class_init(MathDisplayClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS(klass); object_class->get_property = math_display_get_property; object_class->set_property = math_display_set_property; - g_type_class_add_private (klass, sizeof (MathDisplayPrivate)); + g_type_class_add_private(klass, sizeof(MathDisplayPrivate)); g_object_class_install_property(object_class, PROP_EQUATION, @@ -351,8 +444,8 @@ math_display_class_init (MathDisplayClass *klass) } -static void +static void math_display_init(MathDisplay *display) { - display->priv = G_TYPE_INSTANCE_GET_PRIVATE (display, math_display_get_type(), MathDisplayPrivate); + display->priv = G_TYPE_INSTANCE_GET_PRIVATE(display, math_display_get_type(), MathDisplayPrivate); } |