cg@3650: "{ Encoding: utf8 }" cg@3650: tz@400: " tz@767: COPYRIGHT (c) 1997-1998 by eXept Software AG tz@400: All Rights Reserved tz@400: tz@400: This software is furnished under a license and may be used tz@400: only in accordance with the terms of that license and with the tz@405: inclusion of the above copyright notice. This software may not tz@400: be provided or otherwise made available to, or used by, any tz@405: other person. No title to or ownership of the software is tz@400: hereby transferred. tz@400: " cg@1376: "{ Package: 'stx:libtool2' }" cg@1376: cg@3180: "{ NameSpace: Smalltalk }" cg@3180: cg@1975: ResourceSpecEditor subclass:#ImageEditor tz@975: instanceVariableNames:'imageEditView colorMapMode editMode mouseKeyColorMode cg@1960: selectedColorIndex postOpenAction imageSeqNr drawingColormap cg@2767: lastShiftUsedWrap lastGrabbedScreenArea cg@3379: allowedToChangeImageDimensionAndDepth savedImage savedFile' cg@3416: classVariableNames:'DefaultRelativeSizes LastColormapMode LastDirectory cg@3497: LastSizeString LastURL MaskClipboard LastDepth cg@3550: LastNumThresholdGrayColors LastMagnifyTo LastMagnifyBy cg@3550: LastMagnifySmoothing' 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. cg@3375: It is also used subclasses as a tool to post-process captured screen images and cg@3375: bitmaps in expecco. tz@400: cg@3530: The actual drawing functionality is found in ImageEditView; cg@3530: the code here (an appModel) provides nice menus, previews, colormap manipulation etc. cg@3530: tz@400: [start with:] tz@400: ImageEditor open tz@941: ImageEditor openOnClass:Icon andSelector:#startIcon cg@3466: (Image fromFile:'../../goodies/bitmaps/gifImages/garfield.gif') edit cg@3466: (Image fromScreen:(0@0 corner:100@100)) edit tz@400: tz@400: [see also:] tz@400: ImageEditView Image tz@400: tz@400: [author:] tz@544: Thomas Zwick, eXept Software AG cg@1806: Claus Gittinger, eXept Software AG tz@400: " tz@400: ! ! tz@400: tz@400: !ImageEditor class methodsFor:'instance creation'! tz@400: sv@3357: openLoadingImageWith:aBlock modal:modalBoolean cg@3376: "opens an Image Editor on anImage. cg@3427: Returns the editor (to access its attributes)" cg@1975: cg@1975: |editor| cg@1975: cg@1975: editor := self new. cg@1975: editor allButOpen. cg@1975: aBlock value:editor. sv@3357: modalBoolean ifTrue:[ sv@3357: editor openWindowModal. sv@3357: ] ifFalse:[ sv@3357: editor openWindow. sv@3357: ]. cg@2764: ^ editor cg@3427: cg@3427: "Modified (comment): / 07-03-2017 / 16:36:16 / cg" cg@1975: ! cg@1975: tz@400: openModalOnClass: aClass andSelector: aSelector cg@1975: "opens a modal Image Editor on aClass and aSelector. cg@1975: Returns the real name of the edited resource method (in case, user changed it)." cg@1975: cg@1975: |imageEditor imageEditView className resourceClass resourceSelector| tz@767: tz@400: imageEditor := self new. tz@767: tz@900: aClass isClass ifTrue: [className := aClass name]. tz@900: aClass isString ifTrue: [className := aClass]. tz@903: aClass isNil ifTrue: [className := '']. tz@400: cg@2764: imageEditor postOpenAction: [ cg@2764: imageEditView := imageEditor imageEditView. cg@2764: imageEditor loadFromOrPrepareForClass: aClass andSelector: aSelector cg@2764: ]. tz@400: imageEditor openModal. tz@400: cg@1975: resourceClass := imageEditView resourceClass. cg@1975: resourceSelector := imageEditView resourceSelector. cg@1975: cg@1975: (resourceClass isNil or:[resourceSelector isNil]) ifTrue:[^ nil]. cg@1975: ^ Array with:resourceClass with:resourceSelector cg@1966: cg@1966: " cg@1966: self openModalOnClass: self andSelector: #leftMouseKeyIcon cg@1966: " tz@400: ! tz@400: sv@3357: openModalOnFile:aFileName cg@3427: "opens an Image Editor on aFileName. cg@3427: Returns the editor (to access its attributes)" cg@3427: cg@3427: ^ self openOnFile:aFileName modal:true sv@3357: sv@3357: " sv@3357: self openModalOnFile: '../../goodies/bitmaps/gifImages/back.gif' sv@3357: " cg@3411: cg@3427: "Modified: / 07-03-2017 / 16:36:32 / cg" sv@3357: ! sv@3357: cg@2764: openModalOnImage:anImage cg@2764: "opens a modal Image Editor on an image. cg@2764: Returns the modified image or nil if unsaved/unchanged" cg@2764: cg@2764: |imageEditor imageEditView newImage| cg@2764: cg@2764: imageEditor := self new. cg@2767: imageEditor allowedToChangeImageDimensionAndDepth:false. cg@2764: imageEditor postOpenAction: [ cg@2764: imageEditView := imageEditor imageEditView. cg@2764: imageEditor loadFromImage: anImage cg@2764: ]. cg@2764: imageEditor openModal. cg@2764: cg@2766: newImage := imageEditor savedImage. cg@2764: ^ newImage cg@2764: ! cg@2764: cg@1966: openOnClass:aClass andSelector:aSelector cg@3427: "opens an Image Editor on aClass and aSelector. cg@3427: Returns the editor (to access its attributes)" cg@3427: cg@3427: ^ self openOnClass:aClass andSelector:aSelector modal:false cg@1057: cg@1966: " cg@1966: self openOnClass:self andSelector:#leftMouseKeyIcon cg@1966: self openOnClass:self andSelector:nil cg@1966: " cg@1966: cg@3427: "Modified: / 07-03-2017 / 16:36:58 / cg" cg@3427: ! cg@3427: cg@3427: openOnClass:aClass andSelector:aSelector modal:modal cg@3427: "opens an Image Editor on aClass and aSelector. cg@3427: Returns the editor (to access its attributes)" cg@3427: cg@3427: ^ self cg@3427: openLoadingImageWith:[:editor | cg@3427: editor loadFromClass:(aClass theNonMetaclass) andSelector:aSelector cg@3427: ] cg@3427: modal:modal. cg@3427: cg@3427: " cg@3427: self openOnClass:self andSelector:#leftMouseKeyIcon modal:true cg@3427: self openOnClass:self andSelector:nil cg@3427: " cg@3427: cg@3427: "Created: / 07-03-2017 / 16:34:36 / cg" tz@400: ! tz@400: cg@1966: openOnFile:aFileName cg@3427: "opens an Image Editor on aFileName. cg@3427: Returns the editor (to access its attributes)" cg@3427: cg@3427: ^ self openOnFile:aFileName modal:false cg@1057: cg@1966: " cg@1975: self openOnFile: '../../goodies/bitmaps/gifImages/back.gif' cg@1966: " cg@1966: cg@3427: "Modified: / 07-03-2017 / 16:37:33 / cg" cg@3427: ! cg@3427: cg@3427: openOnFile:aFileName modal:modal cg@3427: "opens an Image Editor on aFileName. cg@3427: Returns the editor (to access its attributes)" cg@3427: cg@3427: ^ self cg@3427: openLoadingImageWith:[:editor | cg@3427: editor loadFromFile:aFileName. cg@3427: ] cg@3427: modal:modal. cg@3427: cg@3427: " cg@3427: self openOnFile: '../../goodies/bitmaps/gifImages/back.gif' modal:false cg@3427: self openOnFile: '../../goodies/bitmaps/gifImages/back.gif' modal:true cg@3427: " cg@3427: cg@3427: "Created: / 07-03-2017 / 16:33:12 / cg" tz@400: ! tz@400: cg@1966: openOnImage:anImage cg@3427: "opens an Image Editor on anImage. cg@3427: Returns the editor (to access its attributes)" cg@3427: cg@3427: ^ self cg@3375: openLoadingImageWith:[:editor | editor loadFromImage: anImage ] cg@3375: modal:false cg@1053: cg@1966: " cg@1966: self openOnImage: Icon startIcon cg@1966: " cg@1966: cg@3427: "Modified: / 07-03-2017 / 16:37:57 / cg" tz@400: ! ! tz@400: tz@400: !ImageEditor class methodsFor:'accessing'! tz@400: tz@400: listOfColorMaps tz@767: "returns the list of default color maps for a new image" tz@400: tz@400: |colorMap| tz@898: tz@400: (colorMap := OrderedCollection new) tz@400: add: Color black; tz@400: add: Color white; tz@400: add: Color red; tz@400: add: Color green; tz@400: add: Color blue; tz@400: add: Color cyan; tz@400: add: Color yellow; tz@400: add: Color magenta; tz@898: add: (Color redByte: 127 greenByte: 0 blueByte: 0); tz@898: add: (Color redByte: 0 greenByte: 127 blueByte: 0); tz@898: add: (Color redByte: 0 greenByte: 0 blueByte: 127); tz@898: add: (Color redByte: 0 greenByte: 127 blueByte: 127); tz@898: add: (Color redByte: 127 greenByte: 127 blueByte: 0); tz@898: add: (Color redByte: 127 greenByte: 0 blueByte: 127); tz@898: add: (Color redByte: 127 greenByte: 127 blueByte: 127); tz@898: add: (Color redByte: 170 greenByte: 170 blueByte: 170). tz@898: cg@3346: 0 to: 5 do: [:r| cg@3346: 0 to: 5 do: [:g| cg@3346: 0 to: 5 do: [:b| tz@898: colorMap add: (Color redByte: (r*255//5) ceiling greenByte: (g*255//5) ceiling blueByte: (b*255//5) ceiling) tz@400: ] tz@400: ] tz@400: ]. tz@400: cg@3346: 1 to: 25 do: [:g| tz@898: colorMap add: (Color redByte: (g*255//26) ceiling greenByte: (g*255//26) ceiling blueByte: (g*255//26) ceiling) tz@400: ]. tz@400: cg@1847: ^ Dictionary new cg@2571: at: #depth32 put:(FixedPalette redShift:16 redMask:16rFF greenShift:8 greenMask:16rFF blueShift:0 blueMask:16rFF); cg@1847: at: #depth24 put:(FixedPalette redShift:16 redMask:16rFF greenShift:8 greenMask:16rFF blueShift:0 blueMask:16rFF); cg@1847: at: #masked24 put:(FixedPalette redShift:16 redMask:16rFF greenShift:8 greenMask:16rFF blueShift:0 blueMask:16rFF); cg@1847: at: #depth16 put:(FixedPalette redShift:11 redMask:16r1F greenShift:5 greenMask:16r3F blueShift:0 blueMask:16r1F); cg@1847: at: #masked16 put:(FixedPalette redShift:11 redMask:16r1F greenShift:5 greenMask:16r3F blueShift:0 blueMask:16r1F); cg@1847: at: #depth8 put: colorMap; cg@1847: at: #masked8 put: colorMap; cg@1847: at: #depth4 put: (colorMap copyFrom: 1 to: 16); cg@1847: at: #masked4 put: (colorMap copyFrom: 1 to: 16); cg@1847: at: #depth2 put: (colorMap copyFrom: 1 to: 4); cg@1847: at: #masked2 put: (colorMap copyFrom: 1 to: 4); cg@1847: at: #depth1 put: (colorMap copyFrom: 1 to: 2); cg@1847: at: #masked1 put: (colorMap copyFrom: 1 to: 2); tz@400: yourself tz@400: ! tz@400: tz@400: listOfDefaultSizes tz@767: "returns the list of default sizes for a new image" tz@400: cg@1960: ^ #('8x8' '16x16' '22x22' '32x32' '48x48' '64x64') cg@932: cg@932: "Modified: / 31.7.1998 / 01:57:34 / cg" cg@1847: ! cg@1847: cg@1847: namesOfColorMaps cg@1847: ^ Dictionary new cg@2571: at: #depth32 put: '32-plane (rgba)'; cg@1847: at: #depth24 put: '24-plane'; cg@1847: at: #masked24 put: '24-plane + mask'; cg@1847: at: #depth16 put: '16-plane'; cg@1847: at: #masked16 put: '16-plane + mask'; cg@1847: at: #depth8 put: ' 8-plane'; cg@1847: at: #masked8 put: ' 8-plane + mask'; cg@1847: at: #depth4 put: ' 4-plane'; cg@1847: at: #masked4 put: ' 4-plane + mask'; cg@1847: at: #depth2 put: ' 2-plane'; cg@1847: at: #masked2 put: ' 2-plane + mask'; cg@1847: at: #depth1 put: ' 1-plane'; cg@1847: at: #masked1 put: ' 1-plane + mask' ; cg@1847: yourself tz@400: ! ! tz@400: tz@460: !ImageEditor class methodsFor:'help specs'! tz@460: cg@3644: helpSpec cg@2871: "This resource specification was automatically generated cg@2871: by the UIHelpTool of ST/X." cg@2871: cg@2871: "Do not manually edit this!! If it is corrupted, cg@2871: the UIHelpTool may not be able to read the specification." cg@2871: cg@2871: " cg@3408: UIHelpTool openOnClass:ImageEditor cg@2871: " cg@2871: cg@2871: cg@2871: cg@3644: ^super helpSpec addPairsFrom: #( cg@2871: cg@3417: #autoCropAll cg@3417: 'Find and remove all borders' cg@3417: cg@3417: #autoCropBottom cg@3417: 'Find and remove bottom border' cg@3417: cg@3417: #autoCropLeft cg@3417: 'Find and remove left border' cg@3417: cg@3417: #autoCropRight cg@3417: 'Find and remove right border' cg@3417: cg@3417: #autoCropTop cg@3417: 'Find and remove top border' cg@3417: tz@460: #colorMap cg@2765: 'ColorMap functions' cg@929: cg@929: #colorMap1 cg@2765: 'Convert to depth-1 image' cg@929: cg@986: #colorMap1M cg@2765: 'Convert to depth-1 image plus mask' cg@986: cg@929: #colorMap2 cg@2765: 'Convert to depth-2 image' cg@2765: cg@2765: #colorMap24 cg@2765: 'Convert to depth-24 image (rgb)' cg@929: cg@986: #colorMap2M cg@2765: 'Convert to depth-2 image plus mask' cg@2765: cg@2765: #colorMap32 cg@2765: 'Convert to depth-32 image (rgba)' cg@986: cg@929: #colorMap4 cg@2765: 'Convert to depth-4 image' cg@929: cg@986: #colorMap4M cg@2765: 'Convert to depth-4 image plus mask' cg@986: cg@929: #colorMap8 cg@2765: 'Convert to depth-8 image' cg@929: cg@929: #colorMap8M cg@2765: 'Convert to depth-8 image plus mask' cg@2571: cg@986: #colorMapTable cg@2765: 'Shows a list of used colors of the image' cg@986: cg@929: #compressColormap cg@2765: 'Remove unneeded entries from the colorMap' tz@460: cg@1045: #cropAll cg@3417: 'Crop (cut off) all four sides by the amounts entered into the above fields.' cg@986: cg@1045: #cropBottom cg@3417: 'Cut off the specified number of pixels at the bottom' cg@3417: cg@3417: #cropBySelectingArea cg@3417: 'Select new area in the right detail view.' cg@986: cg@1045: #cropLeft cg@3417: 'Cut off the specified number of pixels at the left' cg@986: cg@1045: #cropManual cg@986: 'Specify border(s) to remove.' cg@986: cg@1045: #cropRight cg@3417: 'Cut off the specified number of pixels at the right' cg@986: cg@1045: #cropTop cg@3417: 'Cut off the specified number of pixels at the top' cg@3417: cg@3417: #cropubImage cg@3417: 'Select a subarea as the image''s new dimension' tz@487: tz@460: #drawModeBox cg@2765: 'Rectangle Drawing Mode' tz@460: cg@2375: #drawModeCircle cg@2765: 'Circle Drawing Mode' cg@2375: tz@460: #drawModeCopy cg@2765: 'Area Copy Mode' tz@460: cg@3423: #drawModeCropSubImage cg@3423: 'Select and extract a subimage' cg@3423: tz@460: #drawModeFill cg@2765: 'Flood Fill Mode' tz@460: tz@460: #drawModeFilledBox cg@2765: 'Filled Rectangle Drawing Mode' tz@460: cg@3408: #drawModeFilledCircle cg@3408: 'Filled Circle Drawing Mode' cg@3408: cg@3408: #drawModeMaskOutsideCircle cg@3408: 'Mask everything outside a Circle' cg@3408: cg@3408: #drawModeMaskOutsideRectangle cg@3408: 'Mask everything outside a Rectangle' cg@3408: tz@460: #drawModePaste cg@3512: 'Paste-Over Mode (only paste pixels; keep mask as is)' cg@914: cg@3562: #drawModePasteMasked cg@3562: 'Paste-Under Mode (only paste previously masked pixels)' cg@3562: cg@914: #drawModePasteUnder cg@3561: 'Paste-Under Mode (only paste previously masked pixels where the new pixel is also masked)' cg@3561: cg@1637: #drawModePasteWithMask cg@3512: 'Paste-with-Mask Mode (both pixel and mask are pasted)' tz@460: tz@460: #drawModePoint cg@2765: 'Point Drawing Mode' cg@2375: cg@1639: #drawModeSpecial cg@2871: 'Special operations (select rectangle, then choose operation)' cg@1639: cg@2765: #drawModeSpray cg@2765: 'Spray Drawing Mode' cg@2765: cg@3562: #drawingAlpha cg@3562: 'The alpha value (in percent) to be used in edit operations.\If the "mask"-color is selected, only the alpha value will be changed.\Otherwise, the selected color plus this alpha value will be used for drawing' cg@3562: cg@3562: #drawingColor1 cg@3562: 'The color associated to the left mouse button.\Also the color used in fill operations' cg@3562: cg@3562: #drawingColor2 cg@3562: 'The color associated to the right mouse button.\Also the second color used in gradient fill operations' cg@3562: cg@3408: #edit3DProjection cg@3408: 'Generate a 3D projection' cg@3408: tz@460: #editFlipHorizontal cg@2765: 'Flip the image horizontally' tz@460: tz@460: #editFlipVertical cg@2765: 'Flip the image vertically' tz@460: tz@460: #editMagnifyImage cg@2765: 'Magnify the image' tz@460: tz@460: #editNegate cg@2765: 'Invert the images colors' tz@460: tz@460: #editResize cg@2765: 'Resize the image (preserving the old image)' tz@460: tz@460: #editRotate cg@2765: 'Rotate the image' tz@460: cg@3408: #fileEditMask cg@3408: 'Load Mask from a File' cg@3408: cg@2701: #fileGrabImageFromScreen cg@2765: 'Pick an image from the screen (specify area)' cg@2701: cg@2701: #fileGrabImageFromWindow cg@2765: 'Pick an image from a window on the screen (click on window)' cg@929: tz@460: #fileLoadFromClass cg@2765: 'Select and load an image from a resource method' tz@460: tz@460: #fileLoadFromFile cg@2765: 'Select and load an image from a file' tz@460: cg@2796: #fileLoadFromURL cg@2796: 'Load an image from the net, given its URL' cg@2796: tz@460: #fileNewImage cg@914: 'Create a new image' tz@460: cg@3200: #fileNewImageFromClipboard cg@3200: 'Create a new image and initialize it from the clipboard' cg@3200: cg@3200: #fileNewMaskFromClipboard cg@3200: 'Paste the image in the clipboard as a mask. Must be a depth-1 image' cg@3200: tz@460: #filePrint cg@3417: 'Print the image on a postscript printer' cg@3408: cg@3408: #filePrint cg@3417: 'Print' cg@2765: cg@2765: #fileSave cg@2765: 'Save the image' tz@460: tz@460: #fileSaveAs cg@2765: 'Save the image to a file' cg@2765: cg@2765: #fileSaveButtonImageAs cg@2765: 'Save an image of a button with the image to a file (for html use)' tz@460: tz@460: #fileSaveMaskAs cg@2765: 'Save the mask of the image to a file' ca@1613: tz@460: #fileSaveMethod cg@2765: 'Save the image as resource method in the current class and selector' tz@460: tz@460: #fileSaveMethodAs cg@2765: 'Save the image as resource method in a class' tz@460: cg@3408: #floodFillMaxError cg@3433: 'Specify the max. allowed deviation from the clicked pixel in a flood-fill operation.\Pixels where the hue/light values differ less than that fraction\will be included in the fill.\The range must be between 0 and 1. With 0, only areas with exactly the same pixel will be filled.\With 1, every other pixel is included.\\When filling gradiented areas, start with small values, such as 0.05, and increase slowly (undo and try with higher value).\This is especially useful when masking background areas from screenshots.' cg@3408: cg@3562: #hueShift cg@3562: '' cg@3562: cg@3562: #lightFactor cg@3562: '' cg@3562: cg@3408: #magnificationNumber cg@3408: 'Shows the current magnification' cg@3408: cg@3408: #magnifyImageDown cg@3408: 'Decrease magnification' cg@3408: cg@3408: #magnifyImageUp cg@3408: 'Increase magnification' cg@3408: cg@3408: #mouseKeyColorMode cg@3408: 'Toggle between left and right mouse button color' cg@3408: cg@3408: #nextImageInSequence cg@3408: 'Go to the next image in the animated gif image sequence.' cg@3408: cg@3408: #previewView cg@3408: 'Shows a preview of the image' cg@3408: cg@3408: #previousImageInSequence cg@3408: 'Go to the previous image in the animated gif image sequence.' cg@3408: cg@3562: #resetHueShift cg@3562: 'Reset the hue shift to zero (for unchanged hue)' cg@3562: cg@3562: #resetLightFactor cg@3562: 'Reset the light factor to 1 (for unchanged brightness)' cg@3562: cg@3562: #resetSaturationFactor cg@3562: 'Reset the saturation factor to 1 (for unchanged saturation)' cg@3562: cg@3562: #saturationFactor cg@3562: '' cg@3562: cg@3408: #settingsGridMagnification cg@3408: 'Change the grid magnification of the edit view' cg@3408: cg@3408: #xdrawModeBox cg@3408: 'Rectangle' cg@3408: cg@3408: #xdrawModeCopy cg@3408: 'Copy' cg@3408: cg@3408: #xdrawModeFill cg@3408: 'Flood-fill' cg@3408: cg@3408: #xdrawModeFilledBox cg@3408: 'Filled rectangle' cg@3408: cg@3408: #xdrawModePaste cg@3408: 'Paste' cg@3408: cg@3408: #xdrawModePasteUnder cg@3408: 'Paste under' cg@3408: cg@3408: #xdrawModePasteWithMask cg@3408: 'Paste with Mask' cg@3408: cg@3408: #xdrawModePoint cg@3408: 'Point' cg@3408: cg@3408: #xfileGrabImage cg@3408: 'Pick from screen' cg@3408: cg@3408: #xfileLoadFromClass cg@3408: 'Load from method...' cg@3408: cg@3408: #xfileLoadFromFile cg@3408: 'Load from file...' cg@3408: cg@3408: #xfileNewImage cg@3408: 'New image' cg@3408: cg@3408: #xfileSaveAs cg@3408: 'Save to file...' cg@3408: cg@3408: #xfileSaveMaskAs cg@3408: 'Save mask to file...' cg@3408: cg@3408: #xfileSaveMethod cg@3408: 'Save as method' cg@3408: cg@3408: #xfileSaveMethodAs cg@3408: 'Save as Method...' cg@3405: tz@460: ) cg@2871: cg@3513: "Modified: / 16-02-2017 / 12:30:55 / cg" cg@3644: "Modified: / 28-02-2019 / 11:57:39 / Claus Gittinger" tz@460: ! ! tz@460: tz@737: !ImageEditor class methodsFor:'image specs'! tz@737: cg@3419: brighterIcon cg@3419: "This resource specification was automatically generated cg@3419: by the ImageEditor of ST/X." cg@3419: cg@3419: "Do not manually edit this!! If it is corrupted, cg@3419: the ImageEditor may not be able to read the specification." cg@3419: cg@3419: " cg@3419: self brighterIcon inspect cg@3419: ImageEditor openOnClass:self andSelector:#brighterIcon cg@3419: Icon flushCachedIcons cg@3419: " cg@3419: cg@3419: cg@3419: cg@3419: ^Icon cg@3419: constantNamed:'ImageEditor class brighterIcon' cg@3419: ifAbsentPut:[(Depth8Image width:14 height:14) bits:(ByteArray fromPackedString:' cg@3419: @PDA@PDA@PDA@PDA@PG%9^W%9^W%;>?/;>?/;>W%9^W%9^W/;>?/;>?/9^W%9^W%A [/;>?/;>?%9^W%9^TFA.?/;>?/;>W%9^W%9PXF;>?/;>?/9^W%A XF cg@3419: A XFA [/;>?%9^TFA XFA XFA.?/;>W%9^W%9PXF;>?/;>?/9^W%9^W%A [/;>?/;>?%9^W%9^TFA.?/;>?/;>W%9^W%9^W/;>?/;>?/9^W%9^W%9^?/;>?/ cg@3419: ;> cg@3442: cg@3442: ^Icon cg@3442: constantNamed:'ImageEditor class circleIcon' cg@3442: ifAbsentPut:[(Depth1Image width:14 height:14) bits:(ByteArray fromPackedString:'@@@@@@QAAD@@@C@X@@@@@@@CLA @@@Q@AD@@@@@a') cg@3442: colorMapFromArray:#[0 0 0 127 127 127] cg@3442: mask:((ImageMask width:14 height:14) bits:(ByteArray fromPackedString:'@@@@@@_@CF@PDC@XH@ BB@HLA PD@1 A<@@@@@a'); yourself); yourself] cg@2272: ! cg@2272: cg@1637: copyIcon sv@3121: cg@1637: "This resource specification was automatically generated cg@1637: by the ImageEditor of ST/X." cg@1637: "Do not manually edit this!! If it is corrupted, cg@1637: the ImageEditor may not be able to read the specification." cg@1637: " cg@1637: self copyIcon inspect cg@1637: ImageEditor openOnClass:self andSelector:#copyIcon sv@3121: Icon flushCachedIcons" sv@3121: sv@3121: ^ Icon constantNamed:'ImageEditor class copyIcon' sv@3121: ifAbsentPut:[ sv@3121: (Depth2Image new) sv@3121: width:14; sv@3121: height:14; sv@3121: photometric:(#palette); sv@3121: bitsPerSample:(#( 2 )); sv@3121: samplesPerPixel:(1); sv@3121: bits:(ByteArray sv@3121: fromPackedString:'@@@@@@@@@@@** @@J)UUTB*Z*)@*&**PJ)**$B*Z*)@*&**PJ)**$@@Z*)@@F**P@AUUT@@@@@@b'); sv@3121: colorMapFromArray:#[ 0 0 0 0 0 128 255 255 255 ]; sv@3121: mask:((ImageMask new) sv@3121: width:14; sv@3121: height:14; sv@3121: bits:(ByteArray sv@3121: fromPackedString:'@@C? O>@??3??O? cg@3417: cg@3417: ^Icon cg@3417: constantNamed:'ImageEditor class cropSubImageIcon' cg@3417: ifAbsentPut:[(Depth2Image width:14 height:14) bits:(ByteArray fromPackedString:'@@@@@@@@@@@@@@@@@@@@@@J**@@BUU @@%UX@@IUV@@BUU @@%UX@@J**@@@@@@@@@@@@@@@@@@b') cg@3417: colorMapFromArray:#[0 0 0 255 255 255 127 127 127 0 255 0] cg@3464: mask:((ImageMask width:14 height:14) bits:(ByteArray fromPackedString:'??2@AH@D.@R?9K?$''>R_9I?$''?R_=HA4 @S??@@a'); yourself); yourself] cg@3417: ! cg@3417: cg@3419: darkerIcon cg@3419: "This resource specification was automatically generated cg@3419: by the ImageEditor of ST/X." cg@3419: cg@3419: "Do not manually edit this!! If it is corrupted, cg@3419: the ImageEditor may not be able to read the specification." cg@3419: cg@3419: " cg@3419: self darkerIcon inspect cg@3419: ImageEditor openOnClass:self andSelector:#darkerIcon cg@3419: Icon flushCachedIcons cg@3419: " cg@3419: cg@3419: cg@3419: cg@3419: ^Icon cg@3419: constantNamed:'ImageEditor class darkerIcon' cg@3419: ifAbsentPut:[(Depth8Image width:14 height:14) bits:(ByteArray fromPackedString:' cg@3419: @PDA@PDA@PDA@PDA@PG/;>?/;>?/9^W%9^W%9^?/;>?/;>?%9^W%9^W%;>?/;>?/;>W%9^W%9^W/;>?/;>?/9^W%9^W%9^?/;>?/;>?%9^W%9^W%;>?/A XF cg@3419: A XFA [%9^W/;>?/;>?%9^W%9^W%;>?/;>?/;>W%9^W%9^W/;>?/;>?/9^W%9^W%9^?/;>?/;>?%9^W%9^W%;>?/;>?/;>W%9^W% cg@3419: 9^TA@PDA@PDA@PDA@PDA@P@a') cg@3419: colorMapFromArray:#[88 88 88 0 0 0 255 0 0 0 255 0 0 0 255 0 255 255 255 255 127 255 0 255 127 0 0 0 127 0 0 0 127 0 127 127 127 127 0 127 0 127 127 127 127 170 170 170 0 0 51 0 0 102 0 0 153 0 0 204 0 51 0 0 51 51 0 51 102 0 51 153 0 51 204 0 51 255 0 102 0 0 102 51 0 102 102 0 102 153 0 102 204 0 102 255 0 153 0 0 153 51 0 153 102 0 153 153 0 153 204 0 153 255 0 204 0 0 204 51 0 204 102 0 204 153 0 204 204 0 204 255 0 255 51 0 255 102 0 255 153 0 255 204 51 0 0 51 0 51 51 0 102 51 0 153 51 0 204 51 0 255 51 51 0 51 51 51 51 51 102 51 51 153 51 51 204 51 51 255 51 102 0 51 102 51 51 102 102 51 102 153 51 102 204 51 102 255 51 153 0 51 153 51 51 153 102 51 153 153 51 153 204 51 153 255 51 204 0 51 204 51 51 204 102 51 204 153 51 204 204 51 204 255 51 255 0 51 255 51 51 255 102 51 255 153 51 255 204 51 255 255 102 0 0 102 0 51 102 0 102 102 0 153 102 0 204 102 0 255 102 51 0 102 51 51 102 51 102 102 51 153 102 51 204 102 51 255 102 102 0 102 102 51 102 102 102 102 102 153 102 102 204 102 102 255 102 153 0 102 153 51 102 153 102 102 153 153 102 153 204 102 153 255 102 204 0 102 204 51 102 204 102 102 204 153 102 204 204 102 204 255 102 255 0 102 255 51 102 255 102 102 255 153 102 255 204 102 255 255 153 0 0 153 0 51 153 0 102 153 0 153 153 0 204 153 0 255 153 51 0 153 51 51 153 51 102 153 51 153 153 51 204 153 51 255 153 102 0 153 102 51 153 102 102 153 102 153 153 102 204 153 102 255 153 153 0 153 153 51 153 153 102 153 153 153 153 153 204 153 153 255 153 204 0 153 204 51 153 204 102 153 204 153 153 204 204 153 204 255 153 255 0 153 255 51 153 255 102 153 255 153 153 255 204 153 255 255 204 0 0 204 0 51 204 0 102 204 0 153 204 0 204 204 0 255 204 51 0 204 51 51 204 51 102 204 51 153 204 51 204 204 51 255 204 102 0 204 102 51 204 102 102 204 102 153 204 102 204 204 102 255 204 153 0 204 153 51 204 153 102 204 153 153 204 153 204 204 153 255 204 204 0 204 204 51 204 204 102 204 204 153 204 204 204 204 204 255 204 255 0 204 255 51 204 255 102 204 255 153 204 255 204 204 255 255 255 0 51 255 0 102 255 0 153 255 0 204 255 51 0 255 51 51 255 51 102 255 51 153 255 51 204 255 51 255 255 102 0 255 102 51 255 102 102 255 102 153 255 102 204 255 102 255 255 153 0 255 153 51 255 153 102 255 153 153 255 153 204 255 153 255 255 204 0 255 204 51 255 204 102 255 204 153 255 204 204 255 204 255 255 255 51 255 255 102 255 255 153 255 255 204 255 255 255 9 9 9 19 19 19 29 29 29 39 39 39 49 49 49 58 58 58 68 68 68 78 78 78 98 98 98 107 107 107 117 117 117 137 137 137 147 147 147 156 156 156 166 166 166] cg@3419: mask:((ImageMask width:14 height:14) bits:(ByteArray fromPackedString:'@@C??O? sv@2155: sv@2155: ^ ToolbarIconLibrary startImageEditorIcon sv@2155: ! sv@2155: cg@3419: editIcon cg@3419: "This resource specification was automatically generated cg@3419: by the ImageEditor of ST/X." cg@3419: cg@3419: "Do not manually edit this!! If it is corrupted, cg@3419: the ImageEditor may not be able to read the specification." cg@3419: cg@3419: " cg@3419: self editIcon inspect cg@3419: ImageEditor openOnClass:self andSelector:#editIcon cg@3419: Icon flushCachedIcons cg@3419: " cg@3419: cg@3419: cg@3419: cg@3419: ^Icon cg@3419: constantNamed:'ImageEditor class editIcon' cg@3419: ifAbsentPut:[(Depth8Image width:15 height:16) bits:(ByteArray fromPackedString:' cg@3419: @@@@@@@3V41AJ0T@@@@@@@@@@B1(TD4>EP@@@@@@@@@@@CA!!S4X2D@@@@@@@@@@@LV)XTTHX@@@@@@@@@@@@K6UTS$LR@@@@@@@@@@@9OE9VRQ8@@@@@@@@@ cg@3419: @@@8Z5%WR!!P@@@@@@@@@@B8;X5)RG2@@@@@@@@@@@CY-W51SF @@@@@@@@@@@B5)XE4%E0@@@@@@@@@@@B%,Y3TO@@@@@@@@@@@@@BM,M04@@@@@@@@@@@@@ cg@3419: @@ IDP@@@@@@@@@@@@@@@@\K@@@@@@@@@@@@@@@@@A,@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@') cg@3419: colorMapFromArray:#[0 0 0 0 137 0 0 206 0 87 87 87 133 60 36 145 109 112 155 31 0 160 115 98 161 124 106 163 140 130 166 46 5 169 113 95 174 218 230 182 93 58 183 59 8 186 100 65 192 147 138 193 129 103 193 132 116 195 100 52 195 120 93 197 82 32 204 208 220 205 177 176 207 90 27 210 109 64 210 140 105 213 175 169 213 217 227 215 172 138 220 114 42 222 120 43 222 209 212 223 137 33 223 153 96 226 180 137 228 90 9 228 142 66 232 174 56 234 184 145 240 178 78 241 195 142 241 212 187 242 102 12 242 177 95 245 202 137 245 209 172 247 181 30 247 183 8 247 198 128 248 122 26 248 194 1 248 198 0 248 201 137 248 203 113 248 214 181 249 193 57 249 210 160 250 206 0 253 222 69 253 226 47 254 116 14 254 128 21 254 136 5 254 141 47 254 144 8 254 147 36 254 147 47 254 158 0 254 158 1 254 159 21 254 161 10 254 162 0 254 165 54 254 165 69 254 167 2 254 167 5 254 171 10 254 176 36 254 177 17 254 178 11 254 181 24 254 184 75 254 184 94 254 187 34 254 191 0 254 191 42 254 191 54 254 194 26 254 197 55 254 201 65 254 203 3 254 203 78 254 203 97 254 207 47 254 209 81 254 212 90 254 213 16 254 214 81 254 216 73 254 219 0 254 220 37 254 223 0 254 225 166 254 226 7 254 226 119 254 231 26 254 231 65 254 231 201 254 239 98] cg@3419: mask:((Depth1Image width:15 height:16) bits:(ByteArray fromPackedString:'A>@O0@?@G8@_ C<@O0A?@G8@_ A<@G @\@A @D@@@@@b'); yourself); yourself] cg@3419: ! cg@3419: cg@3418: emptyIcon cg@3418: "This resource specification was automatically generated cg@3418: by the ImageEditor of ST/X." cg@3418: cg@3418: "Do not manually edit this!! If it is corrupted, cg@3418: the ImageEditor may not be able to read the specification." cg@3418: cg@3418: " cg@3418: self emptyIcon inspect cg@3418: ImageEditor openOnClass:self andSelector:#emptyIcon cg@3418: Icon flushCachedIcons cg@3418: " cg@3418: cg@3418: cg@3418: cg@3418: ^Icon cg@3418: constantNamed:'ImageEditor class emptyIcon' cg@3418: ifAbsentPut:[(Depth4Image width:14 height:14) bits:(ByteArray fromPackedString:'@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ cg@3418: @@@@@@@@@@@b') cg@3418: colorMapFromArray:#[0 0 0] cg@3418: mask:((ImageMask width:14 height:14) bits:(ByteArray fromPackedString:'@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@a'); yourself); yourself] cg@3418: ! cg@3418: cg@3418: emptyIcon2 cg@3418: "This resource specification was automatically generated cg@3418: by the ImageEditor of ST/X." cg@3418: cg@3418: "Do not manually edit this!! If it is corrupted, cg@3418: the ImageEditor may not be able to read the specification." cg@3418: cg@3418: " cg@3418: self emptyIcon2 inspect cg@3418: ImageEditor openOnClass:self andSelector:#emptyIcon2 cg@3418: Icon flushCachedIcons cg@3418: " cg@3418: cg@3418: cg@3418: cg@3418: ^Icon cg@3418: constantNamed:'ImageEditor class emptyIcon2' cg@3418: ifAbsentPut:[(Depth4Image width:28 height:14) bits:(ByteArray fromPackedString:' cg@3418: @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ cg@3418: @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ cg@3418: @@@@@@@@@@@@@@@@@@@@@@@a') cg@3418: colorMapFromArray:#[0 0 0] cg@3418: mask:((Depth1Image width:28 height:14) bits:(ByteArray fromPackedString:'@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@b'); yourself); yourself] cg@3418: ! cg@3418: cg@3405: fillCircleIcon cg@3405: "This resource specification was automatically generated cg@3405: by the ImageEditor of ST/X." cg@3405: cg@3405: "Do not manually edit this!! If it is corrupted, cg@3405: the ImageEditor may not be able to read the specification." cg@3405: cg@3405: " cg@3405: self fillCircleIcon inspect cg@3405: ImageEditor openOnClass:self andSelector:#fillCircleIcon cg@3405: Icon flushCachedIcons cg@3405: " cg@3405: cg@3405: cg@3405: cg@3405: ^Icon cg@3405: constantNamed:'ImageEditor class fillCircleIcon' cg@3443: ifAbsentPut:[(Depth1Image width:14 height:14) bits:(ByteArray fromPackedString:'@@@@@@QA@@@@@B@H@@@@@@@CH@ @@@@@AD@@@@@a') cg@3443: colorMapFromArray:#[0 0 0 127 127 127] cg@3443: mask:((ImageMask width:14 height:14) bits:(ByteArray fromPackedString:'@@@@@@_@C>@_C?8O? _<@? A<@@@@@a'); yourself); yourself] cg@3405: ! cg@3405: cg@3418: fillDiagonalGradientRectIcon cg@3418: "This resource specification was automatically generated cg@3418: by the ImageEditor of ST/X." cg@3418: cg@3418: "Do not manually edit this!! If it is corrupted, cg@3418: the ImageEditor may not be able to read the specification." cg@3418: cg@3418: " cg@3418: self fillDiagonalGradientRectIcon inspect cg@3418: ImageEditor openOnClass:self andSelector:#fillDiagonalGradientRectIcon cg@3418: Icon flushCachedIcons cg@3418: " cg@3418: cg@3418: cg@3418: cg@3418: ^Icon cg@3418: constantNamed:'ImageEditor class fillDiagonalGradientRectIcon' cg@3418: ifAbsentPut:[(Depth4Image width:14 height:14) bits:(ByteArray fromPackedString:'@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@QDQDQD@@@DQDQDQ@@@ADH"H"H@@@QBH"H"@@@DP"L3L0@@ADH#L3L@@@QBH3DQ@@@DP"L1DP@@ADH#LQD@@@@@@@@@ cg@3418: @@@@@@@@@@@b') cg@3418: colorMapFromArray:#[0 0 0 255 0 0 127 0 0 191 0 0 91 0 0] cg@3418: mask:((ImageMask width:14 height:14) bits:(ByteArray fromPackedString:'@@@@@C?0O?@? cg@2871: "This resource specification was automatically generated cg@2871: by the ImageEditor of ST/X." cg@2871: "Do not manually edit this!! If it is corrupted, cg@2871: the ImageEditor may not be able to read the specification." cg@2871: " cg@2871: self fillGradientRectIcon inspect cg@2871: ImageEditor openOnClass:self andSelector:#fillGradientRectIcon sv@3121: Icon flushCachedIcons" sv@3121: sv@3121: ^ Icon constantNamed:'ImageEditor class fillGradientRectIcon' sv@3121: ifAbsentPut:[ sv@3121: (Depth4Image new) sv@3121: width:14; sv@3121: height:14; sv@3121: photometric:(#palette); sv@3121: bitsPerSample:(#[ 4 ]); sv@3121: samplesPerPixel:(1); sv@3121: bits:(ByteArray sv@3121: fromPackedString:'@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ADQDQDQ@@@QDQDQDP@@BH"H"H"@@@"H"H"H @@L3L3L3L@@CL3L3L3@@@QDQDQDP@@DQDQDQD@@@@@@@@@ sv@3121: @@@@@@@@@@@b'); sv@3121: colorMapFromArray:#[ 0 0 0 255 0 0 127 0 0 191 0 0 63 0 0 ]; sv@3121: mask:((ImageMask new) sv@3121: width:14; sv@3121: height:14; sv@3121: bits:(ByteArray sv@3121: fromPackedString:'@@@@@C?0O?@? cg@3418: cg@3418: ^Icon cg@3418: constantNamed:'ImageEditor class fillHorizontalGradientRectIcon' cg@3418: ifAbsentPut:[(Depth4Image width:14 height:14) bits:(ByteArray fromPackedString:'@@@@@@@@@@@@@@@@@@@@ADH#LQD@@@QBH3DQ@@@DP"L1DP@@ADH#LQD@@@QBH3DQ@@@DP"L1DP@@ADH#LQD@@@QBH3DQ@@@DP"L1DP@@ADH#LQD@@@@@@@@@ cg@3418: @@@@@@@@@@@b') cg@3418: colorMapFromArray:#[0 0 0 255 0 0 127 0 0 191 0 0 91 0 0] cg@3418: mask:((ImageMask width:14 height:14) bits:(ByteArray fromPackedString:'@@@@@C?0O?@? cg@1637: "This resource specification was automatically generated cg@1637: by the ImageEditor of ST/X." cg@1637: "Do not manually edit this!! If it is corrupted, cg@1637: the ImageEditor may not be able to read the specification." cg@1637: " cg@1637: self fillIcon inspect cg@1637: ImageEditor openOnClass:self andSelector:#fillIcon sv@3121: Icon flushCachedIcons" sv@3121: sv@3121: ^ Icon constantNamed:'ImageEditor class fillIcon' sv@3121: ifAbsentPut:[ sv@3121: (Depth2Image new) sv@3121: width:14; sv@3121: height:14; sv@3121: photometric:(#palette); sv@3121: bitsPerSample:(#( 2 )); sv@3121: samplesPerPixel:(1); sv@3121: bits:(ByteArray sv@3121: fromPackedString:'@@@@@@@@@@@@@ @@@@*H@@D*(@@DUUP@EAUU@AAEU@@@@U@@DDA@@@@@@@@PP@@@@@@@@@@@@@@b'); sv@3121: colorMapFromArray:#[ 0 0 0 255 0 0 255 255 255 ]; sv@3121: mask:((ImageMask new) sv@3121: width:14; sv@3121: height:14; sv@3121: bits:(ByteArray sv@3121: fromPackedString:'C @Q@BN@I<@?8C?0[?!!G<@O P\@@ D@@@@@@@@@a'); sv@3121: yourself); sv@3121: yourself sv@3121: ] cg@1637: ! cg@1637: cg@1637: fillRectIcon sv@3121: cg@1637: "This resource specification was automatically generated cg@1637: by the ImageEditor of ST/X." cg@1637: "Do not manually edit this!! If it is corrupted, cg@1637: the ImageEditor may not be able to read the specification." cg@1637: " cg@1637: self fillRectIcon inspect cg@1637: ImageEditor openOnClass:self andSelector:#fillRectIcon sv@3121: Icon flushCachedIcons" sv@3121: sv@3121: ^ Icon constantNamed:'ImageEditor class fillRectIcon' sv@3121: ifAbsentPut:[ sv@3121: (Depth1Image new) sv@3121: width:14; sv@3121: height:14; sv@3121: photometric:(#palette); sv@3121: bitsPerSample:(#( 1 )); sv@3121: samplesPerPixel:(1); sv@3121: bits:(ByteArray sv@3121: fromPackedString:'@@@@@@@A@@@@@@@@@@@@@@@@@@@@@@@@@@D@@@@a'); sv@3121: colorMapFromArray:#[ 0 0 0 255 0 0 ]; sv@3121: mask:((ImageMask new) sv@3121: width:14; sv@3121: height:14; sv@3121: bits:(ByteArray sv@3121: fromPackedString:'@@@@@C?0O?@? cg@3418: cg@3418: ^Icon cg@3418: constantNamed:'ImageEditor class fillVerticalGradientRectIcon' cg@3418: ifAbsentPut:[(Depth4Image width:14 height:14) bits:(ByteArray fromPackedString:'@@@@@@@@@@@@@@@@@@@@@@@@@@@@@DQDQDQD@@ADQDQDQ@@@H"H"H"H@@BH"H"H"@@@3L3L3L0@@L3L3L3L@@ADQDQDQ@@@QDQDQDP@@DQDQDQD@@@@@@@@@ cg@3418: @@@@@@@@@@@b') cg@3418: colorMapFromArray:#[0 0 0 255 0 0 127 0 0 191 0 0 91 0 0] cg@3418: mask:((ImageMask width:14 height:14) bits:(ByteArray fromPackedString:'@@@@@C?0O?@? cg@2837: "This resource specification was automatically generated cg@2837: by the ImageEditor of ST/X." cg@2837: "Do not manually edit this!! If it is corrupted, cg@2837: the ImageEditor may not be able to read the specification." cg@2837: " cg@2837: self flipHorizontalIcon inspect cg@2837: ImageEditor openOnClass:self andSelector:#flipHorizontalIcon sv@3121: Icon flushCachedIcons" sv@3121: sv@3121: ^ Icon constantNamed:'ImageEditor class flipHorizontalIcon' sv@3121: ifAbsentPut:[ sv@3121: (Depth1Image new) sv@3121: width:14; sv@3121: height:14; sv@3121: photometric:(#palette); sv@3121: bitsPerSample:(#( 1 )); sv@3121: samplesPerPixel:(1); sv@3121: bits:(ByteArray sv@3121: fromPackedString:'@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@a'); sv@3121: colorMapFromArray:#[ 0 0 0 ]; sv@3121: mask:((ImageMask new) sv@3121: width:14; sv@3121: height:14; sv@3121: bits:(ByteArray sv@3121: fromPackedString:'@@@A@C?8HP )JC$8_?1??C$8JR !!BC?8@P@@@@@a'); sv@3121: yourself); sv@3121: yourself sv@3121: ] cg@2837: ! cg@2837: cg@2837: flipVerticalIcon sv@3121: cg@2837: "This resource specification was automatically generated cg@2837: by the ImageEditor of ST/X." cg@2837: "Do not manually edit this!! If it is corrupted, cg@2837: the ImageEditor may not be able to read the specification." cg@2837: " cg@2837: self flipVerticalIcon inspect cg@2837: ImageEditor openOnClass:self andSelector:#flipVerticalIcon sv@3121: Icon flushCachedIcons" sv@3121: sv@3121: ^ Icon constantNamed:'ImageEditor class flipVerticalIcon' sv@3121: ifAbsentPut:[ sv@3121: (Depth1Image new) sv@3121: width:14; sv@3121: height:14; sv@3121: photometric:(#palette); sv@3121: bitsPerSample:(#( 1 )); sv@3121: samplesPerPixel:(1); sv@3121: bits:(ByteArray sv@3121: fromPackedString:'@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@a'); sv@3121: colorMapFromArray:#[ 0 0 0 ]; sv@3121: mask:((ImageMask new) sv@3121: width:14; sv@3121: height:14; sv@3121: bits:(ByteArray sv@3121: fromPackedString:'@@@C@C?0I9@/4BLPH1A?>BLPH1@/4B^PO?@C@@@a'); sv@3121: yourself); sv@3121: yourself sv@3121: ] cg@2837: ! cg@2837: tz@737: leftMouseKeyIcon sv@3121: tz@737: "This resource specification was automatically generated tz@737: by the ImageEditor of ST/X." tz@737: "Do not manually edit this!! If it is corrupted, tz@737: the ImageEditor may not be able to read the specification." tz@737: " cg@1405: self leftMouseKeyIcon inspect tz@737: ImageEditor openOnClass:self andSelector:#leftMouseKeyIcon sv@3121: Icon flushCachedIcons" sv@3121: sv@3121: ^ Icon constantNamed:'ImageEditor class leftMouseKeyIcon' sv@3121: ifAbsentPut:[ sv@3121: (Depth2Image new) sv@3121: width:16; sv@3121: height:16; sv@3121: photometric:(#palette); sv@3121: bitsPerSample:(#( 2 )); sv@3121: samplesPerPixel:(1); sv@3121: bits:(ByteArray sv@3121: fromPackedString:'@@@@@@@@@@@@@@@@@EJJ@@AR" @@T((@@@@@@@B** @@**(@@J**@@B** @@**(@@J**@@@**@@@@@@@@@@@@@@a'); sv@3121: colorMapFromArray:#[ 0 0 0 255 0 0 255 255 255 ]; sv@3121: mask:((ImageMask new) sv@3121: width:16; sv@3121: height:16; sv@3121: bits:(ByteArray sv@3121: fromPackedString:'@@@@@@?0G? _>A?8G? _>A?8G? _>A?8G? O<@_ @@@b'); sv@3121: yourself); sv@3121: yourself sv@3121: ] martin@1433: ! tz@737: cg@3405: maskOutsideCircleIcon cg@3405: "This resource specification was automatically generated cg@3405: by the ImageEditor of ST/X." cg@3405: cg@3405: "Do not manually edit this!! If it is corrupted, cg@3405: the ImageEditor may not be able to read the specification." cg@3405: cg@3405: " cg@3405: self maskOutsideCircleIcon inspect cg@3405: ImageEditor openOnClass:self andSelector:#maskOutsideCircleIcon cg@3405: Icon flushCachedIcons cg@3405: " cg@3405: cg@3405: cg@3405: cg@3405: ^Icon cg@3405: constantNamed:'ImageEditor class maskOutsideCircleIcon' cg@3405: ifAbsentPut:[(Depth1Image width:14 height:14) bits:(ByteArray fromPackedString:'??3??O1= cg@3405: cg@3405: ^Icon cg@3405: constantNamed:'ImageEditor class maskOutsideRectangleIcon' cg@3405: ifAbsentPut:[(Depth1Image width:14 height:14) bits:(ByteArray fromPackedString:'??3??L@M0@3@CL@L0@3@CL@L0@3@CL@L??7??@@a') cg@3407: colorMapFromArray:#[0 0 0 255 127 127] cg@3405: mask:((ImageMask width:14 height:14) bits:(ByteArray fromPackedString:'??3??O? cg@3561: cg@3561: ^Icon cg@3561: constantNamed:'ImageEditor class pasteIcon' cg@3561: ifAbsentPut:[(Depth8Image width:14 height:14) bits:(ByteArray fromPackedString:' cg@3561: :N#(:N#(:N#(:N#(:N#(:N#(:O#8:N#(:N#(:N#5>^#8:N#8:OW9:N#(:O''(=/[6=/[6:OW(:N#(=^#(:N#(:N#(>^#(:N#9=_''5>_W9=_''5:N#(:@DA@PDA cg@3561: @PDA=_''(@@C(@_[6= @@@@@@@@@@@N A=/[6@@XFA XFA @@:@G6=/X@A X@@@XF@@C(@_[6= @F@@@@@@X@@N A=/[6@@XF@@@FA @@@@DA@PD@A XFA XF cg@3561: @@@@@@@@@@@@@@@@@@@@@@@a') cg@3561: colorMapFromArray:#[0 0 0 0 0 128 128 128 0 128 128 128 212 208 200 255 255 0 255 255 255 0 0 51 0 0 102 0 0 153 0 0 204 0 0 255 0 51 0 0 51 51 0 51 102 0 51 153 0 51 204 0 51 255 0 102 0 0 102 51 0 102 102 0 102 153 0 102 204 0 102 255 0 153 0 0 153 51 0 153 102 0 153 153 0 153 204 0 153 255 0 204 0 0 204 51 0 204 102 0 204 153 0 204 204 0 204 255 0 255 0 0 255 51 0 255 102 0 255 153 0 255 204 0 255 255 51 0 0 51 0 51 51 0 102 51 0 153 51 0 204 51 0 255 51 51 0 51 51 51 51 51 102 51 51 153 51 51 204 51 51 255 51 102 0 51 102 51 51 102 102 51 102 153 51 102 204 51 102 255 51 153 0 51 153 51 51 153 102 51 153 153 51 153 204 51 153 255 51 204 0 51 204 51 51 204 102 51 204 153 51 204 204 51 204 255 51 255 0 51 255 51 51 255 102 51 255 153 51 255 204 51 255 255 102 0 0 102 0 51 102 0 102 102 0 153 102 0 204 102 0 255 102 51 0 102 51 51 102 51 102 102 51 153 102 51 204 102 51 255 102 102 0 102 102 51 102 102 102 102 102 153 102 102 204 102 102 255 102 153 0 102 153 51 102 153 102 102 153 153 102 153 204 102 153 255 102 204 0 102 204 51 102 204 102 102 204 153 102 204 204 102 204 255 102 255 0 102 255 51 102 255 102 102 255 153 102 255 204 102 255 255 153 0 0 153 0 51 153 0 102 153 0 153 153 0 204 153 0 255 153 51 0 153 51 51 153 51 102 153 51 153 153 51 204 153 51 255 153 102 0 153 102 51 153 102 102 153 102 153 153 102 204 153 102 255 153 153 0 153 153 51 153 153 102 153 153 153 153 153 204 153 153 255 153 204 0 153 204 51 153 204 102 153 204 153 153 204 204 153 204 255 153 255 0 153 255 51 153 255 102 153 255 153 153 255 204 153 255 255 204 0 0 204 0 51 204 0 102 204 0 153 204 0 204 204 0 255 204 51 0 204 51 51 204 51 102 204 51 153 204 51 204 204 51 255 204 102 0 204 102 51 204 102 102 204 102 153 204 102 204 204 102 255 204 153 0 204 153 51 204 153 102 204 153 153 204 153 204 204 153 255 204 204 0 204 204 51 204 204 102 204 204 153 204 204 204 204 204 255 204 255 0 204 255 51 204 255 102 204 255 153 204 255 204 204 255 255 255 0 0 255 0 51 255 0 102 255 0 153 255 0 204 255 0 255 255 51 0 255 51 51 255 51 102 255 51 153 255 51 204 255 51 255 255 102 0 255 102 51 255 102 102 255 102 153 255 102 204 255 102 255 255 153 0 255 153 51 255 153 102 255 153 153 255 153 204 255 153 255 255 204 0 255 204 51 255 204 102 255 204 153 255 204 204 255 204 255 255 255 51 255 255 102 255 255 153 255 255 204 9 9 9 19 19 19 29 29 29 39 39 39 49 49 49 58 58 58 68 68 68 78 78 78 88 88 88 98 98 98 107 107 107 117 117 117 127 127 127 137 137 137 147 147 147 156 156 156 166 166 166 176 176 176 186 186 186 196 196 196 205 205 205 215 215 215 225 225 225 235 235 235 245 245 245 191 191 191 233 231 227 127 127 127 255 255 127 191 191 127] cg@3561: mask:((ImageMask width:14 height:14) bits:(ByteArray fromPackedString:'C0A?8O?0??C?O?8??#?>O?8_? G>@@a'); yourself); yourself] cg@3561: ! cg@3561: cg@3561: pasteMaskedIcon cg@3561: "This resource specification was automatically generated cg@3561: by the ImageEditor of ST/X." cg@3561: cg@3561: "Do not manually edit this!! If it is corrupted, cg@3561: the ImageEditor may not be able to read the specification." cg@3561: cg@3561: " cg@3561: self pasteMaskedIcon inspect cg@3561: ImageEditor openOnClass:self andSelector:#pasteMaskedIcon cg@3561: Icon flushCachedIcons cg@3561: " cg@3561: cg@3561: cg@3561: cg@3561: ^Icon cg@3561: constantNamed:'ImageEditor class pasteMaskedIcon' cg@3561: ifAbsentPut:[(Depth8Image width:14 height:14) bits:(ByteArray fromPackedString:' cg@3561: :N#(:N#(:N#(:N#(:N#(:N#(:O#8:N#(:N#(:N#5>^#8:N#8:OW9:N#(:O''(=/[6=/[6:OW(:N#(=^#(:N#(:N#(>^#(:N#9=_''5>_W9=_''5:N#(:@DA@PDA cg@3561: @PDA=_''(@@C(@_[6=/[6= D@@@@@@N A=/[6= XFA XFA @@:@G6=/[6A X@@@XF@@C(@_[6=/XF= @@@@X@@N A=/[6= XF@@@FA @@@@DA@PDA@PDAA XF cg@3561: @@@@@@@@@@@@@@@@@@@@@@@a') cg@3561: colorMapFromArray:#[0 0 0 0 0 128 128 128 0 128 128 128 212 208 200 255 255 0 255 255 255 0 0 51 0 0 102 0 0 153 0 0 204 0 0 255 0 51 0 0 51 51 0 51 102 0 51 153 0 51 204 0 51 255 0 102 0 0 102 51 0 102 102 0 102 153 0 102 204 0 102 255 0 153 0 0 153 51 0 153 102 0 153 153 0 153 204 0 153 255 0 204 0 0 204 51 0 204 102 0 204 153 0 204 204 0 204 255 0 255 0 0 255 51 0 255 102 0 255 153 0 255 204 0 255 255 51 0 0 51 0 51 51 0 102 51 0 153 51 0 204 51 0 255 51 51 0 51 51 51 51 51 102 51 51 153 51 51 204 51 51 255 51 102 0 51 102 51 51 102 102 51 102 153 51 102 204 51 102 255 51 153 0 51 153 51 51 153 102 51 153 153 51 153 204 51 153 255 51 204 0 51 204 51 51 204 102 51 204 153 51 204 204 51 204 255 51 255 0 51 255 51 51 255 102 51 255 153 51 255 204 51 255 255 102 0 0 102 0 51 102 0 102 102 0 153 102 0 204 102 0 255 102 51 0 102 51 51 102 51 102 102 51 153 102 51 204 102 51 255 102 102 0 102 102 51 102 102 102 102 102 153 102 102 204 102 102 255 102 153 0 102 153 51 102 153 102 102 153 153 102 153 204 102 153 255 102 204 0 102 204 51 102 204 102 102 204 153 102 204 204 102 204 255 102 255 0 102 255 51 102 255 102 102 255 153 102 255 204 102 255 255 153 0 0 153 0 51 153 0 102 153 0 153 153 0 204 153 0 255 153 51 0 153 51 51 153 51 102 153 51 153 153 51 204 153 51 255 153 102 0 153 102 51 153 102 102 153 102 153 153 102 204 153 102 255 153 153 0 153 153 51 153 153 102 153 153 153 153 153 204 153 153 255 153 204 0 153 204 51 153 204 102 153 204 153 153 204 204 153 204 255 153 255 0 153 255 51 153 255 102 153 255 153 153 255 204 153 255 255 204 0 0 204 0 51 204 0 102 204 0 153 204 0 204 204 0 255 204 51 0 204 51 51 204 51 102 204 51 153 204 51 204 204 51 255 204 102 0 204 102 51 204 102 102 204 102 153 204 102 204 204 102 255 204 153 0 204 153 51 204 153 102 204 153 153 204 153 204 204 153 255 204 204 0 204 204 51 204 204 102 204 204 153 204 204 204 204 204 255 204 255 0 204 255 51 204 255 102 204 255 153 204 255 204 204 255 255 255 0 0 255 0 51 255 0 102 255 0 153 255 0 204 255 0 255 255 51 0 255 51 51 255 51 102 255 51 153 255 51 204 255 51 255 255 102 0 255 102 51 255 102 102 255 102 153 255 102 204 255 102 255 255 153 0 255 153 51 255 153 102 255 153 153 255 153 204 255 153 255 255 204 0 255 204 51 255 204 102 255 204 153 255 204 204 255 204 255 255 255 51 255 255 102 255 255 153 255 255 204 9 9 9 19 19 19 29 29 29 39 39 39 49 49 49 58 58 58 68 68 68 78 78 78 88 88 88 98 98 98 107 107 107 117 117 117 127 127 127 137 137 137 147 147 147 156 156 156 166 166 166 176 176 176 186 186 186 196 196 196 205 205 205 215 215 215 225 225 225 235 235 235 245 245 245 191 191 191 233 231 227 127 127 127 255 255 127 191 191 127] cg@3561: mask:((ImageMask width:14 height:14) 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@3561: cg@1637: "Do not manually edit this!! If it is corrupted, cg@1637: the ImageEditor may not be able to read the specification." cg@3561: cg@1637: " cg@1637: self pasteUnderIcon inspect cg@1637: ImageEditor openOnClass:self andSelector:#pasteUnderIcon cg@3561: Icon flushCachedIcons cg@3561: " cg@3561: cg@3561: cg@3561: cg@3561: ^Icon cg@3561: constantNamed:'ImageEditor class pasteUnderIcon' cg@3561: ifAbsentPut:[(Depth8Image width:14 height:14) bits:(ByteArray fromPackedString:' cg@3561: :N#(:N#(:N#(:N#(:N#(:N#(:O#8:N#(:N#(:N#5>^#8:N#8:OW9:N#(:O''(=/[6=/[6:OW(:N#(=^#(:N#(:N#(>^#(:N#9=_''5>_W9=_''5:N#(:@DA@PDA cg@3561: @PDA=_''(@@C(@_K2O?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@3561: cg@1637: "Do not manually edit this!! If it is corrupted, cg@1637: the ImageEditor may not be able to read the specification." cg@3561: cg@1637: " cg@1637: self pasteWithMaskIcon inspect cg@1637: ImageEditor openOnClass:self andSelector:#pasteWithMaskIcon cg@3561: Icon flushCachedIcons cg@3561: " cg@3561: cg@3561: cg@3561: cg@3561: ^Icon cg@3561: constantNamed:'ImageEditor class pasteWithMaskIcon' cg@3561: ifAbsentPut:[(Depth8Image width:14 height:14) bits:(ByteArray fromPackedString:' cg@3561: :N#(:N#(:N#(:N#(:N#(:N#(:O#8:N#(:N#(:N#5>^#8:N#8:OW9:N#(:O''(=/[6=/[6:OW(:N#(=^#(:N#(:N#(>^#(:N#9=_''5>_W9=_''5:N#(:@DA@PDA cg@3561: @PDA=_''(@@C(@_C0O?8??#?>O?8_? G>@@a'); yourself); yourself] cg@1637: ! cg@1637: cg@1637: pointIcon sv@3121: cg@1637: "This resource specification was automatically generated cg@1637: by the ImageEditor of ST/X." cg@1637: "Do not manually edit this!! If it is corrupted, cg@1637: the ImageEditor may not be able to read the specification." cg@1637: " cg@1637: self pointIcon inspect cg@1637: ImageEditor openOnClass:self andSelector:#pointIcon sv@3121: Icon flushCachedIcons" sv@3121: sv@3121: ^ Icon constantNamed:'ImageEditor class pointIcon' sv@3121: ifAbsentPut:[ sv@3121: (Depth1Image new) sv@3121: width:14; sv@3121: height:14; sv@3121: photometric:(#palette); sv@3121: bitsPerSample:(#( 1 )); sv@3121: samplesPerPixel:(1); sv@3121: bits:(ByteArray sv@3121: fromPackedString:'@@@@@@@A@@@@@@@@@@@@@@@C@@@@@@@@@@@@@@@a'); sv@3121: colorMapFromArray:#[ 0 0 0 255 255 255 ]; sv@3121: mask:((ImageMask new) sv@3121: width:14; sv@3121: height:14; sv@3121: bits:(ByteArray sv@3121: fromPackedString:'@@@@@@@0@G@@8@G@@8@G@@8@G@@X@@@@@@@@@@@a'); sv@3121: yourself); sv@3121: yourself sv@3121: ] cg@1637: ! cg@1637: cg@1637: rectIcon sv@3121: cg@1637: "This resource specification was automatically generated cg@1637: by the ImageEditor of ST/X." cg@1637: "Do not manually edit this!! If it is corrupted, cg@1637: the ImageEditor may not be able to read the specification." cg@1637: " cg@1637: self rectIcon inspect cg@1637: ImageEditor openOnClass:self andSelector:#rectIcon sv@3121: Icon flushCachedIcons" sv@3121: sv@3121: ^ Icon constantNamed:'ImageEditor class rectIcon' sv@3121: ifAbsentPut:[ sv@3121: (Depth1Image new) sv@3121: width:14; sv@3121: height:14; sv@3121: photometric:(#palette); sv@3121: bitsPerSample:(#( 1 )); sv@3121: samplesPerPixel:(1); sv@3121: bits:(ByteArray sv@3121: fromPackedString:'@@@@@@@A@@@@@@@@@@@@@@@C@@@@@@@@@@@@@@@a'); sv@3121: colorMapFromArray:#[ 0 0 0 255 0 0 ]; sv@3121: mask:((ImageMask new) sv@3121: width:14; sv@3121: height:14; sv@3121: bits:(ByteArray sv@3121: fromPackedString:'@@@@@C?0HA@ DB@PHA@ DB@PHA@ DC?0@@@@@@@a'); sv@3121: yourself); sv@3121: yourself sv@3121: ] cg@1637: ! cg@1637: tz@737: rightMouseKeyIcon sv@3121: tz@737: "This resource specification was automatically generated tz@737: by the ImageEditor of ST/X." tz@737: "Do not manually edit this!! If it is corrupted, tz@737: the ImageEditor may not be able to read the specification." tz@737: " cg@1405: self rightMouseKeyIcon inspect tz@737: ImageEditor openOnClass:self andSelector:#rightMouseKeyIcon sv@3121: Icon flushCachedIcons" sv@3121: sv@3121: ^ Icon constantNamed:'ImageEditor class rightMouseKeyIcon' sv@3121: ifAbsentPut:[ sv@3121: (Depth2Image new) sv@3121: width:16; sv@3121: height:16; sv@3121: photometric:(#palette); sv@3121: bitsPerSample:(#( 2 )); sv@3121: samplesPerPixel:(1); sv@3121: bits:(ByteArray sv@3121: fromPackedString:'@@@@@@@@@@@@@@@@@JJE@@B"!!P@@((T@@@@@@@B** @@**(@@J**@@B** @@**(@@J**@@@**@@@@@@@@@@@@@@a'); sv@3121: colorMapFromArray:#[ 0 0 0 255 0 0 255 255 255 ]; sv@3121: mask:((ImageMask new) sv@3121: width:16; sv@3121: height:16; sv@3121: bits:(ByteArray sv@3121: fromPackedString:'@@@@@@?0G? _>A?8G? _>A?8G? _>A?8G? O<@_ @@@b'); sv@3121: yourself); sv@3121: yourself sv@3121: ] cg@1637: ! cg@1637: cg@3419: slightlyBrighterIcon cg@3419: "This resource specification was automatically generated cg@3419: by the ImageEditor of ST/X." cg@3419: cg@3419: "Do not manually edit this!! If it is corrupted, cg@3419: the ImageEditor may not be able to read the specification." cg@3419: cg@3419: " cg@3419: self slightlyBrighterIcon inspect cg@3419: ImageEditor openOnClass:self andSelector:#slightlyBrighterIcon cg@3419: Icon flushCachedIcons cg@3419: " cg@3419: cg@3419: cg@3419: cg@3419: ^Icon cg@3419: constantNamed:'ImageEditor class slightlyBrighterIcon' cg@3419: ifAbsentPut:[(Depth8Image width:14 height:14) bits:(ByteArray fromPackedString:' cg@3419: @PDA@PDA@PDA@PDA@PD@@@@@@@@@;>?/;>?/;0@@@@@@@@C/;>?/;>?/@@@@@@@@A [/;>?/;><@@@@@@@@FA.?/;>?/;0@@@@@@@@XF;>?/;>?/@@@@A XF cg@3419: A XFA [/;><@@@@FA XFA XFA.?/;0@@@@@@@@XF;>?/;>?/@@@@@@@@A [/;>?/;><@@@@@@@@FA.?/;>?/;0@@@@@@@@C/;>?/;>?/@@@@@@@@@N?/;>?/ cg@3419: ;> cg@3419: cg@3419: ^Icon cg@3419: constantNamed:'ImageEditor class slightlyDarkerIcon' cg@3419: ifAbsentPut:[(Depth8Image width:14 height:14) bits:(ByteArray fromPackedString:' cg@3419: @PDA@PDA@PDA@PDA@PG/;>?/;>?/@@@@@@@@@N?/;>?/;><@@@@@@@@@;>?/;>?/;0@@@@@@@@C/;>?/;>?/@@@@@@@@@N?/;>?/;><@@@@@@@@@;>?/A XF cg@3419: A XFA X@@@C/;>?/;><@@@@@@@@@;>?/;>?/;0@@@@@@@@C/;>?/;>?/@@@@@@@@@N?/;>?/;><@@@@@@@@@;>?/;>?/;0@@@@@@ cg@3419: @@@A@PDA@PDA@PDA@PDA@P@a') cg@3419: colorMapFromArray:#[88 88 88 0 0 0 255 0 0 0 255 0 0 0 255 0 255 255 255 255 127 255 0 255 127 0 0 0 127 0 0 0 127 0 127 127 127 127 0 127 0 127 127 127 127 170 170 170 0 0 51 0 0 102 0 0 153 0 0 204 0 51 0 0 51 51 0 51 102 0 51 153 0 51 204 0 51 255 0 102 0 0 102 51 0 102 102 0 102 153 0 102 204 0 102 255 0 153 0 0 153 51 0 153 102 0 153 153 0 153 204 0 153 255 0 204 0 0 204 51 0 204 102 0 204 153 0 204 204 0 204 255 0 255 51 0 255 102 0 255 153 0 255 204 51 0 0 51 0 51 51 0 102 51 0 153 51 0 204 51 0 255 51 51 0 51 51 51 51 51 102 51 51 153 51 51 204 51 51 255 51 102 0 51 102 51 51 102 102 51 102 153 51 102 204 51 102 255 51 153 0 51 153 51 51 153 102 51 153 153 51 153 204 51 153 255 51 204 0 51 204 51 51 204 102 51 204 153 51 204 204 51 204 255 51 255 0 51 255 51 51 255 102 51 255 153 51 255 204 51 255 255 102 0 0 102 0 51 102 0 102 102 0 153 102 0 204 102 0 255 102 51 0 102 51 51 102 51 102 102 51 153 102 51 204 102 51 255 102 102 0 102 102 51 102 102 102 102 102 153 102 102 204 102 102 255 102 153 0 102 153 51 102 153 102 102 153 153 102 153 204 102 153 255 102 204 0 102 204 51 102 204 102 102 204 153 102 204 204 102 204 255 102 255 0 102 255 51 102 255 102 102 255 153 102 255 204 102 255 255 153 0 0 153 0 51 153 0 102 153 0 153 153 0 204 153 0 255 153 51 0 153 51 51 153 51 102 153 51 153 153 51 204 153 51 255 153 102 0 153 102 51 153 102 102 153 102 153 153 102 204 153 102 255 153 153 0 153 153 51 153 153 102 153 153 153 153 153 204 153 153 255 153 204 0 153 204 51 153 204 102 153 204 153 153 204 204 153 204 255 153 255 0 153 255 51 153 255 102 153 255 153 153 255 204 153 255 255 204 0 0 204 0 51 204 0 102 204 0 153 204 0 204 204 0 255 204 51 0 204 51 51 204 51 102 204 51 153 204 51 204 204 51 255 204 102 0 204 102 51 204 102 102 204 102 153 204 102 204 204 102 255 204 153 0 204 153 51 204 153 102 204 153 153 204 153 204 204 153 255 204 204 0 204 204 51 204 204 102 204 204 153 204 204 204 204 204 255 204 255 0 204 255 51 204 255 102 204 255 153 204 255 204 204 255 255 255 0 51 255 0 102 255 0 153 255 0 204 255 51 0 255 51 51 255 51 102 255 51 153 255 51 204 255 51 255 255 102 0 255 102 51 255 102 102 255 102 153 255 102 204 255 102 255 255 153 0 255 153 51 255 153 102 255 153 153 255 153 204 255 153 255 255 204 0 255 204 51 255 204 102 255 204 153 255 204 204 255 204 255 255 255 51 255 255 102 255 255 153 255 255 204 255 255 255 9 9 9 19 19 19 29 29 29 39 39 39 49 49 49 58 58 58 68 68 68 78 78 78 98 98 98 107 107 107 117 117 117 137 137 137 147 147 147 156 156 156 166 166 166] cg@3419: mask:((ImageMask width:14 height:14) bits:(ByteArray fromPackedString:'@@C??O? cg@3191: cg@3191: ^Icon cg@3191: constantNamed:'ImageEditor smoothIcon' cg@3191: ifAbsentPut:[(Depth4Image new) width:14; height:14; bits:(ByteArray fromPackedString:'@@@@@@@@@@@RH@@@H!!@@HRD@@RD @BHQ@@DRH@@ADP@ADP@@@@@QD@@@@@@@DQ@@@@@@@ADP@@@@@QD@@QD@@BHQ@@DRH@@!!HP@AHR@@D"@@@BHP@@@@@@@@ cg@3191: @@@@@@@@@@@b') ; colorMapFromArray:#[127 126 127 255 0 0 255 255 255]; mask:((ImageMask new) width:14; height:14; bits:(ByteArray fromPackedString:'_?1<_G1<_G1??D_DQ cg@3442: cg@3442: ^Icon cg@3442: constantNamed:'ImageEditor class specialCircleIcon' cg@3442: ifAbsentPut:[(Depth2Image width:14 height:14) bits:(ByteArray fromPackedString:'@@@@@@@@@@@@PA@@@RBD@@P@@P@P@@A@D@@@PA@@@D@PHHA@A@@A@@D@A@@@PA@@@@@@@@@@@@@b') cg@3442: colorMapFromArray:#[0 0 0 255 0 0 127 127 127] cg@3442: mask:((ImageMask width:14 height:14) bits:(ByteArray fromPackedString:'@@@@@@-@E:@''$D^HQ8!!G"D^HH1@PH@-@@0@@@@@a'); yourself); yourself] cg@2881: ! cg@2881: cg@3419: specialRectangleIcon cg@1637: "This resource specification was automatically generated cg@1637: by the ImageEditor of ST/X." cg@3419: cg@1637: "Do not manually edit this!! If it is corrupted, cg@1637: the ImageEditor may not be able to read the specification." cg@3419: cg@1637: " cg@3419: self specialRectangleIcon inspect cg@3419: ImageEditor openOnClass:self andSelector:#specialRectangleIcon cg@3419: Icon flushCachedIcons cg@3419: " cg@3419: cg@3419: cg@3419: cg@3419: ^Icon cg@3419: constantNamed:'ImageEditor class specialRectangleIcon' cg@3442: ifAbsentPut:[(Depth2Image width:14 height:14) bits:(ByteArray fromPackedString:'@@@@@@@@@@@UPAU@DBB@PA@@@D@P@@A@D@@@PA@@@D@PHHA@D@@@PA@@@D@UPAU@@@@@@@@@@@@b') cg@3442: colorMapFromArray:#[0 0 0 255 0 0 127 127 127] cg@3442: mask:((ImageMask width:14 height:14) bits:(ByteArray fromPackedString:'@@@@@G-8Q8!!G"D^HQ8!!G"D^HP0!!@BG-8@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@3191: cg@2375: "Do not manually edit this!! If it is corrupted, cg@2375: the ImageEditor may not be able to read the specification." cg@3191: cg@2375: " cg@2375: self sprayIcon inspect cg@2375: ImageEditor openOnClass:self andSelector:#sprayIcon cg@3191: Icon flushCachedIcons cg@3191: " cg@3191: cg@3191: cg@3191: cg@3191: ^Icon cg@3191: constantNamed:'ImageEditor sprayIcon' cg@3191: ifAbsentPut:[(Depth4Image new) width:14; height:14; bits:(ByteArray fromPackedString:'@@@@@@@@@@@@@@@@@@@@@@@@@@@P@@@@@@DA@P@@@@@PDA@@@@@@@PDA@@@@@@@PD@@@@"H@@PD@@@H"@@@@@@@ADP@@@@@@@QD@@@@@@@DQ@@@@@@@ADP@@ cg@3191: @@@@@@@@@@@b') ; colorMapFromArray:#[0 0 0 255 0 0 255 255 255]; mask:((ImageMask new) width:14; height:14; bits:(ByteArray fromPackedString:'@@@@@@@HA%PF*@ITA2 O%@>@C8@O @>@C8@O @@a') ; yourself); yourself] martin@1433: ! ! tz@737: tz@400: !ImageEditor class methodsFor:'interface specs'! tz@400: cg@1650: changeHLSDialogSpec cg@1650: "This resource specification was automatically generated cg@1650: by the UIPainter of ST/X." cg@1650: cg@1650: "Do not manually edit this!! If it is corrupted, cg@1650: the UIPainter may not be able to read the specification." cg@1650: cg@1650: " cg@1650: UIPainter new openOnClass:ImageEditor andSelector:#changeHLSDialogSpec cg@1650: ImageEditor new openInterface:#changeHLSDialogSpec cg@1650: " cg@1650: cg@1650: cg@1650: cg@1650: ^ cg@3468: #(FullSpec cg@3468: name: changeHLSDialogSpec cg@3562: uuid: 'b5dfeb64-6197-11e8-a86d-b8f6b1108e05' cg@3468: window: cg@3468: (WindowSpec cg@3468: label: 'HLS Edit Dialog' cg@3468: name: 'HLS Edit Dialog' cg@3562: uuid: '3787f3b8-6194-11e8-a86d-b8f6b1108e05' cg@3468: min: (Point 10 10) cg@3468: bounds: (Rectangle 0 0 378 312) cg@3468: ) cg@3468: component: cg@3468: (SpecCollection cg@3468: collection: ( cg@3468: (LabelSpec cg@3468: label: 'Hue-Shift:' cg@3468: name: 'HueLabel' cg@3562: layout: (LayoutFrame 4 0 21 0 171 0 43 0) cg@3562: activeHelpKey: hueShift cg@3562: uuid: '3787f638-6194-11e8-a86d-b8f6b1108e05' cg@3468: translateLabel: true cg@3468: adjust: right cg@3468: ) cg@3468: (InputFieldSpec cg@3468: name: 'HueShiftEntryField' cg@3562: layout: (LayoutFrame 172 0 21 0 243 0 43 0) cg@3562: activeHelpKey: hueShift cg@3562: uuid: '3787f84a-6194-11e8-a86d-b8f6b1108e05' cg@3468: tabable: true cg@3562: model: hueShiftHolder cg@3468: type: numberInRange cg@3468: minValue: 0 cg@3468: maxValue: 360 cg@3468: acceptChannel: acceptChannel cg@3562: acceptOnPointerLeave: true cg@3468: ) cg@3468: (ThumbWheelSpec cg@3468: name: 'HueWheel' cg@3468: layout: (LayoutFrame 246 0 22 0 363 0 42 0) cg@3562: activeHelpKey: hueShift cg@3562: uuid: '3787fafc-6194-11e8-a86d-b8f6b1108e05' cg@3562: model: hueShiftHolder cg@3468: orientation: horizontal cg@3468: step: 1 cg@3468: endlessRotation: true cg@3468: ) cg@3562: (ActionButtonSpec cg@3562: name: 'resetHueShift' cg@3562: layout: (LayoutFrame -10 1 27 0 0 1 37 0) cg@3562: activeHelpKey: resetHueShift cg@3562: uuid: 'e8c1e754-6196-11e8-a86d-b8f6b1108e05' cg@3562: translateLabel: true cg@3562: model: resetHueShift cg@3562: ) cg@3468: (LabelSpec cg@3468: label: 'Light Factor:' cg@3468: name: 'LightLabel' cg@3562: layout: (LayoutFrame 4 0 50 0 171 0 72 0) cg@3562: activeHelpKey: lightFactor cg@3562: uuid: '3787fda4-6194-11e8-a86d-b8f6b1108e05' cg@3468: translateLabel: true cg@3468: adjust: right cg@3468: ) cg@3468: (InputFieldSpec cg@3468: name: 'LightEntryField' cg@3562: layout: (LayoutFrame 172 0 50 0 243 0 72 0) cg@3562: activeHelpKey: lightFactor cg@3562: uuid: '3787feee-6194-11e8-a86d-b8f6b1108e05' cg@3468: tabable: true cg@3562: model: lightFactorHolder cg@3468: type: numberInRange cg@3562: minValue: 0.0 cg@3562: maxValue: 10.0 cg@3468: acceptChannel: acceptChannel cg@3562: acceptOnPointerLeave: true cg@3468: ) cg@3468: (ThumbWheelSpec cg@3468: name: 'LightWheel' cg@3468: layout: (LayoutFrame 246 0 51 0 363 0 71 0) cg@3562: activeHelpKey: lightFactor cg@3562: uuid: '378800d8-6194-11e8-a86d-b8f6b1108e05' cg@3562: model: lightFactorHolder cg@3468: orientation: horizontal cg@3562: start: 0.0 cg@3562: stop: 10.0 cg@3562: step: 0.001 cg@3562: ) cg@3562: (ActionButtonSpec cg@3562: name: 'Button3' cg@3562: layout: (LayoutFrame -10 1 56 0 0 1 66 0) cg@3562: activeHelpKey: resetLightFactor cg@3562: uuid: 'e8c1eb50-6196-11e8-a86d-b8f6b1108e05' cg@3562: translateLabel: true cg@3562: model: resetLightFactor cg@3468: ) cg@3468: (LabelSpec cg@3468: label: 'Saturation Factor:' cg@3468: name: 'SaturationLabel' cg@3562: layout: (LayoutFrame 4 0 79 0 171 0 101 0) cg@3562: activeHelpKey: saturationFactor cg@3562: uuid: '3788022c-6194-11e8-a86d-b8f6b1108e05' cg@3468: translateLabel: true cg@3468: adjust: right cg@3468: ) cg@3468: (InputFieldSpec cg@3468: name: 'SaturationEntryField' cg@3562: layout: (LayoutFrame 172 0 79 0 243 0 101 0) cg@3562: activeHelpKey: saturationFactor cg@3562: uuid: '37880358-6194-11e8-a86d-b8f6b1108e05' cg@3468: tabable: true cg@3562: model: saturationFactorHolder cg@3468: type: numberInRange cg@3562: minValue: 0.0 cg@3562: maxValue: 10.0 cg@3468: acceptChannel: acceptChannel cg@3562: acceptOnPointerLeave: true cg@3468: ) cg@3468: (ThumbWheelSpec cg@3468: name: 'SaturationWheel' cg@3468: layout: (LayoutFrame 246 0 80 0 363 0 100 0) cg@3562: activeHelpKey: saturationFactor cg@3562: uuid: '3788051a-6194-11e8-a86d-b8f6b1108e05' cg@3562: model: saturationFactorHolder cg@3468: orientation: horizontal cg@3562: start: 0.0 cg@3562: stop: 10.0 cg@3562: step: 0.001 cg@3562: ) cg@3562: (ActionButtonSpec cg@3562: name: 'Button4' cg@3562: layout: (LayoutFrame -10 1 85 0 0 1 95 0) cg@3562: activeHelpKey: resetSaturationFactor cg@3562: uuid: 'e8c1efce-6196-11e8-a86d-b8f6b1108e05' cg@3562: translateLabel: true cg@3562: model: resetSaturationFactor cg@3468: ) cg@3468: (LabelSpec cg@3468: label: 'Color Shift' cg@3468: name: 'Label2' cg@3468: layout: (LayoutFrame 5 0 127 0 -15 0.5 149 0) cg@3562: uuid: '37880650-6194-11e8-a86d-b8f6b1108e05' cg@3468: translateLabel: true cg@3468: ) cg@3468: (LabelSpec cg@3468: name: 'HueColorLabel' cg@3468: layout: (LayoutFrame 18 0.0 150 0 -41 0.5 234 0) cg@3562: uuid: '37880768-6194-11e8-a86d-b8f6b1108e05' cg@3468: level: -1 cg@3468: backgroundChannel: hlsColor cg@3468: translateLabel: true cg@3468: ) cg@3468: (LabelSpec cg@3468: label: 'Preview' cg@3468: name: 'Label3' cg@3468: layout: (LayoutFrame 5 0.5 127 0 -5 1 149 0) cg@3562: uuid: '37880894-6194-11e8-a86d-b8f6b1108e05' cg@3468: translateLabel: true cg@3468: ) cg@3468: (LabelSpec cg@3468: name: 'PreviewLabel' cg@3468: layout: (LayoutFrame 36 0.5 150 0 -23 1.0 234 0) cg@3562: uuid: '378809ac-6194-11e8-a86d-b8f6b1108e05' cg@3468: level: -1 cg@3468: translateLabel: true cg@3468: labelChannel: previewImageHolder cg@3468: ) cg@3468: (HorizontalPanelViewSpec cg@3468: name: 'HorizontalPanel1' cg@3562: layout: (LayoutFrame 0 0.0 -30 1 -16 1.0 0 1) cg@3562: uuid: '37880ace-6194-11e8-a86d-b8f6b1108e05' cg@3468: horizontalLayout: fitSpace cg@3468: verticalLayout: center cg@3468: horizontalSpace: 3 cg@3468: verticalSpace: 3 cg@3468: reverseOrderIfOKAtLeft: true cg@3468: component: cg@3468: (SpecCollection cg@3468: collection: ( cg@3468: (ActionButtonSpec cg@3468: label: 'Cancel' cg@3468: name: 'Button1' cg@3562: uuid: '37880cd6-6194-11e8-a86d-b8f6b1108e05' cg@3468: translateLabel: true cg@3468: tabable: true cg@3468: model: cancel cg@3562: extent: (Point 175 28) sv@1740: ) cg@3468: (ActionButtonSpec cg@3468: label: 'OK' cg@3468: name: 'Button2' cg@3562: uuid: '37880ee8-6194-11e8-a86d-b8f6b1108e05' cg@3468: translateLabel: true cg@3468: tabable: true cg@3468: model: accept cg@3562: extent: (Point 175 28) cg@3468: ) cg@3468: ) cg@3468: cg@3468: ) cg@3468: keepSpaceForOSXResizeHandleH: true sv@1740: ) cg@3468: ) cg@3468: cg@3468: ) cg@3468: ) cg@3562: cg@3562: "Modified: / 27-05-2018 / 12:27:58 / Claus Gittinger" sv@1740: ! sv@1740: cg@3413: cropSpec 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: " cg@3413: UIPainter new openOnClass:ImageEditor andSelector:#cropSpec cg@3413: ImageEditor new openInterface:#cropSpec sv@1740: " sv@1740: sv@1740: sv@1740: sv@1740: ^ cg@3376: #(FullSpec cg@3413: name: cropSpec cg@3376: window: cg@3376: (WindowSpec cg@3376: label: 'Crop Border(s)' cg@3376: name: 'Crop Border(s)' cg@3376: min: (Point 10 10) cg@3408: bounds: (Rectangle 0 0 364 312) cg@3376: ) cg@3376: component: cg@3376: (SpecCollection cg@3376: collection: ( cg@3376: (LabelSpec cg@3376: label: 'Left:' cg@3413: name: 'CropLeftLabel' cg@3376: layout: (LayoutFrame 14 0 24 0 90 0 46 0) cg@3413: activeHelpKey: cropLeft cg@3376: translateLabel: true cg@3404: adjust: left cg@3376: ) cg@3376: (InputFieldSpec cg@3413: name: 'CropLeftEntryField' cg@3404: layout: (LayoutFrame 95 0 24 0 125 0 46 0) cg@3413: activeHelpKey: cropLeft cg@3376: tabable: true cg@3413: model: cropLeftAmount cg@3376: type: number cg@3376: acceptChannel: acceptChannel cg@3376: acceptOnPointerLeave: false cg@3376: ) cg@3376: (ActionButtonSpec cg@3413: label: 'Crop Now' cg@3413: name: 'CropLeftNowButton' cg@3417: layout: (LayoutFrame 133 0 21 0 229 0 50 0) cg@3413: activeHelpKey: cropLeft cg@3376: translateLabel: true cg@3376: resizeForLabel: true cg@3376: tabable: true cg@3413: model: cropLeftNow cg@3376: autoRepeat: true cg@3376: usePreferredWidth: true cg@3376: ) cg@3417: (ActionButtonSpec cg@3417: label: 'Auto' cg@3417: name: 'Button6' cg@3417: layout: (LayoutFrame 236 0 21 0 289 0 50 0) cg@3417: activeHelpKey: autoCropLeft cg@3417: translateLabel: true cg@3417: resizeForLabel: true cg@3417: tabable: true cg@3417: model: autoCropLeft cg@3417: autoRepeat: true cg@3417: usePreferredWidth: true cg@3417: ) cg@3376: (LabelSpec cg@3376: label: 'Right:' cg@3413: name: 'CropRightLabel' cg@3376: layout: (LayoutFrame 14 0 55 0 90 0 77 0) cg@3413: activeHelpKey: cropRight cg@3376: translateLabel: true cg@3404: adjust: left cg@3376: ) cg@3376: (InputFieldSpec cg@3413: name: 'CropRightEntryField' cg@3404: layout: (LayoutFrame 95 0 55 0 125 0 77 0) cg@3413: activeHelpKey: cropRight cg@3376: tabable: true cg@3413: model: cropRightAmount cg@3376: type: number cg@3376: acceptChannel: acceptChannel cg@3376: acceptOnPointerLeave: false cg@3376: ) cg@3376: (ActionButtonSpec cg@3413: label: 'Crop Now' cg@3413: name: 'CropRightButton' cg@3417: layout: (LayoutFrame 133 0 51 0 229 0 80 0) cg@3413: activeHelpKey: cropRight cg@3376: translateLabel: true cg@3376: resizeForLabel: true cg@3376: tabable: true cg@3413: model: cropRightNow cg@3376: autoRepeat: true cg@3376: usePreferredWidth: true cg@3376: ) cg@3417: (ActionButtonSpec cg@3417: label: 'Auto' cg@3417: name: 'Button7' cg@3417: layout: (LayoutFrame 236 0 51 0 289 0 80 0) cg@3417: activeHelpKey: autoCropRight cg@3417: translateLabel: true cg@3417: resizeForLabel: true cg@3417: tabable: true cg@3417: model: autoCropRight cg@3417: autoRepeat: true cg@3417: usePreferredWidth: true cg@3417: ) cg@3376: (LabelSpec cg@3376: label: 'Top:' cg@3413: name: 'CropTopLabel' cg@3376: layout: (LayoutFrame 14 0 85 0 90 0 107 0) cg@3413: activeHelpKey: cropTop cg@3376: translateLabel: true cg@3404: adjust: left cg@3376: ) cg@3376: (InputFieldSpec cg@3413: name: 'CropTopEntryField' cg@3404: layout: (LayoutFrame 95 0 85 0 125 0 107 0) cg@3413: activeHelpKey: cropTop cg@3376: tabable: true cg@3413: model: cropTopAmount cg@3376: type: number cg@3376: acceptChannel: acceptChannel cg@3376: acceptOnPointerLeave: false cg@3376: ) cg@3376: (ActionButtonSpec cg@3413: label: 'Crop Now' cg@3413: name: 'CropTopButton' cg@3417: layout: (LayoutFrame 133 0 81 0 229 0 110 0) cg@3413: activeHelpKey: cropTop cg@3376: translateLabel: true cg@3376: resizeForLabel: true cg@3376: tabable: true cg@3413: model: cropTopNow cg@3376: autoRepeat: true cg@3376: usePreferredWidth: true cg@3376: ) cg@3417: (ActionButtonSpec cg@3417: label: 'Auto' cg@3417: name: 'Button8' cg@3417: layout: (LayoutFrame 236 0 81 0 289 0 110 0) cg@3417: activeHelpKey: autoCropTop cg@3417: translateLabel: true cg@3417: resizeForLabel: true cg@3417: tabable: true cg@3417: model: autoCropTop cg@3417: autoRepeat: true cg@3417: usePreferredWidth: true cg@3417: ) cg@3376: (LabelSpec cg@3376: label: 'Bottom:' cg@3413: name: 'CropBottomLabel' cg@3376: layout: (LayoutFrame 14 0 115 0 90 0 137 0) cg@3413: activeHelpKey: cropBottom cg@3376: translateLabel: true cg@3404: adjust: left cg@3376: ) cg@3376: (InputFieldSpec cg@3413: name: 'CropBottomEntryField' cg@3404: layout: (LayoutFrame 95 0 115 0 125 0 137 0) cg@3413: activeHelpKey: cropBottom cg@3376: tabable: true cg@3413: model: cropBottomAmount cg@3376: type: number cg@3376: acceptChannel: acceptChannel cg@3376: acceptOnPointerLeave: false cg@3376: ) cg@3376: (ActionButtonSpec cg@3413: label: 'Crop Now' cg@3413: name: 'CropBottomButton' cg@3417: layout: (LayoutFrame 133 0 111 0 229 0 140 0) cg@3413: activeHelpKey: cropBottom cg@3376: translateLabel: true cg@3376: resizeForLabel: true cg@3376: tabable: true cg@3413: model: cropBottomNow cg@3376: autoRepeat: true cg@3376: usePreferredWidth: true cg@3376: ) cg@3408: (ActionButtonSpec cg@3417: label: 'Auto' cg@3417: name: 'Button9' cg@3417: layout: (LayoutFrame 236 0 111 0 289 0 140 0) cg@3417: activeHelpKey: autoCropBottom cg@3417: translateLabel: true cg@3417: resizeForLabel: true cg@3417: tabable: true cg@3417: model: autoCropBottom cg@3417: autoRepeat: true cg@3417: usePreferredWidth: true cg@3417: ) cg@3417: (ActionButtonSpec cg@3417: label: 'All' cg@3408: name: 'Button4' cg@3417: layout: (LayoutFrame 133 0 148 0 229 0 176 0) cg@3413: activeHelpKey: cropAll cg@3408: translateLabel: true cg@3408: resizeForLabel: true cg@3408: tabable: true cg@3408: model: applyCropAction cg@3408: ) cg@3376: (HorizontalPanelViewSpec cg@3376: name: 'HorizontalPanel1' cg@3413: layout: (LayoutFrame 0 0.0 -30 1 0 1.0 0 1) cg@3400: visibilityChannel: cropBoxIsDialog cg@3376: horizontalLayout: fitSpace cg@3376: verticalLayout: center cg@3376: horizontalSpace: 3 cg@3376: verticalSpace: 3 cg@3376: reverseOrderIfOKAtLeft: true cg@3376: component: cg@3376: (SpecCollection cg@3376: collection: ( cg@3376: (ActionButtonSpec cg@3376: label: 'Cancel' cg@3376: name: 'Button1' cg@3376: translateLabel: true cg@3376: resizeForLabel: true cg@3376: tabable: true cg@3376: model: cancel cg@3413: extent: (Point 116 28) cg@1650: ) cg@3376: (ActionButtonSpec cg@3376: label: 'Apply' cg@3376: name: 'Button3' cg@3376: translateLabel: true cg@3376: resizeForLabel: true cg@3376: tabable: true cg@3408: model: applyCropAction cg@3413: extent: (Point 116 28) cg@3376: ) cg@3376: (ActionButtonSpec cg@3376: label: 'OK' cg@3376: name: 'Button2' cg@3376: translateLabel: true cg@3376: resizeForLabel: true cg@3376: tabable: true cg@3376: model: accept cg@3413: extent: (Point 116 28) cg@3376: ) cg@3376: ) cg@3376: cg@3376: ) cg@3408: ) cg@3417: (ActionButtonSpec cg@3417: label: 'All' cg@3417: name: 'Button10' cg@3417: layout: (LayoutFrame 236 0 148 0 289 0 176 0) cg@3417: activeHelpKey: autoCropAll cg@3417: translateLabel: true cg@3417: resizeForLabel: true cg@3417: tabable: true cg@3417: model: autoCropAll cg@3417: ) cg@3376: ) cg@3376: cg@3376: ) cg@3376: ) 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: ^ cg@3494: #(FullSpec cg@3494: name: dialogSpecForNewImage cg@3494: window: cg@3494: (WindowSpec cg@3494: label: 'New Image' cg@3494: name: 'New Image' cg@3494: min: (Point 10 10) cg@3494: bounds: (Rectangle 0 0 301 119) cg@3494: ) cg@3494: component: cg@3494: (SpecCollection cg@3494: collection: ( cg@3494: (ViewSpec cg@3494: name: 'View' cg@3494: layout: (LayoutFrame 0 0.0 0 0.0 0 1.0 -35 1.0) cg@3494: level: 1 cg@3494: component: cg@3494: (SpecCollection cg@3494: collection: ( cg@3494: (FramedBoxSpec cg@3494: label: 'Size' cg@3494: name: 'framedBox1' cg@3494: layout: (LayoutFrame 1 0.0 7 0.0 0 0.40000000000000002 76 0) cg@3494: style: (FontDescription helvetica medium roman 12) cg@3494: labelPosition: topLeft cg@3494: translateLabel: true cg@3494: component: cg@3494: (SpecCollection cg@3494: collection: ( cg@3494: (ComboBoxSpec cg@3494: name: 'defaultSizesComboBox' cg@3494: layout: (LayoutFrame 0 0.0 10 0.0 0 1 35 0.0) cg@3494: model: selectionOfSize cg@3494: type: string cg@3494: acceptOnPointerLeave: false cg@3494: comboList: listOfDefaultSizes cg@3494: isFilenameBox: false sv@1740: ) cg@3494: ) cg@3494: cg@3494: ) cg@3494: ) cg@3494: (FramedBoxSpec cg@3494: label: 'Color Map' cg@3494: name: 'framedBox2' cg@3494: layout: (LayoutFrame 0 0.40000000000000002 7 0.0 -1 1.0 76 0) cg@3494: style: (FontDescription helvetica medium roman 12) cg@3494: labelPosition: topLeft cg@3494: translateLabel: true cg@3494: component: cg@3494: (SpecCollection cg@3494: collection: ( cg@3494: (ComboListSpec cg@3494: name: 'colorMapComboBox' cg@3494: layout: (LayoutFrame 0 0.0 10 0.0 0 1 35 0.0) cg@3494: model: selectionOfColorMap cg@3494: comboList: listOfColorMaps cg@3494: useIndex: false cg@3494: hidePullDownMenuButton: false sv@1740: ) cg@3494: ) cg@3494: cg@3494: ) cg@1457: ) cg@3494: ) cg@3494: cg@3494: ) cg@1457: ) cg@3494: (UISubSpecification cg@3494: name: 'windowSpecForCommitWithoutChannels' cg@3494: layout: (LayoutFrame 2 0.0 -37 1 -2 1.0 -2 1.0) cg@3494: minorKey: windowSpecForCommitWithoutChannels cg@3494: keepSpaceForOSXResizeHandleH: true cg@3494: ) cg@3494: ) cg@3494: cg@3494: ) cg@3494: ) cg@986: ! cg@986: cg@3413: floodFillToleranceSpec cg@3413: "This resource specification was automatically generated cg@3413: by the UIPainter of ST/X." cg@3413: cg@3413: "Do not manually edit this!! If it is corrupted, cg@3413: the UIPainter may not be able to read the specification." cg@3413: cg@3413: " cg@3413: UIPainter new openOnClass:ImageEditor andSelector:#floodFillToleranceSpec cg@3413: ImageEditor new openInterface:#floodFillToleranceSpec cg@3413: " cg@3413: cg@3413: cg@3413: cg@3413: ^ cg@3413: #(FullSpec cg@3413: name: floodFillToleranceSpec cg@3413: window: cg@3413: (WindowSpec cg@3413: label: 'Flood Fill Tolerance' cg@3413: name: 'Flood Fill Tolerance' cg@3413: min: (Point 10 10) cg@3413: bounds: (Rectangle 0 0 364 312) cg@3413: ) cg@3413: component: cg@3413: (SpecCollection cg@3413: collection: ( cg@3413: (LabelSpec cg@3413: label: 'Flood Fill Tolerance:' cg@3413: name: 'Label1' cg@3413: layout: (LayoutFrame 14 0 10 0 242 0 32 0) cg@3413: activeHelpKey: floodFillMaxError cg@3413: visibilityChannel: cropBoxIsNotDialog cg@3413: translateLabel: true cg@3413: adjust: left cg@3413: ) cg@3413: (LabelSpec cg@3413: label: 'Hue:' cg@3413: name: 'Label2' cg@3440: layout: (LayoutFrame 29 0 38 0 127 0 60 0) cg@3413: activeHelpKey: floodFillMaxError cg@3413: visibilityChannel: cropBoxIsNotDialog cg@3413: translateLabel: true cg@3413: adjust: left cg@3413: ) cg@3413: (InputFieldSpec cg@3413: name: 'EntryField2' cg@3413: layout: (LayoutFrame 132 0 38 0 190 0 60 0) cg@3413: activeHelpKey: floodFillMaxError cg@3413: visibilityChannel: cropBoxIsNotDialog cg@3413: tabable: true cg@3413: model: floodFillMaxHueError cg@3413: type: number cg@3413: acceptChannel: acceptChannel cg@3413: acceptOnPointerLeave: true cg@3413: ) cg@3413: (LabelSpec cg@3413: label: 'Light:' cg@3413: name: 'Label3' cg@3440: layout: (LayoutFrame 29 0 64 0 127 0 86 0) cg@3413: activeHelpKey: floodFillMaxError cg@3413: visibilityChannel: cropBoxIsNotDialog cg@3413: translateLabel: true cg@3413: adjust: left cg@3413: ) cg@3413: (InputFieldSpec cg@3413: name: 'EntryField3' cg@3413: layout: (LayoutFrame 132 0 64 0 190 0 86 0) cg@3413: activeHelpKey: floodFillMaxError cg@3413: visibilityChannel: cropBoxIsNotDialog cg@3413: tabable: true cg@3413: model: floodFillMaxLightError cg@3413: type: number cg@3413: acceptChannel: acceptChannel cg@3413: acceptOnPointerLeave: true cg@3413: ) cg@3413: (HorizontalPanelViewSpec cg@3413: name: 'HorizontalPanel1' cg@3413: layout: (LayoutFrame 0 0.0 -30 1 0 1.0 0 1) cg@3413: visibilityChannel: cropBoxIsDialog cg@3413: horizontalLayout: fitSpace cg@3413: verticalLayout: center cg@3413: horizontalSpace: 3 cg@3413: verticalSpace: 3 cg@3413: reverseOrderIfOKAtLeft: true cg@3413: component: cg@3413: (SpecCollection cg@3413: collection: ( cg@3413: (ActionButtonSpec cg@3413: label: 'Cancel' cg@3413: name: 'Button1' cg@3413: translateLabel: true cg@3413: resizeForLabel: true cg@3413: tabable: true cg@3413: model: cancel cg@3413: extent: (Point 116 28) cg@3413: ) cg@3413: (ActionButtonSpec cg@3413: label: 'Apply' cg@3413: name: 'Button3' cg@3413: translateLabel: true cg@3413: resizeForLabel: true cg@3413: tabable: true cg@3413: model: applyCropAction cg@3413: extent: (Point 116 28) cg@3413: ) cg@3413: (ActionButtonSpec cg@3413: label: 'OK' cg@3413: name: 'Button2' cg@3413: translateLabel: true cg@3413: resizeForLabel: true cg@3413: tabable: true cg@3413: model: accept cg@3413: extent: (Point 116 28) cg@3413: ) cg@3413: ) cg@3413: cg@3413: ) cg@3413: ) cg@3413: ) cg@3413: cg@3413: ) cg@3413: ) cg@3413: ! cg@3413: 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: cg@3413: uncropSpec 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@3413: UIPainter new openOnClass:ImageEditor andSelector:#uncropSpec cg@3413: ImageEditor new openInterface:#uncropSpec cg@1480: " cg@1796: cg@1796: cg@1796: cg@1796: ^ cg@3413: #(FullSpec cg@3413: name: uncropSpec cg@3413: window: cg@3413: (WindowSpec cg@3413: label: 'Add Border(s)' cg@3413: name: 'Add Border(s)' cg@3413: min: (Point 10 10) cg@3413: max: (Point 800 478) cg@3413: bounds: (Rectangle 0 0 261 228) cg@3413: ) cg@3413: component: cg@3413: (SpecCollection cg@3413: collection: ( cg@3413: (LabelSpec cg@3413: label: 'Left:' cg@3413: name: 'Label1' cg@3413: layout: (LayoutFrame 14 0 21 0 90 0 43 0) cg@3413: translateLabel: true cg@3413: adjust: right cg@3413: ) cg@3413: (InputFieldSpec cg@3413: name: 'EntryField1' cg@3413: layout: (LayoutFrame 95 0 21 0 132 0 43 0) cg@3413: model: cropLeftAmount cg@3413: type: number cg@3413: acceptOnPointerLeave: false cg@3413: ) cg@3413: (LabelSpec cg@3413: label: 'Right:' cg@3413: name: 'Label2' cg@3413: layout: (LayoutFrame 14 0 51 0 90 0 73 0) cg@3413: translateLabel: true cg@3413: adjust: right cg@3413: ) cg@3413: (InputFieldSpec cg@3413: name: 'EntryField2' cg@3413: layout: (LayoutFrame 95 0 51 0 132 0 73 0) cg@3413: model: cropRightAmount cg@3413: type: number cg@3413: acceptOnPointerLeave: false cg@3413: ) cg@3413: (LabelSpec cg@3413: label: 'Top:' cg@3413: name: 'Label3' cg@3413: layout: (LayoutFrame 14 0 81 0 90 0 103 0) cg@3413: translateLabel: true cg@3413: adjust: right cg@3413: ) cg@3413: (InputFieldSpec cg@3413: name: 'EntryField3' cg@3413: layout: (LayoutFrame 95 0 81 0 132 0 103 0) cg@3413: model: cropTopAmount cg@3413: type: number cg@3413: acceptOnPointerLeave: false cg@3413: ) cg@3413: (LabelSpec cg@3413: label: 'Bottom:' cg@3413: name: 'Label4' cg@3413: layout: (LayoutFrame 14 0 111 0 90 0 133 0) cg@3413: translateLabel: true cg@3413: adjust: right cg@3413: ) cg@3413: (InputFieldSpec cg@3413: name: 'EntryField4' cg@3413: layout: (LayoutFrame 95 0 111 0 132 0 133 0) cg@3413: model: cropBottomAmount cg@3413: type: number cg@3413: acceptOnPointerLeave: false cg@3413: ) cg@3413: (HorizontalPanelViewSpec cg@3413: name: 'HorizontalPanel1' cg@3413: layout: (LayoutFrame 0 0.0 -30 1 0 1.0 0 1) cg@3413: horizontalLayout: fitSpace cg@3413: verticalLayout: center cg@3413: horizontalSpace: 3 cg@3413: verticalSpace: 3 cg@3413: reverseOrderIfOKAtLeft: true cg@3413: component: cg@3413: (SpecCollection cg@3413: collection: ( cg@3413: (ActionButtonSpec cg@3413: label: 'Cancel' cg@3413: name: 'Button1' cg@3413: translateLabel: true cg@3413: model: cancel cg@3413: extent: (Point 124 22) cg@1796: ) cg@3413: (ActionButtonSpec cg@3413: label: 'OK' cg@3413: name: 'Button2' cg@3413: translateLabel: true cg@3413: model: accept cg@3413: extent: (Point 125 22) cg@3413: ) cg@3413: ) cg@3413: cg@3413: ) cg@1796: ) cg@3413: ) cg@3413: cg@3413: ) cg@3413: ) cg@1480: ! cg@1480: tz@767: windowSpec tz@767: "This resource specification was automatically generated tz@767: by the UIPainter of ST/X." tz@767: tz@767: "Do not manually edit this!! If it is corrupted, tz@767: the UIPainter may not be able to read the specification." tz@767: tz@767: " tz@767: UIPainter new openOnClass:ImageEditor andSelector:#windowSpec tz@767: ImageEditor new openInterface:#windowSpec tz@767: ImageEditor open tz@767: " tz@767: tz@767: tz@767: cg@1558: ^ cg@3195: #(FullSpec cg@3195: name: windowSpec mawalch@3546: uuid: 'ea3a8340-1e4a-11b2-83b1-485b39758412' cg@3195: window: cg@3195: (WindowSpec cg@3195: label: 'Image Editor' cg@3195: name: 'Image Editor' mawalch@3546: uuid: 'ea3a8bec-1e4a-11b2-83b1-485b39758412' cg@3443: min: (Point 800 400) cg@3443: bounds: (Rectangle 0 0 800 446) cg@3195: menu: menu cg@3195: icon: defaultIcon cg@3195: ) cg@3195: component: cg@3195: (SpecCollection cg@3195: collection: ( cg@3195: (MenuPanelSpec cg@3195: name: 'menuToolbarView' cg@3195: layout: (LayoutFrame 0 0.0 0 0 0 1.0 32 0) mawalch@3546: style: (FontDescription helvetica medium roman 10 #'iso10646-1' nil nil) mawalch@3546: uuid: 'ea3a98c6-1e4a-11b2-83b1-485b39758412' cg@3195: menu: menuToolbar cg@3195: showSeparatingLines: true cg@3195: ) cg@3195: (VariableHorizontalPanelSpec cg@3195: name: 'mainPanel' cg@3195: layout: (LayoutFrame 0 0.0 34 0.0 0 1.0 -26 1.0) mawalch@3546: uuid: 'ea3a9eca-1e4a-11b2-83b1-485b39758412' cg@3195: snapMode: both cg@3195: barLevel: 0 cg@3195: component: cg@3195: (SpecCollection cg@3195: collection: ( cg@3195: (ViewSpec cg@3195: name: 'leftView' mawalch@3546: uuid: 'ea3aa3d4-1e4a-11b2-83b1-485b39758412' cg@3195: level: 1 cg@3195: component: cg@3195: (SpecCollection cg@3195: collection: ( cg@3195: (VariableVerticalPanelSpec cg@3195: name: 'verticalPanel' cg@3195: layout: (LayoutFrame 0 0.0 0 0.0 0 1.0 0 1.0) mawalch@3546: uuid: 'ea3aa672-1e4a-11b2-83b1-485b39758412' cg@3195: level: 0 cg@3195: snapMode: both cg@3195: component: cg@3195: (SpecCollection cg@3195: collection: ( cg@3195: (ViewSpec cg@3404: name: 'ColorAnCropBox' mawalch@3546: uuid: 'ea3aa992-1e4a-11b2-83b1-485b39758412' cg@3195: component: cg@3195: (SpecCollection cg@3195: collection: ( cg@3413: (TabViewSpec cg@3413: name: 'TabHeader1' cg@3413: layout: (LayoutFrame 0 0 0 0 0 1 36 0) mawalch@3546: uuid: 'ea3aab9a-1e4a-11b2-83b1-485b39758412' cg@3413: model: colorCropTabSelectionIndexHolder cg@3413: menu: colorCropTabLabelList cg@3413: useIndex: true cg@3413: translateLabel: true cg@3413: ) cg@3413: (ViewSpec cg@3413: name: 'ColorBox' cg@3413: layout: (LayoutFrame 0 0 36 0 0 1 0 1) mawalch@3546: uuid: 'ea3ab0ae-1e4a-11b2-83b1-485b39758412' cg@3413: visibilityChannel: colorBoxVisibleHolder cg@3413: component: cg@3413: (SpecCollection cg@3413: collection: ( cg@3413: (MenuPanelSpec cg@3413: name: 'MouseButtonColorToolBar' cg@3413: layout: (LayoutFrame 0 0.0 0 0 0 1.0 24 0) mawalch@3546: uuid: 'ea3ab2d4-1e4a-11b2-83b1-485b39758412' cg@3413: level: 0 cg@3413: menu: menuMouseButtonColors cg@3413: ) cg@3487: (LabelSpec cg@3487: label: 'Label' cg@3487: name: 'Label1' cg@3487: layout: (LayoutFrame -160 1 0 0 -104 1 22 0) mawalch@3546: activeHelpKey: drawingAlpha mawalch@3546: uuid: 'ea3ab590-1e4a-11b2-83b1-485b39758412' mawalch@3546: visibilityChannel: alphaVisibleHolder cg@3487: translateLabel: true cg@3487: labelChannel: alphaText cg@3487: ) cg@3487: (InputFieldSpec cg@3487: name: 'EntryField1' cg@3487: layout: (LayoutFrame -106 1 2 0 -56 1 22 0) mawalch@3546: activeHelpKey: drawingAlpha mawalch@3546: uuid: 'ea3aba90-1e4a-11b2-83b1-485b39758412' mawalch@3546: visibilityChannel: alphaVisibleHolder mawalch@3546: model: alphaHolder mawalch@3546: type: numberInRange cg@3487: acceptOnReturn: true cg@3487: acceptOnTab: true mawalch@3546: numChars: 3 mawalch@3546: minValue: 0 mawalch@3546: maxValue: 100 cg@3487: acceptOnPointerLeave: true cg@3487: ) cg@3421: (ViewSpec cg@3421: name: 'Box1' cg@3421: layout: (LayoutFrame -40 1.0 4 0 -26 1.0 18 0) cg@3421: activeHelpKey: drawingColor1 mawalch@3546: uuid: 'ea3ac1c0-1e4a-11b2-83b1-485b39758412' cg@3421: level: -1 cg@3421: backgroundChannel: drawingColor1Holder cg@3421: ) cg@3421: (ViewSpec cg@3421: name: 'Box2' cg@3421: layout: (LayoutFrame -25 1.0 4 0 -11 1.0 18 0) cg@3421: activeHelpKey: drawingColor2 mawalch@3546: uuid: 'ea3ac418-1e4a-11b2-83b1-485b39758412' cg@3421: level: -1 cg@3421: backgroundChannel: drawingColor2Holder cg@3421: ) cg@3413: (DataSetSpec cg@3413: name: 'colorDataSetView' cg@3413: layout: (LayoutFrame 0 0.0 26 0.0 0 1.0 0 1.0) cg@3413: activeHelpKey: colorMapTable mawalch@3546: style: (FontDescription helvetica medium roman 10 #'iso10646-1' nil nil) mawalch@3546: uuid: 'ea3ac652-1e4a-11b2-83b1-485b39758412' cg@3413: model: selectedColors cg@3475: menu: colorMapMenuHolder cg@3413: hasHorizontalScrollBar: true cg@3413: hasVerticalScrollBar: true cg@3413: miniScrollerHorizontal: true cg@3413: miniScrollerVertical: true cg@3413: dataList: listOfColors cg@3413: has3Dseparators: true cg@3413: doubleClickSelector: doubleClickOnColor: cg@3413: columnHolder: colorTableColumns cg@3413: multipleSelectOk: true cg@3413: verticalSpacing: 1 cg@3413: columnAdaptor: colorColumnAdaptor cg@3413: ) cg@3413: ) cg@3413: cg@3413: ) cg@3413: ) cg@3413: (ViewSpec cg@3413: name: 'FloodFillBox' cg@3413: layout: (LayoutFrame 0 0 36 0 0 1 0 1) mawalch@3546: uuid: 'ea3acfda-1e4a-11b2-83b1-485b39758412' cg@3413: visibilityChannel: floodFillBoxVisibleHolder cg@3413: component: cg@3413: (SpecCollection cg@3413: collection: ( cg@3413: (UISubSpecification cg@3413: name: 'SubSpecification2' cg@3413: layout: (LayoutFrame 0 0 0 0 0 1 0 1) mawalch@3546: uuid: 'ea3ad21e-1e4a-11b2-83b1-485b39758412' cg@3413: minorKey: floodFillToleranceSpec cg@3413: ) cg@3413: ) cg@3413: cg@3413: ) cg@3413: ) cg@3400: (ViewSpec cg@3400: name: 'CropBox' cg@3413: layout: (LayoutFrame 0 0 36 0 0 1 0 1) mawalch@3546: uuid: 'ea3ad552-1e4a-11b2-83b1-485b39758412' cg@3400: visibilityChannel: cropBoxVisibleHolder cg@3400: component: cg@3400: (SpecCollection cg@3400: collection: ( cg@3400: (UISubSpecification cg@3400: name: 'SubSpecification1' cg@3400: layout: (LayoutFrame 0 0 0 0 0 1 0 1) mawalch@3546: uuid: 'ea3ad76e-1e4a-11b2-83b1-485b39758412' cg@3413: minorKey: cropSpec cg@3400: ) cg@3400: ) cg@3400: cg@3400: ) cg@3400: ) cg@3195: ) cg@3195: cg@3195: ) cg@1558: ) cg@3195: (ArbitraryComponentSpec cg@3195: name: 'imagePreView' cg@3195: activeHelpKey: previewView mawalch@3546: uuid: 'ea3ad9a8-1e4a-11b2-83b1-485b39758412' cg@3195: menu: previewMenu cg@3195: hasHorizontalScrollBar: true cg@3195: hasVerticalScrollBar: true cg@3195: miniScrollerHorizontal: false cg@3195: miniScrollerVertical: false cg@3195: hasBorder: false cg@3195: component: ImageView cg@3195: ) cg@3195: ) cg@3195: cg@3195: ) cg@3195: handles: (Any 0.5 1.0) cg@1558: ) cg@3195: ) cg@3195: cg@3195: ) cg@3195: ) cg@3195: (ViewSpec cg@3195: name: 'rightView' mawalch@3546: uuid: 'ea3ade8a-1e4a-11b2-83b1-485b39758412' cg@3195: component: cg@3195: (SpecCollection cg@3195: collection: ( cg@3195: (MenuPanelSpec cg@3195: name: 'ToolBar1' cg@3195: layout: (LayoutFrame 0 0 0 0.0 28 0 0 1.0) mawalch@3546: uuid: 'ea3ae0b0-1e4a-11b2-83b1-485b39758412' cg@3195: level: 1 cg@3195: menu: toolsMenuToolbar cg@3195: verticalLayout: true cg@3195: centerItems: true cg@3195: textDefault: true cg@3195: ) cg@3195: (ViewSpec cg@3195: name: 'editingView' cg@3195: layout: (LayoutFrame 28 0.0 0 0.0 0 1.0 0 1.0) mawalch@3546: uuid: 'ea3ae3bc-1e4a-11b2-83b1-485b39758412' cg@3195: level: 1 cg@3195: component: cg@3195: (SpecCollection cg@3195: collection: ( cg@3195: (ArbitraryComponentSpec cg@3195: name: 'imageEditView' cg@3195: layout: (LayoutFrame 2 0.0 2 0.0 -2 1.0 -24 1.0) mawalch@3546: uuid: 'ea3ae5ec-1e4a-11b2-83b1-485b39758412' cg@3195: hasHorizontalScrollBar: true cg@3195: hasVerticalScrollBar: true cg@3195: hasBorder: false cg@3195: component: ImageEditView cg@3195: ) cg@3195: (LabelSpec cg@3195: name: 'coordLabel' cg@3195: layout: (LayoutFrame 2 0.0 -22 1 -83 1.0 0 1.0) mawalch@3546: uuid: 'ea3ae8da-1e4a-11b2-83b1-485b39758412' cg@3195: level: -1 cg@3195: translateLabel: true cg@3195: labelChannel: imageInfoHolder cg@3195: resizeForLabel: false cg@3195: adjust: left cg@1637: ) cg@3195: (ArrowButtonSpec cg@3195: name: 'magnifyDownButton' cg@3195: layout: (LayoutFrame -80 1 -22 1 -58 1 0 1) cg@3195: activeHelpKey: magnifyImageDown mawalch@3546: uuid: 'ea3aebd2-1e4a-11b2-83b1-485b39758412' cg@3195: translateLabel: true cg@3195: model: doMagnifyDown cg@3195: enableChannel: imageIsLoadedHolder cg@3195: isTriggerOnDown: true cg@3479: autoRepeat: true cg@3195: direction: left cg@3195: ) cg@3195: (ArrowButtonSpec cg@3195: name: 'magnifyUpButton' cg@3195: layout: (LayoutFrame -24 1 -22 1 -2 1 0 1) cg@3195: activeHelpKey: magnifyImageUp mawalch@3546: uuid: 'ea3af26c-1e4a-11b2-83b1-485b39758412' cg@3195: translateLabel: true cg@3195: model: doMagnifyUp cg@3195: enableChannel: imageIsLoadedHolder cg@3195: isTriggerOnDown: true cg@3479: autoRepeat: true cg@3195: direction: right cg@3195: ) cg@3195: (InputFieldSpec cg@3195: name: 'magnificationInputField' cg@3195: layout: (LayoutFrame -57 1 -22 1 -26 1 0 1) cg@3195: activeHelpKey: magnificationNumber mawalch@3546: uuid: 'ea3af62c-1e4a-11b2-83b1-485b39758412' cg@3195: enableChannel: imageIsLoadedHolder cg@3195: model: magnificationHolder cg@3195: type: numberInRange cg@3195: acceptOnReturn: true cg@3195: acceptOnTab: true cg@3195: numChars: 2 cg@3195: minValue: 1 cg@3195: maxValue: 99 cg@3195: acceptOnPointerLeave: true cg@3195: ) cg@3195: ) cg@3195: cg@3195: ) cg@1558: ) cg@3195: ) cg@3195: cg@3195: ) cg@1558: ) cg@3195: ) cg@3195: cg@3195: ) cg@3443: handles: (Any 0.47999999999999998 1.0) cg@1558: ) cg@3195: (UISubSpecification cg@3195: name: 'infoBarSubSpec' cg@3195: layout: (LayoutFrame 0 0.0 -24 1 0 1.0 0 1.0) mawalch@3546: uuid: 'ea3afaf0-1e4a-11b2-83b1-485b39758412' cg@3195: majorKey: ToolApplicationModel cg@3195: minorKey: windowSpecForInfoBar cg@3195: ) cg@3195: ) cg@3195: cg@3195: ) cg@3195: ) tz@519: ! ! tz@519: tz@519: !ImageEditor class methodsFor:'menu specs'! tz@519: cg@1053: colorMapMenu cg@1053: "This resource specification was automatically generated cg@1053: by the MenuEditor of ST/X." cg@1053: cg@1053: "Do not manually edit this!! If it is corrupted, cg@1053: the MenuEditor may not be able to read the specification." cg@1053: cg@3592: 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@3475: enabled: canAddColorToColormapHolder cg@1847: label: 'Add Color' cg@1847: itemValue: addColorToColormap cg@1847: ) cg@1847: (MenuItem cg@3475: enabled: canAddColorToColormapHolder cg@3496: label: 'Add & Paste Color' cg@3496: itemValue: addPastedColorToColormap cg@3496: ) cg@3496: (MenuItem cg@3496: enabled: canAddColorToColormapHolder cg@2539: label: 'Pick and Add Color...' cg@1847: itemValue: pickAndAddColorToColormap cg@1847: ) cg@1847: (MenuItem cg@1847: label: '-' cg@1847: ) cg@1847: (MenuItem cg@3475: enabled: hasColormapAndSingleColorSelectedHolder cg@1852: label: 'Cut Color' cg@1852: itemValue: cutColorFromColormap cg@1852: isVisible: false cg@1852: ) cg@1852: (MenuItem cg@3195: enabled: hasSingleColorSelectedHolder cg@1852: label: 'Copy Color' cg@1852: itemValue: copyColorFromColormap cg@2841: shortcutKey: Copy cg@1852: ) cg@1852: (MenuItem cg@3475: enabled: hasColormapAndSingleWritableColorSelectedHolder cg@2539: label: 'Pick and Paste Color...' cg@1933: itemValue: pickAndPasteColor cg@1852: ) cg@1852: (MenuItem cg@3475: enabled: canChangeColorInColormapHolder cg@1852: label: 'Paste Color' cg@1852: itemValue: pasteColorIntoColormap cg@2841: shortcutKey: Paste cg@1852: ) cg@1852: (MenuItem cg@1852: label: '-' cg@1852: ) cg@1852: (MenuItem cg@3475: enabled: hasColormapAndSingleWritableColorSelectedHolder cg@2539: label: 'Edit Color...' cg@1931: itemValue: editSelectedColor cg@3592: ) cg@3592: (MenuItem cg@3592: enabled: hasColormapAndColorSelected cg@3592: label: 'Make Gray' cg@3592: itemValue: makeSelectedColorGray cg@3592: ) cg@3592: (MenuItem cg@3592: enabled: hasColormapAndSingleWritableColorSelectedHolder cg@3592: label: 'Color Shift...' cg@3592: itemValue: makeSelectedColorShifted cg@3592: ) cg@3592: (MenuItem cg@3592: label: '-' cg@3592: ) cg@3592: (MenuItem cg@3592: enabled: hasColormapAndColorSelected cg@3592: label: 'Slightly Brighter' cg@3592: itemValue: makeSelectedColorSlightlyBrighter cg@3592: ) cg@3592: (MenuItem cg@3592: enabled: hasColormapAndColorSelected cg@3592: label: 'Slightly Darker' cg@3592: itemValue: makeSelectedColorSlightlyDarker cg@1931: ) cg@1931: (MenuItem cg@3553: enabled: hasColormapAndColorSelected cg@1847: label: 'Brighter' cg@1847: itemValue: makeSelectedColorBrighter cg@1847: ) cg@1847: (MenuItem cg@3553: enabled: hasColormapAndColorSelected cg@1847: label: 'Darker' cg@1847: itemValue: makeSelectedColorDarker cg@3195: ) cg@3195: (MenuItem cg@1847: label: '-' cg@1847: ) cg@1847: (MenuItem cg@3195: enabled: hasSingleColorSelectedHolder cg@1847: label: 'Inspect Color' cg@1847: itemValue: inspectColor cg@2651: ) cg@2651: (MenuItem cg@3475: enabled: imageHasColormapHolder cg@2651: label: 'Inspect Colormap' cg@2651: itemValue: inspectColormap cg@1847: ) cg@1847: ) cg@1847: nil cg@1847: nil cg@1053: ) cg@1053: ! cg@1053: tz@400: menu tz@737: "This resource specification was automatically generated tz@737: by the MenuEditor of ST/X." tz@400: tz@737: "Do not manually edit this!! If it is corrupted, tz@737: the MenuEditor may not be able to read the specification." tz@400: tz@400: " tz@400: MenuEditor new openOnClass:ImageEditor andSelector:#menu tz@400: (Menu new fromLiteralArrayEncoding:(ImageEditor menu)) startUp tz@400: " tz@400: tz@400: tz@400: cg@1124: ^ cg@1882: #(Menu cg@1882: ( cg@1882: (MenuItem cg@1882: label: '&File' cg@1882: translateLabel: true cg@2196: submenuChannel: menuFile cg@2585: "/ keepLinkedMenu: true cg@1124: ) cg@1882: (MenuItem cg@1882: label: 'Edit' cg@1882: translateLabel: true cg@2196: submenuChannel: menuEdit cg@2585: "/ keepLinkedMenu: true cg@1124: ) cg@1882: (MenuItem cg@1882: label: 'Mode' cg@1882: translateLabel: true cg@1882: submenuChannel: modeMenu cg@3374: isVisible: modeMenuVisible cg@1637: ) cg@1882: (MenuItem cg@3497: label: 'Image' cg@1882: translateLabel: true cg@2585: submenuChannel: menuColors cg@1124: ) cg@1882: (MenuItem cg@1882: label: 'Settings' cg@1882: translateLabel: true cg@2585: submenuChannel: menuSettings cg@1124: ) cg@1882: (MenuItem cg@1882: label: 'History' cg@1882: translateLabel: true cg@1975: isVisible: isStandAlone cg@1882: submenuChannel: menuHistory cg@1124: ) cg@1882: (MenuItem cg@2136: label: 'MENU_Help' cg@1882: translateLabel: true cg@2125: startGroup: conditionalRight cg@1882: submenuChannel: menuHelp cg@1124: ) cg@1124: ) cg@1124: nil cg@1124: nil tz@400: ) cg@3497: cg@3497: "Modified: / 23-10-2017 / 10:39:43 / cg" tz@400: ! tz@400: cg@2585: menuColors cg@2585: "This resource specification was automatically generated cg@2585: by the MenuEditor of ST/X." cg@2585: cg@2585: "Do not manually edit this!! If it is corrupted, cg@2585: the MenuEditor may not be able to read the specification." cg@2585: cg@3476: cg@2585: " cg@2585: MenuEditor new openOnClass:ImageEditor andSelector:#menuColors cg@2585: (Menu new fromLiteralArrayEncoding:(ImageEditor menuColors)) startUp cg@2585: " cg@2585: cg@2585: cg@2585: cg@2585: ^ cg@2585: #(Menu cg@2585: ( cg@2585: (MenuItem cg@3405: enabled: imageIsLoaded cg@2585: label: 'Depth' cg@2585: submenu: cg@2585: (Menu cg@2585: ( cg@2585: (MenuItem cg@2585: activeHelpKey: colorMap1 cg@3476: enabled: imageIsLoadedAndNotReadonlyHolder cg@2585: label: '1-Plane' cg@2585: itemValue: colorMapMode: cg@2585: argument: depth1 cg@2585: choice: colorMapMode cg@2585: choiceValue: depth1 cg@2585: ) cg@2585: (MenuItem cg@2585: activeHelpKey: colorMap1M cg@3476: enabled: imageIsLoadedAndNotReadonlyHolder cg@2585: label: '1-Plane + Mask' cg@2585: itemValue: colorMapMode: cg@2585: argument: masked1 cg@2585: choice: colorMapMode cg@2585: choiceValue: masked1 cg@2585: ) cg@2585: (MenuItem cg@2585: label: '-' cg@2585: ) cg@2585: (MenuItem cg@2585: activeHelpKey: colorMap2 cg@3476: enabled: imageIsLoadedAndNotReadonlyHolder cg@2585: label: '2-Plane' cg@2585: itemValue: colorMapMode: cg@2585: argument: depth2 cg@2585: choice: colorMapMode cg@2585: choiceValue: depth2 cg@2585: ) cg@2585: (MenuItem cg@2585: activeHelpKey: colorMap2M cg@3476: enabled: imageIsLoadedAndNotReadonlyHolder cg@2585: label: '2-Plane + Mask' cg@2585: itemValue: colorMapMode: cg@2585: argument: masked2 cg@2585: choice: colorMapMode cg@2585: choiceValue: masked2 cg@2585: ) cg@2585: (MenuItem cg@2585: label: '-' cg@2585: ) cg@2585: (MenuItem cg@2585: activeHelpKey: colorMap4 cg@3476: enabled: imageIsLoadedAndNotReadonlyHolder cg@2585: label: '4-Plane' cg@2585: itemValue: colorMapMode: cg@2585: argument: depth4 cg@2585: choice: colorMapMode cg@2585: choiceValue: depth4 cg@2585: ) cg@2585: (MenuItem cg@2585: activeHelpKey: colorMap4M cg@3476: enabled: imageIsLoadedAndNotReadonlyHolder cg@2585: label: '4-Plane + Mask' cg@2585: itemValue: colorMapMode: cg@2585: argument: masked4 cg@2585: choice: colorMapMode cg@2585: choiceValue: masked4 cg@2585: ) cg@2585: (MenuItem cg@2585: label: '-' cg@2585: ) cg@2585: (MenuItem cg@2585: activeHelpKey: colorMap8 cg@3476: enabled: imageIsLoadedAndNotReadonlyHolder cg@2585: label: '8-Plane' cg@2585: itemValue: colorMapMode: cg@2585: argument: depth8 cg@2585: choice: colorMapMode cg@2585: choiceValue: depth8 cg@2585: ) cg@2585: (MenuItem cg@2585: activeHelpKey: colorMap8M cg@3476: enabled: imageIsLoadedAndNotReadonlyHolder cg@2585: label: '8-Plane + Mask' cg@2585: itemValue: colorMapMode: cg@2585: argument: masked8 cg@2585: choice: colorMapMode cg@2585: choiceValue: masked8 cg@2585: ) cg@2585: (MenuItem cg@2585: label: '-' cg@2585: ) cg@2585: (MenuItem cg@2585: activeHelpKey: colorMap16 cg@3476: enabled: imageIsLoadedAndNotReadonlyHolder cg@2585: label: '16-Plane' cg@2585: itemValue: colorMapMode: cg@2585: argument: depth16 cg@2585: choice: colorMapMode cg@2585: choiceValue: depth16 cg@2585: ) cg@2585: (MenuItem cg@2585: activeHelpKey: colorMap16M cg@3476: enabled: imageIsLoadedAndNotReadonlyHolder cg@2585: label: '16-Plane + Mask' cg@2585: itemValue: colorMapMode: cg@2585: argument: masked16 cg@2585: choice: colorMapMode cg@2585: choiceValue: masked16 cg@2585: ) cg@2585: (MenuItem cg@2585: label: '-' cg@2585: ) cg@2585: (MenuItem cg@2585: activeHelpKey: colorMap24 cg@3476: enabled: imageIsLoadedAndNotReadonlyHolder cg@2585: label: '24-Plane' cg@2585: itemValue: colorMapMode: cg@2585: argument: depth24 cg@2585: choice: colorMapMode cg@2585: choiceValue: depth24 cg@2585: ) cg@2585: (MenuItem cg@2585: activeHelpKey: colorMap24M cg@3476: enabled: imageIsLoadedAndNotReadonlyHolder cg@2585: label: '24-Plane + Mask' cg@2585: itemValue: colorMapMode: cg@2585: argument: masked24 cg@2585: choice: colorMapMode cg@2585: choiceValue: masked24 cg@2585: ) cg@2585: (MenuItem cg@2585: label: '-' cg@2585: ) cg@2585: (MenuItem cg@2585: activeHelpKey: colorMap32 cg@3476: enabled: imageIsLoadedAndNotReadonlyHolder cg@2585: label: '32-Plane (rgba)' cg@2585: itemValue: colorMapMode: cg@2585: argument: depth32 cg@2585: choice: colorMapMode cg@2585: choiceValue: depth32 cg@2585: ) cg@2585: ) cg@2585: nil cg@2585: nil cg@2585: ) cg@2585: ) cg@2585: (MenuItem cg@3405: enabled: imageIsLoadedAndNotReadonlyHolder cg@2585: label: 'ColorMap' cg@2585: submenu: cg@2585: (Menu cg@2585: ( cg@2585: (MenuItem cg@2585: activeHelpKey: compressColormap cg@2792: enabled: hasColormapHolder cg@2585: label: 'Compress Colormap' cg@2826: itemValue: #'menu_compressColorMap' cg@2585: ) cg@2585: (MenuItem cg@2792: enabled: hasColormapHolder cg@2585: label: 'Sort Colormap' cg@2826: itemValue: #'menu_sortColorMap' cg@2585: ) cg@2585: (MenuItem cg@2585: label: 'Reduce Number of Colors by Rounding...' cg@2585: itemValue: reduceNumberOfColors2 cg@2585: ) cg@2585: (MenuItem cg@2585: label: 'Reduce Number of Colors by Masking Bits...' cg@2585: itemValue: reduceNumberOfColors cg@2652: ) cg@2585: ) cg@2585: nil cg@2585: nil cg@2585: ) cg@2585: ) cg@2585: (MenuItem cg@3405: enabled: imageIsLoadedAndNotReadonlyHolder cg@2585: label: 'Process' cg@2585: submenu: cg@2585: (Menu cg@2585: ( cg@2585: (MenuItem cg@3476: label: 'Negative' cg@3476: itemValue: makeNegative cg@2585: ) cg@2585: (MenuItem cg@3476: label: 'Invert Pixel Bits' cg@3476: itemValue: makeInvertedBits cg@3598: ) cg@3598: (MenuItem cg@3598: label: 'Exchange Red-Green' cg@3598: itemValue: exchangeRedGreenChannels cg@3598: ) cg@3598: (MenuItem cg@3598: label: 'Exchange Red-Blue' cg@3598: itemValue: exchangeRedBlueChannels cg@3598: ) cg@3598: (MenuItem cg@3598: label: 'Exchange Green-Blue' cg@3598: itemValue: exchangeGreenBlueChannels cg@3458: ) cg@3458: (MenuItem cg@3458: label: '-' cg@3458: ) cg@3458: (MenuItem cg@2826: enabled: allowedToChangeImageDimensionAndDepth cg@2585: label: 'Make dithered 8Bit Palette' cg@2585: itemValue: makeDitheredPaletteImage cg@2585: isVisible: false cg@2585: ) cg@2585: (MenuItem cg@3458: label: 'Dither to Depth...' cg@3458: itemValue: ditherToDepth cg@3458: ) cg@3458: (MenuItem cg@3471: label: 'Threshold to Depth...' cg@3471: itemValue: thresholdToDepth cg@3476: ) cg@3476: (MenuItem cg@3476: label: '-' cg@3476: ) cg@3476: (MenuItem cg@3476: label: 'Make Monochrome...' cg@3476: itemValue: makeMonochromeImage cg@3476: ) cg@3476: (MenuItem cg@3476: label: 'Make GrayScale (same Depth)' cg@3476: itemValue: makeGrayScaleImage cg@3471: ) cg@3471: (MenuItem cg@3460: label: 'Make GrayScale with Depth (Dither)...' cg@3460: itemValue: ditherGrayToDepth cg@3460: ) cg@3460: (MenuItem cg@3460: label: 'Make GrayScale with Depth (Threshold)...' cg@3460: itemValue: thresholdGrayToDepth cg@2826: ) cg@2826: (MenuItem cg@3497: label: 'Make GrayScale with N Gray Colors (Dither)...' cg@3497: itemValue: ditherToNumberOfGrayColors cg@3497: ) cg@3497: (MenuItem cg@3497: label: 'Make GrayScale with N Gray Colors (Threshold)...' cg@3497: itemValue: thresholdToNumberOfGrayColors cg@3497: ) cg@3497: (MenuItem cg@2826: label: '-' cg@2826: ) cg@2826: (MenuItem cg@2826: label: 'Make Slightly Brighter' cg@2826: itemValue: makeSlightlyBrighter cg@3476: ) cg@3476: (MenuItem cg@3476: label: 'Make Brighter' cg@3476: itemValue: makeBrighter cg@2826: ) cg@2826: (MenuItem cg@2826: label: 'Make Slightly Darker' cg@2826: itemValue: makeSlightlyDarker cg@2585: ) cg@2585: (MenuItem cg@2585: label: 'Make Darker' cg@2585: itemValue: makeDarker cg@2585: ) cg@2585: (MenuItem cg@2585: label: '-' cg@2585: ) cg@2585: (MenuItem cg@2585: label: 'Change HLS...' cg@2585: itemValue: changeHLS cg@2585: ) cg@2585: (MenuItem cg@2585: label: 'Colorize...' cg@2585: itemValue: colorize cg@3476: ) cg@3476: (MenuItem cg@3476: enabled: imageIsLoadedHolder cg@3476: label: 'Brighten' cg@3476: itemValue: doBrightenImage cg@3476: ) cg@3476: (MenuItem cg@3476: enabled: imageIsLoadedHolder cg@3476: label: 'Darken' cg@3476: itemValue: doDarkenImage cg@2585: ) cg@2585: ) cg@2585: nil cg@2585: nil cg@2585: ) cg@2585: ) cg@2585: (MenuItem cg@3405: enabled: imageIsLoadedAndNotReadonlyHolder cg@2585: label: 'Mask' cg@2585: submenu: cg@2585: (Menu cg@2585: ( cg@2585: (MenuItem cg@2585: activeHelpKey: copyMask cg@2585: enabled: hasMask cg@2585: label: 'Copy Mask' cg@2826: itemValue: #'menu_copyMask' cg@2585: ) cg@2585: (MenuItem cg@2585: activeHelpKey: pasteMask cg@2585: enabled: hasMask cg@2585: label: 'Paste Mask' cg@2826: itemValue: #'menu_pasteMask' cg@2585: ) cg@2585: (MenuItem cg@2585: enabled: hasMask cg@2585: label: 'Clear Masked Pixels' cg@2826: itemValue: #'menu_clearMaskedPixels' cg@2652: ) cg@2652: (MenuItem cg@2652: enabled: hasMask cg@2653: label: 'Clear Colormap Entry for Masked Pixels' cg@2826: itemValue: #'menu_clearColormapEntry0AndMaskedPixels' cg@2585: ) cg@2585: ) cg@2585: nil cg@2585: nil cg@2585: ) cg@2585: ) cg@2585: ) cg@2585: nil cg@2585: nil cg@2585: ) cg@2585: ! cg@2585: cg@2196: menuEdit cg@2196: "This resource specification was automatically generated cg@2196: by the MenuEditor of ST/X." cg@3497: cg@2196: "Do not manually edit this!! If it is corrupted, cg@2196: the MenuEditor may not be able to read the specification." cg@3497: cg@3497: cg@2196: " cg@2196: MenuEditor new openOnClass:ImageEditor andSelector:#menuEdit cg@3497: (Menu new fromLiteralArrayEncoding:(ImageEditor menuEdit)) startUp cg@3497: " cg@3497: cg@3497: cg@3497: cg@3497: ^ cg@3497: #(Menu cg@3497: ( cg@3497: (MenuItem cg@3497: activeHelpKey: editUndo cg@3497: enabled: canUndoHolder cg@3497: label: 'Undo' cg@3497: itemValue: doUndo cg@3497: ) cg@3497: (MenuItem cg@3497: label: '-' cg@3497: ) cg@3497: (MenuItem cg@3497: enabled: imageIsLoadedHolder cg@3497: label: 'Copy to Clipboard' cg@3497: itemValue: doCopyImageToClipboard cg@3497: ) cg@3497: (MenuItem cg@3497: label: '-' cg@3497: ) cg@3497: (MenuItem cg@3497: activeHelpKey: editResize cg@3497: enabled: imageIsLoadedAndAllowedToChangeImageDimensionAndDepth cg@3497: label: 'Resize...' cg@3497: itemValue: doResizeImage cg@3497: ) cg@3497: (MenuItem cg@3497: activeHelpKey: editMagnifyImage cg@3497: enabled: imageIsLoadedAndAllowedToChangeImageDimensionAndDepth cg@3497: label: 'Magnify...' cg@3497: itemValue: doMagnifyImage cg@3497: ) cg@3497: (MenuItem cg@3497: activeHelpKey: editMagnifyImage cg@3497: enabled: imageIsLoadedAndAllowedToChangeImageDimensionAndDepth cg@3497: label: 'Magnify By...' cg@3497: itemValue: doMagnifyImageBy cg@3497: ) cg@3497: (MenuItem cg@3497: activeHelpKey: editRotate cg@3497: enabled: imageIsLoadedAndAllowedToChangeImageDimensionAndDepth cg@3497: label: 'Rotate...' cg@3497: itemValue: doRotateImage cg@3497: ) cg@3497: (MenuItem cg@3497: activeHelpKey: edit3DProjection cg@3497: enabled: imageIsLoadedAndAllowedToChangeImageDimensionAndDepth cg@3497: label: '3D Projection...' cg@3497: itemValue: do3DProjection cg@3497: ) cg@3497: (MenuItem cg@3497: enabled: imageIsLoadedAndAllowedToFlipHolder cg@3497: label: 'Flip' cg@3497: submenu: cg@3497: (Menu cg@3497: ( cg@3497: (MenuItem cg@3497: activeHelpKey: editFlipVertical cg@3497: enabled: imageIsLoadedAndNotReadonlyHolder cg@3497: label: 'Flip - Vertical' cg@3497: itemValue: doFlipVertical cg@3497: labelImage: (ResourceRetriever ImageEditor flipVerticalIcon 'Flip - Vertical') cg@3497: ) cg@3497: (MenuItem cg@3497: activeHelpKey: editFlipHorizontal cg@3497: enabled: imageIsLoadedAndNotReadonlyHolder cg@3497: label: 'Flip - Horizontal' cg@3497: itemValue: doFlipHorizontal cg@3497: labelImage: (ResourceRetriever ImageEditor flipHorizontalIcon 'Flip - Horizontal') cg@3497: ) cg@3497: ) cg@3497: nil cg@3497: nil cg@3497: ) cg@3497: ) cg@3497: (MenuItem cg@3497: label: '-' cg@3497: ) cg@3497: (MenuItem cg@3497: enabled: imageIsLoadedAndAllowedToChangeImageDimension cg@3497: label: 'Crop' cg@3497: submenu: cg@3497: (Menu cg@3497: ( cg@3497: (MenuItem cg@3497: activeHelpKey: cropManual cg@3497: label: 'Manual...' cg@3497: itemValue: doCropManual cg@3497: ) cg@3497: (MenuItem cg@3497: label: '-' cg@3497: isVisible: false cg@3497: ) cg@3497: (MenuItem cg@3497: activeHelpKey: autoCropAll cg@3497: label: 'All' cg@3497: itemValue: autoCropAll cg@3497: ) cg@3497: (MenuItem cg@3497: label: '-' cg@3497: ) cg@3497: (MenuItem cg@3497: activeHelpKey: autoCropLeft cg@3497: label: 'Left' cg@3497: itemValue: autoCropLeft cg@3497: ) cg@3497: (MenuItem cg@3497: activeHelpKey: autoCropRight cg@3497: label: 'Right' cg@3497: itemValue: autoCropRight cg@3497: ) cg@3497: (MenuItem cg@3497: activeHelpKey: autoCropTop cg@3497: label: 'Top' cg@3497: itemValue: autoCropTop cg@3497: ) cg@3497: (MenuItem cg@3497: activeHelpKey: autoCropBottom cg@3497: label: 'Bottom' cg@3497: itemValue: autoCropBottom cg@3497: ) cg@3497: ) cg@3497: nil cg@3497: nil cg@3497: ) cg@3497: ) cg@3497: (MenuItem cg@3497: activeHelpKey: uncropManual cg@3497: enabled: imageIsLoadedAndAllowedToChangeImageDimensionAndDepth cg@3497: label: 'Uncrop (Add Border)...' cg@3497: itemValue: doUnCropManual cg@3497: ) cg@3497: (MenuItem cg@3497: activeHelpKey: shiftManual cg@3497: enabled: imageIsLoadedAndAllowedToChangeImageDimension cg@3497: label: 'Shift...' cg@3497: itemValue: doShiftManual cg@3497: ) cg@3497: (MenuItem cg@3497: label: '-' cg@3497: ) cg@3497: (MenuItem cg@3497: activeHelpKey: fileEditMask cg@3497: enabled: hasMaskHolder cg@3497: label: 'Edit Mask' cg@3497: itemValue: doEditMask cg@3497: ) cg@3497: (MenuItem cg@3497: enabled: imageIsLoadedAndNotReadonlyHolder cg@3497: label: 'Text...' cg@3497: itemValue: doInsertTextFromUser cg@3497: ) cg@3497: (MenuItem cg@3497: label: '-' cg@3497: ) cg@3497: (MenuItem cg@3497: enabled: imageIsLoadedHolder cg@3497: label: 'Animation Sequence' cg@3497: submenu: cg@3497: (Menu cg@3497: ( cg@3497: (MenuItem cg@3497: enabled: imageHasNextImageHolder cg@3497: label: 'Next in Sequence' cg@3497: itemValue: nextImageInSequence cg@3497: ) cg@3497: (MenuItem cg@3497: enabled: imageHasPreviousImageHolder cg@3497: label: 'Previous in Sequence' cg@3497: itemValue: previousImageInSequence cg@3497: ) cg@3497: (MenuItem cg@3497: label: '-' cg@3497: ) cg@3497: (MenuItem cg@3497: enabled: imageHasImageSequenceHolder cg@3497: label: 'Edit each from Sequence' cg@3497: itemValue: editEachImageFromSequence cg@3497: ) cg@3497: ) cg@3497: nil cg@3497: nil cg@3497: ) cg@3497: ) cg@3497: ) cg@3497: nil cg@3497: nil cg@3497: ) cg@2196: ! cg@2196: cg@2196: menuFile cg@2196: "This resource specification was automatically generated cg@2196: by the MenuEditor of ST/X." cg@2196: cg@2196: "Do not manually edit this!! If it is corrupted, cg@2196: the MenuEditor may not be able to read the specification." cg@2196: cg@3022: cg@2196: " cg@2196: MenuEditor new openOnClass:ImageEditor andSelector:#menuFile cg@2196: (Menu new fromLiteralArrayEncoding:(ImageEditor menuFile)) startUp cg@2196: " cg@2196: cg@2196: cg@2196: cg@2196: ^ cg@2196: #(Menu cg@2196: ( cg@2196: (MenuItem cg@2196: activeHelpKey: fileNewImageEditor cg@2196: label: 'New ImageEditor' cg@2196: itemValue: doNewImageEditor cg@2196: ) cg@2196: (MenuItem cg@2876: label: '-' cg@2876: ) cg@2876: (MenuItem cg@2196: activeHelpKey: fileNewImage cg@2196: label: 'New...' cg@2196: itemValue: doNewImage cg@2196: ) cg@2196: (MenuItem cg@3200: activeHelpKey: fileNewImageFromClipboard cg@2196: label: 'New from ClipBoard' cg@2196: itemValue: doNewImageFromClipboard cg@2196: ) cg@2196: (MenuItem cg@3200: activeHelpKey: fileNewMaskFromClipboard cg@3200: label: 'Mask from ClipBoard' cg@3200: itemValue: doNewMaskFromClipboard cg@3200: ) cg@3200: (MenuItem cg@2196: label: '-' cg@2196: ) cg@2196: (MenuItem cg@2196: activeHelpKey: fileLoadFromClass cg@2196: label: 'Load...' cg@2196: itemValue: doLoadFromClass cg@3374: isVisible: methodSaveAndLoadMenuItemsVisible cg@2196: ) cg@2196: (MenuItem cg@2196: activeHelpKey: fileLoadFromFile cg@2196: label: 'Load from File...' cg@2196: itemValue: doLoadFromFile cg@2196: ) cg@2196: (MenuItem cg@2796: activeHelpKey: fileLoadFromURL cg@2796: label: 'Load from URL...' cg@2796: itemValue: doLoadFromURL cg@2796: ) cg@2796: (MenuItem cg@2707: label: 'Grab' cg@2707: submenu: cg@2707: (Menu cg@2707: ( cg@2707: (MenuItem cg@2707: activeHelpKey: fileGrabImageFromScreen cg@2717: label: 'Grab from Screen Area...' cg@2707: itemValue: grabScreenImage cg@2707: ) cg@2707: (MenuItem cg@2707: activeHelpKey: fileGrabImageFromScreen cg@2707: enabled: hasLastGrabScreenArea cg@2711: label: 'Grab again from same Screen Area' cg@2707: itemValue: grabScreenImageFromLastArea cg@2707: ) cg@2771: (MenuItem cg@2771: label: '-' cg@2771: ) cg@2771: (MenuItem cg@2771: activeHelpKey: fileGrabImageFromWindow cg@2771: label: 'Grab from Window...' cg@2771: itemValue: grabWindowImage cg@2771: ) cg@3422: (MenuItem cg@3422: activeHelpKey: fileGrabFullSreenImage cg@3422: label: 'Grab from whole Screen' cg@3422: itemValue: grabFullScreenImage cg@3422: ) cg@2707: ) cg@2707: nil cg@2707: nil cg@2707: ) cg@2701: ) cg@2701: (MenuItem cg@2196: label: '-' cg@2196: ) cg@2196: (MenuItem cg@2196: activeHelpKey: fileSaveMethod cg@2196: enabled: imageIsLoadedAndClassDefined cg@2196: label: 'Save' cg@2196: itemValue: doSaveMethod cg@3374: isVisible: methodSaveAndLoadMenuItemsVisible cg@2196: ) cg@2196: (MenuItem cg@2196: activeHelpKey: fileSaveMethodAs cg@2792: enabled: imageIsLoadedHolder cg@2196: label: 'Save As...' cg@2196: itemValue: doSaveMethodAs cg@3374: isVisible: methodSaveAndLoadMenuItemsVisible cg@2196: ) cg@2196: (MenuItem cg@2196: activeHelpKey: fileSaveAs cg@2792: enabled: imageIsLoadedHolder cg@2196: label: 'Save to File...' cg@2196: itemValue: doSaveImageFileAs cg@2196: ) cg@2196: (MenuItem cg@2196: activeHelpKey: fileSaveMaskAs cg@3411: enabled: hasMaskHolder cg@2196: label: 'Save Mask to File...' cg@2196: itemValue: doSaveImageMaskFileAs cg@2196: ) cg@2196: (MenuItem cg@2196: activeHelpKey: fileSaveButtonImageAs cg@2792: enabled: imageIsLoadedHolder cg@2196: label: 'Save as Button to File...' cg@2196: itemValue: doSaveButtonImageToFileAs cg@2196: ) cg@2196: (MenuItem cg@2196: label: '-' cg@2196: ) cg@2196: (MenuItem cg@2196: activeHelpKey: filePrint cg@2792: enabled: imageIsLoadedHolder cg@2196: label: 'Print' cg@2196: itemValue: doPrint cg@2196: ) cg@2196: (MenuItem cg@2196: label: '-' cg@2196: isVisible: isStandAlone cg@2196: ) cg@2196: (MenuItem cg@2196: activeHelpKey: fileBrowseClass cg@2792: enabled: hasClassDefinedHolder cg@2196: label: 'Browse Class' cg@2196: itemValue: doBrowseClass cg@2196: isVisible: isStandAlone cg@2196: ) cg@2196: (MenuItem cg@2792: enabled: imageIsLoadedHolder cg@2196: label: 'Inspect Image' cg@2196: itemValue: doInspectImage cg@2196: isVisible: isStandAlone cg@2196: ) cg@2196: (MenuItem cg@2585: activeHelpKey: fileShowStoreString cg@2792: enabled: imageIsLoadedHolder cg@2585: label: 'Show storeString' cg@2585: itemValue: doShowStoreString cg@3022: ) cg@3022: (MenuItem cg@3022: activeHelpKey: fileShowStoreString cg@3022: enabled: imageIsLoadedHolder cg@3022: label: 'Show Pixel Array Literal String' cg@3022: itemValue: doShowPixelArrayLiteralString cg@2585: ) cg@2585: (MenuItem cg@2196: label: '-' cg@2196: isVisible: isStandAlone cg@2196: ) cg@2196: (MenuItem cg@2196: activeHelpKey: fileExit cg@2196: label: 'Exit' cg@2196: itemValue: closeRequest cg@2196: isVisible: isStandAlone cg@2196: ) cg@2196: ) cg@2196: nil cg@2196: nil cg@2196: ) cg@3411: cg@3422: "Modified: / 25-02-2017 / 12:40:30 / cg" cg@2196: ! cg@2196: tz@679: menuMouseButtonColors tz@737: "This resource specification was automatically generated tz@737: by the MenuEditor of ST/X." tz@679: tz@737: "Do not manually edit this!! If it is corrupted, tz@737: the MenuEditor may not be able to read the specification." tz@679: tz@679: " tz@679: MenuEditor new openOnClass:ImageEditor andSelector:#menuMouseButtonColors tz@679: (Menu new fromLiteralArrayEncoding:(ImageEditor menuMouseButtonColors)) startUp tz@679: " tz@679: tz@679: tz@679: tz@679: ^ tz@679: tz@679: #(#Menu tz@679: tz@679: #( tz@679: #(#MenuItem tz@679: #label: 'Left Mouse Button' tz@679: #nameKey: #leftMouseKeyButton tz@679: #activeHelpKey: #mouseKeyColorMode cg@2792: #enabled: #imageIsLoadedHolder tz@679: #labelImage: #(#ResourceRetriever nil #leftMouseKeyIcon) tz@975: #choice: #mouseKeyColorMode tz@975: #choiceValue: 1 tz@679: ) tz@679: #(#MenuItem tz@679: #label: 'Right Mouse Button' tz@679: #nameKey: #rightMouseKeyButton tz@679: #activeHelpKey: #mouseKeyColorMode cg@2792: #enabled: #imageIsLoadedHolder tz@679: #labelImage: #(#ResourceRetriever nil #rightMouseKeyIcon) tz@975: #choice: #mouseKeyColorMode tz@975: #choiceValue: 2 tz@679: ) tz@679: ) nil tz@679: nil tz@679: ) cg@2792: cg@2792: "Modified: / 04-07-2010 / 10:17:37 / cg" tz@679: ! tz@679: cg@2585: menuSettings cg@2585: "This resource specification was automatically generated cg@2585: by the MenuEditor of ST/X." cg@2585: cg@2585: "Do not manually edit this!! If it is corrupted, cg@2585: the MenuEditor may not be able to read the specification." cg@2585: cg@2881: cg@2585: " cg@2585: MenuEditor new openOnClass:ImageEditor andSelector:#menuSettings cg@2585: (Menu new fromLiteralArrayEncoding:(ImageEditor menuSettings)) startUp cg@2585: " cg@2585: cg@2585: cg@2585: cg@2585: ^ cg@2585: #(Menu cg@2585: ( cg@2585: (MenuItem cg@2585: activeHelpKey: settingsGridMagnification cg@2585: label: 'Grid Magnification Limit...' cg@2585: itemValue: doChangeGridMagnification cg@2585: translateLabel: true cg@2585: ) cg@2585: (MenuItem cg@2585: label: 'Pen' cg@2585: translateLabel: true cg@2585: submenu: cg@2585: (Menu cg@2585: ( cg@2585: (MenuItem cg@2585: label: '1' cg@2585: translateLabel: true cg@2881: choice: penWidthHolder cg@2881: choiceValue: 1 cg@2585: ) cg@2585: (MenuItem cg@2585: label: '5' cg@2585: translateLabel: true cg@2881: choice: penWidthHolder cg@2881: choiceValue: 5 cg@2585: ) cg@2585: (MenuItem cg@2585: label: '10' cg@2585: translateLabel: true cg@2881: choice: penWidthHolder cg@2881: choiceValue: 10 cg@2585: ) cg@2585: ) cg@2585: nil cg@2585: nil cg@2585: ) cg@2585: ) cg@2585: (MenuItem cg@2585: label: 'Spray' cg@2585: translateLabel: true cg@2585: submenu: cg@2585: (Menu cg@2585: ( cg@2585: (MenuItem cg@2585: label: '4' cg@2585: translateLabel: true cg@2881: choice: spraySpotHolder cg@2881: choiceValue: 4 cg@2585: ) cg@2585: (MenuItem cg@2585: label: '8' cg@2585: translateLabel: true cg@2881: choice: spraySpotHolder cg@2881: choiceValue: 8 cg@2585: ) cg@2585: (MenuItem cg@2585: label: '16' cg@2585: translateLabel: true cg@2881: choice: spraySpotHolder cg@2881: choiceValue: 16 cg@2585: ) cg@2585: (MenuItem cg@2585: label: '32' cg@2585: translateLabel: true cg@2881: choice: spraySpotHolder cg@2881: choiceValue: 32 cg@2585: ) cg@2585: ) cg@2585: nil cg@2585: nil cg@2585: ) cg@2585: ) cg@2585: ) cg@2585: nil cg@2585: nil cg@2585: ) cg@2585: ! cg@2585: tz@400: menuToolbar tz@737: "This resource specification was automatically generated tz@737: by the MenuEditor of ST/X." tz@400: tz@737: "Do not manually edit this!! If it is corrupted, tz@737: the MenuEditor may not be able to read the specification." tz@400: cg@2876: tz@400: " tz@400: MenuEditor new openOnClass:ImageEditor andSelector:#menuToolbar tz@400: (Menu new fromLiteralArrayEncoding:(ImageEditor menuToolbar)) startUp tz@400: " tz@400: tz@400: tz@400: cg@1196: ^ cg@1820: #(Menu cg@1820: ( cg@1820: (MenuItem cg@1820: activeHelpKey: fileNewImage cg@1820: label: 'newImage' cg@1820: itemValue: doNewImage cg@1820: isButton: true cg@1883: labelImage: (ResourceRetriever ToolbarIconLibrary newImageIcon) cg@1196: ) cg@1820: (MenuItem cg@2876: activeHelpKey: fileGrabImageFromScreen cg@2876: label: 'grabScreenImage' cg@2876: itemValue: grabScreenImage cg@2876: isButton: true cg@2877: labelImage: (ResourceRetriever ToolbarIconLibrary snapshot24x24Icon) cg@2876: ) cg@2876: (MenuItem cg@1949: label: '-' cg@1949: ) cg@1949: (MenuItem cg@1970: activeHelpKey: fileLoadFromClass cg@1970: label: 'loadFromClass' cg@1970: itemValue: doLoadFromClass cg@1970: isButton: true cg@3374: isVisible: isStandAloneAndMethodSaveAndLoadMenuItemsVisible cg@1970: submenuChannel: menuHistory cg@1970: labelImage: (ResourceRetriever XPToolbarIconLibrary loadImageFromMethodIcon) cg@1970: keepLinkedMenu: true cg@1970: ) cg@1970: (MenuItem cg@2567: activeHelpKey: fileSaveMethodAs cg@2792: enabled: imageIsLoadedHolder cg@2567: label: 'fileSaveMethodAs' cg@1970: itemValue: doSaveMethodAs cg@1970: isButton: true cg@3374: isVisible: isStandAloneAndMethodSaveAndLoadMenuItemsVisible cg@1970: labelImage: (ResourceRetriever XPToolbarIconLibrary saveImageAsMethodAsIcon) cg@1970: ) cg@1970: (MenuItem cg@1970: activeHelpKey: fileSaveMethod cg@2792: enabled: imageIsLoadedHolder cg@1970: label: 'saveAsMethod' cg@1970: itemValue: doSaveMethod cg@1970: isButton: true cg@3374: isVisible: isNotStandAloneAndMethodSaveAndLoadMenuItemsVisible cg@2590: labelImage: (ResourceRetriever ToolbarIconLibrary saveImageAsMethodIcon) cg@1970: ) cg@1970: (MenuItem cg@1970: label: '-' cg@3374: isVisible: methodSaveAndLoadMenuItemsVisible cg@1970: ) cg@1970: (MenuItem cg@1820: activeHelpKey: fileLoadFromFile cg@1820: label: 'loadFromFile' cg@1820: itemValue: doLoadFromFile cg@1820: isButton: true cg@1884: labelImage: (ResourceRetriever ToolbarIconLibrary loadImageFromFileIcon) cg@1820: ) cg@1820: (MenuItem cg@3425: activeHelpKey: fileSave cg@3425: enabled: imageIsLoadedHolder cg@3425: label: 'save' cg@3425: itemValue: doSaveImageFile cg@3425: isButton: true cg@3425: isVisible: saveButtonInToolbarVisibleHolder cg@3425: labelImage: (ResourceRetriever ToolbarIconLibrary saveImageIcon) cg@3425: ) cg@3425: (MenuItem cg@1820: activeHelpKey: fileSaveAs cg@2792: enabled: imageIsLoadedHolder cg@1820: label: 'saveAsFile' cg@1820: itemValue: doSaveImageFileAs 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: isButton: true cg@1883: labelImage: (ResourceRetriever ToolbarIconLibrary undoIcon) cg@1196: ) cg@2812: (MenuItem cg@2812: label: '-' cg@2812: isVisible: imageHasImageSequenceHolder cg@2812: ) cg@2812: (MenuItem cg@2812: activeHelpKey: previousImageInSequence cg@2812: enabled: imageHasPreviousImageHolder cg@2812: label: 'Previous Image' cg@2812: itemValue: previousImageInSequence cg@2812: isVisible: imageHasImageSequenceHolder cg@2812: labelImage: (ResourceRetriever ToolbarIconLibrary leftArrow24x24Icon) cg@2812: ) cg@2812: (MenuItem cg@2812: activeHelpKey: nextImageInSequence cg@2812: enabled: imageHasNextImageHolder cg@2812: label: 'Next Image' cg@2812: itemValue: nextImageInSequence cg@2812: isVisible: imageHasImageSequenceHolder cg@2812: labelImage: (ResourceRetriever ToolbarIconLibrary rightArrow24x24Icon) cg@2812: ) cg@1637: ) cg@1637: nil cg@1637: nil cg@1637: ) cg@3425: cg@3425: "Modified: / 26-02-2017 / 23:03:40 / cg" 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@3405: cg@1637: " cg@1637: MenuEditor new openOnClass:ImageEditor andSelector:#modeMenu cg@1637: (Menu new fromLiteralArrayEncoding:(ImageEditor modeMenu)) startUp cg@1637: " cg@1637: cg@1637: cg@1637: cg@1637: ^ cg@2592: #(Menu cg@2592: ( cg@2592: (MenuItem cg@2592: activeHelpKey: drawModePoint cg@2792: enabled: imageIsLoadedHolder cg@2592: label: 'Point' cg@2592: labelImage: (ResourceRetriever ImageEditor pointIcon 'Point') cg@2592: choice: editMode cg@2592: choiceValue: point cg@2592: ) cg@2592: (MenuItem cg@3405: label: '-' cg@3405: ) cg@3405: (MenuItem cg@2592: activeHelpKey: drawModePoint cg@2792: enabled: imageIsLoadedHolder cg@2592: label: 'Spray' cg@2592: labelImage: (ResourceRetriever ImageEditor sprayIcon 'Spray') cg@2592: choice: editMode cg@2592: choiceValue: spray cg@1196: ) cg@2592: (MenuItem cg@3191: activeHelpKey: drawModeSmooth cg@3191: enabled: imageIsLoadedHolder cg@3191: label: 'Smooth' cg@3191: labelImage: (ResourceRetriever ImageEditor smoothIcon 'Smooth') cg@3191: choice: editMode cg@3191: choiceValue: smooth cg@3191: ) cg@3191: (MenuItem cg@3405: label: '-' cg@3405: ) cg@3405: (MenuItem cg@2592: activeHelpKey: drawModeBox cg@2792: enabled: imageIsLoadedHolder cg@2592: label: 'Rect' cg@2592: labelImage: (ResourceRetriever ImageEditor rectIcon 'Rect') cg@2592: choice: editMode cg@2592: choiceValue: box cg@1196: ) cg@2592: (MenuItem cg@2592: activeHelpKey: drawModeFilledBox cg@2792: enabled: imageIsLoadedHolder cg@2592: label: 'Filled Rectangle' cg@2592: labelImage: (ResourceRetriever ImageEditor fillRectIcon 'Filled Rectangle') cg@2592: choice: editMode cg@2592: choiceValue: filledBox cg@1196: ) cg@2592: (MenuItem cg@3405: activeHelpKey: drawModeCircle cg@2792: enabled: imageIsLoadedHolder cg@2592: label: 'Circle' cg@2592: labelImage: (ResourceRetriever ImageEditor circleIcon 'Circle') cg@2592: choice: editMode cg@2592: choiceValue: circle cg@1196: ) cg@2592: (MenuItem cg@3405: activeHelpKey: drawModeFilledCircle cg@3405: enabled: imageIsLoadedHolder cg@3405: label: 'Filled Circle' cg@3405: labelImage: (ResourceRetriever ImageEditor fillCircleIcon 'Filled Circle') cg@3405: choice: editMode cg@3405: choiceValue: filledCircle cg@3405: ) cg@3405: (MenuItem cg@2592: activeHelpKey: drawModeFill cg@2792: enabled: imageIsLoadedHolder cg@2592: label: 'Fill' cg@2592: labelImage: (ResourceRetriever ImageEditor fillIcon 'Fill') cg@2592: choice: editMode cg@2592: choiceValue: fill cg@1196: ) cg@2592: (MenuItem cg@3418: enabled: imageIsLoadedHolder cg@3418: label: 'Gradient Fill' cg@3418: isVisible: false cg@3418: submenu: cg@3418: (Menu cg@3418: ( cg@3418: (MenuItem cg@3418: activeHelpKey: drawModeFill cg@3418: enabled: imageIsLoadedHolder cg@3418: label: 'Horizontal' cg@3418: labelImage: (ResourceRetriever ImageEditor fillHorizontalGradientRectIcon 'Horizontal') cg@3418: choice: editMode cg@3418: choiceValue: fillHorizontalGradient cg@3418: ) cg@3418: (MenuItem cg@3418: activeHelpKey: drawModeFill cg@3418: enabled: imageIsLoadedHolder cg@3418: label: 'Vertical' cg@3418: labelImage: (ResourceRetriever ImageEditor fillVerticalGradientRectIcon 'Vertical') cg@3418: choice: editMode cg@3418: choiceValue: fillVerticalGradient cg@3418: ) cg@3418: (MenuItem cg@3418: activeHelpKey: drawModeFill cg@3418: enabled: imageIsLoadedHolder cg@3421: isVisible: false cg@3418: label: 'Diagonal' cg@3418: labelImage: (ResourceRetriever ImageEditor fillDiagonalGradientRectIcon 'Diagonal') cg@3418: choice: editMode cg@3418: choiceValue: fillDiagonalGradient cg@3418: ) cg@3418: ) cg@3418: nil cg@3418: nil cg@3418: ) cg@3418: ) cg@3418: (MenuItem cg@3405: label: '-' cg@3405: ) cg@3405: (MenuItem cg@3405: activeHelpKey: drawModeMaskOutsideRectangle cg@3405: enabled: imageHasMaskAndIsNotReadOnlyHolder cg@3405: label: 'Mask Outside Rectangle' cg@3405: labelImage: (ResourceRetriever ImageEditor maskOutsideRectangleIcon 'Mask Outside Rectangle') cg@3405: choice: editMode cg@3405: choiceValue: maskOutsideRect cg@3405: ) cg@3405: (MenuItem cg@3405: activeHelpKey: drawModeMaskOutsideCircle cg@3405: enabled: imageHasMaskAndIsNotReadOnlyHolder cg@3405: label: 'Mask Outside Circle' cg@3405: labelImage: (ResourceRetriever ImageEditor maskOutsideCircleIcon 'Mask Outside Circle') cg@3405: choice: editMode cg@3405: choiceValue: maskOutsideCircle cg@3405: ) cg@3405: (MenuItem cg@3405: label: '-' cg@3405: ) cg@3405: (MenuItem cg@2592: activeHelpKey: drawModeCopy cg@2792: enabled: imageIsLoadedHolder cg@2592: label: 'Copy' cg@2592: labelImage: (ResourceRetriever ImageEditor copyIcon 'Copy') cg@2592: choice: editMode cg@2592: choiceValue: copy cg@2592: ) cg@2592: (MenuItem cg@3512: activeHelpKey: drawModePasteWithMask cg@3512: enabled: imageIsLoadedHolder cg@3512: label: 'Paste with Mask' cg@3512: labelImage: (ResourceRetriever ImageEditor pasteWithMaskIcon 'Paste with Mask') cg@3512: choice: editMode cg@3512: choiceValue: pasteWithMask cg@3512: ) cg@3512: (MenuItem cg@2592: activeHelpKey: drawModePaste cg@2792: enabled: imageIsLoadedHolder cg@3512: label: 'Paste Over' cg@3561: labelImage: (ResourceRetriever ImageEditor pasteIcon 'Paste Over') cg@2592: choice: editMode cg@2592: choiceValue: paste cg@1196: ) cg@2592: (MenuItem cg@3561: activeHelpKey: drawModePasteMasked cg@3561: enabled: imageIsLoadedHolder cg@3561: label: 'Paste Masked' cg@3561: labelImage: (ResourceRetriever ImageEditor pasteIcon 'Paste Masked') cg@3561: choice: editMode cg@3561: choiceValue: pasteMasked cg@3561: ) cg@3561: (MenuItem cg@2592: activeHelpKey: drawModePasteUnder cg@2792: enabled: imageIsLoadedHolder cg@2592: label: 'Paste Under' cg@2592: labelImage: (ResourceRetriever ImageEditor pasteUnderIcon 'Paste Under') cg@2592: choice: editMode cg@2592: choiceValue: pasteUnder cg@1196: ) cg@2592: (MenuItem cg@3405: label: '-' cg@3405: ) cg@3405: (MenuItem cg@2592: activeHelpKey: drawModeSpecial cg@2792: enabled: imageIsLoadedHolder cg@2592: label: 'Special' cg@3419: labelImage: (ResourceRetriever ImageEditor specialRectangleIcon 'Special') cg@2592: choice: editMode cg@2592: choiceValue: specialOperation cg@1411: ) cg@1196: ) cg@1196: nil cg@1196: nil tz@400: ) cg@3419: cg@3512: "Modified: / 07-12-2017 / 15:30:46 / cg" cg@3561: "Modified: / 27-05-2018 / 10:41:20 / Claus Gittinger" 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@3489: 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: indication: tileModeHolder cg@1764: ) cg@1764: (MenuItem cg@1764: label: '-' cg@1764: ) cg@1764: (MenuItem cg@1764: label: 'Background Color' cg@1764: submenu: cg@1764: (Menu cg@1764: ( cg@1764: (MenuItem cg@1764: label: 'Gray' cg@2792: choice: previewBackgroundColorHolder cg@1764: ) cg@1764: (MenuItem cg@1764: label: 'Black' cg@2792: choice: previewBackgroundColorHolder cg@1764: choiceValue: black cg@1764: ) cg@1764: (MenuItem cg@1764: label: 'White' cg@2792: choice: previewBackgroundColorHolder cg@1764: choiceValue: white cg@1764: ) cg@1774: (MenuItem cg@1774: label: '-' cg@1774: ) cg@1774: (MenuItem cg@1774: label: 'Red' cg@2792: choice: previewBackgroundColorHolder cg@1774: choiceValue: red cg@1774: ) cg@1774: (MenuItem cg@1774: label: 'Green' cg@2792: choice: previewBackgroundColorHolder cg@1774: choiceValue: green cg@1774: ) cg@1774: (MenuItem cg@1774: label: 'Blue' cg@2792: choice: previewBackgroundColorHolder cg@1774: choiceValue: blue cg@1774: ) cg@1764: ) cg@1764: nil cg@1764: nil cg@1764: ) cg@1558: ) cg@3489: (MenuItem cg@3489: label: '-' cg@3489: ) cg@3489: (MenuItem cg@3489: label: 'Magnification' cg@3489: submenu: cg@3489: (Menu cg@3489: ( cg@3489: (MenuItem cg@3489: label: '0.1' cg@3489: choice: previewMagnificationHolder cg@3489: choiceValue: 0.1 cg@3489: ) cg@3489: (MenuItem cg@3489: label: '0.25' cg@3489: choice: previewMagnificationHolder cg@3489: choiceValue: 0.25 cg@3489: ) cg@3489: (MenuItem cg@3489: label: '0.5' cg@3489: choice: previewMagnificationHolder cg@3489: choiceValue: 0.5 cg@3489: ) cg@3489: (MenuItem cg@3489: label: '1' cg@3489: choice: previewMagnificationHolder cg@3489: choiceValue: 1 cg@3489: ) cg@3489: (MenuItem cg@3489: label: '2' cg@3489: choice: previewMagnificationHolder cg@3489: choiceValue: 2 cg@3489: ) cg@3489: (MenuItem cg@3489: label: '4' cg@3489: choice: previewMagnificationHolder cg@3489: choiceValue: 4 cg@3489: ) cg@3489: (MenuItem cg@3489: label: '-' cg@3489: ) cg@3489: (MenuItem cg@3489: label: 'Choose...' cg@3489: itemValue: changePreviewImageMagnification cg@3489: ) cg@3489: ) cg@3489: nil cg@3489: nil cg@3489: ) cg@3489: ) cg@1558: ) cg@1558: nil cg@1558: nil cg@1558: ) cg@2792: cg@3489: "Modified: / 10-09-2017 / 14:54:41 / cg" cg@1637: ! cg@1637: cg@1637: toolsMenuToolbar cg@1637: "This resource specification was automatically generated cg@1637: by the MenuEditor of ST/X." cg@1637: cg@1637: "Do not manually edit this!! If it is corrupted, cg@1637: the MenuEditor may not be able to read the specification." cg@1637: cg@2881: cg@1637: " cg@1637: MenuEditor new openOnClass:ImageEditor andSelector:#toolsMenuToolbar cg@1637: (Menu new fromLiteralArrayEncoding:(ImageEditor toolsMenuToolbar)) startUp cg@1637: " cg@1637: cg@1637: cg@1637: cg@1637: ^ cg@2881: #(Menu cg@2881: ( cg@2881: (MenuItem cg@2881: activeHelpKey: drawModePoint cg@3404: enabled: canDrawPointsHolder cg@2881: label: 'Point' cg@2881: translateLabel: true cg@2881: isButton: true cg@2881: labelImage: (ResourceRetriever ImageEditor pointIcon) cg@2881: choice: editMode cg@2881: choiceValue: point cg@1637: ) cg@2881: (MenuItem cg@2881: activeHelpKey: drawModeSpray cg@3404: enabled: canSprayHolder cg@2881: label: 'Spray' cg@2881: translateLabel: true cg@2881: isButton: true cg@2881: labelImage: (ResourceRetriever ImageEditor sprayIcon) cg@2881: choice: editMode cg@2881: choiceValue: spray cg@2375: ) cg@2881: (MenuItem cg@2881: activeHelpKey: drawModeBox cg@3404: enabled: canDrawRectsHolder cg@2881: label: 'Rect' cg@2881: translateLabel: true cg@2881: isButton: true cg@2881: labelImage: (ResourceRetriever ImageEditor rectIcon) cg@2881: choice: editMode cg@2881: choiceValue: box cg@1637: ) cg@2881: (MenuItem cg@2881: activeHelpKey: drawModeFilledBox cg@3404: enabled: canFillRectsHolder cg@2881: label: 'FillRect' cg@2881: translateLabel: true cg@2881: isButton: true cg@2881: labelImage: (ResourceRetriever ImageEditor fillRectIcon) cg@2881: choice: editMode cg@2881: choiceValue: filledBox cg@1637: ) cg@2881: (MenuItem cg@2881: activeHelpKey: drawModeCircle cg@3404: enabled: canDrawCirclesHolder cg@2881: label: 'Circle' cg@2881: translateLabel: true cg@2881: isButton: true cg@2881: labelImage: (ResourceRetriever ImageEditor circleIcon) cg@2881: choice: editMode cg@2881: choiceValue: circle cg@2375: ) cg@2881: (MenuItem cg@2881: activeHelpKey: drawModeFill cg@3404: enabled: canFloodFillHolder cg@2881: label: 'Fill' cg@2881: translateLabel: true cg@2881: isButton: true cg@2881: labelImage: (ResourceRetriever ImageEditor fillIcon) cg@2881: choice: editMode cg@2881: choiceValue: fill cg@1637: ) cg@2881: (MenuItem cg@2881: activeHelpKey: drawModeCopy cg@2881: enabled: imageIsLoadedHolder cg@2881: label: 'Copy' cg@2881: translateLabel: true cg@2881: isButton: true cg@2881: labelImage: (ResourceRetriever ImageEditor copyIcon) cg@2881: choice: editMode cg@2881: choiceValue: copy cg@1637: ) cg@2881: (MenuItem cg@2881: activeHelpKey: drawModePasteWithMask cg@3377: enabled: imageIsLoadedAndNotReadonlyHolder cg@2881: label: 'Paste With Mask' cg@2881: translateLabel: true cg@2881: isButton: true cg@2881: labelImage: (ResourceRetriever ImageEditor pasteWithMaskIcon) cg@2881: choice: editMode cg@2881: choiceValue: pasteWithMask cg@1637: ) cg@2881: (MenuItem cg@2881: activeHelpKey: drawModePaste cg@3377: enabled: imageIsLoadedAndNotReadonlyHolder cg@3561: label: 'Paste Over' cg@2881: translateLabel: true cg@2881: isButton: true cg@2881: labelImage: (ResourceRetriever ImageEditor pasteIcon) cg@2881: choice: editMode cg@2881: choiceValue: paste cg@1637: ) cg@2881: (MenuItem cg@3561: activeHelpKey: drawModePasteMasked cg@3561: enabled: imageIsLoadedAndNotReadonlyHolder cg@3561: label: 'Paste Masked' cg@3561: translateLabel: true cg@3561: isButton: true cg@3561: labelImage: (ResourceRetriever ImageEditor pasteMaskedIcon) cg@3561: choice: editMode cg@3561: choiceValue: pasteMasked cg@3561: ) cg@3561: (MenuItem cg@2881: activeHelpKey: drawModePasteUnder cg@3377: enabled: imageIsLoadedAndNotReadonlyHolder cg@2881: label: 'Paste Under' cg@2881: translateLabel: true cg@2881: isButton: true cg@2881: labelImage: (ResourceRetriever ImageEditor pasteUnderIcon) cg@2881: choice: editMode cg@2881: choiceValue: pasteUnder cg@1637: ) cg@2881: (MenuItem cg@3464: activeHelpKey: drawModeCropSubImage cg@3464: enabled: imageIsLoadedHolder cg@3464: label: 'Crop SubImage' cg@3464: translateLabel: true cg@3464: isButton: true cg@3464: labelImage: (ResourceRetriever ImageEditor cropSubImageIcon) cg@3464: choice: editMode cg@3464: choiceValue: cropSubImage cg@3464: ) cg@3464: (MenuItem cg@2881: activeHelpKey: drawModeSpecial cg@2881: enabled: imageIsLoadedHolder cg@2881: label: 'Special' cg@2881: translateLabel: true cg@2881: isButton: true cg@3419: labelImage: (ResourceRetriever ImageEditor specialRectangleIcon) cg@2881: choice: editMode cg@2881: choiceValue: specialOperation cg@1637: ) cg@1637: ) cg@1637: nil cg@1637: nil cg@1637: ) cg@3404: cg@3464: "Modified: / 24-08-2017 / 20:53:02 / cg" cg@3561: "Modified: / 27-05-2018 / 10:45:31 / Claus Gittinger" tz@400: ! ! tz@400: cg@1842: !ImageEditor class methodsFor:'tableColumns specs'! cg@1842: cg@1900: colorTableColumns cg@1842: "This resource specification was automatically generated cg@1842: by the DataSetBuilder of ST/X." cg@1842: cg@1842: "Do not manually edit this!! If it is corrupted, cg@1842: the DataSetBuilder may not be able to read the specification." cg@1842: cg@1842: " cg@1975: DataSetBuilder new openOnClass:ImageEditor andSelector:#colorTableColumns cg@1842: " cg@1842: cg@1842: cg@1842: cg@1842: ^#( cg@1842: (DataSetColumnSpec cg@2174: activeHelpKey: '' cg@1842: labelButtonType: Button cg@1842: rendererType: rowSelector cg@2712: backgroundSelector: theColorItself: cg@2712: selectedBackgroundSelector: theColorItself: cg@1842: isResizeable: false cg@1842: ) cg@1842: (DataSetColumnSpec cg@1842: label: 'R' cg@1842: labelAlignment: left cg@1842: labelButtonType: Button cg@1842: columnAlignment: right cg@1842: editorType: InputField cg@1842: type: number cg@1842: model: redFromColor: cg@1842: writeSelector: redAtColor:put: cg@1842: selectSelector: canSelectRedInColor: cg@1842: ) cg@1842: (DataSetColumnSpec cg@1842: label: 'G' cg@1842: labelAlignment: left cg@1842: labelButtonType: Button cg@1842: columnAlignment: right cg@1842: editorType: InputField cg@1842: type: number cg@1842: model: greenFromColor: cg@1842: writeSelector: greenAtColor:put: cg@1842: selectSelector: canSelectGreenInColor: cg@1842: ) cg@1842: (DataSetColumnSpec cg@1842: label: 'B' cg@1842: labelAlignment: left cg@1842: labelButtonType: Button cg@1842: columnAlignment: right cg@1842: editorType: InputField cg@1842: type: number cg@1842: model: blueFromColor: cg@1842: writeSelector: blueAtColor:put: cg@1842: selectSelector: canSelectBlueInColor: cg@1842: ) cg@1842: ) cg@2174: cg@2174: "Modified: / 22-07-2007 / 13:21:57 / cg" cg@1842: ! ! cg@1842: tz@400: !ImageEditor methodsFor:'accessing'! tz@400: tz@400: image tz@767: "returns the current editing image" tz@400: cg@1376: ^ imageEditView image tz@400: ! tz@400: tz@400: postOpenAction: anAction tz@767: "sets an action which is evaluated after opening" tz@400: tz@400: postOpenAction := anAction cg@1381: ! cg@1381: cg@1381: resourceClass:aClass cg@1381: imageEditView resourceClass:aClass cg@3375: ! cg@3375: cg@3379: savedFile cg@3379: "if user did a save to file, return the filename. cg@3379: Otherwise, this returns nil" cg@3379: cg@3379: ^ savedFile cg@3379: ! cg@3379: cg@3375: savedImage cg@3375: "if user did a save, return what was saved last. cg@3375: Otherwise, this returns nil" cg@3375: cg@3375: ^ savedImage tz@400: ! ! tz@400: cg@2767: !ImageEditor methodsFor:'accessing-behavior'! cg@2767: cg@3405: allowedToChangeImageDimension cg@3405: "used to edit an existing image's contents only (Expecco)" cg@3405: cg@3405: ^ self allowedToChangeImageDimensionAndDepth cg@3405: cg@3405: "Created: / 16-02-2017 / 01:59:21 / cg" cg@3405: ! cg@3405: cg@2767: allowedToChangeImageDimensionAndDepth cg@2767: "used to edit an existing image's contents only (Expecco)" cg@2767: cg@3378: self readOnly ifTrue:[^ false]. cg@2767: ^ allowedToChangeImageDimensionAndDepth ? true cg@2767: ! cg@2767: cg@2767: allowedToChangeImageDimensionAndDepth:aBoolean cg@2767: "used to edit an existing image's contents only (Expecco)" cg@2767: cg@2767: allowedToChangeImageDimensionAndDepth := aBoolean cg@2767: ! ! cg@2767: cg@1398: !ImageEditor methodsFor:'accessing-views'! tz@400: cg@915: colorDataSetView cg@915: "returns the view of the colormap" cg@915: cg@1597: ^(self componentAt: #colorDataSetView) cg@915: cg@915: "Created: / 26.7.1998 / 12:02:14 / cg" cg@915: ! cg@915: tz@487: coordLabel tz@767: "returns the view the coord label" tz@487: cg@1597: ^self componentAt: #coordLabel tz@487: ! tz@487: tz@400: imageEditView cg@3376: "returns the editor 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: cg@3413: !ImageEditor methodsFor:'actions'! cg@3413: cg@3413: applyCropAction cg@3413: self cropLeft:(self cropLeftAmount value) right:(self cropRightAmount value) cg@3413: top:(self cropTopAmount value) bottom:(self cropBottomAmount value) cg@3413: cg@3413: "Created: / 17-02-2017 / 14:34:35 / cg" cg@3413: "Modified: / 19-02-2017 / 15:11:41 / cg" cg@3413: ! cg@3413: cg@3413: cropBottomNow cg@3413: self cropLeft:0 right:0 top:0 bottom:(self cropBottomAmount value) cg@3413: cg@3413: "Created: / 19-02-2017 / 15:07:36 / cg" cg@3413: ! cg@3413: cg@3413: cropLeft:left right:right top:top bottom:bottom cg@3413: |img| cg@3413: cg@3413: img := imageEditView image. cg@3413: img isNil ifTrue:[^ self]. cg@3413: cg@3413: true "firstChange" ifTrue:[ cg@3413: imageEditView makeUndo. cg@3413: "/ firstChange := false. cg@3413: ]. cg@3413: imageEditView cg@3413: makeSubImageX:left y:top cg@3413: width:(img width - left - right) cg@3413: height:(img height - top - bottom). cg@3413: cg@3413: self updateImagePreView. cg@3413: self updateInfoLabel cg@3413: cg@3413: "Created: / 19-02-2017 / 15:07:58 / cg" cg@3413: ! cg@3413: cg@3413: cropLeftNow cg@3413: self cropLeft:(self cropLeftAmount value) right:0 top:0 bottom:0 cg@3413: cg@3413: "Created: / 19-02-2017 / 15:08:06 / cg" cg@3413: ! cg@3413: cg@3413: cropRightNow cg@3413: self cropLeft:0 right:(self cropRightAmount value) top:0 bottom:0 cg@3413: cg@3413: "Created: / 19-02-2017 / 15:08:12 / cg" cg@3413: ! cg@3413: cg@3413: cropTopNow cg@3413: self cropLeft:0 right:0 top:(self cropTopAmount value) bottom:0 cg@3413: cg@3413: "Created: / 19-02-2017 / 15:08:29 / cg" cg@3413: ! ! cg@3413: 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@3487: alphaHolder cg@3487: |holder| cg@3487: cg@3487: (holder := builder bindingAt:#alphaHolder) isNil ifTrue:[ cg@3487: builder aspectAt:#alphaHolder put:(holder := 100 asValue). cg@3487: holder onChangeEvaluate:[ imageEditView drawingAlpha:holder value ]. cg@3487: ]. cg@3487: ^ holder cg@3487: cg@3487: "Created: / 05-09-2017 / 00:38:14 / cg" cg@3488: "Modified: / 05-09-2017 / 10:47:01 / cg" cg@3487: ! cg@3487: cg@3487: alphaText cg@3487: ^ 'alpha:' cg@3487: cg@3487: "Created: / 05-09-2017 / 00:32:55 / cg" cg@3487: ! cg@3487: cg@3487: alphaVisibleHolder cg@3650: ^ builder booleanValueAspectFor:#alphaVisibleHolder cg@3487: cg@3487: "Created: / 05-09-2017 / 00:35:36 / cg" cg@3650: "Modified: / 09-03-2019 / 21:10:52 / Claus Gittinger" cg@3487: ! cg@3487: cg@3475: canAddColorToColormap cg@3475: |img| cg@3475: cg@3475: img := self image. cg@3475: img isNil ifTrue:[^ false]. cg@3475: img photometric == #blackIs0 ifTrue:[^ false]. cg@3475: img photometric == #whiteIs0 ifTrue:[^ false]. cg@3475: ^ true cg@3475: cg@3475: "Created: / 31-08-2017 / 18:32:27 / cg" cg@3475: ! cg@3475: cg@3475: canAddColorToColormapHolder cg@3475: ^ [self canAddColorToColormap] cg@3475: cg@3475: "Created: / 31-08-2017 / 18:32:40 / cg" cg@3475: ! cg@3475: cg@3475: canChangeColorInColormap cg@3475: |img| cg@3475: cg@3475: img := self image. cg@3475: img isNil ifTrue:[^ false]. cg@3475: img photometric == #palette ifFalse:[^ false]. cg@3475: ^ true cg@3475: cg@3475: "Created: / 31-08-2017 / 18:34:12 / cg" cg@3475: ! cg@3475: cg@3475: canChangeColorInColormapHolder cg@3475: ^ [self canChangeColorInColormap] cg@3475: cg@3475: "Created: / 31-08-2017 / 18:34:18 / cg" cg@3475: ! cg@3475: cg@3378: canResizeImage cg@3378: ^ self imageIsLoadedAndNotReadonlyHolder cg@3378: ! cg@3378: cg@3393: colorBoxVisibleHolder cg@3653: ^ builder valueAspectFor:#colorBoxVisibleHolder initialValue:true cg@3393: cg@3393: "Created: / 03-02-2017 / 11:20:21 / cg" cg@3653: "Modified: / 09-03-2019 / 22:18:00 / Claus Gittinger" cg@3393: ! cg@3393: cg@915: colorColumnAdaptor cg@915: ^ self cg@915: cg@915: "Created: / 26.7.1998 / 12:17:03 / cg" cg@915: ! cg@915: cg@3413: colorCropTabLabelList cg@3413: ^ resources array:(self colorCropTabSpecList collect:#first) cg@3413: cg@3413: "Created: / 19-02-2017 / 14:58:25 / cg" cg@3413: ! cg@3413: cg@3413: colorCropTabSelectionIndexHolder cg@3413: |holder| cg@3413: cg@3413: (holder := builder bindingAt:#colorCropTabSelectionIndexHolder) isNil ifTrue:[ cg@3415: builder aspectAt:#colorCropTabSelectionIndexHolder put:(holder := self defaultEditTabIndex asValue). cg@3413: holder onChangeSend:#colorCropTabSelectionIndexChanged to:self. cg@3413: ]. cg@3413: ^ holder cg@3413: cg@3413: "Created: / 19-02-2017 / 14:59:11 / cg" cg@3415: "Modified: / 19-02-2017 / 23:33:39 / cg" cg@3413: ! cg@3413: cg@3413: colorCropTabSpecList cg@3413: ^ #( cg@3413: ('Colors' colors) cg@3413: ('Crop' crop) cg@3413: ('Fill' fill) cg@3413: ) cg@3413: cg@3413: "Created: / 19-02-2017 / 15:34:33 / cg" cg@3413: ! cg@3413: cg@3413: colorCropTabSymbolList cg@3413: ^ self colorCropTabSpecList collect:#second cg@3413: cg@3413: "Created: / 19-02-2017 / 15:34:54 / cg" cg@3413: ! cg@3413: cg@3413: cropBottomAmount cg@3413: ^ builder valueAspectFor:'cropBottomAmount' initialValue:1 cg@3413: cg@3413: "Created: / 19-02-2017 / 15:09:09 / cg" cg@3413: ! cg@3413: cg@3393: cropBoxIsDialog cg@3413: ^ false cg@3393: cg@3393: "Created: / 03-02-2017 / 11:23:50 / cg" cg@3413: "Modified: / 19-02-2017 / 15:24:07 / cg" cg@3393: ! cg@3393: cg@3408: cropBoxIsNotDialog cg@3408: ^ self cropBoxIsDialog not cg@3408: cg@3408: "Created: / 17-02-2017 / 14:38:04 / cg" cg@3408: ! cg@3408: cg@3393: cropBoxVisibleHolder cg@3650: ^ builder booleanValueAspectFor:#cropBoxVisibleHolder cg@3393: cg@3393: "Created: / 03-02-2017 / 11:20:13 / cg" cg@3650: "Modified: / 09-03-2019 / 21:11:00 / Claus Gittinger" cg@3393: ! cg@3393: cg@3413: cropLeftAmount cg@3413: ^ builder valueAspectFor:'cropLeftAmount' initialValue:1 cg@3413: cg@3413: "Created: / 19-02-2017 / 15:09:23 / cg" cg@3413: ! cg@3413: cg@3413: cropRightAmount cg@3413: ^ builder valueAspectFor:'cropRightAmount' initialValue:1 cg@3413: cg@3413: "Created: / 19-02-2017 / 15:09:29 / cg" cg@3413: ! cg@3413: cg@3413: cropTopAmount cg@3413: ^ builder valueAspectFor:'cropTopAmount' initialValue:1 cg@3413: cg@3413: "Created: / 19-02-2017 / 15:09:35 / cg" cg@3413: ! cg@3413: cg@3415: defaultEditTabIndex cg@3415: "the default tab to show in the color/crop/fill tablist" cg@3415: cg@3415: ^ 1 cg@3415: cg@3415: "Created: / 19-02-2017 / 23:34:12 / cg" cg@3415: ! cg@3415: cg@3421: drawingColor1Holder cg@3421: "returns a valueHolder for the current selected mouse-button-1 color" cg@3421: cg@3421: |holder| cg@3421: cg@3421: (holder := builder bindingAt:#drawingColor1Holder) isNil ifTrue:[ cg@3421: builder aspectAt:#drawingColor1Holder put:(holder := IndirectValue new) cg@3421: ]. cg@3421: ^ holder cg@3421: cg@3421: "Created: / 23-02-2017 / 10:18:25 / cg" cg@3421: ! cg@3421: cg@3421: drawingColor2Holder cg@3421: "returns a valueHolder for the current selected mouse-button-2 color" cg@3421: cg@3421: |holder| cg@3421: cg@3421: (holder := builder bindingAt:#drawingColor2Holder) isNil ifTrue:[ cg@3421: builder aspectAt:#drawingColor2Holder put:(holder := IndirectValue new) cg@3421: ]. cg@3421: ^ holder cg@3421: cg@3421: "Created: / 23-02-2017 / 10:18:33 / cg" cg@3421: ! cg@3421: cg@3413: floodFillBoxVisibleHolder cg@3650: ^ builder booleanValueAspectFor:#floodFillBoxVisibleHolder cg@3413: cg@3413: "Created: / 19-02-2017 / 15:28:40 / cg" cg@3650: "Modified: / 09-03-2019 / 21:11:11 / Claus Gittinger" cg@3413: ! cg@3413: cg@3408: floodFillMaxHueError cg@3408: |holder| cg@3408: cg@3408: (holder := builder bindingAt:#floodFillMaxHueError) isNil ifTrue:[ cg@3408: builder aspectAt:#floodFillMaxHueError put:(holder := 0 asValue). cg@3408: holder onChangeEvaluate:[ imageEditView floodFillMaxHueError:holder value ]. cg@3408: ]. cg@3408: ^ holder cg@3408: cg@3408: "Created: / 17-02-2017 / 15:19:17 / cg" cg@3408: ! cg@3408: cg@3408: floodFillMaxLightError cg@3408: |holder| cg@3408: cg@3408: (holder := builder bindingAt:#floodFillMaxLightError) isNil ifTrue:[ cg@3408: builder aspectAt:#floodFillMaxLightError put:(holder := 0 asValue). cg@3408: holder onChangeEvaluate:[ imageEditView floodFillMaxLightError:holder value ]. cg@3408: ]. cg@3408: ^ holder cg@3408: cg@3408: "Created: / 17-02-2017 / 15:19:11 / cg" cg@3408: ! cg@3408: cg@2792: hasClassAndSelectorDefinedHolder cg@1054: ^ [ cg@1965: |cls| cg@1965: cg@1965: (cls := imageEditView resourceClass) notNil cg@1965: and:[imageEditView resourceSelector notNil] cg@1054: ] cg@933: cg@2792: "Created: / 04-07-2010 / 10:11:10 / cg" cg@2792: ! cg@2792: cg@2792: hasClassDefinedHolder cg@1054: ^ [ cg@1965: imageEditView resourceClass notNil cg@1054: ] cg@933: cg@2792: "Created: / 04-07-2010 / 10:11:47 / cg" cg@2792: ! cg@2792: cg@2792: hasColorSelectedHolder cg@3195: ^ [ self selectedColors value notEmptyOrNil "self selectedColorIndexOrNil notNil" ] cg@2792: cg@2792: "Created: / 04-07-2010 / 10:12:22 / cg" cg@2651: ! cg@2651: cg@1008: hasColormap cg@3475: "true if a colormap is shown (might be a drwing map, not the real map)" cg@3475: cg@3421: |img| cg@3421: cg@3421: ^ (img := self image) notNil cg@3598: and:[img colorMap notNil cg@3598: or:[ drawingColormap notNil cg@3598: or:[ self listOfColors notEmptyOrNil ]]] cg@2792: cg@2792: "Created: / 30-09-1998 / 23:53:55 / cg" cg@3421: "Modified: / 23-02-2017 / 09:57:45 / cg" cg@3475: "Modified (comment): / 31-08-2017 / 18:36:08 / cg" cg@1008: ! cg@1008: cg@2651: hasColormapAndColorSelected cg@3476: ^ [ self hasColormap and:[self hasColorSelectedHolder value]] cg@3476: cg@3476: "Modified: / 31-08-2017 / 14:08:20 / cg" cg@2792: ! cg@2792: cg@3195: hasColormapAndSingleColorSelected cg@3475: ^ self hasColormapHolder value and:[self hasSingleColorSelectedHolder value] cg@3475: cg@3475: "Modified: / 31-08-2017 / 18:44:49 / cg" cg@3475: ! cg@3475: cg@3475: hasColormapAndSingleColorSelectedHolder cg@3475: ^ [ self hasColormapAndSingleColorSelected value ] cg@3475: cg@3475: "Created: / 31-08-2017 / 18:44:36 / cg" cg@3475: ! cg@3475: cg@3475: hasColormapAndSingleWritableColorSelectedHolder cg@3553: ^ [ self hasColormapAndSingleColorSelected cg@3553: and:[self canChangeColorInColormap ]] cg@3475: cg@3475: "Created: / 31-08-2017 / 18:42:46 / cg" cg@3195: ! cg@3195: cg@2792: hasColormapHolder cg@3475: "true if a colormap is shown (might be a drwing map, not the real map)" cg@3475: cg@2792: ^ [self hasColormap] cg@2792: cg@2792: "Created: / 04-07-2010 / 10:13:05 / cg" cg@3475: "Modified (comment): / 31-08-2017 / 18:36:47 / cg" cg@2792: ! cg@2792: cg@3195: hasSingleColorSelectedHolder cg@3195: ^ [ self selectedColors value size == 1 "self selectedColorIndexOrNil notNil" ] cg@3195: cg@3195: "Created: / 04-07-2010 / 10:12:22 / cg" cg@3195: ! cg@3195: cg@3496: hasWritableColorSelectedHolder cg@3496: ^ [ self hasSingleColorSelectedHolder value and:[self canChangeColorInColormap ]] cg@3496: cg@3496: "Created: / 08-10-2017 / 14:45:11 / cg" cg@3496: ! cg@3496: cg@3475: imageHasColormap cg@3475: "true if a colormap is shown (might be a drwing map, not the real map)" cg@3475: cg@3475: |img| cg@3475: cg@3475: ^ (img := self image) notNil cg@3475: and:[img colorMap notNil ] cg@3475: cg@3475: "Created: / 31-08-2017 / 18:36:25 / cg" cg@3475: ! cg@3475: cg@3475: imageHasColormapHolder cg@3475: ^ [self imageHasColormap] cg@3475: cg@3475: "Created: / 31-08-2017 / 18:36:42 / cg" cg@3475: ! cg@3475: cg@2812: imageHasImageSequence cg@3080: |img| cg@3080: cg@3080: ^ (img := self image) notNil and:[img imageSequence notNil] cg@2812: cg@2812: "Created: / 21-10-2010 / 14:35:45 / cg" cg@2812: ! cg@2812: cg@2812: imageHasImageSequenceHolder cg@2812: |holder| cg@2812: cg@2812: (holder := builder bindingAt:#imageHasImageSequenceHolder) isNil ifTrue:[ cg@2812: builder aspectAt:#imageHasImageSequenceHolder put:(holder := false asValue). cg@2812: holder value:(self imageHasImageSequence). cg@2812: ]. cg@2812: ^ holder cg@2812: cg@2812: "Modified: / 21-10-2010 / 14:36:57 / cg" cg@2812: ! cg@2812: cg@3405: imageHasMaskAndIsNotReadOnlyHolder cg@3405: "returns whether an image is loaded and editable as value holder" cg@3405: cg@3405: ^ BlockValue cg@3405: with:[:loaded | loaded and:[ self image mask notNil and:[self readOnly not] ]] cg@3405: argument:(self imageIsLoadedHolder) cg@3405: cg@3405: "Created: / 16-02-2017 / 12:17:25 / cg" cg@3405: ! cg@3405: cg@2812: imageHasNextImage cg@2812: ^ self imageHasImageSequence and:[ (imageSeqNr ? 1) < self image imageSequence size ] cg@2812: cg@2812: "Created: / 21-10-2010 / 14:37:10 / cg" cg@2812: ! cg@2812: cg@2792: imageHasNextImageHolder cg@2812: |holder| cg@2812: cg@2812: (holder := builder bindingAt:#imageHasNextImageHolder) isNil ifTrue:[ cg@2812: builder aspectAt:#imageHasNextImageHolder put:(holder := false asValue). cg@2812: holder value:(self imageHasNextImage). cg@2812: ]. cg@2812: ^ holder cg@2812: cg@2812: "Modified: / 21-10-2010 / 14:37:40 / cg" cg@2812: ! cg@2812: cg@2812: imageHasPreviousImage cg@2812: ^ self imageHasImageSequence and:[ (imageSeqNr ? 1) > 1 ] cg@2812: cg@2812: "Created: / 21-10-2010 / 14:37:21 / cg" cg@2812: ! cg@2812: cg@2812: imageHasPreviousImageHolder cg@2812: |holder| cg@2812: cg@2812: (holder := builder bindingAt:#imageHasPreviousImageHolder) isNil ifTrue:[ cg@2812: builder aspectAt:#imageHasPreviousImageHolder put:(holder := false asValue). cg@2812: holder value:(self imageHasPreviousImage). cg@2812: ]. cg@2812: ^ holder cg@2812: cg@2812: "Modified: / 21-10-2010 / 14:37:48 / cg" cg@1380: ! cg@1380: cg@928: imageInfoHolder cg@3653: ^ builder valueAspectFor:#imageInfoHolder initialValue:'' cg@928: cg@2792: "Modified: / 04-07-2010 / 10:15:14 / cg" cg@3653: "Modified: / 09-03-2019 / 22:18:11 / Claus Gittinger" tz@400: ! tz@400: tz@400: listOfColors penk@1896: "returns the list of colors" penk@1896: penk@1896: |list| penk@1896: penk@1896: (list := builder bindingAt:#listOfColors) isNil ifTrue:[ penk@1896: builder aspectAt:#listOfColors put:(list := List new). penk@1896: list addDependent:self. tz@400: ]. penk@1896: ^ list tz@400: ! tz@400: cg@1987: magnificationHolder cg@1987: "returns current magnification of the image as an AspectAdaptor" cg@1987: cg@1987: |holder| cg@1987: (holder := builder bindingAt:#valueOfMagnification) isNil ifTrue:[ cg@1987: builder aspectAt:#valueOfMagnification put:( cg@1987: holder := AspectAdaptor new subject:self; forAspect:#magnification) cg@1987: ]. cg@1987: ^ holder cg@1987: ! cg@1987: cg@2881: penWidthHolder cg@2881: |holder| cg@2881: cg@2881: (holder := builder bindingAt:#penWidthHolder) isNil ifTrue:[ cg@2881: builder aspectAt:#penWidthHolder put:(holder := imageEditView penWidth asValue). cg@2881: holder onChangeSend:#penWidthHolderChanged to:self. cg@2881: ]. cg@2881: ^ holder cg@2881: cg@2881: "Created: / 15-02-2012 / 22:30:58 / cg" cg@2881: ! cg@2881: cg@2792: previewBackgroundColorHolder cg@1764: |holder| cg@2792: cg@1764: (holder := builder bindingAt:#previewBackgroundColor) isNil ifTrue:[ cg@1764: builder aspectAt:#previewBackgroundColor put:(holder := nil asValue). cg@1764: holder addDependent:self. cg@1764: ]. cg@1764: ^ holder cg@2792: cg@2792: "Created: / 04-07-2010 / 10:19:34 / cg" cg@1764: ! cg@1764: cg@3489: previewMagnificationHolder cg@3489: |holder| cg@3489: cg@3489: (holder := builder bindingAt:#previewMagnificationHolder) isNil ifTrue:[ cg@3489: builder aspectAt:#previewMagnificationHolder put:(holder := 1 asValue). cg@3489: holder addDependent:self. cg@3489: ]. cg@3489: ^ holder cg@3489: cg@3489: "Created: / 10-09-2017 / 14:10:07 / cg" cg@3489: ! cg@3489: cg@3377: readOnly cg@3377: ^ false cg@3377: ! cg@3377: cg@3425: saveButtonInToolbarVisibleHolder cg@3425: ^ false cg@3425: cg@3425: "Created: / 26-02-2017 / 22:58:41 / cg" cg@3425: ! cg@3425: cg@3195: selectedColors cg@3195: "returns a valueHolder for the current set of selected colors." cg@3195: cg@3195: |holder| cg@3195: cg@3195: (holder := builder bindingAt:#selectedColors) isNil ifTrue:[ cg@3195: builder aspectAt:#selectedColors put:(holder := nil asValue). cg@3195: holder onChangeSend:#selectedColorsChanged to:self. cg@3195: ]. cg@3195: ^ holder cg@3195: ! cg@3195: tz@400: selectionOfColor cg@1682: "returns a valueHolder for the current selection of the edit color. cg@1682: Here, an AspectAdaptor which accesses selectedColorIndex is returned." tz@400: tz@400: |holder| cg@1682: tz@400: (holder := builder bindingAt:#selectionOfColor) isNil ifTrue:[ tz@400: builder aspectAt:#selectionOfColor put:( cg@1682: holder := AspectAdaptor new subject:self; forAspect:#selectedColorIndex ). tz@400: ]. tz@400: ^ holder tz@400: ! tz@400: cg@2881: spraySpotHolder cg@2881: |holder| cg@2881: cg@2881: (holder := builder bindingAt:#spraySpotHolder) isNil ifTrue:[ cg@2881: builder aspectAt:#spraySpotHolder put:(holder := imageEditView spraySpot asValue). cg@2881: holder onChangeSend:#spraySpotHolderChanged to:self. cg@2881: ]. cg@2881: ^ holder cg@2881: cg@2881: "Created: / 15-02-2012 / 22:36:38 / cg" cg@2881: ! cg@2881: cg@1558: tileModeHolder cg@1558: |holder| cg@2812: cg@1558: (holder := builder bindingAt:#tileModeHolder) isNil ifTrue:[ cg@1558: builder aspectAt:#tileModeHolder put:(holder := false asValue). cg@1558: holder addDependent:self. cg@1558: ]. cg@1558: ^ holder cg@2812: cg@2812: "Modified: / 21-10-2010 / 14:35:24 / cg" cg@1558: ! cg@1558: tz@400: valueOfMagnification sv@2308: tz@767: "returns current magnification of the image as an AspectAdaptor" tz@400: cg@1987: self obsoleteMethodWarning:'stupid method name - use #magnificationHolder'. cg@1987: ^ self magnificationHolder tz@400: ! ! tz@400: tz@767: !ImageEditor methodsFor:'change & update'! tz@767: cg@3489: changePreviewImageMagnification cg@3489: |mag| cg@3489: cg@3489: mag := Dialog request:'Magnification?' initialAnswer:self imagePreView magnificationFactor. cg@3489: mag isEmptyOrNil ifTrue:[^ self]. cg@3489: mag := Number readFrom:mag onError:nil. cg@3489: mag isNil ifTrue:[^ self]. cg@3489: cg@3489: self previewMagnificationHolder value:mag cg@3489: cg@3489: "Created: / 10-09-2017 / 14:52:52 / cg" cg@3489: ! cg@3489: cg@3413: colorCropTabSelectionIndexChanged cg@3413: |selIndex sym| cg@3413: cg@3413: selIndex := self colorCropTabSelectionIndexHolder value. cg@3413: sym := self colorCropTabSymbolList at:selIndex. cg@3413: cg@3413: self colorBoxVisibleHolder value:(sym == #colors). cg@3413: self cropBoxVisibleHolder value:(sym == #crop). cg@3413: self floodFillBoxVisibleHolder value:(sym == #fill). cg@3413: cg@3413: "Created: / 19-02-2017 / 15:01:05 / cg" cg@3443: "Modified: / 21-04-2017 / 16:05:51 / cg" cg@3413: ! cg@3413: cg@3433: colorMapModeFromImage:anImage cg@3433: "retrieves the colorMapMode for an image" cg@3433: cg@3433: |image colorMapModeKey| cg@3433: cg@3433: image := self image. cg@3433: image isNil ifTrue:[^ nil ]. cg@3433: cg@3433: image mask notNil ifTrue: [ cg@3433: colorMapModeKey := 'masked'. cg@3433: ] ifFalse:[ cg@3433: colorMapModeKey := 'depth'. cg@3433: ]. cg@3433: colorMapModeKey := (colorMapModeKey , image depth printString) asSymbol. cg@3433: ^ colorMapModeKey cg@3433: cg@3433: "Created: / 06-04-2017 / 13:19:19 / cg" cg@3433: ! cg@3433: 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@3433: (colorMapModeKey := self colorMapModeFromImage:image) isNil ifTrue:[^ self]. cg@3433: cg@1967: self colorMapMode setValue:colorMapModeKey. cg@1847: cg@3359: image photometric == #palette ifTrue:[ cg@3359: image colorMap isNil ifTrue:[ cg@3359: image depth > 16 ifTrue:[ cg@3359: image photometric:#rgb cg@3359: ]. cg@3359: ]. cg@3359: ]. cg@1928: cg@1847: image depth > 12 ifTrue:[ cg@2447: newListOfColors := OrderedCollection new. cg@2870: (image depth > 16 or:[image colorMap isEmptyOrNil]) ifTrue:[ cg@1927: someOrAllUsedColors := image usedColorsMax:10000. cg@2054: someOrAllUsedColors notNil ifTrue:[ cg@2054: someOrAllUsedColors := someOrAllUsedColors asArray. cg@2054: someOrAllUsedColors sort:self sortBlockForColors. cg@2446: newListOfColors addAll:someOrAllUsedColors. cg@2054: "/ listOfColors add:Color black; add:Color white. cg@3317: ]. cg@3317: image mask notNil ifTrue:[ cg@3317: newListOfColors := (Array with:(Color noColor)),newListOfColors. cg@3317: ]. cg@1904: ] ifFalse:[ cg@2446: newListOfColors addAll:(image colorMap). cg@1847: ]. cg@1847: ] ifFalse:[ cg@2447: newListOfColors := OrderedCollection withAll:(self listOfColors). cg@2446: newListOfColors isEmpty ifTrue:[ cg@1847: self colorMapMode: colorMapMode value. cg@1847: image := self image. cg@1847: ]. cg@3317: "/ image mask notNil ifTrue:[ cg@3317: "/ newListOfColors := (Array with:(Color noColor)),newListOfColors. cg@3317: "/ ]. cg@2054: ]. cg@2446: newListOfColors notEmptyOrNil ifTrue:[ cg@2446: drawColor1 := newListOfColors at:1. cg@2446: drawColor2 := newListOfColors at:2 ifAbsent:drawColor1. cg@2054: cg@3487: self hasTransparentColorInColorList ifTrue: [ sv@3367: (newListOfColors includes:(Color colorId:0)) ifFalse:[ cg@2446: newListOfColors addFirst:(Color colorId:0). cg@2446: drawColor1 := newListOfColors at:2. cg@2446: drawColor2 := newListOfColors at:3 ifAbsent:drawColor1. cg@2054: ] cg@2054: ]. cg@2446: "/ imageEditView drawingColors:(Array with: drawColor1 with: drawColor2). cg@2446: "/ self selectionOfColor cg@2446: "/ setValue: 0; cg@2446: "/ value: (listOfColors indexOf: imageEditView selectedColor). tz@767: ]. cg@2447: self listOfColors asOrderedCollection ~= newListOfColors ifTrue:[ cg@2447: self listOfColors contents:newListOfColors. cg@2447: ]. cg@2870: cg@3487: "Modified: / 05-09-2017 / 09:03:31 / cg" tz@767: ! tz@767: cg@3195: selectedColorsChanged cg@3408: |colorIndices selectedIndex| cg@3408: cg@3408: (colorIndices := self selectedColors value) size == 1 ifTrue:[ cg@3408: "/ a single color selected cg@3408: selectedIndex := colorIndices first cg@3408: ]. cg@3408: self selectionOfColor value:selectedIndex cg@3408: cg@3408: "Modified: / 17-02-2017 / 14:40:33 / cg" cg@3195: ! cg@3195: tz@942: update:something with:aParameter from:changedObject cg@3405: |clrIndex image imagePreView clr changedColor cMap| cg@3405: cg@3405: image := self image. cg@2042: imagePreView := self imagePreView. cg@1558: cg@1558: changedObject == self tileModeHolder ifTrue:[ mawalch@3546: image isNil ifTrue:[ mawalch@3546: ^ self mawalch@3546: ]. mawalch@3546: imagePreView cg@3405: tileMode:(changedObject value) tileOffset:(image extent); mawalch@3546: clear; cg@1764: invalidate. cg@1764: ^ self cg@1764: ]. mawalch@3546: cg@2792: changedObject == self previewBackgroundColorHolder ifTrue:[ mawalch@3546: clr := changedObject value isNil cg@1764: ifTrue:[imageEditView viewBackground] cg@1764: ifFalse:[Color perform:changedObject value]. mawalch@3546: imagePreView cg@1764: viewBackground:clr; cg@3493: clear; cg@1764: invalidate. cg@1558: ^ self cg@1558: ]. cg@3489: changedObject == self previewMagnificationHolder ifTrue:[ mawalch@3546: imagePreView cg@3489: magnificationFactor:(self previewMagnificationHolder value); mawalch@3546: clear; cg@3493: invalidate. mawalch@3546: ^ self mawalch@3546: ]. mawalch@3546: 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@3487: (self hasTransparentColorInColorList) ifTrue:[ cg@960: clrIndex := clrIndex - 1. cg@960: ]. cg@1928: changedColor := changedObject at:aParameter. cg@3405: cMap := image colorMap. cg@3407: (cMap notNil and:[cMap isFixedPalette not]) ifTrue:[ cg@3405: image colorMap at:clrIndex put:changedColor. cg@1928: self colorMapChanged. cg@3430: ] ifFalse:[ cg@3430: drawingColormap notNil ifTrue:[ cg@3430: drawingColormap size < clrIndex ifTrue:[ cg@3430: |newDrawingColormap| mawalch@3546: cg@3430: newDrawingColormap := drawingColormap species new:clrIndex. cg@3430: newDrawingColormap replaceFrom:1 with:drawingColormap. cg@3430: drawingColormap := newDrawingColormap. mawalch@3546: ]. cg@3430: drawingColormap at:clrIndex put:changedColor. cg@3430: ]. mawalch@3546: ]. 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). mawalch@3546: ^ self cg@1124: ]. cg@1124: cg@1345: changedObject == imageEditView ifTrue:[ cg@1345: something == #imageColors ifTrue:[ cg@1847: self updateListOfColorsAndColormapMode. mawalch@3546: ^ self cg@1345: ]. cg@1345: something == #image ifTrue:[ cg@2812: self updateAfterImageChange. cg@3405: imagePreView image:image scroll:false. cg@1847: self updateListOfColorsAndColormapMode. cg@1558: self tileModeHolder value ifTrue:[ cg@3405: imagePreView tileMode:true tileOffset:(image extent). cg@1558: ]. cg@3460: self updateInfoLabel. mawalch@3546: ^ self cg@1345: ]. cg@1345: something == #subImageIn ifTrue:[ cg@3405: imagePreView image ~~ image 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: ]. mawalch@3546: ^ 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@3487: clrIndex := self hasTransparentColorInColorList ifTrue:[1] ifFalse:[0]. cg@1842: ] ifFalse:[ cg@1842: clrIndex := self listOfColors indexOf:aParameter. cg@1491: ]. cg@3195: self selectedColors value:{clrIndex}. "/ selectionOfColor value:clrIndex. mawalch@3546: ^ self cg@1491: ]. mawalch@3546: ^ self cg@1345: ]. cg@1345: cg@1880: changedObject == imageEditView modifiedHolder ifTrue:[ cg@1880: "/ self halt:'to be implemented'. cg@1880: ^ self cg@1880: ]. cg@1880: cg@1345: changedObject == imageEditView image ifTrue:[ cg@2042: "/ self halt:'to be implemented'. cg@2812: self updateAfterImageChange. mawalch@3546: ^ self cg@1345: ]. cg@1345: tz@942: super update:something with:aParameter from:changedObject tz@942: cg@3493: "Modified: / 13-09-2017 / 18:01:26 / cg" cg@2812: ! cg@2812: cg@2812: updateAfterImageChange cg@2812: |img| cg@2812: cg@2812: (img := self image) notNil ifTrue:[ cg@2812: img := img onDevice:device. cg@2812: self updateColorsFromImage:img. cg@2812: self findColorMapMode. cg@2812: self updateLabelsAndHistory. cg@2812: cg@2812: imageSeqNr isNil ifTrue:[ cg@2812: imageSeqNr := 1 cg@2812: ]. cg@2812: self imageHasImageSequenceHolder value:(self imageHasImageSequence). cg@2812: self imageHasNextImageHolder value:(self imageHasNextImage). cg@2812: self imageHasPreviousImageHolder value:(self imageHasPreviousImage). cg@3561: self alphaVisibleHolder value:(img hasAlphaChannel). cg@2812: ] ifFalse:[ cg@2812: self updateForNoImage cg@3561: ]. cg@3561: self window label:(self constructWindowTitle). cg@2812: cg@3487: "Modified: / 05-09-2017 / 00:44:10 / cg" cg@3561: "Modified: / 27-05-2018 / 11:32:01 / Claus Gittinger" tz@942: ! tz@942: cg@1900: updateColorsFromImage:image cg@3475: |colors depth| cg@3475: cg@3475: depth := image depth. cg@3475: cg@3475: depth > 16 ifTrue:[ cg@3475: colors := #() "/ too many - will only show the one's which are explicitly added. cg@3475: ] ifFalse:[ cg@3475: ((image photometric == #blackIs0) cg@3475: or:[ image photometric == #whiteIs0 ]) ifTrue:[ cg@3475: depth <= 8 ifTrue:[ cg@3475: colors := 1 to:(1 << depth) collect:[:i | image colorFromValue:i-1] cg@3475: ]. cg@2870: ]. cg@3475: colors isNil ifTrue:[ cg@3475: colors := image colorMap. cg@3475: colors isNil ifTrue:[ cg@3475: Error handle:[:ex | cg@3475: colors := OrderedCollection new. cg@3475: ] do:[ cg@3475: colors := image usedColors asSet. cg@3475: ]. cg@3475: ]. cg@3475: ]. cg@3475: ]. cg@1904: self listOfColors contents:(colors asOrderedCollection). cg@2870: cg@3475: "Modified: / 31-08-2017 / 18:54:53 / cg" cg@1900: ! cg@1900: cg@1054: updateForNoImage tz@767: "updates channels and view, if image is loaded" tz@767: cg@2792: self imageIsLoadedHolder value: false. tz@767: self listOfColors removeAll. cg@2812: self imagePreView image: nil. cg@2812: self imageHasImageSequenceHolder value:false. cg@3487: self alphaVisibleHolder value:false. cg@3487: cg@3487: "Modified: / 05-09-2017 / 00:44:20 / cg" cg@3561: "Modified: / 27-05-2018 / 11:32:06 / Claus Gittinger" tz@767: ! tz@767: tz@767: updateLabelsAndHistory tz@767: "updates labels and history, if something has changed" tz@767: cg@3476: |image rsrcClass rsrcSelector imgFile| cg@1910: cg@1910: image := self image. cg@1910: cg@2792: self imageIsLoadedHolder value: image notNil. cg@1910: image isNil ifTrue: [^nil]. tz@767: tz@767: self updateInfoLabel. tz@767: cg@3476: ((rsrcClass := imageEditView resourceClass) notNil cg@3476: and:[ (rsrcSelector := imageEditView resourceSelector) notNil ]) ifTrue:[ cg@3476: self addHistoryEntryForClass:rsrcClass selector:rsrcSelector. cg@3476: ] ifFalse:[ cg@3476: (imgFile := image fileName) notNil ifTrue: [ cg@3476: self addHistoryEntryForFile:imgFile. cg@3476: ]. cg@3476: ]. cg@3476: cg@3476: "Modified: / 01-09-2017 / 10:10:12 / cg" cg@1847: ! cg@1847: cg@1847: updateListOfColorsAndColormapMode cg@3487: |listOfColors selectedColor colorMap image| cg@2446: cg@2446: selectedColor := self selectedColorOrNil. cg@3487: listOfColors := self listOfColors. cg@3487: cg@1847: image := self image. cg@1975: image isNil ifTrue:[ cg@3487: listOfColors removeAll. cg@1975: ] ifFalse:[ cg@1975: colorMap := image colorMap. cg@2447: colorMap notNil ifTrue:[ cg@2447: (colorMap size <= 4096) ifTrue:[ cg@3487: (image mask notNil or:[image hasAlphaChannel]) ifTrue:[ cg@2447: colorMap := (Array with:(Color noColor)),colorMap. cg@2447: ]. cg@3487: listOfColors contents:colorMap. cg@2447: ] ifFalse:[ cg@3487: 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: ]. cg@3487: cg@3487: "Modified: / 05-09-2017 / 08:25:14 / cg" tz@767: ! ! tz@767: cg@915: !ImageEditor methodsFor:'data access'! cg@915: cg@1951: atColor:anOldColor put:newColor cg@1952: "a color changed to a new color" cg@1952: cg@1930: |index list oldColor image newImage oldSel| ca@1611: ca@1611: list := self listOfColors. cg@1951: index := list identityIndexOf:anOldColor. ca@1611: cg@1930: oldSel := self selectionOfColor value. ca@1611: index ~~ 0 ifTrue:[ cg@1928: oldColor := list at:index. cg@1928: list at:index put:newColor ca@1611: ] ifFalse:[ sv@1740: self error:'internal error' mayProceed:true. cg@1928: list add:newColor cg@1928: ]. cg@1928: cg@1928: image := self image. cg@1928: (image colorMap isNil cg@1928: and:[drawingColormap isNil]) ifTrue:[ cg@1928: oldColor notNil ifTrue:[ cg@1928: imageEditView makeUndo. cg@1928: newImage := image copy. cg@1928: newImage cg@1928: colorsFromX:0 y:0 toX:(image width-1) y:(image height-1) cg@1928: do:[:x :y :clr | cg@1928: |newClr| cg@1928: cg@1951: newClr := (clr = oldColor) ifTrue:[newColor] ifFalse:[clr]. cg@1928: newImage colorAtX:x y:y put:newClr cg@1928: ]. cg@1928: imageEditView image:newImage. cg@1928: imageEditView setModified. cg@1928: self updateImage. cg@1928: self updateImagePreView. cg@1930: cg@3195: self selectedColors value:{oldSel}. cg@1930: imageEditView selectedColorIndex:oldSel. cg@1930: imageEditView selectedColor:(self listOfColors at:oldSel). cg@1928: ] ca@1611: ]. ca@1611: ! ca@1611: tz@942: blueAtColor:aColor put:newBlue tz@942: "helper used to return a new row element, when blue is changed" tz@942: tz@942: |byte| tz@942: ca@1611: aColor isNil ifTrue:[^ self]. "/ mask cannot be changed tz@942: byte := newBlue clampBetween:0 and:255. ca@1611: byte = aColor blueByte ifTrue:[^ self ]. ca@1611: ca@1611: self atColor:aColor ca@1611: put:(Color redByte:(aColor redByte) greenByte:(aColor greenByte) blueByte:byte). tz@942: ! tz@942: cg@915: blueFromColor:aColor cg@915: "helper used to access a color as a row in the dataSet view" cg@915: cg@930: aColor isNil ifTrue:[^ 'none']. cg@915: ^ aColor blueByte ? 'mask' cg@915: cg@915: "Created: / 26.7.1998 / 12:30:35 / cg" cg@930: "Modified: / 31.7.1998 / 01:11:18 / cg" cg@915: ! cg@915: cg@945: canSelectBlueInColor:aColor cg@945: ^ aColor blueByte notNil cg@945: cg@945: "Created: / 7.8.1998 / 22:50:34 / cg" cg@945: "Modified: / 7.8.1998 / 22:52:57 / cg" cg@945: ! cg@945: cg@945: canSelectGreenInColor:aColor cg@945: ^ aColor greenByte notNil cg@945: cg@945: "Created: / 7.8.1998 / 22:50:22 / cg" cg@945: "Modified: / 7.8.1998 / 22:52:46 / cg" cg@945: ! cg@945: cg@945: canSelectRedInColor:aColor cg@945: ^ aColor redByte notNil cg@945: cg@945: "Created: / 7.8.1998 / 22:50:00 / cg" cg@945: "Modified: / 7.8.1998 / 22:51:03 / cg" cg@945: ! cg@945: tz@942: greenAtColor:aColor put:newGreen tz@942: "helper used to return a new row element, when green is changed" tz@942: tz@942: |byte| tz@942: ca@1611: aColor isNil ifTrue:[^ self]. "/ mask cannot be changed tz@942: byte := newGreen clampBetween:0 and:255. ca@1611: byte = aColor greenByte ifTrue:[^ self]. ca@1611: ca@1611: self atColor:aColor ca@1611: put:(Color redByte:(aColor redByte) greenByte:byte blueByte:(aColor blueByte)). tz@942: ! tz@942: cg@915: greenFromColor:aColor cg@915: "helper used to access a color as a row in the dataSet view" cg@915: cg@930: aColor isNil ifTrue:[^ 'none']. cg@915: ^ aColor greenByte ? 'mask' cg@915: cg@915: "Created: / 26.7.1998 / 12:30:29 / cg" cg@930: "Modified: / 31.7.1998 / 01:11:31 / cg" cg@915: ! cg@915: tz@942: redAtColor:aColor put:newRed tz@942: "helper used to return a new row element, when red is changed" tz@942: tz@942: |byte| tz@942: ca@1611: aColor isNil ifTrue:[^ self]. "/ mask cannot be changed tz@942: byte := newRed clampBetween:0 and:255. ca@1611: byte = aColor redByte ifTrue:[^ self]. ca@1611: ca@1611: self atColor:aColor ca@1611: put:(Color redByte:byte greenByte:(aColor greenByte) blueByte:(aColor blueByte)). tz@942: ! tz@942: cg@915: redFromColor:aColor cg@915: "helper used to access a color as a row in the dataSet view" cg@915: cg@930: aColor isNil ifTrue:[^ 'none']. cg@915: ^ aColor redByte ? 'mask' cg@915: cg@930: "Modified: / 31.7.1998 / 01:11:35 / cg" cg@1449: ! cg@1449: cg@2712: theColorItself:aColor cg@2712: "an accessor for the table-column" cg@2712: cg@1449: ^ aColor cg@915: ! ! cg@915: cg@2663: !ImageEditor methodsFor:'defaults'! cg@2663: cg@2663: aboutIcon cg@2663: ^ self class defaultIcon cg@2663: ! ! cg@2663: cg@2339: !ImageEditor methodsFor:'drag & drop'! cg@2339: cg@2339: canDropObjects:aCollectionOfDropObjects in:aWidget cg@2339: ^ (aCollectionOfDropObjects size == 1) cg@2339: and:[ aCollectionOfDropObjects cg@2339: contains:[:dropObject | dropObject isFileObject]] cg@2339: ! cg@2339: cg@2339: dropObjects:aCollectionOfDropObjects in:aWidget at:position cg@2339: |dropObject| cg@2339: cg@2339: dropObject := aCollectionOfDropObjects first. cg@2339: dropObject isFileObject ifTrue:[ cg@2339: self loadFromFile:dropObject asFilename. cg@2339: ] cg@2339: ! ! cg@2339: cg@2339: !ImageEditor methodsFor:'event handling'! cg@2339: cg@2339: processEvent:anEvent cg@2339: "Return true, if I have eaten the event" cg@2339: cg@2945: cg@2945: cg@2841: |view focusView p transformation| cg@2841: cg@2841: view := anEvent view. cg@2841: view notNil ifTrue:[ cg@3405: cg@2841: view == self imagePreView ifTrue:[ cg@2841: ((anEvent isButtonPressEvent and:[ anEvent button == 1 ]) cg@2841: or:[ anEvent isButtonMotionEvent and:[ anEvent hasButton1 ]]) ifTrue:[ cg@3489: p := anEvent x @ anEvent y. cg@2841: (transformation := view transformation) notNil ifTrue:[ cg@2841: p := transformation applyInverseTo:p. cg@2841: ]. cg@3489: p := p / self previewMagnificationHolder value. cg@2841: self imageEditView scrollToMakeVisible:p. cg@2841: ^ true. cg@2546: ]. cg@2841: ]. cg@2841: cg@2841: anEvent isKeyPressEvent ifTrue:[ cg@2841: focusView := view windowGroup focusView ? view. cg@2841: (focusView isComponentOf:(builder componentAt:#colorDataSetView)) ifTrue:[ cg@2841: anEvent key == #Paste ifTrue:[ cg@2841: self pasteColorIntoColormap. cg@2841: ^ true. cg@2841: ]. cg@2841: anEvent key == #Copy ifTrue:[ cg@2841: self copyColorFromColormap. cg@2841: ^ true. cg@2841: ]. cg@2841: ]. cg@2339: ]. cg@2339: ]. cg@2339: ^ false. cg@2841: cg@3489: "Modified: / 10-09-2017 / 16:40:13 / cg" cg@2339: ! ! cg@2339: tz@672: !ImageEditor methodsFor:'help'! tz@672: cg@3561: constructWindowTitle cg@3561: |resourceClass resourceSelector img| cg@3561: cg@3561: resourceClass := imageEditView resourceClass. cg@3561: resourceClass notNil ifTrue:[ cg@3561: resourceSelector := imageEditView resourceSelector. cg@3561: resourceSelector notNil ifTrue:[ cg@3561: ^ resources cg@3561: string:(self modified cg@3650: ifTrue:['ImageEditor (modified): %1 » %2'] cg@3650: ifFalse:['ImageEditor: %1 » %2']) cg@3561: with:resourceClass name cg@3561: with:resourceSelector cg@3561: ]. cg@3561: ]. cg@3561: cg@3561: (img := imageEditView image) notNil ifTrue:[ cg@3561: img fileName notNil ifTrue:[ cg@3561: ^ resources cg@3561: string:(self modified cg@3561: ifTrue:['ImageEditor (modified): %1'] cg@3561: ifFalse:['ImageEditor: %1']) cg@3561: with:(img fileName asFilename baseName). cg@3561: ]. cg@3561: ^ resources string:'ImageEditor: some image.' cg@3561: ]. cg@3561: ^ resources string:'ImageEditor: << no image >>.' cg@3561: cg@3561: "Created: / 27-05-2018 / 11:31:20 / Claus Gittinger" cg@3561: ! cg@3561: 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@3465: |resourceClass resourceSelector img| cg@1376: cg@1376: resourceClass := imageEditView resourceClass. cg@1965: resourceClass notNil ifTrue:[ cg@1969: resourceSelector := imageEditView resourceSelector. cg@1966: resourceSelector notNil ifTrue:[ cg@3469: ^ resources cg@3469: string:(self modified cg@3650: ifTrue:['Image (modified) from: %1 » %2'] cg@3650: ifFalse:['Image from: %1 » %2']) cg@3469: with:resourceClass name cg@3469: with:resourceSelector cg@1966: ]. tz@672: ]. cg@3465: cg@3465: (img := imageEditView image) notNil ifTrue:[ cg@3465: img fileName notNil ifTrue:[ cg@3469: ^ resources cg@3469: string:(self modified cg@3469: ifTrue:['Image (modified) from: %1'] cg@3469: ifFalse:['Image from: %1']) cg@3469: with:(img fileName asFilename baseName). cg@3465: ]. cg@3465: ]. cg@3380: ^ resources string:'No class and selector defined.' cg@3465: cg@3469: "Modified: / 29-08-2017 / 19:47:25 / cg" tz@674: ! tz@674: tz@702: openDocumentation tz@767: "opens the documentation file of the Image Editor" tz@674: tz@763: self openHTMLDocument: 'tools/uipainter/ImageEditor.html' tz@763: tz@672: ! ! tz@672: tz@767: !ImageEditor methodsFor:'loading'! tz@767: cg@1975: loadFromClass:aClass andSelector:aSelector cg@1975: "loads an image from the method specified by class and selector" cg@1975: cg@1975: self assert:(aClass isNil or:[aClass isClass]). cg@1975: cg@2932: (aClass isNil or:[aSelector isNil]) ifTrue:[ cg@1975: imageEditView resourceClass:aClass. cg@1975: imageEditView resourceSelector:aSelector. cg@1969: imageEditView image:nil. cg@2006: self clearModified. cg@1966: ^ self. cg@1966: ]. cg@1966: cg@1975: (imageEditView loadFromClass:aClass andSelector:aSelector) notNil ifTrue:[ cg@1966: self updateAfterImageChange. cg@2006: self clearModified. cg@1966: ] cg@1975: cg@3405: "Modified: / 16-03-1999 / 21:44:41 / cg" cg@3405: "Modified (comment): / 16-02-2017 / 10:22:51 / 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@3405: cg@3405: "Modified: / 16-03-1999 / 21:43:56 / cg" cg@3405: "Modified (comment): / 16-02-2017 / 10:21:47 / cg" tz@767: ! tz@767: cg@1975: loadFromOrPrepareForClass: aClass andSelector: aSelector tz@767: "loads an image by evaluating aMessage; tz@767: if no image could extract from aMessage; do set the class and the selector from tz@767: the aMessage for a saving at the end of editing" tz@767: cg@1975: (imageEditView loadFromClass:aClass andSelector:aSelector) notNil ifTrue: [ cg@1900: self updateColorsFromImage:self image. tz@767: self findColorMapMode. cg@1376: ] ifFalse: [ cg@1975: imageEditView resourceClass: aClass. cg@1975: imageEditView resourceSelector:aSelector. tz@767: ]. tz@767: self updateLabelsAndHistory. cg@1057: cg@1057: "Modified: / 16.3.1999 / 21:45:07 / cg" tz@767: ! ! tz@767: cg@3404: !ImageEditor methodsFor:'menu aspects'! cg@3404: cg@3404: canDrawCirclesHolder cg@3404: ^ self imageIsLoadedAndNotReadonlyHolder cg@3404: cg@3404: "Created: / 16-02-2017 / 01:41:31 / cg" cg@3404: ! cg@3404: cg@3404: canDrawPointsHolder cg@3404: ^ self imageIsLoadedAndNotReadonlyHolder cg@3404: cg@3404: "Created: / 16-02-2017 / 01:39:37 / cg" cg@3404: ! cg@3404: cg@3404: canDrawRectsHolder cg@3404: ^ self imageIsLoadedAndNotReadonlyHolder cg@3404: cg@3404: "Created: / 16-02-2017 / 01:40:17 / cg" cg@3404: ! cg@3404: cg@3435: canFillCircleHolder cg@3435: ^ self imageIsLoadedAndNotReadonlyHolder cg@3435: cg@3435: "Created: / 10-04-2017 / 08:46:00 / cg" cg@3435: ! cg@3435: cg@3404: canFillRectsHolder cg@3404: ^ self imageIsLoadedAndNotReadonlyHolder cg@3404: cg@3404: "Created: / 16-02-2017 / 01:40:21 / cg" cg@3404: ! cg@3404: cg@3404: canFloodFillHolder cg@3404: ^ self imageIsLoadedAndNotReadonlyHolder cg@3404: cg@3404: "Created: / 16-02-2017 / 01:41:33 / cg" cg@3404: ! cg@3404: cg@3404: canSprayHolder cg@3404: ^ self imageIsLoadedAndNotReadonlyHolder cg@3404: cg@3404: "Created: / 16-02-2017 / 01:44:47 / cg" cg@3405: ! cg@3405: cg@3475: colorMapMenuHolder cg@3475: ^ [ self class colorMapMenu ] cg@3475: cg@3475: "Created: / 31-08-2017 / 18:47:17 / cg" cg@3475: ! cg@3475: cg@3413: imageIsLoadedAndAllowedToChangeImageDimension cg@3413: "returns whether an image is loaded as value holder" cg@3413: cg@3413: ^ [ cg@3413: self imageIsLoadedHolder value cg@3413: and:[ self allowedToChangeImageDimension ] cg@3413: ] cg@3413: cg@3413: "Created: / 16-02-2017 / 01:58:41 / cg" cg@3413: ! cg@3413: cg@3413: imageIsLoadedAndAllowedToChangeImageDimensionAndDepth cg@3413: "returns whether an image is loaded as value holder" cg@3413: cg@3413: ^ [ cg@3413: self imageIsLoadedHolder value cg@3413: and:[ self allowedToChangeImageDimensionAndDepth ] cg@3413: ] cg@3413: cg@3413: "Modified: / 04-07-2010 / 10:15:43 / cg" cg@3413: ! cg@3413: cg@3405: imageIsLoadedAndAllowedToFlipHolder cg@3405: ^ self imageIsLoadedAndNotReadonlyHolder cg@3405: cg@3405: "Created: / 16-02-2017 / 01:57:02 / cg" cg@3413: ! cg@3413: cg@3413: imageIsLoadedAndClassDefined cg@3413: "returns whether an image is loaded as value holder" cg@3413: cg@3413: ^ [self hasClassAndSelectorDefinedHolder value cg@3413: and:[self imageIsLoadedHolder value]] cg@3413: cg@3413: "Created: / 31-07-1998 / 02:04:18 / cg" cg@3413: "Modified: / 04-07-2010 / 10:15:48 / cg" cg@3413: ! cg@3413: cg@3413: imageIsLoadedAndNotReadonlyHolder cg@3413: "returns whether an image is loaded and editable as value holder" cg@3413: cg@3413: ^ BlockValue cg@3413: with:[:loaded | loaded and:[ self readOnly not ]] cg@3413: argument:(self imageIsLoadedHolder) cg@3413: cg@3413: "Modified: / 16-02-2017 / 12:11:31 / cg" cg@3413: ! cg@3413: cg@3413: imageIsLoadedHolder cg@3413: "returns whether an image is loaded as value holder" cg@3413: cg@3650: ^ builder booleanValueAspectFor:#imageIsLoadedHolder cg@3413: cg@3413: "Created: / 04-07-2010 / 10:15:38 / cg" cg@3650: "Modified: / 09-03-2019 / 21:11:20 / Claus Gittinger" cg@3404: ! ! cg@3404: cg@3374: !ImageEditor methodsFor:'menu item visibility'! cg@3374: cg@3374: isNotStandAloneAndMethodSaveAndLoadMenuItemsVisible cg@3374: ^ self isNotStandAlone and:[ self methodSaveAndLoadMenuItemsVisible ] cg@3374: ! cg@3374: cg@3374: isStandAloneAndMethodSaveAndLoadMenuItemsVisible cg@3374: ^ self isStandAlone and:[ self methodSaveAndLoadMenuItemsVisible ] cg@3374: ! cg@3374: cg@3374: methodSaveAndLoadMenuItemsVisible cg@3374: ^ true cg@3374: ! cg@3374: cg@3374: modeMenuVisible cg@3374: ^ true cg@3374: ! ! cg@3374: tz@400: !ImageEditor methodsFor:'menu modes'! tz@400: tz@975: colorMapMode cg@1847: "returns the colorMapMode" tz@400: tz@975: colorMapMode isNil ifTrue: [colorMapMode := '' asValue]. tz@400: tz@975: ^colorMapMode tz@400: ! tz@400: tz@975: editMode tz@975: "returns editMode" tz@400: cg@1054: editMode isNil ifTrue: [ tz@975: editMode := #point asValue. cg@1329: editMode onChangeEvaluate:[imageEditView editMode:(editMode value)] tz@975: ]. tz@975: tz@975: ^editMode tz@400: ! tz@400: tz@975: mouseKeyColorMode tz@975: "returns mouseKeyColorMode" tz@400: cg@1345: mouseKeyColorMode isNil ifTrue:[ tz@975: mouseKeyColorMode := 1 asValue. cg@1345: mouseKeyColorMode onChangeEvaluate: [ cg@1345: imageEditView mouseKeyColorMode:mouseKeyColorMode value. cg@3195: self selectedColors value:{ self listOfColors indexOf:imageEditView selectedColor }. cg@1345: ] ca@956: ]. tz@400: tz@975: ^mouseKeyColorMode cg@1345: cg@1345: "Modified: / 10.2.2000 / 23:16:42 / cg" tz@400: ! ! tz@400: cg@1558: !ImageEditor methodsFor:'private'! cg@1558: cg@3460: askForDepthThenDo:aBlock cg@3460: |oldDepth suggestion depth| cg@3460: cg@3460: oldDepth := self image depth. cg@3471: cg@3471: suggestion := LastDepth notNil ifTrue:[ cg@3471: LastDepth cg@3471: ] ifFalse:[ cg@3471: oldDepth > 8 cg@3471: ifTrue:[8] cg@3471: ifFalse:[(oldDepth // 2 - 1) nextPowerOf2] cg@3471: ]. cg@3460: cg@3460: depth := Dialog request:'New depth ?' initialAnswer:suggestion asString. cg@3460: depth isEmptyOrNil ifTrue:[^ self]. cg@3460: cg@3460: depth := Number readFrom:depth onError:nil. cg@3460: depth isNil ifTrue:[^ self]. cg@3460: cg@3471: LastDepth := depth. cg@3460: aBlock value:depth cg@3460: cg@3460: "Created: / 24-08-2017 / 17:05:39 / cg" cg@3471: "Modified: / 30-08-2017 / 01:22:36 / cg" cg@3460: ! cg@3460: 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@3379: clearModifiedAndRememberImageSaved cg@3379: "called after a save-to-xxx operation" cg@3375: cg@3375: self clearModified. cg@3375: savedImage := self image. cg@3375: ! cg@3375: cg@3379: clearModifiedAndRememberImageSavedAsFile:file cg@3379: "called after a save-to-file operation" cg@3379: cg@3379: self clearModifiedAndRememberImageSaved. cg@3379: savedFile := file. cg@3379: ! cg@3379: cg@1960: pointFromString:aString cg@1960: |p s x y| cg@1960: cg@1960: p := Object readFromString:aString onError:nil. cg@1962: p isPoint ifTrue:[^ p]. cg@1960: cg@1960: s := aString readStream. cg@1960: x := Number readFrom:s onError:nil. cg@1960: x notNil ifTrue:[ cg@1960: s skipSeparators. cg@1962: [s atEnd not and:[s peek isDigit not]] whileTrue:[s next]. cg@1960: y := Number readFrom:s onError:nil. cg@1961: ^ x @ (y ? x) cg@1960: ]. cg@1962: ^ nil cg@1960: ! cg@1960: cg@1939: sortBlockForColors cg@3195: ^ self sortBlockForColorsByHLS. cg@3195: "/ ^ self sortBlockForColorsByRGB cg@3195: ! cg@3195: cg@3195: sortBlockForColorsByHLS cg@3195: ^ [:a :b | cg@3195: |h1 h2 s1 s2 l1 l2| cg@3195: cg@3195: h1 := a hue ? 0. cg@3195: h2 := b hue ? 0. cg@3195: (h1 between: h2-30 and:h2+30) ifTrue:[ cg@3195: l1 := a light. cg@3195: l2 := b light. cg@3195: l1 = l2 ifTrue:[ cg@3195: a saturation < b saturation cg@3195: ] ifFalse:[ cg@3195: l1 < l2 cg@3195: ]. cg@3195: "/ s1 := a saturation. cg@3195: "/ s2 := b saturation. cg@3195: "/ s1 = s2 ifTrue:[ cg@3195: "/ a light < b light cg@3195: "/ ] ifFalse:[ cg@3195: "/ s1 < s2 cg@3195: "/ ] cg@3195: ] ifFalse:[ cg@3195: h1 < h2 cg@3195: ] cg@3195: ] cg@3195: ! cg@3195: cg@3195: sortBlockForColorsByRGB cg@1939: ^ [:a :b | cg@1939: a redByte == b redByte ifTrue:[ cg@1939: a greenByte == b greenByte ifTrue:[ cg@1939: a blueByte < b blueByte cg@1939: ] ifFalse:[ cg@1939: a greenByte < b greenByte cg@1939: ] cg@1939: ] ifFalse:[ cg@1939: a redByte < b redByte cg@1939: ] cg@1939: ] cg@1939: ! cg@1939: cg@1598: updateImage cg@1598: |img| cg@1598: cg@1598: img := imageEditView image. cg@1598: imageEditView image:img. cg@1598: self fetchImageData. cg@3405: self imageIsLoadedHolder changed. cg@3405: cg@3405: "Modified: / 16-02-2017 / 12:18:08 / cg" cg@1598: ! cg@1598: cg@1558: updateImagePreView cg@1558: self tileModeHolder value ifTrue:[ cg@1558: self imagePreView tileMode:true tileOffset:(self image extent). cg@1923: ]. cg@3253: self imagePreView cg@3253: setImage:(self image) scroll:false invalidate:false; "/ true. cg@3253: invalidate. cg@1558: ! ! cg@1558: tz@535: !ImageEditor methodsFor:'queries'! tz@535: cg@3487: hasAlphaChannel cg@3487: |img| cg@3487: cg@3487: img := self image. cg@3487: img isNil ifTrue:[^ false]. cg@3487: ^ img hasAlphaChannel cg@3487: cg@3487: "Created: / 05-09-2017 / 08:29:23 / cg" cg@3487: ! cg@3487: cg@2707: hasLastGrabScreenArea cg@2707: ^ [ lastGrabbedScreenArea notNil ] cg@2707: ! cg@2707: cg@960: hasMask cg@3487: |img| cg@3487: cg@3487: img := self image. cg@3487: img isNil ifTrue:[^ false]. cg@3487: img mask isNil ifTrue:[^ false]. cg@1847: ^ colorMapMode value notNil and:[colorMapMode value startsWith:'mask'] cg@960: cg@3411: "Created: / 18-08-1998 / 17:17:38 / cg" cg@3487: "Modified: / 05-09-2017 / 08:28:44 / cg" cg@3411: ! cg@3411: cg@3411: hasMaskHolder cg@3411: ^ [ self hasMask ] cg@3411: cg@3411: "Created: / 18-02-2017 / 00:41:19 / cg" cg@960: ! cg@960: cg@3487: hasTransparentColorInColorList cg@3487: ^ self hasMask or:[self hasAlphaChannel] cg@3487: cg@3487: "Created: / 05-09-2017 / 09:03:24 / cg" cg@3487: ! cg@3487: cg@1975: modified cg@3416: "true if the image was modified" cg@3416: cg@1975: ^ imageEditView modified cg@3416: cg@3416: "Modified (comment): / 20-02-2017 / 16:23:32 / cg" 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: cg@3443: ^ super preferredExtent max: ((Screen current width//3)@(Screen current height//3.5)) cg@3443: cg@3443: "Modified (format): / 13-04-2017 / 09:52:25 / cg" 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@3393: 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@3409: imageEditView selectedColor:clr. cg@1054: imageEditView selectedColorIndex:pixel. cg@3409: cg@3409: "Modified: / 17-02-2017 / 16:29:09 / cg" tz@400: ! ! tz@400: cg@1716: !ImageEditor methodsFor:'startup & release'! tz@400: cg@1640: closeDownViews cg@1644: builder notNil ifTrue:[ cg@1644: DefaultRelativeSizes := cg@1644: Array cg@1998: with:(builder componentAt:#mainPanel) relativeCorners cg@1644: with:(builder componentAt:#verticalPanel) relativeCorners. cg@1644: ]. cg@1640: super closeDownViews cg@1640: ! cg@1640: tz@400: closeRequest cg@2016: "asks for permission before closing" cg@2016: cg@2016: imageEditView checkModified ifTrue:[ cg@2016: super closeRequest cg@2016: ] tz@400: ! tz@400: cg@1980: commonPostBuild cg@1975: imageEditView undoImages addDependent:self. cg@1975: imageEditView imageInfoHolder:(self imageInfoHolder). cg@1975: imageEditView activityInfoHolder:(self activityInfoHolder). cg@1975: cg@1975: imageEditView clickInfoCallBack:[:button :point | cg@1975: |mouseButtonColorToolBar| cg@3170: button <= 2 ifTrue:[ cg@3170: mouseButtonColorToolBar := self componentAt:#MouseButtonColorToolBar. cg@3170: (mouseButtonColorToolBar itemAt:button) toggleIndication. cg@3170: mouseButtonColorToolBar do: [:i| i updateIndicators]. cg@3170: ]. cg@1975: ]. cg@1975: cg@1975: imageEditView addDependent:self. cg@1975: imageEditView modifiedHolder addDependent:self. cg@1975: cg@1640: DefaultRelativeSizes notNil ifTrue:[ cg@1998: (builder componentAt:#mainPanel) relativeCorners:DefaultRelativeSizes first. cg@1980: (builder componentAt:#verticalPanel) relativeCorners:DefaultRelativeSizes second. cg@1640: ]. cg@1995: cg@1996: "/ using masters infoHolder ? sv@3543: self useAlienInfoLabel ifTrue:[ cg@1998: (builder componentAt:#mainPanel) layout bottomOffset:0. cg@1995: (builder componentAt:#infoBarSubSpec) beInvisible cg@1995: ] sv@3535: sv@3535: "Modified: / 20-02-2018 / 13:05:30 / stefan" cg@1640: ! cg@1640: cg@1980: open cg@3487: "after opening, gets the imageEditView" cg@1980: cg@1980: super open. cg@1980: cg@1980: imageEditView := (self componentAt: #imageEditView) subViews first. cg@3487: cg@3487: "Modified (comment): / 05-09-2017 / 10:39:45 / cg" 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. cg@3415: self colorCropTabSelectionIndexChanged. cg@3415: cg@3421: self drawingColor1Holder valueHolder:(imageEditView drawingColorHolders at:1). cg@3421: self drawingColor2Holder valueHolder:(imageEditView drawingColorHolders at:2). cg@3487: imageEditView drawingAlpha:(self alphaHolder value). cg@3561: self updateAfterImageChange. cg@3487: cg@3487: "Modified (format): / 05-09-2017 / 10:40:10 / cg" cg@3561: "Modified: / 27-05-2018 / 11:20:57 / Claus Gittinger" tz@400: ! ! tz@400: cg@1715: !ImageEditor methodsFor:'user actions-colormap'! cg@919: cg@1053: addColorToColormap cg@3476: "undoable: add black (a new color) to the map" cg@3476: cg@3476: self addColorToColormap:(Color black) undoable:true cg@3476: cg@3476: "Modified: / 31-08-2017 / 14:30:32 / cg" cg@1682: ! cg@1682: cg@1682: addColorToColormap:newColor cg@3476: "undoable cg@3476: when editing a palette image, the new color is added to the image's colorMap cg@3405: (unless it is full). cg@3476: When editing a true-color image, it is added to my own list-of-colors, cg@3405: which only holds drawing colors, but is not the colormap's image" cg@3405: 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@3393: (cMap isNil or:[cMap isMappedPalette or:[cMap isFixedPalette]]) ifTrue:[ cg@1643: drawingColormap isNil ifTrue:[ cg@1916: self information:(resources stringWithCRs:'Image has no colormap.\The shown colorMap is for drawing only.'). cg@1643: drawingColormap := OrderedCollection new. cg@1643: ]. cg@1682: drawingColormap add:newColor. cg@1643: self listOfColors contents:drawingColormap. cg@3195: self selectedColors value:{drawingColormap size}. cg@1643: "/ self warn:'Image has no colormap.\Change colorMap mode first.' withCRs. cg@1054: ^ self cg@1054: ]. cg@1054: cg@3405: (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@3405: width:(img width) height:(img height) depth:depth cg@1054: fromArray:img bits. cg@1054: cg@1054: newImage colorMap:newColorMap. cg@1054: newImage fileName:img fileName. cg@1054: newImage mask:(img mask copy). cg@1054: cg@1054: (imageEditView image:newImage) notNil ifTrue:[ cg@1643: listOfColors contents: newImage colorMap. cg@1054: self findColorMapMode. cg@1054: "/ mhmh - somehow, we get two colors added ... (sigh findColorMapMode adds another one ...) cg@1643: listOfColors size > (oldCListSize + 1) ifTrue:[ cg@1643: listOfColors removeLast cg@1054: ]. cg@3195: self selectedColors value:{listOfColors size}. cg@1054: self updateLabelsAndHistory. cg@1054: ] cg@1053: cg@3393: "Created: / 12-03-1999 / 00:20:28 / cg" cg@3405: "Modified: / 16-02-2017 / 10:17:25 / cg" cg@3476: "Modified (comment): / 31-08-2017 / 14:28:11 / cg" cg@3476: ! cg@3476: cg@3476: addColorToColormap:newColor undoable:undoable cg@3476: "when editing a palette image, the new color is added to the image's colorMap cg@3476: (unless it is full). cg@3476: When editing a true-color image, it is added to my own list-of-colors, cg@3476: which only holds drawing colors, but is not the colormap's image" cg@3476: cg@3476: |depth img cMap newColorMap newImage oldCListSize newMode listOfColors| cg@3476: cg@3476: img := self image. cg@3476: img isNil ifTrue:[ cg@3476: self warn:'No Image.'. cg@3476: ^ self cg@3476: ]. cg@3476: cg@3476: depth := img depth. cg@3476: cMap := img colorMap. cg@3496: cg@3496: (cMap notNil and:[cMap isMappedPalette or:[cMap isArray]]) ifTrue:[ cg@3496: ] ifFalse:[ cg@3496: (cMap isNil or:[cMap isFixedPalette]) ifTrue:[ cg@3496: drawingColormap isNil ifTrue:[ cg@3496: self information:(resources stringWithCRs:'Image has no colormap.\The shown colorMap is for drawing only.'). cg@3496: drawingColormap := OrderedCollection new. cg@3496: ]. cg@3496: drawingColormap add:newColor. cg@3496: self listOfColors contents:drawingColormap. cg@3496: self selectedColors value:{drawingColormap size}. cg@3496: "/ self warn:'Image has no colormap.\Change colorMap mode first.' withCRs. cg@3496: ^ self cg@3476: ]. cg@3496: ]. cg@3496: cg@3476: (cMap size == (1 bitShift:depth)) ifTrue:[ cg@3476: depth >= 8 ifTrue:[ cg@3476: self warn:'No space for more colors in colormap.'. cg@3476: ^ self cg@3476: ]. cg@3476: (self confirm:(resources stringWithCRs:'No space for more colors in colormap.\Change depth ?')) cg@3476: ifFalse:[ cg@3476: ^ self cg@3476: ]. cg@3476: cg@3476: undoable ifTrue:[ imageEditView makeUndo ]. cg@3476: img mask notNil ifTrue:[ cg@3476: newMode := 'masked' , (depth*2) printString. cg@3476: ] ifFalse:[ cg@3476: newMode := 'depth' , (depth*2) printString. cg@3476: ]. cg@3476: self colorMapMode:newMode. cg@3476: ] ifFalse:[ cg@3476: undoable ifTrue:[ imageEditView makeUndo ]. cg@3476: ]. cg@3476: cg@3476: cMap := cMap asArray. cg@3476: listOfColors := self listOfColors. cg@3476: oldCListSize := listOfColors size. cg@3476: cg@3476: newColorMap := cMap copyWith:newColor. cg@3476: cg@3476: newImage := img species new cg@3476: width:(img width) height:(img height) depth:depth cg@3476: fromArray:img bits. cg@3476: cg@3476: newImage colorMap:newColorMap. cg@3476: newImage fileName:img fileName. cg@3476: newImage mask:(img mask copy). cg@3476: cg@3476: (imageEditView image:newImage) notNil ifTrue:[ cg@3476: listOfColors contents: newImage colorMap. cg@3476: self findColorMapMode. cg@3476: "/ mhmh - somehow, we get two colors added ... (sigh findColorMapMode adds another one ...) cg@3476: listOfColors size > (oldCListSize + 1) ifTrue:[ cg@3476: listOfColors removeLast cg@3476: ]. cg@3476: self selectedColors value:{listOfColors size}. cg@3476: self updateLabelsAndHistory. cg@3476: ] cg@3476: cg@3476: "Created: / 31-08-2017 / 14:30:01 / cg" cg@3496: "Modified: / 08-10-2017 / 09:15:10 / cg" cg@3496: ! cg@3496: cg@3496: addPastedColorToColormap cg@3496: "undoable: add the color in the clipboard to the map" cg@3496: cg@3496: |clipBoardColor| cg@3496: cg@3496: (clipBoardColor := self clipBoardColor) isNil ifTrue:[ cg@3496: ^ self cg@3496: ]. cg@3496: self addColorToColormap:clipBoardColor undoable:true cg@3496: cg@3496: "Created: / 08-10-2017 / 09:04:23 / cg" cg@1053: ! cg@1053: cg@1650: changeHLS cg@3468: "interactive Hue/Light/Saturation editing with thumbWheels" cg@1650: cg@3562: |bindings hueShiftHolder lightFactorHolder saturationFactorHolder originalColormap firstChange acceptChannel cg@3468: shiftAction originalAvgColor avgColorHolder avgColor shiftedColor shiftProcess readySema cg@2438: originalPixels p previewImage previewImageHolder originalPreviewColormap originalPreviewPixels cg@2438: anyChange | cg@1652: cg@2438: avgColorHolder := nil asValue. cg@2438: previewImageHolder := nil asValue. cg@2438: cg@3468: "/ cg@3468: "/ compute the averageColor in the background (while building dialog and asking user) cg@3468: "/ 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@2438: cg@2438: previewImage := self image magnifiedPreservingRatioTo:100@100. cg@3468: cg@3468: avgColor := originalAvgColor := previewImage "image" averageColor. cg@3468: avgColorHolder value:avgColor. cg@3468: 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@3562: light:(((clr light * (lFactor)) min:100) max:0) cg@3562: saturation:(((clr saturation * (sFactor)) min:100) max:0)]. 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@3562: hShift := hueShiftHolder value. cg@3562: lFactor := lightFactorHolder value. cg@3562: sFactor := saturationFactorHolder value. cg@1650: cg@3468: avgColorHolder value:(shiftedColor value:originalAvgColor 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@3562: bindings at:#hueShiftHolder put:(hueShiftHolder := 0 asValue). cg@3562: hueShiftHolder onChangeEvaluate:shiftAction. cg@3562: cg@3562: bindings at:#lightFactorHolder put:(lightFactorHolder := 1.0 asValue). cg@3562: lightFactorHolder onChangeEvaluate:shiftAction. cg@3562: cg@3562: bindings at:#saturationFactorHolder put:(saturationFactorHolder := 1.0 asValue). cg@3562: saturationFactorHolder 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@3562: bindings at:#resetHueShift put:[hueShiftHolder value:0]. cg@3562: bindings at:#resetLightFactor put:[lightFactorHolder value:1.0]. cg@3562: bindings at:#resetSaturationFactor put:[saturationFactorHolder value:1.0]. cg@3562: 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@3468: cg@3468: "Modified: / 28-08-2017 / 13:05:35 / cg" cg@3580: "Modified: / 28-07-2018 / 10:35:37 / Claus Gittinger" cg@1649: ! cg@1649: cg@3195: changeHLSOfColors:colorsToShift cg@3195: "interactive Hue/Light/Saturation editing" cg@3195: cg@3195: |bindings hueShift lightValue saturationValue originalColormap firstChange acceptChannel cg@3195: shiftAction avgColorHolder avgColor shiftedColor shiftProcess readySema cg@3195: originalPixels p previewImage previewImageHolder originalPreviewColormap originalPreviewPixels cg@3195: anyChange | cg@3195: cg@3195: avgColorHolder := nil asValue. cg@3195: previewImageHolder := nil asValue. cg@3195: cg@3468: "/ cg@3468: "/ compute the averageColor in the background (while building dialog and asking user) cg@3468: "/ cg@3195: readySema := Semaphore new. cg@3195: [ cg@3195: |image red green blue| cg@3195: cg@3195: image := imageEditView image. cg@3195: originalColormap := image colorMap copy. cg@3195: originalPixels := image bits. cg@3635: colorsToShift size > 0 ifTrue:[ cg@3635: red := (colorsToShift collect:[:clr | clr red]) average. cg@3635: green := (colorsToShift collect:[:clr | clr green]) average. cg@3635: blue := (colorsToShift collect:[:clr | clr blue]) average. cg@3635: avgColor := Color red:red green:green blue:blue. cg@3635: ]. cg@3195: avgColorHolder value:avgColor. cg@3195: cg@3195: previewImage := self image magnifiedPreservingRatioTo:100@100. cg@3195: previewImageHolder value: previewImage. cg@3195: originalPreviewColormap := previewImage colorMap copy. cg@3195: originalPreviewPixels := previewImage bits. cg@3195: cg@3195: readySema signal. cg@3195: ] forkAt:7. cg@3195: cg@3195: acceptChannel := TriggerValue new. cg@3195: cg@3195: firstChange := true. cg@3195: anyChange := false. cg@3195: cg@3195: shiftedColor := [:clr :hShift :lFactor :sFactor | cg@3195: Color cg@3195: hue:((clr hue) ? 0 + hShift) cg@3468: light:((clr light * lFactor) min:100) cg@3468: saturation:((clr saturation * sFactor) min:100)]. cg@3195: cg@3195: shiftAction := cg@3195: [ cg@3195: |hShift lFactor sFactor| cg@3195: cg@3195: acceptChannel value:true. cg@3195: cg@3195: firstChange ifTrue:[ cg@3195: imageEditView makeUndo. cg@3195: firstChange := false. cg@3195: anyChange := true. cg@3195: ]. cg@3195: readySema notNil ifTrue:[readySema wait. readySema := nil]. cg@3195: cg@3195: hShift := hueShift value. cg@3195: lFactor := lightValue value. cg@3195: sFactor := saturationValue value. cg@3195: cg@3195: avgColorHolder value:(shiftedColor value:avgColor value:hShift value:lFactor value:sFactor). cg@3195: cg@3195: previewImage cg@3195: colorMap:originalPreviewColormap copy; cg@3195: bits:originalPreviewPixels copy; cg@3195: release; cg@3195: colorMapProcessing:[:clr | cg@3195: (colorsToShift includes:clr) ifTrue:[ cg@3195: shiftedColor value:clr value:hShift value:lFactor value:sFactor. cg@3195: ] ifFalse:[ cg@3195: clr cg@3195: ] cg@3195: ]. cg@3195: previewImageHolder value:nil; value:previewImage. cg@3195: cg@3195: shiftProcess notNil ifTrue:[ cg@3195: shiftProcess terminate. cg@3195: shiftProcess waitUntilTerminated. cg@3195: shiftProcess := nil. cg@3195: ]. cg@3195: cg@3195: shiftProcess := cg@3195: [ cg@3195: [ cg@3195: imageEditView image cg@3195: colorMap:originalColormap copy; cg@3195: bits:originalPixels copy; cg@3195: release; cg@3195: colorMapProcessing:[:clr | cg@3195: (colorsToShift includes:clr) ifTrue:[ cg@3195: shiftedColor value:clr value:hShift value:lFactor value:sFactor. cg@3195: ] ifFalse:[ cg@3195: clr cg@3195: ] cg@3195: ]. cg@3195: self updateImage. cg@3195: self updateInfoLabel. cg@3195: self updateImagePreView. cg@3195: ] ensure:[ shiftProcess := nil ]. cg@3195: ] forkAt:7. cg@3195: ]. cg@3195: cg@3195: bindings := IdentityDictionary new. cg@3195: bindings at:#hueShiftAmount put:(hueShift := 0 asValue). cg@3195: hueShift onChangeEvaluate:shiftAction. cg@3195: cg@3635: bindings at:#lightAmount put:(lightValue := 1.0 asValue). cg@3195: lightValue onChangeEvaluate:shiftAction. cg@3195: cg@3635: bindings at:#saturationAmount put:(saturationValue := 1.0 asValue). cg@3195: saturationValue onChangeEvaluate:shiftAction. cg@3195: cg@3195: bindings at:#acceptChannel put:acceptChannel. cg@3195: bindings at:#hlsColor put:avgColorHolder. cg@3195: bindings at:#previewImageHolder put:previewImageHolder. cg@3195: cg@3635: bindings at:#resetHueShift put:[ hueShift value: 0 ]. cg@3635: bindings at:#resetLightFactor put:[ lightValue value: 1.0 ]. cg@3635: bindings at:#resetSaturationFactor put:[ saturationValue value: 1.0 ]. cg@3635: cg@3195: (self openDialogInterface:#changeHLSDialogSpec withBindings:bindings) cg@3195: ifFalse:[ cg@3195: anyChange ifTrue:[ cg@3195: imageEditView undo cg@3195: ] cg@3195: ]. cg@3195: cg@3195: (p := shiftProcess) notNil ifTrue:[ cg@3195: p waitUntilTerminated. cg@3195: ]. cg@3195: cg@3195: anyChange ifTrue:[ cg@3195: self updateImage. cg@3195: self updateImagePreView. cg@3195: ]. cg@3468: cg@3468: "Modified (comment): / 28-08-2017 / 13:04:44 / cg" cg@3635: "Modified: / 14-01-2019 / 14:52:50 / Claus Gittinger" cg@3195: ! cg@3195: cg@2652: clearColormapEntry0AndMaskedPixels cg@2652: "ensure that there is a colorMap entry with 0/0/0 at position cg@2652: 0 and then clear all masked pixels (to pixelValue 0). cg@2652: This is required for windows icons to be really transparent" cg@2652: cg@2652: |index colorMap| cg@2652: cg@3476: self nonUndoableCompressColorMap. cg@3476: cg@2652: colorMap := self image colorMap. cg@2652: (colorMap includes:(Color black)) ifFalse:[ cg@3476: self addColorToColormap:(Color black) undoable:false. cg@2652: colorMap := self image colorMap. cg@2652: ]. cg@2652: index := colorMap indexOf:(Color black). cg@2652: index == 1 ifFalse:[ cg@3476: self nonUndoableSortColorMapWith:self sortBlockForColorsByRGB. cg@2652: colorMap := self image colorMap. cg@2652: ]. cg@3476: self nonUndoableClearMaskedPixels cg@3476: cg@3476: "Modified: / 31-08-2017 / 14:30:28 / cg" cg@2652: ! cg@2652: cg@1403: clearMaskedPixels cg@1403: "clear all masked pixels (to pixelValue 0)" cg@1403: cg@2652: |newImage| cg@2652: cg@2652: newImage := self image clearMaskedPixels. cg@2652: 0 to:newImage height - 1 do:[:y | cg@2652: 0 to:newImage width - 1 do:[:x | cg@2652: (newImage maskAtX:x y:y) == 0 ifTrue:[ cg@2652: newImage pixelAtX:x y:y put:0 cg@1460: ] cg@1403: ] cg@2652: ]. cg@2652: cg@2652: (imageEditView image:newImage) notNil ifTrue:[ cg@2652: self fetchImageData. cg@1403: ] cg@1403: ! cg@1403: cg@3496: clipBoardColor cg@3496: "return the color in the clipboard, or nil, if there is none. cg@3496: If there is none, beep (if user's settings allow it)" cg@3496: cg@3496: |clr| cg@3496: cg@3496: clr := imageEditView getClipboardObject. cg@3496: clr isColor ifFalse:[ cg@3526: self beepInEditor. cg@3496: ^ nil cg@3496: ]. cg@3496: ^ clr cg@3496: cg@3496: "Created: / 08-10-2017 / 09:02:14 / cg" cg@3496: ! cg@3496: 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@3405: "calculates a new color map for the image from aMode. cg@3405: This might involve the computation of a colormap cg@3405: (if depth is smaller)" 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@3433: oldImage := self image. cg@3433: cg@3433: "/ rubbish; the mode is already changed cg@3433: "/ prevMode := colorMapMode value. cg@3433: prevMode := self colorMapModeFromImage:oldImage. cg@3433: prevMode == aMode ifTrue:[^ self]. cg@3433: cg@919: self withExecuteCursorDo:[ cg@919: newColorMap := self class listOfColorMaps at:aMode. cg@3230: (aMode == #depth32 or:[aMode == #masked32]) ifTrue:[ cg@2572: depth := 32. cg@2572: ] ifFalse:[ cg@3230: (aMode == #depth24 or:[aMode == #masked24]) ifTrue:[ cg@3230: depth := 24. cg@3230: ] ifFalse:[ cg@3370: (aMode == #depth16 or:[aMode == #masked16]) ifTrue:[ cg@3370: depth := 16. cg@3370: ] ifFalse:[ cg@3370: depth := (newColorMap size log:2) asInteger. cg@3370: ]. cg@3230: ]. cg@2572: ]. cg@919: cg@919: useNearest := false. cg@928: depth == 1 ifTrue:[ cg@928: quest := 'Keep colormap (or use standard B&W)' cg@928: ] ifFalse:[ cg@1008: prevMode isNil ifTrue:[ cg@1008: quest := 'Compute colormap (or use standard)' cg@1008: ] ifFalse:[ cg@1008: quest := 'Keep colormap (or use standard)' cg@1008: ] cg@928: ]. cg@3433: cg@3433: "/ currently always true!! cg@1008: ((prevMode = aMode) cg@3405: or:[depth > oldImage depth cg@3405: or:[true "self confirm:(resources string:quest)"]] cg@3405: ) ifTrue:[ cg@1937: (newColorMap isOrderedCollection or:[newColorMap isFixedPalette not]) ifTrue:[ cg@1935: cg@1935: "/ keep the colormap cg@3355: "/ newColorMap atAllPut:Color black. cg@1935: depth > oldImage depth ifTrue:[ cg@1935: "/ easy - simply copy the part cg@1935: numColors := 1 bitShift:oldImage depth. cg@1935: 0 to:numColors-1 do:[:pixel | cg@1935: newColorMap at:(pixel+1) put:(oldImage colorFromValue:pixel) cg@1008: ]. cg@919: ] ifFalse:[ cg@1935: "/ see if all used color fit the new colormap cg@1935: usedColors := oldImage usedColorsMax:(1 bitShift:depth). cg@1935: (usedColors notNil and:[usedColors size > (1 bitShift:depth)]) ifTrue:[ cg@1935: usedColors := oldImage realUsedColors cg@1935: ]. cg@1935: (usedColors notNil and:[usedColors size <= (1 bitShift:depth)]) ifTrue:[ cg@1935: "/ yea - just install them cg@1935: usedColors asArray keysAndValuesDo:[:idx :clr | cg@1935: newColorMap at:idx put:clr cg@1935: ]. cg@919: ] ifFalse:[ cg@1935: "/ copy over those that are most often used. cg@1935: oldImage depth < 8 ifTrue:[ cg@1935: tmpBits := ByteArray uninitializedNew:(oldImage width*oldImage height). cg@1935: oldImage bits cg@1935: expandPixels:(oldImage depth) cg@1935: width:oldImage width cg@1935: height:oldImage height cg@1935: into:tmpBits cg@1935: mapping:nil. cg@986: ] ifFalse:[ cg@1935: oldImage depth == 8 ifTrue:[ cg@1935: tmpBits := oldImage bits cg@1935: ] ifFalse:[ cg@1935: colorMapMode value:prevMode. cg@1935: self findColorMapMode. cg@3586: self warn:'Too many used colors (%1) in image.\\You should choose one of:\\- convert the image to gray\- reduce the number of colors\- dither to depth\- choose another depth' cg@3586: with: oldImage realUsedColors size. 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@3505: labels:(resources array:#('Cancel' 'First' 'Nearest')). cg@921: useNearest isNil ifTrue:[ cg@1542: colorMapMode value:prevMode. cg@921: ^ self "/ cancel cg@921: ]. cg@921: ]. cg@3356: newColorMap := oldImage colorMap. cg@919: ]. cg@919: cg@919: imageEditView makeUndo. cg@919: cg@2260: newImage := Image newForDepth:depth. cg@1424: newImage depth:depth. cg@3230: depth >= 16 ifTrue:[ cg@3405: newImage colorMap:nil. cg@3230: depth == 32 ifTrue:[ cg@3405: newImage samplesPerPixel:4; photometric:#rgba. cg@3230: ] ifFalse:[ cg@3405: newImage samplesPerPixel:3; photometric:#rgb. cg@3230: ]. cg@3405: ]. cg@3405: "/ newImage photometric:oldImage photometric. cg@2260: cg@919: oldFileName := oldImage fileName. cg@919: cg@1008: Image imageErrorSignal handle:[:ex| cg@3227: "/ arrive here only if not all colors can be represented; cg@3227: "/ then do a more expensive nearest color search cg@1008: Color colorErrorSignal handle:[:ex| cg@1542: colorMapMode value:prevMode. cg@919: imageEditView undo. cg@3586: ^ self warn:('Conversion failed !!') cg@1008: ] do:[ cg@1393: newImage := Image newForDepth:depth. sv@3103: newImage sv@3103: width:oldImage width height:oldImage height depth:depth; sv@3103: colorMap:newColorMap; sv@3103: photometric:#palette; sv@3103: bits:(ByteArray new:(newImage bytesPerRow * newImage height)); sv@3103: mask:oldImage mask. cg@2260: cg@3227: oldImage cg@3227: colorsFromX:0 y:0 cg@3227: toX:(oldImage width-1) y:(oldImage height-1) cg@3227: do:[:x :y :clr | cg@3227: |newColor| cg@3227: cg@3227: (newColorMap includes:clr) cg@3227: ifTrue: [newColor := clr] cg@3227: ifFalse: [ cg@3227: newColor := clr nearestIn:newColorMap. cg@3227: useNearest ifFalse:[ cg@3227: (newColor deltaFrom:clr) > 0.5 ifTrue:[ cg@3227: newColor := oldImage colorFromValue:0 cg@3227: ] cg@1008: ] cg@3227: ]. cg@3227: newImage colorAtX:x y:y put:newColor. cg@3227: ]. cg@3227: cg@919: image := newImage cg@919: ]. cg@1008: ] do:[ cg@3461: |newPhotometric| cg@3461: cg@3461: depth == 32 ifTrue:[ cg@3461: newPhotometric := #rgba. cg@3461: ] ifFalse:[ cg@3461: (newColorMap notNil and:[newColorMap isOrderedCollection or:[newColorMap isFixedPalette not]]) ifTrue:[ cg@3461: newPhotometric := #palette cg@3461: ] cg@3461: ]. cg@3461: image := newImage fromImage:oldImage photometric:newPhotometric. cg@3461: "/ -- nope; keep the newly determined photometric. image photometric:oldImage photometric. cg@919: ]. cg@919: cg@1847: (aMode asString startsWith:'mask') ifTrue:[ cg@1008: image mask isNil ifTrue:[ cg@3436: (oldImage depth == 32 and:[ oldImage photometric == #rgba ]) ifTrue:[ cg@3436: maskImage := ImageMask fromAlphaInImage:oldImage cg@3436: ] ifFalse:[ cg@3436: false "(Dialog confirm:'Generate mask from black ?' default:false)" ifTrue:[ cg@3436: maskThreshold := 0.1. cg@3436: maskImage := Depth1Image fromImage:(image asThresholdMonochromeImage:maskThreshold). cg@3436: ] ifFalse:[ cg@3436: maskImage := ImageMask extent:image extent. cg@3436: maskImage bits:(ByteArray cg@3436: new:(maskImage bytesPerRow * maskImage height) cg@3436: withAll:16rFF). cg@3436: ]. cg@1008: ]. cg@1008: image mask:maskImage. cg@919: ]. cg@1008: ] ifFalse:[ cg@919: image mask: nil. cg@3317: oldImage mask notNil ifTrue:[ cg@3317: newImage depth == 32 ifTrue:[ cg@3317: newImage computeAlphaValuesFromMask:oldImage mask cg@3317: ]. cg@3317: ]. cg@919: ]. cg@1935: cg@1937: (newColorMap isOrderedCollection or:[newColorMap isFixedPalette not]) ifTrue:[ cg@1935: realColorMap := OrderedCollection new. cg@1935: image realColorMap do:[:clr| cg@1935: (realColorMap includes: clr) ifFalse: [realColorMap add: clr] cg@1935: ]. cg@1935: newColors := realColorMap copyFrom: 1 to: (newColorMap size min: realColorMap size). cg@1935: newColorMap do:[:clr| cg@1935: ((newColors size < newColorMap size) and: [(newColors includes: clr) not]) cg@1935: ifTrue:[ cg@1935: newColors add: clr cg@1935: ] cg@1935: ]. cg@1935: image colorMap: newColors. cg@919: ]. cg@1446: image fileName: oldFileName. cg@919: cg@1054: (imageEditView image: image) notNil ifTrue:[ cg@1446: self fetchImageData. cg@919: ] cg@919: ] cg@919: cg@3506: "Modified: / 28-11-2017 / 16:39:03 / cg" cg@3586: "Modified: / 09-08-2018 / 15:59:31 / Claus Gittinger" cg@919: ! cg@919: cg@2192: colorize cg@2192: "interactive Hue editing" cg@2192: cg@2192: |bindings hueShift lightValue saturationValue originalColormap firstChange acceptChannel cg@2192: shiftAction avgColorHolder avgColor shiftedColor shiftProcess readySema cg@2192: originalPixels p| cg@2192: cg@2192: "/ compute the averageColor in the background (while asking user) cg@2192: readySema := Semaphore new. cg@2192: [ cg@2192: |image| cg@2192: cg@2192: image := imageEditView image. cg@2192: originalColormap := image colorMap copy. cg@2192: avgColor := image averageColor. cg@2192: originalPixels := image bits. cg@2192: readySema signal. cg@2192: ] forkAt:7. cg@2192: cg@2192: acceptChannel := TriggerValue new. cg@2192: avgColorHolder := avgColor asValue. cg@2192: cg@2192: firstChange := true. cg@2192: cg@2192: shiftedColor := [:clr :hShift :lFactor :sFactor | cg@2192: Color cg@2192: hue:((clr hue) ? 0 + hShift) cg@3173: light:((clr light * lFactor / 100) min:100) cg@3173: saturation:(((clr saturation max:20) * sFactor / 100) min:100)]. cg@2192: cg@2192: cg@2192: shiftAction := cg@2192: [ cg@2192: |hShift lFactor sFactor| cg@2192: cg@2192: acceptChannel value:true. cg@2192: cg@2192: firstChange ifTrue:[ cg@2192: imageEditView makeUndo. cg@2192: firstChange := false. cg@2192: ]. cg@2192: readySema notNil ifTrue:[readySema wait. readySema := nil]. cg@2192: cg@2192: hShift := hueShift value. cg@2192: lFactor := lightValue value. cg@2192: sFactor := saturationValue value. cg@2192: cg@2192: avgColorHolder value:(shiftedColor value:avgColor value:hShift value:lFactor value:sFactor). cg@2192: cg@2192: shiftProcess notNil ifTrue:[ cg@2192: shiftProcess terminate. cg@2192: shiftProcess waitUntilTerminated. cg@2192: shiftProcess := nil. cg@2192: ]. cg@2192: shiftProcess := cg@2192: [ cg@2192: [ cg@2192: imageEditView image cg@2192: colorMap:originalColormap copy; cg@2192: bits:originalPixels copy; cg@2192: release; cg@2192: colorMapProcessing:[:clr | shiftedColor value:clr value:hShift value:lFactor value:sFactor]. cg@2192: self updateImage. cg@2192: self updateInfoLabel. cg@2192: self updateImagePreView. cg@2192: ] ensure:[ shiftProcess := nil ]. cg@2192: ] forkAt:7. cg@2192: ]. cg@2192: cg@2192: bindings := IdentityDictionary new. cg@2192: bindings at:#hueShiftAmount put:(hueShift := 0 asValue). cg@2192: hueShift onChangeEvaluate:shiftAction. cg@2192: cg@2192: bindings at:#lightAmount put:(lightValue := 100 asValue). cg@2192: lightValue onChangeEvaluate:shiftAction. cg@2192: cg@2192: bindings at:#saturationAmount put:(saturationValue := 100 asValue). cg@2192: saturationValue onChangeEvaluate:shiftAction. cg@2192: cg@2192: bindings at:#acceptChannel put:acceptChannel. cg@2192: bindings at:#hlsColor put:avgColorHolder. cg@2192: cg@2192: (self openDialogInterface:#changeHLSDialogSpec withBindings:bindings) cg@2192: ifFalse:[ cg@2192: firstChange ~~ true ifTrue:[ cg@2192: imageEditView undo cg@2192: ] cg@2192: ]. cg@2192: cg@2192: (p := shiftProcess) notNil ifTrue:[ cg@2192: p waitUntilTerminated. cg@2192: ]. cg@2192: self updateImage. cg@2192: self updateImagePreView. cg@2192: cg@2192: "Created: / 01-11-2007 / 23:27:37 / cg" cg@2192: ! cg@2192: cg@919: compressColorMap cg@919: "calculates a new color map for the image, using only used colors" cg@919: sv@2893: |newImage| sv@2893: sv@2893: newImage := self image. sv@2893: newImage compressColorMap. cg@2652: cg@2652: (imageEditView image:newImage) notNil ifTrue:[ cg@2652: self fetchImageData. cg@919: ] cg@1008: ! cg@1008: cg@1852: copyColorFromColormap ca@1871: imageEditView setClipboardObject:(self selectedColorOrNil) cg@1852: ! cg@1852: cg@2174: doubleClickOnColor:aColorIndex cg@2174: self editSelectedColor. cg@2174: cg@2174: "Created: / 22-07-2007 / 13:14:37 / cg" cg@2174: ! cg@2174: cg@1847: editSelectedColor cg@1847: self processSelectedColorWith:[:clr | cg@1847: |editor| cg@1847: cg@1847: editor := ColorEditDialog new. cg@1847: editor color:clr. cg@1847: editor open. cg@1847: editor accepted ifFalse:[ cg@1847: AbortOperationRequest raise. cg@1847: ]. cg@3180: editor color cg@1847: ] cg@1847: ! cg@1847: cg@1446: fetchImageData cg@1460: |image| cg@1460: cg@1460: (image := imageEditView image) notNil ifTrue:[ cg@1460: self findColorMapMode. cg@1460: self updateLabelsAndHistory. cg@3463: self updateInfoLabel. cg@1460: ] cg@3463: cg@3463: "Modified: / 24-08-2017 / 18:20:37 / cg" cg@1446: ! cg@1446: cg@1544: inspectColor cg@2573: |clrIndex clr| cg@2573: cg@2573: self hasColormap ifFalse:[ cg@2573: clr := self selectedColorOrNil cg@2573: ] ifTrue:[ cg@2573: clrIndex := self selectedColorIndexOrNil. cg@2573: clrIndex isNil ifTrue:[ cg@2573: ^ self cg@2573: ]. cg@2573: clr := self image colorFromValue:clrIndex-1 cg@1544: ]. cg@2573: clr inspect cg@1544: ! cg@1544: cg@2651: inspectColormap cg@2651: self hasColormap ifTrue:[ cg@2651: self image colorMap inspect cg@2651: ]. cg@2651: ! cg@2651: cg@1598: makeBrighter cg@3476: self updateImageAfterDoing:#makeBrighter. cg@3476: cg@3476: "Modified: / 31-08-2017 / 12:16:30 / cg" cg@1598: ! cg@1598: cg@1598: makeDarker cg@3476: self updateImageAfterDoing:#makeDarker. cg@3476: cg@3476: "Modified: / 31-08-2017 / 12:16:24 / cg" cg@1598: ! cg@1598: cg@1926: makeGrayScaleImage cg@3476: self updateImageAfterDoing:#makeGrayScaleImage. cg@3476: cg@3476: "Modified: / 31-08-2017 / 12:16:15 / cg" cg@1436: ! cg@1436: cg@1446: makeSelectedColorBrighter cg@3195: self processSelectedColorsWith:[:clr | clr lightened] cg@1446: ! cg@1446: cg@1446: makeSelectedColorDarker cg@3195: self processSelectedColorsWith:[:clr | clr darkened] cg@1446: ! cg@1446: cg@1884: makeSelectedColorGray cg@3195: self processSelectedColorsWith:[:clr | Color brightness:(clr brightness)] cg@3195: ! cg@3195: cg@3195: makeSelectedColorShifted cg@3476: "shift the selected color (in the colormap) cg@3476: using the hls/rgb shifting slider dialog" cg@3476: cg@3476: |cMap colors cmapOffset| cg@3195: cg@3195: cMap := self image colorMap. cg@3476: cg@3476: "/ if there is a mask, it is at position 1 in the table cg@3487: cmapOffset := self hasTransparentColorInColorList ifTrue:[1] ifFalse:[0]. cg@3635: colors := self selectedColors value cg@3635: select:[:idx | idx > cmapOffset] cg@3635: thenCollect:[:idx | cMap at:idx-cmapOffset]. cg@3195: self changeHLSOfColors:colors. cg@3476: cg@3487: "Modified: / 05-09-2017 / 09:03:47 / cg" cg@3635: "Modified: / 14-01-2019 / 14:46:51 / Claus Gittinger" cg@1884: ! cg@1884: cg@3592: makeSelectedColorSlightlyBrighter cg@3592: self processSelectedColorsWith:[:clr | clr slightlyLightened] cg@3592: ! cg@3592: cg@3592: makeSelectedColorSlightlyDarker cg@3592: self processSelectedColorsWith:[:clr | clr slightlyDarkened] cg@3592: ! cg@3592: cg@2826: makeSlightlyBrighter cg@3476: self updateImageAfterDoing:#makeSlightlyBrighter. cg@2826: cg@2826: "Created: / 24-11-2010 / 11:06:11 / cg" cg@3476: "Modified: / 31-08-2017 / 12:16:01 / cg" cg@2826: ! cg@2826: cg@2826: makeSlightlyDarker cg@3476: self updateImageAfterDoing:#makeSlightlyDarker. cg@2826: cg@2826: "Created: / 24-11-2010 / 11:06:23 / cg" cg@3476: "Modified: / 31-08-2017 / 12:15:55 / cg" cg@2826: ! cg@2826: cg@2652: menu_clearColormapEntry0AndMaskedPixels cg@2652: "ensure that there is a colorMap entry with 0/0/0 at position cg@2652: 0 and then clear all masked pixels (to pixelValue 0)" cg@2652: cg@2652: imageEditView makeUndo. cg@2652: self withExecuteCursorDo:[ cg@3476: self nonUndoableClearColormapEntry0AndMaskedPixels cg@2652: ] cg@3476: cg@3476: "Modified: / 31-08-2017 / 14:31:21 / cg" cg@2652: ! cg@2652: cg@2652: menu_clearMaskedPixels cg@2652: "clear all masked pixels (to pixelValue 0)" cg@2652: cg@2652: imageEditView makeUndo. cg@2652: self withExecuteCursorDo:[ cg@3476: self nonUndoableClearMaskedPixels cg@2652: ] cg@3476: cg@3476: "Modified: / 31-08-2017 / 14:23:20 / cg" cg@2652: ! cg@2652: cg@2652: menu_compressColorMap cg@2652: "calculates a new color map for the image, using only used colors" cg@2652: sv@2893: |depth oldImage usedColors colorMap| cg@2652: cg@2652: oldImage := self image. cg@2652: cg@2652: oldImage photometric ~~ #palette ifTrue:[ cg@2652: self information:'Compress colorMap: Only palette images have colormaps.'. cg@1852: ^ self cg@1852: ]. sv@2893: depth := oldImage depth. sv@3103: colorMap := oldImage colorMap asArray. cg@2652: usedColors := oldImage realUsedColors. sv@2893: usedColors size == colorMap size ifTrue:[ cg@2652: self information:'Compress colorMap: Colormap already compressed - no compression.'. cg@2652: ^ self cg@2652: ]. cg@2652: cg@2652: imageEditView makeUndo. cg@2652: self withExecuteCursorDo:[ cg@3476: self nonUndoableCompressColorMap cg@1852: ] cg@3476: cg@3476: "Modified: / 31-08-2017 / 14:22:19 / cg" cg@1852: ! cg@1852: cg@2652: menu_copyMask cg@2652: |mask| cg@2652: cg@2652: mask := self image mask. cg@2652: MaskClipboard := mask subImageIn: (0@0 extent:mask extent). cg@2652: ! cg@2652: cg@2652: menu_pasteMask cg@3561: "paste a mask from the clipboard" cg@3561: 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@3561: cg@3561: "Modified (comment): / 27-05-2018 / 11:11:54 / Claus Gittinger" cg@1480: ! cg@1480: cg@2652: menu_sortColorMap cg@2652: "calculates a new color map for the image, sorting colors" cg@2652: cg@2652: self menu_sortColorMapWith:self sortBlockForColors cg@2652: ! cg@2652: cg@2652: menu_sortColorMapWith:sortBlock cg@2652: "calculates a new color map for the image, sorting colors" cg@2652: cg@2652: self image photometric ~~ #palette ifTrue:[ cg@2652: self information:'Compress colorMap: Only palette images have colormaps.'. cg@2652: ^ self cg@2652: ]. cg@2652: cg@2652: imageEditView makeUndo. cg@2652: self withExecuteCursorDo:[ cg@3476: self nonUndoableSortColorMapWith:sortBlock cg@2652: ] cg@2652: cg@3476: "Created: / 30-09-1998 / 23:51:23 / cg" cg@3476: "Modified: / 31-08-2017 / 14:20:14 / cg" cg@2652: ! cg@2652: cg@2652: pasteColorIntoColormap cg@3496: |clipBoardColor cmap| cg@3496: cg@3496: (clipBoardColor := self clipBoardColor) isNil ifTrue:[ cg@2652: ^ self cg@2652: ]. cg@2652: cg@3393: cmap := self image colorMap. cg@3393: (cmap isNil or:[cmap isMappedPalette or:[cmap isFixedPalette]]) ifTrue:[ cg@3393: drawingColormap isNil ifTrue:[ cg@3393: drawingColormap := #() cg@3393: ]. cg@3496: drawingColormap := drawingColormap copyWith:clipBoardColor. cg@3393: self selectedColors value:drawingColormap size. cg@3393: ^ self. cg@3393: ]. cg@3393: cg@3496: self processSelectedColorWith:[:clr | clipBoardColor] cg@3496: cg@3496: "Modified (format): / 08-10-2017 / 09:03:59 / cg" cg@2652: ! cg@2652: cg@1682: pickAndAddColorToColormap cg@3476: self addColorToColormap:(Color fromUser) undoable:true cg@3476: cg@3476: "Modified: / 31-08-2017 / 14:30:22 / cg" cg@1682: ! cg@1682: cg@1933: pickAndPasteColor cg@1933: self pickColor. cg@1933: self pasteColorIntoColormap. cg@1933: ! cg@1933: cg@1852: pickColor ca@1871: imageEditView setClipboardObject:(Color fromUser) cg@1852: ! cg@1852: cg@1682: processSelectedColorWith:aBlock cg@3195: "undoable color processing: cg@3195: the selected color will be replaced by the value of aBlock" cg@3195: cg@3195: self processSelectedColorsWith:aBlock. cg@3195: ! cg@3195: cg@3195: processSelectedColorsWith:aBlock mawalch@3546: "undoable color processing: mawalch@3546: the selected colors will be replaced by the value of aBlock cg@3195: (which gets a color vector and must return a color vector)" cg@3195: mawalch@3546: |img cMap modifiedColormap oldColors newImage selectedColorIndices newColors maskOffset processingSubset| cg@3195: cg@3195: selectedColorIndices := self selectedColors value. cg@3195: selectedColorIndices isEmptyOrNil ifTrue:[^ self]. cg@1682: cg@1682: img := self image. cg@3487: self hasTransparentColorInColorList ifTrue:[ sv@3281: maskOffset := 1. cg@3195: ] ifFalse:[ sv@3281: maskOffset := 0. cg@3195: ]. cg@3393: cMap := img colorMap. cg@3418: (cMap isNil) ifTrue:[ mawalch@3546: oldColors := drawingColormap. mawalch@3546: processingSubset := false. mawalch@3546: ] ifFalse:[ cg@3561: ("cMap isMappedPalette or:["cMap isFixedPalette"]") ifTrue:[ mawalch@3546: oldColors := cMap asArray. mawalch@3546: processingSubset := false. mawalch@3546: ] ifFalse:[ cg@3635: selectedColorIndices := selectedColorIndices select:[:idx | idx > maskOffset]. cg@3635: selectedColorIndices isEmpty ifTrue:[ cg@3635: Dialog warn:'Please select any non-mask color'. cg@3635: ^ self. cg@3635: ]. cg@3418: oldColors := selectedColorIndices collect:[:idx | cMap at:idx-maskOffset]. mawalch@3546: processingSubset := true. cg@3418: ]. cg@3393: ]. cg@1682: imageEditView makeUndo. cg@1682: sv@2992: modifiedColormap := cMap asNewArray. cg@3635: (selectedColorIndices max - maskOffset) > modifiedColormap size ifTrue:[ cg@3496: |t| mawalch@3546: t := Array new:(selectedColorIndices max - maskOffset). cg@3496: t replaceFrom:1 with:modifiedColormap. cg@3496: modifiedColormap := t. cg@3496: ]. mawalch@3546: cg@3195: newColors := oldColors collect:aBlock. mawalch@3546: processingSubset ifTrue:[ mawalch@3546: selectedColorIndices with:newColors do:[:idx :newColor | mawalch@3546: modifiedColormap at:idx-maskOffset put:newColor. mawalch@3546: ]. mawalch@3546: ] ifFalse:[ mawalch@3546: selectedColorIndices do:[:idx | mawalch@3546: modifiedColormap at:idx-maskOffset put:(newColors at:idx-maskOffset ifAbsent:[self halt.Color black]) mawalch@3546: ]. mawalch@3546: ]. 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@3418: (cMap isNil) ifTrue:[ cg@3393: "/ only a dummy... mawalch@3546: ] ifFalse:[ mawalch@3546: newImage colorMap:modifiedColormap. mawalch@3546: newImage photometric:#palette. cg@3393: ]. cg@1682: newImage fileName:img fileName. cg@1682: newImage mask:(img mask copy). cg@1682: cg@1682: (imageEditView image:newImage) notNil ifTrue:[ cg@1682: self fetchImageData. cg@1682: ]. cg@3195: self selectedColors value:selectedColorIndices. cg@3393: cg@3496: "Modified: / 08-10-2017 / 09:20:13 / cg" cg@3635: "Modified: / 14-01-2019 / 14:56:49 / Claus Gittinger" cg@1682: ! cg@1682: cg@1124: reduceNumberOfColors cg@3464: "reduce by masking off r/g/b bits" cg@3464: cg@1727: |s n anyChange img usedColors| cg@1124: cg@2817: s := Dialog request:'Number of color bits to strip (1-7) ?' initialAnswer:3. cg@1435: s size == 0 ifTrue:[^ self]. cg@1934: cg@1124: n := Integer readFrom:s onError:0. cg@1124: (n between:1 and:7) ifFalse:[ cg@1124: Dialog warn:'Image unchanged'. cg@1124: ^ self cg@1124: ]. cg@1124: cg@1124: self withExecuteCursorDo:[ cg@1124: anyChange := imageEditView reduceColorResolutionBy:n. cg@1124: anyChange ifFalse:[ cg@1124: Dialog warn:'Image unchanged'. cg@1124: ] ifTrue:[ cg@1124: img := imageEditView image. cg@1124: imageEditView image:img. cg@1446: cg@1446: self fetchImageData. cg@1727: usedColors := img usedColorsMax:10000. cg@1727: usedColors size == 10000 ifTrue:[ cg@1727: Dialog information:('>= ' , usedColors size printString , ' colors used.') cg@1727: ] ifFalse:[ cg@1727: Dialog information:(usedColors size printString , ' colors used.') cg@1727: ] cg@1124: ] cg@1124: ]. cg@2817: cg@2817: "Modified: / 29-10-2010 / 18:08:01 / cg" cg@3464: "Modified (comment): / 24-08-2017 / 20:50:28 / cg" cg@1124: ! cg@1124: cg@1930: reduceNumberOfColors2 cg@3464: "reduce by rounding r/g/b channel values" cg@3464: 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@3463: |reduceColor nUsed| cg@3195: cg@3195: reduceColor := cg@3195: [:clr | cg@3195: |r g b nr ng nb| cg@1934: cg@1934: r := clr redByte. cg@1934: g := clr greenByte. cg@1934: b := clr blueByte. cg@1938: nr := (r roundTo:rndR) min:255. cg@1938: ng := (g roundTo:rndG) min:255. cg@1938: nb := (b roundTo:rndB) min:255. cg@1934: cg@3195: Color redByte:nr greenByte:ng blueByte:nb. cg@3195: ]. cg@3195: cg@3195: image := self image. cg@3195: "/ usedColors := image usedColorsMax:4096. cg@3195: imageEditView makeUndo. cg@3195: cg@3195: newImage := image copy. cg@3195: newImage photometric == #palette ifTrue:[ cg@3195: newImage colorMap:(image colorMap collect:reduceColor). cg@3195: ] ifFalse:[ cg@3195: image cg@3195: colorsFromX:0 y:0 toX:(image width-1) y:(image height-1) cg@3195: do:[:x :y :clr | cg@3195: newImage colorAtX:x y:y put:(reduceColor value:clr) cg@2260: ]. cg@3195: ]. cg@1934: imageEditView image:newImage. cg@1934: imageEditView setModified. cg@1934: self updateImage. cg@1934: self updateImagePreView. cg@1934: cg@1934: self fetchImageData. cg@3463: cg@1934: usedColors := newImage usedColorsMax:10000. cg@3463: nUsed := usedColors size. cg@3463: nUsed == 10000 ifTrue:[ cg@3463: Dialog information:('>= ' , nUsed printString , ' colors used.') cg@1934: ] ifFalse:[ cg@3463: Dialog information:(nUsed printString , ' colors used.') cg@1934: ] cg@1930: ]. cg@2054: cg@3463: "Modified: / 24-08-2017 / 18:25:04 / cg" cg@3464: "Modified (comment): / 24-08-2017 / 20:50:14 / cg" cg@1930: ! cg@1930: cg@2446: selectColor:aColor cg@2446: |idx img cMap| cg@2446: cg@2446: aColor isNil ifTrue:[ cg@2446: idx := nil. cg@2446: ] ifFalse:[ cg@2791: img := self image. cg@2791: img notNil ifTrue: [ cg@2791: aColor == Color noColor ifTrue:[ cg@2791: (img mask notNil) ifTrue:[ cg@2791: idx := 1. cg@2791: ] cg@2791: ] ifFalse:[ cg@2447: (cMap := self listOfColors) notNil ifTrue:[ cg@2446: idx := cMap indexOf:aColor ifAbsent:nil. cg@2447: ]. cg@2447: idx isNil ifTrue:[ cg@2447: "/ should not happen... cg@2447: (cMap := img colorMap) notNil ifTrue:[ cg@2447: idx := cMap indexOf:aColor ifAbsent:nil. cg@2447: idx notNil ifTrue:[ cg@2447: img mask notNil ifTrue:[ cg@2447: idx := idx + 1. cg@2447: ]. cg@2447: ] cg@2446: ]. cg@2447: ]. cg@2446: ]. cg@2446: ]. cg@2446: ]. cg@3195: self selectedColors value:{idx}. cg@2790: cg@2791: "Modified: / 02-07-2010 / 12:06:07 / cg" cg@2446: ! cg@2446: cg@1682: selectedColorIndexOrNil cg@2651: |img clrIndex| cg@1682: cg@1682: img := self image. cg@1682: img isNil ifTrue:[ cg@2764: "/ self warn:'No Image.'. cg@1682: ^ nil cg@1682: ]. cg@1682: clrIndex := self selectionOfColor value. cg@3487: self hasTransparentColorInColorList ifTrue: [ cg@2449: (clrIndex isInteger and:[clrIndex > 1]) ifTrue:[ cg@2449: ^ clrIndex - 1 cg@2449: ]. cg@2449: ^ nil cg@1847: ]. cg@1682: ^ clrIndex cg@3487: cg@3487: "Modified: / 05-09-2017 / 09:04:05 / cg" 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@3476: self nonUndoableSortColorMapWith:self sortBlockForColorsByRGB cg@3476: cg@3476: "Modified: / 31-08-2017 / 14:20:07 / cg" cg@1939: ! cg@1939: cg@1939: sortColorMapWith:sortBlock cg@3476: "warning: not undoable cg@3476: calculates a new color map for the image, sorting colors" cg@3476: cg@3476: |depth newColorMap newImage oldImage usedColors oldToNew oldBits newBits tmpBits cg@3476: expectedSize w h| cg@3476: cg@3476: oldImage := self image. cg@3476: depth := oldImage depth. cg@3476: w := oldImage width. cg@3476: h := oldImage height. cg@3476: cg@3476: usedColors := oldImage realColorMap. cg@3476: cg@3476: "/ translation table cg@3476: oldToNew := ByteArray new:(1 bitShift:depth). cg@3476: newColorMap := usedColors asArray. cg@3476: newColorMap sort:sortBlock. cg@3476: cg@3476: oldImage colorMap asArray keysAndValuesDo:[:oldIdx :clr | cg@3476: |newPixel| cg@3476: cg@3476: (usedColors includes:clr) ifTrue:[ cg@3476: newPixel := newColorMap indexOf:clr. cg@3476: oldToNew at:oldIdx put:newPixel-1. cg@3476: ] cg@3476: ]. cg@3476: cg@3476: oldBits := oldImage bits. cg@3476: "/ sanity check... cg@3476: expectedSize := ((w * h * depth + 7) // 8). cg@3476: (oldBits size < expectedSize) ifTrue:[ cg@3476: self halt:'incorrect pixeldata size'. cg@3476: oldBits := (ByteArray new:expectedSize) replaceFrom:1 with:oldBits; yourself. cg@3476: ]. cg@3476: newBits := ByteArray new:(oldBits size). cg@3476: depth ~~ 8 ifTrue:[ cg@3476: cg@3476: "/ expand/compress can only handle 8bits cg@3476: tmpBits := ByteArray uninitializedNew:(w*h). cg@3476: oldBits cg@3476: expandPixels:depth cg@3476: width:w height:h cg@3476: into:tmpBits cg@3476: mapping:oldToNew. cg@3476: tmpBits cg@3476: compressPixels:depth cg@3476: width:w height:h cg@3476: into:newBits cg@3476: mapping:nil cg@3476: ] ifFalse:[ cg@3476: oldBits cg@3476: expandPixels:depth cg@3476: width:w height:h cg@3476: into:newBits cg@3476: mapping:oldToNew. cg@3476: ]. cg@3476: cg@3476: newImage := oldImage species new cg@3476: width:w height:h depth:depth cg@3476: fromArray:newBits. cg@3476: cg@3476: newImage colorMap:newColorMap. cg@3476: newImage fileName:oldImage fileName. cg@3476: newImage mask:(oldImage mask copy). cg@3476: cg@3476: (imageEditView image:newImage) notNil ifTrue:[ cg@3476: self fetchImageData. cg@3476: ] cg@3476: cg@3476: "Modified: / 15-09-1998 / 17:53:32 / cg" cg@3476: "Created: / 30-09-1998 / 23:51:23 / cg" cg@3476: "Modified (comment): / 31-08-2017 / 14:19:21 / cg" cg@3476: ! cg@3476: cg@3476: updateImageAfterDoing:aBlockOrSelector cg@3476: self withExecuteCursorDo:[ cg@3476: aBlockOrSelector value:imageEditView. cg@3476: self updateImage. cg@3476: ]. cg@3476: cg@3476: "Created: / 31-08-2017 / 12:14:39 / cg" cg@3476: ! ! cg@3476: cg@3476: !ImageEditor methodsFor:'user actions-colormap-basic'! cg@3476: cg@3476: nonUndoableClearColormapEntry0AndMaskedPixels cg@3476: "ensure that there is a colorMap entry with 0/0/0 at position cg@3476: 0 and then clear all masked pixels (to pixelValue 0). cg@3476: This is required for windows icons to be really transparent" cg@3476: cg@3476: |index colorMap| cg@3476: cg@3476: self nonUndoableCompressColorMap. cg@3476: cg@3476: colorMap := self image colorMap. cg@3476: (colorMap includes:(Color black)) ifFalse:[ cg@3476: self addColorToColormap:(Color black) undoable:false. cg@3476: colorMap := self image colorMap. cg@3476: ]. cg@3476: index := colorMap indexOf:(Color black). cg@3476: index == 1 ifFalse:[ cg@3476: self nonUndoableSortColorMapWith:self sortBlockForColorsByRGB. cg@3476: colorMap := self image colorMap. cg@3476: ]. cg@3476: self nonUndoableClearMaskedPixels cg@3476: cg@3476: "Created: / 31-08-2017 / 14:31:09 / cg" cg@3476: ! cg@3476: cg@3476: nonUndoableClearMaskedPixels cg@3476: "clear all masked pixels (to pixelValue 0)" cg@3476: cg@3476: |newImage| cg@3476: cg@3476: newImage := self image clearMaskedPixels. cg@3476: 0 to:newImage height - 1 do:[:y | cg@3476: 0 to:newImage width - 1 do:[:x | cg@3476: (newImage maskAtX:x y:y) == 0 ifTrue:[ cg@3476: newImage pixelAtX:x y:y put:0 cg@3476: ] cg@3476: ] cg@3476: ]. cg@3476: cg@3476: (imageEditView image:newImage) notNil ifTrue:[ cg@3476: self fetchImageData. cg@3476: ] cg@3476: cg@3476: "Created: / 31-08-2017 / 14:22:58 / cg" cg@3476: ! cg@3476: cg@3476: nonUndoableCompressColorMap cg@3476: "not undoable cg@3476: calculates a new color map for the image, using only used colors" cg@3476: cg@3476: |newImage| cg@3476: cg@3476: newImage := self image. cg@3476: newImage compressColorMap. cg@3476: cg@3476: (imageEditView image:newImage) notNil ifTrue:[ cg@3476: self fetchImageData. cg@3476: ] cg@3476: cg@3476: "Created: / 31-08-2017 / 14:21:51 / cg" cg@3476: ! cg@3476: cg@3476: nonUndoableSortColorMapWith:sortBlock cg@3476: "not undoable cg@3476: calculates a new color map for the image, sorting colors" cg@1939: cg@3224: |depth newColorMap newImage oldImage usedColors oldToNew oldBits newBits tmpBits cg@3224: expectedSize w h| cg@1008: cg@1008: oldImage := self image. cg@1008: depth := oldImage depth. cg@3224: w := oldImage width. cg@3224: h := oldImage height. cg@1008: cg@2652: usedColors := oldImage realColorMap. cg@2652: cg@2652: "/ translation table cg@2652: oldToNew := ByteArray new:(1 bitShift:depth). cg@2652: newColorMap := usedColors asArray. cg@2652: newColorMap sort:sortBlock. cg@2652: cg@2652: oldImage colorMap asArray keysAndValuesDo:[:oldIdx :clr | cg@2652: |newPixel| cg@2652: cg@2652: (usedColors includes:clr) ifTrue:[ cg@2652: newPixel := newColorMap indexOf:clr. cg@2652: oldToNew at:oldIdx put:newPixel-1. cg@2652: ] cg@1008: ]. cg@1008: cg@2652: oldBits := oldImage bits. cg@3224: "/ sanity check... cg@3224: expectedSize := ((w * h * depth + 7) // 8). cg@3224: (oldBits size < expectedSize) ifTrue:[ cg@3224: self halt:'incorrect pixeldata size'. cg@3224: oldBits := (ByteArray new:expectedSize) replaceFrom:1 with:oldBits; yourself. cg@3224: ]. cg@2652: newBits := ByteArray new:(oldBits size). cg@2652: depth ~~ 8 ifTrue:[ cg@3224: cg@2652: "/ expand/compress can only handle 8bits cg@3224: tmpBits := ByteArray uninitializedNew:(w*h). cg@2652: oldBits cg@2652: expandPixels:depth cg@3224: width:w height:h cg@2652: into:tmpBits cg@2652: mapping:oldToNew. cg@2652: tmpBits cg@2652: compressPixels:depth cg@3224: width:w height:h cg@2652: into:newBits cg@2652: mapping:nil cg@2652: ] ifFalse:[ cg@2652: oldBits cg@2652: expandPixels:depth cg@3224: width:w height:h cg@2652: into:newBits cg@2652: mapping:oldToNew. cg@2652: ]. cg@2652: cg@2652: newImage := oldImage species new cg@3224: width:w height:h depth:depth cg@2652: fromArray:newBits. cg@2652: cg@2652: newImage colorMap:newColorMap. cg@2652: newImage fileName:oldImage fileName. cg@2652: newImage mask:(oldImage mask copy). cg@2652: cg@2652: (imageEditView image:newImage) notNil ifTrue:[ cg@2652: self fetchImageData. cg@1008: ] cg@1008: cg@3476: "Created: / 31-08-2017 / 14:19:42 / cg" cg@919: ! ! cg@919: cg@1715: !ImageEditor methodsFor:'user actions-editing'! tz@400: cg@3417: autoCropAll cg@3417: "find all borders and cut them off" cg@3417: cg@3417: imageEditView autoCropLeft:true right:true top:true bottom:true. cg@3417: self updateInfoLabel cg@3417: cg@3417: "Created: / 20-02-2017 / 18:05:38 / cg" cg@3417: ! cg@3417: cg@3417: autoCropBottom cg@3417: "find a bottom border and cut it off" cg@3417: cg@3417: imageEditView autoCropLeft:false right:false top:false bottom:true. cg@3417: self updateInfoLabel cg@3417: cg@3417: "Created: / 20-02-2017 / 18:05:45 / cg" cg@3417: ! cg@3417: cg@3417: autoCropLeft cg@3417: "find a left border and cut it off" cg@3417: cg@3417: imageEditView autoCropLeft:true right:false top:false bottom:false. cg@3417: self updateInfoLabel cg@3417: cg@3417: "Created: / 20-02-2017 / 18:05:52 / cg" cg@3417: ! cg@3417: cg@3417: autoCropRight cg@3417: "find a right border and cut it off" cg@3417: cg@3417: imageEditView autoCropLeft:false right:true top:false bottom:false. cg@3417: self updateInfoLabel cg@3417: cg@3417: "Created: / 20-02-2017 / 18:04:20 / cg" cg@3417: ! cg@3417: cg@3417: autoCropTop cg@3417: "find a top border and cut it off" cg@3417: cg@3417: imageEditView autoCropLeft:false right:false top:true bottom:false. cg@3417: self updateInfoLabel cg@3417: cg@3417: "Created: / 20-02-2017 / 18:06:03 / cg" cg@3417: ! cg@3417: cg@3476: ditherGrayToDepth cg@3476: self askForDepthThenDo:[:depth | cg@3476: self ditherGrayToDepth:depth cg@3476: ]. cg@3476: cg@3476: "Created: / 24-08-2017 / 17:49:42 / cg" cg@3476: ! cg@3476: cg@3476: ditherGrayToDepth:depth cg@3476: self withExecuteCursorDo:[ cg@3497: |image newImage| cg@3497: cg@3497: image := self image. cg@3476: depth == 1 ifTrue:[ cg@3497: newImage := image asErrorDitheredMonochromeImage cg@3476: ] ifFalse:[ cg@3497: newImage := image asGrayImageDepth:depth dither:#floydSteinberg. cg@3476: ]. cg@3476: imageEditView newImageWithUndo:newImage. cg@3476: ]. cg@3476: cg@3476: "Created: / 24-08-2017 / 17:51:07 / cg" cg@3497: "Modified: / 23-10-2017 / 10:58:18 / cg" cg@3476: ! cg@3476: cg@3476: ditherToDepth cg@3476: self askForDepthThenDo:[:depth | cg@3476: self convertToDepth:depth dither:true cg@3476: ]. cg@3476: cg@3476: "Created: / 07-07-2006 / 13:22:10 / cg" cg@3476: "Modified: / 30-08-2017 / 00:34:42 / cg" cg@3476: ! cg@3476: cg@3497: ditherToNumberOfGrayColors cg@3497: |oldDepth numGrayColors suggestion grayImage userInput grayColors| cg@3497: cg@3497: oldDepth := self image depth. cg@3497: grayImage := self image asGrayImageDepth:8. cg@3497: cg@3497: suggestion := LastNumThresholdGrayColors notNil ifTrue:[ cg@3497: LastNumThresholdGrayColors cg@3497: ] ifFalse:[ cg@3497: oldDepth > 8 cg@3497: ifTrue:[256] cg@3497: ifFalse:[2 raisedTo:((oldDepth // 2 - 1) nextPowerOf2)] cg@3497: ]. cg@3497: cg@3497: Dialog modifyingBoxWith:[:box | cg@3497: |preview slider update thresholdValue| cg@3497: cg@3497: thresholdValue := suggestion asValue. cg@3497: cg@3497: box enterField cg@3497: converter:(PrintConverter new initForNumber); cg@3497: model:thresholdValue. cg@3497: cg@3497: box verticalPanel extent:1.0 @ 300. cg@3497: cg@3497: box verticalPanel add:(slider := HorizontalSlider new start:2 stop:256 step:1). cg@3497: slider model:thresholdValue. cg@3497: slider width:1.0; leftInset:4; rightInset:4. cg@3497: cg@3497: box verticalPanel add:(preview := ImageView new). cg@3497: preview extent:300 @300. cg@3497: preview level:-1. cg@3497: box verticalPanel horizontalLayout:#fitSpace. cg@3497: cg@3497: update := cg@3497: [ cg@3497: |numGrayColors depth s t tImage| cg@3497: cg@3497: numGrayColors := thresholdValue value clampBetween:2 and:256. cg@3497: grayColors := Color grayColorVector:numGrayColors. cg@3497: tImage := grayImage asDitheredImageUsing:grayColors depth:(grayImage depth). cg@3497: cg@3497: preview image:(tImage magnifiedPreservingRatioTo:preview extent). cg@3497: ]. cg@3497: update value. cg@3497: box enterField acceptOnLostFocus:true. cg@3497: box enterField acceptOnLeave:true. cg@3497: thresholdValue onChangeEvaluate:update. cg@3497: cg@3497: ] do:[ cg@3497: userInput := Dialog request:'Number of Gray Colors ?' initialAnswer:suggestion asString. cg@3497: ]. cg@3497: userInput isEmptyOrNil ifTrue:[^ self]. cg@3497: cg@3497: cg@3497: numGrayColors := Number readFrom:userInput onError:nil. cg@3497: numGrayColors isNil ifTrue:[^ self]. cg@3497: cg@3497: grayColors := Color grayColorVector:numGrayColors. cg@3497: imageEditView newImageWithUndo:(grayImage asDitheredImageUsing:grayColors depth:(grayImage depth)). cg@3497: cg@3497: "Created: / 23-10-2017 / 11:17:44 / cg" cg@3497: ! cg@3497: cg@3476: do3DProjection cg@3476: "make a naive 3D projection; cg@3476: can be used to create those typical marketing images as seen in web pages" cg@3476: cg@3476: |box dx1 dx2 image| cg@3476: cg@3476: image := imageEditView image. cg@3476: cg@3476: box := EnterBox new. cg@3476: box title:(resources string:'dX1 (0 < dx < 0.5):'). cg@3476: box okText:(resources string:'OK'). cg@3476: box abortText:(resources string:'Cancel'). cg@3476: box initialText:'0.1'. cg@3476: box showAtPointer. cg@3476: cg@3476: (box accepted cg@3476: and: [(dx1 := Number readFrom:(box contents) onError:nil) notNil]) cg@3476: ifTrue:[ cg@3476: box title:(resources string:'dX2 (0 < dx < 0.5):'). cg@3476: box initialText:(dx1 printString). cg@3476: box showAtPointer. cg@3476: (box accepted cg@3476: and: [(dx2 := Number readFrom:(box contents) onError:nil) notNil]) cg@3476: ifTrue:[ cg@3476: imageEditView threeDProjection:dx1 and:dx2. cg@3476: ] cg@3476: ]. cg@3476: cg@3476: self updateInfoLabel cg@3476: cg@3476: "Modified (comment): / 31-08-2017 / 13:58:03 / cg" cg@3476: ! cg@3476: cg@3476: doBrightenImage cg@3476: imageEditView brightenImage. cg@3476: self listOfColors removeAll. cg@3476: self findColorMapMode. cg@3476: "/ imageEditView removelastUndo cg@3476: ! cg@3476: cg@3476: doBrowseClass cg@3476: "opens a System Browser on the resourceClass and the resourceSelector" cg@3476: cg@3476: |cls| cg@3476: cg@3476: cls := imageEditView resourceClass. cg@3476: cls isNil ifTrue:[^ self warn:'No Class specified']. cg@3476: cg@3476: cls browserClass cg@3476: openInClass:cls class cg@3476: selector:(imageEditView resourceSelector) cg@3476: cg@3476: "Modified: / 31.7.1998 / 02:01:15 / cg" cg@3476: ! cg@3476: cg@3476: doCopyImageToClipboard cg@3476: imageEditView copyImageToClipboard. cg@3476: ! cg@3476: cg@3476: doCropManual cg@3476: "let user specify borders and cut them off" cg@3476: cg@3476: |bindings left top right bottom img firstChange cropAction acceptChannel| cg@3476: cg@3476: acceptChannel := TriggerValue new. cg@3476: cg@3476: firstChange := true. cg@3476: cg@3476: cropAction := cg@3476: [:lV :rV :tV :bV | |l r t b| cg@3476: acceptChannel value:true. cg@3476: cg@3476: l := lV value. cg@3476: r := rV value. cg@3476: t := tV value. cg@3476: b := bV value. cg@3476: (l + r + t + b) == 0 ifTrue:[ cg@3526: self window beepInEditor cg@3476: ] ifFalse:[ cg@3476: img := imageEditView image. cg@3476: firstChange ifTrue:[ cg@3476: imageEditView makeUndo. cg@3476: firstChange := false. cg@3476: ]. cg@3476: imageEditView cg@3476: makeSubImageX:l y:t cg@3476: width:(img width - l - r) cg@3476: height:(img height - t - b). cg@3476: cg@3476: self updateImagePreView. cg@3476: self updateInfoLabel cg@3476: ]. cg@3476: ]. cg@3476: cg@3476: bindings := IdentityDictionary new. cg@3476: bindings at:#cropLeftAmount put:(left := 1 asValue). cg@3476: bindings at:#cropRightAmount put:(right := 1 asValue). cg@3476: bindings at:#cropTopAmount put:(top := 1 asValue). cg@3476: bindings at:#cropBottomAmount put:(bottom := 1 asValue). cg@3476: bindings at:#acceptChannel put:acceptChannel. cg@3476: cg@3476: bindings at:#cropLeftNow put:[ cropAction value:left value:0 value:0 value:0 ]. cg@3476: bindings at:#cropRightNow put:[ cropAction value:0 value:right value:0 value:0 ]. cg@3476: bindings at:#cropTopNow put:[ cropAction value:0 value:0 value:top value:0 ]. cg@3476: bindings at:#cropBottomNow put:[ cropAction value:0 value:0 value:0 value:bottom ]. cg@3476: cg@3476: bindings at:#applyCropAction put:[ cropAction value:left value:right value:top value:bottom ]. cg@3476: bindings at:#cropBoxIsDialog put:true. cg@3476: cg@3476: (self openDialogInterface:#cropSpec withBindings:bindings) cg@3476: ifFalse:[ cg@3476: firstChange ~~ true ifTrue:[ cg@3476: imageEditView undo. cg@3476: self updateImagePreView. cg@3476: ] cg@3476: ]. cg@3476: cg@3476: "Created: / 07-09-1998 / 18:16:07 / cg" cg@3476: "Modified: / 19-02-2017 / 15:43:50 / cg" cg@3476: ! cg@3476: cg@3476: doDarkenImage cg@3476: imageEditView darkenImage. cg@3476: self listOfColors removeAll. cg@3476: self findColorMapMode. cg@3476: "/ imageEditView removelastUndo cg@3476: ! cg@3476: cg@3476: doEditMask cg@3476: |mask| cg@3476: cg@3476: (mask := self image mask) notNil ifTrue:[ cg@3476: mask edit cg@3476: ]. cg@3476: cg@3476: "Modified: / 18-02-2017 / 00:38:51 / cg" cg@3476: ! cg@3476: cg@3476: doFlipHorizontal cg@3476: "flips horizontally current image" cg@3476: cg@3476: imageEditView flipHorizontal cg@3476: ! cg@3476: cg@3476: doFlipVertical cg@3476: "flips vertically current image" cg@3476: cg@3476: imageEditView flipVertical cg@3476: ! cg@3476: cg@3476: doInsertTextFromUser cg@3476: |text tempForm tempImage maskImage font w h paintColor| cg@3476: cg@3476: text := Dialog request:'Text to be inserted (placed as bitmap into clipboard for paste):'. cg@3476: text isEmptyOrNil ifTrue:[^ self ]. cg@3476: cg@3476: font := Font family:'arial' size:20. cg@3476: font := font onDevice:Screen current. cg@3476: w := font widthOf:text. cg@3476: h := font heightOf:text. cg@3476: cg@3476: tempForm := Form extent:(w@h) depth:1 onDevice:(Screen current). cg@3476: tempForm clear. cg@3476: tempForm font:font. cg@3476: tempForm paint:(Color colorId:1). cg@3476: tempForm displayString:text at:(0@font ascent). cg@3476: cg@3476: tempImage := tempForm asImage. cg@3476: maskImage := tempForm asImage. cg@3476: cg@3476: paintColor := imageEditView selectedColor. cg@3476: paintColor colorId == 0 ifTrue:[ cg@3476: paintColor := Color black cg@3476: ]. cg@3476: tempImage cg@3476: photometric:#palette; cg@3476: colorMap:(Array cg@3476: with:Color white cg@3476: with:paintColor); cg@3476: mask:maskImage. cg@3476: cg@3476: ImageEditView copyImageToClipboard:tempImage. cg@3476: self editMode value:#paste. cg@3476: cg@3476: "Modified: / 11-11-2007 / 12:32:55 / cg" cg@3476: ! cg@3476: cg@3476: doInspectImage cg@3476: "opens a System Browser on the resourceClass and the resourceSelector" cg@3476: cg@3476: self image inspect cg@3476: ! cg@3476: cg@3476: doInvertedBitsImage cg@3476: "inverts the pixels" cg@3476: cg@3476: self withExecuteCursorDo:[ cg@3476: imageEditView makeInvertedBits. cg@3476: self updateImage. cg@3476: ]. cg@3476: "/ cg@3476: "/ imageEditView negativeImage. cg@3476: "/ self listOfColors removeAll. cg@3476: "/ self findColorMapMode. cg@3476: "/ "/ imageEditView removelastUndo cg@3476: "/ cg@3476: "/ cg@3476: cg@3476: "Created: / 31-08-2017 / 12:49:13 / cg" cg@3476: ! cg@3476: cg@3476: doMagnifyDown cg@3476: "magnifies the current image one step down" cg@3476: cg@3476: |magHolder mag| cg@3476: cg@3476: magHolder := self magnificationHolder. cg@3476: (mag := magHolder value) > 1 ifTrue: [ cg@3476: magHolder value: mag - 1 cg@3476: ] cg@3476: cg@3476: "Modified: / 26.7.1998 / 20:24:08 / cg" cg@3476: ! cg@3476: cg@3476: doMagnifyImage cg@3476: "magnifies the current image to a new size" cg@3476: cg@3476: |box newSize image antiAliased| cg@3476: cg@3550: antiAliased := (LastMagnifySmoothing ? false) asValue. cg@3476: image := imageEditView image. cg@3476: cg@3476: box := EnterBox new. cg@3476: box title:(resources string:'Images new size:'). cg@3476: box okText:(resources string:'OK'). cg@3476: box abortText:(resources string:'Cancel'). cg@3550: box initialText:(LastMagnifyTo ? image extent) printString. cg@3476: box verticalPanel add:(CheckBox label:(resources string:'Antialias/Smooth') model:antiAliased). cg@3476: box showAtPointer. cg@3476: cg@3476: (box accepted cg@3476: and: [(newSize := self pointFromString:(box contents)) notNil]) cg@3476: ifTrue:[ cg@3476: newSize isPoint ifFalse:[ cg@3476: self warn:'Please enter the new size as ''x @ y''.'. cg@3476: ^ self. cg@3476: ]. cg@3550: LastMagnifyTo := newSize. cg@3550: LastMagnifySmoothing := antiAliased value. cg@3476: antiAliased value ifTrue:[ cg@3476: ((newSize x < image width) or:[(newSize y < image height)]) ifTrue:[ cg@3476: imageEditView magnifySmoothingTo:newSize. cg@3476: ] ifFalse:[ cg@3476: imageEditView magnifyAntiAliasedImageTo:newSize. cg@3476: ]. cg@3476: ] ifFalse:[ cg@3476: imageEditView magnifyImageTo:newSize. cg@3476: ]. cg@3476: ]. cg@3476: cg@3476: self updateInfoLabel cg@3476: cg@3476: "Modified: / 30-08-2017 / 15:46:02 / cg" cg@3476: ! cg@3476: cg@3476: doMagnifyImageBy cg@3476: "magnifies the current image (by a scale)" cg@3476: cg@3550: |oldSize newSize scaleString scale image smoothing| cg@3476: cg@3476: image := imageEditView image. cg@3476: oldSize := image extent. cg@3476: cg@3550: smoothing := (LastMagnifySmoothing ? false) asValue. cg@3476: cg@3476: Dialog modifyingBoxWith:[:box | cg@3550: box verticalPanel add:(CheckBox label:(resources string:'Antialias/Smooth') model:smoothing). cg@3476: "/ box verticalPanel add:(CheckBox label:(resources string:'Smoothing') model:smoothing). cg@3476: ] do:[ cg@3476: scaleString := Dialog cg@3476: request:(resources string:'Scale factor (<1 to shrink; >1 to magnify):') cg@3550: initialAnswer:(LastMagnifyBy ? 1) printString cg@3476: list:#('0.1' '0.25' '0.3' '0.5' '1.5' '2' '3' '4'). cg@3476: ]. cg@3476: scaleString isNil ifTrue:[^ self]. cg@3476: cg@3476: scale := Object readFromString:scaleString onError:nil. cg@3476: cg@3476: scale notNil ifTrue:[ cg@3476: scale isNumber ifFalse:[ cg@3476: self warn:'please enter a scale factor (<1 to shrink; >1 to magnify).'. cg@3476: ^ self. cg@3476: ]. cg@3550: cg@3550: LastMagnifyBy := scale. cg@3550: LastMagnifySmoothing := smoothing value. cg@3550: cg@3476: newSize := oldSize * scale. cg@3550: smoothing value ifTrue:[ cg@3476: scale < 1 ifTrue:[ cg@3476: imageEditView magnifySmoothingBy:scale. cg@3476: ] ifFalse:[ cg@3476: imageEditView magnifyAntiAliasedImageTo:newSize. cg@3476: ]. cg@3476: ] ifFalse:[ cg@3476: imageEditView magnifyImageTo:newSize. cg@3476: ]. cg@3476: ]. cg@3476: cg@3476: self updateInfoLabel cg@3476: cg@3476: "Modified: / 30-08-2017 / 15:34:56 / cg" cg@3476: ! cg@3476: cg@3476: doMagnifyUp cg@3476: "magnifies the current image one step up" cg@3476: cg@3476: |magHolder mag| cg@3476: cg@3476: magHolder := self magnificationHolder. cg@3476: (mag := magHolder value) < 63 ifTrue: [ cg@3476: magHolder value: mag + 1 cg@3476: ] cg@3476: cg@3476: "Modified: / 26.7.1998 / 20:23:52 / cg" cg@3476: ! cg@3476: cg@3476: doResizeImage cg@3476: "resizes the current image" cg@3476: cg@3476: |box newSize image| cg@3476: cg@3476: image := imageEditView image. cg@3476: cg@3476: box := EnterBox new. cg@3476: box title:(resources string:'Images new size:'). cg@3476: box okText:(resources string:'OK'). cg@3476: box abortText:(resources string:'Cancel'). cg@3476: box initialText:image extent printString. cg@3476: box showAtPointer. cg@3476: (box accepted cg@3476: and: [(newSize := self pointFromString:(box contents)) notNil]) cg@3476: ifTrue:[ cg@3476: imageEditView resizeImageTo:newSize. cg@3476: ]. cg@3476: ! cg@3476: cg@3476: doRotateImage cg@3476: "rotates current image" cg@3476: cg@3476: |rotationString box rotation| cg@3476: cg@3476: rotationString := Dialog cg@3476: request:(resources string:'Rotate by (degrees, clockwise):') cg@3476: list:#( '-90' '90' '180' '45' '-45' '135' '-135' ) cg@3476: initialAnswer:90. cg@3476: rotationString isEmptyOrNil ifTrue:[^ self]. "/ canceled cg@3476: rotation := Number readFrom:rotationString onError:[nil]. cg@3476: rotation isNil ifTrue:[^ self]. cg@3476: cg@3476: "/ box := EnterBox new. cg@3476: "/ box title:(resources string:'Rotate by (degrees, clockwise):'). cg@3476: "/ box okText:(resources string:'OK'). cg@3476: "/ box abortText:(resources string:'Cancel'). cg@3476: "/ box initialText: '0'. cg@3476: "/ box showAtPointer. cg@3476: "/ (box accepted and: [(rotation := Number readFromString: box contents onError:nil) notNil]) cg@3476: "/ ifFalse:[ ^ self ]. cg@3476: cg@3476: imageEditView rotateImageBy:rotation. cg@3476: self updateInfoLabel. cg@3476: cg@3476: "Modified: / 18-03-2012 / 14:41:14 / cg" cg@3476: "Modified (comment): / 24-08-2017 / 15:02:57 / cg" cg@3476: ! cg@3476: cg@3476: doShiftManual cg@3476: "let user specify amount and shift" cg@3476: cg@3476: |bindings amount img firstChange shiftAction acceptChannel wrapHolder| cg@3476: cg@3476: acceptChannel := TriggerValue new. cg@3476: wrapHolder := (lastShiftUsedWrap ? true) asValue. cg@3476: cg@3476: firstChange := true. cg@3476: cg@3476: shiftAction := cg@3476: [:shiftH :shiftV | cg@3476: acceptChannel value:true. cg@3476: cg@3476: img := imageEditView image. cg@3476: firstChange ifTrue:[ cg@3476: imageEditView makeUndo. cg@3476: firstChange := false. cg@3476: ]. cg@3476: imageEditView shiftImageHorizontal:(shiftH value) vertical:(shiftV value) wrap:(wrapHolder value). cg@3476: self updateInfoLabel cg@3476: ]. cg@3476: cg@3476: bindings := IdentityDictionary new. cg@3476: bindings at:#shiftAmount put:(amount := 1 asValue). cg@3476: bindings at:#wrap put:wrapHolder. cg@3476: bindings at:#acceptChannel put:acceptChannel. cg@3476: cg@3476: bindings at:#shiftLeftNow put:[ shiftAction value:(-1*amount value) value:0 ]. cg@3476: bindings at:#shiftRightNow put:[ shiftAction value:amount value value:0 ]. cg@3476: bindings at:#shiftUpNow put:[ shiftAction value:0 value:(-1*amount value) ]. cg@3476: bindings at:#shiftDownNow put:[ shiftAction value:0 value:amount value ]. cg@3476: cg@3476: (self openDialogInterface:#shiftDialogSpec withBindings:bindings) cg@3476: ifFalse:[ cg@3476: firstChange ~~ true ifTrue:[ cg@3476: imageEditView undo cg@3476: ] cg@3476: ]. cg@3476: lastShiftUsedWrap := wrapHolder value. cg@3476: cg@3476: "Created: / 7.9.1998 / 18:16:07 / cg" cg@3476: "Modified: / 7.9.1998 / 18:20:42 / cg" cg@3476: ! cg@3476: cg@3476: doUnCropManual cg@3476: "let user specify borders and add them" cg@3476: cg@3476: |bindings leftAmount topAmount rightAmount bottomAmount img| cg@3476: cg@3476: bindings := IdentityDictionary new. cg@3476: bindings at:#cropLeftAmount put:(leftAmount := 1 asValue). cg@3476: bindings at:#cropRightAmount put:(rightAmount := 1 asValue). cg@3476: bindings at:#cropTopAmount put:(topAmount := 1 asValue). cg@3476: bindings at:#cropBottomAmount put:(bottomAmount := 1 asValue). cg@3476: bindings at:#cropBoxIsDialog put:true. cg@3476: cg@3476: (self openDialogInterface:#uncropSpec withBindings:bindings) cg@3476: ifTrue:[ cg@3476: leftAmount := leftAmount value. cg@3476: rightAmount := rightAmount value. cg@3476: topAmount := topAmount value. cg@3476: bottomAmount := bottomAmount value. cg@3476: img := imageEditView image. cg@3476: cg@3476: imageEditView cg@3476: makeBorderedImageX:leftAmount y:topAmount cg@3476: width:(img width + leftAmount + rightAmount) cg@3476: height:(img height + topAmount + bottomAmount). cg@3476: self updateInfoLabel cg@3476: ]. cg@3476: cg@3476: "Created: / 07-09-1998 / 18:16:07 / cg" cg@3476: "Modified: / 19-02-2017 / 15:31:00 / cg" cg@3476: ! cg@3476: cg@3476: doUndo cg@3476: "reverses last edit action" cg@3476: cg@3476: imageEditView undo. cg@3476: self updateImagePreView cg@3476: ! cg@3476: cg@3476: makeInverse cg@3476: "inverts the pixels - for palettes, this leads to funny results" cg@3476: cg@3476: self updateImageAfterDoing:#makeInverse. cg@3476: cg@3476: "Modified: / 31-08-2017 / 12:16:07 / cg" cg@3476: "Modified (comment): / 31-08-2017 / 13:51:28 / cg" cg@3476: ! cg@3476: cg@3476: makeMonochromeImage cg@3476: "let user choose a threshold, then convert to monochrome" cg@3476: cg@3476: |image userInput thresholdBrighness| cg@3476: cg@3476: image := imageEditView image. cg@3476: cg@3476: Dialog modifyingBoxWith:[:box | cg@3476: |preview slider update thresholdValue| cg@3476: cg@3476: thresholdValue := 0.5 asValue. cg@3476: cg@3476: box enterField cg@3476: converter:(PrintConverter new initForNumber); cg@3476: model:thresholdValue. cg@3476: cg@3476: box verticalPanel extent:1.0 @ 300. cg@3476: cg@3476: box verticalPanel add:(slider := HorizontalSlider new start:0 stop:1 step:0.05). cg@3476: slider model:thresholdValue. cg@3476: slider width:1.0; leftInset:4; rightInset:4. cg@3476: cg@3476: box verticalPanel add:(preview := ImageView new). cg@3476: preview extent:300 @300. cg@3476: preview level:-1. cg@3476: box verticalPanel horizontalLayout:#fitSpace. cg@3476: cg@3476: update := cg@3476: [ cg@3476: |s t| cg@3476: cg@3476: t := thresholdValue value clampBetween:0 and:1. cg@3476: preview image:((image asThresholdMonochromeImage:t) cg@3476: magnifiedPreservingRatioTo:preview extent). cg@3476: ]. cg@3476: update value. cg@3476: box enterField acceptOnLostFocus:true. cg@3476: box enterField acceptOnLeave:true. cg@3476: thresholdValue onChangeEvaluate:update. cg@3476: cg@3476: ] do:[ cg@3476: userInput := Dialog request:'Threshold (0=black; 1=white) ?' initialAnswer:0.5. cg@3476: ]. cg@3476: userInput isEmptyOrNil ifTrue:[^ self]. cg@3497: cg@3476: thresholdBrighness := Number readFrom:userInput onError:nil. cg@3476: thresholdBrighness isNil ifTrue:[^ self]. cg@3476: cg@3476: thresholdBrighness := thresholdBrighness clampBetween:0 and:1. cg@3478: cg@3476: imageEditView newImageWithUndo:(image asThresholdMonochromeImage:thresholdBrighness) cg@3476: cg@3476: "Created: / 24-08-2017 / 15:26:44 / cg" cg@3476: "Modified: / 24-08-2017 / 17:54:21 / cg" cg@3497: "Modified (format): / 23-10-2017 / 10:42:52 / cg" cg@3476: ! cg@3476: cg@3476: makeNegative cg@3476: "negates current image by negating the color map" cg@3476: cg@3476: self withExecuteCursorDo:[ cg@3477: imageEditView makeNegative. cg@3476: self updateImage. cg@3476: ]. cg@3476: cg@3476: "Created: / 31-08-2017 / 13:49:47 / cg" cg@3477: "Modified (comment): / 01-09-2017 / 10:27:37 / cg" cg@3476: ! cg@3476: cg@3476: thresholdGrayToDepth cg@3476: self askForDepthThenDo:[:depth | cg@3476: self thresholdGrayToDepth:depth cg@3476: ]. cg@3476: cg@3476: "Created: / 24-08-2017 / 17:49:23 / cg" cg@3476: ! cg@3476: cg@3476: thresholdGrayToDepth:depth cg@3476: self withExecuteCursorDo:[ cg@3476: |newImage| cg@3476: cg@3476: newImage := self image asThresholdGrayImageDepth:depth. cg@3476: imageEditView newImageWithUndo:newImage. cg@3476: ]. cg@3476: cg@3476: "Created: / 24-08-2017 / 17:49:30 / cg" cg@3476: ! cg@3476: cg@3476: thresholdToDepth cg@3476: self askForDepthThenDo:[:depth | cg@3476: self convertToDepth:depth dither:false cg@3476: ]. cg@3476: cg@3476: "Created: / 30-08-2017 / 00:31:33 / cg" cg@3497: ! cg@3497: cg@3497: thresholdToNumberOfGrayColors cg@3497: |oldDepth numGrayColors suggestion grayImage userInput grayColors| cg@3497: cg@3497: oldDepth := self image depth. cg@3497: grayImage := self image asGrayImageDepth:8. cg@3497: cg@3497: suggestion := LastNumThresholdGrayColors notNil ifTrue:[ cg@3497: LastNumThresholdGrayColors cg@3497: ] ifFalse:[ cg@3497: oldDepth > 8 cg@3497: ifTrue:[256] cg@3497: ifFalse:[2 raisedTo:((oldDepth // 2 - 1) nextPowerOf2)] cg@3497: ]. cg@3497: cg@3497: Dialog modifyingBoxWith:[:box | cg@3497: |preview slider update thresholdValue| cg@3497: cg@3497: thresholdValue := suggestion asValue. cg@3497: cg@3497: box enterField cg@3497: converter:(PrintConverter new initForNumber); cg@3497: model:thresholdValue. cg@3497: cg@3497: box verticalPanel extent:1.0 @ 300. cg@3497: cg@3497: box verticalPanel add:(slider := HorizontalSlider new start:2 stop:256 step:1). cg@3497: slider model:thresholdValue. cg@3497: slider width:1.0; leftInset:4; rightInset:4. cg@3497: cg@3497: box verticalPanel add:(preview := ImageView new). cg@3497: preview extent:300 @300. cg@3497: preview level:-1. cg@3497: box verticalPanel horizontalLayout:#fitSpace. cg@3497: cg@3497: update := cg@3497: [ cg@3497: |numGrayColors depth s t tImage| cg@3497: cg@3497: numGrayColors := thresholdValue value clampBetween:2 and:256. cg@3497: grayColors := Color grayColorVector:numGrayColors. cg@3497: tImage := grayImage asNearestPaintImageDepth:(grayImage depth) colors:grayColors. cg@3497: cg@3497: preview image:(tImage magnifiedPreservingRatioTo:preview extent). cg@3497: ]. cg@3497: update value. cg@3497: box enterField acceptOnLostFocus:true. cg@3497: box enterField acceptOnLeave:true. cg@3497: thresholdValue onChangeEvaluate:update. cg@3497: cg@3497: ] do:[ cg@3497: userInput := Dialog request:'Number of Gray Colors ?' initialAnswer:suggestion asString. cg@3497: ]. cg@3497: userInput isEmptyOrNil ifTrue:[^ self]. cg@3497: cg@3497: cg@3497: numGrayColors := Number readFrom:userInput onError:nil. cg@3497: numGrayColors isNil ifTrue:[^ self]. cg@3497: cg@3497: grayColors := Color grayColorVector:numGrayColors. cg@3497: imageEditView newImageWithUndo:(grayImage asNearestPaintImageDepth:(grayImage depth) colors:grayColors). cg@3497: cg@3497: "Created: / 23-10-2017 / 10:55:15 / cg" cg@3476: ! ! cg@3476: cg@3476: !ImageEditor methodsFor:'user actions-editing-colors'! cg@3476: cg@3471: convertToDepth:depth dither:doDither cg@3471: |answer labels values cg@3471: ditherColors fixColors cg@3471: nGrey greyColorsAlready moreColors d| cg@3471: cg@3471: "/ no colormap above 12 bits!! cg@3471: depth > 12 ifTrue:[ cg@3471: answer := #TrueColor. cg@3471: ] ifFalse:[ cg@3471: doDither ifTrue:[ cg@3471: (depth >= 8) ifTrue:[ cg@3471: labels := #('Cancel' 'Use Browser Palette' 'Use Standard' 'Compute' 'TrueColor'). cg@3471: values := #(nil UseBrowserPalette UseStandard Compute TrueColor). cg@3471: ] ifFalse:[ cg@3471: depth == 1 ifTrue:[ cg@3471: answer := #UseStandard cg@3471: ] ifFalse:[ cg@3471: labels := #('Cancel' 'Use Standard' 'Compute' 'TrueColor'). cg@3471: values := #(nil UseStandard Compute TrueColor). cg@3471: ]. cg@3471: ]. cg@3471: ] ifFalse:[ cg@3471: (depth >= 8) ifTrue:[ cg@3471: labels := #('Cancel' 'Use Browser Palette' 'Use Standard' 'TrueColor'). cg@3471: values := #(nil UseBrowserPalette UseStandard TrueColor). cg@3471: ] ifFalse:[ cg@3471: answer := #UseStandard cg@3471: ]. cg@3471: ]. cg@3471: ]. cg@3471: cg@3471: answer isNil ifTrue:[ cg@3471: answer := OptionBox cg@3471: request:'Compute a new (optimized) colormap\(Warning: this may take some time)\\or else use a standard colormap?' withCRs cg@3471: label:(resources string:'Dither how') cg@3471: image:(YesNoBox iconBitmap) cg@3471: buttonLabels:(resources array:labels) cg@3471: values:values cg@3471: default:#UseStandard cg@3471: onCancel:nil. cg@3471: answer isNil ifTrue:[^ self]. cg@3471: ]. cg@3471: cg@3471: (answer == #Compute) ifTrue:[ cg@3471: ditherColors := cg@3471: Color cg@3471: best:(1 bitShift:depth) cg@3471: ditherColorsForImage:self image cg@3471: ] ifFalse:[ cg@3471: (answer == #UseBrowserPalette) ifTrue:[ cg@3471: ditherColors := Color colorCubeWithRed:6 green:6 blue:6. cg@3471: ] ifFalse:[ cg@3471: answer == #TrueColor ifTrue:[ cg@3471: depth == 6 ifTrue:[ cg@3471: fixColors := FixedPalette cg@3471: redShift:4 redMask:3 cg@3471: greenShift:2 greenMask:3 cg@3471: blueShift:0 blueMask:3 cg@3471: ]. cg@3471: depth == 9 ifTrue:[ cg@3471: fixColors := FixedPalette cg@3471: redShift:6 redMask:7 cg@3471: greenShift:3 greenMask:7 cg@3471: blueShift:0 blueMask:7 cg@3471: ]. cg@3471: depth == 12 ifTrue:[ cg@3471: fixColors := FixedPalette cg@3471: redShift:8 redMask:16r0F cg@3471: greenShift:4 greenMask:16r0F cg@3471: blueShift:0 blueMask:16r0F cg@3471: ]. cg@3471: depth == 15 ifTrue:[ cg@3471: fixColors := FixedPalette cg@3471: redShift:10 redMask:16r1F cg@3471: greenShift:5 greenMask:16r1F cg@3471: blueShift:0 blueMask:16r1F cg@3471: ]. cg@3471: depth == 16 ifTrue:[ cg@3471: fixColors := FixedPalette cg@3471: redShift:11 redMask:16r1F cg@3471: greenShift:5 greenMask:16r3F cg@3471: blueShift:0 blueMask:16r1F cg@3471: ]. cg@3471: depth == 18 ifTrue:[ cg@3471: fixColors := FixedPalette cg@3471: redShift:12 redMask:16r3F cg@3471: greenShift:6 greenMask:16r3F cg@3471: blueShift:0 blueMask:16r3F cg@3471: ]. cg@3471: ] ifFalse:[ cg@3471: depth == 1 ifTrue:[ cg@3471: ditherColors := { Color black . Color white }. cg@3471: ]. cg@3471: depth == 2 ifTrue:[ cg@3471: ditherColors := { Color black . Color darkGray .Color lightGray . Color white }. cg@3471: ]. cg@3471: depth = 3 ifTrue:[ cg@3471: ditherColors := Color colorCubeWithRed:2 green:2 blue:2. cg@3471: ]. cg@3471: depth = 4 ifTrue:[ cg@3471: ditherColors := Color vgaColors. cg@3471: ]. cg@3471: depth = 5 ifTrue:[ cg@3471: ditherColors := Color colorCubeWithRed:3 green:4 blue:2. cg@3471: ]. cg@3471: depth = 6 ifTrue:[ cg@3471: ditherColors := Color colorCubeWithRed:4 green:4 blue:3. cg@3471: ]. cg@3471: depth = 7 ifTrue:[ cg@3471: ditherColors := Color colorCubeWithRed:5 green:5 blue:4. cg@3471: ]. cg@3471: depth == 8 ifTrue:[ cg@3471: ditherColors := Color standardDitherColorsForDepth8. cg@3471: ]. cg@3471: depth == 9 ifTrue:[ cg@3471: ditherColors := Color colorCubeWithRed:8 green:8 blue:8. cg@3471: ]. cg@3471: ditherColors isNil ifTrue:[ cg@3471: self error:'unsupported depth'. cg@3471: ]. cg@3471: cg@3471: "/ add as many gray colors as possible. cg@3471: nGrey := (2 raisedTo:depth) - ditherColors size. cg@3471: nGrey > 0 ifTrue:[ cg@3471: nGrey := nGrey min:100. cg@3471: greyColorsAlready := ditherColors select:[:clr | clr isGreyColor]. cg@3471: d := 1 / nGrey. cg@3471: moreColors := (1 to:nGrey-1) cg@3471: collect:[:i | Color brightness:(d * i)] cg@3471: thenReject:[:clr | greyColorsAlready includes:clr ]. cg@3471: cg@3471: ditherColors := ditherColors , moreColors. cg@3471: ]. cg@3471: ]. cg@3471: ]. cg@3471: ]. cg@3471: cg@3471: self withExecuteCursorDo:[ cg@3471: |newImage| cg@3471: cg@3471: doDither ifTrue:[ cg@3471: depth == 1 ifTrue:[ cg@3471: newImage := self image asErrorDitheredMonochromeImage cg@3471: ] ifFalse:[ cg@3471: answer == #TrueColor ifTrue:[ cg@3471: newImage := self image asDitheredImageUsing:fixColors depth:depth. cg@3471: ] ifFalse:[ cg@3471: newImage := self image asDitheredImageUsing:ditherColors depth:depth. cg@3471: ] cg@3471: ] cg@3471: ] ifFalse:[ cg@3471: answer == #TrueColor ifTrue:[ cg@3471: self halt. cg@3471: ] ifFalse:[ cg@3471: newImage := self image asNearestPaintImageDepth:depth colors:ditherColors cg@3471: ]. cg@3471: ]. cg@3471: imageEditView newImageWithUndo:newImage. cg@3471: ]. cg@3471: cg@3471: "Created: / 30-08-2017 / 00:33:55 / cg" cg@3471: "Modified: / 30-08-2017 / 02:13:03 / cg" cg@3471: ! cg@3471: cg@3598: exchangeGreenBlueChannels cg@3598: self updateImageAfterDoing:#exchangeGreenBlueChannels. cg@3598: cg@3598: "Created: / 31-08-2017 / 13:51:10 / cg" cg@3598: ! cg@3598: cg@3598: exchangeRedBlueChannels cg@3598: self updateImageAfterDoing:#exchangeRedBlueChannels. cg@3598: cg@3598: "Created: / 31-08-2017 / 13:51:10 / cg" cg@3598: ! cg@3598: cg@3598: exchangeRedGreenChannels cg@3598: self updateImageAfterDoing:#exchangeRedGreenChannels. cg@3598: cg@3598: "Created: / 31-08-2017 / 13:51:10 / cg" cg@3598: ! cg@3598: cg@3476: makeInvertedBits cg@3476: "inverts the pixels - for palettes, this leads to funny results. cg@3476: For others, this is the same as negating" cg@3476: cg@3476: self updateImageAfterDoing:#makeInvertedBits. cg@3476: cg@3476: "Created: / 31-08-2017 / 13:51:10 / cg" tz@400: ! ! tz@400: cg@2812: !ImageEditor methodsFor:'user actions-image sequences'! cg@2812: cg@2812: editEachImageFromSequence cg@2812: |seq| cg@2812: cg@2812: self checkModified ifFalse:[ ^ self ]. cg@2812: cg@2812: imageEditView releaseUndos. cg@2812: cg@2812: seq := self image imageSequence. cg@2812: seq size > 10 ifTrue:[ cg@2812: (Dialog confirm:(resources string:'Ok to open %1 image editor windows?' with:seq size)) cg@2812: ifFalse:[^ self]. cg@2812: ]. cg@2812: cg@2812: seq do:[:eachFrame | cg@2812: ImageEditor openOnImage:eachFrame image cg@2812: ]. cg@2812: cg@2812: "Modified: / 21-10-2010 / 15:01:25 / cg" cg@2812: ! cg@2812: cg@2812: gotoImageInSequence:index cg@2812: "display the next image in the image sequence" cg@2812: cg@2812: |img seq frame listOfColors| cg@2812: cg@2812: imageEditView releaseUndos. cg@2812: cg@2812: seq := self image imageSequence. cg@2812: cg@2812: imageSeqNr := index. cg@2812: frame := seq at:imageSeqNr. cg@2812: imageEditView image:(frame image). cg@2812: cg@2812: (img := self image) notNil ifTrue:[ cg@2812: listOfColors := self listOfColors. cg@2812: img colorMap notNil ifTrue:[ cg@2812: listOfColors contents:(img usedColors asSet asOrderedCollection). cg@2812: ] ifFalse:[ cg@2812: listOfColors removeAll. cg@2812: ]. cg@2812: self findColorMapMode. cg@2812: self updateLabelsAndHistory. cg@2812: img := img onDevice:device. cg@2812: imageEditView image:img. cg@2812: ] ifFalse:[ cg@2812: self updateForNoImage cg@2812: ]. cg@2812: cg@2812: "Created: / 21-10-2010 / 14:22:11 / cg" cg@2812: ! cg@2812: cg@2812: nextImageInSequence cg@2812: "display the next image in the image sequence" cg@2812: cg@2812: |seq index| cg@2812: cg@2812: seq := self image imageSequence. cg@2812: (index := imageSeqNr) isNil ifTrue:[ cg@2812: index := 1. cg@2812: ]. cg@2812: index := index + 1. cg@2812: index > seq size ifTrue:[ cg@2812: self information:'Back to first image in sequence'. cg@2812: index := 1. cg@2812: ]. cg@2812: self gotoImageInSequence:index. cg@2812: cg@2812: "Modified: / 21-10-2010 / 14:24:11 / cg" cg@2812: ! cg@2812: cg@2812: previousImageInSequence cg@2812: "display the previous image in the image sequence" cg@2812: cg@2812: |seq index| cg@2812: cg@2812: seq := self image imageSequence. cg@2812: (index := imageSeqNr) isNil ifTrue:[ cg@2812: index := 1. cg@2812: ]. cg@2812: index := index - 1. cg@2812: index < 1 ifTrue:[ cg@2812: self information:'Wrap to last image in sequence'. cg@2812: index := seq size. cg@2812: ]. cg@2812: self gotoImageInSequence:index. cg@2812: cg@2812: "Created: / 21-10-2010 / 14:25:03 / cg" cg@2812: ! ! cg@2812: cg@1715: !ImageEditor methodsFor:'user actions-loading'! tz@400: tz@767: doLoadFromClass tz@767: "opens a dialog for loading an image from class and a (resource-) selector" tz@400: cg@1122: |img| cg@1122: cg@1975: self checkModified ifFalse:[ ^ self ]. cg@1975: cg@1054: (imageEditView loadFromClass) notNil ifTrue:[ cg@1380: imageSeqNr := nil. cg@1122: (img := self image) notNil ifTrue: [ cg@1900: self updateColorsFromImage:img. tz@574: self findColorMapMode. cg@1376: self updateLabelsAndHistory. cg@1054: ] ifFalse: [ cg@1054: self updateForNoImage cg@1376: ]. tz@449: ] tz@400: ! tz@400: tz@767: doLoadFromFile tz@767: "opens a dialog for loading an image from a file" tz@400: cg@2820: |img file filters title| cg@1353: cg@1975: self checkModified ifFalse:[ ^ self ]. cg@1975: cg@1380: imageSeqNr := nil. cg@1353: img := self image. cg@1353: img notNil ifTrue: [ cg@1353: file := img fileName cg@1353: ]. cg@1353: cg@3405: title := (resources string:'Load Image from File:'). cg@2820: sv@3066: (UserPreferences current useNativeFileDialog cg@3100: and:[Screen current isWindowsPlatform]) ifTrue:[ cg@2820: self withWaitCursorDo:[ sr@3623: file isNil ifTrue:[ sr@3623: file := LastDirectory. sr@3623: file notNil ifTrue:[ sr@3623: file := file asFilename / 'image.png'. sr@3623: ]. sr@3623: ]. sr@3623: sv@3066: file := Screen current sr@3623: nativeFileDialogWithTitle:title sr@3623: defaultFilename:file sr@3623: owningTopView:self window topView sr@3623: filter:{ sr@3623: {(resources string:'Image Files'). '*.tif;*.png;*.gif;*.bmp;*.jpg'}. sr@3623: {(resources string:'All Files'). '*.*'} sr@3623: } sr@3623: filterIndex:nil sr@3624: trueForSave:false sr@3625: trueForMultiSelect:false sr@3624: trueForPromptOverwrite:false. cg@2820: ]. cg@2820: ] ifFalse:[ cg@2820: filters := FileSelectionBrowser loadImageFileNameFilters. cg@2820: file notNil ifTrue:[ cg@2820: file := FileSelectionBrowser cg@2820: request:title cg@2820: fileName:file cg@2820: withFileFilters:filters. cg@2820: ] ifFalse:[ cg@2820: file := FileSelectionBrowser cg@2820: request:title cg@2820: inDirectory:LastDirectory cg@2820: withFileFilters:filters. cg@2820: ]. cg@1353: ]. cg@2820: cg@1353: file notNil ifTrue:[ cg@1353: LastDirectory := file asFilename directoryName. cg@1353: self loadFromFile:file cg@1353: ] cg@2820: cg@3405: "Modified: / 16-02-2017 / 10:53:41 / cg" sr@3625: "Modified: / 25-10-2018 / 10:55:54 / sr" tz@400: ! tz@400: cg@2796: doLoadFromURL cg@2796: "opens a dialog for loading an image from a URL" cg@2796: cg@2866: |tempFile url response| cg@2796: cg@2796: self checkModified ifFalse:[ ^ self ]. cg@2796: cg@2796: url := Dialog cg@3405: request:(resources string:'Load Image from URL:') cg@2796: initialAnswer:LastURL. cg@2796: cg@2796: url notEmptyOrNil ifTrue:[ cg@3050: HTTPInterface isNil ifTrue:[ Smalltalk loadPackage:'stx:goodies/communication']. cg@3050: cg@2796: LastURL := url. sv@3027: tempFile := FileStream newTemporary close fileName. cg@2866: self withWaitCursorDo:[ cg@3492: |newURL| cg@3492: cg@2866: response := HTTPInterface get:url destinationFile:tempFile. cg@3492: response isMovedResponse ifTrue:[ cg@3492: newURL := response location. cg@3492: newURL ~= url ifTrue:[ cg@3492: response := HTTPInterface get:newURL destinationFile:tempFile. cg@3492: ]. cg@3492: ]. cg@2866: ]. cg@2866: response isErrorResponse ifTrue:[ cg@2866: Dialog warn:(resources string:'Could not load image ("%1")' with:response responseText). cg@2866: ] ifFalse:[ cg@2866: self loadFromFile:tempFile. cg@2866: ]. cg@3552: tempFile remove cg@2796: ] cg@2796: cg@2796: "Created: / 20-09-2010 / 11:30:59 / cg" cg@3492: "Modified: / 13-09-2017 / 17:00:28 / cg" cg@2796: ! cg@2796: tz@767: doNewImage tz@767: "opens a dialog with choices of size and color map for creating a new image" tz@400: cg@3494: |dialogAspects width height cMapString cMapMode cMap imageClass image szString defaultSize ext depth| 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@3494: depth := (cMapMode startsWith:'depth') cg@3494: ifTrue:[ Integer readFrom:(cMapMode copyFrom:'depth' size + 1) ] cg@3494: ifFalse:[ cg@3494: (cMapMode startsWith:'masked') cg@3494: ifTrue:[ Integer readFrom:(cMapMode copyFrom:'masked' size + 1) ] cg@3494: ifFalse:[ cMap size highBit-1 ]]. cg@3494: imageClass := Image implementorForDepth:depth. 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@3494: (cMapMode startsWith:'mask') ifTrue:[ sv@3125: image mask: (ImageMask width: width height: height depth: 1 fromArray: (ByteArray new: width*height)). tz@400: ]. cg@3494: depth == 32 ifTrue:[ cg@3494: image photometric:#rgba cg@3494: ] ifFalse:[ cg@3494: image colorMap: cMap. cg@3494: ]. 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@3494: cg@3494: "Modified: / 13-09-2017 / 23:57:52 / cg" 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@3496: image := imageEditView clipBoardImage. cg@3164: image isImageOrForm ifFalse:[ cg@3164: image := Image readFrom:(image asString) onError:nil. cg@3164: image isNil ifTrue:[ cg@3164: Dialog warn:'Clipboard does not contain an image I can use/understand'. cg@3164: ^ self. cg@3164: ]. cg@3164: ]. cg@3496: 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@3496: cg@3496: "Modified (format): / 08-10-2017 / 08:58:03 / cg" cg@1682: ! cg@1682: cg@3200: doNewMaskFromClipboard cg@3200: |mask image newImage| cg@3200: cg@3200: self checkModified ifFalse:[ ^ self ]. cg@3200: cg@3496: mask := imageEditView clipBoardImage. cg@3200: mask isImageOrForm ifFalse:[ cg@3200: mask := Image readFrom:(mask asString) onError:nil. cg@3200: mask isNil ifTrue:[ cg@3200: Dialog warn:'Clipboard does not contain an image I can use/understand'. cg@3200: ^ self. cg@3200: ]. cg@3200: ]. cg@3496: cg@3200: (image:= imageEditView image) isNil ifTrue:[ cg@3200: image := mask. cg@3200: ]. cg@3200: mask extent ~= image extent ifTrue:[ cg@3200: mask := imageEditView resizedImage:mask to:image extent. cg@3200: ]. cg@3200: newImage := image copy. cg@3200: newImage mask:mask. cg@3200: imageEditView newImageWithUndo:newImage. cg@3200: self updateAfterImageChange. cg@3405: cg@3496: "Modified (format): / 08-10-2017 / 08:57:58 / cg" cg@3200: ! cg@3200: cg@3422: grabFullScreenImage cg@3422: "grab all for editing" cg@3422: cg@3422: self grabScreenImageUsing:[ cg@3422: Image fromScreen cg@3422: ]. cg@3422: cg@3422: "Created: / 25-02-2017 / 12:41:29 / cg" cg@3422: ! cg@3422: cg@929: grabScreenImage cg@3422: "let user choose an area and grab that area for editing" cg@929: cg@2707: self grabScreenImageUsing:[ cg@2707: |r| cg@2707: cg@2707: [Screen current leftButtonPressed] whileTrue:[Delay waitForSeconds:0.05]. cg@2707: r := Rectangle fromUser. cg@2708: (r width == 0 or:[r height == 0]) ifTrue:[ cg@2708: nil cg@2708: ] ifFalse:[ cg@2708: lastGrabbedScreenArea := r. cg@2708: Image fromScreen:r cg@2708: ] cg@2707: ]. cg@3422: cg@3422: "Modified (comment): / 25-02-2017 / 12:41:00 / cg" cg@2707: ! cg@2707: cg@2707: grabScreenImageFromLastArea cg@2707: "grab again from the previous area for editing" cg@2707: cg@2707: self grabScreenImageUsing:[ cg@2708: Image fromScreen:lastGrabbedScreenArea cg@2707: ]. cg@2701: ! cg@2701: cg@2701: grabScreenImageUsing:aBlock cg@3422: "let user choose an area and grab that area for editing" cg@2701: cg@1975: self checkModified ifFalse:[ ^ self ]. cg@1975: cg@990: Processor cg@990: addTimedBlock:[ cg@990: |image d8image img| cg@929: cg@1380: imageSeqNr := nil. cg@2701: image := aBlock value. cg@2708: image notNil ifTrue:[ cg@1121: image depth > 8 ifTrue:[ cg@2420: false ifTrue:[ sv@1687: Error handle:[:ex | |sig| cg@2996: (sig := ex creator) == HaltInterrupt ifTrue:[ex reject]. cg@1122: sig == Signal noHandlerSignal ifTrue:[ex reject]. cg@1121: cg@1121: self warn:'Could not convert to depth8 image (too many colors)'. cg@1121: d8image := nil. cg@1121: ] do:[ cg@2420: d8image := Depth8Image fromImage:image photometric:#palette. cg@1121: ]. cg@1121: d8image notNil ifTrue:[ cg@1121: image := d8image cg@1121: ] cg@2420: ]. cg@990: ]. cg@1121: (imageEditView image:image) notNil ifTrue:[ cg@1121: self listOfColors contents:(image colorMap). cg@1121: self findColorMapMode. cg@1121: self updateLabelsAndHistory. cg@990: ] cg@1121: ] cg@1121: ] cg@990: afterSeconds:1 cg@929: cg@3422: "Created: / 29-07-1998 / 21:24:42 / cg" cg@3422: "Modified: / 16-11-2001 / 16:21:19 / cg" cg@3422: "Modified (comment): / 25-02-2017 / 12:41:06 / cg" cg@1380: ! cg@1380: cg@2701: grabWindowImage cg@3422: "let user choose a window and grab its area for editing" cg@2701: cg@2701: self grabScreenImageUsing:[ cg@3188: |v topView| cg@2701: cg@2701: (v := Screen current viewFromUser) notNil ifTrue:[ cg@3188: topView := v topView. cg@3188: topView raise; makeFullyVisible. cg@2704: Delay waitForSeconds:0.5. "/ give view a chance to redraw itself. cg@3188: Image fromView:topView cg@2701: ]. cg@2701: ]. cg@3422: cg@3422: "Modified (comment): / 25-02-2017 / 12:41:20 / cg" 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 cg@3375: "opens a dialog for saving current image to a file. cg@3375: Saved as a button image (i.e. with a frame around)" 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@3379: self clearModifiedAndRememberImageSaved. 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@3426: cg@2595: filters := FileSelectionBrowser saveImageFileNameFilters. cg@1922: sv@3066: (UserPreferences current useNativeFileDialog cg@3100: and:[Screen current isWindowsPlatform]) ifTrue:[ cg@2820: self withWaitCursorDo:[ sr@3623: file isNil ifTrue:[ sr@3623: file := LastDirectory. sr@3623: file notNil ifTrue:[ sr@3623: file := file asFilename / 'image.png'. sr@3623: ]. sr@3623: ]. sr@3623: sv@3066: file := Screen current sr@3623: nativeFileDialogWithTitle:(resources string:'Save Image in File') sr@3623: defaultFilename:file sr@3623: owningTopView:self window topView sr@3623: filter:{ sr@3623: {(resources string:'Image Files'). '*.tif;*.png;*.gif;*.bmp'}. sr@3623: {(resources string:'All Files'). '*.*'} sr@3623: } sr@3623: filterIndex:nil sr@3625: trueForSave:true sr@3625: trueForMultiSelect:false sr@3624: trueForPromptOverwrite:true. cg@2807: ]. cg@3425: ] ifFalse:[ cg@3425: img fileName isNil ifTrue:[ cg@3425: LastDirectory notNil ifTrue:[ cg@3426: file isNil ifTrue:[ cg@3426: file := 'image.png'. cg@3426: ]. cg@3425: file := LastDirectory asFilename construct:(file asFilename baseName). cg@3425: ]. cg@3425: ]. cg@2820: (FileSelectionBrowser isNil or:[DirectoryView isNil]) ifTrue:[ cg@2820: file notNil ifTrue:[ cg@2820: file := Dialog requestFileName:'Save Image To' cg@2820: default:file cg@2820: pattern:(filters first). cg@2820: ] ifFalse:[ cg@2820: file := Dialog cg@2820: requestFileName:'Save Image To' cg@2820: default:'image.png' cg@2820: pattern:(filters first) cg@2820: fromDirectory:LastDirectory. cg@2820: ]. cg@2807: ] ifFalse:[ cg@2820: file notNil ifTrue:[ cg@2820: file := FileSelectionBrowser cg@2820: request:'Save Image To' cg@2820: fileName:file cg@2820: withFileFilters:filters. cg@2820: ] ifFalse:[ cg@2820: file := FileSelectionBrowser cg@3405: request:'Save Image in File:' cg@2820: inDirectory:LastDirectory cg@2820: withFileFilters:filters. cg@2820: ]. cg@2807: ]. cg@1922: ]. cg@1922: file notNil ifTrue:[ cg@1922: imageEditView saveImageFileAs:file. cg@1922: LastDirectory := file asFilename directoryName. cg@1922: self updateLabelsAndHistory. cg@3379: self clearModifiedAndRememberImageSavedAsFile:file. cg@1922: ] cg@2807: cg@3426: "Modified: / 27-02-2017 / 01:26:05 / cg" sr@3625: "Modified: / 25-10-2018 / 10:56:01 / sr" 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@3379: self clearModifiedAndRememberImageSaved. 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@3379: self clearModifiedAndRememberImageSaved. tz@400: ] cg@1309: ! cg@1309: cg@3022: doShowPixelArrayLiteralString cg@3022: "opens a dialog showing a literal array-like storeString cg@3022: (sometimes useful to embed an image into source code)" cg@3022: cg@3022: |img| cg@3022: cg@3022: img := imageEditView image. cg@3022: TextBox openOn:img bits storeString cg@3022: ! cg@3022: cg@1309: doShowStoreString cg@1309: "opens a dialog showing the storeString cg@1309: (sometimes useful to embed an image into source code)" cg@1309: cg@1309: |img| cg@1309: cg@1309: img := imageEditView image. cg@1309: TextBox openOn:img storeString cg@1975: ! cg@1975: cg@1975: save cg@1975: "saves current image on current class and selector" cg@1975: cg@1975: self doSaveMethod tz@400: ! ! tz@400: cg@1715: !ImageEditor methodsFor:'user actions-settings'! cg@1353: cg@1353: doChangeGridMagnification cg@1353: "change grid magnification" cg@1353: cg@1353: |box oldGridLimit newGridLimit| cg@1353: cg@1353: oldGridLimit := imageEditView class gridMagnificationLimit asPoint. cg@1353: cg@1353: box := EnterBox new. cg@1353: box title:(resources string:'Grid Magnification Limit:'). cg@1353: box okText:(resources string:'OK'). cg@1353: box abortText:(resources string:'Cancel'). cg@1353: box initialText:(oldGridLimit x printString). cg@1353: box showAtPointer. cg@1353: cg@1353: (box accepted cg@1353: and: [(newGridLimit := Number readFromString:(box contents) onError:[2]) notNil] cg@1353: ) ifTrue:[ cg@1353: newGridLimit := (99 min: (2 max:newGridLimit)) asPoint. cg@1353: imageEditView class gridMagnificationLimit:newGridLimit. cg@1353: imageEditView invalidate cg@1353: ] cg@1353: cg@2192: ! cg@2192: cg@2192: penWidth:n cg@2192: imageEditView penWidth:n cg@2192: cg@2192: "Created: / 01-11-2007 / 23:47:48 / cg" cg@2375: ! cg@2375: cg@2881: penWidthHolderChanged cg@2881: imageEditView penWidth:(self penWidthHolder value) cg@2881: cg@2881: "Created: / 15-02-2012 / 22:32:00 / cg" cg@2881: ! cg@2881: cg@2375: spraySpot:n cg@2375: imageEditView spraySpot:n cg@2375: cg@2375: "Created: / 01-11-2007 / 23:47:48 / cg" cg@2881: ! cg@2881: cg@2881: spraySpotHolderChanged cg@2881: imageEditView spraySpot:(self spraySpotHolder value) cg@2881: cg@2881: "Created: / 15-02-2012 / 22:37:08 / cg" cg@1353: ! ! cg@1353: tz@400: !ImageEditor class methodsFor:'documentation'! tz@400: tz@400: version tz@400: ^ '$Header$' cg@2590: ! cg@2590: cg@2590: version_CVS cg@2590: ^ '$Header$' tz@400: ! ! cg@2945: