oops
authorClaus Gittinger <cg@exept.de>
Thu, 22 Oct 2009 21:24:38 +0200
changeset 3813 0595ad4f2239
parent 3812 f65a55aadf08
child 3814 71bd81ca3f67
oops
AssistantApplication.st
--- a/AssistantApplication.st	Thu Oct 22 21:07:29 2009 +0200
+++ b/AssistantApplication.st	Thu Oct 22 21:24:38 2009 +0200
@@ -13,23 +13,93 @@
 
 !AssistantApplication class methodsFor:'documentation'!
 
-documentation'
+documentation
+"
+    an easy to use framework for assistant-dialog applications.
+    These are multipage applications, in which the user is able to navigate
+    along achain of pages as specified in the AssistantSpec
+
+    see stx:doc/coding:DemoAssistant for a demo example.
+    see ProjectBuilderAssistantApplication for a concrete example.
+"
 ! !
 
 !AssistantApplication class methodsFor:'help'!
 
-hodsFor:'help'
+flyByHelpSpec
+    <resource: #help>
+
+    ^ super flyByHelpSpec addPairsFrom:#(
+
+#backButton
+'Navigate to the previous page %(previousPageInfo)'
+
+#nextButton
+'Navigate to the next page %(nextPageInfo)'
+
+)
 ! !
 
 !AssistantApplication class methodsFor:'image specs'!
 
-:'image specs'
+bulletIcon
+    "This resource specification was automatically generated
+     by the ImageEditor of ST/X."
+
+    "Do not manually edit this!! If it is corrupted,
+     the ImageEditor may not be able to read the specification."
+
+    "
+     self bulletIcon inspect
+     ImageEditor openOnClass:self andSelector:#bulletIcon
+     Icon flushCachedIcons
+    "
+
+    <resource: #image>
+
+    ^Icon
+        constantNamed:'AssistantApplication class bulletIcon'
+        ifAbsentPut:[(Depth2Image new) width: 16; height: 16; photometric:(#palette); bitsPerSample:(#[2]); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@@@@@@@@@@@@@@@@% @@BPA @@P@D@@ @@ @D@@D@A@@A@@ @@ @A@@P@@$@X@@@% @@@@@@@@@@@@@@@@@@@a') ; colorMapFromArray:#[0 0 0 84 84 84 170 170 170 255 255 255]; mask:((Depth1Image new) width: 16; height: 16; photometric:(#blackIs0); bitsPerSample:(#[1]); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@@@@@@@<@O<@?0G? _>A?8G? O<@?0@<@@@@@@@@@b') ; yourself); yourself]
 !
 
-); yourself]
+leftArrowIcon
+    "This resource specification was automatically generated
+     by the ImageEditor of ST/X."
+
+    "Do not manually edit this!! If it is corrupted,
+     the ImageEditor may not be able to read the specification."
+
+    "
+     self leftArrowIcon inspect
+     ImageEditor openOnClass:self andSelector:#leftArrowIcon
+     Icon flushCachedIcons
+    "
+
+    <resource: #image>
+
+    ^Icon
+        constantNamed:'AssistantApplication class leftArrowIcon'
+        ifAbsentPut:[(Depth2Image new) width: 16; height: 16; photometric:(#palette); bitsPerSample:(#[2]); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@@@@@@@@@@@@@@@@@@@@@@@@@@D@@@@G@@@@G??<@A???@@G@@@@@P@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@a') ; colorMapFromArray:#[0 0 0 84 84 84 170 170 170 255 255 255]; mask:((Depth1Image new) width: 16; height: 16; photometric:(#blackIs0); bitsPerSample:(#[1]); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@A@@L@A0@O@A?>O?9??''?>O?8_? <@A0@C@@D@@@@b') ; yourself); yourself]
 !
 
-); yourself]
+rightArrowIcon
+    "This resource specification was automatically generated
+     by the ImageEditor of ST/X."
+
+    "Do not manually edit this!! If it is corrupted,
+     the ImageEditor may not be able to read the specification."
+
+    "
+     self rightArrowIcon inspect
+     ImageEditor openOnClass:self andSelector:#rightArrowIcon
+     Icon flushCachedIcons
+    "
+
+    <resource: #image>
+
+    ^Icon
+        constantNamed:'AssistantApplication class rightArrowIcon'
+        ifAbsentPut:[(Depth2Image new) width: 16; height: 16; photometric:(#palette); bitsPerSample:(#[2]); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@P@@@@M@@O??4@C??=@@@@M@@@@A@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@a') ; colorMapFromArray:#[0 0 0 84 84 84 170 170 170 255 255 255]; mask:((Depth1Image new) width: 16; height: 16; photometric:(#blackIs0); bitsPerSample:(#[1]); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@@ @C@@N@@<G?8_?1??''?>_?1?>@C0@N@@0@B@@@@b') ; yourself); yourself]
 ! !
 
 !AssistantApplication class methodsFor:'interface specs'!
@@ -56,7 +126,6 @@
        (WindowSpec
           label: 'NewApplication'
           name: 'NewApplication'
-          min: (Point 534 440)
           bounds: (Rectangle 0 0 534 440)
           menu: mainMenu
         )
@@ -88,19 +157,17 @@
                             collection: (
                              (SequenceViewSpec
                                 name: 'PagesLabelList'
-                                layout: (LayoutFrame 0 0 0 0 0 1 0 0.6)
+                                layout: (LayoutFrame 0 0 0 0 0 1 0 0.7)
                                 level: 0
                                 enableChannel: false
                                 hasHorizontalScrollBar: true
                                 hasVerticalScrollBar: true
-                                miniScrollerHorizontal: true
-                                miniScrollerVertical: true
                                 useIndex: true
                                 sequenceList: pageLabelsInList
                               )
                              (HTMLViewSpec
                                 name: 'HTMLBrowser1'
-                                layout: (LayoutFrame 0 0 0 0.6 0 1 0 1)
+                                layout: (LayoutFrame 0 0 0 0.7 0 1 0 1)
                                 level: 0
                                 hasHorizontalScrollBar: true
                                 hasVerticalScrollBar: true
@@ -216,43 +283,31 @@
 
 !AssistantApplication class methodsFor:'menu specs'!
 
-enableChannel: finishButtonEnabled
-                          extent: (Point 65 22)
-                        )
-                       (ActionButtonSpec
-                          label: 'Cancel'
-                          name: 'Button8'
-                          translateLabel: true
-                          resizeForLabel: true
-                          model: doCancel
-                          extent: (Point 65 22)
-                        )
-                       )
-                     
-                    )
-                  )
-                 )
-               
-              )
-            )
-           (LabelSpec
-              label: 'Label'
-              name: 'Label1'
-              layout: (LayoutFrame 1 0 -25 1 -1 1 -1 1)
-              level: -1
-              translateLabel: true
-              labelChannel: infoHolder
-              adjust: left
-            )
-           )
-         
-        )
-      )
-! !
+mainMenu
+    "This resource specification was automatically generated
+     by the MenuEditor of ST/X."
+
+    "Do not manually edit this!! If it is corrupted,
+     the MenuEditor may not be able to read the specification."
+
+    "
+     MenuEditor new openOnClass:AssistantApplication andSelector:#mainMenu
+     (Menu new fromLiteralArrayEncoding:(AssistantApplication mainMenu)) startUp
+    "
 
-!AssistantApplication class methodsFor:'required protocol'!
+    <resource: #menu>
 
-label: 'Exit'
+    ^ 
+     #(Menu
+        (
+         (MenuItem
+            label: 'File'
+            translateLabel: true
+            submenu: 
+           (Menu
+              (
+               (MenuItem
+                  label: 'Exit'
                   itemValue: closeRequest
                   translateLabel: true
                 )
@@ -292,53 +347,23 @@
       )
 ! !
 
+!AssistantApplication class methodsFor:'required protocol'!
+
+assistantSpec
+    "must return a sequenceable collection of assistantPageSpecs - one for each page"
+
+    self subclassResponsibility
+! !
+
 !AssistantApplication methodsFor:'actions'!
 
-)
-         (MenuItem
-            label: 'Help'
-            translateLabel: true
-            startGroup: right
-            submenu: 
-           (Menu
-              (
-               (MenuItem
-                  label: 'Documentation'
-                  itemValue: openDocumentation
-                  translateLabel: true
-                )
-               (MenuItem
-                  label: '-'
-                )
-               (MenuItem
-                  label: 'About this Application...'
-                  itemValue: openAboutThisApplication
-                  translateLabel: true
-                )
-               )
-              nil
-              nil
-            )
-          )
-         )
-        nil
-        nil
-      )
-!
+canGoBackward
+    |currentPageSpec previousPageSpec|
 
-)
-               )
-              nil
-              nil
-            )
-          )
-         )
-        nil
-        nil
-      )
-!
-
-ector) ifFalse:[^ false].
+    "/ see if we are allowed to leave...
+    currentPageSpec := self currentPageSpec.
+    currentPageSpec canLeaveQuerySelector notNil ifTrue:[
+        (self perform:currentPageSpec canLeaveQuerySelector) ifFalse:[^ false].
     ].
 
     "/ see if we are allowed to enter the next...
@@ -351,27 +376,15 @@
     ^ true
 !
 
-"/ see if we are allowed to enter the next...
-    previousPageSpec := self previousEnabledPageSpec.
-    previousPageSpec isNil ifTrue:[^ false].
+canGoForward
+    |currentPageSpec nextPageSpec|
 
-    previousPageSpec canEnterQuerySelector notNil ifTrue:[
-        (self perform:previousPageSpec canEnterQuerySelector) ifFalse:[^ false].
-    ].
-    ^ true
-!
+    self currentPageIndex == self numberOfPages ifTrue:[^ false].
 
-he next...
-    previousPageSpec := self previousEnabledPageSpec.
-    previousPageSpec isNil ifTrue:[^ false].
-
-    previousPageSpec canEnterQuerySelector notNil ifTrue:[
-        (self perform:previousPageSpec canEnterQuerySelector) ifFalse:[^ false].
-    ].
-    ^ true
-!
-
-lf perform:currentPageSpec canLeaveQuerySelector) ifFalse:[^ false].
+    "/ see if we are allowed to leave...
+    currentPageSpec := self currentPageSpec.
+    currentPageSpec canLeaveQuerySelector notNil ifTrue:[
+        (self perform:currentPageSpec canLeaveQuerySelector) ifFalse:[^ false].
     ].
 
     "/ see if we are allowed to enter the next...
@@ -382,11 +395,23 @@
         (self perform:nextPageSpec canEnterQuerySelector) ifFalse:[^ false].
     ].
     ^ true
-! !
+!
+
+doCancel
+    self closeRequest
+!
 
-!AssistantApplication methodsFor:'aspects'!
+doFinish
+    self closeRequest
+!
 
-tPageSpec leaveCallbackSelector notNil ifTrue:[
+goBackward
+    |currentPageSpec|
+
+    (self canGoBackward) ifFalse:[^ self].
+
+    currentPageSpec := self currentPageSpec.
+    currentPageSpec leaveCallbackSelector notNil ifTrue:[
         self perform:currentPageSpec leaveCallbackSelector
     ].
 
@@ -400,28 +425,7 @@
     self updateButtonEnableState.
 !
 
-self perform:currentPageSpec leaveCallbackSelector
-    ].
-
-    self currentPageIndexHolder value:((self indexOfPreviousEnabledPageSpec) max:1).
-
-    currentPageSpec := self currentPageSpec.
-    currentPageSpec enterCallbackSelector notNil ifTrue:[
-        self perform:currentPageSpec enterCallbackSelector
-    ].
-
-    self updateButtonEnableState.
-!
-
-Spec := self currentPageSpec.
-    currentPageSpec enterCallbackSelector notNil ifTrue:[
-        self perform:currentPageSpec enterCallbackSelector
-    ].
-
-    self updateButtonEnableState.
-!
-
-oForward
+goForward
     |currentPageSpec|
 
     (self canGoForward) ifFalse:[^ self].
@@ -439,57 +443,131 @@
     ].
 
     self updateButtonEnableState.
+! !
+
+!AssistantApplication methodsFor:'aspects'!
+
+assistantSpec
+    ^ self class assistantSpec
 !
 
-otNil ifTrue:[
-        self perform:currentPageSpec leaveCallbackSelector
-    ].
-
-    self currentPageIndexHolder value:(self indexOfNextEnabledPageSpec).
+backButtonEnabled
+    <resource: #uiAspect>
 
-    currentPageSpec := self currentPageSpec.
-    currentPageSpec enterCallbackSelector notNil ifTrue:[
-        self perform:currentPageSpec enterCallbackSelector
+    backButtonEnabled isNil ifTrue:[
+        backButtonEnabled := false asValue.
     ].
-
-    self updateButtonEnableState.
+    ^ backButtonEnabled.
 !
 
-Nil ifTrue:[
-        self perform:currentPageSpec enterCallbackSelector
-    ].
+backButtonLabelHolder
+    <resource: #uiAspect>
 
-    self updateButtonEnableState.
-!
-
-assistantSpec
+    backButtonLabelHolder isNil ifTrue:[
+        backButtonLabelHolder := self backButtonLabel asValue.
+    ].
+    ^ backButtonLabelHolder.
 !
 
-!
+backButtonVisible
+    <resource: #uiAspect>
 
-backButtonLabelHolder.
+    backButtonVisible isNil ifTrue:[
+        backButtonVisible := true asValue.
+    ].
+    ^ backButtonVisible.
 !
 
-ButtonVisible.
-!
+currentPageIndexHolder
+    <resource: #uiAspect>
 
-IndexHolder onChangeSend:#updateCanvas to:self
+    currentPageIndexHolder isNil ifTrue:[
+        currentPageIndexHolder := 1 asValue.
+        currentPageIndexHolder onChangeSend:#updateCanvas to:self
     ].
     ^ currentPageIndexHolder.
 !
 
-il ifTrue:[
+currentPageInfoHTMLHolder
+    <resource: #uiAspect>
+
+    currentPageInfoHTMLHolder isNil ifTrue:[
         currentPageInfoHTMLHolder := ValueHolder new.
     ].
     ^ currentPageInfoHTMLHolder.
 !
 
-True:[
+currentPageSpecHolder
+    <resource: #uiAspect>
+
+    currentPageSpecHolder isNil ifTrue:[
         currentPageSpecHolder := nil asValue.
     ].
     ^ currentPageSpecHolder.
 !
 
+finishButtonEnabled
+    <resource: #uiAspect>
+
+    finishButtonEnabled isNil ifTrue:[
+        finishButtonEnabled := false asValue.
+    ].
+    ^ finishButtonEnabled.
+!
+
+finishButtonVisible
+    <resource: #uiAspect>
+
+    finishButtonVisible isNil ifTrue:[
+        finishButtonVisible := false asValue.
+    ].
+    ^ finishButtonVisible.
+!
+
+forwardButtonEnabled
+    <resource: #uiAspect>
+
+    forwardButtonEnabled isNil ifTrue:[
+        forwardButtonEnabled := false asValue.
+    ].
+    ^ forwardButtonEnabled.
+!
+
+forwardButtonVisible
+    <resource: #uiAspect>
+
+    forwardButtonVisible isNil ifTrue:[
+        forwardButtonVisible := true asValue.
+    ].
+    ^ forwardButtonVisible.
+!
+
+nextButtonLabelHolder
+    <resource: #uiAspect>
+
+    nextButtonLabelHolder isNil ifTrue:[
+        nextButtonLabelHolder := self nextButtonLabel asValue.
+    ].
+    ^ nextButtonLabelHolder.
+!
+
+pageInfoHolder
+    <resource: #uiAspect>
+
+    pageInfoHolder isNil ifTrue:[
+        pageInfoHolder := nil asValue.
+    ].
+    ^ pageInfoHolder.
+!
+
+pageLabelsInList
+    pageLabelsInList isNil ifTrue:[
+        pageLabelsInList := List new.
+        pageLabelsInList contents:(self pageLabelsInListWithBullet).
+    ].
+    ^ pageLabelsInList
+!
+
 pageLabelsInListWithBullet
     |newList|
 
@@ -514,37 +592,15 @@
 
 !AssistantApplication methodsFor:'help'!
 
-pageInfoHolder isNil ifTrue:[
-        pageInfoHolder := nil asValue.
-    ].
-    ^ pageInfoHolder.
-!
+flyByHelpTextForKey:aKey
+    <resource: #help>
 
-pageInfoHolder isNil ifTrue:[
-        pageInfoHolder := nil asValue.
-    ].
-    ^ pageInfoHolder.
-! !
-
-!AssistantApplication methodsFor:'initialization & release'!
+    |text bindings nextSpec prevSpec|
 
-ith:(TextView defaultSelectionForegroundColor) on:(TextView defaultSelectionBackgroundColor) );
-                            icon:(self class rightArrowIcon);
-                            image2:(self class leftArrowIcon)
-                    ] ifFalse:[
-                        (self isPageEnabledAtIndex:index) ifFalse:[
-                            entry colorizeAllWith:(Button defaultDisabledForegroundColor) "Color grey".
-                        ] ifTrue:[
-                            entry
-                        ].
-                    ].
-                ].
-    ^ newList
-! !
+    text := super flyByHelpTextForKey:aKey.
 
-!AssistantApplication methodsFor:'look'!
-
-revSpec := self previousEnabledPageSpec.
+    nextSpec := self nextEnabledPageSpec.
+    prevSpec := self previousEnabledPageSpec.
 
     bindings := Dictionary new.
     bindings 
@@ -555,14 +611,15 @@
         put:(nextSpec notNil ifTrue:[ '"',nextSpec pageTitle,'"' ] ifFalse:['']).
 
     ^ self resources string:text withArgs:bindings.    
-!
+! !
 
-xtSpec notNil ifTrue:[ '"',nextSpec pageTitle,'"' ] ifFalse:['']).
+!AssistantApplication methodsFor:'initialization & release'!
 
-    ^ self resources string:text withArgs:bindings.    
-!
+postBuildWith:aBuilder
+    |maxCanvasExtent|
 
-self updateCanvas.
+    super postBuildWith:aBuilder.
+    self updateCanvas.
 
     maxCanvasExtent := (self assistantSpec 
                             collect:[:eachPageSpec | 
@@ -578,58 +635,48 @@
     self window extent:(maxCanvasExtent + (200 @ 40)).
 ! !
 
-!AssistantApplication methodsFor:'private'!
-
-|windowSpecSelector specArray windowSpec|
-
-                                windowSpecSelector := eachPageSpec windowSpecSelector.
-                                specArray := self perform:windowSpecSelector ifNotUnderstood:[self class perform:windowSpecSelector].
-                                windowSpec := specArray decodeAsLiteralArray.
-                                windowSpec window bounds extent.
-                            ]
-                       ) max.
+!AssistantApplication methodsFor:'look'!
 
-    self window extent:(maxCanvasExtent + (200 @ 40)).
-!
-
-[self class perform:windowSpecSelector].
-                                windowSpec := specArray decodeAsLiteralArray.
-                                windowSpec window bounds extent.
-                            ]
-                       ) max.
-
-    self window extent:(maxCanvasExtent + (200 @ 40)).
+backButtonLabel
+    ^ LabelAndIcon 
+        label:(resources string:'Back')
+        icon:(self backButtonEnabled value
+                ifTrue:[ToolbarIconLibrary leftArrow24x24Icon]
+                ifFalse:[ToolbarIconLibrary leftArrow24x24disabledIcon])
 !
 
-windowSpec := specArray decodeAsLiteralArray.
-                                windowSpec window bounds extent.
-                            ]
-                       ) max.
-
-    self window extent:(maxCanvasExtent + (200 @ 40)).
+nextButtonLabel
+    ^ LabelAndTwoIcons new 
+        string:(resources string:'Next');
+        image2:(self forwardButtonEnabled value
+                ifTrue:[ToolbarIconLibrary rightArrow24x24Icon]
+                ifFalse:[ToolbarIconLibrary rightArrow24x24disabledIcon])
 !
 
-windowSpec window bounds extent.
-                            ]
-                       ) max.
+pageLabels
+    ^ self assistantSpec collect:[:specEntry | specEntry pageTitle].
+! !
 
-    self window extent:(maxCanvasExtent + (200 @ 40)).
-!
+!AssistantApplication methodsFor:'private'!
 
-Arrow24x24disabledIcon])
-!
+canFinish
+    |pageIndex pageSpec|
 
-ication methodsFor:'private'
-!
-
-isNil
+    pageIndex := self currentPageIndexHolder value.
+    pageSpec := self assistantSpec at:pageIndex.
+    ^ pageSpec canLeaveQuerySelector isNil
     or:[ self perform:pageSpec canLeaveQuerySelector ]
 !
 
-elf assistantSpec at:(self currentPageIndex).
+currentPageIndex
+    ^ self currentPageIndexHolder value
 !
 
-c
+currentPageSpec
+    ^ self assistantSpec at:(self currentPageIndex).
+!
+
+indexOfNextEnabledPageSpec
     |delta currentPageIndex|
 
     currentPageIndex := self currentPageIndex.
@@ -646,37 +693,65 @@
     ^ nil
 !
 
-ndex := self currentPageIndex.
+indexOfPreviousEnabledPageSpec
+    |delta currentPageIndex|
+
+    currentPageIndex := self currentPageIndex.
     delta := 1.
     [ 
-        (currentPageIndex + delta) <= (self numberOfPages)
-        and:[ (self isPageEnabledAtIndex:(currentPageIndex + delta)) not ]
+        (currentPageIndex - delta) > 0
+        and:[ (self isPageEnabledAtIndex:(currentPageIndex - delta)) not ]
     ] whileTrue:[
         delta := delta + 1.
     ].
-    (currentPageIndex + delta) <= (self numberOfPages) ifTrue:[
-        ^ (currentPageIndex + delta).
+    (currentPageIndex - delta) > 0 ifTrue:[
+        ^ (currentPageIndex - delta).
     ].
     ^ nil
 !
 
-tPageIndex + delta)) not ]
-    ] whileTrue:[
-        delta := delta + 1.
-    ].
-    (currentPageIndex + delta) <= (self numberOfPages) ifTrue:[
-        ^ (currentPageIndex + delta).
-    ].
-    ^ nil
+isPageEnabledAtIndex:index
+    |isEnabledSelector|
+
+    isEnabledSelector := (self assistantSpec at:index) isEnabledQuerySelector.
+    ^ isEnabledSelector isNil or:[ (self perform:isEnabledSelector) ]
+!
+
+nextEnabledPageSpec
+    |index|
+
+    index := self indexOfNextEnabledPageSpec.
+    index isNil ifTrue:[^ nil].
+    ^ self assistantSpec at:index.
+!
+
+nextPageSpec
+    ^ self assistantSpec at:(self currentPageIndex + 1).
+!
+
+numberOfPages
+    ^ self assistantSpec size
+!
+
+previousEnabledPageSpec
+    |index|
+
+    index := self indexOfPreviousEnabledPageSpec.
+    index isNil ifTrue:[^ nil].
+    ^ self assistantSpec at:index.
+!
+
+previousPageSpec
+    ^ self assistantSpec at:(self currentPageIndex - 1).
 ! !
 
 !AssistantApplication methodsFor:'update'!
 
-.
-    (currentPageIndex + delta) <= (self numberOfPages) ifTrue:[
-        ^ (currentPageIndex + delta).
-    ].
-    ^ nil
+updateButtonEnableState
+    self backButtonEnabled value:(self canGoBackward).
+    self forwardButtonEnabled value:(self canGoForward).
+    self backButtonLabelHolder value:(self backButtonLabel).
+    self nextButtonLabelHolder value:(self nextButtonLabel).
 !
 
 updateCanvas
@@ -705,5 +780,5 @@
 !AssistantApplication class methodsFor:'documentation'!
 
 version_CVS
-    ^ '$Header: /cvs/stx/stx/libwidg2/AssistantApplication.st,v 1.10 2009-10-22 19:07:29 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libwidg2/AssistantApplication.st,v 1.11 2009-10-22 19:24:38 cg Exp $'
 ! !