Cleanup iconlist class in preperation of splitting to iconlist+icon classes, and...
[AROS.git] / workbench / system / Wanderer / Classes / iconlist.c
blob3b41dd2c94fa8b6b5bb1d284e0a26dabf0c6fb4d
1 /*
2 Copyright 2002-2009, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include "../portable_macros.h"
7 #if !defined(__AROS__)
8 #define WANDERER_BUILTIN_ICONLIST 1
9 #else
10 #define DEBUG 0
11 #include <aros/debug.h>
12 #endif
14 //#define DEBUG_ILC_FUNCS
15 //#define DEBUG_ILC_ATTRIBS
16 //#define DEBUG_ILC_EVENTS
17 //#define DEBUG_ILC_KEYEVENTS
18 //#define DEBUG_ILC_ICONDRAGDROP
19 //#define DEBUG_ILC_ICONRENDERING
20 //#define DEBUG_ILC_ICONSORTING
21 //#define DEBUG_ILC_ICONSORTING_DUMP
22 //#define DEBUG_ILC_ICONPOSITIONING
23 //#define DEBUG_ILC_LASSO
24 //#define DEBUG_ILC_MEMALLOC
26 #define CREATE_FULL_DRAGIMAGE
28 #include <string.h>
29 #include <stdlib.h>
30 #include <stdio.h>
31 #include <string.h>
32 #include <math.h>
34 #include <dos/dos.h>
35 #include <dos/datetime.h>
36 #include <dos/filehandler.h>
38 #include <exec/memory.h>
39 #include <graphics/gfx.h>
40 #include <graphics/view.h>
41 #include <graphics/rpattr.h>
42 #include <workbench/icon.h>
43 #include <workbench/workbench.h>
45 #if defined(__AROS__)
46 #include <devices/rawkeycodes.h>
47 #include <clib/alib_protos.h>
48 #else
49 #include <devices_AROS/rawkeycodes.h>
50 #endif
53 #include <proto/exec.h>
54 #include <proto/graphics.h>
55 #include <proto/utility.h>
56 #include <proto/dos.h>
57 #include <proto/icon.h>
58 #include <proto/layers.h>
59 #include <proto/dos.h>
60 #include <proto/iffparse.h>
62 #if defined(__AROS__)
63 #include <prefs/prefhdr.h>
64 #include <prefs/wanderer.h>
65 #else
66 #include <prefs_AROS/prefhdr.h>
67 #include <prefs_AROS/wanderer.h>
68 #endif
70 #include <proto/cybergraphics.h>
72 #if defined(__AROS__)
73 #include <cybergraphx/cybergraphics.h>
74 #else
75 #include <cybergraphx_AROS/cybergraphics.h>
76 #endif
79 #if defined(__AMIGA__) && !defined(__PPC__)
80 #define NO_INLINE_STDARG
81 #endif
82 #include <proto/intuition.h>
83 #include <proto/muimaster.h>
84 #include <libraries/mui.h>
85 #include "iconlist_attributes.h"
86 #include "icon_attributes.h"
87 #include "iconlist.h"
88 #include "iconlist_private.h"
89 #include "iconlistview.h"
91 #if !defined(__AROS__)
92 #define DEBUG 1
94 #ifdef DEBUG
95 #define D(x) if (DEBUG) x
96 #ifdef __amigaos4__
97 #define bug DebugPrintF
98 #else
99 #define bug kprintf
100 #endif
101 #else
102 #define D(...)
103 #endif
104 #endif
106 #define _between(a,x,b) ((x)>=(a) && (x)<=(b))
107 #define _isinobject(x,y) (_between(_mleft(obj),(x),_mright (obj)) \
108 && _between(_mtop(obj) ,(y),_mbottom(obj)))
110 extern struct Library *MUIMasterBase;
112 static struct Hook __iconlist_UpdateLabels_hook;
114 // N.B: We Handle frame/background rendering so make sure icon.library doesnt do it ..
115 struct TagItem __iconList_DrawIconStateTags[] = {
116 { ICONDRAWA_Frameless, TRUE},
117 { ICONDRAWA_Borderless, TRUE},
118 { ICONDRAWA_EraseBackground, FALSE},
119 { TAG_DONE, }
122 #ifndef NO_ICON_POSITION
123 #define NO_ICON_POSITION (0x8000000) /* belongs to workbench/workbench.h */
124 #endif
126 #define UPDATE_SINGLEICON 1
127 #define UPDATE_SCROLL 2
128 #define UPDATE_SORT 3
129 #define UPDATE_RESIZE 4
131 #define LEFT_BUTTON 1
132 #define RIGHT_BUTTON 2
133 #define MIDDLE_BUTTON 4
135 #define ICONLIST_DRAWMODE_NORMAL 1
136 #define ICONLIST_DRAWMODE_FAST 2
138 /**************************************************************************
139 Support Functions
140 **************************************************************************/
142 #define ForeachNodeReversed(list, node) \
143 for \
145 node = (void *)(((struct List *)(list))->lh_TailPred); \
146 ((struct Node *)(node))->ln_Pred; \
147 node = (void *)(((struct Node *)(node))->ln_Pred) \
150 #if defined(AndRectRect)
151 /* Fine */
152 #else
153 #if defined(__AROS__)
154 #error "Implement AndRectRect (rom/graphics/andrectrect.c)"
155 #else
156 #warning "Implement AndRectRect (rom/graphics/andrectrect.c)"
157 #endif
158 #endif
160 #define RPALPHAFLAT (1 << 0)
161 #define RPALPHARADIAL (1 << 1)
163 static void RastPortSetAlpha(struct RastPort *arport, ULONG ax, ULONG ay, ULONG width, ULONG height, UBYTE val, UBYTE alphamode)
165 ULONG x, y;
166 ULONG alphaval, pixelval;
168 for (y = 0; y < height; y++)
170 for (x = 0; x < width; x++)
172 if ((pixelval = ReadRGBPixel(arport, x, y)))
174 if (alphamode == RPALPHARADIAL){
175 //Set the alpha value based on distance from ax,ay
176 } else {
177 alphaval = val;
179 WriteRGBPixel(arport, x, y, ((pixelval & 0xffffff)|(alphaval << 24)));
185 ///RectAndRect()
186 // Icon/Label Area support functions
187 static int RectAndRect(struct Rectangle *a, struct Rectangle *b)
189 if ((a->MinX > b->MaxX) || (a->MinY > b->MaxY) || (a->MaxX < b->MinX) || (a->MaxY < b->MinY))
190 return 0;
191 return 1;
195 ///Node_NextVisible()
196 // IconEntry List navigation functions ..
197 static struct IconEntry *Node_NextVisible(struct IconEntry *current_Node)
199 current_Node = (struct IconEntry *)GetSucc(&current_Node->ie_IconNode);
200 while ((current_Node != NULL) && (!(current_Node->ie_Flags & ICONENTRY_FLAG_VISIBLE)))
202 current_Node = (struct IconEntry *)GetSucc(&current_Node->ie_IconNode);
204 return current_Node;
208 ///Node_FirstVisible()
209 static struct IconEntry *Node_FirstVisible(struct List *icon_list)
211 struct IconEntry *current_Node = (struct IconEntry *)GetHead(icon_list);
213 if ((current_Node != NULL) && !(current_Node->ie_Flags & ICONENTRY_FLAG_VISIBLE))
214 current_Node = Node_NextVisible(current_Node);
216 return current_Node;
220 ///Node_PreviousVisible()
221 static struct IconEntry *Node_PreviousVisible(struct IconEntry *current_Node)
223 current_Node = (struct IconEntry *)GetPred(&current_Node->ie_IconNode);
224 while ((current_Node != NULL) && (!(current_Node->ie_Flags & ICONENTRY_FLAG_VISIBLE)))
226 current_Node = (struct IconEntry *)GetPred(&current_Node->ie_IconNode);
228 return current_Node;
232 ///Node_LastVisible()
233 static struct IconEntry *Node_LastVisible(struct List *icon_list)
235 struct IconEntry *current_Node = (struct IconEntry *)GetTail(icon_list);
237 if ((current_Node != NULL) && !(current_Node->ie_Flags & ICONENTRY_FLAG_VISIBLE))
238 current_Node = Node_PreviousVisible(current_Node);
240 return current_Node;
244 const UBYTE MSG_MEM_G[] = "GB";
245 const UBYTE MSG_MEM_M[] = "MB";
246 const UBYTE MSG_MEM_K[] = "KB";
247 const UBYTE MSG_MEM_B[] = "Bytes";
249 ///FmtSizeToString()
250 static void FmtSizeToString(UBYTE *buf, ULONG num)
252 UQUAD d;
253 UBYTE *ch;
254 struct
256 IPTR val;
257 IPTR dec;
258 } array =
260 num,
264 if (num >= 1073741824)
266 //Gigabytes
267 array.val = num >> 30;
268 d = ((UQUAD)num * 10 + 536870912) / 1073741824;
269 array.dec = d % 10;
270 ch = MSG_MEM_G;
272 else if (num >= 1048576)
274 //Megabytes
275 array.val = num >> 20;
276 d = ((UQUAD)num * 10 + 524288) / 1048576;
277 array.dec = d % 10;
278 ch = MSG_MEM_M;
280 else if (num >= 1024)
282 //Kilobytes
283 array.val = num >> 10;
284 d = (num * 10 + 512) / 1024;
285 array.dec = d % 10;
286 ch = MSG_MEM_K;
288 else
290 //Bytes
291 array.val = num;
292 array.dec = 0;
293 d = 0;
294 ch = MSG_MEM_B;
297 if (!array.dec && (d > array.val * 10))
299 array.val++;
302 RawDoFmt(array.dec ? "%lu.%lu" : "%lu", &array, NULL, buf);
304 while (*buf)
306 buf++;
309 sprintf(buf, " %s", ch);
313 ///GetAbsoluteLassoRect()
314 // get positive lasso coords
315 static void GetAbsoluteLassoRect(struct IconList_DATA *data, struct Rectangle *LassoRectangle)
317 WORD minx = data->icld_LassoRectangle.MinX;
318 WORD miny = data->icld_LassoRectangle.MinY;
319 WORD maxx = data->icld_LassoRectangle.MaxX;
320 WORD maxy = data->icld_LassoRectangle.MaxY;
322 #if defined(DEBUG_ILC_LASSO) && defined(DEBUG_ILC_FUNCS)
323 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
324 #endif
326 if (minx > maxx)
328 /* Swap minx, maxx */
329 minx ^= maxx;
330 maxx ^= minx;
331 minx ^= maxx;
334 if (miny > maxy)
336 /* Swap miny, maxy */
337 miny ^= maxy;
338 maxy ^= miny;
339 miny ^= maxy;
342 LassoRectangle->MinX = data->view_rect.MinX - data->icld_ViewX + minx;
343 LassoRectangle->MinY = data->view_rect.MinY - data->icld_ViewY + miny;
344 LassoRectangle->MaxX = data->view_rect.MinX - data->icld_ViewX + maxx;
345 LassoRectangle->MaxY = data->view_rect.MinY - data->icld_ViewY + maxy;
349 ///IconList_InvertPixelRect()
350 static void IconList_InvertPixelRect(struct RastPort *rp, WORD minx, WORD miny, WORD maxx, WORD maxy, struct Rectangle *clip)
352 struct Rectangle r, clipped_r;
354 #if defined(DEBUG_ILC_RENDERING) && defined(DEBUG_ILC_FUNCS)
355 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
356 #endif
358 if (maxx < minx)
360 /* Swap minx, maxx */
361 minx ^= maxx;
362 maxx ^= minx;
363 minx ^= maxx;
366 if (maxy < miny)
368 /* Swap miny, maxy */
369 miny ^= maxy;
370 maxy ^= miny;
371 miny ^= maxy;
374 r.MinX = minx;
375 r.MinY = miny;
376 r.MaxX = maxx;
377 r.MaxY = maxy;
379 if (AndRectRect(&r, clip, &clipped_r))
381 InvertPixelArray(rp, clipped_r.MinX, clipped_r.MinY,
382 clipped_r.MaxX - clipped_r.MinX + 1, clipped_r.MaxY - clipped_r.MinY + 1);
387 ///IconList_InvertLassoOutlines()
388 // Simple lasso drawing by inverting area outlines
389 static void IconList_InvertLassoOutlines(Object *obj, struct Rectangle *rect)
391 struct Rectangle lasso;
392 struct Rectangle clip;
394 #if defined(DEBUG_ILC_LASSO) && defined(DEBUG_ILC_FUNCS)
395 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
396 #endif
398 /* get abolute iconlist coords */
399 lasso.MinX = rect->MinX + _mleft(obj);
400 lasso.MaxX = rect->MaxX + _mleft(obj);
401 lasso.MinY = rect->MinY + _mtop(obj);
402 lasso.MaxY = rect->MaxY + _mtop(obj);
404 clip.MinX = _mleft(obj);
405 clip.MinY = _mtop(obj);
406 clip.MaxX = _mright(obj);
407 clip.MaxY = _mbottom(obj);
409 /* horizontal lasso lines */
410 IconList_InvertPixelRect(_rp(obj), lasso.MinX, lasso.MinY, lasso.MaxX-1, lasso.MinY + 1, &clip);
411 IconList_InvertPixelRect(_rp(obj), lasso.MinX, lasso.MaxY, lasso.MaxX-1, lasso.MaxY + 1, &clip);
413 /* vertical lasso lines */
414 IconList_InvertPixelRect(_rp(obj), lasso.MinX, lasso.MinY, lasso.MinX + 1, lasso.MaxY - 1, &clip);
415 IconList_InvertPixelRect(_rp(obj), lasso.MaxX, lasso.MinY, lasso.MaxX + 1, lasso.MaxY - 1, &clip);
419 ///IconList_GetIconImageRectangle()
420 //We don't use icon.library's label drawing so we do this by hand
421 static void IconList_GetIconImageRectangle(Object *obj, struct IconList_DATA *data, struct IconEntry *icon, struct Rectangle *rect)
423 #if defined(DEBUG_ILC_ICONPOSITIONING) && defined(DEBUG_ILC_FUNCS)
424 D(bug("[IconList]: %s(icon @ %p)\n", __PRETTY_FUNCTION__, icon));
425 #endif
427 /* Get basic width/height */
428 GetIconRectangleA(NULL, icon->ie_DiskObj, NULL, rect, NULL);
429 #if defined(DEBUG_ILC_ICONPOSITIONING)
430 D(bug("[IconList] %s: MinX %d, MinY %d MaxX %d, MaxY %d\n", __PRETTY_FUNCTION__, rect->MinX, rect->MinY, rect->MaxX, rect->MaxY));
431 #endif
432 icon->ie_IconWidth = (rect->MaxX - rect->MinX) + 1;
433 icon->ie_IconHeight = (rect->MaxY - rect->MinY) + 1;
435 if (icon->ie_IconHeight > data->icld_IconLargestHeight)
436 data->icld_IconLargestHeight = icon->ie_IconHeight;
440 ///IconList_GetIconLabelRectangle()
441 static void IconList_GetIconLabelRectangle(Object *obj, struct IconList_DATA *data, struct IconEntry *icon, struct Rectangle *rect)
443 ULONG outline_offset = 0;
444 ULONG textwidth = 0;
446 #if defined(DEBUG_ILC_ICONPOSITIONING) && defined(DEBUG_ILC_FUNCS)
447 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
448 #endif
450 switch ( data->icld__Option_LabelTextMode )
452 case ICON_TEXTMODE_DROPSHADOW:
453 outline_offset = 1;
454 break;
456 case ICON_TEXTMODE_PLAIN:
457 break;
459 default:
460 outline_offset = 2;
461 break;
464 /* Get icon box width including text width */
465 if ((icon->ie_IconListEntry.label != NULL) && (icon->ie_TxtBuf_DisplayedLabel != NULL))
467 ULONG curlabel_TotalLines;
468 SetFont(data->icld_BufferRastPort, data->icld_IconLabelFont);
470 rect->MinX = 0;
471 rect->MaxX = (((data->icld__Option_LabelTextHorizontalPadding + data->icld__Option_LabelTextBorderWidth) * 2) + icon->ie_TxtBuf_DisplayedLabelWidth + outline_offset) - 1;
473 rect->MinY = 0;
475 curlabel_TotalLines = icon->ie_SplitParts;
476 if (curlabel_TotalLines == 0)
477 curlabel_TotalLines = 1;
478 if (curlabel_TotalLines > data->icld__Option_LabelTextMultiLine)
479 curlabel_TotalLines = data->icld__Option_LabelTextMultiLine;
481 rect->MaxY = (((data->icld__Option_LabelTextBorderHeight + data->icld__Option_LabelTextVerticalPadding) * 2) +
482 ((data->icld_IconLabelFont->tf_YSize + outline_offset) * curlabel_TotalLines)) - 1;
484 /* Date/size sorting has the date/size appended under the icon label
485 only list regular files like this (drawers have no size/date output) */
487 icon->ie_IconListEntry.type != ST_USERDIR &&
488 ((data->icld_SortFlags & ICONLIST_SORT_BY_SIZE) || (data->icld_SortFlags & ICONLIST_SORT_BY_DATE))
491 SetFont(data->icld_BufferRastPort, data->icld_IconInfoFont);
493 if( (data->icld_SortFlags & ICONLIST_SORT_BY_SIZE) && !(data->icld_SortFlags & ICONLIST_SORT_BY_DATE) )
495 icon->ie_TxtBuf_SIZEWidth = TextLength(data->icld_BufferRastPort, icon->ie_TxtBuf_SIZE, strlen(icon->ie_TxtBuf_SIZE));
496 textwidth = icon->ie_TxtBuf_SIZEWidth;
498 else
500 if( !(data->icld_SortFlags & ICONLIST_SORT_BY_SIZE) && (data->icld_SortFlags & ICONLIST_SORT_BY_DATE) )
502 if( icon->ie_Flags & ICONENTRY_FLAG_TODAY )
504 icon->ie_TxtBuf_TIMEWidth = TextLength(data->icld_BufferRastPort, icon->ie_TxtBuf_TIME, strlen(icon->ie_TxtBuf_TIME));
505 textwidth = icon->ie_TxtBuf_TIMEWidth;
507 else
509 icon->ie_TxtBuf_DATEWidth = TextLength(data->icld_BufferRastPort, icon->ie_TxtBuf_DATE, strlen(icon->ie_TxtBuf_DATE));
510 textwidth = icon->ie_TxtBuf_DATEWidth;
515 if (textwidth > 0)
517 rect->MaxY = rect->MaxY + data->icld_IconInfoFont->tf_YSize + outline_offset;
518 if ((textwidth + outline_offset + ((data->icld__Option_LabelTextHorizontalPadding + data->icld__Option_LabelTextBorderWidth) * 2)) > ((rect->MaxX - rect->MinX) + 1))
519 rect->MaxX = (textwidth + outline_offset + ((data->icld__Option_LabelTextVerticalPadding + data->icld__Option_LabelTextBorderWidth) * 2)) - 1;
523 if (((rect->MaxY - rect->MinY) + 1) > data->icld_LabelLargestHeight) data->icld_LabelLargestHeight = ((rect->MaxY - rect->MinY) + 1);
527 ///IconList_GetIconAreaRectangle()
528 static void IconList_GetIconAreaRectangle(Object *obj, struct IconList_DATA *data, struct IconEntry *icon, struct Rectangle *rect)
530 struct Rectangle labelrect;
531 ULONG iconlabel_Width;
532 ULONG iconlabel_Height;
534 #if defined(DEBUG_ILC_ICONPOSITIONING) && defined(DEBUG_ILC_FUNCS)
535 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
536 #endif
538 /* Get icon box width including text width */
539 memset(rect, 0, sizeof(struct Rectangle));
541 IconList_GetIconImageRectangle(obj, data, icon, rect);
543 icon->ie_AreaWidth = icon->ie_IconWidth;
544 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
546 icon->ie_AreaHeight = data->icld_IconLargestHeight;
548 else
550 icon->ie_AreaHeight = icon->ie_IconHeight;
553 IconList_GetIconLabelRectangle(obj, data, icon, &labelrect);
555 iconlabel_Width = ((labelrect.MaxX - labelrect.MinX) + 1);
556 iconlabel_Height = ((labelrect.MaxY - labelrect.MinY) + 1);
558 if (iconlabel_Width > icon->ie_AreaWidth)
559 icon->ie_AreaWidth = iconlabel_Width;
561 icon->ie_AreaHeight = icon->ie_AreaHeight + data->icld__Option_IconImageSpacing + iconlabel_Height;
563 /* Store */
564 rect->MaxX = (rect->MinX + icon->ie_AreaWidth) - 1;
565 rect->MaxY = (rect->MinY + icon->ie_AreaHeight) - 1;
567 if (icon->ie_AreaWidth > data->icld_IconAreaLargestWidth) data->icld_IconAreaLargestWidth = icon->ie_AreaWidth;
568 if (icon->ie_AreaHeight > data->icld_IconAreaLargestHeight) data->icld_IconAreaLargestHeight = icon->ie_AreaHeight;
571 /**************************************************************************
572 Draw the icon at its position
573 **************************************************************************/
574 ///IconList__MUIM_IconList_DrawEntry()
575 IPTR IconList__MUIM_IconList_DrawEntry(struct IClass *CLASS, Object *obj, struct MUIP_IconList_DrawEntry *message)
577 struct IconList_DATA *data = INST_DATA(CLASS, obj);
579 BOOL outside = FALSE;
581 struct Rectangle iconrect;
582 struct Rectangle objrect;
584 LONG offsetx,offsety;
586 ULONG objX, objY, objW, objH;
587 LONG iconX, iconY;
588 ULONG iconW, iconH;
590 if (data->icld_BufferRastPort == data->icld_DisplayRastPort)
592 objX = _mleft(obj);
593 objY = _mtop(obj);
595 else
597 objX = objY = 0;
599 objW = _mright(obj) - _mleft(obj) + 1;
600 objH = _mbottom(obj) - _mtop(obj) + 1;
602 #if defined(DEBUG_ILC_ICONRENDERING)
603 D(bug("[IconList]: %s(message->icon = 0x%p)\n", __PRETTY_FUNCTION__, message->icon));
604 #endif
606 if ((!(message->icon->ie_Flags & ICONENTRY_FLAG_VISIBLE)) ||
607 (data->icld_BufferRastPort == NULL) ||
608 (!(message->icon->ie_DiskObj)))
610 #if defined(DEBUG_ILC_ICONRENDERING)
611 D(bug("[IconList] %s: Not visible or missing DOB\n", __PRETTY_FUNCTION__));
612 #endif
613 return FALSE;
616 /* Get the dimensions and affected area of message->icon */
617 IconList_GetIconImageRectangle(obj, data, message->icon, &iconrect);
618 iconW = iconrect.MaxX - iconrect.MinX + 1;
619 iconH = iconrect.MaxY - iconrect.MinY + 1;
621 /* Add the relative position offset of the message->icon */
622 offsetx = objX - data->icld_ViewX + message->icon->ie_IconX;
623 /* Centre our image with our text */
624 if (message->icon->ie_IconWidth < message->icon->ie_AreaWidth)
625 offsetx += (message->icon->ie_AreaWidth - message->icon->ie_IconWidth)/2;
627 if ((data->icld__Option_IconListMode == ICON_LISTMODE_GRID) &&
628 (message->icon->ie_AreaWidth < data->icld_IconAreaLargestWidth))
629 offsetx += ((data->icld_IconAreaLargestWidth - message->icon->ie_AreaWidth)/2);
631 iconrect.MinX += offsetx;
632 iconrect.MaxX += offsetx;
634 offsety = objY - data->icld_ViewY + message->icon->ie_IconY;
635 iconrect.MinY += offsety;
636 iconrect.MaxY += offsety;
638 /* Add the relative position of the window */
639 objrect.MinX = objX;
640 objrect.MinY = objY;
641 objrect.MaxX = objX + objW;
642 objrect.MaxY = objY + objH;
644 if (!RectAndRect(&iconrect, &objrect))
646 #if defined(DEBUG_ILC_ICONRENDERING)
647 D(bug("[IconList] %s: Icon '%s' image outside of visible area .. skipping\n", __PRETTY_FUNCTION__, message->icon->ie_IconListEntry.label));
648 #endif
649 return FALSE;
652 /* data->update_rect1 and data->update_rect2 may
653 point to rectangles to indicate that only icons
654 in any of this rectangles need to be drawn */
655 if (data->update_rect1)
657 if (!RectAndRect(&iconrect, data->update_rect1)) outside = TRUE;
660 if (data->update_rect2)
662 if (data->update_rect1)
664 if ((outside == TRUE) && RectAndRect(&iconrect, data->update_rect2))
665 outside = FALSE;
667 else
669 if (!RectAndRect(&iconrect, data->update_rect2))
670 outside = TRUE;
674 if (outside == TRUE)
676 #if defined(DEBUG_ILC_ICONRENDERING)
677 D(bug("[IconList] %s: Icon '%s' image outside of update area .. skipping\n", __PRETTY_FUNCTION__, message->icon->ie_IconListEntry.label));
678 #endif
679 return FALSE;
682 if (message->drawmode == ICONENTRY_DRAWMODE_NONE) return TRUE;
684 // Center icon image
685 iconX = iconrect.MinX - objX + data->icld_DrawOffsetX;
686 iconY = iconrect.MinY - objY + data->icld_DrawOffsetY;
688 if ((data->icld_BufferRastPort == data->icld_DisplayRastPort) ||
689 ((data->icld_BufferRastPort != data->icld_DisplayRastPort) &&
690 ((iconX > objX) && (iconX < (objX + objW)) && (iconY > objY) && (iconY < (objY + objH))) &&
691 (((iconX + iconW) > objX) && ((iconX + iconW)< (objX + objW)) && ((iconY + iconH) > objY) && ((iconY + iconH) < (objY + objH)))
694 #if defined(DEBUG_ILC_ICONRENDERING)
695 D(bug("[IconList] %s: DrawIconState('%s') .. %d, %d\n", __PRETTY_FUNCTION__, message->icon->ie_IconListEntry.label, iconX, iconY));
696 #endif
697 DrawIconStateA
699 data->icld_BufferRastPort, message->icon->ie_DiskObj, NULL,
700 iconX,
701 iconY,
702 (message->icon->ie_Flags & ICONENTRY_FLAG_SELECTED) ? IDS_SELECTED : IDS_NORMAL,
703 __iconList_DrawIconStateTags
705 #if defined(DEBUG_ILC_ICONRENDERING)
706 D(bug("[IconList] %s: DrawIconState Done\n", __PRETTY_FUNCTION__));
707 #endif
709 #if defined(DEBUG_ILC_ICONRENDERING)
710 else
712 D(bug("[IconList] %s: DrawIconState('%s') NEEDS CLIPPED!\n", __PRETTY_FUNCTION__, message->icon->ie_IconListEntry.label));
714 #endif
716 return TRUE;
720 ///IconList__LabelFunc_SplitLabel()
721 void IconList__LabelFunc_SplitLabel(Object *obj, struct IconList_DATA *data, struct IconEntry *icon)
723 ULONG labelSplit_MaxLabelLineLength = data->icld__Option_LabelTextMaxLen;
724 ULONG labelSplit_LabelLength = strlen(icon->ie_IconListEntry.label);
725 ULONG txwidth;
726 // ULONG labelSplit_FontY = data->icld_IconLabelFont->tf_YSize;
727 int labelSplit_CharsDone, labelSplit_CharsSplit;
728 ULONG labelSplit_CurSplitWidth;
730 if ((data->icld__Option_TrimVolumeNames) &&
731 ((icon->ie_IconListEntry.type == ST_ROOT) && (icon->ie_IconListEntry.label[labelSplit_LabelLength - 1] == ':')))
732 labelSplit_LabelLength--;
734 if (labelSplit_MaxLabelLineLength >= labelSplit_LabelLength)
736 #if defined(DEBUG_ILC_ICONRENDERING)
737 D(bug("[IconList]: %s: Label'%s' doesnt need split (onyl %d chars)\n", __PRETTY_FUNCTION__, icon->ie_IconListEntry.label, labelSplit_LabelLength));
738 #endif
739 return;
742 SetFont(data->icld_BufferRastPort, data->icld_IconLabelFont);
743 txwidth = TextLength(data->icld_BufferRastPort, icon->ie_IconListEntry.label, labelSplit_MaxLabelLineLength);
744 #if defined(DEBUG_ILC_ICONRENDERING)
745 D(bug("[IconList]: %s: txwidth = %d\n", __PRETTY_FUNCTION__, txwidth));
746 #endif
747 icon->ie_TxtBuf_DisplayedLabel = AllocVecPooled(data->icld_Pool, 256);
748 memset(icon->ie_TxtBuf_DisplayedLabel, 0, 256);
749 icon->ie_SplitParts = 0;
751 labelSplit_CharsDone = 0;
752 labelSplit_CharsSplit = 0;
754 while (labelSplit_CharsDone < labelSplit_LabelLength)
756 ULONG labelSplit_CurSplitLength = labelSplit_LabelLength - labelSplit_CharsDone;
757 IPTR labelSplit_SplitStart = (IPTR)(icon->ie_IconListEntry.label + labelSplit_CharsDone);
758 int tmp_checkoffs = 0;
759 IPTR labelSplit_RemainingCharsAfterSplit;
760 IPTR labelSplit_CurSplitDest;
762 while (*(char *)(labelSplit_SplitStart) == ' ')
764 //Skip preceding spaces..
765 labelSplit_SplitStart = labelSplit_SplitStart + 1;
766 labelSplit_CurSplitLength = labelSplit_CurSplitLength - 1;
767 labelSplit_CharsDone = labelSplit_CharsDone + 1;
770 while(TextLength(data->icld_BufferRastPort, (char *)labelSplit_SplitStart, labelSplit_CurSplitLength) < txwidth) labelSplit_CurSplitLength++;
771 while(TextLength(data->icld_BufferRastPort, (char *)labelSplit_SplitStart, labelSplit_CurSplitLength) > txwidth) labelSplit_CurSplitLength--;
772 #if defined(DEBUG_ILC_ICONRENDERING)
773 D(bug("[IconList]: %s: labelSplit_CurSplitLength = %d\n", __PRETTY_FUNCTION__, labelSplit_CurSplitLength));
774 #endif
776 #if defined(DEBUG_ILC_ICONRENDERING)
777 D(bug("[IconList]: %s: Attempting to find neat split ", __PRETTY_FUNCTION__));
778 #endif
779 while(tmp_checkoffs < (labelSplit_CurSplitLength - ILC_ICONLABEL_SHORTEST))
781 #if defined(DEBUG_ILC_ICONRENDERING)
782 D(bug("%d", tmp_checkoffs));
783 #endif
784 labelSplit_RemainingCharsAfterSplit = labelSplit_LabelLength - (labelSplit_CharsDone + labelSplit_CurSplitLength);
786 if ((labelSplit_CurSplitLength - tmp_checkoffs) > ILC_ICONLABEL_SHORTEST)
788 #if defined(DEBUG_ILC_ICONRENDERING)
789 D(bug("<"));
790 #endif
791 if ((*(char *)(labelSplit_SplitStart + labelSplit_CurSplitLength - tmp_checkoffs) == ' ') ||
792 (*(char *)(labelSplit_SplitStart + labelSplit_CurSplitLength - tmp_checkoffs) == '.') ||
793 (*(char *)(labelSplit_SplitStart + labelSplit_CurSplitLength - tmp_checkoffs) == '-'))
795 #if defined(DEBUG_ILC_ICONRENDERING)
796 D(bug("!"));
797 #endif
798 labelSplit_CurSplitLength = labelSplit_CurSplitLength - tmp_checkoffs;
799 labelSplit_RemainingCharsAfterSplit = labelSplit_RemainingCharsAfterSplit - tmp_checkoffs;
800 tmp_checkoffs = 0;
801 break;
805 if ((labelSplit_RemainingCharsAfterSplit - tmp_checkoffs) < 0)
807 #if defined(DEBUG_ILC_ICONRENDERING)
808 D(bug("="));
809 #endif
810 labelSplit_CurSplitLength = labelSplit_CurSplitLength + tmp_checkoffs;
811 labelSplit_RemainingCharsAfterSplit = labelSplit_RemainingCharsAfterSplit + tmp_checkoffs;
812 tmp_checkoffs = 0;
813 break;
816 if ((labelSplit_RemainingCharsAfterSplit - tmp_checkoffs) >= ILC_ICONLABEL_SHORTEST)
818 #if defined(DEBUG_ILC_ICONRENDERING)
819 D(bug(">"));
820 #endif
821 if ((*(char *)(labelSplit_SplitStart + labelSplit_CurSplitLength + tmp_checkoffs) == ' ') ||
822 (*(char *)(labelSplit_SplitStart + labelSplit_CurSplitLength + tmp_checkoffs) == '.') ||
823 (*(char *)(labelSplit_SplitStart + labelSplit_CurSplitLength + tmp_checkoffs) == '-'))
825 #if defined(DEBUG_ILC_ICONRENDERING)
826 D(bug("!"));
827 #endif
828 labelSplit_CurSplitLength = labelSplit_CurSplitLength + tmp_checkoffs;
829 labelSplit_RemainingCharsAfterSplit = labelSplit_RemainingCharsAfterSplit + tmp_checkoffs;
830 tmp_checkoffs = 0;
831 break;
835 tmp_checkoffs = tmp_checkoffs + 1;
837 #if defined(DEBUG_ILC_ICONRENDERING)
838 D(bug("\n"));
839 #endif
840 if (tmp_checkoffs != 0)
842 #if defined(DEBUG_ILC_ICONRENDERING)
843 D(bug("[IconList]: %s: Couldnt find neat split : Still %d chars\n", __PRETTY_FUNCTION__, labelSplit_RemainingCharsAfterSplit));
844 #endif
845 if (labelSplit_RemainingCharsAfterSplit <= ILC_ICONLABEL_SHORTEST)
847 labelSplit_CurSplitLength = labelSplit_CurSplitLength + (labelSplit_RemainingCharsAfterSplit - ILC_ICONLABEL_SHORTEST);
850 if ((labelSplit_CharsDone + labelSplit_CurSplitLength) > labelSplit_LabelLength) labelSplit_CurSplitLength = labelSplit_LabelLength - labelSplit_CharsDone;
852 labelSplit_CurSplitDest = (IPTR)(icon->ie_TxtBuf_DisplayedLabel + labelSplit_CharsSplit + icon->ie_SplitParts);
854 strncpy((char *)labelSplit_CurSplitDest, (char *)labelSplit_SplitStart, labelSplit_CurSplitLength);
856 labelSplit_CurSplitWidth = TextLength(data->icld_BufferRastPort, (char *)labelSplit_CurSplitDest, labelSplit_CurSplitLength);
858 icon->ie_SplitParts = icon->ie_SplitParts + 1;
860 labelSplit_CharsDone = labelSplit_CharsDone + labelSplit_CurSplitLength;
861 labelSplit_CharsSplit = labelSplit_CharsSplit + labelSplit_CurSplitLength;
863 if (labelSplit_CurSplitWidth > icon->ie_TxtBuf_DisplayedLabelWidth) icon->ie_TxtBuf_DisplayedLabelWidth = labelSplit_CurSplitWidth;
865 if ((icon->ie_SplitParts <= 1) && icon->ie_TxtBuf_DisplayedLabel)
867 FreeVecPooled(data->icld_Pool, icon->ie_TxtBuf_DisplayedLabel);
868 icon->ie_TxtBuf_DisplayedLabel = NULL;
869 icon->ie_SplitParts = 0;
871 // if ((labelSplit_FontY * icon->ie_SplitParts) > data->icld_LabelLargestHeight) data->icld_LabelLargestHeight = (labelSplit_FontY * icon->ie_SplitParts);
875 ///IconList__LabelFunc_CreateLabel()
876 IPTR IconList__LabelFunc_CreateLabel(Object *obj, struct IconList_DATA *data, struct IconEntry *icon)
878 #if defined(DEBUG_ILC_ICONRENDERING) && defined(DEBUG_ILC_FUNCS)
879 D(bug("[IconList]: %s('%s')\n", __PRETTY_FUNCTION__, icon->ie_IconListEntry.label));
880 #endif
881 if (icon->ie_TxtBuf_DisplayedLabel)
883 FreeVecPooled(data->icld_Pool, icon->ie_TxtBuf_DisplayedLabel);
884 icon->ie_TxtBuf_DisplayedLabel = NULL;
885 icon->ie_SplitParts = 0;
888 if (data->icld__Option_LabelTextMultiLine > 1)
890 #if defined(DEBUG_ILC_ICONRENDERING)
891 D(bug("[IconList]: %s: Attempting to split label ..\n", __PRETTY_FUNCTION__));
892 #endif
893 IconList__LabelFunc_SplitLabel(obj, data, icon);
896 if (icon->ie_TxtBuf_DisplayedLabel == NULL)
898 ULONG ie_LabelLength = strlen(icon->ie_IconListEntry.label);
899 icon->ie_SplitParts = 1;
901 #if defined(DEBUG_ILC_ICONRENDERING)
902 D(bug("[IconList]: %s: Building unsplit label (len = %d) ..\n", __PRETTY_FUNCTION__, ie_LabelLength));
903 #endif
905 if ((data->icld__Option_TrimVolumeNames) &&
906 ((icon->ie_IconListEntry.type == ST_ROOT) && (icon->ie_IconListEntry.label[ie_LabelLength - 1] == ':')))
907 ie_LabelLength--;
909 if(ie_LabelLength > data->icld__Option_LabelTextMaxLen)
911 if (!(icon->ie_TxtBuf_DisplayedLabel = AllocVecPooled(data->icld_Pool, data->icld__Option_LabelTextMaxLen + 1)))
913 return (IPTR)NULL;
915 memset(icon->ie_TxtBuf_DisplayedLabel, 0, data->icld__Option_LabelTextMaxLen + 1);
916 strncpy(icon->ie_TxtBuf_DisplayedLabel, icon->ie_IconListEntry.label, data->icld__Option_LabelTextMaxLen - 3);
917 strcat(icon->ie_TxtBuf_DisplayedLabel , " ..");
919 else
921 if (!(icon->ie_TxtBuf_DisplayedLabel = AllocVecPooled(data->icld_Pool, ie_LabelLength + 1)))
923 return (IPTR)NULL;
925 memset(icon->ie_TxtBuf_DisplayedLabel, 0, ie_LabelLength + 1);
926 strncpy(icon->ie_TxtBuf_DisplayedLabel, icon->ie_IconListEntry.label, ie_LabelLength );
928 icon->ie_TxtBuf_DisplayedLabelWidth = TextLength(data->icld_BufferRastPort, icon->ie_TxtBuf_DisplayedLabel, strlen(icon->ie_TxtBuf_DisplayedLabel));
929 // if ((data->icld_IconLabelFont->tf_YSize) > data->icld_LabelLargestHeight) data->icld_LabelLargestHeight = data->icld_IconLabelFont->tf_YSize;
932 // if (icon->ie_TxtBuf_DisplayedLabelWidth > data->icld_LabelLargestWidth) data->icld_LabelLargestWidth = icon->ie_TxtBuf_DisplayedLabelWidth;
934 return (IPTR)icon->ie_TxtBuf_DisplayedLabel;
938 ///IconList__HookFunc_UpdateLabelsFunc()
939 AROS_UFH3(
940 void, IconList__HookFunc_UpdateLabelsFunc,
941 AROS_UFHA(struct Hook *, hook, A0),
942 AROS_UFHA(APTR *, obj, A2),
943 AROS_UFHA(APTR, param, A1)
946 AROS_USERFUNC_INIT
948 /* Get our private data */
949 Class *CLASS = *( Class **)param;
950 struct IconList_DATA *data = INST_DATA(CLASS, obj);
952 #if defined(DEBUG_ILC_LASSO) && defined(DEBUG_ILC_FUNCS)
953 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
954 #endif
956 if (((data->icld__Option_LabelTextMaxLen != data->icld__Option_LastLabelTextMaxLen) &&
957 (data->icld__Option_LabelTextMultiLine > 1)) ||
958 (data->icld__Option_LabelTextMultiLine != data->icld__Option_LastLabelTextMultiLine));
960 struct IconEntry *iconentry_Current = NULL;
961 #if defined(__AROS__)
962 ForeachNode(&data->icld_IconList, iconentry_Current)
963 #else
964 Foreach_Node(&data->icld_IconList, iconentry_Current);
965 #endif
967 IconList__LabelFunc_CreateLabel((Object *)obj, data, iconentry_Current);
971 data->icld__Option_LastLabelTextMaxLen = data->icld__Option_LabelTextMaxLen;
972 data->icld__Option_LastLabelTextMultiLine = data->icld__Option_LabelTextMultiLine;
974 AROS_USERFUNC_EXIT
978 ///IconList__MUIM_IconList_DrawEntryLabel()
979 IPTR IconList__MUIM_IconList_DrawEntryLabel(struct IClass *CLASS, Object *obj, struct MUIP_IconList_DrawEntry *message)
981 struct IconList_DATA *data = INST_DATA(CLASS, obj);
983 STRPTR buf = NULL;
984 BOOL outside = FALSE;
986 struct Rectangle iconlabelrect;
987 struct Rectangle objrect;
989 ULONG txtbox_width = 0;
990 LONG tx,ty,offsetx,offsety;
991 LONG txwidth; // txheight;
993 ULONG objX, objY, objW, objH;
994 LONG labelX, labelY;
995 ULONG labelW, labelH;
997 if (data->icld_BufferRastPort == data->icld_DisplayRastPort)
999 objX = _mleft(obj);
1000 objY = _mtop(obj);
1002 else
1004 objX = objY = 0;
1006 objW = _mright(obj) - _mleft(obj) + 1;
1007 objH = _mbottom(obj) - _mtop(obj) + 1;
1009 ULONG txtarea_width;
1010 ULONG curlabel_TotalLines, curlabel_CurrentLine, offset_y;
1012 #if defined(DEBUG_ILC_ICONRENDERING) && defined(DEBUG_ILC_FUNCS)
1013 D(bug("[IconList]: %s(message->icon = 0x%p), '%s'\n", __PRETTY_FUNCTION__, message->icon, message->icon->ie_IconListEntry.label));
1014 #endif
1016 if ((!(message->icon->ie_Flags & ICONENTRY_FLAG_VISIBLE)) ||
1017 (data->icld_BufferRastPort == NULL) ||
1018 (!(message->icon->ie_DiskObj)))
1020 #if defined(DEBUG_ILC_ICONRENDERING)
1021 D(bug("[IconList] %s: Not visible or missing DOB\n", __PRETTY_FUNCTION__));
1022 #endif
1023 return FALSE;
1026 /* Get the dimensions and affected area of message->icon's label */
1027 IconList_GetIconLabelRectangle(obj, data, message->icon, &iconlabelrect);
1028 labelW = iconlabelrect.MaxX - iconlabelrect.MinX + 1;
1029 labelH = iconlabelrect.MaxY - iconlabelrect.MinY + 1;
1031 /* Add the relative position offset of the message->icon's label */
1032 offsetx = (objX - data->icld_ViewX) + message->icon->ie_IconX;
1033 txtbox_width = (iconlabelrect.MaxX - iconlabelrect.MinX) + 1;
1035 if (txtbox_width < message->icon->ie_AreaWidth)
1036 offsetx += ((message->icon->ie_AreaWidth - txtbox_width)/2);
1038 if ((data->icld__Option_IconListMode == ICON_LISTMODE_GRID) &&
1039 (message->icon->ie_AreaWidth < data->icld_IconAreaLargestWidth))
1040 offsetx += ((data->icld_IconAreaLargestWidth - message->icon->ie_AreaWidth)/2);
1042 iconlabelrect.MinX += offsetx;
1043 iconlabelrect.MaxX += offsetx;
1045 offsety = (objY - data->icld_ViewY) + message->icon->ie_IconY + data->icld__Option_IconImageSpacing;
1046 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
1048 offsety = offsety + data->icld_IconLargestHeight;
1050 else
1052 offsety = offsety + message->icon->ie_IconHeight;
1054 iconlabelrect.MinY += offsety;
1055 iconlabelrect.MaxY += offsety;
1057 /* Add the relative position of the window */
1058 objrect.MinX = objX;
1059 objrect.MinY = objX;
1060 objrect.MaxX = objX + objW;
1061 objrect.MaxY = objY + objH;
1063 if (!RectAndRect(&iconlabelrect, &objrect))
1065 #if defined(DEBUG_ILC_ICONRENDERING)
1066 (bug("[IconList] %s: Icon '%s' label outside of visible area .. skipping\n", __PRETTY_FUNCTION__, message->icon->ie_IconListEntry.label));
1067 #endif
1068 return FALSE;
1071 /* data->update_rect1 and data->update_rect2 may
1072 point to rectangles to indicate that only icons
1073 in any of this rectangles need to be drawn */
1074 if (data->update_rect1)
1076 if (!RectAndRect(&iconlabelrect, data->update_rect1))
1077 outside = TRUE;
1080 if (data->update_rect2)
1082 if (data->update_rect1)
1084 if ((outside == TRUE) && RectAndRect(&iconlabelrect, data->update_rect2))
1085 outside = FALSE;
1087 else
1089 if (!RectAndRect(&iconlabelrect, data->update_rect2))
1090 outside = TRUE;
1094 if (outside == TRUE)
1096 #if defined(DEBUG_ILC_ICONRENDERING)
1097 D(bug("[IconList] %s: Icon '%s' label outside of update area .. skipping\n", __PRETTY_FUNCTION__, message->icon->ie_IconListEntry.label));
1098 #endif
1099 return FALSE;
1102 if (message->drawmode == ICONENTRY_DRAWMODE_NONE)
1103 return TRUE;
1105 SetABPenDrMd(data->icld_BufferRastPort, _pens(obj)[MPEN_TEXT], 0, JAM1);
1107 iconlabelrect.MinX = (iconlabelrect.MinX - objX) + data->icld_DrawOffsetX;
1108 iconlabelrect.MinY = (iconlabelrect.MinY - objY) + data->icld_DrawOffsetY;
1109 iconlabelrect.MaxX = (iconlabelrect.MaxX - objX) + data->icld_DrawOffsetX;
1110 iconlabelrect.MaxY = (iconlabelrect.MaxY - objY) + data->icld_DrawOffsetY;
1112 labelX = iconlabelrect.MinX + data->icld__Option_LabelTextBorderWidth + data->icld__Option_LabelTextHorizontalPadding;
1113 labelY = iconlabelrect.MinY + data->icld__Option_LabelTextBorderHeight + data->icld__Option_LabelTextVerticalPadding;
1115 txtarea_width = txtbox_width - ((data->icld__Option_LabelTextBorderWidth + data->icld__Option_LabelTextHorizontalPadding) * 2);
1117 if ((data->icld_BufferRastPort == data->icld_DisplayRastPort) ||
1118 ((data->icld_BufferRastPort != data->icld_DisplayRastPort) &&
1119 ((iconlabelrect.MinX > objX) && (iconlabelrect.MinX < (objX + objW)) && (iconlabelrect.MinY > objY) && (iconlabelrect.MinY < (objY + objH))) &&
1120 ((iconlabelrect.MaxX > objX) && (iconlabelrect.MaxX < (objX + objW)) && (iconlabelrect.MaxY > objY) && (iconlabelrect.MaxY < (objY + objH)))
1123 #if defined(DEBUG_ILC_ICONRENDERING)
1124 D(bug("[IconList] %s: Drawing Label '%s' .. %d, %d\n", __PRETTY_FUNCTION__, message->icon->ie_IconListEntry.label, labelX, labelY));
1125 #endif
1126 if (message->icon->ie_IconListEntry.label && message->icon->ie_TxtBuf_DisplayedLabel)
1128 char *curlabel_StrPtr;
1130 if ((message->icon->ie_Flags & ICONENTRY_FLAG_FOCUS) && ((BOOL)XGET(_win(obj), MUIA_Window_Activate)))
1132 //Draw the focus box around the selected label ..
1133 if (data->icld__Option_LabelTextBorderHeight > 0)
1135 InvertPixelArray(data->icld_BufferRastPort,
1136 iconlabelrect.MinX, iconlabelrect.MinY,
1137 (iconlabelrect.MaxX - iconlabelrect.MinX) + 1, data->icld__Option_LabelTextBorderHeight);
1139 InvertPixelArray(data->icld_BufferRastPort,
1140 iconlabelrect.MinX, iconlabelrect.MaxY - (data->icld__Option_LabelTextBorderHeight - 1),
1141 (iconlabelrect.MaxX - iconlabelrect.MinX) + 1, data->icld__Option_LabelTextBorderHeight);
1143 if (data->icld__Option_LabelTextBorderWidth > 0)
1145 InvertPixelArray(data->icld_BufferRastPort,
1146 iconlabelrect.MinX, iconlabelrect.MinY + data->icld__Option_LabelTextBorderHeight,
1147 data->icld__Option_LabelTextBorderWidth, (((iconlabelrect.MaxY - iconlabelrect.MinY) + 1) - (data->icld__Option_LabelTextBorderHeight * 2)));
1149 InvertPixelArray(data->icld_BufferRastPort,
1150 iconlabelrect.MaxX - (data->icld__Option_LabelTextBorderWidth - 1), iconlabelrect.MinY + data->icld__Option_LabelTextBorderHeight,
1151 data->icld__Option_LabelTextBorderWidth, (((iconlabelrect.MaxY - iconlabelrect.MinY) + 1) - (data->icld__Option_LabelTextBorderHeight * 2)));
1155 SetFont(data->icld_BufferRastPort, data->icld_IconLabelFont);
1157 curlabel_TotalLines = message->icon->ie_SplitParts;
1158 curlabel_CurrentLine = 0;
1160 if (curlabel_TotalLines == 0)
1161 curlabel_TotalLines = 1;
1163 if (!(data->icld__Option_LabelTextMultiLineOnFocus) || (data->icld__Option_LabelTextMultiLineOnFocus && (message->icon->ie_Flags & ICONENTRY_FLAG_FOCUS)))
1165 if (curlabel_TotalLines > data->icld__Option_LabelTextMultiLine)
1166 curlabel_TotalLines = data->icld__Option_LabelTextMultiLine;
1168 else
1169 curlabel_TotalLines = 1;
1171 curlabel_StrPtr = message->icon->ie_TxtBuf_DisplayedLabel;
1173 ty = labelY - 1;
1175 #if defined(DEBUG_ILC_ICONRENDERING)
1176 D(bug("[IconList] %s: Font YSize %d Baseline %d\n", __PRETTY_FUNCTION__,data->icld_IconLabelFont->tf_YSize, data->icld_IconLabelFont->tf_Baseline));
1177 #endif
1178 for (curlabel_CurrentLine = 0; curlabel_CurrentLine < curlabel_TotalLines; curlabel_CurrentLine++)
1180 ULONG ie_LabelLength;
1182 if (curlabel_CurrentLine > 0) curlabel_StrPtr = curlabel_StrPtr + strlen(curlabel_StrPtr) + 1;
1183 if ((curlabel_CurrentLine >= (curlabel_TotalLines -1)) && (curlabel_TotalLines < message->icon->ie_SplitParts))
1185 char *tmpLine = curlabel_StrPtr;
1186 ULONG tmpLen = strlen(tmpLine);
1188 if ((curlabel_StrPtr = AllocVecPooled(data->icld_Pool, tmpLen + 1)) != NULL)
1190 memset(curlabel_StrPtr, 0, tmpLen + 1);
1191 strncpy(curlabel_StrPtr, tmpLine, tmpLen - 3);
1192 strcat(curlabel_StrPtr , " ..");
1194 else
1195 return FALSE;
1199 ie_LabelLength = strlen(curlabel_StrPtr);
1200 offset_y = 0;
1202 // Center message->icon's label
1203 tx = (labelX + (message->icon->ie_TxtBuf_DisplayedLabelWidth / 2) - (TextLength(data->icld_BufferRastPort, curlabel_StrPtr, strlen(curlabel_StrPtr)) / 2));
1205 if (message->icon->ie_TxtBuf_DisplayedLabelWidth < txtarea_width)
1206 tx += ((txtarea_width - message->icon->ie_TxtBuf_DisplayedLabelWidth)/2);
1208 ty = ty + data->icld_IconLabelFont->tf_YSize;
1210 switch ( data->icld__Option_LabelTextMode )
1212 case ICON_TEXTMODE_DROPSHADOW:
1213 SetAPen(data->icld_BufferRastPort, data->icld_LabelShadowPen);
1214 Move(data->icld_BufferRastPort, tx + 1, ty + 1);
1215 Text(data->icld_BufferRastPort, curlabel_StrPtr, ie_LabelLength);
1216 offset_y = 1;
1217 case ICON_TEXTMODE_PLAIN:
1218 SetAPen(data->icld_BufferRastPort, data->icld_LabelPen);
1219 Move(data->icld_BufferRastPort, tx, ty);
1220 Text(data->icld_BufferRastPort, curlabel_StrPtr, ie_LabelLength);
1221 break;
1223 default:
1224 // Outline mode:
1225 SetSoftStyle(data->icld_BufferRastPort, FSF_BOLD, AskSoftStyle(data->icld_BufferRastPort));
1227 SetAPen(data->icld_BufferRastPort, data->icld_LabelShadowPen);
1228 Move(data->icld_BufferRastPort, tx + 1, ty );
1229 Text(data->icld_BufferRastPort, curlabel_StrPtr, ie_LabelLength);
1230 Move(data->icld_BufferRastPort, tx - 1, ty );
1231 Text(data->icld_BufferRastPort, curlabel_StrPtr, ie_LabelLength);
1232 Move(data->icld_BufferRastPort, tx, ty + 1);
1233 Text(data->icld_BufferRastPort, curlabel_StrPtr, ie_LabelLength);
1234 Move(data->icld_BufferRastPort, tx, ty - 1);
1235 Text(data->icld_BufferRastPort, curlabel_StrPtr, ie_LabelLength);
1237 SetAPen(data->icld_BufferRastPort, data->icld_LabelPen);
1238 Move(data->icld_BufferRastPort, tx , ty );
1239 Text(data->icld_BufferRastPort, curlabel_StrPtr, ie_LabelLength);
1241 SetSoftStyle(data->icld_BufferRastPort, FS_NORMAL, AskSoftStyle(data->icld_BufferRastPort));
1242 offset_y = 2;
1243 break;
1245 if ((curlabel_CurrentLine >= (curlabel_TotalLines -1)) && (curlabel_TotalLines < message->icon->ie_SplitParts))
1247 FreeVecPooled(data->icld_Pool, curlabel_StrPtr);
1249 ty = ty + offset_y;
1252 /*date/size sorting has the date/size appended under the message->icon label*/
1254 if ((message->icon->ie_IconListEntry.type != ST_USERDIR) && ((data->icld_SortFlags & (ICONLIST_SORT_BY_SIZE|ICONLIST_SORT_BY_DATE)) != 0))
1256 buf = NULL;
1257 SetFont(data->icld_BufferRastPort, data->icld_IconInfoFont);
1259 if ((data->icld_SortFlags & ICONLIST_SORT_MASK) == ICONLIST_SORT_BY_SIZE)
1261 buf = message->icon->ie_TxtBuf_SIZE;
1262 txwidth = message->icon->ie_TxtBuf_SIZEWidth;
1264 else if ((data->icld_SortFlags & ICONLIST_SORT_MASK) == ICONLIST_SORT_BY_DATE)
1266 if (message->icon->ie_Flags & ICONENTRY_FLAG_TODAY)
1268 buf = message->icon->ie_TxtBuf_TIME;
1269 txwidth = message->icon->ie_TxtBuf_TIMEWidth;
1271 else
1273 buf = message->icon->ie_TxtBuf_DATE;
1274 txwidth = message->icon->ie_TxtBuf_DATEWidth;
1278 if (buf)
1280 ULONG ie_LabelLength = strlen(buf);
1281 tx = labelX;
1283 if (txwidth < txtarea_width)
1284 tx += ((txtarea_width - txwidth)/2);
1286 ty = labelY + ((data->icld__Option_LabelTextVerticalPadding + data->icld_IconLabelFont->tf_YSize ) * curlabel_TotalLines) + data->icld_IconInfoFont->tf_YSize;
1288 switch ( data->icld__Option_LabelTextMode )
1290 case ICON_TEXTMODE_DROPSHADOW:
1291 SetAPen(data->icld_BufferRastPort, data->icld_InfoShadowPen);
1292 Move(data->icld_BufferRastPort, tx + 1, ty + 1); Text(data->icld_BufferRastPort, buf, ie_LabelLength);
1293 case ICON_TEXTMODE_PLAIN:
1294 SetAPen(data->icld_BufferRastPort, data->icld_InfoPen);
1295 Move(data->icld_BufferRastPort, tx, ty); Text(data->icld_BufferRastPort, buf, ie_LabelLength);
1296 break;
1298 default:
1299 // Outline mode..
1300 SetSoftStyle(data->icld_BufferRastPort, FSF_BOLD, AskSoftStyle(data->icld_BufferRastPort));
1301 SetAPen(data->icld_BufferRastPort, data->icld_InfoShadowPen);
1303 Move(data->icld_BufferRastPort, tx + 1, ty );
1304 Text(data->icld_BufferRastPort, buf, ie_LabelLength);
1305 Move(data->icld_BufferRastPort, tx - 1, ty );
1306 Text(data->icld_BufferRastPort, buf, ie_LabelLength);
1307 Move(data->icld_BufferRastPort, tx, ty - 1 );
1308 Text(data->icld_BufferRastPort, buf, ie_LabelLength);
1309 Move(data->icld_BufferRastPort, tx, ty + 1 );
1310 Text(data->icld_BufferRastPort, buf, ie_LabelLength);
1312 SetAPen(data->icld_BufferRastPort, data->icld_InfoPen);
1314 Move(data->icld_BufferRastPort, tx, ty );
1315 Text(data->icld_BufferRastPort, buf, ie_LabelLength);
1317 SetSoftStyle(data->icld_BufferRastPort, FS_NORMAL, AskSoftStyle(data->icld_BufferRastPort));
1318 break;
1325 return TRUE;
1328 /**************************************************************************
1330 **************************************************************************/
1331 ///IconList__MUIM_IconList_RethinkDimensions()
1332 IPTR IconList__MUIM_IconList_RethinkDimensions(struct IClass *CLASS, Object *obj, struct MUIP_IconList_RethinkDimensions *message)
1334 struct IconList_DATA *data = INST_DATA(CLASS, obj);
1336 struct IconEntry *icon = NULL;
1337 LONG maxx = 0,
1338 maxy = 0;
1339 struct Rectangle icon_rect;
1341 #if defined(DEBUG_ILC_ICONPOSITIONING) && defined(DEBUG_ILC_FUNCS)
1342 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
1343 #endif
1345 if (message->singleicon != NULL)
1347 icon = message->singleicon;
1348 maxx = data->icld_AreaWidth - 1,
1349 maxy = data->icld_AreaHeight - 1;
1350 #if defined(DEBUG_ILC_ICONPOSITIONING)
1351 D(bug("[IconList] %s: SingleIcon - maxx = %d, maxy = %d\n", __PRETTY_FUNCTION__, maxx, maxy));
1352 #endif
1354 else
1355 icon = (struct IconEntry *)GetHead(&data->icld_IconList);
1357 while (icon != NULL)
1359 if (icon->ie_DiskObj &&
1360 (icon->ie_Flags & ICONENTRY_FLAG_VISIBLE) &&
1361 (icon->ie_IconX != NO_ICON_POSITION) &&
1362 (icon->ie_IconY != NO_ICON_POSITION))
1364 IconList_GetIconAreaRectangle(obj, data, icon, &icon_rect);
1366 icon_rect.MaxX += icon->ie_IconX + data->icld__Option_IconHorizontalSpacing;
1367 if ((data->icld__Option_IconListMode == ICON_LISTMODE_GRID) &&
1368 (icon->ie_AreaWidth < data->icld_IconAreaLargestWidth))
1369 icon_rect.MaxX += (data->icld_IconAreaLargestWidth - icon->ie_AreaWidth);
1371 icon_rect.MaxY += icon->ie_IconY + data->icld__Option_IconVerticalSpacing;
1373 if (icon_rect.MaxX > maxx) maxx = icon_rect.MaxX;
1374 if (icon_rect.MaxY > maxy) maxy = icon_rect.MaxY;
1377 if (message->singleicon)
1378 break;
1380 icon = (struct IconEntry *)GetSucc(&icon->ie_IconNode);
1383 /* update our view when max x/y have changed */
1384 if (maxx + 1 != data->icld_AreaWidth)
1386 data->icld_AreaWidth = maxx + 1;
1387 SET(obj, MUIA_IconList_Width, data->icld_AreaWidth);
1389 if (maxy + 1 != data->icld_AreaHeight)
1391 data->icld_AreaHeight = maxy + 1;
1392 SET(obj, MUIA_IconList_Height, data->icld_AreaHeight);
1395 return TRUE;
1398 ///IconList__MUIM_IconList_PositionIcons()
1399 /**************************************************************************
1400 MUIM_PositionIcons - Place icons with NO_ICON_POSITION coords somewhere
1401 **************************************************************************/
1402 IPTR IconList__MUIM_IconList_PositionIcons(struct IClass *CLASS, Object *obj, struct MUIP_IconList_PositionIcons *message)
1404 struct IconList_DATA *data = INST_DATA(CLASS, obj);
1405 struct IconEntry *icon = NULL, *pass_first = NULL;
1407 int left = data->icld__Option_IconHorizontalSpacing;
1408 int top = data->icld__Option_IconVerticalSpacing;
1409 int cur_x = left;
1410 int cur_y = top;
1411 int gridx = 0;
1412 int gridy = 0;
1413 int maxw = 0; // Widest & Talest icon in a column or row.
1414 int maxh = 0;
1416 BOOL next;
1417 struct Rectangle iconrect;
1419 #if defined(DEBUG_ILC_ICONPOSITIONING) && defined(DEBUG_ILC_FUNCS)
1420 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
1421 #endif
1423 // Now go to the actual positioning
1424 icon = (struct IconEntry *)GetHead(&data->icld_IconList);
1425 while (icon != NULL)
1427 next = FALSE;
1428 if ((icon->ie_DiskObj != NULL) && (icon->ie_Flags & ICONENTRY_FLAG_VISIBLE))
1430 next = TRUE;
1431 icon->ie_IconX = cur_x;
1432 icon->ie_IconY = cur_y;
1434 if (icon->ie_Flags & ICONENTRY_FLAG_SELECTED)
1436 if (data->icld_SelectionLastClicked == NULL) data->icld_SelectionLastClicked = icon;
1437 if (data->icld_FocusIcon == NULL) data->icld_FocusIcon = icon;
1440 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
1442 maxw = data->icld_IconAreaLargestWidth + data->icld__Option_IconHorizontalSpacing;
1443 maxh = data->icld_IconLargestHeight + data->icld__Option_IconImageSpacing + data->icld_LabelLargestHeight + data->icld__Option_IconVerticalSpacing;
1444 gridx = maxw;
1445 gridy = maxh;
1447 else
1449 if (!(pass_first)) pass_first = icon;
1451 IconList_GetIconAreaRectangle(obj, data, icon, &iconrect);
1453 if (icon->ie_AreaWidth < maxw)
1454 icon->ie_IconX += ( maxw - icon->ie_AreaWidth ) / 2;
1456 if ((maxw < icon->ie_AreaWidth) || (maxh < icon->ie_AreaHeight))
1458 if (maxw < icon->ie_AreaWidth) maxw = icon->ie_AreaWidth;
1459 if (maxh < icon->ie_AreaHeight) maxh = icon->ie_AreaHeight;
1460 if (pass_first != icon)
1462 icon = pass_first;
1463 cur_x = icon->ie_IconX;
1464 cur_y = icon->ie_IconY;
1465 continue;
1469 if (data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL)
1471 gridx = maxw;
1472 gridy = icon->ie_AreaHeight + data->icld__Option_IconHorizontalSpacing;
1474 else
1476 gridx = icon->ie_AreaWidth + data->icld__Option_IconVerticalSpacing;
1477 gridy = maxh;
1481 if ((icon = (struct IconEntry *)GetSucc(&icon->ie_IconNode)) != NULL)
1483 if (next == TRUE)
1485 if (data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL)
1487 cur_y += gridy;
1489 if ((cur_y >= data->icld_ViewHeight) ||
1490 ((data->icld__Option_IconListMode == ICON_LISTMODE_ROUGH) && ((cur_y + icon->ie_AreaHeight - data->icld__Option_IconBorderOverlap) >= data->icld_ViewHeight)) ||
1491 ((data->icld__Option_IconListMode == ICON_LISTMODE_GRID) && ((cur_y + data->icld_IconAreaLargestHeight - data->icld__Option_IconBorderOverlap) >= data->icld_ViewHeight)))
1493 cur_x += maxw;
1494 cur_y = top;
1495 pass_first = NULL;
1496 maxw = 0;
1499 else
1501 cur_x += gridx;
1503 if ((cur_x >= data->icld_ViewWidth) ||
1504 ((data->icld__Option_IconListMode == ICON_LISTMODE_ROUGH) && ((cur_x + icon->ie_AreaWidth - data->icld__Option_IconBorderOverlap) >= data->icld_ViewWidth)) ||
1505 ((data->icld__Option_IconListMode == ICON_LISTMODE_GRID) && ((cur_x + data->icld_IconAreaLargestWidth - data->icld__Option_IconBorderOverlap) >= data->icld_ViewWidth)))
1507 cur_x = left;
1508 cur_y += maxh;
1509 pass_first = NULL;
1510 maxh = 0;
1512 else if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
1520 DoMethod(obj, MUIM_IconList_RethinkDimensions, NULL);
1521 return (IPTR)NULL;
1525 ///OM_NEW()
1526 /**************************************************************************
1527 OM_NEW
1528 **************************************************************************/
1529 IPTR IconList__OM_NEW(struct IClass *CLASS, Object *obj, struct opSet *message)
1531 struct IconList_DATA *data = NULL;
1532 struct TextFont *icl_WindowFont = NULL;
1533 // struct RastPort *icl_RastPort = NULL;
1535 #if defined(DEBUG_ILC_FUNCS)
1536 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
1537 #endif
1539 icl_WindowFont = (struct TextFont *) GetTagData(MUIA_Font, (IPTR) NULL, message->ops_AttrList);
1541 obj = (Object *)DoSuperNewTags(CLASS, obj, NULL,
1542 MUIA_FillArea, FALSE,
1543 MUIA_Dropable, TRUE,
1544 MUIA_Font, MUIV_Font_Tiny,
1545 TAG_MORE, (IPTR) message->ops_AttrList);
1547 if (!obj) return FALSE;
1549 data = INST_DATA(CLASS, obj);
1551 data->icld_Pool = CreatePool(0,4096,4096);
1552 if (!data->icld_Pool)
1554 CoerceMethod(CLASS,obj,OM_DISPOSE);
1555 return (IPTR)NULL;
1558 #if defined(DEBUG_ILC_FUNCS)
1559 D(bug("[IconList] %s: SELF = 0x%p, muiRenderInfo = 0x%p\n", __PRETTY_FUNCTION__, obj, muiRenderInfo(obj)));
1560 #endif
1561 NewList((struct List*)&data->icld_IconList);
1562 NewList((struct List*)&data->icld_SelectionList);
1563 data->icld_IconLabelFont = icl_WindowFont;
1565 /* Get/Set initial values */
1566 #warning "TODO: TrimVolumeNames should be prefs settable"
1567 data->icld__Option_TrimVolumeNames = TRUE;
1568 #warning "TODO: Adjust overlap by window border width"
1569 data->icld__Option_IconBorderOverlap = 10;
1571 data->icld__Option_IconListMode = (UBYTE)GetTagData(MUIA_IconList_IconListMode, 0, message->ops_AttrList);
1572 data->icld__Option_LabelTextMode = (UBYTE)GetTagData(MUIA_IconList_LabelText_Mode, 0, message->ops_AttrList);
1573 data->icld__Option_LabelTextMaxLen = (ULONG)GetTagData(MUIA_IconList_LabelText_MaxLineLen, ILC_ICONLABEL_MAXLINELEN_DEFAULT, message->ops_AttrList);
1575 if ( data->icld__Option_LabelTextMaxLen < ILC_ICONLABEL_SHORTEST )
1576 data->icld__Option_LabelTextMaxLen = ILC_ICONLABEL_MAXLINELEN_DEFAULT;
1578 data->icld__Option_LastLabelTextMaxLen = data->icld__Option_LabelTextMaxLen;
1580 #if defined(DEBUG_ILC_FUNCS)
1581 D(bug("[IconList] %s: MaxLineLen : %ld\n", __PRETTY_FUNCTION__, data->icld__Option_LabelTextMaxLen));
1582 #endif
1583 data->ehn.ehn_Events = IDCMP_MOUSEBUTTONS | IDCMP_RAWKEY;
1584 data->ehn.ehn_Priority = 0;
1585 data->ehn.ehn_Flags = 0;
1586 data->ehn.ehn_Object = obj;
1587 data->ehn.ehn_Class = CLASS;
1589 data->icld_SortFlags = ICONLIST_SORT_BY_NAME;
1590 data->icld_DisplayFlags = ICONLIST_DISP_SHOWINFO;
1592 __iconlist_UpdateLabels_hook.h_Entry = (HOOKFUNC)IconList__HookFunc_UpdateLabelsFunc;
1594 DoMethod
1596 obj, MUIM_Notify, MUIA_IconList_LabelText_MaxLineLen, MUIV_EveryTime,
1597 (IPTR)obj, 3,
1598 MUIM_CallHook, &__iconlist_UpdateLabels_hook, (IPTR)CLASS
1601 DoMethod
1603 obj, MUIM_Notify, MUIA_IconList_LabelText_MultiLine, MUIV_EveryTime,
1604 (IPTR)obj, 3,
1605 MUIM_CallHook, &__iconlist_UpdateLabels_hook, (IPTR)CLASS
1608 #if defined(DEBUG_ILC_FUNCS)
1609 D(bug("[IconList] obj = %ld\n", obj));
1610 #endif
1611 return (IPTR)obj;
1615 ///OM_DISPOSE()
1616 /**************************************************************************
1617 OM_DISPOSE
1618 **************************************************************************/
1619 IPTR IconList__OM_DISPOSE(struct IClass *CLASS, Object *obj, Msg message)
1621 struct IconList_DATA *data = INST_DATA(CLASS, obj);
1622 struct IconEntry *node = NULL;
1624 #if defined(DEBUG_ILC_FUNCS)
1625 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
1626 #endif
1628 #if defined(__AROS__)
1629 ForeachNode(&data->icld_IconList, node)
1630 #else
1631 Foreach_Node(&data->icld_IconList, node);
1632 #endif
1634 if (node->ie_DiskObj)
1635 FreeDiskObject(node->ie_DiskObj);
1638 if (data->icld_Pool) DeletePool(data->icld_Pool);
1640 DoSuperMethodA(CLASS,obj,message);
1641 return (IPTR)NULL;
1645 ///OM_SET()
1646 /**************************************************************************
1647 OM_SET
1648 **************************************************************************/
1649 IPTR IconList__OM_SET(struct IClass *CLASS, Object *obj, struct opSet *message)
1651 struct IconList_DATA *data = INST_DATA(CLASS, obj);
1652 struct TagItem *tag = NULL,
1653 *tags = NULL;
1655 WORD oldleft = data->icld_ViewX,
1656 oldtop = data->icld_ViewY;
1657 //oldwidth = data->icld_ViewWidth,
1658 //oldheight = data->icld_ViewHeight;
1660 #if defined(DEBUG_ILC_FUNCS) && defined(DEBUG_ILC_ATTRIBS)
1661 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
1662 #endif
1664 /* parse initial taglist */
1665 for (tags = message->ops_AttrList; (tag = NextTagItem((TAGITEM)&tags)); )
1667 switch (tag->ti_Tag)
1669 case MUIA_Virtgroup_Left:
1670 #if defined(DEBUG_ILC_ATTRIBS)
1671 D(bug("[IconList] %s: MUIA_Virtgroup_Left %ld\n", __PRETTY_FUNCTION__, tag->ti_Data));
1672 #endif
1673 if (data->icld_ViewX != tag->ti_Data)
1674 data->icld_ViewX = tag->ti_Data;
1675 break;
1677 case MUIA_Virtgroup_Top:
1678 #if defined(DEBUG_ILC_ATTRIBS)
1679 D(bug("[IconList] %s: MUIA_Virtgroup_Top %ld\n", __PRETTY_FUNCTION__, tag->ti_Data));
1680 #endif
1681 if (data->icld_ViewY != tag->ti_Data)
1682 data->icld_ViewY = tag->ti_Data;
1683 break;
1685 case MUIA_IconList_Rastport:
1686 #if defined(DEBUG_ILC_ATTRIBS)
1687 D(bug("[IconList] %s: MUIA_IconList_Rastport 0x%p\n", __PRETTY_FUNCTION__, tag->ti_Data));
1688 #endif
1689 data->icld_DisplayRastPort = (struct RastPort*)tag->ti_Data;
1690 data->icld_DrawOffsetX = _mleft(obj);
1691 data->icld_DrawOffsetY = _mtop(obj);
1692 if (data->icld_BufferRastPort != NULL)
1694 //Buffer still set!?!?!
1696 SET(obj, MUIA_IconList_BufferRastport, tag->ti_Data);
1697 break;
1699 case MUIA_IconList_BufferRastport:
1700 #if defined(DEBUG_ILC_ATTRIBS)
1701 D(bug("[IconList] %s: MUIA_IconList_BufferRastport 0x%p\n", __PRETTY_FUNCTION__, tag->ti_Data));
1702 #endif
1703 data->icld_BufferRastPort = (struct RastPort*)tag->ti_Data;
1704 break;
1706 case MUIA_Font:
1707 #if defined(DEBUG_ILC_ATTRIBS)
1708 D(bug("[IconList] %s: MUIA_Font 0x%p\n", __PRETTY_FUNCTION__, tag->ti_Data));
1709 #endif
1710 data->icld_IconLabelFont = (struct TextFont*)tag->ti_Data;
1711 break;
1713 case MUIA_IconList_LabelInfoText_Font:
1714 #if defined(DEBUG_ILC_ATTRIBS)
1715 D(bug("[IconList] %s: MUIA_IconList_LabelInfoText_Font 0x%p\n", __PRETTY_FUNCTION__, tag->ti_Data));
1716 #endif
1717 data->icld_IconInfoFont = (struct TextFont*)tag->ti_Data;
1718 break;
1720 case MUIA_IconList_DisplayFlags:
1722 #if defined(DEBUG_ILC_ATTRIBS)
1723 D(bug("[IconList] %s: MUIA_IconList_DisplayFlags %08x\n", __PRETTY_FUNCTION__, tag->ti_Data));
1724 #endif
1725 data->icld_DisplayFlags = (ULONG)tag->ti_Data;
1727 if (data->icld_DisplayFlags & ICONLIST_DISP_BUFFERED)
1729 struct BitMap *tmp_BuffBitMap = NULL;
1730 ULONG tmp_RastDepth;
1732 #if defined(DEBUG_ILC_ATTRIBS) && defined(DEBUG_ILC_ICONRENDERING)
1733 D(bug("[IconList] %s: MUIA_IconList_DisplayFlags & ICONLIST_DISP_BUFFERED\n", __PRETTY_FUNCTION__));
1734 #endif
1735 if ((data->icld_BufferRastPort) && (data->icld_BufferRastPort != data->icld_DisplayRastPort))
1737 //Free up the buffers rastport and bitmap so we can replace them ..
1738 FreeBitMap(data->icld_BufferRastPort->BitMap);
1739 FreeRastPort(data->icld_BufferRastPort);
1740 SET(obj, MUIA_IconList_BufferRastport, NULL);
1742 tmp_RastDepth = GetCyberMapAttr(data->icld_DisplayRastPort->BitMap, CYBRMATTR_DEPTH);
1743 if ((tmp_BuffBitMap = AllocBitMap(data->icld_ViewWidth,
1744 data->icld_ViewHeight,
1745 tmp_RastDepth,
1746 BMF_CLEAR,
1747 data->icld_DisplayRastPort->BitMap))!=NULL)
1749 if ((data->icld_BufferRastPort = CreateRastPort())!=NULL)
1751 data->icld_BufferRastPort->BitMap = tmp_BuffBitMap;
1752 SET(obj, MUIA_IconList_BufferRastport, data->icld_BufferRastPort);
1753 data->icld_DrawOffsetX = 0;
1754 data->icld_DrawOffsetY = 0;
1756 else
1758 FreeBitMap(tmp_BuffBitMap);
1759 data->icld_BufferRastPort = data->icld_DisplayRastPort;
1760 data->icld_DrawOffsetX = _mleft(obj);
1761 data->icld_DrawOffsetY = _mtop(obj);
1765 else
1767 if ((data->icld_BufferRastPort) && (data->icld_BufferRastPort != data->icld_DisplayRastPort))
1769 //Free up the buffers rastport and bitmap since they are no longer needed ..
1770 FreeBitMap(data->icld_BufferRastPort->BitMap);
1771 FreeRastPort(data->icld_BufferRastPort);
1772 data->icld_BufferRastPort = data->icld_DisplayRastPort;
1773 data->icld_DrawOffsetX = _mleft(obj);
1774 data->icld_DrawOffsetY = _mtop(obj);
1777 SET(obj, MUIA_IconList_Changed, TRUE);
1779 break;
1781 case MUIA_IconList_SortFlags:
1782 #if defined(DEBUG_ILC_ATTRIBS)
1783 D(bug("[IconList] %s: MUIA_IconList_SortFlags %08x\n", __PRETTY_FUNCTION__, tag->ti_Data));
1784 #endif
1785 data->icld_SortFlags = (ULONG)tag->ti_Data;
1786 break;
1788 case MUIA_IconList_IconListMode:
1789 #if defined(DEBUG_ILC_ATTRIBS)
1790 D(bug("[IconList] %s: MUIA_IconList_IconListMode %d\n", __PRETTY_FUNCTION__, tag->ti_Data));
1791 #endif
1792 data->icld__Option_IconListMode = (UBYTE)tag->ti_Data;
1793 break;
1795 case MUIA_IconList_LabelText_Mode:
1796 #if defined(DEBUG_ILC_ATTRIBS)
1797 D(bug("[IconList] %s: MUIA_IconList_LabelText_Mode %d\n", __PRETTY_FUNCTION__, tag->ti_Data));
1798 #endif
1799 data->icld__Option_LabelTextMode = (UBYTE)tag->ti_Data;
1800 break;
1802 case MUIA_IconList_LabelText_MaxLineLen:
1803 #if defined(DEBUG_ILC_ATTRIBS)
1804 D(bug("[IconList] %s: MUIA_IconList_LabelText_MaxLineLen %d\n", __PRETTY_FUNCTION__, tag->ti_Data));
1805 #endif
1806 if (tag->ti_Data >= ILC_ICONLABEL_SHORTEST)
1808 data->icld__Option_LabelTextMaxLen = (ULONG)tag->ti_Data;
1810 else
1812 data->icld__Option_LabelTextMaxLen = ILC_ICONLABEL_MAXLINELEN_DEFAULT;
1814 break;
1816 case MUIA_IconList_LabelText_MultiLine:
1817 #if defined(DEBUG_ILC_ATTRIBS)
1818 D(bug("[IconList] %s: MUIA_IconList_LabelText_MultiLine %d\n", __PRETTY_FUNCTION__, tag->ti_Data));
1819 #endif
1820 data->icld__Option_LabelTextMultiLine = (ULONG)tag->ti_Data;
1821 if (data->icld__Option_LabelTextMultiLine == 0)data->icld__Option_LabelTextMultiLine = 1;
1822 break;
1824 case MUIA_IconList_LabelText_MultiLineOnFocus:
1825 #if defined(DEBUG_ILC_ATTRIBS)
1826 D(bug("[IconList] %s: MUIA_IconList_LabelText_MultiLineOnFocus %d\n", __PRETTY_FUNCTION__, tag->ti_Data));
1827 #endif
1828 data->icld__Option_LabelTextMultiLineOnFocus = (BOOL)tag->ti_Data;
1829 break;
1831 case MUIA_IconList_Icon_HorizontalSpacing:
1832 #if defined(DEBUG_ILC_ATTRIBS)
1833 D(bug("[IconList] %s: MUIA_IconList_Icon_HorizontalSpacing %d\n", __PRETTY_FUNCTION__, tag->ti_Data));
1834 #endif
1835 data->icld__Option_IconHorizontalSpacing = (UBYTE)tag->ti_Data;
1836 break;
1838 case MUIA_IconList_Icon_VerticalSpacing:
1839 #if defined(DEBUG_ILC_ATTRIBS)
1840 D(bug("[IconList] %s: MUIA_IconList_Icon_VerticalSpacing %d\n", __PRETTY_FUNCTION__, tag->ti_Data));
1841 #endif
1842 data->icld__Option_IconVerticalSpacing = (UBYTE)tag->ti_Data;
1843 break;
1845 case MUIA_IconList_Icon_ImageSpacing:
1846 #if defined(DEBUG_ILC_ATTRIBS)
1847 D(bug("[IconList] %s: MUIA_IconList_Icon_ImageSpacing %d\n", __PRETTY_FUNCTION__, tag->ti_Data));
1848 #endif
1849 data->icld__Option_IconImageSpacing = (UBYTE)tag->ti_Data;
1850 break;
1852 case MUIA_IconList_LabelText_HorizontalPadding:
1853 #if defined(DEBUG_ILC_ATTRIBS)
1854 D(bug("[IconList] %s: MUIA_IconList_LabelText_HorizontalPadding %d\n", __PRETTY_FUNCTION__, tag->ti_Data));
1855 #endif
1856 data->icld__Option_LabelTextHorizontalPadding = (UBYTE)tag->ti_Data;
1857 break;
1859 case MUIA_IconList_LabelText_VerticalPadding:
1860 #if defined(DEBUG_ILC_ATTRIBS)
1861 D(bug("[IconList] %s: MUIA_IconList_LabelText_VerticalPadding %d\n", __PRETTY_FUNCTION__, tag->ti_Data));
1862 #endif
1863 data->icld__Option_LabelTextVerticalPadding = (UBYTE)tag->ti_Data;
1864 break;
1866 case MUIA_IconList_LabelText_BorderWidth:
1867 #if defined(DEBUG_ILC_ATTRIBS)
1868 D(bug("[IconList] %s: MUIA_IconList_LabelText_BorderWidth %d\n", __PRETTY_FUNCTION__, tag->ti_Data));
1869 #endif
1870 data->icld__Option_LabelTextBorderWidth = (UBYTE)tag->ti_Data;
1871 break;
1873 case MUIA_IconList_LabelText_BorderHeight:
1874 #if defined(DEBUG_ILC_ATTRIBS)
1875 D(bug("[IconList] %s: MUIA_IconList_LabelText_BorderHeight %d\n", __PRETTY_FUNCTION__, tag->ti_Data));
1876 #endif
1877 data->icld__Option_LabelTextBorderHeight = (UBYTE)tag->ti_Data;
1878 break;
1880 case MUIA_IconList_LabelText_Pen:
1881 data->icld_LabelPen = (ULONG)tag->ti_Data;
1882 break;
1884 case MUIA_IconList_LabelText_ShadowPen:
1885 data->icld_LabelShadowPen = (ULONG)tag->ti_Data;
1886 break;
1888 case MUIA_IconList_LabelInfoText_Pen:
1889 data->icld_InfoPen = (ULONG)tag->ti_Data;
1890 break;
1892 case MUIA_IconList_LabelInfoText_ShadowPen:
1893 data->icld_InfoShadowPen = (ULONG)tag->ti_Data;
1894 break;
1896 /* Settings defined by the view class */
1897 case MUIA_IconListview_FixedBackground:
1898 #if defined(DEBUG_ILC_ATTRIBS)
1899 D(bug("[IconList] %s: MUIA_IconListview_FixedBackground\n", __PRETTY_FUNCTION__));
1900 #endif
1901 data->icld__Option_IconListFixedBackground = (BOOL)tag->ti_Data;
1902 break;
1904 case MUIA_IconListview_ScaledBackground:
1905 #if defined(DEBUG_ILC_ATTRIBS)
1906 D(bug("[IconList] %s: MUIA_IconListview_ScaledBackground\n", __PRETTY_FUNCTION__));
1907 #endif
1908 data->icld__Option_IconListScaledBackground = (BOOL)tag->ti_Data;
1909 break;
1911 /* We listen for MUIA_Background and set default values for known types */
1912 case MUIA_Background:
1913 #if defined(DEBUG_ILC_ATTRIBS) && defined(DEBUG_ILC_ICONRENDERING)
1914 D(bug("[IconList] %s: MUIA_Background\n", __PRETTY_FUNCTION__));
1915 #endif
1917 char *bgmode_string = (char *)tag->ti_Data;
1918 BYTE this_mode = bgmode_string[0] - 48;
1920 #if defined(DEBUG_ILC_ATTRIBS) && defined(DEBUG_ILC_ICONRENDERING)
1921 D(bug("[IconList] %s: MUIA_Background | MUI BG Mode = %d\n", __PRETTY_FUNCTION__, this_mode));
1922 #endif
1923 switch (this_mode)
1925 case 0:
1926 //MUI Pattern
1927 NNSET(obj, MUIA_IconListview_FixedBackground, FALSE);
1928 NNSET(obj, MUIA_IconListview_ScaledBackground, FALSE);
1929 break;
1930 case 2:
1931 //MUI RGB color
1932 NNSET(obj, MUIA_IconListview_FixedBackground, FALSE);
1933 NNSET(obj, MUIA_IconListview_ScaledBackground, FALSE);
1934 break;
1935 case 7:
1936 //Zune Gradient
1937 NNSET(obj, MUIA_IconListview_FixedBackground, TRUE);
1938 NNSET(obj, MUIA_IconListview_ScaledBackground, TRUE);
1939 break;
1940 case 5:
1941 //Image
1942 NNSET(obj, MUIA_IconListview_FixedBackground, FALSE);
1943 NNSET(obj, MUIA_IconListview_ScaledBackground, FALSE);
1944 break;
1947 break;
1948 case MUIA_IconList_IconsDropped:
1949 data->icld_DragDropEvent = (struct IconList_Drop_Event *)tag->ti_Data;
1950 break;
1954 #if defined(DEBUG_ILC_ATTRIBS)
1955 D(bug("[IconList] %s(), out of switch\n", __PRETTY_FUNCTION__));
1956 #endif
1957 if ((oldleft != data->icld_ViewX) || (oldtop != data->icld_ViewY))
1959 data->icld_UpdateMode = UPDATE_SCROLL;
1960 data->update_scrolldx = data->icld_ViewX - oldleft;
1961 data->update_scrolldy = data->icld_ViewY - oldtop;
1962 #if defined(DEBUG_ILC_ATTRIBS)
1963 D(bug("[IconList] %s(), call MUI_Redraw()\n", __PRETTY_FUNCTION__));
1964 #endif
1965 MUI_Redraw(obj, MADF_DRAWUPDATE);
1968 #if defined(DEBUG_ILC_ATTRIBS)
1969 D(bug("[IconList] %s(), call DoSuperMethodA()\n", __PRETTY_FUNCTION__));
1970 #endif
1971 return DoSuperMethodA(CLASS, obj, (Msg)message);
1975 ///OM_GET()
1976 /**************************************************************************
1977 OM_GET
1978 **************************************************************************/
1979 IPTR IconList__OM_GET(struct IClass *CLASS, Object *obj, struct opGet *message)
1981 /* small macro to simplify return value storage */
1982 #define STORE *(message->opg_Storage)
1983 struct IconList_DATA *data = INST_DATA(CLASS, obj);
1985 #if defined(DEBUG_ILC_FUNCS) && defined(DEBUG_ILC_ATTRIBS)
1986 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
1987 #endif
1989 switch (message->opg_AttrID)
1991 case MUIA_IconList_Rastport: STORE = (IPTR)data->icld_DisplayRastPort; return 1;
1992 case MUIA_IconList_BufferRastport: STORE = (IPTR)data->icld_BufferRastPort; return 1;
1993 case MUIA_IconList_BufferLeft: STORE = (IPTR)data->icld_DrawOffsetX; return 1;
1994 case MUIA_IconList_BufferTop: STORE = (IPTR)data->icld_DrawOffsetY; return 1;
1995 case MUIA_IconList_BufferWidth:
1996 case MUIA_IconList_Width: STORE = (IPTR)data->icld_AreaWidth; return 1;
1997 case MUIA_IconList_BufferHeight:
1998 case MUIA_IconList_Height: STORE = (IPTR)data->icld_AreaHeight; return 1;
1999 case MUIA_IconList_IconsDropped: STORE = (IPTR)data->icld_DragDropEvent; return 1;
2000 case MUIA_IconList_Clicked: STORE = (IPTR)&data->icld_ClickEvent; return 1;
2001 case MUIA_IconList_IconListMode: STORE = (IPTR)data->icld__Option_IconListMode; return 1;
2002 case MUIA_IconList_LabelText_Mode: STORE = (IPTR)data->icld__Option_LabelTextMode; return 1;
2003 case MUIA_IconList_LabelText_MaxLineLen: STORE = (IPTR)data->icld__Option_LabelTextMaxLen; return 1;
2004 case MUIA_IconList_LabelText_MultiLine: STORE = (IPTR)data->icld__Option_LabelTextMultiLine; return 1;
2005 case MUIA_IconList_LabelText_MultiLineOnFocus: STORE = (IPTR)data->icld__Option_LabelTextMultiLineOnFocus; return 1;
2006 case MUIA_IconList_DisplayFlags: STORE = (IPTR)data->icld_DisplayFlags; return 1;
2007 case MUIA_IconList_SortFlags: STORE = (IPTR)data->icld_SortFlags; return 1;
2009 case MUIA_IconList_FocusIcon: STORE = (IPTR)data->icld_FocusIcon; return 1;
2011 case MUIA_Font: STORE = (IPTR)data->icld_IconLabelFont; return 1;
2012 case MUIA_IconList_LabelText_Pen: STORE = (IPTR)data->icld_LabelPen; return 1;
2013 case MUIA_IconList_LabelText_ShadowPen: STORE = (IPTR)data->icld_LabelShadowPen; return 1;
2014 case MUIA_IconList_LabelInfoText_Font: STORE = (IPTR)data->icld_IconInfoFont; return 1;
2015 case MUIA_IconList_LabelInfoText_Pen: STORE = (IPTR)data->icld_InfoPen; return 1;
2016 case MUIA_IconList_LabelInfoText_ShadowPen: STORE = (IPTR)data->icld_InfoShadowPen; return 1;
2018 case MUIA_IconList_Icon_HorizontalSpacing: STORE = (IPTR)data->icld__Option_IconHorizontalSpacing; return 1;
2019 case MUIA_IconList_Icon_VerticalSpacing: STORE = (IPTR)data->icld__Option_IconVerticalSpacing; return 1;
2020 case MUIA_IconList_Icon_ImageSpacing: STORE = (IPTR)data->icld__Option_IconImageSpacing; return 1;
2021 case MUIA_IconList_LabelText_HorizontalPadding: STORE = (IPTR)data->icld__Option_LabelTextHorizontalPadding; return 1;
2022 case MUIA_IconList_LabelText_VerticalPadding: STORE = (IPTR)data->icld__Option_LabelTextVerticalPadding; return 1;
2023 case MUIA_IconList_LabelText_BorderWidth: STORE = (IPTR)data->icld__Option_LabelTextBorderWidth; return 1;
2024 case MUIA_IconList_LabelText_BorderHeight: STORE = (IPTR)data->icld__Option_LabelTextBorderHeight; return 1;
2026 /* Settings defined by the view class */
2027 case MUIA_IconListview_FixedBackground: STORE = (IPTR)data->icld__Option_IconListFixedBackground; return 1;
2028 case MUIA_IconListview_ScaledBackground: STORE = (IPTR)data->icld__Option_IconListScaledBackground; return 1;
2030 /* ICON obj Changes */
2031 case MUIA_Virtgroup_Left: STORE = (IPTR)data->icld_ViewX; return 1;
2032 case MUIA_Virtgroup_Top: STORE = (IPTR)data->icld_ViewY; return 1;
2033 case MUIA_Family_List: STORE = (IPTR)&(data->icld_IconList); return 1; /* Get our list object */
2035 #warning "TODO: Get the version/revision from our config.."
2036 case MUIA_Version: STORE = (IPTR)1; return 1;
2037 case MUIA_Revision: STORE = (IPTR)7; return 1;
2040 return DoSuperMethodA(CLASS, obj, (Msg) message);
2041 #undef STORE
2045 IPTR IconList__MUIM_Family_AddHead(struct IClass *CLASS, Object *obj, struct MUIP_Family_AddHead *message)
2047 struct IconList_DATA *data = INST_DATA(CLASS, obj);
2048 #if defined(DEBUG_ILC_FUNCS)
2049 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
2050 #endif
2052 if (message->obj)
2054 #warning "TODO: Use the correct _OBJECT() code when we switch to icon.mui"
2055 // AddHead(&(data->icld_IconList), (struct Node *)_OBJECT(message->obj));
2056 AddHead(&(data->icld_IconList), (struct Node *)message->obj);
2057 return TRUE;
2059 else
2060 return FALSE;
2063 IPTR IconList__MUIM_Family_AddTail(struct IClass *CLASS, Object *obj, struct MUIP_Family_AddTail *message)
2065 struct IconList_DATA *data = INST_DATA(CLASS, obj);
2066 #if defined(DEBUG_ILC_FUNCS)
2067 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
2068 #endif
2070 if (message->obj)
2072 #warning "TODO: Use the correct _OBJECT() code when we switch to icon.mui"
2073 // AddTail(&(data->icld_IconList), (struct Node *)_OBJECT(message->obj));
2074 AddTail(&(data->icld_IconList), (struct Node *)message->obj);
2075 return TRUE;
2077 else
2078 return FALSE;
2080 return (IPTR)NULL;
2082 #if !defined(WANDERER_BUILTIN_ICONLIST)
2083 IPTR IconList__OM_ADDMEMBER(struct IClass *CLASS, Object *obj, struct MUIP_Family_AddTail *message)
2085 return IconList__MUIM_Family_AddTail(CLASS, obj, message);
2087 #endif
2089 IPTR IconList__MUIM_Family_Remove(struct IClass *CLASS, Object *obj, struct MUIP_Family_Remove *message)
2091 struct IconList_DATA *data = INST_DATA(CLASS, obj);
2092 #if defined(DEBUG_ILC_FUNCS)
2093 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
2094 #endif
2096 if (message->obj)
2098 #warning "TODO: Use the correct _OBJECT() code when we switch to icon.mui"
2099 // Remove((struct Node *)_OBJECT(message->obj));
2100 Remove((struct Node *)message->obj);
2101 return TRUE;
2103 else
2104 return FALSE;
2106 return (IPTR)NULL;
2108 #if !defined(WANDERER_BUILTIN_ICONLIST)
2109 IPTR IconList__OM_REMMEMBER(struct IClass *CLASS, Object *obj, struct MUIP_Family_Remove *message)
2111 return IconList__MUIM_Family_Remove(CLASS, obj, message);
2113 #endif
2115 ///MUIM_Setup()
2116 /**************************************************************************
2117 MUIM_Setup
2118 **************************************************************************/
2119 IPTR IconList__MUIM_Setup(struct IClass *CLASS, Object *obj, struct MUIP_Setup *message)
2121 struct IconList_DATA *data = INST_DATA(CLASS, obj);
2122 struct IconEntry *node = NULL;
2123 IPTR geticon_error = 0;
2125 #if defined(DEBUG_ILC_FUNCS)
2126 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
2127 #endif
2129 if (!DoSuperMethodA(CLASS, obj, (Msg) message)) return (IPTR)NULL;
2131 DoMethod(_win(obj), MUIM_Window_AddEventHandler, (IPTR)&data->ehn);
2133 /* Get Internal Objects to use if not set .. */
2134 data->icld_DisplayRastPort = NULL;
2135 data->icld_BufferRastPort = NULL;
2137 if (data->icld_IconLabelFont == NULL) data->icld_IconLabelFont = _font(obj);
2138 if (data->icld_IconInfoFont == NULL) data->icld_IconInfoFont = data->icld_IconLabelFont;
2139 #if defined(DEBUG_ILC_ICONRENDERING)
2140 D(bug("[IconList] %s: Use Font @ 0x%p, RastPort @ 0x%p\n", __PRETTY_FUNCTION__, data->icld_IconLabelFont, data->icld_BufferRastPort ));
2141 #endif
2143 /* Set our base options .. */
2144 data->icld_LabelPen = _pens(obj)[MPEN_SHINE];
2145 data->icld_LabelShadowPen = _pens(obj)[MPEN_SHADOW];
2146 data->icld_InfoPen = _pens(obj)[MPEN_SHINE];
2147 data->icld_InfoShadowPen = _pens(obj)[MPEN_SHADOW];
2149 data->icld__Option_LabelTextMultiLine = 1;
2150 data->icld__Option_LastLabelTextMultiLine = data->icld__Option_LabelTextMultiLine;
2152 data->icld__Option_LabelTextMultiLineOnFocus = FALSE;
2154 data->icld__Option_IconHorizontalSpacing = ILC_ICON_HORIZONTALMARGIN_DEFAULT;
2155 data->icld__Option_IconVerticalSpacing = ILC_ICON_VERTICALMARGIN_DEFAULT;
2156 data->icld__Option_IconImageSpacing = ILC_ICONLABEL_IMAGEMARGIN_DEFAULT;
2157 data->icld__Option_LabelTextHorizontalPadding = ILC_ICONLABEL_HORIZONTALTEXTMARGIN_DEFAULT;
2158 data->icld__Option_LabelTextVerticalPadding = ILC_ICONLABEL_VERTICALTEXTMARGIN_DEFAULT;
2159 data->icld__Option_LabelTextBorderWidth = ILC_ICONLABEL_BORDERWIDTH_DEFAULT;
2160 data->icld__Option_LabelTextBorderHeight = ILC_ICONLABEL_BORDERHEIGHT_DEFAULT;
2162 #if defined(__AROS__)
2163 ForeachNode(&data->icld_IconList, node)
2164 #else
2165 Foreach_Node(&data->icld_IconList, node);
2166 #endif
2168 if (!node->ie_DiskObj)
2170 IPTR iconlistScreen = _screen(obj);
2171 #if defined(DEBUG_ILC_ICONRENDERING)
2172 D(bug("[IconList] %s: IconList Screen @ 0x%p)\n", __PRETTY_FUNCTION__, iconlistScreen));
2173 #endif
2174 if (!(node->ie_DiskObj = GetIconTags(node->ie_IconNode.ln_Name,
2175 (iconlistScreen) ? ICONGETA_Screen : TAG_IGNORE, iconlistScreen,
2176 (iconlistScreen) ? ICONGETA_RemapIcon : TAG_IGNORE, TRUE,
2177 ICONGETA_GenerateImageMasks, TRUE,
2178 ICONGETA_FailIfUnavailable, FALSE,
2179 ICONA_ErrorCode, &geticon_error,
2180 TAG_DONE)))
2182 #if defined(DEBUG_ILC_ICONRENDERING)
2183 D(bug("[IconList] %s: Failed to obtain Icon '%s's diskobj! (error code = 0x%p)\n", __PRETTY_FUNCTION__, node->ie_IconNode.ln_Name, geticon_error));
2184 #endif
2185 /* We should probably remove this node if the icon cant be obtained ? */
2189 return 1;
2193 ///MUIM_Show()
2194 /**************************************************************************
2195 MUIM_Show
2196 **************************************************************************/
2197 IPTR IconList__MUIM_Show(struct IClass *CLASS, Object *obj, struct MUIP_Show *message)
2199 struct IconList_DATA *data = INST_DATA(CLASS, obj);
2200 LONG newleft,
2201 newtop;
2202 IPTR rc;
2204 #if defined(DEBUG_ILC_FUNCS)
2205 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
2206 #endif
2208 if ((rc = DoSuperMethodA(CLASS, obj, (Msg)message)))
2210 newleft = data->icld_ViewX;
2211 newtop = data->icld_ViewY;
2213 if (newleft + _mwidth(obj) > data->icld_AreaWidth)
2214 newleft = data->icld_AreaWidth - _mwidth(obj);
2215 if (newleft < 0)
2216 newleft = 0;
2218 if (newtop + _mheight(obj) > data->icld_AreaHeight)
2219 newtop = data->icld_AreaHeight - _mheight(obj);
2220 if (newtop < 0)
2221 newtop = 0;
2223 if ((newleft != data->icld_ViewX) || (newtop != data->icld_ViewY))
2225 SetAttrs(obj, MUIA_Virtgroup_Left, newleft,
2226 MUIA_Virtgroup_Top, newtop,
2227 TAG_DONE);
2230 /* Get Internal Objects to use if not set .. */
2231 if (data->icld_DisplayRastPort == NULL)
2233 if (_rp(obj) != NULL)
2235 data->icld_DisplayRastPort = CloneRastPort(_rp(obj));
2237 #if defined(DEBUG_ILC_ICONRENDERING)
2238 else
2240 D(bug("[IconList] IconList__MUIM_Show: ERROR - NULL RastPort!\n"));
2242 #endif
2245 if (data->icld_DisplayFlags & ICONLIST_DISP_BUFFERED)
2247 struct BitMap *tmp_BuffBitMap = NULL;
2248 ULONG tmp_RastDepth = GetCyberMapAttr(data->icld_DisplayRastPort->BitMap, CYBRMATTR_DEPTH);
2249 if ((tmp_BuffBitMap = AllocBitMap(data->icld_ViewWidth,
2250 data->icld_ViewHeight,
2251 tmp_RastDepth,
2252 BMF_CLEAR,
2253 data->icld_DisplayRastPort->BitMap))!=NULL)
2255 if ((data->icld_BufferRastPort = CreateRastPort())!=NULL)
2257 data->icld_BufferRastPort->BitMap = tmp_BuffBitMap;
2258 data->icld_DrawOffsetX = 0;
2259 data->icld_DrawOffsetY = 0;
2261 else
2263 FreeBitMap(tmp_BuffBitMap);
2264 data->icld_BufferRastPort = data->icld_DisplayRastPort;
2265 data->icld_DrawOffsetX = _mleft(obj);
2266 data->icld_DrawOffsetY = _mtop(obj);
2270 else
2272 data->icld_BufferRastPort = data->icld_DisplayRastPort;
2273 data->icld_DrawOffsetX = _mleft(obj);
2274 data->icld_DrawOffsetY = _mtop(obj);
2276 if (data->icld_IconLabelFont == NULL) data->icld_IconLabelFont = _font(obj);
2277 if (data->icld_IconInfoFont == NULL) data->icld_IconInfoFont = data->icld_IconLabelFont;
2278 #if defined(DEBUG_ILC_ICONRENDERING)
2279 D(bug("[IconList] IconList__MUIM_Show: Use Font @ 0x%p, RastPort @ 0x%p\n", data->icld_IconLabelFont, data->icld_BufferRastPort ));
2280 #endif
2282 if ((data->icld_BufferRastPort) && (data->icld_IconLabelFont))
2283 SetFont(data->icld_BufferRastPort, data->icld_IconLabelFont);
2285 return rc;
2289 ///MUIM_Hide()
2290 /**************************************************************************
2291 MUIM_Hide
2292 **************************************************************************/
2293 IPTR IconList__MUIM_Hide(struct IClass *CLASS, Object *obj, struct MUIP_Hide *message)
2295 struct IconList_DATA *data = INST_DATA(CLASS, obj);
2296 IPTR rc;
2298 #if defined(DEBUG_ILC_FUNCS)
2299 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
2300 #endif
2302 if ((rc = DoSuperMethodA(CLASS, obj, (Msg)message)))
2304 if ((data->icld_BufferRastPort) && (data->icld_BufferRastPort != data->icld_DisplayRastPort))
2306 FreeBitMap(data->icld_BufferRastPort->BitMap);
2307 FreeRastPort(data->icld_BufferRastPort);
2310 data->icld_BufferRastPort = NULL;
2312 if (data->icld_DisplayRastPort)
2313 FreeRastPort(data->icld_DisplayRastPort);
2315 data->icld_DisplayRastPort = NULL;
2317 return rc;
2321 ///MUIM_Cleanup()
2322 /**************************************************************************
2323 MUIM_Cleanup
2324 **************************************************************************/
2325 IPTR IconList__MUIM_Cleanup(struct IClass *CLASS, Object *obj, struct MUIP_Cleanup *message)
2327 struct IconList_DATA *data = INST_DATA(CLASS, obj);
2328 struct IconEntry *node = NULL;
2330 #if defined(DEBUG_ILC_FUNCS)
2331 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
2332 #endif
2334 #if defined(__AROS__)
2335 ForeachNode(&data->icld_IconList, node)
2336 #else
2337 Foreach_Node(&data->icld_IconList, node);
2338 #endif
2340 if (node->ie_DiskObj)
2342 FreeDiskObject(node->ie_DiskObj);
2343 node->ie_DiskObj = NULL;
2347 DoMethod(_win(obj), MUIM_Window_RemEventHandler, (IPTR)&data->ehn);
2349 return DoSuperMethodA(CLASS, obj, (Msg)message);
2353 ///MUIM_AskMinMax()
2354 /**************************************************************************
2355 MUIM_AskMinMax
2356 **************************************************************************/
2357 IPTR IconList__MUIM_AskMinMax(struct IClass *CLASS, Object *obj, struct MUIP_AskMinMax *message)
2359 ULONG rc = DoSuperMethodA(CLASS, obj, (Msg) message);
2361 #if defined(DEBUG_ILC_FUNCS)
2362 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
2363 #endif
2365 message->MinMaxInfo->MinWidth += 96;
2366 message->MinMaxInfo->MinHeight += 64;
2368 message->MinMaxInfo->DefWidth += 200;
2369 message->MinMaxInfo->DefHeight += 180;
2371 message->MinMaxInfo->MaxWidth = MUI_MAXMAX;
2372 message->MinMaxInfo->MaxHeight = MUI_MAXMAX;
2374 return rc;
2378 ///MUIM_Layout()
2379 /**************************************************************************
2380 MUIM_Layout
2381 **************************************************************************/
2382 IPTR IconList__MUIM_Layout(struct IClass *CLASS, Object *obj,struct MUIP_Layout *message)
2384 struct IconList_DATA *data = INST_DATA(CLASS, obj);
2385 ULONG rc;
2387 #if defined(DEBUG_ILC_FUNCS)
2388 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
2389 #endif
2391 rc = DoSuperMethodA(CLASS, obj, (Msg)message);
2393 data->icld_ViewWidth = _mwidth(obj);
2394 data->icld_ViewHeight = _mheight(obj);
2396 return rc;
2400 ///MUIM_Draw()
2401 /**************************************************************************
2402 MUIM_Draw - draw the IconList
2403 **************************************************************************/
2404 IPTR DrawCount;
2405 IPTR IconList__MUIM_Draw(struct IClass *CLASS, Object *obj, struct MUIP_Draw *message)
2407 struct IconList_DATA *data = INST_DATA(CLASS, obj);
2408 struct IconEntry *icon = NULL;
2410 APTR clip;
2412 ULONG update_oldwidth = 0,
2413 update_oldheight = 0;
2415 LONG clear_xoffset = 0,
2416 clear_yoffset = 0;
2418 IPTR draw_id = DrawCount++;
2420 #if defined(DEBUG_ILC_FUNCS)
2421 D(bug("[IconList]: %s(obj @ 0x%p)\n", __PRETTY_FUNCTION__, obj));
2422 #endif
2423 #if defined(DEBUG_ILC_ICONRENDERING)
2424 D(bug("[IconList] %s: id %d\n", __PRETTY_FUNCTION__, draw_id));
2425 #endif
2427 DoSuperMethodA(CLASS, obj, (Msg)message);
2429 if (!(data->icld__Option_IconListFixedBackground))
2431 clear_xoffset = data->icld_ViewX;
2432 clear_yoffset = data->icld_ViewY;
2435 // If window size changes, only update needed areas
2436 if (data->update_oldwidth == 0) data->update_oldwidth = data->icld_ViewWidth;
2437 if (data->update_oldheight == 0) data->update_oldheight = data->icld_ViewHeight;
2438 if ((data->update_oldwidth != data->icld_ViewWidth) || (data->update_oldheight != data->icld_ViewHeight))
2440 if (data->icld_UpdateMode != UPDATE_SCROLL)
2442 data->icld_UpdateMode = UPDATE_RESIZE;
2443 update_oldwidth = data->update_oldwidth;
2444 update_oldheight = data->update_oldheight;
2445 data->update_oldwidth = data->icld_ViewWidth;
2446 data->update_oldheight = data->icld_ViewHeight;
2450 if ((message->flags & MADF_DRAWUPDATE) || (data->icld_UpdateMode == UPDATE_RESIZE))
2452 #if defined(DEBUG_ILC_ICONRENDERING)
2454 if (message->flags & MADF_DRAWUPDATE)
2456 bug("[IconList] %s#%d: MADF_DRAWUPDATE\n", __PRETTY_FUNCTION__, draw_id);
2458 else
2460 bug("[IconList] %s#%d: UPDATE_RESIZE\n", __PRETTY_FUNCTION__, draw_id);
2463 #endif
2464 if ((data->icld_UpdateMode == UPDATE_SINGLEICON) && (data->update_icon != NULL)) /* draw only a single icon at update_icon */
2466 struct Rectangle rect;
2468 #if defined(DEBUG_ILC_ICONRENDERING)
2469 D(bug("[IconList] %s#%d: UPDATE_SINGLEICON (icon @ 0x%p)\n", __PRETTY_FUNCTION__, draw_id, data->update_icon));
2470 #endif
2472 IconList_GetIconAreaRectangle(obj, data, data->update_icon, &rect);
2474 rect.MinX += _mleft(obj) + (data->update_icon->ie_IconX - data->icld_ViewX);
2475 rect.MaxX += _mleft(obj) + (data->update_icon->ie_IconX - data->icld_ViewX);
2476 rect.MinY += _mtop(obj) + (data->update_icon->ie_IconY - data->icld_ViewY);
2477 rect.MaxY += _mtop(obj) + (data->update_icon->ie_IconY - data->icld_ViewY);
2479 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
2481 if (data->update_icon->ie_AreaWidth < data->icld_IconAreaLargestWidth)
2483 rect.MinX += ((data->icld_IconAreaLargestWidth - data->update_icon->ie_AreaWidth)/2);
2484 rect.MaxX += ((data->icld_IconAreaLargestWidth - data->update_icon->ie_AreaWidth)/2);
2487 if (data->update_icon->ie_AreaHeight < data->icld_IconAreaLargestHeight)
2489 rect.MinY += ((data->icld_IconAreaLargestHeight - data->update_icon->ie_AreaHeight)/2);
2490 rect.MaxY += ((data->icld_IconAreaLargestHeight - data->update_icon->ie_AreaHeight)/2);
2494 clip = MUI_AddClipping(muiRenderInfo(obj), _mleft(obj), _mtop(obj), _mwidth(obj), _mheight(obj));
2496 #if defined(DEBUG_ILC_ICONRENDERING)
2497 D(bug("[IconList] %s#%d: UPDATE_SINGLEICON: Calling MUIM_DrawBackground (A)\n", __PRETTY_FUNCTION__, draw_id));
2498 #endif
2499 DoMethod(obj, MUIM_DrawBackground,
2500 rect.MinX, rect.MinY,
2501 rect.MaxX - rect.MinX + 1, rect.MaxY - rect.MinY + 1,
2502 clear_xoffset, clear_yoffset,
2505 /* We could have deleted also other icons so they must be redrawn */
2506 #if defined(__AROS__)
2507 ForeachNode(&data->icld_IconList, icon)
2508 #else
2509 Foreach_Node(&data->icld_IconList, icon);
2510 #endif
2512 if ((icon != data->update_icon) && (icon->ie_Flags & ICONENTRY_FLAG_VISIBLE))
2514 struct Rectangle rect2;
2515 IconList_GetIconAreaRectangle(obj, data, icon, &rect2);
2517 rect2.MinX += _mleft(obj) - data->icld_ViewX + icon->ie_IconX;
2518 rect2.MaxX += _mleft(obj) - data->icld_ViewX + icon->ie_IconX;
2519 rect2.MinY += _mtop(obj) - data->icld_ViewY + icon->ie_IconY;
2520 rect2.MaxY += _mtop(obj) - data->icld_ViewY + icon->ie_IconY;
2522 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
2524 if (icon->ie_AreaWidth < data->icld_IconAreaLargestWidth)
2526 rect2.MinX += ((data->icld_IconAreaLargestWidth - icon->ie_AreaWidth)/2);
2527 rect2.MaxX += ((data->icld_IconAreaLargestWidth - icon->ie_AreaWidth)/2);
2530 if (icon->ie_AreaHeight < data->icld_IconAreaLargestHeight)
2532 rect2.MinY += ((data->icld_IconAreaLargestHeight - icon->ie_AreaHeight)/2);
2533 rect2.MaxY += ((data->icld_IconAreaLargestHeight - icon->ie_AreaHeight)/2);
2537 if (RectAndRect(&rect, &rect2))
2539 // Update icon here
2540 icon->ie_Flags |= ICONENTRY_FLAG_NEEDSUPDATE;
2541 DoMethod(obj, MUIM_IconList_DrawEntry, icon, ICONENTRY_DRAWMODE_PLAIN);
2542 DoMethod(obj, MUIM_IconList_DrawEntryLabel, icon, ICONENTRY_DRAWMODE_PLAIN);
2543 icon->ie_Flags &= ~ICONENTRY_FLAG_NEEDSUPDATE;
2548 icon->ie_Flags |= ICONENTRY_FLAG_NEEDSUPDATE;
2549 DoMethod(obj, MUIM_IconList_DrawEntry, data->update_icon, ICONENTRY_DRAWMODE_PLAIN);
2550 DoMethod(obj, MUIM_IconList_DrawEntryLabel, data->update_icon, ICONENTRY_DRAWMODE_PLAIN);
2551 icon->ie_Flags &= ~ICONENTRY_FLAG_NEEDSUPDATE;
2552 data->icld_UpdateMode = 0;
2553 data->update_icon = NULL;
2555 if (data->icld_DisplayRastPort != data->icld_BufferRastPort)
2557 #if defined(DEBUG_ILC_ICONRENDERING)
2558 D(bug("[IconList] %s#%d: UPDATE_SINGLEICON Blitting to front rastport..\n", __PRETTY_FUNCTION__, draw_id));
2559 #endif
2560 BltBitMapRastPort(data->icld_BufferRastPort->BitMap,
2561 rect.MinX - _mleft(obj), rect.MinY - _mtop(obj),
2562 data->icld_DisplayRastPort,
2563 rect.MinX, rect.MinY,
2564 rect.MaxX - rect.MinX + 1, rect.MaxY - rect.MinY + 1,
2565 0xC0);
2568 MUI_RemoveClipping(muiRenderInfo(obj),clip);
2569 goto draw_done;
2571 else if (data->icld_UpdateMode == UPDATE_SCROLL)
2573 struct Region *region = NULL;
2574 struct Rectangle xrect,
2575 yrect;
2576 BOOL scroll_caused_damage;
2578 #if defined(DEBUG_ILC_ICONRENDERING)
2579 D(bug("[IconList] %s#%d: UPDATE_SCROLL.\n", __PRETTY_FUNCTION__, draw_id));
2580 #endif
2582 if (!data->icld__Option_IconListFixedBackground)
2584 scroll_caused_damage = (_rp(obj)->Layer->Flags & LAYERREFRESH) ? FALSE : TRUE;
2586 data->icld_UpdateMode = 0;
2588 if ((abs(data->update_scrolldx) >= _mwidth(obj)) ||
2589 (abs(data->update_scrolldy) >= _mheight(obj)))
2591 #if defined(DEBUG_ILC_ICONRENDERING)
2592 D(bug("[IconList] %s#%d: UPDATE_SCROLL: Moved outside current view -> Causing Redraw .. MADF_DRAWOBJECT\n", __PRETTY_FUNCTION__, draw_id));
2593 #endif
2594 MUI_Redraw(obj, MADF_DRAWOBJECT);
2595 goto draw_done;
2598 if (!(region = NewRegion()))
2600 #if defined(DEBUG_ILC_ICONRENDERING)
2601 D(bug("[IconList] %s#%d: UPDATE_SCROLL: Couldnt Alloc Region -> Causing Redraw ...MADF_DRAWOBJECT\n", __PRETTY_FUNCTION__, draw_id));
2602 #endif
2603 MUI_Redraw(obj, MADF_DRAWOBJECT);
2604 goto draw_done;
2607 if (data->update_scrolldx > 0)
2609 xrect.MinX = _mright(obj) - data->update_scrolldx;
2610 xrect.MinY = _mtop(obj);
2611 xrect.MaxX = _mright(obj);
2612 xrect.MaxY = _mbottom(obj);
2614 OrRectRegion(region, &xrect);
2616 data->update_rect1 = &xrect;
2618 else if (data->update_scrolldx < 0)
2620 xrect.MinX = _mleft(obj);
2621 xrect.MinY = _mtop(obj);
2622 xrect.MaxX = _mleft(obj) - data->update_scrolldx;
2623 xrect.MaxY = _mbottom(obj);
2625 OrRectRegion(region, &xrect);
2627 data->update_rect1 = &xrect;
2630 if (data->update_scrolldy > 0)
2632 yrect.MinX = _mleft(obj);
2633 yrect.MinY = _mbottom(obj) - data->update_scrolldy;
2634 yrect.MaxX = _mright(obj);
2635 yrect.MaxY = _mbottom(obj);
2637 OrRectRegion(region, &yrect);
2639 data->update_rect2 = &yrect;
2641 else if (data->update_scrolldy < 0)
2643 yrect.MinX = _mleft(obj);
2644 yrect.MinY = _mtop(obj);
2645 yrect.MaxX = _mright(obj);
2646 yrect.MaxY = _mtop(obj) - data->update_scrolldy;
2648 OrRectRegion(region, &yrect);
2650 data->update_rect2 = &yrect;
2653 #if defined(DEBUG_ILC_ICONRENDERING)
2654 D(bug("[IconList] %s#%d: UPDATE_SCROLL: Scrolling Raster..\n", __PRETTY_FUNCTION__, draw_id));
2655 #endif
2656 if (data->icld_DisplayRastPort == data->icld_BufferRastPort)
2658 ScrollRasterBF(data->icld_BufferRastPort,
2659 data->update_scrolldx,
2660 data->update_scrolldy,
2661 _mleft(obj),
2662 _mtop(obj),
2663 _mright(obj),
2664 _mbottom(obj));
2666 else
2668 ScrollRasterBF(data->icld_BufferRastPort,
2669 data->update_scrolldx,
2670 data->update_scrolldy,
2673 _mwidth(obj),
2674 _mheight(obj));
2677 scroll_caused_damage = scroll_caused_damage && (_rp(obj)->Layer->Flags & LAYERREFRESH) ? TRUE : FALSE;
2679 clip = MUI_AddClipRegion(muiRenderInfo(obj), region);
2682 #if defined(DEBUG_ILC_ICONRENDERING)
2683 D(bug("[IconList] %s#%d: UPDATE_SCROLL: Causing Redraw -> MADF_DRAWOBJECT..\n", __PRETTY_FUNCTION__, draw_id));
2684 #endif
2685 MUI_Redraw(obj, MADF_DRAWOBJECT);
2687 data->update_rect1 = data->update_rect2 = NULL;
2689 if (!data->icld__Option_IconListFixedBackground)
2691 MUI_RemoveClipRegion(muiRenderInfo(obj), clip);
2693 if (scroll_caused_damage)
2695 if (MUI_BeginRefresh(muiRenderInfo(obj), 0))
2697 /* Theoretically it might happen that more damage is caused
2698 after ScrollRaster. By something else, like window movement
2699 in front of our window. Therefore refresh root object of
2700 window, not just this object */
2702 Object *o = NULL;
2704 GET(_win(obj),MUIA_Window_RootObject, &o);
2705 MUI_Redraw(o, MADF_DRAWOBJECT);
2706 #if defined(DEBUG_ILC_ICONRENDERING)
2707 D(bug("[IconList] %s#%d: UPDATE_SCROLL: Causing Redraw -> MADF_DRAWOBJECT..\n", __PRETTY_FUNCTION__, draw_id));
2708 #endif
2709 MUI_EndRefresh(muiRenderInfo(obj), 0);
2713 if (data->icld_DisplayRastPort != data->icld_BufferRastPort)
2715 #if defined(DEBUG_ILC_ICONRENDERING)
2716 D(bug("[IconList] %s#%d: UPDATE_SCROLL: Blitting to front rastport..\n", __PRETTY_FUNCTION__, draw_id));
2717 #endif
2718 BltBitMapRastPort(data->icld_BufferRastPort->BitMap,
2719 0, 0,
2720 data->icld_DisplayRastPort,
2721 _mleft(obj), _mtop(obj),
2722 _mwidth(obj), _mheight(obj),
2723 0xC0);
2725 goto draw_done;
2727 else if (data->icld_UpdateMode == UPDATE_RESIZE)
2729 struct Region *region = NULL;
2730 struct Rectangle wrect,
2731 hrect;
2732 ULONG diffw = 0,
2733 diffh = 0;
2735 #if defined(DEBUG_ILC_ICONRENDERING)
2736 D(bug("[IconList] %s#%d: UPDATE_RESIZE.\n", __PRETTY_FUNCTION__, draw_id));
2737 #endif
2739 if ((data->icld_BufferRastPort) && (data->icld_BufferRastPort != data->icld_DisplayRastPort))
2741 //Free up the buffers rastport and bitmap so we can replace them ..
2742 struct Bitmap *bitmap_Old = (struct Bitmap *)data->icld_BufferRastPort->BitMap;
2743 struct Bitmap *bitmap_New;
2745 ULONG tmp_RastDepth;
2747 data->icld_BufferRastPort->BitMap = NULL;
2749 FreeRastPort(data->icld_BufferRastPort);
2750 SET(obj, MUIA_IconList_BufferRastport, NULL);
2752 tmp_RastDepth = GetCyberMapAttr(data->icld_DisplayRastPort->BitMap, CYBRMATTR_DEPTH);
2753 if ((bitmap_New = (struct Bitmap *)AllocBitMap(data->icld_ViewWidth,
2754 data->icld_ViewHeight,
2755 tmp_RastDepth,
2756 BMF_CLEAR,
2757 data->icld_DisplayRastPort->BitMap))!=NULL)
2759 if ((data->icld_BufferRastPort = CreateRastPort())!=NULL)
2761 data->icld_BufferRastPort->BitMap = (struct BitMap *)bitmap_New;
2762 SET(obj, MUIA_IconList_BufferRastport, data->icld_BufferRastPort);
2763 data->icld_DrawOffsetX = 0;
2764 data->icld_DrawOffsetY = 0;
2766 else
2768 FreeBitMap((struct BitMap *)bitmap_New);
2769 data->icld_BufferRastPort = data->icld_DisplayRastPort;
2770 data->icld_DrawOffsetX = _mleft(obj);
2771 data->icld_DrawOffsetY = _mtop(obj);
2775 if (bitmap_Old != (struct Bitmap *)data->icld_BufferRastPort->BitMap)
2776 FreeBitMap((struct BitMap *)bitmap_Old);
2779 data->icld_UpdateMode = 0;
2781 if (!data->icld__Option_IconListScaledBackground)
2783 if (!(region = NewRegion()))
2785 #if defined(DEBUG_ILC_ICONRENDERING)
2786 D(bug("[IconList] %s#%d: UPDATE_RESIZE: Causing Redraw -> MADF_DRAWOBJECT..\n", __PRETTY_FUNCTION__, draw_id));
2787 #endif
2788 MUI_Redraw(obj, MADF_DRAWOBJECT);
2789 goto draw_done;
2792 if ( data->icld_ViewWidth > update_oldwidth )
2793 diffw = data->icld_ViewWidth - update_oldwidth;
2794 if ( data->icld_ViewHeight > update_oldheight )
2795 diffh = data->icld_ViewHeight - update_oldheight;
2797 if (diffw)
2799 wrect.MinX = _mright(obj) - diffw;
2800 wrect.MinY = _mtop(obj);
2801 wrect.MaxX = _mright(obj);
2802 wrect.MaxY = _mbottom(obj);
2803 OrRectRegion(region, &wrect);
2804 data->update_rect1 = &wrect;
2807 if (diffh)
2809 hrect.MinX = _mleft(obj);
2810 hrect.MinY = _mbottom(obj) - diffh;
2811 hrect.MaxX = _mright(obj);
2812 hrect.MaxX = _mright(obj);
2813 hrect.MaxY = _mbottom(obj);
2814 OrRectRegion(region, &hrect);
2815 data->update_rect2 = &hrect;
2817 if (diffh||diffw)
2819 clip = MUI_AddClipRegion(muiRenderInfo(obj), region);
2821 else
2823 /* View became smaller both in horizontal and vertical direction.
2824 Nothing to do */
2826 DisposeRegion(region);
2827 goto draw_done;
2831 #if defined(DEBUG_ILC_ICONRENDERING)
2832 D(bug("[IconList] %s#%d: UPDATE_RESIZE: Causing Redraw -> MADF_DRAWOBJECT..\n", __PRETTY_FUNCTION__, draw_id));
2833 #endif
2834 MUI_Redraw(obj, MADF_DRAWOBJECT);
2836 if (!data->icld__Option_IconListScaledBackground)
2838 if (diffh||diffw)
2840 data->update_rect1 = data->update_rect2 = NULL;
2841 MUI_RemoveClipRegion(muiRenderInfo(obj), clip);
2842 } else DisposeRegion(region);
2845 goto draw_done;
2849 if (message->flags & MADF_DRAWOBJECT)
2851 struct Rectangle viewrect;
2853 #if defined(DEBUG_ILC_ICONRENDERING)
2854 D(bug("[IconList] %s#%d: MADF_DRAWOBJECT\n", __PRETTY_FUNCTION__, draw_id));
2855 #endif
2857 clip = MUI_AddClipping(muiRenderInfo(obj), _mleft(obj), _mtop(obj), _mwidth(obj), _mheight(obj));
2859 viewrect.MinX = _mleft(obj);
2860 viewrect.MaxX = _mleft(obj) + _mwidth(obj);
2861 viewrect.MinY = _mtop(obj);
2862 viewrect.MaxY = _mtop(obj) + _mheight(obj);
2864 #if defined(DEBUG_ILC_ICONRENDERING)
2865 D(bug("[IconList] %s#%d: MADF_DRAWOBJECT: Calling MUIM_DrawBackground (B)\n", __PRETTY_FUNCTION__, draw_id));
2866 #endif
2867 DoMethod(
2868 obj, MUIM_DrawBackground, _mleft(obj), _mtop(obj), _mwidth(obj), _mheight(obj),
2869 clear_xoffset, clear_yoffset, 0
2871 #if defined(__AROS__)
2872 ForeachNode(&data->icld_IconList, icon)
2873 #else
2874 Foreach_Node(&data->icld_IconList, icon);
2875 #endif
2877 if ((icon->ie_Flags & ICONENTRY_FLAG_VISIBLE) &&
2878 (icon->ie_DiskObj) &&
2879 (icon->ie_IconX != NO_ICON_POSITION) &&
2880 (icon->ie_IconY != NO_ICON_POSITION))
2882 struct Rectangle iconrect;
2883 IconList_GetIconAreaRectangle(obj, data, icon, &iconrect);
2885 iconrect.MinX += _mleft(obj) - data->icld_ViewX + icon->ie_IconX;
2886 iconrect.MaxX += _mleft(obj) - data->icld_ViewX + icon->ie_IconX;
2887 iconrect.MinY += _mtop(obj) - data->icld_ViewY + icon->ie_IconY;
2888 iconrect.MaxY += _mtop(obj) - data->icld_ViewY + icon->ie_IconY;
2890 if (RectAndRect(&viewrect, &iconrect))
2892 DoMethod(obj, MUIM_IconList_DrawEntry, icon, ICONENTRY_DRAWMODE_PLAIN);
2893 DoMethod(obj, MUIM_IconList_DrawEntryLabel, icon, ICONENTRY_DRAWMODE_PLAIN);
2898 if (data->icld_DisplayRastPort != data->icld_BufferRastPort)
2900 #if defined(DEBUG_ILC_ICONRENDERING)
2901 D(bug("[IconList] %s#%d: MADF_DRAWOBJECT: Blitting to front rastport..\n", __PRETTY_FUNCTION__, draw_id));
2902 #endif
2903 BltBitMapRastPort(data->icld_BufferRastPort->BitMap,
2904 0, 0,
2905 data->icld_DisplayRastPort,
2906 _mleft(obj), _mtop(obj),
2907 _mwidth(obj), _mheight(obj),
2908 0xC0);
2911 MUI_RemoveClipping(muiRenderInfo(obj), clip);
2913 data->icld_UpdateMode = 0;
2915 draw_done:;
2917 #if defined(DEBUG_ILC_ICONRENDERING)
2918 D(bug("[IconList] %s: Draw finished for id %d\n", __PRETTY_FUNCTION__, draw_id));
2919 #endif
2920 return 0;
2924 ///IconList__MUIM_IconList_Update()
2925 /**************************************************************************
2926 MUIM_IconList_Refresh
2927 Implemented by subclasses
2928 **************************************************************************/
2929 IPTR IconList__MUIM_IconList_Update(struct IClass *CLASS, Object *obj, struct MUIP_IconList_Update *message)
2931 struct IconList_DATA *data = INST_DATA(CLASS, obj);
2933 #if defined(DEBUG_ILC_FUNCS)
2934 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
2935 #endif
2937 data->icld_FocusIcon = NULL;
2938 SET(obj, MUIA_IconList_Changed, TRUE);
2940 return 1;
2944 ///MUIM_IconList_Clear()
2945 /**************************************************************************
2946 MUIM_IconList_Clear
2947 **************************************************************************/
2948 IPTR IconList__MUIM_IconList_Clear(struct IClass *CLASS, Object *obj, struct MUIP_IconList_Clear *message)
2950 struct IconList_DATA *data = INST_DATA(CLASS, obj);
2951 struct IconEntry *node = NULL;
2953 #if defined(DEBUG_ILC_FUNCS)
2954 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
2955 #endif
2957 while ((node = (struct IconEntry*)RemTail((struct List*)&data->icld_IconList)))
2959 DoMethod(obj, MUIM_IconList_DestroyEntry, node);
2962 data->icld_SelectionLastClicked = NULL;
2963 data->icld_FocusIcon = NULL;
2965 data->icld_ViewX = data->icld_ViewY = data->icld_AreaWidth = data->icld_AreaHeight = 0;
2967 D(bug("[IconList]: %s: call SetSuperAttrs()\n", __PRETTY_FUNCTION__));
2968 SetSuperAttrs(CLASS, obj, MUIA_Virtgroup_Left, data->icld_ViewX,
2969 MUIA_Virtgroup_Top, data->icld_ViewY,
2970 TAG_DONE);
2972 D(bug("[IconList]: %s: call SetAttrs()\n", __PRETTY_FUNCTION__));
2973 SetAttrs(obj, MUIA_Virtgroup_Left, data->icld_ViewX,
2974 MUIA_Virtgroup_Top, data->icld_ViewY,
2975 TAG_DONE);
2977 D(bug("[IconList]: %s: Set MUIA_IconList_Width and MUIA_IconList_Height\n", __PRETTY_FUNCTION__));
2978 SetAttrs(obj, MUIA_IconList_Width, data->icld_AreaWidth,
2979 MUIA_IconList_Height, data->icld_AreaHeight,
2980 TAG_DONE);
2982 D(bug("[IconList]: %s: call MUI_Redraw()\n", __PRETTY_FUNCTION__));
2983 MUI_Redraw(obj,MADF_DRAWOBJECT);
2984 return 1;
2988 ///IconList__MUIM_IconList_DestroyEntry()
2989 IPTR IconList__MUIM_IconList_DestroyEntry(struct IClass *CLASS, Object *obj, struct MUIP_IconList_DestroyEntry *message)
2991 struct IconList_DATA *data = INST_DATA(CLASS, obj);
2993 #if defined(DEBUG_ILC_FUNCS)
2994 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
2995 #endif
2997 if (message->icon)
2999 if (message->icon->ie_Flags & ICONENTRY_FLAG_SELECTED)
3001 if (data->icld_SelectionLastClicked == message->icon)
3003 struct IconList_Entry *nextentry = &message->icon->ie_IconListEntry;
3005 /* get selected entries from SOURCE iconlist */
3006 DoMethod(obj, MUIM_IconList_NextIcon, MUIV_IconList_NextIcon_Selected, (IPTR)&nextentry);
3007 if ((nextentry) && (nextentry != (IPTR)MUIV_IconList_NextIcon_End))
3008 data->icld_SelectionLastClicked = (struct IconEntry *)((IPTR)nextentry - ((IPTR)&message->icon->ie_IconListEntry - (IPTR)message->icon));
3009 else
3010 data->icld_SelectionLastClicked = NULL;
3012 if (data->icld_FocusIcon == message->icon)
3013 data->icld_FocusIcon = data->icld_SelectionLastClicked;
3015 Remove(&message->icon->ie_SelectionNode);
3018 if (message->icon->ie_TxtBuf_DisplayedLabel)
3019 FreeVecPooled(data->icld_Pool, message->icon->ie_TxtBuf_DisplayedLabel);
3021 if (message->icon->ie_TxtBuf_PROT)
3022 FreePooled(data->icld_Pool, message->icon->ie_TxtBuf_PROT, 8);
3024 if (message->icon->ie_TxtBuf_SIZE)
3025 FreePooled(data->icld_Pool, message->icon->ie_TxtBuf_SIZE, 30);
3027 if (message->icon->ie_TxtBuf_TIME)
3028 FreePooled(data->icld_Pool, message->icon->ie_TxtBuf_TIME, LEN_DATSTRING);
3030 if (message->icon->ie_TxtBuf_DATE)
3031 FreePooled(data->icld_Pool, message->icon->ie_TxtBuf_DATE, LEN_DATSTRING);
3033 if (message->icon->ie_DiskObj)
3034 FreeDiskObject(message->icon->ie_DiskObj);
3036 if (message->icon->ie_FileInfoBlock)
3037 FreeMem(message->icon->ie_FileInfoBlock, sizeof(struct FileInfoBlock));
3039 if (message->icon->ie_IconListEntry.label)
3040 FreePooled(data->icld_Pool, message->icon->ie_IconListEntry.label, strlen(message->icon->ie_IconListEntry.label)+1);
3042 if (message->icon->ie_IconNode.ln_Name)
3043 FreePooled(data->icld_Pool, message->icon->ie_IconNode.ln_Name, strlen(message->icon->ie_IconNode.ln_Name)+1);
3045 FreePooled(data->icld_Pool, message->icon, sizeof(struct IconEntry));
3047 return (IPTR)TRUE;
3051 ///IconList__MUIM_IconList_CreateEntry()
3052 /**************************************************************************
3053 MUIM_IconList_CreateEntry.
3054 Returns 0 on failure otherwise it returns the icons entry ..
3055 **************************************************************************/
3056 IPTR IconList__MUIM_IconList_CreateEntry(struct IClass *CLASS, Object *obj, struct MUIP_IconList_CreateEntry *message)
3058 struct IconList_DATA *data = INST_DATA(CLASS, obj);
3059 struct IconEntry *entry = NULL;
3060 struct DateTime dt;
3061 struct DateStamp now;
3062 UBYTE *sp = NULL;
3064 struct DiskObject *dob = NULL;
3065 struct Rectangle rect;
3067 IPTR geticon_error = 0;
3069 #if defined(DEBUG_ILC_FUNCS)
3070 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
3071 #endif
3073 /*disk object (icon)*/
3074 if (message->icon_dob == NULL)
3076 IPTR iconlistScreen = _screen(obj);
3077 D(bug("[IconList] %s: IconList Screen @ 0x%p)\n", __PRETTY_FUNCTION__, iconlistScreen));
3079 dob = GetIconTags
3081 message->filename,
3082 (iconlistScreen) ? ICONGETA_Screen : TAG_IGNORE, iconlistScreen,
3083 (iconlistScreen) ? ICONGETA_RemapIcon : TAG_IGNORE, TRUE,
3084 ICONGETA_FailIfUnavailable, FALSE,
3085 ICONGETA_GenerateImageMasks, TRUE,
3086 ICONA_ErrorCode, &geticon_error,
3087 TAG_DONE
3090 if (dob == NULL)
3092 D(bug("[IconList] %s: Fatal: Couldnt get DiskObject! (error code = 0x%p)\n", __PRETTY_FUNCTION__, geticon_error));
3094 return (IPTR)NULL;
3097 else
3099 dob = message->icon_dob;
3102 D(bug("[IconList] %s: DiskObject @ 0x%p\n", __PRETTY_FUNCTION__, dob));
3104 if ((entry = AllocPooled(data->icld_Pool, sizeof(struct IconEntry))) == NULL)
3106 D(bug("[IconList] %s: Failed to Allocate Entry Storage!\n", __PRETTY_FUNCTION__));
3107 FreeDiskObject(dob);
3108 return (IPTR)NULL;
3110 memset(entry, 0, sizeof(struct IconEntry));
3111 entry->ie_Flags |= ICONENTRY_FLAG_NEEDSUPDATE;
3112 entry->ie_IconListEntry.ile_IconEntry = entry;
3114 /* Allocate Text Buffers */
3116 if ((entry->ie_TxtBuf_DATE = AllocPooled(data->icld_Pool, LEN_DATSTRING)) == NULL)
3118 D(bug("[IconList] %s: Failed to Allocate Entry DATE Storage!\n", __PRETTY_FUNCTION__));
3119 DoMethod(obj, MUIM_IconList_DestroyEntry, entry);
3120 return (IPTR)NULL;
3122 memset(entry->ie_TxtBuf_DATE, 0, LEN_DATSTRING);
3124 if ((entry->ie_TxtBuf_TIME = AllocPooled(data->icld_Pool, LEN_DATSTRING)) == NULL)
3126 D(bug("[IconList] %s: Failed to Allocate Entry TIME string Storage!\n", __PRETTY_FUNCTION__));
3127 DoMethod(obj, MUIM_IconList_DestroyEntry, entry);
3128 return (IPTR)NULL;
3130 memset(entry->ie_TxtBuf_TIME, 0, LEN_DATSTRING);
3132 if ((entry->ie_TxtBuf_SIZE = AllocPooled(data->icld_Pool, 30)) == NULL)
3134 D(bug("[IconList] %s: Failed to Allocate Entry SIZE string Storage!\n", __PRETTY_FUNCTION__));
3135 DoMethod(obj, MUIM_IconList_DestroyEntry, entry);
3136 return (IPTR)NULL;
3138 memset(entry->ie_TxtBuf_SIZE, 0, 30);
3140 if ((entry->ie_TxtBuf_PROT = AllocPooled(data->icld_Pool, 8)) == NULL)
3142 D(bug("[IconList] %s: Failed to Allocate Entry PROT Flag string Storage!\n", __PRETTY_FUNCTION__));
3143 DoMethod(obj, MUIM_IconList_DestroyEntry, entry);
3144 return (IPTR)NULL;
3146 memset(entry->ie_TxtBuf_PROT, 0, 8);
3148 /*alloc filename*/
3149 if ((entry->ie_IconNode.ln_Name = AllocPooled(data->icld_Pool, strlen(message->filename) + 1)) == NULL)
3151 D(bug("[IconList] %s: Failed to Allocate Entry filename string Storage!\n", __PRETTY_FUNCTION__));
3152 DoMethod(obj, MUIM_IconList_DestroyEntry, entry);
3153 return (IPTR)NULL;
3156 /*alloc icon label*/
3157 if ((entry->ie_IconListEntry.label = AllocPooled(data->icld_Pool, strlen(message->label) + 1)) == NULL)
3159 D(bug("[IconList] %s: Failed to Allocate Entry label string Storage!\n", __PRETTY_FUNCTION__));
3160 DoMethod(obj, MUIM_IconList_DestroyEntry, entry);
3161 return (IPTR)NULL;
3164 /*file info block*/
3165 if(message->fib != NULL)
3167 if ((entry->ie_FileInfoBlock = AllocMem(sizeof(struct FileInfoBlock), MEMF_CLEAR)) != NULL)
3169 CopyMem(message->fib, entry->ie_FileInfoBlock, sizeof(struct FileInfoBlock));
3171 if (entry->ie_FileInfoBlock->fib_DirEntryType > 0)
3173 strcpy(entry->ie_TxtBuf_SIZE, "Drawer");
3175 else
3177 FmtSizeToString(entry->ie_TxtBuf_SIZE, entry->ie_FileInfoBlock->fib_Size);
3180 dt.dat_Stamp = entry->ie_FileInfoBlock->fib_Date;
3181 dt.dat_Format = FORMAT_DEF;
3182 dt.dat_Flags = 0;
3183 dt.dat_StrDay = NULL;
3184 dt.dat_StrDate = entry->ie_TxtBuf_DATE;
3185 dt.dat_StrTime = entry->ie_TxtBuf_TIME;
3187 DateToStr(&dt);
3188 DateStamp(&now);
3190 /*if modified today show time, otherwise just show date*/
3191 if (now.ds_Days == entry->ie_FileInfoBlock->fib_Date.ds_Days)
3192 entry->ie_Flags |= ICONENTRY_FLAG_TODAY;
3193 else
3194 entry->ie_Flags &= ~ICONENTRY_FLAG_TODAY;
3196 sp = entry->ie_TxtBuf_PROT;
3197 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_SCRIPT) ? 's' : '-';
3198 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_PURE) ? 'p' : '-';
3199 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_ARCHIVE) ? 'a' : '-';
3200 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_READ) ? '-' : 'r';
3201 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_WRITE) ? '-' : 'w';
3202 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_EXECUTE) ? '-' : 'e';
3203 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_DELETE) ? '-' : 'd';
3204 *sp++ = '\0';
3206 entry->ie_IconListEntry.type = entry->ie_FileInfoBlock->fib_DirEntryType;
3209 else
3211 entry->ie_IconListEntry.type = ST_USERDIR;
3214 /* Override type if specified during createntry */
3215 if (message->type != 0)
3217 entry->ie_IconListEntry.type = message->type;
3218 D(bug("[IconList] %s: Overide Entry Type. New Type = %x\n", __PRETTY_FUNCTION__, entry->ie_IconListEntry.type));
3220 else
3222 D(bug("[IconList] %s: Entry Type = %x\n", __PRETTY_FUNCTION__, entry->ie_IconListEntry.type));
3225 strcpy(entry->ie_IconNode.ln_Name, message->filename);
3226 strcpy(entry->ie_IconListEntry.label, message->label);
3228 entry->ie_IconListEntry.udata = NULL;
3230 if (IconList__LabelFunc_CreateLabel(obj, data, entry) != (IPTR)NULL)
3232 entry->ie_DiskObj = dob;
3234 /* Use a geticonrectangle routine that gets textwidth! */
3235 IconList_GetIconAreaRectangle(obj, data, entry, &rect);
3237 return (IPTR)entry;
3240 DoMethod(obj, MUIM_IconList_DestroyEntry, entry);
3241 return (IPTR)NULL;
3245 ///IconList__MUIM_IconList_UpdateEntry()
3246 /**************************************************************************
3247 MUIM_IconList_UpdateEntry.
3248 Returns 0 on failure otherwise it returns the icons entry ..
3249 **************************************************************************/
3250 IPTR IconList__MUIM_IconList_UpdateEntry(struct IClass *CLASS, Object *obj, struct MUIP_IconList_UpdateEntry *message)
3252 struct IconList_DATA *data = INST_DATA(CLASS, obj);
3253 struct DateTime dt;
3254 struct DateStamp now;
3255 UBYTE *sp = NULL;
3257 struct DiskObject *dob = NULL;
3258 struct Rectangle rect;
3260 IPTR geticon_error = 0;
3262 #if defined(DEBUG_ILC_FUNCS)
3263 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
3264 #endif
3266 /* Update disk object (icon)*/
3267 /* if (message->icon_dob == NULL)
3269 IPTR iconlistScreen = _screen(obj);
3270 D(bug("[IconList] %s: IconList Screen @ 0x%p)\n", __PRETTY_FUNCTION__, iconlistScreen));
3272 dob = GetIconTags
3274 message->filename,
3275 (iconlistScreen) ? ICONGETA_Screen : TAG_IGNORE, iconlistScreen,
3276 (iconlistScreen) ? ICONGETA_RemapIcon : TAG_IGNORE, TRUE,
3277 ICONGETA_FailIfUnavailable, FALSE,
3278 ICONGETA_GenerateImageMasks, TRUE,
3279 ICONA_ErrorCode, &geticon_error,
3280 TAG_DONE
3283 if (dob == NULL)
3285 D(bug("[IconList] %s: Fatal: Couldnt get DiskObject! (error code = 0x%p)\n", __PRETTY_FUNCTION__, geticon_error));
3287 return (IPTR)NULL;
3290 else
3292 dob = message->icon_dob;
3295 D(bug("[IconList] %s: DiskObject @ 0x%p\n", __PRETTY_FUNCTION__, dob));
3298 /* Update filename */
3299 if (strcmp(message->icon->ie_IconNode.ln_Name, message->filename) != 0)
3301 message->icon->ie_Flags |= ICONENTRY_FLAG_NEEDSUPDATE;
3302 FreePooled(data->icld_Pool, message->icon->ie_IconNode.ln_Name, strlen(message->icon->ie_IconNode.ln_Name) + 1);
3303 if ((message->icon->ie_IconNode.ln_Name = AllocPooled(data->icld_Pool, strlen(message->filename) + 1)) == NULL)
3305 D(bug("[IconList] %s: Failed to Allocate Entry filename string Storage!\n", __PRETTY_FUNCTION__));
3306 DoMethod(obj, MUIM_IconList_DestroyEntry, message->icon);
3307 return (IPTR)NULL;
3309 strcpy(message->icon->ie_IconNode.ln_Name, message->filename);
3312 /* Update icon label */
3313 if (strcmp(message->icon->ie_IconListEntry.label, message->label) != 0)
3315 message->icon->ie_Flags |= ICONENTRY_FLAG_NEEDSUPDATE;
3316 FreePooled(data->icld_Pool, message->icon->ie_IconListEntry.label, strlen(message->icon->ie_IconListEntry.label) + 1);
3317 if ((message->icon->ie_IconListEntry.label = AllocPooled(data->icld_Pool, strlen(message->label) + 1)) == NULL)
3319 D(bug("[IconList] %s: Failed to Allocate Entry label string Storage!\n", __PRETTY_FUNCTION__));
3320 DoMethod(obj, MUIM_IconList_DestroyEntry, message->icon);
3321 return (IPTR)NULL;
3323 strcpy(message->icon->ie_IconListEntry.label, message->label);
3324 if (IconList__LabelFunc_CreateLabel(obj, data, message->icon) == (IPTR)NULL)
3326 D(bug("[IconList] %s: Failed to create label\n", __PRETTY_FUNCTION__));
3327 DoMethod(obj, MUIM_IconList_DestroyEntry, message->icon);
3328 return (IPTR)NULL;
3332 /* Update file info block */
3333 if(message->fib != NULL)
3335 if (!(message->icon->ie_FileInfoBlock))
3337 if ((message->icon->ie_FileInfoBlock = AllocMem(sizeof(struct FileInfoBlock), MEMF_CLEAR)) != NULL)
3339 CopyMem(message->fib, message->icon->ie_FileInfoBlock, sizeof(struct FileInfoBlock));
3343 /* if (entry->ie_FileInfoBlock->fib_DirEntryType > 0)
3345 strcpy(entry->ie_TxtBuf_SIZE, "Drawer");
3347 else
3349 FmtSizeToString(entry->ie_TxtBuf_SIZE, entry->ie_FileInfoBlock->fib_Size);
3352 dt.dat_Stamp = entry->ie_FileInfoBlock->fib_Date;
3353 dt.dat_Format = FORMAT_DEF;
3354 dt.dat_Flags = 0;
3355 dt.dat_StrDay = NULL;
3356 dt.dat_StrDate = entry->ie_TxtBuf_DATE;
3357 dt.dat_StrTime = entry->ie_TxtBuf_TIME;
3359 DateToStr(&dt);
3360 DateStamp(&now);
3362 //if modified today show time, otherwise just show date
3363 if (now.ds_Days == entry->ie_FileInfoBlock->fib_Date.ds_Days)
3364 entry->ie_Flags |= ICONENTRY_FLAG_TODAY;
3365 else
3366 entry->ie_Flags &= ~ICONENTRY_FLAG_TODAY;
3368 sp = entry->ie_TxtBuf_PROT;
3369 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_SCRIPT) ? 's' : '-';
3370 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_PURE) ? 'p' : '-';
3371 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_ARCHIVE) ? 'a' : '-';
3372 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_READ) ? '-' : 'r';
3373 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_WRITE) ? '-' : 'w';
3374 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_EXECUTE) ? '-' : 'e';
3375 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_DELETE) ? '-' : 'd';
3376 *sp++ = '\0';
3378 entry->ie_IconListEntry.type = entry->ie_FileInfoBlock->fib_DirEntryType;
3381 else
3383 if (message->icon->ie_FileInfoBlock)
3384 FreeMem(message->icon->ie_FileInfoBlock, sizeof(struct FileInfoBlock));
3386 if (message->icon->ie_IconListEntry.type != ST_USERDIR)
3388 message->icon->ie_Flags |= ICONENTRY_FLAG_NEEDSUPDATE;
3389 message->icon->ie_IconListEntry.type = ST_USERDIR;
3393 /* Override type if specified */
3394 if ((message->type != 0) && (message->icon->ie_IconListEntry.type != message->type))
3396 message->icon->ie_Flags |= ICONENTRY_FLAG_NEEDSUPDATE;
3397 message->icon->ie_IconListEntry.type = message->type;
3398 D(bug("[IconList] %s: Overide Entry Type. New Type = %x\n", __PRETTY_FUNCTION__, message->icon->ie_IconListEntry.type));
3400 else
3402 D(bug("[IconList] %s: Entry Type = %x\n", __PRETTY_FUNCTION__, message->icon->ie_IconListEntry.type));
3405 IconList_GetIconAreaRectangle(obj, data, message->icon, &rect);
3407 return (IPTR)message->icon;
3411 ///DoWheelMove()
3412 static void DoWheelMove(struct IClass *CLASS, Object *obj, LONG wheelx, LONG wheely, UWORD qual)
3414 struct IconList_DATA *data = INST_DATA(CLASS, obj);
3416 LONG newleft = data->icld_ViewX,
3417 newtop = data->icld_ViewY;
3419 /* Use horizontal scrolling if any of the following cases are true ...
3421 # vertical wheel is used but there's nothing to scroll
3422 (everything is visible already) ..
3424 # vertical wheel is used and one of the ALT keys is down. */
3426 if ((wheely && !wheelx) &&
3427 ((data->icld_AreaHeight <= _mheight(obj)) || (qual & (IEQUALIFIER_LALT | IEQUALIFIER_RALT))))
3429 wheelx = wheely; wheely = 0;
3432 if (qual & (IEQUALIFIER_CONTROL))
3434 if (wheelx < 0) newleft = 0;
3435 if (wheelx > 0) newleft = data->icld_AreaWidth;
3436 if (wheely < 0) newtop = 0;
3437 if (wheely > 0) newtop = data->icld_AreaHeight;
3439 else if (qual & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
3441 newleft += (wheelx * _mwidth(obj));
3442 newtop += (wheely * _mheight(obj));
3444 else
3446 newleft += wheelx * 30;
3447 newtop += wheely * 30;
3450 if (newleft + _mwidth(obj) > data->icld_AreaWidth)
3451 newleft = data->icld_AreaWidth - _mwidth(obj);
3452 if (newleft < 0)
3453 newleft = 0;
3455 if (newtop + _mheight(obj) > data->icld_AreaHeight)
3456 newtop = data->icld_AreaHeight - _mheight(obj);
3457 if (newtop < 0)
3458 newtop = 0;
3460 if ((newleft != data->icld_ViewX) || (newtop != data->icld_ViewY))
3462 SetAttrs(obj, MUIA_Virtgroup_Left, newleft,
3463 MUIA_Virtgroup_Top, newtop,
3464 TAG_DONE);
3469 ///MUIM_HandleEvent()
3470 /**************************************************************************
3471 MUIM_HandleEvent
3472 **************************************************************************/
3473 IPTR IconList__MUIM_HandleEvent(struct IClass *CLASS, Object *obj, struct MUIP_HandleEvent *message)
3475 struct IconList_DATA *data = INST_DATA(CLASS, obj);
3477 #if defined(DEBUG_ILC_FUNCS)
3478 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
3479 #endif
3481 if (message->imsg)
3483 LONG mx = message->imsg->MouseX - _mleft(obj);
3484 LONG my = message->imsg->MouseY - _mtop(obj);
3486 LONG wheelx = 0;
3487 LONG wheely = 0;
3489 switch (message->imsg->Class)
3491 case IDCMP_RAWKEY:
3493 #if defined(DEBUG_ILC_EVENTS)
3494 D(bug("[IconList] %s: IDCMP_RAWKEY\n", __PRETTY_FUNCTION__));
3495 #endif
3496 BOOL rawkey_handled = FALSE;
3498 switch(message->imsg->Code)
3500 case RAWKEY_NM_WHEEL_UP:
3501 wheely = -1;
3502 rawkey_handled = TRUE;
3503 break;
3505 case RAWKEY_NM_WHEEL_DOWN:
3506 wheely = 1;
3507 rawkey_handled = TRUE;
3508 break;
3510 case RAWKEY_NM_WHEEL_LEFT:
3511 wheelx = -1;
3512 rawkey_handled = TRUE;
3513 break;
3515 case RAWKEY_NM_WHEEL_RIGHT:
3516 wheelx = 1;
3517 rawkey_handled = TRUE;
3518 break;
3521 if (rawkey_handled)
3523 #if defined(DEBUG_ILC_KEYEVENTS)
3524 D(bug("[IconList] %s: Processing mouse wheel event\n", __PRETTY_FUNCTION__));
3525 #endif
3526 if (_isinobject(message->imsg->MouseX, message->imsg->MouseY) &&
3527 (wheelx || wheely))
3529 DoWheelMove(CLASS, obj, wheelx, wheely, message->imsg->Qualifier);
3532 else if (!(message->imsg->Code & IECODE_UP_PREFIX))
3534 LONG new_ViewY = data->icld_ViewY;
3535 struct IconEntry *start_entry = NULL, *active_entry = NULL, *entry_next = NULL;
3536 IPTR start_X = 0, start_Y = 0, active_X = 0, active_Y = 0, next_X = 0, next_Y = 0;
3537 IPTR x_diff = 0;
3539 #if defined(DEBUG_ILC_KEYEVENTS)
3540 D(bug("[IconList] %s: Processing key up event\n", __PRETTY_FUNCTION__));
3541 #endif
3543 switch(message->imsg->Code)
3545 case RAWKEY_RETURN:
3546 rawkey_handled = TRUE;
3548 #if defined(DEBUG_ILC_KEYEVENTS)
3549 D(bug("[IconList] %s: RAWKEY_RETURN\n", __PRETTY_FUNCTION__));
3550 #endif
3552 if (data->icld_FocusIcon) active_entry = data->icld_FocusIcon;
3553 else if (data->icld_SelectionLastClicked) active_entry = data->icld_SelectionLastClicked;
3555 if (active_entry)
3557 if (!(active_entry->ie_Flags & ICONENTRY_FLAG_SELECTED))
3559 active_entry->ie_Flags |= ICONENTRY_FLAG_SELECTED;
3560 AddTail(&data->icld_SelectionList, &active_entry->ie_SelectionNode);
3561 data->icld_UpdateMode = UPDATE_SINGLEICON;
3562 data->update_icon = active_entry;
3563 MUI_Redraw(obj, MADF_DRAWUPDATE);
3565 data->icld_SelectionLastClicked = active_entry;
3566 data->icld_FocusIcon = active_entry;
3568 SET(obj, MUIA_IconList_DoubleClick, TRUE);
3570 break;
3572 case RAWKEY_SPACE:
3573 rawkey_handled = TRUE;
3575 #if defined(DEBUG_ILC_KEYEVENTS)
3576 D(bug("[IconList] %s: RAWKEY_SPACE\n", __PRETTY_FUNCTION__));
3577 #endif
3579 if (data->icld_FocusIcon) active_entry = data->icld_FocusIcon;
3580 else if (data->icld_SelectionLastClicked) active_entry = data->icld_SelectionLastClicked;
3582 if (!(message->imsg->Qualifier & IEQUALIFIER_LSHIFT) && ((data->icld_SelectionLastClicked)||(data->icld_SelectionLastClicked != active_entry)))
3584 #if defined(DEBUG_ILC_KEYEVENTS)
3585 D(bug("[IconList] %s: SPACE: Clearing selected icons ..\n", __PRETTY_FUNCTION__));
3586 #endif
3587 DoMethod(obj, MUIM_IconList_UnselectAll);
3590 if (active_entry)
3592 if (!(active_entry->ie_Flags & ICONENTRY_FLAG_SELECTED))
3594 AddTail(&data->icld_SelectionList, &active_entry->ie_SelectionNode);
3595 active_entry->ie_Flags |= ICONENTRY_FLAG_SELECTED;
3596 data->icld_SelectionLastClicked = active_entry;
3598 else
3600 Remove(&active_entry->ie_SelectionNode);
3601 active_entry->ie_Flags &= ~ICONENTRY_FLAG_SELECTED;
3604 data->icld_FocusIcon = active_entry;
3606 data->icld_UpdateMode = UPDATE_SINGLEICON;
3607 data->update_icon = active_entry;
3608 MUI_Redraw(obj, MADF_DRAWUPDATE);
3610 break;
3612 case RAWKEY_PAGEUP:
3613 rawkey_handled = TRUE;
3615 #if defined(DEBUG_ILC_KEYEVENTS)
3616 D(bug("[IconList] %s: RAWKEY_PAGEUP\n", __PRETTY_FUNCTION__));
3617 #endif
3619 if (data->icld_AreaHeight > data->icld_ViewHeight)
3621 new_ViewY -= data->icld_ViewHeight;
3622 if (new_ViewY< 0)
3623 new_ViewY = 0;
3626 if (new_ViewY != data->icld_ViewY)
3628 SET(obj, MUIA_Virtgroup_Top, new_ViewY);
3630 break;
3632 case RAWKEY_PAGEDOWN:
3633 rawkey_handled = TRUE;
3635 #if defined(DEBUG_ILC_KEYEVENTS)
3636 D(bug("[IconList] %s: RAWKEY_PAGEDOWN\n", __PRETTY_FUNCTION__));
3637 #endif
3639 if (data->icld_AreaHeight > data->icld_ViewHeight)
3641 new_ViewY += data->icld_ViewHeight;
3642 if (new_ViewY > (data->icld_AreaHeight - data->icld_ViewHeight))
3643 new_ViewY = data->icld_AreaHeight - data->icld_ViewHeight;
3646 if (new_ViewY != data->icld_ViewY)
3648 SET(obj, MUIA_Virtgroup_Top, new_ViewY);
3650 break;
3652 case RAWKEY_UP:
3653 rawkey_handled = TRUE;
3655 #if defined(DEBUG_ILC_KEYEVENTS)
3656 D(bug("[IconList] %s: RAWKEY_UP\n", __PRETTY_FUNCTION__));
3657 #endif
3659 if (data->icld_FocusIcon)
3661 start_entry = data->icld_FocusIcon;
3662 #if defined(DEBUG_ILC_KEYEVENTS)
3663 D(bug("[IconList] %s: UP: Clearing existing focused icon @ 0x%p\n", __PRETTY_FUNCTION__, start_entry));
3664 #endif
3666 start_entry->ie_Flags &= ~ICONENTRY_FLAG_FOCUS;
3667 data->icld_UpdateMode = UPDATE_SINGLEICON;
3668 data->update_icon = start_entry;
3669 MUI_Redraw(obj, MADF_DRAWUPDATE);
3671 start_X = start_entry->ie_IconX;
3672 start_Y = start_entry->ie_IconY;
3673 #if defined(DEBUG_ILC_KEYEVENTS)
3674 D(bug("[IconList] %s: UP: start_icon @ 0x%p '%s' - start_X %d, start_Y %d\n", __PRETTY_FUNCTION__, start_entry, start_entry->ie_IconListEntry.label, start_X, start_Y));
3675 #endif
3676 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
3678 if (start_entry->ie_AreaWidth < data->icld_IconAreaLargestWidth)
3680 start_X = start_X - ((data->icld_IconAreaLargestWidth - start_entry->ie_AreaWidth)/2);
3681 #if defined(DEBUG_ILC_KEYEVENTS)
3682 D(bug("[IconList] %s: UP: adjusted start_X for grid = %d\n", __PRETTY_FUNCTION__, start_X));
3683 #endif
3687 if ((active_entry = Node_PreviousVisible(start_entry)) && !(data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL))
3689 //Check if we are at the edge of the icon area ..
3690 #if defined(DEBUG_ILC_KEYEVENTS)
3691 D(bug("[IconList] %s: UP: active_entry @ 0x%p '%s' , X %d, Y %d\n", __PRETTY_FUNCTION__, active_entry, active_entry->ie_IconListEntry.label, active_entry->ie_IconX, active_entry->ie_IconY));
3692 #endif
3693 active_Y = active_entry->ie_IconY;
3695 if (active_Y == start_Y)
3698 #if defined(DEBUG_ILC_KEYEVENTS)
3699 D(bug("[IconList] %s: UP: active_entry is on our row (not at the edge)\n", __PRETTY_FUNCTION__));
3700 #endif
3701 entry_next = active_entry;
3702 next_X = entry_next->ie_IconX;
3703 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
3705 if (entry_next->ie_AreaWidth < data->icld_IconAreaLargestWidth)
3706 next_X = next_X - ((data->icld_IconAreaLargestWidth - entry_next->ie_AreaWidth)/2);
3710 #if defined(DEBUG_ILC_KEYEVENTS)
3711 D(bug("[IconList] %s: UP: using start_X %d, start_Y %d\n", __PRETTY_FUNCTION__, start_X, start_Y));
3712 #endif
3715 if (!(message->imsg->Qualifier & IEQUALIFIER_LSHIFT) && ((data->icld_SelectionLastClicked)&&(data->icld_SelectionLastClicked != active_entry)))
3717 #if defined(DEBUG_ILC_KEYEVENTS)
3718 D(bug("[IconList] %s: UP: Clearing selected icons ..\n", __PRETTY_FUNCTION__));
3719 #endif
3720 DoMethod(obj, MUIM_IconList_UnselectAll);
3723 #if defined(DEBUG_ILC_KEYEVENTS)
3724 D(bug("[IconList] %s: UP: active = 0x%p, next = 0x%p\n", __PRETTY_FUNCTION__, active_entry, entry_next));
3725 #endif
3726 if (!(active_entry))
3728 // If nothing is selected we will use the last visible icon ..
3729 active_entry = Node_LastVisible(&data->icld_IconList);
3730 start_X = active_entry->ie_IconX;
3731 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
3733 if (active_entry->ie_AreaWidth < data->icld_IconAreaLargestWidth)
3734 start_X = start_X - ((data->icld_IconAreaLargestWidth - active_entry->ie_AreaWidth)/2);
3736 start_Y = active_entry->ie_IconY;
3739 while (active_entry != NULL)
3741 #if defined(DEBUG_ILC_KEYEVENTS)
3742 D(bug("[IconList] %s: UP: Checking active @ 0x%p\n", __PRETTY_FUNCTION__, active_entry));
3743 #endif
3744 if (data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL)
3746 // Return the first visible since the list flow direction matches
3747 // our cursor direction
3748 if (active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE)
3749 break;
3751 else
3753 active_X = active_entry->ie_IconX;
3755 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
3757 if (active_entry->ie_AreaWidth < data->icld_IconAreaLargestWidth)
3758 x_diff = ((data->icld_IconAreaLargestWidth - active_entry->ie_AreaWidth)/2);
3760 active_Y = active_entry->ie_IconY;
3762 if (start_entry)
3764 if (entry_next)
3766 if ((active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE) &&
3767 (active_Y < start_Y) &&
3768 (((active_X - x_diff) >= start_X ) &&
3769 ((active_X - x_diff) <= (start_X + start_entry->ie_AreaWidth + (x_diff*2)))))
3771 #if defined(DEBUG_ILC_KEYEVENTS)
3772 D(bug("[IconList] %s: UP: (A) entry 0x%p matches\n", __PRETTY_FUNCTION__, active_entry));
3773 #endif
3774 break;
3776 else if (active_entry == (struct IconEntry *)GetHead(&data->icld_IconList))
3778 #if defined(DEBUG_ILC_KEYEVENTS)
3779 D(bug("[IconList] %s: UP: (A) reached list start .. restarting from the end ..\n", __PRETTY_FUNCTION__));
3780 #endif
3781 start_X = next_X;
3783 if ((entry_next = Node_PreviousVisible(entry_next)))
3785 if (entry_next->ie_IconX > start_X)
3786 entry_next = NULL;
3787 else
3789 next_X = entry_next->ie_IconX;
3790 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
3792 if (entry_next->ie_AreaWidth < data->icld_IconAreaLargestWidth)
3793 next_X = next_X - ((data->icld_IconAreaLargestWidth - entry_next->ie_AreaWidth)/2);
3797 start_Y = 0;
3798 #if defined(DEBUG_ILC_KEYEVENTS)
3799 D(bug("[IconList] %s: UP: (A) startx = %d, start_Y = %d, next_X = %d, entry_next @ 0x%p\n", __PRETTY_FUNCTION__, start_X, start_Y, next_X, entry_next));
3800 #endif
3801 active_entry = Node_LastVisible(&data->icld_IconList);
3804 else
3806 if ((active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE) &&
3807 (active_Y < start_Y) &&
3808 ((active_X + x_diff) < (start_X + start_entry->ie_AreaWidth + x_diff)))
3810 #if defined(DEBUG_ILC_KEYEVENTS)
3811 D(bug("[IconList] %s: UP: (B) entry 0x%p matches\n", __PRETTY_FUNCTION__, active_entry));
3812 #endif
3813 break;
3817 else
3819 if (active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE)
3821 #if defined(DEBUG_ILC_KEYEVENTS)
3822 D(bug("[IconList] %s: UP: (C) entry 0x%p matches\n", __PRETTY_FUNCTION__, active_entry));
3823 #endif
3824 break;
3828 active_entry = (struct IconEntry *)(((struct Node *)active_entry)->ln_Pred);
3831 if (!(active_entry))
3833 #if defined(DEBUG_ILC_KEYEVENTS)
3834 D(bug("[IconList] %s: UP: No Next UP Node - Getting Last visible icon ..\n", __PRETTY_FUNCTION__));
3835 #endif
3836 /* We didnt find a "next UP" icon so just use the last visible */
3837 active_entry = Node_LastVisible(&data->icld_IconList);
3840 if (active_entry)
3842 if (!(active_entry->ie_Flags & ICONENTRY_FLAG_FOCUS))
3844 active_entry->ie_Flags |= ICONENTRY_FLAG_FOCUS;
3845 data->icld_UpdateMode = UPDATE_SINGLEICON;
3846 data->update_icon = active_entry;
3847 MUI_Redraw(obj, MADF_DRAWUPDATE);
3850 data->icld_FocusIcon = active_entry;
3851 break;
3853 case RAWKEY_DOWN:
3854 rawkey_handled = TRUE;
3856 #if defined(DEBUG_ILC_KEYEVENTS)
3857 D(bug("[IconList] %s: RAWKEY_DOWN\n", __PRETTY_FUNCTION__));
3858 #endif
3859 if (data->icld_FocusIcon)
3861 start_entry = data->icld_FocusIcon;
3862 #if defined(DEBUG_ILC_KEYEVENTS)
3863 D(bug("[IconList] %s: DOWN: Clearing existing focused icon @ 0x%p\n", __PRETTY_FUNCTION__, start_entry));
3864 #endif
3866 start_entry->ie_Flags &= ~ICONENTRY_FLAG_FOCUS;
3867 data->icld_UpdateMode = UPDATE_SINGLEICON;
3868 data->update_icon = start_entry;
3869 MUI_Redraw(obj, MADF_DRAWUPDATE);
3871 start_X = start_entry->ie_IconX;
3872 start_Y = start_entry->ie_IconY;
3873 #if defined(DEBUG_ILC_KEYEVENTS)
3874 D(bug("[IconList] %s: DOWN: start_icon @ 0x%p '%s' - start_X %d, start_Y %d\n", __PRETTY_FUNCTION__, start_entry, start_entry->ie_IconListEntry.label, start_X, start_Y));
3875 #endif
3876 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
3878 if (start_entry->ie_AreaWidth < data->icld_IconAreaLargestWidth)
3880 start_X = start_X - ((data->icld_IconAreaLargestWidth - start_entry->ie_AreaWidth)/2);
3881 #if defined(DEBUG_ILC_KEYEVENTS)
3882 D(bug("[IconList] %s: DOWN: adjusted start_X for grid = %d\n", __PRETTY_FUNCTION__, start_X));
3883 #endif
3887 if ((active_entry = Node_NextVisible(start_entry)) &&
3888 (!(data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL)))
3890 #if defined(DEBUG_ILC_KEYEVENTS)
3891 D(bug("[IconList] %s: DOWN: active_entry @ 0x%p '%s' , X %d, Y %d\n", __PRETTY_FUNCTION__, active_entry, active_entry->ie_IconListEntry.label, active_entry->ie_IconX, active_entry->ie_IconY));
3892 #endif
3893 active_Y = active_entry->ie_IconY;
3895 if (active_Y == start_Y)
3898 #if defined(DEBUG_ILC_KEYEVENTS)
3899 D(bug("[IconList] %s: DOWN: active_entry is on our row (not at the edge)\n", __PRETTY_FUNCTION__));
3900 #endif
3901 entry_next = active_entry;
3902 next_X = entry_next->ie_IconX;
3903 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
3905 if (entry_next->ie_AreaWidth < data->icld_IconAreaLargestWidth)
3906 next_X = next_X - ((data->icld_IconAreaLargestWidth - entry_next->ie_AreaWidth)/2);
3910 #if defined(DEBUG_ILC_KEYEVENTS)
3911 D(bug("[IconList] %s: DOWN: using start_X %d, start_Y %d\n", __PRETTY_FUNCTION__, start_X, start_Y));
3912 #endif
3915 if (!(message->imsg->Qualifier & IEQUALIFIER_LSHIFT) && ((data->icld_SelectionLastClicked)&&(data->icld_SelectionLastClicked != active_entry)))
3917 #if defined(DEBUG_ILC_KEYEVENTS)
3918 D(bug("[IconList] %s: DOWN: Clearing selected icons ..\n", __PRETTY_FUNCTION__));
3919 #endif
3920 DoMethod(obj, MUIM_IconList_UnselectAll);
3923 #if defined(DEBUG_ILC_KEYEVENTS)
3924 D(bug("[IconList] %s: DOWN: active = 0x%p, next = 0x%p\n", __PRETTY_FUNCTION__, active_entry, entry_next));
3925 #endif
3926 if (!(active_entry))
3928 // If nothing is selected we will use the First visible icon ..
3929 active_entry = Node_FirstVisible(&data->icld_IconList);
3930 start_X = active_entry->ie_IconX;
3931 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
3933 if (active_entry->ie_AreaWidth < data->icld_IconAreaLargestWidth)
3934 start_X = start_X - ((data->icld_IconAreaLargestWidth - active_entry->ie_AreaWidth)/2);
3936 start_Y = active_entry->ie_IconY;
3939 while (active_entry != NULL)
3941 #if defined(DEBUG_ILC_KEYEVENTS)
3942 D(bug("[IconList] %s: DOWN: Checking active @ 0x%p\n", __PRETTY_FUNCTION__, active_entry));
3943 #endif
3944 if (data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL)
3946 if (active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE)
3947 break;
3949 else
3951 active_X = active_entry->ie_IconX;
3953 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
3955 if (active_entry->ie_AreaWidth < data->icld_IconAreaLargestWidth)
3956 x_diff = ((data->icld_IconAreaLargestWidth - active_entry->ie_AreaWidth)/2);
3958 active_Y = active_entry->ie_IconY;
3960 if (start_entry)
3962 if (entry_next)
3964 if ((active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE) &&
3965 (active_Y > start_Y) &&
3966 (((active_X - x_diff) >= start_X ) &&
3967 ((active_X - x_diff) <= (start_X + start_entry->ie_AreaWidth + (x_diff*2)))))
3969 #if defined(DEBUG_ILC_KEYEVENTS)
3970 D(bug("[IconList] %s: DOWN: (A) entry 0x%p matches\n", __PRETTY_FUNCTION__, active_entry));
3971 #endif
3972 break;
3974 else if (active_entry == (struct IconEntry *)GetTail(&data->icld_IconList))
3976 #if defined(DEBUG_ILC_KEYEVENTS)
3977 D(bug("[IconList] %s: DOWN: (A) reached list end .. starting at the beginng ..\n", __PRETTY_FUNCTION__));
3978 #endif
3979 start_X = entry_next->ie_IconX;
3980 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
3982 if (entry_next->ie_AreaWidth < data->icld_IconAreaLargestWidth)
3983 start_X = start_X - ((data->icld_IconAreaLargestWidth - entry_next->ie_AreaWidth)/2);
3986 if ((entry_next = (struct IconEntry *)Node_NextVisible(entry_next)))
3988 if (entry_next->ie_IconX < start_X)
3989 entry_next = NULL;
3990 else
3992 next_X = entry_next->ie_IconX;
3993 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
3995 if (entry_next->ie_AreaWidth < data->icld_IconAreaLargestWidth)
3996 next_X = next_X + ((data->icld_IconAreaLargestWidth - entry_next->ie_AreaWidth)/2);
4000 start_Y = 0;
4001 #if defined(DEBUG_ILC_KEYEVENTS)
4002 D(bug("[IconList] %s: DOWN: (A) startx = %d, start_Y = %d, next_X = %d, entry_next @ 0x%p\n", __PRETTY_FUNCTION__, start_X, start_Y, next_X, entry_next));
4003 #endif
4004 active_entry = Node_FirstVisible(&data->icld_IconList);
4007 else
4009 if ((active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE) &&
4010 (active_Y > start_Y) &&
4011 (active_X > start_X - 1))
4013 #if defined(DEBUG_ILC_KEYEVENTS)
4014 D(bug("[IconList] %s: DOWN: (B) entry 0x%p matches\n", __PRETTY_FUNCTION__, active_entry));
4015 #endif
4016 break;
4020 else
4022 if (active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE)
4024 #if defined(DEBUG_ILC_KEYEVENTS)
4025 D(bug("[IconList] %s: DOWN: (C) entry 0x%p matches\n", __PRETTY_FUNCTION__, active_entry));
4026 #endif
4027 break;
4031 active_entry = (struct IconEntry *)GetSucc(&active_entry->ie_IconNode);
4034 if (!(active_entry))
4036 #if defined(DEBUG_ILC_KEYEVENTS)
4037 D(bug("[IconList] %s: DOWN: No Next DOWN Node - Getting first visable icon ..\n", __PRETTY_FUNCTION__));
4038 #endif
4039 /* We didnt find a "next DOWN" icon so just use the first visible */
4040 active_entry = Node_FirstVisible(&data->icld_IconList);
4043 if (active_entry)
4045 if (!(active_entry->ie_Flags & ICONENTRY_FLAG_FOCUS))
4047 active_entry->ie_Flags |= ICONENTRY_FLAG_FOCUS;
4048 data->icld_UpdateMode = UPDATE_SINGLEICON;
4049 data->update_icon = active_entry;
4050 MUI_Redraw(obj, MADF_DRAWUPDATE);
4053 data->icld_FocusIcon = active_entry;
4054 break;
4056 case RAWKEY_LEFT:
4057 rawkey_handled = TRUE;
4059 #if defined(DEBUG_ILC_KEYEVENTS)
4060 D(bug("[IconList] %s: RAWKEY_LEFT\n", __PRETTY_FUNCTION__));
4061 #endif
4062 if (data->icld_FocusIcon)
4064 start_entry = data->icld_FocusIcon;
4065 #if defined(DEBUG_ILC_KEYEVENTS)
4066 D(bug("[IconList] %s: LEFT: Clearing existing focused icon @ 0x%p\n", __PRETTY_FUNCTION__, start_entry));
4067 #endif
4069 start_entry->ie_Flags &= ~ICONENTRY_FLAG_FOCUS;
4070 data->icld_UpdateMode = UPDATE_SINGLEICON;
4071 data->update_icon = start_entry;
4072 MUI_Redraw(obj, MADF_DRAWUPDATE);
4074 start_X = start_entry->ie_IconX;
4075 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
4077 if (start_entry->ie_AreaWidth < data->icld_IconAreaLargestWidth)
4078 start_X = start_X - ((data->icld_IconAreaLargestWidth - start_entry->ie_AreaWidth)/2);
4080 start_Y = start_entry->ie_IconY;
4082 #if defined(DEBUG_ILC_KEYEVENTS)
4083 D(bug("[IconList] %s: LEFT: start_X %d, start_Y %d\n", __PRETTY_FUNCTION__, start_X, start_Y));
4084 #endif
4086 if (!(active_entry = Node_NextVisible(start_entry)) && (!(data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL)))
4088 active_entry = (struct IconEntry *)GetHead(&data->icld_IconList);
4089 #if defined(DEBUG_ILC_KEYEVENTS)
4090 D(bug("[IconList] %s: LEFT: Start at the beginning (Active @ 0x%p) using icon X + Width\n", __PRETTY_FUNCTION__, active_entry));
4091 #endif
4092 start_X = start_X + start_entry->ie_AreaWidth;
4093 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
4095 if (start_entry->ie_AreaWidth < data->icld_IconAreaLargestWidth)
4096 start_X = start_X + ((data->icld_IconAreaLargestWidth - start_entry->ie_AreaWidth)/2);
4099 start_Y = 0;
4100 entry_next = NULL;
4102 else if (active_entry && (!(data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL)))
4104 #if defined(DEBUG_ILC_KEYEVENTS)
4105 D(bug("[IconList] %s: LEFT: Active @ 0x%p, X %d\n", __PRETTY_FUNCTION__, active_entry, active_entry->ie_IconX));
4106 #endif
4107 if ((entry_next = Node_NextVisible(start_entry)))
4109 #if defined(DEBUG_ILC_KEYEVENTS)
4110 D(bug("[IconList] %s: LEFT: Next @ 0x%p, X %d\n", __PRETTY_FUNCTION__, entry_next, entry_next->ie_IconX));
4111 #endif
4113 if (entry_next->ie_IconX < start_X)
4114 entry_next = NULL;
4115 else
4117 next_X = entry_next->ie_IconX;
4118 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
4120 if (entry_next->ie_AreaWidth < data->icld_IconAreaLargestWidth)
4121 next_X = next_X - ((data->icld_IconAreaLargestWidth - entry_next->ie_AreaWidth)/2);
4126 #if defined(DEBUG_ILC_KEYEVENTS)
4127 D(bug("[IconList] %s: LEFT: using start_X %d, start_Y %d\n", __PRETTY_FUNCTION__, start_X, start_Y));
4128 #endif
4131 if (!(message->imsg->Qualifier & IEQUALIFIER_LSHIFT) && ((data->icld_SelectionLastClicked)&&(data->icld_SelectionLastClicked != active_entry)))
4133 #if defined(DEBUG_ILC_KEYEVENTS)
4134 D(bug("[IconList] %s: LEFT: Clearing selected icons ..\n", __PRETTY_FUNCTION__));
4135 #endif
4136 DoMethod(obj, MUIM_IconList_UnselectAll);
4139 #if defined(DEBUG_ILC_KEYEVENTS)
4140 D(bug("[IconList] %s: LEFT: active = 0x%p, next = 0x%p\n", __PRETTY_FUNCTION__, active_entry, entry_next));
4141 #endif
4143 if (!(active_entry))
4145 active_entry = (struct IconEntry *)GetHead(&data->icld_IconList);
4148 while (active_entry != NULL)
4150 #if defined(DEBUG_ILC_KEYEVENTS)
4151 D(bug("[IconList] %s: LEFT: Checking active @ 0x%p\n", __PRETTY_FUNCTION__, active_entry));
4152 #endif
4153 if (data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL)
4155 if (active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE)
4156 break;
4158 else
4160 LONG active_entry_X = active_entry->ie_IconX;
4161 LONG active_entry_Y;
4162 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
4164 if (active_entry->ie_AreaWidth < data->icld_IconAreaLargestWidth)
4165 active_entry_X = active_entry_X - ((data->icld_IconAreaLargestWidth - active_entry->ie_AreaWidth)/2);
4167 active_entry_Y = active_entry->ie_IconY;
4169 if (start_entry)
4171 if (entry_next)
4173 if ((active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE) &&
4174 (active_entry_Y > start_Y) &&
4175 ((active_entry_X > start_X - 1) &&
4176 (active_entry_X < next_X)))
4178 #if defined(DEBUG_ILC_KEYEVENTS)
4179 D(bug("[IconList] %s: LEFT: (A) entry 0x%p matches\n", __PRETTY_FUNCTION__, active_entry));
4180 #endif
4181 break;
4183 else if (active_entry == (struct IconEntry *)GetTail(&data->icld_IconList))
4185 #if defined(DEBUG_ILC_KEYEVENTS)
4186 D(bug("[IconList] %s: LEFT: (A) reached list end .. starting at the beginng ..\n", __PRETTY_FUNCTION__));
4187 #endif
4188 start_X = entry_next->ie_IconX;
4189 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
4191 if (entry_next->ie_AreaWidth < data->icld_IconAreaLargestWidth)
4192 start_X = start_X - ((data->icld_IconAreaLargestWidth - entry_next->ie_AreaWidth)/2);
4195 if ((entry_next = Node_NextVisible(entry_next)))
4197 if (entry_next->ie_IconX < start_X)
4198 entry_next = NULL;
4199 else
4201 next_X = entry_next->ie_IconX;
4202 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
4204 if (entry_next->ie_AreaWidth < data->icld_IconAreaLargestWidth)
4205 next_X = next_X + ((data->icld_IconAreaLargestWidth - entry_next->ie_AreaWidth)/2);
4209 start_Y = 0;
4210 #if defined(DEBUG_ILC_KEYEVENTS)
4211 D(bug("[IconList] %s: LEFT: (A) startx = %d, start_Y = %d, next_X = %d, entry_next @ 0x%p\n", __PRETTY_FUNCTION__, start_X, start_Y, next_X, entry_next));
4212 #endif
4213 active_entry = (struct IconEntry *)GetHead(&data->icld_IconList);
4216 else
4218 if ((active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE) &&
4219 (active_entry_Y > start_Y) &&
4220 (active_entry_X > start_X - 1))
4222 #if defined(DEBUG_ILC_KEYEVENTS)
4223 D(bug("[IconList] %s: LEFT: (B) entry 0x%p matches\n", __PRETTY_FUNCTION__, active_entry));
4224 #endif
4225 break;
4229 else
4231 if (active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE)
4233 #if defined(DEBUG_ILC_KEYEVENTS)
4234 D(bug("[IconList] %s: LEFT: (C) entry 0x%p matches\n", __PRETTY_FUNCTION__, active_entry));
4235 #endif
4236 break;
4240 active_entry = (struct IconEntry *)GetSucc(&active_entry->ie_IconNode);
4243 if (!(active_entry))
4245 #if defined(DEBUG_ILC_KEYEVENTS)
4246 D(bug("[IconList] %s: LEFT: No Next LEFT Node - Getting first visable icon ..\n", __PRETTY_FUNCTION__));
4247 #endif
4248 /* We didnt find a "next LEFT" icon so just use the last visible */
4249 active_entry = (struct IconEntry *)GetHead(&data->icld_IconList);
4250 while ((active_entry != NULL) &&(!(active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE)))
4252 active_entry = (struct IconEntry *)GetSucc(&active_entry->ie_IconNode);
4256 if (active_entry)
4258 if (!(active_entry->ie_Flags & ICONENTRY_FLAG_FOCUS))
4260 active_entry->ie_Flags |= ICONENTRY_FLAG_FOCUS;
4261 data->icld_UpdateMode = UPDATE_SINGLEICON;
4262 data->update_icon = active_entry;
4263 MUI_Redraw(obj, MADF_DRAWUPDATE);
4266 data->icld_FocusIcon = active_entry;
4267 break;
4269 case RAWKEY_RIGHT:
4270 rawkey_handled = TRUE;
4272 #if defined(DEBUG_ILC_KEYEVENTS)
4273 D(bug("[IconList] %s: RAWKEY_RIGHT\n", __PRETTY_FUNCTION__));
4274 #endif
4276 if (data->icld_FocusIcon)
4278 start_entry = data->icld_FocusIcon;
4279 #if defined(DEBUG_ILC_KEYEVENTS)
4280 D(bug("[IconList] %s: RIGHT: Clearing existing focused icon @ 0x%p\n", __PRETTY_FUNCTION__, start_entry));
4281 #endif
4282 start_entry->ie_Flags &= ~ICONENTRY_FLAG_FOCUS;
4283 data->icld_UpdateMode = UPDATE_SINGLEICON;
4284 data->update_icon = start_entry;
4285 MUI_Redraw(obj, MADF_DRAWUPDATE);
4287 start_X = start_entry->ie_IconX;
4288 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
4290 if (start_entry->ie_AreaWidth < data->icld_IconAreaLargestWidth)
4291 start_X = start_X - ((data->icld_IconAreaLargestWidth - start_entry->ie_AreaWidth)/2);
4293 start_Y = start_entry->ie_IconY;
4295 #if defined(DEBUG_ILC_KEYEVENTS)
4296 D(bug("[IconList] %s: RIGHT: start_X %d, start_Y %d\n", __PRETTY_FUNCTION__, start_X, start_Y));
4297 #endif
4298 if (!(active_entry = Node_NextVisible(start_entry)) && (!(data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL)))
4300 active_entry = (struct IconEntry *)GetHead(&data->icld_IconList);
4301 #if defined(DEBUG_ILC_KEYEVENTS)
4302 D(bug("[IconList] %s: RIGHT: Start at the beginning (Active @ 0x%p) using icon X + Width\n", __PRETTY_FUNCTION__, active_entry));
4303 #endif
4304 start_X = 0;
4305 start_Y = start_Y + start_entry->ie_AreaHeight;
4306 entry_next = NULL;
4308 else if (active_entry && (data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL))
4310 #if defined(DEBUG_ILC_KEYEVENTS)
4311 D(bug("[IconList] %s: RIGHT: Active @ 0x%p, X %d\n", __PRETTY_FUNCTION__, active_entry, active_entry->ie_IconX));
4312 #endif
4313 if ((entry_next = Node_NextVisible(start_entry)))
4315 #if defined(DEBUG_ILC_KEYEVENTS)
4316 D(bug("[IconList] %s: RIGHT: Next @ 0x%p, X %d\n", __PRETTY_FUNCTION__, entry_next, entry_next->ie_IconX));
4317 #endif
4319 if (entry_next->ie_IconY < start_Y)
4320 entry_next = NULL;
4321 else
4322 next_Y = entry_next->ie_IconY;
4325 #if defined(DEBUG_ILC_KEYEVENTS)
4326 D(bug("[IconList] %s: RIGHT: using start_X %d, start_Y %d\n", __PRETTY_FUNCTION__, start_X, start_Y));
4327 #endif
4330 if (!(message->imsg->Qualifier & IEQUALIFIER_LSHIFT) && ((data->icld_SelectionLastClicked)&&(data->icld_SelectionLastClicked != active_entry)))
4332 #if defined(DEBUG_ILC_KEYEVENTS)
4333 D(bug("[IconList] %s: RIGHT: Clearing selected icons ..\n", __PRETTY_FUNCTION__));
4334 #endif
4335 DoMethod(obj, MUIM_IconList_UnselectAll);
4338 #if defined(DEBUG_ILC_KEYEVENTS)
4339 D(bug("[IconList] %s: RIGHT: active = 0x%p, next = 0x%p\n", __PRETTY_FUNCTION__, active_entry, entry_next));
4340 #endif
4342 if (!(active_entry))
4344 active_entry = (struct IconEntry *)GetHead(&data->icld_IconList);
4347 while (active_entry != NULL)
4349 #if defined(DEBUG_ILC_KEYEVENTS)
4350 D(bug("[IconList] %s: RIGHT: Checking active @ 0x%p\n", __PRETTY_FUNCTION__, active_entry));
4351 #endif
4352 if (!(data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL))
4354 if (active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE)
4355 break;
4357 else
4359 LONG active_entry_X = active_entry->ie_IconX;
4360 LONG active_entry_Y;
4361 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
4363 if (active_entry->ie_AreaWidth < data->icld_IconAreaLargestWidth)
4364 active_entry_X = active_entry_X - ((data->icld_IconAreaLargestWidth - active_entry->ie_AreaWidth)/2);
4366 active_entry_Y = active_entry->ie_IconY;
4368 if (start_entry)
4370 if (entry_next)
4372 if ((active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE) &&
4373 (active_entry_X > start_X) &&
4374 ((active_entry_Y > start_Y - 1) &&
4375 (active_entry_Y < next_Y)))
4377 #if defined(DEBUG_ILC_KEYEVENTS)
4378 D(bug("[IconList] %s: RIGHT: (A) entry 0x%p matches\n", __PRETTY_FUNCTION__, active_entry));
4379 #endif
4380 break;
4382 else if (active_entry == (struct IconEntry *)GetTail(&data->icld_IconList))
4384 #if defined(DEBUG_ILC_KEYEVENTS)
4385 D(bug("[IconList] %s: RIGHT: (A) reached list end .. starting at the beginng ..\n", __PRETTY_FUNCTION__));
4386 #endif
4387 start_Y = entry_next->ie_IconY;
4389 if ((entry_next = Node_NextVisible(entry_next)))
4391 if (entry_next->ie_IconY < start_Y)
4392 entry_next = NULL;
4393 else
4395 next_Y = entry_next->ie_IconY;
4398 start_Y = 0;
4399 #if defined(DEBUG_ILC_KEYEVENTS)
4400 D(bug("[IconList] %s: RIGHT: (A) startx = %d, start_Y = %d, next_X = %d, entry_next @ 0x%p\n", __PRETTY_FUNCTION__, start_X, start_Y, next_X, entry_next));
4401 #endif
4402 active_entry = (struct IconEntry *)GetHead(&data->icld_IconList);
4405 else
4407 if ((active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE) &&
4408 (active_entry_X > start_X) &&
4409 (active_entry_Y > start_Y - 1))
4411 #if defined(DEBUG_ILC_KEYEVENTS)
4412 D(bug("[IconList] %s: RIGHT: (B) entry 0x%p matches\n", __PRETTY_FUNCTION__, active_entry));
4413 #endif
4414 break;
4418 else
4420 if (active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE)
4422 #if defined(DEBUG_ILC_KEYEVENTS)
4423 D(bug("[IconList] %s: RIGHT: (C) entry 0x%p matches\n", __PRETTY_FUNCTION__, active_entry));
4424 #endif
4425 break;
4429 active_entry = (struct IconEntry *)GetSucc(&active_entry->ie_IconNode);
4432 if (!(active_entry))
4434 #if defined(DEBUG_ILC_KEYEVENTS)
4435 D(bug("[IconList] %s: RIGHT: No Next RIGHT Node - Getting first visable icon ..\n", __PRETTY_FUNCTION__));
4436 #endif
4437 /* We didnt find a "next RIGHT" icon so just use the first visible */
4438 active_entry = (struct IconEntry *)GetHead(&data->icld_IconList);
4439 while ((active_entry != NULL) &&(!(active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE)))
4441 active_entry = (struct IconEntry *)GetSucc(&active_entry->ie_IconNode);
4445 if (active_entry)
4447 if (!(active_entry->ie_Flags & ICONENTRY_FLAG_FOCUS))
4449 active_entry->ie_Flags |= ICONENTRY_FLAG_FOCUS;
4450 data->icld_UpdateMode = UPDATE_SINGLEICON;
4451 data->update_icon = active_entry;
4452 MUI_Redraw(obj, MADF_DRAWUPDATE);
4455 data->icld_FocusIcon = active_entry;
4456 break;
4458 case RAWKEY_HOME:
4459 rawkey_handled = TRUE;
4461 #if defined(DEBUG_ILC_KEYEVENTS)
4462 D(bug("[IconList] %s: RAWKEY_HOME\n", __PRETTY_FUNCTION__));
4463 #endif
4465 if (data->icld_FocusIcon)
4467 data->icld_FocusIcon->ie_Flags &= ~ICONENTRY_FLAG_FOCUS;
4468 data->icld_UpdateMode = UPDATE_SINGLEICON;
4469 data->update_icon = data->icld_FocusIcon;
4470 MUI_Redraw(obj, MADF_DRAWUPDATE);
4473 active_entry = Node_FirstVisible(&data->icld_IconList);
4475 if ((active_entry) && (!(active_entry->ie_Flags & ICONENTRY_FLAG_FOCUS)))
4477 active_entry->ie_Flags |= ICONENTRY_FLAG_FOCUS;
4478 data->icld_UpdateMode = UPDATE_SINGLEICON;
4479 data->update_icon = active_entry;
4480 MUI_Redraw(obj, MADF_DRAWUPDATE);
4482 data->icld_FocusIcon = active_entry;
4483 break;
4485 case RAWKEY_END:
4486 rawkey_handled = TRUE;
4488 #if defined(DEBUG_ILC_KEYEVENTS)
4489 D(bug("[IconList] %s: RAWKEY_END\n", __PRETTY_FUNCTION__));
4490 #endif
4492 if (data->icld_FocusIcon)
4494 data->icld_FocusIcon->ie_Flags &= ~ICONENTRY_FLAG_FOCUS;
4495 data->icld_UpdateMode = UPDATE_SINGLEICON;
4496 data->update_icon = data->icld_FocusIcon;
4497 MUI_Redraw(obj, MADF_DRAWUPDATE);
4500 active_entry = Node_LastVisible(&data->icld_IconList);
4502 if ((active_entry) && (!(active_entry->ie_Flags & ICONENTRY_FLAG_FOCUS)))
4504 active_entry->ie_Flags |= ICONENTRY_FLAG_FOCUS;
4505 data->icld_UpdateMode = UPDATE_SINGLEICON;
4506 data->update_icon = active_entry;
4507 MUI_Redraw(obj, MADF_DRAWUPDATE);
4509 data->icld_FocusIcon = active_entry;
4510 break;
4513 if (rawkey_handled) return MUI_EventHandlerRC_Eat;
4515 break;
4517 case IDCMP_MOUSEBUTTONS:
4518 #if defined(DEBUG_ILC_EVENTS)
4519 D(bug("[IconList] %s: IDCMP_MOUSEBUTTONS\n", __PRETTY_FUNCTION__));
4520 #endif
4521 if (message->imsg->Code == SELECTDOWN)
4523 /* check if mouse pressed on iconlist area */
4524 if (mx >= 0 && mx < _width(obj) && my >= 0 && my < _height(obj))
4526 struct IconEntry *node = NULL;
4527 struct IconEntry *new_selected = NULL;
4528 struct Rectangle rect;
4530 // int selections = 0;
4531 BOOL icon_doubleclicked;
4533 /* check if clicked on icon */
4534 #if defined(__AROS__)
4535 ForeachNode(&data->icld_IconList, node)
4536 #else
4537 Foreach_Node(&data->icld_IconList, node);
4538 #endif
4540 if (node->ie_Flags & ICONENTRY_FLAG_VISIBLE)
4542 BOOL update_icon = FALSE;
4544 rect.MinX = node->ie_IconX;
4545 rect.MaxX = node->ie_IconX + node->ie_AreaWidth - 1;
4546 rect.MinY = node->ie_IconY;
4547 rect.MaxY = node->ie_IconY + node->ie_AreaHeight - 1;
4549 if ((data->icld__Option_IconListMode == ICON_LISTMODE_GRID) &&
4550 (node->ie_AreaWidth < data->icld_IconAreaLargestWidth))
4552 rect.MinX += ((data->icld_IconAreaLargestWidth - node->ie_AreaWidth)/2);
4553 rect.MaxX += ((data->icld_IconAreaLargestWidth - node->ie_AreaWidth)/2);
4556 if ((((mx + data->icld_ViewX) >= rect.MinX) && ((mx + data->icld_ViewX) <= rect.MaxX )) &&
4557 (((my + data->icld_ViewY) >= rect.MinY) && ((my + data->icld_ViewY) <= rect.MaxY )) &&
4558 !new_selected)
4560 new_selected = node;
4561 #if defined(DEBUG_ILC_EVENTS)
4562 D(bug("[IconList] %s: Icon '%s' clicked on ..\n", __PRETTY_FUNCTION__, node->ie_IconListEntry.label));
4563 #endif
4566 if (node->ie_Flags & ICONENTRY_FLAG_SELECTED)
4568 if ((new_selected != node) &&
4569 (!(message->imsg->Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))))
4571 Remove(&node->ie_SelectionNode);
4572 node->ie_Flags &= ~ICONENTRY_FLAG_SELECTED;
4573 update_icon = TRUE;
4577 if ((node->ie_Flags & ICONENTRY_FLAG_FOCUS) && (new_selected != node))
4579 node->ie_Flags &= ~ICONENTRY_FLAG_FOCUS;
4580 update_icon = TRUE;
4583 if (update_icon)
4585 data->icld_UpdateMode = UPDATE_SINGLEICON;
4586 data->update_icon = node;
4587 MUI_Redraw(obj, MADF_DRAWUPDATE);
4588 #if defined(DEBUG_ILC_EVENTS)
4589 D(bug("[IconList] %s: Rendered icon '%s'\n", __PRETTY_FUNCTION__, node->ie_IconListEntry.label));
4590 #endif
4595 icon_doubleclicked = FALSE;
4597 if ((DoubleClick(data->last_secs, data->last_mics, message->imsg->Seconds, message->imsg->Micros)) && (data->icld_SelectionLastClicked == new_selected))
4599 #if defined(DEBUG_ILC_EVENTS)
4600 D(bug("[IconList] %s: Icon double-clicked\n", __PRETTY_FUNCTION__));
4601 #endif
4602 icon_doubleclicked = TRUE;
4605 if (new_selected == NULL)
4607 struct Window * thisWindow = NULL;
4608 #if defined(DEBUG_ILC_EVENTS) && defined(DEBUG_ILC_LASSO)
4609 D(bug("[IconList] %s: Starting Lasso\n", __PRETTY_FUNCTION__));
4610 #endif
4611 /* No icon clicked on ... Start Lasso-selection */
4612 data->icld_LassoActive = TRUE;
4613 if (!(message->imsg->Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT)))
4615 data->icld_SelectionLastClicked = NULL;
4616 data->icld_FocusIcon = NULL;
4618 data->icld_LassoRectangle.MinX = mx - data->view_rect.MinX + data->icld_ViewX;
4619 data->icld_LassoRectangle.MinY = my - data->view_rect.MinY + data->icld_ViewY;
4620 data->icld_LassoRectangle.MaxX = mx - data->view_rect.MinX + data->icld_ViewX;
4621 data->icld_LassoRectangle.MaxY = my - data->view_rect.MinY + data->icld_ViewY;
4623 /* Draw initial Lasso frame */
4624 IconList_InvertLassoOutlines(obj, &data->icld_LassoRectangle);
4626 GET(obj, MUIA_Window, &thisWindow);
4627 if (thisWindow)
4629 ModifyIDCMP(thisWindow, (thisWindow->IDCMPFlags|IDCMP_INTUITICKS));
4630 if (!(data->ehn.ehn_Events & IDCMP_INTUITICKS))
4632 DoMethod(_win(obj), MUIM_Window_RemEventHandler, (IPTR)&data->ehn);
4633 data->ehn.ehn_Events |= IDCMP_INTUITICKS;
4634 DoMethod(_win(obj), MUIM_Window_AddEventHandler, (IPTR)&data->ehn);
4638 else
4640 struct IconEntry *update_icon = NULL;
4642 data->icld_LassoActive = FALSE;
4644 if (!(new_selected->ie_Flags & ICONENTRY_FLAG_SELECTED))
4646 AddTail(&data->icld_SelectionList, &new_selected->ie_SelectionNode);
4647 new_selected->ie_Flags |= ICONENTRY_FLAG_SELECTED;
4648 update_icon = new_selected;
4650 if (!(new_selected->ie_Flags & ICONENTRY_FLAG_FOCUS))
4652 new_selected->ie_Flags |= ICONENTRY_FLAG_FOCUS;
4653 update_icon = new_selected;
4654 data->icld_FocusIcon = new_selected;
4657 else if ((icon_doubleclicked == FALSE) && (message->imsg->Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT)))
4659 Remove(&new_selected->ie_SelectionNode);
4660 new_selected->ie_Flags &= ~ICONENTRY_FLAG_SELECTED;
4661 update_icon = new_selected;
4662 new_selected = NULL;
4665 if (update_icon != NULL)
4667 data->icld_UpdateMode = UPDATE_SINGLEICON;
4668 data->update_icon = update_icon;
4669 MUI_Redraw(obj, MADF_DRAWUPDATE);
4670 #if defined(DEBUG_ILC_EVENTS)
4671 D(bug("[IconList] %s: Rendered 'new_selected' icon '%s'\n", __PRETTY_FUNCTION__, update_icon->ie_IconListEntry.label));
4672 #endif
4676 data->icld_ClickEvent.shift = !!(message->imsg->Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT));
4677 data->icld_ClickEvent.entry = new_selected ? &new_selected->ie_IconListEntry : NULL;
4678 SET(obj, MUIA_IconList_Clicked, (IPTR)&data->icld_ClickEvent);
4680 if (icon_doubleclicked)
4682 SET(obj, MUIA_IconList_DoubleClick, TRUE);
4684 else if (!data->mouse_pressed)
4686 data->last_secs = message->imsg->Seconds;
4687 data->last_mics = message->imsg->Micros;
4689 /* After a double click you often open a new window
4690 * and since Zune doesn't not support the faking
4691 * of SELECTUP events only change the Events
4692 * if not doubleclicked */
4694 data->mouse_pressed |= LEFT_BUTTON;
4696 if (!(data->ehn.ehn_Events & IDCMP_MOUSEMOVE))
4698 DoMethod(_win(obj), MUIM_Window_RemEventHandler, (IPTR)&data->ehn);
4699 data->ehn.ehn_Events |= IDCMP_MOUSEMOVE;
4700 DoMethod(_win(obj), MUIM_Window_AddEventHandler, (IPTR)&data->ehn);
4704 data->icld_SelectionLastClicked = new_selected;
4706 data->click_x = mx;
4707 data->click_y = my;
4709 SET(obj, MUIA_IconList_SelectionChanged, TRUE);
4711 return MUI_EventHandlerRC_Eat;
4714 else if (message->imsg->Code == MIDDLEDOWN)
4716 if (!data->mouse_pressed)
4718 data->mouse_pressed |= MIDDLE_BUTTON;
4720 data->click_x = data->icld_ViewX + mx;
4721 data->click_y = data->icld_ViewY + my;
4723 if (!(data->ehn.ehn_Events & IDCMP_MOUSEMOVE))
4725 DoMethod(_win(obj), MUIM_Window_RemEventHandler, (IPTR)&data->ehn);
4726 data->ehn.ehn_Events |= IDCMP_MOUSEMOVE;
4727 DoMethod(_win(obj), MUIM_Window_AddEventHandler, (IPTR)&data->ehn);
4731 else
4733 if (message->imsg->Code == SELECTUP)
4735 if (data->icld_LassoActive == TRUE)
4737 #if defined(DEBUG_ILC_EVENTS) && defined(DEBUG_ILC_LASSO)
4738 D(bug("[IconList] %s: Removing Lasso\n", __PRETTY_FUNCTION__));
4739 #endif
4740 // End Lasso-selection
4741 struct Rectangle old_lasso;
4742 struct IconEntry *node = NULL;
4743 struct Window *thisWindow = NULL;
4745 GET(obj, MUIA_Window, &thisWindow);
4746 if (thisWindow)
4748 ModifyIDCMP(thisWindow, (thisWindow->IDCMPFlags & ~(IDCMP_INTUITICKS)));
4749 if ((data->ehn.ehn_Events & IDCMP_INTUITICKS))
4751 DoMethod(_win(obj), MUIM_Window_RemEventHandler, (IPTR)&data->ehn);
4752 data->ehn.ehn_Events &= ~IDCMP_INTUITICKS;
4753 DoMethod(_win(obj), MUIM_Window_AddEventHandler, (IPTR)&data->ehn);
4756 //Clear Lasso Frame..
4757 GetAbsoluteLassoRect(data, &old_lasso);
4758 IconList_InvertLassoOutlines(obj, &old_lasso);
4760 data->icld_LassoActive = FALSE;
4762 //Remove Lasso flag from affected icons..
4763 #if defined(__AROS__)
4764 ForeachNode(&data->icld_IconList, node)
4765 #else
4766 Foreach_Node(&data->icld_IconList, node);
4767 #endif
4769 if (node->ie_Flags & ICONENTRY_FLAG_LASSO)
4771 node->ie_Flags &= ~ICONENTRY_FLAG_LASSO;
4774 SET(obj, MUIA_IconList_SelectionChanged, TRUE);
4777 data->mouse_pressed &= ~LEFT_BUTTON;
4780 if (message->imsg->Code == MIDDLEUP)
4782 data->mouse_pressed &= ~MIDDLE_BUTTON;
4785 if ((data->ehn.ehn_Events & IDCMP_MOUSEMOVE) && !data->mouse_pressed)
4787 DoMethod(_win(obj),MUIM_Window_RemEventHandler, (IPTR)&data->ehn);
4788 data->ehn.ehn_Events &= ~IDCMP_MOUSEMOVE;
4789 DoMethod(_win(obj),MUIM_Window_AddEventHandler, (IPTR)&data->ehn);
4792 break;
4794 case IDCMP_INTUITICKS:
4796 #if defined(DEBUG_ILC_EVENTS)
4797 D(bug("[IconList] %s: IDCMP_INTUITICKS (%d, %d)\n", __PRETTY_FUNCTION__, mx, my));
4798 #endif
4799 if ((data->icld_LassoActive == FALSE)||(!(data->mouse_pressed & LEFT_BUTTON)))
4801 break;
4803 if (((mx >= 0) && (mx <= _mwidth(obj))) &&
4804 ((my >= 0) && (my <= _mheight(obj))))
4805 break;
4808 case IDCMP_MOUSEMOVE:
4809 #if defined(DEBUG_ILC_EVENTS)
4810 D(bug("[IconList] %s: IDCMP_MOUSEMOVE\n", __PRETTY_FUNCTION__));
4811 #endif
4812 if (data->mouse_pressed & LEFT_BUTTON)
4814 LONG move_x = mx;
4815 LONG move_y = my;
4817 if (data->icld_SelectionLastClicked && (data->icld_LassoActive == FALSE) &&
4818 ((abs(move_x - data->click_x) >= 2) || (abs(move_y - data->click_y) >= 2)))
4820 // Icon(s) being dragged ....
4821 DoMethod(_win(obj),MUIM_Window_RemEventHandler, (IPTR)&data->ehn);
4822 data->ehn.ehn_Events &= ~IDCMP_MOUSEMOVE;
4823 DoMethod(_win(obj),MUIM_Window_AddEventHandler, (IPTR)&data->ehn);
4825 data->mouse_pressed &= ~LEFT_BUTTON;
4827 data->touch_x = move_x + data->icld_ViewX - data->icld_SelectionLastClicked->ie_IconX;
4828 data->touch_y = move_y + data->icld_ViewY - data->icld_SelectionLastClicked->ie_IconY;
4829 DoMethod(obj,MUIM_DoDrag, data->touch_x, data->touch_y, 0);
4831 else if (data->icld_LassoActive == TRUE)
4833 #if defined(DEBUG_ILC_EVENTS) && defined(DEBUG_ILC_LASSO)
4834 D(bug("[IconList] %s: Update Lasso\n", __PRETTY_FUNCTION__));
4835 #endif
4836 //Lasso active ..
4837 struct Rectangle new_lasso,
4838 old_lasso;
4839 struct Rectangle iconrect;
4841 struct IconEntry *node = NULL;
4842 // struct IconEntry *new_selected = NULL;
4844 /* Remove previous Lasso frame */
4845 GetAbsoluteLassoRect(data, &old_lasso);
4846 IconList_InvertLassoOutlines(obj, &old_lasso);
4848 /* if the mouse leaves our visible area scroll the view */
4849 if (mx < 0 || mx >= _mwidth(obj) || my < 0 || my >= _mheight(obj))
4851 LONG newleft = data->icld_ViewX;
4852 LONG newtop = data->icld_ViewY;
4854 if (mx >= _mwidth(obj)) newleft += (mx - _mwidth(obj));
4855 else if (mx < 0) newleft += mx;
4856 if (my >= _mheight(obj)) newtop += (my - _mheight(obj));
4857 else if (my < 0) newtop += my;
4859 if (newleft + _mwidth(obj) > data->icld_AreaWidth) newleft = data->icld_AreaWidth - _mwidth(obj);
4860 if (newleft < 0) newleft = 0;
4862 if (newtop + _mheight(obj) > data->icld_AreaHeight) newtop = data->icld_AreaHeight - _mheight(obj);
4863 if (newtop < 0) newtop = 0;
4865 if ((newleft != data->icld_ViewX) || (newtop != data->icld_ViewY))
4867 SetAttrs(obj, MUIA_Virtgroup_Left, newleft, MUIA_Virtgroup_Top, newtop, TAG_DONE);
4871 /* update Lasso coordinates */
4872 data->icld_LassoRectangle.MaxX = mx - data->view_rect.MinX + data->icld_ViewX;
4873 data->icld_LassoRectangle.MaxY = my - data->view_rect.MinY + data->icld_ViewY;
4875 /* get absolute Lasso coordinates */
4876 GetAbsoluteLassoRect(data, &new_lasso);
4878 #if defined(__AROS__)
4879 ForeachNode(&data->icld_IconList, node)
4880 #else
4881 Foreach_Node(&data->icld_IconList, node);
4882 #endif
4884 IPTR update_icon = (IPTR)NULL;
4886 if (node->ie_Flags & ICONENTRY_FLAG_VISIBLE)
4888 iconrect.MinX = node->ie_IconX;
4889 iconrect.MaxX = node->ie_IconX + node->ie_AreaWidth - 1;
4890 iconrect.MinY = node->ie_IconY;
4891 iconrect.MaxY = node->ie_IconY + node->ie_AreaHeight - 1;
4892 if ((data->icld__Option_IconListMode == ICON_LISTMODE_GRID) &&
4893 (node->ie_AreaWidth < data->icld_IconAreaLargestWidth))
4895 iconrect.MinX += ((data->icld_IconAreaLargestWidth - node->ie_AreaWidth)/2);
4896 iconrect.MaxX += ((data->icld_IconAreaLargestWidth - node->ie_AreaWidth)/2);
4899 if ((((new_lasso.MaxX + data->icld_ViewX) >= iconrect.MinX) && ((new_lasso.MinX + data->icld_ViewX) <= iconrect.MaxX)) &&
4900 (((new_lasso.MaxY + data->icld_ViewY) >= iconrect.MinY) && ((new_lasso.MinY + data->icld_ViewY) <= iconrect.MaxY)))
4902 //Icon is inside our lasso ..
4903 if (!(node->ie_Flags & ICONENTRY_FLAG_LASSO))
4905 /* check if icon was already selected before */
4906 if (node->ie_Flags & ICONENTRY_FLAG_SELECTED)
4908 Remove(&node->ie_SelectionNode);
4909 node->ie_Flags &= ~ICONENTRY_FLAG_SELECTED;
4911 else
4913 AddTail(&data->icld_SelectionList, &node->ie_SelectionNode);
4914 node->ie_Flags |= ICONENTRY_FLAG_SELECTED;
4916 node->ie_Flags |= ICONENTRY_FLAG_LASSO;
4917 update_icon = (IPTR)node;
4920 else if (node->ie_Flags & ICONENTRY_FLAG_LASSO)
4922 //Icon is no longer inside our lasso - revert its selected state
4923 if (node->ie_Flags & ICONENTRY_FLAG_SELECTED)
4925 Remove(&node->ie_SelectionNode);
4926 node->ie_Flags &= ~ICONENTRY_FLAG_SELECTED;
4928 else
4930 AddTail(&data->icld_SelectionList, &node->ie_SelectionNode);
4931 node->ie_Flags |= ICONENTRY_FLAG_SELECTED;
4933 node->ie_Flags &= ~ICONENTRY_FLAG_LASSO;
4934 update_icon = (IPTR)node;
4937 if (update_icon)
4939 data->icld_UpdateMode = UPDATE_SINGLEICON;
4940 data->update_icon = (struct IconEntry *)update_icon;
4941 MUI_Redraw(obj, MADF_DRAWUPDATE);
4945 /* Draw Lasso frame */
4946 IconList_InvertLassoOutlines(obj, &new_lasso);
4949 return MUI_EventHandlerRC_Eat;
4951 else if (data->mouse_pressed & MIDDLE_BUTTON)
4953 LONG newleft,
4954 newtop;
4956 newleft = data->click_x - mx;
4957 newtop = data->click_y - my;
4959 if (newleft + _mwidth(obj) > data->icld_AreaWidth) newleft = data->icld_AreaWidth - _mwidth(obj);
4960 if (newleft < 0) newleft = 0;
4962 if (newtop + _mheight(obj) > data->icld_AreaHeight) newtop = data->icld_AreaHeight - _mheight(obj);
4963 if (newtop < 0) newtop = 0;
4965 if ((newleft != data->icld_ViewX) || (newtop != data->icld_ViewY))
4967 SetAttrs(obj, MUIA_Virtgroup_Left, newleft,
4968 MUIA_Virtgroup_Top, newtop,
4969 TAG_DONE);
4972 return MUI_EventHandlerRC_Eat;
4975 break;
4979 return 0;
4983 ///MUIM_IconList_NextIcon()
4984 /**************************************************************************
4985 MUIM_IconList_NextIcon
4986 **************************************************************************/
4987 IPTR IconList__MUIM_IconList_NextIcon(struct IClass *CLASS, Object *obj, struct MUIP_IconList_NextIcon *message)
4989 struct IconList_DATA *data = INST_DATA(CLASS, obj);
4990 struct IconEntry *node = NULL;
4991 struct IconList_Entry *ent = NULL;
4992 IPTR node_successor = (IPTR)NULL;
4994 if (message->entry == NULL) return (IPTR)NULL;
4995 ent = *message->entry;
4997 #if defined(DEBUG_ILC_FUNCS)
4998 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
4999 #endif
5001 if ((IPTR)ent == (IPTR)MUIV_IconList_NextIcon_Start)
5003 D(bug("[IconList] %s: Finding First Entry ..\n", __PRETTY_FUNCTION__));
5004 if (message->nextflag == MUIV_IconList_NextIcon_Selected)
5006 node = (struct IconEntry *)GetHead(&data->icld_SelectionList);
5007 if (node != NULL)
5009 node = (struct IconEntry *)((IPTR)node - ((IPTR)&node->ie_SelectionNode - (IPTR)node));
5012 else if (message->nextflag == MUIV_IconList_NextIcon_Visible)
5014 node = (struct IconEntry *)GetHead(&data->icld_IconList);
5015 while (node != NULL)
5017 if (node->ie_Flags & ICONENTRY_FLAG_VISIBLE)
5018 break;
5020 node = (struct IconEntry *)GetSucc(&node->ie_IconNode);
5024 else if ((IPTR)ent != (IPTR)MUIV_IconList_NextIcon_End)
5026 node = (struct IconEntry *)((IPTR)ent - ((IPTR)&node->ie_IconListEntry - (IPTR)node));
5027 if (message->nextflag == MUIV_IconList_NextIcon_Selected)
5029 node_successor = (IPTR)GetSucc(&node->ie_SelectionNode);
5030 if (node_successor != (IPTR)NULL)
5031 node = (struct IconEntry *)((IPTR)node_successor - ((IPTR)&node->ie_SelectionNode - (IPTR)node));
5032 else
5034 D(bug("[IconList] %s: GetSucc() == NULL\n", __PRETTY_FUNCTION__));
5035 node = NULL;
5038 else if (message->nextflag == MUIV_IconList_NextIcon_Visible)
5040 node = (struct IconEntry *)GetSucc(&node->ie_IconNode);
5041 while (node != NULL)
5043 if (node->ie_Flags & ICONENTRY_FLAG_VISIBLE)
5044 break;
5046 node = (struct IconEntry *)GetSucc(&node->ie_IconNode);
5051 if (node == NULL)
5053 D(bug("[IconList] %s: Returning MUIV_IconList_NextIcon_End\n", __PRETTY_FUNCTION__));
5055 *message->entry = (struct IconList_Entry *)MUIV_IconList_NextIcon_End;
5057 else
5059 D(bug("[IconList] %s: Returning entry for '%s'\n", __PRETTY_FUNCTION__, node->ie_IconListEntry.label));
5061 *message->entry = &node->ie_IconListEntry;
5064 return (IPTR)NULL;
5068 ///MUIM_IconList_GetIconPrivate()
5069 /**************************************************************************
5070 MUIM_IconList_GetIconPrivate
5071 **************************************************************************/
5072 IPTR IconList__MUIM_IconList_GetIconPrivate(struct IClass *CLASS, Object *obj, struct MUIP_IconList_GetIconPrivate *message)
5074 // struct IconList_DATA *data = INST_DATA(CLASS, obj);
5075 struct IconEntry *node = NULL;
5077 if (message->entry == NULL) return (IPTR)NULL;
5079 node = (struct IconEntry *)((IPTR)message->entry - ((IPTR)&node->ie_IconListEntry - (IPTR)node));
5081 return (IPTR)node;
5084 ///MUIM_CreateDragImage()
5085 /**************************************************************************
5086 MUIM_CreateDragImage
5087 **************************************************************************/
5088 IPTR IconList__MUIM_CreateDragImage(struct IClass *CLASS, Object *obj, struct MUIP_CreateDragImage *message)
5090 struct IconList_DATA *data = INST_DATA(CLASS, obj);
5091 struct MUI_DragImage *img = NULL;
5092 LONG first_x = -1,
5093 first_y = -1;
5095 #if defined(DEBUG_ILC_FUNCS)
5096 (bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
5097 #endif
5099 if (!(data->icld_SelectionLastClicked))
5100 DoSuperMethodA(CLASS, obj, (Msg)message);
5102 if ((img = (struct MUI_DragImage *)AllocVec(sizeof(struct MUIP_CreateDragImage), MEMF_CLEAR)))
5104 struct Node *node = NULL;
5105 struct IconEntry *entry = NULL;
5107 LONG depth = GetBitMapAttr(_screen(obj)->RastPort.BitMap, BMA_DEPTH);
5109 #if defined(CREATE_FULL_DRAGIMAGE)
5110 #if defined(__AROS__)
5111 ForeachNode(&data->icld_SelectionList, node)
5112 #else
5113 Foreach_Node(&data->icld_SelectionList, node);
5114 #endif
5116 entry = (struct IconEntry *)((IPTR)node - ((IPTR)&entry->ie_SelectionNode - (IPTR)entry));
5117 if ((entry->ie_Flags & ICONENTRY_FLAG_VISIBLE) && (entry->ie_Flags & ICONENTRY_FLAG_SELECTED))
5119 if ((first_x == -1) || ((first_x != -1) && (entry->ie_IconX < first_x))) first_x = entry->ie_IconX;
5120 if ((first_y == -1) || ((first_y != -1) && (entry->ie_IconY < first_y))) first_y = entry->ie_IconY;
5121 if ((entry->ie_IconX + entry->ie_IconWidth) > img->width) img->width = entry->ie_IconX + entry->ie_IconWidth;
5122 if ((entry->ie_IconY + entry->ie_IconHeight) > img->height) img->height = entry->ie_IconY + entry->ie_IconHeight;
5125 img->width = (img->width - first_x) + 2;
5126 img->height = (img->height - first_y) + 2;
5127 #else
5128 entry = data->icld_SelectionLastClicked;
5129 img->width = entry->ie_IconWidth;
5130 img->height = entry->ie_IconHeight;
5131 first_x = entry->ie_IconX;
5132 first_y = entry->ie_IconY;
5133 #endif
5135 img->touchx = data->click_x - first_x;
5136 img->touchy = data->click_y - first_y;
5138 if ((img->bm = AllocBitMap(img->width, img->height, depth, BMF_CLEAR, _screen(obj)->RastPort.BitMap)))
5140 struct RastPort temprp;
5141 InitRastPort(&temprp);
5142 temprp.BitMap = img->bm;
5144 #if defined(CREATE_FULL_DRAGIMAGE)
5145 ForeachNode(&data->icld_SelectionList, node)
5147 entry = (struct IconEntry *)((IPTR)node - ((IPTR)&entry->ie_SelectionNode - (IPTR)entry));
5148 if ((entry->ie_Flags & ICONENTRY_FLAG_VISIBLE) && (entry->ie_Flags & ICONENTRY_FLAG_SELECTED))
5150 DrawIconStateA
5152 &temprp, entry->ie_DiskObj, NULL,
5153 (entry->ie_IconX + 1) - first_x, (entry->ie_IconY + 1) - first_y,
5154 IDS_SELECTED,
5155 __iconList_DrawIconStateTags
5159 #else
5160 DrawIconStateA
5162 &temprp, entry->ie_DiskObj, NULL,
5163 0, 0,
5164 IDS_SELECTED,
5165 __iconList_DrawIconStateTags
5167 #endif
5168 RastPortSetAlpha(&temprp, data->click_x, data->click_y, img->width, img->height, 0x80, RPALPHAFLAT);
5169 DeinitRastPort(&temprp);
5172 img->touchx = message->touchx;
5173 img->touchy = message->touchy;
5174 img->flags = 0;
5175 #if defined(__MORPHOS__)
5176 img->dragmode = DD_TRANSPARENT;
5177 #endif
5179 return (IPTR)img;
5183 ///MUIM_DeleteDragImage()
5184 /**************************************************************************
5185 MUIM_DeleteDragImage
5186 **************************************************************************/
5187 IPTR IconList__MUIM_DeleteDragImage(struct IClass *CLASS, Object *obj, struct MUIP_DeleteDragImage *message)
5189 struct IconList_DATA *data = INST_DATA(CLASS, obj);
5191 #if defined(DEBUG_ILC_FUNCS)
5192 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
5193 #endif
5195 if (!(data->icld_SelectionLastClicked)) return DoSuperMethodA(CLASS,obj,(Msg)message);
5197 if (message->di)
5199 if (message->di->bm)
5200 FreeBitMap(message->di->bm);
5201 FreeVec(message->di);
5203 return (IPTR)NULL;
5207 ///MUIM_DragQuery()
5208 /**************************************************************************
5209 MUIM_DragQuery
5210 **************************************************************************/
5211 IPTR IconList__MUIM_DragQuery(struct IClass *CLASS, Object *obj, struct MUIP_DragQuery *message)
5213 #if defined(DEBUG_ILC_FUNCS)
5214 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
5215 #endif
5216 if (message->obj == obj)
5217 return MUIV_DragQuery_Accept;
5218 else
5220 BOOL is_iconlist = FALSE;
5221 struct IClass *msg_cl = OCLASS(message->obj);
5223 while (msg_cl)
5225 if (msg_cl == CLASS)
5227 is_iconlist = TRUE;
5228 break;
5230 msg_cl = msg_cl->cl_Super;
5232 if (is_iconlist)
5233 return MUIV_DragQuery_Accept;
5236 return MUIV_DragQuery_Refuse;
5240 ///MUIM_DragDrop()
5241 /**************************************************************************
5242 MUIM_DragDrop
5243 **************************************************************************/
5244 IPTR IconList__MUIM_DragDrop(struct IClass *CLASS, Object *obj, struct MUIP_DragDrop *message)
5246 struct IconList_DATA *data = INST_DATA(CLASS, obj);
5248 #if defined(DEBUG_ILC_FUNCS)
5249 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
5250 #endif
5252 struct IconList_Entry *entry = (IPTR)MUIV_IconList_NextIcon_Start;
5254 if (data->icld_DragDropEvent)
5256 struct IconList_Drop_SourceEntry *clean_node;
5257 #if defined(DEBUG_ILC_ICONDRAGDROP)
5258 D(bug("[IconList] %s: Cleaning existing IconList_Drop_Event @ %p\n", __PRETTY_FUNCTION__, data->icld_DragDropEvent));
5259 #endif
5260 while ((clean_node = (struct IconList_Drop_SourceEntry *)RemTail(&data->icld_DragDropEvent->drop_SourceList)) != NULL)
5262 FreeVec(clean_node->dropse_Node.ln_Name);
5263 FreeMem(clean_node, sizeof(struct IconList_Drop_SourceEntry));
5265 if (data->icld_DragDropEvent->drop_TargetPath) FreeVec(data->icld_DragDropEvent->drop_TargetPath);
5266 FreeMem(data->icld_DragDropEvent, sizeof(struct IconList_Drop_Event));
5267 data->icld_DragDropEvent = NULL;
5270 /* SANITY CHECK: Get first selected entry from SOURCE iconlist */
5271 DoMethod(message->obj, MUIM_IconList_NextIcon, MUIV_IconList_NextIcon_Selected, (IPTR)&entry);
5273 if ((entry) && (entry != (IPTR)MUIV_IconList_NextIcon_End))
5275 /* Ok.. atleast one icon was dropped .. */
5276 BOOL iconMove = FALSE;
5277 struct IconEntry *node = NULL;
5278 struct IconEntry *drop_target_node = NULL;
5279 STRPTR directory_path = NULL;
5280 struct IconList_Drop_Event *dragDropEvent = NULL;
5282 GET(obj, MUIA_IconDrawerList_Drawer, &directory_path);
5284 if ((dragDropEvent = AllocMem(sizeof(struct IconList_Drop_Event), MEMF_CLEAR)) == NULL)
5286 #if defined(DEBUG_ILC_ICONDRAGDROP)
5287 D(bug("[IconList] %s: Failed to allocate IconList_Drop_Event Storage!\n", __PRETTY_FUNCTION__));
5288 #endif
5289 goto dragdropdone;
5291 D(bug("[IconList] %s: Allocated IconList_Drop_Event @ %p\n", __PRETTY_FUNCTION__, dragDropEvent));
5293 NewList(&dragDropEvent->drop_SourceList);
5295 /* go through list and check if dropped on icon */
5296 #if defined(__AROS__)
5297 ForeachNode(&data->icld_IconList, node)
5298 #else
5299 Foreach_Node(&data->icld_IconList, node);
5300 #endif
5302 if ((node->ie_Flags & ICONENTRY_FLAG_VISIBLE) &&
5303 (message->x >= (node->ie_IconX - data->icld_ViewX)) &&
5304 (message->x < (node->ie_IconX - data->icld_ViewX + node->ie_AreaWidth)) &&
5305 (message->y >= (node->ie_IconY - data->icld_ViewY + _mtop(obj))) &&
5306 (message->y < (node->ie_IconY - data->icld_ViewY + node->ie_AreaHeight + _mtop(obj))))
5308 drop_target_node = node;
5309 break;
5313 if (drop_target_node &&
5314 ((drop_target_node->ie_IconListEntry.type == ST_SOFTLINK) ||
5315 (drop_target_node->ie_IconListEntry.type == ST_ROOT) ||
5316 (drop_target_node->ie_IconListEntry.type == ST_USERDIR) ||
5317 (drop_target_node->ie_IconListEntry.type == ST_LINKDIR) ||
5318 (drop_target_node->ie_IconListEntry.type == ST_FILE) ||
5319 (drop_target_node->ie_IconListEntry.type == ST_LINKFILE)))
5321 if ((drop_target_node->ie_IconListEntry.type != ST_ROOT) && (drop_target_node->ie_IconListEntry.type != ST_SOFTLINK))
5323 if (directory_path)
5325 int fulllen = strlen(directory_path) + strlen(drop_target_node->ie_IconListEntry.label) + 2;
5327 if ((dragDropEvent->drop_TargetPath = AllocVec(fulllen, MEMF_CLEAR)) == NULL)
5329 #if defined(DEBUG_ILC_ICONDRAGDROP)
5330 D(bug("[IconList] %s: Failed to allocate IconList_Drop_Event->drop_TargetPath Storage!\n", __PRETTY_FUNCTION__));
5331 #endif
5332 goto dragdropdone;
5334 strcpy(dragDropEvent->drop_TargetPath, directory_path);
5335 AddPart(dragDropEvent->drop_TargetPath, drop_target_node->ie_IconListEntry.label, fulllen);
5338 else
5340 if ((dragDropEvent->drop_TargetPath = AllocVec(strlen(drop_target_node->ie_IconListEntry.label) + 1, MEMF_CLEAR)) == NULL)
5342 #if defined(DEBUG_ILC_ICONDRAGDROP)
5343 D(bug("[IconList] %s: Failed to allocate IconList_Drop_Event->drop_TargetPath Storage!\n", __PRETTY_FUNCTION__));
5344 #endif
5345 goto dragdropdone;
5347 strcpy(dragDropEvent->drop_TargetPath, drop_target_node->ie_IconListEntry.label);
5350 #if defined(DEBUG_ILC_ICONDRAGDROP)
5351 D(bug("[IconList] %s: Target Icon Full Path = '%s'\n", __PRETTY_FUNCTION__, dragDropEvent->drop_TargetPath));
5352 #endif
5353 /* mark the Icon the selection was dropped on*/
5354 //drop_target_node->ie_Flags |= ICONENTRY_FLAG_SELECTED;
5355 //data->icld_UpdateMode = UPDATE_SINGLEICON;
5356 //data->update_icon = drop_target_node;
5357 //MUI_Redraw(obj,MADF_DRAWUPDATE);
5359 else
5361 /* not dropped on icon -> get path of DESTINATION iconlist */
5362 /* Note: directory_path is NULL when dropped on Wanderer's desktop */
5363 if ((message->obj != obj) && directory_path)
5365 #if defined(DEBUG_ILC_ICONDRAGDROP)
5366 D(bug("[IconList] %s: drop entry: Icons dropped in window '%s'\n", __PRETTY_FUNCTION__, directory_path));
5367 #endif
5368 /* copy path */
5369 if ((dragDropEvent->drop_TargetPath = AllocVec(strlen(directory_path) + 1, MEMF_CLEAR)) != NULL)
5371 strcpy(dragDropEvent->drop_TargetPath, directory_path);
5373 else
5375 #if defined(DEBUG_ILC_ICONDRAGDROP)
5376 D(bug("[IconList] %s: Failed to allocate IconList_Drop_Event->drop_TargetPath Storage!\n", __PRETTY_FUNCTION__));
5377 #endif
5378 goto dragdropdone;
5381 else if (message->obj == obj)
5383 #if defined(DEBUG_ILC_ICONDRAGDROP)
5384 D(bug("[IconList] %s: drop entry: Icon Move detected ..\n", __PRETTY_FUNCTION__));
5385 #endif
5386 iconMove = TRUE;
5387 SET(obj, MUIA_IconList_IconsMoved, (IPTR)entry); // Now notify
5388 MUI_Redraw(obj,MADF_DRAWOBJECT);
5389 DoMethod(obj, MUIM_IconList_CoordsSort);
5391 else
5393 #if defined(DEBUG_ILC_ICONDRAGDROP)
5394 D(bug("[IconList] %s: Icons Dropped on Wanderer Desktop (unhandled)!\n", __PRETTY_FUNCTION__));
5395 #endif
5396 iconMove = TRUE;
5399 if (!(iconMove))
5401 int copycount = 0;
5402 /* Create list of entries to copy .. */
5403 entry = (IPTR)MUIV_IconList_NextIcon_Start;
5404 while (entry != (IPTR)MUIV_IconList_NextIcon_End)
5406 DoMethod(message->obj, MUIM_IconList_NextIcon, MUIV_IconList_NextIcon_Selected, (IPTR)&entry);
5408 if (entry != (IPTR)MUIV_IconList_NextIcon_End)
5410 struct IconList_Drop_SourceEntry *sourceEntry = NULL;
5411 sourceEntry = AllocMem(sizeof(struct IconList_Drop_SourceEntry), MEMF_CLEAR);
5412 if ((entry->type != ST_ROOT) && (entry->type != ST_SOFTLINK))
5414 int fulllen = 0;
5415 IPTR path = 0;
5417 GET(message->obj, MUIA_IconDrawerList_Drawer, &path);
5419 if (path)
5421 fulllen = strlen(path) + strlen(entry->ile_IconEntry->ie_IconNode.ln_Name) + 2;
5422 sourceEntry->dropse_Node.ln_Name = AllocVec(fulllen, MEMF_CLEAR);
5423 strcpy(sourceEntry->dropse_Node.ln_Name, path);
5424 AddPart(sourceEntry->dropse_Node.ln_Name, entry->ile_IconEntry->ie_IconNode.ln_Name, fulllen);
5425 #if defined(DEBUG_ILC_ICONDRAGDROP)
5426 D(bug("[IconList] %s: Source Icon (Full Path) = '%s'\n", __PRETTY_FUNCTION__, sourceEntry->dropse_Node.ln_Name));
5427 #endif
5430 else
5432 sourceEntry->dropse_Node.ln_Name = AllocVec(strlen(entry->ile_IconEntry->ie_IconNode.ln_Name) + 1, MEMF_CLEAR);
5433 strcpy(sourceEntry->dropse_Node.ln_Name, entry->ile_IconEntry->ie_IconNode.ln_Name);
5434 #if defined(DEBUG_ILC_ICONDRAGDROP)
5435 D(bug("[IconList] %s: Source Icon = '%s'\n", __PRETTY_FUNCTION__, sourceEntry->dropse_Node.ln_Name));
5436 #endif
5438 if ((strcasecmp(dragDropEvent->drop_TargetPath, sourceEntry->dropse_Node.ln_Name)) != 0)
5440 copycount += 1;
5441 AddTail(&dragDropEvent->drop_SourceList, &sourceEntry->dropse_Node);
5443 else
5445 #if defined(DEBUG_ILC_ICONDRAGDROP)
5446 D(bug("[IconList] %s: Source == Dest, Skipping!\n", __PRETTY_FUNCTION__));
5447 #endif
5448 FreeVec(sourceEntry->dropse_Node.ln_Name);
5449 FreeMem(sourceEntry, sizeof(struct IconList_Drop_SourceEntry));
5453 if (copycount > 0)
5455 dragDropEvent->drop_TargetObj = (IPTR)obj;
5457 #if defined(DEBUG_ILC_ICONDRAGDROP)
5458 D(bug("[IconList] %s: Causing DROP notification..\n", __PRETTY_FUNCTION__));
5459 #endif
5460 SET(obj, MUIA_IconList_IconsDropped, (IPTR)dragDropEvent);
5461 DoMethod(obj, MUIM_IconList_CoordsSort);
5463 else
5465 if (dragDropEvent->drop_TargetPath) FreeVec(dragDropEvent->drop_TargetPath);
5466 FreeMem(dragDropEvent, sizeof(struct IconList_Drop_Event));
5470 else
5472 #if defined(DEBUG_ILC_ICONDRAGDROP)
5473 D(bug("[IconList] %s: BUG - DragDrop recieved with no source icons!\n", __PRETTY_FUNCTION__));
5474 #endif
5475 NNSET(obj, MUIA_IconList_IconsDropped, (IPTR)NULL);
5478 dragdropdone:
5479 return DoSuperMethodA(CLASS, obj, (Msg)message);
5483 ///MUIM_UnselectAll()
5484 /**************************************************************************
5485 MUIM_UnselectAll
5486 **************************************************************************/
5487 IPTR IconList__MUIM_IconList_UnselectAll(struct IClass *CLASS, Object *obj, Msg message)
5489 struct IconList_DATA *data = INST_DATA(CLASS, obj);
5490 struct Node *node = NULL, *next_node = NULL;
5491 BOOL changed = FALSE;
5493 #if defined(DEBUG_ILC_FUNCS)
5494 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
5495 #endif
5497 data->icld_SelectionLastClicked = NULL;
5498 data->icld_FocusIcon = NULL;
5499 #if defined(__AROS__)
5500 ForeachNodeSafe(&data->icld_SelectionList, node, next_node)
5501 #else
5502 Foreach_NodeSafe(&data->icld_SelectionList, node, next_node);
5503 #endif
5505 struct IconEntry *entry = (struct IconEntry *)((IPTR)node - ((IPTR)&entry->ie_SelectionNode - (IPTR)entry));
5506 BOOL update_icon = FALSE;
5508 if (entry->ie_Flags & ICONENTRY_FLAG_VISIBLE)
5510 if (entry->ie_Flags & ICONENTRY_FLAG_SELECTED)
5512 Remove(node);
5513 entry->ie_Flags &= ~ICONENTRY_FLAG_SELECTED;
5514 update_icon = TRUE;
5516 if (entry->ie_Flags & ICONENTRY_FLAG_FOCUS)
5518 entry->ie_Flags &= ~ICONENTRY_FLAG_FOCUS;
5519 update_icon = TRUE;
5523 if (update_icon)
5525 changed = TRUE;
5526 data->icld_UpdateMode = UPDATE_SINGLEICON;
5527 data->update_icon = entry;
5528 MUI_Redraw(obj, MADF_DRAWUPDATE);
5532 if (changed)
5533 SET(obj, MUIA_IconList_SelectionChanged, TRUE);
5535 return 1;
5539 ///MUIM_SelectAll()
5540 /**************************************************************************
5541 MUIM_SelectAll
5542 **************************************************************************/
5543 IPTR IconList__MUIM_IconList_SelectAll(struct IClass *CLASS, Object *obj, Msg message)
5545 struct IconList_DATA *data = INST_DATA(CLASS, obj);
5546 struct IconEntry *node = NULL;
5547 BOOL changed = FALSE;
5549 #if defined(DEBUG_ILC_FUNCS)
5550 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
5551 #endif
5553 node = (struct IconEntry *)GetHead(&data->icld_IconList);
5555 while (node != NULL)
5557 if (node->ie_Flags & ICONENTRY_FLAG_VISIBLE)
5559 BOOL update_icon = FALSE;
5561 if (!(node->ie_Flags & ICONENTRY_FLAG_SELECTED))
5563 AddTail(&data->icld_SelectionList, &node->ie_SelectionNode);
5564 node->ie_Flags |= ICONENTRY_FLAG_SELECTED;
5565 update_icon = TRUE;
5567 data->icld_SelectionLastClicked = node;
5569 else if (node->ie_Flags & ICONENTRY_FLAG_FOCUS)
5571 node->ie_Flags &= ~ICONENTRY_FLAG_FOCUS;
5572 update_icon = TRUE;
5575 if (update_icon)
5577 changed = TRUE;
5578 data->icld_UpdateMode = UPDATE_SINGLEICON;
5579 data->update_icon = node;
5580 MUI_Redraw(obj, MADF_DRAWUPDATE);
5583 node = (struct IconEntry *)GetSucc(&node->ie_IconNode);
5586 if ((data->icld_SelectionLastClicked) && (data->icld_SelectionLastClicked != data->icld_FocusIcon))
5588 data->icld_FocusIcon = data->icld_SelectionLastClicked;
5589 if (!(data->icld_FocusIcon->ie_Flags & ICONENTRY_FLAG_FOCUS))
5591 data->icld_FocusIcon->ie_Flags &= ~ICONENTRY_FLAG_FOCUS;
5592 data->icld_FocusIcon->ie_Flags |= ICONENTRY_FLAG_FOCUS;
5593 data->icld_UpdateMode = UPDATE_SINGLEICON;
5594 data->update_icon = data->icld_FocusIcon;
5595 MUI_Redraw(obj, MADF_DRAWUPDATE);
5599 if (changed)
5600 SET(obj, MUIA_IconList_SelectionChanged, TRUE);
5602 return 1;
5606 ///IconList__MUIM_IconList_CoordsSort()
5607 IPTR IconList__MUIM_IconList_CoordsSort(struct IClass *CLASS, Object *obj, struct MUIP_IconList_Sort *message)
5609 struct IconList_DATA *data = INST_DATA(CLASS, obj);
5611 struct IconEntry *entry = NULL,
5612 *test_icon = NULL;
5614 struct List list_VisibleIcons;
5615 struct List list_HiddenIcons;
5618 perform a quick sort of the iconlist based on icon coords
5619 this method DOESNT cause any visual output.
5621 #if defined(DEBUG_ILC_FUNCS) && defined(DEBUG_ILC_ICONSORTING)
5622 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
5623 #endif
5625 NewList((struct List*)&list_VisibleIcons);
5626 NewList((struct List*)&list_HiddenIcons);
5628 /*move list into our local list struct(s)*/
5629 while ((entry = (struct IconEntry *)RemTail((struct List*)&data->icld_IconList)))
5631 if (entry->ie_Flags & ICONENTRY_FLAG_VISIBLE)
5632 AddHead((struct List*)&list_VisibleIcons, (struct Node *)&entry->ie_IconNode);
5633 else
5634 AddHead((struct List*)&list_HiddenIcons, (struct Node *)&entry->ie_IconNode);
5637 while ((entry = (struct IconEntry *)RemTail((struct List*)&list_VisibleIcons)))
5639 if ((test_icon = (struct IconEntry *)GetTail(&data->icld_IconList)) != NULL)
5641 while (test_icon != NULL)
5643 if (((data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL) && (test_icon->ie_IconX > entry->ie_IconX)) ||
5644 (!(data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL) && (test_icon->ie_IconY > entry->ie_IconY)))
5646 test_icon = (struct IconEntry *)GetPred(&test_icon->ie_IconNode);
5647 continue;
5649 else break;
5652 while (test_icon != NULL)
5654 if (((data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL) && (test_icon->ie_IconY > entry->ie_IconY)) ||
5655 (!(data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL) && (test_icon->ie_IconX > entry->ie_IconX)))
5657 test_icon = (struct IconEntry *)GetPred(&test_icon->ie_IconNode);
5658 continue;
5660 else break;
5662 Insert((struct List*)&data->icld_IconList, (struct Node *)&entry->ie_IconNode, (struct Node *)&test_icon->ie_IconNode);
5664 else
5665 AddTail((struct List*)&data->icld_IconList, (struct Node *)&entry->ie_IconNode);
5667 #if defined(DEBUG_ILC_ICONSORTING)
5668 D(bug("[IconList] %s: Done\n", __PRETTY_FUNCTION__));
5669 #endif
5671 while ((entry = (struct IconEntry *)RemTail((struct List*)&list_HiddenIcons)))
5673 AddTail((struct List*)&data->icld_IconList, (struct Node *)&entry->ie_IconNode);
5676 #if defined(DEBUG_ILC_ICONSORTING_DUMP)
5677 #if defined(__AROS__)
5678 ForeachNode(&data->icld_IconList, entry)
5679 #else
5680 Foreach_Node(&data->icld_IconList, entry);
5681 #endif
5683 D(bug("[IconList] %s: %d %d '%s'\n", __PRETTY_FUNCTION__, entry->ie_IconX, entry->ie_IconY, entry->ie_IconListEntry.label));
5685 #endif
5687 return TRUE;
5691 ///MUIM_Sort()
5692 /**************************************************************************
5693 MUIM_Sort - sortsort
5694 **************************************************************************/
5695 IPTR IconList__MUIM_IconList_Sort(struct IClass *CLASS, Object *obj, struct MUIP_IconList_Sort *message)
5697 struct IconList_DATA *data = INST_DATA(CLASS, obj);
5698 struct IconEntry *entry = NULL,
5699 *icon1 = NULL,
5700 *icon2 = NULL;
5702 struct List list_VisibleIcons,
5703 list_SortedIcons,
5704 list_HiddenIcons;
5706 BOOL sortme, enqueue = FALSE;
5707 int i, visible_count = 0;
5709 #if defined(DEBUG_ILC_FUNCS) && defined(DEBUG_ILC_ICONSORTING)
5710 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
5711 #endif
5713 /* Reset incase view options have changed .. */
5714 data->icld_IconAreaLargestWidth = 0;
5715 data->icld_IconAreaLargestHeight = 0;
5716 data->icld_IconLargestHeight = 0;
5717 data->icld_LabelLargestHeight = 0;
5719 if ((data->icld_SortFlags & ICONLIST_SORT_MASK) != 0)
5721 #if defined(DEBUG_ILC_ICONSORTING)
5722 D(bug("[IconList] %s: Sorting (Flags %x)\n", __PRETTY_FUNCTION__, (data->icld_SortFlags & ICONLIST_SORT_MASK)));
5723 #endif
5724 NewList((struct List*)&list_VisibleIcons);
5725 NewList((struct List*)&list_SortedIcons);
5726 NewList((struct List*)&list_HiddenIcons);
5728 /*move list into our local list struct(s)*/
5729 while ((entry = (struct IconEntry *)RemTail((struct List*)&data->icld_IconList)))
5731 if (entry->ie_DiskObj)
5733 if (entry->ie_IconX != entry->ie_DiskObj->do_CurrentX)
5735 entry->ie_IconX = entry->ie_DiskObj->do_CurrentX;
5736 if ((data->icld_SortFlags & ICONLIST_SORT_MASK) == 0)
5737 entry->ie_Flags |= ICONENTRY_FLAG_NEEDSUPDATE;
5739 if (entry->ie_IconY != entry->ie_DiskObj->do_CurrentY)
5741 entry->ie_IconY = entry->ie_DiskObj->do_CurrentY;
5742 if ((data->icld_SortFlags & ICONLIST_SORT_MASK) == 0)
5743 entry->ie_Flags |= ICONENTRY_FLAG_NEEDSUPDATE;
5747 if (!(entry->ie_Flags & ICONENTRY_FLAG_HASICON))
5749 if (data->icld_DisplayFlags & ICONLIST_DISP_SHOWINFO)
5751 if (entry->ie_Flags & ICONENTRY_FLAG_VISIBLE)
5753 entry->ie_Flags &= ~(ICONENTRY_FLAG_VISIBLE|ICONENTRY_FLAG_NEEDSUPDATE);
5756 else if (!(entry->ie_Flags & ICONENTRY_FLAG_VISIBLE))
5758 entry->ie_Flags |= (ICONENTRY_FLAG_VISIBLE|ICONENTRY_FLAG_NEEDSUPDATE);
5761 else
5763 if (!(entry->ie_Flags & ICONENTRY_FLAG_VISIBLE))
5765 entry->ie_Flags |= (ICONENTRY_FLAG_VISIBLE|ICONENTRY_FLAG_NEEDSUPDATE);
5769 /* Now we have fixed visibility lets dump them into the correct list for sorting */
5770 if (entry->ie_Flags & ICONENTRY_FLAG_VISIBLE)
5772 if(entry->ie_AreaWidth > data->icld_IconAreaLargestWidth) data->icld_IconAreaLargestWidth = entry->ie_AreaWidth;
5773 if(entry->ie_AreaHeight > data->icld_IconAreaLargestHeight) data->icld_IconAreaLargestHeight = entry->ie_AreaHeight;
5774 if(entry->ie_IconHeight > data->icld_IconLargestHeight) data->icld_IconLargestHeight = entry->ie_IconHeight;
5775 if((entry->ie_AreaHeight - entry->ie_IconHeight) > data->icld_LabelLargestHeight) data->icld_LabelLargestHeight = entry->ie_AreaHeight - entry->ie_IconHeight;
5777 if (((data->icld_SortFlags & ICONLIST_SORT_MASK) == 0) && (entry->ie_IconX == NO_ICON_POSITION))
5778 AddTail((struct List*)&list_VisibleIcons, (struct Node *)&entry->ie_IconNode);
5779 else
5780 AddHead((struct List*)&list_VisibleIcons, (struct Node *)&entry->ie_IconNode);
5781 visible_count++;
5783 else
5785 if (entry->ie_Flags & ICONENTRY_FLAG_SELECTED)
5787 Remove(&entry->ie_SelectionNode);
5789 entry->ie_Flags &= ~(ICONENTRY_FLAG_SELECTED|ICONENTRY_FLAG_FOCUS);
5790 if (data->icld_SelectionLastClicked == entry) data->icld_SelectionLastClicked = NULL;
5791 if (data->icld_FocusIcon == entry) data->icld_FocusIcon = data->icld_SelectionLastClicked;
5792 AddHead((struct List*)&list_HiddenIcons, (struct Node *)&entry->ie_IconNode);
5796 /* Copy each visible icon entry back to the main list, sorting as we go*/
5798 while ((entry = (struct IconEntry *)RemHead((struct List*)&list_VisibleIcons)))
5800 icon1 = (struct IconEntry *)GetHead(&list_SortedIcons);
5801 icon2 = NULL;
5803 sortme = FALSE;
5805 if (visible_count > 1)
5807 // D(bug(" - %s %s %s %i\n",entry->ie_IconListEntry.label,entry->ie_TxtBuf_DATE,entry->ie_TxtBuf_TIME,entry->ie_FileInfoBlock->fib_Size));
5809 while (icon1)
5811 if((icon1->ie_IconListEntry.type == ST_ROOT)||(data->icld_SortFlags & ICONLIST_SORT_DRAWERS_MIXED))
5813 /*volume list or drawers mixed*/
5814 sortme = TRUE;
5816 else
5818 /*drawers first*/
5819 if ((icon1->ie_IconListEntry.type == ST_USERDIR) && (entry->ie_IconListEntry.type == ST_USERDIR))
5821 sortme = TRUE;
5823 else
5825 if ((icon1->ie_IconListEntry.type != ST_USERDIR) && (entry->ie_IconListEntry.type != ST_USERDIR))
5826 sortme = TRUE;
5827 else
5829 /* we are the first drawer to arrive or we need to insert ourselves
5830 due to being sorted to the end of the drawers*/
5832 if ((!icon2 || icon2->ie_IconListEntry.type == ST_USERDIR) &&
5833 (entry->ie_IconListEntry.type == ST_USERDIR) &&
5834 (icon1->ie_IconListEntry.type != ST_USERDIR))
5836 // D(bug("force %s\n",entry->ie_IconListEntry.label));
5837 break;
5843 if (sortme)
5845 i = 0;
5847 if ((data->icld_SortFlags & ICONLIST_SORT_MASK) == ICONLIST_SORT_BY_DATE)
5849 /* Sort by Date */
5850 i = CompareDates((const struct DateStamp *)&entry->ie_FileInfoBlock->fib_Date,(const struct DateStamp *)&icon1->ie_FileInfoBlock->fib_Date);
5852 else if ((data->icld_SortFlags & ICONLIST_SORT_MASK) == ICONLIST_SORT_BY_SIZE)
5854 /* Sort by Size .. */
5855 i = entry->ie_FileInfoBlock->fib_Size - icon1->ie_FileInfoBlock->fib_Size;
5857 else if (((data->icld_SortFlags & ICONLIST_SORT_MASK) == ICONLIST_SORT_MASK) && (entry->ie_IconListEntry.type != ST_ROOT))
5859 /* Sort by Type .. */
5860 #warning "TODO: Sort icons based on type using datatypes"
5862 else
5864 if (
5865 ((data->icld_SortFlags & ICONLIST_SORT_MASK) == ICONLIST_SORT_MASK) ||
5866 ((data->icld_SortFlags & ICONLIST_SORT_MASK) == ICONLIST_SORT_BY_NAME) ||
5867 (entry->ie_IconX == NO_ICON_POSITION)
5870 /* Sort by Name .. */
5871 i = Stricmp(entry->ie_IconListEntry.label, icon1->ie_IconListEntry.label);
5872 if ((data->icld_SortFlags & ICONLIST_SORT_MASK) == ICONLIST_SORT_MASK)
5873 enqueue = TRUE;
5875 else
5877 /* coord sort */
5878 #warning "TODO: Implement default coord sorting.."
5882 if (data->icld_SortFlags & ICONLIST_SORT_REVERSE)
5884 if (i > 0)
5885 break;
5887 else if (i < 0)
5888 break;
5890 icon2 = icon1;
5891 icon1 = (struct IconEntry *)GetSucc(&icon1->ie_IconNode);
5894 Insert((struct List*)&list_SortedIcons, (struct Node *)&entry->ie_IconNode, (struct Node *)&icon2->ie_IconNode);
5896 if (enqueue)
5898 /* Quickly resort based on node priorities .. */
5899 while ((entry = (struct IconEntry *)RemHead((struct List*)&list_SortedIcons)))
5901 Enqueue((struct List*)&data->icld_IconList, (struct Node *)&entry->ie_IconNode);
5904 else
5906 while ((entry = (struct IconEntry *)RemHead((struct List*)&list_SortedIcons)))
5908 AddTail((struct List*)&data->icld_IconList, (struct Node *)&entry->ie_IconNode);
5912 else
5914 #if defined(DEBUG_ILC_ICONSORTING)
5915 D(bug("[IconList] %s: Coord Sorting\n", __PRETTY_FUNCTION__));
5916 #endif
5917 DoMethod(obj, MUIM_IconList_CoordsSort);
5920 DoMethod(obj, MUIM_IconList_PositionIcons);
5921 MUI_Redraw(obj, MADF_DRAWOBJECT);
5923 if ((data->icld_SortFlags & ICONLIST_SORT_MASK) != 0)
5925 DoMethod(obj, MUIM_IconList_CoordsSort);
5927 /* leave hidden icons on a seperate list to speed up normal list parsing ? */
5928 while ((entry = (struct IconEntry *)RemHead((struct List*)&list_HiddenIcons)))
5930 AddTail((struct List*)&data->icld_IconList, (struct Node *)&entry->ie_IconNode);
5933 SET(obj, MUIA_IconList_Changed, TRUE);
5935 return 1;
5939 ///MUIM_DragReport()
5940 /**************************************************************************
5941 MUIM_DragReport. Since MUI doesn't change the drop object if the dragged
5942 object is moved above another window (while still in the bounds of the
5943 orginal drop object) we must do it here manually to be compatible with
5944 MUI. Maybe Zune should fix this bug somewhen.
5945 **************************************************************************/
5946 IPTR IconList__MUIM_DragReport(struct IClass *CLASS, Object *obj, struct MUIP_DragReport *message)
5948 struct Window *wnd = _window(obj);
5949 struct Layer *l = NULL;
5951 #if defined(DEBUG_ILC_FUNCS)
5952 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
5953 #endif
5955 l = WhichLayer(&wnd->WScreen->LayerInfo, wnd->LeftEdge + message->x, wnd->TopEdge + message->y);
5957 if (l != wnd->WLayer) return MUIV_DragReport_Abort;
5959 return MUIV_DragReport_Continue;
5963 ///MUIM_IconList_UnknownDropDestination()
5964 /**************************************************************************
5965 MUIM_IconList_UnknownDropDestination
5966 **************************************************************************/
5967 IPTR IconList__MUIM_UnknownDropDestination(struct IClass *CLASS, Object *obj, struct MUIP_UnknownDropDestination *message)
5969 #if defined(DEBUG_ILC_FUNCS)
5970 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
5971 #endif
5972 D(bug("[IconList] %s: icons dropped on custom window \n", __PRETTY_FUNCTION__));
5974 SET(obj, MUIA_IconList_AppWindowDrop, (IPTR)message); /* Now notify */
5976 return (IPTR)NULL;
5980 ///MUIM_IconList_MakeIconVisible()
5981 /**************************************************************************
5982 Move the visible area so that the selected icon becomes visible ..
5983 **************************************************************************/
5984 IPTR IconList__MUIM_IconList_MakeIconVisible(struct IClass *CLASS, Object *obj, struct MUIP_IconList_MakeIconVisible *message)
5986 struct IconList_DATA *data = INST_DATA(CLASS, obj);
5987 BOOL viewmoved = FALSE;
5988 struct Rectangle iconrect, viewrect;
5990 #if defined(DEBUG_ILC_FUNCS)
5991 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
5992 #endif
5994 viewrect.MinX = data->icld_ViewX;
5995 viewrect.MaxX = data->icld_ViewX + data->icld_AreaWidth;
5996 viewrect.MinY = data->icld_ViewY;
5997 viewrect.MaxY = data->icld_ViewY + data->icld_AreaHeight;
5999 IconList_GetIconAreaRectangle(obj, data, message->icon, &iconrect);
6001 if (!(RectAndRect(&viewrect, &iconrect)))
6003 viewmoved = TRUE;
6004 if (message->icon->ie_IconX < data->icld_ViewX)
6005 data->icld_ViewX = message->icon->ie_IconX;
6006 else if (message->icon->ie_IconX > (data->icld_ViewX + data->icld_AreaWidth))
6007 data->icld_ViewX = (message->icon->ie_IconX + message->icon->ie_AreaWidth) - data->icld_AreaWidth;
6009 if (message->icon->ie_IconY < data->icld_ViewY)
6010 data->icld_ViewY = message->icon->ie_IconX;
6011 else if (message->icon->ie_IconY > (data->icld_ViewY + data->icld_AreaHeight))
6012 data->icld_ViewY = (message->icon->ie_IconY + message->icon->ie_AreaHeight) - data->icld_AreaHeight;
6015 if (viewmoved)
6017 D(bug("[IconList]: %s: call SetSuperAttrs()\n", __PRETTY_FUNCTION__));
6018 SetSuperAttrs(CLASS, obj, MUIA_Virtgroup_Left, data->icld_ViewX,
6019 MUIA_Virtgroup_Top, data->icld_ViewY,
6020 TAG_DONE);
6022 D(bug("[IconList]: %s: call SetAttrs()\n", __PRETTY_FUNCTION__));
6023 SetAttrs(obj, MUIA_Virtgroup_Left, data->icld_ViewX,
6024 MUIA_Virtgroup_Top, data->icld_ViewY,
6025 TAG_DONE);
6027 D(bug("[IconList]: %s: call MUI_Redraw()\n", __PRETTY_FUNCTION__));
6028 MUI_Redraw(obj,MADF_DRAWOBJECT);
6030 return 1;
6033 #if defined(WANDERER_BUILTIN_ICONLIST)
6034 BOOPSI_DISPATCHER(IPTR,IconList_Dispatcher, CLASS, obj, message)
6036 #if defined(__AROS__)
6037 switch (message->MethodID)
6038 #else
6039 struct IClass *CLASS = cl;
6040 Msg message = msg;
6042 switch (msg->MethodID)
6043 #endif
6045 case OM_NEW: return IconList__OM_NEW(CLASS, obj, (struct opSet *)message);
6046 case OM_DISPOSE: return IconList__OM_DISPOSE(CLASS, obj, message);
6047 case OM_SET: return IconList__OM_SET(CLASS, obj, (struct opSet *)message);
6048 case OM_GET: return IconList__OM_GET(CLASS, obj, (struct opGet *)message);
6049 case OM_ADDMEMBER:
6050 case MUIM_Family_AddTail: return IconList__MUIM_Family_AddTail(CLASS, obj, (APTR)message);
6051 case MUIM_Family_AddHead: return IconList__MUIM_Family_AddHead(CLASS, obj, (APTR)message);
6052 case OM_REMMEMBER:
6053 case MUIM_Family_Remove: return IconList__MUIM_Family_Remove(CLASS, obj, (APTR)message);
6055 case MUIM_Setup: return IconList__MUIM_Setup(CLASS, obj, (struct MUIP_Setup *)message);
6057 case MUIM_Show: return IconList__MUIM_Show(CLASS,obj, (struct MUIP_Show *)message);
6058 case MUIM_Hide: return IconList__MUIM_Hide(CLASS,obj, (struct MUIP_Hide *)message);
6059 case MUIM_Cleanup: return IconList__MUIM_Cleanup(CLASS, obj, (struct MUIP_Cleanup *)message);
6060 case MUIM_AskMinMax: return IconList__MUIM_AskMinMax(CLASS, obj, (struct MUIP_AskMinMax *)message);
6061 case MUIM_Draw: return IconList__MUIM_Draw(CLASS, obj, (struct MUIP_Draw *)message);
6062 #if defined(__AROS__)
6063 case MUIM_Layout: return IconList__MUIM_Layout(CLASS, obj, (struct MUIP_Layout *)message);
6064 #endif
6065 case MUIM_HandleEvent: return IconList__MUIM_HandleEvent(CLASS, obj, (struct MUIP_HandleEvent *)message);
6066 case MUIM_CreateDragImage: return IconList__MUIM_CreateDragImage(CLASS, obj, (APTR)message);
6067 case MUIM_DeleteDragImage: return IconList__MUIM_DeleteDragImage(CLASS, obj, (APTR)message);
6068 case MUIM_DragQuery: return IconList__MUIM_DragQuery(CLASS, obj, (APTR)message);
6069 case MUIM_DragReport: return IconList__MUIM_DragReport(CLASS, obj, (APTR)message);
6070 case MUIM_DragDrop: return IconList__MUIM_DragDrop(CLASS, obj, (APTR)message);
6071 #if defined(__AROS__)
6072 case MUIM_UnknownDropDestination: return IconList__MUIM_UnknownDropDestination(CLASS, obj, (APTR)message);
6073 #endif
6074 case MUIM_IconList_Update: return IconList__MUIM_IconList_Update(CLASS, obj, (APTR)message);
6075 case MUIM_IconList_Clear: return IconList__MUIM_IconList_Clear(CLASS, obj, (APTR)message);
6076 case MUIM_IconList_RethinkDimensions: return IconList__MUIM_IconList_RethinkDimensions(CLASS, obj, (APTR)message);
6077 case MUIM_IconList_CreateEntry: return IconList__MUIM_IconList_CreateEntry(CLASS, obj, (APTR)message);
6078 case MUIM_IconList_UpdateEntry: return IconList__MUIM_IconList_UpdateEntry(CLASS, obj, (APTR)message);
6079 case MUIM_IconList_DestroyEntry: return IconList__MUIM_IconList_DestroyEntry(CLASS, obj, (APTR)message);
6080 case MUIM_IconList_DrawEntry: return IconList__MUIM_IconList_DrawEntry(CLASS, obj, (APTR)message);
6081 case MUIM_IconList_DrawEntryLabel: return IconList__MUIM_IconList_DrawEntryLabel(CLASS, obj, (APTR)message);
6082 case MUIM_IconList_NextIcon: return IconList__MUIM_IconList_NextIcon(CLASS, obj, (APTR)message);
6083 case MUIM_IconList_GetIconPrivate: return IconList__MUIM_IconList_GetIconPrivate(CLASS, obj, (APTR)message);
6084 case MUIM_IconList_UnselectAll: return IconList__MUIM_IconList_UnselectAll(CLASS, obj, (APTR)message);
6085 case MUIM_IconList_Sort: return IconList__MUIM_IconList_Sort(CLASS, obj, (APTR)message);
6086 case MUIM_IconList_CoordsSort: return IconList__MUIM_IconList_CoordsSort(CLASS, obj, (APTR)message);
6087 case MUIM_IconList_PositionIcons: return IconList__MUIM_IconList_PositionIcons(CLASS, obj, (APTR)message);
6088 case MUIM_IconList_SelectAll: return IconList__MUIM_IconList_SelectAll(CLASS, obj, (APTR)message);
6089 case MUIM_IconList_MakeIconVisible: return IconList__MUIM_IconList_MakeIconVisible(CLASS, obj, (APTR)message);
6092 return DoSuperMethodA(CLASS, obj, message);
6094 BOOPSI_DISPATCHER_END
6096 #if defined(__AROS__)
6097 /* Class descriptor. */
6098 const struct __MUIBuiltinClass _MUI_IconList_desc = {
6099 MUIC_IconList,
6100 MUIC_Area,
6101 sizeof(struct IconList_DATA),
6102 (void*)IconList_Dispatcher
6104 #endif
6105 #endif /* WANDERER_BUILTIN_ICONLIST */
6107 #if !defined(__AROS__)
6108 struct MUI_CustomClass *initIconListClass(void)
6110 return (struct MUI_CustomClass *) MUI_CreateCustomClass(NULL, MUIC_Area, NULL, sizeof(struct IconList_DATA), ENTRY(IconList_Dispatcher));
6112 #endif