Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix visibility and display support in Pack() #2435

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changes/2428.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Issue with `visibility` on GTK and `display` on all platform.
30 changes: 27 additions & 3 deletions core/src/toga/style/pack.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ def _debug(self, *args): # pragma: no cover
@property
def _hidden(self):
"Does this style declaration define a object that should be hidden"
return self.visibility == HIDDEN
return self.visibility == HIDDEN or self.display == NONE

def apply(self, prop, value):
if self._applicator:
Expand All @@ -104,8 +104,8 @@ def apply(self, prop, value):
self._applicator.set_color(value)
elif prop == "background_color":
self._applicator.set_background_color(value)
elif prop == "visibility":
self._applicator.set_hidden(value == HIDDEN)
elif prop == "visibility" or prop == "display":
self._applicator.set_hidden(self._hidden)
elif prop in (
"font_family",
"font_size",
Expand Down Expand Up @@ -275,6 +275,9 @@ def _layout_row_children(
min_width = 0
remaining_width = available_width
for child in node.children:
# Skip calculation if widget is not displayed
if child.style.display == NONE:
continue
# self._debug(f"PASS 1 {child}")
if child.style.width != NONE:
# self._debug(f"- fixed width {child.style.width}")
Expand Down Expand Up @@ -404,6 +407,9 @@ def _layout_row_children(
# Pass 2: Lay out children with an intrinsic flexible width,
# or no width specification at all.
for child in node.children:
# Skip calculation if widget is not displayed
if child.style.display == NONE:
continue
# self._debug(f"PASS 2 {child}")
if child.style.width != NONE:
# self._debug("- already laid out (explicit width)")
Expand Down Expand Up @@ -489,6 +495,9 @@ def _layout_row_children(
height = 0
min_height = 0
for child in node.children:
# Skip calculation if widget is not displayed
if child.style.display == NONE:
continue
# self._debug(f"PASS 3: {child} AT HORIZONTAL {offset=}")
if node.style.text_direction is RTL:
# self._debug("- RTL")
Expand Down Expand Up @@ -522,6 +531,9 @@ def _layout_row_children(

# Pass 4: set vertical position of each child.
for child in node.children:
# Skip calculation if widget is not displayed
if child.style.display == NONE:
continue
# self._debug(f"PASS 4: {child}")
extra = height - (
child.layout.content_height
Expand Down Expand Up @@ -559,6 +571,9 @@ def _layout_column_children(
min_height = 0
remaining_height = available_height
for child in node.children:
# Skip calculation if widget is not displayed
if child.style.display == NONE:
continue
# self._debug(f"PASS 1 {child}")
if child.style.height != NONE:
# self._debug(f"- fixed height {child.style.height}")
Expand Down Expand Up @@ -689,6 +704,9 @@ def _layout_column_children(
# Pass 2: Lay out children with an intrinsic flexible height,
# or no height specification at all.
for child in node.children:
# Skip calculation if widget is not displayed
if child.style.display == NONE:
continue
# self._debug(f"PASS 2 {child}")
if child.style.height != NONE:
# self._debug("- already laid out (explicit height)")
Expand Down Expand Up @@ -775,6 +793,9 @@ def _layout_column_children(
width = 0
min_width = 0
for child in node.children:
# Skip calculation if widget is not displayed
if child.style.display == NONE:
continue
# self._debug(f"PASS 3: {child} AT VERTICAL OFFSET {offset}")
offset += child.style.padding_top
child.layout.content_top = offset
Expand All @@ -800,6 +821,9 @@ def _layout_column_children(

# Pass 4: set horizontal position of each child.
for child in node.children:
# Skip calculation if widget is not displayed
if child.style.display == NONE:
continue
# self._debug(f"PASS 4: {child}")
extra = width - (
child.layout.content_width
Expand Down
5 changes: 1 addition & 4 deletions gtk/src/toga_gtk/widgets/activityindicator.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,6 @@ def stop(self):
self.native.stop()

def rehint(self):
# print("REHINT", self, self.native.get_preferred_width(), self.native.get_preferred_height())
width = self.native.get_preferred_width()
height = self.native.get_preferred_height()

width, height = self._get_preferred_size(self.native)
self.interface.intrinsic.width = width[0]
self.interface.intrinsic.height = height[0]
18 changes: 13 additions & 5 deletions gtk/src/toga_gtk/widgets/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ def container(self, container):
# setting container, adding self to container.native
self._container = container
self._container.add(self.native)
self.native.show_all()

for child in self.interface.children:
child._impl.container = container
Expand All @@ -84,6 +83,18 @@ def get_tab_index(self):
def set_tab_index(self, tab_index):
self.interface.factory.not_implemented("Widget.set_tab_index()")

def _get_preferred_size(self, native):
# Utility function to get the preferred size of widget regardless of it's visibility.
visible = native.get_visible()
if not visible:
native.set_visible(True)
# print("REHINT", self, native.get_preferred_width(), native.get_preferred_height())
width = native.get_preferred_width()
height = native.get_preferred_height()
if not visible:
native.set_visible(visible)
return width, height

######################################################################
# CSS tools
######################################################################
Expand Down Expand Up @@ -185,9 +196,6 @@ def refresh(self):

def rehint(self):
# Perform the actual GTK rehint.
# print("REHINT", self, self.native.get_preferred_width(), self.native.get_preferred_height())
width = self.native.get_preferred_width()
height = self.native.get_preferred_height()

width, height = self._get_preferred_size(self.native)
self.interface.intrinsic.width = at_least(width[0])
self.interface.intrinsic.height = at_least(height[0])
5 changes: 1 addition & 4 deletions gtk/src/toga_gtk/widgets/button.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,7 @@ def set_background_color(self, color):
super().set_background_color(color)

def rehint(self):
# print("REHINT", self, self.native.get_preferred_width(), self.native.get_preferred_height())
width = self.native.get_preferred_width()
height = self.native.get_preferred_height()

width, height = self._get_preferred_size(self.native)
self.interface.intrinsic.width = at_least(width[0])
self.interface.intrinsic.height = height[1]

Expand Down
1 change: 0 additions & 1 deletion gtk/src/toga_gtk/widgets/canvas.py
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,6 @@ def get_image_data(self):

# Rehint
def rehint(self):
# print("REHINT", self, self.native.get_preferred_width(), self.native.get_preferred_height())
# width = self.native.get_allocation().width
# height = self.native.get_allocation().height
width = self.interface._MIN_WIDTH
Expand Down
4 changes: 1 addition & 3 deletions gtk/src/toga_gtk/widgets/divider.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@ def create(self):
self.native = Gtk.Separator()

def rehint(self):
width = self.native.get_preferred_width()
height = self.native.get_preferred_height()

width, height = self._get_preferred_size(self.native)
if self.get_direction() == self.interface.VERTICAL:
self.interface.intrinsic.width = width[0]
self.interface.intrinsic.height = at_least(height[1])
Expand Down
8 changes: 1 addition & 7 deletions gtk/src/toga_gtk/widgets/label.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,6 @@ def set_text(self, value):
self.native.set_text(value)

def rehint(self):
# print("REHINT", self,
# self.native.get_preferred_width(), self.native.get_preferred_height(),
# getattr(self, '_fixed_height', False), getattr(self, '_fixed_width', False)
# )
width = self.native.get_preferred_width()
height = self.native.get_preferred_height()

width, height = self._get_preferred_size(self.native)
self.interface.intrinsic.width = at_least(width[0])
self.interface.intrinsic.height = height[1]
4 changes: 1 addition & 3 deletions gtk/src/toga_gtk/widgets/numberinput.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,7 @@ def set_alignment(self, value):
self.native.set_alignment(xalign)

def rehint(self):
width = self.native.get_preferred_width()
height = self.native.get_preferred_height()

width, height = self._get_preferred_size(self.native)
self.interface.intrinsic.width = at_least(
max(self.interface._MIN_WIDTH, width[1])
)
Expand Down
5 changes: 1 addition & 4 deletions gtk/src/toga_gtk/widgets/progressbar.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,6 @@ def stop(self):
self._stop_indeterminate()

def rehint(self):
# print("REHINT", self, self.native.get_preferred_width(), self.native.get_preferred_height())
width = self.native.get_preferred_width()
height = self.native.get_preferred_height()

width, height = self._get_preferred_size(self.native)
self.interface.intrinsic.width = at_least(width[0])
self.interface.intrinsic.height = height[0]
3 changes: 1 addition & 2 deletions gtk/src/toga_gtk/widgets/selection.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,7 @@ def get_selected_index(self):
return index

def rehint(self):
width = self.native.get_preferred_width()
height = self.native.get_preferred_height()
width, height = self._get_preferred_size(self.native)

# FIXME: 2023-05-31 This will always provide a size that is big enough,
# but sometimes it will be *too* big. For example, if you set the font size
Expand Down
3 changes: 1 addition & 2 deletions gtk/src/toga_gtk/widgets/slider.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,7 @@ def get_tick_count(self):
return self.tick_count

def rehint(self):
# print("REHINT", self, self.native.get_preferred_width(), self.native.get_preferred_height())
height = self.native.get_preferred_height()
width, height = self._get_preferred_size(self.native)

# Set intrinsic width to at least the minimum width
self.interface.intrinsic.width = at_least(self.interface._MIN_WIDTH)
Expand Down
8 changes: 2 additions & 6 deletions gtk/src/toga_gtk/widgets/switch.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,8 @@ def set_font(self, font):
self.apply_css("font", get_font_css(font), native=self.native_label)

def rehint(self):
# print("REHINT", self, self.native.get_preferred_width(), self.native.get_preferred_height())
label_width = self.native_label.get_preferred_width()
label_height = self.native_label.get_preferred_height()

switch_width = self.native_switch.get_preferred_width()
switch_height = self.native_switch.get_preferred_height()
label_width, label_height = self._get_preferred_size(native=self.native_label)
switch_width, switch_height = self._get_preferred_size(native=self.native_label)

# Set intrinsic width to at least the minimum width
self.interface.intrinsic.width = at_least(
Expand Down
8 changes: 1 addition & 7 deletions gtk/src/toga_gtk/widgets/textinput.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,7 @@ def set_value(self, value):
self.native.set_text(value)

def rehint(self):
# print("REHINT", self,
# self._impl.get_preferred_width(), self._impl.get_preferred_height(),
# getattr(self, '_fixed_height', False), getattr(self, '_fixed_width', False)
# )
width = self.native.get_preferred_width()
height = self.native.get_preferred_height()

width, height = self._get_preferred_size(self.native)
self.interface.intrinsic.width = at_least(
max(self.interface._MIN_WIDTH, width[1])
)
Expand Down
5 changes: 4 additions & 1 deletion gtk/src/toga_gtk/window.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,10 @@ def set_app(self, app):
app.native.add_window(self.native)

def show(self):
self.native.show_all()
# Avoid calling show_all() as it change the visibility of all children.
self.native.show()
self.layout.show()
self.container.show()

######################################################################
# Window content and resources
Expand Down
Loading