# HG changeset patch # User ca # Date 888416958 -3600 # Node ID c0fab03dd225c6f404e7a08ed779f9f4ae14f4da # Parent 175a6578eb8154ade41dc40b1ca7338074c08ab6 access mechanism for aspects diff -r 175a6578eb81 -r c0fab03dd225 UIBuilder.st --- a/UIBuilder.st Sat Feb 21 15:32:35 1998 +0100 +++ b/UIBuilder.st Wed Feb 25 15:29:18 1998 +0100 @@ -144,42 +144,6 @@ isEditing := aState ! -menuAt:aKey - "Find a binding for the menu named aKey, either in the bindings - or from the source" - - | menu | - - menu := self bindingAt:aKey. - menu isNil ifTrue:[ - menu := self safelyPerform:#menuFor: with:aKey. - menu isNil ifTrue:[ - menu := self safelyPerform:aKey - ]. - menu := menu value. - - (application notNil and:[menu notNil]) ifTrue:[ - menu isArray ifTrue:[ - menu := Menu new fromLiteralArrayEncoding:menu. - menu receiver:application. - ^ menu - ]. - menu findGuiResourcesIn:application - ] - ]. - ^ menu - - "Modified: / 30.10.1997 / 20:37:14 / cg" -! - -menuAt:aSymbol put:someMenuOrHolder - "add someMenuOrHolder as the binding for the menu named aSymbol to the bindings" - - ^ self aspectAt:aSymbol put:someMenuOrHolder - - "Modified: / 30.10.1997 / 20:32:51 / cg" -! - menuBar "return the value of the instance variable 'menuBar' (automatically generated)" @@ -383,6 +347,6 @@ !UIBuilder class methodsFor:'documentation'! version - ^ '$Header: /cvs/stx/stx/libview2/UIBuilder.st,v 1.32 1998-02-05 12:49:55 stefan Exp $' + ^ '$Header: /cvs/stx/stx/libview2/UIBuilder.st,v 1.33 1998-02-25 14:29:18 ca Exp $' ! ! UIBuilder initialize! diff -r 175a6578eb81 -r c0fab03dd225 WinBuilder.st --- a/WinBuilder.st Sat Feb 21 15:32:35 1998 +0100 +++ b/WinBuilder.st Wed Feb 25 15:29:18 1998 +0100 @@ -39,7 +39,16 @@ " a no-op class, for systems which do not use the UIBuilder. Concrete subclasses know how to create a view (with components) from - some interface spec. + some interface spec. + + The order of the lookup sequence to access an aspect is defined: + application + application class + additional class (applicationClass). + + Methods to access any aspect are located in the category + 'spec creation aspect fetch'. + Currently, an experimantal version of UIBuilder exists, and more may be added in the future (for example, to parse different UI specs - thinking of motifs UIL specs, Windows DialogSpecs etc.). @@ -156,6 +165,8 @@ applicationClass := something.! aspectAt:aSymbol + "return the aspect for a symbol or nil. + " |b| aSymbol notNil ifTrue:[ @@ -179,16 +190,15 @@ ] do:[ ^ application class aspectFor:aSymbol ]. - Transcript showCR:'WindowBuilder: no aspect for ' , aSymbol storeString. - StopOnError == true ifTrue:[self halt]. "/ avoids debugger in end-user apps - ]. + self aspectNotFound:aSymbol error:'no aspect for:' + ] ]. ^ nil - - "Modified: / 29.10.1997 / 17:26:16 / cg" ! aspectAt:aSymbol put:aModel + "store an aspect identified by its symbol and its value + " bindings isNil ifTrue:[ bindings := IdentityDictionary new ]. @@ -198,6 +208,8 @@ ! bindingAt:aSymbol + "return the binding for a symbol or nil + " bindings notNil ifTrue:[ ^ bindings at:aSymbol ifAbsent:nil. ]. @@ -205,19 +217,27 @@ ! bindings + "return my bindings + " ^ bindings ! bindings:aDictionary + "set bindings to a dictionary + " bindings := aDictionary ! componentAt:name + "return a component identified by its name. + " namedComponents isNil ifTrue:[^ nil]. ^ namedComponents at:name asSymbol ifAbsent:nil ! componentAt:name put:aComponent + "store a component identified by its name. + " namedComponents isNil ifTrue:[ namedComponents := IdentityDictionary new. ]. @@ -230,10 +250,14 @@ componentCreationHook := something.! focusSequence + "return my focus sequence + " ^ focusSequence ! helpKeyFor:aComponent + "return the helpkey for a component or nil + " |v key| helpKeys isNil ifTrue:[^ nil]. @@ -248,7 +272,9 @@ ! helpKeyFor:aComponent put:aKey - + "assign a key for a component which is used to access the help text + from the application. + " aKey isNil ifTrue:[ helpKeys isNil ifFalse:[ helpKeys removeKey:aComponent ifAbsent:nil @@ -263,6 +289,8 @@ ! keyboardProcessor + "return my keyboard processor + " keyboardProcessor isNil ifTrue:[ keyboardProcessor := KeyboardProcessor new ]. @@ -272,7 +300,25 @@ "Modified: 3.3.1997 / 18:32:27 / cg" ! +menuAt:aKey + "Find a binding for the menu named aKey, either in the bindings + or from the source" + + ^ self menuFor:aKey + + +! + +menuAt:aSymbol put:someMenuOrHolder + "add someMenuOrHolder as the binding for the menu named aSymbol to the bindings" + + ^ self aspectAt:aSymbol put:someMenuOrHolder + +! + namedComponents + "return list of named components + " ^ namedComponents ! @@ -316,47 +362,29 @@ ]. majorKey isNil ifTrue:[ - spec := self specificationFor:minorKey. - "/ try if application or applicationClass respond to minorKey - "/ (possible if not a subclass of ApplicationModel) - spec isNil ifTrue:[ - application messageNotUnderstoodSignal handle:[:ex | - ex proceed. - ] do:[ - application notNil ifTrue:[ - spec := application perform:minorKey. - ]. - (spec isNil and:[applicationClass notNil]) ifTrue:[ - spec := applicationClass perform:minorKey. - ]. - ]. - ]. + ^ self specificationFor:minorKey + ]. + + application notNil ifTrue:[ + "/ look for class in applications namespace ... + cls := application resolveName:majorKey. ] ifFalse:[ - application notNil ifTrue:[ - "/ look for class in applications namespace ... - cls := application resolveName:majorKey. - ] ifFalse:[ - "/ fallBack - use that global, if it exists - cls := Smalltalk at:majorKey. - cls isNil ifTrue:[ - Transcript showCR:('WindowBuilder[warning]: missing application when fetching majorKey:' , majorKey). - ]. + "/ fallBack - use that global, if it exists + cls := Smalltalk at:majorKey. + cls isNil ifTrue:[ + Transcript showCR:('WindowBuilder[warning]: missing application when fetching majorKey:' , majorKey). ]. - cls notNil ifTrue:[ - Object messageNotUnderstoodSignal handle:[:ex | - ex proceed. - ] do:[ - spec := cls specificationFor:minorKey. - spec isNil ifTrue:[ - spec := cls perform:minorKey. - ]. - ]. - ]. ]. - ^ spec - "Modified: / 27.1.1998 / 12:17:13 / cg" - "Modified: / 6.2.1998 / 12:31:45 / stefan" + cls notNil ifTrue:[ + Object messageNotUnderstoodSignal handle:[:ex|] do:[ + ^ cls specificationFor:minorKey + ]. + Object messageNotUnderstoodSignal handle:[:ex|] do:[ + ^ cls perform:minorKey. + ] + ]. + ^ nil ! subCanvasAt:majorKey at:minorKey put:aSpec @@ -496,56 +524,100 @@ "Modified: / 31.10.1997 / 18:39:30 / cg" ! ! +!WindowBuilder methodsFor:'error handling'! + +aspectNotFound:anAspect error:aString + "show error message on transcript + " + Transcript showCR:'WindowBuilder: ' + , aString + , ' aspect: <' + , anAspect storeString + , '>'. + + StopOnError == true ifTrue:[ + self halt "/ avoids debugger in end-user apps + ]. +! ! + !WindowBuilder methodsFor:'message sending'! -safelyPerform:aSelector +safelyPerform:aSelector ifNone:aBlock "send the message aSelector to the application; the result returned from the send or nil is returned " - |res| + |cls| - aSelector isSymbol ifTrue:[ + aSelector notNil ifTrue:[ application notNil ifTrue:[ - application messageNotUnderstoodSignal handle:[:ex | - ] do:[ - (res := application perform:aSelector) notNil ifTrue:[^ res] + application messageNotUnderstoodSignal handle:[:ex|] do:[ + ^ application perform:aSelector + ]. + cls := application class. + + cls messageNotUnderstoodSignal handle:[:ex|] do:[ + ^ cls perform:aSelector ] ]. applicationClass notNil ifTrue:[ - applicationClass messageNotUnderstoodSignal handle:[:ex | - ] do:[ - (res := applicationClass perform:aSelector) notNil ifTrue:[^ res] + applicationClass messageNotUnderstoodSignal handle:[:ex|] do:[ + ^ applicationClass perform:aSelector ] ] ]. - ^ nil - - "Modified: / 5.2.1998 / 12:28:23 / stefan" + ^ aBlock value ! -safelyPerform:aSelector with:anArgument +safelyPerform:aSelector with:anArgument ifNone:aBlock "send the one-arg-message aSelector to the application; the result returned from the send or nil is returned " - |res| + |cls| - aSelector isSymbol ifTrue:[ + aSelector notNil ifTrue:[ application notNil ifTrue:[ - application messageNotUnderstoodSignal handle:[:ex | - ] do:[ - (res := application perform:aSelector with:anArgument) notNil ifTrue:[^ res] + application messageNotUnderstoodSignal handle:[:ex|] do:[ + ^ application perform:aSelector with:anArgument + ]. + cls := application class. + + cls messageNotUnderstoodSignal handle:[:ex|] do:[ + ^ cls perform:aSelector with:anArgument ] ]. applicationClass notNil ifTrue:[ - applicationClass messageNotUnderstoodSignal handle:[:ex | - ] do:[ - (res := applicationClass perform:aSelector with:anArgument) notNil ifTrue:[^ res] + applicationClass messageNotUnderstoodSignal handle:[:ex|] do:[ + ^ applicationClass perform:aSelector with:anArgument + ]. + ] + ]. + ^ aBlock value +! + +safelyPerform:aSelector with:arg1 with:arg2 ifNone:aBlock + "send the two-arg-message aSelector to the application; + the result returned from the send or nil is returned + " + |cls| + + aSelector notNil ifTrue:[ + application notNil ifTrue:[ + application messageNotUnderstoodSignal handle:[:ex|] do:[ + ^ application perform:aSelector with:arg1 with:arg2 + ]. + cls := application class. + + cls messageNotUnderstoodSignal handle:[:ex|] do:[ + ^ cls perform:aSelector with:arg1 with:arg2 ] ]. + applicationClass notNil ifTrue:[ + applicationClass messageNotUnderstoodSignal handle:[:ex|] do:[ + ^ applicationClass perform:aSelector with:arg1 with:arg2 + ]. + ] ]. - ^ nil - - "Modified: / 5.2.1998 / 12:28:54 / stefan" + ^ aBlock value ! ! !WindowBuilder methodsFor:'spec creation aspect fetch'! @@ -564,25 +636,9 @@ b notNil ifTrue:[^ b]. ]. - application notNil ifTrue:[ - Object messageNotUnderstoodSignal handle:[:ex | - ] do:[ - ^ application actionFor:aKey - ] - ]. - applicationClass notNil ifTrue:[ - (applicationClass respondsTo:#actionFor:) ifTrue:[ - ^ applicationClass actionFor:aKey - ] - ]. - - Transcript showCR:'WindowBuilder: no action for: ' , aKey storeString. - StopOnError == true ifTrue:[self halt]. "/ avoids debugger in end-user apps - - ^ [] - - "Created: / 17.1.1997 / 21:08:22 / cg" - "Modified: / 28.10.1997 / 12:52:57 / cg" + ^ self safelyPerform:#actionFor: + with:aKey + ifNone:[ self aspectNotFound:aKey error:'no action for:'. [] ] ! actionFor:aKey withValue:aValue @@ -601,25 +657,10 @@ b notNil ifTrue:[^ b]. ]. - application notNil ifTrue:[ - Object messageNotUnderstoodSignal handle:[:ex | - ] do:[ - ^ application actionFor:aKey withValue:aValue - ] - ]. - applicationClass notNil ifTrue:[ - (applicationClass respondsTo:#actionFor:withValue:) ifTrue:[ - ^ applicationClass actionFor:aKey withValue:aValue - ] - ]. - - Transcript showCR:'WindowBuilder: no action for: ' , aKey storeString. - StopOnError == true ifTrue:[self halt]. "/ avoids debugger in end-user apps - - ^ [:dummy | ] - - "Created: / 17.1.1997 / 21:08:22 / cg" - "Modified: / 28.10.1997 / 12:53:22 / cg" + ^ self safelyPerform:#actionFor:withValue: + with:aKey + with:aValue + ifNone:[ self aspectNotFound:aKey error:'no action for:'. [:dummy |] ] ! aspectFor:aKey @@ -636,23 +677,9 @@ b notNil ifTrue:[^ b]. ]. - application notNil ifTrue:[ - Object messageNotUnderstoodSignal handle:[:ex | - ] do:[ - ^ application aspectFor:aKey - ] - ]. - applicationClass notNil ifTrue:[ - Object messageNotUnderstoodSignal handle:[:ex | - ] do:[ - ^ applicationClass aspectFor:aKey - ] - ]. - - ^ self aspectAt:aKey - - "Created: / 17.1.1997 / 21:06:16 / cg" - "Modified: / 1.11.1997 / 13:40:24 / cg" + ^ self safelyPerform:#aspectFor: + with:aKey + ifNone:[ self aspectAt:aKey ] ! componentFor:aKey @@ -662,20 +689,9 @@ finally the applications class is asked for a corresponding action. The returned object is typically a view." - |component| - - application notNil ifTrue:[ - component := application componentFor:aKey. - component notNil ifTrue:[^ component]. - ]. - applicationClass notNil ifTrue:[ - (applicationClass respondsTo:#componentFor:) ifTrue:[ - ^ applicationClass componentFor:aKey - ] - ]. - ^ self aspectAt:aKey - - "Modified: 20.6.1997 / 11:40:22 / cg" + ^ self safelyPerform:#componentFor: + with:aKey + ifNone:[ self aspectAt:aKey ] ! labelFor:aKey @@ -685,24 +701,9 @@ finally the applications class is asked for a corresponding action. The returned object is typically a string." - application notNil ifTrue:[ - Object messageNotUnderstoodSignal handle:[:ex | - ] do:[ - ^ application labelFor:aKey - ] - ]. - applicationClass notNil ifTrue:[ - (applicationClass respondsTo:#labelFor:) ifTrue:[ - ^ applicationClass labelFor:aKey - ] - ]. - -"/ Transcript showCR:'WindowBuilder: no label for: ' , aKey storeString. -"/ StopOnError == true ifTrue:[self halt]. "/ avoids debugger in end-user apps - - ^ self aspectAt:aKey - - "Modified: / 28.10.1997 / 12:54:10 / cg" + ^ self safelyPerform:#labelFor: + with:aKey + ifNone:[ self aspectAt:aKey ] ! listFor:aKey @@ -712,25 +713,39 @@ finally the applications class is asked for a corresponding action. The returned object is typically a list." - application notNil ifTrue:[ - Object messageNotUnderstoodSignal handle:[:ex | - ] do:[ - ^ application listFor:aKey + ^ self safelyPerform:#listFor: + with:aKey + ifNone:[ self aspectAt:aKey ] +! + +menuFor:aKey + "Find a binding for the menu named aKey, either in the bindings + or from the source" + + |menu| + + (menu := self bindingAt:aKey) notNil ifTrue:[ + ^ menu + ]. + + menu := self safelyPerform:#menuFor: with:aKey ifNone:[ + self safelyPerform:aKey ifNone:[ + self aspectNotFound:aKey error:'no menu for:'. + nil + ] + ]. + + ((menu := menu value) notNil and:[application notNil]) ifTrue:[ + menu isArray ifTrue:[ + menu := Menu new fromLiteralArrayEncoding:menu. + menu receiver:application. + ] ifFalse:[ + menu findGuiResourcesIn:application ] ]. - applicationClass notNil ifTrue:[ - (applicationClass respondsTo:#listFor:) ifTrue:[ - ^ applicationClass listFor:aKey - ] - ]. + ^ menu -"/ Transcript showCR:'WindowBuilder: no list for: ' , aKey storeString. -"/ StopOnError == true ifTrue:[self halt]. "/ avoids debugger in end-user apps - ^ self aspectAt:aKey - - "Created: / 17.1.1997 / 21:08:45 / cg" - "Modified: / 28.10.1997 / 12:54:32 / cg" ! specificationFor:aKey @@ -740,29 +755,9 @@ finally the applications class is asked for a corresponding interfaceSPec. The returned object is typically an interfaceSpec array." - |spec| - - application notNil ifTrue:[ - application messageNotUnderstoodSignal handle:[:ex | - ] do:[ - spec := application specificationFor:aKey. - ]. - spec notNil ifTrue:[^ spec]. - ]. - applicationClass notNil ifTrue:[ - (applicationClass respondsTo:#specificationFor:) ifTrue:[ - application messageNotUnderstoodSignal handle:[:ex | - ] do:[ - spec := applicationClass specificationFor:aKey - ]. - spec notNil ifTrue:[^ spec]. - ] - ]. - ^ self aspectAt:aKey - - "Modified: / 20.6.1997 / 11:40:22 / cg" - "Created: / 5.2.1998 / 10:47:46 / stefan" - "Modified: / 5.2.1998 / 12:25:08 / stefan" + ^ self safelyPerform:#specificationFor: + with:aKey + ifNone:[ self aspectFor:aKey ] ! ! !WindowBuilder methodsFor:'spec creation callbacks'! @@ -983,5 +978,5 @@ !WindowBuilder class methodsFor:'documentation'! version - ^ '$Header: /cvs/stx/stx/libview2/Attic/WinBuilder.st,v 1.59 1998-02-13 13:53:14 ca Exp $' + ^ '$Header: /cvs/stx/stx/libview2/Attic/WinBuilder.st,v 1.60 1998-02-25 14:28:55 ca Exp $' ! ! diff -r 175a6578eb81 -r c0fab03dd225 WindowBuilder.st --- a/WindowBuilder.st Sat Feb 21 15:32:35 1998 +0100 +++ b/WindowBuilder.st Wed Feb 25 15:29:18 1998 +0100 @@ -39,7 +39,16 @@ " a no-op class, for systems which do not use the UIBuilder. Concrete subclasses know how to create a view (with components) from - some interface spec. + some interface spec. + + The order of the lookup sequence to access an aspect is defined: + application + application class + additional class (applicationClass). + + Methods to access any aspect are located in the category + 'spec creation aspect fetch'. + Currently, an experimantal version of UIBuilder exists, and more may be added in the future (for example, to parse different UI specs - thinking of motifs UIL specs, Windows DialogSpecs etc.). @@ -156,6 +165,8 @@ applicationClass := something.! aspectAt:aSymbol + "return the aspect for a symbol or nil. + " |b| aSymbol notNil ifTrue:[ @@ -179,16 +190,15 @@ ] do:[ ^ application class aspectFor:aSymbol ]. - Transcript showCR:'WindowBuilder: no aspect for ' , aSymbol storeString. - StopOnError == true ifTrue:[self halt]. "/ avoids debugger in end-user apps - ]. + self aspectNotFound:aSymbol error:'no aspect for:' + ] ]. ^ nil - - "Modified: / 29.10.1997 / 17:26:16 / cg" ! aspectAt:aSymbol put:aModel + "store an aspect identified by its symbol and its value + " bindings isNil ifTrue:[ bindings := IdentityDictionary new ]. @@ -198,6 +208,8 @@ ! bindingAt:aSymbol + "return the binding for a symbol or nil + " bindings notNil ifTrue:[ ^ bindings at:aSymbol ifAbsent:nil. ]. @@ -205,19 +217,27 @@ ! bindings + "return my bindings + " ^ bindings ! bindings:aDictionary + "set bindings to a dictionary + " bindings := aDictionary ! componentAt:name + "return a component identified by its name. + " namedComponents isNil ifTrue:[^ nil]. ^ namedComponents at:name asSymbol ifAbsent:nil ! componentAt:name put:aComponent + "store a component identified by its name. + " namedComponents isNil ifTrue:[ namedComponents := IdentityDictionary new. ]. @@ -230,10 +250,14 @@ componentCreationHook := something.! focusSequence + "return my focus sequence + " ^ focusSequence ! helpKeyFor:aComponent + "return the helpkey for a component or nil + " |v key| helpKeys isNil ifTrue:[^ nil]. @@ -248,7 +272,9 @@ ! helpKeyFor:aComponent put:aKey - + "assign a key for a component which is used to access the help text + from the application. + " aKey isNil ifTrue:[ helpKeys isNil ifFalse:[ helpKeys removeKey:aComponent ifAbsent:nil @@ -263,6 +289,8 @@ ! keyboardProcessor + "return my keyboard processor + " keyboardProcessor isNil ifTrue:[ keyboardProcessor := KeyboardProcessor new ]. @@ -272,7 +300,25 @@ "Modified: 3.3.1997 / 18:32:27 / cg" ! +menuAt:aKey + "Find a binding for the menu named aKey, either in the bindings + or from the source" + + ^ self menuFor:aKey + + +! + +menuAt:aSymbol put:someMenuOrHolder + "add someMenuOrHolder as the binding for the menu named aSymbol to the bindings" + + ^ self aspectAt:aSymbol put:someMenuOrHolder + +! + namedComponents + "return list of named components + " ^ namedComponents ! @@ -316,47 +362,29 @@ ]. majorKey isNil ifTrue:[ - spec := self specificationFor:minorKey. - "/ try if application or applicationClass respond to minorKey - "/ (possible if not a subclass of ApplicationModel) - spec isNil ifTrue:[ - application messageNotUnderstoodSignal handle:[:ex | - ex proceed. - ] do:[ - application notNil ifTrue:[ - spec := application perform:minorKey. - ]. - (spec isNil and:[applicationClass notNil]) ifTrue:[ - spec := applicationClass perform:minorKey. - ]. - ]. - ]. + ^ self specificationFor:minorKey + ]. + + application notNil ifTrue:[ + "/ look for class in applications namespace ... + cls := application resolveName:majorKey. ] ifFalse:[ - application notNil ifTrue:[ - "/ look for class in applications namespace ... - cls := application resolveName:majorKey. - ] ifFalse:[ - "/ fallBack - use that global, if it exists - cls := Smalltalk at:majorKey. - cls isNil ifTrue:[ - Transcript showCR:('WindowBuilder[warning]: missing application when fetching majorKey:' , majorKey). - ]. + "/ fallBack - use that global, if it exists + cls := Smalltalk at:majorKey. + cls isNil ifTrue:[ + Transcript showCR:('WindowBuilder[warning]: missing application when fetching majorKey:' , majorKey). ]. - cls notNil ifTrue:[ - Object messageNotUnderstoodSignal handle:[:ex | - ex proceed. - ] do:[ - spec := cls specificationFor:minorKey. - spec isNil ifTrue:[ - spec := cls perform:minorKey. - ]. - ]. - ]. ]. - ^ spec - "Modified: / 27.1.1998 / 12:17:13 / cg" - "Modified: / 6.2.1998 / 12:31:45 / stefan" + cls notNil ifTrue:[ + Object messageNotUnderstoodSignal handle:[:ex|] do:[ + ^ cls specificationFor:minorKey + ]. + Object messageNotUnderstoodSignal handle:[:ex|] do:[ + ^ cls perform:minorKey. + ] + ]. + ^ nil ! subCanvasAt:majorKey at:minorKey put:aSpec @@ -496,56 +524,100 @@ "Modified: / 31.10.1997 / 18:39:30 / cg" ! ! +!WindowBuilder methodsFor:'error handling'! + +aspectNotFound:anAspect error:aString + "show error message on transcript + " + Transcript showCR:'WindowBuilder: ' + , aString + , ' aspect: <' + , anAspect storeString + , '>'. + + StopOnError == true ifTrue:[ + self halt "/ avoids debugger in end-user apps + ]. +! ! + !WindowBuilder methodsFor:'message sending'! -safelyPerform:aSelector +safelyPerform:aSelector ifNone:aBlock "send the message aSelector to the application; the result returned from the send or nil is returned " - |res| + |cls| - aSelector isSymbol ifTrue:[ + aSelector notNil ifTrue:[ application notNil ifTrue:[ - application messageNotUnderstoodSignal handle:[:ex | - ] do:[ - (res := application perform:aSelector) notNil ifTrue:[^ res] + application messageNotUnderstoodSignal handle:[:ex|] do:[ + ^ application perform:aSelector + ]. + cls := application class. + + cls messageNotUnderstoodSignal handle:[:ex|] do:[ + ^ cls perform:aSelector ] ]. applicationClass notNil ifTrue:[ - applicationClass messageNotUnderstoodSignal handle:[:ex | - ] do:[ - (res := applicationClass perform:aSelector) notNil ifTrue:[^ res] + applicationClass messageNotUnderstoodSignal handle:[:ex|] do:[ + ^ applicationClass perform:aSelector ] ] ]. - ^ nil - - "Modified: / 5.2.1998 / 12:28:23 / stefan" + ^ aBlock value ! -safelyPerform:aSelector with:anArgument +safelyPerform:aSelector with:anArgument ifNone:aBlock "send the one-arg-message aSelector to the application; the result returned from the send or nil is returned " - |res| + |cls| - aSelector isSymbol ifTrue:[ + aSelector notNil ifTrue:[ application notNil ifTrue:[ - application messageNotUnderstoodSignal handle:[:ex | - ] do:[ - (res := application perform:aSelector with:anArgument) notNil ifTrue:[^ res] + application messageNotUnderstoodSignal handle:[:ex|] do:[ + ^ application perform:aSelector with:anArgument + ]. + cls := application class. + + cls messageNotUnderstoodSignal handle:[:ex|] do:[ + ^ cls perform:aSelector with:anArgument ] ]. applicationClass notNil ifTrue:[ - applicationClass messageNotUnderstoodSignal handle:[:ex | - ] do:[ - (res := applicationClass perform:aSelector with:anArgument) notNil ifTrue:[^ res] + applicationClass messageNotUnderstoodSignal handle:[:ex|] do:[ + ^ applicationClass perform:aSelector with:anArgument + ]. + ] + ]. + ^ aBlock value +! + +safelyPerform:aSelector with:arg1 with:arg2 ifNone:aBlock + "send the two-arg-message aSelector to the application; + the result returned from the send or nil is returned + " + |cls| + + aSelector notNil ifTrue:[ + application notNil ifTrue:[ + application messageNotUnderstoodSignal handle:[:ex|] do:[ + ^ application perform:aSelector with:arg1 with:arg2 + ]. + cls := application class. + + cls messageNotUnderstoodSignal handle:[:ex|] do:[ + ^ cls perform:aSelector with:arg1 with:arg2 ] ]. + applicationClass notNil ifTrue:[ + applicationClass messageNotUnderstoodSignal handle:[:ex|] do:[ + ^ applicationClass perform:aSelector with:arg1 with:arg2 + ]. + ] ]. - ^ nil - - "Modified: / 5.2.1998 / 12:28:54 / stefan" + ^ aBlock value ! ! !WindowBuilder methodsFor:'spec creation aspect fetch'! @@ -564,25 +636,9 @@ b notNil ifTrue:[^ b]. ]. - application notNil ifTrue:[ - Object messageNotUnderstoodSignal handle:[:ex | - ] do:[ - ^ application actionFor:aKey - ] - ]. - applicationClass notNil ifTrue:[ - (applicationClass respondsTo:#actionFor:) ifTrue:[ - ^ applicationClass actionFor:aKey - ] - ]. - - Transcript showCR:'WindowBuilder: no action for: ' , aKey storeString. - StopOnError == true ifTrue:[self halt]. "/ avoids debugger in end-user apps - - ^ [] - - "Created: / 17.1.1997 / 21:08:22 / cg" - "Modified: / 28.10.1997 / 12:52:57 / cg" + ^ self safelyPerform:#actionFor: + with:aKey + ifNone:[ self aspectNotFound:aKey error:'no action for:'. [] ] ! actionFor:aKey withValue:aValue @@ -601,25 +657,10 @@ b notNil ifTrue:[^ b]. ]. - application notNil ifTrue:[ - Object messageNotUnderstoodSignal handle:[:ex | - ] do:[ - ^ application actionFor:aKey withValue:aValue - ] - ]. - applicationClass notNil ifTrue:[ - (applicationClass respondsTo:#actionFor:withValue:) ifTrue:[ - ^ applicationClass actionFor:aKey withValue:aValue - ] - ]. - - Transcript showCR:'WindowBuilder: no action for: ' , aKey storeString. - StopOnError == true ifTrue:[self halt]. "/ avoids debugger in end-user apps - - ^ [:dummy | ] - - "Created: / 17.1.1997 / 21:08:22 / cg" - "Modified: / 28.10.1997 / 12:53:22 / cg" + ^ self safelyPerform:#actionFor:withValue: + with:aKey + with:aValue + ifNone:[ self aspectNotFound:aKey error:'no action for:'. [:dummy |] ] ! aspectFor:aKey @@ -636,23 +677,9 @@ b notNil ifTrue:[^ b]. ]. - application notNil ifTrue:[ - Object messageNotUnderstoodSignal handle:[:ex | - ] do:[ - ^ application aspectFor:aKey - ] - ]. - applicationClass notNil ifTrue:[ - Object messageNotUnderstoodSignal handle:[:ex | - ] do:[ - ^ applicationClass aspectFor:aKey - ] - ]. - - ^ self aspectAt:aKey - - "Created: / 17.1.1997 / 21:06:16 / cg" - "Modified: / 1.11.1997 / 13:40:24 / cg" + ^ self safelyPerform:#aspectFor: + with:aKey + ifNone:[ self aspectAt:aKey ] ! componentFor:aKey @@ -662,20 +689,9 @@ finally the applications class is asked for a corresponding action. The returned object is typically a view." - |component| - - application notNil ifTrue:[ - component := application componentFor:aKey. - component notNil ifTrue:[^ component]. - ]. - applicationClass notNil ifTrue:[ - (applicationClass respondsTo:#componentFor:) ifTrue:[ - ^ applicationClass componentFor:aKey - ] - ]. - ^ self aspectAt:aKey - - "Modified: 20.6.1997 / 11:40:22 / cg" + ^ self safelyPerform:#componentFor: + with:aKey + ifNone:[ self aspectAt:aKey ] ! labelFor:aKey @@ -685,24 +701,9 @@ finally the applications class is asked for a corresponding action. The returned object is typically a string." - application notNil ifTrue:[ - Object messageNotUnderstoodSignal handle:[:ex | - ] do:[ - ^ application labelFor:aKey - ] - ]. - applicationClass notNil ifTrue:[ - (applicationClass respondsTo:#labelFor:) ifTrue:[ - ^ applicationClass labelFor:aKey - ] - ]. - -"/ Transcript showCR:'WindowBuilder: no label for: ' , aKey storeString. -"/ StopOnError == true ifTrue:[self halt]. "/ avoids debugger in end-user apps - - ^ self aspectAt:aKey - - "Modified: / 28.10.1997 / 12:54:10 / cg" + ^ self safelyPerform:#labelFor: + with:aKey + ifNone:[ self aspectAt:aKey ] ! listFor:aKey @@ -712,25 +713,39 @@ finally the applications class is asked for a corresponding action. The returned object is typically a list." - application notNil ifTrue:[ - Object messageNotUnderstoodSignal handle:[:ex | - ] do:[ - ^ application listFor:aKey + ^ self safelyPerform:#listFor: + with:aKey + ifNone:[ self aspectAt:aKey ] +! + +menuFor:aKey + "Find a binding for the menu named aKey, either in the bindings + or from the source" + + |menu| + + (menu := self bindingAt:aKey) notNil ifTrue:[ + ^ menu + ]. + + menu := self safelyPerform:#menuFor: with:aKey ifNone:[ + self safelyPerform:aKey ifNone:[ + self aspectNotFound:aKey error:'no menu for:'. + nil + ] + ]. + + ((menu := menu value) notNil and:[application notNil]) ifTrue:[ + menu isArray ifTrue:[ + menu := Menu new fromLiteralArrayEncoding:menu. + menu receiver:application. + ] ifFalse:[ + menu findGuiResourcesIn:application ] ]. - applicationClass notNil ifTrue:[ - (applicationClass respondsTo:#listFor:) ifTrue:[ - ^ applicationClass listFor:aKey - ] - ]. + ^ menu -"/ Transcript showCR:'WindowBuilder: no list for: ' , aKey storeString. -"/ StopOnError == true ifTrue:[self halt]. "/ avoids debugger in end-user apps - ^ self aspectAt:aKey - - "Created: / 17.1.1997 / 21:08:45 / cg" - "Modified: / 28.10.1997 / 12:54:32 / cg" ! specificationFor:aKey @@ -740,29 +755,9 @@ finally the applications class is asked for a corresponding interfaceSPec. The returned object is typically an interfaceSpec array." - |spec| - - application notNil ifTrue:[ - application messageNotUnderstoodSignal handle:[:ex | - ] do:[ - spec := application specificationFor:aKey. - ]. - spec notNil ifTrue:[^ spec]. - ]. - applicationClass notNil ifTrue:[ - (applicationClass respondsTo:#specificationFor:) ifTrue:[ - application messageNotUnderstoodSignal handle:[:ex | - ] do:[ - spec := applicationClass specificationFor:aKey - ]. - spec notNil ifTrue:[^ spec]. - ] - ]. - ^ self aspectAt:aKey - - "Modified: / 20.6.1997 / 11:40:22 / cg" - "Created: / 5.2.1998 / 10:47:46 / stefan" - "Modified: / 5.2.1998 / 12:25:08 / stefan" + ^ self safelyPerform:#specificationFor: + with:aKey + ifNone:[ self aspectFor:aKey ] ! ! !WindowBuilder methodsFor:'spec creation callbacks'! @@ -983,5 +978,5 @@ !WindowBuilder class methodsFor:'documentation'! version - ^ '$Header: /cvs/stx/stx/libview2/WindowBuilder.st,v 1.59 1998-02-13 13:53:14 ca Exp $' + ^ '$Header: /cvs/stx/stx/libview2/WindowBuilder.st,v 1.60 1998-02-25 14:28:55 ca Exp $' ! !