VarPanelC.st
author Claus Gittinger <cg@exept.de>
Mon, 05 May 1997 17:57:22 +0200
changeset 1215 0d9e67bdfbe4
parent 872 3cdb211615e2
child 1333 56af09878b96
permissions -rw-r--r--
check for any change before moving handle (tiny optimization)

"
 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'
	classVariableNames:''
	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 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.
    ].
    view invertHandleBarAtX:oldHx y:oldHy. 
    view invertHandleBarAtX:newHx y:newHy.

    prevPos := pos
!

buttonPress:button x:bx y:by
    "button was pressed - if it hits a handle, start move"

    |handle barHeight group|

    ((button == 1) or:[button == #select]) ifTrue:[
        handle := 1.
        barHeight := view barHeight.

        "
         search the handle, invert the first time
        "
        view handleOriginsWithIndexDo:[:hPoint :hIndex |
            |hx hy|

            view orientation ~~ #vertical ifTrue:[
                hx := hPoint x.
                (bx between:hx and:(hx + barHeight)) ifTrue:[
                    movedHandle := handle.
                    prevPos := hx.
                    startPos := bx - hx.

                    view grabPointer.
                    view invertHandleBarAtX:hx y:0.
                    (group := view windowGroup) notNil ifTrue:[
                        group showCursor:view cursor
                    ].
                    ^ self
                ].
            ] ifFalse:[
                hy := hPoint y.
                (by between:hy and:(hy + barHeight)) ifTrue:[
                    movedHandle := handle.
                    prevPos := hy.
                    startPos := by - hy.

                    view grabPointer.
                    view invertHandleBarAtX:0 y:hy.
                    (group := view windowGroup) notNil ifTrue:[
                        group showCursor:view cursor
                    ].
                    ^ self
                ].
            ].
            handle := handle + 1
        ].
        movedHandle := nil
    ] ifFalse:[
        super buttonPress:button x:bx y:by
    ]
!

buttonRelease:button x:x y:y
    "end bar-move"

    |aboveView belowView aboveIndex belowIndex 
     newPos oldPos group subViews 
     relCornerAbove fromIndex toIndex|

    ((button == 1) or:[button == #select]) ifTrue:[
	movedHandle isNil ifTrue:[^ self].

	view ungrabPointer.
	(group := view windowGroup) notNil ifTrue:[
	    group restoreCursors
	].

	"undo the last invert"

	view orientation ~~ #vertical ifTrue:[
	    view invertHandleBarAtX:prevPos y:0. 
	] ifFalse:[
	    view invertHandleBarAtX:0 y:prevPos. 
	].

	"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.
	view orientation ~~ #vertical ifTrue:[
	    oldPos := relCornerAbove x.
	    newPos := (prevPos + startPos / view width) asFloat.
	    aboveView relativeCorner:newPos @ relCornerAbove y.
	    belowView relativeOrigin:newPos @ belowView relativeOrigin y.
	] ifFalse:[
	    oldPos := relCornerAbove y.
	    newPos := (prevPos + startPos / view height) asFloat.
	    aboveView relativeCorner:relCornerAbove x @ newPos.
	    belowView relativeOrigin:belowView relativeOrigin x @ newPos.
	].

	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:x y:y
    ]
! !

!VariablePanelController class methodsFor:'documentation'!

version
    ^ '$Header: /cvs/stx/stx/libwidg/Attic/VarPanelC.st,v 1.13 1997-05-05 15:57:22 cg Exp $'
! !