Format status bar size display, and cleanup code a little
[AROS.git] / workbench / system / Wanderer / Classes / iconlist.c
blob12f9eb9e25f273f680e96b288918458b72a2da48
1 /*
2 Copyright 2002-2009, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include "../portable_macros.h"
7 #ifndef __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 #ifdef __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 #ifdef __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 #ifdef __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 #ifndef __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 #ifdef AndRectRect
151 /* Fine */
152 #else
153 #ifdef __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 ///GetAbsoluteLassoRect()
245 // get positive lasso coords
246 static void GetAbsoluteLassoRect(struct IconList_DATA *data, struct Rectangle *LassoRectangle)
248 WORD minx = data->icld_LassoRectangle.MinX;
249 WORD miny = data->icld_LassoRectangle.MinY;
250 WORD maxx = data->icld_LassoRectangle.MaxX;
251 WORD maxy = data->icld_LassoRectangle.MaxY;
253 #if defined(DEBUG_ILC_LASSO) && defined(DEBUG_ILC_FUNCS)
254 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
255 #endif
257 if (minx > maxx)
259 /* Swap minx, maxx */
260 minx ^= maxx;
261 maxx ^= minx;
262 minx ^= maxx;
265 if (miny > maxy)
267 /* Swap miny, maxy */
268 miny ^= maxy;
269 maxy ^= miny;
270 miny ^= maxy;
273 LassoRectangle->MinX = data->view_rect.MinX - data->icld_ViewX + minx;
274 LassoRectangle->MinY = data->view_rect.MinY - data->icld_ViewY + miny;
275 LassoRectangle->MaxX = data->view_rect.MinX - data->icld_ViewX + maxx;
276 LassoRectangle->MaxY = data->view_rect.MinY - data->icld_ViewY + maxy;
280 ///IconList_InvertPixelRect()
281 static void IconList_InvertPixelRect(struct RastPort *rp, WORD minx, WORD miny, WORD maxx, WORD maxy, struct Rectangle *clip)
283 struct Rectangle r, clipped_r;
285 #if defined(DEBUG_ILC_RENDERING) && defined(DEBUG_ILC_FUNCS)
286 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
287 #endif
289 if (maxx < minx)
291 /* Swap minx, maxx */
292 minx ^= maxx;
293 maxx ^= minx;
294 minx ^= maxx;
297 if (maxy < miny)
299 /* Swap miny, maxy */
300 miny ^= maxy;
301 maxy ^= miny;
302 miny ^= maxy;
305 r.MinX = minx;
306 r.MinY = miny;
307 r.MaxX = maxx;
308 r.MaxY = maxy;
310 if (AndRectRect(&r, clip, &clipped_r))
312 InvertPixelArray(rp, clipped_r.MinX, clipped_r.MinY,
313 clipped_r.MaxX - clipped_r.MinX + 1, clipped_r.MaxY - clipped_r.MinY + 1);
318 ///IconList_InvertLassoOutlines()
319 // Simple lasso drawing by inverting area outlines
320 static void IconList_InvertLassoOutlines(Object *obj, struct Rectangle *rect)
322 struct Rectangle lasso;
323 struct Rectangle clip;
325 #if defined(DEBUG_ILC_LASSO) && defined(DEBUG_ILC_FUNCS)
326 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
327 #endif
329 /* get abolute iconlist coords */
330 lasso.MinX = rect->MinX + _mleft(obj);
331 lasso.MaxX = rect->MaxX + _mleft(obj);
332 lasso.MinY = rect->MinY + _mtop(obj);
333 lasso.MaxY = rect->MaxY + _mtop(obj);
335 clip.MinX = _mleft(obj);
336 clip.MinY = _mtop(obj);
337 clip.MaxX = _mright(obj);
338 clip.MaxY = _mbottom(obj);
340 /* horizontal lasso lines */
341 IconList_InvertPixelRect(_rp(obj), lasso.MinX, lasso.MinY, lasso.MaxX-1, lasso.MinY + 1, &clip);
342 IconList_InvertPixelRect(_rp(obj), lasso.MinX, lasso.MaxY, lasso.MaxX-1, lasso.MaxY + 1, &clip);
344 /* vertical lasso lines */
345 IconList_InvertPixelRect(_rp(obj), lasso.MinX, lasso.MinY, lasso.MinX + 1, lasso.MaxY - 1, &clip);
346 IconList_InvertPixelRect(_rp(obj), lasso.MaxX, lasso.MinY, lasso.MaxX + 1, lasso.MaxY - 1, &clip);
350 ///IconList_GetIconImageRectangle()
351 //We don't use icon.library's label drawing so we do this by hand
352 static void IconList_GetIconImageRectangle(Object *obj, struct IconList_DATA *data, struct IconEntry *icon, struct Rectangle *rect)
354 #if defined(DEBUG_ILC_ICONPOSITIONING) && defined(DEBUG_ILC_FUNCS)
355 D(bug("[IconList]: %s(icon @ %p)\n", __PRETTY_FUNCTION__, icon));
356 #endif
358 /* Get basic width/height */
359 GetIconRectangleA(NULL, icon->ie_DiskObj, NULL, rect, NULL);
360 #if defined(DEBUG_ILC_ICONPOSITIONING)
361 D(bug("[IconList] %s: MinX %d, MinY %d MaxX %d, MaxY %d\n", __PRETTY_FUNCTION__, rect->MinX, rect->MinY, rect->MaxX, rect->MaxY));
362 #endif
363 icon->ie_IconWidth = (rect->MaxX - rect->MinX) + 1;
364 icon->ie_IconHeight = (rect->MaxY - rect->MinY) + 1;
366 if (icon->ie_IconHeight > data->icld_IconLargestHeight)
367 data->icld_IconLargestHeight = icon->ie_IconHeight;
371 ///IconList_GetIconLabelRectangle()
372 static void IconList_GetIconLabelRectangle(Object *obj, struct IconList_DATA *data, struct IconEntry *icon, struct Rectangle *rect)
374 ULONG outline_offset = 0;
375 ULONG textwidth = 0;
377 #if defined(DEBUG_ILC_ICONPOSITIONING) && defined(DEBUG_ILC_FUNCS)
378 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
379 #endif
381 switch ( data->icld__Option_LabelTextMode )
383 case ICON_TEXTMODE_DROPSHADOW:
384 outline_offset = 1;
385 break;
387 case ICON_TEXTMODE_PLAIN:
388 break;
390 default:
391 outline_offset = 2;
392 break;
395 /* Get icon box width including text width */
396 if ((icon->ie_IconListEntry.label != NULL) && (icon->ie_TxtBuf_DisplayedLabel != NULL))
398 ULONG curlabel_TotalLines;
399 SetFont(data->icld_BufferRastPort, data->icld_IconLabelFont);
401 rect->MinX = 0;
402 rect->MaxX = (((data->icld__Option_LabelTextHorizontalPadding + data->icld__Option_LabelTextBorderWidth) * 2) + icon->ie_TxtBuf_DisplayedLabelWidth + outline_offset) - 1;
404 rect->MinY = 0;
406 curlabel_TotalLines = icon->ie_SplitParts;
407 if (curlabel_TotalLines == 0)
408 curlabel_TotalLines = 1;
409 if (curlabel_TotalLines > data->icld__Option_LabelTextMultiLine)
410 curlabel_TotalLines = data->icld__Option_LabelTextMultiLine;
412 rect->MaxY = (((data->icld__Option_LabelTextBorderHeight + data->icld__Option_LabelTextVerticalPadding) * 2) +
413 ((data->icld_IconLabelFont->tf_YSize + outline_offset) * curlabel_TotalLines)) - 1;
415 /* Date/size sorting has the date/size appended under the icon label
416 only list regular files like this (drawers have no size/date output) */
418 icon->ie_IconListEntry.type != ST_USERDIR &&
419 ((data->icld_SortFlags & ICONLIST_SORT_BY_SIZE) || (data->icld_SortFlags & ICONLIST_SORT_BY_DATE))
422 SetFont(data->icld_BufferRastPort, data->icld_IconInfoFont);
424 if( (data->icld_SortFlags & ICONLIST_SORT_BY_SIZE) && !(data->icld_SortFlags & ICONLIST_SORT_BY_DATE) )
426 icon->ie_TxtBuf_SIZEWidth = TextLength(data->icld_BufferRastPort, icon->ie_TxtBuf_SIZE, strlen(icon->ie_TxtBuf_SIZE));
427 textwidth = icon->ie_TxtBuf_SIZEWidth;
429 else
431 if( !(data->icld_SortFlags & ICONLIST_SORT_BY_SIZE) && (data->icld_SortFlags & ICONLIST_SORT_BY_DATE) )
433 if( icon->ie_Flags & ICONENTRY_FLAG_TODAY )
435 icon->ie_TxtBuf_TIMEWidth = TextLength(data->icld_BufferRastPort, icon->ie_TxtBuf_TIME, strlen(icon->ie_TxtBuf_TIME));
436 textwidth = icon->ie_TxtBuf_TIMEWidth;
438 else
440 icon->ie_TxtBuf_DATEWidth = TextLength(data->icld_BufferRastPort, icon->ie_TxtBuf_DATE, strlen(icon->ie_TxtBuf_DATE));
441 textwidth = icon->ie_TxtBuf_DATEWidth;
446 if (textwidth > 0)
448 rect->MaxY = rect->MaxY + data->icld_IconInfoFont->tf_YSize + outline_offset;
449 if ((textwidth + outline_offset + ((data->icld__Option_LabelTextHorizontalPadding + data->icld__Option_LabelTextBorderWidth) * 2)) > ((rect->MaxX - rect->MinX) + 1))
450 rect->MaxX = (textwidth + outline_offset + ((data->icld__Option_LabelTextVerticalPadding + data->icld__Option_LabelTextBorderWidth) * 2)) - 1;
454 if (((rect->MaxY - rect->MinY) + 1) > data->icld_LabelLargestHeight) data->icld_LabelLargestHeight = ((rect->MaxY - rect->MinY) + 1);
458 ///IconList_GetIconAreaRectangle()
459 static void IconList_GetIconAreaRectangle(Object *obj, struct IconList_DATA *data, struct IconEntry *icon, struct Rectangle *rect)
461 struct Rectangle labelrect;
462 ULONG iconlabel_Width;
463 ULONG iconlabel_Height;
465 #if defined(DEBUG_ILC_ICONPOSITIONING) && defined(DEBUG_ILC_FUNCS)
466 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
467 #endif
469 /* Get icon box width including text width */
470 memset(rect, 0, sizeof(struct Rectangle));
472 IconList_GetIconImageRectangle(obj, data, icon, rect);
474 icon->ie_AreaWidth = icon->ie_IconWidth;
475 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
477 icon->ie_AreaHeight = data->icld_IconLargestHeight;
479 else
481 icon->ie_AreaHeight = icon->ie_IconHeight;
484 IconList_GetIconLabelRectangle(obj, data, icon, &labelrect);
486 iconlabel_Width = ((labelrect.MaxX - labelrect.MinX) + 1);
487 iconlabel_Height = ((labelrect.MaxY - labelrect.MinY) + 1);
489 if (iconlabel_Width > icon->ie_AreaWidth)
490 icon->ie_AreaWidth = iconlabel_Width;
492 icon->ie_AreaHeight = icon->ie_AreaHeight + data->icld__Option_IconImageSpacing + iconlabel_Height;
494 /* Store */
495 rect->MaxX = (rect->MinX + icon->ie_AreaWidth) - 1;
496 rect->MaxY = (rect->MinY + icon->ie_AreaHeight) - 1;
498 if (icon->ie_AreaWidth > data->icld_IconAreaLargestWidth) data->icld_IconAreaLargestWidth = icon->ie_AreaWidth;
499 if (icon->ie_AreaHeight > data->icld_IconAreaLargestHeight) data->icld_IconAreaLargestHeight = icon->ie_AreaHeight;
502 /**************************************************************************
503 Draw the icon at its position
504 **************************************************************************/
505 ///IconList__MUIM_IconList_DrawEntry()
506 IPTR IconList__MUIM_IconList_DrawEntry(struct IClass *CLASS, Object *obj, struct MUIP_IconList_DrawEntry *message)
508 struct IconList_DATA *data = INST_DATA(CLASS, obj);
510 BOOL outside = FALSE;
512 struct Rectangle iconrect;
513 struct Rectangle objrect;
515 LONG offsetx,offsety;
517 ULONG objX, objY, objW, objH;
518 LONG iconX, iconY;
519 ULONG iconW, iconH;
521 if (data->icld_BufferRastPort == data->icld_DisplayRastPort)
523 objX = _mleft(obj);
524 objY = _mtop(obj);
526 else
528 objX = objY = 0;
530 objW = _mright(obj) - _mleft(obj) + 1;
531 objH = _mbottom(obj) - _mtop(obj) + 1;
533 #if defined(DEBUG_ILC_ICONRENDERING)
534 D(bug("[IconList]: %s(message->icon = 0x%p)\n", __PRETTY_FUNCTION__, message->icon));
535 #endif
537 if ((!(message->icon->ie_Flags & ICONENTRY_FLAG_VISIBLE)) ||
538 (data->icld_BufferRastPort == NULL) ||
539 (!(message->icon->ie_DiskObj)))
541 #if defined(DEBUG_ILC_ICONRENDERING)
542 D(bug("[IconList] %s: Not visible or missing DOB\n", __PRETTY_FUNCTION__));
543 #endif
544 return FALSE;
547 /* Get the dimensions and affected area of message->icon */
548 IconList_GetIconImageRectangle(obj, data, message->icon, &iconrect);
549 iconW = iconrect.MaxX - iconrect.MinX + 1;
550 iconH = iconrect.MaxY - iconrect.MinY + 1;
552 /* Add the relative position offset of the message->icon */
553 offsetx = objX - data->icld_ViewX + message->icon->ie_IconX;
554 /* Centre our image with our text */
555 if (message->icon->ie_IconWidth < message->icon->ie_AreaWidth)
556 offsetx += (message->icon->ie_AreaWidth - message->icon->ie_IconWidth)/2;
558 if ((data->icld__Option_IconListMode == ICON_LISTMODE_GRID) &&
559 (message->icon->ie_AreaWidth < data->icld_IconAreaLargestWidth))
560 offsetx += ((data->icld_IconAreaLargestWidth - message->icon->ie_AreaWidth)/2);
562 iconrect.MinX += offsetx;
563 iconrect.MaxX += offsetx;
565 offsety = objY - data->icld_ViewY + message->icon->ie_IconY;
566 iconrect.MinY += offsety;
567 iconrect.MaxY += offsety;
569 /* Add the relative position of the window */
570 objrect.MinX = objX;
571 objrect.MinY = objY;
572 objrect.MaxX = objX + objW;
573 objrect.MaxY = objY + objH;
575 if (!RectAndRect(&iconrect, &objrect))
577 #if defined(DEBUG_ILC_ICONRENDERING)
578 D(bug("[IconList] %s: Icon '%s' image outside of visible area .. skipping\n", __PRETTY_FUNCTION__, message->icon->ie_IconListEntry.label));
579 #endif
580 return FALSE;
583 /* data->update_rect1 and data->update_rect2 may
584 point to rectangles to indicate that only icons
585 in any of this rectangles need to be drawn */
586 if (data->update_rect1)
588 if (!RectAndRect(&iconrect, data->update_rect1)) outside = TRUE;
591 if (data->update_rect2)
593 if (data->update_rect1)
595 if ((outside == TRUE) && RectAndRect(&iconrect, data->update_rect2)) outside = FALSE;
597 else
599 if (!RectAndRect(&iconrect, data->update_rect2)) outside = TRUE;
603 if (outside == TRUE)
605 #if defined(DEBUG_ILC_ICONRENDERING)
606 D(bug("[IconList] %s: Icon '%s' image outside of update area .. skipping\n", __PRETTY_FUNCTION__, message->icon->ie_IconListEntry.label));
607 #endif
608 return FALSE;
611 if (message->drawmode == ICONENTRY_DRAWMODE_NONE) return TRUE;
613 // Center icon image
614 iconX = iconrect.MinX - objX + data->icld_DrawOffsetX;
615 iconY = iconrect.MinY - objY + data->icld_DrawOffsetY;
617 if ((data->icld_BufferRastPort == data->icld_DisplayRastPort) ||
618 ((data->icld_BufferRastPort != data->icld_DisplayRastPort) &&
619 ((iconX > objX) && (iconX < (objX + objW)) && (iconY > objY) && (iconY < (objY + objH))) &&
620 (((iconX + iconW) > objX) && ((iconX + iconW)< (objX + objW)) && ((iconY + iconH) > objY) && ((iconY + iconH) < (objY + objH)))
623 #if defined(DEBUG_ILC_ICONRENDERING)
624 D(bug("[IconList] %s: DrawIconState('%s') .. %d, %d\n", __PRETTY_FUNCTION__, message->icon->ie_IconListEntry.label, iconX, iconY));
625 #endif
626 DrawIconStateA
628 data->icld_BufferRastPort, message->icon->ie_DiskObj, NULL,
629 iconX,
630 iconY,
631 (message->icon->ie_Flags & ICONENTRY_FLAG_SELECTED) ? IDS_SELECTED : IDS_NORMAL,
632 __iconList_DrawIconStateTags
634 #if defined(DEBUG_ILC_ICONRENDERING)
635 D(bug("[IconList] %s: DrawIconState Done\n", __PRETTY_FUNCTION__));
636 #endif
638 else
640 #if defined(DEBUG_ILC_ICONRENDERING)
641 D(bug("[IconList] %s: DrawIconState('%s') NEEDS CLIPPED!\n", __PRETTY_FUNCTION__, message->icon->ie_IconListEntry.label));
642 #endif
645 return TRUE;
649 ///IconList__LabelFunc_SplitLabel()
650 void IconList__LabelFunc_SplitLabel(Object *obj, struct IconList_DATA *data, struct IconEntry *icon)
652 ULONG labelSplit_MaxLabelLineLength = data->icld__Option_LabelTextMaxLen;
653 ULONG labelSplit_LabelLength = strlen(icon->ie_IconListEntry.label);
654 ULONG txwidth;
655 // ULONG labelSplit_FontY = data->icld_IconLabelFont->tf_YSize;
656 int labelSplit_CharsDone, labelSplit_CharsSplit;
657 ULONG labelSplit_CurSplitWidth;
659 if ((data->icld__Option_TrimVolumeNames) &&
660 ((icon->ie_IconListEntry.type == ST_ROOT) && (icon->ie_IconListEntry.label[labelSplit_LabelLength - 1] == ':')))
661 labelSplit_LabelLength--;
663 if (labelSplit_MaxLabelLineLength >= labelSplit_LabelLength)
665 #if defined(DEBUG_ILC_ICONRENDERING)
666 D(bug("[IconList]: %s: Label'%s' doesnt need split (onyl %d chars)\n", __PRETTY_FUNCTION__, icon->ie_IconListEntry.label, labelSplit_LabelLength));
667 #endif
668 return;
671 SetFont(data->icld_BufferRastPort, data->icld_IconLabelFont);
672 txwidth = TextLength(data->icld_BufferRastPort, icon->ie_IconListEntry.label, labelSplit_MaxLabelLineLength);
673 #if defined(DEBUG_ILC_ICONRENDERING)
674 D(bug("[IconList]: %s: txwidth = %d\n", __PRETTY_FUNCTION__, txwidth));
675 #endif
676 icon->ie_TxtBuf_DisplayedLabel = AllocVecPooled(data->icld_Pool, 256);
677 memset(icon->ie_TxtBuf_DisplayedLabel, 0, 256);
678 icon->ie_SplitParts = 0;
680 labelSplit_CharsDone = 0;
681 labelSplit_CharsSplit = 0;
683 while (labelSplit_CharsDone < labelSplit_LabelLength)
685 ULONG labelSplit_CurSplitLength = labelSplit_LabelLength - labelSplit_CharsDone;
686 IPTR labelSplit_SplitStart = (IPTR)(icon->ie_IconListEntry.label + labelSplit_CharsDone);
687 int tmp_checkoffs = 0;
688 IPTR labelSplit_RemainingCharsAfterSplit;
689 IPTR labelSplit_CurSplitDest;
691 while (*(char *)(labelSplit_SplitStart) == ' ')
693 //Skip preceding spaces..
694 labelSplit_SplitStart = labelSplit_SplitStart + 1;
695 labelSplit_CurSplitLength = labelSplit_CurSplitLength - 1;
696 labelSplit_CharsDone = labelSplit_CharsDone + 1;
699 while(TextLength(data->icld_BufferRastPort, (char *)labelSplit_SplitStart, labelSplit_CurSplitLength) < txwidth) labelSplit_CurSplitLength++;
700 while(TextLength(data->icld_BufferRastPort, (char *)labelSplit_SplitStart, labelSplit_CurSplitLength) > txwidth) labelSplit_CurSplitLength--;
701 #if defined(DEBUG_ILC_ICONRENDERING)
702 D(bug("[IconList]: %s: labelSplit_CurSplitLength = %d\n", __PRETTY_FUNCTION__, labelSplit_CurSplitLength));
703 #endif
705 #if defined(DEBUG_ILC_ICONRENDERING)
706 D(bug("[IconList]: %s: Attempting to find neat split ", __PRETTY_FUNCTION__));
707 #endif
708 while(tmp_checkoffs < (labelSplit_CurSplitLength - ILC_ICONLABEL_SHORTEST))
710 #if defined(DEBUG_ILC_ICONRENDERING)
711 D(bug("%d", tmp_checkoffs));
712 #endif
713 labelSplit_RemainingCharsAfterSplit = labelSplit_LabelLength - (labelSplit_CharsDone + labelSplit_CurSplitLength);
715 if ((labelSplit_CurSplitLength - tmp_checkoffs) > ILC_ICONLABEL_SHORTEST)
717 #if defined(DEBUG_ILC_ICONRENDERING)
718 D(bug("<"));
719 #endif
720 if ((*(char *)(labelSplit_SplitStart + labelSplit_CurSplitLength - tmp_checkoffs) == ' ') ||
721 (*(char *)(labelSplit_SplitStart + labelSplit_CurSplitLength - tmp_checkoffs) == '.') ||
722 (*(char *)(labelSplit_SplitStart + labelSplit_CurSplitLength - tmp_checkoffs) == '-'))
724 #if defined(DEBUG_ILC_ICONRENDERING)
725 D(bug("!"));
726 #endif
727 labelSplit_CurSplitLength = labelSplit_CurSplitLength - tmp_checkoffs;
728 labelSplit_RemainingCharsAfterSplit = labelSplit_RemainingCharsAfterSplit - tmp_checkoffs;
729 tmp_checkoffs = 0;
730 break;
734 if ((labelSplit_RemainingCharsAfterSplit - tmp_checkoffs) < 0)
736 #if defined(DEBUG_ILC_ICONRENDERING)
737 D(bug("="));
738 #endif
739 labelSplit_CurSplitLength = labelSplit_CurSplitLength + tmp_checkoffs;
740 labelSplit_RemainingCharsAfterSplit = labelSplit_RemainingCharsAfterSplit + tmp_checkoffs;
741 tmp_checkoffs = 0;
742 break;
745 if ((labelSplit_RemainingCharsAfterSplit - tmp_checkoffs) >= ILC_ICONLABEL_SHORTEST)
747 #if defined(DEBUG_ILC_ICONRENDERING)
748 D(bug(">"));
749 #endif
750 if ((*(char *)(labelSplit_SplitStart + labelSplit_CurSplitLength + tmp_checkoffs) == ' ') ||
751 (*(char *)(labelSplit_SplitStart + labelSplit_CurSplitLength + tmp_checkoffs) == '.') ||
752 (*(char *)(labelSplit_SplitStart + labelSplit_CurSplitLength + tmp_checkoffs) == '-'))
754 #if defined(DEBUG_ILC_ICONRENDERING)
755 D(bug("!"));
756 #endif
757 labelSplit_CurSplitLength = labelSplit_CurSplitLength + tmp_checkoffs;
758 labelSplit_RemainingCharsAfterSplit = labelSplit_RemainingCharsAfterSplit + tmp_checkoffs;
759 tmp_checkoffs = 0;
760 break;
764 tmp_checkoffs = tmp_checkoffs + 1;
766 #if defined(DEBUG_ILC_ICONRENDERING)
767 D(bug("\n"));
768 #endif
769 if (tmp_checkoffs != 0)
771 #if defined(DEBUG_ILC_ICONRENDERING)
772 D(bug("[IconList]: %s: Couldnt find neat split : Still %d chars\n", __PRETTY_FUNCTION__, labelSplit_RemainingCharsAfterSplit));
773 #endif
774 if (labelSplit_RemainingCharsAfterSplit <= ILC_ICONLABEL_SHORTEST)
776 labelSplit_CurSplitLength = labelSplit_CurSplitLength + (labelSplit_RemainingCharsAfterSplit - ILC_ICONLABEL_SHORTEST);
779 if ((labelSplit_CharsDone + labelSplit_CurSplitLength) > labelSplit_LabelLength) labelSplit_CurSplitLength = labelSplit_LabelLength - labelSplit_CharsDone;
781 labelSplit_CurSplitDest = (IPTR)(icon->ie_TxtBuf_DisplayedLabel + labelSplit_CharsSplit + icon->ie_SplitParts);
783 strncpy((char *)labelSplit_CurSplitDest, (char *)labelSplit_SplitStart, labelSplit_CurSplitLength);
785 labelSplit_CurSplitWidth = TextLength(data->icld_BufferRastPort, (char *)labelSplit_CurSplitDest, labelSplit_CurSplitLength);
787 icon->ie_SplitParts = icon->ie_SplitParts + 1;
789 labelSplit_CharsDone = labelSplit_CharsDone + labelSplit_CurSplitLength;
790 labelSplit_CharsSplit = labelSplit_CharsSplit + labelSplit_CurSplitLength;
792 if (labelSplit_CurSplitWidth > icon->ie_TxtBuf_DisplayedLabelWidth) icon->ie_TxtBuf_DisplayedLabelWidth = labelSplit_CurSplitWidth;
794 if ((icon->ie_SplitParts <= 1) && icon->ie_TxtBuf_DisplayedLabel)
796 FreeVecPooled(data->icld_Pool, icon->ie_TxtBuf_DisplayedLabel);
797 icon->ie_TxtBuf_DisplayedLabel = NULL;
798 icon->ie_SplitParts = 0;
800 // if ((labelSplit_FontY * icon->ie_SplitParts) > data->icld_LabelLargestHeight) data->icld_LabelLargestHeight = (labelSplit_FontY * icon->ie_SplitParts);
804 ///IconList__LabelFunc_CreateLabel()
805 IPTR IconList__LabelFunc_CreateLabel(Object *obj, struct IconList_DATA *data, struct IconEntry *icon)
807 #if defined(DEBUG_ILC_ICONRENDERING) && defined(DEBUG_ILC_FUNCS)
808 D(bug("[IconList]: %s('%s')\n", __PRETTY_FUNCTION__, icon->ie_IconListEntry.label));
809 #endif
810 if (icon->ie_TxtBuf_DisplayedLabel)
812 FreeVecPooled(data->icld_Pool, icon->ie_TxtBuf_DisplayedLabel);
813 icon->ie_TxtBuf_DisplayedLabel = NULL;
814 icon->ie_SplitParts = 0;
817 if (data->icld__Option_LabelTextMultiLine > 1)
819 #if defined(DEBUG_ILC_ICONRENDERING)
820 D(bug("[IconList]: %s: Attempting to split label ..\n", __PRETTY_FUNCTION__));
821 #endif
822 IconList__LabelFunc_SplitLabel(obj, data, icon);
825 if (icon->ie_TxtBuf_DisplayedLabel == NULL)
827 ULONG ie_LabelLength = strlen(icon->ie_IconListEntry.label);
828 icon->ie_SplitParts = 1;
830 #if defined(DEBUG_ILC_ICONRENDERING)
831 D(bug("[IconList]: %s: Building unsplit label (len = %d) ..\n", __PRETTY_FUNCTION__, ie_LabelLength));
832 #endif
834 if ((data->icld__Option_TrimVolumeNames) &&
835 ((icon->ie_IconListEntry.type == ST_ROOT) && (icon->ie_IconListEntry.label[ie_LabelLength - 1] == ':')))
836 ie_LabelLength--;
838 if(ie_LabelLength > data->icld__Option_LabelTextMaxLen)
840 if (!(icon->ie_TxtBuf_DisplayedLabel = AllocVecPooled(data->icld_Pool, data->icld__Option_LabelTextMaxLen + 1)))
842 return (IPTR)NULL;
844 memset(icon->ie_TxtBuf_DisplayedLabel, 0, data->icld__Option_LabelTextMaxLen + 1);
845 strncpy(icon->ie_TxtBuf_DisplayedLabel, icon->ie_IconListEntry.label, data->icld__Option_LabelTextMaxLen - 3);
846 strcat(icon->ie_TxtBuf_DisplayedLabel , " ..");
848 else
850 if (!(icon->ie_TxtBuf_DisplayedLabel = AllocVecPooled(data->icld_Pool, ie_LabelLength + 1)))
852 return (IPTR)NULL;
854 memset(icon->ie_TxtBuf_DisplayedLabel, 0, ie_LabelLength + 1);
855 strncpy(icon->ie_TxtBuf_DisplayedLabel, icon->ie_IconListEntry.label, ie_LabelLength );
857 icon->ie_TxtBuf_DisplayedLabelWidth = TextLength(data->icld_BufferRastPort, icon->ie_TxtBuf_DisplayedLabel, strlen(icon->ie_TxtBuf_DisplayedLabel));
858 // if ((data->icld_IconLabelFont->tf_YSize) > data->icld_LabelLargestHeight) data->icld_LabelLargestHeight = data->icld_IconLabelFont->tf_YSize;
861 // if (icon->ie_TxtBuf_DisplayedLabelWidth > data->icld_LabelLargestWidth) data->icld_LabelLargestWidth = icon->ie_TxtBuf_DisplayedLabelWidth;
863 return (IPTR)icon->ie_TxtBuf_DisplayedLabel;
867 ///IconList__HookFunc_UpdateLabelsFunc()
868 AROS_UFH3(
869 void, IconList__HookFunc_UpdateLabelsFunc,
870 AROS_UFHA(struct Hook *, hook, A0),
871 AROS_UFHA(APTR *, obj, A2),
872 AROS_UFHA(APTR, param, A1)
875 AROS_USERFUNC_INIT
877 /* Get our private data */
878 Class *CLASS = *( Class **)param;
880 struct IconList_DATA *data = INST_DATA(CLASS, obj);
882 #if defined(DEBUG_ILC_LASSO) && defined(DEBUG_ILC_FUNCS)
883 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
884 #endif
886 if (((data->icld__Option_LabelTextMaxLen != data->icld__Option_LastLabelTextMaxLen) &&
887 (data->icld__Option_LabelTextMultiLine > 1)) ||
888 (data->icld__Option_LabelTextMultiLine != data->icld__Option_LastLabelTextMultiLine));
890 struct IconEntry *iconentry_Current = NULL;
891 #ifdef __AROS__
892 ForeachNode(&data->icld_IconList, iconentry_Current)
893 #else
894 Foreach_Node(&data->icld_IconList, iconentry_Current);
895 #endif
897 IconList__LabelFunc_CreateLabel((Object *)obj, data, iconentry_Current);
901 data->icld__Option_LastLabelTextMaxLen = data->icld__Option_LabelTextMaxLen;
902 data->icld__Option_LastLabelTextMultiLine = data->icld__Option_LabelTextMultiLine;
904 AROS_USERFUNC_EXIT
908 ///IconList__MUIM_IconList_DrawEntryLabel()
909 IPTR IconList__MUIM_IconList_DrawEntryLabel(struct IClass *CLASS, Object *obj, struct MUIP_IconList_DrawEntry *message)
911 struct IconList_DATA *data = INST_DATA(CLASS, obj);
913 STRPTR buf = NULL;
914 BOOL outside = FALSE;
916 struct Rectangle iconlabelrect;
917 struct Rectangle objrect;
919 ULONG txtbox_width = 0;
920 LONG tx,ty,offsetx,offsety;
921 LONG txwidth; // txheight;
923 ULONG objX, objY, objW, objH;
924 LONG labelX, labelY;
925 ULONG labelW, labelH;
927 if (data->icld_BufferRastPort == data->icld_DisplayRastPort)
929 objX = _mleft(obj);
930 objY = _mtop(obj);
932 else
934 objX = objY = 0;
936 objW = _mright(obj) - _mleft(obj) + 1;
937 objH = _mbottom(obj) - _mtop(obj) + 1;
939 ULONG txtarea_width;
940 ULONG curlabel_TotalLines, curlabel_CurrentLine, offset_y;
942 #if defined(DEBUG_ILC_ICONRENDERING) && defined(DEBUG_ILC_FUNCS)
943 D(bug("[IconList]: %s(message->icon = 0x%p), '%s'\n", __PRETTY_FUNCTION__, message->icon, message->icon->ie_IconListEntry.label));
944 #endif
946 if ((!(message->icon->ie_Flags & ICONENTRY_FLAG_VISIBLE)) ||
947 (data->icld_BufferRastPort == NULL) ||
948 (!(message->icon->ie_DiskObj)))
950 #if defined(DEBUG_ILC_ICONRENDERING)
951 D(bug("[IconList] %s: Not visible or missing DOB\n", __PRETTY_FUNCTION__));
952 #endif
953 return FALSE;
956 /* Get the dimensions and affected area of message->icon's label */
957 IconList_GetIconLabelRectangle(obj, data, message->icon, &iconlabelrect);
958 labelW = iconlabelrect.MaxX - iconlabelrect.MinX + 1;
959 labelH = iconlabelrect.MaxY - iconlabelrect.MinY + 1;
961 /* Add the relative position offset of the message->icon's label */
962 offsetx = (objX - data->icld_ViewX) + message->icon->ie_IconX;
963 txtbox_width = (iconlabelrect.MaxX - iconlabelrect.MinX) + 1;
965 if (txtbox_width < message->icon->ie_AreaWidth)
966 offsetx += ((message->icon->ie_AreaWidth - txtbox_width)/2);
968 if ((data->icld__Option_IconListMode == ICON_LISTMODE_GRID) &&
969 (message->icon->ie_AreaWidth < data->icld_IconAreaLargestWidth))
970 offsetx += ((data->icld_IconAreaLargestWidth - message->icon->ie_AreaWidth)/2);
972 iconlabelrect.MinX += offsetx;
973 iconlabelrect.MaxX += offsetx;
975 offsety = (objY - data->icld_ViewY) + message->icon->ie_IconY + data->icld__Option_IconImageSpacing;
976 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
978 offsety = offsety + data->icld_IconLargestHeight;
980 else
982 offsety = offsety + message->icon->ie_IconHeight;
984 iconlabelrect.MinY += offsety;
985 iconlabelrect.MaxY += offsety;
987 /* Add the relative position of the window */
988 objrect.MinX = objX;
989 objrect.MinY = objX;
990 objrect.MaxX = objX + objW;
991 objrect.MaxY = objY + objH;
993 if (!RectAndRect(&iconlabelrect, &objrect))
995 #if defined(DEBUG_ILC_ICONRENDERING)
996 D(bug("[IconList] %s: Icon '%s' label outside of visible area .. skipping\n", __PRETTY_FUNCTION__, message->icon->ie_IconListEntry.label));
997 #endif
998 return FALSE;
1001 /* data->update_rect1 and data->update_rect2 may
1002 point to rectangles to indicate that only icons
1003 in any of this rectangles need to be drawn */
1004 if (data->update_rect1)
1006 if (!RectAndRect(&iconlabelrect, data->update_rect1)) outside = TRUE;
1009 if (data->update_rect2)
1011 if (data->update_rect1)
1013 if ((outside == TRUE) && RectAndRect(&iconlabelrect, data->update_rect2)) outside = FALSE;
1015 else
1017 if (!RectAndRect(&iconlabelrect, data->update_rect2)) outside = TRUE;
1021 if (outside == TRUE)
1023 #if defined(DEBUG_ILC_ICONRENDERING)
1024 D(bug("[IconList] %s: Icon '%s' label outside of update area .. skipping\n", __PRETTY_FUNCTION__, message->icon->ie_IconListEntry.label));
1025 #endif
1026 return FALSE;
1029 if (message->drawmode == ICONENTRY_DRAWMODE_NONE) return TRUE;
1031 SetABPenDrMd(data->icld_BufferRastPort, _pens(obj)[MPEN_TEXT], 0, JAM1);
1033 iconlabelrect.MinX = (iconlabelrect.MinX - objX) + data->icld_DrawOffsetX;
1034 iconlabelrect.MinY = (iconlabelrect.MinY - objY) + data->icld_DrawOffsetY;
1035 iconlabelrect.MaxX = (iconlabelrect.MaxX - objX) + data->icld_DrawOffsetX;
1036 iconlabelrect.MaxY = (iconlabelrect.MaxY - objY) + data->icld_DrawOffsetY;
1038 labelX = iconlabelrect.MinX + data->icld__Option_LabelTextBorderWidth + data->icld__Option_LabelTextHorizontalPadding;
1039 labelY = iconlabelrect.MinY + data->icld__Option_LabelTextBorderHeight + data->icld__Option_LabelTextVerticalPadding;
1041 txtarea_width = txtbox_width - ((data->icld__Option_LabelTextBorderWidth + data->icld__Option_LabelTextHorizontalPadding) * 2);
1043 if ((data->icld_BufferRastPort == data->icld_DisplayRastPort) ||
1044 ((data->icld_BufferRastPort != data->icld_DisplayRastPort) &&
1045 ((iconlabelrect.MinX > objX) && (iconlabelrect.MinX < (objX + objW)) && (iconlabelrect.MinY > objY) && (iconlabelrect.MinY < (objY + objH))) &&
1046 ((iconlabelrect.MaxX > objX) && (iconlabelrect.MaxX < (objX + objW)) && (iconlabelrect.MaxY > objY) && (iconlabelrect.MaxY < (objY + objH)))
1049 #if defined(DEBUG_ILC_ICONRENDERING)
1050 D(bug("[IconList] %s: Drawing Label '%s' .. %d, %d\n", __PRETTY_FUNCTION__, message->icon->ie_IconListEntry.label, labelX, labelY));
1051 #endif
1052 if (message->icon->ie_IconListEntry.label && message->icon->ie_TxtBuf_DisplayedLabel)
1054 char *curlabel_StrPtr;
1056 if ((message->icon->ie_Flags & ICONENTRY_FLAG_FOCUS) && ((BOOL)XGET(_win(obj), MUIA_Window_Activate)))
1058 //Draw the focus box around the selected label ..
1059 if (data->icld__Option_LabelTextBorderHeight > 0)
1061 InvertPixelArray(data->icld_BufferRastPort,
1062 iconlabelrect.MinX, iconlabelrect.MinY,
1063 (iconlabelrect.MaxX - iconlabelrect.MinX) + 1, data->icld__Option_LabelTextBorderHeight);
1065 InvertPixelArray(data->icld_BufferRastPort,
1066 iconlabelrect.MinX, iconlabelrect.MaxY - (data->icld__Option_LabelTextBorderHeight - 1),
1067 (iconlabelrect.MaxX - iconlabelrect.MinX) + 1, data->icld__Option_LabelTextBorderHeight);
1069 if (data->icld__Option_LabelTextBorderWidth > 0)
1071 InvertPixelArray(data->icld_BufferRastPort,
1072 iconlabelrect.MinX, iconlabelrect.MinY + data->icld__Option_LabelTextBorderHeight,
1073 data->icld__Option_LabelTextBorderWidth, (((iconlabelrect.MaxY - iconlabelrect.MinY) + 1) - (data->icld__Option_LabelTextBorderHeight * 2)));
1075 InvertPixelArray(data->icld_BufferRastPort,
1076 iconlabelrect.MaxX - (data->icld__Option_LabelTextBorderWidth - 1), iconlabelrect.MinY + data->icld__Option_LabelTextBorderHeight,
1077 data->icld__Option_LabelTextBorderWidth, (((iconlabelrect.MaxY - iconlabelrect.MinY) + 1) - (data->icld__Option_LabelTextBorderHeight * 2)));
1081 SetFont(data->icld_BufferRastPort, data->icld_IconLabelFont);
1083 curlabel_TotalLines = message->icon->ie_SplitParts;
1084 curlabel_CurrentLine = 0;
1086 if (curlabel_TotalLines == 0)
1087 curlabel_TotalLines = 1;
1089 if (!(data->icld__Option_LabelTextMultiLineOnFocus) || (data->icld__Option_LabelTextMultiLineOnFocus && (message->icon->ie_Flags & ICONENTRY_FLAG_FOCUS)))
1091 if (curlabel_TotalLines > data->icld__Option_LabelTextMultiLine)
1092 curlabel_TotalLines = data->icld__Option_LabelTextMultiLine;
1094 else
1095 curlabel_TotalLines = 1;
1097 curlabel_StrPtr = message->icon->ie_TxtBuf_DisplayedLabel;
1099 ty = labelY - 1;
1101 #if defined(DEBUG_ILC_ICONRENDERING)
1102 D(bug("[IconList] %s: Font YSize %d Baseline %d\n", __PRETTY_FUNCTION__,data->icld_IconLabelFont->tf_YSize, data->icld_IconLabelFont->tf_Baseline));
1103 #endif
1104 for (curlabel_CurrentLine = 0; curlabel_CurrentLine < curlabel_TotalLines; curlabel_CurrentLine++)
1106 ULONG ie_LabelLength;
1108 if (curlabel_CurrentLine > 0) curlabel_StrPtr = curlabel_StrPtr + strlen(curlabel_StrPtr) + 1;
1109 if ((curlabel_CurrentLine >= (curlabel_TotalLines -1)) && (curlabel_TotalLines < message->icon->ie_SplitParts))
1111 char *tmpLine = curlabel_StrPtr;
1112 ULONG tmpLen = strlen(tmpLine);
1114 if ((curlabel_StrPtr = AllocVecPooled(data->icld_Pool, tmpLen + 1)) != NULL)
1116 memset(curlabel_StrPtr, 0, tmpLen + 1);
1117 strncpy(curlabel_StrPtr, tmpLine, tmpLen - 3);
1118 strcat(curlabel_StrPtr , " ..");
1120 else return FALSE;
1124 ie_LabelLength = strlen(curlabel_StrPtr);
1125 offset_y = 0;
1127 // Center message->icon's label
1128 tx = (labelX + (message->icon->ie_TxtBuf_DisplayedLabelWidth / 2) - (TextLength(data->icld_BufferRastPort, curlabel_StrPtr, strlen(curlabel_StrPtr)) / 2));
1130 if (message->icon->ie_TxtBuf_DisplayedLabelWidth < txtarea_width)
1131 tx += ((txtarea_width - message->icon->ie_TxtBuf_DisplayedLabelWidth)/2);
1133 ty = ty + data->icld_IconLabelFont->tf_YSize;
1135 switch ( data->icld__Option_LabelTextMode )
1137 case ICON_TEXTMODE_DROPSHADOW:
1138 SetAPen(data->icld_BufferRastPort, data->icld_LabelShadowPen);
1139 Move(data->icld_BufferRastPort, tx + 1, ty + 1);
1140 Text(data->icld_BufferRastPort, curlabel_StrPtr, ie_LabelLength);
1141 offset_y = 1;
1142 case ICON_TEXTMODE_PLAIN:
1143 SetAPen(data->icld_BufferRastPort, data->icld_LabelPen);
1144 Move(data->icld_BufferRastPort, tx, ty);
1145 Text(data->icld_BufferRastPort, curlabel_StrPtr, ie_LabelLength);
1146 break;
1148 default:
1149 // Outline mode:
1151 SetSoftStyle(data->icld_BufferRastPort, FSF_BOLD, AskSoftStyle(data->icld_BufferRastPort));
1153 SetAPen(data->icld_BufferRastPort, data->icld_LabelShadowPen);
1154 Move(data->icld_BufferRastPort, tx + 1, ty );
1155 Text(data->icld_BufferRastPort, curlabel_StrPtr, ie_LabelLength);
1156 Move(data->icld_BufferRastPort, tx - 1, ty );
1157 Text(data->icld_BufferRastPort, curlabel_StrPtr, ie_LabelLength);
1158 Move(data->icld_BufferRastPort, tx, ty + 1);
1159 Text(data->icld_BufferRastPort, curlabel_StrPtr, ie_LabelLength);
1160 Move(data->icld_BufferRastPort, tx, ty - 1);
1161 Text(data->icld_BufferRastPort, curlabel_StrPtr, ie_LabelLength);
1163 SetAPen(data->icld_BufferRastPort, data->icld_LabelPen);
1164 Move(data->icld_BufferRastPort, tx , ty );
1165 Text(data->icld_BufferRastPort, curlabel_StrPtr, ie_LabelLength);
1167 SetSoftStyle(data->icld_BufferRastPort, FS_NORMAL, AskSoftStyle(data->icld_BufferRastPort));
1168 offset_y = 2;
1169 break;
1171 if ((curlabel_CurrentLine >= (curlabel_TotalLines -1)) && (curlabel_TotalLines < message->icon->ie_SplitParts))
1173 FreeVecPooled(data->icld_Pool, curlabel_StrPtr);
1175 ty = ty + offset_y;
1178 /*date/size sorting has the date/size appended under the message->icon label*/
1180 if ((message->icon->ie_IconListEntry.type != ST_USERDIR) && ((data->icld_SortFlags & (ICONLIST_SORT_BY_SIZE|ICONLIST_SORT_BY_DATE)) != 0))
1182 buf = NULL;
1183 SetFont(data->icld_BufferRastPort, data->icld_IconInfoFont);
1185 if ((data->icld_SortFlags & ICONLIST_SORT_MASK) == ICONLIST_SORT_BY_SIZE)
1187 buf = message->icon->ie_TxtBuf_SIZE;
1188 txwidth = message->icon->ie_TxtBuf_SIZEWidth;
1190 else if ((data->icld_SortFlags & ICONLIST_SORT_MASK) == ICONLIST_SORT_BY_DATE)
1192 if (message->icon->ie_Flags & ICONENTRY_FLAG_TODAY)
1194 buf = message->icon->ie_TxtBuf_TIME;
1195 txwidth = message->icon->ie_TxtBuf_TIMEWidth;
1197 else
1199 buf = message->icon->ie_TxtBuf_DATE;
1200 txwidth = message->icon->ie_TxtBuf_DATEWidth;
1204 if (buf)
1206 ULONG ie_LabelLength = strlen(buf);
1207 tx = labelX;
1209 if (txwidth < txtarea_width)
1210 tx += ((txtarea_width - txwidth)/2);
1212 ty = labelY + ((data->icld__Option_LabelTextVerticalPadding + data->icld_IconLabelFont->tf_YSize ) * curlabel_TotalLines) + data->icld_IconInfoFont->tf_YSize;
1214 switch ( data->icld__Option_LabelTextMode )
1216 case ICON_TEXTMODE_DROPSHADOW:
1217 SetAPen(data->icld_BufferRastPort, data->icld_InfoShadowPen);
1218 Move(data->icld_BufferRastPort, tx + 1, ty + 1); Text(data->icld_BufferRastPort, buf, ie_LabelLength);
1219 case ICON_TEXTMODE_PLAIN:
1220 SetAPen(data->icld_BufferRastPort, data->icld_InfoPen);
1221 Move(data->icld_BufferRastPort, tx, ty); Text(data->icld_BufferRastPort, buf, ie_LabelLength);
1222 break;
1224 default:
1225 // Outline mode..
1226 SetSoftStyle(data->icld_BufferRastPort, FSF_BOLD, AskSoftStyle(data->icld_BufferRastPort));
1227 SetAPen(data->icld_BufferRastPort, data->icld_InfoShadowPen);
1229 Move(data->icld_BufferRastPort, tx + 1, ty );
1230 Text(data->icld_BufferRastPort, buf, ie_LabelLength);
1231 Move(data->icld_BufferRastPort, tx - 1, ty );
1232 Text(data->icld_BufferRastPort, buf, ie_LabelLength);
1233 Move(data->icld_BufferRastPort, tx, ty - 1 );
1234 Text(data->icld_BufferRastPort, buf, ie_LabelLength);
1235 Move(data->icld_BufferRastPort, tx, ty + 1 );
1236 Text(data->icld_BufferRastPort, buf, ie_LabelLength);
1238 SetAPen(data->icld_BufferRastPort, data->icld_InfoPen);
1240 Move(data->icld_BufferRastPort, tx, ty );
1241 Text(data->icld_BufferRastPort, buf, ie_LabelLength);
1243 SetSoftStyle(data->icld_BufferRastPort, FS_NORMAL, AskSoftStyle(data->icld_BufferRastPort));
1244 break;
1251 return TRUE;
1254 /**************************************************************************
1256 **************************************************************************/
1257 ///IconList__MUIM_IconList_RethinkDimensions()
1258 IPTR IconList__MUIM_IconList_RethinkDimensions(struct IClass *CLASS, Object *obj, struct MUIP_IconList_RethinkDimensions *message)
1260 struct IconList_DATA *data = INST_DATA(CLASS, obj);
1262 struct IconEntry *icon = NULL;
1263 LONG maxx = 0,
1264 maxy = 0;
1265 struct Rectangle icon_rect;
1267 #if defined(DEBUG_ILC_ICONPOSITIONING) && defined(DEBUG_ILC_FUNCS)
1268 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
1269 #endif
1271 #warning "TODO: Handle MADF_SETUP"
1272 // if (!(_flags(obj) & MADF_SETUP)) return FALSE;
1274 if (message->singleicon != NULL)
1276 icon = message->singleicon;
1277 maxx = data->icld_AreaWidth - 1,
1278 maxy = data->icld_AreaHeight - 1;
1279 #if defined(DEBUG_ILC_ICONPOSITIONING)
1280 D(bug("[IconList] %s: SingleIcon - maxx = %d, maxy = %d\n", __PRETTY_FUNCTION__, maxx, maxy));
1281 #endif
1283 else icon = (struct IconEntry *)GetHead(&data->icld_IconList);
1285 while (icon != NULL)
1287 if (icon->ie_DiskObj &&
1288 (icon->ie_Flags & ICONENTRY_FLAG_VISIBLE) &&
1289 (icon->ie_IconX != NO_ICON_POSITION) &&
1290 (icon->ie_IconY != NO_ICON_POSITION))
1292 IconList_GetIconAreaRectangle(obj, data, icon, &icon_rect);
1294 icon_rect.MaxX += icon->ie_IconX + data->icld__Option_IconHorizontalSpacing;
1295 if ((data->icld__Option_IconListMode == ICON_LISTMODE_GRID) &&
1296 (icon->ie_AreaWidth < data->icld_IconAreaLargestWidth))
1297 icon_rect.MaxX += (data->icld_IconAreaLargestWidth - icon->ie_AreaWidth);
1299 icon_rect.MaxY += icon->ie_IconY + data->icld__Option_IconVerticalSpacing;
1301 if (icon_rect.MaxX > maxx) maxx = icon_rect.MaxX;
1302 if (icon_rect.MaxY > maxy) maxy = icon_rect.MaxY;
1305 if (message->singleicon) break;
1307 icon = (struct IconEntry *)GetSucc(&icon->ie_IconNode);
1310 /* update our view when max x/y have changed */
1311 if (maxx + 1 != data->icld_AreaWidth)
1313 data->icld_AreaWidth = maxx + 1;
1314 SET(obj, MUIA_IconList_Width, data->icld_AreaWidth);
1316 if (maxy + 1 != data->icld_AreaHeight)
1318 data->icld_AreaHeight = maxy + 1;
1319 SET(obj, MUIA_IconList_Height, data->icld_AreaHeight);
1322 return TRUE;
1325 /**************************************************************************
1326 Checks weather we can place an icon with the given dimesions at the
1327 suggested positions.
1329 atx and aty are absolute positions
1330 **************************************************************************/
1332 ///IconList_CouldPlaceIcon()
1333 static int IconList_CouldPlaceIcon(Object *obj, struct IconList_DATA *data, struct IconEntry *toplace, int atx, int aty)
1335 struct IconEntry *icon;
1336 struct Rectangle toplace_rect;
1338 IconList_GetIconAreaRectangle(obj, toplace, &toplace_rect);
1339 toplace_rect.MinX += atx;
1340 toplace_rect.MaxX += atx;
1341 toplace_rect.MinY += aty;
1342 toplace_rect.MaxY += aty;
1344 icon = GetHead(&data->icld_IconList);
1345 while (icon)
1347 if (icon->ie_DiskObj && icon->ie_IconX != NO_ICON_POSITION && icon->ie_IconY != NO_ICON_POSITION)
1349 struct Rectangle icon_rect;
1350 IconList_GetIconAreaRectangle(obj, icon, &icon_rect);
1351 icon_rect.MinX += icon->ie_IconX;
1352 icon_rect.MaxX += icon->ie_IconX;
1353 icon_rect.MinY += icon->ie_IconY;
1354 icon_rect.MaxY += icon->ie_IconY;
1356 if (RectAndRect(&icon_rect, &toplace_rect))
1357 return FALSE; *//* There is already an icon on this place *//*
1359 icon = GetSucc(icon);
1361 return 1;
1366 /**************************************************************************
1367 Place the icon at atx and aty.
1369 atx and aty are absolute positions
1370 **************************************************************************/
1372 ///IconList_PlaceIcon
1373 static void IconList_PlaceIcon(Object *obj, struct IconList_DATA *data, struct IconEntry *toplace, int atx, int aty)
1375 #if 0
1376 struct Rectangle toplace_rect;
1378 IconList_GetIconAreaRectangle(obj, toplace, &toplace_rect);
1379 toplace_rect.MinX += atx + data->icld_ViewX;
1380 toplace_rect.MaxX += atx + data->icld_ViewX;
1381 toplace_rect.MinY += aty + data->icld_ViewY;
1382 toplace_rect.MaxY += aty + data->icld_ViewY;
1383 #endif
1384 toplace->x = atx;
1385 toplace->y = aty;
1386 #if 0
1387 *//* update our view *//*
1388 if (toplace_rect.MaxX - data->icld_ViewX > data->icld_AreaWidth)
1390 data->icld_AreaWidth = toplace_rect.MaxX - data->icld_ViewX;
1391 SET(obj, MUIA_IconList_Width, data->icld_AreaWidth);
1394 if (toplace_rect.MaxY - data->icld_ViewY > data->icld_AreaHeight)
1396 data->icld_AreaHeight = toplace_rect.MaxY - data->icld_ViewY;
1397 SET(obj, MUIA_IconList_Height, data->icld_AreaHeight);
1399 #endif
1404 ///IconList__MUIM_IconList_PositionIcons()
1405 /**************************************************************************
1406 MUIM_PositionIcons - Place icons with NO_ICON_POSITION coords somewhere
1407 **************************************************************************/
1409 IPTR IconList__MUIM_IconList_PositionIcons(struct IClass *CLASS, Object *obj, struct MUIP_IconList_PositionIcons *message)
1411 struct IconList_DATA *data = INST_DATA(CLASS, obj);
1412 struct IconEntry *icon = NULL, *pass_first = NULL;
1414 int left = data->icld__Option_IconHorizontalSpacing;
1415 int top = data->icld__Option_IconVerticalSpacing;
1416 int cur_x = left;
1417 int cur_y = top;
1418 int gridx = 0;
1419 int gridy = 0;
1420 int maxw = 0; // Widest & Talest icon in a column or row.
1421 int maxh = 0;
1423 BOOL next;
1424 struct Rectangle iconrect;
1426 #if defined(DEBUG_ILC_ICONPOSITIONING) && defined(DEBUG_ILC_FUNCS)
1427 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
1428 #endif
1430 // Now go to the actual positioning
1431 icon = (struct IconEntry *)GetHead(&data->icld_IconList);
1432 while (icon != NULL)
1434 next = FALSE;
1435 if ((icon->ie_DiskObj != NULL) && (icon->ie_Flags & ICONENTRY_FLAG_VISIBLE))
1437 next = TRUE;
1438 icon->ie_IconX = cur_x;
1439 icon->ie_IconY = cur_y;
1441 if (icon->ie_Flags & ICONENTRY_FLAG_SELECTED)
1443 if (data->icld_SelectionLastClicked == NULL) data->icld_SelectionLastClicked = icon;
1444 if (data->icld_FocusIcon == NULL) data->icld_FocusIcon = icon;
1447 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
1449 maxw = data->icld_IconAreaLargestWidth + data->icld__Option_IconHorizontalSpacing;
1450 maxh = data->icld_IconLargestHeight + data->icld__Option_IconImageSpacing + data->icld_LabelLargestHeight + data->icld__Option_IconVerticalSpacing;
1451 gridx = maxw;
1452 gridy = maxh;
1454 else
1456 if (!(pass_first)) pass_first = icon;
1458 IconList_GetIconAreaRectangle(obj, data, icon, &iconrect);
1460 if (icon->ie_AreaWidth < maxw)
1461 icon->ie_IconX += ( maxw - icon->ie_AreaWidth ) / 2;
1463 if ((maxw < icon->ie_AreaWidth) || (maxh < icon->ie_AreaHeight))
1465 if (maxw < icon->ie_AreaWidth) maxw = icon->ie_AreaWidth;
1466 if (maxh < icon->ie_AreaHeight) maxh = icon->ie_AreaHeight;
1467 if (pass_first != icon)
1469 icon = pass_first;
1470 cur_x = icon->ie_IconX;
1471 cur_y = icon->ie_IconY;
1472 continue;
1476 if (data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL)
1478 gridx = maxw;
1479 gridy = icon->ie_AreaHeight + data->icld__Option_IconHorizontalSpacing;
1481 else
1483 gridx = icon->ie_AreaWidth + data->icld__Option_IconVerticalSpacing;
1484 gridy = maxh;
1488 if ((icon = (struct IconEntry *)GetSucc(&icon->ie_IconNode)) != NULL)
1490 if (next == TRUE)
1492 if (data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL)
1494 cur_y += gridy;
1496 if ((cur_y >= data->icld_ViewHeight) ||
1497 ((data->icld__Option_IconListMode == ICON_LISTMODE_ROUGH) && ((cur_y + icon->ie_AreaHeight - data->icld__Option_IconBorderOverlap) >= data->icld_ViewHeight)) ||
1498 ((data->icld__Option_IconListMode == ICON_LISTMODE_GRID) && ((cur_y + data->icld_IconAreaLargestHeight - data->icld__Option_IconBorderOverlap) >= data->icld_ViewHeight)))
1500 cur_x += maxw;
1501 cur_y = top;
1502 pass_first = NULL;
1503 maxw = 0;
1506 else
1508 cur_x += gridx;
1510 if ((cur_x >= data->icld_ViewWidth) ||
1511 ((data->icld__Option_IconListMode == ICON_LISTMODE_ROUGH) && ((cur_x + icon->ie_AreaWidth - data->icld__Option_IconBorderOverlap) >= data->icld_ViewWidth)) ||
1512 ((data->icld__Option_IconListMode == ICON_LISTMODE_GRID) && ((cur_x + data->icld_IconAreaLargestWidth - data->icld__Option_IconBorderOverlap) >= data->icld_ViewWidth)))
1514 cur_x = left;
1515 cur_y += maxh;
1516 pass_first = NULL;
1517 maxh = 0;
1519 else if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
1527 DoMethod(obj, MUIM_IconList_RethinkDimensions, NULL);
1528 return 0;
1533 ///IconList_FixNoPositionIcons
1534 static void IconList_FixNoPositionIcons(Object *obj, struct IconList_DATA *data)
1536 struct IconEntry *icon;
1537 int cur_x = data->icld_ViewX + 36;
1538 int cur_y = data->icld_ViewY + 4;
1540 icon = GetHead(&data->icld_IconList);
1541 while (icon)
1543 if (icon->ie_DiskObj && icon->ie_IconX == NO_ICON_POSITION && icon->ie_IconY == NO_ICON_POSITION)
1545 int loops = 0;
1546 int cur_x_save = cur_x;
1547 int cur_y_save = cur_y;
1548 struct Rectangle icon_rect;
1550 IconList_GetIconAreaRectangle(obj, icon, &icon_rect);
1551 icon_rect.MinX += cur_x - icon->ie_IconWidth/2 + data->icld_ViewX;
1552 if (icon_rect.MinX < 0)
1553 cur_x -= icon_rect.MinX;
1555 while (!IconList_CouldPlaceIcon(obj, data, icon, cur_x - icon->ie_IconWidth/2, cur_y) && loops < 5000)
1557 cur_y++;
1559 if (cur_y + icon->ie_IconHeight > data->icld_ViewX + data->icld_ViewHeight) *//* on both sides -1 *//*
1561 cur_x += 72;
1562 cur_y = data->icld_ViewY + 4;
1566 IconList_PlaceIcon(obj, data, icon, cur_x - icon->ie_IconWidth/2, cur_y);
1568 if (icon_rect.MinX < 0)
1570 cur_x = cur_x_save;
1571 cur_y = cur_y_save;
1574 icon = GetSucc(icon);
1577 DoMethod(obj, MUIM_IconList_RethinkDimensions, NULL);
1582 ///OM_NEW()
1583 /**************************************************************************
1584 OM_NEW
1585 **************************************************************************/
1586 IPTR IconList__OM_NEW(struct IClass *CLASS, Object *obj, struct opSet *message)
1588 struct IconList_DATA *data = NULL;
1589 struct TextFont *icl_WindowFont = NULL;
1590 // struct RastPort *icl_RastPort = NULL;
1592 #if defined(DEBUG_ILC_FUNCS)
1593 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
1594 #endif
1596 icl_WindowFont = (struct TextFont *) GetTagData(MUIA_Font, (IPTR) NULL, message->ops_AttrList);
1598 obj = (Object *)DoSuperNewTags(CLASS, obj, NULL,
1599 MUIA_FillArea, FALSE,
1600 MUIA_Dropable, TRUE,
1601 MUIA_Font, MUIV_Font_Tiny,
1602 TAG_MORE, (IPTR) message->ops_AttrList);
1604 if (!obj) return FALSE;
1606 data = INST_DATA(CLASS, obj);
1608 data->icld_Pool = CreatePool(0,4096,4096);
1609 if (!data->icld_Pool)
1611 CoerceMethod(CLASS,obj,OM_DISPOSE);
1612 return (IPTR)NULL;
1615 #if defined(DEBUG_ILC_FUNCS)
1616 D(bug("[IconList] %s: SELF = 0x%p, muiRenderInfo = 0x%p\n", __PRETTY_FUNCTION__, obj, muiRenderInfo(obj)));
1617 #endif
1618 NewList((struct List*)&data->icld_IconList);
1619 NewList((struct List*)&data->icld_SelectionList);
1620 data->icld_IconLabelFont = icl_WindowFont;
1622 /* Get/Set initial values */
1623 #warning "TODO: TrimVolumeNames should be prefs settable"
1624 data->icld__Option_TrimVolumeNames = TRUE;
1625 #warning "TODO: Adjust overlap by window border width"
1626 data->icld__Option_IconBorderOverlap = 10;
1628 data->icld__Option_IconListMode = (UBYTE)GetTagData(MUIA_IconList_IconListMode, 0, message->ops_AttrList);
1629 data->icld__Option_LabelTextMode = (UBYTE)GetTagData(MUIA_IconList_LabelText_Mode, 0, message->ops_AttrList);
1630 data->icld__Option_LabelTextMaxLen = (ULONG)GetTagData(MUIA_IconList_LabelText_MaxLineLen, ILC_ICONLABEL_MAXLINELEN_DEFAULT, message->ops_AttrList);
1632 if ( data->icld__Option_LabelTextMaxLen < ILC_ICONLABEL_SHORTEST )
1633 data->icld__Option_LabelTextMaxLen = ILC_ICONLABEL_MAXLINELEN_DEFAULT;
1635 data->icld__Option_LastLabelTextMaxLen = data->icld__Option_LabelTextMaxLen;
1637 #if defined(DEBUG_ILC_FUNCS)
1638 D(bug("[IconList] %s: MaxLineLen : %ld\n", __PRETTY_FUNCTION__, data->icld__Option_LabelTextMaxLen));
1639 #endif
1640 data->ehn.ehn_Events = IDCMP_MOUSEBUTTONS | IDCMP_RAWKEY;
1641 data->ehn.ehn_Priority = 0;
1642 data->ehn.ehn_Flags = 0;
1643 data->ehn.ehn_Object = obj;
1644 data->ehn.ehn_Class = CLASS;
1646 data->icld_SortFlags = ICONLIST_SORT_BY_NAME;
1647 data->icld_DisplayFlags = ICONLIST_DISP_SHOWINFO;
1649 __iconlist_UpdateLabels_hook.h_Entry = (HOOKFUNC)IconList__HookFunc_UpdateLabelsFunc;
1651 DoMethod
1653 obj, MUIM_Notify, MUIA_IconList_LabelText_MaxLineLen, MUIV_EveryTime,
1654 (IPTR)obj, 3,
1655 MUIM_CallHook, &__iconlist_UpdateLabels_hook, (IPTR)CLASS
1658 DoMethod
1660 obj, MUIM_Notify, MUIA_IconList_LabelText_MultiLine, MUIV_EveryTime,
1661 (IPTR)obj, 3,
1662 MUIM_CallHook, &__iconlist_UpdateLabels_hook, (IPTR)CLASS
1665 #if defined(DEBUG_ILC_FUNCS)
1666 D(bug("[IconList] obj = %ld\n", obj));
1667 #endif
1668 return (IPTR)obj;
1672 ///OM_DISPOSE()
1673 /**************************************************************************
1674 OM_DISPOSE
1675 **************************************************************************/
1676 IPTR IconList__OM_DISPOSE(struct IClass *CLASS, Object *obj, Msg message)
1678 struct IconList_DATA *data = INST_DATA(CLASS, obj);
1679 struct IconEntry *node = NULL;
1681 #if defined(DEBUG_ILC_FUNCS)
1682 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
1683 #endif
1685 #ifdef __AROS__
1686 ForeachNode(&data->icld_IconList, node)
1687 #else
1688 Foreach_Node(&data->icld_IconList, node);
1689 #endif
1691 if (node->ie_DiskObj) FreeDiskObject(node->ie_DiskObj);
1694 if (data->icld_Pool) DeletePool(data->icld_Pool);
1696 DoSuperMethodA(CLASS,obj,message);
1697 return 0;
1701 ///OM_SET()
1702 /**************************************************************************
1703 OM_SET
1704 **************************************************************************/
1705 IPTR IconList__OM_SET(struct IClass *CLASS, Object *obj, struct opSet *message)
1707 struct IconList_DATA *data = INST_DATA(CLASS, obj);
1708 struct TagItem *tag = NULL,
1709 *tags = NULL;
1711 WORD oldleft = data->icld_ViewX,
1712 oldtop = data->icld_ViewY;
1713 //oldwidth = data->icld_ViewWidth,
1714 //oldheight = data->icld_ViewHeight;
1716 #if defined(DEBUG_ILC_FUNCS) && defined(DEBUG_ILC_ATTRIBS)
1717 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
1718 #endif
1720 /* parse initial taglist */
1721 for (tags = message->ops_AttrList; (tag = NextTagItem((TAGITEM)&tags)); )
1723 switch (tag->ti_Tag)
1725 case MUIA_Virtgroup_Left:
1726 #if defined(DEBUG_ILC_ATTRIBS)
1727 D(bug("[IconList] %s: MUIA_Virtgroup_Left %ld\n", __PRETTY_FUNCTION__, tag->ti_Data));
1728 #endif
1729 if (data->icld_ViewX != tag->ti_Data)
1730 data->icld_ViewX = tag->ti_Data;
1731 break;
1733 case MUIA_Virtgroup_Top:
1734 #if defined(DEBUG_ILC_ATTRIBS)
1735 D(bug("[IconList] %s: MUIA_Virtgroup_Top %ld\n", __PRETTY_FUNCTION__, tag->ti_Data));
1736 #endif
1737 if (data->icld_ViewY != tag->ti_Data)
1738 data->icld_ViewY = tag->ti_Data;
1739 break;
1741 case MUIA_IconList_Rastport:
1742 #if defined(DEBUG_ILC_ATTRIBS)
1743 D(bug("[IconList] %s: MUIA_IconList_Rastport 0x%p\n", __PRETTY_FUNCTION__, tag->ti_Data));
1744 #endif
1745 data->icld_DisplayRastPort = (struct RastPort*)tag->ti_Data;
1746 data->icld_DrawOffsetX = _mleft(obj);
1747 data->icld_DrawOffsetY = _mtop(obj);
1748 if (data->icld_BufferRastPort != NULL)
1750 //Buffer still set!?!?!
1752 SET(obj, MUIA_IconList_BufferRastport, tag->ti_Data);
1753 break;
1755 case MUIA_IconList_BufferRastport:
1756 #if defined(DEBUG_ILC_ATTRIBS)
1757 D(bug("[IconList] %s: MUIA_IconList_BufferRastport 0x%p\n", __PRETTY_FUNCTION__, tag->ti_Data));
1758 #endif
1759 data->icld_BufferRastPort = (struct RastPort*)tag->ti_Data;
1760 break;
1762 case MUIA_Font:
1763 #if defined(DEBUG_ILC_ATTRIBS)
1764 D(bug("[IconList] %s: MUIA_Font 0x%p\n", __PRETTY_FUNCTION__, tag->ti_Data));
1765 #endif
1766 data->icld_IconLabelFont = (struct TextFont*)tag->ti_Data;
1767 break;
1769 case MUIA_IconList_LabelInfoText_Font:
1770 #if defined(DEBUG_ILC_ATTRIBS)
1771 D(bug("[IconList] %s: MUIA_IconList_LabelInfoText_Font 0x%p\n", __PRETTY_FUNCTION__, tag->ti_Data));
1772 #endif
1773 data->icld_IconInfoFont = (struct TextFont*)tag->ti_Data;
1774 break;
1776 case MUIA_IconList_DisplayFlags:
1778 #if defined(DEBUG_ILC_ATTRIBS)
1779 D(bug("[IconList] %s: MUIA_IconList_DisplayFlags %08x\n", __PRETTY_FUNCTION__, tag->ti_Data));
1780 #endif
1781 data->icld_DisplayFlags = (ULONG)tag->ti_Data;
1783 if (data->icld_DisplayFlags & ICONLIST_DISP_BUFFERED)
1785 struct BitMap *tmp_BuffBitMap = NULL;
1786 ULONG tmp_RastDepth;
1788 #if defined(DEBUG_ILC_ATTRIBS) && defined(DEBUG_ILC_ICONRENDERING)
1789 D(bug("[IconList] %s: MUIA_IconList_DisplayFlags & ICONLIST_DISP_BUFFERED\n", __PRETTY_FUNCTION__));
1790 #endif
1791 if ((data->icld_BufferRastPort) && (data->icld_BufferRastPort != data->icld_DisplayRastPort))
1793 //Free up the buffers rastport and bitmap so we can replace them ..
1794 FreeBitMap(data->icld_BufferRastPort->BitMap);
1795 FreeRastPort(data->icld_BufferRastPort);
1796 SET(obj, MUIA_IconList_BufferRastport, NULL);
1798 tmp_RastDepth = GetCyberMapAttr(data->icld_DisplayRastPort->BitMap, CYBRMATTR_DEPTH);
1799 if ((tmp_BuffBitMap = AllocBitMap(data->icld_ViewWidth,
1800 data->icld_ViewHeight,
1801 tmp_RastDepth,
1802 BMF_CLEAR,
1803 data->icld_DisplayRastPort->BitMap))!=NULL)
1805 if ((data->icld_BufferRastPort = CreateRastPort())!=NULL)
1807 data->icld_BufferRastPort->BitMap = tmp_BuffBitMap;
1808 SET(obj, MUIA_IconList_BufferRastport, data->icld_BufferRastPort);
1809 data->icld_DrawOffsetX = 0;
1810 data->icld_DrawOffsetY = 0;
1812 else
1814 FreeBitMap(tmp_BuffBitMap);
1815 data->icld_BufferRastPort = data->icld_DisplayRastPort;
1816 data->icld_DrawOffsetX = _mleft(obj);
1817 data->icld_DrawOffsetY = _mtop(obj);
1821 else
1823 if ((data->icld_BufferRastPort) && (data->icld_BufferRastPort != data->icld_DisplayRastPort))
1825 //Free up the buffers rastport and bitmap since they are no longer needed ..
1826 FreeBitMap(data->icld_BufferRastPort->BitMap);
1827 FreeRastPort(data->icld_BufferRastPort);
1828 data->icld_BufferRastPort = data->icld_DisplayRastPort;
1829 data->icld_DrawOffsetX = _mleft(obj);
1830 data->icld_DrawOffsetY = _mtop(obj);
1833 SET(obj, MUIA_IconList_Changed, TRUE);
1835 break;
1837 case MUIA_IconList_SortFlags:
1838 #if defined(DEBUG_ILC_ATTRIBS)
1839 bug("[IconList] %s: MUIA_IconList_SortFlags %08x\n", __PRETTY_FUNCTION__, tag->ti_Data);
1840 #endif
1841 data->icld_SortFlags = (ULONG)tag->ti_Data;
1842 break;
1844 case MUIA_IconList_IconListMode:
1845 #if defined(DEBUG_ILC_ATTRIBS)
1846 D(bug("[IconList] %s: MUIA_IconList_IconListMode %d\n", __PRETTY_FUNCTION__, tag->ti_Data));
1847 #endif
1848 data->icld__Option_IconListMode = (UBYTE)tag->ti_Data;
1849 break;
1851 case MUIA_IconList_LabelText_Mode:
1852 #if defined(DEBUG_ILC_ATTRIBS)
1853 D(bug("[IconList] %s: MUIA_IconList_LabelText_Mode %d\n", __PRETTY_FUNCTION__, tag->ti_Data));
1854 #endif
1855 data->icld__Option_LabelTextMode = (UBYTE)tag->ti_Data;
1856 break;
1858 case MUIA_IconList_LabelText_MaxLineLen:
1859 #if defined(DEBUG_ILC_ATTRIBS)
1860 D(bug("[IconList] %s: MUIA_IconList_LabelText_MaxLineLen %d\n", __PRETTY_FUNCTION__, tag->ti_Data));
1861 #endif
1862 if (tag->ti_Data >= ILC_ICONLABEL_SHORTEST)
1864 data->icld__Option_LabelTextMaxLen = (ULONG)tag->ti_Data;
1866 else
1868 data->icld__Option_LabelTextMaxLen = ILC_ICONLABEL_MAXLINELEN_DEFAULT;
1870 break;
1872 case MUIA_IconList_LabelText_MultiLine:
1873 #if defined(DEBUG_ILC_ATTRIBS)
1874 D(bug("[IconList] %s: MUIA_IconList_LabelText_MultiLine %d\n", __PRETTY_FUNCTION__, tag->ti_Data));
1875 #endif
1876 data->icld__Option_LabelTextMultiLine = (ULONG)tag->ti_Data;
1877 if (data->icld__Option_LabelTextMultiLine == 0)data->icld__Option_LabelTextMultiLine = 1;
1878 break;
1880 case MUIA_IconList_LabelText_MultiLineOnFocus:
1881 #if defined(DEBUG_ILC_ATTRIBS)
1882 D(bug("[IconList] %s: MUIA_IconList_LabelText_MultiLineOnFocus %d\n", __PRETTY_FUNCTION__, tag->ti_Data));
1883 #endif
1884 data->icld__Option_LabelTextMultiLineOnFocus = (BOOL)tag->ti_Data;
1885 break;
1887 case MUIA_IconList_Icon_HorizontalSpacing:
1888 #if defined(DEBUG_ILC_ATTRIBS)
1889 D(bug("[IconList] %s: MUIA_IconList_Icon_HorizontalSpacing %d\n", __PRETTY_FUNCTION__, tag->ti_Data));
1890 #endif
1891 data->icld__Option_IconHorizontalSpacing = (UBYTE)tag->ti_Data;
1892 break;
1894 case MUIA_IconList_Icon_VerticalSpacing:
1895 #if defined(DEBUG_ILC_ATTRIBS)
1896 D(bug("[IconList] %s: MUIA_IconList_Icon_VerticalSpacing %d\n", __PRETTY_FUNCTION__, tag->ti_Data));
1897 #endif
1898 data->icld__Option_IconVerticalSpacing = (UBYTE)tag->ti_Data;
1899 break;
1901 case MUIA_IconList_Icon_ImageSpacing:
1902 #if defined(DEBUG_ILC_ATTRIBS)
1903 D(bug("[IconList] %s: MUIA_IconList_Icon_ImageSpacing %d\n", __PRETTY_FUNCTION__, tag->ti_Data));
1904 #endif
1905 data->icld__Option_IconImageSpacing = (UBYTE)tag->ti_Data;
1906 break;
1908 case MUIA_IconList_LabelText_HorizontalPadding:
1909 #if defined(DEBUG_ILC_ATTRIBS)
1910 D(bug("[IconList] %s: MUIA_IconList_LabelText_HorizontalPadding %d\n", __PRETTY_FUNCTION__, tag->ti_Data));
1911 #endif
1912 data->icld__Option_LabelTextHorizontalPadding = (UBYTE)tag->ti_Data;
1913 break;
1915 case MUIA_IconList_LabelText_VerticalPadding:
1916 #if defined(DEBUG_ILC_ATTRIBS)
1917 D(bug("[IconList] %s: MUIA_IconList_LabelText_VerticalPadding %d\n", __PRETTY_FUNCTION__, tag->ti_Data));
1918 #endif
1919 data->icld__Option_LabelTextVerticalPadding = (UBYTE)tag->ti_Data;
1920 break;
1922 case MUIA_IconList_LabelText_BorderWidth:
1923 #if defined(DEBUG_ILC_ATTRIBS)
1924 D(bug("[IconList] %s: MUIA_IconList_LabelText_BorderWidth %d\n", __PRETTY_FUNCTION__, tag->ti_Data));
1925 #endif
1926 data->icld__Option_LabelTextBorderWidth = (UBYTE)tag->ti_Data;
1927 break;
1929 case MUIA_IconList_LabelText_BorderHeight:
1930 #if defined(DEBUG_ILC_ATTRIBS)
1931 D(bug("[IconList] %s: MUIA_IconList_LabelText_BorderHeight %d\n", __PRETTY_FUNCTION__, tag->ti_Data));
1932 #endif
1933 data->icld__Option_LabelTextBorderHeight = (UBYTE)tag->ti_Data;
1934 break;
1936 case MUIA_IconList_LabelText_Pen:
1937 data->icld_LabelPen = (ULONG)tag->ti_Data;
1938 break;
1940 case MUIA_IconList_LabelText_ShadowPen:
1941 data->icld_LabelShadowPen = (ULONG)tag->ti_Data;
1942 break;
1944 case MUIA_IconList_LabelInfoText_Pen:
1945 data->icld_InfoPen = (ULONG)tag->ti_Data;
1946 break;
1948 case MUIA_IconList_LabelInfoText_ShadowPen:
1949 data->icld_InfoShadowPen = (ULONG)tag->ti_Data;
1950 break;
1952 /* Settings defined by the view class */
1953 case MUIA_IconListview_FixedBackground:
1954 #if defined(DEBUG_ILC_ATTRIBS)
1955 D(bug("[IconList] %s: MUIA_IconListview_FixedBackground\n", __PRETTY_FUNCTION__));
1956 #endif
1957 data->icld__Option_IconListFixedBackground = (BOOL)tag->ti_Data;
1958 break;
1960 case MUIA_IconListview_ScaledBackground:
1961 #if defined(DEBUG_ILC_ATTRIBS)
1962 D(bug("[IconList] %s: MUIA_IconListview_ScaledBackground\n", __PRETTY_FUNCTION__));
1963 #endif
1964 data->icld__Option_IconListScaledBackground = (BOOL)tag->ti_Data;
1965 break;
1967 /* We listen for MUIA_Background and set default values for known types */
1968 case MUIA_Background:
1969 #if defined(DEBUG_ILC_ATTRIBS) && defined(DEBUG_ILC_ICONRENDERING)
1970 D(bug("[IconList] %s: MUIA_Background\n", __PRETTY_FUNCTION__));
1971 #endif
1973 char *bgmode_string = (char *)tag->ti_Data;
1974 BYTE this_mode = bgmode_string[0] - 48;
1976 #if defined(DEBUG_ILC_ATTRIBS) && defined(DEBUG_ILC_ICONRENDERING)
1977 D(bug("[IconList] %s: MUIA_Background | MUI BG Mode = %d\n", __PRETTY_FUNCTION__, this_mode));
1978 #endif
1979 switch (this_mode)
1981 case 0:
1982 //MUI Pattern
1983 NNSET(obj, MUIA_IconListview_FixedBackground, FALSE);
1984 NNSET(obj, MUIA_IconListview_ScaledBackground, FALSE);
1985 break;
1986 case 2:
1987 //MUI RGB color
1988 NNSET(obj, MUIA_IconListview_FixedBackground, FALSE);
1989 NNSET(obj, MUIA_IconListview_ScaledBackground, FALSE);
1990 break;
1991 case 7:
1992 //Zune Gradient
1993 NNSET(obj, MUIA_IconListview_FixedBackground, TRUE);
1994 NNSET(obj, MUIA_IconListview_ScaledBackground, TRUE);
1995 break;
1996 case 5:
1997 //Image
1998 NNSET(obj, MUIA_IconListview_FixedBackground, FALSE);
1999 NNSET(obj, MUIA_IconListview_ScaledBackground, FALSE);
2000 break;
2003 break;
2004 case MUIA_IconList_IconsDropped:
2005 data->icld_DragDropEvent = (struct IconList_Drop_Event *)tag->ti_Data;
2006 break;
2010 #if defined(DEBUG_ILC_ATTRIBS)
2011 D(bug("[IconList] %s(), out of switch\n", __PRETTY_FUNCTION__));
2012 #endif
2013 if ((oldleft != data->icld_ViewX) || (oldtop != data->icld_ViewY))
2015 data->icld_UpdateMode = UPDATE_SCROLL;
2016 data->update_scrolldx = data->icld_ViewX - oldleft;
2017 data->update_scrolldy = data->icld_ViewY - oldtop;
2018 #if defined(DEBUG_ILC_ATTRIBS)
2019 D(bug("[IconList] %s(), call MUI_Redraw()\n", __PRETTY_FUNCTION__));
2020 #endif
2021 MUI_Redraw(obj, MADF_DRAWUPDATE);
2024 #if defined(DEBUG_ILC_ATTRIBS)
2025 D(bug("[IconList] %s(), call DoSuperMethodA()\n", __PRETTY_FUNCTION__));
2026 #endif
2027 return DoSuperMethodA(CLASS, obj, (Msg)message);
2031 ///OM_GET()
2032 /**************************************************************************
2033 OM_GET
2034 **************************************************************************/
2035 IPTR IconList__OM_GET(struct IClass *CLASS, Object *obj, struct opGet *message)
2037 /* small macro to simplify return value storage */
2038 #define STORE *(message->opg_Storage)
2039 struct IconList_DATA *data = INST_DATA(CLASS, obj);
2041 #if defined(DEBUG_ILC_FUNCS) && defined(DEBUG_ILC_ATTRIBS)
2042 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
2043 #endif
2045 switch (message->opg_AttrID)
2047 case MUIA_IconList_Rastport: STORE = (IPTR)data->icld_DisplayRastPort; return 1;
2048 case MUIA_IconList_BufferRastport: STORE = (IPTR)data->icld_BufferRastPort; return 1;
2049 case MUIA_IconList_BufferLeft: STORE = (IPTR)data->icld_DrawOffsetX; return 1;
2050 case MUIA_IconList_BufferTop: STORE = (IPTR)data->icld_DrawOffsetY; return 1;
2051 case MUIA_IconList_BufferWidth:
2052 case MUIA_IconList_Width: STORE = (IPTR)data->icld_AreaWidth; return 1;
2053 case MUIA_IconList_BufferHeight:
2054 case MUIA_IconList_Height: STORE = (IPTR)data->icld_AreaHeight; return 1;
2055 case MUIA_IconList_IconsDropped: STORE = (IPTR)data->icld_DragDropEvent; return 1;
2056 case MUIA_IconList_Clicked: STORE = (IPTR)&data->icld_ClickEvent; return 1;
2057 case MUIA_IconList_IconListMode: STORE = (IPTR)data->icld__Option_IconListMode; return 1;
2058 case MUIA_IconList_LabelText_Mode: STORE = (IPTR)data->icld__Option_LabelTextMode; return 1;
2059 case MUIA_IconList_LabelText_MaxLineLen: STORE = (IPTR)data->icld__Option_LabelTextMaxLen; return 1;
2060 case MUIA_IconList_LabelText_MultiLine: STORE = (IPTR)data->icld__Option_LabelTextMultiLine; return 1;
2061 case MUIA_IconList_LabelText_MultiLineOnFocus: STORE = (IPTR)data->icld__Option_LabelTextMultiLineOnFocus; return 1;
2062 case MUIA_IconList_DisplayFlags: STORE = (IPTR)data->icld_DisplayFlags; return 1;
2063 case MUIA_IconList_SortFlags: STORE = (IPTR)data->icld_SortFlags; return 1;
2065 case MUIA_IconList_FocusIcon: STORE = (IPTR)data->icld_FocusIcon; return 1;
2067 case MUIA_Font: STORE = (IPTR)data->icld_IconLabelFont; return 1;
2068 case MUIA_IconList_LabelText_Pen: STORE = (IPTR)data->icld_LabelPen; return 1;
2069 case MUIA_IconList_LabelText_ShadowPen: STORE = (IPTR)data->icld_LabelShadowPen; return 1;
2070 case MUIA_IconList_LabelInfoText_Font: STORE = (IPTR)data->icld_IconInfoFont; return 1;
2071 case MUIA_IconList_LabelInfoText_Pen: STORE = (IPTR)data->icld_InfoPen; return 1;
2072 case MUIA_IconList_LabelInfoText_ShadowPen: STORE = (IPTR)data->icld_InfoShadowPen; return 1;
2074 case MUIA_IconList_Icon_HorizontalSpacing: STORE = (IPTR)data->icld__Option_IconHorizontalSpacing; return 1;
2075 case MUIA_IconList_Icon_VerticalSpacing: STORE = (IPTR)data->icld__Option_IconVerticalSpacing; return 1;
2076 case MUIA_IconList_Icon_ImageSpacing: STORE = (IPTR)data->icld__Option_IconImageSpacing; return 1;
2077 case MUIA_IconList_LabelText_HorizontalPadding: STORE = (IPTR)data->icld__Option_LabelTextHorizontalPadding; return 1;
2078 case MUIA_IconList_LabelText_VerticalPadding: STORE = (IPTR)data->icld__Option_LabelTextVerticalPadding; return 1;
2079 case MUIA_IconList_LabelText_BorderWidth: STORE = (IPTR)data->icld__Option_LabelTextBorderWidth; return 1;
2080 case MUIA_IconList_LabelText_BorderHeight: STORE = (IPTR)data->icld__Option_LabelTextBorderHeight; return 1;
2082 /* Settings defined by the view class */
2083 case MUIA_IconListview_FixedBackground: STORE = (IPTR)data->icld__Option_IconListFixedBackground; return 1;
2084 case MUIA_IconListview_ScaledBackground: STORE = (IPTR)data->icld__Option_IconListScaledBackground; return 1;
2086 /* ICON obj Changes */
2087 case MUIA_Virtgroup_Left: STORE = (IPTR)data->icld_ViewX; return 1;
2088 case MUIA_Virtgroup_Top: STORE = (IPTR)data->icld_ViewY; return 1;
2089 case MUIA_Group_ChildList: STORE = (IPTR)&data->icld_IconList; return 1; /* Get our list object */
2092 if (DoSuperMethodA(CLASS, obj, (Msg) message))
2093 return 1;
2095 return 0;
2096 #undef STORE
2100 IPTR IconList__OM_ADDMEMBER(struct IClass *CLASS, Object *obj, APTR message)
2102 #if defined(DEBUG_ILC_FUNCS)
2103 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
2104 #endif
2106 return NULL;
2109 IPTR IconList__OM_REMMEMBER(struct IClass *CLASS, Object *obj, APTR message)
2111 #if defined(DEBUG_ILC_FUNCS)
2112 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
2113 #endif
2115 return NULL;
2118 ///MUIM_Setup()
2119 /**************************************************************************
2120 MUIM_Setup
2121 **************************************************************************/
2122 IPTR IconList__MUIM_Setup(struct IClass *CLASS, Object *obj, struct MUIP_Setup *message)
2124 struct IconList_DATA *data = INST_DATA(CLASS, obj);
2125 struct IconEntry *node = NULL;
2126 IPTR geticon_error = 0;
2128 #if defined(DEBUG_ILC_FUNCS)
2129 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
2130 #endif
2132 if (!DoSuperMethodA(CLASS, obj, (Msg) message)) return 0;
2134 DoMethod(_win(obj), MUIM_Window_AddEventHandler, (IPTR)&data->ehn);
2136 /* Get Internal Objects to use if not set .. */
2137 data->icld_DisplayRastPort = NULL;
2138 data->icld_BufferRastPort = NULL;
2140 if (data->icld_IconLabelFont == NULL) data->icld_IconLabelFont = _font(obj);
2141 if (data->icld_IconInfoFont == NULL) data->icld_IconInfoFont = data->icld_IconLabelFont;
2142 #if defined(DEBUG_ILC_ICONRENDERING)
2143 D(bug("[IconList] %s: Use Font @ 0x%p, RastPort @ 0x%p\n", __PRETTY_FUNCTION__, data->icld_IconLabelFont, data->icld_BufferRastPort ));
2144 #endif
2146 /* Set our base options .. */
2147 data->icld_LabelPen = _pens(obj)[MPEN_SHINE];
2148 data->icld_LabelShadowPen = _pens(obj)[MPEN_SHADOW];
2149 data->icld_InfoPen = _pens(obj)[MPEN_SHINE];
2150 data->icld_InfoShadowPen = _pens(obj)[MPEN_SHADOW];
2152 data->icld__Option_LabelTextMultiLine = 1;
2153 data->icld__Option_LastLabelTextMultiLine = data->icld__Option_LabelTextMultiLine;
2155 data->icld__Option_LabelTextMultiLineOnFocus = FALSE;
2157 data->icld__Option_IconHorizontalSpacing = ILC_ICON_HORIZONTALMARGIN_DEFAULT;
2158 data->icld__Option_IconVerticalSpacing = ILC_ICON_VERTICALMARGIN_DEFAULT;
2159 data->icld__Option_IconImageSpacing = ILC_ICONLABEL_IMAGEMARGIN_DEFAULT;
2160 data->icld__Option_LabelTextHorizontalPadding = ILC_ICONLABEL_HORIZONTALTEXTMARGIN_DEFAULT;
2161 data->icld__Option_LabelTextVerticalPadding = ILC_ICONLABEL_VERTICALTEXTMARGIN_DEFAULT;
2162 data->icld__Option_LabelTextBorderWidth = ILC_ICONLABEL_BORDERWIDTH_DEFAULT;
2163 data->icld__Option_LabelTextBorderHeight = ILC_ICONLABEL_BORDERHEIGHT_DEFAULT;
2165 #ifdef __AROS__
2166 ForeachNode(&data->icld_IconList, node)
2167 #else
2168 Foreach_Node(&data->icld_IconList, node);
2169 #endif
2171 if (!node->ie_DiskObj)
2173 IPTR iconlistScreen = _screen(obj);
2174 #if defined(DEBUG_ILC_ICONRENDERING)
2175 bug("[IconList] %s: IconList Screen @ 0x%p)\n", __PRETTY_FUNCTION__, iconlistScreen);
2176 #endif
2177 if (!(node->ie_DiskObj = GetIconTags(node->ie_IconNode.ln_Name,
2178 (iconlistScreen) ? ICONGETA_Screen : TAG_IGNORE, iconlistScreen,
2179 (iconlistScreen) ? ICONGETA_RemapIcon : TAG_IGNORE, TRUE,
2180 ICONGETA_GenerateImageMasks, TRUE,
2181 ICONGETA_FailIfUnavailable, FALSE,
2182 ICONA_ErrorCode, &geticon_error,
2183 TAG_DONE)))
2185 #if defined(DEBUG_ILC_ICONRENDERING)
2186 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));
2187 #endif
2188 /* We should probably remove this node if the icon cant be obtained ? */
2192 return 1;
2196 ///MUIM_Show()
2197 /**************************************************************************
2198 MUIM_Show
2199 **************************************************************************/
2200 IPTR IconList__MUIM_Show(struct IClass *CLASS, Object *obj, struct MUIP_Show *message)
2202 struct IconList_DATA *data = INST_DATA(CLASS, obj);
2203 LONG newleft,
2204 newtop;
2205 IPTR rc;
2207 #if defined(DEBUG_ILC_FUNCS)
2208 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
2209 #endif
2211 if ((rc = DoSuperMethodA(CLASS, obj, (Msg)message)))
2214 newleft = data->icld_ViewX;
2215 newtop = data->icld_ViewY;
2217 if (newleft + _mwidth(obj) > data->icld_AreaWidth) newleft = data->icld_AreaWidth - _mwidth(obj);
2218 if (newleft < 0) newleft = 0;
2220 if (newtop + _mheight(obj) > data->icld_AreaHeight) newtop = data->icld_AreaHeight - _mheight(obj);
2221 if (newtop < 0) newtop = 0;
2223 if ((newleft != data->icld_ViewX) || (newtop != data->icld_ViewY))
2225 SetAttrs(obj, MUIA_Virtgroup_Left, newleft,
2226 MUIA_Virtgroup_Top, newtop,
2227 TAG_DONE);
2230 /* Get Internal Objects to use if not set .. */
2231 if (data->icld_DisplayRastPort == NULL)
2233 if (_rp(obj) != NULL)
2235 data->icld_DisplayRastPort = CloneRastPort(_rp(obj));
2237 else
2239 #if defined(DEBUG_ILC_ICONRENDERING)
2240 D(bug("[IconList] IconList__MUIM_Show: ERROR - NULL RastPort!\n"));
2241 #endif
2245 if (data->icld_DisplayFlags & ICONLIST_DISP_BUFFERED)
2247 struct BitMap *tmp_BuffBitMap = NULL;
2248 ULONG tmp_RastDepth = GetCyberMapAttr(data->icld_DisplayRastPort->BitMap, CYBRMATTR_DEPTH);
2249 if ((tmp_BuffBitMap = AllocBitMap(data->icld_ViewWidth,
2250 data->icld_ViewHeight,
2251 tmp_RastDepth,
2252 BMF_CLEAR,
2253 data->icld_DisplayRastPort->BitMap))!=NULL)
2255 if ((data->icld_BufferRastPort = CreateRastPort())!=NULL)
2257 data->icld_BufferRastPort->BitMap = tmp_BuffBitMap;
2258 data->icld_DrawOffsetX = 0;
2259 data->icld_DrawOffsetY = 0;
2261 else
2263 FreeBitMap(tmp_BuffBitMap);
2264 data->icld_BufferRastPort = data->icld_DisplayRastPort;
2265 data->icld_DrawOffsetX = _mleft(obj);
2266 data->icld_DrawOffsetY = _mtop(obj);
2270 else
2272 data->icld_BufferRastPort = data->icld_DisplayRastPort;
2273 data->icld_DrawOffsetX = _mleft(obj);
2274 data->icld_DrawOffsetY = _mtop(obj);
2276 if (data->icld_IconLabelFont == NULL) data->icld_IconLabelFont = _font(obj);
2277 if (data->icld_IconInfoFont == NULL) data->icld_IconInfoFont = data->icld_IconLabelFont;
2278 #if defined(DEBUG_ILC_ICONRENDERING)
2279 D(bug("[IconList] IconList__MUIM_Show: Use Font @ 0x%p, RastPort @ 0x%p\n", data->icld_IconLabelFont, data->icld_BufferRastPort ));
2280 #endif
2282 if ((data->icld_BufferRastPort) && (data->icld_IconLabelFont))
2283 SetFont(data->icld_BufferRastPort, data->icld_IconLabelFont);
2285 return rc;
2289 ///MUIM_Hide()
2290 /**************************************************************************
2291 MUIM_Hide
2292 **************************************************************************/
2293 IPTR IconList__MUIM_Hide(struct IClass *CLASS, Object *obj, struct MUIP_Hide *message)
2295 struct IconList_DATA *data = INST_DATA(CLASS, obj);
2296 IPTR rc;
2298 #if defined(DEBUG_ILC_FUNCS)
2299 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
2300 #endif
2302 if ((rc = DoSuperMethodA(CLASS, obj, (Msg)message)))
2304 if ((data->icld_BufferRastPort) && (data->icld_BufferRastPort != data->icld_DisplayRastPort))
2306 FreeBitMap(data->icld_BufferRastPort->BitMap);
2307 FreeRastPort(data->icld_BufferRastPort);
2310 data->icld_BufferRastPort = NULL;
2312 if (data->icld_DisplayRastPort)
2313 FreeRastPort(data->icld_DisplayRastPort);
2315 data->icld_DisplayRastPort = NULL;
2317 return rc;
2321 ///MUIM_Cleanup()
2322 /**************************************************************************
2323 MUIM_Cleanup
2324 **************************************************************************/
2325 IPTR IconList__MUIM_Cleanup(struct IClass *CLASS, Object *obj, struct MUIP_Cleanup *message)
2327 struct IconList_DATA *data = INST_DATA(CLASS, obj);
2328 struct IconEntry *node = NULL;
2330 #if defined(DEBUG_ILC_FUNCS)
2331 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
2332 #endif
2334 #ifdef __AROS__
2335 ForeachNode(&data->icld_IconList, node)
2336 #else
2337 Foreach_Node(&data->icld_IconList, node);
2338 #endif
2340 if (node->ie_DiskObj)
2342 FreeDiskObject(node->ie_DiskObj);
2343 node->ie_DiskObj = NULL;
2347 DoMethod(_win(obj), MUIM_Window_RemEventHandler, (IPTR)&data->ehn);
2349 return DoSuperMethodA(CLASS, obj, (Msg)message);
2353 ///MUIM_AskMinMax()
2354 /**************************************************************************
2355 MUIM_AskMinMax
2356 **************************************************************************/
2357 IPTR IconList__MUIM_AskMinMax(struct IClass *CLASS, Object *obj, struct MUIP_AskMinMax *message)
2359 ULONG rc = DoSuperMethodA(CLASS, obj, (Msg) message);
2361 #if defined(DEBUG_ILC_FUNCS)
2362 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
2363 #endif
2365 message->MinMaxInfo->MinWidth += 96;
2366 message->MinMaxInfo->MinHeight += 64;
2368 message->MinMaxInfo->DefWidth += 200;
2369 message->MinMaxInfo->DefHeight += 180;
2371 message->MinMaxInfo->MaxWidth = MUI_MAXMAX;
2372 message->MinMaxInfo->MaxHeight = MUI_MAXMAX;
2374 return rc;
2378 ///MUIM_Layout()
2379 /**************************************************************************
2380 MUIM_Layout
2381 **************************************************************************/
2382 IPTR IconList__MUIM_Layout(struct IClass *CLASS, Object *obj,struct MUIP_Layout *message)
2384 struct IconList_DATA *data = INST_DATA(CLASS, obj);
2385 ULONG rc;
2387 #if defined(DEBUG_ILC_FUNCS)
2388 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
2389 #endif
2391 rc = DoSuperMethodA(CLASS, obj, (Msg)message);
2393 data->icld_ViewWidth = _mwidth(obj);
2394 data->icld_ViewHeight = _mheight(obj);
2396 return rc;
2400 ///MUIM_Draw()
2401 /**************************************************************************
2402 MUIM_Draw - draw the IconList
2403 **************************************************************************/
2404 IPTR DrawCount;
2405 IPTR IconList__MUIM_Draw(struct IClass *CLASS, Object *obj, struct MUIP_Draw *message)
2407 struct IconList_DATA *data = INST_DATA(CLASS, obj);
2408 struct IconEntry *icon = NULL;
2410 APTR clip;
2412 ULONG update_oldwidth = 0,
2413 update_oldheight = 0;
2415 LONG clear_xoffset = 0,
2416 clear_yoffset = 0;
2418 IPTR draw_id = DrawCount++;
2420 #if defined(DEBUG_ILC_FUNCS)
2421 D(bug("[IconList]: %s(obj @ 0x%p)\n", __PRETTY_FUNCTION__, obj));
2422 #endif
2424 D(bug("[IconList] %s: id %d\n", __PRETTY_FUNCTION__, draw_id));
2426 DoSuperMethodA(CLASS, obj, (Msg)message);
2428 if (!(data->icld__Option_IconListFixedBackground))
2430 clear_xoffset = data->icld_ViewX;
2431 clear_yoffset = data->icld_ViewY;
2434 // If window size changes, only update needed areas
2435 if (data->update_oldwidth == 0) data->update_oldwidth = data->icld_ViewWidth;
2436 if (data->update_oldheight == 0) data->update_oldheight = data->icld_ViewHeight;
2437 if ((data->update_oldwidth != data->icld_ViewWidth) || (data->update_oldheight != data->icld_ViewHeight))
2439 if (data->icld_UpdateMode != UPDATE_SCROLL)
2441 data->icld_UpdateMode = UPDATE_RESIZE;
2442 update_oldwidth = data->update_oldwidth;
2443 update_oldheight = data->update_oldheight;
2444 data->update_oldwidth = data->icld_ViewWidth;
2445 data->update_oldheight = data->icld_ViewHeight;
2449 if ((message->flags & MADF_DRAWUPDATE) || (data->icld_UpdateMode == UPDATE_RESIZE))
2451 #if defined(DEBUG_ILC_ICONRENDERING)
2453 if (message->flags & MADF_DRAWUPDATE)
2455 bug("[IconList] %s#%d: MADF_DRAWUPDATE\n", __PRETTY_FUNCTION__, draw_id);
2457 else
2459 bug("[IconList] %s#%d: UPDATE_RESIZE\n", __PRETTY_FUNCTION__, draw_id);
2462 #endif
2463 if ((data->icld_UpdateMode == UPDATE_SINGLEICON) && (data->update_icon != NULL)) /* draw only a single icon at update_icon */
2465 struct Rectangle rect;
2467 D(bug("[IconList] %s#%d: UPDATE_SINGLEICON (icon @ 0x%p)\n", __PRETTY_FUNCTION__, draw_id, data->update_icon));
2469 IconList_GetIconAreaRectangle(obj, data, data->update_icon, &rect);
2471 rect.MinX += _mleft(obj) + (data->update_icon->ie_IconX - data->icld_ViewX);
2472 rect.MaxX += _mleft(obj) + (data->update_icon->ie_IconX - data->icld_ViewX);
2473 rect.MinY += _mtop(obj) + (data->update_icon->ie_IconY - data->icld_ViewY);
2474 rect.MaxY += _mtop(obj) + (data->update_icon->ie_IconY - data->icld_ViewY);
2476 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
2478 if (data->update_icon->ie_AreaWidth < data->icld_IconAreaLargestWidth)
2480 rect.MinX += ((data->icld_IconAreaLargestWidth - data->update_icon->ie_AreaWidth)/2);
2481 rect.MaxX += ((data->icld_IconAreaLargestWidth - data->update_icon->ie_AreaWidth)/2);
2484 if (data->update_icon->ie_AreaHeight < data->icld_IconAreaLargestHeight)
2486 rect.MinY += ((data->icld_IconAreaLargestHeight - data->update_icon->ie_AreaHeight)/2);
2487 rect.MaxY += ((data->icld_IconAreaLargestHeight - data->update_icon->ie_AreaHeight)/2);
2491 clip = MUI_AddClipping(muiRenderInfo(obj), _mleft(obj), _mtop(obj), _mwidth(obj), _mheight(obj));
2493 #if defined(DEBUG_ILC_ICONRENDERING)
2494 D(bug("[IconList] %s#%d: UPDATE_SINGLEICON: Calling MUIM_DrawBackground (A)\n", __PRETTY_FUNCTION__, draw_id));
2495 #endif
2496 DoMethod(obj, MUIM_DrawBackground,
2497 rect.MinX, rect.MinY,
2498 rect.MaxX - rect.MinX + 1, rect.MaxY - rect.MinY + 1,
2499 clear_xoffset, clear_yoffset,
2502 /* We could have deleted also other icons so they must be redrawn */
2503 #ifdef __AROS__
2504 ForeachNode(&data->icld_IconList, icon)
2505 #else
2506 Foreach_Node(&data->icld_IconList, icon);
2507 #endif
2509 if ((icon != data->update_icon) && (icon->ie_Flags & ICONENTRY_FLAG_VISIBLE))
2511 struct Rectangle rect2;
2512 IconList_GetIconAreaRectangle(obj, data, icon, &rect2);
2514 rect2.MinX += _mleft(obj) - data->icld_ViewX + icon->ie_IconX;
2515 rect2.MaxX += _mleft(obj) - data->icld_ViewX + icon->ie_IconX;
2516 rect2.MinY += _mtop(obj) - data->icld_ViewY + icon->ie_IconY;
2517 rect2.MaxY += _mtop(obj) - data->icld_ViewY + icon->ie_IconY;
2519 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
2521 if (icon->ie_AreaWidth < data->icld_IconAreaLargestWidth)
2523 rect2.MinX += ((data->icld_IconAreaLargestWidth - icon->ie_AreaWidth)/2);
2524 rect2.MaxX += ((data->icld_IconAreaLargestWidth - icon->ie_AreaWidth)/2);
2527 if (icon->ie_AreaHeight < data->icld_IconAreaLargestHeight)
2529 rect2.MinY += ((data->icld_IconAreaLargestHeight - icon->ie_AreaHeight)/2);
2530 rect2.MaxY += ((data->icld_IconAreaLargestHeight - icon->ie_AreaHeight)/2);
2534 if (RectAndRect(&rect, &rect2))
2536 // Update icon here
2537 icon->ie_Flags |= ICONENTRY_FLAG_NEEDSUPDATE;
2538 DoMethod(obj, MUIM_IconList_DrawEntry, icon, ICONENTRY_DRAWMODE_PLAIN);
2539 DoMethod(obj, MUIM_IconList_DrawEntryLabel, icon, ICONENTRY_DRAWMODE_PLAIN);
2540 icon->ie_Flags &= ~ICONENTRY_FLAG_NEEDSUPDATE;
2545 icon->ie_Flags |= ICONENTRY_FLAG_NEEDSUPDATE;
2546 DoMethod(obj, MUIM_IconList_DrawEntry, data->update_icon, ICONENTRY_DRAWMODE_PLAIN);
2547 DoMethod(obj, MUIM_IconList_DrawEntryLabel, data->update_icon, ICONENTRY_DRAWMODE_PLAIN);
2548 icon->ie_Flags &= ~ICONENTRY_FLAG_NEEDSUPDATE;
2549 data->icld_UpdateMode = 0;
2550 data->update_icon = NULL;
2552 if (data->icld_DisplayRastPort != data->icld_BufferRastPort)
2554 #if defined(DEBUG_ILC_ICONRENDERING)
2555 D(bug("[IconList] %s#%d: UPDATE_SINGLEICON Blitting to front rastport..\n", __PRETTY_FUNCTION__, draw_id));
2556 #endif
2557 BltBitMapRastPort(data->icld_BufferRastPort->BitMap,
2558 rect.MinX - _mleft(obj), rect.MinY - _mtop(obj),
2559 data->icld_DisplayRastPort,
2560 rect.MinX, rect.MinY,
2561 rect.MaxX - rect.MinX + 1, rect.MaxY - rect.MinY + 1,
2562 0xC0);
2565 MUI_RemoveClipping(muiRenderInfo(obj),clip);
2566 goto draw_done;
2568 else if (data->icld_UpdateMode == UPDATE_SCROLL)
2570 struct Region *region = NULL;
2571 struct Rectangle xrect,
2572 yrect;
2573 BOOL scroll_caused_damage;
2575 #if defined(DEBUG_ILC_ICONRENDERING)
2576 D(bug("[IconList] %s#%d: UPDATE_SCROLL.\n", __PRETTY_FUNCTION__, draw_id));
2577 #endif
2579 if (!data->icld__Option_IconListFixedBackground)
2581 scroll_caused_damage = (_rp(obj)->Layer->Flags & LAYERREFRESH) ? FALSE : TRUE;
2583 data->icld_UpdateMode = 0;
2585 if ((abs(data->update_scrolldx) >= _mwidth(obj)) ||
2586 (abs(data->update_scrolldy) >= _mheight(obj)))
2588 #if defined(DEBUG_ILC_ICONRENDERING)
2589 D(bug("[IconList] %s#%d: UPDATE_SCROLL: Moved outside current view -> Causing Redraw .. MADF_DRAWOBJECT\n", __PRETTY_FUNCTION__, draw_id));
2590 #endif
2591 MUI_Redraw(obj, MADF_DRAWOBJECT);
2592 goto draw_done;
2595 if (!(region = NewRegion()))
2597 #if defined(DEBUG_ILC_ICONRENDERING)
2598 D(bug("[IconList] %s#%d: UPDATE_SCROLL: Couldnt Alloc Region -> Causing Redraw ...MADF_DRAWOBJECT\n", __PRETTY_FUNCTION__, draw_id));
2599 #endif
2600 MUI_Redraw(obj, MADF_DRAWOBJECT);
2601 goto draw_done;
2604 if (data->update_scrolldx > 0)
2606 xrect.MinX = _mright(obj) - data->update_scrolldx;
2607 xrect.MinY = _mtop(obj);
2608 xrect.MaxX = _mright(obj);
2609 xrect.MaxY = _mbottom(obj);
2611 OrRectRegion(region, &xrect);
2613 data->update_rect1 = &xrect;
2615 else if (data->update_scrolldx < 0)
2617 xrect.MinX = _mleft(obj);
2618 xrect.MinY = _mtop(obj);
2619 xrect.MaxX = _mleft(obj) - data->update_scrolldx;
2620 xrect.MaxY = _mbottom(obj);
2622 OrRectRegion(region, &xrect);
2624 data->update_rect1 = &xrect;
2627 if (data->update_scrolldy > 0)
2629 yrect.MinX = _mleft(obj);
2630 yrect.MinY = _mbottom(obj) - data->update_scrolldy;
2631 yrect.MaxX = _mright(obj);
2632 yrect.MaxY = _mbottom(obj);
2634 OrRectRegion(region, &yrect);
2636 data->update_rect2 = &yrect;
2638 else if (data->update_scrolldy < 0)
2640 yrect.MinX = _mleft(obj);
2641 yrect.MinY = _mtop(obj);
2642 yrect.MaxX = _mright(obj);
2643 yrect.MaxY = _mtop(obj) - data->update_scrolldy;
2645 OrRectRegion(region, &yrect);
2647 data->update_rect2 = &yrect;
2650 #if defined(DEBUG_ILC_ICONRENDERING)
2651 D(bug("[IconList] %s#%d: UPDATE_SCROLL: Scrolling Raster..\n", __PRETTY_FUNCTION__, draw_id));
2652 #endif
2653 if (data->icld_DisplayRastPort == data->icld_BufferRastPort)
2655 ScrollRasterBF(data->icld_BufferRastPort,
2656 data->update_scrolldx,
2657 data->update_scrolldy,
2658 _mleft(obj),
2659 _mtop(obj),
2660 _mright(obj),
2661 _mbottom(obj));
2663 else
2665 ScrollRasterBF(data->icld_BufferRastPort,
2666 data->update_scrolldx,
2667 data->update_scrolldy,
2670 _mwidth(obj),
2671 _mheight(obj));
2674 scroll_caused_damage = scroll_caused_damage && (_rp(obj)->Layer->Flags & LAYERREFRESH) ? TRUE : FALSE;
2676 clip = MUI_AddClipRegion(muiRenderInfo(obj), region);
2679 #if defined(DEBUG_ILC_ICONRENDERING)
2680 D(bug("[IconList] %s#%d: UPDATE_SCROLL: Causing Redraw -> MADF_DRAWOBJECT..\n", __PRETTY_FUNCTION__, draw_id));
2681 #endif
2682 MUI_Redraw(obj, MADF_DRAWOBJECT);
2684 data->update_rect1 = data->update_rect2 = NULL;
2686 if (!data->icld__Option_IconListFixedBackground)
2688 MUI_RemoveClipRegion(muiRenderInfo(obj), clip);
2690 if (scroll_caused_damage)
2692 if (MUI_BeginRefresh(muiRenderInfo(obj), 0))
2694 /* Theoretically it might happen that more damage is caused
2695 after ScrollRaster. By something else, like window movement
2696 in front of our window. Therefore refresh root object of
2697 window, not just this object */
2699 Object *o = NULL;
2701 GET(_win(obj),MUIA_Window_RootObject, &o);
2702 MUI_Redraw(o, MADF_DRAWOBJECT);
2703 #if defined(DEBUG_ILC_ICONRENDERING)
2704 D(bug("[IconList] %s#%d: UPDATE_SCROLL: Causing Redraw -> MADF_DRAWOBJECT..\n", __PRETTY_FUNCTION__, draw_id));
2705 #endif
2706 MUI_EndRefresh(muiRenderInfo(obj), 0);
2710 if (data->icld_DisplayRastPort != data->icld_BufferRastPort)
2712 #if defined(DEBUG_ILC_ICONRENDERING)
2713 D(bug("[IconList] %s#%d: UPDATE_SCROLL: Blitting to front rastport..\n", __PRETTY_FUNCTION__, draw_id));
2714 #endif
2715 BltBitMapRastPort(data->icld_BufferRastPort->BitMap,
2716 0, 0,
2717 data->icld_DisplayRastPort,
2718 _mleft(obj), _mtop(obj),
2719 _mwidth(obj), _mheight(obj),
2720 0xC0);
2722 goto draw_done;
2724 else if (data->icld_UpdateMode == UPDATE_RESIZE)
2726 struct Region *region = NULL;
2727 struct Rectangle wrect,
2728 hrect;
2729 ULONG diffw = 0,
2730 diffh = 0;
2732 #if defined(DEBUG_ILC_ICONRENDERING)
2733 D(bug("[IconList] %s#%d: UPDATE_RESIZE.\n", __PRETTY_FUNCTION__, draw_id));
2734 #endif
2736 if ((data->icld_BufferRastPort) && (data->icld_BufferRastPort != data->icld_DisplayRastPort))
2738 //Free up the buffers rastport and bitmap so we can replace them ..
2739 struct Bitmap *bitmap_Old = (struct Bitmap *)data->icld_BufferRastPort->BitMap;
2740 struct Bitmap *bitmap_New;
2742 ULONG tmp_RastDepth;
2744 data->icld_BufferRastPort->BitMap = NULL;
2746 FreeRastPort(data->icld_BufferRastPort);
2747 SET(obj, MUIA_IconList_BufferRastport, NULL);
2749 tmp_RastDepth = GetCyberMapAttr(data->icld_DisplayRastPort->BitMap, CYBRMATTR_DEPTH);
2750 if ((bitmap_New = (struct Bitmap *)AllocBitMap(data->icld_ViewWidth,
2751 data->icld_ViewHeight,
2752 tmp_RastDepth,
2753 BMF_CLEAR,
2754 data->icld_DisplayRastPort->BitMap))!=NULL)
2756 if ((data->icld_BufferRastPort = CreateRastPort())!=NULL)
2758 data->icld_BufferRastPort->BitMap = (struct BitMap *)bitmap_New;
2759 SET(obj, MUIA_IconList_BufferRastport, data->icld_BufferRastPort);
2760 data->icld_DrawOffsetX = 0;
2761 data->icld_DrawOffsetY = 0;
2763 else
2765 FreeBitMap((struct BitMap *)bitmap_New);
2766 data->icld_BufferRastPort = data->icld_DisplayRastPort;
2767 data->icld_DrawOffsetX = _mleft(obj);
2768 data->icld_DrawOffsetY = _mtop(obj);
2772 if (bitmap_Old != (struct Bitmap *)data->icld_BufferRastPort->BitMap)
2773 FreeBitMap((struct BitMap *)bitmap_Old);
2776 data->icld_UpdateMode = 0;
2778 if (!data->icld__Option_IconListScaledBackground)
2780 if (!(region = NewRegion()))
2782 #if defined(DEBUG_ILC_ICONRENDERING)
2783 D(bug("[IconList] %s#%d: UPDATE_RESIZE: Causing Redraw -> MADF_DRAWOBJECT..\n", __PRETTY_FUNCTION__, draw_id));
2784 #endif
2785 MUI_Redraw(obj, MADF_DRAWOBJECT);
2786 goto draw_done;
2789 if ( data->icld_ViewWidth > update_oldwidth )
2790 diffw = data->icld_ViewWidth - update_oldwidth;
2791 if ( data->icld_ViewHeight > update_oldheight )
2792 diffh = data->icld_ViewHeight - update_oldheight;
2794 if (diffw)
2796 wrect.MinX = _mright(obj) - diffw;
2797 wrect.MinY = _mtop(obj);
2798 wrect.MaxX = _mright(obj);
2799 wrect.MaxY = _mbottom(obj);
2800 OrRectRegion(region, &wrect);
2801 data->update_rect1 = &wrect;
2804 if (diffh)
2806 hrect.MinX = _mleft(obj);
2807 hrect.MinY = _mbottom(obj) - diffh;
2808 hrect.MaxX = _mright(obj);
2809 hrect.MaxX = _mright(obj);
2810 hrect.MaxY = _mbottom(obj);
2811 OrRectRegion(region, &hrect);
2812 data->update_rect2 = &hrect;
2814 if (diffh||diffw)
2816 clip = MUI_AddClipRegion(muiRenderInfo(obj), region);
2818 else
2820 /* View became smaller both in horizontal and vertical direction.
2821 Nothing to do */
2823 DisposeRegion(region);
2824 goto draw_done;
2828 #if defined(DEBUG_ILC_ICONRENDERING)
2829 D(bug("[IconList] %s#%d: UPDATE_RESIZE: Causing Redraw -> MADF_DRAWOBJECT..\n", __PRETTY_FUNCTION__, draw_id));
2830 #endif
2831 MUI_Redraw(obj, MADF_DRAWOBJECT);
2833 if (!data->icld__Option_IconListScaledBackground)
2835 if (diffh||diffw)
2837 data->update_rect1 = data->update_rect2 = NULL;
2838 MUI_RemoveClipRegion(muiRenderInfo(obj), clip);
2839 } else DisposeRegion(region);
2842 goto draw_done;
2846 if (message->flags & MADF_DRAWOBJECT)
2848 struct Rectangle viewrect;
2850 #if defined(DEBUG_ILC_ICONRENDERING)
2851 D(bug("[IconList] %s#%d: MADF_DRAWOBJECT\n", __PRETTY_FUNCTION__, draw_id));
2852 #endif
2854 clip = MUI_AddClipping(muiRenderInfo(obj), _mleft(obj), _mtop(obj), _mwidth(obj), _mheight(obj));
2856 viewrect.MinX = _mleft(obj);
2857 viewrect.MaxX = _mleft(obj) + _mwidth(obj);
2858 viewrect.MinY = _mtop(obj);
2859 viewrect.MaxY = _mtop(obj) + _mheight(obj);
2861 #if defined(DEBUG_ILC_ICONRENDERING)
2862 D(bug("[IconList] %s#%d: MADF_DRAWOBJECT: Calling MUIM_DrawBackground (B)\n", __PRETTY_FUNCTION__, draw_id));
2863 #endif
2864 DoMethod(
2865 obj, MUIM_DrawBackground, _mleft(obj), _mtop(obj), _mwidth(obj), _mheight(obj),
2866 clear_xoffset, clear_yoffset, 0
2868 #ifdef __AROS__
2869 ForeachNode(&data->icld_IconList, icon)
2870 #else
2871 Foreach_Node(&data->icld_IconList, icon);
2872 #endif
2874 if ((icon->ie_Flags & ICONENTRY_FLAG_VISIBLE) &&
2875 (icon->ie_DiskObj) &&
2876 (icon->ie_IconX != NO_ICON_POSITION) &&
2877 (icon->ie_IconY != NO_ICON_POSITION))
2879 struct Rectangle iconrect;
2880 IconList_GetIconAreaRectangle(obj, data, icon, &iconrect);
2882 iconrect.MinX += _mleft(obj) - data->icld_ViewX + icon->ie_IconX;
2883 iconrect.MaxX += _mleft(obj) - data->icld_ViewX + icon->ie_IconX;
2884 iconrect.MinY += _mtop(obj) - data->icld_ViewY + icon->ie_IconY;
2885 iconrect.MaxY += _mtop(obj) - data->icld_ViewY + icon->ie_IconY;
2887 if (RectAndRect(&viewrect, &iconrect))
2889 DoMethod(obj, MUIM_IconList_DrawEntry, icon, ICONENTRY_DRAWMODE_PLAIN);
2890 DoMethod(obj, MUIM_IconList_DrawEntryLabel, icon, ICONENTRY_DRAWMODE_PLAIN);
2895 if (data->icld_DisplayRastPort != data->icld_BufferRastPort)
2897 #if defined(DEBUG_ILC_ICONRENDERING)
2898 D(bug("[IconList] %s#%d: MADF_DRAWOBJECT: Blitting to front rastport..\n", __PRETTY_FUNCTION__, draw_id));
2899 #endif
2900 BltBitMapRastPort(data->icld_BufferRastPort->BitMap,
2901 0, 0,
2902 data->icld_DisplayRastPort,
2903 _mleft(obj), _mtop(obj),
2904 _mwidth(obj), _mheight(obj),
2905 0xC0);
2908 MUI_RemoveClipping(muiRenderInfo(obj), clip);
2910 data->icld_UpdateMode = 0;
2912 draw_done:;
2914 D(bug("[IconList] %s: Draw finished for id %d\n", __PRETTY_FUNCTION__, draw_id));
2916 return 0;
2920 ///IconList__MUIM_IconList_Update()
2921 /**************************************************************************
2922 MUIM_IconList_Refresh
2923 Implemented by subclasses
2924 **************************************************************************/
2925 IPTR IconList__MUIM_IconList_Update(struct IClass *CLASS, Object *obj, struct MUIP_IconList_Update *message)
2927 struct IconList_DATA *data = INST_DATA(CLASS, obj);
2929 #if defined(DEBUG_ILC_FUNCS)
2930 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
2931 #endif
2933 data->icld_FocusIcon = NULL;
2934 SET(obj, MUIA_IconList_Changed, TRUE);
2936 return 1;
2940 ///MUIM_IconList_Clear()
2941 /**************************************************************************
2942 MUIM_IconList_Clear
2943 **************************************************************************/
2944 IPTR IconList__MUIM_IconList_Clear(struct IClass *CLASS, Object *obj, struct MUIP_IconList_Clear *message)
2946 struct IconList_DATA *data = INST_DATA(CLASS, obj);
2947 struct IconEntry *node = NULL;
2949 #if defined(DEBUG_ILC_FUNCS)
2950 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
2951 #endif
2953 while ((node = (struct IconEntry*)RemTail((struct List*)&data->icld_IconList)))
2955 DoMethod(obj, MUIM_IconList_DestroyEntry, node);
2958 data->icld_SelectionLastClicked = NULL;
2959 data->icld_FocusIcon = NULL;
2961 data->icld_ViewX = data->icld_ViewY = data->icld_AreaWidth = data->icld_AreaHeight = 0;
2963 D(bug("[IconList]: %s: call SetSuperAttrs()\n", __PRETTY_FUNCTION__));
2964 SetSuperAttrs(CLASS, obj, MUIA_Virtgroup_Left, data->icld_ViewX,
2965 MUIA_Virtgroup_Top, data->icld_ViewY,
2966 TAG_DONE);
2967 D(bug("[IconList]: %s: call SetAttrs()\n", __PRETTY_FUNCTION__));
2968 SetAttrs(obj, MUIA_Virtgroup_Left, data->icld_ViewX,
2969 MUIA_Virtgroup_Top, data->icld_ViewY,
2970 TAG_DONE);
2972 D(bug("[IconList]: %s: Set MUIA_IconList_Width and MUIA_IconList_Height\n", __PRETTY_FUNCTION__));
2973 SetAttrs(obj, MUIA_IconList_Width, data->icld_AreaWidth,
2974 MUIA_IconList_Height, data->icld_AreaHeight,
2975 TAG_DONE);
2977 D(bug("[IconList]: %s: call MUI_Redraw()\n", __PRETTY_FUNCTION__));
2978 MUI_Redraw(obj,MADF_DRAWOBJECT);
2979 return 1;
2983 ///IconList__MUIM_IconList_DestroyEntry()
2984 IPTR IconList__MUIM_IconList_DestroyEntry(struct IClass *CLASS, Object *obj, struct MUIP_IconList_DestroyEntry *message)
2986 struct IconList_DATA *data = INST_DATA(CLASS, obj);
2988 #if defined(DEBUG_ILC_FUNCS)
2989 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
2990 #endif
2992 if (message->icon)
2994 if (message->icon->ie_Flags & ICONENTRY_FLAG_SELECTED)
2996 if (data->icld_SelectionLastClicked == message->icon)
2998 struct IconList_Entry *nextentry = &message->icon->ie_IconListEntry;
3000 /* get selected entries from SOURCE iconlist */
3001 DoMethod(obj, MUIM_IconList_NextIcon, MUIV_IconList_NextIcon_Selected, (IPTR)&nextentry);
3002 if (nextentry)
3003 data->icld_SelectionLastClicked = (struct IconEntry *)((IPTR)nextentry - ((IPTR)&message->icon->ie_IconListEntry - (IPTR)message->icon));
3004 else
3005 data->icld_SelectionLastClicked = NULL;
3007 if (data->icld_FocusIcon == message->icon)
3008 data->icld_FocusIcon = data->icld_SelectionLastClicked;
3010 Remove(&message->icon->ie_SelectionNode);
3012 if (message->icon->ie_TxtBuf_DisplayedLabel) FreeVecPooled(data->icld_Pool, message->icon->ie_TxtBuf_DisplayedLabel);
3013 if (message->icon->ie_TxtBuf_PROT) FreePooled(data->icld_Pool, message->icon->ie_TxtBuf_PROT, 8);
3014 if (message->icon->ie_TxtBuf_SIZE) FreePooled(data->icld_Pool, message->icon->ie_TxtBuf_SIZE, 30);
3015 if (message->icon->ie_TxtBuf_TIME) FreePooled(data->icld_Pool, message->icon->ie_TxtBuf_TIME, LEN_DATSTRING);
3016 if (message->icon->ie_TxtBuf_DATE) FreePooled(data->icld_Pool, message->icon->ie_TxtBuf_DATE, LEN_DATSTRING);
3017 if (message->icon->ie_DiskObj) FreeDiskObject(message->icon->ie_DiskObj);
3018 if (message->icon->ie_IconListEntry.label) FreePooled(data->icld_Pool, message->icon->ie_IconListEntry.label, strlen(message->icon->ie_IconListEntry.label)+1);
3019 if (message->icon->ie_IconNode.ln_Name) FreePooled(data->icld_Pool, message->icon->ie_IconNode.ln_Name, strlen(message->icon->ie_IconNode.ln_Name)+1);
3020 FreePooled(data->icld_Pool, message->icon, sizeof(struct IconEntry));
3022 return TRUE;
3026 ///IconList__MUIM_IconList_CreateEntry()
3027 /**************************************************************************
3028 MUIM_IconList_CreateEntry.
3029 Returns 0 on failure otherwise it returns the icons entry ..
3030 **************************************************************************/
3031 IPTR IconList__MUIM_IconList_CreateEntry(struct IClass *CLASS, Object *obj, struct MUIP_IconList_CreateEntry *message)
3033 struct IconList_DATA *data = INST_DATA(CLASS, obj);
3034 struct IconEntry *entry = NULL;
3035 struct DateTime dt;
3036 struct DateStamp now;
3037 UBYTE *sp = NULL;
3039 struct DiskObject *dob = NULL;
3040 struct Rectangle rect;
3042 IPTR geticon_error = 0;
3044 #if defined(DEBUG_ILC_FUNCS)
3045 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
3046 #endif
3048 /*disk object (icon)*/
3049 if (message->icon_dob == NULL)
3051 IPTR iconlistScreen = _screen(obj);
3052 D(bug("[IconList] %s: IconList Screen @ 0x%p)\n", __PRETTY_FUNCTION__, iconlistScreen));
3054 dob = GetIconTags
3056 message->filename,
3057 (iconlistScreen) ? ICONGETA_Screen : TAG_IGNORE, iconlistScreen,
3058 (iconlistScreen) ? ICONGETA_RemapIcon : TAG_IGNORE, TRUE,
3059 ICONGETA_FailIfUnavailable, FALSE,
3060 ICONGETA_GenerateImageMasks, TRUE,
3061 ICONA_ErrorCode, &geticon_error,
3062 TAG_DONE
3065 if (dob == NULL)
3067 D(bug("[IconList] %s: Fatal: Couldnt get DiskObject! (error code = 0x%p)\n", __PRETTY_FUNCTION__, geticon_error));
3069 return (IPTR)NULL;
3072 else
3074 dob = message->icon_dob;
3077 D(bug("[IconList] %s: DiskObject @ 0x%p\n", __PRETTY_FUNCTION__, dob));
3079 if ((entry = AllocPooled(data->icld_Pool, sizeof(struct IconEntry))) == NULL)
3081 D(bug("[IconList] %s: Failed to Allocate Entry Storage!\n", __PRETTY_FUNCTION__));
3082 FreeDiskObject(dob);
3083 return (IPTR)NULL;
3085 memset(entry, 0, sizeof(struct IconEntry));
3086 entry->ie_Flags |= ICONENTRY_FLAG_NEEDSUPDATE;
3087 entry->ie_IconListEntry.ile_IconEntry = entry;
3089 /* Allocate Text Buffers */
3091 if ((entry->ie_TxtBuf_DATE = AllocPooled(data->icld_Pool, LEN_DATSTRING)) == NULL)
3093 D(bug("[IconList] %s: Failed to Allocate Entry DATE Storage!\n", __PRETTY_FUNCTION__));
3094 DoMethod(obj, MUIM_IconList_DestroyEntry, entry);
3095 return (IPTR)NULL;
3097 memset(entry->ie_TxtBuf_DATE, 0, LEN_DATSTRING);
3099 if ((entry->ie_TxtBuf_TIME = AllocPooled(data->icld_Pool, LEN_DATSTRING)) == NULL)
3101 D(bug("[IconList] %s: Failed to Allocate Entry TIME string Storage!\n", __PRETTY_FUNCTION__));
3102 DoMethod(obj, MUIM_IconList_DestroyEntry, entry);
3103 return (IPTR)NULL;
3105 memset(entry->ie_TxtBuf_TIME, 0, LEN_DATSTRING);
3107 if ((entry->ie_TxtBuf_SIZE = AllocPooled(data->icld_Pool, 30)) == NULL)
3109 D(bug("[IconList] %s: Failed to Allocate Entry SIZE string Storage!\n", __PRETTY_FUNCTION__));
3110 DoMethod(obj, MUIM_IconList_DestroyEntry, entry);
3111 return (IPTR)NULL;
3113 memset(entry->ie_TxtBuf_SIZE, 0, 30);
3115 if ((entry->ie_TxtBuf_PROT = AllocPooled(data->icld_Pool, 8)) == NULL)
3117 D(bug("[IconList] %s: Failed to Allocate Entry PROT Flag string Storage!\n", __PRETTY_FUNCTION__));
3118 DoMethod(obj, MUIM_IconList_DestroyEntry, entry);
3119 return (IPTR)NULL;
3121 memset(entry->ie_TxtBuf_PROT, 0, 8);
3123 /*alloc filename*/
3124 if ((entry->ie_IconNode.ln_Name = AllocPooled(data->icld_Pool, strlen(message->filename) + 1)) == NULL)
3126 D(bug("[IconList] %s: Failed to Allocate Entry filename string Storage!\n", __PRETTY_FUNCTION__));
3127 DoMethod(obj, MUIM_IconList_DestroyEntry, entry);
3128 return (IPTR)NULL;
3131 /*alloc icon label*/
3132 if ((entry->ie_IconListEntry.label = AllocPooled(data->icld_Pool, strlen(message->label) + 1)) == NULL)
3134 D(bug("[IconList] %s: Failed to Allocate Entry label string Storage!\n", __PRETTY_FUNCTION__));
3135 DoMethod(obj, MUIM_IconList_DestroyEntry, entry);
3136 return (IPTR)NULL;
3139 /*file info block*/
3140 if(message->fib != NULL)
3142 entry->ie_FileInfoBlock = message->fib;
3144 if (entry->ie_FileInfoBlock->fib_DirEntryType > 0)
3146 strcpy(entry->ie_TxtBuf_SIZE, "Drawer");
3148 else
3150 int i = entry->ie_FileInfoBlock->fib_Size;
3152 /*show byte size for small files*/
3153 if (i > 9999)
3154 sprintf(entry->ie_TxtBuf_SIZE, "%d KB", (LONG)(i/1024));
3155 else
3156 sprintf(entry->ie_TxtBuf_SIZE, "%d B", (LONG)i);
3159 dt.dat_Stamp = entry->ie_FileInfoBlock->fib_Date;
3160 dt.dat_Format = FORMAT_DEF;
3161 dt.dat_Flags = 0;
3162 dt.dat_StrDay = NULL;
3163 dt.dat_StrDate = entry->ie_TxtBuf_DATE;
3164 dt.dat_StrTime = entry->ie_TxtBuf_TIME;
3166 DateToStr(&dt);
3167 DateStamp(&now);
3169 /*if modified today show time, otherwise just show date*/
3170 if (now.ds_Days == entry->ie_FileInfoBlock->fib_Date.ds_Days)
3171 entry->ie_Flags |= ICONENTRY_FLAG_TODAY;
3172 else
3173 entry->ie_Flags &= ~ICONENTRY_FLAG_TODAY;
3175 sp = entry->ie_TxtBuf_PROT;
3176 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_SCRIPT) ? 's' : '-';
3177 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_PURE) ? 'p' : '-';
3178 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_ARCHIVE) ? 'a' : '-';
3179 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_READ) ? '-' : 'r';
3180 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_WRITE) ? '-' : 'w';
3181 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_EXECUTE) ? '-' : 'e';
3182 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_DELETE) ? '-' : 'd';
3183 *sp++ = '\0';
3185 entry->ie_IconListEntry.type = entry->ie_FileInfoBlock->fib_DirEntryType;
3187 else
3189 entry->ie_IconListEntry.type = ST_USERDIR;
3192 /* Override type if specified during createntry */
3193 if (message->type != 0)
3195 entry->ie_IconListEntry.type = message->type;
3196 D(bug("[IconList] %s: Overide Entry Type. New Type = %x\n", __PRETTY_FUNCTION__, entry->ie_IconListEntry.type));
3198 else
3200 D(bug("[IconList] %s: Entry Type = %x\n", __PRETTY_FUNCTION__, entry->ie_IconListEntry.type));
3203 strcpy(entry->ie_IconNode.ln_Name, message->filename);
3204 strcpy(entry->ie_IconListEntry.label, message->label);
3206 if (IconList__LabelFunc_CreateLabel(obj, data, entry) != (IPTR)NULL)
3208 entry->ie_DiskObj = dob;
3209 entry->ie_IconListEntry.udata = NULL;
3211 /* Use a geticonrectangle routine that gets textwidth! */
3212 IconList_GetIconAreaRectangle(obj, data, entry, &rect);
3214 AddTail((struct List*)&data->icld_IconList, (struct Node*)&entry->ie_IconNode);
3216 return (IPTR)entry;
3219 DoMethod(obj, MUIM_IconList_DestroyEntry, entry);
3220 return (IPTR)NULL;
3224 ///DoWheelMove()
3225 static void DoWheelMove(struct IClass *CLASS, Object *obj, LONG wheelx, LONG wheely, UWORD qual)
3227 struct IconList_DATA *data = INST_DATA(CLASS, obj);
3229 LONG newleft = data->icld_ViewX,
3230 newtop = data->icld_ViewY;
3232 /* Use horizontal scrolling if any of the following cases are true ...
3234 # vertical wheel is used but there's nothing to scroll
3235 (everything is visible already) ..
3237 # vertical wheel is used and one of the ALT keys is down. */
3239 if ((wheely && !wheelx) &&
3240 ((data->icld_AreaHeight <= _mheight(obj)) || (qual & (IEQUALIFIER_LALT | IEQUALIFIER_RALT))))
3242 wheelx = wheely; wheely = 0;
3245 if (qual & (IEQUALIFIER_CONTROL))
3247 if (wheelx < 0) newleft = 0;
3248 if (wheelx > 0) newleft = data->icld_AreaWidth;
3249 if (wheely < 0) newtop = 0;
3250 if (wheely > 0) newtop = data->icld_AreaHeight;
3252 else if (qual & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
3254 newleft += (wheelx * _mwidth(obj));
3255 newtop += (wheely * _mheight(obj));
3257 else
3259 newleft += wheelx * 30;
3260 newtop += wheely * 30;
3263 if (newleft + _mwidth(obj) > data->icld_AreaWidth) newleft = data->icld_AreaWidth - _mwidth(obj);
3264 if (newleft < 0) newleft = 0;
3266 if (newtop + _mheight(obj) > data->icld_AreaHeight) newtop = data->icld_AreaHeight - _mheight(obj);
3267 if (newtop < 0) newtop = 0;
3269 if ((newleft != data->icld_ViewX) || (newtop != data->icld_ViewY))
3271 SetAttrs(obj, MUIA_Virtgroup_Left, newleft,
3272 MUIA_Virtgroup_Top, newtop,
3273 TAG_DONE);
3278 ///MUIM_HandleEvent()
3279 /**************************************************************************
3280 MUIM_HandleEvent
3281 **************************************************************************/
3282 IPTR IconList__MUIM_HandleEvent(struct IClass *CLASS, Object *obj, struct MUIP_HandleEvent *message)
3284 struct IconList_DATA *data = INST_DATA(CLASS, obj);
3286 #if defined(DEBUG_ILC_FUNCS)
3287 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
3288 #endif
3290 if (message->imsg)
3292 LONG mx = message->imsg->MouseX - _mleft(obj);
3293 LONG my = message->imsg->MouseY - _mtop(obj);
3295 LONG wheelx = 0;
3296 LONG wheely = 0;
3298 switch (message->imsg->Class)
3300 case IDCMP_RAWKEY:
3302 BOOL rawkey_handled = FALSE;
3304 switch(message->imsg->Code)
3306 case RAWKEY_NM_WHEEL_UP:
3307 wheely = -1;
3308 rawkey_handled = TRUE;
3309 break;
3311 case RAWKEY_NM_WHEEL_DOWN:
3312 wheely = 1;
3313 rawkey_handled = TRUE;
3314 break;
3316 case RAWKEY_NM_WHEEL_LEFT:
3317 wheelx = -1;
3318 rawkey_handled = TRUE;
3319 break;
3321 case RAWKEY_NM_WHEEL_RIGHT:
3322 wheelx = 1;
3323 rawkey_handled = TRUE;
3324 break;
3327 if (rawkey_handled)
3329 #if defined(DEBUG_ILC_KEYEVENTS)
3330 D(bug("[IconList] %s: Processing mouse wheel event\n", __PRETTY_FUNCTION__));
3331 #endif
3332 if (_isinobject(message->imsg->MouseX, message->imsg->MouseY) &&
3333 (wheelx || wheely))
3335 DoWheelMove(CLASS, obj, wheelx, wheely, message->imsg->Qualifier);
3338 else if (!(message->imsg->Code & IECODE_UP_PREFIX))
3340 LONG new_ViewY = data->icld_ViewY;
3341 struct IconEntry *start_entry = NULL, *active_entry = NULL, *entry_next = NULL;
3342 IPTR start_X = 0, start_Y = 0, active_X = 0, active_Y = 0, next_X = 0, next_Y = 0;
3343 IPTR x_diff = 0;
3345 #if defined(DEBUG_ILC_KEYEVENTS)
3346 D(bug("[IconList] %s: Processing key up event\n", __PRETTY_FUNCTION__));
3347 #endif
3349 switch(message->imsg->Code)
3351 case RAWKEY_RETURN:
3352 rawkey_handled = TRUE;
3354 #if defined(DEBUG_ILC_KEYEVENTS)
3355 D(bug("[IconList] %s: RAWKEY_RETURN\n", __PRETTY_FUNCTION__));
3356 #endif
3358 if (data->icld_FocusIcon) active_entry = data->icld_FocusIcon;
3359 else if (data->icld_SelectionLastClicked) active_entry = data->icld_SelectionLastClicked;
3361 if (active_entry)
3363 if (!(active_entry->ie_Flags & ICONENTRY_FLAG_SELECTED))
3365 active_entry->ie_Flags |= ICONENTRY_FLAG_SELECTED;
3366 AddTail(&data->icld_SelectionList, &active_entry->ie_SelectionNode);
3367 data->icld_UpdateMode = UPDATE_SINGLEICON;
3368 data->update_icon = active_entry;
3369 MUI_Redraw(obj, MADF_DRAWUPDATE);
3371 data->icld_SelectionLastClicked = active_entry;
3372 data->icld_FocusIcon = active_entry;
3374 SET(obj, MUIA_IconList_DoubleClick, TRUE);
3376 break;
3378 case RAWKEY_SPACE:
3379 rawkey_handled = TRUE;
3381 #if defined(DEBUG_ILC_KEYEVENTS)
3382 D(bug("[IconList] %s: RAWKEY_SPACE\n", __PRETTY_FUNCTION__));
3383 #endif
3385 if (data->icld_FocusIcon) active_entry = data->icld_FocusIcon;
3386 else if (data->icld_SelectionLastClicked) active_entry = data->icld_SelectionLastClicked;
3388 if (!(message->imsg->Qualifier & IEQUALIFIER_LSHIFT) && ((data->icld_SelectionLastClicked)||(data->icld_SelectionLastClicked != active_entry)))
3390 #if defined(DEBUG_ILC_KEYEVENTS)
3391 D(bug("[IconList] %s: SPACE: Clearing selected icons ..\n", __PRETTY_FUNCTION__));
3392 #endif
3393 DoMethod(obj, MUIM_IconList_UnselectAll);
3396 if (active_entry)
3398 if (!(active_entry->ie_Flags & ICONENTRY_FLAG_SELECTED))
3400 AddTail(&data->icld_SelectionList, &active_entry->ie_SelectionNode);
3401 active_entry->ie_Flags |= ICONENTRY_FLAG_SELECTED;
3402 data->icld_SelectionLastClicked = active_entry;
3404 else
3406 Remove(&active_entry->ie_SelectionNode);
3407 active_entry->ie_Flags &= ~ICONENTRY_FLAG_SELECTED;
3410 data->icld_FocusIcon = active_entry;
3412 data->icld_UpdateMode = UPDATE_SINGLEICON;
3413 data->update_icon = active_entry;
3414 MUI_Redraw(obj, MADF_DRAWUPDATE);
3416 break;
3418 case RAWKEY_PAGEUP:
3419 rawkey_handled = TRUE;
3421 #if defined(DEBUG_ILC_KEYEVENTS)
3422 D(bug("[IconList] %s: RAWKEY_PAGEUP\n", __PRETTY_FUNCTION__));
3423 #endif
3425 if (data->icld_AreaHeight > data->icld_ViewHeight)
3427 new_ViewY -= data->icld_ViewHeight;
3428 if (new_ViewY< 0)
3429 new_ViewY = 0;
3432 if (new_ViewY != data->icld_ViewY)
3434 SET(obj, MUIA_Virtgroup_Top, new_ViewY);
3436 break;
3438 case RAWKEY_PAGEDOWN:
3439 rawkey_handled = TRUE;
3441 #if defined(DEBUG_ILC_KEYEVENTS)
3442 D(bug("[IconList] %s: RAWKEY_PAGEDOWN\n", __PRETTY_FUNCTION__));
3443 #endif
3445 if (data->icld_AreaHeight > data->icld_ViewHeight)
3447 new_ViewY += data->icld_ViewHeight;
3448 if (new_ViewY > (data->icld_AreaHeight - data->icld_ViewHeight))
3449 new_ViewY = data->icld_AreaHeight - data->icld_ViewHeight;
3452 if (new_ViewY != data->icld_ViewY)
3454 SET(obj, MUIA_Virtgroup_Top, new_ViewY);
3456 break;
3458 case RAWKEY_UP:
3459 rawkey_handled = TRUE;
3461 #if defined(DEBUG_ILC_KEYEVENTS)
3462 D(bug("[IconList] %s: RAWKEY_UP\n", __PRETTY_FUNCTION__));
3463 #endif
3465 if (data->icld_FocusIcon)
3467 start_entry = data->icld_FocusIcon;
3468 #if defined(DEBUG_ILC_KEYEVENTS)
3469 D(bug("[IconList] %s: UP: Clearing existing focused icon @ 0x%p\n", __PRETTY_FUNCTION__, start_entry));
3470 #endif
3472 start_entry->ie_Flags &= ~ICONENTRY_FLAG_FOCUS;
3473 data->icld_UpdateMode = UPDATE_SINGLEICON;
3474 data->update_icon = start_entry;
3475 MUI_Redraw(obj, MADF_DRAWUPDATE);
3477 start_X = start_entry->ie_IconX;
3478 start_Y = start_entry->ie_IconY;
3479 #if defined(DEBUG_ILC_KEYEVENTS)
3480 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));
3481 #endif
3482 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
3484 if (start_entry->ie_AreaWidth < data->icld_IconAreaLargestWidth)
3486 start_X = start_X - ((data->icld_IconAreaLargestWidth - start_entry->ie_AreaWidth)/2);
3487 #if defined(DEBUG_ILC_KEYEVENTS)
3488 D(bug("[IconList] %s: UP: adjusted start_X for grid = %d\n", __PRETTY_FUNCTION__, start_X));
3489 #endif
3493 if ((active_entry = Node_PreviousVisible(start_entry)) && !(data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL))
3495 //Check if we are at the edge of the icon area ..
3496 #if defined(DEBUG_ILC_KEYEVENTS)
3497 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));
3498 #endif
3499 active_Y = active_entry->ie_IconY;
3501 if (active_Y == start_Y)
3504 #if defined(DEBUG_ILC_KEYEVENTS)
3505 D(bug("[IconList] %s: UP: active_entry is on our row (not at the edge)\n", __PRETTY_FUNCTION__));
3506 #endif
3507 entry_next = active_entry;
3508 next_X = entry_next->ie_IconX;
3509 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
3511 if (entry_next->ie_AreaWidth < data->icld_IconAreaLargestWidth)
3512 next_X = next_X - ((data->icld_IconAreaLargestWidth - entry_next->ie_AreaWidth)/2);
3516 #if defined(DEBUG_ILC_KEYEVENTS)
3517 D(bug("[IconList] %s: UP: using start_X %d, start_Y %d\n", __PRETTY_FUNCTION__, start_X, start_Y));
3518 #endif
3521 if (!(message->imsg->Qualifier & IEQUALIFIER_LSHIFT) && ((data->icld_SelectionLastClicked)&&(data->icld_SelectionLastClicked != active_entry)))
3523 #if defined(DEBUG_ILC_KEYEVENTS)
3524 D(bug("[IconList] %s: UP: Clearing selected icons ..\n", __PRETTY_FUNCTION__));
3525 #endif
3526 DoMethod(obj, MUIM_IconList_UnselectAll);
3529 #if defined(DEBUG_ILC_KEYEVENTS)
3530 D(bug("[IconList] %s: UP: active = 0x%p, next = 0x%p\n", __PRETTY_FUNCTION__, active_entry, entry_next));
3531 #endif
3532 if (!(active_entry))
3534 // If nothing is selected we will use the last visible icon ..
3535 active_entry = Node_LastVisible(&data->icld_IconList);
3536 start_X = active_entry->ie_IconX;
3537 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
3539 if (active_entry->ie_AreaWidth < data->icld_IconAreaLargestWidth)
3540 start_X = start_X - ((data->icld_IconAreaLargestWidth - active_entry->ie_AreaWidth)/2);
3542 start_Y = active_entry->ie_IconY;
3545 while (active_entry != NULL)
3547 #if defined(DEBUG_ILC_KEYEVENTS)
3548 D(bug("[IconList] %s: UP: Checking active @ 0x%p\n", __PRETTY_FUNCTION__, active_entry));
3549 #endif
3550 if (data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL)
3552 // Return the first visible since the list flow direction matches
3553 // our cursor direction
3554 if (active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE)
3555 break;
3557 else
3559 active_X = active_entry->ie_IconX;
3561 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
3563 if (active_entry->ie_AreaWidth < data->icld_IconAreaLargestWidth)
3564 x_diff = ((data->icld_IconAreaLargestWidth - active_entry->ie_AreaWidth)/2);
3566 active_Y = active_entry->ie_IconY;
3568 if (start_entry)
3570 if (entry_next)
3572 if ((active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE) &&
3573 (active_Y < start_Y) &&
3574 (((active_X - x_diff) >= start_X ) &&
3575 ((active_X - x_diff) <= (start_X + start_entry->ie_AreaWidth + (x_diff*2)))))
3577 #if defined(DEBUG_ILC_KEYEVENTS)
3578 D(bug("[IconList] %s: UP: (A) entry 0x%p matches\n", __PRETTY_FUNCTION__, active_entry));
3579 #endif
3580 break;
3582 else if (active_entry == (struct IconEntry *)GetHead(&data->icld_IconList))
3584 #if defined(DEBUG_ILC_KEYEVENTS)
3585 D(bug("[IconList] %s: UP: (A) reached list start .. restarting from the end ..\n", __PRETTY_FUNCTION__));
3586 #endif
3587 start_X = next_X;
3589 if ((entry_next = Node_PreviousVisible(entry_next)))
3591 if (entry_next->ie_IconX > start_X)
3592 entry_next = NULL;
3593 else
3595 next_X = entry_next->ie_IconX;
3596 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
3598 if (entry_next->ie_AreaWidth < data->icld_IconAreaLargestWidth)
3599 next_X = next_X - ((data->icld_IconAreaLargestWidth - entry_next->ie_AreaWidth)/2);
3603 start_Y = 0;
3604 #if defined(DEBUG_ILC_KEYEVENTS)
3605 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));
3606 #endif
3607 active_entry = Node_LastVisible(&data->icld_IconList);
3610 else
3612 if ((active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE) &&
3613 (active_Y < start_Y) &&
3614 ((active_X + x_diff) < (start_X + start_entry->ie_AreaWidth + x_diff)))
3616 #if defined(DEBUG_ILC_KEYEVENTS)
3617 D(bug("[IconList] %s: UP: (B) entry 0x%p matches\n", __PRETTY_FUNCTION__, active_entry));
3618 #endif
3619 break;
3623 else
3625 if (active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE)
3627 #if defined(DEBUG_ILC_KEYEVENTS)
3628 D(bug("[IconList] %s: UP: (C) entry 0x%p matches\n", __PRETTY_FUNCTION__, active_entry));
3629 #endif
3630 break;
3634 active_entry = (struct IconEntry *)(((struct Node *)active_entry)->ln_Pred);
3637 if (!(active_entry))
3639 #if defined(DEBUG_ILC_KEYEVENTS)
3640 D(bug("[IconList] %s: UP: No Next UP Node - Getting Last visible icon ..\n", __PRETTY_FUNCTION__));
3641 #endif
3642 /* We didnt find a "next UP" icon so just use the last visible */
3643 active_entry = Node_LastVisible(&data->icld_IconList);
3646 if (active_entry)
3648 if (!(active_entry->ie_Flags & ICONENTRY_FLAG_FOCUS))
3650 active_entry->ie_Flags |= ICONENTRY_FLAG_FOCUS;
3651 data->icld_UpdateMode = UPDATE_SINGLEICON;
3652 data->update_icon = active_entry;
3653 MUI_Redraw(obj, MADF_DRAWUPDATE);
3657 data->icld_FocusIcon = active_entry;
3658 break;
3660 case RAWKEY_DOWN:
3661 rawkey_handled = TRUE;
3663 #if defined(DEBUG_ILC_KEYEVENTS)
3664 D(bug("[IconList] %s: RAWKEY_DOWN\n", __PRETTY_FUNCTION__));
3665 #endif
3667 if (data->icld_FocusIcon)
3669 start_entry = data->icld_FocusIcon;
3670 #if defined(DEBUG_ILC_KEYEVENTS)
3671 D(bug("[IconList] %s: DOWN: Clearing existing focused icon @ 0x%p\n", __PRETTY_FUNCTION__, start_entry));
3672 #endif
3674 start_entry->ie_Flags &= ~ICONENTRY_FLAG_FOCUS;
3675 data->icld_UpdateMode = UPDATE_SINGLEICON;
3676 data->update_icon = start_entry;
3677 MUI_Redraw(obj, MADF_DRAWUPDATE);
3679 start_X = start_entry->ie_IconX;
3680 start_Y = start_entry->ie_IconY;
3681 #if defined(DEBUG_ILC_KEYEVENTS)
3682 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));
3683 #endif
3684 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
3686 if (start_entry->ie_AreaWidth < data->icld_IconAreaLargestWidth)
3688 start_X = start_X - ((data->icld_IconAreaLargestWidth - start_entry->ie_AreaWidth)/2);
3689 #if defined(DEBUG_ILC_KEYEVENTS)
3690 D(bug("[IconList] %s: DOWN: adjusted start_X for grid = %d\n", __PRETTY_FUNCTION__, start_X));
3691 #endif
3695 if ((active_entry = Node_NextVisible(start_entry)) &&
3696 (!(data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL)))
3698 #if defined(DEBUG_ILC_KEYEVENTS)
3699 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));
3700 #endif
3701 active_Y = active_entry->ie_IconY;
3703 if (active_Y == start_Y)
3706 #if defined(DEBUG_ILC_KEYEVENTS)
3707 D(bug("[IconList] %s: DOWN: active_entry is on our row (not at the edge)\n", __PRETTY_FUNCTION__));
3708 #endif
3709 entry_next = active_entry;
3710 next_X = entry_next->ie_IconX;
3711 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
3713 if (entry_next->ie_AreaWidth < data->icld_IconAreaLargestWidth)
3714 next_X = next_X - ((data->icld_IconAreaLargestWidth - entry_next->ie_AreaWidth)/2);
3718 #if defined(DEBUG_ILC_KEYEVENTS)
3719 D(bug("[IconList] %s: DOWN: using start_X %d, start_Y %d\n", __PRETTY_FUNCTION__, start_X, start_Y));
3720 #endif
3723 if (!(message->imsg->Qualifier & IEQUALIFIER_LSHIFT) && ((data->icld_SelectionLastClicked)&&(data->icld_SelectionLastClicked != active_entry)))
3725 #if defined(DEBUG_ILC_KEYEVENTS)
3726 D(bug("[IconList] %s: DOWN: Clearing selected icons ..\n", __PRETTY_FUNCTION__));
3727 #endif
3728 DoMethod(obj, MUIM_IconList_UnselectAll);
3731 #if defined(DEBUG_ILC_KEYEVENTS)
3732 D(bug("[IconList] %s: DOWN: active = 0x%p, next = 0x%p\n", __PRETTY_FUNCTION__, active_entry, entry_next));
3733 #endif
3734 if (!(active_entry))
3736 // If nothing is selected we will use the First visible icon ..
3737 active_entry = Node_FirstVisible(&data->icld_IconList);
3738 start_X = active_entry->ie_IconX;
3739 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
3741 if (active_entry->ie_AreaWidth < data->icld_IconAreaLargestWidth)
3742 start_X = start_X - ((data->icld_IconAreaLargestWidth - active_entry->ie_AreaWidth)/2);
3744 start_Y = active_entry->ie_IconY;
3747 while (active_entry != NULL)
3749 #if defined(DEBUG_ILC_KEYEVENTS)
3750 D(bug("[IconList] %s: DOWN: Checking active @ 0x%p\n", __PRETTY_FUNCTION__, active_entry));
3751 #endif
3752 if (data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL)
3754 if (active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE)
3755 break;
3757 else
3759 active_X = active_entry->ie_IconX;
3761 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
3763 if (active_entry->ie_AreaWidth < data->icld_IconAreaLargestWidth)
3764 x_diff = ((data->icld_IconAreaLargestWidth - active_entry->ie_AreaWidth)/2);
3766 active_Y = active_entry->ie_IconY;
3768 if (start_entry)
3770 if (entry_next)
3772 if ((active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE) &&
3773 (active_Y > start_Y) &&
3774 (((active_X - x_diff) >= start_X ) &&
3775 ((active_X - x_diff) <= (start_X + start_entry->ie_AreaWidth + (x_diff*2)))))
3777 #if defined(DEBUG_ILC_KEYEVENTS)
3778 D(bug("[IconList] %s: DOWN: (A) entry 0x%p matches\n", __PRETTY_FUNCTION__, active_entry));
3779 #endif
3780 break;
3782 else if (active_entry == (struct IconEntry *)GetTail(&data->icld_IconList))
3784 #if defined(DEBUG_ILC_KEYEVENTS)
3785 D(bug("[IconList] %s: DOWN: (A) reached list end .. starting at the beginng ..\n", __PRETTY_FUNCTION__));
3786 #endif
3787 start_X = entry_next->ie_IconX;
3788 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
3790 if (entry_next->ie_AreaWidth < data->icld_IconAreaLargestWidth)
3791 start_X = start_X - ((data->icld_IconAreaLargestWidth - entry_next->ie_AreaWidth)/2);
3794 if ((entry_next = (struct IconEntry *)Node_NextVisible(entry_next)))
3796 if (entry_next->ie_IconX < start_X)
3797 entry_next = NULL;
3798 else
3800 next_X = entry_next->ie_IconX;
3801 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
3803 if (entry_next->ie_AreaWidth < data->icld_IconAreaLargestWidth)
3804 next_X = next_X + ((data->icld_IconAreaLargestWidth - entry_next->ie_AreaWidth)/2);
3808 start_Y = 0;
3809 #if defined(DEBUG_ILC_KEYEVENTS)
3810 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));
3811 #endif
3812 active_entry = Node_FirstVisible(&data->icld_IconList);
3815 else
3817 if ((active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE) &&
3818 (active_Y > start_Y) &&
3819 (active_X > start_X - 1))
3821 #if defined(DEBUG_ILC_KEYEVENTS)
3822 D(bug("[IconList] %s: DOWN: (B) entry 0x%p matches\n", __PRETTY_FUNCTION__, active_entry));
3823 #endif
3824 break;
3828 else
3830 if (active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE)
3832 #if defined(DEBUG_ILC_KEYEVENTS)
3833 D(bug("[IconList] %s: DOWN: (C) entry 0x%p matches\n", __PRETTY_FUNCTION__, active_entry));
3834 #endif
3835 break;
3839 active_entry = (struct IconEntry *)GetSucc(&active_entry->ie_IconNode);
3842 if (!(active_entry))
3844 #if defined(DEBUG_ILC_KEYEVENTS)
3845 D(bug("[IconList] %s: DOWN: No Next DOWN Node - Getting first visable icon ..\n", __PRETTY_FUNCTION__));
3846 #endif
3847 /* We didnt find a "next DOWN" icon so just use the first visible */
3848 active_entry = Node_FirstVisible(&data->icld_IconList);
3851 if (active_entry)
3853 if (!(active_entry->ie_Flags & ICONENTRY_FLAG_FOCUS))
3855 active_entry->ie_Flags |= ICONENTRY_FLAG_FOCUS;
3856 data->icld_UpdateMode = UPDATE_SINGLEICON;
3857 data->update_icon = active_entry;
3858 MUI_Redraw(obj, MADF_DRAWUPDATE);
3862 data->icld_FocusIcon = active_entry;
3863 break;
3865 case RAWKEY_LEFT:
3866 rawkey_handled = TRUE;
3868 #if defined(DEBUG_ILC_KEYEVENTS)
3869 D(bug("[IconList] %s: RAWKEY_LEFT\n", __PRETTY_FUNCTION__));
3870 #endif
3872 if (data->icld_FocusIcon)
3874 start_entry = data->icld_FocusIcon;
3875 #if defined(DEBUG_ILC_KEYEVENTS)
3876 D(bug("[IconList] %s: LEFT: Clearing existing focused icon @ 0x%p\n", __PRETTY_FUNCTION__, start_entry));
3877 #endif
3879 start_entry->ie_Flags &= ~ICONENTRY_FLAG_FOCUS;
3880 data->icld_UpdateMode = UPDATE_SINGLEICON;
3881 data->update_icon = start_entry;
3882 MUI_Redraw(obj, MADF_DRAWUPDATE);
3884 start_X = start_entry->ie_IconX;
3885 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
3887 if (start_entry->ie_AreaWidth < data->icld_IconAreaLargestWidth)
3888 start_X = start_X - ((data->icld_IconAreaLargestWidth - start_entry->ie_AreaWidth)/2);
3890 start_Y = start_entry->ie_IconY;
3892 #if defined(DEBUG_ILC_KEYEVENTS)
3893 D(bug("[IconList] %s: LEFT: start_X %d, start_Y %d\n", __PRETTY_FUNCTION__, start_X, start_Y));
3894 #endif
3896 if (!(active_entry = Node_NextVisible(start_entry)) && (!(data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL)))
3898 active_entry = (struct IconEntry *)GetHead(&data->icld_IconList);
3899 #if defined(DEBUG_ILC_KEYEVENTS)
3900 D(bug("[IconList] %s: LEFT: Start at the beginning (Active @ 0x%p) using icon X + Width\n", __PRETTY_FUNCTION__, active_entry));
3901 #endif
3902 start_X = start_X + start_entry->ie_AreaWidth;
3903 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
3905 if (start_entry->ie_AreaWidth < data->icld_IconAreaLargestWidth)
3906 start_X = start_X + ((data->icld_IconAreaLargestWidth - start_entry->ie_AreaWidth)/2);
3909 start_Y = 0;
3910 entry_next = NULL;
3912 else if (active_entry && (!(data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL)))
3914 #if defined(DEBUG_ILC_KEYEVENTS)
3915 D(bug("[IconList] %s: LEFT: Active @ 0x%p, X %d\n", __PRETTY_FUNCTION__, active_entry, active_entry->ie_IconX));
3916 #endif
3917 if ((entry_next = Node_NextVisible(start_entry)))
3919 #if defined(DEBUG_ILC_KEYEVENTS)
3920 D(bug("[IconList] %s: LEFT: Next @ 0x%p, X %d\n", __PRETTY_FUNCTION__, entry_next, entry_next->ie_IconX));
3921 #endif
3923 if (entry_next->ie_IconX < start_X)
3924 entry_next = NULL;
3925 else
3927 next_X = entry_next->ie_IconX;
3928 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
3930 if (entry_next->ie_AreaWidth < data->icld_IconAreaLargestWidth)
3931 next_X = next_X - ((data->icld_IconAreaLargestWidth - entry_next->ie_AreaWidth)/2);
3936 #if defined(DEBUG_ILC_KEYEVENTS)
3937 D(bug("[IconList] %s: LEFT: using start_X %d, start_Y %d\n", __PRETTY_FUNCTION__, start_X, start_Y));
3938 #endif
3941 if (!(message->imsg->Qualifier & IEQUALIFIER_LSHIFT) && ((data->icld_SelectionLastClicked)&&(data->icld_SelectionLastClicked != active_entry)))
3943 #if defined(DEBUG_ILC_KEYEVENTS)
3944 D(bug("[IconList] %s: LEFT: Clearing selected icons ..\n", __PRETTY_FUNCTION__));
3945 #endif
3946 DoMethod(obj, MUIM_IconList_UnselectAll);
3949 #if defined(DEBUG_ILC_KEYEVENTS)
3950 D(bug("[IconList] %s: LEFT: active = 0x%p, next = 0x%p\n", __PRETTY_FUNCTION__, active_entry, entry_next));
3951 #endif
3953 if (!(active_entry))
3955 active_entry = (struct IconEntry *)GetHead(&data->icld_IconList);
3958 while (active_entry != NULL)
3960 #if defined(DEBUG_ILC_KEYEVENTS)
3961 D(bug("[IconList] %s: LEFT: Checking active @ 0x%p\n", __PRETTY_FUNCTION__, active_entry));
3962 #endif
3963 if (data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL)
3965 if (active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE)
3966 break;
3968 else
3970 LONG active_entry_X = active_entry->ie_IconX;
3971 LONG active_entry_Y;
3972 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
3974 if (active_entry->ie_AreaWidth < data->icld_IconAreaLargestWidth)
3975 active_entry_X = active_entry_X - ((data->icld_IconAreaLargestWidth - active_entry->ie_AreaWidth)/2);
3977 active_entry_Y = active_entry->ie_IconY;
3979 if (start_entry)
3981 if (entry_next)
3983 if ((active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE) &&
3984 (active_entry_Y > start_Y) &&
3985 ((active_entry_X > start_X - 1) &&
3986 (active_entry_X < next_X)))
3988 #if defined(DEBUG_ILC_KEYEVENTS)
3989 D(bug("[IconList] %s: LEFT: (A) entry 0x%p matches\n", __PRETTY_FUNCTION__, active_entry));
3990 #endif
3991 break;
3993 else if (active_entry == (struct IconEntry *)GetTail(&data->icld_IconList))
3995 #if defined(DEBUG_ILC_KEYEVENTS)
3996 D(bug("[IconList] %s: LEFT: (A) reached list end .. starting at the beginng ..\n", __PRETTY_FUNCTION__));
3997 #endif
3998 start_X = entry_next->ie_IconX;
3999 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
4001 if (entry_next->ie_AreaWidth < data->icld_IconAreaLargestWidth)
4002 start_X = start_X - ((data->icld_IconAreaLargestWidth - entry_next->ie_AreaWidth)/2);
4005 if ((entry_next = Node_NextVisible(entry_next)))
4007 if (entry_next->ie_IconX < start_X)
4008 entry_next = NULL;
4009 else
4011 next_X = entry_next->ie_IconX;
4012 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
4014 if (entry_next->ie_AreaWidth < data->icld_IconAreaLargestWidth)
4015 next_X = next_X + ((data->icld_IconAreaLargestWidth - entry_next->ie_AreaWidth)/2);
4019 start_Y = 0;
4020 #if defined(DEBUG_ILC_KEYEVENTS)
4021 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));
4022 #endif
4023 active_entry = (struct IconEntry *)GetHead(&data->icld_IconList);
4026 else
4028 if ((active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE) &&
4029 (active_entry_Y > start_Y) &&
4030 (active_entry_X > start_X - 1))
4032 #if defined(DEBUG_ILC_KEYEVENTS)
4033 D(bug("[IconList] %s: LEFT: (B) entry 0x%p matches\n", __PRETTY_FUNCTION__, active_entry));
4034 #endif
4035 break;
4039 else
4041 if (active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE)
4043 #if defined(DEBUG_ILC_KEYEVENTS)
4044 D(bug("[IconList] %s: LEFT: (C) entry 0x%p matches\n", __PRETTY_FUNCTION__, active_entry));
4045 #endif
4046 break;
4050 active_entry = (struct IconEntry *)GetSucc(&active_entry->ie_IconNode);
4053 if (!(active_entry))
4055 #if defined(DEBUG_ILC_KEYEVENTS)
4056 D(bug("[IconList] %s: LEFT: No Next LEFT Node - Getting first visable icon ..\n", __PRETTY_FUNCTION__));
4057 #endif
4058 /* We didnt find a "next LEFT" icon so just use the last visible */
4059 active_entry = (struct IconEntry *)GetHead(&data->icld_IconList);
4060 while ((active_entry != NULL) &&(!(active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE)))
4062 active_entry = (struct IconEntry *)GetSucc(&active_entry->ie_IconNode);
4066 if (active_entry)
4068 if (!(active_entry->ie_Flags & ICONENTRY_FLAG_FOCUS))
4070 active_entry->ie_Flags |= ICONENTRY_FLAG_FOCUS;
4071 data->icld_UpdateMode = UPDATE_SINGLEICON;
4072 data->update_icon = active_entry;
4073 MUI_Redraw(obj, MADF_DRAWUPDATE);
4077 data->icld_FocusIcon = active_entry;
4078 break;
4080 case RAWKEY_RIGHT:
4081 rawkey_handled = TRUE;
4083 #if defined(DEBUG_ILC_KEYEVENTS)
4084 D(bug("[IconList] %s: RAWKEY_RIGHT\n", __PRETTY_FUNCTION__));
4085 #endif
4087 if (data->icld_FocusIcon)
4089 start_entry = data->icld_FocusIcon;
4090 #if defined(DEBUG_ILC_KEYEVENTS)
4091 D(bug("[IconList] %s: RIGHT: Clearing existing focused icon @ 0x%p\n", __PRETTY_FUNCTION__, start_entry));
4092 #endif
4093 start_entry->ie_Flags &= ~ICONENTRY_FLAG_FOCUS;
4094 data->icld_UpdateMode = UPDATE_SINGLEICON;
4095 data->update_icon = start_entry;
4096 MUI_Redraw(obj, MADF_DRAWUPDATE);
4098 start_X = start_entry->ie_IconX;
4099 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
4101 if (start_entry->ie_AreaWidth < data->icld_IconAreaLargestWidth)
4102 start_X = start_X - ((data->icld_IconAreaLargestWidth - start_entry->ie_AreaWidth)/2);
4104 start_Y = start_entry->ie_IconY;
4106 #if defined(DEBUG_ILC_KEYEVENTS)
4107 D(bug("[IconList] %s: RIGHT: start_X %d, start_Y %d\n", __PRETTY_FUNCTION__, start_X, start_Y));
4108 #endif
4109 if (!(active_entry = Node_NextVisible(start_entry)) && (!(data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL)))
4111 active_entry = (struct IconEntry *)GetHead(&data->icld_IconList);
4112 #if defined(DEBUG_ILC_KEYEVENTS)
4113 D(bug("[IconList] %s: RIGHT: Start at the beginning (Active @ 0x%p) using icon X + Width\n", __PRETTY_FUNCTION__, active_entry));
4114 #endif
4115 start_X = 0;
4116 start_Y = start_Y + start_entry->ie_AreaHeight;
4117 entry_next = NULL;
4119 else if (active_entry && (data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL))
4121 #if defined(DEBUG_ILC_KEYEVENTS)
4122 D(bug("[IconList] %s: RIGHT: Active @ 0x%p, X %d\n", __PRETTY_FUNCTION__, active_entry, active_entry->ie_IconX));
4123 #endif
4124 if ((entry_next = Node_NextVisible(start_entry)))
4126 #if defined(DEBUG_ILC_KEYEVENTS)
4127 D(bug("[IconList] %s: RIGHT: Next @ 0x%p, X %d\n", __PRETTY_FUNCTION__, entry_next, entry_next->ie_IconX));
4128 #endif
4130 if (entry_next->ie_IconY < start_Y)
4131 entry_next = NULL;
4132 else
4133 next_Y = entry_next->ie_IconY;
4136 #if defined(DEBUG_ILC_KEYEVENTS)
4137 D(bug("[IconList] %s: RIGHT: using start_X %d, start_Y %d\n", __PRETTY_FUNCTION__, start_X, start_Y));
4138 #endif
4141 if (!(message->imsg->Qualifier & IEQUALIFIER_LSHIFT) && ((data->icld_SelectionLastClicked)&&(data->icld_SelectionLastClicked != active_entry)))
4143 #if defined(DEBUG_ILC_KEYEVENTS)
4144 D(bug("[IconList] %s: RIGHT: Clearing selected icons ..\n", __PRETTY_FUNCTION__));
4145 #endif
4146 DoMethod(obj, MUIM_IconList_UnselectAll);
4149 #if defined(DEBUG_ILC_KEYEVENTS)
4150 D(bug("[IconList] %s: RIGHT: active = 0x%p, next = 0x%p\n", __PRETTY_FUNCTION__, active_entry, entry_next));
4151 #endif
4153 if (!(active_entry))
4155 active_entry = (struct IconEntry *)GetHead(&data->icld_IconList);
4158 while (active_entry != NULL)
4160 #if defined(DEBUG_ILC_KEYEVENTS)
4161 D(bug("[IconList] %s: RIGHT: Checking active @ 0x%p\n", __PRETTY_FUNCTION__, active_entry));
4162 #endif
4163 if (!(data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL))
4165 if (active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE)
4166 break;
4168 else
4170 LONG active_entry_X = active_entry->ie_IconX;
4171 LONG active_entry_Y;
4172 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
4174 if (active_entry->ie_AreaWidth < data->icld_IconAreaLargestWidth)
4175 active_entry_X = active_entry_X - ((data->icld_IconAreaLargestWidth - active_entry->ie_AreaWidth)/2);
4177 active_entry_Y = active_entry->ie_IconY;
4179 if (start_entry)
4181 if (entry_next)
4183 if ((active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE) &&
4184 (active_entry_X > start_X) &&
4185 ((active_entry_Y > start_Y - 1) &&
4186 (active_entry_Y < next_Y)))
4188 #if defined(DEBUG_ILC_KEYEVENTS)
4189 D(bug("[IconList] %s: RIGHT: (A) entry 0x%p matches\n", __PRETTY_FUNCTION__, active_entry));
4190 #endif
4191 break;
4193 else if (active_entry == (struct IconEntry *)GetTail(&data->icld_IconList))
4195 #if defined(DEBUG_ILC_KEYEVENTS)
4196 D(bug("[IconList] %s: RIGHT: (A) reached list end .. starting at the beginng ..\n", __PRETTY_FUNCTION__));
4197 #endif
4198 start_Y = entry_next->ie_IconY;
4200 if ((entry_next = Node_NextVisible(entry_next)))
4202 if (entry_next->ie_IconY < start_Y)
4203 entry_next = NULL;
4204 else
4206 next_Y = entry_next->ie_IconY;
4209 start_Y = 0;
4210 #if defined(DEBUG_ILC_KEYEVENTS)
4211 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));
4212 #endif
4213 active_entry = (struct IconEntry *)GetHead(&data->icld_IconList);
4216 else
4218 if ((active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE) &&
4219 (active_entry_X > start_X) &&
4220 (active_entry_Y > start_Y - 1))
4222 #if defined(DEBUG_ILC_KEYEVENTS)
4223 D(bug("[IconList] %s: RIGHT: (B) entry 0x%p matches\n", __PRETTY_FUNCTION__, active_entry));
4224 #endif
4225 break;
4229 else
4231 if (active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE)
4233 #if defined(DEBUG_ILC_KEYEVENTS)
4234 D(bug("[IconList] %s: RIGHT: (C) entry 0x%p matches\n", __PRETTY_FUNCTION__, active_entry));
4235 #endif
4236 break;
4240 active_entry = (struct IconEntry *)GetSucc(&active_entry->ie_IconNode);
4243 if (!(active_entry))
4245 #if defined(DEBUG_ILC_KEYEVENTS)
4246 D(bug("[IconList] %s: RIGHT: No Next RIGHT Node - Getting first visable icon ..\n", __PRETTY_FUNCTION__));
4247 #endif
4248 /* We didnt find a "next RIGHT" icon so just use the first visible */
4249 active_entry = (struct IconEntry *)GetHead(&data->icld_IconList);
4250 while ((active_entry != NULL) &&(!(active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE)))
4252 active_entry = (struct IconEntry *)GetSucc(&active_entry->ie_IconNode);
4256 if (active_entry)
4258 if (!(active_entry->ie_Flags & ICONENTRY_FLAG_FOCUS))
4260 active_entry->ie_Flags |= ICONENTRY_FLAG_FOCUS;
4261 data->icld_UpdateMode = UPDATE_SINGLEICON;
4262 data->update_icon = active_entry;
4263 MUI_Redraw(obj, MADF_DRAWUPDATE);
4267 data->icld_FocusIcon = active_entry;
4268 break;
4270 case RAWKEY_HOME:
4271 rawkey_handled = TRUE;
4273 #if defined(DEBUG_ILC_KEYEVENTS)
4274 D(bug("[IconList] %s: RAWKEY_HOME\n", __PRETTY_FUNCTION__));
4275 #endif
4277 if (data->icld_FocusIcon)
4279 data->icld_FocusIcon->ie_Flags &= ~ICONENTRY_FLAG_FOCUS;
4280 data->icld_UpdateMode = UPDATE_SINGLEICON;
4281 data->update_icon = data->icld_FocusIcon;
4282 MUI_Redraw(obj, MADF_DRAWUPDATE);
4285 active_entry = Node_FirstVisible(&data->icld_IconList);
4287 if ((active_entry) && (!(active_entry->ie_Flags & ICONENTRY_FLAG_FOCUS)))
4289 active_entry->ie_Flags |= ICONENTRY_FLAG_FOCUS;
4290 data->icld_UpdateMode = UPDATE_SINGLEICON;
4291 data->update_icon = active_entry;
4292 MUI_Redraw(obj, MADF_DRAWUPDATE);
4294 data->icld_FocusIcon = active_entry;
4295 break;
4297 case RAWKEY_END:
4298 rawkey_handled = TRUE;
4300 #if defined(DEBUG_ILC_KEYEVENTS)
4301 D(bug("[IconList] %s: RAWKEY_END\n", __PRETTY_FUNCTION__));
4302 #endif
4304 if (data->icld_FocusIcon)
4306 data->icld_FocusIcon->ie_Flags &= ~ICONENTRY_FLAG_FOCUS;
4307 data->icld_UpdateMode = UPDATE_SINGLEICON;
4308 data->update_icon = data->icld_FocusIcon;
4309 MUI_Redraw(obj, MADF_DRAWUPDATE);
4312 active_entry = Node_LastVisible(&data->icld_IconList);
4314 if ((active_entry) && (!(active_entry->ie_Flags & ICONENTRY_FLAG_FOCUS)))
4316 active_entry->ie_Flags |= ICONENTRY_FLAG_FOCUS;
4317 data->icld_UpdateMode = UPDATE_SINGLEICON;
4318 data->update_icon = active_entry;
4319 MUI_Redraw(obj, MADF_DRAWUPDATE);
4321 data->icld_FocusIcon = active_entry;
4322 break;
4325 if (rawkey_handled) return MUI_EventHandlerRC_Eat;
4327 break;
4329 case IDCMP_MOUSEBUTTONS:
4331 if (message->imsg->Code == SELECTDOWN)
4333 /* check if mouse pressed on iconlist area */
4334 if (mx >= 0 && mx < _width(obj) && my >= 0 && my < _height(obj))
4336 struct IconEntry *node = NULL;
4337 struct IconEntry *new_selected = NULL;
4338 struct Rectangle rect;
4340 // int selections = 0;
4341 BOOL icon_doubleclicked;
4343 /* check if clicked on icon */
4344 #ifdef __AROS__
4345 ForeachNode(&data->icld_IconList, node)
4346 #else
4347 Foreach_Node(&data->icld_IconList, node);
4348 #endif
4350 if (node->ie_Flags & ICONENTRY_FLAG_VISIBLE)
4352 BOOL update_icon = FALSE;
4354 rect.MinX = node->ie_IconX;
4355 rect.MaxX = node->ie_IconX + node->ie_AreaWidth - 1;
4356 rect.MinY = node->ie_IconY;
4357 rect.MaxY = node->ie_IconY + node->ie_AreaHeight - 1;
4359 if ((data->icld__Option_IconListMode == ICON_LISTMODE_GRID) &&
4360 (node->ie_AreaWidth < data->icld_IconAreaLargestWidth))
4362 rect.MinX += ((data->icld_IconAreaLargestWidth - node->ie_AreaWidth)/2);
4363 rect.MaxX += ((data->icld_IconAreaLargestWidth - node->ie_AreaWidth)/2);
4366 if ((((mx + data->icld_ViewX) >= rect.MinX) && ((mx + data->icld_ViewX) <= rect.MaxX )) &&
4367 (((my + data->icld_ViewY) >= rect.MinY) && ((my + data->icld_ViewY) <= rect.MaxY )) &&
4368 !new_selected)
4370 new_selected = node;
4371 #if defined(DEBUG_ILC_EVENTS)
4372 D(bug("[IconList] %s: Icon '%s' clicked on ..\n", __PRETTY_FUNCTION__, node->ie_IconListEntry.label));
4373 #endif
4376 if (node->ie_Flags & ICONENTRY_FLAG_SELECTED)
4378 if ((new_selected != node) &&
4379 (!(message->imsg->Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))))
4381 Remove(&node->ie_SelectionNode);
4382 node->ie_Flags &= ~ICONENTRY_FLAG_SELECTED;
4383 update_icon = TRUE;
4387 if ((node->ie_Flags & ICONENTRY_FLAG_FOCUS) && (new_selected != node))
4389 node->ie_Flags &= ~ICONENTRY_FLAG_FOCUS;
4390 update_icon = TRUE;
4393 if (update_icon)
4395 data->icld_UpdateMode = UPDATE_SINGLEICON;
4396 data->update_icon = node;
4397 MUI_Redraw(obj, MADF_DRAWUPDATE);
4398 #if defined(DEBUG_ILC_EVENTS)
4399 D(bug("[IconList] %s: Rendered icon '%s'\n", __PRETTY_FUNCTION__, node->ie_IconListEntry.label));
4400 #endif
4405 icon_doubleclicked = FALSE;
4407 if ((DoubleClick(data->last_secs, data->last_mics, message->imsg->Seconds, message->imsg->Micros)) && (data->icld_SelectionLastClicked == new_selected))
4409 D(bug("[IconList] %s: Icon double-clicked\n", __PRETTY_FUNCTION__));
4410 icon_doubleclicked = TRUE;
4413 if (new_selected == NULL)
4415 /* No icon clicked on ... Start Lasso-selection */
4416 data->icld_LassoActive = TRUE;
4417 if (!(message->imsg->Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT)))
4419 data->icld_SelectionLastClicked = NULL;
4420 data->icld_FocusIcon = NULL;
4422 data->icld_LassoRectangle.MinX = mx - data->view_rect.MinX + data->icld_ViewX;
4423 data->icld_LassoRectangle.MinY = my - data->view_rect.MinY + data->icld_ViewY;
4424 data->icld_LassoRectangle.MaxX = mx - data->view_rect.MinX + data->icld_ViewX;
4425 data->icld_LassoRectangle.MaxY = my - data->view_rect.MinY + data->icld_ViewY;
4427 /* Draw initial Lasso frame */
4428 IconList_InvertLassoOutlines(obj, &data->icld_LassoRectangle);
4430 else
4432 struct IconEntry *update_icon = NULL;
4434 data->icld_LassoActive = FALSE;
4436 if (!(new_selected->ie_Flags & ICONENTRY_FLAG_SELECTED))
4438 AddTail(&data->icld_SelectionList, &new_selected->ie_SelectionNode);
4439 new_selected->ie_Flags |= ICONENTRY_FLAG_SELECTED;
4440 update_icon = new_selected;
4442 if (!(new_selected->ie_Flags & ICONENTRY_FLAG_FOCUS))
4444 new_selected->ie_Flags |= ICONENTRY_FLAG_FOCUS;
4445 update_icon = new_selected;
4446 data->icld_FocusIcon = new_selected;
4449 else if ((icon_doubleclicked == FALSE) && (message->imsg->Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT)))
4451 Remove(&new_selected->ie_SelectionNode);
4452 new_selected->ie_Flags &= ~ICONENTRY_FLAG_SELECTED;
4453 update_icon = new_selected;
4454 new_selected = NULL;
4457 if (update_icon != NULL)
4459 data->icld_UpdateMode = UPDATE_SINGLEICON;
4460 data->update_icon = update_icon;
4461 MUI_Redraw(obj, MADF_DRAWUPDATE);
4462 #if defined(DEBUG_ILC_EVENTS)
4463 D(bug("[IconList] %s: Rendered 'new_selected' icon '%s'\n", __PRETTY_FUNCTION__, update_icon->ie_IconListEntry.label));
4464 #endif
4468 data->icld_ClickEvent.shift = !!(message->imsg->Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT));
4469 data->icld_ClickEvent.entry = new_selected ? &new_selected->ie_IconListEntry : NULL;
4470 SET(obj, MUIA_IconList_Clicked, (IPTR)&data->icld_ClickEvent);
4472 if (icon_doubleclicked)
4474 SET(obj, MUIA_IconList_DoubleClick, TRUE);
4476 else if (!data->mouse_pressed)
4478 data->last_secs = message->imsg->Seconds;
4479 data->last_mics = message->imsg->Micros;
4481 /* After a double click you often open a new window
4482 * and since Zune doesn't not support the faking
4483 * of SELECTUP events only change the Events
4484 * if not doubleclicked */
4486 data->mouse_pressed |= LEFT_BUTTON;
4488 if (!(data->ehn.ehn_Events & IDCMP_MOUSEMOVE))
4490 DoMethod(_win(obj), MUIM_Window_RemEventHandler, (IPTR)&data->ehn);
4491 data->ehn.ehn_Events |= IDCMP_MOUSEMOVE;
4492 DoMethod(_win(obj), MUIM_Window_AddEventHandler, (IPTR)&data->ehn);
4496 data->icld_SelectionLastClicked = new_selected;
4498 data->click_x = mx;
4499 data->click_y = my;
4501 SET(obj, MUIA_IconList_SelectionChanged, TRUE);
4503 return MUI_EventHandlerRC_Eat;
4506 else if (message->imsg->Code == MIDDLEDOWN)
4508 if (!data->mouse_pressed)
4510 data->mouse_pressed |= MIDDLE_BUTTON;
4512 data->click_x = data->icld_ViewX + mx;
4513 data->click_y = data->icld_ViewY + my;
4515 if (!(data->ehn.ehn_Events & IDCMP_MOUSEMOVE))
4517 DoMethod(_win(obj), MUIM_Window_RemEventHandler, (IPTR)&data->ehn);
4518 data->ehn.ehn_Events |= IDCMP_MOUSEMOVE;
4519 DoMethod(_win(obj), MUIM_Window_AddEventHandler, (IPTR)&data->ehn);
4523 else
4525 if (message->imsg->Code == SELECTUP)
4527 if (data->icld_LassoActive == TRUE)
4529 // End Lasso-selection
4530 struct Rectangle old_lasso;
4531 struct IconEntry *node = NULL;
4533 //Clear Lasso Frame..
4534 GetAbsoluteLassoRect(data, &old_lasso);
4535 IconList_InvertLassoOutlines(obj, &old_lasso);
4537 data->icld_LassoActive = FALSE;
4539 //Remove Lasso flag from affected icons..
4540 #ifdef __AROS__
4541 ForeachNode(&data->icld_IconList, node)
4542 #else
4543 Foreach_Node(&data->icld_IconList, node);
4544 #endif
4546 if (node->ie_Flags & ICONENTRY_FLAG_LASSO)
4548 node->ie_Flags &= ~ICONENTRY_FLAG_LASSO;
4551 SET(obj, MUIA_IconList_SelectionChanged, TRUE);
4554 data->mouse_pressed &= ~LEFT_BUTTON;
4557 if (message->imsg->Code == MIDDLEUP)
4559 data->mouse_pressed &= ~MIDDLE_BUTTON;
4562 if ((data->ehn.ehn_Events & IDCMP_MOUSEMOVE) && !data->mouse_pressed)
4564 DoMethod(_win(obj),MUIM_Window_RemEventHandler, (IPTR)&data->ehn);
4565 data->ehn.ehn_Events &= ~IDCMP_MOUSEMOVE;
4566 DoMethod(_win(obj),MUIM_Window_AddEventHandler, (IPTR)&data->ehn);
4569 break;
4571 case IDCMP_MOUSEMOVE:
4573 if (data->mouse_pressed & LEFT_BUTTON)
4575 LONG move_x = mx;
4576 LONG move_y = my;
4578 if (data->icld_SelectionLastClicked && (data->icld_LassoActive == FALSE) &&
4579 ((abs(move_x - data->click_x) >= 2) || (abs(move_y - data->click_y) >= 2)))
4581 // Icon(s) being dragged ....
4582 DoMethod(_win(obj),MUIM_Window_RemEventHandler, (IPTR)&data->ehn);
4583 data->ehn.ehn_Events &= ~IDCMP_MOUSEMOVE;
4584 DoMethod(_win(obj),MUIM_Window_AddEventHandler, (IPTR)&data->ehn);
4586 data->mouse_pressed &= ~LEFT_BUTTON;
4588 data->touch_x = move_x + data->icld_ViewX - data->icld_SelectionLastClicked->ie_IconX;
4589 data->touch_y = move_y + data->icld_ViewY - data->icld_SelectionLastClicked->ie_IconY;
4590 DoMethod(obj,MUIM_DoDrag, data->touch_x, data->touch_y, 0);
4592 else if (data->icld_LassoActive == TRUE)
4594 //Lasso active ..
4595 struct Rectangle new_lasso,
4596 old_lasso;
4597 struct Rectangle iconrect;
4599 struct IconEntry *node = NULL;
4600 // struct IconEntry *new_selected = NULL;
4602 /* Remove previous Lasso frame */
4603 GetAbsoluteLassoRect(data, &old_lasso);
4604 IconList_InvertLassoOutlines(obj, &old_lasso);
4606 /* if the mouse leaves our visible area scroll the view */
4607 if (mx < 0 || mx >= _mwidth(obj) || my < 0 || my >= _mheight(obj))
4609 LONG newleft = data->icld_ViewX;
4610 LONG newtop = data->icld_ViewY;
4612 if (mx >= _mwidth(obj)) newleft += 5;
4613 else if (mx < 0) newleft -= 5;
4614 if (my >= _mheight(obj)) newtop += 5;
4615 else if (my < 0) newtop -= 5;
4617 if (newleft + _mwidth(obj) > data->icld_AreaWidth) newleft = data->icld_AreaWidth - _mwidth(obj);
4618 if (newleft < 0) newleft = 0;
4620 if (newtop + _mheight(obj) > data->icld_AreaHeight) newtop = data->icld_AreaHeight - _mheight(obj);
4621 if (newtop < 0) newtop = 0;
4623 if ((newleft != data->icld_ViewX) || (newtop != data->icld_ViewY))
4625 SetAttrs(obj, MUIA_Virtgroup_Left, newleft, MUIA_Virtgroup_Top, newtop, TAG_DONE);
4629 /* update Lasso coordinates */
4630 data->icld_LassoRectangle.MaxX = mx - data->view_rect.MinX + data->icld_ViewX;
4631 data->icld_LassoRectangle.MaxY = my - data->view_rect.MinY + data->icld_ViewY;
4633 /* get absolute Lasso coordinates */
4634 GetAbsoluteLassoRect(data, &new_lasso);
4636 #ifdef __AROS__
4637 ForeachNode(&data->icld_IconList, node)
4638 #else
4639 Foreach_Node(&data->icld_IconList, node);
4640 #endif
4642 IPTR update_icon = (IPTR)NULL;
4644 if (node->ie_Flags & ICONENTRY_FLAG_VISIBLE)
4646 iconrect.MinX = node->ie_IconX;
4647 iconrect.MaxX = node->ie_IconX + node->ie_AreaWidth - 1;
4648 iconrect.MinY = node->ie_IconY;
4649 iconrect.MaxY = node->ie_IconY + node->ie_AreaHeight - 1;
4650 if ((data->icld__Option_IconListMode == ICON_LISTMODE_GRID) &&
4651 (node->ie_AreaWidth < data->icld_IconAreaLargestWidth))
4653 iconrect.MinX += ((data->icld_IconAreaLargestWidth - node->ie_AreaWidth)/2);
4654 iconrect.MaxX += ((data->icld_IconAreaLargestWidth - node->ie_AreaWidth)/2);
4657 if ((((new_lasso.MaxX + data->icld_ViewX) >= iconrect.MinX) && ((new_lasso.MinX + data->icld_ViewX) <= iconrect.MaxX)) &&
4658 (((new_lasso.MaxY + data->icld_ViewY) >= iconrect.MinY) && ((new_lasso.MinY + data->icld_ViewY) <= iconrect.MaxY)))
4660 //Icon is inside our lasso ..
4661 if (!(node->ie_Flags & ICONENTRY_FLAG_LASSO))
4663 /* check if icon was already selected before */
4664 if (node->ie_Flags & ICONENTRY_FLAG_SELECTED)
4666 Remove(&node->ie_SelectionNode);
4667 node->ie_Flags &= ~ICONENTRY_FLAG_SELECTED;
4669 else
4671 AddTail(&data->icld_SelectionList, &node->ie_SelectionNode);
4672 node->ie_Flags |= ICONENTRY_FLAG_SELECTED;
4674 node->ie_Flags |= ICONENTRY_FLAG_LASSO;
4675 update_icon = (IPTR)node;
4678 else if (node->ie_Flags & ICONENTRY_FLAG_LASSO)
4680 //Icon is no longer inside our lasso - revert its selected state
4681 if (node->ie_Flags & ICONENTRY_FLAG_SELECTED)
4683 Remove(&node->ie_SelectionNode);
4684 node->ie_Flags &= ~ICONENTRY_FLAG_SELECTED;
4686 else
4688 AddTail(&data->icld_SelectionList, &node->ie_SelectionNode);
4689 node->ie_Flags |= ICONENTRY_FLAG_SELECTED;
4691 node->ie_Flags &= ~ICONENTRY_FLAG_LASSO;
4692 update_icon = (IPTR)node;
4695 if (update_icon)
4697 data->icld_UpdateMode = UPDATE_SINGLEICON;
4698 data->update_icon = (struct IconEntry *)update_icon;
4699 MUI_Redraw(obj, MADF_DRAWUPDATE);
4703 /* Draw Lasso frame */
4704 IconList_InvertLassoOutlines(obj, &new_lasso);
4707 return MUI_EventHandlerRC_Eat;
4709 else if (data->mouse_pressed & MIDDLE_BUTTON)
4711 LONG newleft,
4712 newtop;
4714 newleft = data->click_x - mx;
4715 newtop = data->click_y - my;
4717 if (newleft + _mwidth(obj) > data->icld_AreaWidth) newleft = data->icld_AreaWidth - _mwidth(obj);
4718 if (newleft < 0) newleft = 0;
4720 if (newtop + _mheight(obj) > data->icld_AreaHeight) newtop = data->icld_AreaHeight - _mheight(obj);
4721 if (newtop < 0) newtop = 0;
4723 if ((newleft != data->icld_ViewX) || (newtop != data->icld_ViewY))
4725 SetAttrs(obj, MUIA_Virtgroup_Left, newleft,
4726 MUIA_Virtgroup_Top, newtop,
4727 TAG_DONE);
4730 return MUI_EventHandlerRC_Eat;
4733 break;
4737 return 0;
4741 ///MUIM_IconList_NextIcon()
4742 /**************************************************************************
4743 MUIM_IconList_NextIcon
4744 **************************************************************************/
4745 IPTR IconList__MUIM_IconList_NextIcon(struct IClass *CLASS, Object *obj, struct MUIP_IconList_NextIcon *message)
4747 struct IconList_DATA *data = INST_DATA(CLASS, obj);
4748 struct IconEntry *node = NULL;
4749 struct IconList_Entry *ent = NULL;
4750 IPTR node_successor = (IPTR)NULL;
4752 if (message->entry == NULL) return (IPTR)NULL;
4753 ent = *message->entry;
4755 #if defined(DEBUG_ILC_FUNCS)
4756 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
4757 #endif
4759 if ((IPTR)ent == (IPTR)MUIV_IconList_NextIcon_Start)
4761 D(bug("[IconList] %s: Finding First Entry ..\n", __PRETTY_FUNCTION__));
4762 if (message->nextflag == MUIV_IconList_NextIcon_Selected)
4764 node = (struct IconEntry *)GetHead(&data->icld_SelectionList);
4765 if (node != NULL)
4767 node = (struct IconEntry *)((IPTR)node - ((IPTR)&node->ie_SelectionNode - (IPTR)node));
4770 else if (message->nextflag == MUIV_IconList_NextIcon_Visible)
4772 node = (struct IconEntry *)GetHead(&data->icld_IconList);
4773 while (node != NULL)
4775 if (node->ie_Flags & ICONENTRY_FLAG_VISIBLE)
4776 break;
4778 node = (struct IconEntry *)GetSucc(&node->ie_IconNode);
4782 else if ((IPTR)ent != (IPTR)MUIV_IconList_NextIcon_End)
4784 node = (struct IconEntry *)((IPTR)ent - ((IPTR)&node->ie_IconListEntry - (IPTR)node));
4785 if (message->nextflag == MUIV_IconList_NextIcon_Selected)
4787 node_successor = (IPTR)GetSucc(&node->ie_SelectionNode);
4788 if (node_successor != (IPTR)NULL)
4789 node = (struct IconEntry *)((IPTR)node_successor - ((IPTR)&node->ie_SelectionNode - (IPTR)node));
4790 else
4792 D(bug("[IconList] %s: GetSucc() == NULL\n", __PRETTY_FUNCTION__));
4793 node = NULL;
4796 else if (message->nextflag == MUIV_IconList_NextIcon_Visible)
4798 node = (struct IconEntry *)GetSucc(&node->ie_IconNode);
4799 while (node != NULL)
4801 if (node->ie_Flags & ICONENTRY_FLAG_VISIBLE)
4802 break;
4804 node = (struct IconEntry *)GetSucc(&node->ie_IconNode);
4809 if (node == NULL)
4811 D(bug("[IconList] %s: Returning MUIV_IconList_NextIcon_End\n", __PRETTY_FUNCTION__));
4813 *message->entry = (struct IconList_Entry *)MUIV_IconList_NextIcon_End;
4815 else
4817 D(bug("[IconList] %s: Returning entry for '%s'\n", __PRETTY_FUNCTION__, node->ie_IconListEntry.label));
4819 *message->entry = &node->ie_IconListEntry;
4822 return (IPTR)NULL;
4826 ///MUIM_IconList_GetIconPrivate()
4827 /**************************************************************************
4828 MUIM_IconList_GetIconPrivate
4829 **************************************************************************/
4830 IPTR IconList__MUIM_IconList_GetIconPrivate(struct IClass *CLASS, Object *obj, struct MUIP_IconList_GetIconPrivate *message)
4832 // struct IconList_DATA *data = INST_DATA(CLASS, obj);
4833 struct IconEntry *node = NULL;
4835 if (message->entry == NULL) return (IPTR)NULL;
4837 node = (struct IconEntry *)((IPTR)message->entry - ((IPTR)&node->ie_IconListEntry - (IPTR)node));
4839 return (IPTR)node;
4842 ///MUIM_CreateDragImage()
4843 /**************************************************************************
4844 MUIM_CreateDragImage
4845 **************************************************************************/
4846 IPTR IconList__MUIM_CreateDragImage(struct IClass *CLASS, Object *obj, struct MUIP_CreateDragImage *message)
4848 struct IconList_DATA *data = INST_DATA(CLASS, obj);
4849 struct MUI_DragImage *img = NULL;
4850 LONG first_x = -1,
4851 first_y = -1;
4853 #if defined(DEBUG_ILC_FUNCS)
4854 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
4855 #endif
4857 if (!(data->icld_SelectionLastClicked)) DoSuperMethodA(CLASS, obj, (Msg)message);
4859 if ((img = (struct MUI_DragImage *)AllocVec(sizeof(struct MUIP_CreateDragImage), MEMF_CLEAR)))
4861 struct Node *node = NULL;
4862 struct IconEntry *entry = NULL;
4864 LONG depth = GetBitMapAttr(_screen(obj)->RastPort.BitMap, BMA_DEPTH);
4866 #if defined(CREATE_FULL_DRAGIMAGE)
4867 #ifdef __AROS__
4868 ForeachNode(&data->icld_SelectionList, node)
4869 #else
4870 Foreach_Node(&data->icld_SelectionList, node);
4871 #endif
4873 entry = (struct IconEntry *)((IPTR)node - ((IPTR)&entry->ie_SelectionNode - (IPTR)entry));
4874 if ((entry->ie_Flags & ICONENTRY_FLAG_VISIBLE) && (entry->ie_Flags & ICONENTRY_FLAG_SELECTED))
4876 if ((first_x == -1) || ((first_x != -1) && (entry->ie_IconX < first_x))) first_x = entry->ie_IconX;
4877 if ((first_y == -1) || ((first_y != -1) && (entry->ie_IconY < first_y))) first_y = entry->ie_IconY;
4878 if ((entry->ie_IconX + entry->ie_IconWidth) > img->width) img->width = entry->ie_IconX + entry->ie_IconWidth;
4879 if ((entry->ie_IconY + entry->ie_IconHeight) > img->height) img->height = entry->ie_IconY + entry->ie_IconHeight;
4882 img->width = (img->width - first_x) + 2;
4883 img->height = (img->height - first_y) + 2;
4884 #else
4885 entry = data->icld_SelectionLastClicked;
4886 img->width = entry->ie_IconWidth;
4887 img->height = entry->ie_IconHeight;
4888 first_x = entry->ie_IconX;
4889 first_y = entry->ie_IconY;
4890 #endif
4892 img->touchx = data->click_x - first_x;
4893 img->touchy = data->click_y - first_y;
4895 if ((img->bm = AllocBitMap(img->width, img->height, depth, BMF_CLEAR, _screen(obj)->RastPort.BitMap)))
4897 struct RastPort temprp;
4898 InitRastPort(&temprp);
4899 temprp.BitMap = img->bm;
4901 #if defined(CREATE_FULL_DRAGIMAGE)
4902 ForeachNode(&data->icld_SelectionList, node)
4904 entry = (struct IconEntry *)((IPTR)node - ((IPTR)&entry->ie_SelectionNode - (IPTR)entry));
4905 if ((entry->ie_Flags & ICONENTRY_FLAG_VISIBLE) && (entry->ie_Flags & ICONENTRY_FLAG_SELECTED))
4907 DrawIconStateA
4909 &temprp, entry->ie_DiskObj, NULL,
4910 (entry->ie_IconX + 1) - first_x, (entry->ie_IconY + 1) - first_y,
4911 IDS_SELECTED,
4912 __iconList_DrawIconStateTags
4916 #else
4917 DrawIconStateA
4919 &temprp, entry->ie_DiskObj, NULL,
4920 0, 0,
4921 IDS_SELECTED,
4922 __iconList_DrawIconStateTags
4924 #endif
4925 RastPortSetAlpha(&temprp, data->click_x, data->click_y, img->width, img->height, 0x80, RPALPHAFLAT);
4926 DeinitRastPort(&temprp);
4929 img->touchx = message->touchx;
4930 img->touchy = message->touchy;
4931 img->flags = 0;
4932 #if defined(__MORPHOS__)
4933 img->dragmode = DD_TRANSPARENT;
4934 #endif
4936 return (IPTR)img;
4940 ///MUIM_DeleteDragImage()
4941 /**************************************************************************
4942 MUIM_DeleteDragImage
4943 **************************************************************************/
4944 IPTR IconList__MUIM_DeleteDragImage(struct IClass *CLASS, Object *obj, struct MUIP_DeleteDragImage *message)
4946 struct IconList_DATA *data = INST_DATA(CLASS, obj);
4948 #if defined(DEBUG_ILC_FUNCS)
4949 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
4950 #endif
4952 if (!(data->icld_SelectionLastClicked)) return DoSuperMethodA(CLASS,obj,(Msg)message);
4954 if (message->di)
4956 if (message->di->bm)
4957 FreeBitMap(message->di->bm);
4958 FreeVec(message->di);
4960 return (IPTR)NULL;
4964 ///MUIM_DragQuery()
4965 /**************************************************************************
4966 MUIM_DragQuery
4967 **************************************************************************/
4968 IPTR IconList__MUIM_DragQuery(struct IClass *CLASS, Object *obj, struct MUIP_DragQuery *message)
4970 #if defined(DEBUG_ILC_FUNCS)
4971 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
4972 #endif
4973 if (message->obj == obj)
4974 return MUIV_DragQuery_Accept;
4975 else
4977 BOOL is_iconlist = FALSE;
4978 struct IClass *msg_cl = OCLASS(message->obj);
4980 while (msg_cl)
4982 if (msg_cl == CLASS)
4984 is_iconlist = TRUE;
4985 break;
4987 msg_cl = msg_cl->cl_Super;
4989 if (is_iconlist)
4990 return MUIV_DragQuery_Accept;
4993 return MUIV_DragQuery_Refuse;
4997 ///MUIM_DragDrop()
4998 /**************************************************************************
4999 MUIM_DragDrop
5000 **************************************************************************/
5001 IPTR IconList__MUIM_DragDrop(struct IClass *CLASS, Object *obj, struct MUIP_DragDrop *message)
5003 struct IconList_DATA *data = INST_DATA(CLASS, obj);
5005 #if defined(DEBUG_ILC_FUNCS)
5006 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
5007 #endif
5009 struct IconList_Entry *entry = (IPTR)MUIV_IconList_NextIcon_Start;
5011 if (data->icld_DragDropEvent)
5013 struct IconList_Drop_SourceEntry *clean_node;
5014 #if defined(DEBUG_ILC_ICONDRAGDROP)
5015 D(bug("[IconList] %s: Cleaning existing IconList_Drop_Event @ %p\n", __PRETTY_FUNCTION__, data->icld_DragDropEvent));
5016 #endif
5017 while ((clean_node = (struct IconList_Drop_SourceEntry *)RemTail(&data->icld_DragDropEvent->drop_SourceList)) != NULL)
5019 FreeVec(clean_node->dropse_Node.ln_Name);
5020 FreeMem(clean_node, sizeof(struct IconList_Drop_SourceEntry));
5022 if (data->icld_DragDropEvent->drop_TargetPath) FreeVec(data->icld_DragDropEvent->drop_TargetPath);
5023 FreeMem(data->icld_DragDropEvent, sizeof(struct IconList_Drop_Event));
5024 data->icld_DragDropEvent = NULL;
5027 /* SANITY CHECK: Get first selected entry from SOURCE iconlist */
5028 DoMethod(message->obj, MUIM_IconList_NextIcon, MUIV_IconList_NextIcon_Selected, (IPTR)&entry);
5030 if ((entry) && (entry != (IPTR)MUIV_IconList_NextIcon_End))
5032 /* Ok.. atleast one icon was dropped .. */
5033 BOOL iconMove = FALSE;
5034 struct IconEntry *node = NULL;
5035 struct IconEntry *drop_target_node = NULL;
5036 STRPTR directory_path = NULL;
5037 struct IconList_Drop_Event *dragDropEvent = NULL;
5039 GET(obj, MUIA_IconDrawerList_Drawer, &directory_path);
5041 if ((dragDropEvent = AllocMem(sizeof(struct IconList_Drop_Event), MEMF_CLEAR)) == NULL)
5043 #if defined(DEBUG_ILC_ICONDRAGDROP)
5044 D(bug("[IconList] %s: Failed to allocate IconList_Drop_Event Storage!\n", __PRETTY_FUNCTION__));
5045 #endif
5046 goto dragdropdone;
5048 D(bug("[IconList] %s: Allocated IconList_Drop_Event @ %p\n", __PRETTY_FUNCTION__, dragDropEvent));
5050 NewList(&dragDropEvent->drop_SourceList);
5052 /* go through list and check if dropped on icon */
5053 #ifdef __AROS__
5054 ForeachNode(&data->icld_IconList, node)
5055 #else
5056 Foreach_Node(&data->icld_IconList, node);
5057 #endif
5059 if ((node->ie_Flags & ICONENTRY_FLAG_VISIBLE) &&
5060 (message->x >= (node->ie_IconX - data->icld_ViewX)) &&
5061 (message->x < (node->ie_IconX - data->icld_ViewX + node->ie_AreaWidth)) &&
5062 (message->y >= (node->ie_IconY - data->icld_ViewY + _mtop(obj))) &&
5063 (message->y < (node->ie_IconY - data->icld_ViewY + node->ie_AreaHeight + _mtop(obj))))
5065 drop_target_node = node;
5066 break;
5070 if (drop_target_node &&
5071 ((drop_target_node->ie_IconListEntry.type == ST_SOFTLINK) ||
5072 (drop_target_node->ie_IconListEntry.type == ST_ROOT) ||
5073 (drop_target_node->ie_IconListEntry.type == ST_USERDIR) ||
5074 (drop_target_node->ie_IconListEntry.type == ST_LINKDIR) ||
5075 (drop_target_node->ie_IconListEntry.type == ST_FILE) ||
5076 (drop_target_node->ie_IconListEntry.type == ST_LINKFILE)))
5078 if ((drop_target_node->ie_IconListEntry.type != ST_ROOT) && (drop_target_node->ie_IconListEntry.type != ST_SOFTLINK))
5080 if (directory_path)
5082 int fulllen = strlen(directory_path) + strlen(drop_target_node->ie_IconListEntry.label) + 2;
5084 if ((dragDropEvent->drop_TargetPath = AllocVec(fulllen, MEMF_CLEAR)) == NULL)
5086 #if defined(DEBUG_ILC_ICONDRAGDROP)
5087 D(bug("[IconList] %s: Failed to allocate IconList_Drop_Event->drop_TargetPath Storage!\n", __PRETTY_FUNCTION__));
5088 #endif
5089 goto dragdropdone;
5091 strcpy(dragDropEvent->drop_TargetPath, directory_path);
5092 AddPart(dragDropEvent->drop_TargetPath, drop_target_node->ie_IconListEntry.label, fulllen);
5095 else
5097 if ((dragDropEvent->drop_TargetPath = AllocVec(strlen(drop_target_node->ie_IconListEntry.label) + 1, MEMF_CLEAR)) == NULL)
5099 #if defined(DEBUG_ILC_ICONDRAGDROP)
5100 D(bug("[IconList] %s: Failed to allocate IconList_Drop_Event->drop_TargetPath Storage!\n", __PRETTY_FUNCTION__));
5101 #endif
5102 goto dragdropdone;
5104 strcpy(dragDropEvent->drop_TargetPath, drop_target_node->ie_IconListEntry.label);
5107 #if defined(DEBUG_ILC_ICONDRAGDROP)
5108 D(bug("[IconList] %s: Target Icon Full Path = '%s'\n", __PRETTY_FUNCTION__, dragDropEvent->drop_TargetPath));
5109 #endif
5110 /* mark the Icon the selection was dropped on*/
5111 //drop_target_node->ie_Flags |= ICONENTRY_FLAG_SELECTED;
5112 //data->icld_UpdateMode = UPDATE_SINGLEICON;
5113 //data->update_icon = drop_target_node;
5114 //MUI_Redraw(obj,MADF_DRAWUPDATE);
5116 else
5118 /* not dropped on icon -> get path of DESTINATION iconlist */
5119 /* Note: directory_path is NULL when dropped on Wanderer's desktop */
5120 if ((message->obj != obj) && directory_path)
5122 #if defined(DEBUG_ILC_ICONDRAGDROP)
5123 D(bug("[IconList] %s: drop entry: Icons dropped in window '%s'\n", __PRETTY_FUNCTION__, directory_path));
5124 #endif
5125 /* copy path */
5126 if ((dragDropEvent->drop_TargetPath = AllocVec(strlen(directory_path) + 1, MEMF_CLEAR)) != NULL)
5128 strcpy(dragDropEvent->drop_TargetPath, directory_path);
5130 else
5132 #if defined(DEBUG_ILC_ICONDRAGDROP)
5133 D(bug("[IconList] %s: Failed to allocate IconList_Drop_Event->drop_TargetPath Storage!\n", __PRETTY_FUNCTION__));
5134 #endif
5135 goto dragdropdone;
5138 else if (message->obj == obj)
5140 #if defined(DEBUG_ILC_ICONDRAGDROP)
5141 D(bug("[IconList] %s: drop entry: Icon Move detected ..\n", __PRETTY_FUNCTION__));
5142 #endif
5143 iconMove = TRUE;
5144 SET(obj, MUIA_IconList_IconsMoved, (IPTR)entry); // Now notify
5145 MUI_Redraw(obj,MADF_DRAWOBJECT);
5146 DoMethod(obj, MUIM_IconList_CoordsSort);
5148 else
5150 #if defined(DEBUG_ILC_ICONDRAGDROP)
5151 D(bug("[IconList] %s: Icons Dropped on Wanderer Desktop (unhandled)!\n", __PRETTY_FUNCTION__));
5152 #endif
5153 iconMove = TRUE;
5156 if (!(iconMove))
5158 int copycount = 0;
5159 /* Create list of entries to copy .. */
5160 entry = (IPTR)MUIV_IconList_NextIcon_Start;
5161 while (entry != (IPTR)MUIV_IconList_NextIcon_End)
5163 DoMethod(message->obj, MUIM_IconList_NextIcon, MUIV_IconList_NextIcon_Selected, (IPTR)&entry);
5165 if (entry != (IPTR)MUIV_IconList_NextIcon_End)
5167 struct IconList_Drop_SourceEntry *sourceEntry = NULL;
5168 sourceEntry = AllocMem(sizeof(struct IconList_Drop_SourceEntry), MEMF_CLEAR);
5169 if ((entry->type != ST_ROOT) && (entry->type != ST_SOFTLINK))
5171 int fulllen = 0;
5172 IPTR path = 0;
5174 GET(message->obj, MUIA_IconDrawerList_Drawer, &path);
5176 if (path)
5178 #warning "TODO: Get full path for source icons .. "
5179 fulllen = strlen(path) + strlen(entry->ile_IconEntry->ie_IconNode.ln_Name) + 2;
5180 sourceEntry->dropse_Node.ln_Name = AllocVec(fulllen, MEMF_CLEAR);
5181 strcpy(sourceEntry->dropse_Node.ln_Name, path);
5182 AddPart(sourceEntry->dropse_Node.ln_Name, entry->ile_IconEntry->ie_IconNode.ln_Name, fulllen);
5183 #if defined(DEBUG_ILC_ICONDRAGDROP)
5184 D(bug("[IconList] %s: Source Icon (Full Path) = '%s'\n", __PRETTY_FUNCTION__, sourceEntry->dropse_Node.ln_Name));
5185 #endif
5188 else
5190 sourceEntry->dropse_Node.ln_Name = AllocVec(strlen(entry->ile_IconEntry->ie_IconNode.ln_Name) + 1, MEMF_CLEAR);
5191 strcpy(sourceEntry->dropse_Node.ln_Name, entry->ile_IconEntry->ie_IconNode.ln_Name);
5192 #if defined(DEBUG_ILC_ICONDRAGDROP)
5193 D(bug("[IconList] %s: Source Icon = '%s'\n", __PRETTY_FUNCTION__, sourceEntry->dropse_Node.ln_Name));
5194 #endif
5196 if ((strcasecmp(dragDropEvent->drop_TargetPath, sourceEntry->dropse_Node.ln_Name)) != 0)
5198 copycount += 1;
5199 AddTail(&dragDropEvent->drop_SourceList, &sourceEntry->dropse_Node);
5201 else
5203 #if defined(DEBUG_ILC_ICONDRAGDROP)
5204 D(bug("[IconList] %s: Source == Dest, Skipping!\n", __PRETTY_FUNCTION__));
5205 #endif
5206 FreeVec(sourceEntry->dropse_Node.ln_Name);
5207 FreeMem(sourceEntry, sizeof(struct IconList_Drop_SourceEntry));
5211 if (copycount > 0)
5213 dragDropEvent->drop_TargetObj = (IPTR)obj;
5215 #if defined(DEBUG_ILC_ICONDRAGDROP)
5216 D(bug("[IconList] %s: Causing DROP notification..\n", __PRETTY_FUNCTION__));
5217 #endif
5218 SET(obj, MUIA_IconList_IconsDropped, (IPTR)dragDropEvent);
5219 DoMethod(obj, MUIM_IconList_CoordsSort);
5221 else
5223 if (dragDropEvent->drop_TargetPath) FreeVec(dragDropEvent->drop_TargetPath);
5224 FreeMem(dragDropEvent, sizeof(struct IconList_Drop_Event));
5228 else
5230 #if defined(DEBUG_ILC_ICONDRAGDROP)
5231 D(bug("[IconList] %s: BUG - DragDrop recieved with no source icons!\n", __PRETTY_FUNCTION__));
5232 #endif
5233 NNSET(obj, MUIA_IconList_IconsDropped, (IPTR)NULL);
5236 dragdropdone:
5237 return DoSuperMethodA(CLASS, obj, (Msg)message);
5241 ///MUIM_UnselectAll()
5242 /**************************************************************************
5243 MUIM_UnselectAll
5244 **************************************************************************/
5245 IPTR IconList__MUIM_IconList_UnselectAll(struct IClass *CLASS, Object *obj, Msg message)
5247 struct IconList_DATA *data = INST_DATA(CLASS, obj);
5248 struct Node *node = NULL, *next_node = NULL;
5249 BOOL changed = FALSE;
5251 #if defined(DEBUG_ILC_FUNCS)
5252 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
5253 #endif
5255 data->icld_SelectionLastClicked = NULL;
5256 data->icld_FocusIcon = NULL;
5257 #ifdef __AROS__
5258 ForeachNodeSafe(&data->icld_SelectionList, node, next_node)
5259 #else
5260 Foreach_NodeSafe(&data->icld_SelectionList, node, next_node);
5261 #endif
5263 struct IconEntry *entry = (struct IconEntry *)((IPTR)node - ((IPTR)&entry->ie_SelectionNode - (IPTR)entry));
5264 BOOL update_icon = FALSE;
5266 if (entry->ie_Flags & ICONENTRY_FLAG_VISIBLE)
5268 if (entry->ie_Flags & ICONENTRY_FLAG_SELECTED)
5270 Remove(node);
5271 entry->ie_Flags &= ~ICONENTRY_FLAG_SELECTED;
5272 update_icon = TRUE;
5274 if (entry->ie_Flags & ICONENTRY_FLAG_FOCUS)
5276 entry->ie_Flags &= ~ICONENTRY_FLAG_FOCUS;
5277 update_icon = TRUE;
5281 if (update_icon)
5283 changed = TRUE;
5284 data->icld_UpdateMode = UPDATE_SINGLEICON;
5285 data->update_icon = entry;
5286 MUI_Redraw(obj, MADF_DRAWUPDATE);
5290 if (changed)
5291 SET(obj, MUIA_IconList_SelectionChanged, TRUE);
5293 return 1;
5297 ///MUIM_SelectAll()
5298 /**************************************************************************
5299 MUIM_SelectAll
5300 **************************************************************************/
5301 IPTR IconList__MUIM_IconList_SelectAll(struct IClass *CLASS, Object *obj, Msg message)
5303 struct IconList_DATA *data = INST_DATA(CLASS, obj);
5304 struct IconEntry *node = NULL;
5305 BOOL changed = FALSE;
5307 #if defined(DEBUG_ILC_FUNCS)
5308 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
5309 #endif
5311 node = (struct IconEntry *)GetHead(&data->icld_IconList);
5313 while (node != NULL)
5315 if (node->ie_Flags & ICONENTRY_FLAG_VISIBLE)
5317 BOOL update_icon = FALSE;
5319 if (!(node->ie_Flags & ICONENTRY_FLAG_SELECTED))
5321 AddTail(&data->icld_SelectionList, &node->ie_SelectionNode);
5322 node->ie_Flags |= ICONENTRY_FLAG_SELECTED;
5323 update_icon = TRUE;
5325 data->icld_SelectionLastClicked = node;
5327 else if (node->ie_Flags & ICONENTRY_FLAG_FOCUS)
5329 node->ie_Flags &= ~ICONENTRY_FLAG_FOCUS;
5330 update_icon = TRUE;
5333 if (update_icon)
5335 changed = TRUE;
5336 data->icld_UpdateMode = UPDATE_SINGLEICON;
5337 data->update_icon = node;
5338 MUI_Redraw(obj, MADF_DRAWUPDATE);
5341 node = (struct IconEntry *)GetSucc(&node->ie_IconNode);
5344 if ((data->icld_SelectionLastClicked) && (data->icld_SelectionLastClicked != data->icld_FocusIcon))
5346 data->icld_FocusIcon = data->icld_SelectionLastClicked;
5347 if (!(data->icld_FocusIcon->ie_Flags & ICONENTRY_FLAG_FOCUS))
5349 data->icld_FocusIcon->ie_Flags &= ~ICONENTRY_FLAG_FOCUS;
5350 data->icld_FocusIcon->ie_Flags |= ICONENTRY_FLAG_FOCUS;
5351 data->icld_UpdateMode = UPDATE_SINGLEICON;
5352 data->update_icon = data->icld_FocusIcon;
5353 MUI_Redraw(obj, MADF_DRAWUPDATE);
5357 if (changed)
5358 SET(obj, MUIA_IconList_SelectionChanged, TRUE);
5360 return 1;
5364 ///IconList__MUIM_IconList_CoordsSort()
5365 IPTR IconList__MUIM_IconList_CoordsSort(struct IClass *CLASS, Object *obj, struct MUIP_IconList_Sort *message)
5367 struct IconList_DATA *data = INST_DATA(CLASS, obj);
5369 struct IconEntry *entry = NULL,
5370 *test_icon = NULL;
5372 struct List list_VisibleIcons;
5373 struct List list_HiddenIcons;
5376 perform a quick sort of the iconlist based on icon coords
5377 this method DOESNT cause any visual output.
5379 #if defined(DEBUG_ILC_FUNCS) && defined(DEBUG_ILC_ICONSORTING)
5380 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
5381 #endif
5383 NewList((struct List*)&list_VisibleIcons);
5384 NewList((struct List*)&list_HiddenIcons);
5386 /*move list into our local list struct(s)*/
5387 while ((entry = (struct IconEntry *)RemTail((struct List*)&data->icld_IconList)))
5389 if (entry->ie_Flags & ICONENTRY_FLAG_VISIBLE)
5390 AddHead((struct List*)&list_VisibleIcons, (struct Node *)&entry->ie_IconNode);
5391 else
5392 AddHead((struct List*)&list_HiddenIcons, (struct Node *)&entry->ie_IconNode);
5395 while ((entry = (struct IconEntry *)RemTail((struct List*)&list_VisibleIcons)))
5397 if ((test_icon = (struct IconEntry *)GetTail(&data->icld_IconList)) != NULL)
5399 while (test_icon != NULL)
5401 if (((data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL) && (test_icon->ie_IconX > entry->ie_IconX)) ||
5402 (!(data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL) && (test_icon->ie_IconY > entry->ie_IconY)))
5404 test_icon = (struct IconEntry *)GetPred(&test_icon->ie_IconNode);
5405 continue;
5407 else break;
5410 while (test_icon != NULL)
5412 if (((data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL) && (test_icon->ie_IconY > entry->ie_IconY)) ||
5413 (!(data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL) && (test_icon->ie_IconX > entry->ie_IconX)))
5415 test_icon = (struct IconEntry *)GetPred(&test_icon->ie_IconNode);
5416 continue;
5418 else break;
5420 Insert((struct List*)&data->icld_IconList, (struct Node *)&entry->ie_IconNode, (struct Node *)&test_icon->ie_IconNode);
5422 else
5423 AddTail((struct List*)&data->icld_IconList, (struct Node *)&entry->ie_IconNode);
5425 #if defined(DEBUG_ILC_ICONSORTING)
5426 D(bug("[IconList] %s: Done\n", __PRETTY_FUNCTION__));
5427 #endif
5429 while ((entry = (struct IconEntry *)RemTail((struct List*)&list_HiddenIcons)))
5431 AddTail((struct List*)&data->icld_IconList, (struct Node *)&entry->ie_IconNode);
5434 #if defined(DEBUG_ILC_ICONSORTING_DUMP)
5435 #ifdef __AROS__
5436 ForeachNode(&data->icld_IconList, entry)
5437 #else
5438 Foreach_Node(&data->icld_IconList, entry);
5439 #endif
5441 D(bug("[IconList] %s: %d %d '%s'\n", __PRETTY_FUNCTION__, entry->ie_IconX, entry->ie_IconY, entry->ie_IconListEntry.label));
5443 #endif
5445 return TRUE;
5449 ///MUIM_Sort()
5450 /**************************************************************************
5451 MUIM_Sort - sortsort
5452 **************************************************************************/
5453 IPTR IconList__MUIM_IconList_Sort(struct IClass *CLASS, Object *obj, struct MUIP_IconList_Sort *message)
5455 struct IconList_DATA *data = INST_DATA(CLASS, obj);
5456 struct IconEntry *entry = NULL,
5457 *icon1 = NULL,
5458 *icon2 = NULL;
5459 struct List list_VisibleIcons,
5460 list_SortedIcons,
5461 list_HiddenIcons;
5463 BOOL sortme, enqueue = FALSE;
5464 int i, visible_count = 0;
5466 #if defined(DEBUG_ILC_FUNCS) && defined(DEBUG_ILC_ICONSORTING)
5467 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
5468 #endif
5470 /* Reset incase view options have changed .. */
5471 data->icld_IconAreaLargestWidth = 0;
5472 data->icld_IconAreaLargestHeight = 0;
5473 data->icld_IconLargestHeight = 0;
5474 data->icld_LabelLargestHeight = 0;
5476 if ((data->icld_SortFlags & ICONLIST_SORT_MASK) != 0)
5478 #if defined(DEBUG_ILC_ICONSORTING)
5479 D(bug("[IconList] %s: Sorting (Flags %x)\n", __PRETTY_FUNCTION__, (data->icld_SortFlags & ICONLIST_SORT_MASK)));
5480 #endif
5481 NewList((struct List*)&list_VisibleIcons);
5482 NewList((struct List*)&list_SortedIcons);
5483 NewList((struct List*)&list_HiddenIcons);
5485 /*move list into our local list struct(s)*/
5486 while ((entry = (struct IconEntry *)RemTail((struct List*)&data->icld_IconList)))
5488 if (entry->ie_DiskObj)
5490 if (entry->ie_IconX != entry->ie_DiskObj->do_CurrentX)
5492 entry->ie_IconX = entry->ie_DiskObj->do_CurrentX;
5493 if ((data->icld_SortFlags & ICONLIST_SORT_MASK) == 0)
5494 entry->ie_Flags |= ICONENTRY_FLAG_NEEDSUPDATE;
5496 if (entry->ie_IconY != entry->ie_DiskObj->do_CurrentY)
5498 entry->ie_IconY = entry->ie_DiskObj->do_CurrentY;
5499 if ((data->icld_SortFlags & ICONLIST_SORT_MASK) == 0)
5500 entry->ie_Flags |= ICONENTRY_FLAG_NEEDSUPDATE;
5504 if (!(entry->ie_Flags & ICONENTRY_FLAG_HASICON))
5506 if (data->icld_DisplayFlags & ICONLIST_DISP_SHOWINFO)
5508 if (entry->ie_Flags & ICONENTRY_FLAG_VISIBLE)
5510 entry->ie_Flags &= ~(ICONENTRY_FLAG_VISIBLE|ICONENTRY_FLAG_NEEDSUPDATE);
5513 else if (!(entry->ie_Flags & ICONENTRY_FLAG_VISIBLE))
5515 entry->ie_Flags |= (ICONENTRY_FLAG_VISIBLE|ICONENTRY_FLAG_NEEDSUPDATE);
5518 else
5520 if (!(entry->ie_Flags & ICONENTRY_FLAG_VISIBLE))
5522 entry->ie_Flags |= (ICONENTRY_FLAG_VISIBLE|ICONENTRY_FLAG_NEEDSUPDATE);
5526 /* Now we have fixed visibility lets dump them into the correct list for sorting */
5527 if (entry->ie_Flags & ICONENTRY_FLAG_VISIBLE)
5529 if(entry->ie_AreaWidth > data->icld_IconAreaLargestWidth) data->icld_IconAreaLargestWidth = entry->ie_AreaWidth;
5530 if(entry->ie_AreaHeight > data->icld_IconAreaLargestHeight) data->icld_IconAreaLargestHeight = entry->ie_AreaHeight;
5531 if(entry->ie_IconHeight > data->icld_IconLargestHeight) data->icld_IconLargestHeight = entry->ie_IconHeight;
5532 if((entry->ie_AreaHeight - entry->ie_IconHeight) > data->icld_LabelLargestHeight) data->icld_LabelLargestHeight = entry->ie_AreaHeight - entry->ie_IconHeight;
5534 if (((data->icld_SortFlags & ICONLIST_SORT_MASK) == 0) && (entry->ie_IconX == NO_ICON_POSITION))
5535 AddTail((struct List*)&list_VisibleIcons, (struct Node *)&entry->ie_IconNode);
5536 else
5537 AddHead((struct List*)&list_VisibleIcons, (struct Node *)&entry->ie_IconNode);
5538 visible_count++;
5540 else
5542 if (entry->ie_Flags & ICONENTRY_FLAG_SELECTED)
5544 Remove(&entry->ie_SelectionNode);
5546 entry->ie_Flags &= ~(ICONENTRY_FLAG_SELECTED|ICONENTRY_FLAG_FOCUS);
5547 if (data->icld_SelectionLastClicked == entry) data->icld_SelectionLastClicked = NULL;
5548 if (data->icld_FocusIcon == entry) data->icld_FocusIcon = data->icld_SelectionLastClicked;
5549 AddHead((struct List*)&list_HiddenIcons, (struct Node *)&entry->ie_IconNode);
5553 /* Copy each visible icon entry back to the main list, sorting as we go*/
5555 while ((entry = (struct IconEntry *)RemHead((struct List*)&list_VisibleIcons)))
5557 icon1 = (struct IconEntry *)GetHead(&list_SortedIcons);
5558 icon2 = NULL;
5560 sortme = FALSE;
5562 if (visible_count > 1)
5564 //D(bug(" - %s %s %s %i\n",entry->ie_IconListEntry.label,entry->ie_TxtBuf_DATE,entry->ie_TxtBuf_TIME,entry->ie_FileInfoBlock->fib_Size));
5566 while (icon1)
5568 if((icon1->ie_IconListEntry.type == ST_ROOT)||(data->icld_SortFlags & ICONLIST_SORT_DRAWERS_MIXED))
5570 /*volume list or drawers mixed*/
5571 sortme = TRUE;
5573 else
5575 /*drawers first*/
5576 if ((icon1->ie_IconListEntry.type == ST_USERDIR) && (entry->ie_IconListEntry.type == ST_USERDIR))
5578 sortme = TRUE;
5580 else
5582 if ((icon1->ie_IconListEntry.type != ST_USERDIR) && (entry->ie_IconListEntry.type != ST_USERDIR))
5583 sortme = TRUE;
5584 else
5586 /* we are the first drawer to arrive or we need to insert ourselves
5587 due to being sorted to the end of the drawers*/
5589 if ((!icon2 || icon2->ie_IconListEntry.type == ST_USERDIR) &&
5590 (entry->ie_IconListEntry.type == ST_USERDIR) &&
5591 (icon1->ie_IconListEntry.type != ST_USERDIR))
5593 //D(bug("force %s\n",entry->ie_IconListEntry.label));
5594 break;
5600 if (sortme)
5602 i = 0;
5604 if ((data->icld_SortFlags & ICONLIST_SORT_MASK) == ICONLIST_SORT_BY_DATE)
5606 /* Sort by Date */
5607 i = CompareDates((const struct DateStamp *)&entry->ie_FileInfoBlock->fib_Date,(const struct DateStamp *)&icon1->ie_FileInfoBlock->fib_Date);
5609 else if ((data->icld_SortFlags & ICONLIST_SORT_MASK) == ICONLIST_SORT_BY_SIZE)
5611 /* Sort by Size .. */
5612 i = entry->ie_FileInfoBlock->fib_Size - icon1->ie_FileInfoBlock->fib_Size;
5614 else if (((data->icld_SortFlags & ICONLIST_SORT_MASK) == ICONLIST_SORT_MASK) && (entry->ie_IconListEntry.type != ST_ROOT))
5616 /* Sort by Type .. */
5617 #warning "TODO: Sort icons based on type using datatypes"
5619 else
5621 if (
5622 ((data->icld_SortFlags & ICONLIST_SORT_MASK) == ICONLIST_SORT_MASK) ||
5623 ((data->icld_SortFlags & ICONLIST_SORT_MASK) == ICONLIST_SORT_BY_NAME) ||
5624 (entry->ie_IconX == NO_ICON_POSITION)
5627 /* Sort by Name .. */
5628 i = Stricmp(entry->ie_IconListEntry.label, icon1->ie_IconListEntry.label);
5629 if ((data->icld_SortFlags & ICONLIST_SORT_MASK) == ICONLIST_SORT_MASK)
5630 enqueue = TRUE;
5632 else
5634 /* coord sort */
5635 #warning "TODO: Implement default coord sorting.."
5639 if (data->icld_SortFlags & ICONLIST_SORT_REVERSE)
5641 if (i > 0)
5642 break;
5644 else if (i < 0)
5645 break;
5647 icon2 = icon1;
5648 icon1 = (struct IconEntry *)GetSucc(&icon1->ie_IconNode);
5651 Insert((struct List*)&list_SortedIcons, (struct Node *)&entry->ie_IconNode, (struct Node *)&icon2->ie_IconNode);
5653 if (enqueue)
5655 /* Quickly resort based on node priorities .. */
5656 while ((entry = (struct IconEntry *)RemHead((struct List*)&list_SortedIcons)))
5658 Enqueue((struct List*)&data->icld_IconList, (struct Node *)&entry->ie_IconNode);
5661 else
5663 while ((entry = (struct IconEntry *)RemHead((struct List*)&list_SortedIcons)))
5665 AddTail((struct List*)&data->icld_IconList, (struct Node *)&entry->ie_IconNode);
5669 else
5671 #if defined(DEBUG_ILC_ICONSORTING)
5672 D(bug("[IconList] %s: Coord Sorting\n", __PRETTY_FUNCTION__));
5673 #endif
5674 DoMethod(obj, MUIM_IconList_CoordsSort);
5677 DoMethod(obj, MUIM_IconList_PositionIcons);
5678 MUI_Redraw(obj, MADF_DRAWOBJECT);
5680 if ((data->icld_SortFlags & ICONLIST_SORT_MASK) != 0)
5682 DoMethod(obj, MUIM_IconList_CoordsSort);
5684 /* leave hidden icons on a seperate list to speed up normal list parsing ? */
5685 while ((entry = (struct IconEntry *)RemHead((struct List*)&list_HiddenIcons)))
5687 AddTail((struct List*)&data->icld_IconList, (struct Node *)&entry->ie_IconNode);
5690 SET(obj, MUIA_IconList_Changed, TRUE);
5692 return 1;
5696 ///MUIM_DragReport()
5697 /**************************************************************************
5698 MUIM_DragReport. Since MUI doesn't change the drop object if the dragged
5699 object is moved above another window (while still in the bounds of the
5700 orginal drop object) we must do it here manually to be compatible with
5701 MUI. Maybe Zune should fix this bug somewhen.
5702 **************************************************************************/
5703 IPTR IconList__MUIM_DragReport(struct IClass *CLASS, Object *obj, struct MUIP_DragReport *message)
5705 struct Window *wnd = _window(obj);
5706 struct Layer *l = NULL;
5708 #if defined(DEBUG_ILC_FUNCS)
5709 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
5710 #endif
5712 l = WhichLayer(&wnd->WScreen->LayerInfo, wnd->LeftEdge + message->x, wnd->TopEdge + message->y);
5714 if (l != wnd->WLayer) return MUIV_DragReport_Abort;
5716 return MUIV_DragReport_Continue;
5720 ///MUIM_IconList_UnknownDropDestination()
5721 /**************************************************************************
5722 MUIM_IconList_UnknownDropDestination
5723 **************************************************************************/
5725 IPTR IconList__MUIM_UnknownDropDestination(struct IClass *CLASS, Object *obj, struct MUIP_UnknownDropDestination *message)
5727 #if defined(DEBUG_ILC_FUNCS)
5728 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
5729 #endif
5730 D(bug("[IconList] %s: icons dropped on custom window \n", __PRETTY_FUNCTION__));
5732 SET(obj, MUIA_IconList_AppWindowDrop, (IPTR)message); /* Now notify */
5734 return 0;
5738 #if WANDERER_BUILTIN_ICONLIST
5739 BOOPSI_DISPATCHER(IPTR,IconList_Dispatcher, CLASS, obj, message)
5741 #ifdef __AROS__
5742 switch (message->MethodID)
5743 #else
5744 struct IClass *CLASS = cl;
5745 Msg message = msg;
5747 switch (msg->MethodID)
5748 #endif
5750 case OM_NEW: return IconList__OM_NEW(CLASS, obj, (struct opSet *)message);
5751 case OM_DISPOSE: return IconList__OM_DISPOSE(CLASS, obj, message);
5752 case OM_SET: return IconList__OM_SET(CLASS, obj, (struct opSet *)message);
5753 case OM_GET: return IconList__OM_GET(CLASS, obj, (struct opGet *)message);
5754 case OM_ADDMEMBER: return IconList__OM_ADDMEMBER(CLASS, obj, (APTR)message);
5755 case OM_REMMEMBER: return IconList__OM_REMMEMBER(CLASS, obj, (APTR)message);
5757 case MUIM_Setup: return IconList__MUIM_Setup(CLASS, obj, (struct MUIP_Setup *)message);
5759 case MUIM_Show: return IconList__MUIM_Show(CLASS,obj, (struct MUIP_Show *)message);
5760 case MUIM_Hide: return IconList__MUIM_Hide(CLASS,obj, (struct MUIP_Hide *)message);
5761 case MUIM_Cleanup: return IconList__MUIM_Cleanup(CLASS, obj, (struct MUIP_Cleanup *)message);
5762 case MUIM_AskMinMax: return IconList__MUIM_AskMinMax(CLASS, obj, (struct MUIP_AskMinMax *)message);
5763 case MUIM_Draw: return IconList__MUIM_Draw(CLASS, obj, (struct MUIP_Draw *)message);
5764 #ifdef __AROS__
5765 case MUIM_Layout: return IconList__MUIM_Layout(CLASS, obj, (struct MUIP_Layout *)message);
5766 #endif
5767 case MUIM_HandleEvent: return IconList__MUIM_HandleEvent(CLASS, obj, (struct MUIP_HandleEvent *)message);
5768 case MUIM_CreateDragImage: return IconList__MUIM_CreateDragImage(CLASS, obj, (APTR)message);
5769 case MUIM_DeleteDragImage: return IconList__MUIM_DeleteDragImage(CLASS, obj, (APTR)message);
5770 case MUIM_DragQuery: return IconList__MUIM_DragQuery(CLASS, obj, (APTR)message);
5771 case MUIM_DragReport: return IconList__MUIM_DragReport(CLASS, obj, (APTR)message);
5772 case MUIM_DragDrop: return IconList__MUIM_DragDrop(CLASS, obj, (APTR)message);
5773 #ifdef __AROS__
5774 case MUIM_UnknownDropDestination: return IconList__MUIM_UnknownDropDestination(CLASS, obj, (APTR)message);
5775 #endif
5776 case MUIM_IconList_Update: return IconList__MUIM_IconList_Update(CLASS, obj, (APTR)message);
5777 case MUIM_IconList_Clear: return IconList__MUIM_IconList_Clear(CLASS, obj, (APTR)message);
5778 case MUIM_IconList_RethinkDimensions: return IconList__MUIM_IconList_RethinkDimensions(CLASS, obj, (APTR)message);
5779 case MUIM_IconList_CreateEntry: return IconList__MUIM_IconList_CreateEntry(CLASS, obj, (APTR)message);
5780 case MUIM_IconList_DestroyEntry: return IconList__MUIM_IconList_DestroyEntry(CLASS, obj, (APTR)message);
5781 case MUIM_IconList_DrawEntry: return IconList__MUIM_IconList_DrawEntry(CLASS, obj, (APTR)message);
5782 case MUIM_IconList_DrawEntryLabel: return IconList__MUIM_IconList_DrawEntryLabel(CLASS, obj, (APTR)message);
5783 case MUIM_IconList_NextIcon: return IconList__MUIM_IconList_NextIcon(CLASS, obj, (APTR)message);
5784 case MUIM_IconList_GetIconPrivate: return IconList__MUIM_IconList_GetIconPrivate(CLASS, obj, (APTR)message);
5785 case MUIM_IconList_UnselectAll: return IconList__MUIM_IconList_UnselectAll(CLASS, obj, (APTR)message);
5786 case MUIM_IconList_Sort: return IconList__MUIM_IconList_Sort(CLASS, obj, (APTR)message);
5787 case MUIM_IconList_CoordsSort: return IconList__MUIM_IconList_CoordsSort(CLASS, obj, (APTR)message);
5788 case MUIM_IconList_PositionIcons: return IconList__MUIM_IconList_PositionIcons(CLASS, obj, (APTR)message);
5789 case MUIM_IconList_SelectAll: return IconList__MUIM_IconList_SelectAll(CLASS, obj, (APTR)message);
5790 // case MUIM_IconList_ViewIcon: return IconList__MUIM_IconList_ViewIcon(CLASS, obj, (APTR)message);
5793 return DoSuperMethodA(CLASS, obj, message);
5795 BOOPSI_DISPATCHER_END
5797 #ifdef __AROS__
5798 /* Class descriptor. */
5799 const struct __MUIBuiltinClass _MUI_IconList_desc = {
5800 MUIC_IconList,
5801 MUIC_Area,
5802 sizeof(struct IconList_DATA),
5803 (void*)IconList_Dispatcher
5805 #endif
5806 #endif /* WANDERER_BUILTIN_ICONLIST */
5808 #ifndef __AROS__
5809 struct MUI_CustomClass *initIconListClass(void)
5811 return (struct MUI_CustomClass *) MUI_CreateCustomClass(NULL, MUIC_Area, NULL, sizeof(struct IconList_DATA), ENTRY(IconList_Dispatcher));
5813 #endif