diff -r bf056eb85f41 -r 0ff0a7132e35 Tools__InlineMessageDialog.st --- a/Tools__InlineMessageDialog.st Wed May 16 21:39:03 2012 +0200 +++ b/Tools__InlineMessageDialog.st Thu May 17 17:31:22 2012 +0200 @@ -28,8 +28,10 @@ "{ NameSpace: Tools }" ApplicationModel subclass:#InlineMessageDialog - instanceVariableNames:'messageHolder progressHolder progressView specHolder - panelShownHolder panelHiddenHolder worker layout' + instanceVariableNames:'messageHolder progressHolder backgroundColorHolder + backgroundColorOrDefaultHolder progressView panelView + panelViewComponents specHolder panelShownHolder panelHiddenHolder + worker layout changeLayoutUponShowHide' classVariableNames:'' poolDictionaries:'' category:'Interface-Tools' @@ -63,6 +65,61 @@ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. " +! + +documentation +" + A simple info/warning dialog to embed into application window - + much like information panel in Firefox or other applications. + Use it when a modal dialog might be too disturbing. + + + [author:] + Jan Vrany + + [instance variables:] + + [class variables:] + + [see also:] + +" +! + +examples +" + Starting the application: + [exBegin] + Tools::InlineMessageDialog new + open; + message: 'Hello World'; + show: #messageInfoSpec. + + + [exEnd] + + more examples to be added: + [exBegin] + ... add code fragment for + ... executable example here ... + [exEnd] +" +! ! + +!InlineMessageDialog class methodsFor:'accessing-colors'! + +defaultInformationBackground + + ^(Color red:100.0 green:78.0392156862745 blue:22.7450980392157) + + "Created: / 10-04-2012 / 19:31:39 / Jan Vrany " +! + +defaultWarningBackground + + ^(Color red:76.078431372549 green:43.1372549019608 blue:43.1372549019608) + + "Created: / 10-04-2012 / 19:30:22 / Jan Vrany " ! ! !InlineMessageDialog class methodsFor:'interface specs'! @@ -75,8 +132,8 @@ the UIPainter may not be able to read the specification." " - UIPainter new openOnClass:Tools::NewSystemBrowser andSelector:#messageInfoSpec - Tools::NewSystemBrowser new openInterface:#messageInfoSpec + UIPainter new openOnClass:Tools::InlineMessageDialog andSelector:#messageInfoSpec + Tools::InlineMessageDialog new openInterface:#messageInfoSpec " @@ -90,8 +147,6 @@ name: 'MessageInfo' min: (Point 10 10) bounds: (Rectangle 0 0 800 40) - backgroundColor: (Color 100.0 78.0392156862745 22.7450980392157) - forceRecursiveBackgroundOfDefaultBackground: true ) component: (SpecCollection @@ -99,25 +154,16 @@ (LabelSpec label: 'Label' name: 'Message' - layout: (LayoutFrame 10 0 -10 0.5 -90 1 10 0.5) - backgroundColor: (Color 100.0 78.0392156862745 22.7450980392157) + layout: (LayoutFrame 0 0 0 0 0 1 0 1) + backgroundChannel: backgroundColorOrDefaultHolder translateLabel: true labelChannel: messageHolder adjust: left ) - (ActionButtonSpec - label: 'OK' - name: 'OK' - layout: (LayoutFrame -80 1 -12 0.5 -12 1 12 0.5) - translateLabel: true - model: doOK - ) ) ) ) - - "Modified: / 28-10-2010 / 18:30:47 / Jan Vrany " ! progressInfoSpec @@ -143,36 +189,40 @@ name: 'ProgressInfo' min: (Point 10 10) bounds: (Rectangle 0 0 800 40) - backgroundColor: (Color 100.0 78.0392156862745 22.7450980392157) forceRecursiveBackgroundOfDefaultBackground: true ) component: (SpecCollection collection: ( - (LabelSpec - label: 'Label' - name: 'Message' - layout: (LayoutFrame 10 0 0 0 -90 1 20 0) - backgroundColor: (Color 100.0 78.0392156862745 22.7450980392157) - translateLabel: true - labelChannel: messageHolder - adjust: left - ) - (ProgressIndicatorSpec - name: 'ProgressIndicator' - layout: (LayoutFrame 10 0 -20 1 -133 1 -3 1) - model: progressHolder - foregroundColor: (Color 52.156862745098 37.2549019607843 0.0) - backgroundColor: (Color 100.0 91.3725490196078 70.1960784313726) - postBuildCallback: postBuildProgressView: - ) - (ActionButtonSpec - label: 'Abort' - name: 'Abort' - layout: (AlignmentOrigin -12 1 0 0.5 1 0.5) - translateLabel: true - resizeForLabel: true - model: doAbort + (ViewSpec + name: 'Box1' + layout: (LayoutFrame 0 0 0 0 0 1 0 1) + level: 0 + backgroundChannel: backgroundColorOrDefaultHolder + component: + (SpecCollection + collection: ( + (LabelSpec + label: 'Label' + name: 'Message' + layout: (LayoutFrame 0 0 0 0 -20 1 20 0) + backgroundChannel: backgroundColorOrDefaultHolder + translateLabel: true + labelChannel: messageHolder + adjust: left + ) + (ProgressIndicatorSpec + name: 'ProgressIndicator' + layout: (LayoutFrame 0 0 -20 1 -20 1 -3 1) + level: 0 + backgroundChannel: backgroundColorOrDefaultHolder + model: progressHolder + foregroundColor: (Color 52.156862745098 37.2549019607843 0.0) + postBuildCallback: postBuildProgressView: + ) + ) + + ) ) ) @@ -180,6 +230,15 @@ ) ! +warningInfoSpec + + + + ^self messageInfoSpec + + "Modified: / 10-04-2012 / 19:40:35 / Jan Vrany " +! + windowSpec "This resource specification was automatically generated by the UIPainter of ST/X." @@ -204,20 +263,51 @@ name: 'Tools::InlineMessageDialog' min: (Point 10 10) bounds: (Rectangle 0 0 800 40) - backgroundColor: (Color 100.0 78.0392156862745 22.7450980392157) - forceRecursiveBackgroundOfDefaultBackground: true ) component: (SpecCollection collection: ( - (SubCanvasSpec - name: 'InfoSpec' + (ViewSpec + name: 'Layout' layout: (LayoutFrame 0 0 0 0 0 1 0 1) - hasHorizontalScrollBar: false - hasVerticalScrollBar: false - miniScrollerHorizontal: false - specHolder: specHolder - createNewBuilder: false + backgroundChannel: backgroundColorOrDefaultHolder + component: + (SpecCollection + collection: ( + (HorizontalPanelViewSpec + name: 'ComponentPanel' + layout: (LayoutFrame 12 0 0 0 -10 1 0 1) + backgroundChannel: backgroundColorOrDefaultHolder + horizontalLayout: rightSpaceFit + verticalLayout: fit + horizontalSpace: 0 + verticalSpace: 3 + elementsChangeSize: true + component: + (SpecCollection + collection: ( + (SubCanvasSpec + name: 'InfoSpec' + level: 0 + hasHorizontalScrollBar: false + hasVerticalScrollBar: false + miniScrollerHorizontal: false + specHolder: specHolder + createNewBuilder: false + usePreferredHeight: true + useDynamicPreferredWidth: true + useDynamicPreferredHeight: true + useDefaultExtent: true + usePreferredWidth: true + ) + ) + + ) + postBuildCallback: postBuildPanelView: + ) + ) + + ) ) ) @@ -225,8 +315,25 @@ ) ! ! +!InlineMessageDialog class methodsFor:'others'! + +version_CVS + ^ '$Header: /cvs/stx/stx/libtool/Tools__InlineMessageDialog.st,v 1.7 2012-05-17 15:31:22 vrany Exp $' +! ! + !InlineMessageDialog methodsFor:'accessing'! +backgroundColor: aColor + "Sets the background color, but only iff backgroundColorHolder is + not set" + + backgroundColorHolder isNil ifTrue:[ + self backgroundColorOrDefaultHolder value: aColor + ] + + "Created: / 10-04-2012 / 19:38:31 / Jan Vrany " +! + message: aString self messageHolder value: aString @@ -251,6 +358,20 @@ "Created: / 28-10-2010 / 18:24:21 / Jan Vrany " ! ! +!InlineMessageDialog methodsFor:'accessing-presentation'! + +changeLayoutUponShowHide: aBoolean + "If set to false, no changes to compokent layout is done + when panel is shown/hidden. This effectively means, that + that panel is shown over the normal content. + + Default value is true (i.e., relayout components)" + + changeLayoutUponShowHide := aBoolean + + "Modified (comment): / 17-05-2012 / 13:56:39 / Jan Vrany " +! ! + !InlineMessageDialog methodsFor:'actions'! doAbort @@ -266,26 +387,171 @@ AbortOperationRequest raise. ]. ]. - (worker notNil and:[worker isDead]) ifTrue:[ + (worker notNil and:[worker isDead not]) ifTrue:[ + worker terminate. + "/ raise its prio to make it terminate quickly + worker priority:(Processor userSchedulingPriority + 1). + worker := nil. + ]. + + "Modified: / 11-04-2012 / 16:24:46 / Jan Vrany " +! + +doOK + + + (worker notNil and:[worker isDead not]) ifTrue:[ worker := nil. worker terminate. "/ raise its prio to make it terminate quickly worker priority:(Processor userSchedulingPriority + 1) ]. + self hide. - "Modified: / 10-02-2012 / 10:49:25 / Jan Vrany " + "Modified: / 11-04-2012 / 13:18:55 / Jan Vrany " +! ! + +!InlineMessageDialog methodsFor:'adding & removing components'! + +addButton: aButton + | layoutView | + + aButton preferredExtent: ((aButton width + 20) max: 70"px") @ 24. + layoutView := View new. + layoutView backgroundChannel: self backgroundColorOrDefaultHolder. + layoutView addComponent: aButton. + aButton layout: + ( LayoutFrame fractions:(0 @ 0.5 corner:1.0 @ 0.5) offsets:(3 @ -12 corner:-3 @ 12) ). + layoutView preferredExtent: (aButton preferredExtent x + 12) @ 24. + + ^self addComponent: layoutView + + "Created: / 10-04-2012 / 20:49:06 / Jan Vrany " +! + +addButtonAbort + + ^self addButtonWithLabel: (self resources string:'Abort') action: [ self doAbort ] + + "Created: / 10-04-2012 / 21:45:01 / Jan Vrany " +! + +addButtonOK + + ^self addButtonWithLabel: (self resources string:'OK') action: [ self doOK ] + + "Created: / 10-04-2012 / 21:44:50 / Jan Vrany " +! + +addButtonWithLabel: label action: action + ^self addButton: (Button label: label action: action) + + "Created: / 10-04-2012 / 20:50:25 / Jan Vrany " ! -doOK - +addComponent: aView + panelView isNil ifTrue:[ + panelViewComponents isNil ifTrue:[ + panelViewComponents := OrderedCollection new + ]. + panelViewComponents add: aView + ] ifFalse:[ + panelView addSubView: aView. + aView isVisible: true. + ]. + ^aView. + + "Created: / 10-04-2012 / 20:50:45 / Jan Vrany " +! + +beInformation + + self backgroundColor: self class defaultInformationBackground. + self specHolder value: #messageInfoSpec + + "Created: / 11-04-2012 / 11:39:46 / Jan Vrany " +! + +beProgress + + self backgroundColor: self class defaultInformationBackground. + self specHolder value: #progressInfoSpec + + "Created: / 11-04-2012 / 11:41:30 / Jan Vrany " +! - self hide. +beWarning + + self backgroundColor: self class defaultWarningBackground. + self specHolder value: #messageInfoSpec + + "Created: / 11-04-2012 / 11:41:17 / Jan Vrany " +! - "Modified: / 28-10-2010 / 18:21:58 / Jan Vrany " +removeComponent: aView + panelView notNil ifTrue:[ + panelView removeComponent: aView. + ]. + panelViewComponents notNil ifTrue:[ + panelViewComponents remove: aView ifAbsent:[]. + ] + + "Created: / 11-04-2012 / 00:51:46 / Jan Vrany " +! + +removeComponents + "Removes all components except subcanvas" + panelViewComponents := nil. + panelView notNil ifTrue:[ + panelView subViews copyWithoutFirst do:[:component| + component destroy + ] + + ]. + + "Created: / 11-04-2012 / 00:51:52 / Jan Vrany " ! ! !InlineMessageDialog methodsFor:'aspects'! +backgroundColorHolder + "return/create the 'backgroundColorHolder' value holder (automatically generated)" + + backgroundColorHolder isNil ifTrue:[ + backgroundColorHolder := ValueHolder new. + ]. + ^ backgroundColorHolder +! + +backgroundColorHolder:something + "set the 'backgroundColorHolder' value holder (automatically generated)" + + |oldValue newValue| + + backgroundColorHolder notNil ifTrue:[ + oldValue := backgroundColorHolder value. + backgroundColorHolder removeDependent:self. + ]. + backgroundColorHolder := something. + backgroundColorHolder notNil ifTrue:[ + backgroundColorHolder addDependent:self. + ]. + newValue := backgroundColorHolder value. + oldValue ~~ newValue ifTrue:[ + self update:#value with:newValue from:backgroundColorHolder. + ]. +! + +backgroundColorOrDefaultHolder + "return/create the 'backgroundColorOrDefaultHolder' value holder (automatically generated)" + + backgroundColorOrDefaultHolder isNil ifTrue:[ + backgroundColorOrDefaultHolder := ValueHolder new. + backgroundColorOrDefaultHolder addDependent:self. + ]. + ^ backgroundColorOrDefaultHolder +! + messageHolder @@ -357,68 +623,55 @@ "Modified: / 28-10-2010 / 18:29:05 / Jan Vrany " ! ! +!InlineMessageDialog methodsFor:'change & update'! + +update:aspect with:parameter from:changedObject + "Invoked when an object that I depend upon sends a change notification." + + changedObject == backgroundColorHolder ifTrue:[ + self backgroundColorOrDefaultHolder value: backgroundColorHolder value. + ^ self. + ]. + super update:aspect with:parameter from:changedObject + + "Modified: / 10-04-2012 / 19:36:31 / Jan Vrany " +! ! + !InlineMessageDialog methodsFor:'hooks'! +commonPostBuild + panelViewComponents notEmptyOrNil ifTrue:[ + | correctionView | + panelViewComponents do:[:each|panelView addSubView: each]. +"/ "/Correction view, dunno why the layout is bad without it... +"/ correctionView := View new. +"/ correctionView extent: (panelView subViews size * 3)@24. +"/ correctionView backgroundChannel: self backgroundColorOrDefaultHolder. +"/ panelView addComponent: correctionView + ] + + "Created: / 10-04-2012 / 21:02:09 / Jan Vrany " +! + +postBuildPanelView: aPanelView + panelView := aPanelView. + + "Created: / 10-04-2012 / 20:47:31 / Jan Vrany " +! + postBuildProgressView: aProgressIndicator progressView := aProgressIndicator "Created: / 10-02-2012 / 10:42:01 / Jan Vrany " ! ! -!InlineMessageDialog methodsFor:'informing'! - -information: message - - self information: message timeout: nil - - "Created: / 11-02-2012 / 23:14:26 / Jan Vrany " -! - -information: message timeout: timeoutOrNil - - self message: message. - self show: #messageInfoSpec. - timeoutOrNil isInteger ifTrue:[ - [ - Delay waitForSeconds: timeoutOrNil. - self hide. - ] fork. - ] - - "Created: / 11-02-2012 / 23:14:49 / Jan Vrany " -! - -progress: label while: block - - worker := [ - self message: label. - self progress: nil. - self show: #progressInfoSpec. - [ - block value. - ] on: ProgressNotification , ActivityNotification do:[:ex| - self progress: ex parameter. - ex messageText notNil ifTrue:[ - self message: ex messageText. - ]. - ex proceed. - ]. - ] newProcess. - worker addExitAction:[ - self hide. - worker := nil. - ]. - worker resume. - - "Created: / 10-02-2012 / 10:34:17 / Jan Vrany " -! ! - !InlineMessageDialog methodsFor:'private'! getMyView | v | + builder isNil ifTrue:[ ^ nil ]. v := builder window. ^(v superView isKindOf: SubCanvas) ifTrue:[v superView] @@ -432,7 +685,7 @@ | myView | myView := self getMyView. - ^ myView superView isNil ifTrue:[ + ^ (myView isNil or:[myView superView isNil]) ifTrue:[ nil. ] ifFalse: [ myView superView subViews after: myView @@ -447,7 +700,10 @@ myView := self getMyView. otherView := self getOtherView. - myView isVisible ifFalse:[^self]."/already hidden" + myView isVisible ifFalse:[ "/already hidden" + self reset. + ^self + ]. myView isVisible: false. panelShownHolder notNil ifTrue:[ panelShownHolder value: false @@ -455,19 +711,23 @@ panelHiddenHolder notNil ifTrue:[ panelHiddenHolder value: true ]. + changeLayoutUponShowHide ~~ false ifTrue:[ + otherView layout: layout. + ]. - otherView layout: layout + self reset. "Created: / 29-10-2010 / 11:55:44 / Jan Vrany " ! -show: spec +show | myView otherView | myView := self getMyView. otherView := self getOtherView. - myView isVisible ifTrue:[^self]."/already shown" - layout := otherView layout copy. + (myView isNil or:[myView isVisible]) ifTrue:[ + ^self. + ]. myView isVisible: true. panelShownHolder notNil ifTrue:[ panelShownHolder value: true @@ -476,23 +736,199 @@ panelHiddenHolder value: false ]. - otherView layout: - (layout copy topOffset: layout topOffset + 40; yourself). - self specHolder value: spec. + changeLayoutUponShowHide ~~ false ifTrue:[ + otherView notNil ifTrue:[ + layout := otherView layout copy. + otherView layout: + (layout copy topOffset: layout topOffset + 40; yourself). + ]. + ]. + + "Created: / 11-04-2012 / 11:43:28 / Jan Vrany " +! + +show: spec + + + self obsoleteMethodWarning. + self breakPoint: #jv. + + spec == #warningInfoSpec ifTrue:[ self beWarning ]. + spec == #messageInfoSpec ifTrue:[ self beInformation ]. + spec == #progressInfoSpec ifTrue:[ self beProgress ]. + self show. "Created: / 29-10-2010 / 11:48:15 / Jan Vrany " ! ! +!InlineMessageDialog methodsFor:'utilities'! + +reset + "Resets the dialog to initial state, removes all + user supplied components." + + self removeComponents. + + "Created: / 11-04-2012 / 00:51:37 / Jan Vrany " +! + +showMessage: aString + "Shows given message and OK button (which closes the dialog + when clicked" + + self showMessage: aString closeAfter: nil + + "Created: / 11-04-2012 / 13:11:47 / Jan Vrany " +! + +showMessage: aString closeAfter: aTimeDurationOrIntegerOrNil + "Shows given message and OK button (which closes the dialog + when clicked). The dialog closes automaticaly after + aTimeDurationOrIntegerOrNil (integer value means secons, nil + means do not close automatically)" + + + self reset. + self beInformation. + self message: aString. + self addButtonOK. + self show. + aTimeDurationOrIntegerOrNil notNil ifTrue:[ + worker := + [ + aTimeDurationOrIntegerOrNil isInteger ifTrue:[ + Delay waitForSeconds: aTimeDurationOrIntegerOrNil. + ] ifFalse:[ + Delay waitForMilliseconds: aTimeDurationOrIntegerOrNil milliseconds + ]. + self hide. + ] newProcess. + worker addExitAction:[ worker := nil ]. + worker resume. + ]. + + "Created: / 11-04-2012 / 13:13:37 / Jan Vrany " +! + +showProgressLabeled: aString while: aBlock + "During an execution of aBlock, show a label with given + string, a progressbar showing the progress and an 'Abort' button. + + If the block raises a ProgressNotification, then the percentage + progress is updated accordingly. If it raises an ActivityNotification, + then the label is updated and progress bar is changed to be an + activity notificator. + + When an 'Abort' button is pressed, the block is interrupted by + AbortOperationRequest. + + When a block terminates (either normally or abruptly, dialog is closed. + " + + worker := [ + self reset. + self beProgress. + self message: aString. + self addButtonAbort. + self progress: nil. + self show. + [ + aBlock value. + ] on: ProgressNotification , ActivityNotification do:[:ex| + self progress: ex parameter. + ex messageText notNil ifTrue:[ + self message: ex messageText. + ]. + ex proceed. + ]. + ] newProcess. + worker addExitAction:[ + "This check is required, since somebody may want to show + info/warning from within the action block" + self specHolder value == #progressInfoSpec ifTrue:[ + self hide. + ]. + worker := nil. + ]. + worker resume. + + "Created: / 11-04-2012 / 13:38:20 / Jan Vrany " +! ! + +!InlineMessageDialog methodsFor:'utilities-obsolete'! + +information: message + + self information: message timeout: nil + + "Created: / 11-02-2012 / 23:14:26 / Jan Vrany " +! + +information: message timeout: timeoutOrNil + + self reset. + self beInformation. + self message: message. + self addButtonOK. + self show. + timeoutOrNil isInteger ifTrue:[ + [ + Delay waitForSeconds: timeoutOrNil. + self hide. + ] fork. + ] + + "Created: / 11-02-2012 / 23:14:49 / Jan Vrany " +! + +progress: label while: block + + worker := [ + self reset. + self beProgress. + self message: label. + self addButtonAbort. + self progress: nil. + self show. + [ + block value. + ] on: ProgressNotification , ActivityNotification do:[:ex| + self progress: ex parameter. + ex messageText notNil ifTrue:[ + self message: ex messageText. + ]. + ex proceed. + ]. + ] newProcess. + worker addExitAction:[ + self specHolder value == #progressInfoSpec ifTrue:[ + self hide. + ]. + worker := nil. + ]. + worker resume. + + "Created: / 10-02-2012 / 10:34:17 / Jan Vrany " +! + +warning: message action: block labeled: label + + self reset. + self beWarning. + self message: message. + self addButtonWithLabel: label action: block. + self addButtonOK. + self show + + "Created: / 13-02-2012 / 16:59:32 / Jan Vrany " +! ! + !InlineMessageDialog class methodsFor:'documentation'! version - ^ '$Header: /cvs/stx/stx/libtool/Tools__InlineMessageDialog.st,v 1.6 2012-05-15 09:51:40 cg Exp $' -! - -version_CVS - ^ '$Header: /cvs/stx/stx/libtool/Tools__InlineMessageDialog.st,v 1.6 2012-05-15 09:51:40 cg Exp $' + ^ '$Header: /cvs/stx/stx/libtool/Tools__InlineMessageDialog.st,v 1.7 2012-05-17 15:31:22 vrany Exp $' ! version_SVN - ^ '§Id: Tools__InlineMessageDialog.st 7881 2012-02-11 22:16:34Z vranyj1 §' + ^ '§Id: Tools__InlineMessageDialog.st 7976 2012-04-11 16:14:22Z vranyj1 §' ! !