Skip to content

Commit

Permalink
Winforms to 100%, no skips.
Browse files Browse the repository at this point in the history
  • Loading branch information
freakboy3742 committed Feb 25, 2023
1 parent 8a03783 commit 37985ae
Show file tree
Hide file tree
Showing 24 changed files with 183 additions and 98 deletions.
8 changes: 7 additions & 1 deletion android/tests_backend/widgets/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,15 @@ def assert_container(self, container):
else:
raise AssertionError(f"cannot find {self.native} in {container_native}")

def alignment_equivalent(self, actual, expected):
assert actual == expected
return True

async def redraw(self):
"""Request a redraw of the app, waiting until that redraw has completed."""
# Refresh the layout
# TODO: Travertino/Pack doesn't force a layout refresh
# when properties such as flex or width are altered.
# For now, do a manual refresh.
self.widget.window.content.refresh()

@property
Expand Down
4 changes: 2 additions & 2 deletions cocoa/src/toga_cocoa/constraints.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ def container(self):
@container.setter
def container(self, value):
if value is None and self.container:
# print("Remove constraints for", self.widget, 'in', self.container)
self.container.native.removeConstraint(self.width_constraint)
self.container.native.removeConstraint(self.height_constraint)
self.container.native.removeConstraint(self.left_constraint)
Expand Down Expand Up @@ -84,9 +85,8 @@ def container(self, value):
self.container.native.addConstraint(self.height_constraint)

def update(self, x, y, width, height):
# print("UPDATE", self.widget, 'in', self.container, 'to', x, y, width, height)
if self.container:
# print("IN CONTAINER")
# print("UPDATE", self.widget, 'in', self.container, 'to', x, y, width, height)
self.left_constraint.constant = x
self.top_constraint.constant = y

Expand Down
9 changes: 8 additions & 1 deletion cocoa/tests_backend/widgets/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,17 @@ def assert_container(self, container):
else:
raise ValueError(f"cannot find {self.native} in {container_native}")

def alignment_equivalent(self, actual, expected):
assert actual == expected
return True

async def redraw(self):
"""Request a redraw of the app, waiting until that redraw has completed."""
# Refresh the layout
# TODO: Travertino/Pack doesn't force a layout refresh
# when properties such as flex or width are altered.
# For now, do a manual refresh.
self.widget.window.content.refresh()

# Force a repaint
self.widget.window.content._impl.native.displayIfNeeded()

Expand Down
14 changes: 4 additions & 10 deletions cocoa/tests_backend/widgets/properties.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from dataclasses import dataclass
from travertino.fonts import Font

from toga.colors import rgba
from toga.fonts import FANTASY, NORMAL, SYSTEM
Expand All @@ -23,22 +23,16 @@ def toga_color(color):
return None


@dataclass
class Font:
family: str
size: int
style: str = NORMAL
variant: str = NORMAL
weight: str = NORMAL


def toga_font(font):
return Font(
family={
".AppleSystemUIFont": SYSTEM,
"Papyrus": FANTASY,
}.get(str(font.familyName), str(font.familyName)),
size=font.pointSize,
style=NORMAL, # TODO: ITALIC if..., SMALL_CAPS if ...
variant=NORMAL,
weight=NORMAL, # TODO: BOLD if ...
)


Expand Down
5 changes: 4 additions & 1 deletion core/src/toga/style/applicator.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ def refresh(self):
self.widget.refresh()

def set_bounds(self):
# print("APPLY LAYOUT", self.widget, self.widget.layout)
# print(" APPLY LAYOUT", self.widget, self.widget.layout)
self.widget._impl.set_bounds(
self.widget.layout.absolute_content_left,
self.widget.layout.absolute_content_top,
Expand All @@ -27,8 +27,11 @@ def set_hidden(self, hidden):
self.widget._impl.set_hidden(hidden)

def set_font(self, font):
# Changing the font of a widget can make the widget change size,
# which in turn means we need to do a re-layout
self.widget._impl.set_font(font)
self.widget._impl.rehint()
self.widget.refresh()

def set_color(self, color):
self.widget._impl.set_color(color)
Expand Down
3 changes: 3 additions & 0 deletions core/src/toga/widgets/button.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,10 @@ def text(self, value):
else:
value = str(value)
self._impl.set_text(value)
# Changing the text will probably cause the size of the button to change
# so we need to rehint, then recompute layout.
self._impl.rehint()
self.refresh()

@property
def on_press(self):
Expand Down
3 changes: 3 additions & 0 deletions core/src/toga/widgets/label.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,7 @@ def text(self, value):
else:
self._text = str(value)
self._impl.set_text(value)
# Changing the text will probably cause the size of the label to change
# so we need to rehint, then recompute layout.
self._impl.rehint()
self.refresh()
3 changes: 3 additions & 0 deletions core/src/toga/widgets/switch.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,10 @@ def text(self, value):
else:
self._text = str(value)
self._impl.set_text(value)
# Changing the text will probably cause the size of the switch to change
# so we need to rehint, then recompute layout.
self._impl.rehint()
self.refresh()

@property
def on_change(self):
Expand Down
6 changes: 6 additions & 0 deletions docs/reference/api/widgets/label.rst
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ Usage
label = toga.Label('Hello world')
Notes
-----

* Winforms does not support an alignment value of ``JUSTIFIED``. If this
alignment value is used, the label will default left alignment.

Reference
---------

Expand Down
4 changes: 4 additions & 0 deletions gtk/tests_backend/widgets/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ def assert_container(self, container):
else:
raise ValueError(f"cannot find {self.native} in {container_native}")

def alignment_equivalent(self, actual, expected):
assert actual == expected
return True

async def redraw(self):
"""Request a redraw of the app, waiting until that redraw has completed."""
# Force a repaint
Expand Down
10 changes: 8 additions & 2 deletions iOS/tests_backend/widgets/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,18 @@ def assert_container(self, container):
else:
raise ValueError(f"cannot find {self.native} in {container_native}")

def alignment_equivalent(self, actual, expected):
assert actual == expected
return True

async def redraw(self):
"""Request a redraw of the app, waiting until that redraw has completed."""
# Refresh the layout
# TODO: Travertino/Pack doesn't force a layout refresh
# when properties such as flex or width are altered.
# For now, do a manual refresh.
self.widget.window.content.refresh()

# Force a repaint
# self.widget.window.content._impl.native.layer.setNeedsDisplay_(True)
self.widget.window.content._impl.native.layer.displayIfNeeded()

@property
Expand Down
7 changes: 2 additions & 5 deletions testbed/tests/widgets/properties.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ async def test_color(widget, probe):


@mark.skipif(
current_platform in {"android", "windows"},
current_platform in {"android"},
reason="color resets don't work",
)
async def test_color_reset(widget, probe):
Expand Down Expand Up @@ -111,10 +111,7 @@ async def test_background_color_reset(widget, probe):
assert_color(probe.background_color, original)


@mark.skipif(
current_platform == "windows",
reason="TRANSPARENT not implemented",
)
async def test_background_color_transparent(widget, probe):
"Background transparency is treated as a color reset"
widget.style.background_color = TRANSPARENT
assert_color(probe.background_color, TRANSPARENT)
22 changes: 9 additions & 13 deletions testbed/tests/widgets/test_button.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@
test_text_width_change,
)


@fixture
async def widget():
return toga.Button("Hello")


test_font = mark.skipif(
current_platform in {"iOS"},
reason="font changes don't alter size",
Expand All @@ -28,12 +34,6 @@
reason="round trip empty strings don't work",
)(test_text)


@fixture
async def widget():
return toga.Button("Hello")


test_text_width_change = mark.skipif(
current_platform in {"linux"},
reason="resizes not applying correctly",
Expand All @@ -54,10 +54,6 @@ async def test_press(widget, probe):
handler.assert_called_once_with(widget)


@mark.skipif(
current_platform in {"windows"},
reason="color reset on transparent not implemented",
)
async def test_background_color_transparent(widget, probe):
"Buttons treat background transparency as a color reset."
widget.style.background_color = TRANSPARENT
Expand All @@ -75,10 +71,10 @@ async def test_background_color_transparent(widget, probe):
async def test_button_size(widget, probe):
"Check that the button resizes"
# Container is initially a non-flex row box.
# Initial button size is small, based on content size.
# Initial button size is small (but non-zero), based on content size.
await probe.redraw()
assert 50 <= probe.width <= 100
assert probe.height <= 50
assert 10 <= probe.width <= 100
assert 10 <= probe.height <= 50

# Make the button flexible; it will expand to fill horizontal space
widget.style.flex = 1
Expand Down
4 changes: 2 additions & 2 deletions testbed/tests/widgets/test_label.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,14 @@ def make_lines(n):


async def test_alignment(widget, probe):
# Initial alignment is LEFT
# Initial alignment is LEFT, initial direction is LTR
widget.parent.style.direction = COLUMN
assert probe.alignment == LEFT

for alignment in [RIGHT, CENTER, JUSTIFY]:
widget.style.text_align = alignment
await probe.redraw()
assert probe.alignment == alignment
assert probe.alignment_equivalent(probe.alignment, alignment)

# Clearing the alignment reverts to default alignment of LEFT
widget.style.text_align = None
Expand Down
2 changes: 2 additions & 0 deletions winforms/src/toga_winforms/libs/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
Action,
Bitmap,
Color,
ContentAlignment,
Convert,
CultureInfo,
Drawing2D,
Expand All @@ -32,6 +33,7 @@
String,
StringFormat,
SystemColors,
SystemFonts,
Task,
TaskScheduler,
Threading,
Expand Down
15 changes: 10 additions & 5 deletions winforms/src/toga_winforms/widgets/base.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from toga_winforms.libs import Point, Size
from toga_winforms.colors import native_color
from toga_winforms.libs import Point, Size, SystemColors


class Widget:
Expand Down Expand Up @@ -100,12 +101,16 @@ def set_font(self, font):
pass

def set_color(self, color):
# By default, color can't be changed
pass
if color is None:
self.native.ForeColor = SystemColors.WindowText
else:
self.native.ForeColor = native_color(color)

def set_background_color(self, color):
# By default, background color can't be changed.
pass
if color is None:
self.native.BackColor = SystemColors.Control
else:
self.native.BackColor = native_color(color)

# INTERFACE

Expand Down
12 changes: 3 additions & 9 deletions winforms/src/toga_winforms/widgets/box.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
from travertino.constants import TRANSPARENT

from toga_winforms.colors import native_color
from toga_winforms.libs import Point, Size, WinForms

from .base import Widget
Expand All @@ -19,6 +16,9 @@ def set_bounds(self, x, y, width, height):
vertical_shift = (
self.frame.vertical_shift - self.interface.style.padding_top
)
# The outermost widget assumes the size of the viewport
width = self.viewport.width
height = self.viewport.height
except AttributeError:
vertical_shift = self.interface.style.padding_top
horizontal_shift = self.interface.style.padding_left
Expand All @@ -30,9 +30,3 @@ def set_bounds(self, x, y, width, height):
width + horizontal_size_adjustment, height + vertical_size_adjustment
)
self.native.Location = Point(x - horizontal_shift, y + vertical_shift)

def set_background_color(self, value):
if value:
self.native.BackColor = native_color(value)
else:
self.native.BackColor = native_color(TRANSPARENT)
24 changes: 9 additions & 15 deletions winforms/src/toga_winforms/widgets/button.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
from travertino.constants import TRANSPARENT
from travertino.size import at_least

from toga.colors import TRANSPARENT
from toga_winforms.colors import native_color
from toga_winforms.libs import WinForms
from toga_winforms.libs import SystemColors, WinForms

from .base import Widget


class Button(Widget):
def create(self):
self.native = WinForms.Button()
self.native.AutoSizeMode = WinForms.AutoSizeMode.GrowAndShrink
self.native.Click += self.winforms_click
self.set_enabled(self.interface._enabled)

Expand All @@ -22,30 +23,23 @@ def get_text(self):

def set_text(self, text):
self.native.Text = text
self.rehint()

def set_font(self, font):
self.native.Font = font._impl.native

def set_background_color(self, color):
if color is None or color == TRANSPARENT:
self.native.BackColor = SystemColors.Control
else:
self.native.BackColor = native_color(color)

def set_enabled(self, value):
self.native.Enabled = self.interface._enabled

def set_on_press(self, handler):
# No special handling required
pass

def set_color(self, value):
if value:
self.native.ForeColor = native_color(value)
else:
self.native.ForeColor = native_color(TRANSPARENT)

def set_background_color(self, value):
if value:
self.native.BackColor = native_color(value)
else:
self.native.BackColor = native_color(TRANSPARENT)

def rehint(self):
# self.native.Size = Size(0, 0)
# print("REHINT Button", self, self.native.PreferredSize)
Expand Down
Loading

0 comments on commit 37985ae

Please sign in to comment.