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

marcel.taeumel Marcel.Taeumel at hpi.de
Thu Jul 28 14:53:58 UTC 2016


marcel.taeumel wrote
> 
> 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

Anyway, you can always re-apply a theme.

Best,
Marcel



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


More information about the Squeak-dev mailing list