Skip to content

Commit

Permalink
All Winforms tests passing except test_scroll_position
Browse files Browse the repository at this point in the history
  • Loading branch information
mhsmith committed May 23, 2023
1 parent df00658 commit bb71950
Show file tree
Hide file tree
Showing 13 changed files with 210 additions and 111 deletions.
2 changes: 1 addition & 1 deletion android/src/toga_android/widgets/multilinetextinput.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def beforeTextChanged(self, _charSequence, _start, _count, _after):
pass

def afterTextChanged(self, _editable):
self.interface.on_change(widget=self.interface)
self.interface.on_change(None)

def onTextChanged(self, _charSequence, _start, _before, _count):
pass
Expand Down
8 changes: 2 additions & 6 deletions android/tests_backend/widgets/multilinetextinput.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,11 @@ class MultilineTextInputProbe(LabelProbe):

@property
def value(self):
return self.text

@property
def placeholder(self):
return str(self.native.getHint())
return self.native.getHint() if self.placeholder_visible else self.text

@property
def placeholder_visible(self):
return not self.value
return not self.text

@property
def placeholder_hides_on_focus(self):
Expand Down
10 changes: 5 additions & 5 deletions cocoa/tests_backend/widgets/multilinetextinput.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ def __init__(self, widget):

@property
def value(self):
return str(self.native_text.string)

@property
def placeholder(self):
return str(self.native_text.placeholderString)
return str(
self.native_text.placeholderString
if self.placeholder_visible
else self.native_text.string
)

@property
def placeholder_visible(self):
Expand Down
2 changes: 2 additions & 0 deletions examples/colors/colors/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ def startup(self):
label = toga.Label("This is a Label", style=Pack(padding=5))
multiline_text_input = toga.MultilineTextInput(
value="This is a Multiline Text Input field!",
placeholder="placeholder",
style=Pack(padding=5, flex=1),
)
number_input = toga.NumberInput(value=1337, style=Pack(padding=5))
Expand Down Expand Up @@ -63,6 +64,7 @@ def startup(self):
)
text_input = toga.TextInput(
value="This is a Text input field!",
placeholder="placeholder",
style=Pack(padding=5),
)

Expand Down
2 changes: 1 addition & 1 deletion examples/multilinetextinput/multilinetextinput/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def add_content_pressed(self, widget, **kwargs):
)

def clear_pressed(self, widget, **kwargs):
self.multiline_input.clear()
self.multiline_input.value = ""

def scroll_to_top(self, widget):
self.multiline_input.scroll_to_top()
Expand Down
13 changes: 2 additions & 11 deletions gtk/tests_backend/widgets/multilinetextinput.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,13 @@ def __init__(self, widget):

@property
def value(self):
return self.impl.buffer.get_text(
self.impl.buffer.get_start_iter(), self.impl.buffer.get_end_iter(), True
)
buffer = self.impl.placeholder if self.placeholder_visible else self.impl.buffer
return buffer.get_text(buffer.get_start_iter(), buffer.get_end_iter(), True)

@property
def has_focus(self):
return self.native_textview.has_focus()

@property
def placeholder(self):
return self.impl.placeholder.get_text(
self.impl.placeholder.get_start_iter(),
self.impl.placeholder.get_end_iter(),
True,
)

@property
def placeholder_visible(self):
return self.native_textview.get_buffer() == self.impl.placeholder
Expand Down
10 changes: 5 additions & 5 deletions iOS/tests_backend/widgets/multilinetextinput.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ class MultilineTextInputProbe(SimpleProbe):

@property
def value(self):
return str(self.native.text)

@property
def placeholder(self):
return str(self.native.placeholder_label.text)
return str(
self.native.placeholder_label.text
if self.placeholder_visible
else self.native.text
)

@property
def placeholder_visible(self):
Expand Down
109 changes: 75 additions & 34 deletions testbed/tests/widgets/properties.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,97 +111,133 @@ async def test_text_value(widget, probe):

async def test_placeholder(widget, probe):
"The placeholder displayed by a widget can be changed"
# Placeholder visibility can be focus dependent, so add another
# widget that can take take focus
other = toga.TextInput()
widget.parent.add(other)
other.focus()

# Set a value and a placeholder.
widget.value = "Hello"
widget.placeholder = "placeholder"
await probe.redraw("Widget placeholder should not be visible")
assert widget.value == "Hello"
assert widget.placeholder == "placeholder"
assert probe.value == "Hello"
assert not probe.placeholder_visible

widget.value = "placeholder"
await probe.redraw("Placeholder should not be visible, even if value matches it")
assert widget.value == "placeholder"
assert widget.placeholder == "placeholder"
assert probe.placeholder == "placeholder"
assert probe.value == "placeholder"
assert not probe.placeholder_visible

# Clear value, making placeholder visible
widget.value = None
await probe.redraw("Widget placeholder should be visible")

assert widget.value == ""
assert widget.placeholder == "placeholder"
assert probe.placeholder == "placeholder"
assert probe.value == "placeholder"
assert probe.placeholder_visible

# Change placeholder while visible
widget.placeholder = "replacement"
await probe.redraw("Widget placeholder is now 'replacement'")

assert widget.value == ""
assert widget.placeholder == "replacement"
assert probe.placeholder == "replacement"
assert probe.value == "replacement"
assert probe.placeholder_visible


async def test_placeholder_focus(widget, probe):
"Placeholders interact correctly with focus changes"

widget.value = ""
widget.placeholder = "replacement"
hides_on_focus = probe.placeholder_hides_on_focus

# Placeholder visibility can be focus dependent, so add another
# widget that can take take focus
other = toga.TextInput()
widget.parent.add(other)
other.focus()

# Give the widget focus; this may hide the placeholder.
widget.focus()
await probe.redraw("Widget has focus")
assert widget.value == ""
assert widget.placeholder == "replacement"
assert probe.placeholder == "replacement"
if probe.placeholder_hides_on_focus:
assert not probe.placeholder_visible
else:
assert probe.placeholder_visible
assert probe.value == "" if hides_on_focus else "replacement"
assert probe.placeholder_visible == (not hides_on_focus)

# Give a different widget focus; this will show the placeholder
other.focus()
await probe.redraw("Widget has lost focus")
assert widget.value == ""
assert widget.placeholder == "replacement"
assert probe.placeholder == "replacement"
assert probe.value == "replacement"
assert probe.placeholder_visible

# Give the widget focus, again
widget.focus()
await probe.redraw("Widget has focus; placeholder may not be visible")
assert widget.value == ""
assert widget.placeholder == "replacement"
assert probe.placeholder == "replacement"
if probe.placeholder_hides_on_focus:
assert not probe.placeholder_visible
else:
assert probe.placeholder_visible
assert probe.value == "" if hides_on_focus else "replacement"
assert probe.placeholder_visible == (not hides_on_focus)

# Change the placeholder text while the widget has focus
widget.placeholder = "placeholder"
await probe.redraw("Widget placeholder should be 'placeholder'")

assert widget.value == ""
assert widget.placeholder == "placeholder"
assert probe.placeholder == "placeholder"
if probe.placeholder_hides_on_focus:
assert not probe.placeholder_visible
else:
assert probe.placeholder_visible
assert probe.value == "" if hides_on_focus else "placeholder"
assert probe.placeholder_visible == (not hides_on_focus)

# Give a different widget focus; this will show the placeholder
other.focus()
await probe.redraw("Widget has lost focus; placeholder should be visible")
assert widget.value == ""
assert widget.placeholder == "placeholder"
assert probe.placeholder == "placeholder"
assert probe.value == "placeholder"
assert probe.placeholder_visible

# Focus in and out while a value is set.
widget.value = "example"
widget.focus()
await probe.redraw("Widget has focus; placeholder not visible")
await probe.redraw("Widget has focus; value is set")
assert widget.value == "example"
assert widget.placeholder == "placeholder"
assert probe.placeholder == "placeholder"
assert probe.value == "example"
assert not probe.placeholder_visible

other.focus()
await probe.redraw("Widget has lost focus, placeholder not visible")
await probe.redraw("Widget has lost focus, value is set")
assert widget.value == "example"
assert widget.placeholder == "placeholder"
assert probe.placeholder == "placeholder"
assert probe.value == "example"
assert not probe.placeholder_visible


async def test_placeholder_color(widget, probe):
"Placeholders interact correctly with custom colors"
widget.value = "Hello"
widget.placeholder = "placeholder"
widget.style.color = RED
await probe.redraw("Value is set, color is red")
assert probe.value == "Hello"
assert not probe.placeholder_visible
assert_color(probe.color, named_color(RED))

widget.value = ""
await probe.redraw("Value is empty, placeholder is visible")
assert probe.value == "placeholder"
assert probe.placeholder_visible
# The placeholder color varies from platform to platform, so we don't test that.

widget.value = "Hello"
await probe.redraw("Value is set, color is still red")
assert probe.value == "Hello"
assert not probe.placeholder_visible
assert_color(probe.color, named_color(RED))


async def test_text_width_change(widget, probe):
"If the widget text is changed, the width of the widget changes"
orig_width = probe.width
Expand Down Expand Up @@ -315,6 +351,8 @@ async def test_background_color(widget, probe):
for color in COLORS:
widget.style.background_color = color
await probe.redraw("Widget text background color should be %s" % color)
if not getattr(probe, "background_supports_alpha", True):
color.a = 1
assert_color(probe.background_color, color)


Expand All @@ -337,10 +375,13 @@ async def test_background_color_reset(widget, probe):


async def test_background_color_transparent(widget, probe):
"Background transparency is treated as a color reset"
"Background transparency is supported"
original = probe.background_color
supports_alpha = getattr(probe, "background_supports_alpha", True)

widget.style.background_color = TRANSPARENT
await probe.redraw("Widget text background color should be TRANSPARENT")
assert_color(probe.background_color, TRANSPARENT)
assert_color(probe.background_color, TRANSPARENT if supports_alpha else original)


async def test_alignment(widget, probe):
Expand Down
5 changes: 3 additions & 2 deletions testbed/tests/widgets/test_multilinetextinput.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import toga
from toga.style import Pack

from ..conftest import skip_on_platforms
from .properties import ( # noqa: F401
test_alignment,
test_background_color,
Expand All @@ -19,14 +18,15 @@
test_font,
test_font_attrs,
test_placeholder,
test_placeholder_color,
test_placeholder_focus,
test_text_value,
test_vertical_alignment_top,
)


@pytest.fixture
async def widget():
skip_on_platforms("windows")
return toga.MultilineTextInput(value="Hello", style=Pack(flex=1))


Expand Down Expand Up @@ -129,3 +129,4 @@ async def test_on_change_handler(widget, probe):

# The number of events equals the number of characters typed.
assert handler.mock_calls == [call(widget)] * (count + 2)
assert probe.value == "Hello world"[:count]
13 changes: 10 additions & 3 deletions winforms/src/toga_winforms/widgets/base.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
from abc import abstractmethod

from toga_winforms.colors import native_color
from toga_winforms.libs import Point, Size, SystemColors
from toga_winforms.libs import Color, Point, Size, SystemColors


class Widget:
_background_supports_alpha = True

def __init__(self, interface):
super().__init__()
self.interface = interface
Expand Down Expand Up @@ -108,10 +110,15 @@ def set_color(self, color):
self.native.ForeColor = native_color(color)

def set_background_color(self, color):
if not hasattr(self, "_default_background"):
self._default_background = self.native.BackColor
if color is None:
self.native.BackColor = SystemColors.Control
self.native.BackColor = self._default_background
else:
self.native.BackColor = native_color(color)
win_color = native_color(color)
if (win_color != Color.Empty) and (not self._background_supports_alpha):
win_color = Color.FromArgb(255, win_color.R, win_color.G, win_color.B)
self.native.BackColor = win_color

# INTERFACE

Expand Down
Loading

0 comments on commit bb71950

Please sign in to comment.