From 5d3fb980aff84c504eb80b6e2b954401888e63a8 Mon Sep 17 00:00:00 2001 From: Anna Schumaker Date: Mon, 26 Sep 2022 11:36:22 -0400 Subject: [PATCH] entry: Create entries for displaying specific types of values I implement Integer, Float, and String entries that update their "value" property based on the user-provided text when the Enter key is pressed. Signed-off-by: Anna Schumaker --- emmental/entry.py | 48 +++++++++++++++++++++++++++++++++ tests/test_entry.py | 65 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 113 insertions(+) diff --git a/emmental/entry.py b/emmental/entry.py index 67d4151..36524c4 100644 --- a/emmental/entry.py +++ b/emmental/entry.py @@ -1,6 +1,7 @@ # Copyright 2022 (c) Anna Schumaker. """Customized Gtk.Entries for easier development.""" from gi.repository import Gtk +from gi.repository import GObject from . import format @@ -18,3 +19,50 @@ class Filter(Gtk.SearchEntry): def get_query(self) -> str | None: """Get the query string for the entered text.""" return format.search(self.get_text()) + + +class ValueBase(Gtk.Entry): + """Base class for value entries.""" + + def __init__(self, input_purpose: Gtk.InputPurpose, value, **kwargs): + """Initialize a ValueBase Entry.""" + super().__init__(input_purpose=input_purpose, + value=value, text=str(value), **kwargs) + self.connect("notify::value", self.__notify_value) + + def __notify_value(self, entry: Gtk.Entry, param) -> None: + self.set_text(str(self.value)) + + def do_activate(self) -> None: + """Handle the activate signal.""" + self.value = type(self.value)(self.get_text()) + + +class Integer(ValueBase): + """Entry for Integers.""" + + value = GObject.Property(type=int) + + def __init__(self, value: int = 0, **kwargs): + """Initialize an Integer Entry.""" + super().__init__(Gtk.InputPurpose.DIGITS, value, **kwargs) + + +class Float(ValueBase): + """Entry for Floats.""" + + value = GObject.Property(type=float) + + def __init__(self, value: float = 0.0, **kwargs): + """Initialize a Float Entry.""" + super().__init__(Gtk.InputPurpose.NUMBER, value, **kwargs) + + +class String(ValueBase): + """Entry for Strings.""" + + value = GObject.Property(type=str) + + def __init__(self, value: str = "", **kwargs): + """Initialize a String Entry.""" + super().__init__(Gtk.InputPurpose.FREE_FORM, value, **kwargs) diff --git a/tests/test_entry.py b/tests/test_entry.py index f6d8d29..341391b 100644 --- a/tests/test_entry.py +++ b/tests/test_entry.py @@ -25,3 +25,68 @@ class TestFilterEntry(unittest.TestCase): self.assertEqual(self.entry.get_query(), None) self.entry.set_text("^test") self.assertEqual(self.entry.get_query(), "test*") + + +class TestValueEntry(unittest.TestCase): + """Test our custom Value Entries.""" + + def test_integer(self): + """Test the Integer entry.""" + entry = emmental.entry.Integer() + self.assertIsInstance(entry, emmental.entry.ValueBase) + self.assertIsInstance(entry, emmental.entry.Gtk.Entry) + self.assertEqual(entry.get_input_purpose(), Gtk.InputPurpose.DIGITS) + + self.assertEqual(entry.value, 0) + self.assertEqual(entry.get_text(), "0") + + entry.value = 42 + self.assertEqual(entry.get_text(), "42") + + entry.set_text("12345") + entry.emit("activate") + self.assertEqual(entry.value, 12345) + + entry2 = emmental.entry.Integer(value=42) + self.assertEqual(entry2.value, 42) + self.assertEqual(entry2.get_text(), "42") + + def test_float(self): + """Test the Float entry.""" + entry = emmental.entry.Float() + self.assertIsInstance(entry, emmental.entry.ValueBase) + self.assertEqual(entry.get_input_purpose(), Gtk.InputPurpose.NUMBER) + + self.assertEqual(entry.value, 0.0) + self.assertEqual(entry.get_text(), "0.0") + + entry.value = 4.2 + self.assertEqual(entry.get_text(), "4.2") + + entry.set_text("1.2345") + entry.emit("activate") + self.assertEqual(entry.value, 1.2345) + + entry2 = emmental.entry.Float(value=4.2) + self.assertEqual(entry2.value, 4.2) + self.assertEqual(entry2.get_text(), "4.2") + + def test_string(self): + """Test the String entry.""" + entry = emmental.entry.String() + self.assertIsInstance(entry, emmental.entry.ValueBase) + self.assertEqual(entry.get_input_purpose(), Gtk.InputPurpose.FREE_FORM) + + self.assertEqual(entry.value, "") + self.assertEqual(entry.get_text(), "") + + entry.value = "text" + self.assertEqual(entry.get_text(), "text") + + entry.set_text("other text") + entry.emit("activate") + self.assertEqual(entry.value, "other text") + + entry2 = emmental.entry.String(value="text") + self.assertEqual(entry2.value, "text") + self.assertEqual(entry2.get_text(), "text")