ImageView.st
author Claus Gittinger <cg@exept.de>
Wed, 19 Apr 2000 13:18:21 +0200
changeset 1764 3dd553f8d9f0
parent 1763 7d6d64622ee4
child 1970 b7cf91b688d1
permissions -rw-r--r--
oops - leftover halts

"
 COPYRIGHT (c) 1993 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.
"

"{ Package: 'stx:libwidg2' }"

View subclass:#ImageView
	instanceVariableNames:'image adjust imageChannel'
	classVariableNames:''
	poolDictionaries:''
	category:'Views-Misc'
!

!ImageView class methodsFor:'documentation'!

copyright
"
 COPYRIGHT (c) 1993 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
"
    This View knows how to display an image (or form).

    You can display an image with:

        ImageView openOn:anImageFileName
    or:
        ImageView openOnImage:anImage
    or:
        ImageView new image:anImage

    i.e.

        ImageView openOn:'bitmaps/gifImages/garfield.gif'
        ImageView openOn:'bitmaps/SBrowser.xbm'

        ImageView openOnImage:(Image fromFile:'bitmaps/gifImages/garfield.gif')
        ImageView openOnImage:(Image fromFile:'bitmaps/SBrowser.xbm')

    [author:]
        Claus Gittinger

    [see also:]
        Image Form
"
! !

!ImageView class methodsFor:'queries - plugin'!

aspectSelectors
    ^ #( imageChannel )

    "Created: / 11.2.2000 / 00:37:33 / cg"
! !

!ImageView class methodsFor:'startup'!

openOn:aFileName
    "startup an image viewer on an image read from a file"

    |imageView img e|

    img := Image fromFile:aFileName.
    img isNil ifTrue:[
        aFileName asFilename exists ifTrue:[
            e := 'unknown/unsupported image format'
        ] ifFalse:[
            e := 'no such image'.
        ].
        self warn:e.
        ^ nil
    ].
    imageView := self openOnImage:img.

    imageView topView label:aFileName iconLabel:(aFileName asFilename baseName).

    ^ imageView

    "
     ImageView openOn:'bitmaps/gifImages/garfield.gif'
     ImageView openOn:'bitmaps/xpmBitmaps/BOOK.xpm'
    "

    "Modified: / 31.10.1997 / 16:17:52 / cg"
!

openOnImage:anImage
    "startup an image viewer on an image"

    |top v imageView icnW icnH iconView magX magY mag lbl imgWidth imgHeight|

    anImage isImage ifTrue:[
        lbl := 'an Image'
    ] ifFalse:[
        lbl := 'a Form'
    ].
    top := StandardSystemView label:lbl.

    v := HVScrollableView for:self in:top.
    v origin:0@0 extent:1.0@1.0. 
    imageView := v scrolledView.

    anImage notNil ifTrue:[
        imageView image:anImage.

        "define an icon view showing a little version of image.
         Since some window managers cannot handle this correctly (twm),
         this is only done when running on an IRIS"

        (true "(OperatingSystem getSystemType = 'iris')" 
        and:[StyleSheet name == #iris]) ifTrue:[
            iconView := ImageView new.

            "for now; should somehow get access to preferred iconview extent ..."
            icnW := 86.
            icnH := 68.

            imgWidth := anImage width.
            imgHeight := anImage height.

            ((imgWidth <= icnW) and:[imgHeight <= icnH]) ifTrue:[
                iconView extent:(imgWidth @ imgHeight).
                mag := 1 @ 1
            ] ifFalse:[
                magX := icnW / imgWidth.
                magY := icnH / imgHeight.

                "scale image"
"
                mag := magX @ magY.
"
                "preserve ratio"
" 
                mag := (magX min:magY) asPoint.
" 
" "
                mag := (magX max:magY) asPoint.
" "

                iconView extent:((anImage width @ anImage height) * mag) rounded.
            ].

            top iconView:iconView.
        ].
    ].

    top open.

    iconView notNil ifTrue:[
        top windowGroup addView:iconView.
        [ 
            iconView image:(anImage magnifyBy:mag).
        ] forkAt:4
    ].
    ^ imageView

    "
     ImageView openOnImage:(Image fromFile:'bitmaps/gifImages/garfield.gif')
     ImageView openOnImage:(Image fromFile:'bitmaps/SBrowser.xbm')
    "

    "Modified: / 18.12.1997 / 11:46:19 / cg"
! !

!ImageView methodsFor:'accessing'!

adjust:layoutSymbol
    "set the adjust (how the image is displayed);
     currently, only support #topLeft and #center"

    adjust := layoutSymbol
!

image
    "return the image"

    ^ image
!

image:anImage
    "set the image - show a wait cursor, since image dithering may take a while"

    |oldSize newSize devImage|

    image ~= anImage ifTrue:[
        oldSize := image ifNil:[0@0] ifNotNil:[image extent].

        image := anImage.

        newSize := image ifNil:[0@0] ifNotNil:[image extent].
        oldSize ~= newSize ifTrue:[
            self contentsChanged.
        ].

        shown ifTrue:[
            self withWaitCursorDo:[
                (image notNil and: [image device ~~ device]) ifTrue:[
                    devImage := image on:device.
                    devImage ~~ image ifTrue:[
                        image := devImage.
                    ].
                ].
                self clear.
                self invalidate
            ].
        ].
        self changed:#image.
    ]

    "Modified: / 10.2.2000 / 23:25:51 / cg"
! !

!ImageView methodsFor:'accessing channels'!

imageChannel
    imageChannel isNil ifTrue:[
        imageChannel := ValueHolder new.
        imageChannel addDependent:self.
    ].
    ^ imageChannel

    "Created: / 11.2.2000 / 00:34:44 / cg"
!

imageChannel:aValueHolder
    imageChannel notNil ifTrue:[
        imageChannel removeDependent:self.
    ].
    imageChannel := aValueHolder.
    imageChannel notNil ifTrue:[
        imageChannel addDependent:self.
    ].

    "Created: / 11.2.2000 / 00:34:33 / cg"
! !

!ImageView methodsFor:'change & update'!

update:something with:aParameter from:changedObject
    something == imageChannel ifTrue:[
        self image:(imageChannel value).
        ^ self
    ].
    super update:something with:aParameter from:changedObject

    "Created: / 11.2.2000 / 00:37:02 / cg"
! !

!ImageView methodsFor:'drawing'!

redrawX:x y:y width:w height:h
    |xI yI depth ext imgWidth imgHeight right bott devImage|

    image notNil ifTrue:[
        imgWidth := image width.
        imgHeight := image height.

        adjust == #center ifTrue:[
            xI := (width - (margin * 2) - imgWidth) // 2.
            yI := (height - (margin * 2) - imgHeight) // 2.
        ] ifFalse:[
            xI := yI := margin
        ].

        ((depth := image depth) == 1) ifTrue:[
            self paint:(image colorFromValue:1)
                    on:(image colorFromValue:0).
        ].

        Object errorSignal handle:[:ex |
            Transcript showCR:'cannot convert image'.
            ^ self.
        ] do:[
            devImage := image onDevice:device.
            devImage ~~ image ifTrue:[
                image := devImage.
                self changed:#image.
            ].
        ].

        (depth == 1
        and:[image mask isNil]) ifFalse:[
            self clearRectangleX:x y:y width:w height:h.
            self displayForm:image x:xI y:yI 
        ] ifTrue:[
            self displayOpaqueForm:image x:xI y:yI 
        ].

        "/ right of image ?
        right := x + w - 1.
        right > (xI + imgWidth) ifTrue:[
            self clearRectangleX:(xI + imgWidth)
                               y:y
                           width:(right - imgWidth - xI)
                          height:h  
        ].
        "/ below of image ?
        bott := y + h - 1.
        bott > (yI + imgHeight) ifTrue:[
            self clearRectangleX:margin
                               y:(yI + imgHeight)
                           width:w
                          height:(bott - imgHeight - yI)  
        ].
    ]

    "Created: / 11.7.1996 / 21:02:12 / cg"
    "Modified: / 12.8.1998 / 14:02:28 / cg"
! !

!ImageView methodsFor:'initialize / release'!

destroy
    image := nil.
    super destroy.
! !

!ImageView methodsFor:'queries'!

heightOfContents
    "return the images height - scrollbar needs this info"

    image isNil ifTrue:[^ 0].
    ^ image height
!

widthOfContents
    "return the images width - scrollbar needs this info"

    image isNil ifTrue:[^ 0].
    ^ image width
! !

!ImageView class methodsFor:'documentation'!

version
    ^ '$Header: /cvs/stx/stx/libwidg2/ImageView.st,v 1.42 2000-04-19 11:18:03 cg Exp $'
! !