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>
13 #include "math-buttons.h"
14 #include "math-converter.h"
15 #include "math-variable-popup.h"
16 #include "financial.h"
17 #include "mp-serializer.h"
26 static GType button_mode_type
;
28 #define MAXBITS 64 /* Bit panel: number of bit fields. */
30 struct MathButtonsPrivate
32 MathEquation
*equation
;
35 gint programming_base
;
37 MathConverter
*converter
;
39 GtkBuilder
*basic_ui
, *advanced_ui
, *financial_ui
, *programming_ui
;
41 GdkColor color_numbers
, color_action
, color_operator
, color_function
, color_memory
, color_group
;
43 GtkWidget
*bas_panel
, *adv_panel
, *fin_panel
, *prog_panel
;
44 GtkWidget
*active_panel
;
46 GtkWidget
*shift_left_menu
, *shift_right_menu
;
48 GtkWidget
*function_menu
;
50 GList
*superscript_toggles
;
51 GList
*subscript_toggles
;
53 GtkWidget
*base_combo
;
54 GtkWidget
*base_label
;
56 GtkWidget
*bit_labels
[MAXBITS
];
58 GtkWidget
*character_code_dialog
;
59 GtkWidget
*character_code_entry
;
62 G_DEFINE_TYPE (MathButtons
, math_buttons
, GTK_TYPE_VBOX
);
64 #define UI_BASIC_FILE UI_DIR "/buttons-basic.ui"
65 #define UI_ADVANCED_FILE UI_DIR "/buttons-advanced.ui"
66 #define UI_FINANCIAL_FILE UI_DIR "/buttons-financial.ui"
67 #define UI_PROGRAMMING_FILE UI_DIR "/buttons-programming.ui"
69 #define GET_WIDGET(ui, name) \
70 GTK_WIDGET(gtk_builder_get_object((ui), (name)))
72 #define WM_WIDTH_FACTOR 10
73 #define WM_HEIGHT_FACTOR 30
87 const char *widget_name
;
93 static ButtonData button_data
[] = {
95 /* Tooltip for the Pi button */
97 {"eulers_number", "e", NUMBER
,
98 /* Tooltip for the Euler's Number button */
99 N_("Euler’s Number")},
100 {"imaginary", "i", NUMBER
, NULL
},
101 {"numeric_point", NULL
, NUMBER
, NULL
},
102 {"subscript", NULL
, NUMBER_BOLD
,
103 /* Tooltip for the subscript button */
104 N_("Subscript mode [Alt]")},
105 {"superscript", NULL
, NUMBER_BOLD
,
106 /* Tooltip for the superscript button */
107 N_("Superscript mode [Ctrl]")},
108 {"exponential", NULL
, NUMBER_BOLD
,
109 /* Tooltip for the scientific exponent button */
110 N_("Scientific exponent [Ctrl+E]")},
111 {"add", "+", OPERATOR
,
112 /* Tooltip for the add button */
114 {"subtract", "−", OPERATOR
,
115 /* Tooltip for the subtract button */
117 {"multiply", "×", OPERATOR
,
118 /* Tooltip for the multiply button */
120 {"divide", "÷", OPERATOR
,
121 /* Tooltip for the divide button */
123 {"modulus_divide", " mod ", OPERATOR
,
124 /* Tooltip for the modulus divide button */
125 N_("Modulus divide")},
126 {"function", NULL
, FUNCTION
,
127 /* Tooltip for the additional functions button */
128 N_("Additional Functions")},
129 {"x_pow_y", "^", FUNCTION
,
130 /* Tooltip for the exponent button */
131 N_("Exponent [^ or **]")},
132 {"x_squared", "²", FUNCTION
,
133 /* Tooltip for the square button */
134 N_("Square [Ctrl+2]")},
135 {"percentage", "%", NUMBER
,
136 /* Tooltip for the percentage button */
137 N_("Percentage [%]")},
138 {"factorial", "!", FUNCTION
,
139 /* Tooltip for the factorial button */
140 N_("Factorial [!]")},
141 {"abs", "|", FUNCTION
,
142 /* Tooltip for the absolute value button */
143 N_("Absolute value [|]")},
144 {"arg", "Arg ", FUNCTION
,
145 /* Tooltip for the complex argument component button */
146 N_("Complex argument")},
147 {"conjugate", "conj ", FUNCTION
,
148 /* Tooltip for the complex conjugate button */
149 N_("Complex conjugate")},
150 {"root", "√", FUNCTION
,
151 /* Tooltip for the root button */
152 N_("Root [Ctrl+R]")},
153 {"square_root", "√", FUNCTION
,
154 /* Tooltip for the square root button */
155 N_("Square root [Ctrl+R]")},
156 {"logarithm", "log ", FUNCTION
,
157 /* Tooltip for the logarithm button */
159 {"natural_logarithm", "ln ", FUNCTION
,
160 /* Tooltip for the natural logarithm button */
161 N_("Natural Logarithm")},
162 {"sine", "sin ", FUNCTION
,
163 /* Tooltip for the sine button */
165 {"cosine", "cos ", FUNCTION
,
166 /* Tooltip for the cosine button */
168 {"tangent", "tan ", FUNCTION
,
169 /* Tooltip for the tangent button */
171 {"hyperbolic_sine", "sinh ", FUNCTION
,
172 /* Tooltip for the hyperbolic sine button */
173 N_("Hyperbolic Sine")},
174 {"hyperbolic_cosine", "cosh ", FUNCTION
,
175 /* Tooltip for the hyperbolic cosine button */
176 N_("Hyperbolic Cosine")},
177 {"hyperbolic_tangent", "tanh ", FUNCTION
,
178 /* Tooltip for the hyperbolic tangent button */
179 N_("Hyperbolic Tangent")},
180 {"inverse", "⁻¹", FUNCTION
,
181 /* Tooltip for the inverse button */
182 N_("Inverse [Ctrl+I]")},
183 {"and", "∧", OPERATOR
,
184 /* Tooltip for the boolean AND button */
186 {"or", "∨", OPERATOR
,
187 /* Tooltip for the boolean OR button */
189 {"xor", "⊻", OPERATOR
,
190 /* Tooltip for the exclusive OR button */
191 N_("Boolean Exclusive OR")},
192 {"not", "¬", FUNCTION
,
193 /* Tooltip for the boolean NOT button */
195 {"integer_portion", "int ", FUNCTION
,
196 /* Tooltip for the integer component button */
197 N_("Integer Component")},
198 {"fractional_portion", "frac ", FUNCTION
,
199 /* Tooltip for the fractional component button */
200 N_("Fractional Component")},
201 {"real_portion", "Re ", FUNCTION
,
202 /* Tooltip for the real component button */
203 N_("Real Component")},
204 {"imaginary_portion", "Im ", FUNCTION
,
205 /* Tooltip for the imaginary component button */
206 N_("Imaginary Component")},
207 {"ones_complement", "ones ", FUNCTION
,
208 /* Tooltip for the ones' complement button */
209 N_("Ones' Complement")},
210 {"twos_complement", "twos ", FUNCTION
,
211 /* Tooltip for the two's complement button */
212 N_("Two's Complement")},
213 {"trunc", "trunc ", FUNCTION
,
214 /* Tooltip for the truncate button */
216 {"start_group", "(", GROUP
,
217 /* Tooltip for the start group button */
218 N_("Start Group [(]")},
219 {"end_group", ")", GROUP
,
220 /* Tooltip for the end group button */
221 N_("End Group [)]")},
222 {"memory", NULL
, MEMORY
,
223 /* Tooltip for the memory button */
225 {"character", NULL
, MEMORY
,
226 /* Tooltip for the insert character code button */
227 N_("Insert Character Code")},
228 {"result", NULL
, ACTION
,
229 /* Tooltip for the solve button */
230 N_("Calculate Result")},
231 {"factor", NULL
, ACTION
,
232 /* Tooltip for the factor button */
233 N_("Factorize [Ctrl+F]")},
234 {"clear", NULL
, GROUP
,
235 /* Tooltip for the clear button */
236 N_("Clear Display [Escape]")},
237 {"undo", NULL
, GROUP
,
238 /* Tooltip for the undo button */
239 N_("Undo [Ctrl+Z]")},
240 {"shift_left", NULL
, ACTION
,
241 /* Tooltip for the shift left button */
243 {"shift_right", NULL
, ACTION
,
244 /* Tooltip for the shift right button */
246 {"finc_compounding_term", NULL
, FUNCTION
,
247 /* Tooltip for the compounding term button */
248 N_("Compounding Term")},
249 {"finc_double_declining_depreciation", NULL
, FUNCTION
,
250 /* Tooltip for the double declining depreciation button */
251 N_("Double Declining Depreciation")},
252 {"finc_future_value", NULL
, FUNCTION
,
253 /* Tooltip for the future value button */
255 {"finc_term", NULL
, FUNCTION
,
256 /* Tooltip for the financial term button */
257 N_("Financial Term")},
258 {"finc_sum_of_the_years_digits_depreciation", NULL
, FUNCTION
,
259 /* Tooltip for the sum of the years digits depreciation button */
260 N_("Sum of the Years Digits Depreciation")},
261 {"finc_straight_line_depreciation", NULL
, FUNCTION
,
262 /* Tooltip for the straight line depreciation button */
263 N_("Straight Line Depreciation")},
264 {"finc_periodic_interest_rate", NULL
, FUNCTION
,
265 /* Tooltip for the periodic interest rate button */
266 N_("Periodic Interest Rate")},
267 {"finc_present_value", NULL
, FUNCTION
,
268 /* Tooltip for the present value button */
269 N_("Present Value")},
270 {"finc_periodic_payment", NULL
, FUNCTION
,
271 /* Tooltip for the periodic payment button */
272 N_("Periodic Payment")},
273 {"finc_gross_profit_margin", NULL
, FUNCTION
,
274 /* Tooltip for the gross profit margin button */
275 N_("Gross Profit Margin")},
276 {NULL
, NULL
, 0, NULL
}
279 /* The names of each field in the dialogs for the financial functions */
280 static char *finc_dialog_fields
[][5] = {
281 {"ctrm_pint", "ctrm_fv", "ctrm_pv", NULL
, NULL
},
282 {"ddb_cost", "ddb_life", "ddb_period", NULL
, NULL
},
283 {"fv_pmt", "fv_pint", "fv_n", NULL
, NULL
},
284 {"gpm_cost", "gpm_margin", NULL
, NULL
, NULL
},
285 {"pmt_prin", "pmt_pint", "pmt_n", NULL
, NULL
},
286 {"pv_pmt", "pv_pint", "pv_n", NULL
, NULL
},
287 {"rate_fv", "rate_pv", "rate_n", NULL
, NULL
},
288 {"sln_cost", "sln_salvage", "sln_life", NULL
, NULL
},
289 {"syd_cost", "syd_salvage", "syd_life", "syd_period", NULL
},
290 {"term_pmt", "term_fv", "term_pint", NULL
, NULL
},
291 {NULL
, NULL
, NULL
, NULL
, NULL
}
296 math_buttons_new(MathEquation
*equation
)
298 return g_object_new(math_buttons_get_type(), "equation", equation
, NULL
);
303 set_tint(GtkWidget
*widget
, GdkColor
*tint
, gint alpha
)
311 gtk_widget_ensure_style(widget
);
312 style
= gtk_widget_get_style(widget
);
314 for (j
= 0; j
< 5; j
++) {
317 color
.red
= (style
->bg
[j
].red
* (10 - alpha
) + tint
->red
* alpha
) / 10;
318 color
.green
= (style
->bg
[j
].green
* (10 - alpha
) + tint
->green
* alpha
) / 10;
319 color
.blue
= (style
->bg
[j
].blue
* (10 - alpha
) + tint
->blue
* alpha
) / 10;
321 gtk_widget_modify_bg(widget
, j
, &color
);
327 set_data(GtkBuilder
*ui
, const gchar
*object_name
, const gchar
*name
, const char *value
)
330 object
= gtk_builder_get_object(ui
, object_name
);
332 g_object_set_data(object
, name
, GINT_TO_POINTER(value
));
337 set_int_data(GtkBuilder
*ui
, const gchar
*object_name
, const gchar
*name
, gint value
)
340 object
= gtk_builder_get_object(ui
, object_name
);
342 g_object_set_data(object
, name
, GINT_TO_POINTER(value
));
347 load_finc_dialogs(MathButtons
*buttons
)
351 set_int_data(buttons
->priv
->financial_ui
, "ctrm_dialog", "finc_dialog", FINC_CTRM_DIALOG
);
352 set_int_data(buttons
->priv
->financial_ui
, "ddb_dialog", "finc_dialog", FINC_DDB_DIALOG
);
353 set_int_data(buttons
->priv
->financial_ui
, "fv_dialog", "finc_dialog", FINC_FV_DIALOG
);
354 set_int_data(buttons
->priv
->financial_ui
, "gpm_dialog", "finc_dialog", FINC_GPM_DIALOG
);
355 set_int_data(buttons
->priv
->financial_ui
, "pmt_dialog", "finc_dialog", FINC_PMT_DIALOG
);
356 set_int_data(buttons
->priv
->financial_ui
, "pv_dialog", "finc_dialog", FINC_PV_DIALOG
);
357 set_int_data(buttons
->priv
->financial_ui
, "rate_dialog", "finc_dialog", FINC_RATE_DIALOG
);
358 set_int_data(buttons
->priv
->financial_ui
, "sln_dialog", "finc_dialog", FINC_SLN_DIALOG
);
359 set_int_data(buttons
->priv
->financial_ui
, "syd_dialog", "finc_dialog", FINC_SYD_DIALOG
);
360 set_int_data(buttons
->priv
->financial_ui
, "term_dialog", "finc_dialog", FINC_TERM_DIALOG
);
362 for (i
= 0; finc_dialog_fields
[i
][0] != NULL
; i
++) {
363 for (j
= 0; finc_dialog_fields
[i
][j
]; j
++) {
365 o
= gtk_builder_get_object (buttons
->priv
->financial_ui
, finc_dialog_fields
[i
][j
]);
366 g_object_set_data(o
, "finc_field", GINT_TO_POINTER(j
));
367 g_object_set_data(o
, "finc_dialog", GINT_TO_POINTER(i
));
374 update_bit_panel(MathButtons
*buttons
)
383 if (!buttons
->priv
->bit_panel
)
386 enabled
= math_equation_get_number(buttons
->priv
->equation
, &x
);
389 MPNumber max
, fraction
;
391 mp_set_from_unsigned_integer(G_MAXUINT64
, &max
);
392 mp_fractional_part(&x
, &fraction
);
393 if (mp_is_negative(&x
) || mp_is_greater_than(&x
, &max
) || !mp_is_zero(&fraction
))
396 bits
= mp_cast_to_unsigned_int(&x
);
399 gtk_widget_set_sensitive(buttons
->priv
->bit_panel
, enabled
);
400 gtk_widget_set_sensitive(buttons
->priv
->base_label
, enabled
);
405 for (i
= 0; i
< MAXBITS
; i
++) {
408 if (bits
& (1LL << (MAXBITS
-i
-1)))
412 gtk_label_set_text(GTK_LABEL(buttons
->priv
->bit_labels
[i
]), label
);
415 base
= math_equation_get_base(buttons
->priv
->equation
);
416 label
= g_string_new("");
419 g_string_append(label
, " = ");
420 g_string_append_printf(label
, "%" G_GINT64_MODIFIER
"o", bits
);
421 g_string_append(label
, "₈");
425 g_string_append(label
, " = ");
426 g_string_append_printf(label
, "%" G_GINT64_MODIFIER
"u", bits
);
427 g_string_append(label
, "₁₀");
431 g_string_append(label
, " = ");
432 g_string_append_printf(label
, "%" G_GINT64_MODIFIER
"X", bits
);
433 g_string_append(label
, "₁₆");
436 gtk_label_set_text(GTK_LABEL(buttons
->priv
->base_label
), label
->str
);
437 g_string_free(label
, TRUE
);
442 display_changed_cb(MathEquation
*equation
, GParamSpec
*spec
, MathButtons
*buttons
)
444 update_bit_panel(buttons
);
449 base_combobox_changed_cb(GtkWidget
*combo
, MathButtons
*buttons
)
455 model
= gtk_combo_box_get_model(GTK_COMBO_BOX(combo
));
456 gtk_combo_box_get_active_iter(GTK_COMBO_BOX(combo
), &iter
);
457 gtk_tree_model_get(model
, &iter
, 1, &value
, -1);
459 math_buttons_set_programming_base(buttons
, value
);
464 base_changed_cb(MathEquation
*equation
, GParamSpec
*spec
, MathButtons
*buttons
)
470 if (buttons
->priv
->mode
!= PROGRAMMING
)
473 model
= gtk_combo_box_get_model(GTK_COMBO_BOX(buttons
->priv
->base_combo
));
474 valid
= gtk_tree_model_get_iter_first(model
, &iter
);
475 buttons
->priv
->programming_base
= math_equation_get_base(buttons
->priv
->equation
);
480 gtk_tree_model_get(model
, &iter
, 1, &v
, -1);
481 if (v
== buttons
->priv
->programming_base
)
483 valid
= gtk_tree_model_iter_next(model
, &iter
);
486 valid
= gtk_tree_model_get_iter_first(model
, &iter
);
488 gtk_combo_box_set_active_iter(GTK_COMBO_BOX(buttons
->priv
->base_combo
), &iter
);
493 load_mode(MathButtons
*buttons
, ButtonMode mode
)
495 GtkBuilder
*builder
, **builder_ptr
;
498 const gchar
*builder_file
;
499 static gchar
*objects
[] = { "button_panel", "character_code_dialog", "currency_dialog",
500 "ctrm_dialog", "ddb_dialog", "fv_dialog", "gpm_dialog",
501 "pmt_dialog", "pv_dialog", "rate_dialog", "sln_dialog",
502 "syd_dialog", "term_dialog", "adjustment1", "adjustment2", NULL
};
503 GtkWidget
*widget
, **panel
;
504 GError
*error
= NULL
;
509 builder_ptr
= &buttons
->priv
->basic_ui
;
510 builder_file
= UI_BASIC_FILE
;
511 panel
= &buttons
->priv
->bas_panel
;
514 builder_ptr
= &buttons
->priv
->advanced_ui
;
515 builder_file
= UI_ADVANCED_FILE
;
516 panel
= &buttons
->priv
->adv_panel
;
519 builder_ptr
= &buttons
->priv
->financial_ui
;
520 builder_file
= UI_FINANCIAL_FILE
;
521 panel
= &buttons
->priv
->fin_panel
;
524 builder_ptr
= &buttons
->priv
->programming_ui
;
525 builder_file
= UI_PROGRAMMING_FILE
;
526 panel
= &buttons
->priv
->prog_panel
;
533 builder
= *builder_ptr
= gtk_builder_new();
534 // FIXME: Show dialog if failed to load
535 gtk_builder_add_objects_from_file(builder
, builder_file
, objects
, &error
);
537 g_warning("Error loading button UI: %s", error
->message
);
538 g_clear_error(&error
);
540 *panel
= GET_WIDGET(builder
, "button_panel");
541 gtk_box_pack_end(GTK_BOX(buttons
), *panel
, TRUE
, TRUE
, 0);
543 /* Configure buttons */
544 for (i
= 0; button_data
[i
].widget_name
!= NULL
; i
++) {
548 name
= g_strdup_printf("calc_%s_button", button_data
[i
].widget_name
);
549 object
= gtk_builder_get_object(*builder_ptr
, name
);
554 button
= GTK_WIDGET(object
);
555 if (button_data
[i
].data
)
556 g_object_set_data(object
, "calc_text", (gpointer
) button_data
[i
].data
);
558 if (button_data
[i
].tooltip
)
559 gtk_widget_set_tooltip_text(button
, _(button_data
[i
].tooltip
));
561 atk_object_set_name(gtk_widget_get_accessible(button
), button_data
[i
].widget_name
);
563 switch (button_data
[i
].class) {
565 set_tint(button
, &buttons
->priv
->color_numbers
, 1);
568 set_tint(button
, &buttons
->priv
->color_numbers
, 2);
571 set_tint(button
, &buttons
->priv
->color_operator
, 1);
574 set_tint(button
, &buttons
->priv
->color_function
, 1);
577 set_tint(button
, &buttons
->priv
->color_memory
, 1);
580 set_tint(button
, &buttons
->priv
->color_group
, 1);
583 set_tint(button
, &buttons
->priv
->color_action
, 2);
588 /* Set special button data */
589 for (i
= 0; i
< 16; i
++) {
592 name
= g_strdup_printf("calc_%d_button", i
);
593 button
= GET_WIDGET(builder
, name
);
598 g_object_set_data(G_OBJECT(button
), "calc_digit", GINT_TO_POINTER(i
));
599 set_tint(button
, &buttons
->priv
->color_numbers
, 1);
600 len
= g_unichar_to_utf8(math_equation_get_digit_text(buttons
->priv
->equation
, i
), buffer
);
602 gtk_button_set_label(GTK_BUTTON(button
), buffer
);
606 widget
= GET_WIDGET(builder
, "calc_numeric_point_button");
608 MpSerializer
*serializer
= math_equation_get_serializer(buttons
->priv
->equation
);
611 len
= g_unichar_to_utf8(mp_serializer_get_radix(serializer
), buffer
);
613 gtk_button_set_label(GTK_BUTTON(widget
), buffer
);
616 widget
= GET_WIDGET(builder
, "calc_superscript_button");
618 buttons
->priv
->superscript_toggles
= g_list_append(buttons
->priv
->superscript_toggles
, widget
);
619 if (math_equation_get_number_mode(buttons
->priv
->equation
) == SUPERSCRIPT
)
620 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget
), TRUE
);
622 widget
= GET_WIDGET(builder
, "calc_subscript_button");
624 buttons
->priv
->subscript_toggles
= g_list_append(buttons
->priv
->subscript_toggles
, widget
);
625 if (math_equation_get_number_mode(buttons
->priv
->equation
) == SUBSCRIPT
)
626 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget
), TRUE
);
629 if (mode
== PROGRAMMING
) {
632 GtkCellRenderer
*renderer
;
634 buttons
->priv
->base_label
= GET_WIDGET(builder
, "base_label");
635 buttons
->priv
->character_code_dialog
= GET_WIDGET(builder
, "character_code_dialog");
636 buttons
->priv
->character_code_entry
= GET_WIDGET(builder
, "character_code_entry");
638 buttons
->priv
->bit_panel
= GET_WIDGET(builder
, "bit_table");
639 for (i
= 0; i
< MAXBITS
; i
++) {
640 name
= g_strdup_printf("bit_label_%d", i
);
641 buttons
->priv
->bit_labels
[i
] = GET_WIDGET(builder
, name
);
643 name
= g_strdup_printf("bit_eventbox_%d", i
);
644 set_int_data(builder
, name
, "bit_index", i
);
647 buttons
->priv
->base_combo
= GET_WIDGET(builder
, "base_combo");
648 model
= gtk_list_store_new(2, G_TYPE_STRING
, G_TYPE_INT
, G_TYPE_INT
);
649 gtk_combo_box_set_model(GTK_COMBO_BOX(buttons
->priv
->base_combo
), GTK_TREE_MODEL(model
));
650 gtk_list_store_append(GTK_LIST_STORE(model
), &iter
);
651 gtk_list_store_set(GTK_LIST_STORE(model
), &iter
, 0,
652 /* Number display mode combo: Binary, e.g. 10011010010₂ */
653 _("Binary"), 1, 2, -1);
654 gtk_list_store_append(GTK_LIST_STORE(model
), &iter
);
655 gtk_list_store_set(GTK_LIST_STORE(model
), &iter
, 0,
656 /* Number display mode combo: Octal, e.g. 2322₈ */
657 _("Octal"), 1, 8, -1);
658 gtk_list_store_append(GTK_LIST_STORE(model
), &iter
);
659 gtk_list_store_set(GTK_LIST_STORE(model
), &iter
, 0,
660 /* Number display mode combo: Decimal, e.g. 1234 */
661 _("Decimal"), 1, 10, -1);
662 gtk_list_store_append(GTK_LIST_STORE(model
), &iter
);
663 gtk_list_store_set(GTK_LIST_STORE(model
), &iter
, 0,
664 /* Number display mode combo: Hexadecimal, e.g. 4D2₁₆ */
665 _("Hexadecimal"), 1, 16, -1);
666 renderer
= gtk_cell_renderer_text_new();
667 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(buttons
->priv
->base_combo
), renderer
, TRUE
);
668 gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(buttons
->priv
->base_combo
), renderer
, "text", 0);
670 g_signal_connect(buttons
->priv
->base_combo
, "changed", G_CALLBACK(base_combobox_changed_cb
), buttons
);
671 g_signal_connect(buttons
->priv
->equation
, "notify::base", G_CALLBACK(base_changed_cb
), buttons
);
672 base_changed_cb(buttons
->priv
->equation
, NULL
, buttons
);
675 /* Setup financial functions */
676 if (mode
== FINANCIAL
) {
677 load_finc_dialogs(buttons
);
679 set_data(builder
, "calc_finc_compounding_term_button", "finc_dialog", "ctrm_dialog");
680 set_data(builder
, "calc_finc_double_declining_depreciation_button", "finc_dialog", "ddb_dialog");
681 set_data(builder
, "calc_finc_future_value_button", "finc_dialog", "fv_dialog");
682 set_data(builder
, "calc_finc_gross_profit_margin_button", "finc_dialog", "gpm_dialog");
683 set_data(builder
, "calc_finc_periodic_payment_button", "finc_dialog", "pmt_dialog");
684 set_data(builder
, "calc_finc_present_value_button", "finc_dialog", "pv_dialog");
685 set_data(builder
, "calc_finc_periodic_interest_rate_button", "finc_dialog", "rate_dialog");
686 set_data(builder
, "calc_finc_straight_line_depreciation_button", "finc_dialog", "sln_dialog");
687 set_data(builder
, "calc_finc_sum_of_the_years_digits_depreciation_button", "finc_dialog", "syd_dialog");
688 set_data(builder
, "calc_finc_term_button", "finc_dialog", "term_dialog");
691 gtk_builder_connect_signals(builder
, buttons
);
693 display_changed_cb(buttons
->priv
->equation
, NULL
, buttons
);
700 converter_changed_cb(MathConverter
*converter
, MathButtons
*buttons
)
702 Unit
*from_unit
, *to_unit
;
704 math_converter_get_conversion(converter
, &from_unit
, &to_unit
);
705 if (buttons
->priv
->mode
== FINANCIAL
) {
706 math_equation_set_source_currency(buttons
->priv
->equation
, unit_get_name(from_unit
));
707 math_equation_set_target_currency(buttons
->priv
->equation
, unit_get_name(to_unit
));
710 math_equation_set_source_units(buttons
->priv
->equation
, unit_get_name(from_unit
));
711 math_equation_set_target_units(buttons
->priv
->equation
, unit_get_name(to_unit
));
714 g_object_unref(from_unit
);
715 g_object_unref(to_unit
);
720 load_buttons(MathButtons
*buttons
)
724 if (!gtk_widget_get_visible(GTK_WIDGET(buttons
)))
727 if (!buttons
->priv
->converter
) {
728 buttons
->priv
->converter
= math_converter_new(buttons
->priv
->equation
);
729 g_signal_connect(buttons
->priv
->converter
, "changed", G_CALLBACK(converter_changed_cb
), buttons
);
730 gtk_box_pack_start(GTK_BOX(buttons
), GTK_WIDGET(buttons
->priv
->converter
), FALSE
, TRUE
, 0);
733 panel
= load_mode(buttons
, buttons
->priv
->mode
);
734 if (buttons
->priv
->active_panel
== panel
)
737 /* Hide old buttons */
738 if (buttons
->priv
->active_panel
)
739 gtk_widget_hide(buttons
->priv
->active_panel
);
741 /* Load and display new buttons */
742 buttons
->priv
->active_panel
= panel
;
744 gtk_widget_show(panel
);
749 math_buttons_set_mode(MathButtons
*buttons
, ButtonMode mode
)
751 g_return_if_fail(buttons
!= NULL
);
753 if (buttons
->priv
->mode
== mode
)
756 buttons
->priv
->mode
= mode
;
758 if (mode
== PROGRAMMING
)
759 math_equation_set_base(buttons
->priv
->equation
, buttons
->priv
->programming_base
);
761 math_equation_set_base(buttons
->priv
->equation
, 10);
763 load_buttons(buttons
);
765 gtk_widget_set_visible(GTK_WIDGET(buttons
->priv
->converter
), mode
== ADVANCED
|| mode
== FINANCIAL
);
766 if (mode
== ADVANCED
) {
767 math_converter_set_category(buttons
->priv
->converter
, NULL
);
768 math_converter_set_conversion(buttons
->priv
->converter
,
769 math_equation_get_source_units(buttons
->priv
->equation
),
770 math_equation_get_target_units(buttons
->priv
->equation
));
772 else if (mode
== FINANCIAL
) {
773 math_converter_set_category(buttons
->priv
->converter
, "currency");
774 math_converter_set_conversion(buttons
->priv
->converter
,
775 math_equation_get_source_currency(buttons
->priv
->equation
),
776 math_equation_get_target_currency(buttons
->priv
->equation
));
779 g_object_notify(G_OBJECT(buttons
), "mode");
784 math_buttons_get_mode(MathButtons
*buttons
)
786 return buttons
->priv
->mode
;
791 math_buttons_set_programming_base(MathButtons
*buttons
, gint base
)
793 g_return_if_fail(buttons
!= NULL
);
795 if (base
== buttons
->priv
->programming_base
)
798 buttons
->priv
->programming_base
= base
;
799 g_object_notify(G_OBJECT(buttons
), "programming-base");
801 if (buttons
->priv
->mode
== PROGRAMMING
)
802 math_equation_set_base(buttons
->priv
->equation
, base
);
807 math_buttons_get_programming_base(MathButtons
*buttons
)
809 g_return_val_if_fail(buttons
!= NULL
, 10);
810 return buttons
->priv
->programming_base
;
814 void exponent_cb(GtkWidget
*widget
, MathButtons
*buttons
);
817 exponent_cb(GtkWidget
*widget
, MathButtons
*buttons
)
819 math_equation_insert_exponent(buttons
->priv
->equation
);
823 void subtract_cb(GtkWidget
*widget
, MathButtons
*buttons
);
826 subtract_cb(GtkWidget
*widget
, MathButtons
*buttons
)
828 math_equation_insert_subtract(buttons
->priv
->equation
);
832 void button_cb(GtkWidget
*widget
, MathButtons
*buttons
);
835 button_cb(GtkWidget
*widget
, MathButtons
*buttons
)
837 math_equation_insert(buttons
->priv
->equation
, g_object_get_data(G_OBJECT(widget
), "calc_text"));
841 void solve_cb(GtkWidget
*widget
, MathButtons
*buttons
);
844 solve_cb(GtkWidget
*widget
, MathButtons
*buttons
)
846 math_equation_solve(buttons
->priv
->equation
);
850 void clear_cb(GtkWidget
*widget
, MathButtons
*buttons
);
853 clear_cb(GtkWidget
*widget
, MathButtons
*buttons
)
855 math_equation_clear(buttons
->priv
->equation
);
859 void delete_cb(GtkWidget
*widget
, MathButtons
*buttons
);
862 delete_cb(GtkWidget
*widget
, MathButtons
*buttons
)
864 math_equation_delete(buttons
->priv
->equation
);
868 void undo_cb(GtkWidget
*widget
, MathButtons
*buttons
);
871 undo_cb(GtkWidget
*widget
, MathButtons
*buttons
)
873 math_equation_undo(buttons
->priv
->equation
);
878 shift_cb(GtkWidget
*widget
, MathButtons
*buttons
)
880 math_equation_shift(buttons
->priv
->equation
, GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget
), "shiftcount")));
885 button_menu_position_func(GtkMenu
*menu
, gint
*x
, gint
*y
,
886 gboolean
*push_in
, gpointer user_data
)
888 GtkWidget
*button
= user_data
;
889 GtkAllocation allocation
;
893 gdk_window_get_origin(gtk_widget_get_window(button
), &loc
.x
, &loc
.y
);
894 border
= gtk_container_get_border_width(GTK_CONTAINER(button
));
895 gtk_widget_get_allocation(button
, &allocation
);
896 *x
= loc
.x
+ allocation
.x
+ border
;
897 *y
= loc
.y
+ allocation
.y
+ border
;
902 popup_button_menu(GtkWidget
*widget
, GtkMenu
*menu
)
904 gtk_menu_popup(menu
, NULL
, NULL
,
905 button_menu_position_func
, widget
, 1, gtk_get_current_event_time());
909 void memory_cb(GtkWidget
*widget
, MathButtons
*buttons
);
912 memory_cb(GtkWidget
*widget
, MathButtons
*buttons
)
914 MathVariablePopup
*popup
;
915 GtkAllocation allocation
;
918 popup
= math_variable_popup_new(buttons
->priv
->equation
);
919 set_tint(GTK_WIDGET(popup
), &buttons
->priv
->color_memory
, 1);
920 gtk_window_set_transient_for(GTK_WINDOW(popup
), GTK_WINDOW(gtk_widget_get_toplevel(widget
)));
922 gtk_widget_get_allocation(widget
, &allocation
);
923 gdk_window_get_root_coords(gtk_widget_get_window(widget
), allocation
.x
, allocation
.y
, &x
, &y
);
924 gtk_window_move(GTK_WINDOW(popup
), x
, y
);
925 gtk_widget_show(GTK_WIDGET(popup
));
929 void shift_left_cb(GtkWidget
*widget
, MathButtons
*buttons
);
932 shift_left_cb(GtkWidget
*widget
, MathButtons
*buttons
)
934 if (!buttons
->priv
->shift_left_menu
) {
938 menu
= buttons
->priv
->shift_left_menu
= gtk_menu_new();
939 gtk_menu_set_reserve_toggle_size(GTK_MENU(menu
), FALSE
);
940 set_tint(menu
, &buttons
->priv
->color_action
, 1);
942 for (i
= 1; i
< 16; i
++) {
943 GtkWidget
*item
, *label
;
944 gchar
*format
, *text
;
947 /* Left Shift Popup: Menu item to shift left by n places (n < 10) */
948 format
= ngettext("_%d place", "_%d places", i
);
951 /* Left Shift Popup: Menu item to shift left by n places (n >= 10) */
952 format
= ngettext("%d place", "%d places", i
);
954 text
= g_strdup_printf(format
, i
);
955 label
= gtk_label_new_with_mnemonic(text
);
957 item
= gtk_menu_item_new();
958 g_object_set_data(G_OBJECT(item
), "shiftcount", GINT_TO_POINTER(i
));
959 gtk_container_add(GTK_CONTAINER(item
), label
);
960 gtk_menu_shell_append(GTK_MENU_SHELL(menu
), item
);
961 g_signal_connect(item
, "activate", G_CALLBACK(shift_cb
), buttons
);
963 gtk_widget_show(label
);
964 gtk_widget_show(item
);
969 popup_button_menu(widget
, GTK_MENU(buttons
->priv
->shift_left_menu
));
973 void shift_right_cb(GtkWidget
*widget
, MathButtons
*buttons
);
976 shift_right_cb(GtkWidget
*widget
, MathButtons
*buttons
)
978 if (!buttons
->priv
->shift_right_menu
) {
982 menu
= buttons
->priv
->shift_right_menu
= gtk_menu_new();
983 gtk_menu_set_reserve_toggle_size(GTK_MENU(menu
), FALSE
);
984 set_tint(menu
, &buttons
->priv
->color_action
, 1);
986 for (i
= 1; i
< 16; i
++) {
987 GtkWidget
*item
, *label
;
988 gchar
*format
, *text
;
991 /* Right Shift Popup: Menu item to shift right by n places (n < 10) */
992 format
= ngettext("_%d place", "_%d places", i
);
995 /* Right Shift Popup: Menu item to shift right by n places (n >= 10) */
996 format
= ngettext("%d place", "%d places", i
);
998 text
= g_strdup_printf(format
, i
);
999 label
= gtk_label_new_with_mnemonic(text
);
1001 item
= gtk_menu_item_new();
1002 g_object_set_data(G_OBJECT(item
), "shiftcount", GINT_TO_POINTER(-i
));
1003 gtk_container_add(GTK_CONTAINER(item
), label
);
1004 gtk_menu_shell_append(GTK_MENU_SHELL(menu
), item
);
1005 g_signal_connect(item
, "activate", G_CALLBACK(shift_cb
), buttons
);
1007 gtk_widget_show(label
);
1008 gtk_widget_show(item
);
1013 popup_button_menu(widget
, GTK_MENU(buttons
->priv
->shift_right_menu
));
1018 insert_function_cb(GtkWidget
*widget
, MathButtons
*buttons
)
1020 math_equation_insert(buttons
->priv
->equation
, g_object_get_data(G_OBJECT(widget
), "function"));
1024 void function_cb(GtkWidget
*widget
, MathButtons
*buttons
);
1027 function_cb(GtkWidget
*widget
, MathButtons
*buttons
)
1029 if (!buttons
->priv
->function_menu
) {
1034 gchar
*name
, *function
;
1037 { /* Tooltip for the integer component button */
1038 N_("Integer Component"), "int " },
1039 { /* Tooltip for the fractional component button */
1040 N_("Fractional Component"), "frac " },
1041 { /* Tooltip for the round button */
1042 N_("Round"), "round " },
1043 { /* Tooltip for the floor button */
1044 N_("Floor"), "floor " },
1045 { /* Tooltip for the ceiling button */
1046 N_("Ceiling"), "ceil " },
1047 { /* Tooltip for the ceiling button */
1048 N_("Sign"), "sgn " },
1052 menu
= buttons
->priv
->function_menu
= gtk_menu_new();
1053 gtk_menu_set_reserve_toggle_size(GTK_MENU(menu
), FALSE
);
1054 set_tint(menu
, &buttons
->priv
->color_function
, 1);
1056 for (i
= 0; functions
[i
].name
!= NULL
; i
++) {
1059 item
= gtk_menu_item_new_with_label(_(functions
[i
].name
));
1060 g_object_set_data(G_OBJECT(item
), "function", g_strdup(functions
[i
].function
));
1061 gtk_menu_shell_append(GTK_MENU_SHELL(menu
), item
);
1062 g_signal_connect(item
, "activate", G_CALLBACK(insert_function_cb
), buttons
);
1063 gtk_widget_show(item
);
1067 popup_button_menu(widget
, GTK_MENU(buttons
->priv
->function_menu
));
1071 void factorize_cb(GtkWidget
*widget
, MathButtons
*buttons
);
1074 factorize_cb(GtkWidget
*widget
, MathButtons
*buttons
)
1076 math_equation_factorize(buttons
->priv
->equation
);
1080 void digit_cb(GtkWidget
*widget
, MathButtons
*buttons
);
1083 digit_cb(GtkWidget
*widget
, MathButtons
*buttons
)
1085 math_equation_insert_digit(buttons
->priv
->equation
, GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget
), "calc_digit")));
1089 void numeric_point_cb(GtkWidget
*widget
, MathButtons
*buttons
);
1092 numeric_point_cb(GtkWidget
*widget
, MathButtons
*buttons
)
1094 math_equation_insert_numeric_point(buttons
->priv
->equation
);
1099 void finc_cb(GtkWidget
*widget
, MathButtons
*buttons
);
1102 finc_cb(GtkWidget
*widget
, MathButtons
*buttons
)
1106 name
= g_object_get_data(G_OBJECT(widget
), "finc_dialog");
1107 gtk_dialog_run(GTK_DIALOG(GET_WIDGET(buttons
->priv
->financial_ui
, name
)));
1108 gtk_widget_hide(GTK_WIDGET(GET_WIDGET(buttons
->priv
->financial_ui
, name
)));
1112 void insert_character_code_cb(GtkWidget
*widget
, MathButtons
*buttons
);
1115 insert_character_code_cb(GtkWidget
*widget
, MathButtons
*buttons
)
1117 gtk_window_present(GTK_WINDOW(buttons
->priv
->character_code_dialog
));
1121 void finc_activate_cb(GtkWidget
*widget
, MathButtons
*buttons
);
1124 finc_activate_cb(GtkWidget
*widget
, MathButtons
*buttons
)
1128 dialog
= GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget
), "finc_dialog"));
1129 field
= GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget
), "finc_field"));
1131 if (finc_dialog_fields
[dialog
][field
+1] == NULL
) {
1132 GtkWidget
*dialog_widget
;
1133 dialog_widget
= gtk_widget_get_toplevel(widget
);
1134 if (gtk_widget_is_toplevel(dialog_widget
)) {
1135 gtk_dialog_response(GTK_DIALOG(dialog_widget
),
1141 GtkWidget
*next_widget
;
1142 next_widget
= GET_WIDGET(buttons
->priv
->financial_ui
, finc_dialog_fields
[dialog
][field
+1]);
1143 gtk_widget_grab_focus(next_widget
);
1148 void finc_response_cb(GtkWidget
*widget
, gint response_id
, MathButtons
*buttons
);
1151 finc_response_cb(GtkWidget
*widget
, gint response_id
, MathButtons
*buttons
)
1158 if (response_id
!= GTK_RESPONSE_OK
)
1161 dialog
= GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget
), "finc_dialog"));
1163 for (i
= 0; i
< 4; i
++) {
1164 if (finc_dialog_fields
[dialog
][i
] == NULL
) {
1167 entry
= GET_WIDGET(buttons
->priv
->financial_ui
, finc_dialog_fields
[dialog
][i
]);
1168 mp_set_from_string(gtk_entry_get_text(GTK_ENTRY(entry
)), 10, &arg
[i
]);
1169 gtk_entry_set_text(GTK_ENTRY(entry
), "0");
1171 gtk_widget_grab_focus(GET_WIDGET(buttons
->priv
->financial_ui
, finc_dialog_fields
[dialog
][0]));
1173 do_finc_expression(buttons
->priv
->equation
, dialog
, &arg
[0], &arg
[1], &arg
[2], &arg
[3]);
1177 void character_code_dialog_response_cb(GtkWidget
*dialog
, gint response_id
, MathButtons
*buttons
);
1180 character_code_dialog_response_cb(GtkWidget
*dialog
, gint response_id
, MathButtons
*buttons
)
1184 text
= gtk_entry_get_text(GTK_ENTRY(buttons
->priv
->character_code_entry
));
1186 if (response_id
== GTK_RESPONSE_OK
) {
1190 mp_set_from_integer(0, &x
);
1192 mp_add_integer(&x
, text
[i
], &x
);
1194 mp_shift(&x
, 8, &x
);
1201 math_equation_insert_number(buttons
->priv
->equation
, &x
);
1204 gtk_widget_hide(dialog
);
1208 void character_code_dialog_activate_cb(GtkWidget
*entry
, MathButtons
*buttons
);
1211 character_code_dialog_activate_cb(GtkWidget
*entry
, MathButtons
*buttons
)
1213 character_code_dialog_response_cb(buttons
->priv
->character_code_dialog
, GTK_RESPONSE_OK
, buttons
);
1217 gboolean
character_code_dialog_delete_cb(GtkWidget
*dialog
, GdkEvent
*event
, MathButtons
*buttons
);
1220 character_code_dialog_delete_cb(GtkWidget
*dialog
, GdkEvent
*event
, MathButtons
*buttons
)
1222 character_code_dialog_response_cb(dialog
, GTK_RESPONSE_CANCEL
, buttons
);
1227 gboolean
bit_toggle_cb(GtkWidget
*event_box
, GdkEventButton
*event
, MathButtons
*buttons
);
1230 bit_toggle_cb(GtkWidget
*event_box
, GdkEventButton
*event
, MathButtons
*buttons
)
1232 math_equation_toggle_bit(buttons
->priv
->equation
, GPOINTER_TO_INT(g_object_get_data(G_OBJECT(event_box
), "bit_index")));
1238 remove_trailing_spaces(MathButtons
*buttons
)
1240 GtkTextMark
*insert_mark
;
1241 GtkTextIter start
, end
;
1242 insert_mark
= gtk_text_buffer_get_insert (GTK_TEXT_BUFFER(buttons
->priv
->equation
));
1243 gtk_text_buffer_get_iter_at_mark(GTK_TEXT_BUFFER(buttons
->priv
->equation
), &end
, insert_mark
);
1245 while (gtk_text_iter_backward_char(&start
)) {
1246 if (!g_unichar_isspace(gtk_text_iter_get_char(&start
)))
1248 gtk_text_buffer_delete(GTK_TEXT_BUFFER(buttons
->priv
->equation
), &start
, &end
);
1253 void set_superscript_cb(GtkWidget
*widget
, MathButtons
*buttons
);
1256 set_superscript_cb(GtkWidget
*widget
, MathButtons
*buttons
)
1258 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget
))) {
1259 math_equation_set_number_mode(buttons
->priv
->equation
, SUPERSCRIPT
);
1260 if (!gtk_text_buffer_get_has_selection(GTK_TEXT_BUFFER(buttons
->priv
->equation
))) {
1261 remove_trailing_spaces(buttons
);
1264 else if (math_equation_get_number_mode(buttons
->priv
->equation
) == SUPERSCRIPT
)
1265 math_equation_set_number_mode(buttons
->priv
->equation
, NORMAL
);
1269 void set_subscript_cb(GtkWidget
*widget
, MathButtons
*buttons
);
1272 set_subscript_cb(GtkWidget
*widget
, MathButtons
*buttons
)
1274 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget
))) {
1275 math_equation_set_number_mode(buttons
->priv
->equation
, SUBSCRIPT
);
1276 if (!gtk_text_buffer_get_has_selection(GTK_TEXT_BUFFER(buttons
->priv
->equation
))) {
1277 remove_trailing_spaces(buttons
);
1280 else if (math_equation_get_number_mode(buttons
->priv
->equation
) == SUBSCRIPT
)
1281 math_equation_set_number_mode(buttons
->priv
->equation
, NORMAL
);
1286 number_mode_changed_cb(MathEquation
*equation
, GParamSpec
*spec
, MathButtons
*buttons
)
1291 mode
= math_equation_get_number_mode(equation
);
1293 for (i
= buttons
->priv
->superscript_toggles
; i
; i
= i
->next
) {
1294 GtkWidget
*widget
= i
->data
;
1295 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget
), mode
== SUPERSCRIPT
);
1297 for (i
= buttons
->priv
->subscript_toggles
; i
; i
= i
->next
) {
1298 GtkWidget
*widget
= i
->data
;
1299 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget
), mode
== SUBSCRIPT
);
1305 math_buttons_set_property(GObject
*object
,
1307 const GValue
*value
,
1312 self
= MATH_BUTTONS(object
);
1316 self
->priv
->equation
= g_value_get_object(value
);
1317 math_buttons_set_mode(self
, self
->priv
->mode
);
1318 g_signal_connect(self
->priv
->equation
, "notify::display", G_CALLBACK(display_changed_cb
), self
);
1319 g_signal_connect(self
->priv
->equation
, "notify::number-mode", G_CALLBACK(number_mode_changed_cb
), self
);
1320 g_signal_connect(self
->priv
->equation
, "notify::angle-units", G_CALLBACK(display_changed_cb
), self
);
1321 g_signal_connect(self
->priv
->equation
, "notify::number-format", G_CALLBACK(display_changed_cb
), self
);
1322 number_mode_changed_cb(self
->priv
->equation
, NULL
, self
);
1323 display_changed_cb(self
->priv
->equation
, NULL
, self
);
1326 math_buttons_set_mode(self
, g_value_get_int(value
));
1328 case PROP_PROGRAMMING_BASE
:
1329 math_buttons_set_programming_base(self
, g_value_get_int(value
));
1332 G_OBJECT_WARN_INVALID_PROPERTY_ID(object
, prop_id
, pspec
);
1339 math_buttons_get_property(GObject
*object
,
1346 self
= MATH_BUTTONS(object
);
1350 g_value_set_object(value
, self
->priv
->equation
);
1353 g_value_set_int(value
, self
->priv
->mode
);
1355 case PROP_PROGRAMMING_BASE
:
1356 g_value_set_int(value
, math_buttons_get_programming_base(self
));
1359 G_OBJECT_WARN_INVALID_PROPERTY_ID(object
, prop_id
, pspec
);
1366 math_buttons_class_init(MathButtonsClass
*klass
)
1368 static GEnumValue button_mode_values
[] =
1370 {BASIC
, "basic", "basic"},
1371 {ADVANCED
, "advanced", "advanced"},
1372 {FINANCIAL
, "financial", "financial"},
1373 {PROGRAMMING
, "programming", "programming"},
1376 GObjectClass
*object_class
= G_OBJECT_CLASS(klass
);
1378 object_class
->get_property
= math_buttons_get_property
;
1379 object_class
->set_property
= math_buttons_set_property
;
1381 g_type_class_add_private(klass
, sizeof(MathButtonsPrivate
));
1383 button_mode_type
= g_enum_register_static("ButtonMode", button_mode_values
);
1385 g_object_class_install_property(object_class
,
1387 g_param_spec_object("equation",
1389 "Equation being controlled",
1390 math_equation_get_type(),
1391 G_PARAM_READWRITE
| G_PARAM_CONSTRUCT_ONLY
));
1392 g_object_class_install_property(object_class
,
1394 g_param_spec_enum("mode",
1399 G_PARAM_READWRITE
));
1400 g_object_class_install_property(object_class
,
1401 PROP_PROGRAMMING_BASE
,
1402 g_param_spec_int("programming-base",
1404 "Base to use in programming mode",
1406 G_PARAM_READWRITE
));
1411 math_buttons_init(MathButtons
*buttons
)
1413 buttons
->priv
= G_TYPE_INSTANCE_GET_PRIVATE(buttons
, math_buttons_get_type(), MathButtonsPrivate
);
1414 gtk_box_set_spacing(GTK_BOX(buttons
), 6);
1415 buttons
->priv
->programming_base
= 10;
1416 gdk_color_parse("#0000FF", &buttons
->priv
->color_numbers
);
1417 gdk_color_parse("#00FF00", &buttons
->priv
->color_action
);
1418 gdk_color_parse("#FF0000", &buttons
->priv
->color_operator
);
1419 gdk_color_parse("#00FFFF", &buttons
->priv
->color_function
);
1420 gdk_color_parse("#FF00FF", &buttons
->priv
->color_memory
);
1421 gdk_color_parse("#FFFFFF", &buttons
->priv
->color_group
);
1422 g_signal_connect(G_OBJECT(buttons
), "show", G_CALLBACK(load_buttons
), NULL
);