2 Copyright © 2001-2019, The AROS Development Team. All rights reserved.
6 #include "../portable_macros.h"
8 #define WANDERER_BUILTIN_ICONLIST 1
11 #include <aros/debug.h>
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
35 #include <dos/datetime.h>
36 #include <dos/filehandler.h>
38 #include <exec/memory.h>
39 #include <exec/rawfmt.h>
40 #include <graphics/gfx.h>
41 #include <graphics/view.h>
42 #include <graphics/rpattr.h>
43 #include <workbench/icon.h>
44 #include <workbench/workbench.h>
47 #include <devices/rawkeycodes.h>
48 #include <clib/alib_protos.h>
50 #include <devices_AROS/rawkeycodes.h>
54 #include <proto/exec.h>
55 #include <proto/graphics.h>
56 #include <proto/utility.h>
57 #include <proto/dos.h>
58 #include <proto/icon.h>
59 #include <proto/layers.h>
60 #include <proto/dos.h>
61 #include <proto/iffparse.h>
64 #include <prefs/prefhdr.h>
65 #include <prefs/wanderer.h>
67 #include <prefs_AROS/prefhdr.h>
68 #include <prefs_AROS/wanderer.h>
71 #include <proto/cybergraphics.h>
74 #include <cybergraphx/cybergraphics.h>
76 #include <cybergraphx_AROS/cybergraphics.h>
80 #if defined(__AMIGA__) && !defined(__PPC__)
81 #define NO_INLINE_STDARG
83 #include <proto/intuition.h>
84 #include <proto/muimaster.h>
85 #include <libraries/mui.h>
86 #include "iconlist_attributes.h"
87 #include "icon_attributes.h"
89 #include "iconlist_private.h"
90 #include "iconlistview.h"
92 #if !defined(__AROS__)
96 #define D(x) if (DEBUG) x
98 #define bug DebugPrintF
107 #define _between(a,x,b) ((x)>=(a) && (x)<=(b))
108 #define _isinobject(x,y) (_between(_mleft(obj),(x),_mright (obj)) \
109 && _between(_mtop(obj) ,(y),_mbottom(obj)))
111 extern struct Library
*MUIMasterBase
;
113 static struct Hook __iconlist_UpdateLabels_hook
;
115 // N.B: We Handle frame/background rendering so make sure icon.library doesnt do it ..
116 static struct TagItem __iconList_DrawIconStateTags
[] = {
117 { ICONDRAWA_Frameless
, TRUE
},
118 { ICONDRAWA_Borderless
, TRUE
},
119 { ICONDRAWA_EraseBackground
, FALSE
},
124 static struct TagItem __iconList_BackBuffLayerTags
[] =
126 { LA_Visible
, FALSE
},
131 #ifndef NO_ICON_POSITION
132 #define NO_ICON_POSITION (0x8000000) /* belongs to workbench/workbench.h */
135 #define UPDATE_HEADERENTRY 1
136 #define UPDATE_SINGLEENTRY 2
137 #define UPDATE_SCROLL 3
138 #define UPDATE_RESIZE 4
140 #define LEFT_BUTTON 1
141 #define RIGHT_BUTTON 2
142 #define MIDDLE_BUTTON 4
144 #define ICONLIST_DRAWMODE_NORMAL 1
145 #define ICONLIST_DRAWMODE_FAST 2
147 /* Values used for List View-Mode */
148 #define COLOR_COLUMN_BACKGROUND 0
149 #define COLOR_COLUMN_BACKGROUND_SORTED 1
150 #define COLOR_COLUMN_BACKGROUND_LASSO 2
151 #define COLOR_COLUMN_BACKGROUND_LASSO_SORTED 3
153 #define COLOR_SELECTED_BACKGROUND 4
154 #define COLOR_SELECTED_BACKGROUND_SORTED 5
156 #define MIN_COLUMN_WIDTH 10
158 #define COLUMN_ALIGN_LEFT 0
159 #define COLUMN_ALIGN_CENTER 1
160 #define COLUMN_ALIGN_RIGHT 2
162 #define LINE_SPACING_TOP 2
163 #define LINE_SPACING_BOTTOM 2
164 #define LINE_EXTRAHEIGHT (LINE_SPACING_TOP + LINE_SPACING_BOTTOM)
166 #define LINE_SPACING_LEFT 1
167 #define LINE_SPACING_RIGHT 1
168 #define LINE_EXTRAWIDTH (LINE_SPACING_LEFT + LINE_SPACING_RIGHT)
170 #define ENTRY_SPACING_LEFT 1
171 #define ENTRY_SPACING_RIGHT 1
172 #define ENTRY_EXTRAWIDTH (ENTRY_SPACING_LEFT + ENTRY_SPACING_RIGHT)
174 #define HEADERLINE_SPACING_TOP 3
175 #define HEADERLINE_SPACING_BOTTOM 3
176 #define HEADERLINE_EXTRAHEIGHT (HEADERLINE_SPACING_TOP + HEADERLINE_SPACING_BOTTOM)
178 #define HEADERLINE_SPACING_LEFT 1
179 #define HEADERLINE_SPACING_RIGHT 1
180 #define HEADERLINE_EXTRAWIDTH (HEADERLINE_SPACING_LEFT + HEADERLINE_SPACING_RIGHT)
182 #define HEADERENTRY_SPACING_LEFT 4
183 #define HEADERENTRY_SPACING_RIGHT 4
184 #define HEADERENTRY_EXTRAWIDTH (HEADERENTRY_SPACING_LEFT + HEADERENTRY_SPACING_RIGHT)
196 /**************************************************************************
198 **************************************************************************/
200 #define ForeachPrevNode(list, node) \
203 node = (void *)(((struct List *)(list))->lh_TailPred); \
204 ((struct Node *)(node))->ln_Pred; \
205 node = (void *)(((struct Node *)(node))->ln_Pred) \
208 #define RPALPHAFLAT (1 << 0)
209 #define RPALPHARADIAL (1 << 1)
211 static void RastPortSetAlpha(struct RastPort
*arport
, ULONG ax
, ULONG ay
, ULONG width
, ULONG height
, UBYTE val
, UBYTE alphamode
)
214 ULONG alphaval
, pixelval
;
215 APTR buffer
, pixelptr
;
217 if ((buffer
= AllocVec(width
* height
* sizeof(ULONG
), MEMF_ANY
)) == NULL
)
220 ReadPixelArray(buffer
, 0, 0, width
* sizeof(ULONG
), arport
, 0, 0, width
, height
, RECTFMT_ARGB
);
224 for (y
= 0; y
< height
; y
++)
226 for (x
= 0; x
< width
; x
++)
228 if((pixelval
= *((ULONG
*)pixelptr
)))
230 if (alphamode
== RPALPHARADIAL
){
231 //Set the alpha value based on distance from ax,ay
235 pixelval
= (pixelval
& 0xffffff00) | alphaval
;
236 *((ULONG
*)pixelptr
) = pixelval
;
238 pixelptr
+= sizeof(ULONG
);
242 WritePixelArray(buffer
, 0, 0, width
* sizeof(ULONG
), arport
, 0, 0, width
, height
, RECTFMT_ARGB
);
247 // Entry/Label Area support functions
248 static int RectAndRect(struct Rectangle
*a
, struct Rectangle
*b
)
250 if ((a
->MinX
> b
->MaxX
) || (a
->MinY
> b
->MaxY
) || (a
->MaxX
< b
->MinX
) || (a
->MaxY
< b
->MinY
))
258 * offx and offy define the largest jump from b->MinX b->MinY that is safe not to
259 * miss a free zone of size b
261 static int RegionAndRect(struct Region
* a
, struct Rectangle
*b
, LONG
*offx
, LONG
*offy
)
263 D(bug("Region (%d, %d)(%d, %d), Rect (%d, %d)(%d, %d)\n",
264 (LONG
)a
->bounds
.MinX
, (LONG
)a
->bounds
.MinY
, (LONG
)a
->bounds
.MaxX
, (LONG
)a
->bounds
.MaxY
,
265 (LONG
)b
->MinX
, (LONG
)b
->MinY
, (LONG
)b
->MaxX
, (LONG
)b
->MaxY
));
267 /* First check with region bounds */
268 if (RectAndRect(&a
->bounds
, b
) == 0)
271 if (a
->RegionRectangle
)
273 struct RegionRectangle
* c
= a
->RegionRectangle
;
276 struct Rectangle d
= {
277 a
->bounds
.MinX
+ c
->bounds
.MinX
,
278 a
->bounds
.MinY
+ c
->bounds
.MinY
,
279 a
->bounds
.MinX
+ c
->bounds
.MaxX
,
280 a
->bounds
.MinY
+ c
->bounds
.MaxY
281 }; /* We need absolute coordinates */
282 struct Rectangle intersect
;
284 if (AndRectRect(&d
, b
, &intersect
))
286 *offx
= (LONG
)(intersect
.MaxX
- intersect
.MinX
+ 1);
287 *offy
= (LONG
)(intersect
.MaxY
- intersect
.MinY
+ 1);
297 ///Node_NextVisible()
298 // IconEntry List navigation functions ..
299 static struct IconEntry
*Node_NextVisible(struct IconEntry
*current_Node
)
301 current_Node
= (struct IconEntry
*)GetSucc(¤t_Node
->ie_IconNode
);
302 while ((current_Node
!= NULL
) && (!(current_Node
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)))
304 current_Node
= (struct IconEntry
*)GetSucc(¤t_Node
->ie_IconNode
);
310 ///Node_FirstVisible()
311 static struct IconEntry
*Node_FirstVisible(struct List
*icon_list
)
313 struct IconEntry
*current_Node
= (struct IconEntry
*)GetHead(icon_list
);
315 if ((current_Node
!= NULL
) && !(current_Node
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
))
316 current_Node
= Node_NextVisible(current_Node
);
322 ///Node_PreviousVisible()
323 static struct IconEntry
*Node_PreviousVisible(struct IconEntry
*current_Node
)
325 current_Node
= (struct IconEntry
*)GetPred(¤t_Node
->ie_IconNode
);
326 while ((current_Node
!= NULL
) && (!(current_Node
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)))
328 current_Node
= (struct IconEntry
*)GetPred(¤t_Node
->ie_IconNode
);
334 ///Node_LastVisible()
335 static struct IconEntry
*Node_LastVisible(struct List
*icon_list
)
337 struct IconEntry
*current_Node
= (struct IconEntry
*)GetTail(icon_list
);
339 if ((current_Node
!= NULL
) && !(current_Node
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
))
340 current_Node
= Node_PreviousVisible(current_Node
);
346 const UBYTE MSG_MEM_G
[] = "GB";
347 const UBYTE MSG_MEM_M
[] = "MB";
348 const UBYTE MSG_MEM_K
[] = "KB";
349 const UBYTE MSG_MEM_B
[] = "Bytes";
352 static void FmtSizeToString(UBYTE
*buf
, ULONG num
)
366 if (num
>= 1073741824)
369 array
.val
= num
>> 30;
370 d
= ((UQUAD
)num
* 10 + 536870912) / 1073741824;
374 else if (num
>= 1048576)
377 array
.val
= num
>> 20;
378 d
= ((UQUAD
)num
* 10 + 524288) / 1048576;
382 else if (num
>= 1024)
385 array
.val
= num
>> 10;
386 d
= (num
* 10 + 512) / 1024;
399 if (!array
.dec
&& (d
> array
.val
* 10))
404 RawDoFmt(array
.dec
? "%lu.%lu" : "%lu", (RAWARG
)&array
, RAWFMTFUNC_STRING
, buf
);
411 sprintf(buf
, " %s", ch
);
415 ///GetAbsoluteLassoRect()
416 // get positive lasso coords
417 static void GetAbsoluteLassoRect(struct IconList_DATA
*data
, struct Rectangle
*LassoRectangle
)
419 WORD minx
= data
->icld_LassoRectangle
.MinX
;
420 WORD miny
= data
->icld_LassoRectangle
.MinY
;
421 WORD maxx
= data
->icld_LassoRectangle
.MaxX
;
422 WORD maxy
= data
->icld_LassoRectangle
.MaxY
;
424 #if defined(DEBUG_ILC_LASSO) || defined(DEBUG_ILC_FUNCS)
425 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
430 /* Swap minx, maxx */
438 /* Swap miny, maxy */
444 LassoRectangle
->MinX
= data
->view_rect
.MinX
- data
->icld_ViewX
+ minx
;
445 LassoRectangle
->MinY
= data
->view_rect
.MinY
- data
->icld_ViewY
+ miny
;
446 LassoRectangle
->MaxX
= data
->view_rect
.MinX
- data
->icld_ViewX
+ maxx
;
447 LassoRectangle
->MaxY
= data
->view_rect
.MinY
- data
->icld_ViewY
+ maxy
;
451 ///IconList_InvertPixelRect()
452 static void IconList_InvertPixelRect(struct RastPort
*rp
, WORD minx
, WORD miny
, WORD maxx
, WORD maxy
, struct Rectangle
*clip
)
454 struct Rectangle r
, clipped_r
;
456 #if defined(DEBUG_ILC_RENDERING) || defined(DEBUG_ILC_FUNCS)
457 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
462 /* Swap minx, maxx */
470 /* Swap miny, maxy */
481 if (AndRectRect(&r
, clip
, &clipped_r
))
483 InvertPixelArray(rp
, clipped_r
.MinX
, clipped_r
.MinY
,
484 clipped_r
.MaxX
- clipped_r
.MinX
+ 1, clipped_r
.MaxY
- clipped_r
.MinY
+ 1);
489 ///IconList_InvertLassoOutlines()
490 // Simple lasso drawing by inverting area outlines
491 static void IconList_InvertLassoOutlines(Object
*obj
, struct IconList_DATA
*data
, struct Rectangle
*rect
)
493 struct Rectangle lasso
;
494 struct Rectangle clip
;
496 #if defined(DEBUG_ILC_LASSO) || defined(DEBUG_ILC_FUNCS)
497 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
500 /* get abolute iconlist coords */
501 lasso
.MinX
= rect
->MinX
+ _mleft(obj
);
502 lasso
.MaxX
= rect
->MaxX
+ _mleft(obj
);
503 lasso
.MinY
= rect
->MinY
+ _mtop(obj
);
504 lasso
.MaxY
= rect
->MaxY
+ _mtop(obj
);
506 clip
.MinX
= _mleft(obj
);
507 clip
.MinY
= _mtop(obj
);
508 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
510 clip
.MinY
+= data
->icld_LVMAttribs
->lmva_HeaderHeight
;
512 clip
.MaxX
= _mright(obj
);
513 clip
.MaxY
= _mbottom(obj
);
515 /* horizontal lasso lines */
516 IconList_InvertPixelRect(_rp(obj
), lasso
.MinX
+ 2, lasso
.MinY
, lasso
.MaxX
- 1, lasso
.MinY
+ 1, &clip
);
517 IconList_InvertPixelRect(_rp(obj
), lasso
.MinX
, lasso
.MaxY
, lasso
.MaxX
+ 1, lasso
.MaxY
+ 1, &clip
);
519 /* vertical lasso lines */
520 IconList_InvertPixelRect(_rp(obj
), lasso
.MinX
, lasso
.MinY
, lasso
.MinX
+ 1, lasso
.MaxY
- 1, &clip
);
521 IconList_InvertPixelRect(_rp(obj
), lasso
.MaxX
, lasso
.MinY
, lasso
.MaxX
+ 1, lasso
.MaxY
- 1, &clip
);
525 ///IconList_GetIconImageRectangle()
526 //We don't use icon.library's label drawing so we do this by hand
527 static void IconList_GetIconImageRectangle(Object
*obj
, struct IconList_DATA
*data
, struct IconEntry
*entry
, struct Rectangle
*rect
)
529 #if defined(DEBUG_ILC_ICONPOSITIONING) || defined(DEBUG_ILC_FUNCS)
530 D(bug("[IconList]: %s(entry @ %p)\n", __PRETTY_FUNCTION__
, entry
));
533 /* Get basic width/height */
534 GetIconRectangleA(NULL
, entry
->ie_DiskObj
, NULL
, rect
, __iconList_DrawIconStateTags
);
535 #if defined(DEBUG_ILC_ICONPOSITIONING)
536 D(bug("[IconList] %s: MinX %d, MinY %d MaxX %d, MaxY %d\n", __PRETTY_FUNCTION__
, rect
->MinX
, rect
->MinY
, rect
->MaxX
, rect
->MaxY
));
538 entry
->ie_IconWidth
= (rect
->MaxX
- rect
->MinX
) + 1;
539 entry
->ie_IconHeight
= (rect
->MaxY
- rect
->MinY
) + 1;
541 if (entry
->ie_IconHeight
> data
->icld_IconLargestHeight
)
542 data
->icld_IconLargestHeight
= entry
->ie_IconHeight
;
546 ///IconList_GetIconImageOffsets()
547 static void IconList_GetIconImageOffsets(struct IconList_DATA
*data
, struct IconEntry
*entry
, LONG
*offsetx
, LONG
*offsety
)
549 *offsetx
= *offsety
= 0;
550 if (entry
->ie_IconWidth
< entry
->ie_AreaWidth
)
551 *offsetx
+= (entry
->ie_AreaWidth
- entry
->ie_IconWidth
)/2;
553 if ((data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
) &&
554 (entry
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
))
555 *offsetx
+= ((data
->icld_IconAreaLargestWidth
- entry
->ie_AreaWidth
)/2);
557 if ((data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
) &&
558 (entry
->ie_AreaHeight
< data
->icld_IconAreaLargestHeight
))
559 *offsety
+= ((data
->icld_IconAreaLargestHeight
- entry
->ie_AreaHeight
)/2);
562 ///IconList_GetIconLabelRectangle()
563 static void IconList_GetIconLabelRectangle(Object
*obj
, struct IconList_DATA
*data
, struct IconEntry
*entry
, struct Rectangle
*rect
)
565 ULONG outline_offset
= 0;
568 #if defined(DEBUG_ILC_ICONPOSITIONING) || defined(DEBUG_ILC_FUNCS)
569 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
572 switch ( data
->icld__Option_LabelTextMode
)
574 case ICON_TEXTMODE_DROPSHADOW
:
578 case ICON_TEXTMODE_PLAIN
:
586 /* Get entry box width including text width */
587 if ((entry
->ie_IconListEntry
.label
!= NULL
) && (entry
->ie_TxtBuf_DisplayedLabel
!= NULL
))
589 ULONG curlabel_TotalLines
;
590 SetFont(data
->icld_BufferRastPort
, data
->icld_IconLabelFont
);
593 rect
->MaxX
= (((data
->icld__Option_LabelTextHorizontalPadding
+ data
->icld__Option_LabelTextBorderWidth
) * 2) + entry
->ie_TxtBuf_DisplayedLabelWidth
+ outline_offset
) - 1;
597 curlabel_TotalLines
= entry
->ie_SplitParts
;
598 if (curlabel_TotalLines
== 0)
599 curlabel_TotalLines
= 1;
600 if (curlabel_TotalLines
> data
->icld__Option_LabelTextMultiLine
)
601 curlabel_TotalLines
= data
->icld__Option_LabelTextMultiLine
;
603 rect
->MaxY
= (((data
->icld__Option_LabelTextBorderHeight
+ data
->icld__Option_LabelTextVerticalPadding
) * 2) +
604 ((data
->icld_IconLabelFont
->tf_YSize
+ outline_offset
) * curlabel_TotalLines
)) - 1;
606 /* Date/size sorting has the date/size appended under the entry label
607 only list regular files like this (drawers have no size/date output) */
609 entry
->ie_IconListEntry
.type
!= ST_USERDIR
&&
610 ((data
->icld_SortFlags
& MUIV_IconList_Sort_BySize
) || (data
->icld_SortFlags
& MUIV_IconList_Sort_ByDate
))
613 SetFont(data
->icld_BufferRastPort
, data
->icld_IconInfoFont
);
615 if( (data
->icld_SortFlags
& MUIV_IconList_Sort_BySize
) && !(data
->icld_SortFlags
& MUIV_IconList_Sort_ByDate
) )
617 entry
->ie_TxtBuf_SIZEWidth
= TextLength(data
->icld_BufferRastPort
, entry
->ie_TxtBuf_SIZE
, strlen(entry
->ie_TxtBuf_SIZE
));
618 textwidth
= entry
->ie_TxtBuf_SIZEWidth
;
622 if( !(data
->icld_SortFlags
& MUIV_IconList_Sort_BySize
) && (data
->icld_SortFlags
& MUIV_IconList_Sort_ByDate
) )
624 if( entry
->ie_Flags
& ICONENTRY_FLAG_TODAY
)
626 entry
->ie_TxtBuf_TIMEWidth
= TextLength(data
->icld_BufferRastPort
, entry
->ie_TxtBuf_TIME
, strlen(entry
->ie_TxtBuf_TIME
));
627 textwidth
= entry
->ie_TxtBuf_TIMEWidth
;
631 entry
->ie_TxtBuf_DATEWidth
= TextLength(data
->icld_BufferRastPort
, entry
->ie_TxtBuf_DATE
, strlen(entry
->ie_TxtBuf_DATE
));
632 textwidth
= entry
->ie_TxtBuf_DATEWidth
;
639 rect
->MaxY
= rect
->MaxY
+ data
->icld_IconInfoFont
->tf_YSize
+ outline_offset
;
640 if ((textwidth
+ outline_offset
+ ((data
->icld__Option_LabelTextHorizontalPadding
+ data
->icld__Option_LabelTextBorderWidth
) * 2)) > ((rect
->MaxX
- rect
->MinX
) + 1))
641 rect
->MaxX
= (textwidth
+ outline_offset
+ ((data
->icld__Option_LabelTextVerticalPadding
+ data
->icld__Option_LabelTextBorderWidth
) * 2)) - 1;
645 if (((rect
->MaxY
- rect
->MinY
) + 1) > data
->icld_LabelLargestHeight
) data
->icld_LabelLargestHeight
= ((rect
->MaxY
- rect
->MinY
) + 1);
649 ///IconList_GetIconAreaRectangle()
650 static void IconList_GetIconAreaRectangle(Object
*obj
, struct IconList_DATA
*data
, struct IconEntry
*entry
, struct Rectangle
*rect
)
652 struct Rectangle labelrect
;
653 ULONG iconlabel_Width
;
654 ULONG iconlabel_Height
;
656 #if defined(DEBUG_ILC_ICONPOSITIONING) || defined(DEBUG_ILC_FUNCS)
657 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
660 /* Get entry box width including text width */
661 memset(rect
, 0, sizeof(struct Rectangle
));
663 IconList_GetIconImageRectangle(obj
, data
, entry
, rect
);
665 entry
->ie_AreaWidth
= entry
->ie_IconWidth
;
666 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
668 entry
->ie_AreaHeight
= data
->icld_IconLargestHeight
;
672 entry
->ie_AreaHeight
= entry
->ie_IconHeight
;
675 IconList_GetIconLabelRectangle(obj
, data
, entry
, &labelrect
);
677 iconlabel_Width
= ((labelrect
.MaxX
- labelrect
.MinX
) + 1);
678 iconlabel_Height
= ((labelrect
.MaxY
- labelrect
.MinY
) + 1);
680 if (iconlabel_Width
> entry
->ie_AreaWidth
)
681 entry
->ie_AreaWidth
= iconlabel_Width
;
683 entry
->ie_AreaHeight
= entry
->ie_AreaHeight
+ data
->icld__Option_IconImageSpacing
+ iconlabel_Height
;
686 rect
->MaxX
= (rect
->MinX
+ entry
->ie_AreaWidth
) - 1;
687 rect
->MaxY
= (rect
->MinY
+ entry
->ie_AreaHeight
) - 1;
689 if (entry
->ie_AreaWidth
> data
->icld_IconAreaLargestWidth
) data
->icld_IconAreaLargestWidth
= entry
->ie_AreaWidth
;
690 if (entry
->ie_AreaHeight
> data
->icld_IconAreaLargestHeight
) data
->icld_IconAreaLargestHeight
= entry
->ie_AreaHeight
;
694 static LONG
FirstVisibleColumnNumber(struct IconList_DATA
*data
)
699 if (data
->icld_LVMAttribs
!= NULL
)
701 for(i
= 0; i
< NUM_COLUMNS
; i
++)
703 LONG index
= data
->icld_LVMAttribs
->lmva_ColumnPos
[i
];
705 if (data
->icld_LVMAttribs
->lmva_ColumnFlags
[index
] & LVMCF_COLVISIBLE
)
716 static LONG
LastVisibleColumnNumber(struct IconList_DATA
*data
)
721 if (data
->icld_LVMAttribs
!= NULL
)
723 for(i
= 0; i
< NUM_COLUMNS
; i
++)
725 LONG index
= data
->icld_LVMAttribs
->lmva_ColumnPos
[i
];
727 if (data
->icld_LVMAttribs
->lmva_ColumnFlags
[index
] & LVMCF_COLVISIBLE
)
739 // Remove the lasso from the screen
740 static void NullifyLasso(struct IconList_DATA
*data
, Object
*obj
)
742 /* End Lasso-selection */
743 struct Rectangle old_lasso
;
744 struct IconEntry
*node
= NULL
;
745 struct Window
*thisWindow
= NULL
;
747 #if defined(DEBUG_ILC_EVENTS) || defined(DEBUG_ILC_LASSO)
748 D(bug("[IconList] %s: Removing Lasso\n", __PRETTY_FUNCTION__
));
751 /* Stop handling INTUITICKS */
752 GET(obj
, MUIA_Window
, &thisWindow
);
755 ModifyIDCMP(thisWindow
, (thisWindow
->IDCMPFlags
& ~(IDCMP_INTUITICKS
)));
756 if ((data
->ehn
.ehn_Events
& IDCMP_INTUITICKS
))
758 DoMethod(_win(obj
), MUIM_Window_RemEventHandler
, (IPTR
)&data
->ehn
);
759 data
->ehn
.ehn_Events
&= ~IDCMP_INTUITICKS
;
760 DoMethod(_win(obj
), MUIM_Window_AddEventHandler
, (IPTR
)&data
->ehn
);
764 /* Clear Lasso Frame.. */
765 GetAbsoluteLassoRect(data
, &old_lasso
);
766 IconList_InvertLassoOutlines(obj
, data
, &old_lasso
);
768 data
->icld_LassoActive
= FALSE
;
770 /* Remove Lasso flag from affected icons.. */
771 #if defined(__AROS__)
772 ForeachNode(&data
->icld_IconList
, node
)
774 Foreach_Node(&data
->icld_IconList
, node
);
777 if (node
->ie_Flags
& ICONENTRY_FLAG_LASSO
)
779 node
->ie_Flags
&= ~ICONENTRY_FLAG_LASSO
;
782 SET(obj
, MUIA_IconList_SelectionChanged
, TRUE
);
786 static void RenderEntryField(Object
*obj
, struct IconList_DATA
*data
,
787 struct IconEntry
*entry
, struct Rectangle
*rect
, LONG index
, BOOL firstvis
,
788 BOOL lastvis
, struct RastPort
* rp
)
790 STRPTR text
= NULL
, renderflag
= "<UHOH>";
791 struct TextExtent te
;
794 if (entry
->ie_Flags
& ICONENTRY_FLAG_SELECTED
)
797 rect
->MinX
, rect
->MinY
,
798 rect
->MaxX
- rect
->MinX
+ 1, rect
->MaxY
- rect
->MinY
,
802 rect
->MinX
+= ENTRY_SPACING_LEFT
;
803 rect
->MaxX
-= ENTRY_SPACING_RIGHT
;
804 rect
->MinY
+= LINE_SPACING_TOP
;
805 rect
->MaxY
-= LINE_SPACING_BOTTOM
;
807 if (firstvis
) rect
->MinX
+= LINE_SPACING_LEFT
;
808 if (lastvis
) rect
->MaxX
-= LINE_SPACING_RIGHT
;
815 /* Special case !! we draw an image instead .. */
820 text
= entry
->ie_IconListEntry
.label
;
824 text
= entry
->ie_TxtBuf_SIZE
;
827 case INDEX_LASTACCESS
:
828 text
= AllocVec(strlen(entry
->ie_TxtBuf_DATE
) + strlen(entry
->ie_TxtBuf_TIME
) + 5, MEMF_CLEAR
);
830 sprintf(text
, "%s %s", entry
->ie_TxtBuf_DATE
,
831 entry
->ie_TxtBuf_TIME
);
835 text
= entry
->ie_FileInfoBlock
->fib_Comment
;
838 case INDEX_PROTECTION
:
839 text
= entry
->ie_TxtBuf_PROT
;
844 if (!text
[0]) return;
846 if (text
== renderflag
)
848 if (entry
->ie_IconListEntry
.type
== ST_USERDIR
)
850 if (data
->icld_LVMAttribs
->lvma_IconDrawer
)
854 rp
, data
->icld_LVMAttribs
->lvma_IconDrawer
, NULL
,
855 rect
->MinX
+ 1, rect
->MinY
+ 1,
856 (entry
->ie_Flags
& ICONENTRY_FLAG_SELECTED
) ? IDS_SELECTED
: IDS_NORMAL
,
857 __iconList_DrawIconStateTags
863 rect
->MinX
+ 1, rect
->MinY
+ 1,
864 rect
->MaxX
- rect
->MinX
- 1, rect
->MaxY
- rect
->MinY
- 1,
870 if (data
->icld_LVMAttribs
->lvma_IconFile
)
874 rp
, data
->icld_LVMAttribs
->lvma_IconFile
, NULL
,
875 rect
->MinX
+ 1, rect
->MinY
+ 1,
876 (entry
->ie_Flags
& ICONENTRY_FLAG_SELECTED
) ? IDS_SELECTED
: IDS_NORMAL
,
877 __iconList_DrawIconStateTags
883 rect
->MinX
+ 1, rect
->MinY
+ 1,
884 rect
->MaxX
- rect
->MinX
- 1, rect
->MaxY
- rect
->MinY
- 1,
891 fit
= TextFit(rp
, text
, strlen(text
), &te
, NULL
, 1,
892 rect
->MaxX
- rect
->MinX
+ 1,
893 rect
->MaxY
- rect
->MinY
+ 1);
897 SetABPenDrMd(rp
, _pens(obj
)[(entry
->ie_Flags
& ICONENTRY_FLAG_SELECTED
) ? MPEN_SHINE
: MPEN_TEXT
], 0, JAM1
);
899 if (((rect
->MaxY
- rect
->MinY
+ 1) - data
->icld_IconLabelFont
->tf_YSize
) > 0)
901 rect
->MinY
+= ((rect
->MaxY
- rect
->MinY
+ 1) - data
->icld_IconLabelFont
->tf_YSize
) / 2;
904 switch(data
->icld_LVMAttribs
->lmva_ColumnHAlign
[index
])
906 case COLUMN_ALIGN_LEFT
:
907 Move(rp
, rect
->MinX
, rect
->MinY
+ rp
->TxBaseline
);
910 case COLUMN_ALIGN_RIGHT
:
911 Move(rp
, rect
->MaxX
- te
.te_Width
, rect
->MinY
+ rp
->TxBaseline
);
914 case COLUMN_ALIGN_CENTER
:
915 Move(rp
, rect
->MinX
+ (rect
->MaxX
- rect
->MinX
+ 1 + 1 - te
.te_Width
) / 2,
916 rect
->MinY
+ rp
->TxBaseline
);
922 if ((index
== INDEX_LASTACCESS
) && text
)
927 /**************************************************************************
928 Draw the entry at its position
929 **************************************************************************/
930 ///IconList__MUIM_IconList_DrawEntry()
931 IPTR
IconList__MUIM_IconList_DrawEntry(struct IClass
*CLASS
, Object
*obj
, struct MUIP_IconList_DrawEntry
*message
)
933 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
935 BOOL outside
= FALSE
;
937 struct Rectangle iconrect
;
938 struct Rectangle objrect
;
940 ULONG objX
, objY
, objW
, objH
;
943 if (data
->icld_BufferRastPort
== data
->icld_DisplayRastPort
)
952 objW
= _mright(obj
) - _mleft(obj
) + 1;
953 objH
= _mbottom(obj
) - _mtop(obj
) + 1;
955 #if defined(DEBUG_ILC_ICONRENDERING)
956 D(bug("[IconList]: %s(message->entry = 0x%p)\n", __PRETTY_FUNCTION__
, message
->entry
));
959 if ((!(message
->entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)) ||
960 (data
->icld_BufferRastPort
== NULL
) ||
961 (!(message
->entry
->ie_DiskObj
)))
963 #if defined(DEBUG_ILC_ICONRENDERING)
964 D(bug("[IconList] %s: Not visible or missing DOB\n", __PRETTY_FUNCTION__
));
969 /* Set the dimensions of our "view" */
972 objrect
.MaxX
= objX
+ objW
- 1;
973 objrect
.MaxY
= objY
+ objH
- 1;
975 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
977 struct Rectangle linerect
;
979 LONG firstvis
, lastvis
;
981 linerect
.MinX
= objX
- data
->icld_ViewX
;
982 linerect
.MaxX
= objX
+ objW
- 1; //linerect.MinX + data->width - 1;
983 linerect
.MinY
= (objY
- data
->icld_ViewY
) + data
->icld_LVMAttribs
->lmva_HeaderHeight
+ (message
->drawmode
* data
->icld_LVMAttribs
->lmva_RowHeight
);
984 linerect
.MaxY
= linerect
.MinY
+ data
->icld_LVMAttribs
->lmva_RowHeight
- 1;
986 if (!AndRectRect(&linerect
, &objrect
, NULL
)) return FALSE
;
987 // if (!MustRenderRect(data, &linerect)) return;
989 SetFont(data
->icld_BufferRastPort
, data
->icld_IconLabelFont
);
991 x
= linerect
.MinX
+ LINE_SPACING_LEFT
;
993 firstvis
= FirstVisibleColumnNumber(data
);
994 lastvis
= LastVisibleColumnNumber(data
);
996 for(i
= 0; i
< NUM_COLUMNS
; i
++)
998 struct Rectangle field_rect
;
999 LONG index
= data
->icld_LVMAttribs
->lmva_ColumnPos
[i
];
1001 if (!(data
->icld_LVMAttribs
->lmva_ColumnFlags
[i
] & LVMCF_COLVISIBLE
)) continue;
1003 field_rect
.MinX
= (i
== firstvis
) ? linerect
.MinX
: x
;
1004 field_rect
.MinY
= linerect
.MinY
;
1005 field_rect
.MaxX
= x
+ data
->icld_LVMAttribs
->lmva_ColumnWidth
[index
] - 1 + ((i
== lastvis
) ? LINE_SPACING_RIGHT
: 0);
1006 field_rect
.MaxY
= linerect
.MaxY
;
1008 /* if (MustRenderRect(data, &field_rect))
1010 if (AndRectRect(&field_rect
, &objrect
, NULL
))
1012 RenderEntryField(obj
, data
, message
->entry
, &field_rect
, index
,
1013 (i
== firstvis
), (i
== lastvis
), data
->icld_BufferRastPort
);
1016 x
+= data
->icld_LVMAttribs
->lmva_ColumnWidth
[index
];
1019 if ((data
->icld_LVMAttribs
->lvma_Flags
& LVMAF_ROWDRAWTOEND
) == LVMAF_ROWDRAWTOEND
)
1021 x
+= LINE_SPACING_RIGHT
;
1023 if (x
< linerect
.MaxX
)
1027 SetABPenDrMd(data
->icld_BufferRastPort
, _pens(obj
)[MPEN_SHINE
], 0, JAM1
);
1028 RectFill(data
->icld_BufferRastPort
, linerect
.MinX
, linerect
.MinY
, linerect
.MaxX
, linerect
.MaxY
);
1034 LONG offsetx
,offsety
;
1036 /* Get the dimensions and affected area of message->entry */
1037 IconList_GetIconImageRectangle(obj
, data
, message
->entry
, &iconrect
);
1039 /* Get offset corrections */
1040 IconList_GetIconImageOffsets(data
, message
->entry
, &offsetx
, &offsety
);
1042 /* Add the relative position offset of the message->entry */
1043 iconrect
.MinX
+= objX
- data
->icld_ViewX
+ message
->entry
->ie_IconX
+ offsetx
;
1044 iconrect
.MaxX
+= objX
- data
->icld_ViewX
+ message
->entry
->ie_IconX
+ offsetx
;
1045 iconrect
.MinY
+= objY
- data
->icld_ViewY
+ message
->entry
->ie_IconY
+ offsety
;
1046 iconrect
.MaxY
+= objY
- data
->icld_ViewY
+ message
->entry
->ie_IconY
+ offsety
;
1048 if (!RectAndRect(&iconrect
, &objrect
))
1050 #if defined(DEBUG_ILC_ICONRENDERING)
1051 D(bug("[IconList] %s: Entry '%s' image outside of visible area .. skipping\n", __PRETTY_FUNCTION__
, message
->entry
->ie_IconListEntry
.label
));
1056 /* data->update_rect1 and data->update_rect2 may
1057 point to rectangles to indicate that only icons
1058 in any of this rectangles need to be drawn */
1059 if (data
->update_rect1
)
1061 if (!RectAndRect(&iconrect
, data
->update_rect1
)) outside
= TRUE
;
1064 if (data
->update_rect2
)
1066 if (data
->update_rect1
)
1068 if ((outside
== TRUE
) && RectAndRect(&iconrect
, data
->update_rect2
))
1073 if (!RectAndRect(&iconrect
, data
->update_rect2
))
1078 if (outside
== TRUE
)
1080 #if defined(DEBUG_ILC_ICONRENDERING)
1081 D(bug("[IconList] %s: Entry '%s' image outside of update area .. skipping\n", __PRETTY_FUNCTION__
, message
->entry
->ie_IconListEntry
.label
));
1086 if (message
->drawmode
== ICONENTRY_DRAWMODE_NONE
) return TRUE
;
1088 // Center entry image
1089 iconX
= iconrect
.MinX
- objX
+ data
->icld_DrawOffsetX
;
1090 iconY
= iconrect
.MinY
- objY
+ data
->icld_DrawOffsetY
;
1092 #if defined(DEBUG_ILC_ICONRENDERING)
1093 D(bug("[IconList] %s: DrawIconState('%s') .. %d, %d\n", __PRETTY_FUNCTION__
, message
->entry
->ie_IconListEntry
.label
, iconX
, iconY
));
1097 data
->icld_BufferRastPort
, message
->entry
->ie_DiskObj
, NULL
,
1100 (message
->entry
->ie_Flags
& ICONENTRY_FLAG_SELECTED
) ? IDS_SELECTED
: IDS_NORMAL
,
1101 __iconList_DrawIconStateTags
1103 #if defined(DEBUG_ILC_ICONRENDERING)
1104 D(bug("[IconList] %s: DrawIconState Done\n", __PRETTY_FUNCTION__
));
1112 ///IconList__LabelFunc_SplitLabel()
1113 static void IconList__LabelFunc_SplitLabel(Object
*obj
, struct IconList_DATA
*data
, struct IconEntry
*entry
)
1115 ULONG labelSplit_MaxLabelLineLength
= data
->icld__Option_LabelTextMaxLen
;
1116 ULONG labelSplit_LabelLength
= strlen(entry
->ie_IconListEntry
.label
);
1118 // ULONG labelSplit_FontY = data->icld_IconLabelFont->tf_YSize;
1119 int labelSplit_CharsDone
, labelSplit_CharsSplit
;
1120 ULONG labelSplit_CurSplitWidth
;
1122 if ((data
->icld__Option_TrimVolumeNames
) &&
1123 ((entry
->ie_IconListEntry
.type
== ST_ROOT
) && (entry
->ie_IconListEntry
.label
[labelSplit_LabelLength
- 1] == ':')))
1124 labelSplit_LabelLength
--;
1126 if (labelSplit_MaxLabelLineLength
>= labelSplit_LabelLength
)
1128 #if defined(DEBUG_ILC_ICONRENDERING)
1129 D(bug("[IconList]: %s: Label'%s' doesnt need split (onyl %d chars)\n", __PRETTY_FUNCTION__
, entry
->ie_IconListEntry
.label
, labelSplit_LabelLength
));
1134 SetFont(data
->icld_BufferRastPort
, data
->icld_IconLabelFont
);
1135 txwidth
= TextLength(data
->icld_BufferRastPort
, entry
->ie_IconListEntry
.label
, labelSplit_MaxLabelLineLength
);
1136 #if defined(DEBUG_ILC_ICONRENDERING)
1137 D(bug("[IconList]: %s: txwidth = %d\n", __PRETTY_FUNCTION__
, txwidth
));
1139 entry
->ie_TxtBuf_DisplayedLabel
= AllocVecPooled(data
->icld_Pool
, 256);
1140 if (entry
->ie_TxtBuf_DisplayedLabel
!= NULL
)
1141 memset(entry
->ie_TxtBuf_DisplayedLabel
, 0, 256);
1142 entry
->ie_SplitParts
= 0;
1144 labelSplit_CharsDone
= 0;
1145 labelSplit_CharsSplit
= 0;
1146 labelSplit_CurSplitWidth
= 0;
1148 while (labelSplit_CharsDone
< labelSplit_LabelLength
)
1150 ULONG labelSplit_CurSplitLength
= labelSplit_LabelLength
- labelSplit_CharsDone
;
1151 IPTR labelSplit_SplitStart
= (IPTR
)(entry
->ie_IconListEntry
.label
+ labelSplit_CharsDone
);
1152 int tmp_checkoffs
= 0;
1153 IPTR labelSplit_RemainingCharsAfterSplit
= 0;
1154 IPTR labelSplit_CurSplitDest
;
1156 while (*(char *)(labelSplit_SplitStart
) == ' ')
1158 //Skip preceding spaces..
1159 labelSplit_SplitStart
= labelSplit_SplitStart
+ 1;
1160 labelSplit_CurSplitLength
= labelSplit_CurSplitLength
- 1;
1161 labelSplit_CharsDone
= labelSplit_CharsDone
+ 1;
1164 while(TextLength(data
->icld_BufferRastPort
, (char *)labelSplit_SplitStart
, labelSplit_CurSplitLength
) < txwidth
) labelSplit_CurSplitLength
++;
1165 while(TextLength(data
->icld_BufferRastPort
, (char *)labelSplit_SplitStart
, labelSplit_CurSplitLength
) > txwidth
) labelSplit_CurSplitLength
--;
1166 #if defined(DEBUG_ILC_ICONRENDERING)
1167 D(bug("[IconList]: %s: labelSplit_CurSplitLength = %d\n", __PRETTY_FUNCTION__
, labelSplit_CurSplitLength
));
1170 #if defined(DEBUG_ILC_ICONRENDERING)
1171 D(bug("[IconList]: %s: Attempting to find neat split ", __PRETTY_FUNCTION__
));
1173 while(tmp_checkoffs
< (labelSplit_CurSplitLength
- ILC_ICONLABEL_SHORTEST
))
1175 #if defined(DEBUG_ILC_ICONRENDERING)
1176 D(bug("%d", tmp_checkoffs
));
1178 labelSplit_RemainingCharsAfterSplit
= labelSplit_LabelLength
- (labelSplit_CharsDone
+ labelSplit_CurSplitLength
);
1180 if ((labelSplit_CurSplitLength
- tmp_checkoffs
) > ILC_ICONLABEL_SHORTEST
)
1182 #if defined(DEBUG_ILC_ICONRENDERING)
1185 if ((*(char *)(labelSplit_SplitStart
+ labelSplit_CurSplitLength
- tmp_checkoffs
) == ' ') ||
1186 (*(char *)(labelSplit_SplitStart
+ labelSplit_CurSplitLength
- tmp_checkoffs
) == '.') ||
1187 (*(char *)(labelSplit_SplitStart
+ labelSplit_CurSplitLength
- tmp_checkoffs
) == '-'))
1189 #if defined(DEBUG_ILC_ICONRENDERING)
1192 labelSplit_CurSplitLength
= labelSplit_CurSplitLength
- tmp_checkoffs
;
1193 labelSplit_RemainingCharsAfterSplit
= labelSplit_RemainingCharsAfterSplit
- tmp_checkoffs
;
1199 if ((labelSplit_RemainingCharsAfterSplit
- tmp_checkoffs
) < 0)
1201 #if defined(DEBUG_ILC_ICONRENDERING)
1204 labelSplit_CurSplitLength
= labelSplit_CurSplitLength
+ tmp_checkoffs
;
1205 labelSplit_RemainingCharsAfterSplit
= labelSplit_RemainingCharsAfterSplit
+ tmp_checkoffs
;
1210 if ((labelSplit_RemainingCharsAfterSplit
- tmp_checkoffs
) >= ILC_ICONLABEL_SHORTEST
)
1212 #if defined(DEBUG_ILC_ICONRENDERING)
1215 if ((*(char *)(labelSplit_SplitStart
+ labelSplit_CurSplitLength
+ tmp_checkoffs
) == ' ') ||
1216 (*(char *)(labelSplit_SplitStart
+ labelSplit_CurSplitLength
+ tmp_checkoffs
) == '.') ||
1217 (*(char *)(labelSplit_SplitStart
+ labelSplit_CurSplitLength
+ tmp_checkoffs
) == '-'))
1219 #if defined(DEBUG_ILC_ICONRENDERING)
1222 labelSplit_CurSplitLength
= labelSplit_CurSplitLength
+ tmp_checkoffs
;
1223 labelSplit_RemainingCharsAfterSplit
= labelSplit_RemainingCharsAfterSplit
+ tmp_checkoffs
;
1229 tmp_checkoffs
= tmp_checkoffs
+ 1;
1231 #if defined(DEBUG_ILC_ICONRENDERING)
1234 if (tmp_checkoffs
!= 0)
1236 #if defined(DEBUG_ILC_ICONRENDERING)
1237 D(bug("[IconList]: %s: Couldnt find neat split : Still %d chars\n", __PRETTY_FUNCTION__
, labelSplit_RemainingCharsAfterSplit
));
1239 if (labelSplit_RemainingCharsAfterSplit
<= ILC_ICONLABEL_SHORTEST
)
1241 labelSplit_CurSplitLength
= labelSplit_CurSplitLength
+ (labelSplit_RemainingCharsAfterSplit
- ILC_ICONLABEL_SHORTEST
);
1244 if ((labelSplit_CharsDone
+ labelSplit_CurSplitLength
) > labelSplit_LabelLength
) labelSplit_CurSplitLength
= labelSplit_LabelLength
- labelSplit_CharsDone
;
1246 if (entry
->ie_TxtBuf_DisplayedLabel
!= NULL
)
1248 labelSplit_CurSplitDest
= (IPTR
)(entry
->ie_TxtBuf_DisplayedLabel
1249 + labelSplit_CharsSplit
+ entry
->ie_SplitParts
);
1251 strncpy((char *)labelSplit_CurSplitDest
,
1252 (char *)labelSplit_SplitStart
, labelSplit_CurSplitLength
);
1254 labelSplit_CurSplitWidth
= TextLength(data
->icld_BufferRastPort
,
1255 (char *)labelSplit_CurSplitDest
, labelSplit_CurSplitLength
);
1258 entry
->ie_SplitParts
= entry
->ie_SplitParts
+ 1;
1260 labelSplit_CharsDone
= labelSplit_CharsDone
+ labelSplit_CurSplitLength
;
1261 labelSplit_CharsSplit
= labelSplit_CharsSplit
+ labelSplit_CurSplitLength
;
1263 if (labelSplit_CurSplitWidth
> entry
->ie_TxtBuf_DisplayedLabelWidth
) entry
->ie_TxtBuf_DisplayedLabelWidth
= labelSplit_CurSplitWidth
;
1265 if ((entry
->ie_SplitParts
<= 1) && entry
->ie_TxtBuf_DisplayedLabel
)
1267 FreeVecPooled(data
->icld_Pool
, entry
->ie_TxtBuf_DisplayedLabel
);
1268 entry
->ie_TxtBuf_DisplayedLabel
= NULL
;
1269 entry
->ie_SplitParts
= 0;
1271 // if ((labelSplit_FontY * entry->ie_SplitParts) > data->icld_LabelLargestHeight) data->icld_LabelLargestHeight = (labelSplit_FontY * entry->ie_SplitParts);
1275 ///IconList__LabelFunc_CreateLabel()
1276 static IPTR
IconList__LabelFunc_CreateLabel(Object
*obj
, struct IconList_DATA
*data
, struct IconEntry
*entry
)
1278 #if defined(DEBUG_ILC_ICONRENDERING) || defined(DEBUG_ILC_FUNCS)
1279 D(bug("[IconList]: %s('%s')\n", __PRETTY_FUNCTION__
, entry
->ie_IconListEntry
.label
));
1281 if (entry
->ie_TxtBuf_DisplayedLabel
)
1283 FreeVecPooled(data
->icld_Pool
, entry
->ie_TxtBuf_DisplayedLabel
);
1284 entry
->ie_TxtBuf_DisplayedLabel
= NULL
;
1285 entry
->ie_SplitParts
= 0;
1288 if (data
->icld__Option_LabelTextMultiLine
> 1)
1290 #if defined(DEBUG_ILC_ICONRENDERING)
1291 D(bug("[IconList]: %s: Attempting to split label ..\n", __PRETTY_FUNCTION__
));
1293 IconList__LabelFunc_SplitLabel(obj
, data
, entry
);
1296 if (entry
->ie_TxtBuf_DisplayedLabel
== NULL
)
1298 ULONG ie_LabelLength
= strlen(entry
->ie_IconListEntry
.label
);
1299 entry
->ie_SplitParts
= 1;
1301 #if defined(DEBUG_ILC_ICONRENDERING)
1302 D(bug("[IconList]: %s: Building unsplit label (len = %d) ..\n", __PRETTY_FUNCTION__
, ie_LabelLength
));
1305 if ((data
->icld__Option_TrimVolumeNames
) &&
1306 ((entry
->ie_IconListEntry
.type
== ST_ROOT
) && (entry
->ie_IconListEntry
.label
[ie_LabelLength
- 1] == ':')))
1309 if(ie_LabelLength
> data
->icld__Option_LabelTextMaxLen
)
1311 if (!(entry
->ie_TxtBuf_DisplayedLabel
= AllocVecPooled(data
->icld_Pool
, data
->icld__Option_LabelTextMaxLen
+ 1)))
1315 memset(entry
->ie_TxtBuf_DisplayedLabel
, 0, data
->icld__Option_LabelTextMaxLen
+ 1);
1316 strncpy(entry
->ie_TxtBuf_DisplayedLabel
, entry
->ie_IconListEntry
.label
, data
->icld__Option_LabelTextMaxLen
- 3);
1317 strcat(entry
->ie_TxtBuf_DisplayedLabel
, " ..");
1321 if (!(entry
->ie_TxtBuf_DisplayedLabel
= AllocVecPooled(data
->icld_Pool
, ie_LabelLength
+ 1)))
1325 memset(entry
->ie_TxtBuf_DisplayedLabel
, 0, ie_LabelLength
+ 1);
1326 strncpy(entry
->ie_TxtBuf_DisplayedLabel
, entry
->ie_IconListEntry
.label
, ie_LabelLength
);
1328 entry
->ie_TxtBuf_DisplayedLabelWidth
= TextLength(data
->icld_BufferRastPort
, entry
->ie_TxtBuf_DisplayedLabel
, strlen(entry
->ie_TxtBuf_DisplayedLabel
));
1329 // if ((data->icld_IconLabelFont->tf_YSize) > data->icld_LabelLargestHeight) data->icld_LabelLargestHeight = data->icld_IconLabelFont->tf_YSize;
1332 // if (entry->ie_TxtBuf_DisplayedLabelWidth > data->icld_LabelLargestWidth) data->icld_LabelLargestWidth = entry->ie_TxtBuf_DisplayedLabelWidth;
1334 return (IPTR
)entry
->ie_TxtBuf_DisplayedLabel
;
1338 ///IconList__HookFunc_UpdateLabelsFunc()
1340 void, IconList__HookFunc_UpdateLabelsFunc
,
1341 AROS_UFHA(struct Hook
*, hook
, A0
),
1342 AROS_UFHA(APTR
*, obj
, A2
),
1343 AROS_UFHA(APTR
, param
, A1
)
1348 /* Get our private data */
1349 Class
*CLASS
= *( Class
**)param
;
1350 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
1352 #if defined(DEBUG_ILC_LASSO) || defined(DEBUG_ILC_FUNCS)
1353 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
1356 if (((data
->icld__Option_LabelTextMaxLen
!= data
->icld__Option_LastLabelTextMaxLen
) &&
1357 (data
->icld__Option_LabelTextMultiLine
> 1)) ||
1358 (data
->icld__Option_LabelTextMultiLine
!= data
->icld__Option_LastLabelTextMultiLine
));
1360 struct IconEntry
*iconentry_Current
= NULL
;
1361 #if defined(__AROS__)
1362 ForeachNode(&data
->icld_IconList
, iconentry_Current
)
1364 Foreach_Node(&data
->icld_IconList
, iconentry_Current
);
1367 IconList__LabelFunc_CreateLabel((Object
*)obj
, data
, iconentry_Current
);
1371 data
->icld__Option_LastLabelTextMaxLen
= data
->icld__Option_LabelTextMaxLen
;
1372 data
->icld__Option_LastLabelTextMultiLine
= data
->icld__Option_LabelTextMultiLine
;
1378 ///IconList__MUIM_IconList_DrawEntryLabel()
1379 IPTR
IconList__MUIM_IconList_DrawEntryLabel(struct IClass
*CLASS
, Object
*obj
, struct MUIP_IconList_DrawEntry
*message
)
1381 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
1384 BOOL outside
= FALSE
;
1386 struct Rectangle iconlabelrect
;
1387 struct Rectangle objrect
;
1389 ULONG txtbox_width
= 0;
1390 LONG tx
,ty
,offsetx
,offsety
;
1391 LONG txwidth
; // txheight;
1393 ULONG objX
, objY
, objW
, objH
;
1394 LONG labelX
, labelY
;
1396 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
1399 if (data
->icld_BufferRastPort
== data
->icld_DisplayRastPort
)
1408 objW
= _mright(obj
) - _mleft(obj
) + 1;
1409 objH
= _mbottom(obj
) - _mtop(obj
) + 1;
1411 ULONG txtarea_width
;
1412 ULONG curlabel_TotalLines
, curlabel_CurrentLine
, offset_y
;
1414 #if defined(DEBUG_ILC_ICONRENDERING) || defined(DEBUG_ILC_FUNCS)
1415 D(bug("[IconList]: %s(message->entry = 0x%p), '%s'\n", __PRETTY_FUNCTION__
, message
->entry
, message
->entry
->ie_IconListEntry
.label
));
1418 if ((!(message
->entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)) ||
1419 (data
->icld_BufferRastPort
== NULL
) ||
1420 (!(message
->entry
->ie_DiskObj
)))
1422 #if defined(DEBUG_ILC_ICONRENDERING)
1423 D(bug("[IconList] %s: Not visible or missing DOB\n", __PRETTY_FUNCTION__
));
1428 /* Get the dimensions and affected area of message->entry's label */
1429 IconList_GetIconLabelRectangle(obj
, data
, message
->entry
, &iconlabelrect
);
1431 /* Add the relative position offset of the message->entry's label */
1432 offsetx
= (objX
- data
->icld_ViewX
) + message
->entry
->ie_IconX
;
1433 txtbox_width
= (iconlabelrect
.MaxX
- iconlabelrect
.MinX
) + 1;
1435 if (txtbox_width
< message
->entry
->ie_AreaWidth
)
1436 offsetx
+= ((message
->entry
->ie_AreaWidth
- txtbox_width
)/2);
1438 if ((data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
) &&
1439 (message
->entry
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
))
1440 offsetx
+= ((data
->icld_IconAreaLargestWidth
- message
->entry
->ie_AreaWidth
)/2);
1442 iconlabelrect
.MinX
+= offsetx
;
1443 iconlabelrect
.MaxX
+= offsetx
;
1445 offsety
= (objY
- data
->icld_ViewY
) + message
->entry
->ie_IconY
+ data
->icld__Option_IconImageSpacing
;
1446 if ((data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
) &&
1447 (message
->entry
->ie_AreaHeight
< data
->icld_IconAreaLargestHeight
))
1448 offsety
+= ((data
->icld_IconAreaLargestHeight
- message
->entry
->ie_AreaHeight
)/2);
1450 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
1452 offsety
= offsety
+ data
->icld_IconLargestHeight
;
1456 offsety
= offsety
+ message
->entry
->ie_IconHeight
;
1458 iconlabelrect
.MinY
+= offsety
;
1459 iconlabelrect
.MaxY
+= offsety
;
1461 /* Add the relative position of the window */
1462 objrect
.MinX
= objX
;
1463 objrect
.MinY
= objX
;
1464 objrect
.MaxX
= objX
+ objW
;
1465 objrect
.MaxY
= objY
+ objH
;
1467 if (!RectAndRect(&iconlabelrect
, &objrect
))
1469 #if defined(DEBUG_ILC_ICONRENDERING)
1470 (bug("[IconList] %s: Entry '%s' label outside of visible area .. skipping\n", __PRETTY_FUNCTION__
, message
->entry
->ie_IconListEntry
.label
));
1475 /* data->update_rect1 and data->update_rect2 may
1476 point to rectangles to indicate that only icons
1477 in any of this rectangles need to be drawn */
1478 if (data
->update_rect1
)
1480 if (!RectAndRect(&iconlabelrect
, data
->update_rect1
))
1484 if (data
->update_rect2
)
1486 if (data
->update_rect1
)
1488 if ((outside
== TRUE
) && RectAndRect(&iconlabelrect
, data
->update_rect2
))
1493 if (!RectAndRect(&iconlabelrect
, data
->update_rect2
))
1498 if (outside
== TRUE
)
1500 #if defined(DEBUG_ILC_ICONRENDERING)
1501 D(bug("[IconList] %s: Entry '%s' label outside of update area .. skipping\n", __PRETTY_FUNCTION__
, message
->entry
->ie_IconListEntry
.label
));
1506 if (message
->drawmode
== ICONENTRY_DRAWMODE_NONE
)
1509 SetABPenDrMd(data
->icld_BufferRastPort
, _pens(obj
)[MPEN_TEXT
], 0, JAM1
);
1511 iconlabelrect
.MinX
= (iconlabelrect
.MinX
- objX
) + data
->icld_DrawOffsetX
;
1512 iconlabelrect
.MinY
= (iconlabelrect
.MinY
- objY
) + data
->icld_DrawOffsetY
;
1513 iconlabelrect
.MaxX
= (iconlabelrect
.MaxX
- objX
) + data
->icld_DrawOffsetX
;
1514 iconlabelrect
.MaxY
= (iconlabelrect
.MaxY
- objY
) + data
->icld_DrawOffsetY
;
1516 labelX
= iconlabelrect
.MinX
+ data
->icld__Option_LabelTextBorderWidth
+ data
->icld__Option_LabelTextHorizontalPadding
;
1517 labelY
= iconlabelrect
.MinY
+ data
->icld__Option_LabelTextBorderHeight
+ data
->icld__Option_LabelTextVerticalPadding
;
1519 txtarea_width
= txtbox_width
- ((data
->icld__Option_LabelTextBorderWidth
+ data
->icld__Option_LabelTextHorizontalPadding
) * 2);
1521 #if defined(DEBUG_ILC_ICONRENDERING)
1522 D(bug("[IconList] %s: Drawing Label '%s' .. %d, %d\n", __PRETTY_FUNCTION__
, message
->entry
->ie_IconListEntry
.label
, labelX
, labelY
));
1524 if (message
->entry
->ie_IconListEntry
.label
&& message
->entry
->ie_TxtBuf_DisplayedLabel
)
1526 char *curlabel_StrPtr
;
1528 if ((message
->entry
->ie_Flags
& ICONENTRY_FLAG_FOCUS
))
1530 //Draw the focus box around the selected label ..
1531 if (data
->icld__Option_LabelTextBorderHeight
> 0)
1533 InvertPixelArray(data
->icld_BufferRastPort
,
1534 iconlabelrect
.MinX
, iconlabelrect
.MinY
,
1535 (iconlabelrect
.MaxX
- iconlabelrect
.MinX
) + 1, data
->icld__Option_LabelTextBorderHeight
);
1537 InvertPixelArray(data
->icld_BufferRastPort
,
1538 iconlabelrect
.MinX
, iconlabelrect
.MaxY
- (data
->icld__Option_LabelTextBorderHeight
- 1),
1539 (iconlabelrect
.MaxX
- iconlabelrect
.MinX
) + 1, data
->icld__Option_LabelTextBorderHeight
);
1541 if (data
->icld__Option_LabelTextBorderWidth
> 0)
1543 InvertPixelArray(data
->icld_BufferRastPort
,
1544 iconlabelrect
.MinX
, iconlabelrect
.MinY
+ data
->icld__Option_LabelTextBorderHeight
,
1545 data
->icld__Option_LabelTextBorderWidth
, (((iconlabelrect
.MaxY
- iconlabelrect
.MinY
) + 1) - (data
->icld__Option_LabelTextBorderHeight
* 2)));
1547 InvertPixelArray(data
->icld_BufferRastPort
,
1548 iconlabelrect
.MaxX
- (data
->icld__Option_LabelTextBorderWidth
- 1), iconlabelrect
.MinY
+ data
->icld__Option_LabelTextBorderHeight
,
1549 data
->icld__Option_LabelTextBorderWidth
, (((iconlabelrect
.MaxY
- iconlabelrect
.MinY
) + 1) - (data
->icld__Option_LabelTextBorderHeight
* 2)));
1553 SetFont(data
->icld_BufferRastPort
, data
->icld_IconLabelFont
);
1555 curlabel_TotalLines
= message
->entry
->ie_SplitParts
;
1556 curlabel_CurrentLine
= 0;
1558 if (curlabel_TotalLines
== 0)
1559 curlabel_TotalLines
= 1;
1561 if (!(data
->icld__Option_LabelTextMultiLineOnFocus
) || (data
->icld__Option_LabelTextMultiLineOnFocus
&& (message
->entry
->ie_Flags
& ICONENTRY_FLAG_FOCUS
)))
1563 if (curlabel_TotalLines
> data
->icld__Option_LabelTextMultiLine
)
1564 curlabel_TotalLines
= data
->icld__Option_LabelTextMultiLine
;
1567 curlabel_TotalLines
= 1;
1569 curlabel_StrPtr
= message
->entry
->ie_TxtBuf_DisplayedLabel
;
1573 #if defined(DEBUG_ILC_ICONRENDERING)
1574 D(bug("[IconList] %s: Font YSize %d Baseline %d\n", __PRETTY_FUNCTION__
,data
->icld_IconLabelFont
->tf_YSize
, data
->icld_IconLabelFont
->tf_Baseline
));
1576 for (curlabel_CurrentLine
= 0; curlabel_CurrentLine
< curlabel_TotalLines
; curlabel_CurrentLine
++)
1578 ULONG ie_LabelLength
;
1580 if (curlabel_CurrentLine
> 0) curlabel_StrPtr
= curlabel_StrPtr
+ strlen(curlabel_StrPtr
) + 1;
1581 if ((curlabel_CurrentLine
>= (curlabel_TotalLines
-1)) && (curlabel_TotalLines
< message
->entry
->ie_SplitParts
))
1583 char *tmpLine
= curlabel_StrPtr
;
1584 ULONG tmpLen
= strlen(tmpLine
);
1586 if ((curlabel_StrPtr
= AllocVecPooled(data
->icld_Pool
, tmpLen
+ 1)) != NULL
)
1588 memset(curlabel_StrPtr
, 0, tmpLen
+ 1);
1589 strncpy(curlabel_StrPtr
, tmpLine
, tmpLen
- 3);
1590 strcat(curlabel_StrPtr
, " ..");
1597 ie_LabelLength
= strlen(curlabel_StrPtr
);
1600 // Center message->entry's label
1601 tx
= (labelX
+ (message
->entry
->ie_TxtBuf_DisplayedLabelWidth
/ 2) - (TextLength(data
->icld_BufferRastPort
, curlabel_StrPtr
, strlen(curlabel_StrPtr
)) / 2));
1603 if (message
->entry
->ie_TxtBuf_DisplayedLabelWidth
< txtarea_width
)
1604 tx
+= ((txtarea_width
- message
->entry
->ie_TxtBuf_DisplayedLabelWidth
)/2);
1606 ty
= ty
+ data
->icld_IconLabelFont
->tf_YSize
;
1608 switch ( data
->icld__Option_LabelTextMode
)
1610 case ICON_TEXTMODE_DROPSHADOW
:
1611 SetAPen(data
->icld_BufferRastPort
, data
->icld_LabelShadowPen
);
1612 Move(data
->icld_BufferRastPort
, tx
+ 1, ty
+ 1);
1613 Text(data
->icld_BufferRastPort
, curlabel_StrPtr
, ie_LabelLength
);
1615 case ICON_TEXTMODE_PLAIN
:
1616 SetAPen(data
->icld_BufferRastPort
, data
->icld_LabelPen
);
1617 Move(data
->icld_BufferRastPort
, tx
, ty
);
1618 Text(data
->icld_BufferRastPort
, curlabel_StrPtr
, ie_LabelLength
);
1623 SetSoftStyle(data
->icld_BufferRastPort
, FSF_BOLD
, AskSoftStyle(data
->icld_BufferRastPort
));
1625 SetAPen(data
->icld_BufferRastPort
, data
->icld_LabelShadowPen
);
1626 Move(data
->icld_BufferRastPort
, tx
+ 1, ty
);
1627 Text(data
->icld_BufferRastPort
, curlabel_StrPtr
, ie_LabelLength
);
1628 Move(data
->icld_BufferRastPort
, tx
- 1, ty
);
1629 Text(data
->icld_BufferRastPort
, curlabel_StrPtr
, ie_LabelLength
);
1630 Move(data
->icld_BufferRastPort
, tx
, ty
+ 1);
1631 Text(data
->icld_BufferRastPort
, curlabel_StrPtr
, ie_LabelLength
);
1632 Move(data
->icld_BufferRastPort
, tx
, ty
- 1);
1633 Text(data
->icld_BufferRastPort
, curlabel_StrPtr
, ie_LabelLength
);
1635 SetAPen(data
->icld_BufferRastPort
, data
->icld_LabelPen
);
1636 Move(data
->icld_BufferRastPort
, tx
, ty
);
1637 Text(data
->icld_BufferRastPort
, curlabel_StrPtr
, ie_LabelLength
);
1639 SetSoftStyle(data
->icld_BufferRastPort
, FS_NORMAL
, AskSoftStyle(data
->icld_BufferRastPort
));
1643 if ((curlabel_CurrentLine
>= (curlabel_TotalLines
-1)) && (curlabel_TotalLines
< message
->entry
->ie_SplitParts
))
1645 FreeVecPooled(data
->icld_Pool
, curlabel_StrPtr
);
1650 /*date/size sorting has the date/size appended under the message->entry label*/
1652 if ((message
->entry
->ie_IconListEntry
.type
!= ST_USERDIR
) && ((data
->icld_SortFlags
& (MUIV_IconList_Sort_BySize
|MUIV_IconList_Sort_ByDate
)) != 0))
1655 SetFont(data
->icld_BufferRastPort
, data
->icld_IconInfoFont
);
1657 if (data
->icld_SortFlags
& MUIV_IconList_Sort_BySize
)
1659 buf
= message
->entry
->ie_TxtBuf_SIZE
;
1660 txwidth
= message
->entry
->ie_TxtBuf_SIZEWidth
;
1662 else if (data
->icld_SortFlags
& MUIV_IconList_Sort_ByDate
)
1664 if (message
->entry
->ie_Flags
& ICONENTRY_FLAG_TODAY
)
1666 buf
= message
->entry
->ie_TxtBuf_TIME
;
1667 txwidth
= message
->entry
->ie_TxtBuf_TIMEWidth
;
1671 buf
= message
->entry
->ie_TxtBuf_DATE
;
1672 txwidth
= message
->entry
->ie_TxtBuf_DATEWidth
;
1678 ULONG ie_LabelLength
= strlen(buf
);
1681 if (txwidth
< txtarea_width
)
1682 tx
+= ((txtarea_width
- txwidth
)/2);
1684 ty
= labelY
+ ((data
->icld__Option_LabelTextVerticalPadding
+ data
->icld_IconLabelFont
->tf_YSize
) * curlabel_TotalLines
) + data
->icld_IconInfoFont
->tf_YSize
;
1686 switch ( data
->icld__Option_LabelTextMode
)
1688 case ICON_TEXTMODE_DROPSHADOW
:
1689 SetAPen(data
->icld_BufferRastPort
, data
->icld_InfoShadowPen
);
1690 Move(data
->icld_BufferRastPort
, tx
+ 1, ty
+ 1); Text(data
->icld_BufferRastPort
, buf
, ie_LabelLength
);
1691 case ICON_TEXTMODE_PLAIN
:
1692 SetAPen(data
->icld_BufferRastPort
, data
->icld_InfoPen
);
1693 Move(data
->icld_BufferRastPort
, tx
, ty
); Text(data
->icld_BufferRastPort
, buf
, ie_LabelLength
);
1698 SetSoftStyle(data
->icld_BufferRastPort
, FSF_BOLD
, AskSoftStyle(data
->icld_BufferRastPort
));
1699 SetAPen(data
->icld_BufferRastPort
, data
->icld_InfoShadowPen
);
1701 Move(data
->icld_BufferRastPort
, tx
+ 1, ty
);
1702 Text(data
->icld_BufferRastPort
, buf
, ie_LabelLength
);
1703 Move(data
->icld_BufferRastPort
, tx
- 1, ty
);
1704 Text(data
->icld_BufferRastPort
, buf
, ie_LabelLength
);
1705 Move(data
->icld_BufferRastPort
, tx
, ty
- 1 );
1706 Text(data
->icld_BufferRastPort
, buf
, ie_LabelLength
);
1707 Move(data
->icld_BufferRastPort
, tx
, ty
+ 1 );
1708 Text(data
->icld_BufferRastPort
, buf
, ie_LabelLength
);
1710 SetAPen(data
->icld_BufferRastPort
, data
->icld_InfoPen
);
1712 Move(data
->icld_BufferRastPort
, tx
, ty
);
1713 Text(data
->icld_BufferRastPort
, buf
, ie_LabelLength
);
1715 SetSoftStyle(data
->icld_BufferRastPort
, FS_NORMAL
, AskSoftStyle(data
->icld_BufferRastPort
));
1725 /**************************************************************************
1727 **************************************************************************/
1728 ///IconList__MUIM_IconList_RethinkDimensions()
1729 IPTR
IconList__MUIM_IconList_RethinkDimensions(struct IClass
*CLASS
, Object
*obj
, struct MUIP_IconList_RethinkDimensions
*message
)
1731 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
1733 struct IconEntry
*entry
= NULL
;
1736 struct Rectangle icon_rect
;
1738 #if defined(DEBUG_ILC_ICONPOSITIONING) || defined(DEBUG_ILC_FUNCS)
1739 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
1742 if (message
->singleicon
!= NULL
)
1744 entry
= message
->singleicon
;
1745 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
1747 maxy
= data
->icld_LVMAttribs
->lmva_RowHeight
;
1748 if ((data
->icld_LVMAttribs
->lvma_Flags
& LVMAF_NOHEADER
) == 0)
1750 maxy
+= data
->icld_LVMAttribs
->lmva_HeaderHeight
;
1755 maxx
= data
->icld_AreaWidth
- 1,
1756 maxy
= data
->icld_AreaHeight
- 1;
1759 #if defined(DEBUG_ILC_ICONPOSITIONING)
1760 D(bug("[IconList] %s: SingleIcon - maxx = %d, maxy = %d\n", __PRETTY_FUNCTION__
, maxx
, maxy
));
1765 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
1767 maxy
= data
->icld_LVMAttribs
->lmva_RowHeight
;
1768 if ((data
->icld_LVMAttribs
->lvma_Flags
& LVMAF_NOHEADER
) == 0)
1770 maxy
+= data
->icld_LVMAttribs
->lmva_HeaderHeight
;
1773 entry
= (struct IconEntry
*)GetHead(&data
->icld_IconList
);
1776 while (entry
!= NULL
)
1778 if (entry
->ie_DiskObj
&&
1779 (entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
))
1781 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
1783 maxy
+= data
->icld_LVMAttribs
->lmva_RowHeight
;
1787 IconList_GetIconAreaRectangle(obj
, data
, entry
, &icon_rect
);
1789 icon_rect
.MaxX
+= entry
->ie_IconX
+ data
->icld__Option_IconHorizontalSpacing
;
1790 if ((data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
) &&
1791 (entry
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
))
1792 icon_rect
.MaxX
+= (data
->icld_IconAreaLargestWidth
- entry
->ie_AreaWidth
);
1794 icon_rect
.MaxY
+= entry
->ie_IconY
+ data
->icld__Option_IconVerticalSpacing
;
1796 if (icon_rect
.MaxX
> maxx
) maxx
= icon_rect
.MaxX
;
1797 if (icon_rect
.MaxY
> maxy
) maxy
= icon_rect
.MaxY
;
1801 if (message
->singleicon
)
1804 entry
= (struct IconEntry
*)GetSucc(&entry
->ie_IconNode
);
1807 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
1811 for(col
= 0; col
< NUM_COLUMNS
; col
++)
1813 LONG index
= data
->icld_LVMAttribs
->lmva_ColumnPos
[col
];
1815 if (!(data
->icld_LVMAttribs
->lmva_ColumnFlags
[index
] & LVMCF_COLVISIBLE
)) continue;
1817 maxx
+= data
->icld_LVMAttribs
->lmva_ColumnWidth
[index
];
1821 /* update our view when max x/y have changed */
1822 if (maxx
+ 1 != data
->icld_AreaWidth
)
1824 data
->icld_AreaWidth
= maxx
+ 1;
1825 SET(obj
, MUIA_IconList_Width
, data
->icld_AreaWidth
);
1827 if (maxy
+ 1 != data
->icld_AreaHeight
)
1829 data
->icld_AreaHeight
= maxy
+ 1;
1830 SET(obj
, MUIA_IconList_Height
, data
->icld_AreaHeight
);
1837 * This function executes the layouting when AutoSort is enabled. This means all icons are layouted regardless if
1838 * they have Provided position or not.
1841 static VOID
IconList_Layout_FullAutoLayout(struct IClass
*CLASS
, Object
*obj
)
1843 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
1844 struct IconEntry
*entry
= NULL
;
1845 struct IconEntry
*pass_first
= NULL
; /* First entry of current column or row */
1847 LONG left
= data
->icld__Option_IconHorizontalSpacing
;
1848 LONG top
= data
->icld__Option_IconVerticalSpacing
;
1853 LONG maxw
= 0; /* Widest & talest entry in a column or row */
1857 struct Rectangle iconrect
;
1859 /* Now go to the actual positioning */
1860 entry
= (struct IconEntry
*)GetHead(&data
->icld_IconList
);
1861 while (entry
!= NULL
)
1863 calcnextpos
= FALSE
;
1864 if ((entry
->ie_DiskObj
!= NULL
) && (entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
))
1868 /* Set previously calculated position to this icon */
1869 entry
->ie_IconX
= cur_x
;
1870 entry
->ie_IconY
= cur_y
;
1872 if (entry
->ie_Flags
& ICONENTRY_FLAG_SELECTED
)
1874 if (data
->icld_SelectionLastClicked
== NULL
) data
->icld_SelectionLastClicked
= entry
;
1875 if (data
->icld_FocusIcon
== NULL
) data
->icld_FocusIcon
= entry
;
1878 /* Calculate grid size to advanced the coordinate in next step */
1879 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
1881 maxw
= data
->icld_IconAreaLargestWidth
+ data
->icld__Option_IconHorizontalSpacing
;
1882 maxh
= data
->icld_IconLargestHeight
+ data
->icld__Option_IconImageSpacing
+ data
->icld_LabelLargestHeight
+ data
->icld__Option_IconVerticalSpacing
;
1888 if (!(pass_first
)) pass_first
= entry
;
1890 IconList_GetIconAreaRectangle(obj
, data
, entry
, &iconrect
);
1892 if ((maxw
< entry
->ie_AreaWidth
) || (maxh
< entry
->ie_AreaHeight
))
1894 if (maxw
< entry
->ie_AreaWidth
) maxw
= entry
->ie_AreaWidth
;
1895 if (maxh
< entry
->ie_AreaHeight
) maxh
= entry
->ie_AreaHeight
;
1896 if (pass_first
!= entry
)
1899 cur_x
= entry
->ie_IconX
;
1900 cur_y
= entry
->ie_IconY
;
1901 /* We detected that the new icon it taller/wider than icons so far in this row/column.
1902 * We need to re-layout this row/column. */
1907 if (data
->icld_DisplayFlags
& ICONLIST_DISP_VERTICAL
)
1910 if (entry
->ie_AreaWidth
< maxw
)
1911 entry
->ie_IconX
+= ( maxw
- entry
->ie_AreaWidth
) / 2;
1914 gridy
= entry
->ie_AreaHeight
+ data
->icld__Option_IconVerticalSpacing
;
1918 /* Centering */ /* Icons look better not centered in this case - disabled */
1919 /* if (entry->ie_AreaHeight < maxh)
1920 entry->ie_IconY += ( maxh - entry->ie_AreaHeight ) / 2; */
1922 gridx
= entry
->ie_AreaWidth
+ data
->icld__Option_IconHorizontalSpacing
;
1929 * Advance to next icon and calculate its position based on grid sizes from previous step.
1930 * Don't set position - it is done at beginning of the loop.
1932 if ((entry
= (struct IconEntry
*)GetSucc(&entry
->ie_IconNode
)) != NULL
)
1936 if (data
->icld_DisplayFlags
& ICONLIST_DISP_VERTICAL
)
1940 if ((cur_y
>= data
->icld_ViewHeight
) ||
1941 ((data
->icld__Option_IconListMode
== ICON_LISTMODE_ROUGH
) && ((cur_y
+ entry
->ie_AreaHeight
- data
->icld__Option_IconBorderOverlap
) >= data
->icld_ViewHeight
)) ||
1942 ((data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
) && ((cur_y
+ data
->icld_IconAreaLargestHeight
- data
->icld__Option_IconBorderOverlap
) >= data
->icld_ViewHeight
)))
1944 /* Wrap "around" if the icon would be below bottom border */
1955 if ((cur_x
>= data
->icld_ViewWidth
) ||
1956 ((data
->icld__Option_IconListMode
== ICON_LISTMODE_ROUGH
) && ((cur_x
+ entry
->ie_AreaWidth
- data
->icld__Option_IconBorderOverlap
) >= data
->icld_ViewWidth
)) ||
1957 ((data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
) && ((cur_x
+ data
->icld_IconAreaLargestWidth
- data
->icld__Option_IconBorderOverlap
) >= data
->icld_ViewWidth
)))
1959 /* Wrap "around" if the icon would be right of right border */
1971 static VOID
IconList_Layout_PartialAutoLayout(struct IClass
*CLASS
, Object
*obj
)
1973 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
1974 struct Region
*occupied
= NewRegion();
1975 struct IconEntry
*entry
= NULL
;
1976 LONG left
= data
->icld__Option_IconHorizontalSpacing
;
1977 LONG top
= data
->icld__Option_IconVerticalSpacing
;
1978 LONG cur_x
= left
, cur_y
= top
;
1980 entry
= (struct IconEntry
*)GetHead(&data
->icld_IconList
);
1981 while (entry
!= NULL
)
1983 if ((entry
->ie_ProvidedIconX
!= NO_ICON_POSITION
) && (entry
->ie_ProvidedIconY
!= NO_ICON_POSITION
)
1984 && (entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
))
1986 struct Rectangle iconrect
= {
1987 entry
->ie_ProvidedIconX
,
1988 entry
->ie_ProvidedIconY
,
1989 entry
->ie_ProvidedIconX
+ entry
->ie_AreaWidth
- 1,
1990 entry
->ie_ProvidedIconY
+ entry
->ie_AreaHeight
- 1
1993 if (data
->icld_DisplayFlags
& ICONLIST_DISP_VERTICAL
)
1994 iconrect
.MaxY
+= data
->icld__Option_IconVerticalSpacing
;
1996 iconrect
.MaxX
+= data
->icld__Option_IconHorizontalSpacing
;
1998 D(bug("Adding %s (%d %d)(%d %d)\n", entry
->ie_TxtBuf_DisplayedLabel
,
1999 (LONG
)iconrect
.MinX
, (LONG
)iconrect
.MinY
, (LONG
)iconrect
.MaxX
, (LONG
)iconrect
.MaxY
));
2001 OrRectRegion(occupied
, &iconrect
);
2003 entry
= (struct IconEntry
*)GetSucc(&entry
->ie_IconNode
);
2006 /* Now go to the actual positioning */
2007 entry
= (struct IconEntry
*)GetHead(&data
->icld_IconList
);
2008 while (entry
!= NULL
)
2010 if ((entry
->ie_DiskObj
!= NULL
) && (entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
))
2012 if ((entry
->ie_ProvidedIconX
!= NO_ICON_POSITION
) && (entry
->ie_ProvidedIconY
!= NO_ICON_POSITION
))
2014 entry
->ie_IconX
= entry
->ie_ProvidedIconX
;
2015 entry
->ie_IconY
= entry
->ie_ProvidedIconY
;
2019 LONG gridx
, gridy
, stepx
= 0, stepy
= 0, addx
= 0;
2020 struct Rectangle iconarea
;
2023 /* Calculate grid size and step */
2024 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
2026 gridx
= data
->icld_IconAreaLargestWidth
+ data
->icld__Option_IconHorizontalSpacing
;
2027 gridy
= data
->icld_IconLargestHeight
+ data
->icld__Option_IconImageSpacing
+ data
->icld_LabelLargestHeight
+ data
->icld__Option_IconVerticalSpacing
;
2031 if (data
->icld_DisplayFlags
& ICONLIST_DISP_VERTICAL
)
2033 gridx
= data
->icld_IconAreaLargestWidth
; /* This gives better centering effect */
2034 gridy
= entry
->ie_AreaHeight
+ data
->icld__Option_IconVerticalSpacing
;
2035 addx
= (gridx
- entry
->ie_AreaWidth
) / 2;
2039 gridx
= entry
->ie_AreaWidth
+ data
->icld__Option_IconHorizontalSpacing
;
2040 gridy
= entry
->ie_AreaHeight
+ data
->icld__Option_IconVerticalSpacing
;
2044 /* Find first not occupied spot matching the calculate rectangle */
2047 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
2049 /* Overwrite value set via RegionAndRect */
2054 if (data
->icld_DisplayFlags
& ICONLIST_DISP_VERTICAL
)
2056 /* Advance to next position */
2057 if (!first
) cur_y
+= stepy
;
2059 if ((cur_y
>= data
->icld_ViewHeight
) ||
2060 ((cur_y
+ gridy
- data
->icld__Option_IconBorderOverlap
) >= data
->icld_ViewHeight
))
2062 /* Wrap "around" if the icon would be below bottom border */
2069 /* Advance to next position */
2070 if (!first
) cur_x
+= stepx
;
2072 if ((cur_x
>= data
->icld_ViewWidth
) ||
2073 ((cur_x
+ gridx
- data
->icld__Option_IconBorderOverlap
) >= data
->icld_ViewWidth
))
2075 /* Wrap "around" if the icon would be right of right border */
2081 iconarea
.MinX
= cur_x
;
2082 iconarea
.MinY
= cur_y
;
2083 iconarea
.MaxX
= cur_x
+ gridx
- 1;
2084 iconarea
.MaxY
= cur_y
+ gridy
- 1;
2088 } while(RegionAndRect(occupied
, &iconarea
, &stepx
, &stepy
));
2090 entry
->ie_IconX
= iconarea
.MinX
+ addx
;
2091 entry
->ie_IconY
= iconarea
.MinY
;
2093 /* Add this area to occupied list */
2094 OrRectRegion(occupied
, &iconarea
);
2096 /* Add spacing to next icon */
2097 if (data
->icld_DisplayFlags
& ICONLIST_DISP_VERTICAL
)
2104 entry
= (struct IconEntry
*)GetSucc(&entry
->ie_IconNode
);
2107 DisposeRegion(occupied
);
2111 ///IconList__MUIM_IconList_PositionIcons()
2112 /**************************************************************************
2113 MUIM_PositionIcons - Place icons with NO_ICON_POSITION coords somewhere
2114 **************************************************************************/
2115 IPTR
IconList__MUIM_IconList_PositionIcons(struct IClass
*CLASS
, Object
*obj
, struct MUIP_IconList_PositionIcons
*message
)
2117 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
2118 struct IconEntry
*entry
= NULL
;
2121 #if defined(DEBUG_ILC_ICONPOSITIONING) || defined(DEBUG_ILC_FUNCS)
2122 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
2124 if ((data
->icld_SortFlags
& MUIV_IconList_Sort_AutoSort
) == 0)
2126 IconList_Layout_PartialAutoLayout(CLASS
, obj
);
2130 IconList_Layout_FullAutoLayout(CLASS
, obj
);
2134 * Set Provided icon position on all icons (this can't be done as part of previous loop!)
2135 * The icons will not no longer be autolayouted unless MUIV_IconList_Sort_AutoSort is set.
2136 * This give the stability that new icons appearing won't make existing icons jump from their places
2138 entry
= (struct IconEntry
*)GetHead(&data
->icld_IconList
);
2139 while (entry
!= NULL
)
2141 if (entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
2142 DoMethod(obj
, MUIM_IconList_PropagateEntryPos
, entry
);
2144 entry
= (struct IconEntry
*)GetSucc(&entry
->ie_IconNode
);
2148 DoMethod(obj
, MUIM_IconList_RethinkDimensions
, NULL
);
2155 #define ICONENTRY_SIZE 16
2157 static inline void CalcHeight(struct ListViewModeAttribs
*LVMAttribs
, struct TextFont
*LabelFont
)
2159 ULONG YSize
= LabelFont
? LabelFont
->tf_YSize
: 0;
2161 LVMAttribs
->lmva_HeaderHeight
= HEADERLINE_EXTRAHEIGHT
+ YSize
;
2162 LVMAttribs
->lmva_RowHeight
= LINE_EXTRAHEIGHT
+ ((ICONENTRY_SIZE
> YSize
) ? ICONENTRY_SIZE
: YSize
);
2165 /**************************************************************************
2167 **************************************************************************/
2168 IPTR
IconList__OM_NEW(struct IClass
*CLASS
, Object
*obj
, struct opSet
*message
)
2170 struct IconList_DATA
*data
= NULL
;
2171 struct TextFont
*icl_WindowFont
= NULL
;
2172 // struct RastPort *icl_RastPort = NULL;
2175 #if defined(DEBUG_ILC_FUNCS)
2176 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
2179 icl_WindowFont
= (struct TextFont
*) GetTagData(MUIA_Font
, (IPTR
) NULL
, message
->ops_AttrList
);
2181 obj
= (Object
*)DoSuperNewTags(CLASS
, obj
, NULL
,
2182 MUIA_FillArea
, FALSE
,
2183 MUIA_Dropable
, TRUE
,
2184 MUIA_Font
, MUIV_Font_Tiny
,
2185 TAG_MORE
, (IPTR
) message
->ops_AttrList
);
2187 if (!obj
) return FALSE
;
2189 data
= INST_DATA(CLASS
, obj
);
2191 data
->icld_Pool
= CreatePool(0,4096,4096);
2192 if (!data
->icld_Pool
)
2194 CoerceMethod(CLASS
,obj
,OM_DISPOSE
);
2198 #if defined(DEBUG_ILC_FUNCS)
2199 D(bug("[IconList] %s: SELF = 0x%p, muiRenderInfo = 0x%p\n", __PRETTY_FUNCTION__
, obj
, muiRenderInfo(obj
)));
2201 NewList((struct List
*)&data
->icld_IconList
);
2202 NewList((struct List
*)&data
->icld_SelectionList
);
2204 data
->icld_IconLabelFont
= icl_WindowFont
;
2206 /* Setup List View-Mode options */
2207 if ((data
->icld_LVMAttribs
= AllocMem(sizeof(struct ListViewModeAttribs
), MEMF_CLEAR
)) != NULL
)
2209 for(i
= 0; i
< NUM_COLUMNS
; i
++)
2211 data
->icld_LVMAttribs
->lmva_ColumnPos
[i
] = i
;
2212 data
->icld_LVMAttribs
->lmva_ColumnFlags
[i
] = LVMCF_COLVISIBLE
;
2213 data
->icld_LVMAttribs
->lmva_ColumnWidth
[i
] = 100;
2214 data
->icld_LVMAttribs
->lmva_ColumnHAlign
[i
] = COLUMN_ALIGN_LEFT
;
2218 data
->icld_LVMAttribs
->lmva_ColumnHAlign
[i
] = COLUMN_ALIGN_RIGHT
;
2219 data
->icld_LVMAttribs
->lmva_ColumnFlags
[i
] |= (LVMCF_COLCLICKABLE
|LVMCF_COLSORTABLE
);
2220 data
->icld_LVMAttribs
->lmva_ColumnTitle
[i
] = "Type";
2221 data
->icld_LVMAttribs
->lmva_ColumnWidth
[i
] = ICONENTRY_SIZE
+ 2;
2225 data
->icld_LVMAttribs
->lmva_ColumnFlags
[i
] |= (LVMCF_COLCLICKABLE
|LVMCF_COLSORTABLE
);
2226 data
->icld_LVMAttribs
->lmva_ColumnTitle
[i
] = "Name";
2230 data
->icld_LVMAttribs
->lmva_ColumnHAlign
[i
] = COLUMN_ALIGN_RIGHT
;
2231 data
->icld_LVMAttribs
->lmva_ColumnFlags
[i
] |= LVMCF_COLSORTABLE
;
2232 data
->icld_LVMAttribs
->lmva_ColumnTitle
[i
] = "Size";
2235 case INDEX_LASTACCESS
:
2236 data
->icld_LVMAttribs
->lmva_ColumnFlags
[i
] |= LVMCF_COLSORTABLE
;
2237 data
->icld_LVMAttribs
->lmva_ColumnTitle
[i
] = "Last Accessed";
2241 data
->icld_LVMAttribs
->lmva_ColumnTitle
[i
] = "Comment";
2244 case INDEX_PROTECTION
:
2245 data
->icld_LVMAttribs
->lmva_ColumnTitle
[i
] = "Protection";
2249 data
->icld_LVMAttribs
->lmva_ColumnTitle
[i
] = "<Unknown>";
2253 data
->icld_LVMAttribs
->lmva_LastSelectedColumn
= -1;
2254 data
->icld_LVMAttribs
->lmva_SortColumn
= INDEX_NAME
;
2255 data
->icld_LVMAttribs
->lvma_Flags
= LVMAF_HEADERDRAWTOEND
;
2257 * Seems to be not needed because it's done in MUIM_Setup. No rendering happens before it.
2258 * Height calculation moved to MUIM_Setup because font pointer can be NULL here (if user-specified
2259 * font failed to open). In this case we fail back to the font specified in MUI's AreaData, but
2260 * it becomes known only in MUIM_Setup
2262 CalcHeight(data->icld_LVMAttribs, data->icld_IconLabelFont); */
2265 /* Get/Set initial values */
2266 /* TODO: TrimVolumeNames should be prefs settable */
2267 data
->icld__Option_TrimVolumeNames
= TRUE
;
2268 /* TODO: Adjust overlap by window border width */
2269 data
->icld__Option_IconBorderOverlap
= 10;
2271 data
->icld__Option_IconListMode
= (UBYTE
)GetTagData(MUIA_IconList_IconListMode
, 0, message
->ops_AttrList
);
2272 data
->icld__Option_LabelTextMode
= (UBYTE
)GetTagData(MUIA_IconList_LabelText_Mode
, 0, message
->ops_AttrList
);
2273 data
->icld__Option_LabelTextMaxLen
= (ULONG
)GetTagData(MUIA_IconList_LabelText_MaxLineLen
, ILC_ICONLABEL_MAXLINELEN_DEFAULT
, message
->ops_AttrList
);
2274 data
->icld__Option_DragImageTransparent
= (BOOL
)GetTagData(MUIA_IconList_DragImageTransparent
, FALSE
, message
->ops_AttrList
);
2276 if ( data
->icld__Option_LabelTextMaxLen
< ILC_ICONLABEL_SHORTEST
)
2277 data
->icld__Option_LabelTextMaxLen
= ILC_ICONLABEL_MAXLINELEN_DEFAULT
;
2279 data
->icld__Option_LastLabelTextMaxLen
= data
->icld__Option_LabelTextMaxLen
;
2281 #if defined(DEBUG_ILC_FUNCS)
2282 D(bug("[IconList] %s: MaxLineLen : %ld\n", __PRETTY_FUNCTION__
, data
->icld__Option_LabelTextMaxLen
));
2284 data
->ehn
.ehn_Events
= IDCMP_MOUSEBUTTONS
| IDCMP_RAWKEY
| IDCMP_NEWSIZE
| IDCMP_MENUVERIFY
;
2285 data
->ehn
.ehn_Priority
= 0;
2286 data
->ehn
.ehn_Flags
= 0;
2287 data
->ehn
.ehn_Object
= obj
;
2288 data
->ehn
.ehn_Class
= CLASS
;
2290 data
->icld_SortFlags
= MUIV_IconList_Sort_ByName
;
2291 data
->icld_DisplayFlags
= ICONLIST_DISP_SHOWINFO
;
2293 __iconlist_UpdateLabels_hook
.h_Entry
= (HOOKFUNC
)IconList__HookFunc_UpdateLabelsFunc
;
2297 obj
, MUIM_Notify
, MUIA_IconList_LabelText_MaxLineLen
, MUIV_EveryTime
,
2299 MUIM_CallHook
, &__iconlist_UpdateLabels_hook
, (IPTR
)CLASS
2304 obj
, MUIM_Notify
, MUIA_IconList_LabelText_MultiLine
, MUIV_EveryTime
,
2306 MUIM_CallHook
, &__iconlist_UpdateLabels_hook
, (IPTR
)CLASS
2309 #if defined(DEBUG_ILC_FUNCS)
2310 D(bug("[IconList] obj = %ld\n", obj
));
2317 /**************************************************************************
2319 **************************************************************************/
2320 IPTR
IconList__OM_DISPOSE(struct IClass
*CLASS
, Object
*obj
, Msg message
)
2322 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
2323 struct IconEntry
*node
= NULL
;
2325 #if defined(DEBUG_ILC_FUNCS)
2326 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
2329 #if defined(__AROS__)
2330 ForeachNode(&data
->icld_IconList
, node
)
2332 Foreach_Node(&data
->icld_IconList
, node
);
2335 if (node
->ie_DiskObj
)
2336 FreeDiskObject(node
->ie_DiskObj
);
2339 if (data
->icld_Pool
) DeletePool(data
->icld_Pool
);
2341 DoSuperMethodA(CLASS
,obj
,message
);
2347 /**************************************************************************
2349 **************************************************************************/
2350 IPTR
IconList__OM_SET(struct IClass
*CLASS
, Object
*obj
, struct opSet
*message
)
2352 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
2353 struct TagItem
*tag
= NULL
,
2356 WORD oldleft
= data
->icld_ViewX
,
2357 oldtop
= data
->icld_ViewY
;
2358 //oldwidth = data->icld_ViewWidth,
2359 //oldheight = data->icld_ViewHeight;
2361 #if defined(DEBUG_ILC_FUNCS) || defined(DEBUG_ILC_ATTRIBS)
2362 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
2365 /* parse initial taglist */
2366 for (tags
= message
->ops_AttrList
; (tag
= NextTagItem((TAGITEM
)&tags
)); )
2368 switch (tag
->ti_Tag
)
2370 case MUIA_Virtgroup_Left
:
2371 #if defined(DEBUG_ILC_ATTRIBS)
2372 D(bug("[IconList] %s: MUIA_Virtgroup_Left %ld\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2374 if (data
->icld_ViewX
!= tag
->ti_Data
)
2375 data
->icld_ViewX
= tag
->ti_Data
;
2378 case MUIA_Virtgroup_Top
:
2379 #if defined(DEBUG_ILC_ATTRIBS)
2380 D(bug("[IconList] %s: MUIA_Virtgroup_Top %ld\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2382 if (data
->icld_ViewY
!= tag
->ti_Data
)
2383 data
->icld_ViewY
= tag
->ti_Data
;
2386 case MUIA_IconList_Rastport
:
2387 #if defined(DEBUG_ILC_ATTRIBS)
2388 D(bug("[IconList] %s: MUIA_IconList_Rastport 0x%p\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2390 data
->icld_DisplayRastPort
= (struct RastPort
*)tag
->ti_Data
;
2391 data
->icld_DrawOffsetX
= _mleft(obj
);
2392 data
->icld_DrawOffsetY
= _mtop(obj
);
2393 if (data
->icld_BufferRastPort
!= NULL
)
2395 //Buffer still set!?!?!
2397 SET(obj
, MUIA_IconList_BufferRastport
, tag
->ti_Data
);
2400 case MUIA_IconList_BufferRastport
:
2401 #if defined(DEBUG_ILC_ATTRIBS)
2402 D(bug("[IconList] %s: MUIA_IconList_BufferRastport 0x%p\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2404 data
->icld_BufferRastPort
= (struct RastPort
*)tag
->ti_Data
;
2408 #if defined(DEBUG_ILC_ATTRIBS)
2409 D(bug("[IconList] %s: MUIA_Font 0x%p\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2411 data
->icld_IconLabelFont
= (struct TextFont
*)tag
->ti_Data
;
2412 /* FIXME: Should we call CalcHeight() here because our font changed? */
2415 case MUIA_IconList_LabelInfoText_Font
:
2416 #if defined(DEBUG_ILC_ATTRIBS)
2417 D(bug("[IconList] %s: MUIA_IconList_LabelInfoText_Font 0x%p\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2419 data
->icld_IconInfoFont
= (struct TextFont
*)tag
->ti_Data
;
2422 case MUIA_IconList_DisplayFlags
:
2424 #if defined(DEBUG_ILC_ATTRIBS)
2425 D(bug("[IconList] %s: MUIA_IconList_DisplayFlags %08x\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2427 // ULONG origModeFlags = data->icld_DisplayFlags & (ICONLIST_DISP_MODEDEFAULT|ICONLIST_DISP_MODELABELRIGHT|ICONLIST_DISP_MODELIST);
2428 data
->icld_DisplayFlags
= (ULONG
)tag
->ti_Data
;
2430 if (data
->icld_DisplayFlags
& ICONLIST_DISP_BUFFERED
)
2432 #if defined(DEBUG_ILC_ATTRIBS) || defined(DEBUG_ILC_ICONRENDERING)
2433 D(bug("[IconList] %s: MUIA_IconList_DisplayFlags & ICONLIST_DISP_BUFFERED\n", __PRETTY_FUNCTION__
));
2435 if ((data
->icld_BufferRastPort
!= NULL
)
2436 && (data
->icld_BufferRastPort
!= data
->icld_DisplayRastPort
))
2438 #if defined(DEBUG_ILC_ATTRIBS) || defined(DEBUG_ILC_ICONRENDERING)
2439 D(bug("[IconList] %s: BackLayer @ %p for BackRastport @ %p\n", __PRETTY_FUNCTION__
, data
->icld_BufferRastPort
->Layer
, data
->icld_BufferRastPort
));
2441 if ((GetBitMapAttr(data
->icld_BufferRastPort
->BitMap
, BMA_WIDTH
) != data
->icld_ViewWidth
)
2442 || (GetBitMapAttr(data
->icld_BufferRastPort
->BitMap
, BMA_HEIGHT
) != data
->icld_ViewHeight
))
2444 struct Layer
*oldLayer
= data
->icld_BufferRastPort
->Layer
;
2445 #if defined(DEBUG_ILC_ATTRIBS) || defined(DEBUG_ILC_ICONRENDERING)
2446 D(bug("[IconList] %s: Destroying old BackLayer\n", __PRETTY_FUNCTION__
));
2448 data
->icld_BufferRastPort
= data
->icld_DisplayRastPort
;
2449 DeleteLayer(0, oldLayer
);
2453 if ((data
->icld_BufferRastPort
== NULL
) || (data
->icld_BufferRastPort
== data
->icld_DisplayRastPort
))
2455 struct BitMap
*bitmap_New
= NULL
;
2456 ULONG tmp_RastDepth
;
2457 struct Layer_Info
*li
= NULL
;
2459 tmp_RastDepth
= GetCyberMapAttr(data
->icld_DisplayRastPort
->BitMap
, CYBRMATTR_DEPTH
);
2460 if ((bitmap_New
= AllocBitMap(data
->icld_ViewWidth
,
2461 data
->icld_ViewHeight
,
2464 data
->icld_DisplayRastPort
->BitMap
))!=NULL
)
2466 if ((data
->icld_BufferRastPort
= CreateRastPort())!=NULL
)
2468 data
->icld_BufferRastPort
->BitMap
= bitmap_New
;
2469 if ((li
= NewLayerInfo()))
2471 if ((data
->icld_BufferRastPort
->Layer
= CreateUpfrontLayer(li
, data
->icld_BufferRastPort
->BitMap
, 0, 0, data
->icld_ViewWidth
- 1, data
->icld_ViewHeight
- 1, 0, NULL
)))
2474 * Mark it as a buffered rastport.
2477 #if defined(DEBUG_ILC_ATTRIBS) || defined(DEBUG_ILC_ICONRENDERING)
2478 D(bug("[IconList] %s: FrontRastPort @ %p, New BackLayer @ %p, BackRastport @ %p\n", __PRETTY_FUNCTION__
, data
->icld_DisplayRastPort
, data
->icld_BufferRastPort
->Layer
, data
->icld_BufferRastPort
));
2480 SET(obj
, MUIA_IconList_BufferRastport
, data
->icld_BufferRastPort
);
2481 data
->icld_DrawOffsetX
= 0;
2482 data
->icld_DrawOffsetY
= 0;
2485 data
->icld_BufferRastPort
= data
->icld_DisplayRastPort
;
2488 data
->icld_BufferRastPort
= data
->icld_DisplayRastPort
;
2491 data
->icld_BufferRastPort
= data
->icld_DisplayRastPort
;
2493 if (data
->icld_BufferRastPort
== data
->icld_DisplayRastPort
)
2495 if (bitmap_New
) FreeBitMap(bitmap_New
);
2496 if (li
) DisposeLayerInfo(li
);
2497 data
->icld_DrawOffsetX
= _mleft(obj
);
2498 data
->icld_DrawOffsetY
= _mtop(obj
);
2504 if ((data
->icld_BufferRastPort
) && (data
->icld_BufferRastPort
!= data
->icld_DisplayRastPort
))
2506 //Free up the buffers layer, rastport and bitmap since they are no longer needed ..
2507 struct Layer
*oldLayer
= data
->icld_BufferRastPort
->Layer
;
2508 data
->icld_BufferRastPort
= data
->icld_DisplayRastPort
;
2509 InstallClipRegion(oldLayer
, NULL
);
2510 DeleteLayer(0, oldLayer
);
2511 FreeBitMap(data
->icld_BufferRastPort
->BitMap
);
2512 data
->icld_DrawOffsetX
= _mleft(obj
);
2513 data
->icld_DrawOffsetY
= _mtop(obj
);
2516 SET(obj
, MUIA_IconList_Changed
, TRUE
);
2520 case MUIA_IconList_SortFlags
:
2521 #if defined(DEBUG_ILC_ATTRIBS)
2522 D(bug("[IconList] %s: MUIA_IconList_SortFlags %08x\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2524 data
->icld_SortFlags
= (ULONG
)tag
->ti_Data
;
2527 case MUIA_IconList_DragImageTransparent
:
2528 data
->icld__Option_DragImageTransparent
= (BOOL
)tag
->ti_Data
;
2531 case MUIA_IconList_IconListMode
:
2532 #if defined(DEBUG_ILC_ATTRIBS)
2533 D(bug("[IconList] %s: MUIA_IconList_IconListMode %d\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2535 data
->icld__Option_IconListMode
= (UBYTE
)tag
->ti_Data
;
2538 case MUIA_IconList_LabelText_Mode
:
2539 #if defined(DEBUG_ILC_ATTRIBS)
2540 D(bug("[IconList] %s: MUIA_IconList_LabelText_Mode %d\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2542 data
->icld__Option_LabelTextMode
= (UBYTE
)tag
->ti_Data
;
2545 case MUIA_IconList_LabelText_MaxLineLen
:
2546 #if defined(DEBUG_ILC_ATTRIBS)
2547 D(bug("[IconList] %s: MUIA_IconList_LabelText_MaxLineLen %d\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2549 if (tag
->ti_Data
>= ILC_ICONLABEL_SHORTEST
)
2551 data
->icld__Option_LabelTextMaxLen
= (ULONG
)tag
->ti_Data
;
2555 data
->icld__Option_LabelTextMaxLen
= ILC_ICONLABEL_MAXLINELEN_DEFAULT
;
2559 case MUIA_IconList_LabelText_MultiLine
:
2560 #if defined(DEBUG_ILC_ATTRIBS)
2561 D(bug("[IconList] %s: MUIA_IconList_LabelText_MultiLine %d\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2563 data
->icld__Option_LabelTextMultiLine
= (ULONG
)tag
->ti_Data
;
2564 if (data
->icld__Option_LabelTextMultiLine
== 0)data
->icld__Option_LabelTextMultiLine
= 1;
2567 case MUIA_IconList_LabelText_MultiLineOnFocus
:
2568 #if defined(DEBUG_ILC_ATTRIBS)
2569 D(bug("[IconList] %s: MUIA_IconList_LabelText_MultiLineOnFocus %d\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2571 data
->icld__Option_LabelTextMultiLineOnFocus
= (BOOL
)tag
->ti_Data
;
2574 case MUIA_IconList_Icon_HorizontalSpacing
:
2575 #if defined(DEBUG_ILC_ATTRIBS)
2576 D(bug("[IconList] %s: MUIA_IconList_Icon_HorizontalSpacing %d\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2578 data
->icld__Option_IconHorizontalSpacing
= (UBYTE
)tag
->ti_Data
;
2581 case MUIA_IconList_Icon_VerticalSpacing
:
2582 #if defined(DEBUG_ILC_ATTRIBS)
2583 D(bug("[IconList] %s: MUIA_IconList_Icon_VerticalSpacing %d\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2585 data
->icld__Option_IconVerticalSpacing
= (UBYTE
)tag
->ti_Data
;
2588 case MUIA_IconList_Icon_ImageSpacing
:
2589 #if defined(DEBUG_ILC_ATTRIBS)
2590 D(bug("[IconList] %s: MUIA_IconList_Icon_ImageSpacing %d\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2592 data
->icld__Option_IconImageSpacing
= (UBYTE
)tag
->ti_Data
;
2595 case MUIA_IconList_LabelText_HorizontalPadding
:
2596 #if defined(DEBUG_ILC_ATTRIBS)
2597 D(bug("[IconList] %s: MUIA_IconList_LabelText_HorizontalPadding %d\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2599 data
->icld__Option_LabelTextHorizontalPadding
= (UBYTE
)tag
->ti_Data
;
2602 case MUIA_IconList_LabelText_VerticalPadding
:
2603 #if defined(DEBUG_ILC_ATTRIBS)
2604 D(bug("[IconList] %s: MUIA_IconList_LabelText_VerticalPadding %d\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2606 data
->icld__Option_LabelTextVerticalPadding
= (UBYTE
)tag
->ti_Data
;
2609 case MUIA_IconList_LabelText_BorderWidth
:
2610 #if defined(DEBUG_ILC_ATTRIBS)
2611 D(bug("[IconList] %s: MUIA_IconList_LabelText_BorderWidth %d\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2613 data
->icld__Option_LabelTextBorderWidth
= (UBYTE
)tag
->ti_Data
;
2616 case MUIA_IconList_LabelText_BorderHeight
:
2617 #if defined(DEBUG_ILC_ATTRIBS)
2618 D(bug("[IconList] %s: MUIA_IconList_LabelText_BorderHeight %d\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2620 data
->icld__Option_LabelTextBorderHeight
= (UBYTE
)tag
->ti_Data
;
2623 case MUIA_IconList_LabelText_Pen
:
2624 data
->icld_LabelPen
= (ULONG
)tag
->ti_Data
;
2627 case MUIA_IconList_LabelText_ShadowPen
:
2628 data
->icld_LabelShadowPen
= (ULONG
)tag
->ti_Data
;
2631 case MUIA_IconList_LabelInfoText_Pen
:
2632 data
->icld_InfoPen
= (ULONG
)tag
->ti_Data
;
2635 case MUIA_IconList_LabelInfoText_ShadowPen
:
2636 data
->icld_InfoShadowPen
= (ULONG
)tag
->ti_Data
;
2639 /* Settings defined by the view class */
2640 case MUIA_IconListview_FixedBackground
:
2641 #if defined(DEBUG_ILC_ATTRIBS)
2642 D(bug("[IconList] %s: MUIA_IconListview_FixedBackground\n", __PRETTY_FUNCTION__
));
2644 data
->icld__Option_IconListFixedBackground
= (BOOL
)tag
->ti_Data
;
2647 case MUIA_IconListview_ScaledBackground
:
2648 #if defined(DEBUG_ILC_ATTRIBS)
2649 D(bug("[IconList] %s: MUIA_IconListview_ScaledBackground\n", __PRETTY_FUNCTION__
));
2651 data
->icld__Option_IconListScaledBackground
= (BOOL
)tag
->ti_Data
;
2654 /* We listen for MUIA_Background and set default values for known types */
2655 case MUIA_Background
:
2656 #if defined(DEBUG_ILC_ATTRIBS) || defined(DEBUG_ILC_ICONRENDERING)
2657 D(bug("[IconList] %s: MUIA_Background\n", __PRETTY_FUNCTION__
));
2660 char *bgmode_string
= (char *)tag
->ti_Data
;
2661 BYTE this_mode
= bgmode_string
[0] - 48;
2663 #if defined(DEBUG_ILC_ATTRIBS) || defined(DEBUG_ILC_ICONRENDERING)
2664 D(bug("[IconList] %s: MUIA_Background | MUI BG Mode = %d\n", __PRETTY_FUNCTION__
, this_mode
));
2670 NNSET(obj
, MUIA_IconListview_FixedBackground
, FALSE
);
2671 NNSET(obj
, MUIA_IconListview_ScaledBackground
, FALSE
);
2675 NNSET(obj
, MUIA_IconListview_FixedBackground
, FALSE
);
2676 NNSET(obj
, MUIA_IconListview_ScaledBackground
, FALSE
);
2680 NNSET(obj
, MUIA_IconListview_FixedBackground
, TRUE
);
2681 NNSET(obj
, MUIA_IconListview_ScaledBackground
, TRUE
);
2685 NNSET(obj
, MUIA_IconListview_FixedBackground
, FALSE
);
2686 NNSET(obj
, MUIA_IconListview_ScaledBackground
, FALSE
);
2691 case MUIA_IconList_IconsDropped
:
2692 data
->icld_DragDropEvent
= (struct IconList_Drop_Event
*)tag
->ti_Data
;
2697 #if defined(DEBUG_ILC_ATTRIBS)
2698 D(bug("[IconList] %s(), out of switch\n", __PRETTY_FUNCTION__
));
2700 if ((oldleft
!= data
->icld_ViewX
) || (oldtop
!= data
->icld_ViewY
))
2702 data
->icld_UpdateMode
= UPDATE_SCROLL
;
2703 data
->update_scrolldx
= data
->icld_ViewX
- oldleft
;
2704 data
->update_scrolldy
= data
->icld_ViewY
- oldtop
;
2705 #if defined(DEBUG_ILC_ATTRIBS)
2706 D(bug("[IconList] %s(), call MUI_Redraw()\n", __PRETTY_FUNCTION__
));
2708 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
2711 #if defined(DEBUG_ILC_ATTRIBS)
2712 D(bug("[IconList] %s(), call DoSuperMethodA()\n", __PRETTY_FUNCTION__
));
2714 return DoSuperMethodA(CLASS
, obj
, (Msg
)message
);
2719 /**************************************************************************
2721 **************************************************************************/
2722 IPTR
IconList__OM_GET(struct IClass
*CLASS
, Object
*obj
, struct opGet
*message
)
2724 /* small macro to simplify return value storage */
2725 #define STORE *(message->opg_Storage)
2726 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
2728 #if defined(DEBUG_ILC_FUNCS) || defined(DEBUG_ILC_ATTRIBS)
2729 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
2732 switch (message
->opg_AttrID
)
2734 case MUIA_IconList_Rastport
: STORE
= (IPTR
)data
->icld_DisplayRastPort
; return 1;
2735 case MUIA_IconList_BufferRastport
: STORE
= (IPTR
)data
->icld_BufferRastPort
; return 1;
2736 case MUIA_IconList_BufferLeft
: STORE
= (IPTR
)data
->icld_DrawOffsetX
; return 1;
2737 case MUIA_IconList_BufferTop
: STORE
= (IPTR
)data
->icld_DrawOffsetY
; return 1;
2738 case MUIA_IconList_BufferWidth
:
2739 case MUIA_IconList_Width
: STORE
= (IPTR
)data
->icld_AreaWidth
; return 1;
2740 case MUIA_IconList_BufferHeight
:
2741 case MUIA_IconList_Height
: STORE
= (IPTR
)data
->icld_AreaHeight
; return 1;
2742 case MUIA_IconList_IconsDropped
: STORE
= (IPTR
)data
->icld_DragDropEvent
; return 1;
2743 case MUIA_IconList_Clicked
: STORE
= (IPTR
)&data
->icld_ClickEvent
; return 1;
2744 case MUIA_IconList_IconListMode
: STORE
= (IPTR
)data
->icld__Option_IconListMode
; return 1;
2745 case MUIA_IconList_LabelText_Mode
: STORE
= (IPTR
)data
->icld__Option_LabelTextMode
; return 1;
2746 case MUIA_IconList_LabelText_MaxLineLen
: STORE
= (IPTR
)data
->icld__Option_LabelTextMaxLen
; return 1;
2747 case MUIA_IconList_LabelText_MultiLine
: STORE
= (IPTR
)data
->icld__Option_LabelTextMultiLine
; return 1;
2748 case MUIA_IconList_LabelText_MultiLineOnFocus
: STORE
= (IPTR
)data
->icld__Option_LabelTextMultiLineOnFocus
; return 1;
2749 case MUIA_IconList_DisplayFlags
: STORE
= (IPTR
)data
->icld_DisplayFlags
; return 1;
2750 case MUIA_IconList_SortFlags
: STORE
= (IPTR
)data
->icld_SortFlags
; return 1;
2752 case MUIA_IconList_FocusIcon
: STORE
= (IPTR
)data
->icld_FocusIcon
; return 1;
2754 case MUIA_Font
: STORE
= (IPTR
)data
->icld_IconLabelFont
; return 1;
2755 case MUIA_IconList_LabelText_Pen
: STORE
= (IPTR
)data
->icld_LabelPen
; return 1;
2756 case MUIA_IconList_LabelText_ShadowPen
: STORE
= (IPTR
)data
->icld_LabelShadowPen
; return 1;
2757 case MUIA_IconList_LabelInfoText_Font
: STORE
= (IPTR
)data
->icld_IconInfoFont
; return 1;
2758 case MUIA_IconList_LabelInfoText_Pen
: STORE
= (IPTR
)data
->icld_InfoPen
; return 1;
2759 case MUIA_IconList_LabelInfoText_ShadowPen
: STORE
= (IPTR
)data
->icld_InfoShadowPen
; return 1;
2760 case MUIA_IconList_DragImageTransparent
: STORE
= (IPTR
)data
->icld__Option_DragImageTransparent
; return 1;
2762 case MUIA_IconList_Icon_HorizontalSpacing
: STORE
= (IPTR
)data
->icld__Option_IconHorizontalSpacing
; return 1;
2763 case MUIA_IconList_Icon_VerticalSpacing
: STORE
= (IPTR
)data
->icld__Option_IconVerticalSpacing
; return 1;
2764 case MUIA_IconList_Icon_ImageSpacing
: STORE
= (IPTR
)data
->icld__Option_IconImageSpacing
; return 1;
2765 case MUIA_IconList_LabelText_HorizontalPadding
: STORE
= (IPTR
)data
->icld__Option_LabelTextHorizontalPadding
; return 1;
2766 case MUIA_IconList_LabelText_VerticalPadding
: STORE
= (IPTR
)data
->icld__Option_LabelTextVerticalPadding
; return 1;
2767 case MUIA_IconList_LabelText_BorderWidth
: STORE
= (IPTR
)data
->icld__Option_LabelTextBorderWidth
; return 1;
2768 case MUIA_IconList_LabelText_BorderHeight
: STORE
= (IPTR
)data
->icld__Option_LabelTextBorderHeight
; return 1;
2770 /* Settings defined by the view class */
2771 case MUIA_IconListview_FixedBackground
: STORE
= (IPTR
)data
->icld__Option_IconListFixedBackground
; return 1;
2772 case MUIA_IconListview_ScaledBackground
: STORE
= (IPTR
)data
->icld__Option_IconListScaledBackground
; return 1;
2774 /* ICON obj Changes */
2775 case MUIA_Virtgroup_Left
: STORE
= (IPTR
)data
->icld_ViewX
; return 1;
2776 case MUIA_Virtgroup_Top
: STORE
= (IPTR
)data
->icld_ViewY
; return 1;
2777 case MUIA_Family_List
: STORE
= (IPTR
)&(data
->icld_IconList
); return 1; /* Get our list object */
2779 /* TODO: Get the version/revision from our config.. */
2780 case MUIA_Version
: STORE
= (IPTR
)1; return 1;
2781 case MUIA_Revision
: STORE
= (IPTR
)7; return 1;
2784 return DoSuperMethodA(CLASS
, obj
, (Msg
) message
);
2789 IPTR
IconList__MUIM_Family_AddHead(struct IClass
*CLASS
, Object
*obj
, struct MUIP_Family_AddHead
*message
)
2791 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
2792 #if defined(DEBUG_ILC_FUNCS)
2793 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
2798 /* TODO: Use the correct _OBJECT() code when we switch to icon.mui */
2799 // AddHead(&(data->icld_IconList), (struct Node *)_OBJECT(message->obj));
2800 AddHead(&(data
->icld_IconList
), (struct Node
*)message
->obj
);
2807 IPTR
IconList__MUIM_Family_AddTail(struct IClass
*CLASS
, Object
*obj
, struct MUIP_Family_AddTail
*message
)
2809 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
2810 #if defined(DEBUG_ILC_FUNCS)
2811 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
2814 D(bug("[IconList] %s: list @ 0x%p, entry @ 0x%p '%s'\n", __PRETTY_FUNCTION__
, &(data
->icld_IconList
), message
->obj
, ((struct IconEntry
*)message
->obj
)->ie_IconNode
.ln_Name
));
2818 /* TODO: Use the correct _OBJECT() code when we switch to icon.mui */
2819 // AddTail(&(data->icld_IconList), (struct Node *)_OBJECT(message->obj));
2820 AddTail(&(data
->icld_IconList
), (struct Node
*)message
->obj
);
2828 #if !defined(WANDERER_BUILTIN_ICONLIST)
2829 IPTR
IconList__OM_ADDMEMBER(struct IClass
*CLASS
, Object
*obj
, struct MUIP_Family_AddTail
*message
)
2831 return IconList__MUIM_Family_AddTail(CLASS
, obj
, message
);
2835 IPTR
IconList__MUIM_Family_Remove(struct IClass
*CLASS
, Object
*obj
, struct MUIP_Family_Remove
*message
)
2837 // struct IconList_DATA *data = INST_DATA(CLASS, obj);
2838 #if defined(DEBUG_ILC_FUNCS)
2839 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
2842 D(bug("[IconList] %s: entry @ 0x%p '%s'\n", __PRETTY_FUNCTION__
, message
->obj
, ((struct IconEntry
*)message
->obj
)->ie_IconNode
.ln_Name
));
2846 /* TODO: Use the correct _OBJECT() code when we switch to icon.mui */
2847 // Remove((struct Node *)_OBJECT(message->obj));
2848 Remove((struct Node
*)message
->obj
);
2856 #if !defined(WANDERER_BUILTIN_ICONLIST)
2857 IPTR
IconList__OM_REMMEMBER(struct IClass
*CLASS
, Object
*obj
, struct MUIP_Family_Remove
*message
)
2859 return IconList__MUIM_Family_Remove(CLASS
, obj
, message
);
2864 /**************************************************************************
2866 **************************************************************************/
2867 IPTR
IconList__MUIM_Setup(struct IClass
*CLASS
, Object
*obj
, struct MUIP_Setup
*message
)
2869 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
2870 struct IconEntry
*node
= NULL
;
2871 IPTR geticon_error
= 0, iconlistScreen
;
2873 #if defined(DEBUG_ILC_FUNCS)
2874 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
2877 if (!DoSuperMethodA(CLASS
, obj
, (Msg
) message
)) return (IPTR
)NULL
;
2879 iconlistScreen
= (IPTR
)_screen(obj
);
2880 #if defined(DEBUG_ILC_ICONRENDERING)
2881 D(bug("[IconList] %s: IconList Screen @ 0x%p)\n", __PRETTY_FUNCTION__
, iconlistScreen
));
2884 DoMethod(_win(obj
), MUIM_Window_AddEventHandler
, (IPTR
)&data
->ehn
);
2886 /* Get Internal Objects to use if not set .. */
2887 data
->icld_DisplayRastPort
= NULL
;
2888 data
->icld_BufferRastPort
= NULL
;
2890 if (data
->icld_IconLabelFont
== NULL
) data
->icld_IconLabelFont
= _font(obj
);
2891 if (data
->icld_IconInfoFont
== NULL
) data
->icld_IconInfoFont
= data
->icld_IconLabelFont
;
2894 * Here we have our font, either from user preferences or from MUI's AreaData.
2895 * It's right time to set up some sizes.
2897 if (data
->icld_LVMAttribs
)
2898 CalcHeight(data
->icld_LVMAttribs
, data
->icld_IconLabelFont
);
2899 #if defined(DEBUG_ILC_ICONRENDERING)
2900 D(bug("[IconList] %s: Use Font @ 0x%p, RastPort @ 0x%p\n", __PRETTY_FUNCTION__
, data
->icld_IconLabelFont
, data
->icld_BufferRastPort
));
2903 /* Set our base options .. */
2904 data
->icld_LabelPen
= _pens(obj
)[MPEN_SHINE
];
2905 data
->icld_LabelShadowPen
= _pens(obj
)[MPEN_SHADOW
];
2906 data
->icld_InfoPen
= _pens(obj
)[MPEN_SHINE
];
2907 data
->icld_InfoShadowPen
= _pens(obj
)[MPEN_SHADOW
];
2909 data
->icld__Option_LabelTextMultiLine
= 1;
2910 data
->icld__Option_LastLabelTextMultiLine
= data
->icld__Option_LabelTextMultiLine
;
2912 data
->icld__Option_LabelTextMultiLineOnFocus
= FALSE
;
2914 data
->icld__Option_IconHorizontalSpacing
= ILC_ICON_HORIZONTALMARGIN_DEFAULT
;
2915 data
->icld__Option_IconVerticalSpacing
= ILC_ICON_VERTICALMARGIN_DEFAULT
;
2916 data
->icld__Option_IconImageSpacing
= ILC_ICONLABEL_IMAGEMARGIN_DEFAULT
;
2917 data
->icld__Option_LabelTextHorizontalPadding
= ILC_ICONLABEL_HORIZONTALTEXTMARGIN_DEFAULT
;
2918 data
->icld__Option_LabelTextVerticalPadding
= ILC_ICONLABEL_VERTICALTEXTMARGIN_DEFAULT
;
2919 data
->icld__Option_LabelTextBorderWidth
= ILC_ICONLABEL_BORDERWIDTH_DEFAULT
;
2920 data
->icld__Option_LabelTextBorderHeight
= ILC_ICONLABEL_BORDERHEIGHT_DEFAULT
;
2922 if (data
->icld_LVMAttribs
)
2924 data
->icld_LVMAttribs
->lvma_IconDrawer
= GetIconTags
2926 "WANDERER:Icons/drawer",
2927 (iconlistScreen
) ? ICONGETA_Screen
: TAG_IGNORE
, iconlistScreen
,
2928 (iconlistScreen
) ? ICONGETA_RemapIcon
: TAG_IGNORE
, TRUE
,
2929 ICONGETA_FailIfUnavailable
, TRUE
,
2930 ICONGETA_GenerateImageMasks
, TRUE
,
2931 ICONA_ErrorCode
, &geticon_error
,
2935 #if defined(DEBUG_ILC_ICONRENDERING)
2936 if (data
->icld_LVMAttribs
->lvma_IconDrawer
== NULL
)
2938 D(bug("[IconList] %s: Couldnt get drawer DiskObject! (error code = 0x%p)\n", __PRETTY_FUNCTION__
, geticon_error
));
2941 data
->icld_LVMAttribs
->lvma_IconFile
= GetIconTags
2943 "WANDERER:Icons/file",
2944 (iconlistScreen
) ? ICONGETA_Screen
: TAG_IGNORE
, iconlistScreen
,
2945 (iconlistScreen
) ? ICONGETA_RemapIcon
: TAG_IGNORE
, TRUE
,
2946 ICONGETA_FailIfUnavailable
, TRUE
,
2947 ICONGETA_GenerateImageMasks
, TRUE
,
2948 ICONA_ErrorCode
, &geticon_error
,
2952 #if defined(DEBUG_ILC_ICONRENDERING)
2953 if (data
->icld_LVMAttribs
->lvma_IconFile
== NULL
)
2955 D(bug("[IconList] %s: Couldnt get file DiskObject! (error code = 0x%p)\n", __PRETTY_FUNCTION__
, geticon_error
));
2960 #if defined(__AROS__)
2961 ForeachNode(&data
->icld_IconList
, node
)
2963 Foreach_Node(&data
->icld_IconList
, node
);
2966 if (!node
->ie_DiskObj
)
2968 if (!(node
->ie_DiskObj
= GetIconTags(node
->ie_IconNode
.ln_Name
,
2969 (iconlistScreen
) ? ICONGETA_Screen
: TAG_IGNORE
, iconlistScreen
,
2970 (iconlistScreen
) ? ICONGETA_RemapIcon
: TAG_IGNORE
, TRUE
,
2971 ICONGETA_GenerateImageMasks
, TRUE
,
2972 ICONGETA_FailIfUnavailable
, FALSE
,
2973 ICONA_ErrorCode
, &geticon_error
,
2976 #if defined(DEBUG_ILC_ICONRENDERING)
2977 D(bug("[IconList] %s: Failed to obtain Entry '%s's diskobj! (error code = 0x%p)\n", __PRETTY_FUNCTION__
, node
->ie_IconNode
.ln_Name
, geticon_error
));
2979 /* We should probably remove this node if the entry cant be obtained ? */
2988 /**************************************************************************
2990 **************************************************************************/
2991 IPTR
IconList__MUIM_Show(struct IClass
*CLASS
, Object
*obj
, struct MUIP_Show
*message
)
2993 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
2998 #if defined(DEBUG_ILC_FUNCS)
2999 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
3002 if ((rc
= DoSuperMethodA(CLASS
, obj
, (Msg
)message
)))
3004 newleft
= data
->icld_ViewX
;
3005 newtop
= data
->icld_ViewY
;
3007 if (newleft
+ _mwidth(obj
) > data
->icld_AreaWidth
)
3008 newleft
= data
->icld_AreaWidth
- _mwidth(obj
);
3012 if (newtop
+ _mheight(obj
) > data
->icld_AreaHeight
)
3013 newtop
= data
->icld_AreaHeight
- _mheight(obj
);
3017 if ((newleft
!= data
->icld_ViewX
) || (newtop
!= data
->icld_ViewY
))
3019 SetAttrs(obj
, MUIA_Virtgroup_Left
, newleft
,
3020 MUIA_Virtgroup_Top
, newtop
,
3024 /* Get Internal Objects to use if not set .. */
3025 if (data
->icld_DisplayRastPort
== NULL
)
3027 if (_rp(obj
) != NULL
)
3029 data
->icld_DisplayRastPort
= CloneRastPort(_rp(obj
));
3031 #if defined(DEBUG_ILC_ICONRENDERING)
3034 D(bug("[IconList] IconList__MUIM_Show: ERROR - NULL RastPort!\n"));
3039 if (data
->icld_DisplayFlags
& ICONLIST_DISP_BUFFERED
)
3041 struct BitMap
*bitmap_New
= NULL
;
3042 struct Layer_Info
*li
= NULL
;
3044 ULONG tmp_RastDepth
= GetCyberMapAttr(data
->icld_DisplayRastPort
->BitMap
, CYBRMATTR_DEPTH
);
3045 if ((bitmap_New
= AllocBitMap(data
->icld_ViewWidth
,
3046 data
->icld_ViewHeight
,
3049 data
->icld_DisplayRastPort
->BitMap
))!=NULL
)
3051 if ((data
->icld_BufferRastPort
= CreateRastPort())!=NULL
)
3053 data
->icld_BufferRastPort
->BitMap
= bitmap_New
;
3054 if ((li
= NewLayerInfo()))
3056 if ((data
->icld_BufferRastPort
->Layer
= CreateUpfrontLayer(li
, data
->icld_BufferRastPort
->BitMap
, 0, 0, data
->icld_ViewWidth
- 1, data
->icld_ViewHeight
- 1, 0, NULL
)))
3059 * Mark it as a buffered rastport.
3062 #if defined(DEBUG_ILC_ATTRIBS) || defined(DEBUG_ILC_ICONRENDERING)
3063 D(bug("[IconList] %s: FrontRastPort @ %p, New BackLayer @ %p, BackRastport @ %p\n", __PRETTY_FUNCTION__
, data
->icld_DisplayRastPort
, data
->icld_BufferRastPort
->Layer
, data
->icld_BufferRastPort
));
3065 SET(obj
, MUIA_IconList_BufferRastport
, data
->icld_BufferRastPort
);
3066 data
->icld_DrawOffsetX
= 0;
3067 data
->icld_DrawOffsetY
= 0;
3070 data
->icld_BufferRastPort
= data
->icld_DisplayRastPort
;
3073 data
->icld_BufferRastPort
= data
->icld_DisplayRastPort
;
3076 data
->icld_BufferRastPort
= data
->icld_DisplayRastPort
;
3078 if (data
->icld_BufferRastPort
== data
->icld_DisplayRastPort
)
3080 if (bitmap_New
) FreeBitMap(bitmap_New
);
3081 if (li
) DisposeLayerInfo(li
);
3082 data
->icld_DrawOffsetX
= _mleft(obj
);
3083 data
->icld_DrawOffsetY
= _mtop(obj
);
3088 data
->icld_BufferRastPort
= data
->icld_DisplayRastPort
;
3089 data
->icld_DrawOffsetX
= _mleft(obj
);
3090 data
->icld_DrawOffsetY
= _mtop(obj
);
3093 if (data
->icld_IconLabelFont
== NULL
) data
->icld_IconLabelFont
= _font(obj
);
3094 if (data
->icld_IconInfoFont
== NULL
) data
->icld_IconInfoFont
= data
->icld_IconLabelFont
;
3095 #if defined(DEBUG_ILC_ICONRENDERING)
3096 D(bug("[IconList] IconList__MUIM_Show: Use Font @ 0x%p, RastPort @ 0x%p\n", data
->icld_IconLabelFont
, data
->icld_BufferRastPort
));
3099 if ((data
->icld_BufferRastPort
) && (data
->icld_IconLabelFont
))
3100 SetFont(data
->icld_BufferRastPort
, data
->icld_IconLabelFont
);
3107 /**************************************************************************
3109 **************************************************************************/
3110 IPTR
IconList__MUIM_Hide(struct IClass
*CLASS
, Object
*obj
, struct MUIP_Hide
*message
)
3112 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
3115 #if defined(DEBUG_ILC_FUNCS)
3116 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
3119 if ((rc
= DoSuperMethodA(CLASS
, obj
, (Msg
)message
)))
3121 if ((data
->icld_BufferRastPort
) && (data
->icld_BufferRastPort
!= data
->icld_DisplayRastPort
))
3123 DeleteLayer(0, data
->icld_BufferRastPort
->Layer
);
3126 data
->icld_BufferRastPort
= NULL
;
3128 if (data
->icld_DisplayRastPort
)
3129 FreeRastPort(data
->icld_DisplayRastPort
);
3131 data
->icld_DisplayRastPort
= NULL
;
3138 /**************************************************************************
3140 **************************************************************************/
3141 IPTR
IconList__MUIM_Cleanup(struct IClass
*CLASS
, Object
*obj
, struct MUIP_Cleanup
*message
)
3143 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
3144 struct IconEntry
*node
= NULL
;
3146 #if defined(DEBUG_ILC_FUNCS)
3147 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
3150 #if defined(__AROS__)
3151 ForeachNode(&data
->icld_IconList
, node
)
3153 Foreach_Node(&data
->icld_IconList
, node
);
3156 if (node
->ie_DiskObj
)
3158 FreeDiskObject(node
->ie_DiskObj
);
3159 node
->ie_DiskObj
= NULL
;
3163 DoMethod(_win(obj
), MUIM_Window_RemEventHandler
, (IPTR
)&data
->ehn
);
3165 return DoSuperMethodA(CLASS
, obj
, (Msg
)message
);
3170 /**************************************************************************
3172 **************************************************************************/
3173 IPTR
IconList__MUIM_AskMinMax(struct IClass
*CLASS
, Object
*obj
, struct MUIP_AskMinMax
*message
)
3175 ULONG rc
= DoSuperMethodA(CLASS
, obj
, (Msg
) message
);
3177 #if defined(DEBUG_ILC_FUNCS)
3178 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
3181 message
->MinMaxInfo
->MinWidth
+= 96;
3182 message
->MinMaxInfo
->MinHeight
+= 64;
3184 message
->MinMaxInfo
->DefWidth
+= 200;
3185 message
->MinMaxInfo
->DefHeight
+= 180;
3187 message
->MinMaxInfo
->MaxWidth
= MUI_MAXMAX
;
3188 message
->MinMaxInfo
->MaxHeight
= MUI_MAXMAX
;
3195 /**************************************************************************
3197 **************************************************************************/
3198 IPTR
IconList__MUIM_Layout(struct IClass
*CLASS
, Object
*obj
,struct MUIP_Layout
*message
)
3200 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
3203 #if defined(DEBUG_ILC_FUNCS)
3204 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
3207 rc
= DoSuperMethodA(CLASS
, obj
, (Msg
)message
);
3209 data
->icld_ViewWidth
= _mwidth(obj
);
3210 data
->icld_ViewHeight
= _mheight(obj
);
3216 static LONG
FirstVisibleLine(struct IconList_DATA
*data
)
3218 return data
->icld_ViewY
/ data
->icld_LVMAttribs
->lmva_RowHeight
;
3221 static LONG
NumVisibleLines(struct IconList_DATA
*data
)
3223 LONG visible
= data
->icld_ViewHeight
+ data
->icld_LVMAttribs
->lmva_RowHeight
- 1 +
3224 (data
->icld_ViewY
% data
->icld_LVMAttribs
->lmva_RowHeight
);
3226 visible
/= data
->icld_LVMAttribs
->lmva_RowHeight
;
3231 static void RenderListViewModeHeaderField(Object
*obj
, struct IconList_DATA
*data
,
3232 struct Rectangle
*rect
, LONG index
, BOOL sel
)
3234 IPTR penFill
, penText
, penDark
, penBright
;
3235 struct Rectangle rendRect
;
3237 struct TextExtent te
;
3242 penFill
= _pens(obj
)[MPEN_HALFSHADOW
];
3243 penBright
= _pens(obj
)[MPEN_SHADOW
];
3244 penDark
= _pens(obj
)[MPEN_HALFSHINE
];
3248 penFill
= _pens(obj
)[MPEN_HALFSHINE
];
3249 penBright
= _pens(obj
)[MPEN_SHINE
];
3250 penDark
= _pens(obj
)[MPEN_HALFSHADOW
];
3252 penText
= _pens(obj
)[MPEN_TEXT
];
3254 rendRect
.MinX
= rect
->MinX
;
3255 rendRect
.MaxX
= rect
->MaxX
;
3256 rendRect
.MinY
= rect
->MinY
;
3257 rendRect
.MaxY
= rect
->MaxY
;
3259 if (data
->icld_DisplayRastPort
!= data
->icld_BufferRastPort
)
3261 rendRect
.MinX
-= _mleft(obj
);
3262 rendRect
.MaxX
-= _mleft(obj
);
3263 rendRect
.MinY
-= _mtop(obj
);
3264 rendRect
.MaxY
-= _mtop(obj
);
3267 #if defined(DEBUG_ILC_FUNCS)
3268 D(bug("[IconList]: %s(obj @ 0x%p)\n", __PRETTY_FUNCTION__
, obj
));
3271 if (((data
->icld_LVMAttribs
->lvma_Flags
& LVMAF_NOHEADER
) == 0) && (index
< NUM_COLUMNS
))
3273 text
= data
->icld_LVMAttribs
->lmva_ColumnTitle
[index
];
3275 SetAPen(data
->icld_BufferRastPort
, penFill
); /* Background */
3276 RectFill(data
->icld_BufferRastPort
, rendRect
.MinX
+ 1, rendRect
.MinY
+ 1,
3277 rendRect
.MaxX
- 1, rendRect
.MaxY
- 1);
3279 SetAPen(data
->icld_BufferRastPort
, penBright
); /* Top/Left */
3280 RectFill(data
->icld_BufferRastPort
, rendRect
.MinX
, rendRect
.MinY
, rendRect
.MinX
, rendRect
.MaxY
);
3281 RectFill(data
->icld_BufferRastPort
, rendRect
.MinX
+ 1, rendRect
.MinY
, rendRect
.MaxX
- 1, rendRect
.MinY
);
3283 SetAPen(data
->icld_BufferRastPort
,penDark
); /* Bottom/Right */
3284 RectFill(data
->icld_BufferRastPort
, rendRect
.MaxX
, rendRect
.MinY
, rendRect
.MaxX
, rendRect
.MaxY
);
3285 RectFill(data
->icld_BufferRastPort
, rendRect
.MinX
+ 1, rendRect
.MaxY
, rendRect
.MaxX
- 1, rendRect
.MaxY
);
3287 /* Draw the Sort indicator .. */
3288 if (index
== data
->icld_LVMAttribs
->lmva_SortColumn
)
3290 LONG x
= rendRect
.MaxX
- 4 - 6;
3291 LONG y
= (rendRect
.MinY
+ rendRect
.MaxY
+ 1) / 2 - 3;
3293 if (x
> rendRect
.MinX
)
3295 SetAPen(data
->icld_BufferRastPort
, _pens(obj
)[sel
? MPEN_SHADOW
: MPEN_HALFSHADOW
]);
3296 if (data
->icld_SortFlags
& MUIV_IconList_Sort_Reverse
)
3298 RectFill(data
->icld_BufferRastPort
, x
, y
, x
+ 5, y
+ 1);
3299 RectFill(data
->icld_BufferRastPort
, x
+ 1, y
+ 2, x
+ 4, y
+ 3);
3300 RectFill(data
->icld_BufferRastPort
, x
+ 2, y
+ 4, x
+ 3, y
+ 5);
3304 RectFill(data
->icld_BufferRastPort
, x
, y
+ 4, x
+ 5, y
+ 5);
3305 RectFill(data
->icld_BufferRastPort
, x
+ 1, y
+ 2, x
+ 4, y
+ 3);
3306 RectFill(data
->icld_BufferRastPort
, x
+ 2, y
, x
+ 3, y
+ 1);
3311 rendRect
.MinX
+= HEADERENTRY_SPACING_LEFT
;
3312 rendRect
.MinY
+= HEADERLINE_SPACING_TOP
;
3313 rendRect
.MaxX
-= HEADERENTRY_SPACING_RIGHT
;
3314 rendRect
.MaxY
-= HEADERLINE_SPACING_BOTTOM
;
3316 if (text
&& text
[0])
3319 fit
= TextFit(data
->icld_BufferRastPort
, text
, strlen(text
), &te
, NULL
, 1,
3320 rendRect
.MaxX
- rendRect
.MinX
+ 1,
3321 rendRect
.MaxY
- rendRect
.MinY
+ 1);
3325 SetABPenDrMd(data
->icld_BufferRastPort
, penText
, 0, JAM1
);
3326 Move(data
->icld_BufferRastPort
, rendRect
.MinX
, rendRect
.MinY
+ data
->icld_BufferRastPort
->TxBaseline
);
3327 Text(data
->icld_BufferRastPort
, text
, fit
);
3332 static void RenderListViewModeHeader(Object
*obj
, struct IconList_DATA
*data
)
3334 struct Rectangle linerect
;
3336 LONG firstvis
, lastvis
;
3338 #if defined(DEBUG_ILC_FUNCS)
3339 D(bug("[IconList]: %s(obj @ 0x%p)\n", __PRETTY_FUNCTION__
, obj
));
3342 if ((data
->icld_LVMAttribs
->lvma_Flags
& LVMAF_NOHEADER
) == 0)
3344 linerect
.MinX
= _mleft(obj
) - data
->icld_ViewX
;
3345 linerect
.MaxX
= _mright(obj
);
3346 linerect
.MinY
= _mtop(obj
);
3347 linerect
.MaxY
= _mtop(obj
) + data
->icld_LVMAttribs
->lmva_HeaderHeight
- 1;
3349 SetFont(data
->icld_BufferRastPort
, data
->icld_IconLabelFont
);
3351 x
= linerect
.MinX
+ HEADERLINE_SPACING_LEFT
;
3353 firstvis
= FirstVisibleColumnNumber(data
);
3354 lastvis
= LastVisibleColumnNumber(data
);
3356 for(i
= 0; i
< NUM_COLUMNS
; i
++)
3358 LONG index
= data
->icld_LVMAttribs
->lmva_ColumnPos
[i
];
3360 if (!(data
->icld_LVMAttribs
->lmva_ColumnFlags
[index
] & LVMCF_COLVISIBLE
)) continue;
3362 struct Rectangle field_rect
;
3364 field_rect
.MinX
= (i
== firstvis
) ? linerect
.MinX
: x
;
3365 field_rect
.MinY
= linerect
.MinY
;
3366 field_rect
.MaxX
= x
+ data
->icld_LVMAttribs
->lmva_ColumnWidth
[index
] - 1 + ((i
== lastvis
) ? HEADERLINE_SPACING_RIGHT
: 0);
3367 field_rect
.MaxY
= linerect
.MaxY
;
3369 /* data->update_rect1 and data->update_rect2 may
3370 point to rectangles to indicate that only icons
3371 in any of this rectangles need to be drawn */
3372 if (data
->update_rect1
)
3374 RectAndRect(&field_rect
, data
->update_rect1
);
3377 if (data
->update_rect2
)
3379 RectAndRect(&field_rect
, data
->update_rect2
);
3382 RenderListViewModeHeaderField(obj
, data
, &field_rect
, index
, FALSE
);
3383 x
+= data
->icld_LVMAttribs
->lmva_ColumnWidth
[index
];
3386 if ((data
->icld_LVMAttribs
->lvma_Flags
& LVMAF_HEADERDRAWTOEND
) == LVMAF_HEADERDRAWTOEND
)
3388 x
+= HEADERLINE_SPACING_RIGHT
;
3390 if (x
< linerect
.MaxX
)
3394 // if (MustRenderRect(data, &linerect))
3396 SetABPenDrMd(data
->icld_BufferRastPort
, _pens(obj
)[MPEN_HALFSHINE
], 0, JAM1
);
3397 RectFill(data
->icld_BufferRastPort
, linerect
.MinX
, linerect
.MinY
, linerect
.MaxX
, linerect
.MaxY
);
3405 /**************************************************************************
3406 MUIM_Draw - draw the IconList
3407 **************************************************************************/
3409 IPTR
IconList__MUIM_Draw(struct IClass
*CLASS
, Object
*obj
, struct MUIP_Draw
*message
)
3411 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
3412 struct IconEntry
*entry
= NULL
;
3416 ULONG update_oldwidth
= 0,
3417 update_oldheight
= 0;
3419 LONG clear_xoffset
= 0,
3422 __unused IPTR draw_id
= DrawCount
++;
3424 #if defined(DEBUG_ILC_FUNCS)
3425 D(bug("[IconList]: %s(obj @ 0x%p)\n", __PRETTY_FUNCTION__
, obj
));
3427 #if defined(DEBUG_ILC_ICONRENDERING)
3428 D(bug("[IconList] %s: id %d\n", __PRETTY_FUNCTION__
, draw_id
));
3431 DoSuperMethodA(CLASS
, obj
, (Msg
)message
);
3433 if (!(data
->icld__Option_IconListFixedBackground
))
3435 clear_xoffset
= data
->icld_ViewX
;
3436 clear_yoffset
= data
->icld_ViewY
;
3439 // If window size changes, only update needed areas
3440 if (data
->update_oldwidth
== 0) data
->update_oldwidth
= data
->icld_ViewWidth
;
3441 if (data
->update_oldheight
== 0) data
->update_oldheight
= data
->icld_ViewHeight
;
3442 if ((data
->update_oldwidth
!= data
->icld_ViewWidth
) || (data
->update_oldheight
!= data
->icld_ViewHeight
))
3444 if (data
->icld_UpdateMode
!= UPDATE_SCROLL
)
3446 data
->icld_UpdateMode
= UPDATE_RESIZE
;
3447 update_oldwidth
= data
->update_oldwidth
;
3448 update_oldheight
= data
->update_oldheight
;
3449 data
->update_oldwidth
= data
->icld_ViewWidth
;
3450 data
->update_oldheight
= data
->icld_ViewHeight
;
3454 if ((message
->flags
& MADF_DRAWUPDATE
) || (data
->icld_UpdateMode
== UPDATE_RESIZE
))
3456 #if defined(DEBUG_ILC_ICONRENDERING)
3458 if (message
->flags
& MADF_DRAWUPDATE
)
3460 bug("[IconList] %s#%d: MADF_DRAWUPDATE\n", __PRETTY_FUNCTION__
, draw_id
);
3464 bug("[IconList] %s#%d: UPDATE_RESIZE\n", __PRETTY_FUNCTION__
, draw_id
);
3468 if ((data
->icld_UpdateMode
== UPDATE_HEADERENTRY
) && ((IPTR
)data
->update_entry
< NUM_COLUMNS
)) /* draw the header entry */
3470 struct Rectangle field_rect
;
3471 LONG index
, i
, firstvis
, lastvis
;
3473 firstvis
= FirstVisibleColumnNumber(data
);
3474 lastvis
= LastVisibleColumnNumber(data
);
3476 field_rect
.MinX
= _mleft(obj
) - data
->icld_ViewX
;
3478 field_rect
.MinY
= _mtop(obj
);
3479 field_rect
.MaxY
= field_rect
.MinY
+ data
->icld_LVMAttribs
->lmva_HeaderHeight
- 1;
3481 for(i
= 0; i
< NUM_COLUMNS
; i
++)
3483 index
= data
->icld_LVMAttribs
->lmva_ColumnPos
[i
];
3484 if (!(data
->icld_LVMAttribs
->lmva_ColumnFlags
[index
] & LVMCF_COLVISIBLE
)) continue;
3486 field_rect
.MaxX
= field_rect
.MinX
+ data
->icld_LVMAttribs
->lmva_ColumnWidth
[index
] - 1;
3487 if (index
== lastvis
)
3488 field_rect
.MaxX
+= HEADERLINE_SPACING_RIGHT
;
3490 if ((IPTR
)data
->update_entry
!= index
)
3492 field_rect
.MinX
+= data
->icld_LVMAttribs
->lmva_ColumnWidth
[index
];
3493 if (index
== firstvis
)
3494 field_rect
.MinX
+= HEADERLINE_SPACING_LEFT
;
3500 clip
= MUI_AddClipping(muiRenderInfo(obj
), _mleft(obj
), _mtop(obj
), _mright(obj
) - _mleft(obj
) + 1, data
->icld_LVMAttribs
->lmva_HeaderHeight
);
3502 if (data
->icld_LVMAttribs
->lmva_LastSelectedColumn
== (IPTR
)data
->update_entry
)
3503 RenderListViewModeHeaderField(obj
, data
, &field_rect
, (IPTR
)data
->update_entry
, TRUE
);
3505 RenderListViewModeHeaderField(obj
, data
, &field_rect
, (IPTR
)data
->update_entry
, FALSE
);
3507 data
->icld_UpdateMode
= 0;
3508 data
->update_entry
= NULL
;
3510 if (data
->icld_DisplayRastPort
!= data
->icld_BufferRastPort
)
3512 #if defined(DEBUG_ILC_ICONRENDERING)
3513 D(bug("[IconList] %s#%d: UPDATE_HEADERENTRY Blitting to front rastport..\n", __PRETTY_FUNCTION__
, draw_id
));
3515 BltBitMapRastPort(data
->icld_BufferRastPort
->BitMap
,
3516 field_rect
.MinX
- _mleft(obj
), field_rect
.MinY
- _mtop(obj
),
3517 data
->icld_DisplayRastPort
,
3518 field_rect
.MinX
, field_rect
.MinY
,
3519 field_rect
.MaxX
- field_rect
.MinX
+ 1, field_rect
.MaxY
- field_rect
.MinY
+ 1,
3522 MUI_RemoveClipping(muiRenderInfo(obj
), clip
);
3526 else if ((data
->icld_UpdateMode
== UPDATE_SINGLEENTRY
) && (data
->update_entry
!= NULL
)) /* draw only a single entry at update_entry */
3528 struct Rectangle rect
;
3530 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
3532 LONG count
= 0, index
= -1;
3534 #if defined(DEBUG_ILC_ICONRENDERING)
3535 D(bug("[IconList] %s#%d: UPDATE_SINGLEENTRY + ICONLIST_DISP_MODELIST\n", __PRETTY_FUNCTION__
, draw_id
));
3537 rect
.MinX
= _mleft(obj
);
3538 rect
.MaxX
= _mleft(obj
) + _mwidth(obj
) - 1;
3540 ForeachNode(&data
->icld_IconList
, entry
)
3542 if (entry
== data
->update_entry
)
3547 if (entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
3555 rect
.MinY
= _mtop(obj
) + data
->icld_LVMAttribs
->lmva_HeaderHeight
- data
->icld_ViewY
+ (index
* data
->icld_LVMAttribs
->lmva_RowHeight
);
3556 rect
.MaxY
= rect
.MinY
+ data
->icld_LVMAttribs
->lmva_RowHeight
- 1;
3558 if ((rect
.MaxY
< (_mtop(obj
) + data
->icld_LVMAttribs
->lmva_HeaderHeight
))
3559 || (rect
.MinY
> (_mtop(obj
) + _mheight(obj
) - 1)))
3562 if (rect
.MinY
< (_mtop(obj
) + data
->icld_LVMAttribs
->lmva_HeaderHeight
)) rect
.MinY
= _mtop(obj
) + data
->icld_LVMAttribs
->lmva_HeaderHeight
;
3563 if (rect
.MaxY
> (_mtop(obj
) + _mheight(obj
) - 1)) rect
.MaxY
= _mtop(obj
) + _mheight(obj
) - 1;
3565 clip
= MUI_AddClipping(muiRenderInfo(obj
), rect
.MinX
, rect
.MinY
, rect
.MaxX
- rect
.MinX
+ 1, rect
.MaxY
- rect
.MinY
+ 1);
3567 DoMethod(obj
, MUIM_DrawBackground
,
3568 rect
.MinX
, rect
.MinY
,
3569 rect
.MaxX
- rect
.MinX
+ 1, rect
.MaxY
- rect
.MinY
+ 1,
3570 clear_xoffset
, clear_yoffset
,
3573 entry
->ie_Flags
|= ICONENTRY_FLAG_NEEDSUPDATE
;
3574 DoMethod(obj
, MUIM_IconList_DrawEntry
, data
->update_entry
, index
);
3575 entry
->ie_Flags
&= ~ICONENTRY_FLAG_NEEDSUPDATE
;
3576 data
->icld_UpdateMode
= 0;
3577 data
->update_entry
= NULL
;
3582 #if defined(DEBUG_ILC_ICONRENDERING)
3583 D(bug("[IconList] %s#%d: UPDATE_SINGLEENTRY (entry @ 0x%p)\n", __PRETTY_FUNCTION__
, draw_id
, data
->update_entry
));
3585 IconList_GetIconAreaRectangle(obj
, data
, data
->update_entry
, &rect
);
3587 rect
.MinX
+= _mleft(obj
) + (data
->update_entry
->ie_IconX
- data
->icld_ViewX
);
3588 rect
.MaxX
+= _mleft(obj
) + (data
->update_entry
->ie_IconX
- data
->icld_ViewX
);
3589 rect
.MinY
+= _mtop(obj
) + (data
->update_entry
->ie_IconY
- data
->icld_ViewY
);
3590 rect
.MaxY
+= _mtop(obj
) + (data
->update_entry
->ie_IconY
- data
->icld_ViewY
);
3592 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
3594 if (data
->update_entry
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
3596 rect
.MinX
+= ((data
->icld_IconAreaLargestWidth
- data
->update_entry
->ie_AreaWidth
)/2);
3597 rect
.MaxX
+= ((data
->icld_IconAreaLargestWidth
- data
->update_entry
->ie_AreaWidth
)/2);
3600 if (data
->update_entry
->ie_AreaHeight
< data
->icld_IconAreaLargestHeight
)
3602 rect
.MinY
+= ((data
->icld_IconAreaLargestHeight
- data
->update_entry
->ie_AreaHeight
)/2);
3603 rect
.MaxY
+= ((data
->icld_IconAreaLargestHeight
- data
->update_entry
->ie_AreaHeight
)/2);
3607 if (rect
.MinX
< _mleft(obj
)) rect
.MinX
= _mleft(obj
);
3608 if (rect
.MaxX
> _mright(obj
)) rect
.MaxX
=_mright(obj
);
3609 if (rect
.MinY
< _mtop(obj
)) rect
.MinY
= _mtop(obj
);
3610 if (rect
.MaxY
> _mbottom(obj
)) rect
.MaxY
= _mbottom(obj
);
3612 clip
= MUI_AddClipping(muiRenderInfo(obj
), rect
.MinX
, rect
.MinY
, rect
.MaxX
- rect
.MinX
+ 1, rect
.MaxY
- rect
.MinY
+ 1);
3614 #if defined(DEBUG_ILC_ICONRENDERING)
3615 D(bug("[IconList] %s#%d: UPDATE_SINGLEENTRY: Calling MUIM_DrawBackground (A)\n", __PRETTY_FUNCTION__
, draw_id
));
3617 DoMethod(obj
, MUIM_DrawBackground
,
3618 rect
.MinX
, rect
.MinY
,
3619 rect
.MaxX
- rect
.MinX
+ 1, rect
.MaxY
- rect
.MinY
+ 1,
3620 clear_xoffset
, clear_yoffset
,
3623 /* We could have deleted also other icons so they must be redrawn */
3624 #if defined(__AROS__)
3625 ForeachNode(&data
->icld_IconList
, entry
)
3627 Foreach_Node(&data
->icld_IconList
, entry
);
3630 if ((entry
!= data
->update_entry
) && (entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
))
3632 struct Rectangle rect2
;
3633 IconList_GetIconAreaRectangle(obj
, data
, entry
, &rect2
);
3635 rect2
.MinX
+= _mleft(obj
) - data
->icld_ViewX
+ entry
->ie_IconX
;
3636 rect2
.MaxX
+= _mleft(obj
) - data
->icld_ViewX
+ entry
->ie_IconX
;
3637 rect2
.MinY
+= _mtop(obj
) - data
->icld_ViewY
+ entry
->ie_IconY
;
3638 rect2
.MaxY
+= _mtop(obj
) - data
->icld_ViewY
+ entry
->ie_IconY
;
3640 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
3642 if (entry
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
3644 rect2
.MinX
+= ((data
->icld_IconAreaLargestWidth
- entry
->ie_AreaWidth
)/2);
3645 rect2
.MaxX
+= ((data
->icld_IconAreaLargestWidth
- entry
->ie_AreaWidth
)/2);
3648 if (entry
->ie_AreaHeight
< data
->icld_IconAreaLargestHeight
)
3650 rect2
.MinY
+= ((data
->icld_IconAreaLargestHeight
- entry
->ie_AreaHeight
)/2);
3651 rect2
.MaxY
+= ((data
->icld_IconAreaLargestHeight
- entry
->ie_AreaHeight
)/2);
3655 if (RectAndRect(&rect
, &rect2
))
3657 // Update entry here
3658 entry
->ie_Flags
|= ICONENTRY_FLAG_NEEDSUPDATE
;
3659 DoMethod(obj
, MUIM_IconList_DrawEntry
, entry
, ICONENTRY_DRAWMODE_PLAIN
);
3660 DoMethod(obj
, MUIM_IconList_DrawEntryLabel
, entry
, ICONENTRY_DRAWMODE_PLAIN
);
3661 entry
->ie_Flags
&= ~ICONENTRY_FLAG_NEEDSUPDATE
;
3666 entry
->ie_Flags
|= ICONENTRY_FLAG_NEEDSUPDATE
;
3667 DoMethod(obj
, MUIM_IconList_DrawEntry
, data
->update_entry
, ICONENTRY_DRAWMODE_PLAIN
);
3668 DoMethod(obj
, MUIM_IconList_DrawEntryLabel
, data
->update_entry
, ICONENTRY_DRAWMODE_PLAIN
);
3669 entry
->ie_Flags
&= ~ICONENTRY_FLAG_NEEDSUPDATE
;
3670 data
->icld_UpdateMode
= 0;
3671 data
->update_entry
= NULL
;
3673 if (data
->update_entry
== NULL
)
3675 if (data
->icld_DisplayRastPort
!= data
->icld_BufferRastPort
)
3677 #if defined(DEBUG_ILC_ICONRENDERING)
3678 D(bug("[IconList] %s#%d: UPDATE_SINGLEENTRY Blitting to front rastport..\n", __PRETTY_FUNCTION__
, draw_id
));
3680 BltBitMapRastPort(data
->icld_BufferRastPort
->BitMap
,
3681 rect
.MinX
- _mleft(obj
), rect
.MinY
- _mtop(obj
),
3682 data
->icld_DisplayRastPort
,
3683 rect
.MinX
, rect
.MinY
,
3684 rect
.MaxX
- rect
.MinX
+ 1, rect
.MaxY
- rect
.MinY
+ 1,
3687 MUI_RemoveClipping(muiRenderInfo(obj
), clip
);
3691 else if (data
->icld_UpdateMode
== UPDATE_SCROLL
)
3693 struct Region
*region
= NULL
;
3694 struct Rectangle xrect
,
3696 BOOL scroll_caused_damage
= FALSE
;
3698 #if defined(DEBUG_ILC_ICONRENDERING)
3699 D(bug("[IconList] %s#%d: UPDATE_SCROLL.\n", __PRETTY_FUNCTION__
, draw_id
));
3702 if (!data
->icld__Option_IconListFixedBackground
)
3704 scroll_caused_damage
= (_rp(obj
)->Layer
->Flags
& LAYERREFRESH
) ? FALSE
: TRUE
;
3706 data
->icld_UpdateMode
= 0;
3708 if ((abs(data
->update_scrolldx
) >= _mwidth(obj
)) ||
3709 (abs(data
->update_scrolldy
) >= _mheight(obj
)))
3711 #if defined(DEBUG_ILC_ICONRENDERING)
3712 D(bug("[IconList] %s#%d: UPDATE_SCROLL: Moved outside current view -> Causing Redraw .. MADF_DRAWOBJECT\n", __PRETTY_FUNCTION__
, draw_id
));
3714 MUI_Redraw(obj
, MADF_DRAWOBJECT
);
3718 if (!(region
= NewRegion()))
3720 #if defined(DEBUG_ILC_ICONRENDERING)
3721 D(bug("[IconList] %s#%d: UPDATE_SCROLL: Couldnt Alloc Region -> Causing Redraw ...MADF_DRAWOBJECT\n", __PRETTY_FUNCTION__
, draw_id
));
3723 MUI_Redraw(obj
, MADF_DRAWOBJECT
);
3727 if (data
->update_scrolldx
> 0)
3729 xrect
.MinX
= _mright(obj
) - data
->update_scrolldx
;
3730 xrect
.MinY
= _mtop(obj
);
3731 xrect
.MaxX
= _mright(obj
);
3732 xrect
.MaxY
= _mbottom(obj
);
3734 OrRectRegion(region
, &xrect
);
3736 data
->update_rect1
= &xrect
;
3738 else if (data
->update_scrolldx
< 0)
3740 xrect
.MinX
= _mleft(obj
);
3741 xrect
.MinY
= _mtop(obj
);
3742 xrect
.MaxX
= _mleft(obj
) - data
->update_scrolldx
;
3743 xrect
.MaxY
= _mbottom(obj
);
3745 OrRectRegion(region
, &xrect
);
3747 data
->update_rect1
= &xrect
;
3750 if (data
->update_scrolldy
> 0)
3752 yrect
.MinX
= _mleft(obj
);
3753 yrect
.MinY
= _mbottom(obj
) - data
->update_scrolldy
;
3754 if (((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
3755 && (yrect
.MinY
< (_mtop(obj
) + data
->icld_LVMAttribs
->lmva_HeaderHeight
)))
3757 xrect
.MinY
= data
->icld_LVMAttribs
->lmva_HeaderHeight
;
3759 yrect
.MaxX
= _mright(obj
);
3760 yrect
.MaxY
= _mbottom(obj
);
3762 OrRectRegion(region
, &yrect
);
3764 data
->update_rect2
= &yrect
;
3766 else if (data
->update_scrolldy
< 0)
3768 yrect
.MinX
= _mleft(obj
);
3769 yrect
.MinY
= _mtop(obj
);
3770 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
3772 xrect
.MinY
+= data
->icld_LVMAttribs
->lmva_HeaderHeight
;
3774 yrect
.MaxX
= _mright(obj
);
3775 yrect
.MaxY
= _mtop(obj
) - data
->update_scrolldy
;
3777 OrRectRegion(region
, &yrect
);
3779 data
->update_rect2
= &yrect
;
3782 #if defined(DEBUG_ILC_ICONRENDERING)
3783 D(bug("[IconList] %s#%d: UPDATE_SCROLL: Scrolling Raster..\n", __PRETTY_FUNCTION__
, draw_id
));
3785 if (data
->icld_DisplayRastPort
== data
->icld_BufferRastPort
)
3787 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
3789 ScrollRasterBF(data
->icld_BufferRastPort
,
3790 data
->update_scrolldx
,
3791 data
->update_scrolldy
,
3793 _mtop(obj
) + (data
->update_scrolldx
? 0 : data
->icld_LVMAttribs
->lmva_HeaderHeight
),
3799 ScrollRasterBF(data
->icld_BufferRastPort
,
3800 data
->update_scrolldx
,
3801 data
->update_scrolldy
,
3810 ScrollRasterBF(data
->icld_BufferRastPort
,
3811 data
->update_scrolldx
,
3812 data
->update_scrolldy
,
3819 scroll_caused_damage
= scroll_caused_damage
&& (_rp(obj
)->Layer
->Flags
& LAYERREFRESH
) ? TRUE
: FALSE
;
3821 clip
= MUI_AddClipRegion(muiRenderInfo(obj
), region
);
3824 #if defined(DEBUG_ILC_ICONRENDERING)
3825 D(bug("[IconList] %s#%d: UPDATE_SCROLL: Causing Redraw -> MADF_DRAWOBJECT..\n", __PRETTY_FUNCTION__
, draw_id
));
3827 MUI_Redraw(obj
, MADF_DRAWOBJECT
);
3829 data
->update_rect1
= data
->update_rect2
= NULL
;
3831 if (!data
->icld__Option_IconListFixedBackground
)
3833 MUI_RemoveClipRegion(muiRenderInfo(obj
), clip
);
3835 if (scroll_caused_damage
)
3837 if (MUI_BeginRefresh(muiRenderInfo(obj
), 0))
3839 /* Theoretically it might happen that more damage is caused
3840 after ScrollRaster. By something else, like window movement
3841 in front of our window. Therefore refresh root object of
3842 window, not just this object */
3846 GET(_win(obj
),MUIA_Window_RootObject
, &o
);
3847 MUI_Redraw(o
, MADF_DRAWOBJECT
);
3848 #if defined(DEBUG_ILC_ICONRENDERING)
3849 D(bug("[IconList] %s#%d: UPDATE_SCROLL: Causing Redraw -> MADF_DRAWOBJECT..\n", __PRETTY_FUNCTION__
, draw_id
));
3851 MUI_EndRefresh(muiRenderInfo(obj
), 0);
3855 if (data
->icld_DisplayRastPort
!= data
->icld_BufferRastPort
)
3857 #if defined(DEBUG_ILC_ICONRENDERING)
3858 D(bug("[IconList] %s#%d: UPDATE_SCROLL: Blitting to front rastport..\n", __PRETTY_FUNCTION__
, draw_id
));
3860 BltBitMapRastPort(data
->icld_BufferRastPort
->BitMap
,
3862 data
->icld_DisplayRastPort
,
3863 _mleft(obj
), _mtop(obj
),
3864 _mwidth(obj
), _mheight(obj
),
3869 else if (data
->icld_UpdateMode
== UPDATE_RESIZE
)
3871 struct Region
*region
= NULL
;
3872 struct Rectangle wrect
,
3877 #if defined(DEBUG_ILC_ICONRENDERING)
3878 D(bug("[IconList] %s#%d: UPDATE_RESIZE.\n", __PRETTY_FUNCTION__
, draw_id
));
3881 if ((data
->icld_BufferRastPort
) && (data
->icld_BufferRastPort
!= data
->icld_DisplayRastPort
))
3883 //Free up the buffers Layer, rastport and bitmap so we can replace them ..
3884 if ((GetBitMapAttr(data
->icld_BufferRastPort
->BitMap
, BMA_WIDTH
) != data
->icld_ViewWidth
)
3885 || (GetBitMapAttr(data
->icld_BufferRastPort
->BitMap
, BMA_HEIGHT
) != data
->icld_ViewHeight
))
3887 struct Layer
*oldLayer
= data
->icld_BufferRastPort
->Layer
;
3888 #if defined(DEBUG_ILC_ATTRIBS) || defined(DEBUG_ILC_ICONRENDERING)
3889 D(bug("[IconList] %s: Destroying old BackLayer\n", __PRETTY_FUNCTION__
));
3891 data
->icld_BufferRastPort
= data
->icld_DisplayRastPort
;
3892 DeleteLayer(0, oldLayer
);
3895 if (data
->icld_BufferRastPort
== data
->icld_DisplayRastPort
)
3897 struct BitMap
*bitmap_New
;
3898 ULONG tmp_RastDepth
;
3899 struct Layer_Info
*li
= NULL
;
3901 tmp_RastDepth
= GetCyberMapAttr(data
->icld_DisplayRastPort
->BitMap
, CYBRMATTR_DEPTH
);
3902 if ((bitmap_New
= AllocBitMap(data
->icld_ViewWidth
,
3903 data
->icld_ViewHeight
,
3906 data
->icld_DisplayRastPort
->BitMap
)) != NULL
)
3908 if ((data
->icld_BufferRastPort
= CreateRastPort()) != NULL
)
3910 data
->icld_BufferRastPort
->BitMap
= bitmap_New
;
3911 if ((li
= NewLayerInfo()))
3913 if ((data
->icld_BufferRastPort
->Layer
= CreateUpfrontLayer(li
, data
->icld_BufferRastPort
->BitMap
, 0, 0, data
->icld_ViewWidth
- 1, data
->icld_ViewHeight
- 1, 0, NULL
)))
3916 * Mark it as a buffered rastport.
3919 #if defined(DEBUG_ILC_ATTRIBS) || defined(DEBUG_ILC_ICONRENDERING)
3920 D(bug("[IconList] %s: FrontRastPort @ %p, New BackLayer @ %p, BackRastport @ %p\n", __PRETTY_FUNCTION__
, data
->icld_DisplayRastPort
, data
->icld_BufferRastPort
->Layer
, data
->icld_BufferRastPort
));
3922 SET(obj
, MUIA_IconList_BufferRastport
, data
->icld_BufferRastPort
);
3923 data
->icld_DrawOffsetX
= 0;
3924 data
->icld_DrawOffsetY
= 0;
3927 data
->icld_BufferRastPort
= data
->icld_DisplayRastPort
;
3930 data
->icld_BufferRastPort
= data
->icld_DisplayRastPort
;
3933 data
->icld_BufferRastPort
= data
->icld_DisplayRastPort
;
3936 if (data
->icld_BufferRastPort
== data
->icld_DisplayRastPort
)
3938 if (bitmap_New
) FreeBitMap(bitmap_New
);
3939 if (li
) DisposeLayerInfo(li
);
3940 data
->icld_DrawOffsetX
= _mleft(obj
);
3941 data
->icld_DrawOffsetY
= _mtop(obj
);
3946 data
->icld_UpdateMode
= 0;
3948 if (!data
->icld__Option_IconListScaledBackground
)
3950 if (!(region
= NewRegion()))
3952 #if defined(DEBUG_ILC_ICONRENDERING)
3953 D(bug("[IconList] %s#%d: UPDATE_RESIZE: Causing Redraw -> MADF_DRAWOBJECT..\n", __PRETTY_FUNCTION__
, draw_id
));
3955 MUI_Redraw(obj
, MADF_DRAWOBJECT
);
3959 if ( data
->icld_ViewWidth
> update_oldwidth
)
3960 diffw
= data
->icld_ViewWidth
- update_oldwidth
;
3961 if ( data
->icld_ViewHeight
> update_oldheight
)
3962 diffh
= data
->icld_ViewHeight
- update_oldheight
;
3966 wrect
.MinX
= _mright(obj
) - diffw
;
3967 wrect
.MinY
= _mtop(obj
);
3968 wrect
.MaxX
= _mright(obj
);
3969 wrect
.MaxY
= _mbottom(obj
);
3970 OrRectRegion(region
, &wrect
);
3971 data
->update_rect1
= &wrect
;
3976 hrect
.MinX
= _mleft(obj
);
3977 hrect
.MinY
= _mbottom(obj
) - diffh
;
3978 hrect
.MaxX
= _mright(obj
);
3979 hrect
.MaxX
= _mright(obj
);
3980 hrect
.MaxY
= _mbottom(obj
);
3981 OrRectRegion(region
, &hrect
);
3982 data
->update_rect2
= &hrect
;
3986 clip
= MUI_AddClipRegion(muiRenderInfo(obj
), region
);
3990 /* View became smaller both in horizontal and vertical direction.
3993 DisposeRegion(region
);
3998 #if defined(DEBUG_ILC_ICONRENDERING)
3999 D(bug("[IconList] %s#%d: UPDATE_RESIZE: Causing Redraw -> MADF_DRAWOBJECT..\n", __PRETTY_FUNCTION__
, draw_id
));
4001 MUI_Redraw(obj
, MADF_DRAWOBJECT
);
4003 if (!data
->icld__Option_IconListScaledBackground
)
4007 data
->update_rect1
= data
->update_rect2
= NULL
;
4008 MUI_RemoveClipRegion(muiRenderInfo(obj
), clip
);
4009 } else DisposeRegion(region
);
4016 if (message
->flags
& MADF_DRAWOBJECT
)
4018 struct Rectangle viewrect
;
4019 int current
= 0, first
= 0, visible
= 0;
4021 #if defined(DEBUG_ILC_ICONRENDERING)
4022 D(bug("[IconList] %s#%d: MADF_DRAWOBJECT\n", __PRETTY_FUNCTION__
, draw_id
));
4025 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
4027 clip
= MUI_AddClipping(muiRenderInfo(obj
), _mleft(obj
), _mtop(obj
), _mwidth(obj
), data
->icld_LVMAttribs
->lmva_HeaderHeight
);
4028 RenderListViewModeHeader(obj
, data
);
4030 if (data
->icld_DisplayRastPort
!= data
->icld_BufferRastPort
)
4032 #if defined(DEBUG_ILC_ICONRENDERING)
4033 D(bug("[IconList] %s#%d: MADF_DRAWOBJECT Blitting Header to front rastport..\n", __PRETTY_FUNCTION__
, draw_id
));
4035 BltBitMapRastPort(data
->icld_BufferRastPort
->BitMap
,
4037 data
->icld_DisplayRastPort
,
4038 _mleft(obj
), _mtop(obj
), _mwidth(obj
), data
->icld_LVMAttribs
->lmva_HeaderHeight
,
4042 MUI_RemoveClipping(muiRenderInfo(obj
), clip
);
4044 viewrect
.MinY
= _mtop(obj
) + data
->icld_LVMAttribs
->lmva_HeaderHeight
;
4046 first
= FirstVisibleLine(data
);
4047 visible
= NumVisibleLines(data
);
4049 clip
= MUI_AddClipping(muiRenderInfo(obj
), _mleft(obj
), _mtop(obj
) + data
->icld_LVMAttribs
->lmva_HeaderHeight
, _mwidth(obj
), _mheight(obj
) - data
->icld_LVMAttribs
->lmva_HeaderHeight
);
4053 viewrect
.MinY
= _mtop(obj
);
4054 clip
= MUI_AddClipping(muiRenderInfo(obj
), _mleft(obj
), _mtop(obj
), _mwidth(obj
), _mheight(obj
));
4057 viewrect
.MaxY
= _mtop(obj
) + _mheight(obj
) - 1;
4058 viewrect
.MinX
= _mleft(obj
);
4059 viewrect
.MaxX
= _mleft(obj
) + _mwidth(obj
) - 1;
4061 #if defined(DEBUG_ILC_ICONRENDERING)
4062 D(bug("[IconList] %s#%d: MADF_DRAWOBJECT: Calling MUIM_DrawBackground (B)\n", __PRETTY_FUNCTION__
, draw_id
));
4065 obj
, MUIM_DrawBackground
, viewrect
.MinX
, viewrect
.MinY
, (viewrect
.MaxX
- viewrect
.MinX
) + 1, (viewrect
.MaxY
- viewrect
.MinY
) + 1,
4066 clear_xoffset
, clear_yoffset
, 0
4068 #if defined(__AROS__)
4069 ForeachNode(&data
->icld_IconList
, entry
)
4071 Foreach_Node(&data
->icld_IconList
, entry
);
4074 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
4076 if (entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
4078 if ((current
>= first
) && (current
<= (first
+ visible
)))
4080 DoMethod(obj
, MUIM_IconList_DrawEntry
, entry
, current
);
4087 if ((entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
) &&
4088 (entry
->ie_DiskObj
) &&
4089 (entry
->ie_IconX
!= NO_ICON_POSITION
) &&
4090 (entry
->ie_IconY
!= NO_ICON_POSITION
))
4092 struct Rectangle iconrect
;
4093 IconList_GetIconAreaRectangle(obj
, data
, entry
, &iconrect
);
4095 iconrect
.MinX
+= viewrect
.MinX
- data
->icld_ViewX
+ entry
->ie_IconX
;
4096 iconrect
.MaxX
+= viewrect
.MinX
- data
->icld_ViewX
+ entry
->ie_IconX
;
4097 iconrect
.MinY
+= viewrect
.MinY
- data
->icld_ViewY
+ entry
->ie_IconY
;
4098 iconrect
.MaxY
+= viewrect
.MinY
- data
->icld_ViewY
+ entry
->ie_IconY
;
4100 if (RectAndRect(&viewrect
, &iconrect
))
4102 DoMethod(obj
, MUIM_IconList_DrawEntry
, entry
, ICONENTRY_DRAWMODE_PLAIN
);
4103 DoMethod(obj
, MUIM_IconList_DrawEntryLabel
, entry
, ICONENTRY_DRAWMODE_PLAIN
);
4109 if (data
->icld_DisplayRastPort
!= data
->icld_BufferRastPort
)
4111 #if defined(DEBUG_ILC_ICONRENDERING)
4112 D(bug("[IconList] %s#%d: MADF_DRAWOBJECT: Blitting to front rastport..\n", __PRETTY_FUNCTION__
, draw_id
));
4114 BltBitMapRastPort(data
->icld_BufferRastPort
->BitMap
,
4116 data
->icld_DisplayRastPort
,
4117 _mleft(obj
), _mtop(obj
),
4118 _mwidth(obj
), _mheight(obj
),
4122 MUI_RemoveClipping(muiRenderInfo(obj
), clip
);
4124 data
->icld_UpdateMode
= 0;
4128 #if defined(DEBUG_ILC_ICONRENDERING)
4129 D(bug("[IconList] %s: Draw finished for id %d\n", __PRETTY_FUNCTION__
, draw_id
));
4135 ///IconList__MUIM_IconList_Update()
4136 /**************************************************************************
4137 MUIM_IconList_Refresh
4138 Implemented by subclasses
4139 **************************************************************************/
4140 IPTR
IconList__MUIM_IconList_Update(struct IClass
*CLASS
, Object
*obj
, struct MUIP_IconList_Update
*message
)
4142 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
4144 #if defined(DEBUG_ILC_FUNCS)
4145 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
4148 data
->icld_FocusIcon
= NULL
;
4149 SET(obj
, MUIA_IconList_Changed
, TRUE
);
4155 ///MUIM_IconList_Clear()
4156 /**************************************************************************
4158 **************************************************************************/
4159 IPTR
IconList__MUIM_IconList_Clear(struct IClass
*CLASS
, Object
*obj
, struct MUIP_IconList_Clear
*message
)
4161 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
4162 struct IconEntry
*node
= NULL
;
4164 #if defined(DEBUG_ILC_FUNCS)
4165 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
4168 while ((node
= (struct IconEntry
*)RemTail((struct List
*)&data
->icld_IconList
)))
4170 DoMethod(obj
, MUIM_IconList_DestroyEntry
, node
);
4173 data
->icld_SelectionLastClicked
= NULL
;
4174 data
->icld_FocusIcon
= NULL
;
4176 data
->icld_ViewX
= data
->icld_ViewY
= data
->icld_AreaWidth
= data
->icld_AreaHeight
= 0;
4177 data
->icld_IconAreaLargestWidth
= 0;
4178 data
->icld_IconAreaLargestHeight
= 0;
4179 data
->icld_IconLargestHeight
= 0;
4180 data
->icld_LabelLargestHeight
= 0;
4182 #if defined(DEBUG_ILC_ICONRENDERING)
4183 D(bug("[IconList]: %s: call SetSuperAttrs()\n", __PRETTY_FUNCTION__
));
4185 SetSuperAttrs(CLASS
, obj
, MUIA_Virtgroup_Left
, data
->icld_ViewX
,
4186 MUIA_Virtgroup_Top
, data
->icld_ViewY
,
4189 #if defined(DEBUG_ILC_ICONRENDERING)
4190 D(bug("[IconList]: %s: call SetAttrs()\n", __PRETTY_FUNCTION__
));
4192 SetAttrs(obj
, MUIA_Virtgroup_Left
, data
->icld_ViewX
,
4193 MUIA_Virtgroup_Top
, data
->icld_ViewY
,
4196 #if defined(DEBUG_ILC_ICONRENDERING)
4197 D(bug("[IconList]: %s: Set MUIA_IconList_Width and MUIA_IconList_Height\n", __PRETTY_FUNCTION__
));
4199 SetAttrs(obj
, MUIA_IconList_Width
, data
->icld_AreaWidth
,
4200 MUIA_IconList_Height
, data
->icld_AreaHeight
,
4203 D(bug("[IconList]: %s: call MUI_Redraw()\n", __PRETTY_FUNCTION__
));
4204 MUI_Redraw(obj
,MADF_DRAWOBJECT
);
4209 ///IconList__MUIM_IconList_DestroyEntry()
4210 IPTR
IconList__MUIM_IconList_DestroyEntry(struct IClass
*CLASS
, Object
*obj
, struct MUIP_IconList_DestroyEntry
*message
)
4212 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
4214 #if defined(DEBUG_ILC_FUNCS)
4215 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
4220 if (message
->entry
->ie_Flags
& ICONENTRY_FLAG_SELECTED
)
4222 if (data
->icld_SelectionLastClicked
== message
->entry
)
4224 struct IconList_Entry
*nextentry
= &message
->entry
->ie_IconListEntry
;
4226 /* get selected entries from SOURCE iconlist */
4227 DoMethod(obj
, MUIM_IconList_NextIcon
, MUIV_IconList_NextIcon_Selected
, (IPTR
)&nextentry
);
4228 if ((nextentry
) && ((IPTR
)nextentry
!= MUIV_IconList_NextIcon_End
))
4229 data
->icld_SelectionLastClicked
= (struct IconEntry
*)((IPTR
)nextentry
- ((IPTR
)&message
->entry
->ie_IconListEntry
- (IPTR
)message
->entry
));
4231 data
->icld_SelectionLastClicked
= NULL
;
4233 if (data
->icld_FocusIcon
== message
->entry
)
4234 data
->icld_FocusIcon
= data
->icld_SelectionLastClicked
;
4236 Remove(&message
->entry
->ie_SelectionNode
);
4239 if (message
->entry
->ie_TxtBuf_DisplayedLabel
)
4240 FreeVecPooled(data
->icld_Pool
, message
->entry
->ie_TxtBuf_DisplayedLabel
);
4242 if (message
->entry
->ie_TxtBuf_PROT
)
4243 FreePooled(data
->icld_Pool
, message
->entry
->ie_TxtBuf_PROT
, 8);
4245 if (message
->entry
->ie_TxtBuf_SIZE
)
4246 FreePooled(data
->icld_Pool
, message
->entry
->ie_TxtBuf_SIZE
, 30);
4248 if (message
->entry
->ie_TxtBuf_TIME
)
4249 FreePooled(data
->icld_Pool
, message
->entry
->ie_TxtBuf_TIME
, LEN_DATSTRING
);
4251 if (message
->entry
->ie_TxtBuf_DATE
)
4252 FreePooled(data
->icld_Pool
, message
->entry
->ie_TxtBuf_DATE
, LEN_DATSTRING
);
4254 if (message
->entry
->ie_DiskObj
)
4255 FreeDiskObject(message
->entry
->ie_DiskObj
);
4257 if (message
->entry
->ie_FileInfoBlock
)
4258 FreeMem(message
->entry
->ie_FileInfoBlock
, sizeof(struct FileInfoBlock
));
4260 if (message
->entry
->ie_IconListEntry
.label
)
4261 FreePooled(data
->icld_Pool
, message
->entry
->ie_IconListEntry
.label
, strlen(message
->entry
->ie_IconListEntry
.label
)+1);
4263 if (message
->entry
->ie_IconNode
.ln_Name
)
4264 FreePooled(data
->icld_Pool
, message
->entry
->ie_IconNode
.ln_Name
, strlen(message
->entry
->ie_IconNode
.ln_Name
)+1);
4266 FreePooled(data
->icld_Pool
, message
->entry
, sizeof(struct IconEntry
));
4272 ///IconList__MUIM_IconList_PropagateEntryPos()
4273 IPTR
IconList__MUIM_IconList_PropagateEntryPos(struct IClass
*CLASS
, Object
*obj
,
4274 struct MUIP_IconList_PropagateEntryPos
*message
)
4276 message
->entry
->ie_ProvidedIconX
= message
->entry
->ie_IconX
;
4277 message
->entry
->ie_ProvidedIconY
= message
->entry
->ie_IconY
;
4283 ///IconList__MUIM_IconList_CreateEntry()
4284 /**************************************************************************
4285 MUIM_IconList_CreateEntry.
4286 Returns 0 on failure; otherwise it returns the icon's entry.
4287 **************************************************************************/
4288 IPTR
IconList__MUIM_IconList_CreateEntry(struct IClass
*CLASS
, Object
*obj
, struct MUIP_IconList_CreateEntry
*message
)
4290 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
4291 struct IconEntry
*entry
= NULL
;
4293 struct DateStamp now
;
4296 struct DiskObject
*dob
= NULL
;
4297 struct Rectangle rect
;
4299 IPTR geticon_error
= 0;
4301 #if defined(DEBUG_ILC_FUNCS)
4302 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
4305 if (message
->filename
== NULL
) {
4306 D(bug("[IconList] %s: IconList - filename was NULL\n", __PRETTY_FUNCTION__
));
4310 /*disk object (icon)*/
4311 if (message
->entry_dob
== NULL
)
4313 IPTR iconlistScreen
= (IPTR
)_screen(obj
);
4314 D(bug("[IconList] %s: IconList Screen @ 0x%p)\n", __PRETTY_FUNCTION__
, iconlistScreen
));
4319 (iconlistScreen
) ? ICONGETA_Screen
: TAG_IGNORE
, iconlistScreen
,
4320 (iconlistScreen
) ? ICONGETA_RemapIcon
: TAG_IGNORE
, TRUE
,
4321 ICONGETA_FailIfUnavailable
, FALSE
,
4322 ICONGETA_GenerateImageMasks
, TRUE
,
4323 ICONA_ErrorCode
, &geticon_error
,
4329 D(bug("[IconList] %s: Fatal: Couldnt get DiskObject! (error code = 0x%p)\n", __PRETTY_FUNCTION__
, geticon_error
));
4336 dob
= message
->entry_dob
;
4339 D(bug("[IconList] %s: DiskObject @ 0x%p\n", __PRETTY_FUNCTION__
, dob
));
4341 if ((entry
= AllocPooled(data
->icld_Pool
, sizeof(struct IconEntry
))) == NULL
)
4343 D(bug("[IconList] %s: Failed to Allocate Entry Storage!\n", __PRETTY_FUNCTION__
));
4344 FreeDiskObject(dob
);
4347 memset(entry
, 0, sizeof(struct IconEntry
));
4348 entry
->ie_Flags
|= ICONENTRY_FLAG_NEEDSUPDATE
;
4349 entry
->ie_IconListEntry
.ile_IconEntry
= entry
;
4351 /* Allocate Text Buffers */
4353 if ((entry
->ie_TxtBuf_DATE
= AllocPooled(data
->icld_Pool
, LEN_DATSTRING
)) == NULL
)
4355 D(bug("[IconList] %s: Failed to Allocate Entry DATE Storage!\n", __PRETTY_FUNCTION__
));
4356 DoMethod(obj
, MUIM_IconList_DestroyEntry
, entry
);
4359 memset(entry
->ie_TxtBuf_DATE
, 0, LEN_DATSTRING
);
4361 if ((entry
->ie_TxtBuf_TIME
= AllocPooled(data
->icld_Pool
, LEN_DATSTRING
)) == NULL
)
4363 D(bug("[IconList] %s: Failed to Allocate Entry TIME string Storage!\n", __PRETTY_FUNCTION__
));
4364 DoMethod(obj
, MUIM_IconList_DestroyEntry
, entry
);
4367 memset(entry
->ie_TxtBuf_TIME
, 0, LEN_DATSTRING
);
4369 if ((entry
->ie_TxtBuf_SIZE
= AllocPooled(data
->icld_Pool
, 30)) == NULL
)
4371 D(bug("[IconList] %s: Failed to Allocate Entry SIZE string Storage!\n", __PRETTY_FUNCTION__
));
4372 DoMethod(obj
, MUIM_IconList_DestroyEntry
, entry
);
4375 memset(entry
->ie_TxtBuf_SIZE
, 0, 30);
4377 if ((entry
->ie_TxtBuf_PROT
= AllocPooled(data
->icld_Pool
, 8)) == NULL
)
4379 D(bug("[IconList] %s: Failed to Allocate Entry PROT Flag string Storage!\n", __PRETTY_FUNCTION__
));
4380 DoMethod(obj
, MUIM_IconList_DestroyEntry
, entry
);
4383 memset(entry
->ie_TxtBuf_PROT
, 0, 8);
4386 if ((entry
->ie_IconNode
.ln_Name
= AllocPooled(data
->icld_Pool
, strlen(message
->filename
) + 1)) == NULL
)
4388 D(bug("[IconList] %s: Failed to Allocate Entry filename string Storage!\n", __PRETTY_FUNCTION__
));
4389 DoMethod(obj
, MUIM_IconList_DestroyEntry
, entry
);
4393 /*alloc entry label*/
4394 if ((entry
->ie_IconListEntry
.label
= AllocPooled(data
->icld_Pool
, strlen(message
->label
) + 1)) == NULL
)
4396 D(bug("[IconList] %s: Failed to Allocate Entry label string Storage!\n", __PRETTY_FUNCTION__
));
4397 DoMethod(obj
, MUIM_IconList_DestroyEntry
, entry
);
4402 if(message
->fib
!= NULL
)
4404 if ((entry
->ie_FileInfoBlock
= AllocMem(sizeof(struct FileInfoBlock
), MEMF_CLEAR
)) != NULL
)
4406 CopyMem(message
->fib
, entry
->ie_FileInfoBlock
, sizeof(struct FileInfoBlock
));
4408 if (entry
->ie_FileInfoBlock
->fib_DirEntryType
> 0)
4410 strcpy(entry
->ie_TxtBuf_SIZE
, "Drawer");
4414 FmtSizeToString(entry
->ie_TxtBuf_SIZE
, entry
->ie_FileInfoBlock
->fib_Size
);
4417 dt
.dat_Stamp
= entry
->ie_FileInfoBlock
->fib_Date
;
4418 dt
.dat_Format
= FORMAT_DEF
;
4420 dt
.dat_StrDay
= NULL
;
4421 dt
.dat_StrDate
= entry
->ie_TxtBuf_DATE
;
4422 dt
.dat_StrTime
= entry
->ie_TxtBuf_TIME
;
4427 /*if modified today show time, otherwise just show date*/
4428 if (now
.ds_Days
== entry
->ie_FileInfoBlock
->fib_Date
.ds_Days
)
4429 entry
->ie_Flags
|= ICONENTRY_FLAG_TODAY
;
4431 entry
->ie_Flags
&= ~ICONENTRY_FLAG_TODAY
;
4433 sp
= entry
->ie_TxtBuf_PROT
;
4434 *sp
++ = (entry
->ie_FileInfoBlock
->fib_Protection
& FIBF_SCRIPT
) ? 's' : '-';
4435 *sp
++ = (entry
->ie_FileInfoBlock
->fib_Protection
& FIBF_PURE
) ? 'p' : '-';
4436 *sp
++ = (entry
->ie_FileInfoBlock
->fib_Protection
& FIBF_ARCHIVE
) ? 'a' : '-';
4437 *sp
++ = (entry
->ie_FileInfoBlock
->fib_Protection
& FIBF_READ
) ? '-' : 'r';
4438 *sp
++ = (entry
->ie_FileInfoBlock
->fib_Protection
& FIBF_WRITE
) ? '-' : 'w';
4439 *sp
++ = (entry
->ie_FileInfoBlock
->fib_Protection
& FIBF_EXECUTE
) ? '-' : 'e';
4440 *sp
++ = (entry
->ie_FileInfoBlock
->fib_Protection
& FIBF_DELETE
) ? '-' : 'd';
4443 entry
->ie_IconListEntry
.type
= entry
->ie_FileInfoBlock
->fib_DirEntryType
;
4448 entry
->ie_IconListEntry
.type
= ST_USERDIR
;
4451 /* Override type if specified during CreateEntry */
4452 if (message
->type
!= 0)
4454 entry
->ie_IconListEntry
.type
= message
->type
;
4455 D(bug("[IconList] %s: Overide Entry Type. New Type = %x\n", __PRETTY_FUNCTION__
, entry
->ie_IconListEntry
.type
));
4459 D(bug("[IconList] %s: Entry Type = %x\n", __PRETTY_FUNCTION__
, entry
->ie_IconListEntry
.type
));
4462 strcpy(entry
->ie_IconNode
.ln_Name
, message
->filename
);
4463 strcpy(entry
->ie_IconListEntry
.label
, message
->label
);
4465 entry
->ie_IconListEntry
.udata
= message
->udata
;
4467 entry
->ie_IconX
= dob
->do_CurrentX
;
4468 entry
->ie_IconY
= dob
->do_CurrentY
;
4470 DoMethod(obj
, MUIM_IconList_PropagateEntryPos
, entry
);
4472 if (IconList__LabelFunc_CreateLabel(obj
, data
, entry
) != (IPTR
)NULL
)
4474 entry
->ie_DiskObj
= dob
;
4476 /* Use a geticonrectangle routine that gets textwidth! */
4477 IconList_GetIconAreaRectangle(obj
, data
, entry
, &rect
);
4482 DoMethod(obj
, MUIM_IconList_DestroyEntry
, entry
);
4487 ///IconList__MUIM_IconList_UpdateEntry()
4488 /**************************************************************************
4489 MUIM_IconList_UpdateEntry.
4490 Returns 0 on failure; otherwise it returns the icon's entry.
4491 **************************************************************************/
4492 IPTR
IconList__MUIM_IconList_UpdateEntry(struct IClass
*CLASS
, Object
*obj
, struct MUIP_IconList_UpdateEntry
*message
)
4494 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
4495 // struct DateTime dt;
4496 // struct DateStamp now;
4497 // UBYTE *sp = NULL;
4499 // struct DiskObject *dob = NULL;
4500 struct Rectangle rect
;
4502 // IPTR geticon_error = 0;
4504 #if defined(DEBUG_ILC_FUNCS)
4505 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
4508 /* Update disk object (icon)*/
4509 /* if (message->entry_dob == NULL)
4511 IPTR iconlistScreen = _screen(obj);
4512 D(bug("[IconList] %s: IconList Screen @ 0x%p)\n", __PRETTY_FUNCTION__, iconlistScreen));
4517 (iconlistScreen) ? ICONGETA_Screen : TAG_IGNORE, iconlistScreen,
4518 (iconlistScreen) ? ICONGETA_RemapIcon : TAG_IGNORE, TRUE,
4519 ICONGETA_FailIfUnavailable, FALSE,
4520 ICONGETA_GenerateImageMasks, TRUE,
4521 ICONA_ErrorCode, &geticon_error,
4527 D(bug("[IconList] %s: Fatal: Couldnt get DiskObject! (error code = 0x%p)\n", __PRETTY_FUNCTION__, geticon_error));
4534 dob = message->entry_dob;
4537 D(bug("[IconList] %s: DiskObject @ 0x%p\n", __PRETTY_FUNCTION__, dob));
4540 /* Update filename */
4541 if (strcmp(message
->entry
->ie_IconNode
.ln_Name
, message
->filename
) != 0)
4543 message
->entry
->ie_Flags
|= ICONENTRY_FLAG_NEEDSUPDATE
;
4544 FreePooled(data
->icld_Pool
, message
->entry
->ie_IconNode
.ln_Name
, strlen(message
->entry
->ie_IconNode
.ln_Name
) + 1);
4545 if ((message
->entry
->ie_IconNode
.ln_Name
= AllocPooled(data
->icld_Pool
, strlen(message
->filename
) + 1)) == NULL
)
4547 D(bug("[IconList] %s: Failed to Allocate Entry filename string Storage!\n", __PRETTY_FUNCTION__
));
4548 DoMethod(obj
, MUIM_IconList_DestroyEntry
, message
->entry
);
4551 strcpy(message
->entry
->ie_IconNode
.ln_Name
, message
->filename
);
4554 /* Update entry label */
4555 if (strcmp(message
->entry
->ie_IconListEntry
.label
, message
->label
) != 0)
4557 message
->entry
->ie_Flags
|= ICONENTRY_FLAG_NEEDSUPDATE
;
4558 FreePooled(data
->icld_Pool
, message
->entry
->ie_IconListEntry
.label
, strlen(message
->entry
->ie_IconListEntry
.label
) + 1);
4559 if ((message
->entry
->ie_IconListEntry
.label
= AllocPooled(data
->icld_Pool
, strlen(message
->label
) + 1)) == NULL
)
4561 D(bug("[IconList] %s: Failed to Allocate Entry label string Storage!\n", __PRETTY_FUNCTION__
));
4562 DoMethod(obj
, MUIM_IconList_DestroyEntry
, message
->entry
);
4565 strcpy(message
->entry
->ie_IconListEntry
.label
, message
->label
);
4566 if (IconList__LabelFunc_CreateLabel(obj
, data
, message
->entry
) == (IPTR
)NULL
)
4568 D(bug("[IconList] %s: Failed to create label\n", __PRETTY_FUNCTION__
));
4569 DoMethod(obj
, MUIM_IconList_DestroyEntry
, message
->entry
);
4574 /* Update file info block */
4575 if(message
->fib
!= NULL
)
4577 if (!(message
->entry
->ie_FileInfoBlock
))
4579 if ((message
->entry
->ie_FileInfoBlock
= AllocMem(sizeof(struct FileInfoBlock
), MEMF_CLEAR
)) != NULL
)
4581 CopyMem(message
->fib
, message
->entry
->ie_FileInfoBlock
, sizeof(struct FileInfoBlock
));
4585 /* if (entry->ie_FileInfoBlock->fib_DirEntryType > 0)
4587 strcpy(entry->ie_TxtBuf_SIZE, "Drawer");
4591 FmtSizeToString(entry->ie_TxtBuf_SIZE, entry->ie_FileInfoBlock->fib_Size);
4594 dt.dat_Stamp = entry->ie_FileInfoBlock->fib_Date;
4595 dt.dat_Format = FORMAT_DEF;
4597 dt.dat_StrDay = NULL;
4598 dt.dat_StrDate = entry->ie_TxtBuf_DATE;
4599 dt.dat_StrTime = entry->ie_TxtBuf_TIME;
4604 //if modified today show time, otherwise just show date
4605 if (now.ds_Days == entry->ie_FileInfoBlock->fib_Date.ds_Days)
4606 entry->ie_Flags |= ICONENTRY_FLAG_TODAY;
4608 entry->ie_Flags &= ~ICONENTRY_FLAG_TODAY;
4610 sp = entry->ie_TxtBuf_PROT;
4611 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_SCRIPT) ? 's' : '-';
4612 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_PURE) ? 'p' : '-';
4613 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_ARCHIVE) ? 'a' : '-';
4614 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_READ) ? '-' : 'r';
4615 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_WRITE) ? '-' : 'w';
4616 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_EXECUTE) ? '-' : 'e';
4617 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_DELETE) ? '-' : 'd';
4620 entry->ie_IconListEntry.type = entry->ie_FileInfoBlock->fib_DirEntryType;
4625 if (message
->entry
->ie_FileInfoBlock
)
4627 FreeMem(message
->entry
->ie_FileInfoBlock
, sizeof(struct FileInfoBlock
));
4628 message
->entry
->ie_FileInfoBlock
= NULL
;
4630 if (message
->entry
->ie_IconListEntry
.type
!= ST_USERDIR
)
4632 message
->entry
->ie_Flags
|= ICONENTRY_FLAG_NEEDSUPDATE
;
4633 message
->entry
->ie_IconListEntry
.type
= ST_USERDIR
;
4637 /* Override type if specified */
4638 if ((message
->type
!= 0) && (message
->entry
->ie_IconListEntry
.type
!= message
->type
))
4640 message
->entry
->ie_Flags
|= ICONENTRY_FLAG_NEEDSUPDATE
;
4641 message
->entry
->ie_IconListEntry
.type
= message
->type
;
4642 D(bug("[IconList] %s: Overide Entry Type. New Type = %x\n", __PRETTY_FUNCTION__
, message
->entry
->ie_IconListEntry
.type
));
4646 D(bug("[IconList] %s: Entry Type = %x\n", __PRETTY_FUNCTION__
, message
->entry
->ie_IconListEntry
.type
));
4649 IconList_GetIconAreaRectangle(obj
, data
, message
->entry
, &rect
);
4651 return (IPTR
)message
->entry
;
4656 static void DoWheelMove(struct IClass
*CLASS
, Object
*obj
, LONG wheelx
, LONG wheely
, UWORD qual
)
4658 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
4660 LONG newleft
= data
->icld_ViewX
,
4661 newtop
= data
->icld_ViewY
;
4663 /* Use horizontal scrolling if any of the following cases are true ...
4665 # vertical wheel is used but there's nothing to scroll
4666 (everything is visible already) ..
4668 # vertical wheel is used and one of the ALT keys is down. */
4670 if ((wheely
&& !wheelx
) &&
4671 ((data
->icld_AreaHeight
<= _mheight(obj
)) || (qual
& (IEQUALIFIER_LALT
| IEQUALIFIER_RALT
))))
4673 wheelx
= wheely
; wheely
= 0;
4676 if (qual
& (IEQUALIFIER_CONTROL
))
4678 if (wheelx
< 0) newleft
= 0;
4679 if (wheelx
> 0) newleft
= data
->icld_AreaWidth
;
4680 if (wheely
< 0) newtop
= 0;
4681 if (wheely
> 0) newtop
= data
->icld_AreaHeight
;
4683 else if (qual
& (IEQUALIFIER_LSHIFT
| IEQUALIFIER_RSHIFT
))
4685 newleft
+= (wheelx
* _mwidth(obj
));
4686 newtop
+= (wheely
* _mheight(obj
));
4690 newleft
+= wheelx
* 30;
4691 newtop
+= wheely
* 30;
4694 if (newleft
+ _mwidth(obj
) > data
->icld_AreaWidth
)
4695 newleft
= data
->icld_AreaWidth
- _mwidth(obj
);
4699 if (newtop
+ _mheight(obj
) > data
->icld_AreaHeight
)
4700 newtop
= data
->icld_AreaHeight
- _mheight(obj
);
4704 if ((newleft
!= data
->icld_ViewX
) || (newtop
!= data
->icld_ViewY
))
4706 SetAttrs(obj
, MUIA_Virtgroup_Left
, newleft
,
4707 MUIA_Virtgroup_Top
, newtop
,
4716 * a) if clicked object is selected, nothing
4717 * b) if clicked object is not selected, unselect all, select object
4718 * c) if no clicked object, start lasso
4720 * a) if in lasso, finish lasso
4722 * a) if object is selected, unselect it (= remove from multiselection)
4723 * b) if object is not selected, select it (= add to multiselection)
4726 * Expected behaviour:
4727 * a) you can only "remove" multiselection by clicking on not selected object or on space where there is no icon
4731 static void IconList_HandleNewIconSelection(struct IClass
*CLASS
, Object
*obj
, struct MUIP_HandleEvent
*message
,
4732 struct IconEntry
*new_selected
, BOOL
*doubleclicked
)
4734 struct IconEntry
*node
= NULL
;
4735 BOOL update_entry
= FALSE
;
4736 LONG mx
= message
->imsg
->MouseX
- _mleft(obj
);
4737 LONG my
= message
->imsg
->MouseY
- _mtop(obj
);
4738 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
4739 BOOL nounselection
= (new_selected
!= NULL
&&
4740 (new_selected
->ie_Flags
& ICONENTRY_FLAG_SELECTED
)); /* see notes above */
4743 /* Check if this is a double click on icon or empty space */
4744 if ((DoubleClick(data
->last_secs
, data
->last_mics
, message
->imsg
->Seconds
, message
->imsg
->Micros
)) && (data
->icld_SelectionLastClicked
== new_selected
))
4746 #if defined(DEBUG_ILC_EVENTS)
4747 D(bug("[IconList] %s: Entry double-clicked\n", __PRETTY_FUNCTION__
));
4749 *doubleclicked
= TRUE
;
4752 /* Deselection lopp */
4753 #if defined(__AROS__)
4754 ForeachNode(&data
->icld_IconList
, node
)
4756 Foreach_Node(&data
->icld_IconList
, node
);
4759 if (node
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
4761 update_entry
= FALSE
;
4763 /* If node that is being checked is selected and it is not the clicked node
4764 * and no shift pressed and
4765 * clicked node is not part of selection (see notes above) or this is a double click */
4766 if (node
->ie_Flags
& ICONENTRY_FLAG_SELECTED
)
4768 if ((new_selected
!= node
) &&
4769 (!(message
->imsg
->Qualifier
& (IEQUALIFIER_LSHIFT
| IEQUALIFIER_RSHIFT
))) &&
4770 (!nounselection
|| *doubleclicked
))
4772 Remove(&node
->ie_SelectionNode
);
4773 node
->ie_Flags
&= ~ICONENTRY_FLAG_SELECTED
;
4774 update_entry
= TRUE
;
4779 if ((node
->ie_Flags
& ICONENTRY_FLAG_FOCUS
) && (new_selected
!= node
))
4781 node
->ie_Flags
&= ~ICONENTRY_FLAG_FOCUS
;
4782 update_entry
= TRUE
;
4788 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
4789 data
->update_entry
= node
;
4790 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
4791 #if defined(DEBUG_ILC_EVENTS)
4792 D(bug("[IconList] %s: Rendered entry '%s'\n", __PRETTY_FUNCTION__
, node
->ie_IconListEntry
.label
));
4798 if (new_selected
!= NULL
)
4800 /* Found clicked entry... */
4801 data
->icld_LassoActive
= FALSE
;
4802 update_entry
= FALSE
;
4804 if (!(new_selected
->ie_Flags
& ICONENTRY_FLAG_SELECTED
))
4806 /* Add new entry to selection */
4807 AddTail(&data
->icld_SelectionList
, &new_selected
->ie_SelectionNode
);
4808 new_selected
->ie_Flags
|= ICONENTRY_FLAG_SELECTED
;
4809 update_entry
= TRUE
;
4811 else if ((*doubleclicked
== FALSE
) && (message
->imsg
->Qualifier
& (IEQUALIFIER_LSHIFT
| IEQUALIFIER_RSHIFT
)))
4813 /* Unselect previously selected entry */
4814 Remove(&new_selected
->ie_SelectionNode
);
4815 new_selected
->ie_Flags
&= ~ICONENTRY_FLAG_SELECTED
;
4816 update_entry
= TRUE
;
4820 if (!(new_selected
->ie_Flags
& ICONENTRY_FLAG_FOCUS
))
4822 new_selected
->ie_Flags
|= ICONENTRY_FLAG_FOCUS
;
4823 data
->icld_FocusIcon
= new_selected
;
4824 update_entry
= TRUE
;
4830 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
4831 data
->update_entry
= new_selected
;
4832 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
4833 #if defined(DEBUG_ILC_EVENTS)
4834 D(bug("[IconList] %s: Rendered 'new_selected' entry '%s'\n", __PRETTY_FUNCTION__
, new_selected
->ie_IconListEntry
.label
));
4840 struct Window
* thisWindow
= NULL
;
4841 #if defined(DEBUG_ILC_EVENTS) || defined(DEBUG_ILC_LASSO)
4842 D(bug("[IconList] %s: Starting Lasso\n", __PRETTY_FUNCTION__
));
4844 /* No entry clicked on ... Start Lasso-selection */
4845 data
->icld_LassoActive
= TRUE
;
4846 if (!(message
->imsg
->Qualifier
& (IEQUALIFIER_LSHIFT
| IEQUALIFIER_RSHIFT
)))
4848 data
->icld_SelectionLastClicked
= NULL
;
4849 data
->icld_FocusIcon
= NULL
;
4851 data
->icld_LassoRectangle
.MinX
= mx
- data
->view_rect
.MinX
+ data
->icld_ViewX
;
4852 data
->icld_LassoRectangle
.MinY
= my
- data
->view_rect
.MinY
+ data
->icld_ViewY
;
4853 data
->icld_LassoRectangle
.MaxX
= mx
- data
->view_rect
.MinX
+ data
->icld_ViewX
;
4854 data
->icld_LassoRectangle
.MaxY
= my
- data
->view_rect
.MinY
+ data
->icld_ViewY
;
4856 /* Draw initial Lasso frame */
4857 IconList_InvertLassoOutlines(obj
, data
, &data
->icld_LassoRectangle
);
4859 /* Start handling INTUITICKS */
4860 GET(obj
, MUIA_Window
, &thisWindow
);
4863 ModifyIDCMP(thisWindow
, (thisWindow
->IDCMPFlags
|IDCMP_INTUITICKS
));
4864 if (!(data
->ehn
.ehn_Events
& IDCMP_INTUITICKS
))
4866 DoMethod(_win(obj
), MUIM_Window_RemEventHandler
, (IPTR
)&data
->ehn
);
4867 data
->ehn
.ehn_Events
|= IDCMP_INTUITICKS
;
4868 DoMethod(_win(obj
), MUIM_Window_AddEventHandler
, (IPTR
)&data
->ehn
);
4874 ///MUIM_HandleEvent()
4875 /**************************************************************************
4877 **************************************************************************/
4878 IPTR
IconList__MUIM_HandleEvent(struct IClass
*CLASS
, Object
*obj
, struct MUIP_HandleEvent
*message
)
4880 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
4882 #if defined(DEBUG_ILC_FUNCS)
4883 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
4888 LONG mx
= message
->imsg
->MouseX
- _mleft(obj
);
4889 LONG my
= message
->imsg
->MouseY
- _mtop(obj
);
4894 switch (message
->imsg
->Class
)
4897 bug("[IconList] %s: IDCMP_NEWSIZE\n", __PRETTY_FUNCTION__
);
4902 #if defined(DEBUG_ILC_EVENTS)
4903 D(bug("[IconList] %s: IDCMP_RAWKEY\n", __PRETTY_FUNCTION__
));
4905 BOOL rawkey_handled
= FALSE
;
4907 switch(message
->imsg
->Code
)
4909 case RAWKEY_NM_WHEEL_UP
:
4911 rawkey_handled
= TRUE
;
4914 case RAWKEY_NM_WHEEL_DOWN
:
4916 rawkey_handled
= TRUE
;
4919 case RAWKEY_NM_WHEEL_LEFT
:
4921 rawkey_handled
= TRUE
;
4924 case RAWKEY_NM_WHEEL_RIGHT
:
4926 rawkey_handled
= TRUE
;
4930 /* Remove the lasso if a key is pressed or the mouse wheel is used */
4931 NullifyLasso(data
, obj
);
4935 #if defined(DEBUG_ILC_KEYEVENTS)
4936 D(bug("[IconList] %s: Processing mouse wheel event\n", __PRETTY_FUNCTION__
));
4938 if (_isinobject(message
->imsg
->MouseX
, message
->imsg
->MouseY
) &&
4941 DoWheelMove(CLASS
, obj
, wheelx
, wheely
, message
->imsg
->Qualifier
);
4944 else if (!(message
->imsg
->Code
& IECODE_UP_PREFIX
))
4946 LONG new_ViewY
= data
->icld_ViewY
;
4947 struct IconEntry
*start_entry
= NULL
, *active_entry
= NULL
, *entry_next
= NULL
;
4948 IPTR start_X
= 0, start_Y
= 0, active_X
= 0, active_Y
= 0, next_X
= 0, next_Y
= 0;
4951 #if defined(DEBUG_ILC_KEYEVENTS)
4952 D(bug("[IconList] %s: Processing key up event\n", __PRETTY_FUNCTION__
));
4955 switch(message
->imsg
->Code
)
4958 rawkey_handled
= TRUE
;
4960 #if defined(DEBUG_ILC_KEYEVENTS)
4961 D(bug("[IconList] %s: RAWKEY_RETURN\n", __PRETTY_FUNCTION__
));
4964 if (data
->icld_FocusIcon
) active_entry
= data
->icld_FocusIcon
;
4965 else if (data
->icld_SelectionLastClicked
) active_entry
= data
->icld_SelectionLastClicked
;
4969 if (!(active_entry
->ie_Flags
& ICONENTRY_FLAG_SELECTED
))
4971 active_entry
->ie_Flags
|= ICONENTRY_FLAG_SELECTED
;
4972 AddTail(&data
->icld_SelectionList
, &active_entry
->ie_SelectionNode
);
4973 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
4974 data
->update_entry
= active_entry
;
4975 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
4977 data
->icld_SelectionLastClicked
= active_entry
;
4978 data
->icld_FocusIcon
= active_entry
;
4980 SET(obj
, MUIA_IconList_DoubleClick
, TRUE
);
4985 rawkey_handled
= TRUE
;
4987 #if defined(DEBUG_ILC_KEYEVENTS)
4988 D(bug("[IconList] %s: RAWKEY_SPACE\n", __PRETTY_FUNCTION__
));
4991 if (data
->icld_FocusIcon
) active_entry
= data
->icld_FocusIcon
;
4992 else if (data
->icld_SelectionLastClicked
) active_entry
= data
->icld_SelectionLastClicked
;
4994 if (!(message
->imsg
->Qualifier
& IEQUALIFIER_LSHIFT
) && ((data
->icld_SelectionLastClicked
)||(data
->icld_SelectionLastClicked
!= active_entry
)))
4996 #if defined(DEBUG_ILC_KEYEVENTS)
4997 D(bug("[IconList] %s: SPACE: Clearing selected icons ..\n", __PRETTY_FUNCTION__
));
4999 DoMethod(obj
, MUIM_IconList_UnselectAll
);
5004 if (!(active_entry
->ie_Flags
& ICONENTRY_FLAG_SELECTED
))
5006 AddTail(&data
->icld_SelectionList
, &active_entry
->ie_SelectionNode
);
5007 active_entry
->ie_Flags
|= ICONENTRY_FLAG_SELECTED
;
5008 data
->icld_SelectionLastClicked
= active_entry
;
5012 Remove(&active_entry
->ie_SelectionNode
);
5013 active_entry
->ie_Flags
&= ~ICONENTRY_FLAG_SELECTED
;
5016 data
->icld_FocusIcon
= active_entry
;
5018 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
5019 data
->update_entry
= active_entry
;
5020 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
5025 rawkey_handled
= TRUE
;
5027 #if defined(DEBUG_ILC_KEYEVENTS)
5028 D(bug("[IconList] %s: RAWKEY_PAGEUP\n", __PRETTY_FUNCTION__
));
5031 if (data
->icld_AreaHeight
> data
->icld_ViewHeight
)
5033 new_ViewY
-= data
->icld_ViewHeight
;
5038 if (new_ViewY
!= data
->icld_ViewY
)
5040 SET(obj
, MUIA_Virtgroup_Top
, new_ViewY
);
5044 case RAWKEY_PAGEDOWN
:
5045 rawkey_handled
= TRUE
;
5047 #if defined(DEBUG_ILC_KEYEVENTS)
5048 D(bug("[IconList] %s: RAWKEY_PAGEDOWN\n", __PRETTY_FUNCTION__
));
5051 if (data
->icld_AreaHeight
> data
->icld_ViewHeight
)
5053 new_ViewY
+= data
->icld_ViewHeight
;
5054 if (new_ViewY
> (data
->icld_AreaHeight
- data
->icld_ViewHeight
))
5055 new_ViewY
= data
->icld_AreaHeight
- data
->icld_ViewHeight
;
5058 if (new_ViewY
!= data
->icld_ViewY
)
5060 SET(obj
, MUIA_Virtgroup_Top
, new_ViewY
);
5065 rawkey_handled
= TRUE
;
5067 #if defined(DEBUG_ILC_KEYEVENTS)
5068 D(bug("[IconList] %s: RAWKEY_UP\n", __PRETTY_FUNCTION__
));
5071 if (data
->icld_FocusIcon
)
5073 start_entry
= data
->icld_FocusIcon
;
5074 #if defined(DEBUG_ILC_KEYEVENTS)
5075 D(bug("[IconList] %s: UP: Clearing existing focused entry @ 0x%p\n", __PRETTY_FUNCTION__
, start_entry
));
5078 start_entry
->ie_Flags
&= ~ICONENTRY_FLAG_FOCUS
;
5079 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
5080 data
->update_entry
= start_entry
;
5081 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
5083 start_X
= start_entry
->ie_IconX
;
5084 start_Y
= start_entry
->ie_IconY
;
5085 #if defined(DEBUG_ILC_KEYEVENTS)
5086 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
));
5088 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
5090 if (start_entry
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
5092 start_X
= start_X
- ((data
->icld_IconAreaLargestWidth
- start_entry
->ie_AreaWidth
)/2);
5093 #if defined(DEBUG_ILC_KEYEVENTS)
5094 D(bug("[IconList] %s: UP: adjusted start_X for grid = %d\n", __PRETTY_FUNCTION__
, start_X
));
5099 if ((active_entry
= Node_PreviousVisible(start_entry
)) && !(data
->icld_DisplayFlags
& ICONLIST_DISP_VERTICAL
))
5101 //Check if we are at the edge of the entry area ..
5102 #if defined(DEBUG_ILC_KEYEVENTS)
5103 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
));
5105 active_Y
= active_entry
->ie_IconY
;
5107 if (active_Y
== start_Y
)
5110 #if defined(DEBUG_ILC_KEYEVENTS)
5111 D(bug("[IconList] %s: UP: active_entry is on our row (not at the edge)\n", __PRETTY_FUNCTION__
));
5113 entry_next
= active_entry
;
5114 next_X
= entry_next
->ie_IconX
;
5115 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
5117 if (entry_next
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
5118 next_X
= next_X
- ((data
->icld_IconAreaLargestWidth
- entry_next
->ie_AreaWidth
)/2);
5122 #if defined(DEBUG_ILC_KEYEVENTS)
5123 D(bug("[IconList] %s: UP: using start_X %d, start_Y %d\n", __PRETTY_FUNCTION__
, start_X
, start_Y
));
5127 if (!(message
->imsg
->Qualifier
& IEQUALIFIER_LSHIFT
) && ((data
->icld_SelectionLastClicked
)&&(data
->icld_SelectionLastClicked
!= active_entry
)))
5129 #if defined(DEBUG_ILC_KEYEVENTS)
5130 D(bug("[IconList] %s: UP: Clearing selected icons ..\n", __PRETTY_FUNCTION__
));
5132 DoMethod(obj
, MUIM_IconList_UnselectAll
);
5135 #if defined(DEBUG_ILC_KEYEVENTS)
5136 D(bug("[IconList] %s: UP: active = 0x%p, next = 0x%p\n", __PRETTY_FUNCTION__
, active_entry
, entry_next
));
5138 if (!(active_entry
))
5140 // If nothing is selected we will use the last visible entry ..
5141 active_entry
= Node_LastVisible(&data
->icld_IconList
);
5142 start_X
= active_entry
->ie_IconX
;
5143 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
5145 if (active_entry
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
5146 start_X
= start_X
- ((data
->icld_IconAreaLargestWidth
- active_entry
->ie_AreaWidth
)/2);
5148 start_Y
= active_entry
->ie_IconY
;
5151 while (active_entry
!= NULL
)
5153 #if defined(DEBUG_ILC_KEYEVENTS)
5154 D(bug("[IconList] %s: UP: Checking active @ 0x%p\n", __PRETTY_FUNCTION__
, active_entry
));
5156 if (data
->icld_DisplayFlags
& ICONLIST_DISP_VERTICAL
)
5158 // Return the first visible since the list flow direction matches
5159 // our cursor direction
5160 if (active_entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
5165 active_X
= active_entry
->ie_IconX
;
5167 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
5169 if (active_entry
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
5170 x_diff
= ((data
->icld_IconAreaLargestWidth
- active_entry
->ie_AreaWidth
)/2);
5172 active_Y
= active_entry
->ie_IconY
;
5178 if ((active_entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
) &&
5179 (active_Y
< start_Y
) &&
5180 (((active_X
- x_diff
) >= start_X
) &&
5181 ((active_X
- x_diff
) <= (start_X
+ start_entry
->ie_AreaWidth
+ (x_diff
*2)))))
5183 #if defined(DEBUG_ILC_KEYEVENTS)
5184 D(bug("[IconList] %s: UP: (A) entry 0x%p matches\n", __PRETTY_FUNCTION__
, active_entry
));
5188 else if (active_entry
== (struct IconEntry
*)GetHead(&data
->icld_IconList
))
5190 #if defined(DEBUG_ILC_KEYEVENTS)
5191 D(bug("[IconList] %s: UP: (A) reached list start .. restarting from the end ..\n", __PRETTY_FUNCTION__
));
5195 if ((entry_next
= Node_PreviousVisible(entry_next
)))
5197 if (entry_next
->ie_IconX
> start_X
)
5201 next_X
= entry_next
->ie_IconX
;
5202 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
5204 if (entry_next
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
5205 next_X
= next_X
- ((data
->icld_IconAreaLargestWidth
- entry_next
->ie_AreaWidth
)/2);
5210 #if defined(DEBUG_ILC_KEYEVENTS)
5211 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
));
5213 active_entry
= Node_LastVisible(&data
->icld_IconList
);
5218 if ((active_entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
) &&
5219 (active_Y
< start_Y
) &&
5220 ((active_X
+ x_diff
) < (start_X
+ start_entry
->ie_AreaWidth
+ x_diff
)))
5222 #if defined(DEBUG_ILC_KEYEVENTS)
5223 D(bug("[IconList] %s: UP: (B) entry 0x%p matches\n", __PRETTY_FUNCTION__
, active_entry
));
5231 if (active_entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
5233 #if defined(DEBUG_ILC_KEYEVENTS)
5234 D(bug("[IconList] %s: UP: (C) entry 0x%p matches\n", __PRETTY_FUNCTION__
, active_entry
));
5240 active_entry
= (struct IconEntry
*)(((struct Node
*)active_entry
)->ln_Pred
);
5243 if (!(active_entry
))
5245 #if defined(DEBUG_ILC_KEYEVENTS)
5246 D(bug("[IconList] %s: UP: No Next UP Node - Getting Last visible entry ..\n", __PRETTY_FUNCTION__
));
5248 /* We didnt find a "next UP" entry so just use the last visible */
5249 active_entry
= Node_LastVisible(&data
->icld_IconList
);
5254 if (!(active_entry
->ie_Flags
& ICONENTRY_FLAG_FOCUS
))
5256 active_entry
->ie_Flags
|= ICONENTRY_FLAG_FOCUS
;
5257 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
5258 data
->update_entry
= active_entry
;
5259 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
5262 data
->icld_FocusIcon
= active_entry
;
5266 rawkey_handled
= TRUE
;
5268 #if defined(DEBUG_ILC_KEYEVENTS)
5269 D(bug("[IconList] %s: RAWKEY_DOWN\n", __PRETTY_FUNCTION__
));
5271 if (data
->icld_FocusIcon
)
5273 start_entry
= data
->icld_FocusIcon
;
5274 #if defined(DEBUG_ILC_KEYEVENTS)
5275 D(bug("[IconList] %s: DOWN: Clearing existing focused entry @ 0x%p\n", __PRETTY_FUNCTION__
, start_entry
));
5278 start_entry
->ie_Flags
&= ~ICONENTRY_FLAG_FOCUS
;
5279 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
5280 data
->update_entry
= start_entry
;
5281 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
5283 start_X
= start_entry
->ie_IconX
;
5284 start_Y
= start_entry
->ie_IconY
;
5285 #if defined(DEBUG_ILC_KEYEVENTS)
5286 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
));
5288 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
5290 if (start_entry
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
5292 start_X
= start_X
- ((data
->icld_IconAreaLargestWidth
- start_entry
->ie_AreaWidth
)/2);
5293 #if defined(DEBUG_ILC_KEYEVENTS)
5294 D(bug("[IconList] %s: DOWN: adjusted start_X for grid = %d\n", __PRETTY_FUNCTION__
, start_X
));
5299 if ((active_entry
= Node_NextVisible(start_entry
)) &&
5300 (!(data
->icld_DisplayFlags
& ICONLIST_DISP_VERTICAL
)))
5302 #if defined(DEBUG_ILC_KEYEVENTS)
5303 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
));
5305 active_Y
= active_entry
->ie_IconY
;
5307 if (active_Y
== start_Y
)
5310 #if defined(DEBUG_ILC_KEYEVENTS)
5311 D(bug("[IconList] %s: DOWN: active_entry is on our row (not at the edge)\n", __PRETTY_FUNCTION__
));
5313 entry_next
= active_entry
;
5314 next_X
= entry_next
->ie_IconX
;
5315 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
5317 if (entry_next
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
5318 next_X
= next_X
- ((data
->icld_IconAreaLargestWidth
- entry_next
->ie_AreaWidth
)/2);
5322 #if defined(DEBUG_ILC_KEYEVENTS)
5323 D(bug("[IconList] %s: DOWN: using start_X %d, start_Y %d\n", __PRETTY_FUNCTION__
, start_X
, start_Y
));
5327 if (!(message
->imsg
->Qualifier
& IEQUALIFIER_LSHIFT
) && ((data
->icld_SelectionLastClicked
)&&(data
->icld_SelectionLastClicked
!= active_entry
)))
5329 #if defined(DEBUG_ILC_KEYEVENTS)
5330 D(bug("[IconList] %s: DOWN: Clearing selected icons ..\n", __PRETTY_FUNCTION__
));
5332 DoMethod(obj
, MUIM_IconList_UnselectAll
);
5335 #if defined(DEBUG_ILC_KEYEVENTS)
5336 D(bug("[IconList] %s: DOWN: active = 0x%p, next = 0x%p\n", __PRETTY_FUNCTION__
, active_entry
, entry_next
));
5338 if (!(active_entry
))
5340 // If nothing is selected we will use the First visible entry ..
5341 active_entry
= Node_FirstVisible(&data
->icld_IconList
);
5342 start_X
= active_entry
->ie_IconX
;
5343 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
5345 if (active_entry
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
5346 start_X
= start_X
- ((data
->icld_IconAreaLargestWidth
- active_entry
->ie_AreaWidth
)/2);
5348 start_Y
= active_entry
->ie_IconY
;
5351 while (active_entry
!= NULL
)
5353 #if defined(DEBUG_ILC_KEYEVENTS)
5354 D(bug("[IconList] %s: DOWN: Checking active @ 0x%p\n", __PRETTY_FUNCTION__
, active_entry
));
5356 if (data
->icld_DisplayFlags
& ICONLIST_DISP_VERTICAL
)
5358 if (active_entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
5363 active_X
= active_entry
->ie_IconX
;
5365 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
5367 if (active_entry
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
5368 x_diff
= ((data
->icld_IconAreaLargestWidth
- active_entry
->ie_AreaWidth
)/2);
5370 active_Y
= active_entry
->ie_IconY
;
5376 if ((active_entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
) &&
5377 (active_Y
> start_Y
) &&
5378 (((active_X
- x_diff
) >= start_X
) &&
5379 ((active_X
- x_diff
) <= (start_X
+ start_entry
->ie_AreaWidth
+ (x_diff
*2)))))
5381 #if defined(DEBUG_ILC_KEYEVENTS)
5382 D(bug("[IconList] %s: DOWN: (A) entry 0x%p matches\n", __PRETTY_FUNCTION__
, active_entry
));
5386 else if (active_entry
== (struct IconEntry
*)GetTail(&data
->icld_IconList
))
5388 #if defined(DEBUG_ILC_KEYEVENTS)
5389 D(bug("[IconList] %s: DOWN: (A) reached list end .. starting at the beginng ..\n", __PRETTY_FUNCTION__
));
5391 start_X
= entry_next
->ie_IconX
;
5392 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
5394 if (entry_next
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
5395 start_X
= start_X
- ((data
->icld_IconAreaLargestWidth
- entry_next
->ie_AreaWidth
)/2);
5398 if ((entry_next
= (struct IconEntry
*)Node_NextVisible(entry_next
)))
5400 if (entry_next
->ie_IconX
< start_X
)
5404 next_X
= entry_next
->ie_IconX
;
5405 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
5407 if (entry_next
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
5408 next_X
= next_X
+ ((data
->icld_IconAreaLargestWidth
- entry_next
->ie_AreaWidth
)/2);
5413 #if defined(DEBUG_ILC_KEYEVENTS)
5414 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
));
5416 active_entry
= Node_FirstVisible(&data
->icld_IconList
);
5421 if ((active_entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
) &&
5422 (active_Y
> start_Y
) &&
5423 (active_X
> start_X
- 1))
5425 #if defined(DEBUG_ILC_KEYEVENTS)
5426 D(bug("[IconList] %s: DOWN: (B) entry 0x%p matches\n", __PRETTY_FUNCTION__
, active_entry
));
5434 if (active_entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
5436 #if defined(DEBUG_ILC_KEYEVENTS)
5437 D(bug("[IconList] %s: DOWN: (C) entry 0x%p matches\n", __PRETTY_FUNCTION__
, active_entry
));
5443 active_entry
= (struct IconEntry
*)GetSucc(&active_entry
->ie_IconNode
);
5446 if (!(active_entry
))
5448 #if defined(DEBUG_ILC_KEYEVENTS)
5449 D(bug("[IconList] %s: DOWN: No Next DOWN Node - Getting first visable entry ..\n", __PRETTY_FUNCTION__
));
5451 /* We didnt find a "next DOWN" entry so just use the first visible */
5452 active_entry
= Node_FirstVisible(&data
->icld_IconList
);
5457 if (!(active_entry
->ie_Flags
& ICONENTRY_FLAG_FOCUS
))
5459 active_entry
->ie_Flags
|= ICONENTRY_FLAG_FOCUS
;
5460 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
5461 data
->update_entry
= active_entry
;
5462 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
5465 data
->icld_FocusIcon
= active_entry
;
5469 rawkey_handled
= TRUE
;
5471 #if defined(DEBUG_ILC_KEYEVENTS)
5472 D(bug("[IconList] %s: RAWKEY_LEFT\n", __PRETTY_FUNCTION__
));
5474 if (data
->icld_FocusIcon
)
5476 start_entry
= data
->icld_FocusIcon
;
5477 #if defined(DEBUG_ILC_KEYEVENTS)
5478 D(bug("[IconList] %s: LEFT: Clearing existing focused entry @ 0x%p\n", __PRETTY_FUNCTION__
, start_entry
));
5481 start_entry
->ie_Flags
&= ~ICONENTRY_FLAG_FOCUS
;
5482 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
5483 data
->update_entry
= start_entry
;
5484 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
5486 start_X
= start_entry
->ie_IconX
;
5487 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
5489 if (start_entry
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
5490 start_X
= start_X
- ((data
->icld_IconAreaLargestWidth
- start_entry
->ie_AreaWidth
)/2);
5492 start_Y
= start_entry
->ie_IconY
;
5494 #if defined(DEBUG_ILC_KEYEVENTS)
5495 D(bug("[IconList] %s: LEFT: start_X %d, start_Y %d\n", __PRETTY_FUNCTION__
, start_X
, start_Y
));
5498 if (!(active_entry
= Node_NextVisible(start_entry
)) && (!(data
->icld_DisplayFlags
& ICONLIST_DISP_VERTICAL
)))
5500 active_entry
= (struct IconEntry
*)GetHead(&data
->icld_IconList
);
5501 #if defined(DEBUG_ILC_KEYEVENTS)
5502 D(bug("[IconList] %s: LEFT: Start at the beginning (Active @ 0x%p) using entry X + Width\n", __PRETTY_FUNCTION__
, active_entry
));
5504 start_X
= start_X
+ start_entry
->ie_AreaWidth
;
5505 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
5507 if (start_entry
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
5508 start_X
= start_X
+ ((data
->icld_IconAreaLargestWidth
- start_entry
->ie_AreaWidth
)/2);
5514 else if (active_entry
&& (!(data
->icld_DisplayFlags
& ICONLIST_DISP_VERTICAL
)))
5516 #if defined(DEBUG_ILC_KEYEVENTS)
5517 D(bug("[IconList] %s: LEFT: Active @ 0x%p, X %d\n", __PRETTY_FUNCTION__
, active_entry
, active_entry
->ie_IconX
));
5519 if ((entry_next
= Node_NextVisible(start_entry
)))
5521 #if defined(DEBUG_ILC_KEYEVENTS)
5522 D(bug("[IconList] %s: LEFT: Next @ 0x%p, X %d\n", __PRETTY_FUNCTION__
, entry_next
, entry_next
->ie_IconX
));
5525 if (entry_next
->ie_IconX
< start_X
)
5529 next_X
= entry_next
->ie_IconX
;
5530 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
5532 if (entry_next
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
5533 next_X
= next_X
- ((data
->icld_IconAreaLargestWidth
- entry_next
->ie_AreaWidth
)/2);
5538 #if defined(DEBUG_ILC_KEYEVENTS)
5539 D(bug("[IconList] %s: LEFT: using start_X %d, start_Y %d\n", __PRETTY_FUNCTION__
, start_X
, start_Y
));
5543 if (!(message
->imsg
->Qualifier
& IEQUALIFIER_LSHIFT
) && ((data
->icld_SelectionLastClicked
)&&(data
->icld_SelectionLastClicked
!= active_entry
)))
5545 #if defined(DEBUG_ILC_KEYEVENTS)
5546 D(bug("[IconList] %s: LEFT: Clearing selected icons ..\n", __PRETTY_FUNCTION__
));
5548 DoMethod(obj
, MUIM_IconList_UnselectAll
);
5551 #if defined(DEBUG_ILC_KEYEVENTS)
5552 D(bug("[IconList] %s: LEFT: active = 0x%p, next = 0x%p\n", __PRETTY_FUNCTION__
, active_entry
, entry_next
));
5555 if (!(active_entry
))
5557 active_entry
= (struct IconEntry
*)GetHead(&data
->icld_IconList
);
5560 while (active_entry
!= NULL
)
5562 #if defined(DEBUG_ILC_KEYEVENTS)
5563 D(bug("[IconList] %s: LEFT: Checking active @ 0x%p\n", __PRETTY_FUNCTION__
, active_entry
));
5565 if (data
->icld_DisplayFlags
& ICONLIST_DISP_VERTICAL
)
5567 if (active_entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
5572 LONG active_entry_X
= active_entry
->ie_IconX
;
5573 LONG active_entry_Y
;
5574 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
5576 if (active_entry
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
5577 active_entry_X
= active_entry_X
- ((data
->icld_IconAreaLargestWidth
- active_entry
->ie_AreaWidth
)/2);
5579 active_entry_Y
= active_entry
->ie_IconY
;
5585 if ((active_entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
) &&
5586 (active_entry_Y
> start_Y
) &&
5587 ((active_entry_X
> start_X
- 1) &&
5588 (active_entry_X
< next_X
)))
5590 #if defined(DEBUG_ILC_KEYEVENTS)
5591 D(bug("[IconList] %s: LEFT: (A) entry 0x%p matches\n", __PRETTY_FUNCTION__
, active_entry
));
5595 else if (active_entry
== (struct IconEntry
*)GetTail(&data
->icld_IconList
))
5597 #if defined(DEBUG_ILC_KEYEVENTS)
5598 D(bug("[IconList] %s: LEFT: (A) reached list end .. starting at the beginng ..\n", __PRETTY_FUNCTION__
));
5600 start_X
= entry_next
->ie_IconX
;
5601 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
5603 if (entry_next
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
5604 start_X
= start_X
- ((data
->icld_IconAreaLargestWidth
- entry_next
->ie_AreaWidth
)/2);
5607 if ((entry_next
= Node_NextVisible(entry_next
)))
5609 if (entry_next
->ie_IconX
< start_X
)
5613 next_X
= entry_next
->ie_IconX
;
5614 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
5616 if (entry_next
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
5617 next_X
= next_X
+ ((data
->icld_IconAreaLargestWidth
- entry_next
->ie_AreaWidth
)/2);
5622 #if defined(DEBUG_ILC_KEYEVENTS)
5623 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
));
5625 active_entry
= (struct IconEntry
*)GetHead(&data
->icld_IconList
);
5630 if ((active_entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
) &&
5631 (active_entry_Y
> start_Y
) &&
5632 (active_entry_X
> start_X
- 1))
5634 #if defined(DEBUG_ILC_KEYEVENTS)
5635 D(bug("[IconList] %s: LEFT: (B) entry 0x%p matches\n", __PRETTY_FUNCTION__
, active_entry
));
5643 if (active_entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
5645 #if defined(DEBUG_ILC_KEYEVENTS)
5646 D(bug("[IconList] %s: LEFT: (C) entry 0x%p matches\n", __PRETTY_FUNCTION__
, active_entry
));
5652 active_entry
= (struct IconEntry
*)GetSucc(&active_entry
->ie_IconNode
);
5655 if (!(active_entry
))
5657 #if defined(DEBUG_ILC_KEYEVENTS)
5658 D(bug("[IconList] %s: LEFT: No Next LEFT Node - Getting first visable entry ..\n", __PRETTY_FUNCTION__
));
5660 /* We didnt find a "next LEFT" entry so just use the last visible */
5661 active_entry
= (struct IconEntry
*)GetHead(&data
->icld_IconList
);
5662 while ((active_entry
!= NULL
) &&(!(active_entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)))
5664 active_entry
= (struct IconEntry
*)GetSucc(&active_entry
->ie_IconNode
);
5670 if (!(active_entry
->ie_Flags
& ICONENTRY_FLAG_FOCUS
))
5672 active_entry
->ie_Flags
|= ICONENTRY_FLAG_FOCUS
;
5673 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
5674 data
->update_entry
= active_entry
;
5675 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
5678 data
->icld_FocusIcon
= active_entry
;
5682 rawkey_handled
= TRUE
;
5684 #if defined(DEBUG_ILC_KEYEVENTS)
5685 D(bug("[IconList] %s: RAWKEY_RIGHT\n", __PRETTY_FUNCTION__
));
5688 if (data
->icld_FocusIcon
)
5690 start_entry
= data
->icld_FocusIcon
;
5691 #if defined(DEBUG_ILC_KEYEVENTS)
5692 D(bug("[IconList] %s: RIGHT: Clearing existing focused entry @ 0x%p\n", __PRETTY_FUNCTION__
, start_entry
));
5694 start_entry
->ie_Flags
&= ~ICONENTRY_FLAG_FOCUS
;
5695 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
5696 data
->update_entry
= start_entry
;
5697 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
5699 start_X
= start_entry
->ie_IconX
;
5700 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
5702 if (start_entry
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
5703 start_X
= start_X
- ((data
->icld_IconAreaLargestWidth
- start_entry
->ie_AreaWidth
)/2);
5705 start_Y
= start_entry
->ie_IconY
;
5707 #if defined(DEBUG_ILC_KEYEVENTS)
5708 D(bug("[IconList] %s: RIGHT: start_X %d, start_Y %d\n", __PRETTY_FUNCTION__
, start_X
, start_Y
));
5710 if (!(active_entry
= Node_NextVisible(start_entry
)) && (!(data
->icld_DisplayFlags
& ICONLIST_DISP_VERTICAL
)))
5712 active_entry
= (struct IconEntry
*)GetHead(&data
->icld_IconList
);
5713 #if defined(DEBUG_ILC_KEYEVENTS)
5714 D(bug("[IconList] %s: RIGHT: Start at the beginning (Active @ 0x%p) using entry X + Width\n", __PRETTY_FUNCTION__
, active_entry
));
5717 start_Y
= start_Y
+ start_entry
->ie_AreaHeight
;
5720 else if (active_entry
&& (data
->icld_DisplayFlags
& ICONLIST_DISP_VERTICAL
))
5722 #if defined(DEBUG_ILC_KEYEVENTS)
5723 D(bug("[IconList] %s: RIGHT: Active @ 0x%p, X %d\n", __PRETTY_FUNCTION__
, active_entry
, active_entry
->ie_IconX
));
5725 if ((entry_next
= Node_NextVisible(start_entry
)))
5727 #if defined(DEBUG_ILC_KEYEVENTS)
5728 D(bug("[IconList] %s: RIGHT: Next @ 0x%p, X %d\n", __PRETTY_FUNCTION__
, entry_next
, entry_next
->ie_IconX
));
5731 if (entry_next
->ie_IconY
< start_Y
)
5734 next_Y
= entry_next
->ie_IconY
;
5737 #if defined(DEBUG_ILC_KEYEVENTS)
5738 D(bug("[IconList] %s: RIGHT: using start_X %d, start_Y %d\n", __PRETTY_FUNCTION__
, start_X
, start_Y
));
5742 if (!(message
->imsg
->Qualifier
& IEQUALIFIER_LSHIFT
) && ((data
->icld_SelectionLastClicked
)&&(data
->icld_SelectionLastClicked
!= active_entry
)))
5744 #if defined(DEBUG_ILC_KEYEVENTS)
5745 D(bug("[IconList] %s: RIGHT: Clearing selected icons ..\n", __PRETTY_FUNCTION__
));
5747 DoMethod(obj
, MUIM_IconList_UnselectAll
);
5750 #if defined(DEBUG_ILC_KEYEVENTS)
5751 D(bug("[IconList] %s: RIGHT: active = 0x%p, next = 0x%p\n", __PRETTY_FUNCTION__
, active_entry
, entry_next
));
5754 if (!(active_entry
))
5756 active_entry
= (struct IconEntry
*)GetHead(&data
->icld_IconList
);
5759 while (active_entry
!= NULL
)
5761 #if defined(DEBUG_ILC_KEYEVENTS)
5762 D(bug("[IconList] %s: RIGHT: Checking active @ 0x%p\n", __PRETTY_FUNCTION__
, active_entry
));
5764 if (!(data
->icld_DisplayFlags
& ICONLIST_DISP_VERTICAL
))
5766 if (active_entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
5771 LONG active_entry_X
= active_entry
->ie_IconX
;
5772 LONG active_entry_Y
;
5773 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
5775 if (active_entry
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
5776 active_entry_X
= active_entry_X
- ((data
->icld_IconAreaLargestWidth
- active_entry
->ie_AreaWidth
)/2);
5778 active_entry_Y
= active_entry
->ie_IconY
;
5784 if ((active_entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
) &&
5785 (active_entry_X
> start_X
) &&
5786 ((active_entry_Y
> start_Y
- 1) &&
5787 (active_entry_Y
< next_Y
)))
5789 #if defined(DEBUG_ILC_KEYEVENTS)
5790 D(bug("[IconList] %s: RIGHT: (A) entry 0x%p matches\n", __PRETTY_FUNCTION__
, active_entry
));
5794 else if (active_entry
== (struct IconEntry
*)GetTail(&data
->icld_IconList
))
5796 #if defined(DEBUG_ILC_KEYEVENTS)
5797 D(bug("[IconList] %s: RIGHT: (A) reached list end .. starting at the beginng ..\n", __PRETTY_FUNCTION__
));
5799 start_Y
= entry_next
->ie_IconY
;
5801 if ((entry_next
= Node_NextVisible(entry_next
)))
5803 if (entry_next
->ie_IconY
< start_Y
)
5807 next_Y
= entry_next
->ie_IconY
;
5811 #if defined(DEBUG_ILC_KEYEVENTS)
5812 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
));
5814 active_entry
= (struct IconEntry
*)GetHead(&data
->icld_IconList
);
5819 if ((active_entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
) &&
5820 (active_entry_X
> start_X
) &&
5821 (active_entry_Y
> start_Y
- 1))
5823 #if defined(DEBUG_ILC_KEYEVENTS)
5824 D(bug("[IconList] %s: RIGHT: (B) entry 0x%p matches\n", __PRETTY_FUNCTION__
, active_entry
));
5832 if (active_entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
5834 #if defined(DEBUG_ILC_KEYEVENTS)
5835 D(bug("[IconList] %s: RIGHT: (C) entry 0x%p matches\n", __PRETTY_FUNCTION__
, active_entry
));
5841 active_entry
= (struct IconEntry
*)GetSucc(&active_entry
->ie_IconNode
);
5844 if (!(active_entry
))
5846 #if defined(DEBUG_ILC_KEYEVENTS)
5847 D(bug("[IconList] %s: RIGHT: No Next RIGHT Node - Getting first visable entry ..\n", __PRETTY_FUNCTION__
));
5849 /* We didnt find a "next RIGHT" entry so just use the first visible */
5850 active_entry
= (struct IconEntry
*)GetHead(&data
->icld_IconList
);
5851 while ((active_entry
!= NULL
) &&(!(active_entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)))
5853 active_entry
= (struct IconEntry
*)GetSucc(&active_entry
->ie_IconNode
);
5859 if (!(active_entry
->ie_Flags
& ICONENTRY_FLAG_FOCUS
))
5861 active_entry
->ie_Flags
|= ICONENTRY_FLAG_FOCUS
;
5862 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
5863 data
->update_entry
= active_entry
;
5864 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
5867 data
->icld_FocusIcon
= active_entry
;
5871 rawkey_handled
= TRUE
;
5873 #if defined(DEBUG_ILC_KEYEVENTS)
5874 D(bug("[IconList] %s: RAWKEY_HOME\n", __PRETTY_FUNCTION__
));
5877 if (data
->icld_FocusIcon
)
5879 data
->icld_FocusIcon
->ie_Flags
&= ~ICONENTRY_FLAG_FOCUS
;
5880 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
5881 data
->update_entry
= data
->icld_FocusIcon
;
5882 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
5885 active_entry
= Node_FirstVisible(&data
->icld_IconList
);
5887 if ((active_entry
) && (!(active_entry
->ie_Flags
& ICONENTRY_FLAG_FOCUS
)))
5889 active_entry
->ie_Flags
|= ICONENTRY_FLAG_FOCUS
;
5890 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
5891 data
->update_entry
= active_entry
;
5892 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
5894 data
->icld_FocusIcon
= active_entry
;
5898 rawkey_handled
= TRUE
;
5900 #if defined(DEBUG_ILC_KEYEVENTS)
5901 D(bug("[IconList] %s: RAWKEY_END\n", __PRETTY_FUNCTION__
));
5904 if (data
->icld_FocusIcon
)
5906 data
->icld_FocusIcon
->ie_Flags
&= ~ICONENTRY_FLAG_FOCUS
;
5907 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
5908 data
->update_entry
= data
->icld_FocusIcon
;
5909 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
5912 active_entry
= Node_LastVisible(&data
->icld_IconList
);
5914 if ((active_entry
) && (!(active_entry
->ie_Flags
& ICONENTRY_FLAG_FOCUS
)))
5916 active_entry
->ie_Flags
|= ICONENTRY_FLAG_FOCUS
;
5917 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
5918 data
->update_entry
= active_entry
;
5919 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
5921 data
->icld_FocusIcon
= active_entry
;
5925 if (rawkey_handled
) return MUI_EventHandlerRC_Eat
;
5929 case IDCMP_MOUSEBUTTONS
:
5930 #if defined(DEBUG_ILC_EVENTS)
5931 D(bug("[IconList] %s: IDCMP_MOUSEBUTTONS\n", __PRETTY_FUNCTION__
));
5933 if (message
->imsg
->Code
== SELECTDOWN
)
5935 /* Check if mouse pressed on iconlist area */
5936 if (mx
>= 0 && mx
< _width(obj
) && my
>= 0 && my
< _height(obj
))
5938 BOOL doubleclicked
= FALSE
; /* both icon and empty space */
5939 struct IconEntry
*node
= NULL
;
5940 struct IconEntry
*new_selected
= NULL
;
5942 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
5944 /* LIST-VIEW HANDLING */
5946 LONG clickColumn
= -1;
5948 LONG x
= _mleft(obj
) - data
->icld_ViewX
+ LINE_SPACING_LEFT
;
5951 /* Find column in which click happened */
5952 for(i
= 0; i
< NUM_COLUMNS
; i
++)
5954 index
= data
->icld_LVMAttribs
->lmva_ColumnPos
[i
];
5956 if (!(data
->icld_LVMAttribs
->lmva_ColumnFlags
[index
] & LVMCF_COLVISIBLE
)) continue;
5958 w
= data
->icld_LVMAttribs
->lmva_ColumnWidth
[index
];
5960 if ((mx
>= x
) && (mx
< x
+ w
))
5962 clickColumn
= index
;
5968 if (((data
->icld_LVMAttribs
->lvma_Flags
& LVMAF_NOHEADER
) == 0) && (my
<= data
->icld_LVMAttribs
->lmva_HeaderHeight
))
5970 /* Click on header, update list */
5971 data
->icld_LVMAttribs
->lmva_LastSelectedColumn
= clickColumn
;
5973 data
->icld_UpdateMode
= UPDATE_HEADERENTRY
;
5974 data
->update_entry
= (APTR
)(IPTR
)clickColumn
;
5976 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
5981 LONG current
= 0, index
= (my
- data
->icld_LVMAttribs
->lmva_HeaderHeight
+ data
->icld_ViewY
) / data
->icld_LVMAttribs
->lmva_RowHeight
;
5983 /* Check if clicked on entry */
5984 ForeachNode(&data
->icld_IconList
, node
)
5986 if (node
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
5988 /* Is this node clicked? */
5989 if (current
== index
)
5991 new_selected
= node
;
5999 /* Handle actions */
6000 IconList_HandleNewIconSelection(CLASS
, obj
, message
, new_selected
, &doubleclicked
);
6005 /* ICON-VIEW HANDLING */
6007 struct Rectangle rect
;
6009 /* Check if clicked on entry */
6010 #if defined(__AROS__)
6011 ForeachNode(&data
->icld_IconList
, node
)
6013 Foreach_Node(&data
->icld_IconList
, node
);
6016 if (node
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
6018 /* Is this node clicked? */
6019 rect
.MinX
= node
->ie_IconX
;
6020 rect
.MaxX
= node
->ie_IconX
+ node
->ie_AreaWidth
- 1;
6021 rect
.MinY
= node
->ie_IconY
;
6022 rect
.MaxY
= node
->ie_IconY
+ node
->ie_AreaHeight
- 1;
6024 if ((data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
) &&
6025 (node
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
))
6027 rect
.MinX
+= ((data
->icld_IconAreaLargestWidth
- node
->ie_AreaWidth
)/2);
6028 rect
.MaxX
+= ((data
->icld_IconAreaLargestWidth
- node
->ie_AreaWidth
)/2);
6031 if ((((mx
+ data
->icld_ViewX
) >= rect
.MinX
) && ((mx
+ data
->icld_ViewX
) <= rect
.MaxX
)) &&
6032 (((my
+ data
->icld_ViewY
) >= rect
.MinY
) && ((my
+ data
->icld_ViewY
) <= rect
.MaxY
)))
6034 new_selected
= node
;
6035 #if defined(DEBUG_ILC_EVENTS)
6036 D(bug("[IconList] %s: Entry '%s' clicked on ..\n", __PRETTY_FUNCTION__
, node
->ie_IconListEntry
.label
));
6043 /* Handle actions */
6044 IconList_HandleNewIconSelection(CLASS
, obj
, message
, new_selected
, &doubleclicked
);
6047 if (new_selected
&& (new_selected
->ie_Flags
& ICONENTRY_FLAG_SELECTED
))
6048 data
->icld_SelectionLastClicked
= new_selected
;
6050 data
->icld_SelectionLastClicked
= NULL
;
6055 SET(obj
, MUIA_IconList_SelectionChanged
, TRUE
);
6057 data
->icld_ClickEvent
.shift
= !!(message
->imsg
->Qualifier
& (IEQUALIFIER_LSHIFT
| IEQUALIFIER_RSHIFT
));
6058 data
->icld_ClickEvent
.entry
= data
->icld_SelectionLastClicked
? &data
->icld_SelectionLastClicked
->ie_IconListEntry
: NULL
;
6059 SET(obj
, MUIA_IconList_Clicked
, (IPTR
)&data
->icld_ClickEvent
);
6063 SET(obj
, MUIA_IconList_DoubleClick
, TRUE
);
6066 if ((!data
->mouse_pressed
) &&
6067 (!doubleclicked
|| (doubleclicked
&& (data
->icld_SelectionLastClicked
== NULL
))))
6069 data
->last_secs
= message
->imsg
->Seconds
;
6070 data
->last_mics
= message
->imsg
->Micros
;
6072 /* After a double click you often open a new window
6073 * and since Zune doesn't not support the faking
6074 * of SELECTUP events only change the Events
6075 * if not doubleclicked on an icon */
6077 data
->mouse_pressed
|= LEFT_BUTTON
;
6079 /* Start listening to mouse events */
6080 if (!(data
->ehn
.ehn_Events
& IDCMP_MOUSEMOVE
))
6082 DoMethod(_win(obj
), MUIM_Window_RemEventHandler
, (IPTR
)&data
->ehn
);
6083 data
->ehn
.ehn_Events
|= IDCMP_MOUSEMOVE
;
6084 DoMethod(_win(obj
), MUIM_Window_AddEventHandler
, (IPTR
)&data
->ehn
);
6088 return MUI_EventHandlerRC_Eat
;
6091 else if (message
->imsg
->Code
== MIDDLEDOWN
)
6093 if (!data
->mouse_pressed
)
6095 data
->mouse_pressed
|= MIDDLE_BUTTON
;
6097 data
->click_x
= data
->icld_ViewX
+ mx
;
6098 data
->click_y
= data
->icld_ViewY
+ my
;
6100 /* Start listening to mouse events */
6101 if (!(data
->ehn
.ehn_Events
& IDCMP_MOUSEMOVE
))
6103 DoMethod(_win(obj
), MUIM_Window_RemEventHandler
, (IPTR
)&data
->ehn
);
6104 data
->ehn
.ehn_Events
|= IDCMP_MOUSEMOVE
;
6105 DoMethod(_win(obj
), MUIM_Window_AddEventHandler
, (IPTR
)&data
->ehn
);
6111 if (message
->imsg
->Code
== SELECTUP
)
6113 if (data
->icld_LassoActive
== TRUE
)
6115 NullifyLasso(data
, obj
);
6117 else if (data
->icld_LVMAttribs
->lmva_LastSelectedColumn
!= -1)
6119 ULONG orig_sortflags
= data
->icld_SortFlags
;
6121 if (data
->icld_LVMAttribs
->lmva_SortColumn
== data
->icld_LVMAttribs
->lmva_LastSelectedColumn
)
6123 if (data
->icld_SortFlags
& MUIV_IconList_Sort_Reverse
)
6124 data
->icld_SortFlags
&= ~MUIV_IconList_Sort_Reverse
;
6126 data
->icld_SortFlags
|= MUIV_IconList_Sort_Reverse
;
6129 switch (data
->icld_LVMAttribs
->lmva_LastSelectedColumn
)
6132 data
->icld_SortFlags
&= ~MUIV_IconList_Sort_Orders
;
6133 data
->icld_SortFlags
|= MUIV_IconList_Sort_ByName
;
6137 data
->icld_SortFlags
&= ~MUIV_IconList_Sort_Orders
;
6138 data
->icld_SortFlags
|= MUIV_IconList_Sort_BySize
;
6141 case INDEX_LASTACCESS
:
6142 data
->icld_SortFlags
&= ~MUIV_IconList_Sort_Orders
;
6143 data
->icld_SortFlags
|= MUIV_IconList_Sort_ByDate
;
6147 if (orig_sortflags
!= data
->icld_SortFlags
)
6149 data
->icld_LVMAttribs
->lmva_SortColumn
= data
->icld_LVMAttribs
->lmva_LastSelectedColumn
;
6151 data
->icld_LVMAttribs
->lmva_LastSelectedColumn
= -1;
6153 DoMethod(obj
, MUIM_IconList_Sort
);
6157 data
->mouse_pressed
&= ~LEFT_BUTTON
;
6160 if (message
->imsg
->Code
== MIDDLEUP
)
6162 data
->mouse_pressed
&= ~MIDDLE_BUTTON
;
6165 /* Stop listening to mouse move events is no buttons pressed */
6166 if ((data
->ehn
.ehn_Events
& IDCMP_MOUSEMOVE
) && !data
->mouse_pressed
)
6168 DoMethod(_win(obj
),MUIM_Window_RemEventHandler
, (IPTR
)&data
->ehn
);
6169 data
->ehn
.ehn_Events
&= ~IDCMP_MOUSEMOVE
;
6170 DoMethod(_win(obj
),MUIM_Window_AddEventHandler
, (IPTR
)&data
->ehn
);
6175 case IDCMP_INTUITICKS
:
6177 #if defined(DEBUG_ILC_EVENTS)
6178 D(bug("[IconList] %s: IDCMP_INTUITICKS (%d, %d)\n", __PRETTY_FUNCTION__
, mx
, my
));
6180 if ((data
->icld_LassoActive
== FALSE
)||(!(data
->mouse_pressed
& LEFT_BUTTON
)))
6184 if (((mx
>= 0) && (mx
<= _mwidth(obj
))) &&
6185 ((my
>= 0) && (my
<= _mheight(obj
))))
6189 case IDCMP_MOUSEMOVE
:
6190 #if defined(DEBUG_ILC_EVENTS)
6191 D(bug("[IconList] %s: IDCMP_MOUSEMOVE\n", __PRETTY_FUNCTION__
));
6193 if (data
->mouse_pressed
& LEFT_BUTTON
)
6198 if (data
->icld_SelectionLastClicked
&& (data
->icld_LassoActive
== FALSE
) &&
6199 ((abs(move_x
- data
->click_x
) >= 2) || (abs(move_y
- data
->click_y
) >= 2)))
6201 LONG touch_x
, touch_y
;
6203 /* Entry(s) being dragged .... */
6204 DoMethod(_win(obj
),MUIM_Window_RemEventHandler
, (IPTR
)&data
->ehn
);
6205 data
->ehn
.ehn_Events
&= ~IDCMP_MOUSEMOVE
;
6206 DoMethod(_win(obj
),MUIM_Window_AddEventHandler
, (IPTR
)&data
->ehn
);
6208 data
->mouse_pressed
&= ~LEFT_BUTTON
;
6210 /* Pass view relative coords */
6211 touch_x
= move_x
+ data
->icld_ViewX
;
6212 touch_y
= move_y
+ data
->icld_ViewY
;
6213 DoMethod(obj
,MUIM_DoDrag
, touch_x
, touch_y
, 0);
6215 else if (data
->icld_LassoActive
== TRUE
)
6217 #if defined(DEBUG_ILC_EVENTS) || defined(DEBUG_ILC_LASSO)
6218 D(bug("[IconList] %s: Update Lasso\n", __PRETTY_FUNCTION__
));
6221 struct Rectangle new_lasso
,
6223 struct Rectangle iconrect
;
6225 struct IconEntry
*node
= NULL
;
6226 // struct IconEntry *new_selected = NULL;
6228 /* Remove previous Lasso frame */
6229 GetAbsoluteLassoRect(data
, &old_lasso
);
6230 IconList_InvertLassoOutlines(obj
, data
, &old_lasso
);
6232 /* if the mouse leaves our visible area scroll the view */
6233 if (mx
< 0 || mx
>= _mwidth(obj
) || my
< 0 || my
>= _mheight(obj
))
6235 LONG newleft
= data
->icld_ViewX
;
6236 LONG newtop
= data
->icld_ViewY
;
6238 if (mx
>= _mwidth(obj
)) newleft
+= (mx
- _mwidth(obj
));
6239 else if (mx
< 0) newleft
+= mx
;
6240 if (my
>= _mheight(obj
)) newtop
+= (my
- _mheight(obj
));
6241 else if (my
< 0) newtop
+= my
;
6243 if (newleft
+ _mwidth(obj
) > data
->icld_AreaWidth
) newleft
= data
->icld_AreaWidth
- _mwidth(obj
);
6244 if (newleft
< 0) newleft
= 0;
6246 if (newtop
+ _mheight(obj
) > data
->icld_AreaHeight
) newtop
= data
->icld_AreaHeight
- _mheight(obj
);
6247 if (newtop
< 0) newtop
= 0;
6249 if ((newleft
!= data
->icld_ViewX
) || (newtop
!= data
->icld_ViewY
))
6251 SetAttrs(obj
, MUIA_Virtgroup_Left
, newleft
, MUIA_Virtgroup_Top
, newtop
, TAG_DONE
);
6255 /* update Lasso coordinates */
6256 data
->icld_LassoRectangle
.MaxX
= mx
- data
->view_rect
.MinX
+ data
->icld_ViewX
;
6257 data
->icld_LassoRectangle
.MaxY
= my
- data
->view_rect
.MinY
+ data
->icld_ViewY
;
6259 /* get absolute Lasso coordinates */
6260 GetAbsoluteLassoRect(data
, &new_lasso
);
6262 LONG current
= 0, startIndex
= 0, endIndex
= 0;
6264 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
6266 LONG minY
= data
->icld_LassoRectangle
.MinY
,
6267 maxY
= data
->icld_LassoRectangle
.MaxY
;
6276 startIndex
= ((minY
+ 1) - data
->icld_LVMAttribs
->lmva_HeaderHeight
) / data
->icld_LVMAttribs
->lmva_RowHeight
;
6277 endIndex
= ((maxY
- 1) - data
->icld_LVMAttribs
->lmva_HeaderHeight
) / data
->icld_LVMAttribs
->lmva_RowHeight
;
6280 #if defined(__AROS__)
6281 ForeachNode(&data
->icld_IconList
, node
)
6283 Foreach_Node(&data
->icld_IconList
, node
);
6286 IPTR update_entry
= (IPTR
)NULL
;
6288 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
6290 if (node
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
6292 update_entry
= FALSE
;
6294 if ((current
>= startIndex
) && (current
<= endIndex
))
6296 //Entry is inside our lasso ..
6297 if (!(node
->ie_Flags
& ICONENTRY_FLAG_LASSO
))
6299 /* check if entry was already selected before */
6300 if (node
->ie_Flags
& ICONENTRY_FLAG_SELECTED
)
6302 Remove(&node
->ie_SelectionNode
);
6303 node
->ie_Flags
&= ~ICONENTRY_FLAG_SELECTED
;
6307 AddTail(&data
->icld_SelectionList
, &node
->ie_SelectionNode
);
6308 node
->ie_Flags
|= ICONENTRY_FLAG_SELECTED
;
6310 node
->ie_Flags
|= ICONENTRY_FLAG_LASSO
;
6311 update_entry
= (IPTR
)node
;
6314 else if (node
->ie_Flags
& ICONENTRY_FLAG_LASSO
)
6316 //Entry is no longer inside our lasso - revert its selected state
6317 if (node
->ie_Flags
& ICONENTRY_FLAG_SELECTED
)
6319 Remove(&node
->ie_SelectionNode
);
6320 node
->ie_Flags
&= ~ICONENTRY_FLAG_SELECTED
;
6324 AddTail(&data
->icld_SelectionList
, &node
->ie_SelectionNode
);
6325 node
->ie_Flags
|= ICONENTRY_FLAG_SELECTED
;
6327 node
->ie_Flags
&= ~ICONENTRY_FLAG_LASSO
;
6328 update_entry
= (IPTR
)node
;
6336 if (node
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
6338 iconrect
.MinX
= node
->ie_IconX
;
6339 iconrect
.MaxX
= node
->ie_IconX
+ node
->ie_AreaWidth
- 1;
6340 iconrect
.MinY
= node
->ie_IconY
;
6341 iconrect
.MaxY
= node
->ie_IconY
+ node
->ie_AreaHeight
- 1;
6342 if ((data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
) &&
6343 (node
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
))
6345 iconrect
.MinX
+= ((data
->icld_IconAreaLargestWidth
- node
->ie_AreaWidth
)/2);
6346 iconrect
.MaxX
+= ((data
->icld_IconAreaLargestWidth
- node
->ie_AreaWidth
)/2);
6349 if ((((new_lasso
.MaxX
+ data
->icld_ViewX
) >= iconrect
.MinX
) && ((new_lasso
.MinX
+ data
->icld_ViewX
) <= iconrect
.MaxX
)) &&
6350 (((new_lasso
.MaxY
+ data
->icld_ViewY
) >= iconrect
.MinY
) && ((new_lasso
.MinY
+ data
->icld_ViewY
) <= iconrect
.MaxY
)))
6352 //Entry is inside our lasso ..
6353 if (!(node
->ie_Flags
& ICONENTRY_FLAG_LASSO
))
6355 /* check if entry was already selected before */
6356 if (node
->ie_Flags
& ICONENTRY_FLAG_SELECTED
)
6358 Remove(&node
->ie_SelectionNode
);
6359 node
->ie_Flags
&= ~ICONENTRY_FLAG_SELECTED
;
6363 AddTail(&data
->icld_SelectionList
, &node
->ie_SelectionNode
);
6364 node
->ie_Flags
|= ICONENTRY_FLAG_SELECTED
;
6366 node
->ie_Flags
|= ICONENTRY_FLAG_LASSO
;
6367 update_entry
= (IPTR
)node
;
6370 else if (node
->ie_Flags
& ICONENTRY_FLAG_LASSO
)
6372 //Entry is no longer inside our lasso - revert its selected state
6373 if (node
->ie_Flags
& ICONENTRY_FLAG_SELECTED
)
6375 Remove(&node
->ie_SelectionNode
);
6376 node
->ie_Flags
&= ~ICONENTRY_FLAG_SELECTED
;
6380 AddTail(&data
->icld_SelectionList
, &node
->ie_SelectionNode
);
6381 node
->ie_Flags
|= ICONENTRY_FLAG_SELECTED
;
6383 node
->ie_Flags
&= ~ICONENTRY_FLAG_LASSO
;
6384 update_entry
= (IPTR
)node
;
6390 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
6391 data
->update_entry
= (struct IconEntry
*)update_entry
;
6392 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
6395 /* Draw Lasso frame */
6396 IconList_InvertLassoOutlines(obj
, data
, &new_lasso
);
6399 return MUI_EventHandlerRC_Eat
;
6401 else if (data
->mouse_pressed
& MIDDLE_BUTTON
)
6403 /* Content is being scrolled */
6404 LONG newleft
, newtop
;
6406 newleft
= data
->click_x
- mx
;
6407 newtop
= data
->click_y
- my
;
6409 if (newleft
+ _mwidth(obj
) > data
->icld_AreaWidth
) newleft
= data
->icld_AreaWidth
- _mwidth(obj
);
6410 if (newleft
< 0) newleft
= 0;
6412 if (newtop
+ _mheight(obj
) > data
->icld_AreaHeight
) newtop
= data
->icld_AreaHeight
- _mheight(obj
);
6413 if (newtop
< 0) newtop
= 0;
6415 if ((newleft
!= data
->icld_ViewX
) || (newtop
!= data
->icld_ViewY
))
6417 SetAttrs(obj
, MUIA_Virtgroup_Left
, newleft
,
6418 MUIA_Virtgroup_Top
, newtop
,
6422 return MUI_EventHandlerRC_Eat
;
6426 case IDCMP_MENUVERIFY
:
6428 #if defined(DEBUG_ILC_EVENTS)
6429 D(bug("[IconList] %s: IDCMP_MENUVERIFY\n", __PRETTY_FUNCTION__
));
6432 if (data
->icld_LassoActive
== TRUE
)
6434 /* Remove the lasso if the right mouse button is pressed */
6435 NullifyLasso(data
, obj
);
6445 ///MUIM_IconList_NextIcon()
6446 /**************************************************************************
6447 MUIM_IconList_NextIcon
6448 **************************************************************************/
6449 IPTR
IconList__MUIM_IconList_NextIcon(struct IClass
*CLASS
, Object
*obj
, struct MUIP_IconList_NextIcon
*message
)
6451 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
6452 struct IconEntry
*node
= NULL
;
6453 struct IconList_Entry
*ent
= NULL
;
6454 IPTR node_successor
= (IPTR
)NULL
;
6456 if (message
->entry
== NULL
) return (IPTR
)NULL
;
6457 ent
= *message
->entry
;
6459 #if defined(DEBUG_ILC_FUNCS)
6460 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
6463 if ((IPTR
)ent
== (IPTR
)MUIV_IconList_NextIcon_Start
)
6465 D(bug("[IconList] %s: Finding First Entry ..\n", __PRETTY_FUNCTION__
));
6466 if (message
->nextflag
== MUIV_IconList_NextIcon_Selected
)
6468 node
= (struct IconEntry
*)GetHead(&data
->icld_SelectionList
);
6471 node
= (struct IconEntry
*)((IPTR
)node
- ((IPTR
)&node
->ie_SelectionNode
- (IPTR
)node
));
6474 else if (message
->nextflag
== MUIV_IconList_NextIcon_Visible
)
6476 node
= (struct IconEntry
*)GetHead(&data
->icld_IconList
);
6477 while (node
!= NULL
)
6479 if (node
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
6482 node
= (struct IconEntry
*)GetSucc(&node
->ie_IconNode
);
6486 else if ((IPTR
)ent
!= (IPTR
)MUIV_IconList_NextIcon_End
)
6488 node
= (struct IconEntry
*)((IPTR
)ent
- ((IPTR
)&node
->ie_IconListEntry
- (IPTR
)node
));
6489 if (message
->nextflag
== MUIV_IconList_NextIcon_Selected
)
6491 node_successor
= (IPTR
)GetSucc(&node
->ie_SelectionNode
);
6492 if (node_successor
!= (IPTR
)NULL
)
6493 node
= (struct IconEntry
*)((IPTR
)node_successor
- ((IPTR
)&node
->ie_SelectionNode
- (IPTR
)node
));
6496 D(bug("[IconList] %s: GetSucc() == NULL\n", __PRETTY_FUNCTION__
));
6500 else if (message
->nextflag
== MUIV_IconList_NextIcon_Visible
)
6502 node
= (struct IconEntry
*)GetSucc(&node
->ie_IconNode
);
6503 while (node
!= NULL
)
6505 if (node
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
6508 node
= (struct IconEntry
*)GetSucc(&node
->ie_IconNode
);
6515 D(bug("[IconList] %s: Returning MUIV_IconList_NextIcon_End\n", __PRETTY_FUNCTION__
));
6517 *message
->entry
= (struct IconList_Entry
*)MUIV_IconList_NextIcon_End
;
6521 D(bug("[IconList] %s: Returning entry for '%s'\n", __PRETTY_FUNCTION__
, node
->ie_IconListEntry
.label
));
6523 *message
->entry
= &node
->ie_IconListEntry
;
6530 ///MUIM_IconList_GetIconPrivate()
6531 /**************************************************************************
6532 MUIM_IconList_GetIconPrivate
6533 **************************************************************************/
6534 IPTR
IconList__MUIM_IconList_GetIconPrivate(struct IClass
*CLASS
, Object
*obj
, struct MUIP_IconList_GetIconPrivate
*message
)
6536 // struct IconList_DATA *data = INST_DATA(CLASS, obj);
6537 struct IconEntry
*node
= NULL
;
6539 if (message
->entry
== NULL
) return (IPTR
)NULL
;
6541 node
= (struct IconEntry
*)((IPTR
)message
->entry
- ((IPTR
)&node
->ie_IconListEntry
- (IPTR
)node
));
6546 ///MUIM_CreateDragImage()
6547 /**************************************************************************
6548 MUIM_CreateDragImage
6549 **************************************************************************/
6550 IPTR
IconList__MUIM_CreateDragImage(struct IClass
*CLASS
, Object
*obj
, struct MUIP_CreateDragImage
*message
)
6552 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
6553 struct MUI_DragImage
*img
= NULL
;
6556 BOOL transp
= XGET(obj
, MUIA_IconList_DragImageTransparent
);
6558 #if defined(DEBUG_ILC_FUNCS) || defined(DEBUG_ILC_ICONDRAGDROP)
6559 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
6562 if (!(data
->icld_SelectionLastClicked
))
6563 DoSuperMethodA(CLASS
, obj
, (Msg
)message
);
6565 if ((img
= (struct MUI_DragImage
*)AllocVec(sizeof(struct MUIP_CreateDragImage
), MEMF_CLEAR
)))
6567 struct Node
*node
= NULL
;
6568 struct IconEntry
*entry
= NULL
;
6570 #if defined(CREATE_FULL_DRAGIMAGE)
6571 #if defined(__AROS__)
6572 ForeachNode(&data
->icld_SelectionList
, node
)
6574 Foreach_Node(&data
->icld_SelectionList
, node
);
6577 entry
= (struct IconEntry
*)((IPTR
)node
- ((IPTR
)&entry
->ie_SelectionNode
- (IPTR
)entry
));
6578 if ((entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
) && (entry
->ie_Flags
& ICONENTRY_FLAG_SELECTED
))
6580 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) != ICONLIST_DISP_MODELIST
)
6582 if ((first_x
== -1) || ((first_x
!= -1) && (entry
->ie_IconX
< first_x
))) first_x
= entry
->ie_IconX
;
6583 if ((first_y
== -1) || ((first_y
!= -1) && (entry
->ie_IconY
< first_y
))) first_y
= entry
->ie_IconY
;
6585 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_ROUGH
)
6587 if ((entry
->ie_IconX
+ entry
->ie_AreaWidth
) > img
->width
) img
->width
= entry
->ie_IconX
+ entry
->ie_AreaWidth
;
6588 if ((entry
->ie_IconY
+ entry
->ie_AreaHeight
) > img
->height
) img
->height
= entry
->ie_IconY
+ entry
->ie_AreaHeight
;
6591 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
6593 if ((entry
->ie_IconX
+ data
->icld_IconAreaLargestWidth
) > img
->width
) img
->width
= entry
->ie_IconX
+ data
->icld_IconAreaLargestWidth
;
6594 if ((entry
->ie_IconY
+ data
->icld_IconAreaLargestHeight
) > img
->height
) img
->height
= entry
->ie_IconY
+ data
->icld_IconAreaLargestHeight
;
6599 img
->height
+= data
->icld_LVMAttribs
->lmva_RowHeight
;
6603 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
6606 first_y
= -message
->touchy
;
6607 img
->width
= data
->icld_LVMAttribs
->lmva_ColumnWidth
[data
->icld_LVMAttribs
->lmva_ColumnPos
[INDEX_TYPE
]] +
6608 data
->icld_LVMAttribs
->lmva_ColumnWidth
[data
->icld_LVMAttribs
->lmva_ColumnPos
[INDEX_NAME
]];
6613 img
->width
= (img
->width
- first_x
) + 2;
6614 img
->height
= (img
->height
- first_y
) + 2;
6617 entry
= data
->icld_SelectionLastClicked
;
6618 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
6620 img
->width
= _mright(obj
) - _mleft(obj
);
6621 img
->height
= data
->icld_LVMAttribs
->lmva_RowHeight
;
6627 img
->width
= entry
->ie_IconWidth
;
6628 img
->height
= entry
->ie_IconHeight
;
6629 first_x
= entry
->ie_IconX
;
6630 first_y
= entry
->ie_IconY
;
6636 /* Request 32-bit, because the image will have alpha channel */
6637 img
->bm
= AllocBitMap(img
->width
, img
->height
, 32, BMF_CLEAR
, NULL
);
6641 LONG depth
= GetBitMapAttr(_screen(obj
)->RastPort
.BitMap
, BMA_DEPTH
);
6642 img
->bm
= AllocBitMap(img
->width
, img
->height
, depth
, BMF_CLEAR
, _screen(obj
)->RastPort
.BitMap
);
6647 struct RastPort temprp
;
6648 InitRastPort(&temprp
);
6649 temprp
.BitMap
= img
->bm
;
6652 #if defined(CREATE_FULL_DRAGIMAGE)
6653 ForeachNode(&data
->icld_SelectionList
, node
)
6655 entry
= (struct IconEntry
*)((IPTR
)node
- ((IPTR
)&entry
->ie_SelectionNode
- (IPTR
)entry
));
6656 if ((entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
) && (entry
->ie_Flags
& ICONENTRY_FLAG_SELECTED
))
6658 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
6660 struct Rectangle field_rect
;
6661 ULONG selected
= entry
->ie_Flags
& ICONENTRY_FLAG_SELECTED
;
6662 entry
->ie_Flags
&= ~ICONENTRY_FLAG_SELECTED
; /* Drawing as not selected actually looks better */
6664 field_rect
.MinX
= 0; field_rect
.MaxX
= img
->width
- 1;
6665 field_rect
.MinY
= minY
; field_rect
.MaxY
= field_rect
.MinY
+ data
->icld_LVMAttribs
->lmva_RowHeight
- 1;
6666 RenderEntryField(obj
, data
, entry
, &field_rect
, INDEX_TYPE
, TRUE
, FALSE
, &temprp
);
6668 field_rect
.MinX
= data
->icld_LVMAttribs
->lmva_ColumnWidth
[data
->icld_LVMAttribs
->lmva_ColumnPos
[INDEX_TYPE
]] - 1;
6669 field_rect
.MaxX
= img
->width
- 1;
6670 field_rect
.MinY
= minY
; field_rect
.MaxY
= field_rect
.MinY
+ data
->icld_LVMAttribs
->lmva_RowHeight
- 1;
6671 RenderEntryField(obj
, data
, entry
, &field_rect
, INDEX_NAME
, FALSE
, FALSE
, &temprp
);
6673 minY
+= data
->icld_LVMAttribs
->lmva_RowHeight
;
6675 entry
->ie_Flags
|= selected
;
6679 LONG offsetx
, offsety
;
6681 IconList_GetIconImageOffsets(data
, entry
, &offsetx
, &offsety
);
6685 &temprp
, entry
->ie_DiskObj
, NULL
,
6686 (entry
->ie_IconX
+ 1) - first_x
+ offsetx
, (entry
->ie_IconY
+ 1) - first_y
+ offsety
,
6688 __iconList_DrawIconStateTags
6694 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
6696 SetABPenDrMd(&temprp
, _pens(obj
)[MPEN_SHINE
], 0, JAM1
);
6697 RectFill(&temprp
, 0, 0, img
->width
, img
->height
);
6703 &temprp
, entry
->ie_DiskObj
, NULL
,
6706 __iconList_DrawIconStateTags
6711 RastPortSetAlpha(&temprp
, data
->click_x
, data
->click_y
, img
->width
, img
->height
, 0xC0, RPALPHAFLAT
);
6712 DeinitRastPort(&temprp
);
6715 /* Convert view relative coords to drag image relative. This is done because the "object" that is being
6716 * dragged is virtual (its a collection of icons) and the coords passed to DoDrag are not relative to this
6719 img
->touchx
= first_x
+ message
->touchx
;
6720 img
->touchy
= first_y
+ message
->touchy
;
6723 img
->flags
= MUIF_DRAGIMAGE_SOURCEALPHA
;
6731 ///MUIM_DeleteDragImage()
6732 /**************************************************************************
6733 MUIM_DeleteDragImage
6734 **************************************************************************/
6735 IPTR
IconList__MUIM_DeleteDragImage(struct IClass
*CLASS
, Object
*obj
, struct MUIP_DeleteDragImage
*message
)
6737 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
6739 #if defined(DEBUG_ILC_FUNCS) || defined(DEBUG_ILC_ICONDRAGDROP)
6740 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
6743 if (!(data
->icld_SelectionLastClicked
)) return DoSuperMethodA(CLASS
,obj
,(Msg
)message
);
6747 if (message
->di
->bm
)
6748 FreeBitMap(message
->di
->bm
);
6749 FreeVec(message
->di
);
6756 /**************************************************************************
6758 **************************************************************************/
6759 IPTR
IconList__MUIM_DragQuery(struct IClass
*CLASS
, Object
*obj
, struct MUIP_DragQuery
*message
)
6761 #if defined(DEBUG_ILC_FUNCS) || defined(DEBUG_ILC_ICONDRAGDROP)
6762 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
6765 /* TODO: highlight the possible drop target entry .. */
6767 if (message
->obj
== obj
)
6768 return MUIV_DragQuery_Accept
;
6771 BOOL is_iconlist
= FALSE
;
6772 struct IClass
*msg_cl
= OCLASS(message
->obj
);
6776 if (msg_cl
== CLASS
)
6781 msg_cl
= msg_cl
->cl_Super
;
6784 return MUIV_DragQuery_Accept
;
6787 return MUIV_DragQuery_Refuse
;
6792 /**************************************************************************
6794 **************************************************************************/
6795 IPTR
IconList__MUIM_DragDrop(struct IClass
*CLASS
, Object
*obj
, struct MUIP_DragDrop
*message
)
6797 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
6799 #if defined(DEBUG_ILC_FUNCS) || defined(DEBUG_ILC_ICONDRAGDROP)
6800 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
6803 struct IconList_Entry
*entry
= (IPTR
)MUIV_IconList_NextIcon_Start
;
6805 if (data
->icld_DragDropEvent
)
6807 struct IconList_Drop_SourceEntry
*clean_node
;
6808 #if defined(DEBUG_ILC_ICONDRAGDROP)
6809 D(bug("[IconList] %s: Cleaning existing IconList_Drop_Event @ %p\n", __PRETTY_FUNCTION__
, data
->icld_DragDropEvent
));
6811 while ((clean_node
= (struct IconList_Drop_SourceEntry
*)RemTail(&data
->icld_DragDropEvent
->drop_SourceList
)) != NULL
)
6813 FreeVec(clean_node
->dropse_Node
.ln_Name
);
6814 FreeMem(clean_node
, sizeof(struct IconList_Drop_SourceEntry
));
6816 FreeVec(data
->icld_DragDropEvent
->drop_TargetPath
);
6817 FreeMem(data
->icld_DragDropEvent
, sizeof(struct IconList_Drop_Event
));
6818 data
->icld_DragDropEvent
= NULL
;
6821 /* SANITY CHECK: Get first selected entry from SOURCE iconlist */
6822 DoMethod(message
->obj
, MUIM_IconList_NextIcon
, MUIV_IconList_NextIcon_Selected
, (IPTR
)&entry
);
6824 if ((entry
) && ((IPTR
)entry
!= MUIV_IconList_NextIcon_End
))
6826 /* Ok.. atleast one entry was dropped .. */
6827 char tmp_dirbuff
[256];
6828 BPTR tmp_dirlock
= (BPTR
) NULL
;
6830 BOOL iconMove
= FALSE
;
6831 struct IconEntry
*node
= NULL
;
6832 struct IconEntry
*drop_target_node
= NULL
;
6833 STRPTR directory_path
= NULL
;
6834 struct IconList_Drop_Event
*dragDropEvent
= NULL
;
6836 GET(obj
, MUIA_IconDrawerList_Drawer
, &directory_path
);
6838 /* Properly expand the name incase it uses devices rather than volumes */
6839 if (directory_path
!= NULL
)
6841 tmp_dirlock
= Lock(directory_path
, SHARED_LOCK
);
6844 if (NameFromLock(tmp_dirlock
, tmp_dirbuff
, 256) != 0)
6846 directory_path
= tmp_dirbuff
;
6848 UnLock(tmp_dirlock
);
6851 if ((dragDropEvent
= AllocMem(sizeof(struct IconList_Drop_Event
), MEMF_CLEAR
)) == NULL
)
6853 #if defined(DEBUG_ILC_ICONDRAGDROP)
6854 D(bug("[IconList] %s: Failed to allocate IconList_Drop_Event Storage!\n", __PRETTY_FUNCTION__
));
6858 #if defined(DEBUG_ILC_ICONDRAGDROP)
6859 D(bug("[IconList] %s: Allocated IconList_Drop_Event @ %p\n", __PRETTY_FUNCTION__
, dragDropEvent
));
6862 NewList(&dragDropEvent
->drop_SourceList
);
6864 /* go through list and check if dropped on entry */
6867 #if defined(__AROS__)
6868 ForeachNode(&data
->icld_IconList
, node
)
6870 Foreach_Node(&data
->icld_IconList
, node
);
6873 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
6875 if (node
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
6877 ULONG rowTop
= _mtop(obj
) + (rowCount
* data
->icld_LVMAttribs
->lmva_RowHeight
);
6878 rowTop
+= data
->icld_LVMAttribs
->lmva_HeaderHeight
;
6880 if (((message
->x
> _mleft(obj
)) && (message
->x
< _mright(obj
)))
6881 && ((message
->y
> rowTop
) && (message
->y
< (rowTop
+ data
->icld_LVMAttribs
->lmva_RowHeight
))))
6883 drop_target_node
= node
;
6892 struct Rectangle iconbox
;
6893 LONG click_x
= message
->x
- _mleft(obj
);
6894 LONG click_y
= message
->y
- _mtop(obj
);
6895 iconbox
.MinX
= node
->ie_IconX
- data
->icld_ViewX
;
6896 iconbox
.MaxX
= (node
->ie_IconX
+ node
->ie_AreaWidth
) - data
->icld_ViewX
;
6897 iconbox
.MinY
= node
->ie_IconY
- data
->icld_ViewY
;
6898 iconbox
.MaxY
= (node
->ie_IconY
+ node
->ie_AreaHeight
)- data
->icld_ViewY
;
6900 if ((node
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
) &&
6901 (click_x
>= iconbox
.MinX
) &&
6902 (click_x
< iconbox
.MaxX
) &&
6903 (click_y
>= iconbox
.MinY
) &&
6904 (click_y
< iconbox
.MaxY
))
6906 drop_target_node
= node
;
6912 /* Additional filter - if same window and the target entry is selected (==dragged), then it was intended as a move */
6913 if ((message
->obj
== obj
) && (drop_target_node
) && (drop_target_node
->ie_Flags
& ICONENTRY_FLAG_SELECTED
))
6914 drop_target_node
= NULL
;
6916 if ((drop_target_node
!= NULL
) &&
6917 ((drop_target_node
->ie_IconListEntry
.type
== ST_SOFTLINK
) ||
6918 (drop_target_node
->ie_IconListEntry
.type
== ST_ROOT
) ||
6919 (drop_target_node
->ie_IconListEntry
.type
== ST_USERDIR
) ||
6920 (drop_target_node
->ie_IconListEntry
.type
== ST_LINKDIR
) ||
6921 (drop_target_node
->ie_IconListEntry
.type
== ST_FILE
) ||
6922 (drop_target_node
->ie_IconListEntry
.type
== ST_LINKFILE
)))
6924 /* Dropped on some entry */
6925 if ((drop_target_node
->ie_IconListEntry
.type
!= ST_ROOT
) && (drop_target_node
->ie_IconListEntry
.type
!= ST_SOFTLINK
))
6929 int fulllen
= strlen(directory_path
) + strlen(drop_target_node
->ie_IconListEntry
.label
) + 2;
6931 if ((dragDropEvent
->drop_TargetPath
= AllocVec(fulllen
, MEMF_CLEAR
)) == NULL
)
6933 bug("[IconList] %s: Failed to allocate IconList_Drop_Event->drop_TargetPath Storage!\n", __PRETTY_FUNCTION__
);
6936 strcpy(dragDropEvent
->drop_TargetPath
, directory_path
);
6937 AddPart(dragDropEvent
->drop_TargetPath
, drop_target_node
->ie_IconListEntry
.label
, fulllen
);
6944 if ((dragDropEvent
->drop_TargetPath
= AllocVec(strlen(drop_target_node
->ie_IconListEntry
.label
) + 1, MEMF_CLEAR
)) == NULL
)
6946 bug("[IconList] %s: Failed to allocate IconList_Drop_Event->drop_TargetPath Storage!\n", __PRETTY_FUNCTION__
);
6949 strcpy(dragDropEvent
->drop_TargetPath
, drop_target_node
->ie_IconListEntry
.label
);
6952 #if defined(DEBUG_ILC_ICONDRAGDROP)
6953 D(bug("[IconList] %s: Target Entry Full Path = '%s'\n", __PRETTY_FUNCTION__
, dragDropEvent
->drop_TargetPath
));
6955 /* mark the Entry the selection was dropped on*/
6956 //drop_target_node->ie_Flags |= ICONENTRY_FLAG_SELECTED;
6957 //data->icld_UpdateMode = UPDATE_SINGLEENTRY;
6958 //data->update_entry = drop_target_node;
6959 //MUI_Redraw(obj,MADF_DRAWUPDATE);
6963 /* Not dropped on entry -> get path of DESTINATION iconlist */
6964 /* Note: directory_path is NULL when dropped on Wanderer's desktop */
6965 if ((message
->obj
!= obj
) && directory_path
)
6967 #if defined(DEBUG_ILC_ICONDRAGDROP)
6968 D(bug("[IconList] %s: drop entry: Icons dropped in window '%s'\n", __PRETTY_FUNCTION__
, directory_path
));
6971 if ((dragDropEvent
->drop_TargetPath
= AllocVec(strlen(directory_path
) + 1, MEMF_CLEAR
)) != NULL
)
6973 strcpy(dragDropEvent
->drop_TargetPath
, directory_path
);
6977 #if defined(DEBUG_ILC_ICONDRAGDROP)
6978 D(bug("[IconList] %s: Failed to allocate IconList_Drop_Event->drop_TargetPath Storage!\n", __PRETTY_FUNCTION__
));
6983 else if (message
->obj
== obj
)
6985 #if defined(DEBUG_ILC_ICONDRAGDROP)
6986 D(bug("[IconList] %s: drop entry: Entry Move detected ..\n", __PRETTY_FUNCTION__
));
6990 /* Adjust entry posiions .. */
6991 #if defined(DEBUG_ILC_ICONDRAGDROP)
6992 D(bug("[IconList] %s: drop entry: message x,y = %d, %d click = %d, %d..\n", __PRETTY_FUNCTION__
, message
->x
, message
->y
, data
->click_x
, data
->click_y
));
6994 LONG offset_x
= message
->x
- (data
->click_x
+ _mleft(obj
));
6995 LONG offset_y
= message
->y
- (data
->click_y
+ _mtop(obj
));
6997 entry
= (IPTR
)MUIV_IconList_NextIcon_Start
;
6998 while ((IPTR
)entry
!= MUIV_IconList_NextIcon_End
)
7000 DoMethod(message
->obj
, MUIM_IconList_NextIcon
, MUIV_IconList_NextIcon_Selected
, (IPTR
)&entry
);
7002 if ((IPTR
)entry
!= MUIV_IconList_NextIcon_End
)
7004 entry
->ile_IconEntry
->ie_IconX
+= offset_x
;
7005 entry
->ile_IconEntry
->ie_IconY
+= offset_y
;
7006 /* Remember new position as provided */
7007 DoMethod(obj
, MUIM_IconList_PropagateEntryPos
, entry
->ile_IconEntry
);
7009 SET(obj
, MUIA_IconList_IconMoved
, (IPTR
)entry
); // Now notify
7011 MUI_Redraw(obj
,MADF_DRAWOBJECT
);
7012 DoMethod(obj
, MUIM_IconList_CoordsSort
);
7016 #if defined(DEBUG_ILC_ICONDRAGDROP)
7017 D(bug("[IconList] %s: Icons Dropped on Wanderer Desktop (unhandled)!\n", __PRETTY_FUNCTION__
));
7027 /* Create list of entries to copy .. */
7028 entry
= (IPTR
)MUIV_IconList_NextIcon_Start
;
7029 while ((IPTR
)entry
!= MUIV_IconList_NextIcon_End
)
7031 DoMethod(message
->obj
, MUIM_IconList_NextIcon
, MUIV_IconList_NextIcon_Selected
, (IPTR
)&entry
);
7033 if ((IPTR
)entry
!= MUIV_IconList_NextIcon_End
)
7035 struct IconList_Drop_SourceEntry
*sourceEntry
= NULL
;
7036 sourceEntry
= AllocMem(sizeof(struct IconList_Drop_SourceEntry
), MEMF_CLEAR
);
7037 if ((entry
->type
!= ST_ROOT
) && (entry
->type
!= ST_SOFTLINK
))
7042 GET(message
->obj
, MUIA_IconDrawerList_Drawer
, &path
);
7043 /* Properly expand the location in case it uses devices rather than volumes */
7046 tmp_dirlock
= Lock(path
, SHARED_LOCK
);
7049 if (NameFromLock(tmp_dirlock
, tmp_dirbuff
, 256))
7053 UnLock(tmp_dirlock
);
7056 if (strcasecmp(dragDropEvent
->drop_TargetPath
, path
) != 0)
7058 fulllen
= strlen(path
) + strlen(entry
->ile_IconEntry
->ie_IconNode
.ln_Name
) + 2;
7059 sourceEntry
->dropse_Node
.ln_Name
= AllocVec(fulllen
, MEMF_CLEAR
);
7060 if (sourceEntry
->dropse_Node
.ln_Name
!= NULL
)
7062 strcpy(sourceEntry
->dropse_Node
.ln_Name
, path
);
7063 AddPart(sourceEntry
->dropse_Node
.ln_Name
, entry
->label
, fulllen
);
7065 #if defined(DEBUG_ILC_ICONDRAGDROP)
7066 D(bug("[IconList] %s: Source Entry (Full Path) = '%s'\n", __PRETTY_FUNCTION__
, sourceEntry
->dropse_Node
.ln_Name
));
7073 sourceEntry
->dropse_Node
.ln_Name
= AllocVec(strlen(entry
->label
) + 1, MEMF_CLEAR
);
7074 if (sourceEntry
->dropse_Node
.ln_Name
!= NULL
)
7075 strcpy(sourceEntry
->dropse_Node
.ln_Name
, entry
->label
);
7076 #if defined(DEBUG_ILC_ICONDRAGDROP)
7077 D(bug("[IconList] %s: Source Entry = '%s'\n", __PRETTY_FUNCTION__
, sourceEntry
->dropse_Node
.ln_Name
));
7081 if ((sourceEntry
->dropse_Node
.ln_Name
!= NULL
) && (strcasecmp(dragDropEvent
->drop_TargetPath
, sourceEntry
->dropse_Node
.ln_Name
) != 0))
7084 AddTail(&dragDropEvent
->drop_SourceList
, &sourceEntry
->dropse_Node
);
7088 #if defined(DEBUG_ILC_ICONDRAGDROP)
7089 D(bug("[IconList] %s: Source == Dest, Skipping!\n", __PRETTY_FUNCTION__
));
7091 FreeVec(sourceEntry
->dropse_Node
.ln_Name
);
7092 FreeMem(sourceEntry
, sizeof(struct IconList_Drop_SourceEntry
));
7098 dragDropEvent
->drop_TargetObj
= obj
;
7100 #if defined(DEBUG_ILC_ICONDRAGDROP)
7101 D(bug("[IconList] %s: Causing DROP notification..\n", __PRETTY_FUNCTION__
));
7103 SET(obj
, MUIA_IconList_IconsDropped
, (IPTR
)dragDropEvent
);
7104 DoMethod(obj
, MUIM_IconList_CoordsSort
);
7108 FreeVec(dragDropEvent
->drop_TargetPath
);
7109 FreeMem(dragDropEvent
, sizeof(struct IconList_Drop_Event
));
7115 #if defined(DEBUG_ILC_ICONDRAGDROP)
7116 D(bug("[IconList] %s: BUG - DragDrop received with no source icons!\n", __PRETTY_FUNCTION__
));
7118 NNSET(obj
, MUIA_IconList_IconsDropped
, (IPTR
)NULL
);
7122 return DoSuperMethodA(CLASS
, obj
, (Msg
)message
);
7126 ///MUIM_UnselectAll()
7127 /**************************************************************************
7129 **************************************************************************/
7130 IPTR
IconList__MUIM_IconList_UnselectAll(struct IClass
*CLASS
, Object
*obj
, Msg message
)
7132 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
7133 struct Node
*node
= NULL
, *next_node
= NULL
;
7134 BOOL changed
= FALSE
;
7136 #if defined(DEBUG_ILC_FUNCS)
7137 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
7140 data
->icld_SelectionLastClicked
= NULL
;
7141 data
->icld_FocusIcon
= NULL
;
7142 #if defined(__AROS__)
7143 ForeachNodeSafe(&data
->icld_SelectionList
, node
, next_node
)
7145 Foreach_NodeSafe(&data
->icld_SelectionList
, node
, next_node
);
7148 struct IconEntry
*entry
= (struct IconEntry
*)((IPTR
)node
- ((IPTR
)&entry
->ie_SelectionNode
- (IPTR
)entry
));
7149 BOOL update_entry
= FALSE
;
7151 if (entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
7153 if (entry
->ie_Flags
& ICONENTRY_FLAG_SELECTED
)
7156 entry
->ie_Flags
&= ~ICONENTRY_FLAG_SELECTED
;
7157 update_entry
= TRUE
;
7159 if (entry
->ie_Flags
& ICONENTRY_FLAG_FOCUS
)
7161 entry
->ie_Flags
&= ~ICONENTRY_FLAG_FOCUS
;
7162 update_entry
= TRUE
;
7169 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
7170 data
->update_entry
= entry
;
7171 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
7176 SET(obj
, MUIA_IconList_SelectionChanged
, TRUE
);
7183 /**************************************************************************
7185 **************************************************************************/
7186 IPTR
IconList__MUIM_IconList_SelectAll(struct IClass
*CLASS
, Object
*obj
, Msg message
)
7188 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
7189 struct IconEntry
*node
= NULL
;
7190 BOOL changed
= FALSE
;
7192 #if defined(DEBUG_ILC_FUNCS)
7193 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
7196 node
= (struct IconEntry
*)GetHead(&data
->icld_IconList
);
7198 while (node
!= NULL
)
7200 if (node
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
7202 BOOL update_entry
= FALSE
;
7204 if (!(node
->ie_Flags
& ICONENTRY_FLAG_SELECTED
))
7206 AddTail(&data
->icld_SelectionList
, &node
->ie_SelectionNode
);
7207 node
->ie_Flags
|= ICONENTRY_FLAG_SELECTED
;
7208 update_entry
= TRUE
;
7210 data
->icld_SelectionLastClicked
= node
;
7212 else if (node
->ie_Flags
& ICONENTRY_FLAG_FOCUS
)
7214 node
->ie_Flags
&= ~ICONENTRY_FLAG_FOCUS
;
7215 update_entry
= TRUE
;
7221 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
7222 data
->update_entry
= node
;
7223 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
7226 node
= (struct IconEntry
*)GetSucc(&node
->ie_IconNode
);
7229 if ((data
->icld_SelectionLastClicked
) && (data
->icld_SelectionLastClicked
!= data
->icld_FocusIcon
))
7231 data
->icld_FocusIcon
= data
->icld_SelectionLastClicked
;
7232 if (!(data
->icld_FocusIcon
->ie_Flags
& ICONENTRY_FLAG_FOCUS
))
7234 data
->icld_FocusIcon
->ie_Flags
&= ~ICONENTRY_FLAG_FOCUS
;
7235 data
->icld_FocusIcon
->ie_Flags
|= ICONENTRY_FLAG_FOCUS
;
7236 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
7237 data
->update_entry
= data
->icld_FocusIcon
;
7238 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
7243 SET(obj
, MUIA_IconList_SelectionChanged
, TRUE
);
7249 ///IconList__MUIM_IconList_CoordsSort()
7250 IPTR
IconList__MUIM_IconList_CoordsSort(struct IClass
*CLASS
, Object
*obj
, struct MUIP_IconList_Sort
*message
)
7252 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
7254 struct IconEntry
*entry
= NULL
,
7257 struct List list_VisibleIcons
;
7258 struct List list_HiddenIcons
;
7259 // struct List list_UnplacedIcons;
7262 perform a quick sort of the iconlist based on entry coords
7263 this method DOESNT cause any visual output.
7265 #if defined(DEBUG_ILC_FUNCS) || defined(DEBUG_ILC_ICONSORTING)
7266 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
7269 NewList((struct List
*)&list_VisibleIcons
);
7270 NewList((struct List
*)&list_HiddenIcons
);
7272 /*move list into our local list struct(s)*/
7273 while ((entry
= (struct IconEntry
*)RemTail((struct List
*)&data
->icld_IconList
)))
7275 if (entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
7277 AddHead((struct List
*)&list_VisibleIcons
, (struct Node
*)&entry
->ie_IconNode
);
7280 AddHead((struct List
*)&list_HiddenIcons
, (struct Node
*)&entry
->ie_IconNode
);
7283 while ((entry
= (struct IconEntry
*)RemTail((struct List
*)&list_VisibleIcons
)))
7285 if ((test_icon
= (struct IconEntry
*)GetTail(&data
->icld_IconList
)) != NULL
)
7287 while (test_icon
!= NULL
)
7289 if (((data
->icld_DisplayFlags
& ICONLIST_DISP_VERTICAL
) && (test_icon
->ie_IconX
> entry
->ie_IconX
)) ||
7290 (!(data
->icld_DisplayFlags
& ICONLIST_DISP_VERTICAL
) && (test_icon
->ie_IconY
> entry
->ie_IconY
)))
7292 test_icon
= (struct IconEntry
*)GetPred(&test_icon
->ie_IconNode
);
7298 while (test_icon
!= NULL
)
7300 if (((data
->icld_DisplayFlags
& ICONLIST_DISP_VERTICAL
) && (test_icon
->ie_IconY
> entry
->ie_IconY
)) ||
7301 (!(data
->icld_DisplayFlags
& ICONLIST_DISP_VERTICAL
) && (test_icon
->ie_IconX
> entry
->ie_IconX
)))
7303 test_icon
= (struct IconEntry
*)GetPred(&test_icon
->ie_IconNode
);
7308 Insert((struct List
*)&data
->icld_IconList
, (struct Node
*)&entry
->ie_IconNode
, (struct Node
*)&test_icon
->ie_IconNode
);
7311 AddTail((struct List
*)&data
->icld_IconList
, (struct Node
*)&entry
->ie_IconNode
);
7313 #if defined(DEBUG_ILC_ICONSORTING)
7314 D(bug("[IconList] %s: Done\n", __PRETTY_FUNCTION__
));
7317 while ((entry
= (struct IconEntry
*)RemTail((struct List
*)&list_HiddenIcons
)))
7319 AddTail((struct List
*)&data
->icld_IconList
, (struct Node
*)&entry
->ie_IconNode
);
7322 #if defined(DEBUG_ILC_ICONSORTING_DUMP)
7323 #if defined(__AROS__)
7324 ForeachNode(&data
->icld_IconList
, entry
)
7326 Foreach_Node(&data
->icld_IconList
, entry
);
7329 D(bug("[IconList] %s: %d %d '%s'\n", __PRETTY_FUNCTION__
, entry
->ie_IconX
, entry
->ie_IconY
, entry
->ie_IconListEntry
.label
));
7338 /**************************************************************************
7339 MUIM_Sort - sortsort
7340 **************************************************************************/
7341 IPTR
IconList__MUIM_IconList_Sort(struct IClass
*CLASS
, Object
*obj
, struct MUIP_IconList_Sort
*message
)
7343 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
7344 struct IconEntry
*entry
= NULL
,
7348 struct List list_VisibleIcons
,
7352 BOOL sortme
, reversable
= TRUE
, enqueue
= FALSE
;
7353 int i
, visible_count
= 0;
7355 #if defined(DEBUG_ILC_FUNCS) || defined(DEBUG_ILC_ICONSORTING)
7356 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
7359 /* Reset incase view options have changed .. */
7360 data
->icld_IconAreaLargestWidth
= 0;
7361 data
->icld_IconAreaLargestHeight
= 0;
7362 data
->icld_IconLargestHeight
= 0;
7363 data
->icld_LabelLargestHeight
= 0;
7365 #if defined(DEBUG_ILC_ICONSORTING)
7366 D(bug("[IconList] %s: Sort-Flags : %x\n", __PRETTY_FUNCTION__
, (data
->icld_SortFlags
& MUIV_IconList_Sort_MASK
)));
7368 NewList((struct List
*)&list_VisibleIcons
);
7369 NewList((struct List
*)&list_SortedIcons
);
7370 NewList((struct List
*)&list_HiddenIcons
);
7372 /*move list into our local list struct(s)*/
7373 while ((entry
= (struct IconEntry
*)RemTail((struct List
*)&data
->icld_IconList
)))
7375 if (!(entry
->ie_Flags
& ICONENTRY_FLAG_HASICON
))
7377 if (data
->icld_DisplayFlags
& ICONLIST_DISP_SHOWINFO
)
7379 if (entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
7381 entry
->ie_Flags
&= ~(ICONENTRY_FLAG_VISIBLE
|ICONENTRY_FLAG_NEEDSUPDATE
);
7384 else if (!(entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
))
7386 entry
->ie_Flags
|= (ICONENTRY_FLAG_VISIBLE
|ICONENTRY_FLAG_NEEDSUPDATE
);
7391 if (!(entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
))
7393 entry
->ie_Flags
|= (ICONENTRY_FLAG_VISIBLE
|ICONENTRY_FLAG_NEEDSUPDATE
);
7397 /* Now we have fixed visibility lets dump them into the correct list for sorting */
7398 if (entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
7400 if(entry
->ie_AreaWidth
> data
->icld_IconAreaLargestWidth
) data
->icld_IconAreaLargestWidth
= entry
->ie_AreaWidth
;
7401 if(entry
->ie_AreaHeight
> data
->icld_IconAreaLargestHeight
) data
->icld_IconAreaLargestHeight
= entry
->ie_AreaHeight
;
7402 if(entry
->ie_IconHeight
> data
->icld_IconLargestHeight
) data
->icld_IconLargestHeight
= entry
->ie_IconHeight
;
7403 if((entry
->ie_AreaHeight
- entry
->ie_IconHeight
) > data
->icld_LabelLargestHeight
) data
->icld_LabelLargestHeight
= entry
->ie_AreaHeight
- entry
->ie_IconHeight
;
7405 if (((data
->icld_SortFlags
& MUIV_IconList_Sort_AutoSort
) == 0) && (entry
->ie_ProvidedIconX
== NO_ICON_POSITION
))
7406 AddTail((struct List
*)&list_VisibleIcons
, (struct Node
*)&entry
->ie_IconNode
);
7408 AddHead((struct List
*)&list_VisibleIcons
, (struct Node
*)&entry
->ie_IconNode
);
7413 if (entry
->ie_Flags
& ICONENTRY_FLAG_SELECTED
)
7415 Remove(&entry
->ie_SelectionNode
);
7417 entry
->ie_Flags
&= ~(ICONENTRY_FLAG_SELECTED
|ICONENTRY_FLAG_FOCUS
);
7418 if (data
->icld_SelectionLastClicked
== entry
) data
->icld_SelectionLastClicked
= NULL
;
7419 if (data
->icld_FocusIcon
== entry
) data
->icld_FocusIcon
= data
->icld_SelectionLastClicked
;
7420 AddHead((struct List
*)&list_HiddenIcons
, (struct Node
*)&entry
->ie_IconNode
);
7424 /* Copy each visible entry back to the main list, sorting as we go*/
7425 while ((entry
= (struct IconEntry
*)RemHead((struct List
*)&list_VisibleIcons
)))
7427 icon1
= (struct IconEntry
*)GetHead(&list_SortedIcons
);
7432 if (visible_count
> 1)
7434 #if defined(DEBUG_ILC_ICONSORTING)
7435 D(bug("[IconList] %s: - %s %s %s %i\n", __PRETTY_FUNCTION__
, entry
->ie_IconListEntry
.label
, entry
->ie_TxtBuf_DATE
, entry
->ie_TxtBuf_TIME
, entry
->ie_FileInfoBlock
->fib_Size
));
7439 if(((icon1
->ie_IconListEntry
.type
== ST_ROOT
) || (icon1
->ie_IconListEntry
.type
== ST_LINKDIR
) || (icon1
->ie_IconListEntry
.type
== ST_LINKFILE
))
7440 || (data
->icld_SortFlags
& MUIV_IconList_Sort_DrawersMixed
))
7442 /*volume list or drawers mixed*/
7448 if ((icon1
->ie_IconListEntry
.type
== ST_USERDIR
) && (entry
->ie_IconListEntry
.type
== ST_USERDIR
))
7454 if ((icon1
->ie_IconListEntry
.type
!= ST_USERDIR
) && (entry
->ie_IconListEntry
.type
!= ST_USERDIR
))
7458 /* we are the first drawer to arrive or we need to insert ourselves
7459 due to being sorted to the end of the drawers*/
7461 if ((!icon2
|| icon2
->ie_IconListEntry
.type
== ST_USERDIR
) &&
7462 (entry
->ie_IconListEntry
.type
== ST_USERDIR
) &&
7463 (icon1
->ie_IconListEntry
.type
!= ST_USERDIR
))
7465 #if defined(DEBUG_ILC_ICONSORTING)
7466 D(bug("[IconList] %s: force %s\n", __PRETTY_FUNCTION__
, entry
->ie_IconListEntry
.label
));
7478 if ((data
->icld_SortFlags
& MUIV_IconList_Sort_AutoSort
) == 0)
7480 if ((entry
->ie_ProvidedIconX
!= NO_ICON_POSITION
) && (entry
->ie_ProvidedIconY
!= NO_ICON_POSITION
))
7488 if (data
->icld_SortFlags
& MUIV_IconList_Sort_ByDate
)
7491 i
= CompareDates((const struct DateStamp
*)&entry
->ie_FileInfoBlock
->fib_Date
,(const struct DateStamp
*)&icon1
->ie_FileInfoBlock
->fib_Date
);
7493 else if (data
->icld_SortFlags
& MUIV_IconList_Sort_BySize
)
7495 /* Sort by Size .. */
7496 i
= entry
->ie_FileInfoBlock
->fib_Size
- icon1
->ie_FileInfoBlock
->fib_Size
;
7498 else if ((data
->icld_SortFlags
& MUIV_IconList_Sort_ByType
) && ((entry
->ie_IconListEntry
.type
== ST_FILE
) || (entry
->ie_IconListEntry
.type
== ST_USERDIR
)))
7500 /* Sort by Type .. */
7501 /* TODO: Sort icons based on type using datatypes */
7505 /* Sort by Name .. */
7506 i
= Stricmp(entry
->ie_IconListEntry
.label
, icon1
->ie_IconListEntry
.label
);
7507 if ((data
->icld_SortFlags
& MUIV_IconList_Sort_DrawersMixed
) == 0) enqueue
= TRUE
;
7511 if ((reversable
) && data
->icld_SortFlags
& MUIV_IconList_Sort_Reverse
)
7520 icon1
= (struct IconEntry
*)GetSucc(&icon1
->ie_IconNode
);
7523 Insert((struct List
*)&list_SortedIcons
, (struct Node
*)&entry
->ie_IconNode
, (struct Node
*)&icon2
->ie_IconNode
);
7527 /* Quickly resort based on node priorities .. */
7528 while ((entry
= (struct IconEntry
*)RemHead((struct List
*)&list_SortedIcons
)))
7530 Enqueue((struct List
*)&data
->icld_IconList
, (struct Node
*)&entry
->ie_IconNode
);
7535 while ((entry
= (struct IconEntry
*)RemHead((struct List
*)&list_SortedIcons
)))
7537 AddTail((struct List
*)&data
->icld_IconList
, (struct Node
*)&entry
->ie_IconNode
);
7541 DoMethod(obj
, MUIM_IconList_PositionIcons
);
7542 MUI_Redraw(obj
, MADF_DRAWOBJECT
);
7544 if ((data
->icld_SortFlags
& MUIV_IconList_Sort_Orders
) != 0)
7546 DoMethod(obj
, MUIM_IconList_CoordsSort
);
7548 /* leave hidden icons on a seperate list to speed up normal list parsing ? */
7549 while ((entry
= (struct IconEntry
*)RemHead((struct List
*)&list_HiddenIcons
)))
7551 AddTail((struct List
*)&data
->icld_IconList
, (struct Node
*)&entry
->ie_IconNode
);
7554 SET(obj
, MUIA_IconList_Changed
, TRUE
);
7560 ///MUIM_DragReport()
7561 /**************************************************************************
7562 MUIM_DragReport. Since MUI doesn't change the drop object if the dragged
7563 object is moved above another window (while still in the bounds of the
7564 orginal drop object) we must do it here manually to be compatible with
7565 MUI. Maybe Zune should fix this bug somewhen.
7566 **************************************************************************/
7567 IPTR
IconList__MUIM_DragReport(struct IClass
*CLASS
, Object
*obj
, struct MUIP_DragReport
*message
)
7569 struct Window
*wnd
= _window(obj
);
7570 struct Layer
*l
= NULL
;
7572 #if defined(DEBUG_ILC_FUNCS) || defined(DEBUG_ILC_ICONDRAGDROP)
7573 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
7576 LockLayerInfo(&wnd
->WScreen
->LayerInfo
);
7577 l
= WhichLayer(&wnd
->WScreen
->LayerInfo
, wnd
->LeftEdge
+ message
->x
, wnd
->TopEdge
+ message
->y
);
7578 UnlockLayerInfo(&wnd
->WScreen
->LayerInfo
);
7580 if (l
!= wnd
->WLayer
) return MUIV_DragReport_Abort
;
7582 return MUIV_DragReport_Continue
;
7586 ///MUIM_IconList_UnknownDropDestination()
7587 /**************************************************************************
7588 MUIM_IconList_UnknownDropDestination
7589 **************************************************************************/
7590 IPTR
IconList__MUIM_UnknownDropDestination(struct IClass
*CLASS
, Object
*obj
, struct MUIP_UnknownDropDestination
*message
)
7592 #if defined(DEBUG_ILC_FUNCS) || defined(DEBUG_ILC_ICONDRAGDROP)
7593 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
7595 #if defined(DEBUG_ILC_ICONDRAGDROP)
7596 D(bug("[IconList] %s: icons dropped on custom window \n", __PRETTY_FUNCTION__
));
7599 SET(obj
, MUIA_IconList_AppWindowDrop
, (IPTR
)message
); /* Now notify */
7605 ///MUIM_IconList_MakeEntryVisible()
7606 /**************************************************************************
7607 Move the visible area so that the selected entry becomes visible ..
7608 **************************************************************************/
7609 IPTR
IconList__MUIM_IconList_MakeEntryVisible(struct IClass
*CLASS
, Object
*obj
, struct MUIP_IconList_MakeEntryVisible
*message
)
7611 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
7612 BOOL viewmoved
= FALSE
;
7613 struct Rectangle iconrect
, viewrect
;
7615 #if defined(DEBUG_ILC_FUNCS)
7616 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
7619 viewrect
.MinX
= data
->icld_ViewX
;
7620 viewrect
.MaxX
= data
->icld_ViewX
+ data
->icld_AreaWidth
;
7621 viewrect
.MinY
= data
->icld_ViewY
;
7622 viewrect
.MaxY
= data
->icld_ViewY
+ data
->icld_AreaHeight
;
7624 IconList_GetIconAreaRectangle(obj
, data
, message
->entry
, &iconrect
);
7626 if (!(RectAndRect(&viewrect
, &iconrect
)))
7629 if (message
->entry
->ie_IconX
< data
->icld_ViewX
)
7630 data
->icld_ViewX
= message
->entry
->ie_IconX
;
7631 else if (message
->entry
->ie_IconX
> (data
->icld_ViewX
+ data
->icld_AreaWidth
))
7632 data
->icld_ViewX
= (message
->entry
->ie_IconX
+ message
->entry
->ie_AreaWidth
) - data
->icld_AreaWidth
;
7634 if (message
->entry
->ie_IconY
< data
->icld_ViewY
)
7635 data
->icld_ViewY
= message
->entry
->ie_IconX
;
7636 else if (message
->entry
->ie_IconY
> (data
->icld_ViewY
+ data
->icld_AreaHeight
))
7637 data
->icld_ViewY
= (message
->entry
->ie_IconY
+ message
->entry
->ie_AreaHeight
) - data
->icld_AreaHeight
;
7642 #if defined(DEBUG_ILC_ICONRENDERING)
7643 D(bug("[IconList]: %s: call SetSuperAttrs()\n", __PRETTY_FUNCTION__
));
7645 SetSuperAttrs(CLASS
, obj
, MUIA_Virtgroup_Left
, data
->icld_ViewX
,
7646 MUIA_Virtgroup_Top
, data
->icld_ViewY
,
7649 #if defined(DEBUG_ILC_ICONRENDERING)
7650 D(bug("[IconList]: %s: call SetAttrs()\n", __PRETTY_FUNCTION__
));
7652 SetAttrs(obj
, MUIA_Virtgroup_Left
, data
->icld_ViewX
,
7653 MUIA_Virtgroup_Top
, data
->icld_ViewY
,
7656 #if defined(DEBUG_ILC_ICONRENDERING)
7657 D(bug("[IconList]: %s: call MUI_Redraw()\n", __PRETTY_FUNCTION__
));
7659 MUI_Redraw(obj
,MADF_DRAWOBJECT
);
7664 #if defined(WANDERER_BUILTIN_ICONLIST)
7665 BOOPSI_DISPATCHER(IPTR
,IconList_Dispatcher
, CLASS
, obj
, message
)
7667 #if defined(__AROS__)
7668 switch (message
->MethodID
)
7670 struct IClass
*CLASS
= cl
;
7673 switch (msg
->MethodID
)
7676 case OM_NEW
: return IconList__OM_NEW(CLASS
, obj
, (struct opSet
*)message
);
7677 case OM_DISPOSE
: return IconList__OM_DISPOSE(CLASS
, obj
, message
);
7678 case OM_SET
: return IconList__OM_SET(CLASS
, obj
, (struct opSet
*)message
);
7679 case OM_GET
: return IconList__OM_GET(CLASS
, obj
, (struct opGet
*)message
);
7681 case MUIM_Family_AddTail
: return IconList__MUIM_Family_AddTail(CLASS
, obj
, (APTR
)message
);
7682 case MUIM_Family_AddHead
: return IconList__MUIM_Family_AddHead(CLASS
, obj
, (APTR
)message
);
7684 case MUIM_Family_Remove
: return IconList__MUIM_Family_Remove(CLASS
, obj
, (APTR
)message
);
7686 case MUIM_Setup
: return IconList__MUIM_Setup(CLASS
, obj
, (struct MUIP_Setup
*)message
);
7688 case MUIM_Show
: return IconList__MUIM_Show(CLASS
,obj
, (struct MUIP_Show
*)message
);
7689 case MUIM_Hide
: return IconList__MUIM_Hide(CLASS
,obj
, (struct MUIP_Hide
*)message
);
7690 case MUIM_Cleanup
: return IconList__MUIM_Cleanup(CLASS
, obj
, (struct MUIP_Cleanup
*)message
);
7691 case MUIM_AskMinMax
: return IconList__MUIM_AskMinMax(CLASS
, obj
, (struct MUIP_AskMinMax
*)message
);
7692 case MUIM_Draw
: return IconList__MUIM_Draw(CLASS
, obj
, (struct MUIP_Draw
*)message
);
7693 #if defined(__AROS__)
7694 case MUIM_Layout
: return IconList__MUIM_Layout(CLASS
, obj
, (struct MUIP_Layout
*)message
);
7696 case MUIM_HandleEvent
: return IconList__MUIM_HandleEvent(CLASS
, obj
, (struct MUIP_HandleEvent
*)message
);
7697 case MUIM_CreateDragImage
: return IconList__MUIM_CreateDragImage(CLASS
, obj
, (APTR
)message
);
7698 case MUIM_DeleteDragImage
: return IconList__MUIM_DeleteDragImage(CLASS
, obj
, (APTR
)message
);
7699 case MUIM_DragQuery
: return IconList__MUIM_DragQuery(CLASS
, obj
, (APTR
)message
);
7700 case MUIM_DragReport
: return IconList__MUIM_DragReport(CLASS
, obj
, (APTR
)message
);
7701 case MUIM_DragDrop
: return IconList__MUIM_DragDrop(CLASS
, obj
, (APTR
)message
);
7702 #if defined(__AROS__)
7703 case MUIM_UnknownDropDestination
: return IconList__MUIM_UnknownDropDestination(CLASS
, obj
, (APTR
)message
);
7705 case MUIM_IconList_Update
: return IconList__MUIM_IconList_Update(CLASS
, obj
, (APTR
)message
);
7706 case MUIM_IconList_Clear
: return IconList__MUIM_IconList_Clear(CLASS
, obj
, (APTR
)message
);
7707 case MUIM_IconList_RethinkDimensions
: return IconList__MUIM_IconList_RethinkDimensions(CLASS
, obj
, (APTR
)message
);
7708 case MUIM_IconList_CreateEntry
: return IconList__MUIM_IconList_CreateEntry(CLASS
, obj
, (APTR
)message
);
7709 case MUIM_IconList_UpdateEntry
: return IconList__MUIM_IconList_UpdateEntry(CLASS
, obj
, (APTR
)message
);
7710 case MUIM_IconList_DestroyEntry
: return IconList__MUIM_IconList_DestroyEntry(CLASS
, obj
, (APTR
)message
);
7711 case MUIM_IconList_DrawEntry
: return IconList__MUIM_IconList_DrawEntry(CLASS
, obj
, (APTR
)message
);
7712 case MUIM_IconList_DrawEntryLabel
: return IconList__MUIM_IconList_DrawEntryLabel(CLASS
, obj
, (APTR
)message
);
7713 case MUIM_IconList_NextIcon
: return IconList__MUIM_IconList_NextIcon(CLASS
, obj
, (APTR
)message
);
7714 case MUIM_IconList_GetIconPrivate
: return IconList__MUIM_IconList_GetIconPrivate(CLASS
, obj
, (APTR
)message
);
7715 case MUIM_IconList_UnselectAll
: return IconList__MUIM_IconList_UnselectAll(CLASS
, obj
, (APTR
)message
);
7716 case MUIM_IconList_Sort
: return IconList__MUIM_IconList_Sort(CLASS
, obj
, (APTR
)message
);
7717 case MUIM_IconList_CoordsSort
: return IconList__MUIM_IconList_CoordsSort(CLASS
, obj
, (APTR
)message
);
7718 case MUIM_IconList_PositionIcons
: return IconList__MUIM_IconList_PositionIcons(CLASS
, obj
, (APTR
)message
);
7719 case MUIM_IconList_SelectAll
: return IconList__MUIM_IconList_SelectAll(CLASS
, obj
, (APTR
)message
);
7720 case MUIM_IconList_MakeEntryVisible
: return IconList__MUIM_IconList_MakeEntryVisible(CLASS
, obj
, (APTR
)message
);
7723 return DoSuperMethodA(CLASS
, obj
, message
);
7725 BOOPSI_DISPATCHER_END
7727 #if defined(__AROS__)
7728 /* Class descriptor. */
7729 const struct __MUIBuiltinClass _MUI_IconList_desc
= {
7732 sizeof(struct IconList_DATA
),
7733 (void*)IconList_Dispatcher
7736 #endif /* WANDERER_BUILTIN_ICONLIST */
7738 #if !defined(__AROS__)
7739 struct MUI_CustomClass
*initIconListClass(void)
7741 return (struct MUI_CustomClass
*) MUI_CreateCustomClass(NULL
, MUIC_Area
, NULL
, sizeof(struct IconList_DATA
), ENTRY(IconList_Dispatcher
));