2 Copyright © 2001-2013, 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
, 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
)
738 static void RenderEntryField(Object
*obj
, struct IconList_DATA
*data
,
739 struct IconEntry
*entry
, struct Rectangle
*rect
, LONG index
, BOOL firstvis
,
740 BOOL lastvis
, struct RastPort
* rp
)
742 STRPTR text
= NULL
, renderflag
= "<UHOH>";
743 struct TextExtent te
;
746 if (entry
->ie_Flags
& ICONENTRY_FLAG_SELECTED
)
749 rect
->MinX
, rect
->MinY
,
750 rect
->MaxX
- rect
->MinX
+ 1, rect
->MaxY
- rect
->MinY
,
754 rect
->MinX
+= ENTRY_SPACING_LEFT
;
755 rect
->MaxX
-= ENTRY_SPACING_RIGHT
;
756 rect
->MinY
+= LINE_SPACING_TOP
;
757 rect
->MaxY
-= LINE_SPACING_BOTTOM
;
759 if (firstvis
) rect
->MinX
+= LINE_SPACING_LEFT
;
760 if (lastvis
) rect
->MaxX
-= LINE_SPACING_RIGHT
;
767 /* Special case !! we draw an image instead .. */
772 text
= entry
->ie_IconListEntry
.label
;
776 text
= entry
->ie_TxtBuf_SIZE
;
779 case INDEX_LASTACCESS
:
780 text
= AllocVec(strlen(entry
->ie_TxtBuf_DATE
) + strlen(entry
->ie_TxtBuf_TIME
) + 5, MEMF_CLEAR
);
782 sprintf(text
, "%s at %s", entry
->ie_TxtBuf_DATE
,
783 entry
->ie_TxtBuf_TIME
);
787 text
= entry
->ie_FileInfoBlock
->fib_Comment
;
790 case INDEX_PROTECTION
:
791 text
= entry
->ie_TxtBuf_PROT
;
796 if (!text
[0]) return;
798 if (text
== renderflag
)
800 if (entry
->ie_IconListEntry
.type
== ST_USERDIR
)
802 if (data
->icld_LVMAttribs
->lvma_IconDrawer
)
806 rp
, data
->icld_LVMAttribs
->lvma_IconDrawer
, NULL
,
807 rect
->MinX
+ 1, rect
->MinY
+ 1,
808 (entry
->ie_Flags
& ICONENTRY_FLAG_SELECTED
) ? IDS_SELECTED
: IDS_NORMAL
,
809 __iconList_DrawIconStateTags
815 rect
->MinX
+ 1, rect
->MinY
+ 1,
816 rect
->MaxX
- rect
->MinX
- 1, rect
->MaxY
- rect
->MinY
- 1,
822 if (data
->icld_LVMAttribs
->lvma_IconFile
)
826 rp
, data
->icld_LVMAttribs
->lvma_IconFile
, NULL
,
827 rect
->MinX
+ 1, rect
->MinY
+ 1,
828 (entry
->ie_Flags
& ICONENTRY_FLAG_SELECTED
) ? IDS_SELECTED
: IDS_NORMAL
,
829 __iconList_DrawIconStateTags
835 rect
->MinX
+ 1, rect
->MinY
+ 1,
836 rect
->MaxX
- rect
->MinX
- 1, rect
->MaxY
- rect
->MinY
- 1,
843 fit
= TextFit(rp
, text
, strlen(text
), &te
, NULL
, 1,
844 rect
->MaxX
- rect
->MinX
+ 1,
845 rect
->MaxY
- rect
->MinY
+ 1);
849 SetABPenDrMd(rp
, _pens(obj
)[(entry
->ie_Flags
& ICONENTRY_FLAG_SELECTED
) ? MPEN_SHINE
: MPEN_TEXT
], 0, JAM1
);
851 if (((rect
->MaxY
- rect
->MinY
+ 1) - data
->icld_IconLabelFont
->tf_YSize
) > 0)
853 rect
->MinY
+= ((rect
->MaxY
- rect
->MinY
+ 1) - data
->icld_IconLabelFont
->tf_YSize
)/2;
856 switch(data
->icld_LVMAttribs
->lmva_ColumnHAlign
[index
])
858 case COLUMN_ALIGN_LEFT
:
859 Move(rp
, rect
->MinX
, rect
->MinY
+ rp
->TxBaseline
);
862 case COLUMN_ALIGN_RIGHT
:
863 Move(rp
, rect
->MaxX
- te
.te_Width
, rect
->MinY
+ rp
->TxBaseline
);
866 case COLUMN_ALIGN_CENTER
:
867 Move(rp
, rect
->MinX
+ (rect
->MaxX
- rect
->MinX
+ 1 + 1 - te
.te_Width
) / 2,
868 rect
->MinY
+ rp
->TxBaseline
);
874 if ((index
== INDEX_LASTACCESS
) && text
)
879 /**************************************************************************
880 Draw the entry at its position
881 **************************************************************************/
882 ///IconList__MUIM_IconList_DrawEntry()
883 IPTR
IconList__MUIM_IconList_DrawEntry(struct IClass
*CLASS
, Object
*obj
, struct MUIP_IconList_DrawEntry
*message
)
885 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
887 BOOL outside
= FALSE
;
889 struct Rectangle iconrect
;
890 struct Rectangle objrect
;
892 ULONG objX
, objY
, objW
, objH
;
895 if (data
->icld_BufferRastPort
== data
->icld_DisplayRastPort
)
904 objW
= _mright(obj
) - _mleft(obj
) + 1;
905 objH
= _mbottom(obj
) - _mtop(obj
) + 1;
907 #if defined(DEBUG_ILC_ICONRENDERING)
908 D(bug("[IconList]: %s(message->entry = 0x%p)\n", __PRETTY_FUNCTION__
, message
->entry
));
911 if ((!(message
->entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)) ||
912 (data
->icld_BufferRastPort
== NULL
) ||
913 (!(message
->entry
->ie_DiskObj
)))
915 #if defined(DEBUG_ILC_ICONRENDERING)
916 D(bug("[IconList] %s: Not visible or missing DOB\n", __PRETTY_FUNCTION__
));
921 /* Set the dimensions of our "view" */
924 objrect
.MaxX
= objX
+ objW
- 1;
925 objrect
.MaxY
= objY
+ objH
- 1;
927 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
929 struct Rectangle linerect
;
931 LONG firstvis
, lastvis
;
933 linerect
.MinX
= objX
- data
->icld_ViewX
;
934 linerect
.MaxX
= objX
+ objW
- 1; //linerect.MinX + data->width - 1;
935 linerect
.MinY
= (objY
- data
->icld_ViewY
) + data
->icld_LVMAttribs
->lmva_HeaderHeight
+ (message
->drawmode
* data
->icld_LVMAttribs
->lmva_RowHeight
);
936 linerect
.MaxY
= linerect
.MinY
+ data
->icld_LVMAttribs
->lmva_RowHeight
- 1;
938 if (!AndRectRect(&linerect
, &objrect
, NULL
)) return FALSE
;
939 // if (!MustRenderRect(data, &linerect)) return;
941 SetFont(data
->icld_BufferRastPort
, data
->icld_IconLabelFont
);
943 x
= linerect
.MinX
+ LINE_SPACING_LEFT
;
945 firstvis
= FirstVisibleColumnNumber(data
);
946 lastvis
= LastVisibleColumnNumber(data
);
948 for(i
= 0; i
< NUM_COLUMNS
; i
++)
950 struct Rectangle field_rect
;
951 LONG index
= data
->icld_LVMAttribs
->lmva_ColumnPos
[i
];
953 if (!(data
->icld_LVMAttribs
->lmva_ColumnFlags
[i
] & LVMCF_COLVISIBLE
)) continue;
955 field_rect
.MinX
= (i
== firstvis
) ? linerect
.MinX
: x
;
956 field_rect
.MinY
= linerect
.MinY
;
957 field_rect
.MaxX
= x
+ data
->icld_LVMAttribs
->lmva_ColumnWidth
[index
] - 1 + ((i
== lastvis
) ? LINE_SPACING_RIGHT
: 0);
958 field_rect
.MaxY
= linerect
.MaxY
;
960 /* if (MustRenderRect(data, &field_rect))
962 if (AndRectRect(&field_rect
, &objrect
, NULL
))
964 RenderEntryField(obj
, data
, message
->entry
, &field_rect
, index
,
965 (i
== firstvis
), (i
== lastvis
), data
->icld_BufferRastPort
);
968 x
+= data
->icld_LVMAttribs
->lmva_ColumnWidth
[index
];
971 if ((data
->icld_LVMAttribs
->lvma_Flags
& LVMAF_ROWDRAWTOEND
) == LVMAF_ROWDRAWTOEND
)
973 x
+= LINE_SPACING_RIGHT
;
975 if (x
< linerect
.MaxX
)
979 SetABPenDrMd(data
->icld_BufferRastPort
, _pens(obj
)[MPEN_SHINE
], 0, JAM1
);
980 RectFill(data
->icld_BufferRastPort
, linerect
.MinX
, linerect
.MinY
, linerect
.MaxX
, linerect
.MaxY
);
986 LONG offsetx
,offsety
;
988 /* Get the dimensions and affected area of message->entry */
989 IconList_GetIconImageRectangle(obj
, data
, message
->entry
, &iconrect
);
991 /* Get offset corrections */
992 IconList_GetIconImageOffsets(data
, message
->entry
, &offsetx
, &offsety
);
994 /* Add the relative position offset of the message->entry */
995 iconrect
.MinX
+= objX
- data
->icld_ViewX
+ message
->entry
->ie_IconX
+ offsetx
;
996 iconrect
.MaxX
+= objX
- data
->icld_ViewX
+ message
->entry
->ie_IconX
+ offsetx
;
997 iconrect
.MinY
+= objY
- data
->icld_ViewY
+ message
->entry
->ie_IconY
+ offsety
;
998 iconrect
.MaxY
+= objY
- data
->icld_ViewY
+ message
->entry
->ie_IconY
+ offsety
;
1000 if (!RectAndRect(&iconrect
, &objrect
))
1002 #if defined(DEBUG_ILC_ICONRENDERING)
1003 D(bug("[IconList] %s: Entry '%s' image outside of visible area .. skipping\n", __PRETTY_FUNCTION__
, message
->entry
->ie_IconListEntry
.label
));
1008 /* data->update_rect1 and data->update_rect2 may
1009 point to rectangles to indicate that only icons
1010 in any of this rectangles need to be drawn */
1011 if (data
->update_rect1
)
1013 if (!RectAndRect(&iconrect
, data
->update_rect1
)) outside
= TRUE
;
1016 if (data
->update_rect2
)
1018 if (data
->update_rect1
)
1020 if ((outside
== TRUE
) && RectAndRect(&iconrect
, data
->update_rect2
))
1025 if (!RectAndRect(&iconrect
, data
->update_rect2
))
1030 if (outside
== TRUE
)
1032 #if defined(DEBUG_ILC_ICONRENDERING)
1033 D(bug("[IconList] %s: Entry '%s' image outside of update area .. skipping\n", __PRETTY_FUNCTION__
, message
->entry
->ie_IconListEntry
.label
));
1038 if (message
->drawmode
== ICONENTRY_DRAWMODE_NONE
) return TRUE
;
1040 // Center entry image
1041 iconX
= iconrect
.MinX
- objX
+ data
->icld_DrawOffsetX
;
1042 iconY
= iconrect
.MinY
- objY
+ data
->icld_DrawOffsetY
;
1044 #if defined(DEBUG_ILC_ICONRENDERING)
1045 D(bug("[IconList] %s: DrawIconState('%s') .. %d, %d\n", __PRETTY_FUNCTION__
, message
->entry
->ie_IconListEntry
.label
, iconX
, iconY
));
1049 data
->icld_BufferRastPort
, message
->entry
->ie_DiskObj
, NULL
,
1052 (message
->entry
->ie_Flags
& ICONENTRY_FLAG_SELECTED
) ? IDS_SELECTED
: IDS_NORMAL
,
1053 __iconList_DrawIconStateTags
1055 #if defined(DEBUG_ILC_ICONRENDERING)
1056 D(bug("[IconList] %s: DrawIconState Done\n", __PRETTY_FUNCTION__
));
1064 ///IconList__LabelFunc_SplitLabel()
1065 static void IconList__LabelFunc_SplitLabel(Object
*obj
, struct IconList_DATA
*data
, struct IconEntry
*entry
)
1067 ULONG labelSplit_MaxLabelLineLength
= data
->icld__Option_LabelTextMaxLen
;
1068 ULONG labelSplit_LabelLength
= strlen(entry
->ie_IconListEntry
.label
);
1070 // ULONG labelSplit_FontY = data->icld_IconLabelFont->tf_YSize;
1071 int labelSplit_CharsDone
, labelSplit_CharsSplit
;
1072 ULONG labelSplit_CurSplitWidth
;
1074 if ((data
->icld__Option_TrimVolumeNames
) &&
1075 ((entry
->ie_IconListEntry
.type
== ST_ROOT
) && (entry
->ie_IconListEntry
.label
[labelSplit_LabelLength
- 1] == ':')))
1076 labelSplit_LabelLength
--;
1078 if (labelSplit_MaxLabelLineLength
>= labelSplit_LabelLength
)
1080 #if defined(DEBUG_ILC_ICONRENDERING)
1081 D(bug("[IconList]: %s: Label'%s' doesnt need split (onyl %d chars)\n", __PRETTY_FUNCTION__
, entry
->ie_IconListEntry
.label
, labelSplit_LabelLength
));
1086 SetFont(data
->icld_BufferRastPort
, data
->icld_IconLabelFont
);
1087 txwidth
= TextLength(data
->icld_BufferRastPort
, entry
->ie_IconListEntry
.label
, labelSplit_MaxLabelLineLength
);
1088 #if defined(DEBUG_ILC_ICONRENDERING)
1089 D(bug("[IconList]: %s: txwidth = %d\n", __PRETTY_FUNCTION__
, txwidth
));
1091 entry
->ie_TxtBuf_DisplayedLabel
= AllocVecPooled(data
->icld_Pool
, 256);
1092 if (entry
->ie_TxtBuf_DisplayedLabel
!= NULL
)
1093 memset(entry
->ie_TxtBuf_DisplayedLabel
, 0, 256);
1094 entry
->ie_SplitParts
= 0;
1096 labelSplit_CharsDone
= 0;
1097 labelSplit_CharsSplit
= 0;
1098 labelSplit_CurSplitWidth
= 0;
1100 while (labelSplit_CharsDone
< labelSplit_LabelLength
)
1102 ULONG labelSplit_CurSplitLength
= labelSplit_LabelLength
- labelSplit_CharsDone
;
1103 IPTR labelSplit_SplitStart
= (IPTR
)(entry
->ie_IconListEntry
.label
+ labelSplit_CharsDone
);
1104 int tmp_checkoffs
= 0;
1105 IPTR labelSplit_RemainingCharsAfterSplit
;
1106 IPTR labelSplit_CurSplitDest
;
1108 while (*(char *)(labelSplit_SplitStart
) == ' ')
1110 //Skip preceding spaces..
1111 labelSplit_SplitStart
= labelSplit_SplitStart
+ 1;
1112 labelSplit_CurSplitLength
= labelSplit_CurSplitLength
- 1;
1113 labelSplit_CharsDone
= labelSplit_CharsDone
+ 1;
1116 while(TextLength(data
->icld_BufferRastPort
, (char *)labelSplit_SplitStart
, labelSplit_CurSplitLength
) < txwidth
) labelSplit_CurSplitLength
++;
1117 while(TextLength(data
->icld_BufferRastPort
, (char *)labelSplit_SplitStart
, labelSplit_CurSplitLength
) > txwidth
) labelSplit_CurSplitLength
--;
1118 #if defined(DEBUG_ILC_ICONRENDERING)
1119 D(bug("[IconList]: %s: labelSplit_CurSplitLength = %d\n", __PRETTY_FUNCTION__
, labelSplit_CurSplitLength
));
1122 #if defined(DEBUG_ILC_ICONRENDERING)
1123 D(bug("[IconList]: %s: Attempting to find neat split ", __PRETTY_FUNCTION__
));
1125 while(tmp_checkoffs
< (labelSplit_CurSplitLength
- ILC_ICONLABEL_SHORTEST
))
1127 #if defined(DEBUG_ILC_ICONRENDERING)
1128 D(bug("%d", tmp_checkoffs
));
1130 labelSplit_RemainingCharsAfterSplit
= labelSplit_LabelLength
- (labelSplit_CharsDone
+ labelSplit_CurSplitLength
);
1132 if ((labelSplit_CurSplitLength
- tmp_checkoffs
) > ILC_ICONLABEL_SHORTEST
)
1134 #if defined(DEBUG_ILC_ICONRENDERING)
1137 if ((*(char *)(labelSplit_SplitStart
+ labelSplit_CurSplitLength
- tmp_checkoffs
) == ' ') ||
1138 (*(char *)(labelSplit_SplitStart
+ labelSplit_CurSplitLength
- tmp_checkoffs
) == '.') ||
1139 (*(char *)(labelSplit_SplitStart
+ labelSplit_CurSplitLength
- tmp_checkoffs
) == '-'))
1141 #if defined(DEBUG_ILC_ICONRENDERING)
1144 labelSplit_CurSplitLength
= labelSplit_CurSplitLength
- tmp_checkoffs
;
1145 labelSplit_RemainingCharsAfterSplit
= labelSplit_RemainingCharsAfterSplit
- tmp_checkoffs
;
1151 if ((labelSplit_RemainingCharsAfterSplit
- tmp_checkoffs
) < 0)
1153 #if defined(DEBUG_ILC_ICONRENDERING)
1156 labelSplit_CurSplitLength
= labelSplit_CurSplitLength
+ tmp_checkoffs
;
1157 labelSplit_RemainingCharsAfterSplit
= labelSplit_RemainingCharsAfterSplit
+ tmp_checkoffs
;
1162 if ((labelSplit_RemainingCharsAfterSplit
- tmp_checkoffs
) >= ILC_ICONLABEL_SHORTEST
)
1164 #if defined(DEBUG_ILC_ICONRENDERING)
1167 if ((*(char *)(labelSplit_SplitStart
+ labelSplit_CurSplitLength
+ tmp_checkoffs
) == ' ') ||
1168 (*(char *)(labelSplit_SplitStart
+ labelSplit_CurSplitLength
+ tmp_checkoffs
) == '.') ||
1169 (*(char *)(labelSplit_SplitStart
+ labelSplit_CurSplitLength
+ tmp_checkoffs
) == '-'))
1171 #if defined(DEBUG_ILC_ICONRENDERING)
1174 labelSplit_CurSplitLength
= labelSplit_CurSplitLength
+ tmp_checkoffs
;
1175 labelSplit_RemainingCharsAfterSplit
= labelSplit_RemainingCharsAfterSplit
+ tmp_checkoffs
;
1181 tmp_checkoffs
= tmp_checkoffs
+ 1;
1183 #if defined(DEBUG_ILC_ICONRENDERING)
1186 if (tmp_checkoffs
!= 0)
1188 #if defined(DEBUG_ILC_ICONRENDERING)
1189 D(bug("[IconList]: %s: Couldnt find neat split : Still %d chars\n", __PRETTY_FUNCTION__
, labelSplit_RemainingCharsAfterSplit
));
1191 if (labelSplit_RemainingCharsAfterSplit
<= ILC_ICONLABEL_SHORTEST
)
1193 labelSplit_CurSplitLength
= labelSplit_CurSplitLength
+ (labelSplit_RemainingCharsAfterSplit
- ILC_ICONLABEL_SHORTEST
);
1196 if ((labelSplit_CharsDone
+ labelSplit_CurSplitLength
) > labelSplit_LabelLength
) labelSplit_CurSplitLength
= labelSplit_LabelLength
- labelSplit_CharsDone
;
1198 if (entry
->ie_TxtBuf_DisplayedLabel
!= NULL
)
1200 labelSplit_CurSplitDest
= (IPTR
)(entry
->ie_TxtBuf_DisplayedLabel
1201 + labelSplit_CharsSplit
+ entry
->ie_SplitParts
);
1203 strncpy((char *)labelSplit_CurSplitDest
,
1204 (char *)labelSplit_SplitStart
, labelSplit_CurSplitLength
);
1206 labelSplit_CurSplitWidth
= TextLength(data
->icld_BufferRastPort
,
1207 (char *)labelSplit_CurSplitDest
, labelSplit_CurSplitLength
);
1210 entry
->ie_SplitParts
= entry
->ie_SplitParts
+ 1;
1212 labelSplit_CharsDone
= labelSplit_CharsDone
+ labelSplit_CurSplitLength
;
1213 labelSplit_CharsSplit
= labelSplit_CharsSplit
+ labelSplit_CurSplitLength
;
1215 if (labelSplit_CurSplitWidth
> entry
->ie_TxtBuf_DisplayedLabelWidth
) entry
->ie_TxtBuf_DisplayedLabelWidth
= labelSplit_CurSplitWidth
;
1217 if ((entry
->ie_SplitParts
<= 1) && entry
->ie_TxtBuf_DisplayedLabel
)
1219 FreeVecPooled(data
->icld_Pool
, entry
->ie_TxtBuf_DisplayedLabel
);
1220 entry
->ie_TxtBuf_DisplayedLabel
= NULL
;
1221 entry
->ie_SplitParts
= 0;
1223 // if ((labelSplit_FontY * entry->ie_SplitParts) > data->icld_LabelLargestHeight) data->icld_LabelLargestHeight = (labelSplit_FontY * entry->ie_SplitParts);
1227 ///IconList__LabelFunc_CreateLabel()
1228 static IPTR
IconList__LabelFunc_CreateLabel(Object
*obj
, struct IconList_DATA
*data
, struct IconEntry
*entry
)
1230 #if defined(DEBUG_ILC_ICONRENDERING) || defined(DEBUG_ILC_FUNCS)
1231 D(bug("[IconList]: %s('%s')\n", __PRETTY_FUNCTION__
, entry
->ie_IconListEntry
.label
));
1233 if (entry
->ie_TxtBuf_DisplayedLabel
)
1235 FreeVecPooled(data
->icld_Pool
, entry
->ie_TxtBuf_DisplayedLabel
);
1236 entry
->ie_TxtBuf_DisplayedLabel
= NULL
;
1237 entry
->ie_SplitParts
= 0;
1240 if (data
->icld__Option_LabelTextMultiLine
> 1)
1242 #if defined(DEBUG_ILC_ICONRENDERING)
1243 D(bug("[IconList]: %s: Attempting to split label ..\n", __PRETTY_FUNCTION__
));
1245 IconList__LabelFunc_SplitLabel(obj
, data
, entry
);
1248 if (entry
->ie_TxtBuf_DisplayedLabel
== NULL
)
1250 ULONG ie_LabelLength
= strlen(entry
->ie_IconListEntry
.label
);
1251 entry
->ie_SplitParts
= 1;
1253 #if defined(DEBUG_ILC_ICONRENDERING)
1254 D(bug("[IconList]: %s: Building unsplit label (len = %d) ..\n", __PRETTY_FUNCTION__
, ie_LabelLength
));
1257 if ((data
->icld__Option_TrimVolumeNames
) &&
1258 ((entry
->ie_IconListEntry
.type
== ST_ROOT
) && (entry
->ie_IconListEntry
.label
[ie_LabelLength
- 1] == ':')))
1261 if(ie_LabelLength
> data
->icld__Option_LabelTextMaxLen
)
1263 if (!(entry
->ie_TxtBuf_DisplayedLabel
= AllocVecPooled(data
->icld_Pool
, data
->icld__Option_LabelTextMaxLen
+ 1)))
1267 memset(entry
->ie_TxtBuf_DisplayedLabel
, 0, data
->icld__Option_LabelTextMaxLen
+ 1);
1268 strncpy(entry
->ie_TxtBuf_DisplayedLabel
, entry
->ie_IconListEntry
.label
, data
->icld__Option_LabelTextMaxLen
- 3);
1269 strcat(entry
->ie_TxtBuf_DisplayedLabel
, " ..");
1273 if (!(entry
->ie_TxtBuf_DisplayedLabel
= AllocVecPooled(data
->icld_Pool
, ie_LabelLength
+ 1)))
1277 memset(entry
->ie_TxtBuf_DisplayedLabel
, 0, ie_LabelLength
+ 1);
1278 strncpy(entry
->ie_TxtBuf_DisplayedLabel
, entry
->ie_IconListEntry
.label
, ie_LabelLength
);
1280 entry
->ie_TxtBuf_DisplayedLabelWidth
= TextLength(data
->icld_BufferRastPort
, entry
->ie_TxtBuf_DisplayedLabel
, strlen(entry
->ie_TxtBuf_DisplayedLabel
));
1281 // if ((data->icld_IconLabelFont->tf_YSize) > data->icld_LabelLargestHeight) data->icld_LabelLargestHeight = data->icld_IconLabelFont->tf_YSize;
1284 // if (entry->ie_TxtBuf_DisplayedLabelWidth > data->icld_LabelLargestWidth) data->icld_LabelLargestWidth = entry->ie_TxtBuf_DisplayedLabelWidth;
1286 return (IPTR
)entry
->ie_TxtBuf_DisplayedLabel
;
1290 ///IconList__HookFunc_UpdateLabelsFunc()
1292 void, IconList__HookFunc_UpdateLabelsFunc
,
1293 AROS_UFHA(struct Hook
*, hook
, A0
),
1294 AROS_UFHA(APTR
*, obj
, A2
),
1295 AROS_UFHA(APTR
, param
, A1
)
1300 /* Get our private data */
1301 Class
*CLASS
= *( Class
**)param
;
1302 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
1304 #if defined(DEBUG_ILC_LASSO) || defined(DEBUG_ILC_FUNCS)
1305 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
1308 if (((data
->icld__Option_LabelTextMaxLen
!= data
->icld__Option_LastLabelTextMaxLen
) &&
1309 (data
->icld__Option_LabelTextMultiLine
> 1)) ||
1310 (data
->icld__Option_LabelTextMultiLine
!= data
->icld__Option_LastLabelTextMultiLine
));
1312 struct IconEntry
*iconentry_Current
= NULL
;
1313 #if defined(__AROS__)
1314 ForeachNode(&data
->icld_IconList
, iconentry_Current
)
1316 Foreach_Node(&data
->icld_IconList
, iconentry_Current
);
1319 IconList__LabelFunc_CreateLabel((Object
*)obj
, data
, iconentry_Current
);
1323 data
->icld__Option_LastLabelTextMaxLen
= data
->icld__Option_LabelTextMaxLen
;
1324 data
->icld__Option_LastLabelTextMultiLine
= data
->icld__Option_LabelTextMultiLine
;
1330 ///IconList__MUIM_IconList_DrawEntryLabel()
1331 IPTR
IconList__MUIM_IconList_DrawEntryLabel(struct IClass
*CLASS
, Object
*obj
, struct MUIP_IconList_DrawEntry
*message
)
1333 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
1336 BOOL outside
= FALSE
;
1338 struct Rectangle iconlabelrect
;
1339 struct Rectangle objrect
;
1341 ULONG txtbox_width
= 0;
1342 LONG tx
,ty
,offsetx
,offsety
;
1343 LONG txwidth
; // txheight;
1345 ULONG objX
, objY
, objW
, objH
;
1346 LONG labelX
, labelY
;
1348 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
1351 if (data
->icld_BufferRastPort
== data
->icld_DisplayRastPort
)
1360 objW
= _mright(obj
) - _mleft(obj
) + 1;
1361 objH
= _mbottom(obj
) - _mtop(obj
) + 1;
1363 ULONG txtarea_width
;
1364 ULONG curlabel_TotalLines
, curlabel_CurrentLine
, offset_y
;
1366 #if defined(DEBUG_ILC_ICONRENDERING) || defined(DEBUG_ILC_FUNCS)
1367 D(bug("[IconList]: %s(message->entry = 0x%p), '%s'\n", __PRETTY_FUNCTION__
, message
->entry
, message
->entry
->ie_IconListEntry
.label
));
1370 if ((!(message
->entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)) ||
1371 (data
->icld_BufferRastPort
== NULL
) ||
1372 (!(message
->entry
->ie_DiskObj
)))
1374 #if defined(DEBUG_ILC_ICONRENDERING)
1375 D(bug("[IconList] %s: Not visible or missing DOB\n", __PRETTY_FUNCTION__
));
1380 /* Get the dimensions and affected area of message->entry's label */
1381 IconList_GetIconLabelRectangle(obj
, data
, message
->entry
, &iconlabelrect
);
1383 /* Add the relative position offset of the message->entry's label */
1384 offsetx
= (objX
- data
->icld_ViewX
) + message
->entry
->ie_IconX
;
1385 txtbox_width
= (iconlabelrect
.MaxX
- iconlabelrect
.MinX
) + 1;
1387 if (txtbox_width
< message
->entry
->ie_AreaWidth
)
1388 offsetx
+= ((message
->entry
->ie_AreaWidth
- txtbox_width
)/2);
1390 if ((data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
) &&
1391 (message
->entry
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
))
1392 offsetx
+= ((data
->icld_IconAreaLargestWidth
- message
->entry
->ie_AreaWidth
)/2);
1394 iconlabelrect
.MinX
+= offsetx
;
1395 iconlabelrect
.MaxX
+= offsetx
;
1397 offsety
= (objY
- data
->icld_ViewY
) + message
->entry
->ie_IconY
+ data
->icld__Option_IconImageSpacing
;
1398 if ((data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
) &&
1399 (message
->entry
->ie_AreaHeight
< data
->icld_IconAreaLargestHeight
))
1400 offsety
+= ((data
->icld_IconAreaLargestHeight
- message
->entry
->ie_AreaHeight
)/2);
1402 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
1404 offsety
= offsety
+ data
->icld_IconLargestHeight
;
1408 offsety
= offsety
+ message
->entry
->ie_IconHeight
;
1410 iconlabelrect
.MinY
+= offsety
;
1411 iconlabelrect
.MaxY
+= offsety
;
1413 /* Add the relative position of the window */
1414 objrect
.MinX
= objX
;
1415 objrect
.MinY
= objX
;
1416 objrect
.MaxX
= objX
+ objW
;
1417 objrect
.MaxY
= objY
+ objH
;
1419 if (!RectAndRect(&iconlabelrect
, &objrect
))
1421 #if defined(DEBUG_ILC_ICONRENDERING)
1422 (bug("[IconList] %s: Entry '%s' label outside of visible area .. skipping\n", __PRETTY_FUNCTION__
, message
->entry
->ie_IconListEntry
.label
));
1427 /* data->update_rect1 and data->update_rect2 may
1428 point to rectangles to indicate that only icons
1429 in any of this rectangles need to be drawn */
1430 if (data
->update_rect1
)
1432 if (!RectAndRect(&iconlabelrect
, data
->update_rect1
))
1436 if (data
->update_rect2
)
1438 if (data
->update_rect1
)
1440 if ((outside
== TRUE
) && RectAndRect(&iconlabelrect
, data
->update_rect2
))
1445 if (!RectAndRect(&iconlabelrect
, data
->update_rect2
))
1450 if (outside
== TRUE
)
1452 #if defined(DEBUG_ILC_ICONRENDERING)
1453 D(bug("[IconList] %s: Entry '%s' label outside of update area .. skipping\n", __PRETTY_FUNCTION__
, message
->entry
->ie_IconListEntry
.label
));
1458 if (message
->drawmode
== ICONENTRY_DRAWMODE_NONE
)
1461 SetABPenDrMd(data
->icld_BufferRastPort
, _pens(obj
)[MPEN_TEXT
], 0, JAM1
);
1463 iconlabelrect
.MinX
= (iconlabelrect
.MinX
- objX
) + data
->icld_DrawOffsetX
;
1464 iconlabelrect
.MinY
= (iconlabelrect
.MinY
- objY
) + data
->icld_DrawOffsetY
;
1465 iconlabelrect
.MaxX
= (iconlabelrect
.MaxX
- objX
) + data
->icld_DrawOffsetX
;
1466 iconlabelrect
.MaxY
= (iconlabelrect
.MaxY
- objY
) + data
->icld_DrawOffsetY
;
1468 labelX
= iconlabelrect
.MinX
+ data
->icld__Option_LabelTextBorderWidth
+ data
->icld__Option_LabelTextHorizontalPadding
;
1469 labelY
= iconlabelrect
.MinY
+ data
->icld__Option_LabelTextBorderHeight
+ data
->icld__Option_LabelTextVerticalPadding
;
1471 txtarea_width
= txtbox_width
- ((data
->icld__Option_LabelTextBorderWidth
+ data
->icld__Option_LabelTextHorizontalPadding
) * 2);
1473 #if defined(DEBUG_ILC_ICONRENDERING)
1474 D(bug("[IconList] %s: Drawing Label '%s' .. %d, %d\n", __PRETTY_FUNCTION__
, message
->entry
->ie_IconListEntry
.label
, labelX
, labelY
));
1476 if (message
->entry
->ie_IconListEntry
.label
&& message
->entry
->ie_TxtBuf_DisplayedLabel
)
1478 char *curlabel_StrPtr
;
1480 if ((message
->entry
->ie_Flags
& ICONENTRY_FLAG_FOCUS
))
1482 //Draw the focus box around the selected label ..
1483 if (data
->icld__Option_LabelTextBorderHeight
> 0)
1485 InvertPixelArray(data
->icld_BufferRastPort
,
1486 iconlabelrect
.MinX
, iconlabelrect
.MinY
,
1487 (iconlabelrect
.MaxX
- iconlabelrect
.MinX
) + 1, data
->icld__Option_LabelTextBorderHeight
);
1489 InvertPixelArray(data
->icld_BufferRastPort
,
1490 iconlabelrect
.MinX
, iconlabelrect
.MaxY
- (data
->icld__Option_LabelTextBorderHeight
- 1),
1491 (iconlabelrect
.MaxX
- iconlabelrect
.MinX
) + 1, data
->icld__Option_LabelTextBorderHeight
);
1493 if (data
->icld__Option_LabelTextBorderWidth
> 0)
1495 InvertPixelArray(data
->icld_BufferRastPort
,
1496 iconlabelrect
.MinX
, iconlabelrect
.MinY
+ data
->icld__Option_LabelTextBorderHeight
,
1497 data
->icld__Option_LabelTextBorderWidth
, (((iconlabelrect
.MaxY
- iconlabelrect
.MinY
) + 1) - (data
->icld__Option_LabelTextBorderHeight
* 2)));
1499 InvertPixelArray(data
->icld_BufferRastPort
,
1500 iconlabelrect
.MaxX
- (data
->icld__Option_LabelTextBorderWidth
- 1), iconlabelrect
.MinY
+ data
->icld__Option_LabelTextBorderHeight
,
1501 data
->icld__Option_LabelTextBorderWidth
, (((iconlabelrect
.MaxY
- iconlabelrect
.MinY
) + 1) - (data
->icld__Option_LabelTextBorderHeight
* 2)));
1505 SetFont(data
->icld_BufferRastPort
, data
->icld_IconLabelFont
);
1507 curlabel_TotalLines
= message
->entry
->ie_SplitParts
;
1508 curlabel_CurrentLine
= 0;
1510 if (curlabel_TotalLines
== 0)
1511 curlabel_TotalLines
= 1;
1513 if (!(data
->icld__Option_LabelTextMultiLineOnFocus
) || (data
->icld__Option_LabelTextMultiLineOnFocus
&& (message
->entry
->ie_Flags
& ICONENTRY_FLAG_FOCUS
)))
1515 if (curlabel_TotalLines
> data
->icld__Option_LabelTextMultiLine
)
1516 curlabel_TotalLines
= data
->icld__Option_LabelTextMultiLine
;
1519 curlabel_TotalLines
= 1;
1521 curlabel_StrPtr
= message
->entry
->ie_TxtBuf_DisplayedLabel
;
1525 #if defined(DEBUG_ILC_ICONRENDERING)
1526 D(bug("[IconList] %s: Font YSize %d Baseline %d\n", __PRETTY_FUNCTION__
,data
->icld_IconLabelFont
->tf_YSize
, data
->icld_IconLabelFont
->tf_Baseline
));
1528 for (curlabel_CurrentLine
= 0; curlabel_CurrentLine
< curlabel_TotalLines
; curlabel_CurrentLine
++)
1530 ULONG ie_LabelLength
;
1532 if (curlabel_CurrentLine
> 0) curlabel_StrPtr
= curlabel_StrPtr
+ strlen(curlabel_StrPtr
) + 1;
1533 if ((curlabel_CurrentLine
>= (curlabel_TotalLines
-1)) && (curlabel_TotalLines
< message
->entry
->ie_SplitParts
))
1535 char *tmpLine
= curlabel_StrPtr
;
1536 ULONG tmpLen
= strlen(tmpLine
);
1538 if ((curlabel_StrPtr
= AllocVecPooled(data
->icld_Pool
, tmpLen
+ 1)) != NULL
)
1540 memset(curlabel_StrPtr
, 0, tmpLen
+ 1);
1541 strncpy(curlabel_StrPtr
, tmpLine
, tmpLen
- 3);
1542 strcat(curlabel_StrPtr
, " ..");
1549 ie_LabelLength
= strlen(curlabel_StrPtr
);
1552 // Center message->entry's label
1553 tx
= (labelX
+ (message
->entry
->ie_TxtBuf_DisplayedLabelWidth
/ 2) - (TextLength(data
->icld_BufferRastPort
, curlabel_StrPtr
, strlen(curlabel_StrPtr
)) / 2));
1555 if (message
->entry
->ie_TxtBuf_DisplayedLabelWidth
< txtarea_width
)
1556 tx
+= ((txtarea_width
- message
->entry
->ie_TxtBuf_DisplayedLabelWidth
)/2);
1558 ty
= ty
+ data
->icld_IconLabelFont
->tf_YSize
;
1560 switch ( data
->icld__Option_LabelTextMode
)
1562 case ICON_TEXTMODE_DROPSHADOW
:
1563 SetAPen(data
->icld_BufferRastPort
, data
->icld_LabelShadowPen
);
1564 Move(data
->icld_BufferRastPort
, tx
+ 1, ty
+ 1);
1565 Text(data
->icld_BufferRastPort
, curlabel_StrPtr
, ie_LabelLength
);
1567 case ICON_TEXTMODE_PLAIN
:
1568 SetAPen(data
->icld_BufferRastPort
, data
->icld_LabelPen
);
1569 Move(data
->icld_BufferRastPort
, tx
, ty
);
1570 Text(data
->icld_BufferRastPort
, curlabel_StrPtr
, ie_LabelLength
);
1575 SetSoftStyle(data
->icld_BufferRastPort
, FSF_BOLD
, AskSoftStyle(data
->icld_BufferRastPort
));
1577 SetAPen(data
->icld_BufferRastPort
, data
->icld_LabelShadowPen
);
1578 Move(data
->icld_BufferRastPort
, tx
+ 1, ty
);
1579 Text(data
->icld_BufferRastPort
, curlabel_StrPtr
, ie_LabelLength
);
1580 Move(data
->icld_BufferRastPort
, tx
- 1, ty
);
1581 Text(data
->icld_BufferRastPort
, curlabel_StrPtr
, ie_LabelLength
);
1582 Move(data
->icld_BufferRastPort
, tx
, ty
+ 1);
1583 Text(data
->icld_BufferRastPort
, curlabel_StrPtr
, ie_LabelLength
);
1584 Move(data
->icld_BufferRastPort
, tx
, ty
- 1);
1585 Text(data
->icld_BufferRastPort
, curlabel_StrPtr
, ie_LabelLength
);
1587 SetAPen(data
->icld_BufferRastPort
, data
->icld_LabelPen
);
1588 Move(data
->icld_BufferRastPort
, tx
, ty
);
1589 Text(data
->icld_BufferRastPort
, curlabel_StrPtr
, ie_LabelLength
);
1591 SetSoftStyle(data
->icld_BufferRastPort
, FS_NORMAL
, AskSoftStyle(data
->icld_BufferRastPort
));
1595 if ((curlabel_CurrentLine
>= (curlabel_TotalLines
-1)) && (curlabel_TotalLines
< message
->entry
->ie_SplitParts
))
1597 FreeVecPooled(data
->icld_Pool
, curlabel_StrPtr
);
1602 /*date/size sorting has the date/size appended under the message->entry label*/
1604 if ((message
->entry
->ie_IconListEntry
.type
!= ST_USERDIR
) && ((data
->icld_SortFlags
& (MUIV_IconList_Sort_BySize
|MUIV_IconList_Sort_ByDate
)) != 0))
1607 SetFont(data
->icld_BufferRastPort
, data
->icld_IconInfoFont
);
1609 if (data
->icld_SortFlags
& MUIV_IconList_Sort_BySize
)
1611 buf
= message
->entry
->ie_TxtBuf_SIZE
;
1612 txwidth
= message
->entry
->ie_TxtBuf_SIZEWidth
;
1614 else if (data
->icld_SortFlags
& MUIV_IconList_Sort_ByDate
)
1616 if (message
->entry
->ie_Flags
& ICONENTRY_FLAG_TODAY
)
1618 buf
= message
->entry
->ie_TxtBuf_TIME
;
1619 txwidth
= message
->entry
->ie_TxtBuf_TIMEWidth
;
1623 buf
= message
->entry
->ie_TxtBuf_DATE
;
1624 txwidth
= message
->entry
->ie_TxtBuf_DATEWidth
;
1630 ULONG ie_LabelLength
= strlen(buf
);
1633 if (txwidth
< txtarea_width
)
1634 tx
+= ((txtarea_width
- txwidth
)/2);
1636 ty
= labelY
+ ((data
->icld__Option_LabelTextVerticalPadding
+ data
->icld_IconLabelFont
->tf_YSize
) * curlabel_TotalLines
) + data
->icld_IconInfoFont
->tf_YSize
;
1638 switch ( data
->icld__Option_LabelTextMode
)
1640 case ICON_TEXTMODE_DROPSHADOW
:
1641 SetAPen(data
->icld_BufferRastPort
, data
->icld_InfoShadowPen
);
1642 Move(data
->icld_BufferRastPort
, tx
+ 1, ty
+ 1); Text(data
->icld_BufferRastPort
, buf
, ie_LabelLength
);
1643 case ICON_TEXTMODE_PLAIN
:
1644 SetAPen(data
->icld_BufferRastPort
, data
->icld_InfoPen
);
1645 Move(data
->icld_BufferRastPort
, tx
, ty
); Text(data
->icld_BufferRastPort
, buf
, ie_LabelLength
);
1650 SetSoftStyle(data
->icld_BufferRastPort
, FSF_BOLD
, AskSoftStyle(data
->icld_BufferRastPort
));
1651 SetAPen(data
->icld_BufferRastPort
, data
->icld_InfoShadowPen
);
1653 Move(data
->icld_BufferRastPort
, tx
+ 1, ty
);
1654 Text(data
->icld_BufferRastPort
, buf
, ie_LabelLength
);
1655 Move(data
->icld_BufferRastPort
, tx
- 1, ty
);
1656 Text(data
->icld_BufferRastPort
, buf
, ie_LabelLength
);
1657 Move(data
->icld_BufferRastPort
, tx
, ty
- 1 );
1658 Text(data
->icld_BufferRastPort
, buf
, ie_LabelLength
);
1659 Move(data
->icld_BufferRastPort
, tx
, ty
+ 1 );
1660 Text(data
->icld_BufferRastPort
, buf
, ie_LabelLength
);
1662 SetAPen(data
->icld_BufferRastPort
, data
->icld_InfoPen
);
1664 Move(data
->icld_BufferRastPort
, tx
, ty
);
1665 Text(data
->icld_BufferRastPort
, buf
, ie_LabelLength
);
1667 SetSoftStyle(data
->icld_BufferRastPort
, FS_NORMAL
, AskSoftStyle(data
->icld_BufferRastPort
));
1677 /**************************************************************************
1679 **************************************************************************/
1680 ///IconList__MUIM_IconList_RethinkDimensions()
1681 IPTR
IconList__MUIM_IconList_RethinkDimensions(struct IClass
*CLASS
, Object
*obj
, struct MUIP_IconList_RethinkDimensions
*message
)
1683 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
1685 struct IconEntry
*entry
= NULL
;
1688 struct Rectangle icon_rect
;
1690 #if defined(DEBUG_ILC_ICONPOSITIONING) || defined(DEBUG_ILC_FUNCS)
1691 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
1694 if (message
->singleicon
!= NULL
)
1696 entry
= message
->singleicon
;
1697 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
1699 maxy
= data
->icld_LVMAttribs
->lmva_RowHeight
;
1700 if ((data
->icld_LVMAttribs
->lvma_Flags
& LVMAF_NOHEADER
) == 0)
1702 maxy
+= data
->icld_LVMAttribs
->lmva_HeaderHeight
;
1707 maxx
= data
->icld_AreaWidth
- 1,
1708 maxy
= data
->icld_AreaHeight
- 1;
1711 #if defined(DEBUG_ILC_ICONPOSITIONING)
1712 D(bug("[IconList] %s: SingleIcon - maxx = %d, maxy = %d\n", __PRETTY_FUNCTION__
, maxx
, maxy
));
1717 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
1719 maxy
= data
->icld_LVMAttribs
->lmva_RowHeight
;
1720 if ((data
->icld_LVMAttribs
->lvma_Flags
& LVMAF_NOHEADER
) == 0)
1722 maxy
+= data
->icld_LVMAttribs
->lmva_HeaderHeight
;
1725 entry
= (struct IconEntry
*)GetHead(&data
->icld_IconList
);
1728 while (entry
!= NULL
)
1730 if (entry
->ie_DiskObj
&&
1731 (entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
))
1733 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
1735 maxy
+= data
->icld_LVMAttribs
->lmva_RowHeight
;
1739 IconList_GetIconAreaRectangle(obj
, data
, entry
, &icon_rect
);
1741 icon_rect
.MaxX
+= entry
->ie_IconX
+ data
->icld__Option_IconHorizontalSpacing
;
1742 if ((data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
) &&
1743 (entry
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
))
1744 icon_rect
.MaxX
+= (data
->icld_IconAreaLargestWidth
- entry
->ie_AreaWidth
);
1746 icon_rect
.MaxY
+= entry
->ie_IconY
+ data
->icld__Option_IconVerticalSpacing
;
1748 if (icon_rect
.MaxX
> maxx
) maxx
= icon_rect
.MaxX
;
1749 if (icon_rect
.MaxY
> maxy
) maxy
= icon_rect
.MaxY
;
1753 if (message
->singleicon
)
1756 entry
= (struct IconEntry
*)GetSucc(&entry
->ie_IconNode
);
1759 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
1763 for(col
= 0; col
< NUM_COLUMNS
; col
++)
1765 LONG index
= data
->icld_LVMAttribs
->lmva_ColumnPos
[col
];
1767 if (!(data
->icld_LVMAttribs
->lmva_ColumnFlags
[index
] & LVMCF_COLVISIBLE
)) continue;
1769 maxx
+= data
->icld_LVMAttribs
->lmva_ColumnWidth
[index
];
1773 /* update our view when max x/y have changed */
1774 if (maxx
+ 1 != data
->icld_AreaWidth
)
1776 data
->icld_AreaWidth
= maxx
+ 1;
1777 SET(obj
, MUIA_IconList_Width
, data
->icld_AreaWidth
);
1779 if (maxy
+ 1 != data
->icld_AreaHeight
)
1781 data
->icld_AreaHeight
= maxy
+ 1;
1782 SET(obj
, MUIA_IconList_Height
, data
->icld_AreaHeight
);
1789 * This function executes the layouting when AutoSort is enabled. This means all icons are layouted regardless if
1790 * they have Provided position or not.
1793 static VOID
IconList_Layout_FullAutoLayout(struct IClass
*CLASS
, Object
*obj
)
1795 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
1796 struct IconEntry
*entry
= NULL
;
1797 struct IconEntry
*pass_first
= NULL
; /* First entry of current column or row */
1799 LONG left
= data
->icld__Option_IconHorizontalSpacing
;
1800 LONG top
= data
->icld__Option_IconVerticalSpacing
;
1805 LONG maxw
= 0; /* Widest & talest entry in a column or row */
1809 struct Rectangle iconrect
;
1811 /* Now go to the actual positioning */
1812 entry
= (struct IconEntry
*)GetHead(&data
->icld_IconList
);
1813 while (entry
!= NULL
)
1815 calcnextpos
= FALSE
;
1816 if ((entry
->ie_DiskObj
!= NULL
) && (entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
))
1820 /* Set previously calculated position to this icon */
1821 entry
->ie_IconX
= cur_x
;
1822 entry
->ie_IconY
= cur_y
;
1824 if (entry
->ie_Flags
& ICONENTRY_FLAG_SELECTED
)
1826 if (data
->icld_SelectionLastClicked
== NULL
) data
->icld_SelectionLastClicked
= entry
;
1827 if (data
->icld_FocusIcon
== NULL
) data
->icld_FocusIcon
= entry
;
1830 /* Calculate grid size to advanced the coordinate in next step */
1831 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
1833 maxw
= data
->icld_IconAreaLargestWidth
+ data
->icld__Option_IconHorizontalSpacing
;
1834 maxh
= data
->icld_IconLargestHeight
+ data
->icld__Option_IconImageSpacing
+ data
->icld_LabelLargestHeight
+ data
->icld__Option_IconVerticalSpacing
;
1840 if (!(pass_first
)) pass_first
= entry
;
1842 IconList_GetIconAreaRectangle(obj
, data
, entry
, &iconrect
);
1844 if ((maxw
< entry
->ie_AreaWidth
) || (maxh
< entry
->ie_AreaHeight
))
1846 if (maxw
< entry
->ie_AreaWidth
) maxw
= entry
->ie_AreaWidth
;
1847 if (maxh
< entry
->ie_AreaHeight
) maxh
= entry
->ie_AreaHeight
;
1848 if (pass_first
!= entry
)
1851 cur_x
= entry
->ie_IconX
;
1852 cur_y
= entry
->ie_IconY
;
1853 /* We detected that the new icon it taller/wider than icons so far in this row/column.
1854 * We need to re-layout this row/column. */
1859 if (data
->icld_DisplayFlags
& ICONLIST_DISP_VERTICAL
)
1862 if (entry
->ie_AreaWidth
< maxw
)
1863 entry
->ie_IconX
+= ( maxw
- entry
->ie_AreaWidth
) / 2;
1866 gridy
= entry
->ie_AreaHeight
+ data
->icld__Option_IconVerticalSpacing
;
1870 /* Centering */ /* Icons look better not centered in this case - disabled */
1871 /* if (entry->ie_AreaHeight < maxh)
1872 entry->ie_IconY += ( maxh - entry->ie_AreaHeight ) / 2; */
1874 gridx
= entry
->ie_AreaWidth
+ data
->icld__Option_IconHorizontalSpacing
;
1881 * Advance to next icon and calculate its position based on grid sizes from previous step.
1882 * Don't set position - it is done at beginning of the loop.
1884 if ((entry
= (struct IconEntry
*)GetSucc(&entry
->ie_IconNode
)) != NULL
)
1888 if (data
->icld_DisplayFlags
& ICONLIST_DISP_VERTICAL
)
1892 if ((cur_y
>= data
->icld_ViewHeight
) ||
1893 ((data
->icld__Option_IconListMode
== ICON_LISTMODE_ROUGH
) && ((cur_y
+ entry
->ie_AreaHeight
- data
->icld__Option_IconBorderOverlap
) >= data
->icld_ViewHeight
)) ||
1894 ((data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
) && ((cur_y
+ data
->icld_IconAreaLargestHeight
- data
->icld__Option_IconBorderOverlap
) >= data
->icld_ViewHeight
)))
1896 /* Wrap "around" if the icon would be below bottom border */
1907 if ((cur_x
>= data
->icld_ViewWidth
) ||
1908 ((data
->icld__Option_IconListMode
== ICON_LISTMODE_ROUGH
) && ((cur_x
+ entry
->ie_AreaWidth
- data
->icld__Option_IconBorderOverlap
) >= data
->icld_ViewWidth
)) ||
1909 ((data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
) && ((cur_x
+ data
->icld_IconAreaLargestWidth
- data
->icld__Option_IconBorderOverlap
) >= data
->icld_ViewWidth
)))
1911 /* Wrap "around" if the icon would be right of right border */
1923 static VOID
IconList_Layout_PartialAutoLayout(struct IClass
*CLASS
, Object
*obj
)
1925 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
1926 struct Region
*occupied
= NewRegion();
1927 struct IconEntry
*entry
= NULL
;
1928 LONG left
= data
->icld__Option_IconHorizontalSpacing
;
1929 LONG top
= data
->icld__Option_IconVerticalSpacing
;
1930 LONG cur_x
= left
, cur_y
= top
;
1932 entry
= (struct IconEntry
*)GetHead(&data
->icld_IconList
);
1933 while (entry
!= NULL
)
1935 if ((entry
->ie_ProvidedIconX
!= NO_ICON_POSITION
) && (entry
->ie_ProvidedIconY
!= NO_ICON_POSITION
)
1936 && (entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
))
1938 struct Rectangle iconrect
= {
1939 entry
->ie_ProvidedIconX
,
1940 entry
->ie_ProvidedIconY
,
1941 entry
->ie_ProvidedIconX
+ entry
->ie_AreaWidth
- 1,
1942 entry
->ie_ProvidedIconY
+ entry
->ie_AreaHeight
- 1
1945 if (data
->icld_DisplayFlags
& ICONLIST_DISP_VERTICAL
)
1946 iconrect
.MaxY
+= data
->icld__Option_IconVerticalSpacing
;
1948 iconrect
.MaxX
+= data
->icld__Option_IconHorizontalSpacing
;
1950 D(bug("Adding %s (%d %d)(%d %d)\n", entry
->ie_TxtBuf_DisplayedLabel
,
1951 (LONG
)iconrect
.MinX
, (LONG
)iconrect
.MinY
, (LONG
)iconrect
.MaxX
, (LONG
)iconrect
.MaxY
));
1953 OrRectRegion(occupied
, &iconrect
);
1955 entry
= (struct IconEntry
*)GetSucc(&entry
->ie_IconNode
);
1958 /* Now go to the actual positioning */
1959 entry
= (struct IconEntry
*)GetHead(&data
->icld_IconList
);
1960 while (entry
!= NULL
)
1962 if ((entry
->ie_DiskObj
!= NULL
) && (entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
))
1964 if ((entry
->ie_ProvidedIconX
!= NO_ICON_POSITION
) && (entry
->ie_ProvidedIconY
!= NO_ICON_POSITION
))
1966 entry
->ie_IconX
= entry
->ie_ProvidedIconX
;
1967 entry
->ie_IconY
= entry
->ie_ProvidedIconY
;
1971 LONG gridx
, gridy
, stepx
= 0, stepy
= 0, addx
= 0;
1972 struct Rectangle iconarea
;
1975 /* Calculate grid size and step */
1976 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
1978 gridx
= data
->icld_IconAreaLargestWidth
+ data
->icld__Option_IconHorizontalSpacing
;
1979 gridy
= data
->icld_IconLargestHeight
+ data
->icld__Option_IconImageSpacing
+ data
->icld_LabelLargestHeight
+ data
->icld__Option_IconVerticalSpacing
;
1983 if (data
->icld_DisplayFlags
& ICONLIST_DISP_VERTICAL
)
1985 gridx
= data
->icld_IconAreaLargestWidth
; /* This gives better centering effect */
1986 gridy
= entry
->ie_AreaHeight
+ data
->icld__Option_IconVerticalSpacing
;
1987 addx
= (gridx
- entry
->ie_AreaWidth
) / 2;
1991 gridx
= entry
->ie_AreaWidth
+ data
->icld__Option_IconHorizontalSpacing
;
1992 gridy
= entry
->ie_AreaHeight
+ data
->icld__Option_IconVerticalSpacing
;
1996 /* Find first not occupied spot matching the calculate rectangle */
1999 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
2001 /* Overwrite value set via RegionAndRect */
2006 if (data
->icld_DisplayFlags
& ICONLIST_DISP_VERTICAL
)
2008 /* Advance to next position */
2009 if (!first
) cur_y
+= stepy
;
2011 if ((cur_y
>= data
->icld_ViewHeight
) ||
2012 ((cur_y
+ gridy
- data
->icld__Option_IconBorderOverlap
) >= data
->icld_ViewHeight
))
2014 /* Wrap "around" if the icon would be below bottom border */
2021 /* Advance to next position */
2022 if (!first
) cur_x
+= stepx
;
2024 if ((cur_x
>= data
->icld_ViewWidth
) ||
2025 ((cur_x
+ gridx
- data
->icld__Option_IconBorderOverlap
) >= data
->icld_ViewWidth
))
2027 /* Wrap "around" if the icon would be right of right border */
2033 iconarea
.MinX
= cur_x
;
2034 iconarea
.MinY
= cur_y
;
2035 iconarea
.MaxX
= cur_x
+ gridx
- 1;
2036 iconarea
.MaxY
= cur_y
+ gridy
- 1;
2040 } while(RegionAndRect(occupied
, &iconarea
, &stepx
, &stepy
));
2042 entry
->ie_IconX
= iconarea
.MinX
+ addx
;
2043 entry
->ie_IconY
= iconarea
.MinY
;
2045 /* Add this area to occupied list */
2046 OrRectRegion(occupied
, &iconarea
);
2048 /* Add spacing to next icon */
2049 if (data
->icld_DisplayFlags
& ICONLIST_DISP_VERTICAL
)
2056 entry
= (struct IconEntry
*)GetSucc(&entry
->ie_IconNode
);
2059 DisposeRegion(occupied
);
2063 ///IconList__MUIM_IconList_PositionIcons()
2064 /**************************************************************************
2065 MUIM_PositionIcons - Place icons with NO_ICON_POSITION coords somewhere
2066 **************************************************************************/
2067 IPTR
IconList__MUIM_IconList_PositionIcons(struct IClass
*CLASS
, Object
*obj
, struct MUIP_IconList_PositionIcons
*message
)
2069 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
2070 struct IconEntry
*entry
= NULL
;
2073 #if defined(DEBUG_ILC_ICONPOSITIONING) || defined(DEBUG_ILC_FUNCS)
2074 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
2076 if ((data
->icld_SortFlags
& MUIV_IconList_Sort_AutoSort
) == 0)
2078 IconList_Layout_PartialAutoLayout(CLASS
, obj
);
2082 IconList_Layout_FullAutoLayout(CLASS
, obj
);
2086 * Set Provided icon position on all icons (this can't be done as part of previous loop!)
2087 * The icons will not no longer be autolayouted unless MUIV_IconList_Sort_AutoSort is set.
2088 * This give the stability that new icons appearing won't make existing icons jump from their places
2090 entry
= (struct IconEntry
*)GetHead(&data
->icld_IconList
);
2091 while (entry
!= NULL
)
2093 if (entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
2094 DoMethod(obj
, MUIM_IconList_PropagateEntryPos
, entry
);
2096 entry
= (struct IconEntry
*)GetSucc(&entry
->ie_IconNode
);
2100 DoMethod(obj
, MUIM_IconList_RethinkDimensions
, NULL
);
2107 #define ICONENTRY_SIZE 16
2109 static inline void CalcHeight(struct ListViewModeAttribs
*LVMAttribs
, struct TextFont
*LabelFont
)
2111 ULONG YSize
= LabelFont
? LabelFont
->tf_YSize
: 0;
2113 LVMAttribs
->lmva_HeaderHeight
= HEADERLINE_EXTRAHEIGHT
+ YSize
;
2114 LVMAttribs
->lmva_RowHeight
= LINE_EXTRAHEIGHT
+ ((ICONENTRY_SIZE
> YSize
) ? ICONENTRY_SIZE
: YSize
);
2117 /**************************************************************************
2119 **************************************************************************/
2120 IPTR
IconList__OM_NEW(struct IClass
*CLASS
, Object
*obj
, struct opSet
*message
)
2122 struct IconList_DATA
*data
= NULL
;
2123 struct TextFont
*icl_WindowFont
= NULL
;
2124 // struct RastPort *icl_RastPort = NULL;
2127 #if defined(DEBUG_ILC_FUNCS)
2128 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
2131 icl_WindowFont
= (struct TextFont
*) GetTagData(MUIA_Font
, (IPTR
) NULL
, message
->ops_AttrList
);
2133 obj
= (Object
*)DoSuperNewTags(CLASS
, obj
, NULL
,
2134 MUIA_FillArea
, FALSE
,
2135 MUIA_Dropable
, TRUE
,
2136 MUIA_Font
, MUIV_Font_Tiny
,
2137 TAG_MORE
, (IPTR
) message
->ops_AttrList
);
2139 if (!obj
) return FALSE
;
2141 data
= INST_DATA(CLASS
, obj
);
2143 data
->icld_Pool
= CreatePool(0,4096,4096);
2144 if (!data
->icld_Pool
)
2146 CoerceMethod(CLASS
,obj
,OM_DISPOSE
);
2150 #if defined(DEBUG_ILC_FUNCS)
2151 D(bug("[IconList] %s: SELF = 0x%p, muiRenderInfo = 0x%p\n", __PRETTY_FUNCTION__
, obj
, muiRenderInfo(obj
)));
2153 NewList((struct List
*)&data
->icld_IconList
);
2154 NewList((struct List
*)&data
->icld_SelectionList
);
2156 data
->icld_IconLabelFont
= icl_WindowFont
;
2158 /* Setup List View-Mode options */
2159 if ((data
->icld_LVMAttribs
= AllocMem(sizeof(struct ListViewModeAttribs
), MEMF_CLEAR
)) != NULL
)
2161 for(i
= 0; i
< NUM_COLUMNS
; i
++)
2163 data
->icld_LVMAttribs
->lmva_ColumnPos
[i
] = i
;
2164 data
->icld_LVMAttribs
->lmva_ColumnFlags
[i
] = LVMCF_COLVISIBLE
;
2165 data
->icld_LVMAttribs
->lmva_ColumnWidth
[i
] = 100;
2166 data
->icld_LVMAttribs
->lmva_ColumnHAlign
[i
] = COLUMN_ALIGN_LEFT
;
2170 data
->icld_LVMAttribs
->lmva_ColumnHAlign
[i
] = COLUMN_ALIGN_RIGHT
;
2171 data
->icld_LVMAttribs
->lmva_ColumnFlags
[i
] |= (LVMCF_COLCLICKABLE
|LVMCF_COLSORTABLE
);
2172 data
->icld_LVMAttribs
->lmva_ColumnTitle
[i
] = "Type";
2173 data
->icld_LVMAttribs
->lmva_ColumnWidth
[i
] = ICONENTRY_SIZE
+ 2;
2177 data
->icld_LVMAttribs
->lmva_ColumnFlags
[i
] |= (LVMCF_COLCLICKABLE
|LVMCF_COLSORTABLE
);
2178 data
->icld_LVMAttribs
->lmva_ColumnTitle
[i
] = "Name";
2182 data
->icld_LVMAttribs
->lmva_ColumnHAlign
[i
] = COLUMN_ALIGN_RIGHT
;
2183 data
->icld_LVMAttribs
->lmva_ColumnFlags
[i
] |= LVMCF_COLSORTABLE
;
2184 data
->icld_LVMAttribs
->lmva_ColumnTitle
[i
] = "Size";
2187 case INDEX_LASTACCESS
:
2188 data
->icld_LVMAttribs
->lmva_ColumnFlags
[i
] |= LVMCF_COLSORTABLE
;
2189 data
->icld_LVMAttribs
->lmva_ColumnTitle
[i
] = "Last Accessed";
2193 data
->icld_LVMAttribs
->lmva_ColumnTitle
[i
] = "Comment";
2196 case INDEX_PROTECTION
:
2197 data
->icld_LVMAttribs
->lmva_ColumnTitle
[i
] = "Protection";
2201 data
->icld_LVMAttribs
->lmva_ColumnTitle
[i
] = "<Unknown>";
2205 data
->icld_LVMAttribs
->lmva_LastSelectedColumn
= -1;
2206 data
->icld_LVMAttribs
->lmva_SortColumn
= INDEX_NAME
;
2207 data
->icld_LVMAttribs
->lvma_Flags
= LVMAF_HEADERDRAWTOEND
;
2209 * Seems to be not needed because it's done in MUIM_Setup. No rendering happens before it.
2210 * Height calculation moved to MUIM_Setup because font pointer can be NULL here (if user-specified
2211 * font failed to open). In this case we fail back to the font specified in MUI's AreaData, but
2212 * it becomes known only in MUIM_Setup
2214 CalcHeight(data->icld_LVMAttribs, data->icld_IconLabelFont); */
2217 /* Get/Set initial values */
2218 /* TODO: TrimVolumeNames should be prefs settable */
2219 data
->icld__Option_TrimVolumeNames
= TRUE
;
2220 /* TODO: Adjust overlap by window border width */
2221 data
->icld__Option_IconBorderOverlap
= 10;
2223 data
->icld__Option_IconListMode
= (UBYTE
)GetTagData(MUIA_IconList_IconListMode
, 0, message
->ops_AttrList
);
2224 data
->icld__Option_LabelTextMode
= (UBYTE
)GetTagData(MUIA_IconList_LabelText_Mode
, 0, message
->ops_AttrList
);
2225 data
->icld__Option_LabelTextMaxLen
= (ULONG
)GetTagData(MUIA_IconList_LabelText_MaxLineLen
, ILC_ICONLABEL_MAXLINELEN_DEFAULT
, message
->ops_AttrList
);
2226 data
->icld__Option_DragImageTransparent
= (BOOL
)GetTagData(MUIA_IconList_DragImageTransparent
, FALSE
, message
->ops_AttrList
);
2228 if ( data
->icld__Option_LabelTextMaxLen
< ILC_ICONLABEL_SHORTEST
)
2229 data
->icld__Option_LabelTextMaxLen
= ILC_ICONLABEL_MAXLINELEN_DEFAULT
;
2231 data
->icld__Option_LastLabelTextMaxLen
= data
->icld__Option_LabelTextMaxLen
;
2233 #if defined(DEBUG_ILC_FUNCS)
2234 D(bug("[IconList] %s: MaxLineLen : %ld\n", __PRETTY_FUNCTION__
, data
->icld__Option_LabelTextMaxLen
));
2236 data
->ehn
.ehn_Events
= IDCMP_MOUSEBUTTONS
| IDCMP_RAWKEY
| IDCMP_NEWSIZE
;
2237 data
->ehn
.ehn_Priority
= 0;
2238 data
->ehn
.ehn_Flags
= 0;
2239 data
->ehn
.ehn_Object
= obj
;
2240 data
->ehn
.ehn_Class
= CLASS
;
2242 data
->icld_SortFlags
= MUIV_IconList_Sort_ByName
;
2243 data
->icld_DisplayFlags
= ICONLIST_DISP_SHOWINFO
;
2245 __iconlist_UpdateLabels_hook
.h_Entry
= (HOOKFUNC
)IconList__HookFunc_UpdateLabelsFunc
;
2249 obj
, MUIM_Notify
, MUIA_IconList_LabelText_MaxLineLen
, MUIV_EveryTime
,
2251 MUIM_CallHook
, &__iconlist_UpdateLabels_hook
, (IPTR
)CLASS
2256 obj
, MUIM_Notify
, MUIA_IconList_LabelText_MultiLine
, MUIV_EveryTime
,
2258 MUIM_CallHook
, &__iconlist_UpdateLabels_hook
, (IPTR
)CLASS
2261 #if defined(DEBUG_ILC_FUNCS)
2262 D(bug("[IconList] obj = %ld\n", obj
));
2269 /**************************************************************************
2271 **************************************************************************/
2272 IPTR
IconList__OM_DISPOSE(struct IClass
*CLASS
, Object
*obj
, Msg message
)
2274 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
2275 struct IconEntry
*node
= NULL
;
2277 #if defined(DEBUG_ILC_FUNCS)
2278 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
2281 #if defined(__AROS__)
2282 ForeachNode(&data
->icld_IconList
, node
)
2284 Foreach_Node(&data
->icld_IconList
, node
);
2287 if (node
->ie_DiskObj
)
2288 FreeDiskObject(node
->ie_DiskObj
);
2291 if (data
->icld_Pool
) DeletePool(data
->icld_Pool
);
2293 DoSuperMethodA(CLASS
,obj
,message
);
2299 /**************************************************************************
2301 **************************************************************************/
2302 IPTR
IconList__OM_SET(struct IClass
*CLASS
, Object
*obj
, struct opSet
*message
)
2304 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
2305 struct TagItem
*tag
= NULL
,
2308 WORD oldleft
= data
->icld_ViewX
,
2309 oldtop
= data
->icld_ViewY
;
2310 //oldwidth = data->icld_ViewWidth,
2311 //oldheight = data->icld_ViewHeight;
2313 #if defined(DEBUG_ILC_FUNCS) || defined(DEBUG_ILC_ATTRIBS)
2314 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
2317 /* parse initial taglist */
2318 for (tags
= message
->ops_AttrList
; (tag
= NextTagItem((TAGITEM
)&tags
)); )
2320 switch (tag
->ti_Tag
)
2322 case MUIA_Virtgroup_Left
:
2323 #if defined(DEBUG_ILC_ATTRIBS)
2324 D(bug("[IconList] %s: MUIA_Virtgroup_Left %ld\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2326 if (data
->icld_ViewX
!= tag
->ti_Data
)
2327 data
->icld_ViewX
= tag
->ti_Data
;
2330 case MUIA_Virtgroup_Top
:
2331 #if defined(DEBUG_ILC_ATTRIBS)
2332 D(bug("[IconList] %s: MUIA_Virtgroup_Top %ld\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2334 if (data
->icld_ViewY
!= tag
->ti_Data
)
2335 data
->icld_ViewY
= tag
->ti_Data
;
2338 case MUIA_IconList_Rastport
:
2339 #if defined(DEBUG_ILC_ATTRIBS)
2340 D(bug("[IconList] %s: MUIA_IconList_Rastport 0x%p\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2342 data
->icld_DisplayRastPort
= (struct RastPort
*)tag
->ti_Data
;
2343 data
->icld_DrawOffsetX
= _mleft(obj
);
2344 data
->icld_DrawOffsetY
= _mtop(obj
);
2345 if (data
->icld_BufferRastPort
!= NULL
)
2347 //Buffer still set!?!?!
2349 SET(obj
, MUIA_IconList_BufferRastport
, tag
->ti_Data
);
2352 case MUIA_IconList_BufferRastport
:
2353 #if defined(DEBUG_ILC_ATTRIBS)
2354 D(bug("[IconList] %s: MUIA_IconList_BufferRastport 0x%p\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2356 data
->icld_BufferRastPort
= (struct RastPort
*)tag
->ti_Data
;
2360 #if defined(DEBUG_ILC_ATTRIBS)
2361 D(bug("[IconList] %s: MUIA_Font 0x%p\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2363 data
->icld_IconLabelFont
= (struct TextFont
*)tag
->ti_Data
;
2364 /* FIXME: Should we call CalcHeight() here because our font changed? */
2367 case MUIA_IconList_LabelInfoText_Font
:
2368 #if defined(DEBUG_ILC_ATTRIBS)
2369 D(bug("[IconList] %s: MUIA_IconList_LabelInfoText_Font 0x%p\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2371 data
->icld_IconInfoFont
= (struct TextFont
*)tag
->ti_Data
;
2374 case MUIA_IconList_DisplayFlags
:
2376 #if defined(DEBUG_ILC_ATTRIBS)
2377 D(bug("[IconList] %s: MUIA_IconList_DisplayFlags %08x\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2379 // ULONG origModeFlags = data->icld_DisplayFlags & (ICONLIST_DISP_MODEDEFAULT|ICONLIST_DISP_MODELABELRIGHT|ICONLIST_DISP_MODELIST);
2380 data
->icld_DisplayFlags
= (ULONG
)tag
->ti_Data
;
2382 if (data
->icld_DisplayFlags
& ICONLIST_DISP_BUFFERED
)
2384 #if defined(DEBUG_ILC_ATTRIBS) || defined(DEBUG_ILC_ICONRENDERING)
2385 D(bug("[IconList] %s: MUIA_IconList_DisplayFlags & ICONLIST_DISP_BUFFERED\n", __PRETTY_FUNCTION__
));
2387 if ((data
->icld_BufferRastPort
!= NULL
)
2388 && (data
->icld_BufferRastPort
!= data
->icld_DisplayRastPort
))
2390 #if defined(DEBUG_ILC_ATTRIBS) || defined(DEBUG_ILC_ICONRENDERING)
2391 D(bug("[IconList] %s: BackLayer @ %p for BackRastport @ %p\n", __PRETTY_FUNCTION__
, data
->icld_BufferRastPort
->Layer
, data
->icld_BufferRastPort
));
2393 if ((GetBitMapAttr(data
->icld_BufferRastPort
->BitMap
, BMA_WIDTH
) != data
->icld_ViewWidth
)
2394 || (GetBitMapAttr(data
->icld_BufferRastPort
->BitMap
, BMA_HEIGHT
) != data
->icld_ViewHeight
))
2396 struct Layer
*oldLayer
= data
->icld_BufferRastPort
->Layer
;
2397 #if defined(DEBUG_ILC_ATTRIBS) || defined(DEBUG_ILC_ICONRENDERING)
2398 D(bug("[IconList] %s: Destroying old BackLayer\n", __PRETTY_FUNCTION__
));
2400 data
->icld_BufferRastPort
= data
->icld_DisplayRastPort
;
2401 DeleteLayer(0, oldLayer
);
2405 if ((data
->icld_BufferRastPort
== NULL
) || (data
->icld_BufferRastPort
== data
->icld_DisplayRastPort
))
2407 struct BitMap
*bitmap_New
= NULL
;
2408 ULONG tmp_RastDepth
;
2409 struct Layer_Info
*li
= NULL
;
2411 tmp_RastDepth
= GetCyberMapAttr(data
->icld_DisplayRastPort
->BitMap
, CYBRMATTR_DEPTH
);
2412 if ((bitmap_New
= AllocBitMap(data
->icld_ViewWidth
,
2413 data
->icld_ViewHeight
,
2416 data
->icld_DisplayRastPort
->BitMap
))!=NULL
)
2418 if ((data
->icld_BufferRastPort
= CreateRastPort())!=NULL
)
2420 data
->icld_BufferRastPort
->BitMap
= bitmap_New
;
2421 if ((li
= NewLayerInfo()))
2423 if ((data
->icld_BufferRastPort
->Layer
= CreateUpfrontLayer(li
, data
->icld_BufferRastPort
->BitMap
, 0, 0, data
->icld_ViewWidth
- 1, data
->icld_ViewHeight
- 1, 0, NULL
)))
2426 * Mark it as a buffered rastport.
2429 #if defined(DEBUG_ILC_ATTRIBS) || defined(DEBUG_ILC_ICONRENDERING)
2430 D(bug("[IconList] %s: FrontRastPort @ %p, New BackLayer @ %p, BackRastport @ %p\n", __PRETTY_FUNCTION__
, data
->icld_DisplayRastPort
, data
->icld_BufferRastPort
->Layer
, data
->icld_BufferRastPort
));
2432 SET(obj
, MUIA_IconList_BufferRastport
, data
->icld_BufferRastPort
);
2433 data
->icld_DrawOffsetX
= 0;
2434 data
->icld_DrawOffsetY
= 0;
2437 data
->icld_BufferRastPort
= data
->icld_DisplayRastPort
;
2440 data
->icld_BufferRastPort
= data
->icld_DisplayRastPort
;
2443 data
->icld_BufferRastPort
= data
->icld_DisplayRastPort
;
2445 if (data
->icld_BufferRastPort
== data
->icld_DisplayRastPort
)
2447 if (bitmap_New
) FreeBitMap(bitmap_New
);
2448 if (li
) DisposeLayerInfo(li
);
2449 data
->icld_DrawOffsetX
= _mleft(obj
);
2450 data
->icld_DrawOffsetY
= _mtop(obj
);
2456 if ((data
->icld_BufferRastPort
) && (data
->icld_BufferRastPort
!= data
->icld_DisplayRastPort
))
2458 //Free up the buffers layer, rastport and bitmap since they are no longer needed ..
2459 struct Layer
*oldLayer
= data
->icld_BufferRastPort
->Layer
;
2460 data
->icld_BufferRastPort
= data
->icld_DisplayRastPort
;
2461 InstallClipRegion(oldLayer
, NULL
);
2462 DeleteLayer(0, oldLayer
);
2463 FreeBitMap(data
->icld_BufferRastPort
->BitMap
);
2464 data
->icld_DrawOffsetX
= _mleft(obj
);
2465 data
->icld_DrawOffsetY
= _mtop(obj
);
2468 SET(obj
, MUIA_IconList_Changed
, TRUE
);
2472 case MUIA_IconList_SortFlags
:
2473 #if defined(DEBUG_ILC_ATTRIBS)
2474 D(bug("[IconList] %s: MUIA_IconList_SortFlags %08x\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2476 data
->icld_SortFlags
= (ULONG
)tag
->ti_Data
;
2479 case MUIA_IconList_DragImageTransparent
:
2480 data
->icld__Option_DragImageTransparent
= (BOOL
)tag
->ti_Data
;
2483 case MUIA_IconList_IconListMode
:
2484 #if defined(DEBUG_ILC_ATTRIBS)
2485 D(bug("[IconList] %s: MUIA_IconList_IconListMode %d\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2487 data
->icld__Option_IconListMode
= (UBYTE
)tag
->ti_Data
;
2490 case MUIA_IconList_LabelText_Mode
:
2491 #if defined(DEBUG_ILC_ATTRIBS)
2492 D(bug("[IconList] %s: MUIA_IconList_LabelText_Mode %d\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2494 data
->icld__Option_LabelTextMode
= (UBYTE
)tag
->ti_Data
;
2497 case MUIA_IconList_LabelText_MaxLineLen
:
2498 #if defined(DEBUG_ILC_ATTRIBS)
2499 D(bug("[IconList] %s: MUIA_IconList_LabelText_MaxLineLen %d\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2501 if (tag
->ti_Data
>= ILC_ICONLABEL_SHORTEST
)
2503 data
->icld__Option_LabelTextMaxLen
= (ULONG
)tag
->ti_Data
;
2507 data
->icld__Option_LabelTextMaxLen
= ILC_ICONLABEL_MAXLINELEN_DEFAULT
;
2511 case MUIA_IconList_LabelText_MultiLine
:
2512 #if defined(DEBUG_ILC_ATTRIBS)
2513 D(bug("[IconList] %s: MUIA_IconList_LabelText_MultiLine %d\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2515 data
->icld__Option_LabelTextMultiLine
= (ULONG
)tag
->ti_Data
;
2516 if (data
->icld__Option_LabelTextMultiLine
== 0)data
->icld__Option_LabelTextMultiLine
= 1;
2519 case MUIA_IconList_LabelText_MultiLineOnFocus
:
2520 #if defined(DEBUG_ILC_ATTRIBS)
2521 D(bug("[IconList] %s: MUIA_IconList_LabelText_MultiLineOnFocus %d\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2523 data
->icld__Option_LabelTextMultiLineOnFocus
= (BOOL
)tag
->ti_Data
;
2526 case MUIA_IconList_Icon_HorizontalSpacing
:
2527 #if defined(DEBUG_ILC_ATTRIBS)
2528 D(bug("[IconList] %s: MUIA_IconList_Icon_HorizontalSpacing %d\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2530 data
->icld__Option_IconHorizontalSpacing
= (UBYTE
)tag
->ti_Data
;
2533 case MUIA_IconList_Icon_VerticalSpacing
:
2534 #if defined(DEBUG_ILC_ATTRIBS)
2535 D(bug("[IconList] %s: MUIA_IconList_Icon_VerticalSpacing %d\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2537 data
->icld__Option_IconVerticalSpacing
= (UBYTE
)tag
->ti_Data
;
2540 case MUIA_IconList_Icon_ImageSpacing
:
2541 #if defined(DEBUG_ILC_ATTRIBS)
2542 D(bug("[IconList] %s: MUIA_IconList_Icon_ImageSpacing %d\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2544 data
->icld__Option_IconImageSpacing
= (UBYTE
)tag
->ti_Data
;
2547 case MUIA_IconList_LabelText_HorizontalPadding
:
2548 #if defined(DEBUG_ILC_ATTRIBS)
2549 D(bug("[IconList] %s: MUIA_IconList_LabelText_HorizontalPadding %d\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2551 data
->icld__Option_LabelTextHorizontalPadding
= (UBYTE
)tag
->ti_Data
;
2554 case MUIA_IconList_LabelText_VerticalPadding
:
2555 #if defined(DEBUG_ILC_ATTRIBS)
2556 D(bug("[IconList] %s: MUIA_IconList_LabelText_VerticalPadding %d\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2558 data
->icld__Option_LabelTextVerticalPadding
= (UBYTE
)tag
->ti_Data
;
2561 case MUIA_IconList_LabelText_BorderWidth
:
2562 #if defined(DEBUG_ILC_ATTRIBS)
2563 D(bug("[IconList] %s: MUIA_IconList_LabelText_BorderWidth %d\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2565 data
->icld__Option_LabelTextBorderWidth
= (UBYTE
)tag
->ti_Data
;
2568 case MUIA_IconList_LabelText_BorderHeight
:
2569 #if defined(DEBUG_ILC_ATTRIBS)
2570 D(bug("[IconList] %s: MUIA_IconList_LabelText_BorderHeight %d\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2572 data
->icld__Option_LabelTextBorderHeight
= (UBYTE
)tag
->ti_Data
;
2575 case MUIA_IconList_LabelText_Pen
:
2576 data
->icld_LabelPen
= (ULONG
)tag
->ti_Data
;
2579 case MUIA_IconList_LabelText_ShadowPen
:
2580 data
->icld_LabelShadowPen
= (ULONG
)tag
->ti_Data
;
2583 case MUIA_IconList_LabelInfoText_Pen
:
2584 data
->icld_InfoPen
= (ULONG
)tag
->ti_Data
;
2587 case MUIA_IconList_LabelInfoText_ShadowPen
:
2588 data
->icld_InfoShadowPen
= (ULONG
)tag
->ti_Data
;
2591 /* Settings defined by the view class */
2592 case MUIA_IconListview_FixedBackground
:
2593 #if defined(DEBUG_ILC_ATTRIBS)
2594 D(bug("[IconList] %s: MUIA_IconListview_FixedBackground\n", __PRETTY_FUNCTION__
));
2596 data
->icld__Option_IconListFixedBackground
= (BOOL
)tag
->ti_Data
;
2599 case MUIA_IconListview_ScaledBackground
:
2600 #if defined(DEBUG_ILC_ATTRIBS)
2601 D(bug("[IconList] %s: MUIA_IconListview_ScaledBackground\n", __PRETTY_FUNCTION__
));
2603 data
->icld__Option_IconListScaledBackground
= (BOOL
)tag
->ti_Data
;
2606 /* We listen for MUIA_Background and set default values for known types */
2607 case MUIA_Background
:
2608 #if defined(DEBUG_ILC_ATTRIBS) || defined(DEBUG_ILC_ICONRENDERING)
2609 D(bug("[IconList] %s: MUIA_Background\n", __PRETTY_FUNCTION__
));
2612 char *bgmode_string
= (char *)tag
->ti_Data
;
2613 BYTE this_mode
= bgmode_string
[0] - 48;
2615 #if defined(DEBUG_ILC_ATTRIBS) || defined(DEBUG_ILC_ICONRENDERING)
2616 D(bug("[IconList] %s: MUIA_Background | MUI BG Mode = %d\n", __PRETTY_FUNCTION__
, this_mode
));
2622 NNSET(obj
, MUIA_IconListview_FixedBackground
, FALSE
);
2623 NNSET(obj
, MUIA_IconListview_ScaledBackground
, FALSE
);
2627 NNSET(obj
, MUIA_IconListview_FixedBackground
, FALSE
);
2628 NNSET(obj
, MUIA_IconListview_ScaledBackground
, FALSE
);
2632 NNSET(obj
, MUIA_IconListview_FixedBackground
, TRUE
);
2633 NNSET(obj
, MUIA_IconListview_ScaledBackground
, TRUE
);
2637 NNSET(obj
, MUIA_IconListview_FixedBackground
, FALSE
);
2638 NNSET(obj
, MUIA_IconListview_ScaledBackground
, FALSE
);
2643 case MUIA_IconList_IconsDropped
:
2644 data
->icld_DragDropEvent
= (struct IconList_Drop_Event
*)tag
->ti_Data
;
2649 #if defined(DEBUG_ILC_ATTRIBS)
2650 D(bug("[IconList] %s(), out of switch\n", __PRETTY_FUNCTION__
));
2652 if ((oldleft
!= data
->icld_ViewX
) || (oldtop
!= data
->icld_ViewY
))
2654 data
->icld_UpdateMode
= UPDATE_SCROLL
;
2655 data
->update_scrolldx
= data
->icld_ViewX
- oldleft
;
2656 data
->update_scrolldy
= data
->icld_ViewY
- oldtop
;
2657 #if defined(DEBUG_ILC_ATTRIBS)
2658 D(bug("[IconList] %s(), call MUI_Redraw()\n", __PRETTY_FUNCTION__
));
2660 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
2663 #if defined(DEBUG_ILC_ATTRIBS)
2664 D(bug("[IconList] %s(), call DoSuperMethodA()\n", __PRETTY_FUNCTION__
));
2666 return DoSuperMethodA(CLASS
, obj
, (Msg
)message
);
2671 /**************************************************************************
2673 **************************************************************************/
2674 IPTR
IconList__OM_GET(struct IClass
*CLASS
, Object
*obj
, struct opGet
*message
)
2676 /* small macro to simplify return value storage */
2677 #define STORE *(message->opg_Storage)
2678 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
2680 #if defined(DEBUG_ILC_FUNCS) || defined(DEBUG_ILC_ATTRIBS)
2681 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
2684 switch (message
->opg_AttrID
)
2686 case MUIA_IconList_Rastport
: STORE
= (IPTR
)data
->icld_DisplayRastPort
; return 1;
2687 case MUIA_IconList_BufferRastport
: STORE
= (IPTR
)data
->icld_BufferRastPort
; return 1;
2688 case MUIA_IconList_BufferLeft
: STORE
= (IPTR
)data
->icld_DrawOffsetX
; return 1;
2689 case MUIA_IconList_BufferTop
: STORE
= (IPTR
)data
->icld_DrawOffsetY
; return 1;
2690 case MUIA_IconList_BufferWidth
:
2691 case MUIA_IconList_Width
: STORE
= (IPTR
)data
->icld_AreaWidth
; return 1;
2692 case MUIA_IconList_BufferHeight
:
2693 case MUIA_IconList_Height
: STORE
= (IPTR
)data
->icld_AreaHeight
; return 1;
2694 case MUIA_IconList_IconsDropped
: STORE
= (IPTR
)data
->icld_DragDropEvent
; return 1;
2695 case MUIA_IconList_Clicked
: STORE
= (IPTR
)&data
->icld_ClickEvent
; return 1;
2696 case MUIA_IconList_IconListMode
: STORE
= (IPTR
)data
->icld__Option_IconListMode
; return 1;
2697 case MUIA_IconList_LabelText_Mode
: STORE
= (IPTR
)data
->icld__Option_LabelTextMode
; return 1;
2698 case MUIA_IconList_LabelText_MaxLineLen
: STORE
= (IPTR
)data
->icld__Option_LabelTextMaxLen
; return 1;
2699 case MUIA_IconList_LabelText_MultiLine
: STORE
= (IPTR
)data
->icld__Option_LabelTextMultiLine
; return 1;
2700 case MUIA_IconList_LabelText_MultiLineOnFocus
: STORE
= (IPTR
)data
->icld__Option_LabelTextMultiLineOnFocus
; return 1;
2701 case MUIA_IconList_DisplayFlags
: STORE
= (IPTR
)data
->icld_DisplayFlags
; return 1;
2702 case MUIA_IconList_SortFlags
: STORE
= (IPTR
)data
->icld_SortFlags
; return 1;
2704 case MUIA_IconList_FocusIcon
: STORE
= (IPTR
)data
->icld_FocusIcon
; return 1;
2706 case MUIA_Font
: STORE
= (IPTR
)data
->icld_IconLabelFont
; return 1;
2707 case MUIA_IconList_LabelText_Pen
: STORE
= (IPTR
)data
->icld_LabelPen
; return 1;
2708 case MUIA_IconList_LabelText_ShadowPen
: STORE
= (IPTR
)data
->icld_LabelShadowPen
; return 1;
2709 case MUIA_IconList_LabelInfoText_Font
: STORE
= (IPTR
)data
->icld_IconInfoFont
; return 1;
2710 case MUIA_IconList_LabelInfoText_Pen
: STORE
= (IPTR
)data
->icld_InfoPen
; return 1;
2711 case MUIA_IconList_LabelInfoText_ShadowPen
: STORE
= (IPTR
)data
->icld_InfoShadowPen
; return 1;
2712 case MUIA_IconList_DragImageTransparent
: STORE
= (IPTR
)data
->icld__Option_DragImageTransparent
; return 1;
2714 case MUIA_IconList_Icon_HorizontalSpacing
: STORE
= (IPTR
)data
->icld__Option_IconHorizontalSpacing
; return 1;
2715 case MUIA_IconList_Icon_VerticalSpacing
: STORE
= (IPTR
)data
->icld__Option_IconVerticalSpacing
; return 1;
2716 case MUIA_IconList_Icon_ImageSpacing
: STORE
= (IPTR
)data
->icld__Option_IconImageSpacing
; return 1;
2717 case MUIA_IconList_LabelText_HorizontalPadding
: STORE
= (IPTR
)data
->icld__Option_LabelTextHorizontalPadding
; return 1;
2718 case MUIA_IconList_LabelText_VerticalPadding
: STORE
= (IPTR
)data
->icld__Option_LabelTextVerticalPadding
; return 1;
2719 case MUIA_IconList_LabelText_BorderWidth
: STORE
= (IPTR
)data
->icld__Option_LabelTextBorderWidth
; return 1;
2720 case MUIA_IconList_LabelText_BorderHeight
: STORE
= (IPTR
)data
->icld__Option_LabelTextBorderHeight
; return 1;
2722 /* Settings defined by the view class */
2723 case MUIA_IconListview_FixedBackground
: STORE
= (IPTR
)data
->icld__Option_IconListFixedBackground
; return 1;
2724 case MUIA_IconListview_ScaledBackground
: STORE
= (IPTR
)data
->icld__Option_IconListScaledBackground
; return 1;
2726 /* ICON obj Changes */
2727 case MUIA_Virtgroup_Left
: STORE
= (IPTR
)data
->icld_ViewX
; return 1;
2728 case MUIA_Virtgroup_Top
: STORE
= (IPTR
)data
->icld_ViewY
; return 1;
2729 case MUIA_Family_List
: STORE
= (IPTR
)&(data
->icld_IconList
); return 1; /* Get our list object */
2731 /* TODO: Get the version/revision from our config.. */
2732 case MUIA_Version
: STORE
= (IPTR
)1; return 1;
2733 case MUIA_Revision
: STORE
= (IPTR
)7; return 1;
2736 return DoSuperMethodA(CLASS
, obj
, (Msg
) message
);
2741 IPTR
IconList__MUIM_Family_AddHead(struct IClass
*CLASS
, Object
*obj
, struct MUIP_Family_AddHead
*message
)
2743 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
2744 #if defined(DEBUG_ILC_FUNCS)
2745 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
2750 /* TODO: Use the correct _OBJECT() code when we switch to icon.mui */
2751 // AddHead(&(data->icld_IconList), (struct Node *)_OBJECT(message->obj));
2752 AddHead(&(data
->icld_IconList
), (struct Node
*)message
->obj
);
2759 IPTR
IconList__MUIM_Family_AddTail(struct IClass
*CLASS
, Object
*obj
, struct MUIP_Family_AddTail
*message
)
2761 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
2762 #if defined(DEBUG_ILC_FUNCS)
2763 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
2766 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
));
2770 /* TODO: Use the correct _OBJECT() code when we switch to icon.mui */
2771 // AddTail(&(data->icld_IconList), (struct Node *)_OBJECT(message->obj));
2772 AddTail(&(data
->icld_IconList
), (struct Node
*)message
->obj
);
2780 #if !defined(WANDERER_BUILTIN_ICONLIST)
2781 IPTR
IconList__OM_ADDMEMBER(struct IClass
*CLASS
, Object
*obj
, struct MUIP_Family_AddTail
*message
)
2783 return IconList__MUIM_Family_AddTail(CLASS
, obj
, message
);
2787 IPTR
IconList__MUIM_Family_Remove(struct IClass
*CLASS
, Object
*obj
, struct MUIP_Family_Remove
*message
)
2789 // struct IconList_DATA *data = INST_DATA(CLASS, obj);
2790 #if defined(DEBUG_ILC_FUNCS)
2791 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
2794 D(bug("[IconList] %s: entry @ 0x%p '%s'\n", __PRETTY_FUNCTION__
, message
->obj
, ((struct IconEntry
*)message
->obj
)->ie_IconNode
.ln_Name
));
2798 /* TODO: Use the correct _OBJECT() code when we switch to icon.mui */
2799 // Remove((struct Node *)_OBJECT(message->obj));
2800 Remove((struct Node
*)message
->obj
);
2808 #if !defined(WANDERER_BUILTIN_ICONLIST)
2809 IPTR
IconList__OM_REMMEMBER(struct IClass
*CLASS
, Object
*obj
, struct MUIP_Family_Remove
*message
)
2811 return IconList__MUIM_Family_Remove(CLASS
, obj
, message
);
2816 /**************************************************************************
2818 **************************************************************************/
2819 IPTR
IconList__MUIM_Setup(struct IClass
*CLASS
, Object
*obj
, struct MUIP_Setup
*message
)
2821 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
2822 struct IconEntry
*node
= NULL
;
2823 IPTR geticon_error
= 0, iconlistScreen
;
2825 #if defined(DEBUG_ILC_FUNCS)
2826 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
2829 if (!DoSuperMethodA(CLASS
, obj
, (Msg
) message
)) return (IPTR
)NULL
;
2831 iconlistScreen
= (IPTR
)_screen(obj
);
2832 #if defined(DEBUG_ILC_ICONRENDERING)
2833 D(bug("[IconList] %s: IconList Screen @ 0x%p)\n", __PRETTY_FUNCTION__
, iconlistScreen
));
2836 DoMethod(_win(obj
), MUIM_Window_AddEventHandler
, (IPTR
)&data
->ehn
);
2838 /* Get Internal Objects to use if not set .. */
2839 data
->icld_DisplayRastPort
= NULL
;
2840 data
->icld_BufferRastPort
= NULL
;
2842 if (data
->icld_IconLabelFont
== NULL
) data
->icld_IconLabelFont
= _font(obj
);
2843 if (data
->icld_IconInfoFont
== NULL
) data
->icld_IconInfoFont
= data
->icld_IconLabelFont
;
2846 * Here we have our font, either from user preferences or from MUI's AreaData.
2847 * It's right time to set up some sizes.
2849 if (data
->icld_LVMAttribs
)
2850 CalcHeight(data
->icld_LVMAttribs
, data
->icld_IconLabelFont
);
2851 #if defined(DEBUG_ILC_ICONRENDERING)
2852 D(bug("[IconList] %s: Use Font @ 0x%p, RastPort @ 0x%p\n", __PRETTY_FUNCTION__
, data
->icld_IconLabelFont
, data
->icld_BufferRastPort
));
2855 /* Set our base options .. */
2856 data
->icld_LabelPen
= _pens(obj
)[MPEN_SHINE
];
2857 data
->icld_LabelShadowPen
= _pens(obj
)[MPEN_SHADOW
];
2858 data
->icld_InfoPen
= _pens(obj
)[MPEN_SHINE
];
2859 data
->icld_InfoShadowPen
= _pens(obj
)[MPEN_SHADOW
];
2861 data
->icld__Option_LabelTextMultiLine
= 1;
2862 data
->icld__Option_LastLabelTextMultiLine
= data
->icld__Option_LabelTextMultiLine
;
2864 data
->icld__Option_LabelTextMultiLineOnFocus
= FALSE
;
2866 data
->icld__Option_IconHorizontalSpacing
= ILC_ICON_HORIZONTALMARGIN_DEFAULT
;
2867 data
->icld__Option_IconVerticalSpacing
= ILC_ICON_VERTICALMARGIN_DEFAULT
;
2868 data
->icld__Option_IconImageSpacing
= ILC_ICONLABEL_IMAGEMARGIN_DEFAULT
;
2869 data
->icld__Option_LabelTextHorizontalPadding
= ILC_ICONLABEL_HORIZONTALTEXTMARGIN_DEFAULT
;
2870 data
->icld__Option_LabelTextVerticalPadding
= ILC_ICONLABEL_VERTICALTEXTMARGIN_DEFAULT
;
2871 data
->icld__Option_LabelTextBorderWidth
= ILC_ICONLABEL_BORDERWIDTH_DEFAULT
;
2872 data
->icld__Option_LabelTextBorderHeight
= ILC_ICONLABEL_BORDERHEIGHT_DEFAULT
;
2874 if (data
->icld_LVMAttribs
)
2876 data
->icld_LVMAttribs
->lvma_IconDrawer
= GetIconTags
2878 "WANDERER:Icons/drawer",
2879 (iconlistScreen
) ? ICONGETA_Screen
: TAG_IGNORE
, iconlistScreen
,
2880 (iconlistScreen
) ? ICONGETA_RemapIcon
: TAG_IGNORE
, TRUE
,
2881 ICONGETA_FailIfUnavailable
, TRUE
,
2882 ICONGETA_GenerateImageMasks
, TRUE
,
2883 ICONA_ErrorCode
, &geticon_error
,
2887 #if defined(DEBUG_ILC_ICONRENDERING)
2888 if (data
->icld_LVMAttribs
->lvma_IconDrawer
== NULL
)
2890 D(bug("[IconList] %s: Couldnt get drawer DiskObject! (error code = 0x%p)\n", __PRETTY_FUNCTION__
, geticon_error
));
2893 data
->icld_LVMAttribs
->lvma_IconFile
= GetIconTags
2895 "WANDERER:Icons/file",
2896 (iconlistScreen
) ? ICONGETA_Screen
: TAG_IGNORE
, iconlistScreen
,
2897 (iconlistScreen
) ? ICONGETA_RemapIcon
: TAG_IGNORE
, TRUE
,
2898 ICONGETA_FailIfUnavailable
, TRUE
,
2899 ICONGETA_GenerateImageMasks
, TRUE
,
2900 ICONA_ErrorCode
, &geticon_error
,
2904 #if defined(DEBUG_ILC_ICONRENDERING)
2905 if (data
->icld_LVMAttribs
->lvma_IconFile
== NULL
)
2907 D(bug("[IconList] %s: Couldnt get file DiskObject! (error code = 0x%p)\n", __PRETTY_FUNCTION__
, geticon_error
));
2912 #if defined(__AROS__)
2913 ForeachNode(&data
->icld_IconList
, node
)
2915 Foreach_Node(&data
->icld_IconList
, node
);
2918 if (!node
->ie_DiskObj
)
2920 if (!(node
->ie_DiskObj
= GetIconTags(node
->ie_IconNode
.ln_Name
,
2921 (iconlistScreen
) ? ICONGETA_Screen
: TAG_IGNORE
, iconlistScreen
,
2922 (iconlistScreen
) ? ICONGETA_RemapIcon
: TAG_IGNORE
, TRUE
,
2923 ICONGETA_GenerateImageMasks
, TRUE
,
2924 ICONGETA_FailIfUnavailable
, FALSE
,
2925 ICONA_ErrorCode
, &geticon_error
,
2928 #if defined(DEBUG_ILC_ICONRENDERING)
2929 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
));
2931 /* We should probably remove this node if the entry cant be obtained ? */
2940 /**************************************************************************
2942 **************************************************************************/
2943 IPTR
IconList__MUIM_Show(struct IClass
*CLASS
, Object
*obj
, struct MUIP_Show
*message
)
2945 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
2950 #if defined(DEBUG_ILC_FUNCS)
2951 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
2954 if ((rc
= DoSuperMethodA(CLASS
, obj
, (Msg
)message
)))
2956 newleft
= data
->icld_ViewX
;
2957 newtop
= data
->icld_ViewY
;
2959 if (newleft
+ _mwidth(obj
) > data
->icld_AreaWidth
)
2960 newleft
= data
->icld_AreaWidth
- _mwidth(obj
);
2964 if (newtop
+ _mheight(obj
) > data
->icld_AreaHeight
)
2965 newtop
= data
->icld_AreaHeight
- _mheight(obj
);
2969 if ((newleft
!= data
->icld_ViewX
) || (newtop
!= data
->icld_ViewY
))
2971 SetAttrs(obj
, MUIA_Virtgroup_Left
, newleft
,
2972 MUIA_Virtgroup_Top
, newtop
,
2976 /* Get Internal Objects to use if not set .. */
2977 if (data
->icld_DisplayRastPort
== NULL
)
2979 if (_rp(obj
) != NULL
)
2981 data
->icld_DisplayRastPort
= CloneRastPort(_rp(obj
));
2983 #if defined(DEBUG_ILC_ICONRENDERING)
2986 D(bug("[IconList] IconList__MUIM_Show: ERROR - NULL RastPort!\n"));
2991 if (data
->icld_DisplayFlags
& ICONLIST_DISP_BUFFERED
)
2993 struct BitMap
*bitmap_New
= NULL
;
2994 struct Layer_Info
*li
= NULL
;
2996 ULONG tmp_RastDepth
= GetCyberMapAttr(data
->icld_DisplayRastPort
->BitMap
, CYBRMATTR_DEPTH
);
2997 if ((bitmap_New
= AllocBitMap(data
->icld_ViewWidth
,
2998 data
->icld_ViewHeight
,
3001 data
->icld_DisplayRastPort
->BitMap
))!=NULL
)
3003 if ((data
->icld_BufferRastPort
= CreateRastPort())!=NULL
)
3005 data
->icld_BufferRastPort
->BitMap
= bitmap_New
;
3006 if ((li
= NewLayerInfo()))
3008 if ((data
->icld_BufferRastPort
->Layer
= CreateUpfrontLayer(li
, data
->icld_BufferRastPort
->BitMap
, 0, 0, data
->icld_ViewWidth
- 1, data
->icld_ViewHeight
- 1, 0, NULL
)))
3011 * Mark it as a buffered rastport.
3014 #if defined(DEBUG_ILC_ATTRIBS) || defined(DEBUG_ILC_ICONRENDERING)
3015 D(bug("[IconList] %s: FrontRastPort @ %p, New BackLayer @ %p, BackRastport @ %p\n", __PRETTY_FUNCTION__
, data
->icld_DisplayRastPort
, data
->icld_BufferRastPort
->Layer
, data
->icld_BufferRastPort
));
3017 SET(obj
, MUIA_IconList_BufferRastport
, data
->icld_BufferRastPort
);
3018 data
->icld_DrawOffsetX
= 0;
3019 data
->icld_DrawOffsetY
= 0;
3022 data
->icld_BufferRastPort
= data
->icld_DisplayRastPort
;
3025 data
->icld_BufferRastPort
= data
->icld_DisplayRastPort
;
3028 data
->icld_BufferRastPort
= data
->icld_DisplayRastPort
;
3030 if (data
->icld_BufferRastPort
== data
->icld_DisplayRastPort
)
3032 if (bitmap_New
) FreeBitMap(bitmap_New
);
3033 if (li
) DisposeLayerInfo(li
);
3034 data
->icld_DrawOffsetX
= _mleft(obj
);
3035 data
->icld_DrawOffsetY
= _mtop(obj
);
3040 data
->icld_BufferRastPort
= data
->icld_DisplayRastPort
;
3041 data
->icld_DrawOffsetX
= _mleft(obj
);
3042 data
->icld_DrawOffsetY
= _mtop(obj
);
3045 if (data
->icld_IconLabelFont
== NULL
) data
->icld_IconLabelFont
= _font(obj
);
3046 if (data
->icld_IconInfoFont
== NULL
) data
->icld_IconInfoFont
= data
->icld_IconLabelFont
;
3047 #if defined(DEBUG_ILC_ICONRENDERING)
3048 D(bug("[IconList] IconList__MUIM_Show: Use Font @ 0x%p, RastPort @ 0x%p\n", data
->icld_IconLabelFont
, data
->icld_BufferRastPort
));
3051 if ((data
->icld_BufferRastPort
) && (data
->icld_IconLabelFont
))
3052 SetFont(data
->icld_BufferRastPort
, data
->icld_IconLabelFont
);
3059 /**************************************************************************
3061 **************************************************************************/
3062 IPTR
IconList__MUIM_Hide(struct IClass
*CLASS
, Object
*obj
, struct MUIP_Hide
*message
)
3064 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
3067 #if defined(DEBUG_ILC_FUNCS)
3068 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
3071 if ((rc
= DoSuperMethodA(CLASS
, obj
, (Msg
)message
)))
3073 if ((data
->icld_BufferRastPort
) && (data
->icld_BufferRastPort
!= data
->icld_DisplayRastPort
))
3075 DeleteLayer(0, data
->icld_BufferRastPort
->Layer
);
3078 data
->icld_BufferRastPort
= NULL
;
3080 if (data
->icld_DisplayRastPort
)
3081 FreeRastPort(data
->icld_DisplayRastPort
);
3083 data
->icld_DisplayRastPort
= NULL
;
3090 /**************************************************************************
3092 **************************************************************************/
3093 IPTR
IconList__MUIM_Cleanup(struct IClass
*CLASS
, Object
*obj
, struct MUIP_Cleanup
*message
)
3095 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
3096 struct IconEntry
*node
= NULL
;
3098 #if defined(DEBUG_ILC_FUNCS)
3099 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
3102 #if defined(__AROS__)
3103 ForeachNode(&data
->icld_IconList
, node
)
3105 Foreach_Node(&data
->icld_IconList
, node
);
3108 if (node
->ie_DiskObj
)
3110 FreeDiskObject(node
->ie_DiskObj
);
3111 node
->ie_DiskObj
= NULL
;
3115 DoMethod(_win(obj
), MUIM_Window_RemEventHandler
, (IPTR
)&data
->ehn
);
3117 return DoSuperMethodA(CLASS
, obj
, (Msg
)message
);
3122 /**************************************************************************
3124 **************************************************************************/
3125 IPTR
IconList__MUIM_AskMinMax(struct IClass
*CLASS
, Object
*obj
, struct MUIP_AskMinMax
*message
)
3127 ULONG rc
= DoSuperMethodA(CLASS
, obj
, (Msg
) message
);
3129 #if defined(DEBUG_ILC_FUNCS)
3130 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
3133 message
->MinMaxInfo
->MinWidth
+= 96;
3134 message
->MinMaxInfo
->MinHeight
+= 64;
3136 message
->MinMaxInfo
->DefWidth
+= 200;
3137 message
->MinMaxInfo
->DefHeight
+= 180;
3139 message
->MinMaxInfo
->MaxWidth
= MUI_MAXMAX
;
3140 message
->MinMaxInfo
->MaxHeight
= MUI_MAXMAX
;
3147 /**************************************************************************
3149 **************************************************************************/
3150 IPTR
IconList__MUIM_Layout(struct IClass
*CLASS
, Object
*obj
,struct MUIP_Layout
*message
)
3152 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
3155 #if defined(DEBUG_ILC_FUNCS)
3156 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
3159 rc
= DoSuperMethodA(CLASS
, obj
, (Msg
)message
);
3161 data
->icld_ViewWidth
= _mwidth(obj
);
3162 data
->icld_ViewHeight
= _mheight(obj
);
3168 static LONG
FirstVisibleLine(struct IconList_DATA
*data
)
3170 return data
->icld_ViewY
/ data
->icld_LVMAttribs
->lmva_RowHeight
;
3173 static LONG
NumVisibleLines(struct IconList_DATA
*data
)
3175 LONG visible
= data
->icld_ViewHeight
+ data
->icld_LVMAttribs
->lmva_RowHeight
- 1 +
3176 (data
->icld_ViewY
% data
->icld_LVMAttribs
->lmva_RowHeight
);
3178 visible
/= data
->icld_LVMAttribs
->lmva_RowHeight
;
3183 static void RenderListViewModeHeaderField(Object
*obj
, struct IconList_DATA
*data
,
3184 struct Rectangle
*rect
, LONG index
, BOOL sel
)
3186 IPTR penFill
, penText
, penDark
, penBright
;
3187 struct Rectangle rendRect
;
3189 struct TextExtent te
;
3194 penFill
= _pens(obj
)[MPEN_HALFSHADOW
];
3195 penBright
= _pens(obj
)[MPEN_SHADOW
];
3196 penDark
= _pens(obj
)[MPEN_HALFSHINE
];
3200 penFill
= _pens(obj
)[MPEN_HALFSHINE
];
3201 penBright
= _pens(obj
)[MPEN_SHINE
];
3202 penDark
= _pens(obj
)[MPEN_HALFSHADOW
];
3204 penText
= _pens(obj
)[MPEN_TEXT
];
3206 rendRect
.MinX
= rect
->MinX
;
3207 rendRect
.MaxX
= rect
->MaxX
;
3208 rendRect
.MinY
= rect
->MinY
;
3209 rendRect
.MaxY
= rect
->MaxY
;
3211 if (data
->icld_DisplayRastPort
!= data
->icld_BufferRastPort
)
3213 rendRect
.MinX
-= _mleft(obj
);
3214 rendRect
.MaxX
-= _mleft(obj
);
3215 rendRect
.MinY
-= _mtop(obj
);
3216 rendRect
.MaxY
-= _mtop(obj
);
3219 #if defined(DEBUG_ILC_FUNCS)
3220 D(bug("[IconList]: %s(obj @ 0x%p)\n", __PRETTY_FUNCTION__
, obj
));
3223 if (((data
->icld_LVMAttribs
->lvma_Flags
& LVMAF_NOHEADER
) == 0) && (index
< NUM_COLUMNS
))
3225 text
= data
->icld_LVMAttribs
->lmva_ColumnTitle
[index
];
3227 SetAPen(data
->icld_BufferRastPort
, penFill
); /* Background */
3228 RectFill(data
->icld_BufferRastPort
, rendRect
.MinX
+ 1, rendRect
.MinY
+ 1,
3229 rendRect
.MaxX
- 1, rendRect
.MaxY
- 1);
3231 SetAPen(data
->icld_BufferRastPort
, penBright
); /* Top/Left */
3232 RectFill(data
->icld_BufferRastPort
, rendRect
.MinX
, rendRect
.MinY
, rendRect
.MinX
, rendRect
.MaxY
);
3233 RectFill(data
->icld_BufferRastPort
, rendRect
.MinX
+ 1, rendRect
.MinY
, rendRect
.MaxX
- 1, rendRect
.MinY
);
3235 SetAPen(data
->icld_BufferRastPort
,penDark
); /* Bottom/Right */
3236 RectFill(data
->icld_BufferRastPort
, rendRect
.MaxX
, rendRect
.MinY
, rendRect
.MaxX
, rendRect
.MaxY
);
3237 RectFill(data
->icld_BufferRastPort
, rendRect
.MinX
+ 1, rendRect
.MaxY
, rendRect
.MaxX
- 1, rendRect
.MaxY
);
3239 /* Draw the Sort indicator .. */
3240 if (index
== data
->icld_LVMAttribs
->lmva_SortColumn
)
3242 LONG x
= rendRect
.MaxX
- 4 - 6;
3243 LONG y
= (rendRect
.MinY
+ rendRect
.MaxY
+ 1) / 2 - 3;
3245 if (x
> rendRect
.MinX
)
3247 SetAPen(data
->icld_BufferRastPort
, _pens(obj
)[sel
? MPEN_SHADOW
: MPEN_HALFSHADOW
]);
3248 if (data
->icld_SortFlags
& MUIV_IconList_Sort_Reverse
)
3250 RectFill(data
->icld_BufferRastPort
, x
, y
, x
+ 5, y
+ 1);
3251 RectFill(data
->icld_BufferRastPort
, x
+ 1, y
+ 2, x
+ 4, y
+ 3);
3252 RectFill(data
->icld_BufferRastPort
, x
+ 2, y
+ 4, x
+ 3, y
+ 5);
3256 RectFill(data
->icld_BufferRastPort
, x
, y
+ 4, x
+ 5, y
+ 5);
3257 RectFill(data
->icld_BufferRastPort
, x
+ 1, y
+ 2, x
+ 4, y
+ 3);
3258 RectFill(data
->icld_BufferRastPort
, x
+ 2, y
, x
+ 3, y
+ 1);
3263 rendRect
.MinX
+= HEADERENTRY_SPACING_LEFT
;
3264 rendRect
.MinY
+= HEADERLINE_SPACING_TOP
;
3265 rendRect
.MaxX
-= HEADERENTRY_SPACING_RIGHT
;
3266 rendRect
.MaxY
-= HEADERLINE_SPACING_BOTTOM
;
3268 if (text
&& text
[0])
3271 fit
= TextFit(data
->icld_BufferRastPort
, text
, strlen(text
), &te
, NULL
, 1,
3272 rendRect
.MaxX
- rendRect
.MinX
+ 1,
3273 rendRect
.MaxY
- rendRect
.MinY
+ 1);
3277 SetABPenDrMd(data
->icld_BufferRastPort
, penText
, 0, JAM1
);
3278 Move(data
->icld_BufferRastPort
, rendRect
.MinX
, rendRect
.MinY
+ data
->icld_BufferRastPort
->TxBaseline
);
3279 Text(data
->icld_BufferRastPort
, text
, fit
);
3284 static void RenderListViewModeHeader(Object
*obj
, struct IconList_DATA
*data
)
3286 struct Rectangle linerect
;
3288 LONG firstvis
, lastvis
;
3290 #if defined(DEBUG_ILC_FUNCS)
3291 D(bug("[IconList]: %s(obj @ 0x%p)\n", __PRETTY_FUNCTION__
, obj
));
3294 if ((data
->icld_LVMAttribs
->lvma_Flags
& LVMAF_NOHEADER
) == 0)
3296 linerect
.MinX
= _mleft(obj
) - data
->icld_ViewX
;
3297 linerect
.MaxX
= _mright(obj
);
3298 linerect
.MinY
= _mtop(obj
);
3299 linerect
.MaxY
= _mtop(obj
) + data
->icld_LVMAttribs
->lmva_HeaderHeight
- 1;
3301 SetFont(data
->icld_BufferRastPort
, data
->icld_IconLabelFont
);
3303 x
= linerect
.MinX
+ HEADERLINE_SPACING_LEFT
;
3305 firstvis
= FirstVisibleColumnNumber(data
);
3306 lastvis
= LastVisibleColumnNumber(data
);
3308 for(i
= 0; i
< NUM_COLUMNS
; i
++)
3310 LONG index
= data
->icld_LVMAttribs
->lmva_ColumnPos
[i
];
3312 if (!(data
->icld_LVMAttribs
->lmva_ColumnFlags
[index
] & LVMCF_COLVISIBLE
)) continue;
3314 BOOL outside
= FALSE
;
3315 struct Rectangle field_rect
;
3317 field_rect
.MinX
= (i
== firstvis
) ? linerect
.MinX
: x
;
3318 field_rect
.MinY
= linerect
.MinY
;
3319 field_rect
.MaxX
= x
+ data
->icld_LVMAttribs
->lmva_ColumnWidth
[index
] - 1 + ((i
== lastvis
) ? HEADERLINE_SPACING_RIGHT
: 0);
3320 field_rect
.MaxY
= linerect
.MaxY
;
3322 /* data->update_rect1 and data->update_rect2 may
3323 point to rectangles to indicate that only icons
3324 in any of this rectangles need to be drawn */
3325 if (data
->update_rect1
)
3327 if (!RectAndRect(&field_rect
, data
->update_rect1
))
3331 if (data
->update_rect2
)
3333 if (data
->update_rect1
)
3335 if ((outside
== TRUE
) && RectAndRect(&field_rect
, data
->update_rect2
))
3340 if (!RectAndRect(&field_rect
, data
->update_rect2
))
3345 if (outside
!= TRUE
)
3347 RenderListViewModeHeaderField(obj
, data
, &field_rect
, index
, FALSE
);
3348 x
+= data
->icld_LVMAttribs
->lmva_ColumnWidth
[index
];
3350 #if defined(DEBUG_ILC_ICONRENDERING)
3353 D(bug("[IconList] %s: Column '%s' outside of update area .. skipping\n", __PRETTY_FUNCTION__
, data
->icld_LVMAttribs
->lmva_ColumnTitle
[i
]));
3358 if ((data
->icld_LVMAttribs
->lvma_Flags
& LVMAF_HEADERDRAWTOEND
) == LVMAF_HEADERDRAWTOEND
)
3360 x
+= HEADERLINE_SPACING_RIGHT
;
3362 if (x
< linerect
.MaxX
)
3366 // if (MustRenderRect(data, &linerect))
3368 SetABPenDrMd(data
->icld_BufferRastPort
, _pens(obj
)[MPEN_HALFSHINE
], 0, JAM1
);
3369 RectFill(data
->icld_BufferRastPort
, linerect
.MinX
, linerect
.MinY
, linerect
.MaxX
, linerect
.MaxY
);
3377 /**************************************************************************
3378 MUIM_Draw - draw the IconList
3379 **************************************************************************/
3381 IPTR
IconList__MUIM_Draw(struct IClass
*CLASS
, Object
*obj
, struct MUIP_Draw
*message
)
3383 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
3384 struct IconEntry
*entry
= NULL
;
3388 ULONG update_oldwidth
= 0,
3389 update_oldheight
= 0;
3391 LONG clear_xoffset
= 0,
3394 __unused IPTR draw_id
= DrawCount
++;
3396 #if defined(DEBUG_ILC_FUNCS)
3397 D(bug("[IconList]: %s(obj @ 0x%p)\n", __PRETTY_FUNCTION__
, obj
));
3399 #if defined(DEBUG_ILC_ICONRENDERING)
3400 D(bug("[IconList] %s: id %d\n", __PRETTY_FUNCTION__
, draw_id
));
3403 DoSuperMethodA(CLASS
, obj
, (Msg
)message
);
3405 if (!(data
->icld__Option_IconListFixedBackground
))
3407 clear_xoffset
= data
->icld_ViewX
;
3408 clear_yoffset
= data
->icld_ViewY
;
3411 // If window size changes, only update needed areas
3412 if (data
->update_oldwidth
== 0) data
->update_oldwidth
= data
->icld_ViewWidth
;
3413 if (data
->update_oldheight
== 0) data
->update_oldheight
= data
->icld_ViewHeight
;
3414 if ((data
->update_oldwidth
!= data
->icld_ViewWidth
) || (data
->update_oldheight
!= data
->icld_ViewHeight
))
3416 if (data
->icld_UpdateMode
!= UPDATE_SCROLL
)
3418 data
->icld_UpdateMode
= UPDATE_RESIZE
;
3419 update_oldwidth
= data
->update_oldwidth
;
3420 update_oldheight
= data
->update_oldheight
;
3421 data
->update_oldwidth
= data
->icld_ViewWidth
;
3422 data
->update_oldheight
= data
->icld_ViewHeight
;
3426 if ((message
->flags
& MADF_DRAWUPDATE
) || (data
->icld_UpdateMode
== UPDATE_RESIZE
))
3428 #if defined(DEBUG_ILC_ICONRENDERING)
3430 if (message
->flags
& MADF_DRAWUPDATE
)
3432 bug("[IconList] %s#%d: MADF_DRAWUPDATE\n", __PRETTY_FUNCTION__
, draw_id
);
3436 bug("[IconList] %s#%d: UPDATE_RESIZE\n", __PRETTY_FUNCTION__
, draw_id
);
3440 if ((data
->icld_UpdateMode
== UPDATE_HEADERENTRY
) && ((IPTR
)data
->update_entry
< NUM_COLUMNS
)) /* draw the header entry */
3442 struct Rectangle field_rect
;
3443 LONG index
, i
, firstvis
, lastvis
;
3445 firstvis
= FirstVisibleColumnNumber(data
);
3446 lastvis
= LastVisibleColumnNumber(data
);
3448 field_rect
.MinX
= _mleft(obj
) - data
->icld_ViewX
;
3450 field_rect
.MinY
= _mtop(obj
);
3451 field_rect
.MaxY
= field_rect
.MinY
+ data
->icld_LVMAttribs
->lmva_HeaderHeight
- 1;
3453 for(i
= 0; i
< NUM_COLUMNS
; i
++)
3455 index
= data
->icld_LVMAttribs
->lmva_ColumnPos
[i
];
3456 if (!(data
->icld_LVMAttribs
->lmva_ColumnFlags
[index
] & LVMCF_COLVISIBLE
)) continue;
3458 field_rect
.MaxX
= field_rect
.MinX
+ data
->icld_LVMAttribs
->lmva_ColumnWidth
[index
] - 1;
3459 if (index
== lastvis
)
3460 field_rect
.MaxX
+= HEADERLINE_SPACING_RIGHT
;
3462 if ((IPTR
)data
->update_entry
!= index
)
3464 field_rect
.MinX
+= data
->icld_LVMAttribs
->lmva_ColumnWidth
[index
];
3465 if (index
== firstvis
)
3466 field_rect
.MinX
+= HEADERLINE_SPACING_LEFT
;
3472 clip
= MUI_AddClipping(muiRenderInfo(obj
), _mleft(obj
), _mtop(obj
), _mright(obj
) - _mleft(obj
) + 1, data
->icld_LVMAttribs
->lmva_HeaderHeight
);
3474 if (data
->icld_LVMAttribs
->lmva_LastSelectedColumn
== (IPTR
)data
->update_entry
)
3475 RenderListViewModeHeaderField(obj
, data
, &field_rect
, (IPTR
)data
->update_entry
, TRUE
);
3477 RenderListViewModeHeaderField(obj
, data
, &field_rect
, (IPTR
)data
->update_entry
, FALSE
);
3479 data
->icld_UpdateMode
= 0;
3480 data
->update_entry
= NULL
;
3482 if (data
->icld_DisplayRastPort
!= data
->icld_BufferRastPort
)
3484 #if defined(DEBUG_ILC_ICONRENDERING)
3485 D(bug("[IconList] %s#%d: UPDATE_HEADERENTRY Blitting to front rastport..\n", __PRETTY_FUNCTION__
, draw_id
));
3487 BltBitMapRastPort(data
->icld_BufferRastPort
->BitMap
,
3488 field_rect
.MinX
- _mleft(obj
), field_rect
.MinY
- _mtop(obj
),
3489 data
->icld_DisplayRastPort
,
3490 field_rect
.MinX
, field_rect
.MinY
,
3491 field_rect
.MaxX
- field_rect
.MinX
+ 1, field_rect
.MaxY
- field_rect
.MinY
+ 1,
3494 MUI_RemoveClipping(muiRenderInfo(obj
), clip
);
3498 else if ((data
->icld_UpdateMode
== UPDATE_SINGLEENTRY
) && (data
->update_entry
!= NULL
)) /* draw only a single entry at update_entry */
3500 struct Rectangle rect
;
3502 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
3504 LONG count
= 0, index
= -1;
3506 #if defined(DEBUG_ILC_ICONRENDERING)
3507 D(bug("[IconList] %s#%d: UPDATE_SINGLEENTRY + ICONLIST_DISP_MODELIST\n", __PRETTY_FUNCTION__
, draw_id
));
3509 rect
.MinX
= _mleft(obj
);
3510 rect
.MaxX
= _mleft(obj
) + _mwidth(obj
) - 1;
3512 ForeachNode(&data
->icld_IconList
, entry
)
3514 if (entry
== data
->update_entry
)
3519 if (entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
3527 rect
.MinY
= _mtop(obj
) + data
->icld_LVMAttribs
->lmva_HeaderHeight
- data
->icld_ViewY
+ (index
* data
->icld_LVMAttribs
->lmva_RowHeight
);
3528 rect
.MaxY
= rect
.MinY
+ data
->icld_LVMAttribs
->lmva_RowHeight
- 1;
3530 if ((rect
.MaxY
< (_mtop(obj
) + data
->icld_LVMAttribs
->lmva_HeaderHeight
))
3531 || (rect
.MinY
> (_mtop(obj
) + _mheight(obj
) - 1)))
3534 if (rect
.MinY
< (_mtop(obj
) + data
->icld_LVMAttribs
->lmva_HeaderHeight
)) rect
.MinY
= _mtop(obj
) + data
->icld_LVMAttribs
->lmva_HeaderHeight
;
3535 if (rect
.MaxY
> (_mtop(obj
) + _mheight(obj
) - 1)) rect
.MaxY
= _mtop(obj
) + _mheight(obj
) - 1;
3537 clip
= MUI_AddClipping(muiRenderInfo(obj
), rect
.MinX
, rect
.MinY
, rect
.MaxX
- rect
.MinX
+ 1, rect
.MaxY
- rect
.MinY
+ 1);
3539 DoMethod(obj
, MUIM_DrawBackground
,
3540 rect
.MinX
, rect
.MinY
,
3541 rect
.MaxX
- rect
.MinX
+ 1, rect
.MaxY
- rect
.MinY
+ 1,
3542 clear_xoffset
, clear_yoffset
,
3545 entry
->ie_Flags
|= ICONENTRY_FLAG_NEEDSUPDATE
;
3546 DoMethod(obj
, MUIM_IconList_DrawEntry
, data
->update_entry
, index
);
3547 entry
->ie_Flags
&= ~ICONENTRY_FLAG_NEEDSUPDATE
;
3548 data
->icld_UpdateMode
= 0;
3549 data
->update_entry
= NULL
;
3554 #if defined(DEBUG_ILC_ICONRENDERING)
3555 D(bug("[IconList] %s#%d: UPDATE_SINGLEENTRY (entry @ 0x%p)\n", __PRETTY_FUNCTION__
, draw_id
, data
->update_entry
));
3557 IconList_GetIconAreaRectangle(obj
, data
, data
->update_entry
, &rect
);
3559 rect
.MinX
+= _mleft(obj
) + (data
->update_entry
->ie_IconX
- data
->icld_ViewX
);
3560 rect
.MaxX
+= _mleft(obj
) + (data
->update_entry
->ie_IconX
- data
->icld_ViewX
);
3561 rect
.MinY
+= _mtop(obj
) + (data
->update_entry
->ie_IconY
- data
->icld_ViewY
);
3562 rect
.MaxY
+= _mtop(obj
) + (data
->update_entry
->ie_IconY
- data
->icld_ViewY
);
3564 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
3566 if (data
->update_entry
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
3568 rect
.MinX
+= ((data
->icld_IconAreaLargestWidth
- data
->update_entry
->ie_AreaWidth
)/2);
3569 rect
.MaxX
+= ((data
->icld_IconAreaLargestWidth
- data
->update_entry
->ie_AreaWidth
)/2);
3572 if (data
->update_entry
->ie_AreaHeight
< data
->icld_IconAreaLargestHeight
)
3574 rect
.MinY
+= ((data
->icld_IconAreaLargestHeight
- data
->update_entry
->ie_AreaHeight
)/2);
3575 rect
.MaxY
+= ((data
->icld_IconAreaLargestHeight
- data
->update_entry
->ie_AreaHeight
)/2);
3579 if (rect
.MinX
< _mleft(obj
)) rect
.MinX
= _mleft(obj
);
3580 if (rect
.MaxX
> _mright(obj
)) rect
.MaxX
=_mright(obj
);
3581 if (rect
.MinY
< _mtop(obj
)) rect
.MinY
= _mtop(obj
);
3582 if (rect
.MaxY
> _mbottom(obj
)) rect
.MaxY
= _mbottom(obj
);
3584 clip
= MUI_AddClipping(muiRenderInfo(obj
), rect
.MinX
, rect
.MinY
, rect
.MaxX
- rect
.MinX
+ 1, rect
.MaxY
- rect
.MinY
+ 1);
3586 #if defined(DEBUG_ILC_ICONRENDERING)
3587 D(bug("[IconList] %s#%d: UPDATE_SINGLEENTRY: Calling MUIM_DrawBackground (A)\n", __PRETTY_FUNCTION__
, draw_id
));
3589 DoMethod(obj
, MUIM_DrawBackground
,
3590 rect
.MinX
, rect
.MinY
,
3591 rect
.MaxX
- rect
.MinX
+ 1, rect
.MaxY
- rect
.MinY
+ 1,
3592 clear_xoffset
, clear_yoffset
,
3595 /* We could have deleted also other icons so they must be redrawn */
3596 #if defined(__AROS__)
3597 ForeachNode(&data
->icld_IconList
, entry
)
3599 Foreach_Node(&data
->icld_IconList
, entry
);
3602 if ((entry
!= data
->update_entry
) && (entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
))
3604 struct Rectangle rect2
;
3605 IconList_GetIconAreaRectangle(obj
, data
, entry
, &rect2
);
3607 rect2
.MinX
+= _mleft(obj
) - data
->icld_ViewX
+ entry
->ie_IconX
;
3608 rect2
.MaxX
+= _mleft(obj
) - data
->icld_ViewX
+ entry
->ie_IconX
;
3609 rect2
.MinY
+= _mtop(obj
) - data
->icld_ViewY
+ entry
->ie_IconY
;
3610 rect2
.MaxY
+= _mtop(obj
) - data
->icld_ViewY
+ entry
->ie_IconY
;
3612 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
3614 if (entry
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
3616 rect2
.MinX
+= ((data
->icld_IconAreaLargestWidth
- entry
->ie_AreaWidth
)/2);
3617 rect2
.MaxX
+= ((data
->icld_IconAreaLargestWidth
- entry
->ie_AreaWidth
)/2);
3620 if (entry
->ie_AreaHeight
< data
->icld_IconAreaLargestHeight
)
3622 rect2
.MinY
+= ((data
->icld_IconAreaLargestHeight
- entry
->ie_AreaHeight
)/2);
3623 rect2
.MaxY
+= ((data
->icld_IconAreaLargestHeight
- entry
->ie_AreaHeight
)/2);
3627 if (RectAndRect(&rect
, &rect2
))
3629 // Update entry here
3630 entry
->ie_Flags
|= ICONENTRY_FLAG_NEEDSUPDATE
;
3631 DoMethod(obj
, MUIM_IconList_DrawEntry
, entry
, ICONENTRY_DRAWMODE_PLAIN
);
3632 DoMethod(obj
, MUIM_IconList_DrawEntryLabel
, entry
, ICONENTRY_DRAWMODE_PLAIN
);
3633 entry
->ie_Flags
&= ~ICONENTRY_FLAG_NEEDSUPDATE
;
3638 entry
->ie_Flags
|= ICONENTRY_FLAG_NEEDSUPDATE
;
3639 DoMethod(obj
, MUIM_IconList_DrawEntry
, data
->update_entry
, ICONENTRY_DRAWMODE_PLAIN
);
3640 DoMethod(obj
, MUIM_IconList_DrawEntryLabel
, data
->update_entry
, ICONENTRY_DRAWMODE_PLAIN
);
3641 entry
->ie_Flags
&= ~ICONENTRY_FLAG_NEEDSUPDATE
;
3642 data
->icld_UpdateMode
= 0;
3643 data
->update_entry
= NULL
;
3645 if (data
->update_entry
== NULL
)
3647 if (data
->icld_DisplayRastPort
!= data
->icld_BufferRastPort
)
3649 #if defined(DEBUG_ILC_ICONRENDERING)
3650 D(bug("[IconList] %s#%d: UPDATE_SINGLEENTRY Blitting to front rastport..\n", __PRETTY_FUNCTION__
, draw_id
));
3652 BltBitMapRastPort(data
->icld_BufferRastPort
->BitMap
,
3653 rect
.MinX
- _mleft(obj
), rect
.MinY
- _mtop(obj
),
3654 data
->icld_DisplayRastPort
,
3655 rect
.MinX
, rect
.MinY
,
3656 rect
.MaxX
- rect
.MinX
+ 1, rect
.MaxY
- rect
.MinY
+ 1,
3659 MUI_RemoveClipping(muiRenderInfo(obj
), clip
);
3663 else if (data
->icld_UpdateMode
== UPDATE_SCROLL
)
3665 struct Region
*region
= NULL
;
3666 struct Rectangle xrect
,
3668 BOOL scroll_caused_damage
= FALSE
;
3670 #if defined(DEBUG_ILC_ICONRENDERING)
3671 D(bug("[IconList] %s#%d: UPDATE_SCROLL.\n", __PRETTY_FUNCTION__
, draw_id
));
3674 if (!data
->icld__Option_IconListFixedBackground
)
3676 scroll_caused_damage
= (_rp(obj
)->Layer
->Flags
& LAYERREFRESH
) ? FALSE
: TRUE
;
3678 data
->icld_UpdateMode
= 0;
3680 if ((abs(data
->update_scrolldx
) >= _mwidth(obj
)) ||
3681 (abs(data
->update_scrolldy
) >= _mheight(obj
)))
3683 #if defined(DEBUG_ILC_ICONRENDERING)
3684 D(bug("[IconList] %s#%d: UPDATE_SCROLL: Moved outside current view -> Causing Redraw .. MADF_DRAWOBJECT\n", __PRETTY_FUNCTION__
, draw_id
));
3686 MUI_Redraw(obj
, MADF_DRAWOBJECT
);
3690 if (!(region
= NewRegion()))
3692 #if defined(DEBUG_ILC_ICONRENDERING)
3693 D(bug("[IconList] %s#%d: UPDATE_SCROLL: Couldnt Alloc Region -> Causing Redraw ...MADF_DRAWOBJECT\n", __PRETTY_FUNCTION__
, draw_id
));
3695 MUI_Redraw(obj
, MADF_DRAWOBJECT
);
3699 if (data
->update_scrolldx
> 0)
3701 xrect
.MinX
= _mright(obj
) - data
->update_scrolldx
;
3702 xrect
.MinY
= _mtop(obj
);
3703 xrect
.MaxX
= _mright(obj
);
3704 xrect
.MaxY
= _mbottom(obj
);
3706 OrRectRegion(region
, &xrect
);
3708 data
->update_rect1
= &xrect
;
3710 else if (data
->update_scrolldx
< 0)
3712 xrect
.MinX
= _mleft(obj
);
3713 xrect
.MinY
= _mtop(obj
);
3714 xrect
.MaxX
= _mleft(obj
) - data
->update_scrolldx
;
3715 xrect
.MaxY
= _mbottom(obj
);
3717 OrRectRegion(region
, &xrect
);
3719 data
->update_rect1
= &xrect
;
3722 if (data
->update_scrolldy
> 0)
3724 yrect
.MinX
= _mleft(obj
);
3725 yrect
.MinY
= _mbottom(obj
) - data
->update_scrolldy
;
3726 if (((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
3727 && (yrect
.MinY
< (_mtop(obj
) + data
->icld_LVMAttribs
->lmva_HeaderHeight
)))
3729 xrect
.MinY
= data
->icld_LVMAttribs
->lmva_HeaderHeight
;
3731 yrect
.MaxX
= _mright(obj
);
3732 yrect
.MaxY
= _mbottom(obj
);
3734 OrRectRegion(region
, &yrect
);
3736 data
->update_rect2
= &yrect
;
3738 else if (data
->update_scrolldy
< 0)
3740 yrect
.MinX
= _mleft(obj
);
3741 yrect
.MinY
= _mtop(obj
);
3742 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
3744 xrect
.MinY
+= data
->icld_LVMAttribs
->lmva_HeaderHeight
;
3746 yrect
.MaxX
= _mright(obj
);
3747 yrect
.MaxY
= _mtop(obj
) - data
->update_scrolldy
;
3749 OrRectRegion(region
, &yrect
);
3751 data
->update_rect2
= &yrect
;
3754 #if defined(DEBUG_ILC_ICONRENDERING)
3755 D(bug("[IconList] %s#%d: UPDATE_SCROLL: Scrolling Raster..\n", __PRETTY_FUNCTION__
, draw_id
));
3757 if (data
->icld_DisplayRastPort
== data
->icld_BufferRastPort
)
3759 ScrollRasterBF(data
->icld_BufferRastPort
,
3760 data
->update_scrolldx
,
3761 data
->update_scrolldy
,
3769 ScrollRasterBF(data
->icld_BufferRastPort
,
3770 data
->update_scrolldx
,
3771 data
->update_scrolldy
,
3778 scroll_caused_damage
= scroll_caused_damage
&& (_rp(obj
)->Layer
->Flags
& LAYERREFRESH
) ? TRUE
: FALSE
;
3780 clip
= MUI_AddClipRegion(muiRenderInfo(obj
), region
);
3783 #if defined(DEBUG_ILC_ICONRENDERING)
3784 D(bug("[IconList] %s#%d: UPDATE_SCROLL: Causing Redraw -> MADF_DRAWOBJECT..\n", __PRETTY_FUNCTION__
, draw_id
));
3786 MUI_Redraw(obj
, MADF_DRAWOBJECT
);
3788 data
->update_rect1
= data
->update_rect2
= NULL
;
3790 if (!data
->icld__Option_IconListFixedBackground
)
3792 MUI_RemoveClipRegion(muiRenderInfo(obj
), clip
);
3794 if (scroll_caused_damage
)
3796 if (MUI_BeginRefresh(muiRenderInfo(obj
), 0))
3798 /* Theoretically it might happen that more damage is caused
3799 after ScrollRaster. By something else, like window movement
3800 in front of our window. Therefore refresh root object of
3801 window, not just this object */
3805 GET(_win(obj
),MUIA_Window_RootObject
, &o
);
3806 MUI_Redraw(o
, MADF_DRAWOBJECT
);
3807 #if defined(DEBUG_ILC_ICONRENDERING)
3808 D(bug("[IconList] %s#%d: UPDATE_SCROLL: Causing Redraw -> MADF_DRAWOBJECT..\n", __PRETTY_FUNCTION__
, draw_id
));
3810 MUI_EndRefresh(muiRenderInfo(obj
), 0);
3814 if (data
->icld_DisplayRastPort
!= data
->icld_BufferRastPort
)
3816 #if defined(DEBUG_ILC_ICONRENDERING)
3817 D(bug("[IconList] %s#%d: UPDATE_SCROLL: Blitting to front rastport..\n", __PRETTY_FUNCTION__
, draw_id
));
3819 BltBitMapRastPort(data
->icld_BufferRastPort
->BitMap
,
3821 data
->icld_DisplayRastPort
,
3822 _mleft(obj
), _mtop(obj
),
3823 _mwidth(obj
), _mheight(obj
),
3828 else if (data
->icld_UpdateMode
== UPDATE_RESIZE
)
3830 struct Region
*region
= NULL
;
3831 struct Rectangle wrect
,
3836 #if defined(DEBUG_ILC_ICONRENDERING)
3837 D(bug("[IconList] %s#%d: UPDATE_RESIZE.\n", __PRETTY_FUNCTION__
, draw_id
));
3840 if ((data
->icld_BufferRastPort
) && (data
->icld_BufferRastPort
!= data
->icld_DisplayRastPort
))
3842 //Free up the buffers Layer, rastport and bitmap so we can replace them ..
3843 if ((GetBitMapAttr(data
->icld_BufferRastPort
->BitMap
, BMA_WIDTH
) != data
->icld_ViewWidth
)
3844 || (GetBitMapAttr(data
->icld_BufferRastPort
->BitMap
, BMA_HEIGHT
) != data
->icld_ViewHeight
))
3846 struct Layer
*oldLayer
= data
->icld_BufferRastPort
->Layer
;
3847 #if defined(DEBUG_ILC_ATTRIBS) || defined(DEBUG_ILC_ICONRENDERING)
3848 D(bug("[IconList] %s: Destroying old BackLayer\n", __PRETTY_FUNCTION__
));
3850 data
->icld_BufferRastPort
= data
->icld_DisplayRastPort
;
3851 DeleteLayer(0, oldLayer
);
3854 if (data
->icld_BufferRastPort
== data
->icld_DisplayRastPort
)
3856 struct BitMap
*bitmap_New
;
3857 ULONG tmp_RastDepth
;
3858 struct Layer_Info
*li
= NULL
;
3860 tmp_RastDepth
= GetCyberMapAttr(data
->icld_DisplayRastPort
->BitMap
, CYBRMATTR_DEPTH
);
3861 if ((bitmap_New
= AllocBitMap(data
->icld_ViewWidth
,
3862 data
->icld_ViewHeight
,
3865 data
->icld_DisplayRastPort
->BitMap
)) != NULL
)
3867 if ((data
->icld_BufferRastPort
= CreateRastPort()) != NULL
)
3869 data
->icld_BufferRastPort
->BitMap
= bitmap_New
;
3870 if ((li
= NewLayerInfo()))
3872 if ((data
->icld_BufferRastPort
->Layer
= CreateUpfrontLayer(li
, data
->icld_BufferRastPort
->BitMap
, 0, 0, data
->icld_ViewWidth
- 1, data
->icld_ViewHeight
- 1, 0, NULL
)))
3875 * Mark it as a buffered rastport.
3878 #if defined(DEBUG_ILC_ATTRIBS) || defined(DEBUG_ILC_ICONRENDERING)
3879 D(bug("[IconList] %s: FrontRastPort @ %p, New BackLayer @ %p, BackRastport @ %p\n", __PRETTY_FUNCTION__
, data
->icld_DisplayRastPort
, data
->icld_BufferRastPort
->Layer
, data
->icld_BufferRastPort
));
3881 SET(obj
, MUIA_IconList_BufferRastport
, data
->icld_BufferRastPort
);
3882 data
->icld_DrawOffsetX
= 0;
3883 data
->icld_DrawOffsetY
= 0;
3886 data
->icld_BufferRastPort
= data
->icld_DisplayRastPort
;
3889 data
->icld_BufferRastPort
= data
->icld_DisplayRastPort
;
3892 data
->icld_BufferRastPort
= data
->icld_DisplayRastPort
;
3895 if (data
->icld_BufferRastPort
== data
->icld_DisplayRastPort
)
3897 if (bitmap_New
) FreeBitMap(bitmap_New
);
3898 if (li
) DisposeLayerInfo(li
);
3899 data
->icld_DrawOffsetX
= _mleft(obj
);
3900 data
->icld_DrawOffsetY
= _mtop(obj
);
3905 data
->icld_UpdateMode
= 0;
3907 if (!data
->icld__Option_IconListScaledBackground
)
3909 if (!(region
= NewRegion()))
3911 #if defined(DEBUG_ILC_ICONRENDERING)
3912 D(bug("[IconList] %s#%d: UPDATE_RESIZE: Causing Redraw -> MADF_DRAWOBJECT..\n", __PRETTY_FUNCTION__
, draw_id
));
3914 MUI_Redraw(obj
, MADF_DRAWOBJECT
);
3918 if ( data
->icld_ViewWidth
> update_oldwidth
)
3919 diffw
= data
->icld_ViewWidth
- update_oldwidth
;
3920 if ( data
->icld_ViewHeight
> update_oldheight
)
3921 diffh
= data
->icld_ViewHeight
- update_oldheight
;
3925 wrect
.MinX
= _mright(obj
) - diffw
;
3926 wrect
.MinY
= _mtop(obj
);
3927 wrect
.MaxX
= _mright(obj
);
3928 wrect
.MaxY
= _mbottom(obj
);
3929 OrRectRegion(region
, &wrect
);
3930 data
->update_rect1
= &wrect
;
3935 hrect
.MinX
= _mleft(obj
);
3936 hrect
.MinY
= _mbottom(obj
) - diffh
;
3937 hrect
.MaxX
= _mright(obj
);
3938 hrect
.MaxX
= _mright(obj
);
3939 hrect
.MaxY
= _mbottom(obj
);
3940 OrRectRegion(region
, &hrect
);
3941 data
->update_rect2
= &hrect
;
3945 clip
= MUI_AddClipRegion(muiRenderInfo(obj
), region
);
3949 /* View became smaller both in horizontal and vertical direction.
3952 DisposeRegion(region
);
3957 #if defined(DEBUG_ILC_ICONRENDERING)
3958 D(bug("[IconList] %s#%d: UPDATE_RESIZE: Causing Redraw -> MADF_DRAWOBJECT..\n", __PRETTY_FUNCTION__
, draw_id
));
3960 MUI_Redraw(obj
, MADF_DRAWOBJECT
);
3962 if (!data
->icld__Option_IconListScaledBackground
)
3966 data
->update_rect1
= data
->update_rect2
= NULL
;
3967 MUI_RemoveClipRegion(muiRenderInfo(obj
), clip
);
3968 } else DisposeRegion(region
);
3975 if (message
->flags
& MADF_DRAWOBJECT
)
3977 struct Rectangle viewrect
;
3978 int current
= 0, first
= 0, visible
= 0;
3980 #if defined(DEBUG_ILC_ICONRENDERING)
3981 D(bug("[IconList] %s#%d: MADF_DRAWOBJECT\n", __PRETTY_FUNCTION__
, draw_id
));
3984 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
3986 clip
= MUI_AddClipping(muiRenderInfo(obj
), _mleft(obj
), _mtop(obj
), _mwidth(obj
), data
->icld_LVMAttribs
->lmva_HeaderHeight
);
3987 RenderListViewModeHeader(obj
, data
);
3989 if (data
->icld_DisplayRastPort
!= data
->icld_BufferRastPort
)
3991 #if defined(DEBUG_ILC_ICONRENDERING)
3992 D(bug("[IconList] %s#%d: MADF_DRAWOBJECT Blitting Header to front rastport..\n", __PRETTY_FUNCTION__
, draw_id
));
3994 BltBitMapRastPort(data
->icld_BufferRastPort
->BitMap
,
3996 data
->icld_DisplayRastPort
,
3997 _mleft(obj
), _mtop(obj
), _mwidth(obj
), data
->icld_LVMAttribs
->lmva_HeaderHeight
,
4001 MUI_RemoveClipping(muiRenderInfo(obj
), clip
);
4003 viewrect
.MinY
= _mtop(obj
) + data
->icld_LVMAttribs
->lmva_HeaderHeight
;
4005 first
= FirstVisibleLine(data
);
4006 visible
= NumVisibleLines(data
);
4008 clip
= MUI_AddClipping(muiRenderInfo(obj
), _mleft(obj
), _mtop(obj
) + data
->icld_LVMAttribs
->lmva_HeaderHeight
, _mwidth(obj
), _mheight(obj
) - data
->icld_LVMAttribs
->lmva_HeaderHeight
);
4012 viewrect
.MinY
= _mtop(obj
);
4013 clip
= MUI_AddClipping(muiRenderInfo(obj
), _mleft(obj
), _mtop(obj
), _mwidth(obj
), _mheight(obj
));
4016 viewrect
.MaxY
= _mtop(obj
) + _mheight(obj
) - 1;
4017 viewrect
.MinX
= _mleft(obj
);
4018 viewrect
.MaxX
= _mleft(obj
) + _mwidth(obj
) - 1;
4020 #if defined(DEBUG_ILC_ICONRENDERING)
4021 D(bug("[IconList] %s#%d: MADF_DRAWOBJECT: Calling MUIM_DrawBackground (B)\n", __PRETTY_FUNCTION__
, draw_id
));
4024 obj
, MUIM_DrawBackground
, viewrect
.MinX
, viewrect
.MinY
, (viewrect
.MaxX
- viewrect
.MinX
) + 1, (viewrect
.MaxY
- viewrect
.MinY
) + 1,
4025 clear_xoffset
, clear_yoffset
, 0
4027 #if defined(__AROS__)
4028 ForeachNode(&data
->icld_IconList
, entry
)
4030 Foreach_Node(&data
->icld_IconList
, entry
);
4033 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
4035 if (entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
4037 if ((current
>= first
) && (current
<= (first
+ visible
)))
4039 DoMethod(obj
, MUIM_IconList_DrawEntry
, entry
, current
);
4046 if ((entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
) &&
4047 (entry
->ie_DiskObj
) &&
4048 (entry
->ie_IconX
!= NO_ICON_POSITION
) &&
4049 (entry
->ie_IconY
!= NO_ICON_POSITION
))
4051 struct Rectangle iconrect
;
4052 IconList_GetIconAreaRectangle(obj
, data
, entry
, &iconrect
);
4054 iconrect
.MinX
+= viewrect
.MinX
- data
->icld_ViewX
+ entry
->ie_IconX
;
4055 iconrect
.MaxX
+= viewrect
.MinX
- data
->icld_ViewX
+ entry
->ie_IconX
;
4056 iconrect
.MinY
+= viewrect
.MinY
- data
->icld_ViewY
+ entry
->ie_IconY
;
4057 iconrect
.MaxY
+= viewrect
.MinY
- data
->icld_ViewY
+ entry
->ie_IconY
;
4059 if (RectAndRect(&viewrect
, &iconrect
))
4061 DoMethod(obj
, MUIM_IconList_DrawEntry
, entry
, ICONENTRY_DRAWMODE_PLAIN
);
4062 DoMethod(obj
, MUIM_IconList_DrawEntryLabel
, entry
, ICONENTRY_DRAWMODE_PLAIN
);
4068 if (data
->icld_DisplayRastPort
!= data
->icld_BufferRastPort
)
4070 #if defined(DEBUG_ILC_ICONRENDERING)
4071 D(bug("[IconList] %s#%d: MADF_DRAWOBJECT: Blitting to front rastport..\n", __PRETTY_FUNCTION__
, draw_id
));
4073 BltBitMapRastPort(data
->icld_BufferRastPort
->BitMap
,
4075 data
->icld_DisplayRastPort
,
4076 _mleft(obj
), _mtop(obj
),
4077 _mwidth(obj
), _mheight(obj
),
4081 MUI_RemoveClipping(muiRenderInfo(obj
), clip
);
4083 data
->icld_UpdateMode
= 0;
4087 #if defined(DEBUG_ILC_ICONRENDERING)
4088 D(bug("[IconList] %s: Draw finished for id %d\n", __PRETTY_FUNCTION__
, draw_id
));
4094 ///IconList__MUIM_IconList_Update()
4095 /**************************************************************************
4096 MUIM_IconList_Refresh
4097 Implemented by subclasses
4098 **************************************************************************/
4099 IPTR
IconList__MUIM_IconList_Update(struct IClass
*CLASS
, Object
*obj
, struct MUIP_IconList_Update
*message
)
4101 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
4103 #if defined(DEBUG_ILC_FUNCS)
4104 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
4107 data
->icld_FocusIcon
= NULL
;
4108 SET(obj
, MUIA_IconList_Changed
, TRUE
);
4114 ///MUIM_IconList_Clear()
4115 /**************************************************************************
4117 **************************************************************************/
4118 IPTR
IconList__MUIM_IconList_Clear(struct IClass
*CLASS
, Object
*obj
, struct MUIP_IconList_Clear
*message
)
4120 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
4121 struct IconEntry
*node
= NULL
;
4123 #if defined(DEBUG_ILC_FUNCS)
4124 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
4127 while ((node
= (struct IconEntry
*)RemTail((struct List
*)&data
->icld_IconList
)))
4129 DoMethod(obj
, MUIM_IconList_DestroyEntry
, node
);
4132 data
->icld_SelectionLastClicked
= NULL
;
4133 data
->icld_FocusIcon
= NULL
;
4135 data
->icld_ViewX
= data
->icld_ViewY
= data
->icld_AreaWidth
= data
->icld_AreaHeight
= 0;
4136 data
->icld_IconAreaLargestWidth
= 0;
4137 data
->icld_IconAreaLargestHeight
= 0;
4138 data
->icld_IconLargestHeight
= 0;
4139 data
->icld_LabelLargestHeight
= 0;
4141 #if defined(DEBUG_ILC_ICONRENDERING)
4142 D(bug("[IconList]: %s: call SetSuperAttrs()\n", __PRETTY_FUNCTION__
));
4144 SetSuperAttrs(CLASS
, obj
, MUIA_Virtgroup_Left
, data
->icld_ViewX
,
4145 MUIA_Virtgroup_Top
, data
->icld_ViewY
,
4148 #if defined(DEBUG_ILC_ICONRENDERING)
4149 D(bug("[IconList]: %s: call SetAttrs()\n", __PRETTY_FUNCTION__
));
4151 SetAttrs(obj
, MUIA_Virtgroup_Left
, data
->icld_ViewX
,
4152 MUIA_Virtgroup_Top
, data
->icld_ViewY
,
4155 #if defined(DEBUG_ILC_ICONRENDERING)
4156 D(bug("[IconList]: %s: Set MUIA_IconList_Width and MUIA_IconList_Height\n", __PRETTY_FUNCTION__
));
4158 SetAttrs(obj
, MUIA_IconList_Width
, data
->icld_AreaWidth
,
4159 MUIA_IconList_Height
, data
->icld_AreaHeight
,
4162 D(bug("[IconList]: %s: call MUI_Redraw()\n", __PRETTY_FUNCTION__
));
4163 MUI_Redraw(obj
,MADF_DRAWOBJECT
);
4168 ///IconList__MUIM_IconList_DestroyEntry()
4169 IPTR
IconList__MUIM_IconList_DestroyEntry(struct IClass
*CLASS
, Object
*obj
, struct MUIP_IconList_DestroyEntry
*message
)
4171 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
4173 #if defined(DEBUG_ILC_FUNCS)
4174 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
4179 if (message
->entry
->ie_Flags
& ICONENTRY_FLAG_SELECTED
)
4181 if (data
->icld_SelectionLastClicked
== message
->entry
)
4183 struct IconList_Entry
*nextentry
= &message
->entry
->ie_IconListEntry
;
4185 /* get selected entries from SOURCE iconlist */
4186 DoMethod(obj
, MUIM_IconList_NextIcon
, MUIV_IconList_NextIcon_Selected
, (IPTR
)&nextentry
);
4187 if ((nextentry
) && ((IPTR
)nextentry
!= MUIV_IconList_NextIcon_End
))
4188 data
->icld_SelectionLastClicked
= (struct IconEntry
*)((IPTR
)nextentry
- ((IPTR
)&message
->entry
->ie_IconListEntry
- (IPTR
)message
->entry
));
4190 data
->icld_SelectionLastClicked
= NULL
;
4192 if (data
->icld_FocusIcon
== message
->entry
)
4193 data
->icld_FocusIcon
= data
->icld_SelectionLastClicked
;
4195 Remove(&message
->entry
->ie_SelectionNode
);
4198 if (message
->entry
->ie_TxtBuf_DisplayedLabel
)
4199 FreeVecPooled(data
->icld_Pool
, message
->entry
->ie_TxtBuf_DisplayedLabel
);
4201 if (message
->entry
->ie_TxtBuf_PROT
)
4202 FreePooled(data
->icld_Pool
, message
->entry
->ie_TxtBuf_PROT
, 8);
4204 if (message
->entry
->ie_TxtBuf_SIZE
)
4205 FreePooled(data
->icld_Pool
, message
->entry
->ie_TxtBuf_SIZE
, 30);
4207 if (message
->entry
->ie_TxtBuf_TIME
)
4208 FreePooled(data
->icld_Pool
, message
->entry
->ie_TxtBuf_TIME
, LEN_DATSTRING
);
4210 if (message
->entry
->ie_TxtBuf_DATE
)
4211 FreePooled(data
->icld_Pool
, message
->entry
->ie_TxtBuf_DATE
, LEN_DATSTRING
);
4213 if (message
->entry
->ie_DiskObj
)
4214 FreeDiskObject(message
->entry
->ie_DiskObj
);
4216 if (message
->entry
->ie_FileInfoBlock
)
4217 FreeMem(message
->entry
->ie_FileInfoBlock
, sizeof(struct FileInfoBlock
));
4219 if (message
->entry
->ie_IconListEntry
.label
)
4220 FreePooled(data
->icld_Pool
, message
->entry
->ie_IconListEntry
.label
, strlen(message
->entry
->ie_IconListEntry
.label
)+1);
4222 if (message
->entry
->ie_IconNode
.ln_Name
)
4223 FreePooled(data
->icld_Pool
, message
->entry
->ie_IconNode
.ln_Name
, strlen(message
->entry
->ie_IconNode
.ln_Name
)+1);
4225 FreePooled(data
->icld_Pool
, message
->entry
, sizeof(struct IconEntry
));
4231 ///IconList__MUIM_IconList_PropagateEntryPos()
4232 IPTR
IconList__MUIM_IconList_PropagateEntryPos(struct IClass
*CLASS
, Object
*obj
,
4233 struct MUIP_IconList_PropagateEntryPos
*message
)
4235 message
->entry
->ie_ProvidedIconX
= message
->entry
->ie_IconX
;
4236 message
->entry
->ie_ProvidedIconY
= message
->entry
->ie_IconY
;
4242 ///IconList__MUIM_IconList_CreateEntry()
4243 /**************************************************************************
4244 MUIM_IconList_CreateEntry.
4245 Returns 0 on failure; otherwise it returns the icon's entry.
4246 **************************************************************************/
4247 IPTR
IconList__MUIM_IconList_CreateEntry(struct IClass
*CLASS
, Object
*obj
, struct MUIP_IconList_CreateEntry
*message
)
4249 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
4250 struct IconEntry
*entry
= NULL
;
4252 struct DateStamp now
;
4255 struct DiskObject
*dob
= NULL
;
4256 struct Rectangle rect
;
4258 IPTR geticon_error
= 0;
4260 #if defined(DEBUG_ILC_FUNCS)
4261 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
4264 if (message
->filename
== NULL
) {
4265 D(bug("[IconList] %s: IconList - filename was NULL\n", __PRETTY_FUNCTION__
));
4269 /*disk object (icon)*/
4270 if (message
->entry_dob
== NULL
)
4272 IPTR iconlistScreen
= (IPTR
)_screen(obj
);
4273 D(bug("[IconList] %s: IconList Screen @ 0x%p)\n", __PRETTY_FUNCTION__
, iconlistScreen
));
4278 (iconlistScreen
) ? ICONGETA_Screen
: TAG_IGNORE
, iconlistScreen
,
4279 (iconlistScreen
) ? ICONGETA_RemapIcon
: TAG_IGNORE
, TRUE
,
4280 ICONGETA_FailIfUnavailable
, FALSE
,
4281 ICONGETA_GenerateImageMasks
, TRUE
,
4282 ICONA_ErrorCode
, &geticon_error
,
4288 D(bug("[IconList] %s: Fatal: Couldnt get DiskObject! (error code = 0x%p)\n", __PRETTY_FUNCTION__
, geticon_error
));
4295 dob
= message
->entry_dob
;
4298 D(bug("[IconList] %s: DiskObject @ 0x%p\n", __PRETTY_FUNCTION__
, dob
));
4300 if ((entry
= AllocPooled(data
->icld_Pool
, sizeof(struct IconEntry
))) == NULL
)
4302 D(bug("[IconList] %s: Failed to Allocate Entry Storage!\n", __PRETTY_FUNCTION__
));
4303 FreeDiskObject(dob
);
4306 memset(entry
, 0, sizeof(struct IconEntry
));
4307 entry
->ie_Flags
|= ICONENTRY_FLAG_NEEDSUPDATE
;
4308 entry
->ie_IconListEntry
.ile_IconEntry
= entry
;
4310 /* Allocate Text Buffers */
4312 if ((entry
->ie_TxtBuf_DATE
= AllocPooled(data
->icld_Pool
, LEN_DATSTRING
)) == NULL
)
4314 D(bug("[IconList] %s: Failed to Allocate Entry DATE Storage!\n", __PRETTY_FUNCTION__
));
4315 DoMethod(obj
, MUIM_IconList_DestroyEntry
, entry
);
4318 memset(entry
->ie_TxtBuf_DATE
, 0, LEN_DATSTRING
);
4320 if ((entry
->ie_TxtBuf_TIME
= AllocPooled(data
->icld_Pool
, LEN_DATSTRING
)) == NULL
)
4322 D(bug("[IconList] %s: Failed to Allocate Entry TIME string Storage!\n", __PRETTY_FUNCTION__
));
4323 DoMethod(obj
, MUIM_IconList_DestroyEntry
, entry
);
4326 memset(entry
->ie_TxtBuf_TIME
, 0, LEN_DATSTRING
);
4328 if ((entry
->ie_TxtBuf_SIZE
= AllocPooled(data
->icld_Pool
, 30)) == NULL
)
4330 D(bug("[IconList] %s: Failed to Allocate Entry SIZE string Storage!\n", __PRETTY_FUNCTION__
));
4331 DoMethod(obj
, MUIM_IconList_DestroyEntry
, entry
);
4334 memset(entry
->ie_TxtBuf_SIZE
, 0, 30);
4336 if ((entry
->ie_TxtBuf_PROT
= AllocPooled(data
->icld_Pool
, 8)) == NULL
)
4338 D(bug("[IconList] %s: Failed to Allocate Entry PROT Flag string Storage!\n", __PRETTY_FUNCTION__
));
4339 DoMethod(obj
, MUIM_IconList_DestroyEntry
, entry
);
4342 memset(entry
->ie_TxtBuf_PROT
, 0, 8);
4345 if ((entry
->ie_IconNode
.ln_Name
= AllocPooled(data
->icld_Pool
, strlen(message
->filename
) + 1)) == NULL
)
4347 D(bug("[IconList] %s: Failed to Allocate Entry filename string Storage!\n", __PRETTY_FUNCTION__
));
4348 DoMethod(obj
, MUIM_IconList_DestroyEntry
, entry
);
4352 /*alloc entry label*/
4353 if ((entry
->ie_IconListEntry
.label
= AllocPooled(data
->icld_Pool
, strlen(message
->label
) + 1)) == NULL
)
4355 D(bug("[IconList] %s: Failed to Allocate Entry label string Storage!\n", __PRETTY_FUNCTION__
));
4356 DoMethod(obj
, MUIM_IconList_DestroyEntry
, entry
);
4361 if(message
->fib
!= NULL
)
4363 if ((entry
->ie_FileInfoBlock
= AllocMem(sizeof(struct FileInfoBlock
), MEMF_CLEAR
)) != NULL
)
4365 CopyMem(message
->fib
, entry
->ie_FileInfoBlock
, sizeof(struct FileInfoBlock
));
4367 if (entry
->ie_FileInfoBlock
->fib_DirEntryType
> 0)
4369 strcpy(entry
->ie_TxtBuf_SIZE
, "Drawer");
4373 FmtSizeToString(entry
->ie_TxtBuf_SIZE
, entry
->ie_FileInfoBlock
->fib_Size
);
4376 dt
.dat_Stamp
= entry
->ie_FileInfoBlock
->fib_Date
;
4377 dt
.dat_Format
= FORMAT_DEF
;
4379 dt
.dat_StrDay
= NULL
;
4380 dt
.dat_StrDate
= entry
->ie_TxtBuf_DATE
;
4381 dt
.dat_StrTime
= entry
->ie_TxtBuf_TIME
;
4386 /*if modified today show time, otherwise just show date*/
4387 if (now
.ds_Days
== entry
->ie_FileInfoBlock
->fib_Date
.ds_Days
)
4388 entry
->ie_Flags
|= ICONENTRY_FLAG_TODAY
;
4390 entry
->ie_Flags
&= ~ICONENTRY_FLAG_TODAY
;
4392 sp
= entry
->ie_TxtBuf_PROT
;
4393 *sp
++ = (entry
->ie_FileInfoBlock
->fib_Protection
& FIBF_SCRIPT
) ? 's' : '-';
4394 *sp
++ = (entry
->ie_FileInfoBlock
->fib_Protection
& FIBF_PURE
) ? 'p' : '-';
4395 *sp
++ = (entry
->ie_FileInfoBlock
->fib_Protection
& FIBF_ARCHIVE
) ? 'a' : '-';
4396 *sp
++ = (entry
->ie_FileInfoBlock
->fib_Protection
& FIBF_READ
) ? '-' : 'r';
4397 *sp
++ = (entry
->ie_FileInfoBlock
->fib_Protection
& FIBF_WRITE
) ? '-' : 'w';
4398 *sp
++ = (entry
->ie_FileInfoBlock
->fib_Protection
& FIBF_EXECUTE
) ? '-' : 'e';
4399 *sp
++ = (entry
->ie_FileInfoBlock
->fib_Protection
& FIBF_DELETE
) ? '-' : 'd';
4402 entry
->ie_IconListEntry
.type
= entry
->ie_FileInfoBlock
->fib_DirEntryType
;
4407 entry
->ie_IconListEntry
.type
= ST_USERDIR
;
4410 /* Override type if specified during CreateEntry */
4411 if (message
->type
!= 0)
4413 entry
->ie_IconListEntry
.type
= message
->type
;
4414 D(bug("[IconList] %s: Overide Entry Type. New Type = %x\n", __PRETTY_FUNCTION__
, entry
->ie_IconListEntry
.type
));
4418 D(bug("[IconList] %s: Entry Type = %x\n", __PRETTY_FUNCTION__
, entry
->ie_IconListEntry
.type
));
4421 strcpy(entry
->ie_IconNode
.ln_Name
, message
->filename
);
4422 strcpy(entry
->ie_IconListEntry
.label
, message
->label
);
4424 entry
->ie_IconListEntry
.udata
= message
->udata
;
4426 entry
->ie_IconX
= dob
->do_CurrentX
;
4427 entry
->ie_IconY
= dob
->do_CurrentY
;
4429 DoMethod(obj
, MUIM_IconList_PropagateEntryPos
, entry
);
4431 if (IconList__LabelFunc_CreateLabel(obj
, data
, entry
) != (IPTR
)NULL
)
4433 entry
->ie_DiskObj
= dob
;
4435 /* Use a geticonrectangle routine that gets textwidth! */
4436 IconList_GetIconAreaRectangle(obj
, data
, entry
, &rect
);
4441 DoMethod(obj
, MUIM_IconList_DestroyEntry
, entry
);
4446 ///IconList__MUIM_IconList_UpdateEntry()
4447 /**************************************************************************
4448 MUIM_IconList_UpdateEntry.
4449 Returns 0 on failure; otherwise it returns the icon's entry.
4450 **************************************************************************/
4451 IPTR
IconList__MUIM_IconList_UpdateEntry(struct IClass
*CLASS
, Object
*obj
, struct MUIP_IconList_UpdateEntry
*message
)
4453 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
4454 // struct DateTime dt;
4455 // struct DateStamp now;
4456 // UBYTE *sp = NULL;
4458 // struct DiskObject *dob = NULL;
4459 struct Rectangle rect
;
4461 // IPTR geticon_error = 0;
4463 #if defined(DEBUG_ILC_FUNCS)
4464 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
4467 /* Update disk object (icon)*/
4468 /* if (message->entry_dob == NULL)
4470 IPTR iconlistScreen = _screen(obj);
4471 D(bug("[IconList] %s: IconList Screen @ 0x%p)\n", __PRETTY_FUNCTION__, iconlistScreen));
4476 (iconlistScreen) ? ICONGETA_Screen : TAG_IGNORE, iconlistScreen,
4477 (iconlistScreen) ? ICONGETA_RemapIcon : TAG_IGNORE, TRUE,
4478 ICONGETA_FailIfUnavailable, FALSE,
4479 ICONGETA_GenerateImageMasks, TRUE,
4480 ICONA_ErrorCode, &geticon_error,
4486 D(bug("[IconList] %s: Fatal: Couldnt get DiskObject! (error code = 0x%p)\n", __PRETTY_FUNCTION__, geticon_error));
4493 dob = message->entry_dob;
4496 D(bug("[IconList] %s: DiskObject @ 0x%p\n", __PRETTY_FUNCTION__, dob));
4499 /* Update filename */
4500 if (strcmp(message
->entry
->ie_IconNode
.ln_Name
, message
->filename
) != 0)
4502 message
->entry
->ie_Flags
|= ICONENTRY_FLAG_NEEDSUPDATE
;
4503 FreePooled(data
->icld_Pool
, message
->entry
->ie_IconNode
.ln_Name
, strlen(message
->entry
->ie_IconNode
.ln_Name
) + 1);
4504 if ((message
->entry
->ie_IconNode
.ln_Name
= AllocPooled(data
->icld_Pool
, strlen(message
->filename
) + 1)) == NULL
)
4506 D(bug("[IconList] %s: Failed to Allocate Entry filename string Storage!\n", __PRETTY_FUNCTION__
));
4507 DoMethod(obj
, MUIM_IconList_DestroyEntry
, message
->entry
);
4510 strcpy(message
->entry
->ie_IconNode
.ln_Name
, message
->filename
);
4513 /* Update entry label */
4514 if (strcmp(message
->entry
->ie_IconListEntry
.label
, message
->label
) != 0)
4516 message
->entry
->ie_Flags
|= ICONENTRY_FLAG_NEEDSUPDATE
;
4517 FreePooled(data
->icld_Pool
, message
->entry
->ie_IconListEntry
.label
, strlen(message
->entry
->ie_IconListEntry
.label
) + 1);
4518 if ((message
->entry
->ie_IconListEntry
.label
= AllocPooled(data
->icld_Pool
, strlen(message
->label
) + 1)) == NULL
)
4520 D(bug("[IconList] %s: Failed to Allocate Entry label string Storage!\n", __PRETTY_FUNCTION__
));
4521 DoMethod(obj
, MUIM_IconList_DestroyEntry
, message
->entry
);
4524 strcpy(message
->entry
->ie_IconListEntry
.label
, message
->label
);
4525 if (IconList__LabelFunc_CreateLabel(obj
, data
, message
->entry
) == (IPTR
)NULL
)
4527 D(bug("[IconList] %s: Failed to create label\n", __PRETTY_FUNCTION__
));
4528 DoMethod(obj
, MUIM_IconList_DestroyEntry
, message
->entry
);
4533 /* Update file info block */
4534 if(message
->fib
!= NULL
)
4536 if (!(message
->entry
->ie_FileInfoBlock
))
4538 if ((message
->entry
->ie_FileInfoBlock
= AllocMem(sizeof(struct FileInfoBlock
), MEMF_CLEAR
)) != NULL
)
4540 CopyMem(message
->fib
, message
->entry
->ie_FileInfoBlock
, sizeof(struct FileInfoBlock
));
4544 /* if (entry->ie_FileInfoBlock->fib_DirEntryType > 0)
4546 strcpy(entry->ie_TxtBuf_SIZE, "Drawer");
4550 FmtSizeToString(entry->ie_TxtBuf_SIZE, entry->ie_FileInfoBlock->fib_Size);
4553 dt.dat_Stamp = entry->ie_FileInfoBlock->fib_Date;
4554 dt.dat_Format = FORMAT_DEF;
4556 dt.dat_StrDay = NULL;
4557 dt.dat_StrDate = entry->ie_TxtBuf_DATE;
4558 dt.dat_StrTime = entry->ie_TxtBuf_TIME;
4563 //if modified today show time, otherwise just show date
4564 if (now.ds_Days == entry->ie_FileInfoBlock->fib_Date.ds_Days)
4565 entry->ie_Flags |= ICONENTRY_FLAG_TODAY;
4567 entry->ie_Flags &= ~ICONENTRY_FLAG_TODAY;
4569 sp = entry->ie_TxtBuf_PROT;
4570 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_SCRIPT) ? 's' : '-';
4571 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_PURE) ? 'p' : '-';
4572 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_ARCHIVE) ? 'a' : '-';
4573 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_READ) ? '-' : 'r';
4574 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_WRITE) ? '-' : 'w';
4575 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_EXECUTE) ? '-' : 'e';
4576 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_DELETE) ? '-' : 'd';
4579 entry->ie_IconListEntry.type = entry->ie_FileInfoBlock->fib_DirEntryType;
4584 if (message
->entry
->ie_FileInfoBlock
)
4586 FreeMem(message
->entry
->ie_FileInfoBlock
, sizeof(struct FileInfoBlock
));
4587 message
->entry
->ie_FileInfoBlock
= NULL
;
4589 if (message
->entry
->ie_IconListEntry
.type
!= ST_USERDIR
)
4591 message
->entry
->ie_Flags
|= ICONENTRY_FLAG_NEEDSUPDATE
;
4592 message
->entry
->ie_IconListEntry
.type
= ST_USERDIR
;
4596 /* Override type if specified */
4597 if ((message
->type
!= 0) && (message
->entry
->ie_IconListEntry
.type
!= message
->type
))
4599 message
->entry
->ie_Flags
|= ICONENTRY_FLAG_NEEDSUPDATE
;
4600 message
->entry
->ie_IconListEntry
.type
= message
->type
;
4601 D(bug("[IconList] %s: Overide Entry Type. New Type = %x\n", __PRETTY_FUNCTION__
, message
->entry
->ie_IconListEntry
.type
));
4605 D(bug("[IconList] %s: Entry Type = %x\n", __PRETTY_FUNCTION__
, message
->entry
->ie_IconListEntry
.type
));
4608 IconList_GetIconAreaRectangle(obj
, data
, message
->entry
, &rect
);
4610 return (IPTR
)message
->entry
;
4615 static void DoWheelMove(struct IClass
*CLASS
, Object
*obj
, LONG wheelx
, LONG wheely
, UWORD qual
)
4617 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
4619 LONG newleft
= data
->icld_ViewX
,
4620 newtop
= data
->icld_ViewY
;
4622 /* Use horizontal scrolling if any of the following cases are true ...
4624 # vertical wheel is used but there's nothing to scroll
4625 (everything is visible already) ..
4627 # vertical wheel is used and one of the ALT keys is down. */
4629 if ((wheely
&& !wheelx
) &&
4630 ((data
->icld_AreaHeight
<= _mheight(obj
)) || (qual
& (IEQUALIFIER_LALT
| IEQUALIFIER_RALT
))))
4632 wheelx
= wheely
; wheely
= 0;
4635 if (qual
& (IEQUALIFIER_CONTROL
))
4637 if (wheelx
< 0) newleft
= 0;
4638 if (wheelx
> 0) newleft
= data
->icld_AreaWidth
;
4639 if (wheely
< 0) newtop
= 0;
4640 if (wheely
> 0) newtop
= data
->icld_AreaHeight
;
4642 else if (qual
& (IEQUALIFIER_LSHIFT
| IEQUALIFIER_RSHIFT
))
4644 newleft
+= (wheelx
* _mwidth(obj
));
4645 newtop
+= (wheely
* _mheight(obj
));
4649 newleft
+= wheelx
* 30;
4650 newtop
+= wheely
* 30;
4653 if (newleft
+ _mwidth(obj
) > data
->icld_AreaWidth
)
4654 newleft
= data
->icld_AreaWidth
- _mwidth(obj
);
4658 if (newtop
+ _mheight(obj
) > data
->icld_AreaHeight
)
4659 newtop
= data
->icld_AreaHeight
- _mheight(obj
);
4663 if ((newleft
!= data
->icld_ViewX
) || (newtop
!= data
->icld_ViewY
))
4665 SetAttrs(obj
, MUIA_Virtgroup_Left
, newleft
,
4666 MUIA_Virtgroup_Top
, newtop
,
4675 * a) if clicked object is selected, nothing
4676 * b) if clicked object is not selected, unselect all, select object
4677 * c) if no clicked object, start lasso
4679 * a) if in lasso, finish lasso
4681 * a) if object is selected, unselect it (= remove from multiselection)
4682 * b) if object is not selected, select it (= add to multiselection)
4685 * Expected behaviour:
4686 * a) you can only "remove" multiselection by clicking on not selected object or on space where there is no icon
4690 static void IconList_HandleNewIconSelection(struct IClass
*CLASS
, Object
*obj
, struct MUIP_HandleEvent
*message
,
4691 struct IconEntry
*new_selected
, BOOL
*doubleclicked
)
4693 struct IconEntry
*node
= NULL
;
4694 BOOL update_entry
= FALSE
;
4695 LONG mx
= message
->imsg
->MouseX
- _mleft(obj
);
4696 LONG my
= message
->imsg
->MouseY
- _mtop(obj
);
4697 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
4698 BOOL nounselection
= (new_selected
!= NULL
&&
4699 (new_selected
->ie_Flags
& ICONENTRY_FLAG_SELECTED
)); /* see notes above */
4702 /* Check if this is a double click on icon or empty space */
4703 if ((DoubleClick(data
->last_secs
, data
->last_mics
, message
->imsg
->Seconds
, message
->imsg
->Micros
)) && (data
->icld_SelectionLastClicked
== new_selected
))
4705 #if defined(DEBUG_ILC_EVENTS)
4706 D(bug("[IconList] %s: Entry double-clicked\n", __PRETTY_FUNCTION__
));
4708 *doubleclicked
= TRUE
;
4711 /* Deselection lopp */
4712 #if defined(__AROS__)
4713 ForeachNode(&data
->icld_IconList
, node
)
4715 Foreach_Node(&data
->icld_IconList
, node
);
4718 if (node
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
4720 update_entry
= FALSE
;
4722 /* If node that is being checked is selected and it is not the clicked node
4723 * and no shift pressed and
4724 * clicked node is not part of selection (see notes above) or this is a double click */
4725 if (node
->ie_Flags
& ICONENTRY_FLAG_SELECTED
)
4727 if ((new_selected
!= node
) &&
4728 (!(message
->imsg
->Qualifier
& (IEQUALIFIER_LSHIFT
| IEQUALIFIER_RSHIFT
))) &&
4729 (!nounselection
|| *doubleclicked
))
4731 Remove(&node
->ie_SelectionNode
);
4732 node
->ie_Flags
&= ~ICONENTRY_FLAG_SELECTED
;
4733 update_entry
= TRUE
;
4738 if ((node
->ie_Flags
& ICONENTRY_FLAG_FOCUS
) && (new_selected
!= node
))
4740 node
->ie_Flags
&= ~ICONENTRY_FLAG_FOCUS
;
4741 update_entry
= TRUE
;
4747 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
4748 data
->update_entry
= node
;
4749 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
4750 #if defined(DEBUG_ILC_EVENTS)
4751 D(bug("[IconList] %s: Rendered entry '%s'\n", __PRETTY_FUNCTION__
, node
->ie_IconListEntry
.label
));
4757 if (new_selected
!= NULL
)
4759 /* Found clicked entry... */
4760 data
->icld_LassoActive
= FALSE
;
4761 update_entry
= FALSE
;
4763 if (!(new_selected
->ie_Flags
& ICONENTRY_FLAG_SELECTED
))
4765 /* Add new entry to selection */
4766 AddTail(&data
->icld_SelectionList
, &new_selected
->ie_SelectionNode
);
4767 new_selected
->ie_Flags
|= ICONENTRY_FLAG_SELECTED
;
4768 update_entry
= TRUE
;
4770 else if ((*doubleclicked
== FALSE
) && (message
->imsg
->Qualifier
& (IEQUALIFIER_LSHIFT
| IEQUALIFIER_RSHIFT
)))
4772 /* Unselect previously selected entry */
4773 Remove(&new_selected
->ie_SelectionNode
);
4774 new_selected
->ie_Flags
&= ~ICONENTRY_FLAG_SELECTED
;
4775 update_entry
= TRUE
;
4779 if (!(new_selected
->ie_Flags
& ICONENTRY_FLAG_FOCUS
))
4781 new_selected
->ie_Flags
|= ICONENTRY_FLAG_FOCUS
;
4782 data
->icld_FocusIcon
= new_selected
;
4783 update_entry
= TRUE
;
4789 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
4790 data
->update_entry
= new_selected
;
4791 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
4792 #if defined(DEBUG_ILC_EVENTS)
4793 D(bug("[IconList] %s: Rendered 'new_selected' entry '%s'\n", __PRETTY_FUNCTION__
, new_selected
->ie_IconListEntry
.label
));
4799 struct Window
* thisWindow
= NULL
;
4800 #if defined(DEBUG_ILC_EVENTS) || defined(DEBUG_ILC_LASSO)
4801 D(bug("[IconList] %s: Starting Lasso\n", __PRETTY_FUNCTION__
));
4803 /* No entry clicked on ... Start Lasso-selection */
4804 data
->icld_LassoActive
= TRUE
;
4805 if (!(message
->imsg
->Qualifier
& (IEQUALIFIER_LSHIFT
| IEQUALIFIER_RSHIFT
)))
4807 data
->icld_SelectionLastClicked
= NULL
;
4808 data
->icld_FocusIcon
= NULL
;
4810 data
->icld_LassoRectangle
.MinX
= mx
- data
->view_rect
.MinX
+ data
->icld_ViewX
;
4811 data
->icld_LassoRectangle
.MinY
= my
- data
->view_rect
.MinY
+ data
->icld_ViewY
;
4812 data
->icld_LassoRectangle
.MaxX
= mx
- data
->view_rect
.MinX
+ data
->icld_ViewX
;
4813 data
->icld_LassoRectangle
.MaxY
= my
- data
->view_rect
.MinY
+ data
->icld_ViewY
;
4815 /* Draw initial Lasso frame */
4816 IconList_InvertLassoOutlines(obj
, data
, &data
->icld_LassoRectangle
);
4818 /* Start handling INTUITICKS */
4819 GET(obj
, MUIA_Window
, &thisWindow
);
4822 ModifyIDCMP(thisWindow
, (thisWindow
->IDCMPFlags
|IDCMP_INTUITICKS
));
4823 if (!(data
->ehn
.ehn_Events
& IDCMP_INTUITICKS
))
4825 DoMethod(_win(obj
), MUIM_Window_RemEventHandler
, (IPTR
)&data
->ehn
);
4826 data
->ehn
.ehn_Events
|= IDCMP_INTUITICKS
;
4827 DoMethod(_win(obj
), MUIM_Window_AddEventHandler
, (IPTR
)&data
->ehn
);
4833 ///MUIM_HandleEvent()
4834 /**************************************************************************
4836 **************************************************************************/
4837 IPTR
IconList__MUIM_HandleEvent(struct IClass
*CLASS
, Object
*obj
, struct MUIP_HandleEvent
*message
)
4839 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
4841 #if defined(DEBUG_ILC_FUNCS)
4842 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
4847 LONG mx
= message
->imsg
->MouseX
- _mleft(obj
);
4848 LONG my
= message
->imsg
->MouseY
- _mtop(obj
);
4853 switch (message
->imsg
->Class
)
4856 bug("[IconList] %s: IDCMP_NEWSIZE\n", __PRETTY_FUNCTION__
);
4861 #if defined(DEBUG_ILC_EVENTS)
4862 D(bug("[IconList] %s: IDCMP_RAWKEY\n", __PRETTY_FUNCTION__
));
4864 BOOL rawkey_handled
= FALSE
;
4866 switch(message
->imsg
->Code
)
4868 case RAWKEY_NM_WHEEL_UP
:
4870 rawkey_handled
= TRUE
;
4873 case RAWKEY_NM_WHEEL_DOWN
:
4875 rawkey_handled
= TRUE
;
4878 case RAWKEY_NM_WHEEL_LEFT
:
4880 rawkey_handled
= TRUE
;
4883 case RAWKEY_NM_WHEEL_RIGHT
:
4885 rawkey_handled
= TRUE
;
4891 #if defined(DEBUG_ILC_KEYEVENTS)
4892 D(bug("[IconList] %s: Processing mouse wheel event\n", __PRETTY_FUNCTION__
));
4894 if (_isinobject(message
->imsg
->MouseX
, message
->imsg
->MouseY
) &&
4897 DoWheelMove(CLASS
, obj
, wheelx
, wheely
, message
->imsg
->Qualifier
);
4900 else if (!(message
->imsg
->Code
& IECODE_UP_PREFIX
))
4902 LONG new_ViewY
= data
->icld_ViewY
;
4903 struct IconEntry
*start_entry
= NULL
, *active_entry
= NULL
, *entry_next
= NULL
;
4904 IPTR start_X
= 0, start_Y
= 0, active_X
= 0, active_Y
= 0, next_X
= 0, next_Y
= 0;
4907 #if defined(DEBUG_ILC_KEYEVENTS)
4908 D(bug("[IconList] %s: Processing key up event\n", __PRETTY_FUNCTION__
));
4911 switch(message
->imsg
->Code
)
4914 rawkey_handled
= TRUE
;
4916 #if defined(DEBUG_ILC_KEYEVENTS)
4917 D(bug("[IconList] %s: RAWKEY_RETURN\n", __PRETTY_FUNCTION__
));
4920 if (data
->icld_FocusIcon
) active_entry
= data
->icld_FocusIcon
;
4921 else if (data
->icld_SelectionLastClicked
) active_entry
= data
->icld_SelectionLastClicked
;
4925 if (!(active_entry
->ie_Flags
& ICONENTRY_FLAG_SELECTED
))
4927 active_entry
->ie_Flags
|= ICONENTRY_FLAG_SELECTED
;
4928 AddTail(&data
->icld_SelectionList
, &active_entry
->ie_SelectionNode
);
4929 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
4930 data
->update_entry
= active_entry
;
4931 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
4933 data
->icld_SelectionLastClicked
= active_entry
;
4934 data
->icld_FocusIcon
= active_entry
;
4936 SET(obj
, MUIA_IconList_DoubleClick
, TRUE
);
4941 rawkey_handled
= TRUE
;
4943 #if defined(DEBUG_ILC_KEYEVENTS)
4944 D(bug("[IconList] %s: RAWKEY_SPACE\n", __PRETTY_FUNCTION__
));
4947 if (data
->icld_FocusIcon
) active_entry
= data
->icld_FocusIcon
;
4948 else if (data
->icld_SelectionLastClicked
) active_entry
= data
->icld_SelectionLastClicked
;
4950 if (!(message
->imsg
->Qualifier
& IEQUALIFIER_LSHIFT
) && ((data
->icld_SelectionLastClicked
)||(data
->icld_SelectionLastClicked
!= active_entry
)))
4952 #if defined(DEBUG_ILC_KEYEVENTS)
4953 D(bug("[IconList] %s: SPACE: Clearing selected icons ..\n", __PRETTY_FUNCTION__
));
4955 DoMethod(obj
, MUIM_IconList_UnselectAll
);
4960 if (!(active_entry
->ie_Flags
& ICONENTRY_FLAG_SELECTED
))
4962 AddTail(&data
->icld_SelectionList
, &active_entry
->ie_SelectionNode
);
4963 active_entry
->ie_Flags
|= ICONENTRY_FLAG_SELECTED
;
4964 data
->icld_SelectionLastClicked
= active_entry
;
4968 Remove(&active_entry
->ie_SelectionNode
);
4969 active_entry
->ie_Flags
&= ~ICONENTRY_FLAG_SELECTED
;
4972 data
->icld_FocusIcon
= active_entry
;
4974 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
4975 data
->update_entry
= active_entry
;
4976 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
4981 rawkey_handled
= TRUE
;
4983 #if defined(DEBUG_ILC_KEYEVENTS)
4984 D(bug("[IconList] %s: RAWKEY_PAGEUP\n", __PRETTY_FUNCTION__
));
4987 if (data
->icld_AreaHeight
> data
->icld_ViewHeight
)
4989 new_ViewY
-= data
->icld_ViewHeight
;
4994 if (new_ViewY
!= data
->icld_ViewY
)
4996 SET(obj
, MUIA_Virtgroup_Top
, new_ViewY
);
5000 case RAWKEY_PAGEDOWN
:
5001 rawkey_handled
= TRUE
;
5003 #if defined(DEBUG_ILC_KEYEVENTS)
5004 D(bug("[IconList] %s: RAWKEY_PAGEDOWN\n", __PRETTY_FUNCTION__
));
5007 if (data
->icld_AreaHeight
> data
->icld_ViewHeight
)
5009 new_ViewY
+= data
->icld_ViewHeight
;
5010 if (new_ViewY
> (data
->icld_AreaHeight
- data
->icld_ViewHeight
))
5011 new_ViewY
= data
->icld_AreaHeight
- data
->icld_ViewHeight
;
5014 if (new_ViewY
!= data
->icld_ViewY
)
5016 SET(obj
, MUIA_Virtgroup_Top
, new_ViewY
);
5021 rawkey_handled
= TRUE
;
5023 #if defined(DEBUG_ILC_KEYEVENTS)
5024 D(bug("[IconList] %s: RAWKEY_UP\n", __PRETTY_FUNCTION__
));
5027 if (data
->icld_FocusIcon
)
5029 start_entry
= data
->icld_FocusIcon
;
5030 #if defined(DEBUG_ILC_KEYEVENTS)
5031 D(bug("[IconList] %s: UP: Clearing existing focused entry @ 0x%p\n", __PRETTY_FUNCTION__
, start_entry
));
5034 start_entry
->ie_Flags
&= ~ICONENTRY_FLAG_FOCUS
;
5035 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
5036 data
->update_entry
= start_entry
;
5037 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
5039 start_X
= start_entry
->ie_IconX
;
5040 start_Y
= start_entry
->ie_IconY
;
5041 #if defined(DEBUG_ILC_KEYEVENTS)
5042 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
));
5044 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
5046 if (start_entry
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
5048 start_X
= start_X
- ((data
->icld_IconAreaLargestWidth
- start_entry
->ie_AreaWidth
)/2);
5049 #if defined(DEBUG_ILC_KEYEVENTS)
5050 D(bug("[IconList] %s: UP: adjusted start_X for grid = %d\n", __PRETTY_FUNCTION__
, start_X
));
5055 if ((active_entry
= Node_PreviousVisible(start_entry
)) && !(data
->icld_DisplayFlags
& ICONLIST_DISP_VERTICAL
))
5057 //Check if we are at the edge of the entry area ..
5058 #if defined(DEBUG_ILC_KEYEVENTS)
5059 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
));
5061 active_Y
= active_entry
->ie_IconY
;
5063 if (active_Y
== start_Y
)
5066 #if defined(DEBUG_ILC_KEYEVENTS)
5067 D(bug("[IconList] %s: UP: active_entry is on our row (not at the edge)\n", __PRETTY_FUNCTION__
));
5069 entry_next
= active_entry
;
5070 next_X
= entry_next
->ie_IconX
;
5071 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
5073 if (entry_next
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
5074 next_X
= next_X
- ((data
->icld_IconAreaLargestWidth
- entry_next
->ie_AreaWidth
)/2);
5078 #if defined(DEBUG_ILC_KEYEVENTS)
5079 D(bug("[IconList] %s: UP: using start_X %d, start_Y %d\n", __PRETTY_FUNCTION__
, start_X
, start_Y
));
5083 if (!(message
->imsg
->Qualifier
& IEQUALIFIER_LSHIFT
) && ((data
->icld_SelectionLastClicked
)&&(data
->icld_SelectionLastClicked
!= active_entry
)))
5085 #if defined(DEBUG_ILC_KEYEVENTS)
5086 D(bug("[IconList] %s: UP: Clearing selected icons ..\n", __PRETTY_FUNCTION__
));
5088 DoMethod(obj
, MUIM_IconList_UnselectAll
);
5091 #if defined(DEBUG_ILC_KEYEVENTS)
5092 D(bug("[IconList] %s: UP: active = 0x%p, next = 0x%p\n", __PRETTY_FUNCTION__
, active_entry
, entry_next
));
5094 if (!(active_entry
))
5096 // If nothing is selected we will use the last visible entry ..
5097 active_entry
= Node_LastVisible(&data
->icld_IconList
);
5098 start_X
= active_entry
->ie_IconX
;
5099 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
5101 if (active_entry
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
5102 start_X
= start_X
- ((data
->icld_IconAreaLargestWidth
- active_entry
->ie_AreaWidth
)/2);
5104 start_Y
= active_entry
->ie_IconY
;
5107 while (active_entry
!= NULL
)
5109 #if defined(DEBUG_ILC_KEYEVENTS)
5110 D(bug("[IconList] %s: UP: Checking active @ 0x%p\n", __PRETTY_FUNCTION__
, active_entry
));
5112 if (data
->icld_DisplayFlags
& ICONLIST_DISP_VERTICAL
)
5114 // Return the first visible since the list flow direction matches
5115 // our cursor direction
5116 if (active_entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
5121 active_X
= active_entry
->ie_IconX
;
5123 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
5125 if (active_entry
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
5126 x_diff
= ((data
->icld_IconAreaLargestWidth
- active_entry
->ie_AreaWidth
)/2);
5128 active_Y
= active_entry
->ie_IconY
;
5134 if ((active_entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
) &&
5135 (active_Y
< start_Y
) &&
5136 (((active_X
- x_diff
) >= start_X
) &&
5137 ((active_X
- x_diff
) <= (start_X
+ start_entry
->ie_AreaWidth
+ (x_diff
*2)))))
5139 #if defined(DEBUG_ILC_KEYEVENTS)
5140 D(bug("[IconList] %s: UP: (A) entry 0x%p matches\n", __PRETTY_FUNCTION__
, active_entry
));
5144 else if (active_entry
== (struct IconEntry
*)GetHead(&data
->icld_IconList
))
5146 #if defined(DEBUG_ILC_KEYEVENTS)
5147 D(bug("[IconList] %s: UP: (A) reached list start .. restarting from the end ..\n", __PRETTY_FUNCTION__
));
5151 if ((entry_next
= Node_PreviousVisible(entry_next
)))
5153 if (entry_next
->ie_IconX
> start_X
)
5157 next_X
= entry_next
->ie_IconX
;
5158 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
5160 if (entry_next
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
5161 next_X
= next_X
- ((data
->icld_IconAreaLargestWidth
- entry_next
->ie_AreaWidth
)/2);
5166 #if defined(DEBUG_ILC_KEYEVENTS)
5167 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
));
5169 active_entry
= Node_LastVisible(&data
->icld_IconList
);
5174 if ((active_entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
) &&
5175 (active_Y
< start_Y
) &&
5176 ((active_X
+ x_diff
) < (start_X
+ start_entry
->ie_AreaWidth
+ x_diff
)))
5178 #if defined(DEBUG_ILC_KEYEVENTS)
5179 D(bug("[IconList] %s: UP: (B) entry 0x%p matches\n", __PRETTY_FUNCTION__
, active_entry
));
5187 if (active_entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
5189 #if defined(DEBUG_ILC_KEYEVENTS)
5190 D(bug("[IconList] %s: UP: (C) entry 0x%p matches\n", __PRETTY_FUNCTION__
, active_entry
));
5196 active_entry
= (struct IconEntry
*)(((struct Node
*)active_entry
)->ln_Pred
);
5199 if (!(active_entry
))
5201 #if defined(DEBUG_ILC_KEYEVENTS)
5202 D(bug("[IconList] %s: UP: No Next UP Node - Getting Last visible entry ..\n", __PRETTY_FUNCTION__
));
5204 /* We didnt find a "next UP" entry so just use the last visible */
5205 active_entry
= Node_LastVisible(&data
->icld_IconList
);
5210 if (!(active_entry
->ie_Flags
& ICONENTRY_FLAG_FOCUS
))
5212 active_entry
->ie_Flags
|= ICONENTRY_FLAG_FOCUS
;
5213 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
5214 data
->update_entry
= active_entry
;
5215 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
5218 data
->icld_FocusIcon
= active_entry
;
5222 rawkey_handled
= TRUE
;
5224 #if defined(DEBUG_ILC_KEYEVENTS)
5225 D(bug("[IconList] %s: RAWKEY_DOWN\n", __PRETTY_FUNCTION__
));
5227 if (data
->icld_FocusIcon
)
5229 start_entry
= data
->icld_FocusIcon
;
5230 #if defined(DEBUG_ILC_KEYEVENTS)
5231 D(bug("[IconList] %s: DOWN: Clearing existing focused entry @ 0x%p\n", __PRETTY_FUNCTION__
, start_entry
));
5234 start_entry
->ie_Flags
&= ~ICONENTRY_FLAG_FOCUS
;
5235 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
5236 data
->update_entry
= start_entry
;
5237 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
5239 start_X
= start_entry
->ie_IconX
;
5240 start_Y
= start_entry
->ie_IconY
;
5241 #if defined(DEBUG_ILC_KEYEVENTS)
5242 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
));
5244 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
5246 if (start_entry
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
5248 start_X
= start_X
- ((data
->icld_IconAreaLargestWidth
- start_entry
->ie_AreaWidth
)/2);
5249 #if defined(DEBUG_ILC_KEYEVENTS)
5250 D(bug("[IconList] %s: DOWN: adjusted start_X for grid = %d\n", __PRETTY_FUNCTION__
, start_X
));
5255 if ((active_entry
= Node_NextVisible(start_entry
)) &&
5256 (!(data
->icld_DisplayFlags
& ICONLIST_DISP_VERTICAL
)))
5258 #if defined(DEBUG_ILC_KEYEVENTS)
5259 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
));
5261 active_Y
= active_entry
->ie_IconY
;
5263 if (active_Y
== start_Y
)
5266 #if defined(DEBUG_ILC_KEYEVENTS)
5267 D(bug("[IconList] %s: DOWN: active_entry is on our row (not at the edge)\n", __PRETTY_FUNCTION__
));
5269 entry_next
= active_entry
;
5270 next_X
= entry_next
->ie_IconX
;
5271 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
5273 if (entry_next
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
5274 next_X
= next_X
- ((data
->icld_IconAreaLargestWidth
- entry_next
->ie_AreaWidth
)/2);
5278 #if defined(DEBUG_ILC_KEYEVENTS)
5279 D(bug("[IconList] %s: DOWN: using start_X %d, start_Y %d\n", __PRETTY_FUNCTION__
, start_X
, start_Y
));
5283 if (!(message
->imsg
->Qualifier
& IEQUALIFIER_LSHIFT
) && ((data
->icld_SelectionLastClicked
)&&(data
->icld_SelectionLastClicked
!= active_entry
)))
5285 #if defined(DEBUG_ILC_KEYEVENTS)
5286 D(bug("[IconList] %s: DOWN: Clearing selected icons ..\n", __PRETTY_FUNCTION__
));
5288 DoMethod(obj
, MUIM_IconList_UnselectAll
);
5291 #if defined(DEBUG_ILC_KEYEVENTS)
5292 D(bug("[IconList] %s: DOWN: active = 0x%p, next = 0x%p\n", __PRETTY_FUNCTION__
, active_entry
, entry_next
));
5294 if (!(active_entry
))
5296 // If nothing is selected we will use the First visible entry ..
5297 active_entry
= Node_FirstVisible(&data
->icld_IconList
);
5298 start_X
= active_entry
->ie_IconX
;
5299 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
5301 if (active_entry
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
5302 start_X
= start_X
- ((data
->icld_IconAreaLargestWidth
- active_entry
->ie_AreaWidth
)/2);
5304 start_Y
= active_entry
->ie_IconY
;
5307 while (active_entry
!= NULL
)
5309 #if defined(DEBUG_ILC_KEYEVENTS)
5310 D(bug("[IconList] %s: DOWN: Checking active @ 0x%p\n", __PRETTY_FUNCTION__
, active_entry
));
5312 if (data
->icld_DisplayFlags
& ICONLIST_DISP_VERTICAL
)
5314 if (active_entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
5319 active_X
= active_entry
->ie_IconX
;
5321 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
5323 if (active_entry
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
5324 x_diff
= ((data
->icld_IconAreaLargestWidth
- active_entry
->ie_AreaWidth
)/2);
5326 active_Y
= active_entry
->ie_IconY
;
5332 if ((active_entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
) &&
5333 (active_Y
> start_Y
) &&
5334 (((active_X
- x_diff
) >= start_X
) &&
5335 ((active_X
- x_diff
) <= (start_X
+ start_entry
->ie_AreaWidth
+ (x_diff
*2)))))
5337 #if defined(DEBUG_ILC_KEYEVENTS)
5338 D(bug("[IconList] %s: DOWN: (A) entry 0x%p matches\n", __PRETTY_FUNCTION__
, active_entry
));
5342 else if (active_entry
== (struct IconEntry
*)GetTail(&data
->icld_IconList
))
5344 #if defined(DEBUG_ILC_KEYEVENTS)
5345 D(bug("[IconList] %s: DOWN: (A) reached list end .. starting at the beginng ..\n", __PRETTY_FUNCTION__
));
5347 start_X
= entry_next
->ie_IconX
;
5348 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
5350 if (entry_next
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
5351 start_X
= start_X
- ((data
->icld_IconAreaLargestWidth
- entry_next
->ie_AreaWidth
)/2);
5354 if ((entry_next
= (struct IconEntry
*)Node_NextVisible(entry_next
)))
5356 if (entry_next
->ie_IconX
< start_X
)
5360 next_X
= entry_next
->ie_IconX
;
5361 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
5363 if (entry_next
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
5364 next_X
= next_X
+ ((data
->icld_IconAreaLargestWidth
- entry_next
->ie_AreaWidth
)/2);
5369 #if defined(DEBUG_ILC_KEYEVENTS)
5370 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
));
5372 active_entry
= Node_FirstVisible(&data
->icld_IconList
);
5377 if ((active_entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
) &&
5378 (active_Y
> start_Y
) &&
5379 (active_X
> start_X
- 1))
5381 #if defined(DEBUG_ILC_KEYEVENTS)
5382 D(bug("[IconList] %s: DOWN: (B) entry 0x%p matches\n", __PRETTY_FUNCTION__
, active_entry
));
5390 if (active_entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
5392 #if defined(DEBUG_ILC_KEYEVENTS)
5393 D(bug("[IconList] %s: DOWN: (C) entry 0x%p matches\n", __PRETTY_FUNCTION__
, active_entry
));
5399 active_entry
= (struct IconEntry
*)GetSucc(&active_entry
->ie_IconNode
);
5402 if (!(active_entry
))
5404 #if defined(DEBUG_ILC_KEYEVENTS)
5405 D(bug("[IconList] %s: DOWN: No Next DOWN Node - Getting first visable entry ..\n", __PRETTY_FUNCTION__
));
5407 /* We didnt find a "next DOWN" entry so just use the first visible */
5408 active_entry
= Node_FirstVisible(&data
->icld_IconList
);
5413 if (!(active_entry
->ie_Flags
& ICONENTRY_FLAG_FOCUS
))
5415 active_entry
->ie_Flags
|= ICONENTRY_FLAG_FOCUS
;
5416 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
5417 data
->update_entry
= active_entry
;
5418 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
5421 data
->icld_FocusIcon
= active_entry
;
5425 rawkey_handled
= TRUE
;
5427 #if defined(DEBUG_ILC_KEYEVENTS)
5428 D(bug("[IconList] %s: RAWKEY_LEFT\n", __PRETTY_FUNCTION__
));
5430 if (data
->icld_FocusIcon
)
5432 start_entry
= data
->icld_FocusIcon
;
5433 #if defined(DEBUG_ILC_KEYEVENTS)
5434 D(bug("[IconList] %s: LEFT: Clearing existing focused entry @ 0x%p\n", __PRETTY_FUNCTION__
, start_entry
));
5437 start_entry
->ie_Flags
&= ~ICONENTRY_FLAG_FOCUS
;
5438 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
5439 data
->update_entry
= start_entry
;
5440 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
5442 start_X
= start_entry
->ie_IconX
;
5443 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
5445 if (start_entry
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
5446 start_X
= start_X
- ((data
->icld_IconAreaLargestWidth
- start_entry
->ie_AreaWidth
)/2);
5448 start_Y
= start_entry
->ie_IconY
;
5450 #if defined(DEBUG_ILC_KEYEVENTS)
5451 D(bug("[IconList] %s: LEFT: start_X %d, start_Y %d\n", __PRETTY_FUNCTION__
, start_X
, start_Y
));
5454 if (!(active_entry
= Node_NextVisible(start_entry
)) && (!(data
->icld_DisplayFlags
& ICONLIST_DISP_VERTICAL
)))
5456 active_entry
= (struct IconEntry
*)GetHead(&data
->icld_IconList
);
5457 #if defined(DEBUG_ILC_KEYEVENTS)
5458 D(bug("[IconList] %s: LEFT: Start at the beginning (Active @ 0x%p) using entry X + Width\n", __PRETTY_FUNCTION__
, active_entry
));
5460 start_X
= start_X
+ start_entry
->ie_AreaWidth
;
5461 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
5463 if (start_entry
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
5464 start_X
= start_X
+ ((data
->icld_IconAreaLargestWidth
- start_entry
->ie_AreaWidth
)/2);
5470 else if (active_entry
&& (!(data
->icld_DisplayFlags
& ICONLIST_DISP_VERTICAL
)))
5472 #if defined(DEBUG_ILC_KEYEVENTS)
5473 D(bug("[IconList] %s: LEFT: Active @ 0x%p, X %d\n", __PRETTY_FUNCTION__
, active_entry
, active_entry
->ie_IconX
));
5475 if ((entry_next
= Node_NextVisible(start_entry
)))
5477 #if defined(DEBUG_ILC_KEYEVENTS)
5478 D(bug("[IconList] %s: LEFT: Next @ 0x%p, X %d\n", __PRETTY_FUNCTION__
, entry_next
, entry_next
->ie_IconX
));
5481 if (entry_next
->ie_IconX
< start_X
)
5485 next_X
= entry_next
->ie_IconX
;
5486 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
5488 if (entry_next
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
5489 next_X
= next_X
- ((data
->icld_IconAreaLargestWidth
- entry_next
->ie_AreaWidth
)/2);
5494 #if defined(DEBUG_ILC_KEYEVENTS)
5495 D(bug("[IconList] %s: LEFT: using start_X %d, start_Y %d\n", __PRETTY_FUNCTION__
, start_X
, start_Y
));
5499 if (!(message
->imsg
->Qualifier
& IEQUALIFIER_LSHIFT
) && ((data
->icld_SelectionLastClicked
)&&(data
->icld_SelectionLastClicked
!= active_entry
)))
5501 #if defined(DEBUG_ILC_KEYEVENTS)
5502 D(bug("[IconList] %s: LEFT: Clearing selected icons ..\n", __PRETTY_FUNCTION__
));
5504 DoMethod(obj
, MUIM_IconList_UnselectAll
);
5507 #if defined(DEBUG_ILC_KEYEVENTS)
5508 D(bug("[IconList] %s: LEFT: active = 0x%p, next = 0x%p\n", __PRETTY_FUNCTION__
, active_entry
, entry_next
));
5511 if (!(active_entry
))
5513 active_entry
= (struct IconEntry
*)GetHead(&data
->icld_IconList
);
5516 while (active_entry
!= NULL
)
5518 #if defined(DEBUG_ILC_KEYEVENTS)
5519 D(bug("[IconList] %s: LEFT: Checking active @ 0x%p\n", __PRETTY_FUNCTION__
, active_entry
));
5521 if (data
->icld_DisplayFlags
& ICONLIST_DISP_VERTICAL
)
5523 if (active_entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
5528 LONG active_entry_X
= active_entry
->ie_IconX
;
5529 LONG active_entry_Y
;
5530 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
5532 if (active_entry
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
5533 active_entry_X
= active_entry_X
- ((data
->icld_IconAreaLargestWidth
- active_entry
->ie_AreaWidth
)/2);
5535 active_entry_Y
= active_entry
->ie_IconY
;
5541 if ((active_entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
) &&
5542 (active_entry_Y
> start_Y
) &&
5543 ((active_entry_X
> start_X
- 1) &&
5544 (active_entry_X
< next_X
)))
5546 #if defined(DEBUG_ILC_KEYEVENTS)
5547 D(bug("[IconList] %s: LEFT: (A) entry 0x%p matches\n", __PRETTY_FUNCTION__
, active_entry
));
5551 else if (active_entry
== (struct IconEntry
*)GetTail(&data
->icld_IconList
))
5553 #if defined(DEBUG_ILC_KEYEVENTS)
5554 D(bug("[IconList] %s: LEFT: (A) reached list end .. starting at the beginng ..\n", __PRETTY_FUNCTION__
));
5556 start_X
= entry_next
->ie_IconX
;
5557 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
5559 if (entry_next
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
5560 start_X
= start_X
- ((data
->icld_IconAreaLargestWidth
- entry_next
->ie_AreaWidth
)/2);
5563 if ((entry_next
= Node_NextVisible(entry_next
)))
5565 if (entry_next
->ie_IconX
< start_X
)
5569 next_X
= entry_next
->ie_IconX
;
5570 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
5572 if (entry_next
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
5573 next_X
= next_X
+ ((data
->icld_IconAreaLargestWidth
- entry_next
->ie_AreaWidth
)/2);
5578 #if defined(DEBUG_ILC_KEYEVENTS)
5579 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
));
5581 active_entry
= (struct IconEntry
*)GetHead(&data
->icld_IconList
);
5586 if ((active_entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
) &&
5587 (active_entry_Y
> start_Y
) &&
5588 (active_entry_X
> start_X
- 1))
5590 #if defined(DEBUG_ILC_KEYEVENTS)
5591 D(bug("[IconList] %s: LEFT: (B) entry 0x%p matches\n", __PRETTY_FUNCTION__
, active_entry
));
5599 if (active_entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
5601 #if defined(DEBUG_ILC_KEYEVENTS)
5602 D(bug("[IconList] %s: LEFT: (C) entry 0x%p matches\n", __PRETTY_FUNCTION__
, active_entry
));
5608 active_entry
= (struct IconEntry
*)GetSucc(&active_entry
->ie_IconNode
);
5611 if (!(active_entry
))
5613 #if defined(DEBUG_ILC_KEYEVENTS)
5614 D(bug("[IconList] %s: LEFT: No Next LEFT Node - Getting first visable entry ..\n", __PRETTY_FUNCTION__
));
5616 /* We didnt find a "next LEFT" entry so just use the last visible */
5617 active_entry
= (struct IconEntry
*)GetHead(&data
->icld_IconList
);
5618 while ((active_entry
!= NULL
) &&(!(active_entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)))
5620 active_entry
= (struct IconEntry
*)GetSucc(&active_entry
->ie_IconNode
);
5626 if (!(active_entry
->ie_Flags
& ICONENTRY_FLAG_FOCUS
))
5628 active_entry
->ie_Flags
|= ICONENTRY_FLAG_FOCUS
;
5629 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
5630 data
->update_entry
= active_entry
;
5631 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
5634 data
->icld_FocusIcon
= active_entry
;
5638 rawkey_handled
= TRUE
;
5640 #if defined(DEBUG_ILC_KEYEVENTS)
5641 D(bug("[IconList] %s: RAWKEY_RIGHT\n", __PRETTY_FUNCTION__
));
5644 if (data
->icld_FocusIcon
)
5646 start_entry
= data
->icld_FocusIcon
;
5647 #if defined(DEBUG_ILC_KEYEVENTS)
5648 D(bug("[IconList] %s: RIGHT: Clearing existing focused entry @ 0x%p\n", __PRETTY_FUNCTION__
, start_entry
));
5650 start_entry
->ie_Flags
&= ~ICONENTRY_FLAG_FOCUS
;
5651 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
5652 data
->update_entry
= start_entry
;
5653 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
5655 start_X
= start_entry
->ie_IconX
;
5656 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
5658 if (start_entry
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
5659 start_X
= start_X
- ((data
->icld_IconAreaLargestWidth
- start_entry
->ie_AreaWidth
)/2);
5661 start_Y
= start_entry
->ie_IconY
;
5663 #if defined(DEBUG_ILC_KEYEVENTS)
5664 D(bug("[IconList] %s: RIGHT: start_X %d, start_Y %d\n", __PRETTY_FUNCTION__
, start_X
, start_Y
));
5666 if (!(active_entry
= Node_NextVisible(start_entry
)) && (!(data
->icld_DisplayFlags
& ICONLIST_DISP_VERTICAL
)))
5668 active_entry
= (struct IconEntry
*)GetHead(&data
->icld_IconList
);
5669 #if defined(DEBUG_ILC_KEYEVENTS)
5670 D(bug("[IconList] %s: RIGHT: Start at the beginning (Active @ 0x%p) using entry X + Width\n", __PRETTY_FUNCTION__
, active_entry
));
5673 start_Y
= start_Y
+ start_entry
->ie_AreaHeight
;
5676 else if (active_entry
&& (data
->icld_DisplayFlags
& ICONLIST_DISP_VERTICAL
))
5678 #if defined(DEBUG_ILC_KEYEVENTS)
5679 D(bug("[IconList] %s: RIGHT: Active @ 0x%p, X %d\n", __PRETTY_FUNCTION__
, active_entry
, active_entry
->ie_IconX
));
5681 if ((entry_next
= Node_NextVisible(start_entry
)))
5683 #if defined(DEBUG_ILC_KEYEVENTS)
5684 D(bug("[IconList] %s: RIGHT: Next @ 0x%p, X %d\n", __PRETTY_FUNCTION__
, entry_next
, entry_next
->ie_IconX
));
5687 if (entry_next
->ie_IconY
< start_Y
)
5690 next_Y
= entry_next
->ie_IconY
;
5693 #if defined(DEBUG_ILC_KEYEVENTS)
5694 D(bug("[IconList] %s: RIGHT: using start_X %d, start_Y %d\n", __PRETTY_FUNCTION__
, start_X
, start_Y
));
5698 if (!(message
->imsg
->Qualifier
& IEQUALIFIER_LSHIFT
) && ((data
->icld_SelectionLastClicked
)&&(data
->icld_SelectionLastClicked
!= active_entry
)))
5700 #if defined(DEBUG_ILC_KEYEVENTS)
5701 D(bug("[IconList] %s: RIGHT: Clearing selected icons ..\n", __PRETTY_FUNCTION__
));
5703 DoMethod(obj
, MUIM_IconList_UnselectAll
);
5706 #if defined(DEBUG_ILC_KEYEVENTS)
5707 D(bug("[IconList] %s: RIGHT: active = 0x%p, next = 0x%p\n", __PRETTY_FUNCTION__
, active_entry
, entry_next
));
5710 if (!(active_entry
))
5712 active_entry
= (struct IconEntry
*)GetHead(&data
->icld_IconList
);
5715 while (active_entry
!= NULL
)
5717 #if defined(DEBUG_ILC_KEYEVENTS)
5718 D(bug("[IconList] %s: RIGHT: Checking active @ 0x%p\n", __PRETTY_FUNCTION__
, active_entry
));
5720 if (!(data
->icld_DisplayFlags
& ICONLIST_DISP_VERTICAL
))
5722 if (active_entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
5727 LONG active_entry_X
= active_entry
->ie_IconX
;
5728 LONG active_entry_Y
;
5729 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
5731 if (active_entry
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
5732 active_entry_X
= active_entry_X
- ((data
->icld_IconAreaLargestWidth
- active_entry
->ie_AreaWidth
)/2);
5734 active_entry_Y
= active_entry
->ie_IconY
;
5740 if ((active_entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
) &&
5741 (active_entry_X
> start_X
) &&
5742 ((active_entry_Y
> start_Y
- 1) &&
5743 (active_entry_Y
< next_Y
)))
5745 #if defined(DEBUG_ILC_KEYEVENTS)
5746 D(bug("[IconList] %s: RIGHT: (A) entry 0x%p matches\n", __PRETTY_FUNCTION__
, active_entry
));
5750 else if (active_entry
== (struct IconEntry
*)GetTail(&data
->icld_IconList
))
5752 #if defined(DEBUG_ILC_KEYEVENTS)
5753 D(bug("[IconList] %s: RIGHT: (A) reached list end .. starting at the beginng ..\n", __PRETTY_FUNCTION__
));
5755 start_Y
= entry_next
->ie_IconY
;
5757 if ((entry_next
= Node_NextVisible(entry_next
)))
5759 if (entry_next
->ie_IconY
< start_Y
)
5763 next_Y
= entry_next
->ie_IconY
;
5767 #if defined(DEBUG_ILC_KEYEVENTS)
5768 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
));
5770 active_entry
= (struct IconEntry
*)GetHead(&data
->icld_IconList
);
5775 if ((active_entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
) &&
5776 (active_entry_X
> start_X
) &&
5777 (active_entry_Y
> start_Y
- 1))
5779 #if defined(DEBUG_ILC_KEYEVENTS)
5780 D(bug("[IconList] %s: RIGHT: (B) entry 0x%p matches\n", __PRETTY_FUNCTION__
, active_entry
));
5788 if (active_entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
5790 #if defined(DEBUG_ILC_KEYEVENTS)
5791 D(bug("[IconList] %s: RIGHT: (C) entry 0x%p matches\n", __PRETTY_FUNCTION__
, active_entry
));
5797 active_entry
= (struct IconEntry
*)GetSucc(&active_entry
->ie_IconNode
);
5800 if (!(active_entry
))
5802 #if defined(DEBUG_ILC_KEYEVENTS)
5803 D(bug("[IconList] %s: RIGHT: No Next RIGHT Node - Getting first visable entry ..\n", __PRETTY_FUNCTION__
));
5805 /* We didnt find a "next RIGHT" entry so just use the first visible */
5806 active_entry
= (struct IconEntry
*)GetHead(&data
->icld_IconList
);
5807 while ((active_entry
!= NULL
) &&(!(active_entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)))
5809 active_entry
= (struct IconEntry
*)GetSucc(&active_entry
->ie_IconNode
);
5815 if (!(active_entry
->ie_Flags
& ICONENTRY_FLAG_FOCUS
))
5817 active_entry
->ie_Flags
|= ICONENTRY_FLAG_FOCUS
;
5818 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
5819 data
->update_entry
= active_entry
;
5820 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
5823 data
->icld_FocusIcon
= active_entry
;
5827 rawkey_handled
= TRUE
;
5829 #if defined(DEBUG_ILC_KEYEVENTS)
5830 D(bug("[IconList] %s: RAWKEY_HOME\n", __PRETTY_FUNCTION__
));
5833 if (data
->icld_FocusIcon
)
5835 data
->icld_FocusIcon
->ie_Flags
&= ~ICONENTRY_FLAG_FOCUS
;
5836 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
5837 data
->update_entry
= data
->icld_FocusIcon
;
5838 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
5841 active_entry
= Node_FirstVisible(&data
->icld_IconList
);
5843 if ((active_entry
) && (!(active_entry
->ie_Flags
& ICONENTRY_FLAG_FOCUS
)))
5845 active_entry
->ie_Flags
|= ICONENTRY_FLAG_FOCUS
;
5846 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
5847 data
->update_entry
= active_entry
;
5848 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
5850 data
->icld_FocusIcon
= active_entry
;
5854 rawkey_handled
= TRUE
;
5856 #if defined(DEBUG_ILC_KEYEVENTS)
5857 D(bug("[IconList] %s: RAWKEY_END\n", __PRETTY_FUNCTION__
));
5860 if (data
->icld_FocusIcon
)
5862 data
->icld_FocusIcon
->ie_Flags
&= ~ICONENTRY_FLAG_FOCUS
;
5863 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
5864 data
->update_entry
= data
->icld_FocusIcon
;
5865 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
5868 active_entry
= Node_LastVisible(&data
->icld_IconList
);
5870 if ((active_entry
) && (!(active_entry
->ie_Flags
& ICONENTRY_FLAG_FOCUS
)))
5872 active_entry
->ie_Flags
|= ICONENTRY_FLAG_FOCUS
;
5873 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
5874 data
->update_entry
= active_entry
;
5875 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
5877 data
->icld_FocusIcon
= active_entry
;
5881 if (rawkey_handled
) return MUI_EventHandlerRC_Eat
;
5885 case IDCMP_MOUSEBUTTONS
:
5886 #if defined(DEBUG_ILC_EVENTS)
5887 D(bug("[IconList] %s: IDCMP_MOUSEBUTTONS\n", __PRETTY_FUNCTION__
));
5889 if (message
->imsg
->Code
== SELECTDOWN
)
5891 /* Check if mouse pressed on iconlist area */
5892 if (mx
>= 0 && mx
< _width(obj
) && my
>= 0 && my
< _height(obj
))
5894 BOOL doubleclicked
= FALSE
; /* both icon and empty space */
5895 struct IconEntry
*node
= NULL
;
5896 struct IconEntry
*new_selected
= NULL
;
5898 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
5900 /* LIST-VIEW HANDLING */
5902 LONG clickColumn
= -1;
5904 LONG x
= _mleft(obj
) - data
->icld_ViewX
+ LINE_SPACING_LEFT
;
5907 /* Find column in which click happened */
5908 for(i
= 0; i
< NUM_COLUMNS
; i
++)
5910 index
= data
->icld_LVMAttribs
->lmva_ColumnPos
[i
];
5912 if (!(data
->icld_LVMAttribs
->lmva_ColumnFlags
[index
] & LVMCF_COLVISIBLE
)) continue;
5914 w
= data
->icld_LVMAttribs
->lmva_ColumnWidth
[index
];
5916 if ((mx
>= x
) && (mx
< x
+ w
))
5918 clickColumn
= index
;
5924 if (((data
->icld_LVMAttribs
->lvma_Flags
& LVMAF_NOHEADER
) == 0) && (my
<= data
->icld_LVMAttribs
->lmva_HeaderHeight
))
5926 /* Click on header, update list */
5927 data
->icld_LVMAttribs
->lmva_LastSelectedColumn
= clickColumn
;
5929 data
->icld_UpdateMode
= UPDATE_HEADERENTRY
;
5930 data
->update_entry
= (APTR
)(IPTR
)clickColumn
;
5932 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
5937 LONG current
= 0, index
= (my
- data
->icld_LVMAttribs
->lmva_HeaderHeight
+ data
->icld_ViewY
) / data
->icld_LVMAttribs
->lmva_RowHeight
;
5939 /* Check if clicked on entry */
5940 ForeachNode(&data
->icld_IconList
, node
)
5942 if (node
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
5944 /* Is this node clicked? */
5945 if (current
== index
)
5947 new_selected
= node
;
5955 /* Handle actions */
5956 IconList_HandleNewIconSelection(CLASS
, obj
, message
, new_selected
, &doubleclicked
);
5961 /* ICON-VIEW HANDLING */
5963 struct Rectangle rect
;
5965 /* Check if clicked on entry */
5966 #if defined(__AROS__)
5967 ForeachNode(&data
->icld_IconList
, node
)
5969 Foreach_Node(&data
->icld_IconList
, node
);
5972 if (node
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
5974 /* Is this node clicked? */
5975 rect
.MinX
= node
->ie_IconX
;
5976 rect
.MaxX
= node
->ie_IconX
+ node
->ie_AreaWidth
- 1;
5977 rect
.MinY
= node
->ie_IconY
;
5978 rect
.MaxY
= node
->ie_IconY
+ node
->ie_AreaHeight
- 1;
5980 if ((data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
) &&
5981 (node
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
))
5983 rect
.MinX
+= ((data
->icld_IconAreaLargestWidth
- node
->ie_AreaWidth
)/2);
5984 rect
.MaxX
+= ((data
->icld_IconAreaLargestWidth
- node
->ie_AreaWidth
)/2);
5987 if ((((mx
+ data
->icld_ViewX
) >= rect
.MinX
) && ((mx
+ data
->icld_ViewX
) <= rect
.MaxX
)) &&
5988 (((my
+ data
->icld_ViewY
) >= rect
.MinY
) && ((my
+ data
->icld_ViewY
) <= rect
.MaxY
)))
5990 new_selected
= node
;
5991 #if defined(DEBUG_ILC_EVENTS)
5992 D(bug("[IconList] %s: Entry '%s' clicked on ..\n", __PRETTY_FUNCTION__
, node
->ie_IconListEntry
.label
));
5999 /* Handle actions */
6000 IconList_HandleNewIconSelection(CLASS
, obj
, message
, new_selected
, &doubleclicked
);
6003 if (new_selected
&& (new_selected
->ie_Flags
& ICONENTRY_FLAG_SELECTED
))
6004 data
->icld_SelectionLastClicked
= new_selected
;
6006 data
->icld_SelectionLastClicked
= NULL
;
6011 SET(obj
, MUIA_IconList_SelectionChanged
, TRUE
);
6013 data
->icld_ClickEvent
.shift
= !!(message
->imsg
->Qualifier
& (IEQUALIFIER_LSHIFT
| IEQUALIFIER_RSHIFT
));
6014 data
->icld_ClickEvent
.entry
= data
->icld_SelectionLastClicked
? &data
->icld_SelectionLastClicked
->ie_IconListEntry
: NULL
;
6015 SET(obj
, MUIA_IconList_Clicked
, (IPTR
)&data
->icld_ClickEvent
);
6019 SET(obj
, MUIA_IconList_DoubleClick
, TRUE
);
6022 if ((!data
->mouse_pressed
) &&
6023 (!doubleclicked
|| (doubleclicked
&& (data
->icld_SelectionLastClicked
== NULL
))))
6025 data
->last_secs
= message
->imsg
->Seconds
;
6026 data
->last_mics
= message
->imsg
->Micros
;
6028 /* After a double click you often open a new window
6029 * and since Zune doesn't not support the faking
6030 * of SELECTUP events only change the Events
6031 * if not doubleclicked on an icon */
6033 data
->mouse_pressed
|= LEFT_BUTTON
;
6035 /* Start listening to mouse events */
6036 if (!(data
->ehn
.ehn_Events
& IDCMP_MOUSEMOVE
))
6038 DoMethod(_win(obj
), MUIM_Window_RemEventHandler
, (IPTR
)&data
->ehn
);
6039 data
->ehn
.ehn_Events
|= IDCMP_MOUSEMOVE
;
6040 DoMethod(_win(obj
), MUIM_Window_AddEventHandler
, (IPTR
)&data
->ehn
);
6044 return MUI_EventHandlerRC_Eat
;
6047 else if (message
->imsg
->Code
== MIDDLEDOWN
)
6049 if (!data
->mouse_pressed
)
6051 data
->mouse_pressed
|= MIDDLE_BUTTON
;
6053 data
->click_x
= data
->icld_ViewX
+ mx
;
6054 data
->click_y
= data
->icld_ViewY
+ my
;
6056 /* Start listening to mouse events */
6057 if (!(data
->ehn
.ehn_Events
& IDCMP_MOUSEMOVE
))
6059 DoMethod(_win(obj
), MUIM_Window_RemEventHandler
, (IPTR
)&data
->ehn
);
6060 data
->ehn
.ehn_Events
|= IDCMP_MOUSEMOVE
;
6061 DoMethod(_win(obj
), MUIM_Window_AddEventHandler
, (IPTR
)&data
->ehn
);
6067 if (message
->imsg
->Code
== SELECTUP
)
6069 if (data
->icld_LassoActive
== TRUE
)
6071 #if defined(DEBUG_ILC_EVENTS) || defined(DEBUG_ILC_LASSO)
6072 D(bug("[IconList] %s: Removing Lasso\n", __PRETTY_FUNCTION__
));
6074 /* End Lasso-selection */
6075 struct Rectangle old_lasso
;
6076 struct IconEntry
*node
= NULL
;
6077 struct Window
*thisWindow
= NULL
;
6079 /* Stop handling INTUITICKS */
6080 GET(obj
, MUIA_Window
, &thisWindow
);
6083 ModifyIDCMP(thisWindow
, (thisWindow
->IDCMPFlags
& ~(IDCMP_INTUITICKS
)));
6084 if ((data
->ehn
.ehn_Events
& IDCMP_INTUITICKS
))
6086 DoMethod(_win(obj
), MUIM_Window_RemEventHandler
, (IPTR
)&data
->ehn
);
6087 data
->ehn
.ehn_Events
&= ~IDCMP_INTUITICKS
;
6088 DoMethod(_win(obj
), MUIM_Window_AddEventHandler
, (IPTR
)&data
->ehn
);
6091 /* Clear Lasso Frame.. */
6092 GetAbsoluteLassoRect(data
, &old_lasso
);
6093 IconList_InvertLassoOutlines(obj
, data
, &old_lasso
);
6095 data
->icld_LassoActive
= FALSE
;
6097 /* Remove Lasso flag from affected icons.. */
6098 #if defined(__AROS__)
6099 ForeachNode(&data
->icld_IconList
, node
)
6101 Foreach_Node(&data
->icld_IconList
, node
);
6104 if (node
->ie_Flags
& ICONENTRY_FLAG_LASSO
)
6106 node
->ie_Flags
&= ~ICONENTRY_FLAG_LASSO
;
6109 SET(obj
, MUIA_IconList_SelectionChanged
, TRUE
);
6111 else if (data
->icld_LVMAttribs
->lmva_LastSelectedColumn
!= -1)
6113 ULONG orig_sortflags
= data
->icld_SortFlags
;
6115 if (data
->icld_LVMAttribs
->lmva_SortColumn
== data
->icld_LVMAttribs
->lmva_LastSelectedColumn
)
6117 if (data
->icld_SortFlags
& MUIV_IconList_Sort_Reverse
)
6118 data
->icld_SortFlags
&= ~MUIV_IconList_Sort_Reverse
;
6120 data
->icld_SortFlags
|= MUIV_IconList_Sort_Reverse
;
6123 switch (data
->icld_LVMAttribs
->lmva_LastSelectedColumn
)
6126 data
->icld_SortFlags
&= ~MUIV_IconList_Sort_Orders
;
6127 data
->icld_SortFlags
|= MUIV_IconList_Sort_ByName
;
6131 data
->icld_SortFlags
&= ~MUIV_IconList_Sort_Orders
;
6132 data
->icld_SortFlags
|= MUIV_IconList_Sort_BySize
;
6135 case INDEX_LASTACCESS
:
6136 data
->icld_SortFlags
&= ~MUIV_IconList_Sort_Orders
;
6137 data
->icld_SortFlags
|= MUIV_IconList_Sort_ByDate
;
6141 if (orig_sortflags
!= data
->icld_SortFlags
)
6143 data
->icld_LVMAttribs
->lmva_SortColumn
= data
->icld_LVMAttribs
->lmva_LastSelectedColumn
;
6145 data
->icld_LVMAttribs
->lmva_LastSelectedColumn
= -1;
6147 DoMethod(obj
, MUIM_IconList_Sort
);
6151 data
->mouse_pressed
&= ~LEFT_BUTTON
;
6154 if (message
->imsg
->Code
== MIDDLEUP
)
6156 data
->mouse_pressed
&= ~MIDDLE_BUTTON
;
6159 /* Stop listening to mouse move events is no buttons pressed */
6160 if ((data
->ehn
.ehn_Events
& IDCMP_MOUSEMOVE
) && !data
->mouse_pressed
)
6162 DoMethod(_win(obj
),MUIM_Window_RemEventHandler
, (IPTR
)&data
->ehn
);
6163 data
->ehn
.ehn_Events
&= ~IDCMP_MOUSEMOVE
;
6164 DoMethod(_win(obj
),MUIM_Window_AddEventHandler
, (IPTR
)&data
->ehn
);
6169 case IDCMP_INTUITICKS
:
6171 #if defined(DEBUG_ILC_EVENTS)
6172 D(bug("[IconList] %s: IDCMP_INTUITICKS (%d, %d)\n", __PRETTY_FUNCTION__
, mx
, my
));
6174 if ((data
->icld_LassoActive
== FALSE
)||(!(data
->mouse_pressed
& LEFT_BUTTON
)))
6178 if (((mx
>= 0) && (mx
<= _mwidth(obj
))) &&
6179 ((my
>= 0) && (my
<= _mheight(obj
))))
6183 case IDCMP_MOUSEMOVE
:
6184 #if defined(DEBUG_ILC_EVENTS)
6185 D(bug("[IconList] %s: IDCMP_MOUSEMOVE\n", __PRETTY_FUNCTION__
));
6187 if (data
->mouse_pressed
& LEFT_BUTTON
)
6192 if (data
->icld_SelectionLastClicked
&& (data
->icld_LassoActive
== FALSE
) &&
6193 ((abs(move_x
- data
->click_x
) >= 2) || (abs(move_y
- data
->click_y
) >= 2)))
6195 LONG touch_x
, touch_y
;
6197 /* Entry(s) being dragged .... */
6198 DoMethod(_win(obj
),MUIM_Window_RemEventHandler
, (IPTR
)&data
->ehn
);
6199 data
->ehn
.ehn_Events
&= ~IDCMP_MOUSEMOVE
;
6200 DoMethod(_win(obj
),MUIM_Window_AddEventHandler
, (IPTR
)&data
->ehn
);
6202 data
->mouse_pressed
&= ~LEFT_BUTTON
;
6204 /* Pass view relative coords */
6205 touch_x
= move_x
+ data
->icld_ViewX
;
6206 touch_y
= move_y
+ data
->icld_ViewY
;
6207 DoMethod(obj
,MUIM_DoDrag
, touch_x
, touch_y
, 0);
6209 else if (data
->icld_LassoActive
== TRUE
)
6211 #if defined(DEBUG_ILC_EVENTS) || defined(DEBUG_ILC_LASSO)
6212 D(bug("[IconList] %s: Update Lasso\n", __PRETTY_FUNCTION__
));
6215 struct Rectangle new_lasso
,
6217 struct Rectangle iconrect
;
6219 struct IconEntry
*node
= NULL
;
6220 // struct IconEntry *new_selected = NULL;
6222 /* Remove previous Lasso frame */
6223 GetAbsoluteLassoRect(data
, &old_lasso
);
6224 IconList_InvertLassoOutlines(obj
, data
, &old_lasso
);
6226 /* if the mouse leaves our visible area scroll the view */
6227 if (mx
< 0 || mx
>= _mwidth(obj
) || my
< 0 || my
>= _mheight(obj
))
6229 LONG newleft
= data
->icld_ViewX
;
6230 LONG newtop
= data
->icld_ViewY
;
6232 if (mx
>= _mwidth(obj
)) newleft
+= (mx
- _mwidth(obj
));
6233 else if (mx
< 0) newleft
+= mx
;
6234 if (my
>= _mheight(obj
)) newtop
+= (my
- _mheight(obj
));
6235 else if (my
< 0) newtop
+= my
;
6237 if (newleft
+ _mwidth(obj
) > data
->icld_AreaWidth
) newleft
= data
->icld_AreaWidth
- _mwidth(obj
);
6238 if (newleft
< 0) newleft
= 0;
6240 if (newtop
+ _mheight(obj
) > data
->icld_AreaHeight
) newtop
= data
->icld_AreaHeight
- _mheight(obj
);
6241 if (newtop
< 0) newtop
= 0;
6243 if ((newleft
!= data
->icld_ViewX
) || (newtop
!= data
->icld_ViewY
))
6245 SetAttrs(obj
, MUIA_Virtgroup_Left
, newleft
, MUIA_Virtgroup_Top
, newtop
, TAG_DONE
);
6249 /* update Lasso coordinates */
6250 data
->icld_LassoRectangle
.MaxX
= mx
- data
->view_rect
.MinX
+ data
->icld_ViewX
;
6251 data
->icld_LassoRectangle
.MaxY
= my
- data
->view_rect
.MinY
+ data
->icld_ViewY
;
6253 /* get absolute Lasso coordinates */
6254 GetAbsoluteLassoRect(data
, &new_lasso
);
6256 LONG current
= 0, startIndex
= 0, endIndex
= 0;
6258 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
6260 LONG minY
= data
->icld_LassoRectangle
.MinY
,
6261 maxY
= data
->icld_LassoRectangle
.MaxY
;
6270 startIndex
= ((minY
+ 1) - data
->icld_LVMAttribs
->lmva_HeaderHeight
) / data
->icld_LVMAttribs
->lmva_RowHeight
;
6271 endIndex
= ((maxY
- 1) - data
->icld_LVMAttribs
->lmva_HeaderHeight
) / data
->icld_LVMAttribs
->lmva_RowHeight
;
6274 #if defined(__AROS__)
6275 ForeachNode(&data
->icld_IconList
, node
)
6277 Foreach_Node(&data
->icld_IconList
, node
);
6280 IPTR update_entry
= (IPTR
)NULL
;
6282 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
6284 if (node
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
6286 update_entry
= FALSE
;
6288 if ((current
>= startIndex
) && (current
<= endIndex
))
6290 //Entry is inside our lasso ..
6291 if (!(node
->ie_Flags
& ICONENTRY_FLAG_LASSO
))
6293 /* check if entry was already selected before */
6294 if (node
->ie_Flags
& ICONENTRY_FLAG_SELECTED
)
6296 Remove(&node
->ie_SelectionNode
);
6297 node
->ie_Flags
&= ~ICONENTRY_FLAG_SELECTED
;
6301 AddTail(&data
->icld_SelectionList
, &node
->ie_SelectionNode
);
6302 node
->ie_Flags
|= ICONENTRY_FLAG_SELECTED
;
6304 node
->ie_Flags
|= ICONENTRY_FLAG_LASSO
;
6305 update_entry
= (IPTR
)node
;
6308 else if (node
->ie_Flags
& ICONENTRY_FLAG_LASSO
)
6310 //Entry is no longer inside our lasso - revert its selected state
6311 if (node
->ie_Flags
& ICONENTRY_FLAG_SELECTED
)
6313 Remove(&node
->ie_SelectionNode
);
6314 node
->ie_Flags
&= ~ICONENTRY_FLAG_SELECTED
;
6318 AddTail(&data
->icld_SelectionList
, &node
->ie_SelectionNode
);
6319 node
->ie_Flags
|= ICONENTRY_FLAG_SELECTED
;
6321 node
->ie_Flags
&= ~ICONENTRY_FLAG_LASSO
;
6322 update_entry
= (IPTR
)node
;
6330 if (node
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
6332 iconrect
.MinX
= node
->ie_IconX
;
6333 iconrect
.MaxX
= node
->ie_IconX
+ node
->ie_AreaWidth
- 1;
6334 iconrect
.MinY
= node
->ie_IconY
;
6335 iconrect
.MaxY
= node
->ie_IconY
+ node
->ie_AreaHeight
- 1;
6336 if ((data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
) &&
6337 (node
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
))
6339 iconrect
.MinX
+= ((data
->icld_IconAreaLargestWidth
- node
->ie_AreaWidth
)/2);
6340 iconrect
.MaxX
+= ((data
->icld_IconAreaLargestWidth
- node
->ie_AreaWidth
)/2);
6343 if ((((new_lasso
.MaxX
+ data
->icld_ViewX
) >= iconrect
.MinX
) && ((new_lasso
.MinX
+ data
->icld_ViewX
) <= iconrect
.MaxX
)) &&
6344 (((new_lasso
.MaxY
+ data
->icld_ViewY
) >= iconrect
.MinY
) && ((new_lasso
.MinY
+ data
->icld_ViewY
) <= iconrect
.MaxY
)))
6346 //Entry is inside our lasso ..
6347 if (!(node
->ie_Flags
& ICONENTRY_FLAG_LASSO
))
6349 /* check if entry was already selected before */
6350 if (node
->ie_Flags
& ICONENTRY_FLAG_SELECTED
)
6352 Remove(&node
->ie_SelectionNode
);
6353 node
->ie_Flags
&= ~ICONENTRY_FLAG_SELECTED
;
6357 AddTail(&data
->icld_SelectionList
, &node
->ie_SelectionNode
);
6358 node
->ie_Flags
|= ICONENTRY_FLAG_SELECTED
;
6360 node
->ie_Flags
|= ICONENTRY_FLAG_LASSO
;
6361 update_entry
= (IPTR
)node
;
6364 else if (node
->ie_Flags
& ICONENTRY_FLAG_LASSO
)
6366 //Entry is no longer inside our lasso - revert its selected state
6367 if (node
->ie_Flags
& ICONENTRY_FLAG_SELECTED
)
6369 Remove(&node
->ie_SelectionNode
);
6370 node
->ie_Flags
&= ~ICONENTRY_FLAG_SELECTED
;
6374 AddTail(&data
->icld_SelectionList
, &node
->ie_SelectionNode
);
6375 node
->ie_Flags
|= ICONENTRY_FLAG_SELECTED
;
6377 node
->ie_Flags
&= ~ICONENTRY_FLAG_LASSO
;
6378 update_entry
= (IPTR
)node
;
6384 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
6385 data
->update_entry
= (struct IconEntry
*)update_entry
;
6386 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
6389 /* Draw Lasso frame */
6390 IconList_InvertLassoOutlines(obj
, data
, &new_lasso
);
6393 return MUI_EventHandlerRC_Eat
;
6395 else if (data
->mouse_pressed
& MIDDLE_BUTTON
)
6397 /* Content is being scrolled */
6398 LONG newleft
, newtop
;
6400 newleft
= data
->click_x
- mx
;
6401 newtop
= data
->click_y
- my
;
6403 if (newleft
+ _mwidth(obj
) > data
->icld_AreaWidth
) newleft
= data
->icld_AreaWidth
- _mwidth(obj
);
6404 if (newleft
< 0) newleft
= 0;
6406 if (newtop
+ _mheight(obj
) > data
->icld_AreaHeight
) newtop
= data
->icld_AreaHeight
- _mheight(obj
);
6407 if (newtop
< 0) newtop
= 0;
6409 if ((newleft
!= data
->icld_ViewX
) || (newtop
!= data
->icld_ViewY
))
6411 SetAttrs(obj
, MUIA_Virtgroup_Left
, newleft
,
6412 MUIA_Virtgroup_Top
, newtop
,
6416 return MUI_EventHandlerRC_Eat
;
6427 ///MUIM_IconList_NextIcon()
6428 /**************************************************************************
6429 MUIM_IconList_NextIcon
6430 **************************************************************************/
6431 IPTR
IconList__MUIM_IconList_NextIcon(struct IClass
*CLASS
, Object
*obj
, struct MUIP_IconList_NextIcon
*message
)
6433 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
6434 struct IconEntry
*node
= NULL
;
6435 struct IconList_Entry
*ent
= NULL
;
6436 IPTR node_successor
= (IPTR
)NULL
;
6438 if (message
->entry
== NULL
) return (IPTR
)NULL
;
6439 ent
= *message
->entry
;
6441 #if defined(DEBUG_ILC_FUNCS)
6442 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
6445 if ((IPTR
)ent
== (IPTR
)MUIV_IconList_NextIcon_Start
)
6447 D(bug("[IconList] %s: Finding First Entry ..\n", __PRETTY_FUNCTION__
));
6448 if (message
->nextflag
== MUIV_IconList_NextIcon_Selected
)
6450 node
= (struct IconEntry
*)GetHead(&data
->icld_SelectionList
);
6453 node
= (struct IconEntry
*)((IPTR
)node
- ((IPTR
)&node
->ie_SelectionNode
- (IPTR
)node
));
6456 else if (message
->nextflag
== MUIV_IconList_NextIcon_Visible
)
6458 node
= (struct IconEntry
*)GetHead(&data
->icld_IconList
);
6459 while (node
!= NULL
)
6461 if (node
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
6464 node
= (struct IconEntry
*)GetSucc(&node
->ie_IconNode
);
6468 else if ((IPTR
)ent
!= (IPTR
)MUIV_IconList_NextIcon_End
)
6470 node
= (struct IconEntry
*)((IPTR
)ent
- ((IPTR
)&node
->ie_IconListEntry
- (IPTR
)node
));
6471 if (message
->nextflag
== MUIV_IconList_NextIcon_Selected
)
6473 node_successor
= (IPTR
)GetSucc(&node
->ie_SelectionNode
);
6474 if (node_successor
!= (IPTR
)NULL
)
6475 node
= (struct IconEntry
*)((IPTR
)node_successor
- ((IPTR
)&node
->ie_SelectionNode
- (IPTR
)node
));
6478 D(bug("[IconList] %s: GetSucc() == NULL\n", __PRETTY_FUNCTION__
));
6482 else if (message
->nextflag
== MUIV_IconList_NextIcon_Visible
)
6484 node
= (struct IconEntry
*)GetSucc(&node
->ie_IconNode
);
6485 while (node
!= NULL
)
6487 if (node
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
6490 node
= (struct IconEntry
*)GetSucc(&node
->ie_IconNode
);
6497 D(bug("[IconList] %s: Returning MUIV_IconList_NextIcon_End\n", __PRETTY_FUNCTION__
));
6499 *message
->entry
= (struct IconList_Entry
*)MUIV_IconList_NextIcon_End
;
6503 D(bug("[IconList] %s: Returning entry for '%s'\n", __PRETTY_FUNCTION__
, node
->ie_IconListEntry
.label
));
6505 *message
->entry
= &node
->ie_IconListEntry
;
6512 ///MUIM_IconList_GetIconPrivate()
6513 /**************************************************************************
6514 MUIM_IconList_GetIconPrivate
6515 **************************************************************************/
6516 IPTR
IconList__MUIM_IconList_GetIconPrivate(struct IClass
*CLASS
, Object
*obj
, struct MUIP_IconList_GetIconPrivate
*message
)
6518 // struct IconList_DATA *data = INST_DATA(CLASS, obj);
6519 struct IconEntry
*node
= NULL
;
6521 if (message
->entry
== NULL
) return (IPTR
)NULL
;
6523 node
= (struct IconEntry
*)((IPTR
)message
->entry
- ((IPTR
)&node
->ie_IconListEntry
- (IPTR
)node
));
6528 ///MUIM_CreateDragImage()
6529 /**************************************************************************
6530 MUIM_CreateDragImage
6531 **************************************************************************/
6532 IPTR
IconList__MUIM_CreateDragImage(struct IClass
*CLASS
, Object
*obj
, struct MUIP_CreateDragImage
*message
)
6534 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
6535 struct MUI_DragImage
*img
= NULL
;
6538 BOOL transp
= XGET(obj
, MUIA_IconList_DragImageTransparent
);
6540 #if defined(DEBUG_ILC_FUNCS) || defined(DEBUG_ILC_ICONDRAGDROP)
6541 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
6544 if (!(data
->icld_SelectionLastClicked
))
6545 DoSuperMethodA(CLASS
, obj
, (Msg
)message
);
6547 if ((img
= (struct MUI_DragImage
*)AllocVec(sizeof(struct MUIP_CreateDragImage
), MEMF_CLEAR
)))
6549 struct Node
*node
= NULL
;
6550 struct IconEntry
*entry
= NULL
;
6552 #if defined(CREATE_FULL_DRAGIMAGE)
6553 #if defined(__AROS__)
6554 ForeachNode(&data
->icld_SelectionList
, node
)
6556 Foreach_Node(&data
->icld_SelectionList
, node
);
6559 entry
= (struct IconEntry
*)((IPTR
)node
- ((IPTR
)&entry
->ie_SelectionNode
- (IPTR
)entry
));
6560 if ((entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
) && (entry
->ie_Flags
& ICONENTRY_FLAG_SELECTED
))
6562 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) != ICONLIST_DISP_MODELIST
)
6564 if ((first_x
== -1) || ((first_x
!= -1) && (entry
->ie_IconX
< first_x
))) first_x
= entry
->ie_IconX
;
6565 if ((first_y
== -1) || ((first_y
!= -1) && (entry
->ie_IconY
< first_y
))) first_y
= entry
->ie_IconY
;
6567 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_ROUGH
)
6569 if ((entry
->ie_IconX
+ entry
->ie_AreaWidth
) > img
->width
) img
->width
= entry
->ie_IconX
+ entry
->ie_AreaWidth
;
6570 if ((entry
->ie_IconY
+ entry
->ie_AreaHeight
) > img
->height
) img
->height
= entry
->ie_IconY
+ entry
->ie_AreaHeight
;
6573 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
6575 if ((entry
->ie_IconX
+ data
->icld_IconAreaLargestWidth
) > img
->width
) img
->width
= entry
->ie_IconX
+ data
->icld_IconAreaLargestWidth
;
6576 if ((entry
->ie_IconY
+ data
->icld_IconAreaLargestHeight
) > img
->height
) img
->height
= entry
->ie_IconY
+ data
->icld_IconAreaLargestHeight
;
6581 img
->height
+= data
->icld_LVMAttribs
->lmva_RowHeight
;
6585 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
6588 first_y
= -message
->touchy
;
6589 img
->width
= data
->icld_LVMAttribs
->lmva_ColumnWidth
[data
->icld_LVMAttribs
->lmva_ColumnPos
[INDEX_TYPE
]] +
6590 data
->icld_LVMAttribs
->lmva_ColumnWidth
[data
->icld_LVMAttribs
->lmva_ColumnPos
[INDEX_NAME
]];
6595 img
->width
= (img
->width
- first_x
) + 2;
6596 img
->height
= (img
->height
- first_y
) + 2;
6599 entry
= data
->icld_SelectionLastClicked
;
6600 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
6602 img
->width
= _mright(obj
) - _mleft(obj
);
6603 img
->height
= data
->icld_LVMAttribs
->lmva_RowHeight
;
6609 img
->width
= entry
->ie_IconWidth
;
6610 img
->height
= entry
->ie_IconHeight
;
6611 first_x
= entry
->ie_IconX
;
6612 first_y
= entry
->ie_IconY
;
6618 /* Request 32-bit, because the image will have alpha channel */
6619 img
->bm
= AllocBitMap(img
->width
, img
->height
, 32, BMF_CLEAR
, NULL
);
6623 LONG depth
= GetBitMapAttr(_screen(obj
)->RastPort
.BitMap
, BMA_DEPTH
);
6624 img
->bm
= AllocBitMap(img
->width
, img
->height
, depth
, BMF_CLEAR
, _screen(obj
)->RastPort
.BitMap
);
6629 struct RastPort temprp
;
6630 InitRastPort(&temprp
);
6631 temprp
.BitMap
= img
->bm
;
6634 #if defined(CREATE_FULL_DRAGIMAGE)
6635 ForeachNode(&data
->icld_SelectionList
, node
)
6637 entry
= (struct IconEntry
*)((IPTR
)node
- ((IPTR
)&entry
->ie_SelectionNode
- (IPTR
)entry
));
6638 if ((entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
) && (entry
->ie_Flags
& ICONENTRY_FLAG_SELECTED
))
6640 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
6642 struct Rectangle field_rect
;
6643 ULONG selected
= entry
->ie_Flags
& ICONENTRY_FLAG_SELECTED
;
6644 entry
->ie_Flags
&= ~ICONENTRY_FLAG_SELECTED
; /* Drawing as not selected actually looks better */
6646 field_rect
.MinX
= 0; field_rect
.MaxX
= img
->width
- 1;
6647 field_rect
.MinY
= minY
; field_rect
.MaxY
= field_rect
.MinY
+ data
->icld_LVMAttribs
->lmva_RowHeight
- 1;
6648 RenderEntryField(obj
, data
, entry
, &field_rect
, INDEX_TYPE
, TRUE
, FALSE
, &temprp
);
6650 field_rect
.MinX
= data
->icld_LVMAttribs
->lmva_ColumnWidth
[data
->icld_LVMAttribs
->lmva_ColumnPos
[INDEX_TYPE
]] - 1;
6651 field_rect
.MaxX
= img
->width
- 1;
6652 field_rect
.MinY
= minY
; field_rect
.MaxY
= field_rect
.MinY
+ data
->icld_LVMAttribs
->lmva_RowHeight
- 1;
6653 RenderEntryField(obj
, data
, entry
, &field_rect
, INDEX_NAME
, FALSE
, FALSE
, &temprp
);
6655 minY
+= data
->icld_LVMAttribs
->lmva_RowHeight
;
6657 entry
->ie_Flags
|= selected
;
6661 LONG offsetx
, offsety
;
6663 IconList_GetIconImageOffsets(data
, entry
, &offsetx
, &offsety
);
6667 &temprp
, entry
->ie_DiskObj
, NULL
,
6668 (entry
->ie_IconX
+ 1) - first_x
+ offsetx
, (entry
->ie_IconY
+ 1) - first_y
+ offsety
,
6670 __iconList_DrawIconStateTags
6676 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
6678 SetABPenDrMd(&temprp
, _pens(obj
)[MPEN_SHINE
], 0, JAM1
);
6679 RectFill(&temprp
, 0, 0, img
->width
, img
->height
);
6685 &temprp
, entry
->ie_DiskObj
, NULL
,
6688 __iconList_DrawIconStateTags
6693 RastPortSetAlpha(&temprp
, data
->click_x
, data
->click_y
, img
->width
, img
->height
, 0xC0, RPALPHAFLAT
);
6694 DeinitRastPort(&temprp
);
6697 /* Convert view relative coords to drag image relative. This is done because the "object" that is being
6698 * dragged is virtual (its a collection of icons) and the coords passed to DoDrag are not relative to this
6701 img
->touchx
= first_x
+ message
->touchx
;
6702 img
->touchy
= first_y
+ message
->touchy
;
6705 img
->flags
= MUIF_DRAGIMAGE_SOURCEALPHA
;
6713 ///MUIM_DeleteDragImage()
6714 /**************************************************************************
6715 MUIM_DeleteDragImage
6716 **************************************************************************/
6717 IPTR
IconList__MUIM_DeleteDragImage(struct IClass
*CLASS
, Object
*obj
, struct MUIP_DeleteDragImage
*message
)
6719 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
6721 #if defined(DEBUG_ILC_FUNCS) || defined(DEBUG_ILC_ICONDRAGDROP)
6722 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
6725 if (!(data
->icld_SelectionLastClicked
)) return DoSuperMethodA(CLASS
,obj
,(Msg
)message
);
6729 if (message
->di
->bm
)
6730 FreeBitMap(message
->di
->bm
);
6731 FreeVec(message
->di
);
6738 /**************************************************************************
6740 **************************************************************************/
6741 IPTR
IconList__MUIM_DragQuery(struct IClass
*CLASS
, Object
*obj
, struct MUIP_DragQuery
*message
)
6743 #if defined(DEBUG_ILC_FUNCS) || defined(DEBUG_ILC_ICONDRAGDROP)
6744 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
6747 /* TODO: highlight the possible drop target entry .. */
6749 if (message
->obj
== obj
)
6750 return MUIV_DragQuery_Accept
;
6753 BOOL is_iconlist
= FALSE
;
6754 struct IClass
*msg_cl
= OCLASS(message
->obj
);
6758 if (msg_cl
== CLASS
)
6763 msg_cl
= msg_cl
->cl_Super
;
6766 return MUIV_DragQuery_Accept
;
6769 return MUIV_DragQuery_Refuse
;
6774 /**************************************************************************
6776 **************************************************************************/
6777 IPTR
IconList__MUIM_DragDrop(struct IClass
*CLASS
, Object
*obj
, struct MUIP_DragDrop
*message
)
6779 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
6781 #if defined(DEBUG_ILC_FUNCS) || defined(DEBUG_ILC_ICONDRAGDROP)
6782 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
6785 struct IconList_Entry
*entry
= (IPTR
)MUIV_IconList_NextIcon_Start
;
6787 if (data
->icld_DragDropEvent
)
6789 struct IconList_Drop_SourceEntry
*clean_node
;
6790 #if defined(DEBUG_ILC_ICONDRAGDROP)
6791 D(bug("[IconList] %s: Cleaning existing IconList_Drop_Event @ %p\n", __PRETTY_FUNCTION__
, data
->icld_DragDropEvent
));
6793 while ((clean_node
= (struct IconList_Drop_SourceEntry
*)RemTail(&data
->icld_DragDropEvent
->drop_SourceList
)) != NULL
)
6795 FreeVec(clean_node
->dropse_Node
.ln_Name
);
6796 FreeMem(clean_node
, sizeof(struct IconList_Drop_SourceEntry
));
6798 FreeVec(data
->icld_DragDropEvent
->drop_TargetPath
);
6799 FreeMem(data
->icld_DragDropEvent
, sizeof(struct IconList_Drop_Event
));
6800 data
->icld_DragDropEvent
= NULL
;
6803 /* SANITY CHECK: Get first selected entry from SOURCE iconlist */
6804 DoMethod(message
->obj
, MUIM_IconList_NextIcon
, MUIV_IconList_NextIcon_Selected
, (IPTR
)&entry
);
6806 if ((entry
) && ((IPTR
)entry
!= MUIV_IconList_NextIcon_End
))
6808 /* Ok.. atleast one entry was dropped .. */
6809 char tmp_dirbuff
[256];
6810 BPTR tmp_dirlock
= (BPTR
) NULL
;
6812 BOOL iconMove
= FALSE
;
6813 struct IconEntry
*node
= NULL
;
6814 struct IconEntry
*drop_target_node
= NULL
;
6815 STRPTR directory_path
= NULL
;
6816 struct IconList_Drop_Event
*dragDropEvent
= NULL
;
6818 GET(obj
, MUIA_IconDrawerList_Drawer
, &directory_path
);
6820 /* Properly expand the name incase it uses devices rather than volumes */
6821 if (directory_path
!= NULL
)
6823 tmp_dirlock
= Lock(directory_path
, SHARED_LOCK
);
6826 if (NameFromLock(tmp_dirlock
, tmp_dirbuff
, 256) != 0)
6828 directory_path
= tmp_dirbuff
;
6830 UnLock(tmp_dirlock
);
6833 if ((dragDropEvent
= AllocMem(sizeof(struct IconList_Drop_Event
), MEMF_CLEAR
)) == NULL
)
6835 #if defined(DEBUG_ILC_ICONDRAGDROP)
6836 D(bug("[IconList] %s: Failed to allocate IconList_Drop_Event Storage!\n", __PRETTY_FUNCTION__
));
6840 #if defined(DEBUG_ILC_ICONDRAGDROP)
6841 D(bug("[IconList] %s: Allocated IconList_Drop_Event @ %p\n", __PRETTY_FUNCTION__
, dragDropEvent
));
6844 NewList(&dragDropEvent
->drop_SourceList
);
6846 /* go through list and check if dropped on entry */
6849 #if defined(__AROS__)
6850 ForeachNode(&data
->icld_IconList
, node
)
6852 Foreach_Node(&data
->icld_IconList
, node
);
6855 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
6857 if (node
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
6859 ULONG rowTop
= _mtop(obj
) + (rowCount
* data
->icld_LVMAttribs
->lmva_RowHeight
);
6860 rowTop
+= data
->icld_LVMAttribs
->lmva_HeaderHeight
;
6862 if (((message
->x
> _mleft(obj
)) && (message
->x
< _mright(obj
)))
6863 && ((message
->y
> rowTop
) && (message
->y
< (rowTop
+ data
->icld_LVMAttribs
->lmva_RowHeight
))))
6865 drop_target_node
= node
;
6874 struct Rectangle iconbox
;
6875 LONG click_x
= message
->x
- _mleft(obj
);
6876 LONG click_y
= message
->y
- _mtop(obj
);
6877 iconbox
.MinX
= node
->ie_IconX
- data
->icld_ViewX
;
6878 iconbox
.MaxX
= (node
->ie_IconX
+ node
->ie_AreaWidth
) - data
->icld_ViewX
;
6879 iconbox
.MinY
= node
->ie_IconY
- data
->icld_ViewY
;
6880 iconbox
.MaxY
= (node
->ie_IconY
+ node
->ie_AreaHeight
)- data
->icld_ViewY
;
6882 if ((node
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
) &&
6883 (click_x
>= iconbox
.MinX
) &&
6884 (click_x
< iconbox
.MaxX
) &&
6885 (click_y
>= iconbox
.MinY
) &&
6886 (click_y
< iconbox
.MaxY
))
6888 drop_target_node
= node
;
6894 /* Additional filter - if same window and the target entry is selected (==dragged), then it was intended as a move */
6895 if ((message
->obj
== obj
) && (drop_target_node
) && (drop_target_node
->ie_Flags
& ICONENTRY_FLAG_SELECTED
))
6896 drop_target_node
= NULL
;
6898 if ((drop_target_node
!= NULL
) &&
6899 ((drop_target_node
->ie_IconListEntry
.type
== ST_SOFTLINK
) ||
6900 (drop_target_node
->ie_IconListEntry
.type
== ST_ROOT
) ||
6901 (drop_target_node
->ie_IconListEntry
.type
== ST_USERDIR
) ||
6902 (drop_target_node
->ie_IconListEntry
.type
== ST_LINKDIR
) ||
6903 (drop_target_node
->ie_IconListEntry
.type
== ST_FILE
) ||
6904 (drop_target_node
->ie_IconListEntry
.type
== ST_LINKFILE
)))
6906 /* Dropped on some entry */
6907 if ((drop_target_node
->ie_IconListEntry
.type
!= ST_ROOT
) && (drop_target_node
->ie_IconListEntry
.type
!= ST_SOFTLINK
))
6911 int fulllen
= strlen(directory_path
) + strlen(drop_target_node
->ie_IconListEntry
.label
) + 2;
6913 if ((dragDropEvent
->drop_TargetPath
= AllocVec(fulllen
, MEMF_CLEAR
)) == NULL
)
6915 bug("[IconList] %s: Failed to allocate IconList_Drop_Event->drop_TargetPath Storage!\n", __PRETTY_FUNCTION__
);
6918 strcpy(dragDropEvent
->drop_TargetPath
, directory_path
);
6919 AddPart(dragDropEvent
->drop_TargetPath
, drop_target_node
->ie_IconListEntry
.label
, fulllen
);
6926 if ((dragDropEvent
->drop_TargetPath
= AllocVec(strlen(drop_target_node
->ie_IconListEntry
.label
) + 1, MEMF_CLEAR
)) == NULL
)
6928 bug("[IconList] %s: Failed to allocate IconList_Drop_Event->drop_TargetPath Storage!\n", __PRETTY_FUNCTION__
);
6931 strcpy(dragDropEvent
->drop_TargetPath
, drop_target_node
->ie_IconListEntry
.label
);
6934 #if defined(DEBUG_ILC_ICONDRAGDROP)
6935 D(bug("[IconList] %s: Target Entry Full Path = '%s'\n", __PRETTY_FUNCTION__
, dragDropEvent
->drop_TargetPath
));
6937 /* mark the Entry the selection was dropped on*/
6938 //drop_target_node->ie_Flags |= ICONENTRY_FLAG_SELECTED;
6939 //data->icld_UpdateMode = UPDATE_SINGLEENTRY;
6940 //data->update_entry = drop_target_node;
6941 //MUI_Redraw(obj,MADF_DRAWUPDATE);
6945 /* Not dropped on entry -> get path of DESTINATION iconlist */
6946 /* Note: directory_path is NULL when dropped on Wanderer's desktop */
6947 if ((message
->obj
!= obj
) && directory_path
)
6949 #if defined(DEBUG_ILC_ICONDRAGDROP)
6950 D(bug("[IconList] %s: drop entry: Icons dropped in window '%s'\n", __PRETTY_FUNCTION__
, directory_path
));
6953 if ((dragDropEvent
->drop_TargetPath
= AllocVec(strlen(directory_path
) + 1, MEMF_CLEAR
)) != NULL
)
6955 strcpy(dragDropEvent
->drop_TargetPath
, directory_path
);
6959 #if defined(DEBUG_ILC_ICONDRAGDROP)
6960 D(bug("[IconList] %s: Failed to allocate IconList_Drop_Event->drop_TargetPath Storage!\n", __PRETTY_FUNCTION__
));
6965 else if (message
->obj
== obj
)
6967 #if defined(DEBUG_ILC_ICONDRAGDROP)
6968 D(bug("[IconList] %s: drop entry: Entry Move detected ..\n", __PRETTY_FUNCTION__
));
6972 /* Adjust entry posiions .. */
6973 #if defined(DEBUG_ILC_ICONDRAGDROP)
6974 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
));
6976 LONG offset_x
= message
->x
- (data
->click_x
+ _mleft(obj
));
6977 LONG offset_y
= message
->y
- (data
->click_y
+ _mtop(obj
));
6979 entry
= (IPTR
)MUIV_IconList_NextIcon_Start
;
6980 while ((IPTR
)entry
!= MUIV_IconList_NextIcon_End
)
6982 DoMethod(message
->obj
, MUIM_IconList_NextIcon
, MUIV_IconList_NextIcon_Selected
, (IPTR
)&entry
);
6984 if ((IPTR
)entry
!= MUIV_IconList_NextIcon_End
)
6986 entry
->ile_IconEntry
->ie_IconX
+= offset_x
;
6987 entry
->ile_IconEntry
->ie_IconY
+= offset_y
;
6988 /* Remember new position as provided */
6989 DoMethod(obj
, MUIM_IconList_PropagateEntryPos
, entry
->ile_IconEntry
);
6991 SET(obj
, MUIA_IconList_IconMoved
, (IPTR
)entry
); // Now notify
6993 MUI_Redraw(obj
,MADF_DRAWOBJECT
);
6994 DoMethod(obj
, MUIM_IconList_CoordsSort
);
6998 #if defined(DEBUG_ILC_ICONDRAGDROP)
6999 D(bug("[IconList] %s: Icons Dropped on Wanderer Desktop (unhandled)!\n", __PRETTY_FUNCTION__
));
7009 /* Create list of entries to copy .. */
7010 entry
= (IPTR
)MUIV_IconList_NextIcon_Start
;
7011 while ((IPTR
)entry
!= MUIV_IconList_NextIcon_End
)
7013 DoMethod(message
->obj
, MUIM_IconList_NextIcon
, MUIV_IconList_NextIcon_Selected
, (IPTR
)&entry
);
7015 if ((IPTR
)entry
!= MUIV_IconList_NextIcon_End
)
7017 struct IconList_Drop_SourceEntry
*sourceEntry
= NULL
;
7018 sourceEntry
= AllocMem(sizeof(struct IconList_Drop_SourceEntry
), MEMF_CLEAR
);
7019 if ((entry
->type
!= ST_ROOT
) && (entry
->type
!= ST_SOFTLINK
))
7024 GET(message
->obj
, MUIA_IconDrawerList_Drawer
, &path
);
7025 /* Properly expand the location in case it uses devices rather than volumes */
7028 tmp_dirlock
= Lock(path
, SHARED_LOCK
);
7031 if (NameFromLock(tmp_dirlock
, tmp_dirbuff
, 256))
7035 UnLock(tmp_dirlock
);
7038 if (strcasecmp(dragDropEvent
->drop_TargetPath
, path
) != 0)
7040 fulllen
= strlen(path
) + strlen(entry
->ile_IconEntry
->ie_IconNode
.ln_Name
) + 2;
7041 sourceEntry
->dropse_Node
.ln_Name
= AllocVec(fulllen
, MEMF_CLEAR
);
7042 if (sourceEntry
->dropse_Node
.ln_Name
!= NULL
)
7044 strcpy(sourceEntry
->dropse_Node
.ln_Name
, path
);
7045 AddPart(sourceEntry
->dropse_Node
.ln_Name
, entry
->label
, fulllen
);
7047 #if defined(DEBUG_ILC_ICONDRAGDROP)
7048 D(bug("[IconList] %s: Source Entry (Full Path) = '%s'\n", __PRETTY_FUNCTION__
, sourceEntry
->dropse_Node
.ln_Name
));
7055 sourceEntry
->dropse_Node
.ln_Name
= AllocVec(strlen(entry
->label
) + 1, MEMF_CLEAR
);
7056 if (sourceEntry
->dropse_Node
.ln_Name
!= NULL
)
7057 strcpy(sourceEntry
->dropse_Node
.ln_Name
, entry
->label
);
7058 #if defined(DEBUG_ILC_ICONDRAGDROP)
7059 D(bug("[IconList] %s: Source Entry = '%s'\n", __PRETTY_FUNCTION__
, sourceEntry
->dropse_Node
.ln_Name
));
7063 if ((sourceEntry
->dropse_Node
.ln_Name
!= NULL
) && (strcasecmp(dragDropEvent
->drop_TargetPath
, sourceEntry
->dropse_Node
.ln_Name
) != 0))
7066 AddTail(&dragDropEvent
->drop_SourceList
, &sourceEntry
->dropse_Node
);
7070 #if defined(DEBUG_ILC_ICONDRAGDROP)
7071 D(bug("[IconList] %s: Source == Dest, Skipping!\n", __PRETTY_FUNCTION__
));
7073 FreeVec(sourceEntry
->dropse_Node
.ln_Name
);
7074 FreeMem(sourceEntry
, sizeof(struct IconList_Drop_SourceEntry
));
7080 dragDropEvent
->drop_TargetObj
= obj
;
7082 #if defined(DEBUG_ILC_ICONDRAGDROP)
7083 D(bug("[IconList] %s: Causing DROP notification..\n", __PRETTY_FUNCTION__
));
7085 SET(obj
, MUIA_IconList_IconsDropped
, (IPTR
)dragDropEvent
);
7086 DoMethod(obj
, MUIM_IconList_CoordsSort
);
7090 FreeVec(dragDropEvent
->drop_TargetPath
);
7091 FreeMem(dragDropEvent
, sizeof(struct IconList_Drop_Event
));
7097 #if defined(DEBUG_ILC_ICONDRAGDROP)
7098 D(bug("[IconList] %s: BUG - DragDrop received with no source icons!\n", __PRETTY_FUNCTION__
));
7100 NNSET(obj
, MUIA_IconList_IconsDropped
, (IPTR
)NULL
);
7104 return DoSuperMethodA(CLASS
, obj
, (Msg
)message
);
7108 ///MUIM_UnselectAll()
7109 /**************************************************************************
7111 **************************************************************************/
7112 IPTR
IconList__MUIM_IconList_UnselectAll(struct IClass
*CLASS
, Object
*obj
, Msg message
)
7114 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
7115 struct Node
*node
= NULL
, *next_node
= NULL
;
7116 BOOL changed
= FALSE
;
7118 #if defined(DEBUG_ILC_FUNCS)
7119 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
7122 data
->icld_SelectionLastClicked
= NULL
;
7123 data
->icld_FocusIcon
= NULL
;
7124 #if defined(__AROS__)
7125 ForeachNodeSafe(&data
->icld_SelectionList
, node
, next_node
)
7127 Foreach_NodeSafe(&data
->icld_SelectionList
, node
, next_node
);
7130 struct IconEntry
*entry
= (struct IconEntry
*)((IPTR
)node
- ((IPTR
)&entry
->ie_SelectionNode
- (IPTR
)entry
));
7131 BOOL update_entry
= FALSE
;
7133 if (entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
7135 if (entry
->ie_Flags
& ICONENTRY_FLAG_SELECTED
)
7138 entry
->ie_Flags
&= ~ICONENTRY_FLAG_SELECTED
;
7139 update_entry
= TRUE
;
7141 if (entry
->ie_Flags
& ICONENTRY_FLAG_FOCUS
)
7143 entry
->ie_Flags
&= ~ICONENTRY_FLAG_FOCUS
;
7144 update_entry
= TRUE
;
7151 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
7152 data
->update_entry
= entry
;
7153 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
7158 SET(obj
, MUIA_IconList_SelectionChanged
, TRUE
);
7165 /**************************************************************************
7167 **************************************************************************/
7168 IPTR
IconList__MUIM_IconList_SelectAll(struct IClass
*CLASS
, Object
*obj
, Msg message
)
7170 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
7171 struct IconEntry
*node
= NULL
;
7172 BOOL changed
= FALSE
;
7174 #if defined(DEBUG_ILC_FUNCS)
7175 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
7178 node
= (struct IconEntry
*)GetHead(&data
->icld_IconList
);
7180 while (node
!= NULL
)
7182 if (node
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
7184 BOOL update_entry
= FALSE
;
7186 if (!(node
->ie_Flags
& ICONENTRY_FLAG_SELECTED
))
7188 AddTail(&data
->icld_SelectionList
, &node
->ie_SelectionNode
);
7189 node
->ie_Flags
|= ICONENTRY_FLAG_SELECTED
;
7190 update_entry
= TRUE
;
7192 data
->icld_SelectionLastClicked
= node
;
7194 else if (node
->ie_Flags
& ICONENTRY_FLAG_FOCUS
)
7196 node
->ie_Flags
&= ~ICONENTRY_FLAG_FOCUS
;
7197 update_entry
= TRUE
;
7203 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
7204 data
->update_entry
= node
;
7205 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
7208 node
= (struct IconEntry
*)GetSucc(&node
->ie_IconNode
);
7211 if ((data
->icld_SelectionLastClicked
) && (data
->icld_SelectionLastClicked
!= data
->icld_FocusIcon
))
7213 data
->icld_FocusIcon
= data
->icld_SelectionLastClicked
;
7214 if (!(data
->icld_FocusIcon
->ie_Flags
& ICONENTRY_FLAG_FOCUS
))
7216 data
->icld_FocusIcon
->ie_Flags
&= ~ICONENTRY_FLAG_FOCUS
;
7217 data
->icld_FocusIcon
->ie_Flags
|= ICONENTRY_FLAG_FOCUS
;
7218 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
7219 data
->update_entry
= data
->icld_FocusIcon
;
7220 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
7225 SET(obj
, MUIA_IconList_SelectionChanged
, TRUE
);
7231 ///IconList__MUIM_IconList_CoordsSort()
7232 IPTR
IconList__MUIM_IconList_CoordsSort(struct IClass
*CLASS
, Object
*obj
, struct MUIP_IconList_Sort
*message
)
7234 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
7236 struct IconEntry
*entry
= NULL
,
7239 struct List list_VisibleIcons
;
7240 struct List list_HiddenIcons
;
7241 // struct List list_UnplacedIcons;
7244 perform a quick sort of the iconlist based on entry coords
7245 this method DOESNT cause any visual output.
7247 #if defined(DEBUG_ILC_FUNCS) || defined(DEBUG_ILC_ICONSORTING)
7248 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
7251 NewList((struct List
*)&list_VisibleIcons
);
7252 NewList((struct List
*)&list_HiddenIcons
);
7254 /*move list into our local list struct(s)*/
7255 while ((entry
= (struct IconEntry
*)RemTail((struct List
*)&data
->icld_IconList
)))
7257 if (entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
7259 AddHead((struct List
*)&list_VisibleIcons
, (struct Node
*)&entry
->ie_IconNode
);
7262 AddHead((struct List
*)&list_HiddenIcons
, (struct Node
*)&entry
->ie_IconNode
);
7265 while ((entry
= (struct IconEntry
*)RemTail((struct List
*)&list_VisibleIcons
)))
7267 if ((test_icon
= (struct IconEntry
*)GetTail(&data
->icld_IconList
)) != NULL
)
7269 while (test_icon
!= NULL
)
7271 if (((data
->icld_DisplayFlags
& ICONLIST_DISP_VERTICAL
) && (test_icon
->ie_IconX
> entry
->ie_IconX
)) ||
7272 (!(data
->icld_DisplayFlags
& ICONLIST_DISP_VERTICAL
) && (test_icon
->ie_IconY
> entry
->ie_IconY
)))
7274 test_icon
= (struct IconEntry
*)GetPred(&test_icon
->ie_IconNode
);
7280 while (test_icon
!= NULL
)
7282 if (((data
->icld_DisplayFlags
& ICONLIST_DISP_VERTICAL
) && (test_icon
->ie_IconY
> entry
->ie_IconY
)) ||
7283 (!(data
->icld_DisplayFlags
& ICONLIST_DISP_VERTICAL
) && (test_icon
->ie_IconX
> entry
->ie_IconX
)))
7285 test_icon
= (struct IconEntry
*)GetPred(&test_icon
->ie_IconNode
);
7290 Insert((struct List
*)&data
->icld_IconList
, (struct Node
*)&entry
->ie_IconNode
, (struct Node
*)&test_icon
->ie_IconNode
);
7293 AddTail((struct List
*)&data
->icld_IconList
, (struct Node
*)&entry
->ie_IconNode
);
7295 #if defined(DEBUG_ILC_ICONSORTING)
7296 D(bug("[IconList] %s: Done\n", __PRETTY_FUNCTION__
));
7299 while ((entry
= (struct IconEntry
*)RemTail((struct List
*)&list_HiddenIcons
)))
7301 AddTail((struct List
*)&data
->icld_IconList
, (struct Node
*)&entry
->ie_IconNode
);
7304 #if defined(DEBUG_ILC_ICONSORTING_DUMP)
7305 #if defined(__AROS__)
7306 ForeachNode(&data
->icld_IconList
, entry
)
7308 Foreach_Node(&data
->icld_IconList
, entry
);
7311 D(bug("[IconList] %s: %d %d '%s'\n", __PRETTY_FUNCTION__
, entry
->ie_IconX
, entry
->ie_IconY
, entry
->ie_IconListEntry
.label
));
7320 /**************************************************************************
7321 MUIM_Sort - sortsort
7322 **************************************************************************/
7323 IPTR
IconList__MUIM_IconList_Sort(struct IClass
*CLASS
, Object
*obj
, struct MUIP_IconList_Sort
*message
)
7325 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
7326 struct IconEntry
*entry
= NULL
,
7330 struct List list_VisibleIcons
,
7334 BOOL sortme
, reversable
= TRUE
, enqueue
= FALSE
;
7335 int i
, visible_count
= 0;
7337 #if defined(DEBUG_ILC_FUNCS) || defined(DEBUG_ILC_ICONSORTING)
7338 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
7341 /* Reset incase view options have changed .. */
7342 data
->icld_IconAreaLargestWidth
= 0;
7343 data
->icld_IconAreaLargestHeight
= 0;
7344 data
->icld_IconLargestHeight
= 0;
7345 data
->icld_LabelLargestHeight
= 0;
7347 #if defined(DEBUG_ILC_ICONSORTING)
7348 D(bug("[IconList] %s: Sort-Flags : %x\n", __PRETTY_FUNCTION__
, (data
->icld_SortFlags
& MUIV_IconList_Sort_MASK
)));
7350 NewList((struct List
*)&list_VisibleIcons
);
7351 NewList((struct List
*)&list_SortedIcons
);
7352 NewList((struct List
*)&list_HiddenIcons
);
7354 /*move list into our local list struct(s)*/
7355 while ((entry
= (struct IconEntry
*)RemTail((struct List
*)&data
->icld_IconList
)))
7357 if (!(entry
->ie_Flags
& ICONENTRY_FLAG_HASICON
))
7359 if (data
->icld_DisplayFlags
& ICONLIST_DISP_SHOWINFO
)
7361 if (entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
7363 entry
->ie_Flags
&= ~(ICONENTRY_FLAG_VISIBLE
|ICONENTRY_FLAG_NEEDSUPDATE
);
7366 else if (!(entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
))
7368 entry
->ie_Flags
|= (ICONENTRY_FLAG_VISIBLE
|ICONENTRY_FLAG_NEEDSUPDATE
);
7373 if (!(entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
))
7375 entry
->ie_Flags
|= (ICONENTRY_FLAG_VISIBLE
|ICONENTRY_FLAG_NEEDSUPDATE
);
7379 /* Now we have fixed visibility lets dump them into the correct list for sorting */
7380 if (entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
7382 if(entry
->ie_AreaWidth
> data
->icld_IconAreaLargestWidth
) data
->icld_IconAreaLargestWidth
= entry
->ie_AreaWidth
;
7383 if(entry
->ie_AreaHeight
> data
->icld_IconAreaLargestHeight
) data
->icld_IconAreaLargestHeight
= entry
->ie_AreaHeight
;
7384 if(entry
->ie_IconHeight
> data
->icld_IconLargestHeight
) data
->icld_IconLargestHeight
= entry
->ie_IconHeight
;
7385 if((entry
->ie_AreaHeight
- entry
->ie_IconHeight
) > data
->icld_LabelLargestHeight
) data
->icld_LabelLargestHeight
= entry
->ie_AreaHeight
- entry
->ie_IconHeight
;
7387 if (((data
->icld_SortFlags
& MUIV_IconList_Sort_AutoSort
) == 0) && (entry
->ie_ProvidedIconX
== NO_ICON_POSITION
))
7388 AddTail((struct List
*)&list_VisibleIcons
, (struct Node
*)&entry
->ie_IconNode
);
7390 AddHead((struct List
*)&list_VisibleIcons
, (struct Node
*)&entry
->ie_IconNode
);
7395 if (entry
->ie_Flags
& ICONENTRY_FLAG_SELECTED
)
7397 Remove(&entry
->ie_SelectionNode
);
7399 entry
->ie_Flags
&= ~(ICONENTRY_FLAG_SELECTED
|ICONENTRY_FLAG_FOCUS
);
7400 if (data
->icld_SelectionLastClicked
== entry
) data
->icld_SelectionLastClicked
= NULL
;
7401 if (data
->icld_FocusIcon
== entry
) data
->icld_FocusIcon
= data
->icld_SelectionLastClicked
;
7402 AddHead((struct List
*)&list_HiddenIcons
, (struct Node
*)&entry
->ie_IconNode
);
7406 /* Copy each visible entry back to the main list, sorting as we go*/
7407 while ((entry
= (struct IconEntry
*)RemHead((struct List
*)&list_VisibleIcons
)))
7409 icon1
= (struct IconEntry
*)GetHead(&list_SortedIcons
);
7414 if (visible_count
> 1)
7416 #if defined(DEBUG_ILC_ICONSORTING)
7417 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
));
7421 if(((icon1
->ie_IconListEntry
.type
== ST_ROOT
) || (icon1
->ie_IconListEntry
.type
== ST_LINKDIR
) || (icon1
->ie_IconListEntry
.type
== ST_LINKFILE
))
7422 || (data
->icld_SortFlags
& MUIV_IconList_Sort_DrawersMixed
))
7424 /*volume list or drawers mixed*/
7430 if ((icon1
->ie_IconListEntry
.type
== ST_USERDIR
) && (entry
->ie_IconListEntry
.type
== ST_USERDIR
))
7436 if ((icon1
->ie_IconListEntry
.type
!= ST_USERDIR
) && (entry
->ie_IconListEntry
.type
!= ST_USERDIR
))
7440 /* we are the first drawer to arrive or we need to insert ourselves
7441 due to being sorted to the end of the drawers*/
7443 if ((!icon2
|| icon2
->ie_IconListEntry
.type
== ST_USERDIR
) &&
7444 (entry
->ie_IconListEntry
.type
== ST_USERDIR
) &&
7445 (icon1
->ie_IconListEntry
.type
!= ST_USERDIR
))
7447 #if defined(DEBUG_ILC_ICONSORTING)
7448 D(bug("[IconList] %s: force %s\n", __PRETTY_FUNCTION__
, entry
->ie_IconListEntry
.label
));
7460 if ((data
->icld_SortFlags
& MUIV_IconList_Sort_AutoSort
) == 0)
7462 if ((entry
->ie_ProvidedIconX
!= NO_ICON_POSITION
) && (entry
->ie_ProvidedIconY
!= NO_ICON_POSITION
))
7470 if (data
->icld_SortFlags
& MUIV_IconList_Sort_ByDate
)
7473 i
= CompareDates((const struct DateStamp
*)&entry
->ie_FileInfoBlock
->fib_Date
,(const struct DateStamp
*)&icon1
->ie_FileInfoBlock
->fib_Date
);
7475 else if (data
->icld_SortFlags
& MUIV_IconList_Sort_BySize
)
7477 /* Sort by Size .. */
7478 i
= entry
->ie_FileInfoBlock
->fib_Size
- icon1
->ie_FileInfoBlock
->fib_Size
;
7480 else if ((data
->icld_SortFlags
& MUIV_IconList_Sort_ByType
) && ((entry
->ie_IconListEntry
.type
== ST_FILE
) || (entry
->ie_IconListEntry
.type
== ST_USERDIR
)))
7482 /* Sort by Type .. */
7483 /* TODO: Sort icons based on type using datatypes */
7487 /* Sort by Name .. */
7488 i
= Stricmp(entry
->ie_IconListEntry
.label
, icon1
->ie_IconListEntry
.label
);
7489 if ((data
->icld_SortFlags
& MUIV_IconList_Sort_DrawersMixed
) == 0) enqueue
= TRUE
;
7493 if ((reversable
) && data
->icld_SortFlags
& MUIV_IconList_Sort_Reverse
)
7502 icon1
= (struct IconEntry
*)GetSucc(&icon1
->ie_IconNode
);
7505 Insert((struct List
*)&list_SortedIcons
, (struct Node
*)&entry
->ie_IconNode
, (struct Node
*)&icon2
->ie_IconNode
);
7509 /* Quickly resort based on node priorities .. */
7510 while ((entry
= (struct IconEntry
*)RemHead((struct List
*)&list_SortedIcons
)))
7512 Enqueue((struct List
*)&data
->icld_IconList
, (struct Node
*)&entry
->ie_IconNode
);
7517 while ((entry
= (struct IconEntry
*)RemHead((struct List
*)&list_SortedIcons
)))
7519 AddTail((struct List
*)&data
->icld_IconList
, (struct Node
*)&entry
->ie_IconNode
);
7523 DoMethod(obj
, MUIM_IconList_PositionIcons
);
7524 MUI_Redraw(obj
, MADF_DRAWOBJECT
);
7526 if ((data
->icld_SortFlags
& MUIV_IconList_Sort_Orders
) != 0)
7528 DoMethod(obj
, MUIM_IconList_CoordsSort
);
7530 /* leave hidden icons on a seperate list to speed up normal list parsing ? */
7531 while ((entry
= (struct IconEntry
*)RemHead((struct List
*)&list_HiddenIcons
)))
7533 AddTail((struct List
*)&data
->icld_IconList
, (struct Node
*)&entry
->ie_IconNode
);
7536 SET(obj
, MUIA_IconList_Changed
, TRUE
);
7542 ///MUIM_DragReport()
7543 /**************************************************************************
7544 MUIM_DragReport. Since MUI doesn't change the drop object if the dragged
7545 object is moved above another window (while still in the bounds of the
7546 orginal drop object) we must do it here manually to be compatible with
7547 MUI. Maybe Zune should fix this bug somewhen.
7548 **************************************************************************/
7549 IPTR
IconList__MUIM_DragReport(struct IClass
*CLASS
, Object
*obj
, struct MUIP_DragReport
*message
)
7551 struct Window
*wnd
= _window(obj
);
7552 struct Layer
*l
= NULL
;
7554 #if defined(DEBUG_ILC_FUNCS) || defined(DEBUG_ILC_ICONDRAGDROP)
7555 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
7558 LockLayerInfo(&wnd
->WScreen
->LayerInfo
);
7559 l
= WhichLayer(&wnd
->WScreen
->LayerInfo
, wnd
->LeftEdge
+ message
->x
, wnd
->TopEdge
+ message
->y
);
7560 UnlockLayerInfo(&wnd
->WScreen
->LayerInfo
);
7562 if (l
!= wnd
->WLayer
) return MUIV_DragReport_Abort
;
7564 return MUIV_DragReport_Continue
;
7568 ///MUIM_IconList_UnknownDropDestination()
7569 /**************************************************************************
7570 MUIM_IconList_UnknownDropDestination
7571 **************************************************************************/
7572 IPTR
IconList__MUIM_UnknownDropDestination(struct IClass
*CLASS
, Object
*obj
, struct MUIP_UnknownDropDestination
*message
)
7574 #if defined(DEBUG_ILC_FUNCS) || defined(DEBUG_ILC_ICONDRAGDROP)
7575 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
7577 #if defined(DEBUG_ILC_ICONDRAGDROP)
7578 D(bug("[IconList] %s: icons dropped on custom window \n", __PRETTY_FUNCTION__
));
7581 SET(obj
, MUIA_IconList_AppWindowDrop
, (IPTR
)message
); /* Now notify */
7587 ///MUIM_IconList_MakeEntryVisible()
7588 /**************************************************************************
7589 Move the visible area so that the selected entry becomes visible ..
7590 **************************************************************************/
7591 IPTR
IconList__MUIM_IconList_MakeEntryVisible(struct IClass
*CLASS
, Object
*obj
, struct MUIP_IconList_MakeEntryVisible
*message
)
7593 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
7594 BOOL viewmoved
= FALSE
;
7595 struct Rectangle iconrect
, viewrect
;
7597 #if defined(DEBUG_ILC_FUNCS)
7598 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
7601 viewrect
.MinX
= data
->icld_ViewX
;
7602 viewrect
.MaxX
= data
->icld_ViewX
+ data
->icld_AreaWidth
;
7603 viewrect
.MinY
= data
->icld_ViewY
;
7604 viewrect
.MaxY
= data
->icld_ViewY
+ data
->icld_AreaHeight
;
7606 IconList_GetIconAreaRectangle(obj
, data
, message
->entry
, &iconrect
);
7608 if (!(RectAndRect(&viewrect
, &iconrect
)))
7611 if (message
->entry
->ie_IconX
< data
->icld_ViewX
)
7612 data
->icld_ViewX
= message
->entry
->ie_IconX
;
7613 else if (message
->entry
->ie_IconX
> (data
->icld_ViewX
+ data
->icld_AreaWidth
))
7614 data
->icld_ViewX
= (message
->entry
->ie_IconX
+ message
->entry
->ie_AreaWidth
) - data
->icld_AreaWidth
;
7616 if (message
->entry
->ie_IconY
< data
->icld_ViewY
)
7617 data
->icld_ViewY
= message
->entry
->ie_IconX
;
7618 else if (message
->entry
->ie_IconY
> (data
->icld_ViewY
+ data
->icld_AreaHeight
))
7619 data
->icld_ViewY
= (message
->entry
->ie_IconY
+ message
->entry
->ie_AreaHeight
) - data
->icld_AreaHeight
;
7624 #if defined(DEBUG_ILC_ICONRENDERING)
7625 D(bug("[IconList]: %s: call SetSuperAttrs()\n", __PRETTY_FUNCTION__
));
7627 SetSuperAttrs(CLASS
, obj
, MUIA_Virtgroup_Left
, data
->icld_ViewX
,
7628 MUIA_Virtgroup_Top
, data
->icld_ViewY
,
7631 #if defined(DEBUG_ILC_ICONRENDERING)
7632 D(bug("[IconList]: %s: call SetAttrs()\n", __PRETTY_FUNCTION__
));
7634 SetAttrs(obj
, MUIA_Virtgroup_Left
, data
->icld_ViewX
,
7635 MUIA_Virtgroup_Top
, data
->icld_ViewY
,
7638 #if defined(DEBUG_ILC_ICONRENDERING)
7639 D(bug("[IconList]: %s: call MUI_Redraw()\n", __PRETTY_FUNCTION__
));
7641 MUI_Redraw(obj
,MADF_DRAWOBJECT
);
7646 #if defined(WANDERER_BUILTIN_ICONLIST)
7647 BOOPSI_DISPATCHER(IPTR
,IconList_Dispatcher
, CLASS
, obj
, message
)
7649 #if defined(__AROS__)
7650 switch (message
->MethodID
)
7652 struct IClass
*CLASS
= cl
;
7655 switch (msg
->MethodID
)
7658 case OM_NEW
: return IconList__OM_NEW(CLASS
, obj
, (struct opSet
*)message
);
7659 case OM_DISPOSE
: return IconList__OM_DISPOSE(CLASS
, obj
, message
);
7660 case OM_SET
: return IconList__OM_SET(CLASS
, obj
, (struct opSet
*)message
);
7661 case OM_GET
: return IconList__OM_GET(CLASS
, obj
, (struct opGet
*)message
);
7663 case MUIM_Family_AddTail
: return IconList__MUIM_Family_AddTail(CLASS
, obj
, (APTR
)message
);
7664 case MUIM_Family_AddHead
: return IconList__MUIM_Family_AddHead(CLASS
, obj
, (APTR
)message
);
7666 case MUIM_Family_Remove
: return IconList__MUIM_Family_Remove(CLASS
, obj
, (APTR
)message
);
7668 case MUIM_Setup
: return IconList__MUIM_Setup(CLASS
, obj
, (struct MUIP_Setup
*)message
);
7670 case MUIM_Show
: return IconList__MUIM_Show(CLASS
,obj
, (struct MUIP_Show
*)message
);
7671 case MUIM_Hide
: return IconList__MUIM_Hide(CLASS
,obj
, (struct MUIP_Hide
*)message
);
7672 case MUIM_Cleanup
: return IconList__MUIM_Cleanup(CLASS
, obj
, (struct MUIP_Cleanup
*)message
);
7673 case MUIM_AskMinMax
: return IconList__MUIM_AskMinMax(CLASS
, obj
, (struct MUIP_AskMinMax
*)message
);
7674 case MUIM_Draw
: return IconList__MUIM_Draw(CLASS
, obj
, (struct MUIP_Draw
*)message
);
7675 #if defined(__AROS__)
7676 case MUIM_Layout
: return IconList__MUIM_Layout(CLASS
, obj
, (struct MUIP_Layout
*)message
);
7678 case MUIM_HandleEvent
: return IconList__MUIM_HandleEvent(CLASS
, obj
, (struct MUIP_HandleEvent
*)message
);
7679 case MUIM_CreateDragImage
: return IconList__MUIM_CreateDragImage(CLASS
, obj
, (APTR
)message
);
7680 case MUIM_DeleteDragImage
: return IconList__MUIM_DeleteDragImage(CLASS
, obj
, (APTR
)message
);
7681 case MUIM_DragQuery
: return IconList__MUIM_DragQuery(CLASS
, obj
, (APTR
)message
);
7682 case MUIM_DragReport
: return IconList__MUIM_DragReport(CLASS
, obj
, (APTR
)message
);
7683 case MUIM_DragDrop
: return IconList__MUIM_DragDrop(CLASS
, obj
, (APTR
)message
);
7684 #if defined(__AROS__)
7685 case MUIM_UnknownDropDestination
: return IconList__MUIM_UnknownDropDestination(CLASS
, obj
, (APTR
)message
);
7687 case MUIM_IconList_Update
: return IconList__MUIM_IconList_Update(CLASS
, obj
, (APTR
)message
);
7688 case MUIM_IconList_Clear
: return IconList__MUIM_IconList_Clear(CLASS
, obj
, (APTR
)message
);
7689 case MUIM_IconList_RethinkDimensions
: return IconList__MUIM_IconList_RethinkDimensions(CLASS
, obj
, (APTR
)message
);
7690 case MUIM_IconList_CreateEntry
: return IconList__MUIM_IconList_CreateEntry(CLASS
, obj
, (APTR
)message
);
7691 case MUIM_IconList_UpdateEntry
: return IconList__MUIM_IconList_UpdateEntry(CLASS
, obj
, (APTR
)message
);
7692 case MUIM_IconList_DestroyEntry
: return IconList__MUIM_IconList_DestroyEntry(CLASS
, obj
, (APTR
)message
);
7693 case MUIM_IconList_DrawEntry
: return IconList__MUIM_IconList_DrawEntry(CLASS
, obj
, (APTR
)message
);
7694 case MUIM_IconList_DrawEntryLabel
: return IconList__MUIM_IconList_DrawEntryLabel(CLASS
, obj
, (APTR
)message
);
7695 case MUIM_IconList_NextIcon
: return IconList__MUIM_IconList_NextIcon(CLASS
, obj
, (APTR
)message
);
7696 case MUIM_IconList_GetIconPrivate
: return IconList__MUIM_IconList_GetIconPrivate(CLASS
, obj
, (APTR
)message
);
7697 case MUIM_IconList_UnselectAll
: return IconList__MUIM_IconList_UnselectAll(CLASS
, obj
, (APTR
)message
);
7698 case MUIM_IconList_Sort
: return IconList__MUIM_IconList_Sort(CLASS
, obj
, (APTR
)message
);
7699 case MUIM_IconList_CoordsSort
: return IconList__MUIM_IconList_CoordsSort(CLASS
, obj
, (APTR
)message
);
7700 case MUIM_IconList_PositionIcons
: return IconList__MUIM_IconList_PositionIcons(CLASS
, obj
, (APTR
)message
);
7701 case MUIM_IconList_SelectAll
: return IconList__MUIM_IconList_SelectAll(CLASS
, obj
, (APTR
)message
);
7702 case MUIM_IconList_MakeEntryVisible
: return IconList__MUIM_IconList_MakeEntryVisible(CLASS
, obj
, (APTR
)message
);
7705 return DoSuperMethodA(CLASS
, obj
, message
);
7707 BOOPSI_DISPATCHER_END
7709 #if defined(__AROS__)
7710 /* Class descriptor. */
7711 const struct __MUIBuiltinClass _MUI_IconList_desc
= {
7714 sizeof(struct IconList_DATA
),
7715 (void*)IconList_Dispatcher
7718 #endif /* WANDERER_BUILTIN_ICONLIST */
7720 #if !defined(__AROS__)
7721 struct MUI_CustomClass
*initIconListClass(void)
7723 return (struct MUI_CustomClass
*) MUI_CreateCustomClass(NULL
, MUIC_Area
, NULL
, sizeof(struct IconList_DATA
), ENTRY(IconList_Dispatcher
));