ImageEditor.st
author tz
Fri, 16 Jan 1998 15:03:04 +0100
changeset 407 578a7aaed19e
parent 405 8546da96ab11
child 415 f792d83774b3
permissions -rw-r--r--
totally revised version

"
 COPYRIGHT (c) 1997 by eXept Software AG / Thomas Zwick
              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.
"

ToolApplicationModel subclass:#ImageEditor
	instanceVariableNames:'colorMapMode selectedColorIndex postOpenAction'
	classVariableNames:''
	poolDictionaries:''
	category:'Interface-Advanced-Tools'
!

!ImageEditor class methodsFor:'documentation'!

copyright
"
 COPYRIGHT (c) 1997 by eXept Software AG / Thomas Zwick
              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
"
    By the Image Editor you are able to create, design, modify or just inspect images.

    [start with:]
        ImageEditor open
        ImageEditor openOnClass:ImageEditor andSelector:#newImageIcon

    [see also:]
        ImageEditView Image

    [author:]
        Thomas Zwick
"
! !

!ImageEditor class methodsFor:'instance creation'!

openModalOnClass: aClass andSelector: aSelector

    "self openModalOnClass: self andSelector: #newImageIcon"

    |imageEditor className resourceClassName resourceSelector|                          
    imageEditor := self new.
    aClass isClass ifTrue: [className := aClass name].
    aClass isString ifTrue: [className := aClass].      

    imageEditor postOpenAction: [imageEditor loadFromMessage: className printString, ' ', aSelector].
    imageEditor openModal.

    resourceClassName := imageEditor valueOfResourceClass value.
    resourceSelector := imageEditor valueOfResourceSelector value.
    ^resourceClassName, ' ', resourceSelector
!

openOnClass: aClass andSelector: aSelector

    "self openOnClass: self andSelector: #newImageIcon"

    ^self open loadFromMessage: aClass name, ' ', aSelector
!

openOnFile: image

    "self openOnFile: 'bitmaps/SmalltalkX.xbm'"

    ^self open loadFromFile: image
!

openOnImage: image

    "self openOnImage: self stxIcon"

    ^self open loadFromImage: image
! !

!ImageEditor class methodsFor:'accessing'!

listOfColorMaps

    |colorMap|
    (colorMap := OrderedCollection new)
        add: Color black;
        add: Color white;
        add: Color red;
        add: Color green;
        add: Color blue;
        add: Color cyan;
        add: Color yellow;
        add: Color magenta;
        add: (Color red: 50 green: 0 blue: 0);
        add: (Color red: 0 green: 50 blue: 0);
        add: (Color red: 0 green: 0 blue: 50);
        add: (Color red: 0 green: 50 blue: 50);
        add: (Color red: 50 green: 50 blue: 0);
        add: (Color red: 50 green: 0 blue: 50);
        add: Color gray;
        add: Color lightGray.                                
    0 to: 5 do:
    [:r|                                                    
        0 to: 5 do:         
        [:g|
            0 to: 5 do:                             
            [:b|
                colorMap add: (Color red: (r*100//5) ceiling green: (g*100//5) ceiling blue: (b*100//5) ceiling)
            ]
        ]
    ].

    1 to: 25 do:
    [:g|                             
        colorMap add: (Color gray: (g*100//26) ceiling)
    ].

    ^Dictionary new
        at: '8-plane' put: colorMap;
        at: '8-plane + mask' put: colorMap;
        at: '4-plane' put: (colorMap copyFrom: 1 to: 16);
        at: '4-plane + mask' put: (colorMap copyFrom: 1 to: 16);
        at: '2-plane' put: (colorMap copyFrom: 1 to: 4);
        at: '2-plane + mask' put: (colorMap copyFrom: 1 to: 4);
        at: '1-plane' put: (colorMap copyFrom: 1 to: 2);
        at: '1-plane + mask' put: (colorMap copyFrom: 1 to: 2);
        yourself
!

listOfDefaultSizes

    ^#('24x24' '16x16' '32x32')
! !

!ImageEditor class methodsFor:'interface specs'!

menu
    "this window spec was automatically generated by the ST/X MenuEditor"

    "do not manually edit this - the builder may not be able to
     handle the specification if its corrupted."

    "
     MenuEditor new openOnClass:ImageEditor andSelector:#menu
     (Menu new fromLiteralArrayEncoding:(ImageEditor menu)) startUp
    "

    <resource: #menu>

    ^
     
       #(#Menu
          
           #(
             #(#MenuItem
                #'label:' 'About'
                #'labelImage:' #(#ResourceRetriever #ImageEditor #icon)
                #'submenuChannel:' #menuAbout
            )
             #(#MenuItem
                #'label:' 'File'
                #'translateLabel:' true
                #'submenu:' 
                 #(#Menu
                    
                     #(
                       #(#MenuItem
                          #'label:' 'New...'
                          #'value:' #newImage
                      )
                       #(#MenuItem
                          #'label:' '-'
                      )
                       #(#MenuItem
                          #'label:' 'Load From File...'
                          #'value:' #loadFromFile
                      )
                       #(#MenuItem
                          #'label:' 'Load From Class...'
                          #'value:' #loadFromClass
                      )
                       #(#MenuItem
                          #'label:' 'Load From Class With Superclass...'
                          #'translateLabel:' true
                          #'value:' #loadFromClassWithSuperclass
                      )
                       #(#MenuItem
                          #'label:' '-'
                      )
                       #(#MenuItem
                          #'label:' 'Save'
                          #'value:' #saveImageFile
                          #'enabled:' #imageIsLoaded
                      )
                       #(#MenuItem
                          #'label:' 'Save As...'
                          #'value:' #saveImageFileAs
                          #'enabled:' #imageIsLoaded
                      )
                       #(#MenuItem
                          #'label:' 'Save Mask As...'
                          #'value:' #saveImageMaskFileAs
                          #'enabled:' #imageIsLoaded
                      )
                       #(#MenuItem
                          #'label:' '-'
                      )
                       #(#MenuItem
                          #'label:' 'Save Method'
                          #'value:' #saveMethod
                          #'enabled:' #imageIsLoaded
                      )
                       #(#MenuItem
                          #'label:' 'Save Method As...'
                          #'value:' #saveMethodAs
                          #'enabled:' #imageIsLoaded
                      )
                       #(#MenuItem
                          #'label:' '-'
                      )
                       #(#MenuItem
                          #'label:' 'Print'
                          #'value:' #print
                          #'enabled:' #imageIsLoaded
                      )
                       #(#MenuItem
                          #'label:' '-'
                      )
                       #(#MenuItem
                          #'label:' 'Browse Class'
                          #'value:' #browseClass
                          #'enabled:' #imageIsLoaded
                      )
                       #(#MenuItem
                          #'label:' '-'
                      )
                       #(#MenuItem
                          #'label:' 'Exit'
                          #'translateLabel:' true
                          #'value:' #closeRequest
                      )
                    ) nil
                    nil
                )
            )
             #(#MenuItem
                #'label:' 'Edit'
                #'enabled:' #imageIsLoaded
                #'submenu:' 
                 #(#Menu
                    
                     #(
                       #(#MenuItem
                          #'label:' 'Undo'
                          #'value:' #undo
                      )
                       #(#MenuItem
                          #'label:' '-'
                      )
                       #(#MenuItem
                          #'label:' 'Flip - Vertical'
                          #'value:' #flipVertical
                      )
                       #(#MenuItem
                          #'label:' 'Flip - Horizontal'
                          #'value:' #flipHorizontal
                      )
                       #(#MenuItem
                          #'label:' '-'
                      )
                       #(#MenuItem
                          #'label:' 'Resize...'
                          #'value:' #resizeImage
                      )
                       #(#MenuItem
                          #'label:' 'Magnify...'
                          #'value:' #magnifyImage
                      )
                       #(#MenuItem
                          #'label:' 'Rotate...'
                          #'value:' #rotateImage
                      )
                       #(#MenuItem
                          #'label:' '-'
                      )
                       #(#MenuItem
                          #'label:' 'Negative'
                          #'value:' #negativeImage
                      )
                    ) nil
                    nil
                )
            )
             #(#MenuItem
                #'label:' 'Color Map'
                #'enabled:' #imageIsLoaded
                #'submenu:' 
                 #(#Menu
                    
                     #(
                       #(#MenuItem
                          #'label:' '8-Plane'
                          #'argument:' '8-plane'
                          #'indication:' #'colorMapMode:value:'
                      )
                       #(#MenuItem
                          #'label:' '4-Plane'
                          #'argument:' '4-plane'
                          #'indication:' #'colorMapMode:value:'
                      )
                       #(#MenuItem
                          #'label:' '2-Plane'
                          #'argument:' '2-plane'
                          #'indication:' #'colorMapMode:value:'
                      )
                       #(#MenuItem
                          #'label:' '1-Plane'
                          #'argument:' '1-plane'
                          #'indication:' #'colorMapMode:value:'
                      )
                       #(#MenuItem
                          #'label:' '-'
                      )
                       #(#MenuItem
                          #'label:' '8-Plane + Mask'
                          #'argument:' '8-plane + mask'
                          #'indication:' #'colorMapMode:value:'
                      )
                       #(#MenuItem
                          #'label:' '4-Plane + Mask'
                          #'argument:' '4-plane + mask'
                          #'indication:' #'colorMapMode:value:'
                      )
                       #(#MenuItem
                          #'label:' '2-Plane + Mask'
                          #'argument:' '2-plane + mask'
                          #'indication:' #'colorMapMode:value:'
                      )
                       #(#MenuItem
                          #'label:' '1-Plane + Mask'
                          #'argument:' '1-plane + mask'
                          #'indication:' #'colorMapMode:value:'
                      )
                    ) nil
                    nil
                )
            )
             #(#MenuItem
                #'label:' 'History'
                #'submenuChannel:' #menuHistory
            )
             #(#MenuItem
                #'label:' 'Help'
                #'submenuChannel:' #menuHelp
            )
          ) nil
          nil
      )
!

menuColorAssignment
    "this window spec was automatically generated by the ST/X MenuEditor"

    "do not manually edit this - the builder may not be able to
     handle the specification if its corrupted."

    "
     MenuEditor new openOnClass:ImageEditor andSelector:#menuColorAssignment
     (Menu new fromLiteralArrayEncoding:(ImageEditor menuColorAssignment)) startUp
    "

    <resource: #menu>

    ^
     
       #(#Menu
          
           #(
             #(#MenuItem
                #'label:' 'left'
                #'nameKey:' #leftMouseKeyButton
                #'argument:' '1'
                #'labelImage:' #(#ResourceRetriever nil #leftMouseKeyIcon)
                #'indication:' #'mouseKeyColorMode:value:'
            )
             #(#MenuItem
                #'label:' 'right'
                #'nameKey:' #rightMouseKeyButton
                #'argument:' '2'
                #'labelImage:' #(#ResourceRetriever nil #rightMouseKeyIcon)
                #'indication:' #'mouseKeyColorMode:value:'
            )
          ) nil
          nil
      )
!

menuToolbar
    "this window spec was automatically generated by the ST/X MenuEditor"

    "do not manually edit this - the builder may not be able to
     handle the specification if its corrupted."

    "
     MenuEditor new openOnClass:ImageEditor andSelector:#menuToolbar
     (Menu new fromLiteralArrayEncoding:(ImageEditor menuToolbar)) startUp
    "

    <resource: #menu>

    ^
     
       #(#Menu
          
           #(
             #(#MenuItem
                #'label:' 'newImage'
                #'isButton:' true
                #'value:' #newImage
                #'labelImage:' #(#ResourceRetriever nil #newImageIcon)
            )
             #(#MenuItem
                #'label:' 'loadFromClass'
                #'isButton:' true
                #'value:' #loadFromClass
                #'labelImage:' #(#ResourceRetriever nil #loadFromClassIcon)
            )
             #(#MenuItem
                #'label:' 'loadFromFile'
                #'isButton:' true
                #'value:' #loadFromFile
                #'labelImage:' #(#ResourceRetriever nil #loadFromFileIcon)
            )
             #(#MenuItem
                #'label:' '-'
            )
             #(#MenuItem
                #'label:' 'saveMethod'
                #'isButton:' true
                #'value:' #saveMethod
                #'enabled:' #imageIsLoaded
                #'labelImage:' #(#ResourceRetriever nil #saveAsMethodIcon)
            )
             #(#MenuItem
                #'label:' 'saveFile'
                #'isButton:' true
                #'value:' #saveImageFile
                #'enabled:' #imageIsLoaded
                #'labelImage:' #(#ResourceRetriever nil #saveIcon)
            )
             #(#MenuItem
                #'label:' '-'
            )
             #(#MenuItem
                #'label:' 'Point'
                #'enabled:' #imageIsLoaded
                #'argument:' 'point'
                #'indication:' #'editMode:value:'
            )
             #(#MenuItem
                #'label:' 'Box'
                #'enabled:' #imageIsLoaded
                #'argument:' 'box'
                #'indication:' #'editMode:value:'
            )
             #(#MenuItem
                #'label:' 'Filled Box'
                #'enabled:' #imageIsLoaded
                #'argument:' 'filledBox'
                #'indication:' #'editMode:value:'
            )
             #(#MenuItem
                #'label:' 'Fill'
                #'enabled:' #imageIsLoaded
                #'argument:' 'fill'
                #'indication:' #'editMode:value:'
            )
             #(#MenuItem
                #'label:' 'Copy'
                #'enabled:' #imageIsLoaded
                #'argument:' 'copy'
                #'indication:' #'editMode:value:'
            )
             #(#MenuItem
                #'label:' 'Paste'
                #'enabled:' #imageIsLoaded
                #'argument:' 'paste'
                #'indication:' #'editMode:value:'
            )
          ) nil
          nil
      )
!

windowSpec
    "this window spec was automatically generated by the ST/X UIPainter"

    "do not manually edit this - the painter/builder may not be able to
     handle the specification if its corrupted."

    "
     UIPainter new openOnClass:ImageEditor andSelector:#windowSpec
     ImageEditor new openInterface:#windowSpec
    "
    "ImageEditor open"

    <resource: #canvas>

    ^
     
       #(#FullSpec
          #'window:' 
           #(#WindowSpec
              #'name:' 'Image Editor'
              #'layout:' #(#LayoutFrame 368 0 254 0 867 0 599 0)
              #'label:' 'Image Editor'
              #'min:' #(#Point 400 320)
              #'max:' #(#Point 1152 900)
              #'bounds:' #(#Rectangle 368 254 868 600)
              #'menu:' #menu
              #'usePreferredExtent:' false
          )
          #'component:' 
           #(#SpecCollection
              #'collection:' 
               #(
                 #(#MenuPanelSpec
                    #'name:' 'menuToolbarView'
                    #'layout:' #(#LayoutFrame 0 0.0 0 0 0 1.0 34 0)
                    #'menu:' #menuToolbar
                    #'style:' #(#FontDescription #helvetica #medium #roman 10)
                    #'showSeparatingLines:' true
                )
                 #(#VariableHorizontalPanelSpec
                    #'name:' 'variableHorizontalPanel1'
                    #'layout:' #(#LayoutFrame 0 0.0 36 0.0 0 1.0 -22 1.0)
                    #'component:' 
                     #(#SpecCollection
                        #'collection:' 
                         #(
                           #(#ViewSpec
                              #'name:' 'view1'
                              #'component:' 
                               #(#SpecCollection
                                  #'collection:' 
                                   #(
                                     #(#FramedBoxSpec
                                        #'name:' 'framedBox1'
                                        #'layout:' #(#LayoutFrame 1 0.0 3 0.0 110 0 65 0)
                                        #'component:' 
                                         #(#SpecCollection
                                            #'collection:' 
                                             #(
                                               #(#ArrowButtonSpec
                                                  #'name:' 'magnifyDownButton'
                                                  #'layout:' #(#LayoutFrame 13 0 20 0 35 0 42 0)
                                                  #'model:' #magnifyDown
                                                  #'enableChannel:' #imageIsLoaded
                                                  #'isTriggerOnDown:' true
                                                  #'direction:' #left
                                              )
                                               #(#ArrowButtonSpec
                                                  #'name:' 'magnifyUpButton'
                                                  #'layout:' #(#LayoutFrame 73 0 20 0 95 0 42 0)
                                                  #'model:' #magnifyUp
                                                  #'enableChannel:' #imageIsLoaded
                                                  #'isTriggerOnDown:' true
                                                  #'direction:' #right
                                              )
                                               #(#InputFieldSpec
                                                  #'name:' 'magnificationInputField'
                                                  #'layout:' #(#LayoutFrame 36 0 20 0.0 72 0 42 0)
                                                  #'enableChannel:' #imageIsLoaded
                                                  #'model:' #valueOfMagnification
                                                  #'type:' #number
                                                  #'acceptOnReturn:' false
                                                  #'acceptOnTab:' false
                                                  #'numChars:' 2
                                              )
                                            )
                                        )
                                        #'label:' 'Magnification'
                                        #'labelPosition:' #topLeft
                                        #'style:' #(#FontDescription #helvetica #medium #roman 12)
                                    )
                                     #(#FramedBoxSpec
                                        #'name:' 'framedBox2'
                                        #'layout:' #(#LayoutFrame 1 0.0 68 0 0 1.0 -66 1)
                                        #'component:' 
                                         #(#SpecCollection
                                            #'collection:' 
                                             #(
                                               #(#DataSetSpec
                                                  #'name:' 'colorDataSetView'
                                                  #'layout:' #(#LayoutFrame 11 0.0 19 0.0 20 1.0 -10 1.0)
                                                  #'model:' #selectionOfColor
                                                  #'style:' #(#FontDescription #helvetica #medium #roman 12)
                                                  #'hasHorizontalScrollBar:' true
                                                  #'hasVerticalScrollBar:' true
                                                  #'miniScrollerHorizontal:' true
                                                  #'miniScrollerVertical:' true
                                                  #'dataList:' #listOfColors
                                                  #'has3Dsepartors:' true
                                                  #'verticalSpacing:' 1
                                                  #'columns:' 
                                                   #(
                                                     #(#DataSetColumnSpec
                                                        #'rendererType:' #rowSelector
                                                        #'backgroundSelector:' #yourself
                                                    )
                                                     #(#DataSetColumnSpec
                                                        #'label:' ' Red'
                                                        #'model:' #rowRedByte
                                                        #'canSelect:' false
                                                    )
                                                     #(#DataSetColumnSpec
                                                        #'label:' ' Green'
                                                        #'model:' #rowGreenByte
                                                        #'canSelect:' false
                                                    )
                                                     #(#DataSetColumnSpec
                                                        #'label:' ' Blue'
                                                        #'model:' #rowBlueByte
                                                        #'canSelect:' false
                                                    )
                                                  )
                                              )
                                               #(#MenuPanelSpec
                                                  #'name:' 'menuColorAssignmentPanel'
                                                  #'layout:' #(#LayoutFrame 11 0 -10 1 18 1 17 1)
                                                  #'enableChannel:' #imageIsLoaded
                                                  #'menu:' #menuColorAssignment
                                                  #'style:' #(#FontDescription #helvetica #medium #roman 10)
                                              )
                                            )
                                        )
                                        #'label:' 'Color Map'
                                        #'labelPosition:' #topLeft
                                        #'style:' #(#FontDescription #helvetica #medium #roman 12)
                                    )
                                     #(#VerticalPanelViewSpec
                                        #'name:' 'verticalPanelView1'
                                        #'layout:' #(#LayoutFrame 1 0.0 -68 1 83 0 0 1.0)
                                        #'component:' 
                                         #(#SpecCollection
                                            #'collection:' 
                                             #(
                                               #(#LabelSpec
                                                  #'name:' 'classNameLabel'
                                                  #'label:' 'Class:'
                                                  #'adjust:' #right
                                                  #'extent:' #(#Point 82 21)
                                              )
                                               #(#LabelSpec
                                                  #'name:' 'selectorLabel'
                                                  #'label:' 'Selector:'
                                                  #'adjust:' #right
                                                  #'extent:' #(#Point 82 20)
                                              )
                                               #(#LabelSpec
                                                  #'name:' 'fileNameLabel'
                                                  #'label:' 'File Name:'
                                                  #'adjust:' #right
                                                  #'extent:' #(#Point 82 21)
                                              )
                                            )
                                        )
                                        #'horizontalLayout:' #fit
                                        #'verticalLayout:' #fit
                                        #'horizontalSpace:' 3
                                        #'verticalSpace:' 3
                                    )
                                     #(#VerticalPanelViewSpec
                                        #'name:' 'verticalPanelView2'
                                        #'layout:' #(#LayoutFrame 85 0.0 -68 1 -6 1 0 1.0)
                                        #'component:' 
                                         #(#SpecCollection
                                            #'collection:' 
                                             #(
                                               #(#InputFieldSpec
                                                  #'name:' 'resourceClassInputField'
                                                  #'activeHelpKey:' #classNameInputField
                                                  #'model:' #valueOfResourceClass
                                                  #'immediateAccept:' false
                                                  #'extent:' #(#Point 129 21)
                                              )
                                               #(#InputFieldSpec
                                                  #'name:' 'resourceSelectorInputField'
                                                  #'activeHelpKey:' #selectorInputFieldHelp
                                                  #'model:' #valueOfResourceSelector
                                                  #'immediateAccept:' false
                                                  #'acceptOnTab:' false
                                                  #'extent:' #(#Point 129 20)
                                              )
                                               #(#InputFieldSpec
                                                  #'name:' 'fileNameInputField'
                                                  #'activeHelpKey:' #fileNameInputFieldHelp
                                                  #'model:' #valueOfFileName
                                                  #'immediateAccept:' false
                                                  #'acceptOnTab:' false
                                                  #'extent:' #(#Point 129 21)
                                              )
                                            )
                                        )
                                        #'horizontalLayout:' #fit
                                        #'verticalLayout:' #fit
                                        #'horizontalSpace:' 3
                                        #'verticalSpace:' 3
                                    )
                                     #(#ArbitraryComponentSpec
                                        #'name:' 'imagePreView'
                                        #'layout:' #(#LayoutFrame 111 0.0 9 0.0 -6 1 60 0)
                                        #'hasHorizontalScrollBar:' true
                                        #'hasVerticalScrollBar:' true
                                        #'miniScrollerHorizontal:' true
                                        #'miniScrollerVertical:' true
                                        #'component:' #ImageView
                                        #'hasBorder:' true
                                    )
                                  )
                              )
                              #'level:' -1
                          )
                           #(#ViewSpec
                              #'name:' 'view2'
                              #'component:' 
                               #(#SpecCollection
                                  #'collection:' 
                                   #(
                                     #(#ArbitraryComponentSpec
                                        #'name:' 'imageEditView'
                                        #'layout:' #(#LayoutFrame 2 0.0 2 0.0 -2 1.0 1 1.0)
                                        #'hasHorizontalScrollBar:' true
                                        #'hasVerticalScrollBar:' true
                                        #'component:' #ImageEditView
                                        #'hasBorder:' false
                                    )
                                  )
                              )
                              #'level:' -1
                          )
                        )
                    )
                    #'handles:' #(#Any 0.45082 1.0)
                )
                 #(#LabelSpec
                    #'name:' 'infoLabel'
                    #'layout:' #(#LayoutFrame 0 0 -22 1 -170 1 0 1.0)
                    #'labelChannel:' #valueOfInfoLabel
                    #'level:' 1
                    #'adjust:' #left
                )
                 #(#LabelSpec
                    #'name:' 'timeLabel'
                    #'layout:' #(#LayoutFrame -80 1 -22 1 0 1.0 0 1.0)
                    #'labelChannel:' #valueOfTimeLabel
                    #'level:' 1
                    #'adjust:' #right
                )
                 #(#LabelSpec
                    #'name:' 'coordLabel'
                    #'layout:' #(#LayoutFrame -170 1 -22 1 -80 1 0 1.0)
                    #'labelChannel:' #valueOfCoordLabel
                    #'level:' 1
                    #'adjust:' #left
                )
              )
          )
      )
!

windowSpecForNewImage
    "this window spec was automatically generated by the ST/X UIPainter"

    "do not manually edit this - the painter/builder may not be able to
     handle the specification if its corrupted."

    "
     UIPainter new openOnClass:ImageEditor andSelector:#windowSpecForNewImage
     ImageEditor new openInterface:#windowSpecForNewImage
    "

    <resource: #canvas>

    ^
     
       #(#FullSpec
          #'window:' 
           #(#WindowSpec
              #'name:' 'New Image'
              #'layout:' #(#LayoutFrame 194 0 152 0 461 0 248 0)
              #'label:' 'New Image'
              #'min:' #(#Point 10 10)
              #'max:' #(#Point 1152 900)
              #'bounds:' #(#Rectangle 194 152 462 249)
              #'usePreferredExtent:' false
          )
          #'component:' 
           #(#SpecCollection
              #'collection:' 
               #(
                 #(#ViewSpec
                    #'name:' 'View'
                    #'layout:' #(#LayoutFrame 0 0.0 0 0.0 0 1.0 -38 1.0)
                    #'component:' 
                     #(#SpecCollection
                        #'collection:' 
                         #(
                           #(#FramedBoxSpec
                              #'name:' 'framedBox1'
                              #'layout:' #(#LayoutFrame 1 0.0 1 0.0 0 0.4 55 0)
                              #'component:' 
                               #(#SpecCollection
                                  #'collection:' 
                                   #(
                                     #(#ComboBoxSpec
                                        #'name:' 'defaultSizesComboBox'
                                        #'layout:' #(#LayoutFrame 15 0.0 16 0.0 15 1.0 16 1.0)
                                        #'model:' #selectionOfSize
                                        #'type:' #string
                                        #'comboList:' #listOfDefaultSizes
                                    )
                                  )
                              )
                              #'label:' 'Size'
                              #'labelPosition:' #topLeft
                              #'style:' #(#FontDescription #helvetica #medium #roman 12)
                          )
                           #(#FramedBoxSpec
                              #'name:' 'framedBox2'
                              #'layout:' #(#LayoutFrame 0 0.4 1 0.0 -1 1.0 55 0)
                              #'component:' 
                               #(#SpecCollection
                                  #'collection:' 
                                   #(
                                     #(#ComboListSpec
                                        #'name:' 'colorMapComboBox'
                                        #'layout:' #(#LayoutFrame 15 0.0 16 0.0 15 1.0 16 1.0)
                                        #'model:' #selectionOfColorMap
                                        #'comboList:' #listOfColorMaps
                                        #'useIndex:' false
                                    )
                                  )
                              )
                              #'label:' 'Color Map'
                              #'labelPosition:' #topLeft
                              #'style:' #(#FontDescription #helvetica #medium #roman 12)
                          )
                        )
                    )
                    #'level:' 1
                )
                 #(#HorizontalPanelViewSpec
                    #'name:' 'horizontalPanelView1'
                    #'layout:' #(#LayoutFrame 0 0.0 -38 1 0 1.0 0 1.0)
                    #'component:' 
                     #(#SpecCollection
                        #'collection:' 
                         #(
                           #(#ActionButtonSpec
                              #'name:' 'actionButton2'
                              #'label:' 'Cancel'
                              #'model:' #cancel
                              #'extent:' #(#Point 100 22)
                          )
                           #(#ActionButtonSpec
                              #'name:' 'actionButton1'
                              #'label:' 'OK'
                              #'model:' #accept
                              #'isDefault:' true
                              #'extent:' #(#Point 100 22)
                          )
                        )
                    )
                    #'horizontalLayout:' #center
                    #'verticalLayout:' #center
                    #'horizontalSpace:' 2
                    #'verticalSpace:' 1
                )
              )
          )
      )
! !

!ImageEditor class methodsFor:'resources'!

leftMouseKeyIcon
    "ImageEditor openOnClass:self andSelector:#leftMouseKeyIcon"

    <resource: #image>
    ^(Depth2Image new) width: 16; height: 16; photometric:(#palette); bitsPerSample:(#(2 )); samplesPerPixel:(1); bits:(#[0 0 0 0 0 0 0 0 0 0 0 0 0 161 69 0 0 161 69 0 0 161 69 0 0 0 0 0 0 85 85 0 0 85 85 0 0 85 85 0 0 85 85 0 0 85 85 0 0 85 85 0 0 21 84 0 0 0 0 0 0 0 0 0]) ; colorMap:((OrderedCollection new add:(Color black); add:(Color white); add:(Color red:100.0 green:0.0 blue:0.0); add:(Color red:0.0 green:100.0 blue:0.0); yourself)); mask:((Depth1Image new) width: 16; height: 16; photometric:(#blackIs0); bitsPerSample:(#(1 )); samplesPerPixel:(1); bits:(#[0 0 0 0 15 240 31 248 31 248 31 248 31 248 31 248 31 248 31 248 31 248 31 248 31 248 15 240 7 224 0 0]) ; yourself); yourself
!

loadFromClassIcon
    "ImageEditor openOnClass:self andSelector:#loadFromClassIcon"

    <resource: #image>
    ^(Depth4Image new) width: 22; height: 22; photometric:(#palette); bitsPerSample:(#(4 )); samplesPerPixel:(1); bits:(#[17 17 17 17 17 17 17 17 17 17 17 17 0 0 0 0 0 0 0 17 17 17 17 15 255 255 255 255 255 255 30 17 17 17 15 255 255 255 255 255 255 30 225 17 17 15 68 71 119 74 71 215 17 17 17 17 15 68 71 119 164 173 125 255 254 17 17 15 68 71 119 74 71 215 255 254 17 17 15 51 54 102 57 54 198 255 254 17 17 15 51 54 102 147 156 108 255 254 17 17 15 51 54 102 57 54 198 255 254 17 17 15 34 37 85 40 37 181 255 254 17 17 15 34 37 85 130 139 91 255 254 17 17 15 34 37 85 40 37 181 255 254 17 17 15 255 255 255 255 255 255 255 254 17 17 15 17 241 255 31 241 31 17 254 17 17 15 31 241 241 241 241 255 31 254 17 17 15 31 241 241 17 241 31 17 254 17 17 15 31 241 241 241 255 31 241 254 17 17 15 17 241 17 241 241 31 17 254 17 17 15 255 255 255 255 255 255 255 254 17 17 254 238 238 238 238 238 238 238 238 17 17 17 17 17 17 17 17 17 17 17 17]) ; colorMap:((OrderedCollection new add:(Color white); add:(Color black); add:(Color red:100.0 green:0.0 blue:0.0); add:(Color red:0.0 green:100.0 blue:0.0); add:(Color red:0.0 green:0.0 blue:100.0); add:(Color red:0.0 green:100.0 blue:100.0); add:(Color red:100.0 green:100.0 blue:0.0); add:(Color red:100.0 green:0.0 blue:100.0); add:(Color red:49.9962 green:0.0 blue:0.0); add:(Color red:0.0 green:49.9962 blue:0.0); add:(Color red:0.0 green:0.0 blue:49.9962); add:(Color red:0.0 green:49.9962 blue:49.9962); add:(Color red:49.9962 green:49.9962 blue:0.0); add:(Color red:49.9962 green:0.0 blue:49.9962); add:(Color grey:49.9962); add:(Color grey:66.9978); add:(Color black); yourself)); mask:((Depth1Image new) width: 22; height: 22; photometric:(#blackIs0); bitsPerSample:(#(1 )); samplesPerPixel:(1); bits:(#[127 255 128 127 255 192 127 255 224 127 255 240 127 255 248 127 255 248 127 255 248 127 255 248 127 255 248 127 255 248 127 255 248 127 255 248 127 255 248 127 255 248 127 255 248 127 255 248 127 255 248 127 255 248 127 255 248 127 255 248 127 255 248 127 255 248]) ; yourself); yourself!

loadFromFileIcon
    "ImageEditor openOnClass:self andSelector:#loadFromFileIcon"

    <resource: #image>
    ^(Depth4Image new) width: 22; height: 22; photometric:(#palette); bitsPerSample:(#(4 )); samplesPerPixel:(1); bits:(#[17 17 17 17 17 17 17 17 17 17 17 17 0 0 0 0 0 0 0 17 17 17 17 15 255 255 255 255 255 255 30 17 17 17 15 255 255 255 255 255 255 30 225 17 17 15 68 71 119 74 71 215 17 17 17 17 15 68 71 119 164 173 125 255 254 17 17 15 68 71 119 74 71 215 255 254 17 17 15 51 54 102 57 54 198 255 254 17 17 15 51 54 102 147 156 108 255 254 17 17 15 51 54 102 57 54 198 255 254 17 17 15 34 37 85 40 37 181 255 254 17 17 15 34 37 85 130 139 91 255 254 17 17 15 34 37 85 40 37 181 255 254 17 17 15 255 255 255 255 255 255 255 254 17 17 15 17 31 31 241 255 241 17 254 17 17 15 31 255 31 241 255 241 255 254 17 17 15 17 255 31 241 255 241 31 254 17 17 15 31 255 31 241 255 241 255 254 17 17 15 31 255 31 241 17 241 17 254 17 17 15 255 255 255 255 255 255 255 254 17 17 254 238 238 238 238 238 238 238 238 17 17 17 17 17 17 17 17 17 17 17 17]) ; colorMap:((OrderedCollection new add:(Color white); add:(Color black); add:(Color red:100.0 green:0.0 blue:0.0); add:(Color red:0.0 green:100.0 blue:0.0); add:(Color red:0.0 green:0.0 blue:100.0); add:(Color red:0.0 green:100.0 blue:100.0); add:(Color red:100.0 green:100.0 blue:0.0); add:(Color red:100.0 green:0.0 blue:100.0); add:(Color red:49.9962 green:0.0 blue:0.0); add:(Color red:0.0 green:49.9962 blue:0.0); add:(Color red:0.0 green:0.0 blue:49.9962); add:(Color red:0.0 green:49.9962 blue:49.9962); add:(Color red:49.9962 green:49.9962 blue:0.0); add:(Color red:49.9962 green:0.0 blue:49.9962); add:(Color grey:49.9962); add:(Color grey:66.9978); add:(Color black); yourself)); mask:((Depth1Image new) width: 22; height: 22; photometric:(#blackIs0); bitsPerSample:(#(1 )); samplesPerPixel:(1); bits:(#[127 255 128 127 255 192 127 255 224 127 255 240 127 255 248 127 255 248 127 255 248 127 255 248 127 255 248 127 255 248 127 255 248 127 255 248 127 255 248 127 255 248 127 255 248 127 255 248 127 255 248 127 255 248 127 255 248 127 255 248 127 255 248 127 255 248]) ; yourself); yourself!

newImageIcon
    "ImageEditor openOnClass:self andSelector:#newImageIcon"

    <resource: #image>
    ^(Depth4Image new) width: 22; height: 22; photometric:(#palette); bitsPerSample:(#(4 )); samplesPerPixel:(1); bits:(#[17 17 17 17 17 17 17 17 17 17 17 17 0 0 0 0 0 0 0 17 17 17 17 15 255 255 255 255 255 255 30 17 17 17 15 255 255 255 255 255 255 30 225 17 17 15 68 71 119 74 71 215 17 17 17 17 15 68 71 119 164 173 125 255 254 17 17 15 68 71 119 74 71 215 255 254 17 17 15 51 54 102 57 54 198 255 254 17 17 15 51 54 102 147 156 108 255 254 17 17 15 51 54 102 57 54 198 255 254 17 17 15 34 37 85 40 37 181 255 254 17 17 15 34 37 85 130 139 91 255 254 17 17 15 34 37 85 40 37 181 255 254 17 17 15 255 255 255 255 255 255 255 254 17 17 15 31 241 241 17 241 241 241 254 17 17 15 17 241 241 255 241 241 241 254 17 17 15 17 17 241 31 241 241 241 254 17 17 15 31 17 241 255 241 241 241 254 17 17 15 31 241 241 17 255 31 31 254 17 17 15 255 255 255 255 255 255 255 254 17 17 254 238 238 238 238 238 238 238 238 17 17 17 17 17 17 17 17 17 17 17 17]) ; colorMap:((OrderedCollection new add:(Color white); add:(Color black); add:(Color red:100.0 green:0.0 blue:0.0); add:(Color red:0.0 green:100.0 blue:0.0); add:(Color red:0.0 green:0.0 blue:100.0); add:(Color red:0.0 green:100.0 blue:100.0); add:(Color red:100.0 green:100.0 blue:0.0); add:(Color red:100.0 green:0.0 blue:100.0); add:(Color red:49.9962 green:0.0 blue:0.0); add:(Color red:0.0 green:49.9962 blue:0.0); add:(Color red:0.0 green:0.0 blue:49.9962); add:(Color red:0.0 green:49.9962 blue:49.9962); add:(Color red:49.9962 green:49.9962 blue:0.0); add:(Color red:49.9962 green:0.0 blue:49.9962); add:(Color grey:49.9962); add:(Color grey:66.9978); add:(Color black); yourself)); mask:((Depth1Image new) width: 22; height: 22; photometric:(#blackIs0); bitsPerSample:(#(1 )); samplesPerPixel:(1); bits:(#[127 255 128 127 255 192 127 255 224 127 255 240 127 255 248 127 255 248 127 255 248 127 255 248 127 255 248 127 255 248 127 255 248 127 255 248 127 255 248 127 255 248 127 255 248 127 255 248 127 255 248 127 255 248 127 255 248 127 255 248 127 255 248 127 255 248]) ; yourself); yourself!

rightMouseKeyIcon
    "ImageEditor openOnClass:self andSelector:#rightMouseKeyIcon"

    <resource: #image>
    ^(Depth2Image new) width: 16; height: 16; photometric:(#palette); bitsPerSample:(#(2 )); samplesPerPixel:(1); bits:(#[0 0 0 0 0 0 0 0 0 0 0 0 0 82 138 0 0 82 138 0 0 82 138 0 0 0 0 0 0 85 85 0 0 85 85 0 0 85 85 0 0 85 85 0 0 85 85 0 0 85 85 0 0 21 84 0 0 0 0 0 0 0 0 0]) ; colorMap:((OrderedCollection new add:(Color black); add:(Color white); add:(Color red:100.0 green:0.0 blue:0.0); add:(Color red:0.0 green:100.0 blue:0.0); yourself)); mask:((Depth1Image new) width: 16; height: 16; photometric:(#blackIs0); bitsPerSample:(#(1 )); samplesPerPixel:(1); bits:(#[0 0 0 0 15 240 31 248 31 248 31 248 31 248 31 248 31 248 31 248 31 248 31 248 31 248 15 240 7 224 0 0]) ; yourself); yourself
!

saveAsMethodIcon
    "ImageEditor openOnClass:self andSelector:#saveAsMethodIcon"

    <resource: #image>
    ^(Depth4Image new) width: 22; height: 22; photometric:(#palette); bitsPerSample:(#(4 )); samplesPerPixel:(1); bits:(#[17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 30 225 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 20 68 119 116 164 125 126 30 17 17 17 20 68 119 122 74 215 209 225 17 17 17 20 68 119 116 164 125 126 30 17 17 17 19 51 102 99 147 108 96 240 17 17 17 19 51 102 105 57 198 207 15 17 17 17 19 51 102 99 147 108 96 240 17 17 17 18 34 85 82 130 91 94 238 17 17 17 18 34 85 88 40 181 190 238 17 17 17 18 34 85 82 130 91 94 238]) ; colorMap:((OrderedCollection new add:(Color white); add:(Color black); add:(Color red:100.0 green:0.0 blue:0.0); add:(Color red:0.0 green:100.0 blue:0.0); add:(Color red:0.0 green:0.0 blue:100.0); add:(Color red:0.0 green:100.0 blue:100.0); add:(Color red:100.0 green:100.0 blue:0.0); add:(Color red:100.0 green:0.0 blue:100.0); add:(Color red:49.9962 green:0.0 blue:0.0); add:(Color red:0.0 green:49.9962 blue:0.0); add:(Color red:0.0 green:0.0 blue:49.9962); add:(Color red:0.0 green:49.9962 blue:49.9962); add:(Color red:49.9962 green:49.9962 blue:0.0); add:(Color red:49.9962 green:0.0 blue:49.9962); add:(Color grey:49.9962); add:(Color grey:66.9978); add:(Color black); yourself)); mask:((Depth1Image new) width: 22; height: 22; photometric:(#blackIs0); bitsPerSample:(#(1 )); samplesPerPixel:(1); bits:(#[0 0 0 32 0 0 0 0 0 35 51 128 36 74 64 36 74 64 19 50 64 0 0 0 0 0 0 6 0 0 6 0 0 9 0 0 0 0 0 1 255 252 1 255 252 1 255 252 1 255 252 1 255 252 1 255 252 1 255 252 1 255 252 1 255 252]) ; yourself); yourself! !

!ImageEditor methodsFor:'accessing'!

image

    ^self imageEditView image
!

postOpenAction: anAction

    postOpenAction := anAction
! !

!ImageEditor methodsFor:'accessing - views'!

fileNameInputField

    ^builder componentAt: #fileNameInputField
!

imageEditView

    ^(builder componentAt: #imageEditView) subViews first 
!

imagePreView

    ^(builder componentAt: #imagePreView) subViews first 

!

resourceClassInputField

    ^builder componentAt: #resourceClassInputField
!

resourceSelectorInputField

    ^builder componentAt: #resourceSelectorInputField
! !

!ImageEditor methodsFor:'accessing menu'!

menu
    "this window spec was automatically generated by the UI Builder"

    ^ self class menu


!

menuToolbar
    "this window spec was automatically generated by the UI Builder"

    ^ self class menuToolbar


! !

!ImageEditor methodsFor:'aspects'!

imageIsLoaded

    |holder|
    (holder := builder bindingAt:#imageIsLoaded) isNil ifTrue:[
        builder aspectAt:#imageIsLoaded put:(holder :=  false asValue).
    ].
    ^ holder
!

listOfColors

    |holder|
    (holder := builder bindingAt:#listOfColors) isNil ifTrue:[
        builder aspectAt:#listOfColors put:(holder :=  List new).
    ].
    ^ holder
!

selectionOfColor

    |holder|
    (holder := builder bindingAt:#selectionOfColor) isNil ifTrue:[
        builder aspectAt:#selectionOfColor put:(
        holder := AspectAdaptor new subject:self; forAspect:#selectedColorIndex).
    ].
    ^ holder
!

valueOfCoordLabel

    |holder|
    (holder := builder bindingAt:#valueOfCoordLabel) isNil ifTrue:[
        builder aspectAt:#valueOfCoordLabel put:(holder :=  ValueHolder new).
    ].
    ^ holder
!

valueOfFileName

    |holder|
    (holder := builder bindingAt:#valueOfFileName) isNil ifTrue:[
        builder aspectAt:#valueOfFileName put:(holder :=  '' asValue).
        holder addDependent: self
    ].
    ^ holder
!

valueOfMagnification

    |holder|
    (holder := builder bindingAt:#valueOfMagnification) isNil ifTrue:[
        builder aspectAt:#valueOfMagnification put:(
        holder := AspectAdaptor new subject:self; forAspect:#magnification)
    ].
    ^ holder
!

valueOfResourceClass

    |holder|
    (holder := builder bindingAt:#valueOfResourceClass) isNil ifTrue:[
        builder aspectAt:#valueOfResourceClass put: (holder := '' asValue).
        holder addDependent: self
    ].
    ^ holder
!

valueOfResourceSelector

    |holder|
    (holder := builder bindingAt:#valueOfResourceSelector) isNil ifTrue:[
        builder aspectAt:#valueOfResourceSelector put: (holder := '' asValue).
        holder addDependent: self
    ].
    ^ holder
! !

!ImageEditor methodsFor:'change & update'!

update:something with:aParameter from:changedObject

    something == #value
    ifTrue:
    [   
        (changedObject = self valueOfResourceClass)
        ifTrue:
        [   
            |s what m|
            s := self resourceClassInputField contents withoutSpaces.
            what := Smalltalk classnameCompletion:s.
            self resourceClassInputField contents:what first.
            (what at:2) size ~~ 1 ifTrue:[
                Display beep
            ]
        ].
        (changedObject = self valueOfResourceClass) | (changedObject = self valueOfResourceSelector)
        ifTrue:
        [   
            self loadFromMessage: self resourceClassInputField contents, ' ', self resourceSelectorInputField contents
        ].
        (changedObject = self valueOfFileName)
        ifTrue:
        [   
            self loadFromFile: self fileNameInputField contents
        ].
    ].

    super update:something with:aParameter from:changedObject

! !

!ImageEditor methodsFor:'menu modes'!

colorMapMode: aMode

    ^colorMapMode = aMode
!

colorMapMode: aMode value: aValue

    |depth newColorMap newImage image newColors realColorMap oldFileName| 

    newColorMap := self class listOfColorMaps at: aMode.
    depth := (newColorMap size log: 2) asInteger. 
    newImage := (Image implementorForDepth: depth) new.  
    oldFileName := self image fileName.
    Object errorSignal handle:
    [:ex|
        Object errorSignal handle:
        [:ex|
            ^self warn: 'Convertation failed!!'
        ]
        do:
        [
            self image colorsFromX:0 y:0 toX:(self image width-1) y:(self image height-1) do:
            [:x :y :clr |
                (newColorMap includes: clr)
                    ifTrue: [self image colorAtX:x y:y put:clr]
                    ifFalse: [self image colorAtX:x y:y put: self image colorMap first]
            ].
            image := newImage fromImage: self image.
        ].
    ] 
    do:
    [ 
        image := newImage fromImage: self image
    ].
    (String fromString: aMode) reverse readStream nextWord reverse = 'mask'
    ifTrue:
    [
        image mask isNil
        ifTrue:
        [
            image mask: (Depth1Image fromImage: (image asThresholdMonochromeImage: 0.1)). 
        ].
    ]
    ifFalse:
    [ 
        image mask: nil.
    ]. 
    realColorMap := OrderedCollection new.
    image realColorMap do:
    [:clr|
        (realColorMap includes: clr) ifFalse: [realColorMap add: clr]
    ].
    newColors := realColorMap copyFrom: 1 to: (newColorMap size min: realColorMap size).
    newColorMap do:
    [:clr|
        ((newColors size < newColorMap size) and: [(newColors includes: clr) not]) 
        ifTrue:
        [      
            newColors add: clr
        ]
    ].       
    image colorMap: newColors.
    colorMapMode := aMode.
    (self imageEditView image: image) notNil
    ifTrue:
    [
        self image fileName: oldFileName.
        self listOfColors contents: image colorMap.
        self findColorMapMode.
        self updateInputFieldsAndLabelsAndHistory.
    ]
!

editMode: aMode

    ^self imageEditView editMode = aMode
!

editMode: aMode value: aValue

    self imageEditView editMode: aMode
!

mouseKeyColorMode: aMode

    ^self imageEditView mouseKeyColorMode = aMode
!

mouseKeyColorMode: aMode value: aValue

    self imageEditView mouseKeyColorMode: aMode.

    self selectionOfColor value: (self listOfColors indexOf: self imageEditView selectedColor).
! !

!ImageEditor methodsFor:'private'!

findColorMapMode

    self image depth > 8 ifTrue: [colorMapMode := ''. self listOfColors removeAll. ^nil].
    colorMapMode := self image depth printString, '-plane'.
    self listOfColors isEmpty
    ifTrue:
    [   
         self colorMapMode: colorMapMode value: nil
    ].       
    self imageEditView selectColor: (Array with: (self listOfColors at: 1) with: (self listOfColors at: 2)).
    self image mask notNil
    ifTrue:
    [
        colorMapMode := colorMapMode, ' + mask'.
        self listOfColors addFirst: (Color basicNew setColorId:0).
        self imageEditView selectColor: (Array with: (self listOfColors at: 2) with: (self listOfColors at: 1)).
    ].
    self selectionOfColor value: 0.
    self selectionOfColor value: (self listOfColors indexOf: self imageEditView selectedColor).
!

sortColorColumn: aColumn



!

updateInfoLabel

    |usedColors|
    self image colorMap isNil ifTrue: [usedColors := '?'] ifFalse: [usedColors := self image usedColors size].
    self valueOfInfoLabel value:
        self image width printString, 'x',
        self image height printString, 'x',
        (2 raisedTo: self image depth) printString,
        (self image mask notNil ifTrue: [' (mask + '] ifFalse: ['(']),
        usedColors printString,
        ' used colors)'


!

updateInputFieldsAndLabelsAndHistory

    self imageIsLoaded value: self image notNil.

    self image isNil ifTrue: [^nil].

    self updateInfoLabel.
    self imageEditView coordInfoBlock: [:value| self valueOfCoordLabel value: value].

    self valueOfFileName removeDependent: self.
    self valueOfFileName value: self image fileName.
    self valueOfFileName addDependent: self.

    self valueOfResourceSelector removeDependent: self.
    self valueOfResourceSelector value: self imageEditView resourceSelector.
    self valueOfResourceSelector addDependent: self.

    self valueOfResourceClass removeDependent: self.
    self imageEditView resourceClass notNil
        ifTrue: [self valueOfResourceClass value: self imageEditView resourceClass]
        ifFalse: [self valueOfResourceClass value: ''].
    self valueOfResourceClass addDependent: self.

    self imageEditView resourceMessage asCollectionOfWords size = 2
        ifTrue: [self addToHistory: self imageEditView resourceMessage -> #loadFromMessage:].

    self image fileName notNil
        ifTrue: [self addToHistory: self image fileName -> #loadFromFile:].



! !

!ImageEditor methodsFor:'selection'!

magnification

    (builder componentAt: #imageEditView) isNil ifTrue: [^1].
    ^self imageEditView magnification x
!

magnification: aValue

    |magnification|
    magnification := aValue asInteger asPoint.
    (magnification = self imageEditView magnification) | (magnification = (0@0)) ifTrue: [^nil].
    self imageEditView magnification: magnification
!

selectedColorIndex

    ^selectedColorIndex
!

selectedColorIndex: anIndex

    selectedColorIndex := anIndex.    
    self imageEditView selectedColor: (self listOfColors at: anIndex ifAbsent: [^nil])

! !

!ImageEditor methodsFor:'startup / release'!

closeRequest

    self imageEditView checkModified ifTrue:[super closeRequest]

!

open

    super open.

    self imageEditView masterApplication: self.

    self resourceClassInputField entryCompletionBlock:
    [:value|
        |what|
        what := Smalltalk classnameCompletion: value withoutSpaces.
        self resourceClassInputField contents:what first.
        (what at:2) size ~~ 1 ifTrue:[
            Display beep
        ]
    ].
    self resourceSelectorInputField entryCompletionBlock:
    [:value|
        |cls what|
        (cls := Smalltalk at: self resourceClassInputField contents asSymbol) notNil
        ifTrue:
        [
            |firstPossibleSelector resourceType|
            what := cls class selectorCompletion: value withoutSpaces.
            firstPossibleSelector := what first asSymbol.
            (cls class selectors includes: firstPossibleSelector)
            ifTrue:
            [
                resourceType := (cls class compiledMethodAt: firstPossibleSelector) resourceType.
                ((resourceType = #image) or: [resourceType = #fileImage])
                ifTrue:
                [
                    self resourceSelectorInputField contents:firstPossibleSelector.
                ].
            ].
            (what at:2) size ~~ 1 ifTrue:[
                Display beep
            ]
        ]
    ].
!

postOpenWith:aBuilder

    postOpenAction notNil ifTrue: [postOpenAction value].
    super postOpenWith:aBuilder.
!

reOpen

    self imageEditView checkModified ifTrue:[super reOpen]

! !

!ImageEditor methodsFor:'user actions - editing'!

browseClass

    SystemBrowser openInClass: (Smalltalk at: self imageEditView resourceClass ifAbsent: [^nil]) class selector: self imageEditView resourceSelector
!

flipHorizontal

    self imageEditView flipHorizontal
!

flipVertical

    self imageEditView flipVertical
!

magnifyDown

    self valueOfMagnification value > 1
    ifTrue:
    [
        self valueOfMagnification value: self valueOfMagnification value - 1
    ]
!

magnifyImage

    self imageEditView magnifyImage.   
    self updateInfoLabel
!

magnifyUp

    self valueOfMagnification value < 99
    ifTrue:
    [
        self valueOfMagnification value: self valueOfMagnification value + 1
    ]
!

negativeImage

    self imageEditView negativeImage.
    self listOfColors removeAll.
    self findColorMapMode.     
!

resizeImage

    self imageEditView resizeImage.   
    self updateInfoLabel
!

rotateImage

    self imageEditView rotateImage.
    self updateInfoLabel
!

undo

    self imageEditView undo
! !

!ImageEditor methodsFor:'user actions - loading'!

loadFromClass

    self loadFromInClassesOf: #Object.
   
!

loadFromClassWithSuperclass

    |box|
    box := EnterBox new.
    box title:'Name of superclass:'.
    box okText:'OK'.
    box abortText:'Cancel'.
    box initialText: 'ApplicationModel'.
    box showAtPointer.
    box accepted
    ifTrue:
    [            
        self loadFromInClassesOf: box contents asSymbol
    ].

!

loadFromFile

    self loadFromFile:
        (FileSelectionBrowser
            request: 'Load Image From' 
            fileFilters: FileSelectionBrowser loadImageFileNameFilters)
!

loadFromFile: aFileName

    (aFileName notNil and: [(self imageEditView loadFromFile: aFileName) notNil])
    ifTrue:
    [          
        self image colorMap notNil
        ifTrue:
        [
            self listOfColors contents: self image usedColors asSet.
        ]
        ifFalse:
        [
            self listOfColors removeAll.
        ].
        self findColorMapMode.     
        self updateInputFieldsAndLabelsAndHistory.
    ]

!

loadFromImage: image

    (self imageEditView image: image) notNil
    ifTrue:
    [    
        self image colorMap notNil
        ifTrue:
        [
            self listOfColors contents: self image usedColors asSet asOrderedCollection.
        ]
        ifFalse:
        [
            self listOfColors removeAll.
        ].
        self findColorMapMode.
        self updateInputFieldsAndLabelsAndHistory.
    ]
!

loadFromInClassesOf: aSuperclassOrSymbol

    self imageEditView loadFromInClassesOf: aSuperclassOrSymbol.
    self image notNil
    ifTrue:
    [
        self listOfColors contents: self image usedColors asSet asOrderedCollection.
        self findColorMapMode.
        self updateInputFieldsAndLabelsAndHistory.
    ]
!

loadFromMessage: aMessage

    (self imageEditView loadFromMessage: aMessage) notNil
    ifTrue:
    [
        self listOfColors contents: self image usedColors asSet asOrderedCollection.
        self findColorMapMode.
        self updateInputFieldsAndLabelsAndHistory.
    ]
!

newImage

    |aspects|
    aspects  := IdentityDictionary new
        at:#listOfSizes put: self class listOfDefaultSizes asValue;
        at:#listOfColorMaps put: self class listOfColorMaps keys asSortedCollection asValue;
        at:#selectionOfSize put: self class listOfDefaultSizes first copy asValue;
        at:#selectionOfColorMap put: self class listOfColorMaps keys asSortedCollection first asValue;
        yourself.

    (self openDialogInterface:#windowSpecForNewImage withBindings:aspects)
    ifTrue:
    [
        |width height cMap imageClass image|
        width := 128 min: (Integer readFromString: ((aspects at:#selectionOfSize) value upTo: $x) onError:[24]).
        height := 128 min: (Integer readFromString: ((aspects at:#selectionOfSize) value copy reverse upTo: $x) reverse onError:[24]).

        cMap := (self class listOfColorMaps at: (colorMapMode := (aspects at:#selectionOfColorMap) value)).
        imageClass := Image implementorForDepth: ((cMap size log: 2) asInteger).
        image := imageClass width: width height: height fromArray: (ByteArray new: width*height).

        (colorMapMode copy reverse readStream nextWord reverse = 'mask')
        ifTrue:
        [
            image mask: (Depth1Image width: width height: height depth: 1 fromArray: (ByteArray new: width*height)) clearMaskedPixels.
        ].
        image colorMap: cMap.
        image fillRectangleX:0 y:0 width:width height:height with:Color white.
        (self imageEditView image: image) notNil
        ifTrue:
        [
            self listOfColors contents: cMap.
            self findColorMapMode.
            self updateInputFieldsAndLabelsAndHistory
        ]
    ].
! !

!ImageEditor methodsFor:'user actions - saving'!

print

    self imageEditView print
!

saveImageFile

    self imageEditView saveImageFileAs: self fileNameInputField contents
!

saveImageFileAs

    self imageEditView saveImageFileAs.
    self updateInputFieldsAndLabelsAndHistory
!

saveImageMaskFileAs

    self imageEditView saveImageMaskFileAs
!

saveMethod

    (self imageEditView 
        resourceSelector: self resourceSelectorInputField contents;
        resourceClass: self resourceClassInputField contents;
        saveMethod) notNil
    ifTrue:
    [
        self updateInputFieldsAndLabelsAndHistory
    ]
!

saveMethodAs

    self imageEditView saveMethodAs notNil
    ifTrue:
    [
        self updateInputFieldsAndLabelsAndHistory
    ]
! !

!ImageEditor class methodsFor:'documentation'!

version
    ^ '$Header$'
! !