diff -r 668eb9eae2ac -r 0a2b2ff030a0 UIPropertyView.st --- a/UIPropertyView.st Fri Feb 21 20:33:57 1997 +0100 +++ b/UIPropertyView.st Tue Feb 25 14:15:56 1997 +0100 @@ -1,7 +1,7 @@ ApplicationModel subclass:#UIPropertyView - instanceVariableNames:'receiver modified propertyFrame propertyList propertySpecs - currentView currentSpec aspects specBeingEdited - userSelectedProperty' + instanceVariableNames:'builderView modified propertyFrame propertyList propertySpecs + currentView currentSpec propertyAspects staticAspects + specBeingEdited userSelectedProperty currentSpecChannel' classVariableNames:'' poolDictionaries:'' category:'Interface-UIPainter' @@ -18,6 +18,12 @@ ^ application ! ! +!UIPropertyView class methodsFor:'constants'! + +titleOfLayoutMenu + ^ 'Dimension' +! ! + !UIPropertyView class methodsFor:'specifications'! specificationAlignmentOrigin @@ -74,7 +80,9 @@ #'type:' #numberOrNil #'layout:' #(#LayoutFrame 57 0 42 0 114 0 60 0) #'model:' #leftFraction - #acceptOnLostFocus: true + #'immediateAccept:' false + #'acceptOnReturn:' true + #'acceptOnTab:' true #tabable: true ) #(#InputFieldSpec @@ -82,7 +90,9 @@ #'type:' #numberOrNil #'layout:' #(#LayoutFrame 57 0 69 0 114 0 87 0) #'model:' #topFraction - #acceptOnLostFocus: true + #'immediateAccept:' false + #'acceptOnReturn:' true + #'acceptOnTab:' true #tabable: true ) #(#InputFieldSpec @@ -90,7 +100,9 @@ #'type:' #numberOrNil #'layout:' #(#LayoutFrame 57 0 96 0 114 0 114 0) #'model:' #leftAlignmentFraction - #acceptOnLostFocus: true + #'immediateAccept:' false + #'acceptOnReturn:' true + #'acceptOnTab:' true #tabable: true ) #(#InputFieldSpec @@ -98,7 +110,9 @@ #'type:' #numberOrNil #'layout:' #(#LayoutFrame 56 0 122 0 113 0 140 0) #'model:' #topAlignmentFraction - #acceptOnLostFocus: true + #'immediateAccept:' false + #'acceptOnReturn:' true + #'acceptOnTab:' true #tabable: true ) #(#InputFieldSpec @@ -106,7 +120,9 @@ #'type:' #numberOrNil #'layout:' #(#LayoutFrame 154 0 42 0 212 0 60 0) #'model:' #leftOffset - #acceptOnLostFocus: true + #'immediateAccept:' false + #'acceptOnReturn:' true + #'acceptOnTab:' true #tabable: true ) #(#InputFieldSpec @@ -114,7 +130,9 @@ #'type:' #numberOrNil #'layout:' #(#LayoutFrame 154 0 69 0 212 0 87 0) #'model:' #topOffset - #acceptOnLostFocus: true + #'immediateAccept:' false + #'acceptOnReturn:' true + #'acceptOnTab:' true #tabable: true ) #(#ActionButtonSpec @@ -147,19 +165,19 @@ #'name:' 'button' #'layout:' #(#LayoutFrame 16 0 210 0 76 0 240 0) #'label:' 'frame' - #'model:' #setLayoutFrame + #'model:' #showLayoutFrame ) #(#ActionButtonSpec #'name:' 'button' #'layout:' #(#LayoutFrame 96 0 210 0 156 0 240 0) #'label:' 'origin' - #'model:' #setLayoutOrigin + #'model:' #showLayoutOrigin ) #(#ActionButtonSpec #'name:' 'button' #'layout:' #(#LayoutFrame 176 0 210 0 236 0 240 0) #'label:' 'align' - #'model:' #setAlignmentOrigin + #'model:' #showAlignmentOrigin #'initiallyDisabled:' true ) @@ -236,10 +254,8 @@ #'model:' #leftFraction #'type:' #numberOrNil #'immediateAccept:' false - #'acceptOnLeave:' true #'acceptOnReturn:' true #'acceptOnTab:' true - #'acceptOnLostFocus:' true ) #(#InputFieldSpec #'name:' 'relative E2' @@ -247,10 +263,8 @@ #'model:' #topFraction #'type:' #numberOrNil #'immediateAccept:' false - #'acceptOnLeave:' true #'acceptOnReturn:' true #'acceptOnTab:' true - #'acceptOnLostFocus:' true ) #(#InputFieldSpec #'name:' 'relative E3' @@ -258,10 +272,8 @@ #'model:' #rightFraction #'type:' #numberOrNil #'immediateAccept:' false - #'acceptOnLeave:' true #'acceptOnReturn:' true #'acceptOnTab:' true - #'acceptOnLostFocus:' true ) #(#InputFieldSpec #'name:' 'relative E4' @@ -269,10 +281,8 @@ #'model:' #bottomFraction #'type:' #numberOrNil #'immediateAccept:' false - #'acceptOnLeave:' true #'acceptOnReturn:' true #'acceptOnTab:' true - #'acceptOnLostFocus:' true ) #(#InputFieldSpec #'name:' 'offset E1' @@ -280,10 +290,8 @@ #'model:' #leftOffset #'type:' #numberOrNil #'immediateAccept:' false - #'acceptOnLeave:' true #'acceptOnReturn:' true #'acceptOnTab:' true - #'acceptOnLostFocus:' true ) #(#InputFieldSpec #'name:' 'offset E2' @@ -291,10 +299,8 @@ #'model:' #topOffset #'type:' #numberOrNil #'immediateAccept:' false - #'acceptOnLeave:' true #'acceptOnReturn:' true #'acceptOnTab:' true - #'acceptOnLostFocus:' true ) #(#InputFieldSpec #'name:' 'offset E3' @@ -302,10 +308,8 @@ #'model:' #rightOffset #'type:' #numberOrNil #'immediateAccept:' false - #'acceptOnLeave:' true #'acceptOnReturn:' true #'acceptOnTab:' true - #'acceptOnLostFocus:' true ) #(#InputFieldSpec #'name:' 'offset E4' @@ -313,10 +317,8 @@ #'model:' #bottomOffset #'type:' #numberOrNil #'immediateAccept:' false - #'acceptOnLeave:' true #'acceptOnReturn:' true #'acceptOnTab:' true - #'acceptOnLostFocus:' true ) #(#ActionButtonSpec #'name:' 'relative B1' @@ -382,19 +384,20 @@ #'name:' 'button' #'layout:' #(#LayoutFrame 16 0 210 0 76 0 240 0) #'label:' 'frame' - #'model:' #setLayoutFrame + #'model:' #showLayoutFrame + #'initiallyDisabled:' true ) #(#ActionButtonSpec #'name:' 'button10' #'layout:' #(#LayoutFrame 96 0 210 0 156 0 240 0) #'label:' 'origin' - #'model:' #setLayoutOrigin + #'model:' #showLayoutOrigin ) #(#ActionButtonSpec #'name:' 'button11' #'layout:' #(#LayoutFrame 176 0 210 0 236 0 240 0) #'label:' 'align' - #'model:' #setAlignmentOrigin + #'model:' #showAlignmentOrigin ) ) @@ -449,7 +452,9 @@ #'type:' #numberOrNil #'layout:' #(#LayoutFrame 57 0 42 0 114 0 60 0) #'model:' #leftFraction - #acceptOnLostFocus: true + #'immediateAccept:' false + #'acceptOnReturn:' true + #'acceptOnTab:' true #tabable: true ) #(#InputFieldSpec @@ -457,7 +462,9 @@ #'type:' #numberOrNil #'layout:' #(#LayoutFrame 57 0 69 0 114 0 87 0) #'model:' #topFraction - #acceptOnLostFocus: true + #'immediateAccept:' false + #'acceptOnReturn:' true + #'acceptOnTab:' true #tabable: true ) #(#InputFieldSpec @@ -465,7 +472,9 @@ #'type:' #numberOrNil #'layout:' #(#LayoutFrame 154 0 42 0 212 0 60 0) #'model:' #leftOffset - #acceptOnLostFocus: true + #'immediateAccept:' false + #'acceptOnReturn:' true + #'acceptOnTab:' true #tabable: true ) #(#InputFieldSpec @@ -473,7 +482,9 @@ #'type:' #numberOrNil #'layout:' #(#LayoutFrame 154 0 69 0 212 0 87 0) #'model:' #topOffset - #acceptOnLostFocus: true + #'immediateAccept:' false + #'acceptOnReturn:' true + #'acceptOnTab:' true #tabable: true ) #(#ActionButtonSpec @@ -506,20 +517,20 @@ #'name:' 'button' #'layout:' #(#LayoutFrame 16 0 210 0 76 0 240 0) #'label:' 'frame' - #'model:' #setLayoutFrame + #'model:' #showLayoutFrame ) #(#ActionButtonSpec #'name:' 'button' #'layout:' #(#LayoutFrame 96 0 210 0 156 0 240 0) #'label:' 'origin' - #'model:' #setLayoutOrigin + #'model:' #showLayoutOrigin #'initiallyDisabled:' true ) #(#ActionButtonSpec #'name:' 'button' #'layout:' #(#LayoutFrame 176 0 210 0 236 0 240 0) #'label:' 'align' - #'model:' #setAlignmentOrigin + #'model:' #showAlignmentOrigin ) ) @@ -532,11 +543,70 @@ !UIPropertyView methodsFor:'accessing'! -modified - "returns state of modification flag - " - ^ modified -! +update:something + |slices list view prevSpecClass| + + (something == #selection or:[something == #tree]) ifFalse:[ + (something == #layout and:[modified not and:[self isLayoutSpec]]) ifTrue:[ + self layoutRead. + ]. + ^ self + ]. + + view := builderView singleSelection. + + propertyAspects := nil. + currentView := view. + self modified:false. + + + currentView isNil ifTrue:[ + "/ the workView itself. + + propertyList selectionIndex:nil. + currentSpecChannel := nil. + + propertyList list:#(). + propertySpecs := nil. + + "/ must setup for a WindowSpec (to allow entry of min- maxSize etc). +"/ propertyList list:#('Basics' 'Detail'). + ^ self + ]. + + prevSpecClass := specBeingEdited class. + + specBeingEdited := (builderView generateSpecFor:currentView) first. + + (specBeingEdited class ~~ prevSpecClass + or:[currentSpecChannel isNil]) ifTrue:[ + propertyList selectionIndex:nil. + propertyAspects := IdentityDictionary new. + propertySpecs := OrderedCollection new. + slices := currentView specClass slices. + + list := slices collect:[:slice| + propertySpecs add:(slice last). + slice first asString + ]. + + list := list, (Array with:(self class titleOfLayoutMenu)). + + currentSpecChannel := specBeingEdited asValue. + specBeingEdited class addBindingsTo:propertyAspects + for:specBeingEdited + channel:currentSpecChannel. + propertyAspects do:[:anAspect | anAspect addDependent:self ]. + propertyList list:list. + propertyList selection:userSelectedProperty. + ] ifFalse:[ + currentSpecChannel value:specBeingEdited + ] + + +! ! + +!UIPropertyView methodsFor:'change & update'! modified:aState "change state of modification flag @@ -552,86 +622,6 @@ ] ! -setupView:aView - - |slices list| - - currentView == aView ifTrue:[ - ^ self - ]. - - aspects := nil. - currentView := aView. - - propertyList selectionIndex:nil. - - currentView isNil ifTrue:[ - propertyList list:#(). - propertySpecs := nil. - aspects := nil. - self modified:false. - ^ self - ]. - - aspects := IdentityDictionary new. - - #( bottomFraction bottomOffset - leftFraction leftOffset - topFraction topOffset - rightFraction rightOffset - leftAlignmentFraction topAlignmentFraction - ) - do:[:aChannel| - aspects at:aChannel put:(ValueHolder new) - ]. - - specBeingEdited := (receiver generateSpecFor:currentView) first. - - propertySpecs := OrderedCollection new. - slices := currentView specClass slices. - - list := slices collect:[:slice| - propertySpecs add:(slice last). - slice first asString - ]. - - list := list, #( 'Dimension' ). - - specBeingEdited class addBindingsTo:aspects - for:specBeingEdited - channel:nil. - - aspects do:[:anAspect | anAspect addDependent:self ]. - - propertyList list:list. - propertyList selection:userSelectedProperty. - -! ! - -!UIPropertyView methodsFor:'button actions'! - -apply - self modified ifTrue:[ - receiver updateFromSpec:specBeingEdited. - self modified:false. - ] -! - -cancel - |view| - - self modified ifTrue:[ - self modified:false. - - (view := currentView) notNil ifTrue:[ - currentView := nil. - self setupView:view - ]. - ] -! ! - -!UIPropertyView methodsFor:'change & update'! - propertySelectionChanged "called when the property selection changed " @@ -640,37 +630,38 @@ sel := propertyList selection. (currentView isNil or:[sel isNil]) ifTrue:[ + "/ must setup for a WindowSpec for workView (to allow entry of min- maxSize etc). +"/ currentView isNil ifTrue:[ +"/ currentView := receiver +"/ ]. ^ self showSpec:nil ]. index := propertyList selectionIndex. userSelectedProperty := sel. index > propertySpecs size ifTrue:[ "/ one of my specifications - sel = 'Dimension' ifTrue:[ + (sel == self class titleOfLayoutMenu) ifTrue:[ spec := self specificationLayout ] ] ifFalse:[ spec := currentView specClass perform:(propertySpecs at:index). ]. self showSpec:spec. - self modified:false. - ! update:something with:aParameter from:changedObject - self modified ifFalse:[ - self modified:true - ] + self modified:true ! ! !UIPropertyView methodsFor:'initialization'! -in:aTopView receiver:aReceiver +in:aTopView receiver:aBuilderView |menu y cancelButton applyButton panel| super initialize. + self initializeStaticAspects. - receiver := aReceiver. + builderView := aBuilderView. menu := PopUpList label:'properties' in:aTopView. menu defaultLabel:'properties'. @@ -682,7 +673,8 @@ propertyList := SelectionInList new. propertyList list:#( ). - propertyList selectionIndexHolder onChangeSend:#propertySelectionChanged to:self. + propertyList selectionIndexHolder onChangeSend:#propertySelectionChanged + to:self. menu model:propertyList. y := menu preferredExtent y. @@ -698,17 +690,43 @@ builder componentAt:#applyButton put:applyButton. cancelButton action:[ self cancel ]. - applyButton action:[ self apply ]. + applyButton action:[ self apply ]. modified := true. self modified:false. +! + +initializeStaticAspects + + staticAspects := IdentityDictionary new. + + #( bottomFraction bottomOffset + leftFraction leftOffset + topFraction topOffset + rightFraction rightOffset + leftAlignmentFraction topAlignmentFraction + ) + do:[:aChannel| + staticAspects at:aChannel put:(ValueHolder new). + ]. + + staticAspects do:[:anAspect | anAspect addDependent:self ]. + ! ! !UIPropertyView methodsFor:'private'! aspectFor:aKey + |aspect| - ^ aspects at:aKey ifAbsent:[ super aspectFor:aKey ]. + propertyAspects notNil ifTrue:[ + aspect := propertyAspects at:aKey ifAbsent:nil. + aspect notNil ifTrue:[ + ^ aspect + ] + ]. + + ^ staticAspects at:aKey ifAbsent:[super aspectFor:aKey] ! showSpec:aSpec @@ -723,77 +741,158 @@ ] ]. currentSpec := aSpec. + self modified:false. +! ! + +!UIPropertyView methodsFor:'private actions'! + +apply + modified ifTrue:[ + self modified:false. + + self isLayoutSpec ifFalse:[ + builderView updateFromSpec:specBeingEdited + ] ifTrue:[ + self layoutWrite + ] + ] + +! + +cancel + |view| + + modified ifTrue:[ + self modified:false. + + self isLayoutSpec ifFalse:[ + currentView := nil. + self update:#selection + ] ifTrue:[ + self layoutRead + ] + ] + ! ! !UIPropertyView methodsFor:'private layout'! -fetchLayout +layoutRead |layout extent| layout := currentView geometryLayout. layout isNil ifTrue:[^ self]. + modified := true. "supress event notifications" layout isLayout ifFalse:[ - layout isRectangle ifTrue:[ - (aspects at:#leftOffset) value:(layout left). - (aspects at:#rightOffset) value:(layout right). - (aspects at:#topOffset) value:(layout top). - (aspects at:#bottomOffset) value:(layout bottom). + (layout isRectangle or:[layout isPoint]) ifTrue:[ + (staticAspects at:#leftOffset) value:(layout left). + (staticAspects at:#rightOffset) value:(layout right). + + layout isRectangle ifTrue:[ + (staticAspects at:#topOffset) value:(layout top). + (staticAspects at:#bottomOffset) value:(layout bottom). + ]. + modified := false. ^ self - ]. - layout isPoint ifTrue:[ - (aspects at:#leftOffset) value:(layout left). - (aspects at:#rightOffset) value:(layout right). - ^ self - ]. + ] ]. - (aspects at:#leftOffset) value:(layout leftOffset). - (aspects at:#leftFraction) value:(layout leftFraction). - (aspects at:#topOffset) value:(layout topOffset). - (aspects at:#topFraction) value:(layout topFraction). + (staticAspects at:#leftOffset) value:(layout leftOffset). + (staticAspects at:#leftFraction) value:(layout leftFraction). + (staticAspects at:#topOffset) value:(layout topOffset). + (staticAspects at:#topFraction) value:(layout topFraction). layout isLayoutFrame ifTrue:[ - (aspects at:#rightOffset) value:(layout rightOffset). - (aspects at:#bottomOffset) value:(layout bottomOffset). + (staticAspects at:#rightOffset) value:(layout rightOffset). + (staticAspects at:#bottomOffset) value:(layout bottomOffset). - (aspects at:#rightFraction) value:(layout rightFraction). - (aspects at:#bottomFraction) value:(layout bottomFraction). + (staticAspects at:#rightFraction) value:(layout rightFraction). + (staticAspects at:#bottomFraction) value:(layout bottomFraction). - (aspects at:#leftAlignmentFraction) value:0. - (aspects at:#topAlignmentFraction) value:0. + (staticAspects at:#leftAlignmentFraction) value:0. + (staticAspects at:#topAlignmentFraction) value:0. ] ifFalse:[ extent := currentView extent. - (aspects at:#rightOffset) value:(layout leftOffset + extent x). - (aspects at:#bottomOffset) value:(layout topOffset + extent y). + (staticAspects at:#rightOffset) value:(layout leftOffset + extent x). + (staticAspects at:#bottomOffset) value:(layout topOffset + extent y). - (aspects at:#rightFraction) value:0. - (aspects at:#bottomFraction) value:0. + (staticAspects at:#rightFraction) value:0. + (staticAspects at:#bottomFraction) value:0. layout isAlignmentOrigin ifTrue:[ - (aspects at:#leftAlignmentFraction) value:(layout leftAlignmentFraction). - (aspects at:#topAlignmentFraction) value:(layout topAlignmentFraction). + (staticAspects at:#leftAlignmentFraction) value:(layout leftAlignmentFraction). + (staticAspects at:#topAlignmentFraction) value:(layout topAlignmentFraction). ] ifFalse:[ - (aspects at:#leftAlignmentFraction) value:0. - (aspects at:#topAlignmentFraction) value:0. + (staticAspects at:#leftAlignmentFraction) value:0. + (staticAspects at:#topAlignmentFraction) value:0. ] ]. -! - -setAlignmentOrigin - self showSpec:(self class specificationAlignmentOrigin). + modified := false. ! -setLayoutFrame - self showSpec:(self class specificationLayoutFrame). +layoutWrite + |layout| + + currentView isNil ifTrue:[ + ^ self + ]. + + (currentSpec == self class specificationLayoutFrame) ifTrue:[ + layout := LayoutFrame new. + + layout leftOffset:((staticAspects at:#leftOffset) value) ? 0. + layout rightOffset:((staticAspects at:#rightOffset) value) ? 0. + layout topOffset:((staticAspects at:#topOffset) value) ? 0. + layout bottomOffset:((staticAspects at:#bottomOffset) value) ? 0. + layout leftFraction:((staticAspects at:#leftFraction) value) ? 0. + layout rightFraction:((staticAspects at:#rightFraction) value) ? 0. + layout topFraction:((staticAspects at:#topFraction) value) ? 0. + layout bottomFraction:((staticAspects at:#bottomFraction) value) ? 0. + + builderView setDimension:layout + ]. + + (currentSpec == self class specificationAlignmentOrigin) ifTrue:[ + layout := AlignmentOrigin new. + + layout leftOffset:((staticAspects at:#leftOffset) value) ? 0. + layout topOffset:((staticAspects at:#topOffset) value) ? 0. + layout leftFraction:((staticAspects at:#leftFraction) value) ? 0. + layout topFraction:((staticAspects at:#topFraction) value) ? 0. + + layout leftAlignmentFraction:((staticAspects at:#leftAlignmentFraction) value) ? 0. + layout topAlignmentFraction:((staticAspects at:#topAlignmentFraction) value) ? 0. + + ^ builderView setDimension:layout. + ]. + + (currentSpec == self class specificationLayoutOrigin) ifTrue:[ + layout := LayoutOrigin new. + + layout leftOffset:((staticAspects at:#leftOffset) value) ? 0. + layout topOffset:((staticAspects at:#topOffset) value) ? 0. + layout leftFraction:((staticAspects at:#leftFraction) value) ? 0. + layout topFraction:((staticAspects at:#topFraction) value) ? 0. + + builderView setDimension:layout. + ]. + ! -setLayoutOrigin - self showSpec:(self class specificationLayoutOrigin). +showAlignmentOrigin + self switchLayoutSpec:(self class specificationAlignmentOrigin) +! +showLayoutFrame + self switchLayoutSpec:(self class specificationLayoutFrame) +! + +showLayoutOrigin + self switchLayoutSpec:(self class specificationLayoutOrigin) ! specificationLayout @@ -821,8 +920,17 @@ ] ]. - spec notNil ifTrue:[ self fetchLayout]. + spec notNil ifTrue:[ + self layoutRead + ]. ^ spec +! + +switchLayoutSpec:aSpecification + self layoutRead. + self showSpec:aSpecification. + self modified:true. + ! ! !UIPropertyView methodsFor:'private make layout'! @@ -851,16 +959,16 @@ aBool ifTrue:[ offset := offset + ((fraction * extent) asInteger). - (aspects at:offsetSymb) value:offset. - (aspects at:fractSymb) value:0. + (staticAspects at:offsetSymb) value:offset. + (staticAspects at:fractSymb) value:0. ] ifFalse:[ fraction := (fraction + (offset / extent)) asFloat. (fraction > 1.0) ifTrue:[ fraction := 1.0 ]. (fraction < 0.0) ifTrue:[ fraction := 0.0 ]. - (aspects at:offsetSymb) value:0. - (aspects at:fractSymb) value:fraction. + (staticAspects at:offsetSymb) value:0. + (staticAspects at:fractSymb) value:fraction. ] ] @@ -923,6 +1031,14 @@ ! ! +!UIPropertyView methodsFor:'queries'! + +isLayoutSpec + "returns true if current menu is layout + " + ^ propertyList selection == self class titleOfLayoutMenu +! ! + !UIPropertyView class methodsFor:'documentation'! version