A new version of ToolBuilder-Morphic was added to project The Inbox:
==================== Summary ====================
Time: 8 January 2021, 11:27:47.8204 am
Set the initial extent of the ListChooser to not require resizing the dialog for reasonable sized lists (i.e., expand it so you can see all of the list).
At the small end, still object MT's suggested size; at the large end, will not take up more the 3/4ths of the world size.
=============== Diff against ToolBuilder-Morphic-mt.269 ===============
Item was changed:
----- Method: ListChooser>>initialExtent (in category 'building') -----
+ | listFont width height |
- | listFont |
listFont := Preferences standardListFont.
+ width := (items collect: [:item| listFont widthOfString: item]) max + 20 "Acutal size of items plus dialog buffer left/right"
+ max: (20 * (listFont widthOf: $m)). "but we want a not-too-small box as well"
+ height := ((items size max: 15) * listFont height) + 40. "for various other stuff in dialog above/below list"
+ "But, don't use the whole world."
+ width := width min: (self currentWorld extent x * 0.75) asInteger.
+ height := height min: (self currentWorld extent y * 0.75) asInteger.
+ ^ width@height!
- ^ (20 * (listFont widthOf: $m))@(15 * listFont height)!
From my experience with the codebase in Squeak 3 and 4, any magic buffers such as "20" and "40" should be avoided for the sake of HI-DPI and hard-to-debug UI glitches. Deriving such buffers from the current font metrics seems to be more robust. Note that, in general, I am not opposed to giving content "more space to breathe" :-)
Having to iterate over all items in a list is too costly for larger lists. The LazyListMorph attempt to only consider a sample proved to entail annoying UI glitches such as shaky UI elements while scrolling.
Here are some numbers:
font := TextStyle defaultFont.
items := SystemNavigation default allClasses collect: [:class | class name].
[items do: [:item | font widthOfString: item]] bench.
'718 per second. 1.39 milliseconds per run. 0 % GC time.'
[(20 * (font widthOf: $m))@(15 * font height)] bench.
'22,000,000 per second. 45.4 nanoseconds per run. 2.47901 % GC time.'
Having milliseconds for a simple thing such as #initialExtent is really an issue for snappy GUIs because, for example, there are only 25 milliseconds for a frame in 40 FPS.
All in all, you are oppsed to always make room for 15 items and (roughly) 20 characters per item. So, I suggest that we could make the 15 derived from the actual number of items ... plus 1-2 if you want to leave more whitespace. For the 20, I would suggest to only count the number of characters and multiply with that width-of-$m. For performance reasons:
[items inject: 0 into: [:max :item | max max: item size]] bench.
'30,200 per second. 33.1 microseconds per run. 0.05999 % GC time.'
Yes, we could watch out for the size of #currentWorld, as you suggested. But this already happens via RealEstateAgent class >> maximumUsableAreaInWorld: as well as sends of #translatedToBeWithin: to a world's bounds. No need to duplicate and scatter those constraints all over the code base. :-) ... That said ... I think there is a bug in DialogWindow >> #moveToPreferredPosition and also in its initial extent. DialogWindow does not talk to RealEstateAgent at all ...
P.S.: How can you know that "item" is something that works with #widthOfString:? :-) Could be an instance of Text, for example.
Still, it makes me wonder if you ever you "list filtering" in such dialogs? You seem to want to optimize the users browsing experience, not the searching experience.
Hi Chris --
In "ToolBuilder-Morphic-mt.270", I tweaked a dialog's minimal size for smaller lists and added an expand button so that you can see more at once. I am aware that this is just a compromise to your proposed changes. Can you work with that? :-)
And I just realized that you did not propose a "breathing space" but just estimated the dialogs decorations around the central pane. My bad. Well, there is now extra space to breathe. We might remove that as well.
In reply to this post by marcel.taeumel
Actually, this even helps with filtering. If I have large items (which I often do), and I don't know the exact combination of characters for what I want to choose, it can be frustrating with the default size. Try:
ListChooser chooseFrom: #(
'A Really Big Option With Useful Stuff after: here, option Alpha'
'A Really Big Option With Useful Stuff after: here, option Beta'
'A Really Big Option With Useful Stuff after: here, option Gamma'
'Not what we want'
and filter by, say 'Stuff'. Which one do you pick?
Further, the grippies on this dialog are frustrating. If the dialog is near the bottom right of the screen, just dragging the top left (or bottom left) to make the dialog bigger to be able to see the rest of the text doesn't work. The dialog only expands down and to the right - no matter which grippy you try to expand (or shrink) the dialog with. So, I have to make it bigger, then move the dialog. If you need to do this often enough, I at least get frustrated.
The buffer size I am talking about here isn't for more white space around the list, but for the size of the dialog that is outside of the list. InitialExtent is for the complete dialog size, not just the list box. So, you will never be able to see 15 lines in the previous version because of the other space taken up by buttons and filter box. (Which is ok if the lists choices are small in few in number, of course.)
That said, you are right about HI-DPI and possible other font choices and/or future changes to ListChooser - I should derive the value and not hard code it.
<snip good stuff>
Yes, agreed (and much better). Except extra space should not be based on the list items/count, but on the other Dialog stuff.
I'll try removing my #currentWorld and see what happens with a really REALLY large list. I did notice that it will not open the dialog with any of it off the screen by default - but didn't try with an extent larger than the world. So, at least that part is somehow handled. (But not the growth of the dialog by grippies, unfortunately).
err, yeah. I always use stuff that knows #widthOfString, but that's just me. Will go with using size and width of $m.
Thanks for the explanations. I will address your concerns. Also see my response to cbc.271 :-)
In reply to this post by cbc
> InitialExtent is for the complete dialog size, not just the list box.
For clarification: #initialExtent is for the dialog's contents only. The model should not have to deal with dialog decorations such as title bar or button bar or other borders. See ListChooser >> #buildWith: for more information.
DialogWindow is the attempt to bring all the many scenarios around dialogs from the past 25 years together to make them somewhat manageable:
The button wrapping in the last example is still buggy in HiDPI/Demo mode. :-/
|Free forum by Nabble||Edit this page|