"
COPYRIGHT (c) 1995 by Claus Gittinger
All Rights Reserved
This software is furnished under a license and may be used
only in accordance with the terms of that license and with the
inclusion of the above copyright notice. This software may not
be provided or otherwise made available to, or used by, any
other person. No title to or ownership of the software is
hereby transferred.
"
Controller subclass:#VariablePanelController
instanceVariableNames:'movedHandle prevPos startPos clickPos'
classVariableNames:'OpaqueResize'
poolDictionaries:''
category:'Interface-Support-Controllers'
!
!VariablePanelController class methodsFor:'documentation'!
copyright
"
COPYRIGHT (c) 1995 by Claus Gittinger
All Rights Reserved
This software is furnished under a license and may be used
only in accordance with the terms of that license and with the
inclusion of the above copyright notice. This software may not
be provided or otherwise made available to, or used by, any
other person. No title to or ownership of the software is
hereby transferred.
"
!
documentation
"
An abstract class for variablePanel controllers;
normally, not used directly by applications, these are created automatically
whenever a variablePanel is created.
Instances are responsible for tracking the mouse pointer and resize the
views (a panel) subviews as appropriate.
[author:]
Claus Gittinger
"
! !
!VariablePanelController class methodsFor:'defaults'!
opaqueResize
"return the sopaque-resizing flag setting.
If off (the default), the resizing takes place at the end of
the handle move operation (when the mouse button is released).
If on, the resizing is syncronous with the move.
On slow machines, it may make sense to leave it off."
^ OpaqueResize
"Created: / 19.11.1998 / 12:35:26 / cg"
!
opaqueResize:aBoolean
"set/clear opaque-resizing.
If off (the default), the resizing takes place at the end of
the handle move operation (when the mouse button is released).
If on, the resizing is syncronous with the move.
On slow machines, it may make sense to leave it off."
OpaqueResize := aBoolean.
"
self opaqueResize:true
self opaqueResize:false
"
"Modified: / 13.11.1998 / 15:16:37 / cg"
! !
!VariablePanelController methodsFor:'event handling'!
buttonMotion:state x:bx y:by
"mouse-button was moved while pressed;
clear prev handleBar and draw handle bar at new position"
|pos limitMin limitMax subViews barHeight
oldHx oldHy newHx newHy|
movedHandle isNil ifTrue: [^ self]. "should not happen"
"speedup - if there is already another movement,
ignore thisone ... "
view buttonMotionEventPending ifTrue:[^ self].
subViews := view subViews.
barHeight := view barHeight.
view orientation ~~ #vertical ifTrue:[
pos := bx - startPos.
"
the two lines below will not allow resizing down to zero
(so that some is always visible)
"
"/ limitMin := barHeight // 2.
"/ limitMax := view width - barHeight.
"
these allow resizing to zero - which is better ?
"
limitMin := 0.
limitMax := view innerWidth.
movedHandle > 1 ifTrue:[
limitMin := (subViews at:movedHandle) origin x + (barHeight // 2)
].
movedHandle < (subViews size - 1) ifTrue:[
limitMax := (subViews at:(movedHandle + 2)) origin x - barHeight
].
] ifFalse:[
pos := by - startPos.
"
the two lines below will not allow resizing down to zero
(so that some is always visible)
"
"/ limitMin := barHeight // 2.
"/ limitMax := view height - barHeight.
"
these allow resizing to zero - which is better ?
"
limitMin := 0.
limitMax := view innerHeight.
movedHandle > 1 ifTrue:[
limitMin := (subViews at:movedHandle) origin y + (barHeight // 2)
].
movedHandle < (subViews size - 1) ifTrue:[
limitMax := (subViews at:(movedHandle + 2)) origin y - barHeight
].
].
limitMax := limitMax - barHeight.
(pos < limitMin) ifTrue:[ "check against view limits"
pos := limitMin
] ifFalse:[
(pos > limitMax) ifTrue:[
pos := limitMax
]
].
prevPos == pos ifTrue:[^ self].
view orientation ~~ #vertical ifTrue:[
oldHx := prevPos.
newHx := pos.
oldHy := newHy := 0.
] ifFalse:[
oldHy := prevPos.
newHy := pos.
oldHx := newHx := 0.
].
OpaqueResize ~~ true ifTrue:[
view invertHandleBarAtX:oldHx y:oldHy.
view invertHandleBarAtX:newHx y:newHy.
].
prevPos := pos.
OpaqueResize == true ifTrue:[
"/ simulate buttonRelease and repress,
"/ to force immediate change
self buttonRelease:1 x:bx y:by.
self buttonPress:1 x:bx y:by.
]
"Modified: / 13.11.1998 / 15:13:47 / cg"
!
buttonPress:button x:bx y:by
"button was pressed - if it hits a handle, start move"
|handle barHeight group isHorizontal|
((button == 1) or:[button == #select]) ifTrue:[
handle := 1.
barHeight := view barHeight.
isHorizontal := view orientation ~~ #vertical.
"
search the handle, invert the first time
"
view handleOriginsWithIndexDo:[:hPoint :hIndex |
|hx hy thatsTheHandle|
thatsTheHandle := false.
isHorizontal ifTrue:[
hx := hPoint x.
hy := 0.
(bx between:(hx - barHeight) and:(hx + barHeight)) ifTrue:[
prevPos := hx.
startPos := bx - hx.
thatsTheHandle := true.
].
] ifFalse:[
hx := 0.
hy := hPoint y.
(by between:(hy - barHeight) and:(hy + barHeight)) ifTrue:[
prevPos := hy.
startPos := by - hy.
thatsTheHandle := true.
].
].
thatsTheHandle ifTrue:[
movedHandle := handle.
OpaqueResize ~~ true ifTrue:[
view grabPointer.
view invertHandleBarAtX:hx y:hy.
].
(group := view windowGroup) notNil ifTrue:[
group showCursor:view cursor
].
clickPos := bx @ by.
^ self
].
handle := handle + 1
].
movedHandle := nil
] ifFalse:[
super buttonPress:button x:bx y:by
]
"Modified: / 13.11.1998 / 15:18:10 / cg"
!
buttonRelease:button x:bx y:by
"end bar-move"
|aboveView belowView aboveIndex belowIndex
newPos oldPos group subViews
relCornerAbove fromIndex toIndex
hX hY isHorizontal newCorner newOrigin|
((button == 1) or:[button == #select]) ifTrue:[
movedHandle isNil ifTrue:[^ self].
isHorizontal := view orientation ~~ #vertical.
OpaqueResize ~~ true ifTrue:[
view ungrabPointer.
].
(group := view windowGroup) notNil ifTrue:[
group restoreCursors
].
"undo the last invert"
isHorizontal ifTrue:[
hX := prevPos. hY := 0.
] ifFalse:[
hX := 0. hY := prevPos.
].
OpaqueResize ~~ true ifTrue:[
view invertHandleBarAtX:hX y:hY.
].
"/ any change ?
((isHorizontal and:[bx == clickPos x])
or:[isHorizontal not and:[by == clickPos y]]) ifTrue:[
movedHandle := nil.
^ self.
].
"compute the new relative heights"
aboveIndex := movedHandle.
belowIndex := movedHandle + 1.
movedHandle := nil.
subViews := view subViews.
aboveView := subViews at:aboveIndex.
belowView := subViews at:belowIndex.
relCornerAbove := aboveView relativeCorner.
isHorizontal ifTrue:[
oldPos := relCornerAbove x.
newPos := (prevPos + startPos / view width) asFloat.
newCorner := newPos @ relCornerAbove y.
newOrigin := newPos @ belowView relativeOrigin y.
] ifFalse:[
oldPos := relCornerAbove y.
newPos := (prevPos + startPos / view height) asFloat.
newCorner := relCornerAbove x @ newPos.
newOrigin := belowView relativeOrigin x @ newPos.
].
aboveView relativeCorner:newCorner.
belowView relativeOrigin:newOrigin.
view lockRedraw.
oldPos > newPos ifTrue:[
fromIndex := aboveIndex. toIndex := belowIndex.
] ifFalse:[
fromIndex := belowIndex. toIndex := aboveIndex.
].
view resizeSubviewsFrom:fromIndex to:toIndex.
view redrawHandlesFrom:aboveIndex to:belowIndex.
view unlockRedraw.
] ifFalse:[
super buttonRelease:button x:bx y:by
]
"Modified: / 11.3.1999 / 16:31:29 / cg"
!
pointerEnter:state x:x y:y
state == 0 ifTrue:[
movedHandle notNil ifTrue:[self buttonRelease:1 x:x y:y]
]
"Created: / 9.4.1998 / 12:34:22 / cg"
"Modified: / 9.4.1998 / 12:35:05 / cg"
! !
!VariablePanelController class methodsFor:'documentation'!
version
^ '$Header: /cvs/stx/stx/libwidg/VariablePanelController.st,v 1.21 1999-03-19 10:40:23 cg Exp $'
! !