1 /****************************************************************************
3 * canvas.c -- Lunapaint, *
4 * http://developer.berlios.de/projects/lunapaintami/ *
5 * Copyright (C) 2006, 2007, Hogne Titlestad <hogga@sub-ether.org> *
6 * Copyright (C) 2009-2011 LunaPaint Development Team *
8 * This program is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU General Public License as published by *
10 * the Free Software Foundation; either version 2 of the License, or *
11 * (at your option) any later version. *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License for more details. *
18 * You should have received a copy of the GNU General Public License *
19 * along with this program; if not, write to the Free Software Foundation, *
20 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
22 ****************************************************************************/
31 BOOL fullscreenEditing
;
33 Object
*windowFullscreen
;
34 Object
*fullscreenGroup
;
36 //---------------------------------------------------------------------
42 HOOKPROTONHNO(projFunc
, void, int *param
)
44 // We allocate but do not deallocate as
45 // this var is freed by Zune when it becomes part
47 unsigned char *projectName
= NULL
;
49 struct WindowList
*lst
= *( struct WindowList
**)param
;
51 get ( lst
->projName
, MUIA_String_Contents
, &projectName
);
52 set ( lst
->win
, MUIA_Window_Title
, projectName
);
53 set ( lst
->projectWin
, MUIA_Window_Open
, FALSE
);
59 Dispatcher for our RGBitmapObject
61 BOOPSI_DISPATCHER(IPTR
, RGBitmapDispatcher
, cl
, obj
, msg
)
63 switch ( msg
->MethodID
)
65 case MUIM_Draw
: return MUIM_RGB_Draw ( cl
, obj
, msg
);
66 case MUIM_Luna_Canvas_Redraw
: return MUIM_RGB_Redraw ( );
67 case MUIM_Luna_Canvas_RedrawArea
: return MUIM_RGB_RedrawArea ( );
68 case MUIM_HandleInput
: return MUIM_RGB_HandleInput ( cl
, obj
, msg
);
69 case MUIM_Setup
: return MUIM_RGB_Setup ( cl
, obj
, msg
);
70 case MUIM_Cleanup
: return MUIM_RGB_Cleanup ( cl
, obj
, msg
);
71 case MUIM_Luna_Canvas_ScrollingNotify
: return MUIM_RGB_ScrollingNotify ( );
72 case MUIM_Luna_CanvasActivate
: return MUIM_RGB_CanvasActivate ( cl
, obj
, msg
);
73 case MUIM_Luna_CanvasDeactivate
: return MUIM_RGB_CanvasDeactivate ( cl
, obj
, msg
);
74 case MUIM_Luna_ZoomIn
: return MUIM_RGB_ZoomIn ( );
75 case MUIM_Luna_ZoomOut
: return MUIM_RGB_ZoomOut ( );
76 case MUIM_Luna_ShowAll
: return MUIM_RGB_ShowAll ( );
77 case MUIM_AskMinMax
: return MUIM_RGB_AskMinMax ( cl
, obj
, msg
);
78 case MUIM_Luna_CloseCanvasWin
: return MUIM_RGB_CloseCanvasWin ( cl
, obj
, msg
);
79 default: return DoSuperMethodA ( cl
, obj
, msg
);
86 /******************************************************************************
88 ******************************************************************************/
90 IPTR
MUIM_RGB_Draw ( Class
*CLASS
, Object
*self
, Msg message
)
93 if ( globalActiveCanvas
!= NULL
)
96 globalActiveWindow
->prevBlit
.w
= 0;
97 _RGBitmapRedraw ( CLASS
, self
);
100 return DoSuperMethodA ( CLASS
, self
, message
);
102 IPTR
MUIM_RGB_Redraw ( )
104 if ( globalActiveCanvas
)
106 MUI_Redraw ( globalActiveWindow
->area
, MADF_DRAWUPDATE
);
111 // Called from outside the object
112 IPTR
MUIM_RGB_RedrawArea ( )
114 if ( globalActiveCanvas
!= NULL
)
116 globalActiveCanvas
->winHasChanged
= TRUE
;
117 if ( redrawTimes
< 5 )
123 IPTR
MUIM_RGB_HandleInput ( Class
*CLASS
, Object
*self
, Msg message
)
125 if ( CLASS
== NULL
|| isZooming
|| globalActiveCanvas
== NULL
)
128 struct MUIP_HandleInput
*Message
= ( struct MUIP_HandleInput
*)message
;
130 struct RGBitmapData
*data
= ( struct RGBitmapData
*)INST_DATA ( CLASS
, self
);
133 // Immediately set this window as active window!
134 if ( globalActiveCanvas
!= data
->window
->canvas
)
136 globalActiveCanvas
= data
->window
->canvas
;
137 globalActiveWindow
= data
->window
;
140 // Get current zoom in a simpler to write variable
141 int zoom
= globalActiveCanvas
->zoom
;
143 // Get correct offset coordinates
144 // and align them to zoom "grid"
145 int ox
= XGET ( globalActiveWindow
->scrollH
, MUIA_Prop_First
);
146 int oy
= XGET ( globalActiveWindow
->scrollV
, MUIA_Prop_First
);
147 ox
= ( int )( ( double )ox
/ zoom
) * zoom
;
148 oy
= ( int )( ( double )oy
/ zoom
) * zoom
;
150 // If the offset has changed (with a window resize etc) or we got a scroll event
153 ( ox
!= globalActiveCanvas
->offsetx
|| oy
!= globalActiveCanvas
->offsety
) &&
157 ScrollCanvas ( ox
, oy
);
162 ULONG areaWidth
= _getAreaWidth ( );
164 // Make sure we have a message
167 switch ( Message
->imsg
->Class
)
169 case IDCMP_MOUSEMOVE
:
171 if ( !data
->window
->isActive
)
173 data
->window
->isActive
= TRUE
;
177 // Signalize that we have movement
179 MouseHasMoved
= TRUE
;
181 // Get the mose coordinates relative to top and left widget edges
182 data
->zuneAreaLeft
= XGET ( self
, MUIA_LeftEdge
);
183 data
->zuneAreaTop
= XGET ( self
, MUIA_TopEdge
);
185 // Update window edge coordinates
186 data
->window
->canvas
->winEdgeWidth
= data
->zuneAreaLeft
;
187 data
->window
->canvas
->winEdgeHeight
= data
->zuneAreaTop
;
189 // Update coordinates on display
190 STRPTR coord
= AllocVec ( 20, MEMF_CLEAR
);
191 sprintf ( coord
, "X: %d ", ( int )cMouseX
);
192 set ( data
->window
->txtCoordX
, MUIA_Text_Contents
, ( IPTR
)coord
);
194 coord
= AllocVec ( 20, MEMF_CLEAR
);
195 sprintf ( coord
, "Y: %d ", ( int )cMouseY
);
196 set ( data
->window
->txtCoordY
, MUIA_Text_Contents
, ( IPTR
)coord
);
200 case IDCMP_MOUSEBUTTONS
:
202 // Signalize that we have movement
205 // And that the window has changed
206 data
->window
->canvas
->winHasChanged
= TRUE
;
208 if ( Message
->imsg
->Code
== SELECTDOWN
)
210 if ( cMouseX
>= ox
|| cMouseX
< ox
+ areaWidth
|| cMouseY
>= oy
|| cMouseY
< oy
+ areaWidth
)
212 // Register the click!
213 if ( !MouseButtonL
) MouseHasMoved
= TRUE
;
215 // Paintbrush tool filled
216 if ( globalCurrentTool
== LUNA_TOOL_BRUSH
) brushTool
.RecordContour
= TRUE
;
220 // Inactivizers happen everywhere
221 if ( Message
->imsg
->Code
== SELECTUP
)
223 MouseHasMoved
= TRUE
;
224 MouseButtonL
= FALSE
;
225 if ( globalCurrentTool
== LUNA_TOOL_BRUSH
) brushTool
.RecordContour
= FALSE
;
226 globalActiveWindow
->layersChg
= TRUE
;
227 MUI_Redraw ( WidgetLayers
, MADF_DRAWUPDATE
);
236 IPTR
MUIM_RGB_Setup ( Class
*CLASS
, Object
*self
, Msg message
)
241 MUI_RequestIDCMP( self
, IDCMP_MOUSEBUTTONS
| IDCMP_MOUSEMOVE
| IDCMP_RAWKEY
);
242 return DoSuperMethodA ( CLASS
, self
, message
);
245 IPTR
MUIM_RGB_Cleanup ( Class
*CLASS
, Object
*self
, Msg message
)
247 MUI_RejectIDCMP( self
, IDCMP_MOUSEBUTTONS
| IDCMP_MOUSEMOVE
| IDCMP_RAWKEY
);
248 return DoSuperMethodA ( CLASS
, self
, message
);
251 IPTR
MUIM_RGB_ScrollingNotify ( )
257 IPTR
MUIM_RGB_CanvasActivate ( Class
*CLASS
, Object
*self
, Msg message
)
259 struct RGBitmapData
*data
= INST_DATA ( CLASS
, self
);
261 // We can use keyboard shortcuts
262 keyboardEnabled
= TRUE
;
264 // Quicky update these two globals
265 globalActiveWindow
= data
->window
;
266 globalActiveCanvas
= data
->window
->canvas
;
272 Update_AnimValues ( );
274 // Set window is unactive to force an up
275 data
->window
->isActive
= TRUE
;
278 MUI_Redraw ( WidgetLayers
, MADF_DRAWUPDATE
);
283 IPTR
MUIM_RGB_CanvasDeactivate ( Class
*CLASS
, Object
*self
, Msg message
)
285 if ( globalActiveWindow
!= NULL
&& !fullscreenEditing
)
287 struct RGBitmapData
*data
= INST_DATA ( CLASS
, self
);
288 data
->window
->isActive
= FALSE
;
293 IPTR
MUIM_RGB_ZoomIn ( )
295 if ( globalActiveCanvas
->zoom
+ 1 <= 32 && !isZooming
)
300 // Remove any previous tool preview
301 removePrevToolPreview ( );
304 int ox
= globalActiveCanvas
->offsetx
;
305 int oy
= globalActiveCanvas
->offsety
;
308 globalActiveCanvas
->zoom
++;
311 globalActiveCanvas
->offsetx
= ( ox
* 2 );
312 globalActiveCanvas
->offsety
= ( oy
* 2 );
313 constrainOffset ( globalActiveCanvas
);
322 IPTR
MUIM_RGB_ZoomOut ( )
324 if ( globalActiveCanvas
->zoom
- 1 >= 1 && !isZooming
)
329 // Remove any previous tool preview
330 removePrevToolPreview ( );
333 globalActiveCanvas
->zoom
--;
336 globalActiveCanvas
->offsetx
= globalActiveCanvas
->offsetx
* 0.5;
337 globalActiveCanvas
->offsety
= globalActiveCanvas
->offsety
* 0.5;
338 constrainOffset ( globalActiveCanvas
);
347 IPTR
MUIM_RGB_ShowAll ( )
349 // Remove any previous tool preview
351 removePrevToolPreview ( );
353 globalActiveCanvas
->zoom
= 1;
354 globalActiveCanvas
->offsetx
= 0;
355 globalActiveCanvas
->offsety
= 0;
361 IPTR
MUIM_RGB_AskMinMax ( Class
*CLASS
, Object
*self
, Msg message
)
363 DoSuperMethodA ( CLASS
, self
, message
);
364 struct RGBitmapData
*data
= INST_DATA ( CLASS
, self
);
365 struct MUIP_AskMinMax
*Message
= ( struct MUIP_AskMinMax
*)message
;
367 // This one is needed when askminmax is asked with reopening windows that
368 // have been _hidden_ (not disposed), like when going into fullscreen mode
369 if ( !globalActiveWindow
)
371 globalActiveWindow
= data
->window
;
372 globalActiveCanvas
= data
->window
->canvas
;
375 int calcwidth
= data
->window
->canvas
->width
* data
->window
->canvas
->zoom
;
376 int calcheight
= data
->window
->canvas
->height
* data
->window
->canvas
->zoom
;
378 int tWidth
= _getAreaWidth ( ),
379 tHeight
= _getAreaHeight ( ),
380 minWidth
= calcwidth
,
381 minHeight
= calcheight
;
383 if ( minWidth
> tWidth
) minWidth
= tWidth
;
384 if ( minHeight
> tHeight
) minHeight
= tHeight
;
386 if ( AskMinMaxTimes
> 0 )
388 // Dunno why I need to add the lunaPubScreen size or run this the second
389 // time askminmax is executed
390 Message
->MinMaxInfo
->MinWidth
+= minWidth
;
391 Message
->MinMaxInfo
->MinHeight
+= minHeight
;
395 Message
->MinMaxInfo
->DefWidth
+= calcwidth
;
396 Message
->MinMaxInfo
->DefHeight
+= calcheight
;
397 Message
->MinMaxInfo
->MaxWidth
+= lunaPubScreen
->Width
;
398 Message
->MinMaxInfo
->MaxHeight
+= lunaPubScreen
->Height
;
403 IPTR
MUIM_RGB_CloseCanvasWin ( Class
*CLASS
, Object
*self
, Msg message
)
405 if ( !fullscreenEditing
)
407 removeActiveWindow ( CLASS
, self
);
408 layerRenderBlank ( );
414 void checkKeyboardShortcuts ( UWORD valu
)
419 if ( brushTool
.antialias
== FALSE
)
421 DoMethod ( antiOffImage
, MUIM_CallHook
, &brushOptions_hook
, SET_ANTIALIAS
);
425 DoMethod ( antiOffImage
, MUIM_CallHook
, &brushOptions_hook
, SET_ANTIALIASOFF
);
431 int VAL
= ( int )XGET( tbxCyc_PaletteSnap
, MUIA_Cycle_Active
);
433 set ( tbxCyc_PaletteSnap
, MUIA_Cycle_Active
, 1 );
434 else set ( tbxCyc_PaletteSnap
, MUIA_Cycle_Active
, 0 );
438 globalCurrentTool
= LUNA_TOOL_FILL
;
439 setToolbarActive ( );
442 DoMethod ( paletteRect
, MUIM_Luna_SetTool_Draw
);
445 DoMethod ( paletteRect
, MUIM_Luna_SetTool_Line
);
448 DoMethod ( paletteRect
, MUIM_Luna_SetTool_Circle
);
451 DoMethod ( paletteRect
, MUIM_Luna_SetTool_Rectangle
);
454 DoMethod ( paletteRect
, MUIM_Luna_SetTool_Colorpicker
);
457 DoMethod ( paletteRect
, MUIM_Luna_SetTool_ClipBrush
);
461 ULONG curr
= XGET ( tbxCycGrid
, MUIA_Cycle_Active
);
463 set ( tbxCycGrid
, MUIA_Cycle_Active
, 1 );
465 set ( tbxCycGrid
, MUIA_Cycle_Active
, 0 );
469 if ( !globalActiveCanvas
) return;
470 swapCanvasBuffers ( globalActiveCanvas
);
471 globalActiveWindow
->rRectW
= 0;
472 globalActiveWindow
->rRectX
= 0;
473 globalActiveWindow
->rRectH
= 0;
474 globalActiveWindow
->rRectY
= 0;
475 globalActiveCanvas
->winHasChanged
= TRUE
;
476 globalActiveWindow
->layersChg
= TRUE
;
477 MUI_Redraw ( globalActiveWindow
->area
, MADF_DRAWUPDATE
);
479 case RAWKEY_J
| RAWKEY_RSHIFT
:
480 if ( !globalActiveCanvas
) return;
481 copyToSwap ( globalActiveCanvas
);
493 nextPaletteColor ( );
496 prevPaletteColor ( );
498 case RAWKEY_F1
: set ( tbxCycPaintMode
, MUIA_Cycle_Active
, 0 ); break;
499 case RAWKEY_F2
: set ( tbxCycPaintMode
, MUIA_Cycle_Active
, 1 ); break;
500 case RAWKEY_F3
: set ( tbxCycPaintMode
, MUIA_Cycle_Active
, 6 ); break;
501 case RAWKEY_F4
: set ( tbxCycPaintMode
, MUIA_Cycle_Active
, 4 ); break;
502 case RAWKEY_F5
: set ( tbxCycPaintMode
, MUIA_Cycle_Active
, 5 ); break;
503 case RAWKEY_F6
: set ( tbxCycPaintMode
, MUIA_Cycle_Active
, 7 ); break;
504 case RAWKEY_F7
: set ( tbxCycPaintMode
, MUIA_Cycle_Active
, 8 ); break;
505 case RAWKEY_F8
: set ( tbxCycPaintMode
, MUIA_Cycle_Active
, 2 ); break;
506 case RAWKEY_F9
: set ( tbxCycPaintMode
, MUIA_Cycle_Active
, 3 ); break;
508 // Toggle fullscreen mode
510 if ( !globalActiveCanvas
) return;
511 if ( !fullscreenEditing
)
513 if ( !globalActiveWindow
) return;
514 showFullscreenWindow ( globalActiveCanvas
);
516 else hideFullscreenWindow ( );
522 // Don't hide the toolbox if we're not in fullscreen and we're not having a canvas window
523 if ( GlobalPrefs
.ScreenmodeType
== 0 && !fullscreenEditing
&& !globalActiveWindow
) break;
525 BOOL boxopen
= XGET ( toolbox
, MUIA_Window_Open
);
526 if ( boxopen
) set ( toolbox
, MUIA_Window_Open
, FALSE
);
527 else set ( toolbox
, MUIA_Window_Open
, TRUE
);
531 case RAWKEY_UP
: moveScrollbarUp ( ); break;
532 case RAWKEY_DOWN
: moveScrollbarDown ( ); break;
533 case RAWKEY_LEFT
: moveScrollbarLeft ( ); break;
534 case RAWKEY_RIGHT
: moveScrollbarRight ( ); break;
537 case RAWKEY_KP_1
: set ( tbxSlider_Brushopacity
, MUIA_Numeric_Value
, 5 ); break;
538 case RAWKEY_KP_2
: set ( tbxSlider_Brushopacity
, MUIA_Numeric_Value
, 10 ); break;
539 case RAWKEY_KP_3
: set ( tbxSlider_Brushopacity
, MUIA_Numeric_Value
, 30 ); break;
540 case RAWKEY_KP_4
: set ( tbxSlider_Brushopacity
, MUIA_Numeric_Value
, 60 ); break;
541 case RAWKEY_KP_5
: set ( tbxSlider_Brushopacity
, MUIA_Numeric_Value
, 128 ); break;
542 case RAWKEY_KP_6
: set ( tbxSlider_Brushopacity
, MUIA_Numeric_Value
, 255 ); break;
547 int bsz
= XGET ( tbxSlider_Brushdiameter
, MUIA_Numeric_Value
);
548 set ( tbxSlider_Brushdiameter
, MUIA_Numeric_Value
, bsz
+ 2 );
553 int bsz
= XGET ( tbxSlider_Brushdiameter
, MUIA_Numeric_Value
);
554 set ( tbxSlider_Brushdiameter
, MUIA_Numeric_Value
, bsz
- 2 );
557 case RAWKEY_KP_DECIMAL
: set ( tbxSlider_Brushdiameter
, MUIA_Numeric_Value
, 1 ); break;
558 case RAWKEY_KP_ENTER
: set ( tbxSlider_Brushdiameter
, MUIA_Numeric_Value
, 100 ); break;
562 lastKeyPressed
= valu
;
565 void moveScrollbarUp ( )
567 if ( globalActiveWindow
== NULL
) return;
568 int pos
= XGET ( globalActiveWindow
->scrollV
, MUIA_Prop_First
);
569 int dist
= globalActiveCanvas
->zoom
* 10;
570 set ( globalActiveWindow
->scrollV
, MUIA_Prop_First
, pos
- dist
);
573 void moveScrollbarDown ( )
575 if ( globalActiveWindow
== NULL
) return;
576 int pos
= XGET ( globalActiveWindow
->scrollV
, MUIA_Prop_First
);
577 int dist
= globalActiveCanvas
->zoom
* 10;
578 set ( globalActiveWindow
->scrollV
, MUIA_Prop_First
, pos
+ dist
);
581 void moveScrollbarLeft ( )
583 if ( globalActiveWindow
== NULL
) return;
584 int pos
= XGET ( globalActiveWindow
->scrollH
, MUIA_Prop_First
);
585 int dist
= globalActiveCanvas
->zoom
* 10;
586 set ( globalActiveWindow
->scrollH
, MUIA_Prop_First
, pos
- dist
);
589 void moveScrollbarRight ( )
591 if ( globalActiveWindow
== NULL
) return;
592 int pos
= XGET ( globalActiveWindow
->scrollH
, MUIA_Prop_First
);
593 int dist
= globalActiveCanvas
->zoom
* 10;
594 set ( globalActiveWindow
->scrollH
, MUIA_Prop_First
, pos
+ dist
);
597 void constrainOffset ( struct oCanvas
*canvas
)
600 int zoom
= canvas
->zoom
;
602 int vWidth
= _getAreaWidth ( ),
603 vHeight
= _getAreaHeight ( );
605 vWidth
= ( double )vWidth
/ zoom
;
606 vHeight
= ( double )vHeight
/ zoom
;
608 int cWidth
= canvas
->width
;
609 int cHeight
= canvas
->height
;
611 int ox
= ( double )canvas
->offsetx
/ zoom
;
612 int oy
= ( double )canvas
->offsety
/ zoom
;
615 if ( ox
< 0 ) canvas
->offsetx
= 0;
616 else if ( ox
+ vWidth
>= cWidth
)
617 canvas
->offsetx
= ( cWidth
- vWidth
) * zoom
;
618 if ( oy
< 0 ) canvas
->offsety
= 0;
619 else if ( oy
+ vHeight
>= cHeight
)
620 canvas
->offsety
= ( cHeight
- vHeight
) * zoom
;
623 canvas
->offsetx
= ( int )( ( double )canvas
->offsetx
/ zoom
) * zoom
;
624 canvas
->offsety
= ( int )( ( double )canvas
->offsety
/ zoom
) * zoom
;
627 void snapToBounds ( int *x
, int *y
)
630 int zoom
= globalActiveCanvas
->zoom
;
632 int vWidth
= _getAreaWidth ( ),
633 vHeight
= _getAreaHeight ( );
635 int cWidth
= globalActiveCanvas
->width
* zoom
;
636 int cHeight
= globalActiveCanvas
->height
* zoom
;
638 // Adapt x/y in bounds
639 if ( *x
< 0 ) *x
= 0;
640 else if ( *x
+ vWidth
>= cWidth
)
641 *x
= ( int )( ( cWidth
- vWidth
) / zoom
) * zoom
;
642 if ( *y
< 0 ) *y
= 0;
643 else if ( *y
+ vHeight
>= cHeight
)
644 *y
= ( int )( ( cHeight
- vHeight
) / zoom
) * zoom
;
647 void winHasChanged ( )
649 globalActiveCanvas
->winHasChanged
= TRUE
;
650 DoMethod ( globalActiveWindow
->area
, MUIM_Draw
);
653 IPTR
_RGBitmapRedraw ( Class
*CLASS
, Object
*self
)
656 struct RGBitmapData
*data
= INST_DATA ( CLASS
, self
);
658 if ( globalActiveCanvas
== data
->window
->canvas
)
660 // Get image dimensions multiplied by zoom
661 ULONG imageWidth
= data
->window
->canvas
->width
* data
->window
->canvas
->zoom
;
662 ULONG imageHeight
= data
->window
->canvas
->height
* data
->window
->canvas
->zoom
;
664 // Check if the dimensions of the visible width has changed
665 ULONG ZuneWidth
= XGET ( data
->window
->area
, MUIA_Width
);
666 ULONG ZuneHeight
= XGET ( data
->window
->area
, MUIA_Height
);
667 if ( data
->zuneAreaWidth
!= ZuneWidth
|| data
->zuneAreaHeight
!= ZuneHeight
)
668 data
->window
->canvas
->winHasChanged
= TRUE
;
670 // Get top and left edge of area
671 data
->zuneAreaTop
= XGET ( data
->window
->area
, MUIA_TopEdge
);
672 data
->zuneAreaLeft
= XGET ( data
->window
->area
, MUIA_LeftEdge
);
673 data
->zuneAreaWidth
= ZuneWidth
;
674 data
->zuneAreaHeight
= ZuneHeight
;
675 data
->rgbAreaTop
= _getAreaOffsetY ( ) + data
->zuneAreaTop
;
676 data
->rgbAreaLeft
= _getAreaOffsetX ( ) + data
->zuneAreaLeft
;
678 // Update known container size
679 // This needs cleaning up
680 int cvisWidth
= _getAreaWidth ( ),
681 cvisHeight
= _getAreaHeight ( );
682 data
->window
->contWidth
= cvisWidth
;
683 data
->window
->contHeight
= cvisHeight
;
684 data
->window
->canvas
->visibleWidth
= cvisWidth
;
685 data
->window
->canvas
->visibleHeight
= cvisHeight
;
687 // we're only using a maximum area of the container for
688 // the drawing itself
689 if ( cvisWidth
> imageWidth
) cvisWidth
= imageWidth
;
690 if ( cvisHeight
> imageHeight
) cvisHeight
= imageHeight
;
692 // Update window edge coordinates (do we need this? find out)
693 data
->window
->canvas
->winEdgeWidth
= _getAreaLeft ( );
694 data
->window
->canvas
->winEdgeHeight
= _getAreaTop ( );
697 // Update scrollbars if we're changing zoom
699 globalActiveCanvas
->zoom
!= data
->currentzoom
||
700 data
->window
->canvas
->winHasChanged
704 set ( data
->window
->scrollH
, MUIA_Prop_Visible
, ( IPTR
)cvisWidth
);
705 set ( data
->window
->scrollV
, MUIA_Prop_Visible
, ( IPTR
)cvisHeight
);
706 set ( data
->window
->scrollH
, MUIA_Prop_Entries
, ( IPTR
)imageWidth
);
707 set ( data
->window
->scrollV
, MUIA_Prop_Entries
, ( IPTR
)imageHeight
);
708 set ( data
->window
->scrollH
, MUIA_Prop_First
, ( IPTR
)globalActiveCanvas
->offsetx
);
709 set ( data
->window
->scrollV
, MUIA_Prop_First
, ( IPTR
)globalActiveCanvas
->offsety
);
712 data
->currentzoom
= globalActiveCanvas
->zoom
;
713 data
->rgbAreaWidth
= cvisWidth
;
714 data
->rgbAreaHeight
= cvisHeight
;
716 // In case triggered by zoom
717 data
->window
->canvas
->winHasChanged
= TRUE
;
720 // Update the screen buffer
721 if ( data
->window
->canvas
->winHasChanged
)
723 int Tool
= globalCurrentTool
; // <- disables drawing tool preview in rendering func
724 globalCurrentTool
= -1; //
726 // Accelerated redraw
727 if ( data
->window
->rRectW
|| data
->window
->rRectH
)
729 struct oCanvas
*canvas
= data
->window
->canvas
;
730 int offsetx
= ( canvas
->offsetx
+ data
->window
->rRectX
) / canvas
->zoom
;
731 int offsety
= ( canvas
->offsety
+ data
->window
->rRectY
) / canvas
->zoom
;
732 int width
= ( double )data
->window
->rRectW
/ canvas
->zoom
;
733 int height
= ( double )data
->window
->rRectH
/ canvas
->zoom
;
735 D(bug("1a. Redrawing accelerated %dx%d\n", width
, height
));
740 canvas
, _rp ( data
->window
->area
)
743 // Reset accelerator parameters
744 data
->window
->rRectX
= 0;
745 data
->window
->rRectY
= 0;
746 data
->window
->rRectW
= 0;
747 data
->window
->rRectH
= 0;
749 D(bug("1b. Redraw complete\n"));
751 // Slow redraw (with zoom etc)
755 _rp ( data
->window
->area
),
756 data
->zuneAreaLeft
, data
->zuneAreaTop
,
758 data
->zuneAreaHeight
,
761 D(bug("2a. Redrawing anew %dx%d\n", cvisWidth
, cvisHeight
));
762 if ( redrawScreenbuffer ( data
->window
->canvas
) )
765 data
->window
->canvas
->screenbuffer
,
766 0, 0, data
->window
->canvas
->scrStorageWidth
* 4, _rp ( data
->window
->area
),
767 data
->rgbAreaLeft
, data
->rgbAreaTop
, cvisWidth
, cvisHeight
, RECTFMT_RAW
770 D(bug("2b. Redraw complete\n"));
771 UpdateCanvasInfo ( data
->window
);
772 Update_AnimValues ( );
774 data
->window
->canvas
->winHasChanged
= FALSE
;
776 globalCurrentTool
= Tool
; // Resets tool setting
780 if ( data
->window
->canvas
->screenstorage
!= NULL
)
782 // Write all data to the rastport!
784 _rp ( data
->window
->area
),
785 data
->zuneAreaLeft
, data
->zuneAreaTop
,
787 data
->zuneAreaHeight
,
791 data
->window
->canvas
->screenstorage
,
792 0, 0, data
->window
->canvas
->scrStorageWidth
* 4, _rp ( data
->window
->area
),
793 data
->rgbAreaLeft
, data
->rgbAreaTop
, cvisWidth
, cvisHeight
, RECTFMT_RAW
797 if ( globalActiveWindow
->layersChg
) MUI_Redraw ( WidgetLayers
, MADF_DRAWUPDATE
);
799 // For some reason, we're updatated and not actived
802 if ( data
->window
->canvas
->screenstorage
)
804 // Write all data to the rastport!
806 data
->window
->canvas
->screenstorage
,
807 0, 0, data
->window
->canvas
->scrStorageWidth
* 4,
808 _rp ( data
->window
->area
),
809 data
->rgbAreaLeft
, data
->rgbAreaTop
, data
->rgbAreaWidth
, data
->rgbAreaHeight
, RECTFMT_RAW
817 void SnapOffsetToZoom ( struct oCanvas
*canv
)
819 if ( canv
== NULL
) canv
= globalActiveCanvas
;
820 // Contstrain offset to zoom
821 int *ofx
= &canv
->offsetx
, *ofy
= &canv
->offsety
, zoom
= canv
->zoom
;
822 *ofx
= ( int )( *ofx
/ zoom
) * zoom
;
823 *ofy
= ( int )( *ofy
/ zoom
) * zoom
;
826 void UpdateCanvasInfo ( struct WindowList
*win
)
828 unsigned char frameText
[ 32 ];
829 unsigned char layerText
[ 32 ];
830 int frame
= ( int )( win
->canvas
->currentFrame
+ 1 );
831 int frams
= ( int )win
->canvas
->totalFrames
;
832 int layer
= ( int )( win
->canvas
->currentLayer
+ 1 );
833 int layrs
= ( int )win
->canvas
->totalLayers
;
834 sprintf ( ( unsigned char *)&frameText
, _(MSG_CANVAS_FRAME
), frame
, frams
);
835 set ( win
->txtFrameInf
, MUIA_Text_Contents
, ( STRPTR
)&frameText
);
836 sprintf ( ( unsigned char *)&layerText
, _(MSG_CANVAS_LAYER
), layer
, layrs
);
837 set ( win
->txtLayerInf
, MUIA_Text_Contents
, ( STRPTR
)&layerText
);
839 // Update zoom display
840 STRPTR zlevel
= AllocVec ( 20, MEMF_CLEAR
);
841 sprintf ( zlevel
, _(MSG_CANVAS_ZOOM
), ( int )win
->canvas
->zoom
);
842 set ( win
->txtZoomLevel
, MUIA_Text_Contents
, ( IPTR
)zlevel
);
846 IPTR
ScrollCanvas ( int x
, int y
)
848 // Ajust to not collide with canvas bounds
849 snapToBounds ( &x
, &y
);
851 // Remove any prevous toolpreview
852 removePrevToolPreview ( );
855 ULONG areaWidth
= _getAreaWidth ( );
856 ULONG areaHeight
= _getAreaHeight ( );
857 ULONG areaLeft
= _getAreaLeft ( ) + _getAreaOffsetX ( );
858 ULONG areaTop
= _getAreaTop ( ) + _getAreaOffsetY ( );
860 // find diff and align to zoom
861 int diffx
= x
- ( int )globalActiveCanvas
->offsetx
;
862 int diffy
= y
- ( int )globalActiveCanvas
->offsety
;
863 int hght
= areaHeight
- abs ( diffy
);
864 int wdth
= areaWidth
- abs ( diffx
);
866 // Scroll storage buffer
867 if ( globalActiveCanvas
->screenstorage
)
869 removePrevToolPreview ( );
870 scrollScreenStorage ( globalActiveCanvas
, diffx
, diffy
);
872 globalActiveCanvas
->screenstorage
,
874 globalActiveCanvas
->scrStorageWidth
* 4,
875 _rp ( globalActiveWindow
->area
),
876 areaLeft
, areaTop
, globalActiveCanvas
->scrStorageWidth
, globalActiveCanvas
->scrStorageHeight
,
881 // Draw emptied areas on y
882 if ( abs ( diffy
) > 0 )
884 // If scrolling inside viewable area
887 globalActiveWindow
->rRectW
= areaWidth
;
888 globalActiveWindow
->rRectX
= 0;
889 globalActiveWindow
->rRectH
= abs ( diffy
) ? abs ( diffy
) : areaHeight
;
890 globalActiveWindow
->rRectY
= ( diffy
> 0 ) ? ( areaHeight
- diffy
) : 0;
895 globalActiveWindow
->rRectW
= 0;
896 globalActiveWindow
->rRectX
= 0;
897 globalActiveWindow
->rRectH
= 0;
898 globalActiveWindow
->rRectY
= 0;
900 globalActiveCanvas
->offsety
= y
;
901 globalActiveCanvas
->winHasChanged
= TRUE
;
902 MUI_Redraw ( globalActiveWindow
->area
, MADF_DRAWUPDATE
);
904 // Draw emptied areas on x
905 if ( abs ( diffx
) > 0 )
907 // If scrolling inside viewable area
910 globalActiveWindow
->rRectW
= abs ( diffx
) ? abs ( diffx
) : areaWidth
;
911 globalActiveWindow
->rRectX
= ( diffx
> 0 ) ? ( areaWidth
- diffx
) : 0;
912 globalActiveWindow
->rRectH
= areaHeight
;
913 globalActiveWindow
->rRectY
= 0;
918 globalActiveWindow
->rRectW
= 0;
919 globalActiveWindow
->rRectX
= 0;
920 globalActiveWindow
->rRectH
= 0;
921 globalActiveWindow
->rRectY
= 0;
924 globalActiveCanvas
->offsetx
= x
;
925 globalActiveCanvas
->winHasChanged
= TRUE
;
926 MUI_Redraw ( globalActiveWindow
->area
, MADF_DRAWUPDATE
);
932 void getMouseCoordinates ( )
934 if ( !globalActiveCanvas
|| !globalActiveWindow
) return;
936 int ox
= globalActiveCanvas
->offsetx
;
937 int oy
= globalActiveCanvas
->offsety
;
940 ( int )lunaPubScreen
->MouseX
-
941 XGET ( globalActiveWindow
->win
, MUIA_Window_LeftEdge
) - _getAreaOffsetX ( ) - _getAreaLeft ( )
944 ( int )lunaPubScreen
->MouseY
-
945 XGET ( globalActiveWindow
->win
, MUIA_Window_TopEdge
) - _getAreaOffsetY ( ) - _getAreaTop ( )
948 cMouseX
= ( eMouseX
+ ox
) / globalActiveCanvas
->zoom
;
949 cMouseY
= ( eMouseY
+ oy
) / globalActiveCanvas
->zoom
;
953 cMouseX
= ( int )( cMouseX
/ globalCurrentGrid
) * globalCurrentGrid
;
954 cMouseY
= ( int )( cMouseY
/ globalCurrentGrid
) * globalCurrentGrid
;
957 // Unantialiased coords..
958 if ( !brushTool
.antialias
)
960 cMouseX
= ( int )cMouseX
;
961 cMouseY
= ( int )cMouseY
;
964 if ( !MouseButtonL
&& !MouseButtonR
) dMouseX
= cMouseX
, dMouseY
= cMouseY
;
967 void addCanvaswindow (
968 unsigned int width
, unsigned int height
,
969 unsigned int layers
, unsigned int frames
,
973 struct WindowList
*temp
= canvases
; // Put current in temp
974 canvases
= AllocVec ( sizeof ( WindowList
), MEMF_CLEAR
);
976 struct MUI_CustomClass
*mcc
=
977 MUI_CreateCustomClass (
978 NULL
, MUIC_Group
, NULL
,
979 sizeof ( struct RGBitmapData
),
983 canvases
->win
= MUI_NewObject ( MUIC_Window
,
984 MUIA_Window_Title
, __(MSG_CANVAS_UNNAMED
),
985 MUIA_Window_SizeGadget
, TRUE
,
986 MUIA_Window_Screen
, ( IPTR
)lunaPubScreen
,
987 MUIA_Window_ID
, MAKE_ID('L','P','W','C'),
988 MUIA_Window_MouseObject
, ( IPTR
)canvases
->mouse
,
989 MUIA_Window_ScreenTitle
, ( IPTR
)VERSION
,
990 MUIA_Window_UseRightBorderScroller
, TRUE
,
991 MUIA_Window_UseBottomBorderScroller
, TRUE
,
992 MUIA_Window_IsSubWindow
, TRUE
,
993 WindowContents
, ( IPTR
)VGroup
,
994 InnerSpacing( 0, 0 ),
995 MUIA_Group_HorizSpacing
, 0,
996 MUIA_Group_VertSpacing
, 0,
997 Child
, ( IPTR
)VGroup
,
998 InnerSpacing( 0, 0 ),
999 MUIA_Group_HorizSpacing
, 0,
1000 MUIA_Group_VertSpacing
, 0,
1001 Child
, ( IPTR
)( canvases
->container
= VGroup
,
1002 InnerSpacing( 0, 0 ),
1003 MUIA_Group_HorizSpacing
, 0,
1004 MUIA_Group_VertSpacing
, 0,
1005 Child
, ( IPTR
)( canvases
->area
= NewObject(
1006 mcc
->mcc_Class
, NULL
,
1007 MUIA_FillArea
, FALSE
,
1008 MUIA_Frame
, MUIV_Frame_None
,
1009 InnerSpacing( 0, 0 ),
1013 Child
, ( IPTR
)HGroup
,
1014 MUIA_Group_SameHeight
, TRUE
,
1015 MUIA_Frame
, MUIV_Frame_Group
,
1016 InnerSpacing ( 4, 4 ),
1017 MUIA_Background
, MUII_FILL
,
1018 MUIA_Group_Child
, ( IPTR
)HGroup
,
1019 MUIA_Frame
, MUIV_Frame_None
,
1020 InnerSpacing ( 3, 3 ),
1022 Child
, ( IPTR
)( canvases
->txtLayerInf
= TextObject
,
1023 MUIA_Text_Contents
, _(MSG_CANVAS_LAYER2
),
1025 Child
, ( IPTR
)( canvases
->txtFrameInf
= TextObject
,
1026 MUIA_Text_Contents
, _(MSG_CANVAS_FRAME2
),
1028 Child
, ( IPTR
)( canvases
->txtZoomLevel
= TextObject
,
1029 MUIA_Text_Contents
, _(MSG_CANVAS_ZOOM2
),
1031 Child
, ( IPTR
)( canvases
->txtCoordX
= TextObject
,
1032 MUIA_Text_Contents
, "X: 0 " ,
1034 Child
, ( IPTR
)( canvases
->txtCoordY
= TextObject
,
1035 MUIA_Text_Contents
, "Y: 0 ",
1037 Child
, ( IPTR
)RectangleObject
, MUIA_Weight
, 20, End
,
1039 Child
, ( IPTR
)HGroup
,
1043 MUIA_InnerBottom
, 0,
1045 Child
, ( IPTR
)( canvases
->btnZoom
= SimpleButton ( ( IPTR
)"+" ) ),
1046 Child
, ( IPTR
)( canvases
->btnUnZoom
= SimpleButton ( ( IPTR
)"-" ) ),
1047 Child
, ( IPTR
)( canvases
->btnShowAll
= SimpleButton ( ( IPTR
)"1:1" ) ),
1051 Child
, ( IPTR
)( canvases
->scrollH
= ScrollbarObject
,
1052 MUIA_Prop_UseWinBorder
, MUIV_Prop_UseWinBorder_Bottom
,
1054 Child
, ( IPTR
)( canvases
->scrollV
= ScrollbarObject
,
1055 MUIA_Prop_UseWinBorder
, MUIV_Prop_UseWinBorder_Right
,
1060 // Some values in the area object
1061 struct RGBitmapData
*areaData
= INST_DATA ( mcc
->mcc_Class
, canvases
->area
);
1062 areaData
->window
= canvases
;
1063 areaData
->mousepressed
= FALSE
;
1064 canvases
->id
= globalWindowIncrement
;
1065 canvases
->layersChg
= TRUE
; // initially, say yes layers changed
1066 canvases
->prevBlit
= ( struct RectStruct
){ 0, 0, 0, 0 };
1067 canvases
->filename
= NULL
; // set the filename to null *obviously*
1068 canvases
->rRectX
= 0;
1069 canvases
->rRectY
= 0;
1070 canvases
->rRectW
= 0;
1071 canvases
->rRectH
= 0;
1072 canvases
->contWidth
= 0;
1073 canvases
->contHeight
= 0;
1075 // Add project func to hook
1076 canvases
->projHook
.h_Entry
= ( HOOKFUNC
)projFunc
;
1080 canvases
->canvas
= Init_Canvas ( width
, height
, layers
, frames
, generateCanvas
);
1081 canvases
->nextwin
= temp
;
1083 if ( canvases
->canvas
->buffer
!= NULL
)
1084 setActiveBuffer ( canvases
->canvas
);
1086 // Add the canvas window to the application gui
1087 DoMethod ( PaintApp
, OM_ADDMEMBER
, ( IPTR
)canvases
->win
);
1089 // Generate window object and add it to the application gui
1090 CreateProjectWindow ( canvases
);
1094 canvases
->btnZoom
, MUIM_Notify
, MUIA_Pressed
, FALSE
,
1095 ( IPTR
)canvases
->area
, 1, MUIM_Luna_ZoomIn
1098 canvases
->btnUnZoom
, MUIM_Notify
, MUIA_Pressed
, FALSE
,
1099 ( IPTR
)canvases
->area
, 1, MUIM_Luna_ZoomOut
1102 canvases
->btnShowAll
, MUIM_Notify
, MUIA_Pressed
, FALSE
,
1103 ( IPTR
)canvases
->area
, 1, MUIM_Luna_ShowAll
1106 canvases
->win
, MUIM_Notify
, MUIA_Window_CloseRequest
, TRUE
,
1107 ( IPTR
)canvases
->area
, 1, MUIM_Luna_CloseCanvasWin
1111 canvases
->win
, MUIM_Notify
, MUIA_Window_Activate
, TRUE
,
1112 ( IPTR
)canvases
->area
, 1, MUIM_Luna_CanvasActivate
1116 canvases
->win
, MUIM_Notify
, MUIA_Window_Activate
, FALSE
,
1117 ( IPTR
)canvases
->area
, 1, MUIM_Luna_CanvasDeactivate
1121 canvases
->scrollV
, MUIM_Notify
, MUIA_Prop_First
, MUIV_EveryTime
,
1122 ( IPTR
)canvases
->area
, 1, MUIM_Luna_Canvas_ScrollingNotify
1126 canvases
->scrollH
, MUIM_Notify
, MUIA_Prop_First
, MUIV_EveryTime
,
1127 ( IPTR
)canvases
->area
, 1, MUIM_Luna_Canvas_ScrollingNotify
1130 DoMethod ( canvases
->win
, MUIM_Notify
, MUIA_Window_Open
, TRUE
,
1131 canvases
->win
, 2, MUIM_CallHook
, &EnableKeyboard_hook
);
1133 // Set global thingies
1134 globalActiveWindow
= canvases
;
1135 globalActiveCanvas
= canvases
->canvas
;
1137 globalWindowIncrement
++;
1140 void showFullscreenWindow ( struct oCanvas
*canvas
)
1142 // Prevent tool preview
1143 int Tool
= globalCurrentTool
;
1144 globalCurrentTool
= -1;
1146 // Set some vars, we need no interference
1147 fullscreenEditing
= TRUE
;
1148 keyboardEnabled
= TRUE
;
1150 // Hide all other canvas windows
1151 struct WindowList
*l
= canvases
;
1154 set ( l
->win
, MUIA_Window_Open
, FALSE
);
1156 while ( ( l
= l
->nextwin
) );
1158 if ( !windowFullscreen
)
1160 windowFullscreen
= WindowObject
,
1161 MUIA_Window_Title
, ( IPTR
)NULL
,
1162 MUIA_Window_SizeGadget
, FALSE
,
1163 MUIA_Window_DepthGadget
, FALSE
,
1164 MUIA_Window_CloseGadget
, FALSE
,
1165 MUIA_Window_TopEdge
, 0,
1166 MUIA_Window_LeftEdge
, 0,
1167 MUIA_Window_DragBar
, FALSE
,
1168 MUIA_Window_Screen
, ( IPTR
) lunaPubScreen
,
1169 MUIA_Window_MouseObject
, ( IPTR
) canvases
->mouse
,
1170 MUIA_Window_ScreenTitle
, ( IPTR
) VERSION
,
1171 MUIA_Window_UseRightBorderScroller
, FALSE
,
1172 MUIA_Window_UseBottomBorderScroller
, FALSE
,
1173 MUIA_Window_IsSubWindow
, FALSE
,
1174 MUIA_Window_Backdrop
, TRUE
,
1175 MUIA_Window_Borderless
, TRUE
,
1176 WindowContents
, ( IPTR
)( fullscreenGroup
= VGroup
,
1177 InnerSpacing ( 0, 0 ),
1178 MUIA_Group_HorizSpacing
, 0,
1179 MUIA_Group_VertSpacing
, 0,
1180 MUIA_Background
, ( IPTR
)"5:PROGDIR:data/backdrop.png",
1183 DoMethod ( PaintApp
, OM_ADDMEMBER
, ( IPTR
)windowFullscreen
);
1186 DoMethod ( globalActiveWindow
->container
, MUIM_Group_InitChange
);
1187 DoMethod ( globalActiveWindow
->container
, OM_REMMEMBER
, ( IPTR
)globalActiveWindow
->area
);
1188 DoMethod ( globalActiveWindow
->container
, MUIM_Group_ExitChange
);
1190 DoMethod ( fullscreenGroup
, MUIM_Group_InitChange
);
1191 DoMethod ( fullscreenGroup
, OM_ADDMEMBER
, ( IPTR
)globalActiveWindow
->area
);
1192 DoMethod ( fullscreenGroup
, MUIM_Group_ExitChange
);
1194 set ( windowFullscreen
, MUIA_Window_Open
, TRUE
);
1196 // Ideal width/height
1197 WORD width
= lunaPubScreen
->Width
;
1198 WORD height
= lunaPubScreen
->Height
;
1199 struct Window
*win
= ( struct Window
*)XGET ( windowFullscreen
, MUIA_Window_Window
);
1200 ChangeWindowBox( win
, 0, 0, width
, height
);
1202 globalCurrentTool
= Tool
;
1205 void hideFullscreenWindow ( )
1207 // Prevent tool preview
1208 int Tool
= globalCurrentTool
;
1209 globalCurrentTool
= -1;
1211 // Let us hide the fullscreen window
1212 set ( windowFullscreen
, MUIA_Window_Open
, FALSE
);
1214 // Remove from fullscreen window and add to container
1215 DoMethod ( fullscreenGroup
, MUIM_Group_InitChange
);
1216 DoMethod ( fullscreenGroup
, OM_REMMEMBER
, ( IPTR
)globalActiveWindow
->area
);
1217 DoMethod ( fullscreenGroup
, MUIM_Group_ExitChange
);
1218 DoMethod ( globalActiveWindow
->container
, MUIM_Group_InitChange
);
1219 DoMethod ( globalActiveWindow
->container
, OM_ADDMEMBER
, ( IPTR
)globalActiveWindow
->area
);
1220 DoMethod ( globalActiveWindow
->container
, MUIM_Group_ExitChange
);
1223 // Show all other canvas windows
1224 struct WindowList
*l
= canvases
;
1227 set ( l
->win
, MUIA_Window_Open
, TRUE
);
1232 fullscreenEditing
= FALSE
;
1234 // Ideal width/height
1237 struct Window
*win
= ( struct Window
*)XGET ( globalActiveWindow
->win
, MUIA_Window_Window
);
1238 ChangeWindowBox( win
, 0, 0, width
, height
);
1240 globalCurrentTool
= Tool
;
1243 Object
*getCanvaswindowById ( unsigned int id
)
1245 struct WindowList
*tmp
= canvases
;
1247 while ( tmp
!= NULL
)
1249 if ( tmp
->id
== id
)
1256 struct WindowList
*getCanvasDataById ( unsigned int id
)
1258 struct WindowList
*tmp
= canvases
;
1260 while ( tmp
!= NULL
)
1262 if ( tmp
->id
== id
)
1269 void deleteCanvaswindows ( )
1271 struct WindowList
*tmp
= NULL
;
1273 while ( canvases
!= NULL
)
1275 tmp
= canvases
->nextwin
;
1276 set ( canvases
->win
, MUIA_Window_Open
, FALSE
);
1278 DoMethod ( PaintApp
, OM_REMMEMBER
, ( IPTR
)canvases
->win
);
1279 if ( canvases
->win
!= NULL
) DoMethod ( PaintApp
, OM_REMMEMBER
, ( IPTR
)canvases
->win
);
1281 Destroy_Canvas ( canvases
->canvas
);
1282 DestroyProjectWindow ( canvases
);
1284 if ( canvases
->filename
!= NULL
)
1285 FreeVec ( canvases
->filename
);
1286 if ( canvases
!= NULL
)
1287 FreeVec ( canvases
);
1293 IPTR
removeActiveWindow ( Class
*CLASS
, Object
*self
)
1295 struct RGBitmapData
*data
= INST_DATA ( CLASS
, self
);
1296 set ( data
->window
->win
, MUIA_Window_Open
, FALSE
);
1297 DoMethod ( PaintApp
, OM_REMMEMBER
, ( IPTR
)data
->window
->win
);
1299 struct WindowList
*tmp
= NULL
;
1300 struct WindowList
*ptr
= canvases
;
1301 struct WindowList
*prev
= NULL
;
1303 while ( ptr
!= NULL
)
1307 if ( ptr
== globalActiveWindow
)
1310 Destroy_Canvas ( ptr
->canvas
);
1311 DestroyProjectWindow ( ptr
);
1312 if ( ptr
->filename
!= NULL
)
1313 FreeVec ( ptr
->filename
);
1317 // Disconnect ptr from canvases chain
1323 prev
->nextwin
= tmp
;
1330 globalActiveWindow
= canvases
;
1331 globalActiveCanvas
= NULL
;
1333 //TODO: Lets reuse hidden windows in the future
1334 data
->window
->win
= NULL
;
1335 return ( IPTR
)NULL
;
1339 int x
, int y
, int w
, int h
,
1340 struct oCanvas
* canvas
, struct RastPort
*rp
1343 // Get zoom - bork bork
1344 int zoom
= canvas
->zoom
;
1346 // Look for conflict with pixel coordinates and canvas dimensions
1347 // was 0 instead of offset on the two next lines
1349 int testofx
= canvas
->offsetx
/ zoom
;
1350 int testofy
= canvas
->offsety
/ zoom
;
1351 if ( x
< testofx
){ w
-= testofx
- x
; x
= testofx
; }
1352 if ( y
< testofy
){ h
-= testofy
- y
; y
= testofy
; }
1353 if ( x
>= ( int )canvas
->width
) w
= 0; // terminates func
1354 if ( y
>= ( int )canvas
->height
) h
= 0; // terminates func
1355 if ( x
+ w
>= ( int )canvas
->width
) w
= ( int )canvas
->width
- x
;
1356 if ( y
+ h
>= ( int )canvas
->height
) h
= ( int )canvas
->height
- y
;
1358 // Look for conflict with onscreen coordinates and widget
1361 double sx
= ( x
* zoom
) - ( ( canvas
->offsetx
/ zoom
) * zoom
);
1362 double sy
= ( y
* zoom
) - ( ( canvas
->offsety
/ zoom
) * zoom
);
1363 double sw
= w
* zoom
;
1364 double sh
= h
* zoom
;
1365 if ( sx
< 0 ){ sw
+= sx
; sx
= 0; }
1366 if ( sy
< 0 ){ sh
+= sy
; sy
= 0; }
1367 if ( sx
>= canvas
->visibleWidth
) sw
= 0;
1368 if ( sy
>= canvas
->visibleHeight
) sh
= 0;
1369 if ( sx
+ sw
> canvas
->visibleWidth
) sw
= canvas
->visibleWidth
- sx
;
1370 if ( sy
+ sh
> canvas
->visibleHeight
) sh
= canvas
->visibleHeight
- sy
;
1372 // TODO: Check for tool preview size and add to update area
1375 if ( sw
> 0 && sh
> 0 )
1377 // Update screenbuffer
1378 if ( redrawScreenbufferRect ( canvas
, x
, y
, w
, h
, FALSE
) )
1381 canvas
->screenbuffer
, 0, 0, canvas
->visibleWidth
* 4, rp
,
1382 ( int )sx
+ _getAreaOffsetX ( ) + _getAreaLeft ( ),
1383 ( int )sy
+ _getAreaOffsetY ( ) + _getAreaTop ( ),
1384 ( int )sw
, ( int )sh
, RECTFMT_RAW
1390 void importImageRAW ( unsigned int w
, unsigned int h
, unsigned long long int *buffer
)
1392 // We have a filename!!
1393 char *filename
= getFilename ( );
1394 if ( filename
!= NULL
)
1396 if ( getFilesize ( filename
) == 8 * w
* h
)
1400 if ( ( myfile
= Open ( filename
, MODE_OLDFILE
) ) != BNULL
)
1402 Read ( myfile
, buffer
, 8 * w
* h
);
1404 MUI_Redraw ( globalActiveWindow
->area
, MADF_DRAWUPDATE
);
1407 FreeVec ( filename
);
1411 BOOL
loadDatatypeImage ( )
1413 char *filename
= getFilename ( );
1414 BOOL result
= FALSE
;
1416 if ( filename
!= NULL
)
1418 unsigned int size
= getFilesize ( filename
);
1423 Object
*myDtObj
= NewDTObject (
1425 DTA_GroupID
, GID_PICTURE
,
1427 PDTA_DestMode
, PMODE_V43
,
1428 PDTA_Screen
, ( IPTR
)lunaPubScreen
,
1432 if ( myDtObj
!= NULL
)
1435 struct BitMapHeader
*bHead
= NULL
;
1436 struct pdtBlitPixelArray message
;
1438 GetDTAttrs ( myDtObj
, PDTA_BitMapHeader
, &bHead
, TAG_END
);
1440 // Do some memtests before you commence
1441 BOOL proceed
= TRUE
;
1443 unsigned long long int *memtest
=
1444 AllocVec ( bHead
->bmh_Width
* bHead
->bmh_Height
* 8 * 3, MEMF_ANY
);
1445 if ( memtest
== NULL
)
1447 else FreeVec ( memtest
);
1449 unsigned int *bitmap
= AllocVec ( bHead
->bmh_Width
* bHead
->bmh_Height
* 4, MEMF_ANY
);
1450 if ( bitmap
== NULL
)
1453 // We are proceeding!
1456 message
.MethodID
= PDTM_READPIXELARRAY
;
1457 message
.pbpa_PixelData
= bitmap
;
1458 message
.pbpa_PixelFormat
= PBPAFMT_RGBA
;
1459 message
.pbpa_PixelArrayMod
= bHead
->bmh_Width
* 4;
1460 message
.pbpa_Left
= 0;
1461 message
.pbpa_Top
= 0;
1462 message
.pbpa_Width
= bHead
->bmh_Width
;
1463 message
.pbpa_Height
= bHead
->bmh_Height
;
1465 DoMethodA ( myDtObj
, ( Msg
)&message
);
1468 bHead
->bmh_Width
, bHead
->bmh_Height
, 1, 1, TRUE
1471 int y
= 0; for ( ; y
< bHead
->bmh_Height
; y
++ )
1473 int pixy
= y
* bHead
->bmh_Width
;
1474 int x
= 0; for ( ; x
< bHead
->bmh_Width
; x
++ )
1476 unsigned long long int r
= 0ULL, g
= 0ULL, b
= 0ULL, a
= 0ULL;
1478 unsigned int p
= bitmap
[ pixy
+ x
];
1480 r
= ( ( p
<< 24 ) >> 24 ) * 256;
1481 g
= ( ( p
<< 16 ) >> 24 ) * 256;
1482 b
= ( ( p
<< 8 ) >> 24 ) * 256;
1483 if ( bHead
->bmh_Depth
== 24 )
1486 a
= ( p
>> 24 ) * 256;
1488 globalActiveCanvas
->activebuffer
[ pixy
+ x
] =
1489 ( r
<< 48 ) | ( g
<< 32 ) | ( b
<< 16 ) | a
;
1494 DisposeDTObject ( myDtObj
);
1495 set ( globalActiveWindow
->win
, MUIA_Window_Title
, ( STRPTR
)filename
);
1496 set ( globalActiveWindow
->projName
, MUIA_String_Contents
, ( STRPTR
)filename
);
1499 else printf ( "Not enough memory.\n" );
1503 FreeVec ( filename
);
1508 void removePrevToolPreview ( )
1510 if ( globalActiveWindow
->prevBlit
.w
> 0 && globalActiveWindow
->prevBlit
.h
> 0 )
1512 int Tool
= globalCurrentTool
;
1513 globalCurrentTool
= -1;
1515 // Blit over prev pos
1517 globalActiveWindow
->prevBlit
.x
, globalActiveWindow
->prevBlit
.y
,
1518 globalActiveWindow
->prevBlit
.w
, globalActiveWindow
->prevBlit
.h
,
1519 globalActiveCanvas
, _rp ( globalActiveWindow
->area
)
1522 globalCurrentTool
= Tool
;
1524 // Clear prevblit coords
1525 globalActiveWindow
->prevBlit
.x
= 0;
1526 globalActiveWindow
->prevBlit
.y
= 0;
1527 globalActiveWindow
->prevBlit
.w
= 0;
1528 globalActiveWindow
->prevBlit
.h
= 0;
1532 void callToolPreview ( )
1534 if ( globalActiveWindow
== NULL
)
1537 // Some vars to be used
1538 int x
= 0, y
= 0, w
= 1, h
= 1; double offx
= 0.0, offy
= 0.0;
1540 switch ( globalCurrentTool
)
1542 case LUNA_TOOL_FILL
:
1543 case LUNA_TOOL_COLORPICKER
:
1552 case LUNA_TOOL_BRUSH
:
1554 offx
= ( double )brushTool
.width
/ 2;
1555 offy
= ( double )brushTool
.height
/ 2;
1558 w
= brushTool
.width
;
1559 h
= brushTool
.height
;
1562 case LUNA_TOOL_LINE
:
1564 if ( lineTool
.mode
== 0 )
1566 offx
= ( double )brushTool
.width
/ 2;
1567 offy
= ( double )brushTool
.height
/ 2;
1570 w
= brushTool
.width
;
1571 h
= brushTool
.height
;
1573 else if ( lineTool
.mode
== 1 )
1582 case LUNA_TOOL_RECTANGLE
:
1584 if ( rectangleTool
.mode
== 0 )
1586 offx
= ( double )brushTool
.width
/ 2;
1587 offy
= ( double )brushTool
.height
/ 2;
1590 w
= brushTool
.width
;
1591 h
= brushTool
.height
;
1593 else if ( rectangleTool
.mode
== 1 )
1595 x
= rectangleTool
.ox
;
1596 y
= rectangleTool
.oy
;
1597 w
= rectangleTool
.w
;
1598 h
= rectangleTool
.h
;
1602 case LUNA_TOOL_CIRCLE
:
1604 if ( circleTool
.mode
== 0 )
1606 offx
= ( double )brushTool
.width
/ 2;
1607 offy
= ( double )brushTool
.height
/ 2;
1610 w
= brushTool
.width
;
1611 h
= brushTool
.height
;
1613 else if ( circleTool
.mode
== 1 )
1617 w
= circleTool
.bufwidth
;
1618 h
= circleTool
.bufheight
;
1622 case LUNA_TOOL_CLIPBRUSH
:
1624 if ( clipbrushTool
.mode
== 0 )
1631 else if ( clipbrushTool
.mode
== 1 )
1633 x
= clipbrushTool
.ox
;
1634 y
= clipbrushTool
.oy
;
1635 w
= clipbrushTool
.w
;
1636 h
= clipbrushTool
.h
;
1643 if ( !w
|| !h
) return;
1644 blitToolPreview ( x
- 1, y
- 1, w
+ 2, h
+ 2 );
1647 void blitToolPreview ( int x
, int y
, int w
, int h
)
1649 removePrevToolPreview ( );
1650 blitAreaRect ( x
, y
, w
, h
, globalActiveCanvas
, _rp ( globalActiveWindow
->area
) );
1651 globalActiveWindow
->prevBlit
= ( struct RectStruct
){ x
, y
, w
, h
};
1654 ULONG
_getAreaWidth ( )
1656 ULONG ideal
= globalActiveCanvas
->width
* globalActiveCanvas
->zoom
;
1657 ULONG view
= XGET ( globalActiveWindow
->area
, MUIA_Width
);
1664 ULONG
_getAreaHeight ( )
1666 ULONG ideal
= globalActiveCanvas
->height
* globalActiveCanvas
->zoom
;
1667 ULONG view
= XGET ( globalActiveWindow
->area
, MUIA_Height
);
1673 ULONG
_getAreaTop ( )
1675 return XGET ( globalActiveWindow
->area
, MUIA_TopEdge
);
1678 ULONG
_getAreaLeft ( )
1680 return XGET ( globalActiveWindow
->area
, MUIA_LeftEdge
);
1683 ULONG
_getAreaOffsetX ( )
1685 ULONG screenOffX
= XGET ( globalActiveWindow
->area
, MUIA_Width
);
1686 ULONG view
= _getAreaWidth ( );
1687 if ( screenOffX
> view
)
1688 screenOffX
= ( screenOffX
/ 2.0 ) - ( view
/ 2.0 );
1689 else screenOffX
= 0;
1693 ULONG
_getAreaOffsetY ( )
1695 ULONG screenOffY
= XGET ( globalActiveWindow
->area
, MUIA_Height
);
1696 ULONG view
= _getAreaHeight ( );
1697 if ( screenOffY
> view
)
1698 screenOffY
= ( screenOffY
/ 2.0 ) - ( view
/ 2.0 );
1699 else screenOffY
= 0;