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@1975: ResourceSpecEditor subclass:#ImageEditor tz@975: instanceVariableNames:'imageEditView colorMapMode editMode mouseKeyColorMode cg@1960: selectedColorIndex postOpenAction imageSeqNr drawingColormap cg@1960: lastShiftUsedWrap' cg@1640: classVariableNames:'LastDirectory LastSizeString MaskClipboard LastColormapMode cg@1640: DefaultRelativeSizes' 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: cg@1975: openLoadingImageWith:aBlock 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. cg@1975: editor openWindow 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@1975: imageEditor postOpenAction: [imageEditView := imageEditor imageEditView. cg@1975: imageEditor loadFromOrPrepareForClass: aClass andSelector: aSelector]. 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: cg@1966: openOnClass:aClass andSelector:aSelector cg@1966: "opens an Image Editor on aClass and aSelector" tz@400: cg@1975: self openLoadingImageWith:[:editor | editor loadFromClass:aClass theNonMetaclass andSelector:aSelector.] 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@1975: self openLoadingImageWith:[:editor | editor loadFromFile:aFileName.] 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@1975: self openLoadingImageWith:[:editor | editor loadFromImage: anImage.] 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: tz@400: 0 to: 5 do: tz@400: [:r| tz@400: 0 to: 5 do: tz@400: [:g| tz@400: 0 to: 5 do: tz@400: [: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: tz@400: 1 to: 25 do: tz@400: [: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@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@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@1545: ^super flyByHelpSpec addPairsFrom:#( cg@1545: cg@1545: #drawModeBox cg@1545: 'Rectangle' cg@1545: cg@1545: #drawModeCopy cg@1545: 'Copy' cg@1545: cg@1545: #drawModeFill cg@1637: 'Flood-Fill' cg@1545: cg@1545: #drawModeFilledBox cg@1637: 'Filled Rectangle' cg@1545: cg@1545: #drawModePaste cg@1545: 'Paste' cg@1545: cg@1545: #drawModePasteUnder cg@1637: 'Paste Under' cg@1637: cg@1637: #drawModePasteWithMask cg@1656: 'Paste with Mask' cg@1545: cg@1545: #drawModePoint cg@1545: 'Point' cg@1545: cg@1639: #drawModeSpecial cg@1639: 'Special Operations' cg@1639: cg@1545: #fileGrabImage cg@1748: 'Pick from Screen' cg@1545: cg@1545: #fileLoadFromClass cg@1884: 'Load from Method...' cg@1545: cg@1545: #fileLoadFromFile cg@1884: 'Load from File...' cg@1545: cg@1545: #fileNewImage cg@1637: 'New Image' cg@1545: cg@1545: #filePrint cg@1545: 'Print' cg@1545: cg@1545: #fileSaveAs cg@1884: 'Save to File...' cg@1545: cg@1545: #fileSaveMaskAs cg@1884: 'Save Mask to File...' cg@1545: cg@1545: #fileSaveMethod cg@1637: 'Save as Method' cg@1545: cg@1545: #fileSaveMethodAs cg@1884: 'Save as Method...' cg@1545: cg@1545: ) 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: tz@737: ^super helpSpec addPairsFrom:#( tz@460: tz@460: #colorMap cg@929: 'ColorMap functions.' cg@929: cg@929: #colorMap1 cg@929: 'Convert to depth-1 image.' cg@929: cg@986: #colorMap1M cg@986: 'Convert to depth-1 image plus mask.' cg@986: cg@929: #colorMap2 cg@929: 'Convert to depth-2 image.' cg@929: cg@986: #colorMap2M cg@986: 'Convert to depth-2 image plus mask.' cg@986: cg@929: #colorMap4 cg@929: 'Convert to depth-4 image.' cg@929: cg@986: #colorMap4M cg@986: 'Convert to depth-4 image plus mask.' cg@986: cg@929: #colorMap8 cg@929: 'Convert to depth-8 image.' cg@929: cg@929: #colorMap8M cg@929: 'Convert to depth-8 image plus mask.' cg@929: cg@986: #colorMapTable cg@986: 'Shows a list of used colors of the image.' cg@986: cg@929: #compressColormap cg@929: 'Remove unneeded entries from the colorMap.' tz@460: cg@1045: #cropAll cg@986: 'Find and remove all borders.' cg@986: cg@1045: #cropBottom cg@986: 'Find and remove bottom border.' cg@986: cg@1045: #cropLeft cg@986: 'Find and remove left border.' cg@986: cg@1045: #cropManual cg@986: 'Specify border(s) to remove.' cg@986: cg@1045: #cropRight cg@986: 'Find and remove right border.' cg@986: cg@1045: #cropTop cg@986: 'Find and remove top border.' tz@487: tz@460: #drawModeBox cg@1637: 'Rectangle Drawing Mode.' tz@460: cg@2375: #drawModeCircle cg@2375: 'Circle Drawing Mode.' cg@2375: tz@460: #drawModeCopy cg@1637: 'Area Copy Mode.' tz@460: tz@460: #drawModeFill cg@1637: 'Flood Fill Mode.' tz@460: tz@460: #drawModeFilledBox cg@1637: 'Filled Rectangle Drawing Mode.' tz@460: tz@460: #drawModePaste cg@1637: 'Paste Mode.' cg@914: cg@914: #drawModePasteUnder cg@1637: 'Paste-Under Mode.' cg@1637: cg@1637: #drawModePasteWithMask cg@1637: 'Paste-with-Mask Mode.' tz@460: tz@460: #drawModePoint cg@1637: 'Point Drawing Mode.' tz@460: cg@2375: #drawModeSpray cg@2375: 'Spray Drawing Mode.' cg@2375: cg@1639: #drawModeSpecial cg@1639: 'Special Operations' cg@1639: tz@460: #editFlipHorizontal cg@1637: 'Flip the image horizontally.' tz@460: tz@460: #editFlipVertical cg@1637: 'Flip the image vertically.' tz@460: tz@460: #editMagnifyImage cg@914: 'Magnify the image.' tz@460: tz@460: #editNegate cg@914: 'Invert the images colors.' tz@460: tz@460: #editResize cg@914: 'Resize the image (preserving the old image).' tz@460: tz@460: #editRotate cg@914: 'Rotate the image.' tz@460: cg@929: #fileGrabImage cg@929: 'Pick an image from the screen.' cg@929: tz@460: #fileLoadFromClass cg@929: 'Select and load an image from a resource method.' tz@460: tz@460: #fileLoadFromFile cg@929: 'Select and load an image from a file.' tz@460: tz@460: #fileNewImage cg@914: 'Create a new image' tz@460: tz@460: #filePrint tz@460: 'Print the image on a postscript printer.' tz@460: tz@460: #fileSaveAs cg@914: 'Save the image to a file.' tz@460: tz@460: #fileSaveMaskAs cg@914: 'Save the mask of the image to a file.' tz@460: ca@1613: #fileSaveButtonImageAs ca@1613: 'Save an image of a button with the image to a file (for html use).' ca@1613: tz@460: #fileSaveMethod cg@914: 'Save the image as resource method in the current class and selector.' tz@460: tz@460: #fileSaveMethodAs cg@914: 'Save the image as resource method in a class.' tz@460: tz@487: #magnificationNumber cg@914: 'Shows the current magnification.' tz@487: tz@487: #magnifyImageDown cg@914: 'Decrease magnification.' tz@487: tz@487: #magnifyImageUp cg@914: 'Increase magnification.' tz@487: tz@487: #mouseKeyColorMode cg@1637: 'Toggle between left and right mouse button color.' tz@487: tz@487: #previewView cg@914: 'Shows a preview of the image.' tz@487: tz@905: #settingsGridMagnification cg@914: 'Change the grid magnification of the edit view.' tz@905: tz@460: ) cg@928: cg@986: "Modified: / 7.9.1998 / 18:20:26 / cg" tz@460: ! ! tz@460: tz@737: !ImageEditor class methodsFor:'image specs'! tz@737: cg@2272: circleIcon cg@2272: "This resource specification was automatically generated cg@2272: by the ImageEditor of ST/X." cg@2272: 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: " cg@2272: self circleIcon inspect cg@2272: ImageEditor openOnClass:self andSelector:#circleIcon cg@2272: Icon flushCachedIcons cg@2272: " cg@2272: cg@2272: cg@2272: cg@2272: ^Icon cg@2272: constantNamed:'ImageEditor class circleIcon' cg@2272: ifAbsentPut:[(Depth1Image new) width: 14; height: 14; photometric:(#palette); bitsPerSample:(#(1)); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@@@@@A@@@@@@@@@@@@@@@C@@@@@@@@@@@@@@@a') ; colorMapFromArray:#[0 0 0 255 0 0]; mask:((Depth1Image new) width: 14; height: 14; photometric:(#blackIs0); bitsPerSample:(#(1)); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@@@@N@CF@PDA@PH@ BB@HDA@PD@1 @8@@@@@a') ; yourself); yourself] cg@2272: ! cg@2272: cg@1637: copyIcon cg@1637: "This resource specification was automatically generated cg@1637: by the ImageEditor of ST/X." cg@1637: 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: " cg@1637: self copyIcon inspect cg@1637: ImageEditor openOnClass:self andSelector:#copyIcon cg@1637: Icon flushCachedIcons cg@1637: " cg@1637: cg@1637: cg@1637: cg@1637: ^Icon cg@2272: constantNamed:'ImageEditor class copyIcon' cg@1975: ifAbsentPut:[(Depth2Image new) width: 14; height: 14; photometric:(#palette); bitsPerSample:(#(2)); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@@@@@@@@@** @@J)UUTB*Z*)@*&**PJ)**$B*Z*)@*&**PJ)**$@@Z*)@@F**P@AUUT@@@@@@b') ; colorMapFromArray:#[0 0 0 0 0 128 255 255 255]; mask:((Depth1Image new) width: 14; height: 14; photometric:(#blackIs0); bitsPerSample:(#(1)); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@C? O>@??3??O? sv@2155: sv@2155: ^ ToolbarIconLibrary startImageEditorIcon sv@2155: ! sv@2155: cg@1637: fillIcon cg@1637: "This resource specification was automatically generated cg@1637: by the ImageEditor of ST/X." cg@1637: 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: " cg@1637: self fillIcon inspect cg@1637: ImageEditor openOnClass:self andSelector:#fillIcon cg@1637: Icon flushCachedIcons cg@1637: " cg@1637: cg@1637: cg@1637: cg@1637: ^Icon cg@2272: constantNamed:'ImageEditor class fillIcon' cg@1975: ifAbsentPut:[(Depth2Image new) width: 14; height: 14; photometric:(#palette); bitsPerSample:(#(2)); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@@@@@@@@@@@ @@@@*H@@D*(@@DUUP@EAUU@AAEU@@@@U@@DDA@@@@@@@@PP@@@@@@@@@@@@@@b') ; colorMapFromArray:#[0 0 0 255 0 0 255 255 255]; mask:((Depth1Image new) width: 14; height: 14; photometric:(#blackIs0); bitsPerSample:(#(1)); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'C @Q@BN@I<@?8C?0[?!!G<@O P\@@ D@@@@@@@@@a') ; yourself); yourself] cg@1637: ! cg@1637: cg@1637: fillRectIcon cg@1637: "This resource specification was automatically generated cg@1637: by the ImageEditor of ST/X." cg@1637: 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: " cg@1637: self fillRectIcon inspect cg@1637: ImageEditor openOnClass:self andSelector:#fillRectIcon cg@1637: Icon flushCachedIcons cg@1637: " cg@1637: cg@1637: cg@1637: cg@1637: ^Icon cg@2272: constantNamed:'ImageEditor class fillRectIcon' cg@2272: ifAbsentPut:[(Depth1Image new) width: 14; height: 14; photometric:(#palette); bitsPerSample:(#(1)); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@@@@@A@@@@@@@@@@@@@@@@@@@@@@@@@@D@@@@a') ; colorMapFromArray:#[0 0 0 255 0 0]; mask:((Depth1Image new) width: 14; height: 14; photometric:(#blackIs0); bitsPerSample:(#(1)); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@@@C?0O?@? tz@737: tz@737: ^Icon cg@2272: constantNamed:'ImageEditor class leftMouseKeyIcon' cg@2272: ifAbsentPut:[(Depth2Image new) width: 16; height: 16; photometric:(#palette); bitsPerSample:(#(2)); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@@@@@@@@@@@@@@@EJJ@@AR" @@T((@@@@@@@B** @@**(@@J**@@B** @@**(@@J**@@@**@@@@@@@@@@@@@@a') ; colorMapFromArray:#[0 0 0 255 0 0 255 255 255]; mask:((Depth1Image new) width: 16; height: 16; photometric:(#blackIs0); bitsPerSample:(#(1)); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@@@@?0G? _>A?8G? _>A?8G? _>A?8G? O<@_ @@@b') ; yourself); yourself] martin@1433: ! tz@737: cg@1637: pasteIcon cg@1637: "This resource specification was automatically generated cg@1637: by the ImageEditor of ST/X." cg@1637: 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: " cg@1637: self pasteIcon inspect cg@1637: ImageEditor openOnClass:self andSelector:#pasteIcon cg@1637: Icon flushCachedIcons cg@1637: " cg@1637: cg@1637: cg@1637: cg@1637: ^Icon cg@2272: constantNamed:'ImageEditor class pasteIcon' cg@1975: ifAbsentPut:[(Depth4Image new) width: 14; height: 14; photometric:(#palette); bitsPerSample:(#(4)); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@@@@@@@@@@AU@@@@@CHE@E@2@@@ QDQD@0@@L@@@@@H@@BL#H2L#@@@QDQDQL @@D3L@@@@@@AL3A&Y&X@@SL0Y A&@@D3LF@@A @AL3A&@FX@@QDPY&Y& cg@1975: @@@@@@@@@@@b') ; colorMapFromArray:#[0 0 0 0 0 128 128 128 0 128 128 128 212 208 200 255 255 0 255 255 255]; mask:((Depth1Image new) width: 14; height: 14; photometric:(#blackIs0); bitsPerSample:(#(1)); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'C0A?8O?0??C?O?8??#?>O?8_? G>@@a') ; yourself); yourself] cg@1637: ! cg@1637: cg@1637: pasteUnderIcon cg@1637: "This resource specification was automatically generated cg@1637: by the ImageEditor of ST/X." cg@1637: 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: " cg@1637: self pasteUnderIcon inspect cg@1637: ImageEditor openOnClass:self andSelector:#pasteUnderIcon cg@1637: Icon flushCachedIcons cg@1637: " cg@1637: cg@1637: cg@1637: cg@1637: ^Icon cg@2272: constantNamed:'ImageEditor class pasteUnderIcon' cg@1975: ifAbsentPut:[(Depth4Image new) width: 14; height: 14; photometric:(#palette); bitsPerSample:(#(4)); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@@@@@@@@@@AU@@@@@CHE@E@2@@@ QDQD@0@@L@@@@@H@@BL#H2L#@@@QDQDQL @@D3L3LP@@@AL3L3E&X@@SL3L0A&@@D3L3@@A @AL3L3@FX@@QDQDQY& cg@1975: @@@@@@@@@@@b') ; colorMapFromArray:#[0 0 0 0 0 128 128 128 0 128 128 128 212 208 200 255 255 0 255 255 255]; mask:((Depth1Image new) width: 14; height: 14; photometric:(#blackIs0); bitsPerSample:(#(1)); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'C0A?8O?0??C?O?8??#?>O?8_? G>@@a') ; yourself); yourself] cg@1637: ! cg@1637: cg@1637: pasteWithMaskIcon cg@1637: "This resource specification was automatically generated cg@1637: by the ImageEditor of ST/X." cg@1637: 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: " cg@1637: self pasteWithMaskIcon inspect cg@1637: ImageEditor openOnClass:self andSelector:#pasteWithMaskIcon cg@1637: Icon flushCachedIcons cg@1637: " cg@1637: cg@1637: cg@1637: cg@1637: ^Icon cg@2272: constantNamed:'ImageEditor class pasteWithMaskIcon' cg@2272: ifAbsentPut:[(Depth4Image new) width: 14; height: 14; photometric:(#palette); bitsPerSample:(#(4)); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@@@@@@@@@@AU@@@@@CHE@E@2@@@ QDQD@0@@L@@@@@H@@BL#H2L#@@@QDQDQL @@D3L@@@@@@AL3@3M&X@@SL0L3A&@@D3LCL0A @AL3@3LFX@@QDPY&Y& cg@2272: @@@@@@@@@@@b') ; colorMapFromArray:#[0 0 0 0 0 128 128 128 0 128 128 128 212 208 200 255 255 0 255 255 255]; mask:((Depth1Image new) width: 14; height: 14; photometric:(#blackIs0); bitsPerSample:(#(1)); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'C0A?8O?0??C?O?8??#?>O?8_? G>@@a') ; yourself); yourself] cg@1637: ! cg@1637: cg@1637: pointIcon cg@1637: "This resource specification was automatically generated cg@1637: by the ImageEditor of ST/X." cg@1637: 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: " cg@1637: self pointIcon inspect cg@1637: ImageEditor openOnClass:self andSelector:#pointIcon cg@1637: Icon flushCachedIcons cg@1637: " cg@1637: cg@1637: cg@1637: cg@1637: ^Icon cg@2272: constantNamed:'ImageEditor class pointIcon' cg@1975: ifAbsentPut:[(Depth1Image new) width: 14; height: 14; photometric:(#palette); bitsPerSample:(#(1)); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@@@@@A@@@@@@@@@@@@@@@C@@@@@@@@@@@@@@@a') ; colorMapFromArray:#[0 0 0 255 255 255]; mask:((Depth1Image new) width: 14; height: 14; photometric:(#blackIs0); bitsPerSample:(#(1)); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@@@@@0@G@@8@G@@8@G@@8@G@@X@@@@@@@@@@@a') ; yourself); yourself] cg@1637: ! cg@1637: cg@1637: rectIcon cg@1637: "This resource specification was automatically generated cg@1637: by the ImageEditor of ST/X." cg@1637: 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: " cg@1637: self rectIcon inspect cg@1637: ImageEditor openOnClass:self andSelector:#rectIcon cg@1637: Icon flushCachedIcons cg@1637: " cg@1637: cg@1637: cg@1637: cg@1637: ^Icon cg@2272: constantNamed:'ImageEditor class rectIcon' cg@2272: ifAbsentPut:[(Depth1Image new) width: 14; height: 14; photometric:(#palette); bitsPerSample:(#(1)); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@@@@@A@@@@@@@@@@@@@@@C@@@@@@@@@@@@@@@a') ; colorMapFromArray:#[0 0 0 255 0 0]; mask:((Depth1Image new) width: 14; height: 14; photometric:(#blackIs0); bitsPerSample:(#(1)); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@@@C?0HA@ DB@PHA@ DB@PHA@ DC?0@@@@@@@a') ; yourself); yourself] cg@1637: ! cg@1637: tz@737: rightMouseKeyIcon tz@737: "This resource specification was automatically generated tz@737: by the ImageEditor of ST/X." tz@737: 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: tz@737: " cg@1405: self rightMouseKeyIcon inspect tz@737: ImageEditor openOnClass:self andSelector:#rightMouseKeyIcon cg@2272: Icon flushCachedIcons tz@737: " tz@737: tz@737: tz@737: tz@737: ^Icon cg@2272: constantNamed:'ImageEditor class rightMouseKeyIcon' cg@2272: ifAbsentPut:[(Depth2Image new) width: 16; height: 16; photometric:(#palette); bitsPerSample:(#(2)); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@@@@@@@@@@@@@@@JJE@@B"!!P@@((T@@@@@@@B** @@**(@@J**@@B** @@**(@@J**@@@**@@@@@@@@@@@@@@a') ; colorMapFromArray:#[0 0 0 255 0 0 255 255 255]; mask:((Depth1Image new) width: 16; height: 16; photometric:(#blackIs0); bitsPerSample:(#(1)); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@@@@?0G? _>A?8G? _>A?8G? _>A?8G? O<@_ @@@b') ; yourself); yourself] cg@1637: ! cg@1637: cg@1637: specialIcon cg@1637: "This resource specification was automatically generated cg@1637: by the ImageEditor of ST/X." cg@1637: 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: " cg@1637: self specialIcon inspect cg@1637: ImageEditor openOnClass:self andSelector:#specialIcon cg@1637: Icon flushCachedIcons cg@1637: " cg@1637: cg@1637: cg@1637: cg@1637: ^Icon cg@2272: constantNamed:'ImageEditor class specialIcon' cg@2272: ifAbsentPut:[(Depth1Image new) width: 14; height: 14; photometric:(#palette); bitsPerSample:(#(1)); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@L@@@@B@@@@@0@@@@@@@@@@@@@@@P@@@@@@@@@a') ; colorMapFromArray:#[0 0 0 255 0 0]; mask:((Depth1Image new) width: 14; height: 14; photometric:(#blackIs0); bitsPerSample:(#(1)); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@@@@L@@0@G @^@A8@G @L@@0@@@@L@@0@@@@@a') ; yourself); yourself] cg@2375: ! cg@2375: cg@2375: sprayIcon cg@2375: "This resource specification was automatically generated cg@2375: by the ImageEditor of ST/X." cg@2375: cg@2375: "Do not manually edit this!! If it is corrupted, cg@2375: the ImageEditor may not be able to read the specification." cg@2375: cg@2375: " cg@2375: self sprayIcon inspect cg@2375: ImageEditor openOnClass:self andSelector:#sprayIcon cg@2375: Icon flushCachedIcons cg@2375: " cg@2375: cg@2375: cg@2375: cg@2375: ^Icon cg@2375: constantNamed:'ImageEditor class sprayIcon' cg@2375: ifAbsentPut:[(Depth4Image new) width: 14; height: 14; photometric:(#palette); bitsPerSample:(#[4]); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@@@@@@@@@@@@@@@D@@@@@@@DA@@@@@@D@D@@@@@@A@PD@@@@@@A@P@@@@@@@A@P@@@@@@@A@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ cg@2375: @@@@@@@@@@@b') ; colorMapFromArray:#[0 0 0 84 84 84 170 170 170 255 255 255 255 0 0]; mask:((Depth1Image new) width: 14; height: 14; photometric:(#blackIs0); bitsPerSample:(#(1)); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@@B@@(A)@F*@IPA2 H$@"@BH@H @"@BH@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@1820: #(FullSpec cg@1820: name: windowSpec cg@1820: window: cg@1820: (WindowSpec cg@1820: label: 'Image Editor' cg@1820: name: 'Image Editor' cg@1820: min: (Point 400 320) cg@1820: bounds: (Rectangle 0 0 450 350) cg@1820: menu: menu sv@2155: icon: defaultIcon cg@1558: ) cg@1820: component: cg@1820: (SpecCollection cg@1820: collection: ( cg@1820: (MenuPanelSpec cg@1820: name: 'menuToolbarView' cg@1820: layout: (LayoutFrame 0 0.0 0 0 0 1.0 32 0) cg@1820: style: (FontDescription helvetica medium roman 10) cg@1820: menu: menuToolbar cg@1820: showSeparatingLines: true cg@1558: ) cg@1820: (VariableHorizontalPanelSpec cg@1998: name: 'mainPanel' cg@1820: layout: (LayoutFrame 0 0.0 34 0.0 0 1.0 -26 1.0) cg@1820: snapMode: both cg@1843: barLevel: 0 cg@1820: component: cg@1820: (SpecCollection cg@1820: collection: ( cg@1820: (ViewSpec cg@1820: name: 'leftView' cg@1820: level: 1 cg@1820: component: cg@1820: (SpecCollection cg@1820: collection: ( cg@1820: (VariableVerticalPanelSpec cg@1820: name: 'verticalPanel' cg@1820: layout: (LayoutFrame 0 0.0 0 0.0 0 1.0 0 1.0) cg@1820: level: 0 cg@1820: snapMode: both cg@1820: component: cg@1820: (SpecCollection cg@1820: collection: ( cg@1820: (ViewSpec cg@1820: name: 'View1' cg@1820: component: cg@1820: (SpecCollection cg@1820: collection: ( cg@1820: (MenuPanelSpec cg@1820: name: 'MouseButtonColorToolBar' cg@1820: layout: (LayoutFrame 0 0.0 0 0 0 1.0 24 0) cg@1820: level: 0 cg@1820: menu: menuMouseButtonColors cg@1558: ) cg@1820: (DataSetSpec cg@1820: name: 'colorDataSetView' cg@1820: layout: (LayoutFrame 0 0.0 26 0.0 0 1.0 0 1.0) cg@1820: activeHelpKey: colorMapTable cg@1820: style: (FontDescription helvetica medium roman 10) cg@1820: model: selectionOfColor cg@1820: menu: colorMapMenu cg@1820: hasHorizontalScrollBar: true cg@1820: hasVerticalScrollBar: true cg@1820: miniScrollerHorizontal: true cg@1820: miniScrollerVertical: true cg@1820: dataList: listOfColors cg@1820: has3Dseparators: true cg@2174: doubleClickSelector: doubleClickOnColor: cg@1900: columnHolder: colorTableColumns cg@1820: verticalSpacing: 1 cg@1820: columnAdaptor: colorColumnAdaptor tz@767: ) cg@1558: ) cg@1558: cg@1558: ) cg@1558: ) cg@1820: (ArbitraryComponentSpec cg@1820: name: 'imagePreView' cg@1820: activeHelpKey: previewView cg@1820: menu: previewMenu cg@1820: hasHorizontalScrollBar: true cg@1820: hasVerticalScrollBar: true cg@1820: miniScrollerHorizontal: true cg@1820: miniScrollerVertical: true cg@1820: hasBorder: false cg@1820: component: ImageView tz@767: ) cg@1558: ) cg@1558: tz@767: ) cg@1820: handles: (Any 0.5 1.0) tz@767: ) cg@1558: ) cg@1558: tz@767: ) cg@1558: ) cg@1820: (ViewSpec cg@1820: name: 'rightView' cg@1820: component: cg@1820: (SpecCollection cg@1820: collection: ( cg@1820: (MenuPanelSpec cg@1820: name: 'ToolBar1' cg@1820: layout: (LayoutFrame 0 0 0 0.0 28 0 0 1.0) cg@1820: level: 1 cg@1820: menu: toolsMenuToolbar cg@1820: verticalLayout: true cg@1820: centerItems: true cg@1820: textDefault: true cg@1558: ) cg@1820: (ViewSpec cg@1820: name: 'editingView' cg@1820: layout: (LayoutFrame 28 0.0 0 0.0 0 1.0 0 1.0) cg@1820: level: 1 cg@1820: component: cg@1820: (SpecCollection cg@1820: collection: ( cg@1820: (ArbitraryComponentSpec cg@1820: name: 'imageEditView' cg@1820: layout: (LayoutFrame 2 0.0 2 0.0 -2 1.0 -24 1.0) cg@1820: hasHorizontalScrollBar: true cg@1820: hasVerticalScrollBar: true cg@1820: hasBorder: false cg@1820: component: ImageEditView cg@1637: ) cg@1820: (LabelSpec cg@1820: name: 'coordLabel' cg@1820: layout: (LayoutFrame 2 0.0 -22 1 -83 1.0 0 1.0) cg@1820: level: -1 cg@1820: labelChannel: imageInfoHolder cg@1820: resizeForLabel: false cg@1820: adjust: left cg@1637: ) cg@1820: (ArrowButtonSpec cg@1820: name: 'magnifyDownButton' cg@1820: layout: (LayoutFrame -80 1 -22 1 -58 1 0 1) cg@1820: activeHelpKey: magnifyImageDown cg@1820: model: doMagnifyDown cg@1820: enableChannel: imageIsLoaded cg@1820: isTriggerOnDown: true cg@1820: direction: left cg@1637: ) cg@1820: (ArrowButtonSpec cg@1820: name: 'magnifyUpButton' cg@1820: layout: (LayoutFrame -24 1 -22 1 -2 1 0 1) cg@1820: activeHelpKey: magnifyImageUp cg@1820: model: doMagnifyUp cg@1820: enableChannel: imageIsLoaded cg@1820: isTriggerOnDown: true cg@1820: direction: right cg@1637: ) cg@1820: (InputFieldSpec cg@1820: name: 'magnificationInputField' cg@1820: layout: (LayoutFrame -57 1 -22 1 -26 1 0 1) cg@1820: activeHelpKey: magnificationNumber cg@1820: enableChannel: imageIsLoaded cg@1987: model: magnificationHolder cg@1820: type: numberInRange cg@1975: acceptOnReturn: true cg@1975: acceptOnTab: true cg@1820: numChars: 2 cg@1820: minValue: 1 cg@1820: maxValue: 99 cg@1975: acceptOnPointerLeave: true cg@1637: ) cg@1637: ) cg@1637: cg@1637: ) cg@1558: ) cg@1558: ) cg@1558: cg@1558: ) cg@1558: ) cg@1558: ) cg@1558: tz@767: ) cg@1843: handles: (Any 0.288889 1.0) cg@1558: ) cg@1820: (UISubSpecification cg@1820: name: 'infoBarSubSpec' cg@1820: layout: (LayoutFrame 0 0.0 -24 1 0 1.0 0 1.0) cg@1820: majorKey: ToolApplicationModel cg@1820: minorKey: windowSpecForInfoBar cg@1558: ) cg@1558: ) cg@1558: cg@1558: ) tz@767: ) 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@1847: enabled: hasColormap cg@1847: label: 'Add Color' cg@1847: itemValue: addColorToColormap cg@1847: translateLabel: true cg@1847: ) cg@1847: (MenuItem cg@1847: enabled: hasColormap 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@1847: enabled: hasColormap cg@1852: label: 'Cut Color' cg@1852: itemValue: cutColorFromColormap cg@1852: translateLabel: true cg@1852: isVisible: false cg@1852: ) cg@1852: (MenuItem cg@1852: label: 'Copy Color' cg@1852: itemValue: copyColorFromColormap cg@1852: translateLabel: true cg@1852: ) cg@1852: (MenuItem cg@1852: enabled: hasColormap 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@1852: ) cg@1852: (MenuItem cg@1852: label: '-' cg@1852: ) cg@1852: (MenuItem cg@1852: enabled: hasColormap cg@2539: label: 'Edit Color...' cg@1931: itemValue: editSelectedColor cg@1931: translateLabel: true cg@1931: ) cg@1931: (MenuItem cg@1931: enabled: hasColormap cg@1847: label: 'Brighter' cg@1847: itemValue: makeSelectedColorBrighter cg@1847: translateLabel: true cg@1847: ) cg@1847: (MenuItem cg@1847: enabled: hasColormap cg@1847: label: 'Darker' cg@1847: itemValue: makeSelectedColorDarker cg@1847: translateLabel: true cg@1847: ) cg@1847: (MenuItem cg@1847: enabled: hasColormap cg@1884: label: 'Make Gray' cg@1884: itemValue: makeSelectedColorGray cg@1884: translateLabel: true cg@1884: ) cg@1884: (MenuItem cg@1847: label: '-' cg@1847: ) cg@1847: (MenuItem cg@1847: enabled: hasColormap cg@1847: label: 'Inspect Color' cg@1847: itemValue: inspectColor cg@1847: translateLabel: true cg@1847: ) cg@1847: ) cg@1847: nil cg@1847: nil cg@1053: ) cg@2190: cg@2190: "Modified: / 27-10-2007 / 10:24:00 / cg" 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@2196: keepLinkedMenu: true cg@1124: ) cg@1882: (MenuItem cg@1882: label: 'Edit' cg@1882: translateLabel: true cg@2196: submenuChannel: menuEdit cg@2196: keepLinkedMenu: true cg@1124: ) cg@1882: (MenuItem cg@1882: enabled: imageIsLoaded cg@1882: label: 'Mode' cg@1882: translateLabel: true cg@1882: submenuChannel: modeMenu cg@1637: ) cg@1882: (MenuItem cg@1882: enabled: imageIsLoaded cg@1924: label: 'Colors' cg@1882: translateLabel: true cg@1882: submenu: cg@1882: (Menu cg@1882: ( cg@1882: (MenuItem cg@1882: label: 'Depth' cg@1882: translateLabel: true cg@1882: submenu: cg@1882: (Menu cg@1882: ( cg@1882: (MenuItem cg@1936: activeHelpKey: colorMap1 cg@1936: label: '1-Plane' cg@1934: itemValue: colorMapMode: cg@1934: translateLabel: true cg@1936: argument: depth1 cg@1934: choice: colorMapMode cg@1936: choiceValue: depth1 cg@1934: ) cg@1934: (MenuItem cg@1936: activeHelpKey: colorMap1M cg@1936: label: '1-Plane + Mask' cg@1882: itemValue: colorMapMode: cg@1882: translateLabel: true cg@1936: argument: masked1 cg@1882: choice: colorMapMode cg@1936: choiceValue: masked1 cg@1649: ) cg@1882: (MenuItem cg@1936: label: '-' cg@1649: ) cg@1882: (MenuItem cg@1882: activeHelpKey: colorMap2 cg@1882: label: '2-Plane' cg@1882: itemValue: colorMapMode: cg@1882: translateLabel: true cg@1882: argument: depth2 cg@1882: choice: colorMapMode cg@1882: choiceValue: depth2 cg@1649: ) cg@1882: (MenuItem cg@1936: activeHelpKey: colorMap2M cg@1936: label: '2-Plane + Mask' cg@1882: itemValue: colorMapMode: cg@1882: translateLabel: true cg@1936: argument: masked2 cg@1882: choice: colorMapMode cg@1936: choiceValue: masked2 cg@1649: ) cg@1882: (MenuItem cg@1882: label: '-' cg@1649: ) cg@1882: (MenuItem cg@1936: activeHelpKey: colorMap4 cg@1936: label: '4-Plane' cg@1936: itemValue: colorMapMode: cg@1936: translateLabel: true cg@1936: argument: depth4 cg@1936: choice: colorMapMode cg@1936: choiceValue: depth4 cg@1936: ) cg@1936: (MenuItem cg@1936: activeHelpKey: colorMap4M cg@1936: label: '4-Plane + Mask' cg@1936: itemValue: colorMapMode: cg@1936: translateLabel: true cg@1936: argument: masked4 cg@1936: choice: colorMapMode cg@1936: choiceValue: masked4 cg@1936: ) cg@1936: (MenuItem cg@1936: label: '-' cg@1936: ) cg@1936: (MenuItem cg@1936: activeHelpKey: colorMap8 cg@1936: label: '8-Plane' cg@1934: itemValue: colorMapMode: cg@1934: translateLabel: true cg@1936: argument: depth8 cg@1936: choice: colorMapMode cg@1936: choiceValue: depth8 cg@1936: ) cg@1936: (MenuItem cg@1936: activeHelpKey: colorMap8M cg@1936: label: '8-Plane + Mask' cg@1936: itemValue: colorMapMode: cg@1936: translateLabel: true cg@1936: argument: masked8 cg@1934: choice: colorMapMode cg@1936: choiceValue: masked8 cg@1936: ) cg@1936: (MenuItem cg@1936: label: '-' cg@1936: ) cg@1936: (MenuItem cg@1936: activeHelpKey: colorMap16 cg@1936: label: '16-Plane' cg@1936: itemValue: colorMapMode: cg@1936: translateLabel: true cg@1936: argument: depth16 cg@1936: choice: colorMapMode cg@1936: choiceValue: depth16 cg@1934: ) cg@1934: (MenuItem cg@1934: activeHelpKey: colorMap16M cg@1934: label: '16-Plane + Mask' cg@1934: itemValue: colorMapMode: cg@1934: translateLabel: true cg@1934: argument: masked16 cg@1934: choice: colorMapMode cg@1934: choiceValue: masked16 cg@1934: ) cg@1934: (MenuItem cg@1936: label: '-' cg@1649: ) cg@1882: (MenuItem cg@1936: activeHelpKey: colorMap24 cg@1936: label: '24-Plane' cg@1882: itemValue: colorMapMode: cg@1882: translateLabel: true cg@1936: argument: depth24 cg@1882: choice: colorMapMode cg@1936: choiceValue: depth24 cg@1649: ) cg@1882: (MenuItem cg@1936: activeHelpKey: colorMap24M cg@1936: label: '24-Plane + Mask' cg@1882: itemValue: colorMapMode: cg@1882: translateLabel: true cg@1936: argument: masked24 cg@1882: choice: colorMapMode cg@1936: choiceValue: masked24 cg@1649: ) cg@1649: ) cg@1649: nil cg@1649: nil cg@1649: ) cg@1124: ) cg@1882: (MenuItem cg@1924: label: 'ColorMap' cg@1882: translateLabel: true cg@1882: submenu: cg@1882: (Menu cg@1882: ( cg@1882: (MenuItem cg@1882: activeHelpKey: compressColormap cg@1882: enabled: hasColormap cg@1882: label: 'Compress Colormap' cg@1882: itemValue: compressColorMap cg@1882: translateLabel: true cg@1649: ) cg@1882: (MenuItem cg@1882: enabled: hasColormap cg@1882: label: 'Sort Colormap' cg@1882: itemValue: sortColorMap cg@1882: translateLabel: true cg@1649: ) cg@1882: (MenuItem cg@1934: label: 'Reduce Number of Colors by Rounding...' cg@1934: itemValue: reduceNumberOfColors2 cg@1934: translateLabel: true cg@1934: ) cg@1934: (MenuItem cg@1934: label: 'Reduce Number of Colors by Masking Bits...' cg@1882: itemValue: reduceNumberOfColors cg@1882: translateLabel: true cg@1649: ) cg@2054: (MenuItem cg@2054: label: 'Dither to Depth...' cg@2054: itemValue: ditherToDepth cg@2054: translateLabel: true cg@2054: ) cg@1649: ) cg@1649: nil cg@1649: nil cg@1649: ) cg@1124: ) cg@1882: (MenuItem cg@1882: label: 'Process' cg@1882: translateLabel: true cg@1882: submenu: cg@1882: (Menu cg@1882: ( cg@1882: (MenuItem cg@1882: label: 'Make GrayScale' cg@1924: itemValue: makeGrayScaleImage cg@1882: translateLabel: true cg@1649: ) cg@1882: (MenuItem cg@1924: enabled: hasNoColormap cg@1924: label: 'Make dithered 8Bit Palette' cg@1924: itemValue: makeDitheredPaletteImage cg@1924: translateLabel: true cg@1924: isVisible: false cg@1924: ) cg@1924: (MenuItem cg@1882: label: 'Make Brighter' cg@1882: itemValue: makeBrighter cg@1882: translateLabel: true cg@1649: ) cg@1882: (MenuItem cg@1882: label: 'Make Darker' cg@1882: itemValue: makeDarker cg@1882: translateLabel: true cg@1649: ) cg@1882: (MenuItem cg@1882: label: 'Make Inverse' cg@1882: itemValue: makeInverse cg@1882: translateLabel: true cg@1649: ) cg@1882: (MenuItem cg@1882: label: '-' cg@1649: ) cg@1882: (MenuItem cg@1882: label: 'Change HLS...' cg@1882: itemValue: changeHLS cg@1882: translateLabel: true cg@1649: ) cg@2192: (MenuItem cg@2192: label: 'Colorize...' cg@2192: itemValue: colorize cg@2192: translateLabel: true cg@2192: ) cg@1649: ) cg@1649: nil cg@1649: nil cg@1649: ) cg@1436: ) cg@1882: (MenuItem cg@1882: label: 'Mask' cg@1882: translateLabel: true cg@1882: submenu: cg@1882: (Menu cg@1882: ( cg@1882: (MenuItem cg@1882: activeHelpKey: copyMask cg@1882: enabled: hasMask cg@1882: label: 'Copy Mask' cg@1882: itemValue: copyMask cg@1882: translateLabel: true cg@1649: ) cg@1882: (MenuItem cg@1882: activeHelpKey: pasteMask cg@1882: enabled: hasMask cg@1882: label: 'Paste Mask' cg@1882: itemValue: pasteMask cg@1882: translateLabel: true cg@1649: ) cg@1882: (MenuItem cg@1924: enabled: hasMask cg@1882: label: 'Clear Masked Pixels' cg@1882: itemValue: clearMaskedPixels cg@1882: translateLabel: true cg@1649: ) cg@1649: ) cg@1649: nil cg@1649: nil cg@1649: ) cg@1598: ) cg@1124: ) cg@1124: nil cg@1124: nil tz@756: ) cg@1124: ) cg@1882: (MenuItem cg@1882: label: 'Settings' cg@1882: translateLabel: true cg@1882: submenu: cg@1882: (Menu cg@1882: ( cg@1882: (MenuItem cg@1882: activeHelpKey: settingsGridMagnification cg@1882: label: 'Grid Magnification Limit...' cg@1882: itemValue: doChangeGridMagnification cg@1882: translateLabel: true cg@1124: ) cg@2192: (MenuItem cg@2192: label: 'Pen' cg@2192: translateLabel: true cg@2192: submenu: cg@2192: (Menu cg@2192: ( cg@2192: (MenuItem cg@2192: label: '1' cg@2192: itemValue: penWidth: cg@2192: translateLabel: true cg@2192: argument: 1 cg@2192: ) cg@2192: (MenuItem cg@2192: label: '5' cg@2192: itemValue: penWidth: cg@2192: translateLabel: true cg@2192: argument: 5 cg@2192: ) cg@2192: (MenuItem cg@2192: label: '10' cg@2192: itemValue: penWidth: cg@2192: translateLabel: true cg@2192: argument: 10 cg@2192: ) cg@2192: ) cg@2192: nil cg@2192: nil cg@2192: ) cg@2192: ) cg@2375: (MenuItem cg@2375: label: 'Spray' cg@2375: translateLabel: true cg@2375: submenu: cg@2375: (Menu cg@2375: ( cg@2375: (MenuItem cg@2375: label: '4' cg@2375: itemValue: spraySpot: cg@2375: translateLabel: true cg@2375: argument: 4 cg@2375: ) cg@2375: (MenuItem cg@2375: label: '8' cg@2375: itemValue: spraySpot: cg@2375: translateLabel: true cg@2375: argument: 8 cg@2375: ) cg@2375: (MenuItem cg@2375: label: '16' cg@2375: itemValue: spraySpot: cg@2375: translateLabel: true cg@2375: argument: 16 cg@2375: ) cg@2375: (MenuItem cg@2375: label: '32' cg@2375: itemValue: spraySpot: cg@2375: translateLabel: true cg@2375: argument: 32 cg@2375: ) cg@2375: ) cg@2375: nil cg@2375: nil cg@2375: ) cg@2375: ) cg@1124: ) cg@1124: nil cg@1124: nil tz@400: ) 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@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@2196: activeHelpKey: editResize cg@2196: label: 'Resize...' cg@2196: itemValue: doResizeImage cg@2196: translateLabel: true cg@2196: ) cg@2196: (MenuItem cg@2196: activeHelpKey: editMagnifyImage cg@2196: label: 'Magnify...' cg@2196: itemValue: doMagnifyImage cg@2196: translateLabel: true cg@2196: ) cg@2196: (MenuItem cg@2196: activeHelpKey: editMagnifyImage cg@2196: label: 'Magnify By...' cg@2196: itemValue: doMagnifyImageBy cg@2196: translateLabel: true cg@2196: ) cg@2196: (MenuItem cg@2196: activeHelpKey: editRotate cg@2196: label: 'Rotate...' cg@2196: itemValue: doRotateImage cg@2196: translateLabel: true cg@2196: ) cg@2196: (MenuItem cg@2354: activeHelpKey: edit3DProjection cg@2354: label: '3D Projection...' cg@2354: itemValue: do3DProjection cg@2354: translateLabel: true cg@2354: ) cg@2354: (MenuItem cg@2196: label: 'Flip' cg@2196: translateLabel: true cg@2196: submenu: cg@2196: (Menu cg@2196: ( cg@2196: (MenuItem cg@2196: activeHelpKey: editFlipVertical cg@2196: label: 'Flip - Vertical' cg@2196: itemValue: doFlipVertical cg@2196: translateLabel: true cg@2196: ) cg@2196: (MenuItem cg@2196: activeHelpKey: editFlipHorizontal cg@2196: label: 'Flip - Horizontal' cg@2196: itemValue: doFlipHorizontal cg@2196: translateLabel: true 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@2196: label: 'Invert' cg@2196: itemValue: doNegativeImage cg@2196: translateLabel: true cg@2196: ) cg@2196: (MenuItem cg@2196: label: 'Brighten' cg@2196: itemValue: doBrightenImage cg@2196: translateLabel: true cg@2196: ) cg@2196: (MenuItem cg@2196: label: 'Darken' cg@2196: itemValue: doDarkenImage cg@2196: translateLabel: true cg@2196: ) cg@2196: (MenuItem cg@2196: label: '-' cg@2196: ) cg@2196: (MenuItem 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@2196: activeHelpKey: uncropManual cg@2196: label: 'Uncrop (Add Border)...' cg@2196: itemValue: doUnCropManual cg@2196: translateLabel: true cg@2196: ) cg@2196: (MenuItem cg@2196: activeHelpKey: shiftManual 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@2196: label: 'Text...' cg@2196: itemValue: doInsertTextFromUser cg@2196: translateLabel: true cg@2196: ) cg@2424: 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@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: translateLabel: true cg@2196: ) cg@2196: (MenuItem cg@2196: activeHelpKey: fileNewImage cg@2196: label: 'New...' cg@2196: itemValue: doNewImage cg@2196: translateLabel: true cg@2196: ) cg@2196: (MenuItem cg@2196: activeHelpKey: fileNewImage cg@2196: label: 'New from ClipBoard' cg@2196: itemValue: doNewImageFromClipboard cg@2196: translateLabel: true cg@2196: ) cg@2196: (MenuItem cg@2196: label: '-' cg@2196: ) cg@2196: (MenuItem cg@2196: activeHelpKey: fileLoadFromClass cg@2196: label: 'Load...' cg@2196: itemValue: doLoadFromClass cg@2196: translateLabel: true cg@2196: ) cg@2196: (MenuItem cg@2196: activeHelpKey: fileLoadFromFile cg@2196: label: 'Load from File...' cg@2196: itemValue: doLoadFromFile cg@2196: translateLabel: true cg@2196: ) cg@2196: (MenuItem cg@2196: activeHelpKey: fileGrabImage cg@2196: label: 'Grab from Screen...' cg@2196: itemValue: grabScreenImage cg@2196: translateLabel: true cg@2196: ) cg@2196: (MenuItem cg@2196: enabled: imageHasNextImage cg@2196: label: 'Next in Sequence' cg@2196: itemValue: nextImageInSequence cg@2196: translateLabel: true cg@2196: isVisible: isStandAlone cg@2196: ) cg@2196: (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: translateLabel: true cg@2196: ) cg@2196: (MenuItem cg@2196: activeHelpKey: fileSaveMethodAs cg@2196: enabled: imageIsLoaded cg@2196: label: 'Save As...' cg@2196: itemValue: doSaveMethodAs cg@2196: translateLabel: true cg@2196: ) cg@2196: (MenuItem cg@2196: activeHelpKey: fileSaveAs cg@2196: enabled: imageIsLoaded cg@2196: label: 'Save to File...' cg@2196: itemValue: doSaveImageFileAs cg@2196: translateLabel: true cg@2196: ) cg@2196: (MenuItem cg@2196: activeHelpKey: fileSaveMaskAs cg@2196: enabled: imageIsLoaded cg@2196: label: 'Save Mask to File...' cg@2196: itemValue: doSaveImageMaskFileAs cg@2196: translateLabel: true cg@2196: ) cg@2196: (MenuItem cg@2196: activeHelpKey: fileSaveButtonImageAs cg@2196: enabled: imageIsLoaded cg@2196: label: 'Save as Button to File...' cg@2196: itemValue: doSaveButtonImageToFileAs cg@2196: translateLabel: true cg@2196: ) cg@2196: (MenuItem cg@2196: enabled: imageIsLoaded cg@2196: label: 'Copy to Clipboard' cg@2196: itemValue: doCopyImageToClipboard cg@2196: translateLabel: true cg@2196: ) cg@2196: (MenuItem cg@2196: label: '-' cg@2196: ) cg@2196: (MenuItem cg@2196: activeHelpKey: fileShowStoreString cg@2196: enabled: imageIsLoaded cg@2196: label: 'Show storeString' cg@2196: itemValue: doShowStoreString cg@2196: translateLabel: true cg@2196: ) cg@2196: (MenuItem cg@2196: activeHelpKey: fileEditMask cg@2196: enabled: imageIsLoaded cg@2196: label: 'Edit Mask' cg@2196: itemValue: doEditMask cg@2196: translateLabel: true cg@2196: ) cg@2196: (MenuItem cg@2196: label: '-' cg@2196: ) cg@2196: (MenuItem cg@2196: activeHelpKey: filePrint cg@2196: enabled: imageIsLoaded cg@2196: label: 'Print' cg@2196: itemValue: doPrint cg@2196: translateLabel: true cg@2196: ) cg@2196: (MenuItem cg@2196: label: '-' cg@2196: isVisible: isStandAlone cg@2196: ) cg@2196: (MenuItem cg@2196: activeHelpKey: fileBrowseClass cg@2196: enabled: hasClassDefined cg@2196: label: 'Browse Class' cg@2196: itemValue: doBrowseClass cg@2196: translateLabel: true cg@2196: isVisible: isStandAlone cg@2196: ) cg@2196: (MenuItem cg@2196: label: 'Inspect Image' cg@2196: itemValue: doInspectImage cg@2196: translateLabel: true cg@2196: isVisible: isStandAlone cg@2196: ) cg@2196: (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: translateLabel: true 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 tz@975: #enabled: #imageIsLoaded 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 tz@975: #enabled: #imageIsLoaded tz@679: #labelImage: #(#ResourceRetriever nil #rightMouseKeyIcon) tz@975: #choice: #mouseKeyColorMode tz@975: #choiceValue: 2 tz@679: ) tz@679: ) nil tz@679: nil tz@679: ) tz@679: ! tz@679: 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: 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@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@1970: enabled: imageIsLoaded 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@1970: enabled: imageIsLoaded cg@1970: label: 'saveAsMethod' cg@1970: itemValue: doSaveMethod cg@1970: translateLabel: true cg@1970: isButton: true cg@1975: isVisible: isNotStandAlone cg@1970: labelImage: (ResourceRetriever XPToolbarIconLibrary saveImageAsMethodAsIcon) 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@1820: enabled: imageIsLoaded 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@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@1637: #(#Menu cg@1637: #( cg@1196: #(#MenuItem cg@1196: #activeHelpKey: #drawModePoint cg@1196: #enabled: #imageIsLoaded cg@1637: #label: 'Point' cg@1637: #translateLabel: true cg@1196: #choice: #editMode cg@1196: #choiceValue: #point cg@1196: ) cg@1196: #(#MenuItem cg@1196: #activeHelpKey: #drawModeBox cg@1196: #enabled: #imageIsLoaded cg@1637: #label: 'Rect' cg@1637: #translateLabel: true cg@1196: #choice: #editMode cg@1196: #choiceValue: #box cg@1196: ) cg@1196: #(#MenuItem cg@1196: #activeHelpKey: #drawModeFilledBox cg@1196: #enabled: #imageIsLoaded cg@1656: #label: 'Filled Rectangle' cg@1637: #translateLabel: true cg@1196: #choice: #editMode cg@1196: #choiceValue: #filledBox cg@1196: ) cg@1196: #(#MenuItem cg@1196: #activeHelpKey: #drawModeFill cg@1196: #enabled: #imageIsLoaded cg@1637: #label: 'Fill' cg@1637: #translateLabel: true cg@1196: #choice: #editMode cg@1196: #choiceValue: #fill cg@1196: ) cg@1196: #(#MenuItem cg@1196: #activeHelpKey: #drawModeCopy cg@1196: #enabled: #imageIsLoaded cg@1637: #label: 'Copy' cg@1637: #translateLabel: true cg@1196: #choice: #editMode cg@1196: #choiceValue: #copy cg@1196: ) cg@1196: #(#MenuItem cg@1196: #activeHelpKey: #drawModePaste cg@1196: #enabled: #imageIsLoaded cg@1637: #label: 'Paste' cg@1637: #translateLabel: true cg@1196: #choice: #editMode cg@1196: #choiceValue: #paste cg@1196: ) cg@1196: #(#MenuItem cg@1196: #activeHelpKey: #drawModePasteUnder cg@1196: #enabled: #imageIsLoaded cg@1637: #label: 'Paste Under' cg@1637: #translateLabel: true cg@1196: #choice: #editMode cg@1196: #choiceValue: #pasteUnder cg@1196: ) cg@1411: #(#MenuItem cg@1579: #activeHelpKey: #drawModePasteWithMask cg@1579: #enabled: #imageIsLoaded cg@1656: #label: 'Paste with Mask' cg@1637: #translateLabel: true cg@1579: #choice: #editMode cg@1579: #choiceValue: #pasteWithMask cg@1579: ) cg@1579: #(#MenuItem cg@1411: #activeHelpKey: #drawModeSpecial cg@1411: #enabled: #imageIsLoaded cg@1637: #label: 'Special' cg@1637: #translateLabel: true cg@1411: #choice: #editMode cg@1411: #choiceValue: #specialOperation cg@1411: ) cg@1196: ) cg@1196: nil cg@1196: nil tz@400: ) 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@1764: choice: previewBackgroundColor cg@1764: choiceValue: nil cg@1764: ) cg@1764: (MenuItem cg@1764: label: 'Black' cg@1764: translateLabel: true cg@1764: choice: previewBackgroundColor cg@1764: choiceValue: black cg@1764: ) cg@1764: (MenuItem cg@1764: label: 'White' cg@1764: translateLabel: true cg@1764: choice: previewBackgroundColor 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@1774: choice: previewBackgroundColor cg@1774: choiceValue: red cg@1774: ) cg@1774: (MenuItem cg@1774: label: 'Green' cg@1774: translateLabel: true cg@1774: choice: previewBackgroundColor cg@1774: choiceValue: green cg@1774: ) cg@1774: (MenuItem cg@1774: label: 'Blue' cg@1774: translateLabel: true cg@1774: choice: previewBackgroundColor 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@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@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@1637: #(#Menu cg@1637: #( cg@1637: #(#MenuItem cg@1637: #activeHelpKey: #drawModePoint cg@1637: #enabled: #imageIsLoaded cg@1637: #label: 'Point' cg@1637: #translateLabel: true cg@1637: #isButton: true cg@1637: #labelImage: #(#ResourceRetriever #ImageEditor #pointIcon) cg@1637: #choice: #editMode cg@1637: #choiceValue: #point cg@1637: ) cg@1637: #(#MenuItem cg@2375: #activeHelpKey: #drawModeSpray cg@2375: #enabled: #imageIsLoaded cg@2375: #label: 'Spray' cg@2375: #translateLabel: true cg@2375: #isButton: true cg@2375: #labelImage: #(#ResourceRetriever #ImageEditor #sprayIcon) cg@2375: #choice: #editMode cg@2375: #choiceValue: #spray cg@2375: ) cg@2375: #(#MenuItem cg@1637: #activeHelpKey: #drawModeBox cg@1637: #enabled: #imageIsLoaded cg@1637: #label: 'Rect' cg@1637: #translateLabel: true cg@1637: #isButton: true cg@1637: #labelImage: #(#ResourceRetriever #ImageEditor #rectIcon) cg@1637: #choice: #editMode cg@1637: #choiceValue: #box cg@1637: ) cg@1637: #(#MenuItem cg@1637: #activeHelpKey: #drawModeFilledBox cg@1637: #enabled: #imageIsLoaded cg@1637: #label: 'FillRect' cg@1637: #translateLabel: true cg@1637: #isButton: true cg@1637: #labelImage: #(#ResourceRetriever #ImageEditor #fillRectIcon) cg@1637: #choice: #editMode cg@1637: #choiceValue: #filledBox cg@1637: ) cg@1637: #(#MenuItem cg@2375: #activeHelpKey: #drawModeCircle cg@2375: #enabled: #imageIsLoaded cg@2375: #label: 'Circle' cg@2375: #translateLabel: true cg@2375: #isButton: true cg@2375: #labelImage: #(#ResourceRetriever #ImageEditor #circleIcon) cg@2375: #choice: #editMode cg@2375: #choiceValue: #circle cg@2375: ) cg@2375: #(#MenuItem cg@1637: #activeHelpKey: #drawModeFill cg@1637: #enabled: #imageIsLoaded cg@1637: #label: 'Fill' cg@1637: #translateLabel: true cg@1637: #isButton: true cg@1637: #labelImage: #(#ResourceRetriever #ImageEditor #fillIcon) cg@1637: #choice: #editMode cg@1637: #choiceValue: #fill cg@1637: ) cg@1637: #(#MenuItem cg@1637: #activeHelpKey: #drawModeCopy cg@1637: #enabled: #imageIsLoaded cg@1637: #label: 'Copy' cg@1637: #translateLabel: true cg@1637: #isButton: true cg@1637: #labelImage: #(#ResourceRetriever #ImageEditor #copyIcon) cg@1637: #choice: #editMode cg@1637: #choiceValue: #copy cg@1637: ) cg@1637: #(#MenuItem cg@1637: #activeHelpKey: #drawModePaste cg@1637: #enabled: #imageIsLoaded cg@1637: #label: 'Paste' cg@1637: #translateLabel: true cg@1637: #isButton: true cg@1637: #labelImage: #(#ResourceRetriever #ImageEditor #pasteIcon) cg@1637: #choice: #editMode cg@1637: #choiceValue: #paste cg@1637: ) cg@1637: #(#MenuItem cg@1637: #activeHelpKey: #drawModePasteUnder cg@1637: #enabled: #imageIsLoaded cg@1637: #label: 'Paste Under' cg@1637: #translateLabel: true cg@1637: #isButton: true cg@1637: #labelImage: #(#ResourceRetriever #ImageEditor #pasteUnderIcon) cg@1637: #choice: #editMode cg@1637: #choiceValue: #pasteUnder cg@1637: ) cg@1637: #(#MenuItem cg@1637: #activeHelpKey: #drawModePasteWithMask cg@1637: #enabled: #imageIsLoaded cg@1637: #label: 'Paste With Mask' cg@1637: #translateLabel: true cg@1637: #isButton: true cg@1637: #labelImage: #(#ResourceRetriever #ImageEditor #pasteWithMaskIcon) cg@1637: #choice: #editMode cg@1637: #choiceValue: #pasteWithMask cg@1637: ) cg@1637: #(#MenuItem cg@1637: #activeHelpKey: #drawModeSpecial cg@1637: #enabled: #imageIsLoaded cg@1637: #label: 'Special' cg@1637: #translateLabel: true cg@1637: #isButton: true cg@1637: #labelImage: #(#ResourceRetriever #ImageEditor #specialIcon) cg@1637: #choice: #editMode cg@1637: #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@1842: backgroundSelector: theColorItSelf: cg@1842: 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@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@933: hasClassAndSelectorDefined cg@1054: ^ [ cg@1965: |cls| cg@1965: cg@1965: (cls := imageEditView resourceClass) notNil cg@1965: and:[imageEditView resourceSelector notNil] cg@1054: ] cg@933: cg@933: "Created: / 31.7.1998 / 02:02:54 / cg" cg@933: ! cg@933: cg@933: hasClassDefined cg@1054: ^ [ cg@1965: imageEditView resourceClass notNil cg@1054: ] cg@933: cg@933: "Created: / 31.7.1998 / 02:02:22 / cg" cg@933: ! cg@933: cg@1008: hasColormap cg@1008: ^ [self image notNil and:[self image colorMap notNil]] cg@1008: cg@1008: "Created: / 30.9.1998 / 23:53:55 / cg" cg@1008: ! cg@1008: cg@1924: hasNoColormap cg@1924: ^ [self image notNil and:[self image colorMap isNil]] cg@1924: cg@1924: "Created: / 30.9.1998 / 23:53:55 / cg" cg@1924: ! cg@1924: cg@1380: imageHasNextImage cg@1380: "returns whether an image is loaded as value holder" cg@1380: cg@1380: ^ [self image notNil cg@1380: and:[self image imageSequence notNil]] cg@1380: cg@1380: "Created: / 31.7.1998 / 02:04:18 / cg" cg@1380: ! cg@1380: cg@928: imageInfoHolder cg@928: |holder| cg@928: (holder := builder bindingAt:#imageInfoHolder) isNil ifTrue:[ cg@928: builder aspectAt:#imageInfoHolder put:(holder := '' asValue). cg@928: ]. cg@928: ^ holder cg@928: cg@928: "Modified: / 29.7.1998 / 18:32:08 / cg" cg@928: ! cg@928: tz@400: imageIsLoaded tz@767: "returns whether an image is loaded as value holder" tz@400: tz@400: |holder| tz@400: (holder := builder bindingAt:#imageIsLoaded) isNil ifTrue:[ tz@400: builder aspectAt:#imageIsLoaded put:(holder := false asValue). tz@400: ]. tz@400: ^ holder tz@400: ! tz@400: cg@933: imageIsLoadedAndClassDefined cg@933: "returns whether an image is loaded as value holder" cg@933: cg@933: ^ [self hasClassAndSelectorDefined value cg@933: and:[self imageIsLoaded value]] cg@933: cg@933: "Created: / 31.7.1998 / 02:04:18 / 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@1764: previewBackgroundColor cg@1764: |holder| 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@1764: ! cg@1764: 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@1558: tileModeHolder cg@1558: |holder| 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@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@1928: cg@1847: image depth > 12 ifTrue:[ cg@2447: newListOfColors := OrderedCollection new. cg@1904: 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@2054: ] 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@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: [ cg@2446: (newListOfColors contains: [:clr| clr = (Color colorId:0)]) cg@2054: 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@2054: "Modified: / 07-07-2006 / 12:27:43 / cg" tz@767: ! tz@767: 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@1764: changedObject == self previewBackgroundColor 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@2042: imagePreView image:img. 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@1491: self 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@1345: ^ self. cg@1345: ]. cg@1345: tz@942: super update:something with:aParameter from:changedObject tz@942: cg@1345: "Modified: / 10.2.2000 / 23:36:49 / cg" tz@942: ! tz@942: cg@1900: updateColorsFromImage:image cg@1900: |colors| cg@1900: 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@1906: ] cg@1900: ]. cg@1904: self listOfColors contents:(colors asOrderedCollection). cg@1900: ! cg@1900: cg@1054: updateForNoImage tz@767: "updates channels and view, if image is loaded" tz@767: tz@767: self imageIsLoaded value: false. tz@767: self listOfColors removeAll. tz@767: self imagePreView image: nil tz@767: tz@767: tz@767: tz@767: 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@1910: self imageIsLoaded 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@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@1930: self selectionOfColor 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@1449: theColorItSelf:aColor cg@1449: ^ aColor cg@915: ! ! cg@915: 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@2339: |p| cg@2339: cg@2339: anEvent view == self imagePreView ifTrue:[ cg@2339: ((anEvent isButtonPressEvent and:[ anEvent button == 1 ]) cg@2339: or:[ anEvent isButtonMotionEvent and:[ anEvent hasButton1 ]]) ifTrue:[ cg@2339: p := anEvent x @ anEvent y. cg@2546: anEvent view transformation notNil ifTrue:[ cg@2546: p := anEvent view transformation applyInverseTo:p. cg@2546: ]. cg@2339: self imageEditView scrollToMakeVisible:p. cg@2339: ^ true. cg@2339: ]. cg@2339: ]. cg@2339: ^ false. 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@1975: (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" cg@1966: ! cg@1966: cg@1966: updateAfterImageChange cg@1966: |img| cg@1966: cg@1966: (img := self image) notNil ifTrue:[ cg@1966: img := img onDevice:device. cg@1966: self updateColorsFromImage:img. cg@1966: self findColorMapMode. cg@1966: self updateLabelsAndHistory. cg@1966: ] ifFalse:[ cg@1966: self updateForNoImage cg@1966: ] 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@1345: self selectionOfColor 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@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@2546: self imagePreView setImage:(self image) scroll:false invalidate:true. cg@1558: ! ! cg@1558: tz@535: !ImageEditor methodsFor:'queries'! tz@535: 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@1975: cg@1975: mouseButtonColorToolBar := self componentAt:#MouseButtonColorToolBar. cg@1975: (mouseButtonColorToolBar itemAt:button) toggleIndication. cg@1975: mouseButtonColorToolBar do: [:i| i updateIndicators]. 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@1643: self selectionOfColor value:(drawingColormap size). cg@1643: 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@1643: self selectionOfColor 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@1925: light:((clr light * lFactor / 100) "min:100") cg@1925: 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@1403: clearMaskedPixels cg@1403: "clear all masked pixels (to pixelValue 0)" cg@1403: cg@1460: |newImage oldImage| cg@1403: cg@1403: oldImage := self image. cg@1403: cg@1403: imageEditView makeUndo. cg@1403: cg@1403: self withExecuteCursorDo:[ cg@1403: newImage := oldImage clearMaskedPixels. cg@1460: 0 to:newImage height - 1 do:[:y | cg@1460: 0 to:newImage width - 1 do:[:x | cg@1460: (newImage maskAtX:x y:y) == 0 ifTrue:[ cg@1460: newImage pixelAtX:x y:y put:0 cg@1460: ] cg@1460: ] cg@1460: ]. cg@1460: cg@1403: (imageEditView image:newImage) notNil ifTrue:[ cg@1446: self fetchImageData. cg@1403: ] 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@1847: depth := (newColorMap size log:2) asInteger. 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@1935: 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@919: ]. cg@919: cg@919: imageEditView makeUndo. cg@919: cg@2260: newImage := Image newForDepth:depth. cg@1424: newImage depth:depth. cg@2260: newImage photometric:oldImage photometric. cg@2260: cg@919: oldFileName := oldImage fileName. cg@919: cg@1008: Image imageErrorSignal handle:[:ex| 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. cg@919: newImage width:oldImage width height:oldImage height depth:depth. cg@919: newImage colorMap:newColorMap. cg@919: newImage photometric:#palette. cg@919: newImage bits:(ByteArray new:(newImage bytesPerRow * newImage height)). cg@2260: cg@919: oldImage colorsFromX:0 y:0 toX:(oldImage width-1) y:(oldImage height-1) do: cg@919: [:x :y :clr | cg@919: |newColor| cg@919: cg@919: (newColorMap includes:clr) cg@919: ifTrue: [newColor := clr] cg@919: ifFalse: [ cg@1008: newColor := clr nearestIn:newColorMap. cg@1008: useNearest ifFalse:[ cg@1008: (newColor deltaFrom:clr) > 0.5 ifTrue:[ cg@1008: newColor := oldImage colorFromValue:0 cg@1008: ] cg@919: ] cg@919: ]. cg@919: newImage colorAtX:x y:y put:newColor. cg@919: ]. cg@919: image := newImage cg@919: ]. cg@1008: ] do:[ cg@2260: image := newImage fromImage:oldImage. 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:[ cg@1008: maskImage := Depth1Image 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@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@2174: "Modified: / 20-07-2007 / 09:18:59 / 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@2192: light:((clr light * lFactor / 100) "min:100") cg@2192: 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: tz@927: |depth newColorMap newImage oldImage usedColors oldToNew oldBits newBits tmpBits| cg@919: cg@919: oldImage := self image. cg@919: depth := oldImage depth. cg@919: cg@919: oldImage photometric ~~ #palette ifTrue:[ cg@930: self information:'Compress colorMap: Only palette images have colormaps.'. cg@919: ^ self cg@919: ]. cg@919: cg@1403: usedColors := oldImage realUsedColors. cg@919: usedColors size == (1 bitShift:depth) ifTrue:[ cg@930: self information:'Compress colorMap: All colors are used - no compression.'. cg@919: ^ self cg@919: ]. cg@919: usedColors size == oldImage colorMap size ifTrue:[ cg@930: self information:'Compress colorMap: Colormap already compressed - no compression.'. cg@919: ^ self cg@919: ]. cg@919: cg@919: imageEditView makeUndo. cg@919: cg@1949: "/ self information:('Compress colorMap: %1 colors used.' bindWith:usedColors size). cg@919: cg@919: self withExecuteCursorDo:[ cg@996: "/ newColorMap := Array new:usedColors size. cg@919: cg@919: "/ translation table cg@919: oldToNew := ByteArray new:(1 bitShift:depth). cg@919: newColorMap := usedColors asArray. cg@1939: newColorMap sort:self sortBlockForColors. cg@996: cg@919: oldImage colorMap asArray keysAndValuesDo:[:oldIdx :clr | cg@919: |newPixel| cg@919: cg@919: (usedColors includes:clr) ifTrue:[ cg@919: newPixel := newColorMap indexOf:clr. cg@919: oldToNew at:oldIdx put:newPixel-1. cg@919: ] cg@919: ]. cg@919: cg@919: oldBits := oldImage bits. cg@919: newBits := ByteArray new:(oldBits size). cg@919: depth ~~ 8 ifTrue:[ cg@919: "/ expand/compress can only handle 8bits cg@919: tmpBits := ByteArray uninitializedNew:(oldImage width*oldImage height). cg@919: oldBits cg@919: expandPixels:depth cg@919: width:oldImage width cg@919: height:oldImage height cg@919: into:tmpBits cg@919: mapping:oldToNew. cg@919: tmpBits cg@919: compressPixels:depth cg@919: width:oldImage width cg@919: height:oldImage height cg@919: into:newBits cg@919: mapping:nil cg@919: ] ifFalse:[ cg@919: oldBits cg@919: expandPixels:depth cg@919: width:oldImage width cg@919: height:oldImage height cg@919: into:newBits cg@919: mapping:oldToNew. cg@919: ]. cg@919: cg@919: newImage := oldImage species new cg@919: width:oldImage width cg@919: height:oldImage height cg@919: depth:depth cg@919: fromArray:newBits. cg@919: cg@919: newImage colorMap:newColorMap. cg@919: newImage fileName:oldImage fileName. cg@919: newImage mask:(oldImage mask copy). cg@919: cg@919: (imageEditView image:newImage) notNil ifTrue: cg@919: [ cg@1446: self fetchImageData. cg@919: ] cg@919: ] cg@919: cg@919: "Created: / 28.7.1998 / 20:03:11 / cg" cg@996: "Modified: / 15.9.1998 / 17:53:32 / cg" cg@1008: ! cg@1008: cg@1852: copyColorFromColormap ca@1871: imageEditView setClipboardObject:(self selectedColorOrNil) cg@1852: ! cg@1852: cg@1480: copyMask cg@1480: |mask| cg@1480: cg@1480: mask := self image mask. cg@1480: MaskClipboard := mask subImageIn: (0@0 extent:mask extent). cg@1480: ! cg@1480: 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 cg@2054: |ditherColors newImage| cg@2054: cg@2054: depth = 1 ifTrue:[ cg@2054: ditherColors := Array with:(Color black) with:(Color white). cg@2054: ] ifFalse:[ depth = 2 ifTrue:[ cg@2054: ditherColors := Array cg@2054: with:(Color black) cg@2054: with:(Color darkGrey) cg@2054: with:(Color lightGrey) cg@2054: with:(Color white). cg@2054: ] ifFalse:[ depth = 3 ifTrue:[ cg@2054: ditherColors := Color colorCubeWithRed:2 green:2 blue:2. cg@2054: ] ifFalse:[ depth = 4 ifTrue:[ cg@2054: ditherColors := Color vgaColors. cg@2054: ] ifFalse:[ depth = 5 ifTrue:[ cg@2054: ditherColors := Color colorCubeWithRed:4 green:4 blue:2. cg@2054: ] ifFalse:[ depth = 5 ifTrue:[ cg@2054: ditherColors := Color colorCubeWithRed:4 green:4 blue:3. cg@2054: ] ifFalse:[ depth <= 8 ifTrue:[ cg@2054: ditherColors := Color colorCubeWithRed:6 green:6 blue:5. cg@2054: ] ifFalse:[ cg@2073: self error:'unsupported depth'. cg@2054: ]]]]]]]. cg@2054: cg@2054: self withExecuteCursorDo:[ 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@1847: 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@1682: |clrIndex| cg@1682: cg@1682: clrIndex := self selectedColorIndexOrNil. cg@1682: clrIndex isNil ifTrue:[ cg@1544: ^ self cg@1544: ]. cg@1682: (self image colorFromValue:clrIndex-1) inspect cg@1544: ! cg@1544: 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@1682: self processSelectedColorWith:[:clr | clr lightened] cg@1446: ! cg@1446: cg@1446: makeSelectedColorDarker cg@1682: self processSelectedColorWith:[:clr | clr darkened] cg@1446: ! cg@1446: cg@1884: makeSelectedColorGray cg@1884: self processSelectedColorWith:[:clr | Color brightness:(clr brightness)] cg@1884: ! cg@1884: cg@1852: pasteColorIntoColormap cg@1852: |copyBufferColor| cg@1852: ca@1873: copyBufferColor := imageEditView getClipboardObject. cg@1852: copyBufferColor isColor ifFalse:[ cg@2520: UserPreferences current beepInEditor ifTrue:[ cg@2520: self window beep. cg@2520: ]. cg@1852: ^ self cg@1852: ]. cg@1852: cg@1852: self processSelectedColorWith:[:clr | cg@1852: copyBufferColor cg@1852: ] cg@1852: ! cg@1852: cg@1480: 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@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@1852: "undoable color processing: the selected color will be replaced by the cg@1852: value of aBlock" cg@1852: cg@1852: |img cMap modifiedColormap oldColor newImage selectedColorIndex oldSelection newColor| cg@1682: cg@1682: selectedColorIndex := self selectedColorIndexOrNil. cg@1682: selectedColorIndex isNil 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@1852: cg@1852: oldColor := cMap at:selectedColorIndex. cg@1682: imageEditView makeUndo. cg@1682: cg@1847: modifiedColormap := cMap asArray copy. cg@1852: cg@1852: newColor := aBlock value:oldColor. cg@1859: modifiedColormap at:selectedColorIndex put:newColor. 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: oldSelection := self selectionOfColor value. cg@1682: cg@1682: (imageEditView image:newImage) notNil ifTrue:[ cg@1682: self fetchImageData. cg@1682: ]. cg@1682: self selectionOfColor value:oldSelection. cg@1682: cg@1682: "Created: / 12.3.1999 / 00:20:28 / cg" cg@1682: "Modified: / 16.3.1999 / 21:57:26 / cg" cg@1682: ! cg@1682: cg@1124: reduceNumberOfColors cg@1727: |s n anyChange img usedColors| cg@1124: cg@1124: s := Dialog request:'Number of color bits to strip (1-7) ?'. 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@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@1934: image := self image. cg@2054: "/ usedColors := image usedColorsMax:4096. cg@1934: imageEditView makeUndo. cg@1934: cg@1934: newImage := image copy. cg@2260: newImage photometric == #palette ifTrue:[ cg@2260: newImage colorMap:(OrderedCollection new). cg@2260: ]. cg@2260: cg@1934: image cg@1934: colorsFromX:0 y:0 toX:(image width-1) y:(image height-1) cg@1934: do:[:x :y :clr | cg@1934: |r g b nr ng nb newClr| 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@1934: newClr := Color redByte:nr greenByte:ng blueByte:nb. cg@2260: newImage photometric == #palette ifTrue:[ cg@2260: (newImage colorMap includes:newClr) ifFalse:[ cg@2260: newImage colorMap add:newClr cg@2260: ]. cg@2260: ]. cg@1934: newImage colorAtX:x y:y put:newClr cg@1934: ]. cg@1934: 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@2446: aColor == Color noColor ifTrue:[ cg@2446: img mask notNil ifTrue:[ cg@2446: idx := 1. cg@2446: ] cg@2446: ] ifFalse:[ cg@2446: (img := self image) notNil ifTrue:[ 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@2446: self selectionOfColor value:idx. cg@2446: ! cg@2446: cg@1682: selectedColorIndexOrNil cg@1682: | img clrIndex| cg@1682: cg@1682: img := self image. cg@1682: img isNil ifTrue:[ cg@1682: 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@1939: self cg@1939: sortColorMapWith:self sortBlockForColors cg@1939: ! cg@1939: cg@1939: sortColorMapWith:sortBlock cg@1939: "calculates a new color map for the image, sorting colors" cg@1939: cg@1008: |depth newColorMap newImage oldImage usedColors oldToNew oldBits newBits tmpBits| cg@1008: cg@1008: oldImage := self image. cg@1008: depth := oldImage depth. cg@1008: cg@1008: oldImage photometric ~~ #palette ifTrue:[ cg@1008: self information:'Compress colorMap: Only palette images have colormaps.'. cg@1008: ^ self cg@1008: ]. cg@1008: cg@1008: usedColors := oldImage realColorMap. cg@1008: cg@1008: imageEditView makeUndo. cg@1008: cg@1008: self withExecuteCursorDo:[ cg@1008: "/ newColorMap := Array new:usedColors size. cg@1008: cg@1008: "/ translation table cg@1008: oldToNew := ByteArray new:(1 bitShift:depth). cg@1008: newColorMap := usedColors asArray. cg@1939: newColorMap sort:sortBlock. cg@1008: cg@1008: oldImage colorMap asArray keysAndValuesDo:[:oldIdx :clr | cg@1008: |newPixel| cg@1008: cg@1008: (usedColors includes:clr) ifTrue:[ cg@1008: newPixel := newColorMap indexOf:clr. cg@1008: oldToNew at:oldIdx put:newPixel-1. cg@1008: ] cg@1008: ]. cg@1008: cg@1008: oldBits := oldImage bits. cg@1008: newBits := ByteArray new:(oldBits size). cg@1008: depth ~~ 8 ifTrue:[ cg@1008: "/ expand/compress can only handle 8bits cg@1008: tmpBits := ByteArray uninitializedNew:(oldImage width*oldImage height). cg@1008: oldBits cg@1008: expandPixels:depth cg@1008: width:oldImage width cg@1008: height:oldImage height cg@1008: into:tmpBits cg@1008: mapping:oldToNew. cg@1008: tmpBits cg@1008: compressPixels:depth cg@1008: width:oldImage width cg@1008: height:oldImage height cg@1008: into:newBits cg@1008: mapping:nil cg@1008: ] ifFalse:[ cg@1008: oldBits cg@1008: expandPixels:depth cg@1008: width:oldImage width cg@1008: height:oldImage height cg@1008: into:newBits cg@1008: mapping:oldToNew. cg@1008: ]. cg@1008: cg@1008: newImage := oldImage species new cg@1008: width:oldImage width cg@1008: height:oldImage height cg@1008: depth:depth cg@1008: fromArray:newBits. cg@1008: cg@1008: newImage colorMap:newColorMap. cg@1008: newImage fileName:oldImage fileName. cg@1008: newImage mask:(oldImage mask copy). cg@1008: cg@1054: (imageEditView image:newImage) notNil ifTrue:[ cg@1446: self fetchImageData. cg@1008: ] 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@1975: 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@1488: UserPreferences systemBrowserClass 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@1975: 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@2196: |text tempForm tempImage maskImage font w h| 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@2196: tempImage cg@2196: photometric:#palette; cg@2196: colorMap:(Array with:Color white with:imageEditView selectedColor); 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@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@1479: newSize isPoint ifFalse:[ cg@1479: self warn:'please enter the new size as ''x @ y''.'. cg@1479: ^ self. cg@1479: ]. cg@1479: imageEditView magnifyImageTo:newSize. 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@2260: |box oldSize newSize scaleString scale image| cg@1479: cg@1479: image := imageEditView image. cg@1479: oldSize := image extent. cg@1479: cg@2260: 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@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@1353: imageEditView magnifyImageTo:newSize. 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@915: (mag := magHolder value) < 99 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@1975: 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@1353: |box rotation| cg@1353: cg@1353: box := EnterBox new. cg@1353: box title:(resources string:'Rotate by (degrees, clockwise):'). cg@1353: box okText:(resources string:'OK'). cg@1353: box abortText:(resources string:'Cancel'). cg@1353: box initialText: '0'. cg@1353: box showAtPointer. cg@2196: (box accepted and: [(rotation := Number readFromString: box contents onError:nil) notNil]) cg@1353: ifTrue:[ cg@1353: imageEditView rotateImageBy:rotation. cg@1558: self updateInfoLabel. cg@1353: ]. cg@2196: cg@2196: "Modified: / 11-11-2007 / 13:21:11 / 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. tz@400: ! ! tz@400: 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@1922: |img file filters| 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@1353: filters := FileSelectionBrowser loadImageFileNameFilters. cg@1353: cg@1353: file notNil ifTrue:[ cg@1353: file := FileSelectionBrowser cg@1353: request:'Load Image From' cg@1353: fileName:file cg@1353: withFileFilters:filters. cg@1353: ] ifFalse:[ cg@1353: file := FileSelectionBrowser cg@1353: request:'Load Image From' cg@1922: inDirectory:LastDirectory cg@1353: withFileFilters:filters. cg@1353: ]. cg@1353: file notNil ifTrue:[ cg@1353: LastDirectory := file asFilename directoryName. cg@1353: self loadFromFile:file cg@1353: ] tz@400: ! tz@400: 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:[ tz@767: image mask: (Depth1Image width: width height: height depth: 1 fromArray: (ByteArray new: width*height)) clearMaskedPixels 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@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@929: grabScreenImage cg@929: "let user choose an area and grab that are for editing" cg@929: 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@990: image := Image fromUser. cg@1121: image isNil ifFalse:[ cg@1121: image depth > 8 ifTrue:[ cg@2420: false ifTrue:[ sv@1687: Error handle:[:ex | |sig| cg@1537: (sig := ex signal) == 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@1380: nextImageInSequence cg@1380: "display the next image in the image sequence" cg@1383: |img seq frame listOfColors| cg@1380: cg@1380: imageEditView releaseUndos. cg@1380: cg@1380: seq := self image imageSequence. cg@1380: imageSeqNr isNil ifTrue:[ cg@1380: imageSeqNr := 1. cg@1380: ]. cg@1380: imageSeqNr := imageSeqNr + 1. cg@1380: imageSeqNr > seq size ifTrue:[ cg@1380: self information:'Back to first image in sequence'. cg@1380: imageSeqNr := 1. cg@1380: ]. cg@1380: frame := seq at:imageSeqNr. cg@1380: imageEditView image:(frame image). cg@1380: cg@1380: (img := self image) notNil ifTrue:[ cg@1383: listOfColors := self listOfColors. cg@1380: img colorMap notNil ifTrue:[ cg@1383: listOfColors contents:(img usedColors asSet asOrderedCollection). cg@1380: ] ifFalse:[ cg@1383: listOfColors removeAll. cg@1380: ]. cg@1380: self findColorMapMode. cg@1380: self updateLabelsAndHistory. cg@1380: img := img onDevice:device. cg@1380: imageEditView image:img. cg@1380: ] ifFalse:[ cg@1380: self updateForNoImage cg@1380: ]. cg@1380: 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@1922: filters := FileSelectionBrowser loadImageFileNameFilters. cg@1922: cg@1922: file notNil ifTrue:[ cg@1922: file := FileSelectionBrowser cg@1922: request:'Save Image To' cg@1922: fileName:file cg@1922: withFileFilters:filters. cg@1922: ] ifFalse:[ cg@1922: file := FileSelectionBrowser cg@1922: request:'Save Image To' cg@1922: inDirectory:LastDirectory cg@1922: withFileFilters:filters. 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: ] 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@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@2375: spraySpot:n cg@2375: imageEditView spraySpot:n cg@2375: cg@2375: "Created: / 01-11-2007 / 23:47:48 / cg" cg@1353: ! ! cg@1353: tz@400: !ImageEditor class methodsFor:'documentation'! tz@400: tz@400: version tz@400: ^ '$Header$' tz@400: ! !