# HG changeset patch # User Claus Gittinger # Date 1256239478 -7200 # Node ID 0595ad4f223960e885ea87d98eb4c91162c62ea4 # Parent f65a55aadf084b133f7ad01d8e8bab6857620589 oops diff -r f65a55aadf08 -r 0595ad4f2239 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 + + + ^ 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 + " + + + + ^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 + " + + + + ^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 + " + + + + ^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@@_?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'! + -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 + - 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 + - self updateButtonEnableState. -! - -assistantSpec + backButtonLabelHolder isNil ifTrue:[ + backButtonLabelHolder := self backButtonLabel asValue. + ]. + ^ backButtonLabelHolder. ! -! +backButtonVisible + -backButtonLabelHolder. + backButtonVisible isNil ifTrue:[ + backButtonVisible := true asValue. + ]. + ^ backButtonVisible. ! -ButtonVisible. -! +currentPageIndexHolder + -IndexHolder onChangeSend:#updateCanvas to:self + currentPageIndexHolder isNil ifTrue:[ + currentPageIndexHolder := 1 asValue. + currentPageIndexHolder onChangeSend:#updateCanvas to:self ]. ^ currentPageIndexHolder. ! -il ifTrue:[ +currentPageInfoHTMLHolder + + + currentPageInfoHTMLHolder isNil ifTrue:[ currentPageInfoHTMLHolder := ValueHolder new. ]. ^ currentPageInfoHTMLHolder. ! -True:[ +currentPageSpecHolder + + + currentPageSpecHolder isNil ifTrue:[ currentPageSpecHolder := nil asValue. ]. ^ currentPageSpecHolder. ! +finishButtonEnabled + + + finishButtonEnabled isNil ifTrue:[ + finishButtonEnabled := false asValue. + ]. + ^ finishButtonEnabled. +! + +finishButtonVisible + + + finishButtonVisible isNil ifTrue:[ + finishButtonVisible := false asValue. + ]. + ^ finishButtonVisible. +! + +forwardButtonEnabled + + + forwardButtonEnabled isNil ifTrue:[ + forwardButtonEnabled := false asValue. + ]. + ^ forwardButtonEnabled. +! + +forwardButtonVisible + + + forwardButtonVisible isNil ifTrue:[ + forwardButtonVisible := true asValue. + ]. + ^ forwardButtonVisible. +! + +nextButtonLabelHolder + + + nextButtonLabelHolder isNil ifTrue:[ + nextButtonLabelHolder := self nextButtonLabel asValue. + ]. + ^ nextButtonLabelHolder. +! + +pageInfoHolder + + + 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 + -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 $' ! !