tz@400: " tz@767: COPYRIGHT (c) 1997-1998 by eXept Software AG tz@400: All Rights Reserved tz@400: tz@400: This software is furnished under a license and may be used tz@400: only in accordance with the terms of that license and with the tz@405: inclusion of the above copyright notice. This software may not tz@400: be provided or otherwise made available to, or used by, any tz@405: other person. No title to or ownership of the software is tz@400: hereby transferred. tz@400: " cg@1376: "{ Package: 'stx:libtool2' }" cg@1376: cg@3180: "{ NameSpace: Smalltalk }" cg@3180: cg@1975: ResourceSpecEditor subclass:#ImageEditor tz@975: instanceVariableNames:'imageEditView colorMapMode editMode mouseKeyColorMode cg@1960: selectedColorIndex postOpenAction imageSeqNr drawingColormap cg@2767: lastShiftUsedWrap lastGrabbedScreenArea cg@2767: allowedToChangeImageDimensionAndDepth' cg@1640: classVariableNames:'LastDirectory LastSizeString MaskClipboard LastColormapMode cg@2796: DefaultRelativeSizes LastURL' cg@929: poolDictionaries:'' cg@929: category:'Interface-UIPainter' tz@400: ! tz@400: tz@400: !ImageEditor class methodsFor:'documentation'! tz@400: tz@400: copyright tz@400: " tz@767: COPYRIGHT (c) 1997-1998 by eXept Software AG tz@400: All Rights Reserved tz@400: tz@400: This software is furnished under a license and may be used tz@400: only in accordance with the terms of that license and with the tz@405: inclusion of the above copyright notice. This software may not tz@400: be provided or otherwise made available to, or used by, any tz@405: other person. No title to or ownership of the software is tz@400: hereby transferred. tz@400: " tz@400: ! tz@400: tz@400: documentation tz@400: " tz@737: Image Editor allows you to create, design, modify or just inspect images. tz@400: tz@400: [start with:] tz@400: ImageEditor open tz@941: ImageEditor openOnClass:Icon andSelector:#startIcon tz@400: tz@400: [see also:] tz@400: ImageEditView Image tz@400: tz@400: [author:] tz@544: Thomas Zwick, eXept Software AG cg@1806: Claus Gittinger, eXept Software AG tz@400: " tz@400: ! ! tz@400: tz@400: !ImageEditor class methodsFor:'instance creation'! tz@400: sv@3357: openLoadingImageWith:aBlock modal:modalBoolean cg@1975: "opens an Image Editor on anImage" cg@1975: cg@1975: |editor| cg@1975: cg@1975: editor := self new. cg@1975: editor allButOpen. cg@1975: aBlock value:editor. sv@3357: modalBoolean ifTrue:[ sv@3357: editor openWindowModal. sv@3357: ] ifFalse:[ sv@3357: editor openWindow. sv@3357: ]. cg@2764: ^ editor cg@1975: ! cg@1975: tz@400: openModalOnClass: aClass andSelector: aSelector cg@1975: "opens a modal Image Editor on aClass and aSelector. cg@1975: Returns the real name of the edited resource method (in case, user changed it)." cg@1975: cg@1975: |imageEditor imageEditView className resourceClass resourceSelector| tz@767: tz@400: imageEditor := self new. tz@767: tz@900: aClass isClass ifTrue: [className := aClass name]. tz@900: aClass isString ifTrue: [className := aClass]. tz@903: aClass isNil ifTrue: [className := '']. tz@400: cg@2764: imageEditor postOpenAction: [ cg@2764: imageEditView := imageEditor imageEditView. cg@2764: imageEditor loadFromOrPrepareForClass: aClass andSelector: aSelector cg@2764: ]. tz@400: imageEditor openModal. tz@400: cg@1975: resourceClass := imageEditView resourceClass. cg@1975: resourceSelector := imageEditView resourceSelector. cg@1975: cg@1975: (resourceClass isNil or:[resourceSelector isNil]) ifTrue:[^ nil]. cg@1975: ^ Array with:resourceClass with:resourceSelector cg@1966: cg@1966: " cg@1966: self openModalOnClass: self andSelector: #leftMouseKeyIcon cg@1966: " tz@400: ! tz@400: sv@3357: openModalOnFile:aFileName sv@3357: "opens an Image Editor on aFileName" sv@3357: sv@3357: self openLoadingImageWith:[:editor | sv@3357: editor loadFromFile:aFileName. sv@3357: ] modal:true. sv@3357: sv@3357: " sv@3357: self openModalOnFile: '../../goodies/bitmaps/gifImages/back.gif' sv@3357: " sv@3357: ! sv@3357: cg@2764: openModalOnImage:anImage cg@2764: "opens a modal Image Editor on an image. cg@2764: Returns the modified image or nil if unsaved/unchanged" cg@2764: cg@2764: |imageEditor imageEditView newImage| cg@2764: cg@2764: imageEditor := self new. cg@2767: imageEditor allowedToChangeImageDimensionAndDepth:false. cg@2764: imageEditor postOpenAction: [ cg@2764: imageEditView := imageEditor imageEditView. cg@2764: imageEditor loadFromImage: anImage cg@2764: ]. cg@2764: imageEditor openModal. cg@2764: cg@2766: newImage := imageEditor savedImage. cg@2764: ^ newImage cg@2764: ! cg@2764: cg@1966: openOnClass:aClass andSelector:aSelector cg@1966: "opens an Image Editor on aClass and aSelector" tz@400: cg@2764: self openLoadingImageWith:[:editor | cg@2764: editor loadFromClass:aClass theNonMetaclass andSelector:aSelector. sv@3357: ] modal:false. cg@1057: cg@1966: " cg@1966: self openOnClass:self andSelector:#leftMouseKeyIcon cg@1966: self openOnClass:self andSelector:nil cg@1966: " cg@1966: cg@1057: "Modified: / 16.3.1999 / 21:33:49 / cg" tz@400: ! tz@400: cg@1966: openOnFile:aFileName cg@1966: "opens an Image Editor on aFileName" tz@400: cg@2764: self openLoadingImageWith:[:editor | cg@2764: editor loadFromFile:aFileName. sv@3357: ] modal:false. cg@1057: cg@1966: " cg@1975: self openOnFile: '../../goodies/bitmaps/gifImages/back.gif' cg@1966: " cg@1966: cg@1057: "Modified: / 16.3.1999 / 21:33:25 / cg" tz@400: ! tz@400: cg@1966: openOnImage:anImage cg@1966: "opens an Image Editor on anImage" tz@400: cg@2764: self openLoadingImageWith:[:editor | cg@2764: editor loadFromImage: anImage. sv@3357: ] modal:false cg@1053: cg@1966: " cg@1966: self openOnImage: Icon startIcon cg@1966: " cg@1966: cg@1053: "Modified: / 11.3.1999 / 16:18:33 / cg" tz@400: ! ! tz@400: tz@400: !ImageEditor class methodsFor:'accessing'! tz@400: tz@400: listOfColorMaps tz@767: "returns the list of default color maps for a new image" tz@400: tz@400: |colorMap| tz@898: tz@400: (colorMap := OrderedCollection new) tz@400: add: Color black; tz@400: add: Color white; tz@400: add: Color red; tz@400: add: Color green; tz@400: add: Color blue; tz@400: add: Color cyan; tz@400: add: Color yellow; tz@400: add: Color magenta; tz@898: add: (Color redByte: 127 greenByte: 0 blueByte: 0); tz@898: add: (Color redByte: 0 greenByte: 127 blueByte: 0); tz@898: add: (Color redByte: 0 greenByte: 0 blueByte: 127); tz@898: add: (Color redByte: 0 greenByte: 127 blueByte: 127); tz@898: add: (Color redByte: 127 greenByte: 127 blueByte: 0); tz@898: add: (Color redByte: 127 greenByte: 0 blueByte: 127); tz@898: add: (Color redByte: 127 greenByte: 127 blueByte: 127); tz@898: add: (Color redByte: 170 greenByte: 170 blueByte: 170). tz@898: cg@3346: 0 to: 5 do: [:r| cg@3346: 0 to: 5 do: [:g| cg@3346: 0 to: 5 do: [:b| tz@898: colorMap add: (Color redByte: (r*255//5) ceiling greenByte: (g*255//5) ceiling blueByte: (b*255//5) ceiling) tz@400: ] tz@400: ] tz@400: ]. tz@400: cg@3346: 1 to: 25 do: [:g| tz@898: colorMap add: (Color redByte: (g*255//26) ceiling greenByte: (g*255//26) ceiling blueByte: (g*255//26) ceiling) tz@400: ]. tz@400: cg@1847: ^ Dictionary new cg@2571: at: #depth32 put:(FixedPalette redShift:16 redMask:16rFF greenShift:8 greenMask:16rFF blueShift:0 blueMask:16rFF); cg@1847: at: #depth24 put:(FixedPalette redShift:16 redMask:16rFF greenShift:8 greenMask:16rFF blueShift:0 blueMask:16rFF); cg@1847: at: #masked24 put:(FixedPalette redShift:16 redMask:16rFF greenShift:8 greenMask:16rFF blueShift:0 blueMask:16rFF); cg@1847: at: #depth16 put:(FixedPalette redShift:11 redMask:16r1F greenShift:5 greenMask:16r3F blueShift:0 blueMask:16r1F); cg@1847: at: #masked16 put:(FixedPalette redShift:11 redMask:16r1F greenShift:5 greenMask:16r3F blueShift:0 blueMask:16r1F); cg@1847: at: #depth8 put: colorMap; cg@1847: at: #masked8 put: colorMap; cg@1847: at: #depth4 put: (colorMap copyFrom: 1 to: 16); cg@1847: at: #masked4 put: (colorMap copyFrom: 1 to: 16); cg@1847: at: #depth2 put: (colorMap copyFrom: 1 to: 4); cg@1847: at: #masked2 put: (colorMap copyFrom: 1 to: 4); cg@1847: at: #depth1 put: (colorMap copyFrom: 1 to: 2); cg@1847: at: #masked1 put: (colorMap copyFrom: 1 to: 2); tz@400: yourself tz@400: ! tz@400: tz@400: listOfDefaultSizes tz@767: "returns the list of default sizes for a new image" tz@400: cg@1960: ^ #('8x8' '16x16' '22x22' '32x32' '48x48' '64x64') cg@932: cg@932: "Modified: / 31.7.1998 / 01:57:34 / cg" cg@1847: ! cg@1847: cg@1847: namesOfColorMaps cg@1847: ^ Dictionary new cg@2571: at: #depth32 put: '32-plane (rgba)'; cg@1847: at: #depth24 put: '24-plane'; cg@1847: at: #masked24 put: '24-plane + mask'; cg@1847: at: #depth16 put: '16-plane'; cg@1847: at: #masked16 put: '16-plane + mask'; cg@1847: at: #depth8 put: ' 8-plane'; cg@1847: at: #masked8 put: ' 8-plane + mask'; cg@1847: at: #depth4 put: ' 4-plane'; cg@1847: at: #masked4 put: ' 4-plane + mask'; cg@1847: at: #depth2 put: ' 2-plane'; cg@1847: at: #masked2 put: ' 2-plane + mask'; cg@1847: at: #depth1 put: ' 1-plane'; cg@1847: at: #masked1 put: ' 1-plane + mask' ; cg@1847: yourself tz@400: ! ! tz@400: tz@460: !ImageEditor class methodsFor:'help specs'! tz@460: cg@1545: flyByHelpSpec cg@1545: cg@1545: cg@2871: ^super flyByHelpSpec addPairsFrom:(self localHelpTexts) cg@2871: cg@2871: "Modified: / 19-01-2012 / 13:29:48 / cg" cg@1545: ! cg@1545: tz@460: helpSpec tz@737: "This resource specification was automatically generated tz@737: by the UIHelpTool of ST/X." tz@737: tz@737: "Do not manually edit this!! If it is corrupted, tz@737: the UIHelpTool may not be able to read the specification." tz@460: tz@460: " tz@737: UIHelpTool openOnClass:ImageEditor tz@460: " tz@460: tz@737: tz@737: cg@2871: ^ super helpSpec addPairsFrom:(self localHelpTexts) cg@2871: cg@2871: "Modified: / 19-01-2012 / 13:29:42 / cg" cg@2871: ! cg@2871: cg@2871: localHelpTexts cg@2871: "This resource specification was automatically generated cg@2871: by the UIHelpTool of ST/X." cg@2871: cg@2871: "Do not manually edit this!! If it is corrupted, cg@2871: the UIHelpTool may not be able to read the specification." cg@2871: cg@2871: " cg@2871: UIHelpTool openOnClass:ImageEditor cg@2871: " cg@2871: cg@2871: cg@2871: cg@2871: ^ #( cg@2871: cg@2871: #xdrawModeBox cg@2871: 'Rectangle' cg@2871: cg@2871: #xdrawModeCopy cg@2871: 'Copy' cg@2871: cg@2871: #xdrawModeFill cg@2871: 'Flood-fill' cg@2871: cg@2871: #xdrawModeFilledBox cg@2871: 'Filled rectangle' cg@2871: cg@2871: #xdrawModePaste cg@2871: 'Paste' cg@2871: cg@2871: #xdrawModePasteUnder cg@2871: 'Paste under' cg@2871: cg@2871: #xdrawModePasteWithMask cg@2871: 'Paste with Mask' cg@2871: cg@2871: #xdrawModePoint cg@2871: 'Point' cg@2871: cg@2871: #xfileGrabImage cg@2871: 'Pick from screen' cg@2871: cg@2871: #xfileLoadFromClass cg@2871: 'Load from method...' cg@2871: cg@2871: #xfileLoadFromFile cg@2871: 'Load from file...' cg@2871: cg@2871: #xfileNewImage cg@2871: 'New image' cg@2871: cg@2871: #filePrint cg@2871: 'Print' cg@2871: cg@2871: #xfileSaveAs cg@2871: 'Save to file...' cg@2871: cg@2871: #xfileSaveMaskAs cg@2871: 'Save mask to file...' cg@2871: cg@2871: #xfileSaveMethod cg@2871: 'Save as method' cg@2871: cg@2871: #xfileSaveMethodAs cg@2871: 'Save as Method...' cg@2871: cg@2871: #nextImageInSequence cg@2871: 'Go to the next image in the animated gif image sequence.' cg@2871: cg@2871: #previousImageInSequence cg@2871: 'Go to the previous image in the animated gif image sequence.' tz@460: tz@460: #colorMap cg@2765: 'ColorMap functions' cg@929: cg@929: #colorMap1 cg@2765: 'Convert to depth-1 image' cg@929: cg@986: #colorMap1M cg@2765: 'Convert to depth-1 image plus mask' cg@986: cg@929: #colorMap2 cg@2765: 'Convert to depth-2 image' cg@2765: cg@2765: #colorMap24 cg@2765: 'Convert to depth-24 image (rgb)' cg@929: cg@986: #colorMap2M cg@2765: 'Convert to depth-2 image plus mask' cg@2765: cg@2765: #colorMap32 cg@2765: 'Convert to depth-32 image (rgba)' cg@986: cg@929: #colorMap4 cg@2765: 'Convert to depth-4 image' cg@929: cg@986: #colorMap4M cg@2765: 'Convert to depth-4 image plus mask' cg@986: cg@929: #colorMap8 cg@2765: 'Convert to depth-8 image' cg@929: cg@929: #colorMap8M cg@2765: 'Convert to depth-8 image plus mask' cg@2571: cg@986: #colorMapTable cg@2765: 'Shows a list of used colors of the image' cg@986: cg@929: #compressColormap cg@2765: 'Remove unneeded entries from the colorMap' tz@460: cg@1045: #cropAll cg@2765: 'Find and remove all borders' cg@986: cg@1045: #cropBottom cg@2765: 'Find and remove bottom border' cg@986: cg@1045: #cropLeft cg@2765: 'Find and remove left border' cg@986: cg@1045: #cropManual cg@986: 'Specify border(s) to remove.' cg@986: cg@1045: #cropRight cg@2765: 'Find and remove right border' cg@986: cg@1045: #cropTop cg@2765: 'Find and remove top border' tz@487: tz@460: #drawModeBox cg@2765: 'Rectangle Drawing Mode' tz@460: cg@2375: #drawModeCircle cg@2765: 'Circle Drawing Mode' cg@2375: tz@460: #drawModeCopy cg@2765: 'Area Copy Mode' tz@460: tz@460: #drawModeFill cg@2765: 'Flood Fill Mode' tz@460: tz@460: #drawModeFilledBox cg@2765: 'Filled Rectangle Drawing Mode' tz@460: tz@460: #drawModePaste cg@2765: 'Paste Mode' cg@914: cg@914: #drawModePasteUnder cg@2765: 'Paste-Under Mode' cg@1637: cg@1637: #drawModePasteWithMask cg@2765: 'Paste-with-Mask Mode' tz@460: tz@460: #drawModePoint cg@2765: 'Point Drawing Mode' cg@2375: cg@1639: #drawModeSpecial cg@2871: 'Special operations (select rectangle, then choose operation)' cg@1639: cg@2765: #drawModeSpray cg@2765: 'Spray Drawing Mode' cg@2765: tz@460: #editFlipHorizontal cg@2765: 'Flip the image horizontally' tz@460: tz@460: #editFlipVertical cg@2765: 'Flip the image vertically' tz@460: tz@460: #editMagnifyImage cg@2765: 'Magnify the image' tz@460: tz@460: #editNegate cg@2765: 'Invert the images colors' tz@460: tz@460: #editResize cg@2765: 'Resize the image (preserving the old image)' tz@460: tz@460: #editRotate cg@2765: 'Rotate the image' tz@460: cg@2701: #fileGrabImageFromScreen cg@2765: 'Pick an image from the screen (specify area)' cg@2701: cg@2701: #fileGrabImageFromWindow cg@2765: 'Pick an image from a window on the screen (click on window)' cg@929: tz@460: #fileLoadFromClass cg@2765: 'Select and load an image from a resource method' tz@460: tz@460: #fileLoadFromFile cg@2765: 'Select and load an image from a file' tz@460: cg@2796: #fileLoadFromURL cg@2796: 'Load an image from the net, given its URL' cg@2796: tz@460: #fileNewImage cg@914: 'Create a new image' tz@460: cg@3200: #fileNewImageFromClipboard cg@3200: 'Create a new image and initialize it from the clipboard' cg@3200: cg@3200: #fileNewMaskFromClipboard cg@3200: 'Paste the image in the clipboard as a mask. Must be a depth-1 image' cg@3200: tz@460: #filePrint cg@2765: 'Print the image on a postscript printer' cg@2765: cg@2765: #fileSave cg@2765: 'Save the image' tz@460: tz@460: #fileSaveAs cg@2765: 'Save the image to a file' cg@2765: cg@2765: #fileSaveButtonImageAs cg@2765: 'Save an image of a button with the image to a file (for html use)' tz@460: tz@460: #fileSaveMaskAs cg@2765: 'Save the mask of the image to a file' ca@1613: tz@460: #fileSaveMethod cg@2765: 'Save the image as resource method in the current class and selector' tz@460: tz@460: #fileSaveMethodAs cg@2765: 'Save the image as resource method in a class' tz@460: tz@487: #magnificationNumber cg@2765: 'Shows the current magnification' tz@487: tz@487: #magnifyImageDown cg@2765: 'Decrease magnification' tz@487: tz@487: #magnifyImageUp cg@2765: 'Increase magnification' tz@487: tz@487: #mouseKeyColorMode cg@2765: 'Toggle between left and right mouse button color' tz@487: tz@487: #previewView cg@2765: 'Shows a preview of the image' tz@487: tz@905: #settingsGridMagnification cg@2765: 'Change the grid magnification of the edit view' tz@905: tz@460: ) cg@2871: cg@2871: "Created: / 19-01-2012 / 13:29:31 / cg" tz@460: ! ! tz@460: tz@737: !ImageEditor class methodsFor:'image specs'! tz@737: cg@2272: circleIcon sv@3121: cg@2272: "This resource specification was automatically generated cg@2272: by the ImageEditor of ST/X." cg@2272: "Do not manually edit this!! If it is corrupted, cg@2272: the ImageEditor may not be able to read the specification." cg@2272: " cg@2272: self circleIcon inspect cg@2272: ImageEditor openOnClass:self andSelector:#circleIcon sv@3121: Icon flushCachedIcons" sv@3121: sv@3121: ^ Icon constantNamed:'ImageEditor class circleIcon' sv@3121: ifAbsentPut:[ sv@3121: (Depth1Image new) sv@3121: width:14; sv@3121: height:14; sv@3121: photometric:(#palette); sv@3121: bitsPerSample:(#( 1 )); sv@3121: samplesPerPixel:(1); sv@3121: bits:(ByteArray sv@3121: fromPackedString:'@@@@@@@A@@@@@@@@@@@@@@@C@@@@@@@@@@@@@@@a'); sv@3121: colorMapFromArray:#[ 0 0 0 255 0 0 ]; sv@3121: mask:((ImageMask new) sv@3121: width:14; sv@3121: height:14; sv@3121: bits:(ByteArray sv@3121: fromPackedString:'@@@@@@N@CF@PDA@PH@ BB@HDA@PD@1 @8@@@@@a'); sv@3121: yourself); sv@3121: yourself sv@3121: ] cg@2272: ! cg@2272: cg@1637: copyIcon sv@3121: cg@1637: "This resource specification was automatically generated cg@1637: by the ImageEditor of ST/X." cg@1637: "Do not manually edit this!! If it is corrupted, cg@1637: the ImageEditor may not be able to read the specification." cg@1637: " cg@1637: self copyIcon inspect cg@1637: ImageEditor openOnClass:self andSelector:#copyIcon sv@3121: Icon flushCachedIcons" sv@3121: sv@3121: ^ Icon constantNamed:'ImageEditor class copyIcon' sv@3121: ifAbsentPut:[ sv@3121: (Depth2Image new) sv@3121: width:14; sv@3121: height:14; sv@3121: photometric:(#palette); sv@3121: bitsPerSample:(#( 2 )); sv@3121: samplesPerPixel:(1); sv@3121: bits:(ByteArray sv@3121: fromPackedString:'@@@@@@@@@@@** @@J)UUTB*Z*)@*&**PJ)**$B*Z*)@*&**PJ)**$@@Z*)@@F**P@AUUT@@@@@@b'); sv@3121: colorMapFromArray:#[ 0 0 0 0 0 128 255 255 255 ]; sv@3121: mask:((ImageMask new) sv@3121: width:14; sv@3121: height:14; sv@3121: bits:(ByteArray sv@3121: fromPackedString:'@@C? O>@??3??O? sv@2155: sv@2155: ^ ToolbarIconLibrary startImageEditorIcon sv@2155: ! sv@2155: cg@2871: fillGradientRectIcon sv@3121: cg@2871: "This resource specification was automatically generated cg@2871: by the ImageEditor of ST/X." cg@2871: "Do not manually edit this!! If it is corrupted, cg@2871: the ImageEditor may not be able to read the specification." cg@2871: " cg@2871: self fillGradientRectIcon inspect cg@2871: ImageEditor openOnClass:self andSelector:#fillGradientRectIcon sv@3121: Icon flushCachedIcons" sv@3121: sv@3121: ^ Icon constantNamed:'ImageEditor class fillGradientRectIcon' sv@3121: ifAbsentPut:[ sv@3121: (Depth4Image new) sv@3121: width:14; sv@3121: height:14; sv@3121: photometric:(#palette); sv@3121: bitsPerSample:(#[ 4 ]); sv@3121: samplesPerPixel:(1); sv@3121: bits:(ByteArray sv@3121: fromPackedString:'@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ADQDQDQ@@@QDQDQDP@@BH"H"H"@@@"H"H"H @@L3L3L3L@@CL3L3L3@@@QDQDQDP@@DQDQDQD@@@@@@@@@ sv@3121: @@@@@@@@@@@b'); sv@3121: colorMapFromArray:#[ 0 0 0 255 0 0 127 0 0 191 0 0 63 0 0 ]; sv@3121: mask:((ImageMask new) sv@3121: width:14; sv@3121: height:14; sv@3121: bits:(ByteArray sv@3121: fromPackedString:'@@@@@C?0O?@? cg@2871: "This resource specification was automatically generated cg@2871: by the ImageEditor of ST/X." cg@2871: "Do not manually edit this!! If it is corrupted, cg@2871: the ImageEditor may not be able to read the specification." cg@2871: " cg@2871: self fillHorizontalGradientRectIcon inspect cg@2871: ImageEditor openOnClass:self andSelector:#fillHorizontalGradientRectIcon sv@3121: Icon flushCachedIcons" sv@3121: sv@3121: ^ Icon constantNamed:'ImageEditor class fillHorizontalGradientRectIcon' sv@3121: ifAbsentPut:[ sv@3121: (Depth4Image new) sv@3121: width:14; sv@3121: height:14; sv@3121: photometric:(#palette); sv@3121: bitsPerSample:(#[ 4 ]); sv@3121: samplesPerPixel:(1); sv@3121: bits:(ByteArray sv@3121: fromPackedString:'@@@@@@@@@@@@@@@@@@@@@DP"L1D@@@ADH#LQ@@@@QBH3DP@@@DP"L1D@@@ADH#LQ@@@@QBH3DP@@@DP"L1D@@@ADH#LQ@@@@QBH3DP@@@DP"L1D@@@@@@@@@ sv@3121: @@@@@@@@@@@b'); sv@3121: colorMapFromArray:#[ 0 0 0 255 0 0 127 0 0 191 0 0 63 0 0 ]; sv@3121: mask:((ImageMask new) sv@3121: width:14; sv@3121: height:14; sv@3121: bits:(ByteArray sv@3121: fromPackedString:'@@@@@C?0O?@? cg@1637: "This resource specification was automatically generated cg@1637: by the ImageEditor of ST/X." cg@1637: "Do not manually edit this!! If it is corrupted, cg@1637: the ImageEditor may not be able to read the specification." cg@1637: " cg@1637: self fillIcon inspect cg@1637: ImageEditor openOnClass:self andSelector:#fillIcon sv@3121: Icon flushCachedIcons" sv@3121: sv@3121: ^ Icon constantNamed:'ImageEditor class fillIcon' sv@3121: ifAbsentPut:[ sv@3121: (Depth2Image new) sv@3121: width:14; sv@3121: height:14; sv@3121: photometric:(#palette); sv@3121: bitsPerSample:(#( 2 )); sv@3121: samplesPerPixel:(1); sv@3121: bits:(ByteArray sv@3121: fromPackedString:'@@@@@@@@@@@@@ @@@@*H@@D*(@@DUUP@EAUU@AAEU@@@@U@@DDA@@@@@@@@PP@@@@@@@@@@@@@@b'); sv@3121: colorMapFromArray:#[ 0 0 0 255 0 0 255 255 255 ]; sv@3121: mask:((ImageMask new) sv@3121: width:14; sv@3121: height:14; sv@3121: bits:(ByteArray sv@3121: fromPackedString:'C @Q@BN@I<@?8C?0[?!!G<@O P\@@ D@@@@@@@@@a'); sv@3121: yourself); sv@3121: yourself sv@3121: ] cg@1637: ! cg@1637: cg@1637: fillRectIcon sv@3121: cg@1637: "This resource specification was automatically generated cg@1637: by the ImageEditor of ST/X." cg@1637: "Do not manually edit this!! If it is corrupted, cg@1637: the ImageEditor may not be able to read the specification." cg@1637: " cg@1637: self fillRectIcon inspect cg@1637: ImageEditor openOnClass:self andSelector:#fillRectIcon sv@3121: Icon flushCachedIcons" sv@3121: sv@3121: ^ Icon constantNamed:'ImageEditor class fillRectIcon' sv@3121: ifAbsentPut:[ sv@3121: (Depth1Image new) sv@3121: width:14; sv@3121: height:14; sv@3121: photometric:(#palette); sv@3121: bitsPerSample:(#( 1 )); sv@3121: samplesPerPixel:(1); sv@3121: bits:(ByteArray sv@3121: fromPackedString:'@@@@@@@A@@@@@@@@@@@@@@@@@@@@@@@@@@D@@@@a'); sv@3121: colorMapFromArray:#[ 0 0 0 255 0 0 ]; sv@3121: mask:((ImageMask new) sv@3121: width:14; sv@3121: height:14; sv@3121: bits:(ByteArray sv@3121: fromPackedString:'@@@@@C?0O?@? cg@2871: "This resource specification was automatically generated cg@2871: by the ImageEditor of ST/X." cg@2871: "Do not manually edit this!! If it is corrupted, cg@2871: the ImageEditor may not be able to read the specification." cg@2871: " cg@2871: self fillGradientRectIcon inspect cg@2871: ImageEditor openOnClass:self andSelector:#fillGradientRectIcon sv@3121: Icon flushCachedIcons" sv@3121: sv@3121: ^ Icon constantNamed:'ImageEditor class fillGradientRectIcon' sv@3121: ifAbsentPut:[ sv@3121: (Depth4Image new) sv@3121: width:14; sv@3121: height:14; sv@3121: photometric:(#palette); sv@3121: bitsPerSample:(#[ 4 ]); sv@3121: samplesPerPixel:(1); sv@3121: bits:(ByteArray sv@3121: fromPackedString:'@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ADQDQDQ@@@QDQDQDP@@BH"H"H"@@@"H"H"H @@L3L3L3L@@CL3L3L3@@@QDQDQDP@@DQDQDQD@@@@@@@@@ sv@3121: @@@@@@@@@@@b'); sv@3121: colorMapFromArray:#[ 0 0 0 255 0 0 127 0 0 191 0 0 63 0 0 ]; sv@3121: mask:((ImageMask new) sv@3121: width:14; sv@3121: height:14; sv@3121: bits:(ByteArray sv@3121: fromPackedString:'@@@@@C?0O?@? cg@2837: "This resource specification was automatically generated cg@2837: by the ImageEditor of ST/X." cg@2837: "Do not manually edit this!! If it is corrupted, cg@2837: the ImageEditor may not be able to read the specification." cg@2837: " cg@2837: self flipHorizontalIcon inspect cg@2837: ImageEditor openOnClass:self andSelector:#flipHorizontalIcon sv@3121: Icon flushCachedIcons" sv@3121: sv@3121: ^ Icon constantNamed:'ImageEditor class flipHorizontalIcon' sv@3121: ifAbsentPut:[ sv@3121: (Depth1Image new) sv@3121: width:14; sv@3121: height:14; sv@3121: photometric:(#palette); sv@3121: bitsPerSample:(#( 1 )); sv@3121: samplesPerPixel:(1); sv@3121: bits:(ByteArray sv@3121: fromPackedString:'@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@a'); sv@3121: colorMapFromArray:#[ 0 0 0 ]; sv@3121: mask:((ImageMask new) sv@3121: width:14; sv@3121: height:14; sv@3121: bits:(ByteArray sv@3121: fromPackedString:'@@@A@C?8HP )JC$8_?1??C$8JR !!BC?8@P@@@@@a'); sv@3121: yourself); sv@3121: yourself sv@3121: ] cg@2837: ! cg@2837: cg@2837: flipVerticalIcon sv@3121: cg@2837: "This resource specification was automatically generated cg@2837: by the ImageEditor of ST/X." cg@2837: "Do not manually edit this!! If it is corrupted, cg@2837: the ImageEditor may not be able to read the specification." cg@2837: " cg@2837: self flipVerticalIcon inspect cg@2837: ImageEditor openOnClass:self andSelector:#flipVerticalIcon sv@3121: Icon flushCachedIcons" sv@3121: sv@3121: ^ Icon constantNamed:'ImageEditor class flipVerticalIcon' sv@3121: ifAbsentPut:[ sv@3121: (Depth1Image new) sv@3121: width:14; sv@3121: height:14; sv@3121: photometric:(#palette); sv@3121: bitsPerSample:(#( 1 )); sv@3121: samplesPerPixel:(1); sv@3121: bits:(ByteArray sv@3121: fromPackedString:'@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@a'); sv@3121: colorMapFromArray:#[ 0 0 0 ]; sv@3121: mask:((ImageMask new) sv@3121: width:14; sv@3121: height:14; sv@3121: bits:(ByteArray sv@3121: fromPackedString:'@@@C@C?0I9@/4BLPH1A?>BLPH1@/4B^PO?@C@@@a'); sv@3121: yourself); sv@3121: yourself sv@3121: ] cg@2837: ! cg@2837: tz@737: leftMouseKeyIcon sv@3121: tz@737: "This resource specification was automatically generated tz@737: by the ImageEditor of ST/X." tz@737: "Do not manually edit this!! If it is corrupted, tz@737: the ImageEditor may not be able to read the specification." tz@737: " cg@1405: self leftMouseKeyIcon inspect tz@737: ImageEditor openOnClass:self andSelector:#leftMouseKeyIcon sv@3121: Icon flushCachedIcons" sv@3121: sv@3121: ^ Icon constantNamed:'ImageEditor class leftMouseKeyIcon' sv@3121: ifAbsentPut:[ sv@3121: (Depth2Image new) sv@3121: width:16; sv@3121: height:16; sv@3121: photometric:(#palette); sv@3121: bitsPerSample:(#( 2 )); sv@3121: samplesPerPixel:(1); sv@3121: bits:(ByteArray sv@3121: fromPackedString:'@@@@@@@@@@@@@@@@@EJJ@@AR" @@T((@@@@@@@B** @@**(@@J**@@B** @@**(@@J**@@@**@@@@@@@@@@@@@@a'); sv@3121: colorMapFromArray:#[ 0 0 0 255 0 0 255 255 255 ]; sv@3121: mask:((ImageMask new) sv@3121: width:16; sv@3121: height:16; sv@3121: bits:(ByteArray sv@3121: fromPackedString:'@@@@@@?0G? _>A?8G? _>A?8G? _>A?8G? O<@_ @@@b'); sv@3121: yourself); sv@3121: yourself sv@3121: ] martin@1433: ! tz@737: cg@1637: pasteIcon sv@3121: cg@1637: "This resource specification was automatically generated cg@1637: by the ImageEditor of ST/X." cg@1637: "Do not manually edit this!! If it is corrupted, cg@1637: the ImageEditor may not be able to read the specification." cg@1637: " cg@1637: self pasteIcon inspect cg@1637: ImageEditor openOnClass:self andSelector:#pasteIcon sv@3121: Icon flushCachedIcons" sv@3121: sv@3121: ^ Icon constantNamed:'ImageEditor class pasteIcon' sv@3121: ifAbsentPut:[ sv@3121: (Depth4Image new) sv@3121: width:14; sv@3121: height:14; sv@3121: photometric:(#palette); sv@3121: bitsPerSample:(#( 4 )); sv@3121: samplesPerPixel:(1); sv@3121: bits:(ByteArray sv@3121: fromPackedString:'@@@@@@@@@@@@AU@@@@@CHE@E@2@@@ QDQD@0@@L@@@@@H@@BL#H2L#@@@QDQDQL @@D3L@@@@@@AL3A&Y&X@@SL0Y A&@@D3LF@@A @AL3A&@FX@@QDPY&Y& sv@3121: @@@@@@@@@@@b'); sv@3121: colorMapFromArray:#[ 0 0 0 0 0 128 128 128 0 128 128 128 212 208 200 255 255 0 255 255 255 ]; sv@3121: mask:((ImageMask new) sv@3121: width:14; sv@3121: height:14; sv@3121: bits:(ByteArray sv@3121: fromPackedString:'C0A?8O?0??C?O?8??#?>O?8_? G>@@a'); sv@3121: yourself); sv@3121: yourself sv@3121: ] cg@1637: ! cg@1637: cg@1637: pasteUnderIcon sv@3121: cg@1637: "This resource specification was automatically generated cg@1637: by the ImageEditor of ST/X." cg@1637: "Do not manually edit this!! If it is corrupted, cg@1637: the ImageEditor may not be able to read the specification." cg@1637: " cg@1637: self pasteUnderIcon inspect cg@1637: ImageEditor openOnClass:self andSelector:#pasteUnderIcon sv@3121: Icon flushCachedIcons" sv@3121: sv@3121: ^ Icon constantNamed:'ImageEditor class pasteUnderIcon' sv@3121: ifAbsentPut:[ sv@3121: (Depth4Image new) sv@3121: width:14; sv@3121: height:14; sv@3121: photometric:(#palette); sv@3121: bitsPerSample:(#( 4 )); sv@3121: samplesPerPixel:(1); sv@3121: bits:(ByteArray sv@3121: fromPackedString:'@@@@@@@@@@@@AU@@@@@CHE@E@2@@@ QDQD@0@@L@@@@@H@@BL#H2L#@@@QDQDQL @@D3L3LP@@@AL3L3E&X@@SL3L0A&@@D3L3@@A @AL3L3@FX@@QDQDQY& sv@3121: @@@@@@@@@@@b'); sv@3121: colorMapFromArray:#[ 0 0 0 0 0 128 128 128 0 128 128 128 212 208 200 255 255 0 255 255 255 ]; sv@3121: mask:((ImageMask new) sv@3121: width:14; sv@3121: height:14; sv@3121: bits:(ByteArray sv@3121: fromPackedString:'C0A?8O?0??C?O?8??#?>O?8_? G>@@a'); sv@3121: yourself); sv@3121: yourself sv@3121: ] cg@1637: ! cg@1637: cg@1637: pasteWithMaskIcon sv@3121: cg@1637: "This resource specification was automatically generated cg@1637: by the ImageEditor of ST/X." cg@1637: "Do not manually edit this!! If it is corrupted, cg@1637: the ImageEditor may not be able to read the specification." cg@1637: " cg@1637: self pasteWithMaskIcon inspect cg@1637: ImageEditor openOnClass:self andSelector:#pasteWithMaskIcon sv@3121: Icon flushCachedIcons" sv@3121: sv@3121: ^ Icon constantNamed:'ImageEditor class pasteWithMaskIcon' sv@3121: ifAbsentPut:[ sv@3121: (Depth4Image new) sv@3121: width:14; sv@3121: height:14; sv@3121: photometric:(#palette); sv@3121: bitsPerSample:(#( 4 )); sv@3121: samplesPerPixel:(1); sv@3121: bits:(ByteArray sv@3121: fromPackedString:'@@@@@@@@@@@@AU@@@@@CHE@E@2@@@ QDQD@0@@L@@@@@H@@BL#H2L#@@@QDQDQL @@D3L@@@@@@AL3@3M&X@@SL0L3A&@@D3LCL0A @AL3@3LFX@@QDPY&Y& sv@3121: @@@@@@@@@@@b'); sv@3121: colorMapFromArray:#[ 0 0 0 0 0 128 128 128 0 128 128 128 212 208 200 255 255 0 255 255 255 ]; sv@3121: mask:((ImageMask new) sv@3121: width:14; sv@3121: height:14; sv@3121: bits:(ByteArray sv@3121: fromPackedString:'C0A?8O?0??C?O?8??#?>O?8_? G>@@a'); sv@3121: yourself); sv@3121: yourself sv@3121: ] cg@1637: ! cg@1637: cg@1637: pointIcon sv@3121: cg@1637: "This resource specification was automatically generated cg@1637: by the ImageEditor of ST/X." cg@1637: "Do not manually edit this!! If it is corrupted, cg@1637: the ImageEditor may not be able to read the specification." cg@1637: " cg@1637: self pointIcon inspect cg@1637: ImageEditor openOnClass:self andSelector:#pointIcon sv@3121: Icon flushCachedIcons" sv@3121: sv@3121: ^ Icon constantNamed:'ImageEditor class pointIcon' sv@3121: ifAbsentPut:[ sv@3121: (Depth1Image new) sv@3121: width:14; sv@3121: height:14; sv@3121: photometric:(#palette); sv@3121: bitsPerSample:(#( 1 )); sv@3121: samplesPerPixel:(1); sv@3121: bits:(ByteArray sv@3121: fromPackedString:'@@@@@@@A@@@@@@@@@@@@@@@C@@@@@@@@@@@@@@@a'); sv@3121: colorMapFromArray:#[ 0 0 0 255 255 255 ]; sv@3121: mask:((ImageMask new) sv@3121: width:14; sv@3121: height:14; sv@3121: bits:(ByteArray sv@3121: fromPackedString:'@@@@@@@0@G@@8@G@@8@G@@8@G@@X@@@@@@@@@@@a'); sv@3121: yourself); sv@3121: yourself sv@3121: ] cg@1637: ! cg@1637: cg@1637: rectIcon sv@3121: cg@1637: "This resource specification was automatically generated cg@1637: by the ImageEditor of ST/X." cg@1637: "Do not manually edit this!! If it is corrupted, cg@1637: the ImageEditor may not be able to read the specification." cg@1637: " cg@1637: self rectIcon inspect cg@1637: ImageEditor openOnClass:self andSelector:#rectIcon sv@3121: Icon flushCachedIcons" sv@3121: sv@3121: ^ Icon constantNamed:'ImageEditor class rectIcon' sv@3121: ifAbsentPut:[ sv@3121: (Depth1Image new) sv@3121: width:14; sv@3121: height:14; sv@3121: photometric:(#palette); sv@3121: bitsPerSample:(#( 1 )); sv@3121: samplesPerPixel:(1); sv@3121: bits:(ByteArray sv@3121: fromPackedString:'@@@@@@@A@@@@@@@@@@@@@@@C@@@@@@@@@@@@@@@a'); sv@3121: colorMapFromArray:#[ 0 0 0 255 0 0 ]; sv@3121: mask:((ImageMask new) sv@3121: width:14; sv@3121: height:14; sv@3121: bits:(ByteArray sv@3121: fromPackedString:'@@@@@C?0HA@ DB@PHA@ DB@PHA@ DC?0@@@@@@@a'); sv@3121: yourself); sv@3121: yourself sv@3121: ] cg@1637: ! cg@1637: tz@737: rightMouseKeyIcon sv@3121: tz@737: "This resource specification was automatically generated tz@737: by the ImageEditor of ST/X." tz@737: "Do not manually edit this!! If it is corrupted, tz@737: the ImageEditor may not be able to read the specification." tz@737: " cg@1405: self rightMouseKeyIcon inspect tz@737: ImageEditor openOnClass:self andSelector:#rightMouseKeyIcon sv@3121: Icon flushCachedIcons" sv@3121: sv@3121: ^ Icon constantNamed:'ImageEditor class rightMouseKeyIcon' sv@3121: ifAbsentPut:[ sv@3121: (Depth2Image new) sv@3121: width:16; sv@3121: height:16; sv@3121: photometric:(#palette); sv@3121: bitsPerSample:(#( 2 )); sv@3121: samplesPerPixel:(1); sv@3121: bits:(ByteArray sv@3121: fromPackedString:'@@@@@@@@@@@@@@@@@JJE@@B"!!P@@((T@@@@@@@B** @@**(@@J**@@B** @@**(@@J**@@@**@@@@@@@@@@@@@@a'); sv@3121: colorMapFromArray:#[ 0 0 0 255 0 0 255 255 255 ]; sv@3121: mask:((ImageMask new) sv@3121: width:16; sv@3121: height:16; sv@3121: bits:(ByteArray sv@3121: fromPackedString:'@@@@@@?0G? _>A?8G? _>A?8G? _>A?8G? O<@_ @@@b'); sv@3121: yourself); sv@3121: yourself sv@3121: ] cg@1637: ! cg@1637: cg@3191: smoothIcon cg@3191: "This resource specification was automatically generated cg@3191: by the ImageEditor of ST/X." cg@3191: cg@3191: "Do not manually edit this!! If it is corrupted, cg@3191: the ImageEditor may not be able to read the specification." cg@3191: cg@3191: " cg@3191: self smoothIcon inspect cg@3191: ImageEditor openOnClass:self andSelector:#smoothIcon cg@3191: Icon flushCachedIcons cg@3191: " cg@3191: cg@3191: cg@3191: cg@3191: ^Icon cg@3191: constantNamed:'ImageEditor smoothIcon' cg@3191: ifAbsentPut:[(Depth4Image new) width:14; height:14; bits:(ByteArray fromPackedString:'@@@@@@@@@@@RH@@@H!!@@HRD@@RD @BHQ@@DRH@@ADP@ADP@@@@@QD@@@@@@@DQ@@@@@@@ADP@@@@@QD@@QD@@BHQ@@DRH@@!!HP@AHR@@D"@@@BHP@@@@@@@@ cg@3191: @@@@@@@@@@@b') ; colorMapFromArray:#[127 126 127 255 0 0 255 255 255]; mask:((ImageMask new) width:14; height:14; bits:(ByteArray fromPackedString:'_?1<_G1<_G1??D_DQ cg@2881: "This resource specification was automatically generated cg@2881: by the ImageEditor of ST/X." cg@2881: "Do not manually edit this!! If it is corrupted, cg@2881: the ImageEditor may not be able to read the specification." cg@2881: " cg@2881: self specialCircleIcon inspect cg@2881: ImageEditor openOnClass:self andSelector:#specialCircleIcon sv@3121: Icon flushCachedIcons" sv@3121: sv@3121: ^ Icon constantNamed:'ImageEditor class specialCircleIcon' sv@3121: ifAbsentPut:[ sv@3121: (Depth1Image new) sv@3121: width:14; sv@3121: height:14; sv@3121: photometric:(#palette); sv@3121: bitsPerSample:(#( 1 )); sv@3121: samplesPerPixel:(1); sv@3121: bits:(ByteArray sv@3121: fromPackedString:'@@L@@@!!BDB@ D4@HP@!!@BD@HHA@PHP!!@@@@@@@@a'); sv@3121: colorMapFromArray:#[ 0 0 0 255 0 0 ]; sv@3121: mask:((ImageMask new) sv@3121: width:14; sv@3121: height:14; sv@3121: bits:(ByteArray sv@3121: fromPackedString:'@@@@@@-@D2@''$D^HQ8!!G"DLHH1@PH@-@@0@@@@@a'); sv@3121: yourself); sv@3121: yourself sv@3121: ] cg@2881: ! cg@2881: cg@1637: specialIcon sv@3121: cg@1637: "This resource specification was automatically generated cg@1637: by the ImageEditor of ST/X." cg@1637: "Do not manually edit this!! If it is corrupted, cg@1637: the ImageEditor may not be able to read the specification." cg@1637: " cg@1637: self specialIcon inspect cg@1637: ImageEditor openOnClass:self andSelector:#specialIcon sv@3121: Icon flushCachedIcons" sv@3121: sv@3121: ^ Icon constantNamed:'ImageEditor class specialIcon' sv@3121: ifAbsentPut:[ sv@3121: (Depth1Image new) sv@3121: width:14; sv@3121: height:14; sv@3121: photometric:(#palette); sv@3121: bitsPerSample:(#( 1 )); sv@3121: samplesPerPixel:(1); sv@3121: bits:(ByteArray sv@3121: fromPackedString:'@@L@@G!!:P@!!@B4@HP@!!@BD@HP@!!@BW!!8@@@@@@@a'); sv@3121: colorMapFromArray:#[ 0 0 0 255 0 0 ]; sv@3121: mask:((ImageMask new) sv@3121: width:14; sv@3121: height:14; sv@3121: bits:(ByteArray sv@3121: fromPackedString:'@@@@@G-8P0!!G"D^HQ8!!G"DLHP0!!@BG-8@0@@@@@a'); sv@3121: yourself); sv@3121: yourself sv@3121: ] cg@2375: ! cg@2375: cg@2375: sprayIcon cg@2375: "This resource specification was automatically generated cg@2375: by the ImageEditor of ST/X." cg@3191: cg@2375: "Do not manually edit this!! If it is corrupted, cg@2375: the ImageEditor may not be able to read the specification." cg@3191: cg@2375: " cg@2375: self sprayIcon inspect cg@2375: ImageEditor openOnClass:self andSelector:#sprayIcon cg@3191: Icon flushCachedIcons cg@3191: " cg@3191: cg@3191: cg@3191: cg@3191: ^Icon cg@3191: constantNamed:'ImageEditor sprayIcon' cg@3191: ifAbsentPut:[(Depth4Image new) width:14; height:14; bits:(ByteArray fromPackedString:'@@@@@@@@@@@@@@@@@@@@@@@@@@@P@@@@@@DA@P@@@@@PDA@@@@@@@PDA@@@@@@@PD@@@@"H@@PD@@@H"@@@@@@@ADP@@@@@@@QD@@@@@@@DQ@@@@@@@ADP@@ cg@3191: @@@@@@@@@@@b') ; colorMapFromArray:#[0 0 0 255 0 0 255 255 255]; mask:((ImageMask new) width:14; height:14; bits:(ByteArray fromPackedString:'@@@@@@@HA%PF*@ITA2 O%@>@C8@O @>@C8@O @@a') ; yourself); yourself] martin@1433: ! ! tz@737: tz@400: !ImageEditor class methodsFor:'interface specs'! tz@400: cg@1650: changeHLSDialogSpec cg@1650: "This resource specification was automatically generated cg@1650: by the UIPainter of ST/X." cg@1650: cg@1650: "Do not manually edit this!! If it is corrupted, cg@1650: the UIPainter may not be able to read the specification." cg@1650: cg@1650: " cg@1650: UIPainter new openOnClass:ImageEditor andSelector:#changeHLSDialogSpec cg@1650: ImageEditor new openInterface:#changeHLSDialogSpec cg@1650: " cg@1650: cg@1650: cg@1650: cg@1650: ^ sv@1740: #(FullSpec sv@1740: name: changeHLSDialogSpec sv@1740: window: sv@1740: (WindowSpec sv@1740: label: 'HLS Edit Dialog' sv@1740: name: 'HLS Edit Dialog' sv@1740: min: (Point 10 10) cg@2438: bounds: (Rectangle 0 0 312 258) cg@1650: ) sv@1740: component: sv@1740: (SpecCollection sv@1740: collection: ( sv@1740: (LabelSpec sv@1740: label: 'Hue-Shift:' sv@1740: name: 'HueLabel' sv@1740: layout: (LayoutFrame 20 0 21 0 120 0 43 0) sv@1740: translateLabel: true sv@1740: adjust: right sv@1740: ) sv@1740: (InputFieldSpec sv@1740: name: 'HueShiftEntryField' sv@1740: layout: (LayoutFrame 123 0 21 0 166 0 43 0) sv@1740: tabable: true sv@1740: model: hueShiftAmount sv@1740: type: numberInRange sv@1740: minValue: 0 sv@1740: maxValue: 360 sv@1740: acceptChannel: acceptChannel sv@1740: acceptOnPointerLeave: false sv@1740: ) sv@1740: (ThumbWheelSpec sv@1740: name: 'HueWheel' sv@1740: layout: (LayoutFrame 180 0 22 0 297 0 42 0) sv@1740: model: hueShiftAmount sv@1740: orientation: horizontal sv@1740: step: 1 sv@1740: endlessRotation: true sv@1740: ) sv@1740: (LabelSpec sv@1740: label: 'Light Factor:' sv@1740: name: 'LightLabel' sv@1740: layout: (LayoutFrame 18 0 50 0 120 0 72 0) sv@1740: translateLabel: true sv@1740: adjust: right sv@1740: ) sv@1740: (InputFieldSpec sv@1740: name: 'LightEntryField' sv@1740: layout: (LayoutFrame 123 0 50 0 166 0 72 0) sv@1740: tabable: true sv@1740: model: lightAmount sv@1740: type: numberInRange sv@1740: minValue: 0 sv@1740: maxValue: 1000 sv@1740: acceptChannel: acceptChannel sv@1740: acceptOnPointerLeave: false cg@1650: ) sv@1740: (ThumbWheelSpec sv@1740: name: 'LightWheel' sv@1740: layout: (LayoutFrame 180 0 51 0 297 0 71 0) sv@1740: model: lightAmount sv@1740: orientation: horizontal sv@1740: stop: 1000 sv@1740: step: 1 sv@1740: ) sv@1740: (LabelSpec sv@1740: label: 'Saturation Factor:' sv@1740: name: 'SaturationLabel' sv@1740: layout: (LayoutFrame 9 0 79 0 120 0 101 0) sv@1740: translateLabel: true sv@1740: adjust: right sv@1740: ) sv@1740: (InputFieldSpec sv@1740: name: 'SaturationEntryField' sv@1740: layout: (LayoutFrame 123 0 79 0 166 0 101 0) sv@1740: tabable: true sv@1740: model: saturationAmount sv@1740: type: numberInRange sv@1740: minValue: 0 sv@1740: maxValue: 1000 sv@1740: acceptChannel: acceptChannel sv@1740: acceptOnPointerLeave: false sv@1740: ) sv@1740: (ThumbWheelSpec sv@1740: name: 'SaturationWheel' sv@1740: layout: (LayoutFrame 180 0 80 0 297 0 100 0) sv@1740: model: saturationAmount sv@1740: orientation: horizontal sv@1740: stop: 1000 sv@1740: step: 1 cg@1650: ) sv@1740: (LabelSpec cg@2438: label: 'Color Shift' cg@2438: name: 'Label2' cg@2438: layout: (LayoutFrame 5 0 110 0 -15 0.5 132 0) cg@2438: translateLabel: true cg@2438: ) cg@2438: (LabelSpec sv@1740: name: 'HueColorLabel' cg@2438: layout: (LayoutFrame 18 0.0 133 0 -41 0.5 217 0) cg@2438: level: -1 cg@1975: backgroundChannel: hlsColor sv@1740: translateLabel: true cg@1650: ) cg@2438: (LabelSpec cg@2438: label: 'Preview' cg@2438: name: 'Label3' cg@2438: layout: (LayoutFrame 5 0.5 110 0 -5 1 132 0) cg@2438: translateLabel: true cg@2438: ) cg@2438: (LabelSpec cg@2438: name: 'PreviewLabel' cg@2438: layout: (LayoutFrame 36 0.5 133 0 -23 1.0 217 0) cg@2438: level: -1 cg@2438: translateLabel: true cg@2438: labelChannel: previewImageHolder cg@2438: ) sv@1740: (HorizontalPanelViewSpec sv@1740: name: 'HorizontalPanel1' sv@1740: layout: (LayoutFrame 0 0.0 -30 1 0 1.0 0 1) sv@1740: horizontalLayout: fitSpace sv@1740: verticalLayout: center sv@1740: horizontalSpace: 3 sv@1740: verticalSpace: 3 sv@1740: reverseOrderIfOKAtLeft: true sv@1740: component: sv@1740: (SpecCollection sv@1740: collection: ( sv@1740: (ActionButtonSpec sv@1740: label: 'Cancel' sv@1740: name: 'Button1' sv@1740: translateLabel: true sv@1740: tabable: true sv@1740: model: cancel sv@1740: extent: (Point 151 22) sv@1740: ) sv@1740: (ActionButtonSpec sv@1740: label: 'OK' sv@1740: name: 'Button2' sv@1740: translateLabel: true sv@1740: tabable: true sv@1740: model: accept sv@1740: extent: (Point 152 22) sv@1740: ) sv@1740: ) sv@1740: sv@1740: ) cg@1650: ) sv@1740: ) sv@1740: sv@1740: ) sv@1740: ) sv@1740: ! sv@1740: sv@1740: cropDialogSpec sv@1740: "This resource specification was automatically generated sv@1740: by the UIPainter of ST/X." sv@1740: sv@1740: "Do not manually edit this!! If it is corrupted, sv@1740: the UIPainter may not be able to read the specification." sv@1740: sv@1740: " sv@1740: UIPainter new openOnClass:ImageEditor andSelector:#cropDialogSpec sv@1740: ImageEditor new openInterface:#cropDialogSpec sv@1740: " sv@1740: sv@1740: sv@1740: sv@1740: ^ sv@1740: #(FullSpec sv@1740: name: cropDialogSpec sv@1740: window: sv@1740: (WindowSpec sv@1740: label: 'Crop Border(s)' sv@1740: name: 'Crop Border(s)' sv@1740: min: (Point 10 10) sv@1740: bounds: (Rectangle 14 46 259 229) sv@1740: ) sv@1740: component: sv@1740: (SpecCollection sv@1740: collection: ( sv@1740: (LabelSpec sv@1740: label: 'Left:' sv@1740: name: 'GropLeftLabel' sv@1740: layout: (LayoutFrame 14 0 21 0 90 0 43 0) sv@1740: translateLabel: true sv@1740: adjust: right cg@1650: ) sv@1740: (InputFieldSpec sv@1740: name: 'GropLeftEntryField' sv@1740: layout: (LayoutFrame 95 0 21 0 132 0 43 0) sv@1740: tabable: true sv@1740: model: left sv@1740: type: number sv@1740: acceptChannel: acceptChannel sv@1740: acceptOnPointerLeave: false sv@1740: ) sv@1740: (ActionButtonSpec sv@1740: label: 'Now' sv@1740: name: 'GropLeftNowButton' sv@1740: layout: (LayoutFrame 148 0 21 0 221 0 43 0) sv@1740: translateLabel: true sv@1740: tabable: true sv@1740: model: gropLeftNow sv@1740: autoRepeat: true cg@1650: ) sv@1740: (LabelSpec sv@1740: label: 'Right:' sv@1740: name: 'GropRightLabel' sv@1740: layout: (LayoutFrame 14 0 51 0 90 0 73 0) sv@1740: translateLabel: true sv@1740: adjust: right sv@1740: ) sv@1740: (InputFieldSpec sv@1740: name: 'GropRightEntryField' sv@1740: layout: (LayoutFrame 95 0 51 0 132 0 73 0) sv@1740: tabable: true sv@1740: model: right sv@1740: type: number sv@1740: acceptChannel: acceptChannel sv@1740: acceptOnPointerLeave: false sv@1740: ) sv@1740: (ActionButtonSpec sv@1740: label: 'Now' sv@1740: name: 'GropRightButton' sv@1740: layout: (LayoutFrame 148 0 51 0 221 0 73 0) sv@1740: translateLabel: true sv@1740: tabable: true sv@1740: model: gropRightNow sv@1740: autoRepeat: true cg@1650: ) sv@1740: (LabelSpec sv@1740: label: 'Top:' sv@1740: name: 'GropTopLabel' sv@1740: layout: (LayoutFrame 14 0 81 0 90 0 103 0) sv@1740: translateLabel: true sv@1740: adjust: right sv@1740: ) sv@1740: (InputFieldSpec sv@1740: name: 'GropTopEntryField' sv@1740: layout: (LayoutFrame 95 0 81 0 132 0 103 0) sv@1740: tabable: true sv@1740: model: top sv@1740: type: number sv@1740: acceptChannel: acceptChannel sv@1740: acceptOnPointerLeave: false cg@1650: ) sv@1740: (ActionButtonSpec sv@1740: label: 'Now' sv@1740: name: 'GropTopButton' sv@1740: layout: (LayoutFrame 148 0 81 0 221 0 103 0) sv@1740: translateLabel: true sv@1740: tabable: true sv@1740: model: gropTopNow sv@1740: autoRepeat: true sv@1740: ) sv@1740: (LabelSpec sv@1740: label: 'Bottom:' sv@1740: name: 'GropBottomLabel' sv@1740: layout: (LayoutFrame 14 0 111 0 90 0 133 0) sv@1740: translateLabel: true sv@1740: adjust: right sv@1740: ) sv@1740: (InputFieldSpec sv@1740: name: 'GropBottomEntryField' sv@1740: layout: (LayoutFrame 95 0 111 0 132 0 133 0) sv@1740: tabable: true sv@1740: model: bottom sv@1740: type: number sv@1740: acceptChannel: acceptChannel sv@1740: acceptOnPointerLeave: false cg@1650: ) sv@1740: (ActionButtonSpec sv@1740: label: 'Now' sv@1740: name: 'GropBottomButton' sv@1740: layout: (LayoutFrame 148 0 111 0 221 0 133 0) sv@1740: translateLabel: true sv@1740: tabable: true sv@1740: model: gropBottomNow sv@1740: autoRepeat: true sv@1740: ) sv@1740: (HorizontalPanelViewSpec sv@1740: name: 'HorizontalPanel1' sv@1740: layout: (LayoutFrame 0 0.0 -30 1 0 1.0 0 1) sv@1740: horizontalLayout: fitSpace sv@1740: verticalLayout: center sv@1740: horizontalSpace: 3 sv@1740: verticalSpace: 3 sv@1740: reverseOrderIfOKAtLeft: true sv@1740: component: sv@1740: (SpecCollection sv@1740: collection: ( sv@1740: (ActionButtonSpec sv@1740: label: 'Cancel' sv@1740: name: 'Button1' sv@1740: translateLabel: true sv@1740: tabable: true sv@1740: model: cancel sv@1740: extent: (Point 77 22) cg@1650: ) sv@1740: (ActionButtonSpec sv@1740: label: 'Apply' sv@1740: name: 'Button3' sv@1740: translateLabel: true sv@1740: tabable: true sv@1740: model: applyAction sv@1740: extent: (Point 78 22) sv@1740: ) sv@1740: (ActionButtonSpec sv@1740: label: 'OK' sv@1740: name: 'Button2' sv@1740: translateLabel: true sv@1740: tabable: true sv@1740: model: accept sv@1740: extent: (Point 78 22) cg@1650: ) cg@1650: ) cg@1650: cg@1650: ) cg@1650: ) cg@1650: ) cg@1650: cg@1650: ) cg@1650: ) cg@1650: ! cg@1650: tz@767: dialogSpecForNewImage tz@737: "This resource specification was automatically generated tz@737: by the UIPainter of ST/X." tz@519: tz@737: "Do not manually edit this!! If it is corrupted, tz@737: the UIPainter may not be able to read the specification." tz@519: tz@519: " tz@767: UIPainter new openOnClass:ImageEditor andSelector:#dialogSpecForNewImage tz@767: ImageEditor new openInterface:#dialogSpecForNewImage tz@519: " tz@519: tz@519: tz@519: cg@1457: ^ sv@1740: #(FullSpec sv@1740: name: dialogSpecForNewImage sv@1740: window: sv@1740: (WindowSpec sv@1740: label: 'New Image' sv@1740: name: 'New Image' sv@1740: min: (Point 10 10) cg@1806: bounds: (Rectangle 0 0 301 119) cg@1457: ) sv@1740: component: sv@1740: (SpecCollection sv@1740: collection: ( sv@1740: (ViewSpec sv@1740: name: 'View' sv@1740: layout: (LayoutFrame 0 0.0 0 0.0 0 1.0 -35 1.0) sv@1740: level: 1 sv@1740: component: sv@1740: (SpecCollection sv@1740: collection: ( sv@1740: (FramedBoxSpec sv@1740: label: 'Size' sv@1740: name: 'framedBox1' sv@1740: layout: (LayoutFrame 1 0.0 7 0.0 0 0.4 76 0) cg@1806: style: (FontDescription helvetica medium roman 12) sv@1740: labelPosition: topLeft cg@1806: translateLabel: true sv@1740: component: sv@1740: (SpecCollection sv@1740: collection: ( sv@1740: (ComboBoxSpec sv@1740: name: 'defaultSizesComboBox' sv@1740: layout: (LayoutFrame 0 0.0 10 0.0 0 1 35 0.0) sv@1740: model: selectionOfSize sv@1740: type: string sv@1740: acceptOnPointerLeave: false sv@1740: comboList: listOfDefaultSizes sv@1740: isFilenameBox: false sv@1740: ) sv@1740: ) sv@1740: sv@1740: ) cg@1490: ) sv@1740: (FramedBoxSpec sv@1740: label: 'Color Map' sv@1740: name: 'framedBox2' sv@1740: layout: (LayoutFrame 0 0.4 7 0.0 -1 1.0 76 0) cg@1806: style: (FontDescription helvetica medium roman 12) sv@1740: labelPosition: topLeft cg@1806: translateLabel: true sv@1740: component: sv@1740: (SpecCollection sv@1740: collection: ( sv@1740: (ComboListSpec sv@1740: name: 'colorMapComboBox' sv@1740: layout: (LayoutFrame 0 0.0 10 0.0 0 1 35 0.0) sv@1740: model: selectionOfColorMap sv@1740: comboList: listOfColorMaps sv@1740: useIndex: false cg@1847: hidePullDownMenuButton: false sv@1740: ) sv@1740: ) sv@1740: sv@1740: ) cg@1457: ) cg@1457: ) cg@1457: cg@986: ) cg@1457: ) sv@1740: (UISubSpecification sv@1740: name: 'windowSpecForCommitWithoutChannels' sv@1740: layout: (LayoutFrame 2 0.0 -26 1 -2 1.0 -2 1.0) sv@1740: minorKey: windowSpecForCommitWithoutChannels sv@1740: ) cg@1457: ) cg@1457: cg@1457: ) cg@986: ) cg@986: ! cg@986: cg@1557: shiftDialogSpec cg@1557: "This resource specification was automatically generated cg@1557: by the UIPainter of ST/X." cg@1557: cg@1557: "Do not manually edit this!! If it is corrupted, cg@1557: the UIPainter may not be able to read the specification." cg@1557: cg@1557: " cg@1557: UIPainter new openOnClass:ImageEditor andSelector:#shiftDialogSpec cg@1557: ImageEditor new openInterface:#shiftDialogSpec cg@1557: " cg@1557: cg@1557: cg@1557: cg@1557: ^ sv@1740: #(FullSpec sv@1740: name: shiftDialogSpec sv@1740: window: sv@1740: (WindowSpec sv@1740: label: 'Shift' sv@1740: name: 'Shift' sv@1740: min: (Point 10 10) sv@1740: bounds: (Rectangle 14 46 259 229) cg@1557: ) sv@1740: component: sv@1740: (SpecCollection sv@1740: collection: ( sv@1740: (LabelSpec sv@1740: label: 'Amount:' sv@1740: name: 'AmountLabel' sv@1740: layout: (LayoutFrame 14 0 21 0 90 0 43 0) sv@1740: translateLabel: true sv@1740: adjust: right cg@1557: ) sv@1740: (InputFieldSpec sv@1740: name: 'AmountEntryField' sv@1740: layout: (LayoutFrame 95 0 21 0 139 0 43 0) sv@1740: tabable: true sv@1740: model: shiftAmount sv@1740: type: number sv@1740: acceptChannel: acceptChannel sv@1740: acceptOnPointerLeave: false cg@1557: ) sv@1740: (HorizontalPanelViewSpec sv@1740: name: 'HorizontalPanel1' sv@1740: layout: (LayoutFrame 0 0.0 -30 1 0 1.0 0 1) sv@1740: horizontalLayout: fitSpace sv@1740: verticalLayout: center sv@1740: horizontalSpace: 3 sv@1740: verticalSpace: 3 sv@1740: reverseOrderIfOKAtLeft: true sv@1740: component: sv@1740: (SpecCollection sv@1740: collection: ( sv@1740: (ActionButtonSpec sv@1740: label: 'Cancel' sv@1740: name: 'Button1' sv@1740: translateLabel: true sv@1740: tabable: true sv@1740: model: cancel sv@1740: extent: (Point 118 22) cg@1557: ) sv@1740: (ActionButtonSpec sv@1740: label: 'OK' sv@1740: name: 'Button2' sv@1740: translateLabel: true sv@1740: tabable: true sv@1740: model: accept sv@1740: extent: (Point 118 22) cg@1557: ) cg@1557: ) cg@1557: cg@1557: ) cg@1557: ) sv@1740: (ArrowButtonSpec sv@1740: name: 'upArrowButton' sv@1740: layout: (LayoutFrame 105 0 63 0 127 0 85 0) sv@1740: model: shiftUpNow sv@1740: isTriggerOnDown: true sv@1740: autoRepeat: true sv@1740: actionValue: '' sv@1740: direction: up cg@1557: ) sv@1740: (ArrowButtonSpec sv@1740: name: 'leftArrowButton' sv@1740: layout: (LayoutFrame 84 0 86 0 106 0 108 0) sv@1740: model: shiftLeftNow sv@1740: isTriggerOnDown: true sv@1740: autoRepeat: true sv@1740: actionValue: '' sv@1740: direction: left cg@1557: ) sv@1740: (ArrowButtonSpec sv@1740: name: 'rightArrowButton' sv@1740: layout: (LayoutFrame 126 0 86 0 148 0 108 0) sv@1740: model: shiftRightNow sv@1740: isTriggerOnDown: true sv@1740: autoRepeat: true sv@1740: actionValue: '' sv@1740: direction: right cg@1557: ) sv@1740: (ArrowButtonSpec sv@1740: name: 'downArrowButton' sv@1740: layout: (LayoutFrame 105 0 107 0 127 0 129 0) sv@1740: model: shiftDownNow sv@1740: isTriggerOnDown: true sv@1740: autoRepeat: true sv@1740: actionValue: '' sv@1740: direction: down cg@1557: ) sv@1740: (CheckBoxSpec sv@1740: label: 'Wrap' sv@1740: name: 'CheckBox1' sv@1740: layout: (LayoutFrame 153 0 22 0 289 0 44 0) sv@1740: model: wrap sv@1740: translateLabel: true cg@1713: ) cg@1557: ) cg@1557: cg@1557: ) cg@1557: ) cg@1557: ! cg@1557: sv@1740: uncropDialogSpec cg@1480: "This resource specification was automatically generated cg@1480: by the UIPainter of ST/X." cg@1796: cg@1480: "Do not manually edit this!! If it is corrupted, cg@1480: the UIPainter may not be able to read the specification." cg@1796: cg@1480: " cg@1796: UIPainter new openOnClass:ImageEditor andSelector:#uncropDialogSpec cg@1796: ImageEditor new openInterface:#uncropDialogSpec cg@1480: " cg@1796: cg@1796: cg@1796: cg@1796: ^ cg@1796: #(FullSpec cg@1796: name: uncropDialogSpec cg@1796: window: cg@1796: (WindowSpec cg@1796: label: 'Add Border(s)' cg@1796: name: 'Add Border(s)' cg@1796: min: (Point 10 10) cg@1796: max: (Point 800 478) cg@1796: bounds: (Rectangle 0 0 261 228) cg@1796: ) cg@1796: component: cg@1796: (SpecCollection cg@1796: collection: ( cg@1796: (LabelSpec cg@1796: label: 'Left:' cg@1796: name: 'Label1' cg@1796: layout: (LayoutFrame 14 0 21 0 90 0 43 0) cg@1796: translateLabel: true cg@1796: adjust: right cg@1796: ) cg@1796: (InputFieldSpec cg@1796: name: 'EntryField1' cg@1796: layout: (LayoutFrame 95 0 21 0 132 0 43 0) cg@1796: model: left cg@1796: type: number cg@1796: acceptOnPointerLeave: false cg@1796: ) cg@1796: (LabelSpec cg@1796: label: 'Right:' cg@1796: name: 'Label2' cg@1796: layout: (LayoutFrame 14 0 51 0 90 0 73 0) cg@1796: translateLabel: true cg@1796: adjust: right cg@1796: ) cg@1796: (InputFieldSpec cg@1796: name: 'EntryField2' cg@1796: layout: (LayoutFrame 95 0 51 0 132 0 73 0) cg@1796: model: right cg@1796: type: number cg@1796: acceptOnPointerLeave: false cg@1796: ) cg@1796: (LabelSpec cg@1796: label: 'Top:' cg@1796: name: 'Label3' cg@1796: layout: (LayoutFrame 14 0 81 0 90 0 103 0) cg@1796: translateLabel: true cg@1796: adjust: right cg@1796: ) cg@1796: (InputFieldSpec cg@1796: name: 'EntryField3' cg@1796: layout: (LayoutFrame 95 0 81 0 132 0 103 0) cg@1796: model: top cg@1796: type: number cg@1796: acceptOnPointerLeave: false cg@1796: ) cg@1796: (LabelSpec cg@1796: label: 'Bottom:' cg@1796: name: 'Label4' cg@1796: layout: (LayoutFrame 14 0 111 0 90 0 133 0) cg@1796: translateLabel: true cg@1796: adjust: right cg@1796: ) cg@1796: (InputFieldSpec cg@1796: name: 'EntryField4' cg@1796: layout: (LayoutFrame 95 0 111 0 132 0 133 0) cg@1796: model: bottom cg@1796: type: number cg@1796: acceptOnPointerLeave: false cg@1796: ) cg@1796: (HorizontalPanelViewSpec cg@1796: name: 'HorizontalPanel1' cg@1796: layout: (LayoutFrame 0 0.0 -30 1 0 1.0 0 1) cg@1796: horizontalLayout: fitSpace cg@1796: verticalLayout: center cg@1796: horizontalSpace: 3 cg@1796: verticalSpace: 3 cg@1796: reverseOrderIfOKAtLeft: true cg@1796: component: cg@1796: (SpecCollection cg@1796: collection: ( cg@1796: (ActionButtonSpec cg@1796: label: 'Cancel' cg@1796: name: 'Button1' cg@1796: translateLabel: true cg@1796: model: cancel cg@1796: extent: (Point 118 22) cg@1796: ) cg@1796: (ActionButtonSpec cg@1796: label: 'OK' cg@1796: name: 'Button2' cg@1796: translateLabel: true cg@1796: model: accept cg@1796: extent: (Point 118 22) cg@1796: ) cg@1796: ) cg@1796: cg@1796: ) cg@1796: ) cg@1796: ) cg@1796: cg@1796: ) cg@1796: ) cg@1480: ! cg@1480: tz@767: windowSpec tz@767: "This resource specification was automatically generated tz@767: by the UIPainter of ST/X." tz@767: tz@767: "Do not manually edit this!! If it is corrupted, tz@767: the UIPainter may not be able to read the specification." tz@767: tz@767: " tz@767: UIPainter new openOnClass:ImageEditor andSelector:#windowSpec tz@767: ImageEditor new openInterface:#windowSpec tz@767: ImageEditor open tz@767: " tz@767: tz@767: tz@767: cg@1558: ^ cg@3195: #(FullSpec cg@3195: name: windowSpec cg@3195: window: cg@3195: (WindowSpec cg@3195: label: 'Image Editor' cg@3195: name: 'Image Editor' cg@3195: min: (Point 400 320) cg@3195: bounds: (Rectangle 0 0 450 350) cg@3195: menu: menu cg@3195: icon: defaultIcon cg@3195: ) cg@3195: component: cg@3195: (SpecCollection cg@3195: collection: ( cg@3195: (MenuPanelSpec cg@3195: name: 'menuToolbarView' cg@3195: layout: (LayoutFrame 0 0.0 0 0 0 1.0 32 0) cg@3195: style: (FontDescription helvetica medium roman 10) cg@3195: menu: menuToolbar cg@3195: showSeparatingLines: true cg@3195: ) cg@3195: (VariableHorizontalPanelSpec cg@3195: name: 'mainPanel' cg@3195: layout: (LayoutFrame 0 0.0 34 0.0 0 1.0 -26 1.0) cg@3195: snapMode: both cg@3195: barLevel: 0 cg@3195: component: cg@3195: (SpecCollection cg@3195: collection: ( cg@3195: (ViewSpec cg@3195: name: 'leftView' cg@3195: level: 1 cg@3195: component: cg@3195: (SpecCollection cg@3195: collection: ( cg@3195: (VariableVerticalPanelSpec cg@3195: name: 'verticalPanel' cg@3195: layout: (LayoutFrame 0 0.0 0 0.0 0 1.0 0 1.0) cg@3195: level: 0 cg@3195: snapMode: both cg@3195: component: cg@3195: (SpecCollection cg@3195: collection: ( cg@3195: (ViewSpec cg@3195: name: 'View1' cg@3195: component: cg@3195: (SpecCollection cg@3195: collection: ( cg@3195: (MenuPanelSpec cg@3195: name: 'MouseButtonColorToolBar' cg@3195: layout: (LayoutFrame 0 0.0 0 0 0 1.0 24 0) cg@3195: level: 0 cg@3195: menu: menuMouseButtonColors cg@1558: ) cg@3195: (DataSetSpec cg@3195: name: 'colorDataSetView' cg@3195: layout: (LayoutFrame 0 0.0 26 0.0 0 1.0 0 1.0) cg@3195: activeHelpKey: colorMapTable cg@3195: style: (FontDescription helvetica medium roman 10) cg@3195: model: selectedColors cg@3195: menu: colorMapMenu cg@3195: hasHorizontalScrollBar: true cg@3195: hasVerticalScrollBar: true cg@3195: miniScrollerHorizontal: true cg@3195: miniScrollerVertical: true cg@3195: dataList: listOfColors cg@3195: has3Dseparators: true cg@3195: doubleClickSelector: doubleClickOnColor: cg@3195: columnHolder: colorTableColumns cg@3195: multipleSelectOk: true cg@3195: verticalSpacing: 1 cg@3195: columnAdaptor: colorColumnAdaptor cg@3195: ) cg@3195: ) cg@3195: cg@3195: ) cg@1558: ) cg@3195: (ArbitraryComponentSpec cg@3195: name: 'imagePreView' cg@3195: activeHelpKey: previewView cg@3195: menu: previewMenu cg@3195: hasHorizontalScrollBar: true cg@3195: hasVerticalScrollBar: true cg@3195: miniScrollerHorizontal: false cg@3195: miniScrollerVertical: false cg@3195: hasBorder: false cg@3195: component: ImageView cg@3195: ) cg@3195: ) cg@3195: cg@3195: ) cg@3195: handles: (Any 0.5 1.0) cg@1558: ) cg@3195: ) cg@3195: cg@3195: ) cg@3195: ) cg@3195: (ViewSpec cg@3195: name: 'rightView' cg@3195: component: cg@3195: (SpecCollection cg@3195: collection: ( cg@3195: (MenuPanelSpec cg@3195: name: 'ToolBar1' cg@3195: layout: (LayoutFrame 0 0 0 0.0 28 0 0 1.0) cg@3195: level: 1 cg@3195: menu: toolsMenuToolbar cg@3195: verticalLayout: true cg@3195: centerItems: true cg@3195: textDefault: true cg@3195: ) cg@3195: (ViewSpec cg@3195: name: 'editingView' cg@3195: layout: (LayoutFrame 28 0.0 0 0.0 0 1.0 0 1.0) cg@3195: level: 1 cg@3195: component: cg@3195: (SpecCollection cg@3195: collection: ( cg@3195: (ArbitraryComponentSpec cg@3195: name: 'imageEditView' cg@3195: layout: (LayoutFrame 2 0.0 2 0.0 -2 1.0 -24 1.0) cg@3195: hasHorizontalScrollBar: true cg@3195: hasVerticalScrollBar: true cg@3195: hasBorder: false cg@3195: component: ImageEditView cg@3195: ) cg@3195: (LabelSpec cg@3195: name: 'coordLabel' cg@3195: layout: (LayoutFrame 2 0.0 -22 1 -83 1.0 0 1.0) cg@3195: level: -1 cg@3195: translateLabel: true cg@3195: labelChannel: imageInfoHolder cg@3195: resizeForLabel: false cg@3195: adjust: left cg@1637: ) cg@3195: (ArrowButtonSpec cg@3195: name: 'magnifyDownButton' cg@3195: layout: (LayoutFrame -80 1 -22 1 -58 1 0 1) cg@3195: activeHelpKey: magnifyImageDown cg@3195: translateLabel: true cg@3195: model: doMagnifyDown cg@3195: enableChannel: imageIsLoadedHolder cg@3195: isTriggerOnDown: true cg@3195: direction: left cg@3195: ) cg@3195: (ArrowButtonSpec cg@3195: name: 'magnifyUpButton' cg@3195: layout: (LayoutFrame -24 1 -22 1 -2 1 0 1) cg@3195: activeHelpKey: magnifyImageUp cg@3195: translateLabel: true cg@3195: model: doMagnifyUp cg@3195: enableChannel: imageIsLoadedHolder cg@3195: isTriggerOnDown: true cg@3195: direction: right cg@3195: ) cg@3195: (InputFieldSpec cg@3195: name: 'magnificationInputField' cg@3195: layout: (LayoutFrame -57 1 -22 1 -26 1 0 1) cg@3195: activeHelpKey: magnificationNumber cg@3195: enableChannel: imageIsLoadedHolder cg@3195: model: magnificationHolder cg@3195: type: numberInRange cg@3195: acceptOnReturn: true cg@3195: acceptOnTab: true cg@3195: numChars: 2 cg@3195: minValue: 1 cg@3195: maxValue: 99 cg@3195: acceptOnPointerLeave: true cg@3195: ) cg@3195: ) cg@3195: cg@3195: ) cg@1558: ) cg@3195: ) cg@3195: cg@3195: ) cg@1558: ) cg@3195: ) cg@3195: cg@3195: ) cg@3195: handles: (Any 0.28888900000000006 1.0) cg@1558: ) cg@3195: (UISubSpecification cg@3195: name: 'infoBarSubSpec' cg@3195: layout: (LayoutFrame 0 0.0 -24 1 0 1.0 0 1.0) cg@3195: majorKey: ToolApplicationModel cg@3195: minorKey: windowSpecForInfoBar cg@3195: ) cg@3195: ) cg@3195: cg@3195: ) cg@3195: ) tz@519: ! ! tz@519: tz@519: !ImageEditor class methodsFor:'menu specs'! tz@519: cg@1053: colorMapMenu cg@1053: "This resource specification was automatically generated cg@1053: by the MenuEditor of ST/X." cg@1053: cg@1053: "Do not manually edit this!! If it is corrupted, cg@1053: the MenuEditor may not be able to read the specification." cg@1053: cg@1053: " cg@1847: MenuEditor new openOnClass:ImageEditor andSelector:#colorMapMenu cg@1847: (Menu new fromLiteralArrayEncoding:(ImageEditor colorMapMenu)) startUp cg@1053: " cg@1053: cg@1053: cg@1053: cg@1847: ^ cg@1847: #(Menu cg@1847: ( cg@1847: (MenuItem cg@2792: enabled: hasColormapHolder cg@1847: label: 'Add Color' cg@1847: itemValue: addColorToColormap cg@1847: translateLabel: true cg@1847: ) cg@1847: (MenuItem cg@2792: enabled: hasColormapHolder cg@2539: label: 'Pick and Add Color...' cg@1847: itemValue: pickAndAddColorToColormap cg@1847: translateLabel: true cg@1847: ) cg@1847: (MenuItem cg@1847: label: '-' cg@1847: ) cg@1847: (MenuItem cg@3195: enabled: hasColormapAndSingleColorSelected cg@1852: label: 'Cut Color' cg@1852: itemValue: cutColorFromColormap cg@1852: translateLabel: true cg@1852: isVisible: false cg@1852: ) cg@1852: (MenuItem cg@3195: enabled: hasSingleColorSelectedHolder cg@1852: label: 'Copy Color' cg@1852: itemValue: copyColorFromColormap cg@1852: translateLabel: true cg@2841: shortcutKey: Copy cg@1852: ) cg@1852: (MenuItem cg@3195: enabled: hasColormapAndSingleColorSelected cg@2539: label: 'Pick and Paste Color...' cg@1933: itemValue: pickAndPasteColor cg@1852: translateLabel: true cg@1852: ) cg@1852: (MenuItem cg@1852: label: 'Paste Color' cg@1852: itemValue: pasteColorIntoColormap cg@1852: translateLabel: true cg@2841: shortcutKey: Paste cg@1852: ) cg@1852: (MenuItem cg@1852: label: '-' cg@1852: ) cg@1852: (MenuItem cg@3195: enabled: hasColormapAndSingleColorSelected cg@2539: label: 'Edit Color...' cg@1931: itemValue: editSelectedColor cg@1931: translateLabel: true cg@1931: ) cg@1931: (MenuItem cg@2651: enabled: hasColormapAndColorSelected cg@1847: label: 'Brighter' cg@1847: itemValue: makeSelectedColorBrighter cg@1847: translateLabel: true cg@1847: ) cg@1847: (MenuItem cg@2651: enabled: hasColormapAndColorSelected cg@1847: label: 'Darker' cg@1847: itemValue: makeSelectedColorDarker cg@1847: translateLabel: true cg@1847: ) cg@1847: (MenuItem cg@2651: enabled: hasColormapAndColorSelected cg@1884: label: 'Make Gray' cg@1884: itemValue: makeSelectedColorGray cg@1884: translateLabel: true cg@1884: ) cg@1884: (MenuItem cg@3195: enabled: hasColormapAndColorSelected cg@3195: label: 'Color Shift' cg@3195: itemValue: makeSelectedColorShifted cg@3195: translateLabel: true cg@3195: ) cg@3195: (MenuItem cg@1847: label: '-' cg@1847: ) cg@1847: (MenuItem cg@3195: enabled: hasSingleColorSelectedHolder cg@1847: label: 'Inspect Color' cg@1847: itemValue: inspectColor cg@1847: translateLabel: true cg@2651: ) cg@2651: (MenuItem cg@2792: enabled: hasColormapHolder cg@2651: label: 'Inspect Colormap' cg@2651: itemValue: inspectColormap cg@2651: translateLabel: true cg@1847: ) cg@1847: ) cg@1847: nil cg@1847: nil cg@1053: ) cg@1053: ! cg@1053: tz@400: menu tz@737: "This resource specification was automatically generated tz@737: by the MenuEditor of ST/X." tz@400: tz@737: "Do not manually edit this!! If it is corrupted, tz@737: the MenuEditor may not be able to read the specification." tz@400: tz@400: " tz@400: MenuEditor new openOnClass:ImageEditor andSelector:#menu tz@400: (Menu new fromLiteralArrayEncoding:(ImageEditor menu)) startUp tz@400: " tz@400: tz@400: tz@400: cg@1124: ^ cg@1882: #(Menu cg@1882: ( cg@1882: (MenuItem cg@1882: label: '&File' cg@1882: translateLabel: true cg@2196: submenuChannel: menuFile cg@2585: "/ keepLinkedMenu: true cg@1124: ) cg@1882: (MenuItem cg@1882: label: 'Edit' cg@1882: translateLabel: true cg@2196: submenuChannel: menuEdit cg@2585: "/ keepLinkedMenu: true cg@1124: ) cg@1882: (MenuItem cg@1882: label: 'Mode' cg@1882: translateLabel: true cg@1882: submenuChannel: modeMenu cg@1637: ) cg@1882: (MenuItem cg@1924: label: 'Colors' cg@1882: translateLabel: true cg@2585: submenuChannel: menuColors cg@1124: ) cg@1882: (MenuItem cg@1882: label: 'Settings' cg@1882: translateLabel: true cg@2585: submenuChannel: menuSettings cg@1124: ) cg@1882: (MenuItem cg@1882: label: 'History' cg@1882: translateLabel: true cg@1975: isVisible: isStandAlone cg@1882: submenuChannel: menuHistory cg@1124: ) cg@1882: (MenuItem cg@2136: label: 'MENU_Help' cg@1882: translateLabel: true cg@2125: startGroup: conditionalRight cg@1882: submenuChannel: menuHelp cg@1124: ) cg@1124: ) cg@1124: nil cg@1124: nil tz@400: ) tz@400: ! tz@400: cg@2585: menuColors cg@2585: "This resource specification was automatically generated cg@2585: by the MenuEditor of ST/X." cg@2585: cg@2585: "Do not manually edit this!! If it is corrupted, cg@2585: the MenuEditor may not be able to read the specification." cg@2585: cg@2585: " cg@2585: MenuEditor new openOnClass:ImageEditor andSelector:#menuColors cg@2585: (Menu new fromLiteralArrayEncoding:(ImageEditor menuColors)) startUp cg@2585: " cg@2585: cg@2585: cg@2585: cg@2585: ^ cg@2585: #(Menu cg@2585: ( cg@2585: (MenuItem cg@2767: enabled: imageIsLoadedAndAllowedToChangeImageDimensionAndDepth cg@2585: label: 'Depth' cg@2585: translateLabel: true cg@2585: submenu: cg@2585: (Menu cg@2585: ( cg@2585: (MenuItem cg@2585: activeHelpKey: colorMap1 cg@2585: label: '1-Plane' cg@2585: itemValue: colorMapMode: cg@2585: translateLabel: true cg@2585: argument: depth1 cg@2585: choice: colorMapMode cg@2585: choiceValue: depth1 cg@2585: ) cg@2585: (MenuItem cg@2585: activeHelpKey: colorMap1M cg@2585: label: '1-Plane + Mask' cg@2585: itemValue: colorMapMode: cg@2585: translateLabel: true cg@2585: argument: masked1 cg@2585: choice: colorMapMode cg@2585: choiceValue: masked1 cg@2585: ) cg@2585: (MenuItem cg@2585: label: '-' cg@2585: ) cg@2585: (MenuItem cg@2585: activeHelpKey: colorMap2 cg@2585: label: '2-Plane' cg@2585: itemValue: colorMapMode: cg@2585: translateLabel: true cg@2585: argument: depth2 cg@2585: choice: colorMapMode cg@2585: choiceValue: depth2 cg@2585: ) cg@2585: (MenuItem cg@2585: activeHelpKey: colorMap2M cg@2585: label: '2-Plane + Mask' cg@2585: itemValue: colorMapMode: cg@2585: translateLabel: true cg@2585: argument: masked2 cg@2585: choice: colorMapMode cg@2585: choiceValue: masked2 cg@2585: ) cg@2585: (MenuItem cg@2585: label: '-' cg@2585: ) cg@2585: (MenuItem cg@2585: activeHelpKey: colorMap4 cg@2585: label: '4-Plane' cg@2585: itemValue: colorMapMode: cg@2585: translateLabel: true cg@2585: argument: depth4 cg@2585: choice: colorMapMode cg@2585: choiceValue: depth4 cg@2585: ) cg@2585: (MenuItem cg@2585: activeHelpKey: colorMap4M cg@2585: label: '4-Plane + Mask' cg@2585: itemValue: colorMapMode: cg@2585: translateLabel: true cg@2585: argument: masked4 cg@2585: choice: colorMapMode cg@2585: choiceValue: masked4 cg@2585: ) cg@2585: (MenuItem cg@2585: label: '-' cg@2585: ) cg@2585: (MenuItem cg@2585: activeHelpKey: colorMap8 cg@2585: label: '8-Plane' cg@2585: itemValue: colorMapMode: cg@2585: translateLabel: true cg@2585: argument: depth8 cg@2585: choice: colorMapMode cg@2585: choiceValue: depth8 cg@2585: ) cg@2585: (MenuItem cg@2585: activeHelpKey: colorMap8M cg@2585: label: '8-Plane + Mask' cg@2585: itemValue: colorMapMode: cg@2585: translateLabel: true cg@2585: argument: masked8 cg@2585: choice: colorMapMode cg@2585: choiceValue: masked8 cg@2585: ) cg@2585: (MenuItem cg@2585: label: '-' cg@2585: ) cg@2585: (MenuItem cg@2585: activeHelpKey: colorMap16 cg@2585: label: '16-Plane' cg@2585: itemValue: colorMapMode: cg@2585: translateLabel: true cg@2585: argument: depth16 cg@2585: choice: colorMapMode cg@2585: choiceValue: depth16 cg@2585: ) cg@2585: (MenuItem cg@2585: activeHelpKey: colorMap16M cg@2585: label: '16-Plane + Mask' cg@2585: itemValue: colorMapMode: cg@2585: translateLabel: true cg@2585: argument: masked16 cg@2585: choice: colorMapMode cg@2585: choiceValue: masked16 cg@2585: ) cg@2585: (MenuItem cg@2585: label: '-' cg@2585: ) cg@2585: (MenuItem cg@2585: activeHelpKey: colorMap24 cg@2585: label: '24-Plane' cg@2585: itemValue: colorMapMode: cg@2585: translateLabel: true cg@2585: argument: depth24 cg@2585: choice: colorMapMode cg@2585: choiceValue: depth24 cg@2585: ) cg@2585: (MenuItem cg@2585: activeHelpKey: colorMap24M cg@2585: label: '24-Plane + Mask' cg@2585: itemValue: colorMapMode: cg@2585: translateLabel: true cg@2585: argument: masked24 cg@2585: choice: colorMapMode cg@2585: choiceValue: masked24 cg@2585: ) cg@2585: (MenuItem cg@2585: label: '-' cg@2585: ) cg@2585: (MenuItem cg@2585: activeHelpKey: colorMap32 cg@2585: label: '32-Plane (rgba)' cg@2585: itemValue: colorMapMode: cg@2585: translateLabel: true cg@2585: argument: depth32 cg@2585: choice: colorMapMode cg@2585: choiceValue: depth32 cg@2585: ) cg@2585: ) cg@2585: nil cg@2585: nil cg@2585: ) cg@2585: ) cg@2585: (MenuItem cg@2792: enabled: imageIsLoadedHolder cg@2585: label: 'ColorMap' cg@2585: translateLabel: true cg@2585: submenu: cg@2585: (Menu cg@2585: ( cg@2585: (MenuItem cg@2585: activeHelpKey: compressColormap cg@2792: enabled: hasColormapHolder cg@2585: label: 'Compress Colormap' cg@2826: itemValue: #'menu_compressColorMap' cg@2585: translateLabel: true cg@2585: ) cg@2585: (MenuItem cg@2792: enabled: hasColormapHolder cg@2585: label: 'Sort Colormap' cg@2826: itemValue: #'menu_sortColorMap' cg@2585: translateLabel: true cg@2585: ) cg@2585: (MenuItem cg@2585: label: 'Reduce Number of Colors by Rounding...' cg@2585: itemValue: reduceNumberOfColors2 cg@2585: translateLabel: true cg@2585: ) cg@2585: (MenuItem cg@2585: label: 'Reduce Number of Colors by Masking Bits...' cg@2585: itemValue: reduceNumberOfColors cg@2585: translateLabel: true cg@2585: ) cg@2585: (MenuItem cg@2585: label: 'Dither to Depth...' cg@2585: itemValue: ditherToDepth cg@2585: translateLabel: true cg@2585: ) cg@2585: (MenuItem cg@2585: label: '-' cg@2585: ) cg@2585: (MenuItem cg@2792: enabled: imageIsLoadedHolder cg@2585: label: 'Brighten' cg@2585: itemValue: doBrightenImage cg@2585: translateLabel: true cg@2585: ) cg@2585: (MenuItem cg@2792: enabled: imageIsLoadedHolder cg@2585: label: 'Darken' cg@2585: itemValue: doDarkenImage cg@2585: translateLabel: true cg@2585: ) cg@2652: (MenuItem cg@2792: enabled: imageIsLoadedHolder cg@2652: label: 'Invert' cg@2652: itemValue: doNegativeImage cg@2652: translateLabel: true cg@2652: ) cg@2585: ) cg@2585: nil cg@2585: nil cg@2585: ) cg@2585: ) cg@2585: (MenuItem cg@2792: enabled: imageIsLoadedHolder cg@2585: label: 'Process' cg@2585: translateLabel: true cg@2585: submenu: cg@2585: (Menu cg@2585: ( cg@2585: (MenuItem cg@2585: label: 'Make GrayScale' cg@2585: itemValue: makeGrayScaleImage cg@2585: translateLabel: true cg@2585: ) cg@2585: (MenuItem cg@2826: enabled: allowedToChangeImageDimensionAndDepth cg@2585: label: 'Make dithered 8Bit Palette' cg@2585: itemValue: makeDitheredPaletteImage cg@2585: translateLabel: true cg@2585: isVisible: false cg@2585: ) cg@2585: (MenuItem cg@2826: label: 'Make Inverse' cg@2826: itemValue: makeInverse cg@2826: translateLabel: true cg@2826: ) cg@2826: (MenuItem cg@2826: label: '-' cg@2826: ) cg@2826: (MenuItem cg@2826: label: 'Make Slightly Brighter' cg@2826: itemValue: makeSlightlyBrighter cg@2826: translateLabel: true cg@2826: ) cg@2826: (MenuItem cg@2826: label: 'Make Slightly Darker' cg@2826: itemValue: makeSlightlyDarker cg@2826: translateLabel: true cg@2826: ) cg@2826: (MenuItem cg@2826: label: '-' cg@2826: ) cg@2826: (MenuItem cg@2585: label: 'Make Brighter' cg@2585: itemValue: makeBrighter cg@2585: translateLabel: true cg@2585: ) cg@2585: (MenuItem cg@2585: label: 'Make Darker' cg@2585: itemValue: makeDarker cg@2585: translateLabel: true cg@2585: ) cg@2585: (MenuItem cg@2585: label: '-' cg@2585: ) cg@2585: (MenuItem cg@2585: label: 'Change HLS...' cg@2585: itemValue: changeHLS cg@2585: translateLabel: true cg@2585: ) cg@2585: (MenuItem cg@2585: label: 'Colorize...' cg@2585: itemValue: colorize cg@2585: translateLabel: true cg@2585: ) cg@2585: ) cg@2585: nil cg@2585: nil cg@2585: ) cg@2585: ) cg@2585: (MenuItem cg@2792: enabled: imageIsLoadedHolder cg@2585: label: 'Mask' cg@2585: translateLabel: true cg@2585: submenu: cg@2585: (Menu cg@2585: ( cg@2585: (MenuItem cg@2585: activeHelpKey: copyMask cg@2585: enabled: hasMask cg@2585: label: 'Copy Mask' cg@2826: itemValue: #'menu_copyMask' cg@2585: translateLabel: true cg@2585: ) cg@2585: (MenuItem cg@2585: activeHelpKey: pasteMask cg@2585: enabled: hasMask cg@2585: label: 'Paste Mask' cg@2826: itemValue: #'menu_pasteMask' cg@2585: translateLabel: true cg@2585: ) cg@2585: (MenuItem cg@2585: enabled: hasMask cg@2585: label: 'Clear Masked Pixels' cg@2826: itemValue: #'menu_clearMaskedPixels' cg@2652: translateLabel: true cg@2652: ) cg@2652: (MenuItem cg@2652: enabled: hasMask cg@2653: label: 'Clear Colormap Entry for Masked Pixels' cg@2826: itemValue: #'menu_clearColormapEntry0AndMaskedPixels' cg@2585: translateLabel: true cg@2585: ) cg@2585: ) cg@2585: nil cg@2585: nil cg@2585: ) cg@2585: ) cg@2585: ) cg@2585: nil cg@2585: nil cg@2585: ) cg@2585: ! cg@2585: cg@2196: menuEdit cg@2196: "This resource specification was automatically generated cg@2196: by the MenuEditor of ST/X." cg@2196: cg@2196: "Do not manually edit this!! If it is corrupted, cg@2196: the MenuEditor may not be able to read the specification." cg@2196: cg@2196: " cg@2196: MenuEditor new openOnClass:ImageEditor andSelector:#menuEdit cg@2196: (Menu new fromLiteralArrayEncoding:(ImageEditor menuEdit)) startUp cg@2196: " cg@2196: cg@2196: cg@2196: cg@2196: ^ cg@2196: #(Menu cg@2196: ( cg@2196: (MenuItem cg@2196: activeHelpKey: editUndo cg@2196: enabled: canUndoHolder cg@2196: label: 'Undo' cg@2196: itemValue: doUndo cg@2196: translateLabel: true cg@2196: ) cg@2196: (MenuItem cg@2196: label: '-' cg@2196: ) cg@2196: (MenuItem cg@2812: enabled: imageIsLoadedHolder cg@2812: label: 'Copy to Clipboard' cg@2812: itemValue: doCopyImageToClipboard cg@2812: translateLabel: true cg@2812: ) cg@2812: (MenuItem cg@2812: label: '-' cg@2812: ) cg@2812: (MenuItem cg@2812: activeHelpKey: editResize cg@2767: enabled: imageIsLoadedAndAllowedToChangeImageDimensionAndDepth cg@2196: label: 'Resize...' cg@2196: itemValue: doResizeImage cg@2196: translateLabel: true cg@2196: ) cg@2196: (MenuItem cg@2812: activeHelpKey: editMagnifyImage cg@2767: enabled: imageIsLoadedAndAllowedToChangeImageDimensionAndDepth cg@2196: label: 'Magnify...' cg@2196: itemValue: doMagnifyImage cg@2196: translateLabel: true cg@2196: ) cg@2196: (MenuItem cg@2812: activeHelpKey: editMagnifyImage cg@2767: enabled: imageIsLoadedAndAllowedToChangeImageDimensionAndDepth cg@2196: label: 'Magnify By...' cg@2196: itemValue: doMagnifyImageBy cg@2196: translateLabel: true cg@2196: ) cg@2196: (MenuItem cg@2812: activeHelpKey: editRotate cg@2767: enabled: imageIsLoadedAndAllowedToChangeImageDimensionAndDepth cg@2196: label: 'Rotate...' cg@2196: itemValue: doRotateImage cg@2196: translateLabel: true cg@2196: ) cg@2196: (MenuItem cg@2812: activeHelpKey: edit3DProjection cg@2767: enabled: imageIsLoadedAndAllowedToChangeImageDimensionAndDepth cg@2354: label: '3D Projection...' cg@2354: itemValue: do3DProjection cg@2354: translateLabel: true cg@2354: ) cg@2354: (MenuItem cg@2792: enabled: imageIsLoadedHolder cg@2196: label: 'Flip' cg@2196: translateLabel: true cg@2196: submenu: cg@2196: (Menu cg@2196: ( cg@2196: (MenuItem cg@2196: activeHelpKey: editFlipVertical cg@2812: enabled: imageIsLoadedHolder cg@2196: label: 'Flip - Vertical' cg@2196: itemValue: doFlipVertical cg@2196: translateLabel: true cg@2837: labelImage: (ResourceRetriever ImageEditor flipVerticalIcon 'Flip - Vertical') cg@2196: ) cg@2196: (MenuItem cg@2196: activeHelpKey: editFlipHorizontal cg@2812: enabled: imageIsLoadedHolder cg@2196: label: 'Flip - Horizontal' cg@2196: itemValue: doFlipHorizontal cg@2196: translateLabel: true cg@2837: labelImage: (ResourceRetriever ImageEditor flipHorizontalIcon 'Flip - Horizontal') cg@2196: ) cg@2196: ) cg@2196: nil cg@2196: nil cg@2196: ) cg@2196: ) cg@2196: (MenuItem cg@2196: label: '-' cg@2196: ) cg@2196: (MenuItem cg@2767: enabled: imageIsLoadedAndAllowedToChangeImageDimensionAndDepth cg@2196: label: 'Crop' cg@2196: translateLabel: true cg@2196: submenu: cg@2196: (Menu cg@2196: ( cg@2196: (MenuItem cg@2196: activeHelpKey: cropManual cg@2196: label: 'Manual...' cg@2196: itemValue: doCropManual cg@2196: translateLabel: true cg@2196: ) cg@2196: (MenuItem cg@2196: label: '-' cg@2196: ) cg@2196: (MenuItem cg@2196: activeHelpKey: cropAll cg@2196: label: 'All' cg@2196: itemValue: doCropAll cg@2196: translateLabel: true cg@2196: ) cg@2196: (MenuItem cg@2196: label: '-' cg@2196: ) cg@2196: (MenuItem cg@2196: activeHelpKey: cropLeft cg@2196: label: 'Left' cg@2196: itemValue: doCropLeft cg@2196: translateLabel: true cg@2196: ) cg@2196: (MenuItem cg@2196: activeHelpKey: cropRight cg@2196: label: 'Right' cg@2196: itemValue: doCropRight cg@2196: translateLabel: true cg@2196: ) cg@2196: (MenuItem cg@2196: activeHelpKey: cropTop cg@2196: label: 'Top' cg@2196: itemValue: doCropTop cg@2196: translateLabel: true cg@2196: ) cg@2196: (MenuItem cg@2196: activeHelpKey: cropBottom cg@2196: label: 'Bottom' cg@2196: itemValue: doCropBottom cg@2196: translateLabel: true cg@2196: ) cg@2196: ) cg@2196: nil cg@2196: nil cg@2196: ) cg@2196: ) cg@2196: (MenuItem cg@2812: activeHelpKey: uncropManual cg@2767: enabled: imageIsLoadedAndAllowedToChangeImageDimensionAndDepth cg@2196: label: 'Uncrop (Add Border)...' cg@2196: itemValue: doUnCropManual cg@2196: translateLabel: true cg@2196: ) cg@2196: (MenuItem cg@2812: activeHelpKey: shiftManual cg@2792: enabled: imageIsLoadedHolder cg@2196: label: 'Shift...' cg@2196: itemValue: doShiftManual cg@2196: translateLabel: true cg@2196: ) cg@2196: (MenuItem cg@2196: label: '-' cg@2196: ) cg@2196: (MenuItem cg@2585: activeHelpKey: fileEditMask cg@2792: enabled: imageIsLoadedHolder cg@2585: label: 'Edit Mask' cg@2585: itemValue: doEditMask cg@2585: translateLabel: true cg@2585: ) cg@2585: (MenuItem cg@2792: enabled: imageIsLoadedHolder cg@2196: label: 'Text...' cg@2196: itemValue: doInsertTextFromUser cg@2196: translateLabel: true cg@2196: ) cg@2812: (MenuItem cg@2812: label: '-' cg@2812: ) cg@2812: (MenuItem cg@2814: label: 'Animation Sequence' cg@2812: translateLabel: true cg@2812: submenu: cg@2812: (Menu cg@2812: ( cg@2812: (MenuItem cg@2812: enabled: imageHasNextImageHolder cg@2812: label: 'Next in Sequence' cg@2812: itemValue: nextImageInSequence cg@2812: translateLabel: true cg@2812: ) cg@2812: (MenuItem cg@2812: enabled: imageHasPreviousImageHolder cg@2813: label: 'Previous in Sequence' cg@2812: itemValue: previousImageInSequence cg@2812: translateLabel: true cg@2812: ) cg@2812: (MenuItem cg@2812: label: '-' cg@2812: ) cg@2812: (MenuItem cg@2812: enabled: imageHasImageSequenceHolder cg@2812: label: 'Edit each from Sequence' cg@2812: itemValue: editEachImageFromSequence cg@2812: translateLabel: true cg@2812: ) cg@2812: ) cg@2812: nil cg@2812: nil cg@2812: ) cg@2812: ) cg@2196: ) cg@2196: nil cg@2196: nil cg@2196: ) cg@2196: ! cg@2196: cg@2196: menuFile cg@2196: "This resource specification was automatically generated cg@2196: by the MenuEditor of ST/X." cg@2196: cg@2196: "Do not manually edit this!! If it is corrupted, cg@2196: the MenuEditor may not be able to read the specification." cg@2196: cg@3022: cg@2196: " cg@2196: MenuEditor new openOnClass:ImageEditor andSelector:#menuFile cg@2196: (Menu new fromLiteralArrayEncoding:(ImageEditor menuFile)) startUp cg@2196: " cg@2196: cg@2196: cg@2196: cg@2196: ^ cg@2196: #(Menu cg@2196: ( cg@2196: (MenuItem cg@2196: activeHelpKey: fileNewImageEditor cg@2196: label: 'New ImageEditor' cg@2196: itemValue: doNewImageEditor cg@2196: ) cg@2196: (MenuItem cg@2876: label: '-' cg@2876: ) cg@2876: (MenuItem cg@2196: activeHelpKey: fileNewImage cg@2196: label: 'New...' cg@2196: itemValue: doNewImage cg@2196: ) cg@2196: (MenuItem cg@3200: activeHelpKey: fileNewImageFromClipboard cg@2196: label: 'New from ClipBoard' cg@2196: itemValue: doNewImageFromClipboard cg@2196: ) cg@2196: (MenuItem cg@3200: activeHelpKey: fileNewMaskFromClipboard cg@3200: label: 'Mask from ClipBoard' cg@3200: itemValue: doNewMaskFromClipboard cg@3200: ) cg@3200: (MenuItem cg@2196: label: '-' cg@2196: ) cg@2196: (MenuItem cg@2196: activeHelpKey: fileLoadFromClass cg@2196: label: 'Load...' cg@2196: itemValue: doLoadFromClass cg@2196: ) cg@2196: (MenuItem cg@2196: activeHelpKey: fileLoadFromFile cg@2196: label: 'Load from File...' cg@2196: itemValue: doLoadFromFile cg@2196: ) cg@2196: (MenuItem cg@2796: activeHelpKey: fileLoadFromURL cg@2796: label: 'Load from URL...' cg@2796: itemValue: doLoadFromURL cg@2796: ) cg@2796: (MenuItem cg@2707: label: 'Grab' cg@2707: submenu: cg@2707: (Menu cg@2707: ( cg@2707: (MenuItem cg@2707: activeHelpKey: fileGrabImageFromScreen cg@2717: label: 'Grab from Screen Area...' cg@2707: itemValue: grabScreenImage cg@2707: ) cg@2707: (MenuItem cg@2707: activeHelpKey: fileGrabImageFromScreen cg@2707: enabled: hasLastGrabScreenArea cg@2711: label: 'Grab again from same Screen Area' cg@2707: itemValue: grabScreenImageFromLastArea cg@2707: ) cg@2771: (MenuItem cg@2771: label: '-' cg@2771: ) cg@2771: (MenuItem cg@2771: activeHelpKey: fileGrabImageFromWindow cg@2771: label: 'Grab from Window...' cg@2771: itemValue: grabWindowImage cg@2771: ) cg@2707: ) cg@2707: nil cg@2707: nil cg@2707: ) cg@2701: ) cg@2701: (MenuItem cg@2196: label: '-' cg@2196: ) cg@2196: (MenuItem cg@2196: activeHelpKey: fileSaveMethod cg@2196: enabled: imageIsLoadedAndClassDefined cg@2196: label: 'Save' cg@2196: itemValue: doSaveMethod cg@2196: ) cg@2196: (MenuItem cg@2196: activeHelpKey: fileSaveMethodAs cg@2792: enabled: imageIsLoadedHolder cg@2196: label: 'Save As...' cg@2196: itemValue: doSaveMethodAs cg@2196: ) cg@2196: (MenuItem cg@2196: activeHelpKey: fileSaveAs cg@2792: enabled: imageIsLoadedHolder cg@2196: label: 'Save to File...' cg@2196: itemValue: doSaveImageFileAs cg@2196: ) cg@2196: (MenuItem cg@2196: activeHelpKey: fileSaveMaskAs cg@2792: enabled: imageIsLoadedHolder cg@2196: label: 'Save Mask to File...' cg@2196: itemValue: doSaveImageMaskFileAs cg@2196: ) cg@2196: (MenuItem cg@2196: activeHelpKey: fileSaveButtonImageAs cg@2792: enabled: imageIsLoadedHolder cg@2196: label: 'Save as Button to File...' cg@2196: itemValue: doSaveButtonImageToFileAs cg@2196: ) cg@2196: (MenuItem cg@2196: label: '-' cg@2196: ) cg@2196: (MenuItem cg@2196: activeHelpKey: filePrint cg@2792: enabled: imageIsLoadedHolder cg@2196: label: 'Print' cg@2196: itemValue: doPrint cg@2196: ) cg@2196: (MenuItem cg@2196: label: '-' cg@2196: isVisible: isStandAlone cg@2196: ) cg@2196: (MenuItem cg@2196: activeHelpKey: fileBrowseClass cg@2792: enabled: hasClassDefinedHolder cg@2196: label: 'Browse Class' cg@2196: itemValue: doBrowseClass cg@2196: isVisible: isStandAlone cg@2196: ) cg@2196: (MenuItem cg@2792: enabled: imageIsLoadedHolder cg@2196: label: 'Inspect Image' cg@2196: itemValue: doInspectImage cg@2196: isVisible: isStandAlone cg@2196: ) cg@2196: (MenuItem cg@2585: activeHelpKey: fileShowStoreString cg@2792: enabled: imageIsLoadedHolder cg@2585: label: 'Show storeString' cg@2585: itemValue: doShowStoreString cg@3022: ) cg@3022: (MenuItem cg@3022: activeHelpKey: fileShowStoreString cg@3022: enabled: imageIsLoadedHolder cg@3022: label: 'Show Pixel Array Literal String' cg@3022: itemValue: doShowPixelArrayLiteralString cg@2585: ) cg@2585: (MenuItem cg@2196: label: '-' cg@2196: isVisible: isStandAlone cg@2196: ) cg@2196: (MenuItem cg@2196: activeHelpKey: fileExit cg@2196: label: 'Exit' cg@2196: itemValue: closeRequest cg@2196: isVisible: isStandAlone cg@2196: ) cg@2196: ) cg@2196: nil cg@2196: nil cg@2196: ) cg@2196: ! cg@2196: tz@679: menuMouseButtonColors tz@737: "This resource specification was automatically generated tz@737: by the MenuEditor of ST/X." tz@679: tz@737: "Do not manually edit this!! If it is corrupted, tz@737: the MenuEditor may not be able to read the specification." tz@679: tz@679: " tz@679: MenuEditor new openOnClass:ImageEditor andSelector:#menuMouseButtonColors tz@679: (Menu new fromLiteralArrayEncoding:(ImageEditor menuMouseButtonColors)) startUp tz@679: " tz@679: tz@679: tz@679: tz@679: ^ tz@679: tz@679: #(#Menu tz@679: tz@679: #( tz@679: #(#MenuItem tz@679: #label: 'Left Mouse Button' tz@679: #nameKey: #leftMouseKeyButton tz@679: #activeHelpKey: #mouseKeyColorMode cg@2792: #enabled: #imageIsLoadedHolder tz@679: #labelImage: #(#ResourceRetriever nil #leftMouseKeyIcon) tz@975: #choice: #mouseKeyColorMode tz@975: #choiceValue: 1 tz@679: ) tz@679: #(#MenuItem tz@679: #label: 'Right Mouse Button' tz@679: #nameKey: #rightMouseKeyButton tz@679: #activeHelpKey: #mouseKeyColorMode cg@2792: #enabled: #imageIsLoadedHolder tz@679: #labelImage: #(#ResourceRetriever nil #rightMouseKeyIcon) tz@975: #choice: #mouseKeyColorMode tz@975: #choiceValue: 2 tz@679: ) tz@679: ) nil tz@679: nil tz@679: ) cg@2792: cg@2792: "Modified: / 04-07-2010 / 10:17:37 / cg" tz@679: ! tz@679: cg@2585: menuSettings cg@2585: "This resource specification was automatically generated cg@2585: by the MenuEditor of ST/X." cg@2585: cg@2585: "Do not manually edit this!! If it is corrupted, cg@2585: the MenuEditor may not be able to read the specification." cg@2585: cg@2881: cg@2585: " cg@2585: MenuEditor new openOnClass:ImageEditor andSelector:#menuSettings cg@2585: (Menu new fromLiteralArrayEncoding:(ImageEditor menuSettings)) startUp cg@2585: " cg@2585: cg@2585: cg@2585: cg@2585: ^ cg@2585: #(Menu cg@2585: ( cg@2585: (MenuItem cg@2585: activeHelpKey: settingsGridMagnification cg@2585: label: 'Grid Magnification Limit...' cg@2585: itemValue: doChangeGridMagnification cg@2585: translateLabel: true cg@2585: ) cg@2585: (MenuItem cg@2585: label: 'Pen' cg@2585: translateLabel: true cg@2585: submenu: cg@2585: (Menu cg@2585: ( cg@2585: (MenuItem cg@2585: label: '1' cg@2585: translateLabel: true cg@2881: choice: penWidthHolder cg@2881: choiceValue: 1 cg@2585: ) cg@2585: (MenuItem cg@2585: label: '5' cg@2585: translateLabel: true cg@2881: choice: penWidthHolder cg@2881: choiceValue: 5 cg@2585: ) cg@2585: (MenuItem cg@2585: label: '10' cg@2585: translateLabel: true cg@2881: choice: penWidthHolder cg@2881: choiceValue: 10 cg@2585: ) cg@2585: ) cg@2585: nil cg@2585: nil cg@2585: ) cg@2585: ) cg@2585: (MenuItem cg@2585: label: 'Spray' cg@2585: translateLabel: true cg@2585: submenu: cg@2585: (Menu cg@2585: ( cg@2585: (MenuItem cg@2585: label: '4' cg@2585: translateLabel: true cg@2881: choice: spraySpotHolder cg@2881: choiceValue: 4 cg@2585: ) cg@2585: (MenuItem cg@2585: label: '8' cg@2585: translateLabel: true cg@2881: choice: spraySpotHolder cg@2881: choiceValue: 8 cg@2585: ) cg@2585: (MenuItem cg@2585: label: '16' cg@2585: translateLabel: true cg@2881: choice: spraySpotHolder cg@2881: choiceValue: 16 cg@2585: ) cg@2585: (MenuItem cg@2585: label: '32' cg@2585: translateLabel: true cg@2881: choice: spraySpotHolder cg@2881: choiceValue: 32 cg@2585: ) cg@2585: ) cg@2585: nil cg@2585: nil cg@2585: ) cg@2585: ) cg@2585: ) cg@2585: nil cg@2585: nil cg@2585: ) cg@2585: ! cg@2585: tz@400: menuToolbar tz@737: "This resource specification was automatically generated tz@737: by the MenuEditor of ST/X." tz@400: tz@737: "Do not manually edit this!! If it is corrupted, tz@737: the MenuEditor may not be able to read the specification." tz@400: cg@2876: tz@400: " tz@400: MenuEditor new openOnClass:ImageEditor andSelector:#menuToolbar tz@400: (Menu new fromLiteralArrayEncoding:(ImageEditor menuToolbar)) startUp tz@400: " tz@400: tz@400: tz@400: cg@1196: ^ cg@1820: #(Menu cg@1820: ( cg@1820: (MenuItem cg@1820: activeHelpKey: fileNewImage cg@1820: label: 'newImage' cg@1820: itemValue: doNewImage cg@1820: translateLabel: true cg@1820: isButton: true cg@1883: labelImage: (ResourceRetriever ToolbarIconLibrary newImageIcon) cg@1196: ) cg@1820: (MenuItem cg@2876: activeHelpKey: fileGrabImageFromScreen cg@2876: label: 'grabScreenImage' cg@2876: itemValue: grabScreenImage cg@2876: translateLabel: true cg@2876: isButton: true cg@2877: labelImage: (ResourceRetriever ToolbarIconLibrary snapshot24x24Icon) cg@2876: ) cg@2876: (MenuItem cg@1949: label: '-' cg@1949: ) cg@1949: (MenuItem cg@1970: activeHelpKey: fileLoadFromClass cg@1970: label: 'loadFromClass' cg@1970: itemValue: doLoadFromClass cg@1970: translateLabel: true cg@1970: isButton: true cg@1975: isVisible: isStandAlone cg@1970: submenuChannel: menuHistory cg@1970: labelImage: (ResourceRetriever XPToolbarIconLibrary loadImageFromMethodIcon) cg@1970: keepLinkedMenu: true cg@1970: ) cg@1970: (MenuItem cg@2567: activeHelpKey: fileSaveMethodAs cg@2792: enabled: imageIsLoadedHolder cg@2567: label: 'fileSaveMethodAs' cg@1970: itemValue: doSaveMethodAs cg@1970: translateLabel: true cg@1970: isButton: true cg@1975: isVisible: isStandAlone cg@1970: labelImage: (ResourceRetriever XPToolbarIconLibrary saveImageAsMethodAsIcon) cg@1970: ) cg@1970: (MenuItem cg@1970: activeHelpKey: fileSaveMethod cg@2792: enabled: imageIsLoadedHolder cg@1970: label: 'saveAsMethod' cg@1970: itemValue: doSaveMethod cg@1970: translateLabel: true cg@1970: isButton: true cg@1975: isVisible: isNotStandAlone cg@2590: labelImage: (ResourceRetriever ToolbarIconLibrary saveImageAsMethodIcon) cg@1970: ) cg@1970: (MenuItem cg@1970: label: '-' cg@1970: ) cg@1970: (MenuItem cg@1820: activeHelpKey: fileLoadFromFile cg@1820: label: 'loadFromFile' cg@1820: itemValue: doLoadFromFile cg@1820: translateLabel: true cg@1820: isButton: true cg@1884: labelImage: (ResourceRetriever ToolbarIconLibrary loadImageFromFileIcon) cg@1820: ) cg@1820: (MenuItem cg@1820: activeHelpKey: fileSaveAs cg@2792: enabled: imageIsLoadedHolder cg@1820: label: 'saveAsFile' cg@1820: itemValue: doSaveImageFileAs cg@1820: translateLabel: true cg@1820: isButton: true cg@1885: labelImage: (ResourceRetriever ToolbarIconLibrary saveImageToFileAsIcon) cg@1820: ) cg@1820: (MenuItem cg@1949: label: '-' cg@1196: ) cg@1820: (MenuItem cg@1820: activeHelpKey: editUndo cg@1987: enabled: canUndoHolder cg@1820: label: 'Undo' cg@1820: itemValue: doUndo cg@1820: translateLabel: true cg@1820: isButton: true cg@1883: labelImage: (ResourceRetriever ToolbarIconLibrary undoIcon) cg@1196: ) cg@2812: (MenuItem cg@2812: label: '-' cg@2812: isVisible: imageHasImageSequenceHolder cg@2812: ) cg@2812: (MenuItem cg@2812: activeHelpKey: previousImageInSequence cg@2812: enabled: imageHasPreviousImageHolder cg@2812: label: 'Previous Image' cg@2812: itemValue: previousImageInSequence cg@2812: translateLabel: true cg@2812: isVisible: imageHasImageSequenceHolder cg@2812: labelImage: (ResourceRetriever ToolbarIconLibrary leftArrow24x24Icon) cg@2812: ) cg@2812: (MenuItem cg@2812: activeHelpKey: nextImageInSequence cg@2812: enabled: imageHasNextImageHolder cg@2812: label: 'Next Image' cg@2812: itemValue: nextImageInSequence cg@2812: translateLabel: true cg@2812: isVisible: imageHasImageSequenceHolder cg@2812: labelImage: (ResourceRetriever ToolbarIconLibrary rightArrow24x24Icon) cg@2812: ) cg@1637: ) cg@1637: nil cg@1637: nil cg@1637: ) cg@1637: ! cg@1637: cg@1637: modeMenu cg@1637: "This resource specification was automatically generated cg@1637: by the MenuEditor of ST/X." cg@1637: cg@1637: "Do not manually edit this!! If it is corrupted, cg@1637: the MenuEditor may not be able to read the specification." cg@1637: cg@1637: " cg@1637: MenuEditor new openOnClass:ImageEditor andSelector:#modeMenu cg@1637: (Menu new fromLiteralArrayEncoding:(ImageEditor modeMenu)) startUp cg@1637: " cg@1637: cg@1637: cg@1637: cg@1637: ^ cg@2592: #(Menu cg@2592: ( cg@2592: (MenuItem cg@2592: activeHelpKey: drawModePoint cg@2792: enabled: imageIsLoadedHolder cg@2592: label: 'Point' cg@2592: translateLabel: true cg@2592: labelImage: (ResourceRetriever ImageEditor pointIcon 'Point') cg@2592: choice: editMode cg@2592: choiceValue: point cg@2592: ) cg@2592: (MenuItem cg@2592: activeHelpKey: drawModePoint cg@2792: enabled: imageIsLoadedHolder cg@2592: label: 'Spray' cg@2592: translateLabel: true cg@2592: labelImage: (ResourceRetriever ImageEditor sprayIcon 'Spray') cg@2592: choice: editMode cg@2592: choiceValue: spray cg@1196: ) cg@2592: (MenuItem cg@3191: activeHelpKey: drawModeSmooth cg@3191: enabled: imageIsLoadedHolder cg@3191: label: 'Smooth' cg@3191: translateLabel: true cg@3191: labelImage: (ResourceRetriever ImageEditor smoothIcon 'Smooth') cg@3191: choice: editMode cg@3191: choiceValue: smooth cg@3191: ) cg@3191: (MenuItem cg@2592: activeHelpKey: drawModeBox cg@2792: enabled: imageIsLoadedHolder cg@2592: label: 'Rect' cg@2592: translateLabel: true cg@2592: labelImage: (ResourceRetriever ImageEditor rectIcon 'Rect') cg@2592: choice: editMode cg@2592: choiceValue: box cg@1196: ) cg@2592: (MenuItem cg@2592: activeHelpKey: drawModeFilledBox cg@2792: enabled: imageIsLoadedHolder cg@2592: label: 'Filled Rectangle' cg@2592: translateLabel: true cg@2592: labelImage: (ResourceRetriever ImageEditor fillRectIcon 'Filled Rectangle') cg@2592: choice: editMode cg@2592: choiceValue: filledBox cg@1196: ) cg@2592: (MenuItem cg@2592: activeHelpKey: drawModeBox cg@2792: enabled: imageIsLoadedHolder cg@2592: label: 'Circle' cg@2592: translateLabel: true cg@2592: labelImage: (ResourceRetriever ImageEditor circleIcon 'Circle') cg@2592: choice: editMode cg@2592: choiceValue: circle cg@1196: ) cg@2592: (MenuItem cg@2592: activeHelpKey: drawModeFill cg@2792: enabled: imageIsLoadedHolder cg@2592: label: 'Fill' cg@2592: translateLabel: true cg@2592: labelImage: (ResourceRetriever ImageEditor fillIcon 'Fill') cg@2592: choice: editMode cg@2592: choiceValue: fill cg@1196: ) cg@2592: (MenuItem cg@2592: activeHelpKey: drawModeCopy cg@2792: enabled: imageIsLoadedHolder cg@2592: label: 'Copy' cg@2592: translateLabel: true cg@2592: labelImage: (ResourceRetriever ImageEditor copyIcon 'Copy') cg@2592: choice: editMode cg@2592: choiceValue: copy cg@2592: ) cg@2592: (MenuItem cg@2592: activeHelpKey: drawModePaste cg@2792: enabled: imageIsLoadedHolder cg@2592: label: 'Paste' cg@2592: translateLabel: true cg@2592: labelImage: (ResourceRetriever ImageEditor pasteIcon 'Paste') cg@2592: choice: editMode cg@2592: choiceValue: paste cg@1196: ) cg@2592: (MenuItem cg@2592: activeHelpKey: drawModePasteUnder cg@2792: enabled: imageIsLoadedHolder cg@2592: label: 'Paste Under' cg@2592: translateLabel: true cg@2592: labelImage: (ResourceRetriever ImageEditor pasteUnderIcon 'Paste Under') cg@2592: choice: editMode cg@2592: choiceValue: pasteUnder cg@1196: ) cg@2592: (MenuItem cg@2592: activeHelpKey: drawModePasteWithMask cg@2792: enabled: imageIsLoadedHolder cg@2592: label: 'Paste with Mask' cg@2592: translateLabel: true cg@2592: labelImage: (ResourceRetriever ImageEditor pasteWithMaskIcon 'Paste with Mask') cg@2592: choice: editMode cg@2592: choiceValue: pasteWithMask cg@1579: ) cg@2592: (MenuItem cg@2592: activeHelpKey: drawModeSpecial cg@2792: enabled: imageIsLoadedHolder cg@2592: label: 'Special' cg@2592: translateLabel: true cg@2592: labelImage: (ResourceRetriever ImageEditor specialIcon 'Special') cg@2592: choice: editMode cg@2592: choiceValue: specialOperation cg@1411: ) cg@1196: ) cg@1196: nil cg@1196: nil tz@400: ) cg@2792: cg@2792: "Modified: / 04-07-2010 / 10:18:08 / cg" cg@1558: ! cg@1558: cg@1558: previewMenu cg@1558: "This resource specification was automatically generated cg@1558: by the MenuEditor of ST/X." cg@1558: cg@1558: "Do not manually edit this!! If it is corrupted, cg@1558: the MenuEditor may not be able to read the specification." cg@1558: cg@1558: " cg@1558: MenuEditor new openOnClass:ImageEditor andSelector:#previewMenu cg@1558: (Menu new fromLiteralArrayEncoding:(ImageEditor previewMenu)) startUp cg@1558: " cg@1558: cg@1558: cg@1558: cg@1558: ^ cg@1764: #(Menu cg@1764: ( cg@1764: (MenuItem cg@1764: label: 'TileMode' cg@1764: translateLabel: true cg@1764: indication: tileModeHolder cg@1764: ) cg@1764: (MenuItem cg@1764: label: '-' cg@1764: ) cg@1764: (MenuItem cg@1764: label: 'Background Color' cg@1764: translateLabel: true cg@1764: submenu: cg@1764: (Menu cg@1764: ( cg@1764: (MenuItem cg@1764: label: 'Gray' cg@1764: translateLabel: true cg@2792: choice: previewBackgroundColorHolder cg@1764: choiceValue: nil cg@1764: ) cg@1764: (MenuItem cg@1764: label: 'Black' cg@1764: translateLabel: true cg@2792: choice: previewBackgroundColorHolder cg@1764: choiceValue: black cg@1764: ) cg@1764: (MenuItem cg@1764: label: 'White' cg@1764: translateLabel: true cg@2792: choice: previewBackgroundColorHolder cg@1764: choiceValue: white cg@1764: ) cg@1774: (MenuItem cg@1774: label: '-' cg@1774: ) cg@1774: (MenuItem cg@1774: label: 'Red' cg@1774: translateLabel: true cg@2792: choice: previewBackgroundColorHolder cg@1774: choiceValue: red cg@1774: ) cg@1774: (MenuItem cg@1774: label: 'Green' cg@1774: translateLabel: true cg@2792: choice: previewBackgroundColorHolder cg@1774: choiceValue: green cg@1774: ) cg@1774: (MenuItem cg@1774: label: 'Blue' cg@1774: translateLabel: true cg@2792: choice: previewBackgroundColorHolder cg@1774: choiceValue: blue cg@1774: ) cg@1764: ) cg@1764: nil cg@1764: nil cg@1764: ) cg@1558: ) cg@1558: ) cg@1558: nil cg@1558: nil cg@1558: ) cg@2792: cg@2792: "Modified: / 04-07-2010 / 10:20:09 / cg" cg@1637: ! cg@1637: cg@1637: toolsMenuToolbar cg@1637: "This resource specification was automatically generated cg@1637: by the MenuEditor of ST/X." cg@1637: cg@1637: "Do not manually edit this!! If it is corrupted, cg@1637: the MenuEditor may not be able to read the specification." cg@1637: cg@2881: cg@1637: " cg@1637: MenuEditor new openOnClass:ImageEditor andSelector:#toolsMenuToolbar cg@1637: (Menu new fromLiteralArrayEncoding:(ImageEditor toolsMenuToolbar)) startUp cg@1637: " cg@1637: cg@1637: cg@1637: cg@1637: ^ cg@2881: #(Menu cg@2881: ( cg@2881: (MenuItem cg@2881: activeHelpKey: drawModePoint cg@2881: enabled: imageIsLoadedHolder cg@2881: label: 'Point' cg@2881: translateLabel: true cg@2881: isButton: true cg@2881: labelImage: (ResourceRetriever ImageEditor pointIcon) cg@2881: choice: editMode cg@2881: choiceValue: point cg@1637: ) cg@2881: (MenuItem cg@2881: activeHelpKey: drawModeSpray cg@2881: enabled: imageIsLoadedHolder cg@2881: label: 'Spray' cg@2881: translateLabel: true cg@2881: isButton: true cg@2881: labelImage: (ResourceRetriever ImageEditor sprayIcon) cg@2881: choice: editMode cg@2881: choiceValue: spray cg@2375: ) cg@2881: (MenuItem cg@2881: activeHelpKey: drawModeBox cg@2881: enabled: imageIsLoadedHolder cg@2881: label: 'Rect' cg@2881: translateLabel: true cg@2881: isButton: true cg@2881: labelImage: (ResourceRetriever ImageEditor rectIcon) cg@2881: choice: editMode cg@2881: choiceValue: box cg@1637: ) cg@2881: (MenuItem cg@2881: activeHelpKey: drawModeFilledBox cg@2881: enabled: imageIsLoadedHolder cg@2881: label: 'FillRect' cg@2881: translateLabel: true cg@2881: isButton: true cg@2881: labelImage: (ResourceRetriever ImageEditor fillRectIcon) cg@2881: choice: editMode cg@2881: choiceValue: filledBox cg@1637: ) cg@2881: (MenuItem cg@2881: activeHelpKey: drawModeCircle cg@2881: enabled: imageIsLoadedHolder cg@2881: label: 'Circle' cg@2881: translateLabel: true cg@2881: isButton: true cg@2881: labelImage: (ResourceRetriever ImageEditor circleIcon) cg@2881: choice: editMode cg@2881: choiceValue: circle cg@2375: ) cg@2881: (MenuItem cg@2881: activeHelpKey: drawModeFill cg@2881: enabled: imageIsLoadedHolder cg@2881: label: 'Fill' cg@2881: translateLabel: true cg@2881: isButton: true cg@2881: labelImage: (ResourceRetriever ImageEditor fillIcon) cg@2881: choice: editMode cg@2881: choiceValue: fill cg@1637: ) cg@2881: (MenuItem cg@2881: activeHelpKey: drawModeCopy cg@2881: enabled: imageIsLoadedHolder cg@2881: label: 'Copy' cg@2881: translateLabel: true cg@2881: isButton: true cg@2881: labelImage: (ResourceRetriever ImageEditor copyIcon) cg@2881: choice: editMode cg@2881: choiceValue: copy cg@1637: ) cg@2881: (MenuItem cg@2881: activeHelpKey: drawModePasteWithMask cg@2881: enabled: imageIsLoadedHolder cg@2881: label: 'Paste With Mask' cg@2881: translateLabel: true cg@2881: isButton: true cg@2881: labelImage: (ResourceRetriever ImageEditor pasteWithMaskIcon) cg@2881: choice: editMode cg@2881: choiceValue: pasteWithMask cg@1637: ) cg@2881: (MenuItem cg@2881: activeHelpKey: drawModePaste cg@2881: enabled: imageIsLoadedHolder cg@2881: label: 'Paste' cg@2881: translateLabel: true cg@2881: isButton: true cg@2881: labelImage: (ResourceRetriever ImageEditor pasteIcon) cg@2881: choice: editMode cg@2881: choiceValue: paste cg@1637: ) cg@2881: (MenuItem cg@2881: activeHelpKey: drawModePasteUnder cg@2881: enabled: imageIsLoadedHolder cg@2881: label: 'Paste Under' cg@2881: translateLabel: true cg@2881: isButton: true cg@2881: labelImage: (ResourceRetriever ImageEditor pasteUnderIcon) cg@2881: choice: editMode cg@2881: choiceValue: pasteUnder cg@1637: ) cg@2881: (MenuItem cg@2881: activeHelpKey: drawModeSpecial cg@2881: enabled: imageIsLoadedHolder cg@2881: label: 'Special' cg@2881: translateLabel: true cg@2881: isButton: true cg@2881: labelImage: (ResourceRetriever ImageEditor specialIcon) cg@2881: choice: editMode cg@2881: choiceValue: specialOperation cg@1637: ) cg@1637: ) cg@1637: nil cg@1637: nil cg@1637: ) tz@400: ! ! tz@400: cg@1842: !ImageEditor class methodsFor:'tableColumns specs'! cg@1842: cg@1900: colorTableColumns cg@1842: "This resource specification was automatically generated cg@1842: by the DataSetBuilder of ST/X." cg@1842: cg@1842: "Do not manually edit this!! If it is corrupted, cg@1842: the DataSetBuilder may not be able to read the specification." cg@1842: cg@1842: " cg@1975: DataSetBuilder new openOnClass:ImageEditor andSelector:#colorTableColumns cg@1842: " cg@1842: cg@1842: cg@1842: cg@1842: ^#( cg@1842: (DataSetColumnSpec cg@2174: activeHelpKey: '' cg@1842: labelButtonType: Button cg@1842: rendererType: rowSelector cg@2712: backgroundSelector: theColorItself: cg@2712: selectedBackgroundSelector: theColorItself: cg@1842: isResizeable: false cg@1842: ) cg@1842: (DataSetColumnSpec cg@1842: label: 'R' cg@1842: labelAlignment: left cg@1842: labelButtonType: Button cg@1842: columnAlignment: right cg@1842: editorType: InputField cg@1842: type: number cg@1842: model: redFromColor: cg@1842: writeSelector: redAtColor:put: cg@1842: selectSelector: canSelectRedInColor: cg@1842: ) cg@1842: (DataSetColumnSpec cg@1842: label: 'G' cg@1842: labelAlignment: left cg@1842: labelButtonType: Button cg@1842: columnAlignment: right cg@1842: editorType: InputField cg@1842: type: number cg@1842: model: greenFromColor: cg@1842: writeSelector: greenAtColor:put: cg@1842: selectSelector: canSelectGreenInColor: cg@1842: ) cg@1842: (DataSetColumnSpec cg@1842: label: 'B' cg@1842: labelAlignment: left cg@1842: labelButtonType: Button cg@1842: columnAlignment: right cg@1842: editorType: InputField cg@1842: type: number cg@1842: model: blueFromColor: cg@1842: writeSelector: blueAtColor:put: cg@1842: selectSelector: canSelectBlueInColor: cg@1842: ) cg@1842: ) cg@2174: cg@2174: "Modified: / 22-07-2007 / 13:21:57 / cg" cg@1842: ! ! cg@1842: tz@400: !ImageEditor methodsFor:'accessing'! tz@400: tz@400: image tz@767: "returns the current editing image" tz@400: cg@1376: ^ imageEditView image tz@400: ! tz@400: tz@400: postOpenAction: anAction tz@767: "sets an action which is evaluated after opening" tz@400: tz@400: postOpenAction := anAction cg@1381: ! cg@1381: cg@1381: resourceClass:aClass cg@1381: imageEditView resourceClass:aClass tz@400: ! ! tz@400: cg@2767: !ImageEditor methodsFor:'accessing-behavior'! cg@2767: cg@2767: allowedToChangeImageDimensionAndDepth cg@2767: "used to edit an existing image's contents only (Expecco)" cg@2767: cg@2767: ^ allowedToChangeImageDimensionAndDepth ? true cg@2767: ! cg@2767: cg@2767: allowedToChangeImageDimensionAndDepth:aBoolean cg@2767: "used to edit an existing image's contents only (Expecco)" cg@2767: cg@2767: allowedToChangeImageDimensionAndDepth := aBoolean cg@2767: ! ! cg@2767: cg@1398: !ImageEditor methodsFor:'accessing-views'! tz@400: cg@915: colorDataSetView cg@915: "returns the view of the colormap" cg@915: cg@1597: ^(self componentAt: #colorDataSetView) cg@915: cg@915: "Created: / 26.7.1998 / 12:02:14 / cg" cg@915: ! cg@915: tz@487: coordLabel tz@767: "returns the view the coord label" tz@487: cg@1597: ^self componentAt: #coordLabel tz@487: ! tz@487: tz@400: imageEditView tz@911: "returns the view of the image" tz@400: cg@1376: imageEditView isNil ifTrue:[ cg@1597: imageEditView := (self componentAt: #imageEditView) scrolledView. cg@1376: imageEditView addDependent:self. cg@1376: ]. cg@1376: ^ imageEditView cg@1345: cg@1345: "Modified: / 10.2.2000 / 23:19:20 / cg" tz@400: ! tz@400: tz@400: imagePreView tz@767: "returns the preview of the image" tz@400: cg@2339: |imagePreViewSubViews| cg@2339: cg@2339: imagePreViewSubViews := (self componentAt: #imagePreView) subViews. cg@2339: sr@2043: "subViews is an empty array at closing image Editor" cg@2339: imagePreViewSubViews isEmptyOrNil ifTrue:[ sr@2043: ^ nil sr@2043: ]. sr@2043: cg@2339: ^ imagePreViewSubViews first tz@475: ! ! tz@475: tz@400: !ImageEditor methodsFor:'aspects'! tz@400: cg@928: activityInfoHolder cg@1987: ^ self infoLabelHolder cg@928: cg@928: "Modified: / 29.7.1998 / 18:49:03 / cg" cg@928: ! cg@928: cg@915: colorColumnAdaptor cg@915: ^ self cg@915: cg@915: "Created: / 26.7.1998 / 12:17:03 / cg" cg@915: ! cg@915: cg@2792: hasClassAndSelectorDefinedHolder cg@1054: ^ [ cg@1965: |cls| cg@1965: cg@1965: (cls := imageEditView resourceClass) notNil cg@1965: and:[imageEditView resourceSelector notNil] cg@1054: ] cg@933: cg@2792: "Created: / 04-07-2010 / 10:11:10 / cg" cg@2792: ! cg@2792: cg@2792: hasClassDefinedHolder cg@1054: ^ [ cg@1965: imageEditView resourceClass notNil cg@1054: ] cg@933: cg@2792: "Created: / 04-07-2010 / 10:11:47 / cg" cg@2792: ! cg@2792: cg@2792: hasColorSelectedHolder cg@3195: ^ [ self selectedColors value notEmptyOrNil "self selectedColorIndexOrNil notNil" ] cg@2792: cg@2792: "Created: / 04-07-2010 / 10:12:22 / cg" cg@2651: ! cg@2651: cg@1008: hasColormap cg@2792: ^ self image notNil and:[self image colorMap notNil] cg@2792: cg@2792: "Created: / 30-09-1998 / 23:53:55 / cg" cg@2792: "Modified: / 04-07-2010 / 10:13:26 / cg" cg@1008: ! cg@1008: cg@2651: hasColormapAndColorSelected cg@2792: ^ [ self hasColormapHolder value and:[self hasColorSelectedHolder value]] cg@2792: cg@2792: "Modified: / 04-07-2010 / 10:13:13 / cg" cg@2792: ! cg@2792: cg@3195: hasColormapAndSingleColorSelected cg@3195: ^ [ self hasColormapHolder value and:[self hasSingleColorSelectedHolder value]] cg@3195: cg@3195: "Modified: / 04-07-2010 / 10:13:13 / cg" cg@3195: ! cg@3195: cg@2792: hasColormapHolder cg@2792: ^ [self hasColormap] cg@2792: cg@2792: "Created: / 04-07-2010 / 10:13:05 / cg" cg@2792: ! cg@2792: cg@3195: hasSingleColorSelectedHolder cg@3195: ^ [ self selectedColors value size == 1 "self selectedColorIndexOrNil notNil" ] cg@3195: cg@3195: "Created: / 04-07-2010 / 10:12:22 / cg" cg@3195: ! cg@3195: cg@2812: imageHasImageSequence cg@3080: |img| cg@3080: cg@3080: ^ (img := self image) notNil and:[img imageSequence notNil] cg@2812: cg@2812: "Created: / 21-10-2010 / 14:35:45 / cg" cg@2812: ! cg@2812: cg@2812: imageHasImageSequenceHolder cg@2812: |holder| cg@2812: cg@2812: (holder := builder bindingAt:#imageHasImageSequenceHolder) isNil ifTrue:[ cg@2812: builder aspectAt:#imageHasImageSequenceHolder put:(holder := false asValue). cg@2812: holder value:(self imageHasImageSequence). cg@2812: ]. cg@2812: ^ holder cg@2812: cg@2812: "Modified: / 21-10-2010 / 14:36:57 / cg" cg@2812: ! cg@2812: cg@2812: imageHasNextImage cg@2812: ^ self imageHasImageSequence and:[ (imageSeqNr ? 1) < self image imageSequence size ] cg@2812: cg@2812: "Created: / 21-10-2010 / 14:37:10 / cg" cg@2812: ! cg@2812: cg@2792: imageHasNextImageHolder cg@2812: |holder| cg@2812: cg@2812: (holder := builder bindingAt:#imageHasNextImageHolder) isNil ifTrue:[ cg@2812: builder aspectAt:#imageHasNextImageHolder put:(holder := false asValue). cg@2812: holder value:(self imageHasNextImage). cg@2812: ]. cg@2812: ^ holder cg@2812: cg@2812: "Modified: / 21-10-2010 / 14:37:40 / cg" cg@2812: ! cg@2812: cg@2812: imageHasPreviousImage cg@2812: ^ self imageHasImageSequence and:[ (imageSeqNr ? 1) > 1 ] cg@2812: cg@2812: "Created: / 21-10-2010 / 14:37:21 / cg" cg@2812: ! cg@2812: cg@2812: imageHasPreviousImageHolder cg@2812: |holder| cg@2812: cg@2812: (holder := builder bindingAt:#imageHasPreviousImageHolder) isNil ifTrue:[ cg@2812: builder aspectAt:#imageHasPreviousImageHolder put:(holder := false asValue). cg@2812: holder value:(self imageHasPreviousImage). cg@2812: ]. cg@2812: ^ holder cg@2812: cg@2812: "Modified: / 21-10-2010 / 14:37:48 / cg" cg@1380: ! cg@1380: cg@928: imageInfoHolder cg@928: |holder| cg@2792: cg@928: (holder := builder bindingAt:#imageInfoHolder) isNil ifTrue:[ cg@928: builder aspectAt:#imageInfoHolder put:(holder := '' asValue). cg@928: ]. cg@928: ^ holder cg@928: cg@2792: "Modified: / 04-07-2010 / 10:15:14 / cg" tz@400: ! tz@400: cg@2767: imageIsLoadedAndAllowedToChangeImageDimensionAndDepth cg@2767: "returns whether an image is loaded as value holder" cg@2767: cg@2767: ^ [ cg@2792: self imageIsLoadedHolder value cg@2767: and:[ self allowedToChangeImageDimensionAndDepth ] cg@2767: ] cg@2792: cg@2792: "Modified: / 04-07-2010 / 10:15:43 / cg" cg@2767: ! cg@2767: cg@933: imageIsLoadedAndClassDefined cg@933: "returns whether an image is loaded as value holder" cg@933: cg@2792: ^ [self hasClassAndSelectorDefinedHolder value cg@2792: and:[self imageIsLoadedHolder value]] cg@2792: cg@2792: "Created: / 31-07-1998 / 02:04:18 / cg" cg@2792: "Modified: / 04-07-2010 / 10:15:48 / cg" cg@2792: ! cg@2792: cg@2792: imageIsLoadedHolder cg@2792: "returns whether an image is loaded as value holder" cg@2792: cg@2792: |holder| cg@2792: cg@2792: (holder := builder bindingAt:#imageIsLoaded) isNil ifTrue:[ cg@2792: builder aspectAt:#imageIsLoaded put:(holder := false asValue). cg@2792: ]. cg@2792: ^ holder cg@2792: cg@2792: "Created: / 04-07-2010 / 10:15:38 / cg" cg@933: ! cg@933: tz@400: listOfColors penk@1896: "returns the list of colors" penk@1896: penk@1896: |list| penk@1896: penk@1896: (list := builder bindingAt:#listOfColors) isNil ifTrue:[ penk@1896: builder aspectAt:#listOfColors put:(list := List new). penk@1896: list addDependent:self. tz@400: ]. penk@1896: ^ list tz@400: ! tz@400: cg@1987: magnificationHolder cg@1987: "returns current magnification of the image as an AspectAdaptor" cg@1987: cg@1987: |holder| cg@1987: (holder := builder bindingAt:#valueOfMagnification) isNil ifTrue:[ cg@1987: builder aspectAt:#valueOfMagnification put:( cg@1987: holder := AspectAdaptor new subject:self; forAspect:#magnification) cg@1987: ]. cg@1987: ^ holder cg@1987: ! cg@1987: cg@2881: penWidthHolder cg@2881: |holder| cg@2881: cg@2881: (holder := builder bindingAt:#penWidthHolder) isNil ifTrue:[ cg@2881: builder aspectAt:#penWidthHolder put:(holder := imageEditView penWidth asValue). cg@2881: holder onChangeSend:#penWidthHolderChanged to:self. cg@2881: ]. cg@2881: ^ holder cg@2881: cg@2881: "Created: / 15-02-2012 / 22:30:58 / cg" cg@2881: ! cg@2881: cg@2792: previewBackgroundColorHolder cg@1764: |holder| cg@2792: cg@1764: (holder := builder bindingAt:#previewBackgroundColor) isNil ifTrue:[ cg@1764: builder aspectAt:#previewBackgroundColor put:(holder := nil asValue). cg@1764: holder addDependent:self. cg@1764: ]. cg@1764: ^ holder cg@2792: cg@2792: "Created: / 04-07-2010 / 10:19:34 / cg" cg@1764: ! cg@1764: cg@3195: selectedColors cg@3195: "returns a valueHolder for the current set of selected colors." cg@3195: cg@3195: |holder| cg@3195: cg@3195: (holder := builder bindingAt:#selectedColors) isNil ifTrue:[ cg@3195: builder aspectAt:#selectedColors put:(holder := nil asValue). cg@3195: holder onChangeSend:#selectedColorsChanged to:self. cg@3195: ]. cg@3195: ^ holder cg@3195: ! cg@3195: tz@400: selectionOfColor cg@1682: "returns a valueHolder for the current selection of the edit color. cg@1682: Here, an AspectAdaptor which accesses selectedColorIndex is returned." tz@400: tz@400: |holder| cg@1682: tz@400: (holder := builder bindingAt:#selectionOfColor) isNil ifTrue:[ tz@400: builder aspectAt:#selectionOfColor put:( cg@1682: holder := AspectAdaptor new subject:self; forAspect:#selectedColorIndex ). tz@400: ]. tz@400: ^ holder tz@400: ! tz@400: cg@2881: spraySpotHolder cg@2881: |holder| cg@2881: cg@2881: (holder := builder bindingAt:#spraySpotHolder) isNil ifTrue:[ cg@2881: builder aspectAt:#spraySpotHolder put:(holder := imageEditView spraySpot asValue). cg@2881: holder onChangeSend:#spraySpotHolderChanged to:self. cg@2881: ]. cg@2881: ^ holder cg@2881: cg@2881: "Created: / 15-02-2012 / 22:36:38 / cg" cg@2881: ! cg@2881: cg@1558: tileModeHolder cg@1558: |holder| cg@2812: cg@1558: (holder := builder bindingAt:#tileModeHolder) isNil ifTrue:[ cg@1558: builder aspectAt:#tileModeHolder put:(holder := false asValue). cg@1558: holder addDependent:self. cg@1558: ]. cg@1558: ^ holder cg@2812: cg@2812: "Modified: / 21-10-2010 / 14:35:24 / cg" cg@1558: ! cg@1558: tz@400: valueOfMagnification sv@2308: tz@767: "returns current magnification of the image as an AspectAdaptor" tz@400: cg@1987: self obsoleteMethodWarning:'stupid method name - use #magnificationHolder'. cg@1987: ^ self magnificationHolder tz@400: ! ! tz@400: tz@767: !ImageEditor methodsFor:'change & update'! tz@767: tz@767: findColorMapMode tz@899: "finds the colorMapMode for a new image" tz@767: cg@2446: |image newListOfColors colorMapModeKey drawColor1 drawColor2 someOrAllUsedColors| cg@1054: cg@1054: image := self image. cg@1975: image isNil ifTrue:[^ self ]. cg@1847: cg@1847: image mask notNil ifTrue: [ penk@1896: colorMapModeKey := 'masked'. cg@1847: ] ifFalse:[ penk@1896: colorMapModeKey := 'depth'. cg@1054: ]. penk@1896: colorMapModeKey := colorMapModeKey , image depth printString. cg@1967: self colorMapMode setValue:colorMapModeKey. cg@1847: cg@3359: image photometric == #palette ifTrue:[ cg@3359: image colorMap isNil ifTrue:[ cg@3359: image depth > 16 ifTrue:[ cg@3359: image photometric:#rgb cg@3359: ]. cg@3359: ]. cg@3359: ]. cg@1928: cg@1847: image depth > 12 ifTrue:[ cg@2447: newListOfColors := OrderedCollection new. cg@2870: (image depth > 16 or:[image colorMap isEmptyOrNil]) ifTrue:[ cg@1927: someOrAllUsedColors := image usedColorsMax:10000. cg@2054: someOrAllUsedColors notNil ifTrue:[ cg@2054: someOrAllUsedColors := someOrAllUsedColors asArray. cg@2054: someOrAllUsedColors sort:self sortBlockForColors. cg@2446: newListOfColors addAll:someOrAllUsedColors. cg@2054: "/ listOfColors add:Color black; add:Color white. cg@3317: ]. cg@3317: image mask notNil ifTrue:[ cg@3317: newListOfColors := (Array with:(Color noColor)),newListOfColors. cg@3317: ]. cg@1904: ] ifFalse:[ cg@2446: newListOfColors addAll:(image colorMap). cg@1847: ]. cg@1847: ] ifFalse:[ cg@2447: newListOfColors := OrderedCollection withAll:(self listOfColors). cg@2446: newListOfColors isEmpty ifTrue:[ cg@1847: self colorMapMode: colorMapMode value. cg@1847: image := self image. cg@1847: ]. cg@3317: "/ image mask notNil ifTrue:[ cg@3317: "/ newListOfColors := (Array with:(Color noColor)),newListOfColors. cg@3317: "/ ]. cg@2054: ]. cg@2446: newListOfColors notEmptyOrNil ifTrue:[ cg@2446: drawColor1 := newListOfColors at:1. cg@2446: drawColor2 := newListOfColors at:2 ifAbsent:drawColor1. cg@2054: cg@2054: self hasMask ifTrue: [ sv@3367: (newListOfColors includes:(Color colorId:0)) ifFalse:[ cg@2446: newListOfColors addFirst:(Color colorId:0). cg@2446: drawColor1 := newListOfColors at:2. cg@2446: drawColor2 := newListOfColors at:3 ifAbsent:drawColor1. cg@2054: ] cg@2054: ]. cg@2446: "/ imageEditView drawingColors:(Array with: drawColor1 with: drawColor2). cg@2446: "/ self selectionOfColor cg@2446: "/ setValue: 0; cg@2446: "/ value: (listOfColors indexOf: imageEditView selectedColor). tz@767: ]. cg@2447: self listOfColors asOrderedCollection ~= newListOfColors ifTrue:[ cg@2447: self listOfColors contents:newListOfColors. cg@2447: ]. cg@2870: cg@3359: "Modified: / 06-12-2016 / 12:51:36 / cg" tz@767: ! tz@767: cg@3195: selectedColorsChanged cg@3195: |colorIndices| cg@3195: cg@3195: (colorIndices := self selectedColors value) isEmptyOrNil ifTrue:[ cg@3195: self selectionOfColor value:nil cg@3195: ] ifFalse:[ cg@3195: colorIndices size == 1 ifTrue:[ cg@3195: "/ as single color selected cg@3195: self selectionOfColor value:colorIndices first cg@3195: ] ifFalse:[ cg@3195: "/ multipl selected cg@3195: self selectionOfColor value:nil cg@3195: ]. cg@3195: ]. cg@3195: ! cg@3195: tz@942: update:something with:aParameter from:changedObject cg@2042: |clrIndex img imagePreView clr changedColor| cg@1436: cg@1436: img := self image. cg@2042: imagePreView := self imagePreView. cg@1558: cg@1558: changedObject == self tileModeHolder ifTrue:[ cg@2042: imagePreView cg@1764: tileMode:(changedObject value) tileOffset:(img extent); cg@1764: clear; cg@1764: invalidate. cg@1764: ^ self cg@1764: ]. cg@2792: changedObject == self previewBackgroundColorHolder ifTrue:[ cg@1764: clr := changedObject value isNil cg@1764: ifTrue:[imageEditView viewBackground] cg@1764: ifFalse:[Color perform:changedObject value]. cg@2042: imagePreView cg@1764: viewBackground:clr; cg@1764: clear; cg@1764: invalidate. cg@1558: ^ self cg@1558: ]. cg@1558: cg@945: changedObject == self listOfColors ifTrue:[ cg@945: something == #at: ifTrue:[ cg@945: "/ colormap entry changed at aParameter cg@960: cg@960: clrIndex := aParameter. cg@960: (self hasMask) ifTrue:[ cg@960: clrIndex := clrIndex - 1. cg@960: ]. cg@1928: changedColor := changedObject at:aParameter. cg@1928: img colorMap notNil ifTrue:[ cg@1928: img colorMap at:clrIndex put:changedColor. cg@1928: self colorMapChanged. cg@1928: ] ifFalse:[ cg@1928: drawingColormap notNil ifTrue:[ cg@1928: drawingColormap at:clrIndex put:changedColor. cg@1928: ]. cg@1928: ]. cg@945: ^ self cg@945: ]. penk@1896: ^ self cg@945: ]. cg@1124: cg@1124: changedObject == imageEditView undoImages ifTrue:[ cg@1987: self canUndoHolder value:(changedObject notEmpty). cg@1124: ^ self. cg@1124: ]. cg@1124: cg@1345: changedObject == imageEditView ifTrue:[ cg@1345: something == #imageColors ifTrue:[ cg@1847: self updateListOfColorsAndColormapMode. cg@1345: ^ self. cg@1345: ]. cg@1345: something == #image ifTrue:[ cg@2812: self updateAfterImageChange. cg@2728: imagePreView image:img scroll:false. cg@1847: self updateListOfColorsAndColormapMode. cg@1558: self tileModeHolder value ifTrue:[ cg@2042: imagePreView tileMode:true tileOffset:(img extent). cg@1558: ]. cg@1345: ^ self. cg@1345: ]. cg@1345: something == #subImageIn ifTrue:[ cg@2042: imagePreView image ~~ img ifTrue:[ sv@1740: self error:'internal error' mayProceed:true. cg@1406: ]. cg@1558: self tileModeHolder value ifTrue:[ cg@2042: imagePreView invalidate. cg@1558: ] ifFalse:[ cg@2042: imagePreView invalidate:aParameter. cg@1558: ]. cg@1345: ^ self. cg@1345: ]. cg@1491: something == #selectedColor ifTrue:[ cg@1842: (aParameter isNil or:[aParameter = (Color colorId:0)]) ifTrue:[ cg@1842: "/ no color/mask */ cg@1842: "/ self halt. cg@1842: clrIndex := self hasMask ifTrue:[1] ifFalse:[0]. cg@1842: ] ifFalse:[ cg@1842: clrIndex := self listOfColors indexOf:aParameter. cg@1491: ]. cg@3195: self selectedColors value:{clrIndex}. "/ selectionOfColor value:clrIndex. cg@1491: ^ self. cg@1491: ]. cg@1345: ^ self. cg@1345: ]. cg@1345: cg@1880: changedObject == imageEditView modifiedHolder ifTrue:[ cg@1880: "/ self halt:'to be implemented'. cg@1880: ^ self cg@1880: ]. cg@1880: cg@1345: changedObject == imageEditView image ifTrue:[ cg@2042: "/ self halt:'to be implemented'. cg@2812: self updateAfterImageChange. cg@1345: ^ self. cg@1345: ]. cg@1345: tz@942: super update:something with:aParameter from:changedObject tz@942: cg@2812: "Modified: / 21-10-2010 / 14:34:31 / cg" cg@2812: ! cg@2812: cg@2812: updateAfterImageChange cg@2812: |img| cg@2812: cg@2812: (img := self image) notNil ifTrue:[ cg@2812: img := img onDevice:device. cg@2812: self updateColorsFromImage:img. cg@2812: self findColorMapMode. cg@2812: self updateLabelsAndHistory. cg@2812: cg@2812: imageSeqNr isNil ifTrue:[ cg@2812: imageSeqNr := 1 cg@2812: ]. cg@2812: self imageHasImageSequenceHolder value:(self imageHasImageSequence). cg@2812: self imageHasNextImageHolder value:(self imageHasNextImage). cg@2812: self imageHasPreviousImageHolder value:(self imageHasPreviousImage). cg@2812: ] ifFalse:[ cg@2812: self updateForNoImage cg@2812: ] cg@2812: cg@2812: "Modified: / 21-10-2010 / 14:40:45 / cg" tz@942: ! tz@942: cg@1900: updateColorsFromImage:image cg@1900: |colors| cg@1900: cg@2870: image depth > 16 ifTrue:[ cg@2870: self listOfColors contents:#(). cg@2870: ^ self. cg@2870: ]. cg@2870: cg@1904: colors := image colorMap. cg@1904: colors isNil ifTrue:[ cg@1906: Error handle:[:ex | cg@1906: colors := OrderedCollection new. cg@1906: ] do:[ cg@1906: colors := image usedColors asSet. cg@2870: ]. cg@1900: ]. cg@1904: self listOfColors contents:(colors asOrderedCollection). cg@2870: cg@2870: "Modified: / 18-01-2012 / 13:57:43 / cg" cg@1900: ! cg@1900: cg@1054: updateForNoImage tz@767: "updates channels and view, if image is loaded" tz@767: cg@2792: self imageIsLoadedHolder value: false. tz@767: self listOfColors removeAll. cg@2812: self imagePreView image: nil. cg@2812: self imageHasImageSequenceHolder value:false. cg@2812: cg@2812: "Modified: / 21-10-2010 / 14:39:13 / cg" tz@767: ! tz@767: tz@767: updateLabelsAndHistory tz@767: "updates labels and history, if something has changed" tz@767: cg@1910: |image| cg@1910: cg@1910: image := self image. cg@1910: cg@2792: self imageIsLoadedHolder value: image notNil. cg@1910: image isNil ifTrue: [^nil]. tz@767: tz@767: self updateInfoLabel. tz@767: cg@1975: imageEditView resourceClass notNil ifTrue:[ cg@1975: imageEditView resourceSelector notNil ifTrue:[ cg@1975: self addHistoryEntryForClass:imageEditView resourceClass selector:imageEditView resourceSelector. cg@1975: ] cg@1975: ]. cg@1975: cg@1975: image fileName notNil ifTrue: [ cg@1975: self addHistoryEntryForFile:image fileName. cg@1975: ]. cg@2792: cg@2792: "Modified: / 04-07-2010 / 10:16:02 / cg" cg@1847: ! cg@1847: cg@1847: updateListOfColorsAndColormapMode cg@2446: |selectedColor colorMap image| cg@2446: cg@2446: selectedColor := self selectedColorOrNil. cg@1847: cg@1847: image := self image. cg@1975: image isNil ifTrue:[ cg@1847: self listOfColors removeAll. cg@1975: ] ifFalse:[ cg@1975: colorMap := image colorMap. cg@2447: colorMap notNil ifTrue:[ cg@2447: (colorMap size <= 4096) ifTrue:[ cg@2447: image mask notNil ifTrue:[ cg@2447: colorMap := (Array with:(Color noColor)),colorMap. cg@2447: ]. cg@2447: self listOfColors contents:colorMap. cg@2447: ] ifFalse:[ cg@2447: self listOfColors removeAll. cg@2447: colorMap isFixedPalette ifTrue:[ cg@2447: image colorMap:nil. cg@2447: image photometric:#rgb. cg@2447: image samplesPerPixel:3. cg@2447: cg@2447: image bitsPerSample:(Array cg@2447: with:(colorMap bitsRed) cg@2447: with:(colorMap bitsGreen) cg@2447: with:(colorMap bitsBlue)). cg@2447: ]. cg@2447: ] cg@1847: ]. cg@1847: ]. cg@1847: self findColorMapMode. cg@2446: selectedColor notNil ifTrue:[ cg@2446: self selectColor:selectedColor. cg@2446: ]. tz@767: ! ! tz@767: cg@915: !ImageEditor methodsFor:'data access'! cg@915: cg@1951: atColor:anOldColor put:newColor cg@1952: "a color changed to a new color" cg@1952: cg@1930: |index list oldColor image newImage oldSel| ca@1611: ca@1611: list := self listOfColors. cg@1951: index := list identityIndexOf:anOldColor. ca@1611: cg@1930: oldSel := self selectionOfColor value. ca@1611: index ~~ 0 ifTrue:[ cg@1928: oldColor := list at:index. cg@1928: list at:index put:newColor ca@1611: ] ifFalse:[ sv@1740: self error:'internal error' mayProceed:true. cg@1928: list add:newColor cg@1928: ]. cg@1928: cg@1928: image := self image. cg@1928: (image colorMap isNil cg@1928: and:[drawingColormap isNil]) ifTrue:[ cg@1928: oldColor notNil ifTrue:[ cg@1928: imageEditView makeUndo. cg@1928: newImage := image copy. cg@1928: newImage cg@1928: colorsFromX:0 y:0 toX:(image width-1) y:(image height-1) cg@1928: do:[:x :y :clr | cg@1928: |newClr| cg@1928: cg@1951: newClr := (clr = oldColor) ifTrue:[newColor] ifFalse:[clr]. cg@1928: newImage colorAtX:x y:y put:newClr cg@1928: ]. cg@1928: imageEditView image:newImage. cg@1928: imageEditView setModified. cg@1928: self updateImage. cg@1928: self updateImagePreView. cg@1930: cg@3195: self selectedColors value:{oldSel}. cg@1930: imageEditView selectedColorIndex:oldSel. cg@1930: imageEditView selectedColor:(self listOfColors at:oldSel). cg@1928: ] ca@1611: ]. ca@1611: ! ca@1611: tz@942: blueAtColor:aColor put:newBlue tz@942: "helper used to return a new row element, when blue is changed" tz@942: tz@942: |byte| tz@942: ca@1611: aColor isNil ifTrue:[^ self]. "/ mask cannot be changed tz@942: byte := newBlue clampBetween:0 and:255. ca@1611: byte = aColor blueByte ifTrue:[^ self ]. ca@1611: ca@1611: self atColor:aColor ca@1611: put:(Color redByte:(aColor redByte) greenByte:(aColor greenByte) blueByte:byte). tz@942: ! tz@942: cg@915: blueFromColor:aColor cg@915: "helper used to access a color as a row in the dataSet view" cg@915: cg@930: aColor isNil ifTrue:[^ 'none']. cg@915: ^ aColor blueByte ? 'mask' cg@915: cg@915: "Created: / 26.7.1998 / 12:30:35 / cg" cg@930: "Modified: / 31.7.1998 / 01:11:18 / cg" cg@915: ! cg@915: cg@945: canSelectBlueInColor:aColor cg@945: ^ aColor blueByte notNil cg@945: cg@945: "Created: / 7.8.1998 / 22:50:34 / cg" cg@945: "Modified: / 7.8.1998 / 22:52:57 / cg" cg@945: ! cg@945: cg@945: canSelectGreenInColor:aColor cg@945: ^ aColor greenByte notNil cg@945: cg@945: "Created: / 7.8.1998 / 22:50:22 / cg" cg@945: "Modified: / 7.8.1998 / 22:52:46 / cg" cg@945: ! cg@945: cg@945: canSelectRedInColor:aColor cg@945: ^ aColor redByte notNil cg@945: cg@945: "Created: / 7.8.1998 / 22:50:00 / cg" cg@945: "Modified: / 7.8.1998 / 22:51:03 / cg" cg@945: ! cg@945: tz@942: greenAtColor:aColor put:newGreen tz@942: "helper used to return a new row element, when green is changed" tz@942: tz@942: |byte| tz@942: ca@1611: aColor isNil ifTrue:[^ self]. "/ mask cannot be changed tz@942: byte := newGreen clampBetween:0 and:255. ca@1611: byte = aColor greenByte ifTrue:[^ self]. ca@1611: ca@1611: self atColor:aColor ca@1611: put:(Color redByte:(aColor redByte) greenByte:byte blueByte:(aColor blueByte)). tz@942: ! tz@942: cg@915: greenFromColor:aColor cg@915: "helper used to access a color as a row in the dataSet view" cg@915: cg@930: aColor isNil ifTrue:[^ 'none']. cg@915: ^ aColor greenByte ? 'mask' cg@915: cg@915: "Created: / 26.7.1998 / 12:30:29 / cg" cg@930: "Modified: / 31.7.1998 / 01:11:31 / cg" cg@915: ! cg@915: tz@942: redAtColor:aColor put:newRed tz@942: "helper used to return a new row element, when red is changed" tz@942: tz@942: |byte| tz@942: ca@1611: aColor isNil ifTrue:[^ self]. "/ mask cannot be changed tz@942: byte := newRed clampBetween:0 and:255. ca@1611: byte = aColor redByte ifTrue:[^ self]. ca@1611: ca@1611: self atColor:aColor ca@1611: put:(Color redByte:byte greenByte:(aColor greenByte) blueByte:(aColor blueByte)). tz@942: ! tz@942: cg@915: redFromColor:aColor cg@915: "helper used to access a color as a row in the dataSet view" cg@915: cg@930: aColor isNil ifTrue:[^ 'none']. cg@915: ^ aColor redByte ? 'mask' cg@915: cg@930: "Modified: / 31.7.1998 / 01:11:35 / cg" cg@1449: ! cg@1449: cg@2712: theColorItself:aColor cg@2712: "an accessor for the table-column" cg@2712: cg@1449: ^ aColor cg@915: ! ! cg@915: cg@2663: !ImageEditor methodsFor:'defaults'! cg@2663: cg@2663: aboutIcon cg@2663: ^ self class defaultIcon cg@2663: ! ! cg@2663: cg@2339: !ImageEditor methodsFor:'drag & drop'! cg@2339: cg@2339: canDropObjects:aCollectionOfDropObjects in:aWidget cg@2339: ^ (aCollectionOfDropObjects size == 1) cg@2339: and:[ aCollectionOfDropObjects cg@2339: contains:[:dropObject | dropObject isFileObject]] cg@2339: ! cg@2339: cg@2339: dropObjects:aCollectionOfDropObjects in:aWidget at:position cg@2339: |dropObject| cg@2339: cg@2339: dropObject := aCollectionOfDropObjects first. cg@2339: dropObject isFileObject ifTrue:[ cg@2339: self loadFromFile:dropObject asFilename. cg@2339: ] cg@2339: ! ! cg@2339: cg@2339: !ImageEditor methodsFor:'event handling'! cg@2339: cg@2339: processEvent:anEvent cg@2339: "Return true, if I have eaten the event" cg@2339: cg@2945: cg@2945: cg@2841: |view focusView p transformation| cg@2841: cg@2841: view := anEvent view. cg@2841: view notNil ifTrue:[ cg@2841: view == self imagePreView ifTrue:[ cg@2841: ((anEvent isButtonPressEvent and:[ anEvent button == 1 ]) cg@2841: or:[ anEvent isButtonMotionEvent and:[ anEvent hasButton1 ]]) ifTrue:[ cg@2841: p := anEvent x @ anEvent y. cg@2841: (transformation := view transformation) notNil ifTrue:[ cg@2841: p := transformation applyInverseTo:p. cg@2841: ]. cg@2841: self imageEditView scrollToMakeVisible:p. cg@2841: ^ true. cg@2546: ]. cg@2841: ]. cg@2841: cg@2841: anEvent isKeyPressEvent ifTrue:[ cg@2841: focusView := view windowGroup focusView ? view. cg@2841: (focusView isComponentOf:(builder componentAt:#colorDataSetView)) ifTrue:[ cg@2841: anEvent key == #Paste ifTrue:[ cg@2841: self pasteColorIntoColormap. cg@2841: ^ true. cg@2841: ]. cg@2841: anEvent key == #Copy ifTrue:[ cg@2841: self copyColorFromColormap. cg@2841: ^ true. cg@2841: ]. cg@2841: ]. cg@2339: ]. cg@2339: ]. cg@2339: ^ false. cg@2841: cg@2841: "Modified: / 04-04-2011 / 13:50:09 / cg" cg@2339: ! ! cg@2339: tz@672: !ImageEditor methodsFor:'help'! tz@672: tz@672: defaultInfoLabel cg@1969: "returns the text shown in the info label, when the mouse is NOT over cg@1969: some widget with a help text." tz@672: cg@1966: |resourceClass resourceSelector| cg@1376: cg@1376: resourceClass := imageEditView resourceClass. cg@1965: resourceClass notNil ifTrue:[ cg@1969: resourceSelector := imageEditView resourceSelector. cg@1966: resourceSelector notNil ifTrue:[ cg@1969: ^ resourceClass name, ' >> ', resourceSelector cg@1966: ]. tz@672: ]. cg@1376: ^ 'No class and selector defined.' tz@674: ! tz@674: tz@702: openDocumentation tz@767: "opens the documentation file of the Image Editor" tz@674: tz@763: self openHTMLDocument: 'tools/uipainter/ImageEditor.html' tz@763: tz@672: ! ! tz@672: tz@767: !ImageEditor methodsFor:'loading'! tz@767: cg@1975: loadFromClass:aClass andSelector:aSelector cg@1975: "loads an image from the method specified by class and selector" cg@1975: cg@1975: self assert:(aClass isNil or:[aClass isClass]). cg@1975: cg@2932: (aClass isNil or:[aSelector isNil]) ifTrue:[ cg@1975: imageEditView resourceClass:aClass. cg@1975: imageEditView resourceSelector:aSelector. cg@1969: imageEditView image:nil. cg@2006: self clearModified. cg@1966: ^ self. cg@1966: ]. cg@1966: cg@2006: "/ (imageEditView resourceClass == aClass cg@2006: "/ and:[ imageEditView resourceSelector == aSelector ]) ifTrue:[ cg@2006: "/ imageEditView modified ifFalse:[ cg@2006: "/ ^ self. cg@2006: "/ ]. cg@2006: "/ ]. cg@1969: cg@1975: (imageEditView loadFromClass:aClass andSelector:aSelector) notNil ifTrue:[ cg@1966: self updateAfterImageChange. cg@2006: self clearModified. cg@1966: ] cg@1975: cg@1975: "Modified: / 16.3.1999 / 21:44:41 / cg" cg@1966: ! cg@1966: cg@2339: loadFromFile:aFileName tz@767: "loads an image from aFileName and sets up color map list and other info labels" tz@767: cg@980: self withCursor:Cursor wait do:[ cg@980: (imageEditView loadFromFile: aFileName) notNil ifTrue:[ cg@1966: self updateAfterImageChange tz@767: ] tz@767: ] cg@960: cg@1057: "Modified: / 16.3.1999 / 21:44:26 / cg" tz@767: ! tz@767: cg@960: loadFromImage:anImage tz@767: "loads an image from anImage and sets up color map list and other info labels" tz@767: cg@1376: |img| cg@1376: cg@1057: anImage notNil ifTrue:[ cg@1376: img := anImage onDevice:device. cg@1376: ]. cg@1376: cg@1376: imageEditView image:img. cg@1799: imageEditView clearModified. cg@1376: cg@1966: self updateAfterImageChange. cg@1966: "/ img notNil ifTrue:[ cg@1966: "/ self updateColorsFromImage:img. cg@1966: "/ self findColorMapMode. cg@1966: "/ self updateLabelsAndHistory. cg@1966: "/ ] ifFalse:[ cg@1966: "/ self updateForNoImage cg@1966: "/ ] cg@960: cg@1057: "Modified: / 16.3.1999 / 21:43:56 / cg" tz@767: ! tz@767: cg@1975: loadFromOrPrepareForClass: aClass andSelector: aSelector tz@767: "loads an image by evaluating aMessage; tz@767: if no image could extract from aMessage; do set the class and the selector from tz@767: the aMessage for a saving at the end of editing" tz@767: cg@1975: (imageEditView loadFromClass:aClass andSelector:aSelector) notNil ifTrue: [ cg@1900: self updateColorsFromImage:self image. tz@767: self findColorMapMode. cg@1376: ] ifFalse: [ cg@1975: imageEditView resourceClass: aClass. cg@1975: imageEditView resourceSelector:aSelector. tz@767: ]. tz@767: self updateLabelsAndHistory. cg@1057: cg@1057: "Modified: / 16.3.1999 / 21:45:07 / cg" tz@767: ! ! tz@767: tz@400: !ImageEditor methodsFor:'menu modes'! tz@400: tz@975: colorMapMode cg@1847: "returns the colorMapMode" tz@400: tz@975: colorMapMode isNil ifTrue: [colorMapMode := '' asValue]. tz@400: tz@975: ^colorMapMode tz@400: ! tz@400: tz@975: editMode tz@975: "returns editMode" tz@400: cg@1054: editMode isNil ifTrue: [ tz@975: editMode := #point asValue. cg@1329: editMode onChangeEvaluate:[imageEditView editMode:(editMode value)] tz@975: ]. tz@975: tz@975: ^editMode tz@400: ! tz@400: tz@975: mouseKeyColorMode tz@975: "returns mouseKeyColorMode" tz@400: cg@1345: mouseKeyColorMode isNil ifTrue:[ tz@975: mouseKeyColorMode := 1 asValue. cg@1345: mouseKeyColorMode onChangeEvaluate: [ cg@1345: imageEditView mouseKeyColorMode:mouseKeyColorMode value. cg@3195: self selectedColors value:{ self listOfColors indexOf:imageEditView selectedColor }. cg@1345: ] ca@956: ]. tz@400: tz@975: ^mouseKeyColorMode cg@1345: cg@1345: "Modified: / 10.2.2000 / 23:16:42 / cg" tz@400: ! ! tz@400: cg@1558: !ImageEditor methodsFor:'private'! cg@1558: cg@1975: checkModified cg@1975: imageEditView modified value ifTrue:[ cg@1975: (Dialog cg@1975: confirm:(resources string:'Image was not saved. Proceed anyway ?') cg@1975: yesLabel:(resources string:'Proceed') cg@1975: noLabel:(resources string:'Cancel') cg@1975: initialAnswer:false cg@1975: ) ifFalse: [^false]. cg@1975: cg@1975: imageEditView clearModified. cg@1975: ]. cg@1975: ^ true cg@1975: cg@1975: "Modified: / 29.7.1998 / 18:55:24 / cg" cg@1975: ! cg@1975: cg@1960: pointFromString:aString cg@1960: |p s x y| cg@1960: cg@1960: p := Object readFromString:aString onError:nil. cg@1962: p isPoint ifTrue:[^ p]. cg@1960: cg@1960: s := aString readStream. cg@1960: x := Number readFrom:s onError:nil. cg@1960: x notNil ifTrue:[ cg@1960: s skipSeparators. cg@1962: [s atEnd not and:[s peek isDigit not]] whileTrue:[s next]. cg@1960: y := Number readFrom:s onError:nil. cg@1961: ^ x @ (y ? x) cg@1960: ]. cg@1962: ^ nil cg@1960: ! cg@1960: cg@1939: sortBlockForColors cg@3195: ^ self sortBlockForColorsByHLS. cg@3195: "/ ^ self sortBlockForColorsByRGB cg@3195: ! cg@3195: cg@3195: sortBlockForColorsByHLS cg@3195: ^ [:a :b | cg@3195: |h1 h2 s1 s2 l1 l2| cg@3195: cg@3195: h1 := a hue ? 0. cg@3195: h2 := b hue ? 0. cg@3195: (h1 between: h2-30 and:h2+30) ifTrue:[ cg@3195: l1 := a light. cg@3195: l2 := b light. cg@3195: l1 = l2 ifTrue:[ cg@3195: a saturation < b saturation cg@3195: ] ifFalse:[ cg@3195: l1 < l2 cg@3195: ]. cg@3195: "/ s1 := a saturation. cg@3195: "/ s2 := b saturation. cg@3195: "/ s1 = s2 ifTrue:[ cg@3195: "/ a light < b light cg@3195: "/ ] ifFalse:[ cg@3195: "/ s1 < s2 cg@3195: "/ ] cg@3195: ] ifFalse:[ cg@3195: h1 < h2 cg@3195: ] cg@3195: ] cg@3195: ! cg@3195: cg@3195: sortBlockForColorsByRGB cg@1939: ^ [:a :b | cg@1939: a redByte == b redByte ifTrue:[ cg@1939: a greenByte == b greenByte ifTrue:[ cg@1939: a blueByte < b blueByte cg@1939: ] ifFalse:[ cg@1939: a greenByte < b greenByte cg@1939: ] cg@1939: ] ifFalse:[ cg@1939: a redByte < b redByte cg@1939: ] cg@1939: ] cg@1939: ! cg@1939: cg@1598: updateImage cg@1598: |img| cg@1598: cg@1598: img := imageEditView image. cg@1598: imageEditView image:img. cg@1598: self fetchImageData. cg@1598: ! cg@1598: cg@1558: updateImagePreView cg@1558: self tileModeHolder value ifTrue:[ cg@1558: self imagePreView tileMode:true tileOffset:(self image extent). cg@1923: ]. cg@3253: self imagePreView cg@3253: setImage:(self image) scroll:false invalidate:false; "/ true. cg@3253: invalidate. cg@1558: ! ! cg@1558: tz@535: !ImageEditor methodsFor:'queries'! tz@535: cg@2707: hasLastGrabScreenArea cg@2707: ^ [ lastGrabbedScreenArea notNil ] cg@2707: ! cg@2707: cg@960: hasMask cg@1847: ^ colorMapMode value notNil and:[colorMapMode value startsWith:'mask'] cg@960: cg@960: "Created: / 18.8.1998 / 17:17:38 / cg" cg@960: ! cg@960: cg@1975: modified cg@1975: ^ imageEditView modified cg@1975: ! cg@1975: cg@2006: modified:aBoolean cg@2006: super modified:aBoolean. cg@2006: imageEditView modified:aBoolean cg@2006: ! cg@2006: tz@535: preferredExtent tz@767: "returns the preferred extent" tz@535: sv@2423: ^ super preferredExtent max: (Screen current width//3)@(Screen current height//3.5) tz@535: ! ! tz@535: tz@400: !ImageEditor methodsFor:'selection'! tz@400: tz@400: magnification tz@767: "returns the magnification of the image" tz@400: tz@911: self imageEditView isNil ifTrue: [^1]. tz@911: ^imageEditView magnification x tz@400: ! tz@400: tz@400: magnification: aValue tz@767: "sets the magnification of the image" tz@400: tz@905: |magnification| tz@905: magnification := (aValue ? 1) asPoint. tz@911: (magnification = imageEditView magnification or: [magnification = (0@0)]) ifTrue: [^nil]. tz@911: imageEditView magnification: magnification tz@400: ! tz@400: tz@400: selectedColorIndex tz@767: "returns the index of the selected color" tz@400: tz@400: ^selectedColorIndex tz@400: ! tz@400: tz@400: selectedColorIndex: anIndex tz@767: "sets the index of the selected color" tz@400: cg@1054: |clr pixel| cg@1054: cg@1054: selectedColorIndex := anIndex. cg@2447: anIndex isNil ifTrue:[^ self]. cg@1054: clr := self listOfColors at:anIndex ifAbsent:nil. cg@1054: clr isNil ifTrue:[^ self]. cg@1054: cg@1075: pixel := anIndex - 1. cg@1054: (self listOfColors at:1) = Color noColor ifTrue:[ cg@1054: anIndex == 1 ifTrue:[ cg@1054: pixel := nil. "/ mask cg@1054: ] ifFalse:[ cg@1075: pixel := pixel - 1 cg@1054: ] cg@1054: ]. cg@1054: imageEditView selectedColorIndex:pixel. cg@1054: imageEditView selectedColor:clr. tz@400: ! ! tz@400: cg@1716: !ImageEditor methodsFor:'startup & release'! tz@400: cg@1640: closeDownViews cg@1644: builder notNil ifTrue:[ cg@1644: DefaultRelativeSizes := cg@1644: Array cg@1998: with:(builder componentAt:#mainPanel) relativeCorners cg@1644: with:(builder componentAt:#verticalPanel) relativeCorners. cg@1644: ]. cg@1640: super closeDownViews cg@1640: ! cg@1640: tz@400: closeRequest cg@2016: "asks for permission before closing" cg@2016: cg@2016: imageEditView checkModified ifTrue:[ cg@2016: super closeRequest cg@2016: ] tz@400: ! tz@400: cg@1980: commonPostBuild cg@1975: imageEditView undoImages addDependent:self. cg@1975: imageEditView imageInfoHolder:(self imageInfoHolder). cg@1975: imageEditView activityInfoHolder:(self activityInfoHolder). cg@1975: cg@1975: imageEditView clickInfoCallBack:[:button :point | cg@1975: |mouseButtonColorToolBar| cg@3170: button <= 2 ifTrue:[ cg@3170: mouseButtonColorToolBar := self componentAt:#MouseButtonColorToolBar. cg@3170: (mouseButtonColorToolBar itemAt:button) toggleIndication. cg@3170: mouseButtonColorToolBar do: [:i| i updateIndicators]. cg@3170: ]. cg@1975: ]. cg@1975: cg@1975: imageEditView addDependent:self. cg@1975: imageEditView modifiedHolder addDependent:self. cg@1975: cg@1640: DefaultRelativeSizes notNil ifTrue:[ cg@1998: (builder componentAt:#mainPanel) relativeCorners:DefaultRelativeSizes first. cg@1980: (builder componentAt:#verticalPanel) relativeCorners:DefaultRelativeSizes second. cg@1640: ]. cg@1995: cg@1996: "/ using masters infoHolder ? cg@1996: (builder aspectAt:#useAlienInfoLabelHolder) == true ifTrue:[ cg@1998: (builder componentAt:#mainPanel) layout bottomOffset:0. cg@1995: (builder componentAt:#infoBarSubSpec) beInvisible cg@1995: ] cg@1640: ! cg@1640: cg@1980: open cg@1980: "after opening, sets the masterApplication of the imageEditView to self" cg@1980: cg@1980: super open. cg@1980: cg@1980: imageEditView := (self componentAt: #imageEditView) subViews first. cg@1980: ! cg@1980: tz@400: postOpenWith:aBuilder tz@767: "after opening, sets the masterApplication of the imageEditView to self; tz@767: evaluate the postOpenAction" tz@400: cg@1921: postOpenAction value. tz@400: ca@1250: super postOpenWith:aBuilder. ca@1250: ca@1250: aBuilder keyboardProcessor menuBar:nil. cg@2339: self windowGroup addPreEventHook:self. tz@400: ! ! tz@400: cg@1715: !ImageEditor methodsFor:'user actions-colormap'! cg@919: cg@1053: addColorToColormap cg@1682: self addColorToColormap:(Color black) cg@1682: ! cg@1682: cg@1682: addColorToColormap:newColor cg@1643: |depth img cMap newColorMap newImage oldCListSize newMode listOfColors| cg@1053: cg@1053: img := self image. cg@1499: img isNil ifTrue:[ cg@1499: self warn:'No Image.'. cg@1499: ^ self cg@1499: ]. cg@1499: cg@1054: depth := img depth. cg@1053: cMap := img colorMap. cg@1054: cMap isNil ifTrue:[ cg@1643: drawingColormap isNil ifTrue:[ cg@1916: self information:(resources stringWithCRs:'Image has no colormap.\The shown colorMap is for drawing only.'). cg@1643: drawingColormap := OrderedCollection new. cg@1643: ]. cg@1682: drawingColormap add:newColor. cg@1643: self listOfColors contents:drawingColormap. cg@3195: self selectedColors value:{drawingColormap size}. cg@1643: "/ self warn:'Image has no colormap.\Change colorMap mode first.' withCRs. cg@1054: ^ self cg@1054: ]. cg@1054: cg@1583: ("(depth == 1)" false cg@1054: or:[cMap size == (1 bitShift:depth)]) ifTrue:[ cg@1054: depth >= 8 ifTrue:[ cg@1053: self warn:'No space for more colors in colormap.'. cg@1053: ^ self cg@1053: ]. cg@1916: (self confirm:(resources stringWithCRs:'No space for more colors in colormap.\Change depth ?')) cg@1053: ifFalse:[ cg@1053: ^ self cg@1057: ]. cg@1057: cg@1057: imageEditView makeUndo. cg@1847: img mask notNil ifTrue:[ cg@1847: newMode := 'masked' , (depth*2) printString. cg@1847: ] ifFalse:[ cg@1847: newMode := 'depth' , (depth*2) printString. cg@1847: ]. cg@1057: self colorMapMode:newMode. cg@1057: ] ifFalse:[ cg@1057: imageEditView makeUndo. cg@1053: ]. cg@1054: cg@1054: cMap := cMap asArray. cg@1643: listOfColors := self listOfColors. cg@1643: oldCListSize := listOfColors size. cg@1054: cg@1682: newColorMap := cMap copyWith:newColor. cg@1054: cg@1054: newImage := img species new cg@1054: width:img width cg@1054: height:img height cg@1054: depth:depth cg@1054: fromArray:img bits. cg@1054: cg@1054: newImage colorMap:newColorMap. cg@1054: newImage fileName:img fileName. cg@1054: newImage mask:(img mask copy). cg@1054: cg@1054: (imageEditView image:newImage) notNil ifTrue:[ cg@1643: listOfColors contents: newImage colorMap. cg@1054: self findColorMapMode. cg@1054: "/ mhmh - somehow, we get two colors added ... (sigh findColorMapMode adds another one ...) cg@1643: listOfColors size > (oldCListSize + 1) ifTrue:[ cg@1643: listOfColors removeLast cg@1054: ]. cg@3195: self selectedColors value:{listOfColors size}. cg@1054: self updateLabelsAndHistory. cg@1054: ] cg@1053: cg@1053: "Created: / 12.3.1999 / 00:20:28 / cg" cg@1057: "Modified: / 16.3.1999 / 21:57:26 / cg" cg@1053: ! cg@1053: cg@1650: changeHLS cg@1650: "interactive Hue/Light/Saturation editing" cg@1650: cg@1650: |bindings hueShift lightValue saturationValue originalColormap firstChange acceptChannel cg@1923: shiftAction avgColorHolder avgColor shiftedColor shiftProcess readySema cg@2438: originalPixels p previewImage previewImageHolder originalPreviewColormap originalPreviewPixels cg@2438: anyChange | cg@1652: cg@1741: "/ compute the averageColor in the background (while asking user) cg@2438: avgColorHolder := nil asValue. cg@2438: previewImageHolder := nil asValue. cg@2438: cg@1652: readySema := Semaphore new. cg@1652: [ cg@1923: |image| cg@1923: cg@1923: image := imageEditView image. cg@1923: originalColormap := image colorMap copy. cg@2438: originalPixels := image bits. cg@1923: avgColor := image averageColor. cg@2438: avgColorHolder value:avgColor. cg@2438: cg@2438: previewImage := self image magnifiedPreservingRatioTo:100@100. cg@2438: previewImageHolder value: previewImage. cg@2438: originalPreviewColormap := previewImage colorMap copy. cg@2438: originalPreviewPixels := previewImage bits. cg@2438: cg@1652: readySema signal. cg@1652: ] forkAt:7. cg@1649: cg@1649: acceptChannel := TriggerValue new. cg@1649: cg@1649: firstChange := true. cg@2438: anyChange := false. cg@1649: cg@1651: shiftedColor := [:clr :hShift :lFactor :sFactor | cg@1651: Color cg@1651: hue:((clr hue) ? 0 + hShift) cg@3172: light:((clr light * lFactor / 100) min:100) cg@3172: saturation:((clr saturation * sFactor / 100) min:100)]. cg@1652: cg@1649: shiftAction := cg@1649: [ cg@1650: |hShift lFactor sFactor| cg@1650: cg@1649: acceptChannel value:true. cg@1649: cg@1649: firstChange ifTrue:[ cg@1649: imageEditView makeUndo. cg@1649: firstChange := false. cg@2438: anyChange := true. cg@1649: ]. cg@1652: readySema notNil ifTrue:[readySema wait. readySema := nil]. cg@1650: cg@1650: hShift := hueShift value. cg@1650: lFactor := lightValue value. cg@1650: sFactor := saturationValue value. cg@1650: cg@1652: avgColorHolder value:(shiftedColor value:avgColor value:hShift value:lFactor value:sFactor). cg@1652: cg@2438: previewImage cg@2438: colorMap:originalPreviewColormap copy; cg@2438: bits:originalPreviewPixels copy; cg@2438: release; cg@2438: colorMapProcessing:[:clr | shiftedColor value:clr value:hShift value:lFactor value:sFactor]. cg@2438: previewImageHolder value:nil; value:previewImage. cg@2438: cg@1652: shiftProcess notNil ifTrue:[ cg@1652: shiftProcess terminate. cg@1652: shiftProcess waitUntilTerminated. cg@1652: shiftProcess := nil. cg@1652: ]. cg@1652: shiftProcess := cg@1652: [ cg@1652: [ cg@1656: imageEditView image cg@1656: colorMap:originalColormap copy; cg@1923: bits:originalPixels copy; cg@1923: release; cg@1656: colorMapProcessing:[:clr | shiftedColor value:clr value:hShift value:lFactor value:sFactor]. cg@1652: self updateImage. cg@1652: self updateInfoLabel. cg@1923: self updateImagePreView. cg@1652: ] ensure:[ shiftProcess := nil ]. cg@1652: ] forkAt:7. cg@1649: ]. cg@1649: cg@1649: bindings := IdentityDictionary new. cg@1650: bindings at:#hueShiftAmount put:(hueShift := 0 asValue). cg@1656: hueShift onChangeEvaluate:shiftAction. cg@1650: cg@1650: bindings at:#lightAmount put:(lightValue := 100 asValue). cg@1656: lightValue onChangeEvaluate:shiftAction. cg@1650: cg@1650: bindings at:#saturationAmount put:(saturationValue := 100 asValue). cg@1656: saturationValue onChangeEvaluate:shiftAction. cg@1650: cg@1649: bindings at:#acceptChannel put:acceptChannel. cg@1652: bindings at:#hlsColor put:avgColorHolder. cg@2438: bindings at:#previewImageHolder put:previewImageHolder. cg@1650: cg@1650: (self openDialogInterface:#changeHLSDialogSpec withBindings:bindings) cg@1649: ifFalse:[ cg@2438: anyChange ifTrue:[ cg@1649: imageEditView undo cg@1649: ] cg@1649: ]. cg@1923: cg@1923: (p := shiftProcess) notNil ifTrue:[ cg@1923: p waitUntilTerminated. cg@1923: ]. cg@2438: cg@2438: anyChange ifTrue:[ cg@2438: self updateImage. cg@2438: self updateImagePreView. cg@2438: ]. cg@1649: ! cg@1649: cg@3195: changeHLSOfColors:colorsToShift cg@3195: "interactive Hue/Light/Saturation editing" cg@3195: cg@3195: |bindings hueShift lightValue saturationValue originalColormap firstChange acceptChannel cg@3195: shiftAction avgColorHolder avgColor shiftedColor shiftProcess readySema cg@3195: originalPixels p previewImage previewImageHolder originalPreviewColormap originalPreviewPixels cg@3195: anyChange | cg@3195: cg@3195: "/ compute the averageColor in the background (while asking user) cg@3195: avgColorHolder := nil asValue. cg@3195: previewImageHolder := nil asValue. cg@3195: cg@3195: readySema := Semaphore new. cg@3195: [ cg@3195: |image red green blue| cg@3195: cg@3195: image := imageEditView image. cg@3195: originalColormap := image colorMap copy. cg@3195: originalPixels := image bits. cg@3195: red := (colorsToShift collect:[:clr | clr red]) average. cg@3195: green := (colorsToShift collect:[:clr | clr green]) average. cg@3195: blue := (colorsToShift collect:[:clr | clr blue]) average. cg@3195: avgColor := Color red:red green:green blue:blue. cg@3195: avgColorHolder value:avgColor. cg@3195: cg@3195: previewImage := self image magnifiedPreservingRatioTo:100@100. cg@3195: previewImageHolder value: previewImage. cg@3195: originalPreviewColormap := previewImage colorMap copy. cg@3195: originalPreviewPixels := previewImage bits. cg@3195: cg@3195: readySema signal. cg@3195: ] forkAt:7. cg@3195: cg@3195: acceptChannel := TriggerValue new. cg@3195: cg@3195: firstChange := true. cg@3195: anyChange := false. cg@3195: cg@3195: shiftedColor := [:clr :hShift :lFactor :sFactor | cg@3195: Color cg@3195: hue:((clr hue) ? 0 + hShift) cg@3195: light:((clr light * lFactor / 100) min:100) cg@3195: saturation:((clr saturation * sFactor / 100) min:100)]. cg@3195: cg@3195: shiftAction := cg@3195: [ cg@3195: |hShift lFactor sFactor| cg@3195: cg@3195: acceptChannel value:true. cg@3195: cg@3195: firstChange ifTrue:[ cg@3195: imageEditView makeUndo. cg@3195: firstChange := false. cg@3195: anyChange := true. cg@3195: ]. cg@3195: readySema notNil ifTrue:[readySema wait. readySema := nil]. cg@3195: cg@3195: hShift := hueShift value. cg@3195: lFactor := lightValue value. cg@3195: sFactor := saturationValue value. cg@3195: cg@3195: avgColorHolder value:(shiftedColor value:avgColor value:hShift value:lFactor value:sFactor). cg@3195: cg@3195: previewImage cg@3195: colorMap:originalPreviewColormap copy; cg@3195: bits:originalPreviewPixels copy; cg@3195: release; cg@3195: colorMapProcessing:[:clr | cg@3195: (colorsToShift includes:clr) ifTrue:[ cg@3195: shiftedColor value:clr value:hShift value:lFactor value:sFactor. cg@3195: ] ifFalse:[ cg@3195: clr cg@3195: ] cg@3195: ]. cg@3195: previewImageHolder value:nil; value:previewImage. cg@3195: cg@3195: shiftProcess notNil ifTrue:[ cg@3195: shiftProcess terminate. cg@3195: shiftProcess waitUntilTerminated. cg@3195: shiftProcess := nil. cg@3195: ]. cg@3195: cg@3195: shiftProcess := cg@3195: [ cg@3195: [ cg@3195: imageEditView image cg@3195: colorMap:originalColormap copy; cg@3195: bits:originalPixels copy; cg@3195: release; cg@3195: colorMapProcessing:[:clr | cg@3195: (colorsToShift includes:clr) ifTrue:[ cg@3195: shiftedColor value:clr value:hShift value:lFactor value:sFactor. cg@3195: ] ifFalse:[ cg@3195: clr cg@3195: ] cg@3195: ]. cg@3195: self updateImage. cg@3195: self updateInfoLabel. cg@3195: self updateImagePreView. cg@3195: ] ensure:[ shiftProcess := nil ]. cg@3195: ] forkAt:7. cg@3195: ]. cg@3195: cg@3195: bindings := IdentityDictionary new. cg@3195: bindings at:#hueShiftAmount put:(hueShift := 0 asValue). cg@3195: hueShift onChangeEvaluate:shiftAction. cg@3195: cg@3195: bindings at:#lightAmount put:(lightValue := 100 asValue). cg@3195: lightValue onChangeEvaluate:shiftAction. cg@3195: cg@3195: bindings at:#saturationAmount put:(saturationValue := 100 asValue). cg@3195: saturationValue onChangeEvaluate:shiftAction. cg@3195: cg@3195: bindings at:#acceptChannel put:acceptChannel. cg@3195: bindings at:#hlsColor put:avgColorHolder. cg@3195: bindings at:#previewImageHolder put:previewImageHolder. cg@3195: cg@3195: (self openDialogInterface:#changeHLSDialogSpec withBindings:bindings) cg@3195: ifFalse:[ cg@3195: anyChange ifTrue:[ cg@3195: imageEditView undo cg@3195: ] cg@3195: ]. cg@3195: cg@3195: (p := shiftProcess) notNil ifTrue:[ cg@3195: p waitUntilTerminated. cg@3195: ]. cg@3195: cg@3195: anyChange ifTrue:[ cg@3195: self updateImage. cg@3195: self updateImagePreView. cg@3195: ]. cg@3195: ! cg@3195: cg@2652: clearColormapEntry0AndMaskedPixels cg@2652: "ensure that there is a colorMap entry with 0/0/0 at position cg@2652: 0 and then clear all masked pixels (to pixelValue 0). cg@2652: This is required for windows icons to be really transparent" cg@2652: cg@2652: |index colorMap| cg@2652: cg@2652: self compressColorMap. cg@2652: colorMap := self image colorMap. cg@2652: (colorMap includes:(Color black)) ifFalse:[ cg@2652: self addColorToColormap:(Color black). cg@2652: colorMap := self image colorMap. cg@2652: ]. cg@2652: index := colorMap indexOf:(Color black). cg@2652: index == 1 ifFalse:[ cg@2652: self sortColorMap. cg@2652: colorMap := self image colorMap. cg@2652: ]. cg@2652: self clearMaskedPixels cg@2652: ! cg@2652: cg@1403: clearMaskedPixels cg@1403: "clear all masked pixels (to pixelValue 0)" cg@1403: cg@2652: |newImage| cg@2652: cg@2652: newImage := self image clearMaskedPixels. cg@2652: 0 to:newImage height - 1 do:[:y | cg@2652: 0 to:newImage width - 1 do:[:x | cg@2652: (newImage maskAtX:x y:y) == 0 ifTrue:[ cg@2652: newImage pixelAtX:x y:y put:0 cg@1460: ] cg@1403: ] cg@2652: ]. cg@2652: cg@2652: (imageEditView image:newImage) notNil ifTrue:[ cg@2652: self fetchImageData. cg@1403: ] cg@1403: ! cg@1403: cg@945: colorMapChanged cg@945: |img| cg@945: cg@945: img := self image. cg@945: img release. cg@1376: cg@1376: self imageEditView invalidate. cg@960: self imagePreView invalidate. cg@960: cg@960: "/ (imageEditView image:img) notNil ifTrue:[ cg@960: "/ self updateLabelsAndHistory. cg@960: "/ self imagePreView image:img cg@960: "/ ] cg@945: cg@945: "Created: / 7.8.1998 / 22:26:10 / cg" cg@960: "Modified: / 18.8.1998 / 17:08:55 / cg" cg@945: ! cg@945: tz@975: colorMapMode:aMode cg@919: "calculates a new color map for the image from aMode" cg@919: cg@919: |depth numColors newColorMap newImage cg@919: oldImage image newColors realColorMap oldFileName cg@1008: usedColors useNearest usageCounts tmpBits tmpMap quest cg@1008: prevMode maskThreshold maskImage| cg@919: cg@919: self withExecuteCursorDo:[ cg@919: oldImage := self image. cg@919: cg@1053: prevMode := colorMapMode value. cg@1008: cg@919: newColorMap := self class listOfColorMaps at:aMode. cg@3230: (aMode == #depth32 or:[aMode == #masked32]) ifTrue:[ cg@2572: depth := 32. cg@2572: ] ifFalse:[ cg@3230: (aMode == #depth24 or:[aMode == #masked24]) ifTrue:[ cg@3230: depth := 24. cg@3230: ] ifFalse:[ cg@3370: (aMode == #depth16 or:[aMode == #masked16]) ifTrue:[ cg@3370: depth := 16. cg@3370: ] ifFalse:[ cg@3370: depth := (newColorMap size log:2) asInteger. cg@3370: ]. cg@3230: ]. cg@2572: ]. cg@919: cg@919: useNearest := false. cg@928: depth == 1 ifTrue:[ cg@928: quest := 'Keep colormap (or use standard B&W)' cg@928: ] ifFalse:[ cg@1008: prevMode isNil ifTrue:[ cg@1008: quest := 'Compute colormap (or use standard)' cg@1008: ] ifFalse:[ cg@1008: quest := 'Keep colormap (or use standard)' cg@1008: ] cg@928: ]. cg@1008: ((prevMode = aMode) cg@1057: or:[depth > oldImage depth cg@1057: or:[self confirm:(resources string:quest)]]) ifTrue:[ cg@1937: (newColorMap isOrderedCollection or:[newColorMap isFixedPalette not]) ifTrue:[ cg@1935: cg@1935: "/ keep the colormap cg@3355: "/ newColorMap atAllPut:Color black. cg@1935: depth > oldImage depth ifTrue:[ cg@1935: "/ easy - simply copy the part cg@1935: numColors := 1 bitShift:oldImage depth. cg@1935: 0 to:numColors-1 do:[:pixel | cg@1935: newColorMap at:(pixel+1) put:(oldImage colorFromValue:pixel) cg@1008: ]. cg@919: ] ifFalse:[ cg@1935: "/ see if all used color fit the new colormap cg@1935: usedColors := oldImage usedColorsMax:(1 bitShift:depth). cg@1935: (usedColors notNil and:[usedColors size > (1 bitShift:depth)]) ifTrue:[ cg@1935: usedColors := oldImage realUsedColors cg@1935: ]. cg@1935: (usedColors notNil and:[usedColors size <= (1 bitShift:depth)]) ifTrue:[ cg@1935: "/ yea - just install them cg@1935: usedColors asArray keysAndValuesDo:[:idx :clr | cg@1935: newColorMap at:idx put:clr cg@1935: ]. cg@919: ] ifFalse:[ cg@1935: "/ copy over those that are most often used. cg@1935: oldImage depth < 8 ifTrue:[ cg@1935: tmpBits := ByteArray uninitializedNew:(oldImage width*oldImage height). cg@1935: oldImage bits cg@1935: expandPixels:(oldImage depth) cg@1935: width:oldImage width cg@1935: height:oldImage height cg@1935: into:tmpBits cg@1935: mapping:nil. cg@986: ] ifFalse:[ cg@1935: oldImage depth == 8 ifTrue:[ cg@1935: tmpBits := oldImage bits cg@1935: ] ifFalse:[ cg@1935: colorMapMode value:prevMode. cg@1935: self findColorMapMode. cg@1935: self warn:('Too many used colors in image (', oldImage usedColors size printString , ').'). cg@1935: ^ self cg@1935: "/ (self confirm:('Too many used colors in image (', oldImage usedColors size printString , ').\\Dither ?' withCRs)) cg@1935: "/ ifFalse:[. cg@1935: "/ ^ self cg@1935: "/ ]. cg@1935: "/ self image: (Image newForDepth:depth) fromImage:oldImage. cg@1935: "/ ^ self. cg@1935: ] cg@1935: ]. cg@1935: usageCounts := tmpBits usageCounts. cg@1935: tmpMap := Array new:usageCounts size. cg@1935: oldImage colorMap asArray keysAndValuesDo:[:i :clr | cg@1935: tmpMap at:i put:clr cg@1935: ]. cg@1935: usageCounts sort:[:a :b | a > b] with:tmpMap. cg@1935: cg@1935: 1 to:(1 bitShift:depth) do:[:idx | cg@1935: newColorMap at:idx put:(tmpMap at:idx) cg@1935: ]. cg@1935: cg@1935: useNearest := Dialog cg@1935: confirmWithCancel:(resources cg@1935: stringWithCRs:'Image requires %1 colors.\ColorMap has only space for %2\\Use nearest (or map to first color) ?' cg@1935: with:usedColors size cg@1935: with:(1 bitShift:depth)) cg@1935: labels:(resources array:#('Cancel' 'First' 'Nearest')). cg@1935: useNearest isNil ifTrue:[ cg@1124: colorMapMode value:prevMode. cg@1935: ^ self "/ cancel cg@1935: ]. cg@1935: ] cg@919: ] cg@919: ] cg@919: ] ifFalse:[ cg@919: "/ standard colormap cg@921: usedColors := oldImage usedColors. cg@921: (usedColors conform:[:clr | newColorMap includes:clr]) ifFalse:[ cg@921: useNearest := Dialog cg@928: confirmWithCancel:(resources cg@1916: stringWithCRs:'Not all colors are present in the new colormap.\\Map missing ones to nearest (or map to first color) ?' cg@1916: ) cg@1542: labels:(resources string:#('Cancel' 'First' 'Nearest')). cg@921: useNearest isNil ifTrue:[ cg@1542: colorMapMode value:prevMode. cg@921: ^ self "/ cancel cg@921: ]. cg@921: ]. cg@3356: newColorMap := oldImage colorMap. cg@919: ]. cg@919: cg@919: imageEditView makeUndo. cg@919: cg@2260: newImage := Image newForDepth:depth. cg@1424: newImage depth:depth. cg@3230: depth >= 16 ifTrue:[ cg@3230: depth == 32 ifTrue:[ cg@3230: newImage colorMap:nil. cg@3230: newImage samplesPerPixel:4. cg@3230: newImage photometric:#rgba. cg@3230: ] ifFalse:[ cg@3230: newImage colorMap:nil. cg@3230: newImage samplesPerPixel:3. cg@3230: newImage photometric:#rgb. cg@3230: ]. cg@3230: ]. sv@3125: "/ newImage photometric:oldImage photometric. cg@2260: cg@919: oldFileName := oldImage fileName. cg@919: cg@1008: Image imageErrorSignal handle:[:ex| cg@3227: "/ arrive here only if not all colors can be represented; cg@3227: "/ then do a more expensive nearest color search cg@1008: Color colorErrorSignal handle:[:ex| cg@1542: colorMapMode value:prevMode. cg@919: imageEditView undo. cg@1008: ^ self warn:(resources string:'Conversion failed !!') cg@1008: ] do:[ cg@1393: newImage := Image newForDepth:depth. sv@3103: newImage sv@3103: width:oldImage width height:oldImage height depth:depth; sv@3103: colorMap:newColorMap; sv@3103: photometric:#palette; sv@3103: bits:(ByteArray new:(newImage bytesPerRow * newImage height)); sv@3103: mask:oldImage mask. cg@2260: cg@3227: oldImage cg@3227: colorsFromX:0 y:0 cg@3227: toX:(oldImage width-1) y:(oldImage height-1) cg@3227: do:[:x :y :clr | cg@3227: |newColor| cg@3227: cg@3227: (newColorMap includes:clr) cg@3227: ifTrue: [newColor := clr] cg@3227: ifFalse: [ cg@3227: newColor := clr nearestIn:newColorMap. cg@3227: useNearest ifFalse:[ cg@3227: (newColor deltaFrom:clr) > 0.5 ifTrue:[ cg@3227: newColor := oldImage colorFromValue:0 cg@3227: ] cg@1008: ] cg@3227: ]. cg@3227: newImage colorAtX:x y:y put:newColor. cg@3227: ]. cg@3227: cg@919: image := newImage cg@919: ]. cg@1008: ] do:[ cg@3356: image := newImage cg@3356: fromImage:oldImage cg@3370: photometric:((newColorMap notNil and:[newColorMap isOrderedCollection or:[newColorMap isFixedPalette not]]) cg@3356: ifTrue:[#palette] cg@3356: ifFalse:[nil]). cg@3356: "/ -- nope; keep the newly determined photometric. photometric:oldImage photometric. cg@919: ]. cg@919: cg@1847: (aMode asString startsWith:'mask') ifTrue:[ cg@1008: image mask isNil ifTrue:[ cg@1949: false "(Dialog confirm:'Generate mask from black ?' default:false)" ifTrue:[ cg@1008: maskThreshold := 0.1. cg@1008: maskImage := Depth1Image fromImage:(image asThresholdMonochromeImage:maskThreshold). cg@1008: ] ifFalse:[ sv@3122: maskImage := ImageMask extent:image extent. cg@1770: maskImage bits:(ByteArray cg@1008: new:(maskImage bytesPerRow * maskImage height) cg@1008: withAll:16rFF). cg@1008: cg@1008: "/ maskImage fillRectangle:(image bounds) withColor:(Color colorId:1). cg@1008: ]. cg@1008: image mask:maskImage. cg@919: ]. cg@1008: ] ifFalse:[ cg@919: image mask: nil. cg@3317: oldImage mask notNil ifTrue:[ cg@3317: newImage depth == 32 ifTrue:[ cg@3317: newImage computeAlphaValuesFromMask:oldImage mask cg@3317: ]. cg@3317: ]. cg@919: ]. cg@1935: cg@1937: (newColorMap isOrderedCollection or:[newColorMap isFixedPalette not]) ifTrue:[ cg@1935: realColorMap := OrderedCollection new. cg@1935: image realColorMap do:[:clr| cg@1935: (realColorMap includes: clr) ifFalse: [realColorMap add: clr] cg@1935: ]. cg@1935: newColors := realColorMap copyFrom: 1 to: (newColorMap size min: realColorMap size). cg@1935: newColorMap do:[:clr| cg@1935: ((newColors size < newColorMap size) and: [(newColors includes: clr) not]) cg@1935: ifTrue:[ cg@1935: newColors add: clr cg@1935: ] cg@1935: ]. cg@1935: image colorMap: newColors. cg@919: ]. cg@1446: image fileName: oldFileName. cg@919: cg@1054: (imageEditView image: image) notNil ifTrue:[ cg@1446: self fetchImageData. cg@919: ] cg@919: ] cg@919: cg@3356: "Modified: / 22-11-2016 / 03:44:00 / cg" cg@919: ! cg@919: cg@2192: colorize cg@2192: "interactive Hue editing" cg@2192: cg@2192: |bindings hueShift lightValue saturationValue originalColormap firstChange acceptChannel cg@2192: shiftAction avgColorHolder avgColor shiftedColor shiftProcess readySema cg@2192: originalPixels p| cg@2192: cg@2192: "/ compute the averageColor in the background (while asking user) cg@2192: readySema := Semaphore new. cg@2192: [ cg@2192: |image| cg@2192: cg@2192: image := imageEditView image. cg@2192: originalColormap := image colorMap copy. cg@2192: avgColor := image averageColor. cg@2192: originalPixels := image bits. cg@2192: readySema signal. cg@2192: ] forkAt:7. cg@2192: cg@2192: acceptChannel := TriggerValue new. cg@2192: avgColorHolder := avgColor asValue. cg@2192: cg@2192: firstChange := true. cg@2192: cg@2192: shiftedColor := [:clr :hShift :lFactor :sFactor | cg@2192: Color cg@2192: hue:((clr hue) ? 0 + hShift) cg@3173: light:((clr light * lFactor / 100) min:100) cg@3173: saturation:(((clr saturation max:20) * sFactor / 100) min:100)]. cg@2192: cg@2192: cg@2192: shiftAction := cg@2192: [ cg@2192: |hShift lFactor sFactor| cg@2192: cg@2192: acceptChannel value:true. cg@2192: cg@2192: firstChange ifTrue:[ cg@2192: imageEditView makeUndo. cg@2192: firstChange := false. cg@2192: ]. cg@2192: readySema notNil ifTrue:[readySema wait. readySema := nil]. cg@2192: cg@2192: hShift := hueShift value. cg@2192: lFactor := lightValue value. cg@2192: sFactor := saturationValue value. cg@2192: cg@2192: avgColorHolder value:(shiftedColor value:avgColor value:hShift value:lFactor value:sFactor). cg@2192: cg@2192: shiftProcess notNil ifTrue:[ cg@2192: shiftProcess terminate. cg@2192: shiftProcess waitUntilTerminated. cg@2192: shiftProcess := nil. cg@2192: ]. cg@2192: shiftProcess := cg@2192: [ cg@2192: [ cg@2192: imageEditView image cg@2192: colorMap:originalColormap copy; cg@2192: bits:originalPixels copy; cg@2192: release; cg@2192: colorMapProcessing:[:clr | shiftedColor value:clr value:hShift value:lFactor value:sFactor]. cg@2192: self updateImage. cg@2192: self updateInfoLabel. cg@2192: self updateImagePreView. cg@2192: ] ensure:[ shiftProcess := nil ]. cg@2192: ] forkAt:7. cg@2192: ]. cg@2192: cg@2192: bindings := IdentityDictionary new. cg@2192: bindings at:#hueShiftAmount put:(hueShift := 0 asValue). cg@2192: hueShift onChangeEvaluate:shiftAction. cg@2192: cg@2192: bindings at:#lightAmount put:(lightValue := 100 asValue). cg@2192: lightValue onChangeEvaluate:shiftAction. cg@2192: cg@2192: bindings at:#saturationAmount put:(saturationValue := 100 asValue). cg@2192: saturationValue onChangeEvaluate:shiftAction. cg@2192: cg@2192: bindings at:#acceptChannel put:acceptChannel. cg@2192: bindings at:#hlsColor put:avgColorHolder. cg@2192: cg@2192: (self openDialogInterface:#changeHLSDialogSpec withBindings:bindings) cg@2192: ifFalse:[ cg@2192: firstChange ~~ true ifTrue:[ cg@2192: imageEditView undo cg@2192: ] cg@2192: ]. cg@2192: cg@2192: (p := shiftProcess) notNil ifTrue:[ cg@2192: p waitUntilTerminated. cg@2192: ]. cg@2192: self updateImage. cg@2192: self updateImagePreView. cg@2192: cg@2192: "Created: / 01-11-2007 / 23:27:37 / cg" cg@2192: ! cg@2192: cg@919: compressColorMap cg@919: "calculates a new color map for the image, using only used colors" cg@919: sv@2893: |newImage| sv@2893: sv@2893: newImage := self image. sv@2893: newImage compressColorMap. cg@2652: cg@2652: (imageEditView image:newImage) notNil ifTrue:[ cg@2652: self fetchImageData. cg@919: ] cg@1008: ! cg@1008: cg@1852: copyColorFromColormap ca@1871: imageEditView setClipboardObject:(self selectedColorOrNil) cg@1852: ! cg@1852: cg@2054: ditherToDepth cg@2054: |depth| cg@2054: cg@2054: depth := Dialog request:'New depth ?'. cg@2054: depth isEmptyOrNil ifTrue:[^ self]. cg@2054: depth := Number readFrom:depth onError:nil. cg@2054: depth isNil ifTrue:[^ self]. cg@2054: cg@2054: self ditherToDepth:depth cg@2054: cg@2054: "Created: / 07-07-2006 / 13:22:10 / cg" cg@2054: ! cg@2054: cg@2054: ditherToDepth:depth sv@3331: |ditherColors newImage useStandardColors nGrey greyColorsAlready moreColors d| cg@2576: cg@2576: useStandardColors := true. cg@2576: "/ useStandardColors := Dialog confirmWithCancel:'Dither in standard colors or use a new (optimized) colormap ?'. cg@2576: "/ useStandardColors isNil ifTrue:[^ self]. cg@2576: cg@2576: useStandardColors ifTrue:[ cg@2576: depth = 1 ifTrue:[ cg@2576: ditherColors := Array with:(Color black) with:(Color white). cg@2576: ] ifFalse:[ depth = 2 ifTrue:[ cg@2576: ditherColors := Array cg@2576: with:(Color black) cg@3140: with:(Color darkGray) cg@3140: with:(Color lightGray) cg@2576: with:(Color white). cg@2576: ] ifFalse:[ depth = 3 ifTrue:[ cg@2576: ditherColors := Color colorCubeWithRed:2 green:2 blue:2. cg@2576: ] ifFalse:[ depth = 4 ifTrue:[ cg@2576: ditherColors := Color vgaColors. cg@2576: ] ifFalse:[ depth = 5 ifTrue:[ cg@2576: ditherColors := Color colorCubeWithRed:4 green:4 blue:2. cg@2576: ] ifFalse:[ depth = 6 ifTrue:[ cg@2576: ditherColors := Color colorCubeWithRed:4 green:4 blue:3. cg@2576: ] ifFalse:[ depth <= 8 ifTrue:[ cg@2576: ditherColors := Color colorCubeWithRed:6 green:6 blue:5. cg@2576: ] ifFalse:[ cg@2576: self error:'unsupported depth'. cg@2576: ]]]]]]]. cg@2576: cg@2576: nGrey := (2 raisedTo:depth) - ditherColors size. cg@2576: nGrey > 0 ifTrue:[ cg@2576: nGrey := nGrey min:128. cg@2576: greyColorsAlready := ditherColors select:[:clr | clr isGreyColor]. cg@2576: d := 1 / nGrey. cg@2576: moreColors := (1 to:nGrey-1) cg@2576: collect:[:i | Color brightness:(d * i)] cg@2576: thenReject:[:clr | greyColorsAlready includes:clr ]. cg@2576: cg@2576: ditherColors := ditherColors , moreColors. cg@2576: ]. cg@2576: ] ifFalse:[ cg@3020: self halt:'unhandled dither color setup'. cg@2576: ]. cg@2054: cg@2054: self withExecuteCursorDo:[ cg@2576: "/ newImage := self image asDitheredImageUsing:ditherColors depth:depth. cg@2054: newImage := self image asDitheredImageUsing:ditherColors depth:8. cg@2054: cg@2054: imageEditView makeUndo. cg@2054: imageEditView image:newImage. cg@2054: imageEditView setModified. cg@2054: self updateImage. cg@2054: self updateImagePreView. cg@2054: cg@2054: self fetchImageData. cg@2054: ]. cg@2054: cg@2054: "Created: / 07-07-2006 / 13:20:56 / cg" cg@2073: "Modified: / 05-09-2006 / 16:13:25 / cg" cg@2054: ! cg@2054: cg@2174: doubleClickOnColor:aColorIndex cg@2174: self editSelectedColor. cg@2174: cg@2174: "Created: / 22-07-2007 / 13:14:37 / cg" cg@2174: ! cg@2174: cg@1847: editSelectedColor cg@1847: self processSelectedColorWith:[:clr | cg@1847: |editor| cg@1847: cg@1847: editor := ColorEditDialog new. cg@1847: editor color:clr. cg@1847: editor open. cg@1847: editor accepted ifFalse:[ cg@1847: AbortOperationRequest raise. cg@1847: ]. cg@3180: editor color cg@1847: ] cg@1847: ! cg@1847: cg@1446: fetchImageData cg@1460: |image| cg@1460: cg@1460: (image := imageEditView image) notNil ifTrue:[ cg@1460: self findColorMapMode. cg@1460: self updateLabelsAndHistory. cg@1460: ] cg@1446: ! cg@1446: cg@1544: inspectColor cg@2573: |clrIndex clr| cg@2573: cg@2573: self hasColormap ifFalse:[ cg@2573: clr := self selectedColorOrNil cg@2573: ] ifTrue:[ cg@2573: clrIndex := self selectedColorIndexOrNil. cg@2573: clrIndex isNil ifTrue:[ cg@2573: ^ self cg@2573: ]. cg@2573: clr := self image colorFromValue:clrIndex-1 cg@1544: ]. cg@2573: clr inspect cg@1544: ! cg@1544: cg@2651: inspectColormap cg@2651: self hasColormap ifTrue:[ cg@2651: self image colorMap inspect cg@2651: ]. cg@2651: ! cg@2651: cg@1598: makeBrighter cg@1598: | anyChange| cg@1598: cg@1598: self withExecuteCursorDo:[ cg@1598: anyChange := imageEditView makeBrighter. cg@1598: anyChange ifFalse:[ cg@1598: Dialog warn:'Image unchanged'. cg@1598: ] ifTrue:[ cg@1598: self updateImage. cg@1598: ] cg@1598: ]. cg@1598: ! cg@1598: cg@1598: makeDarker cg@1598: | anyChange| cg@1598: cg@1598: self withExecuteCursorDo:[ cg@1598: anyChange := imageEditView makeDarker. cg@1598: anyChange ifFalse:[ cg@1598: Dialog warn:'Image unchanged'. cg@1598: ] ifTrue:[ cg@1598: self updateImage. cg@1598: ] cg@1598: ]. cg@1598: ! cg@1598: cg@1926: makeGrayScaleImage cg@1598: |anyChange| cg@1436: cg@1436: self withExecuteCursorDo:[ cg@1926: anyChange := imageEditView makeGrayScaleImage. cg@1436: anyChange ifFalse:[ cg@1436: Dialog warn:'Image unchanged'. cg@1436: ] ifTrue:[ cg@1598: self updateImage. cg@1598: ] cg@1598: ]. cg@1598: ! cg@1598: cg@1598: makeInverse cg@1598: | anyChange| cg@1598: cg@1598: self withExecuteCursorDo:[ cg@1598: anyChange := imageEditView makeInverse. cg@1598: anyChange ifFalse:[ cg@1598: Dialog warn:'Image unchanged'. cg@1598: ] ifTrue:[ cg@1598: self updateImage. cg@1436: ] cg@1436: ]. cg@1436: ! cg@1436: cg@1446: makeSelectedColorBrighter cg@3195: self processSelectedColorsWith:[:clr | clr lightened] cg@1446: ! cg@1446: cg@1446: makeSelectedColorDarker cg@3195: self processSelectedColorsWith:[:clr | clr darkened] cg@1446: ! cg@1446: cg@1884: makeSelectedColorGray cg@3195: self processSelectedColorsWith:[:clr | Color brightness:(clr brightness)] cg@3195: ! cg@3195: cg@3195: makeSelectedColorShifted cg@3195: |cMap colors| cg@3195: cg@3195: cMap := self image colorMap. cg@3195: self hasMask ifTrue:[ cg@3195: colors := self selectedColors value collect:[:idx | cMap at:idx-1]. cg@3195: ] ifFalse:[ cg@3195: colors := self selectedColors value collect:[:idx | cMap at:idx]. cg@3195: ]. cg@3195: self changeHLSOfColors:colors. cg@1884: ! cg@1884: cg@2826: makeSlightlyBrighter cg@2826: | anyChange| cg@2826: cg@2826: self withExecuteCursorDo:[ cg@2826: anyChange := imageEditView makeSlightlyBrighter. cg@2826: anyChange ifFalse:[ cg@2826: Dialog warn:'Image unchanged'. cg@2826: ] ifTrue:[ cg@2826: self updateImage. cg@2826: ] cg@2826: ]. cg@2826: cg@2826: "Created: / 24-11-2010 / 11:06:11 / cg" cg@2826: ! cg@2826: cg@2826: makeSlightlyDarker cg@2826: | anyChange| cg@2826: cg@2826: self withExecuteCursorDo:[ cg@2826: anyChange := imageEditView makeSlightlyDarker. cg@2826: anyChange ifFalse:[ cg@2826: Dialog warn:'Image unchanged'. cg@2826: ] ifTrue:[ cg@2826: self updateImage. cg@2826: ] cg@2826: ]. cg@2826: cg@2826: "Created: / 24-11-2010 / 11:06:23 / cg" cg@2826: ! cg@2826: cg@2652: menu_clearColormapEntry0AndMaskedPixels cg@2652: "ensure that there is a colorMap entry with 0/0/0 at position cg@2652: 0 and then clear all masked pixels (to pixelValue 0)" cg@2652: cg@2652: imageEditView makeUndo. cg@2652: self withExecuteCursorDo:[ cg@2652: self clearColormapEntry0AndMaskedPixels cg@2652: ] cg@2652: ! cg@2652: cg@2652: menu_clearMaskedPixels cg@2652: "clear all masked pixels (to pixelValue 0)" cg@2652: cg@2652: imageEditView makeUndo. cg@2652: cg@2652: self withExecuteCursorDo:[ cg@2652: self clearMaskedPixels cg@2652: ] cg@2652: ! cg@2652: cg@2652: menu_compressColorMap cg@2652: "calculates a new color map for the image, using only used colors" cg@2652: sv@2893: |depth oldImage usedColors colorMap| cg@2652: cg@2652: oldImage := self image. cg@2652: cg@2652: oldImage photometric ~~ #palette ifTrue:[ cg@2652: self information:'Compress colorMap: Only palette images have colormaps.'. cg@1852: ^ self cg@1852: ]. sv@2893: depth := oldImage depth. sv@3103: colorMap := oldImage colorMap asArray. cg@2652: usedColors := oldImage realUsedColors. sv@2893: usedColors size == colorMap size ifTrue:[ cg@2652: self information:'Compress colorMap: Colormap already compressed - no compression.'. cg@2652: ^ self cg@2652: ]. cg@2652: cg@2652: imageEditView makeUndo. cg@2652: cg@2652: self withExecuteCursorDo:[ cg@2652: self compressColorMap cg@1852: ] cg@1852: ! cg@1852: cg@2652: menu_copyMask cg@2652: |mask| cg@2652: cg@2652: mask := self image mask. cg@2652: MaskClipboard := mask subImageIn: (0@0 extent:mask extent). cg@2652: ! cg@2652: cg@2652: menu_pasteMask cg@1480: |img mask| cg@1480: cg@1480: imageEditView makeUndo. cg@1480: cg@1480: img := self image. cg@1480: mask := img mask. cg@1480: cg@1480: mask cg@1480: copyFrom:MaskClipboard cg@1480: x:0 y:0 cg@1480: toX:0 y:0 cg@1480: width:(mask width min:MaskClipboard width) cg@1480: height:(mask height min:MaskClipboard height). cg@1480: img mask:mask. cg@1480: (imageEditView image:img copy) notNil ifTrue:[ cg@1480: self fetchImageData. cg@1480: ] cg@1480: ! cg@1480: cg@2652: menu_sortColorMap cg@2652: "calculates a new color map for the image, sorting colors" cg@2652: cg@2652: self menu_sortColorMapWith:self sortBlockForColors cg@2652: ! cg@2652: cg@2652: menu_sortColorMapWith:sortBlock cg@2652: "calculates a new color map for the image, sorting colors" cg@2652: cg@2652: self image photometric ~~ #palette ifTrue:[ cg@2652: self information:'Compress colorMap: Only palette images have colormaps.'. cg@2652: ^ self cg@2652: ]. cg@2652: cg@2652: imageEditView makeUndo. cg@2652: cg@2652: self withExecuteCursorDo:[ cg@2652: self sortColorMapWith:sortBlock cg@2652: ] cg@2652: cg@2652: "Modified: / 15.9.1998 / 17:53:32 / cg" cg@2652: "Created: / 30.9.1998 / 23:51:23 / cg" cg@2652: ! cg@2652: cg@2652: pasteColorIntoColormap cg@2652: |copyBufferColor| cg@2652: cg@2652: copyBufferColor := imageEditView getClipboardObject. cg@2652: copyBufferColor isColor ifFalse:[ cg@2652: UserPreferences current beepInEditor ifTrue:[ cg@2652: self window beep. cg@2652: ]. cg@2652: ^ self cg@2652: ]. cg@2652: cg@2652: self processSelectedColorWith:[:clr | cg@2652: copyBufferColor cg@2652: ] cg@2652: ! cg@2652: cg@1682: pickAndAddColorToColormap cg@1682: self addColorToColormap:(Color fromUser) cg@1682: ! cg@1682: cg@1933: pickAndPasteColor cg@1933: self pickColor. cg@1933: self pasteColorIntoColormap. cg@1933: ! cg@1933: cg@1852: pickColor ca@1871: imageEditView setClipboardObject:(Color fromUser) cg@1852: ! cg@1852: cg@1682: processSelectedColorWith:aBlock cg@3195: "undoable color processing: cg@3195: the selected color will be replaced by the value of aBlock" cg@3195: cg@3195: self processSelectedColorsWith:aBlock. cg@3195: ! cg@3195: cg@3195: processSelectedColorsWith:aBlock cg@3195: "undoable color processing: cg@3195: the selected colors will be replaced by the value of aBlock cg@3195: (which gets a color vector and must return a color vector)" cg@3195: sv@3281: |img cMap modifiedColormap oldColors newImage selectedColorIndices newColors maskOffset| cg@3195: cg@3195: selectedColorIndices := self selectedColors value. cg@3195: selectedColorIndices isEmptyOrNil ifTrue:[^ self]. cg@1682: cg@1682: img := self image. cg@1682: cMap := img colorMap. cg@1682: cMap isNil ifTrue:[ cg@1916: self warn:(resources stringWithCRs:'Image has no colormap.\Please change the colorMap mode first.'). cg@1682: ^ self cg@1682: ]. cg@3195: self hasMask ifTrue:[ sv@3281: maskOffset := 1. cg@3195: ] ifFalse:[ sv@3281: maskOffset := 0. cg@3195: ]. sv@3281: oldColors := selectedColorIndices collect:[:idx | cMap at:idx-maskOffset]. cg@1682: imageEditView makeUndo. cg@1682: sv@2992: modifiedColormap := cMap asNewArray. cg@1852: cg@3195: newColors := oldColors collect:aBlock. cg@3195: selectedColorIndices with:newColors do:[:idx :newColor | sv@3281: modifiedColormap at:idx-maskOffset put:newColor cg@3195: ]. cg@1682: cg@1682: newImage := img species new cg@1682: width:img width cg@1682: height:img height cg@1843: depth:img depth cg@1682: fromArray:img bits. cg@1682: cg@1847: newImage colorMap:modifiedColormap. cg@1682: newImage fileName:img fileName. cg@1682: newImage mask:(img mask copy). cg@1682: cg@1682: (imageEditView image:newImage) notNil ifTrue:[ cg@1682: self fetchImageData. cg@1682: ]. cg@3195: self selectedColors value:selectedColorIndices. cg@1682: ! cg@1682: cg@1124: reduceNumberOfColors cg@1727: |s n anyChange img usedColors| cg@1124: cg@2817: s := Dialog request:'Number of color bits to strip (1-7) ?' initialAnswer:3. cg@1435: s size == 0 ifTrue:[^ self]. cg@1934: cg@1124: n := Integer readFrom:s onError:0. cg@1124: (n between:1 and:7) ifFalse:[ cg@1124: Dialog warn:'Image unchanged'. cg@1124: ^ self cg@1124: ]. cg@1124: cg@1124: self withExecuteCursorDo:[ cg@1124: anyChange := imageEditView reduceColorResolutionBy:n. cg@1124: anyChange ifFalse:[ cg@1124: Dialog warn:'Image unchanged'. cg@1124: ] ifTrue:[ cg@1124: img := imageEditView image. cg@1124: imageEditView image:img. cg@1446: cg@1446: self fetchImageData. cg@1727: usedColors := img usedColorsMax:10000. cg@1727: usedColors size == 10000 ifTrue:[ cg@1727: Dialog information:('>= ' , usedColors size printString , ' colors used.') cg@1727: ] ifFalse:[ cg@1727: Dialog information:(usedColors size printString , ' colors used.') cg@1727: ] cg@1124: ] cg@1124: ]. cg@2817: cg@2817: "Modified: / 29-10-2010 / 18:08:01 / cg" cg@1124: ! cg@1124: cg@1930: reduceNumberOfColors2 cg@1938: |s rndR rndG rndB usedColors image newImage| cg@1938: cg@1938: s := Dialog request:'Rounding Interval red (2..) ?' initialAnswer:4. cg@1934: s size == 0 ifTrue:[^ self]. cg@1938: rndR := Integer readFrom:s onError:0. cg@1939: cg@1938: s := Dialog request:'Rounding Interval green (2..) ?' initialAnswer:2. cg@1938: s size == 0 ifTrue:[^ self]. cg@1938: rndG := Integer readFrom:s onError:0. cg@1939: cg@1938: s := Dialog request:'Rounding Interval blue (2..) ?' initialAnswer:10. cg@1938: s size == 0 ifTrue:[^ self]. cg@1938: rndB := Integer readFrom:s onError:0. cg@1939: cg@1939: ((rndR > 1) or:[(rndG > 1) or:[(rndB > 1)]]) ifFalse:[ cg@1930: Dialog warn:'Image unchanged'. cg@1930: ^ self cg@1930: ]. cg@1930: cg@1930: self withExecuteCursorDo:[ cg@3195: |reduceColor| cg@3195: cg@3195: reduceColor := cg@3195: [:clr | cg@3195: |r g b nr ng nb| cg@1934: cg@1934: r := clr redByte. cg@1934: g := clr greenByte. cg@1934: b := clr blueByte. cg@1938: nr := (r roundTo:rndR) min:255. cg@1938: ng := (g roundTo:rndG) min:255. cg@1938: nb := (b roundTo:rndB) min:255. cg@1934: cg@3195: Color redByte:nr greenByte:ng blueByte:nb. cg@3195: ]. cg@3195: cg@3195: image := self image. cg@3195: "/ usedColors := image usedColorsMax:4096. cg@3195: imageEditView makeUndo. cg@3195: cg@3195: newImage := image copy. cg@3195: newImage photometric == #palette ifTrue:[ cg@3195: newImage colorMap:(image colorMap collect:reduceColor). cg@3195: ] ifFalse:[ cg@3195: image cg@3195: colorsFromX:0 y:0 toX:(image width-1) y:(image height-1) cg@3195: do:[:x :y :clr | cg@3195: newImage colorAtX:x y:y put:(reduceColor value:clr) cg@2260: ]. cg@3195: ]. cg@1934: imageEditView image:newImage. cg@1934: imageEditView setModified. cg@1934: self updateImage. cg@1934: self updateImagePreView. cg@1934: cg@1934: self fetchImageData. cg@1934: usedColors := newImage usedColorsMax:10000. cg@1934: usedColors size == 10000 ifTrue:[ cg@1934: Dialog information:('>= ' , usedColors size printString , ' colors used.') cg@1934: ] ifFalse:[ cg@1934: Dialog information:(usedColors size printString , ' colors used.') cg@1934: ] cg@1930: ]. cg@2054: cg@2054: "Modified: / 07-07-2006 / 13:10:42 / cg" cg@1930: ! cg@1930: cg@2446: selectColor:aColor cg@2446: |idx img cMap| cg@2446: cg@2446: aColor isNil ifTrue:[ cg@2446: idx := nil. cg@2446: ] ifFalse:[ cg@2791: img := self image. cg@2791: img notNil ifTrue: [ cg@2791: aColor == Color noColor ifTrue:[ cg@2791: (img mask notNil) ifTrue:[ cg@2791: idx := 1. cg@2791: ] cg@2791: ] ifFalse:[ cg@2447: (cMap := self listOfColors) notNil ifTrue:[ cg@2446: idx := cMap indexOf:aColor ifAbsent:nil. cg@2447: ]. cg@2447: idx isNil ifTrue:[ cg@2447: "/ should not happen... cg@2447: (cMap := img colorMap) notNil ifTrue:[ cg@2447: idx := cMap indexOf:aColor ifAbsent:nil. cg@2447: idx notNil ifTrue:[ cg@2447: img mask notNil ifTrue:[ cg@2447: idx := idx + 1. cg@2447: ]. cg@2447: ] cg@2446: ]. cg@2447: ]. cg@2446: ]. cg@2446: ]. cg@2446: ]. cg@3195: self selectedColors value:{idx}. cg@2790: cg@2791: "Modified: / 02-07-2010 / 12:06:07 / cg" cg@2446: ! cg@2446: cg@1682: selectedColorIndexOrNil cg@2651: |img clrIndex| cg@1682: cg@1682: img := self image. cg@1682: img isNil ifTrue:[ cg@2764: "/ self warn:'No Image.'. cg@1682: ^ nil cg@1682: ]. cg@1682: clrIndex := self selectionOfColor value. penk@1896: self hasMask "img mask notNil" ifTrue: [ cg@2449: (clrIndex isInteger and:[clrIndex > 1]) ifTrue:[ cg@2449: ^ clrIndex - 1 cg@2449: ]. cg@2449: ^ nil cg@1847: ]. cg@1682: ^ clrIndex cg@1682: ! cg@1682: cg@1852: selectedColorOrNil cg@2447: |cmapIndex img cMap colorList| penk@1896: penk@1896: cmapIndex := self selectedColorIndexOrNil. cg@1900: cmapIndex isNil ifTrue:[^ nil]. cg@2556: cmapIndex == 0 ifTrue:[^ nil]. cg@1852: cg@1852: img := self image. cg@1852: cMap := img colorMap. cg@1852: cMap isNil ifTrue:[ cg@2447: "/ self warn:(resources stringWithCRs:'Image has no colormap.\Please change the colorMap mode first.'). cg@2447: colorList := self listOfColors. cg@2447: colorList notNil ifTrue:[ cg@2447: ^ colorList at:cmapIndex ifAbsent:nil cg@2447: ]. cg@1900: ^ nil cg@1852: ]. penk@1896: ^ cMap at:cmapIndex. cg@1852: ! cg@1852: cg@1008: sortColorMap cg@1008: "calculates a new color map for the image, sorting colors" cg@1008: cg@3195: self sortColorMapWith:self sortBlockForColorsByRGB cg@1939: ! cg@1939: cg@1939: sortColorMapWith:sortBlock cg@1939: "calculates a new color map for the image, sorting colors" cg@1939: cg@3224: |depth newColorMap newImage oldImage usedColors oldToNew oldBits newBits tmpBits cg@3224: expectedSize w h| cg@1008: cg@1008: oldImage := self image. cg@1008: depth := oldImage depth. cg@3224: w := oldImage width. cg@3224: h := oldImage height. cg@1008: cg@2652: usedColors := oldImage realColorMap. cg@2652: cg@2652: "/ translation table cg@2652: oldToNew := ByteArray new:(1 bitShift:depth). cg@2652: newColorMap := usedColors asArray. cg@2652: newColorMap sort:sortBlock. cg@2652: cg@2652: oldImage colorMap asArray keysAndValuesDo:[:oldIdx :clr | cg@2652: |newPixel| cg@2652: cg@2652: (usedColors includes:clr) ifTrue:[ cg@2652: newPixel := newColorMap indexOf:clr. cg@2652: oldToNew at:oldIdx put:newPixel-1. cg@2652: ] cg@1008: ]. cg@1008: cg@2652: oldBits := oldImage bits. cg@3224: "/ sanity check... cg@3224: expectedSize := ((w * h * depth + 7) // 8). cg@3224: (oldBits size < expectedSize) ifTrue:[ cg@3224: self halt:'incorrect pixeldata size'. cg@3224: oldBits := (ByteArray new:expectedSize) replaceFrom:1 with:oldBits; yourself. cg@3224: ]. cg@2652: newBits := ByteArray new:(oldBits size). cg@2652: depth ~~ 8 ifTrue:[ cg@3224: cg@2652: "/ expand/compress can only handle 8bits cg@3224: tmpBits := ByteArray uninitializedNew:(w*h). cg@2652: oldBits cg@2652: expandPixels:depth cg@3224: width:w height:h cg@2652: into:tmpBits cg@2652: mapping:oldToNew. cg@2652: tmpBits cg@2652: compressPixels:depth cg@3224: width:w height:h cg@2652: into:newBits cg@2652: mapping:nil cg@2652: ] ifFalse:[ cg@2652: oldBits cg@2652: expandPixels:depth cg@3224: width:w height:h cg@2652: into:newBits cg@2652: mapping:oldToNew. cg@2652: ]. cg@2652: cg@2652: newImage := oldImage species new cg@3224: width:w height:h depth:depth cg@2652: fromArray:newBits. cg@2652: cg@2652: newImage colorMap:newColorMap. cg@2652: newImage fileName:oldImage fileName. cg@2652: newImage mask:(oldImage mask copy). cg@2652: cg@2652: (imageEditView image:newImage) notNil ifTrue:[ cg@2652: self fetchImageData. cg@1008: ] cg@1008: cg@1008: "Modified: / 15.9.1998 / 17:53:32 / cg" cg@1008: "Created: / 30.9.1998 / 23:51:23 / cg" cg@919: ! ! cg@919: cg@1715: !ImageEditor methodsFor:'user actions-editing'! tz@400: cg@2354: do3DProjection cg@2354: |box dx1 dx2 image| cg@2354: cg@2354: image := imageEditView image. cg@2354: cg@2354: box := EnterBox new. cg@2354: box title:(resources string:'dX1 (0 < dx < 0.5):'). cg@2354: box okText:(resources string:'OK'). cg@2354: box abortText:(resources string:'Cancel'). cg@2354: box initialText:'0.1'. cg@2354: box showAtPointer. cg@2354: cg@2354: (box accepted cg@2354: and: [(dx1 := Number readFrom:(box contents) onError:nil) notNil]) cg@2354: ifTrue:[ cg@2354: box title:(resources string:'dX2 (0 < dx < 0.5):'). cg@2354: box initialText:(dx1 printString). cg@2354: box showAtPointer. cg@2354: (box accepted cg@2354: and: [(dx2 := Number readFrom:(box contents) onError:nil) notNil]) cg@2354: ifTrue:[ cg@2354: imageEditView threeDProjection:dx1 and:dx2. cg@2354: ] cg@2354: ]. cg@2354: cg@2354: self updateInfoLabel cg@2354: ! cg@2354: cg@1882: doBrightenImage cg@1882: imageEditView brightenImage. cg@1882: self listOfColors removeAll. cg@1882: self findColorMapMode. cg@2585: "/ imageEditView removelastUndo cg@1882: ! cg@1882: tz@767: doBrowseClass tz@767: "opens a System Browser on the resourceClass and the resourceSelector" tz@400: cg@933: |cls| cg@933: cg@1965: cls := imageEditView resourceClass. cg@933: cls isNil ifTrue:[^ self warn:'No Class specified']. cg@1965: cg@3242: cls browserClass cg@933: openInClass:cls class cg@933: selector:(imageEditView resourceSelector) cg@933: cg@933: "Modified: / 31.7.1998 / 02:01:15 / cg" tz@400: ! tz@400: cg@1703: doCopyImageToClipboard cg@1703: imageEditView copyImageToClipboard. cg@1703: ! cg@1703: cg@1045: doCropAll cg@986: "find all borders and cut them off" cg@986: cg@1045: imageEditView cropLeft:true right:true top:true bottom:true. cg@986: self updateInfoLabel cg@986: cg@986: "Modified: / 7.9.1998 / 14:26:23 / cg" cg@986: "Created: / 7.9.1998 / 16:33:43 / cg" cg@986: ! cg@986: cg@1045: doCropBottom cg@986: "find a bottom border and cut it off" cg@986: cg@1045: imageEditView cropLeft:false right:false top:false bottom:true. cg@986: self updateInfoLabel cg@986: cg@986: "Created: / 7.9.1998 / 13:00:20 / cg" cg@986: "Modified: / 7.9.1998 / 14:26:23 / cg" cg@986: ! cg@986: cg@1045: doCropLeft cg@986: "find a left border and cut it off" cg@986: cg@1045: imageEditView cropLeft:true right:false top:false bottom:false. cg@986: self updateInfoLabel cg@986: cg@986: "Created: / 7.9.1998 / 13:00:14 / cg" cg@986: "Modified: / 7.9.1998 / 14:26:34 / cg" cg@986: ! cg@986: cg@1045: doCropManual cg@986: "let user specify borders and cut them off" cg@986: cg@1502: |bindings left top right bottom img firstChange gropAction acceptChannel| cg@1502: cg@1502: acceptChannel := TriggerValue new. cg@1490: cg@1490: firstChange := true. cg@1490: cg@1502: gropAction := cg@1502: [:lV :rV :tV :bV | |l r t b| cg@1502: acceptChannel value:true. cg@1502: cg@1502: l := lV value. cg@1502: r := rV value. cg@1502: t := tV value. cg@1502: b := bV value. cg@1502: (l + r + t + b) == 0 ifTrue:[ cg@2520: UserPreferences current beepInEditor ifTrue:[ cg@2520: self window beep cg@2520: ] cg@1502: ] ifFalse:[ cg@1502: img := imageEditView image. cg@1502: firstChange ifTrue:[ cg@1502: imageEditView makeUndo. cg@1502: firstChange := false. cg@1502: ]. cg@1502: imageEditView cg@1502: makeSubImageX:l y:t cg@1502: width:(img width - l - r) cg@1502: height:(img height - t - b). cg@2546: cg@2546: self updateImagePreView. cg@1502: self updateInfoLabel cg@1502: ]. cg@1490: ]. cg@986: cg@986: bindings := IdentityDictionary new. cg@1507: bindings at:#left put:(left := 1 asValue). cg@1507: bindings at:#right put:(right := 1 asValue). cg@1507: bindings at:#top put:(top := 1 asValue). cg@1507: bindings at:#bottom put:(bottom := 1 asValue). cg@1502: bindings at:#acceptChannel put:acceptChannel. cg@1502: cg@1502: bindings at:#gropLeftNow put:[ gropAction value:left value:0 value:0 value:0 ]. cg@1502: bindings at:#gropRightNow put:[ gropAction value:0 value:right value:0 value:0 ]. cg@1502: bindings at:#gropTopNow put:[ gropAction value:0 value:0 value:top value:0 ]. cg@1502: bindings at:#gropBottomNow put:[ gropAction value:0 value:0 value:0 value:bottom ]. cg@1502: cg@1502: bindings at:#applyAction put:[ gropAction value:left value:right value:top value:bottom ]. cg@1490: sv@1740: (self openDialogInterface:#cropDialogSpec withBindings:bindings) cg@1507: ifFalse:[ cg@1507: firstChange ~~ true ifTrue:[ cg@1558: imageEditView undo. cg@1558: self updateImagePreView. cg@1507: ] cg@1507: ]. cg@986: cg@986: "Created: / 7.9.1998 / 18:16:07 / cg" cg@986: "Modified: / 7.9.1998 / 18:20:42 / cg" cg@986: ! cg@986: cg@1045: doCropRight cg@986: "find a right border and cut it off" cg@986: cg@1045: imageEditView cropLeft:false right:true top:false bottom:false. cg@986: self updateInfoLabel cg@986: cg@986: "Created: / 7.9.1998 / 13:00:14 / cg" cg@986: "Modified: / 7.9.1998 / 14:26:44 / cg" cg@986: ! cg@986: cg@1045: doCropTop cg@986: "find a top border and cut it off" cg@986: cg@1045: imageEditView cropLeft:false right:false top:true bottom:false. cg@986: self updateInfoLabel cg@986: cg@986: "Created: / 7.9.1998 / 13:00:19 / cg" cg@986: "Modified: / 7.9.1998 / 14:26:52 / cg" cg@986: ! cg@986: cg@1882: doDarkenImage cg@1882: imageEditView darkenImage. cg@1882: self listOfColors removeAll. cg@1882: self findColorMapMode. cg@2585: "/ imageEditView removelastUndo cg@1882: ! cg@1882: martin@1433: doEditMask martin@1433: self image mask edit martin@1433: ! martin@1433: tz@767: doFlipHorizontal tz@767: "flips horizontally current image" tz@400: tz@911: imageEditView flipHorizontal tz@400: ! tz@400: tz@767: doFlipVertical tz@767: "flips vertically current image" tz@400: tz@911: imageEditView flipVertical tz@400: ! tz@400: cg@2196: doInsertTextFromUser cg@3157: |text tempForm tempImage maskImage font w h paintColor| cg@2196: cg@2424: text := Dialog request:'Text to be inserted (placed as bitmap into clipboard for paste):'. cg@2424: text isEmptyOrNil ifTrue:[^ self ]. cg@2196: cg@2196: font := Font family:'arial' size:20. cg@2196: font := font onDevice:Screen current. cg@2196: w := font widthOf:text. cg@2196: h := font heightOf:text. cg@2196: cg@2196: tempForm := Form extent:(w@h) depth:1 onDevice:(Screen current). cg@2196: tempForm clear. cg@2196: tempForm font:font. cg@2196: tempForm paint:(Color colorId:1). cg@2196: tempForm displayString:text at:(0@font ascent). cg@2196: cg@2196: tempImage := tempForm asImage. cg@2196: maskImage := tempForm asImage. cg@3157: cg@3157: paintColor := imageEditView selectedColor. cg@3157: paintColor colorId == 0 ifTrue:[ cg@3157: paintColor := Color black cg@3157: ]. cg@2196: tempImage cg@2196: photometric:#palette; cg@3157: colorMap:(Array cg@3157: with:Color white cg@3157: with:paintColor); cg@2196: mask:maskImage. cg@2196: cg@2196: ImageEditView copyImageToClipboard:tempImage. cg@2196: self editMode value:#paste. cg@2196: cg@2196: "Modified: / 11-11-2007 / 12:32:55 / cg" cg@2196: ! cg@2196: penk@1896: doInspectImage penk@1896: "opens a System Browser on the resourceClass and the resourceSelector" penk@1896: penk@1896: self image inspect penk@1896: ! penk@1896: tz@767: doMagnifyDown cg@1987: "magnifies the current image one step down" tz@400: cg@915: |magHolder mag| cg@915: cg@1987: magHolder := self magnificationHolder. cg@915: (mag := magHolder value) > 1 ifTrue: [ cg@915: magHolder value: mag - 1 tz@400: ] cg@915: cg@915: "Modified: / 26.7.1998 / 20:24:08 / cg" tz@400: ! tz@400: tz@767: doMagnifyImage cg@1479: "magnifies the current image to a new size" tz@400: cg@3196: |box newSize image antiAliased| cg@3196: cg@3196: antiAliased := false asValue. cg@1353: image := imageEditView image. cg@1353: cg@1353: box := EnterBox new. cg@1353: box title:(resources string:'Images new size:'). cg@1353: box okText:(resources string:'OK'). cg@1353: box abortText:(resources string:'Cancel'). cg@1353: box initialText:image extent printString. cg@3196: box addCheckBox:(resources string:'Antialiased') on:antiAliased. cg@1353: box showAtPointer. cg@3196: cg@1353: (box accepted cg@1960: and: [(newSize := self pointFromString:(box contents)) notNil]) cg@1353: ifTrue:[ cg@1479: newSize isPoint ifFalse:[ cg@3196: self warn:'Please enter the new size as ''x @ y''.'. cg@1479: ^ self. cg@1479: ]. cg@3196: antiAliased value ifTrue:[ cg@3196: imageEditView magnifyAntiAliasedImageTo:newSize. cg@3196: ] ifFalse:[ cg@3196: imageEditView magnifyImageTo:newSize. cg@3196: ]. cg@1479: ]. cg@1479: cg@1479: self updateInfoLabel cg@1479: ! cg@1479: cg@1479: doMagnifyImageBy cg@1479: "magnifies the current image (by a scale)" cg@1479: cg@3196: |oldSize newSize scaleString scale image antiAliased| cg@1479: cg@1479: image := imageEditView image. cg@1479: oldSize := image extent. cg@1479: cg@3196: antiAliased := false asValue. cg@3196: cg@3196: Dialog modifyingBoxWith:[:box | cg@3196: box addCheckBox:(resources string:'Antialiased') on:antiAliased. cg@3196: ] do:[ cg@3196: scaleString := Dialog cg@2260: request:(resources string:'Scale factor (<1 to shrink; >1 to magnify):') cg@2260: initialAnswer:'1' cg@2260: list:#('0.25' '0.5' '2' '4'). cg@3196: ]. cg@3196: scaleString isNil ifTrue:[^ self]. cg@2260: cg@2260: "/ box := EnterBox new. cg@2260: "/ box title:(resources string:'Scale factor (<1 to shrink; >1 to magnify):'). cg@2260: "/ box okText:(resources string:'OK'). cg@2260: "/ box abortText:(resources string:'Cancel'). cg@2260: "/ box initialText:1 printString. cg@2260: "/ box showAtPointer. cg@2260: "/ box accepted ifTrue:[ cg@2260: "/ scaleString := box contents. cg@2260: "/ ]. cg@2260: cg@2260: scale := Object readFromString:scaleString onError:nil. cg@2260: cg@2260: scale notNil ifTrue:[ cg@1479: scale isNumber ifFalse:[ cg@1479: self warn:'please enter a scale factor (<1 to shrink; >1 to magnify).'. cg@1479: ^ self. cg@1479: ]. cg@1479: newSize := oldSize * scale. cg@3196: antiAliased value ifTrue:[ cg@3196: imageEditView magnifyAntiAliasedImageTo:newSize. cg@3196: ] ifFalse:[ cg@3196: imageEditView magnifyImageTo:newSize. cg@3196: ]. cg@1353: ]. cg@1353: tz@400: self updateInfoLabel tz@400: ! tz@400: tz@767: doMagnifyUp cg@1987: "magnifies the current image one step up" tz@400: cg@915: |magHolder mag| cg@915: cg@1987: magHolder := self magnificationHolder. cg@3344: (mag := magHolder value) < 63 ifTrue: [ cg@915: magHolder value: mag + 1 tz@400: ] cg@915: cg@915: "Modified: / 26.7.1998 / 20:23:52 / cg" tz@400: ! tz@400: tz@767: doNegativeImage tz@767: "negates current image by negating the color map" tz@400: cg@1598: self image depth ~~ 1 ifTrue:[ cg@1598: Dialog warn:'Only useful for depth 1 images'. cg@1598: ^ self cg@1598: ]. tz@911: imageEditView negativeImage. tz@400: self listOfColors removeAll. tz@901: self findColorMapMode. cg@2585: "/ imageEditView removelastUndo tz@400: ! tz@400: tz@767: doResizeImage cg@1353: "resizes the current image" cg@1353: cg@1353: |box newSize image| cg@1353: cg@1353: image := imageEditView image. cg@1353: cg@1353: box := EnterBox new. cg@1353: box title:(resources string:'Images new size:'). cg@1353: box okText:(resources string:'OK'). cg@1353: box abortText:(resources string:'Cancel'). cg@1353: box initialText:image extent printString. cg@1353: box showAtPointer. cg@1353: (box accepted cg@1960: and: [(newSize := self pointFromString:(box contents)) notNil]) cg@1353: ifTrue:[ cg@1353: imageEditView resizeImageTo:newSize. cg@1353: ]. tz@400: ! tz@400: tz@767: doRotateImage tz@767: "rotates current image" tz@400: cg@2884: |rotationString box rotation| cg@2884: cg@2884: rotationString := Dialog cg@2884: request:(resources string:'Rotate by (degrees, clockwise):') cg@2884: list:#( '-90' '90' '180' '45' '-45' '135' '-135' ) cg@2884: initialAnswer:90. cg@2884: rotationString isEmptyOrNil ifTrue:[^ self]. "/ cancelled cg@2884: rotation := Number readFrom:rotationString onError:[nil]. cg@2884: rotation isNil ifTrue:[^ self]. cg@2884: cg@2884: "/ box := EnterBox new. cg@2884: "/ box title:(resources string:'Rotate by (degrees, clockwise):'). cg@2884: "/ box okText:(resources string:'OK'). cg@2884: "/ box abortText:(resources string:'Cancel'). cg@2884: "/ box initialText: '0'. cg@2884: "/ box showAtPointer. cg@2884: "/ (box accepted and: [(rotation := Number readFromString: box contents onError:nil) notNil]) cg@2884: "/ ifFalse:[ ^ self ]. cg@2884: cg@2884: imageEditView rotateImageBy:rotation. cg@2884: self updateInfoLabel. cg@2884: cg@2884: "Modified: / 18-03-2012 / 14:41:14 / cg" tz@400: ! tz@400: cg@1557: doShiftManual cg@1557: "let user specify amount and shift" cg@1557: cg@1713: |bindings amount img firstChange shiftAction acceptChannel wrapHolder| cg@1557: cg@1557: acceptChannel := TriggerValue new. cg@1960: wrapHolder := (lastShiftUsedWrap ? true) asValue. cg@1557: cg@1557: firstChange := true. cg@1557: cg@1557: shiftAction := cg@1557: [:shiftH :shiftV | cg@1557: acceptChannel value:true. cg@1557: cg@1557: img := imageEditView image. cg@1557: firstChange ifTrue:[ cg@1557: imageEditView makeUndo. cg@1557: firstChange := false. cg@1557: ]. cg@1713: imageEditView shiftImageHorizontal:(shiftH value) vertical:(shiftV value) wrap:(wrapHolder value). cg@1557: self updateInfoLabel cg@1557: ]. cg@1557: cg@1557: bindings := IdentityDictionary new. cg@1557: bindings at:#shiftAmount put:(amount := 1 asValue). cg@1713: bindings at:#wrap put:wrapHolder. cg@1557: bindings at:#acceptChannel put:acceptChannel. cg@1557: cg@1557: bindings at:#shiftLeftNow put:[ shiftAction value:(-1*amount value) value:0 ]. cg@1557: bindings at:#shiftRightNow put:[ shiftAction value:amount value value:0 ]. cg@1557: bindings at:#shiftUpNow put:[ shiftAction value:0 value:(-1*amount value) ]. cg@1557: bindings at:#shiftDownNow put:[ shiftAction value:0 value:amount value ]. cg@1557: cg@1557: (self openDialogInterface:#shiftDialogSpec withBindings:bindings) cg@1557: ifFalse:[ cg@1557: firstChange ~~ true ifTrue:[ cg@1557: imageEditView undo cg@1557: ] cg@1557: ]. cg@1960: lastShiftUsedWrap := wrapHolder value. cg@1557: cg@1557: "Created: / 7.9.1998 / 18:16:07 / cg" cg@1557: "Modified: / 7.9.1998 / 18:20:42 / cg" cg@1557: ! cg@1557: cg@1480: doUnCropManual cg@1480: "let user specify borders and add them" cg@1480: cg@1480: |bindings left top right bottom img| cg@1480: cg@1480: bindings := IdentityDictionary new. tm@1704: bindings at:#left put:(left := 1 asValue). tm@1704: bindings at:#right put:(right := 1 asValue). tm@1704: bindings at:#top put:(top := 1 asValue). tm@1704: bindings at:#bottom put:(bottom := 1 asValue). sv@1740: (self openDialogInterface:#uncropDialogSpec withBindings:bindings) cg@1480: ifTrue:[ cg@1480: left := left value. cg@1480: right := right value. cg@1480: top := top value. cg@1480: bottom := bottom value. cg@1480: img := imageEditView image. cg@1480: cg@1480: imageEditView cg@1480: makeBorderedImageX:left y:top cg@1480: width:(img width + left + right) cg@1480: height:(img height + top + bottom). cg@1480: self updateInfoLabel cg@1480: ]. cg@1480: cg@1480: "Created: / 7.9.1998 / 18:16:07 / cg" cg@1480: "Modified: / 7.9.1998 / 18:20:42 / cg" cg@1480: ! cg@1480: tz@767: doUndo tz@767: "reverses last edit action" tz@400: cg@1436: imageEditView undo. cg@3253: self updateImagePreView tz@400: ! ! tz@400: cg@2812: !ImageEditor methodsFor:'user actions-image sequences'! cg@2812: cg@2812: editEachImageFromSequence cg@2812: |seq| cg@2812: cg@2812: self checkModified ifFalse:[ ^ self ]. cg@2812: cg@2812: imageEditView releaseUndos. cg@2812: cg@2812: seq := self image imageSequence. cg@2812: seq size > 10 ifTrue:[ cg@2812: (Dialog confirm:(resources string:'Ok to open %1 image editor windows?' with:seq size)) cg@2812: ifFalse:[^ self]. cg@2812: ]. cg@2812: cg@2812: seq do:[:eachFrame | cg@2812: ImageEditor openOnImage:eachFrame image cg@2812: ]. cg@2812: cg@2812: "Modified: / 21-10-2010 / 15:01:25 / cg" cg@2812: ! cg@2812: cg@2812: gotoImageInSequence:index cg@2812: "display the next image in the image sequence" cg@2812: cg@2812: |img seq frame listOfColors| cg@2812: cg@2812: imageEditView releaseUndos. cg@2812: cg@2812: seq := self image imageSequence. cg@2812: cg@2812: imageSeqNr := index. cg@2812: frame := seq at:imageSeqNr. cg@2812: imageEditView image:(frame image). cg@2812: cg@2812: (img := self image) notNil ifTrue:[ cg@2812: listOfColors := self listOfColors. cg@2812: img colorMap notNil ifTrue:[ cg@2812: listOfColors contents:(img usedColors asSet asOrderedCollection). cg@2812: ] ifFalse:[ cg@2812: listOfColors removeAll. cg@2812: ]. cg@2812: self findColorMapMode. cg@2812: self updateLabelsAndHistory. cg@2812: img := img onDevice:device. cg@2812: imageEditView image:img. cg@2812: ] ifFalse:[ cg@2812: self updateForNoImage cg@2812: ]. cg@2812: cg@2812: "Created: / 21-10-2010 / 14:22:11 / cg" cg@2812: ! cg@2812: cg@2812: nextImageInSequence cg@2812: "display the next image in the image sequence" cg@2812: cg@2812: |seq index| cg@2812: cg@2812: seq := self image imageSequence. cg@2812: (index := imageSeqNr) isNil ifTrue:[ cg@2812: index := 1. cg@2812: ]. cg@2812: index := index + 1. cg@2812: index > seq size ifTrue:[ cg@2812: self information:'Back to first image in sequence'. cg@2812: index := 1. cg@2812: ]. cg@2812: self gotoImageInSequence:index. cg@2812: cg@2812: "Modified: / 21-10-2010 / 14:24:11 / cg" cg@2812: ! cg@2812: cg@2812: previousImageInSequence cg@2812: "display the previous image in the image sequence" cg@2812: cg@2812: |seq index| cg@2812: cg@2812: seq := self image imageSequence. cg@2812: (index := imageSeqNr) isNil ifTrue:[ cg@2812: index := 1. cg@2812: ]. cg@2812: index := index - 1. cg@2812: index < 1 ifTrue:[ cg@2812: self information:'Wrap to last image in sequence'. cg@2812: index := seq size. cg@2812: ]. cg@2812: self gotoImageInSequence:index. cg@2812: cg@2812: "Created: / 21-10-2010 / 14:25:03 / cg" cg@2812: ! ! cg@2812: cg@1715: !ImageEditor methodsFor:'user actions-loading'! tz@400: tz@767: doLoadFromClass tz@767: "opens a dialog for loading an image from class and a (resource-) selector" tz@400: cg@1122: |img| cg@1122: cg@1975: self checkModified ifFalse:[ ^ self ]. cg@1975: cg@1054: (imageEditView loadFromClass) notNil ifTrue:[ cg@1380: imageSeqNr := nil. cg@1122: (img := self image) notNil ifTrue: [ cg@1900: self updateColorsFromImage:img. tz@574: self findColorMapMode. cg@1376: self updateLabelsAndHistory. cg@1054: ] ifFalse: [ cg@1054: self updateForNoImage cg@1376: ]. tz@449: ] tz@400: ! tz@400: tz@767: doLoadFromFile tz@767: "opens a dialog for loading an image from a file" tz@400: cg@2820: |img file filters title| cg@1353: cg@1975: self checkModified ifFalse:[ ^ self ]. cg@1975: cg@1380: imageSeqNr := nil. cg@1353: img := self image. cg@1353: img notNil ifTrue: [ cg@1353: file := img fileName cg@1353: ]. cg@1353: cg@2820: title := (resources string:'Load Image From'). cg@2820: sv@3066: (UserPreferences current useNativeFileDialog cg@3100: and:[Screen current isWindowsPlatform]) ifTrue:[ cg@2820: self withWaitCursorDo:[ sv@3066: file := Screen current cg@2820: nativeFileDialogFor:(self window topView id) cg@2820: save:false cg@2820: title:title cg@2820: inDirectory:(file notNil ifTrue:[file asFilename directory pathName] ifFalse:[LastDirectory]) cg@2820: initialAnswer:(file notNil ifTrue:[file asFilename baseName] ifFalse:['image.png']) cg@2827: "/ flags:#( ENABLESIZING "HIDEREADONLY" EXPLORER NOCHANGEDIR) cg@2820: filter: cg@2820: { cg@2820: { (resources string:'Image Files') . '*.tif;*.png;*.gif;*.bmp;*.jpg' } . cg@2820: { (resources string:'All Files') . '*.*' } cg@2820: } cg@2821: extension:nil cg@2827: "blocking:false". cg@2820: ]. cg@2820: ] ifFalse:[ cg@2820: filters := FileSelectionBrowser loadImageFileNameFilters. cg@2820: file notNil ifTrue:[ cg@2820: file := FileSelectionBrowser cg@2820: request:title cg@2820: fileName:file cg@2820: withFileFilters:filters. cg@2820: ] ifFalse:[ cg@2820: file := FileSelectionBrowser cg@2820: request:title cg@2820: inDirectory:LastDirectory cg@2820: withFileFilters:filters. cg@2820: ]. cg@1353: ]. cg@2820: cg@1353: file notNil ifTrue:[ cg@1353: LastDirectory := file asFilename directoryName. cg@1353: self loadFromFile:file cg@1353: ] cg@2820: cg@2827: "Modified: / 14-12-2010 / 13:52:11 / cg" tz@400: ! tz@400: cg@2796: doLoadFromURL cg@2796: "opens a dialog for loading an image from a URL" cg@2796: cg@2866: |tempFile url response| cg@2796: cg@2796: self checkModified ifFalse:[ ^ self ]. cg@2796: cg@2796: url := Dialog cg@2866: request:(resources string:'Load Image from URL') cg@2796: initialAnswer:LastURL. cg@2796: cg@2796: url notEmptyOrNil ifTrue:[ cg@3050: HTTPInterface isNil ifTrue:[ Smalltalk loadPackage:'stx:goodies/communication']. cg@3050: cg@2796: LastURL := url. sv@3027: tempFile := FileStream newTemporary close fileName. cg@2866: self withWaitCursorDo:[ cg@2866: response := HTTPInterface get:url destinationFile:tempFile. cg@2866: ]. cg@2866: response isErrorResponse ifTrue:[ cg@2866: Dialog warn:(resources string:'Could not load image ("%1")' with:response responseText). cg@2866: ] ifFalse:[ cg@2866: self loadFromFile:tempFile. cg@2866: ]. cg@2796: tempFile delete cg@2796: ] cg@2796: cg@2796: "Created: / 20-09-2010 / 11:30:59 / cg" cg@2796: ! cg@2796: tz@767: doNewImage tz@767: "opens a dialog with choices of size and color map for creating a new image" tz@400: cg@1975: |dialogAspects width height cMapString cMapMode cMap imageClass image szString defaultSize ext| cg@1975: cg@1975: self checkModified ifFalse:[ ^ self ]. cg@1847: cg@1847: defaultSize := (self class listOfDefaultSizes includes:'32x32') cg@1847: ifTrue:['32x32'] cg@1847: ifFalse:[self class listOfDefaultSizes first]. tz@767: cg@1975: dialogAspects := IdentityDictionary new tz@767: at:#listOfSizes put: self class listOfDefaultSizes asValue; cg@1847: at:#listOfColorMaps put: self class namesOfColorMaps values asSortedCollection asValue; cg@1847: at:#selectionOfSize put: (LastSizeString ? defaultSize) asValue; cg@1847: at:#selectionOfColorMap put: (LastColormapMode ? self class namesOfColorMaps values asSortedCollection first) asValue; tz@400: yourself. tz@400: cg@1975: (self openDialogInterface:#dialogSpecForNewImage withBindings:dialogAspects) cg@1383: ifTrue:[ cg@1975: szString := (dialogAspects at:#selectionOfSize) value. cg@1960: ext := self pointFromString:szString. cg@1962: ext isNil ifTrue:[ cg@1962: width := height := 32 cg@1962: ] ifFalse:[ cg@1962: width := ext x. cg@1962: height := ext y. cg@1962: ]. cg@1960: "/ width := "128 min: "(Integer readFromString: (szString upTo: $x) onError:[32]). cg@1960: "/ height := "128 min: " (Integer readFromString: (szString copy reverse upTo: $x) reverse onError:[32]). tz@400: cg@1975: cMapString := (dialogAspects at:#selectionOfColorMap) value. cg@1847: cMapMode := self class namesOfColorMaps keyAtEqualValue:cMapString. cg@1847: cMap := self class listOfColorMaps at:cMapMode. cg@1847: imageClass := Image implementorForDepth:(cMap size highBit-1). cg@1847: image := imageClass width: width height: height. cg@1847: image bits:(ByteArray new:(image bytesPerRow*height)). tz@400: cg@1637: LastSizeString := szString. cg@1637: LastColormapMode := cMapString. cg@1637: cg@1847: (cMapMode startsWith: 'mask') ifTrue:[ sv@3125: image mask: (ImageMask width: width height: height depth: 1 fromArray: (ByteArray new: width*height)). tz@400: ]. tz@400: image colorMap: cMap. cg@1847: (imageEditView image: image) notNil ifTrue:[ cg@1847: self updateListOfColorsAndColormapMode. cg@1847: self updateLabelsAndHistory. cg@1847: ]. tz@400: image fillRectangleX:0 y:0 width:width height:height with:Color white. tz@767: ] cg@929: ! cg@929: cg@2058: doNewImageEditor cg@2058: "opens a new image editor" cg@2058: cg@2058: ImageEditor open cg@2058: cg@2058: "Created: / 17-08-2006 / 09:03:14 / cg" cg@2058: ! cg@2058: cg@1682: doNewImageFromClipboard cg@1682: |image| cg@1682: cg@1975: self checkModified ifFalse:[ ^ self ]. cg@1975: cg@1682: image := imageEditView clipBoard. cg@3164: image isImageOrForm ifFalse:[ cg@3164: image := Image readFrom:(image asString) onError:nil. cg@3164: image isNil ifTrue:[ cg@3164: Dialog warn:'Clipboard does not contain an image I can use/understand'. cg@3164: ^ self. cg@3164: ]. cg@3164: ]. cg@1975: imageEditView image:image. cg@1975: cg@1975: image notNil ifTrue:[ cg@1900: self updateColorsFromImage:image. cg@1682: self findColorMapMode. cg@1682: self updateLabelsAndHistory. cg@1682: ] cg@1682: ! cg@1682: cg@3200: doNewMaskFromClipboard cg@3200: |mask image newImage| cg@3200: cg@3200: self checkModified ifFalse:[ ^ self ]. cg@3200: cg@3200: mask := imageEditView clipBoard. cg@3200: mask isImageOrForm ifFalse:[ cg@3200: mask := Image readFrom:(mask asString) onError:nil. cg@3200: mask isNil ifTrue:[ cg@3200: Dialog warn:'Clipboard does not contain an image I can use/understand'. cg@3200: ^ self. cg@3200: ]. cg@3200: ]. cg@3200: (image:= imageEditView image) isNil ifTrue:[ cg@3200: image := mask. cg@3200: ]. cg@3200: mask extent ~= image extent ifTrue:[ cg@3200: mask := imageEditView resizedImage:mask to:image extent. cg@3200: ]. cg@3200: newImage := image copy. cg@3200: newImage mask:mask. cg@3200: imageEditView newImageWithUndo:newImage. cg@3200: self updateAfterImageChange. cg@3200: "/ self updateColorsFromImage:image. cg@3200: "/ self findColorMapMode. cg@3200: "/ self updateLabelsAndHistory. cg@3200: ! cg@3200: cg@929: grabScreenImage cg@929: "let user choose an area and grab that are for editing" cg@929: cg@2707: self grabScreenImageUsing:[ cg@2707: |r| cg@2707: cg@2707: [Screen current leftButtonPressed] whileTrue:[Delay waitForSeconds:0.05]. cg@2707: r := Rectangle fromUser. cg@2708: (r width == 0 or:[r height == 0]) ifTrue:[ cg@2708: nil cg@2708: ] ifFalse:[ cg@2708: lastGrabbedScreenArea := r. cg@2708: Image fromScreen:r cg@2708: ] cg@2707: ]. cg@2707: ! cg@2707: cg@2707: grabScreenImageFromLastArea cg@2707: "grab again from the previous area for editing" cg@2707: cg@2707: self grabScreenImageUsing:[ cg@2708: Image fromScreen:lastGrabbedScreenArea cg@2707: ]. cg@2701: ! cg@2701: cg@2701: grabScreenImageUsing:aBlock cg@2701: "let user choose an area and grab that are for editing" cg@2701: cg@1975: self checkModified ifFalse:[ ^ self ]. cg@1975: cg@990: Processor cg@990: addTimedBlock:[ cg@990: |image d8image img| cg@929: cg@1380: imageSeqNr := nil. cg@2701: image := aBlock value. cg@2708: image notNil ifTrue:[ cg@1121: image depth > 8 ifTrue:[ cg@2420: false ifTrue:[ sv@1687: Error handle:[:ex | |sig| cg@2996: (sig := ex creator) == HaltInterrupt ifTrue:[ex reject]. cg@1122: sig == Signal noHandlerSignal ifTrue:[ex reject]. cg@1121: cg@1121: self warn:'Could not convert to depth8 image (too many colors)'. cg@1121: d8image := nil. cg@1121: ] do:[ cg@2420: d8image := Depth8Image fromImage:image photometric:#palette. cg@1121: ]. cg@1121: d8image notNil ifTrue:[ cg@1121: image := d8image cg@1121: ] cg@2420: ]. cg@990: ]. cg@1121: (imageEditView image:image) notNil ifTrue:[ cg@1121: self listOfColors contents:(image colorMap). cg@1121: self findColorMapMode. cg@1121: self updateLabelsAndHistory. cg@990: ] cg@1121: ] cg@1121: ] cg@990: afterSeconds:1 cg@929: cg@929: "Created: / 29.7.1998 / 21:24:42 / cg" cg@1537: "Modified: / 16.11.2001 / 16:21:19 / cg" cg@1380: ! cg@1380: cg@2701: grabWindowImage cg@2701: "let user choose an area and grab that are for editing" cg@2701: cg@2701: self grabScreenImageUsing:[ cg@3188: |v topView| cg@2701: cg@2701: (v := Screen current viewFromUser) notNil ifTrue:[ cg@3188: topView := v topView. cg@3188: topView raise; makeFullyVisible. cg@2704: Delay waitForSeconds:0.5. "/ give view a chance to redraw itself. cg@3188: Image fromView:topView cg@2701: ]. cg@2701: ]. tz@400: ! ! tz@400: cg@1715: !ImageEditor methodsFor:'user actions-saving'! tz@400: tz@767: doPrint tz@767: "prints current image on the current printer" tz@400: cg@1734: self withWaitCursorDo:[ cg@1734: imageEditView print cg@1734: ] tz@400: ! tz@400: ca@1613: doSaveButtonImageToFileAs ca@1613: "opens a dialog for saving current image to a file" ca@1613: ca@1613: imageEditView saveButtonImageToFileAs. ca@1613: self updateLabelsAndHistory. ca@1613: ! ca@1613: tz@767: doSaveImageFile tz@767: "saves current image to current file" tz@400: cg@1481: imageEditView save. cg@2006: self clearModified. tz@400: ! tz@400: tz@767: doSaveImageFileAs cg@1922: "opens a dialog for saving an image to a file" cg@1922: cg@1922: |img file filters| cg@1922: cg@1922: img := self image. cg@1922: img notNil ifTrue: [ cg@1922: file := img fileName cg@1922: ]. cg@1922: cg@2595: filters := FileSelectionBrowser saveImageFileNameFilters. cg@1922: sv@3066: (UserPreferences current useNativeFileDialog cg@3100: and:[Screen current isWindowsPlatform]) ifTrue:[ cg@2820: self withWaitCursorDo:[ sv@3066: file := Screen current cg@2820: nativeFileDialogFor:(self window topView id) cg@2820: save:true cg@2820: title:(resources string:'Save Image To') cg@2820: inDirectory:(file notNil ifTrue:[file asFilename directory pathName] ifFalse:[LastDirectory]) cg@2820: initialAnswer:(file notNil ifTrue:[file asFilename baseName] ifFalse:['image.png']) cg@2827: "/ flags:#( ENABLESIZING "HIDEREADONLY" EXPLORER NOCHANGEDIR) cg@2820: filter: cg@2820: { cg@2820: { (resources string:'Image Files') . '*.tif;*.png;*.gif;*.bmp' } . cg@2820: { (resources string:'All Files') . '*.*' } cg@2820: } cg@2821: extension:nil cg@2827: "blocking:false". cg@2807: ]. cg@2820: ] ifFalse:[ cg@2820: (FileSelectionBrowser isNil or:[DirectoryView isNil]) ifTrue:[ cg@2820: file notNil ifTrue:[ cg@2820: file := Dialog requestFileName:'Save Image To' cg@2820: default:file cg@2820: pattern:(filters first). cg@2820: ] ifFalse:[ cg@2820: file := Dialog cg@2820: requestFileName:'Save Image To' cg@2820: default:'image.png' cg@2820: pattern:(filters first) cg@2820: fromDirectory:LastDirectory. cg@2820: ]. cg@2807: ] ifFalse:[ cg@2820: file notNil ifTrue:[ cg@2820: file := FileSelectionBrowser cg@2820: request:'Save Image To' cg@2820: fileName:file cg@2820: withFileFilters:filters. cg@2820: ] ifFalse:[ cg@2820: file := FileSelectionBrowser cg@2820: request:'Save Image To' cg@2820: inDirectory:LastDirectory cg@2820: withFileFilters:filters. cg@2820: ]. cg@2807: ]. cg@1922: ]. cg@1922: file notNil ifTrue:[ cg@1922: imageEditView saveImageFileAs:file. cg@1922: LastDirectory := file asFilename directoryName. cg@1922: self updateLabelsAndHistory. cg@2006: self clearModified. cg@1922: ] cg@2807: cg@2827: "Modified: / 14-12-2010 / 13:51:47 / cg" tz@400: ! tz@400: tz@767: doSaveImageMaskFileAs tz@767: "opens a dialog for saving mask of current image to a file" tz@400: cg@1481: imageEditView saveImageMaskFileAs. tz@400: ! tz@400: tz@767: doSaveMethod cg@1975: "saves the image in current class and selector" cg@1975: cg@1975: imageEditView saveMethod ifTrue:[ cg@2006: self updateLabelsAndHistory. cg@2006: self clearModified. tz@400: ] tz@400: ! tz@400: tz@767: doSaveMethodAs tz@767: "opens a dialog for saving current image on a class and a selector" tz@400: cg@1975: imageEditView saveMethodAs ifTrue:[ cg@2006: self updateLabelsAndHistory. cg@2006: self clearModified. tz@400: ] cg@1309: ! cg@1309: cg@3022: doShowPixelArrayLiteralString cg@3022: "opens a dialog showing a literal array-like storeString cg@3022: (sometimes useful to embed an image into source code)" cg@3022: cg@3022: |img| cg@3022: cg@3022: img := imageEditView image. cg@3022: TextBox openOn:img bits storeString cg@3022: ! cg@3022: cg@1309: doShowStoreString cg@1309: "opens a dialog showing the storeString cg@1309: (sometimes useful to embed an image into source code)" cg@1309: cg@1309: |img| cg@1309: cg@1309: img := imageEditView image. cg@1309: TextBox openOn:img storeString cg@1975: ! cg@1975: cg@1975: save cg@1975: "saves current image on current class and selector" cg@1975: cg@1975: self doSaveMethod tz@400: ! ! tz@400: cg@1715: !ImageEditor methodsFor:'user actions-settings'! cg@1353: cg@1353: doChangeGridMagnification cg@1353: "change grid magnification" cg@1353: cg@1353: |box oldGridLimit newGridLimit| cg@1353: cg@1353: oldGridLimit := imageEditView class gridMagnificationLimit asPoint. cg@1353: cg@1353: box := EnterBox new. cg@1353: box title:(resources string:'Grid Magnification Limit:'). cg@1353: box okText:(resources string:'OK'). cg@1353: box abortText:(resources string:'Cancel'). cg@1353: box initialText:(oldGridLimit x printString). cg@1353: box showAtPointer. cg@1353: cg@1353: (box accepted cg@1353: and: [(newGridLimit := Number readFromString:(box contents) onError:[2]) notNil] cg@1353: ) ifTrue:[ cg@1353: newGridLimit := (99 min: (2 max:newGridLimit)) asPoint. cg@1353: imageEditView class gridMagnificationLimit:newGridLimit. cg@1353: imageEditView invalidate cg@1353: ] cg@1353: cg@2192: ! cg@2192: cg@2192: penWidth:n cg@2192: imageEditView penWidth:n cg@2192: cg@2192: "Created: / 01-11-2007 / 23:47:48 / cg" cg@2375: ! cg@2375: cg@2881: penWidthHolderChanged cg@2881: imageEditView penWidth:(self penWidthHolder value) cg@2881: cg@2881: "Created: / 15-02-2012 / 22:32:00 / cg" cg@2881: ! cg@2881: cg@2375: spraySpot:n cg@2375: imageEditView spraySpot:n cg@2375: cg@2375: "Created: / 01-11-2007 / 23:47:48 / cg" cg@2881: ! cg@2881: cg@2881: spraySpotHolderChanged cg@2881: imageEditView spraySpot:(self spraySpotHolder value) cg@2881: cg@2881: "Created: / 15-02-2012 / 22:37:08 / cg" cg@1353: ! ! cg@1353: tz@400: !ImageEditor class methodsFor:'documentation'! tz@400: tz@400: version tz@400: ^ '$Header$' cg@2590: ! cg@2590: cg@2590: version_CVS cg@2590: ^ '$Header$' tz@400: ! ! cg@2945: