The Trunk: System-mt.963.mcz

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

The Trunk: System-mt.963.mcz

commits-2
Marcel Taeumel uploaded a new version of System to project The Trunk:
http://source.squeak.org/trunk/System-mt.963.mcz

==================== Summary ====================

Name: System-mt.963
Author: mt
Time: 23 September 2017, 10:47:56.940596 am
UUID: d6e13c37-16d6-c34b-a3cf-64afaf4cfaba
Ancestors: System-tpr.962

Removes "scope" from UI themes. Encapsulates look-up for properties in the current theme into short-living a request object.

Why?
1. Dispels some magic from UserInterfaceTheme class.
2. Supports keeping reference to the result of "self userInterfaceTheme" without annoying the GC.
3. Speeds up look-up performance by up to 5%.

=============== Diff against System-tpr.962 ===============

Item was changed:
  ----- Method: Object>>userInterfaceTheme (in category '*System-Preferences') -----
  userInterfaceTheme
  "Call this to conveniently access properties from the current user interface theme."
 
+ ^ UserInterfaceThemeRequest new
+ target: self;
+ theme: UserInterfaceTheme current;
- ^ UserInterfaceTheme current
- pushScope: self;
  yourself!

Item was changed:
  Object subclass: #UserInterfaceTheme
+ instanceVariableNames: 'properties name next ignoreApply lastScaleFactor'
- instanceVariableNames: 'scope properties name next ignoreApply lastScaleFactor'
  classVariableNames: 'All Current Default'
  poolDictionaries: ''
  category: 'System-Support'!
 
  !UserInterfaceTheme commentStamp: '<historical>' prior: 0!
  A UserInterfaceTheme is a dictionary of preferred visual-properties; colors, borderStyles, borderWidths, fonts, forms, etc. used to color and style the IDE.
 
  Accessing The Theme
  To access the proper UserInterfaceTheme instance for an object, send it #userInterfaceTheme.  The default implementation on Object provides the one instance of that is in-use by the IDE at the current time.
 
  Customizing The Theme
  We can ask the userInterfaceTheme for the value of any visual-property, by name:
 
  mySystemWindow userInterfaceTheme closeBoxImage
 
  Initially, the above answers nil, which causes the legacy code to use whatever default it's always used.  To override various visual-properties of any kind of object, the #set: onAny: to: message can be used.  For example,
 
  myUserInterfaceTheme
  set: #closeBoxImage
  for: SystemWindow
  to: MenuIcons smallCancelIcon
 
  Alternatively, values may be derived based on other values in the theme, as in:
 
  myUserInterfaceTheme
  set: #color
  for: FillInTheBlankMorph
  to: { MenuMorph->#color.  #twiceDarker }
 
  Now, the accessing expression, above, will answer will answer MenuIcons' smallCancelIcon instead of nil.  SystemWindow's code can be changed to use the expression above to access elements of the theme.
 
  Upgrading Legacy Code
  Following the introduction of this class, various client code all around the system must be modified to access it.  This variety of legacy code uses a variety of methods to specify their visual properties:
 
  1) a hard-coded values.
  2) a values derived from some other value.
  3) providing local storage for a settable value which can be nil.
  4) providing local storage for a settable value which is expected to always have a particular valid value (never nil).
 
  The requirement, for each case, is to let the value be overridden.  
 
  The solution for each of the above should be handled respectively to the above list, as follows:
 
  1) Check the userInterfaceTheme, if that property returns nil, use the legacy hard-coded value.  (see example: SystemWindow>>#createCloseBox).
  2) Nothing to do -- simply perform the same derivation on the result of (1).
  3) Check the local storage, if present, use it.  If nil, then check the userInterfaceTheme, if it has this property present, use it, else return nil.
  4) Check the userInterfaceTheme, if the property is not nil, use it, otherwise use the local value.
 
  Tool Support
  If a new access to #userInterfaceTheme is added to the code, be sure to add the property and its description to the #themeSettings for that class.  See implementors of #themeSettings for examples.!

Item was removed:
- ----- Method: UserInterfaceTheme>>doesNotUnderstand: (in category 'lookup') -----
- doesNotUnderstand: aMessage
- "In order to be able to use a UserInterfaceTheme as a container of fairly arbitrary properties whilst making it seem like we are sending regular messages as a way of accessing those properties we can handle the dNU: and check the not understood message name against our property list. This is clever, devious, interesting and may confuse users until they get to see an explanation like this"
- "Answer nil or a value for the property specified by aMessage's #selector. Searching for the property proceeds by
- a) searching my dictionary for a key made up of an Association with a key of the class of the 'client' and a value of the message name. For example SimpleButtonMorph->borderColor
- b) searching again for a key made from the superclass(es) of the client - e.g. RectangleMorph->borderColor and then if required BorderedMorph->borderColor etc.
- c) if there is a linked theme, search it in the same manner.
-
- As an extreme example, consider a basic theme with a linked theme specifically for buttons.
- mySimpleButtonMorph borderColor
- would search the basic theme for SimpleButtonMorph->borderColor, the superclass equivalents as in b) above, then search the linked theme for SimpleButtonMorph->borderColor and, we hope, find something meaningful"
-
- aMessage numArgs > 0 ifTrue: [^ super doesNotUnderstand: aMessage].
- scope isEmpty ifTrue: [^ super doesNotUnderstand: aMessage].
-
- ^ [self get: scope top class -> aMessage selector]
- ensure: [scope pop]!

Item was changed:
  ----- Method: UserInterfaceTheme>>initialize (in category 'initialization') -----
  initialize
  super initialize.
  name := 'unnamed'.
+ properties := Dictionary new.!
- properties := Dictionary new.
- scope := Stack new!

Item was changed:
  ----- Method: UserInterfaceTheme>>postCopy (in category 'copying') -----
  postCopy
  "Keep same name and linked next."
  super postCopy.
+ properties := properties copy.!
- properties := properties copy.
- scope := nil!

Item was removed:
- ----- Method: UserInterfaceTheme>>pushScope: (in category 'private') -----
- pushScope: anObject
- scope push: anObject!

Item was added:
+ Object subclass: #UserInterfaceThemeRequest
+ instanceVariableNames: 'target theme'
+ classVariableNames: ''
+ poolDictionaries: ''
+ category: 'System-Support'!
+
+ !UserInterfaceThemeRequest commentStamp: 'mt 9/23/2017 10:37' prior: 0!
+ In order to be able to use a UserInterfaceTheme as a container of fairly arbitrary properties whilst making it seem like we are sending regular messages as a way of accessing those properties we can handle the dNU: and check the not understood message name against our property list. This is clever, devious, interesting and may confuse users until they get to see an explanation like this.
+
+ Answer nil or a value for the property specified by aMessage's #selector. Searching for the property proceeds by
+ a) searching my dictionary for a key made up of an Association with a key of the class of the 'client' and a value of the message name. For example SimpleButtonMorph->borderColor
+ b) searching again for a key made from the superclass(es) of the client - e.g. RectangleMorph->borderColor and then if required BorderedMorph->borderColor etc.
+ c) if there is a linked theme, search it in the same manner.
+
+ As an extreme example, consider a basic theme with a linked theme specifically for buttons.
+
+ mySimpleButtonMorph borderColor
+
+ ... would search the basic theme for SimpleButtonMorph->borderColor, the superclass equivalents as in b) above, then search the linked theme for SimpleButtonMorph->borderColor and, we hope, find something meaningful.!

Item was added:
+ ----- Method: UserInterfaceThemeRequest>>doesNotUnderstand: (in category 'lookup') -----
+ doesNotUnderstand: aMessage
+ "Look up the visual-attribute specified by aMessage's #selector in the current theme for the current target object."
+
+ ^ aMessage numArgs = 0
+ ifTrue: [self theme get: self target class -> aMessage selector]
+ ifFalse: [super doesNotUnderstand: aMessage]!

Item was added:
+ ----- Method: UserInterfaceThemeRequest>>target (in category 'accessing') -----
+ target
+
+ ^ target
+ !

Item was added:
+ ----- Method: UserInterfaceThemeRequest>>target: (in category 'accessing') -----
+ target: anObject
+
+ target := anObject.
+ !

Item was added:
+ ----- Method: UserInterfaceThemeRequest>>theme (in category 'accessing') -----
+ theme
+
+ ^ theme
+ !

Item was added:
+ ----- Method: UserInterfaceThemeRequest>>theme: (in category 'accessing') -----
+ theme: anObject
+
+ theme := anObject.
+ !