[gnome-calculator] Prepare for GTK4 porting.
- From: Robert Roth <robertroth src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-calculator] Prepare for GTK4 porting.
- Date: Fri, 1 Oct 2021 17:12:26 +0000 (UTC)
commit 6a06beeb8833bd3989a228474897cc18073fcd72
Author: Robert Roth <robert roth off gmail com>
Date: Fri Oct 1 17:12:25 2021 +0000
Prepare for GTK4 porting.
* refactored function and variable popover to have a common ancestor handling most of the gtk-specific
work
* changed the way space character is removed from function and variable name to use changed signal
instead of key_press event to avoid the need for key controller
* use a Glib ListStore and bind that as a model to the function/variable popover instead of working
directly with ListBoxRows
* use EventController key on the application window instead of catching the key_press event
lib/math-function.vala | 10 +++
src/gnome-calculator.vala | 2 +-
src/math-buttons.vala | 70 +++++++++++-------
src/math-display.vala | 58 ++++++++-------
src/math-function-popover.vala | 143 +++++++++++--------------------------
src/math-popover.vala | 92 ++++++++++++++++++++++++
src/math-variable-popover.vala | 153 +++++++++++++++-------------------------
src/math-window.vala | 25 ++++---
src/meson.build | 1 +
src/ui/math-function-popover.ui | 7 +-
src/ui/math-variable-popover.ui | 3 +-
11 files changed, 297 insertions(+), 267 deletions(-)
---
diff --git a/lib/math-function.vala b/lib/math-function.vala
index de3b44a3..473f6c93 100644
--- a/lib/math-function.vala
+++ b/lib/math-function.vala
@@ -31,6 +31,16 @@ public class MathFunction : Object
get { return _description; }
}
+ public static int name_compare_func (MathFunction function1, MathFunction function2)
+ {
+ return strcmp (function1.name, function2.name);
+ }
+
+ public static bool name_equal_func (MathFunction function1, MathFunction function2)
+ {
+ return function1.name == function2.name;
+ }
+
public MathFunction (string function_name, string[] arguments, string? expression, string? description)
{
_name = function_name;
diff --git a/src/gnome-calculator.vala b/src/gnome-calculator.vala
index 49b0b92b..befe3b73 100644
--- a/src/gnome-calculator.vala
+++ b/src/gnome-calculator.vala
@@ -306,7 +306,7 @@ public class Calculator : Gtk.Application
{
try
{
- Gtk.show_uri_on_window (get_active_window (), "help:gnome-calculator",
Gtk.get_current_event_time ());
+ Gtk.show_uri (get_active_window ().get_screen (), "help:gnome-calculator", Gdk.CURRENT_TIME);
}
catch (Error e)
{
diff --git a/src/math-buttons.vala b/src/math-buttons.vala
index 7e739f93..97d86f9d 100644
--- a/src/math-buttons.vala
+++ b/src/math-buttons.vala
@@ -327,28 +327,6 @@ public class MathButtons : Gtk.Box
prog_view_more_button.visible = visible;
}
- private void update_view_more_active ()
- {
- switch (mode)
- {
- default:
- case ButtonMode.BASIC:
- break;
- case ButtonMode.ADVANCED:
- if (adv_panel != null)
- converter.view_more_active = prog_view_more_button.active = (adv_panel as
Hdy.Leaflet).visible_child_name == "advanced";
- break;
- case ButtonMode.FINANCIAL:
- if (fin_panel != null)
- converter.view_more_active = prog_view_more_button.active = (fin_panel as
Hdy.Leaflet).visible_child_name == "advanced";
- break;
- case ButtonMode.PROGRAMMING:
- if (prog_panel != null)
- converter.view_more_active = prog_view_more_button.active = prog_leaflet.visible_child_name
== "advanced";
- break;
- }
- }
-
private Gtk.Widget load_mode (ButtonMode mode)
{
Gtk.Builder builder;
@@ -447,10 +425,22 @@ public class MathButtons : Gtk.Box
menu_button.menu_model = create_word_size_menu ();
menu_button = builder.get_object ("calc_memory_button") as Gtk.MenuButton;
if (menu_button != null)
- menu_button.popover = new MathVariablePopover (equation);
+ {
+ var model = new ListStore(typeof(MathVariable));
+ MathVariablePopover math_popover = new MathVariablePopover (equation, model, (a,b) =>
MathVariable.name_compare_func(a as MathVariable, b as MathVariable));
+ fill_variables_model (model, math_popover, equation);
+ menu_button.popover = math_popover;
+ }
menu_button = builder.get_object ("calc_function_button") as Gtk.MenuButton;
+
+ FunctionManager function_manager = FunctionManager.get_default_function_manager ();
if (menu_button != null)
- menu_button.popover = new MathFunctionPopover (equation);
+ {
+ var model = new ListStore(typeof(MathFunction));
+ MathFunctionPopover math_popover = new MathFunctionPopover (equation, model);
+ fill_functions_model (model, math_popover, function_manager);
+ menu_button.popover = math_popover;
+ }
if (mode == ButtonMode.PROGRAMMING)
{
@@ -494,6 +484,38 @@ public class MathButtons : Gtk.Box
return panel;
}
+ private void fill_functions_model (ListStore model, MathPopover<MathFunction> math_popover,
FunctionManager function_manager)
+ {
+ var names = function_manager.get_names ();
+
+ for (var i = 0; names[i] != null; i++)
+ {
+ var function = function_manager[names[i]];
+ math_popover.item_added_cb (function);
+ }
+
+ function_manager.function_added.connect (f=>math_popover.item_added_cb(f as MathFunction));
+ function_manager.function_edited.connect (f=>math_popover.item_edited_cb(f as MathFunction));
+ function_manager.function_deleted.connect (f=>math_popover.item_deleted_cb(f as MathFunction));
+ }
+
+ private void fill_variables_model (ListStore model, MathPopover<MathVariable> math_popover, MathEquation
equation)
+ {
+ // Fill variable list
+ var names = equation.variables.get_names ();
+ for (var i = 0; names[i] != null; i++)
+ {
+ var value = equation.variables[names[i]];
+ math_popover.item_added_cb (new MathVariable(names[i], value));
+ }
+
+ math_popover.item_added_cb (new MathVariable ("rand", null));
+ // Listen for variable changes
+ equation.variables.variable_added.connect ((name, value) => math_popover.item_added_cb (new
MathVariable (name, value)));
+ equation.variables.variable_edited.connect ((name, value) => math_popover.item_edited_cb (new
MathVariable (name, value)));
+ equation.variables.variable_deleted.connect ((name) => math_popover.item_deleted_cb (new
MathVariable (name, null)));
+ }
+
private void converter_changed_cb ()
{
Unit from_unit, to_unit;
diff --git a/src/math-display.vala b/src/math-display.vala
index 93f2dc39..d104e812 100644
--- a/src/math-display.vala
+++ b/src/math-display.vala
@@ -21,6 +21,8 @@ public class MathDisplay : Gtk.Box
/* Buffer that shows errors etc */
Gtk.TextBuffer info_buffer;
+ Gtk.EventControllerKey event_controller;
+
/* Spinner widget that shows if we're calculating a response */
Gtk.Spinner spinner;
public bool completion_visible { get; set;}
@@ -65,7 +67,8 @@ public class MathDisplay : Gtk.Box
source_view.set_size_request (20, 20);
source_view.get_accessible ().set_role (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>
- source_view.key_press_event.connect (key_press_cb);
+ event_controller = new Gtk.EventControllerKey(source_view); //.key_press_event.connect
(key_press_cb);
+ event_controller.key_pressed.connect (key_press_cb);
create_autocompletion ();
completion_visible = false;
completion_selected = false;
@@ -152,31 +155,27 @@ public class MathDisplay : Gtk.Box
}
}
- protected override bool key_press_event (Gdk.EventKey event)
- {
- return source_view.key_press_event (event);
- }
-
- private bool key_press_cb (Gdk.EventKey event)
+ private bool key_press_cb (Gtk.EventControllerKey controller, uint keyval, uint keycode,
Gdk.ModifierType mod_state)
{
+ info ("event\n");
/* Clear on escape */
- var state = event.state & (Gdk.ModifierType.CONTROL_MASK | Gdk.ModifierType.MOD1_MASK);
+ var state = mod_state & (Gdk.ModifierType.CONTROL_MASK | Gdk.ModifierType.MOD1_MASK);
- if ((event.keyval == Gdk.Key.Escape && state == 0 && !completion_visible) ||
- (event.keyval == Gdk.Key.Delete && (event.state & Gdk.ModifierType.CONTROL_MASK) ==
Gdk.ModifierType.CONTROL_MASK))
+ if ((keyval == Gdk.Key.Escape && state == 0 && !completion_visible) ||
+ (keyval == Gdk.Key.Delete && (mod_state & Gdk.ModifierType.CONTROL_MASK) ==
Gdk.ModifierType.CONTROL_MASK))
{
equation.clear ();
status_changed_cb ();
return true;
- } else if (event.keyval == Gdk.Key.Escape && state == 0 && completion_visible)
+ } else if (keyval == Gdk.Key.Escape && state == 0 && completion_visible)
/* If completion window is shown and escape is pressed, hide it */
{
Gtk.SourceCompletion completion = source_view.get_completion ();
completion.hide ();
return true;
- } else if (state == Gdk.ModifierType.MOD1_MASK && (event.keyval == Gdk.Key.Left || event.keyval ==
Gdk.Key.Right))
+ } else if (state == Gdk.ModifierType.MOD1_MASK && (keyval == Gdk.Key.Left || keyval ==
Gdk.Key.Right))
{
- switch (event.keyval)
+ switch (keyval)
{
case Gdk.Key.Left:
history.current -= 1;
@@ -199,7 +198,7 @@ public class MathDisplay : Gtk.Box
/* Treat keypad keys as numbers even when numlock is off */
uint new_keyval = 0;
- switch (event.keyval)
+ switch (keyval)
{
case Gdk.Key.KP_Insert:
new_keyval = Gdk.Key.@0;
@@ -238,25 +237,24 @@ public class MathDisplay : Gtk.Box
if (new_keyval != 0)
{
- var new_event = event; // FIXME: Does this copy?
- new_event.keyval = new_keyval;
- return key_press_event (new_event);
+ info ("forwarding\n");
+ return key_press_cb (controller, new_keyval, keycode, mod_state);
}
- var c = Gdk.keyval_to_unicode (event.keyval);
+ var c = Gdk.keyval_to_unicode (keyval);
/* Solve on [=] if the input is not a variable name */
- if (event.keyval == Gdk.Key.equal || event.keyval == Gdk.Key.KP_Equal)
+ if (keyval == Gdk.Key.equal || keyval == Gdk.Key.KP_Equal)
{
if (!(only_variable_name.match((string) equation.equation)
|| only_function_definition.match((string) equation.equation)))
{
- event.keyval = Gdk.Key.KP_Enter;
+ keyval = Gdk.Key.KP_Enter;
}
}
/* Solve on enter */
- if (event.keyval == Gdk.Key.Return || event.keyval == Gdk.Key.KP_Enter)
+ if (keyval == Gdk.Key.Return || keyval == Gdk.Key.KP_Enter)
{
if (completion_visible && completion_selected)
return false;
@@ -265,11 +263,11 @@ public class MathDisplay : Gtk.Box
}
/* Numeric keypad will insert '.' or ',' depending on layout */
- if ((event.keyval == Gdk.Key.KP_Decimal) ||
- (event.keyval == Gdk.Key.KP_Separator) ||
- (event.keyval == Gdk.Key.period) ||
- (event.keyval == Gdk.Key.decimalpoint) ||
- (event.keyval == Gdk.Key.comma))
+ if ((keyval == Gdk.Key.KP_Decimal) ||
+ (keyval == Gdk.Key.KP_Separator) ||
+ (keyval == Gdk.Key.period) ||
+ (keyval == Gdk.Key.decimalpoint) ||
+ (keyval == Gdk.Key.comma))
{
equation.insert_numeric_point ();
return true;
@@ -308,7 +306,7 @@ public class MathDisplay : Gtk.Box
/* Shortcuts */
if (state == Gdk.ModifierType.CONTROL_MASK)
{
- switch (event.keyval)
+ switch (keyval)
{
case Gdk.Key.bracketleft:
equation.insert ("⌈");
@@ -350,7 +348,7 @@ public class MathDisplay : Gtk.Box
}
if (state == Gdk.ModifierType.MOD1_MASK)
{
- switch (event.keyval)
+ switch (keyval)
{
case Gdk.Key.bracketleft:
equation.insert ("⌊");
@@ -365,7 +363,7 @@ public class MathDisplay : Gtk.Box
{
if (!equation.has_selection)
equation.remove_trailing_spaces ();
- switch (event.keyval)
+ switch (keyval)
{
case Gdk.Key.@0:
case Gdk.Key.KP_0:
@@ -413,7 +411,7 @@ public class MathDisplay : Gtk.Box
{
if (!equation.has_selection)
equation.remove_trailing_spaces ();
- switch (event.keyval)
+ switch (keyval)
{
case Gdk.Key.@0:
case Gdk.Key.KP_0:
diff --git a/src/math-function-popover.vala b/src/math-function-popover.vala
index 159f99c2..98959996 100644
--- a/src/math-function-popover.vala
+++ b/src/math-function-popover.vala
@@ -8,14 +8,16 @@
* license.
*/
+class Something
+{
+
+}
[GtkTemplate (ui = "/org/gnome/calculator/math-function-popover.ui")]
-public class MathFunctionPopover : Gtk.Popover
+public class MathFunctionPopover : MathPopover<MathFunction>
{
// Used to pretty print function arguments, e.g. f(x, y, z)
private static string[] FUNCTION_ARGS = {"x","y","z","u","v","w","a","b","c","d"};
- private MathEquation equation;
-
[GtkChild]
private unowned Gtk.ListBox function_list;
@@ -28,51 +30,38 @@ public class MathFunctionPopover : Gtk.Popover
[GtkChild]
private unowned Gtk.SpinButton add_arguments_button;
- public MathFunctionPopover (MathEquation equation)
+ public MathFunctionPopover (MathEquation equation, ListStore model)
{
- this.equation = equation;
-
- FunctionManager function_manager = FunctionManager.get_default_function_manager ();
- var names = function_manager.get_names ();
-
- for (var i = 0; names[i] != null; i++)
- {
- var function = function_manager[names[i]];
- function_list.add (make_function_row (function));
- }
-
- // Sort list
- function_list.set_sort_func (function_list_sort);
+ base (equation, model, (a,b) => MathFunction.name_compare_func (a as MathFunction,b as
MathFunction));
- function_manager.function_added.connect ((function) => {
- function_list.add (make_function_row (function));
- });
- function_manager.function_edited.connect ((function) => {
- function_list.remove (find_row_for_function (function));
- function_list.add (make_function_row (function));
- });
- function_manager.function_deleted.connect ((function) => {
- function_list.remove (find_row_for_function (function));
- });
+ function_list.bind_model (model, (item) => make_item_row(item as MathFunction));
add_arguments_button.set_range (1, 10);
add_arguments_button.set_increments (1, 1);
+ item_edited.connect (function_edited_cb);
+ item_deleted.connect (function_deleted_cb);
}
- private Gtk.ListBoxRow? find_row_for_function (MathFunction function)
+ private void function_edited_cb (MathFunction function)
{
- weak Gtk.ListBoxRow? row = null;
- function_list.foreach ((child) => {
- if (function.name == child.get_data<MathFunction> ("function").name)
- row = child as Gtk.ListBoxRow;
- });
- return row;
+ var function_to_edit = "%s(%s)=%s@%s".printf (function.name,
+ string.joinv (";", function.arguments),
+ function.expression,
+ function.description);
+ equation.clear ();
+ equation.insert (function_to_edit);
+ }
+
+ private void function_deleted_cb (MathFunction function)
+ {
+ var function_manager = FunctionManager.get_default_function_manager ();
+ function_manager.delete (function.name);
}
[GtkCallback]
private void insert_function_cb (Gtk.ListBoxRow row)
{
- var function = row.get_data<MathFunction> ("function");
+ var function = model.get_item (row.get_index ()) as MathFunction;
equation.insert (function.name + "()");
// Place the cursor between the parentheses after inserting the function
@@ -83,7 +72,7 @@ public class MathFunctionPopover : Gtk.Popover
}
[GtkCallback]
- private bool function_name_mouse_click_cb (Gtk.Widget widget, Gdk.EventButton event)
+ private bool function_name_focus_cb (Gtk.Widget widget, Gtk.DirectionType direction)
{
if (!this.function_name_entry_placeholder_reseted)
{
@@ -95,21 +84,12 @@ public class MathFunctionPopover : Gtk.Popover
}
[GtkCallback]
- private bool function_name_key_press_cb (Gtk.Widget widget, Gdk.EventKey event)
+ private void function_name_entry_changed_cb (Gtk.Editable editable)
{
this.function_name_entry_placeholder_reseted = true;
-
- /* Can't have whitespace in names, so replace with underscores */
- if (event.keyval == Gdk.Key.space || event.keyval == Gdk.Key.KP_Space)
- event.keyval = Gdk.Key.underscore;
-
- return false;
- }
-
- [GtkCallback]
- private void function_name_changed_cb ()
- {
- add_function_button.sensitive = function_name_entry.get_text () != "";
+ var entry = editable as Gtk.Entry;
+ entry.text = entry.text.replace (" ", "_");
+ add_function_button.sensitive = entry.text != "";
}
[GtkCallback]
@@ -129,70 +109,33 @@ public class MathFunctionPopover : Gtk.Popover
equation.insert (name);
}
- private void save_function_cb (Gtk.Widget widget)
+ protected override bool is_deletable (MathFunction function)
{
- var function = widget.get_data<MathFunction> ("function");
- var function_to_edit = "%s(%s)=%s@%s".printf (function.name,
- string.joinv (";", function.arguments),
- function.expression,
- function.description);
- equation.clear ();
- equation.insert (function_to_edit);
+ return function.is_custom_function ();
}
- private void delete_function_cb (Gtk.Widget widget)
+ protected override bool is_editable (MathFunction function)
{
- var function = widget.get_data<MathFunction> ("function");
-
- var function_manager = FunctionManager.get_default_function_manager ();
- function_manager.delete (function.name);
+ return function.is_custom_function ();
}
- private Gtk.ListBoxRow make_function_row (MathFunction function)
+ protected override string get_item_text (MathFunction function)
{
- var row = new Gtk.ListBoxRow ();
- row.get_style_context ().add_class ("popover-row");
- row.set_data<MathFunction> ("function", function);
- row.set_tooltip_text ("%s".printf (function.description));
-
- var hbox = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 6);
-
var expression = "(x)";
if (function.is_custom_function ())
expression = "(%s)".printf (string.joinv (";", function.arguments));
- var label = new Gtk.Label ("<b>%s</b>%s".printf (function.name, expression));
- label.set_margin_start (6);
- label.set_use_markup (true);
- label.halign = Gtk.Align.START;
- hbox.pack_start (label, true, true, 0);
-
- if (function.is_custom_function ())
- {
- var button = new Gtk.Button.from_icon_name ("edit-symbolic");
- button.get_style_context ().add_class ("flat");
- button.set_data<MathFunction> ("function", function);
- button.clicked.connect (save_function_cb);
- hbox.pack_start (button, false, true, 0);
-
- button = new Gtk.Button.from_icon_name ("list-remove-symbolic");
- button.get_style_context ().add_class ("flat");
- button.set_data<MathFunction> ("function", function);
- button.clicked.connect (delete_function_cb);
- hbox.pack_start (button, false, true, 0);
- }
-
- row.add (hbox);
- row.show_all ();
-
- return row;
+ string text = "<b>%s</b>%s".printf (function.name, expression);
+ return text;
}
- private int function_list_sort (Gtk.ListBoxRow row1, Gtk.ListBoxRow row2)
+ protected override int get_item_index (MathFunction item)
{
- var function1 = row1.get_data<MathFunction> ("function");
- var function2 = row2.get_data<MathFunction> ("function");
-
- return strcmp (function1.name, function2.name);
+ uint position;
+ if (model.find_with_equal_func (item as Object, (a, b) => (MathFunction.name_equal_func(a as
MathFunction, b as MathFunction)), out position))
+ return (int)position;
+ else
+ return -1;
}
+
}
diff --git a/src/math-popover.vala b/src/math-popover.vala
new file mode 100644
index 00000000..aba349c1
--- /dev/null
+++ b/src/math-popover.vala
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2021 Robert Roth
+ *
+ * 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 3 of the License, or (at your option) any later
+ * version. See http://www.gnu.org/copyleft/gpl.html the full text of the
+ * license.
+ */
+
+public abstract class MathPopover<T> : Gtk.Popover
+{
+ protected MathEquation equation;
+
+ protected ListStore model;
+
+ private CompareDataFunc<T> compare_func;
+
+ protected MathPopover (MathEquation equation, ListStore model, CompareDataFunc<T> compare_func)
+ {
+ this.equation = equation;
+ this.model = model;
+ this.compare_func = (a,b) => compare_func(a,b);
+ }
+
+ public void item_added_cb (T item)
+ {
+ model.insert_sorted (item as Object, (a,b) => compare_func(a, b));
+ }
+
+ public void item_edited_cb (T item)
+ {
+ item_deleted_cb (item);
+ item_added_cb (item);
+ }
+
+ public void item_deleted_cb (T item)
+ {
+ int position = get_item_index (item);
+ if (position >= 0)
+ model.remove (position);
+ }
+
+ protected abstract int get_item_index (T item);
+
+ protected abstract bool is_deletable (T item);
+ protected abstract bool is_editable (T item);
+ protected abstract string get_item_text (T item);
+
+ public signal void item_edited(T item);
+ public signal void item_deleted(T item);
+
+ protected Gtk.Widget make_item_row (T item)
+ {
+ var hbox = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 6);
+
+ var label = new Gtk.Label (get_item_text (item));
+ label.set_margin_start (6);
+ label.set_use_markup (true);
+ label.halign = Gtk.Align.START;
+ hbox.pack_start (label, true, true, 0);
+
+ if (is_editable (item))
+ {
+ var button = new Gtk.Button.from_icon_name ("document-edit-symbolic");
+ button.get_style_context ().add_class ("flat");
+ button.set_data<Object> ("object", item as Object);
+ button.clicked.connect (save_function_cb);
+ hbox.pack_start (button, false, true, 0);
+ }
+ if (is_deletable (item))
+ {
+ var button = new Gtk.Button.from_icon_name ("list-remove-symbolic");
+ button.get_style_context ().add_class ("flat");
+ button.set_data<Object> ("object", item as Object);
+ button.clicked.connect (delete_function_cb);
+ hbox.pack_start (button, false, true, 0);
+ }
+ hbox.show_all ();
+ return hbox;
+ }
+
+ private void save_function_cb (Gtk.Widget widget)
+ {
+ item_edited((T)widget.get_data<Object> ("object"));
+ }
+
+ private void delete_function_cb (Gtk.Widget widget)
+ {
+ item_deleted((T)widget.get_data<Object> ("object"));
+ }
+}
diff --git a/src/math-variable-popover.vala b/src/math-variable-popover.vala
index a6c67981..2318934d 100644
--- a/src/math-variable-popover.vala
+++ b/src/math-variable-popover.vala
@@ -8,13 +8,33 @@
* license.
*/
+public class MathVariable : Object
+{
+ public string name;
+ public Number? value;
+
+ public MathVariable (string name, Number? value)
+ {
+ this.name = name;
+ this.value = value;
+ }
+
+ public static int name_compare_func (MathVariable var1, MathVariable var2)
+ {
+ return strcmp (var1.name, var2.name);
+ }
+
+ public static bool name_equal_func (MathVariable var1, MathVariable var2)
+ {
+ return var1.name == var2.name;
+ }
+}
+
[GtkTemplate (ui = "/org/gnome/calculator/math-variable-popover.ui")]
-public class MathVariablePopover : Gtk.Popover
+public class MathVariablePopover : MathPopover<MathVariable>
{
private static string[] RESERVED_VARIABLE_NAMES = {"_", "rand"};
- private MathEquation equation;
-
[GtkChild]
private unowned Gtk.ListBox variable_list;
[GtkChild]
@@ -22,76 +42,42 @@ public class MathVariablePopover : Gtk.Popover
[GtkChild]
private unowned Gtk.Button store_variable_button;
- public MathVariablePopover (MathEquation equation)
+ public MathVariablePopover (MathEquation equation, ListStore model, CompareDataFunc compare_func)
{
- this.equation = equation;
- equation.history_signal.connect (this.handler);
-
- // Fill variable list
- var names = equation.variables.get_names ();
- for (var i = 0; names[i] != null; i++)
- {
- var value = equation.variables[names[i]];
- variable_list.add (make_variable_row (names[i], value));
- }
+ base(equation, model, (a,b) => MathVariable.name_compare_func(a as MathVariable,b as MathVariable));
- variable_list.add (make_variable_row ("rand", null));
-
- // Sort list
- variable_list.set_sort_func (variable_list_sort);
-
- // Listen for variable changes
- equation.variables.variable_added.connect ((name, value) => {
- variable_list.add (make_variable_row (name, value));
- });
- equation.variables.variable_edited.connect ((name, value) => {
- variable_list.remove (find_row_for_variable (name));
- variable_list.add (make_variable_row (name, value));
- });
- equation.variables.variable_deleted.connect ((name) => {
- variable_list.remove (find_row_for_variable (name));
- });
+ variable_list.bind_model (model, (variable) => make_item_row (variable as MathVariable));
+ equation.history_signal.connect (this.handler);
+ item_deleted.connect (delete_variable_cb);
}
- private void handler (string answer, Number number, int number_base, uint representation_base)
+ protected override int get_item_index (MathVariable item)
{
- var row = find_row_for_variable ("_");
- if (row != null)
- variable_list.remove (row);
- variable_list.add (make_variable_row ("_", number));
+ uint position;
+ if (model.find_with_equal_func (item as Object, (a, b) => (MathVariable.name_equal_func(a as
MathVariable, b as MathVariable)), out position))
+ return (int)position;
+ else
+ return -1;
}
- private Gtk.ListBoxRow? find_row_for_variable (string name)
+ private void handler (string answer, Number number, int number_base, uint representation_base)
{
- weak Gtk.ListBoxRow? row = null;
- variable_list.foreach ((child) => {
- if (name == child.get_data<string> ("variable_name"))
- row = child as Gtk.ListBoxRow;
- });
- return row;
+ item_edited_cb (new MathVariable("_", number));
}
[GtkCallback]
private void insert_variable_cb (Gtk.ListBoxRow row)
{
- var name = row.get_data<string> ("variable_name");
- equation.insert (name);
+ var variable = model.get_item (row.get_index ()) as MathVariable;
+ equation.insert (variable.name);
}
[GtkCallback]
- private bool variable_name_key_press_cb (Gtk.Widget widget, Gdk.EventKey event)
+ private void variable_name_changed_cb (Gtk.Editable editable)
{
- /* Can't have whitespace in names, so replace with underscores */
- if (event.keyval == Gdk.Key.space || event.keyval == Gdk.Key.KP_Space)
- event.keyval = Gdk.Key.underscore;
-
- return false;
- }
-
- [GtkCallback]
- private void variable_name_changed_cb ()
- {
- store_variable_button.sensitive = (variable_name_entry.get_text () != "");
+ var entry = editable as Gtk.Entry;
+ entry.text = entry.text.replace (" ", "_");
+ store_variable_button.sensitive = (entry.text != "");
}
[GtkCallback]
@@ -112,55 +98,32 @@ public class MathVariablePopover : Gtk.Popover
variable_name_entry.set_text ("");
}
- private void delete_variable_cb (Gtk.Widget widget)
+ private void delete_variable_cb (MathVariable variable)
{
- var name = widget.get_data<string> ("variable_name");
- equation.variables.delete (name);
+ equation.variables.delete (variable.name);
}
- private Gtk.ListBoxRow make_variable_row (string name, Number? value)
+ protected override bool is_deletable (MathVariable variable)
{
- var row = new Gtk.ListBoxRow ();
- row.get_style_context ().add_class ("popover-row");
- row.set_data<string> ("variable_name", name);
+ return !(variable.name in RESERVED_VARIABLE_NAMES);
+ }
- var hbox = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 6);
+ protected override bool is_editable (MathVariable variable)
+ {
+ return false;
+ }
+ protected override string get_item_text (MathVariable variable)
+ {
string text;
- if (value != null)
+ if (variable.value != null)
{
- var value_text = equation.serializer.to_string (value);
- text = "<b>%s</b> = %s".printf (name, value_text);
+ var value_text = equation.serializer.to_string (variable.value);
+ text = "<b>%s</b> = %s".printf (variable.name, value_text);
}
else
- text = "<b>%s</b>".printf (name);
-
- var label = new Gtk.Label (text);
- label.set_margin_start (6);
- label.set_use_markup (true);
- label.halign = Gtk.Align.START;
- hbox.pack_start (label, true, true, 0);
-
- if (!(name in RESERVED_VARIABLE_NAMES))
- {
- var button = new Gtk.Button.from_icon_name ("list-remove-symbolic");
- button.get_style_context ().add_class ("flat");
- button.set_data<string> ("variable_name", name);
- button.clicked.connect (delete_variable_cb);
- hbox.pack_start (button, false, true, 0);
- }
-
- row.add (hbox);
- row.show_all ();
-
- return row;
+ text = "<b>%s</b>".printf (variable.name);
+ return text;
}
- private int variable_list_sort (Gtk.ListBoxRow row1, Gtk.ListBoxRow row2)
- {
- string name1 = row1.get_data<string> ("variable_name");
- string name2 = row2.get_data<string> ("variable_name");
-
- return strcmp (name1, name2);
- }
}
diff --git a/src/math-window.vala b/src/math-window.vala
index e0f7c444..28c8198c 100644
--- a/src/math-window.vala
+++ b/src/math-window.vala
@@ -16,7 +16,7 @@ public class MathWindow : Hdy.ApplicationWindow
public MathEquation equation { get { return _equation; } }
private MathDisplay _display;
- public MathDisplay display { get { return _display; } }
+ public MathDisplay math_display { get { return _display; } }
private MathButtons _buttons;
public MathButtons buttons { get { return _buttons; } }
private bool right_aligned;
@@ -31,6 +31,8 @@ public class MathWindow : Hdy.ApplicationWindow
[GtkChild]
private unowned MathConverter converter;
+ private Gtk.EventControllerKey event_controller;
+
private const ActionEntry[] window_entries =
{
{ "copy", copy_cb, null, null, null },
@@ -56,13 +58,17 @@ public class MathWindow : Hdy.ApplicationWindow
converter.set_category (null);
converter.set_conversion (equation.source_units, equation.target_units);
+ event_controller = new Gtk.EventControllerKey (this as Gtk.Widget);
+ // (this as Gtk.Widget).add_controller (event_controller);
+ event_controller.key_pressed.connect (key_press_cb);
+
_display = new MathDisplay (equation);
grid.attach (_display, 0, 1, 1, 1);
_display.show ();
_display.grabfocus ();
_buttons = new MathButtons (equation);
- grid.add(_buttons);
+ grid.attach_next_to(_buttons, _display, Gtk.PositionType.BOTTOM);
remove_buttons = (_buttons.mode != ButtonMode.KEYBOARD) ? true : false;
@@ -125,7 +131,7 @@ public class MathWindow : Hdy.ApplicationWindow
converter.show ();
}
- display.set_enable_osk (remove_buttons);
+ _display.set_enable_osk (remove_buttons);
}
public void critical_error (string title, string contents)
@@ -142,13 +148,11 @@ public class MathWindow : Hdy.ApplicationWindow
destroy ();
}
- protected override bool key_press_event (Gdk.EventKey event)
+ protected bool key_press_cb (Gtk.EventControllerKey controller, uint keyval, uint keycode,
Gdk.ModifierType state)
{
- var result = base.key_press_event (event);
-
- if (buttons.mode == ButtonMode.PROGRAMMING && (event.state & Gdk.ModifierType.CONTROL_MASK) ==
Gdk.ModifierType.CONTROL_MASK)
+ if (buttons.mode == ButtonMode.PROGRAMMING && (state & Gdk.ModifierType.CONTROL_MASK) ==
Gdk.ModifierType.CONTROL_MASK)
{
- switch (event.keyval)
+ switch (keyval)
{
/* Binary */
case Gdk.Key.b:
@@ -168,8 +172,7 @@ public class MathWindow : Hdy.ApplicationWindow
return true;
}
}
-
- return result;
+ return false;
}
[GtkCallback]
@@ -216,7 +219,7 @@ public class MathWindow : Hdy.ApplicationWindow
popover.hide ();
menu_button.set_active (false);
- display.grab_focus ();
+ _display.grab_focus ();
var mode = ButtonMode.BASIC;
var mode_str = parameter.get_string (null);
diff --git a/src/meson.build b/src/meson.build
index d4ee5ffc..5c8fa032 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -5,6 +5,7 @@ gnome_calculator_vala_sources = [
'math-converter.vala',
'math-display.vala',
'math-preferences.vala',
+ 'math-popover.vala',
'math-function-popover.vala',
'math-variable-popover.vala',
'math-window.vala',
diff --git a/src/ui/math-function-popover.ui b/src/ui/math-function-popover.ui
index 3cc88b76..2e3bbf14 100644
--- a/src/ui/math-function-popover.ui
+++ b/src/ui/math-function-popover.ui
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk+" version="3.16"/>
- <template class="MathFunctionPopover" parent="GtkPopover">
+ <template class="MathFunctionPopover" parent="MathPopover">
<property name="can_focus">False</property>
<child>
<object class="GtkBox" id="vbox">
@@ -32,9 +32,8 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="placeholder_text" translatable="yes">New function</property>
- <signal name="button_press_event" handler="function_name_mouse_click_cb" swapped="no"/>
- <signal name="key_press_event" handler="function_name_key_press_cb" swapped="no"/>
- <signal name="changed" handler="function_name_changed_cb" swapped="no"/>
+ <signal name="focus" handler="function_name_focus_cb" swapped="no"/>
+ <signal name="changed" handler="function_name_entry_changed_cb" swapped="no"/>
<signal name="activate" handler="add_function_cb" swapped="no"/>
</object>
</child>
diff --git a/src/ui/math-variable-popover.ui b/src/ui/math-variable-popover.ui
index 7a4c5d1a..1d375d29 100644
--- a/src/ui/math-variable-popover.ui
+++ b/src/ui/math-variable-popover.ui
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk+" version="3.16"/>
- <template class="MathVariablePopover" parent="GtkPopover">
+ <template class="MathVariablePopover" parent="MathPopover">
<property name="can_focus">False</property>
<child>
<object class="GtkBox" id="content">
@@ -39,7 +39,6 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
- <signal name="key_press_event" handler="variable_name_key_press_cb" swapped="no"/>
<signal name="changed" handler="variable_name_changed_cb" swapped="no"/>
<signal name="activate" handler="store_variable_cb" swapped="no"/>
</object>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]