Merge the Date + Time columns
[AROS.git] / workbench / system / Wanderer / Classes / iconlist.c
blob2579765350a13be4dc9ba18674fe2f06d0dccbab
1 /*
2 Copyright 2002-2010, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include "../portable_macros.h"
7 #if !defined(__AROS__)
8 #define WANDERER_BUILTIN_ICONLIST 1
9 #else
10 #define DEBUG 0
11 #include <aros/debug.h>
12 #endif
14 //#define DEBUG_ILC_FUNCS
15 //#define DEBUG_ILC_ATTRIBS
16 //#define DEBUG_ILC_EVENTS
17 //#define DEBUG_ILC_KEYEVENTS
18 //#define DEBUG_ILC_ICONDRAGDROP
19 //#define DEBUG_ILC_ICONRENDERING
20 //#define DEBUG_ILC_ICONSORTING
21 //#define DEBUG_ILC_ICONSORTING_DUMP
22 //#define DEBUG_ILC_ICONPOSITIONING
23 //#define DEBUG_ILC_LASSO
24 //#define DEBUG_ILC_MEMALLOC
26 #define CREATE_FULL_DRAGIMAGE
28 #include <string.h>
29 #include <stdlib.h>
30 #include <stdio.h>
31 #include <string.h>
32 #include <math.h>
34 #include <dos/dos.h>
35 #include <dos/datetime.h>
36 #include <dos/filehandler.h>
38 #include <exec/memory.h>
39 #include <graphics/gfx.h>
40 #include <graphics/view.h>
41 #include <graphics/rpattr.h>
42 #include <workbench/icon.h>
43 #include <workbench/workbench.h>
45 #if defined(__AROS__)
46 #include <devices/rawkeycodes.h>
47 #include <clib/alib_protos.h>
48 #else
49 #include <devices_AROS/rawkeycodes.h>
50 #endif
53 #include <proto/exec.h>
54 #include <proto/graphics.h>
55 #include <proto/utility.h>
56 #include <proto/dos.h>
57 #include <proto/icon.h>
58 #include <proto/layers.h>
59 #include <proto/dos.h>
60 #include <proto/iffparse.h>
62 #if defined(__AROS__)
63 #include <prefs/prefhdr.h>
64 #include <prefs/wanderer.h>
65 #else
66 #include <prefs_AROS/prefhdr.h>
67 #include <prefs_AROS/wanderer.h>
68 #endif
70 #include <proto/cybergraphics.h>
72 #if defined(__AROS__)
73 #include <cybergraphx/cybergraphics.h>
74 #else
75 #include <cybergraphx_AROS/cybergraphics.h>
76 #endif
79 #if defined(__AMIGA__) && !defined(__PPC__)
80 #define NO_INLINE_STDARG
81 #endif
82 #include <proto/intuition.h>
83 #include <proto/muimaster.h>
84 #include <libraries/mui.h>
85 #include "iconlist_attributes.h"
86 #include "icon_attributes.h"
87 #include "iconlist.h"
88 #include "iconlist_private.h"
89 #include "iconlistview.h"
91 #if !defined(__AROS__)
92 #define DEBUG 1
94 #ifdef DEBUG
95 #define D(x) if (DEBUG) x
96 #ifdef __amigaos4__
97 #define bug DebugPrintF
98 #else
99 #define bug kprintf
100 #endif
101 #else
102 #define D(...)
103 #endif
104 #endif
106 #define _between(a,x,b) ((x)>=(a) && (x)<=(b))
107 #define _isinobject(x,y) (_between(_mleft(obj),(x),_mright (obj)) \
108 && _between(_mtop(obj) ,(y),_mbottom(obj)))
110 extern struct Library *MUIMasterBase;
112 static struct Hook __iconlist_UpdateLabels_hook;
114 // N.B: We Handle frame/background rendering so make sure icon.library doesnt do it ..
115 static struct TagItem __iconList_DrawIconStateTags[] = {
116 { ICONDRAWA_Frameless, TRUE },
117 { ICONDRAWA_Borderless, TRUE },
118 { ICONDRAWA_EraseBackground, FALSE },
119 { TAG_DONE, }
122 static struct TagItem __iconList_BackBuffLayerTags[] =
124 { LA_Visible, FALSE },
125 { TAG_DONE, }
128 #ifndef NO_ICON_POSITION
129 #define NO_ICON_POSITION (0x8000000) /* belongs to workbench/workbench.h */
130 #endif
132 #define UPDATE_HEADERENTRY 1
133 #define UPDATE_SINGLEENTRY 2
134 #define UPDATE_SCROLL 3
135 #define UPDATE_RESIZE 4
137 #define LEFT_BUTTON 1
138 #define RIGHT_BUTTON 2
139 #define MIDDLE_BUTTON 4
141 #define ICONLIST_DRAWMODE_NORMAL 1
142 #define ICONLIST_DRAWMODE_FAST 2
144 /* Values used for List View-Mode */
145 #define COLOR_COLUMN_BACKGROUND 0
146 #define COLOR_COLUMN_BACKGROUND_SORTED 1
147 #define COLOR_COLUMN_BACKGROUND_LASSO 2
148 #define COLOR_COLUMN_BACKGROUND_LASSO_SORTED 3
150 #define COLOR_SELECTED_BACKGROUND 4
151 #define COLOR_SELECTED_BACKGROUND_SORTED 5
153 #define MIN_COLUMN_WIDTH 10
155 #define COLUMN_ALIGN_LEFT 0
156 #define COLUMN_ALIGN_CENTER 1
157 #define COLUMN_ALIGN_RIGHT 2
159 #define LINE_SPACING_TOP 2
160 #define LINE_SPACING_BOTTOM 2
161 #define LINE_EXTRAHEIGHT (LINE_SPACING_TOP + LINE_SPACING_BOTTOM)
163 #define LINE_SPACING_LEFT 1
164 #define LINE_SPACING_RIGHT 1
165 #define LINE_EXTRAWIDTH (LINE_SPACING_LEFT + LINE_SPACING_RIGHT)
167 #define ENTRY_SPACING_LEFT 1
168 #define ENTRY_SPACING_RIGHT 1
169 #define ENTRY_EXTRAWIDTH (ENTRY_SPACING_LEFT + ENTRY_SPACING_RIGHT)
171 #define HEADERLINE_SPACING_TOP 3
172 #define HEADERLINE_SPACING_BOTTOM 3
173 #define HEADERLINE_EXTRAHEIGHT (HEADERLINE_SPACING_TOP + HEADERLINE_SPACING_BOTTOM)
175 #define HEADERLINE_SPACING_LEFT 1
176 #define HEADERLINE_SPACING_RIGHT 1
177 #define HEADERLINE_EXTRAWIDTH (HEADERLINE_SPACING_LEFT + HEADERLINE_SPACING_RIGHT)
179 #define HEADERENTRY_SPACING_LEFT 4
180 #define HEADERENTRY_SPACING_RIGHT 4
181 #define HEADERENTRY_EXTRAWIDTH (HEADERENTRY_SPACING_LEFT + HEADERENTRY_SPACING_RIGHT)
183 enum
185 INDEX_TYPE,
186 INDEX_NAME,
187 INDEX_SIZE,
188 INDEX_PROTECTION,
189 INDEX_LASTACCESS,
190 INDEX_COMMENT
193 /**************************************************************************
194 Support Functions
195 **************************************************************************/
197 #define ForeachPrevNode(list, node) \
198 for \
200 node = (void *)(((struct List *)(list))->lh_TailPred); \
201 ((struct Node *)(node))->ln_Pred; \
202 node = (void *)(((struct Node *)(node))->ln_Pred) \
205 #define RPALPHAFLAT (1 << 0)
206 #define RPALPHARADIAL (1 << 1)
208 static void RastPortSetAlpha(struct RastPort *arport, ULONG ax, ULONG ay, ULONG width, ULONG height, UBYTE val, UBYTE alphamode)
210 ULONG x, y;
211 ULONG alphaval, pixelval;
213 for (y = 0; y < height; y++)
215 for (x = 0; x < width; x++)
217 if ((pixelval = ReadRGBPixel(arport, x, y)))
219 if (alphamode == RPALPHARADIAL){
220 //Set the alpha value based on distance from ax,ay
221 } else {
222 alphaval = val;
224 WriteRGBPixel(arport, x, y, ((pixelval & 0xffffff)|(alphaval << 24)));
230 ///RectAndRect()
231 // Entry/Label Area support functions
232 static int RectAndRect(struct Rectangle *a, struct Rectangle *b)
234 if ((a->MinX > b->MaxX) || (a->MinY > b->MaxY) || (a->MaxX < b->MinX) || (a->MaxY < b->MinY))
235 return 0;
236 return 1;
240 ///Node_NextVisible()
241 // IconEntry List navigation functions ..
242 static struct IconEntry *Node_NextVisible(struct IconEntry *current_Node)
244 current_Node = (struct IconEntry *)GetSucc(&current_Node->ie_IconNode);
245 while ((current_Node != NULL) && (!(current_Node->ie_Flags & ICONENTRY_FLAG_VISIBLE)))
247 current_Node = (struct IconEntry *)GetSucc(&current_Node->ie_IconNode);
249 return current_Node;
253 ///Node_FirstVisible()
254 static struct IconEntry *Node_FirstVisible(struct List *icon_list)
256 struct IconEntry *current_Node = (struct IconEntry *)GetHead(icon_list);
258 if ((current_Node != NULL) && !(current_Node->ie_Flags & ICONENTRY_FLAG_VISIBLE))
259 current_Node = Node_NextVisible(current_Node);
261 return current_Node;
265 ///Node_PreviousVisible()
266 static struct IconEntry *Node_PreviousVisible(struct IconEntry *current_Node)
268 current_Node = (struct IconEntry *)GetPred(&current_Node->ie_IconNode);
269 while ((current_Node != NULL) && (!(current_Node->ie_Flags & ICONENTRY_FLAG_VISIBLE)))
271 current_Node = (struct IconEntry *)GetPred(&current_Node->ie_IconNode);
273 return current_Node;
277 ///Node_LastVisible()
278 static struct IconEntry *Node_LastVisible(struct List *icon_list)
280 struct IconEntry *current_Node = (struct IconEntry *)GetTail(icon_list);
282 if ((current_Node != NULL) && !(current_Node->ie_Flags & ICONENTRY_FLAG_VISIBLE))
283 current_Node = Node_PreviousVisible(current_Node);
285 return current_Node;
289 const UBYTE MSG_MEM_G[] = "GB";
290 const UBYTE MSG_MEM_M[] = "MB";
291 const UBYTE MSG_MEM_K[] = "KB";
292 const UBYTE MSG_MEM_B[] = "Bytes";
294 ///FmtSizeToString()
295 static void FmtSizeToString(UBYTE *buf, ULONG num)
297 UQUAD d;
298 UBYTE *ch;
299 struct
301 IPTR val;
302 IPTR dec;
303 } array =
305 num,
309 if (num >= 1073741824)
311 //Gigabytes
312 array.val = num >> 30;
313 d = ((UQUAD)num * 10 + 536870912) / 1073741824;
314 array.dec = d % 10;
315 ch = MSG_MEM_G;
317 else if (num >= 1048576)
319 //Megabytes
320 array.val = num >> 20;
321 d = ((UQUAD)num * 10 + 524288) / 1048576;
322 array.dec = d % 10;
323 ch = MSG_MEM_M;
325 else if (num >= 1024)
327 //Kilobytes
328 array.val = num >> 10;
329 d = (num * 10 + 512) / 1024;
330 array.dec = d % 10;
331 ch = MSG_MEM_K;
333 else
335 //Bytes
336 array.val = num;
337 array.dec = 0;
338 d = 0;
339 ch = MSG_MEM_B;
342 if (!array.dec && (d > array.val * 10))
344 array.val++;
347 RawDoFmt(array.dec ? "%lu.%lu" : "%lu", &array, NULL, buf);
349 while (*buf)
351 buf++;
354 sprintf(buf, " %s", ch);
358 ///GetAbsoluteLassoRect()
359 // get positive lasso coords
360 static void GetAbsoluteLassoRect(struct IconList_DATA *data, struct Rectangle *LassoRectangle)
362 WORD minx = data->icld_LassoRectangle.MinX;
363 WORD miny = data->icld_LassoRectangle.MinY;
364 WORD maxx = data->icld_LassoRectangle.MaxX;
365 WORD maxy = data->icld_LassoRectangle.MaxY;
367 #if defined(DEBUG_ILC_LASSO) || defined(DEBUG_ILC_FUNCS)
368 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
369 #endif
371 if (minx > maxx)
373 /* Swap minx, maxx */
374 minx ^= maxx;
375 maxx ^= minx;
376 minx ^= maxx;
379 if (miny > maxy)
381 /* Swap miny, maxy */
382 miny ^= maxy;
383 maxy ^= miny;
384 miny ^= maxy;
387 LassoRectangle->MinX = data->view_rect.MinX - data->icld_ViewX + minx;
388 LassoRectangle->MinY = data->view_rect.MinY - data->icld_ViewY + miny;
389 LassoRectangle->MaxX = data->view_rect.MinX - data->icld_ViewX + maxx;
390 LassoRectangle->MaxY = data->view_rect.MinY - data->icld_ViewY + maxy;
394 ///IconList_InvertPixelRect()
395 static void IconList_InvertPixelRect(struct RastPort *rp, WORD minx, WORD miny, WORD maxx, WORD maxy, struct Rectangle *clip)
397 struct Rectangle r, clipped_r;
399 #if defined(DEBUG_ILC_RENDERING) || defined(DEBUG_ILC_FUNCS)
400 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
401 #endif
403 if (maxx < minx)
405 /* Swap minx, maxx */
406 minx ^= maxx;
407 maxx ^= minx;
408 minx ^= maxx;
411 if (maxy < miny)
413 /* Swap miny, maxy */
414 miny ^= maxy;
415 maxy ^= miny;
416 miny ^= maxy;
419 r.MinX = minx;
420 r.MinY = miny;
421 r.MaxX = maxx;
422 r.MaxY = maxy;
424 if (AndRectRect(&r, clip, &clipped_r))
426 InvertPixelArray(rp, clipped_r.MinX, clipped_r.MinY,
427 clipped_r.MaxX - clipped_r.MinX + 1, clipped_r.MaxY - clipped_r.MinY + 1);
432 ///IconList_InvertLassoOutlines()
433 // Simple lasso drawing by inverting area outlines
434 static void IconList_InvertLassoOutlines(Object *obj, struct IconList_DATA *data, struct Rectangle *rect)
436 struct Rectangle lasso;
437 struct Rectangle clip;
439 #if defined(DEBUG_ILC_LASSO) || defined(DEBUG_ILC_FUNCS)
440 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
441 #endif
443 /* get abolute iconlist coords */
444 lasso.MinX = rect->MinX + _mleft(obj);
445 lasso.MaxX = rect->MaxX + _mleft(obj);
446 lasso.MinY = rect->MinY + _mtop(obj);
447 lasso.MaxY = rect->MaxY + _mtop(obj);
449 clip.MinX = _mleft(obj);
450 clip.MinY = _mtop(obj);
451 if ((data->icld_DisplayFlags & ICONLIST_DISP_MODELIST) == ICONLIST_DISP_MODELIST)
453 clip.MinY += data->icld_LVMAttribs->lmva_HeaderHeight;
455 clip.MaxX = _mright(obj);
456 clip.MaxY = _mbottom(obj);
458 /* horizontal lasso lines */
459 IconList_InvertPixelRect(_rp(obj), lasso.MinX, lasso.MinY, lasso.MaxX-1, lasso.MinY + 1, &clip);
460 IconList_InvertPixelRect(_rp(obj), lasso.MinX, lasso.MaxY, lasso.MaxX-1, lasso.MaxY + 1, &clip);
462 /* vertical lasso lines */
463 IconList_InvertPixelRect(_rp(obj), lasso.MinX, lasso.MinY, lasso.MinX + 1, lasso.MaxY - 1, &clip);
464 IconList_InvertPixelRect(_rp(obj), lasso.MaxX, lasso.MinY, lasso.MaxX + 1, lasso.MaxY - 1, &clip);
468 ///IconList_GetIconImageRectangle()
469 //We don't use icon.library's label drawing so we do this by hand
470 static void IconList_GetIconImageRectangle(Object *obj, struct IconList_DATA *data, struct IconEntry *entry, struct Rectangle *rect)
472 #if defined(DEBUG_ILC_ICONPOSITIONING) || defined(DEBUG_ILC_FUNCS)
473 D(bug("[IconList]: %s(entry @ %p)\n", __PRETTY_FUNCTION__, entry));
474 #endif
476 /* Get basic width/height */
477 GetIconRectangleA(NULL, entry->ie_DiskObj, NULL, rect, NULL);
478 #if defined(DEBUG_ILC_ICONPOSITIONING)
479 D(bug("[IconList] %s: MinX %d, MinY %d MaxX %d, MaxY %d\n", __PRETTY_FUNCTION__, rect->MinX, rect->MinY, rect->MaxX, rect->MaxY));
480 #endif
481 entry->ie_IconWidth = (rect->MaxX - rect->MinX) + 1;
482 entry->ie_IconHeight = (rect->MaxY - rect->MinY) + 1;
484 if (entry->ie_IconHeight > data->icld_IconLargestHeight)
485 data->icld_IconLargestHeight = entry->ie_IconHeight;
489 ///IconList_GetIconLabelRectangle()
490 static void IconList_GetIconLabelRectangle(Object *obj, struct IconList_DATA *data, struct IconEntry *entry, struct Rectangle *rect)
492 ULONG outline_offset = 0;
493 ULONG textwidth = 0;
495 #if defined(DEBUG_ILC_ICONPOSITIONING) || defined(DEBUG_ILC_FUNCS)
496 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
497 #endif
499 switch ( data->icld__Option_LabelTextMode )
501 case ICON_TEXTMODE_DROPSHADOW:
502 outline_offset = 1;
503 break;
505 case ICON_TEXTMODE_PLAIN:
506 break;
508 default:
509 outline_offset = 2;
510 break;
513 /* Get entry box width including text width */
514 if ((entry->ie_IconListEntry.label != NULL) && (entry->ie_TxtBuf_DisplayedLabel != NULL))
516 ULONG curlabel_TotalLines;
517 SetFont(data->icld_BufferRastPort, data->icld_IconLabelFont);
519 rect->MinX = 0;
520 rect->MaxX = (((data->icld__Option_LabelTextHorizontalPadding + data->icld__Option_LabelTextBorderWidth) * 2) + entry->ie_TxtBuf_DisplayedLabelWidth + outline_offset) - 1;
522 rect->MinY = 0;
524 curlabel_TotalLines = entry->ie_SplitParts;
525 if (curlabel_TotalLines == 0)
526 curlabel_TotalLines = 1;
527 if (curlabel_TotalLines > data->icld__Option_LabelTextMultiLine)
528 curlabel_TotalLines = data->icld__Option_LabelTextMultiLine;
530 rect->MaxY = (((data->icld__Option_LabelTextBorderHeight + data->icld__Option_LabelTextVerticalPadding) * 2) +
531 ((data->icld_IconLabelFont->tf_YSize + outline_offset) * curlabel_TotalLines)) - 1;
533 /* Date/size sorting has the date/size appended under the entry label
534 only list regular files like this (drawers have no size/date output) */
536 entry->ie_IconListEntry.type != ST_USERDIR &&
537 ((data->icld_SortFlags & MUIV_IconList_Sort_BySize) || (data->icld_SortFlags & MUIV_IconList_Sort_ByDate))
540 SetFont(data->icld_BufferRastPort, data->icld_IconInfoFont);
542 if( (data->icld_SortFlags & MUIV_IconList_Sort_BySize) && !(data->icld_SortFlags & MUIV_IconList_Sort_ByDate) )
544 entry->ie_TxtBuf_SIZEWidth = TextLength(data->icld_BufferRastPort, entry->ie_TxtBuf_SIZE, strlen(entry->ie_TxtBuf_SIZE));
545 textwidth = entry->ie_TxtBuf_SIZEWidth;
547 else
549 if( !(data->icld_SortFlags & MUIV_IconList_Sort_BySize) && (data->icld_SortFlags & MUIV_IconList_Sort_ByDate) )
551 if( entry->ie_Flags & ICONENTRY_FLAG_TODAY )
553 entry->ie_TxtBuf_TIMEWidth = TextLength(data->icld_BufferRastPort, entry->ie_TxtBuf_TIME, strlen(entry->ie_TxtBuf_TIME));
554 textwidth = entry->ie_TxtBuf_TIMEWidth;
556 else
558 entry->ie_TxtBuf_DATEWidth = TextLength(data->icld_BufferRastPort, entry->ie_TxtBuf_DATE, strlen(entry->ie_TxtBuf_DATE));
559 textwidth = entry->ie_TxtBuf_DATEWidth;
564 if (textwidth > 0)
566 rect->MaxY = rect->MaxY + data->icld_IconInfoFont->tf_YSize + outline_offset;
567 if ((textwidth + outline_offset + ((data->icld__Option_LabelTextHorizontalPadding + data->icld__Option_LabelTextBorderWidth) * 2)) > ((rect->MaxX - rect->MinX) + 1))
568 rect->MaxX = (textwidth + outline_offset + ((data->icld__Option_LabelTextVerticalPadding + data->icld__Option_LabelTextBorderWidth) * 2)) - 1;
572 if (((rect->MaxY - rect->MinY) + 1) > data->icld_LabelLargestHeight) data->icld_LabelLargestHeight = ((rect->MaxY - rect->MinY) + 1);
576 ///IconList_GetIconAreaRectangle()
577 static void IconList_GetIconAreaRectangle(Object *obj, struct IconList_DATA *data, struct IconEntry *entry, struct Rectangle *rect)
579 struct Rectangle labelrect;
580 ULONG iconlabel_Width;
581 ULONG iconlabel_Height;
583 #if defined(DEBUG_ILC_ICONPOSITIONING) || defined(DEBUG_ILC_FUNCS)
584 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
585 #endif
587 /* Get entry box width including text width */
588 memset(rect, 0, sizeof(struct Rectangle));
590 IconList_GetIconImageRectangle(obj, data, entry, rect);
592 entry->ie_AreaWidth = entry->ie_IconWidth;
593 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
595 entry->ie_AreaHeight = data->icld_IconLargestHeight;
597 else
599 entry->ie_AreaHeight = entry->ie_IconHeight;
602 IconList_GetIconLabelRectangle(obj, data, entry, &labelrect);
604 iconlabel_Width = ((labelrect.MaxX - labelrect.MinX) + 1);
605 iconlabel_Height = ((labelrect.MaxY - labelrect.MinY) + 1);
607 if (iconlabel_Width > entry->ie_AreaWidth)
608 entry->ie_AreaWidth = iconlabel_Width;
610 entry->ie_AreaHeight = entry->ie_AreaHeight + data->icld__Option_IconImageSpacing + iconlabel_Height;
612 /* Store */
613 rect->MaxX = (rect->MinX + entry->ie_AreaWidth) - 1;
614 rect->MaxY = (rect->MinY + entry->ie_AreaHeight) - 1;
616 if (entry->ie_AreaWidth > data->icld_IconAreaLargestWidth) data->icld_IconAreaLargestWidth = entry->ie_AreaWidth;
617 if (entry->ie_AreaHeight > data->icld_IconAreaLargestHeight) data->icld_IconAreaLargestHeight = entry->ie_AreaHeight;
621 static LONG FirstVisibleColumnNumber(struct IconList_DATA *data)
623 LONG i;
624 LONG retval = -1;
626 if (data->icld_LVMAttribs != NULL)
628 for(i = 0; i < NUM_COLUMNS; i++)
630 LONG index = data->icld_LVMAttribs->lmva_ColumnPos[i];
632 if (data->icld_LVMAttribs->lmva_ColumnFlags[index] & LVMCF_COLVISIBLE)
634 retval = i;
635 break;
640 return retval;
643 static LONG LastVisibleColumnNumber(struct IconList_DATA *data)
645 LONG i;
646 LONG retval = -1;
648 if (data->icld_LVMAttribs != NULL)
650 for(i = 0; i < NUM_COLUMNS; i++)
652 LONG index = data->icld_LVMAttribs->lmva_ColumnPos[i];
654 if (data->icld_LVMAttribs->lmva_ColumnFlags[index] & LVMCF_COLVISIBLE)
656 retval = i;
661 return retval;
665 static void RenderEntryField(Object *obj, struct IconList_DATA *data,
666 struct IconEntry *entry, struct Rectangle *rect,
667 LONG index, BOOL firstvis, BOOL lastvis)
669 STRPTR text, renderflag = "<UHOH>";
670 struct TextExtent te;
671 ULONG fit;
673 if (entry->ie_Flags & ICONENTRY_FLAG_SELECTED)
675 FillPixelArray(data->icld_BufferRastPort,
676 rect->MinX, rect->MinY,
677 rect->MaxX - rect->MinX + 1, rect->MaxY - rect->MinY,
678 0x0A246A);
681 rect->MinX += ENTRY_SPACING_LEFT;
682 rect->MaxX -= ENTRY_SPACING_RIGHT;
683 rect->MinY += LINE_SPACING_TOP;
684 rect->MaxY -= LINE_SPACING_BOTTOM;
686 if (firstvis) rect->MinX += LINE_SPACING_LEFT;
687 if (lastvis) rect->MaxX -= LINE_SPACING_RIGHT;
689 if (!entry) return;
691 switch(index)
693 case INDEX_TYPE:
694 /* Special case !! we draw an image instead .. */
695 text = renderflag;
696 break;
698 case INDEX_NAME:
699 text = entry->ie_IconListEntry.label;
700 break;
702 case INDEX_SIZE:
703 text = entry->ie_TxtBuf_SIZE;
704 break;
706 case INDEX_LASTACCESS:
707 text = AllocVec(strlen(entry->ie_TxtBuf_DATE) + strlen(entry->ie_TxtBuf_TIME) + 5, MEMF_CLEAR);
708 sprintf(text, "%s at %s", entry->ie_TxtBuf_DATE, entry->ie_TxtBuf_TIME);
709 break;
711 case INDEX_COMMENT:
712 text = entry->ie_FileInfoBlock->fib_Comment;
713 break;
715 case INDEX_PROTECTION:
716 text = entry->ie_TxtBuf_PROT;
717 break;
720 if (!text) return;
721 if (!text[0]) return;
723 if (text == renderflag)
725 if (entry->ie_IconListEntry.type == ST_USERDIR)
727 if (data->icld_LVMAttribs->lvma_IconDrawer)
729 DrawIconStateA
731 data->icld_BufferRastPort, data->icld_LVMAttribs->lvma_IconDrawer, NULL,
732 rect->MinX + 1, rect->MinY + 1,
733 (entry->ie_Flags & ICONENTRY_FLAG_SELECTED) ? IDS_SELECTED : IDS_NORMAL,
734 __iconList_DrawIconStateTags
737 else
739 FillPixelArray(data->icld_BufferRastPort,
740 rect->MinX + 1, rect->MinY + 1,
741 rect->MaxX - rect->MinX - 1, rect->MaxY - rect->MinY - 1,
742 0xc0f0f0);
745 else
747 if (data->icld_LVMAttribs->lvma_IconFile)
749 DrawIconStateA
751 data->icld_BufferRastPort, data->icld_LVMAttribs->lvma_IconFile, NULL,
752 rect->MinX + 1, rect->MinY + 1,
753 (entry->ie_Flags & ICONENTRY_FLAG_SELECTED) ? IDS_SELECTED : IDS_NORMAL,
754 __iconList_DrawIconStateTags
757 else
759 FillPixelArray(data->icld_BufferRastPort,
760 rect->MinX + 1, rect->MinY + 1,
761 rect->MaxX - rect->MinX - 1, rect->MaxY - rect->MinY - 1,
762 0xe0e0e0);
766 else
768 fit = TextFit(data->icld_BufferRastPort, text, strlen(text), &te, NULL, 1,
769 rect->MaxX - rect->MinX + 1,
770 rect->MaxY - rect->MinY + 1);
772 if (!fit) return;
774 SetABPenDrMd(data->icld_BufferRastPort, _pens(obj)[(entry->ie_Flags & ICONENTRY_FLAG_SELECTED) ? MPEN_SHINE : MPEN_TEXT], 0, JAM1);
776 if (((rect->MaxY - rect->MinY + 1) - data->icld_IconLabelFont->tf_YSize) > 0)
778 rect->MinY += ((rect->MaxY - rect->MinY + 1) - data->icld_IconLabelFont->tf_YSize)/2;
781 switch(data->icld_LVMAttribs->lmva_ColumnHAlign[index])
783 case COLUMN_ALIGN_LEFT:
784 Move(data->icld_BufferRastPort, rect->MinX, rect->MinY + data->icld_BufferRastPort->TxBaseline);
785 break;
787 case COLUMN_ALIGN_RIGHT:
788 Move(data->icld_BufferRastPort, rect->MaxX - te.te_Width, rect->MinY + data->icld_BufferRastPort->TxBaseline);
789 break;
791 case COLUMN_ALIGN_CENTER:
792 Move(data->icld_BufferRastPort, rect->MinX + (rect->MaxX - rect->MinX + 1 + 1 - te.te_Width) / 2,
793 rect->MinY + data->icld_BufferRastPort->TxBaseline);
794 break;
797 Text(data->icld_BufferRastPort, text, fit);
799 if ((index == INDEX_LASTACCESS) && text)
800 FreeVec(text);
804 /**************************************************************************
805 Draw the entry at its position
806 **************************************************************************/
807 ///IconList__MUIM_IconList_DrawEntry()
808 IPTR IconList__MUIM_IconList_DrawEntry(struct IClass *CLASS, Object *obj, struct MUIP_IconList_DrawEntry *message)
810 struct IconList_DATA *data = INST_DATA(CLASS, obj);
812 BOOL outside = FALSE;
814 struct Rectangle iconrect;
815 struct Rectangle objrect;
817 LONG offsetx,offsety;
819 ULONG objX, objY, objW, objH;
820 LONG iconX, iconY;
821 ULONG iconW, iconH;
823 if (data->icld_BufferRastPort == data->icld_DisplayRastPort)
825 objX = _mleft(obj);
826 objY = _mtop(obj);
828 else
830 objX = objY = 0;
832 objW = _mright(obj) - _mleft(obj) + 1;
833 objH = _mbottom(obj) - _mtop(obj) + 1;
835 #if defined(DEBUG_ILC_ICONRENDERING)
836 D(bug("[IconList]: %s(message->entry = 0x%p)\n", __PRETTY_FUNCTION__, message->entry));
837 #endif
839 if ((!(message->entry->ie_Flags & ICONENTRY_FLAG_VISIBLE)) ||
840 (data->icld_BufferRastPort == NULL) ||
841 (!(message->entry->ie_DiskObj)))
843 #if defined(DEBUG_ILC_ICONRENDERING)
844 D(bug("[IconList] %s: Not visible or missing DOB\n", __PRETTY_FUNCTION__));
845 #endif
846 return FALSE;
849 /* Set the dimensions of our "view" */
850 objrect.MinX = objX;
851 objrect.MinY = objY;
852 objrect.MaxX = objX + objW - 1;
853 objrect.MaxY = objY + objH - 1;
855 if ((data->icld_DisplayFlags & ICONLIST_DISP_MODELIST) == ICONLIST_DISP_MODELIST)
857 struct Rectangle linerect;
858 LONG x, i;
859 LONG firstvis, lastvis;
861 linerect.MinX = objX - data->icld_ViewX;
862 linerect.MaxX = objX + objW - 1; //linerect.MinX + data->width - 1;
863 linerect.MinY = (objY - data->icld_ViewY) + data->icld_LVMAttribs->lmva_HeaderHeight + (message->drawmode * data->icld_LVMAttribs->lmva_RowHeight);
864 linerect.MaxY = linerect.MinY + data->icld_LVMAttribs->lmva_RowHeight - 1;
866 if (!AndRectRect(&linerect, &objrect, NULL)) return;
867 // if (!MustRenderRect(data, &linerect)) return;
869 SetFont(data->icld_BufferRastPort, data->icld_IconLabelFont);
871 x = linerect.MinX + LINE_SPACING_LEFT;
873 firstvis = FirstVisibleColumnNumber(data);
874 lastvis = LastVisibleColumnNumber(data);
876 for(i = 0; i < NUM_COLUMNS; i++)
878 struct Rectangle field_rect;
879 LONG index = data->icld_LVMAttribs->lmva_ColumnPos[i];
881 if (!(data->icld_LVMAttribs->lmva_ColumnFlags[i] & LVMCF_COLVISIBLE)) continue;
883 field_rect.MinX = (i == firstvis) ? linerect.MinX : x;
884 field_rect.MinY = linerect.MinY;
885 field_rect.MaxX = x + data->icld_LVMAttribs->lmva_ColumnWidth[index] - 1 + ((i == lastvis) ? LINE_SPACING_RIGHT : 0);
886 field_rect.MaxY = linerect.MaxY;
888 /* if (MustRenderRect(data, &field_rect))
890 if (AndRectRect(&field_rect, &objrect, NULL))
892 RenderEntryField(obj, data, message->entry, &field_rect, index,
893 (i == firstvis), (i == lastvis));
895 /* }*/
896 x += data->icld_LVMAttribs->lmva_ColumnWidth[index];
899 if ((data->icld_LVMAttribs->lvma_Flags & LVMAF_ROWDRAWTOEND) == LVMAF_ROWDRAWTOEND)
901 x += LINE_SPACING_RIGHT;
903 if (x < linerect.MaxX)
905 linerect.MinX = x;
907 SetABPenDrMd(data->icld_BufferRastPort, _pens(obj)[MPEN_SHINE], 0, JAM1);
908 RectFill(data->icld_BufferRastPort, linerect.MinX, linerect.MinY, linerect.MaxX, linerect.MaxY);
912 else
914 /* Get the dimensions and affected area of message->entry */
915 IconList_GetIconImageRectangle(obj, data, message->entry, &iconrect);
916 iconW = iconrect.MaxX - iconrect.MinX + 1;
917 iconH = iconrect.MaxY - iconrect.MinY + 1;
919 /* Add the relative position offset of the message->entry */
920 offsetx = objX - data->icld_ViewX + message->entry->ie_IconX;
921 /* Centre our image with our text */
922 if (message->entry->ie_IconWidth < message->entry->ie_AreaWidth)
923 offsetx += (message->entry->ie_AreaWidth - message->entry->ie_IconWidth)/2;
925 if ((data->icld__Option_IconListMode == ICON_LISTMODE_GRID) &&
926 (message->entry->ie_AreaWidth < data->icld_IconAreaLargestWidth))
927 offsetx += ((data->icld_IconAreaLargestWidth - message->entry->ie_AreaWidth)/2);
929 iconrect.MinX += offsetx;
930 iconrect.MaxX += offsetx;
932 offsety = objY - data->icld_ViewY + message->entry->ie_IconY;
933 iconrect.MinY += offsety;
934 iconrect.MaxY += offsety;
936 if (!RectAndRect(&iconrect, &objrect))
938 #if defined(DEBUG_ILC_ICONRENDERING)
939 D(bug("[IconList] %s: Entry '%s' image outside of visible area .. skipping\n", __PRETTY_FUNCTION__, message->entry->ie_IconListEntry.label));
940 #endif
941 return FALSE;
944 /* data->update_rect1 and data->update_rect2 may
945 point to rectangles to indicate that only icons
946 in any of this rectangles need to be drawn */
947 if (data->update_rect1)
949 if (!RectAndRect(&iconrect, data->update_rect1)) outside = TRUE;
952 if (data->update_rect2)
954 if (data->update_rect1)
956 if ((outside == TRUE) && RectAndRect(&iconrect, data->update_rect2))
957 outside = FALSE;
959 else
961 if (!RectAndRect(&iconrect, data->update_rect2))
962 outside = TRUE;
966 if (outside == TRUE)
968 #if defined(DEBUG_ILC_ICONRENDERING)
969 D(bug("[IconList] %s: Entry '%s' image outside of update area .. skipping\n", __PRETTY_FUNCTION__, message->entry->ie_IconListEntry.label));
970 #endif
971 return FALSE;
974 if (message->drawmode == ICONENTRY_DRAWMODE_NONE) return TRUE;
976 // Center entry image
977 iconX = iconrect.MinX - objX + data->icld_DrawOffsetX;
978 iconY = iconrect.MinY - objY + data->icld_DrawOffsetY;
980 #if defined(DEBUG_ILC_ICONRENDERING)
981 D(bug("[IconList] %s: DrawIconState('%s') .. %d, %d\n", __PRETTY_FUNCTION__, message->entry->ie_IconListEntry.label, iconX, iconY));
982 #endif
983 DrawIconStateA
985 data->icld_BufferRastPort, message->entry->ie_DiskObj, NULL,
986 iconX,
987 iconY,
988 (message->entry->ie_Flags & ICONENTRY_FLAG_SELECTED) ? IDS_SELECTED : IDS_NORMAL,
989 __iconList_DrawIconStateTags
991 #if defined(DEBUG_ILC_ICONRENDERING)
992 D(bug("[IconList] %s: DrawIconState Done\n", __PRETTY_FUNCTION__));
993 #endif
996 return TRUE;
1000 ///IconList__LabelFunc_SplitLabel()
1001 static void IconList__LabelFunc_SplitLabel(Object *obj, struct IconList_DATA *data, struct IconEntry *entry)
1003 ULONG labelSplit_MaxLabelLineLength = data->icld__Option_LabelTextMaxLen;
1004 ULONG labelSplit_LabelLength = strlen(entry->ie_IconListEntry.label);
1005 ULONG txwidth;
1006 // ULONG labelSplit_FontY = data->icld_IconLabelFont->tf_YSize;
1007 int labelSplit_CharsDone, labelSplit_CharsSplit;
1008 ULONG labelSplit_CurSplitWidth;
1010 if ((data->icld__Option_TrimVolumeNames) &&
1011 ((entry->ie_IconListEntry.type == ST_ROOT) && (entry->ie_IconListEntry.label[labelSplit_LabelLength - 1] == ':')))
1012 labelSplit_LabelLength--;
1014 if (labelSplit_MaxLabelLineLength >= labelSplit_LabelLength)
1016 #if defined(DEBUG_ILC_ICONRENDERING)
1017 D(bug("[IconList]: %s: Label'%s' doesnt need split (onyl %d chars)\n", __PRETTY_FUNCTION__, entry->ie_IconListEntry.label, labelSplit_LabelLength));
1018 #endif
1019 return;
1022 SetFont(data->icld_BufferRastPort, data->icld_IconLabelFont);
1023 txwidth = TextLength(data->icld_BufferRastPort, entry->ie_IconListEntry.label, labelSplit_MaxLabelLineLength);
1024 #if defined(DEBUG_ILC_ICONRENDERING)
1025 D(bug("[IconList]: %s: txwidth = %d\n", __PRETTY_FUNCTION__, txwidth));
1026 #endif
1027 entry->ie_TxtBuf_DisplayedLabel = AllocVecPooled(data->icld_Pool, 256);
1028 memset(entry->ie_TxtBuf_DisplayedLabel, 0, 256);
1029 entry->ie_SplitParts = 0;
1031 labelSplit_CharsDone = 0;
1032 labelSplit_CharsSplit = 0;
1034 while (labelSplit_CharsDone < labelSplit_LabelLength)
1036 ULONG labelSplit_CurSplitLength = labelSplit_LabelLength - labelSplit_CharsDone;
1037 IPTR labelSplit_SplitStart = (IPTR)(entry->ie_IconListEntry.label + labelSplit_CharsDone);
1038 int tmp_checkoffs = 0;
1039 IPTR labelSplit_RemainingCharsAfterSplit;
1040 IPTR labelSplit_CurSplitDest;
1042 while (*(char *)(labelSplit_SplitStart) == ' ')
1044 //Skip preceding spaces..
1045 labelSplit_SplitStart = labelSplit_SplitStart + 1;
1046 labelSplit_CurSplitLength = labelSplit_CurSplitLength - 1;
1047 labelSplit_CharsDone = labelSplit_CharsDone + 1;
1050 while(TextLength(data->icld_BufferRastPort, (char *)labelSplit_SplitStart, labelSplit_CurSplitLength) < txwidth) labelSplit_CurSplitLength++;
1051 while(TextLength(data->icld_BufferRastPort, (char *)labelSplit_SplitStart, labelSplit_CurSplitLength) > txwidth) labelSplit_CurSplitLength--;
1052 #if defined(DEBUG_ILC_ICONRENDERING)
1053 D(bug("[IconList]: %s: labelSplit_CurSplitLength = %d\n", __PRETTY_FUNCTION__, labelSplit_CurSplitLength));
1054 #endif
1056 #if defined(DEBUG_ILC_ICONRENDERING)
1057 D(bug("[IconList]: %s: Attempting to find neat split ", __PRETTY_FUNCTION__));
1058 #endif
1059 while(tmp_checkoffs < (labelSplit_CurSplitLength - ILC_ICONLABEL_SHORTEST))
1061 #if defined(DEBUG_ILC_ICONRENDERING)
1062 D(bug("%d", tmp_checkoffs));
1063 #endif
1064 labelSplit_RemainingCharsAfterSplit = labelSplit_LabelLength - (labelSplit_CharsDone + labelSplit_CurSplitLength);
1066 if ((labelSplit_CurSplitLength - tmp_checkoffs) > ILC_ICONLABEL_SHORTEST)
1068 #if defined(DEBUG_ILC_ICONRENDERING)
1069 D(bug("<"));
1070 #endif
1071 if ((*(char *)(labelSplit_SplitStart + labelSplit_CurSplitLength - tmp_checkoffs) == ' ') ||
1072 (*(char *)(labelSplit_SplitStart + labelSplit_CurSplitLength - tmp_checkoffs) == '.') ||
1073 (*(char *)(labelSplit_SplitStart + labelSplit_CurSplitLength - tmp_checkoffs) == '-'))
1075 #if defined(DEBUG_ILC_ICONRENDERING)
1076 D(bug("!"));
1077 #endif
1078 labelSplit_CurSplitLength = labelSplit_CurSplitLength - tmp_checkoffs;
1079 labelSplit_RemainingCharsAfterSplit = labelSplit_RemainingCharsAfterSplit - tmp_checkoffs;
1080 tmp_checkoffs = 0;
1081 break;
1085 if ((labelSplit_RemainingCharsAfterSplit - tmp_checkoffs) < 0)
1087 #if defined(DEBUG_ILC_ICONRENDERING)
1088 D(bug("="));
1089 #endif
1090 labelSplit_CurSplitLength = labelSplit_CurSplitLength + tmp_checkoffs;
1091 labelSplit_RemainingCharsAfterSplit = labelSplit_RemainingCharsAfterSplit + tmp_checkoffs;
1092 tmp_checkoffs = 0;
1093 break;
1096 if ((labelSplit_RemainingCharsAfterSplit - tmp_checkoffs) >= ILC_ICONLABEL_SHORTEST)
1098 #if defined(DEBUG_ILC_ICONRENDERING)
1099 D(bug(">"));
1100 #endif
1101 if ((*(char *)(labelSplit_SplitStart + labelSplit_CurSplitLength + tmp_checkoffs) == ' ') ||
1102 (*(char *)(labelSplit_SplitStart + labelSplit_CurSplitLength + tmp_checkoffs) == '.') ||
1103 (*(char *)(labelSplit_SplitStart + labelSplit_CurSplitLength + tmp_checkoffs) == '-'))
1105 #if defined(DEBUG_ILC_ICONRENDERING)
1106 D(bug("!"));
1107 #endif
1108 labelSplit_CurSplitLength = labelSplit_CurSplitLength + tmp_checkoffs;
1109 labelSplit_RemainingCharsAfterSplit = labelSplit_RemainingCharsAfterSplit + tmp_checkoffs;
1110 tmp_checkoffs = 0;
1111 break;
1115 tmp_checkoffs = tmp_checkoffs + 1;
1117 #if defined(DEBUG_ILC_ICONRENDERING)
1118 D(bug("\n"));
1119 #endif
1120 if (tmp_checkoffs != 0)
1122 #if defined(DEBUG_ILC_ICONRENDERING)
1123 D(bug("[IconList]: %s: Couldnt find neat split : Still %d chars\n", __PRETTY_FUNCTION__, labelSplit_RemainingCharsAfterSplit));
1124 #endif
1125 if (labelSplit_RemainingCharsAfterSplit <= ILC_ICONLABEL_SHORTEST)
1127 labelSplit_CurSplitLength = labelSplit_CurSplitLength + (labelSplit_RemainingCharsAfterSplit - ILC_ICONLABEL_SHORTEST);
1130 if ((labelSplit_CharsDone + labelSplit_CurSplitLength) > labelSplit_LabelLength) labelSplit_CurSplitLength = labelSplit_LabelLength - labelSplit_CharsDone;
1132 labelSplit_CurSplitDest = (IPTR)(entry->ie_TxtBuf_DisplayedLabel + labelSplit_CharsSplit + entry->ie_SplitParts);
1134 strncpy((char *)labelSplit_CurSplitDest, (char *)labelSplit_SplitStart, labelSplit_CurSplitLength);
1136 labelSplit_CurSplitWidth = TextLength(data->icld_BufferRastPort, (char *)labelSplit_CurSplitDest, labelSplit_CurSplitLength);
1138 entry->ie_SplitParts = entry->ie_SplitParts + 1;
1140 labelSplit_CharsDone = labelSplit_CharsDone + labelSplit_CurSplitLength;
1141 labelSplit_CharsSplit = labelSplit_CharsSplit + labelSplit_CurSplitLength;
1143 if (labelSplit_CurSplitWidth > entry->ie_TxtBuf_DisplayedLabelWidth) entry->ie_TxtBuf_DisplayedLabelWidth = labelSplit_CurSplitWidth;
1145 if ((entry->ie_SplitParts <= 1) && entry->ie_TxtBuf_DisplayedLabel)
1147 FreeVecPooled(data->icld_Pool, entry->ie_TxtBuf_DisplayedLabel);
1148 entry->ie_TxtBuf_DisplayedLabel = NULL;
1149 entry->ie_SplitParts = 0;
1151 // if ((labelSplit_FontY * entry->ie_SplitParts) > data->icld_LabelLargestHeight) data->icld_LabelLargestHeight = (labelSplit_FontY * entry->ie_SplitParts);
1155 ///IconList__LabelFunc_CreateLabel()
1156 static IPTR IconList__LabelFunc_CreateLabel(Object *obj, struct IconList_DATA *data, struct IconEntry *entry)
1158 #if defined(DEBUG_ILC_ICONRENDERING) || defined(DEBUG_ILC_FUNCS)
1159 D(bug("[IconList]: %s('%s')\n", __PRETTY_FUNCTION__, entry->ie_IconListEntry.label));
1160 #endif
1161 if (entry->ie_TxtBuf_DisplayedLabel)
1163 FreeVecPooled(data->icld_Pool, entry->ie_TxtBuf_DisplayedLabel);
1164 entry->ie_TxtBuf_DisplayedLabel = NULL;
1165 entry->ie_SplitParts = 0;
1168 if (data->icld__Option_LabelTextMultiLine > 1)
1170 #if defined(DEBUG_ILC_ICONRENDERING)
1171 D(bug("[IconList]: %s: Attempting to split label ..\n", __PRETTY_FUNCTION__));
1172 #endif
1173 IconList__LabelFunc_SplitLabel(obj, data, entry);
1176 if (entry->ie_TxtBuf_DisplayedLabel == NULL)
1178 ULONG ie_LabelLength = strlen(entry->ie_IconListEntry.label);
1179 entry->ie_SplitParts = 1;
1181 #if defined(DEBUG_ILC_ICONRENDERING)
1182 D(bug("[IconList]: %s: Building unsplit label (len = %d) ..\n", __PRETTY_FUNCTION__, ie_LabelLength));
1183 #endif
1185 if ((data->icld__Option_TrimVolumeNames) &&
1186 ((entry->ie_IconListEntry.type == ST_ROOT) && (entry->ie_IconListEntry.label[ie_LabelLength - 1] == ':')))
1187 ie_LabelLength--;
1189 if(ie_LabelLength > data->icld__Option_LabelTextMaxLen)
1191 if (!(entry->ie_TxtBuf_DisplayedLabel = AllocVecPooled(data->icld_Pool, data->icld__Option_LabelTextMaxLen + 1)))
1193 return (IPTR)NULL;
1195 memset(entry->ie_TxtBuf_DisplayedLabel, 0, data->icld__Option_LabelTextMaxLen + 1);
1196 strncpy(entry->ie_TxtBuf_DisplayedLabel, entry->ie_IconListEntry.label, data->icld__Option_LabelTextMaxLen - 3);
1197 strcat(entry->ie_TxtBuf_DisplayedLabel , " ..");
1199 else
1201 if (!(entry->ie_TxtBuf_DisplayedLabel = AllocVecPooled(data->icld_Pool, ie_LabelLength + 1)))
1203 return (IPTR)NULL;
1205 memset(entry->ie_TxtBuf_DisplayedLabel, 0, ie_LabelLength + 1);
1206 strncpy(entry->ie_TxtBuf_DisplayedLabel, entry->ie_IconListEntry.label, ie_LabelLength );
1208 entry->ie_TxtBuf_DisplayedLabelWidth = TextLength(data->icld_BufferRastPort, entry->ie_TxtBuf_DisplayedLabel, strlen(entry->ie_TxtBuf_DisplayedLabel));
1209 // if ((data->icld_IconLabelFont->tf_YSize) > data->icld_LabelLargestHeight) data->icld_LabelLargestHeight = data->icld_IconLabelFont->tf_YSize;
1212 // if (entry->ie_TxtBuf_DisplayedLabelWidth > data->icld_LabelLargestWidth) data->icld_LabelLargestWidth = entry->ie_TxtBuf_DisplayedLabelWidth;
1214 return (IPTR)entry->ie_TxtBuf_DisplayedLabel;
1218 ///IconList__HookFunc_UpdateLabelsFunc()
1219 AROS_UFH3(
1220 void, IconList__HookFunc_UpdateLabelsFunc,
1221 AROS_UFHA(struct Hook *, hook, A0),
1222 AROS_UFHA(APTR *, obj, A2),
1223 AROS_UFHA(APTR, param, A1)
1226 AROS_USERFUNC_INIT
1228 /* Get our private data */
1229 Class *CLASS = *( Class **)param;
1230 struct IconList_DATA *data = INST_DATA(CLASS, obj);
1232 #if defined(DEBUG_ILC_LASSO) || defined(DEBUG_ILC_FUNCS)
1233 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
1234 #endif
1236 if (((data->icld__Option_LabelTextMaxLen != data->icld__Option_LastLabelTextMaxLen) &&
1237 (data->icld__Option_LabelTextMultiLine > 1)) ||
1238 (data->icld__Option_LabelTextMultiLine != data->icld__Option_LastLabelTextMultiLine));
1240 struct IconEntry *iconentry_Current = NULL;
1241 #if defined(__AROS__)
1242 ForeachNode(&data->icld_IconList, iconentry_Current)
1243 #else
1244 Foreach_Node(&data->icld_IconList, iconentry_Current);
1245 #endif
1247 IconList__LabelFunc_CreateLabel((Object *)obj, data, iconentry_Current);
1251 data->icld__Option_LastLabelTextMaxLen = data->icld__Option_LabelTextMaxLen;
1252 data->icld__Option_LastLabelTextMultiLine = data->icld__Option_LabelTextMultiLine;
1254 AROS_USERFUNC_EXIT
1258 ///IconList__MUIM_IconList_DrawEntryLabel()
1259 IPTR IconList__MUIM_IconList_DrawEntryLabel(struct IClass *CLASS, Object *obj, struct MUIP_IconList_DrawEntry *message)
1261 struct IconList_DATA *data = INST_DATA(CLASS, obj);
1263 STRPTR buf = NULL;
1264 BOOL outside = FALSE;
1266 struct Rectangle iconlabelrect;
1267 struct Rectangle objrect;
1269 ULONG txtbox_width = 0;
1270 LONG tx,ty,offsetx,offsety;
1271 LONG txwidth; // txheight;
1273 ULONG objX, objY, objW, objH;
1274 LONG labelX, labelY;
1275 ULONG labelW, labelH;
1277 if ((data->icld_DisplayFlags & ICONLIST_DISP_MODELIST) == ICONLIST_DISP_MODELIST)
1278 return FALSE;
1280 if (data->icld_BufferRastPort == data->icld_DisplayRastPort)
1282 objX = _mleft(obj);
1283 objY = _mtop(obj);
1285 else
1287 objX = objY = 0;
1289 objW = _mright(obj) - _mleft(obj) + 1;
1290 objH = _mbottom(obj) - _mtop(obj) + 1;
1292 ULONG txtarea_width;
1293 ULONG curlabel_TotalLines, curlabel_CurrentLine, offset_y;
1295 #if defined(DEBUG_ILC_ICONRENDERING) || defined(DEBUG_ILC_FUNCS)
1296 D(bug("[IconList]: %s(message->entry = 0x%p), '%s'\n", __PRETTY_FUNCTION__, message->entry, message->entry->ie_IconListEntry.label));
1297 #endif
1299 if ((!(message->entry->ie_Flags & ICONENTRY_FLAG_VISIBLE)) ||
1300 (data->icld_BufferRastPort == NULL) ||
1301 (!(message->entry->ie_DiskObj)))
1303 #if defined(DEBUG_ILC_ICONRENDERING)
1304 D(bug("[IconList] %s: Not visible or missing DOB\n", __PRETTY_FUNCTION__));
1305 #endif
1306 return FALSE;
1309 /* Get the dimensions and affected area of message->entry's label */
1310 IconList_GetIconLabelRectangle(obj, data, message->entry, &iconlabelrect);
1311 labelW = iconlabelrect.MaxX - iconlabelrect.MinX + 1;
1312 labelH = iconlabelrect.MaxY - iconlabelrect.MinY + 1;
1314 /* Add the relative position offset of the message->entry's label */
1315 offsetx = (objX - data->icld_ViewX) + message->entry->ie_IconX;
1316 txtbox_width = (iconlabelrect.MaxX - iconlabelrect.MinX) + 1;
1318 if (txtbox_width < message->entry->ie_AreaWidth)
1319 offsetx += ((message->entry->ie_AreaWidth - txtbox_width)/2);
1321 if ((data->icld__Option_IconListMode == ICON_LISTMODE_GRID) &&
1322 (message->entry->ie_AreaWidth < data->icld_IconAreaLargestWidth))
1323 offsetx += ((data->icld_IconAreaLargestWidth - message->entry->ie_AreaWidth)/2);
1325 iconlabelrect.MinX += offsetx;
1326 iconlabelrect.MaxX += offsetx;
1328 offsety = (objY - data->icld_ViewY) + message->entry->ie_IconY + data->icld__Option_IconImageSpacing;
1329 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
1331 offsety = offsety + data->icld_IconLargestHeight;
1333 else
1335 offsety = offsety + message->entry->ie_IconHeight;
1337 iconlabelrect.MinY += offsety;
1338 iconlabelrect.MaxY += offsety;
1340 /* Add the relative position of the window */
1341 objrect.MinX = objX;
1342 objrect.MinY = objX;
1343 objrect.MaxX = objX + objW;
1344 objrect.MaxY = objY + objH;
1346 if (!RectAndRect(&iconlabelrect, &objrect))
1348 #if defined(DEBUG_ILC_ICONRENDERING)
1349 (bug("[IconList] %s: Entry '%s' label outside of visible area .. skipping\n", __PRETTY_FUNCTION__, message->entry->ie_IconListEntry.label));
1350 #endif
1351 return FALSE;
1354 /* data->update_rect1 and data->update_rect2 may
1355 point to rectangles to indicate that only icons
1356 in any of this rectangles need to be drawn */
1357 if (data->update_rect1)
1359 if (!RectAndRect(&iconlabelrect, data->update_rect1))
1360 outside = TRUE;
1363 if (data->update_rect2)
1365 if (data->update_rect1)
1367 if ((outside == TRUE) && RectAndRect(&iconlabelrect, data->update_rect2))
1368 outside = FALSE;
1370 else
1372 if (!RectAndRect(&iconlabelrect, data->update_rect2))
1373 outside = TRUE;
1377 if (outside == TRUE)
1379 #if defined(DEBUG_ILC_ICONRENDERING)
1380 D(bug("[IconList] %s: Entry '%s' label outside of update area .. skipping\n", __PRETTY_FUNCTION__, message->entry->ie_IconListEntry.label));
1381 #endif
1382 return FALSE;
1385 if (message->drawmode == ICONENTRY_DRAWMODE_NONE)
1386 return TRUE;
1388 SetABPenDrMd(data->icld_BufferRastPort, _pens(obj)[MPEN_TEXT], 0, JAM1);
1390 iconlabelrect.MinX = (iconlabelrect.MinX - objX) + data->icld_DrawOffsetX;
1391 iconlabelrect.MinY = (iconlabelrect.MinY - objY) + data->icld_DrawOffsetY;
1392 iconlabelrect.MaxX = (iconlabelrect.MaxX - objX) + data->icld_DrawOffsetX;
1393 iconlabelrect.MaxY = (iconlabelrect.MaxY - objY) + data->icld_DrawOffsetY;
1395 labelX = iconlabelrect.MinX + data->icld__Option_LabelTextBorderWidth + data->icld__Option_LabelTextHorizontalPadding;
1396 labelY = iconlabelrect.MinY + data->icld__Option_LabelTextBorderHeight + data->icld__Option_LabelTextVerticalPadding;
1398 txtarea_width = txtbox_width - ((data->icld__Option_LabelTextBorderWidth + data->icld__Option_LabelTextHorizontalPadding) * 2);
1400 #if defined(DEBUG_ILC_ICONRENDERING)
1401 D(bug("[IconList] %s: Drawing Label '%s' .. %d, %d\n", __PRETTY_FUNCTION__, message->entry->ie_IconListEntry.label, labelX, labelY));
1402 #endif
1403 if (message->entry->ie_IconListEntry.label && message->entry->ie_TxtBuf_DisplayedLabel)
1405 char *curlabel_StrPtr;
1407 if ((message->entry->ie_Flags & ICONENTRY_FLAG_FOCUS) && ((BOOL)XGET(_win(obj), MUIA_Window_Activate)))
1409 //Draw the focus box around the selected label ..
1410 if (data->icld__Option_LabelTextBorderHeight > 0)
1412 InvertPixelArray(data->icld_BufferRastPort,
1413 iconlabelrect.MinX, iconlabelrect.MinY,
1414 (iconlabelrect.MaxX - iconlabelrect.MinX) + 1, data->icld__Option_LabelTextBorderHeight);
1416 InvertPixelArray(data->icld_BufferRastPort,
1417 iconlabelrect.MinX, iconlabelrect.MaxY - (data->icld__Option_LabelTextBorderHeight - 1),
1418 (iconlabelrect.MaxX - iconlabelrect.MinX) + 1, data->icld__Option_LabelTextBorderHeight);
1420 if (data->icld__Option_LabelTextBorderWidth > 0)
1422 InvertPixelArray(data->icld_BufferRastPort,
1423 iconlabelrect.MinX, iconlabelrect.MinY + data->icld__Option_LabelTextBorderHeight,
1424 data->icld__Option_LabelTextBorderWidth, (((iconlabelrect.MaxY - iconlabelrect.MinY) + 1) - (data->icld__Option_LabelTextBorderHeight * 2)));
1426 InvertPixelArray(data->icld_BufferRastPort,
1427 iconlabelrect.MaxX - (data->icld__Option_LabelTextBorderWidth - 1), iconlabelrect.MinY + data->icld__Option_LabelTextBorderHeight,
1428 data->icld__Option_LabelTextBorderWidth, (((iconlabelrect.MaxY - iconlabelrect.MinY) + 1) - (data->icld__Option_LabelTextBorderHeight * 2)));
1432 SetFont(data->icld_BufferRastPort, data->icld_IconLabelFont);
1434 curlabel_TotalLines = message->entry->ie_SplitParts;
1435 curlabel_CurrentLine = 0;
1437 if (curlabel_TotalLines == 0)
1438 curlabel_TotalLines = 1;
1440 if (!(data->icld__Option_LabelTextMultiLineOnFocus) || (data->icld__Option_LabelTextMultiLineOnFocus && (message->entry->ie_Flags & ICONENTRY_FLAG_FOCUS)))
1442 if (curlabel_TotalLines > data->icld__Option_LabelTextMultiLine)
1443 curlabel_TotalLines = data->icld__Option_LabelTextMultiLine;
1445 else
1446 curlabel_TotalLines = 1;
1448 curlabel_StrPtr = message->entry->ie_TxtBuf_DisplayedLabel;
1450 ty = labelY - 1;
1452 #if defined(DEBUG_ILC_ICONRENDERING)
1453 D(bug("[IconList] %s: Font YSize %d Baseline %d\n", __PRETTY_FUNCTION__,data->icld_IconLabelFont->tf_YSize, data->icld_IconLabelFont->tf_Baseline));
1454 #endif
1455 for (curlabel_CurrentLine = 0; curlabel_CurrentLine < curlabel_TotalLines; curlabel_CurrentLine++)
1457 ULONG ie_LabelLength;
1459 if (curlabel_CurrentLine > 0) curlabel_StrPtr = curlabel_StrPtr + strlen(curlabel_StrPtr) + 1;
1460 if ((curlabel_CurrentLine >= (curlabel_TotalLines -1)) && (curlabel_TotalLines < message->entry->ie_SplitParts))
1462 char *tmpLine = curlabel_StrPtr;
1463 ULONG tmpLen = strlen(tmpLine);
1465 if ((curlabel_StrPtr = AllocVecPooled(data->icld_Pool, tmpLen + 1)) != NULL)
1467 memset(curlabel_StrPtr, 0, tmpLen + 1);
1468 strncpy(curlabel_StrPtr, tmpLine, tmpLen - 3);
1469 strcat(curlabel_StrPtr , " ..");
1471 else
1472 return FALSE;
1476 ie_LabelLength = strlen(curlabel_StrPtr);
1477 offset_y = 0;
1479 // Center message->entry's label
1480 tx = (labelX + (message->entry->ie_TxtBuf_DisplayedLabelWidth / 2) - (TextLength(data->icld_BufferRastPort, curlabel_StrPtr, strlen(curlabel_StrPtr)) / 2));
1482 if (message->entry->ie_TxtBuf_DisplayedLabelWidth < txtarea_width)
1483 tx += ((txtarea_width - message->entry->ie_TxtBuf_DisplayedLabelWidth)/2);
1485 ty = ty + data->icld_IconLabelFont->tf_YSize;
1487 switch ( data->icld__Option_LabelTextMode )
1489 case ICON_TEXTMODE_DROPSHADOW:
1490 SetAPen(data->icld_BufferRastPort, data->icld_LabelShadowPen);
1491 Move(data->icld_BufferRastPort, tx + 1, ty + 1);
1492 Text(data->icld_BufferRastPort, curlabel_StrPtr, ie_LabelLength);
1493 offset_y = 1;
1494 case ICON_TEXTMODE_PLAIN:
1495 SetAPen(data->icld_BufferRastPort, data->icld_LabelPen);
1496 Move(data->icld_BufferRastPort, tx, ty);
1497 Text(data->icld_BufferRastPort, curlabel_StrPtr, ie_LabelLength);
1498 break;
1500 default:
1501 // Outline mode:
1502 SetSoftStyle(data->icld_BufferRastPort, FSF_BOLD, AskSoftStyle(data->icld_BufferRastPort));
1504 SetAPen(data->icld_BufferRastPort, data->icld_LabelShadowPen);
1505 Move(data->icld_BufferRastPort, tx + 1, ty );
1506 Text(data->icld_BufferRastPort, curlabel_StrPtr, ie_LabelLength);
1507 Move(data->icld_BufferRastPort, tx - 1, ty );
1508 Text(data->icld_BufferRastPort, curlabel_StrPtr, ie_LabelLength);
1509 Move(data->icld_BufferRastPort, tx, ty + 1);
1510 Text(data->icld_BufferRastPort, curlabel_StrPtr, ie_LabelLength);
1511 Move(data->icld_BufferRastPort, tx, ty - 1);
1512 Text(data->icld_BufferRastPort, curlabel_StrPtr, ie_LabelLength);
1514 SetAPen(data->icld_BufferRastPort, data->icld_LabelPen);
1515 Move(data->icld_BufferRastPort, tx , ty );
1516 Text(data->icld_BufferRastPort, curlabel_StrPtr, ie_LabelLength);
1518 SetSoftStyle(data->icld_BufferRastPort, FS_NORMAL, AskSoftStyle(data->icld_BufferRastPort));
1519 offset_y = 2;
1520 break;
1522 if ((curlabel_CurrentLine >= (curlabel_TotalLines -1)) && (curlabel_TotalLines < message->entry->ie_SplitParts))
1524 FreeVecPooled(data->icld_Pool, curlabel_StrPtr);
1526 ty = ty + offset_y;
1529 /*date/size sorting has the date/size appended under the message->entry label*/
1531 if ((message->entry->ie_IconListEntry.type != ST_USERDIR) && ((data->icld_SortFlags & (MUIV_IconList_Sort_BySize|MUIV_IconList_Sort_ByDate)) != 0))
1533 buf = NULL;
1534 SetFont(data->icld_BufferRastPort, data->icld_IconInfoFont);
1536 if ((data->icld_SortFlags & MUIV_IconList_Sort_MASK) == MUIV_IconList_Sort_BySize)
1538 buf = message->entry->ie_TxtBuf_SIZE;
1539 txwidth = message->entry->ie_TxtBuf_SIZEWidth;
1541 else if ((data->icld_SortFlags & MUIV_IconList_Sort_MASK) == MUIV_IconList_Sort_ByDate)
1543 if (message->entry->ie_Flags & ICONENTRY_FLAG_TODAY)
1545 buf = message->entry->ie_TxtBuf_TIME;
1546 txwidth = message->entry->ie_TxtBuf_TIMEWidth;
1548 else
1550 buf = message->entry->ie_TxtBuf_DATE;
1551 txwidth = message->entry->ie_TxtBuf_DATEWidth;
1555 if (buf)
1557 ULONG ie_LabelLength = strlen(buf);
1558 tx = labelX;
1560 if (txwidth < txtarea_width)
1561 tx += ((txtarea_width - txwidth)/2);
1563 ty = labelY + ((data->icld__Option_LabelTextVerticalPadding + data->icld_IconLabelFont->tf_YSize ) * curlabel_TotalLines) + data->icld_IconInfoFont->tf_YSize;
1565 switch ( data->icld__Option_LabelTextMode )
1567 case ICON_TEXTMODE_DROPSHADOW:
1568 SetAPen(data->icld_BufferRastPort, data->icld_InfoShadowPen);
1569 Move(data->icld_BufferRastPort, tx + 1, ty + 1); Text(data->icld_BufferRastPort, buf, ie_LabelLength);
1570 case ICON_TEXTMODE_PLAIN:
1571 SetAPen(data->icld_BufferRastPort, data->icld_InfoPen);
1572 Move(data->icld_BufferRastPort, tx, ty); Text(data->icld_BufferRastPort, buf, ie_LabelLength);
1573 break;
1575 default:
1576 // Outline mode..
1577 SetSoftStyle(data->icld_BufferRastPort, FSF_BOLD, AskSoftStyle(data->icld_BufferRastPort));
1578 SetAPen(data->icld_BufferRastPort, data->icld_InfoShadowPen);
1580 Move(data->icld_BufferRastPort, tx + 1, ty );
1581 Text(data->icld_BufferRastPort, buf, ie_LabelLength);
1582 Move(data->icld_BufferRastPort, tx - 1, ty );
1583 Text(data->icld_BufferRastPort, buf, ie_LabelLength);
1584 Move(data->icld_BufferRastPort, tx, ty - 1 );
1585 Text(data->icld_BufferRastPort, buf, ie_LabelLength);
1586 Move(data->icld_BufferRastPort, tx, ty + 1 );
1587 Text(data->icld_BufferRastPort, buf, ie_LabelLength);
1589 SetAPen(data->icld_BufferRastPort, data->icld_InfoPen);
1591 Move(data->icld_BufferRastPort, tx, ty );
1592 Text(data->icld_BufferRastPort, buf, ie_LabelLength);
1594 SetSoftStyle(data->icld_BufferRastPort, FS_NORMAL, AskSoftStyle(data->icld_BufferRastPort));
1595 break;
1601 return TRUE;
1604 /**************************************************************************
1606 **************************************************************************/
1607 ///IconList__MUIM_IconList_RethinkDimensions()
1608 IPTR IconList__MUIM_IconList_RethinkDimensions(struct IClass *CLASS, Object *obj, struct MUIP_IconList_RethinkDimensions *message)
1610 struct IconList_DATA *data = INST_DATA(CLASS, obj);
1612 struct IconEntry *entry = NULL;
1613 LONG maxx = 0,
1614 maxy = 0;
1615 struct Rectangle icon_rect;
1617 #if defined(DEBUG_ILC_ICONPOSITIONING) || defined(DEBUG_ILC_FUNCS)
1618 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
1619 #endif
1621 if (message->singleicon != NULL)
1623 entry = message->singleicon;
1624 if ((data->icld_DisplayFlags & ICONLIST_DISP_MODELIST) == ICONLIST_DISP_MODELIST)
1626 maxy = data->icld_LVMAttribs->lmva_RowHeight;
1627 if ((data->icld_LVMAttribs->lvma_Flags & LVMAF_NOHEADER) == 0)
1629 maxy += data->icld_LVMAttribs->lmva_HeaderHeight;
1632 else
1634 maxx = data->icld_AreaWidth - 1,
1635 maxy = data->icld_AreaHeight - 1;
1638 #if defined(DEBUG_ILC_ICONPOSITIONING)
1639 D(bug("[IconList] %s: SingleIcon - maxx = %d, maxy = %d\n", __PRETTY_FUNCTION__, maxx, maxy));
1640 #endif
1642 else
1644 if ((data->icld_DisplayFlags & ICONLIST_DISP_MODELIST) == ICONLIST_DISP_MODELIST)
1646 maxy = data->icld_LVMAttribs->lmva_RowHeight;
1647 if ((data->icld_LVMAttribs->lvma_Flags & LVMAF_NOHEADER) == 0)
1649 maxy += data->icld_LVMAttribs->lmva_HeaderHeight;
1652 entry = (struct IconEntry *)GetHead(&data->icld_IconList);
1655 while (entry != NULL)
1657 if (entry->ie_DiskObj &&
1658 (entry->ie_Flags & ICONENTRY_FLAG_VISIBLE))
1660 if ((data->icld_DisplayFlags & ICONLIST_DISP_MODELIST) == ICONLIST_DISP_MODELIST)
1662 maxy += data->icld_LVMAttribs->lmva_RowHeight;
1664 else
1666 IconList_GetIconAreaRectangle(obj, data, entry, &icon_rect);
1668 icon_rect.MaxX += entry->ie_IconX + data->icld__Option_IconHorizontalSpacing;
1669 if ((data->icld__Option_IconListMode == ICON_LISTMODE_GRID) &&
1670 (entry->ie_AreaWidth < data->icld_IconAreaLargestWidth))
1671 icon_rect.MaxX += (data->icld_IconAreaLargestWidth - entry->ie_AreaWidth);
1673 icon_rect.MaxY += entry->ie_IconY + data->icld__Option_IconVerticalSpacing;
1675 if (icon_rect.MaxX > maxx) maxx = icon_rect.MaxX;
1676 if (icon_rect.MaxY > maxy) maxy = icon_rect.MaxY;
1680 if (message->singleicon)
1681 break;
1683 entry = (struct IconEntry *)GetSucc(&entry->ie_IconNode);
1686 if ((data->icld_DisplayFlags & ICONLIST_DISP_MODELIST) == ICONLIST_DISP_MODELIST)
1688 int col;
1690 for(col = 0; col < NUM_COLUMNS; col++)
1692 LONG index = data->icld_LVMAttribs->lmva_ColumnPos[col];
1694 if (!(data->icld_LVMAttribs->lmva_ColumnFlags[index] & LVMCF_COLVISIBLE)) continue;
1696 maxx += data->icld_LVMAttribs->lmva_ColumnWidth[index];
1700 /* update our view when max x/y have changed */
1701 if (maxx + 1 != data->icld_AreaWidth)
1703 data->icld_AreaWidth = maxx + 1;
1704 SET(obj, MUIA_IconList_Width, data->icld_AreaWidth);
1706 if (maxy + 1 != data->icld_AreaHeight)
1708 data->icld_AreaHeight = maxy + 1;
1709 SET(obj, MUIA_IconList_Height, data->icld_AreaHeight);
1712 return TRUE;
1715 ///IconList__MUIM_IconList_PositionIcons()
1716 /**************************************************************************
1717 MUIM_PositionIcons - Place icons with NO_ICON_POSITION coords somewhere
1718 **************************************************************************/
1719 IPTR IconList__MUIM_IconList_PositionIcons(struct IClass *CLASS, Object *obj, struct MUIP_IconList_PositionIcons *message)
1721 struct IconList_DATA *data = INST_DATA(CLASS, obj);
1722 struct IconEntry *entry = NULL, *pass_first = NULL;
1724 int left = data->icld__Option_IconHorizontalSpacing;
1725 int top = data->icld__Option_IconVerticalSpacing;
1726 int cur_x = left;
1727 int cur_y = top;
1728 int gridx = 0;
1729 int gridy = 0;
1730 int maxw = 0; // Widest & Talest entry in a column or row.
1731 int maxh = 0;
1733 BOOL next;
1734 struct Rectangle iconrect;
1736 #if defined(DEBUG_ILC_ICONPOSITIONING) || defined(DEBUG_ILC_FUNCS)
1737 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
1738 #endif
1740 // Now go to the actual positioning
1741 entry = (struct IconEntry *)GetHead(&data->icld_IconList);
1742 while (entry != NULL)
1744 next = FALSE;
1745 if ((entry->ie_DiskObj != NULL) && (entry->ie_Flags & ICONENTRY_FLAG_VISIBLE))
1747 if (((data->icld_SortFlags & MUIV_IconList_Sort_MASK) == 0)
1748 && (entry->ie_IconX != NO_ICON_POSITION) && (entry->ie_IconY != NO_ICON_POSITION))
1752 else
1754 next = TRUE;
1755 entry->ie_IconX = cur_x;
1756 entry->ie_IconY = cur_y;
1758 if (entry->ie_Flags & ICONENTRY_FLAG_SELECTED)
1760 if (data->icld_SelectionLastClicked == NULL) data->icld_SelectionLastClicked = entry;
1761 if (data->icld_FocusIcon == NULL) data->icld_FocusIcon = entry;
1764 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
1766 maxw = data->icld_IconAreaLargestWidth + data->icld__Option_IconHorizontalSpacing;
1767 maxh = data->icld_IconLargestHeight + data->icld__Option_IconImageSpacing + data->icld_LabelLargestHeight + data->icld__Option_IconVerticalSpacing;
1768 gridx = maxw;
1769 gridy = maxh;
1771 else
1773 if (!(pass_first)) pass_first = entry;
1775 IconList_GetIconAreaRectangle(obj, data, entry, &iconrect);
1777 if (entry->ie_AreaWidth < maxw)
1778 entry->ie_IconX += ( maxw - entry->ie_AreaWidth ) / 2;
1780 if ((maxw < entry->ie_AreaWidth) || (maxh < entry->ie_AreaHeight))
1782 if (maxw < entry->ie_AreaWidth) maxw = entry->ie_AreaWidth;
1783 if (maxh < entry->ie_AreaHeight) maxh = entry->ie_AreaHeight;
1784 if (pass_first != entry)
1786 entry = pass_first;
1787 cur_x = entry->ie_IconX;
1788 cur_y = entry->ie_IconY;
1789 continue;
1793 if (data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL)
1795 gridx = maxw;
1796 gridy = entry->ie_AreaHeight + data->icld__Option_IconHorizontalSpacing;
1798 else
1800 gridx = entry->ie_AreaWidth + data->icld__Option_IconVerticalSpacing;
1801 gridy = maxh;
1806 if ((entry = (struct IconEntry *)GetSucc(&entry->ie_IconNode)) != NULL)
1808 if (next == TRUE)
1810 if (data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL)
1812 cur_y += gridy;
1814 if ((cur_y >= data->icld_ViewHeight) ||
1815 ((data->icld__Option_IconListMode == ICON_LISTMODE_ROUGH) && ((cur_y + entry->ie_AreaHeight - data->icld__Option_IconBorderOverlap) >= data->icld_ViewHeight)) ||
1816 ((data->icld__Option_IconListMode == ICON_LISTMODE_GRID) && ((cur_y + data->icld_IconAreaLargestHeight - data->icld__Option_IconBorderOverlap) >= data->icld_ViewHeight)))
1818 cur_x += maxw;
1819 cur_y = top;
1820 pass_first = NULL;
1821 maxw = 0;
1824 else
1826 cur_x += gridx;
1828 if ((cur_x >= data->icld_ViewWidth) ||
1829 ((data->icld__Option_IconListMode == ICON_LISTMODE_ROUGH) && ((cur_x + entry->ie_AreaWidth - data->icld__Option_IconBorderOverlap) >= data->icld_ViewWidth)) ||
1830 ((data->icld__Option_IconListMode == ICON_LISTMODE_GRID) && ((cur_x + data->icld_IconAreaLargestWidth - data->icld__Option_IconBorderOverlap) >= data->icld_ViewWidth)))
1832 cur_x = left;
1833 cur_y += maxh;
1834 pass_first = NULL;
1835 maxh = 0;
1837 else if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
1845 DoMethod(obj, MUIM_IconList_RethinkDimensions, NULL);
1846 return (IPTR)NULL;
1850 ///OM_NEW()
1851 /**************************************************************************
1852 OM_NEW
1853 **************************************************************************/
1854 IPTR IconList__OM_NEW(struct IClass *CLASS, Object *obj, struct opSet *message)
1856 struct IconList_DATA *data = NULL;
1857 struct TextFont *icl_WindowFont = NULL;
1858 // struct RastPort *icl_RastPort = NULL;
1859 int i;
1861 #if defined(DEBUG_ILC_FUNCS)
1862 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
1863 #endif
1865 icl_WindowFont = (struct TextFont *) GetTagData(MUIA_Font, (IPTR) NULL, message->ops_AttrList);
1867 obj = (Object *)DoSuperNewTags(CLASS, obj, NULL,
1868 MUIA_FillArea, FALSE,
1869 MUIA_Dropable, TRUE,
1870 MUIA_Font, MUIV_Font_Tiny,
1871 TAG_MORE, (IPTR) message->ops_AttrList);
1873 if (!obj) return FALSE;
1875 data = INST_DATA(CLASS, obj);
1877 data->icld_Pool = CreatePool(0,4096,4096);
1878 if (!data->icld_Pool)
1880 CoerceMethod(CLASS,obj,OM_DISPOSE);
1881 return (IPTR)NULL;
1884 #if defined(DEBUG_ILC_FUNCS)
1885 D(bug("[IconList] %s: SELF = 0x%p, muiRenderInfo = 0x%p\n", __PRETTY_FUNCTION__, obj, muiRenderInfo(obj)));
1886 #endif
1887 NewList((struct List*)&data->icld_IconList);
1888 NewList((struct List*)&data->icld_SelectionList);
1890 data->icld_IconLabelFont = icl_WindowFont;
1892 /* Setup Icon View-Mode options */
1893 data->icld_IVMAttribs = AllocMem(sizeof(struct IconViewModeAttribs), MEMF_CLEAR);
1894 /* Setup List View-Mode options */
1895 if ((data->icld_LVMAttribs = AllocMem(sizeof(struct ListViewModeAttribs), MEMF_CLEAR)) != NULL)
1897 for(i = 0; i < NUM_COLUMNS; i++)
1899 data->icld_LVMAttribs->lmva_ColumnPos[i] = i;
1900 data->icld_LVMAttribs->lmva_ColumnFlags[i] = LVMCF_COLVISIBLE;
1901 data->icld_LVMAttribs->lmva_ColumnWidth[i] = 100;
1902 data->icld_LVMAttribs->lmva_ColumnHAlign[i] = COLUMN_ALIGN_LEFT;
1903 switch (i)
1905 case INDEX_TYPE:
1906 data->icld_LVMAttribs->lmva_ColumnHAlign[i] = COLUMN_ALIGN_RIGHT;
1907 data->icld_LVMAttribs->lmva_ColumnFlags[i] |= (LVMCF_COLCLICKABLE|LVMCF_COLSORTABLE);
1908 data->icld_LVMAttribs->lmva_ColumnTitle[i] = "Type";
1909 #define ICONENTRY_SIZE 16
1910 data->icld_LVMAttribs->lmva_ColumnWidth[i] = ICONENTRY_SIZE + 2;
1911 break;
1913 case INDEX_NAME:
1914 data->icld_LVMAttribs->lmva_ColumnFlags[i] |= (LVMCF_COLCLICKABLE|LVMCF_COLSORTABLE);
1915 data->icld_LVMAttribs->lmva_ColumnTitle[i] = "Name";
1916 break;
1918 case INDEX_SIZE:
1919 data->icld_LVMAttribs->lmva_ColumnHAlign[i] = COLUMN_ALIGN_RIGHT;
1920 data->icld_LVMAttribs->lmva_ColumnFlags[i] | LVMCF_COLSORTABLE;
1921 data->icld_LVMAttribs->lmva_ColumnTitle[i] = "Size";
1922 break;
1924 case INDEX_LASTACCESS:
1925 data->icld_LVMAttribs->lmva_ColumnFlags[i] |= LVMCF_COLSORTABLE;
1926 data->icld_LVMAttribs->lmva_ColumnTitle[i] = "Last Accessed";
1927 break;
1929 case INDEX_COMMENT:
1930 data->icld_LVMAttribs->lmva_ColumnTitle[i] = "Comment";
1931 break;
1933 case INDEX_PROTECTION:
1934 data->icld_LVMAttribs->lmva_ColumnTitle[i] = "Protection";
1935 break;
1937 default:
1938 data->icld_LVMAttribs->lmva_ColumnTitle[i] = "<Unknown>";
1939 break;
1942 data->icld_LVMAttribs->lmva_LastSelectedColumn = -1;
1943 data->icld_LVMAttribs->lmva_SortColumn = INDEX_NAME;
1944 data->icld_LVMAttribs->lmva_HeaderHeight = HEADERLINE_EXTRAHEIGHT + data->icld_IconLabelFont->tf_YSize;
1945 data->icld_LVMAttribs->lmva_RowHeight = LINE_EXTRAHEIGHT + ((ICONENTRY_SIZE > data->icld_IconLabelFont->tf_YSize) ? ICONENTRY_SIZE : data->icld_IconLabelFont->tf_YSize);
1946 data->icld_LVMAttribs->lvma_Flags = LVMAF_HEADERDRAWTOEND;
1949 /* Get/Set initial values */
1950 #warning "TODO: TrimVolumeNames should be prefs settable"
1951 data->icld__Option_TrimVolumeNames = TRUE;
1952 #warning "TODO: Adjust overlap by window border width"
1953 data->icld__Option_IconBorderOverlap = 10;
1955 data->icld__Option_IconListMode = (UBYTE)GetTagData(MUIA_IconList_IconListMode, 0, message->ops_AttrList);
1956 data->icld__Option_LabelTextMode = (UBYTE)GetTagData(MUIA_IconList_LabelText_Mode, 0, message->ops_AttrList);
1957 data->icld__Option_LabelTextMaxLen = (ULONG)GetTagData(MUIA_IconList_LabelText_MaxLineLen, ILC_ICONLABEL_MAXLINELEN_DEFAULT, message->ops_AttrList);
1959 if ( data->icld__Option_LabelTextMaxLen < ILC_ICONLABEL_SHORTEST )
1960 data->icld__Option_LabelTextMaxLen = ILC_ICONLABEL_MAXLINELEN_DEFAULT;
1962 data->icld__Option_LastLabelTextMaxLen = data->icld__Option_LabelTextMaxLen;
1964 #if defined(DEBUG_ILC_FUNCS)
1965 D(bug("[IconList] %s: MaxLineLen : %ld\n", __PRETTY_FUNCTION__, data->icld__Option_LabelTextMaxLen));
1966 #endif
1967 data->ehn.ehn_Events = IDCMP_MOUSEBUTTONS | IDCMP_RAWKEY | IDCMP_NEWSIZE;
1968 data->ehn.ehn_Priority = 0;
1969 data->ehn.ehn_Flags = 0;
1970 data->ehn.ehn_Object = obj;
1971 data->ehn.ehn_Class = CLASS;
1973 data->icld_SortFlags = MUIV_IconList_Sort_ByName;
1974 data->icld_DisplayFlags = ICONLIST_DISP_SHOWINFO;
1976 __iconlist_UpdateLabels_hook.h_Entry = (HOOKFUNC)IconList__HookFunc_UpdateLabelsFunc;
1978 DoMethod
1980 obj, MUIM_Notify, MUIA_IconList_LabelText_MaxLineLen, MUIV_EveryTime,
1981 (IPTR)obj, 3,
1982 MUIM_CallHook, &__iconlist_UpdateLabels_hook, (IPTR)CLASS
1985 DoMethod
1987 obj, MUIM_Notify, MUIA_IconList_LabelText_MultiLine, MUIV_EveryTime,
1988 (IPTR)obj, 3,
1989 MUIM_CallHook, &__iconlist_UpdateLabels_hook, (IPTR)CLASS
1992 #if defined(DEBUG_ILC_FUNCS)
1993 D(bug("[IconList] obj = %ld\n", obj));
1994 #endif
1995 return (IPTR)obj;
1999 ///OM_DISPOSE()
2000 /**************************************************************************
2001 OM_DISPOSE
2002 **************************************************************************/
2003 IPTR IconList__OM_DISPOSE(struct IClass *CLASS, Object *obj, Msg message)
2005 struct IconList_DATA *data = INST_DATA(CLASS, obj);
2006 struct IconEntry *node = NULL;
2008 #if defined(DEBUG_ILC_FUNCS)
2009 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
2010 #endif
2012 #if defined(__AROS__)
2013 ForeachNode(&data->icld_IconList, node)
2014 #else
2015 Foreach_Node(&data->icld_IconList, node);
2016 #endif
2018 if (node->ie_DiskObj)
2019 FreeDiskObject(node->ie_DiskObj);
2022 if (data->icld_Pool) DeletePool(data->icld_Pool);
2024 DoSuperMethodA(CLASS,obj,message);
2025 return (IPTR)NULL;
2029 ///OM_SET()
2030 /**************************************************************************
2031 OM_SET
2032 **************************************************************************/
2033 IPTR IconList__OM_SET(struct IClass *CLASS, Object *obj, struct opSet *message)
2035 struct IconList_DATA *data = INST_DATA(CLASS, obj);
2036 struct TagItem *tag = NULL,
2037 *tags = NULL;
2039 WORD oldleft = data->icld_ViewX,
2040 oldtop = data->icld_ViewY;
2041 //oldwidth = data->icld_ViewWidth,
2042 //oldheight = data->icld_ViewHeight;
2044 #if defined(DEBUG_ILC_FUNCS) || defined(DEBUG_ILC_ATTRIBS)
2045 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
2046 #endif
2048 /* parse initial taglist */
2049 for (tags = message->ops_AttrList; (tag = NextTagItem((TAGITEM)&tags)); )
2051 switch (tag->ti_Tag)
2053 case MUIA_Virtgroup_Left:
2054 #if defined(DEBUG_ILC_ATTRIBS)
2055 D(bug("[IconList] %s: MUIA_Virtgroup_Left %ld\n", __PRETTY_FUNCTION__, tag->ti_Data));
2056 #endif
2057 if (data->icld_ViewX != tag->ti_Data)
2058 data->icld_ViewX = tag->ti_Data;
2059 break;
2061 case MUIA_Virtgroup_Top:
2062 #if defined(DEBUG_ILC_ATTRIBS)
2063 D(bug("[IconList] %s: MUIA_Virtgroup_Top %ld\n", __PRETTY_FUNCTION__, tag->ti_Data));
2064 #endif
2065 if (data->icld_ViewY != tag->ti_Data)
2066 data->icld_ViewY = tag->ti_Data;
2067 break;
2069 case MUIA_IconList_Rastport:
2070 #if defined(DEBUG_ILC_ATTRIBS)
2071 D(bug("[IconList] %s: MUIA_IconList_Rastport 0x%p\n", __PRETTY_FUNCTION__, tag->ti_Data));
2072 #endif
2073 data->icld_DisplayRastPort = (struct RastPort*)tag->ti_Data;
2074 data->icld_DrawOffsetX = _mleft(obj);
2075 data->icld_DrawOffsetY = _mtop(obj);
2076 if (data->icld_BufferRastPort != NULL)
2078 //Buffer still set!?!?!
2080 SET(obj, MUIA_IconList_BufferRastport, tag->ti_Data);
2081 break;
2083 case MUIA_IconList_BufferRastport:
2084 #if defined(DEBUG_ILC_ATTRIBS)
2085 D(bug("[IconList] %s: MUIA_IconList_BufferRastport 0x%p\n", __PRETTY_FUNCTION__, tag->ti_Data));
2086 #endif
2087 data->icld_BufferRastPort = (struct RastPort*)tag->ti_Data;
2088 break;
2090 case MUIA_Font:
2091 #if defined(DEBUG_ILC_ATTRIBS)
2092 D(bug("[IconList] %s: MUIA_Font 0x%p\n", __PRETTY_FUNCTION__, tag->ti_Data));
2093 #endif
2094 data->icld_IconLabelFont = (struct TextFont*)tag->ti_Data;
2095 break;
2097 case MUIA_IconList_LabelInfoText_Font:
2098 #if defined(DEBUG_ILC_ATTRIBS)
2099 D(bug("[IconList] %s: MUIA_IconList_LabelInfoText_Font 0x%p\n", __PRETTY_FUNCTION__, tag->ti_Data));
2100 #endif
2101 data->icld_IconInfoFont = (struct TextFont*)tag->ti_Data;
2102 break;
2104 case MUIA_IconList_DisplayFlags:
2106 #if defined(DEBUG_ILC_ATTRIBS)
2107 D(bug("[IconList] %s: MUIA_IconList_DisplayFlags %08x\n", __PRETTY_FUNCTION__, tag->ti_Data));
2108 #endif
2109 ULONG origModeFlags = data->icld_DisplayFlags & (ICONLIST_DISP_MODEDEFAULT|ICONLIST_DISP_MODELABELRIGHT|ICONLIST_DISP_MODELIST);
2110 data->icld_DisplayFlags = (ULONG)tag->ti_Data;
2112 if (data->icld_DisplayFlags & ICONLIST_DISP_BUFFERED)
2114 #if defined(DEBUG_ILC_ATTRIBS) || defined(DEBUG_ILC_ICONRENDERING)
2115 D(bug("[IconList] %s: MUIA_IconList_DisplayFlags & ICONLIST_DISP_BUFFERED\n", __PRETTY_FUNCTION__));
2116 #endif
2117 if ((data->icld_BufferRastPort != NULL)
2118 && (data->icld_BufferRastPort != data->icld_DisplayRastPort))
2120 #if defined(DEBUG_ILC_ATTRIBS) || defined(DEBUG_ILC_ICONRENDERING)
2121 D(bug("[IconList] %s: BackLayer @ %p for BackRastport @ %p\n", __PRETTY_FUNCTION__, data->icld_BufferRastPort->Layer, data->icld_BufferRastPort));
2122 #endif
2123 if ((GetBitMapAttr(data->icld_BufferRastPort->BitMap, BMA_WIDTH) != data->icld_ViewWidth)
2124 || (GetBitMapAttr(data->icld_BufferRastPort->BitMap, BMA_HEIGHT) != data->icld_ViewHeight))
2126 struct Layer *oldLayer = data->icld_BufferRastPort->Layer;
2127 #if defined(DEBUG_ILC_ATTRIBS) || defined(DEBUG_ILC_ICONRENDERING)
2128 D(bug("[IconList] %s: Destroying old BackLayer\n", __PRETTY_FUNCTION__));
2129 #endif
2130 data->icld_BufferRastPort = data->icld_DisplayRastPort;
2131 DeleteLayer(0, oldLayer);
2135 if ((data->icld_BufferRastPort == NULL) || (data->icld_BufferRastPort == data->icld_DisplayRastPort))
2137 struct BitMap *bitmap_New = NULL;
2138 ULONG tmp_RastDepth;
2139 struct Layer_Info *li;
2141 tmp_RastDepth = GetCyberMapAttr(data->icld_DisplayRastPort->BitMap, CYBRMATTR_DEPTH);
2142 if ((bitmap_New = AllocBitMap(data->icld_ViewWidth,
2143 data->icld_ViewHeight,
2144 tmp_RastDepth,
2145 BMF_CLEAR,
2146 data->icld_DisplayRastPort->BitMap))!=NULL)
2148 if ((data->icld_BufferRastPort = CreateRastPort())!=NULL)
2150 data->icld_BufferRastPort->BitMap = bitmap_New;
2151 if (li = NewLayerInfo())
2153 if (data->icld_BufferRastPort->Layer = CreateUpfrontLayer(li, data->icld_BufferRastPort->BitMap, 0, 0, data->icld_ViewWidth - 1, data->icld_ViewHeight - 1, 0, NULL))
2156 * Mark it as a buffered rastport.
2159 #if defined(DEBUG_ILC_ATTRIBS) || defined(DEBUG_ILC_ICONRENDERING)
2160 D(bug("[IconList] %s: FrontRastPort @ %p, New BackLayer @ %p, BackRastport @ %p\n", __PRETTY_FUNCTION__, data->icld_DisplayRastPort, data->icld_BufferRastPort->Layer, data->icld_BufferRastPort));
2161 #endif
2162 SET(obj, MUIA_IconList_BufferRastport, data->icld_BufferRastPort);
2163 data->icld_DrawOffsetX = 0;
2164 data->icld_DrawOffsetY = 0;
2166 else
2167 data->icld_BufferRastPort = data->icld_DisplayRastPort;
2169 else
2170 data->icld_BufferRastPort = data->icld_DisplayRastPort;
2172 else
2173 data->icld_BufferRastPort = data->icld_DisplayRastPort;
2175 if (data->icld_BufferRastPort == data->icld_DisplayRastPort)
2177 if (bitmap_New) FreeBitMap(bitmap_New);
2178 if (li) DisposeLayerInfo(li);
2179 data->icld_DrawOffsetX = _mleft(obj);
2180 data->icld_DrawOffsetY = _mtop(obj);
2184 else
2186 if ((data->icld_BufferRastPort) && (data->icld_BufferRastPort != data->icld_DisplayRastPort))
2188 //Free up the buffers layer, rastport and bitmap since they are no longer needed ..
2189 struct Layer *oldLayer = data->icld_BufferRastPort->Layer;
2190 data->icld_BufferRastPort = data->icld_DisplayRastPort;
2191 InstallClipRegion(oldLayer, NULL);
2192 DeleteLayer(0, oldLayer);
2193 FreeBitMap(data->icld_BufferRastPort->BitMap);
2194 data->icld_DrawOffsetX = _mleft(obj);
2195 data->icld_DrawOffsetY = _mtop(obj);
2198 SET(obj, MUIA_IconList_Changed, TRUE);
2200 break;
2202 case MUIA_IconList_SortFlags:
2203 #if defined(DEBUG_ILC_ATTRIBS)
2204 D(bug("[IconList] %s: MUIA_IconList_SortFlags %08x\n", __PRETTY_FUNCTION__, tag->ti_Data));
2205 #endif
2206 data->icld_SortFlags = (ULONG)tag->ti_Data;
2207 break;
2209 case MUIA_IconList_IconListMode:
2210 #if defined(DEBUG_ILC_ATTRIBS)
2211 D(bug("[IconList] %s: MUIA_IconList_IconListMode %d\n", __PRETTY_FUNCTION__, tag->ti_Data));
2212 #endif
2213 data->icld__Option_IconListMode = (UBYTE)tag->ti_Data;
2214 break;
2216 case MUIA_IconList_LabelText_Mode:
2217 #if defined(DEBUG_ILC_ATTRIBS)
2218 D(bug("[IconList] %s: MUIA_IconList_LabelText_Mode %d\n", __PRETTY_FUNCTION__, tag->ti_Data));
2219 #endif
2220 data->icld__Option_LabelTextMode = (UBYTE)tag->ti_Data;
2221 break;
2223 case MUIA_IconList_LabelText_MaxLineLen:
2224 #if defined(DEBUG_ILC_ATTRIBS)
2225 D(bug("[IconList] %s: MUIA_IconList_LabelText_MaxLineLen %d\n", __PRETTY_FUNCTION__, tag->ti_Data));
2226 #endif
2227 if (tag->ti_Data >= ILC_ICONLABEL_SHORTEST)
2229 data->icld__Option_LabelTextMaxLen = (ULONG)tag->ti_Data;
2231 else
2233 data->icld__Option_LabelTextMaxLen = ILC_ICONLABEL_MAXLINELEN_DEFAULT;
2235 break;
2237 case MUIA_IconList_LabelText_MultiLine:
2238 #if defined(DEBUG_ILC_ATTRIBS)
2239 D(bug("[IconList] %s: MUIA_IconList_LabelText_MultiLine %d\n", __PRETTY_FUNCTION__, tag->ti_Data));
2240 #endif
2241 data->icld__Option_LabelTextMultiLine = (ULONG)tag->ti_Data;
2242 if (data->icld__Option_LabelTextMultiLine == 0)data->icld__Option_LabelTextMultiLine = 1;
2243 break;
2245 case MUIA_IconList_LabelText_MultiLineOnFocus:
2246 #if defined(DEBUG_ILC_ATTRIBS)
2247 D(bug("[IconList] %s: MUIA_IconList_LabelText_MultiLineOnFocus %d\n", __PRETTY_FUNCTION__, tag->ti_Data));
2248 #endif
2249 data->icld__Option_LabelTextMultiLineOnFocus = (BOOL)tag->ti_Data;
2250 break;
2252 case MUIA_IconList_Icon_HorizontalSpacing:
2253 #if defined(DEBUG_ILC_ATTRIBS)
2254 D(bug("[IconList] %s: MUIA_IconList_Icon_HorizontalSpacing %d\n", __PRETTY_FUNCTION__, tag->ti_Data));
2255 #endif
2256 data->icld__Option_IconHorizontalSpacing = (UBYTE)tag->ti_Data;
2257 break;
2259 case MUIA_IconList_Icon_VerticalSpacing:
2260 #if defined(DEBUG_ILC_ATTRIBS)
2261 D(bug("[IconList] %s: MUIA_IconList_Icon_VerticalSpacing %d\n", __PRETTY_FUNCTION__, tag->ti_Data));
2262 #endif
2263 data->icld__Option_IconVerticalSpacing = (UBYTE)tag->ti_Data;
2264 break;
2266 case MUIA_IconList_Icon_ImageSpacing:
2267 #if defined(DEBUG_ILC_ATTRIBS)
2268 D(bug("[IconList] %s: MUIA_IconList_Icon_ImageSpacing %d\n", __PRETTY_FUNCTION__, tag->ti_Data));
2269 #endif
2270 data->icld__Option_IconImageSpacing = (UBYTE)tag->ti_Data;
2271 break;
2273 case MUIA_IconList_LabelText_HorizontalPadding:
2274 #if defined(DEBUG_ILC_ATTRIBS)
2275 D(bug("[IconList] %s: MUIA_IconList_LabelText_HorizontalPadding %d\n", __PRETTY_FUNCTION__, tag->ti_Data));
2276 #endif
2277 data->icld__Option_LabelTextHorizontalPadding = (UBYTE)tag->ti_Data;
2278 break;
2280 case MUIA_IconList_LabelText_VerticalPadding:
2281 #if defined(DEBUG_ILC_ATTRIBS)
2282 D(bug("[IconList] %s: MUIA_IconList_LabelText_VerticalPadding %d\n", __PRETTY_FUNCTION__, tag->ti_Data));
2283 #endif
2284 data->icld__Option_LabelTextVerticalPadding = (UBYTE)tag->ti_Data;
2285 break;
2287 case MUIA_IconList_LabelText_BorderWidth:
2288 #if defined(DEBUG_ILC_ATTRIBS)
2289 D(bug("[IconList] %s: MUIA_IconList_LabelText_BorderWidth %d\n", __PRETTY_FUNCTION__, tag->ti_Data));
2290 #endif
2291 data->icld__Option_LabelTextBorderWidth = (UBYTE)tag->ti_Data;
2292 break;
2294 case MUIA_IconList_LabelText_BorderHeight:
2295 #if defined(DEBUG_ILC_ATTRIBS)
2296 D(bug("[IconList] %s: MUIA_IconList_LabelText_BorderHeight %d\n", __PRETTY_FUNCTION__, tag->ti_Data));
2297 #endif
2298 data->icld__Option_LabelTextBorderHeight = (UBYTE)tag->ti_Data;
2299 break;
2301 case MUIA_IconList_LabelText_Pen:
2302 data->icld_LabelPen = (ULONG)tag->ti_Data;
2303 break;
2305 case MUIA_IconList_LabelText_ShadowPen:
2306 data->icld_LabelShadowPen = (ULONG)tag->ti_Data;
2307 break;
2309 case MUIA_IconList_LabelInfoText_Pen:
2310 data->icld_InfoPen = (ULONG)tag->ti_Data;
2311 break;
2313 case MUIA_IconList_LabelInfoText_ShadowPen:
2314 data->icld_InfoShadowPen = (ULONG)tag->ti_Data;
2315 break;
2317 /* Settings defined by the view class */
2318 case MUIA_IconListview_FixedBackground:
2319 #if defined(DEBUG_ILC_ATTRIBS)
2320 D(bug("[IconList] %s: MUIA_IconListview_FixedBackground\n", __PRETTY_FUNCTION__));
2321 #endif
2322 data->icld__Option_IconListFixedBackground = (BOOL)tag->ti_Data;
2323 break;
2325 case MUIA_IconListview_ScaledBackground:
2326 #if defined(DEBUG_ILC_ATTRIBS)
2327 D(bug("[IconList] %s: MUIA_IconListview_ScaledBackground\n", __PRETTY_FUNCTION__));
2328 #endif
2329 data->icld__Option_IconListScaledBackground = (BOOL)tag->ti_Data;
2330 break;
2332 /* We listen for MUIA_Background and set default values for known types */
2333 case MUIA_Background:
2334 #if defined(DEBUG_ILC_ATTRIBS) || defined(DEBUG_ILC_ICONRENDERING)
2335 D(bug("[IconList] %s: MUIA_Background\n", __PRETTY_FUNCTION__));
2336 #endif
2338 char *bgmode_string = (char *)tag->ti_Data;
2339 BYTE this_mode = bgmode_string[0] - 48;
2341 #if defined(DEBUG_ILC_ATTRIBS) || defined(DEBUG_ILC_ICONRENDERING)
2342 D(bug("[IconList] %s: MUIA_Background | MUI BG Mode = %d\n", __PRETTY_FUNCTION__, this_mode));
2343 #endif
2344 switch (this_mode)
2346 case 0:
2347 //MUI Pattern
2348 NNSET(obj, MUIA_IconListview_FixedBackground, FALSE);
2349 NNSET(obj, MUIA_IconListview_ScaledBackground, FALSE);
2350 break;
2351 case 2:
2352 //MUI RGB color
2353 NNSET(obj, MUIA_IconListview_FixedBackground, FALSE);
2354 NNSET(obj, MUIA_IconListview_ScaledBackground, FALSE);
2355 break;
2356 case 7:
2357 //Zune Gradient
2358 NNSET(obj, MUIA_IconListview_FixedBackground, TRUE);
2359 NNSET(obj, MUIA_IconListview_ScaledBackground, TRUE);
2360 break;
2361 case 5:
2362 //Image
2363 NNSET(obj, MUIA_IconListview_FixedBackground, FALSE);
2364 NNSET(obj, MUIA_IconListview_ScaledBackground, FALSE);
2365 break;
2368 break;
2369 case MUIA_IconList_IconsDropped:
2370 data->icld_DragDropEvent = (struct IconList_Drop_Event *)tag->ti_Data;
2371 break;
2375 #if defined(DEBUG_ILC_ATTRIBS)
2376 D(bug("[IconList] %s(), out of switch\n", __PRETTY_FUNCTION__));
2377 #endif
2378 if ((oldleft != data->icld_ViewX) || (oldtop != data->icld_ViewY))
2380 data->icld_UpdateMode = UPDATE_SCROLL;
2381 data->update_scrolldx = data->icld_ViewX - oldleft;
2382 data->update_scrolldy = data->icld_ViewY - oldtop;
2383 #if defined(DEBUG_ILC_ATTRIBS)
2384 D(bug("[IconList] %s(), call MUI_Redraw()\n", __PRETTY_FUNCTION__));
2385 #endif
2386 MUI_Redraw(obj, MADF_DRAWUPDATE);
2389 #if defined(DEBUG_ILC_ATTRIBS)
2390 D(bug("[IconList] %s(), call DoSuperMethodA()\n", __PRETTY_FUNCTION__));
2391 #endif
2392 return DoSuperMethodA(CLASS, obj, (Msg)message);
2396 ///OM_GET()
2397 /**************************************************************************
2398 OM_GET
2399 **************************************************************************/
2400 IPTR IconList__OM_GET(struct IClass *CLASS, Object *obj, struct opGet *message)
2402 /* small macro to simplify return value storage */
2403 #define STORE *(message->opg_Storage)
2404 struct IconList_DATA *data = INST_DATA(CLASS, obj);
2406 #if defined(DEBUG_ILC_FUNCS) || defined(DEBUG_ILC_ATTRIBS)
2407 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
2408 #endif
2410 switch (message->opg_AttrID)
2412 case MUIA_IconList_Rastport: STORE = (IPTR)data->icld_DisplayRastPort; return 1;
2413 case MUIA_IconList_BufferRastport: STORE = (IPTR)data->icld_BufferRastPort; return 1;
2414 case MUIA_IconList_BufferLeft: STORE = (IPTR)data->icld_DrawOffsetX; return 1;
2415 case MUIA_IconList_BufferTop: STORE = (IPTR)data->icld_DrawOffsetY; return 1;
2416 case MUIA_IconList_BufferWidth:
2417 case MUIA_IconList_Width: STORE = (IPTR)data->icld_AreaWidth; return 1;
2418 case MUIA_IconList_BufferHeight:
2419 case MUIA_IconList_Height: STORE = (IPTR)data->icld_AreaHeight; return 1;
2420 case MUIA_IconList_IconsDropped: STORE = (IPTR)data->icld_DragDropEvent; return 1;
2421 case MUIA_IconList_Clicked: STORE = (IPTR)&data->icld_ClickEvent; return 1;
2422 case MUIA_IconList_IconListMode: STORE = (IPTR)data->icld__Option_IconListMode; return 1;
2423 case MUIA_IconList_LabelText_Mode: STORE = (IPTR)data->icld__Option_LabelTextMode; return 1;
2424 case MUIA_IconList_LabelText_MaxLineLen: STORE = (IPTR)data->icld__Option_LabelTextMaxLen; return 1;
2425 case MUIA_IconList_LabelText_MultiLine: STORE = (IPTR)data->icld__Option_LabelTextMultiLine; return 1;
2426 case MUIA_IconList_LabelText_MultiLineOnFocus: STORE = (IPTR)data->icld__Option_LabelTextMultiLineOnFocus; return 1;
2427 case MUIA_IconList_DisplayFlags: STORE = (IPTR)data->icld_DisplayFlags; return 1;
2428 case MUIA_IconList_SortFlags: STORE = (IPTR)data->icld_SortFlags; return 1;
2430 case MUIA_IconList_FocusIcon: STORE = (IPTR)data->icld_FocusIcon; return 1;
2432 case MUIA_Font: STORE = (IPTR)data->icld_IconLabelFont; return 1;
2433 case MUIA_IconList_LabelText_Pen: STORE = (IPTR)data->icld_LabelPen; return 1;
2434 case MUIA_IconList_LabelText_ShadowPen: STORE = (IPTR)data->icld_LabelShadowPen; return 1;
2435 case MUIA_IconList_LabelInfoText_Font: STORE = (IPTR)data->icld_IconInfoFont; return 1;
2436 case MUIA_IconList_LabelInfoText_Pen: STORE = (IPTR)data->icld_InfoPen; return 1;
2437 case MUIA_IconList_LabelInfoText_ShadowPen: STORE = (IPTR)data->icld_InfoShadowPen; return 1;
2439 case MUIA_IconList_Icon_HorizontalSpacing: STORE = (IPTR)data->icld__Option_IconHorizontalSpacing; return 1;
2440 case MUIA_IconList_Icon_VerticalSpacing: STORE = (IPTR)data->icld__Option_IconVerticalSpacing; return 1;
2441 case MUIA_IconList_Icon_ImageSpacing: STORE = (IPTR)data->icld__Option_IconImageSpacing; return 1;
2442 case MUIA_IconList_LabelText_HorizontalPadding: STORE = (IPTR)data->icld__Option_LabelTextHorizontalPadding; return 1;
2443 case MUIA_IconList_LabelText_VerticalPadding: STORE = (IPTR)data->icld__Option_LabelTextVerticalPadding; return 1;
2444 case MUIA_IconList_LabelText_BorderWidth: STORE = (IPTR)data->icld__Option_LabelTextBorderWidth; return 1;
2445 case MUIA_IconList_LabelText_BorderHeight: STORE = (IPTR)data->icld__Option_LabelTextBorderHeight; return 1;
2447 /* Settings defined by the view class */
2448 case MUIA_IconListview_FixedBackground: STORE = (IPTR)data->icld__Option_IconListFixedBackground; return 1;
2449 case MUIA_IconListview_ScaledBackground: STORE = (IPTR)data->icld__Option_IconListScaledBackground; return 1;
2451 /* ICON obj Changes */
2452 case MUIA_Virtgroup_Left: STORE = (IPTR)data->icld_ViewX; return 1;
2453 case MUIA_Virtgroup_Top: STORE = (IPTR)data->icld_ViewY; return 1;
2454 case MUIA_Family_List: STORE = (IPTR)&(data->icld_IconList); return 1; /* Get our list object */
2456 #warning "TODO: Get the version/revision from our config.."
2457 case MUIA_Version: STORE = (IPTR)1; return 1;
2458 case MUIA_Revision: STORE = (IPTR)7; return 1;
2461 return DoSuperMethodA(CLASS, obj, (Msg) message);
2462 #undef STORE
2466 IPTR IconList__MUIM_Family_AddHead(struct IClass *CLASS, Object *obj, struct MUIP_Family_AddHead *message)
2468 struct IconList_DATA *data = INST_DATA(CLASS, obj);
2469 #if defined(DEBUG_ILC_FUNCS)
2470 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
2471 #endif
2473 if (message->obj)
2475 #warning "TODO: Use the correct _OBJECT() code when we switch to icon.mui"
2476 // AddHead(&(data->icld_IconList), (struct Node *)_OBJECT(message->obj));
2477 AddHead(&(data->icld_IconList), (struct Node *)message->obj);
2478 return TRUE;
2480 else
2481 return FALSE;
2484 IPTR IconList__MUIM_Family_AddTail(struct IClass *CLASS, Object *obj, struct MUIP_Family_AddTail *message)
2486 struct IconList_DATA *data = INST_DATA(CLASS, obj);
2487 #if defined(DEBUG_ILC_FUNCS)
2488 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
2489 #endif
2491 D(bug("[IconList] %s: list @ 0x%p, entry @ 0x%p '%s'\n", __PRETTY_FUNCTION__, &(data->icld_IconList), message->obj, ((struct IconEntry *)message->obj)->ie_IconNode.ln_Name));
2493 if (message->obj)
2495 #warning "TODO: Use the correct _OBJECT() code when we switch to icon.mui"
2496 // AddTail(&(data->icld_IconList), (struct Node *)_OBJECT(message->obj));
2497 AddTail(&(data->icld_IconList), (struct Node *)message->obj);
2498 return TRUE;
2500 else
2501 return FALSE;
2503 return (IPTR)NULL;
2505 #if !defined(WANDERER_BUILTIN_ICONLIST)
2506 IPTR IconList__OM_ADDMEMBER(struct IClass *CLASS, Object *obj, struct MUIP_Family_AddTail *message)
2508 return IconList__MUIM_Family_AddTail(CLASS, obj, message);
2510 #endif
2512 IPTR IconList__MUIM_Family_Remove(struct IClass *CLASS, Object *obj, struct MUIP_Family_Remove *message)
2514 struct IconList_DATA *data = INST_DATA(CLASS, obj);
2515 #if defined(DEBUG_ILC_FUNCS)
2516 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
2517 #endif
2519 D(bug("[IconList] %s: entry @ 0x%p '%s'\n", __PRETTY_FUNCTION__, message->obj, ((struct IconEntry *)message->obj)->ie_IconNode.ln_Name));
2521 if (message->obj)
2523 #warning "TODO: Use the correct _OBJECT() code when we switch to icon.mui"
2524 // Remove((struct Node *)_OBJECT(message->obj));
2525 Remove((struct Node *)message->obj);
2526 return TRUE;
2528 else
2529 return FALSE;
2531 return (IPTR)NULL;
2533 #if !defined(WANDERER_BUILTIN_ICONLIST)
2534 IPTR IconList__OM_REMMEMBER(struct IClass *CLASS, Object *obj, struct MUIP_Family_Remove *message)
2536 return IconList__MUIM_Family_Remove(CLASS, obj, message);
2538 #endif
2540 ///MUIM_Setup()
2541 /**************************************************************************
2542 MUIM_Setup
2543 **************************************************************************/
2544 IPTR IconList__MUIM_Setup(struct IClass *CLASS, Object *obj, struct MUIP_Setup *message)
2546 struct IconList_DATA *data = INST_DATA(CLASS, obj);
2547 struct IconEntry *node = NULL;
2548 IPTR geticon_error = 0, iconlistScreen;
2550 #if defined(DEBUG_ILC_FUNCS)
2551 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
2552 #endif
2554 if (!DoSuperMethodA(CLASS, obj, (Msg) message)) return (IPTR)NULL;
2556 iconlistScreen = _screen(obj);
2557 #if defined(DEBUG_ILC_ICONRENDERING)
2558 D(bug("[IconList] %s: IconList Screen @ 0x%p)\n", __PRETTY_FUNCTION__, iconlistScreen));
2559 #endif
2561 DoMethod(_win(obj), MUIM_Window_AddEventHandler, (IPTR)&data->ehn);
2563 /* Get Internal Objects to use if not set .. */
2564 data->icld_DisplayRastPort = NULL;
2565 data->icld_BufferRastPort = NULL;
2567 if (data->icld_IconLabelFont == NULL) data->icld_IconLabelFont = _font(obj);
2568 if (data->icld_IconInfoFont == NULL) data->icld_IconInfoFont = data->icld_IconLabelFont;
2569 #if defined(DEBUG_ILC_ICONRENDERING)
2570 D(bug("[IconList] %s: Use Font @ 0x%p, RastPort @ 0x%p\n", __PRETTY_FUNCTION__, data->icld_IconLabelFont, data->icld_BufferRastPort ));
2571 #endif
2573 /* Set our base options .. */
2574 data->icld_LabelPen = _pens(obj)[MPEN_SHINE];
2575 data->icld_LabelShadowPen = _pens(obj)[MPEN_SHADOW];
2576 data->icld_InfoPen = _pens(obj)[MPEN_SHINE];
2577 data->icld_InfoShadowPen = _pens(obj)[MPEN_SHADOW];
2579 data->icld__Option_LabelTextMultiLine = 1;
2580 data->icld__Option_LastLabelTextMultiLine = data->icld__Option_LabelTextMultiLine;
2582 data->icld__Option_LabelTextMultiLineOnFocus = FALSE;
2584 data->icld__Option_IconHorizontalSpacing = ILC_ICON_HORIZONTALMARGIN_DEFAULT;
2585 data->icld__Option_IconVerticalSpacing = ILC_ICON_VERTICALMARGIN_DEFAULT;
2586 data->icld__Option_IconImageSpacing = ILC_ICONLABEL_IMAGEMARGIN_DEFAULT;
2587 data->icld__Option_LabelTextHorizontalPadding = ILC_ICONLABEL_HORIZONTALTEXTMARGIN_DEFAULT;
2588 data->icld__Option_LabelTextVerticalPadding = ILC_ICONLABEL_VERTICALTEXTMARGIN_DEFAULT;
2589 data->icld__Option_LabelTextBorderWidth = ILC_ICONLABEL_BORDERWIDTH_DEFAULT;
2590 data->icld__Option_LabelTextBorderHeight = ILC_ICONLABEL_BORDERHEIGHT_DEFAULT;
2592 if (data->icld_LVMAttribs)
2594 data->icld_LVMAttribs->lvma_IconDrawer = GetIconTags
2596 "WANDERER:Icons/drawer",
2597 (iconlistScreen) ? ICONGETA_Screen : TAG_IGNORE, iconlistScreen,
2598 (iconlistScreen) ? ICONGETA_RemapIcon : TAG_IGNORE, TRUE,
2599 ICONGETA_FailIfUnavailable, TRUE,
2600 ICONGETA_GenerateImageMasks, TRUE,
2601 ICONA_ErrorCode, &geticon_error,
2602 TAG_DONE
2605 #if defined(DEBUG_ILC_ICONRENDERING)
2606 if (data->icld_LVMAttribs->lvma_IconDrawer == NULL)
2608 D(bug("[IconList] %s: Couldnt get drawer DiskObject! (error code = 0x%p)\n", __PRETTY_FUNCTION__, geticon_error));
2610 #endif
2611 data->icld_LVMAttribs->lvma_IconFile = GetIconTags
2613 "WANDERER:Icons/file",
2614 (iconlistScreen) ? ICONGETA_Screen : TAG_IGNORE, iconlistScreen,
2615 (iconlistScreen) ? ICONGETA_RemapIcon : TAG_IGNORE, TRUE,
2616 ICONGETA_FailIfUnavailable, TRUE,
2617 ICONGETA_GenerateImageMasks, TRUE,
2618 ICONA_ErrorCode, &geticon_error,
2619 TAG_DONE
2622 #if defined(DEBUG_ILC_ICONRENDERING)
2623 if (data->icld_LVMAttribs->lvma_IconFile == NULL)
2625 D(bug("[IconList] %s: Couldnt get file DiskObject! (error code = 0x%p)\n", __PRETTY_FUNCTION__, geticon_error));
2627 #endif
2630 #if defined(__AROS__)
2631 ForeachNode(&data->icld_IconList, node)
2632 #else
2633 Foreach_Node(&data->icld_IconList, node);
2634 #endif
2636 if (!node->ie_DiskObj)
2638 if (!(node->ie_DiskObj = GetIconTags(node->ie_IconNode.ln_Name,
2639 (iconlistScreen) ? ICONGETA_Screen : TAG_IGNORE, iconlistScreen,
2640 (iconlistScreen) ? ICONGETA_RemapIcon : TAG_IGNORE, TRUE,
2641 ICONGETA_GenerateImageMasks, TRUE,
2642 ICONGETA_FailIfUnavailable, FALSE,
2643 ICONA_ErrorCode, &geticon_error,
2644 TAG_DONE)))
2646 #if defined(DEBUG_ILC_ICONRENDERING)
2647 D(bug("[IconList] %s: Failed to obtain Entry '%s's diskobj! (error code = 0x%p)\n", __PRETTY_FUNCTION__, node->ie_IconNode.ln_Name, geticon_error));
2648 #endif
2649 /* We should probably remove this node if the entry cant be obtained ? */
2653 return 1;
2657 ///MUIM_Show()
2658 /**************************************************************************
2659 MUIM_Show
2660 **************************************************************************/
2661 IPTR IconList__MUIM_Show(struct IClass *CLASS, Object *obj, struct MUIP_Show *message)
2663 struct IconList_DATA *data = INST_DATA(CLASS, obj);
2664 LONG newleft,
2665 newtop;
2666 IPTR rc;
2668 #if defined(DEBUG_ILC_FUNCS)
2669 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
2670 #endif
2672 if ((rc = DoSuperMethodA(CLASS, obj, (Msg)message)))
2674 newleft = data->icld_ViewX;
2675 newtop = data->icld_ViewY;
2677 if (newleft + _mwidth(obj) > data->icld_AreaWidth)
2678 newleft = data->icld_AreaWidth - _mwidth(obj);
2679 if (newleft < 0)
2680 newleft = 0;
2682 if (newtop + _mheight(obj) > data->icld_AreaHeight)
2683 newtop = data->icld_AreaHeight - _mheight(obj);
2684 if (newtop < 0)
2685 newtop = 0;
2687 if ((newleft != data->icld_ViewX) || (newtop != data->icld_ViewY))
2689 SetAttrs(obj, MUIA_Virtgroup_Left, newleft,
2690 MUIA_Virtgroup_Top, newtop,
2691 TAG_DONE);
2694 /* Get Internal Objects to use if not set .. */
2695 if (data->icld_DisplayRastPort == NULL)
2697 if (_rp(obj) != NULL)
2699 data->icld_DisplayRastPort = CloneRastPort(_rp(obj));
2701 #if defined(DEBUG_ILC_ICONRENDERING)
2702 else
2704 D(bug("[IconList] IconList__MUIM_Show: ERROR - NULL RastPort!\n"));
2706 #endif
2709 if (data->icld_DisplayFlags & ICONLIST_DISP_BUFFERED)
2711 struct BitMap *bitmap_New = NULL;
2712 struct Layer_Info *li;
2714 ULONG tmp_RastDepth = GetCyberMapAttr(data->icld_DisplayRastPort->BitMap, CYBRMATTR_DEPTH);
2715 if ((bitmap_New = AllocBitMap(data->icld_ViewWidth,
2716 data->icld_ViewHeight,
2717 tmp_RastDepth,
2718 BMF_CLEAR,
2719 data->icld_DisplayRastPort->BitMap))!=NULL)
2721 if ((data->icld_BufferRastPort = CreateRastPort())!=NULL)
2723 data->icld_BufferRastPort->BitMap = bitmap_New;
2724 if (li = NewLayerInfo())
2726 if (data->icld_BufferRastPort->Layer = CreateUpfrontLayer(li, data->icld_BufferRastPort->BitMap, 0, 0, data->icld_ViewWidth - 1, data->icld_ViewHeight - 1, 0, NULL))
2729 * Mark it as a buffered rastport.
2732 #if defined(DEBUG_ILC_ATTRIBS) || defined(DEBUG_ILC_ICONRENDERING)
2733 D(bug("[IconList] %s: FrontRastPort @ %p, New BackLayer @ %p, BackRastport @ %p\n", __PRETTY_FUNCTION__, data->icld_DisplayRastPort, data->icld_BufferRastPort->Layer, data->icld_BufferRastPort));
2734 #endif
2735 SET(obj, MUIA_IconList_BufferRastport, data->icld_BufferRastPort);
2736 data->icld_DrawOffsetX = 0;
2737 data->icld_DrawOffsetY = 0;
2739 else
2740 data->icld_BufferRastPort = data->icld_DisplayRastPort;
2742 else
2743 data->icld_BufferRastPort = data->icld_DisplayRastPort;
2745 else
2746 data->icld_BufferRastPort = data->icld_DisplayRastPort;
2748 if (data->icld_BufferRastPort == data->icld_DisplayRastPort)
2750 if (bitmap_New) FreeBitMap(bitmap_New);
2751 if (li) DisposeLayerInfo(li);
2752 data->icld_DrawOffsetX = _mleft(obj);
2753 data->icld_DrawOffsetY = _mtop(obj);
2756 else
2758 data->icld_BufferRastPort = data->icld_DisplayRastPort;
2759 data->icld_DrawOffsetX = _mleft(obj);
2760 data->icld_DrawOffsetY = _mtop(obj);
2763 if (data->icld_IconLabelFont == NULL) data->icld_IconLabelFont = _font(obj);
2764 if (data->icld_IconInfoFont == NULL) data->icld_IconInfoFont = data->icld_IconLabelFont;
2765 #if defined(DEBUG_ILC_ICONRENDERING)
2766 D(bug("[IconList] IconList__MUIM_Show: Use Font @ 0x%p, RastPort @ 0x%p\n", data->icld_IconLabelFont, data->icld_BufferRastPort ));
2767 #endif
2769 if ((data->icld_BufferRastPort) && (data->icld_IconLabelFont))
2770 SetFont(data->icld_BufferRastPort, data->icld_IconLabelFont);
2772 return rc;
2776 ///MUIM_Hide()
2777 /**************************************************************************
2778 MUIM_Hide
2779 **************************************************************************/
2780 IPTR IconList__MUIM_Hide(struct IClass *CLASS, Object *obj, struct MUIP_Hide *message)
2782 struct IconList_DATA *data = INST_DATA(CLASS, obj);
2783 IPTR rc;
2785 #if defined(DEBUG_ILC_FUNCS)
2786 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
2787 #endif
2789 if ((rc = DoSuperMethodA(CLASS, obj, (Msg)message)))
2791 if ((data->icld_BufferRastPort) && (data->icld_BufferRastPort != data->icld_DisplayRastPort))
2793 DeleteLayer(0, data->icld_BufferRastPort->Layer);
2796 data->icld_BufferRastPort = NULL;
2798 if (data->icld_DisplayRastPort)
2799 FreeRastPort(data->icld_DisplayRastPort);
2801 data->icld_DisplayRastPort = NULL;
2803 return rc;
2807 ///MUIM_Cleanup()
2808 /**************************************************************************
2809 MUIM_Cleanup
2810 **************************************************************************/
2811 IPTR IconList__MUIM_Cleanup(struct IClass *CLASS, Object *obj, struct MUIP_Cleanup *message)
2813 struct IconList_DATA *data = INST_DATA(CLASS, obj);
2814 struct IconEntry *node = NULL;
2816 #if defined(DEBUG_ILC_FUNCS)
2817 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
2818 #endif
2820 #if defined(__AROS__)
2821 ForeachNode(&data->icld_IconList, node)
2822 #else
2823 Foreach_Node(&data->icld_IconList, node);
2824 #endif
2826 if (node->ie_DiskObj)
2828 FreeDiskObject(node->ie_DiskObj);
2829 node->ie_DiskObj = NULL;
2833 DoMethod(_win(obj), MUIM_Window_RemEventHandler, (IPTR)&data->ehn);
2835 return DoSuperMethodA(CLASS, obj, (Msg)message);
2839 ///MUIM_AskMinMax()
2840 /**************************************************************************
2841 MUIM_AskMinMax
2842 **************************************************************************/
2843 IPTR IconList__MUIM_AskMinMax(struct IClass *CLASS, Object *obj, struct MUIP_AskMinMax *message)
2845 ULONG rc = DoSuperMethodA(CLASS, obj, (Msg) message);
2847 #if defined(DEBUG_ILC_FUNCS)
2848 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
2849 #endif
2851 message->MinMaxInfo->MinWidth += 96;
2852 message->MinMaxInfo->MinHeight += 64;
2854 message->MinMaxInfo->DefWidth += 200;
2855 message->MinMaxInfo->DefHeight += 180;
2857 message->MinMaxInfo->MaxWidth = MUI_MAXMAX;
2858 message->MinMaxInfo->MaxHeight = MUI_MAXMAX;
2860 return rc;
2864 ///MUIM_Layout()
2865 /**************************************************************************
2866 MUIM_Layout
2867 **************************************************************************/
2868 IPTR IconList__MUIM_Layout(struct IClass *CLASS, Object *obj,struct MUIP_Layout *message)
2870 struct IconList_DATA *data = INST_DATA(CLASS, obj);
2871 ULONG rc;
2873 #if defined(DEBUG_ILC_FUNCS)
2874 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
2875 #endif
2877 rc = DoSuperMethodA(CLASS, obj, (Msg)message);
2879 data->icld_ViewWidth = _mwidth(obj);
2880 data->icld_ViewHeight = _mheight(obj);
2882 return rc;
2886 static LONG FirstVisibleLine(struct IconList_DATA *data)
2888 return data->icld_ViewY / data->icld_LVMAttribs->lmva_RowHeight;
2891 static LONG NumVisibleLines(struct IconList_DATA *data)
2893 LONG visible = data->icld_ViewHeight + data->icld_LVMAttribs->lmva_RowHeight - 1 +
2894 (data->icld_ViewY % data->icld_LVMAttribs->lmva_RowHeight);
2896 visible /= data->icld_LVMAttribs->lmva_RowHeight;
2898 return visible;
2901 static void RenderListViewModeHeaderField(Object *obj, struct IconList_DATA *data,
2902 struct Rectangle *rect, LONG index, BOOL sel)
2904 IPTR penFill, penText, penDark, penBright;
2905 struct Rectangle rendRect;
2906 STRPTR text;
2907 struct TextExtent te;
2908 ULONG fit;
2910 if (sel == TRUE)
2912 penFill = _pens(obj)[MPEN_HALFSHADOW];
2913 penBright = _pens(obj)[MPEN_SHADOW];
2914 penDark = _pens(obj)[MPEN_HALFSHINE];
2916 else
2918 penFill = _pens(obj)[MPEN_HALFSHINE];
2919 penBright = _pens(obj)[MPEN_SHINE];
2920 penDark = _pens(obj)[MPEN_HALFSHADOW];
2922 penText = _pens(obj)[MPEN_TEXT];
2924 rendRect.MinX = rect->MinX;
2925 rendRect.MaxX = rect->MaxX;
2926 rendRect.MinY = rect->MinY;
2927 rendRect.MaxY = rect->MaxY;
2929 if (data->icld_DisplayRastPort != data->icld_BufferRastPort)
2931 rendRect.MinX -= _mleft(obj);
2932 rendRect.MaxX -= _mleft(obj);
2933 rendRect.MinY -= _mtop(obj);
2934 rendRect.MaxY -= _mtop(obj);
2937 #if defined(DEBUG_ILC_FUNCS)
2938 D(bug("[IconList]: %s(obj @ 0x%p)\n", __PRETTY_FUNCTION__, obj));
2939 #endif
2941 if (((data->icld_LVMAttribs->lvma_Flags & LVMAF_NOHEADER) == 0) && (index < NUM_COLUMNS))
2943 text = data->icld_LVMAttribs->lmva_ColumnTitle[index];
2945 SetAPen(data->icld_BufferRastPort, penFill); /* Background */
2946 RectFill(data->icld_BufferRastPort, rendRect.MinX + 1, rendRect.MinY + 1,
2947 rendRect.MaxX - 1, rendRect.MaxY - 1);
2949 SetAPen(data->icld_BufferRastPort, penBright); /* Top/Left */
2950 RectFill(data->icld_BufferRastPort, rendRect.MinX, rendRect.MinY, rendRect.MinX, rendRect.MaxY);
2951 RectFill(data->icld_BufferRastPort, rendRect.MinX + 1, rendRect.MinY, rendRect.MaxX - 1, rendRect.MinY);
2953 SetAPen(data->icld_BufferRastPort,penDark); /* Bottom/Right */
2954 RectFill(data->icld_BufferRastPort, rendRect.MaxX, rendRect.MinY, rendRect.MaxX, rendRect.MaxY);
2955 RectFill(data->icld_BufferRastPort, rendRect.MinX + 1, rendRect.MaxY, rendRect.MaxX - 1, rendRect.MaxY);
2957 /* Draw the Sort indicator .. */
2958 if (index == data->icld_LVMAttribs->lmva_SortColumn)
2960 LONG x = rendRect.MaxX - 4 - 6;
2961 LONG y = (rendRect.MinY + rendRect.MaxY + 1) / 2 - 3;
2963 if (x > rendRect.MinX)
2965 SetAPen(data->icld_BufferRastPort, _pens(obj)[sel ? MPEN_SHADOW : MPEN_HALFSHADOW]);
2966 if (data->icld_SortFlags & MUIV_IconList_Sort_Reverse)
2968 RectFill(data->icld_BufferRastPort, x, y, x + 5, y + 1);
2969 RectFill(data->icld_BufferRastPort, x + 1, y + 2, x + 4, y + 3);
2970 RectFill(data->icld_BufferRastPort, x + 2, y + 4, x + 3, y + 5);
2972 else
2974 RectFill(data->icld_BufferRastPort, x, y + 4, x + 5, y + 5);
2975 RectFill(data->icld_BufferRastPort, x + 1, y + 2, x + 4, y + 3);
2976 RectFill(data->icld_BufferRastPort, x + 2, y, x + 3, y + 1);
2981 rendRect.MinX += HEADERENTRY_SPACING_LEFT;
2982 rendRect.MinY += HEADERLINE_SPACING_TOP;
2983 rendRect.MaxX -= HEADERENTRY_SPACING_RIGHT;
2984 rendRect.MaxY -= HEADERLINE_SPACING_BOTTOM;
2986 if (text && text[0])
2989 fit = TextFit(data->icld_BufferRastPort, text, strlen(text), &te, NULL, 1,
2990 rendRect.MaxX - rendRect.MinX + 1,
2991 rendRect.MaxY - rendRect.MinY + 1);
2993 if (!fit) return;
2995 SetABPenDrMd(data->icld_BufferRastPort, penText, 0, JAM1);
2996 Move(data->icld_BufferRastPort, rendRect.MinX, rendRect.MinY + data->icld_BufferRastPort->TxBaseline);
2997 Text(data->icld_BufferRastPort, text, fit);
3002 static void RenderListViewModeHeader(Object *obj, struct IconList_DATA *data)
3004 struct Rectangle linerect;
3005 LONG x, i;
3006 LONG firstvis, lastvis;
3008 #if defined(DEBUG_ILC_FUNCS)
3009 D(bug("[IconList]: %s(obj @ 0x%p)\n", __PRETTY_FUNCTION__, obj));
3010 #endif
3012 if ((data->icld_LVMAttribs->lvma_Flags & LVMAF_NOHEADER) == 0)
3014 linerect.MinX = _mleft(obj) - data->icld_ViewX;
3015 linerect.MaxX = _mright(obj);
3016 linerect.MinY = _mtop(obj);
3017 linerect.MaxY = _mtop(obj) + data->icld_LVMAttribs->lmva_HeaderHeight - 1;
3019 SetFont(data->icld_BufferRastPort, data->icld_IconLabelFont);
3021 x = linerect.MinX + HEADERLINE_SPACING_LEFT;
3023 firstvis = FirstVisibleColumnNumber(data);
3024 lastvis = LastVisibleColumnNumber(data);
3026 for(i = 0; i < NUM_COLUMNS; i++)
3028 LONG index = data->icld_LVMAttribs->lmva_ColumnPos[i];
3030 if (!(data->icld_LVMAttribs->lmva_ColumnFlags[index] & LVMCF_COLVISIBLE)) continue;
3032 BOOL outside = FALSE;
3033 struct Rectangle field_rect;
3035 field_rect.MinX = (i == firstvis) ? linerect.MinX : x;
3036 field_rect.MinY = linerect.MinY;
3037 field_rect.MaxX = x + data->icld_LVMAttribs->lmva_ColumnWidth[index] - 1 + ((i == lastvis) ? HEADERLINE_SPACING_RIGHT : 0);
3038 field_rect.MaxY = linerect.MaxY;
3040 /* data->update_rect1 and data->update_rect2 may
3041 point to rectangles to indicate that only icons
3042 in any of this rectangles need to be drawn */
3043 if (data->update_rect1)
3045 if (!RectAndRect(&field_rect, data->update_rect1))
3046 outside = TRUE;
3049 if (data->update_rect2)
3051 if (data->update_rect1)
3053 if ((outside == TRUE) && RectAndRect(&field_rect, data->update_rect2))
3054 outside = FALSE;
3056 else
3058 if (!RectAndRect(&field_rect, data->update_rect2))
3059 outside = TRUE;
3063 if (outside != TRUE)
3065 RenderListViewModeHeaderField(obj, data, &field_rect, index, FALSE);
3066 x += data->icld_LVMAttribs->lmva_ColumnWidth[index];
3068 #if defined(DEBUG_ILC_ICONRENDERING)
3069 else
3071 D(bug("[IconList] %s: Column '%s' outside of update area .. skipping\n", __PRETTY_FUNCTION__, data->icld_LVMAttribs->lmva_ColumnTitle[i]));
3073 #endif
3076 if ((data->icld_LVMAttribs->lvma_Flags & LVMAF_HEADERDRAWTOEND) == LVMAF_HEADERDRAWTOEND)
3078 x += HEADERLINE_SPACING_RIGHT;
3080 if (x < linerect.MaxX)
3082 linerect.MinX = x;
3084 // if (MustRenderRect(data, &linerect))
3085 // {
3086 SetABPenDrMd(data->icld_BufferRastPort, _pens(obj)[MPEN_HALFSHINE], 0, JAM1);
3087 RectFill(data->icld_BufferRastPort, linerect.MinX, linerect.MinY, linerect.MaxX, linerect.MaxY);
3088 // }
3094 ///MUIM_Draw()
3095 /**************************************************************************
3096 MUIM_Draw - draw the IconList
3097 **************************************************************************/
3098 IPTR DrawCount;
3099 IPTR IconList__MUIM_Draw(struct IClass *CLASS, Object *obj, struct MUIP_Draw *message)
3101 struct IconList_DATA *data = INST_DATA(CLASS, obj);
3102 struct IconEntry *entry = NULL;
3104 APTR clip = NULL;
3106 ULONG update_oldwidth = 0,
3107 update_oldheight = 0;
3109 LONG clear_xoffset = 0,
3110 clear_yoffset = 0;
3112 IPTR draw_id = DrawCount++;
3114 #if defined(DEBUG_ILC_FUNCS)
3115 D(bug("[IconList]: %s(obj @ 0x%p)\n", __PRETTY_FUNCTION__, obj));
3116 #endif
3117 #if defined(DEBUG_ILC_ICONRENDERING)
3118 D(bug("[IconList] %s: id %d\n", __PRETTY_FUNCTION__, draw_id));
3119 #endif
3121 DoSuperMethodA(CLASS, obj, (Msg)message);
3123 if (!(data->icld__Option_IconListFixedBackground))
3125 clear_xoffset = data->icld_ViewX;
3126 clear_yoffset = data->icld_ViewY;
3129 // If window size changes, only update needed areas
3130 if (data->update_oldwidth == 0) data->update_oldwidth = data->icld_ViewWidth;
3131 if (data->update_oldheight == 0) data->update_oldheight = data->icld_ViewHeight;
3132 if ((data->update_oldwidth != data->icld_ViewWidth) || (data->update_oldheight != data->icld_ViewHeight))
3134 if (data->icld_UpdateMode != UPDATE_SCROLL)
3136 data->icld_UpdateMode = UPDATE_RESIZE;
3137 update_oldwidth = data->update_oldwidth;
3138 update_oldheight = data->update_oldheight;
3139 data->update_oldwidth = data->icld_ViewWidth;
3140 data->update_oldheight = data->icld_ViewHeight;
3144 if ((message->flags & MADF_DRAWUPDATE) || (data->icld_UpdateMode == UPDATE_RESIZE))
3146 #if defined(DEBUG_ILC_ICONRENDERING)
3148 if (message->flags & MADF_DRAWUPDATE)
3150 bug("[IconList] %s#%d: MADF_DRAWUPDATE\n", __PRETTY_FUNCTION__, draw_id);
3152 else
3154 bug("[IconList] %s#%d: UPDATE_RESIZE\n", __PRETTY_FUNCTION__, draw_id);
3157 #endif
3158 if ((data->icld_UpdateMode == UPDATE_HEADERENTRY) && (data->update_entry < NUM_COLUMNS)) /* draw the header entry */
3160 struct Rectangle field_rect;
3161 LONG index, i, firstvis, lastvis;
3163 firstvis = FirstVisibleColumnNumber(data);
3164 lastvis = LastVisibleColumnNumber(data);
3166 field_rect.MinX = _mleft(obj) - data->icld_ViewX;
3168 field_rect.MinY = _mtop(obj);
3169 field_rect.MaxY = field_rect.MinY + data->icld_LVMAttribs->lmva_HeaderHeight - 1;
3171 for(i = 0; i < NUM_COLUMNS; i++)
3173 index = data->icld_LVMAttribs->lmva_ColumnPos[i];
3174 if (!(data->icld_LVMAttribs->lmva_ColumnFlags[index] & LVMCF_COLVISIBLE)) continue;
3176 field_rect.MaxX = field_rect.MinX + data->icld_LVMAttribs->lmva_ColumnWidth[index] - 1;
3177 if (index == lastvis)
3178 field_rect.MaxX += HEADERLINE_SPACING_RIGHT;
3180 if (data->update_entry != index)
3182 field_rect.MinX += data->icld_LVMAttribs->lmva_ColumnWidth[index];
3183 if (index == firstvis)
3184 field_rect.MinX += HEADERLINE_SPACING_LEFT;
3186 else
3187 break;
3190 clip = MUI_AddClipping(muiRenderInfo(obj), _mleft(obj), _mtop(obj), _mright(obj) - _mleft(obj) + 1, data->icld_LVMAttribs->lmva_HeaderHeight);
3192 if (data->icld_LVMAttribs->lmva_LastSelectedColumn == data->update_entry)
3193 RenderListViewModeHeaderField(obj, data, &field_rect, data->update_entry, TRUE);
3194 else
3195 RenderListViewModeHeaderField(obj, data, &field_rect, data->update_entry, FALSE);
3197 data->icld_UpdateMode = 0;
3198 data->update_entry = NULL;
3200 if (data->icld_DisplayRastPort != data->icld_BufferRastPort)
3202 #if defined(DEBUG_ILC_ICONRENDERING)
3203 D(bug("[IconList] %s#%d: UPDATE_HEADERENTRY Blitting to front rastport..\n", __PRETTY_FUNCTION__, draw_id));
3204 #endif
3205 BltBitMapRastPort(data->icld_BufferRastPort->BitMap,
3206 field_rect.MinX - _mleft(obj), field_rect.MinY - _mtop(obj),
3207 data->icld_DisplayRastPort,
3208 field_rect.MinX, field_rect.MinY,
3209 field_rect.MaxX - field_rect.MinX + 1, field_rect.MaxY - field_rect.MinY + 1,
3210 0xC0);
3212 MUI_RemoveClipping(muiRenderInfo(obj), clip);
3214 goto draw_done;
3216 else if ((data->icld_UpdateMode == UPDATE_SINGLEENTRY) && (data->update_entry != NULL)) /* draw only a single entry at update_entry */
3218 struct Rectangle rect;
3220 if ((data->icld_DisplayFlags & ICONLIST_DISP_MODELIST) == ICONLIST_DISP_MODELIST)
3222 LONG count = 0, index = -1;
3224 #if defined(DEBUG_ILC_ICONRENDERING)
3225 D(bug("[IconList] %s#%d: UPDATE_SINGLEENTRY + ICONLIST_DISP_MODELIST\n", __PRETTY_FUNCTION__, draw_id));
3226 #endif
3227 rect.MinX = _mleft(obj);
3228 rect.MaxX = _mleft(obj) + _mwidth(obj) - 1;
3230 ForeachNode(&data->icld_IconList, entry)
3232 if (entry == data->update_entry)
3234 index = count;
3235 break;
3237 if (entry->ie_Flags & ICONENTRY_FLAG_VISIBLE)
3239 count++;
3243 if (index != -1)
3245 rect.MinY = _mtop(obj) + data->icld_LVMAttribs->lmva_HeaderHeight - data->icld_ViewY + (index * data->icld_LVMAttribs->lmva_RowHeight);
3246 rect.MaxY = rect.MinY + data->icld_LVMAttribs->lmva_RowHeight - 1;
3248 if ((rect.MaxY < (_mtop(obj) + data->icld_LVMAttribs->lmva_HeaderHeight))
3249 || (rect.MinY > (_mtop(obj) + _mheight(obj) - 1)))
3250 goto draw_done;
3252 if (rect.MinY < (_mtop(obj) + data->icld_LVMAttribs->lmva_HeaderHeight)) rect.MinY = _mtop(obj) + data->icld_LVMAttribs->lmva_HeaderHeight;
3253 if (rect.MaxY > (_mtop(obj) + _mheight(obj) - 1)) rect.MaxY = _mtop(obj) + _mheight(obj) - 1;
3255 clip = MUI_AddClipping(muiRenderInfo(obj), rect.MinX, rect.MinY, rect.MaxX - rect.MinX + 1, rect.MaxY - rect.MinY + 1);
3257 DoMethod(obj, MUIM_DrawBackground,
3258 rect.MinX, rect.MinY,
3259 rect.MaxX - rect.MinX + 1, rect.MaxY - rect.MinY + 1,
3260 clear_xoffset, clear_yoffset,
3263 entry->ie_Flags |= ICONENTRY_FLAG_NEEDSUPDATE;
3264 DoMethod(obj, MUIM_IconList_DrawEntry, data->update_entry, index);
3265 entry->ie_Flags &= ~ICONENTRY_FLAG_NEEDSUPDATE;
3266 data->icld_UpdateMode = 0;
3267 data->update_entry = NULL;
3270 else
3272 #if defined(DEBUG_ILC_ICONRENDERING)
3273 D(bug("[IconList] %s#%d: UPDATE_SINGLEENTRY (entry @ 0x%p)\n", __PRETTY_FUNCTION__, draw_id, data->update_entry));
3274 #endif
3275 IconList_GetIconAreaRectangle(obj, data, data->update_entry, &rect);
3277 rect.MinX += _mleft(obj) + (data->update_entry->ie_IconX - data->icld_ViewX);
3278 rect.MaxX += _mleft(obj) + (data->update_entry->ie_IconX - data->icld_ViewX);
3279 rect.MinY += _mtop(obj) + (data->update_entry->ie_IconY - data->icld_ViewY);
3280 rect.MaxY += _mtop(obj) + (data->update_entry->ie_IconY - data->icld_ViewY);
3282 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
3284 if (data->update_entry->ie_AreaWidth < data->icld_IconAreaLargestWidth)
3286 rect.MinX += ((data->icld_IconAreaLargestWidth - data->update_entry->ie_AreaWidth)/2);
3287 rect.MaxX += ((data->icld_IconAreaLargestWidth - data->update_entry->ie_AreaWidth)/2);
3290 if (data->update_entry->ie_AreaHeight < data->icld_IconAreaLargestHeight)
3292 rect.MinY += ((data->icld_IconAreaLargestHeight - data->update_entry->ie_AreaHeight)/2);
3293 rect.MaxY += ((data->icld_IconAreaLargestHeight - data->update_entry->ie_AreaHeight)/2);
3297 if (rect.MinX < _mleft(obj)) rect.MinX = _mleft(obj);
3298 if (rect.MaxX > _mright(obj)) rect.MaxX =_mright(obj);
3299 if (rect.MinY < _mtop(obj)) rect.MinY = _mtop(obj);
3300 if (rect.MaxY > _mbottom(obj)) rect.MaxY = _mbottom(obj);
3302 clip = MUI_AddClipping(muiRenderInfo(obj), rect.MinX, rect.MinY, rect.MaxX - rect.MinX + 1, rect.MaxY - rect.MinY + 1);
3304 #if defined(DEBUG_ILC_ICONRENDERING)
3305 D(bug("[IconList] %s#%d: UPDATE_SINGLEENTRY: Calling MUIM_DrawBackground (A)\n", __PRETTY_FUNCTION__, draw_id));
3306 #endif
3307 DoMethod(obj, MUIM_DrawBackground,
3308 rect.MinX, rect.MinY,
3309 rect.MaxX - rect.MinX + 1, rect.MaxY - rect.MinY + 1,
3310 clear_xoffset, clear_yoffset,
3313 /* We could have deleted also other icons so they must be redrawn */
3314 #if defined(__AROS__)
3315 ForeachNode(&data->icld_IconList, entry)
3316 #else
3317 Foreach_Node(&data->icld_IconList, entry);
3318 #endif
3320 if ((entry != data->update_entry) && (entry->ie_Flags & ICONENTRY_FLAG_VISIBLE))
3322 struct Rectangle rect2;
3323 IconList_GetIconAreaRectangle(obj, data, entry, &rect2);
3325 rect2.MinX += _mleft(obj) - data->icld_ViewX + entry->ie_IconX;
3326 rect2.MaxX += _mleft(obj) - data->icld_ViewX + entry->ie_IconX;
3327 rect2.MinY += _mtop(obj) - data->icld_ViewY + entry->ie_IconY;
3328 rect2.MaxY += _mtop(obj) - data->icld_ViewY + entry->ie_IconY;
3330 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
3332 if (entry->ie_AreaWidth < data->icld_IconAreaLargestWidth)
3334 rect2.MinX += ((data->icld_IconAreaLargestWidth - entry->ie_AreaWidth)/2);
3335 rect2.MaxX += ((data->icld_IconAreaLargestWidth - entry->ie_AreaWidth)/2);
3338 if (entry->ie_AreaHeight < data->icld_IconAreaLargestHeight)
3340 rect2.MinY += ((data->icld_IconAreaLargestHeight - entry->ie_AreaHeight)/2);
3341 rect2.MaxY += ((data->icld_IconAreaLargestHeight - entry->ie_AreaHeight)/2);
3345 if (RectAndRect(&rect, &rect2))
3347 // Update entry here
3348 entry->ie_Flags |= ICONENTRY_FLAG_NEEDSUPDATE;
3349 DoMethod(obj, MUIM_IconList_DrawEntry, entry, ICONENTRY_DRAWMODE_PLAIN);
3350 DoMethod(obj, MUIM_IconList_DrawEntryLabel, entry, ICONENTRY_DRAWMODE_PLAIN);
3351 entry->ie_Flags &= ~ICONENTRY_FLAG_NEEDSUPDATE;
3356 entry->ie_Flags |= ICONENTRY_FLAG_NEEDSUPDATE;
3357 DoMethod(obj, MUIM_IconList_DrawEntry, data->update_entry, ICONENTRY_DRAWMODE_PLAIN);
3358 DoMethod(obj, MUIM_IconList_DrawEntryLabel, data->update_entry, ICONENTRY_DRAWMODE_PLAIN);
3359 entry->ie_Flags &= ~ICONENTRY_FLAG_NEEDSUPDATE;
3360 data->icld_UpdateMode = 0;
3361 data->update_entry = NULL;
3363 if (data->update_entry == NULL)
3365 if (data->icld_DisplayRastPort != data->icld_BufferRastPort)
3367 #if defined(DEBUG_ILC_ICONRENDERING)
3368 D(bug("[IconList] %s#%d: UPDATE_SINGLEENTRY Blitting to front rastport..\n", __PRETTY_FUNCTION__, draw_id));
3369 #endif
3370 BltBitMapRastPort(data->icld_BufferRastPort->BitMap,
3371 rect.MinX - _mleft(obj), rect.MinY - _mtop(obj),
3372 data->icld_DisplayRastPort,
3373 rect.MinX, rect.MinY,
3374 rect.MaxX - rect.MinX + 1, rect.MaxY - rect.MinY + 1,
3375 0xC0);
3377 MUI_RemoveClipping(muiRenderInfo(obj), clip);
3379 goto draw_done;
3381 else if (data->icld_UpdateMode == UPDATE_SCROLL)
3383 struct Region *region = NULL;
3384 struct Rectangle xrect,
3385 yrect;
3386 BOOL scroll_caused_damage;
3388 #if defined(DEBUG_ILC_ICONRENDERING)
3389 D(bug("[IconList] %s#%d: UPDATE_SCROLL.\n", __PRETTY_FUNCTION__, draw_id));
3390 #endif
3392 if (!data->icld__Option_IconListFixedBackground)
3394 scroll_caused_damage = (_rp(obj)->Layer->Flags & LAYERREFRESH) ? FALSE : TRUE;
3396 data->icld_UpdateMode = 0;
3398 if ((abs(data->update_scrolldx) >= _mwidth(obj)) ||
3399 (abs(data->update_scrolldy) >= _mheight(obj)))
3401 #if defined(DEBUG_ILC_ICONRENDERING)
3402 D(bug("[IconList] %s#%d: UPDATE_SCROLL: Moved outside current view -> Causing Redraw .. MADF_DRAWOBJECT\n", __PRETTY_FUNCTION__, draw_id));
3403 #endif
3404 MUI_Redraw(obj, MADF_DRAWOBJECT);
3405 goto draw_done;
3408 if (!(region = NewRegion()))
3410 #if defined(DEBUG_ILC_ICONRENDERING)
3411 D(bug("[IconList] %s#%d: UPDATE_SCROLL: Couldnt Alloc Region -> Causing Redraw ...MADF_DRAWOBJECT\n", __PRETTY_FUNCTION__, draw_id));
3412 #endif
3413 MUI_Redraw(obj, MADF_DRAWOBJECT);
3414 goto draw_done;
3417 if (data->update_scrolldx > 0)
3419 xrect.MinX = _mright(obj) - data->update_scrolldx;
3420 xrect.MinY = _mtop(obj);
3421 xrect.MaxX = _mright(obj);
3422 xrect.MaxY = _mbottom(obj);
3424 OrRectRegion(region, &xrect);
3426 data->update_rect1 = &xrect;
3428 else if (data->update_scrolldx < 0)
3430 xrect.MinX = _mleft(obj);
3431 xrect.MinY = _mtop(obj);
3432 xrect.MaxX = _mleft(obj) - data->update_scrolldx;
3433 xrect.MaxY = _mbottom(obj);
3435 OrRectRegion(region, &xrect);
3437 data->update_rect1 = &xrect;
3440 if (data->update_scrolldy > 0)
3442 yrect.MinX = _mleft(obj);
3443 yrect.MinY = _mbottom(obj) - data->update_scrolldy;
3444 if (((data->icld_DisplayFlags & ICONLIST_DISP_MODELIST) == ICONLIST_DISP_MODELIST)
3445 && (yrect.MinY < (_mtop(obj) + data->icld_LVMAttribs->lmva_HeaderHeight)))
3447 xrect.MinY = data->icld_LVMAttribs->lmva_HeaderHeight;
3449 yrect.MaxX = _mright(obj);
3450 yrect.MaxY = _mbottom(obj);
3452 OrRectRegion(region, &yrect);
3454 data->update_rect2 = &yrect;
3456 else if (data->update_scrolldy < 0)
3458 yrect.MinX = _mleft(obj);
3459 yrect.MinY = _mtop(obj);
3460 if ((data->icld_DisplayFlags & ICONLIST_DISP_MODELIST) == ICONLIST_DISP_MODELIST)
3462 xrect.MinY += data->icld_LVMAttribs->lmva_HeaderHeight;
3464 yrect.MaxX = _mright(obj);
3465 yrect.MaxY = _mtop(obj) - data->update_scrolldy;
3467 OrRectRegion(region, &yrect);
3469 data->update_rect2 = &yrect;
3472 #if defined(DEBUG_ILC_ICONRENDERING)
3473 D(bug("[IconList] %s#%d: UPDATE_SCROLL: Scrolling Raster..\n", __PRETTY_FUNCTION__, draw_id));
3474 #endif
3475 if (data->icld_DisplayRastPort == data->icld_BufferRastPort)
3477 ScrollRasterBF(data->icld_BufferRastPort,
3478 data->update_scrolldx,
3479 data->update_scrolldy,
3480 _mleft(obj),
3481 _mtop(obj),
3482 _mright(obj),
3483 _mbottom(obj));
3485 else
3487 ScrollRasterBF(data->icld_BufferRastPort,
3488 data->update_scrolldx,
3489 data->update_scrolldy,
3492 _mwidth(obj) - 1,
3493 _mheight(obj) - 1);
3496 scroll_caused_damage = scroll_caused_damage && (_rp(obj)->Layer->Flags & LAYERREFRESH) ? TRUE : FALSE;
3498 clip = MUI_AddClipRegion(muiRenderInfo(obj), region);
3501 #if defined(DEBUG_ILC_ICONRENDERING)
3502 D(bug("[IconList] %s#%d: UPDATE_SCROLL: Causing Redraw -> MADF_DRAWOBJECT..\n", __PRETTY_FUNCTION__, draw_id));
3503 #endif
3504 MUI_Redraw(obj, MADF_DRAWOBJECT);
3506 data->update_rect1 = data->update_rect2 = NULL;
3508 if (!data->icld__Option_IconListFixedBackground)
3510 MUI_RemoveClipRegion(muiRenderInfo(obj), clip);
3512 if (scroll_caused_damage)
3514 if (MUI_BeginRefresh(muiRenderInfo(obj), 0))
3516 /* Theoretically it might happen that more damage is caused
3517 after ScrollRaster. By something else, like window movement
3518 in front of our window. Therefore refresh root object of
3519 window, not just this object */
3521 Object *o = NULL;
3523 GET(_win(obj),MUIA_Window_RootObject, &o);
3524 MUI_Redraw(o, MADF_DRAWOBJECT);
3525 #if defined(DEBUG_ILC_ICONRENDERING)
3526 D(bug("[IconList] %s#%d: UPDATE_SCROLL: Causing Redraw -> MADF_DRAWOBJECT..\n", __PRETTY_FUNCTION__, draw_id));
3527 #endif
3528 MUI_EndRefresh(muiRenderInfo(obj), 0);
3532 if (data->icld_DisplayRastPort != data->icld_BufferRastPort)
3534 #if defined(DEBUG_ILC_ICONRENDERING)
3535 D(bug("[IconList] %s#%d: UPDATE_SCROLL: Blitting to front rastport..\n", __PRETTY_FUNCTION__, draw_id));
3536 #endif
3537 BltBitMapRastPort(data->icld_BufferRastPort->BitMap,
3538 0, 0,
3539 data->icld_DisplayRastPort,
3540 _mleft(obj), _mtop(obj),
3541 _mwidth(obj), _mheight(obj),
3542 0xC0);
3544 goto draw_done;
3546 else if (data->icld_UpdateMode == UPDATE_RESIZE)
3548 struct Region *region = NULL;
3549 struct Rectangle wrect,
3550 hrect;
3551 ULONG diffw = 0,
3552 diffh = 0;
3554 #if defined(DEBUG_ILC_ICONRENDERING)
3555 D(bug("[IconList] %s#%d: UPDATE_RESIZE.\n", __PRETTY_FUNCTION__, draw_id));
3556 #endif
3558 if ((data->icld_BufferRastPort) && (data->icld_BufferRastPort != data->icld_DisplayRastPort))
3560 //Free up the buffers Layer, rastport and bitmap so we can replace them ..
3561 if ((GetBitMapAttr(data->icld_BufferRastPort->BitMap, BMA_WIDTH) != data->icld_ViewWidth)
3562 || (GetBitMapAttr(data->icld_BufferRastPort->BitMap, BMA_HEIGHT) != data->icld_ViewHeight))
3564 struct Layer *oldLayer = data->icld_BufferRastPort->Layer;
3565 #if defined(DEBUG_ILC_ATTRIBS) || defined(DEBUG_ILC_ICONRENDERING)
3566 D(bug("[IconList] %s: Destroying old BackLayer\n", __PRETTY_FUNCTION__));
3567 #endif
3568 data->icld_BufferRastPort = data->icld_DisplayRastPort;
3569 DeleteLayer(0, oldLayer);
3572 if (data->icld_BufferRastPort == data->icld_DisplayRastPort)
3574 struct Bitmap *bitmap_New;
3575 ULONG tmp_RastDepth;
3576 struct Layer_Info *li;
3578 tmp_RastDepth = GetCyberMapAttr(data->icld_DisplayRastPort->BitMap, CYBRMATTR_DEPTH);
3579 if ((bitmap_New = (struct Bitmap *)AllocBitMap(data->icld_ViewWidth,
3580 data->icld_ViewHeight,
3581 tmp_RastDepth,
3582 BMF_CLEAR,
3583 data->icld_DisplayRastPort->BitMap)) != NULL)
3585 if ((data->icld_BufferRastPort = CreateRastPort()) != NULL)
3587 data->icld_BufferRastPort->BitMap = bitmap_New;
3588 if (li = NewLayerInfo())
3590 if (data->icld_BufferRastPort->Layer = CreateUpfrontLayer(li, data->icld_BufferRastPort->BitMap, 0, 0, data->icld_ViewWidth - 1, data->icld_ViewHeight - 1, 0, NULL))
3593 * Mark it as a buffered rastport.
3596 #if defined(DEBUG_ILC_ATTRIBS) || defined(DEBUG_ILC_ICONRENDERING)
3597 D(bug("[IconList] %s: FrontRastPort @ %p, New BackLayer @ %p, BackRastport @ %p\n", __PRETTY_FUNCTION__, data->icld_DisplayRastPort, data->icld_BufferRastPort->Layer, data->icld_BufferRastPort));
3598 #endif
3599 SET(obj, MUIA_IconList_BufferRastport, data->icld_BufferRastPort);
3600 data->icld_DrawOffsetX = 0;
3601 data->icld_DrawOffsetY = 0;
3603 else
3604 data->icld_BufferRastPort = data->icld_DisplayRastPort;
3606 else
3607 data->icld_BufferRastPort = data->icld_DisplayRastPort;
3609 else
3610 data->icld_BufferRastPort = data->icld_DisplayRastPort;
3613 if (data->icld_BufferRastPort == data->icld_DisplayRastPort)
3615 if (bitmap_New) FreeBitMap(bitmap_New);
3616 if (li) DisposeLayerInfo(li);
3617 data->icld_DrawOffsetX = _mleft(obj);
3618 data->icld_DrawOffsetY = _mtop(obj);
3623 data->icld_UpdateMode = 0;
3625 if (!data->icld__Option_IconListScaledBackground)
3627 if (!(region = NewRegion()))
3629 #if defined(DEBUG_ILC_ICONRENDERING)
3630 D(bug("[IconList] %s#%d: UPDATE_RESIZE: Causing Redraw -> MADF_DRAWOBJECT..\n", __PRETTY_FUNCTION__, draw_id));
3631 #endif
3632 MUI_Redraw(obj, MADF_DRAWOBJECT);
3633 goto draw_done;
3636 if ( data->icld_ViewWidth > update_oldwidth )
3637 diffw = data->icld_ViewWidth - update_oldwidth;
3638 if ( data->icld_ViewHeight > update_oldheight )
3639 diffh = data->icld_ViewHeight - update_oldheight;
3641 if (diffw)
3643 wrect.MinX = _mright(obj) - diffw;
3644 wrect.MinY = _mtop(obj);
3645 wrect.MaxX = _mright(obj);
3646 wrect.MaxY = _mbottom(obj);
3647 OrRectRegion(region, &wrect);
3648 data->update_rect1 = &wrect;
3651 if (diffh)
3653 hrect.MinX = _mleft(obj);
3654 hrect.MinY = _mbottom(obj) - diffh;
3655 hrect.MaxX = _mright(obj);
3656 hrect.MaxX = _mright(obj);
3657 hrect.MaxY = _mbottom(obj);
3658 OrRectRegion(region, &hrect);
3659 data->update_rect2 = &hrect;
3661 if (diffh||diffw)
3663 clip = MUI_AddClipRegion(muiRenderInfo(obj), region);
3665 else
3667 /* View became smaller both in horizontal and vertical direction.
3668 Nothing to do */
3670 DisposeRegion(region);
3671 goto draw_done;
3675 #if defined(DEBUG_ILC_ICONRENDERING)
3676 D(bug("[IconList] %s#%d: UPDATE_RESIZE: Causing Redraw -> MADF_DRAWOBJECT..\n", __PRETTY_FUNCTION__, draw_id));
3677 #endif
3678 MUI_Redraw(obj, MADF_DRAWOBJECT);
3680 if (!data->icld__Option_IconListScaledBackground)
3682 if (diffh||diffw)
3684 data->update_rect1 = data->update_rect2 = NULL;
3685 MUI_RemoveClipRegion(muiRenderInfo(obj), clip);
3686 } else DisposeRegion(region);
3689 goto draw_done;
3693 if (message->flags & MADF_DRAWOBJECT)
3695 struct Rectangle viewrect;
3696 int current = 0, first = 0, visible = 0;
3698 #if defined(DEBUG_ILC_ICONRENDERING)
3699 D(bug("[IconList] %s#%d: MADF_DRAWOBJECT\n", __PRETTY_FUNCTION__, draw_id));
3700 #endif
3702 if ((data->icld_DisplayFlags & ICONLIST_DISP_MODELIST) == ICONLIST_DISP_MODELIST)
3704 clip = MUI_AddClipping(muiRenderInfo(obj), _mleft(obj), _mtop(obj), _mwidth(obj), data->icld_LVMAttribs->lmva_HeaderHeight);
3705 RenderListViewModeHeader(obj, data);
3707 if (data->icld_DisplayRastPort != data->icld_BufferRastPort)
3709 #if defined(DEBUG_ILC_ICONRENDERING)
3710 D(bug("[IconList] %s#%d: MADF_DRAWOBJECT Blitting Header to front rastport..\n", __PRETTY_FUNCTION__, draw_id));
3711 #endif
3712 BltBitMapRastPort(data->icld_BufferRastPort->BitMap,
3713 0, 0,
3714 data->icld_DisplayRastPort,
3715 _mleft(obj), _mtop(obj), _mwidth(obj), data->icld_LVMAttribs->lmva_HeaderHeight,
3716 0xC0);
3719 MUI_RemoveClipping(muiRenderInfo(obj), clip);
3721 viewrect.MinY = _mtop(obj) + data->icld_LVMAttribs->lmva_HeaderHeight;
3723 first = FirstVisibleLine(data);
3724 visible = NumVisibleLines(data);
3726 clip = MUI_AddClipping(muiRenderInfo(obj), _mleft(obj), _mtop(obj) + data->icld_LVMAttribs->lmva_HeaderHeight, _mwidth(obj), _mheight(obj) - data->icld_LVMAttribs->lmva_HeaderHeight);
3728 else
3730 viewrect.MinY = _mtop(obj);
3731 clip = MUI_AddClipping(muiRenderInfo(obj), _mleft(obj), _mtop(obj), _mwidth(obj), _mheight(obj));
3734 viewrect.MaxY = _mtop(obj) + _mheight(obj) - 1;
3735 viewrect.MinX = _mleft(obj);
3736 viewrect.MaxX = _mleft(obj) + _mwidth(obj) - 1;
3738 #if defined(DEBUG_ILC_ICONRENDERING)
3739 D(bug("[IconList] %s#%d: MADF_DRAWOBJECT: Calling MUIM_DrawBackground (B)\n", __PRETTY_FUNCTION__, draw_id));
3740 #endif
3741 DoMethod(
3742 obj, MUIM_DrawBackground, viewrect.MinX, viewrect.MinY, (viewrect.MaxX - viewrect.MinX) + 1, (viewrect.MaxY - viewrect.MinY) + 1,
3743 clear_xoffset, clear_yoffset, 0
3745 #if defined(__AROS__)
3746 ForeachNode(&data->icld_IconList, entry)
3747 #else
3748 Foreach_Node(&data->icld_IconList, entry);
3749 #endif
3751 if ((data->icld_DisplayFlags & ICONLIST_DISP_MODELIST) == ICONLIST_DISP_MODELIST)
3753 if (entry->ie_Flags & ICONENTRY_FLAG_VISIBLE)
3755 if ((current >= first) && (current <= (first + visible)))
3757 DoMethod(obj, MUIM_IconList_DrawEntry, entry, current);
3759 current++;
3762 else
3764 if ((entry->ie_Flags & ICONENTRY_FLAG_VISIBLE) &&
3765 (entry->ie_DiskObj) &&
3766 (entry->ie_IconX != NO_ICON_POSITION) &&
3767 (entry->ie_IconY != NO_ICON_POSITION))
3769 struct Rectangle iconrect;
3770 IconList_GetIconAreaRectangle(obj, data, entry, &iconrect);
3772 iconrect.MinX += viewrect.MinX - data->icld_ViewX + entry->ie_IconX;
3773 iconrect.MaxX += viewrect.MinX - data->icld_ViewX + entry->ie_IconX;
3774 iconrect.MinY += viewrect.MinY - data->icld_ViewY + entry->ie_IconY;
3775 iconrect.MaxY += viewrect.MinY - data->icld_ViewY + entry->ie_IconY;
3777 if (RectAndRect(&viewrect, &iconrect))
3779 DoMethod(obj, MUIM_IconList_DrawEntry, entry, ICONENTRY_DRAWMODE_PLAIN);
3780 DoMethod(obj, MUIM_IconList_DrawEntryLabel, entry, ICONENTRY_DRAWMODE_PLAIN);
3786 if (data->icld_DisplayRastPort != data->icld_BufferRastPort)
3788 #if defined(DEBUG_ILC_ICONRENDERING)
3789 D(bug("[IconList] %s#%d: MADF_DRAWOBJECT: Blitting to front rastport..\n", __PRETTY_FUNCTION__, draw_id));
3790 #endif
3791 BltBitMapRastPort(data->icld_BufferRastPort->BitMap,
3792 0, 0,
3793 data->icld_DisplayRastPort,
3794 _mleft(obj), _mtop(obj),
3795 _mwidth(obj), _mheight(obj),
3796 0xC0);
3799 MUI_RemoveClipping(muiRenderInfo(obj), clip);
3801 data->icld_UpdateMode = 0;
3803 draw_done:;
3805 #if defined(DEBUG_ILC_ICONRENDERING)
3806 D(bug("[IconList] %s: Draw finished for id %d\n", __PRETTY_FUNCTION__, draw_id));
3807 #endif
3808 return 0;
3812 ///IconList__MUIM_IconList_Update()
3813 /**************************************************************************
3814 MUIM_IconList_Refresh
3815 Implemented by subclasses
3816 **************************************************************************/
3817 IPTR IconList__MUIM_IconList_Update(struct IClass *CLASS, Object *obj, struct MUIP_IconList_Update *message)
3819 struct IconList_DATA *data = INST_DATA(CLASS, obj);
3821 #if defined(DEBUG_ILC_FUNCS)
3822 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
3823 #endif
3825 data->icld_FocusIcon = NULL;
3826 SET(obj, MUIA_IconList_Changed, TRUE);
3828 return 1;
3832 ///MUIM_IconList_Clear()
3833 /**************************************************************************
3834 MUIM_IconList_Clear
3835 **************************************************************************/
3836 IPTR IconList__MUIM_IconList_Clear(struct IClass *CLASS, Object *obj, struct MUIP_IconList_Clear *message)
3838 struct IconList_DATA *data = INST_DATA(CLASS, obj);
3839 struct IconEntry *node = NULL;
3841 #if defined(DEBUG_ILC_FUNCS)
3842 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
3843 #endif
3845 while ((node = (struct IconEntry*)RemTail((struct List*)&data->icld_IconList)))
3847 DoMethod(obj, MUIM_IconList_DestroyEntry, node);
3850 data->icld_SelectionLastClicked = NULL;
3851 data->icld_FocusIcon = NULL;
3853 data->icld_ViewX = data->icld_ViewY = data->icld_AreaWidth = data->icld_AreaHeight = 0;
3855 #if defined(DEBUG_ILC_ICONRENDERING)
3856 D(bug("[IconList]: %s: call SetSuperAttrs()\n", __PRETTY_FUNCTION__));
3857 #endif
3858 SetSuperAttrs(CLASS, obj, MUIA_Virtgroup_Left, data->icld_ViewX,
3859 MUIA_Virtgroup_Top, data->icld_ViewY,
3860 TAG_DONE);
3862 #if defined(DEBUG_ILC_ICONRENDERING)
3863 D(bug("[IconList]: %s: call SetAttrs()\n", __PRETTY_FUNCTION__));
3864 #endif
3865 SetAttrs(obj, MUIA_Virtgroup_Left, data->icld_ViewX,
3866 MUIA_Virtgroup_Top, data->icld_ViewY,
3867 TAG_DONE);
3869 #if defined(DEBUG_ILC_ICONRENDERING)
3870 D(bug("[IconList]: %s: Set MUIA_IconList_Width and MUIA_IconList_Height\n", __PRETTY_FUNCTION__));
3871 #endif
3872 SetAttrs(obj, MUIA_IconList_Width, data->icld_AreaWidth,
3873 MUIA_IconList_Height, data->icld_AreaHeight,
3874 TAG_DONE);
3876 D(bug("[IconList]: %s: call MUI_Redraw()\n", __PRETTY_FUNCTION__));
3877 MUI_Redraw(obj,MADF_DRAWOBJECT);
3878 return 1;
3882 ///IconList__MUIM_IconList_DestroyEntry()
3883 IPTR IconList__MUIM_IconList_DestroyEntry(struct IClass *CLASS, Object *obj, struct MUIP_IconList_DestroyEntry *message)
3885 struct IconList_DATA *data = INST_DATA(CLASS, obj);
3887 #if defined(DEBUG_ILC_FUNCS)
3888 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
3889 #endif
3891 if (message->entry)
3893 if (message->entry->ie_Flags & ICONENTRY_FLAG_SELECTED)
3895 if (data->icld_SelectionLastClicked == message->entry)
3897 struct IconList_Entry *nextentry = &message->entry->ie_IconListEntry;
3899 /* get selected entries from SOURCE iconlist */
3900 DoMethod(obj, MUIM_IconList_NextIcon, MUIV_IconList_NextIcon_Selected, (IPTR)&nextentry);
3901 if ((nextentry) && (nextentry != (IPTR)MUIV_IconList_NextIcon_End))
3902 data->icld_SelectionLastClicked = (struct IconEntry *)((IPTR)nextentry - ((IPTR)&message->entry->ie_IconListEntry - (IPTR)message->entry));
3903 else
3904 data->icld_SelectionLastClicked = NULL;
3906 if (data->icld_FocusIcon == message->entry)
3907 data->icld_FocusIcon = data->icld_SelectionLastClicked;
3909 Remove(&message->entry->ie_SelectionNode);
3912 if (message->entry->ie_TxtBuf_DisplayedLabel)
3913 FreeVecPooled(data->icld_Pool, message->entry->ie_TxtBuf_DisplayedLabel);
3915 if (message->entry->ie_TxtBuf_PROT)
3916 FreePooled(data->icld_Pool, message->entry->ie_TxtBuf_PROT, 8);
3918 if (message->entry->ie_TxtBuf_SIZE)
3919 FreePooled(data->icld_Pool, message->entry->ie_TxtBuf_SIZE, 30);
3921 if (message->entry->ie_TxtBuf_TIME)
3922 FreePooled(data->icld_Pool, message->entry->ie_TxtBuf_TIME, LEN_DATSTRING);
3924 if (message->entry->ie_TxtBuf_DATE)
3925 FreePooled(data->icld_Pool, message->entry->ie_TxtBuf_DATE, LEN_DATSTRING);
3927 if (message->entry->ie_DiskObj)
3928 FreeDiskObject(message->entry->ie_DiskObj);
3930 if (message->entry->ie_FileInfoBlock)
3931 FreeMem(message->entry->ie_FileInfoBlock, sizeof(struct FileInfoBlock));
3933 if (message->entry->ie_IconListEntry.label)
3934 FreePooled(data->icld_Pool, message->entry->ie_IconListEntry.label, strlen(message->entry->ie_IconListEntry.label)+1);
3936 if (message->entry->ie_IconNode.ln_Name)
3937 FreePooled(data->icld_Pool, message->entry->ie_IconNode.ln_Name, strlen(message->entry->ie_IconNode.ln_Name)+1);
3939 FreePooled(data->icld_Pool, message->entry, sizeof(struct IconEntry));
3941 return (IPTR)TRUE;
3945 ///IconList__MUIM_IconList_CreateEntry()
3946 /**************************************************************************
3947 MUIM_IconList_CreateEntry.
3948 Returns 0 on failure otherwise it returns the icons entry ..
3949 **************************************************************************/
3950 IPTR IconList__MUIM_IconList_CreateEntry(struct IClass *CLASS, Object *obj, struct MUIP_IconList_CreateEntry *message)
3952 struct IconList_DATA *data = INST_DATA(CLASS, obj);
3953 struct IconEntry *entry = NULL;
3954 struct DateTime dt;
3955 struct DateStamp now;
3956 UBYTE *sp = NULL;
3958 struct DiskObject *dob = NULL;
3959 struct Rectangle rect;
3961 IPTR geticon_error = 0;
3963 #if defined(DEBUG_ILC_FUNCS)
3964 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
3965 #endif
3967 /*disk object (icon)*/
3968 if (message->entry_dob == NULL)
3970 IPTR iconlistScreen = _screen(obj);
3971 D(bug("[IconList] %s: IconList Screen @ 0x%p)\n", __PRETTY_FUNCTION__, iconlistScreen));
3973 dob = GetIconTags
3975 message->filename,
3976 (iconlistScreen) ? ICONGETA_Screen : TAG_IGNORE, iconlistScreen,
3977 (iconlistScreen) ? ICONGETA_RemapIcon : TAG_IGNORE, TRUE,
3978 ICONGETA_FailIfUnavailable, FALSE,
3979 ICONGETA_GenerateImageMasks, TRUE,
3980 ICONA_ErrorCode, &geticon_error,
3981 TAG_DONE
3984 if (dob == NULL)
3986 D(bug("[IconList] %s: Fatal: Couldnt get DiskObject! (error code = 0x%p)\n", __PRETTY_FUNCTION__, geticon_error));
3988 return (IPTR)NULL;
3991 else
3993 dob = message->entry_dob;
3996 D(bug("[IconList] %s: DiskObject @ 0x%p\n", __PRETTY_FUNCTION__, dob));
3998 if ((entry = AllocPooled(data->icld_Pool, sizeof(struct IconEntry))) == NULL)
4000 D(bug("[IconList] %s: Failed to Allocate Entry Storage!\n", __PRETTY_FUNCTION__));
4001 FreeDiskObject(dob);
4002 return (IPTR)NULL;
4004 memset(entry, 0, sizeof(struct IconEntry));
4005 entry->ie_Flags |= ICONENTRY_FLAG_NEEDSUPDATE;
4006 entry->ie_IconListEntry.ile_IconEntry = entry;
4008 /* Allocate Text Buffers */
4010 if ((entry->ie_TxtBuf_DATE = AllocPooled(data->icld_Pool, LEN_DATSTRING)) == NULL)
4012 D(bug("[IconList] %s: Failed to Allocate Entry DATE Storage!\n", __PRETTY_FUNCTION__));
4013 DoMethod(obj, MUIM_IconList_DestroyEntry, entry);
4014 return (IPTR)NULL;
4016 memset(entry->ie_TxtBuf_DATE, 0, LEN_DATSTRING);
4018 if ((entry->ie_TxtBuf_TIME = AllocPooled(data->icld_Pool, LEN_DATSTRING)) == NULL)
4020 D(bug("[IconList] %s: Failed to Allocate Entry TIME string Storage!\n", __PRETTY_FUNCTION__));
4021 DoMethod(obj, MUIM_IconList_DestroyEntry, entry);
4022 return (IPTR)NULL;
4024 memset(entry->ie_TxtBuf_TIME, 0, LEN_DATSTRING);
4026 if ((entry->ie_TxtBuf_SIZE = AllocPooled(data->icld_Pool, 30)) == NULL)
4028 D(bug("[IconList] %s: Failed to Allocate Entry SIZE string Storage!\n", __PRETTY_FUNCTION__));
4029 DoMethod(obj, MUIM_IconList_DestroyEntry, entry);
4030 return (IPTR)NULL;
4032 memset(entry->ie_TxtBuf_SIZE, 0, 30);
4034 if ((entry->ie_TxtBuf_PROT = AllocPooled(data->icld_Pool, 8)) == NULL)
4036 D(bug("[IconList] %s: Failed to Allocate Entry PROT Flag string Storage!\n", __PRETTY_FUNCTION__));
4037 DoMethod(obj, MUIM_IconList_DestroyEntry, entry);
4038 return (IPTR)NULL;
4040 memset(entry->ie_TxtBuf_PROT, 0, 8);
4042 /*alloc filename*/
4043 if ((entry->ie_IconNode.ln_Name = AllocPooled(data->icld_Pool, strlen(message->filename) + 1)) == NULL)
4045 D(bug("[IconList] %s: Failed to Allocate Entry filename string Storage!\n", __PRETTY_FUNCTION__));
4046 DoMethod(obj, MUIM_IconList_DestroyEntry, entry);
4047 return (IPTR)NULL;
4050 /*alloc entry label*/
4051 if ((entry->ie_IconListEntry.label = AllocPooled(data->icld_Pool, strlen(message->label) + 1)) == NULL)
4053 D(bug("[IconList] %s: Failed to Allocate Entry label string Storage!\n", __PRETTY_FUNCTION__));
4054 DoMethod(obj, MUIM_IconList_DestroyEntry, entry);
4055 return (IPTR)NULL;
4058 /*file info block*/
4059 if(message->fib != NULL)
4061 if ((entry->ie_FileInfoBlock = AllocMem(sizeof(struct FileInfoBlock), MEMF_CLEAR)) != NULL)
4063 CopyMem(message->fib, entry->ie_FileInfoBlock, sizeof(struct FileInfoBlock));
4065 if (entry->ie_FileInfoBlock->fib_DirEntryType > 0)
4067 strcpy(entry->ie_TxtBuf_SIZE, "Drawer");
4069 else
4071 FmtSizeToString(entry->ie_TxtBuf_SIZE, entry->ie_FileInfoBlock->fib_Size);
4074 dt.dat_Stamp = entry->ie_FileInfoBlock->fib_Date;
4075 dt.dat_Format = FORMAT_DEF;
4076 dt.dat_Flags = 0;
4077 dt.dat_StrDay = NULL;
4078 dt.dat_StrDate = entry->ie_TxtBuf_DATE;
4079 dt.dat_StrTime = entry->ie_TxtBuf_TIME;
4081 DateToStr(&dt);
4082 DateStamp(&now);
4084 /*if modified today show time, otherwise just show date*/
4085 if (now.ds_Days == entry->ie_FileInfoBlock->fib_Date.ds_Days)
4086 entry->ie_Flags |= ICONENTRY_FLAG_TODAY;
4087 else
4088 entry->ie_Flags &= ~ICONENTRY_FLAG_TODAY;
4090 sp = entry->ie_TxtBuf_PROT;
4091 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_SCRIPT) ? 's' : '-';
4092 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_PURE) ? 'p' : '-';
4093 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_ARCHIVE) ? 'a' : '-';
4094 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_READ) ? '-' : 'r';
4095 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_WRITE) ? '-' : 'w';
4096 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_EXECUTE) ? '-' : 'e';
4097 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_DELETE) ? '-' : 'd';
4098 *sp++ = '\0';
4100 entry->ie_IconListEntry.type = entry->ie_FileInfoBlock->fib_DirEntryType;
4103 else
4105 entry->ie_IconListEntry.type = ST_USERDIR;
4108 /* Override type if specified during createntry */
4109 if (message->type != 0)
4111 entry->ie_IconListEntry.type = message->type;
4112 D(bug("[IconList] %s: Overide Entry Type. New Type = %x\n", __PRETTY_FUNCTION__, entry->ie_IconListEntry.type));
4114 else
4116 D(bug("[IconList] %s: Entry Type = %x\n", __PRETTY_FUNCTION__, entry->ie_IconListEntry.type));
4119 strcpy(entry->ie_IconNode.ln_Name, message->filename);
4120 strcpy(entry->ie_IconListEntry.label, message->label);
4122 entry->ie_IconListEntry.udata = NULL;
4124 if (IconList__LabelFunc_CreateLabel(obj, data, entry) != (IPTR)NULL)
4126 entry->ie_DiskObj = dob;
4128 /* Use a geticonrectangle routine that gets textwidth! */
4129 IconList_GetIconAreaRectangle(obj, data, entry, &rect);
4131 return (IPTR)entry;
4134 DoMethod(obj, MUIM_IconList_DestroyEntry, entry);
4135 return (IPTR)NULL;
4139 ///IconList__MUIM_IconList_UpdateEntry()
4140 /**************************************************************************
4141 MUIM_IconList_UpdateEntry.
4142 Returns 0 on failure otherwise it returns the icons entry ..
4143 **************************************************************************/
4144 IPTR IconList__MUIM_IconList_UpdateEntry(struct IClass *CLASS, Object *obj, struct MUIP_IconList_UpdateEntry *message)
4146 struct IconList_DATA *data = INST_DATA(CLASS, obj);
4147 struct DateTime dt;
4148 struct DateStamp now;
4149 UBYTE *sp = NULL;
4151 struct DiskObject *dob = NULL;
4152 struct Rectangle rect;
4154 IPTR geticon_error = 0;
4156 #if defined(DEBUG_ILC_FUNCS)
4157 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
4158 #endif
4160 /* Update disk object (icon)*/
4161 /* if (message->entry_dob == NULL)
4163 IPTR iconlistScreen = _screen(obj);
4164 D(bug("[IconList] %s: IconList Screen @ 0x%p)\n", __PRETTY_FUNCTION__, iconlistScreen));
4166 dob = GetIconTags
4168 message->filename,
4169 (iconlistScreen) ? ICONGETA_Screen : TAG_IGNORE, iconlistScreen,
4170 (iconlistScreen) ? ICONGETA_RemapIcon : TAG_IGNORE, TRUE,
4171 ICONGETA_FailIfUnavailable, FALSE,
4172 ICONGETA_GenerateImageMasks, TRUE,
4173 ICONA_ErrorCode, &geticon_error,
4174 TAG_DONE
4177 if (dob == NULL)
4179 D(bug("[IconList] %s: Fatal: Couldnt get DiskObject! (error code = 0x%p)\n", __PRETTY_FUNCTION__, geticon_error));
4181 return (IPTR)NULL;
4184 else
4186 dob = message->entry_dob;
4189 D(bug("[IconList] %s: DiskObject @ 0x%p\n", __PRETTY_FUNCTION__, dob));
4192 /* Update filename */
4193 if (strcmp(message->entry->ie_IconNode.ln_Name, message->filename) != 0)
4195 message->entry->ie_Flags |= ICONENTRY_FLAG_NEEDSUPDATE;
4196 FreePooled(data->icld_Pool, message->entry->ie_IconNode.ln_Name, strlen(message->entry->ie_IconNode.ln_Name) + 1);
4197 if ((message->entry->ie_IconNode.ln_Name = AllocPooled(data->icld_Pool, strlen(message->filename) + 1)) == NULL)
4199 D(bug("[IconList] %s: Failed to Allocate Entry filename string Storage!\n", __PRETTY_FUNCTION__));
4200 DoMethod(obj, MUIM_IconList_DestroyEntry, message->entry);
4201 return (IPTR)NULL;
4203 strcpy(message->entry->ie_IconNode.ln_Name, message->filename);
4206 /* Update entry label */
4207 if (strcmp(message->entry->ie_IconListEntry.label, message->label) != 0)
4209 message->entry->ie_Flags |= ICONENTRY_FLAG_NEEDSUPDATE;
4210 FreePooled(data->icld_Pool, message->entry->ie_IconListEntry.label, strlen(message->entry->ie_IconListEntry.label) + 1);
4211 if ((message->entry->ie_IconListEntry.label = AllocPooled(data->icld_Pool, strlen(message->label) + 1)) == NULL)
4213 D(bug("[IconList] %s: Failed to Allocate Entry label string Storage!\n", __PRETTY_FUNCTION__));
4214 DoMethod(obj, MUIM_IconList_DestroyEntry, message->entry);
4215 return (IPTR)NULL;
4217 strcpy(message->entry->ie_IconListEntry.label, message->label);
4218 if (IconList__LabelFunc_CreateLabel(obj, data, message->entry) == (IPTR)NULL)
4220 D(bug("[IconList] %s: Failed to create label\n", __PRETTY_FUNCTION__));
4221 DoMethod(obj, MUIM_IconList_DestroyEntry, message->entry);
4222 return (IPTR)NULL;
4226 /* Update file info block */
4227 if(message->fib != NULL)
4229 if (!(message->entry->ie_FileInfoBlock))
4231 if ((message->entry->ie_FileInfoBlock = AllocMem(sizeof(struct FileInfoBlock), MEMF_CLEAR)) != NULL)
4233 CopyMem(message->fib, message->entry->ie_FileInfoBlock, sizeof(struct FileInfoBlock));
4237 /* if (entry->ie_FileInfoBlock->fib_DirEntryType > 0)
4239 strcpy(entry->ie_TxtBuf_SIZE, "Drawer");
4241 else
4243 FmtSizeToString(entry->ie_TxtBuf_SIZE, entry->ie_FileInfoBlock->fib_Size);
4246 dt.dat_Stamp = entry->ie_FileInfoBlock->fib_Date;
4247 dt.dat_Format = FORMAT_DEF;
4248 dt.dat_Flags = 0;
4249 dt.dat_StrDay = NULL;
4250 dt.dat_StrDate = entry->ie_TxtBuf_DATE;
4251 dt.dat_StrTime = entry->ie_TxtBuf_TIME;
4253 DateToStr(&dt);
4254 DateStamp(&now);
4256 //if modified today show time, otherwise just show date
4257 if (now.ds_Days == entry->ie_FileInfoBlock->fib_Date.ds_Days)
4258 entry->ie_Flags |= ICONENTRY_FLAG_TODAY;
4259 else
4260 entry->ie_Flags &= ~ICONENTRY_FLAG_TODAY;
4262 sp = entry->ie_TxtBuf_PROT;
4263 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_SCRIPT) ? 's' : '-';
4264 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_PURE) ? 'p' : '-';
4265 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_ARCHIVE) ? 'a' : '-';
4266 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_READ) ? '-' : 'r';
4267 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_WRITE) ? '-' : 'w';
4268 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_EXECUTE) ? '-' : 'e';
4269 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_DELETE) ? '-' : 'd';
4270 *sp++ = '\0';
4272 entry->ie_IconListEntry.type = entry->ie_FileInfoBlock->fib_DirEntryType;
4275 else
4277 if (message->entry->ie_FileInfoBlock)
4278 FreeMem(message->entry->ie_FileInfoBlock, sizeof(struct FileInfoBlock));
4280 if (message->entry->ie_IconListEntry.type != ST_USERDIR)
4282 message->entry->ie_Flags |= ICONENTRY_FLAG_NEEDSUPDATE;
4283 message->entry->ie_IconListEntry.type = ST_USERDIR;
4287 /* Override type if specified */
4288 if ((message->type != 0) && (message->entry->ie_IconListEntry.type != message->type))
4290 message->entry->ie_Flags |= ICONENTRY_FLAG_NEEDSUPDATE;
4291 message->entry->ie_IconListEntry.type = message->type;
4292 D(bug("[IconList] %s: Overide Entry Type. New Type = %x\n", __PRETTY_FUNCTION__, message->entry->ie_IconListEntry.type));
4294 else
4296 D(bug("[IconList] %s: Entry Type = %x\n", __PRETTY_FUNCTION__, message->entry->ie_IconListEntry.type));
4299 IconList_GetIconAreaRectangle(obj, data, message->entry, &rect);
4301 return (IPTR)message->entry;
4305 ///DoWheelMove()
4306 static void DoWheelMove(struct IClass *CLASS, Object *obj, LONG wheelx, LONG wheely, UWORD qual)
4308 struct IconList_DATA *data = INST_DATA(CLASS, obj);
4310 LONG newleft = data->icld_ViewX,
4311 newtop = data->icld_ViewY;
4313 /* Use horizontal scrolling if any of the following cases are true ...
4315 # vertical wheel is used but there's nothing to scroll
4316 (everything is visible already) ..
4318 # vertical wheel is used and one of the ALT keys is down. */
4320 if ((wheely && !wheelx) &&
4321 ((data->icld_AreaHeight <= _mheight(obj)) || (qual & (IEQUALIFIER_LALT | IEQUALIFIER_RALT))))
4323 wheelx = wheely; wheely = 0;
4326 if (qual & (IEQUALIFIER_CONTROL))
4328 if (wheelx < 0) newleft = 0;
4329 if (wheelx > 0) newleft = data->icld_AreaWidth;
4330 if (wheely < 0) newtop = 0;
4331 if (wheely > 0) newtop = data->icld_AreaHeight;
4333 else if (qual & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
4335 newleft += (wheelx * _mwidth(obj));
4336 newtop += (wheely * _mheight(obj));
4338 else
4340 newleft += wheelx * 30;
4341 newtop += wheely * 30;
4344 if (newleft + _mwidth(obj) > data->icld_AreaWidth)
4345 newleft = data->icld_AreaWidth - _mwidth(obj);
4346 if (newleft < 0)
4347 newleft = 0;
4349 if (newtop + _mheight(obj) > data->icld_AreaHeight)
4350 newtop = data->icld_AreaHeight - _mheight(obj);
4351 if (newtop < 0)
4352 newtop = 0;
4354 if ((newleft != data->icld_ViewX) || (newtop != data->icld_ViewY))
4356 SetAttrs(obj, MUIA_Virtgroup_Left, newleft,
4357 MUIA_Virtgroup_Top, newtop,
4358 TAG_DONE);
4363 ///MUIM_HandleEvent()
4364 /**************************************************************************
4365 MUIM_HandleEvent
4366 **************************************************************************/
4367 IPTR IconList__MUIM_HandleEvent(struct IClass *CLASS, Object *obj, struct MUIP_HandleEvent *message)
4369 struct IconList_DATA *data = INST_DATA(CLASS, obj);
4371 #if defined(DEBUG_ILC_FUNCS)
4372 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
4373 #endif
4375 if (message->imsg)
4377 LONG mx = message->imsg->MouseX - _mleft(obj);
4378 LONG my = message->imsg->MouseY - _mtop(obj);
4380 LONG wheelx = 0;
4381 LONG wheely = 0;
4383 switch (message->imsg->Class)
4385 case IDCMP_NEWSIZE:
4386 bug("[IconList] %s: IDCMP_NEWSIZE\n", __PRETTY_FUNCTION__);
4387 break;
4389 case IDCMP_RAWKEY:
4391 #if defined(DEBUG_ILC_EVENTS)
4392 D(bug("[IconList] %s: IDCMP_RAWKEY\n", __PRETTY_FUNCTION__));
4393 #endif
4394 BOOL rawkey_handled = FALSE;
4396 switch(message->imsg->Code)
4398 case RAWKEY_NM_WHEEL_UP:
4399 wheely = -1;
4400 rawkey_handled = TRUE;
4401 break;
4403 case RAWKEY_NM_WHEEL_DOWN:
4404 wheely = 1;
4405 rawkey_handled = TRUE;
4406 break;
4408 case RAWKEY_NM_WHEEL_LEFT:
4409 wheelx = -1;
4410 rawkey_handled = TRUE;
4411 break;
4413 case RAWKEY_NM_WHEEL_RIGHT:
4414 wheelx = 1;
4415 rawkey_handled = TRUE;
4416 break;
4419 if (rawkey_handled)
4421 #if defined(DEBUG_ILC_KEYEVENTS)
4422 D(bug("[IconList] %s: Processing mouse wheel event\n", __PRETTY_FUNCTION__));
4423 #endif
4424 if (_isinobject(message->imsg->MouseX, message->imsg->MouseY) &&
4425 (wheelx || wheely))
4427 DoWheelMove(CLASS, obj, wheelx, wheely, message->imsg->Qualifier);
4430 else if (!(message->imsg->Code & IECODE_UP_PREFIX))
4432 LONG new_ViewY = data->icld_ViewY;
4433 struct IconEntry *start_entry = NULL, *active_entry = NULL, *entry_next = NULL;
4434 IPTR start_X = 0, start_Y = 0, active_X = 0, active_Y = 0, next_X = 0, next_Y = 0;
4435 IPTR x_diff = 0;
4437 #if defined(DEBUG_ILC_KEYEVENTS)
4438 D(bug("[IconList] %s: Processing key up event\n", __PRETTY_FUNCTION__));
4439 #endif
4441 switch(message->imsg->Code)
4443 case RAWKEY_RETURN:
4444 rawkey_handled = TRUE;
4446 #if defined(DEBUG_ILC_KEYEVENTS)
4447 D(bug("[IconList] %s: RAWKEY_RETURN\n", __PRETTY_FUNCTION__));
4448 #endif
4450 if (data->icld_FocusIcon) active_entry = data->icld_FocusIcon;
4451 else if (data->icld_SelectionLastClicked) active_entry = data->icld_SelectionLastClicked;
4453 if (active_entry)
4455 if (!(active_entry->ie_Flags & ICONENTRY_FLAG_SELECTED))
4457 active_entry->ie_Flags |= ICONENTRY_FLAG_SELECTED;
4458 AddTail(&data->icld_SelectionList, &active_entry->ie_SelectionNode);
4459 data->icld_UpdateMode = UPDATE_SINGLEENTRY;
4460 data->update_entry = active_entry;
4461 MUI_Redraw(obj, MADF_DRAWUPDATE);
4463 data->icld_SelectionLastClicked = active_entry;
4464 data->icld_FocusIcon = active_entry;
4466 SET(obj, MUIA_IconList_DoubleClick, TRUE);
4468 break;
4470 case RAWKEY_SPACE:
4471 rawkey_handled = TRUE;
4473 #if defined(DEBUG_ILC_KEYEVENTS)
4474 D(bug("[IconList] %s: RAWKEY_SPACE\n", __PRETTY_FUNCTION__));
4475 #endif
4477 if (data->icld_FocusIcon) active_entry = data->icld_FocusIcon;
4478 else if (data->icld_SelectionLastClicked) active_entry = data->icld_SelectionLastClicked;
4480 if (!(message->imsg->Qualifier & IEQUALIFIER_LSHIFT) && ((data->icld_SelectionLastClicked)||(data->icld_SelectionLastClicked != active_entry)))
4482 #if defined(DEBUG_ILC_KEYEVENTS)
4483 D(bug("[IconList] %s: SPACE: Clearing selected icons ..\n", __PRETTY_FUNCTION__));
4484 #endif
4485 DoMethod(obj, MUIM_IconList_UnselectAll);
4488 if (active_entry)
4490 if (!(active_entry->ie_Flags & ICONENTRY_FLAG_SELECTED))
4492 AddTail(&data->icld_SelectionList, &active_entry->ie_SelectionNode);
4493 active_entry->ie_Flags |= ICONENTRY_FLAG_SELECTED;
4494 data->icld_SelectionLastClicked = active_entry;
4496 else
4498 Remove(&active_entry->ie_SelectionNode);
4499 active_entry->ie_Flags &= ~ICONENTRY_FLAG_SELECTED;
4502 data->icld_FocusIcon = active_entry;
4504 data->icld_UpdateMode = UPDATE_SINGLEENTRY;
4505 data->update_entry = active_entry;
4506 MUI_Redraw(obj, MADF_DRAWUPDATE);
4508 break;
4510 case RAWKEY_PAGEUP:
4511 rawkey_handled = TRUE;
4513 #if defined(DEBUG_ILC_KEYEVENTS)
4514 D(bug("[IconList] %s: RAWKEY_PAGEUP\n", __PRETTY_FUNCTION__));
4515 #endif
4517 if (data->icld_AreaHeight > data->icld_ViewHeight)
4519 new_ViewY -= data->icld_ViewHeight;
4520 if (new_ViewY< 0)
4521 new_ViewY = 0;
4524 if (new_ViewY != data->icld_ViewY)
4526 SET(obj, MUIA_Virtgroup_Top, new_ViewY);
4528 break;
4530 case RAWKEY_PAGEDOWN:
4531 rawkey_handled = TRUE;
4533 #if defined(DEBUG_ILC_KEYEVENTS)
4534 D(bug("[IconList] %s: RAWKEY_PAGEDOWN\n", __PRETTY_FUNCTION__));
4535 #endif
4537 if (data->icld_AreaHeight > data->icld_ViewHeight)
4539 new_ViewY += data->icld_ViewHeight;
4540 if (new_ViewY > (data->icld_AreaHeight - data->icld_ViewHeight))
4541 new_ViewY = data->icld_AreaHeight - data->icld_ViewHeight;
4544 if (new_ViewY != data->icld_ViewY)
4546 SET(obj, MUIA_Virtgroup_Top, new_ViewY);
4548 break;
4550 case RAWKEY_UP:
4551 rawkey_handled = TRUE;
4553 #if defined(DEBUG_ILC_KEYEVENTS)
4554 D(bug("[IconList] %s: RAWKEY_UP\n", __PRETTY_FUNCTION__));
4555 #endif
4557 if (data->icld_FocusIcon)
4559 start_entry = data->icld_FocusIcon;
4560 #if defined(DEBUG_ILC_KEYEVENTS)
4561 D(bug("[IconList] %s: UP: Clearing existing focused entry @ 0x%p\n", __PRETTY_FUNCTION__, start_entry));
4562 #endif
4564 start_entry->ie_Flags &= ~ICONENTRY_FLAG_FOCUS;
4565 data->icld_UpdateMode = UPDATE_SINGLEENTRY;
4566 data->update_entry = start_entry;
4567 MUI_Redraw(obj, MADF_DRAWUPDATE);
4569 start_X = start_entry->ie_IconX;
4570 start_Y = start_entry->ie_IconY;
4571 #if defined(DEBUG_ILC_KEYEVENTS)
4572 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));
4573 #endif
4574 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
4576 if (start_entry->ie_AreaWidth < data->icld_IconAreaLargestWidth)
4578 start_X = start_X - ((data->icld_IconAreaLargestWidth - start_entry->ie_AreaWidth)/2);
4579 #if defined(DEBUG_ILC_KEYEVENTS)
4580 D(bug("[IconList] %s: UP: adjusted start_X for grid = %d\n", __PRETTY_FUNCTION__, start_X));
4581 #endif
4585 if ((active_entry = Node_PreviousVisible(start_entry)) && !(data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL))
4587 //Check if we are at the edge of the entry area ..
4588 #if defined(DEBUG_ILC_KEYEVENTS)
4589 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));
4590 #endif
4591 active_Y = active_entry->ie_IconY;
4593 if (active_Y == start_Y)
4596 #if defined(DEBUG_ILC_KEYEVENTS)
4597 D(bug("[IconList] %s: UP: active_entry is on our row (not at the edge)\n", __PRETTY_FUNCTION__));
4598 #endif
4599 entry_next = active_entry;
4600 next_X = entry_next->ie_IconX;
4601 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
4603 if (entry_next->ie_AreaWidth < data->icld_IconAreaLargestWidth)
4604 next_X = next_X - ((data->icld_IconAreaLargestWidth - entry_next->ie_AreaWidth)/2);
4608 #if defined(DEBUG_ILC_KEYEVENTS)
4609 D(bug("[IconList] %s: UP: using start_X %d, start_Y %d\n", __PRETTY_FUNCTION__, start_X, start_Y));
4610 #endif
4613 if (!(message->imsg->Qualifier & IEQUALIFIER_LSHIFT) && ((data->icld_SelectionLastClicked)&&(data->icld_SelectionLastClicked != active_entry)))
4615 #if defined(DEBUG_ILC_KEYEVENTS)
4616 D(bug("[IconList] %s: UP: Clearing selected icons ..\n", __PRETTY_FUNCTION__));
4617 #endif
4618 DoMethod(obj, MUIM_IconList_UnselectAll);
4621 #if defined(DEBUG_ILC_KEYEVENTS)
4622 D(bug("[IconList] %s: UP: active = 0x%p, next = 0x%p\n", __PRETTY_FUNCTION__, active_entry, entry_next));
4623 #endif
4624 if (!(active_entry))
4626 // If nothing is selected we will use the last visible entry ..
4627 active_entry = Node_LastVisible(&data->icld_IconList);
4628 start_X = active_entry->ie_IconX;
4629 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
4631 if (active_entry->ie_AreaWidth < data->icld_IconAreaLargestWidth)
4632 start_X = start_X - ((data->icld_IconAreaLargestWidth - active_entry->ie_AreaWidth)/2);
4634 start_Y = active_entry->ie_IconY;
4637 while (active_entry != NULL)
4639 #if defined(DEBUG_ILC_KEYEVENTS)
4640 D(bug("[IconList] %s: UP: Checking active @ 0x%p\n", __PRETTY_FUNCTION__, active_entry));
4641 #endif
4642 if (data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL)
4644 // Return the first visible since the list flow direction matches
4645 // our cursor direction
4646 if (active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE)
4647 break;
4649 else
4651 active_X = active_entry->ie_IconX;
4653 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
4655 if (active_entry->ie_AreaWidth < data->icld_IconAreaLargestWidth)
4656 x_diff = ((data->icld_IconAreaLargestWidth - active_entry->ie_AreaWidth)/2);
4658 active_Y = active_entry->ie_IconY;
4660 if (start_entry)
4662 if (entry_next)
4664 if ((active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE) &&
4665 (active_Y < start_Y) &&
4666 (((active_X - x_diff) >= start_X ) &&
4667 ((active_X - x_diff) <= (start_X + start_entry->ie_AreaWidth + (x_diff*2)))))
4669 #if defined(DEBUG_ILC_KEYEVENTS)
4670 D(bug("[IconList] %s: UP: (A) entry 0x%p matches\n", __PRETTY_FUNCTION__, active_entry));
4671 #endif
4672 break;
4674 else if (active_entry == (struct IconEntry *)GetHead(&data->icld_IconList))
4676 #if defined(DEBUG_ILC_KEYEVENTS)
4677 D(bug("[IconList] %s: UP: (A) reached list start .. restarting from the end ..\n", __PRETTY_FUNCTION__));
4678 #endif
4679 start_X = next_X;
4681 if ((entry_next = Node_PreviousVisible(entry_next)))
4683 if (entry_next->ie_IconX > start_X)
4684 entry_next = NULL;
4685 else
4687 next_X = entry_next->ie_IconX;
4688 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
4690 if (entry_next->ie_AreaWidth < data->icld_IconAreaLargestWidth)
4691 next_X = next_X - ((data->icld_IconAreaLargestWidth - entry_next->ie_AreaWidth)/2);
4695 start_Y = 0;
4696 #if defined(DEBUG_ILC_KEYEVENTS)
4697 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));
4698 #endif
4699 active_entry = Node_LastVisible(&data->icld_IconList);
4702 else
4704 if ((active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE) &&
4705 (active_Y < start_Y) &&
4706 ((active_X + x_diff) < (start_X + start_entry->ie_AreaWidth + x_diff)))
4708 #if defined(DEBUG_ILC_KEYEVENTS)
4709 D(bug("[IconList] %s: UP: (B) entry 0x%p matches\n", __PRETTY_FUNCTION__, active_entry));
4710 #endif
4711 break;
4715 else
4717 if (active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE)
4719 #if defined(DEBUG_ILC_KEYEVENTS)
4720 D(bug("[IconList] %s: UP: (C) entry 0x%p matches\n", __PRETTY_FUNCTION__, active_entry));
4721 #endif
4722 break;
4726 active_entry = (struct IconEntry *)(((struct Node *)active_entry)->ln_Pred);
4729 if (!(active_entry))
4731 #if defined(DEBUG_ILC_KEYEVENTS)
4732 D(bug("[IconList] %s: UP: No Next UP Node - Getting Last visible entry ..\n", __PRETTY_FUNCTION__));
4733 #endif
4734 /* We didnt find a "next UP" entry so just use the last visible */
4735 active_entry = Node_LastVisible(&data->icld_IconList);
4738 if (active_entry)
4740 if (!(active_entry->ie_Flags & ICONENTRY_FLAG_FOCUS))
4742 active_entry->ie_Flags |= ICONENTRY_FLAG_FOCUS;
4743 data->icld_UpdateMode = UPDATE_SINGLEENTRY;
4744 data->update_entry = active_entry;
4745 MUI_Redraw(obj, MADF_DRAWUPDATE);
4748 data->icld_FocusIcon = active_entry;
4749 break;
4751 case RAWKEY_DOWN:
4752 rawkey_handled = TRUE;
4754 #if defined(DEBUG_ILC_KEYEVENTS)
4755 D(bug("[IconList] %s: RAWKEY_DOWN\n", __PRETTY_FUNCTION__));
4756 #endif
4757 if (data->icld_FocusIcon)
4759 start_entry = data->icld_FocusIcon;
4760 #if defined(DEBUG_ILC_KEYEVENTS)
4761 D(bug("[IconList] %s: DOWN: Clearing existing focused entry @ 0x%p\n", __PRETTY_FUNCTION__, start_entry));
4762 #endif
4764 start_entry->ie_Flags &= ~ICONENTRY_FLAG_FOCUS;
4765 data->icld_UpdateMode = UPDATE_SINGLEENTRY;
4766 data->update_entry = start_entry;
4767 MUI_Redraw(obj, MADF_DRAWUPDATE);
4769 start_X = start_entry->ie_IconX;
4770 start_Y = start_entry->ie_IconY;
4771 #if defined(DEBUG_ILC_KEYEVENTS)
4772 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));
4773 #endif
4774 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
4776 if (start_entry->ie_AreaWidth < data->icld_IconAreaLargestWidth)
4778 start_X = start_X - ((data->icld_IconAreaLargestWidth - start_entry->ie_AreaWidth)/2);
4779 #if defined(DEBUG_ILC_KEYEVENTS)
4780 D(bug("[IconList] %s: DOWN: adjusted start_X for grid = %d\n", __PRETTY_FUNCTION__, start_X));
4781 #endif
4785 if ((active_entry = Node_NextVisible(start_entry)) &&
4786 (!(data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL)))
4788 #if defined(DEBUG_ILC_KEYEVENTS)
4789 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));
4790 #endif
4791 active_Y = active_entry->ie_IconY;
4793 if (active_Y == start_Y)
4796 #if defined(DEBUG_ILC_KEYEVENTS)
4797 D(bug("[IconList] %s: DOWN: active_entry is on our row (not at the edge)\n", __PRETTY_FUNCTION__));
4798 #endif
4799 entry_next = active_entry;
4800 next_X = entry_next->ie_IconX;
4801 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
4803 if (entry_next->ie_AreaWidth < data->icld_IconAreaLargestWidth)
4804 next_X = next_X - ((data->icld_IconAreaLargestWidth - entry_next->ie_AreaWidth)/2);
4808 #if defined(DEBUG_ILC_KEYEVENTS)
4809 D(bug("[IconList] %s: DOWN: using start_X %d, start_Y %d\n", __PRETTY_FUNCTION__, start_X, start_Y));
4810 #endif
4813 if (!(message->imsg->Qualifier & IEQUALIFIER_LSHIFT) && ((data->icld_SelectionLastClicked)&&(data->icld_SelectionLastClicked != active_entry)))
4815 #if defined(DEBUG_ILC_KEYEVENTS)
4816 D(bug("[IconList] %s: DOWN: Clearing selected icons ..\n", __PRETTY_FUNCTION__));
4817 #endif
4818 DoMethod(obj, MUIM_IconList_UnselectAll);
4821 #if defined(DEBUG_ILC_KEYEVENTS)
4822 D(bug("[IconList] %s: DOWN: active = 0x%p, next = 0x%p\n", __PRETTY_FUNCTION__, active_entry, entry_next));
4823 #endif
4824 if (!(active_entry))
4826 // If nothing is selected we will use the First visible entry ..
4827 active_entry = Node_FirstVisible(&data->icld_IconList);
4828 start_X = active_entry->ie_IconX;
4829 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
4831 if (active_entry->ie_AreaWidth < data->icld_IconAreaLargestWidth)
4832 start_X = start_X - ((data->icld_IconAreaLargestWidth - active_entry->ie_AreaWidth)/2);
4834 start_Y = active_entry->ie_IconY;
4837 while (active_entry != NULL)
4839 #if defined(DEBUG_ILC_KEYEVENTS)
4840 D(bug("[IconList] %s: DOWN: Checking active @ 0x%p\n", __PRETTY_FUNCTION__, active_entry));
4841 #endif
4842 if (data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL)
4844 if (active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE)
4845 break;
4847 else
4849 active_X = active_entry->ie_IconX;
4851 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
4853 if (active_entry->ie_AreaWidth < data->icld_IconAreaLargestWidth)
4854 x_diff = ((data->icld_IconAreaLargestWidth - active_entry->ie_AreaWidth)/2);
4856 active_Y = active_entry->ie_IconY;
4858 if (start_entry)
4860 if (entry_next)
4862 if ((active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE) &&
4863 (active_Y > start_Y) &&
4864 (((active_X - x_diff) >= start_X ) &&
4865 ((active_X - x_diff) <= (start_X + start_entry->ie_AreaWidth + (x_diff*2)))))
4867 #if defined(DEBUG_ILC_KEYEVENTS)
4868 D(bug("[IconList] %s: DOWN: (A) entry 0x%p matches\n", __PRETTY_FUNCTION__, active_entry));
4869 #endif
4870 break;
4872 else if (active_entry == (struct IconEntry *)GetTail(&data->icld_IconList))
4874 #if defined(DEBUG_ILC_KEYEVENTS)
4875 D(bug("[IconList] %s: DOWN: (A) reached list end .. starting at the beginng ..\n", __PRETTY_FUNCTION__));
4876 #endif
4877 start_X = entry_next->ie_IconX;
4878 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
4880 if (entry_next->ie_AreaWidth < data->icld_IconAreaLargestWidth)
4881 start_X = start_X - ((data->icld_IconAreaLargestWidth - entry_next->ie_AreaWidth)/2);
4884 if ((entry_next = (struct IconEntry *)Node_NextVisible(entry_next)))
4886 if (entry_next->ie_IconX < start_X)
4887 entry_next = NULL;
4888 else
4890 next_X = entry_next->ie_IconX;
4891 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
4893 if (entry_next->ie_AreaWidth < data->icld_IconAreaLargestWidth)
4894 next_X = next_X + ((data->icld_IconAreaLargestWidth - entry_next->ie_AreaWidth)/2);
4898 start_Y = 0;
4899 #if defined(DEBUG_ILC_KEYEVENTS)
4900 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));
4901 #endif
4902 active_entry = Node_FirstVisible(&data->icld_IconList);
4905 else
4907 if ((active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE) &&
4908 (active_Y > start_Y) &&
4909 (active_X > start_X - 1))
4911 #if defined(DEBUG_ILC_KEYEVENTS)
4912 D(bug("[IconList] %s: DOWN: (B) entry 0x%p matches\n", __PRETTY_FUNCTION__, active_entry));
4913 #endif
4914 break;
4918 else
4920 if (active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE)
4922 #if defined(DEBUG_ILC_KEYEVENTS)
4923 D(bug("[IconList] %s: DOWN: (C) entry 0x%p matches\n", __PRETTY_FUNCTION__, active_entry));
4924 #endif
4925 break;
4929 active_entry = (struct IconEntry *)GetSucc(&active_entry->ie_IconNode);
4932 if (!(active_entry))
4934 #if defined(DEBUG_ILC_KEYEVENTS)
4935 D(bug("[IconList] %s: DOWN: No Next DOWN Node - Getting first visable entry ..\n", __PRETTY_FUNCTION__));
4936 #endif
4937 /* We didnt find a "next DOWN" entry so just use the first visible */
4938 active_entry = Node_FirstVisible(&data->icld_IconList);
4941 if (active_entry)
4943 if (!(active_entry->ie_Flags & ICONENTRY_FLAG_FOCUS))
4945 active_entry->ie_Flags |= ICONENTRY_FLAG_FOCUS;
4946 data->icld_UpdateMode = UPDATE_SINGLEENTRY;
4947 data->update_entry = active_entry;
4948 MUI_Redraw(obj, MADF_DRAWUPDATE);
4951 data->icld_FocusIcon = active_entry;
4952 break;
4954 case RAWKEY_LEFT:
4955 rawkey_handled = TRUE;
4957 #if defined(DEBUG_ILC_KEYEVENTS)
4958 D(bug("[IconList] %s: RAWKEY_LEFT\n", __PRETTY_FUNCTION__));
4959 #endif
4960 if (data->icld_FocusIcon)
4962 start_entry = data->icld_FocusIcon;
4963 #if defined(DEBUG_ILC_KEYEVENTS)
4964 D(bug("[IconList] %s: LEFT: Clearing existing focused entry @ 0x%p\n", __PRETTY_FUNCTION__, start_entry));
4965 #endif
4967 start_entry->ie_Flags &= ~ICONENTRY_FLAG_FOCUS;
4968 data->icld_UpdateMode = UPDATE_SINGLEENTRY;
4969 data->update_entry = start_entry;
4970 MUI_Redraw(obj, MADF_DRAWUPDATE);
4972 start_X = start_entry->ie_IconX;
4973 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
4975 if (start_entry->ie_AreaWidth < data->icld_IconAreaLargestWidth)
4976 start_X = start_X - ((data->icld_IconAreaLargestWidth - start_entry->ie_AreaWidth)/2);
4978 start_Y = start_entry->ie_IconY;
4980 #if defined(DEBUG_ILC_KEYEVENTS)
4981 D(bug("[IconList] %s: LEFT: start_X %d, start_Y %d\n", __PRETTY_FUNCTION__, start_X, start_Y));
4982 #endif
4984 if (!(active_entry = Node_NextVisible(start_entry)) && (!(data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL)))
4986 active_entry = (struct IconEntry *)GetHead(&data->icld_IconList);
4987 #if defined(DEBUG_ILC_KEYEVENTS)
4988 D(bug("[IconList] %s: LEFT: Start at the beginning (Active @ 0x%p) using entry X + Width\n", __PRETTY_FUNCTION__, active_entry));
4989 #endif
4990 start_X = start_X + start_entry->ie_AreaWidth;
4991 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
4993 if (start_entry->ie_AreaWidth < data->icld_IconAreaLargestWidth)
4994 start_X = start_X + ((data->icld_IconAreaLargestWidth - start_entry->ie_AreaWidth)/2);
4997 start_Y = 0;
4998 entry_next = NULL;
5000 else if (active_entry && (!(data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL)))
5002 #if defined(DEBUG_ILC_KEYEVENTS)
5003 D(bug("[IconList] %s: LEFT: Active @ 0x%p, X %d\n", __PRETTY_FUNCTION__, active_entry, active_entry->ie_IconX));
5004 #endif
5005 if ((entry_next = Node_NextVisible(start_entry)))
5007 #if defined(DEBUG_ILC_KEYEVENTS)
5008 D(bug("[IconList] %s: LEFT: Next @ 0x%p, X %d\n", __PRETTY_FUNCTION__, entry_next, entry_next->ie_IconX));
5009 #endif
5011 if (entry_next->ie_IconX < start_X)
5012 entry_next = NULL;
5013 else
5015 next_X = entry_next->ie_IconX;
5016 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
5018 if (entry_next->ie_AreaWidth < data->icld_IconAreaLargestWidth)
5019 next_X = next_X - ((data->icld_IconAreaLargestWidth - entry_next->ie_AreaWidth)/2);
5024 #if defined(DEBUG_ILC_KEYEVENTS)
5025 D(bug("[IconList] %s: LEFT: using start_X %d, start_Y %d\n", __PRETTY_FUNCTION__, start_X, start_Y));
5026 #endif
5029 if (!(message->imsg->Qualifier & IEQUALIFIER_LSHIFT) && ((data->icld_SelectionLastClicked)&&(data->icld_SelectionLastClicked != active_entry)))
5031 #if defined(DEBUG_ILC_KEYEVENTS)
5032 D(bug("[IconList] %s: LEFT: Clearing selected icons ..\n", __PRETTY_FUNCTION__));
5033 #endif
5034 DoMethod(obj, MUIM_IconList_UnselectAll);
5037 #if defined(DEBUG_ILC_KEYEVENTS)
5038 D(bug("[IconList] %s: LEFT: active = 0x%p, next = 0x%p\n", __PRETTY_FUNCTION__, active_entry, entry_next));
5039 #endif
5041 if (!(active_entry))
5043 active_entry = (struct IconEntry *)GetHead(&data->icld_IconList);
5046 while (active_entry != NULL)
5048 #if defined(DEBUG_ILC_KEYEVENTS)
5049 D(bug("[IconList] %s: LEFT: Checking active @ 0x%p\n", __PRETTY_FUNCTION__, active_entry));
5050 #endif
5051 if (data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL)
5053 if (active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE)
5054 break;
5056 else
5058 LONG active_entry_X = active_entry->ie_IconX;
5059 LONG active_entry_Y;
5060 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
5062 if (active_entry->ie_AreaWidth < data->icld_IconAreaLargestWidth)
5063 active_entry_X = active_entry_X - ((data->icld_IconAreaLargestWidth - active_entry->ie_AreaWidth)/2);
5065 active_entry_Y = active_entry->ie_IconY;
5067 if (start_entry)
5069 if (entry_next)
5071 if ((active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE) &&
5072 (active_entry_Y > start_Y) &&
5073 ((active_entry_X > start_X - 1) &&
5074 (active_entry_X < next_X)))
5076 #if defined(DEBUG_ILC_KEYEVENTS)
5077 D(bug("[IconList] %s: LEFT: (A) entry 0x%p matches\n", __PRETTY_FUNCTION__, active_entry));
5078 #endif
5079 break;
5081 else if (active_entry == (struct IconEntry *)GetTail(&data->icld_IconList))
5083 #if defined(DEBUG_ILC_KEYEVENTS)
5084 D(bug("[IconList] %s: LEFT: (A) reached list end .. starting at the beginng ..\n", __PRETTY_FUNCTION__));
5085 #endif
5086 start_X = entry_next->ie_IconX;
5087 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
5089 if (entry_next->ie_AreaWidth < data->icld_IconAreaLargestWidth)
5090 start_X = start_X - ((data->icld_IconAreaLargestWidth - entry_next->ie_AreaWidth)/2);
5093 if ((entry_next = Node_NextVisible(entry_next)))
5095 if (entry_next->ie_IconX < start_X)
5096 entry_next = NULL;
5097 else
5099 next_X = entry_next->ie_IconX;
5100 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
5102 if (entry_next->ie_AreaWidth < data->icld_IconAreaLargestWidth)
5103 next_X = next_X + ((data->icld_IconAreaLargestWidth - entry_next->ie_AreaWidth)/2);
5107 start_Y = 0;
5108 #if defined(DEBUG_ILC_KEYEVENTS)
5109 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));
5110 #endif
5111 active_entry = (struct IconEntry *)GetHead(&data->icld_IconList);
5114 else
5116 if ((active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE) &&
5117 (active_entry_Y > start_Y) &&
5118 (active_entry_X > start_X - 1))
5120 #if defined(DEBUG_ILC_KEYEVENTS)
5121 D(bug("[IconList] %s: LEFT: (B) entry 0x%p matches\n", __PRETTY_FUNCTION__, active_entry));
5122 #endif
5123 break;
5127 else
5129 if (active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE)
5131 #if defined(DEBUG_ILC_KEYEVENTS)
5132 D(bug("[IconList] %s: LEFT: (C) entry 0x%p matches\n", __PRETTY_FUNCTION__, active_entry));
5133 #endif
5134 break;
5138 active_entry = (struct IconEntry *)GetSucc(&active_entry->ie_IconNode);
5141 if (!(active_entry))
5143 #if defined(DEBUG_ILC_KEYEVENTS)
5144 D(bug("[IconList] %s: LEFT: No Next LEFT Node - Getting first visable entry ..\n", __PRETTY_FUNCTION__));
5145 #endif
5146 /* We didnt find a "next LEFT" entry so just use the last visible */
5147 active_entry = (struct IconEntry *)GetHead(&data->icld_IconList);
5148 while ((active_entry != NULL) &&(!(active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE)))
5150 active_entry = (struct IconEntry *)GetSucc(&active_entry->ie_IconNode);
5154 if (active_entry)
5156 if (!(active_entry->ie_Flags & ICONENTRY_FLAG_FOCUS))
5158 active_entry->ie_Flags |= ICONENTRY_FLAG_FOCUS;
5159 data->icld_UpdateMode = UPDATE_SINGLEENTRY;
5160 data->update_entry = active_entry;
5161 MUI_Redraw(obj, MADF_DRAWUPDATE);
5164 data->icld_FocusIcon = active_entry;
5165 break;
5167 case RAWKEY_RIGHT:
5168 rawkey_handled = TRUE;
5170 #if defined(DEBUG_ILC_KEYEVENTS)
5171 D(bug("[IconList] %s: RAWKEY_RIGHT\n", __PRETTY_FUNCTION__));
5172 #endif
5174 if (data->icld_FocusIcon)
5176 start_entry = data->icld_FocusIcon;
5177 #if defined(DEBUG_ILC_KEYEVENTS)
5178 D(bug("[IconList] %s: RIGHT: Clearing existing focused entry @ 0x%p\n", __PRETTY_FUNCTION__, start_entry));
5179 #endif
5180 start_entry->ie_Flags &= ~ICONENTRY_FLAG_FOCUS;
5181 data->icld_UpdateMode = UPDATE_SINGLEENTRY;
5182 data->update_entry = start_entry;
5183 MUI_Redraw(obj, MADF_DRAWUPDATE);
5185 start_X = start_entry->ie_IconX;
5186 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
5188 if (start_entry->ie_AreaWidth < data->icld_IconAreaLargestWidth)
5189 start_X = start_X - ((data->icld_IconAreaLargestWidth - start_entry->ie_AreaWidth)/2);
5191 start_Y = start_entry->ie_IconY;
5193 #if defined(DEBUG_ILC_KEYEVENTS)
5194 D(bug("[IconList] %s: RIGHT: start_X %d, start_Y %d\n", __PRETTY_FUNCTION__, start_X, start_Y));
5195 #endif
5196 if (!(active_entry = Node_NextVisible(start_entry)) && (!(data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL)))
5198 active_entry = (struct IconEntry *)GetHead(&data->icld_IconList);
5199 #if defined(DEBUG_ILC_KEYEVENTS)
5200 D(bug("[IconList] %s: RIGHT: Start at the beginning (Active @ 0x%p) using entry X + Width\n", __PRETTY_FUNCTION__, active_entry));
5201 #endif
5202 start_X = 0;
5203 start_Y = start_Y + start_entry->ie_AreaHeight;
5204 entry_next = NULL;
5206 else if (active_entry && (data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL))
5208 #if defined(DEBUG_ILC_KEYEVENTS)
5209 D(bug("[IconList] %s: RIGHT: Active @ 0x%p, X %d\n", __PRETTY_FUNCTION__, active_entry, active_entry->ie_IconX));
5210 #endif
5211 if ((entry_next = Node_NextVisible(start_entry)))
5213 #if defined(DEBUG_ILC_KEYEVENTS)
5214 D(bug("[IconList] %s: RIGHT: Next @ 0x%p, X %d\n", __PRETTY_FUNCTION__, entry_next, entry_next->ie_IconX));
5215 #endif
5217 if (entry_next->ie_IconY < start_Y)
5218 entry_next = NULL;
5219 else
5220 next_Y = entry_next->ie_IconY;
5223 #if defined(DEBUG_ILC_KEYEVENTS)
5224 D(bug("[IconList] %s: RIGHT: using start_X %d, start_Y %d\n", __PRETTY_FUNCTION__, start_X, start_Y));
5225 #endif
5228 if (!(message->imsg->Qualifier & IEQUALIFIER_LSHIFT) && ((data->icld_SelectionLastClicked)&&(data->icld_SelectionLastClicked != active_entry)))
5230 #if defined(DEBUG_ILC_KEYEVENTS)
5231 D(bug("[IconList] %s: RIGHT: Clearing selected icons ..\n", __PRETTY_FUNCTION__));
5232 #endif
5233 DoMethod(obj, MUIM_IconList_UnselectAll);
5236 #if defined(DEBUG_ILC_KEYEVENTS)
5237 D(bug("[IconList] %s: RIGHT: active = 0x%p, next = 0x%p\n", __PRETTY_FUNCTION__, active_entry, entry_next));
5238 #endif
5240 if (!(active_entry))
5242 active_entry = (struct IconEntry *)GetHead(&data->icld_IconList);
5245 while (active_entry != NULL)
5247 #if defined(DEBUG_ILC_KEYEVENTS)
5248 D(bug("[IconList] %s: RIGHT: Checking active @ 0x%p\n", __PRETTY_FUNCTION__, active_entry));
5249 #endif
5250 if (!(data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL))
5252 if (active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE)
5253 break;
5255 else
5257 LONG active_entry_X = active_entry->ie_IconX;
5258 LONG active_entry_Y;
5259 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
5261 if (active_entry->ie_AreaWidth < data->icld_IconAreaLargestWidth)
5262 active_entry_X = active_entry_X - ((data->icld_IconAreaLargestWidth - active_entry->ie_AreaWidth)/2);
5264 active_entry_Y = active_entry->ie_IconY;
5266 if (start_entry)
5268 if (entry_next)
5270 if ((active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE) &&
5271 (active_entry_X > start_X) &&
5272 ((active_entry_Y > start_Y - 1) &&
5273 (active_entry_Y < next_Y)))
5275 #if defined(DEBUG_ILC_KEYEVENTS)
5276 D(bug("[IconList] %s: RIGHT: (A) entry 0x%p matches\n", __PRETTY_FUNCTION__, active_entry));
5277 #endif
5278 break;
5280 else if (active_entry == (struct IconEntry *)GetTail(&data->icld_IconList))
5282 #if defined(DEBUG_ILC_KEYEVENTS)
5283 D(bug("[IconList] %s: RIGHT: (A) reached list end .. starting at the beginng ..\n", __PRETTY_FUNCTION__));
5284 #endif
5285 start_Y = entry_next->ie_IconY;
5287 if ((entry_next = Node_NextVisible(entry_next)))
5289 if (entry_next->ie_IconY < start_Y)
5290 entry_next = NULL;
5291 else
5293 next_Y = entry_next->ie_IconY;
5296 start_Y = 0;
5297 #if defined(DEBUG_ILC_KEYEVENTS)
5298 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));
5299 #endif
5300 active_entry = (struct IconEntry *)GetHead(&data->icld_IconList);
5303 else
5305 if ((active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE) &&
5306 (active_entry_X > start_X) &&
5307 (active_entry_Y > start_Y - 1))
5309 #if defined(DEBUG_ILC_KEYEVENTS)
5310 D(bug("[IconList] %s: RIGHT: (B) entry 0x%p matches\n", __PRETTY_FUNCTION__, active_entry));
5311 #endif
5312 break;
5316 else
5318 if (active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE)
5320 #if defined(DEBUG_ILC_KEYEVENTS)
5321 D(bug("[IconList] %s: RIGHT: (C) entry 0x%p matches\n", __PRETTY_FUNCTION__, active_entry));
5322 #endif
5323 break;
5327 active_entry = (struct IconEntry *)GetSucc(&active_entry->ie_IconNode);
5330 if (!(active_entry))
5332 #if defined(DEBUG_ILC_KEYEVENTS)
5333 D(bug("[IconList] %s: RIGHT: No Next RIGHT Node - Getting first visable entry ..\n", __PRETTY_FUNCTION__));
5334 #endif
5335 /* We didnt find a "next RIGHT" entry so just use the first visible */
5336 active_entry = (struct IconEntry *)GetHead(&data->icld_IconList);
5337 while ((active_entry != NULL) &&(!(active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE)))
5339 active_entry = (struct IconEntry *)GetSucc(&active_entry->ie_IconNode);
5343 if (active_entry)
5345 if (!(active_entry->ie_Flags & ICONENTRY_FLAG_FOCUS))
5347 active_entry->ie_Flags |= ICONENTRY_FLAG_FOCUS;
5348 data->icld_UpdateMode = UPDATE_SINGLEENTRY;
5349 data->update_entry = active_entry;
5350 MUI_Redraw(obj, MADF_DRAWUPDATE);
5353 data->icld_FocusIcon = active_entry;
5354 break;
5356 case RAWKEY_HOME:
5357 rawkey_handled = TRUE;
5359 #if defined(DEBUG_ILC_KEYEVENTS)
5360 D(bug("[IconList] %s: RAWKEY_HOME\n", __PRETTY_FUNCTION__));
5361 #endif
5363 if (data->icld_FocusIcon)
5365 data->icld_FocusIcon->ie_Flags &= ~ICONENTRY_FLAG_FOCUS;
5366 data->icld_UpdateMode = UPDATE_SINGLEENTRY;
5367 data->update_entry = data->icld_FocusIcon;
5368 MUI_Redraw(obj, MADF_DRAWUPDATE);
5371 active_entry = Node_FirstVisible(&data->icld_IconList);
5373 if ((active_entry) && (!(active_entry->ie_Flags & ICONENTRY_FLAG_FOCUS)))
5375 active_entry->ie_Flags |= ICONENTRY_FLAG_FOCUS;
5376 data->icld_UpdateMode = UPDATE_SINGLEENTRY;
5377 data->update_entry = active_entry;
5378 MUI_Redraw(obj, MADF_DRAWUPDATE);
5380 data->icld_FocusIcon = active_entry;
5381 break;
5383 case RAWKEY_END:
5384 rawkey_handled = TRUE;
5386 #if defined(DEBUG_ILC_KEYEVENTS)
5387 D(bug("[IconList] %s: RAWKEY_END\n", __PRETTY_FUNCTION__));
5388 #endif
5390 if (data->icld_FocusIcon)
5392 data->icld_FocusIcon->ie_Flags &= ~ICONENTRY_FLAG_FOCUS;
5393 data->icld_UpdateMode = UPDATE_SINGLEENTRY;
5394 data->update_entry = data->icld_FocusIcon;
5395 MUI_Redraw(obj, MADF_DRAWUPDATE);
5398 active_entry = Node_LastVisible(&data->icld_IconList);
5400 if ((active_entry) && (!(active_entry->ie_Flags & ICONENTRY_FLAG_FOCUS)))
5402 active_entry->ie_Flags |= ICONENTRY_FLAG_FOCUS;
5403 data->icld_UpdateMode = UPDATE_SINGLEENTRY;
5404 data->update_entry = active_entry;
5405 MUI_Redraw(obj, MADF_DRAWUPDATE);
5407 data->icld_FocusIcon = active_entry;
5408 break;
5411 if (rawkey_handled) return MUI_EventHandlerRC_Eat;
5413 break;
5415 case IDCMP_MOUSEBUTTONS:
5416 #if defined(DEBUG_ILC_EVENTS)
5417 D(bug("[IconList] %s: IDCMP_MOUSEBUTTONS\n", __PRETTY_FUNCTION__));
5418 #endif
5419 if (message->imsg->Code == SELECTDOWN)
5421 /* check if mouse pressed on iconlist area */
5422 if (mx >= 0 && mx < _width(obj) && my >= 0 && my < _height(obj))
5424 BOOL icon_doubleclicked = FALSE;
5425 BOOL update_entry;
5426 struct IconEntry *node = NULL;
5427 struct IconEntry *new_selected = NULL;
5429 if ((data->icld_DisplayFlags & ICONLIST_DISP_MODELIST) == ICONLIST_DISP_MODELIST)
5431 LONG clickColumn = -1, clickRow = -1;
5433 LONG x = _mleft(obj) - data->icld_ViewX + LINE_SPACING_LEFT;
5434 LONG index, w, i;
5436 for(i = 0; i < NUM_COLUMNS; i++)
5438 index = data->icld_LVMAttribs->lmva_ColumnPos[i];
5440 if (!(data->icld_LVMAttribs->lmva_ColumnFlags[index] & LVMCF_COLVISIBLE)) continue;
5442 w = data->icld_LVMAttribs->lmva_ColumnWidth[index];
5444 if ((mx >= x) && (mx < x + w))
5446 clickColumn = index;
5447 break;
5449 x += w;
5452 if (((data->icld_LVMAttribs->lvma_Flags & LVMAF_NOHEADER) == 0) && (my <= data->icld_LVMAttribs->lmva_HeaderHeight))
5454 data->icld_LVMAttribs->lmva_LastSelectedColumn = clickColumn;
5456 data->icld_UpdateMode = UPDATE_HEADERENTRY;
5457 data->update_entry = clickColumn;
5459 MUI_Redraw(obj, MADF_DRAWUPDATE);
5462 else
5464 LONG current = 0, index = (my - data->icld_LVMAttribs->lmva_HeaderHeight + data->icld_ViewY) / data->icld_LVMAttribs->lmva_RowHeight;
5466 ForeachNode(&data->icld_IconList, node)
5468 if (node->ie_Flags & ICONENTRY_FLAG_VISIBLE)
5470 update_entry = FALSE;
5472 if (current == index)
5474 clickRow = current;
5475 new_selected = node;
5477 else
5479 if (node->ie_Flags & ICONENTRY_FLAG_SELECTED)
5481 if (!(message->imsg->Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT)))
5483 Remove(&node->ie_SelectionNode);
5484 node->ie_Flags &= ~ICONENTRY_FLAG_SELECTED;
5485 update_entry = TRUE;
5489 if (node->ie_Flags & ICONENTRY_FLAG_FOCUS)
5491 node->ie_Flags &= ~ICONENTRY_FLAG_FOCUS;
5492 update_entry = TRUE;
5495 if (update_entry)
5497 data->icld_UpdateMode = UPDATE_SINGLEENTRY;
5498 data->update_entry = node;
5499 MUI_Redraw(obj, MADF_DRAWUPDATE);
5500 D(bug("[IconList] %s: Rendered entry '%s'\n", __PRETTY_FUNCTION__, node->ie_IconListEntry.label));
5503 current++;
5507 if ((DoubleClick(data->last_secs, data->last_mics, message->imsg->Seconds, message->imsg->Micros)) && (data->icld_SelectionLastClicked == new_selected))
5509 D(bug("[IconList] %s: Entry double-clicked\n", __PRETTY_FUNCTION__));
5510 icon_doubleclicked = TRUE;
5513 if ((new_selected != NULL) && (clickRow != -1) && (clickColumn != -1))
5515 D(bug("[IconList] %s: Clicked on Row %d Column %d ..\n", __PRETTY_FUNCTION__, clickRow, clickColumn));
5517 data->icld_LassoActive = FALSE;
5518 update_entry = FALSE;
5520 if (!(new_selected->ie_Flags & ICONENTRY_FLAG_SELECTED))
5522 AddTail(&data->icld_SelectionList, &new_selected->ie_SelectionNode);
5523 new_selected->ie_Flags |= ICONENTRY_FLAG_SELECTED;
5524 update_entry = TRUE;
5526 if (!(new_selected->ie_Flags & ICONENTRY_FLAG_FOCUS))
5528 new_selected->ie_Flags |= ICONENTRY_FLAG_FOCUS;
5529 data->icld_FocusIcon = new_selected;
5532 else if ((icon_doubleclicked == FALSE) && (message->imsg->Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT)))
5534 Remove(&new_selected->ie_SelectionNode);
5535 new_selected->ie_Flags &= ~ICONENTRY_FLAG_SELECTED;
5536 update_entry = TRUE;
5539 if (update_entry)
5541 data->icld_UpdateMode = UPDATE_SINGLEENTRY;
5542 data->update_entry = new_selected;
5543 MUI_Redraw(obj, MADF_DRAWUPDATE);
5544 D(bug("[IconList] %s: Rendered 'new_selected' entry '%s'\n", __PRETTY_FUNCTION__, new_selected->ie_IconListEntry.label));
5547 else
5549 struct Window * thisWindow = NULL;
5550 #if defined(DEBUG_ILC_EVENTS) || defined(DEBUG_ILC_LASSO)
5551 D(bug("[IconList] %s: Starting Lasso\n", __PRETTY_FUNCTION__));
5552 #endif
5553 /* No entry clicked on ... Start Lasso-selection */
5554 data->icld_LassoActive = TRUE;
5555 if (!(message->imsg->Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT)))
5557 data->icld_SelectionLastClicked = NULL;
5558 data->icld_FocusIcon = NULL;
5560 data->icld_LassoRectangle.MinX = mx - data->view_rect.MinX + data->icld_ViewX;
5561 data->icld_LassoRectangle.MinY = my - data->view_rect.MinY + data->icld_ViewY;
5562 data->icld_LassoRectangle.MaxX = mx - data->view_rect.MinX + data->icld_ViewX;
5563 data->icld_LassoRectangle.MaxY = my - data->view_rect.MinY + data->icld_ViewY;
5565 /* Draw initial Lasso frame */
5566 IconList_InvertLassoOutlines(obj, data, &data->icld_LassoRectangle);
5568 GET(obj, MUIA_Window, &thisWindow);
5569 if (thisWindow)
5571 ModifyIDCMP(thisWindow, (thisWindow->IDCMPFlags|IDCMP_INTUITICKS));
5572 if (!(data->ehn.ehn_Events & IDCMP_INTUITICKS))
5574 DoMethod(_win(obj), MUIM_Window_RemEventHandler, (IPTR)&data->ehn);
5575 data->ehn.ehn_Events |= IDCMP_INTUITICKS;
5576 DoMethod(_win(obj), MUIM_Window_AddEventHandler, (IPTR)&data->ehn);
5582 else
5584 struct Rectangle rect;
5586 /* check if clicked on entry */
5587 #if defined(__AROS__)
5588 ForeachNode(&data->icld_IconList, node)
5589 #else
5590 Foreach_Node(&data->icld_IconList, node);
5591 #endif
5593 if (node->ie_Flags & ICONENTRY_FLAG_VISIBLE)
5595 update_entry = FALSE;
5597 rect.MinX = node->ie_IconX;
5598 rect.MaxX = node->ie_IconX + node->ie_AreaWidth - 1;
5599 rect.MinY = node->ie_IconY;
5600 rect.MaxY = node->ie_IconY + node->ie_AreaHeight - 1;
5602 if ((data->icld__Option_IconListMode == ICON_LISTMODE_GRID) &&
5603 (node->ie_AreaWidth < data->icld_IconAreaLargestWidth))
5605 rect.MinX += ((data->icld_IconAreaLargestWidth - node->ie_AreaWidth)/2);
5606 rect.MaxX += ((data->icld_IconAreaLargestWidth - node->ie_AreaWidth)/2);
5609 if ((((mx + data->icld_ViewX) >= rect.MinX) && ((mx + data->icld_ViewX) <= rect.MaxX )) &&
5610 (((my + data->icld_ViewY) >= rect.MinY) && ((my + data->icld_ViewY) <= rect.MaxY )) &&
5611 !new_selected)
5613 new_selected = node;
5614 #if defined(DEBUG_ILC_EVENTS)
5615 D(bug("[IconList] %s: Entry '%s' clicked on ..\n", __PRETTY_FUNCTION__, node->ie_IconListEntry.label));
5616 #endif
5619 if (node->ie_Flags & ICONENTRY_FLAG_SELECTED)
5621 if ((new_selected != node) &&
5622 (!(message->imsg->Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))))
5624 Remove(&node->ie_SelectionNode);
5625 node->ie_Flags &= ~ICONENTRY_FLAG_SELECTED;
5626 update_entry = TRUE;
5630 if ((node->ie_Flags & ICONENTRY_FLAG_FOCUS) && (new_selected != node))
5632 node->ie_Flags &= ~ICONENTRY_FLAG_FOCUS;
5633 update_entry = TRUE;
5636 if (update_entry)
5638 data->icld_UpdateMode = UPDATE_SINGLEENTRY;
5639 data->update_entry = node;
5640 MUI_Redraw(obj, MADF_DRAWUPDATE);
5641 #if defined(DEBUG_ILC_EVENTS)
5642 D(bug("[IconList] %s: Rendered entry '%s'\n", __PRETTY_FUNCTION__, node->ie_IconListEntry.label));
5643 #endif
5648 if ((DoubleClick(data->last_secs, data->last_mics, message->imsg->Seconds, message->imsg->Micros)) && (data->icld_SelectionLastClicked == new_selected))
5650 #if defined(DEBUG_ILC_EVENTS)
5651 D(bug("[IconList] %s: Entry double-clicked\n", __PRETTY_FUNCTION__));
5652 #endif
5653 icon_doubleclicked = TRUE;
5656 if (new_selected != NULL)
5658 data->icld_LassoActive = FALSE;
5659 update_entry = FALSE;
5661 if (!(new_selected->ie_Flags & ICONENTRY_FLAG_SELECTED))
5663 AddTail(&data->icld_SelectionList, &new_selected->ie_SelectionNode);
5664 new_selected->ie_Flags |= ICONENTRY_FLAG_SELECTED;
5665 update_entry = TRUE;
5667 if (!(new_selected->ie_Flags & ICONENTRY_FLAG_FOCUS))
5669 new_selected->ie_Flags |= ICONENTRY_FLAG_FOCUS;
5670 data->icld_FocusIcon = new_selected;
5673 else if ((icon_doubleclicked == FALSE) && (message->imsg->Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT)))
5675 Remove(&new_selected->ie_SelectionNode);
5676 new_selected->ie_Flags &= ~ICONENTRY_FLAG_SELECTED;
5677 update_entry = TRUE;
5680 if (update_entry != NULL)
5682 data->icld_UpdateMode = UPDATE_SINGLEENTRY;
5683 data->update_entry = new_selected;
5684 MUI_Redraw(obj, MADF_DRAWUPDATE);
5685 #if defined(DEBUG_ILC_EVENTS)
5686 D(bug("[IconList] %s: Rendered 'new_selected' entry '%s'\n", __PRETTY_FUNCTION__, new_selected->ie_IconListEntry.label));
5687 #endif
5690 else
5692 struct Window * thisWindow = NULL;
5693 #if defined(DEBUG_ILC_EVENTS) || defined(DEBUG_ILC_LASSO)
5694 D(bug("[IconList] %s: Starting Lasso\n", __PRETTY_FUNCTION__));
5695 #endif
5696 /* No entry clicked on ... Start Lasso-selection */
5697 data->icld_LassoActive = TRUE;
5698 if (!(message->imsg->Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT)))
5700 data->icld_SelectionLastClicked = NULL;
5701 data->icld_FocusIcon = NULL;
5703 data->icld_LassoRectangle.MinX = mx - data->view_rect.MinX + data->icld_ViewX;
5704 data->icld_LassoRectangle.MinY = my - data->view_rect.MinY + data->icld_ViewY;
5705 data->icld_LassoRectangle.MaxX = mx - data->view_rect.MinX + data->icld_ViewX;
5706 data->icld_LassoRectangle.MaxY = my - data->view_rect.MinY + data->icld_ViewY;
5708 /* Draw initial Lasso frame */
5709 IconList_InvertLassoOutlines(obj, data, &data->icld_LassoRectangle);
5711 GET(obj, MUIA_Window, &thisWindow);
5712 if (thisWindow)
5714 ModifyIDCMP(thisWindow, (thisWindow->IDCMPFlags|IDCMP_INTUITICKS));
5715 if (!(data->ehn.ehn_Events & IDCMP_INTUITICKS))
5717 DoMethod(_win(obj), MUIM_Window_RemEventHandler, (IPTR)&data->ehn);
5718 data->ehn.ehn_Events |= IDCMP_INTUITICKS;
5719 DoMethod(_win(obj), MUIM_Window_AddEventHandler, (IPTR)&data->ehn);
5725 if (new_selected && (new_selected->ie_Flags & ICONENTRY_FLAG_SELECTED))
5726 data->icld_SelectionLastClicked = new_selected;
5727 else
5728 data->icld_SelectionLastClicked = NULL;
5730 data->click_x = mx;
5731 data->click_y = my;
5733 SET(obj, MUIA_IconList_SelectionChanged, TRUE);
5735 data->icld_ClickEvent.shift = !!(message->imsg->Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT));
5736 data->icld_ClickEvent.entry = data->icld_SelectionLastClicked ? &data->icld_SelectionLastClicked->ie_IconListEntry : NULL;
5737 SET(obj, MUIA_IconList_Clicked, (IPTR)&data->icld_ClickEvent);
5739 if (icon_doubleclicked)
5741 SET(obj, MUIA_IconList_DoubleClick, TRUE);
5743 else if (!data->mouse_pressed)
5745 data->last_secs = message->imsg->Seconds;
5746 data->last_mics = message->imsg->Micros;
5748 /* After a double click you often open a new window
5749 * and since Zune doesn't not support the faking
5750 * of SELECTUP events only change the Events
5751 * if not doubleclicked */
5753 data->mouse_pressed |= LEFT_BUTTON;
5755 if (!(data->ehn.ehn_Events & IDCMP_MOUSEMOVE))
5757 DoMethod(_win(obj), MUIM_Window_RemEventHandler, (IPTR)&data->ehn);
5758 data->ehn.ehn_Events |= IDCMP_MOUSEMOVE;
5759 DoMethod(_win(obj), MUIM_Window_AddEventHandler, (IPTR)&data->ehn);
5763 return MUI_EventHandlerRC_Eat;
5766 else if (message->imsg->Code == MIDDLEDOWN)
5768 if (!data->mouse_pressed)
5770 data->mouse_pressed |= MIDDLE_BUTTON;
5772 data->click_x = data->icld_ViewX + mx;
5773 data->click_y = data->icld_ViewY + my;
5775 if (!(data->ehn.ehn_Events & IDCMP_MOUSEMOVE))
5777 DoMethod(_win(obj), MUIM_Window_RemEventHandler, (IPTR)&data->ehn);
5778 data->ehn.ehn_Events |= IDCMP_MOUSEMOVE;
5779 DoMethod(_win(obj), MUIM_Window_AddEventHandler, (IPTR)&data->ehn);
5783 else
5785 if (message->imsg->Code == SELECTUP)
5787 if (data->icld_LassoActive == TRUE)
5789 #if defined(DEBUG_ILC_EVENTS) || defined(DEBUG_ILC_LASSO)
5790 D(bug("[IconList] %s: Removing Lasso\n", __PRETTY_FUNCTION__));
5791 #endif
5792 // End Lasso-selection
5793 struct Rectangle old_lasso;
5794 struct IconEntry *node = NULL;
5795 struct Window *thisWindow = NULL;
5797 GET(obj, MUIA_Window, &thisWindow);
5798 if (thisWindow)
5800 ModifyIDCMP(thisWindow, (thisWindow->IDCMPFlags & ~(IDCMP_INTUITICKS)));
5801 if ((data->ehn.ehn_Events & IDCMP_INTUITICKS))
5803 DoMethod(_win(obj), MUIM_Window_RemEventHandler, (IPTR)&data->ehn);
5804 data->ehn.ehn_Events &= ~IDCMP_INTUITICKS;
5805 DoMethod(_win(obj), MUIM_Window_AddEventHandler, (IPTR)&data->ehn);
5808 //Clear Lasso Frame..
5809 GetAbsoluteLassoRect(data, &old_lasso);
5810 IconList_InvertLassoOutlines(obj, data, &old_lasso);
5812 data->icld_LassoActive = FALSE;
5814 //Remove Lasso flag from affected icons..
5815 #if defined(__AROS__)
5816 ForeachNode(&data->icld_IconList, node)
5817 #else
5818 Foreach_Node(&data->icld_IconList, node);
5819 #endif
5821 if (node->ie_Flags & ICONENTRY_FLAG_LASSO)
5823 node->ie_Flags &= ~ICONENTRY_FLAG_LASSO;
5826 SET(obj, MUIA_IconList_SelectionChanged, TRUE);
5828 else if (data->icld_LVMAttribs->lmva_LastSelectedColumn != -1)
5830 ULONG orig_sortflags = data->icld_SortFlags;
5832 if (data->icld_LVMAttribs->lmva_SortColumn == data->icld_LVMAttribs->lmva_LastSelectedColumn)
5834 if (data->icld_SortFlags & MUIV_IconList_Sort_Reverse)
5835 data->icld_SortFlags &= ~MUIV_IconList_Sort_Reverse;
5836 else
5837 data->icld_SortFlags |= MUIV_IconList_Sort_Reverse;
5840 switch (data->icld_LVMAttribs->lmva_LastSelectedColumn)
5842 case INDEX_NAME:
5843 data->icld_SortFlags &= ~MUIV_IconList_Sort_MASK;
5844 data->icld_SortFlags |= MUIV_IconList_Sort_ByName;
5845 break;
5847 case INDEX_SIZE:
5848 data->icld_SortFlags &= ~MUIV_IconList_Sort_MASK;
5849 data->icld_SortFlags |= MUIV_IconList_Sort_BySize;
5850 break;
5852 case INDEX_LASTACCESS:
5853 data->icld_SortFlags &= ~MUIV_IconList_Sort_MASK;
5854 data->icld_SortFlags |= MUIV_IconList_Sort_ByDate;
5855 break;
5858 if (orig_sortflags != data->icld_SortFlags)
5860 data->icld_LVMAttribs->lmva_SortColumn = data->icld_LVMAttribs->lmva_LastSelectedColumn;
5862 data->icld_LVMAttribs->lmva_LastSelectedColumn = -1;
5864 DoMethod(obj, MUIM_IconList_Sort);
5868 data->mouse_pressed &= ~LEFT_BUTTON;
5871 if (message->imsg->Code == MIDDLEUP)
5873 data->mouse_pressed &= ~MIDDLE_BUTTON;
5876 if ((data->ehn.ehn_Events & IDCMP_MOUSEMOVE) && !data->mouse_pressed)
5878 DoMethod(_win(obj),MUIM_Window_RemEventHandler, (IPTR)&data->ehn);
5879 data->ehn.ehn_Events &= ~IDCMP_MOUSEMOVE;
5880 DoMethod(_win(obj),MUIM_Window_AddEventHandler, (IPTR)&data->ehn);
5883 break;
5885 case IDCMP_INTUITICKS:
5887 #if defined(DEBUG_ILC_EVENTS)
5888 D(bug("[IconList] %s: IDCMP_INTUITICKS (%d, %d)\n", __PRETTY_FUNCTION__, mx, my));
5889 #endif
5890 if ((data->icld_LassoActive == FALSE)||(!(data->mouse_pressed & LEFT_BUTTON)))
5892 break;
5894 if (((mx >= 0) && (mx <= _mwidth(obj))) &&
5895 ((my >= 0) && (my <= _mheight(obj))))
5896 break;
5899 case IDCMP_MOUSEMOVE:
5900 #if defined(DEBUG_ILC_EVENTS)
5901 D(bug("[IconList] %s: IDCMP_MOUSEMOVE\n", __PRETTY_FUNCTION__));
5902 #endif
5903 if (data->mouse_pressed & LEFT_BUTTON)
5905 LONG move_x = mx;
5906 LONG move_y = my;
5908 if (data->icld_SelectionLastClicked && (data->icld_LassoActive == FALSE) &&
5909 ((abs(move_x - data->click_x) >= 2) || (abs(move_y - data->click_y) >= 2)))
5911 // Entry(s) being dragged ....
5912 DoMethod(_win(obj),MUIM_Window_RemEventHandler, (IPTR)&data->ehn);
5913 data->ehn.ehn_Events &= ~IDCMP_MOUSEMOVE;
5914 DoMethod(_win(obj),MUIM_Window_AddEventHandler, (IPTR)&data->ehn);
5916 data->mouse_pressed &= ~LEFT_BUTTON;
5918 data->touch_x = move_x + data->icld_ViewX - data->icld_SelectionLastClicked->ie_IconX;
5919 data->touch_y = move_y + data->icld_ViewY - data->icld_SelectionLastClicked->ie_IconY;
5920 DoMethod(obj,MUIM_DoDrag, data->touch_x, data->touch_y, 0);
5922 else if (data->icld_LassoActive == TRUE)
5924 #if defined(DEBUG_ILC_EVENTS) || defined(DEBUG_ILC_LASSO)
5925 D(bug("[IconList] %s: Update Lasso\n", __PRETTY_FUNCTION__));
5926 #endif
5927 //Lasso active ..
5928 struct Rectangle new_lasso,
5929 old_lasso;
5930 struct Rectangle iconrect;
5932 struct IconEntry *node = NULL;
5933 // struct IconEntry *new_selected = NULL;
5935 /* Remove previous Lasso frame */
5936 GetAbsoluteLassoRect(data, &old_lasso);
5937 IconList_InvertLassoOutlines(obj, data, &old_lasso);
5939 /* if the mouse leaves our visible area scroll the view */
5940 if (mx < 0 || mx >= _mwidth(obj) || my < 0 || my >= _mheight(obj))
5942 LONG newleft = data->icld_ViewX;
5943 LONG newtop = data->icld_ViewY;
5945 if (mx >= _mwidth(obj)) newleft += (mx - _mwidth(obj));
5946 else if (mx < 0) newleft += mx;
5947 if (my >= _mheight(obj)) newtop += (my - _mheight(obj));
5948 else if (my < 0) newtop += my;
5950 if (newleft + _mwidth(obj) > data->icld_AreaWidth) newleft = data->icld_AreaWidth - _mwidth(obj);
5951 if (newleft < 0) newleft = 0;
5953 if (newtop + _mheight(obj) > data->icld_AreaHeight) newtop = data->icld_AreaHeight - _mheight(obj);
5954 if (newtop < 0) newtop = 0;
5956 if ((newleft != data->icld_ViewX) || (newtop != data->icld_ViewY))
5958 SetAttrs(obj, MUIA_Virtgroup_Left, newleft, MUIA_Virtgroup_Top, newtop, TAG_DONE);
5962 /* update Lasso coordinates */
5963 data->icld_LassoRectangle.MaxX = mx - data->view_rect.MinX + data->icld_ViewX;
5964 data->icld_LassoRectangle.MaxY = my - data->view_rect.MinY + data->icld_ViewY;
5966 /* get absolute Lasso coordinates */
5967 GetAbsoluteLassoRect(data, &new_lasso);
5969 LONG current = 0, startIndex = 0, endIndex = 0;
5971 if ((data->icld_DisplayFlags & ICONLIST_DISP_MODELIST) == ICONLIST_DISP_MODELIST)
5973 LONG minY = data->icld_LassoRectangle.MinY,
5974 maxY = data->icld_LassoRectangle.MaxY;
5976 if (minY > maxY)
5978 minY ^= maxY;
5979 maxY ^= minY;
5980 minY ^= maxY;
5983 startIndex = ((minY + 1) - data->icld_LVMAttribs->lmva_HeaderHeight) / data->icld_LVMAttribs->lmva_RowHeight;
5984 endIndex = ((maxY - 1) - data->icld_LVMAttribs->lmva_HeaderHeight) / data->icld_LVMAttribs->lmva_RowHeight;
5987 #if defined(__AROS__)
5988 ForeachNode(&data->icld_IconList, node)
5989 #else
5990 Foreach_Node(&data->icld_IconList, node);
5991 #endif
5993 IPTR update_entry = (IPTR)NULL;
5995 if ((data->icld_DisplayFlags & ICONLIST_DISP_MODELIST) == ICONLIST_DISP_MODELIST)
5997 if (node->ie_Flags & ICONENTRY_FLAG_VISIBLE)
5999 update_entry = FALSE;
6001 if ((current >= startIndex) && (current <= endIndex))
6003 //Entry is inside our lasso ..
6004 if (!(node->ie_Flags & ICONENTRY_FLAG_LASSO))
6006 /* check if entry was already selected before */
6007 if (node->ie_Flags & ICONENTRY_FLAG_SELECTED)
6009 Remove(&node->ie_SelectionNode);
6010 node->ie_Flags &= ~ICONENTRY_FLAG_SELECTED;
6012 else
6014 AddTail(&data->icld_SelectionList, &node->ie_SelectionNode);
6015 node->ie_Flags |= ICONENTRY_FLAG_SELECTED;
6017 node->ie_Flags |= ICONENTRY_FLAG_LASSO;
6018 update_entry = (IPTR)node;
6021 else if (node->ie_Flags & ICONENTRY_FLAG_LASSO)
6023 //Entry is no longer inside our lasso - revert its selected state
6024 if (node->ie_Flags & ICONENTRY_FLAG_SELECTED)
6026 Remove(&node->ie_SelectionNode);
6027 node->ie_Flags &= ~ICONENTRY_FLAG_SELECTED;
6029 else
6031 AddTail(&data->icld_SelectionList, &node->ie_SelectionNode);
6032 node->ie_Flags |= ICONENTRY_FLAG_SELECTED;
6034 node->ie_Flags &= ~ICONENTRY_FLAG_LASSO;
6035 update_entry = (IPTR)node;
6038 current++;
6041 else
6043 if (node->ie_Flags & ICONENTRY_FLAG_VISIBLE)
6045 iconrect.MinX = node->ie_IconX;
6046 iconrect.MaxX = node->ie_IconX + node->ie_AreaWidth - 1;
6047 iconrect.MinY = node->ie_IconY;
6048 iconrect.MaxY = node->ie_IconY + node->ie_AreaHeight - 1;
6049 if ((data->icld__Option_IconListMode == ICON_LISTMODE_GRID) &&
6050 (node->ie_AreaWidth < data->icld_IconAreaLargestWidth))
6052 iconrect.MinX += ((data->icld_IconAreaLargestWidth - node->ie_AreaWidth)/2);
6053 iconrect.MaxX += ((data->icld_IconAreaLargestWidth - node->ie_AreaWidth)/2);
6056 if ((((new_lasso.MaxX + data->icld_ViewX) >= iconrect.MinX) && ((new_lasso.MinX + data->icld_ViewX) <= iconrect.MaxX)) &&
6057 (((new_lasso.MaxY + data->icld_ViewY) >= iconrect.MinY) && ((new_lasso.MinY + data->icld_ViewY) <= iconrect.MaxY)))
6059 //Entry is inside our lasso ..
6060 if (!(node->ie_Flags & ICONENTRY_FLAG_LASSO))
6062 /* check if entry was already selected before */
6063 if (node->ie_Flags & ICONENTRY_FLAG_SELECTED)
6065 Remove(&node->ie_SelectionNode);
6066 node->ie_Flags &= ~ICONENTRY_FLAG_SELECTED;
6068 else
6070 AddTail(&data->icld_SelectionList, &node->ie_SelectionNode);
6071 node->ie_Flags |= ICONENTRY_FLAG_SELECTED;
6073 node->ie_Flags |= ICONENTRY_FLAG_LASSO;
6074 update_entry = (IPTR)node;
6077 else if (node->ie_Flags & ICONENTRY_FLAG_LASSO)
6079 //Entry is no longer inside our lasso - revert its selected state
6080 if (node->ie_Flags & ICONENTRY_FLAG_SELECTED)
6082 Remove(&node->ie_SelectionNode);
6083 node->ie_Flags &= ~ICONENTRY_FLAG_SELECTED;
6085 else
6087 AddTail(&data->icld_SelectionList, &node->ie_SelectionNode);
6088 node->ie_Flags |= ICONENTRY_FLAG_SELECTED;
6090 node->ie_Flags &= ~ICONENTRY_FLAG_LASSO;
6091 update_entry = (IPTR)node;
6095 if (update_entry)
6097 data->icld_UpdateMode = UPDATE_SINGLEENTRY;
6098 data->update_entry = (struct IconEntry *)update_entry;
6099 MUI_Redraw(obj, MADF_DRAWUPDATE);
6102 /* Draw Lasso frame */
6103 IconList_InvertLassoOutlines(obj, data, &new_lasso);
6106 return MUI_EventHandlerRC_Eat;
6108 else if (data->mouse_pressed & MIDDLE_BUTTON)
6110 LONG newleft,
6111 newtop;
6113 newleft = data->click_x - mx;
6114 newtop = data->click_y - my;
6116 if (newleft + _mwidth(obj) > data->icld_AreaWidth) newleft = data->icld_AreaWidth - _mwidth(obj);
6117 if (newleft < 0) newleft = 0;
6119 if (newtop + _mheight(obj) > data->icld_AreaHeight) newtop = data->icld_AreaHeight - _mheight(obj);
6120 if (newtop < 0) newtop = 0;
6122 if ((newleft != data->icld_ViewX) || (newtop != data->icld_ViewY))
6124 SetAttrs(obj, MUIA_Virtgroup_Left, newleft,
6125 MUIA_Virtgroup_Top, newtop,
6126 TAG_DONE);
6129 return MUI_EventHandlerRC_Eat;
6132 break;
6136 return 0;
6140 ///MUIM_IconList_NextIcon()
6141 /**************************************************************************
6142 MUIM_IconList_NextIcon
6143 **************************************************************************/
6144 IPTR IconList__MUIM_IconList_NextIcon(struct IClass *CLASS, Object *obj, struct MUIP_IconList_NextIcon *message)
6146 struct IconList_DATA *data = INST_DATA(CLASS, obj);
6147 struct IconEntry *node = NULL;
6148 struct IconList_Entry *ent = NULL;
6149 IPTR node_successor = (IPTR)NULL;
6151 if (message->entry == NULL) return (IPTR)NULL;
6152 ent = *message->entry;
6154 #if defined(DEBUG_ILC_FUNCS)
6155 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
6156 #endif
6158 if ((IPTR)ent == (IPTR)MUIV_IconList_NextIcon_Start)
6160 D(bug("[IconList] %s: Finding First Entry ..\n", __PRETTY_FUNCTION__));
6161 if (message->nextflag == MUIV_IconList_NextIcon_Selected)
6163 node = (struct IconEntry *)GetHead(&data->icld_SelectionList);
6164 if (node != NULL)
6166 node = (struct IconEntry *)((IPTR)node - ((IPTR)&node->ie_SelectionNode - (IPTR)node));
6169 else if (message->nextflag == MUIV_IconList_NextIcon_Visible)
6171 node = (struct IconEntry *)GetHead(&data->icld_IconList);
6172 while (node != NULL)
6174 if (node->ie_Flags & ICONENTRY_FLAG_VISIBLE)
6175 break;
6177 node = (struct IconEntry *)GetSucc(&node->ie_IconNode);
6181 else if ((IPTR)ent != (IPTR)MUIV_IconList_NextIcon_End)
6183 node = (struct IconEntry *)((IPTR)ent - ((IPTR)&node->ie_IconListEntry - (IPTR)node));
6184 if (message->nextflag == MUIV_IconList_NextIcon_Selected)
6186 node_successor = (IPTR)GetSucc(&node->ie_SelectionNode);
6187 if (node_successor != (IPTR)NULL)
6188 node = (struct IconEntry *)((IPTR)node_successor - ((IPTR)&node->ie_SelectionNode - (IPTR)node));
6189 else
6191 D(bug("[IconList] %s: GetSucc() == NULL\n", __PRETTY_FUNCTION__));
6192 node = NULL;
6195 else if (message->nextflag == MUIV_IconList_NextIcon_Visible)
6197 node = (struct IconEntry *)GetSucc(&node->ie_IconNode);
6198 while (node != NULL)
6200 if (node->ie_Flags & ICONENTRY_FLAG_VISIBLE)
6201 break;
6203 node = (struct IconEntry *)GetSucc(&node->ie_IconNode);
6208 if (node == NULL)
6210 D(bug("[IconList] %s: Returning MUIV_IconList_NextIcon_End\n", __PRETTY_FUNCTION__));
6212 *message->entry = (struct IconList_Entry *)MUIV_IconList_NextIcon_End;
6214 else
6216 D(bug("[IconList] %s: Returning entry for '%s'\n", __PRETTY_FUNCTION__, node->ie_IconListEntry.label));
6218 *message->entry = &node->ie_IconListEntry;
6221 return (IPTR)NULL;
6225 ///MUIM_IconList_GetIconPrivate()
6226 /**************************************************************************
6227 MUIM_IconList_GetIconPrivate
6228 **************************************************************************/
6229 IPTR IconList__MUIM_IconList_GetIconPrivate(struct IClass *CLASS, Object *obj, struct MUIP_IconList_GetIconPrivate *message)
6231 // struct IconList_DATA *data = INST_DATA(CLASS, obj);
6232 struct IconEntry *node = NULL;
6234 if (message->entry == NULL) return (IPTR)NULL;
6236 node = (struct IconEntry *)((IPTR)message->entry - ((IPTR)&node->ie_IconListEntry - (IPTR)node));
6238 return (IPTR)node;
6241 ///MUIM_CreateDragImage()
6242 /**************************************************************************
6243 MUIM_CreateDragImage
6244 **************************************************************************/
6245 IPTR IconList__MUIM_CreateDragImage(struct IClass *CLASS, Object *obj, struct MUIP_CreateDragImage *message)
6247 struct IconList_DATA *data = INST_DATA(CLASS, obj);
6248 struct MUI_DragImage *img = NULL;
6249 LONG first_x = -1,
6250 first_y = -1;
6252 #if defined(DEBUG_ILC_FUNCS) || defined(DEBUG_ILC_ICONDRAGDROP)
6253 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
6254 #endif
6256 if (!(data->icld_SelectionLastClicked))
6257 DoSuperMethodA(CLASS, obj, (Msg)message);
6259 if ((img = (struct MUI_DragImage *)AllocVec(sizeof(struct MUIP_CreateDragImage), MEMF_CLEAR)))
6261 struct Node *node = NULL;
6262 struct IconEntry *entry = NULL;
6264 LONG depth = GetBitMapAttr(_screen(obj)->RastPort.BitMap, BMA_DEPTH);
6266 #if defined(CREATE_FULL_DRAGIMAGE)
6267 #if defined(__AROS__)
6268 ForeachNode(&data->icld_SelectionList, node)
6269 #else
6270 Foreach_Node(&data->icld_SelectionList, node);
6271 #endif
6273 entry = (struct IconEntry *)((IPTR)node - ((IPTR)&entry->ie_SelectionNode - (IPTR)entry));
6274 if ((entry->ie_Flags & ICONENTRY_FLAG_VISIBLE) && (entry->ie_Flags & ICONENTRY_FLAG_SELECTED))
6276 if ((data->icld_DisplayFlags & ICONLIST_DISP_MODELIST) != ICONLIST_DISP_MODELIST)
6278 if ((first_x == -1) || ((first_x != -1) && (entry->ie_IconX < first_x))) first_x = entry->ie_IconX;
6279 if ((first_y == -1) || ((first_y != -1) && (entry->ie_IconY < first_y))) first_y = entry->ie_IconY;
6280 if ((entry->ie_IconX + entry->ie_IconWidth) > img->width) img->width = entry->ie_IconX + entry->ie_IconWidth;
6281 if ((entry->ie_IconY + entry->ie_IconHeight) > img->height) img->height = entry->ie_IconY + entry->ie_IconHeight;
6283 else
6285 img->height += data->icld_LVMAttribs->lmva_RowHeight;
6289 if ((data->icld_DisplayFlags & ICONLIST_DISP_MODELIST) == ICONLIST_DISP_MODELIST)
6291 first_x = 0;
6292 first_y = 0;
6293 img->width = _mright(obj) - _mleft(obj);
6295 else
6296 img->width = (img->width - first_x) + 2;
6298 img->height = (img->height - first_y) + 2;
6299 #else
6300 entry = data->icld_SelectionLastClicked;
6301 if ((data->icld_DisplayFlags & ICONLIST_DISP_MODELIST) == ICONLIST_DISP_MODELIST)
6303 img->width = _mright(obj) - _mleft(obj);
6304 img->height = data->icld_LVMAttribs->lmva_RowHeight;
6305 first_x = 0;
6306 first_y = 0;
6308 else
6310 img->width = entry->ie_IconWidth;
6311 img->height = entry->ie_IconHeight;
6312 first_x = entry->ie_IconX;
6313 first_y = entry->ie_IconY;
6315 #endif
6317 if ((img->bm = AllocBitMap(img->width, img->height, depth, BMF_CLEAR, _screen(obj)->RastPort.BitMap)))
6319 struct RastPort temprp;
6320 InitRastPort(&temprp);
6321 temprp.BitMap = img->bm;
6323 #if defined(CREATE_FULL_DRAGIMAGE)
6324 ForeachNode(&data->icld_SelectionList, node)
6326 entry = (struct IconEntry *)((IPTR)node - ((IPTR)&entry->ie_SelectionNode - (IPTR)entry));
6327 if ((entry->ie_Flags & ICONENTRY_FLAG_VISIBLE) && (entry->ie_Flags & ICONENTRY_FLAG_SELECTED))
6329 if ((data->icld_DisplayFlags & ICONLIST_DISP_MODELIST) == ICONLIST_DISP_MODELIST)
6332 else
6334 DrawIconStateA
6336 &temprp, entry->ie_DiskObj, NULL,
6337 (entry->ie_IconX + 1) - first_x, (entry->ie_IconY + 1) - first_y,
6338 IDS_SELECTED,
6339 __iconList_DrawIconStateTags
6344 #else
6345 if ((data->icld_DisplayFlags & ICONLIST_DISP_MODELIST) == ICONLIST_DISP_MODELIST)
6347 SetABPenDrMd(&temprp, _pens(obj)[MPEN_SHINE], 0, JAM1);
6348 RectFill(&temprp, 0, 0, img->width, img->height);
6350 else
6352 DrawIconStateA
6354 &temprp, entry->ie_DiskObj, NULL,
6355 0, 0,
6356 IDS_SELECTED,
6357 __iconList_DrawIconStateTags
6360 #endif
6361 RastPortSetAlpha(&temprp, data->click_x, data->click_y, img->width, img->height, 0x80, RPALPHAFLAT);
6362 DeinitRastPort(&temprp);
6365 img->touchx = message->touchx;
6366 img->touchy = message->touchy;
6368 img->flags = 0;
6369 #if defined(__MORPHOS__)
6370 img->dragmode = DD_TRANSPARENT;
6371 #endif
6373 return (IPTR)img;
6377 ///MUIM_DeleteDragImage()
6378 /**************************************************************************
6379 MUIM_DeleteDragImage
6380 **************************************************************************/
6381 IPTR IconList__MUIM_DeleteDragImage(struct IClass *CLASS, Object *obj, struct MUIP_DeleteDragImage *message)
6383 struct IconList_DATA *data = INST_DATA(CLASS, obj);
6385 #if defined(DEBUG_ILC_FUNCS) || defined(DEBUG_ILC_ICONDRAGDROP)
6386 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
6387 #endif
6389 if (!(data->icld_SelectionLastClicked)) return DoSuperMethodA(CLASS,obj,(Msg)message);
6391 if (message->di)
6393 if (message->di->bm)
6394 FreeBitMap(message->di->bm);
6395 FreeVec(message->di);
6397 return (IPTR)NULL;
6401 ///MUIM_DragQuery()
6402 /**************************************************************************
6403 MUIM_DragQuery
6404 **************************************************************************/
6405 IPTR IconList__MUIM_DragQuery(struct IClass *CLASS, Object *obj, struct MUIP_DragQuery *message)
6407 #if defined(DEBUG_ILC_FUNCS) || defined(DEBUG_ILC_ICONDRAGDROP)
6408 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
6409 #endif
6411 #warning "TODO: highlight the possible drop target entry .."
6413 if (message->obj == obj)
6414 return MUIV_DragQuery_Accept;
6415 else
6417 BOOL is_iconlist = FALSE;
6418 struct IClass *msg_cl = OCLASS(message->obj);
6420 while (msg_cl)
6422 if (msg_cl == CLASS)
6424 is_iconlist = TRUE;
6425 break;
6427 msg_cl = msg_cl->cl_Super;
6429 if (is_iconlist)
6430 return MUIV_DragQuery_Accept;
6433 return MUIV_DragQuery_Refuse;
6437 ///MUIM_DragDrop()
6438 /**************************************************************************
6439 MUIM_DragDrop
6440 **************************************************************************/
6441 IPTR IconList__MUIM_DragDrop(struct IClass *CLASS, Object *obj, struct MUIP_DragDrop *message)
6443 struct IconList_DATA *data = INST_DATA(CLASS, obj);
6445 #if defined(DEBUG_ILC_FUNCS) || defined(DEBUG_ILC_ICONDRAGDROP)
6446 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
6447 #endif
6449 struct IconList_Entry *entry = (IPTR)MUIV_IconList_NextIcon_Start;
6451 if (data->icld_DragDropEvent)
6453 struct IconList_Drop_SourceEntry *clean_node;
6454 #if defined(DEBUG_ILC_ICONDRAGDROP)
6455 D(bug("[IconList] %s: Cleaning existing IconList_Drop_Event @ %p\n", __PRETTY_FUNCTION__, data->icld_DragDropEvent));
6456 #endif
6457 while ((clean_node = (struct IconList_Drop_SourceEntry *)RemTail(&data->icld_DragDropEvent->drop_SourceList)) != NULL)
6459 FreeVec(clean_node->dropse_Node.ln_Name);
6460 FreeMem(clean_node, sizeof(struct IconList_Drop_SourceEntry));
6462 if (data->icld_DragDropEvent->drop_TargetPath) FreeVec(data->icld_DragDropEvent->drop_TargetPath);
6463 FreeMem(data->icld_DragDropEvent, sizeof(struct IconList_Drop_Event));
6464 data->icld_DragDropEvent = NULL;
6467 /* SANITY CHECK: Get first selected entry from SOURCE iconlist */
6468 DoMethod(message->obj, MUIM_IconList_NextIcon, MUIV_IconList_NextIcon_Selected, (IPTR)&entry);
6470 if ((entry) && (entry != (IPTR)MUIV_IconList_NextIcon_End))
6472 /* Ok.. atleast one entry was dropped .. */
6473 char tmp_dirbuff[256];
6474 BPTR tmp_dirlock = (BPTR) NULL;
6476 BOOL iconMove = FALSE;
6477 struct IconEntry *node = NULL;
6478 struct IconEntry *drop_target_node = NULL;
6479 STRPTR directory_path = NULL;
6480 struct IconList_Drop_Event *dragDropEvent = NULL;
6482 GET(obj, MUIA_IconDrawerList_Drawer, &directory_path);
6484 /* Properly expand the name incase it uses devices rather than volumes */
6485 if (directory_path != NULL)
6487 tmp_dirlock = Lock(directory_path, SHARED_LOCK);
6488 if (tmp_dirlock)
6490 if (NameFromLock(tmp_dirlock, tmp_dirbuff, 256) != 0)
6492 directory_path = tmp_dirbuff;
6494 UnLock(tmp_dirlock);
6497 if ((dragDropEvent = AllocMem(sizeof(struct IconList_Drop_Event), MEMF_CLEAR)) == NULL)
6499 #if defined(DEBUG_ILC_ICONDRAGDROP)
6500 D(bug("[IconList] %s: Failed to allocate IconList_Drop_Event Storage!\n", __PRETTY_FUNCTION__));
6501 #endif
6502 goto dragdropdone;
6504 #if defined(DEBUG_ILC_ICONDRAGDROP)
6505 D(bug("[IconList] %s: Allocated IconList_Drop_Event @ %p\n", __PRETTY_FUNCTION__, dragDropEvent));
6506 #endif
6508 NewList(&dragDropEvent->drop_SourceList);
6510 /* go through list and check if dropped on entry */
6511 int rowCount = 0;
6513 #if defined(__AROS__)
6514 ForeachNode(&data->icld_IconList, node)
6515 #else
6516 Foreach_Node(&data->icld_IconList, node);
6517 #endif
6519 if ((data->icld_DisplayFlags & ICONLIST_DISP_MODELIST) == ICONLIST_DISP_MODELIST)
6521 if (node->ie_Flags & ICONENTRY_FLAG_VISIBLE)
6523 ULONG rowTop = _mtop(obj) + (rowCount * data->icld_LVMAttribs->lmva_RowHeight);
6524 rowTop += data->icld_LVMAttribs->lmva_HeaderHeight;
6526 if (((message->x > _mleft(obj)) && (message->x < _mright(obj)))
6527 && ((message->y > rowTop) && (message->y < (rowTop + data->icld_LVMAttribs->lmva_RowHeight))))
6529 drop_target_node = node;
6530 break;
6533 rowCount++;
6536 else
6538 struct Rectangle iconbox;
6539 LONG click_x = message->x - _mleft(obj);
6540 LONG click_y = message->y - _mtop(obj);
6541 iconbox.MinX = node->ie_IconX - data->icld_ViewX;
6542 iconbox.MaxX = (node->ie_IconX + node->ie_AreaWidth) - data->icld_ViewX;
6543 iconbox.MinY = node->ie_IconY - data->icld_ViewY;
6544 iconbox.MaxY = (node->ie_IconY + node->ie_AreaHeight)- data->icld_ViewY;
6546 if ((node->ie_Flags & ICONENTRY_FLAG_VISIBLE) &&
6547 (click_x >= iconbox.MinX) &&
6548 (click_x < iconbox.MaxX) &&
6549 (click_y >= iconbox.MinY) &&
6550 (click_y < iconbox.MaxY))
6552 drop_target_node = node;
6553 break;
6558 if ((drop_target_node != NULL) &&
6559 ((drop_target_node->ie_IconListEntry.type == ST_SOFTLINK) ||
6560 (drop_target_node->ie_IconListEntry.type == ST_ROOT) ||
6561 (drop_target_node->ie_IconListEntry.type == ST_USERDIR) ||
6562 (drop_target_node->ie_IconListEntry.type == ST_LINKDIR) ||
6563 (drop_target_node->ie_IconListEntry.type == ST_FILE) ||
6564 (drop_target_node->ie_IconListEntry.type == ST_LINKFILE)))
6566 if ((drop_target_node->ie_IconListEntry.type != ST_ROOT) && (drop_target_node->ie_IconListEntry.type != ST_SOFTLINK))
6568 if (directory_path)
6570 int fulllen = strlen(directory_path) + strlen(drop_target_node->ie_IconListEntry.label) + 2;
6572 if ((dragDropEvent->drop_TargetPath = AllocVec(fulllen, MEMF_CLEAR)) == NULL)
6574 bug("[IconList] %s: Failed to allocate IconList_Drop_Event->drop_TargetPath Storage!\n", __PRETTY_FUNCTION__);
6575 goto dragdropdone;
6577 strcpy(dragDropEvent->drop_TargetPath, directory_path);
6578 AddPart(dragDropEvent->drop_TargetPath, drop_target_node->ie_IconListEntry.label, fulllen);
6581 else
6583 if ((dragDropEvent->drop_TargetPath = AllocVec(strlen(drop_target_node->ie_IconListEntry.label) + 1, MEMF_CLEAR)) == NULL)
6585 bug("[IconList] %s: Failed to allocate IconList_Drop_Event->drop_TargetPath Storage!\n", __PRETTY_FUNCTION__);
6586 goto dragdropdone;
6588 strcpy(dragDropEvent->drop_TargetPath, drop_target_node->ie_IconListEntry.label);
6591 #if defined(DEBUG_ILC_ICONDRAGDROP)
6592 D(bug("[IconList] %s: Target Entry Full Path = '%s'\n", __PRETTY_FUNCTION__, dragDropEvent->drop_TargetPath));
6593 #endif
6594 /* mark the Entry the selection was dropped on*/
6595 //drop_target_node->ie_Flags |= ICONENTRY_FLAG_SELECTED;
6596 //data->icld_UpdateMode = UPDATE_SINGLEENTRY;
6597 //data->update_entry = drop_target_node;
6598 //MUI_Redraw(obj,MADF_DRAWUPDATE);
6600 else
6602 /* not dropped on entry -> get path of DESTINATION iconlist */
6603 /* Note: directory_path is NULL when dropped on Wanderer's desktop */
6604 if ((message->obj != obj) && directory_path)
6606 #if defined(DEBUG_ILC_ICONDRAGDROP)
6607 D(bug("[IconList] %s: drop entry: Icons dropped in window '%s'\n", __PRETTY_FUNCTION__, directory_path));
6608 #endif
6609 /* copy path */
6610 if ((dragDropEvent->drop_TargetPath = AllocVec(strlen(directory_path) + 1, MEMF_CLEAR)) != NULL)
6612 strcpy(dragDropEvent->drop_TargetPath, directory_path);
6614 else
6616 #if defined(DEBUG_ILC_ICONDRAGDROP)
6617 D(bug("[IconList] %s: Failed to allocate IconList_Drop_Event->drop_TargetPath Storage!\n", __PRETTY_FUNCTION__));
6618 #endif
6619 goto dragdropdone;
6622 else if (message->obj == obj)
6624 #if defined(DEBUG_ILC_ICONDRAGDROP)
6625 D(bug("[IconList] %s: drop entry: Entry Move detected ..\n", __PRETTY_FUNCTION__));
6626 #endif
6627 iconMove = TRUE;
6629 /* Adjust entry posiions .. */
6630 #if defined(DEBUG_ILC_ICONDRAGDROP)
6631 D(bug("[IconList] %s: drop entry: message x,y = %d, %d click = %d, %d..\n", __PRETTY_FUNCTION__, message->x, message->y, data->click_x, data->click_y));
6632 #endif
6633 LONG offset_x = message->x - (data->click_x + _mleft(obj));
6634 LONG offset_y = message->y - (data->click_y + _mtop(obj));
6636 entry = (IPTR)MUIV_IconList_NextIcon_Start;
6637 while (entry != (IPTR)MUIV_IconList_NextIcon_End)
6639 DoMethod(message->obj, MUIM_IconList_NextIcon, MUIV_IconList_NextIcon_Selected, (IPTR)&entry);
6641 if (entry != (IPTR)MUIV_IconList_NextIcon_End)
6643 entry->ile_IconEntry->ie_IconX += offset_x;
6644 entry->ile_IconEntry->ie_IconY += offset_y;
6646 SET(obj, MUIA_IconList_IconMoved, (IPTR)entry); // Now notify
6648 MUI_Redraw(obj,MADF_DRAWOBJECT);
6649 DoMethod(obj, MUIM_IconList_CoordsSort);
6651 else
6653 #if defined(DEBUG_ILC_ICONDRAGDROP)
6654 D(bug("[IconList] %s: Icons Dropped on Wanderer Desktop (unhandled)!\n", __PRETTY_FUNCTION__));
6655 #endif
6656 iconMove = TRUE;
6659 if (!(iconMove))
6661 int copycount = 0;
6662 /* Create list of entries to copy .. */
6663 entry = (IPTR)MUIV_IconList_NextIcon_Start;
6664 while (entry != (IPTR)MUIV_IconList_NextIcon_End)
6666 DoMethod(message->obj, MUIM_IconList_NextIcon, MUIV_IconList_NextIcon_Selected, (IPTR)&entry);
6668 if (entry != (IPTR)MUIV_IconList_NextIcon_End)
6670 struct IconList_Drop_SourceEntry *sourceEntry = NULL;
6671 sourceEntry = AllocMem(sizeof(struct IconList_Drop_SourceEntry), MEMF_CLEAR);
6672 if ((entry->type != ST_ROOT) && (entry->type != ST_SOFTLINK))
6674 int fulllen = 0;
6675 char *path = NULL;
6677 GET(message->obj, MUIA_IconDrawerList_Drawer, &path);
6678 /* Properly expand the location incase it uses devices rather than volumes */
6679 if (path != NULL)
6681 tmp_dirlock = Lock(path, SHARED_LOCK);
6682 if (tmp_dirlock)
6684 if (NameFromLock(tmp_dirlock, tmp_dirbuff, 256))
6686 path = tmp_dirbuff;
6688 UnLock(tmp_dirlock);
6691 if (strcasecmp(dragDropEvent->drop_TargetPath, path) != 0)
6693 fulllen = strlen(path) + strlen(entry->ile_IconEntry->ie_IconNode.ln_Name) + 2;
6694 sourceEntry->dropse_Node.ln_Name = AllocVec(fulllen, MEMF_CLEAR);
6695 strcpy(sourceEntry->dropse_Node.ln_Name, path);
6696 AddPart(sourceEntry->dropse_Node.ln_Name, entry->label, fulllen);
6697 #if defined(DEBUG_ILC_ICONDRAGDROP)
6698 D(bug("[IconList] %s: Source Entry (Full Path) = '%s'\n", __PRETTY_FUNCTION__, sourceEntry->dropse_Node.ln_Name));
6699 #endif
6703 else
6705 sourceEntry->dropse_Node.ln_Name = AllocVec(strlen(entry->label) + 1, MEMF_CLEAR);
6706 strcpy(sourceEntry->dropse_Node.ln_Name, entry->label);
6707 #if defined(DEBUG_ILC_ICONDRAGDROP)
6708 D(bug("[IconList] %s: Source Entry = '%s'\n", __PRETTY_FUNCTION__, sourceEntry->dropse_Node.ln_Name));
6709 #endif
6712 if ((sourceEntry->dropse_Node.ln_Name != NULL) && (strcasecmp(dragDropEvent->drop_TargetPath, sourceEntry->dropse_Node.ln_Name) != 0))
6714 copycount += 1;
6715 AddTail(&dragDropEvent->drop_SourceList, &sourceEntry->dropse_Node);
6717 else
6719 #if defined(DEBUG_ILC_ICONDRAGDROP)
6720 D(bug("[IconList] %s: Source == Dest, Skipping!\n", __PRETTY_FUNCTION__));
6721 #endif
6722 if ( sourceEntry->dropse_Node.ln_Name) FreeVec(sourceEntry->dropse_Node.ln_Name);
6723 FreeMem(sourceEntry, sizeof(struct IconList_Drop_SourceEntry));
6727 if (copycount > 0)
6729 dragDropEvent->drop_TargetObj = (IPTR)obj;
6731 #if defined(DEBUG_ILC_ICONDRAGDROP)
6732 D(bug("[IconList] %s: Causing DROP notification..\n", __PRETTY_FUNCTION__));
6733 #endif
6734 SET(obj, MUIA_IconList_IconsDropped, (IPTR)dragDropEvent);
6735 DoMethod(obj, MUIM_IconList_CoordsSort);
6737 else
6739 if (dragDropEvent->drop_TargetPath) FreeVec(dragDropEvent->drop_TargetPath);
6740 FreeMem(dragDropEvent, sizeof(struct IconList_Drop_Event));
6744 else
6746 #if defined(DEBUG_ILC_ICONDRAGDROP)
6747 D(bug("[IconList] %s: BUG - DragDrop recieved with no source icons!\n", __PRETTY_FUNCTION__));
6748 #endif
6749 NNSET(obj, MUIA_IconList_IconsDropped, (IPTR)NULL);
6752 dragdropdone:
6753 return DoSuperMethodA(CLASS, obj, (Msg)message);
6757 ///MUIM_UnselectAll()
6758 /**************************************************************************
6759 MUIM_UnselectAll
6760 **************************************************************************/
6761 IPTR IconList__MUIM_IconList_UnselectAll(struct IClass *CLASS, Object *obj, Msg message)
6763 struct IconList_DATA *data = INST_DATA(CLASS, obj);
6764 struct Node *node = NULL, *next_node = NULL;
6765 BOOL changed = FALSE;
6767 #if defined(DEBUG_ILC_FUNCS)
6768 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
6769 #endif
6771 data->icld_SelectionLastClicked = NULL;
6772 data->icld_FocusIcon = NULL;
6773 #if defined(__AROS__)
6774 ForeachNodeSafe(&data->icld_SelectionList, node, next_node)
6775 #else
6776 Foreach_NodeSafe(&data->icld_SelectionList, node, next_node);
6777 #endif
6779 struct IconEntry *entry = (struct IconEntry *)((IPTR)node - ((IPTR)&entry->ie_SelectionNode - (IPTR)entry));
6780 BOOL update_entry = FALSE;
6782 if (entry->ie_Flags & ICONENTRY_FLAG_VISIBLE)
6784 if (entry->ie_Flags & ICONENTRY_FLAG_SELECTED)
6786 Remove(node);
6787 entry->ie_Flags &= ~ICONENTRY_FLAG_SELECTED;
6788 update_entry = TRUE;
6790 if (entry->ie_Flags & ICONENTRY_FLAG_FOCUS)
6792 entry->ie_Flags &= ~ICONENTRY_FLAG_FOCUS;
6793 update_entry = TRUE;
6797 if (update_entry)
6799 changed = TRUE;
6800 data->icld_UpdateMode = UPDATE_SINGLEENTRY;
6801 data->update_entry = entry;
6802 MUI_Redraw(obj, MADF_DRAWUPDATE);
6806 if (changed)
6807 SET(obj, MUIA_IconList_SelectionChanged, TRUE);
6809 return 1;
6813 ///MUIM_SelectAll()
6814 /**************************************************************************
6815 MUIM_SelectAll
6816 **************************************************************************/
6817 IPTR IconList__MUIM_IconList_SelectAll(struct IClass *CLASS, Object *obj, Msg message)
6819 struct IconList_DATA *data = INST_DATA(CLASS, obj);
6820 struct IconEntry *node = NULL;
6821 BOOL changed = FALSE;
6823 #if defined(DEBUG_ILC_FUNCS)
6824 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
6825 #endif
6827 node = (struct IconEntry *)GetHead(&data->icld_IconList);
6829 while (node != NULL)
6831 if (node->ie_Flags & ICONENTRY_FLAG_VISIBLE)
6833 BOOL update_entry = FALSE;
6835 if (!(node->ie_Flags & ICONENTRY_FLAG_SELECTED))
6837 AddTail(&data->icld_SelectionList, &node->ie_SelectionNode);
6838 node->ie_Flags |= ICONENTRY_FLAG_SELECTED;
6839 update_entry = TRUE;
6841 data->icld_SelectionLastClicked = node;
6843 else if (node->ie_Flags & ICONENTRY_FLAG_FOCUS)
6845 node->ie_Flags &= ~ICONENTRY_FLAG_FOCUS;
6846 update_entry = TRUE;
6849 if (update_entry)
6851 changed = TRUE;
6852 data->icld_UpdateMode = UPDATE_SINGLEENTRY;
6853 data->update_entry = node;
6854 MUI_Redraw(obj, MADF_DRAWUPDATE);
6857 node = (struct IconEntry *)GetSucc(&node->ie_IconNode);
6860 if ((data->icld_SelectionLastClicked) && (data->icld_SelectionLastClicked != data->icld_FocusIcon))
6862 data->icld_FocusIcon = data->icld_SelectionLastClicked;
6863 if (!(data->icld_FocusIcon->ie_Flags & ICONENTRY_FLAG_FOCUS))
6865 data->icld_FocusIcon->ie_Flags &= ~ICONENTRY_FLAG_FOCUS;
6866 data->icld_FocusIcon->ie_Flags |= ICONENTRY_FLAG_FOCUS;
6867 data->icld_UpdateMode = UPDATE_SINGLEENTRY;
6868 data->update_entry = data->icld_FocusIcon;
6869 MUI_Redraw(obj, MADF_DRAWUPDATE);
6873 if (changed)
6874 SET(obj, MUIA_IconList_SelectionChanged, TRUE);
6876 return 1;
6880 ///IconList__MUIM_IconList_CoordsSort()
6881 IPTR IconList__MUIM_IconList_CoordsSort(struct IClass *CLASS, Object *obj, struct MUIP_IconList_Sort *message)
6883 struct IconList_DATA *data = INST_DATA(CLASS, obj);
6885 struct IconEntry *entry = NULL,
6886 *test_icon = NULL;
6888 struct List list_VisibleIcons;
6889 struct List list_HiddenIcons;
6890 struct List list_UnplacedIcons;
6893 perform a quick sort of the iconlist based on entry coords
6894 this method DOESNT cause any visual output.
6896 #if defined(DEBUG_ILC_FUNCS) || defined(DEBUG_ILC_ICONSORTING)
6897 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
6898 #endif
6900 NewList((struct List*)&list_VisibleIcons);
6901 NewList((struct List*)&list_HiddenIcons);
6903 /*move list into our local list struct(s)*/
6904 while ((entry = (struct IconEntry *)RemTail((struct List*)&data->icld_IconList)))
6906 if (entry->ie_Flags & ICONENTRY_FLAG_VISIBLE)
6908 AddHead((struct List*)&list_VisibleIcons, (struct Node *)&entry->ie_IconNode);
6910 else
6911 AddHead((struct List*)&list_HiddenIcons, (struct Node *)&entry->ie_IconNode);
6914 while ((entry = (struct IconEntry *)RemTail((struct List*)&list_VisibleIcons)))
6916 if ((test_icon = (struct IconEntry *)GetTail(&data->icld_IconList)) != NULL)
6918 while (test_icon != NULL)
6920 if (((data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL) && (test_icon->ie_IconX > entry->ie_IconX)) ||
6921 (!(data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL) && (test_icon->ie_IconY > entry->ie_IconY)))
6923 test_icon = (struct IconEntry *)GetPred(&test_icon->ie_IconNode);
6924 continue;
6926 else break;
6929 while (test_icon != NULL)
6931 if (((data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL) && (test_icon->ie_IconY > entry->ie_IconY)) ||
6932 (!(data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL) && (test_icon->ie_IconX > entry->ie_IconX)))
6934 test_icon = (struct IconEntry *)GetPred(&test_icon->ie_IconNode);
6935 continue;
6937 else break;
6939 Insert((struct List*)&data->icld_IconList, (struct Node *)&entry->ie_IconNode, (struct Node *)&test_icon->ie_IconNode);
6941 else
6942 AddTail((struct List*)&data->icld_IconList, (struct Node *)&entry->ie_IconNode);
6944 #if defined(DEBUG_ILC_ICONSORTING)
6945 D(bug("[IconList] %s: Done\n", __PRETTY_FUNCTION__));
6946 #endif
6948 while ((entry = (struct IconEntry *)RemTail((struct List*)&list_HiddenIcons)))
6950 AddTail((struct List*)&data->icld_IconList, (struct Node *)&entry->ie_IconNode);
6953 #if defined(DEBUG_ILC_ICONSORTING_DUMP)
6954 #if defined(__AROS__)
6955 ForeachNode(&data->icld_IconList, entry)
6956 #else
6957 Foreach_Node(&data->icld_IconList, entry);
6958 #endif
6960 D(bug("[IconList] %s: %d %d '%s'\n", __PRETTY_FUNCTION__, entry->ie_IconX, entry->ie_IconY, entry->ie_IconListEntry.label));
6962 #endif
6964 return TRUE;
6968 ///MUIM_Sort()
6969 /**************************************************************************
6970 MUIM_Sort - sortsort
6971 **************************************************************************/
6972 IPTR IconList__MUIM_IconList_Sort(struct IClass *CLASS, Object *obj, struct MUIP_IconList_Sort *message)
6974 struct IconList_DATA *data = INST_DATA(CLASS, obj);
6975 struct IconEntry *entry = NULL,
6976 *icon1 = NULL,
6977 *icon2 = NULL;
6979 struct List list_VisibleIcons,
6980 list_SortedIcons,
6981 list_HiddenIcons;
6983 BOOL sortme, reversable = TRUE, enqueue = FALSE;
6984 int i, visible_count = 0;
6986 #if defined(DEBUG_ILC_FUNCS) || defined(DEBUG_ILC_ICONSORTING)
6987 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
6988 #endif
6990 /* Reset incase view options have changed .. */
6991 data->icld_IconAreaLargestWidth = 0;
6992 data->icld_IconAreaLargestHeight = 0;
6993 data->icld_IconLargestHeight = 0;
6994 data->icld_LabelLargestHeight = 0;
6996 #if defined(DEBUG_ILC_ICONSORTING)
6997 D(bug("[IconList] %s: Sort-Flags : %x\n", __PRETTY_FUNCTION__, (data->icld_SortFlags & MUIV_IconList_Sort_MASK)));
6998 #endif
6999 NewList((struct List*)&list_VisibleIcons);
7000 NewList((struct List*)&list_SortedIcons);
7001 NewList((struct List*)&list_HiddenIcons);
7003 /*move list into our local list struct(s)*/
7004 while ((entry = (struct IconEntry *)RemTail((struct List*)&data->icld_IconList)))
7006 if (entry->ie_DiskObj)
7008 if (entry->ie_IconX != entry->ie_DiskObj->do_CurrentX)
7010 entry->ie_IconX = entry->ie_DiskObj->do_CurrentX;
7011 if ((data->icld_SortFlags & MUIV_IconList_Sort_MASK) == 0)
7012 entry->ie_Flags |= ICONENTRY_FLAG_NEEDSUPDATE;
7014 if (entry->ie_IconY != entry->ie_DiskObj->do_CurrentY)
7016 entry->ie_IconY = entry->ie_DiskObj->do_CurrentY;
7017 if ((data->icld_SortFlags & MUIV_IconList_Sort_MASK) == 0)
7018 entry->ie_Flags |= ICONENTRY_FLAG_NEEDSUPDATE;
7022 if (!(entry->ie_Flags & ICONENTRY_FLAG_HASICON))
7024 if (data->icld_DisplayFlags & ICONLIST_DISP_SHOWINFO)
7026 if (entry->ie_Flags & ICONENTRY_FLAG_VISIBLE)
7028 entry->ie_Flags &= ~(ICONENTRY_FLAG_VISIBLE|ICONENTRY_FLAG_NEEDSUPDATE);
7031 else if (!(entry->ie_Flags & ICONENTRY_FLAG_VISIBLE))
7033 entry->ie_Flags |= (ICONENTRY_FLAG_VISIBLE|ICONENTRY_FLAG_NEEDSUPDATE);
7036 else
7038 if (!(entry->ie_Flags & ICONENTRY_FLAG_VISIBLE))
7040 entry->ie_Flags |= (ICONENTRY_FLAG_VISIBLE|ICONENTRY_FLAG_NEEDSUPDATE);
7044 /* Now we have fixed visibility lets dump them into the correct list for sorting */
7045 if (entry->ie_Flags & ICONENTRY_FLAG_VISIBLE)
7047 if(entry->ie_AreaWidth > data->icld_IconAreaLargestWidth) data->icld_IconAreaLargestWidth = entry->ie_AreaWidth;
7048 if(entry->ie_AreaHeight > data->icld_IconAreaLargestHeight) data->icld_IconAreaLargestHeight = entry->ie_AreaHeight;
7049 if(entry->ie_IconHeight > data->icld_IconLargestHeight) data->icld_IconLargestHeight = entry->ie_IconHeight;
7050 if((entry->ie_AreaHeight - entry->ie_IconHeight) > data->icld_LabelLargestHeight) data->icld_LabelLargestHeight = entry->ie_AreaHeight - entry->ie_IconHeight;
7052 if (((data->icld_SortFlags & MUIV_IconList_Sort_MASK) == 0) && (entry->ie_IconX == NO_ICON_POSITION))
7053 AddTail((struct List*)&list_VisibleIcons, (struct Node *)&entry->ie_IconNode);
7054 else
7055 AddHead((struct List*)&list_VisibleIcons, (struct Node *)&entry->ie_IconNode);
7056 visible_count++;
7058 else
7060 if (entry->ie_Flags & ICONENTRY_FLAG_SELECTED)
7062 Remove(&entry->ie_SelectionNode);
7064 entry->ie_Flags &= ~(ICONENTRY_FLAG_SELECTED|ICONENTRY_FLAG_FOCUS);
7065 if (data->icld_SelectionLastClicked == entry) data->icld_SelectionLastClicked = NULL;
7066 if (data->icld_FocusIcon == entry) data->icld_FocusIcon = data->icld_SelectionLastClicked;
7067 AddHead((struct List*)&list_HiddenIcons, (struct Node *)&entry->ie_IconNode);
7071 /* Copy each visible entry back to the main list, sorting as we go*/
7072 while ((entry = (struct IconEntry *)RemHead((struct List*)&list_VisibleIcons)))
7074 icon1 = (struct IconEntry *)GetHead(&list_SortedIcons);
7075 icon2 = NULL;
7077 sortme = FALSE;
7079 if (visible_count > 1)
7081 #if defined(DEBUG_ILC_ICONSORTING)
7082 D(bug("[IconList] %s: - %s %s %s %i\n", __PRETTY_FUNCTION__, entry->ie_IconListEntry.label, entry->ie_TxtBuf_DATE, entry->ie_TxtBuf_TIME, entry->ie_FileInfoBlock->fib_Size));
7083 #endif
7084 while (icon1)
7086 if(((icon1->ie_IconListEntry.type == ST_ROOT) || (icon1->ie_IconListEntry.type == ST_LINKDIR) || (icon1->ie_IconListEntry.type == ST_LINKFILE))
7087 || (data->icld_SortFlags & MUIV_IconList_Sort_DrawersMixed))
7089 /*volume list or drawers mixed*/
7090 sortme = TRUE;
7092 else
7094 /*drawers first*/
7095 if ((icon1->ie_IconListEntry.type == ST_USERDIR) && (entry->ie_IconListEntry.type == ST_USERDIR))
7097 sortme = TRUE;
7099 else
7101 if ((icon1->ie_IconListEntry.type != ST_USERDIR) && (entry->ie_IconListEntry.type != ST_USERDIR))
7102 sortme = TRUE;
7103 else
7105 /* we are the first drawer to arrive or we need to insert ourselves
7106 due to being sorted to the end of the drawers*/
7108 if ((!icon2 || icon2->ie_IconListEntry.type == ST_USERDIR) &&
7109 (entry->ie_IconListEntry.type == ST_USERDIR) &&
7110 (icon1->ie_IconListEntry.type != ST_USERDIR))
7112 #if defined(DEBUG_ILC_ICONSORTING)
7113 D(bug("[IconList] %s: force %s\n", __PRETTY_FUNCTION__, entry->ie_IconListEntry.label));
7114 #endif
7115 break;
7121 if (sortme)
7123 i = 0;
7125 if ((data->icld_SortFlags & MUIV_IconList_Sort_MASK) == 0)
7127 if ((entry->ie_IconX != NO_ICON_POSITION) && (entry->ie_IconY != NO_ICON_POSITION))
7129 i = 1;
7133 if (i == 0)
7135 if ((data->icld_SortFlags & MUIV_IconList_Sort_MASK) == MUIV_IconList_Sort_ByDate)
7137 /* Sort by Date */
7138 i = CompareDates((const struct DateStamp *)&entry->ie_FileInfoBlock->fib_Date,(const struct DateStamp *)&icon1->ie_FileInfoBlock->fib_Date);
7140 else if ((data->icld_SortFlags & MUIV_IconList_Sort_MASK) == MUIV_IconList_Sort_BySize)
7142 /* Sort by Size .. */
7143 i = entry->ie_FileInfoBlock->fib_Size - icon1->ie_FileInfoBlock->fib_Size;
7145 else if (((data->icld_SortFlags & MUIV_IconList_Sort_MASK) == MUIV_IconList_Sort_MASK) && ((entry->ie_IconListEntry.type == ST_FILE) || (entry->ie_IconListEntry.type == ST_USERDIR)))
7147 /* Sort by Type .. */
7148 #warning "TODO: Sort icons based on type using datatypes"
7150 else
7152 /* Sort by Name .. */
7153 i = Stricmp(entry->ie_IconListEntry.label, icon1->ie_IconListEntry.label);
7154 if ((data->icld_SortFlags & MUIV_IconList_Sort_MASK) == MUIV_IconList_Sort_MASK)
7156 enqueue = TRUE;
7161 if ((reversable) && data->icld_SortFlags & MUIV_IconList_Sort_Reverse)
7163 if (i > 0)
7164 break;
7166 else if (i < 0)
7167 break;
7169 icon2 = icon1;
7170 icon1 = (struct IconEntry *)GetSucc(&icon1->ie_IconNode);
7173 Insert((struct List*)&list_SortedIcons, (struct Node *)&entry->ie_IconNode, (struct Node *)&icon2->ie_IconNode);
7175 if (enqueue)
7177 /* Quickly resort based on node priorities .. */
7178 while ((entry = (struct IconEntry *)RemHead((struct List*)&list_SortedIcons)))
7180 Enqueue((struct List*)&data->icld_IconList, (struct Node *)&entry->ie_IconNode);
7183 else
7185 while ((entry = (struct IconEntry *)RemHead((struct List*)&list_SortedIcons)))
7187 AddTail((struct List*)&data->icld_IconList, (struct Node *)&entry->ie_IconNode);
7191 DoMethod(obj, MUIM_IconList_PositionIcons);
7192 MUI_Redraw(obj, MADF_DRAWOBJECT);
7194 if ((data->icld_SortFlags & MUIV_IconList_Sort_MASK) != 0)
7196 DoMethod(obj, MUIM_IconList_CoordsSort);
7198 /* leave hidden icons on a seperate list to speed up normal list parsing ? */
7199 while ((entry = (struct IconEntry *)RemHead((struct List*)&list_HiddenIcons)))
7201 AddTail((struct List*)&data->icld_IconList, (struct Node *)&entry->ie_IconNode);
7204 SET(obj, MUIA_IconList_Changed, TRUE);
7206 return 1;
7210 ///MUIM_DragReport()
7211 /**************************************************************************
7212 MUIM_DragReport. Since MUI doesn't change the drop object if the dragged
7213 object is moved above another window (while still in the bounds of the
7214 orginal drop object) we must do it here manually to be compatible with
7215 MUI. Maybe Zune should fix this bug somewhen.
7216 **************************************************************************/
7217 IPTR IconList__MUIM_DragReport(struct IClass *CLASS, Object *obj, struct MUIP_DragReport *message)
7219 struct Window *wnd = _window(obj);
7220 struct Layer *l = NULL;
7222 #if defined(DEBUG_ILC_FUNCS) || defined(DEBUG_ILC_ICONDRAGDROP)
7223 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
7224 #endif
7226 l = WhichLayer(&wnd->WScreen->LayerInfo, wnd->LeftEdge + message->x, wnd->TopEdge + message->y);
7228 if (l != wnd->WLayer) return MUIV_DragReport_Abort;
7230 return MUIV_DragReport_Continue;
7234 ///MUIM_IconList_UnknownDropDestination()
7235 /**************************************************************************
7236 MUIM_IconList_UnknownDropDestination
7237 **************************************************************************/
7238 IPTR IconList__MUIM_UnknownDropDestination(struct IClass *CLASS, Object *obj, struct MUIP_UnknownDropDestination *message)
7240 #if defined(DEBUG_ILC_FUNCS) || defined(DEBUG_ILC_ICONDRAGDROP)
7241 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
7242 #endif
7243 #if defined(DEBUG_ILC_ICONDRAGDROP)
7244 D(bug("[IconList] %s: icons dropped on custom window \n", __PRETTY_FUNCTION__));
7245 #endif
7247 SET(obj, MUIA_IconList_AppWindowDrop, (IPTR)message); /* Now notify */
7249 return (IPTR)NULL;
7253 ///MUIM_IconList_MakeEntryVisible()
7254 /**************************************************************************
7255 Move the visible area so that the selected entry becomes visible ..
7256 **************************************************************************/
7257 IPTR IconList__MUIM_IconList_MakeEntryVisible(struct IClass *CLASS, Object *obj, struct MUIP_IconList_MakeEntryVisible *message)
7259 struct IconList_DATA *data = INST_DATA(CLASS, obj);
7260 BOOL viewmoved = FALSE;
7261 struct Rectangle iconrect, viewrect;
7263 #if defined(DEBUG_ILC_FUNCS)
7264 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
7265 #endif
7267 viewrect.MinX = data->icld_ViewX;
7268 viewrect.MaxX = data->icld_ViewX + data->icld_AreaWidth;
7269 viewrect.MinY = data->icld_ViewY;
7270 viewrect.MaxY = data->icld_ViewY + data->icld_AreaHeight;
7272 IconList_GetIconAreaRectangle(obj, data, message->entry, &iconrect);
7274 if (!(RectAndRect(&viewrect, &iconrect)))
7276 viewmoved = TRUE;
7277 if (message->entry->ie_IconX < data->icld_ViewX)
7278 data->icld_ViewX = message->entry->ie_IconX;
7279 else if (message->entry->ie_IconX > (data->icld_ViewX + data->icld_AreaWidth))
7280 data->icld_ViewX = (message->entry->ie_IconX + message->entry->ie_AreaWidth) - data->icld_AreaWidth;
7282 if (message->entry->ie_IconY < data->icld_ViewY)
7283 data->icld_ViewY = message->entry->ie_IconX;
7284 else if (message->entry->ie_IconY > (data->icld_ViewY + data->icld_AreaHeight))
7285 data->icld_ViewY = (message->entry->ie_IconY + message->entry->ie_AreaHeight) - data->icld_AreaHeight;
7288 if (viewmoved)
7290 #if defined(DEBUG_ILC_ICONRENDERING)
7291 D(bug("[IconList]: %s: call SetSuperAttrs()\n", __PRETTY_FUNCTION__));
7292 #endif
7293 SetSuperAttrs(CLASS, obj, MUIA_Virtgroup_Left, data->icld_ViewX,
7294 MUIA_Virtgroup_Top, data->icld_ViewY,
7295 TAG_DONE);
7297 #if defined(DEBUG_ILC_ICONRENDERING)
7298 D(bug("[IconList]: %s: call SetAttrs()\n", __PRETTY_FUNCTION__));
7299 #endif
7300 SetAttrs(obj, MUIA_Virtgroup_Left, data->icld_ViewX,
7301 MUIA_Virtgroup_Top, data->icld_ViewY,
7302 TAG_DONE);
7304 #if defined(DEBUG_ILC_ICONRENDERING)
7305 D(bug("[IconList]: %s: call MUI_Redraw()\n", __PRETTY_FUNCTION__));
7306 #endif
7307 MUI_Redraw(obj,MADF_DRAWOBJECT);
7309 return 1;
7312 #if defined(WANDERER_BUILTIN_ICONLIST)
7313 BOOPSI_DISPATCHER(IPTR,IconList_Dispatcher, CLASS, obj, message)
7315 #if defined(__AROS__)
7316 switch (message->MethodID)
7317 #else
7318 struct IClass *CLASS = cl;
7319 Msg message = msg;
7321 switch (msg->MethodID)
7322 #endif
7324 case OM_NEW: return IconList__OM_NEW(CLASS, obj, (struct opSet *)message);
7325 case OM_DISPOSE: return IconList__OM_DISPOSE(CLASS, obj, message);
7326 case OM_SET: return IconList__OM_SET(CLASS, obj, (struct opSet *)message);
7327 case OM_GET: return IconList__OM_GET(CLASS, obj, (struct opGet *)message);
7328 case OM_ADDMEMBER:
7329 case MUIM_Family_AddTail: return IconList__MUIM_Family_AddTail(CLASS, obj, (APTR)message);
7330 case MUIM_Family_AddHead: return IconList__MUIM_Family_AddHead(CLASS, obj, (APTR)message);
7331 case OM_REMMEMBER:
7332 case MUIM_Family_Remove: return IconList__MUIM_Family_Remove(CLASS, obj, (APTR)message);
7334 case MUIM_Setup: return IconList__MUIM_Setup(CLASS, obj, (struct MUIP_Setup *)message);
7336 case MUIM_Show: return IconList__MUIM_Show(CLASS,obj, (struct MUIP_Show *)message);
7337 case MUIM_Hide: return IconList__MUIM_Hide(CLASS,obj, (struct MUIP_Hide *)message);
7338 case MUIM_Cleanup: return IconList__MUIM_Cleanup(CLASS, obj, (struct MUIP_Cleanup *)message);
7339 case MUIM_AskMinMax: return IconList__MUIM_AskMinMax(CLASS, obj, (struct MUIP_AskMinMax *)message);
7340 case MUIM_Draw: return IconList__MUIM_Draw(CLASS, obj, (struct MUIP_Draw *)message);
7341 #if defined(__AROS__)
7342 case MUIM_Layout: return IconList__MUIM_Layout(CLASS, obj, (struct MUIP_Layout *)message);
7343 #endif
7344 case MUIM_HandleEvent: return IconList__MUIM_HandleEvent(CLASS, obj, (struct MUIP_HandleEvent *)message);
7345 case MUIM_CreateDragImage: return IconList__MUIM_CreateDragImage(CLASS, obj, (APTR)message);
7346 case MUIM_DeleteDragImage: return IconList__MUIM_DeleteDragImage(CLASS, obj, (APTR)message);
7347 case MUIM_DragQuery: return IconList__MUIM_DragQuery(CLASS, obj, (APTR)message);
7348 case MUIM_DragReport: return IconList__MUIM_DragReport(CLASS, obj, (APTR)message);
7349 case MUIM_DragDrop: return IconList__MUIM_DragDrop(CLASS, obj, (APTR)message);
7350 #if defined(__AROS__)
7351 case MUIM_UnknownDropDestination: return IconList__MUIM_UnknownDropDestination(CLASS, obj, (APTR)message);
7352 #endif
7353 case MUIM_IconList_Update: return IconList__MUIM_IconList_Update(CLASS, obj, (APTR)message);
7354 case MUIM_IconList_Clear: return IconList__MUIM_IconList_Clear(CLASS, obj, (APTR)message);
7355 case MUIM_IconList_RethinkDimensions: return IconList__MUIM_IconList_RethinkDimensions(CLASS, obj, (APTR)message);
7356 case MUIM_IconList_CreateEntry: return IconList__MUIM_IconList_CreateEntry(CLASS, obj, (APTR)message);
7357 case MUIM_IconList_UpdateEntry: return IconList__MUIM_IconList_UpdateEntry(CLASS, obj, (APTR)message);
7358 case MUIM_IconList_DestroyEntry: return IconList__MUIM_IconList_DestroyEntry(CLASS, obj, (APTR)message);
7359 case MUIM_IconList_DrawEntry: return IconList__MUIM_IconList_DrawEntry(CLASS, obj, (APTR)message);
7360 case MUIM_IconList_DrawEntryLabel: return IconList__MUIM_IconList_DrawEntryLabel(CLASS, obj, (APTR)message);
7361 case MUIM_IconList_NextIcon: return IconList__MUIM_IconList_NextIcon(CLASS, obj, (APTR)message);
7362 case MUIM_IconList_GetIconPrivate: return IconList__MUIM_IconList_GetIconPrivate(CLASS, obj, (APTR)message);
7363 case MUIM_IconList_UnselectAll: return IconList__MUIM_IconList_UnselectAll(CLASS, obj, (APTR)message);
7364 case MUIM_IconList_Sort: return IconList__MUIM_IconList_Sort(CLASS, obj, (APTR)message);
7365 case MUIM_IconList_CoordsSort: return IconList__MUIM_IconList_CoordsSort(CLASS, obj, (APTR)message);
7366 case MUIM_IconList_PositionIcons: return IconList__MUIM_IconList_PositionIcons(CLASS, obj, (APTR)message);
7367 case MUIM_IconList_SelectAll: return IconList__MUIM_IconList_SelectAll(CLASS, obj, (APTR)message);
7368 case MUIM_IconList_MakeEntryVisible: return IconList__MUIM_IconList_MakeEntryVisible(CLASS, obj, (APTR)message);
7371 return DoSuperMethodA(CLASS, obj, message);
7373 BOOPSI_DISPATCHER_END
7375 #if defined(__AROS__)
7376 /* Class descriptor. */
7377 const struct __MUIBuiltinClass _MUI_IconList_desc = {
7378 MUIC_IconList,
7379 MUIC_Area,
7380 sizeof(struct IconList_DATA),
7381 (void*)IconList_Dispatcher
7383 #endif
7384 #endif /* WANDERER_BUILTIN_ICONLIST */
7386 #if !defined(__AROS__)
7387 struct MUI_CustomClass *initIconListClass(void)
7389 return (struct MUI_CustomClass *) MUI_CreateCustomClass(NULL, MUIC_Area, NULL, sizeof(struct IconList_DATA), ENTRY(IconList_Dispatcher));
7391 #endif