1 /* Copyright (c) 2008-2009 Robert Ancell
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2, or (at your option)
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 #include <glib/gi18n.h>
21 #include "math-buttons.h"
22 #include "math-converter.h"
23 #include "math-variable-popup.h"
24 #include "financial.h"
25 #include "mp-serializer.h"
33 static GType button_mode_type
;
35 #define MAXBITS 64 /* Bit panel: number of bit fields. */
37 struct MathButtonsPrivate
39 MathEquation
*equation
;
42 gint programming_base
;
44 MathConverter
*converter
;
46 GtkBuilder
*basic_ui
, *advanced_ui
, *financial_ui
, *programming_ui
;
48 GdkColor color_numbers
, color_action
, color_operator
, color_function
, color_memory
, color_group
;
50 GtkWidget
*bas_panel
, *adv_panel
, *fin_panel
, *prog_panel
;
51 GtkWidget
*active_panel
;
53 GtkWidget
*shift_left_menu
, *shift_right_menu
;
55 GtkWidget
*function_menu
;
57 GList
*superscript_toggles
;
58 GList
*subscript_toggles
;
60 GtkWidget
*base_combo
;
61 GtkWidget
*base_label
;
63 GtkWidget
*bit_labels
[MAXBITS
];
65 GtkWidget
*character_code_dialog
;
66 GtkWidget
*character_code_entry
;
69 G_DEFINE_TYPE (MathButtons
, math_buttons
, GTK_TYPE_VBOX
);
71 #define UI_BASIC_FILE UI_DIR "/buttons-basic.ui"
72 #define UI_ADVANCED_FILE UI_DIR "/buttons-advanced.ui"
73 #define UI_FINANCIAL_FILE UI_DIR "/buttons-financial.ui"
74 #define UI_PROGRAMMING_FILE UI_DIR "/buttons-programming.ui"
76 #define GET_WIDGET(ui, name) \
77 GTK_WIDGET(gtk_builder_get_object((ui), (name)))
79 #define WM_WIDTH_FACTOR 10
80 #define WM_HEIGHT_FACTOR 30
94 const char *widget_name
;
100 static ButtonData button_data
[] = {
102 /* Tooltip for the Pi button */
104 {"eulers_number", "e", NUMBER
,
105 /* Tooltip for the Euler's Number button */
106 N_("Euler’s Number")},
107 {"imaginary", "i", NUMBER
, NULL
},
108 {"numeric_point", NULL
, NUMBER
, NULL
},
109 {"subscript", NULL
, NUMBER_BOLD
,
110 /* Tooltip for the subscript button */
111 N_("Subscript mode [Alt]")},
112 {"superscript", NULL
, NUMBER_BOLD
,
113 /* Tooltip for the superscript button */
114 N_("Superscript mode [Ctrl]")},
115 {"exponential", NULL
, NUMBER_BOLD
,
116 /* Tooltip for the scientific exponent button */
117 N_("Scientific exponent [Ctrl+E]")},
118 {"add", "+", OPERATOR
,
119 /* Tooltip for the add button */
121 {"subtract", "−", OPERATOR
,
122 /* Tooltip for the subtract button */
124 {"multiply", "×", OPERATOR
,
125 /* Tooltip for the multiply button */
127 {"divide", "÷", OPERATOR
,
128 /* Tooltip for the divide button */
130 {"modulus_divide", " mod ", OPERATOR
,
131 /* Tooltip for the modulus divide button */
132 N_("Modulus divide")},
133 {"function", NULL
, FUNCTION
,
134 /* Tooltip for the additional functions button */
135 N_("Additional Functions")},
136 {"x_pow_y", "^", FUNCTION
,
137 /* Tooltip for the exponent button */
138 N_("Exponent [^ or **]")},
139 {"x_squared", "²", FUNCTION
,
140 /* Tooltip for the square button */
141 N_("Square [Ctrl+2]")},
142 {"percentage", "%", NUMBER
,
143 /* Tooltip for the percentage button */
144 N_("Percentage [%]")},
145 {"factorial", "!", FUNCTION
,
146 /* Tooltip for the factorial button */
147 N_("Factorial [!]")},
148 {"abs", "|", FUNCTION
,
149 /* Tooltip for the absolute value button */
150 N_("Absolute value [|]")},
151 {"arg", "Arg ", FUNCTION
,
152 /* Tooltip for the complex argument component button */
153 N_("Complex argument")},
154 {"conjugate", "conj ", FUNCTION
,
155 /* Tooltip for the complex conjugate button */
156 N_("Complex conjugate")},
157 {"root", "√", FUNCTION
,
158 /* Tooltip for the root button */
159 N_("Root [Ctrl+R]")},
160 {"square_root", "√", FUNCTION
,
161 /* Tooltip for the square root button */
162 N_("Square root [Ctrl+R]")},
163 {"logarithm", "log ", FUNCTION
,
164 /* Tooltip for the logarithm button */
166 {"natural_logarithm", "ln ", FUNCTION
,
167 /* Tooltip for the natural logarithm button */
168 N_("Natural Logarithm")},
169 {"sine", "sin ", FUNCTION
,
170 /* Tooltip for the sine button */
172 {"cosine", "cos ", FUNCTION
,
173 /* Tooltip for the cosine button */
175 {"tangent", "tan ", FUNCTION
,
176 /* Tooltip for the tangent button */
178 {"hyperbolic_sine", "sinh ", FUNCTION
,
179 /* Tooltip for the hyperbolic sine button */
180 N_("Hyperbolic Sine")},
181 {"hyperbolic_cosine", "cosh ", FUNCTION
,
182 /* Tooltip for the hyperbolic cosine button */
183 N_("Hyperbolic Cosine")},
184 {"hyperbolic_tangent", "tanh ", FUNCTION
,
185 /* Tooltip for the hyperbolic tangent button */
186 N_("Hyperbolic Tangent")},
187 {"inverse", "⁻¹", FUNCTION
,
188 /* Tooltip for the inverse button */
189 N_("Inverse [Ctrl+I]")},
190 {"and", "∧", OPERATOR
,
191 /* Tooltip for the boolean AND button */
193 {"or", "∨", OPERATOR
,
194 /* Tooltip for the boolean OR button */
196 {"xor", "⊻", OPERATOR
,
197 /* Tooltip for the exclusive OR button */
198 N_("Boolean Exclusive OR")},
199 {"not", "¬", FUNCTION
,
200 /* Tooltip for the boolean NOT button */
202 {"integer_portion", "int ", FUNCTION
,
203 /* Tooltip for the integer component button */
204 N_("Integer Component")},
205 {"fractional_portion", "frac ", FUNCTION
,
206 /* Tooltip for the fractional component button */
207 N_("Fractional Component")},
208 {"real_portion", "Re ", FUNCTION
,
209 /* Tooltip for the real component button */
210 N_("Real Component")},
211 {"imaginary_portion", "Im ", FUNCTION
,
212 /* Tooltip for the imaginary component button */
213 N_("Imaginary Component")},
214 {"ones_complement", "ones ", FUNCTION
,
215 /* Tooltip for the ones complement button */
216 N_("Ones Complement")},
217 {"twos_complement", "twos ", FUNCTION
,
218 /* Tooltip for the twos complement button */
219 N_("Twos Complement")},
220 {"trunc", "trunc ", FUNCTION
,
221 /* Tooltip for the truncate button */
223 {"start_group", "(", GROUP
,
224 /* Tooltip for the start group button */
225 N_("Start Group [(]")},
226 {"end_group", ")", GROUP
,
227 /* Tooltip for the end group button */
228 N_("End Group [)]")},
229 {"memory", NULL
, MEMORY
,
230 /* Tooltip for the memory button */
232 {"character", NULL
, MEMORY
,
233 /* Tooltip for the insert character code button */
234 N_("Insert Character Code")},
235 {"result", NULL
, ACTION
,
236 /* Tooltip for the solve button */
237 N_("Calculate Result")},
238 {"factor", NULL
, ACTION
,
239 /* Tooltip for the factor button */
240 N_("Factorize [Ctrl+F]")},
241 {"clear", NULL
, GROUP
,
242 /* Tooltip for the clear button */
243 N_("Clear Display [Escape]")},
244 {"undo", NULL
, GROUP
,
245 /* Tooltip for the undo button */
246 N_("Undo [Ctrl+Z]")},
247 {"shift_left", NULL
, ACTION
,
248 /* Tooltip for the shift left button */
250 {"shift_right", NULL
, ACTION
,
251 /* Tooltip for the shift right button */
253 {"finc_compounding_term", NULL
, FUNCTION
,
254 /* Tooltip for the compounding term button */
255 N_("Compounding Term")},
256 {"finc_double_declining_depreciation", NULL
, FUNCTION
,
257 /* Tooltip for the double declining depreciation button */
258 N_("Double Declining Depreciation")},
259 {"finc_future_value", NULL
, FUNCTION
,
260 /* Tooltip for the future value button */
262 {"finc_term", NULL
, FUNCTION
,
263 /* Tooltip for the financial term button */
264 N_("Financial Term")},
265 {"finc_sum_of_the_years_digits_depreciation", NULL
, FUNCTION
,
266 /* Tooltip for the sum of the years digits depreciation button */
267 N_("Sum of the Years Digits Depreciation")},
268 {"finc_straight_line_depreciation", NULL
, FUNCTION
,
269 /* Tooltip for the straight line depreciation button */
270 N_("Straight Line Depreciation")},
271 {"finc_periodic_interest_rate", NULL
, FUNCTION
,
272 /* Tooltip for the periodic interest rate button */
273 N_("Periodic Interest Rate")},
274 {"finc_present_value", NULL
, FUNCTION
,
275 /* Tooltip for the present value button */
276 N_("Present Value")},
277 {"finc_periodic_payment", NULL
, FUNCTION
,
278 /* Tooltip for the periodic payment button */
279 N_("Periodic Payment")},
280 {"finc_gross_profit_margin", NULL
, FUNCTION
,
281 /* Tooltip for the gross profit margin button */
282 N_("Gross Profit Margin")},
283 {NULL
, NULL
, 0, NULL
}
286 /* The names of each field in the dialogs for the financial functions */
287 static char *finc_dialog_fields
[][5] = {
288 {"ctrm_pint", "ctrm_fv", "ctrm_pv", NULL
, NULL
},
289 {"ddb_cost", "ddb_life", "ddb_period", NULL
, NULL
},
290 {"fv_pmt", "fv_pint", "fv_n", NULL
, NULL
},
291 {"gpm_cost", "gpm_margin", NULL
, NULL
, NULL
},
292 {"pmt_prin", "pmt_pint", "pmt_n", NULL
, NULL
},
293 {"pv_pmt", "pv_pint", "pv_n", NULL
, NULL
},
294 {"rate_fv", "rate_pv", "rate_n", NULL
, NULL
},
295 {"sln_cost", "sln_salvage", "sln_life", NULL
, NULL
},
296 {"syd_cost", "syd_salvage", "syd_life", "syd_period", NULL
},
297 {"term_pmt", "term_fv", "term_pint", NULL
, NULL
},
298 {NULL
, NULL
, NULL
, NULL
, NULL
}
303 math_buttons_new(MathEquation
*equation
)
305 return g_object_new(math_buttons_get_type(), "equation", equation
, NULL
);
310 set_tint(GtkWidget
*widget
, GdkColor
*tint
, gint alpha
)
318 gtk_widget_ensure_style(widget
);
319 style
= gtk_widget_get_style(widget
);
321 for (j
= 0; j
< 5; j
++) {
324 color
.red
= (style
->bg
[j
].red
* (10 - alpha
) + tint
->red
* alpha
) / 10;
325 color
.green
= (style
->bg
[j
].green
* (10 - alpha
) + tint
->green
* alpha
) / 10;
326 color
.blue
= (style
->bg
[j
].blue
* (10 - alpha
) + tint
->blue
* alpha
) / 10;
328 gtk_widget_modify_bg(widget
, j
, &color
);
334 set_data(GtkBuilder
*ui
, const gchar
*object_name
, const gchar
*name
, const char *value
)
337 object
= gtk_builder_get_object(ui
, object_name
);
339 g_object_set_data(object
, name
, GINT_TO_POINTER(value
));
344 set_int_data(GtkBuilder
*ui
, const gchar
*object_name
, const gchar
*name
, gint value
)
347 object
= gtk_builder_get_object(ui
, object_name
);
349 g_object_set_data(object
, name
, GINT_TO_POINTER(value
));
354 load_finc_dialogs(MathButtons
*buttons
)
358 set_int_data(buttons
->priv
->financial_ui
, "ctrm_dialog", "finc_dialog", FINC_CTRM_DIALOG
);
359 set_int_data(buttons
->priv
->financial_ui
, "ddb_dialog", "finc_dialog", FINC_DDB_DIALOG
);
360 set_int_data(buttons
->priv
->financial_ui
, "fv_dialog", "finc_dialog", FINC_FV_DIALOG
);
361 set_int_data(buttons
->priv
->financial_ui
, "gpm_dialog", "finc_dialog", FINC_GPM_DIALOG
);
362 set_int_data(buttons
->priv
->financial_ui
, "pmt_dialog", "finc_dialog", FINC_PMT_DIALOG
);
363 set_int_data(buttons
->priv
->financial_ui
, "pv_dialog", "finc_dialog", FINC_PV_DIALOG
);
364 set_int_data(buttons
->priv
->financial_ui
, "rate_dialog", "finc_dialog", FINC_RATE_DIALOG
);
365 set_int_data(buttons
->priv
->financial_ui
, "sln_dialog", "finc_dialog", FINC_SLN_DIALOG
);
366 set_int_data(buttons
->priv
->financial_ui
, "syd_dialog", "finc_dialog", FINC_SYD_DIALOG
);
367 set_int_data(buttons
->priv
->financial_ui
, "term_dialog", "finc_dialog", FINC_TERM_DIALOG
);
369 for (i
= 0; finc_dialog_fields
[i
][0] != NULL
; i
++) {
370 for (j
= 0; finc_dialog_fields
[i
][j
]; j
++) {
372 o
= gtk_builder_get_object (buttons
->priv
->financial_ui
, finc_dialog_fields
[i
][j
]);
373 g_object_set_data(o
, "finc_field", GINT_TO_POINTER(j
));
374 g_object_set_data(o
, "finc_dialog", GINT_TO_POINTER(i
));
381 update_bit_panel(MathButtons
*buttons
)
390 if (!buttons
->priv
->bit_panel
)
393 enabled
= math_equation_get_number(buttons
->priv
->equation
, &x
);
396 MPNumber max
, fraction
;
398 mp_set_from_unsigned_integer(G_MAXUINT64
, &max
);
399 mp_fractional_part(&x
, &fraction
);
400 if (mp_is_negative(&x
) || mp_is_greater_than(&x
, &max
) || !mp_is_zero(&fraction
))
403 bits
= mp_cast_to_unsigned_int(&x
);
406 gtk_widget_set_sensitive(buttons
->priv
->bit_panel
, enabled
);
407 gtk_widget_set_sensitive(buttons
->priv
->base_label
, enabled
);
412 for (i
= 0; i
< MAXBITS
; i
++) {
415 if (bits
& (1LL << (MAXBITS
-i
-1)))
419 gtk_label_set_text(GTK_LABEL(buttons
->priv
->bit_labels
[i
]), label
);
422 base
= math_equation_get_base(buttons
->priv
->equation
);
423 label
= g_string_new("");
426 g_string_append(label
, " = ");
427 g_string_append_printf(label
, "%" G_GINT64_MODIFIER
"o", bits
);
428 g_string_append(label
, "₈");
432 g_string_append(label
, " = ");
433 g_string_append_printf(label
, "%" G_GINT64_MODIFIER
"u", bits
);
434 g_string_append(label
, "₁₀");
438 g_string_append(label
, " = ");
439 g_string_append_printf(label
, "%" G_GINT64_MODIFIER
"X", bits
);
440 g_string_append(label
, "₁₆");
443 gtk_label_set_text(GTK_LABEL(buttons
->priv
->base_label
), label
->str
);
444 g_string_free(label
, TRUE
);
449 display_changed_cb(MathEquation
*equation
, GParamSpec
*spec
, MathButtons
*buttons
)
451 update_bit_panel(buttons
);
456 base_combobox_changed_cb(GtkWidget
*combo
, MathButtons
*buttons
)
462 model
= gtk_combo_box_get_model(GTK_COMBO_BOX(combo
));
463 gtk_combo_box_get_active_iter(GTK_COMBO_BOX(combo
), &iter
);
464 gtk_tree_model_get(model
, &iter
, 1, &value
, -1);
466 math_equation_set_base(buttons
->priv
->equation
, value
);
471 base_changed_cb(MathEquation
*equation
, GParamSpec
*spec
, MathButtons
*buttons
)
477 if (buttons
->priv
->mode
!= PROGRAMMING
)
480 model
= gtk_combo_box_get_model(GTK_COMBO_BOX(buttons
->priv
->base_combo
));
481 valid
= gtk_tree_model_get_iter_first(model
, &iter
);
482 buttons
->priv
->programming_base
= math_equation_get_base(buttons
->priv
->equation
);
487 gtk_tree_model_get(model
, &iter
, 1, &v
, -1);
488 if (v
== buttons
->priv
->programming_base
)
490 valid
= gtk_tree_model_iter_next(model
, &iter
);
493 valid
= gtk_tree_model_get_iter_first(model
, &iter
);
495 gtk_combo_box_set_active_iter(GTK_COMBO_BOX(buttons
->priv
->base_combo
), &iter
);
500 load_mode(MathButtons
*buttons
, ButtonMode mode
)
502 GtkBuilder
*builder
, **builder_ptr
;
505 const gchar
*builder_file
;
506 static gchar
*objects
[] = { "button_panel", "character_code_dialog", "currency_dialog",
507 "ctrm_dialog", "ddb_dialog", "fv_dialog", "gpm_dialog",
508 "pmt_dialog", "pv_dialog", "rate_dialog", "sln_dialog",
509 "syd_dialog", "term_dialog", "adjustment1", "adjustment2", NULL
};
510 GtkWidget
*widget
, **panel
;
511 GError
*error
= NULL
;
516 builder_ptr
= &buttons
->priv
->basic_ui
;
517 builder_file
= UI_BASIC_FILE
;
518 panel
= &buttons
->priv
->bas_panel
;
521 builder_ptr
= &buttons
->priv
->advanced_ui
;
522 builder_file
= UI_ADVANCED_FILE
;
523 panel
= &buttons
->priv
->adv_panel
;
526 builder_ptr
= &buttons
->priv
->financial_ui
;
527 builder_file
= UI_FINANCIAL_FILE
;
528 panel
= &buttons
->priv
->fin_panel
;
531 builder_ptr
= &buttons
->priv
->programming_ui
;
532 builder_file
= UI_PROGRAMMING_FILE
;
533 panel
= &buttons
->priv
->prog_panel
;
540 builder
= *builder_ptr
= gtk_builder_new();
541 // FIXME: Show dialog if failed to load
542 gtk_builder_add_objects_from_file(builder
, builder_file
, objects
, &error
);
544 g_warning("Error loading button UI: %s", error
->message
);
545 g_clear_error(&error
);
547 *panel
= GET_WIDGET(builder
, "button_panel");
548 gtk_box_pack_end(GTK_BOX(buttons
), *panel
, TRUE
, TRUE
, 0);
550 /* Configure buttons */
551 for (i
= 0; button_data
[i
].widget_name
!= NULL
; i
++) {
555 name
= g_strdup_printf("calc_%s_button", button_data
[i
].widget_name
);
556 object
= gtk_builder_get_object(*builder_ptr
, name
);
561 button
= GTK_WIDGET(object
);
562 if (button_data
[i
].data
)
563 g_object_set_data(object
, "calc_text", (gpointer
) button_data
[i
].data
);
565 if (button_data
[i
].tooltip
)
566 gtk_widget_set_tooltip_text(button
, _(button_data
[i
].tooltip
));
568 atk_object_set_name(gtk_widget_get_accessible(button
), button_data
[i
].widget_name
);
570 switch (button_data
[i
].class) {
572 set_tint(button
, &buttons
->priv
->color_numbers
, 1);
575 set_tint(button
, &buttons
->priv
->color_numbers
, 2);
578 set_tint(button
, &buttons
->priv
->color_operator
, 1);
581 set_tint(button
, &buttons
->priv
->color_function
, 1);
584 set_tint(button
, &buttons
->priv
->color_memory
, 1);
587 set_tint(button
, &buttons
->priv
->color_group
, 1);
590 set_tint(button
, &buttons
->priv
->color_action
, 2);
595 /* Set special button data */
596 for (i
= 0; i
< 16; i
++) {
599 name
= g_strdup_printf("calc_%d_button", i
);
600 button
= GET_WIDGET(builder
, name
);
605 g_object_set_data(G_OBJECT(button
), "calc_digit", GINT_TO_POINTER(i
));
606 set_tint(button
, &buttons
->priv
->color_numbers
, 1);
607 len
= g_unichar_to_utf8(math_equation_get_digit_text(buttons
->priv
->equation
, i
), buffer
);
609 gtk_button_set_label(GTK_BUTTON(button
), buffer
);
613 widget
= GET_WIDGET(builder
, "calc_numeric_point_button");
615 MpSerializer
*serializer
= math_equation_get_serializer(buttons
->priv
->equation
);
618 len
= g_unichar_to_utf8(mp_serializer_get_radix(serializer
), buffer
);
620 gtk_button_set_label(GTK_BUTTON(widget
), buffer
);
623 widget
= GET_WIDGET(builder
, "calc_superscript_button");
625 buttons
->priv
->superscript_toggles
= g_list_append(buttons
->priv
->superscript_toggles
, widget
);
626 if (math_equation_get_number_mode(buttons
->priv
->equation
) == SUPERSCRIPT
)
627 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget
), TRUE
);
629 widget
= GET_WIDGET(builder
, "calc_subscript_button");
631 buttons
->priv
->subscript_toggles
= g_list_append(buttons
->priv
->subscript_toggles
, widget
);
632 if (math_equation_get_number_mode(buttons
->priv
->equation
) == SUBSCRIPT
)
633 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget
), TRUE
);
636 if (mode
== PROGRAMMING
) {
639 GtkCellRenderer
*renderer
;
641 buttons
->priv
->base_label
= GET_WIDGET(builder
, "base_label");
642 buttons
->priv
->character_code_dialog
= GET_WIDGET(builder
, "character_code_dialog");
643 buttons
->priv
->character_code_entry
= GET_WIDGET(builder
, "character_code_entry");
645 buttons
->priv
->bit_panel
= GET_WIDGET(builder
, "bit_table");
646 for (i
= 0; i
< MAXBITS
; i
++) {
647 name
= g_strdup_printf("bit_label_%d", i
);
648 buttons
->priv
->bit_labels
[i
] = GET_WIDGET(builder
, name
);
650 name
= g_strdup_printf("bit_eventbox_%d", i
);
651 set_int_data(builder
, name
, "bit_index", i
);
654 buttons
->priv
->base_combo
= GET_WIDGET(builder
, "base_combo");
655 model
= gtk_list_store_new(2, G_TYPE_STRING
, G_TYPE_INT
, G_TYPE_INT
);
656 gtk_combo_box_set_model(GTK_COMBO_BOX(buttons
->priv
->base_combo
), GTK_TREE_MODEL(model
));
657 gtk_list_store_append(GTK_LIST_STORE(model
), &iter
);
658 gtk_list_store_set(GTK_LIST_STORE(model
), &iter
, 0,
659 /* Number display mode combo: Binary, e.g. 10011010010₂ */
660 _("Binary"), 1, 2, -1);
661 gtk_list_store_append(GTK_LIST_STORE(model
), &iter
);
662 gtk_list_store_set(GTK_LIST_STORE(model
), &iter
, 0,
663 /* Number display mode combo: Octal, e.g. 2322₈ */
664 _("Octal"), 1, 8, -1);
665 gtk_list_store_append(GTK_LIST_STORE(model
), &iter
);
666 gtk_list_store_set(GTK_LIST_STORE(model
), &iter
, 0,
667 /* Number display mode combo: Decimal, e.g. 1234 */
668 _("Decimal"), 1, 10, -1);
669 gtk_list_store_append(GTK_LIST_STORE(model
), &iter
);
670 gtk_list_store_set(GTK_LIST_STORE(model
), &iter
, 0,
671 /* Number display mode combo: Hexadecimal, e.g. 4D2₁₆ */
672 _("Hexadecimal"), 1, 16, -1);
673 renderer
= gtk_cell_renderer_text_new();
674 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(buttons
->priv
->base_combo
), renderer
, TRUE
);
675 gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(buttons
->priv
->base_combo
), renderer
, "text", 0);
677 g_signal_connect(buttons
->priv
->base_combo
, "changed", G_CALLBACK(base_combobox_changed_cb
), buttons
);
678 g_signal_connect(buttons
->priv
->equation
, "notify::base", G_CALLBACK(base_changed_cb
), buttons
);
679 base_changed_cb(buttons
->priv
->equation
, NULL
, buttons
);
682 /* Setup financial functions */
683 if (mode
== FINANCIAL
) {
684 load_finc_dialogs(buttons
);
686 set_data(builder
, "calc_finc_compounding_term_button", "finc_dialog", "ctrm_dialog");
687 set_data(builder
, "calc_finc_double_declining_depreciation_button", "finc_dialog", "ddb_dialog");
688 set_data(builder
, "calc_finc_future_value_button", "finc_dialog", "fv_dialog");
689 set_data(builder
, "calc_finc_gross_profit_margin_button", "finc_dialog", "gpm_dialog");
690 set_data(builder
, "calc_finc_periodic_payment_button", "finc_dialog", "pmt_dialog");
691 set_data(builder
, "calc_finc_present_value_button", "finc_dialog", "pv_dialog");
692 set_data(builder
, "calc_finc_periodic_interest_rate_button", "finc_dialog", "rate_dialog");
693 set_data(builder
, "calc_finc_straight_line_depreciation_button", "finc_dialog", "sln_dialog");
694 set_data(builder
, "calc_finc_sum_of_the_years_digits_depreciation_button", "finc_dialog", "syd_dialog");
695 set_data(builder
, "calc_finc_term_button", "finc_dialog", "term_dialog");
698 gtk_builder_connect_signals(builder
, buttons
);
700 display_changed_cb(buttons
->priv
->equation
, NULL
, buttons
);
707 converter_changed_cb(MathConverter
*converter
, MathButtons
*buttons
)
709 Unit
*from_unit
, *to_unit
;
711 math_converter_get_conversion(converter
, &from_unit
, &to_unit
);
712 if (buttons
->priv
->mode
== FINANCIAL
) {
713 math_equation_set_source_currency(buttons
->priv
->equation
, unit_get_name(from_unit
));
714 math_equation_set_target_currency(buttons
->priv
->equation
, unit_get_name(to_unit
));
717 math_equation_set_source_units(buttons
->priv
->equation
, unit_get_name(from_unit
));
718 math_equation_set_target_units(buttons
->priv
->equation
, unit_get_name(to_unit
));
721 g_object_unref(from_unit
);
722 g_object_unref(to_unit
);
727 load_buttons(MathButtons
*buttons
)
731 if (!gtk_widget_get_visible(GTK_WIDGET(buttons
)))
734 if (!buttons
->priv
->converter
) {
735 buttons
->priv
->converter
= math_converter_new(buttons
->priv
->equation
);
736 g_signal_connect(buttons
->priv
->converter
, "changed", G_CALLBACK(converter_changed_cb
), buttons
);
737 gtk_box_pack_start(GTK_BOX(buttons
), GTK_WIDGET(buttons
->priv
->converter
), FALSE
, TRUE
, 0);
740 panel
= load_mode(buttons
, buttons
->priv
->mode
);
741 if (buttons
->priv
->active_panel
== panel
)
744 /* Hide old buttons */
745 if (buttons
->priv
->active_panel
)
746 gtk_widget_hide(buttons
->priv
->active_panel
);
748 /* Load and display new buttons */
749 buttons
->priv
->active_panel
= panel
;
751 gtk_widget_show(panel
);
756 math_buttons_set_mode(MathButtons
*buttons
, ButtonMode mode
)
760 if (buttons
->priv
->mode
== mode
)
763 old_mode
= buttons
->priv
->mode
;
764 buttons
->priv
->mode
= mode
;
766 if (mode
== PROGRAMMING
)
767 math_equation_set_base(buttons
->priv
->equation
, buttons
->priv
->programming_base
);
769 math_equation_set_base(buttons
->priv
->equation
, 10);
771 load_buttons(buttons
);
773 gtk_widget_set_visible(GTK_WIDGET(buttons
->priv
->converter
), mode
== ADVANCED
|| mode
== FINANCIAL
);
774 if (mode
== ADVANCED
) {
775 math_converter_set_category(buttons
->priv
->converter
, NULL
);
776 math_converter_set_conversion(buttons
->priv
->converter
,
777 math_equation_get_source_units(buttons
->priv
->equation
),
778 math_equation_get_target_units(buttons
->priv
->equation
));
780 else if (mode
== FINANCIAL
) {
781 math_converter_set_category(buttons
->priv
->converter
, "currency");
782 math_converter_set_conversion(buttons
->priv
->converter
,
783 math_equation_get_source_currency(buttons
->priv
->equation
),
784 math_equation_get_target_currency(buttons
->priv
->equation
));
787 g_object_notify(G_OBJECT(buttons
), "mode");
792 math_buttons_get_mode(MathButtons
*buttons
)
794 return buttons
->priv
->mode
;
799 math_buttons_set_programming_base(MathButtons
*buttons
, gint base
)
801 buttons
->priv
->programming_base
= base
;
806 math_buttons_get_programming_base(MathButtons
*buttons
)
808 return buttons
->priv
->programming_base
;
812 void exponent_cb(GtkWidget
*widget
, MathButtons
*buttons
);
815 exponent_cb(GtkWidget
*widget
, MathButtons
*buttons
)
817 math_equation_insert_exponent(buttons
->priv
->equation
);
821 void subtract_cb(GtkWidget
*widget
, MathButtons
*buttons
);
824 subtract_cb(GtkWidget
*widget
, MathButtons
*buttons
)
826 math_equation_insert_subtract(buttons
->priv
->equation
);
830 void button_cb(GtkWidget
*widget
, MathButtons
*buttons
);
833 button_cb(GtkWidget
*widget
, MathButtons
*buttons
)
835 math_equation_insert(buttons
->priv
->equation
, g_object_get_data(G_OBJECT(widget
), "calc_text"));
839 void solve_cb(GtkWidget
*widget
, MathButtons
*buttons
);
842 solve_cb(GtkWidget
*widget
, MathButtons
*buttons
)
844 math_equation_solve(buttons
->priv
->equation
);
848 void clear_cb(GtkWidget
*widget
, MathButtons
*buttons
);
851 clear_cb(GtkWidget
*widget
, MathButtons
*buttons
)
853 math_equation_clear(buttons
->priv
->equation
);
857 void delete_cb(GtkWidget
*widget
, MathButtons
*buttons
);
860 delete_cb(GtkWidget
*widget
, MathButtons
*buttons
)
862 math_equation_delete(buttons
->priv
->equation
);
866 void undo_cb(GtkWidget
*widget
, MathButtons
*buttons
);
869 undo_cb(GtkWidget
*widget
, MathButtons
*buttons
)
871 math_equation_undo(buttons
->priv
->equation
);
876 shift_cb(GtkWidget
*widget
, MathButtons
*buttons
)
878 math_equation_shift(buttons
->priv
->equation
, GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget
), "shiftcount")));
883 button_menu_position_func(GtkMenu
*menu
, gint
*x
, gint
*y
,
884 gboolean
*push_in
, gpointer user_data
)
886 GtkWidget
*button
= user_data
;
887 GtkAllocation allocation
;
891 gdk_window_get_origin(gtk_widget_get_window(button
), &loc
.x
, &loc
.y
);
892 border
= gtk_container_get_border_width(GTK_CONTAINER(button
));
893 gtk_widget_get_allocation(button
, &allocation
);
894 *x
= loc
.x
+ allocation
.x
+ border
;
895 *y
= loc
.y
+ allocation
.y
+ border
;
900 popup_button_menu(GtkWidget
*widget
, GtkMenu
*menu
)
902 gtk_menu_popup(menu
, NULL
, NULL
,
903 button_menu_position_func
, widget
, 1, gtk_get_current_event_time());
907 void memory_cb(GtkWidget
*widget
, MathButtons
*buttons
);
910 memory_cb(GtkWidget
*widget
, MathButtons
*buttons
)
912 MathVariablePopup
*popup
;
913 GtkAllocation allocation
;
916 popup
= math_variable_popup_new(buttons
->priv
->equation
);
917 set_tint(GTK_WIDGET(popup
), &buttons
->priv
->color_memory
, 1);
918 gtk_window_set_transient_for(GTK_WINDOW(popup
), GTK_WINDOW(gtk_widget_get_toplevel(widget
)));
920 gtk_widget_get_allocation(widget
, &allocation
);
921 gdk_window_get_root_coords(gtk_widget_get_window(widget
), allocation
.x
, allocation
.y
, &x
, &y
);
922 gtk_window_move(GTK_WINDOW(popup
), x
, y
);
923 gtk_widget_show(GTK_WIDGET(popup
));
927 void shift_left_cb(GtkWidget
*widget
, MathButtons
*buttons
);
930 shift_left_cb(GtkWidget
*widget
, MathButtons
*buttons
)
932 if (!buttons
->priv
->shift_left_menu
) {
936 menu
= buttons
->priv
->shift_left_menu
= gtk_menu_new();
937 gtk_menu_set_reserve_toggle_size(GTK_MENU(menu
), FALSE
);
938 set_tint(menu
, &buttons
->priv
->color_action
, 1);
940 for (i
= 1; i
< 16; i
++) {
941 GtkWidget
*item
, *label
;
942 gchar
*format
, *text
;
945 /* Left Shift Popup: Menu item to shift left by n places (n < 10) */
946 format
= ngettext("_%d place", "_%d places", i
);
949 /* Left Shift Popup: Menu item to shift left by n places (n >= 10) */
950 format
= ngettext("%d place", "%d places", i
);
952 text
= g_strdup_printf(format
, i
);
953 label
= gtk_label_new_with_mnemonic(text
);
955 item
= gtk_menu_item_new();
956 g_object_set_data(G_OBJECT(item
), "shiftcount", GINT_TO_POINTER(i
));
957 gtk_container_add(GTK_CONTAINER(item
), label
);
958 gtk_menu_shell_append(GTK_MENU_SHELL(menu
), item
);
959 g_signal_connect(item
, "activate", G_CALLBACK(shift_cb
), buttons
);
961 gtk_widget_show(label
);
962 gtk_widget_show(item
);
967 popup_button_menu(widget
, GTK_MENU(buttons
->priv
->shift_left_menu
));
971 void shift_right_cb(GtkWidget
*widget
, MathButtons
*buttons
);
974 shift_right_cb(GtkWidget
*widget
, MathButtons
*buttons
)
976 if (!buttons
->priv
->shift_right_menu
) {
980 menu
= buttons
->priv
->shift_right_menu
= gtk_menu_new();
981 gtk_menu_set_reserve_toggle_size(GTK_MENU(menu
), FALSE
);
982 set_tint(menu
, &buttons
->priv
->color_action
, 1);
984 for (i
= 1; i
< 16; i
++) {
985 GtkWidget
*item
, *label
;
986 gchar
*format
, *text
;
989 /* Right Shift Popup: Menu item to shift right by n places (n < 10) */
990 format
= ngettext("_%d place", "_%d places", i
);
993 /* Right Shift Popup: Menu item to shift right by n places (n >= 10) */
994 format
= ngettext("%d place", "%d places", i
);
996 text
= g_strdup_printf(format
, i
);
997 label
= gtk_label_new_with_mnemonic(text
);
999 item
= gtk_menu_item_new();
1000 g_object_set_data(G_OBJECT(item
), "shiftcount", GINT_TO_POINTER(-i
));
1001 gtk_container_add(GTK_CONTAINER(item
), label
);
1002 gtk_menu_shell_append(GTK_MENU_SHELL(menu
), item
);
1003 g_signal_connect(item
, "activate", G_CALLBACK(shift_cb
), buttons
);
1005 gtk_widget_show(label
);
1006 gtk_widget_show(item
);
1011 popup_button_menu(widget
, GTK_MENU(buttons
->priv
->shift_right_menu
));
1016 insert_function_cb(GtkWidget
*widget
, MathButtons
*buttons
)
1018 math_equation_insert(buttons
->priv
->equation
, g_object_get_data(G_OBJECT(widget
), "function"));
1022 void function_cb(GtkWidget
*widget
, MathButtons
*buttons
);
1025 function_cb(GtkWidget
*widget
, MathButtons
*buttons
)
1027 if (!buttons
->priv
->function_menu
) {
1032 gchar
*name
, *function
;
1035 { /* Tooltip for the integer component button */
1036 N_("Integer Component"), "int " },
1037 { /* Tooltip for the fractional component button */
1038 N_("Fractional Component"), "frac " },
1039 { /* Tooltip for the round button */
1040 N_("Round"), "round " },
1041 { /* Tooltip for the floor button */
1042 N_("Floor"), "floor " },
1043 { /* Tooltip for the ceiling button */
1044 N_("Ceiling"), "ceil " },
1045 { /* Tooltip for the ceiling button */
1046 N_("Sign"), "sgn " },
1050 menu
= buttons
->priv
->function_menu
= gtk_menu_new();
1051 gtk_menu_set_reserve_toggle_size(GTK_MENU(menu
), FALSE
);
1052 set_tint(menu
, &buttons
->priv
->color_function
, 1);
1054 for (i
= 0; functions
[i
].name
!= NULL
; i
++) {
1057 item
= gtk_menu_item_new_with_label(_(functions
[i
].name
));
1058 g_object_set_data(G_OBJECT(item
), "function", g_strdup(functions
[i
].function
));
1059 gtk_menu_shell_append(GTK_MENU_SHELL(menu
), item
);
1060 g_signal_connect(item
, "activate", G_CALLBACK(insert_function_cb
), buttons
);
1061 gtk_widget_show(item
);
1065 popup_button_menu(widget
, GTK_MENU(buttons
->priv
->function_menu
));
1069 void factorize_cb(GtkWidget
*widget
, MathButtons
*buttons
);
1072 factorize_cb(GtkWidget
*widget
, MathButtons
*buttons
)
1074 math_equation_factorize(buttons
->priv
->equation
);
1078 void digit_cb(GtkWidget
*widget
, MathButtons
*buttons
);
1081 digit_cb(GtkWidget
*widget
, MathButtons
*buttons
)
1083 math_equation_insert_digit(buttons
->priv
->equation
, GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget
), "calc_digit")));
1087 void numeric_point_cb(GtkWidget
*widget
, MathButtons
*buttons
);
1090 numeric_point_cb(GtkWidget
*widget
, MathButtons
*buttons
)
1092 math_equation_insert_numeric_point(buttons
->priv
->equation
);
1097 void finc_cb(GtkWidget
*widget
, MathButtons
*buttons
);
1100 finc_cb(GtkWidget
*widget
, MathButtons
*buttons
)
1104 name
= g_object_get_data(G_OBJECT(widget
), "finc_dialog");
1105 gtk_dialog_run(GTK_DIALOG(GET_WIDGET(buttons
->priv
->financial_ui
, name
)));
1106 gtk_widget_hide(GTK_WIDGET(GET_WIDGET(buttons
->priv
->financial_ui
, name
)));
1110 void insert_character_code_cb(GtkWidget
*widget
, MathButtons
*buttons
);
1113 insert_character_code_cb(GtkWidget
*widget
, MathButtons
*buttons
)
1115 gtk_window_present(GTK_WINDOW(buttons
->priv
->character_code_dialog
));
1119 void finc_activate_cb(GtkWidget
*widget
, MathButtons
*buttons
);
1122 finc_activate_cb(GtkWidget
*widget
, MathButtons
*buttons
)
1126 dialog
= GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget
), "finc_dialog"));
1127 field
= GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget
), "finc_field"));
1129 if (finc_dialog_fields
[dialog
][field
+1] == NULL
) {
1130 GtkWidget
*dialog_widget
;
1131 dialog_widget
= gtk_widget_get_toplevel(widget
);
1132 if (gtk_widget_is_toplevel(dialog_widget
)) {
1133 gtk_dialog_response(GTK_DIALOG(dialog_widget
),
1139 GtkWidget
*next_widget
;
1140 next_widget
= GET_WIDGET(buttons
->priv
->financial_ui
, finc_dialog_fields
[dialog
][field
+1]);
1141 gtk_widget_grab_focus(next_widget
);
1146 void finc_response_cb(GtkWidget
*widget
, gint response_id
, MathButtons
*buttons
);
1149 finc_response_cb(GtkWidget
*widget
, gint response_id
, MathButtons
*buttons
)
1156 if (response_id
!= GTK_RESPONSE_OK
)
1159 dialog
= GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget
), "finc_dialog"));
1161 for (i
= 0; i
< 4; i
++) {
1162 if (finc_dialog_fields
[dialog
][i
] == NULL
) {
1165 entry
= GET_WIDGET(buttons
->priv
->financial_ui
, finc_dialog_fields
[dialog
][i
]);
1166 mp_set_from_string(gtk_entry_get_text(GTK_ENTRY(entry
)), 10, &arg
[i
]);
1167 gtk_entry_set_text(GTK_ENTRY(entry
), "0");
1169 gtk_widget_grab_focus(GET_WIDGET(buttons
->priv
->financial_ui
, finc_dialog_fields
[dialog
][0]));
1171 do_finc_expression(buttons
->priv
->equation
, dialog
, &arg
[0], &arg
[1], &arg
[2], &arg
[3]);
1175 void character_code_dialog_response_cb(GtkWidget
*dialog
, gint response_id
, MathButtons
*buttons
);
1178 character_code_dialog_response_cb(GtkWidget
*dialog
, gint response_id
, MathButtons
*buttons
)
1182 text
= gtk_entry_get_text(GTK_ENTRY(buttons
->priv
->character_code_entry
));
1184 if (response_id
== GTK_RESPONSE_OK
) {
1188 mp_set_from_integer(0, &x
);
1190 mp_add_integer(&x
, text
[i
], &x
);
1192 mp_shift(&x
, 8, &x
);
1199 math_equation_insert_number(buttons
->priv
->equation
, &x
);
1202 gtk_widget_hide(dialog
);
1206 void character_code_dialog_activate_cb(GtkWidget
*entry
, MathButtons
*buttons
);
1209 character_code_dialog_activate_cb(GtkWidget
*entry
, MathButtons
*buttons
)
1211 character_code_dialog_response_cb(buttons
->priv
->character_code_dialog
, GTK_RESPONSE_OK
, buttons
);
1215 gboolean
character_code_dialog_delete_cb(GtkWidget
*dialog
, GdkEvent
*event
, MathButtons
*buttons
);
1218 character_code_dialog_delete_cb(GtkWidget
*dialog
, GdkEvent
*event
, MathButtons
*buttons
)
1220 character_code_dialog_response_cb(dialog
, GTK_RESPONSE_CANCEL
, buttons
);
1225 gboolean
bit_toggle_cb(GtkWidget
*event_box
, GdkEventButton
*event
, MathButtons
*buttons
);
1228 bit_toggle_cb(GtkWidget
*event_box
, GdkEventButton
*event
, MathButtons
*buttons
)
1230 math_equation_toggle_bit(buttons
->priv
->equation
, GPOINTER_TO_INT(g_object_get_data(G_OBJECT(event_box
), "bit_index")));
1236 remove_trailing_spaces(MathButtons
*buttons
)
1238 GtkTextMark
*insert_mark
;
1239 GtkTextIter start
, end
;
1240 insert_mark
= gtk_text_buffer_get_insert (GTK_TEXT_BUFFER(buttons
->priv
->equation
));
1241 gtk_text_buffer_get_iter_at_mark(GTK_TEXT_BUFFER(buttons
->priv
->equation
), &end
, insert_mark
);
1243 while (gtk_text_iter_backward_char(&start
)) {
1244 if (!g_unichar_isspace(gtk_text_iter_get_char(&start
)))
1246 gtk_text_buffer_delete(GTK_TEXT_BUFFER(buttons
->priv
->equation
), &start
, &end
);
1251 void set_superscript_cb(GtkWidget
*widget
, MathButtons
*buttons
);
1254 set_superscript_cb(GtkWidget
*widget
, MathButtons
*buttons
)
1256 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget
))) {
1257 math_equation_set_number_mode(buttons
->priv
->equation
, SUPERSCRIPT
);
1258 if (!gtk_text_buffer_get_has_selection(GTK_TEXT_BUFFER(buttons
->priv
->equation
))) {
1259 remove_trailing_spaces(buttons
);
1262 else if (math_equation_get_number_mode(buttons
->priv
->equation
) == SUPERSCRIPT
)
1263 math_equation_set_number_mode(buttons
->priv
->equation
, NORMAL
);
1267 void set_subscript_cb(GtkWidget
*widget
, MathButtons
*buttons
);
1270 set_subscript_cb(GtkWidget
*widget
, MathButtons
*buttons
)
1272 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget
))) {
1273 math_equation_set_number_mode(buttons
->priv
->equation
, SUBSCRIPT
);
1274 if (!gtk_text_buffer_get_has_selection(GTK_TEXT_BUFFER(buttons
->priv
->equation
))) {
1275 remove_trailing_spaces(buttons
);
1278 else if (math_equation_get_number_mode(buttons
->priv
->equation
) == SUBSCRIPT
)
1279 math_equation_set_number_mode(buttons
->priv
->equation
, NORMAL
);
1284 number_mode_changed_cb(MathEquation
*equation
, GParamSpec
*spec
, MathButtons
*buttons
)
1289 mode
= math_equation_get_number_mode(equation
);
1291 for (i
= buttons
->priv
->superscript_toggles
; i
; i
= i
->next
) {
1292 GtkWidget
*widget
= i
->data
;
1293 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget
), mode
== SUPERSCRIPT
);
1295 for (i
= buttons
->priv
->subscript_toggles
; i
; i
= i
->next
) {
1296 GtkWidget
*widget
= i
->data
;
1297 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget
), mode
== SUBSCRIPT
);
1303 math_buttons_set_property(GObject
*object
,
1305 const GValue
*value
,
1310 self
= MATH_BUTTONS(object
);
1314 self
->priv
->equation
= g_value_get_object(value
);
1315 math_buttons_set_mode(self
, self
->priv
->mode
);
1316 g_signal_connect(self
->priv
->equation
, "notify::display", G_CALLBACK(display_changed_cb
), self
);
1317 g_signal_connect(self
->priv
->equation
, "notify::number-mode", G_CALLBACK(number_mode_changed_cb
), self
);
1318 g_signal_connect(self
->priv
->equation
, "notify::angle-units", G_CALLBACK(display_changed_cb
), self
);
1319 g_signal_connect(self
->priv
->equation
, "notify::number-format", G_CALLBACK(display_changed_cb
), self
);
1320 number_mode_changed_cb(self
->priv
->equation
, NULL
, self
);
1321 display_changed_cb(self
->priv
->equation
, NULL
, self
);
1324 math_buttons_set_mode(self
, g_value_get_int(value
));
1327 G_OBJECT_WARN_INVALID_PROPERTY_ID(object
, prop_id
, pspec
);
1334 math_buttons_get_property(GObject
*object
,
1341 self
= MATH_BUTTONS(object
);
1345 g_value_set_object(value
, self
->priv
->equation
);
1348 g_value_set_int(value
, self
->priv
->mode
);
1351 G_OBJECT_WARN_INVALID_PROPERTY_ID(object
, prop_id
, pspec
);
1358 math_buttons_class_init(MathButtonsClass
*klass
)
1360 static GEnumValue button_mode_values
[] =
1362 {BASIC
, "basic", "basic"},
1363 {ADVANCED
, "advanced", "advanced"},
1364 {FINANCIAL
, "financial", "financial"},
1365 {PROGRAMMING
, "programming", "programming"},
1368 GObjectClass
*object_class
= G_OBJECT_CLASS(klass
);
1370 object_class
->get_property
= math_buttons_get_property
;
1371 object_class
->set_property
= math_buttons_set_property
;
1373 g_type_class_add_private(klass
, sizeof(MathButtonsPrivate
));
1375 button_mode_type
= g_enum_register_static("ButtonMode", button_mode_values
);
1377 g_object_class_install_property(object_class
,
1379 g_param_spec_object("equation",
1381 "Equation being controlled",
1382 math_equation_get_type(),
1383 G_PARAM_READWRITE
| G_PARAM_CONSTRUCT_ONLY
));
1384 g_object_class_install_property(object_class
,
1386 g_param_spec_enum("mode",
1391 G_PARAM_READWRITE
));
1396 math_buttons_init(MathButtons
*buttons
)
1398 buttons
->priv
= G_TYPE_INSTANCE_GET_PRIVATE(buttons
, math_buttons_get_type(), MathButtonsPrivate
);
1399 gtk_box_set_spacing(GTK_BOX(buttons
), 6);
1400 buttons
->priv
->programming_base
= 10;
1401 gdk_color_parse("#0000FF", &buttons
->priv
->color_numbers
);
1402 gdk_color_parse("#00FF00", &buttons
->priv
->color_action
);
1403 gdk_color_parse("#FF0000", &buttons
->priv
->color_operator
);
1404 gdk_color_parse("#00FFFF", &buttons
->priv
->color_function
);
1405 gdk_color_parse("#FF00FF", &buttons
->priv
->color_memory
);
1406 gdk_color_parse("#FFFFFF", &buttons
->priv
->color_group
);
1407 g_signal_connect(G_OBJECT(buttons
), "show", G_CALLBACK(load_buttons
), NULL
);