"
COPYRIGHT (c) 1997 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.
"
ToolApplicationModel subclass:#ImageEditor
instanceVariableNames:'colorMapMode selectedColorIndex postOpenAction'
classVariableNames:''
poolDictionaries:''
category:'Interface-UIPainter'
!
!ImageEditor class methodsFor:'documentation'!
copyright
"
COPYRIGHT (c) 1997 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
"
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, eXept Software AG
"
!
listOfColors
^List new
! !
!ImageEditor class methodsFor:'instance creation'!
openModalOnClass: aClass andSelector: aSelector
"self openModalOnClass: self andSelector: #newImageIcon"
|imageEditor imageEditView className resourceClassName resourceSelector|
imageEditor := self new.
aClass isClass ifTrue: [className := aClass name].
aClass isString ifTrue: [className := aClass].
imageEditor postOpenAction: [imageEditView := imageEditor imageEditView. imageEditor loadFromOrPrepareForMessage: className, ' ', aSelector].
imageEditor openModal.
resourceClassName := imageEditView resourceClass.
resourceSelector := imageEditView resourceSelector.
(className asString ~= resourceClassName) | (aSelector asString ~= resourceSelector)
ifTrue: [^resourceClassName, ' ', resourceSelector]
ifFalse:[^nil]
!
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:'help specs'!
helpSpec
"return a dictionary filled with helpKey -> helptext associations.
These are used by the activeHelp tool."
"
UIHelpTool openOnClass:ImageEditor
"
^ super helpSpec addPairsFrom:#(
#colorMap
'Increases or reduces size of color map of the image.'
#colorMapTable
'Shows a list of used colors of the image.'
#drawModeBox
'Switches to mode drawing boxes.'
#drawModeCopy
'Switches to mode copying areas.'
#drawModeFill
'Switches to mode filling areas around selected point.'
#drawModeFilledBox
'Switches to mode drawing filled boxes.'
#drawModePaste
'Switches to mode pasting areas at selected point.'
#drawModePoint
'Switches to mode drawing points.'
#editFlipHorizontal
'Flips horizontally the image.'
#editFlipVertical
'Flips vertically the image.'
#editMagnifyImage
'Opens a dialog to magnify the image.'
#editNegate
'Convertes colors of image by negating them.'
#editResize
'Opens a dialog to resize the image with preserving the old image.'
#editRotate
'Opens a dialog to rotate the image in degrees.'
#fileLoadFromClass
'Opens a dialog for selecting and loading an image from resource method of a class.'
#fileLoadFromFile
'Opens a dialog for selecting and loading an image from a file.'
#fileNewImage
'Opens a dialog with choices of size and color depth to create an new image.'
#filePrint
'Print the image on a postscript printer.'
#fileSaveAs
'Opens a dialog to save the image to a file.'
#fileSaveMaskAs
'Opens a dialog to save the mask of the image to a file.'
#fileSaveMethod
'Saves the image on current class and selector.'
#fileSaveMethodAs
'Opens a dialog for selecting and saving the image in a resource method of a class.'
#magnificationNumber
'Shows current number of magnification.'
#magnifyImageDown
'Magnifies down the image.'
#magnifyImageUp
'Magnifies up the image.'
#mouseKeyColorMode
'Switches between left and right mouse button color.'
#previewView
'Shows preview of the image.'
)
! !
!ImageEditor class methodsFor:'interface specs'!
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 153 0 246 0 652 0 591 0)
#label: 'Image Editor'
#min: #(#Point 400 320)
#max: #(#Point 1152 900)
#bounds: #(#Rectangle 153 246 653 592)
#menu: #menu
#usePreferredExtent: false
)
#component:
#(#SpecCollection
#collection:
#(
#(#MenuPanelSpec
#name: 'menuToolbarView'
#layout: #(#LayoutFrame 0 0.0 0 0 0 1.0 32 0)
#menu: #menuToolbar
#style: #(#FontDescription #helvetica #medium #roman 10)
#showSeparatingLines: true
)
#(#VariableHorizontalPanelSpec
#name: 'variableHorizontalPanel1'
#layout: #(#LayoutFrame 0 0.0 34 0.0 0 1.0 -26 1.0)
#component:
#(#SpecCollection
#collection:
#(
#(#ViewSpec
#name: 'view1'
#component:
#(#SpecCollection
#collection:
#(
#(#VariableVerticalPanelSpec
#name: 'VariableVerticalPanel1'
#layout: #(#LayoutFrame 0 0.0 0 0.0 0 1.0 0 1.0)
#component:
#(#SpecCollection
#collection:
#(
#(#ViewSpec
#name: 'View1'
#component:
#(#SpecCollection
#collection:
#(
#(#MenuPanelSpec
#name: 'MenuPanel1'
#layout: #(#LayoutFrame 0 0.0 0 0 0 1.0 24 0)
#menu: #menuMouseButtonColors
)
#(#DataSetSpec
#name: 'colorDataSetView'
#layout: #(#LayoutFrame 0 0.0 26 0.0 0 1.0 0 1.0)
#activeHelpKey: #colorMapTable
#model: #selectionOfColor
#style: #(#FontDescription #helvetica #medium #roman 10)
#hasHorizontalScrollBar: true
#hasVerticalScrollBar: true
#miniScrollerHorizontal: true
#miniScrollerVertical: true
#dataList: #listOfColors
#level: -1
#has3Dsepartors: true
#verticalSpacing: 1
#columns:
#(
#(#DataSetColumnSpec
#rendererType: #rowSelector
#backgroundSelector: #yourself
)
#(#DataSetColumnSpec
#label: 'R'
#model: #rowRedByte
#canSelect: false
)
#(#DataSetColumnSpec
#label: 'G'
#model: #rowGreenByte
#canSelect: false
)
#(#DataSetColumnSpec
#label: 'B'
#model: #rowBlueByte
#canSelect: false
)
)
)
)
)
)
#(#ArbitraryComponentSpec
#name: 'imagePreView'
#activeHelpKey: #previewView
#hasHorizontalScrollBar: true
#hasVerticalScrollBar: true
#miniScrollerHorizontal: true
#miniScrollerVertical: true
#component: #ImageView
#hasBorder: false
)
)
)
#handles: #(#Any 0.723776 1.0)
)
)
)
)
#(#ViewSpec
#name: 'view2'
#component:
#(#SpecCollection
#collection:
#(
#(#ArbitraryComponentSpec
#name: 'imageEditView'
#layout: #(#LayoutFrame 2 0.0 2 0.0 -2 1.0 -24 1.0)
#hasHorizontalScrollBar: true
#hasVerticalScrollBar: true
#component: #ImageEditView
#hasBorder: false
)
#(#LabelSpec
#name: 'coordLabel'
#layout: #(#LayoutFrame 2 0.0 -22 1 -83 1.0 0 1.0)
#level: -1
#adjust: #left
)
#(#ArrowButtonSpec
#name: 'magnifyDownButton'
#layout: #(#LayoutFrame -80 1 -22 1 -58 1 0 1)
#activeHelpKey: #magnifyImageDown
#model: #magnifyDown
#enableChannel: #imageIsLoaded
#isTriggerOnDown: true
#direction: #left
)
#(#ArrowButtonSpec
#name: 'magnifyUpButton'
#layout: #(#LayoutFrame -24 1 -22 1 -2 1 0 1)
#activeHelpKey: #magnifyImageUp
#model: #magnifyUp
#enableChannel: #imageIsLoaded
#isTriggerOnDown: true
#direction: #right
)
#(#InputFieldSpec
#name: 'magnificationInputField'
#layout: #(#LayoutFrame -57 1 -22 1 -26 1 0 1)
#activeHelpKey: #magnificationNumber
#enableChannel: #imageIsLoaded
#model: #valueOfMagnification
#type: #number
#acceptOnReturn: false
#acceptOnTab: false
#numChars: 2
)
)
)
#level: -1
)
)
)
#handles: #(#Any 0.276 1.0)
)
#(#UISubSpecification
#name: 'infoBarSubSpec'
#layout: #(#LayoutFrame 0 0.0 -24 1 0 1.0 0 1.0)
#majorKey: #ToolApplicationModel
#minorKey: #windowSpecForInfoBar
)
)
)
)
!
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 328 0 326 0 628 0 430 0)
#label: 'New Image'
#min: #(#Point 10 10)
#max: #(#Point 1152 900)
#bounds: #(#Rectangle 328 326 629 431)
#usePreferredExtent: false
)
#component:
#(#SpecCollection
#collection:
#(
#(#ViewSpec
#name: 'View'
#layout: #(#LayoutFrame 0 0.0 0 0.0 0 1.0 -37 1.0)
#component:
#(#SpecCollection
#collection:
#(
#(#FramedBoxSpec
#name: 'framedBox1'
#layout: #(#LayoutFrame 1 0.0 1 0.0 0 0.4 60 0)
#component:
#(#SpecCollection
#collection:
#(
#(#ComboBoxSpec
#name: 'defaultSizesComboBox'
#layout: #(#LayoutFrame 15 0.0 20 0.0 17 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 60 0)
#component:
#(#SpecCollection
#collection:
#(
#(#ComboListSpec
#name: 'colorMapComboBox'
#layout: #(#LayoutFrame 15 0.0 20 0.0 18 1.0 16 1.0)
#model: #selectionOfColorMap
#comboList: #listOfColorMaps
#useIndex: false
)
)
)
#label: 'Color Map'
#labelPosition: #topLeft
#style: #(#FontDescription #helvetica #medium #roman 12)
)
)
)
#level: 1
)
#(#UISubSpecification
#name: 'UISubSpecification1'
#layout: #(#LayoutFrame 0 0.0 -30 1 0 1.0 -6 1.0)
#majorKey: #ToolApplicationModel
#minorKey: #windowSpecForCommitWithoutChannels
)
)
)
)
! !
!ImageEditor class methodsFor:'menu 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'
#activeHelpKey: #about
#labelImage: #(#ResourceRetriever nil #menuIcon)
#submenuChannel: #menuAbout
)
#(#MenuItem
#label: 'File'
#translateLabel: true
#activeHelpKey: #file
#submenu:
#(#Menu
#(
#(#MenuItem
#label: 'New...'
#value: #newImage
#activeHelpKey: #fileNewImage
)
#(#MenuItem
#label: '-'
)
#(#MenuItem
#label: 'Load...'
#value: #loadFromClass
#activeHelpKey: #fileLoadFromClass
)
#(#MenuItem
#label: 'Load From File...'
#value: #loadFromFile
#activeHelpKey: #fileLoadFromFile
)
#(#MenuItem
#label: '-'
)
#(#MenuItem
#label: 'Save'
#value: #saveMethod
#activeHelpKey: #fileSaveMethod
#enabled: #imageIsLoaded
)
#(#MenuItem
#label: 'Save As...'
#value: #saveMethodAs
#activeHelpKey: #fileSaveMethodAs
#enabled: #imageIsLoaded
)
#(#MenuItem
#label: '-'
)
#(#MenuItem
#label: 'Save To File...'
#value: #saveImageFileAs
#activeHelpKey: #fileSaveAs
#enabled: #imageIsLoaded
)
#(#MenuItem
#label: 'Save Mask To File...'
#value: #saveImageMaskFileAs
#activeHelpKey: #fileSaveMaskAs
#enabled: #imageIsLoaded
)
#(#MenuItem
#label: '-'
)
#(#MenuItem
#label: 'Print'
#value: #print
#activeHelpKey: #filePrint
#enabled: #imageIsLoaded
)
#(#MenuItem
#label: '-'
)
#(#MenuItem
#label: 'Browse Class'
#value: #browseClass
#activeHelpKey: #fileBrowseClass
#enabled: #imageIsLoaded
)
#(#MenuItem
#label: '-'
)
#(#MenuItem
#label: 'Exit'
#translateLabel: true
#value: #closeRequest
#activeHelpKey: #fileExit
)
) nil
nil
)
)
#(#MenuItem
#label: 'Edit'
#activeHelpKey: #edit
#enabled: #imageIsLoaded
#submenu:
#(#Menu
#(
#(#MenuItem
#label: 'Undo'
#value: #undo
#activeHelpKey: #editUndo
#enabled: #valueOfCanUndo
)
#(#MenuItem
#label: '-'
)
#(#MenuItem
#label: 'Flip - Vertical'
#value: #flipVertical
#activeHelpKey: #editFlipVertical
)
#(#MenuItem
#label: 'Flip - Horizontal'
#value: #flipHorizontal
#activeHelpKey: #editFlipHorizontal
)
#(#MenuItem
#label: '-'
)
#(#MenuItem
#label: 'Resize...'
#value: #resizeImage
#activeHelpKey: #editResize
)
#(#MenuItem
#label: 'Magnify...'
#value: #magnifyImage
#activeHelpKey: #editMagnifyImage
)
#(#MenuItem
#label: 'Rotate...'
#value: #rotateImage
#activeHelpKey: #editRotate
)
#(#MenuItem
#label: '-'
)
#(#MenuItem
#label: 'Negative'
#value: #negativeImage
#activeHelpKey: #editNegate
)
) nil
nil
)
)
#(#MenuItem
#label: 'Color Map'
#activeHelpKey: #colorMap
#enabled: #imageIsLoaded
#submenu:
#(#Menu
#(
#(#MenuItem
#label: '8-Plane'
#activeHelpKey: #colorMap
#argument: '8-plane'
#indication: #colorMapMode:value:
)
#(#MenuItem
#label: '4-Plane'
#activeHelpKey: #colorMap
#argument: '4-plane'
#indication: #colorMapMode:value:
)
#(#MenuItem
#label: '2-Plane'
#activeHelpKey: #colorMap
#argument: '2-plane'
#indication: #colorMapMode:value:
)
#(#MenuItem
#label: '1-Plane'
#activeHelpKey: #colorMap
#argument: '1-plane'
#indication: #colorMapMode:value:
)
#(#MenuItem
#label: '-'
)
#(#MenuItem
#label: '8-Plane + Mask'
#activeHelpKey: #colorMap
#argument: '8-plane + mask'
#indication: #colorMapMode:value:
)
#(#MenuItem
#label: '4-Plane + Mask'
#activeHelpKey: #colorMap
#argument: '4-plane + mask'
#indication: #colorMapMode:value:
)
#(#MenuItem
#label: '2-Plane + Mask'
#activeHelpKey: #colorMap
#argument: '2-plane + mask'
#indication: #colorMapMode:value:
)
#(#MenuItem
#label: '1-Plane + Mask'
#activeHelpKey: #colorMap
#argument: '1-plane + mask'
#indication: #colorMapMode:value:
)
) nil
nil
)
)
#(#MenuItem
#label: 'History'
#activeHelpKey: #history
#submenuChannel: #menuHistory
)
#(#MenuItem
#label: 'Help'
#startGroup: #right
#activeHelpKey: #help
#submenuChannel: #menuHelp
)
) nil
nil
)
!
menuMouseButtonColors
"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:#menuMouseButtonColors
(Menu new fromLiteralArrayEncoding:(ImageEditor menuMouseButtonColors)) startUp
"
<resource: #menu>
^
#(#Menu
#(
#(#MenuItem
#label: 'Left Mouse Button'
#nameKey: #leftMouseKeyButton
#activeHelpKey: #mouseKeyColorMode
#argument: '1'
#labelImage: #(#ResourceRetriever nil #leftMouseKeyIcon)
#indication: #mouseKeyColorMode:value:
)
#(#MenuItem
#label: 'Right Mouse Button'
#nameKey: #rightMouseKeyButton
#activeHelpKey: #mouseKeyColorMode
#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
#activeHelpKey: #fileNewImage
#labelImage: #(#ResourceRetriever nil #newIcon)
)
#(#MenuItem
#label: 'loadFromClass'
#isButton: true
#value: #loadFromClass
#activeHelpKey: #fileLoadFromClass
#labelImage: #(#ResourceRetriever nil #loadIcon)
)
#(#MenuItem
#label: 'saveMethod'
#isButton: true
#value: #saveMethod
#activeHelpKey: #fileSaveMethod
#enabled: #imageIsLoaded
#labelImage: #(#ResourceRetriever nil #saveIcon)
)
#(#MenuItem
#label: ''
)
#(#MenuItem
#label: ''
)
#(#MenuItem
#label: ''
)
#(#MenuItem
#label: ''
)
#(#MenuItem
#label: 'Point'
#activeHelpKey: #drawModePoint
#enabled: #imageIsLoaded
#argument: 'point'
#indication: #editMode:value:
)
#(#MenuItem
#label: 'Box'
#activeHelpKey: #drawModeBox
#enabled: #imageIsLoaded
#argument: 'box'
#indication: #editMode:value:
)
#(#MenuItem
#label: 'Filled Box'
#activeHelpKey: #drawModeFilledBox
#enabled: #imageIsLoaded
#argument: 'filledBox'
#indication: #editMode:value:
)
#(#MenuItem
#label: 'Fill'
#activeHelpKey: #drawModeFill
#enabled: #imageIsLoaded
#argument: 'fill'
#indication: #editMode:value:
)
#(#MenuItem
#label: 'Copy'
#activeHelpKey: #drawModeCopy
#enabled: #imageIsLoaded
#argument: 'copy'
#indication: #editMode:value:
)
#(#MenuItem
#label: 'Paste'
#activeHelpKey: #drawModePaste
#enabled: #imageIsLoaded
#argument: 'paste'
#indication: #editMode:value:
)
) nil
nil
)
! !
!ImageEditor class methodsFor:'resources'!
leftMouseKeyIcon
"Generated by the Image Editor"
"
ImageEditor openOnClass:self andSelector:#leftMouseKeyIcon
"
<resource: #image>
^Icon
constantNamed:#'ImageEditor leftMouseKeyIcon'
ifAbsentPut:[(Depth2Image new) width: 16; height: 16; photometric:(#palette); bitsPerSample:(#(2 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@@@@@@@@@@@@@@@JEE@@B!!QP@@(TT@@@@@@@AUUP@@UUT@@EUU@@AUUP@@UUT@@EUU@@@UU@@@@@@@@@@@@@@a') ; colorMapFromArray:#[0 0 0 255 255 255 255 0 0 0 255 0]; mask:((Depth1Image new) width: 16; height: 16; photometric:(#blackIs0); bitsPerSample:(#(1 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@@@@?0G? _>A?8G? _>A?8G? _>A?8G? O<@_ @@@b') ; yourself); yourself]!
rightMouseKeyIcon
"Generated by the Image Editor"
"
ImageEditor openOnClass:self andSelector:#rightMouseKeyIcon
"
<resource: #image>
^Icon
constantNamed:#'ImageEditor rightMouseKeyIcon'
ifAbsentPut:[(Depth2Image new) width: 16; height: 16; photometric:(#palette); bitsPerSample:(#(2 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@@@@@@@@@@@@@@@EEJ@@AQR @@TT(@@@@@@@AUUP@@UUT@@EUU@@AUUP@@UUT@@EUU@@@UU@@@@@@@@@@@@@@a') ; colorMapFromArray:#[0 0 0 255 255 255 255 0 0 0 255 0]; mask:((Depth1Image new) width: 16; height: 16; photometric:(#blackIs0); bitsPerSample:(#(1 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@@@@?0G? _>A?8G? _>A?8G? _>A?8G? O<@_ @@@b') ; yourself); yourself]! !
!ImageEditor methodsFor:'accessing'!
image
^self imageEditView image
!
postOpenAction: anAction
postOpenAction := anAction
! !
!ImageEditor methodsFor:'accessing - views'!
coordLabel
^builder componentAt: #coordLabel
!
imageEditView
^(builder componentAt: #imageEditView) subViews first
!
imagePreView
^(builder componentAt: #imagePreView) subViews first
! !
!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
!
valueOfMagnification
|holder|
(holder := builder bindingAt:#valueOfMagnification) isNil ifTrue:[
builder aspectAt:#valueOfMagnification put:(
holder := AspectAdaptor new subject:self; forAspect:#magnification)
].
^ holder
! !
!ImageEditor methodsFor:'help'!
defaultInfoLabel
(self imageEditView resourceClass isSymbol and: [(Smalltalk at: self imageEditView resourceClass) isClass])
ifTrue:
[
^self imageEditView resourceClass, ' >> ', self imageEditView resourceSelector
].
^'No class defined'
!
openDocumentation
self openHTMLDocument: 'tools/ImageEditor/TOP.html'
! !
!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 updateLabelsAndHistory.
]
!
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).
!
updateForNoneImage
self imageIsLoaded value: false.
self listOfColors removeAll.
self imagePreView image: nil
!
updateLabelsAndHistory
self imageIsLoaded value: self image notNil.
self image isNil ifTrue: [^nil].
self updateInfoLabel.
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:'queries'!
preferredExtent
^super preferredExtent max: (Screen current width//3)@(Screen current height//3.5)
! !
!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
!
postOpenWith:aBuilder
self imageEditView masterApplication: self.
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 imageEditView loadFromClass) notNil
ifTrue:
[
self image notNil
ifTrue:
[
self listOfColors contents: self image usedColors asSet asOrderedCollection.
self findColorMapMode.
self updateLabelsAndHistory.
]
ifFalse:
[
self updateForNoneImage
]
]
!
loadFromFile
self loadFromFile:
(FileSelectionBrowser
request: 'Load Image From'
fileFilters: FileSelectionBrowser loadImageFileNameFilters)
!
loadFromFile: aFileName
(self imageEditView loadFromFile: aFileName) notNil
ifTrue:
[
self image notNil
ifTrue:
[
self image colorMap notNil
ifTrue:
[
self listOfColors contents: self image usedColors asSet.
]
ifFalse:
[
self listOfColors removeAll.
].
self findColorMapMode.
self updateLabelsAndHistory.
]
ifFalse:
[
self updateForNoneImage
]
]
!
loadFromImage: image
self imageEditView image: image.
self image notNil
ifTrue:
[
self image colorMap notNil
ifTrue:
[
self listOfColors contents: self image usedColors asSet asOrderedCollection.
]
ifFalse:
[
self listOfColors removeAll.
].
self findColorMapMode.
self updateLabelsAndHistory.
]
ifFalse:
[
self updateForNoneImage
]
!
loadFromMessage: aMessage
(self imageEditView loadFromMessage: aMessage) notNil
ifTrue:
[
self image notNil
ifTrue:
[
self listOfColors contents: self image usedColors asSet asOrderedCollection.
self findColorMapMode.
self updateLabelsAndHistory.
]
ifFalse:
[
self updateForNoneImage
]
]
!
loadFromOrPrepareForMessage: aMessage
(self imageEditView loadFromMessage: aMessage) notNil
ifTrue:
[
self listOfColors contents: self image usedColors asSet asOrderedCollection.
self findColorMapMode.
]
ifFalse:
[
self imageEditView resourceMessage: aMessage.
].
self updateLabelsAndHistory.
!
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 updateLabelsAndHistory
]
].
! !
!ImageEditor methodsFor:'user actions - saving'!
print
self imageEditView print
!
saveImageFile
self imageEditView save
!
saveImageFileAs
self imageEditView saveImageFileAs.
self updateLabelsAndHistory
!
saveImageMaskFileAs
self imageEditView saveImageMaskFileAs
!
saveMethod
self imageEditView saveMethod notNil
ifTrue:
[
self updateLabelsAndHistory
]
!
saveMethodAs
self imageEditView saveMethodAs notNil
ifTrue:
[
self updateLabelsAndHistory
]
! !
!ImageEditor class methodsFor:'documentation'!
version
^ '$Header$'
! !