Fixed comment typos.
[AROS.git] / workbench / libs / muimaster / dragndrop.c
blobf83bbbe7ad1debdf55e6645cf70d1a477cabc46b
1 /*
2 Copyright © 2002-2011, The AROS Development Team.
3 All rights reserved.
5 $Id$
6 */
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <math.h>
12 #include <exec/devices.h>
13 #include <exec/memory.h>
14 #include <workbench/icon.h>
16 #include <clib/alib_protos.h>
18 #include <cybergraphx/cybergraphics.h>
19 #include <proto/cybergraphics.h>
20 #include <proto/graphics.h>
21 #include <proto/exec.h>
22 #include <proto/intuition.h>
23 #include <proto/icon.h>
24 #include <proto/wb.h>
25 #include <proto/timer.h>
26 #include <proto/utility.h>
28 #include "dragndrop.h"
29 #include "muimaster_intern.h"
30 #include "support.h"
32 /* #define MYDEBUG 1 */
33 #include "debug.h"
35 extern struct Library *MUIMasterBase;
37 #ifdef __MAXON__
39 ULONG IconControl(struct DiskObject *icon, ...)
41 return IconControlA(icon, (struct TagItem *)((((ULONG *) & icon) + 1)));
44 struct DiskObject *GetIconTags(CONST_STRPTR name, ...)
46 return GetIconTagList(name, (struct TagItem *)(((ULONG *) & name) + 1));
50 #define ASM
52 #else
54 #ifdef __SASC
55 #define ASM __asm
56 #else
57 #define ASM
58 #endif
60 #endif
62 //-------------------------------------
63 // List Funcs
64 //-------------------------------------
65 static struct MinNode *Node_Prev(APTR node)
67 if (node == NULL)
68 return NULL;
69 if (((struct MinNode *)node)->mln_Pred == NULL)
70 return NULL;
71 if (((struct MinNode *)node)->mln_Pred->mln_Pred == NULL)
72 return NULL;
73 return ((struct MinNode *)node)->mln_Pred;
75 //-------------------------------------
77 //-------------------------------------
78 static struct MinNode *List_Last(APTR list)
80 if (!((struct MinList *)list)->mlh_TailPred)
81 return NULL;
83 if (((struct MinList *)list)->mlh_TailPred->mln_Pred == NULL)
84 return NULL;
85 return ((struct MinList *)list)->mlh_TailPred;
87 //-------------------------------------
88 #if 0
89 static ULONG List_Length(APTR list)
91 struct MinNode *node = List_First(list);
92 ULONG len = 0;
93 while (node)
95 len++;
96 node = Node_Next(node);
98 return len;
100 //-------------------------------------
101 static struct MinNode *List_Find(APTR list, ULONG num)
103 struct MinNode *node = List_First(list);
104 while (num--)
106 if (!(node = Node_Next(node)))
107 break;
109 return node;
111 #endif
112 //-------------------------------------
114 struct DragNDrop
116 struct MinList dnd_List;
117 struct Screen *dnd_Screen;
118 struct BitMap *dnd_TempBitMap;
121 struct RastPort dnd_RastPort;
122 struct Layer_Info *dnd_LayerInfo;
123 struct Layer *dnd_Layer;
127 struct BitMapNode
129 struct MinNode bmn_Node;
130 struct BitMap *bmn_BitMap; /* This bitmap is external and not to be modified */
131 APTR bmn_Mask;
133 LONG bmn_Left;
134 LONG bmn_Top;
135 LONG bmn_Width;
136 LONG bmn_Height;
138 LONG bmn_SaveX;
139 LONG bmn_SaveY;
140 LONG bmn_SaveWidth;
141 LONG bmn_SaveHeight;
142 LONG bmn_SaveOffX;
143 LONG bmn_SaveOffY;
144 LONG bmn_Drawed;
145 struct BitMap *bmn_SaveBitMap;
147 struct DragNDrop *bmn_DnD;
149 /* Basic alpha-blitting implementation */
150 APTR bmn_BitMapBuffer; /* Same data as bmn_BitMap but 32-bit ARGB */
153 #define bmn_Succ bmn_Node.mln_Succ
154 #define bmn_Pred bmn_Node.mln_Pred
156 //-------------------------------------
157 STATIC VOID List_Sort_Mode_1(struct MinList *list)
159 BOOL notfinished = TRUE;
161 /* Sort list (quick & dirty bubble sort) */
162 while (notfinished)
164 struct BitMapNode *first;
166 /* Reset not finished flag */
167 notfinished = FALSE;
169 /* Get first node */
170 if ((first = List_First(list)))
172 struct BitMapNode *second;
174 /* One bubble sort round */
175 while ((second = Node_Next(first)))
177 BOOL sort;
178 if (first->bmn_Top > second->bmn_Top)
179 sort = TRUE;
180 else if (first->bmn_Top == second->bmn_Top
181 && first->bmn_Left > second->bmn_Left)
182 sort = TRUE;
183 else
184 sort = FALSE;
186 if (sort)
188 Remove((struct Node *)first);
189 Insert((struct List *)list, (struct Node *)first,
190 (struct Node *)second);
191 notfinished = TRUE;
193 else
194 first = second;
199 //-------------------------------------
200 #if 0
201 STATIC VOID List_Sort_Mode_2(struct MinList *list)
203 BOOL notfinished = TRUE;
205 /* Sort list (quick & dirty bubble sort) */
206 while (notfinished)
208 struct BitMapNode *first;
210 /* Reset not finished flag */
211 notfinished = FALSE;
213 /* Get first node */
214 if ((first = List_First(list)))
216 struct BitMapNode *second;
218 /* One bubble sort round */
219 while ((second = Node_Next(first)))
221 BOOL sort;
222 if (first->bmn_Top > second->bmn_Top)
223 sort = TRUE;
224 else if (first->bmn_Top == second->bmn_Top
225 && first->bmn_Left < second->bmn_Left)
226 sort = TRUE;
227 else
228 sort = FALSE;
230 if (sort)
232 Remove((struct Node *)first);
233 Insert((struct List *)list, (struct Node *)first,
234 (struct Node *)second);
235 notfinished = TRUE;
237 else
238 first = second;
243 #endif
244 //-------------------------------------
245 STATIC VOID List_Sort_Mode_3(struct MinList *list)
247 BOOL notfinished = TRUE;
249 /* Sort list (quick & dirty bubble sort) */
250 while (notfinished)
252 struct BitMapNode *first;
254 /* Reset not finished flag */
255 notfinished = FALSE;
257 /* Get first node */
258 if ((first = List_First(list)))
260 struct BitMapNode *second;
262 /* One bubble sort round */
263 while ((second = Node_Next(first)))
265 BOOL sort;
266 if (first->bmn_Left > second->bmn_Left)
267 sort = TRUE;
268 else if (first->bmn_Left == second->bmn_Left
269 && first->bmn_Top > second->bmn_Top)
270 sort = TRUE;
271 else
272 sort = FALSE;
274 if (sort)
276 Remove((struct Node *)first);
277 Insert((struct List *)list, (struct Node *)first,
278 (struct Node *)second);
279 notfinished = TRUE;
281 else
282 first = second;
287 //-------------------------------------
288 STATIC BOOL AndRectangle(struct Rectangle *a, struct Rectangle *b,
289 struct Rectangle *c)
291 c->MinX = MAX(a->MinX, b->MinX);
292 c->MinY = MAX(a->MinY, b->MinY);
293 c->MaxX = MIN(a->MaxX, b->MaxX);
294 c->MaxY = MIN(a->MaxY, b->MaxY);
296 if ((c->MinX > c->MaxX) || (c->MinY > c->MaxY))
297 return FALSE;
299 return TRUE;
301 //-------------------------------------
303 //-------------------------------------
304 STATIC VOID SafeBltBitMapRastPort(struct BitMap *srcBitMap, long xSrc,
305 long ySrc, struct RastPort *destRP, long xDest, long yDest, long xSize,
306 long ySize, unsigned long minterm)
308 struct BitMap *destBitMap = destRP->BitMap;
309 LONG srcMaxWidth, srcMaxHeight;
310 LONG destMaxWidth, destMaxHeight;
312 srcMaxWidth = GetBitMapAttr(srcBitMap, BMA_WIDTH);
313 srcMaxHeight = GetBitMapAttr(srcBitMap, BMA_HEIGHT);
314 destMaxWidth = GetBitMapAttr(destBitMap, BMA_WIDTH);
315 destMaxHeight = GetBitMapAttr(destBitMap, BMA_HEIGHT);
317 if (xSrc < 0)
319 xDest -= xSrc;
320 xSize += xSrc;
321 xSrc = 0;
324 if (ySrc < 0)
326 yDest -= ySrc;
327 ySize += ySrc;
328 ySrc = 0;
331 if (xDest < 0)
333 xSrc -= xDest;
334 xSize += xDest;
335 xDest = 0;
338 if (yDest < 0)
340 ySrc -= yDest;
341 ySize += yDest;
342 yDest = 0;
345 if (xSize + xSrc > srcMaxWidth)
346 xSize = srcMaxWidth - xSrc;
347 if (ySize + ySrc > srcMaxHeight)
348 ySize = srcMaxHeight - ySrc;
349 if (xSize + xDest > destMaxWidth)
350 xSize = destMaxWidth - xDest;
351 if (ySize + yDest > destMaxHeight)
352 ySize = destMaxHeight - yDest;
354 if (xSize > 0 && ySize > 0)
356 BltBitMapRastPort(srcBitMap, xSrc, ySrc, destRP, xDest, yDest,
357 xSize, ySize, minterm);
360 //-------------------------------------
361 STATIC LONG SafeBltBitMap(struct BitMap *srcBitMap, long xSrc, long ySrc,
362 struct BitMap *destBitMap, long xDest, long yDest, long xSize,
363 long ySize, unsigned long minterm, unsigned long mask, PLANEPTR tempA)
365 LONG srcMaxWidth, srcMaxHeight;
366 LONG destMaxWidth, destMaxHeight;
368 srcMaxWidth = GetBitMapAttr(srcBitMap, BMA_WIDTH);
369 srcMaxHeight = GetBitMapAttr(srcBitMap, BMA_HEIGHT);
370 destMaxWidth = GetBitMapAttr(destBitMap, BMA_WIDTH);
371 destMaxHeight = GetBitMapAttr(destBitMap, BMA_HEIGHT);
373 if (xSrc < 0)
375 xDest -= xSrc;
376 xSize += xSrc;
377 xSrc = 0;
380 if (ySrc < 0)
382 yDest -= ySrc;
383 ySize += ySrc;
384 ySrc = 0;
387 if (xDest < 0)
389 xSrc -= xDest;
390 xSize += xDest;
391 xDest = 0;
394 if (yDest < 0)
396 ySrc -= yDest;
397 ySize += yDest;
398 yDest = 0;
401 if (xSize + xSrc > srcMaxWidth)
402 xSize = srcMaxWidth - xSrc;
403 if (ySize + ySrc > srcMaxHeight)
404 ySize = srcMaxHeight - ySrc;
405 if (xSize + xDest > destMaxWidth)
406 xSize = destMaxWidth - xDest;
407 if (ySize + yDest > destMaxHeight)
408 ySize = destMaxHeight - yDest;
410 if (xSize > 0 && ySize > 0)
412 return BltBitMap(srcBitMap, xSrc, ySrc, destBitMap, xDest, yDest,
413 xSize, ySize, minterm, mask, tempA);
415 return 0;
418 //-------------------------------------
419 STATIC VOID BltBackgroundBitMap(struct BitMapNode *dest_bmn, long xSrc,
420 long ySrc, long xSize, long ySize, ULONG use_temp)
422 struct BitMap *srcBitMap, *destBitMap;
423 struct DragNDrop *dnd = dest_bmn->bmn_DnD;
424 LONG maxWidth, maxHeight;
425 LONG xDest = 0, yDest = 0;
427 struct Rectangle rect;
428 rect.MinX = xSrc;
429 rect.MinY = ySrc;
430 rect.MaxX = xSrc + xSize - 1;
431 rect.MaxY = ySrc + ySize - 1;
433 srcBitMap = dnd->dnd_Screen->RastPort.BitMap;
435 if (use_temp)
436 destBitMap = dnd->dnd_TempBitMap;
437 else
438 destBitMap = dest_bmn->bmn_SaveBitMap;
440 maxWidth = GetBitMapAttr(srcBitMap, BMA_WIDTH);
441 maxHeight = GetBitMapAttr(srcBitMap, BMA_HEIGHT);
443 if (xSrc < 0)
445 xDest -= xSrc;
446 xSize += xSrc;
447 xSrc = 0;
450 if (ySrc < 0)
452 yDest -= ySrc;
453 ySize += ySrc;
454 ySrc = 0;
457 if (xSize + xSrc > maxWidth)
458 xSize = maxWidth - xSrc;
459 if (ySize + ySrc > maxHeight)
460 ySize = maxHeight - ySrc;
462 if (xSize > 0 && ySize > 0)
464 struct BitMapNode *bmn = List_First(&dnd->dnd_List);
466 SafeBltBitMap(srcBitMap, xSrc, ySrc, destBitMap, xDest, yDest,
467 xSize, ySize, 0xc0, -1, NULL);
470 // BltBitMapRastPort(destBitMap,0,0,
471 // &dnd->dnd_Screen->RastPort, 2*dest_bmn->bmn_Left+150, dest_bmn->bmn_Top+200, xSize, ySize,0xc0);
473 while (bmn)
475 if (bmn != dest_bmn)
477 struct Rectangle bmn_rect, result_rect;
478 bmn_rect.MinX = bmn->bmn_SaveX;
479 bmn_rect.MinY = bmn->bmn_SaveY;
480 bmn_rect.MaxX = bmn_rect.MinX + bmn->bmn_SaveWidth - 1;
481 bmn_rect.MaxY = bmn_rect.MinY + bmn->bmn_SaveHeight - 1;
483 if (AndRectangle(&rect, &bmn_rect, &result_rect))
485 LONG bmn_x = result_rect.MinX - bmn_rect.MinX;
486 LONG bmn_y = result_rect.MinY - bmn_rect.MinY;
487 LONG bmn_width =
488 result_rect.MaxX - result_rect.MinX + 1;
489 LONG bmn_height =
490 result_rect.MaxY - result_rect.MinY + 1;
491 LONG xDest = result_rect.MinX - rect.MinX;
492 LONG yDest = result_rect.MinY - rect.MinY;
494 SafeBltBitMap(bmn->bmn_SaveBitMap, bmn_x, bmn_y,
495 destBitMap, xDest, yDest, bmn_width, bmn_height,
496 0xc0, -1, NULL);
498 // BltBitMapRastPort(destBitMap,0,0,
499 // &dnd->dnd_Screen->RastPort, 100,300, xSize, ySize,0xc0);
503 bmn = Node_Next(bmn);
506 // BltBitMapRastPort(destBitMap,0,0,
507 // &dnd->dnd_Screen->RastPort, 2*dest_bmn->bmn_Left+150, dest_bmn->bmn_Top+200, xSize, ySize,0xc0);
511 //-------------------------------------
512 STATIC VOID BltBitMapNode(struct BitMapNode *src_bmn, LONG offx, LONG offy,
513 struct RastPort *rp, LONG x, LONG y, LONG width, LONG height)
515 struct BitMap *destBitMap = rp->BitMap;
516 LONG destMaxWidth = GetBitMapAttr(destBitMap, BMA_WIDTH);
517 LONG destMaxHeight = GetBitMapAttr(destBitMap, BMA_HEIGHT);
519 if (x < 0)
521 offx -= x;
522 width += x;
523 x = 0;
526 if (y < 0)
528 offy -= y;
529 height += y;
530 y = 0;
533 if (width + x > destMaxWidth)
534 width = destMaxWidth - x;
535 if (height + y > destMaxHeight)
536 height = destMaxHeight - y;
538 if (width > 0 && height > 0)
540 if (src_bmn->bmn_Mask)
542 BltMaskBitMapRastPort(src_bmn->bmn_BitMap, offx, offy,
543 rp, x, y, width, height, 0xe2,
544 (PLANEPTR) src_bmn->bmn_Mask);
546 else
548 #ifdef __mc68000
549 /* This operation is insanely expensive on slow m68k
550 * machines in planar modes.
552 IPTR depth = GetBitMapAttr(rp->BitMap, BMA_DEPTH);
553 if (depth > 8 && src_bmn->bmn_BitMapBuffer)
554 #else
555 if (src_bmn->bmn_BitMapBuffer)
556 #endif
558 /* This should be done using BltBitMapRastPortAlpha with
559 * direct video card alpha blit, but this function is not
560 * available on AROS yet. Current implementation is that
561 * src_bmn->bmn_BitMapBuffer contains 32bit ARGB buffer
562 * acquired from src_bmn->bmn_BitMap */
563 WritePixelArrayAlpha(src_bmn->bmn_BitMapBuffer, offx, offy,
564 src_bmn->bmn_Width * sizeof(ULONG), rp, x, y, width,
565 height, 0);
567 else
569 BltBitMapRastPort(src_bmn->bmn_BitMap, offx, offy,
570 rp, x, y, width, height, 0xc0);
575 //-------------------------------------
576 STATIC VOID BltNearBitMaps(struct BitMapNode *src_bmn, struct RastPort *rp,
577 LONG x, LONG y, LONG width, LONG height)
579 struct DragNDrop *dnd = src_bmn->bmn_DnD;
580 struct BitMapNode *bmn = List_First(&dnd->dnd_List);
581 struct Rectangle rect;
583 rect.MinX = x;
584 rect.MinY = y;
585 rect.MaxX = x + width - 1;
586 rect.MaxY = y + height - 1;
588 while (bmn)
590 if (bmn != src_bmn && bmn->bmn_Drawed)
592 struct Rectangle bmn_rect, result_rect;
593 bmn_rect.MinX = bmn->bmn_SaveX;
594 bmn_rect.MinY = bmn->bmn_SaveY;
595 bmn_rect.MaxX = bmn_rect.MinX + bmn->bmn_SaveWidth - 1;
596 bmn_rect.MaxY = bmn_rect.MinY + bmn->bmn_SaveHeight - 1;
598 if (AndRectangle(&rect, &bmn_rect, &result_rect))
600 LONG bmn_x = result_rect.MinX - bmn_rect.MinX;
601 LONG bmn_y = result_rect.MinY - bmn_rect.MinY;
602 LONG bmn_width = result_rect.MaxX - result_rect.MinX + 1;
603 LONG bmn_height = result_rect.MaxY - result_rect.MinY + 1;
604 LONG xDest = result_rect.MinX - rect.MinX;
605 LONG yDest = result_rect.MinY - rect.MinY;
607 BltBitMapNode(bmn, bmn_x, bmn_y,
608 rp, xDest, yDest, bmn_width, bmn_height);
612 bmn = Node_Next(bmn);
615 //-------------------------------------
616 STATIC VOID RestoreBackground(struct BitMapNode *src_bmn,
617 struct RastPort *rp)
619 LONG save_x = src_bmn->bmn_SaveX;
620 LONG save_y = src_bmn->bmn_SaveY;
621 LONG save_width = src_bmn->bmn_SaveWidth;
622 LONG save_height = src_bmn->bmn_SaveHeight;
624 struct DragNDrop *dnd = src_bmn->bmn_DnD;
625 struct BitMapNode *bmn = List_First(&dnd->dnd_List);
626 struct Rectangle last_rect;
628 last_rect.MinX = save_x;
629 last_rect.MinY = save_y;
630 last_rect.MaxX = save_x + save_width - 1;
631 last_rect.MaxY = save_y + save_height - 1;
633 SafeBltBitMapRastPort(src_bmn->bmn_SaveBitMap, 0, 0,
634 rp, save_x, save_y, save_width, save_height, 0xc0);
637 while (bmn)
639 if (bmn != src_bmn && bmn->bmn_Drawed)
641 struct Rectangle bmn_rect, result_rect;
642 bmn_rect.MinX = bmn->bmn_SaveX;
643 bmn_rect.MinY = bmn->bmn_SaveY;
644 bmn_rect.MaxX = bmn_rect.MinX + bmn->bmn_SaveWidth - 1;
645 bmn_rect.MaxY = bmn_rect.MinY + bmn->bmn_SaveHeight - 1;
647 if (AndRectangle(&last_rect, &bmn_rect, &result_rect))
649 LONG bmn_x = result_rect.MinX - bmn_rect.MinX;
650 LONG bmn_y = result_rect.MinY - bmn_rect.MinY;
651 LONG bmn_width = result_rect.MaxX - result_rect.MinX + 1;
652 LONG bmn_height = result_rect.MaxY - result_rect.MinY + 1;
653 /* LONG xDest = result_rect.MinX - last_rect.MinX; */
654 /* LONG yDest = result_rect.MinY - last_rect.MinY; */
656 BltBitMapNode(bmn, bmn_x, bmn_y,
657 rp, result_rect.MinX, result_rect.MinY, bmn_width,
658 bmn_height);
660 // SafeBltBitMapRastPort(bmn->bmn_SaveBitMap, bmn_x, bmn_y,
661 // rp, xDest, yDest, bmn_width, bmn_height,0xc0);
665 bmn = Node_Next(bmn);
668 //-------------------------------------
669 struct BitMapNode *CreateBitMapNodeA(struct TagItem *tagList)
671 struct BitMapNode *bmn =
672 (struct BitMapNode *)AllocMem(sizeof(struct BitMapNode),
673 MEMF_CLEAR);
674 if (bmn)
676 BOOL sourcealpha = FALSE;
677 struct TagItem *tl = tagList;
678 struct TagItem *tag;
680 while ((tag = NextTagItem(&tl)))
682 ULONG id = tag->ti_Tag;
683 IPTR data = tag->ti_Data;
685 switch (id)
687 case GUI_BitMap:
688 bmn->bmn_BitMap = (struct BitMap *)data;
689 break;
691 case GUI_Mask:
692 bmn->bmn_Mask = (APTR) data;
693 break;
695 case GUI_LeftOffset:
696 bmn->bmn_Left = data;
697 break;
699 case GUI_TopOffset:
700 bmn->bmn_Top = data;
701 break;
703 case GUI_Width:
704 bmn->bmn_Width = data;
705 break;
707 case GUI_Height:
708 bmn->bmn_Height = data;
709 break;
711 case GUI_SourceAlpha:
712 sourcealpha = data;
713 break;
717 if (!bmn->bmn_BitMap)
719 FreeMem(bmn, sizeof(struct BitMapNode));
720 bmn = NULL;
723 if (bmn && sourcealpha)
725 /* See notes in BltBitMapNode */
726 struct RastPort temp_rp;
727 InitRastPort(&temp_rp);
728 temp_rp.BitMap = bmn->bmn_BitMap;
729 bmn->bmn_BitMapBuffer =
730 AllocVec(bmn->bmn_Width * bmn->bmn_Height * sizeof(ULONG),
731 MEMF_ANY);
732 ReadPixelArray(bmn->bmn_BitMapBuffer, 0, 0,
733 bmn->bmn_Width * sizeof(ULONG), &temp_rp, 0, 0,
734 bmn->bmn_Width, bmn->bmn_Height, RECTFMT_ARGB);
735 DeinitRastPort(&temp_rp);
738 return bmn;
740 //-------------------------------------
741 VOID DeleteBitMapNode(struct BitMapNode *bmn)
743 if (bmn->bmn_SaveBitMap)
744 FreeBitMap(bmn->bmn_SaveBitMap);
745 FreeVec(bmn->bmn_BitMapBuffer);
746 FreeMem(bmn, sizeof(struct BitMapNode));
748 //-------------------------------------
749 struct BitMap *GetBitMap(struct BitMapNode *bmn)
751 if (bmn)
752 return bmn->bmn_BitMap;
753 return NULL;
755 //-------------------------------------
756 VOID AttachBitMapNode(struct DragNDrop *dnd, struct BitMapNode *bmn)
758 AddTail((struct List *)&dnd->dnd_List, (struct Node *)&bmn->bmn_Node);
759 bmn->bmn_DnD = dnd;
761 //-------------------------------------
762 VOID DetachBitMapNode(struct BitMapNode *bmn)
764 if (bmn->bmn_Succ && bmn->bmn_Pred)
766 Remove((struct Node *)&bmn->bmn_Node);
767 bmn->bmn_Succ = bmn->bmn_Pred = NULL;
769 bmn->bmn_DnD = NULL;
771 //-------------------------------------
772 VOID DrawBitMapNode(struct BitMapNode *bmn, LONG x, LONG y)
774 LONG width = bmn->bmn_Width;
775 LONG height = bmn->bmn_Height;
776 LONG save_x = bmn->bmn_SaveX;
777 LONG save_y = bmn->bmn_SaveY;
778 LONG save_width = bmn->bmn_SaveWidth;
779 LONG save_height = bmn->bmn_SaveHeight;
780 struct RastPort *rp;
781 struct BitMap *temp_bmap;
782 BOOL draw = TRUE; //FALSE;
784 if (!bmn || !bmn->bmn_DnD || !bmn->bmn_DnD->dnd_Screen)
785 return;
786 rp = &bmn->bmn_DnD->dnd_Screen->RastPort;
787 temp_bmap = bmn->bmn_DnD->dnd_TempBitMap;
789 if (!bmn->bmn_SaveBitMap)
790 return;
792 /* if( bmn->bmn_SaveWidth > 0 && bmn->bmn_SaveHeight > 0 )
794 if(!temp_bmap)
796 RestoreBackground(bmn,rp);
801 LONG maxWidth,
802 maxHeight /* , offx=0, offy=0, save_offx=0, save_offy=0 */ ;
803 LONG real_width = width, real_height = height;
804 LONG real_save_width = save_width, real_save_height = save_height;
806 maxWidth = GetBitMapAttr(rp->BitMap, BMA_WIDTH);
807 maxHeight = GetBitMapAttr(rp->BitMap, BMA_HEIGHT);
809 if (x < 0)
810 real_width += x;
811 if (y < 0)
812 real_height += y;
813 if (save_x < 0)
814 real_save_width += save_x;
815 if (save_y < 0)
816 real_save_height += save_y;
818 if (real_width + x > maxWidth)
819 real_width = maxWidth - x;
820 if (real_height + y > maxHeight)
821 real_height = maxHeight - y;
822 if (real_save_width + x > maxWidth)
823 real_save_width = maxWidth - x;
824 if (real_save_height + y > maxHeight)
825 real_save_height = maxHeight - y;
827 if ((real_width > 0 && real_height > 0) || (real_save_width > 0
828 && real_save_height > 0))
829 draw = TRUE;
832 if (draw)
834 if (!temp_bmap)
836 // SafeBltBitMap(rp->BitMap, x,y,
837 // bmn->bmn_SaveBitMap, 0,0, width, height, 0xc0, -1, NULL);
839 // bmn->bmn_SaveWidth = 0;
840 // bmn->bmn_SaveHeight = 0;
842 // BltBackgroundBitMap(bmn->bmn_DnD, x, y,
843 // bmn->bmn_SaveBitMap, 0,0, width, height);
845 if (bmn->bmn_SaveWidth > 0 && bmn->bmn_SaveHeight > 0)
846 RestoreBackground(bmn, rp);
848 BltBackgroundBitMap(bmn, x, y, width, height, FALSE);
850 // BltBitMapRastPort(bmn->bmn_SaveBitMap,0,0,
851 // rp, 20+bmn->bmn_Left*2,20+bmn->bmn_Top,width,height,0xc0);
854 BltBitMapNode(bmn, 0, 0, rp, x, y, width, height);
856 else
858 struct RastPort temp_rp;
859 struct Rectangle save_rect, rect, result_rect;
860 InitRastPort(&temp_rp);
861 temp_rp.BitMap = temp_bmap;
863 save_rect.MinX = save_x;
864 save_rect.MinY = save_y;
865 save_rect.MaxX = save_x + save_width - 1;
866 save_rect.MaxY = save_y + save_height - 1;
868 rect.MinX = x;
869 rect.MinY = y;
870 rect.MaxX = x + width - 1;
871 rect.MaxY = y + height - 1;
873 if (AndRectangle(&rect, &save_rect, &result_rect))
875 LONG result_width = result_rect.MaxX - result_rect.MinX + 1;
876 LONG result_height =
877 result_rect.MaxY - result_rect.MinY + 1;
878 LONG result_x = result_rect.MinX - save_rect.MinX;
879 LONG result_y = result_rect.MinY - save_rect.MinY;
880 // cout << rect.MinX << " " << rect.MaxX << " " << rect.MinY << " " << rect.MaxY << endl;
881 // cout << save_rect.MinX << " " << save_rect.MaxX << " " << save_rect.MinY << " " << save_rect.MaxY << endl;
882 // cout << result_rect.MinX << " " << result_rect.MaxX << " " << result_rect.MinY << " " << result_rect.MaxY << endl;
883 // cout << "soffx:" << save_offx << " offx:" << offx << " rx:" << result_x << " " << result_y << " " << " w: " << width << " " << result_width << " " << result_height << endl;
885 // SetRast(&temp_rp,0);
887 // Neuen Hintergrund in temporäre Bitmap
888 // SafeBltBitMapRastPort( rp->BitMap, x, y,
889 // &temp_rp, 0, 0, width, height,0xc0);
891 BltBackgroundBitMap(bmn, x, y, width, height, TRUE);
893 /* Debug code */
894 // BltBitMapRastPort(temp_bmap,0,0,rp,100+bmn->bmn_Left,
895 // 20+bmn->bmn_Top,bmn->bmn_Width,bmn->bmn_Height,0xc0);
897 // Teile des alten Hintergrundes, die neu verdeckt werden in temporäre Bitmap
898 BltBitMapRastPort(bmn->bmn_SaveBitMap, result_x, result_y,
899 &temp_rp, (result_x ? 0 : (save_width - result_width)),
900 result_y ? 0 : (save_height - result_height),
901 result_width, result_height, 0xc0);
903 /* Debug code */
904 // BltBitMapRastPort(temp_bmap,0,0,rp,180+bmn->bmn_Left,
905 // 20+bmn->bmn_Top,bmn->bmn_Width,bmn->bmn_Height,0xc0);
908 // Teile des alten Hintergrundes, die nicht mehr verdeckt werden auf Screen
909 if ((save_width - result_width) > 0)
911 SafeBltBitMapRastPort(bmn->bmn_SaveBitMap,
912 (result_x ? 0 : (result_width)), 0, rp,
913 save_x + (result_x ? 0 : (result_width)), save_y,
914 save_width - result_width, save_height, 0xc0);
917 if ((save_height - result_height) > 0)
919 SafeBltBitMapRastPort(bmn->bmn_SaveBitMap, 0,
920 result_y ? 0 : (result_height), rp, save_x,
921 save_y + (result_y ? 0 : (result_height)),
922 save_width, save_height - result_height, 0xc0);
925 // temporäre BitMap ist neuer Hintergrund
926 BltBitMap(temp_bmap, 0, 0,
927 bmn->bmn_SaveBitMap, 0, 0, width, height, 0xc0, -1,
928 NULL);
930 /* Blit drag image bitmap to temporary bitmap */
931 BltBitMapNode(bmn, 0, 0, &temp_rp, 0, 0, width, height);
933 // Angenzende BitMaps in temporäre BitMap
934 BltNearBitMaps(bmn, &temp_rp, x, y, width, height);
936 /* Debug code */
937 // BltBitMapRastPort(temp_bmap,0,0,rp,240+bmn->bmn_Left,
938 // 20+bmn->bmn_Top,width,height,0xc0);
941 /* Blit prepared temporaty bitmap to screen */
942 SafeBltBitMapRastPort(temp_bmap, 0, 0,
943 rp, x, y, width, height, 0xc0);
945 /* Debug code */
946 // BltBitMapRastPort(bmn->bmn_SaveBitMap,0,0,rp,40+bmn->bmn_Left,
947 // 20+bmn->bmn_Top,bmn->bmn_Width,bmn->bmn_Height,0xc0);
950 else
952 if (bmn->bmn_SaveWidth > 0 && bmn->bmn_SaveHeight > 0)
953 RestoreBackground(bmn, rp);
955 BltBackgroundBitMap(bmn, x, y, width, height, FALSE);
957 /* BltBitMapRastPort( bmn->bmn_SaveBitMap,0,0,
958 rp, bmn->bmn_SaveX, bmn->bmn_SaveY, bmn->bmn_SaveWidth, bmn->bmn_SaveHeight, 0xc0 );
960 SafeBltBitMap(rp->BitMap, x,y,
961 bmn->bmn_SaveBitMap, 0,0, width, height, 0xc0, -1, NULL);
963 BltBitMapNode(bmn, 0, 0, rp, x, y, width, height);
968 bmn->bmn_Drawed = TRUE;
969 bmn->bmn_SaveX = x;
970 bmn->bmn_SaveY = y;
971 bmn->bmn_SaveWidth = width;
972 bmn->bmn_SaveHeight = height;
973 // bmn->bmn_SaveOffX = offx;
974 // bmn->bmn_SaveOffY = offy;
976 //-------------------------------------
977 VOID UndrawBitMapNode(struct BitMapNode *bmn)
979 struct RastPort *rp = &bmn->bmn_DnD->dnd_Screen->RastPort;
981 if (!bmn->bmn_SaveBitMap)
982 return;
984 if (bmn->bmn_SaveWidth > 0 && bmn->bmn_SaveHeight > 0)
986 SafeBltBitMapRastPort(bmn->bmn_SaveBitMap, 0, 0,
987 rp, bmn->bmn_SaveX, bmn->bmn_SaveY, bmn->bmn_SaveWidth,
988 bmn->bmn_SaveHeight, 0xc0);
990 bmn->bmn_SaveWidth = 0;
991 bmn->bmn_SaveHeight = 0;
993 //-------------------------------------
995 //-------------------------------------
996 struct DragNDrop *CreateDragNDropA(struct TagItem *tlist)
998 struct DragNDrop *dnd =
999 (struct DragNDrop *)AllocMem(sizeof(struct DragNDrop), MEMF_CLEAR);
1000 if (dnd)
1002 NewList((struct List *)&dnd->dnd_List);
1004 /* if(dnd->dnd_LayerInfo = NewLayerInfo()))
1006 dnd->dnd_Screen = NULL
1007 dnd->dnd_TempBitMap = NULL;
1010 struct RastPort *rp = &dnd->dnd_RastPort;
1011 InitRastPort(rp);
1013 rp->BitMap =
1015 if(dnd->dnd_Layer = CreateBehindLayer(dnd->dnd_LayerInfo,
1017 return dnd;
1019 FreeMem( dnd, sizeof(struct DragNDrop ));*/
1021 return dnd;
1022 // return NULL;
1024 //-------------------------------------
1025 VOID DeleteDragNDrop(struct DragNDrop *dnd)
1027 struct BitMapNode *node;
1029 FinishDragNDrop(dnd);
1031 while ((node =
1032 (struct BitMapNode *)RemTail((struct List *)&dnd->dnd_List)))
1033 DeleteBitMapNode(node);
1035 FreeMem(dnd, sizeof(struct DragNDrop));
1037 //-------------------------------------
1038 VOID DrawDragNDrop(struct DragNDrop *dnd, LONG x, LONG y)
1040 static LONG lastx;
1041 static LONG lasty;
1042 // static LONG first=TRUE;
1044 struct BitMapNode *node;
1045 BOOL reverse;
1046 LONG diffx = x - lastx;
1047 LONG diffy = y - lasty;
1049 if (!dnd || !dnd->dnd_Screen)
1050 return;
1052 reverse = FALSE;
1054 if (abs(diffy) < abs(diffx)) //y==lasty)
1056 if (diffx > 0)
1057 reverse = TRUE;
1058 List_Sort_Mode_3(&dnd->dnd_List);
1060 else
1062 if (diffy > 0)
1063 reverse = TRUE;
1064 List_Sort_Mode_1(&dnd->dnd_List);
1068 /* if(first) reverse = FALSE;
1069 else
1071 if( x<lastx) reverse = FALSE;
1072 else
1074 if(x==lastx && y < lasty) reverse=FALSE;
1075 else reverse = TRUE;
1078 if(x>lastx && y < lasty)
1080 List_Sort_Mode_2(&dnd->dnd_List);
1081 reverse=FALSE;
1082 } else
1084 if(x<lastx && y > lasty)
1086 List_Sort_Mode_2(&dnd->dnd_List);
1087 reverse=TRUE;
1092 // cout << x << " " << lastx << " " << y << " " << lasty << " " << reverse << endl;
1095 node = List_First(&dnd->dnd_List);
1096 while (node)
1098 node->bmn_Drawed = FALSE;
1099 node = Node_Next(node);
1102 if (!reverse)
1104 node = List_First(&dnd->dnd_List);
1105 while (node)
1107 DrawBitMapNode(node, x + node->bmn_Left, y + node->bmn_Top);
1108 node = Node_Next(node);
1111 else
1113 node = (struct BitMapNode *)List_Last(&dnd->dnd_List);
1114 while (node)
1116 DrawBitMapNode(node, x + node->bmn_Left, y + node->bmn_Top);
1117 node = (struct BitMapNode *)Node_Prev(node);
1120 // first = FALSE;
1121 lastx = x;
1122 lasty = y;
1124 //-------------------------------------
1125 VOID UndrawDragNDrop(struct DragNDrop *dnd)
1127 struct BitMapNode *node;
1128 node = (struct BitMapNode *)List_Last(&dnd->dnd_List);
1129 while (node)
1131 UndrawBitMapNode(node);
1132 node = (struct BitMapNode *)Node_Prev(node);
1135 //-------------------------------------
1136 BOOL PrepareDragNDrop(struct DragNDrop *dnd, struct Screen *scr)
1138 struct BitMapNode *bmn;
1139 struct RastPort *rp;
1140 LONG depth;
1141 LONG maxwidth = 0, maxheight = 0;
1142 BOOL ok = TRUE;
1144 if (!dnd || !scr)
1145 return FALSE;
1146 dnd->dnd_Screen = scr;
1148 rp = &scr->RastPort;
1149 depth = GetBitMapAttr(rp->BitMap, BMA_DEPTH);
1151 bmn = List_First(&dnd->dnd_List);
1152 while (bmn)
1154 bmn->bmn_SaveWidth = bmn->bmn_SaveHeight = 0;
1155 if (bmn->bmn_Width > maxwidth)
1156 maxwidth = bmn->bmn_Width;
1157 if (bmn->bmn_Height > maxheight)
1158 maxheight = bmn->bmn_Height;
1160 if (!(bmn->bmn_SaveBitMap =
1161 AllocBitMap(bmn->bmn_Width, bmn->bmn_Height, depth,
1162 BMF_MINPLANES, rp->BitMap)))
1164 ok = FALSE;
1165 break;
1167 bmn = Node_Next(bmn);
1170 if (ok && maxwidth && maxheight)
1172 dnd->dnd_TempBitMap =
1173 /*NULL;// */ AllocBitMap(maxwidth, maxheight, depth,
1174 BMF_MINPLANES, rp->BitMap);
1175 return TRUE;
1178 bmn = List_First(&dnd->dnd_List);
1179 while (bmn)
1181 if (bmn->bmn_SaveBitMap)
1183 FreeBitMap(bmn->bmn_SaveBitMap);
1184 bmn->bmn_SaveBitMap = NULL;
1186 bmn = Node_Next(bmn);
1189 return FALSE;
1191 //-------------------------------------
1192 VOID FinishDragNDrop(struct DragNDrop *dnd)
1194 struct BitMapNode *bmn;
1195 if (dnd->dnd_TempBitMap)
1196 FreeBitMap(dnd->dnd_TempBitMap);
1198 bmn = List_First(&dnd->dnd_List);
1199 while (bmn)
1201 if (bmn->bmn_SaveBitMap)
1203 FreeBitMap(bmn->bmn_SaveBitMap);
1204 bmn->bmn_SaveBitMap = NULL;
1206 bmn = Node_Next(bmn);
1210 //-------------------------------------
1212 /**********************************************************************
1213 Varargs function of CreateBitMapNode(). Note that we need a dummy
1214 because we need at least one parameter
1215 **********************************************************************/
1216 struct BitMapNode *VARARGS68K CreateBitMapNode(void *dummy, ...)
1218 #ifndef __amigaos4__
1219 return CreateBitMapNodeA((struct TagItem *)(((ULONG *) & dummy) + 1));
1220 #else
1221 va_list argptr;
1222 struct TagItem *tagList;
1223 struct BitMapNode *res;
1225 va_startlinear(argptr, dummy);
1226 tagList = va_getlinearva(argptr, struct TagItem *);
1227 res = CreateBitMapNodeA(tagList);
1228 va_end(argptr);
1229 return res;
1230 #endif
1233 /******************************************************************************/
1250 #if 0
1252 struct Library *TimerBase;
1253 struct TimerStruct
1255 struct MsgPort *msgport;
1256 struct timerequest *iorequest;
1257 struct Library *timerbase;
1258 ULONG sent;
1261 //-------------------------------------
1262 ASM VOID TIMER_DeleteTimer(register __a0 APTR t)
1264 if (t)
1266 struct TimerStruct *timer = (struct TimerStruct *)t;
1267 if (timer)
1269 if (timer->timerbase)
1271 if (timer->sent)
1273 // printf("Test1\n");
1274 AbortIO((struct IORequest *)timer->iorequest);
1275 // printf("Test2\n");
1276 WaitIO((struct IORequest *)timer->iorequest);
1279 CloseDevice((struct IORequest *)timer->iorequest);
1281 if (timer->iorequest)
1282 DeleteIORequest(timer->iorequest);
1283 if (timer->msgport)
1284 DeleteMsgPort(timer->msgport);
1285 FreeVec(timer);
1289 //-------------------------------------
1290 ASM APTR TIMER_CreateTimer()
1292 struct TimerStruct *timer =
1293 (struct TimerStruct *)AllocVec(sizeof(struct TimerStruct), 0x10000);
1294 if (timer)
1296 if ((timer->msgport = CreateMsgPort()))
1298 if ((timer->iorequest =
1299 (struct timerequest *)CreateIORequest(timer->msgport,
1300 sizeof(struct timerequest))))
1302 if (!OpenDevice(TIMERNAME, UNIT_VBLANK,
1303 (struct IORequest *)timer->iorequest, NULL))
1305 #ifdef __MAXON__
1306 /*TimerBase = */ timer->timerbase =
1307 (struct Library *)timer->iorequest->tr_node.
1308 io_Device;
1309 #else
1310 timer->timerbase =
1311 (struct Library *)timer->iorequest->tr_node.
1312 io_Device;
1313 #endif
1314 return timer;
1318 TIMER_DeleteTimer(timer);
1320 return NULL;
1322 //-------------------------------------
1323 ASM struct MsgPort *TIMER_GetMsgPort(register __a0 APTR t)
1325 if (!t)
1326 return NULL;
1327 return ((struct TimerStruct *)t)->msgport;
1329 //-------------------------------------
1330 ASM ULONG TIMER_GetSigMask(register __a0 APTR t)
1332 if (!t)
1333 return NULL;
1334 return (1UL << (((struct TimerStruct *)t)->msgport->mp_SigBit));
1336 //-------------------------------------
1337 ASM APTR TIMER_StartTimer(register __a0 APTR t, register __d0 ULONG secs,
1338 register __d1 ULONG mics)
1340 struct TimerStruct *timer;
1341 struct timerequest *req;
1343 if (!t)
1344 return NULL;
1346 timer = (struct TimerStruct *)t;
1347 if (timer->sent)
1348 return NULL;
1350 req = timer->iorequest;
1351 req->tr_node.io_Command = TR_ADDREQUEST;
1352 req->tr_time.tv_secs = secs;
1353 req->tr_time.tv_micro = mics;
1354 timer->sent = TRUE;
1355 SendIO((struct IORequest *)req);
1356 return (APTR) 1L;
1358 //-------------------------------------
1359 ASM VOID TIMER_StopTimer(register __a0 APTR t)
1361 struct TimerStruct *timer;
1362 if (!t)
1363 return;
1365 timer = (struct TimerStruct *)t;
1366 if (timer->sent)
1368 AbortIO((struct IORequest *)timer->iorequest);
1369 WaitIO((struct IORequest *)timer->iorequest);
1370 timer->sent = 0;
1373 //-------------------------------------
1375 //-------------------------------------
1376 struct BitMap *CreateBitmapFromIcon(struct Screen *scr,
1377 struct DiskObject *dobj, LONG *width, LONG *height)
1379 struct Rectangle rect;
1380 static struct TagItem rect_tags[] = {
1381 ICONDRAWA_Borderless, TRUE,
1382 TAG_DONE, 0
1385 static struct TagItem draw_tags[] = {
1386 ICONDRAWA_Borderless, TRUE,
1387 ICONDRAWA_EraseBackground, TRUE,
1388 TAG_DONE, 0
1391 if (!dobj)
1392 return NULL;
1394 if (GetIconRectangleA(NULL, dobj, NULL, &rect, rect_tags))
1396 BOOL standard;
1397 struct BitMap *bmap;
1398 if (GetBitMapAttr(scr->RastPort.BitMap, BMA_FLAGS) & BMF_STANDARD)
1399 standard = TRUE;
1400 else
1401 standard = FALSE;
1403 *width = rect.MaxX - rect.MinX + 1;
1404 *height = rect.MaxY - rect.MinY + 1;
1406 // cout << rect.MinY << " " << rect.MaxY << endl;
1408 bmap =
1409 AllocBitMap(*width, *height, 8, /*NULL,NULL);// */
1410 BMF_MINPLANES, standard ? NULL : scr->RastPort.BitMap);
1411 if (bmap)
1413 struct RastPort rp;
1414 InitRastPort(&rp);
1415 rp.BitMap = bmap;
1416 SetRast(&rp, 1);
1417 DrawIconStateA(&rp, dobj, NULL, 0, 0, IDS_SELECTED, draw_tags);
1419 return bmap;
1423 return NULL;
1425 //-------------------------------------
1427 struct Window *wnd;
1428 struct DragNDrop *drag;
1430 //-------------------------------------
1431 VOID loop()
1433 BOOL ready = FALSE;
1434 static LONG lmx, lmy;
1436 WaitPort(wnd->UserPort);
1437 while (ready == FALSE)
1439 struct IntuiMessage *imsg;
1440 while ((imsg = (struct IntuiMessage *)GetMsg(wnd->UserPort)))
1442 ULONG cl = imsg->Class;
1443 UWORD code = imsg->Code;
1444 // LONG mx = imsg->MouseX;
1445 // LONG my = imsg->MouseY;
1447 ReplyMsg((struct Message *)imsg);
1449 switch (cl)
1451 case IDCMP_CLOSEWINDOW:
1452 ready = TRUE;
1453 break;
1455 case IDCMP_VANILLAKEY:
1457 DrawDragNDrop(drag, wnd->WScreen->MouseX,
1458 wnd->WScreen->MouseY);
1459 lmx = wnd->WScreen->MouseX;
1460 lmy = wnd->WScreen->MouseY;
1462 break;
1464 case IDCMP_MOUSEBUTTONS:
1465 if (code == SELECTDOWN)
1467 DrawDragNDrop(drag, wnd->WScreen->MouseX,
1468 wnd->WScreen->MouseY);
1469 lmx = wnd->WScreen->MouseX;
1470 lmy = wnd->WScreen->MouseY;
1472 break;
1474 case IDCMP_MOUSEMOVE:
1475 // cout << wnd->WScreen->MouseX - lmx << " " << wnd->WScreen->MouseY - lmy << endl;
1476 // WaitBOVP(&wnd->WScreen->ViewPort);
1477 DrawDragNDrop(drag, wnd->WScreen->MouseX,
1478 wnd->WScreen->MouseY);
1479 break;
1484 //-------------------------------------
1486 UBYTE fullmask[8192];
1488 void main()
1490 int i;
1491 for (i = 0; i < 8192; i++)
1492 fullmask[i] = 0xff;
1494 wnd = OpenWindowTags(NULL,
1495 WA_InnerWidth, 400,
1496 WA_InnerHeight, 200,
1497 WA_IDCMP,
1498 IDCMP_CLOSEWINDOW | IDCMP_MOUSEMOVE | IDCMP_INTUITICKS |
1499 IDCMP_MOUSEBUTTONS | IDCMP_VANILLAKEY, WA_DragBar, TRUE,
1500 WA_DepthGadget, TRUE, WA_CloseGadget, TRUE, WA_ReportMouse, TRUE,
1501 WA_Activate, TRUE, WA_GimmeZeroZero, TRUE, WA_MouseQueue, 2,
1502 TAG_DONE);
1503 if (wnd)
1505 BOOL ready = FALSE;
1506 struct DiskObject *obj1 = GetIconTags("SYS:Prefs",
1507 ICONGETA_GenerateImageMasks, TRUE,
1508 TAG_DONE);
1509 struct DiskObject *obj2 = GetIconTags("SYS:Picasso96",
1510 ICONGETA_GenerateImageMasks, TRUE,
1511 TAG_DONE);
1512 struct DiskObject *obj3 = GetIconTags("SYS:Tools",
1513 ICONGETA_GenerateImageMasks, TRUE,
1514 TAG_DONE);
1515 LONG width, height;
1516 struct BitMap *bmap1 =
1517 CreateBitmapFromIcon(wnd->WScreen, obj1, &width, &height);
1518 struct BitMap *bmap2 =
1519 CreateBitmapFromIcon(wnd->WScreen, obj2, &width, &height);
1520 struct BitMap *bmap3 =
1521 CreateBitmapFromIcon(wnd->WScreen, obj3, &width, &height);
1522 if (bmap1 && bmap2 && bmap3)
1524 APTR mask1, mask2, mask3;
1525 IconControl(obj1, ICONCTRLA_GetImageMask1, &mask1, TAG_DONE);
1526 IconControl(obj2, ICONCTRLA_GetImageMask1, &mask2, TAG_DONE);
1527 IconControl(obj3, ICONCTRLA_GetImageMask1, &mask3, TAG_DONE);
1528 if ((drag = CreateDragNDropA(NULL)))
1530 struct BitMapNode *bmn1 =
1531 CreateBitMapNode(GUI_BitMap, bmap1,
1532 GUI_Mask, mask1,
1533 GUI_Width, width,
1534 GUI_Height, height,
1535 GUI_TopOffset, -25,
1536 GUI_LeftOffset, -35,
1537 TAG_DONE);
1539 struct BitMapNode *bmn2 =
1540 CreateBitMapNode(GUI_BitMap, bmap2,
1541 GUI_Mask, mask2,
1542 GUI_Width, width,
1543 GUI_Height, height,
1544 GUI_LeftOffset, 0,
1545 TAG_DONE);
1547 struct BitMapNode *bmn3 =
1548 CreateBitMapNode(GUI_BitMap, bmap3,
1549 GUI_Mask, mask3,
1550 GUI_Width, width,
1551 GUI_Height, height,
1552 GUI_LeftOffset, 99,
1553 GUI_TopOffset, -10,
1554 TAG_DONE);
1556 struct BitMapNode *bmn4 =
1557 CreateBitMapNode(GUI_BitMap, bmap1,
1558 GUI_Mask, mask1,
1559 GUI_Width, width,
1560 GUI_Height, height,
1561 GUI_TopOffset, 60,
1562 TAG_DONE);
1564 struct BitMapNode *bmn5 =
1565 CreateBitMapNode(GUI_BitMap, bmap2,
1566 GUI_Mask, mask2,
1567 GUI_Width, width,
1568 GUI_Height, height,
1569 GUI_LeftOffset, 50,
1570 GUI_TopOffset, 60,
1571 TAG_DONE);
1573 struct BitMapNode *bmn6 =
1574 CreateBitMapNode(GUI_BitMap, bmap3,
1575 GUI_Mask, mask3,
1576 GUI_Width, width,
1577 GUI_Height, height,
1578 GUI_LeftOffset, 100,
1579 GUI_TopOffset, 70,
1580 TAG_DONE);
1582 if (bmn1 && bmn2 && bmn3 && bmn4 && bmn5 && bmn6)
1584 AttachBitMapNode(drag, bmn1);
1585 AttachBitMapNode(drag, bmn2);
1586 AttachBitMapNode(drag, bmn3);
1587 AttachBitMapNode(drag, bmn4);
1588 AttachBitMapNode(drag, bmn5);
1589 AttachBitMapNode(drag, bmn6);
1590 PrepareDragNDrop(drag, wnd->WScreen);
1591 loop();
1592 FinishDragNDrop(drag);
1593 DetachBitMapNode(bmn6);
1594 DetachBitMapNode(bmn5);
1595 DetachBitMapNode(bmn4);
1596 DetachBitMapNode(bmn3);
1597 DetachBitMapNode(bmn2);
1598 DetachBitMapNode(bmn1);
1600 if (bmn6)
1601 DeleteBitMapNode(bmn6);
1602 if (bmn5)
1603 DeleteBitMapNode(bmn5);
1604 if (bmn4)
1605 DeleteBitMapNode(bmn4);
1606 if (bmn3)
1607 DeleteBitMapNode(bmn3);
1608 if (bmn2)
1609 DeleteBitMapNode(bmn2);
1610 if (bmn1)
1611 DeleteBitMapNode(bmn1);
1612 DeleteDragNDrop(drag);
1616 if (bmap3)
1617 FreeBitMap(bmap3);
1618 if (bmap2)
1619 FreeBitMap(bmap2);
1620 if (bmap1)
1621 FreeBitMap(bmap1);
1623 if (obj3)
1624 FreeDiskObject(obj3);
1625 if (obj2)
1626 FreeDiskObject(obj2);
1627 if (obj1)
1628 FreeDiskObject(obj1);
1629 CloseWindow(wnd);
1633 //-------------------------------------
1635 #endif