Also dispose of the layer if we are replacing a previous back buffer
[AROS.git] / workbench / system / Wanderer / Classes / iconlist.c
blob9544daa45f0ffe72b5f060cae63790eb745c9a2c
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 Layer, rastport and bitmap so we can replace them ..
1738 DeleteLayer(NULL, data->icld_BufferRastPort->Layer);
1739 SET(obj, MUIA_IconList_BufferRastport, NULL);
1741 tmp_RastDepth = GetCyberMapAttr(data->icld_DisplayRastPort->BitMap, CYBRMATTR_DEPTH);
1742 if ((tmp_BuffBitMap = AllocBitMap(data->icld_ViewWidth,
1743 data->icld_ViewHeight,
1744 tmp_RastDepth,
1745 BMF_CLEAR,
1746 data->icld_DisplayRastPort->BitMap))!=NULL)
1748 struct TagItem lay_tags[] =
1750 {LA_Visible , (IPTR)FALSE },
1751 {TAG_DONE }
1754 struct Layer * buffLayer = CreateLayerTagList(&_screen(obj)->LayerInfo,
1755 tmp_BuffBitMap,
1758 data->icld_ViewWidth,
1759 data->icld_ViewHeight,
1760 LAYERSIMPLE,
1761 lay_tags);
1763 if (buffLayer != NULL)
1765 bug("[IconList] %s: FrontRastPort @ %p, BackLayer @ %p, BackRastport @ %p\n", __PRETTY_FUNCTION__, data->icld_DisplayRastPort, buffLayer, buffLayer->rp);
1766 data->icld_BufferRastPort = buffLayer->rp;
1768 SET(obj, MUIA_IconList_BufferRastport, data->icld_BufferRastPort);
1769 data->icld_DrawOffsetX = 0;
1770 data->icld_DrawOffsetY = 0;
1772 else
1774 FreeBitMap(tmp_BuffBitMap);
1775 data->icld_BufferRastPort = data->icld_DisplayRastPort;
1776 data->icld_DrawOffsetX = _mleft(obj);
1777 data->icld_DrawOffsetY = _mtop(obj);
1781 else
1783 if ((data->icld_BufferRastPort) && (data->icld_BufferRastPort != data->icld_DisplayRastPort))
1785 //Free up the buffers layer, rastport and bitmap since they are no longer needed ..
1786 DeleteLayer(NULL, data->icld_BufferRastPort->Layer);
1787 data->icld_BufferRastPort = data->icld_DisplayRastPort;
1788 data->icld_DrawOffsetX = _mleft(obj);
1789 data->icld_DrawOffsetY = _mtop(obj);
1792 SET(obj, MUIA_IconList_Changed, TRUE);
1794 break;
1796 case MUIA_IconList_SortFlags:
1797 #if defined(DEBUG_ILC_ATTRIBS)
1798 D(bug("[IconList] %s: MUIA_IconList_SortFlags %08x\n", __PRETTY_FUNCTION__, tag->ti_Data));
1799 #endif
1800 data->icld_SortFlags = (ULONG)tag->ti_Data;
1801 break;
1803 case MUIA_IconList_IconListMode:
1804 #if defined(DEBUG_ILC_ATTRIBS)
1805 D(bug("[IconList] %s: MUIA_IconList_IconListMode %d\n", __PRETTY_FUNCTION__, tag->ti_Data));
1806 #endif
1807 data->icld__Option_IconListMode = (UBYTE)tag->ti_Data;
1808 break;
1810 case MUIA_IconList_LabelText_Mode:
1811 #if defined(DEBUG_ILC_ATTRIBS)
1812 D(bug("[IconList] %s: MUIA_IconList_LabelText_Mode %d\n", __PRETTY_FUNCTION__, tag->ti_Data));
1813 #endif
1814 data->icld__Option_LabelTextMode = (UBYTE)tag->ti_Data;
1815 break;
1817 case MUIA_IconList_LabelText_MaxLineLen:
1818 #if defined(DEBUG_ILC_ATTRIBS)
1819 D(bug("[IconList] %s: MUIA_IconList_LabelText_MaxLineLen %d\n", __PRETTY_FUNCTION__, tag->ti_Data));
1820 #endif
1821 if (tag->ti_Data >= ILC_ICONLABEL_SHORTEST)
1823 data->icld__Option_LabelTextMaxLen = (ULONG)tag->ti_Data;
1825 else
1827 data->icld__Option_LabelTextMaxLen = ILC_ICONLABEL_MAXLINELEN_DEFAULT;
1829 break;
1831 case MUIA_IconList_LabelText_MultiLine:
1832 #if defined(DEBUG_ILC_ATTRIBS)
1833 D(bug("[IconList] %s: MUIA_IconList_LabelText_MultiLine %d\n", __PRETTY_FUNCTION__, tag->ti_Data));
1834 #endif
1835 data->icld__Option_LabelTextMultiLine = (ULONG)tag->ti_Data;
1836 if (data->icld__Option_LabelTextMultiLine == 0)data->icld__Option_LabelTextMultiLine = 1;
1837 break;
1839 case MUIA_IconList_LabelText_MultiLineOnFocus:
1840 #if defined(DEBUG_ILC_ATTRIBS)
1841 D(bug("[IconList] %s: MUIA_IconList_LabelText_MultiLineOnFocus %d\n", __PRETTY_FUNCTION__, tag->ti_Data));
1842 #endif
1843 data->icld__Option_LabelTextMultiLineOnFocus = (BOOL)tag->ti_Data;
1844 break;
1846 case MUIA_IconList_Icon_HorizontalSpacing:
1847 #if defined(DEBUG_ILC_ATTRIBS)
1848 D(bug("[IconList] %s: MUIA_IconList_Icon_HorizontalSpacing %d\n", __PRETTY_FUNCTION__, tag->ti_Data));
1849 #endif
1850 data->icld__Option_IconHorizontalSpacing = (UBYTE)tag->ti_Data;
1851 break;
1853 case MUIA_IconList_Icon_VerticalSpacing:
1854 #if defined(DEBUG_ILC_ATTRIBS)
1855 D(bug("[IconList] %s: MUIA_IconList_Icon_VerticalSpacing %d\n", __PRETTY_FUNCTION__, tag->ti_Data));
1856 #endif
1857 data->icld__Option_IconVerticalSpacing = (UBYTE)tag->ti_Data;
1858 break;
1860 case MUIA_IconList_Icon_ImageSpacing:
1861 #if defined(DEBUG_ILC_ATTRIBS)
1862 D(bug("[IconList] %s: MUIA_IconList_Icon_ImageSpacing %d\n", __PRETTY_FUNCTION__, tag->ti_Data));
1863 #endif
1864 data->icld__Option_IconImageSpacing = (UBYTE)tag->ti_Data;
1865 break;
1867 case MUIA_IconList_LabelText_HorizontalPadding:
1868 #if defined(DEBUG_ILC_ATTRIBS)
1869 D(bug("[IconList] %s: MUIA_IconList_LabelText_HorizontalPadding %d\n", __PRETTY_FUNCTION__, tag->ti_Data));
1870 #endif
1871 data->icld__Option_LabelTextHorizontalPadding = (UBYTE)tag->ti_Data;
1872 break;
1874 case MUIA_IconList_LabelText_VerticalPadding:
1875 #if defined(DEBUG_ILC_ATTRIBS)
1876 D(bug("[IconList] %s: MUIA_IconList_LabelText_VerticalPadding %d\n", __PRETTY_FUNCTION__, tag->ti_Data));
1877 #endif
1878 data->icld__Option_LabelTextVerticalPadding = (UBYTE)tag->ti_Data;
1879 break;
1881 case MUIA_IconList_LabelText_BorderWidth:
1882 #if defined(DEBUG_ILC_ATTRIBS)
1883 D(bug("[IconList] %s: MUIA_IconList_LabelText_BorderWidth %d\n", __PRETTY_FUNCTION__, tag->ti_Data));
1884 #endif
1885 data->icld__Option_LabelTextBorderWidth = (UBYTE)tag->ti_Data;
1886 break;
1888 case MUIA_IconList_LabelText_BorderHeight:
1889 #if defined(DEBUG_ILC_ATTRIBS)
1890 D(bug("[IconList] %s: MUIA_IconList_LabelText_BorderHeight %d\n", __PRETTY_FUNCTION__, tag->ti_Data));
1891 #endif
1892 data->icld__Option_LabelTextBorderHeight = (UBYTE)tag->ti_Data;
1893 break;
1895 case MUIA_IconList_LabelText_Pen:
1896 data->icld_LabelPen = (ULONG)tag->ti_Data;
1897 break;
1899 case MUIA_IconList_LabelText_ShadowPen:
1900 data->icld_LabelShadowPen = (ULONG)tag->ti_Data;
1901 break;
1903 case MUIA_IconList_LabelInfoText_Pen:
1904 data->icld_InfoPen = (ULONG)tag->ti_Data;
1905 break;
1907 case MUIA_IconList_LabelInfoText_ShadowPen:
1908 data->icld_InfoShadowPen = (ULONG)tag->ti_Data;
1909 break;
1911 /* Settings defined by the view class */
1912 case MUIA_IconListview_FixedBackground:
1913 #if defined(DEBUG_ILC_ATTRIBS)
1914 D(bug("[IconList] %s: MUIA_IconListview_FixedBackground\n", __PRETTY_FUNCTION__));
1915 #endif
1916 data->icld__Option_IconListFixedBackground = (BOOL)tag->ti_Data;
1917 break;
1919 case MUIA_IconListview_ScaledBackground:
1920 #if defined(DEBUG_ILC_ATTRIBS)
1921 D(bug("[IconList] %s: MUIA_IconListview_ScaledBackground\n", __PRETTY_FUNCTION__));
1922 #endif
1923 data->icld__Option_IconListScaledBackground = (BOOL)tag->ti_Data;
1924 break;
1926 /* We listen for MUIA_Background and set default values for known types */
1927 case MUIA_Background:
1928 #if defined(DEBUG_ILC_ATTRIBS) && defined(DEBUG_ILC_ICONRENDERING)
1929 D(bug("[IconList] %s: MUIA_Background\n", __PRETTY_FUNCTION__));
1930 #endif
1932 char *bgmode_string = (char *)tag->ti_Data;
1933 BYTE this_mode = bgmode_string[0] - 48;
1935 #if defined(DEBUG_ILC_ATTRIBS) && defined(DEBUG_ILC_ICONRENDERING)
1936 D(bug("[IconList] %s: MUIA_Background | MUI BG Mode = %d\n", __PRETTY_FUNCTION__, this_mode));
1937 #endif
1938 switch (this_mode)
1940 case 0:
1941 //MUI Pattern
1942 NNSET(obj, MUIA_IconListview_FixedBackground, FALSE);
1943 NNSET(obj, MUIA_IconListview_ScaledBackground, FALSE);
1944 break;
1945 case 2:
1946 //MUI RGB color
1947 NNSET(obj, MUIA_IconListview_FixedBackground, FALSE);
1948 NNSET(obj, MUIA_IconListview_ScaledBackground, FALSE);
1949 break;
1950 case 7:
1951 //Zune Gradient
1952 NNSET(obj, MUIA_IconListview_FixedBackground, TRUE);
1953 NNSET(obj, MUIA_IconListview_ScaledBackground, TRUE);
1954 break;
1955 case 5:
1956 //Image
1957 NNSET(obj, MUIA_IconListview_FixedBackground, FALSE);
1958 NNSET(obj, MUIA_IconListview_ScaledBackground, FALSE);
1959 break;
1962 break;
1963 case MUIA_IconList_IconsDropped:
1964 data->icld_DragDropEvent = (struct IconList_Drop_Event *)tag->ti_Data;
1965 break;
1969 #if defined(DEBUG_ILC_ATTRIBS)
1970 D(bug("[IconList] %s(), out of switch\n", __PRETTY_FUNCTION__));
1971 #endif
1972 if ((oldleft != data->icld_ViewX) || (oldtop != data->icld_ViewY))
1974 data->icld_UpdateMode = UPDATE_SCROLL;
1975 data->update_scrolldx = data->icld_ViewX - oldleft;
1976 data->update_scrolldy = data->icld_ViewY - oldtop;
1977 #if defined(DEBUG_ILC_ATTRIBS)
1978 D(bug("[IconList] %s(), call MUI_Redraw()\n", __PRETTY_FUNCTION__));
1979 #endif
1980 MUI_Redraw(obj, MADF_DRAWUPDATE);
1983 #if defined(DEBUG_ILC_ATTRIBS)
1984 D(bug("[IconList] %s(), call DoSuperMethodA()\n", __PRETTY_FUNCTION__));
1985 #endif
1986 return DoSuperMethodA(CLASS, obj, (Msg)message);
1990 ///OM_GET()
1991 /**************************************************************************
1992 OM_GET
1993 **************************************************************************/
1994 IPTR IconList__OM_GET(struct IClass *CLASS, Object *obj, struct opGet *message)
1996 /* small macro to simplify return value storage */
1997 #define STORE *(message->opg_Storage)
1998 struct IconList_DATA *data = INST_DATA(CLASS, obj);
2000 #if defined(DEBUG_ILC_FUNCS) && defined(DEBUG_ILC_ATTRIBS)
2001 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
2002 #endif
2004 switch (message->opg_AttrID)
2006 case MUIA_IconList_Rastport: STORE = (IPTR)data->icld_DisplayRastPort; return 1;
2007 case MUIA_IconList_BufferRastport: STORE = (IPTR)data->icld_BufferRastPort; return 1;
2008 case MUIA_IconList_BufferLeft: STORE = (IPTR)data->icld_DrawOffsetX; return 1;
2009 case MUIA_IconList_BufferTop: STORE = (IPTR)data->icld_DrawOffsetY; return 1;
2010 case MUIA_IconList_BufferWidth:
2011 case MUIA_IconList_Width: STORE = (IPTR)data->icld_AreaWidth; return 1;
2012 case MUIA_IconList_BufferHeight:
2013 case MUIA_IconList_Height: STORE = (IPTR)data->icld_AreaHeight; return 1;
2014 case MUIA_IconList_IconsDropped: STORE = (IPTR)data->icld_DragDropEvent; return 1;
2015 case MUIA_IconList_Clicked: STORE = (IPTR)&data->icld_ClickEvent; return 1;
2016 case MUIA_IconList_IconListMode: STORE = (IPTR)data->icld__Option_IconListMode; return 1;
2017 case MUIA_IconList_LabelText_Mode: STORE = (IPTR)data->icld__Option_LabelTextMode; return 1;
2018 case MUIA_IconList_LabelText_MaxLineLen: STORE = (IPTR)data->icld__Option_LabelTextMaxLen; return 1;
2019 case MUIA_IconList_LabelText_MultiLine: STORE = (IPTR)data->icld__Option_LabelTextMultiLine; return 1;
2020 case MUIA_IconList_LabelText_MultiLineOnFocus: STORE = (IPTR)data->icld__Option_LabelTextMultiLineOnFocus; return 1;
2021 case MUIA_IconList_DisplayFlags: STORE = (IPTR)data->icld_DisplayFlags; return 1;
2022 case MUIA_IconList_SortFlags: STORE = (IPTR)data->icld_SortFlags; return 1;
2024 case MUIA_IconList_FocusIcon: STORE = (IPTR)data->icld_FocusIcon; return 1;
2026 case MUIA_Font: STORE = (IPTR)data->icld_IconLabelFont; return 1;
2027 case MUIA_IconList_LabelText_Pen: STORE = (IPTR)data->icld_LabelPen; return 1;
2028 case MUIA_IconList_LabelText_ShadowPen: STORE = (IPTR)data->icld_LabelShadowPen; return 1;
2029 case MUIA_IconList_LabelInfoText_Font: STORE = (IPTR)data->icld_IconInfoFont; return 1;
2030 case MUIA_IconList_LabelInfoText_Pen: STORE = (IPTR)data->icld_InfoPen; return 1;
2031 case MUIA_IconList_LabelInfoText_ShadowPen: STORE = (IPTR)data->icld_InfoShadowPen; return 1;
2033 case MUIA_IconList_Icon_HorizontalSpacing: STORE = (IPTR)data->icld__Option_IconHorizontalSpacing; return 1;
2034 case MUIA_IconList_Icon_VerticalSpacing: STORE = (IPTR)data->icld__Option_IconVerticalSpacing; return 1;
2035 case MUIA_IconList_Icon_ImageSpacing: STORE = (IPTR)data->icld__Option_IconImageSpacing; return 1;
2036 case MUIA_IconList_LabelText_HorizontalPadding: STORE = (IPTR)data->icld__Option_LabelTextHorizontalPadding; return 1;
2037 case MUIA_IconList_LabelText_VerticalPadding: STORE = (IPTR)data->icld__Option_LabelTextVerticalPadding; return 1;
2038 case MUIA_IconList_LabelText_BorderWidth: STORE = (IPTR)data->icld__Option_LabelTextBorderWidth; return 1;
2039 case MUIA_IconList_LabelText_BorderHeight: STORE = (IPTR)data->icld__Option_LabelTextBorderHeight; return 1;
2041 /* Settings defined by the view class */
2042 case MUIA_IconListview_FixedBackground: STORE = (IPTR)data->icld__Option_IconListFixedBackground; return 1;
2043 case MUIA_IconListview_ScaledBackground: STORE = (IPTR)data->icld__Option_IconListScaledBackground; return 1;
2045 /* ICON obj Changes */
2046 case MUIA_Virtgroup_Left: STORE = (IPTR)data->icld_ViewX; return 1;
2047 case MUIA_Virtgroup_Top: STORE = (IPTR)data->icld_ViewY; return 1;
2048 case MUIA_Family_List: STORE = (IPTR)&(data->icld_IconList); return 1; /* Get our list object */
2050 #warning "TODO: Get the version/revision from our config.."
2051 case MUIA_Version: STORE = (IPTR)1; return 1;
2052 case MUIA_Revision: STORE = (IPTR)7; return 1;
2055 return DoSuperMethodA(CLASS, obj, (Msg) message);
2056 #undef STORE
2060 IPTR IconList__MUIM_Family_AddHead(struct IClass *CLASS, Object *obj, struct MUIP_Family_AddHead *message)
2062 struct IconList_DATA *data = INST_DATA(CLASS, obj);
2063 #if defined(DEBUG_ILC_FUNCS)
2064 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
2065 #endif
2067 if (message->obj)
2069 #warning "TODO: Use the correct _OBJECT() code when we switch to icon.mui"
2070 // AddHead(&(data->icld_IconList), (struct Node *)_OBJECT(message->obj));
2071 AddHead(&(data->icld_IconList), (struct Node *)message->obj);
2072 return TRUE;
2074 else
2075 return FALSE;
2078 IPTR IconList__MUIM_Family_AddTail(struct IClass *CLASS, Object *obj, struct MUIP_Family_AddTail *message)
2080 struct IconList_DATA *data = INST_DATA(CLASS, obj);
2081 #if defined(DEBUG_ILC_FUNCS)
2082 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
2083 #endif
2085 if (message->obj)
2087 #warning "TODO: Use the correct _OBJECT() code when we switch to icon.mui"
2088 // AddTail(&(data->icld_IconList), (struct Node *)_OBJECT(message->obj));
2089 AddTail(&(data->icld_IconList), (struct Node *)message->obj);
2090 return TRUE;
2092 else
2093 return FALSE;
2095 return (IPTR)NULL;
2097 #if !defined(WANDERER_BUILTIN_ICONLIST)
2098 IPTR IconList__OM_ADDMEMBER(struct IClass *CLASS, Object *obj, struct MUIP_Family_AddTail *message)
2100 return IconList__MUIM_Family_AddTail(CLASS, obj, message);
2102 #endif
2104 IPTR IconList__MUIM_Family_Remove(struct IClass *CLASS, Object *obj, struct MUIP_Family_Remove *message)
2106 struct IconList_DATA *data = INST_DATA(CLASS, obj);
2107 #if defined(DEBUG_ILC_FUNCS)
2108 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
2109 #endif
2111 if (message->obj)
2113 #warning "TODO: Use the correct _OBJECT() code when we switch to icon.mui"
2114 // Remove((struct Node *)_OBJECT(message->obj));
2115 Remove((struct Node *)message->obj);
2116 return TRUE;
2118 else
2119 return FALSE;
2121 return (IPTR)NULL;
2123 #if !defined(WANDERER_BUILTIN_ICONLIST)
2124 IPTR IconList__OM_REMMEMBER(struct IClass *CLASS, Object *obj, struct MUIP_Family_Remove *message)
2126 return IconList__MUIM_Family_Remove(CLASS, obj, message);
2128 #endif
2130 ///MUIM_Setup()
2131 /**************************************************************************
2132 MUIM_Setup
2133 **************************************************************************/
2134 IPTR IconList__MUIM_Setup(struct IClass *CLASS, Object *obj, struct MUIP_Setup *message)
2136 struct IconList_DATA *data = INST_DATA(CLASS, obj);
2137 struct IconEntry *node = NULL;
2138 IPTR geticon_error = 0;
2140 #if defined(DEBUG_ILC_FUNCS)
2141 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
2142 #endif
2144 if (!DoSuperMethodA(CLASS, obj, (Msg) message)) return (IPTR)NULL;
2146 DoMethod(_win(obj), MUIM_Window_AddEventHandler, (IPTR)&data->ehn);
2148 /* Get Internal Objects to use if not set .. */
2149 data->icld_DisplayRastPort = NULL;
2150 data->icld_BufferRastPort = NULL;
2152 if (data->icld_IconLabelFont == NULL) data->icld_IconLabelFont = _font(obj);
2153 if (data->icld_IconInfoFont == NULL) data->icld_IconInfoFont = data->icld_IconLabelFont;
2154 #if defined(DEBUG_ILC_ICONRENDERING)
2155 D(bug("[IconList] %s: Use Font @ 0x%p, RastPort @ 0x%p\n", __PRETTY_FUNCTION__, data->icld_IconLabelFont, data->icld_BufferRastPort ));
2156 #endif
2158 /* Set our base options .. */
2159 data->icld_LabelPen = _pens(obj)[MPEN_SHINE];
2160 data->icld_LabelShadowPen = _pens(obj)[MPEN_SHADOW];
2161 data->icld_InfoPen = _pens(obj)[MPEN_SHINE];
2162 data->icld_InfoShadowPen = _pens(obj)[MPEN_SHADOW];
2164 data->icld__Option_LabelTextMultiLine = 1;
2165 data->icld__Option_LastLabelTextMultiLine = data->icld__Option_LabelTextMultiLine;
2167 data->icld__Option_LabelTextMultiLineOnFocus = FALSE;
2169 data->icld__Option_IconHorizontalSpacing = ILC_ICON_HORIZONTALMARGIN_DEFAULT;
2170 data->icld__Option_IconVerticalSpacing = ILC_ICON_VERTICALMARGIN_DEFAULT;
2171 data->icld__Option_IconImageSpacing = ILC_ICONLABEL_IMAGEMARGIN_DEFAULT;
2172 data->icld__Option_LabelTextHorizontalPadding = ILC_ICONLABEL_HORIZONTALTEXTMARGIN_DEFAULT;
2173 data->icld__Option_LabelTextVerticalPadding = ILC_ICONLABEL_VERTICALTEXTMARGIN_DEFAULT;
2174 data->icld__Option_LabelTextBorderWidth = ILC_ICONLABEL_BORDERWIDTH_DEFAULT;
2175 data->icld__Option_LabelTextBorderHeight = ILC_ICONLABEL_BORDERHEIGHT_DEFAULT;
2177 #if defined(__AROS__)
2178 ForeachNode(&data->icld_IconList, node)
2179 #else
2180 Foreach_Node(&data->icld_IconList, node);
2181 #endif
2183 if (!node->ie_DiskObj)
2185 IPTR iconlistScreen = _screen(obj);
2186 #if defined(DEBUG_ILC_ICONRENDERING)
2187 D(bug("[IconList] %s: IconList Screen @ 0x%p)\n", __PRETTY_FUNCTION__, iconlistScreen));
2188 #endif
2189 if (!(node->ie_DiskObj = GetIconTags(node->ie_IconNode.ln_Name,
2190 (iconlistScreen) ? ICONGETA_Screen : TAG_IGNORE, iconlistScreen,
2191 (iconlistScreen) ? ICONGETA_RemapIcon : TAG_IGNORE, TRUE,
2192 ICONGETA_GenerateImageMasks, TRUE,
2193 ICONGETA_FailIfUnavailable, FALSE,
2194 ICONA_ErrorCode, &geticon_error,
2195 TAG_DONE)))
2197 #if defined(DEBUG_ILC_ICONRENDERING)
2198 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));
2199 #endif
2200 /* We should probably remove this node if the icon cant be obtained ? */
2204 return 1;
2208 ///MUIM_Show()
2209 /**************************************************************************
2210 MUIM_Show
2211 **************************************************************************/
2212 IPTR IconList__MUIM_Show(struct IClass *CLASS, Object *obj, struct MUIP_Show *message)
2214 struct IconList_DATA *data = INST_DATA(CLASS, obj);
2215 LONG newleft,
2216 newtop;
2217 IPTR rc;
2219 #if defined(DEBUG_ILC_FUNCS)
2220 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
2221 #endif
2223 if ((rc = DoSuperMethodA(CLASS, obj, (Msg)message)))
2225 newleft = data->icld_ViewX;
2226 newtop = data->icld_ViewY;
2228 if (newleft + _mwidth(obj) > data->icld_AreaWidth)
2229 newleft = data->icld_AreaWidth - _mwidth(obj);
2230 if (newleft < 0)
2231 newleft = 0;
2233 if (newtop + _mheight(obj) > data->icld_AreaHeight)
2234 newtop = data->icld_AreaHeight - _mheight(obj);
2235 if (newtop < 0)
2236 newtop = 0;
2238 if ((newleft != data->icld_ViewX) || (newtop != data->icld_ViewY))
2240 SetAttrs(obj, MUIA_Virtgroup_Left, newleft,
2241 MUIA_Virtgroup_Top, newtop,
2242 TAG_DONE);
2245 /* Get Internal Objects to use if not set .. */
2246 if (data->icld_DisplayRastPort == NULL)
2248 if (_rp(obj) != NULL)
2250 data->icld_DisplayRastPort = CloneRastPort(_rp(obj));
2252 #if defined(DEBUG_ILC_ICONRENDERING)
2253 else
2255 D(bug("[IconList] IconList__MUIM_Show: ERROR - NULL RastPort!\n"));
2257 #endif
2260 if (data->icld_DisplayFlags & ICONLIST_DISP_BUFFERED)
2262 struct BitMap *tmp_BuffBitMap = NULL;
2263 ULONG tmp_RastDepth = GetCyberMapAttr(data->icld_DisplayRastPort->BitMap, CYBRMATTR_DEPTH);
2264 if ((tmp_BuffBitMap = AllocBitMap(data->icld_ViewWidth,
2265 data->icld_ViewHeight,
2266 tmp_RastDepth,
2267 BMF_CLEAR,
2268 data->icld_DisplayRastPort->BitMap))!=NULL)
2270 if ((data->icld_BufferRastPort = CreateRastPort())!=NULL)
2272 data->icld_BufferRastPort->BitMap = tmp_BuffBitMap;
2273 data->icld_DrawOffsetX = 0;
2274 data->icld_DrawOffsetY = 0;
2276 else
2278 FreeBitMap(tmp_BuffBitMap);
2279 data->icld_BufferRastPort = data->icld_DisplayRastPort;
2280 data->icld_DrawOffsetX = _mleft(obj);
2281 data->icld_DrawOffsetY = _mtop(obj);
2285 else
2287 data->icld_BufferRastPort = data->icld_DisplayRastPort;
2288 data->icld_DrawOffsetX = _mleft(obj);
2289 data->icld_DrawOffsetY = _mtop(obj);
2291 if (data->icld_IconLabelFont == NULL) data->icld_IconLabelFont = _font(obj);
2292 if (data->icld_IconInfoFont == NULL) data->icld_IconInfoFont = data->icld_IconLabelFont;
2293 #if defined(DEBUG_ILC_ICONRENDERING)
2294 D(bug("[IconList] IconList__MUIM_Show: Use Font @ 0x%p, RastPort @ 0x%p\n", data->icld_IconLabelFont, data->icld_BufferRastPort ));
2295 #endif
2297 if ((data->icld_BufferRastPort) && (data->icld_IconLabelFont))
2298 SetFont(data->icld_BufferRastPort, data->icld_IconLabelFont);
2300 return rc;
2304 ///MUIM_Hide()
2305 /**************************************************************************
2306 MUIM_Hide
2307 **************************************************************************/
2308 IPTR IconList__MUIM_Hide(struct IClass *CLASS, Object *obj, struct MUIP_Hide *message)
2310 struct IconList_DATA *data = INST_DATA(CLASS, obj);
2311 IPTR rc;
2313 #if defined(DEBUG_ILC_FUNCS)
2314 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
2315 #endif
2317 if ((rc = DoSuperMethodA(CLASS, obj, (Msg)message)))
2319 if ((data->icld_BufferRastPort) && (data->icld_BufferRastPort != data->icld_DisplayRastPort))
2321 FreeBitMap(data->icld_BufferRastPort->BitMap);
2322 FreeRastPort(data->icld_BufferRastPort);
2325 data->icld_BufferRastPort = NULL;
2327 if (data->icld_DisplayRastPort)
2328 FreeRastPort(data->icld_DisplayRastPort);
2330 data->icld_DisplayRastPort = NULL;
2332 return rc;
2336 ///MUIM_Cleanup()
2337 /**************************************************************************
2338 MUIM_Cleanup
2339 **************************************************************************/
2340 IPTR IconList__MUIM_Cleanup(struct IClass *CLASS, Object *obj, struct MUIP_Cleanup *message)
2342 struct IconList_DATA *data = INST_DATA(CLASS, obj);
2343 struct IconEntry *node = NULL;
2345 #if defined(DEBUG_ILC_FUNCS)
2346 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
2347 #endif
2349 #if defined(__AROS__)
2350 ForeachNode(&data->icld_IconList, node)
2351 #else
2352 Foreach_Node(&data->icld_IconList, node);
2353 #endif
2355 if (node->ie_DiskObj)
2357 FreeDiskObject(node->ie_DiskObj);
2358 node->ie_DiskObj = NULL;
2362 DoMethod(_win(obj), MUIM_Window_RemEventHandler, (IPTR)&data->ehn);
2364 return DoSuperMethodA(CLASS, obj, (Msg)message);
2368 ///MUIM_AskMinMax()
2369 /**************************************************************************
2370 MUIM_AskMinMax
2371 **************************************************************************/
2372 IPTR IconList__MUIM_AskMinMax(struct IClass *CLASS, Object *obj, struct MUIP_AskMinMax *message)
2374 ULONG rc = DoSuperMethodA(CLASS, obj, (Msg) message);
2376 #if defined(DEBUG_ILC_FUNCS)
2377 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
2378 #endif
2380 message->MinMaxInfo->MinWidth += 96;
2381 message->MinMaxInfo->MinHeight += 64;
2383 message->MinMaxInfo->DefWidth += 200;
2384 message->MinMaxInfo->DefHeight += 180;
2386 message->MinMaxInfo->MaxWidth = MUI_MAXMAX;
2387 message->MinMaxInfo->MaxHeight = MUI_MAXMAX;
2389 return rc;
2393 ///MUIM_Layout()
2394 /**************************************************************************
2395 MUIM_Layout
2396 **************************************************************************/
2397 IPTR IconList__MUIM_Layout(struct IClass *CLASS, Object *obj,struct MUIP_Layout *message)
2399 struct IconList_DATA *data = INST_DATA(CLASS, obj);
2400 ULONG rc;
2402 #if defined(DEBUG_ILC_FUNCS)
2403 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
2404 #endif
2406 rc = DoSuperMethodA(CLASS, obj, (Msg)message);
2408 data->icld_ViewWidth = _mwidth(obj);
2409 data->icld_ViewHeight = _mheight(obj);
2411 return rc;
2415 ///MUIM_Draw()
2416 /**************************************************************************
2417 MUIM_Draw - draw the IconList
2418 **************************************************************************/
2419 IPTR DrawCount;
2420 IPTR IconList__MUIM_Draw(struct IClass *CLASS, Object *obj, struct MUIP_Draw *message)
2422 struct IconList_DATA *data = INST_DATA(CLASS, obj);
2423 struct IconEntry *icon = NULL;
2425 APTR clip;
2427 ULONG update_oldwidth = 0,
2428 update_oldheight = 0;
2430 LONG clear_xoffset = 0,
2431 clear_yoffset = 0;
2433 IPTR draw_id = DrawCount++;
2435 #if defined(DEBUG_ILC_FUNCS)
2436 D(bug("[IconList]: %s(obj @ 0x%p)\n", __PRETTY_FUNCTION__, obj));
2437 #endif
2438 #if defined(DEBUG_ILC_ICONRENDERING)
2439 D(bug("[IconList] %s: id %d\n", __PRETTY_FUNCTION__, draw_id));
2440 #endif
2442 DoSuperMethodA(CLASS, obj, (Msg)message);
2444 if (!(data->icld__Option_IconListFixedBackground))
2446 clear_xoffset = data->icld_ViewX;
2447 clear_yoffset = data->icld_ViewY;
2450 // If window size changes, only update needed areas
2451 if (data->update_oldwidth == 0) data->update_oldwidth = data->icld_ViewWidth;
2452 if (data->update_oldheight == 0) data->update_oldheight = data->icld_ViewHeight;
2453 if ((data->update_oldwidth != data->icld_ViewWidth) || (data->update_oldheight != data->icld_ViewHeight))
2455 if (data->icld_UpdateMode != UPDATE_SCROLL)
2457 data->icld_UpdateMode = UPDATE_RESIZE;
2458 update_oldwidth = data->update_oldwidth;
2459 update_oldheight = data->update_oldheight;
2460 data->update_oldwidth = data->icld_ViewWidth;
2461 data->update_oldheight = data->icld_ViewHeight;
2465 if ((message->flags & MADF_DRAWUPDATE) || (data->icld_UpdateMode == UPDATE_RESIZE))
2467 #if defined(DEBUG_ILC_ICONRENDERING)
2469 if (message->flags & MADF_DRAWUPDATE)
2471 bug("[IconList] %s#%d: MADF_DRAWUPDATE\n", __PRETTY_FUNCTION__, draw_id);
2473 else
2475 bug("[IconList] %s#%d: UPDATE_RESIZE\n", __PRETTY_FUNCTION__, draw_id);
2478 #endif
2479 if ((data->icld_UpdateMode == UPDATE_SINGLEICON) && (data->update_icon != NULL)) /* draw only a single icon at update_icon */
2481 struct Rectangle rect;
2483 #if defined(DEBUG_ILC_ICONRENDERING)
2484 D(bug("[IconList] %s#%d: UPDATE_SINGLEICON (icon @ 0x%p)\n", __PRETTY_FUNCTION__, draw_id, data->update_icon));
2485 #endif
2487 IconList_GetIconAreaRectangle(obj, data, data->update_icon, &rect);
2489 rect.MinX += _mleft(obj) + (data->update_icon->ie_IconX - data->icld_ViewX);
2490 rect.MaxX += _mleft(obj) + (data->update_icon->ie_IconX - data->icld_ViewX);
2491 rect.MinY += _mtop(obj) + (data->update_icon->ie_IconY - data->icld_ViewY);
2492 rect.MaxY += _mtop(obj) + (data->update_icon->ie_IconY - data->icld_ViewY);
2494 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
2496 if (data->update_icon->ie_AreaWidth < data->icld_IconAreaLargestWidth)
2498 rect.MinX += ((data->icld_IconAreaLargestWidth - data->update_icon->ie_AreaWidth)/2);
2499 rect.MaxX += ((data->icld_IconAreaLargestWidth - data->update_icon->ie_AreaWidth)/2);
2502 if (data->update_icon->ie_AreaHeight < data->icld_IconAreaLargestHeight)
2504 rect.MinY += ((data->icld_IconAreaLargestHeight - data->update_icon->ie_AreaHeight)/2);
2505 rect.MaxY += ((data->icld_IconAreaLargestHeight - data->update_icon->ie_AreaHeight)/2);
2509 clip = MUI_AddClipping(muiRenderInfo(obj), _mleft(obj), _mtop(obj), _mwidth(obj), _mheight(obj));
2511 #if defined(DEBUG_ILC_ICONRENDERING)
2512 D(bug("[IconList] %s#%d: UPDATE_SINGLEICON: Calling MUIM_DrawBackground (A)\n", __PRETTY_FUNCTION__, draw_id));
2513 #endif
2514 DoMethod(obj, MUIM_DrawBackground,
2515 rect.MinX, rect.MinY,
2516 rect.MaxX - rect.MinX + 1, rect.MaxY - rect.MinY + 1,
2517 clear_xoffset, clear_yoffset,
2520 /* We could have deleted also other icons so they must be redrawn */
2521 #if defined(__AROS__)
2522 ForeachNode(&data->icld_IconList, icon)
2523 #else
2524 Foreach_Node(&data->icld_IconList, icon);
2525 #endif
2527 if ((icon != data->update_icon) && (icon->ie_Flags & ICONENTRY_FLAG_VISIBLE))
2529 struct Rectangle rect2;
2530 IconList_GetIconAreaRectangle(obj, data, icon, &rect2);
2532 rect2.MinX += _mleft(obj) - data->icld_ViewX + icon->ie_IconX;
2533 rect2.MaxX += _mleft(obj) - data->icld_ViewX + icon->ie_IconX;
2534 rect2.MinY += _mtop(obj) - data->icld_ViewY + icon->ie_IconY;
2535 rect2.MaxY += _mtop(obj) - data->icld_ViewY + icon->ie_IconY;
2537 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
2539 if (icon->ie_AreaWidth < data->icld_IconAreaLargestWidth)
2541 rect2.MinX += ((data->icld_IconAreaLargestWidth - icon->ie_AreaWidth)/2);
2542 rect2.MaxX += ((data->icld_IconAreaLargestWidth - icon->ie_AreaWidth)/2);
2545 if (icon->ie_AreaHeight < data->icld_IconAreaLargestHeight)
2547 rect2.MinY += ((data->icld_IconAreaLargestHeight - icon->ie_AreaHeight)/2);
2548 rect2.MaxY += ((data->icld_IconAreaLargestHeight - icon->ie_AreaHeight)/2);
2552 if (RectAndRect(&rect, &rect2))
2554 // Update icon here
2555 icon->ie_Flags |= ICONENTRY_FLAG_NEEDSUPDATE;
2556 DoMethod(obj, MUIM_IconList_DrawEntry, icon, ICONENTRY_DRAWMODE_PLAIN);
2557 DoMethod(obj, MUIM_IconList_DrawEntryLabel, icon, ICONENTRY_DRAWMODE_PLAIN);
2558 icon->ie_Flags &= ~ICONENTRY_FLAG_NEEDSUPDATE;
2563 icon->ie_Flags |= ICONENTRY_FLAG_NEEDSUPDATE;
2564 DoMethod(obj, MUIM_IconList_DrawEntry, data->update_icon, ICONENTRY_DRAWMODE_PLAIN);
2565 DoMethod(obj, MUIM_IconList_DrawEntryLabel, data->update_icon, ICONENTRY_DRAWMODE_PLAIN);
2566 icon->ie_Flags &= ~ICONENTRY_FLAG_NEEDSUPDATE;
2567 data->icld_UpdateMode = 0;
2568 data->update_icon = NULL;
2570 if (data->icld_DisplayRastPort != data->icld_BufferRastPort)
2572 #if defined(DEBUG_ILC_ICONRENDERING)
2573 D(bug("[IconList] %s#%d: UPDATE_SINGLEICON Blitting to front rastport..\n", __PRETTY_FUNCTION__, draw_id));
2574 #endif
2575 BltBitMapRastPort(data->icld_BufferRastPort->BitMap,
2576 rect.MinX - _mleft(obj), rect.MinY - _mtop(obj),
2577 data->icld_DisplayRastPort,
2578 rect.MinX, rect.MinY,
2579 rect.MaxX - rect.MinX + 1, rect.MaxY - rect.MinY + 1,
2580 0xC0);
2583 MUI_RemoveClipping(muiRenderInfo(obj),clip);
2584 goto draw_done;
2586 else if (data->icld_UpdateMode == UPDATE_SCROLL)
2588 struct Region *region = NULL;
2589 struct Rectangle xrect,
2590 yrect;
2591 BOOL scroll_caused_damage;
2593 #if defined(DEBUG_ILC_ICONRENDERING)
2594 D(bug("[IconList] %s#%d: UPDATE_SCROLL.\n", __PRETTY_FUNCTION__, draw_id));
2595 #endif
2597 if (!data->icld__Option_IconListFixedBackground)
2599 scroll_caused_damage = (_rp(obj)->Layer->Flags & LAYERREFRESH) ? FALSE : TRUE;
2601 data->icld_UpdateMode = 0;
2603 if ((abs(data->update_scrolldx) >= _mwidth(obj)) ||
2604 (abs(data->update_scrolldy) >= _mheight(obj)))
2606 #if defined(DEBUG_ILC_ICONRENDERING)
2607 D(bug("[IconList] %s#%d: UPDATE_SCROLL: Moved outside current view -> Causing Redraw .. MADF_DRAWOBJECT\n", __PRETTY_FUNCTION__, draw_id));
2608 #endif
2609 MUI_Redraw(obj, MADF_DRAWOBJECT);
2610 goto draw_done;
2613 if (!(region = NewRegion()))
2615 #if defined(DEBUG_ILC_ICONRENDERING)
2616 D(bug("[IconList] %s#%d: UPDATE_SCROLL: Couldnt Alloc Region -> Causing Redraw ...MADF_DRAWOBJECT\n", __PRETTY_FUNCTION__, draw_id));
2617 #endif
2618 MUI_Redraw(obj, MADF_DRAWOBJECT);
2619 goto draw_done;
2622 if (data->update_scrolldx > 0)
2624 xrect.MinX = _mright(obj) - data->update_scrolldx;
2625 xrect.MinY = _mtop(obj);
2626 xrect.MaxX = _mright(obj);
2627 xrect.MaxY = _mbottom(obj);
2629 OrRectRegion(region, &xrect);
2631 data->update_rect1 = &xrect;
2633 else if (data->update_scrolldx < 0)
2635 xrect.MinX = _mleft(obj);
2636 xrect.MinY = _mtop(obj);
2637 xrect.MaxX = _mleft(obj) - data->update_scrolldx;
2638 xrect.MaxY = _mbottom(obj);
2640 OrRectRegion(region, &xrect);
2642 data->update_rect1 = &xrect;
2645 if (data->update_scrolldy > 0)
2647 yrect.MinX = _mleft(obj);
2648 yrect.MinY = _mbottom(obj) - data->update_scrolldy;
2649 yrect.MaxX = _mright(obj);
2650 yrect.MaxY = _mbottom(obj);
2652 OrRectRegion(region, &yrect);
2654 data->update_rect2 = &yrect;
2656 else if (data->update_scrolldy < 0)
2658 yrect.MinX = _mleft(obj);
2659 yrect.MinY = _mtop(obj);
2660 yrect.MaxX = _mright(obj);
2661 yrect.MaxY = _mtop(obj) - data->update_scrolldy;
2663 OrRectRegion(region, &yrect);
2665 data->update_rect2 = &yrect;
2668 #if defined(DEBUG_ILC_ICONRENDERING)
2669 D(bug("[IconList] %s#%d: UPDATE_SCROLL: Scrolling Raster..\n", __PRETTY_FUNCTION__, draw_id));
2670 #endif
2671 if (data->icld_DisplayRastPort == data->icld_BufferRastPort)
2673 ScrollRasterBF(data->icld_BufferRastPort,
2674 data->update_scrolldx,
2675 data->update_scrolldy,
2676 _mleft(obj),
2677 _mtop(obj),
2678 _mright(obj),
2679 _mbottom(obj));
2681 else
2683 ScrollRasterBF(data->icld_BufferRastPort,
2684 data->update_scrolldx,
2685 data->update_scrolldy,
2688 _mwidth(obj),
2689 _mheight(obj));
2692 scroll_caused_damage = scroll_caused_damage && (_rp(obj)->Layer->Flags & LAYERREFRESH) ? TRUE : FALSE;
2694 clip = MUI_AddClipRegion(muiRenderInfo(obj), region);
2697 #if defined(DEBUG_ILC_ICONRENDERING)
2698 D(bug("[IconList] %s#%d: UPDATE_SCROLL: Causing Redraw -> MADF_DRAWOBJECT..\n", __PRETTY_FUNCTION__, draw_id));
2699 #endif
2700 MUI_Redraw(obj, MADF_DRAWOBJECT);
2702 data->update_rect1 = data->update_rect2 = NULL;
2704 if (!data->icld__Option_IconListFixedBackground)
2706 MUI_RemoveClipRegion(muiRenderInfo(obj), clip);
2708 if (scroll_caused_damage)
2710 if (MUI_BeginRefresh(muiRenderInfo(obj), 0))
2712 /* Theoretically it might happen that more damage is caused
2713 after ScrollRaster. By something else, like window movement
2714 in front of our window. Therefore refresh root object of
2715 window, not just this object */
2717 Object *o = NULL;
2719 GET(_win(obj),MUIA_Window_RootObject, &o);
2720 MUI_Redraw(o, MADF_DRAWOBJECT);
2721 #if defined(DEBUG_ILC_ICONRENDERING)
2722 D(bug("[IconList] %s#%d: UPDATE_SCROLL: Causing Redraw -> MADF_DRAWOBJECT..\n", __PRETTY_FUNCTION__, draw_id));
2723 #endif
2724 MUI_EndRefresh(muiRenderInfo(obj), 0);
2728 if (data->icld_DisplayRastPort != data->icld_BufferRastPort)
2730 #if defined(DEBUG_ILC_ICONRENDERING)
2731 D(bug("[IconList] %s#%d: UPDATE_SCROLL: Blitting to front rastport..\n", __PRETTY_FUNCTION__, draw_id));
2732 #endif
2733 BltBitMapRastPort(data->icld_BufferRastPort->BitMap,
2734 0, 0,
2735 data->icld_DisplayRastPort,
2736 _mleft(obj), _mtop(obj),
2737 _mwidth(obj), _mheight(obj),
2738 0xC0);
2740 goto draw_done;
2742 else if (data->icld_UpdateMode == UPDATE_RESIZE)
2744 struct Region *region = NULL;
2745 struct Rectangle wrect,
2746 hrect;
2747 ULONG diffw = 0,
2748 diffh = 0;
2750 #if defined(DEBUG_ILC_ICONRENDERING)
2751 D(bug("[IconList] %s#%d: UPDATE_RESIZE.\n", __PRETTY_FUNCTION__, draw_id));
2752 #endif
2754 if ((data->icld_BufferRastPort) && (data->icld_BufferRastPort != data->icld_DisplayRastPort))
2756 //Free up the buffers rastport and bitmap so we can replace them ..
2757 struct Bitmap *bitmap_Old = (struct Bitmap *)data->icld_BufferRastPort->BitMap;
2758 struct Bitmap *bitmap_New;
2760 ULONG tmp_RastDepth;
2762 data->icld_BufferRastPort->BitMap = NULL;
2764 FreeRastPort(data->icld_BufferRastPort);
2765 SET(obj, MUIA_IconList_BufferRastport, NULL);
2767 tmp_RastDepth = GetCyberMapAttr(data->icld_DisplayRastPort->BitMap, CYBRMATTR_DEPTH);
2768 if ((bitmap_New = (struct Bitmap *)AllocBitMap(data->icld_ViewWidth,
2769 data->icld_ViewHeight,
2770 tmp_RastDepth,
2771 BMF_CLEAR,
2772 data->icld_DisplayRastPort->BitMap))!=NULL)
2774 if ((data->icld_BufferRastPort = CreateRastPort())!=NULL)
2776 data->icld_BufferRastPort->BitMap = (struct BitMap *)bitmap_New;
2777 SET(obj, MUIA_IconList_BufferRastport, data->icld_BufferRastPort);
2778 data->icld_DrawOffsetX = 0;
2779 data->icld_DrawOffsetY = 0;
2781 else
2783 FreeBitMap((struct BitMap *)bitmap_New);
2784 data->icld_BufferRastPort = data->icld_DisplayRastPort;
2785 data->icld_DrawOffsetX = _mleft(obj);
2786 data->icld_DrawOffsetY = _mtop(obj);
2790 if (bitmap_Old != (struct Bitmap *)data->icld_BufferRastPort->BitMap)
2791 FreeBitMap((struct BitMap *)bitmap_Old);
2794 data->icld_UpdateMode = 0;
2796 if (!data->icld__Option_IconListScaledBackground)
2798 if (!(region = NewRegion()))
2800 #if defined(DEBUG_ILC_ICONRENDERING)
2801 D(bug("[IconList] %s#%d: UPDATE_RESIZE: Causing Redraw -> MADF_DRAWOBJECT..\n", __PRETTY_FUNCTION__, draw_id));
2802 #endif
2803 MUI_Redraw(obj, MADF_DRAWOBJECT);
2804 goto draw_done;
2807 if ( data->icld_ViewWidth > update_oldwidth )
2808 diffw = data->icld_ViewWidth - update_oldwidth;
2809 if ( data->icld_ViewHeight > update_oldheight )
2810 diffh = data->icld_ViewHeight - update_oldheight;
2812 if (diffw)
2814 wrect.MinX = _mright(obj) - diffw;
2815 wrect.MinY = _mtop(obj);
2816 wrect.MaxX = _mright(obj);
2817 wrect.MaxY = _mbottom(obj);
2818 OrRectRegion(region, &wrect);
2819 data->update_rect1 = &wrect;
2822 if (diffh)
2824 hrect.MinX = _mleft(obj);
2825 hrect.MinY = _mbottom(obj) - diffh;
2826 hrect.MaxX = _mright(obj);
2827 hrect.MaxX = _mright(obj);
2828 hrect.MaxY = _mbottom(obj);
2829 OrRectRegion(region, &hrect);
2830 data->update_rect2 = &hrect;
2832 if (diffh||diffw)
2834 clip = MUI_AddClipRegion(muiRenderInfo(obj), region);
2836 else
2838 /* View became smaller both in horizontal and vertical direction.
2839 Nothing to do */
2841 DisposeRegion(region);
2842 goto draw_done;
2846 #if defined(DEBUG_ILC_ICONRENDERING)
2847 D(bug("[IconList] %s#%d: UPDATE_RESIZE: Causing Redraw -> MADF_DRAWOBJECT..\n", __PRETTY_FUNCTION__, draw_id));
2848 #endif
2849 MUI_Redraw(obj, MADF_DRAWOBJECT);
2851 if (!data->icld__Option_IconListScaledBackground)
2853 if (diffh||diffw)
2855 data->update_rect1 = data->update_rect2 = NULL;
2856 MUI_RemoveClipRegion(muiRenderInfo(obj), clip);
2857 } else DisposeRegion(region);
2860 goto draw_done;
2864 if (message->flags & MADF_DRAWOBJECT)
2866 struct Rectangle viewrect;
2868 #if defined(DEBUG_ILC_ICONRENDERING)
2869 D(bug("[IconList] %s#%d: MADF_DRAWOBJECT\n", __PRETTY_FUNCTION__, draw_id));
2870 #endif
2872 clip = MUI_AddClipping(muiRenderInfo(obj), _mleft(obj), _mtop(obj), _mwidth(obj), _mheight(obj));
2874 viewrect.MinX = _mleft(obj);
2875 viewrect.MaxX = _mleft(obj) + _mwidth(obj);
2876 viewrect.MinY = _mtop(obj);
2877 viewrect.MaxY = _mtop(obj) + _mheight(obj);
2879 #if defined(DEBUG_ILC_ICONRENDERING)
2880 D(bug("[IconList] %s#%d: MADF_DRAWOBJECT: Calling MUIM_DrawBackground (B)\n", __PRETTY_FUNCTION__, draw_id));
2881 #endif
2882 DoMethod(
2883 obj, MUIM_DrawBackground, _mleft(obj), _mtop(obj), _mwidth(obj), _mheight(obj),
2884 clear_xoffset, clear_yoffset, 0
2886 #if defined(__AROS__)
2887 ForeachNode(&data->icld_IconList, icon)
2888 #else
2889 Foreach_Node(&data->icld_IconList, icon);
2890 #endif
2892 if ((icon->ie_Flags & ICONENTRY_FLAG_VISIBLE) &&
2893 (icon->ie_DiskObj) &&
2894 (icon->ie_IconX != NO_ICON_POSITION) &&
2895 (icon->ie_IconY != NO_ICON_POSITION))
2897 struct Rectangle iconrect;
2898 IconList_GetIconAreaRectangle(obj, data, icon, &iconrect);
2900 iconrect.MinX += _mleft(obj) - data->icld_ViewX + icon->ie_IconX;
2901 iconrect.MaxX += _mleft(obj) - data->icld_ViewX + icon->ie_IconX;
2902 iconrect.MinY += _mtop(obj) - data->icld_ViewY + icon->ie_IconY;
2903 iconrect.MaxY += _mtop(obj) - data->icld_ViewY + icon->ie_IconY;
2905 if (RectAndRect(&viewrect, &iconrect))
2907 DoMethod(obj, MUIM_IconList_DrawEntry, icon, ICONENTRY_DRAWMODE_PLAIN);
2908 DoMethod(obj, MUIM_IconList_DrawEntryLabel, icon, ICONENTRY_DRAWMODE_PLAIN);
2913 if (data->icld_DisplayRastPort != data->icld_BufferRastPort)
2915 #if defined(DEBUG_ILC_ICONRENDERING)
2916 D(bug("[IconList] %s#%d: MADF_DRAWOBJECT: Blitting to front rastport..\n", __PRETTY_FUNCTION__, draw_id));
2917 #endif
2918 BltBitMapRastPort(data->icld_BufferRastPort->BitMap,
2919 0, 0,
2920 data->icld_DisplayRastPort,
2921 _mleft(obj), _mtop(obj),
2922 _mwidth(obj), _mheight(obj),
2923 0xC0);
2926 MUI_RemoveClipping(muiRenderInfo(obj), clip);
2928 data->icld_UpdateMode = 0;
2930 draw_done:;
2932 #if defined(DEBUG_ILC_ICONRENDERING)
2933 D(bug("[IconList] %s: Draw finished for id %d\n", __PRETTY_FUNCTION__, draw_id));
2934 #endif
2935 return 0;
2939 ///IconList__MUIM_IconList_Update()
2940 /**************************************************************************
2941 MUIM_IconList_Refresh
2942 Implemented by subclasses
2943 **************************************************************************/
2944 IPTR IconList__MUIM_IconList_Update(struct IClass *CLASS, Object *obj, struct MUIP_IconList_Update *message)
2946 struct IconList_DATA *data = INST_DATA(CLASS, obj);
2948 #if defined(DEBUG_ILC_FUNCS)
2949 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
2950 #endif
2952 data->icld_FocusIcon = NULL;
2953 SET(obj, MUIA_IconList_Changed, TRUE);
2955 return 1;
2959 ///MUIM_IconList_Clear()
2960 /**************************************************************************
2961 MUIM_IconList_Clear
2962 **************************************************************************/
2963 IPTR IconList__MUIM_IconList_Clear(struct IClass *CLASS, Object *obj, struct MUIP_IconList_Clear *message)
2965 struct IconList_DATA *data = INST_DATA(CLASS, obj);
2966 struct IconEntry *node = NULL;
2968 #if defined(DEBUG_ILC_FUNCS)
2969 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
2970 #endif
2972 while ((node = (struct IconEntry*)RemTail((struct List*)&data->icld_IconList)))
2974 DoMethod(obj, MUIM_IconList_DestroyEntry, node);
2977 data->icld_SelectionLastClicked = NULL;
2978 data->icld_FocusIcon = NULL;
2980 data->icld_ViewX = data->icld_ViewY = data->icld_AreaWidth = data->icld_AreaHeight = 0;
2982 D(bug("[IconList]: %s: call SetSuperAttrs()\n", __PRETTY_FUNCTION__));
2983 SetSuperAttrs(CLASS, obj, MUIA_Virtgroup_Left, data->icld_ViewX,
2984 MUIA_Virtgroup_Top, data->icld_ViewY,
2985 TAG_DONE);
2987 D(bug("[IconList]: %s: call SetAttrs()\n", __PRETTY_FUNCTION__));
2988 SetAttrs(obj, MUIA_Virtgroup_Left, data->icld_ViewX,
2989 MUIA_Virtgroup_Top, data->icld_ViewY,
2990 TAG_DONE);
2992 D(bug("[IconList]: %s: Set MUIA_IconList_Width and MUIA_IconList_Height\n", __PRETTY_FUNCTION__));
2993 SetAttrs(obj, MUIA_IconList_Width, data->icld_AreaWidth,
2994 MUIA_IconList_Height, data->icld_AreaHeight,
2995 TAG_DONE);
2997 D(bug("[IconList]: %s: call MUI_Redraw()\n", __PRETTY_FUNCTION__));
2998 MUI_Redraw(obj,MADF_DRAWOBJECT);
2999 return 1;
3003 ///IconList__MUIM_IconList_DestroyEntry()
3004 IPTR IconList__MUIM_IconList_DestroyEntry(struct IClass *CLASS, Object *obj, struct MUIP_IconList_DestroyEntry *message)
3006 struct IconList_DATA *data = INST_DATA(CLASS, obj);
3008 #if defined(DEBUG_ILC_FUNCS)
3009 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
3010 #endif
3012 if (message->icon)
3014 if (message->icon->ie_Flags & ICONENTRY_FLAG_SELECTED)
3016 if (data->icld_SelectionLastClicked == message->icon)
3018 struct IconList_Entry *nextentry = &message->icon->ie_IconListEntry;
3020 /* get selected entries from SOURCE iconlist */
3021 DoMethod(obj, MUIM_IconList_NextIcon, MUIV_IconList_NextIcon_Selected, (IPTR)&nextentry);
3022 if ((nextentry) && (nextentry != (IPTR)MUIV_IconList_NextIcon_End))
3023 data->icld_SelectionLastClicked = (struct IconEntry *)((IPTR)nextentry - ((IPTR)&message->icon->ie_IconListEntry - (IPTR)message->icon));
3024 else
3025 data->icld_SelectionLastClicked = NULL;
3027 if (data->icld_FocusIcon == message->icon)
3028 data->icld_FocusIcon = data->icld_SelectionLastClicked;
3030 Remove(&message->icon->ie_SelectionNode);
3033 if (message->icon->ie_TxtBuf_DisplayedLabel)
3034 FreeVecPooled(data->icld_Pool, message->icon->ie_TxtBuf_DisplayedLabel);
3036 if (message->icon->ie_TxtBuf_PROT)
3037 FreePooled(data->icld_Pool, message->icon->ie_TxtBuf_PROT, 8);
3039 if (message->icon->ie_TxtBuf_SIZE)
3040 FreePooled(data->icld_Pool, message->icon->ie_TxtBuf_SIZE, 30);
3042 if (message->icon->ie_TxtBuf_TIME)
3043 FreePooled(data->icld_Pool, message->icon->ie_TxtBuf_TIME, LEN_DATSTRING);
3045 if (message->icon->ie_TxtBuf_DATE)
3046 FreePooled(data->icld_Pool, message->icon->ie_TxtBuf_DATE, LEN_DATSTRING);
3048 if (message->icon->ie_DiskObj)
3049 FreeDiskObject(message->icon->ie_DiskObj);
3051 if (message->icon->ie_FileInfoBlock)
3052 FreeMem(message->icon->ie_FileInfoBlock, sizeof(struct FileInfoBlock));
3054 if (message->icon->ie_IconListEntry.label)
3055 FreePooled(data->icld_Pool, message->icon->ie_IconListEntry.label, strlen(message->icon->ie_IconListEntry.label)+1);
3057 if (message->icon->ie_IconNode.ln_Name)
3058 FreePooled(data->icld_Pool, message->icon->ie_IconNode.ln_Name, strlen(message->icon->ie_IconNode.ln_Name)+1);
3060 FreePooled(data->icld_Pool, message->icon, sizeof(struct IconEntry));
3062 return (IPTR)TRUE;
3066 ///IconList__MUIM_IconList_CreateEntry()
3067 /**************************************************************************
3068 MUIM_IconList_CreateEntry.
3069 Returns 0 on failure otherwise it returns the icons entry ..
3070 **************************************************************************/
3071 IPTR IconList__MUIM_IconList_CreateEntry(struct IClass *CLASS, Object *obj, struct MUIP_IconList_CreateEntry *message)
3073 struct IconList_DATA *data = INST_DATA(CLASS, obj);
3074 struct IconEntry *entry = NULL;
3075 struct DateTime dt;
3076 struct DateStamp now;
3077 UBYTE *sp = NULL;
3079 struct DiskObject *dob = NULL;
3080 struct Rectangle rect;
3082 IPTR geticon_error = 0;
3084 #if defined(DEBUG_ILC_FUNCS)
3085 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
3086 #endif
3088 /*disk object (icon)*/
3089 if (message->icon_dob == NULL)
3091 IPTR iconlistScreen = _screen(obj);
3092 D(bug("[IconList] %s: IconList Screen @ 0x%p)\n", __PRETTY_FUNCTION__, iconlistScreen));
3094 dob = GetIconTags
3096 message->filename,
3097 (iconlistScreen) ? ICONGETA_Screen : TAG_IGNORE, iconlistScreen,
3098 (iconlistScreen) ? ICONGETA_RemapIcon : TAG_IGNORE, TRUE,
3099 ICONGETA_FailIfUnavailable, FALSE,
3100 ICONGETA_GenerateImageMasks, TRUE,
3101 ICONA_ErrorCode, &geticon_error,
3102 TAG_DONE
3105 if (dob == NULL)
3107 D(bug("[IconList] %s: Fatal: Couldnt get DiskObject! (error code = 0x%p)\n", __PRETTY_FUNCTION__, geticon_error));
3109 return (IPTR)NULL;
3112 else
3114 dob = message->icon_dob;
3117 D(bug("[IconList] %s: DiskObject @ 0x%p\n", __PRETTY_FUNCTION__, dob));
3119 if ((entry = AllocPooled(data->icld_Pool, sizeof(struct IconEntry))) == NULL)
3121 D(bug("[IconList] %s: Failed to Allocate Entry Storage!\n", __PRETTY_FUNCTION__));
3122 FreeDiskObject(dob);
3123 return (IPTR)NULL;
3125 memset(entry, 0, sizeof(struct IconEntry));
3126 entry->ie_Flags |= ICONENTRY_FLAG_NEEDSUPDATE;
3127 entry->ie_IconListEntry.ile_IconEntry = entry;
3129 /* Allocate Text Buffers */
3131 if ((entry->ie_TxtBuf_DATE = AllocPooled(data->icld_Pool, LEN_DATSTRING)) == NULL)
3133 D(bug("[IconList] %s: Failed to Allocate Entry DATE Storage!\n", __PRETTY_FUNCTION__));
3134 DoMethod(obj, MUIM_IconList_DestroyEntry, entry);
3135 return (IPTR)NULL;
3137 memset(entry->ie_TxtBuf_DATE, 0, LEN_DATSTRING);
3139 if ((entry->ie_TxtBuf_TIME = AllocPooled(data->icld_Pool, LEN_DATSTRING)) == NULL)
3141 D(bug("[IconList] %s: Failed to Allocate Entry TIME string Storage!\n", __PRETTY_FUNCTION__));
3142 DoMethod(obj, MUIM_IconList_DestroyEntry, entry);
3143 return (IPTR)NULL;
3145 memset(entry->ie_TxtBuf_TIME, 0, LEN_DATSTRING);
3147 if ((entry->ie_TxtBuf_SIZE = AllocPooled(data->icld_Pool, 30)) == NULL)
3149 D(bug("[IconList] %s: Failed to Allocate Entry SIZE string Storage!\n", __PRETTY_FUNCTION__));
3150 DoMethod(obj, MUIM_IconList_DestroyEntry, entry);
3151 return (IPTR)NULL;
3153 memset(entry->ie_TxtBuf_SIZE, 0, 30);
3155 if ((entry->ie_TxtBuf_PROT = AllocPooled(data->icld_Pool, 8)) == NULL)
3157 D(bug("[IconList] %s: Failed to Allocate Entry PROT Flag string Storage!\n", __PRETTY_FUNCTION__));
3158 DoMethod(obj, MUIM_IconList_DestroyEntry, entry);
3159 return (IPTR)NULL;
3161 memset(entry->ie_TxtBuf_PROT, 0, 8);
3163 /*alloc filename*/
3164 if ((entry->ie_IconNode.ln_Name = AllocPooled(data->icld_Pool, strlen(message->filename) + 1)) == NULL)
3166 D(bug("[IconList] %s: Failed to Allocate Entry filename string Storage!\n", __PRETTY_FUNCTION__));
3167 DoMethod(obj, MUIM_IconList_DestroyEntry, entry);
3168 return (IPTR)NULL;
3171 /*alloc icon label*/
3172 if ((entry->ie_IconListEntry.label = AllocPooled(data->icld_Pool, strlen(message->label) + 1)) == NULL)
3174 D(bug("[IconList] %s: Failed to Allocate Entry label string Storage!\n", __PRETTY_FUNCTION__));
3175 DoMethod(obj, MUIM_IconList_DestroyEntry, entry);
3176 return (IPTR)NULL;
3179 /*file info block*/
3180 if(message->fib != NULL)
3182 if ((entry->ie_FileInfoBlock = AllocMem(sizeof(struct FileInfoBlock), MEMF_CLEAR)) != NULL)
3184 CopyMem(message->fib, entry->ie_FileInfoBlock, sizeof(struct FileInfoBlock));
3186 if (entry->ie_FileInfoBlock->fib_DirEntryType > 0)
3188 strcpy(entry->ie_TxtBuf_SIZE, "Drawer");
3190 else
3192 FmtSizeToString(entry->ie_TxtBuf_SIZE, entry->ie_FileInfoBlock->fib_Size);
3195 dt.dat_Stamp = entry->ie_FileInfoBlock->fib_Date;
3196 dt.dat_Format = FORMAT_DEF;
3197 dt.dat_Flags = 0;
3198 dt.dat_StrDay = NULL;
3199 dt.dat_StrDate = entry->ie_TxtBuf_DATE;
3200 dt.dat_StrTime = entry->ie_TxtBuf_TIME;
3202 DateToStr(&dt);
3203 DateStamp(&now);
3205 /*if modified today show time, otherwise just show date*/
3206 if (now.ds_Days == entry->ie_FileInfoBlock->fib_Date.ds_Days)
3207 entry->ie_Flags |= ICONENTRY_FLAG_TODAY;
3208 else
3209 entry->ie_Flags &= ~ICONENTRY_FLAG_TODAY;
3211 sp = entry->ie_TxtBuf_PROT;
3212 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_SCRIPT) ? 's' : '-';
3213 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_PURE) ? 'p' : '-';
3214 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_ARCHIVE) ? 'a' : '-';
3215 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_READ) ? '-' : 'r';
3216 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_WRITE) ? '-' : 'w';
3217 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_EXECUTE) ? '-' : 'e';
3218 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_DELETE) ? '-' : 'd';
3219 *sp++ = '\0';
3221 entry->ie_IconListEntry.type = entry->ie_FileInfoBlock->fib_DirEntryType;
3224 else
3226 entry->ie_IconListEntry.type = ST_USERDIR;
3229 /* Override type if specified during createntry */
3230 if (message->type != 0)
3232 entry->ie_IconListEntry.type = message->type;
3233 D(bug("[IconList] %s: Overide Entry Type. New Type = %x\n", __PRETTY_FUNCTION__, entry->ie_IconListEntry.type));
3235 else
3237 D(bug("[IconList] %s: Entry Type = %x\n", __PRETTY_FUNCTION__, entry->ie_IconListEntry.type));
3240 strcpy(entry->ie_IconNode.ln_Name, message->filename);
3241 strcpy(entry->ie_IconListEntry.label, message->label);
3243 entry->ie_IconListEntry.udata = NULL;
3245 if (IconList__LabelFunc_CreateLabel(obj, data, entry) != (IPTR)NULL)
3247 entry->ie_DiskObj = dob;
3249 /* Use a geticonrectangle routine that gets textwidth! */
3250 IconList_GetIconAreaRectangle(obj, data, entry, &rect);
3252 return (IPTR)entry;
3255 DoMethod(obj, MUIM_IconList_DestroyEntry, entry);
3256 return (IPTR)NULL;
3260 ///IconList__MUIM_IconList_UpdateEntry()
3261 /**************************************************************************
3262 MUIM_IconList_UpdateEntry.
3263 Returns 0 on failure otherwise it returns the icons entry ..
3264 **************************************************************************/
3265 IPTR IconList__MUIM_IconList_UpdateEntry(struct IClass *CLASS, Object *obj, struct MUIP_IconList_UpdateEntry *message)
3267 struct IconList_DATA *data = INST_DATA(CLASS, obj);
3268 struct DateTime dt;
3269 struct DateStamp now;
3270 UBYTE *sp = NULL;
3272 struct DiskObject *dob = NULL;
3273 struct Rectangle rect;
3275 IPTR geticon_error = 0;
3277 #if defined(DEBUG_ILC_FUNCS)
3278 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
3279 #endif
3281 /* Update disk object (icon)*/
3282 /* if (message->icon_dob == NULL)
3284 IPTR iconlistScreen = _screen(obj);
3285 D(bug("[IconList] %s: IconList Screen @ 0x%p)\n", __PRETTY_FUNCTION__, iconlistScreen));
3287 dob = GetIconTags
3289 message->filename,
3290 (iconlistScreen) ? ICONGETA_Screen : TAG_IGNORE, iconlistScreen,
3291 (iconlistScreen) ? ICONGETA_RemapIcon : TAG_IGNORE, TRUE,
3292 ICONGETA_FailIfUnavailable, FALSE,
3293 ICONGETA_GenerateImageMasks, TRUE,
3294 ICONA_ErrorCode, &geticon_error,
3295 TAG_DONE
3298 if (dob == NULL)
3300 D(bug("[IconList] %s: Fatal: Couldnt get DiskObject! (error code = 0x%p)\n", __PRETTY_FUNCTION__, geticon_error));
3302 return (IPTR)NULL;
3305 else
3307 dob = message->icon_dob;
3310 D(bug("[IconList] %s: DiskObject @ 0x%p\n", __PRETTY_FUNCTION__, dob));
3313 /* Update filename */
3314 if (strcmp(message->icon->ie_IconNode.ln_Name, message->filename) != 0)
3316 message->icon->ie_Flags |= ICONENTRY_FLAG_NEEDSUPDATE;
3317 FreePooled(data->icld_Pool, message->icon->ie_IconNode.ln_Name, strlen(message->icon->ie_IconNode.ln_Name) + 1);
3318 if ((message->icon->ie_IconNode.ln_Name = AllocPooled(data->icld_Pool, strlen(message->filename) + 1)) == NULL)
3320 D(bug("[IconList] %s: Failed to Allocate Entry filename string Storage!\n", __PRETTY_FUNCTION__));
3321 DoMethod(obj, MUIM_IconList_DestroyEntry, message->icon);
3322 return (IPTR)NULL;
3324 strcpy(message->icon->ie_IconNode.ln_Name, message->filename);
3327 /* Update icon label */
3328 if (strcmp(message->icon->ie_IconListEntry.label, message->label) != 0)
3330 message->icon->ie_Flags |= ICONENTRY_FLAG_NEEDSUPDATE;
3331 FreePooled(data->icld_Pool, message->icon->ie_IconListEntry.label, strlen(message->icon->ie_IconListEntry.label) + 1);
3332 if ((message->icon->ie_IconListEntry.label = AllocPooled(data->icld_Pool, strlen(message->label) + 1)) == NULL)
3334 D(bug("[IconList] %s: Failed to Allocate Entry label string Storage!\n", __PRETTY_FUNCTION__));
3335 DoMethod(obj, MUIM_IconList_DestroyEntry, message->icon);
3336 return (IPTR)NULL;
3338 strcpy(message->icon->ie_IconListEntry.label, message->label);
3339 if (IconList__LabelFunc_CreateLabel(obj, data, message->icon) == (IPTR)NULL)
3341 D(bug("[IconList] %s: Failed to create label\n", __PRETTY_FUNCTION__));
3342 DoMethod(obj, MUIM_IconList_DestroyEntry, message->icon);
3343 return (IPTR)NULL;
3347 /* Update file info block */
3348 if(message->fib != NULL)
3350 if (!(message->icon->ie_FileInfoBlock))
3352 if ((message->icon->ie_FileInfoBlock = AllocMem(sizeof(struct FileInfoBlock), MEMF_CLEAR)) != NULL)
3354 CopyMem(message->fib, message->icon->ie_FileInfoBlock, sizeof(struct FileInfoBlock));
3358 /* if (entry->ie_FileInfoBlock->fib_DirEntryType > 0)
3360 strcpy(entry->ie_TxtBuf_SIZE, "Drawer");
3362 else
3364 FmtSizeToString(entry->ie_TxtBuf_SIZE, entry->ie_FileInfoBlock->fib_Size);
3367 dt.dat_Stamp = entry->ie_FileInfoBlock->fib_Date;
3368 dt.dat_Format = FORMAT_DEF;
3369 dt.dat_Flags = 0;
3370 dt.dat_StrDay = NULL;
3371 dt.dat_StrDate = entry->ie_TxtBuf_DATE;
3372 dt.dat_StrTime = entry->ie_TxtBuf_TIME;
3374 DateToStr(&dt);
3375 DateStamp(&now);
3377 //if modified today show time, otherwise just show date
3378 if (now.ds_Days == entry->ie_FileInfoBlock->fib_Date.ds_Days)
3379 entry->ie_Flags |= ICONENTRY_FLAG_TODAY;
3380 else
3381 entry->ie_Flags &= ~ICONENTRY_FLAG_TODAY;
3383 sp = entry->ie_TxtBuf_PROT;
3384 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_SCRIPT) ? 's' : '-';
3385 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_PURE) ? 'p' : '-';
3386 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_ARCHIVE) ? 'a' : '-';
3387 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_READ) ? '-' : 'r';
3388 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_WRITE) ? '-' : 'w';
3389 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_EXECUTE) ? '-' : 'e';
3390 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_DELETE) ? '-' : 'd';
3391 *sp++ = '\0';
3393 entry->ie_IconListEntry.type = entry->ie_FileInfoBlock->fib_DirEntryType;
3396 else
3398 if (message->icon->ie_FileInfoBlock)
3399 FreeMem(message->icon->ie_FileInfoBlock, sizeof(struct FileInfoBlock));
3401 if (message->icon->ie_IconListEntry.type != ST_USERDIR)
3403 message->icon->ie_Flags |= ICONENTRY_FLAG_NEEDSUPDATE;
3404 message->icon->ie_IconListEntry.type = ST_USERDIR;
3408 /* Override type if specified */
3409 if ((message->type != 0) && (message->icon->ie_IconListEntry.type != message->type))
3411 message->icon->ie_Flags |= ICONENTRY_FLAG_NEEDSUPDATE;
3412 message->icon->ie_IconListEntry.type = message->type;
3413 D(bug("[IconList] %s: Overide Entry Type. New Type = %x\n", __PRETTY_FUNCTION__, message->icon->ie_IconListEntry.type));
3415 else
3417 D(bug("[IconList] %s: Entry Type = %x\n", __PRETTY_FUNCTION__, message->icon->ie_IconListEntry.type));
3420 IconList_GetIconAreaRectangle(obj, data, message->icon, &rect);
3422 return (IPTR)message->icon;
3426 ///DoWheelMove()
3427 static void DoWheelMove(struct IClass *CLASS, Object *obj, LONG wheelx, LONG wheely, UWORD qual)
3429 struct IconList_DATA *data = INST_DATA(CLASS, obj);
3431 LONG newleft = data->icld_ViewX,
3432 newtop = data->icld_ViewY;
3434 /* Use horizontal scrolling if any of the following cases are true ...
3436 # vertical wheel is used but there's nothing to scroll
3437 (everything is visible already) ..
3439 # vertical wheel is used and one of the ALT keys is down. */
3441 if ((wheely && !wheelx) &&
3442 ((data->icld_AreaHeight <= _mheight(obj)) || (qual & (IEQUALIFIER_LALT | IEQUALIFIER_RALT))))
3444 wheelx = wheely; wheely = 0;
3447 if (qual & (IEQUALIFIER_CONTROL))
3449 if (wheelx < 0) newleft = 0;
3450 if (wheelx > 0) newleft = data->icld_AreaWidth;
3451 if (wheely < 0) newtop = 0;
3452 if (wheely > 0) newtop = data->icld_AreaHeight;
3454 else if (qual & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
3456 newleft += (wheelx * _mwidth(obj));
3457 newtop += (wheely * _mheight(obj));
3459 else
3461 newleft += wheelx * 30;
3462 newtop += wheely * 30;
3465 if (newleft + _mwidth(obj) > data->icld_AreaWidth)
3466 newleft = data->icld_AreaWidth - _mwidth(obj);
3467 if (newleft < 0)
3468 newleft = 0;
3470 if (newtop + _mheight(obj) > data->icld_AreaHeight)
3471 newtop = data->icld_AreaHeight - _mheight(obj);
3472 if (newtop < 0)
3473 newtop = 0;
3475 if ((newleft != data->icld_ViewX) || (newtop != data->icld_ViewY))
3477 SetAttrs(obj, MUIA_Virtgroup_Left, newleft,
3478 MUIA_Virtgroup_Top, newtop,
3479 TAG_DONE);
3484 ///MUIM_HandleEvent()
3485 /**************************************************************************
3486 MUIM_HandleEvent
3487 **************************************************************************/
3488 IPTR IconList__MUIM_HandleEvent(struct IClass *CLASS, Object *obj, struct MUIP_HandleEvent *message)
3490 struct IconList_DATA *data = INST_DATA(CLASS, obj);
3492 #if defined(DEBUG_ILC_FUNCS)
3493 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
3494 #endif
3496 if (message->imsg)
3498 LONG mx = message->imsg->MouseX - _mleft(obj);
3499 LONG my = message->imsg->MouseY - _mtop(obj);
3501 LONG wheelx = 0;
3502 LONG wheely = 0;
3504 switch (message->imsg->Class)
3506 case IDCMP_RAWKEY:
3508 #if defined(DEBUG_ILC_EVENTS)
3509 D(bug("[IconList] %s: IDCMP_RAWKEY\n", __PRETTY_FUNCTION__));
3510 #endif
3511 BOOL rawkey_handled = FALSE;
3513 switch(message->imsg->Code)
3515 case RAWKEY_NM_WHEEL_UP:
3516 wheely = -1;
3517 rawkey_handled = TRUE;
3518 break;
3520 case RAWKEY_NM_WHEEL_DOWN:
3521 wheely = 1;
3522 rawkey_handled = TRUE;
3523 break;
3525 case RAWKEY_NM_WHEEL_LEFT:
3526 wheelx = -1;
3527 rawkey_handled = TRUE;
3528 break;
3530 case RAWKEY_NM_WHEEL_RIGHT:
3531 wheelx = 1;
3532 rawkey_handled = TRUE;
3533 break;
3536 if (rawkey_handled)
3538 #if defined(DEBUG_ILC_KEYEVENTS)
3539 D(bug("[IconList] %s: Processing mouse wheel event\n", __PRETTY_FUNCTION__));
3540 #endif
3541 if (_isinobject(message->imsg->MouseX, message->imsg->MouseY) &&
3542 (wheelx || wheely))
3544 DoWheelMove(CLASS, obj, wheelx, wheely, message->imsg->Qualifier);
3547 else if (!(message->imsg->Code & IECODE_UP_PREFIX))
3549 LONG new_ViewY = data->icld_ViewY;
3550 struct IconEntry *start_entry = NULL, *active_entry = NULL, *entry_next = NULL;
3551 IPTR start_X = 0, start_Y = 0, active_X = 0, active_Y = 0, next_X = 0, next_Y = 0;
3552 IPTR x_diff = 0;
3554 #if defined(DEBUG_ILC_KEYEVENTS)
3555 D(bug("[IconList] %s: Processing key up event\n", __PRETTY_FUNCTION__));
3556 #endif
3558 switch(message->imsg->Code)
3560 case RAWKEY_RETURN:
3561 rawkey_handled = TRUE;
3563 #if defined(DEBUG_ILC_KEYEVENTS)
3564 D(bug("[IconList] %s: RAWKEY_RETURN\n", __PRETTY_FUNCTION__));
3565 #endif
3567 if (data->icld_FocusIcon) active_entry = data->icld_FocusIcon;
3568 else if (data->icld_SelectionLastClicked) active_entry = data->icld_SelectionLastClicked;
3570 if (active_entry)
3572 if (!(active_entry->ie_Flags & ICONENTRY_FLAG_SELECTED))
3574 active_entry->ie_Flags |= ICONENTRY_FLAG_SELECTED;
3575 AddTail(&data->icld_SelectionList, &active_entry->ie_SelectionNode);
3576 data->icld_UpdateMode = UPDATE_SINGLEICON;
3577 data->update_icon = active_entry;
3578 MUI_Redraw(obj, MADF_DRAWUPDATE);
3580 data->icld_SelectionLastClicked = active_entry;
3581 data->icld_FocusIcon = active_entry;
3583 SET(obj, MUIA_IconList_DoubleClick, TRUE);
3585 break;
3587 case RAWKEY_SPACE:
3588 rawkey_handled = TRUE;
3590 #if defined(DEBUG_ILC_KEYEVENTS)
3591 D(bug("[IconList] %s: RAWKEY_SPACE\n", __PRETTY_FUNCTION__));
3592 #endif
3594 if (data->icld_FocusIcon) active_entry = data->icld_FocusIcon;
3595 else if (data->icld_SelectionLastClicked) active_entry = data->icld_SelectionLastClicked;
3597 if (!(message->imsg->Qualifier & IEQUALIFIER_LSHIFT) && ((data->icld_SelectionLastClicked)||(data->icld_SelectionLastClicked != active_entry)))
3599 #if defined(DEBUG_ILC_KEYEVENTS)
3600 D(bug("[IconList] %s: SPACE: Clearing selected icons ..\n", __PRETTY_FUNCTION__));
3601 #endif
3602 DoMethod(obj, MUIM_IconList_UnselectAll);
3605 if (active_entry)
3607 if (!(active_entry->ie_Flags & ICONENTRY_FLAG_SELECTED))
3609 AddTail(&data->icld_SelectionList, &active_entry->ie_SelectionNode);
3610 active_entry->ie_Flags |= ICONENTRY_FLAG_SELECTED;
3611 data->icld_SelectionLastClicked = active_entry;
3613 else
3615 Remove(&active_entry->ie_SelectionNode);
3616 active_entry->ie_Flags &= ~ICONENTRY_FLAG_SELECTED;
3619 data->icld_FocusIcon = active_entry;
3621 data->icld_UpdateMode = UPDATE_SINGLEICON;
3622 data->update_icon = active_entry;
3623 MUI_Redraw(obj, MADF_DRAWUPDATE);
3625 break;
3627 case RAWKEY_PAGEUP:
3628 rawkey_handled = TRUE;
3630 #if defined(DEBUG_ILC_KEYEVENTS)
3631 D(bug("[IconList] %s: RAWKEY_PAGEUP\n", __PRETTY_FUNCTION__));
3632 #endif
3634 if (data->icld_AreaHeight > data->icld_ViewHeight)
3636 new_ViewY -= data->icld_ViewHeight;
3637 if (new_ViewY< 0)
3638 new_ViewY = 0;
3641 if (new_ViewY != data->icld_ViewY)
3643 SET(obj, MUIA_Virtgroup_Top, new_ViewY);
3645 break;
3647 case RAWKEY_PAGEDOWN:
3648 rawkey_handled = TRUE;
3650 #if defined(DEBUG_ILC_KEYEVENTS)
3651 D(bug("[IconList] %s: RAWKEY_PAGEDOWN\n", __PRETTY_FUNCTION__));
3652 #endif
3654 if (data->icld_AreaHeight > data->icld_ViewHeight)
3656 new_ViewY += data->icld_ViewHeight;
3657 if (new_ViewY > (data->icld_AreaHeight - data->icld_ViewHeight))
3658 new_ViewY = data->icld_AreaHeight - data->icld_ViewHeight;
3661 if (new_ViewY != data->icld_ViewY)
3663 SET(obj, MUIA_Virtgroup_Top, new_ViewY);
3665 break;
3667 case RAWKEY_UP:
3668 rawkey_handled = TRUE;
3670 #if defined(DEBUG_ILC_KEYEVENTS)
3671 D(bug("[IconList] %s: RAWKEY_UP\n", __PRETTY_FUNCTION__));
3672 #endif
3674 if (data->icld_FocusIcon)
3676 start_entry = data->icld_FocusIcon;
3677 #if defined(DEBUG_ILC_KEYEVENTS)
3678 D(bug("[IconList] %s: UP: Clearing existing focused icon @ 0x%p\n", __PRETTY_FUNCTION__, start_entry));
3679 #endif
3681 start_entry->ie_Flags &= ~ICONENTRY_FLAG_FOCUS;
3682 data->icld_UpdateMode = UPDATE_SINGLEICON;
3683 data->update_icon = start_entry;
3684 MUI_Redraw(obj, MADF_DRAWUPDATE);
3686 start_X = start_entry->ie_IconX;
3687 start_Y = start_entry->ie_IconY;
3688 #if defined(DEBUG_ILC_KEYEVENTS)
3689 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));
3690 #endif
3691 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
3693 if (start_entry->ie_AreaWidth < data->icld_IconAreaLargestWidth)
3695 start_X = start_X - ((data->icld_IconAreaLargestWidth - start_entry->ie_AreaWidth)/2);
3696 #if defined(DEBUG_ILC_KEYEVENTS)
3697 D(bug("[IconList] %s: UP: adjusted start_X for grid = %d\n", __PRETTY_FUNCTION__, start_X));
3698 #endif
3702 if ((active_entry = Node_PreviousVisible(start_entry)) && !(data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL))
3704 //Check if we are at the edge of the icon area ..
3705 #if defined(DEBUG_ILC_KEYEVENTS)
3706 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));
3707 #endif
3708 active_Y = active_entry->ie_IconY;
3710 if (active_Y == start_Y)
3713 #if defined(DEBUG_ILC_KEYEVENTS)
3714 D(bug("[IconList] %s: UP: active_entry is on our row (not at the edge)\n", __PRETTY_FUNCTION__));
3715 #endif
3716 entry_next = active_entry;
3717 next_X = entry_next->ie_IconX;
3718 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
3720 if (entry_next->ie_AreaWidth < data->icld_IconAreaLargestWidth)
3721 next_X = next_X - ((data->icld_IconAreaLargestWidth - entry_next->ie_AreaWidth)/2);
3725 #if defined(DEBUG_ILC_KEYEVENTS)
3726 D(bug("[IconList] %s: UP: using start_X %d, start_Y %d\n", __PRETTY_FUNCTION__, start_X, start_Y));
3727 #endif
3730 if (!(message->imsg->Qualifier & IEQUALIFIER_LSHIFT) && ((data->icld_SelectionLastClicked)&&(data->icld_SelectionLastClicked != active_entry)))
3732 #if defined(DEBUG_ILC_KEYEVENTS)
3733 D(bug("[IconList] %s: UP: Clearing selected icons ..\n", __PRETTY_FUNCTION__));
3734 #endif
3735 DoMethod(obj, MUIM_IconList_UnselectAll);
3738 #if defined(DEBUG_ILC_KEYEVENTS)
3739 D(bug("[IconList] %s: UP: active = 0x%p, next = 0x%p\n", __PRETTY_FUNCTION__, active_entry, entry_next));
3740 #endif
3741 if (!(active_entry))
3743 // If nothing is selected we will use the last visible icon ..
3744 active_entry = Node_LastVisible(&data->icld_IconList);
3745 start_X = active_entry->ie_IconX;
3746 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
3748 if (active_entry->ie_AreaWidth < data->icld_IconAreaLargestWidth)
3749 start_X = start_X - ((data->icld_IconAreaLargestWidth - active_entry->ie_AreaWidth)/2);
3751 start_Y = active_entry->ie_IconY;
3754 while (active_entry != NULL)
3756 #if defined(DEBUG_ILC_KEYEVENTS)
3757 D(bug("[IconList] %s: UP: Checking active @ 0x%p\n", __PRETTY_FUNCTION__, active_entry));
3758 #endif
3759 if (data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL)
3761 // Return the first visible since the list flow direction matches
3762 // our cursor direction
3763 if (active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE)
3764 break;
3766 else
3768 active_X = active_entry->ie_IconX;
3770 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
3772 if (active_entry->ie_AreaWidth < data->icld_IconAreaLargestWidth)
3773 x_diff = ((data->icld_IconAreaLargestWidth - active_entry->ie_AreaWidth)/2);
3775 active_Y = active_entry->ie_IconY;
3777 if (start_entry)
3779 if (entry_next)
3781 if ((active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE) &&
3782 (active_Y < start_Y) &&
3783 (((active_X - x_diff) >= start_X ) &&
3784 ((active_X - x_diff) <= (start_X + start_entry->ie_AreaWidth + (x_diff*2)))))
3786 #if defined(DEBUG_ILC_KEYEVENTS)
3787 D(bug("[IconList] %s: UP: (A) entry 0x%p matches\n", __PRETTY_FUNCTION__, active_entry));
3788 #endif
3789 break;
3791 else if (active_entry == (struct IconEntry *)GetHead(&data->icld_IconList))
3793 #if defined(DEBUG_ILC_KEYEVENTS)
3794 D(bug("[IconList] %s: UP: (A) reached list start .. restarting from the end ..\n", __PRETTY_FUNCTION__));
3795 #endif
3796 start_X = next_X;
3798 if ((entry_next = Node_PreviousVisible(entry_next)))
3800 if (entry_next->ie_IconX > start_X)
3801 entry_next = NULL;
3802 else
3804 next_X = entry_next->ie_IconX;
3805 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
3807 if (entry_next->ie_AreaWidth < data->icld_IconAreaLargestWidth)
3808 next_X = next_X - ((data->icld_IconAreaLargestWidth - entry_next->ie_AreaWidth)/2);
3812 start_Y = 0;
3813 #if defined(DEBUG_ILC_KEYEVENTS)
3814 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));
3815 #endif
3816 active_entry = Node_LastVisible(&data->icld_IconList);
3819 else
3821 if ((active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE) &&
3822 (active_Y < start_Y) &&
3823 ((active_X + x_diff) < (start_X + start_entry->ie_AreaWidth + x_diff)))
3825 #if defined(DEBUG_ILC_KEYEVENTS)
3826 D(bug("[IconList] %s: UP: (B) entry 0x%p matches\n", __PRETTY_FUNCTION__, active_entry));
3827 #endif
3828 break;
3832 else
3834 if (active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE)
3836 #if defined(DEBUG_ILC_KEYEVENTS)
3837 D(bug("[IconList] %s: UP: (C) entry 0x%p matches\n", __PRETTY_FUNCTION__, active_entry));
3838 #endif
3839 break;
3843 active_entry = (struct IconEntry *)(((struct Node *)active_entry)->ln_Pred);
3846 if (!(active_entry))
3848 #if defined(DEBUG_ILC_KEYEVENTS)
3849 D(bug("[IconList] %s: UP: No Next UP Node - Getting Last visible icon ..\n", __PRETTY_FUNCTION__));
3850 #endif
3851 /* We didnt find a "next UP" icon so just use the last visible */
3852 active_entry = Node_LastVisible(&data->icld_IconList);
3855 if (active_entry)
3857 if (!(active_entry->ie_Flags & ICONENTRY_FLAG_FOCUS))
3859 active_entry->ie_Flags |= ICONENTRY_FLAG_FOCUS;
3860 data->icld_UpdateMode = UPDATE_SINGLEICON;
3861 data->update_icon = active_entry;
3862 MUI_Redraw(obj, MADF_DRAWUPDATE);
3865 data->icld_FocusIcon = active_entry;
3866 break;
3868 case RAWKEY_DOWN:
3869 rawkey_handled = TRUE;
3871 #if defined(DEBUG_ILC_KEYEVENTS)
3872 D(bug("[IconList] %s: RAWKEY_DOWN\n", __PRETTY_FUNCTION__));
3873 #endif
3874 if (data->icld_FocusIcon)
3876 start_entry = data->icld_FocusIcon;
3877 #if defined(DEBUG_ILC_KEYEVENTS)
3878 D(bug("[IconList] %s: DOWN: Clearing existing focused icon @ 0x%p\n", __PRETTY_FUNCTION__, start_entry));
3879 #endif
3881 start_entry->ie_Flags &= ~ICONENTRY_FLAG_FOCUS;
3882 data->icld_UpdateMode = UPDATE_SINGLEICON;
3883 data->update_icon = start_entry;
3884 MUI_Redraw(obj, MADF_DRAWUPDATE);
3886 start_X = start_entry->ie_IconX;
3887 start_Y = start_entry->ie_IconY;
3888 #if defined(DEBUG_ILC_KEYEVENTS)
3889 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));
3890 #endif
3891 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
3893 if (start_entry->ie_AreaWidth < data->icld_IconAreaLargestWidth)
3895 start_X = start_X - ((data->icld_IconAreaLargestWidth - start_entry->ie_AreaWidth)/2);
3896 #if defined(DEBUG_ILC_KEYEVENTS)
3897 D(bug("[IconList] %s: DOWN: adjusted start_X for grid = %d\n", __PRETTY_FUNCTION__, start_X));
3898 #endif
3902 if ((active_entry = Node_NextVisible(start_entry)) &&
3903 (!(data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL)))
3905 #if defined(DEBUG_ILC_KEYEVENTS)
3906 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));
3907 #endif
3908 active_Y = active_entry->ie_IconY;
3910 if (active_Y == start_Y)
3913 #if defined(DEBUG_ILC_KEYEVENTS)
3914 D(bug("[IconList] %s: DOWN: active_entry is on our row (not at the edge)\n", __PRETTY_FUNCTION__));
3915 #endif
3916 entry_next = active_entry;
3917 next_X = entry_next->ie_IconX;
3918 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
3920 if (entry_next->ie_AreaWidth < data->icld_IconAreaLargestWidth)
3921 next_X = next_X - ((data->icld_IconAreaLargestWidth - entry_next->ie_AreaWidth)/2);
3925 #if defined(DEBUG_ILC_KEYEVENTS)
3926 D(bug("[IconList] %s: DOWN: using start_X %d, start_Y %d\n", __PRETTY_FUNCTION__, start_X, start_Y));
3927 #endif
3930 if (!(message->imsg->Qualifier & IEQUALIFIER_LSHIFT) && ((data->icld_SelectionLastClicked)&&(data->icld_SelectionLastClicked != active_entry)))
3932 #if defined(DEBUG_ILC_KEYEVENTS)
3933 D(bug("[IconList] %s: DOWN: Clearing selected icons ..\n", __PRETTY_FUNCTION__));
3934 #endif
3935 DoMethod(obj, MUIM_IconList_UnselectAll);
3938 #if defined(DEBUG_ILC_KEYEVENTS)
3939 D(bug("[IconList] %s: DOWN: active = 0x%p, next = 0x%p\n", __PRETTY_FUNCTION__, active_entry, entry_next));
3940 #endif
3941 if (!(active_entry))
3943 // If nothing is selected we will use the First visible icon ..
3944 active_entry = Node_FirstVisible(&data->icld_IconList);
3945 start_X = active_entry->ie_IconX;
3946 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
3948 if (active_entry->ie_AreaWidth < data->icld_IconAreaLargestWidth)
3949 start_X = start_X - ((data->icld_IconAreaLargestWidth - active_entry->ie_AreaWidth)/2);
3951 start_Y = active_entry->ie_IconY;
3954 while (active_entry != NULL)
3956 #if defined(DEBUG_ILC_KEYEVENTS)
3957 D(bug("[IconList] %s: DOWN: Checking active @ 0x%p\n", __PRETTY_FUNCTION__, active_entry));
3958 #endif
3959 if (data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL)
3961 if (active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE)
3962 break;
3964 else
3966 active_X = active_entry->ie_IconX;
3968 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
3970 if (active_entry->ie_AreaWidth < data->icld_IconAreaLargestWidth)
3971 x_diff = ((data->icld_IconAreaLargestWidth - active_entry->ie_AreaWidth)/2);
3973 active_Y = active_entry->ie_IconY;
3975 if (start_entry)
3977 if (entry_next)
3979 if ((active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE) &&
3980 (active_Y > start_Y) &&
3981 (((active_X - x_diff) >= start_X ) &&
3982 ((active_X - x_diff) <= (start_X + start_entry->ie_AreaWidth + (x_diff*2)))))
3984 #if defined(DEBUG_ILC_KEYEVENTS)
3985 D(bug("[IconList] %s: DOWN: (A) entry 0x%p matches\n", __PRETTY_FUNCTION__, active_entry));
3986 #endif
3987 break;
3989 else if (active_entry == (struct IconEntry *)GetTail(&data->icld_IconList))
3991 #if defined(DEBUG_ILC_KEYEVENTS)
3992 D(bug("[IconList] %s: DOWN: (A) reached list end .. starting at the beginng ..\n", __PRETTY_FUNCTION__));
3993 #endif
3994 start_X = entry_next->ie_IconX;
3995 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
3997 if (entry_next->ie_AreaWidth < data->icld_IconAreaLargestWidth)
3998 start_X = start_X - ((data->icld_IconAreaLargestWidth - entry_next->ie_AreaWidth)/2);
4001 if ((entry_next = (struct IconEntry *)Node_NextVisible(entry_next)))
4003 if (entry_next->ie_IconX < start_X)
4004 entry_next = NULL;
4005 else
4007 next_X = entry_next->ie_IconX;
4008 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
4010 if (entry_next->ie_AreaWidth < data->icld_IconAreaLargestWidth)
4011 next_X = next_X + ((data->icld_IconAreaLargestWidth - entry_next->ie_AreaWidth)/2);
4015 start_Y = 0;
4016 #if defined(DEBUG_ILC_KEYEVENTS)
4017 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));
4018 #endif
4019 active_entry = Node_FirstVisible(&data->icld_IconList);
4022 else
4024 if ((active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE) &&
4025 (active_Y > start_Y) &&
4026 (active_X > start_X - 1))
4028 #if defined(DEBUG_ILC_KEYEVENTS)
4029 D(bug("[IconList] %s: DOWN: (B) entry 0x%p matches\n", __PRETTY_FUNCTION__, active_entry));
4030 #endif
4031 break;
4035 else
4037 if (active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE)
4039 #if defined(DEBUG_ILC_KEYEVENTS)
4040 D(bug("[IconList] %s: DOWN: (C) entry 0x%p matches\n", __PRETTY_FUNCTION__, active_entry));
4041 #endif
4042 break;
4046 active_entry = (struct IconEntry *)GetSucc(&active_entry->ie_IconNode);
4049 if (!(active_entry))
4051 #if defined(DEBUG_ILC_KEYEVENTS)
4052 D(bug("[IconList] %s: DOWN: No Next DOWN Node - Getting first visable icon ..\n", __PRETTY_FUNCTION__));
4053 #endif
4054 /* We didnt find a "next DOWN" icon so just use the first visible */
4055 active_entry = Node_FirstVisible(&data->icld_IconList);
4058 if (active_entry)
4060 if (!(active_entry->ie_Flags & ICONENTRY_FLAG_FOCUS))
4062 active_entry->ie_Flags |= ICONENTRY_FLAG_FOCUS;
4063 data->icld_UpdateMode = UPDATE_SINGLEICON;
4064 data->update_icon = active_entry;
4065 MUI_Redraw(obj, MADF_DRAWUPDATE);
4068 data->icld_FocusIcon = active_entry;
4069 break;
4071 case RAWKEY_LEFT:
4072 rawkey_handled = TRUE;
4074 #if defined(DEBUG_ILC_KEYEVENTS)
4075 D(bug("[IconList] %s: RAWKEY_LEFT\n", __PRETTY_FUNCTION__));
4076 #endif
4077 if (data->icld_FocusIcon)
4079 start_entry = data->icld_FocusIcon;
4080 #if defined(DEBUG_ILC_KEYEVENTS)
4081 D(bug("[IconList] %s: LEFT: Clearing existing focused icon @ 0x%p\n", __PRETTY_FUNCTION__, start_entry));
4082 #endif
4084 start_entry->ie_Flags &= ~ICONENTRY_FLAG_FOCUS;
4085 data->icld_UpdateMode = UPDATE_SINGLEICON;
4086 data->update_icon = start_entry;
4087 MUI_Redraw(obj, MADF_DRAWUPDATE);
4089 start_X = start_entry->ie_IconX;
4090 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
4092 if (start_entry->ie_AreaWidth < data->icld_IconAreaLargestWidth)
4093 start_X = start_X - ((data->icld_IconAreaLargestWidth - start_entry->ie_AreaWidth)/2);
4095 start_Y = start_entry->ie_IconY;
4097 #if defined(DEBUG_ILC_KEYEVENTS)
4098 D(bug("[IconList] %s: LEFT: start_X %d, start_Y %d\n", __PRETTY_FUNCTION__, start_X, start_Y));
4099 #endif
4101 if (!(active_entry = Node_NextVisible(start_entry)) && (!(data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL)))
4103 active_entry = (struct IconEntry *)GetHead(&data->icld_IconList);
4104 #if defined(DEBUG_ILC_KEYEVENTS)
4105 D(bug("[IconList] %s: LEFT: Start at the beginning (Active @ 0x%p) using icon X + Width\n", __PRETTY_FUNCTION__, active_entry));
4106 #endif
4107 start_X = start_X + start_entry->ie_AreaWidth;
4108 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
4110 if (start_entry->ie_AreaWidth < data->icld_IconAreaLargestWidth)
4111 start_X = start_X + ((data->icld_IconAreaLargestWidth - start_entry->ie_AreaWidth)/2);
4114 start_Y = 0;
4115 entry_next = NULL;
4117 else if (active_entry && (!(data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL)))
4119 #if defined(DEBUG_ILC_KEYEVENTS)
4120 D(bug("[IconList] %s: LEFT: Active @ 0x%p, X %d\n", __PRETTY_FUNCTION__, active_entry, active_entry->ie_IconX));
4121 #endif
4122 if ((entry_next = Node_NextVisible(start_entry)))
4124 #if defined(DEBUG_ILC_KEYEVENTS)
4125 D(bug("[IconList] %s: LEFT: Next @ 0x%p, X %d\n", __PRETTY_FUNCTION__, entry_next, entry_next->ie_IconX));
4126 #endif
4128 if (entry_next->ie_IconX < start_X)
4129 entry_next = NULL;
4130 else
4132 next_X = entry_next->ie_IconX;
4133 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
4135 if (entry_next->ie_AreaWidth < data->icld_IconAreaLargestWidth)
4136 next_X = next_X - ((data->icld_IconAreaLargestWidth - entry_next->ie_AreaWidth)/2);
4141 #if defined(DEBUG_ILC_KEYEVENTS)
4142 D(bug("[IconList] %s: LEFT: using start_X %d, start_Y %d\n", __PRETTY_FUNCTION__, start_X, start_Y));
4143 #endif
4146 if (!(message->imsg->Qualifier & IEQUALIFIER_LSHIFT) && ((data->icld_SelectionLastClicked)&&(data->icld_SelectionLastClicked != active_entry)))
4148 #if defined(DEBUG_ILC_KEYEVENTS)
4149 D(bug("[IconList] %s: LEFT: Clearing selected icons ..\n", __PRETTY_FUNCTION__));
4150 #endif
4151 DoMethod(obj, MUIM_IconList_UnselectAll);
4154 #if defined(DEBUG_ILC_KEYEVENTS)
4155 D(bug("[IconList] %s: LEFT: active = 0x%p, next = 0x%p\n", __PRETTY_FUNCTION__, active_entry, entry_next));
4156 #endif
4158 if (!(active_entry))
4160 active_entry = (struct IconEntry *)GetHead(&data->icld_IconList);
4163 while (active_entry != NULL)
4165 #if defined(DEBUG_ILC_KEYEVENTS)
4166 D(bug("[IconList] %s: LEFT: Checking active @ 0x%p\n", __PRETTY_FUNCTION__, active_entry));
4167 #endif
4168 if (data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL)
4170 if (active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE)
4171 break;
4173 else
4175 LONG active_entry_X = active_entry->ie_IconX;
4176 LONG active_entry_Y;
4177 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
4179 if (active_entry->ie_AreaWidth < data->icld_IconAreaLargestWidth)
4180 active_entry_X = active_entry_X - ((data->icld_IconAreaLargestWidth - active_entry->ie_AreaWidth)/2);
4182 active_entry_Y = active_entry->ie_IconY;
4184 if (start_entry)
4186 if (entry_next)
4188 if ((active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE) &&
4189 (active_entry_Y > start_Y) &&
4190 ((active_entry_X > start_X - 1) &&
4191 (active_entry_X < next_X)))
4193 #if defined(DEBUG_ILC_KEYEVENTS)
4194 D(bug("[IconList] %s: LEFT: (A) entry 0x%p matches\n", __PRETTY_FUNCTION__, active_entry));
4195 #endif
4196 break;
4198 else if (active_entry == (struct IconEntry *)GetTail(&data->icld_IconList))
4200 #if defined(DEBUG_ILC_KEYEVENTS)
4201 D(bug("[IconList] %s: LEFT: (A) reached list end .. starting at the beginng ..\n", __PRETTY_FUNCTION__));
4202 #endif
4203 start_X = entry_next->ie_IconX;
4204 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
4206 if (entry_next->ie_AreaWidth < data->icld_IconAreaLargestWidth)
4207 start_X = start_X - ((data->icld_IconAreaLargestWidth - entry_next->ie_AreaWidth)/2);
4210 if ((entry_next = Node_NextVisible(entry_next)))
4212 if (entry_next->ie_IconX < start_X)
4213 entry_next = NULL;
4214 else
4216 next_X = entry_next->ie_IconX;
4217 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
4219 if (entry_next->ie_AreaWidth < data->icld_IconAreaLargestWidth)
4220 next_X = next_X + ((data->icld_IconAreaLargestWidth - entry_next->ie_AreaWidth)/2);
4224 start_Y = 0;
4225 #if defined(DEBUG_ILC_KEYEVENTS)
4226 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));
4227 #endif
4228 active_entry = (struct IconEntry *)GetHead(&data->icld_IconList);
4231 else
4233 if ((active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE) &&
4234 (active_entry_Y > start_Y) &&
4235 (active_entry_X > start_X - 1))
4237 #if defined(DEBUG_ILC_KEYEVENTS)
4238 D(bug("[IconList] %s: LEFT: (B) entry 0x%p matches\n", __PRETTY_FUNCTION__, active_entry));
4239 #endif
4240 break;
4244 else
4246 if (active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE)
4248 #if defined(DEBUG_ILC_KEYEVENTS)
4249 D(bug("[IconList] %s: LEFT: (C) entry 0x%p matches\n", __PRETTY_FUNCTION__, active_entry));
4250 #endif
4251 break;
4255 active_entry = (struct IconEntry *)GetSucc(&active_entry->ie_IconNode);
4258 if (!(active_entry))
4260 #if defined(DEBUG_ILC_KEYEVENTS)
4261 D(bug("[IconList] %s: LEFT: No Next LEFT Node - Getting first visable icon ..\n", __PRETTY_FUNCTION__));
4262 #endif
4263 /* We didnt find a "next LEFT" icon so just use the last visible */
4264 active_entry = (struct IconEntry *)GetHead(&data->icld_IconList);
4265 while ((active_entry != NULL) &&(!(active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE)))
4267 active_entry = (struct IconEntry *)GetSucc(&active_entry->ie_IconNode);
4271 if (active_entry)
4273 if (!(active_entry->ie_Flags & ICONENTRY_FLAG_FOCUS))
4275 active_entry->ie_Flags |= ICONENTRY_FLAG_FOCUS;
4276 data->icld_UpdateMode = UPDATE_SINGLEICON;
4277 data->update_icon = active_entry;
4278 MUI_Redraw(obj, MADF_DRAWUPDATE);
4281 data->icld_FocusIcon = active_entry;
4282 break;
4284 case RAWKEY_RIGHT:
4285 rawkey_handled = TRUE;
4287 #if defined(DEBUG_ILC_KEYEVENTS)
4288 D(bug("[IconList] %s: RAWKEY_RIGHT\n", __PRETTY_FUNCTION__));
4289 #endif
4291 if (data->icld_FocusIcon)
4293 start_entry = data->icld_FocusIcon;
4294 #if defined(DEBUG_ILC_KEYEVENTS)
4295 D(bug("[IconList] %s: RIGHT: Clearing existing focused icon @ 0x%p\n", __PRETTY_FUNCTION__, start_entry));
4296 #endif
4297 start_entry->ie_Flags &= ~ICONENTRY_FLAG_FOCUS;
4298 data->icld_UpdateMode = UPDATE_SINGLEICON;
4299 data->update_icon = start_entry;
4300 MUI_Redraw(obj, MADF_DRAWUPDATE);
4302 start_X = start_entry->ie_IconX;
4303 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
4305 if (start_entry->ie_AreaWidth < data->icld_IconAreaLargestWidth)
4306 start_X = start_X - ((data->icld_IconAreaLargestWidth - start_entry->ie_AreaWidth)/2);
4308 start_Y = start_entry->ie_IconY;
4310 #if defined(DEBUG_ILC_KEYEVENTS)
4311 D(bug("[IconList] %s: RIGHT: start_X %d, start_Y %d\n", __PRETTY_FUNCTION__, start_X, start_Y));
4312 #endif
4313 if (!(active_entry = Node_NextVisible(start_entry)) && (!(data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL)))
4315 active_entry = (struct IconEntry *)GetHead(&data->icld_IconList);
4316 #if defined(DEBUG_ILC_KEYEVENTS)
4317 D(bug("[IconList] %s: RIGHT: Start at the beginning (Active @ 0x%p) using icon X + Width\n", __PRETTY_FUNCTION__, active_entry));
4318 #endif
4319 start_X = 0;
4320 start_Y = start_Y + start_entry->ie_AreaHeight;
4321 entry_next = NULL;
4323 else if (active_entry && (data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL))
4325 #if defined(DEBUG_ILC_KEYEVENTS)
4326 D(bug("[IconList] %s: RIGHT: Active @ 0x%p, X %d\n", __PRETTY_FUNCTION__, active_entry, active_entry->ie_IconX));
4327 #endif
4328 if ((entry_next = Node_NextVisible(start_entry)))
4330 #if defined(DEBUG_ILC_KEYEVENTS)
4331 D(bug("[IconList] %s: RIGHT: Next @ 0x%p, X %d\n", __PRETTY_FUNCTION__, entry_next, entry_next->ie_IconX));
4332 #endif
4334 if (entry_next->ie_IconY < start_Y)
4335 entry_next = NULL;
4336 else
4337 next_Y = entry_next->ie_IconY;
4340 #if defined(DEBUG_ILC_KEYEVENTS)
4341 D(bug("[IconList] %s: RIGHT: using start_X %d, start_Y %d\n", __PRETTY_FUNCTION__, start_X, start_Y));
4342 #endif
4345 if (!(message->imsg->Qualifier & IEQUALIFIER_LSHIFT) && ((data->icld_SelectionLastClicked)&&(data->icld_SelectionLastClicked != active_entry)))
4347 #if defined(DEBUG_ILC_KEYEVENTS)
4348 D(bug("[IconList] %s: RIGHT: Clearing selected icons ..\n", __PRETTY_FUNCTION__));
4349 #endif
4350 DoMethod(obj, MUIM_IconList_UnselectAll);
4353 #if defined(DEBUG_ILC_KEYEVENTS)
4354 D(bug("[IconList] %s: RIGHT: active = 0x%p, next = 0x%p\n", __PRETTY_FUNCTION__, active_entry, entry_next));
4355 #endif
4357 if (!(active_entry))
4359 active_entry = (struct IconEntry *)GetHead(&data->icld_IconList);
4362 while (active_entry != NULL)
4364 #if defined(DEBUG_ILC_KEYEVENTS)
4365 D(bug("[IconList] %s: RIGHT: Checking active @ 0x%p\n", __PRETTY_FUNCTION__, active_entry));
4366 #endif
4367 if (!(data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL))
4369 if (active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE)
4370 break;
4372 else
4374 LONG active_entry_X = active_entry->ie_IconX;
4375 LONG active_entry_Y;
4376 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
4378 if (active_entry->ie_AreaWidth < data->icld_IconAreaLargestWidth)
4379 active_entry_X = active_entry_X - ((data->icld_IconAreaLargestWidth - active_entry->ie_AreaWidth)/2);
4381 active_entry_Y = active_entry->ie_IconY;
4383 if (start_entry)
4385 if (entry_next)
4387 if ((active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE) &&
4388 (active_entry_X > start_X) &&
4389 ((active_entry_Y > start_Y - 1) &&
4390 (active_entry_Y < next_Y)))
4392 #if defined(DEBUG_ILC_KEYEVENTS)
4393 D(bug("[IconList] %s: RIGHT: (A) entry 0x%p matches\n", __PRETTY_FUNCTION__, active_entry));
4394 #endif
4395 break;
4397 else if (active_entry == (struct IconEntry *)GetTail(&data->icld_IconList))
4399 #if defined(DEBUG_ILC_KEYEVENTS)
4400 D(bug("[IconList] %s: RIGHT: (A) reached list end .. starting at the beginng ..\n", __PRETTY_FUNCTION__));
4401 #endif
4402 start_Y = entry_next->ie_IconY;
4404 if ((entry_next = Node_NextVisible(entry_next)))
4406 if (entry_next->ie_IconY < start_Y)
4407 entry_next = NULL;
4408 else
4410 next_Y = entry_next->ie_IconY;
4413 start_Y = 0;
4414 #if defined(DEBUG_ILC_KEYEVENTS)
4415 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));
4416 #endif
4417 active_entry = (struct IconEntry *)GetHead(&data->icld_IconList);
4420 else
4422 if ((active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE) &&
4423 (active_entry_X > start_X) &&
4424 (active_entry_Y > start_Y - 1))
4426 #if defined(DEBUG_ILC_KEYEVENTS)
4427 D(bug("[IconList] %s: RIGHT: (B) entry 0x%p matches\n", __PRETTY_FUNCTION__, active_entry));
4428 #endif
4429 break;
4433 else
4435 if (active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE)
4437 #if defined(DEBUG_ILC_KEYEVENTS)
4438 D(bug("[IconList] %s: RIGHT: (C) entry 0x%p matches\n", __PRETTY_FUNCTION__, active_entry));
4439 #endif
4440 break;
4444 active_entry = (struct IconEntry *)GetSucc(&active_entry->ie_IconNode);
4447 if (!(active_entry))
4449 #if defined(DEBUG_ILC_KEYEVENTS)
4450 D(bug("[IconList] %s: RIGHT: No Next RIGHT Node - Getting first visable icon ..\n", __PRETTY_FUNCTION__));
4451 #endif
4452 /* We didnt find a "next RIGHT" icon so just use the first visible */
4453 active_entry = (struct IconEntry *)GetHead(&data->icld_IconList);
4454 while ((active_entry != NULL) &&(!(active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE)))
4456 active_entry = (struct IconEntry *)GetSucc(&active_entry->ie_IconNode);
4460 if (active_entry)
4462 if (!(active_entry->ie_Flags & ICONENTRY_FLAG_FOCUS))
4464 active_entry->ie_Flags |= ICONENTRY_FLAG_FOCUS;
4465 data->icld_UpdateMode = UPDATE_SINGLEICON;
4466 data->update_icon = active_entry;
4467 MUI_Redraw(obj, MADF_DRAWUPDATE);
4470 data->icld_FocusIcon = active_entry;
4471 break;
4473 case RAWKEY_HOME:
4474 rawkey_handled = TRUE;
4476 #if defined(DEBUG_ILC_KEYEVENTS)
4477 D(bug("[IconList] %s: RAWKEY_HOME\n", __PRETTY_FUNCTION__));
4478 #endif
4480 if (data->icld_FocusIcon)
4482 data->icld_FocusIcon->ie_Flags &= ~ICONENTRY_FLAG_FOCUS;
4483 data->icld_UpdateMode = UPDATE_SINGLEICON;
4484 data->update_icon = data->icld_FocusIcon;
4485 MUI_Redraw(obj, MADF_DRAWUPDATE);
4488 active_entry = Node_FirstVisible(&data->icld_IconList);
4490 if ((active_entry) && (!(active_entry->ie_Flags & ICONENTRY_FLAG_FOCUS)))
4492 active_entry->ie_Flags |= ICONENTRY_FLAG_FOCUS;
4493 data->icld_UpdateMode = UPDATE_SINGLEICON;
4494 data->update_icon = active_entry;
4495 MUI_Redraw(obj, MADF_DRAWUPDATE);
4497 data->icld_FocusIcon = active_entry;
4498 break;
4500 case RAWKEY_END:
4501 rawkey_handled = TRUE;
4503 #if defined(DEBUG_ILC_KEYEVENTS)
4504 D(bug("[IconList] %s: RAWKEY_END\n", __PRETTY_FUNCTION__));
4505 #endif
4507 if (data->icld_FocusIcon)
4509 data->icld_FocusIcon->ie_Flags &= ~ICONENTRY_FLAG_FOCUS;
4510 data->icld_UpdateMode = UPDATE_SINGLEICON;
4511 data->update_icon = data->icld_FocusIcon;
4512 MUI_Redraw(obj, MADF_DRAWUPDATE);
4515 active_entry = Node_LastVisible(&data->icld_IconList);
4517 if ((active_entry) && (!(active_entry->ie_Flags & ICONENTRY_FLAG_FOCUS)))
4519 active_entry->ie_Flags |= ICONENTRY_FLAG_FOCUS;
4520 data->icld_UpdateMode = UPDATE_SINGLEICON;
4521 data->update_icon = active_entry;
4522 MUI_Redraw(obj, MADF_DRAWUPDATE);
4524 data->icld_FocusIcon = active_entry;
4525 break;
4528 if (rawkey_handled) return MUI_EventHandlerRC_Eat;
4530 break;
4532 case IDCMP_MOUSEBUTTONS:
4533 #if defined(DEBUG_ILC_EVENTS)
4534 D(bug("[IconList] %s: IDCMP_MOUSEBUTTONS\n", __PRETTY_FUNCTION__));
4535 #endif
4536 if (message->imsg->Code == SELECTDOWN)
4538 /* check if mouse pressed on iconlist area */
4539 if (mx >= 0 && mx < _width(obj) && my >= 0 && my < _height(obj))
4541 struct IconEntry *node = NULL;
4542 struct IconEntry *new_selected = NULL;
4543 struct Rectangle rect;
4545 // int selections = 0;
4546 BOOL icon_doubleclicked;
4548 /* check if clicked on icon */
4549 #if defined(__AROS__)
4550 ForeachNode(&data->icld_IconList, node)
4551 #else
4552 Foreach_Node(&data->icld_IconList, node);
4553 #endif
4555 if (node->ie_Flags & ICONENTRY_FLAG_VISIBLE)
4557 BOOL update_icon = FALSE;
4559 rect.MinX = node->ie_IconX;
4560 rect.MaxX = node->ie_IconX + node->ie_AreaWidth - 1;
4561 rect.MinY = node->ie_IconY;
4562 rect.MaxY = node->ie_IconY + node->ie_AreaHeight - 1;
4564 if ((data->icld__Option_IconListMode == ICON_LISTMODE_GRID) &&
4565 (node->ie_AreaWidth < data->icld_IconAreaLargestWidth))
4567 rect.MinX += ((data->icld_IconAreaLargestWidth - node->ie_AreaWidth)/2);
4568 rect.MaxX += ((data->icld_IconAreaLargestWidth - node->ie_AreaWidth)/2);
4571 if ((((mx + data->icld_ViewX) >= rect.MinX) && ((mx + data->icld_ViewX) <= rect.MaxX )) &&
4572 (((my + data->icld_ViewY) >= rect.MinY) && ((my + data->icld_ViewY) <= rect.MaxY )) &&
4573 !new_selected)
4575 new_selected = node;
4576 #if defined(DEBUG_ILC_EVENTS)
4577 D(bug("[IconList] %s: Icon '%s' clicked on ..\n", __PRETTY_FUNCTION__, node->ie_IconListEntry.label));
4578 #endif
4581 if (node->ie_Flags & ICONENTRY_FLAG_SELECTED)
4583 if ((new_selected != node) &&
4584 (!(message->imsg->Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))))
4586 Remove(&node->ie_SelectionNode);
4587 node->ie_Flags &= ~ICONENTRY_FLAG_SELECTED;
4588 update_icon = TRUE;
4592 if ((node->ie_Flags & ICONENTRY_FLAG_FOCUS) && (new_selected != node))
4594 node->ie_Flags &= ~ICONENTRY_FLAG_FOCUS;
4595 update_icon = TRUE;
4598 if (update_icon)
4600 data->icld_UpdateMode = UPDATE_SINGLEICON;
4601 data->update_icon = node;
4602 MUI_Redraw(obj, MADF_DRAWUPDATE);
4603 #if defined(DEBUG_ILC_EVENTS)
4604 D(bug("[IconList] %s: Rendered icon '%s'\n", __PRETTY_FUNCTION__, node->ie_IconListEntry.label));
4605 #endif
4610 icon_doubleclicked = FALSE;
4612 if ((DoubleClick(data->last_secs, data->last_mics, message->imsg->Seconds, message->imsg->Micros)) && (data->icld_SelectionLastClicked == new_selected))
4614 #if defined(DEBUG_ILC_EVENTS)
4615 D(bug("[IconList] %s: Icon double-clicked\n", __PRETTY_FUNCTION__));
4616 #endif
4617 icon_doubleclicked = TRUE;
4620 if (new_selected == NULL)
4622 struct Window * thisWindow = NULL;
4623 #if defined(DEBUG_ILC_EVENTS) && defined(DEBUG_ILC_LASSO)
4624 D(bug("[IconList] %s: Starting Lasso\n", __PRETTY_FUNCTION__));
4625 #endif
4626 /* No icon clicked on ... Start Lasso-selection */
4627 data->icld_LassoActive = TRUE;
4628 if (!(message->imsg->Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT)))
4630 data->icld_SelectionLastClicked = NULL;
4631 data->icld_FocusIcon = NULL;
4633 data->icld_LassoRectangle.MinX = mx - data->view_rect.MinX + data->icld_ViewX;
4634 data->icld_LassoRectangle.MinY = my - data->view_rect.MinY + data->icld_ViewY;
4635 data->icld_LassoRectangle.MaxX = mx - data->view_rect.MinX + data->icld_ViewX;
4636 data->icld_LassoRectangle.MaxY = my - data->view_rect.MinY + data->icld_ViewY;
4638 /* Draw initial Lasso frame */
4639 IconList_InvertLassoOutlines(obj, &data->icld_LassoRectangle);
4641 GET(obj, MUIA_Window, &thisWindow);
4642 if (thisWindow)
4644 ModifyIDCMP(thisWindow, (thisWindow->IDCMPFlags|IDCMP_INTUITICKS));
4645 if (!(data->ehn.ehn_Events & IDCMP_INTUITICKS))
4647 DoMethod(_win(obj), MUIM_Window_RemEventHandler, (IPTR)&data->ehn);
4648 data->ehn.ehn_Events |= IDCMP_INTUITICKS;
4649 DoMethod(_win(obj), MUIM_Window_AddEventHandler, (IPTR)&data->ehn);
4653 else
4655 struct IconEntry *update_icon = NULL;
4657 data->icld_LassoActive = FALSE;
4659 if (!(new_selected->ie_Flags & ICONENTRY_FLAG_SELECTED))
4661 AddTail(&data->icld_SelectionList, &new_selected->ie_SelectionNode);
4662 new_selected->ie_Flags |= ICONENTRY_FLAG_SELECTED;
4663 update_icon = new_selected;
4665 if (!(new_selected->ie_Flags & ICONENTRY_FLAG_FOCUS))
4667 new_selected->ie_Flags |= ICONENTRY_FLAG_FOCUS;
4668 update_icon = new_selected;
4669 data->icld_FocusIcon = new_selected;
4672 else if ((icon_doubleclicked == FALSE) && (message->imsg->Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT)))
4674 Remove(&new_selected->ie_SelectionNode);
4675 new_selected->ie_Flags &= ~ICONENTRY_FLAG_SELECTED;
4676 update_icon = new_selected;
4677 new_selected = NULL;
4680 if (update_icon != NULL)
4682 data->icld_UpdateMode = UPDATE_SINGLEICON;
4683 data->update_icon = update_icon;
4684 MUI_Redraw(obj, MADF_DRAWUPDATE);
4685 #if defined(DEBUG_ILC_EVENTS)
4686 D(bug("[IconList] %s: Rendered 'new_selected' icon '%s'\n", __PRETTY_FUNCTION__, update_icon->ie_IconListEntry.label));
4687 #endif
4691 data->icld_ClickEvent.shift = !!(message->imsg->Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT));
4692 data->icld_ClickEvent.entry = new_selected ? &new_selected->ie_IconListEntry : NULL;
4693 SET(obj, MUIA_IconList_Clicked, (IPTR)&data->icld_ClickEvent);
4695 if (icon_doubleclicked)
4697 SET(obj, MUIA_IconList_DoubleClick, TRUE);
4699 else if (!data->mouse_pressed)
4701 data->last_secs = message->imsg->Seconds;
4702 data->last_mics = message->imsg->Micros;
4704 /* After a double click you often open a new window
4705 * and since Zune doesn't not support the faking
4706 * of SELECTUP events only change the Events
4707 * if not doubleclicked */
4709 data->mouse_pressed |= LEFT_BUTTON;
4711 if (!(data->ehn.ehn_Events & IDCMP_MOUSEMOVE))
4713 DoMethod(_win(obj), MUIM_Window_RemEventHandler, (IPTR)&data->ehn);
4714 data->ehn.ehn_Events |= IDCMP_MOUSEMOVE;
4715 DoMethod(_win(obj), MUIM_Window_AddEventHandler, (IPTR)&data->ehn);
4719 data->icld_SelectionLastClicked = new_selected;
4721 data->click_x = mx;
4722 data->click_y = my;
4724 SET(obj, MUIA_IconList_SelectionChanged, TRUE);
4726 return MUI_EventHandlerRC_Eat;
4729 else if (message->imsg->Code == MIDDLEDOWN)
4731 if (!data->mouse_pressed)
4733 data->mouse_pressed |= MIDDLE_BUTTON;
4735 data->click_x = data->icld_ViewX + mx;
4736 data->click_y = data->icld_ViewY + my;
4738 if (!(data->ehn.ehn_Events & IDCMP_MOUSEMOVE))
4740 DoMethod(_win(obj), MUIM_Window_RemEventHandler, (IPTR)&data->ehn);
4741 data->ehn.ehn_Events |= IDCMP_MOUSEMOVE;
4742 DoMethod(_win(obj), MUIM_Window_AddEventHandler, (IPTR)&data->ehn);
4746 else
4748 if (message->imsg->Code == SELECTUP)
4750 if (data->icld_LassoActive == TRUE)
4752 #if defined(DEBUG_ILC_EVENTS) && defined(DEBUG_ILC_LASSO)
4753 D(bug("[IconList] %s: Removing Lasso\n", __PRETTY_FUNCTION__));
4754 #endif
4755 // End Lasso-selection
4756 struct Rectangle old_lasso;
4757 struct IconEntry *node = NULL;
4758 struct Window *thisWindow = NULL;
4760 GET(obj, MUIA_Window, &thisWindow);
4761 if (thisWindow)
4763 ModifyIDCMP(thisWindow, (thisWindow->IDCMPFlags & ~(IDCMP_INTUITICKS)));
4764 if ((data->ehn.ehn_Events & IDCMP_INTUITICKS))
4766 DoMethod(_win(obj), MUIM_Window_RemEventHandler, (IPTR)&data->ehn);
4767 data->ehn.ehn_Events &= ~IDCMP_INTUITICKS;
4768 DoMethod(_win(obj), MUIM_Window_AddEventHandler, (IPTR)&data->ehn);
4771 //Clear Lasso Frame..
4772 GetAbsoluteLassoRect(data, &old_lasso);
4773 IconList_InvertLassoOutlines(obj, &old_lasso);
4775 data->icld_LassoActive = FALSE;
4777 //Remove Lasso flag from affected icons..
4778 #if defined(__AROS__)
4779 ForeachNode(&data->icld_IconList, node)
4780 #else
4781 Foreach_Node(&data->icld_IconList, node);
4782 #endif
4784 if (node->ie_Flags & ICONENTRY_FLAG_LASSO)
4786 node->ie_Flags &= ~ICONENTRY_FLAG_LASSO;
4789 SET(obj, MUIA_IconList_SelectionChanged, TRUE);
4792 data->mouse_pressed &= ~LEFT_BUTTON;
4795 if (message->imsg->Code == MIDDLEUP)
4797 data->mouse_pressed &= ~MIDDLE_BUTTON;
4800 if ((data->ehn.ehn_Events & IDCMP_MOUSEMOVE) && !data->mouse_pressed)
4802 DoMethod(_win(obj),MUIM_Window_RemEventHandler, (IPTR)&data->ehn);
4803 data->ehn.ehn_Events &= ~IDCMP_MOUSEMOVE;
4804 DoMethod(_win(obj),MUIM_Window_AddEventHandler, (IPTR)&data->ehn);
4807 break;
4809 case IDCMP_INTUITICKS:
4811 #if defined(DEBUG_ILC_EVENTS)
4812 D(bug("[IconList] %s: IDCMP_INTUITICKS (%d, %d)\n", __PRETTY_FUNCTION__, mx, my));
4813 #endif
4814 if ((data->icld_LassoActive == FALSE)||(!(data->mouse_pressed & LEFT_BUTTON)))
4816 break;
4818 if (((mx >= 0) && (mx <= _mwidth(obj))) &&
4819 ((my >= 0) && (my <= _mheight(obj))))
4820 break;
4823 case IDCMP_MOUSEMOVE:
4824 #if defined(DEBUG_ILC_EVENTS)
4825 D(bug("[IconList] %s: IDCMP_MOUSEMOVE\n", __PRETTY_FUNCTION__));
4826 #endif
4827 if (data->mouse_pressed & LEFT_BUTTON)
4829 LONG move_x = mx;
4830 LONG move_y = my;
4832 if (data->icld_SelectionLastClicked && (data->icld_LassoActive == FALSE) &&
4833 ((abs(move_x - data->click_x) >= 2) || (abs(move_y - data->click_y) >= 2)))
4835 // Icon(s) being dragged ....
4836 DoMethod(_win(obj),MUIM_Window_RemEventHandler, (IPTR)&data->ehn);
4837 data->ehn.ehn_Events &= ~IDCMP_MOUSEMOVE;
4838 DoMethod(_win(obj),MUIM_Window_AddEventHandler, (IPTR)&data->ehn);
4840 data->mouse_pressed &= ~LEFT_BUTTON;
4842 data->touch_x = move_x + data->icld_ViewX - data->icld_SelectionLastClicked->ie_IconX;
4843 data->touch_y = move_y + data->icld_ViewY - data->icld_SelectionLastClicked->ie_IconY;
4844 DoMethod(obj,MUIM_DoDrag, data->touch_x, data->touch_y, 0);
4846 else if (data->icld_LassoActive == TRUE)
4848 #if defined(DEBUG_ILC_EVENTS) && defined(DEBUG_ILC_LASSO)
4849 D(bug("[IconList] %s: Update Lasso\n", __PRETTY_FUNCTION__));
4850 #endif
4851 //Lasso active ..
4852 struct Rectangle new_lasso,
4853 old_lasso;
4854 struct Rectangle iconrect;
4856 struct IconEntry *node = NULL;
4857 // struct IconEntry *new_selected = NULL;
4859 /* Remove previous Lasso frame */
4860 GetAbsoluteLassoRect(data, &old_lasso);
4861 IconList_InvertLassoOutlines(obj, &old_lasso);
4863 /* if the mouse leaves our visible area scroll the view */
4864 if (mx < 0 || mx >= _mwidth(obj) || my < 0 || my >= _mheight(obj))
4866 LONG newleft = data->icld_ViewX;
4867 LONG newtop = data->icld_ViewY;
4869 if (mx >= _mwidth(obj)) newleft += (mx - _mwidth(obj));
4870 else if (mx < 0) newleft += mx;
4871 if (my >= _mheight(obj)) newtop += (my - _mheight(obj));
4872 else if (my < 0) newtop += my;
4874 if (newleft + _mwidth(obj) > data->icld_AreaWidth) newleft = data->icld_AreaWidth - _mwidth(obj);
4875 if (newleft < 0) newleft = 0;
4877 if (newtop + _mheight(obj) > data->icld_AreaHeight) newtop = data->icld_AreaHeight - _mheight(obj);
4878 if (newtop < 0) newtop = 0;
4880 if ((newleft != data->icld_ViewX) || (newtop != data->icld_ViewY))
4882 SetAttrs(obj, MUIA_Virtgroup_Left, newleft, MUIA_Virtgroup_Top, newtop, TAG_DONE);
4886 /* update Lasso coordinates */
4887 data->icld_LassoRectangle.MaxX = mx - data->view_rect.MinX + data->icld_ViewX;
4888 data->icld_LassoRectangle.MaxY = my - data->view_rect.MinY + data->icld_ViewY;
4890 /* get absolute Lasso coordinates */
4891 GetAbsoluteLassoRect(data, &new_lasso);
4893 #if defined(__AROS__)
4894 ForeachNode(&data->icld_IconList, node)
4895 #else
4896 Foreach_Node(&data->icld_IconList, node);
4897 #endif
4899 IPTR update_icon = (IPTR)NULL;
4901 if (node->ie_Flags & ICONENTRY_FLAG_VISIBLE)
4903 iconrect.MinX = node->ie_IconX;
4904 iconrect.MaxX = node->ie_IconX + node->ie_AreaWidth - 1;
4905 iconrect.MinY = node->ie_IconY;
4906 iconrect.MaxY = node->ie_IconY + node->ie_AreaHeight - 1;
4907 if ((data->icld__Option_IconListMode == ICON_LISTMODE_GRID) &&
4908 (node->ie_AreaWidth < data->icld_IconAreaLargestWidth))
4910 iconrect.MinX += ((data->icld_IconAreaLargestWidth - node->ie_AreaWidth)/2);
4911 iconrect.MaxX += ((data->icld_IconAreaLargestWidth - node->ie_AreaWidth)/2);
4914 if ((((new_lasso.MaxX + data->icld_ViewX) >= iconrect.MinX) && ((new_lasso.MinX + data->icld_ViewX) <= iconrect.MaxX)) &&
4915 (((new_lasso.MaxY + data->icld_ViewY) >= iconrect.MinY) && ((new_lasso.MinY + data->icld_ViewY) <= iconrect.MaxY)))
4917 //Icon is inside our lasso ..
4918 if (!(node->ie_Flags & ICONENTRY_FLAG_LASSO))
4920 /* check if icon was already selected before */
4921 if (node->ie_Flags & ICONENTRY_FLAG_SELECTED)
4923 Remove(&node->ie_SelectionNode);
4924 node->ie_Flags &= ~ICONENTRY_FLAG_SELECTED;
4926 else
4928 AddTail(&data->icld_SelectionList, &node->ie_SelectionNode);
4929 node->ie_Flags |= ICONENTRY_FLAG_SELECTED;
4931 node->ie_Flags |= ICONENTRY_FLAG_LASSO;
4932 update_icon = (IPTR)node;
4935 else if (node->ie_Flags & ICONENTRY_FLAG_LASSO)
4937 //Icon is no longer inside our lasso - revert its selected state
4938 if (node->ie_Flags & ICONENTRY_FLAG_SELECTED)
4940 Remove(&node->ie_SelectionNode);
4941 node->ie_Flags &= ~ICONENTRY_FLAG_SELECTED;
4943 else
4945 AddTail(&data->icld_SelectionList, &node->ie_SelectionNode);
4946 node->ie_Flags |= ICONENTRY_FLAG_SELECTED;
4948 node->ie_Flags &= ~ICONENTRY_FLAG_LASSO;
4949 update_icon = (IPTR)node;
4952 if (update_icon)
4954 data->icld_UpdateMode = UPDATE_SINGLEICON;
4955 data->update_icon = (struct IconEntry *)update_icon;
4956 MUI_Redraw(obj, MADF_DRAWUPDATE);
4960 /* Draw Lasso frame */
4961 IconList_InvertLassoOutlines(obj, &new_lasso);
4964 return MUI_EventHandlerRC_Eat;
4966 else if (data->mouse_pressed & MIDDLE_BUTTON)
4968 LONG newleft,
4969 newtop;
4971 newleft = data->click_x - mx;
4972 newtop = data->click_y - my;
4974 if (newleft + _mwidth(obj) > data->icld_AreaWidth) newleft = data->icld_AreaWidth - _mwidth(obj);
4975 if (newleft < 0) newleft = 0;
4977 if (newtop + _mheight(obj) > data->icld_AreaHeight) newtop = data->icld_AreaHeight - _mheight(obj);
4978 if (newtop < 0) newtop = 0;
4980 if ((newleft != data->icld_ViewX) || (newtop != data->icld_ViewY))
4982 SetAttrs(obj, MUIA_Virtgroup_Left, newleft,
4983 MUIA_Virtgroup_Top, newtop,
4984 TAG_DONE);
4987 return MUI_EventHandlerRC_Eat;
4990 break;
4994 return 0;
4998 ///MUIM_IconList_NextIcon()
4999 /**************************************************************************
5000 MUIM_IconList_NextIcon
5001 **************************************************************************/
5002 IPTR IconList__MUIM_IconList_NextIcon(struct IClass *CLASS, Object *obj, struct MUIP_IconList_NextIcon *message)
5004 struct IconList_DATA *data = INST_DATA(CLASS, obj);
5005 struct IconEntry *node = NULL;
5006 struct IconList_Entry *ent = NULL;
5007 IPTR node_successor = (IPTR)NULL;
5009 if (message->entry == NULL) return (IPTR)NULL;
5010 ent = *message->entry;
5012 #if defined(DEBUG_ILC_FUNCS)
5013 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
5014 #endif
5016 if ((IPTR)ent == (IPTR)MUIV_IconList_NextIcon_Start)
5018 D(bug("[IconList] %s: Finding First Entry ..\n", __PRETTY_FUNCTION__));
5019 if (message->nextflag == MUIV_IconList_NextIcon_Selected)
5021 node = (struct IconEntry *)GetHead(&data->icld_SelectionList);
5022 if (node != NULL)
5024 node = (struct IconEntry *)((IPTR)node - ((IPTR)&node->ie_SelectionNode - (IPTR)node));
5027 else if (message->nextflag == MUIV_IconList_NextIcon_Visible)
5029 node = (struct IconEntry *)GetHead(&data->icld_IconList);
5030 while (node != NULL)
5032 if (node->ie_Flags & ICONENTRY_FLAG_VISIBLE)
5033 break;
5035 node = (struct IconEntry *)GetSucc(&node->ie_IconNode);
5039 else if ((IPTR)ent != (IPTR)MUIV_IconList_NextIcon_End)
5041 node = (struct IconEntry *)((IPTR)ent - ((IPTR)&node->ie_IconListEntry - (IPTR)node));
5042 if (message->nextflag == MUIV_IconList_NextIcon_Selected)
5044 node_successor = (IPTR)GetSucc(&node->ie_SelectionNode);
5045 if (node_successor != (IPTR)NULL)
5046 node = (struct IconEntry *)((IPTR)node_successor - ((IPTR)&node->ie_SelectionNode - (IPTR)node));
5047 else
5049 D(bug("[IconList] %s: GetSucc() == NULL\n", __PRETTY_FUNCTION__));
5050 node = NULL;
5053 else if (message->nextflag == MUIV_IconList_NextIcon_Visible)
5055 node = (struct IconEntry *)GetSucc(&node->ie_IconNode);
5056 while (node != NULL)
5058 if (node->ie_Flags & ICONENTRY_FLAG_VISIBLE)
5059 break;
5061 node = (struct IconEntry *)GetSucc(&node->ie_IconNode);
5066 if (node == NULL)
5068 D(bug("[IconList] %s: Returning MUIV_IconList_NextIcon_End\n", __PRETTY_FUNCTION__));
5070 *message->entry = (struct IconList_Entry *)MUIV_IconList_NextIcon_End;
5072 else
5074 D(bug("[IconList] %s: Returning entry for '%s'\n", __PRETTY_FUNCTION__, node->ie_IconListEntry.label));
5076 *message->entry = &node->ie_IconListEntry;
5079 return (IPTR)NULL;
5083 ///MUIM_IconList_GetIconPrivate()
5084 /**************************************************************************
5085 MUIM_IconList_GetIconPrivate
5086 **************************************************************************/
5087 IPTR IconList__MUIM_IconList_GetIconPrivate(struct IClass *CLASS, Object *obj, struct MUIP_IconList_GetIconPrivate *message)
5089 // struct IconList_DATA *data = INST_DATA(CLASS, obj);
5090 struct IconEntry *node = NULL;
5092 if (message->entry == NULL) return (IPTR)NULL;
5094 node = (struct IconEntry *)((IPTR)message->entry - ((IPTR)&node->ie_IconListEntry - (IPTR)node));
5096 return (IPTR)node;
5099 ///MUIM_CreateDragImage()
5100 /**************************************************************************
5101 MUIM_CreateDragImage
5102 **************************************************************************/
5103 IPTR IconList__MUIM_CreateDragImage(struct IClass *CLASS, Object *obj, struct MUIP_CreateDragImage *message)
5105 struct IconList_DATA *data = INST_DATA(CLASS, obj);
5106 struct MUI_DragImage *img = NULL;
5107 LONG first_x = -1,
5108 first_y = -1;
5110 #if defined(DEBUG_ILC_FUNCS)
5111 (bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
5112 #endif
5114 if (!(data->icld_SelectionLastClicked))
5115 DoSuperMethodA(CLASS, obj, (Msg)message);
5117 if ((img = (struct MUI_DragImage *)AllocVec(sizeof(struct MUIP_CreateDragImage), MEMF_CLEAR)))
5119 struct Node *node = NULL;
5120 struct IconEntry *entry = NULL;
5122 LONG depth = GetBitMapAttr(_screen(obj)->RastPort.BitMap, BMA_DEPTH);
5124 #if defined(CREATE_FULL_DRAGIMAGE)
5125 #if defined(__AROS__)
5126 ForeachNode(&data->icld_SelectionList, node)
5127 #else
5128 Foreach_Node(&data->icld_SelectionList, node);
5129 #endif
5131 entry = (struct IconEntry *)((IPTR)node - ((IPTR)&entry->ie_SelectionNode - (IPTR)entry));
5132 if ((entry->ie_Flags & ICONENTRY_FLAG_VISIBLE) && (entry->ie_Flags & ICONENTRY_FLAG_SELECTED))
5134 if ((first_x == -1) || ((first_x != -1) && (entry->ie_IconX < first_x))) first_x = entry->ie_IconX;
5135 if ((first_y == -1) || ((first_y != -1) && (entry->ie_IconY < first_y))) first_y = entry->ie_IconY;
5136 if ((entry->ie_IconX + entry->ie_IconWidth) > img->width) img->width = entry->ie_IconX + entry->ie_IconWidth;
5137 if ((entry->ie_IconY + entry->ie_IconHeight) > img->height) img->height = entry->ie_IconY + entry->ie_IconHeight;
5140 img->width = (img->width - first_x) + 2;
5141 img->height = (img->height - first_y) + 2;
5142 #else
5143 entry = data->icld_SelectionLastClicked;
5144 img->width = entry->ie_IconWidth;
5145 img->height = entry->ie_IconHeight;
5146 first_x = entry->ie_IconX;
5147 first_y = entry->ie_IconY;
5148 #endif
5150 img->touchx = data->click_x - first_x;
5151 img->touchy = data->click_y - first_y;
5153 if ((img->bm = AllocBitMap(img->width, img->height, depth, BMF_CLEAR, _screen(obj)->RastPort.BitMap)))
5155 struct RastPort temprp;
5156 InitRastPort(&temprp);
5157 temprp.BitMap = img->bm;
5159 #if defined(CREATE_FULL_DRAGIMAGE)
5160 ForeachNode(&data->icld_SelectionList, node)
5162 entry = (struct IconEntry *)((IPTR)node - ((IPTR)&entry->ie_SelectionNode - (IPTR)entry));
5163 if ((entry->ie_Flags & ICONENTRY_FLAG_VISIBLE) && (entry->ie_Flags & ICONENTRY_FLAG_SELECTED))
5165 DrawIconStateA
5167 &temprp, entry->ie_DiskObj, NULL,
5168 (entry->ie_IconX + 1) - first_x, (entry->ie_IconY + 1) - first_y,
5169 IDS_SELECTED,
5170 __iconList_DrawIconStateTags
5174 #else
5175 DrawIconStateA
5177 &temprp, entry->ie_DiskObj, NULL,
5178 0, 0,
5179 IDS_SELECTED,
5180 __iconList_DrawIconStateTags
5182 #endif
5183 RastPortSetAlpha(&temprp, data->click_x, data->click_y, img->width, img->height, 0x80, RPALPHAFLAT);
5184 DeinitRastPort(&temprp);
5187 img->touchx = message->touchx;
5188 img->touchy = message->touchy;
5189 img->flags = 0;
5190 #if defined(__MORPHOS__)
5191 img->dragmode = DD_TRANSPARENT;
5192 #endif
5194 return (IPTR)img;
5198 ///MUIM_DeleteDragImage()
5199 /**************************************************************************
5200 MUIM_DeleteDragImage
5201 **************************************************************************/
5202 IPTR IconList__MUIM_DeleteDragImage(struct IClass *CLASS, Object *obj, struct MUIP_DeleteDragImage *message)
5204 struct IconList_DATA *data = INST_DATA(CLASS, obj);
5206 #if defined(DEBUG_ILC_FUNCS)
5207 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
5208 #endif
5210 if (!(data->icld_SelectionLastClicked)) return DoSuperMethodA(CLASS,obj,(Msg)message);
5212 if (message->di)
5214 if (message->di->bm)
5215 FreeBitMap(message->di->bm);
5216 FreeVec(message->di);
5218 return (IPTR)NULL;
5222 ///MUIM_DragQuery()
5223 /**************************************************************************
5224 MUIM_DragQuery
5225 **************************************************************************/
5226 IPTR IconList__MUIM_DragQuery(struct IClass *CLASS, Object *obj, struct MUIP_DragQuery *message)
5228 #if defined(DEBUG_ILC_FUNCS)
5229 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
5230 #endif
5231 if (message->obj == obj)
5232 return MUIV_DragQuery_Accept;
5233 else
5235 BOOL is_iconlist = FALSE;
5236 struct IClass *msg_cl = OCLASS(message->obj);
5238 while (msg_cl)
5240 if (msg_cl == CLASS)
5242 is_iconlist = TRUE;
5243 break;
5245 msg_cl = msg_cl->cl_Super;
5247 if (is_iconlist)
5248 return MUIV_DragQuery_Accept;
5251 return MUIV_DragQuery_Refuse;
5255 ///MUIM_DragDrop()
5256 /**************************************************************************
5257 MUIM_DragDrop
5258 **************************************************************************/
5259 IPTR IconList__MUIM_DragDrop(struct IClass *CLASS, Object *obj, struct MUIP_DragDrop *message)
5261 struct IconList_DATA *data = INST_DATA(CLASS, obj);
5263 #if defined(DEBUG_ILC_FUNCS)
5264 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
5265 #endif
5267 struct IconList_Entry *entry = (IPTR)MUIV_IconList_NextIcon_Start;
5269 if (data->icld_DragDropEvent)
5271 struct IconList_Drop_SourceEntry *clean_node;
5272 #if defined(DEBUG_ILC_ICONDRAGDROP)
5273 D(bug("[IconList] %s: Cleaning existing IconList_Drop_Event @ %p\n", __PRETTY_FUNCTION__, data->icld_DragDropEvent));
5274 #endif
5275 while ((clean_node = (struct IconList_Drop_SourceEntry *)RemTail(&data->icld_DragDropEvent->drop_SourceList)) != NULL)
5277 FreeVec(clean_node->dropse_Node.ln_Name);
5278 FreeMem(clean_node, sizeof(struct IconList_Drop_SourceEntry));
5280 if (data->icld_DragDropEvent->drop_TargetPath) FreeVec(data->icld_DragDropEvent->drop_TargetPath);
5281 FreeMem(data->icld_DragDropEvent, sizeof(struct IconList_Drop_Event));
5282 data->icld_DragDropEvent = NULL;
5285 /* SANITY CHECK: Get first selected entry from SOURCE iconlist */
5286 DoMethod(message->obj, MUIM_IconList_NextIcon, MUIV_IconList_NextIcon_Selected, (IPTR)&entry);
5288 if ((entry) && (entry != (IPTR)MUIV_IconList_NextIcon_End))
5290 /* Ok.. atleast one icon was dropped .. */
5291 char tmp_dirbuff[256];
5292 BPTR tmp_dirlock = (BPTR) NULL;
5294 BOOL iconMove = FALSE;
5295 struct IconEntry *node = NULL;
5296 struct IconEntry *drop_target_node = NULL;
5297 STRPTR directory_path = NULL;
5298 struct IconList_Drop_Event *dragDropEvent = NULL;
5300 GET(obj, MUIA_IconDrawerList_Drawer, &directory_path);
5302 /* Properly expand the name incase it uses devices rather than volumes */
5303 if (directory_path != NULL)
5305 tmp_dirlock = Lock(directory_path, SHARED_LOCK);
5306 if (tmp_dirlock)
5308 if (NameFromLock(tmp_dirlock, tmp_dirbuff, 256) != 0)
5310 directory_path = tmp_dirbuff;
5312 UnLock(tmp_dirlock);
5315 if ((dragDropEvent = AllocMem(sizeof(struct IconList_Drop_Event), MEMF_CLEAR)) == NULL)
5317 #if defined(DEBUG_ILC_ICONDRAGDROP)
5318 D(bug("[IconList] %s: Failed to allocate IconList_Drop_Event Storage!\n", __PRETTY_FUNCTION__));
5319 #endif
5320 goto dragdropdone;
5322 D(bug("[IconList] %s: Allocated IconList_Drop_Event @ %p\n", __PRETTY_FUNCTION__, dragDropEvent));
5324 NewList(&dragDropEvent->drop_SourceList);
5326 /* go through list and check if dropped on icon */
5327 #if defined(__AROS__)
5328 ForeachNode(&data->icld_IconList, node)
5329 #else
5330 Foreach_Node(&data->icld_IconList, node);
5331 #endif
5333 struct Rectangle iconbox;
5334 LONG click_x = message->x - _mleft(obj);
5335 LONG click_y = message->y - _mtop(obj);
5336 iconbox.MinX = node->ie_IconX - data->icld_ViewX;
5337 iconbox.MaxX = (node->ie_IconX + node->ie_AreaWidth) - data->icld_ViewX;
5338 iconbox.MinY = node->ie_IconY - data->icld_ViewY;
5339 iconbox.MaxY = (node->ie_IconY + node->ie_AreaHeight)- data->icld_ViewY;
5341 if ((node->ie_Flags & ICONENTRY_FLAG_VISIBLE) &&
5342 (click_x >= iconbox.MinX) &&
5343 (click_x < iconbox.MaxX) &&
5344 (click_y >= iconbox.MinY) &&
5345 (click_y < iconbox.MaxY))
5347 drop_target_node = node;
5348 break;
5352 if ((drop_target_node != NULL) &&
5353 ((drop_target_node->ie_IconListEntry.type == ST_SOFTLINK) ||
5354 (drop_target_node->ie_IconListEntry.type == ST_ROOT) ||
5355 (drop_target_node->ie_IconListEntry.type == ST_USERDIR) ||
5356 (drop_target_node->ie_IconListEntry.type == ST_LINKDIR) ||
5357 (drop_target_node->ie_IconListEntry.type == ST_FILE) ||
5358 (drop_target_node->ie_IconListEntry.type == ST_LINKFILE)))
5360 if ((drop_target_node->ie_IconListEntry.type != ST_ROOT) && (drop_target_node->ie_IconListEntry.type != ST_SOFTLINK))
5362 if (directory_path)
5364 int fulllen = strlen(directory_path) + strlen(drop_target_node->ie_IconListEntry.label) + 2;
5366 if ((dragDropEvent->drop_TargetPath = AllocVec(fulllen, MEMF_CLEAR)) == NULL)
5368 bug("[IconList] %s: Failed to allocate IconList_Drop_Event->drop_TargetPath Storage!\n", __PRETTY_FUNCTION__);
5369 goto dragdropdone;
5371 strcpy(dragDropEvent->drop_TargetPath, directory_path);
5372 AddPart(dragDropEvent->drop_TargetPath, drop_target_node->ie_IconListEntry.label, fulllen);
5375 else
5377 if ((dragDropEvent->drop_TargetPath = AllocVec(strlen(drop_target_node->ie_IconListEntry.label) + 1, MEMF_CLEAR)) == NULL)
5379 bug("[IconList] %s: Failed to allocate IconList_Drop_Event->drop_TargetPath Storage!\n", __PRETTY_FUNCTION__);
5380 goto dragdropdone;
5382 strcpy(dragDropEvent->drop_TargetPath, drop_target_node->ie_IconListEntry.label);
5385 #if defined(DEBUG_ILC_ICONDRAGDROP)
5386 D(bug("[IconList] %s: Target Icon Full Path = '%s'\n", __PRETTY_FUNCTION__, dragDropEvent->drop_TargetPath));
5387 #endif
5388 /* mark the Icon the selection was dropped on*/
5389 //drop_target_node->ie_Flags |= ICONENTRY_FLAG_SELECTED;
5390 //data->icld_UpdateMode = UPDATE_SINGLEICON;
5391 //data->update_icon = drop_target_node;
5392 //MUI_Redraw(obj,MADF_DRAWUPDATE);
5394 else
5396 /* not dropped on icon -> get path of DESTINATION iconlist */
5397 /* Note: directory_path is NULL when dropped on Wanderer's desktop */
5398 if ((message->obj != obj) && directory_path)
5400 #if defined(DEBUG_ILC_ICONDRAGDROP)
5401 D(bug("[IconList] %s: drop entry: Icons dropped in window '%s'\n", __PRETTY_FUNCTION__, directory_path));
5402 #endif
5403 /* copy path */
5404 if ((dragDropEvent->drop_TargetPath = AllocVec(strlen(directory_path) + 1, MEMF_CLEAR)) != NULL)
5406 strcpy(dragDropEvent->drop_TargetPath, directory_path);
5408 else
5410 #if defined(DEBUG_ILC_ICONDRAGDROP)
5411 D(bug("[IconList] %s: Failed to allocate IconList_Drop_Event->drop_TargetPath Storage!\n", __PRETTY_FUNCTION__));
5412 #endif
5413 goto dragdropdone;
5416 else if (message->obj == obj)
5418 #if defined(DEBUG_ILC_ICONDRAGDROP)
5419 D(bug("[IconList] %s: drop entry: Icon Move detected ..\n", __PRETTY_FUNCTION__));
5420 #endif
5421 iconMove = TRUE;
5422 SET(obj, MUIA_IconList_IconsMoved, (IPTR)entry); // Now notify
5423 MUI_Redraw(obj,MADF_DRAWOBJECT);
5424 DoMethod(obj, MUIM_IconList_CoordsSort);
5426 else
5428 #if defined(DEBUG_ILC_ICONDRAGDROP)
5429 D(bug("[IconList] %s: Icons Dropped on Wanderer Desktop (unhandled)!\n", __PRETTY_FUNCTION__));
5430 #endif
5431 iconMove = TRUE;
5434 if (!(iconMove))
5436 int copycount = 0;
5437 /* Create list of entries to copy .. */
5438 entry = (IPTR)MUIV_IconList_NextIcon_Start;
5439 while (entry != (IPTR)MUIV_IconList_NextIcon_End)
5441 DoMethod(message->obj, MUIM_IconList_NextIcon, MUIV_IconList_NextIcon_Selected, (IPTR)&entry);
5443 if (entry != (IPTR)MUIV_IconList_NextIcon_End)
5445 struct IconList_Drop_SourceEntry *sourceEntry = NULL;
5446 sourceEntry = AllocMem(sizeof(struct IconList_Drop_SourceEntry), MEMF_CLEAR);
5447 if ((entry->type != ST_ROOT) && (entry->type != ST_SOFTLINK))
5449 int fulllen = 0;
5450 char *path = NULL;
5452 GET(message->obj, MUIA_IconDrawerList_Drawer, &path);
5453 /* Properly expand the location incase it uses devices rather than volumes */
5454 if (path != NULL)
5456 tmp_dirlock = Lock(path, SHARED_LOCK);
5457 if (tmp_dirlock)
5459 if (NameFromLock(tmp_dirlock, tmp_dirbuff, 256))
5461 path = tmp_dirbuff;
5463 UnLock(tmp_dirlock);
5466 if (strcasecmp(dragDropEvent->drop_TargetPath, path) != 0)
5468 fulllen = strlen(path) + strlen(entry->ile_IconEntry->ie_IconNode.ln_Name) + 2;
5469 sourceEntry->dropse_Node.ln_Name = AllocVec(fulllen, MEMF_CLEAR);
5470 strcpy(sourceEntry->dropse_Node.ln_Name, path);
5471 AddPart(sourceEntry->dropse_Node.ln_Name, entry->label, fulllen);
5472 #if defined(DEBUG_ILC_ICONDRAGDROP)
5473 D(bug("[IconList] %s: Source Icon (Full Path) = '%s'\n", __PRETTY_FUNCTION__, sourceEntry->dropse_Node.ln_Name));
5474 #endif
5478 else
5480 sourceEntry->dropse_Node.ln_Name = AllocVec(strlen(entry->label) + 1, MEMF_CLEAR);
5481 strcpy(sourceEntry->dropse_Node.ln_Name, entry->label);
5482 #if defined(DEBUG_ILC_ICONDRAGDROP)
5483 D(bug("[IconList] %s: Source Icon = '%s'\n", __PRETTY_FUNCTION__, sourceEntry->dropse_Node.ln_Name));
5484 #endif
5487 if ((sourceEntry->dropse_Node.ln_Name != NULL) && (strcasecmp(dragDropEvent->drop_TargetPath, sourceEntry->dropse_Node.ln_Name) != 0))
5489 copycount += 1;
5490 AddTail(&dragDropEvent->drop_SourceList, &sourceEntry->dropse_Node);
5492 else
5494 #if defined(DEBUG_ILC_ICONDRAGDROP)
5495 D(bug("[IconList] %s: Source == Dest, Skipping!\n", __PRETTY_FUNCTION__));
5496 #endif
5497 if ( sourceEntry->dropse_Node.ln_Name) FreeVec(sourceEntry->dropse_Node.ln_Name);
5498 FreeMem(sourceEntry, sizeof(struct IconList_Drop_SourceEntry));
5502 if (copycount > 0)
5504 dragDropEvent->drop_TargetObj = (IPTR)obj;
5506 #if defined(DEBUG_ILC_ICONDRAGDROP)
5507 D(bug("[IconList] %s: Causing DROP notification..\n", __PRETTY_FUNCTION__));
5508 #endif
5509 SET(obj, MUIA_IconList_IconsDropped, (IPTR)dragDropEvent);
5510 DoMethod(obj, MUIM_IconList_CoordsSort);
5512 else
5514 if (dragDropEvent->drop_TargetPath) FreeVec(dragDropEvent->drop_TargetPath);
5515 FreeMem(dragDropEvent, sizeof(struct IconList_Drop_Event));
5519 else
5521 #if defined(DEBUG_ILC_ICONDRAGDROP)
5522 D(bug("[IconList] %s: BUG - DragDrop recieved with no source icons!\n", __PRETTY_FUNCTION__));
5523 #endif
5524 NNSET(obj, MUIA_IconList_IconsDropped, (IPTR)NULL);
5527 dragdropdone:
5528 return DoSuperMethodA(CLASS, obj, (Msg)message);
5532 ///MUIM_UnselectAll()
5533 /**************************************************************************
5534 MUIM_UnselectAll
5535 **************************************************************************/
5536 IPTR IconList__MUIM_IconList_UnselectAll(struct IClass *CLASS, Object *obj, Msg message)
5538 struct IconList_DATA *data = INST_DATA(CLASS, obj);
5539 struct Node *node = NULL, *next_node = NULL;
5540 BOOL changed = FALSE;
5542 #if defined(DEBUG_ILC_FUNCS)
5543 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
5544 #endif
5546 data->icld_SelectionLastClicked = NULL;
5547 data->icld_FocusIcon = NULL;
5548 #if defined(__AROS__)
5549 ForeachNodeSafe(&data->icld_SelectionList, node, next_node)
5550 #else
5551 Foreach_NodeSafe(&data->icld_SelectionList, node, next_node);
5552 #endif
5554 struct IconEntry *entry = (struct IconEntry *)((IPTR)node - ((IPTR)&entry->ie_SelectionNode - (IPTR)entry));
5555 BOOL update_icon = FALSE;
5557 if (entry->ie_Flags & ICONENTRY_FLAG_VISIBLE)
5559 if (entry->ie_Flags & ICONENTRY_FLAG_SELECTED)
5561 Remove(node);
5562 entry->ie_Flags &= ~ICONENTRY_FLAG_SELECTED;
5563 update_icon = TRUE;
5565 if (entry->ie_Flags & ICONENTRY_FLAG_FOCUS)
5567 entry->ie_Flags &= ~ICONENTRY_FLAG_FOCUS;
5568 update_icon = TRUE;
5572 if (update_icon)
5574 changed = TRUE;
5575 data->icld_UpdateMode = UPDATE_SINGLEICON;
5576 data->update_icon = entry;
5577 MUI_Redraw(obj, MADF_DRAWUPDATE);
5581 if (changed)
5582 SET(obj, MUIA_IconList_SelectionChanged, TRUE);
5584 return 1;
5588 ///MUIM_SelectAll()
5589 /**************************************************************************
5590 MUIM_SelectAll
5591 **************************************************************************/
5592 IPTR IconList__MUIM_IconList_SelectAll(struct IClass *CLASS, Object *obj, Msg message)
5594 struct IconList_DATA *data = INST_DATA(CLASS, obj);
5595 struct IconEntry *node = NULL;
5596 BOOL changed = FALSE;
5598 #if defined(DEBUG_ILC_FUNCS)
5599 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
5600 #endif
5602 node = (struct IconEntry *)GetHead(&data->icld_IconList);
5604 while (node != NULL)
5606 if (node->ie_Flags & ICONENTRY_FLAG_VISIBLE)
5608 BOOL update_icon = FALSE;
5610 if (!(node->ie_Flags & ICONENTRY_FLAG_SELECTED))
5612 AddTail(&data->icld_SelectionList, &node->ie_SelectionNode);
5613 node->ie_Flags |= ICONENTRY_FLAG_SELECTED;
5614 update_icon = TRUE;
5616 data->icld_SelectionLastClicked = node;
5618 else if (node->ie_Flags & ICONENTRY_FLAG_FOCUS)
5620 node->ie_Flags &= ~ICONENTRY_FLAG_FOCUS;
5621 update_icon = TRUE;
5624 if (update_icon)
5626 changed = TRUE;
5627 data->icld_UpdateMode = UPDATE_SINGLEICON;
5628 data->update_icon = node;
5629 MUI_Redraw(obj, MADF_DRAWUPDATE);
5632 node = (struct IconEntry *)GetSucc(&node->ie_IconNode);
5635 if ((data->icld_SelectionLastClicked) && (data->icld_SelectionLastClicked != data->icld_FocusIcon))
5637 data->icld_FocusIcon = data->icld_SelectionLastClicked;
5638 if (!(data->icld_FocusIcon->ie_Flags & ICONENTRY_FLAG_FOCUS))
5640 data->icld_FocusIcon->ie_Flags &= ~ICONENTRY_FLAG_FOCUS;
5641 data->icld_FocusIcon->ie_Flags |= ICONENTRY_FLAG_FOCUS;
5642 data->icld_UpdateMode = UPDATE_SINGLEICON;
5643 data->update_icon = data->icld_FocusIcon;
5644 MUI_Redraw(obj, MADF_DRAWUPDATE);
5648 if (changed)
5649 SET(obj, MUIA_IconList_SelectionChanged, TRUE);
5651 return 1;
5655 ///IconList__MUIM_IconList_CoordsSort()
5656 IPTR IconList__MUIM_IconList_CoordsSort(struct IClass *CLASS, Object *obj, struct MUIP_IconList_Sort *message)
5658 struct IconList_DATA *data = INST_DATA(CLASS, obj);
5660 struct IconEntry *entry = NULL,
5661 *test_icon = NULL;
5663 struct List list_VisibleIcons;
5664 struct List list_HiddenIcons;
5667 perform a quick sort of the iconlist based on icon coords
5668 this method DOESNT cause any visual output.
5670 #if defined(DEBUG_ILC_FUNCS) && defined(DEBUG_ILC_ICONSORTING)
5671 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
5672 #endif
5674 NewList((struct List*)&list_VisibleIcons);
5675 NewList((struct List*)&list_HiddenIcons);
5677 /*move list into our local list struct(s)*/
5678 while ((entry = (struct IconEntry *)RemTail((struct List*)&data->icld_IconList)))
5680 if (entry->ie_Flags & ICONENTRY_FLAG_VISIBLE)
5681 AddHead((struct List*)&list_VisibleIcons, (struct Node *)&entry->ie_IconNode);
5682 else
5683 AddHead((struct List*)&list_HiddenIcons, (struct Node *)&entry->ie_IconNode);
5686 while ((entry = (struct IconEntry *)RemTail((struct List*)&list_VisibleIcons)))
5688 if ((test_icon = (struct IconEntry *)GetTail(&data->icld_IconList)) != NULL)
5690 while (test_icon != NULL)
5692 if (((data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL) && (test_icon->ie_IconX > entry->ie_IconX)) ||
5693 (!(data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL) && (test_icon->ie_IconY > entry->ie_IconY)))
5695 test_icon = (struct IconEntry *)GetPred(&test_icon->ie_IconNode);
5696 continue;
5698 else break;
5701 while (test_icon != NULL)
5703 if (((data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL) && (test_icon->ie_IconY > entry->ie_IconY)) ||
5704 (!(data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL) && (test_icon->ie_IconX > entry->ie_IconX)))
5706 test_icon = (struct IconEntry *)GetPred(&test_icon->ie_IconNode);
5707 continue;
5709 else break;
5711 Insert((struct List*)&data->icld_IconList, (struct Node *)&entry->ie_IconNode, (struct Node *)&test_icon->ie_IconNode);
5713 else
5714 AddTail((struct List*)&data->icld_IconList, (struct Node *)&entry->ie_IconNode);
5716 #if defined(DEBUG_ILC_ICONSORTING)
5717 D(bug("[IconList] %s: Done\n", __PRETTY_FUNCTION__));
5718 #endif
5720 while ((entry = (struct IconEntry *)RemTail((struct List*)&list_HiddenIcons)))
5722 AddTail((struct List*)&data->icld_IconList, (struct Node *)&entry->ie_IconNode);
5725 #if defined(DEBUG_ILC_ICONSORTING_DUMP)
5726 #if defined(__AROS__)
5727 ForeachNode(&data->icld_IconList, entry)
5728 #else
5729 Foreach_Node(&data->icld_IconList, entry);
5730 #endif
5732 D(bug("[IconList] %s: %d %d '%s'\n", __PRETTY_FUNCTION__, entry->ie_IconX, entry->ie_IconY, entry->ie_IconListEntry.label));
5734 #endif
5736 return TRUE;
5740 ///MUIM_Sort()
5741 /**************************************************************************
5742 MUIM_Sort - sortsort
5743 **************************************************************************/
5744 IPTR IconList__MUIM_IconList_Sort(struct IClass *CLASS, Object *obj, struct MUIP_IconList_Sort *message)
5746 struct IconList_DATA *data = INST_DATA(CLASS, obj);
5747 struct IconEntry *entry = NULL,
5748 *icon1 = NULL,
5749 *icon2 = NULL;
5751 struct List list_VisibleIcons,
5752 list_SortedIcons,
5753 list_HiddenIcons;
5755 BOOL sortme, enqueue = FALSE;
5756 int i, visible_count = 0;
5758 #if defined(DEBUG_ILC_FUNCS) && defined(DEBUG_ILC_ICONSORTING)
5759 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
5760 #endif
5762 /* Reset incase view options have changed .. */
5763 data->icld_IconAreaLargestWidth = 0;
5764 data->icld_IconAreaLargestHeight = 0;
5765 data->icld_IconLargestHeight = 0;
5766 data->icld_LabelLargestHeight = 0;
5768 if ((data->icld_SortFlags & ICONLIST_SORT_MASK) != 0)
5770 #if defined(DEBUG_ILC_ICONSORTING)
5771 D(bug("[IconList] %s: Sorting (Flags %x)\n", __PRETTY_FUNCTION__, (data->icld_SortFlags & ICONLIST_SORT_MASK)));
5772 #endif
5773 NewList((struct List*)&list_VisibleIcons);
5774 NewList((struct List*)&list_SortedIcons);
5775 NewList((struct List*)&list_HiddenIcons);
5777 /*move list into our local list struct(s)*/
5778 while ((entry = (struct IconEntry *)RemTail((struct List*)&data->icld_IconList)))
5780 if (entry->ie_DiskObj)
5782 if (entry->ie_IconX != entry->ie_DiskObj->do_CurrentX)
5784 entry->ie_IconX = entry->ie_DiskObj->do_CurrentX;
5785 if ((data->icld_SortFlags & ICONLIST_SORT_MASK) == 0)
5786 entry->ie_Flags |= ICONENTRY_FLAG_NEEDSUPDATE;
5788 if (entry->ie_IconY != entry->ie_DiskObj->do_CurrentY)
5790 entry->ie_IconY = entry->ie_DiskObj->do_CurrentY;
5791 if ((data->icld_SortFlags & ICONLIST_SORT_MASK) == 0)
5792 entry->ie_Flags |= ICONENTRY_FLAG_NEEDSUPDATE;
5796 if (!(entry->ie_Flags & ICONENTRY_FLAG_HASICON))
5798 if (data->icld_DisplayFlags & ICONLIST_DISP_SHOWINFO)
5800 if (entry->ie_Flags & ICONENTRY_FLAG_VISIBLE)
5802 entry->ie_Flags &= ~(ICONENTRY_FLAG_VISIBLE|ICONENTRY_FLAG_NEEDSUPDATE);
5805 else if (!(entry->ie_Flags & ICONENTRY_FLAG_VISIBLE))
5807 entry->ie_Flags |= (ICONENTRY_FLAG_VISIBLE|ICONENTRY_FLAG_NEEDSUPDATE);
5810 else
5812 if (!(entry->ie_Flags & ICONENTRY_FLAG_VISIBLE))
5814 entry->ie_Flags |= (ICONENTRY_FLAG_VISIBLE|ICONENTRY_FLAG_NEEDSUPDATE);
5818 /* Now we have fixed visibility lets dump them into the correct list for sorting */
5819 if (entry->ie_Flags & ICONENTRY_FLAG_VISIBLE)
5821 if(entry->ie_AreaWidth > data->icld_IconAreaLargestWidth) data->icld_IconAreaLargestWidth = entry->ie_AreaWidth;
5822 if(entry->ie_AreaHeight > data->icld_IconAreaLargestHeight) data->icld_IconAreaLargestHeight = entry->ie_AreaHeight;
5823 if(entry->ie_IconHeight > data->icld_IconLargestHeight) data->icld_IconLargestHeight = entry->ie_IconHeight;
5824 if((entry->ie_AreaHeight - entry->ie_IconHeight) > data->icld_LabelLargestHeight) data->icld_LabelLargestHeight = entry->ie_AreaHeight - entry->ie_IconHeight;
5826 if (((data->icld_SortFlags & ICONLIST_SORT_MASK) == 0) && (entry->ie_IconX == NO_ICON_POSITION))
5827 AddTail((struct List*)&list_VisibleIcons, (struct Node *)&entry->ie_IconNode);
5828 else
5829 AddHead((struct List*)&list_VisibleIcons, (struct Node *)&entry->ie_IconNode);
5830 visible_count++;
5832 else
5834 if (entry->ie_Flags & ICONENTRY_FLAG_SELECTED)
5836 Remove(&entry->ie_SelectionNode);
5838 entry->ie_Flags &= ~(ICONENTRY_FLAG_SELECTED|ICONENTRY_FLAG_FOCUS);
5839 if (data->icld_SelectionLastClicked == entry) data->icld_SelectionLastClicked = NULL;
5840 if (data->icld_FocusIcon == entry) data->icld_FocusIcon = data->icld_SelectionLastClicked;
5841 AddHead((struct List*)&list_HiddenIcons, (struct Node *)&entry->ie_IconNode);
5845 /* Copy each visible icon entry back to the main list, sorting as we go*/
5847 while ((entry = (struct IconEntry *)RemHead((struct List*)&list_VisibleIcons)))
5849 icon1 = (struct IconEntry *)GetHead(&list_SortedIcons);
5850 icon2 = NULL;
5852 sortme = FALSE;
5854 if (visible_count > 1)
5856 // D(bug(" - %s %s %s %i\n",entry->ie_IconListEntry.label,entry->ie_TxtBuf_DATE,entry->ie_TxtBuf_TIME,entry->ie_FileInfoBlock->fib_Size));
5858 while (icon1)
5860 if((icon1->ie_IconListEntry.type == ST_ROOT)||(data->icld_SortFlags & ICONLIST_SORT_DRAWERS_MIXED))
5862 /*volume list or drawers mixed*/
5863 sortme = TRUE;
5865 else
5867 /*drawers first*/
5868 if ((icon1->ie_IconListEntry.type == ST_USERDIR) && (entry->ie_IconListEntry.type == ST_USERDIR))
5870 sortme = TRUE;
5872 else
5874 if ((icon1->ie_IconListEntry.type != ST_USERDIR) && (entry->ie_IconListEntry.type != ST_USERDIR))
5875 sortme = TRUE;
5876 else
5878 /* we are the first drawer to arrive or we need to insert ourselves
5879 due to being sorted to the end of the drawers*/
5881 if ((!icon2 || icon2->ie_IconListEntry.type == ST_USERDIR) &&
5882 (entry->ie_IconListEntry.type == ST_USERDIR) &&
5883 (icon1->ie_IconListEntry.type != ST_USERDIR))
5885 // D(bug("force %s\n",entry->ie_IconListEntry.label));
5886 break;
5892 if (sortme)
5894 i = 0;
5896 if ((data->icld_SortFlags & ICONLIST_SORT_MASK) == ICONLIST_SORT_BY_DATE)
5898 /* Sort by Date */
5899 i = CompareDates((const struct DateStamp *)&entry->ie_FileInfoBlock->fib_Date,(const struct DateStamp *)&icon1->ie_FileInfoBlock->fib_Date);
5901 else if ((data->icld_SortFlags & ICONLIST_SORT_MASK) == ICONLIST_SORT_BY_SIZE)
5903 /* Sort by Size .. */
5904 i = entry->ie_FileInfoBlock->fib_Size - icon1->ie_FileInfoBlock->fib_Size;
5906 else if (((data->icld_SortFlags & ICONLIST_SORT_MASK) == ICONLIST_SORT_MASK) && (entry->ie_IconListEntry.type != ST_ROOT))
5908 /* Sort by Type .. */
5909 #warning "TODO: Sort icons based on type using datatypes"
5911 else
5913 if (
5914 ((data->icld_SortFlags & ICONLIST_SORT_MASK) == ICONLIST_SORT_MASK) ||
5915 ((data->icld_SortFlags & ICONLIST_SORT_MASK) == ICONLIST_SORT_BY_NAME) ||
5916 (entry->ie_IconX == NO_ICON_POSITION)
5919 /* Sort by Name .. */
5920 i = Stricmp(entry->ie_IconListEntry.label, icon1->ie_IconListEntry.label);
5921 if ((data->icld_SortFlags & ICONLIST_SORT_MASK) == ICONLIST_SORT_MASK)
5922 enqueue = TRUE;
5924 else
5926 /* coord sort */
5927 #warning "TODO: Implement default coord sorting.."
5931 if (data->icld_SortFlags & ICONLIST_SORT_REVERSE)
5933 if (i > 0)
5934 break;
5936 else if (i < 0)
5937 break;
5939 icon2 = icon1;
5940 icon1 = (struct IconEntry *)GetSucc(&icon1->ie_IconNode);
5943 Insert((struct List*)&list_SortedIcons, (struct Node *)&entry->ie_IconNode, (struct Node *)&icon2->ie_IconNode);
5945 if (enqueue)
5947 /* Quickly resort based on node priorities .. */
5948 while ((entry = (struct IconEntry *)RemHead((struct List*)&list_SortedIcons)))
5950 Enqueue((struct List*)&data->icld_IconList, (struct Node *)&entry->ie_IconNode);
5953 else
5955 while ((entry = (struct IconEntry *)RemHead((struct List*)&list_SortedIcons)))
5957 AddTail((struct List*)&data->icld_IconList, (struct Node *)&entry->ie_IconNode);
5961 else
5963 #if defined(DEBUG_ILC_ICONSORTING)
5964 D(bug("[IconList] %s: Coord Sorting\n", __PRETTY_FUNCTION__));
5965 #endif
5966 DoMethod(obj, MUIM_IconList_CoordsSort);
5969 DoMethod(obj, MUIM_IconList_PositionIcons);
5970 MUI_Redraw(obj, MADF_DRAWOBJECT);
5972 if ((data->icld_SortFlags & ICONLIST_SORT_MASK) != 0)
5974 DoMethod(obj, MUIM_IconList_CoordsSort);
5976 /* leave hidden icons on a seperate list to speed up normal list parsing ? */
5977 while ((entry = (struct IconEntry *)RemHead((struct List*)&list_HiddenIcons)))
5979 AddTail((struct List*)&data->icld_IconList, (struct Node *)&entry->ie_IconNode);
5982 SET(obj, MUIA_IconList_Changed, TRUE);
5984 return 1;
5988 ///MUIM_DragReport()
5989 /**************************************************************************
5990 MUIM_DragReport. Since MUI doesn't change the drop object if the dragged
5991 object is moved above another window (while still in the bounds of the
5992 orginal drop object) we must do it here manually to be compatible with
5993 MUI. Maybe Zune should fix this bug somewhen.
5994 **************************************************************************/
5995 IPTR IconList__MUIM_DragReport(struct IClass *CLASS, Object *obj, struct MUIP_DragReport *message)
5997 struct Window *wnd = _window(obj);
5998 struct Layer *l = NULL;
6000 #if defined(DEBUG_ILC_FUNCS)
6001 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
6002 #endif
6004 l = WhichLayer(&wnd->WScreen->LayerInfo, wnd->LeftEdge + message->x, wnd->TopEdge + message->y);
6006 if (l != wnd->WLayer) return MUIV_DragReport_Abort;
6008 return MUIV_DragReport_Continue;
6012 ///MUIM_IconList_UnknownDropDestination()
6013 /**************************************************************************
6014 MUIM_IconList_UnknownDropDestination
6015 **************************************************************************/
6016 IPTR IconList__MUIM_UnknownDropDestination(struct IClass *CLASS, Object *obj, struct MUIP_UnknownDropDestination *message)
6018 #if defined(DEBUG_ILC_FUNCS)
6019 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
6020 #endif
6021 D(bug("[IconList] %s: icons dropped on custom window \n", __PRETTY_FUNCTION__));
6023 SET(obj, MUIA_IconList_AppWindowDrop, (IPTR)message); /* Now notify */
6025 return (IPTR)NULL;
6029 ///MUIM_IconList_MakeIconVisible()
6030 /**************************************************************************
6031 Move the visible area so that the selected icon becomes visible ..
6032 **************************************************************************/
6033 IPTR IconList__MUIM_IconList_MakeIconVisible(struct IClass *CLASS, Object *obj, struct MUIP_IconList_MakeIconVisible *message)
6035 struct IconList_DATA *data = INST_DATA(CLASS, obj);
6036 BOOL viewmoved = FALSE;
6037 struct Rectangle iconrect, viewrect;
6039 #if defined(DEBUG_ILC_FUNCS)
6040 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
6041 #endif
6043 viewrect.MinX = data->icld_ViewX;
6044 viewrect.MaxX = data->icld_ViewX + data->icld_AreaWidth;
6045 viewrect.MinY = data->icld_ViewY;
6046 viewrect.MaxY = data->icld_ViewY + data->icld_AreaHeight;
6048 IconList_GetIconAreaRectangle(obj, data, message->icon, &iconrect);
6050 if (!(RectAndRect(&viewrect, &iconrect)))
6052 viewmoved = TRUE;
6053 if (message->icon->ie_IconX < data->icld_ViewX)
6054 data->icld_ViewX = message->icon->ie_IconX;
6055 else if (message->icon->ie_IconX > (data->icld_ViewX + data->icld_AreaWidth))
6056 data->icld_ViewX = (message->icon->ie_IconX + message->icon->ie_AreaWidth) - data->icld_AreaWidth;
6058 if (message->icon->ie_IconY < data->icld_ViewY)
6059 data->icld_ViewY = message->icon->ie_IconX;
6060 else if (message->icon->ie_IconY > (data->icld_ViewY + data->icld_AreaHeight))
6061 data->icld_ViewY = (message->icon->ie_IconY + message->icon->ie_AreaHeight) - data->icld_AreaHeight;
6064 if (viewmoved)
6066 D(bug("[IconList]: %s: call SetSuperAttrs()\n", __PRETTY_FUNCTION__));
6067 SetSuperAttrs(CLASS, obj, MUIA_Virtgroup_Left, data->icld_ViewX,
6068 MUIA_Virtgroup_Top, data->icld_ViewY,
6069 TAG_DONE);
6071 D(bug("[IconList]: %s: call SetAttrs()\n", __PRETTY_FUNCTION__));
6072 SetAttrs(obj, MUIA_Virtgroup_Left, data->icld_ViewX,
6073 MUIA_Virtgroup_Top, data->icld_ViewY,
6074 TAG_DONE);
6076 D(bug("[IconList]: %s: call MUI_Redraw()\n", __PRETTY_FUNCTION__));
6077 MUI_Redraw(obj,MADF_DRAWOBJECT);
6079 return 1;
6082 #if defined(WANDERER_BUILTIN_ICONLIST)
6083 BOOPSI_DISPATCHER(IPTR,IconList_Dispatcher, CLASS, obj, message)
6085 #if defined(__AROS__)
6086 switch (message->MethodID)
6087 #else
6088 struct IClass *CLASS = cl;
6089 Msg message = msg;
6091 switch (msg->MethodID)
6092 #endif
6094 case OM_NEW: return IconList__OM_NEW(CLASS, obj, (struct opSet *)message);
6095 case OM_DISPOSE: return IconList__OM_DISPOSE(CLASS, obj, message);
6096 case OM_SET: return IconList__OM_SET(CLASS, obj, (struct opSet *)message);
6097 case OM_GET: return IconList__OM_GET(CLASS, obj, (struct opGet *)message);
6098 case OM_ADDMEMBER:
6099 case MUIM_Family_AddTail: return IconList__MUIM_Family_AddTail(CLASS, obj, (APTR)message);
6100 case MUIM_Family_AddHead: return IconList__MUIM_Family_AddHead(CLASS, obj, (APTR)message);
6101 case OM_REMMEMBER:
6102 case MUIM_Family_Remove: return IconList__MUIM_Family_Remove(CLASS, obj, (APTR)message);
6104 case MUIM_Setup: return IconList__MUIM_Setup(CLASS, obj, (struct MUIP_Setup *)message);
6106 case MUIM_Show: return IconList__MUIM_Show(CLASS,obj, (struct MUIP_Show *)message);
6107 case MUIM_Hide: return IconList__MUIM_Hide(CLASS,obj, (struct MUIP_Hide *)message);
6108 case MUIM_Cleanup: return IconList__MUIM_Cleanup(CLASS, obj, (struct MUIP_Cleanup *)message);
6109 case MUIM_AskMinMax: return IconList__MUIM_AskMinMax(CLASS, obj, (struct MUIP_AskMinMax *)message);
6110 case MUIM_Draw: return IconList__MUIM_Draw(CLASS, obj, (struct MUIP_Draw *)message);
6111 #if defined(__AROS__)
6112 case MUIM_Layout: return IconList__MUIM_Layout(CLASS, obj, (struct MUIP_Layout *)message);
6113 #endif
6114 case MUIM_HandleEvent: return IconList__MUIM_HandleEvent(CLASS, obj, (struct MUIP_HandleEvent *)message);
6115 case MUIM_CreateDragImage: return IconList__MUIM_CreateDragImage(CLASS, obj, (APTR)message);
6116 case MUIM_DeleteDragImage: return IconList__MUIM_DeleteDragImage(CLASS, obj, (APTR)message);
6117 case MUIM_DragQuery: return IconList__MUIM_DragQuery(CLASS, obj, (APTR)message);
6118 case MUIM_DragReport: return IconList__MUIM_DragReport(CLASS, obj, (APTR)message);
6119 case MUIM_DragDrop: return IconList__MUIM_DragDrop(CLASS, obj, (APTR)message);
6120 #if defined(__AROS__)
6121 case MUIM_UnknownDropDestination: return IconList__MUIM_UnknownDropDestination(CLASS, obj, (APTR)message);
6122 #endif
6123 case MUIM_IconList_Update: return IconList__MUIM_IconList_Update(CLASS, obj, (APTR)message);
6124 case MUIM_IconList_Clear: return IconList__MUIM_IconList_Clear(CLASS, obj, (APTR)message);
6125 case MUIM_IconList_RethinkDimensions: return IconList__MUIM_IconList_RethinkDimensions(CLASS, obj, (APTR)message);
6126 case MUIM_IconList_CreateEntry: return IconList__MUIM_IconList_CreateEntry(CLASS, obj, (APTR)message);
6127 case MUIM_IconList_UpdateEntry: return IconList__MUIM_IconList_UpdateEntry(CLASS, obj, (APTR)message);
6128 case MUIM_IconList_DestroyEntry: return IconList__MUIM_IconList_DestroyEntry(CLASS, obj, (APTR)message);
6129 case MUIM_IconList_DrawEntry: return IconList__MUIM_IconList_DrawEntry(CLASS, obj, (APTR)message);
6130 case MUIM_IconList_DrawEntryLabel: return IconList__MUIM_IconList_DrawEntryLabel(CLASS, obj, (APTR)message);
6131 case MUIM_IconList_NextIcon: return IconList__MUIM_IconList_NextIcon(CLASS, obj, (APTR)message);
6132 case MUIM_IconList_GetIconPrivate: return IconList__MUIM_IconList_GetIconPrivate(CLASS, obj, (APTR)message);
6133 case MUIM_IconList_UnselectAll: return IconList__MUIM_IconList_UnselectAll(CLASS, obj, (APTR)message);
6134 case MUIM_IconList_Sort: return IconList__MUIM_IconList_Sort(CLASS, obj, (APTR)message);
6135 case MUIM_IconList_CoordsSort: return IconList__MUIM_IconList_CoordsSort(CLASS, obj, (APTR)message);
6136 case MUIM_IconList_PositionIcons: return IconList__MUIM_IconList_PositionIcons(CLASS, obj, (APTR)message);
6137 case MUIM_IconList_SelectAll: return IconList__MUIM_IconList_SelectAll(CLASS, obj, (APTR)message);
6138 case MUIM_IconList_MakeIconVisible: return IconList__MUIM_IconList_MakeIconVisible(CLASS, obj, (APTR)message);
6141 return DoSuperMethodA(CLASS, obj, message);
6143 BOOPSI_DISPATCHER_END
6145 #if defined(__AROS__)
6146 /* Class descriptor. */
6147 const struct __MUIBuiltinClass _MUI_IconList_desc = {
6148 MUIC_IconList,
6149 MUIC_Area,
6150 sizeof(struct IconList_DATA),
6151 (void*)IconList_Dispatcher
6153 #endif
6154 #endif /* WANDERER_BUILTIN_ICONLIST */
6156 #if !defined(__AROS__)
6157 struct MUI_CustomClass *initIconListClass(void)
6159 return (struct MUI_CustomClass *) MUI_CreateCustomClass(NULL, MUIC_Area, NULL, sizeof(struct IconList_DATA), ENTRY(IconList_Dispatcher));
6161 #endif