[squeak-dev] Re: [ANN] Widget Refactorings & UI Themes for Squeak

marcel.taeumel Marcel.Taeumel at hpi.de
Thu Jul 28 14:49:16 UTC 2016


cbc wrote
> Hi.
> 
> First, a warning for other using this sar - it applies updates before
> loading.  So, if you are on trunk, you will be updated to the latest
> trunk.  Mostly that should be ok.
> 
> Second, if you have a LOT of open windows, the image will appear to seize
> up briefly at one point during load.  It isn't frozen - it is just
> applying
> the theme to all open windows.  (I have 47 open windows - takes a bit of
> time).
> 
> Changing themes (with my 47 open windows) takes about 9 seconds.
> 
> Changing themes works - mostly.  It appears to just change the thematic
> elements that are visible at the time of theme changing.  What is mean is,
> if you have a window minimized, then the contents of that window will not
> change to the new theme, but will stay with the old theme (at least, the
> colors do).  This may not be an issue for folks with a reasonably small
> number of windows open, of course.
> 
> As a side effect, it is possible to mix themes this way.
> 
> I'll run with it today, and report any issues, although I doubt I'll see
> many more.
> 
> -cbc
> 
> On Thu, Jul 28, 2016 at 6:14 AM, marcel.taeumel <

> Marcel.Taeumel@

> >
> wrote:
> 
>> Hi, there! :-)
>>
>> TL;DR: Here is a SAR file that cleans up the code of all widget classes
>> such
>> as lists and buttons in your image and adds support for UI theming as
>> well
>> as a bunch of UI themes (choose Themes via "Extras > Themes & Colors"):
>> squeak_trunk_uitheme_v12.sar
>> <http://forum.world.st/file/n4908439/squeak_trunk_uitheme_v12.sar>
>>
>> Here is a preview:
>> http://i.giphy.com/l46CcX46yRE9H6yQ0.gif
>>
>> *Try it out. Report bugs. Report performance issues!!* We will commit the
>> changes to trunk this Saturday.
>>
>> Btw: The SAR installer is compatible with Eliot's current working image.
>> ;o)
>> And there are numerous open windows and projects in that image...^^
>>
>>
>> ==========================================
>> 0. The Long History of Squeak & UI Theming
>> ==========================================
>>
>> ...
>> http://forum.world.st/Dark-theme-td4869082.html
>> http://forum.world.st/Themes-for-Squeak-5-1-td4882848.html
>> http://forum.world.st/Skylark-Theme-and-Squeak-3-9-td54720.html
>>
>> http://forum.world.st/Non-SmallLand-colour-theme-lying-around-td4697438.html#a4697446
>> ...
>>
>>
>> ========================
>> 1. User Interface Themes
>> ========================
>>
>> Chris, Karl, and I designed a very lightweight abstraction to support UI
>> themes in Squeak. You can find the whole implementation in the class
>> UserInterfaceTheme and a bunch of tests in UserInterfaceThemeTests.
>>
>> An object that wants to support theming SHOULD (!) implement three
>> methods:
>>
>> MyFancyClass class >> #themeProperties
>> MyFancyClass >> #applyUserInterfaceTheme
>> MyFancyClass >> #canApplyUserInterfaceTheme
>>
>> It also MUST (!) access the current UI theme when setting visual state.
>> And
>> here comes the nice part:
>>
>> ...
>> self color: (self userInterfaceTheme color ifNil: [Color white]).
>> ...
>>
>> Remember, usually you would write something like this:
>>
>> ...
>> self color: Color white.
>> ...
>>
>> How can this work? It works by using #doesNotUnderstand: and trigger a
>> dynamic lookup in a dictionary inside the current theme:
>>
>> Object >> #userInterfaceTheme
>>         ^ UserInterfaceTheme current
>>                 pushScope: self;
>>                 yourself
>>
>> UserInterfaceTheme >> #doesNotUnderstand: aMessage
>>         ...
>>         ^ [self get: scope top class -> aMessage selector]
>>                 ensure: [scope pop]
>>
>> Isn't this slow? No, not at all. If you have any doubts, try benching it
>> on
>> your machine:
>>
>> UserInterfaceThemeTestObject benchLookup.
>>
>> On my machine, this is even fast enough to support theme lookups in
>> frequently called messages such as Morph >> #drawOn:. However,
>> applications
>> are advised to cache. That's why we have the explicit
>> #applyUserInterfaceTheme callbacks as described above.
>>
>> Note that amazing effects can be achieved by adjusting #color,
>> #borderColor,
>> #borderWidth, #fillStyle, and fonts. :-) The existing themes do exactly
>> that.
>>
>> To get a feeling of the impact of having themes in Squeak, try browsing
>> senders and implementors of #applyUserInterfaceTheme, #themeProperties,
>> #userInterfaceTheme, and maybe #canApplyUserInterfaceTheme. I think we
>> can
>> still reduce the number of sends to #userInterfaceTheme a little more.
>>
>>
>> ==================================
>> 2. Code clean-up in widget classes
>> ==================================
>>
>> We made Shout look up the current theme to build its internal cache of
>> text
>> attributes to quickly style code as you type it.
>>
>> We removed window color specifications and replaced them by simply
>> implementing Model >> #defaultWindowColor. There is also still the
>> #uniformWindowColor if you do not like colorful windows. This makes it
>> also
>> much easier for new applications to have their own window color.
>>
>> We unified the implementation of MenuMorph and DockingBarMorph and fixed
>> several bugs there.
>>
>> Dialogs! *phew* ... *arrrrgss* ... Dialogs. :-) We managed to introduce a
>> general DialogWindow class. FillInTheBlankMorph and UserDialogBoxMorph
>> are
>> now mere subclasses with a custom interface. There is also support for
>> ToolBuilder, see ListChooser for an example. *yay*
>>
>> Buttons feel more like buttons now. It's a good thing, right?
>>
>> For lists and trees and text boxes, we greatly reduced the amount of code
>> that just accessed global state. LazyListMorph, NewParagraph, TextMorph,
>> IndentingListItemMorph, ... they all now get configured by their "hosts",
>> which are PluggableListMorph, PluggableTextMorph, and
>> SimpleHierarchicalListMorph. Having this, we improved the modular
>> structure
>> of our whole Squeak widget library. That modular structure made applying
>> themes much easier. :-)
>>
>>
>> ========================
>> 3. Theme all the widgets
>> ========================
>>
>> There is a nice existing pattern with the message #setDefaultParameters,
>> which is usually called from #initialize. Go, see for yourself. Browse
>> implementors of #setDefaultParameters. We used that pattern and cleaned
>> up
>> many implementations of that message in the image.
>>
>> Note that rounded corners, gradients, colorful windows, and shadows are
>> still preferences outside of UI themes. You can toggle them in any UI
>> theme.
>>
>> Note that the background color/image is also not subject to be themed.
>> Just
>> drop your favorite picture or pattern in the image. It's really easy.
>>
>> Now, take a look at the class SqueakTheme. There, you will find source
>> code
>> for creating the default Squeak theme to be shared via SqueakSource and
>> reset during the release building process. :-)
>>
>> Besides get/set/clear -- which might be expected from the theme structure
>> because it is basically a dictionary with some properties -- There, you
>> will
>> notice a "merge" or "link" or "derive". When creating themes
>> programmatically, you can:
>>   - derive properties from other properties
>>   - link themes to extend property look-up
>>   - merge one theme into another theme
>>
>> How does property look-up work? Well, see UserInterfaceTheme >> #get:
>>   1. Look up the key, which is usually "Class -> symbol".
>>   2. Try the superclass chain.
>>   3. Try the same lookup in the linked theme if any.
>>
>> Theoretically, you could actually implement messages in subclasses of
>> UserInterfaceTheme and bypass that DNU-triggered lookup. We do not do
>> this
>> right now.
>>
>> As you can see, Squeak/Smalltalk offers a great deal of flexibility. It
>> is
>> remains subject to discussion of how to employ the language and its
>> semantics. Think of the current implementation of user interface themes
>> as
>> one way that represents a trade-off between a concise programming
>> interface
>> (i.e. ... self userInterfaceTheme color ifNil ...), a fair amount of
>> comprehensive patterns (i.e. #setDefaultParameters,
>> #applyUserInterfaceTheme, ...), and some other existing constraints (i.e.
>> old code, Monticello/Squeaksource, existing tools such as
>> senders/implementors, ...).
>>
>> Happy Squeaking!
>>
>> Marcel, Chris, Karl
>>
>>
>>
>> --
>> View this message in context:
>> http://forum.world.st/ANN-Widget-Refactorings-UI-Themes-for-Squeak-tp4908439.html
>> Sent from the Squeak - Dev mailing list archive at Nabble.com.
>>
>>

Thanks for this elaborate report. :-)

"Changing themes works - mostly.  It appears to just change the thematic
elements that are visible at the time of theme changing.  What is mean is,
if you have a window minimized, then the contents of that window will not
change to the new theme, but will stay with the old theme (at least, the
colors do).  This may not be an issue for folks with a reasonably small
number of windows open, of course."

There is a filter in Morph >> #canApplyUserInterfaceTheme, which checks
"self isInWorld". For collapsed window contents (text boxes etc.), that
returns false.

One could experiment with removing that check for a while. We think that we
might not want to change prototypical content or left-overs... Hmm... I
think we can fix this for Pluggable* widgets very easy by checking
#containingWindow.

Thanks!

Best,
Marcel



--
View this message in context: http://forum.world.st/ANN-Widget-Refactorings-UI-Themes-for-Squeak-tp4908439p4908467.html
Sent from the Squeak - Dev mailing list archive at Nabble.com.


More information about the Squeak-dev mailing list