Add some List View-Mode rendering controls
[AROS.git] / workbench / system / Wanderer / Classes / iconlist.c
blobc3043279b4288a256778e13ed5ceac6739d0f74f
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_SINGLEENTRY 1
133 #define UPDATE_SCROLL 2
134 #define UPDATE_RESIZE 4
136 #define LEFT_BUTTON 1
137 #define RIGHT_BUTTON 2
138 #define MIDDLE_BUTTON 4
140 #define ICONLIST_DRAWMODE_NORMAL 1
141 #define ICONLIST_DRAWMODE_FAST 2
143 /* Values used for List View-Mode */
144 #define COLOR_COLUMN_BACKGROUND 0
145 #define COLOR_COLUMN_BACKGROUND_SORTED 1
146 #define COLOR_COLUMN_BACKGROUND_LASSO 2
147 #define COLOR_COLUMN_BACKGROUND_LASSO_SORTED 3
149 #define COLOR_SELECTED_BACKGROUND 4
150 #define COLOR_SELECTED_BACKGROUND_SORTED 5
152 #define MIN_COLUMN_WIDTH 10
154 #define COLUMN_ALIGN_LEFT 0
155 #define COLUMN_ALIGN_CENTER 1
156 #define COLUMN_ALIGN_RIGHT 2
158 #define LINE_SPACING_TOP 2
159 #define LINE_SPACING_BOTTOM 2
160 #define LINE_EXTRAHEIGHT (LINE_SPACING_TOP + LINE_SPACING_BOTTOM)
162 #define LINE_SPACING_LEFT 1
163 #define LINE_SPACING_RIGHT 1
164 #define LINE_EXTRAWIDTH (LINE_SPACING_LEFT + LINE_SPACING_RIGHT)
166 #define ENTRY_SPACING_LEFT 1
167 #define ENTRY_SPACING_RIGHT 1
168 #define ENTRY_EXTRAWIDTH (ENTRY_SPACING_LEFT + ENTRY_SPACING_RIGHT)
170 #define HEADERLINE_SPACING_TOP 3
171 #define HEADERLINE_SPACING_BOTTOM 3
172 #define HEADERLINE_EXTRAHEIGHT (HEADERLINE_SPACING_TOP + HEADERLINE_SPACING_BOTTOM)
174 #define HEADERLINE_SPACING_LEFT 1
175 #define HEADERLINE_SPACING_RIGHT 1
176 #define HEADERLINE_EXTRAWIDTH (HEADERLINE_SPACING_LEFT + HEADERLINE_SPACING_RIGHT)
178 #define HEADERENTRY_SPACING_LEFT 4
179 #define HEADERENTRY_SPACING_RIGHT 4
180 #define HEADERENTRY_EXTRAWIDTH (HEADERENTRY_SPACING_LEFT + HEADERENTRY_SPACING_RIGHT)
182 enum
184 INDEX_NAME,
185 INDEX_SIZE,
186 INDEX_PROTECTION,
187 INDEX_DATE,
188 INDEX_TIME,
189 INDEX_COMMENT
192 /**************************************************************************
193 Support Functions
194 **************************************************************************/
196 #define ForeachNodeReversed(list, node) \
197 for \
199 node = (void *)(((struct List *)(list))->lh_TailPred); \
200 ((struct Node *)(node))->ln_Pred; \
201 node = (void *)(((struct Node *)(node))->ln_Pred) \
204 #if defined(AndRectRect)
205 /* Fine */
206 #else
207 #if defined(__AROS__)
208 #error "Implement AndRectRect (rom/graphics/andrectrect.c)"
209 #else
210 #warning "Implement AndRectRect (rom/graphics/andrectrect.c)"
211 #endif
212 #endif
214 #define RPALPHAFLAT (1 << 0)
215 #define RPALPHARADIAL (1 << 1)
217 static void RastPortSetAlpha(struct RastPort *arport, ULONG ax, ULONG ay, ULONG width, ULONG height, UBYTE val, UBYTE alphamode)
219 ULONG x, y;
220 ULONG alphaval, pixelval;
222 for (y = 0; y < height; y++)
224 for (x = 0; x < width; x++)
226 if ((pixelval = ReadRGBPixel(arport, x, y)))
228 if (alphamode == RPALPHARADIAL){
229 //Set the alpha value based on distance from ax,ay
230 } else {
231 alphaval = val;
233 WriteRGBPixel(arport, x, y, ((pixelval & 0xffffff)|(alphaval << 24)));
239 ///RectAndRect()
240 // Icon/Label Area support functions
241 static int RectAndRect(struct Rectangle *a, struct Rectangle *b)
243 if ((a->MinX > b->MaxX) || (a->MinY > b->MaxY) || (a->MaxX < b->MinX) || (a->MaxY < b->MinY))
244 return 0;
245 return 1;
249 ///Node_NextVisible()
250 // IconEntry List navigation functions ..
251 static struct IconEntry *Node_NextVisible(struct IconEntry *current_Node)
253 current_Node = (struct IconEntry *)GetSucc(&current_Node->ie_IconNode);
254 while ((current_Node != NULL) && (!(current_Node->ie_Flags & ICONENTRY_FLAG_VISIBLE)))
256 current_Node = (struct IconEntry *)GetSucc(&current_Node->ie_IconNode);
258 return current_Node;
262 ///Node_FirstVisible()
263 static struct IconEntry *Node_FirstVisible(struct List *icon_list)
265 struct IconEntry *current_Node = (struct IconEntry *)GetHead(icon_list);
267 if ((current_Node != NULL) && !(current_Node->ie_Flags & ICONENTRY_FLAG_VISIBLE))
268 current_Node = Node_NextVisible(current_Node);
270 return current_Node;
274 ///Node_PreviousVisible()
275 static struct IconEntry *Node_PreviousVisible(struct IconEntry *current_Node)
277 current_Node = (struct IconEntry *)GetPred(&current_Node->ie_IconNode);
278 while ((current_Node != NULL) && (!(current_Node->ie_Flags & ICONENTRY_FLAG_VISIBLE)))
280 current_Node = (struct IconEntry *)GetPred(&current_Node->ie_IconNode);
282 return current_Node;
286 ///Node_LastVisible()
287 static struct IconEntry *Node_LastVisible(struct List *icon_list)
289 struct IconEntry *current_Node = (struct IconEntry *)GetTail(icon_list);
291 if ((current_Node != NULL) && !(current_Node->ie_Flags & ICONENTRY_FLAG_VISIBLE))
292 current_Node = Node_PreviousVisible(current_Node);
294 return current_Node;
298 const UBYTE MSG_MEM_G[] = "GB";
299 const UBYTE MSG_MEM_M[] = "MB";
300 const UBYTE MSG_MEM_K[] = "KB";
301 const UBYTE MSG_MEM_B[] = "Bytes";
303 ///FmtSizeToString()
304 static void FmtSizeToString(UBYTE *buf, ULONG num)
306 UQUAD d;
307 UBYTE *ch;
308 struct
310 IPTR val;
311 IPTR dec;
312 } array =
314 num,
318 if (num >= 1073741824)
320 //Gigabytes
321 array.val = num >> 30;
322 d = ((UQUAD)num * 10 + 536870912) / 1073741824;
323 array.dec = d % 10;
324 ch = MSG_MEM_G;
326 else if (num >= 1048576)
328 //Megabytes
329 array.val = num >> 20;
330 d = ((UQUAD)num * 10 + 524288) / 1048576;
331 array.dec = d % 10;
332 ch = MSG_MEM_M;
334 else if (num >= 1024)
336 //Kilobytes
337 array.val = num >> 10;
338 d = (num * 10 + 512) / 1024;
339 array.dec = d % 10;
340 ch = MSG_MEM_K;
342 else
344 //Bytes
345 array.val = num;
346 array.dec = 0;
347 d = 0;
348 ch = MSG_MEM_B;
351 if (!array.dec && (d > array.val * 10))
353 array.val++;
356 RawDoFmt(array.dec ? "%lu.%lu" : "%lu", &array, NULL, buf);
358 while (*buf)
360 buf++;
363 sprintf(buf, " %s", ch);
367 ///GetAbsoluteLassoRect()
368 // get positive lasso coords
369 static void GetAbsoluteLassoRect(struct IconList_DATA *data, struct Rectangle *LassoRectangle)
371 WORD minx = data->icld_LassoRectangle.MinX;
372 WORD miny = data->icld_LassoRectangle.MinY;
373 WORD maxx = data->icld_LassoRectangle.MaxX;
374 WORD maxy = data->icld_LassoRectangle.MaxY;
376 #if defined(DEBUG_ILC_LASSO) && defined(DEBUG_ILC_FUNCS)
377 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
378 #endif
380 if (minx > maxx)
382 /* Swap minx, maxx */
383 minx ^= maxx;
384 maxx ^= minx;
385 minx ^= maxx;
388 if (miny > maxy)
390 /* Swap miny, maxy */
391 miny ^= maxy;
392 maxy ^= miny;
393 miny ^= maxy;
396 LassoRectangle->MinX = data->view_rect.MinX - data->icld_ViewX + minx;
397 LassoRectangle->MinY = data->view_rect.MinY - data->icld_ViewY + miny;
398 LassoRectangle->MaxX = data->view_rect.MinX - data->icld_ViewX + maxx;
399 LassoRectangle->MaxY = data->view_rect.MinY - data->icld_ViewY + maxy;
403 ///IconList_InvertPixelRect()
404 static void IconList_InvertPixelRect(struct RastPort *rp, WORD minx, WORD miny, WORD maxx, WORD maxy, struct Rectangle *clip)
406 struct Rectangle r, clipped_r;
408 #if defined(DEBUG_ILC_RENDERING) && defined(DEBUG_ILC_FUNCS)
409 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
410 #endif
412 if (maxx < minx)
414 /* Swap minx, maxx */
415 minx ^= maxx;
416 maxx ^= minx;
417 minx ^= maxx;
420 if (maxy < miny)
422 /* Swap miny, maxy */
423 miny ^= maxy;
424 maxy ^= miny;
425 miny ^= maxy;
428 r.MinX = minx;
429 r.MinY = miny;
430 r.MaxX = maxx;
431 r.MaxY = maxy;
433 if (AndRectRect(&r, clip, &clipped_r))
435 InvertPixelArray(rp, clipped_r.MinX, clipped_r.MinY,
436 clipped_r.MaxX - clipped_r.MinX + 1, clipped_r.MaxY - clipped_r.MinY + 1);
441 ///IconList_InvertLassoOutlines()
442 // Simple lasso drawing by inverting area outlines
443 static void IconList_InvertLassoOutlines(Object *obj, struct Rectangle *rect)
445 struct Rectangle lasso;
446 struct Rectangle clip;
448 #if defined(DEBUG_ILC_LASSO) && defined(DEBUG_ILC_FUNCS)
449 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
450 #endif
452 /* get abolute iconlist coords */
453 lasso.MinX = rect->MinX + _mleft(obj);
454 lasso.MaxX = rect->MaxX + _mleft(obj);
455 lasso.MinY = rect->MinY + _mtop(obj);
456 lasso.MaxY = rect->MaxY + _mtop(obj);
458 clip.MinX = _mleft(obj);
459 clip.MinY = _mtop(obj);
460 clip.MaxX = _mright(obj);
461 clip.MaxY = _mbottom(obj);
463 /* horizontal lasso lines */
464 IconList_InvertPixelRect(_rp(obj), lasso.MinX, lasso.MinY, lasso.MaxX-1, lasso.MinY + 1, &clip);
465 IconList_InvertPixelRect(_rp(obj), lasso.MinX, lasso.MaxY, lasso.MaxX-1, lasso.MaxY + 1, &clip);
467 /* vertical lasso lines */
468 IconList_InvertPixelRect(_rp(obj), lasso.MinX, lasso.MinY, lasso.MinX + 1, lasso.MaxY - 1, &clip);
469 IconList_InvertPixelRect(_rp(obj), lasso.MaxX, lasso.MinY, lasso.MaxX + 1, lasso.MaxY - 1, &clip);
473 ///IconList_GetIconImageRectangle()
474 //We don't use icon.library's label drawing so we do this by hand
475 static void IconList_GetIconImageRectangle(Object *obj, struct IconList_DATA *data, struct IconEntry *icon, struct Rectangle *rect)
477 #if defined(DEBUG_ILC_ICONPOSITIONING) && defined(DEBUG_ILC_FUNCS)
478 D(bug("[IconList]: %s(icon @ %p)\n", __PRETTY_FUNCTION__, icon));
479 #endif
481 /* Get basic width/height */
482 GetIconRectangleA(NULL, icon->ie_DiskObj, NULL, rect, NULL);
483 #if defined(DEBUG_ILC_ICONPOSITIONING)
484 D(bug("[IconList] %s: MinX %d, MinY %d MaxX %d, MaxY %d\n", __PRETTY_FUNCTION__, rect->MinX, rect->MinY, rect->MaxX, rect->MaxY));
485 #endif
486 icon->ie_IconWidth = (rect->MaxX - rect->MinX) + 1;
487 icon->ie_IconHeight = (rect->MaxY - rect->MinY) + 1;
489 if (icon->ie_IconHeight > data->icld_IconLargestHeight)
490 data->icld_IconLargestHeight = icon->ie_IconHeight;
494 ///IconList_GetIconLabelRectangle()
495 static void IconList_GetIconLabelRectangle(Object *obj, struct IconList_DATA *data, struct IconEntry *icon, struct Rectangle *rect)
497 ULONG outline_offset = 0;
498 ULONG textwidth = 0;
500 #if defined(DEBUG_ILC_ICONPOSITIONING) && defined(DEBUG_ILC_FUNCS)
501 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
502 #endif
504 switch ( data->icld__Option_LabelTextMode )
506 case ICON_TEXTMODE_DROPSHADOW:
507 outline_offset = 1;
508 break;
510 case ICON_TEXTMODE_PLAIN:
511 break;
513 default:
514 outline_offset = 2;
515 break;
518 /* Get icon box width including text width */
519 if ((icon->ie_IconListEntry.label != NULL) && (icon->ie_TxtBuf_DisplayedLabel != NULL))
521 ULONG curlabel_TotalLines;
522 SetFont(data->icld_BufferRastPort, data->icld_IconLabelFont);
524 rect->MinX = 0;
525 rect->MaxX = (((data->icld__Option_LabelTextHorizontalPadding + data->icld__Option_LabelTextBorderWidth) * 2) + icon->ie_TxtBuf_DisplayedLabelWidth + outline_offset) - 1;
527 rect->MinY = 0;
529 curlabel_TotalLines = icon->ie_SplitParts;
530 if (curlabel_TotalLines == 0)
531 curlabel_TotalLines = 1;
532 if (curlabel_TotalLines > data->icld__Option_LabelTextMultiLine)
533 curlabel_TotalLines = data->icld__Option_LabelTextMultiLine;
535 rect->MaxY = (((data->icld__Option_LabelTextBorderHeight + data->icld__Option_LabelTextVerticalPadding) * 2) +
536 ((data->icld_IconLabelFont->tf_YSize + outline_offset) * curlabel_TotalLines)) - 1;
538 /* Date/size sorting has the date/size appended under the icon label
539 only list regular files like this (drawers have no size/date output) */
541 icon->ie_IconListEntry.type != ST_USERDIR &&
542 ((data->icld_SortFlags & MUIV_IconList_Sort_BySize) || (data->icld_SortFlags & MUIV_IconList_Sort_ByDate))
545 SetFont(data->icld_BufferRastPort, data->icld_IconInfoFont);
547 if( (data->icld_SortFlags & MUIV_IconList_Sort_BySize) && !(data->icld_SortFlags & MUIV_IconList_Sort_ByDate) )
549 icon->ie_TxtBuf_SIZEWidth = TextLength(data->icld_BufferRastPort, icon->ie_TxtBuf_SIZE, strlen(icon->ie_TxtBuf_SIZE));
550 textwidth = icon->ie_TxtBuf_SIZEWidth;
552 else
554 if( !(data->icld_SortFlags & MUIV_IconList_Sort_BySize) && (data->icld_SortFlags & MUIV_IconList_Sort_ByDate) )
556 if( icon->ie_Flags & ICONENTRY_FLAG_TODAY )
558 icon->ie_TxtBuf_TIMEWidth = TextLength(data->icld_BufferRastPort, icon->ie_TxtBuf_TIME, strlen(icon->ie_TxtBuf_TIME));
559 textwidth = icon->ie_TxtBuf_TIMEWidth;
561 else
563 icon->ie_TxtBuf_DATEWidth = TextLength(data->icld_BufferRastPort, icon->ie_TxtBuf_DATE, strlen(icon->ie_TxtBuf_DATE));
564 textwidth = icon->ie_TxtBuf_DATEWidth;
569 if (textwidth > 0)
571 rect->MaxY = rect->MaxY + data->icld_IconInfoFont->tf_YSize + outline_offset;
572 if ((textwidth + outline_offset + ((data->icld__Option_LabelTextHorizontalPadding + data->icld__Option_LabelTextBorderWidth) * 2)) > ((rect->MaxX - rect->MinX) + 1))
573 rect->MaxX = (textwidth + outline_offset + ((data->icld__Option_LabelTextVerticalPadding + data->icld__Option_LabelTextBorderWidth) * 2)) - 1;
577 if (((rect->MaxY - rect->MinY) + 1) > data->icld_LabelLargestHeight) data->icld_LabelLargestHeight = ((rect->MaxY - rect->MinY) + 1);
581 ///IconList_GetIconAreaRectangle()
582 static void IconList_GetIconAreaRectangle(Object *obj, struct IconList_DATA *data, struct IconEntry *icon, struct Rectangle *rect)
584 struct Rectangle labelrect;
585 ULONG iconlabel_Width;
586 ULONG iconlabel_Height;
588 #if defined(DEBUG_ILC_ICONPOSITIONING) && defined(DEBUG_ILC_FUNCS)
589 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
590 #endif
592 /* Get icon box width including text width */
593 memset(rect, 0, sizeof(struct Rectangle));
595 IconList_GetIconImageRectangle(obj, data, icon, rect);
597 icon->ie_AreaWidth = icon->ie_IconWidth;
598 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
600 icon->ie_AreaHeight = data->icld_IconLargestHeight;
602 else
604 icon->ie_AreaHeight = icon->ie_IconHeight;
607 IconList_GetIconLabelRectangle(obj, data, icon, &labelrect);
609 iconlabel_Width = ((labelrect.MaxX - labelrect.MinX) + 1);
610 iconlabel_Height = ((labelrect.MaxY - labelrect.MinY) + 1);
612 if (iconlabel_Width > icon->ie_AreaWidth)
613 icon->ie_AreaWidth = iconlabel_Width;
615 icon->ie_AreaHeight = icon->ie_AreaHeight + data->icld__Option_IconImageSpacing + iconlabel_Height;
617 /* Store */
618 rect->MaxX = (rect->MinX + icon->ie_AreaWidth) - 1;
619 rect->MaxY = (rect->MinY + icon->ie_AreaHeight) - 1;
621 if (icon->ie_AreaWidth > data->icld_IconAreaLargestWidth) data->icld_IconAreaLargestWidth = icon->ie_AreaWidth;
622 if (icon->ie_AreaHeight > data->icld_IconAreaLargestHeight) data->icld_IconAreaLargestHeight = icon->ie_AreaHeight;
626 static LONG FirstVisibleColumnNumber(struct IconList_DATA *data)
628 LONG i;
629 LONG retval = -1;
631 if (data->icld_LVMAttribs != NULL)
633 for(i = 0; i < NUM_COLUMNS; i++)
635 LONG index = data->icld_LVMAttribs->lmva_ColumnPos[i];
637 if (data->icld_LVMAttribs->lmva_ColumnVisible[index])
639 retval = i;
640 break;
645 return retval;
648 static LONG LastVisibleColumnNumber(struct IconList_DATA *data)
650 LONG i;
651 LONG retval = -1;
653 if (data->icld_LVMAttribs != NULL)
655 for(i = 0; i < NUM_COLUMNS; i++)
657 LONG index = data->icld_LVMAttribs->lmva_ColumnPos[i];
659 if (data->icld_LVMAttribs->lmva_ColumnVisible[index])
661 retval = i;
666 return retval;
670 static void RenderEntryField(Object *obj, struct IconList_DATA *data,
671 struct IconEntry *entry, struct Rectangle *rect,
672 LONG index, BOOL firstvis, BOOL lastvis)
674 STRPTR text;
675 struct TextExtent te;
676 ULONG fit;
678 if (entry->ie_Flags & ICONENTRY_FLAG_SELECTED)
680 FillPixelArray(data->icld_BufferRastPort, rect->MinX, rect->MinY, rect->MaxX - rect->MinX + 1, rect->MaxY - rect->MinY + 1, 0x0A246A);
683 rect->MinX += ENTRY_SPACING_LEFT;
684 rect->MaxX -= ENTRY_SPACING_RIGHT;
685 rect->MinY += LINE_SPACING_TOP;
686 rect->MaxY -= LINE_SPACING_BOTTOM;
688 if (firstvis) rect->MinX += LINE_SPACING_LEFT;
689 if (lastvis) rect->MaxX -= LINE_SPACING_RIGHT;
691 if (!entry) return;
693 switch(index)
695 case INDEX_NAME:
696 text = entry->ie_IconListEntry.label;
697 break;
699 case INDEX_SIZE:
700 text = entry->ie_TxtBuf_SIZE;
701 break;
703 case INDEX_DATE:
704 text = entry->ie_TxtBuf_DATE;
705 break;
707 case INDEX_TIME:
708 text = 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 fit = TextFit(data->icld_BufferRastPort, text, strlen(text), &te, NULL, 1,
724 rect->MaxX - rect->MinX + 1,
725 rect->MaxY - rect->MinY + 1);
727 if (!fit) return;
729 SetABPenDrMd(data->icld_BufferRastPort, _pens(obj)[(entry->ie_Flags & ICONENTRY_FLAG_SELECTED) ? MPEN_SHINE : MPEN_TEXT], 0, JAM1);
731 switch(data->icld_LVMAttribs->lmva_ColumnAlign[index])
733 case COLUMN_ALIGN_LEFT:
734 Move(data->icld_BufferRastPort, rect->MinX, rect->MinY + data->icld_BufferRastPort->TxBaseline);
735 break;
737 case COLUMN_ALIGN_RIGHT:
738 Move(data->icld_BufferRastPort, rect->MaxX - te.te_Width, rect->MinY + data->icld_BufferRastPort->TxBaseline);
739 break;
741 case COLUMN_ALIGN_CENTER:
742 Move(data->icld_BufferRastPort, rect->MinX + (rect->MaxX - rect->MinX + 1 + 1 - te.te_Width) / 2,
743 rect->MinY + data->icld_BufferRastPort->TxBaseline);
744 break;
747 Text(data->icld_BufferRastPort, text, fit);
750 /**************************************************************************
751 Draw the icon at its position
752 **************************************************************************/
753 ///IconList__MUIM_IconList_DrawEntry()
754 IPTR IconList__MUIM_IconList_DrawEntry(struct IClass *CLASS, Object *obj, struct MUIP_IconList_DrawEntry *message)
756 struct IconList_DATA *data = INST_DATA(CLASS, obj);
758 BOOL outside = FALSE;
760 struct Rectangle iconrect;
761 struct Rectangle objrect;
763 LONG offsetx,offsety;
765 ULONG objX, objY, objW, objH;
766 LONG iconX, iconY;
767 ULONG iconW, iconH;
769 if (data->icld_BufferRastPort == data->icld_DisplayRastPort)
771 objX = _mleft(obj);
772 objY = _mtop(obj);
774 else
776 objX = objY = 0;
778 objW = _mright(obj) - _mleft(obj) + 1;
779 objH = _mbottom(obj) - _mtop(obj) + 1;
781 #if defined(DEBUG_ILC_ICONRENDERING)
782 D(bug("[IconList]: %s(message->icon = 0x%p)\n", __PRETTY_FUNCTION__, message->icon));
783 #endif
785 if ((!(message->icon->ie_Flags & ICONENTRY_FLAG_VISIBLE)) ||
786 (data->icld_BufferRastPort == NULL) ||
787 (!(message->icon->ie_DiskObj)))
789 #if defined(DEBUG_ILC_ICONRENDERING)
790 D(bug("[IconList] %s: Not visible or missing DOB\n", __PRETTY_FUNCTION__));
791 #endif
792 return FALSE;
795 if ((data->icld_DisplayFlags & ICONLIST_DISP_MODELIST) == ICONLIST_DISP_MODELIST)
797 struct Rectangle linerect;
798 LONG x, i;
799 LONG firstvis, lastvis;
801 linerect.MinX = objX - data->icld_ViewX;
802 linerect.MaxX = objX + objW; //linerect.MinX + data->width - 1;
803 linerect.MinY = (objY - data->icld_ViewY) + data->icld_LVMAttribs->lmva_HeaderHeight + (message->drawmode * data->icld_LVMAttribs->lmva_RowHeight);
804 linerect.MaxY = linerect.MinY + data->icld_LVMAttribs->lmva_RowHeight - 1;
806 // if (!AndRectRect(&linerect, &data->view_rect, NULL)) return;
807 // if (!MustRenderRect(data, &linerect)) return;
809 SetFont(data->icld_BufferRastPort, data->icld_IconLabelFont);
811 x = linerect.MinX + LINE_SPACING_LEFT;
813 firstvis = FirstVisibleColumnNumber(data);
814 lastvis = LastVisibleColumnNumber(data);
816 for(i = 0; i < NUM_COLUMNS; i++)
818 struct Rectangle field_rect;
819 LONG index = data->icld_LVMAttribs->lmva_ColumnPos[i];
821 if (!data->icld_LVMAttribs->lmva_ColumnVisible[i]) continue;
823 field_rect.MinX = (i == firstvis) ? linerect.MinX : x;
824 field_rect.MinY = linerect.MinY;
825 field_rect.MaxX = x + data->icld_LVMAttribs->lmva_ColumnWidth[index] - 1 + ((i == lastvis) ? LINE_SPACING_RIGHT : 0);
826 field_rect.MaxY = linerect.MaxY;
828 /* if (MustRenderRect(data, &field_rect))
830 if (AndRectRect(&field_rect, &data->view_rect, NULL))
832 RenderEntryField(obj, data, message->icon, &field_rect, index,
833 (i == firstvis), (i == lastvis));
836 x += data->icld_LVMAttribs->lmva_ColumnWidth[index];
839 if ((data->icld_LVMAttribs->lvma_Flags & LVMAF_ROWDRAWTOEND) == LVMAF_ROWDRAWTOEND)
841 x += LINE_SPACING_RIGHT;
843 if (x < linerect.MaxX)
845 linerect.MinX = x;
847 SetABPenDrMd(data->icld_BufferRastPort, _pens(obj)[MPEN_SHINE], 0, JAM1);
848 RectFill(data->icld_BufferRastPort, linerect.MinX, linerect.MinY, linerect.MaxX, linerect.MaxY);
852 else
854 /* Get the dimensions and affected area of message->icon */
855 IconList_GetIconImageRectangle(obj, data, message->icon, &iconrect);
856 iconW = iconrect.MaxX - iconrect.MinX + 1;
857 iconH = iconrect.MaxY - iconrect.MinY + 1;
859 /* Add the relative position offset of the message->icon */
860 offsetx = objX - data->icld_ViewX + message->icon->ie_IconX;
861 /* Centre our image with our text */
862 if (message->icon->ie_IconWidth < message->icon->ie_AreaWidth)
863 offsetx += (message->icon->ie_AreaWidth - message->icon->ie_IconWidth)/2;
865 if ((data->icld__Option_IconListMode == ICON_LISTMODE_GRID) &&
866 (message->icon->ie_AreaWidth < data->icld_IconAreaLargestWidth))
867 offsetx += ((data->icld_IconAreaLargestWidth - message->icon->ie_AreaWidth)/2);
869 iconrect.MinX += offsetx;
870 iconrect.MaxX += offsetx;
872 offsety = objY - data->icld_ViewY + message->icon->ie_IconY;
873 iconrect.MinY += offsety;
874 iconrect.MaxY += offsety;
876 /* Add the relative position of the window */
877 objrect.MinX = objX;
878 objrect.MinY = objY;
879 objrect.MaxX = objX + objW;
880 objrect.MaxY = objY + objH;
882 if (!RectAndRect(&iconrect, &objrect))
884 #if defined(DEBUG_ILC_ICONRENDERING)
885 D(bug("[IconList] %s: Icon '%s' image outside of visible area .. skipping\n", __PRETTY_FUNCTION__, message->icon->ie_IconListEntry.label));
886 #endif
887 return FALSE;
890 /* data->update_rect1 and data->update_rect2 may
891 point to rectangles to indicate that only icons
892 in any of this rectangles need to be drawn */
893 if (data->update_rect1)
895 if (!RectAndRect(&iconrect, data->update_rect1)) outside = TRUE;
898 if (data->update_rect2)
900 if (data->update_rect1)
902 if ((outside == TRUE) && RectAndRect(&iconrect, data->update_rect2))
903 outside = FALSE;
905 else
907 if (!RectAndRect(&iconrect, data->update_rect2))
908 outside = TRUE;
912 if (outside == TRUE)
914 #if defined(DEBUG_ILC_ICONRENDERING)
915 D(bug("[IconList] %s: Icon '%s' image outside of update area .. skipping\n", __PRETTY_FUNCTION__, message->icon->ie_IconListEntry.label));
916 #endif
917 return FALSE;
920 if (message->drawmode == ICONENTRY_DRAWMODE_NONE) return TRUE;
922 // Center icon image
923 iconX = iconrect.MinX - objX + data->icld_DrawOffsetX;
924 iconY = iconrect.MinY - objY + data->icld_DrawOffsetY;
926 #if defined(DEBUG_ILC_ICONRENDERING)
927 D(bug("[IconList] %s: DrawIconState('%s') .. %d, %d\n", __PRETTY_FUNCTION__, message->icon->ie_IconListEntry.label, iconX, iconY));
928 #endif
929 DrawIconStateA
931 data->icld_BufferRastPort, message->icon->ie_DiskObj, NULL,
932 iconX,
933 iconY,
934 (message->icon->ie_Flags & ICONENTRY_FLAG_SELECTED) ? IDS_SELECTED : IDS_NORMAL,
935 __iconList_DrawIconStateTags
937 #if defined(DEBUG_ILC_ICONRENDERING)
938 D(bug("[IconList] %s: DrawIconState Done\n", __PRETTY_FUNCTION__));
939 #endif
942 return TRUE;
946 ///IconList__LabelFunc_SplitLabel()
947 void IconList__LabelFunc_SplitLabel(Object *obj, struct IconList_DATA *data, struct IconEntry *icon)
949 ULONG labelSplit_MaxLabelLineLength = data->icld__Option_LabelTextMaxLen;
950 ULONG labelSplit_LabelLength = strlen(icon->ie_IconListEntry.label);
951 ULONG txwidth;
952 // ULONG labelSplit_FontY = data->icld_IconLabelFont->tf_YSize;
953 int labelSplit_CharsDone, labelSplit_CharsSplit;
954 ULONG labelSplit_CurSplitWidth;
956 if ((data->icld__Option_TrimVolumeNames) &&
957 ((icon->ie_IconListEntry.type == ST_ROOT) && (icon->ie_IconListEntry.label[labelSplit_LabelLength - 1] == ':')))
958 labelSplit_LabelLength--;
960 if (labelSplit_MaxLabelLineLength >= labelSplit_LabelLength)
962 #if defined(DEBUG_ILC_ICONRENDERING)
963 D(bug("[IconList]: %s: Label'%s' doesnt need split (onyl %d chars)\n", __PRETTY_FUNCTION__, icon->ie_IconListEntry.label, labelSplit_LabelLength));
964 #endif
965 return;
968 SetFont(data->icld_BufferRastPort, data->icld_IconLabelFont);
969 txwidth = TextLength(data->icld_BufferRastPort, icon->ie_IconListEntry.label, labelSplit_MaxLabelLineLength);
970 #if defined(DEBUG_ILC_ICONRENDERING)
971 D(bug("[IconList]: %s: txwidth = %d\n", __PRETTY_FUNCTION__, txwidth));
972 #endif
973 icon->ie_TxtBuf_DisplayedLabel = AllocVecPooled(data->icld_Pool, 256);
974 memset(icon->ie_TxtBuf_DisplayedLabel, 0, 256);
975 icon->ie_SplitParts = 0;
977 labelSplit_CharsDone = 0;
978 labelSplit_CharsSplit = 0;
980 while (labelSplit_CharsDone < labelSplit_LabelLength)
982 ULONG labelSplit_CurSplitLength = labelSplit_LabelLength - labelSplit_CharsDone;
983 IPTR labelSplit_SplitStart = (IPTR)(icon->ie_IconListEntry.label + labelSplit_CharsDone);
984 int tmp_checkoffs = 0;
985 IPTR labelSplit_RemainingCharsAfterSplit;
986 IPTR labelSplit_CurSplitDest;
988 while (*(char *)(labelSplit_SplitStart) == ' ')
990 //Skip preceding spaces..
991 labelSplit_SplitStart = labelSplit_SplitStart + 1;
992 labelSplit_CurSplitLength = labelSplit_CurSplitLength - 1;
993 labelSplit_CharsDone = labelSplit_CharsDone + 1;
996 while(TextLength(data->icld_BufferRastPort, (char *)labelSplit_SplitStart, labelSplit_CurSplitLength) < txwidth) labelSplit_CurSplitLength++;
997 while(TextLength(data->icld_BufferRastPort, (char *)labelSplit_SplitStart, labelSplit_CurSplitLength) > txwidth) labelSplit_CurSplitLength--;
998 #if defined(DEBUG_ILC_ICONRENDERING)
999 D(bug("[IconList]: %s: labelSplit_CurSplitLength = %d\n", __PRETTY_FUNCTION__, labelSplit_CurSplitLength));
1000 #endif
1002 #if defined(DEBUG_ILC_ICONRENDERING)
1003 D(bug("[IconList]: %s: Attempting to find neat split ", __PRETTY_FUNCTION__));
1004 #endif
1005 while(tmp_checkoffs < (labelSplit_CurSplitLength - ILC_ICONLABEL_SHORTEST))
1007 #if defined(DEBUG_ILC_ICONRENDERING)
1008 D(bug("%d", tmp_checkoffs));
1009 #endif
1010 labelSplit_RemainingCharsAfterSplit = labelSplit_LabelLength - (labelSplit_CharsDone + labelSplit_CurSplitLength);
1012 if ((labelSplit_CurSplitLength - tmp_checkoffs) > ILC_ICONLABEL_SHORTEST)
1014 #if defined(DEBUG_ILC_ICONRENDERING)
1015 D(bug("<"));
1016 #endif
1017 if ((*(char *)(labelSplit_SplitStart + labelSplit_CurSplitLength - tmp_checkoffs) == ' ') ||
1018 (*(char *)(labelSplit_SplitStart + labelSplit_CurSplitLength - tmp_checkoffs) == '.') ||
1019 (*(char *)(labelSplit_SplitStart + labelSplit_CurSplitLength - tmp_checkoffs) == '-'))
1021 #if defined(DEBUG_ILC_ICONRENDERING)
1022 D(bug("!"));
1023 #endif
1024 labelSplit_CurSplitLength = labelSplit_CurSplitLength - tmp_checkoffs;
1025 labelSplit_RemainingCharsAfterSplit = labelSplit_RemainingCharsAfterSplit - tmp_checkoffs;
1026 tmp_checkoffs = 0;
1027 break;
1031 if ((labelSplit_RemainingCharsAfterSplit - tmp_checkoffs) < 0)
1033 #if defined(DEBUG_ILC_ICONRENDERING)
1034 D(bug("="));
1035 #endif
1036 labelSplit_CurSplitLength = labelSplit_CurSplitLength + tmp_checkoffs;
1037 labelSplit_RemainingCharsAfterSplit = labelSplit_RemainingCharsAfterSplit + tmp_checkoffs;
1038 tmp_checkoffs = 0;
1039 break;
1042 if ((labelSplit_RemainingCharsAfterSplit - tmp_checkoffs) >= ILC_ICONLABEL_SHORTEST)
1044 #if defined(DEBUG_ILC_ICONRENDERING)
1045 D(bug(">"));
1046 #endif
1047 if ((*(char *)(labelSplit_SplitStart + labelSplit_CurSplitLength + tmp_checkoffs) == ' ') ||
1048 (*(char *)(labelSplit_SplitStart + labelSplit_CurSplitLength + tmp_checkoffs) == '.') ||
1049 (*(char *)(labelSplit_SplitStart + labelSplit_CurSplitLength + tmp_checkoffs) == '-'))
1051 #if defined(DEBUG_ILC_ICONRENDERING)
1052 D(bug("!"));
1053 #endif
1054 labelSplit_CurSplitLength = labelSplit_CurSplitLength + tmp_checkoffs;
1055 labelSplit_RemainingCharsAfterSplit = labelSplit_RemainingCharsAfterSplit + tmp_checkoffs;
1056 tmp_checkoffs = 0;
1057 break;
1061 tmp_checkoffs = tmp_checkoffs + 1;
1063 #if defined(DEBUG_ILC_ICONRENDERING)
1064 D(bug("\n"));
1065 #endif
1066 if (tmp_checkoffs != 0)
1068 #if defined(DEBUG_ILC_ICONRENDERING)
1069 D(bug("[IconList]: %s: Couldnt find neat split : Still %d chars\n", __PRETTY_FUNCTION__, labelSplit_RemainingCharsAfterSplit));
1070 #endif
1071 if (labelSplit_RemainingCharsAfterSplit <= ILC_ICONLABEL_SHORTEST)
1073 labelSplit_CurSplitLength = labelSplit_CurSplitLength + (labelSplit_RemainingCharsAfterSplit - ILC_ICONLABEL_SHORTEST);
1076 if ((labelSplit_CharsDone + labelSplit_CurSplitLength) > labelSplit_LabelLength) labelSplit_CurSplitLength = labelSplit_LabelLength - labelSplit_CharsDone;
1078 labelSplit_CurSplitDest = (IPTR)(icon->ie_TxtBuf_DisplayedLabel + labelSplit_CharsSplit + icon->ie_SplitParts);
1080 strncpy((char *)labelSplit_CurSplitDest, (char *)labelSplit_SplitStart, labelSplit_CurSplitLength);
1082 labelSplit_CurSplitWidth = TextLength(data->icld_BufferRastPort, (char *)labelSplit_CurSplitDest, labelSplit_CurSplitLength);
1084 icon->ie_SplitParts = icon->ie_SplitParts + 1;
1086 labelSplit_CharsDone = labelSplit_CharsDone + labelSplit_CurSplitLength;
1087 labelSplit_CharsSplit = labelSplit_CharsSplit + labelSplit_CurSplitLength;
1089 if (labelSplit_CurSplitWidth > icon->ie_TxtBuf_DisplayedLabelWidth) icon->ie_TxtBuf_DisplayedLabelWidth = labelSplit_CurSplitWidth;
1091 if ((icon->ie_SplitParts <= 1) && icon->ie_TxtBuf_DisplayedLabel)
1093 FreeVecPooled(data->icld_Pool, icon->ie_TxtBuf_DisplayedLabel);
1094 icon->ie_TxtBuf_DisplayedLabel = NULL;
1095 icon->ie_SplitParts = 0;
1097 // if ((labelSplit_FontY * icon->ie_SplitParts) > data->icld_LabelLargestHeight) data->icld_LabelLargestHeight = (labelSplit_FontY * icon->ie_SplitParts);
1101 ///IconList__LabelFunc_CreateLabel()
1102 IPTR IconList__LabelFunc_CreateLabel(Object *obj, struct IconList_DATA *data, struct IconEntry *icon)
1104 #if defined(DEBUG_ILC_ICONRENDERING) && defined(DEBUG_ILC_FUNCS)
1105 D(bug("[IconList]: %s('%s')\n", __PRETTY_FUNCTION__, icon->ie_IconListEntry.label));
1106 #endif
1107 if (icon->ie_TxtBuf_DisplayedLabel)
1109 FreeVecPooled(data->icld_Pool, icon->ie_TxtBuf_DisplayedLabel);
1110 icon->ie_TxtBuf_DisplayedLabel = NULL;
1111 icon->ie_SplitParts = 0;
1114 if (data->icld__Option_LabelTextMultiLine > 1)
1116 #if defined(DEBUG_ILC_ICONRENDERING)
1117 D(bug("[IconList]: %s: Attempting to split label ..\n", __PRETTY_FUNCTION__));
1118 #endif
1119 IconList__LabelFunc_SplitLabel(obj, data, icon);
1122 if (icon->ie_TxtBuf_DisplayedLabel == NULL)
1124 ULONG ie_LabelLength = strlen(icon->ie_IconListEntry.label);
1125 icon->ie_SplitParts = 1;
1127 #if defined(DEBUG_ILC_ICONRENDERING)
1128 D(bug("[IconList]: %s: Building unsplit label (len = %d) ..\n", __PRETTY_FUNCTION__, ie_LabelLength));
1129 #endif
1131 if ((data->icld__Option_TrimVolumeNames) &&
1132 ((icon->ie_IconListEntry.type == ST_ROOT) && (icon->ie_IconListEntry.label[ie_LabelLength - 1] == ':')))
1133 ie_LabelLength--;
1135 if(ie_LabelLength > data->icld__Option_LabelTextMaxLen)
1137 if (!(icon->ie_TxtBuf_DisplayedLabel = AllocVecPooled(data->icld_Pool, data->icld__Option_LabelTextMaxLen + 1)))
1139 return (IPTR)NULL;
1141 memset(icon->ie_TxtBuf_DisplayedLabel, 0, data->icld__Option_LabelTextMaxLen + 1);
1142 strncpy(icon->ie_TxtBuf_DisplayedLabel, icon->ie_IconListEntry.label, data->icld__Option_LabelTextMaxLen - 3);
1143 strcat(icon->ie_TxtBuf_DisplayedLabel , " ..");
1145 else
1147 if (!(icon->ie_TxtBuf_DisplayedLabel = AllocVecPooled(data->icld_Pool, ie_LabelLength + 1)))
1149 return (IPTR)NULL;
1151 memset(icon->ie_TxtBuf_DisplayedLabel, 0, ie_LabelLength + 1);
1152 strncpy(icon->ie_TxtBuf_DisplayedLabel, icon->ie_IconListEntry.label, ie_LabelLength );
1154 icon->ie_TxtBuf_DisplayedLabelWidth = TextLength(data->icld_BufferRastPort, icon->ie_TxtBuf_DisplayedLabel, strlen(icon->ie_TxtBuf_DisplayedLabel));
1155 // if ((data->icld_IconLabelFont->tf_YSize) > data->icld_LabelLargestHeight) data->icld_LabelLargestHeight = data->icld_IconLabelFont->tf_YSize;
1158 // if (icon->ie_TxtBuf_DisplayedLabelWidth > data->icld_LabelLargestWidth) data->icld_LabelLargestWidth = icon->ie_TxtBuf_DisplayedLabelWidth;
1160 return (IPTR)icon->ie_TxtBuf_DisplayedLabel;
1164 ///IconList__HookFunc_UpdateLabelsFunc()
1165 AROS_UFH3(
1166 void, IconList__HookFunc_UpdateLabelsFunc,
1167 AROS_UFHA(struct Hook *, hook, A0),
1168 AROS_UFHA(APTR *, obj, A2),
1169 AROS_UFHA(APTR, param, A1)
1172 AROS_USERFUNC_INIT
1174 /* Get our private data */
1175 Class *CLASS = *( Class **)param;
1176 struct IconList_DATA *data = INST_DATA(CLASS, obj);
1178 #if defined(DEBUG_ILC_LASSO) && defined(DEBUG_ILC_FUNCS)
1179 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
1180 #endif
1182 if (((data->icld__Option_LabelTextMaxLen != data->icld__Option_LastLabelTextMaxLen) &&
1183 (data->icld__Option_LabelTextMultiLine > 1)) ||
1184 (data->icld__Option_LabelTextMultiLine != data->icld__Option_LastLabelTextMultiLine));
1186 struct IconEntry *iconentry_Current = NULL;
1187 #if defined(__AROS__)
1188 ForeachNode(&data->icld_IconList, iconentry_Current)
1189 #else
1190 Foreach_Node(&data->icld_IconList, iconentry_Current);
1191 #endif
1193 IconList__LabelFunc_CreateLabel((Object *)obj, data, iconentry_Current);
1197 data->icld__Option_LastLabelTextMaxLen = data->icld__Option_LabelTextMaxLen;
1198 data->icld__Option_LastLabelTextMultiLine = data->icld__Option_LabelTextMultiLine;
1200 AROS_USERFUNC_EXIT
1204 ///IconList__MUIM_IconList_DrawEntryLabel()
1205 IPTR IconList__MUIM_IconList_DrawEntryLabel(struct IClass *CLASS, Object *obj, struct MUIP_IconList_DrawEntry *message)
1207 struct IconList_DATA *data = INST_DATA(CLASS, obj);
1209 STRPTR buf = NULL;
1210 BOOL outside = FALSE;
1212 struct Rectangle iconlabelrect;
1213 struct Rectangle objrect;
1215 ULONG txtbox_width = 0;
1216 LONG tx,ty,offsetx,offsety;
1217 LONG txwidth; // txheight;
1219 ULONG objX, objY, objW, objH;
1220 LONG labelX, labelY;
1221 ULONG labelW, labelH;
1223 if ((data->icld_DisplayFlags & ICONLIST_DISP_MODELIST) == ICONLIST_DISP_MODELIST)
1224 return FALSE;
1226 if (data->icld_BufferRastPort == data->icld_DisplayRastPort)
1228 objX = _mleft(obj);
1229 objY = _mtop(obj);
1231 else
1233 objX = objY = 0;
1235 objW = _mright(obj) - _mleft(obj) + 1;
1236 objH = _mbottom(obj) - _mtop(obj) + 1;
1238 ULONG txtarea_width;
1239 ULONG curlabel_TotalLines, curlabel_CurrentLine, offset_y;
1241 #if defined(DEBUG_ILC_ICONRENDERING) && defined(DEBUG_ILC_FUNCS)
1242 D(bug("[IconList]: %s(message->icon = 0x%p), '%s'\n", __PRETTY_FUNCTION__, message->icon, message->icon->ie_IconListEntry.label));
1243 #endif
1245 if ((!(message->icon->ie_Flags & ICONENTRY_FLAG_VISIBLE)) ||
1246 (data->icld_BufferRastPort == NULL) ||
1247 (!(message->icon->ie_DiskObj)))
1249 #if defined(DEBUG_ILC_ICONRENDERING)
1250 D(bug("[IconList] %s: Not visible or missing DOB\n", __PRETTY_FUNCTION__));
1251 #endif
1252 return FALSE;
1255 /* Get the dimensions and affected area of message->icon's label */
1256 IconList_GetIconLabelRectangle(obj, data, message->icon, &iconlabelrect);
1257 labelW = iconlabelrect.MaxX - iconlabelrect.MinX + 1;
1258 labelH = iconlabelrect.MaxY - iconlabelrect.MinY + 1;
1260 /* Add the relative position offset of the message->icon's label */
1261 offsetx = (objX - data->icld_ViewX) + message->icon->ie_IconX;
1262 txtbox_width = (iconlabelrect.MaxX - iconlabelrect.MinX) + 1;
1264 if (txtbox_width < message->icon->ie_AreaWidth)
1265 offsetx += ((message->icon->ie_AreaWidth - txtbox_width)/2);
1267 if ((data->icld__Option_IconListMode == ICON_LISTMODE_GRID) &&
1268 (message->icon->ie_AreaWidth < data->icld_IconAreaLargestWidth))
1269 offsetx += ((data->icld_IconAreaLargestWidth - message->icon->ie_AreaWidth)/2);
1271 iconlabelrect.MinX += offsetx;
1272 iconlabelrect.MaxX += offsetx;
1274 offsety = (objY - data->icld_ViewY) + message->icon->ie_IconY + data->icld__Option_IconImageSpacing;
1275 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
1277 offsety = offsety + data->icld_IconLargestHeight;
1279 else
1281 offsety = offsety + message->icon->ie_IconHeight;
1283 iconlabelrect.MinY += offsety;
1284 iconlabelrect.MaxY += offsety;
1286 /* Add the relative position of the window */
1287 objrect.MinX = objX;
1288 objrect.MinY = objX;
1289 objrect.MaxX = objX + objW;
1290 objrect.MaxY = objY + objH;
1292 if (!RectAndRect(&iconlabelrect, &objrect))
1294 #if defined(DEBUG_ILC_ICONRENDERING)
1295 (bug("[IconList] %s: Icon '%s' label outside of visible area .. skipping\n", __PRETTY_FUNCTION__, message->icon->ie_IconListEntry.label));
1296 #endif
1297 return FALSE;
1300 /* data->update_rect1 and data->update_rect2 may
1301 point to rectangles to indicate that only icons
1302 in any of this rectangles need to be drawn */
1303 if (data->update_rect1)
1305 if (!RectAndRect(&iconlabelrect, data->update_rect1))
1306 outside = TRUE;
1309 if (data->update_rect2)
1311 if (data->update_rect1)
1313 if ((outside == TRUE) && RectAndRect(&iconlabelrect, data->update_rect2))
1314 outside = FALSE;
1316 else
1318 if (!RectAndRect(&iconlabelrect, data->update_rect2))
1319 outside = TRUE;
1323 if (outside == TRUE)
1325 #if defined(DEBUG_ILC_ICONRENDERING)
1326 D(bug("[IconList] %s: Icon '%s' label outside of update area .. skipping\n", __PRETTY_FUNCTION__, message->icon->ie_IconListEntry.label));
1327 #endif
1328 return FALSE;
1331 if (message->drawmode == ICONENTRY_DRAWMODE_NONE)
1332 return TRUE;
1334 SetABPenDrMd(data->icld_BufferRastPort, _pens(obj)[MPEN_TEXT], 0, JAM1);
1336 iconlabelrect.MinX = (iconlabelrect.MinX - objX) + data->icld_DrawOffsetX;
1337 iconlabelrect.MinY = (iconlabelrect.MinY - objY) + data->icld_DrawOffsetY;
1338 iconlabelrect.MaxX = (iconlabelrect.MaxX - objX) + data->icld_DrawOffsetX;
1339 iconlabelrect.MaxY = (iconlabelrect.MaxY - objY) + data->icld_DrawOffsetY;
1341 labelX = iconlabelrect.MinX + data->icld__Option_LabelTextBorderWidth + data->icld__Option_LabelTextHorizontalPadding;
1342 labelY = iconlabelrect.MinY + data->icld__Option_LabelTextBorderHeight + data->icld__Option_LabelTextVerticalPadding;
1344 txtarea_width = txtbox_width - ((data->icld__Option_LabelTextBorderWidth + data->icld__Option_LabelTextHorizontalPadding) * 2);
1346 #if defined(DEBUG_ILC_ICONRENDERING)
1347 D(bug("[IconList] %s: Drawing Label '%s' .. %d, %d\n", __PRETTY_FUNCTION__, message->icon->ie_IconListEntry.label, labelX, labelY));
1348 #endif
1349 if (message->icon->ie_IconListEntry.label && message->icon->ie_TxtBuf_DisplayedLabel)
1351 char *curlabel_StrPtr;
1353 if ((message->icon->ie_Flags & ICONENTRY_FLAG_FOCUS) && ((BOOL)XGET(_win(obj), MUIA_Window_Activate)))
1355 //Draw the focus box around the selected label ..
1356 if (data->icld__Option_LabelTextBorderHeight > 0)
1358 InvertPixelArray(data->icld_BufferRastPort,
1359 iconlabelrect.MinX, iconlabelrect.MinY,
1360 (iconlabelrect.MaxX - iconlabelrect.MinX) + 1, data->icld__Option_LabelTextBorderHeight);
1362 InvertPixelArray(data->icld_BufferRastPort,
1363 iconlabelrect.MinX, iconlabelrect.MaxY - (data->icld__Option_LabelTextBorderHeight - 1),
1364 (iconlabelrect.MaxX - iconlabelrect.MinX) + 1, data->icld__Option_LabelTextBorderHeight);
1366 if (data->icld__Option_LabelTextBorderWidth > 0)
1368 InvertPixelArray(data->icld_BufferRastPort,
1369 iconlabelrect.MinX, iconlabelrect.MinY + data->icld__Option_LabelTextBorderHeight,
1370 data->icld__Option_LabelTextBorderWidth, (((iconlabelrect.MaxY - iconlabelrect.MinY) + 1) - (data->icld__Option_LabelTextBorderHeight * 2)));
1372 InvertPixelArray(data->icld_BufferRastPort,
1373 iconlabelrect.MaxX - (data->icld__Option_LabelTextBorderWidth - 1), iconlabelrect.MinY + data->icld__Option_LabelTextBorderHeight,
1374 data->icld__Option_LabelTextBorderWidth, (((iconlabelrect.MaxY - iconlabelrect.MinY) + 1) - (data->icld__Option_LabelTextBorderHeight * 2)));
1378 SetFont(data->icld_BufferRastPort, data->icld_IconLabelFont);
1380 curlabel_TotalLines = message->icon->ie_SplitParts;
1381 curlabel_CurrentLine = 0;
1383 if (curlabel_TotalLines == 0)
1384 curlabel_TotalLines = 1;
1386 if (!(data->icld__Option_LabelTextMultiLineOnFocus) || (data->icld__Option_LabelTextMultiLineOnFocus && (message->icon->ie_Flags & ICONENTRY_FLAG_FOCUS)))
1388 if (curlabel_TotalLines > data->icld__Option_LabelTextMultiLine)
1389 curlabel_TotalLines = data->icld__Option_LabelTextMultiLine;
1391 else
1392 curlabel_TotalLines = 1;
1394 curlabel_StrPtr = message->icon->ie_TxtBuf_DisplayedLabel;
1396 ty = labelY - 1;
1398 #if defined(DEBUG_ILC_ICONRENDERING)
1399 D(bug("[IconList] %s: Font YSize %d Baseline %d\n", __PRETTY_FUNCTION__,data->icld_IconLabelFont->tf_YSize, data->icld_IconLabelFont->tf_Baseline));
1400 #endif
1401 for (curlabel_CurrentLine = 0; curlabel_CurrentLine < curlabel_TotalLines; curlabel_CurrentLine++)
1403 ULONG ie_LabelLength;
1405 if (curlabel_CurrentLine > 0) curlabel_StrPtr = curlabel_StrPtr + strlen(curlabel_StrPtr) + 1;
1406 if ((curlabel_CurrentLine >= (curlabel_TotalLines -1)) && (curlabel_TotalLines < message->icon->ie_SplitParts))
1408 char *tmpLine = curlabel_StrPtr;
1409 ULONG tmpLen = strlen(tmpLine);
1411 if ((curlabel_StrPtr = AllocVecPooled(data->icld_Pool, tmpLen + 1)) != NULL)
1413 memset(curlabel_StrPtr, 0, tmpLen + 1);
1414 strncpy(curlabel_StrPtr, tmpLine, tmpLen - 3);
1415 strcat(curlabel_StrPtr , " ..");
1417 else
1418 return FALSE;
1422 ie_LabelLength = strlen(curlabel_StrPtr);
1423 offset_y = 0;
1425 // Center message->icon's label
1426 tx = (labelX + (message->icon->ie_TxtBuf_DisplayedLabelWidth / 2) - (TextLength(data->icld_BufferRastPort, curlabel_StrPtr, strlen(curlabel_StrPtr)) / 2));
1428 if (message->icon->ie_TxtBuf_DisplayedLabelWidth < txtarea_width)
1429 tx += ((txtarea_width - message->icon->ie_TxtBuf_DisplayedLabelWidth)/2);
1431 ty = ty + data->icld_IconLabelFont->tf_YSize;
1433 switch ( data->icld__Option_LabelTextMode )
1435 case ICON_TEXTMODE_DROPSHADOW:
1436 SetAPen(data->icld_BufferRastPort, data->icld_LabelShadowPen);
1437 Move(data->icld_BufferRastPort, tx + 1, ty + 1);
1438 Text(data->icld_BufferRastPort, curlabel_StrPtr, ie_LabelLength);
1439 offset_y = 1;
1440 case ICON_TEXTMODE_PLAIN:
1441 SetAPen(data->icld_BufferRastPort, data->icld_LabelPen);
1442 Move(data->icld_BufferRastPort, tx, ty);
1443 Text(data->icld_BufferRastPort, curlabel_StrPtr, ie_LabelLength);
1444 break;
1446 default:
1447 // Outline mode:
1448 SetSoftStyle(data->icld_BufferRastPort, FSF_BOLD, AskSoftStyle(data->icld_BufferRastPort));
1450 SetAPen(data->icld_BufferRastPort, data->icld_LabelShadowPen);
1451 Move(data->icld_BufferRastPort, tx + 1, ty );
1452 Text(data->icld_BufferRastPort, curlabel_StrPtr, ie_LabelLength);
1453 Move(data->icld_BufferRastPort, tx - 1, ty );
1454 Text(data->icld_BufferRastPort, curlabel_StrPtr, ie_LabelLength);
1455 Move(data->icld_BufferRastPort, tx, ty + 1);
1456 Text(data->icld_BufferRastPort, curlabel_StrPtr, ie_LabelLength);
1457 Move(data->icld_BufferRastPort, tx, ty - 1);
1458 Text(data->icld_BufferRastPort, curlabel_StrPtr, ie_LabelLength);
1460 SetAPen(data->icld_BufferRastPort, data->icld_LabelPen);
1461 Move(data->icld_BufferRastPort, tx , ty );
1462 Text(data->icld_BufferRastPort, curlabel_StrPtr, ie_LabelLength);
1464 SetSoftStyle(data->icld_BufferRastPort, FS_NORMAL, AskSoftStyle(data->icld_BufferRastPort));
1465 offset_y = 2;
1466 break;
1468 if ((curlabel_CurrentLine >= (curlabel_TotalLines -1)) && (curlabel_TotalLines < message->icon->ie_SplitParts))
1470 FreeVecPooled(data->icld_Pool, curlabel_StrPtr);
1472 ty = ty + offset_y;
1475 /*date/size sorting has the date/size appended under the message->icon label*/
1477 if ((message->icon->ie_IconListEntry.type != ST_USERDIR) && ((data->icld_SortFlags & (MUIV_IconList_Sort_BySize|MUIV_IconList_Sort_ByDate)) != 0))
1479 buf = NULL;
1480 SetFont(data->icld_BufferRastPort, data->icld_IconInfoFont);
1482 if ((data->icld_SortFlags & MUIV_IconList_Sort_MASK) == MUIV_IconList_Sort_BySize)
1484 buf = message->icon->ie_TxtBuf_SIZE;
1485 txwidth = message->icon->ie_TxtBuf_SIZEWidth;
1487 else if ((data->icld_SortFlags & MUIV_IconList_Sort_MASK) == MUIV_IconList_Sort_ByDate)
1489 if (message->icon->ie_Flags & ICONENTRY_FLAG_TODAY)
1491 buf = message->icon->ie_TxtBuf_TIME;
1492 txwidth = message->icon->ie_TxtBuf_TIMEWidth;
1494 else
1496 buf = message->icon->ie_TxtBuf_DATE;
1497 txwidth = message->icon->ie_TxtBuf_DATEWidth;
1501 if (buf)
1503 ULONG ie_LabelLength = strlen(buf);
1504 tx = labelX;
1506 if (txwidth < txtarea_width)
1507 tx += ((txtarea_width - txwidth)/2);
1509 ty = labelY + ((data->icld__Option_LabelTextVerticalPadding + data->icld_IconLabelFont->tf_YSize ) * curlabel_TotalLines) + data->icld_IconInfoFont->tf_YSize;
1511 switch ( data->icld__Option_LabelTextMode )
1513 case ICON_TEXTMODE_DROPSHADOW:
1514 SetAPen(data->icld_BufferRastPort, data->icld_InfoShadowPen);
1515 Move(data->icld_BufferRastPort, tx + 1, ty + 1); Text(data->icld_BufferRastPort, buf, ie_LabelLength);
1516 case ICON_TEXTMODE_PLAIN:
1517 SetAPen(data->icld_BufferRastPort, data->icld_InfoPen);
1518 Move(data->icld_BufferRastPort, tx, ty); Text(data->icld_BufferRastPort, buf, ie_LabelLength);
1519 break;
1521 default:
1522 // Outline mode..
1523 SetSoftStyle(data->icld_BufferRastPort, FSF_BOLD, AskSoftStyle(data->icld_BufferRastPort));
1524 SetAPen(data->icld_BufferRastPort, data->icld_InfoShadowPen);
1526 Move(data->icld_BufferRastPort, tx + 1, ty );
1527 Text(data->icld_BufferRastPort, buf, ie_LabelLength);
1528 Move(data->icld_BufferRastPort, tx - 1, ty );
1529 Text(data->icld_BufferRastPort, buf, ie_LabelLength);
1530 Move(data->icld_BufferRastPort, tx, ty - 1 );
1531 Text(data->icld_BufferRastPort, buf, ie_LabelLength);
1532 Move(data->icld_BufferRastPort, tx, ty + 1 );
1533 Text(data->icld_BufferRastPort, buf, ie_LabelLength);
1535 SetAPen(data->icld_BufferRastPort, data->icld_InfoPen);
1537 Move(data->icld_BufferRastPort, tx, ty );
1538 Text(data->icld_BufferRastPort, buf, ie_LabelLength);
1540 SetSoftStyle(data->icld_BufferRastPort, FS_NORMAL, AskSoftStyle(data->icld_BufferRastPort));
1541 break;
1547 return TRUE;
1550 /**************************************************************************
1552 **************************************************************************/
1553 ///IconList__MUIM_IconList_RethinkDimensions()
1554 IPTR IconList__MUIM_IconList_RethinkDimensions(struct IClass *CLASS, Object *obj, struct MUIP_IconList_RethinkDimensions *message)
1556 struct IconList_DATA *data = INST_DATA(CLASS, obj);
1558 struct IconEntry *icon = NULL;
1559 LONG maxx = 0,
1560 maxy = 0;
1561 struct Rectangle icon_rect;
1563 #if defined(DEBUG_ILC_ICONPOSITIONING) && defined(DEBUG_ILC_FUNCS)
1564 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
1565 #endif
1567 if (message->singleicon != NULL)
1569 icon = message->singleicon;
1570 maxx = data->icld_AreaWidth - 1,
1571 maxy = data->icld_AreaHeight - 1;
1572 #if defined(DEBUG_ILC_ICONPOSITIONING)
1573 D(bug("[IconList] %s: SingleIcon - maxx = %d, maxy = %d\n", __PRETTY_FUNCTION__, maxx, maxy));
1574 #endif
1576 else
1577 icon = (struct IconEntry *)GetHead(&data->icld_IconList);
1579 while (icon != NULL)
1581 if (icon->ie_DiskObj &&
1582 (icon->ie_Flags & ICONENTRY_FLAG_VISIBLE) &&
1583 (icon->ie_IconX != NO_ICON_POSITION) &&
1584 (icon->ie_IconY != NO_ICON_POSITION))
1586 IconList_GetIconAreaRectangle(obj, data, icon, &icon_rect);
1588 icon_rect.MaxX += icon->ie_IconX + data->icld__Option_IconHorizontalSpacing;
1589 if ((data->icld__Option_IconListMode == ICON_LISTMODE_GRID) &&
1590 (icon->ie_AreaWidth < data->icld_IconAreaLargestWidth))
1591 icon_rect.MaxX += (data->icld_IconAreaLargestWidth - icon->ie_AreaWidth);
1593 icon_rect.MaxY += icon->ie_IconY + data->icld__Option_IconVerticalSpacing;
1595 if (icon_rect.MaxX > maxx) maxx = icon_rect.MaxX;
1596 if (icon_rect.MaxY > maxy) maxy = icon_rect.MaxY;
1599 if (message->singleicon)
1600 break;
1602 icon = (struct IconEntry *)GetSucc(&icon->ie_IconNode);
1605 /* update our view when max x/y have changed */
1606 if (maxx + 1 != data->icld_AreaWidth)
1608 data->icld_AreaWidth = maxx + 1;
1609 SET(obj, MUIA_IconList_Width, data->icld_AreaWidth);
1611 if (maxy + 1 != data->icld_AreaHeight)
1613 data->icld_AreaHeight = maxy + 1;
1614 SET(obj, MUIA_IconList_Height, data->icld_AreaHeight);
1617 return TRUE;
1620 ///IconList__MUIM_IconList_PositionIcons()
1621 /**************************************************************************
1622 MUIM_PositionIcons - Place icons with NO_ICON_POSITION coords somewhere
1623 **************************************************************************/
1624 IPTR IconList__MUIM_IconList_PositionIcons(struct IClass *CLASS, Object *obj, struct MUIP_IconList_PositionIcons *message)
1626 struct IconList_DATA *data = INST_DATA(CLASS, obj);
1627 struct IconEntry *icon = NULL, *pass_first = NULL;
1629 int left = data->icld__Option_IconHorizontalSpacing;
1630 int top = data->icld__Option_IconVerticalSpacing;
1631 int cur_x = left;
1632 int cur_y = top;
1633 int gridx = 0;
1634 int gridy = 0;
1635 int maxw = 0; // Widest & Talest icon in a column or row.
1636 int maxh = 0;
1638 BOOL next;
1639 struct Rectangle iconrect;
1641 #if defined(DEBUG_ILC_ICONPOSITIONING) && defined(DEBUG_ILC_FUNCS)
1642 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
1643 #endif
1645 // Now go to the actual positioning
1646 icon = (struct IconEntry *)GetHead(&data->icld_IconList);
1647 while (icon != NULL)
1649 next = FALSE;
1650 if ((icon->ie_DiskObj != NULL) && (icon->ie_Flags & ICONENTRY_FLAG_VISIBLE))
1652 next = TRUE;
1653 icon->ie_IconX = cur_x;
1654 icon->ie_IconY = cur_y;
1656 if (icon->ie_Flags & ICONENTRY_FLAG_SELECTED)
1658 if (data->icld_SelectionLastClicked == NULL) data->icld_SelectionLastClicked = icon;
1659 if (data->icld_FocusIcon == NULL) data->icld_FocusIcon = icon;
1662 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
1664 maxw = data->icld_IconAreaLargestWidth + data->icld__Option_IconHorizontalSpacing;
1665 maxh = data->icld_IconLargestHeight + data->icld__Option_IconImageSpacing + data->icld_LabelLargestHeight + data->icld__Option_IconVerticalSpacing;
1666 gridx = maxw;
1667 gridy = maxh;
1669 else
1671 if (!(pass_first)) pass_first = icon;
1673 IconList_GetIconAreaRectangle(obj, data, icon, &iconrect);
1675 if (icon->ie_AreaWidth < maxw)
1676 icon->ie_IconX += ( maxw - icon->ie_AreaWidth ) / 2;
1678 if ((maxw < icon->ie_AreaWidth) || (maxh < icon->ie_AreaHeight))
1680 if (maxw < icon->ie_AreaWidth) maxw = icon->ie_AreaWidth;
1681 if (maxh < icon->ie_AreaHeight) maxh = icon->ie_AreaHeight;
1682 if (pass_first != icon)
1684 icon = pass_first;
1685 cur_x = icon->ie_IconX;
1686 cur_y = icon->ie_IconY;
1687 continue;
1691 if (data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL)
1693 gridx = maxw;
1694 gridy = icon->ie_AreaHeight + data->icld__Option_IconHorizontalSpacing;
1696 else
1698 gridx = icon->ie_AreaWidth + data->icld__Option_IconVerticalSpacing;
1699 gridy = maxh;
1703 if ((icon = (struct IconEntry *)GetSucc(&icon->ie_IconNode)) != NULL)
1705 if (next == TRUE)
1707 if (data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL)
1709 cur_y += gridy;
1711 if ((cur_y >= data->icld_ViewHeight) ||
1712 ((data->icld__Option_IconListMode == ICON_LISTMODE_ROUGH) && ((cur_y + icon->ie_AreaHeight - data->icld__Option_IconBorderOverlap) >= data->icld_ViewHeight)) ||
1713 ((data->icld__Option_IconListMode == ICON_LISTMODE_GRID) && ((cur_y + data->icld_IconAreaLargestHeight - data->icld__Option_IconBorderOverlap) >= data->icld_ViewHeight)))
1715 cur_x += maxw;
1716 cur_y = top;
1717 pass_first = NULL;
1718 maxw = 0;
1721 else
1723 cur_x += gridx;
1725 if ((cur_x >= data->icld_ViewWidth) ||
1726 ((data->icld__Option_IconListMode == ICON_LISTMODE_ROUGH) && ((cur_x + icon->ie_AreaWidth - data->icld__Option_IconBorderOverlap) >= data->icld_ViewWidth)) ||
1727 ((data->icld__Option_IconListMode == ICON_LISTMODE_GRID) && ((cur_x + data->icld_IconAreaLargestWidth - data->icld__Option_IconBorderOverlap) >= data->icld_ViewWidth)))
1729 cur_x = left;
1730 cur_y += maxh;
1731 pass_first = NULL;
1732 maxh = 0;
1734 else if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
1742 DoMethod(obj, MUIM_IconList_RethinkDimensions, NULL);
1743 return (IPTR)NULL;
1747 ///OM_NEW()
1748 /**************************************************************************
1749 OM_NEW
1750 **************************************************************************/
1751 IPTR IconList__OM_NEW(struct IClass *CLASS, Object *obj, struct opSet *message)
1753 struct IconList_DATA *data = NULL;
1754 struct TextFont *icl_WindowFont = NULL;
1755 // struct RastPort *icl_RastPort = NULL;
1756 int i;
1758 #if defined(DEBUG_ILC_FUNCS)
1759 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
1760 #endif
1762 icl_WindowFont = (struct TextFont *) GetTagData(MUIA_Font, (IPTR) NULL, message->ops_AttrList);
1764 obj = (Object *)DoSuperNewTags(CLASS, obj, NULL,
1765 MUIA_FillArea, FALSE,
1766 MUIA_Dropable, TRUE,
1767 MUIA_Font, MUIV_Font_Tiny,
1768 TAG_MORE, (IPTR) message->ops_AttrList);
1770 if (!obj) return FALSE;
1772 data = INST_DATA(CLASS, obj);
1774 data->icld_Pool = CreatePool(0,4096,4096);
1775 if (!data->icld_Pool)
1777 CoerceMethod(CLASS,obj,OM_DISPOSE);
1778 return (IPTR)NULL;
1781 #if defined(DEBUG_ILC_FUNCS)
1782 D(bug("[IconList] %s: SELF = 0x%p, muiRenderInfo = 0x%p\n", __PRETTY_FUNCTION__, obj, muiRenderInfo(obj)));
1783 #endif
1784 NewList((struct List*)&data->icld_IconList);
1785 NewList((struct List*)&data->icld_SelectionList);
1787 data->icld_IconLabelFont = icl_WindowFont;
1789 /* Setup Icon View-Mode options */
1790 data->icld_IVMAttribs = AllocMem(sizeof(struct IconViewModeAttribs), MEMF_CLEAR);
1791 /* Setup List View-Mode options */
1792 if ((data->icld_LVMAttribs = AllocMem(sizeof(struct ListViewModeAttribs), MEMF_CLEAR)) != NULL)
1794 for(i = 0; i < NUM_COLUMNS; i++)
1796 data->icld_LVMAttribs->lmva_ColumnPos[i] = i;
1797 data->icld_LVMAttribs->lmva_ColumnVisible[i] = TRUE;
1798 data->icld_LVMAttribs->lmva_ColumnWidth[i] = 100;
1799 data->icld_LVMAttribs->lmva_ColumnAlign[i] = COLUMN_ALIGN_LEFT;
1800 data->icld_LVMAttribs->lmva_ColumnSortable[i] = FALSE;
1801 switch (i)
1803 case INDEX_NAME:
1804 data->icld_LVMAttribs->lmva_ColumnClickable[i] = TRUE;
1805 data->icld_LVMAttribs->lmva_ColumnSortable[i] = TRUE;
1806 data->icld_LVMAttribs->lmva_ColumnTitle[i] = "Name";
1807 break;
1809 case INDEX_SIZE:
1810 data->icld_LVMAttribs->lmva_ColumnAlign[i] = COLUMN_ALIGN_RIGHT;
1811 data->icld_LVMAttribs->lmva_ColumnSortable[i] = TRUE;
1812 data->icld_LVMAttribs->lmva_ColumnTitle[i] = "Size";
1813 break;
1815 case INDEX_DATE:
1816 data->icld_LVMAttribs->lmva_ColumnSortable[i] = TRUE;
1817 data->icld_LVMAttribs->lmva_ColumnTitle[i] = "Date";
1818 break;
1820 case INDEX_TIME:
1821 data->icld_LVMAttribs->lmva_ColumnSortable[i] = TRUE;
1822 data->icld_LVMAttribs->lmva_ColumnTitle[i] = "Time";
1823 break;
1825 case INDEX_COMMENT:
1826 data->icld_LVMAttribs->lmva_ColumnTitle[i] = "Comment";
1827 break;
1829 case INDEX_PROTECTION:
1830 data->icld_LVMAttribs->lmva_ColumnTitle[i] = "Protection";
1831 break;
1833 default:
1834 data->icld_LVMAttribs->lmva_ColumnTitle[i] = "<Unknown>";
1835 break;
1838 data->icld_LVMAttribs->lmva_SortColumn = INDEX_NAME;
1839 data->icld_LVMAttribs->lmva_HeaderHeight = HEADERLINE_EXTRAHEIGHT + data->icld_IconLabelFont->tf_YSize;
1840 data->icld_LVMAttribs->lmva_RowHeight = LINE_EXTRAHEIGHT + data->icld_IconLabelFont->tf_YSize;
1841 data->icld_LVMAttribs->lvma_Flags = LVMAF_HEADERDRAWTOEND;
1844 /* Get/Set initial values */
1845 #warning "TODO: TrimVolumeNames should be prefs settable"
1846 data->icld__Option_TrimVolumeNames = TRUE;
1847 #warning "TODO: Adjust overlap by window border width"
1848 data->icld__Option_IconBorderOverlap = 10;
1850 data->icld__Option_IconListMode = (UBYTE)GetTagData(MUIA_IconList_IconListMode, 0, message->ops_AttrList);
1851 data->icld__Option_LabelTextMode = (UBYTE)GetTagData(MUIA_IconList_LabelText_Mode, 0, message->ops_AttrList);
1852 data->icld__Option_LabelTextMaxLen = (ULONG)GetTagData(MUIA_IconList_LabelText_MaxLineLen, ILC_ICONLABEL_MAXLINELEN_DEFAULT, message->ops_AttrList);
1854 if ( data->icld__Option_LabelTextMaxLen < ILC_ICONLABEL_SHORTEST )
1855 data->icld__Option_LabelTextMaxLen = ILC_ICONLABEL_MAXLINELEN_DEFAULT;
1857 data->icld__Option_LastLabelTextMaxLen = data->icld__Option_LabelTextMaxLen;
1859 #if defined(DEBUG_ILC_FUNCS)
1860 D(bug("[IconList] %s: MaxLineLen : %ld\n", __PRETTY_FUNCTION__, data->icld__Option_LabelTextMaxLen));
1861 #endif
1862 data->ehn.ehn_Events = IDCMP_MOUSEBUTTONS | IDCMP_RAWKEY | IDCMP_NEWSIZE;
1863 data->ehn.ehn_Priority = 0;
1864 data->ehn.ehn_Flags = 0;
1865 data->ehn.ehn_Object = obj;
1866 data->ehn.ehn_Class = CLASS;
1868 data->icld_SortFlags = MUIV_IconList_Sort_ByName;
1869 data->icld_DisplayFlags = ICONLIST_DISP_SHOWINFO;
1871 __iconlist_UpdateLabels_hook.h_Entry = (HOOKFUNC)IconList__HookFunc_UpdateLabelsFunc;
1873 DoMethod
1875 obj, MUIM_Notify, MUIA_IconList_LabelText_MaxLineLen, MUIV_EveryTime,
1876 (IPTR)obj, 3,
1877 MUIM_CallHook, &__iconlist_UpdateLabels_hook, (IPTR)CLASS
1880 DoMethod
1882 obj, MUIM_Notify, MUIA_IconList_LabelText_MultiLine, MUIV_EveryTime,
1883 (IPTR)obj, 3,
1884 MUIM_CallHook, &__iconlist_UpdateLabels_hook, (IPTR)CLASS
1887 #if defined(DEBUG_ILC_FUNCS)
1888 D(bug("[IconList] obj = %ld\n", obj));
1889 #endif
1890 return (IPTR)obj;
1894 ///OM_DISPOSE()
1895 /**************************************************************************
1896 OM_DISPOSE
1897 **************************************************************************/
1898 IPTR IconList__OM_DISPOSE(struct IClass *CLASS, Object *obj, Msg message)
1900 struct IconList_DATA *data = INST_DATA(CLASS, obj);
1901 struct IconEntry *node = NULL;
1903 #if defined(DEBUG_ILC_FUNCS)
1904 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
1905 #endif
1907 #if defined(__AROS__)
1908 ForeachNode(&data->icld_IconList, node)
1909 #else
1910 Foreach_Node(&data->icld_IconList, node);
1911 #endif
1913 if (node->ie_DiskObj)
1914 FreeDiskObject(node->ie_DiskObj);
1917 if (data->icld_Pool) DeletePool(data->icld_Pool);
1919 DoSuperMethodA(CLASS,obj,message);
1920 return (IPTR)NULL;
1924 ///OM_SET()
1925 /**************************************************************************
1926 OM_SET
1927 **************************************************************************/
1928 IPTR IconList__OM_SET(struct IClass *CLASS, Object *obj, struct opSet *message)
1930 struct IconList_DATA *data = INST_DATA(CLASS, obj);
1931 struct TagItem *tag = NULL,
1932 *tags = NULL;
1934 WORD oldleft = data->icld_ViewX,
1935 oldtop = data->icld_ViewY;
1936 //oldwidth = data->icld_ViewWidth,
1937 //oldheight = data->icld_ViewHeight;
1939 #if defined(DEBUG_ILC_FUNCS) && defined(DEBUG_ILC_ATTRIBS)
1940 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
1941 #endif
1943 /* parse initial taglist */
1944 for (tags = message->ops_AttrList; (tag = NextTagItem((TAGITEM)&tags)); )
1946 switch (tag->ti_Tag)
1948 case MUIA_Virtgroup_Left:
1949 #if defined(DEBUG_ILC_ATTRIBS)
1950 D(bug("[IconList] %s: MUIA_Virtgroup_Left %ld\n", __PRETTY_FUNCTION__, tag->ti_Data));
1951 #endif
1952 if (data->icld_ViewX != tag->ti_Data)
1953 data->icld_ViewX = tag->ti_Data;
1954 break;
1956 case MUIA_Virtgroup_Top:
1957 #if defined(DEBUG_ILC_ATTRIBS)
1958 D(bug("[IconList] %s: MUIA_Virtgroup_Top %ld\n", __PRETTY_FUNCTION__, tag->ti_Data));
1959 #endif
1960 if (data->icld_ViewY != tag->ti_Data)
1961 data->icld_ViewY = tag->ti_Data;
1962 break;
1964 case MUIA_IconList_Rastport:
1965 #if defined(DEBUG_ILC_ATTRIBS)
1966 D(bug("[IconList] %s: MUIA_IconList_Rastport 0x%p\n", __PRETTY_FUNCTION__, tag->ti_Data));
1967 #endif
1968 data->icld_DisplayRastPort = (struct RastPort*)tag->ti_Data;
1969 data->icld_DrawOffsetX = _mleft(obj);
1970 data->icld_DrawOffsetY = _mtop(obj);
1971 if (data->icld_BufferRastPort != NULL)
1973 //Buffer still set!?!?!
1975 SET(obj, MUIA_IconList_BufferRastport, tag->ti_Data);
1976 break;
1978 case MUIA_IconList_BufferRastport:
1979 #if defined(DEBUG_ILC_ATTRIBS)
1980 D(bug("[IconList] %s: MUIA_IconList_BufferRastport 0x%p\n", __PRETTY_FUNCTION__, tag->ti_Data));
1981 #endif
1982 data->icld_BufferRastPort = (struct RastPort*)tag->ti_Data;
1983 break;
1985 case MUIA_Font:
1986 #if defined(DEBUG_ILC_ATTRIBS)
1987 D(bug("[IconList] %s: MUIA_Font 0x%p\n", __PRETTY_FUNCTION__, tag->ti_Data));
1988 #endif
1989 data->icld_IconLabelFont = (struct TextFont*)tag->ti_Data;
1990 break;
1992 case MUIA_IconList_LabelInfoText_Font:
1993 #if defined(DEBUG_ILC_ATTRIBS)
1994 D(bug("[IconList] %s: MUIA_IconList_LabelInfoText_Font 0x%p\n", __PRETTY_FUNCTION__, tag->ti_Data));
1995 #endif
1996 data->icld_IconInfoFont = (struct TextFont*)tag->ti_Data;
1997 break;
1999 case MUIA_IconList_DisplayFlags:
2001 #if defined(DEBUG_ILC_ATTRIBS)
2002 D(bug("[IconList] %s: MUIA_IconList_DisplayFlags %08x\n", __PRETTY_FUNCTION__, tag->ti_Data));
2003 #endif
2004 data->icld_DisplayFlags = (ULONG)tag->ti_Data;
2006 if (data->icld_DisplayFlags & ICONLIST_DISP_BUFFERED)
2008 struct BitMap *bitmap_New = NULL;
2009 ULONG tmp_RastDepth;
2011 #if defined(DEBUG_ILC_ATTRIBS) && defined(DEBUG_ILC_ICONRENDERING)
2012 D(bug("[IconList] %s: MUIA_IconList_DisplayFlags & ICONLIST_DISP_BUFFERED\n", __PRETTY_FUNCTION__));
2013 #endif
2014 if ((data->icld_BufferRastPort != NULL)
2015 && (data->icld_BufferRastPort != data->icld_DisplayRastPort))
2017 #if defined(DEBUG_ILC_ATTRIBS) && defined(DEBUG_ILC_ICONRENDERING)
2018 D(bug("[IconList] %s: BackLayer @ %p for BackRastport @ %p\n", __PRETTY_FUNCTION__, data->icld_BufferRastPort->Layer, data->icld_BufferRastPort));
2019 #endif
2020 if ((GetBitMapAttr(data->icld_BufferRastPort->BitMap, BMA_WIDTH) != data->icld_ViewWidth)
2021 || (GetBitMapAttr(data->icld_BufferRastPort->BitMap, BMA_HEIGHT) != data->icld_ViewHeight))
2023 struct Layer *oldLayer = data->icld_BufferRastPort->Layer;
2024 #if defined(DEBUG_ILC_ATTRIBS) && defined(DEBUG_ILC_ICONRENDERING)
2025 D(bug("[IconList] %s: Destroying old BackLayer\n", __PRETTY_FUNCTION__));
2026 #endif
2027 data->icld_BufferRastPort = data->icld_DisplayRastPort;
2028 DeleteLayer(0, oldLayer);
2032 if ((data->icld_BufferRastPort == NULL) || (data->icld_BufferRastPort == data->icld_DisplayRastPort))
2034 tmp_RastDepth = GetCyberMapAttr(data->icld_DisplayRastPort->BitMap, CYBRMATTR_DEPTH);
2035 if ((bitmap_New = AllocBitMap(data->icld_ViewWidth,
2036 data->icld_ViewHeight,
2037 tmp_RastDepth,
2038 BMF_CLEAR,
2039 data->icld_DisplayRastPort->BitMap))!=NULL)
2043 struct Layer * buffLayer = CreateLayerTagList(&_screen(obj)->LayerInfo,
2044 bitmap_New,
2047 data->icld_ViewWidth,
2048 data->icld_ViewHeight,
2049 LAYERSIMPLE,
2050 __iconList_BackBuffLayerTags);
2052 if (buffLayer != NULL)
2054 data->icld_BufferRastPort = buffLayer->rp;
2055 #if defined(DEBUG_ILC_ATTRIBS) && defined(DEBUG_ILC_ICONRENDERING)
2056 D(bug("[IconList] %s: FrontRastPort @ %p, New BackLayer @ %p, BackRastport @ %p\n", __PRETTY_FUNCTION__, data->icld_DisplayRastPort, data->icld_BufferRastPort->Layer, data->icld_BufferRastPort));
2057 #endif
2058 SET(obj, MUIA_IconList_BufferRastport, data->icld_BufferRastPort);
2059 data->icld_DrawOffsetX = 0;
2060 data->icld_DrawOffsetY = 0;
2062 else
2064 FreeBitMap(bitmap_New);
2065 data->icld_BufferRastPort = data->icld_DisplayRastPort;
2066 data->icld_DrawOffsetX = _mleft(obj);
2067 data->icld_DrawOffsetY = _mtop(obj);
2072 else
2074 if ((data->icld_BufferRastPort) && (data->icld_BufferRastPort != data->icld_DisplayRastPort))
2076 //Free up the buffers layer, rastport and bitmap since they are no longer needed ..
2077 struct Layer *oldLayer = data->icld_BufferRastPort->Layer;
2078 data->icld_BufferRastPort = data->icld_DisplayRastPort;
2079 DeleteLayer(0, oldLayer);
2080 data->icld_DrawOffsetX = _mleft(obj);
2081 data->icld_DrawOffsetY = _mtop(obj);
2084 SET(obj, MUIA_IconList_Changed, TRUE);
2086 break;
2088 case MUIA_IconList_SortFlags:
2089 #if defined(DEBUG_ILC_ATTRIBS)
2090 D(bug("[IconList] %s: MUIA_IconList_SortFlags %08x\n", __PRETTY_FUNCTION__, tag->ti_Data));
2091 #endif
2092 data->icld_SortFlags = (ULONG)tag->ti_Data;
2093 break;
2095 case MUIA_IconList_IconListMode:
2096 #if defined(DEBUG_ILC_ATTRIBS)
2097 D(bug("[IconList] %s: MUIA_IconList_IconListMode %d\n", __PRETTY_FUNCTION__, tag->ti_Data));
2098 #endif
2099 data->icld__Option_IconListMode = (UBYTE)tag->ti_Data;
2100 break;
2102 case MUIA_IconList_LabelText_Mode:
2103 #if defined(DEBUG_ILC_ATTRIBS)
2104 D(bug("[IconList] %s: MUIA_IconList_LabelText_Mode %d\n", __PRETTY_FUNCTION__, tag->ti_Data));
2105 #endif
2106 data->icld__Option_LabelTextMode = (UBYTE)tag->ti_Data;
2107 break;
2109 case MUIA_IconList_LabelText_MaxLineLen:
2110 #if defined(DEBUG_ILC_ATTRIBS)
2111 D(bug("[IconList] %s: MUIA_IconList_LabelText_MaxLineLen %d\n", __PRETTY_FUNCTION__, tag->ti_Data));
2112 #endif
2113 if (tag->ti_Data >= ILC_ICONLABEL_SHORTEST)
2115 data->icld__Option_LabelTextMaxLen = (ULONG)tag->ti_Data;
2117 else
2119 data->icld__Option_LabelTextMaxLen = ILC_ICONLABEL_MAXLINELEN_DEFAULT;
2121 break;
2123 case MUIA_IconList_LabelText_MultiLine:
2124 #if defined(DEBUG_ILC_ATTRIBS)
2125 D(bug("[IconList] %s: MUIA_IconList_LabelText_MultiLine %d\n", __PRETTY_FUNCTION__, tag->ti_Data));
2126 #endif
2127 data->icld__Option_LabelTextMultiLine = (ULONG)tag->ti_Data;
2128 if (data->icld__Option_LabelTextMultiLine == 0)data->icld__Option_LabelTextMultiLine = 1;
2129 break;
2131 case MUIA_IconList_LabelText_MultiLineOnFocus:
2132 #if defined(DEBUG_ILC_ATTRIBS)
2133 D(bug("[IconList] %s: MUIA_IconList_LabelText_MultiLineOnFocus %d\n", __PRETTY_FUNCTION__, tag->ti_Data));
2134 #endif
2135 data->icld__Option_LabelTextMultiLineOnFocus = (BOOL)tag->ti_Data;
2136 break;
2138 case MUIA_IconList_Icon_HorizontalSpacing:
2139 #if defined(DEBUG_ILC_ATTRIBS)
2140 D(bug("[IconList] %s: MUIA_IconList_Icon_HorizontalSpacing %d\n", __PRETTY_FUNCTION__, tag->ti_Data));
2141 #endif
2142 data->icld__Option_IconHorizontalSpacing = (UBYTE)tag->ti_Data;
2143 break;
2145 case MUIA_IconList_Icon_VerticalSpacing:
2146 #if defined(DEBUG_ILC_ATTRIBS)
2147 D(bug("[IconList] %s: MUIA_IconList_Icon_VerticalSpacing %d\n", __PRETTY_FUNCTION__, tag->ti_Data));
2148 #endif
2149 data->icld__Option_IconVerticalSpacing = (UBYTE)tag->ti_Data;
2150 break;
2152 case MUIA_IconList_Icon_ImageSpacing:
2153 #if defined(DEBUG_ILC_ATTRIBS)
2154 D(bug("[IconList] %s: MUIA_IconList_Icon_ImageSpacing %d\n", __PRETTY_FUNCTION__, tag->ti_Data));
2155 #endif
2156 data->icld__Option_IconImageSpacing = (UBYTE)tag->ti_Data;
2157 break;
2159 case MUIA_IconList_LabelText_HorizontalPadding:
2160 #if defined(DEBUG_ILC_ATTRIBS)
2161 D(bug("[IconList] %s: MUIA_IconList_LabelText_HorizontalPadding %d\n", __PRETTY_FUNCTION__, tag->ti_Data));
2162 #endif
2163 data->icld__Option_LabelTextHorizontalPadding = (UBYTE)tag->ti_Data;
2164 break;
2166 case MUIA_IconList_LabelText_VerticalPadding:
2167 #if defined(DEBUG_ILC_ATTRIBS)
2168 D(bug("[IconList] %s: MUIA_IconList_LabelText_VerticalPadding %d\n", __PRETTY_FUNCTION__, tag->ti_Data));
2169 #endif
2170 data->icld__Option_LabelTextVerticalPadding = (UBYTE)tag->ti_Data;
2171 break;
2173 case MUIA_IconList_LabelText_BorderWidth:
2174 #if defined(DEBUG_ILC_ATTRIBS)
2175 D(bug("[IconList] %s: MUIA_IconList_LabelText_BorderWidth %d\n", __PRETTY_FUNCTION__, tag->ti_Data));
2176 #endif
2177 data->icld__Option_LabelTextBorderWidth = (UBYTE)tag->ti_Data;
2178 break;
2180 case MUIA_IconList_LabelText_BorderHeight:
2181 #if defined(DEBUG_ILC_ATTRIBS)
2182 D(bug("[IconList] %s: MUIA_IconList_LabelText_BorderHeight %d\n", __PRETTY_FUNCTION__, tag->ti_Data));
2183 #endif
2184 data->icld__Option_LabelTextBorderHeight = (UBYTE)tag->ti_Data;
2185 break;
2187 case MUIA_IconList_LabelText_Pen:
2188 data->icld_LabelPen = (ULONG)tag->ti_Data;
2189 break;
2191 case MUIA_IconList_LabelText_ShadowPen:
2192 data->icld_LabelShadowPen = (ULONG)tag->ti_Data;
2193 break;
2195 case MUIA_IconList_LabelInfoText_Pen:
2196 data->icld_InfoPen = (ULONG)tag->ti_Data;
2197 break;
2199 case MUIA_IconList_LabelInfoText_ShadowPen:
2200 data->icld_InfoShadowPen = (ULONG)tag->ti_Data;
2201 break;
2203 /* Settings defined by the view class */
2204 case MUIA_IconListview_FixedBackground:
2205 #if defined(DEBUG_ILC_ATTRIBS)
2206 D(bug("[IconList] %s: MUIA_IconListview_FixedBackground\n", __PRETTY_FUNCTION__));
2207 #endif
2208 data->icld__Option_IconListFixedBackground = (BOOL)tag->ti_Data;
2209 break;
2211 case MUIA_IconListview_ScaledBackground:
2212 #if defined(DEBUG_ILC_ATTRIBS)
2213 D(bug("[IconList] %s: MUIA_IconListview_ScaledBackground\n", __PRETTY_FUNCTION__));
2214 #endif
2215 data->icld__Option_IconListScaledBackground = (BOOL)tag->ti_Data;
2216 break;
2218 /* We listen for MUIA_Background and set default values for known types */
2219 case MUIA_Background:
2220 #if defined(DEBUG_ILC_ATTRIBS) && defined(DEBUG_ILC_ICONRENDERING)
2221 D(bug("[IconList] %s: MUIA_Background\n", __PRETTY_FUNCTION__));
2222 #endif
2224 char *bgmode_string = (char *)tag->ti_Data;
2225 BYTE this_mode = bgmode_string[0] - 48;
2227 #if defined(DEBUG_ILC_ATTRIBS) && defined(DEBUG_ILC_ICONRENDERING)
2228 D(bug("[IconList] %s: MUIA_Background | MUI BG Mode = %d\n", __PRETTY_FUNCTION__, this_mode));
2229 #endif
2230 switch (this_mode)
2232 case 0:
2233 //MUI Pattern
2234 NNSET(obj, MUIA_IconListview_FixedBackground, FALSE);
2235 NNSET(obj, MUIA_IconListview_ScaledBackground, FALSE);
2236 break;
2237 case 2:
2238 //MUI RGB color
2239 NNSET(obj, MUIA_IconListview_FixedBackground, FALSE);
2240 NNSET(obj, MUIA_IconListview_ScaledBackground, FALSE);
2241 break;
2242 case 7:
2243 //Zune Gradient
2244 NNSET(obj, MUIA_IconListview_FixedBackground, TRUE);
2245 NNSET(obj, MUIA_IconListview_ScaledBackground, TRUE);
2246 break;
2247 case 5:
2248 //Image
2249 NNSET(obj, MUIA_IconListview_FixedBackground, FALSE);
2250 NNSET(obj, MUIA_IconListview_ScaledBackground, FALSE);
2251 break;
2254 break;
2255 case MUIA_IconList_IconsDropped:
2256 data->icld_DragDropEvent = (struct IconList_Drop_Event *)tag->ti_Data;
2257 break;
2261 #if defined(DEBUG_ILC_ATTRIBS)
2262 D(bug("[IconList] %s(), out of switch\n", __PRETTY_FUNCTION__));
2263 #endif
2264 if ((oldleft != data->icld_ViewX) || (oldtop != data->icld_ViewY))
2266 data->icld_UpdateMode = UPDATE_SCROLL;
2267 data->update_scrolldx = data->icld_ViewX - oldleft;
2268 data->update_scrolldy = data->icld_ViewY - oldtop;
2269 #if defined(DEBUG_ILC_ATTRIBS)
2270 D(bug("[IconList] %s(), call MUI_Redraw()\n", __PRETTY_FUNCTION__));
2271 #endif
2272 MUI_Redraw(obj, MADF_DRAWUPDATE);
2275 #if defined(DEBUG_ILC_ATTRIBS)
2276 D(bug("[IconList] %s(), call DoSuperMethodA()\n", __PRETTY_FUNCTION__));
2277 #endif
2278 return DoSuperMethodA(CLASS, obj, (Msg)message);
2282 ///OM_GET()
2283 /**************************************************************************
2284 OM_GET
2285 **************************************************************************/
2286 IPTR IconList__OM_GET(struct IClass *CLASS, Object *obj, struct opGet *message)
2288 /* small macro to simplify return value storage */
2289 #define STORE *(message->opg_Storage)
2290 struct IconList_DATA *data = INST_DATA(CLASS, obj);
2292 #if defined(DEBUG_ILC_FUNCS) && defined(DEBUG_ILC_ATTRIBS)
2293 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
2294 #endif
2296 switch (message->opg_AttrID)
2298 case MUIA_IconList_Rastport: STORE = (IPTR)data->icld_DisplayRastPort; return 1;
2299 case MUIA_IconList_BufferRastport: STORE = (IPTR)data->icld_BufferRastPort; return 1;
2300 case MUIA_IconList_BufferLeft: STORE = (IPTR)data->icld_DrawOffsetX; return 1;
2301 case MUIA_IconList_BufferTop: STORE = (IPTR)data->icld_DrawOffsetY; return 1;
2302 case MUIA_IconList_BufferWidth:
2303 case MUIA_IconList_Width: STORE = (IPTR)data->icld_AreaWidth; return 1;
2304 case MUIA_IconList_BufferHeight:
2305 case MUIA_IconList_Height: STORE = (IPTR)data->icld_AreaHeight; return 1;
2306 case MUIA_IconList_IconsDropped: STORE = (IPTR)data->icld_DragDropEvent; return 1;
2307 case MUIA_IconList_Clicked: STORE = (IPTR)&data->icld_ClickEvent; return 1;
2308 case MUIA_IconList_IconListMode: STORE = (IPTR)data->icld__Option_IconListMode; return 1;
2309 case MUIA_IconList_LabelText_Mode: STORE = (IPTR)data->icld__Option_LabelTextMode; return 1;
2310 case MUIA_IconList_LabelText_MaxLineLen: STORE = (IPTR)data->icld__Option_LabelTextMaxLen; return 1;
2311 case MUIA_IconList_LabelText_MultiLine: STORE = (IPTR)data->icld__Option_LabelTextMultiLine; return 1;
2312 case MUIA_IconList_LabelText_MultiLineOnFocus: STORE = (IPTR)data->icld__Option_LabelTextMultiLineOnFocus; return 1;
2313 case MUIA_IconList_DisplayFlags: STORE = (IPTR)data->icld_DisplayFlags; return 1;
2314 case MUIA_IconList_SortFlags: STORE = (IPTR)data->icld_SortFlags; return 1;
2316 case MUIA_IconList_FocusIcon: STORE = (IPTR)data->icld_FocusIcon; return 1;
2318 case MUIA_Font: STORE = (IPTR)data->icld_IconLabelFont; return 1;
2319 case MUIA_IconList_LabelText_Pen: STORE = (IPTR)data->icld_LabelPen; return 1;
2320 case MUIA_IconList_LabelText_ShadowPen: STORE = (IPTR)data->icld_LabelShadowPen; return 1;
2321 case MUIA_IconList_LabelInfoText_Font: STORE = (IPTR)data->icld_IconInfoFont; return 1;
2322 case MUIA_IconList_LabelInfoText_Pen: STORE = (IPTR)data->icld_InfoPen; return 1;
2323 case MUIA_IconList_LabelInfoText_ShadowPen: STORE = (IPTR)data->icld_InfoShadowPen; return 1;
2325 case MUIA_IconList_Icon_HorizontalSpacing: STORE = (IPTR)data->icld__Option_IconHorizontalSpacing; return 1;
2326 case MUIA_IconList_Icon_VerticalSpacing: STORE = (IPTR)data->icld__Option_IconVerticalSpacing; return 1;
2327 case MUIA_IconList_Icon_ImageSpacing: STORE = (IPTR)data->icld__Option_IconImageSpacing; return 1;
2328 case MUIA_IconList_LabelText_HorizontalPadding: STORE = (IPTR)data->icld__Option_LabelTextHorizontalPadding; return 1;
2329 case MUIA_IconList_LabelText_VerticalPadding: STORE = (IPTR)data->icld__Option_LabelTextVerticalPadding; return 1;
2330 case MUIA_IconList_LabelText_BorderWidth: STORE = (IPTR)data->icld__Option_LabelTextBorderWidth; return 1;
2331 case MUIA_IconList_LabelText_BorderHeight: STORE = (IPTR)data->icld__Option_LabelTextBorderHeight; return 1;
2333 /* Settings defined by the view class */
2334 case MUIA_IconListview_FixedBackground: STORE = (IPTR)data->icld__Option_IconListFixedBackground; return 1;
2335 case MUIA_IconListview_ScaledBackground: STORE = (IPTR)data->icld__Option_IconListScaledBackground; return 1;
2337 /* ICON obj Changes */
2338 case MUIA_Virtgroup_Left: STORE = (IPTR)data->icld_ViewX; return 1;
2339 case MUIA_Virtgroup_Top: STORE = (IPTR)data->icld_ViewY; return 1;
2340 case MUIA_Family_List: STORE = (IPTR)&(data->icld_IconList); return 1; /* Get our list object */
2342 #warning "TODO: Get the version/revision from our config.."
2343 case MUIA_Version: STORE = (IPTR)1; return 1;
2344 case MUIA_Revision: STORE = (IPTR)7; return 1;
2347 return DoSuperMethodA(CLASS, obj, (Msg) message);
2348 #undef STORE
2352 IPTR IconList__MUIM_Family_AddHead(struct IClass *CLASS, Object *obj, struct MUIP_Family_AddHead *message)
2354 struct IconList_DATA *data = INST_DATA(CLASS, obj);
2355 #if defined(DEBUG_ILC_FUNCS)
2356 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
2357 #endif
2359 if (message->obj)
2361 #warning "TODO: Use the correct _OBJECT() code when we switch to icon.mui"
2362 // AddHead(&(data->icld_IconList), (struct Node *)_OBJECT(message->obj));
2363 AddHead(&(data->icld_IconList), (struct Node *)message->obj);
2364 return TRUE;
2366 else
2367 return FALSE;
2370 IPTR IconList__MUIM_Family_AddTail(struct IClass *CLASS, Object *obj, struct MUIP_Family_AddTail *message)
2372 struct IconList_DATA *data = INST_DATA(CLASS, obj);
2373 #if defined(DEBUG_ILC_FUNCS)
2374 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
2375 #endif
2377 D(bug("[IconList] %s: list @ 0x%p, icon @ 0x%p '%s'\n", __PRETTY_FUNCTION__, &(data->icld_IconList), message->obj, ((struct IconEntry *)message->obj)->ie_IconNode.ln_Name));
2379 if (message->obj)
2381 #warning "TODO: Use the correct _OBJECT() code when we switch to icon.mui"
2382 // AddTail(&(data->icld_IconList), (struct Node *)_OBJECT(message->obj));
2383 AddTail(&(data->icld_IconList), (struct Node *)message->obj);
2384 return TRUE;
2386 else
2387 return FALSE;
2389 return (IPTR)NULL;
2391 #if !defined(WANDERER_BUILTIN_ICONLIST)
2392 IPTR IconList__OM_ADDMEMBER(struct IClass *CLASS, Object *obj, struct MUIP_Family_AddTail *message)
2394 return IconList__MUIM_Family_AddTail(CLASS, obj, message);
2396 #endif
2398 IPTR IconList__MUIM_Family_Remove(struct IClass *CLASS, Object *obj, struct MUIP_Family_Remove *message)
2400 struct IconList_DATA *data = INST_DATA(CLASS, obj);
2401 #if defined(DEBUG_ILC_FUNCS)
2402 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
2403 #endif
2405 D(bug("[IconList] %s: icon @ 0x%p '%s'\n", __PRETTY_FUNCTION__, message->obj, ((struct IconEntry *)message->obj)->ie_IconNode.ln_Name));
2407 if (message->obj)
2409 #warning "TODO: Use the correct _OBJECT() code when we switch to icon.mui"
2410 // Remove((struct Node *)_OBJECT(message->obj));
2411 Remove((struct Node *)message->obj);
2412 return TRUE;
2414 else
2415 return FALSE;
2417 return (IPTR)NULL;
2419 #if !defined(WANDERER_BUILTIN_ICONLIST)
2420 IPTR IconList__OM_REMMEMBER(struct IClass *CLASS, Object *obj, struct MUIP_Family_Remove *message)
2422 return IconList__MUIM_Family_Remove(CLASS, obj, message);
2424 #endif
2426 ///MUIM_Setup()
2427 /**************************************************************************
2428 MUIM_Setup
2429 **************************************************************************/
2430 IPTR IconList__MUIM_Setup(struct IClass *CLASS, Object *obj, struct MUIP_Setup *message)
2432 struct IconList_DATA *data = INST_DATA(CLASS, obj);
2433 struct IconEntry *node = NULL;
2434 IPTR geticon_error = 0;
2436 #if defined(DEBUG_ILC_FUNCS)
2437 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
2438 #endif
2440 if (!DoSuperMethodA(CLASS, obj, (Msg) message)) return (IPTR)NULL;
2442 DoMethod(_win(obj), MUIM_Window_AddEventHandler, (IPTR)&data->ehn);
2444 /* Get Internal Objects to use if not set .. */
2445 data->icld_DisplayRastPort = NULL;
2446 data->icld_BufferRastPort = NULL;
2448 if (data->icld_IconLabelFont == NULL) data->icld_IconLabelFont = _font(obj);
2449 if (data->icld_IconInfoFont == NULL) data->icld_IconInfoFont = data->icld_IconLabelFont;
2450 #if defined(DEBUG_ILC_ICONRENDERING)
2451 D(bug("[IconList] %s: Use Font @ 0x%p, RastPort @ 0x%p\n", __PRETTY_FUNCTION__, data->icld_IconLabelFont, data->icld_BufferRastPort ));
2452 #endif
2454 /* Set our base options .. */
2455 data->icld_LabelPen = _pens(obj)[MPEN_SHINE];
2456 data->icld_LabelShadowPen = _pens(obj)[MPEN_SHADOW];
2457 data->icld_InfoPen = _pens(obj)[MPEN_SHINE];
2458 data->icld_InfoShadowPen = _pens(obj)[MPEN_SHADOW];
2460 data->icld__Option_LabelTextMultiLine = 1;
2461 data->icld__Option_LastLabelTextMultiLine = data->icld__Option_LabelTextMultiLine;
2463 data->icld__Option_LabelTextMultiLineOnFocus = FALSE;
2465 data->icld__Option_IconHorizontalSpacing = ILC_ICON_HORIZONTALMARGIN_DEFAULT;
2466 data->icld__Option_IconVerticalSpacing = ILC_ICON_VERTICALMARGIN_DEFAULT;
2467 data->icld__Option_IconImageSpacing = ILC_ICONLABEL_IMAGEMARGIN_DEFAULT;
2468 data->icld__Option_LabelTextHorizontalPadding = ILC_ICONLABEL_HORIZONTALTEXTMARGIN_DEFAULT;
2469 data->icld__Option_LabelTextVerticalPadding = ILC_ICONLABEL_VERTICALTEXTMARGIN_DEFAULT;
2470 data->icld__Option_LabelTextBorderWidth = ILC_ICONLABEL_BORDERWIDTH_DEFAULT;
2471 data->icld__Option_LabelTextBorderHeight = ILC_ICONLABEL_BORDERHEIGHT_DEFAULT;
2473 #if defined(__AROS__)
2474 ForeachNode(&data->icld_IconList, node)
2475 #else
2476 Foreach_Node(&data->icld_IconList, node);
2477 #endif
2479 if (!node->ie_DiskObj)
2481 IPTR iconlistScreen = _screen(obj);
2482 #if defined(DEBUG_ILC_ICONRENDERING)
2483 D(bug("[IconList] %s: IconList Screen @ 0x%p)\n", __PRETTY_FUNCTION__, iconlistScreen));
2484 #endif
2485 if (!(node->ie_DiskObj = GetIconTags(node->ie_IconNode.ln_Name,
2486 (iconlistScreen) ? ICONGETA_Screen : TAG_IGNORE, iconlistScreen,
2487 (iconlistScreen) ? ICONGETA_RemapIcon : TAG_IGNORE, TRUE,
2488 ICONGETA_GenerateImageMasks, TRUE,
2489 ICONGETA_FailIfUnavailable, FALSE,
2490 ICONA_ErrorCode, &geticon_error,
2491 TAG_DONE)))
2493 #if defined(DEBUG_ILC_ICONRENDERING)
2494 D(bug("[IconList] %s: Failed to obtain Icon '%s's diskobj! (error code = 0x%p)\n", __PRETTY_FUNCTION__, node->ie_IconNode.ln_Name, geticon_error));
2495 #endif
2496 /* We should probably remove this node if the icon cant be obtained ? */
2500 return 1;
2504 ///MUIM_Show()
2505 /**************************************************************************
2506 MUIM_Show
2507 **************************************************************************/
2508 IPTR IconList__MUIM_Show(struct IClass *CLASS, Object *obj, struct MUIP_Show *message)
2510 struct IconList_DATA *data = INST_DATA(CLASS, obj);
2511 LONG newleft,
2512 newtop;
2513 IPTR rc;
2515 #if defined(DEBUG_ILC_FUNCS)
2516 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
2517 #endif
2519 if ((rc = DoSuperMethodA(CLASS, obj, (Msg)message)))
2521 newleft = data->icld_ViewX;
2522 newtop = data->icld_ViewY;
2524 if (newleft + _mwidth(obj) > data->icld_AreaWidth)
2525 newleft = data->icld_AreaWidth - _mwidth(obj);
2526 if (newleft < 0)
2527 newleft = 0;
2529 if (newtop + _mheight(obj) > data->icld_AreaHeight)
2530 newtop = data->icld_AreaHeight - _mheight(obj);
2531 if (newtop < 0)
2532 newtop = 0;
2534 if ((newleft != data->icld_ViewX) || (newtop != data->icld_ViewY))
2536 SetAttrs(obj, MUIA_Virtgroup_Left, newleft,
2537 MUIA_Virtgroup_Top, newtop,
2538 TAG_DONE);
2541 /* Get Internal Objects to use if not set .. */
2542 if (data->icld_DisplayRastPort == NULL)
2544 if (_rp(obj) != NULL)
2546 data->icld_DisplayRastPort = CloneRastPort(_rp(obj));
2548 #if defined(DEBUG_ILC_ICONRENDERING)
2549 else
2551 D(bug("[IconList] IconList__MUIM_Show: ERROR - NULL RastPort!\n"));
2553 #endif
2556 if (data->icld_DisplayFlags & ICONLIST_DISP_BUFFERED)
2558 struct BitMap *bitmap_New = NULL;
2559 ULONG tmp_RastDepth = GetCyberMapAttr(data->icld_DisplayRastPort->BitMap, CYBRMATTR_DEPTH);
2560 if ((bitmap_New = AllocBitMap(data->icld_ViewWidth,
2561 data->icld_ViewHeight,
2562 tmp_RastDepth,
2563 BMF_CLEAR,
2564 data->icld_DisplayRastPort->BitMap))!=NULL)
2566 struct Layer * buffLayer = CreateLayerTagList(&_screen(obj)->LayerInfo,
2567 bitmap_New,
2570 data->icld_ViewWidth,
2571 data->icld_ViewHeight,
2572 LAYERSIMPLE,
2573 __iconList_BackBuffLayerTags);
2575 if (buffLayer != NULL)
2577 data->icld_BufferRastPort = buffLayer->rp;
2578 #if defined(DEBUG_ILC_ATTRIBS) && defined(DEBUG_ILC_ICONRENDERING)
2579 D(bug("[IconList] %s: FrontRastPort @ %p, New BackLayer @ %p, BackRastport @ %p\n", __PRETTY_FUNCTION__, data->icld_DisplayRastPort, data->icld_BufferRastPort->Layer, data->icld_BufferRastPort));
2580 #endif
2581 SET(obj, MUIA_IconList_BufferRastport, data->icld_BufferRastPort);
2582 data->icld_DrawOffsetX = 0;
2583 data->icld_DrawOffsetY = 0;
2585 else
2587 FreeBitMap(bitmap_New);
2588 data->icld_BufferRastPort = data->icld_DisplayRastPort;
2589 data->icld_DrawOffsetX = _mleft(obj);
2590 data->icld_DrawOffsetY = _mtop(obj);
2594 else
2596 data->icld_BufferRastPort = data->icld_DisplayRastPort;
2597 data->icld_DrawOffsetX = _mleft(obj);
2598 data->icld_DrawOffsetY = _mtop(obj);
2601 if (data->icld_IconLabelFont == NULL) data->icld_IconLabelFont = _font(obj);
2602 if (data->icld_IconInfoFont == NULL) data->icld_IconInfoFont = data->icld_IconLabelFont;
2603 #if defined(DEBUG_ILC_ICONRENDERING)
2604 D(bug("[IconList] IconList__MUIM_Show: Use Font @ 0x%p, RastPort @ 0x%p\n", data->icld_IconLabelFont, data->icld_BufferRastPort ));
2605 #endif
2607 if ((data->icld_BufferRastPort) && (data->icld_IconLabelFont))
2608 SetFont(data->icld_BufferRastPort, data->icld_IconLabelFont);
2610 return rc;
2614 ///MUIM_Hide()
2615 /**************************************************************************
2616 MUIM_Hide
2617 **************************************************************************/
2618 IPTR IconList__MUIM_Hide(struct IClass *CLASS, Object *obj, struct MUIP_Hide *message)
2620 struct IconList_DATA *data = INST_DATA(CLASS, obj);
2621 IPTR rc;
2623 #if defined(DEBUG_ILC_FUNCS)
2624 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
2625 #endif
2627 if ((rc = DoSuperMethodA(CLASS, obj, (Msg)message)))
2629 if ((data->icld_BufferRastPort) && (data->icld_BufferRastPort != data->icld_DisplayRastPort))
2631 DeleteLayer(0, data->icld_BufferRastPort->Layer);
2634 data->icld_BufferRastPort = NULL;
2636 if (data->icld_DisplayRastPort)
2637 FreeRastPort(data->icld_DisplayRastPort);
2639 data->icld_DisplayRastPort = NULL;
2641 return rc;
2645 ///MUIM_Cleanup()
2646 /**************************************************************************
2647 MUIM_Cleanup
2648 **************************************************************************/
2649 IPTR IconList__MUIM_Cleanup(struct IClass *CLASS, Object *obj, struct MUIP_Cleanup *message)
2651 struct IconList_DATA *data = INST_DATA(CLASS, obj);
2652 struct IconEntry *node = NULL;
2654 #if defined(DEBUG_ILC_FUNCS)
2655 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
2656 #endif
2658 #if defined(__AROS__)
2659 ForeachNode(&data->icld_IconList, node)
2660 #else
2661 Foreach_Node(&data->icld_IconList, node);
2662 #endif
2664 if (node->ie_DiskObj)
2666 FreeDiskObject(node->ie_DiskObj);
2667 node->ie_DiskObj = NULL;
2671 DoMethod(_win(obj), MUIM_Window_RemEventHandler, (IPTR)&data->ehn);
2673 return DoSuperMethodA(CLASS, obj, (Msg)message);
2677 ///MUIM_AskMinMax()
2678 /**************************************************************************
2679 MUIM_AskMinMax
2680 **************************************************************************/
2681 IPTR IconList__MUIM_AskMinMax(struct IClass *CLASS, Object *obj, struct MUIP_AskMinMax *message)
2683 ULONG rc = DoSuperMethodA(CLASS, obj, (Msg) message);
2685 #if defined(DEBUG_ILC_FUNCS)
2686 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
2687 #endif
2689 message->MinMaxInfo->MinWidth += 96;
2690 message->MinMaxInfo->MinHeight += 64;
2692 message->MinMaxInfo->DefWidth += 200;
2693 message->MinMaxInfo->DefHeight += 180;
2695 message->MinMaxInfo->MaxWidth = MUI_MAXMAX;
2696 message->MinMaxInfo->MaxHeight = MUI_MAXMAX;
2698 return rc;
2702 ///MUIM_Layout()
2703 /**************************************************************************
2704 MUIM_Layout
2705 **************************************************************************/
2706 IPTR IconList__MUIM_Layout(struct IClass *CLASS, Object *obj,struct MUIP_Layout *message)
2708 struct IconList_DATA *data = INST_DATA(CLASS, obj);
2709 ULONG rc;
2711 #if defined(DEBUG_ILC_FUNCS)
2712 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
2713 #endif
2715 rc = DoSuperMethodA(CLASS, obj, (Msg)message);
2717 data->icld_ViewWidth = _mwidth(obj);
2718 data->icld_ViewHeight = _mheight(obj);
2720 return rc;
2724 static LONG FirstVisibleLine(struct IconList_DATA *data)
2726 return data->icld_ViewY / data->icld_LVMAttribs->lmva_RowHeight;
2729 static LONG NumVisibleLines(struct IconList_DATA *data)
2731 LONG visible = data->icld_ViewHeight + data->icld_LVMAttribs->lmva_RowHeight - 1 +
2732 (data->icld_ViewY % data->icld_LVMAttribs->lmva_RowHeight);
2734 visible /= data->icld_LVMAttribs->lmva_RowHeight;
2736 return visible;
2739 static void RenderListViewModeHeaderField(Object *obj, struct IconList_DATA *data,
2740 struct Rectangle *rect, LONG index)
2742 STRPTR text;
2743 struct TextExtent te;
2744 ULONG fit;
2745 BOOL sel = FALSE;
2747 #if defined(DEBUG_ILC_FUNCS)
2748 D(bug("[IconList]: %s(obj @ 0x%p)\n", __PRETTY_FUNCTION__, obj));
2749 #endif
2751 if ((data->icld_LVMAttribs->lvma_Flags & LVMAF_NOHEADER) == 0)
2754 if ((data->inputstate == INPUTSTATE_COL_HEADER_CLICK) &&
2755 (data->click_column == index))
2758 if (ColumnHeaderUnderMouse(data, data->click_x, data->click_y) == index)
2760 sel = TRUE;
2765 text = data->icld_LVMAttribs->lmva_ColumnTitle[index];
2767 SetAPen(data->icld_BufferRastPort, _pens(obj)[sel ? MPEN_HALFSHADOW : MPEN_HALFSHINE]);
2768 RectFill(data->icld_BufferRastPort, rect->MinX + 1, rect->MinY + 1,
2769 rect->MaxX - 1, rect->MaxY - 1);
2770 SetAPen(data->icld_BufferRastPort, _pens(obj)[sel ? MPEN_SHADOW : MPEN_SHINE]);
2771 RectFill(data->icld_BufferRastPort, rect->MinX, rect->MinY, rect->MinX, rect->MaxY);
2772 RectFill(data->icld_BufferRastPort, rect->MinX + 1, rect->MinY, rect->MaxX - 1, rect->MinY);
2773 SetAPen(data->icld_BufferRastPort, _pens(obj)[sel ? MPEN_HALFSHINE : MPEN_HALFSHADOW]);
2774 RectFill(data->icld_BufferRastPort, rect->MaxX, rect->MinY, rect->MaxX, rect->MaxY);
2775 RectFill(data->icld_BufferRastPort, rect->MinX + 1, rect->MaxY, rect->MaxX - 1, rect->MaxY);
2777 if (index == data->icld_LVMAttribs->lmva_SortColumn)
2779 LONG x = rect->MaxX - 4 - 6;
2780 LONG y = (rect->MinY + rect->MaxY + 1) / 2 - 3;
2782 if (x > rect->MinX)
2784 SetAPen(data->icld_BufferRastPort, _pens(obj)[sel ? MPEN_SHADOW : MPEN_HALFSHADOW]);
2785 if (data->icld_SortFlags & MUIV_IconList_Sort_Reverse)
2787 RectFill(data->icld_BufferRastPort, x, y, x + 5, y + 1);
2788 RectFill(data->icld_BufferRastPort, x + 1, y + 2, x + 4, y + 3);
2789 RectFill(data->icld_BufferRastPort, x + 2, y + 4, x + 3, y + 5);
2791 else
2793 RectFill(data->icld_BufferRastPort, x, y + 4, x + 5, y + 5);
2794 RectFill(data->icld_BufferRastPort, x + 1, y + 2, x + 4, y + 3);
2795 RectFill(data->icld_BufferRastPort, x + 2, y, x + 3, y + 1);
2800 rect->MinX += HEADERENTRY_SPACING_LEFT;
2801 rect->MinY += HEADERLINE_SPACING_TOP;
2802 rect->MaxX -= HEADERENTRY_SPACING_RIGHT;
2803 rect->MaxY -= HEADERLINE_SPACING_BOTTOM;
2805 if (text && text[0])
2808 fit = TextFit(data->icld_BufferRastPort, text, strlen(text), &te, NULL, 1,
2809 rect->MaxX - rect->MinX + 1,
2810 rect->MaxY - rect->MinY + 1);
2812 if (!fit) return;
2814 SetABPenDrMd(data->icld_BufferRastPort, _pens(obj)[MPEN_TEXT], 0, JAM1);
2815 Move(data->icld_BufferRastPort, rect->MinX, rect->MinY + data->icld_BufferRastPort->TxBaseline);
2816 Text(data->icld_BufferRastPort, text, fit);
2821 static void RenderListViewModeHeader(Object *obj, struct IconList_DATA *data)
2823 struct Rectangle linerect;
2824 LONG x, i;
2825 LONG firstvis, lastvis;
2827 #if defined(DEBUG_ILC_FUNCS)
2828 D(bug("[IconList]: %s(obj @ 0x%p)\n", __PRETTY_FUNCTION__, obj));
2829 #endif
2831 if ((data->icld_LVMAttribs->lvma_Flags & LVMAF_NOHEADER) == 0)
2833 linerect.MinX = _mleft(obj) - data->icld_ViewX;
2834 linerect.MaxX = _mright(obj);
2835 linerect.MinY = _mtop(obj);
2836 linerect.MaxY = _mtop(obj) + data->icld_LVMAttribs->lmva_HeaderHeight - 1;
2838 SetFont(data->icld_BufferRastPort, data->icld_IconLabelFont);
2840 x = linerect.MinX + HEADERLINE_SPACING_LEFT;
2842 firstvis = FirstVisibleColumnNumber(data);
2843 lastvis = LastVisibleColumnNumber(data);
2845 for(i = 0; i < NUM_COLUMNS; i++)
2847 LONG index = data->icld_LVMAttribs->lmva_ColumnPos[i];
2849 if (!data->icld_LVMAttribs->lmva_ColumnVisible[index]) continue;
2851 BOOL outside = FALSE;
2852 struct Rectangle field_rect;
2854 field_rect.MinX = (i == firstvis) ? linerect.MinX : x;
2855 field_rect.MinY = linerect.MinY;
2856 field_rect.MaxX = x + data->icld_LVMAttribs->lmva_ColumnWidth[index] - 1 + ((i == lastvis) ? HEADERLINE_SPACING_RIGHT : 0);
2857 field_rect.MaxY = linerect.MaxY;
2859 /* data->update_rect1 and data->update_rect2 may
2860 point to rectangles to indicate that only icons
2861 in any of this rectangles need to be drawn */
2862 if (data->update_rect1)
2864 if (!RectAndRect(&field_rect, data->update_rect1))
2865 outside = TRUE;
2868 if (data->update_rect2)
2870 if (data->update_rect1)
2872 if ((outside == TRUE) && RectAndRect(&field_rect, data->update_rect2))
2873 outside = FALSE;
2875 else
2877 if (!RectAndRect(&field_rect, data->update_rect2))
2878 outside = TRUE;
2882 if (outside != TRUE)
2884 RenderListViewModeHeaderField(obj, data, &field_rect, index);
2885 x += data->icld_LVMAttribs->lmva_ColumnWidth[index];
2887 else
2889 D(bug("[IconList] %s: Column '%s' outside of update area .. skipping\n", __PRETTY_FUNCTION__, data->icld_LVMAttribs->lmva_ColumnTitle[i]));
2893 if ((data->icld_LVMAttribs->lvma_Flags & LVMAF_HEADERDRAWTOEND) == LVMAF_HEADERDRAWTOEND)
2895 x += HEADERLINE_SPACING_RIGHT;
2897 if (x < linerect.MaxX)
2899 linerect.MinX = x;
2901 // if (MustRenderRect(data, &linerect))
2902 // {
2903 SetABPenDrMd(data->icld_BufferRastPort, _pens(obj)[MPEN_HALFSHINE], 0, JAM1);
2904 RectFill(data->icld_BufferRastPort, linerect.MinX, linerect.MinY, linerect.MaxX, linerect.MaxY);
2905 // }
2911 ///MUIM_Draw()
2912 /**************************************************************************
2913 MUIM_Draw - draw the IconList
2914 **************************************************************************/
2915 IPTR DrawCount;
2916 IPTR IconList__MUIM_Draw(struct IClass *CLASS, Object *obj, struct MUIP_Draw *message)
2918 struct IconList_DATA *data = INST_DATA(CLASS, obj);
2919 struct IconEntry *entry = NULL;
2921 APTR clip = NULL;
2923 ULONG update_oldwidth = 0,
2924 update_oldheight = 0;
2926 LONG clear_xoffset = 0,
2927 clear_yoffset = 0;
2929 IPTR draw_id = DrawCount++;
2931 #if defined(DEBUG_ILC_FUNCS)
2932 D(bug("[IconList]: %s(obj @ 0x%p)\n", __PRETTY_FUNCTION__, obj));
2933 #endif
2934 #if defined(DEBUG_ILC_ICONRENDERING)
2935 D(bug("[IconList] %s: id %d\n", __PRETTY_FUNCTION__, draw_id));
2936 #endif
2938 DoSuperMethodA(CLASS, obj, (Msg)message);
2940 if (!(data->icld__Option_IconListFixedBackground))
2942 clear_xoffset = data->icld_ViewX;
2943 clear_yoffset = data->icld_ViewY;
2946 // If window size changes, only update needed areas
2947 if (data->update_oldwidth == 0) data->update_oldwidth = data->icld_ViewWidth;
2948 if (data->update_oldheight == 0) data->update_oldheight = data->icld_ViewHeight;
2949 if ((data->update_oldwidth != data->icld_ViewWidth) || (data->update_oldheight != data->icld_ViewHeight))
2951 if (data->icld_UpdateMode != UPDATE_SCROLL)
2953 data->icld_UpdateMode = UPDATE_RESIZE;
2954 update_oldwidth = data->update_oldwidth;
2955 update_oldheight = data->update_oldheight;
2956 data->update_oldwidth = data->icld_ViewWidth;
2957 data->update_oldheight = data->icld_ViewHeight;
2961 if ((message->flags & MADF_DRAWUPDATE) || (data->icld_UpdateMode == UPDATE_RESIZE))
2963 #if defined(DEBUG_ILC_ICONRENDERING)
2965 if (message->flags & MADF_DRAWUPDATE)
2967 bug("[IconList] %s#%d: MADF_DRAWUPDATE\n", __PRETTY_FUNCTION__, draw_id);
2969 else
2971 bug("[IconList] %s#%d: UPDATE_RESIZE\n", __PRETTY_FUNCTION__, draw_id);
2974 #endif
2975 if ((data->icld_UpdateMode == UPDATE_SINGLEENTRY) && (data->update_entry != NULL)) /* draw only a single entry at update_entry */
2977 struct Rectangle rect;
2979 if ((data->icld_DisplayFlags & ICONLIST_DISP_MODELIST) == ICONLIST_DISP_MODELIST)
2981 LONG count = 0, index = -1;
2983 D(bug("[IconList] %s#%d: UPDATE_SINGLEENTRY + ICONLIST_DISP_MODELIST\n", __PRETTY_FUNCTION__, draw_id));
2985 rect.MinX = _mleft(obj);
2986 rect.MaxX = _mleft(obj) + _mwidth(obj);
2988 ForeachNode(&data->icld_IconList, entry)
2990 if (entry == data->update_entry)
2992 index = count;
2993 break;
2995 if (entry->ie_Flags & ICONENTRY_FLAG_VISIBLE)
2997 count++;
3001 if (index != -1)
3003 rect.MinY = _mtop(obj) + data->icld_LVMAttribs->lmva_HeaderHeight - data->icld_ViewY + (index * data->icld_LVMAttribs->lmva_RowHeight);
3004 rect.MaxY = rect.MinY + data->icld_LVMAttribs->lmva_RowHeight;
3006 clip = MUI_AddClipping(muiRenderInfo(obj), rect.MinX, rect.MinY, rect.MaxX - rect.MinX + 1, rect.MaxY - rect.MinY + 1);
3008 DoMethod(obj, MUIM_DrawBackground,
3009 rect.MinX, rect.MinY,
3010 rect.MaxX - rect.MinX + 1, rect.MaxY - rect.MinY + 1,
3011 clear_xoffset, clear_yoffset,
3014 entry->ie_Flags |= ICONENTRY_FLAG_NEEDSUPDATE;
3015 DoMethod(obj, MUIM_IconList_DrawEntry, data->update_entry, index);
3016 entry->ie_Flags &= ~ICONENTRY_FLAG_NEEDSUPDATE;
3017 data->icld_UpdateMode = 0;
3018 data->update_entry = NULL;
3021 else
3023 D(bug("[IconList] %s#%d: UPDATE_SINGLEENTRY (entry @ 0x%p)\n", __PRETTY_FUNCTION__, draw_id, data->update_entry));
3025 IconList_GetIconAreaRectangle(obj, data, data->update_entry, &rect);
3027 rect.MinX += _mleft(obj) + (data->update_entry->ie_IconX - data->icld_ViewX);
3028 rect.MaxX += _mleft(obj) + (data->update_entry->ie_IconX - data->icld_ViewX);
3029 rect.MinY += _mtop(obj) + (data->update_entry->ie_IconY - data->icld_ViewY);
3030 rect.MaxY += _mtop(obj) + (data->update_entry->ie_IconY - data->icld_ViewY);
3032 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
3034 if (data->update_entry->ie_AreaWidth < data->icld_IconAreaLargestWidth)
3036 rect.MinX += ((data->icld_IconAreaLargestWidth - data->update_entry->ie_AreaWidth)/2);
3037 rect.MaxX += ((data->icld_IconAreaLargestWidth - data->update_entry->ie_AreaWidth)/2);
3040 if (data->update_entry->ie_AreaHeight < data->icld_IconAreaLargestHeight)
3042 rect.MinY += ((data->icld_IconAreaLargestHeight - data->update_entry->ie_AreaHeight)/2);
3043 rect.MaxY += ((data->icld_IconAreaLargestHeight - data->update_entry->ie_AreaHeight)/2);
3047 clip = MUI_AddClipping(muiRenderInfo(obj), rect.MinX, rect.MinY, rect.MaxX - rect.MinX + 1, rect.MaxY - rect.MinY + 1);
3049 #if defined(DEBUG_ILC_ICONRENDERING)
3050 D(bug("[IconList] %s#%d: UPDATE_SINGLEENTRY: Calling MUIM_DrawBackground (A)\n", __PRETTY_FUNCTION__, draw_id));
3051 #endif
3052 DoMethod(obj, MUIM_DrawBackground,
3053 rect.MinX, rect.MinY,
3054 rect.MaxX - rect.MinX + 1, rect.MaxY - rect.MinY + 1,
3055 clear_xoffset, clear_yoffset,
3058 /* We could have deleted also other icons so they must be redrawn */
3059 #if defined(__AROS__)
3060 ForeachNode(&data->icld_IconList, entry)
3061 #else
3062 Foreach_Node(&data->icld_IconList, entry);
3063 #endif
3065 if ((entry != data->update_entry) && (entry->ie_Flags & ICONENTRY_FLAG_VISIBLE))
3067 struct Rectangle rect2;
3068 IconList_GetIconAreaRectangle(obj, data, entry, &rect2);
3070 rect2.MinX += _mleft(obj) - data->icld_ViewX + entry->ie_IconX;
3071 rect2.MaxX += _mleft(obj) - data->icld_ViewX + entry->ie_IconX;
3072 rect2.MinY += _mtop(obj) - data->icld_ViewY + entry->ie_IconY;
3073 rect2.MaxY += _mtop(obj) - data->icld_ViewY + entry->ie_IconY;
3075 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
3077 if (entry->ie_AreaWidth < data->icld_IconAreaLargestWidth)
3079 rect2.MinX += ((data->icld_IconAreaLargestWidth - entry->ie_AreaWidth)/2);
3080 rect2.MaxX += ((data->icld_IconAreaLargestWidth - entry->ie_AreaWidth)/2);
3083 if (entry->ie_AreaHeight < data->icld_IconAreaLargestHeight)
3085 rect2.MinY += ((data->icld_IconAreaLargestHeight - entry->ie_AreaHeight)/2);
3086 rect2.MaxY += ((data->icld_IconAreaLargestHeight - entry->ie_AreaHeight)/2);
3090 if (RectAndRect(&rect, &rect2))
3092 // Update entry here
3093 entry->ie_Flags |= ICONENTRY_FLAG_NEEDSUPDATE;
3094 DoMethod(obj, MUIM_IconList_DrawEntry, entry, ICONENTRY_DRAWMODE_PLAIN);
3095 DoMethod(obj, MUIM_IconList_DrawEntryLabel, entry, ICONENTRY_DRAWMODE_PLAIN);
3096 entry->ie_Flags &= ~ICONENTRY_FLAG_NEEDSUPDATE;
3101 entry->ie_Flags |= ICONENTRY_FLAG_NEEDSUPDATE;
3102 DoMethod(obj, MUIM_IconList_DrawEntry, data->update_entry, ICONENTRY_DRAWMODE_PLAIN);
3103 DoMethod(obj, MUIM_IconList_DrawEntryLabel, data->update_entry, ICONENTRY_DRAWMODE_PLAIN);
3104 entry->ie_Flags &= ~ICONENTRY_FLAG_NEEDSUPDATE;
3105 data->icld_UpdateMode = 0;
3106 data->update_entry = NULL;
3108 if (data->update_entry == NULL)
3110 if (data->icld_DisplayRastPort != data->icld_BufferRastPort)
3112 #if defined(DEBUG_ILC_ICONRENDERING)
3113 D(bug("[IconList] %s#%d: UPDATE_SINGLEENTRY Blitting to front rastport..\n", __PRETTY_FUNCTION__, draw_id));
3114 #endif
3115 BltBitMapRastPort(data->icld_BufferRastPort->BitMap,
3116 rect.MinX - _mleft(obj), rect.MinY - _mtop(obj),
3117 data->icld_DisplayRastPort,
3118 rect.MinX, rect.MinY,
3119 rect.MaxX - rect.MinX + 1, rect.MaxY - rect.MinY + 1,
3120 0xC0);
3122 MUI_RemoveClipping(muiRenderInfo(obj), clip);
3124 goto draw_done;
3126 else if (data->icld_UpdateMode == UPDATE_SCROLL)
3128 struct Region *region = NULL;
3129 struct Rectangle xrect,
3130 yrect;
3131 BOOL scroll_caused_damage;
3133 #if defined(DEBUG_ILC_ICONRENDERING)
3134 D(bug("[IconList] %s#%d: UPDATE_SCROLL.\n", __PRETTY_FUNCTION__, draw_id));
3135 #endif
3137 if (!data->icld__Option_IconListFixedBackground)
3139 scroll_caused_damage = (_rp(obj)->Layer->Flags & LAYERREFRESH) ? FALSE : TRUE;
3141 data->icld_UpdateMode = 0;
3143 if ((abs(data->update_scrolldx) >= _mwidth(obj)) ||
3144 (abs(data->update_scrolldy) >= _mheight(obj)))
3146 #if defined(DEBUG_ILC_ICONRENDERING)
3147 D(bug("[IconList] %s#%d: UPDATE_SCROLL: Moved outside current view -> Causing Redraw .. MADF_DRAWOBJECT\n", __PRETTY_FUNCTION__, draw_id));
3148 #endif
3149 MUI_Redraw(obj, MADF_DRAWOBJECT);
3150 goto draw_done;
3153 if (!(region = NewRegion()))
3155 #if defined(DEBUG_ILC_ICONRENDERING)
3156 D(bug("[IconList] %s#%d: UPDATE_SCROLL: Couldnt Alloc Region -> Causing Redraw ...MADF_DRAWOBJECT\n", __PRETTY_FUNCTION__, draw_id));
3157 #endif
3158 MUI_Redraw(obj, MADF_DRAWOBJECT);
3159 goto draw_done;
3162 if (data->update_scrolldx > 0)
3164 xrect.MinX = _mright(obj) - data->update_scrolldx;
3165 xrect.MinY = _mtop(obj);
3166 xrect.MaxX = _mright(obj);
3167 xrect.MaxY = _mbottom(obj);
3169 OrRectRegion(region, &xrect);
3171 data->update_rect1 = &xrect;
3173 else if (data->update_scrolldx < 0)
3175 xrect.MinX = _mleft(obj);
3176 xrect.MinY = _mtop(obj);
3177 xrect.MaxX = _mleft(obj) - data->update_scrolldx;
3178 xrect.MaxY = _mbottom(obj);
3180 OrRectRegion(region, &xrect);
3182 data->update_rect1 = &xrect;
3185 if (data->update_scrolldy > 0)
3187 yrect.MinX = _mleft(obj);
3188 yrect.MinY = _mbottom(obj) - data->update_scrolldy;
3189 yrect.MaxX = _mright(obj);
3190 yrect.MaxY = _mbottom(obj);
3192 OrRectRegion(region, &yrect);
3194 data->update_rect2 = &yrect;
3196 else if (data->update_scrolldy < 0)
3198 yrect.MinX = _mleft(obj);
3199 yrect.MinY = _mtop(obj);
3200 yrect.MaxX = _mright(obj);
3201 yrect.MaxY = _mtop(obj) - data->update_scrolldy;
3203 OrRectRegion(region, &yrect);
3205 data->update_rect2 = &yrect;
3208 #if defined(DEBUG_ILC_ICONRENDERING)
3209 D(bug("[IconList] %s#%d: UPDATE_SCROLL: Scrolling Raster..\n", __PRETTY_FUNCTION__, draw_id));
3210 #endif
3211 if (data->icld_DisplayRastPort == data->icld_BufferRastPort)
3213 ScrollRasterBF(data->icld_BufferRastPort,
3214 data->update_scrolldx,
3215 data->update_scrolldy,
3216 _mleft(obj),
3217 _mtop(obj),
3218 _mright(obj),
3219 _mbottom(obj));
3221 else
3223 ScrollRasterBF(data->icld_BufferRastPort,
3224 data->update_scrolldx,
3225 data->update_scrolldy,
3228 _mwidth(obj),
3229 _mheight(obj));
3232 scroll_caused_damage = scroll_caused_damage && (_rp(obj)->Layer->Flags & LAYERREFRESH) ? TRUE : FALSE;
3234 clip = MUI_AddClipRegion(muiRenderInfo(obj), region);
3237 #if defined(DEBUG_ILC_ICONRENDERING)
3238 D(bug("[IconList] %s#%d: UPDATE_SCROLL: Causing Redraw -> MADF_DRAWOBJECT..\n", __PRETTY_FUNCTION__, draw_id));
3239 #endif
3240 MUI_Redraw(obj, MADF_DRAWOBJECT);
3242 data->update_rect1 = data->update_rect2 = NULL;
3244 if (!data->icld__Option_IconListFixedBackground)
3246 MUI_RemoveClipRegion(muiRenderInfo(obj), clip);
3248 if (scroll_caused_damage)
3250 if (MUI_BeginRefresh(muiRenderInfo(obj), 0))
3252 /* Theoretically it might happen that more damage is caused
3253 after ScrollRaster. By something else, like window movement
3254 in front of our window. Therefore refresh root object of
3255 window, not just this object */
3257 Object *o = NULL;
3259 GET(_win(obj),MUIA_Window_RootObject, &o);
3260 MUI_Redraw(o, MADF_DRAWOBJECT);
3261 #if defined(DEBUG_ILC_ICONRENDERING)
3262 D(bug("[IconList] %s#%d: UPDATE_SCROLL: Causing Redraw -> MADF_DRAWOBJECT..\n", __PRETTY_FUNCTION__, draw_id));
3263 #endif
3264 MUI_EndRefresh(muiRenderInfo(obj), 0);
3268 if (data->icld_DisplayRastPort != data->icld_BufferRastPort)
3270 #if defined(DEBUG_ILC_ICONRENDERING)
3271 D(bug("[IconList] %s#%d: UPDATE_SCROLL: Blitting to front rastport..\n", __PRETTY_FUNCTION__, draw_id));
3272 #endif
3273 BltBitMapRastPort(data->icld_BufferRastPort->BitMap,
3274 0, 0,
3275 data->icld_DisplayRastPort,
3276 _mleft(obj), _mtop(obj),
3277 _mwidth(obj), _mheight(obj),
3278 0xC0);
3280 goto draw_done;
3282 else if (data->icld_UpdateMode == UPDATE_RESIZE)
3284 struct Region *region = NULL;
3285 struct Rectangle wrect,
3286 hrect;
3287 ULONG diffw = 0,
3288 diffh = 0;
3290 #if defined(DEBUG_ILC_ICONRENDERING)
3291 D(bug("[IconList] %s#%d: UPDATE_RESIZE.\n", __PRETTY_FUNCTION__, draw_id));
3292 #endif
3294 if ((data->icld_BufferRastPort) && (data->icld_BufferRastPort != data->icld_DisplayRastPort))
3296 //Free up the buffers Layer, rastport and bitmap so we can replace them ..
3297 if ((GetBitMapAttr(data->icld_BufferRastPort->BitMap, BMA_WIDTH) != data->icld_ViewWidth)
3298 || (GetBitMapAttr(data->icld_BufferRastPort->BitMap, BMA_HEIGHT) != data->icld_ViewHeight))
3300 struct Layer *oldLayer = data->icld_BufferRastPort->Layer;
3301 #if defined(DEBUG_ILC_ATTRIBS) && defined(DEBUG_ILC_ICONRENDERING)
3302 D(bug("[IconList] %s: Destroying old BackLayer\n", __PRETTY_FUNCTION__));
3303 #endif
3304 data->icld_BufferRastPort = data->icld_DisplayRastPort;
3305 DeleteLayer(0, oldLayer);
3308 if (data->icld_BufferRastPort == data->icld_DisplayRastPort)
3310 struct Bitmap *bitmap_New;
3311 ULONG tmp_RastDepth;
3313 tmp_RastDepth = GetCyberMapAttr(data->icld_DisplayRastPort->BitMap, CYBRMATTR_DEPTH);
3314 if ((bitmap_New = (struct Bitmap *)AllocBitMap(data->icld_ViewWidth,
3315 data->icld_ViewHeight,
3316 tmp_RastDepth,
3317 BMF_CLEAR,
3318 data->icld_DisplayRastPort->BitMap))!=NULL)
3320 struct Layer * buffLayer = CreateLayerTagList(&_screen(obj)->LayerInfo,
3321 bitmap_New,
3324 data->icld_ViewWidth,
3325 data->icld_ViewHeight,
3326 LAYERSIMPLE,
3327 __iconList_BackBuffLayerTags);
3329 if (buffLayer != NULL)
3331 data->icld_BufferRastPort = buffLayer->rp;
3332 #if defined(DEBUG_ILC_ATTRIBS) && defined(DEBUG_ILC_ICONRENDERING)
3333 D(bug("[IconList] %s: FrontRastPort @ %p, New BackLayer @ %p, BackRastport @ %p\n", __PRETTY_FUNCTION__, data->icld_DisplayRastPort, data->icld_BufferRastPort->Layer, data->icld_BufferRastPort));
3334 #endif
3335 SET(obj, MUIA_IconList_BufferRastport, data->icld_BufferRastPort);
3336 data->icld_DrawOffsetX = 0;
3337 data->icld_DrawOffsetY = 0;
3339 else
3341 FreeBitMap(bitmap_New);
3342 data->icld_BufferRastPort = data->icld_DisplayRastPort;
3343 data->icld_DrawOffsetX = _mleft(obj);
3344 data->icld_DrawOffsetY = _mtop(obj);
3350 data->icld_UpdateMode = 0;
3352 if (!data->icld__Option_IconListScaledBackground)
3354 if (!(region = NewRegion()))
3356 #if defined(DEBUG_ILC_ICONRENDERING)
3357 D(bug("[IconList] %s#%d: UPDATE_RESIZE: Causing Redraw -> MADF_DRAWOBJECT..\n", __PRETTY_FUNCTION__, draw_id));
3358 #endif
3359 MUI_Redraw(obj, MADF_DRAWOBJECT);
3360 goto draw_done;
3363 if ( data->icld_ViewWidth > update_oldwidth )
3364 diffw = data->icld_ViewWidth - update_oldwidth;
3365 if ( data->icld_ViewHeight > update_oldheight )
3366 diffh = data->icld_ViewHeight - update_oldheight;
3368 if (diffw)
3370 wrect.MinX = _mright(obj) - diffw;
3371 wrect.MinY = _mtop(obj);
3372 wrect.MaxX = _mright(obj);
3373 wrect.MaxY = _mbottom(obj);
3374 OrRectRegion(region, &wrect);
3375 data->update_rect1 = &wrect;
3378 if (diffh)
3380 hrect.MinX = _mleft(obj);
3381 hrect.MinY = _mbottom(obj) - diffh;
3382 hrect.MaxX = _mright(obj);
3383 hrect.MaxX = _mright(obj);
3384 hrect.MaxY = _mbottom(obj);
3385 OrRectRegion(region, &hrect);
3386 data->update_rect2 = &hrect;
3388 if (diffh||diffw)
3390 clip = MUI_AddClipRegion(muiRenderInfo(obj), region);
3392 else
3394 /* View became smaller both in horizontal and vertical direction.
3395 Nothing to do */
3397 DisposeRegion(region);
3398 goto draw_done;
3402 #if defined(DEBUG_ILC_ICONRENDERING)
3403 D(bug("[IconList] %s#%d: UPDATE_RESIZE: Causing Redraw -> MADF_DRAWOBJECT..\n", __PRETTY_FUNCTION__, draw_id));
3404 #endif
3405 MUI_Redraw(obj, MADF_DRAWOBJECT);
3407 if (!data->icld__Option_IconListScaledBackground)
3409 if (diffh||diffw)
3411 data->update_rect1 = data->update_rect2 = NULL;
3412 MUI_RemoveClipRegion(muiRenderInfo(obj), clip);
3413 } else DisposeRegion(region);
3416 goto draw_done;
3420 if (message->flags & MADF_DRAWOBJECT)
3422 struct Rectangle viewrect;
3423 int current = 0, first = 0, visible = 0;
3425 #if defined(DEBUG_ILC_ICONRENDERING)
3426 D(bug("[IconList] %s#%d: MADF_DRAWOBJECT\n", __PRETTY_FUNCTION__, draw_id));
3427 #endif
3429 clip = MUI_AddClipping(muiRenderInfo(obj), _mleft(obj), _mtop(obj), _mwidth(obj), _mheight(obj));
3431 if ((data->icld_DisplayFlags & ICONLIST_DISP_MODELIST) == ICONLIST_DISP_MODELIST)
3433 RenderListViewModeHeader(obj, data);
3434 viewrect.MinY = _mtop(obj) + data->icld_LVMAttribs->lmva_HeaderHeight;
3436 first = FirstVisibleLine(data);
3437 visible = NumVisibleLines(data);
3439 else
3441 viewrect.MinY = _mtop(obj);
3444 viewrect.MaxY = _mtop(obj) + _mheight(obj);
3445 viewrect.MinX = _mleft(obj);
3446 viewrect.MaxX = _mleft(obj) + _mwidth(obj);
3448 #if defined(DEBUG_ILC_ICONRENDERING)
3449 D(bug("[IconList] %s#%d: MADF_DRAWOBJECT: Calling MUIM_DrawBackground (B)\n", __PRETTY_FUNCTION__, draw_id));
3450 #endif
3451 DoMethod(
3452 obj, MUIM_DrawBackground, viewrect.MinX, viewrect.MinY, (viewrect.MaxX - viewrect.MinX), (viewrect.MaxY - viewrect.MinY),
3453 clear_xoffset, clear_yoffset, 0
3455 #if defined(__AROS__)
3456 ForeachNode(&data->icld_IconList, entry)
3457 #else
3458 Foreach_Node(&data->icld_IconList, entry);
3459 #endif
3461 if ((data->icld_DisplayFlags & ICONLIST_DISP_MODELIST) == ICONLIST_DISP_MODELIST)
3463 if (entry->ie_Flags & ICONENTRY_FLAG_VISIBLE)
3465 if ((current >= first) && (current < visible))
3467 DoMethod(obj, MUIM_IconList_DrawEntry, entry, current);
3468 current++;
3472 else
3474 if ((entry->ie_Flags & ICONENTRY_FLAG_VISIBLE) &&
3475 (entry->ie_DiskObj) &&
3476 (entry->ie_IconX != NO_ICON_POSITION) &&
3477 (entry->ie_IconY != NO_ICON_POSITION))
3479 struct Rectangle iconrect;
3480 IconList_GetIconAreaRectangle(obj, data, entry, &iconrect);
3482 iconrect.MinX += viewrect.MinX - data->icld_ViewX + entry->ie_IconX;
3483 iconrect.MaxX += viewrect.MinX - data->icld_ViewX + entry->ie_IconX;
3484 iconrect.MinY += viewrect.MinY - data->icld_ViewY + entry->ie_IconY;
3485 iconrect.MaxY += viewrect.MinY - data->icld_ViewY + entry->ie_IconY;
3487 if (RectAndRect(&viewrect, &iconrect))
3489 DoMethod(obj, MUIM_IconList_DrawEntry, entry, ICONENTRY_DRAWMODE_PLAIN);
3490 DoMethod(obj, MUIM_IconList_DrawEntryLabel, entry, ICONENTRY_DRAWMODE_PLAIN);
3496 if (data->icld_DisplayRastPort != data->icld_BufferRastPort)
3498 #if defined(DEBUG_ILC_ICONRENDERING)
3499 D(bug("[IconList] %s#%d: MADF_DRAWOBJECT: Blitting to front rastport..\n", __PRETTY_FUNCTION__, draw_id));
3500 #endif
3501 BltBitMapRastPort(data->icld_BufferRastPort->BitMap,
3502 0, 0,
3503 data->icld_DisplayRastPort,
3504 _mleft(obj), _mtop(obj),
3505 _mwidth(obj), _mheight(obj),
3506 0xC0);
3509 MUI_RemoveClipping(muiRenderInfo(obj), clip);
3511 data->icld_UpdateMode = 0;
3513 draw_done:;
3515 #if defined(DEBUG_ILC_ICONRENDERING)
3516 D(bug("[IconList] %s: Draw finished for id %d\n", __PRETTY_FUNCTION__, draw_id));
3517 #endif
3518 return 0;
3522 ///IconList__MUIM_IconList_Update()
3523 /**************************************************************************
3524 MUIM_IconList_Refresh
3525 Implemented by subclasses
3526 **************************************************************************/
3527 IPTR IconList__MUIM_IconList_Update(struct IClass *CLASS, Object *obj, struct MUIP_IconList_Update *message)
3529 struct IconList_DATA *data = INST_DATA(CLASS, obj);
3531 #if defined(DEBUG_ILC_FUNCS)
3532 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
3533 #endif
3535 data->icld_FocusIcon = NULL;
3536 SET(obj, MUIA_IconList_Changed, TRUE);
3538 return 1;
3542 ///MUIM_IconList_Clear()
3543 /**************************************************************************
3544 MUIM_IconList_Clear
3545 **************************************************************************/
3546 IPTR IconList__MUIM_IconList_Clear(struct IClass *CLASS, Object *obj, struct MUIP_IconList_Clear *message)
3548 struct IconList_DATA *data = INST_DATA(CLASS, obj);
3549 struct IconEntry *node = NULL;
3551 #if defined(DEBUG_ILC_FUNCS)
3552 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
3553 #endif
3555 while ((node = (struct IconEntry*)RemTail((struct List*)&data->icld_IconList)))
3557 DoMethod(obj, MUIM_IconList_DestroyEntry, node);
3560 data->icld_SelectionLastClicked = NULL;
3561 data->icld_FocusIcon = NULL;
3563 data->icld_ViewX = data->icld_ViewY = data->icld_AreaWidth = data->icld_AreaHeight = 0;
3565 D(bug("[IconList]: %s: call SetSuperAttrs()\n", __PRETTY_FUNCTION__));
3566 SetSuperAttrs(CLASS, obj, MUIA_Virtgroup_Left, data->icld_ViewX,
3567 MUIA_Virtgroup_Top, data->icld_ViewY,
3568 TAG_DONE);
3570 D(bug("[IconList]: %s: call SetAttrs()\n", __PRETTY_FUNCTION__));
3571 SetAttrs(obj, MUIA_Virtgroup_Left, data->icld_ViewX,
3572 MUIA_Virtgroup_Top, data->icld_ViewY,
3573 TAG_DONE);
3575 D(bug("[IconList]: %s: Set MUIA_IconList_Width and MUIA_IconList_Height\n", __PRETTY_FUNCTION__));
3576 SetAttrs(obj, MUIA_IconList_Width, data->icld_AreaWidth,
3577 MUIA_IconList_Height, data->icld_AreaHeight,
3578 TAG_DONE);
3580 D(bug("[IconList]: %s: call MUI_Redraw()\n", __PRETTY_FUNCTION__));
3581 MUI_Redraw(obj,MADF_DRAWOBJECT);
3582 return 1;
3586 ///IconList__MUIM_IconList_DestroyEntry()
3587 IPTR IconList__MUIM_IconList_DestroyEntry(struct IClass *CLASS, Object *obj, struct MUIP_IconList_DestroyEntry *message)
3589 struct IconList_DATA *data = INST_DATA(CLASS, obj);
3591 #if defined(DEBUG_ILC_FUNCS)
3592 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
3593 #endif
3595 if (message->icon)
3597 if (message->icon->ie_Flags & ICONENTRY_FLAG_SELECTED)
3599 if (data->icld_SelectionLastClicked == message->icon)
3601 struct IconList_Entry *nextentry = &message->icon->ie_IconListEntry;
3603 /* get selected entries from SOURCE iconlist */
3604 DoMethod(obj, MUIM_IconList_NextIcon, MUIV_IconList_NextIcon_Selected, (IPTR)&nextentry);
3605 if ((nextentry) && (nextentry != (IPTR)MUIV_IconList_NextIcon_End))
3606 data->icld_SelectionLastClicked = (struct IconEntry *)((IPTR)nextentry - ((IPTR)&message->icon->ie_IconListEntry - (IPTR)message->icon));
3607 else
3608 data->icld_SelectionLastClicked = NULL;
3610 if (data->icld_FocusIcon == message->icon)
3611 data->icld_FocusIcon = data->icld_SelectionLastClicked;
3613 Remove(&message->icon->ie_SelectionNode);
3616 if (message->icon->ie_TxtBuf_DisplayedLabel)
3617 FreeVecPooled(data->icld_Pool, message->icon->ie_TxtBuf_DisplayedLabel);
3619 if (message->icon->ie_TxtBuf_PROT)
3620 FreePooled(data->icld_Pool, message->icon->ie_TxtBuf_PROT, 8);
3622 if (message->icon->ie_TxtBuf_SIZE)
3623 FreePooled(data->icld_Pool, message->icon->ie_TxtBuf_SIZE, 30);
3625 if (message->icon->ie_TxtBuf_TIME)
3626 FreePooled(data->icld_Pool, message->icon->ie_TxtBuf_TIME, LEN_DATSTRING);
3628 if (message->icon->ie_TxtBuf_DATE)
3629 FreePooled(data->icld_Pool, message->icon->ie_TxtBuf_DATE, LEN_DATSTRING);
3631 if (message->icon->ie_DiskObj)
3632 FreeDiskObject(message->icon->ie_DiskObj);
3634 if (message->icon->ie_FileInfoBlock)
3635 FreeMem(message->icon->ie_FileInfoBlock, sizeof(struct FileInfoBlock));
3637 if (message->icon->ie_IconListEntry.label)
3638 FreePooled(data->icld_Pool, message->icon->ie_IconListEntry.label, strlen(message->icon->ie_IconListEntry.label)+1);
3640 if (message->icon->ie_IconNode.ln_Name)
3641 FreePooled(data->icld_Pool, message->icon->ie_IconNode.ln_Name, strlen(message->icon->ie_IconNode.ln_Name)+1);
3643 FreePooled(data->icld_Pool, message->icon, sizeof(struct IconEntry));
3645 return (IPTR)TRUE;
3649 ///IconList__MUIM_IconList_CreateEntry()
3650 /**************************************************************************
3651 MUIM_IconList_CreateEntry.
3652 Returns 0 on failure otherwise it returns the icons entry ..
3653 **************************************************************************/
3654 IPTR IconList__MUIM_IconList_CreateEntry(struct IClass *CLASS, Object *obj, struct MUIP_IconList_CreateEntry *message)
3656 struct IconList_DATA *data = INST_DATA(CLASS, obj);
3657 struct IconEntry *entry = NULL;
3658 struct DateTime dt;
3659 struct DateStamp now;
3660 UBYTE *sp = NULL;
3662 struct DiskObject *dob = NULL;
3663 struct Rectangle rect;
3665 IPTR geticon_error = 0;
3667 #if defined(DEBUG_ILC_FUNCS)
3668 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
3669 #endif
3671 /*disk object (icon)*/
3672 if (message->icon_dob == NULL)
3674 IPTR iconlistScreen = _screen(obj);
3675 D(bug("[IconList] %s: IconList Screen @ 0x%p)\n", __PRETTY_FUNCTION__, iconlistScreen));
3677 dob = GetIconTags
3679 message->filename,
3680 (iconlistScreen) ? ICONGETA_Screen : TAG_IGNORE, iconlistScreen,
3681 (iconlistScreen) ? ICONGETA_RemapIcon : TAG_IGNORE, TRUE,
3682 ICONGETA_FailIfUnavailable, FALSE,
3683 ICONGETA_GenerateImageMasks, TRUE,
3684 ICONA_ErrorCode, &geticon_error,
3685 TAG_DONE
3688 if (dob == NULL)
3690 D(bug("[IconList] %s: Fatal: Couldnt get DiskObject! (error code = 0x%p)\n", __PRETTY_FUNCTION__, geticon_error));
3692 return (IPTR)NULL;
3695 else
3697 dob = message->icon_dob;
3700 D(bug("[IconList] %s: DiskObject @ 0x%p\n", __PRETTY_FUNCTION__, dob));
3702 if ((entry = AllocPooled(data->icld_Pool, sizeof(struct IconEntry))) == NULL)
3704 D(bug("[IconList] %s: Failed to Allocate Entry Storage!\n", __PRETTY_FUNCTION__));
3705 FreeDiskObject(dob);
3706 return (IPTR)NULL;
3708 memset(entry, 0, sizeof(struct IconEntry));
3709 entry->ie_Flags |= ICONENTRY_FLAG_NEEDSUPDATE;
3710 entry->ie_IconListEntry.ile_IconEntry = entry;
3712 /* Allocate Text Buffers */
3714 if ((entry->ie_TxtBuf_DATE = AllocPooled(data->icld_Pool, LEN_DATSTRING)) == NULL)
3716 D(bug("[IconList] %s: Failed to Allocate Entry DATE Storage!\n", __PRETTY_FUNCTION__));
3717 DoMethod(obj, MUIM_IconList_DestroyEntry, entry);
3718 return (IPTR)NULL;
3720 memset(entry->ie_TxtBuf_DATE, 0, LEN_DATSTRING);
3722 if ((entry->ie_TxtBuf_TIME = AllocPooled(data->icld_Pool, LEN_DATSTRING)) == NULL)
3724 D(bug("[IconList] %s: Failed to Allocate Entry TIME string Storage!\n", __PRETTY_FUNCTION__));
3725 DoMethod(obj, MUIM_IconList_DestroyEntry, entry);
3726 return (IPTR)NULL;
3728 memset(entry->ie_TxtBuf_TIME, 0, LEN_DATSTRING);
3730 if ((entry->ie_TxtBuf_SIZE = AllocPooled(data->icld_Pool, 30)) == NULL)
3732 D(bug("[IconList] %s: Failed to Allocate Entry SIZE string Storage!\n", __PRETTY_FUNCTION__));
3733 DoMethod(obj, MUIM_IconList_DestroyEntry, entry);
3734 return (IPTR)NULL;
3736 memset(entry->ie_TxtBuf_SIZE, 0, 30);
3738 if ((entry->ie_TxtBuf_PROT = AllocPooled(data->icld_Pool, 8)) == NULL)
3740 D(bug("[IconList] %s: Failed to Allocate Entry PROT Flag string Storage!\n", __PRETTY_FUNCTION__));
3741 DoMethod(obj, MUIM_IconList_DestroyEntry, entry);
3742 return (IPTR)NULL;
3744 memset(entry->ie_TxtBuf_PROT, 0, 8);
3746 /*alloc filename*/
3747 if ((entry->ie_IconNode.ln_Name = AllocPooled(data->icld_Pool, strlen(message->filename) + 1)) == NULL)
3749 D(bug("[IconList] %s: Failed to Allocate Entry filename string Storage!\n", __PRETTY_FUNCTION__));
3750 DoMethod(obj, MUIM_IconList_DestroyEntry, entry);
3751 return (IPTR)NULL;
3754 /*alloc icon label*/
3755 if ((entry->ie_IconListEntry.label = AllocPooled(data->icld_Pool, strlen(message->label) + 1)) == NULL)
3757 D(bug("[IconList] %s: Failed to Allocate Entry label string Storage!\n", __PRETTY_FUNCTION__));
3758 DoMethod(obj, MUIM_IconList_DestroyEntry, entry);
3759 return (IPTR)NULL;
3762 /*file info block*/
3763 if(message->fib != NULL)
3765 if ((entry->ie_FileInfoBlock = AllocMem(sizeof(struct FileInfoBlock), MEMF_CLEAR)) != NULL)
3767 CopyMem(message->fib, entry->ie_FileInfoBlock, sizeof(struct FileInfoBlock));
3769 if (entry->ie_FileInfoBlock->fib_DirEntryType > 0)
3771 strcpy(entry->ie_TxtBuf_SIZE, "Drawer");
3773 else
3775 FmtSizeToString(entry->ie_TxtBuf_SIZE, entry->ie_FileInfoBlock->fib_Size);
3778 dt.dat_Stamp = entry->ie_FileInfoBlock->fib_Date;
3779 dt.dat_Format = FORMAT_DEF;
3780 dt.dat_Flags = 0;
3781 dt.dat_StrDay = NULL;
3782 dt.dat_StrDate = entry->ie_TxtBuf_DATE;
3783 dt.dat_StrTime = entry->ie_TxtBuf_TIME;
3785 DateToStr(&dt);
3786 DateStamp(&now);
3788 /*if modified today show time, otherwise just show date*/
3789 if (now.ds_Days == entry->ie_FileInfoBlock->fib_Date.ds_Days)
3790 entry->ie_Flags |= ICONENTRY_FLAG_TODAY;
3791 else
3792 entry->ie_Flags &= ~ICONENTRY_FLAG_TODAY;
3794 sp = entry->ie_TxtBuf_PROT;
3795 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_SCRIPT) ? 's' : '-';
3796 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_PURE) ? 'p' : '-';
3797 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_ARCHIVE) ? 'a' : '-';
3798 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_READ) ? '-' : 'r';
3799 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_WRITE) ? '-' : 'w';
3800 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_EXECUTE) ? '-' : 'e';
3801 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_DELETE) ? '-' : 'd';
3802 *sp++ = '\0';
3804 entry->ie_IconListEntry.type = entry->ie_FileInfoBlock->fib_DirEntryType;
3807 else
3809 entry->ie_IconListEntry.type = ST_USERDIR;
3812 /* Override type if specified during createntry */
3813 if (message->type != 0)
3815 entry->ie_IconListEntry.type = message->type;
3816 D(bug("[IconList] %s: Overide Entry Type. New Type = %x\n", __PRETTY_FUNCTION__, entry->ie_IconListEntry.type));
3818 else
3820 D(bug("[IconList] %s: Entry Type = %x\n", __PRETTY_FUNCTION__, entry->ie_IconListEntry.type));
3823 strcpy(entry->ie_IconNode.ln_Name, message->filename);
3824 strcpy(entry->ie_IconListEntry.label, message->label);
3826 entry->ie_IconListEntry.udata = NULL;
3828 if (IconList__LabelFunc_CreateLabel(obj, data, entry) != (IPTR)NULL)
3830 entry->ie_DiskObj = dob;
3832 /* Use a geticonrectangle routine that gets textwidth! */
3833 IconList_GetIconAreaRectangle(obj, data, entry, &rect);
3835 return (IPTR)entry;
3838 DoMethod(obj, MUIM_IconList_DestroyEntry, entry);
3839 return (IPTR)NULL;
3843 ///IconList__MUIM_IconList_UpdateEntry()
3844 /**************************************************************************
3845 MUIM_IconList_UpdateEntry.
3846 Returns 0 on failure otherwise it returns the icons entry ..
3847 **************************************************************************/
3848 IPTR IconList__MUIM_IconList_UpdateEntry(struct IClass *CLASS, Object *obj, struct MUIP_IconList_UpdateEntry *message)
3850 struct IconList_DATA *data = INST_DATA(CLASS, obj);
3851 struct DateTime dt;
3852 struct DateStamp now;
3853 UBYTE *sp = NULL;
3855 struct DiskObject *dob = NULL;
3856 struct Rectangle rect;
3858 IPTR geticon_error = 0;
3860 #if defined(DEBUG_ILC_FUNCS)
3861 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
3862 #endif
3864 /* Update disk object (icon)*/
3865 /* if (message->icon_dob == NULL)
3867 IPTR iconlistScreen = _screen(obj);
3868 D(bug("[IconList] %s: IconList Screen @ 0x%p)\n", __PRETTY_FUNCTION__, iconlistScreen));
3870 dob = GetIconTags
3872 message->filename,
3873 (iconlistScreen) ? ICONGETA_Screen : TAG_IGNORE, iconlistScreen,
3874 (iconlistScreen) ? ICONGETA_RemapIcon : TAG_IGNORE, TRUE,
3875 ICONGETA_FailIfUnavailable, FALSE,
3876 ICONGETA_GenerateImageMasks, TRUE,
3877 ICONA_ErrorCode, &geticon_error,
3878 TAG_DONE
3881 if (dob == NULL)
3883 D(bug("[IconList] %s: Fatal: Couldnt get DiskObject! (error code = 0x%p)\n", __PRETTY_FUNCTION__, geticon_error));
3885 return (IPTR)NULL;
3888 else
3890 dob = message->icon_dob;
3893 D(bug("[IconList] %s: DiskObject @ 0x%p\n", __PRETTY_FUNCTION__, dob));
3896 /* Update filename */
3897 if (strcmp(message->icon->ie_IconNode.ln_Name, message->filename) != 0)
3899 message->icon->ie_Flags |= ICONENTRY_FLAG_NEEDSUPDATE;
3900 FreePooled(data->icld_Pool, message->icon->ie_IconNode.ln_Name, strlen(message->icon->ie_IconNode.ln_Name) + 1);
3901 if ((message->icon->ie_IconNode.ln_Name = AllocPooled(data->icld_Pool, strlen(message->filename) + 1)) == NULL)
3903 D(bug("[IconList] %s: Failed to Allocate Entry filename string Storage!\n", __PRETTY_FUNCTION__));
3904 DoMethod(obj, MUIM_IconList_DestroyEntry, message->icon);
3905 return (IPTR)NULL;
3907 strcpy(message->icon->ie_IconNode.ln_Name, message->filename);
3910 /* Update icon label */
3911 if (strcmp(message->icon->ie_IconListEntry.label, message->label) != 0)
3913 message->icon->ie_Flags |= ICONENTRY_FLAG_NEEDSUPDATE;
3914 FreePooled(data->icld_Pool, message->icon->ie_IconListEntry.label, strlen(message->icon->ie_IconListEntry.label) + 1);
3915 if ((message->icon->ie_IconListEntry.label = AllocPooled(data->icld_Pool, strlen(message->label) + 1)) == NULL)
3917 D(bug("[IconList] %s: Failed to Allocate Entry label string Storage!\n", __PRETTY_FUNCTION__));
3918 DoMethod(obj, MUIM_IconList_DestroyEntry, message->icon);
3919 return (IPTR)NULL;
3921 strcpy(message->icon->ie_IconListEntry.label, message->label);
3922 if (IconList__LabelFunc_CreateLabel(obj, data, message->icon) == (IPTR)NULL)
3924 D(bug("[IconList] %s: Failed to create label\n", __PRETTY_FUNCTION__));
3925 DoMethod(obj, MUIM_IconList_DestroyEntry, message->icon);
3926 return (IPTR)NULL;
3930 /* Update file info block */
3931 if(message->fib != NULL)
3933 if (!(message->icon->ie_FileInfoBlock))
3935 if ((message->icon->ie_FileInfoBlock = AllocMem(sizeof(struct FileInfoBlock), MEMF_CLEAR)) != NULL)
3937 CopyMem(message->fib, message->icon->ie_FileInfoBlock, sizeof(struct FileInfoBlock));
3941 /* if (entry->ie_FileInfoBlock->fib_DirEntryType > 0)
3943 strcpy(entry->ie_TxtBuf_SIZE, "Drawer");
3945 else
3947 FmtSizeToString(entry->ie_TxtBuf_SIZE, entry->ie_FileInfoBlock->fib_Size);
3950 dt.dat_Stamp = entry->ie_FileInfoBlock->fib_Date;
3951 dt.dat_Format = FORMAT_DEF;
3952 dt.dat_Flags = 0;
3953 dt.dat_StrDay = NULL;
3954 dt.dat_StrDate = entry->ie_TxtBuf_DATE;
3955 dt.dat_StrTime = entry->ie_TxtBuf_TIME;
3957 DateToStr(&dt);
3958 DateStamp(&now);
3960 //if modified today show time, otherwise just show date
3961 if (now.ds_Days == entry->ie_FileInfoBlock->fib_Date.ds_Days)
3962 entry->ie_Flags |= ICONENTRY_FLAG_TODAY;
3963 else
3964 entry->ie_Flags &= ~ICONENTRY_FLAG_TODAY;
3966 sp = entry->ie_TxtBuf_PROT;
3967 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_SCRIPT) ? 's' : '-';
3968 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_PURE) ? 'p' : '-';
3969 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_ARCHIVE) ? 'a' : '-';
3970 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_READ) ? '-' : 'r';
3971 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_WRITE) ? '-' : 'w';
3972 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_EXECUTE) ? '-' : 'e';
3973 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_DELETE) ? '-' : 'd';
3974 *sp++ = '\0';
3976 entry->ie_IconListEntry.type = entry->ie_FileInfoBlock->fib_DirEntryType;
3979 else
3981 if (message->icon->ie_FileInfoBlock)
3982 FreeMem(message->icon->ie_FileInfoBlock, sizeof(struct FileInfoBlock));
3984 if (message->icon->ie_IconListEntry.type != ST_USERDIR)
3986 message->icon->ie_Flags |= ICONENTRY_FLAG_NEEDSUPDATE;
3987 message->icon->ie_IconListEntry.type = ST_USERDIR;
3991 /* Override type if specified */
3992 if ((message->type != 0) && (message->icon->ie_IconListEntry.type != message->type))
3994 message->icon->ie_Flags |= ICONENTRY_FLAG_NEEDSUPDATE;
3995 message->icon->ie_IconListEntry.type = message->type;
3996 D(bug("[IconList] %s: Overide Entry Type. New Type = %x\n", __PRETTY_FUNCTION__, message->icon->ie_IconListEntry.type));
3998 else
4000 D(bug("[IconList] %s: Entry Type = %x\n", __PRETTY_FUNCTION__, message->icon->ie_IconListEntry.type));
4003 IconList_GetIconAreaRectangle(obj, data, message->icon, &rect);
4005 return (IPTR)message->icon;
4009 ///DoWheelMove()
4010 static void DoWheelMove(struct IClass *CLASS, Object *obj, LONG wheelx, LONG wheely, UWORD qual)
4012 struct IconList_DATA *data = INST_DATA(CLASS, obj);
4014 LONG newleft = data->icld_ViewX,
4015 newtop = data->icld_ViewY;
4017 /* Use horizontal scrolling if any of the following cases are true ...
4019 # vertical wheel is used but there's nothing to scroll
4020 (everything is visible already) ..
4022 # vertical wheel is used and one of the ALT keys is down. */
4024 if ((wheely && !wheelx) &&
4025 ((data->icld_AreaHeight <= _mheight(obj)) || (qual & (IEQUALIFIER_LALT | IEQUALIFIER_RALT))))
4027 wheelx = wheely; wheely = 0;
4030 if (qual & (IEQUALIFIER_CONTROL))
4032 if (wheelx < 0) newleft = 0;
4033 if (wheelx > 0) newleft = data->icld_AreaWidth;
4034 if (wheely < 0) newtop = 0;
4035 if (wheely > 0) newtop = data->icld_AreaHeight;
4037 else if (qual & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
4039 newleft += (wheelx * _mwidth(obj));
4040 newtop += (wheely * _mheight(obj));
4042 else
4044 newleft += wheelx * 30;
4045 newtop += wheely * 30;
4048 if (newleft + _mwidth(obj) > data->icld_AreaWidth)
4049 newleft = data->icld_AreaWidth - _mwidth(obj);
4050 if (newleft < 0)
4051 newleft = 0;
4053 if (newtop + _mheight(obj) > data->icld_AreaHeight)
4054 newtop = data->icld_AreaHeight - _mheight(obj);
4055 if (newtop < 0)
4056 newtop = 0;
4058 if ((newleft != data->icld_ViewX) || (newtop != data->icld_ViewY))
4060 SetAttrs(obj, MUIA_Virtgroup_Left, newleft,
4061 MUIA_Virtgroup_Top, newtop,
4062 TAG_DONE);
4067 ///MUIM_HandleEvent()
4068 /**************************************************************************
4069 MUIM_HandleEvent
4070 **************************************************************************/
4071 IPTR IconList__MUIM_HandleEvent(struct IClass *CLASS, Object *obj, struct MUIP_HandleEvent *message)
4073 struct IconList_DATA *data = INST_DATA(CLASS, obj);
4075 #if defined(DEBUG_ILC_FUNCS)
4076 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
4077 #endif
4079 if (message->imsg)
4081 LONG mx = message->imsg->MouseX - _mleft(obj);
4082 LONG my = message->imsg->MouseY - _mtop(obj);
4084 LONG wheelx = 0;
4085 LONG wheely = 0;
4087 switch (message->imsg->Class)
4089 case IDCMP_NEWSIZE:
4090 bug("[IconList] %s: IDCMP_NEWSIZE\n", __PRETTY_FUNCTION__);
4091 break;
4093 case IDCMP_RAWKEY:
4095 #if defined(DEBUG_ILC_EVENTS)
4096 D(bug("[IconList] %s: IDCMP_RAWKEY\n", __PRETTY_FUNCTION__));
4097 #endif
4098 BOOL rawkey_handled = FALSE;
4100 switch(message->imsg->Code)
4102 case RAWKEY_NM_WHEEL_UP:
4103 wheely = -1;
4104 rawkey_handled = TRUE;
4105 break;
4107 case RAWKEY_NM_WHEEL_DOWN:
4108 wheely = 1;
4109 rawkey_handled = TRUE;
4110 break;
4112 case RAWKEY_NM_WHEEL_LEFT:
4113 wheelx = -1;
4114 rawkey_handled = TRUE;
4115 break;
4117 case RAWKEY_NM_WHEEL_RIGHT:
4118 wheelx = 1;
4119 rawkey_handled = TRUE;
4120 break;
4123 if (rawkey_handled)
4125 #if defined(DEBUG_ILC_KEYEVENTS)
4126 D(bug("[IconList] %s: Processing mouse wheel event\n", __PRETTY_FUNCTION__));
4127 #endif
4128 if (_isinobject(message->imsg->MouseX, message->imsg->MouseY) &&
4129 (wheelx || wheely))
4131 DoWheelMove(CLASS, obj, wheelx, wheely, message->imsg->Qualifier);
4134 else if (!(message->imsg->Code & IECODE_UP_PREFIX))
4136 LONG new_ViewY = data->icld_ViewY;
4137 struct IconEntry *start_entry = NULL, *active_entry = NULL, *entry_next = NULL;
4138 IPTR start_X = 0, start_Y = 0, active_X = 0, active_Y = 0, next_X = 0, next_Y = 0;
4139 IPTR x_diff = 0;
4141 #if defined(DEBUG_ILC_KEYEVENTS)
4142 D(bug("[IconList] %s: Processing key up event\n", __PRETTY_FUNCTION__));
4143 #endif
4145 switch(message->imsg->Code)
4147 case RAWKEY_RETURN:
4148 rawkey_handled = TRUE;
4150 #if defined(DEBUG_ILC_KEYEVENTS)
4151 D(bug("[IconList] %s: RAWKEY_RETURN\n", __PRETTY_FUNCTION__));
4152 #endif
4154 if (data->icld_FocusIcon) active_entry = data->icld_FocusIcon;
4155 else if (data->icld_SelectionLastClicked) active_entry = data->icld_SelectionLastClicked;
4157 if (active_entry)
4159 if (!(active_entry->ie_Flags & ICONENTRY_FLAG_SELECTED))
4161 active_entry->ie_Flags |= ICONENTRY_FLAG_SELECTED;
4162 AddTail(&data->icld_SelectionList, &active_entry->ie_SelectionNode);
4163 data->icld_UpdateMode = UPDATE_SINGLEENTRY;
4164 data->update_entry = active_entry;
4165 MUI_Redraw(obj, MADF_DRAWUPDATE);
4167 data->icld_SelectionLastClicked = active_entry;
4168 data->icld_FocusIcon = active_entry;
4170 SET(obj, MUIA_IconList_DoubleClick, TRUE);
4172 break;
4174 case RAWKEY_SPACE:
4175 rawkey_handled = TRUE;
4177 #if defined(DEBUG_ILC_KEYEVENTS)
4178 D(bug("[IconList] %s: RAWKEY_SPACE\n", __PRETTY_FUNCTION__));
4179 #endif
4181 if (data->icld_FocusIcon) active_entry = data->icld_FocusIcon;
4182 else if (data->icld_SelectionLastClicked) active_entry = data->icld_SelectionLastClicked;
4184 if (!(message->imsg->Qualifier & IEQUALIFIER_LSHIFT) && ((data->icld_SelectionLastClicked)||(data->icld_SelectionLastClicked != active_entry)))
4186 #if defined(DEBUG_ILC_KEYEVENTS)
4187 D(bug("[IconList] %s: SPACE: Clearing selected icons ..\n", __PRETTY_FUNCTION__));
4188 #endif
4189 DoMethod(obj, MUIM_IconList_UnselectAll);
4192 if (active_entry)
4194 if (!(active_entry->ie_Flags & ICONENTRY_FLAG_SELECTED))
4196 AddTail(&data->icld_SelectionList, &active_entry->ie_SelectionNode);
4197 active_entry->ie_Flags |= ICONENTRY_FLAG_SELECTED;
4198 data->icld_SelectionLastClicked = active_entry;
4200 else
4202 Remove(&active_entry->ie_SelectionNode);
4203 active_entry->ie_Flags &= ~ICONENTRY_FLAG_SELECTED;
4206 data->icld_FocusIcon = active_entry;
4208 data->icld_UpdateMode = UPDATE_SINGLEENTRY;
4209 data->update_entry = active_entry;
4210 MUI_Redraw(obj, MADF_DRAWUPDATE);
4212 break;
4214 case RAWKEY_PAGEUP:
4215 rawkey_handled = TRUE;
4217 #if defined(DEBUG_ILC_KEYEVENTS)
4218 D(bug("[IconList] %s: RAWKEY_PAGEUP\n", __PRETTY_FUNCTION__));
4219 #endif
4221 if (data->icld_AreaHeight > data->icld_ViewHeight)
4223 new_ViewY -= data->icld_ViewHeight;
4224 if (new_ViewY< 0)
4225 new_ViewY = 0;
4228 if (new_ViewY != data->icld_ViewY)
4230 SET(obj, MUIA_Virtgroup_Top, new_ViewY);
4232 break;
4234 case RAWKEY_PAGEDOWN:
4235 rawkey_handled = TRUE;
4237 #if defined(DEBUG_ILC_KEYEVENTS)
4238 D(bug("[IconList] %s: RAWKEY_PAGEDOWN\n", __PRETTY_FUNCTION__));
4239 #endif
4241 if (data->icld_AreaHeight > data->icld_ViewHeight)
4243 new_ViewY += data->icld_ViewHeight;
4244 if (new_ViewY > (data->icld_AreaHeight - data->icld_ViewHeight))
4245 new_ViewY = data->icld_AreaHeight - data->icld_ViewHeight;
4248 if (new_ViewY != data->icld_ViewY)
4250 SET(obj, MUIA_Virtgroup_Top, new_ViewY);
4252 break;
4254 case RAWKEY_UP:
4255 rawkey_handled = TRUE;
4257 #if defined(DEBUG_ILC_KEYEVENTS)
4258 D(bug("[IconList] %s: RAWKEY_UP\n", __PRETTY_FUNCTION__));
4259 #endif
4261 if (data->icld_FocusIcon)
4263 start_entry = data->icld_FocusIcon;
4264 #if defined(DEBUG_ILC_KEYEVENTS)
4265 D(bug("[IconList] %s: UP: Clearing existing focused icon @ 0x%p\n", __PRETTY_FUNCTION__, start_entry));
4266 #endif
4268 start_entry->ie_Flags &= ~ICONENTRY_FLAG_FOCUS;
4269 data->icld_UpdateMode = UPDATE_SINGLEENTRY;
4270 data->update_entry = start_entry;
4271 MUI_Redraw(obj, MADF_DRAWUPDATE);
4273 start_X = start_entry->ie_IconX;
4274 start_Y = start_entry->ie_IconY;
4275 #if defined(DEBUG_ILC_KEYEVENTS)
4276 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));
4277 #endif
4278 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
4280 if (start_entry->ie_AreaWidth < data->icld_IconAreaLargestWidth)
4282 start_X = start_X - ((data->icld_IconAreaLargestWidth - start_entry->ie_AreaWidth)/2);
4283 #if defined(DEBUG_ILC_KEYEVENTS)
4284 D(bug("[IconList] %s: UP: adjusted start_X for grid = %d\n", __PRETTY_FUNCTION__, start_X));
4285 #endif
4289 if ((active_entry = Node_PreviousVisible(start_entry)) && !(data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL))
4291 //Check if we are at the edge of the icon area ..
4292 #if defined(DEBUG_ILC_KEYEVENTS)
4293 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));
4294 #endif
4295 active_Y = active_entry->ie_IconY;
4297 if (active_Y == start_Y)
4300 #if defined(DEBUG_ILC_KEYEVENTS)
4301 D(bug("[IconList] %s: UP: active_entry is on our row (not at the edge)\n", __PRETTY_FUNCTION__));
4302 #endif
4303 entry_next = active_entry;
4304 next_X = entry_next->ie_IconX;
4305 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
4307 if (entry_next->ie_AreaWidth < data->icld_IconAreaLargestWidth)
4308 next_X = next_X - ((data->icld_IconAreaLargestWidth - entry_next->ie_AreaWidth)/2);
4312 #if defined(DEBUG_ILC_KEYEVENTS)
4313 D(bug("[IconList] %s: UP: using start_X %d, start_Y %d\n", __PRETTY_FUNCTION__, start_X, start_Y));
4314 #endif
4317 if (!(message->imsg->Qualifier & IEQUALIFIER_LSHIFT) && ((data->icld_SelectionLastClicked)&&(data->icld_SelectionLastClicked != active_entry)))
4319 #if defined(DEBUG_ILC_KEYEVENTS)
4320 D(bug("[IconList] %s: UP: Clearing selected icons ..\n", __PRETTY_FUNCTION__));
4321 #endif
4322 DoMethod(obj, MUIM_IconList_UnselectAll);
4325 #if defined(DEBUG_ILC_KEYEVENTS)
4326 D(bug("[IconList] %s: UP: active = 0x%p, next = 0x%p\n", __PRETTY_FUNCTION__, active_entry, entry_next));
4327 #endif
4328 if (!(active_entry))
4330 // If nothing is selected we will use the last visible icon ..
4331 active_entry = Node_LastVisible(&data->icld_IconList);
4332 start_X = active_entry->ie_IconX;
4333 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
4335 if (active_entry->ie_AreaWidth < data->icld_IconAreaLargestWidth)
4336 start_X = start_X - ((data->icld_IconAreaLargestWidth - active_entry->ie_AreaWidth)/2);
4338 start_Y = active_entry->ie_IconY;
4341 while (active_entry != NULL)
4343 #if defined(DEBUG_ILC_KEYEVENTS)
4344 D(bug("[IconList] %s: UP: Checking active @ 0x%p\n", __PRETTY_FUNCTION__, active_entry));
4345 #endif
4346 if (data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL)
4348 // Return the first visible since the list flow direction matches
4349 // our cursor direction
4350 if (active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE)
4351 break;
4353 else
4355 active_X = active_entry->ie_IconX;
4357 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
4359 if (active_entry->ie_AreaWidth < data->icld_IconAreaLargestWidth)
4360 x_diff = ((data->icld_IconAreaLargestWidth - active_entry->ie_AreaWidth)/2);
4362 active_Y = active_entry->ie_IconY;
4364 if (start_entry)
4366 if (entry_next)
4368 if ((active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE) &&
4369 (active_Y < start_Y) &&
4370 (((active_X - x_diff) >= start_X ) &&
4371 ((active_X - x_diff) <= (start_X + start_entry->ie_AreaWidth + (x_diff*2)))))
4373 #if defined(DEBUG_ILC_KEYEVENTS)
4374 D(bug("[IconList] %s: UP: (A) entry 0x%p matches\n", __PRETTY_FUNCTION__, active_entry));
4375 #endif
4376 break;
4378 else if (active_entry == (struct IconEntry *)GetHead(&data->icld_IconList))
4380 #if defined(DEBUG_ILC_KEYEVENTS)
4381 D(bug("[IconList] %s: UP: (A) reached list start .. restarting from the end ..\n", __PRETTY_FUNCTION__));
4382 #endif
4383 start_X = next_X;
4385 if ((entry_next = Node_PreviousVisible(entry_next)))
4387 if (entry_next->ie_IconX > start_X)
4388 entry_next = NULL;
4389 else
4391 next_X = entry_next->ie_IconX;
4392 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
4394 if (entry_next->ie_AreaWidth < data->icld_IconAreaLargestWidth)
4395 next_X = next_X - ((data->icld_IconAreaLargestWidth - entry_next->ie_AreaWidth)/2);
4399 start_Y = 0;
4400 #if defined(DEBUG_ILC_KEYEVENTS)
4401 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));
4402 #endif
4403 active_entry = Node_LastVisible(&data->icld_IconList);
4406 else
4408 if ((active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE) &&
4409 (active_Y < start_Y) &&
4410 ((active_X + x_diff) < (start_X + start_entry->ie_AreaWidth + x_diff)))
4412 #if defined(DEBUG_ILC_KEYEVENTS)
4413 D(bug("[IconList] %s: UP: (B) entry 0x%p matches\n", __PRETTY_FUNCTION__, active_entry));
4414 #endif
4415 break;
4419 else
4421 if (active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE)
4423 #if defined(DEBUG_ILC_KEYEVENTS)
4424 D(bug("[IconList] %s: UP: (C) entry 0x%p matches\n", __PRETTY_FUNCTION__, active_entry));
4425 #endif
4426 break;
4430 active_entry = (struct IconEntry *)(((struct Node *)active_entry)->ln_Pred);
4433 if (!(active_entry))
4435 #if defined(DEBUG_ILC_KEYEVENTS)
4436 D(bug("[IconList] %s: UP: No Next UP Node - Getting Last visible icon ..\n", __PRETTY_FUNCTION__));
4437 #endif
4438 /* We didnt find a "next UP" icon so just use the last visible */
4439 active_entry = Node_LastVisible(&data->icld_IconList);
4442 if (active_entry)
4444 if (!(active_entry->ie_Flags & ICONENTRY_FLAG_FOCUS))
4446 active_entry->ie_Flags |= ICONENTRY_FLAG_FOCUS;
4447 data->icld_UpdateMode = UPDATE_SINGLEENTRY;
4448 data->update_entry = active_entry;
4449 MUI_Redraw(obj, MADF_DRAWUPDATE);
4452 data->icld_FocusIcon = active_entry;
4453 break;
4455 case RAWKEY_DOWN:
4456 rawkey_handled = TRUE;
4458 #if defined(DEBUG_ILC_KEYEVENTS)
4459 D(bug("[IconList] %s: RAWKEY_DOWN\n", __PRETTY_FUNCTION__));
4460 #endif
4461 if (data->icld_FocusIcon)
4463 start_entry = data->icld_FocusIcon;
4464 #if defined(DEBUG_ILC_KEYEVENTS)
4465 D(bug("[IconList] %s: DOWN: Clearing existing focused icon @ 0x%p\n", __PRETTY_FUNCTION__, start_entry));
4466 #endif
4468 start_entry->ie_Flags &= ~ICONENTRY_FLAG_FOCUS;
4469 data->icld_UpdateMode = UPDATE_SINGLEENTRY;
4470 data->update_entry = start_entry;
4471 MUI_Redraw(obj, MADF_DRAWUPDATE);
4473 start_X = start_entry->ie_IconX;
4474 start_Y = start_entry->ie_IconY;
4475 #if defined(DEBUG_ILC_KEYEVENTS)
4476 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));
4477 #endif
4478 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
4480 if (start_entry->ie_AreaWidth < data->icld_IconAreaLargestWidth)
4482 start_X = start_X - ((data->icld_IconAreaLargestWidth - start_entry->ie_AreaWidth)/2);
4483 #if defined(DEBUG_ILC_KEYEVENTS)
4484 D(bug("[IconList] %s: DOWN: adjusted start_X for grid = %d\n", __PRETTY_FUNCTION__, start_X));
4485 #endif
4489 if ((active_entry = Node_NextVisible(start_entry)) &&
4490 (!(data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL)))
4492 #if defined(DEBUG_ILC_KEYEVENTS)
4493 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));
4494 #endif
4495 active_Y = active_entry->ie_IconY;
4497 if (active_Y == start_Y)
4500 #if defined(DEBUG_ILC_KEYEVENTS)
4501 D(bug("[IconList] %s: DOWN: active_entry is on our row (not at the edge)\n", __PRETTY_FUNCTION__));
4502 #endif
4503 entry_next = active_entry;
4504 next_X = entry_next->ie_IconX;
4505 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
4507 if (entry_next->ie_AreaWidth < data->icld_IconAreaLargestWidth)
4508 next_X = next_X - ((data->icld_IconAreaLargestWidth - entry_next->ie_AreaWidth)/2);
4512 #if defined(DEBUG_ILC_KEYEVENTS)
4513 D(bug("[IconList] %s: DOWN: using start_X %d, start_Y %d\n", __PRETTY_FUNCTION__, start_X, start_Y));
4514 #endif
4517 if (!(message->imsg->Qualifier & IEQUALIFIER_LSHIFT) && ((data->icld_SelectionLastClicked)&&(data->icld_SelectionLastClicked != active_entry)))
4519 #if defined(DEBUG_ILC_KEYEVENTS)
4520 D(bug("[IconList] %s: DOWN: Clearing selected icons ..\n", __PRETTY_FUNCTION__));
4521 #endif
4522 DoMethod(obj, MUIM_IconList_UnselectAll);
4525 #if defined(DEBUG_ILC_KEYEVENTS)
4526 D(bug("[IconList] %s: DOWN: active = 0x%p, next = 0x%p\n", __PRETTY_FUNCTION__, active_entry, entry_next));
4527 #endif
4528 if (!(active_entry))
4530 // If nothing is selected we will use the First visible icon ..
4531 active_entry = Node_FirstVisible(&data->icld_IconList);
4532 start_X = active_entry->ie_IconX;
4533 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
4535 if (active_entry->ie_AreaWidth < data->icld_IconAreaLargestWidth)
4536 start_X = start_X - ((data->icld_IconAreaLargestWidth - active_entry->ie_AreaWidth)/2);
4538 start_Y = active_entry->ie_IconY;
4541 while (active_entry != NULL)
4543 #if defined(DEBUG_ILC_KEYEVENTS)
4544 D(bug("[IconList] %s: DOWN: Checking active @ 0x%p\n", __PRETTY_FUNCTION__, active_entry));
4545 #endif
4546 if (data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL)
4548 if (active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE)
4549 break;
4551 else
4553 active_X = active_entry->ie_IconX;
4555 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
4557 if (active_entry->ie_AreaWidth < data->icld_IconAreaLargestWidth)
4558 x_diff = ((data->icld_IconAreaLargestWidth - active_entry->ie_AreaWidth)/2);
4560 active_Y = active_entry->ie_IconY;
4562 if (start_entry)
4564 if (entry_next)
4566 if ((active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE) &&
4567 (active_Y > start_Y) &&
4568 (((active_X - x_diff) >= start_X ) &&
4569 ((active_X - x_diff) <= (start_X + start_entry->ie_AreaWidth + (x_diff*2)))))
4571 #if defined(DEBUG_ILC_KEYEVENTS)
4572 D(bug("[IconList] %s: DOWN: (A) entry 0x%p matches\n", __PRETTY_FUNCTION__, active_entry));
4573 #endif
4574 break;
4576 else if (active_entry == (struct IconEntry *)GetTail(&data->icld_IconList))
4578 #if defined(DEBUG_ILC_KEYEVENTS)
4579 D(bug("[IconList] %s: DOWN: (A) reached list end .. starting at the beginng ..\n", __PRETTY_FUNCTION__));
4580 #endif
4581 start_X = entry_next->ie_IconX;
4582 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
4584 if (entry_next->ie_AreaWidth < data->icld_IconAreaLargestWidth)
4585 start_X = start_X - ((data->icld_IconAreaLargestWidth - entry_next->ie_AreaWidth)/2);
4588 if ((entry_next = (struct IconEntry *)Node_NextVisible(entry_next)))
4590 if (entry_next->ie_IconX < start_X)
4591 entry_next = NULL;
4592 else
4594 next_X = entry_next->ie_IconX;
4595 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
4597 if (entry_next->ie_AreaWidth < data->icld_IconAreaLargestWidth)
4598 next_X = next_X + ((data->icld_IconAreaLargestWidth - entry_next->ie_AreaWidth)/2);
4602 start_Y = 0;
4603 #if defined(DEBUG_ILC_KEYEVENTS)
4604 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));
4605 #endif
4606 active_entry = Node_FirstVisible(&data->icld_IconList);
4609 else
4611 if ((active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE) &&
4612 (active_Y > start_Y) &&
4613 (active_X > start_X - 1))
4615 #if defined(DEBUG_ILC_KEYEVENTS)
4616 D(bug("[IconList] %s: DOWN: (B) entry 0x%p matches\n", __PRETTY_FUNCTION__, active_entry));
4617 #endif
4618 break;
4622 else
4624 if (active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE)
4626 #if defined(DEBUG_ILC_KEYEVENTS)
4627 D(bug("[IconList] %s: DOWN: (C) entry 0x%p matches\n", __PRETTY_FUNCTION__, active_entry));
4628 #endif
4629 break;
4633 active_entry = (struct IconEntry *)GetSucc(&active_entry->ie_IconNode);
4636 if (!(active_entry))
4638 #if defined(DEBUG_ILC_KEYEVENTS)
4639 D(bug("[IconList] %s: DOWN: No Next DOWN Node - Getting first visable icon ..\n", __PRETTY_FUNCTION__));
4640 #endif
4641 /* We didnt find a "next DOWN" icon so just use the first visible */
4642 active_entry = Node_FirstVisible(&data->icld_IconList);
4645 if (active_entry)
4647 if (!(active_entry->ie_Flags & ICONENTRY_FLAG_FOCUS))
4649 active_entry->ie_Flags |= ICONENTRY_FLAG_FOCUS;
4650 data->icld_UpdateMode = UPDATE_SINGLEENTRY;
4651 data->update_entry = active_entry;
4652 MUI_Redraw(obj, MADF_DRAWUPDATE);
4655 data->icld_FocusIcon = active_entry;
4656 break;
4658 case RAWKEY_LEFT:
4659 rawkey_handled = TRUE;
4661 #if defined(DEBUG_ILC_KEYEVENTS)
4662 D(bug("[IconList] %s: RAWKEY_LEFT\n", __PRETTY_FUNCTION__));
4663 #endif
4664 if (data->icld_FocusIcon)
4666 start_entry = data->icld_FocusIcon;
4667 #if defined(DEBUG_ILC_KEYEVENTS)
4668 D(bug("[IconList] %s: LEFT: Clearing existing focused icon @ 0x%p\n", __PRETTY_FUNCTION__, start_entry));
4669 #endif
4671 start_entry->ie_Flags &= ~ICONENTRY_FLAG_FOCUS;
4672 data->icld_UpdateMode = UPDATE_SINGLEENTRY;
4673 data->update_entry = start_entry;
4674 MUI_Redraw(obj, MADF_DRAWUPDATE);
4676 start_X = start_entry->ie_IconX;
4677 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
4679 if (start_entry->ie_AreaWidth < data->icld_IconAreaLargestWidth)
4680 start_X = start_X - ((data->icld_IconAreaLargestWidth - start_entry->ie_AreaWidth)/2);
4682 start_Y = start_entry->ie_IconY;
4684 #if defined(DEBUG_ILC_KEYEVENTS)
4685 D(bug("[IconList] %s: LEFT: start_X %d, start_Y %d\n", __PRETTY_FUNCTION__, start_X, start_Y));
4686 #endif
4688 if (!(active_entry = Node_NextVisible(start_entry)) && (!(data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL)))
4690 active_entry = (struct IconEntry *)GetHead(&data->icld_IconList);
4691 #if defined(DEBUG_ILC_KEYEVENTS)
4692 D(bug("[IconList] %s: LEFT: Start at the beginning (Active @ 0x%p) using icon X + Width\n", __PRETTY_FUNCTION__, active_entry));
4693 #endif
4694 start_X = start_X + start_entry->ie_AreaWidth;
4695 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
4697 if (start_entry->ie_AreaWidth < data->icld_IconAreaLargestWidth)
4698 start_X = start_X + ((data->icld_IconAreaLargestWidth - start_entry->ie_AreaWidth)/2);
4701 start_Y = 0;
4702 entry_next = NULL;
4704 else if (active_entry && (!(data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL)))
4706 #if defined(DEBUG_ILC_KEYEVENTS)
4707 D(bug("[IconList] %s: LEFT: Active @ 0x%p, X %d\n", __PRETTY_FUNCTION__, active_entry, active_entry->ie_IconX));
4708 #endif
4709 if ((entry_next = Node_NextVisible(start_entry)))
4711 #if defined(DEBUG_ILC_KEYEVENTS)
4712 D(bug("[IconList] %s: LEFT: Next @ 0x%p, X %d\n", __PRETTY_FUNCTION__, entry_next, entry_next->ie_IconX));
4713 #endif
4715 if (entry_next->ie_IconX < start_X)
4716 entry_next = NULL;
4717 else
4719 next_X = entry_next->ie_IconX;
4720 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
4722 if (entry_next->ie_AreaWidth < data->icld_IconAreaLargestWidth)
4723 next_X = next_X - ((data->icld_IconAreaLargestWidth - entry_next->ie_AreaWidth)/2);
4728 #if defined(DEBUG_ILC_KEYEVENTS)
4729 D(bug("[IconList] %s: LEFT: using start_X %d, start_Y %d\n", __PRETTY_FUNCTION__, start_X, start_Y));
4730 #endif
4733 if (!(message->imsg->Qualifier & IEQUALIFIER_LSHIFT) && ((data->icld_SelectionLastClicked)&&(data->icld_SelectionLastClicked != active_entry)))
4735 #if defined(DEBUG_ILC_KEYEVENTS)
4736 D(bug("[IconList] %s: LEFT: Clearing selected icons ..\n", __PRETTY_FUNCTION__));
4737 #endif
4738 DoMethod(obj, MUIM_IconList_UnselectAll);
4741 #if defined(DEBUG_ILC_KEYEVENTS)
4742 D(bug("[IconList] %s: LEFT: active = 0x%p, next = 0x%p\n", __PRETTY_FUNCTION__, active_entry, entry_next));
4743 #endif
4745 if (!(active_entry))
4747 active_entry = (struct IconEntry *)GetHead(&data->icld_IconList);
4750 while (active_entry != NULL)
4752 #if defined(DEBUG_ILC_KEYEVENTS)
4753 D(bug("[IconList] %s: LEFT: Checking active @ 0x%p\n", __PRETTY_FUNCTION__, active_entry));
4754 #endif
4755 if (data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL)
4757 if (active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE)
4758 break;
4760 else
4762 LONG active_entry_X = active_entry->ie_IconX;
4763 LONG active_entry_Y;
4764 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
4766 if (active_entry->ie_AreaWidth < data->icld_IconAreaLargestWidth)
4767 active_entry_X = active_entry_X - ((data->icld_IconAreaLargestWidth - active_entry->ie_AreaWidth)/2);
4769 active_entry_Y = active_entry->ie_IconY;
4771 if (start_entry)
4773 if (entry_next)
4775 if ((active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE) &&
4776 (active_entry_Y > start_Y) &&
4777 ((active_entry_X > start_X - 1) &&
4778 (active_entry_X < next_X)))
4780 #if defined(DEBUG_ILC_KEYEVENTS)
4781 D(bug("[IconList] %s: LEFT: (A) entry 0x%p matches\n", __PRETTY_FUNCTION__, active_entry));
4782 #endif
4783 break;
4785 else if (active_entry == (struct IconEntry *)GetTail(&data->icld_IconList))
4787 #if defined(DEBUG_ILC_KEYEVENTS)
4788 D(bug("[IconList] %s: LEFT: (A) reached list end .. starting at the beginng ..\n", __PRETTY_FUNCTION__));
4789 #endif
4790 start_X = entry_next->ie_IconX;
4791 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
4793 if (entry_next->ie_AreaWidth < data->icld_IconAreaLargestWidth)
4794 start_X = start_X - ((data->icld_IconAreaLargestWidth - entry_next->ie_AreaWidth)/2);
4797 if ((entry_next = Node_NextVisible(entry_next)))
4799 if (entry_next->ie_IconX < start_X)
4800 entry_next = NULL;
4801 else
4803 next_X = entry_next->ie_IconX;
4804 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
4806 if (entry_next->ie_AreaWidth < data->icld_IconAreaLargestWidth)
4807 next_X = next_X + ((data->icld_IconAreaLargestWidth - entry_next->ie_AreaWidth)/2);
4811 start_Y = 0;
4812 #if defined(DEBUG_ILC_KEYEVENTS)
4813 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));
4814 #endif
4815 active_entry = (struct IconEntry *)GetHead(&data->icld_IconList);
4818 else
4820 if ((active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE) &&
4821 (active_entry_Y > start_Y) &&
4822 (active_entry_X > start_X - 1))
4824 #if defined(DEBUG_ILC_KEYEVENTS)
4825 D(bug("[IconList] %s: LEFT: (B) entry 0x%p matches\n", __PRETTY_FUNCTION__, active_entry));
4826 #endif
4827 break;
4831 else
4833 if (active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE)
4835 #if defined(DEBUG_ILC_KEYEVENTS)
4836 D(bug("[IconList] %s: LEFT: (C) entry 0x%p matches\n", __PRETTY_FUNCTION__, active_entry));
4837 #endif
4838 break;
4842 active_entry = (struct IconEntry *)GetSucc(&active_entry->ie_IconNode);
4845 if (!(active_entry))
4847 #if defined(DEBUG_ILC_KEYEVENTS)
4848 D(bug("[IconList] %s: LEFT: No Next LEFT Node - Getting first visable icon ..\n", __PRETTY_FUNCTION__));
4849 #endif
4850 /* We didnt find a "next LEFT" icon so just use the last visible */
4851 active_entry = (struct IconEntry *)GetHead(&data->icld_IconList);
4852 while ((active_entry != NULL) &&(!(active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE)))
4854 active_entry = (struct IconEntry *)GetSucc(&active_entry->ie_IconNode);
4858 if (active_entry)
4860 if (!(active_entry->ie_Flags & ICONENTRY_FLAG_FOCUS))
4862 active_entry->ie_Flags |= ICONENTRY_FLAG_FOCUS;
4863 data->icld_UpdateMode = UPDATE_SINGLEENTRY;
4864 data->update_entry = active_entry;
4865 MUI_Redraw(obj, MADF_DRAWUPDATE);
4868 data->icld_FocusIcon = active_entry;
4869 break;
4871 case RAWKEY_RIGHT:
4872 rawkey_handled = TRUE;
4874 #if defined(DEBUG_ILC_KEYEVENTS)
4875 D(bug("[IconList] %s: RAWKEY_RIGHT\n", __PRETTY_FUNCTION__));
4876 #endif
4878 if (data->icld_FocusIcon)
4880 start_entry = data->icld_FocusIcon;
4881 #if defined(DEBUG_ILC_KEYEVENTS)
4882 D(bug("[IconList] %s: RIGHT: Clearing existing focused icon @ 0x%p\n", __PRETTY_FUNCTION__, start_entry));
4883 #endif
4884 start_entry->ie_Flags &= ~ICONENTRY_FLAG_FOCUS;
4885 data->icld_UpdateMode = UPDATE_SINGLEENTRY;
4886 data->update_entry = start_entry;
4887 MUI_Redraw(obj, MADF_DRAWUPDATE);
4889 start_X = start_entry->ie_IconX;
4890 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
4892 if (start_entry->ie_AreaWidth < data->icld_IconAreaLargestWidth)
4893 start_X = start_X - ((data->icld_IconAreaLargestWidth - start_entry->ie_AreaWidth)/2);
4895 start_Y = start_entry->ie_IconY;
4897 #if defined(DEBUG_ILC_KEYEVENTS)
4898 D(bug("[IconList] %s: RIGHT: start_X %d, start_Y %d\n", __PRETTY_FUNCTION__, start_X, start_Y));
4899 #endif
4900 if (!(active_entry = Node_NextVisible(start_entry)) && (!(data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL)))
4902 active_entry = (struct IconEntry *)GetHead(&data->icld_IconList);
4903 #if defined(DEBUG_ILC_KEYEVENTS)
4904 D(bug("[IconList] %s: RIGHT: Start at the beginning (Active @ 0x%p) using icon X + Width\n", __PRETTY_FUNCTION__, active_entry));
4905 #endif
4906 start_X = 0;
4907 start_Y = start_Y + start_entry->ie_AreaHeight;
4908 entry_next = NULL;
4910 else if (active_entry && (data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL))
4912 #if defined(DEBUG_ILC_KEYEVENTS)
4913 D(bug("[IconList] %s: RIGHT: Active @ 0x%p, X %d\n", __PRETTY_FUNCTION__, active_entry, active_entry->ie_IconX));
4914 #endif
4915 if ((entry_next = Node_NextVisible(start_entry)))
4917 #if defined(DEBUG_ILC_KEYEVENTS)
4918 D(bug("[IconList] %s: RIGHT: Next @ 0x%p, X %d\n", __PRETTY_FUNCTION__, entry_next, entry_next->ie_IconX));
4919 #endif
4921 if (entry_next->ie_IconY < start_Y)
4922 entry_next = NULL;
4923 else
4924 next_Y = entry_next->ie_IconY;
4927 #if defined(DEBUG_ILC_KEYEVENTS)
4928 D(bug("[IconList] %s: RIGHT: using start_X %d, start_Y %d\n", __PRETTY_FUNCTION__, start_X, start_Y));
4929 #endif
4932 if (!(message->imsg->Qualifier & IEQUALIFIER_LSHIFT) && ((data->icld_SelectionLastClicked)&&(data->icld_SelectionLastClicked != active_entry)))
4934 #if defined(DEBUG_ILC_KEYEVENTS)
4935 D(bug("[IconList] %s: RIGHT: Clearing selected icons ..\n", __PRETTY_FUNCTION__));
4936 #endif
4937 DoMethod(obj, MUIM_IconList_UnselectAll);
4940 #if defined(DEBUG_ILC_KEYEVENTS)
4941 D(bug("[IconList] %s: RIGHT: active = 0x%p, next = 0x%p\n", __PRETTY_FUNCTION__, active_entry, entry_next));
4942 #endif
4944 if (!(active_entry))
4946 active_entry = (struct IconEntry *)GetHead(&data->icld_IconList);
4949 while (active_entry != NULL)
4951 #if defined(DEBUG_ILC_KEYEVENTS)
4952 D(bug("[IconList] %s: RIGHT: Checking active @ 0x%p\n", __PRETTY_FUNCTION__, active_entry));
4953 #endif
4954 if (!(data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL))
4956 if (active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE)
4957 break;
4959 else
4961 LONG active_entry_X = active_entry->ie_IconX;
4962 LONG active_entry_Y;
4963 if (data->icld__Option_IconListMode == ICON_LISTMODE_GRID)
4965 if (active_entry->ie_AreaWidth < data->icld_IconAreaLargestWidth)
4966 active_entry_X = active_entry_X - ((data->icld_IconAreaLargestWidth - active_entry->ie_AreaWidth)/2);
4968 active_entry_Y = active_entry->ie_IconY;
4970 if (start_entry)
4972 if (entry_next)
4974 if ((active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE) &&
4975 (active_entry_X > start_X) &&
4976 ((active_entry_Y > start_Y - 1) &&
4977 (active_entry_Y < next_Y)))
4979 #if defined(DEBUG_ILC_KEYEVENTS)
4980 D(bug("[IconList] %s: RIGHT: (A) entry 0x%p matches\n", __PRETTY_FUNCTION__, active_entry));
4981 #endif
4982 break;
4984 else if (active_entry == (struct IconEntry *)GetTail(&data->icld_IconList))
4986 #if defined(DEBUG_ILC_KEYEVENTS)
4987 D(bug("[IconList] %s: RIGHT: (A) reached list end .. starting at the beginng ..\n", __PRETTY_FUNCTION__));
4988 #endif
4989 start_Y = entry_next->ie_IconY;
4991 if ((entry_next = Node_NextVisible(entry_next)))
4993 if (entry_next->ie_IconY < start_Y)
4994 entry_next = NULL;
4995 else
4997 next_Y = entry_next->ie_IconY;
5000 start_Y = 0;
5001 #if defined(DEBUG_ILC_KEYEVENTS)
5002 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));
5003 #endif
5004 active_entry = (struct IconEntry *)GetHead(&data->icld_IconList);
5007 else
5009 if ((active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE) &&
5010 (active_entry_X > start_X) &&
5011 (active_entry_Y > start_Y - 1))
5013 #if defined(DEBUG_ILC_KEYEVENTS)
5014 D(bug("[IconList] %s: RIGHT: (B) entry 0x%p matches\n", __PRETTY_FUNCTION__, active_entry));
5015 #endif
5016 break;
5020 else
5022 if (active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE)
5024 #if defined(DEBUG_ILC_KEYEVENTS)
5025 D(bug("[IconList] %s: RIGHT: (C) entry 0x%p matches\n", __PRETTY_FUNCTION__, active_entry));
5026 #endif
5027 break;
5031 active_entry = (struct IconEntry *)GetSucc(&active_entry->ie_IconNode);
5034 if (!(active_entry))
5036 #if defined(DEBUG_ILC_KEYEVENTS)
5037 D(bug("[IconList] %s: RIGHT: No Next RIGHT Node - Getting first visable icon ..\n", __PRETTY_FUNCTION__));
5038 #endif
5039 /* We didnt find a "next RIGHT" icon so just use the first visible */
5040 active_entry = (struct IconEntry *)GetHead(&data->icld_IconList);
5041 while ((active_entry != NULL) &&(!(active_entry->ie_Flags & ICONENTRY_FLAG_VISIBLE)))
5043 active_entry = (struct IconEntry *)GetSucc(&active_entry->ie_IconNode);
5047 if (active_entry)
5049 if (!(active_entry->ie_Flags & ICONENTRY_FLAG_FOCUS))
5051 active_entry->ie_Flags |= ICONENTRY_FLAG_FOCUS;
5052 data->icld_UpdateMode = UPDATE_SINGLEENTRY;
5053 data->update_entry = active_entry;
5054 MUI_Redraw(obj, MADF_DRAWUPDATE);
5057 data->icld_FocusIcon = active_entry;
5058 break;
5060 case RAWKEY_HOME:
5061 rawkey_handled = TRUE;
5063 #if defined(DEBUG_ILC_KEYEVENTS)
5064 D(bug("[IconList] %s: RAWKEY_HOME\n", __PRETTY_FUNCTION__));
5065 #endif
5067 if (data->icld_FocusIcon)
5069 data->icld_FocusIcon->ie_Flags &= ~ICONENTRY_FLAG_FOCUS;
5070 data->icld_UpdateMode = UPDATE_SINGLEENTRY;
5071 data->update_entry = data->icld_FocusIcon;
5072 MUI_Redraw(obj, MADF_DRAWUPDATE);
5075 active_entry = Node_FirstVisible(&data->icld_IconList);
5077 if ((active_entry) && (!(active_entry->ie_Flags & ICONENTRY_FLAG_FOCUS)))
5079 active_entry->ie_Flags |= ICONENTRY_FLAG_FOCUS;
5080 data->icld_UpdateMode = UPDATE_SINGLEENTRY;
5081 data->update_entry = active_entry;
5082 MUI_Redraw(obj, MADF_DRAWUPDATE);
5084 data->icld_FocusIcon = active_entry;
5085 break;
5087 case RAWKEY_END:
5088 rawkey_handled = TRUE;
5090 #if defined(DEBUG_ILC_KEYEVENTS)
5091 D(bug("[IconList] %s: RAWKEY_END\n", __PRETTY_FUNCTION__));
5092 #endif
5094 if (data->icld_FocusIcon)
5096 data->icld_FocusIcon->ie_Flags &= ~ICONENTRY_FLAG_FOCUS;
5097 data->icld_UpdateMode = UPDATE_SINGLEENTRY;
5098 data->update_entry = data->icld_FocusIcon;
5099 MUI_Redraw(obj, MADF_DRAWUPDATE);
5102 active_entry = Node_LastVisible(&data->icld_IconList);
5104 if ((active_entry) && (!(active_entry->ie_Flags & ICONENTRY_FLAG_FOCUS)))
5106 active_entry->ie_Flags |= ICONENTRY_FLAG_FOCUS;
5107 data->icld_UpdateMode = UPDATE_SINGLEENTRY;
5108 data->update_entry = active_entry;
5109 MUI_Redraw(obj, MADF_DRAWUPDATE);
5111 data->icld_FocusIcon = active_entry;
5112 break;
5115 if (rawkey_handled) return MUI_EventHandlerRC_Eat;
5117 break;
5119 case IDCMP_MOUSEBUTTONS:
5120 #if defined(DEBUG_ILC_EVENTS)
5121 D(bug("[IconList] %s: IDCMP_MOUSEBUTTONS\n", __PRETTY_FUNCTION__));
5122 #endif
5123 if (message->imsg->Code == SELECTDOWN)
5125 /* check if mouse pressed on iconlist area */
5126 if (mx >= 0 && mx < _width(obj) && my >= 0 && my < _height(obj))
5128 BOOL icon_doubleclicked = FALSE;
5129 BOOL update_entry;
5130 struct IconEntry *node = NULL;
5131 struct IconEntry *new_selected = NULL;
5133 if ((data->icld_DisplayFlags & ICONLIST_DISP_MODELIST) == ICONLIST_DISP_MODELIST)
5135 LONG clickColumn = -1, clickRow = -1;
5137 LONG x = _mleft(obj) - data->icld_ViewX + LINE_SPACING_LEFT;
5138 LONG w, i;
5140 for(i = 0; i < NUM_COLUMNS; i++)
5142 LONG index = data->icld_LVMAttribs->lmva_ColumnPos[i];
5144 if (!data->icld_LVMAttribs->lmva_ColumnVisible[index]) continue;
5146 w = data->icld_LVMAttribs->lmva_ColumnWidth[index];
5148 if ((mx >= x) && (mx < x + w))
5150 clickColumn = index;
5151 break;
5153 x += w;
5157 if (my <= data->icld_LVMAttribs->lmva_HeaderHeight)
5159 D(bug("[IconList] %s: Clicked on Header Column %d..\n", __PRETTY_FUNCTION__, clickColumn));
5161 else
5163 LONG current = 0, index = (my - data->icld_LVMAttribs->lmva_HeaderHeight + data->icld_ViewY) / data->icld_LVMAttribs->lmva_RowHeight;
5165 ForeachNode(&data->icld_IconList, node)
5167 if (node->ie_Flags & ICONENTRY_FLAG_VISIBLE)
5169 update_entry = FALSE;
5171 if (current == index)
5173 clickRow = current;
5174 new_selected = node;
5176 else
5178 if (node->ie_Flags & ICONENTRY_FLAG_SELECTED)
5180 if (!(message->imsg->Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT)))
5182 Remove(&node->ie_SelectionNode);
5183 node->ie_Flags &= ~ICONENTRY_FLAG_SELECTED;
5184 update_entry = TRUE;
5188 if (node->ie_Flags & ICONENTRY_FLAG_FOCUS)
5190 node->ie_Flags &= ~ICONENTRY_FLAG_FOCUS;
5191 update_entry = TRUE;
5194 if (update_entry)
5196 data->icld_UpdateMode = UPDATE_SINGLEENTRY;
5197 data->update_entry = node;
5198 MUI_Redraw(obj, MADF_DRAWUPDATE);
5199 D(bug("[IconList] %s: Rendered entry '%s'\n", __PRETTY_FUNCTION__, node->ie_IconListEntry.label));
5203 current++;
5207 if ((DoubleClick(data->last_secs, data->last_mics, message->imsg->Seconds, message->imsg->Micros)) && (data->icld_SelectionLastClicked == new_selected))
5209 D(bug("[IconList] %s: Icon double-clicked\n", __PRETTY_FUNCTION__));
5210 icon_doubleclicked = TRUE;
5213 if ((new_selected != NULL) && (clickRow != -1) && (clickColumn != -1))
5215 D(bug("[IconList] %s: Clicked on Row %d Column %d ..\n", __PRETTY_FUNCTION__, clickRow, clickColumn));
5217 data->icld_LassoActive = FALSE;
5218 update_entry = FALSE;
5220 if (!(new_selected->ie_Flags & ICONENTRY_FLAG_SELECTED))
5222 AddTail(&data->icld_SelectionList, &new_selected->ie_SelectionNode);
5223 new_selected->ie_Flags |= ICONENTRY_FLAG_SELECTED;
5224 update_entry = TRUE;
5226 if (!(new_selected->ie_Flags & ICONENTRY_FLAG_FOCUS))
5228 new_selected->ie_Flags |= ICONENTRY_FLAG_FOCUS;
5229 data->icld_FocusIcon = new_selected;
5232 else if ((icon_doubleclicked == FALSE) && (message->imsg->Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT)))
5234 Remove(&new_selected->ie_SelectionNode);
5235 new_selected->ie_Flags &= ~ICONENTRY_FLAG_SELECTED;
5236 update_entry = TRUE;
5239 if (update_entry)
5241 data->icld_UpdateMode = UPDATE_SINGLEENTRY;
5242 data->update_entry = new_selected;
5243 MUI_Redraw(obj, MADF_DRAWUPDATE);
5244 D(bug("[IconList] %s: Rendered 'new_selected' icon '%s'\n", __PRETTY_FUNCTION__, new_selected->ie_IconListEntry.label));
5247 else
5249 struct Window * thisWindow = NULL;
5250 #if defined(DEBUG_ILC_EVENTS) && defined(DEBUG_ILC_LASSO)
5251 D(bug("[IconList] %s: Starting Lasso\n", __PRETTY_FUNCTION__));
5252 #endif
5253 /* No icon clicked on ... Start Lasso-selection */
5254 data->icld_LassoActive = TRUE;
5255 if (!(message->imsg->Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT)))
5257 data->icld_SelectionLastClicked = NULL;
5258 data->icld_FocusIcon = NULL;
5260 data->icld_LassoRectangle.MinX = mx - data->view_rect.MinX + data->icld_ViewX;
5261 data->icld_LassoRectangle.MinY = my - data->view_rect.MinY + data->icld_ViewY;
5262 data->icld_LassoRectangle.MaxX = mx - data->view_rect.MinX + data->icld_ViewX;
5263 data->icld_LassoRectangle.MaxY = my - data->view_rect.MinY + data->icld_ViewY;
5265 /* Draw initial Lasso frame */
5266 IconList_InvertLassoOutlines(obj, &data->icld_LassoRectangle);
5268 GET(obj, MUIA_Window, &thisWindow);
5269 if (thisWindow)
5271 ModifyIDCMP(thisWindow, (thisWindow->IDCMPFlags|IDCMP_INTUITICKS));
5272 if (!(data->ehn.ehn_Events & IDCMP_INTUITICKS))
5274 DoMethod(_win(obj), MUIM_Window_RemEventHandler, (IPTR)&data->ehn);
5275 data->ehn.ehn_Events |= IDCMP_INTUITICKS;
5276 DoMethod(_win(obj), MUIM_Window_AddEventHandler, (IPTR)&data->ehn);
5282 else
5284 struct Rectangle rect;
5286 /* check if clicked on icon */
5287 #if defined(__AROS__)
5288 ForeachNode(&data->icld_IconList, node)
5289 #else
5290 Foreach_Node(&data->icld_IconList, node);
5291 #endif
5293 if (node->ie_Flags & ICONENTRY_FLAG_VISIBLE)
5295 update_entry = FALSE;
5297 rect.MinX = node->ie_IconX;
5298 rect.MaxX = node->ie_IconX + node->ie_AreaWidth - 1;
5299 rect.MinY = node->ie_IconY;
5300 rect.MaxY = node->ie_IconY + node->ie_AreaHeight - 1;
5302 if ((data->icld__Option_IconListMode == ICON_LISTMODE_GRID) &&
5303 (node->ie_AreaWidth < data->icld_IconAreaLargestWidth))
5305 rect.MinX += ((data->icld_IconAreaLargestWidth - node->ie_AreaWidth)/2);
5306 rect.MaxX += ((data->icld_IconAreaLargestWidth - node->ie_AreaWidth)/2);
5309 if ((((mx + data->icld_ViewX) >= rect.MinX) && ((mx + data->icld_ViewX) <= rect.MaxX )) &&
5310 (((my + data->icld_ViewY) >= rect.MinY) && ((my + data->icld_ViewY) <= rect.MaxY )) &&
5311 !new_selected)
5313 new_selected = node;
5314 #if defined(DEBUG_ILC_EVENTS)
5315 D(bug("[IconList] %s: Icon '%s' clicked on ..\n", __PRETTY_FUNCTION__, node->ie_IconListEntry.label));
5316 #endif
5319 if (node->ie_Flags & ICONENTRY_FLAG_SELECTED)
5321 if ((new_selected != node) &&
5322 (!(message->imsg->Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))))
5324 Remove(&node->ie_SelectionNode);
5325 node->ie_Flags &= ~ICONENTRY_FLAG_SELECTED;
5326 update_entry = TRUE;
5330 if ((node->ie_Flags & ICONENTRY_FLAG_FOCUS) && (new_selected != node))
5332 node->ie_Flags &= ~ICONENTRY_FLAG_FOCUS;
5333 update_entry = TRUE;
5336 if (update_entry)
5338 data->icld_UpdateMode = UPDATE_SINGLEENTRY;
5339 data->update_entry = node;
5340 MUI_Redraw(obj, MADF_DRAWUPDATE);
5341 #if defined(DEBUG_ILC_EVENTS)
5342 D(bug("[IconList] %s: Rendered icon '%s'\n", __PRETTY_FUNCTION__, node->ie_IconListEntry.label));
5343 #endif
5348 if ((DoubleClick(data->last_secs, data->last_mics, message->imsg->Seconds, message->imsg->Micros)) && (data->icld_SelectionLastClicked == new_selected))
5350 #if defined(DEBUG_ILC_EVENTS)
5351 D(bug("[IconList] %s: Icon double-clicked\n", __PRETTY_FUNCTION__));
5352 #endif
5353 icon_doubleclicked = TRUE;
5356 if (new_selected != NULL)
5358 data->icld_LassoActive = FALSE;
5359 update_entry = FALSE;
5361 if (!(new_selected->ie_Flags & ICONENTRY_FLAG_SELECTED))
5363 AddTail(&data->icld_SelectionList, &new_selected->ie_SelectionNode);
5364 new_selected->ie_Flags |= ICONENTRY_FLAG_SELECTED;
5365 update_entry = TRUE;
5367 if (!(new_selected->ie_Flags & ICONENTRY_FLAG_FOCUS))
5369 new_selected->ie_Flags |= ICONENTRY_FLAG_FOCUS;
5370 data->icld_FocusIcon = new_selected;
5373 else if ((icon_doubleclicked == FALSE) && (message->imsg->Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT)))
5375 Remove(&new_selected->ie_SelectionNode);
5376 new_selected->ie_Flags &= ~ICONENTRY_FLAG_SELECTED;
5377 update_entry = TRUE;
5380 if (update_entry != NULL)
5382 data->icld_UpdateMode = UPDATE_SINGLEENTRY;
5383 data->update_entry = new_selected;
5384 MUI_Redraw(obj, MADF_DRAWUPDATE);
5385 #if defined(DEBUG_ILC_EVENTS)
5386 D(bug("[IconList] %s: Rendered 'new_selected' icon '%s'\n", __PRETTY_FUNCTION__, new_selected->ie_IconListEntry.label));
5387 #endif
5390 else
5392 struct Window * thisWindow = NULL;
5393 #if defined(DEBUG_ILC_EVENTS) && defined(DEBUG_ILC_LASSO)
5394 D(bug("[IconList] %s: Starting Lasso\n", __PRETTY_FUNCTION__));
5395 #endif
5396 /* No icon clicked on ... Start Lasso-selection */
5397 data->icld_LassoActive = TRUE;
5398 if (!(message->imsg->Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT)))
5400 data->icld_SelectionLastClicked = NULL;
5401 data->icld_FocusIcon = NULL;
5403 data->icld_LassoRectangle.MinX = mx - data->view_rect.MinX + data->icld_ViewX;
5404 data->icld_LassoRectangle.MinY = my - data->view_rect.MinY + data->icld_ViewY;
5405 data->icld_LassoRectangle.MaxX = mx - data->view_rect.MinX + data->icld_ViewX;
5406 data->icld_LassoRectangle.MaxY = my - data->view_rect.MinY + data->icld_ViewY;
5408 /* Draw initial Lasso frame */
5409 IconList_InvertLassoOutlines(obj, &data->icld_LassoRectangle);
5411 GET(obj, MUIA_Window, &thisWindow);
5412 if (thisWindow)
5414 ModifyIDCMP(thisWindow, (thisWindow->IDCMPFlags|IDCMP_INTUITICKS));
5415 if (!(data->ehn.ehn_Events & IDCMP_INTUITICKS))
5417 DoMethod(_win(obj), MUIM_Window_RemEventHandler, (IPTR)&data->ehn);
5418 data->ehn.ehn_Events |= IDCMP_INTUITICKS;
5419 DoMethod(_win(obj), MUIM_Window_AddEventHandler, (IPTR)&data->ehn);
5425 if (new_selected && (new_selected->ie_Flags & ICONENTRY_FLAG_SELECTED))
5426 data->icld_SelectionLastClicked = new_selected;
5427 else
5428 data->icld_SelectionLastClicked = NULL;
5430 data->click_x = mx;
5431 data->click_y = my;
5433 SET(obj, MUIA_IconList_SelectionChanged, TRUE);
5435 data->icld_ClickEvent.shift = !!(message->imsg->Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT));
5436 data->icld_ClickEvent.entry = data->icld_SelectionLastClicked ? &data->icld_SelectionLastClicked->ie_IconListEntry : NULL;
5437 SET(obj, MUIA_IconList_Clicked, (IPTR)&data->icld_ClickEvent);
5439 if (icon_doubleclicked)
5441 SET(obj, MUIA_IconList_DoubleClick, TRUE);
5443 else if (!data->mouse_pressed)
5445 data->last_secs = message->imsg->Seconds;
5446 data->last_mics = message->imsg->Micros;
5448 /* After a double click you often open a new window
5449 * and since Zune doesn't not support the faking
5450 * of SELECTUP events only change the Events
5451 * if not doubleclicked */
5453 data->mouse_pressed |= LEFT_BUTTON;
5455 if (!(data->ehn.ehn_Events & IDCMP_MOUSEMOVE))
5457 DoMethod(_win(obj), MUIM_Window_RemEventHandler, (IPTR)&data->ehn);
5458 data->ehn.ehn_Events |= IDCMP_MOUSEMOVE;
5459 DoMethod(_win(obj), MUIM_Window_AddEventHandler, (IPTR)&data->ehn);
5463 return MUI_EventHandlerRC_Eat;
5466 else if (message->imsg->Code == MIDDLEDOWN)
5468 if (!data->mouse_pressed)
5470 data->mouse_pressed |= MIDDLE_BUTTON;
5472 data->click_x = data->icld_ViewX + mx;
5473 data->click_y = data->icld_ViewY + my;
5475 if (!(data->ehn.ehn_Events & IDCMP_MOUSEMOVE))
5477 DoMethod(_win(obj), MUIM_Window_RemEventHandler, (IPTR)&data->ehn);
5478 data->ehn.ehn_Events |= IDCMP_MOUSEMOVE;
5479 DoMethod(_win(obj), MUIM_Window_AddEventHandler, (IPTR)&data->ehn);
5483 else
5485 if (message->imsg->Code == SELECTUP)
5487 if (data->icld_LassoActive == TRUE)
5489 #if defined(DEBUG_ILC_EVENTS) && defined(DEBUG_ILC_LASSO)
5490 D(bug("[IconList] %s: Removing Lasso\n", __PRETTY_FUNCTION__));
5491 #endif
5492 // End Lasso-selection
5493 struct Rectangle old_lasso;
5494 struct IconEntry *node = NULL;
5495 struct Window *thisWindow = NULL;
5497 GET(obj, MUIA_Window, &thisWindow);
5498 if (thisWindow)
5500 ModifyIDCMP(thisWindow, (thisWindow->IDCMPFlags & ~(IDCMP_INTUITICKS)));
5501 if ((data->ehn.ehn_Events & IDCMP_INTUITICKS))
5503 DoMethod(_win(obj), MUIM_Window_RemEventHandler, (IPTR)&data->ehn);
5504 data->ehn.ehn_Events &= ~IDCMP_INTUITICKS;
5505 DoMethod(_win(obj), MUIM_Window_AddEventHandler, (IPTR)&data->ehn);
5508 //Clear Lasso Frame..
5509 GetAbsoluteLassoRect(data, &old_lasso);
5510 IconList_InvertLassoOutlines(obj, &old_lasso);
5512 data->icld_LassoActive = FALSE;
5514 //Remove Lasso flag from affected icons..
5515 #if defined(__AROS__)
5516 ForeachNode(&data->icld_IconList, node)
5517 #else
5518 Foreach_Node(&data->icld_IconList, node);
5519 #endif
5521 if (node->ie_Flags & ICONENTRY_FLAG_LASSO)
5523 node->ie_Flags &= ~ICONENTRY_FLAG_LASSO;
5526 SET(obj, MUIA_IconList_SelectionChanged, TRUE);
5529 data->mouse_pressed &= ~LEFT_BUTTON;
5532 if (message->imsg->Code == MIDDLEUP)
5534 data->mouse_pressed &= ~MIDDLE_BUTTON;
5537 if ((data->ehn.ehn_Events & IDCMP_MOUSEMOVE) && !data->mouse_pressed)
5539 DoMethod(_win(obj),MUIM_Window_RemEventHandler, (IPTR)&data->ehn);
5540 data->ehn.ehn_Events &= ~IDCMP_MOUSEMOVE;
5541 DoMethod(_win(obj),MUIM_Window_AddEventHandler, (IPTR)&data->ehn);
5544 break;
5546 case IDCMP_INTUITICKS:
5548 #if defined(DEBUG_ILC_EVENTS)
5549 D(bug("[IconList] %s: IDCMP_INTUITICKS (%d, %d)\n", __PRETTY_FUNCTION__, mx, my));
5550 #endif
5551 if ((data->icld_LassoActive == FALSE)||(!(data->mouse_pressed & LEFT_BUTTON)))
5553 break;
5555 if (((mx >= 0) && (mx <= _mwidth(obj))) &&
5556 ((my >= 0) && (my <= _mheight(obj))))
5557 break;
5560 case IDCMP_MOUSEMOVE:
5561 #if defined(DEBUG_ILC_EVENTS)
5562 D(bug("[IconList] %s: IDCMP_MOUSEMOVE\n", __PRETTY_FUNCTION__));
5563 #endif
5564 if (data->mouse_pressed & LEFT_BUTTON)
5566 LONG move_x = mx;
5567 LONG move_y = my;
5569 if (data->icld_SelectionLastClicked && (data->icld_LassoActive == FALSE) &&
5570 ((abs(move_x - data->click_x) >= 2) || (abs(move_y - data->click_y) >= 2)))
5572 // Icon(s) being dragged ....
5573 DoMethod(_win(obj),MUIM_Window_RemEventHandler, (IPTR)&data->ehn);
5574 data->ehn.ehn_Events &= ~IDCMP_MOUSEMOVE;
5575 DoMethod(_win(obj),MUIM_Window_AddEventHandler, (IPTR)&data->ehn);
5577 data->mouse_pressed &= ~LEFT_BUTTON;
5579 data->touch_x = move_x + data->icld_ViewX - data->icld_SelectionLastClicked->ie_IconX;
5580 data->touch_y = move_y + data->icld_ViewY - data->icld_SelectionLastClicked->ie_IconY;
5581 DoMethod(obj,MUIM_DoDrag, data->touch_x, data->touch_y, 0);
5583 else if (data->icld_LassoActive == TRUE)
5585 #if defined(DEBUG_ILC_EVENTS) && defined(DEBUG_ILC_LASSO)
5586 D(bug("[IconList] %s: Update Lasso\n", __PRETTY_FUNCTION__));
5587 #endif
5588 //Lasso active ..
5589 struct Rectangle new_lasso,
5590 old_lasso;
5591 struct Rectangle iconrect;
5593 struct IconEntry *node = NULL;
5594 // struct IconEntry *new_selected = NULL;
5596 /* Remove previous Lasso frame */
5597 GetAbsoluteLassoRect(data, &old_lasso);
5598 IconList_InvertLassoOutlines(obj, &old_lasso);
5600 /* if the mouse leaves our visible area scroll the view */
5601 if (mx < 0 || mx >= _mwidth(obj) || my < 0 || my >= _mheight(obj))
5603 LONG newleft = data->icld_ViewX;
5604 LONG newtop = data->icld_ViewY;
5606 if (mx >= _mwidth(obj)) newleft += (mx - _mwidth(obj));
5607 else if (mx < 0) newleft += mx;
5608 if (my >= _mheight(obj)) newtop += (my - _mheight(obj));
5609 else if (my < 0) newtop += my;
5611 if (newleft + _mwidth(obj) > data->icld_AreaWidth) newleft = data->icld_AreaWidth - _mwidth(obj);
5612 if (newleft < 0) newleft = 0;
5614 if (newtop + _mheight(obj) > data->icld_AreaHeight) newtop = data->icld_AreaHeight - _mheight(obj);
5615 if (newtop < 0) newtop = 0;
5617 if ((newleft != data->icld_ViewX) || (newtop != data->icld_ViewY))
5619 SetAttrs(obj, MUIA_Virtgroup_Left, newleft, MUIA_Virtgroup_Top, newtop, TAG_DONE);
5623 /* update Lasso coordinates */
5624 data->icld_LassoRectangle.MaxX = mx - data->view_rect.MinX + data->icld_ViewX;
5625 data->icld_LassoRectangle.MaxY = my - data->view_rect.MinY + data->icld_ViewY;
5627 /* get absolute Lasso coordinates */
5628 GetAbsoluteLassoRect(data, &new_lasso);
5630 LONG current = 0, startIndex = 0, endIndex = 0;
5632 if ((data->icld_DisplayFlags & ICONLIST_DISP_MODELIST) == ICONLIST_DISP_MODELIST)
5634 startIndex = ((data->icld_LassoRectangle.MinY + 1) - data->icld_LVMAttribs->lmva_HeaderHeight + data->icld_ViewY) / data->icld_LVMAttribs->lmva_RowHeight;
5635 endIndex = ((data->icld_LassoRectangle.MaxY - 1) - data->icld_LVMAttribs->lmva_HeaderHeight + data->icld_ViewY) / data->icld_LVMAttribs->lmva_RowHeight;
5637 if (startIndex > endIndex)
5639 startIndex ^= endIndex;
5640 endIndex ^= startIndex;
5641 startIndex ^= endIndex;
5644 D(bug("[IconList] %s: Start Index : %d, End Index %d\n", __PRETTY_FUNCTION__, startIndex, endIndex));
5647 #if defined(__AROS__)
5648 ForeachNode(&data->icld_IconList, node)
5649 #else
5650 Foreach_Node(&data->icld_IconList, node);
5651 #endif
5653 IPTR update_entry = (IPTR)NULL;
5655 if ((data->icld_DisplayFlags & ICONLIST_DISP_MODELIST) == ICONLIST_DISP_MODELIST)
5657 if (node->ie_Flags & ICONENTRY_FLAG_VISIBLE)
5659 update_entry = FALSE;
5661 if ((current >= startIndex) && (current <= endIndex))
5663 //Icon is inside our lasso ..
5664 if (!(node->ie_Flags & ICONENTRY_FLAG_LASSO))
5666 /* check if icon was already selected before */
5667 if (node->ie_Flags & ICONENTRY_FLAG_SELECTED)
5669 Remove(&node->ie_SelectionNode);
5670 node->ie_Flags &= ~ICONENTRY_FLAG_SELECTED;
5672 else
5674 AddTail(&data->icld_SelectionList, &node->ie_SelectionNode);
5675 node->ie_Flags |= ICONENTRY_FLAG_SELECTED;
5677 node->ie_Flags |= ICONENTRY_FLAG_LASSO;
5678 update_entry = (IPTR)node;
5681 else if (node->ie_Flags & ICONENTRY_FLAG_LASSO)
5683 //Icon is no longer inside our lasso - revert its selected state
5684 if (node->ie_Flags & ICONENTRY_FLAG_SELECTED)
5686 Remove(&node->ie_SelectionNode);
5687 node->ie_Flags &= ~ICONENTRY_FLAG_SELECTED;
5689 else
5691 AddTail(&data->icld_SelectionList, &node->ie_SelectionNode);
5692 node->ie_Flags |= ICONENTRY_FLAG_SELECTED;
5694 node->ie_Flags &= ~ICONENTRY_FLAG_LASSO;
5695 update_entry = (IPTR)node;
5698 current++;
5701 else
5703 if (node->ie_Flags & ICONENTRY_FLAG_VISIBLE)
5705 iconrect.MinX = node->ie_IconX;
5706 iconrect.MaxX = node->ie_IconX + node->ie_AreaWidth - 1;
5707 iconrect.MinY = node->ie_IconY;
5708 iconrect.MaxY = node->ie_IconY + node->ie_AreaHeight - 1;
5709 if ((data->icld__Option_IconListMode == ICON_LISTMODE_GRID) &&
5710 (node->ie_AreaWidth < data->icld_IconAreaLargestWidth))
5712 iconrect.MinX += ((data->icld_IconAreaLargestWidth - node->ie_AreaWidth)/2);
5713 iconrect.MaxX += ((data->icld_IconAreaLargestWidth - node->ie_AreaWidth)/2);
5716 if ((((new_lasso.MaxX + data->icld_ViewX) >= iconrect.MinX) && ((new_lasso.MinX + data->icld_ViewX) <= iconrect.MaxX)) &&
5717 (((new_lasso.MaxY + data->icld_ViewY) >= iconrect.MinY) && ((new_lasso.MinY + data->icld_ViewY) <= iconrect.MaxY)))
5719 //Icon is inside our lasso ..
5720 if (!(node->ie_Flags & ICONENTRY_FLAG_LASSO))
5722 /* check if icon was already selected before */
5723 if (node->ie_Flags & ICONENTRY_FLAG_SELECTED)
5725 Remove(&node->ie_SelectionNode);
5726 node->ie_Flags &= ~ICONENTRY_FLAG_SELECTED;
5728 else
5730 AddTail(&data->icld_SelectionList, &node->ie_SelectionNode);
5731 node->ie_Flags |= ICONENTRY_FLAG_SELECTED;
5733 node->ie_Flags |= ICONENTRY_FLAG_LASSO;
5734 update_entry = (IPTR)node;
5737 else if (node->ie_Flags & ICONENTRY_FLAG_LASSO)
5739 //Icon is no longer inside our lasso - revert its selected state
5740 if (node->ie_Flags & ICONENTRY_FLAG_SELECTED)
5742 Remove(&node->ie_SelectionNode);
5743 node->ie_Flags &= ~ICONENTRY_FLAG_SELECTED;
5745 else
5747 AddTail(&data->icld_SelectionList, &node->ie_SelectionNode);
5748 node->ie_Flags |= ICONENTRY_FLAG_SELECTED;
5750 node->ie_Flags &= ~ICONENTRY_FLAG_LASSO;
5751 update_entry = (IPTR)node;
5755 if (update_entry)
5757 data->icld_UpdateMode = UPDATE_SINGLEENTRY;
5758 data->update_entry = (struct IconEntry *)update_entry;
5759 MUI_Redraw(obj, MADF_DRAWUPDATE);
5762 /* Draw Lasso frame */
5763 IconList_InvertLassoOutlines(obj, &new_lasso);
5766 return MUI_EventHandlerRC_Eat;
5768 else if (data->mouse_pressed & MIDDLE_BUTTON)
5770 LONG newleft,
5771 newtop;
5773 newleft = data->click_x - mx;
5774 newtop = data->click_y - my;
5776 if (newleft + _mwidth(obj) > data->icld_AreaWidth) newleft = data->icld_AreaWidth - _mwidth(obj);
5777 if (newleft < 0) newleft = 0;
5779 if (newtop + _mheight(obj) > data->icld_AreaHeight) newtop = data->icld_AreaHeight - _mheight(obj);
5780 if (newtop < 0) newtop = 0;
5782 if ((newleft != data->icld_ViewX) || (newtop != data->icld_ViewY))
5784 SetAttrs(obj, MUIA_Virtgroup_Left, newleft,
5785 MUIA_Virtgroup_Top, newtop,
5786 TAG_DONE);
5789 return MUI_EventHandlerRC_Eat;
5792 break;
5796 return 0;
5800 ///MUIM_IconList_NextIcon()
5801 /**************************************************************************
5802 MUIM_IconList_NextIcon
5803 **************************************************************************/
5804 IPTR IconList__MUIM_IconList_NextIcon(struct IClass *CLASS, Object *obj, struct MUIP_IconList_NextIcon *message)
5806 struct IconList_DATA *data = INST_DATA(CLASS, obj);
5807 struct IconEntry *node = NULL;
5808 struct IconList_Entry *ent = NULL;
5809 IPTR node_successor = (IPTR)NULL;
5811 if (message->entry == NULL) return (IPTR)NULL;
5812 ent = *message->entry;
5814 #if defined(DEBUG_ILC_FUNCS)
5815 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
5816 #endif
5818 if ((IPTR)ent == (IPTR)MUIV_IconList_NextIcon_Start)
5820 D(bug("[IconList] %s: Finding First Entry ..\n", __PRETTY_FUNCTION__));
5821 if (message->nextflag == MUIV_IconList_NextIcon_Selected)
5823 node = (struct IconEntry *)GetHead(&data->icld_SelectionList);
5824 if (node != NULL)
5826 node = (struct IconEntry *)((IPTR)node - ((IPTR)&node->ie_SelectionNode - (IPTR)node));
5829 else if (message->nextflag == MUIV_IconList_NextIcon_Visible)
5831 node = (struct IconEntry *)GetHead(&data->icld_IconList);
5832 while (node != NULL)
5834 if (node->ie_Flags & ICONENTRY_FLAG_VISIBLE)
5835 break;
5837 node = (struct IconEntry *)GetSucc(&node->ie_IconNode);
5841 else if ((IPTR)ent != (IPTR)MUIV_IconList_NextIcon_End)
5843 node = (struct IconEntry *)((IPTR)ent - ((IPTR)&node->ie_IconListEntry - (IPTR)node));
5844 if (message->nextflag == MUIV_IconList_NextIcon_Selected)
5846 node_successor = (IPTR)GetSucc(&node->ie_SelectionNode);
5847 if (node_successor != (IPTR)NULL)
5848 node = (struct IconEntry *)((IPTR)node_successor - ((IPTR)&node->ie_SelectionNode - (IPTR)node));
5849 else
5851 D(bug("[IconList] %s: GetSucc() == NULL\n", __PRETTY_FUNCTION__));
5852 node = NULL;
5855 else if (message->nextflag == MUIV_IconList_NextIcon_Visible)
5857 node = (struct IconEntry *)GetSucc(&node->ie_IconNode);
5858 while (node != NULL)
5860 if (node->ie_Flags & ICONENTRY_FLAG_VISIBLE)
5861 break;
5863 node = (struct IconEntry *)GetSucc(&node->ie_IconNode);
5868 if (node == NULL)
5870 D(bug("[IconList] %s: Returning MUIV_IconList_NextIcon_End\n", __PRETTY_FUNCTION__));
5872 *message->entry = (struct IconList_Entry *)MUIV_IconList_NextIcon_End;
5874 else
5876 D(bug("[IconList] %s: Returning entry for '%s'\n", __PRETTY_FUNCTION__, node->ie_IconListEntry.label));
5878 *message->entry = &node->ie_IconListEntry;
5881 return (IPTR)NULL;
5885 ///MUIM_IconList_GetIconPrivate()
5886 /**************************************************************************
5887 MUIM_IconList_GetIconPrivate
5888 **************************************************************************/
5889 IPTR IconList__MUIM_IconList_GetIconPrivate(struct IClass *CLASS, Object *obj, struct MUIP_IconList_GetIconPrivate *message)
5891 // struct IconList_DATA *data = INST_DATA(CLASS, obj);
5892 struct IconEntry *node = NULL;
5894 if (message->entry == NULL) return (IPTR)NULL;
5896 node = (struct IconEntry *)((IPTR)message->entry - ((IPTR)&node->ie_IconListEntry - (IPTR)node));
5898 return (IPTR)node;
5901 ///MUIM_CreateDragImage()
5902 /**************************************************************************
5903 MUIM_CreateDragImage
5904 **************************************************************************/
5905 IPTR IconList__MUIM_CreateDragImage(struct IClass *CLASS, Object *obj, struct MUIP_CreateDragImage *message)
5907 struct IconList_DATA *data = INST_DATA(CLASS, obj);
5908 struct MUI_DragImage *img = NULL;
5909 LONG first_x = -1,
5910 first_y = -1;
5912 #if defined(DEBUG_ILC_FUNCS)
5913 (bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
5914 #endif
5916 if (!(data->icld_SelectionLastClicked))
5917 DoSuperMethodA(CLASS, obj, (Msg)message);
5919 if ((img = (struct MUI_DragImage *)AllocVec(sizeof(struct MUIP_CreateDragImage), MEMF_CLEAR)))
5921 struct Node *node = NULL;
5922 struct IconEntry *entry = NULL;
5924 LONG depth = GetBitMapAttr(_screen(obj)->RastPort.BitMap, BMA_DEPTH);
5926 #if defined(CREATE_FULL_DRAGIMAGE)
5927 #if defined(__AROS__)
5928 ForeachNode(&data->icld_SelectionList, node)
5929 #else
5930 Foreach_Node(&data->icld_SelectionList, node);
5931 #endif
5933 entry = (struct IconEntry *)((IPTR)node - ((IPTR)&entry->ie_SelectionNode - (IPTR)entry));
5934 if ((entry->ie_Flags & ICONENTRY_FLAG_VISIBLE) && (entry->ie_Flags & ICONENTRY_FLAG_SELECTED))
5936 if ((data->icld_DisplayFlags & ICONLIST_DISP_MODELIST) != ICONLIST_DISP_MODELIST)
5938 if ((first_x == -1) || ((first_x != -1) && (entry->ie_IconX < first_x))) first_x = entry->ie_IconX;
5939 if ((first_y == -1) || ((first_y != -1) && (entry->ie_IconY < first_y))) first_y = entry->ie_IconY;
5940 if ((entry->ie_IconX + entry->ie_IconWidth) > img->width) img->width = entry->ie_IconX + entry->ie_IconWidth;
5941 if ((entry->ie_IconY + entry->ie_IconHeight) > img->height) img->height = entry->ie_IconY + entry->ie_IconHeight;
5945 img->width = (img->width - first_x) + 2;
5946 img->height = (img->height - first_y) + 2;
5947 #else
5948 entry = data->icld_SelectionLastClicked;
5949 if ((data->icld_DisplayFlags & ICONLIST_DISP_MODELIST) == ICONLIST_DISP_MODELIST)
5951 img->width = 10;
5952 img->height = 10;
5953 first_x = 0;
5954 first_y = 0;
5956 else
5958 img->width = entry->ie_IconWidth;
5959 img->height = entry->ie_IconHeight;
5960 first_x = entry->ie_IconX;
5961 first_y = entry->ie_IconY;
5963 #endif
5965 img->touchx = data->click_x - first_x;
5966 img->touchy = data->click_y - first_y;
5968 if ((img->bm = AllocBitMap(img->width, img->height, depth, BMF_CLEAR, _screen(obj)->RastPort.BitMap)))
5970 struct RastPort temprp;
5971 InitRastPort(&temprp);
5972 temprp.BitMap = img->bm;
5974 #if defined(CREATE_FULL_DRAGIMAGE)
5975 ForeachNode(&data->icld_SelectionList, node)
5977 entry = (struct IconEntry *)((IPTR)node - ((IPTR)&entry->ie_SelectionNode - (IPTR)entry));
5978 if ((entry->ie_Flags & ICONENTRY_FLAG_VISIBLE) && (entry->ie_Flags & ICONENTRY_FLAG_SELECTED))
5980 if ((data->icld_DisplayFlags & ICONLIST_DISP_MODELIST) == ICONLIST_DISP_MODELIST)
5983 else
5985 DrawIconStateA
5987 &temprp, entry->ie_DiskObj, NULL,
5988 (entry->ie_IconX + 1) - first_x, (entry->ie_IconY + 1) - first_y,
5989 IDS_SELECTED,
5990 __iconList_DrawIconStateTags
5995 #else
5996 if ((data->icld_DisplayFlags & ICONLIST_DISP_MODELIST) == ICONLIST_DISP_MODELIST)
5999 else
6001 DrawIconStateA
6003 &temprp, entry->ie_DiskObj, NULL,
6004 0, 0,
6005 IDS_SELECTED,
6006 __iconList_DrawIconStateTags
6009 #endif
6010 RastPortSetAlpha(&temprp, data->click_x, data->click_y, img->width, img->height, 0x80, RPALPHAFLAT);
6011 DeinitRastPort(&temprp);
6014 img->touchx = message->touchx;
6015 img->touchy = message->touchy;
6016 img->flags = 0;
6017 #if defined(__MORPHOS__)
6018 img->dragmode = DD_TRANSPARENT;
6019 #endif
6021 return (IPTR)img;
6025 ///MUIM_DeleteDragImage()
6026 /**************************************************************************
6027 MUIM_DeleteDragImage
6028 **************************************************************************/
6029 IPTR IconList__MUIM_DeleteDragImage(struct IClass *CLASS, Object *obj, struct MUIP_DeleteDragImage *message)
6031 struct IconList_DATA *data = INST_DATA(CLASS, obj);
6033 #if defined(DEBUG_ILC_FUNCS)
6034 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
6035 #endif
6037 if (!(data->icld_SelectionLastClicked)) return DoSuperMethodA(CLASS,obj,(Msg)message);
6039 if (message->di)
6041 if (message->di->bm)
6042 FreeBitMap(message->di->bm);
6043 FreeVec(message->di);
6045 return (IPTR)NULL;
6049 ///MUIM_DragQuery()
6050 /**************************************************************************
6051 MUIM_DragQuery
6052 **************************************************************************/
6053 IPTR IconList__MUIM_DragQuery(struct IClass *CLASS, Object *obj, struct MUIP_DragQuery *message)
6055 #if defined(DEBUG_ILC_FUNCS)
6056 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
6057 #endif
6058 if (message->obj == obj)
6059 return MUIV_DragQuery_Accept;
6060 else
6062 BOOL is_iconlist = FALSE;
6063 struct IClass *msg_cl = OCLASS(message->obj);
6065 while (msg_cl)
6067 if (msg_cl == CLASS)
6069 is_iconlist = TRUE;
6070 break;
6072 msg_cl = msg_cl->cl_Super;
6074 if (is_iconlist)
6075 return MUIV_DragQuery_Accept;
6078 return MUIV_DragQuery_Refuse;
6082 ///MUIM_DragDrop()
6083 /**************************************************************************
6084 MUIM_DragDrop
6085 **************************************************************************/
6086 IPTR IconList__MUIM_DragDrop(struct IClass *CLASS, Object *obj, struct MUIP_DragDrop *message)
6088 struct IconList_DATA *data = INST_DATA(CLASS, obj);
6090 #if defined(DEBUG_ILC_FUNCS)
6091 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
6092 #endif
6094 struct IconList_Entry *entry = (IPTR)MUIV_IconList_NextIcon_Start;
6096 if (data->icld_DragDropEvent)
6098 struct IconList_Drop_SourceEntry *clean_node;
6099 #if defined(DEBUG_ILC_ICONDRAGDROP)
6100 D(bug("[IconList] %s: Cleaning existing IconList_Drop_Event @ %p\n", __PRETTY_FUNCTION__, data->icld_DragDropEvent));
6101 #endif
6102 while ((clean_node = (struct IconList_Drop_SourceEntry *)RemTail(&data->icld_DragDropEvent->drop_SourceList)) != NULL)
6104 FreeVec(clean_node->dropse_Node.ln_Name);
6105 FreeMem(clean_node, sizeof(struct IconList_Drop_SourceEntry));
6107 if (data->icld_DragDropEvent->drop_TargetPath) FreeVec(data->icld_DragDropEvent->drop_TargetPath);
6108 FreeMem(data->icld_DragDropEvent, sizeof(struct IconList_Drop_Event));
6109 data->icld_DragDropEvent = NULL;
6112 /* SANITY CHECK: Get first selected entry from SOURCE iconlist */
6113 DoMethod(message->obj, MUIM_IconList_NextIcon, MUIV_IconList_NextIcon_Selected, (IPTR)&entry);
6115 if ((entry) && (entry != (IPTR)MUIV_IconList_NextIcon_End))
6117 /* Ok.. atleast one icon was dropped .. */
6118 char tmp_dirbuff[256];
6119 BPTR tmp_dirlock = (BPTR) NULL;
6121 BOOL iconMove = FALSE;
6122 struct IconEntry *node = NULL;
6123 struct IconEntry *drop_target_node = NULL;
6124 STRPTR directory_path = NULL;
6125 struct IconList_Drop_Event *dragDropEvent = NULL;
6127 GET(obj, MUIA_IconDrawerList_Drawer, &directory_path);
6129 /* Properly expand the name incase it uses devices rather than volumes */
6130 if (directory_path != NULL)
6132 tmp_dirlock = Lock(directory_path, SHARED_LOCK);
6133 if (tmp_dirlock)
6135 if (NameFromLock(tmp_dirlock, tmp_dirbuff, 256) != 0)
6137 directory_path = tmp_dirbuff;
6139 UnLock(tmp_dirlock);
6142 if ((dragDropEvent = AllocMem(sizeof(struct IconList_Drop_Event), MEMF_CLEAR)) == NULL)
6144 #if defined(DEBUG_ILC_ICONDRAGDROP)
6145 D(bug("[IconList] %s: Failed to allocate IconList_Drop_Event Storage!\n", __PRETTY_FUNCTION__));
6146 #endif
6147 goto dragdropdone;
6149 D(bug("[IconList] %s: Allocated IconList_Drop_Event @ %p\n", __PRETTY_FUNCTION__, dragDropEvent));
6151 NewList(&dragDropEvent->drop_SourceList);
6153 /* go through list and check if dropped on icon */
6154 #if defined(__AROS__)
6155 ForeachNode(&data->icld_IconList, node)
6156 #else
6157 Foreach_Node(&data->icld_IconList, node);
6158 #endif
6160 struct Rectangle iconbox;
6161 LONG click_x = message->x - _mleft(obj);
6162 LONG click_y = message->y - _mtop(obj);
6163 iconbox.MinX = node->ie_IconX - data->icld_ViewX;
6164 iconbox.MaxX = (node->ie_IconX + node->ie_AreaWidth) - data->icld_ViewX;
6165 iconbox.MinY = node->ie_IconY - data->icld_ViewY;
6166 iconbox.MaxY = (node->ie_IconY + node->ie_AreaHeight)- data->icld_ViewY;
6168 if ((node->ie_Flags & ICONENTRY_FLAG_VISIBLE) &&
6169 (click_x >= iconbox.MinX) &&
6170 (click_x < iconbox.MaxX) &&
6171 (click_y >= iconbox.MinY) &&
6172 (click_y < iconbox.MaxY))
6174 drop_target_node = node;
6175 break;
6179 if ((drop_target_node != NULL) &&
6180 ((drop_target_node->ie_IconListEntry.type == ST_SOFTLINK) ||
6181 (drop_target_node->ie_IconListEntry.type == ST_ROOT) ||
6182 (drop_target_node->ie_IconListEntry.type == ST_USERDIR) ||
6183 (drop_target_node->ie_IconListEntry.type == ST_LINKDIR) ||
6184 (drop_target_node->ie_IconListEntry.type == ST_FILE) ||
6185 (drop_target_node->ie_IconListEntry.type == ST_LINKFILE)))
6187 if ((drop_target_node->ie_IconListEntry.type != ST_ROOT) && (drop_target_node->ie_IconListEntry.type != ST_SOFTLINK))
6189 if (directory_path)
6191 int fulllen = strlen(directory_path) + strlen(drop_target_node->ie_IconListEntry.label) + 2;
6193 if ((dragDropEvent->drop_TargetPath = AllocVec(fulllen, MEMF_CLEAR)) == NULL)
6195 bug("[IconList] %s: Failed to allocate IconList_Drop_Event->drop_TargetPath Storage!\n", __PRETTY_FUNCTION__);
6196 goto dragdropdone;
6198 strcpy(dragDropEvent->drop_TargetPath, directory_path);
6199 AddPart(dragDropEvent->drop_TargetPath, drop_target_node->ie_IconListEntry.label, fulllen);
6202 else
6204 if ((dragDropEvent->drop_TargetPath = AllocVec(strlen(drop_target_node->ie_IconListEntry.label) + 1, MEMF_CLEAR)) == NULL)
6206 bug("[IconList] %s: Failed to allocate IconList_Drop_Event->drop_TargetPath Storage!\n", __PRETTY_FUNCTION__);
6207 goto dragdropdone;
6209 strcpy(dragDropEvent->drop_TargetPath, drop_target_node->ie_IconListEntry.label);
6212 #if defined(DEBUG_ILC_ICONDRAGDROP)
6213 D(bug("[IconList] %s: Target Icon Full Path = '%s'\n", __PRETTY_FUNCTION__, dragDropEvent->drop_TargetPath));
6214 #endif
6215 /* mark the Icon the selection was dropped on*/
6216 //drop_target_node->ie_Flags |= ICONENTRY_FLAG_SELECTED;
6217 //data->icld_UpdateMode = UPDATE_SINGLEENTRY;
6218 //data->update_entry = drop_target_node;
6219 //MUI_Redraw(obj,MADF_DRAWUPDATE);
6221 else
6223 /* not dropped on icon -> get path of DESTINATION iconlist */
6224 /* Note: directory_path is NULL when dropped on Wanderer's desktop */
6225 if ((message->obj != obj) && directory_path)
6227 #if defined(DEBUG_ILC_ICONDRAGDROP)
6228 D(bug("[IconList] %s: drop entry: Icons dropped in window '%s'\n", __PRETTY_FUNCTION__, directory_path));
6229 #endif
6230 /* copy path */
6231 if ((dragDropEvent->drop_TargetPath = AllocVec(strlen(directory_path) + 1, MEMF_CLEAR)) != NULL)
6233 strcpy(dragDropEvent->drop_TargetPath, directory_path);
6235 else
6237 #if defined(DEBUG_ILC_ICONDRAGDROP)
6238 D(bug("[IconList] %s: Failed to allocate IconList_Drop_Event->drop_TargetPath Storage!\n", __PRETTY_FUNCTION__));
6239 #endif
6240 goto dragdropdone;
6243 else if (message->obj == obj)
6245 #if defined(DEBUG_ILC_ICONDRAGDROP)
6246 D(bug("[IconList] %s: drop entry: Icon Move detected ..\n", __PRETTY_FUNCTION__));
6247 #endif
6248 iconMove = TRUE;
6249 SET(obj, MUIA_IconList_IconsMoved, (IPTR)entry); // Now notify
6250 MUI_Redraw(obj,MADF_DRAWOBJECT);
6251 DoMethod(obj, MUIM_IconList_CoordsSort);
6253 else
6255 #if defined(DEBUG_ILC_ICONDRAGDROP)
6256 D(bug("[IconList] %s: Icons Dropped on Wanderer Desktop (unhandled)!\n", __PRETTY_FUNCTION__));
6257 #endif
6258 iconMove = TRUE;
6261 if (!(iconMove))
6263 int copycount = 0;
6264 /* Create list of entries to copy .. */
6265 entry = (IPTR)MUIV_IconList_NextIcon_Start;
6266 while (entry != (IPTR)MUIV_IconList_NextIcon_End)
6268 DoMethod(message->obj, MUIM_IconList_NextIcon, MUIV_IconList_NextIcon_Selected, (IPTR)&entry);
6270 if (entry != (IPTR)MUIV_IconList_NextIcon_End)
6272 struct IconList_Drop_SourceEntry *sourceEntry = NULL;
6273 sourceEntry = AllocMem(sizeof(struct IconList_Drop_SourceEntry), MEMF_CLEAR);
6274 if ((entry->type != ST_ROOT) && (entry->type != ST_SOFTLINK))
6276 int fulllen = 0;
6277 char *path = NULL;
6279 GET(message->obj, MUIA_IconDrawerList_Drawer, &path);
6280 /* Properly expand the location incase it uses devices rather than volumes */
6281 if (path != NULL)
6283 tmp_dirlock = Lock(path, SHARED_LOCK);
6284 if (tmp_dirlock)
6286 if (NameFromLock(tmp_dirlock, tmp_dirbuff, 256))
6288 path = tmp_dirbuff;
6290 UnLock(tmp_dirlock);
6293 if (strcasecmp(dragDropEvent->drop_TargetPath, path) != 0)
6295 fulllen = strlen(path) + strlen(entry->ile_IconEntry->ie_IconNode.ln_Name) + 2;
6296 sourceEntry->dropse_Node.ln_Name = AllocVec(fulllen, MEMF_CLEAR);
6297 strcpy(sourceEntry->dropse_Node.ln_Name, path);
6298 AddPart(sourceEntry->dropse_Node.ln_Name, entry->label, fulllen);
6299 #if defined(DEBUG_ILC_ICONDRAGDROP)
6300 D(bug("[IconList] %s: Source Icon (Full Path) = '%s'\n", __PRETTY_FUNCTION__, sourceEntry->dropse_Node.ln_Name));
6301 #endif
6305 else
6307 sourceEntry->dropse_Node.ln_Name = AllocVec(strlen(entry->label) + 1, MEMF_CLEAR);
6308 strcpy(sourceEntry->dropse_Node.ln_Name, entry->label);
6309 #if defined(DEBUG_ILC_ICONDRAGDROP)
6310 D(bug("[IconList] %s: Source Icon = '%s'\n", __PRETTY_FUNCTION__, sourceEntry->dropse_Node.ln_Name));
6311 #endif
6314 if ((sourceEntry->dropse_Node.ln_Name != NULL) && (strcasecmp(dragDropEvent->drop_TargetPath, sourceEntry->dropse_Node.ln_Name) != 0))
6316 copycount += 1;
6317 AddTail(&dragDropEvent->drop_SourceList, &sourceEntry->dropse_Node);
6319 else
6321 #if defined(DEBUG_ILC_ICONDRAGDROP)
6322 D(bug("[IconList] %s: Source == Dest, Skipping!\n", __PRETTY_FUNCTION__));
6323 #endif
6324 if ( sourceEntry->dropse_Node.ln_Name) FreeVec(sourceEntry->dropse_Node.ln_Name);
6325 FreeMem(sourceEntry, sizeof(struct IconList_Drop_SourceEntry));
6329 if (copycount > 0)
6331 dragDropEvent->drop_TargetObj = (IPTR)obj;
6333 #if defined(DEBUG_ILC_ICONDRAGDROP)
6334 D(bug("[IconList] %s: Causing DROP notification..\n", __PRETTY_FUNCTION__));
6335 #endif
6336 SET(obj, MUIA_IconList_IconsDropped, (IPTR)dragDropEvent);
6337 DoMethod(obj, MUIM_IconList_CoordsSort);
6339 else
6341 if (dragDropEvent->drop_TargetPath) FreeVec(dragDropEvent->drop_TargetPath);
6342 FreeMem(dragDropEvent, sizeof(struct IconList_Drop_Event));
6346 else
6348 #if defined(DEBUG_ILC_ICONDRAGDROP)
6349 D(bug("[IconList] %s: BUG - DragDrop recieved with no source icons!\n", __PRETTY_FUNCTION__));
6350 #endif
6351 NNSET(obj, MUIA_IconList_IconsDropped, (IPTR)NULL);
6354 dragdropdone:
6355 return DoSuperMethodA(CLASS, obj, (Msg)message);
6359 ///MUIM_UnselectAll()
6360 /**************************************************************************
6361 MUIM_UnselectAll
6362 **************************************************************************/
6363 IPTR IconList__MUIM_IconList_UnselectAll(struct IClass *CLASS, Object *obj, Msg message)
6365 struct IconList_DATA *data = INST_DATA(CLASS, obj);
6366 struct Node *node = NULL, *next_node = NULL;
6367 BOOL changed = FALSE;
6369 #if defined(DEBUG_ILC_FUNCS)
6370 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
6371 #endif
6373 data->icld_SelectionLastClicked = NULL;
6374 data->icld_FocusIcon = NULL;
6375 #if defined(__AROS__)
6376 ForeachNodeSafe(&data->icld_SelectionList, node, next_node)
6377 #else
6378 Foreach_NodeSafe(&data->icld_SelectionList, node, next_node);
6379 #endif
6381 struct IconEntry *entry = (struct IconEntry *)((IPTR)node - ((IPTR)&entry->ie_SelectionNode - (IPTR)entry));
6382 BOOL update_entry = FALSE;
6384 if (entry->ie_Flags & ICONENTRY_FLAG_VISIBLE)
6386 if (entry->ie_Flags & ICONENTRY_FLAG_SELECTED)
6388 Remove(node);
6389 entry->ie_Flags &= ~ICONENTRY_FLAG_SELECTED;
6390 update_entry = TRUE;
6392 if (entry->ie_Flags & ICONENTRY_FLAG_FOCUS)
6394 entry->ie_Flags &= ~ICONENTRY_FLAG_FOCUS;
6395 update_entry = TRUE;
6399 if (update_entry)
6401 changed = TRUE;
6402 data->icld_UpdateMode = UPDATE_SINGLEENTRY;
6403 data->update_entry = entry;
6404 MUI_Redraw(obj, MADF_DRAWUPDATE);
6408 if (changed)
6409 SET(obj, MUIA_IconList_SelectionChanged, TRUE);
6411 return 1;
6415 ///MUIM_SelectAll()
6416 /**************************************************************************
6417 MUIM_SelectAll
6418 **************************************************************************/
6419 IPTR IconList__MUIM_IconList_SelectAll(struct IClass *CLASS, Object *obj, Msg message)
6421 struct IconList_DATA *data = INST_DATA(CLASS, obj);
6422 struct IconEntry *node = NULL;
6423 BOOL changed = FALSE;
6425 #if defined(DEBUG_ILC_FUNCS)
6426 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
6427 #endif
6429 node = (struct IconEntry *)GetHead(&data->icld_IconList);
6431 while (node != NULL)
6433 if (node->ie_Flags & ICONENTRY_FLAG_VISIBLE)
6435 BOOL update_entry = FALSE;
6437 if (!(node->ie_Flags & ICONENTRY_FLAG_SELECTED))
6439 AddTail(&data->icld_SelectionList, &node->ie_SelectionNode);
6440 node->ie_Flags |= ICONENTRY_FLAG_SELECTED;
6441 update_entry = TRUE;
6443 data->icld_SelectionLastClicked = node;
6445 else if (node->ie_Flags & ICONENTRY_FLAG_FOCUS)
6447 node->ie_Flags &= ~ICONENTRY_FLAG_FOCUS;
6448 update_entry = TRUE;
6451 if (update_entry)
6453 changed = TRUE;
6454 data->icld_UpdateMode = UPDATE_SINGLEENTRY;
6455 data->update_entry = node;
6456 MUI_Redraw(obj, MADF_DRAWUPDATE);
6459 node = (struct IconEntry *)GetSucc(&node->ie_IconNode);
6462 if ((data->icld_SelectionLastClicked) && (data->icld_SelectionLastClicked != data->icld_FocusIcon))
6464 data->icld_FocusIcon = data->icld_SelectionLastClicked;
6465 if (!(data->icld_FocusIcon->ie_Flags & ICONENTRY_FLAG_FOCUS))
6467 data->icld_FocusIcon->ie_Flags &= ~ICONENTRY_FLAG_FOCUS;
6468 data->icld_FocusIcon->ie_Flags |= ICONENTRY_FLAG_FOCUS;
6469 data->icld_UpdateMode = UPDATE_SINGLEENTRY;
6470 data->update_entry = data->icld_FocusIcon;
6471 MUI_Redraw(obj, MADF_DRAWUPDATE);
6475 if (changed)
6476 SET(obj, MUIA_IconList_SelectionChanged, TRUE);
6478 return 1;
6482 ///IconList__MUIM_IconList_CoordsSort()
6483 IPTR IconList__MUIM_IconList_CoordsSort(struct IClass *CLASS, Object *obj, struct MUIP_IconList_Sort *message)
6485 struct IconList_DATA *data = INST_DATA(CLASS, obj);
6487 struct IconEntry *entry = NULL,
6488 *test_icon = NULL;
6490 struct List list_VisibleIcons;
6491 struct List list_HiddenIcons;
6494 perform a quick sort of the iconlist based on icon coords
6495 this method DOESNT cause any visual output.
6497 #if defined(DEBUG_ILC_FUNCS) && defined(DEBUG_ILC_ICONSORTING)
6498 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
6499 #endif
6501 NewList((struct List*)&list_VisibleIcons);
6502 NewList((struct List*)&list_HiddenIcons);
6504 /*move list into our local list struct(s)*/
6505 while ((entry = (struct IconEntry *)RemTail((struct List*)&data->icld_IconList)))
6507 if (entry->ie_Flags & ICONENTRY_FLAG_VISIBLE)
6508 AddHead((struct List*)&list_VisibleIcons, (struct Node *)&entry->ie_IconNode);
6509 else
6510 AddHead((struct List*)&list_HiddenIcons, (struct Node *)&entry->ie_IconNode);
6513 while ((entry = (struct IconEntry *)RemTail((struct List*)&list_VisibleIcons)))
6515 if ((test_icon = (struct IconEntry *)GetTail(&data->icld_IconList)) != NULL)
6517 while (test_icon != NULL)
6519 if (((data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL) && (test_icon->ie_IconX > entry->ie_IconX)) ||
6520 (!(data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL) && (test_icon->ie_IconY > entry->ie_IconY)))
6522 test_icon = (struct IconEntry *)GetPred(&test_icon->ie_IconNode);
6523 continue;
6525 else break;
6528 while (test_icon != NULL)
6530 if (((data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL) && (test_icon->ie_IconY > entry->ie_IconY)) ||
6531 (!(data->icld_DisplayFlags & ICONLIST_DISP_VERTICAL) && (test_icon->ie_IconX > entry->ie_IconX)))
6533 test_icon = (struct IconEntry *)GetPred(&test_icon->ie_IconNode);
6534 continue;
6536 else break;
6538 Insert((struct List*)&data->icld_IconList, (struct Node *)&entry->ie_IconNode, (struct Node *)&test_icon->ie_IconNode);
6540 else
6541 AddTail((struct List*)&data->icld_IconList, (struct Node *)&entry->ie_IconNode);
6543 #if defined(DEBUG_ILC_ICONSORTING)
6544 D(bug("[IconList] %s: Done\n", __PRETTY_FUNCTION__));
6545 #endif
6547 while ((entry = (struct IconEntry *)RemTail((struct List*)&list_HiddenIcons)))
6549 AddTail((struct List*)&data->icld_IconList, (struct Node *)&entry->ie_IconNode);
6552 #if defined(DEBUG_ILC_ICONSORTING_DUMP)
6553 #if defined(__AROS__)
6554 ForeachNode(&data->icld_IconList, entry)
6555 #else
6556 Foreach_Node(&data->icld_IconList, entry);
6557 #endif
6559 D(bug("[IconList] %s: %d %d '%s'\n", __PRETTY_FUNCTION__, entry->ie_IconX, entry->ie_IconY, entry->ie_IconListEntry.label));
6561 #endif
6563 return TRUE;
6567 ///MUIM_Sort()
6568 /**************************************************************************
6569 MUIM_Sort - sortsort
6570 **************************************************************************/
6571 IPTR IconList__MUIM_IconList_Sort(struct IClass *CLASS, Object *obj, struct MUIP_IconList_Sort *message)
6573 struct IconList_DATA *data = INST_DATA(CLASS, obj);
6574 struct IconEntry *entry = NULL,
6575 *icon1 = NULL,
6576 *icon2 = NULL;
6578 struct List list_VisibleIcons,
6579 list_SortedIcons,
6580 list_HiddenIcons;
6582 BOOL sortme, enqueue = FALSE;
6583 int i, visible_count = 0;
6585 #if defined(DEBUG_ILC_FUNCS) && defined(DEBUG_ILC_ICONSORTING)
6586 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
6587 #endif
6589 /* Reset incase view options have changed .. */
6590 data->icld_IconAreaLargestWidth = 0;
6591 data->icld_IconAreaLargestHeight = 0;
6592 data->icld_IconLargestHeight = 0;
6593 data->icld_LabelLargestHeight = 0;
6595 if ((data->icld_SortFlags & MUIV_IconList_Sort_MASK) != 0)
6597 #if defined(DEBUG_ILC_ICONSORTING)
6598 D(bug("[IconList] %s: Sorting (Flags %x)\n", __PRETTY_FUNCTION__, (data->icld_SortFlags & MUIV_IconList_Sort_MASK)));
6599 #endif
6600 NewList((struct List*)&list_VisibleIcons);
6601 NewList((struct List*)&list_SortedIcons);
6602 NewList((struct List*)&list_HiddenIcons);
6604 /*move list into our local list struct(s)*/
6605 while ((entry = (struct IconEntry *)RemTail((struct List*)&data->icld_IconList)))
6607 if (entry->ie_DiskObj)
6609 if (entry->ie_IconX != entry->ie_DiskObj->do_CurrentX)
6611 entry->ie_IconX = entry->ie_DiskObj->do_CurrentX;
6612 if ((data->icld_SortFlags & MUIV_IconList_Sort_MASK) == 0)
6613 entry->ie_Flags |= ICONENTRY_FLAG_NEEDSUPDATE;
6615 if (entry->ie_IconY != entry->ie_DiskObj->do_CurrentY)
6617 entry->ie_IconY = entry->ie_DiskObj->do_CurrentY;
6618 if ((data->icld_SortFlags & MUIV_IconList_Sort_MASK) == 0)
6619 entry->ie_Flags |= ICONENTRY_FLAG_NEEDSUPDATE;
6623 if (!(entry->ie_Flags & ICONENTRY_FLAG_HASICON))
6625 if (data->icld_DisplayFlags & ICONLIST_DISP_SHOWINFO)
6627 if (entry->ie_Flags & ICONENTRY_FLAG_VISIBLE)
6629 entry->ie_Flags &= ~(ICONENTRY_FLAG_VISIBLE|ICONENTRY_FLAG_NEEDSUPDATE);
6632 else if (!(entry->ie_Flags & ICONENTRY_FLAG_VISIBLE))
6634 entry->ie_Flags |= (ICONENTRY_FLAG_VISIBLE|ICONENTRY_FLAG_NEEDSUPDATE);
6637 else
6639 if (!(entry->ie_Flags & ICONENTRY_FLAG_VISIBLE))
6641 entry->ie_Flags |= (ICONENTRY_FLAG_VISIBLE|ICONENTRY_FLAG_NEEDSUPDATE);
6645 /* Now we have fixed visibility lets dump them into the correct list for sorting */
6646 if (entry->ie_Flags & ICONENTRY_FLAG_VISIBLE)
6648 if(entry->ie_AreaWidth > data->icld_IconAreaLargestWidth) data->icld_IconAreaLargestWidth = entry->ie_AreaWidth;
6649 if(entry->ie_AreaHeight > data->icld_IconAreaLargestHeight) data->icld_IconAreaLargestHeight = entry->ie_AreaHeight;
6650 if(entry->ie_IconHeight > data->icld_IconLargestHeight) data->icld_IconLargestHeight = entry->ie_IconHeight;
6651 if((entry->ie_AreaHeight - entry->ie_IconHeight) > data->icld_LabelLargestHeight) data->icld_LabelLargestHeight = entry->ie_AreaHeight - entry->ie_IconHeight;
6653 if (((data->icld_SortFlags & MUIV_IconList_Sort_MASK) == 0) && (entry->ie_IconX == NO_ICON_POSITION))
6654 AddTail((struct List*)&list_VisibleIcons, (struct Node *)&entry->ie_IconNode);
6655 else
6656 AddHead((struct List*)&list_VisibleIcons, (struct Node *)&entry->ie_IconNode);
6657 visible_count++;
6659 else
6661 if (entry->ie_Flags & ICONENTRY_FLAG_SELECTED)
6663 Remove(&entry->ie_SelectionNode);
6665 entry->ie_Flags &= ~(ICONENTRY_FLAG_SELECTED|ICONENTRY_FLAG_FOCUS);
6666 if (data->icld_SelectionLastClicked == entry) data->icld_SelectionLastClicked = NULL;
6667 if (data->icld_FocusIcon == entry) data->icld_FocusIcon = data->icld_SelectionLastClicked;
6668 AddHead((struct List*)&list_HiddenIcons, (struct Node *)&entry->ie_IconNode);
6672 /* Copy each visible icon entry back to the main list, sorting as we go*/
6674 while ((entry = (struct IconEntry *)RemHead((struct List*)&list_VisibleIcons)))
6676 icon1 = (struct IconEntry *)GetHead(&list_SortedIcons);
6677 icon2 = NULL;
6679 sortme = FALSE;
6681 if (visible_count > 1)
6683 // D(bug(" - %s %s %s %i\n",entry->ie_IconListEntry.label,entry->ie_TxtBuf_DATE,entry->ie_TxtBuf_TIME,entry->ie_FileInfoBlock->fib_Size));
6685 while (icon1)
6687 if(((icon1->ie_IconListEntry.type == ST_ROOT) || (icon1->ie_IconListEntry.type == ST_LINKDIR) || (icon1->ie_IconListEntry.type == ST_LINKFILE))
6688 || (data->icld_SortFlags & MUIV_IconList_Sort_DrawersMixed))
6690 /*volume list or drawers mixed*/
6691 sortme = TRUE;
6693 else
6695 /*drawers first*/
6696 if ((icon1->ie_IconListEntry.type == ST_USERDIR) && (entry->ie_IconListEntry.type == ST_USERDIR))
6698 sortme = TRUE;
6700 else
6702 if ((icon1->ie_IconListEntry.type != ST_USERDIR) && (entry->ie_IconListEntry.type != ST_USERDIR))
6703 sortme = TRUE;
6704 else
6706 /* we are the first drawer to arrive or we need to insert ourselves
6707 due to being sorted to the end of the drawers*/
6709 if ((!icon2 || icon2->ie_IconListEntry.type == ST_USERDIR) &&
6710 (entry->ie_IconListEntry.type == ST_USERDIR) &&
6711 (icon1->ie_IconListEntry.type != ST_USERDIR))
6713 // D(bug("force %s\n",entry->ie_IconListEntry.label));
6714 break;
6720 if (sortme)
6722 i = 0;
6724 if ((data->icld_SortFlags & MUIV_IconList_Sort_MASK) == MUIV_IconList_Sort_ByDate)
6726 /* Sort by Date */
6727 i = CompareDates((const struct DateStamp *)&entry->ie_FileInfoBlock->fib_Date,(const struct DateStamp *)&icon1->ie_FileInfoBlock->fib_Date);
6729 else if ((data->icld_SortFlags & MUIV_IconList_Sort_MASK) == MUIV_IconList_Sort_BySize)
6731 /* Sort by Size .. */
6732 i = entry->ie_FileInfoBlock->fib_Size - icon1->ie_FileInfoBlock->fib_Size;
6734 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)))
6736 /* Sort by Type .. */
6737 #warning "TODO: Sort icons based on type using datatypes"
6739 else
6741 if (
6742 ((data->icld_SortFlags & MUIV_IconList_Sort_MASK) == MUIV_IconList_Sort_MASK) ||
6743 ((data->icld_SortFlags & MUIV_IconList_Sort_MASK) == MUIV_IconList_Sort_ByName) ||
6744 (entry->ie_IconX == NO_ICON_POSITION)
6747 /* Sort by Name .. */
6748 i = Stricmp(entry->ie_IconListEntry.label, icon1->ie_IconListEntry.label);
6749 if ((data->icld_SortFlags & MUIV_IconList_Sort_MASK) == MUIV_IconList_Sort_MASK)
6750 enqueue = TRUE;
6752 else
6754 /* coord sort */
6755 #warning "TODO: Implement default coord sorting.."
6759 if (data->icld_SortFlags & MUIV_IconList_Sort_Reverse)
6761 if (i > 0)
6762 break;
6764 else if (i < 0)
6765 break;
6767 icon2 = icon1;
6768 icon1 = (struct IconEntry *)GetSucc(&icon1->ie_IconNode);
6771 Insert((struct List*)&list_SortedIcons, (struct Node *)&entry->ie_IconNode, (struct Node *)&icon2->ie_IconNode);
6773 if (enqueue)
6775 /* Quickly resort based on node priorities .. */
6776 while ((entry = (struct IconEntry *)RemHead((struct List*)&list_SortedIcons)))
6778 Enqueue((struct List*)&data->icld_IconList, (struct Node *)&entry->ie_IconNode);
6781 else
6783 while ((entry = (struct IconEntry *)RemHead((struct List*)&list_SortedIcons)))
6785 AddTail((struct List*)&data->icld_IconList, (struct Node *)&entry->ie_IconNode);
6789 else
6791 #if defined(DEBUG_ILC_ICONSORTING)
6792 D(bug("[IconList] %s: Coord Sorting\n", __PRETTY_FUNCTION__));
6793 #endif
6794 DoMethod(obj, MUIM_IconList_CoordsSort);
6797 DoMethod(obj, MUIM_IconList_PositionIcons);
6798 MUI_Redraw(obj, MADF_DRAWOBJECT);
6800 if ((data->icld_SortFlags & MUIV_IconList_Sort_MASK) != 0)
6802 DoMethod(obj, MUIM_IconList_CoordsSort);
6804 /* leave hidden icons on a seperate list to speed up normal list parsing ? */
6805 while ((entry = (struct IconEntry *)RemHead((struct List*)&list_HiddenIcons)))
6807 AddTail((struct List*)&data->icld_IconList, (struct Node *)&entry->ie_IconNode);
6810 SET(obj, MUIA_IconList_Changed, TRUE);
6812 return 1;
6816 ///MUIM_DragReport()
6817 /**************************************************************************
6818 MUIM_DragReport. Since MUI doesn't change the drop object if the dragged
6819 object is moved above another window (while still in the bounds of the
6820 orginal drop object) we must do it here manually to be compatible with
6821 MUI. Maybe Zune should fix this bug somewhen.
6822 **************************************************************************/
6823 IPTR IconList__MUIM_DragReport(struct IClass *CLASS, Object *obj, struct MUIP_DragReport *message)
6825 struct Window *wnd = _window(obj);
6826 struct Layer *l = NULL;
6828 #if defined(DEBUG_ILC_FUNCS)
6829 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
6830 #endif
6832 l = WhichLayer(&wnd->WScreen->LayerInfo, wnd->LeftEdge + message->x, wnd->TopEdge + message->y);
6834 if (l != wnd->WLayer) return MUIV_DragReport_Abort;
6836 return MUIV_DragReport_Continue;
6840 ///MUIM_IconList_UnknownDropDestination()
6841 /**************************************************************************
6842 MUIM_IconList_UnknownDropDestination
6843 **************************************************************************/
6844 IPTR IconList__MUIM_UnknownDropDestination(struct IClass *CLASS, Object *obj, struct MUIP_UnknownDropDestination *message)
6846 #if defined(DEBUG_ILC_FUNCS)
6847 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
6848 #endif
6849 D(bug("[IconList] %s: icons dropped on custom window \n", __PRETTY_FUNCTION__));
6851 SET(obj, MUIA_IconList_AppWindowDrop, (IPTR)message); /* Now notify */
6853 return (IPTR)NULL;
6857 ///MUIM_IconList_MakeIconVisible()
6858 /**************************************************************************
6859 Move the visible area so that the selected icon becomes visible ..
6860 **************************************************************************/
6861 IPTR IconList__MUIM_IconList_MakeIconVisible(struct IClass *CLASS, Object *obj, struct MUIP_IconList_MakeIconVisible *message)
6863 struct IconList_DATA *data = INST_DATA(CLASS, obj);
6864 BOOL viewmoved = FALSE;
6865 struct Rectangle iconrect, viewrect;
6867 #if defined(DEBUG_ILC_FUNCS)
6868 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__));
6869 #endif
6871 viewrect.MinX = data->icld_ViewX;
6872 viewrect.MaxX = data->icld_ViewX + data->icld_AreaWidth;
6873 viewrect.MinY = data->icld_ViewY;
6874 viewrect.MaxY = data->icld_ViewY + data->icld_AreaHeight;
6876 IconList_GetIconAreaRectangle(obj, data, message->icon, &iconrect);
6878 if (!(RectAndRect(&viewrect, &iconrect)))
6880 viewmoved = TRUE;
6881 if (message->icon->ie_IconX < data->icld_ViewX)
6882 data->icld_ViewX = message->icon->ie_IconX;
6883 else if (message->icon->ie_IconX > (data->icld_ViewX + data->icld_AreaWidth))
6884 data->icld_ViewX = (message->icon->ie_IconX + message->icon->ie_AreaWidth) - data->icld_AreaWidth;
6886 if (message->icon->ie_IconY < data->icld_ViewY)
6887 data->icld_ViewY = message->icon->ie_IconX;
6888 else if (message->icon->ie_IconY > (data->icld_ViewY + data->icld_AreaHeight))
6889 data->icld_ViewY = (message->icon->ie_IconY + message->icon->ie_AreaHeight) - data->icld_AreaHeight;
6892 if (viewmoved)
6894 D(bug("[IconList]: %s: call SetSuperAttrs()\n", __PRETTY_FUNCTION__));
6895 SetSuperAttrs(CLASS, obj, MUIA_Virtgroup_Left, data->icld_ViewX,
6896 MUIA_Virtgroup_Top, data->icld_ViewY,
6897 TAG_DONE);
6899 D(bug("[IconList]: %s: call SetAttrs()\n", __PRETTY_FUNCTION__));
6900 SetAttrs(obj, MUIA_Virtgroup_Left, data->icld_ViewX,
6901 MUIA_Virtgroup_Top, data->icld_ViewY,
6902 TAG_DONE);
6904 D(bug("[IconList]: %s: call MUI_Redraw()\n", __PRETTY_FUNCTION__));
6905 MUI_Redraw(obj,MADF_DRAWOBJECT);
6907 return 1;
6910 #if defined(WANDERER_BUILTIN_ICONLIST)
6911 BOOPSI_DISPATCHER(IPTR,IconList_Dispatcher, CLASS, obj, message)
6913 #if defined(__AROS__)
6914 switch (message->MethodID)
6915 #else
6916 struct IClass *CLASS = cl;
6917 Msg message = msg;
6919 switch (msg->MethodID)
6920 #endif
6922 case OM_NEW: return IconList__OM_NEW(CLASS, obj, (struct opSet *)message);
6923 case OM_DISPOSE: return IconList__OM_DISPOSE(CLASS, obj, message);
6924 case OM_SET: return IconList__OM_SET(CLASS, obj, (struct opSet *)message);
6925 case OM_GET: return IconList__OM_GET(CLASS, obj, (struct opGet *)message);
6926 case OM_ADDMEMBER:
6927 case MUIM_Family_AddTail: return IconList__MUIM_Family_AddTail(CLASS, obj, (APTR)message);
6928 case MUIM_Family_AddHead: return IconList__MUIM_Family_AddHead(CLASS, obj, (APTR)message);
6929 case OM_REMMEMBER:
6930 case MUIM_Family_Remove: return IconList__MUIM_Family_Remove(CLASS, obj, (APTR)message);
6932 case MUIM_Setup: return IconList__MUIM_Setup(CLASS, obj, (struct MUIP_Setup *)message);
6934 case MUIM_Show: return IconList__MUIM_Show(CLASS,obj, (struct MUIP_Show *)message);
6935 case MUIM_Hide: return IconList__MUIM_Hide(CLASS,obj, (struct MUIP_Hide *)message);
6936 case MUIM_Cleanup: return IconList__MUIM_Cleanup(CLASS, obj, (struct MUIP_Cleanup *)message);
6937 case MUIM_AskMinMax: return IconList__MUIM_AskMinMax(CLASS, obj, (struct MUIP_AskMinMax *)message);
6938 case MUIM_Draw: return IconList__MUIM_Draw(CLASS, obj, (struct MUIP_Draw *)message);
6939 #if defined(__AROS__)
6940 case MUIM_Layout: return IconList__MUIM_Layout(CLASS, obj, (struct MUIP_Layout *)message);
6941 #endif
6942 case MUIM_HandleEvent: return IconList__MUIM_HandleEvent(CLASS, obj, (struct MUIP_HandleEvent *)message);
6943 case MUIM_CreateDragImage: return IconList__MUIM_CreateDragImage(CLASS, obj, (APTR)message);
6944 case MUIM_DeleteDragImage: return IconList__MUIM_DeleteDragImage(CLASS, obj, (APTR)message);
6945 case MUIM_DragQuery: return IconList__MUIM_DragQuery(CLASS, obj, (APTR)message);
6946 case MUIM_DragReport: return IconList__MUIM_DragReport(CLASS, obj, (APTR)message);
6947 case MUIM_DragDrop: return IconList__MUIM_DragDrop(CLASS, obj, (APTR)message);
6948 #if defined(__AROS__)
6949 case MUIM_UnknownDropDestination: return IconList__MUIM_UnknownDropDestination(CLASS, obj, (APTR)message);
6950 #endif
6951 case MUIM_IconList_Update: return IconList__MUIM_IconList_Update(CLASS, obj, (APTR)message);
6952 case MUIM_IconList_Clear: return IconList__MUIM_IconList_Clear(CLASS, obj, (APTR)message);
6953 case MUIM_IconList_RethinkDimensions: return IconList__MUIM_IconList_RethinkDimensions(CLASS, obj, (APTR)message);
6954 case MUIM_IconList_CreateEntry: return IconList__MUIM_IconList_CreateEntry(CLASS, obj, (APTR)message);
6955 case MUIM_IconList_UpdateEntry: return IconList__MUIM_IconList_UpdateEntry(CLASS, obj, (APTR)message);
6956 case MUIM_IconList_DestroyEntry: return IconList__MUIM_IconList_DestroyEntry(CLASS, obj, (APTR)message);
6957 case MUIM_IconList_DrawEntry: return IconList__MUIM_IconList_DrawEntry(CLASS, obj, (APTR)message);
6958 case MUIM_IconList_DrawEntryLabel: return IconList__MUIM_IconList_DrawEntryLabel(CLASS, obj, (APTR)message);
6959 case MUIM_IconList_NextIcon: return IconList__MUIM_IconList_NextIcon(CLASS, obj, (APTR)message);
6960 case MUIM_IconList_GetIconPrivate: return IconList__MUIM_IconList_GetIconPrivate(CLASS, obj, (APTR)message);
6961 case MUIM_IconList_UnselectAll: return IconList__MUIM_IconList_UnselectAll(CLASS, obj, (APTR)message);
6962 case MUIM_IconList_Sort: return IconList__MUIM_IconList_Sort(CLASS, obj, (APTR)message);
6963 case MUIM_IconList_CoordsSort: return IconList__MUIM_IconList_CoordsSort(CLASS, obj, (APTR)message);
6964 case MUIM_IconList_PositionIcons: return IconList__MUIM_IconList_PositionIcons(CLASS, obj, (APTR)message);
6965 case MUIM_IconList_SelectAll: return IconList__MUIM_IconList_SelectAll(CLASS, obj, (APTR)message);
6966 case MUIM_IconList_MakeIconVisible: return IconList__MUIM_IconList_MakeIconVisible(CLASS, obj, (APTR)message);
6969 return DoSuperMethodA(CLASS, obj, message);
6971 BOOPSI_DISPATCHER_END
6973 #if defined(__AROS__)
6974 /* Class descriptor. */
6975 const struct __MUIBuiltinClass _MUI_IconList_desc = {
6976 MUIC_IconList,
6977 MUIC_Area,
6978 sizeof(struct IconList_DATA),
6979 (void*)IconList_Dispatcher
6981 #endif
6982 #endif /* WANDERER_BUILTIN_ICONLIST */
6984 #if !defined(__AROS__)
6985 struct MUI_CustomClass *initIconListClass(void)
6987 return (struct MUI_CustomClass *) MUI_CreateCustomClass(NULL, MUIC_Area, NULL, sizeof(struct IconList_DATA), ENTRY(IconList_Dispatcher));
6989 #endif