toga icon indicating copy to clipboard operation
toga copied to clipboard

Android Table does not scroll horizontally

Open t-arn opened this issue 1 year ago • 11 comments

Describe the bug

Since the horizontal scrollview has been removed from the Android implementation of Table, it is not possible anymore to make the table scroll horizontally.

I tried to add the Table into a ScrollContainer, but the horizontal scrolling was still not working.

I then put the Table into a Box along with a very long Label. Then, the window did scroll horizontally, but I did not see more of the Table content than before. All the Table content to the right did not move into view.

	_scroller = toga.ScrollContainer(horizontal=True, vertical=False, style=Pack(flex=1))
	_scrolling_box = toga.Box(style=Pack(flex=1, direction=COLUMN))
	_scrolling_box.add(toga.Label("fdskjfdksfjdkls fjdks fjdklsfjdkls fjdklsfjdklsfjdsfjklds fjklds jfdkls fjklds fjdsfjfklsd fjs fkdsf dsjf dskl kfsd jdkls fjdsklf jdsklfjsfljlsk"))
	self._table = toga.Table(
		headings=[
			_("app.Table.name"),
			_("app.Table.systemApp"),
			_("app.Table.version"),
			_("app.Table.versionCode"),
			_("app.Table.location"),
			_("app.Table.packageName"),
		],
		accessors=["appName", "systemApp", "appVersion", "appVersionCode", "appLocation", "appPackageName"],
		missing_value="",
		style=Pack(flex=1, font_size=G.config["font_size"]),
	)
	_scrolling_box.add(self._table)
	_scrolling_box.add(toga.Label("fdskjfdksfjdkls fjdks fjdklsfjdkls fjdklsfjdklsfjdsfjklds fjklds jfdkls fjklds fjdsfjfklsd fjs fdks fjkdls jfdkls fjdkls fjdkls fjdkls fjds fj"))
	_scroller.content = _scrolling_box
	self.main_box.add(_scroller)

Steps to reproduce

  1. add a Table to a ScrollContainer with horizontal=True
  2. add a lot of colums, so the Table content becomes wider than the screen width
  3. try to scroll horizontally

Expected behavior

It is possbile to scroll the Table content horizontally

Screenshots

image

image

image

image

Environment

  • Operating System: Android 13
  • Python version: 3.9
  • Software versions:
    • Briefcase: 0.3.15
    • toga: 0.3.2.dev1367+g9021f9106

Logs


Additional context

No response

t-arn avatar Nov 03 '23 14:11 t-arn

@freakboy3742 I read your ideas for re-implementing Table for mobile devices (https://github.com/beeware/toga/issues/1392)

Sounds very good to me. The question is how soon this could be done. If this still takes a while, I could in the meanwhile do a PR to re-add the horizontal scrollview in the Android implemention again.

t-arn avatar Nov 03 '23 20:11 t-arn

@t-arn So... it will take until someone implements it :-)

I can't give a concrete timeline, other than to say that it's not currently on our schedule for this calendar year. However, it is high on my personal todo list, mostly because Tree and Table are two high-profile widgets that don't exist at all on iOS, and are limited on Android at present. I can't make a firm commitment at this time, but I wouldn't be surprised if we look at this in the first half of next year.

freakboy3742 avatar Nov 05 '23 00:11 freakboy3742

@freakboy3742 When you define a width for the table (for example style=Pack(flex=1, width=3000), then the horizontal scrolling works and all the table content is shown. The only problem is that it stretches the colums proportionally, so that they are too wide now.

So, the underlying problem seems to be that the current width of the table cannot be evaluated by the Pack mechanism. How does Pack evaluate the width of a Widget?

t-arn avatar Nov 15 '23 09:11 t-arn

hmm....self.interface.intrinsic.width is nowhere set in the Android implementation of Table. Is this the source of the problem?

t-arn avatar Nov 15 '23 09:11 t-arn

Probably not, because we recently added some code to base.py to set a default intrinsic width and height, so widgets only need to override that if they have more specific dimensions.

I think there are some differences between the platforms in how the column widths are adjusted, but they all behave reasonably well (at least for the simple cases covered by the testbed), so it wasn't necessary to fix during the audit.

mhsmith avatar Nov 15 '23 09:11 mhsmith

strange: my_table.intrinsic.width returns at least 100

t-arn avatar Nov 15 '23 11:11 t-arn

I added following rehint method:

    def rehint(self):
        self.native.measure(
            View.MeasureSpec.UNSPECIFIED,
            View.MeasureSpec.UNSPECIFIED,
        )
        self.interface.intrinsic.width = self.scale_out(
            at_least(self.native.getMeasuredWidth()), ROUND_UP
        )
        self.interface.intrinsic.height = self.scale_out(
            self.native.getMeasuredHeight(), ROUND_UP
        )

Now, the table scrolls horizontally and reports a resonable width of at least 670, but only the headers are shown. Somehow, the table data gets lost

t-arn avatar Nov 15 '23 12:11 t-arn

ok, my_table.intrinsic.height now is 26 which is why no data is shown.

t-arn avatar Nov 15 '23 12:11 t-arn

With this rehint method, all table data is shown, but the columns are wider than necessary:

    def rehint(self):
        self.native.measure(
            View.MeasureSpec.UNSPECIFIED,
            View.MeasureSpec.UNSPECIFIED,
        )
        self.interface.intrinsic.width = at_least(self.native.getMeasuredWidth())

my_table.intrinsic.width now is 1757 which is probably too much. But if I set CSS pixels (with scale_out), the table does not scroll far enough horizontally and not all data is shown. In other widgets, for example Button we use scale_out, so why doesn't this work for Table as well??

t-arn avatar Nov 15 '23 12:11 t-arn

Are there any news on this bug?

t-arn avatar Jan 11 '24 07:01 t-arn

Not as far as I know.

mhsmith avatar Jan 11 '24 07:01 mhsmith