1 /*
2     PPCanvasView.h
3 
4     Copyright 2013-2018,2020 Josh Freeman
5     http://www.twilightedge.com
6 
7     This file is part of PikoPixel for Mac OS X and GNUstep.
8     PikoPixel is a graphical application for drawing & editing pixel-art images.
9 
10     PikoPixel is free software: you can redistribute it and/or modify it under
11     the terms of the GNU Affero General Public License as published by the
12     Free Software Foundation, either version 3 of the License, or (at your
13     option) any later version approved for PikoPixel by its copyright holder (or
14     an authorized proxy).
15 
16     PikoPixel is distributed in the hope that it will be useful, but WITHOUT ANY
17     WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18     FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
19     details.
20 
21     You should have received a copy of the GNU Affero General Public License
22     along with this program. If not, see <http://www.gnu.org/licenses/>.
23 */
24 
25 #import <Cocoa/Cocoa.h>
26 #import "PPGridType.h"
27 #import "PPDocumentTypes.h"
28 #import "PPBitmapPixelTypes.h"
29 
30 
31 @class PPGridPattern;
32 
33 @interface PPCanvasView : NSView
34 {
35     NSBitmapImageRep *_canvasBitmap;
36 
37     float _zoomFactor;
38     float _inverseZoomFactor;
39 
40     NSPoint _canvasDrawingOffset;
41 
42     NSRect _canvasFrame;
43     NSRect _zoomedCanvasFrame;
44     NSRect _offsetZoomedCanvasFrame;
45 
46     NSRect _clipViewVisibleRect;
47 
48     NSRect _visibleCanvasBounds;
49     NSRect _zoomedVisibleCanvasBounds;
50     NSRect _offsetZoomedVisibleCanvasBounds;
51 
52     NSSize _zoomedVisibleImagesSize;
53 
54     NSBitmapImageRep *_zoomedVisibleCanvasBitmap;
55     NSImage *_zoomedVisibleCanvasImage;
56 
57     NSBitmapImageRep *_zoomedVisibleBackgroundBitmap;
58     NSImage *_zoomedVisibleBackgroundImage;
59 
60     NSImage *_backgroundImage;
61     NSColor *_backgroundColor;
62 
63 #if PP_DEPLOYMENT_TARGET_SUPPORTS_RETINA_DISPLAY
64 
65     NSBitmapImageRep *_retinaDisplayBuffer;
66 
67 #endif  // PP_DEPLOYMENT_TARGET_SUPPORTS_RETINA_DISPLAY
68 
69     PPGridType _gridType;
70     PPImageBitmapPixel _gridColorPixelValue;
71     NSSize _gridGuidelineSpacingSize;
72     PPImageBitmapPixel _gridGuidelineColorPixelValue;
73     NSPoint _gridGuidelinesTopLeftPhase;
74 
75     NSBezierPath *_selectionOutlineTopRightPath;
76     NSBezierPath *_selectionOutlineBottomLeftPath;
77     NSBezierPath *_selectionOutlineRightEdgePath;
78     NSBezierPath *_selectionOutlineBottomEdgePath;
79 
80     NSBezierPath *_zoomedSelectionOutlineTopRightPath;
81     NSBezierPath *_zoomedSelectionOutlineBottomLeftPath;
82     NSRect _zoomedSelectionOutlineDisplayBounds;
83 
84     NSTimer *_selectionOutlineAnimationTimer;
85     NSPoint _selectionOutlineTopRightAnimationPhase;
86     NSPoint _selectionOutlineBottomLeftAnimationPhase;
87 
88     NSBezierPath *_selectionToolOverlayPath_Working;
89     NSBezierPath *_selectionToolOverlayPath_AddFill;
90     NSBezierPath *_selectionToolOverlayPath_SubtractFill;
91     NSBezierPath *_selectionToolOverlayPath_ToolPath;
92     NSBezierPath *_selectionToolOverlayPath_Outline;
93     NSBitmapImageRep *_selectionToolOverlayWorkingMask;
94     NSBitmapImageRep *_selectionToolOverlayWorkingPathMask;
95     NSTimer *_selectionToolOverlayAnimationTimer;
96     NSDate *_selectionToolOverlayAnimationStartDate;
97     NSPoint _selectionToolOverlayAnimationPhase;
98     NSRect _selectionToolOverlayDisplayBounds;
99 
100     NSBezierPath *_eraserToolOverlayPath_Outline;
101     NSRect _eraserToolOverlayDisplayBounds;
102 
103     NSBezierPath *_fillToolOverlayPath_Fill;
104     NSBezierPath *_fillToolOverlayPath_Outline;
105     NSRect _fillToolOverlayDisplayBounds;
106     NSColor *_fillToolOverlayPatternColor;
107     NSPoint _fillToolOverlayPatternPhase;
108 
109     NSRect _magnifierToolOverlayRect;
110     NSBezierPath *_magnifierToolOverlayRectPath;
111 
112     NSBezierPath *_colorRampToolOverlayPath_Outline;
113     NSBezierPath *_colorRampToolOverlayPath_XMarks;
114     NSRect _colorRampToolOverlayDisplayBounds;
115 
116     NSPoint _matchToolToleranceIndicatorOrigin;
117     unsigned _matchToolToleranceIndicatorRadius;
118     NSBezierPath *_matchToolToleranceIndicatorPath;
119     NSRect _matchToolToleranceIndicatorDisplayBounds;
120 
121     NSCursor *_toolCursor;
122 
123     NSRect _viewBoundsTrackingRect;
124     NSTrackingRectTag _viewBoundsTrackingRectTag;
125 
126     NSRect _visibleCanvasTrackingRect;
127     NSTrackingRectTag _visibleCanvasTrackingRectTag;
128 
129     NSTimer *_autoscrollRepeatTimer;
130     NSEvent *_autoscrollMouseDraggedEvent;
131 
132     int _zoomedImagesDrawMode;
133 
134     bool _shouldDisplayDocumentLayers;
135     bool _shouldDisplayGrid;
136     bool _shouldDisplayGridGuidelines;
137     bool _shouldDisplayBackgroundImage;
138     bool _shouldSmoothenBackgroundImage;
139     bool _disallowBackgroundImageSmoothingForScrolling;
140     bool _shouldDisplaySelectionToolOverlay;
141     bool _shouldDisplayEraserToolOverlay;
142     bool _shouldDisplayFillToolOverlay;
143     bool _shouldDisplayMagnifierToolOverlay;
144     bool _shouldDisplayColorRampToolOverlay;
145     bool _shouldDisplayMatchToolToleranceIndicator;
146 
147     bool _backgroundImageIsOpaque;
148 
149     bool _isDraggingTool;
150 
151     bool _allowSkippingOfMouseDraggedEvents;
152 
153     bool _autoscrollingIsEnabled;
154     bool _isAutoscrolling;
155 
156     bool _isScrolling;
157 
158     bool _mouseIsInsideVisibleCanvasTrackingRect;
159 
160     bool _disallowMouseTracking;
161 
162     bool _hasSelectionOutline;
163     bool _shouldHideSelectionOutline;
164     bool _shouldAnimateSelectionOutline;
165 
166 #if PP_DEPLOYMENT_TARGET_SUPPORTS_RETINA_DISPLAY
167 
168     bool _currentDisplayIsRetina;
169 
170 #endif  // PP_DEPLOYMENT_TARGET_SUPPORTS_RETINA_DISPLAY
171 }
172 
173 - (void) setCanvasBitmap: (NSBitmapImageRep *) canvasBitmap;
174 
175 - (void) setBackgroundImage: (NSImage *) backgroundImage
176             backgroundImageVisibility: (bool) shouldDisplayBackgroundImage
177             backgroundImageSmoothing: (bool) shouldSmoothenBackgroundImage
178             backgroundColor: (NSColor *) backgroundColor;
179 
180 - (void) setBackgroundImage: (NSImage *) backgroundImage;
181 - (void) setBackgroundImageVisibility: (bool) shouldDisplayBackgroundImage;
182 - (void) setBackgroundImageSmoothing: (bool) shouldSmoothenBackgroundImage;
183 - (void) setBackgroundColor: (NSColor *) backgroundColor;
184 
185 - (void) disableBackgroundImageSmoothingForScrollingBegin;
186 - (void) updateBackgroundImageSmoothingForScrollingEnd;
187 
188 - (void) setGridPattern: (PPGridPattern *) gridPattern
189             gridVisibility: (bool) shouldDisplayGrid;
190 
191 - (void) setDocumentLayersVisibility: (bool) shouldDisplayDocumentLayers;
192 - (bool) documentLayersAreHidden;
193 
194 - (void) handleUpdateToCanvasBitmapInRect: (NSRect) updateRect;
195 
196 - (NSRect) normalizedVisibleBounds;
197 
198 - (NSPoint) imagePointAtCenterOfVisibleCanvas;
199 - (void) centerEnclosingScrollViewAtImagePoint: (NSPoint) centerPoint;
200 
201 - (bool) windowPointIsInsideVisibleCanvas: (NSPoint) windowPoint;
202 - (NSPoint) imagePointFromViewPoint: (NSPoint) viewPoint
203                 clippedToCanvasBounds: (bool) shouldClipToCanvasBounds;
204 - (NSPoint) viewPointClippedToCanvasBounds: (NSPoint) viewPoint;
205 
206 - (float) zoomFactor;
207 - (void) setZoomFactor: (float) zoomFactor;
208 
209 - (bool) canIncreaseZoomFactor;
210 - (void) increaseZoomFactor;
211 
212 - (bool) canDecreaseZoomFactor;
213 - (void) decreaseZoomFactor;
214 
215 - (void) setZoomToFitCanvas;
216 - (void) setZoomToFitViewRect: (NSRect) rect;
217 
218 - (void) setIsDraggingTool: (bool) isDraggingTool;
219 
220 - (void) enableSkippingOfMouseDraggedEvents: (bool) allowSkippingOfMouseDraggedEvents;
221 
222 @end
223 
224 @interface PPCanvasView (SelectionOutline)
225 
226 + (void) initializeSelectionOutline;
227 
228 - (bool) initSelectionOutlineMembers;
229 - (void) deallocSelectionOutlineMembers;
230 
231 - (void) setSelectionOutlineToMask: (NSBitmapImageRep *) selectionMask
232             maskBounds: (NSRect) maskBounds;
233 
234 - (void) setShouldHideSelectionOutline: (bool) shouldHideSelectionOutline;
235 - (void) setShouldAnimateSelectionOutline: (bool) shouldAnimateSelectionOutline;
236 
237 - (void) updateSelectionOutlineForCurrentVisibleCanvas;
238 
239 - (void) drawSelectionOutline;
240 
241 @end
242 
243 @interface PPCanvasView (SelectionToolOverlay)
244 
245 + (void) initializeSelectionToolOverlay;
246 
247 - (bool) initSelectionToolOverlayMembers;
248 - (void) deallocSelectionToolOverlayMembers;
249 
250 - (bool) resizeSelectionToolOverlayMasksToSize: (NSSize) size;
251 
252 - (void) setSelectionToolOverlayToRect: (NSRect) rect
253             selectionMode: (PPSelectionMode) selectionMode
254             intersectMask: (NSBitmapImageRep *) intersectMask
255             toolPathRect: (NSRect) toolPathRect;
256 
257 - (void) setSelectionToolOverlayToPath: (NSBezierPath *) path
258             selectionMode: (PPSelectionMode) selectionMode
259             intersectMask: (NSBitmapImageRep *) intersectMask;
260 
261 - (void) setSelectionToolOverlayToMask: (NSBitmapImageRep *) maskBitmap
262             maskBounds: (NSRect) maskBounds
263             selectionMode: (PPSelectionMode) selectionMode
264             intersectMask: (NSBitmapImageRep *) intersectMask;
265 
266 - (void) clearSelectionToolOverlay;
267 
268 - (void) drawSelectionToolOverlay;
269 
270 @end
271 
272 @interface PPCanvasView (EraserToolOverlay)
273 
274 + (void) initializeEraserToolOverlay;
275 
276 - (bool) initEraserToolOverlayMembers;
277 - (void) deallocEraserToolOverlayMembers;
278 
279 - (void) setEraserToolOverlayToMask: (NSBitmapImageRep *) maskBitmap
280             maskBounds: (NSRect) maskBounds;
281 
282 - (void) clearEraserToolOverlay;
283 
284 - (void) drawEraserToolOverlay;
285 
286 @end
287 
288 @interface PPCanvasView (FillToolOverlay)
289 
290 + (void) initializeFillToolOverlay;
291 
292 - (bool) initFillToolOverlayMembers;
293 - (void) deallocFillToolOverlayMembers;
294 
295 - (void) beginFillToolOverlayForOperationTarget: (PPLayerOperationTarget) operationTarget
296             fillColor: (NSColor *) flllColor;
297 
298 - (void) setFillToolOverlayToMask: (NSBitmapImageRep *) maskBitmap
299             maskBounds: (NSRect) maskBounds;
300 
301 - (void) endFillToolOverlay;
302 
303 - (void) drawFillToolOverlay;
304 
305 @end
306 
307 @interface PPCanvasView (MagnifierToolOverlay)
308 
309 + (void) initializeMagnifierToolOverlay;
310 
311 - (bool) initMagnifierToolOverlayMembers;
312 - (void) deallocMagnifierToolOverlayMembers;
313 
314 - (void) setMagnifierToolOverlayToViewRect: (NSRect) rect;
315 
316 - (void) clearMagnifierToolOverlay;
317 
318 - (void) drawMagnifierToolOverlay;
319 
320 @end
321 
322 @interface PPCanvasView (ColorRampToolOverlay)
323 
324 + (void) initializeColorRampToolOverlay;
325 
326 - (bool) initColorRampToolOverlayMembers;
327 - (void) deallocColorRampToolOverlayMembers;
328 
329 - (void) setColorRampToolOverlayToMask: (NSBitmapImageRep *) maskBitmap
330             maskBounds: (NSRect) maskBounds;
331 
332 - (void) clearColorRampToolOverlay;
333 
334 - (void) drawColorRampToolOverlay;
335 
336 @end
337 
338 @interface PPCanvasView (MatchToolToleranceIndicator)
339 
340 + (void) initializeMatchToolToleranceIndicator;
341 
342 - (bool) initMatchToolToleranceIndicatorMembers;
343 - (void) deallocMatchToolToleranceIndicatorMembers;
344 
345 - (void) showMatchToolToleranceIndicatorAtViewPoint: (NSPoint) viewPoint;
346 
347 - (void) hideMatchToolToleranceIndicator;
348 
349 - (void) setMatchToolToleranceIndicatorRadius: (unsigned) radius;
350 
351 - (void) drawMatchToolToleranceIndicator;
352 
353 @end
354 
355 @interface PPCanvasView (MouseCursor)
356 
357 - (void) setToolCursor: (NSCursor *) toolCursor;
358 
359 - (void) updateCursor;
360 - (void) updateCursorForWindowPoint: (NSPoint) windowPoint;
361 - (void) updateCursorForCurrentMouseLocation;
362 
363 @end
364 
365 @interface PPCanvasView (Autoscrolling)
366 
367 - (void) enableAutoscrolling: (bool) shouldEnableAutoscrolling;
368 
369 - (bool) isAutoscrolling;
370 
371 - (void) autoscrollHandleMouseDraggedEvent: (NSEvent *) event;
372 - (void) autoscrollStop;
373 
374 @end
375 
376 #if PP_DEPLOYMENT_TARGET_SUPPORTS_RETINA_DISPLAY
377 
378 @interface PPCanvasView (RetinaDrawing)
379 
380 - (void) setupRetinaDrawingForCurrentDisplay;
381 - (void) setupRetinaDrawingForResizedView;
382 - (void) destroyRetinaDrawingMembers;
383 
384 - (void) beginDrawingToRetinaDisplayBufferInRect: (NSRect) rect;
385 - (void) finishDrawingToRetinaDisplayBufferInRect: (NSRect) rect;
386 
387 @end
388 
389 #endif  // PP_DEPLOYMENT_TARGET_SUPPORTS_RETINA_DISPLAY
390 
391 
392 extern NSString *PPCanvasViewNotification_ChangedZoomFactor;
393 extern NSString *PPCanvasViewNotification_UpdatedNormalizedVisibleBounds;
394