diff -r d03569a6ff03 -r d0b5a33e6df0 UIObjectView.st --- a/UIObjectView.st Mon Feb 17 18:22:30 1997 +0100 +++ b/UIObjectView.st Mon Feb 17 18:23:19 1997 +0100 @@ -1,6 +1,5 @@ ObjectView subclass:#UIObjectView - instanceVariableNames:'inputView testMode undoHistory copiedExtent resizedObject - resizeSelector createInWidget createFrame createdObject + instanceVariableNames:'inputView testMode undoHistory copiedExtent actionData createClass clipChildren' classVariableNames:'' poolDictionaries:'' @@ -8,12 +7,19 @@ ! Object subclass:#UndoHistory - instanceVariableNames:'history transaction enabled modifiedAction' + instanceVariableNames:'history transaction enabled' classVariableNames:'' poolDictionaries:'' privateIn:UIObjectView ! +Object subclass:#Transaction + instanceVariableNames:'type text actions' + classVariableNames:'' + poolDictionaries:'' + privateIn:UIObjectView::UndoHistory +! + !UIObjectView class methodsFor:'defaults'! @@ -109,6 +115,22 @@ ! ! +!UIObjectView methodsFor:'blocked'! + +addObject:anObject + "add the argument, anObject to the contents - with redraw" + + self halt + +! + +addObjectWithoutRedraw:anObject + "add the argument, anObject to the contents - with redraw" + + self halt + +! ! + !UIObjectView methodsFor:'event handling'! doKeyInput:key @@ -215,13 +237,8 @@ self setDefaultActions. - undoHistory := UndoHistory new. - - undoHistory modifiedAction:[:what| - self changed:#undoHistory with:what - ]. - - testMode := false. + undoHistory := UndoHistory new. + testMode := false. clipChildren := true. (self class gridShown) ifTrue:[ @@ -293,25 +310,80 @@ !UIObjectView methodsFor:'object creation'! +actionCreate:anObject frame:aFrame delta:aDelta + "create and initialize action data + " + |extent x y selectors values| + +"minimum extent +" + extent := self extent. + x := extent x // 3. + y := extent y // 3. + extent := anObject preferredExtent. + + (extent x > x) ifTrue:[extent x:x]. + (extent y > y) ifTrue:[extent y:y]. + +"setup structure +" + selectors := #( object frame delta vertical horizontal minExtent ). + values := Array new:(selectors size). + + values at:1 put:anObject. + values at:2 put:aFrame. + values at:3 put:aDelta. + values at:4 put:(self isVerticalResizable:anObject). + values at:5 put:(self isHorizontalResizable:anObject). + values at:6 put:extent. + + actionData := Structure newWith:selectors values:values. + + +"can change cursor dependent on vertical/horizontal resizing +" + oldCursor := cursor. + self cursor:(Cursor leftHand). + + + +! + +createWidgetWithClass:aClass + "prepare to create new widgets + " + createClass := aClass. + pressAction := [:pressPoint | self startCreate:pressPoint]. + self cursor:Cursor origin. + + +! + doDragCreate:aPoint "do a widget create drag " - |p| - - p := self alignToGrid:aPoint. - createFrame corner:(p - (createInWidget originRelativeTo:self)). - - (createFrame extent x < 10) ifTrue:[ - createFrame extent x:10 + |frame object extent minimum| + + frame := actionData frame. + frame corner:((self alignToGrid:aPoint) - (actionData delta)). + + object := actionData object. + minimum := actionData minExtent. + extent := frame extent. + + ((extent x < minimum x) or:[actionData horizontal not]) ifTrue:[ + extent x:(minimum x) ]. - (createFrame extent y < 10) ifTrue:[ - createFrame extent y:10 + ((extent y < minimum y) or:[actionData vertical not]) ifTrue:[ + extent y:(minimum y) ]. - self invertOutlineOf:createdObject. - createdObject origin:(createFrame origin) extent:(createFrame extent). - self invertOutlineOf:createdObject. + frame extent:extent. + + self invertOutlineOf:object. + object origin:(frame origin) extent:(frame extent). + self invertOutlineOf:object. ! endCreate @@ -319,15 +391,15 @@ " |layout x y| - self invertOutlineOf:createdObject. + self invertOutlineOf:(actionData object). inputView raise. - layout := createdObject bounds asLayout. - createdObject geometryLayout:layout. + layout := (actionData object) bounds asLayout. + (actionData object) geometryLayout:layout. self changed:#tree. - self select:createdObject. - createdObject := nil. + self select:(actionData object). + actionData := nil. self setDefaultActions. @@ -340,7 +412,7 @@ startCreate:aPoint "start a widget create " - |startPoint| + |widget object start frame delta| createClass isNil ifTrue:[ ^ self setDefaultActions @@ -350,35 +422,33 @@ ^ self setDefaultActions. ]. - startPoint := self alignToGrid:aPoint. motionAction := [:movePoint| self doDragCreate:movePoint]. releaseAction := [ self endCreate]. selection notNil ifTrue:[ ( (self isPoint:aPoint containedIn:selection) - and:[selection specClass basicNew supportsSubComponents] + and:[self supportsSubComponents:selection] ) ifFalse:[ self unselect ] ]. - oldCursor := cursor. - self cursor:(Cursor leftHand). - - createInWidget := selection ? self. - createdObject := createClass new. - createInWidget addSubView:createdObject. - - createFrame := Rectangle origin:(startPoint - (createInWidget originRelativeTo:self)) - corner:startPoint. - - createdObject origin:(createFrame origin). - - undoHistory transactionNamed:'create' do:[ - self setupCreatedObject:createdObject. - ]. - createdObject realize. - self invertOutlineOf:createdObject. + widget := selection ? self. + object := createClass new. + widget addSubView:object. + + start := self alignToGrid:aPoint. + delta := widget originRelativeTo:self. + frame := Rectangle origin:(start - delta) corner:start. + + object origin:(frame origin). + self setupCreatedObject:object. + object realize. + + self actionCreate:object frame:frame delta:delta. + self invertOutlineOf:object. + + ! ! !UIObjectView methodsFor:'object moving'! @@ -419,6 +489,26 @@ ]. ! +moveObject:anObject to:aPoint + "move anObject to newOrigin, aPoint + " + |dX dY org delta| + + anObject notNil ifTrue:[ + org := anObject computeOrigin. + + delta := aPoint - org. + delta := (self alignToGrid:aPoint) - org. + dX := delta x. + dY := delta y. + + undoHistory disabledTransitionDo:[ + self shifLayout:anObject top:dY bottom:dY left:dX right:dX + ] + ] + +! + startObjectMoveAt:aPoint self startObjectMove:selection at:aPoint. @@ -434,12 +524,13 @@ aPoint - aView computeOrigin ]. - undoHistory transactionNamed:'move' do:[ - movedObject do:[:aView| - self invertOutlineOf:aView. - self undoBlockPositionChanged:aView - ] - ] + selection := movedObject. + self transaction:#move selectionDo:[:aView| + self invertOutlineOf:aView. + self undoBlockPositionChanged:aView + ]. + selection := nil + ! startSelectMoreOrMove:aPoint @@ -472,7 +563,7 @@ b := self whichHandleOf:selection isHitBy:aPoint. (b notNil and:[b ~~ #view]) ifTrue:[ - ^ self startResizeBorder:b of:selection at:aPoint. + ^ self startResizeBorder:b of:selection. ] ]. @@ -501,12 +592,80 @@ "prepare move operation for an object " motionAction := [:movePoint| - (aPoint dist:movePoint) > 2.0 ifTrue:[ + (aPoint dist:movePoint) > 4.0 ifTrue:[ self startObjectMoveAt:aPoint ] ]. ! ! +!UIObjectView methodsFor:'object resize'! + +actionResize:anObject selector:aSelector + "create and initialize action for resize + " + |selector delta| + + delta := anObject container originRelativeTo:self. + selector := ('resize:', aSelector, ':') asSymbol. + + actionData := Structure with:(#object->anObject) + with:(#selector->selector) + with:(#delta->delta). + +"can change cursor dependent on vertical/horizontal resizing +" + oldCursor := cursor. + self cursor:(Cursor leftHand). + + + +! + +doDragResize:aPoint + "do a widget resize drag" + + |p object| + + object := actionData object. + + self invertOutlineOf:object. + p := (self alignToGrid:aPoint) - (actionData delta). + self perform:(actionData selector) with:object with:p. + object geometryLayout:(object geometryLayout). + self invertOutlineOf:object + +! + +endResize + "cleanup after object resize" + + self invertOutlineOf:(actionData object). + self setDefaultActions. + self select:(actionData object). + actionData := nil + + "Modified: 5.9.1995 / 17:11:17 / claus" + +! + +startResizeBorder:b of:selection + "resize selected view + " + |object| + + object := self singleSelection. + self actionResize:object selector:b. + + self transaction:#extent selectionDo:[:aView| + self undoBlockDimensionChanged:aView + ]. + super unselect. + + motionAction := [:movePoint | self doDragResize:movePoint]. + releaseAction := [self endResize]. + self invertOutlineOf:object +! ! + !UIObjectView methodsFor:'private handles'! handlesOf:aComponent do:aBlock @@ -545,7 +704,6 @@ aBlock value:(aComponent bottomLeft + delta) value:#view. ]. - ! showSelected:aComponent @@ -616,7 +774,7 @@ ]. ]. - ^ #view + ^ nil "Modified: 5.9.1995 / 14:39:34 / claus" @@ -631,6 +789,19 @@ ] ! +resize:aView bottomLeft:aPoint + + undoHistory disabledTransitionDo:[ + self shifLayout:aView top:0 + bottom:((aPoint y) - (aView computeCorner y)) + left:((aPoint x) - (aView computeOrigin x)) + right:0 + + ] + + +! + resize:aView corner:aPoint |delta| @@ -649,6 +820,17 @@ ! +resize:aView origin:aPoint + |delta| + + delta := aPoint - aView computeOrigin. + + undoHistory disabledTransitionDo:[ + self shifLayout:aView top:(delta y) bottom:0 left:(delta x) right:0 + ] + +! + resize:aView right:aPoint undoHistory disabledTransitionDo:[ @@ -661,21 +843,33 @@ undoHistory disabledTransitionDo:[ self shifLayout:aView top:((aPoint y) - (aView computeOrigin y)) bottom:0 ] +! + +resize:aView topRight:aPoint + + undoHistory disabledTransitionDo:[ + self shifLayout:aView top:((aPoint y) - (aView computeOrigin y)) + bottom:0 + left:0 + right:((aPoint x) - (aView computeCorner x)) + + ] + ! ! !UIObjectView methodsFor:'private shift-layout'! shifLayout:aView left:l right:r - "shift layout for a view; in case of an open transaction, the - undoAction will be defined + "shift layout for a view; in case of an open transaction, the undo + action is registered " self shifLayout:aView top:0 bottom:0 left:l right:r ! shifLayout:aView top:t bottom:b - "shift layout for a view; in case of an open transaction, the - undoAction will be defined + "shift layout for a view; in case of an open transaction, the undo + action is registered " self shifLayout:aView top:t bottom:b left:0 right:0 @@ -683,8 +877,8 @@ ! shifLayout:aView top:t bottom:b left:l right:r - "shift layout for a view; in case of an open transaction, the - undoAction will be defined + "shift layout for a view; in case of an open transaction, the undo + action is registered " |layout| @@ -706,34 +900,6 @@ ! ! -!UIObjectView methodsFor:'private undo-actions'! - -undoBlockDimensionChanged:aView - - undoHistory isTransactionOpen ifTrue:[ - |layout| - - layout := aView geometryLayout copy. - - undoHistory addUndoBlock:[ - aView geometryLayout:layout. - aView superView sizeChanged:nil. - ] - ] - -! - -undoBlockPositionChanged:aView - - undoHistory isTransactionOpen ifTrue:[ - |layout| - - layout := aView geometryLayout copy. - undoHistory addUndoBlock:[aView geometryLayout:layout] - ] - -! ! - !UIObjectView methodsFor:'searching'! findObjectAt:aPoint @@ -921,26 +1087,84 @@ ^ self subclassResponsibility +! + +supportsSubComponents:something + "returns true if somrthing supports subcomponents + " + |specClass| + + something notNil ifTrue:[ + something isCollection ifFalse:[ + specClass := something specClass + ] ifTrue:[ + something size == 1 ifTrue:[ + specClass := (something at:1) specClass + ] + ]. + specClass notNil ifTrue:[ + ^ specClass basicNew supportsSubComponents + ] + ]. + ^ false ! ! -!UIObjectView methodsFor:'user actions'! - -createWidgetWithClass:aClass - "prepare to create new widgets +!UIObjectView methodsFor:'transaction & undo'! + +transaction:aType objects:something do:aOneArgBlock + "opens a transaction and evaluates a block within the transaction; the + argument to the block is a view from derived from something " - createClass := aClass. - pressAction := [:pressPoint | self startCreate:pressPoint]. - self cursor:Cursor origin. + self subclassResponsibility ! -undoAction - undoHistory notEmpty ifTrue:[ - self unselect. - undoHistory undoLast +transaction:aType selectionDo:aOneArgBlock + "opens a transaction and evaluates a block within the transaction; the + argument to the block is a view from the selection + " + self transaction:aType objects:selection do:aOneArgBlock + + +! + +undoBlockDimensionChanged:aView + + undoHistory isTransactionOpen ifTrue:[ + |layout| + + layout := aView geometryLayout copy. + + undoHistory addUndoBlock:[ + aView geometryLayout:layout. + aView superView sizeChanged:nil. + ] ] +! + +undoBlockPositionChanged:aView + + undoHistory isTransactionOpen ifTrue:[ + |layout| + + layout := aView geometryLayout copy. + undoHistory addUndoBlock:[aView geometryLayout:layout] + ] + +! + +undoLast + self undoLast:1 +! + +undoLast:n + + self unselect. + undoHistory undoLast:n. + self changed:#tree + ! ! @@ -958,7 +1182,7 @@ pasteExtent copiedExtent notNil ifTrue:[ - self transition:'paste extent' dimensionDo:[:v| + self transition:#extent dimensionDo:[:v| self resize:v corner:(v computeOrigin + copiedExtent) ] ] @@ -983,26 +1207,28 @@ ! setDimension:aLayout - |undoText| - - undoText := 'change layout'. + |type| + aLayout isLayout ifTrue:[ - undoText := 'change to layout frame'. - aLayout isAlignmentOrigin ifTrue:[ - undoText := 'change to layout alignOrigin'. + aLayout isLayoutFrame ifTrue:[ + type := #layoutFrame ] ifFalse:[ aLayout isAlignmentOrigin ifTrue:[ - undoText := 'change to layout origin'. + type := #layoutAlignOrigin. + ] ifFalse:[ + type := #layoutOrigin ] ] + ] ifFalse:[ + type := #layout ]. - self transition:undoText dimensionDo:[:v| v geometryLayout:(aLayout copy)] + self transition:type dimensionDo:[:v| v geometryLayout:(aLayout copy)] ! setToDefaultExtent - self transition:'default extent' dimensionDo:[:v| + self transition:#extent dimensionDo:[:v| self resize:v corner:(v computeOrigin + (v preferredExtent)) ] @@ -1022,18 +1248,17 @@ ! -transition:what dimensionDo:aOneArgBlock +transition:aType dimensionDo:aOneArgBlock "change dimension within a transaction for the selected elements by evaluating the block with the argument a view. " self selectionHiddenDo:[ - undoHistory transactionNamed:what do:[ - self selectionDo:[:aView| - self undoBlockDimensionChanged:aView. - aOneArgBlock value:aView. - self elementChangedLayout:aView. - ] - ] + self transaction:aType selectionDo:[:aView| + self undoBlockDimensionChanged:aView. + aOneArgBlock value:aView. + aView superView sizeChanged:nil + ]. + self changed:#layout ] ! ! @@ -1044,9 +1269,7 @@ move right: n > 0 " self selectionHiddenDo:[ - undoHistory transactionNamed:'move' do:[ - self selectionDo:[:aView|self shifLayout:aView left:n right:n] - ]. + self transaction:#move selectionDo:[:v| self shifLayout:v left:n right:n]. self changed:#layout ] @@ -1058,9 +1281,7 @@ move down: n > 0 " self selectionHiddenDo:[ - undoHistory transactionNamed:'move' do:[ - self selectionDo:[:aView| self shifLayout:aView top:n bottom:n ] - ]. + self transaction:#move selectionDo:[:v| self shifLayout:v top:n bottom:n ]. self changed:#layout ] @@ -1068,27 +1289,6 @@ ! -moveObject:anObject to:aPoint - "move anObject to newOrigin, aPoint - " - |dX dY org delta| - - anObject notNil ifTrue:[ - org := anObject computeOrigin. - - delta := aPoint - org. - delta := (self alignToGrid:aPoint) - org. - dX := delta x. - dY := delta y. - - undoHistory disabledTransitionDo:[ - self shifLayout:anObject top:dY bottom:dY left:dX right:dX - ]. - self elementChangedLayout:anObject. - ] - -! - moveSelectionDown self moveSelectionDown:1 @@ -1170,11 +1370,9 @@ bmost := 0. self selectionDo:[:v| bmost := bmost max:(v computeCorner y)]. - undoHistory transactionNamed:'align' do:[ - self selectionDo:[:v| - (delta := bmost - (v computeCorner y)) ~~ 0 ifTrue:[ - self shifLayout:v top:delta bottom:delta - ] + self transaction:#align selectionDo:[:v| + (delta := bmost - (v computeCorner y)) ~~ 0 ifTrue:[ + self shifLayout:v top:delta bottom:delta. ] ]. self changed:#layout @@ -1197,16 +1395,14 @@ ]. centerX := centerX // (counter * 2). - undoHistory transactionNamed:'align' do:[ + self transaction:#align selectionDo:[:v| |newX oldX delta| - self selectionDo:[:v| - oldX := v computeOrigin x. - newX := centerX - ((v computeCorner x - oldX) // 2). - delta := newX - oldX. - - self shifLayout:v left:delta right:delta - ] + oldX := v computeOrigin x. + newX := centerX - ((v computeCorner x - oldX) // 2). + delta := newX - oldX. + + self shifLayout:v left:delta right:delta ]. self changed:#layout ] @@ -1228,16 +1424,14 @@ ]. centerY := centerY // (counter * 2). - undoHistory transactionNamed:'align' do:[ + self transaction:#align selectionDo:[:v| |newY oldY delta| - self selectionDo:[:v| - oldY := v computeOrigin y. - newY := centerY - ((v computeCorner y - oldY) // 2). - delta := newY - oldY. - - self shifLayout:v top:delta bottom:delta - ] + oldY := v computeOrigin y. + newY := centerY - ((v computeCorner y - oldY) // 2). + delta := newY - oldY. + + self shifLayout:v top:delta bottom:delta ]. self changed:#layout ] @@ -1249,11 +1443,9 @@ self selectionHiddenDo:[ lmost := self selectionFindMinimum:[:v| v computeOrigin x]. - undoHistory transactionNamed:'align' do:[ - self selectionDo:[:v| - (delta := lmost - (v computeOrigin x)) ~~ 0 ifTrue:[ - self shifLayout:v left:delta right:delta - ] + self transaction:#align selectionDo:[:v| + (delta := lmost - (v computeOrigin x)) ~~ 0 ifTrue:[ + self shifLayout:v left:delta right:delta ] ]. self changed:#layout @@ -1269,11 +1461,9 @@ rmost := 0. self selectionDo:[:v | rmost := rmost max:(v computeCorner x)]. - undoHistory transactionNamed:'align' do:[ - self selectionDo:[:v| - self shifLayout:v left:(lmost - (v computeOrigin x)) - right:(rmost - (v computeCorner x)) - ] + self transaction:#align selectionDo:[:v| + self shifLayout:v left:(lmost - (v computeOrigin x)) + right:(rmost - (v computeCorner x)) ]. self changed:#layout ] @@ -1286,11 +1476,9 @@ rmost := 0. self selectionDo:[:v| rmost := rmost max:(v computeCorner x)]. - undoHistory transactionNamed:'align' do:[ - self selectionDo:[:v| - (delta := rmost - (v computeCorner x)) ~~ 0 ifTrue:[ - self shifLayout:v left:delta right:delta - ] + self transaction:#align selectionDo:[:v| + (delta := rmost - (v computeCorner x)) ~~ 0 ifTrue:[ + self shifLayout:v left:delta right:delta ] ]. self changed:#layout @@ -1304,11 +1492,9 @@ self selectionHiddenDo:[ tmost := self selectionFindMinimum:[:v| v computeOrigin y]. - undoHistory transactionNamed:'align' do:[ - self selectionDo:[:v||delta| - (delta := tmost - (v computeOrigin y)) ~~ 0 ifTrue:[ - self shifLayout:v top:delta bottom:delta - ] + self transaction:#align selectionDo:[:v| + (delta := tmost - (v computeOrigin y)) ~~ 0 ifTrue:[ + self shifLayout:v top:delta bottom:delta ] ]. self changed:#layout @@ -1324,17 +1510,15 @@ bmost := 0. self selectionDo:[:v| bmost := bmost max:(v computeCorner y)]. - undoHistory transactionNamed:'align' do:[ - self selectionDo:[:v| - self shifLayout:v top:(tmost - (v computeOrigin y)) - bottom:(bmost - (v computeCorner y)) - ] + self transaction:#align selectionDo:[:v| + self shifLayout:v top:(tmost - (v computeOrigin y)) + bottom:(bmost - (v computeCorner y)) ]. self changed:#layout ] ! -centerSelection:aOneArgBlockXorY +centerSelection:aOneArgBlockXorY orientation:orientation "center selection horizontal or vertical dependant on the block result( x or y). The argument to the block is the point. " @@ -1366,12 +1550,15 @@ max == min ifFalse:[ delta := max - min. - undoHistory transactionNamed:'center' do:[ - self selectionDo:[:aView| - self shifLayout:aView top:delta bottom:delta] - ] - ]. - self changed:#layout + self transaction:#center selectionDo:[:v| + orientation == #y ifTrue:[ + self shifLayout:v top:delta bottom:delta + ] ifFalse:[ + self shifLayout:v left:delta right:delta + ] + ]. + self changed:#layout + ] ] @@ -1380,7 +1567,7 @@ centerSelectionHor "center selection horizontal " - self centerSelection:[:aPoint| aPoint x] + self centerSelection:[:aPoint| aPoint x] orientation:#x ! @@ -1388,7 +1575,7 @@ centerSelectionVer "center selection vertical " - self centerSelection:[:aPoint| aPoint y] + self centerSelection:[:aPoint| aPoint y] orientation:#y ! spreadSelectionHor @@ -1416,14 +1603,12 @@ space := (((max - min) - sumWidths) / (count - 1)) rounded asInteger. - undoHistory transactionNamed:'spread' do:[ - viewsInOrder do:[:aView | - |delta| - - delta := min - aView computeOrigin x. - self shifLayout:aView left:delta right:delta. - min := min + aView computeExtent x + space - ] + self transaction:#spread objects:viewsInOrder do:[:aView| + |delta| + + delta := min - aView computeOrigin x. + self shifLayout:aView left:delta right:delta. + min := min + aView computeExtent x + space ]. self changed:#layout ] @@ -1455,108 +1640,17 @@ space := (((max - min) - sumHeights) / (count - 1)) rounded asInteger. - undoHistory transactionNamed:'spread' do:[ - viewsInOrder do:[:aView||delta| - delta := min - aView computeOrigin y. - self shifLayout:aView top:delta bottom:delta. - min := min + aView height + space - ] + self transaction:#spread objects:viewsInOrder do:[:aView| + |delta| + + delta := min - aView computeOrigin y. + self shifLayout:aView top:delta bottom:delta. + min := min + aView height + space ]. self changed:#layout ] ! ! -!UIObjectView methodsFor:'user actions - resize'! - -doDragResize:aPoint - "do a widget resize drag" - - |p| - - self invertOutlineOf:resizedObject. - p := (self alignToGrid:aPoint) - (resizedObject container originRelativeTo:self). - self perform:('x' , resizeSelector , ':') asSymbol with:p. - resizedObject geometryLayout:(resizedObject geometryLayout). - self invertOutlineOf:resizedObject - - "Modified: 5.9.1995 / 17:11:46 / claus" - -! - -endResize - "cleanup after object resize" - - self invertOutlineOf:resizedObject. - self setDefaultActions. - self select:resizedObject. - resizedObject := nil - - "Modified: 5.9.1995 / 17:11:17 / claus" - -! - -startResizeBorder:b of:selection at:aPoint - "resize selected view - " - resizedObject := self singleSelection. - - resizedObject notNil ifTrue:[ - resizeSelector := b. - super unselect. - - undoHistory transactionNamed:'extent' do:[ - self undoBlockDimensionChanged:resizedObject. - ]. - - motionAction := [:movePoint | self doDragResize:movePoint]. - releaseAction := [self endResize]. - self invertOutlineOf:resizedObject - ] -! - -xbottom:aPoint - self resize:resizedObject bottom:aPoint - -! - -xbottomLeft:aPoint - self resize:resizedObject left:aPoint. - self resize:resizedObject bottom:aPoint. - -! - -xcorner:aPoint - self resize:resizedObject corner:aPoint. - -! - -xleft:aPoint - self resize:resizedObject left:aPoint - -! - -xorigin:aPoint - self resize:resizedObject left:aPoint. - self resize:resizedObject top:aPoint. - -! - -xright:aPoint - self resize:resizedObject right:aPoint - -! - -xtop:aPoint - self resize:resizedObject top:aPoint - -! - -xtopRight:aPoint - self resize:resizedObject right:aPoint. - self resize:resizedObject top:aPoint. - -! ! - !UIObjectView::UndoHistory class methodsFor:'constants'! maxHistorySize @@ -1578,13 +1672,8 @@ !UIObjectView::UndoHistory methodsFor:'accessing'! -modifiedAction:aBlockWithOneArg - "the block is evaluated whenever the history changed; the argument to the - block is the newest transaction identifier retrived from 'openTransaction' - " - modifiedAction := aBlockWithOneArg - - +historySize + ^ history size ! ! !UIObjectView::UndoHistory methodsFor:'initialization'! @@ -1599,27 +1688,24 @@ reinitialize "reinitialize all attributes " - history := OrderedCollection new. + history := OrderedCollection new. transaction := nil. - enabled := true. + enabled := true. ! ! -!UIObjectView::UndoHistory methodsFor:'notifications'! - -modified - "raise notification; history changed +!UIObjectView::UndoHistory methodsFor:'menu'! + +popupMenu + "returns a submenu for undo " - modifiedAction notNil ifTrue:[ - |what| - - history isEmpty ifTrue:[what := nil] - ifFalse:[what := history last first]. - - modifiedAction value:what - ] - + |labels| + + labels := OrderedCollection new:(history size). + history reverseDo:[:aRecord| labels add:(aRecord asString) ]. + + ^ PopUpMenu labels:labels selectors:#undoLast:. ! ! @@ -1650,36 +1736,8 @@ addUndoBlock:anUndoBlock "undo block to restore changes; add block to current transaction " - enabled ifTrue:[ - transaction isNil ifTrue:[ - "no existing transaction - " - self halt - ] ifFalse:[ - (transaction at:2) add:anUndoBlock - ] - ] - - -! - -closeTransaction - "close current transaction - " self isTransactionOpen ifTrue:[ - transaction last isEmpty ifTrue:[ - "empty undo transaction - " - transaction := nil - ] ifFalse:[ - history addLast:transaction. - transaction := nil. - - history size > (self class maxHistorySize) ifTrue:[ - history removeFirst - ]. - self modified - ] + transaction add:anUndoBlock ] @@ -1696,68 +1754,140 @@ enabled := oldState. ! -openTransaction:what - "open a new transaction - " - enabled ifTrue:[ - transaction notNil ifTrue:[ - "transaction within transaction - " - self halt. - ] ifFalse:[ - transaction := Array with:what with:OrderedCollection new - ] - ] - +transaction:aType do:aBlock + self transaction:aType text:nil do:aBlock ! -transactionNamed:what do:aBlock +transaction:aType text:aTextOrNil do:aBlock "open a transaction; perform the block; at least close the transaction " - self isTransactionOpen ifFalse:[ - self openTransaction:what. + (enabled and:[transaction isNil]) ifTrue:[ + transaction := Transaction type:aType text:aTextOrNil. + aBlock value. - self closeTransaction - ] ifTrue:[ + + transaction isEmpty ifFalse:[ + history addLast:transaction. + history size > (self class maxHistorySize) ifTrue:[history removeFirst] + ]. + transaction := nil + + ] ifFalse:[ aBlock value ] ! ! !UIObjectView::UndoHistory methodsFor:'undo'! -undoLast - "undo last transactions; an open transaction will be closed; - transactions during undo are disabled - " - self undoLast:1 - - -! - undoLast:nTransactions "undo last n transactions; an open transaction will be closed; transactions during undo are disabled " - |actions n| + |n| transaction := nil. n := nTransactions min:(history size). n ~~ 0 ifTrue:[ enabled := false. - - n timesRepeat:[ - actions := (history removeLast) last. - - actions reverseDo:[:aUndoBlock| - aUndoBlock value - ] + n timesRepeat:[ (history removeLast) undo ]. + enabled := true. + ] + + +! ! + +!UIObjectView::UndoHistory::Transaction class methodsFor:'instance creation'! + +type:aType text:aTextOrNil + ^ self new type:aType text:aTextOrNil + + +! ! + +!UIObjectView::UndoHistory::Transaction methodsFor:'accessing'! + +asString + "returns printable string + " + |string| + + string := type asString. + + text notNil ifTrue:[^ string, ' ', text ] + ifFalse:[^ string ] +! + +text + "returns text or nil assigned to transition + " + ^ text +! + +type + "returns type assigned to transition + " + ^ type +! + +type:aType + "change type assigned to transition + " + type := aType +! ! + +!UIObjectView::UndoHistory::Transaction methodsFor:'add & undo'! + +add:anUndoBlock + "add an undo action to the transition + " + actions isNil ifTrue:[ + actions := anUndoBlock + ] ifFalse:[ + actions isCollection ifFalse:[ + |temp| + + temp := OrderedCollection new. + temp add:actions. + actions := temp. ]. - enabled := true. - self modified. + actions add:anUndoBlock. + ] +! + +undo + "undo transition + " + actions notNil ifTrue:[ + actions isCollection ifFalse:[ + actions value + ] ifTrue:[ + actions reverseDo:[:anUndoBlock| anUndoBlock value ] + ] ] - - +! ! + +!UIObjectView::UndoHistory::Transaction methodsFor:'initialization'! + +type:aType text:aTextOrNil + "initialize transition + " + type := aType. + text := aTextOrNil. +! ! + +!UIObjectView::UndoHistory::Transaction methodsFor:'testing'! + +isEmpty + "returns true if no undo action is registered + " + ^ actions isNil +! + +notEmpty + "returns true if any undo action is registered + " + ^ actions notNil ! ! !UIObjectView class methodsFor:'documentation'!