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