Safer handling of Booleans.
[AROS.git] / workbench / libs / muimaster / dragndrop.c
blob21af8673d6ddb8d2cb4586eac458fc78ac8530b4
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 IPTR depth = GetBitMapAttr(rp->BitMap, BMA_DEPTH);
549 if (depth > 8 && src_bmn->bmn_BitMapBuffer)
551 /* This should be done using BltBitMapRastPortAlpha with
552 * direct video card alpha blit, but this function is not
553 * available on AROS yet. Current implementation is that
554 * src_bmn->bmn_BitMapBuffer contains 32bit ARGB buffer
555 * acquired from src_bmn->bmn_BitMap */
556 WritePixelArrayAlpha(src_bmn->bmn_BitMapBuffer, offx, offy,
557 src_bmn->bmn_Width * sizeof(ULONG), rp, x, y, width,
558 height, 0);
560 else
562 BltBitMapRastPort(src_bmn->bmn_BitMap, offx, offy,
563 rp, x, y, width, height, 0xc0);
568 //-------------------------------------
569 STATIC VOID BltNearBitMaps(struct BitMapNode *src_bmn, struct RastPort *rp,
570 LONG x, LONG y, LONG width, LONG height)
572 struct DragNDrop *dnd = src_bmn->bmn_DnD;
573 struct BitMapNode *bmn = List_First(&dnd->dnd_List);
574 struct Rectangle rect;
576 rect.MinX = x;
577 rect.MinY = y;
578 rect.MaxX = x + width - 1;
579 rect.MaxY = y + height - 1;
581 while (bmn)
583 if (bmn != src_bmn && bmn->bmn_Drawed)
585 struct Rectangle bmn_rect, result_rect;
586 bmn_rect.MinX = bmn->bmn_SaveX;
587 bmn_rect.MinY = bmn->bmn_SaveY;
588 bmn_rect.MaxX = bmn_rect.MinX + bmn->bmn_SaveWidth - 1;
589 bmn_rect.MaxY = bmn_rect.MinY + bmn->bmn_SaveHeight - 1;
591 if (AndRectangle(&rect, &bmn_rect, &result_rect))
593 LONG bmn_x = result_rect.MinX - bmn_rect.MinX;
594 LONG bmn_y = result_rect.MinY - bmn_rect.MinY;
595 LONG bmn_width = result_rect.MaxX - result_rect.MinX + 1;
596 LONG bmn_height = result_rect.MaxY - result_rect.MinY + 1;
597 LONG xDest = result_rect.MinX - rect.MinX;
598 LONG yDest = result_rect.MinY - rect.MinY;
600 BltBitMapNode(bmn, bmn_x, bmn_y,
601 rp, xDest, yDest, bmn_width, bmn_height);
605 bmn = Node_Next(bmn);
608 //-------------------------------------
609 STATIC VOID RestoreBackground(struct BitMapNode *src_bmn,
610 struct RastPort *rp)
612 LONG save_x = src_bmn->bmn_SaveX;
613 LONG save_y = src_bmn->bmn_SaveY;
614 LONG save_width = src_bmn->bmn_SaveWidth;
615 LONG save_height = src_bmn->bmn_SaveHeight;
617 struct DragNDrop *dnd = src_bmn->bmn_DnD;
618 struct BitMapNode *bmn = List_First(&dnd->dnd_List);
619 struct Rectangle last_rect;
621 last_rect.MinX = save_x;
622 last_rect.MinY = save_y;
623 last_rect.MaxX = save_x + save_width - 1;
624 last_rect.MaxY = save_y + save_height - 1;
626 SafeBltBitMapRastPort(src_bmn->bmn_SaveBitMap, 0, 0,
627 rp, save_x, save_y, save_width, save_height, 0xc0);
630 while (bmn)
632 if (bmn != src_bmn && bmn->bmn_Drawed)
634 struct Rectangle bmn_rect, result_rect;
635 bmn_rect.MinX = bmn->bmn_SaveX;
636 bmn_rect.MinY = bmn->bmn_SaveY;
637 bmn_rect.MaxX = bmn_rect.MinX + bmn->bmn_SaveWidth - 1;
638 bmn_rect.MaxY = bmn_rect.MinY + bmn->bmn_SaveHeight - 1;
640 if (AndRectangle(&last_rect, &bmn_rect, &result_rect))
642 LONG bmn_x = result_rect.MinX - bmn_rect.MinX;
643 LONG bmn_y = result_rect.MinY - bmn_rect.MinY;
644 LONG bmn_width = result_rect.MaxX - result_rect.MinX + 1;
645 LONG bmn_height = result_rect.MaxY - result_rect.MinY + 1;
646 /* LONG xDest = result_rect.MinX - last_rect.MinX; */
647 /* LONG yDest = result_rect.MinY - last_rect.MinY; */
649 BltBitMapNode(bmn, bmn_x, bmn_y,
650 rp, result_rect.MinX, result_rect.MinY, bmn_width,
651 bmn_height);
653 // SafeBltBitMapRastPort(bmn->bmn_SaveBitMap, bmn_x, bmn_y,
654 // rp, xDest, yDest, bmn_width, bmn_height,0xc0);
658 bmn = Node_Next(bmn);
661 //-------------------------------------
662 struct BitMapNode *CreateBitMapNodeA(struct TagItem *tagList)
664 struct BitMapNode *bmn =
665 (struct BitMapNode *)AllocMem(sizeof(struct BitMapNode),
666 MEMF_CLEAR);
667 if (bmn)
669 BOOL sourcealpha = FALSE;
670 struct TagItem *tl = tagList;
671 struct TagItem *tag;
673 while ((tag = NextTagItem(&tl)))
675 ULONG id = tag->ti_Tag;
676 IPTR data = tag->ti_Data;
678 switch (id)
680 case GUI_BitMap:
681 bmn->bmn_BitMap = (struct BitMap *)data;
682 break;
684 case GUI_Mask:
685 bmn->bmn_Mask = (APTR) data;
686 break;
688 case GUI_LeftOffset:
689 bmn->bmn_Left = data;
690 break;
692 case GUI_TopOffset:
693 bmn->bmn_Top = data;
694 break;
696 case GUI_Width:
697 bmn->bmn_Width = data;
698 break;
700 case GUI_Height:
701 bmn->bmn_Height = data;
702 break;
704 case GUI_SourceAlpha:
705 sourcealpha = data;
706 break;
710 if (!bmn->bmn_BitMap)
712 FreeMem(bmn, sizeof(struct BitMapNode));
713 bmn = NULL;
716 if (bmn && sourcealpha)
718 /* See notes in BltBitMapNode */
719 struct RastPort temp_rp;
720 InitRastPort(&temp_rp);
721 temp_rp.BitMap = bmn->bmn_BitMap;
722 bmn->bmn_BitMapBuffer =
723 AllocVec(bmn->bmn_Width * bmn->bmn_Height * sizeof(ULONG),
724 MEMF_ANY);
725 ReadPixelArray(bmn->bmn_BitMapBuffer, 0, 0,
726 bmn->bmn_Width * sizeof(ULONG), &temp_rp, 0, 0,
727 bmn->bmn_Width, bmn->bmn_Height, RECTFMT_ARGB);
728 DeinitRastPort(&temp_rp);
731 return bmn;
733 //-------------------------------------
734 VOID DeleteBitMapNode(struct BitMapNode *bmn)
736 if (bmn->bmn_SaveBitMap)
737 FreeBitMap(bmn->bmn_SaveBitMap);
738 FreeVec(bmn->bmn_BitMapBuffer);
739 FreeMem(bmn, sizeof(struct BitMapNode));
741 //-------------------------------------
742 struct BitMap *GetBitMap(struct BitMapNode *bmn)
744 if (bmn)
745 return bmn->bmn_BitMap;
746 return NULL;
748 //-------------------------------------
749 VOID AttachBitMapNode(struct DragNDrop *dnd, struct BitMapNode *bmn)
751 AddTail((struct List *)&dnd->dnd_List, (struct Node *)&bmn->bmn_Node);
752 bmn->bmn_DnD = dnd;
754 //-------------------------------------
755 VOID DetachBitMapNode(struct BitMapNode *bmn)
757 if (bmn->bmn_Succ && bmn->bmn_Pred)
759 Remove((struct Node *)&bmn->bmn_Node);
760 bmn->bmn_Succ = bmn->bmn_Pred = NULL;
762 bmn->bmn_DnD = NULL;
764 //-------------------------------------
765 VOID DrawBitMapNode(struct BitMapNode *bmn, LONG x, LONG y)
767 LONG width = bmn->bmn_Width;
768 LONG height = bmn->bmn_Height;
769 LONG save_x = bmn->bmn_SaveX;
770 LONG save_y = bmn->bmn_SaveY;
771 LONG save_width = bmn->bmn_SaveWidth;
772 LONG save_height = bmn->bmn_SaveHeight;
773 struct RastPort *rp;
774 struct BitMap *temp_bmap;
775 BOOL draw = TRUE; //FALSE;
777 if (!bmn || !bmn->bmn_DnD || !bmn->bmn_DnD->dnd_Screen)
778 return;
779 rp = &bmn->bmn_DnD->dnd_Screen->RastPort;
780 temp_bmap = bmn->bmn_DnD->dnd_TempBitMap;
782 if (!bmn->bmn_SaveBitMap)
783 return;
785 /* if( bmn->bmn_SaveWidth > 0 && bmn->bmn_SaveHeight > 0 )
787 if(!temp_bmap)
789 RestoreBackground(bmn,rp);
794 LONG maxWidth,
795 maxHeight /* , offx=0, offy=0, save_offx=0, save_offy=0 */ ;
796 LONG real_width = width, real_height = height;
797 LONG real_save_width = save_width, real_save_height = save_height;
799 maxWidth = GetBitMapAttr(rp->BitMap, BMA_WIDTH);
800 maxHeight = GetBitMapAttr(rp->BitMap, BMA_HEIGHT);
802 if (x < 0)
803 real_width += x;
804 if (y < 0)
805 real_height += y;
806 if (save_x < 0)
807 real_save_width += save_x;
808 if (save_y < 0)
809 real_save_height += save_y;
811 if (real_width + x > maxWidth)
812 real_width = maxWidth - x;
813 if (real_height + y > maxHeight)
814 real_height = maxHeight - y;
815 if (real_save_width + x > maxWidth)
816 real_save_width = maxWidth - x;
817 if (real_save_height + y > maxHeight)
818 real_save_height = maxHeight - y;
820 if ((real_width > 0 && real_height > 0) || (real_save_width > 0
821 && real_save_height > 0))
822 draw = TRUE;
825 if (draw)
827 if (!temp_bmap)
829 // SafeBltBitMap(rp->BitMap, x,y,
830 // bmn->bmn_SaveBitMap, 0,0, width, height, 0xc0, -1, NULL);
832 // bmn->bmn_SaveWidth = 0;
833 // bmn->bmn_SaveHeight = 0;
835 // BltBackgroundBitMap(bmn->bmn_DnD, x, y,
836 // bmn->bmn_SaveBitMap, 0,0, width, height);
838 if (bmn->bmn_SaveWidth > 0 && bmn->bmn_SaveHeight > 0)
839 RestoreBackground(bmn, rp);
841 BltBackgroundBitMap(bmn, x, y, width, height, FALSE);
843 // BltBitMapRastPort(bmn->bmn_SaveBitMap,0,0,
844 // rp, 20+bmn->bmn_Left*2,20+bmn->bmn_Top,width,height,0xc0);
847 BltBitMapNode(bmn, 0, 0, rp, x, y, width, height);
849 else
851 struct RastPort temp_rp;
852 struct Rectangle save_rect, rect, result_rect;
853 InitRastPort(&temp_rp);
854 temp_rp.BitMap = temp_bmap;
856 save_rect.MinX = save_x;
857 save_rect.MinY = save_y;
858 save_rect.MaxX = save_x + save_width - 1;
859 save_rect.MaxY = save_y + save_height - 1;
861 rect.MinX = x;
862 rect.MinY = y;
863 rect.MaxX = x + width - 1;
864 rect.MaxY = y + height - 1;
866 if (AndRectangle(&rect, &save_rect, &result_rect))
868 LONG result_width = result_rect.MaxX - result_rect.MinX + 1;
869 LONG result_height =
870 result_rect.MaxY - result_rect.MinY + 1;
871 LONG result_x = result_rect.MinX - save_rect.MinX;
872 LONG result_y = result_rect.MinY - save_rect.MinY;
873 // cout << rect.MinX << " " << rect.MaxX << " " << rect.MinY << " " << rect.MaxY << endl;
874 // cout << save_rect.MinX << " " << save_rect.MaxX << " " << save_rect.MinY << " " << save_rect.MaxY << endl;
875 // cout << result_rect.MinX << " " << result_rect.MaxX << " " << result_rect.MinY << " " << result_rect.MaxY << endl;
876 // cout << "soffx:" << save_offx << " offx:" << offx << " rx:" << result_x << " " << result_y << " " << " w: " << width << " " << result_width << " " << result_height << endl;
878 // SetRast(&temp_rp,0);
880 // Neuen Hintergrund in temporäre Bitmap
881 // SafeBltBitMapRastPort( rp->BitMap, x, y,
882 // &temp_rp, 0, 0, width, height,0xc0);
884 BltBackgroundBitMap(bmn, x, y, width, height, TRUE);
886 /* Debug code */
887 // BltBitMapRastPort(temp_bmap,0,0,rp,100+bmn->bmn_Left,
888 // 20+bmn->bmn_Top,bmn->bmn_Width,bmn->bmn_Height,0xc0);
890 // Teile des alten Hintergrundes, die neu verdeckt werden in temporäre Bitmap
891 BltBitMapRastPort(bmn->bmn_SaveBitMap, result_x, result_y,
892 &temp_rp, (result_x ? 0 : (save_width - result_width)),
893 result_y ? 0 : (save_height - result_height),
894 result_width, result_height, 0xc0);
896 /* Debug code */
897 // BltBitMapRastPort(temp_bmap,0,0,rp,180+bmn->bmn_Left,
898 // 20+bmn->bmn_Top,bmn->bmn_Width,bmn->bmn_Height,0xc0);
901 // Teile des alten Hintergrundes, die nicht mehr verdeckt werden auf Screen
902 if ((save_width - result_width) > 0)
904 SafeBltBitMapRastPort(bmn->bmn_SaveBitMap,
905 (result_x ? 0 : (result_width)), 0, rp,
906 save_x + (result_x ? 0 : (result_width)), save_y,
907 save_width - result_width, save_height, 0xc0);
910 if ((save_height - result_height) > 0)
912 SafeBltBitMapRastPort(bmn->bmn_SaveBitMap, 0,
913 result_y ? 0 : (result_height), rp, save_x,
914 save_y + (result_y ? 0 : (result_height)),
915 save_width, save_height - result_height, 0xc0);
918 // temporäre BitMap ist neuer Hintergrund
919 BltBitMap(temp_bmap, 0, 0,
920 bmn->bmn_SaveBitMap, 0, 0, width, height, 0xc0, -1,
921 NULL);
923 /* Blit drag image bitmap to temporary bitmap */
924 BltBitMapNode(bmn, 0, 0, &temp_rp, 0, 0, width, height);
926 // Angenzende BitMaps in temporäre BitMap
927 BltNearBitMaps(bmn, &temp_rp, x, y, width, height);
929 /* Debug code */
930 // BltBitMapRastPort(temp_bmap,0,0,rp,240+bmn->bmn_Left,
931 // 20+bmn->bmn_Top,width,height,0xc0);
934 /* Blit prepared temporaty bitmap to screen */
935 SafeBltBitMapRastPort(temp_bmap, 0, 0,
936 rp, x, y, width, height, 0xc0);
938 /* Debug code */
939 // BltBitMapRastPort(bmn->bmn_SaveBitMap,0,0,rp,40+bmn->bmn_Left,
940 // 20+bmn->bmn_Top,bmn->bmn_Width,bmn->bmn_Height,0xc0);
943 else
945 if (bmn->bmn_SaveWidth > 0 && bmn->bmn_SaveHeight > 0)
946 RestoreBackground(bmn, rp);
948 BltBackgroundBitMap(bmn, x, y, width, height, FALSE);
950 /* BltBitMapRastPort( bmn->bmn_SaveBitMap,0,0,
951 rp, bmn->bmn_SaveX, bmn->bmn_SaveY, bmn->bmn_SaveWidth, bmn->bmn_SaveHeight, 0xc0 );
953 SafeBltBitMap(rp->BitMap, x,y,
954 bmn->bmn_SaveBitMap, 0,0, width, height, 0xc0, -1, NULL);
956 BltBitMapNode(bmn, 0, 0, rp, x, y, width, height);
961 bmn->bmn_Drawed = TRUE;
962 bmn->bmn_SaveX = x;
963 bmn->bmn_SaveY = y;
964 bmn->bmn_SaveWidth = width;
965 bmn->bmn_SaveHeight = height;
966 // bmn->bmn_SaveOffX = offx;
967 // bmn->bmn_SaveOffY = offy;
969 //-------------------------------------
970 VOID UndrawBitMapNode(struct BitMapNode *bmn)
972 struct RastPort *rp = &bmn->bmn_DnD->dnd_Screen->RastPort;
974 if (!bmn->bmn_SaveBitMap)
975 return;
977 if (bmn->bmn_SaveWidth > 0 && bmn->bmn_SaveHeight > 0)
979 SafeBltBitMapRastPort(bmn->bmn_SaveBitMap, 0, 0,
980 rp, bmn->bmn_SaveX, bmn->bmn_SaveY, bmn->bmn_SaveWidth,
981 bmn->bmn_SaveHeight, 0xc0);
983 bmn->bmn_SaveWidth = 0;
984 bmn->bmn_SaveHeight = 0;
986 //-------------------------------------
988 //-------------------------------------
989 struct DragNDrop *CreateDragNDropA(struct TagItem *tlist)
991 struct DragNDrop *dnd =
992 (struct DragNDrop *)AllocMem(sizeof(struct DragNDrop), MEMF_CLEAR);
993 if (dnd)
995 NewList((struct List *)&dnd->dnd_List);
997 /* if(dnd->dnd_LayerInfo = NewLayerInfo()))
999 dnd->dnd_Screen = NULL
1000 dnd->dnd_TempBitMap = NULL;
1003 struct RastPort *rp = &dnd->dnd_RastPort;
1004 InitRastPort(rp);
1006 rp->BitMap =
1008 if(dnd->dnd_Layer = CreateBehindLayer(dnd->dnd_LayerInfo,
1010 return dnd;
1012 FreeMem( dnd, sizeof(struct DragNDrop ));*/
1014 return dnd;
1015 // return NULL;
1017 //-------------------------------------
1018 VOID DeleteDragNDrop(struct DragNDrop *dnd)
1020 struct BitMapNode *node;
1022 FinishDragNDrop(dnd);
1024 while ((node =
1025 (struct BitMapNode *)RemTail((struct List *)&dnd->dnd_List)))
1026 DeleteBitMapNode(node);
1028 FreeMem(dnd, sizeof(struct DragNDrop));
1030 //-------------------------------------
1031 VOID DrawDragNDrop(struct DragNDrop *dnd, LONG x, LONG y)
1033 static LONG lastx;
1034 static LONG lasty;
1035 // static LONG first=TRUE;
1037 struct BitMapNode *node;
1038 BOOL reverse;
1039 LONG diffx = x - lastx;
1040 LONG diffy = y - lasty;
1042 if (!dnd || !dnd->dnd_Screen)
1043 return;
1045 reverse = FALSE;
1047 if (abs(diffy) < abs(diffx)) //y==lasty)
1049 if (diffx > 0)
1050 reverse = TRUE;
1051 List_Sort_Mode_3(&dnd->dnd_List);
1053 else
1055 if (diffy > 0)
1056 reverse = TRUE;
1057 List_Sort_Mode_1(&dnd->dnd_List);
1061 /* if(first) reverse = FALSE;
1062 else
1064 if( x<lastx) reverse = FALSE;
1065 else
1067 if(x==lastx && y < lasty) reverse=FALSE;
1068 else reverse = TRUE;
1071 if(x>lastx && y < lasty)
1073 List_Sort_Mode_2(&dnd->dnd_List);
1074 reverse=FALSE;
1075 } else
1077 if(x<lastx && y > lasty)
1079 List_Sort_Mode_2(&dnd->dnd_List);
1080 reverse=TRUE;
1085 // cout << x << " " << lastx << " " << y << " " << lasty << " " << reverse << endl;
1088 node = List_First(&dnd->dnd_List);
1089 while (node)
1091 node->bmn_Drawed = FALSE;
1092 node = Node_Next(node);
1095 if (!reverse)
1097 node = List_First(&dnd->dnd_List);
1098 while (node)
1100 DrawBitMapNode(node, x + node->bmn_Left, y + node->bmn_Top);
1101 node = Node_Next(node);
1104 else
1106 node = (struct BitMapNode *)List_Last(&dnd->dnd_List);
1107 while (node)
1109 DrawBitMapNode(node, x + node->bmn_Left, y + node->bmn_Top);
1110 node = (struct BitMapNode *)Node_Prev(node);
1113 // first = FALSE;
1114 lastx = x;
1115 lasty = y;
1117 //-------------------------------------
1118 VOID UndrawDragNDrop(struct DragNDrop *dnd)
1120 struct BitMapNode *node;
1121 node = (struct BitMapNode *)List_Last(&dnd->dnd_List);
1122 while (node)
1124 UndrawBitMapNode(node);
1125 node = (struct BitMapNode *)Node_Prev(node);
1128 //-------------------------------------
1129 BOOL PrepareDragNDrop(struct DragNDrop *dnd, struct Screen *scr)
1131 struct BitMapNode *bmn;
1132 struct RastPort *rp;
1133 LONG depth;
1134 LONG maxwidth = 0, maxheight = 0;
1135 BOOL ok = TRUE;
1137 if (!dnd || !scr)
1138 return FALSE;
1139 dnd->dnd_Screen = scr;
1141 rp = &scr->RastPort;
1142 depth = GetBitMapAttr(rp->BitMap, BMA_DEPTH);
1144 bmn = List_First(&dnd->dnd_List);
1145 while (bmn)
1147 bmn->bmn_SaveWidth = bmn->bmn_SaveHeight = 0;
1148 if (bmn->bmn_Width > maxwidth)
1149 maxwidth = bmn->bmn_Width;
1150 if (bmn->bmn_Height > maxheight)
1151 maxheight = bmn->bmn_Height;
1153 if (!(bmn->bmn_SaveBitMap =
1154 AllocBitMap(bmn->bmn_Width, bmn->bmn_Height, depth,
1155 BMF_MINPLANES, rp->BitMap)))
1157 ok = FALSE;
1158 break;
1160 bmn = Node_Next(bmn);
1163 if (ok && maxwidth && maxheight)
1165 dnd->dnd_TempBitMap =
1166 /*NULL;// */ AllocBitMap(maxwidth, maxheight, depth,
1167 BMF_MINPLANES, rp->BitMap);
1168 return TRUE;
1171 bmn = List_First(&dnd->dnd_List);
1172 while (bmn)
1174 if (bmn->bmn_SaveBitMap)
1176 FreeBitMap(bmn->bmn_SaveBitMap);
1177 bmn->bmn_SaveBitMap = NULL;
1179 bmn = Node_Next(bmn);
1182 return FALSE;
1184 //-------------------------------------
1185 VOID FinishDragNDrop(struct DragNDrop *dnd)
1187 struct BitMapNode *bmn;
1188 if (dnd->dnd_TempBitMap)
1189 FreeBitMap(dnd->dnd_TempBitMap);
1191 bmn = List_First(&dnd->dnd_List);
1192 while (bmn)
1194 if (bmn->bmn_SaveBitMap)
1196 FreeBitMap(bmn->bmn_SaveBitMap);
1197 bmn->bmn_SaveBitMap = NULL;
1199 bmn = Node_Next(bmn);
1203 //-------------------------------------
1205 /**********************************************************************
1206 Varargs function of CreateBitMapNode(). Note that we need a dummy
1207 because we need at least one parameter
1208 **********************************************************************/
1209 struct BitMapNode *VARARGS68K CreateBitMapNode(void *dummy, ...)
1211 #ifndef __amigaos4__
1212 return CreateBitMapNodeA((struct TagItem *)(((ULONG *) & dummy) + 1));
1213 #else
1214 va_list argptr;
1215 struct TagItem *tagList;
1216 struct BitMapNode *res;
1218 va_startlinear(argptr, dummy);
1219 tagList = va_getlinearva(argptr, struct TagItem *);
1220 res = CreateBitMapNodeA(tagList);
1221 va_end(argptr);
1222 return res;
1223 #endif
1226 /******************************************************************************/
1243 #if 0
1245 struct Library *TimerBase;
1246 struct TimerStruct
1248 struct MsgPort *msgport;
1249 struct timerequest *iorequest;
1250 struct Library *timerbase;
1251 ULONG sent;
1254 //-------------------------------------
1255 ASM VOID TIMER_DeleteTimer(register __a0 APTR t)
1257 if (t)
1259 struct TimerStruct *timer = (struct TimerStruct *)t;
1260 if (timer)
1262 if (timer->timerbase)
1264 if (timer->sent)
1266 // printf("Test1\n");
1267 AbortIO((struct IORequest *)timer->iorequest);
1268 // printf("Test2\n");
1269 WaitIO((struct IORequest *)timer->iorequest);
1272 CloseDevice((struct IORequest *)timer->iorequest);
1274 if (timer->iorequest)
1275 DeleteIORequest(timer->iorequest);
1276 if (timer->msgport)
1277 DeleteMsgPort(timer->msgport);
1278 FreeVec(timer);
1282 //-------------------------------------
1283 ASM APTR TIMER_CreateTimer()
1285 struct TimerStruct *timer =
1286 (struct TimerStruct *)AllocVec(sizeof(struct TimerStruct), 0x10000);
1287 if (timer)
1289 if ((timer->msgport = CreateMsgPort()))
1291 if ((timer->iorequest =
1292 (struct timerequest *)CreateIORequest(timer->msgport,
1293 sizeof(struct timerequest))))
1295 if (!OpenDevice(TIMERNAME, UNIT_VBLANK,
1296 (struct IORequest *)timer->iorequest, NULL))
1298 #ifdef __MAXON__
1299 /*TimerBase = */ timer->timerbase =
1300 (struct Library *)timer->iorequest->tr_node.
1301 io_Device;
1302 #else
1303 timer->timerbase =
1304 (struct Library *)timer->iorequest->tr_node.
1305 io_Device;
1306 #endif
1307 return timer;
1311 TIMER_DeleteTimer(timer);
1313 return NULL;
1315 //-------------------------------------
1316 ASM struct MsgPort *TIMER_GetMsgPort(register __a0 APTR t)
1318 if (!t)
1319 return NULL;
1320 return ((struct TimerStruct *)t)->msgport;
1322 //-------------------------------------
1323 ASM ULONG TIMER_GetSigMask(register __a0 APTR t)
1325 if (!t)
1326 return NULL;
1327 return (1UL << (((struct TimerStruct *)t)->msgport->mp_SigBit));
1329 //-------------------------------------
1330 ASM APTR TIMER_StartTimer(register __a0 APTR t, register __d0 ULONG secs,
1331 register __d1 ULONG mics)
1333 struct TimerStruct *timer;
1334 struct timerequest *req;
1336 if (!t)
1337 return NULL;
1339 timer = (struct TimerStruct *)t;
1340 if (timer->sent)
1341 return NULL;
1343 req = timer->iorequest;
1344 req->tr_node.io_Command = TR_ADDREQUEST;
1345 req->tr_time.tv_secs = secs;
1346 req->tr_time.tv_micro = mics;
1347 timer->sent = TRUE;
1348 SendIO((struct IORequest *)req);
1349 return (APTR) 1L;
1351 //-------------------------------------
1352 ASM VOID TIMER_StopTimer(register __a0 APTR t)
1354 struct TimerStruct *timer;
1355 if (!t)
1356 return;
1358 timer = (struct TimerStruct *)t;
1359 if (timer->sent)
1361 AbortIO((struct IORequest *)timer->iorequest);
1362 WaitIO((struct IORequest *)timer->iorequest);
1363 timer->sent = 0;
1366 //-------------------------------------
1368 //-------------------------------------
1369 struct BitMap *CreateBitmapFromIcon(struct Screen *scr,
1370 struct DiskObject *dobj, LONG *width, LONG *height)
1372 struct Rectangle rect;
1373 static struct TagItem rect_tags[] = {
1374 ICONDRAWA_Borderless, TRUE,
1375 TAG_DONE, 0
1378 static struct TagItem draw_tags[] = {
1379 ICONDRAWA_Borderless, TRUE,
1380 ICONDRAWA_EraseBackground, TRUE,
1381 TAG_DONE, 0
1384 if (!dobj)
1385 return NULL;
1387 if (GetIconRectangleA(NULL, dobj, NULL, &rect, rect_tags))
1389 BOOL standard;
1390 struct BitMap *bmap;
1391 if (GetBitMapAttr(scr->RastPort.BitMap, BMA_FLAGS) & BMF_STANDARD)
1392 standard = TRUE;
1393 else
1394 standard = FALSE;
1396 *width = rect.MaxX - rect.MinX + 1;
1397 *height = rect.MaxY - rect.MinY + 1;
1399 // cout << rect.MinY << " " << rect.MaxY << endl;
1401 bmap =
1402 AllocBitMap(*width, *height, 8, /*NULL,NULL);// */
1403 BMF_MINPLANES, standard ? NULL : scr->RastPort.BitMap);
1404 if (bmap)
1406 struct RastPort rp;
1407 InitRastPort(&rp);
1408 rp.BitMap = bmap;
1409 SetRast(&rp, 1);
1410 DrawIconStateA(&rp, dobj, NULL, 0, 0, IDS_SELECTED, draw_tags);
1412 return bmap;
1416 return NULL;
1418 //-------------------------------------
1420 struct Window *wnd;
1421 struct DragNDrop *drag;
1423 //-------------------------------------
1424 VOID loop()
1426 BOOL ready = FALSE;
1427 static LONG lmx, lmy;
1429 WaitPort(wnd->UserPort);
1430 while (ready == FALSE)
1432 struct IntuiMessage *imsg;
1433 while ((imsg = (struct IntuiMessage *)GetMsg(wnd->UserPort)))
1435 ULONG cl = imsg->Class;
1436 UWORD code = imsg->Code;
1437 // LONG mx = imsg->MouseX;
1438 // LONG my = imsg->MouseY;
1440 ReplyMsg((struct Message *)imsg);
1442 switch (cl)
1444 case IDCMP_CLOSEWINDOW:
1445 ready = TRUE;
1446 break;
1448 case IDCMP_VANILLAKEY:
1450 DrawDragNDrop(drag, wnd->WScreen->MouseX,
1451 wnd->WScreen->MouseY);
1452 lmx = wnd->WScreen->MouseX;
1453 lmy = wnd->WScreen->MouseY;
1455 break;
1457 case IDCMP_MOUSEBUTTONS:
1458 if (code == SELECTDOWN)
1460 DrawDragNDrop(drag, wnd->WScreen->MouseX,
1461 wnd->WScreen->MouseY);
1462 lmx = wnd->WScreen->MouseX;
1463 lmy = wnd->WScreen->MouseY;
1465 break;
1467 case IDCMP_MOUSEMOVE:
1468 // cout << wnd->WScreen->MouseX - lmx << " " << wnd->WScreen->MouseY - lmy << endl;
1469 // WaitBOVP(&wnd->WScreen->ViewPort);
1470 DrawDragNDrop(drag, wnd->WScreen->MouseX,
1471 wnd->WScreen->MouseY);
1472 break;
1477 //-------------------------------------
1479 UBYTE fullmask[8192];
1481 void main()
1483 int i;
1484 for (i = 0; i < 8192; i++)
1485 fullmask[i] = 0xff;
1487 wnd = OpenWindowTags(NULL,
1488 WA_InnerWidth, 400,
1489 WA_InnerHeight, 200,
1490 WA_IDCMP,
1491 IDCMP_CLOSEWINDOW | IDCMP_MOUSEMOVE | IDCMP_INTUITICKS |
1492 IDCMP_MOUSEBUTTONS | IDCMP_VANILLAKEY, WA_DragBar, TRUE,
1493 WA_DepthGadget, TRUE, WA_CloseGadget, TRUE, WA_ReportMouse, TRUE,
1494 WA_Activate, TRUE, WA_GimmeZeroZero, TRUE, WA_MouseQueue, 2,
1495 TAG_DONE);
1496 if (wnd)
1498 BOOL ready = FALSE;
1499 struct DiskObject *obj1 = GetIconTags("SYS:Prefs",
1500 ICONGETA_GenerateImageMasks, TRUE,
1501 TAG_DONE);
1502 struct DiskObject *obj2 = GetIconTags("SYS:Picasso96",
1503 ICONGETA_GenerateImageMasks, TRUE,
1504 TAG_DONE);
1505 struct DiskObject *obj3 = GetIconTags("SYS:Tools",
1506 ICONGETA_GenerateImageMasks, TRUE,
1507 TAG_DONE);
1508 LONG width, height;
1509 struct BitMap *bmap1 =
1510 CreateBitmapFromIcon(wnd->WScreen, obj1, &width, &height);
1511 struct BitMap *bmap2 =
1512 CreateBitmapFromIcon(wnd->WScreen, obj2, &width, &height);
1513 struct BitMap *bmap3 =
1514 CreateBitmapFromIcon(wnd->WScreen, obj3, &width, &height);
1515 if (bmap1 && bmap2 && bmap3)
1517 APTR mask1, mask2, mask3;
1518 IconControl(obj1, ICONCTRLA_GetImageMask1, &mask1, TAG_DONE);
1519 IconControl(obj2, ICONCTRLA_GetImageMask1, &mask2, TAG_DONE);
1520 IconControl(obj3, ICONCTRLA_GetImageMask1, &mask3, TAG_DONE);
1521 if ((drag = CreateDragNDropA(NULL)))
1523 struct BitMapNode *bmn1 =
1524 CreateBitMapNode(GUI_BitMap, bmap1,
1525 GUI_Mask, mask1,
1526 GUI_Width, width,
1527 GUI_Height, height,
1528 GUI_TopOffset, -25,
1529 GUI_LeftOffset, -35,
1530 TAG_DONE);
1532 struct BitMapNode *bmn2 =
1533 CreateBitMapNode(GUI_BitMap, bmap2,
1534 GUI_Mask, mask2,
1535 GUI_Width, width,
1536 GUI_Height, height,
1537 GUI_LeftOffset, 0,
1538 TAG_DONE);
1540 struct BitMapNode *bmn3 =
1541 CreateBitMapNode(GUI_BitMap, bmap3,
1542 GUI_Mask, mask3,
1543 GUI_Width, width,
1544 GUI_Height, height,
1545 GUI_LeftOffset, 99,
1546 GUI_TopOffset, -10,
1547 TAG_DONE);
1549 struct BitMapNode *bmn4 =
1550 CreateBitMapNode(GUI_BitMap, bmap1,
1551 GUI_Mask, mask1,
1552 GUI_Width, width,
1553 GUI_Height, height,
1554 GUI_TopOffset, 60,
1555 TAG_DONE);
1557 struct BitMapNode *bmn5 =
1558 CreateBitMapNode(GUI_BitMap, bmap2,
1559 GUI_Mask, mask2,
1560 GUI_Width, width,
1561 GUI_Height, height,
1562 GUI_LeftOffset, 50,
1563 GUI_TopOffset, 60,
1564 TAG_DONE);
1566 struct BitMapNode *bmn6 =
1567 CreateBitMapNode(GUI_BitMap, bmap3,
1568 GUI_Mask, mask3,
1569 GUI_Width, width,
1570 GUI_Height, height,
1571 GUI_LeftOffset, 100,
1572 GUI_TopOffset, 70,
1573 TAG_DONE);
1575 if (bmn1 && bmn2 && bmn3 && bmn4 && bmn5 && bmn6)
1577 AttachBitMapNode(drag, bmn1);
1578 AttachBitMapNode(drag, bmn2);
1579 AttachBitMapNode(drag, bmn3);
1580 AttachBitMapNode(drag, bmn4);
1581 AttachBitMapNode(drag, bmn5);
1582 AttachBitMapNode(drag, bmn6);
1583 PrepareDragNDrop(drag, wnd->WScreen);
1584 loop();
1585 FinishDragNDrop(drag);
1586 DetachBitMapNode(bmn6);
1587 DetachBitMapNode(bmn5);
1588 DetachBitMapNode(bmn4);
1589 DetachBitMapNode(bmn3);
1590 DetachBitMapNode(bmn2);
1591 DetachBitMapNode(bmn1);
1593 if (bmn6)
1594 DeleteBitMapNode(bmn6);
1595 if (bmn5)
1596 DeleteBitMapNode(bmn5);
1597 if (bmn4)
1598 DeleteBitMapNode(bmn4);
1599 if (bmn3)
1600 DeleteBitMapNode(bmn3);
1601 if (bmn2)
1602 DeleteBitMapNode(bmn2);
1603 if (bmn1)
1604 DeleteBitMapNode(bmn1);
1605 DeleteDragNDrop(drag);
1609 if (bmap3)
1610 FreeBitMap(bmap3);
1611 if (bmap2)
1612 FreeBitMap(bmap2);
1613 if (bmap1)
1614 FreeBitMap(bmap1);
1616 if (obj3)
1617 FreeDiskObject(obj3);
1618 if (obj2)
1619 FreeDiskObject(obj2);
1620 if (obj1)
1621 FreeDiskObject(obj1);
1622 CloseWindow(wnd);
1626 //-------------------------------------
1628 #endif