author | tz |
Sun, 21 Dec 1997 22:59:57 +0100 | |
changeset 636 | d53428252193 |
parent 633 | 594edef86630 |
child 662 | 61b7601829ea |
permissions | -rw-r--r-- |
636 | 1 |
" |
2 |
COPYRIGHT (c) 1997 by eXept Software AG / Thomas Zwick |
|
3 |
All Rights Reserved |
|
4 |
||
5 |
This software is furnished under a license and may be used |
|
6 |
only in accordance with the terms of that license and with the |
|
7 |
inclusion of the above copyright notice. This software may not |
|
8 |
be provided or otherwise made available to, or used by, any |
|
9 |
other person. No title to or ownership of the software is |
|
10 |
hereby transferred. |
|
11 |
" |
|
12 |
||
1 | 13 |
ImageView subclass:#ImageEditView |
627 | 14 |
instanceVariableNames:'magnification gridMagnification selectColors imageReaderClass |
15 |
resourceClass resourceSelector editMode mouseKeyColorMode |
|
16 |
undoImage modified coordInfoBlock' |
|
17 |
classVariableNames:'Clipboard' |
|
161 | 18 |
poolDictionaries:'' |
19 |
category:'Views-Misc' |
|
1 | 20 |
! |
21 |
||
636 | 22 |
!ImageEditView class methodsFor:'documentation'! |
23 |
||
24 |
copyright |
|
25 |
" |
|
26 |
COPYRIGHT (c) 1997 by eXept Software AG / Thomas Zwick |
|
27 |
All Rights Reserved |
|
28 |
||
29 |
This software is furnished under a license and may be used |
|
30 |
only in accordance with the terms of that license and with the |
|
31 |
inclusion of the above copyright notice. This software may not |
|
32 |
be provided or otherwise made available to, or used by, any |
|
33 |
other person. No title to or ownership of the software is |
|
34 |
hereby transferred. |
|
35 |
" |
|
36 |
! |
|
37 |
||
38 |
documentation |
|
39 |
" |
|
40 |
The ImageEditView is a view class which can be used by applications |
|
41 |
like the Image Editor for modifying or inspecting images. |
|
42 |
||
43 |
[see also:] |
|
44 |
ImageEditor Image |
|
45 |
||
46 |
[author:] |
|
47 |
Thomas Zwick |
|
48 |
" |
|
49 |
! ! |
|
353 | 50 |
|
7 | 51 |
!ImageEditView methodsFor:'accessing'! |
52 |
||
627 | 53 |
coordInfoBlock: aBlock |
624 | 54 |
|
627 | 55 |
coordInfoBlock := aBlock |
624 | 56 |
! |
57 |
||
627 | 58 |
gridMagnification: aPoint |
624 | 59 |
|
627 | 60 |
gridMagnification := aPoint |
624 | 61 |
! |
62 |
||
63 |
imageReaderClass |
|
64 |
||
65 |
^imageReaderClass |
|
66 |
! |
|
67 |
||
68 |
magnification |
|
69 |
||
70 |
^magnification |
|
71 |
||
255 | 72 |
! |
73 |
||
636 | 74 |
magnification: aPoint |
255 | 75 |
|
627 | 76 |
magnification ~= aPoint |
624 | 77 |
ifTrue: |
78 |
[ |
|
627 | 79 |
magnification := aPoint asPoint. |
624 | 80 |
self scrollToTopLeft. |
81 |
self contentsChanged. |
|
82 |
self invalidate. |
|
83 |
]. |
|
84 |
! |
|
255 | 85 |
|
627 | 86 |
resourceClass |
87 |
||
88 |
^resourceClass |
|
89 |
! |
|
90 |
||
91 |
resourceClass: aClassOrSymbol |
|
92 |
||
93 |
resourceClass := aClassOrSymbol isClass ifTrue: [aClassOrSymbol name] ifFalse: [aClassOrSymbol asSymbol]. |
|
94 |
||
95 |
! |
|
96 |
||
97 |
resourceMessage |
|
98 |
||
99 |
^resourceClass, ' ', resourceSelector |
|
100 |
! |
|
101 |
||
636 | 102 |
resourceMessage: aString |
627 | 103 |
|
636 | 104 |
(aString isString and: [aString trimBlanks size > 0]) |
627 | 105 |
ifTrue: |
106 |
[ |
|
636 | 107 |
resourceClass := (aString readStream upTo: Character space) asSymbol. |
108 |
resourceSelector := (aString copy reverse readStream upTo: Character space) reverse asSymbol. |
|
627 | 109 |
] |
110 |
ifFalse: |
|
111 |
[ |
|
112 |
^nil |
|
113 |
]. |
|
114 |
||
115 |
||
116 |
! |
|
117 |
||
118 |
resourceSelector |
|
119 |
||
120 |
^resourceSelector |
|
121 |
! |
|
122 |
||
123 |
resourceSelector: aStringOrSymbol |
|
124 |
||
125 |
resourceSelector := aStringOrSymbol asSymbol |
|
126 |
! |
|
127 |
||
633 | 128 |
selectColor: anArrayTwoColors |
129 |
||
130 |
selectColors := anArrayTwoColors |
|
131 |
! |
|
132 |
||
627 | 133 |
selectedColor |
134 |
||
633 | 135 |
^selectColors at: mouseKeyColorMode |
627 | 136 |
! |
137 |
||
138 |
selectedColor: aColor |
|
139 |
||
140 |
selectColors at: mouseKeyColorMode put: aColor |
|
141 |
! ! |
|
142 |
||
143 |
!ImageEditView methodsFor:'drawing'! |
|
144 |
||
145 |
redrawImageX:x y:y width:w height:h |
|
636 | 146 |
|
627 | 147 |
|ih iw dotW dotH minX maxX minY maxY color last lastY runW x0 xI yI maskColor| |
148 |
||
149 |
ih := image height. |
|
150 |
iw := image width. |
|
151 |
dotW := magnification x. |
|
152 |
dotH := magnification y. |
|
153 |
||
633 | 154 |
minX := x // dotW. |
627 | 155 |
minX >= iw ifTrue:[minX := iw - 1]. |
633 | 156 |
minY := y // dotH. |
627 | 157 |
minY >= ih ifTrue:[minY := ih - 1]. |
158 |
maxX := (x + w) // dotW + 1. |
|
159 |
maxX > iw ifTrue:[maxX := iw]. |
|
160 |
maxY := (y + h) // dotH + 1. |
|
161 |
maxY > ih ifTrue:[maxY := ih]. |
|
162 |
||
163 |
lastY := -1. |
|
164 |
||
165 |
x0 := minX. |
|
166 |
runW := 0. |
|
167 |
maskColor := false. |
|
168 |
image colorsFromX:minX y:minY toX:maxX-1 y:maxY-1 do: |
|
169 |
[:xx :yy :color| |
|
633 | 170 |
yy ~~ lastY |
171 |
ifTrue: |
|
627 | 172 |
[ |
633 | 173 |
runW ~~ 0 |
174 |
ifTrue: |
|
627 | 175 |
[ |
176 |
|origin| |
|
177 |
origin := (x0 * dotW + margin)@(lastY * dotH + margin). |
|
178 |
self fillRectangle: (origin extent: (runW@dotH)). |
|
632 | 179 |
0 to: runW by: dotW do: [:xxx| self drawFrameAt: ((origin x + xxx) @(origin y))]. |
627 | 180 |
maskColor ifTrue: |
181 |
[ |
|
182 |
self drawMaskPointAt: origin |
|
183 |
]. |
|
184 |
runW := 0. |
|
185 |
]. |
|
186 |
x0 := xx. |
|
187 |
lastY := yy. |
|
188 |
]. |
|
624 | 189 |
|
633 | 190 |
color ~~ last |
191 |
ifTrue: |
|
627 | 192 |
[ |
633 | 193 |
runW ~~ 0 |
194 |
ifTrue: |
|
627 | 195 |
[ |
196 |
|origin| |
|
197 |
origin := (x0 * dotW + margin)@(yy * dotH + margin). |
|
198 |
self fillRectangle: (origin extent: (runW@dotH)). |
|
632 | 199 |
0 to: runW by: dotW do: [:xxx| self drawFrameAt: ((origin x + xxx)@(origin y))]. |
627 | 200 |
maskColor ifTrue: |
201 |
[ |
|
202 |
self drawMaskPointAt: origin |
|
203 |
]. |
|
204 |
runW := 0. |
|
205 |
]. |
|
206 |
||
207 |
self paint: (last := color). |
|
208 |
image mask notNil ifTrue: |
|
209 |
[ |
|
210 |
maskColor := false. |
|
211 |
(image mask colorAt: xx@yy) = Color black ifTrue: |
|
212 |
[ |
|
213 |
self paint: (last := self viewBackground). |
|
214 |
maskColor := true. |
|
215 |
]. |
|
216 |
last := nil. |
|
217 |
]. |
|
218 |
runW := 0. |
|
219 |
x0 := xx. |
|
220 |
]. |
|
221 |
runW := runW + dotW |
|
222 |
]. |
|
223 |
runW ~~ 0 ifTrue: |
|
224 |
[ |
|
225 |
|origin| |
|
226 |
origin := (x0 * dotW + margin)@(lastY * dotH + margin). |
|
227 |
self fillRectangle: (origin extent: runW@dotH). |
|
228 |
0 to: runW by: dotW do: [:xxx| self drawFrameAt: ((origin x + xxx) @origin y)]. |
|
229 |
maskColor ifTrue: |
|
230 |
[ |
|
231 |
self drawMaskPointAt: origin. |
|
232 |
]. |
|
233 |
runW := 0. |
|
234 |
]. |
|
235 |
! |
|
236 |
||
237 |
redrawX:x y:y width:w height:h |
|
636 | 238 |
|
627 | 239 |
|ih iw xI yI| |
240 |
||
241 |
image isNil ifTrue:[^self]. |
|
242 |
||
243 |
self clippingRectangle: (x@y extent: w@h). |
|
244 |
||
245 |
self redrawImageX:x y:y width:w height:h. |
|
246 |
||
247 |
"/ right of image ? |
|
248 |
adjust == #center ifTrue: |
|
249 |
[ |
|
633 | 250 |
xI := (width - ih) // 2 - margin. |
251 |
yI := (height - iw) // 2 - margin. |
|
627 | 252 |
] |
253 |
ifFalse: |
|
254 |
[ |
|
255 |
xI := yI := margin |
|
256 |
]. |
|
257 |
(x + w - 1) > (xI + (magnification x * image width)) ifTrue: |
|
258 |
[ |
|
259 |
self clearRectangleX:(xI + (magnification x * image width)) |
|
260 |
y:y |
|
261 |
width:(x + w - (magnification x * image width) - xI) |
|
262 |
height:h |
|
263 |
]. |
|
264 |
(y + h - 1) > (yI + (magnification y * image height)) ifTrue: |
|
265 |
[ |
|
266 |
self clearRectangleX:margin |
|
267 |
y:(yI + (magnification y * image height)) |
|
268 |
width:w |
|
269 |
height:(y + h - (magnification y * image height) - yI) |
|
270 |
]. |
|
271 |
self drawFrame. |
|
272 |
self clippingRectangle: nil. |
|
273 |
! ! |
|
274 |
||
275 |
!ImageEditView methodsFor:'edit modes'! |
|
276 |
||
277 |
editMode |
|
278 |
||
636 | 279 |
^editMode ? (editMode := 'point') |
627 | 280 |
! |
281 |
||
282 |
editMode:aMode |
|
283 |
||
284 |
editMode := aMode |
|
285 |
! |
|
286 |
||
287 |
mouseKeyColorMode |
|
288 |
||
289 |
^mouseKeyColorMode printString |
|
290 |
! |
|
291 |
||
292 |
mouseKeyColorMode:aMode |
|
293 |
||
294 |
mouseKeyColorMode := aMode asInteger |
|
295 |
! ! |
|
296 |
||
297 |
!ImageEditView methodsFor:'event handling'! |
|
298 |
||
299 |
buttonMotion:state x:x y:y |
|
300 |
||
632 | 301 |
self drawCursorAt: x@y. |
627 | 302 |
self selectedColor notNil & image notNil & (self imageContainsPoint: x@y) & (editMode = 'point') |
303 |
ifTrue: [^self pointAt: x@y]. |
|
624 | 304 |
! |
255 | 305 |
|
627 | 306 |
buttonPress:button x:x y:y |
307 |
||
632 | 308 |
self drawCursorAt: x@y. |
627 | 309 |
self selectedColor notNil & image notNil & (self imageContainsPoint: x@y) |
310 |
ifTrue: |
|
632 | 311 |
[ |
627 | 312 |
undoImage := image copy. |
313 |
mouseKeyColorMode := button. |
|
632 | 314 |
self perform: (editMode, 'At:') asSymbol with: x@y. |
627 | 315 |
]. |
632 | 316 |
! |
317 |
||
318 |
buttonRelease:state x:x y:y |
|
319 |
||
320 |
Cursor normal show |
|
627 | 321 |
! ! |
322 |
||
636 | 323 |
!ImageEditView methodsFor:'image editing'! |
627 | 324 |
|
325 |
boxAt: aPoint |
|
326 |
||
632 | 327 |
|choosedBox| |
636 | 328 |
choosedBox := self drawRectangleStartingAt: aPoint emphasis: #box. |
632 | 329 |
image rectangle: (choosedBox origin//magnification extent: (choosedBox extent//magnification)) withColor: self selectedColor. |
330 |
image restored. |
|
636 | 331 |
self redraw: (choosedBox expandedBy: 1). |
632 | 332 |
modified := true. |
333 |
! |
|
334 |
||
335 |
copyAt: aPoint |
|
336 |
||
337 |
|choosedBox| |
|
636 | 338 |
choosedBox := self drawRectangleStartingAt: aPoint emphasis: #inverseFilledBox. |
632 | 339 |
Clipboard := image subImageIn: (choosedBox origin//magnification extent: (choosedBox extent//magnification)). |
340 |
self redraw: choosedBox |
|
341 |
||
342 |
! |
|
343 |
||
344 |
fillAt: aPoint |
|
627 | 345 |
|
632 | 346 |
Cursor execute showWhile: |
347 |
[ |
|
348 |
|filledPoints| |
|
349 |
filledPoints := image floodFillAt: aPoint//magnification withColor: self selectedColor. |
|
350 |
image restored. |
|
633 | 351 |
filledPoints size < 300 |
632 | 352 |
ifTrue: |
353 |
[ |
|
636 | 354 |
filledPoints do: [:p| Delay waitForMilliseconds:0.7. self redraw: ((p * magnification extent: magnification) expandedBy: 1)] |
632 | 355 |
] |
356 |
ifFalse: |
|
357 |
[ |
|
358 |
self invalidate |
|
359 |
]. |
|
360 |
modified := true |
|
361 |
] |
|
362 |
! |
|
363 |
||
364 |
filledBoxAt: aPoint |
|
365 |
||
366 |
|choosedBox| |
|
636 | 367 |
choosedBox := self drawRectangleStartingAt: aPoint emphasis: #filledBox. |
632 | 368 |
image fillRectangle: (choosedBox origin//magnification extent: (choosedBox extent//magnification)) withColor: self selectedColor. |
369 |
image restored. |
|
636 | 370 |
self redraw: (choosedBox expandedBy: 1). |
632 | 371 |
modified := true. |
372 |
! |
|
373 |
||
636 | 374 |
flipHorizontal |
375 |
||
376 |
undoImage := image copy. |
|
377 |
self image: image flipHorizontal |
|
378 |
||
379 |
! |
|
380 |
||
381 |
flipVertical |
|
382 |
||
383 |
undoImage := image copy. |
|
384 |
self image: image flipVertical |
|
385 |
||
386 |
! |
|
387 |
||
388 |
magnifyImage |
|
389 |
||
390 |
|box newSize| |
|
391 |
box := EnterBox new. |
|
392 |
box title:'Image new size:'. |
|
393 |
box okText:'OK'. |
|
394 |
box abortText:'Cancel'. |
|
395 |
box initialText:image extent printString. |
|
396 |
box showAtPointer. |
|
397 |
(box accepted and: [(newSize := Object readFromString: box contents onError:nil) notNil]) |
|
398 |
ifTrue: |
|
399 |
[ |
|
400 |
undoImage := image copy. |
|
401 |
self image: (image magnifiedBy: newSize/image extent) |
|
402 |
]. |
|
403 |
! |
|
404 |
||
405 |
negativeImage |
|
406 |
||
407 |
undoImage := image copy. |
|
408 |
self image: image negative |
|
409 |
||
410 |
! |
|
411 |
||
412 |
pasteAt: aPoint |
|
413 |
||
414 |
Object errorSignal handle: |
|
415 |
[:ex| |
|
416 |
self warn: 'Pasting at selected point failed!!' |
|
417 |
] |
|
418 |
do: |
|
419 |
[ |
|
420 |
|imagePoint| |
|
421 |
imagePoint := aPoint//magnification. |
|
422 |
image copyFrom: Clipboard x:0 y:0 toX: imagePoint x y: imagePoint y width: Clipboard width height: Clipboard height. |
|
423 |
image restored. |
|
424 |
self redraw: ((imagePoint * magnification extent: (Clipboard extent * magnification)) expandedBy: 1@1). |
|
425 |
self drawLabel: imagePoint. |
|
426 |
modified := true. |
|
427 |
] |
|
428 |
! |
|
429 |
||
430 |
pointAt: aPoint |
|
431 |
||
432 |
|imagePoint| |
|
433 |
imagePoint := aPoint//magnification. |
|
434 |
image atImageAndMask: imagePoint put: self selectedColor. |
|
435 |
image restored. |
|
436 |
self redraw: ((imagePoint * magnification extent: magnification) expandedBy: 1). |
|
437 |
self drawLabel: imagePoint. |
|
438 |
modified := true. |
|
439 |
||
440 |
! |
|
441 |
||
442 |
resizeImage |
|
443 |
||
444 |
|box newSize| |
|
445 |
box := EnterBox new. |
|
446 |
box title:'Image new size:'. |
|
447 |
box okText:'OK'. |
|
448 |
box abortText:'Cancel'. |
|
449 |
box initialText:image extent printString. |
|
450 |
box showAtPointer. |
|
451 |
(box accepted and: [(newSize := Object readFromString: box contents onError:nil) notNil]) |
|
452 |
ifTrue: |
|
453 |
[ |
|
454 |
|newImage| |
|
455 |
undoImage := image copy. |
|
456 |
newImage := image class width: newSize x height: newSize y depth: image depth. |
|
457 |
newImage photometric:image photometric. |
|
458 |
newImage colorMap:image colorMap copy. |
|
459 |
newImage bits: (ByteArray new: newImage bytesPerRow * newSize y). |
|
460 |
||
461 |
image mask notNil |
|
462 |
ifTrue: |
|
463 |
[ |
|
464 |
|newMaskImage| |
|
465 |
newMaskImage := Depth1Image width: newSize x height: newSize y. |
|
466 |
newMaskImage photometric: image mask photometric. |
|
467 |
newMaskImage colorMap: image mask colorMap copy. |
|
468 |
newMaskImage bits:(ByteArray new: newMaskImage bytesPerRow * newSize y). |
|
469 |
newImage mask: newMaskImage |
|
470 |
]. |
|
471 |
||
472 |
newImage copyFrom:image x:0 y:0 toX:0 y:0 width: (image width min:newSize x) height: (image height min:newSize y). |
|
473 |
self image: newImage |
|
474 |
]. |
|
475 |
! |
|
476 |
||
477 |
rotateImage |
|
478 |
||
479 |
|box rotation| |
|
480 |
box := EnterBox new. |
|
481 |
box title:'Image new rotation:'. |
|
482 |
box okText:'OK'. |
|
483 |
box abortText:'Cancel'. |
|
484 |
box initialText: '0'. |
|
485 |
box showAtPointer. |
|
486 |
(box accepted and: [(rotation := Object readFromString: box contents onError:nil) notNil]) |
|
487 |
ifTrue: |
|
488 |
[ Object errorSignal handle: |
|
489 |
[:ex| |
|
490 |
self warn: 'Image rotation failed.\' withCRs, 'An increase of image depth could help.'. |
|
491 |
] |
|
492 |
do: |
|
493 |
[ |
|
494 |
undoImage := image copy. |
|
495 |
self image: (image hardRotated: rotation) |
|
496 |
] |
|
497 |
]. |
|
498 |
! |
|
499 |
||
500 |
undo |
|
501 |
||
502 |
undoImage notNil |
|
503 |
ifTrue: |
|
504 |
[ |
|
505 |
modified := false. |
|
506 |
self image: undoImage. |
|
507 |
self invalidate |
|
508 |
] |
|
509 |
! ! |
|
510 |
||
511 |
!ImageEditView methodsFor:'image emphasis'! |
|
512 |
||
513 |
drawCursorAt: aPoint |
|
514 |
||
515 |
image isNil ifTrue: [^Cursor stop show]. |
|
516 |
((0@0 extent: image extent * magnification) containsPoint: aPoint) |
|
517 |
ifFalse:[Cursor stop show] |
|
518 |
ifTrue: [Cursor crossHair show]. |
|
519 |
||
520 |
! |
|
521 |
||
522 |
drawFrame |
|
523 |
||
524 |
self paint:Color black. |
|
525 |
self lineWidth: (magnification x//3 min: 3). |
|
526 |
self displayRectangle: ((0@0) extent:(image extent * magnification) + 2). |
|
527 |
self lineWidth:1. |
|
528 |
! |
|
529 |
||
530 |
drawFrameAt: aPoint |
|
531 |
||
532 |
magnification > gridMagnification |
|
533 |
ifTrue: |
|
534 |
[ |
|
535 |
|lineStartingPoint lineEndingPoint oldColor| |
|
536 |
lineStartingPoint := aPoint//magnification*magnification. |
|
537 |
lineEndingPoint := aPoint//magnification*magnification + magnification. |
|
538 |
oldColor := self paint. |
|
539 |
self xoring: |
|
540 |
[ |
|
541 |
self displayLineFrom: lineEndingPoint |
|
542 |
to: (lineEndingPoint x)@(lineStartingPoint y). |
|
543 |
self displayLineFrom: lineEndingPoint |
|
544 |
to: (lineStartingPoint x)@(lineEndingPoint y). |
|
545 |
]. |
|
546 |
self paint: oldColor. |
|
547 |
] |
|
548 |
! |
|
549 |
||
550 |
drawLabel: aLabel |
|
551 |
||
552 |
coordInfoBlock notNil |
|
553 |
ifTrue: |
|
554 |
[ |
|
555 |
coordInfoBlock value: aLabel printString |
|
556 |
] |
|
557 |
! |
|
558 |
||
559 |
drawMaskPointAt: aPoint |
|
560 |
||
561 |
|sizeOfMaskPoint| |
|
562 |
sizeOfMaskPoint := magnification//3. |
|
563 |
self xoring: [self fillRectangle: (aPoint + sizeOfMaskPoint extent: sizeOfMaskPoint)]. |
|
564 |
||
565 |
! |
|
566 |
||
567 |
drawRectangleStartingAt: aPoint emphasis: emphasis |
|
632 | 568 |
|
633 | 569 |
|currentPoint currentExtent firstPoint lastCurrentPoint gridCorrection p| |
632 | 570 |
firstPoint := currentPoint := lastCurrentPoint := aPoint//magnification*magnification. |
636 | 571 |
magnification > gridMagnification ifFalse: [gridCorrection := 0] ifTrue: [gridCorrection := 1]. |
627 | 572 |
[Display anyButtonPressed] |
573 |
whileTrue: |
|
574 |
[ |
|
632 | 575 |
currentPoint := (0@0) max: (image extent * magnification min: (p := self translation negated + (device translatePoint: self sensor mousePoint from:device rootView id to:self id))). |
627 | 576 |
currentPoint := currentPoint//magnification*magnification. |
577 |
currentExtent := (firstPoint - currentPoint) abs. |
|
632 | 578 |
self drawCursorAt: p. |
579 |
||
627 | 580 |
currentPoint ~= lastCurrentPoint ifTrue: |
632 | 581 |
[ |
627 | 582 |
self redraw: ((firstPoint min: lastCurrentPoint) - 1 extent: (firstPoint - lastCurrentPoint) abs + 2). |
632 | 583 |
emphasis = #inverseFilledBox |
627 | 584 |
ifTrue: |
585 |
[ |
|
633 | 586 |
self xoring: [self fillRectangle: ((firstPoint min: currentPoint) + 1 extent: currentExtent - gridCorrection)] |
627 | 587 |
]. |
632 | 588 |
emphasis = #box |
627 | 589 |
ifTrue: |
590 |
[ |
|
591 |
self selectedColor ~= Color noColor |
|
592 |
ifTrue: [self paint: self selectedColor] |
|
593 |
ifFalse: [self paint: self viewBackground]. |
|
632 | 594 |
self lineWidth: magnification x. |
633 | 595 |
self displayRectangle: ((firstPoint min: currentPoint) + (magnification x//2) + 1 extent: (currentExtent - (magnification x)) - gridCorrection + 1). |
632 | 596 |
self lineWidth: 1. |
597 |
]. |
|
598 |
emphasis = #filledBox |
|
599 |
ifTrue: |
|
600 |
[ |
|
601 |
self selectedColor ~= Color noColor |
|
602 |
ifTrue: [self paint: self selectedColor] |
|
603 |
ifFalse: [self paint: self viewBackground]. |
|
633 | 604 |
self fillRectangle: ((firstPoint min: currentPoint) + 1 extent: currentExtent - gridCorrection). |
632 | 605 |
]. |
627 | 606 |
]. |
607 |
self drawLabel: currentPoint//magnification. |
|
608 |
lastCurrentPoint := currentPoint. |
|
609 |
]. |
|
632 | 610 |
Cursor normal show. |
611 |
^(firstPoint min: currentPoint) extent: (firstPoint - currentPoint) abs |
|
627 | 612 |
! ! |
613 |
||
614 |
!ImageEditView methodsFor:'image setting'! |
|
615 |
||
616 |
image:anImage |
|
617 |
||
618 |
(anImage isImage and: [image isNil or: [self checkModified]]) |
|
619 |
ifTrue: |
|
620 |
[ |
|
621 |
super image: anImage. |
|
622 |
^self |
|
623 |
]. |
|
624 |
^nil |
|
625 |
! |
|
626 |
||
627 |
loadFromFile: aFileName |
|
624 | 628 |
|
629 |
Object errorSignal handle: |
|
630 |
[:exeption| |
|
632 | 631 |
self warn: exeption errorString. |
624 | 632 |
^nil |
633 |
] |
|
634 |
do: |
|
633 | 635 |
[ |
632 | 636 |
(self image: (Image fromFile: aFileName)) notNil |
637 |
ifTrue: |
|
638 |
[ |
|
639 |
imageReaderClass := ImageReader allSubclasses |
|
640 |
detect: [:cls| cls isValidImageFile: aFileName] |
|
641 |
ifNone: [self error: 'Unknown image file format!!'] |
|
642 |
] |
|
643 |
ifFalse: |
|
644 |
[ |
|
645 |
self error: 'Image on file not found!!' |
|
646 |
] |
|
647 |
] |
|
624 | 648 |
! |
255 | 649 |
|
633 | 650 |
loadFromMessage: aMessage |
651 |
||
652 |
(self resourceMessage: aMessage) isNil |
|
653 |
ifTrue: |
|
654 |
[ |
|
655 |
^nil |
|
656 |
]. |
|
624 | 657 |
|
633 | 658 |
^self loadfromClass: resourceClass andSelector: resourceSelector |
659 |
||
660 |
||
661 |
! |
|
662 |
||
663 |
loadfromClass: aClassOrSymbol andSelector: aStringOrSymbol |
|
664 |
||
665 |
|aClass| |
|
627 | 666 |
imageReaderClass := nil. |
667 |
self resourceClass: aClassOrSymbol. |
|
668 |
self resourceSelector: aStringOrSymbol. |
|
669 |
aClass := Smalltalk at: resourceClass. |
|
670 |
(aClass isClass and: [aClass class implements: resourceSelector]) |
|
624 | 671 |
ifTrue: |
672 |
[ |
|
627 | 673 |
^self image: (aClass perform: resourceSelector) copy |
624 | 674 |
]. |
633 | 675 |
self warn: 'No class or selector for evaluation detected!!'. |
624 | 676 |
^nil |
161 | 677 |
! ! |
678 |
||
1 | 679 |
!ImageEditView methodsFor:'initialization'! |
680 |
||
161 | 681 |
initialize |
624 | 682 |
|
161 | 683 |
super initialize. |
627 | 684 |
|
161 | 685 |
magnification := 1@1. |
627 | 686 |
gridMagnification := 8@8. |
687 |
modified := false. |
|
688 |
mouseKeyColorMode := 1. |
|
689 |
resourceClass := resourceSelector := ''. |
|
690 |
selectColors := Array with: nil with: nil. |
|
1 | 691 |
! ! |
692 |
||
636 | 693 |
!ImageEditView methodsFor:'printing & storing'! |
1 | 694 |
|
636 | 695 |
loadFromInClassesOf: aSuperclassOrSymbol |
404 | 696 |
|
636 | 697 |
self loadFromMessage: |
698 |
(ResourceSelectionBrowser |
|
699 |
request: 'Load From Image Resource Method' |
|
700 |
onSuperclass: aSuperclassOrSymbol |
|
701 |
andClass: self resourceClass |
|
702 |
andSelector: self resourceSelector |
|
703 |
withResourceTypes: #(image fileImage)) |
|
704 |
||
477 | 705 |
|
161 | 706 |
! |
707 |
||
627 | 708 |
|
624 | 709 |
|
636 | 710 |
|stream| |
627 | 711 |
image isNil ifTrue: [^nil]. |
636 | 712 |
Printer supportsPostscript ifFalse: |
713 |
[ |
|
714 |
^self warn:'No postscript printer detected!!' |
|
362 | 715 |
]. |
716 |
stream := Printer newNative. |
|
636 | 717 |
stream isNil ifTrue: |
718 |
[ |
|
719 |
^self warn:'Cannot open printer stream!!'. |
|
362 | 720 |
]. |
636 | 721 |
self withWaitCursorDo: |
722 |
[ |
|
723 |
|psgc| |
|
724 |
psgc := PSGraphicsContext on:stream. |
|
627 | 725 |
psgc displayForm: (image magnifiedBy: magnification) x:0 y:0. |
398
7b7255a4db0d
show a wait cursor while printing
Claus Gittinger <cg@exept.de>
parents:
362
diff
changeset
|
726 |
psgc close. |
7b7255a4db0d
show a wait cursor while printing
Claus Gittinger <cg@exept.de>
parents:
362
diff
changeset
|
727 |
] |
624 | 728 |
! |
729 |
||
730 |
save |
|
731 |
||
632 | 732 |
self saveImageOrMask: #image. |
733 |
||
624 | 734 |
! |
735 |
||
297 | 736 |
saveAs |
737 |
"save contents into a file |
|
738 |
- ask user for filename using a fileSelectionBox." |
|
739 |
||
627 | 740 |
self saveImageFileAs |
297 | 741 |
! |
742 |
||
627 | 743 |
saveImageFileAs |
744 |
||
633 | 745 |
self saveImageFileAs: |
746 |
(FileSelectionBrowser |
|
636 | 747 |
request: 'Save Image As' |
748 |
fileName: self image fileName |
|
633 | 749 |
fileFilters: FileSelectionBrowser saveImageFileNameFilters) |
627 | 750 |
! |
297 | 751 |
|
627 | 752 |
saveImageFileAs: aFileName |
297 | 753 |
|
633 | 754 |
aFileName isNil ifTrue: [^nil]. |
636 | 755 |
image notNil |
627 | 756 |
ifTrue: |
757 |
[ |
|
758 |
image fileName: aFileName. |
|
632 | 759 |
self saveImageOrMask: #image |
760 |
] |
|
761 |
ifFalse: |
|
762 |
[ |
|
633 | 763 |
self warn: 'No image or file name for saving detected!!' |
632 | 764 |
] |
765 |
! |
|
766 |
||
767 |
saveImageMaskFileAs |
|
768 |
||
633 | 769 |
self saveImageMaskFileAs: |
636 | 770 |
(FileSelectionBrowser |
771 |
request: 'Save Image Mask As' |
|
772 |
fileName: self image fileName |
|
633 | 773 |
fileFilters: FileSelectionBrowser saveImageFileNameFilters) |
632 | 774 |
! |
775 |
||
776 |
saveImageMaskFileAs: aFileName |
|
777 |
||
633 | 778 |
aFileName isNil ifTrue: [^nil]. |
632 | 779 |
(image notNil and: [image mask notNil]) |
780 |
ifTrue: |
|
781 |
[ |
|
782 |
image mask fileName: aFileName. |
|
783 |
self saveImageOrMask: #mask |
|
627 | 784 |
] |
785 |
ifFalse: |
|
786 |
[ |
|
632 | 787 |
self warn: 'No image or image mask detected!!' |
627 | 788 |
] |
628 | 789 |
! |
790 |
||
632 | 791 |
saveImageOrMask: what |
628 | 792 |
|
632 | 793 |
Object errorSignal handle: |
794 |
[:ex| |
|
795 |
self warn: ex errorString. |
|
796 |
^nil |
|
797 |
] |
|
798 |
do: |
|
799 |
[ |
|
800 |
|fileName| |
|
801 |
image isNil ifTrue: [^self error: 'No image to save!!']. |
|
802 |
what = #image |
|
803 |
ifTrue: |
|
804 |
[ |
|
805 |
image fileName isNil ifTrue: [^self error: 'No file name for image detected!!']. |
|
806 |
fileName := image fileName asFilename |
|
807 |
]. |
|
808 |
what = #mask |
|
809 |
ifTrue: |
|
810 |
[ |
|
811 |
image mask isNil ifTrue: [^self error: 'No image mask to save!!']. |
|
812 |
image mask fileName isNil ifTrue: [^self error: 'No file name for image mask detected!!']. |
|
813 |
fileName := image mask fileName asFilename |
|
814 |
]. |
|
815 |
(fileName suffix = 'tiff') | (fileName suffix = 'tif') ifTrue: [imageReaderClass := TIFFReader]. |
|
816 |
fileName suffix = 'xpm' ifTrue: [imageReaderClass := XPMReader]. |
|
817 |
fileName suffix = 'xbm' ifTrue: [imageReaderClass := XBMReader]. |
|
818 |
fileName suffix = 'gif' ifTrue: [self halt. imageReaderClass := GIFReader]. |
|
819 |
(fileName suffix = 'jpg') | (fileName suffix = 'jpeg') ifTrue: [imageReaderClass := JPEGReader]. |
|
820 |
imageReaderClass isNil ifTrue: [imageReaderClass := XPMReader. image fileName: image fileName, '.xpm']. |
|
821 |
what = #image ifTrue: [image saveOn: image fileName using: imageReaderClass. modified := false]. |
|
822 |
what = #mask ifTrue: [image mask saveOn: image mask fileName using: imageReaderClass]. |
|
823 |
] |
|
824 |
||
825 |
||
633 | 826 |
! |
827 |
||
828 |
saveMethod |
|
829 |
||
830 |
Object errorSignal handle: |
|
831 |
[:ex| |
|
832 |
self warn: ex errorString. |
|
833 |
^nil |
|
834 |
] |
|
835 |
do: |
|
836 |
[ |
|
837 |
|imageStoreStream cls| |
|
838 |
(self resourceSelector trimBlanks size = 0) | (cls := Smalltalk at: self resourceClass) isClass not |
|
839 |
ifTrue: [^self error: 'No class and selector for image detected!!']. |
|
840 |
self image storeOn: (imageStoreStream := WriteStream on: ''). |
|
841 |
ByteCodeCompiler |
|
842 |
compile: (self resourceSelector, |
|
843 |
'\' withCRs, ' "ImageEditor openOnClass:self andSelector:#', self resourceSelector, '"', |
|
844 |
'\\' withCRs, ' <resource: #image>\' withCRs, ' ^', imageStoreStream contents) |
|
845 |
forClass: cls class inCategory: 'resources'. |
|
846 |
modified := false. |
|
847 |
] |
|
848 |
! |
|
849 |
||
850 |
saveMethodAs |
|
851 |
||
636 | 852 |
(self resourceMessage: |
853 |
(ResourceSelectionBrowser |
|
854 |
request: 'Save On Image Resource Selector' |
|
855 |
onSuperclass: #ApplicationModel |
|
856 |
andClass: self resourceClass |
|
857 |
andSelector: self resourceSelector |
|
858 |
withResourceTypes: #(image fileImage))) notNil |
|
633 | 859 |
ifTrue: |
860 |
[ |
|
861 |
^self saveMethod |
|
862 |
]. |
|
863 |
^nil |
|
1 | 864 |
! ! |
865 |
||
161 | 866 |
!ImageEditView methodsFor:'queries'! |
5 | 867 |
|
161 | 868 |
heightOfContents |
869 |
||
870 |
image isNil ifTrue:[^ 0]. |
|
871 |
^ (image height * magnification y) rounded |
|
5 | 872 |
! |
873 |
||
627 | 874 |
imageContainsPoint: aPoint |
632 | 875 |
|
876 |
^image notNil and: |
|
877 |
[((0@0 corner:(image extent) - 1) containsPoint: (((aPoint - margin + 1) / magnification) floor))] |
|
627 | 878 |
! |
879 |
||
161 | 880 |
widthOfContents |
5 | 881 |
|
161 | 882 |
image isNil ifTrue:[^ 0]. |
883 |
^ (image width * magnification x) rounded |
|
5 | 884 |
! ! |
885 |
||
627 | 886 |
!ImageEditView methodsFor:'release'! |
887 |
||
888 |
destroy |
|
889 |
||
890 |
undoImage := nil. |
|
891 |
Clipboard := nil. |
|
892 |
super destroy. |
|
893 |
||
894 |
! ! |
|
895 |
||
632 | 896 |
!ImageEditView methodsFor:'testing'! |
897 |
||
898 |
checkModified |
|
899 |
||
900 |
modified |
|
901 |
ifTrue: |
|
902 |
[ |
|
903 |
((YesNoBox title:'Image was modified!!') |
|
904 |
noText:'Cancel'; |
|
905 |
yesText:'Waste it and proceed'; |
|
906 |
showAtPointer; |
|
907 |
accepted) ifFalse: [^false]. |
|
908 |
modified := false |
|
909 |
]. |
|
910 |
^true |
|
911 |
! ! |
|
912 |
||
255 | 913 |
!ImageEditView class methodsFor:'documentation'! |
161 | 914 |
|
915 |
version |
|
636 | 916 |
^ '$Header: /cvs/stx/stx/libwidg2/ImageEditView.st,v 1.53 1997-12-21 21:59:57 tz Exp $' |
161 | 917 |
! ! |