RectanglefromUserController.st
author Claus Gittinger <cg@exept.de>
Thu, 09 Nov 2017 20:09:30 +0100
changeset 6225 0122e4e6c587
parent 6144 b62a2aacaccb
child 6793 8527e1fe23c4
permissions -rw-r--r--
#FEATURE by cg class: GenericToolbarIconLibrary class added: #hideFilter16x16Icon

"
 COPYRIGHT (c) 2017 by eXept Software AG
              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.
"
"{ Package: 'stx:libwidg' }"

"{ NameSpace: Smalltalk }"

ButtonController subclass:#RectangleFromUserController
	instanceVariableNames:'action startPoint lastX lastY'
	classVariableNames:''
	poolDictionaries:''
	category:'Interface-Support-Controllers'
!

!RectangleFromUserController class methodsFor:'documentation'!

copyright
"
 COPYRIGHT (c) 2017 by eXept Software AG
              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
"
    drags a rectangle.

    An instance of me can be installed temporarily as controller of any view,
    to let the user select a rectangular area from the view.

    Use the utility method:
        dragRectangleIn:aView thenDo:action
    which does exactly that for your (and cares to restore any original controller)    
    
"
!

examples
"
    |v c|

    v := View new openAndWait.
    c := RectangleFromUserController new.
    c action:[:rect | Transcript showCR:rect ].
    v openAndWait.
    
    v controller:c.
"
! !

!RectangleFromUserController class methodsFor:'utilities'!

dragRectangleIn:aView thenDo:action
    "drag a rectangle in aView"
    
    |dragController oldController oldCursor|
    
    dragController := self new.
    dragController view:aView.
    oldController := aView controller.
    oldCursor := aView cursor.

    aView cursor:Cursor origin.
    dragController action:[:rectOrNil |
        |image|

        aView controller:oldController.
        aView cursor:oldCursor.
        action value:rectOrNil.
    ].
    
    aView controller:dragController.

    "Modified: / 07-03-2017 / 18:25:27 / cg"
!

rectangleFromUserIn:aView thenDo:action
    "drag a rectangle in aView"
    
    |dragController oldController oldCursor|
    
    dragController := self new.
    dragController view:aView.
    oldController := aView controller.
    oldCursor := aView cursor.

    aView cursor:Cursor origin.
    dragController action:[:rectOrNil |
        |image|

        aView controller:oldController.
        aView cursor:oldCursor.
        action value:rectOrNil.
    ].
    
    aView controller:dragController.

    "Created: / 07-03-2017 / 18:30:04 / cg"
! !

!RectangleFromUserController methodsFor:'accessing'!

action:aBlock
    "set the block which will be called when the rectangle drag is finished.
     The block will be called with a nil arg, if escape is pressed"
     
    action := aBlock
!

lastMousePoint
    lastX isNil ifTrue:[^ nil].
    ^ lastX @ lastY
!

startPoint
    ^ startPoint
! !

!RectangleFromUserController methodsFor:'event handling'!

buttonMotion:buttonState x:x y:y
    (buttonState == 0 or:[startPoint isNil]) ifTrue:[
        super buttonMotion:buttonState x:x y:y.
        ^ self
    ].
    
    lastX notNil ifTrue:[
        view xoring:[
            view displayRectangle:(startPoint corner:(lastX@lastY))
        ].
    ].
    
    lastX := x.
    lastY := y.

    startPoint ~= (x@y) ifTrue:[
        view xoring:[
            view displayRectangle:(startPoint corner:(lastX@lastY))
        ].
    ].
!

buttonPress:button x:x y:y
    startPoint := x@y.
    view cursor:(Cursor corner).
!

buttonRelease:button x:x y:y
    |rect|
    
    startPoint isNil ifTrue:[
        super buttonRelease:button x:x y:y.
        ^ self
    ].
    
    (lastX isNil or:[lastY isNil]) ifTrue:[
        lastX := x.
        lastY := y.
    ].
    
    view xoring:[
        view displayRectangle:(startPoint corner:(lastX@lastY))
    ].
    rect := startPoint corner:(lastX@lastY).
    startPoint := lastX := lastY := nil.
    action value:rect.

    "Modified: / 09-02-2017 / 23:18:01 / cg"
    "Modified (format): / 10-04-2017 / 08:39:33 / cg"
!

keyPress:key x:x y:y
    "actually, this is for the escape key (to abort a drag operation)"
    
    startPoint isNil ifTrue:[
        super keyPress:key x:x y:y.
        ^ self
    ].

    lastX notNil ifTrue:[
        view xoring:[
            view displayRectangle:(startPoint corner:(lastX@lastY))
        ].
    ].

    startPoint := nil.
    action value:nil.

    "Modified (comment): / 10-04-2017 / 08:40:57 / cg"
! !

!RectangleFromUserController class methodsFor:'documentation'!

version
    ^ '$Header$'
!

version_CVS
    ^ '$Header$'
! !