2 Copyright © 2001-2012, 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 <graphics/gfx.h>
40 #include <graphics/view.h>
41 #include <graphics/rpattr.h>
42 #include <workbench/icon.h>
43 #include <workbench/workbench.h>
46 #include <devices/rawkeycodes.h>
47 #include <clib/alib_protos.h>
49 #include <devices_AROS/rawkeycodes.h>
53 #include <proto/exec.h>
54 #include <proto/graphics.h>
55 #include <proto/utility.h>
56 #include <proto/dos.h>
57 #include <proto/icon.h>
58 #include <proto/layers.h>
59 #include <proto/dos.h>
60 #include <proto/iffparse.h>
63 #include <prefs/prefhdr.h>
64 #include <prefs/wanderer.h>
66 #include <prefs_AROS/prefhdr.h>
67 #include <prefs_AROS/wanderer.h>
70 #include <proto/cybergraphics.h>
73 #include <cybergraphx/cybergraphics.h>
75 #include <cybergraphx_AROS/cybergraphics.h>
79 #if defined(__AMIGA__) && !defined(__PPC__)
80 #define NO_INLINE_STDARG
82 #include <proto/intuition.h>
83 #include <proto/muimaster.h>
84 #include <libraries/mui.h>
85 #include "iconlist_attributes.h"
86 #include "icon_attributes.h"
88 #include "iconlist_private.h"
89 #include "iconlistview.h"
91 #if !defined(__AROS__)
95 #define D(x) if (DEBUG) x
97 #define bug DebugPrintF
106 #define _between(a,x,b) ((x)>=(a) && (x)<=(b))
107 #define _isinobject(x,y) (_between(_mleft(obj),(x),_mright (obj)) \
108 && _between(_mtop(obj) ,(y),_mbottom(obj)))
110 extern struct Library
*MUIMasterBase
;
112 static struct Hook __iconlist_UpdateLabels_hook
;
114 // N.B: We Handle frame/background rendering so make sure icon.library doesnt do it ..
115 static struct TagItem __iconList_DrawIconStateTags
[] = {
116 { ICONDRAWA_Frameless
, TRUE
},
117 { ICONDRAWA_Borderless
, TRUE
},
118 { ICONDRAWA_EraseBackground
, FALSE
},
123 static struct TagItem __iconList_BackBuffLayerTags
[] =
125 { LA_Visible
, FALSE
},
130 #ifndef NO_ICON_POSITION
131 #define NO_ICON_POSITION (0x8000000) /* belongs to workbench/workbench.h */
134 #define UPDATE_HEADERENTRY 1
135 #define UPDATE_SINGLEENTRY 2
136 #define UPDATE_SCROLL 3
137 #define UPDATE_RESIZE 4
139 #define LEFT_BUTTON 1
140 #define RIGHT_BUTTON 2
141 #define MIDDLE_BUTTON 4
143 #define ICONLIST_DRAWMODE_NORMAL 1
144 #define ICONLIST_DRAWMODE_FAST 2
146 /* Values used for List View-Mode */
147 #define COLOR_COLUMN_BACKGROUND 0
148 #define COLOR_COLUMN_BACKGROUND_SORTED 1
149 #define COLOR_COLUMN_BACKGROUND_LASSO 2
150 #define COLOR_COLUMN_BACKGROUND_LASSO_SORTED 3
152 #define COLOR_SELECTED_BACKGROUND 4
153 #define COLOR_SELECTED_BACKGROUND_SORTED 5
155 #define MIN_COLUMN_WIDTH 10
157 #define COLUMN_ALIGN_LEFT 0
158 #define COLUMN_ALIGN_CENTER 1
159 #define COLUMN_ALIGN_RIGHT 2
161 #define LINE_SPACING_TOP 2
162 #define LINE_SPACING_BOTTOM 2
163 #define LINE_EXTRAHEIGHT (LINE_SPACING_TOP + LINE_SPACING_BOTTOM)
165 #define LINE_SPACING_LEFT 1
166 #define LINE_SPACING_RIGHT 1
167 #define LINE_EXTRAWIDTH (LINE_SPACING_LEFT + LINE_SPACING_RIGHT)
169 #define ENTRY_SPACING_LEFT 1
170 #define ENTRY_SPACING_RIGHT 1
171 #define ENTRY_EXTRAWIDTH (ENTRY_SPACING_LEFT + ENTRY_SPACING_RIGHT)
173 #define HEADERLINE_SPACING_TOP 3
174 #define HEADERLINE_SPACING_BOTTOM 3
175 #define HEADERLINE_EXTRAHEIGHT (HEADERLINE_SPACING_TOP + HEADERLINE_SPACING_BOTTOM)
177 #define HEADERLINE_SPACING_LEFT 1
178 #define HEADERLINE_SPACING_RIGHT 1
179 #define HEADERLINE_EXTRAWIDTH (HEADERLINE_SPACING_LEFT + HEADERLINE_SPACING_RIGHT)
181 #define HEADERENTRY_SPACING_LEFT 4
182 #define HEADERENTRY_SPACING_RIGHT 4
183 #define HEADERENTRY_EXTRAWIDTH (HEADERENTRY_SPACING_LEFT + HEADERENTRY_SPACING_RIGHT)
195 /**************************************************************************
197 **************************************************************************/
199 #define ForeachPrevNode(list, node) \
202 node = (void *)(((struct List *)(list))->lh_TailPred); \
203 ((struct Node *)(node))->ln_Pred; \
204 node = (void *)(((struct Node *)(node))->ln_Pred) \
207 #define RPALPHAFLAT (1 << 0)
208 #define RPALPHARADIAL (1 << 1)
210 static void RastPortSetAlpha(struct RastPort
*arport
, ULONG ax
, ULONG ay
, ULONG width
, ULONG height
, UBYTE val
, UBYTE alphamode
)
213 ULONG alphaval
, pixelval
;
214 APTR buffer
, pixelptr
;
216 if ((buffer
= AllocVec(width
* height
* sizeof(ULONG
), MEMF_ANY
)) == NULL
)
219 ReadPixelArray(buffer
, 0, 0, width
* sizeof(ULONG
), arport
, 0, 0, width
, height
, RECTFMT_ARGB
);
223 for (y
= 0; y
< height
; y
++)
225 for (x
= 0; x
< width
; x
++)
227 if((pixelval
= *((ULONG
*)pixelptr
)))
229 if (alphamode
== RPALPHARADIAL
){
230 //Set the alpha value based on distance from ax,ay
234 pixelval
= (pixelval
& 0xffffff00) | alphaval
;
235 *((ULONG
*)pixelptr
) = pixelval
;
237 pixelptr
+= sizeof(ULONG
);
241 WritePixelArray(buffer
, 0, 0, width
* sizeof(ULONG
), arport
, 0, 0, width
, height
, RECTFMT_ARGB
);
246 // Entry/Label Area support functions
247 static int RectAndRect(struct Rectangle
*a
, struct Rectangle
*b
)
249 if ((a
->MinX
> b
->MaxX
) || (a
->MinY
> b
->MaxY
) || (a
->MaxX
< b
->MinX
) || (a
->MaxY
< b
->MinY
))
256 static int RegionAndRect(struct Region
* a
, struct Rectangle
*b
)
258 D(bug("Region (%d, %d)(%d, %d), Rect (%d, %d)(%d, %d)\n",
259 (LONG
)a
->bounds
.MinX
, (LONG
)a
->bounds
.MinY
, (LONG
)a
->bounds
.MaxX
, (LONG
)a
->bounds
.MaxY
,
260 (LONG
)b
->MinX
, (LONG
)b
->MinY
, (LONG
)b
->MaxX
, (LONG
)b
->MaxY
));
262 /* First check with region bounds */
263 if (RectAndRect(&a
->bounds
, b
) == 0)
266 if (a
->RegionRectangle
)
268 struct RegionRectangle
* c
= a
->RegionRectangle
;
271 struct Rectangle d
= {
272 a
->bounds
.MinX
+ c
->bounds
.MinX
,
273 a
->bounds
.MinY
+ c
->bounds
.MinY
,
274 a
->bounds
.MinX
+ c
->bounds
.MaxX
,
275 a
->bounds
.MinY
+ c
->bounds
.MaxY
276 }; /* We need absolute coordinates */
278 if (RectAndRect(&d
, b
))
287 ///Node_NextVisible()
288 // IconEntry List navigation functions ..
289 static struct IconEntry
*Node_NextVisible(struct IconEntry
*current_Node
)
291 current_Node
= (struct IconEntry
*)GetSucc(¤t_Node
->ie_IconNode
);
292 while ((current_Node
!= NULL
) && (!(current_Node
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)))
294 current_Node
= (struct IconEntry
*)GetSucc(¤t_Node
->ie_IconNode
);
300 ///Node_FirstVisible()
301 static struct IconEntry
*Node_FirstVisible(struct List
*icon_list
)
303 struct IconEntry
*current_Node
= (struct IconEntry
*)GetHead(icon_list
);
305 if ((current_Node
!= NULL
) && !(current_Node
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
))
306 current_Node
= Node_NextVisible(current_Node
);
312 ///Node_PreviousVisible()
313 static struct IconEntry
*Node_PreviousVisible(struct IconEntry
*current_Node
)
315 current_Node
= (struct IconEntry
*)GetPred(¤t_Node
->ie_IconNode
);
316 while ((current_Node
!= NULL
) && (!(current_Node
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)))
318 current_Node
= (struct IconEntry
*)GetPred(¤t_Node
->ie_IconNode
);
324 ///Node_LastVisible()
325 static struct IconEntry
*Node_LastVisible(struct List
*icon_list
)
327 struct IconEntry
*current_Node
= (struct IconEntry
*)GetTail(icon_list
);
329 if ((current_Node
!= NULL
) && !(current_Node
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
))
330 current_Node
= Node_PreviousVisible(current_Node
);
336 const UBYTE MSG_MEM_G
[] = "GB";
337 const UBYTE MSG_MEM_M
[] = "MB";
338 const UBYTE MSG_MEM_K
[] = "KB";
339 const UBYTE MSG_MEM_B
[] = "Bytes";
342 static void FmtSizeToString(UBYTE
*buf
, ULONG num
)
356 if (num
>= 1073741824)
359 array
.val
= num
>> 30;
360 d
= ((UQUAD
)num
* 10 + 536870912) / 1073741824;
364 else if (num
>= 1048576)
367 array
.val
= num
>> 20;
368 d
= ((UQUAD
)num
* 10 + 524288) / 1048576;
372 else if (num
>= 1024)
375 array
.val
= num
>> 10;
376 d
= (num
* 10 + 512) / 1024;
389 if (!array
.dec
&& (d
> array
.val
* 10))
394 RawDoFmt(array
.dec
? "%lu.%lu" : "%lu", &array
, NULL
, buf
);
401 sprintf(buf
, " %s", ch
);
405 ///GetAbsoluteLassoRect()
406 // get positive lasso coords
407 static void GetAbsoluteLassoRect(struct IconList_DATA
*data
, struct Rectangle
*LassoRectangle
)
409 WORD minx
= data
->icld_LassoRectangle
.MinX
;
410 WORD miny
= data
->icld_LassoRectangle
.MinY
;
411 WORD maxx
= data
->icld_LassoRectangle
.MaxX
;
412 WORD maxy
= data
->icld_LassoRectangle
.MaxY
;
414 #if defined(DEBUG_ILC_LASSO) || defined(DEBUG_ILC_FUNCS)
415 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
420 /* Swap minx, maxx */
428 /* Swap miny, maxy */
434 LassoRectangle
->MinX
= data
->view_rect
.MinX
- data
->icld_ViewX
+ minx
;
435 LassoRectangle
->MinY
= data
->view_rect
.MinY
- data
->icld_ViewY
+ miny
;
436 LassoRectangle
->MaxX
= data
->view_rect
.MinX
- data
->icld_ViewX
+ maxx
;
437 LassoRectangle
->MaxY
= data
->view_rect
.MinY
- data
->icld_ViewY
+ maxy
;
441 ///IconList_InvertPixelRect()
442 static void IconList_InvertPixelRect(struct RastPort
*rp
, WORD minx
, WORD miny
, WORD maxx
, WORD maxy
, struct Rectangle
*clip
)
444 struct Rectangle r
, clipped_r
;
446 #if defined(DEBUG_ILC_RENDERING) || defined(DEBUG_ILC_FUNCS)
447 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
452 /* Swap minx, maxx */
460 /* Swap miny, maxy */
471 if (AndRectRect(&r
, clip
, &clipped_r
))
473 InvertPixelArray(rp
, clipped_r
.MinX
, clipped_r
.MinY
,
474 clipped_r
.MaxX
- clipped_r
.MinX
+ 1, clipped_r
.MaxY
- clipped_r
.MinY
+ 1);
479 ///IconList_InvertLassoOutlines()
480 // Simple lasso drawing by inverting area outlines
481 static void IconList_InvertLassoOutlines(Object
*obj
, struct IconList_DATA
*data
, struct Rectangle
*rect
)
483 struct Rectangle lasso
;
484 struct Rectangle clip
;
486 #if defined(DEBUG_ILC_LASSO) || defined(DEBUG_ILC_FUNCS)
487 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
490 /* get abolute iconlist coords */
491 lasso
.MinX
= rect
->MinX
+ _mleft(obj
);
492 lasso
.MaxX
= rect
->MaxX
+ _mleft(obj
);
493 lasso
.MinY
= rect
->MinY
+ _mtop(obj
);
494 lasso
.MaxY
= rect
->MaxY
+ _mtop(obj
);
496 clip
.MinX
= _mleft(obj
);
497 clip
.MinY
= _mtop(obj
);
498 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
500 clip
.MinY
+= data
->icld_LVMAttribs
->lmva_HeaderHeight
;
502 clip
.MaxX
= _mright(obj
);
503 clip
.MaxY
= _mbottom(obj
);
505 /* horizontal lasso lines */
506 IconList_InvertPixelRect(_rp(obj
), lasso
.MinX
, lasso
.MinY
, lasso
.MaxX
-1, lasso
.MinY
+ 1, &clip
);
507 IconList_InvertPixelRect(_rp(obj
), lasso
.MinX
, lasso
.MaxY
, lasso
.MaxX
-1, lasso
.MaxY
+ 1, &clip
);
509 /* vertical lasso lines */
510 IconList_InvertPixelRect(_rp(obj
), lasso
.MinX
, lasso
.MinY
, lasso
.MinX
+ 1, lasso
.MaxY
- 1, &clip
);
511 IconList_InvertPixelRect(_rp(obj
), lasso
.MaxX
, lasso
.MinY
, lasso
.MaxX
+ 1, lasso
.MaxY
- 1, &clip
);
515 ///IconList_GetIconImageRectangle()
516 //We don't use icon.library's label drawing so we do this by hand
517 static void IconList_GetIconImageRectangle(Object
*obj
, struct IconList_DATA
*data
, struct IconEntry
*entry
, struct Rectangle
*rect
)
519 #if defined(DEBUG_ILC_ICONPOSITIONING) || defined(DEBUG_ILC_FUNCS)
520 D(bug("[IconList]: %s(entry @ %p)\n", __PRETTY_FUNCTION__
, entry
));
523 /* Get basic width/height */
524 GetIconRectangleA(NULL
, entry
->ie_DiskObj
, NULL
, rect
, __iconList_DrawIconStateTags
);
525 #if defined(DEBUG_ILC_ICONPOSITIONING)
526 D(bug("[IconList] %s: MinX %d, MinY %d MaxX %d, MaxY %d\n", __PRETTY_FUNCTION__
, rect
->MinX
, rect
->MinY
, rect
->MaxX
, rect
->MaxY
));
528 entry
->ie_IconWidth
= (rect
->MaxX
- rect
->MinX
) + 1;
529 entry
->ie_IconHeight
= (rect
->MaxY
- rect
->MinY
) + 1;
531 if (entry
->ie_IconHeight
> data
->icld_IconLargestHeight
)
532 data
->icld_IconLargestHeight
= entry
->ie_IconHeight
;
536 ///IconList_GetIconImageOffsets()
537 static void IconList_GetIconImageOffsets(struct IconList_DATA
*data
, struct IconEntry
*entry
, LONG
*offsetx
, LONG
*offsety
)
539 *offsetx
= *offsety
= 0;
540 if (entry
->ie_IconWidth
< entry
->ie_AreaWidth
)
541 *offsetx
+= (entry
->ie_AreaWidth
- entry
->ie_IconWidth
)/2;
543 if ((data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
) &&
544 (entry
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
))
545 *offsetx
+= ((data
->icld_IconAreaLargestWidth
- entry
->ie_AreaWidth
)/2);
547 if ((data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
) &&
548 (entry
->ie_AreaHeight
< data
->icld_IconAreaLargestHeight
))
549 *offsety
+= ((data
->icld_IconAreaLargestHeight
- entry
->ie_AreaHeight
)/2);
552 ///IconList_GetIconLabelRectangle()
553 static void IconList_GetIconLabelRectangle(Object
*obj
, struct IconList_DATA
*data
, struct IconEntry
*entry
, struct Rectangle
*rect
)
555 ULONG outline_offset
= 0;
558 #if defined(DEBUG_ILC_ICONPOSITIONING) || defined(DEBUG_ILC_FUNCS)
559 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
562 switch ( data
->icld__Option_LabelTextMode
)
564 case ICON_TEXTMODE_DROPSHADOW
:
568 case ICON_TEXTMODE_PLAIN
:
576 /* Get entry box width including text width */
577 if ((entry
->ie_IconListEntry
.label
!= NULL
) && (entry
->ie_TxtBuf_DisplayedLabel
!= NULL
))
579 ULONG curlabel_TotalLines
;
580 SetFont(data
->icld_BufferRastPort
, data
->icld_IconLabelFont
);
583 rect
->MaxX
= (((data
->icld__Option_LabelTextHorizontalPadding
+ data
->icld__Option_LabelTextBorderWidth
) * 2) + entry
->ie_TxtBuf_DisplayedLabelWidth
+ outline_offset
) - 1;
587 curlabel_TotalLines
= entry
->ie_SplitParts
;
588 if (curlabel_TotalLines
== 0)
589 curlabel_TotalLines
= 1;
590 if (curlabel_TotalLines
> data
->icld__Option_LabelTextMultiLine
)
591 curlabel_TotalLines
= data
->icld__Option_LabelTextMultiLine
;
593 rect
->MaxY
= (((data
->icld__Option_LabelTextBorderHeight
+ data
->icld__Option_LabelTextVerticalPadding
) * 2) +
594 ((data
->icld_IconLabelFont
->tf_YSize
+ outline_offset
) * curlabel_TotalLines
)) - 1;
596 /* Date/size sorting has the date/size appended under the entry label
597 only list regular files like this (drawers have no size/date output) */
599 entry
->ie_IconListEntry
.type
!= ST_USERDIR
&&
600 ((data
->icld_SortFlags
& MUIV_IconList_Sort_BySize
) || (data
->icld_SortFlags
& MUIV_IconList_Sort_ByDate
))
603 SetFont(data
->icld_BufferRastPort
, data
->icld_IconInfoFont
);
605 if( (data
->icld_SortFlags
& MUIV_IconList_Sort_BySize
) && !(data
->icld_SortFlags
& MUIV_IconList_Sort_ByDate
) )
607 entry
->ie_TxtBuf_SIZEWidth
= TextLength(data
->icld_BufferRastPort
, entry
->ie_TxtBuf_SIZE
, strlen(entry
->ie_TxtBuf_SIZE
));
608 textwidth
= entry
->ie_TxtBuf_SIZEWidth
;
612 if( !(data
->icld_SortFlags
& MUIV_IconList_Sort_BySize
) && (data
->icld_SortFlags
& MUIV_IconList_Sort_ByDate
) )
614 if( entry
->ie_Flags
& ICONENTRY_FLAG_TODAY
)
616 entry
->ie_TxtBuf_TIMEWidth
= TextLength(data
->icld_BufferRastPort
, entry
->ie_TxtBuf_TIME
, strlen(entry
->ie_TxtBuf_TIME
));
617 textwidth
= entry
->ie_TxtBuf_TIMEWidth
;
621 entry
->ie_TxtBuf_DATEWidth
= TextLength(data
->icld_BufferRastPort
, entry
->ie_TxtBuf_DATE
, strlen(entry
->ie_TxtBuf_DATE
));
622 textwidth
= entry
->ie_TxtBuf_DATEWidth
;
629 rect
->MaxY
= rect
->MaxY
+ data
->icld_IconInfoFont
->tf_YSize
+ outline_offset
;
630 if ((textwidth
+ outline_offset
+ ((data
->icld__Option_LabelTextHorizontalPadding
+ data
->icld__Option_LabelTextBorderWidth
) * 2)) > ((rect
->MaxX
- rect
->MinX
) + 1))
631 rect
->MaxX
= (textwidth
+ outline_offset
+ ((data
->icld__Option_LabelTextVerticalPadding
+ data
->icld__Option_LabelTextBorderWidth
) * 2)) - 1;
635 if (((rect
->MaxY
- rect
->MinY
) + 1) > data
->icld_LabelLargestHeight
) data
->icld_LabelLargestHeight
= ((rect
->MaxY
- rect
->MinY
) + 1);
639 ///IconList_GetIconAreaRectangle()
640 static void IconList_GetIconAreaRectangle(Object
*obj
, struct IconList_DATA
*data
, struct IconEntry
*entry
, struct Rectangle
*rect
)
642 struct Rectangle labelrect
;
643 ULONG iconlabel_Width
;
644 ULONG iconlabel_Height
;
646 #if defined(DEBUG_ILC_ICONPOSITIONING) || defined(DEBUG_ILC_FUNCS)
647 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
650 /* Get entry box width including text width */
651 memset(rect
, 0, sizeof(struct Rectangle
));
653 IconList_GetIconImageRectangle(obj
, data
, entry
, rect
);
655 entry
->ie_AreaWidth
= entry
->ie_IconWidth
;
656 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
658 entry
->ie_AreaHeight
= data
->icld_IconLargestHeight
;
662 entry
->ie_AreaHeight
= entry
->ie_IconHeight
;
665 IconList_GetIconLabelRectangle(obj
, data
, entry
, &labelrect
);
667 iconlabel_Width
= ((labelrect
.MaxX
- labelrect
.MinX
) + 1);
668 iconlabel_Height
= ((labelrect
.MaxY
- labelrect
.MinY
) + 1);
670 if (iconlabel_Width
> entry
->ie_AreaWidth
)
671 entry
->ie_AreaWidth
= iconlabel_Width
;
673 entry
->ie_AreaHeight
= entry
->ie_AreaHeight
+ data
->icld__Option_IconImageSpacing
+ iconlabel_Height
;
676 rect
->MaxX
= (rect
->MinX
+ entry
->ie_AreaWidth
) - 1;
677 rect
->MaxY
= (rect
->MinY
+ entry
->ie_AreaHeight
) - 1;
679 if (entry
->ie_AreaWidth
> data
->icld_IconAreaLargestWidth
) data
->icld_IconAreaLargestWidth
= entry
->ie_AreaWidth
;
680 if (entry
->ie_AreaHeight
> data
->icld_IconAreaLargestHeight
) data
->icld_IconAreaLargestHeight
= entry
->ie_AreaHeight
;
684 static LONG
FirstVisibleColumnNumber(struct IconList_DATA
*data
)
689 if (data
->icld_LVMAttribs
!= NULL
)
691 for(i
= 0; i
< NUM_COLUMNS
; i
++)
693 LONG index
= data
->icld_LVMAttribs
->lmva_ColumnPos
[i
];
695 if (data
->icld_LVMAttribs
->lmva_ColumnFlags
[index
] & LVMCF_COLVISIBLE
)
706 static LONG
LastVisibleColumnNumber(struct IconList_DATA
*data
)
711 if (data
->icld_LVMAttribs
!= NULL
)
713 for(i
= 0; i
< NUM_COLUMNS
; i
++)
715 LONG index
= data
->icld_LVMAttribs
->lmva_ColumnPos
[i
];
717 if (data
->icld_LVMAttribs
->lmva_ColumnFlags
[index
] & LVMCF_COLVISIBLE
)
728 static void RenderEntryField(Object
*obj
, struct IconList_DATA
*data
,
729 struct IconEntry
*entry
, struct Rectangle
*rect
, LONG index
, BOOL firstvis
,
730 BOOL lastvis
, struct RastPort
* rp
)
732 STRPTR text
= NULL
, renderflag
= "<UHOH>";
733 struct TextExtent te
;
736 if (entry
->ie_Flags
& ICONENTRY_FLAG_SELECTED
)
739 rect
->MinX
, rect
->MinY
,
740 rect
->MaxX
- rect
->MinX
+ 1, rect
->MaxY
- rect
->MinY
,
744 rect
->MinX
+= ENTRY_SPACING_LEFT
;
745 rect
->MaxX
-= ENTRY_SPACING_RIGHT
;
746 rect
->MinY
+= LINE_SPACING_TOP
;
747 rect
->MaxY
-= LINE_SPACING_BOTTOM
;
749 if (firstvis
) rect
->MinX
+= LINE_SPACING_LEFT
;
750 if (lastvis
) rect
->MaxX
-= LINE_SPACING_RIGHT
;
757 /* Special case !! we draw an image instead .. */
762 text
= entry
->ie_IconListEntry
.label
;
766 text
= entry
->ie_TxtBuf_SIZE
;
769 case INDEX_LASTACCESS
:
770 text
= AllocVec(strlen(entry
->ie_TxtBuf_DATE
) + strlen(entry
->ie_TxtBuf_TIME
) + 5, MEMF_CLEAR
);
771 sprintf(text
, "%s at %s", entry
->ie_TxtBuf_DATE
, entry
->ie_TxtBuf_TIME
);
775 text
= entry
->ie_FileInfoBlock
->fib_Comment
;
778 case INDEX_PROTECTION
:
779 text
= entry
->ie_TxtBuf_PROT
;
784 if (!text
[0]) return;
786 if (text
== renderflag
)
788 if (entry
->ie_IconListEntry
.type
== ST_USERDIR
)
790 if (data
->icld_LVMAttribs
->lvma_IconDrawer
)
794 rp
, data
->icld_LVMAttribs
->lvma_IconDrawer
, NULL
,
795 rect
->MinX
+ 1, rect
->MinY
+ 1,
796 (entry
->ie_Flags
& ICONENTRY_FLAG_SELECTED
) ? IDS_SELECTED
: IDS_NORMAL
,
797 __iconList_DrawIconStateTags
803 rect
->MinX
+ 1, rect
->MinY
+ 1,
804 rect
->MaxX
- rect
->MinX
- 1, rect
->MaxY
- rect
->MinY
- 1,
810 if (data
->icld_LVMAttribs
->lvma_IconFile
)
814 rp
, data
->icld_LVMAttribs
->lvma_IconFile
, NULL
,
815 rect
->MinX
+ 1, rect
->MinY
+ 1,
816 (entry
->ie_Flags
& ICONENTRY_FLAG_SELECTED
) ? IDS_SELECTED
: IDS_NORMAL
,
817 __iconList_DrawIconStateTags
823 rect
->MinX
+ 1, rect
->MinY
+ 1,
824 rect
->MaxX
- rect
->MinX
- 1, rect
->MaxY
- rect
->MinY
- 1,
831 fit
= TextFit(rp
, text
, strlen(text
), &te
, NULL
, 1,
832 rect
->MaxX
- rect
->MinX
+ 1,
833 rect
->MaxY
- rect
->MinY
+ 1);
837 SetABPenDrMd(rp
, _pens(obj
)[(entry
->ie_Flags
& ICONENTRY_FLAG_SELECTED
) ? MPEN_SHINE
: MPEN_TEXT
], 0, JAM1
);
839 if (((rect
->MaxY
- rect
->MinY
+ 1) - data
->icld_IconLabelFont
->tf_YSize
) > 0)
841 rect
->MinY
+= ((rect
->MaxY
- rect
->MinY
+ 1) - data
->icld_IconLabelFont
->tf_YSize
)/2;
844 switch(data
->icld_LVMAttribs
->lmva_ColumnHAlign
[index
])
846 case COLUMN_ALIGN_LEFT
:
847 Move(rp
, rect
->MinX
, rect
->MinY
+ rp
->TxBaseline
);
850 case COLUMN_ALIGN_RIGHT
:
851 Move(rp
, rect
->MaxX
- te
.te_Width
, rect
->MinY
+ rp
->TxBaseline
);
854 case COLUMN_ALIGN_CENTER
:
855 Move(rp
, rect
->MinX
+ (rect
->MaxX
- rect
->MinX
+ 1 + 1 - te
.te_Width
) / 2,
856 rect
->MinY
+ rp
->TxBaseline
);
862 if ((index
== INDEX_LASTACCESS
) && text
)
867 /**************************************************************************
868 Draw the entry at its position
869 **************************************************************************/
870 ///IconList__MUIM_IconList_DrawEntry()
871 IPTR
IconList__MUIM_IconList_DrawEntry(struct IClass
*CLASS
, Object
*obj
, struct MUIP_IconList_DrawEntry
*message
)
873 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
875 BOOL outside
= FALSE
;
877 struct Rectangle iconrect
;
878 struct Rectangle objrect
;
880 ULONG objX
, objY
, objW
, objH
;
883 if (data
->icld_BufferRastPort
== data
->icld_DisplayRastPort
)
892 objW
= _mright(obj
) - _mleft(obj
) + 1;
893 objH
= _mbottom(obj
) - _mtop(obj
) + 1;
895 #if defined(DEBUG_ILC_ICONRENDERING)
896 D(bug("[IconList]: %s(message->entry = 0x%p)\n", __PRETTY_FUNCTION__
, message
->entry
));
899 if ((!(message
->entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)) ||
900 (data
->icld_BufferRastPort
== NULL
) ||
901 (!(message
->entry
->ie_DiskObj
)))
903 #if defined(DEBUG_ILC_ICONRENDERING)
904 D(bug("[IconList] %s: Not visible or missing DOB\n", __PRETTY_FUNCTION__
));
909 /* Set the dimensions of our "view" */
912 objrect
.MaxX
= objX
+ objW
- 1;
913 objrect
.MaxY
= objY
+ objH
- 1;
915 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
917 struct Rectangle linerect
;
919 LONG firstvis
, lastvis
;
921 linerect
.MinX
= objX
- data
->icld_ViewX
;
922 linerect
.MaxX
= objX
+ objW
- 1; //linerect.MinX + data->width - 1;
923 linerect
.MinY
= (objY
- data
->icld_ViewY
) + data
->icld_LVMAttribs
->lmva_HeaderHeight
+ (message
->drawmode
* data
->icld_LVMAttribs
->lmva_RowHeight
);
924 linerect
.MaxY
= linerect
.MinY
+ data
->icld_LVMAttribs
->lmva_RowHeight
- 1;
926 if (!AndRectRect(&linerect
, &objrect
, NULL
)) return FALSE
;
927 // if (!MustRenderRect(data, &linerect)) return;
929 SetFont(data
->icld_BufferRastPort
, data
->icld_IconLabelFont
);
931 x
= linerect
.MinX
+ LINE_SPACING_LEFT
;
933 firstvis
= FirstVisibleColumnNumber(data
);
934 lastvis
= LastVisibleColumnNumber(data
);
936 for(i
= 0; i
< NUM_COLUMNS
; i
++)
938 struct Rectangle field_rect
;
939 LONG index
= data
->icld_LVMAttribs
->lmva_ColumnPos
[i
];
941 if (!(data
->icld_LVMAttribs
->lmva_ColumnFlags
[i
] & LVMCF_COLVISIBLE
)) continue;
943 field_rect
.MinX
= (i
== firstvis
) ? linerect
.MinX
: x
;
944 field_rect
.MinY
= linerect
.MinY
;
945 field_rect
.MaxX
= x
+ data
->icld_LVMAttribs
->lmva_ColumnWidth
[index
] - 1 + ((i
== lastvis
) ? LINE_SPACING_RIGHT
: 0);
946 field_rect
.MaxY
= linerect
.MaxY
;
948 /* if (MustRenderRect(data, &field_rect))
950 if (AndRectRect(&field_rect
, &objrect
, NULL
))
952 RenderEntryField(obj
, data
, message
->entry
, &field_rect
, index
,
953 (i
== firstvis
), (i
== lastvis
), data
->icld_BufferRastPort
);
956 x
+= data
->icld_LVMAttribs
->lmva_ColumnWidth
[index
];
959 if ((data
->icld_LVMAttribs
->lvma_Flags
& LVMAF_ROWDRAWTOEND
) == LVMAF_ROWDRAWTOEND
)
961 x
+= LINE_SPACING_RIGHT
;
963 if (x
< linerect
.MaxX
)
967 SetABPenDrMd(data
->icld_BufferRastPort
, _pens(obj
)[MPEN_SHINE
], 0, JAM1
);
968 RectFill(data
->icld_BufferRastPort
, linerect
.MinX
, linerect
.MinY
, linerect
.MaxX
, linerect
.MaxY
);
974 LONG offsetx
,offsety
;
976 /* Get the dimensions and affected area of message->entry */
977 IconList_GetIconImageRectangle(obj
, data
, message
->entry
, &iconrect
);
979 /* Get offset corrections */
980 IconList_GetIconImageOffsets(data
, message
->entry
, &offsetx
, &offsety
);
982 /* Add the relative position offset of the message->entry */
983 iconrect
.MinX
+= objX
- data
->icld_ViewX
+ message
->entry
->ie_IconX
+ offsetx
;
984 iconrect
.MaxX
+= objX
- data
->icld_ViewX
+ message
->entry
->ie_IconX
+ offsetx
;
985 iconrect
.MinY
+= objY
- data
->icld_ViewY
+ message
->entry
->ie_IconY
+ offsety
;
986 iconrect
.MaxY
+= objY
- data
->icld_ViewY
+ message
->entry
->ie_IconY
+ offsety
;
988 if (!RectAndRect(&iconrect
, &objrect
))
990 #if defined(DEBUG_ILC_ICONRENDERING)
991 D(bug("[IconList] %s: Entry '%s' image outside of visible area .. skipping\n", __PRETTY_FUNCTION__
, message
->entry
->ie_IconListEntry
.label
));
996 /* data->update_rect1 and data->update_rect2 may
997 point to rectangles to indicate that only icons
998 in any of this rectangles need to be drawn */
999 if (data
->update_rect1
)
1001 if (!RectAndRect(&iconrect
, data
->update_rect1
)) outside
= TRUE
;
1004 if (data
->update_rect2
)
1006 if (data
->update_rect1
)
1008 if ((outside
== TRUE
) && RectAndRect(&iconrect
, data
->update_rect2
))
1013 if (!RectAndRect(&iconrect
, data
->update_rect2
))
1018 if (outside
== TRUE
)
1020 #if defined(DEBUG_ILC_ICONRENDERING)
1021 D(bug("[IconList] %s: Entry '%s' image outside of update area .. skipping\n", __PRETTY_FUNCTION__
, message
->entry
->ie_IconListEntry
.label
));
1026 if (message
->drawmode
== ICONENTRY_DRAWMODE_NONE
) return TRUE
;
1028 // Center entry image
1029 iconX
= iconrect
.MinX
- objX
+ data
->icld_DrawOffsetX
;
1030 iconY
= iconrect
.MinY
- objY
+ data
->icld_DrawOffsetY
;
1032 #if defined(DEBUG_ILC_ICONRENDERING)
1033 D(bug("[IconList] %s: DrawIconState('%s') .. %d, %d\n", __PRETTY_FUNCTION__
, message
->entry
->ie_IconListEntry
.label
, iconX
, iconY
));
1037 data
->icld_BufferRastPort
, message
->entry
->ie_DiskObj
, NULL
,
1040 (message
->entry
->ie_Flags
& ICONENTRY_FLAG_SELECTED
) ? IDS_SELECTED
: IDS_NORMAL
,
1041 __iconList_DrawIconStateTags
1043 #if defined(DEBUG_ILC_ICONRENDERING)
1044 D(bug("[IconList] %s: DrawIconState Done\n", __PRETTY_FUNCTION__
));
1052 ///IconList__LabelFunc_SplitLabel()
1053 static void IconList__LabelFunc_SplitLabel(Object
*obj
, struct IconList_DATA
*data
, struct IconEntry
*entry
)
1055 ULONG labelSplit_MaxLabelLineLength
= data
->icld__Option_LabelTextMaxLen
;
1056 ULONG labelSplit_LabelLength
= strlen(entry
->ie_IconListEntry
.label
);
1058 // ULONG labelSplit_FontY = data->icld_IconLabelFont->tf_YSize;
1059 int labelSplit_CharsDone
, labelSplit_CharsSplit
;
1060 ULONG labelSplit_CurSplitWidth
;
1062 if ((data
->icld__Option_TrimVolumeNames
) &&
1063 ((entry
->ie_IconListEntry
.type
== ST_ROOT
) && (entry
->ie_IconListEntry
.label
[labelSplit_LabelLength
- 1] == ':')))
1064 labelSplit_LabelLength
--;
1066 if (labelSplit_MaxLabelLineLength
>= labelSplit_LabelLength
)
1068 #if defined(DEBUG_ILC_ICONRENDERING)
1069 D(bug("[IconList]: %s: Label'%s' doesnt need split (onyl %d chars)\n", __PRETTY_FUNCTION__
, entry
->ie_IconListEntry
.label
, labelSplit_LabelLength
));
1074 SetFont(data
->icld_BufferRastPort
, data
->icld_IconLabelFont
);
1075 txwidth
= TextLength(data
->icld_BufferRastPort
, entry
->ie_IconListEntry
.label
, labelSplit_MaxLabelLineLength
);
1076 #if defined(DEBUG_ILC_ICONRENDERING)
1077 D(bug("[IconList]: %s: txwidth = %d\n", __PRETTY_FUNCTION__
, txwidth
));
1079 entry
->ie_TxtBuf_DisplayedLabel
= AllocVecPooled(data
->icld_Pool
, 256);
1080 memset(entry
->ie_TxtBuf_DisplayedLabel
, 0, 256);
1081 entry
->ie_SplitParts
= 0;
1083 labelSplit_CharsDone
= 0;
1084 labelSplit_CharsSplit
= 0;
1086 while (labelSplit_CharsDone
< labelSplit_LabelLength
)
1088 ULONG labelSplit_CurSplitLength
= labelSplit_LabelLength
- labelSplit_CharsDone
;
1089 IPTR labelSplit_SplitStart
= (IPTR
)(entry
->ie_IconListEntry
.label
+ labelSplit_CharsDone
);
1090 int tmp_checkoffs
= 0;
1091 IPTR labelSplit_RemainingCharsAfterSplit
;
1092 IPTR labelSplit_CurSplitDest
;
1094 while (*(char *)(labelSplit_SplitStart
) == ' ')
1096 //Skip preceding spaces..
1097 labelSplit_SplitStart
= labelSplit_SplitStart
+ 1;
1098 labelSplit_CurSplitLength
= labelSplit_CurSplitLength
- 1;
1099 labelSplit_CharsDone
= labelSplit_CharsDone
+ 1;
1102 while(TextLength(data
->icld_BufferRastPort
, (char *)labelSplit_SplitStart
, labelSplit_CurSplitLength
) < txwidth
) labelSplit_CurSplitLength
++;
1103 while(TextLength(data
->icld_BufferRastPort
, (char *)labelSplit_SplitStart
, labelSplit_CurSplitLength
) > txwidth
) labelSplit_CurSplitLength
--;
1104 #if defined(DEBUG_ILC_ICONRENDERING)
1105 D(bug("[IconList]: %s: labelSplit_CurSplitLength = %d\n", __PRETTY_FUNCTION__
, labelSplit_CurSplitLength
));
1108 #if defined(DEBUG_ILC_ICONRENDERING)
1109 D(bug("[IconList]: %s: Attempting to find neat split ", __PRETTY_FUNCTION__
));
1111 while(tmp_checkoffs
< (labelSplit_CurSplitLength
- ILC_ICONLABEL_SHORTEST
))
1113 #if defined(DEBUG_ILC_ICONRENDERING)
1114 D(bug("%d", tmp_checkoffs
));
1116 labelSplit_RemainingCharsAfterSplit
= labelSplit_LabelLength
- (labelSplit_CharsDone
+ labelSplit_CurSplitLength
);
1118 if ((labelSplit_CurSplitLength
- tmp_checkoffs
) > ILC_ICONLABEL_SHORTEST
)
1120 #if defined(DEBUG_ILC_ICONRENDERING)
1123 if ((*(char *)(labelSplit_SplitStart
+ labelSplit_CurSplitLength
- tmp_checkoffs
) == ' ') ||
1124 (*(char *)(labelSplit_SplitStart
+ labelSplit_CurSplitLength
- tmp_checkoffs
) == '.') ||
1125 (*(char *)(labelSplit_SplitStart
+ labelSplit_CurSplitLength
- tmp_checkoffs
) == '-'))
1127 #if defined(DEBUG_ILC_ICONRENDERING)
1130 labelSplit_CurSplitLength
= labelSplit_CurSplitLength
- tmp_checkoffs
;
1131 labelSplit_RemainingCharsAfterSplit
= labelSplit_RemainingCharsAfterSplit
- tmp_checkoffs
;
1137 if ((labelSplit_RemainingCharsAfterSplit
- tmp_checkoffs
) < 0)
1139 #if defined(DEBUG_ILC_ICONRENDERING)
1142 labelSplit_CurSplitLength
= labelSplit_CurSplitLength
+ tmp_checkoffs
;
1143 labelSplit_RemainingCharsAfterSplit
= labelSplit_RemainingCharsAfterSplit
+ tmp_checkoffs
;
1148 if ((labelSplit_RemainingCharsAfterSplit
- tmp_checkoffs
) >= ILC_ICONLABEL_SHORTEST
)
1150 #if defined(DEBUG_ILC_ICONRENDERING)
1153 if ((*(char *)(labelSplit_SplitStart
+ labelSplit_CurSplitLength
+ tmp_checkoffs
) == ' ') ||
1154 (*(char *)(labelSplit_SplitStart
+ labelSplit_CurSplitLength
+ tmp_checkoffs
) == '.') ||
1155 (*(char *)(labelSplit_SplitStart
+ labelSplit_CurSplitLength
+ tmp_checkoffs
) == '-'))
1157 #if defined(DEBUG_ILC_ICONRENDERING)
1160 labelSplit_CurSplitLength
= labelSplit_CurSplitLength
+ tmp_checkoffs
;
1161 labelSplit_RemainingCharsAfterSplit
= labelSplit_RemainingCharsAfterSplit
+ tmp_checkoffs
;
1167 tmp_checkoffs
= tmp_checkoffs
+ 1;
1169 #if defined(DEBUG_ILC_ICONRENDERING)
1172 if (tmp_checkoffs
!= 0)
1174 #if defined(DEBUG_ILC_ICONRENDERING)
1175 D(bug("[IconList]: %s: Couldnt find neat split : Still %d chars\n", __PRETTY_FUNCTION__
, labelSplit_RemainingCharsAfterSplit
));
1177 if (labelSplit_RemainingCharsAfterSplit
<= ILC_ICONLABEL_SHORTEST
)
1179 labelSplit_CurSplitLength
= labelSplit_CurSplitLength
+ (labelSplit_RemainingCharsAfterSplit
- ILC_ICONLABEL_SHORTEST
);
1182 if ((labelSplit_CharsDone
+ labelSplit_CurSplitLength
) > labelSplit_LabelLength
) labelSplit_CurSplitLength
= labelSplit_LabelLength
- labelSplit_CharsDone
;
1184 labelSplit_CurSplitDest
= (IPTR
)(entry
->ie_TxtBuf_DisplayedLabel
+ labelSplit_CharsSplit
+ entry
->ie_SplitParts
);
1186 strncpy((char *)labelSplit_CurSplitDest
, (char *)labelSplit_SplitStart
, labelSplit_CurSplitLength
);
1188 labelSplit_CurSplitWidth
= TextLength(data
->icld_BufferRastPort
, (char *)labelSplit_CurSplitDest
, labelSplit_CurSplitLength
);
1190 entry
->ie_SplitParts
= entry
->ie_SplitParts
+ 1;
1192 labelSplit_CharsDone
= labelSplit_CharsDone
+ labelSplit_CurSplitLength
;
1193 labelSplit_CharsSplit
= labelSplit_CharsSplit
+ labelSplit_CurSplitLength
;
1195 if (labelSplit_CurSplitWidth
> entry
->ie_TxtBuf_DisplayedLabelWidth
) entry
->ie_TxtBuf_DisplayedLabelWidth
= labelSplit_CurSplitWidth
;
1197 if ((entry
->ie_SplitParts
<= 1) && entry
->ie_TxtBuf_DisplayedLabel
)
1199 FreeVecPooled(data
->icld_Pool
, entry
->ie_TxtBuf_DisplayedLabel
);
1200 entry
->ie_TxtBuf_DisplayedLabel
= NULL
;
1201 entry
->ie_SplitParts
= 0;
1203 // if ((labelSplit_FontY * entry->ie_SplitParts) > data->icld_LabelLargestHeight) data->icld_LabelLargestHeight = (labelSplit_FontY * entry->ie_SplitParts);
1207 ///IconList__LabelFunc_CreateLabel()
1208 static IPTR
IconList__LabelFunc_CreateLabel(Object
*obj
, struct IconList_DATA
*data
, struct IconEntry
*entry
)
1210 #if defined(DEBUG_ILC_ICONRENDERING) || defined(DEBUG_ILC_FUNCS)
1211 D(bug("[IconList]: %s('%s')\n", __PRETTY_FUNCTION__
, entry
->ie_IconListEntry
.label
));
1213 if (entry
->ie_TxtBuf_DisplayedLabel
)
1215 FreeVecPooled(data
->icld_Pool
, entry
->ie_TxtBuf_DisplayedLabel
);
1216 entry
->ie_TxtBuf_DisplayedLabel
= NULL
;
1217 entry
->ie_SplitParts
= 0;
1220 if (data
->icld__Option_LabelTextMultiLine
> 1)
1222 #if defined(DEBUG_ILC_ICONRENDERING)
1223 D(bug("[IconList]: %s: Attempting to split label ..\n", __PRETTY_FUNCTION__
));
1225 IconList__LabelFunc_SplitLabel(obj
, data
, entry
);
1228 if (entry
->ie_TxtBuf_DisplayedLabel
== NULL
)
1230 ULONG ie_LabelLength
= strlen(entry
->ie_IconListEntry
.label
);
1231 entry
->ie_SplitParts
= 1;
1233 #if defined(DEBUG_ILC_ICONRENDERING)
1234 D(bug("[IconList]: %s: Building unsplit label (len = %d) ..\n", __PRETTY_FUNCTION__
, ie_LabelLength
));
1237 if ((data
->icld__Option_TrimVolumeNames
) &&
1238 ((entry
->ie_IconListEntry
.type
== ST_ROOT
) && (entry
->ie_IconListEntry
.label
[ie_LabelLength
- 1] == ':')))
1241 if(ie_LabelLength
> data
->icld__Option_LabelTextMaxLen
)
1243 if (!(entry
->ie_TxtBuf_DisplayedLabel
= AllocVecPooled(data
->icld_Pool
, data
->icld__Option_LabelTextMaxLen
+ 1)))
1247 memset(entry
->ie_TxtBuf_DisplayedLabel
, 0, data
->icld__Option_LabelTextMaxLen
+ 1);
1248 strncpy(entry
->ie_TxtBuf_DisplayedLabel
, entry
->ie_IconListEntry
.label
, data
->icld__Option_LabelTextMaxLen
- 3);
1249 strcat(entry
->ie_TxtBuf_DisplayedLabel
, " ..");
1253 if (!(entry
->ie_TxtBuf_DisplayedLabel
= AllocVecPooled(data
->icld_Pool
, ie_LabelLength
+ 1)))
1257 memset(entry
->ie_TxtBuf_DisplayedLabel
, 0, ie_LabelLength
+ 1);
1258 strncpy(entry
->ie_TxtBuf_DisplayedLabel
, entry
->ie_IconListEntry
.label
, ie_LabelLength
);
1260 entry
->ie_TxtBuf_DisplayedLabelWidth
= TextLength(data
->icld_BufferRastPort
, entry
->ie_TxtBuf_DisplayedLabel
, strlen(entry
->ie_TxtBuf_DisplayedLabel
));
1261 // if ((data->icld_IconLabelFont->tf_YSize) > data->icld_LabelLargestHeight) data->icld_LabelLargestHeight = data->icld_IconLabelFont->tf_YSize;
1264 // if (entry->ie_TxtBuf_DisplayedLabelWidth > data->icld_LabelLargestWidth) data->icld_LabelLargestWidth = entry->ie_TxtBuf_DisplayedLabelWidth;
1266 return (IPTR
)entry
->ie_TxtBuf_DisplayedLabel
;
1270 ///IconList__HookFunc_UpdateLabelsFunc()
1272 void, IconList__HookFunc_UpdateLabelsFunc
,
1273 AROS_UFHA(struct Hook
*, hook
, A0
),
1274 AROS_UFHA(APTR
*, obj
, A2
),
1275 AROS_UFHA(APTR
, param
, A1
)
1280 /* Get our private data */
1281 Class
*CLASS
= *( Class
**)param
;
1282 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
1284 #if defined(DEBUG_ILC_LASSO) || defined(DEBUG_ILC_FUNCS)
1285 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
1288 if (((data
->icld__Option_LabelTextMaxLen
!= data
->icld__Option_LastLabelTextMaxLen
) &&
1289 (data
->icld__Option_LabelTextMultiLine
> 1)) ||
1290 (data
->icld__Option_LabelTextMultiLine
!= data
->icld__Option_LastLabelTextMultiLine
));
1292 struct IconEntry
*iconentry_Current
= NULL
;
1293 #if defined(__AROS__)
1294 ForeachNode(&data
->icld_IconList
, iconentry_Current
)
1296 Foreach_Node(&data
->icld_IconList
, iconentry_Current
);
1299 IconList__LabelFunc_CreateLabel((Object
*)obj
, data
, iconentry_Current
);
1303 data
->icld__Option_LastLabelTextMaxLen
= data
->icld__Option_LabelTextMaxLen
;
1304 data
->icld__Option_LastLabelTextMultiLine
= data
->icld__Option_LabelTextMultiLine
;
1310 ///IconList__MUIM_IconList_DrawEntryLabel()
1311 IPTR
IconList__MUIM_IconList_DrawEntryLabel(struct IClass
*CLASS
, Object
*obj
, struct MUIP_IconList_DrawEntry
*message
)
1313 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
1316 BOOL outside
= FALSE
;
1318 struct Rectangle iconlabelrect
;
1319 struct Rectangle objrect
;
1321 ULONG txtbox_width
= 0;
1322 LONG tx
,ty
,offsetx
,offsety
;
1323 LONG txwidth
; // txheight;
1325 ULONG objX
, objY
, objW
, objH
;
1326 LONG labelX
, labelY
;
1328 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
1331 if (data
->icld_BufferRastPort
== data
->icld_DisplayRastPort
)
1340 objW
= _mright(obj
) - _mleft(obj
) + 1;
1341 objH
= _mbottom(obj
) - _mtop(obj
) + 1;
1343 ULONG txtarea_width
;
1344 ULONG curlabel_TotalLines
, curlabel_CurrentLine
, offset_y
;
1346 #if defined(DEBUG_ILC_ICONRENDERING) || defined(DEBUG_ILC_FUNCS)
1347 D(bug("[IconList]: %s(message->entry = 0x%p), '%s'\n", __PRETTY_FUNCTION__
, message
->entry
, message
->entry
->ie_IconListEntry
.label
));
1350 if ((!(message
->entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)) ||
1351 (data
->icld_BufferRastPort
== NULL
) ||
1352 (!(message
->entry
->ie_DiskObj
)))
1354 #if defined(DEBUG_ILC_ICONRENDERING)
1355 D(bug("[IconList] %s: Not visible or missing DOB\n", __PRETTY_FUNCTION__
));
1360 /* Get the dimensions and affected area of message->entry's label */
1361 IconList_GetIconLabelRectangle(obj
, data
, message
->entry
, &iconlabelrect
);
1363 /* Add the relative position offset of the message->entry's label */
1364 offsetx
= (objX
- data
->icld_ViewX
) + message
->entry
->ie_IconX
;
1365 txtbox_width
= (iconlabelrect
.MaxX
- iconlabelrect
.MinX
) + 1;
1367 if (txtbox_width
< message
->entry
->ie_AreaWidth
)
1368 offsetx
+= ((message
->entry
->ie_AreaWidth
- txtbox_width
)/2);
1370 if ((data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
) &&
1371 (message
->entry
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
))
1372 offsetx
+= ((data
->icld_IconAreaLargestWidth
- message
->entry
->ie_AreaWidth
)/2);
1374 iconlabelrect
.MinX
+= offsetx
;
1375 iconlabelrect
.MaxX
+= offsetx
;
1377 offsety
= (objY
- data
->icld_ViewY
) + message
->entry
->ie_IconY
+ data
->icld__Option_IconImageSpacing
;
1378 if ((data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
) &&
1379 (message
->entry
->ie_AreaHeight
< data
->icld_IconAreaLargestHeight
))
1380 offsety
+= ((data
->icld_IconAreaLargestHeight
- message
->entry
->ie_AreaHeight
)/2);
1382 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
1384 offsety
= offsety
+ data
->icld_IconLargestHeight
;
1388 offsety
= offsety
+ message
->entry
->ie_IconHeight
;
1390 iconlabelrect
.MinY
+= offsety
;
1391 iconlabelrect
.MaxY
+= offsety
;
1393 /* Add the relative position of the window */
1394 objrect
.MinX
= objX
;
1395 objrect
.MinY
= objX
;
1396 objrect
.MaxX
= objX
+ objW
;
1397 objrect
.MaxY
= objY
+ objH
;
1399 if (!RectAndRect(&iconlabelrect
, &objrect
))
1401 #if defined(DEBUG_ILC_ICONRENDERING)
1402 (bug("[IconList] %s: Entry '%s' label outside of visible area .. skipping\n", __PRETTY_FUNCTION__
, message
->entry
->ie_IconListEntry
.label
));
1407 /* data->update_rect1 and data->update_rect2 may
1408 point to rectangles to indicate that only icons
1409 in any of this rectangles need to be drawn */
1410 if (data
->update_rect1
)
1412 if (!RectAndRect(&iconlabelrect
, data
->update_rect1
))
1416 if (data
->update_rect2
)
1418 if (data
->update_rect1
)
1420 if ((outside
== TRUE
) && RectAndRect(&iconlabelrect
, data
->update_rect2
))
1425 if (!RectAndRect(&iconlabelrect
, data
->update_rect2
))
1430 if (outside
== TRUE
)
1432 #if defined(DEBUG_ILC_ICONRENDERING)
1433 D(bug("[IconList] %s: Entry '%s' label outside of update area .. skipping\n", __PRETTY_FUNCTION__
, message
->entry
->ie_IconListEntry
.label
));
1438 if (message
->drawmode
== ICONENTRY_DRAWMODE_NONE
)
1441 SetABPenDrMd(data
->icld_BufferRastPort
, _pens(obj
)[MPEN_TEXT
], 0, JAM1
);
1443 iconlabelrect
.MinX
= (iconlabelrect
.MinX
- objX
) + data
->icld_DrawOffsetX
;
1444 iconlabelrect
.MinY
= (iconlabelrect
.MinY
- objY
) + data
->icld_DrawOffsetY
;
1445 iconlabelrect
.MaxX
= (iconlabelrect
.MaxX
- objX
) + data
->icld_DrawOffsetX
;
1446 iconlabelrect
.MaxY
= (iconlabelrect
.MaxY
- objY
) + data
->icld_DrawOffsetY
;
1448 labelX
= iconlabelrect
.MinX
+ data
->icld__Option_LabelTextBorderWidth
+ data
->icld__Option_LabelTextHorizontalPadding
;
1449 labelY
= iconlabelrect
.MinY
+ data
->icld__Option_LabelTextBorderHeight
+ data
->icld__Option_LabelTextVerticalPadding
;
1451 txtarea_width
= txtbox_width
- ((data
->icld__Option_LabelTextBorderWidth
+ data
->icld__Option_LabelTextHorizontalPadding
) * 2);
1453 #if defined(DEBUG_ILC_ICONRENDERING)
1454 D(bug("[IconList] %s: Drawing Label '%s' .. %d, %d\n", __PRETTY_FUNCTION__
, message
->entry
->ie_IconListEntry
.label
, labelX
, labelY
));
1456 if (message
->entry
->ie_IconListEntry
.label
&& message
->entry
->ie_TxtBuf_DisplayedLabel
)
1458 char *curlabel_StrPtr
;
1460 if ((message
->entry
->ie_Flags
& ICONENTRY_FLAG_FOCUS
))
1462 //Draw the focus box around the selected label ..
1463 if (data
->icld__Option_LabelTextBorderHeight
> 0)
1465 InvertPixelArray(data
->icld_BufferRastPort
,
1466 iconlabelrect
.MinX
, iconlabelrect
.MinY
,
1467 (iconlabelrect
.MaxX
- iconlabelrect
.MinX
) + 1, data
->icld__Option_LabelTextBorderHeight
);
1469 InvertPixelArray(data
->icld_BufferRastPort
,
1470 iconlabelrect
.MinX
, iconlabelrect
.MaxY
- (data
->icld__Option_LabelTextBorderHeight
- 1),
1471 (iconlabelrect
.MaxX
- iconlabelrect
.MinX
) + 1, data
->icld__Option_LabelTextBorderHeight
);
1473 if (data
->icld__Option_LabelTextBorderWidth
> 0)
1475 InvertPixelArray(data
->icld_BufferRastPort
,
1476 iconlabelrect
.MinX
, iconlabelrect
.MinY
+ data
->icld__Option_LabelTextBorderHeight
,
1477 data
->icld__Option_LabelTextBorderWidth
, (((iconlabelrect
.MaxY
- iconlabelrect
.MinY
) + 1) - (data
->icld__Option_LabelTextBorderHeight
* 2)));
1479 InvertPixelArray(data
->icld_BufferRastPort
,
1480 iconlabelrect
.MaxX
- (data
->icld__Option_LabelTextBorderWidth
- 1), iconlabelrect
.MinY
+ data
->icld__Option_LabelTextBorderHeight
,
1481 data
->icld__Option_LabelTextBorderWidth
, (((iconlabelrect
.MaxY
- iconlabelrect
.MinY
) + 1) - (data
->icld__Option_LabelTextBorderHeight
* 2)));
1485 SetFont(data
->icld_BufferRastPort
, data
->icld_IconLabelFont
);
1487 curlabel_TotalLines
= message
->entry
->ie_SplitParts
;
1488 curlabel_CurrentLine
= 0;
1490 if (curlabel_TotalLines
== 0)
1491 curlabel_TotalLines
= 1;
1493 if (!(data
->icld__Option_LabelTextMultiLineOnFocus
) || (data
->icld__Option_LabelTextMultiLineOnFocus
&& (message
->entry
->ie_Flags
& ICONENTRY_FLAG_FOCUS
)))
1495 if (curlabel_TotalLines
> data
->icld__Option_LabelTextMultiLine
)
1496 curlabel_TotalLines
= data
->icld__Option_LabelTextMultiLine
;
1499 curlabel_TotalLines
= 1;
1501 curlabel_StrPtr
= message
->entry
->ie_TxtBuf_DisplayedLabel
;
1505 #if defined(DEBUG_ILC_ICONRENDERING)
1506 D(bug("[IconList] %s: Font YSize %d Baseline %d\n", __PRETTY_FUNCTION__
,data
->icld_IconLabelFont
->tf_YSize
, data
->icld_IconLabelFont
->tf_Baseline
));
1508 for (curlabel_CurrentLine
= 0; curlabel_CurrentLine
< curlabel_TotalLines
; curlabel_CurrentLine
++)
1510 ULONG ie_LabelLength
;
1512 if (curlabel_CurrentLine
> 0) curlabel_StrPtr
= curlabel_StrPtr
+ strlen(curlabel_StrPtr
) + 1;
1513 if ((curlabel_CurrentLine
>= (curlabel_TotalLines
-1)) && (curlabel_TotalLines
< message
->entry
->ie_SplitParts
))
1515 char *tmpLine
= curlabel_StrPtr
;
1516 ULONG tmpLen
= strlen(tmpLine
);
1518 if ((curlabel_StrPtr
= AllocVecPooled(data
->icld_Pool
, tmpLen
+ 1)) != NULL
)
1520 memset(curlabel_StrPtr
, 0, tmpLen
+ 1);
1521 strncpy(curlabel_StrPtr
, tmpLine
, tmpLen
- 3);
1522 strcat(curlabel_StrPtr
, " ..");
1529 ie_LabelLength
= strlen(curlabel_StrPtr
);
1532 // Center message->entry's label
1533 tx
= (labelX
+ (message
->entry
->ie_TxtBuf_DisplayedLabelWidth
/ 2) - (TextLength(data
->icld_BufferRastPort
, curlabel_StrPtr
, strlen(curlabel_StrPtr
)) / 2));
1535 if (message
->entry
->ie_TxtBuf_DisplayedLabelWidth
< txtarea_width
)
1536 tx
+= ((txtarea_width
- message
->entry
->ie_TxtBuf_DisplayedLabelWidth
)/2);
1538 ty
= ty
+ data
->icld_IconLabelFont
->tf_YSize
;
1540 switch ( data
->icld__Option_LabelTextMode
)
1542 case ICON_TEXTMODE_DROPSHADOW
:
1543 SetAPen(data
->icld_BufferRastPort
, data
->icld_LabelShadowPen
);
1544 Move(data
->icld_BufferRastPort
, tx
+ 1, ty
+ 1);
1545 Text(data
->icld_BufferRastPort
, curlabel_StrPtr
, ie_LabelLength
);
1547 case ICON_TEXTMODE_PLAIN
:
1548 SetAPen(data
->icld_BufferRastPort
, data
->icld_LabelPen
);
1549 Move(data
->icld_BufferRastPort
, tx
, ty
);
1550 Text(data
->icld_BufferRastPort
, curlabel_StrPtr
, ie_LabelLength
);
1555 SetSoftStyle(data
->icld_BufferRastPort
, FSF_BOLD
, AskSoftStyle(data
->icld_BufferRastPort
));
1557 SetAPen(data
->icld_BufferRastPort
, data
->icld_LabelShadowPen
);
1558 Move(data
->icld_BufferRastPort
, tx
+ 1, ty
);
1559 Text(data
->icld_BufferRastPort
, curlabel_StrPtr
, ie_LabelLength
);
1560 Move(data
->icld_BufferRastPort
, tx
- 1, ty
);
1561 Text(data
->icld_BufferRastPort
, curlabel_StrPtr
, ie_LabelLength
);
1562 Move(data
->icld_BufferRastPort
, tx
, ty
+ 1);
1563 Text(data
->icld_BufferRastPort
, curlabel_StrPtr
, ie_LabelLength
);
1564 Move(data
->icld_BufferRastPort
, tx
, ty
- 1);
1565 Text(data
->icld_BufferRastPort
, curlabel_StrPtr
, ie_LabelLength
);
1567 SetAPen(data
->icld_BufferRastPort
, data
->icld_LabelPen
);
1568 Move(data
->icld_BufferRastPort
, tx
, ty
);
1569 Text(data
->icld_BufferRastPort
, curlabel_StrPtr
, ie_LabelLength
);
1571 SetSoftStyle(data
->icld_BufferRastPort
, FS_NORMAL
, AskSoftStyle(data
->icld_BufferRastPort
));
1575 if ((curlabel_CurrentLine
>= (curlabel_TotalLines
-1)) && (curlabel_TotalLines
< message
->entry
->ie_SplitParts
))
1577 FreeVecPooled(data
->icld_Pool
, curlabel_StrPtr
);
1582 /*date/size sorting has the date/size appended under the message->entry label*/
1584 if ((message
->entry
->ie_IconListEntry
.type
!= ST_USERDIR
) && ((data
->icld_SortFlags
& (MUIV_IconList_Sort_BySize
|MUIV_IconList_Sort_ByDate
)) != 0))
1587 SetFont(data
->icld_BufferRastPort
, data
->icld_IconInfoFont
);
1589 if (data
->icld_SortFlags
& MUIV_IconList_Sort_BySize
)
1591 buf
= message
->entry
->ie_TxtBuf_SIZE
;
1592 txwidth
= message
->entry
->ie_TxtBuf_SIZEWidth
;
1594 else if (data
->icld_SortFlags
& MUIV_IconList_Sort_ByDate
)
1596 if (message
->entry
->ie_Flags
& ICONENTRY_FLAG_TODAY
)
1598 buf
= message
->entry
->ie_TxtBuf_TIME
;
1599 txwidth
= message
->entry
->ie_TxtBuf_TIMEWidth
;
1603 buf
= message
->entry
->ie_TxtBuf_DATE
;
1604 txwidth
= message
->entry
->ie_TxtBuf_DATEWidth
;
1610 ULONG ie_LabelLength
= strlen(buf
);
1613 if (txwidth
< txtarea_width
)
1614 tx
+= ((txtarea_width
- txwidth
)/2);
1616 ty
= labelY
+ ((data
->icld__Option_LabelTextVerticalPadding
+ data
->icld_IconLabelFont
->tf_YSize
) * curlabel_TotalLines
) + data
->icld_IconInfoFont
->tf_YSize
;
1618 switch ( data
->icld__Option_LabelTextMode
)
1620 case ICON_TEXTMODE_DROPSHADOW
:
1621 SetAPen(data
->icld_BufferRastPort
, data
->icld_InfoShadowPen
);
1622 Move(data
->icld_BufferRastPort
, tx
+ 1, ty
+ 1); Text(data
->icld_BufferRastPort
, buf
, ie_LabelLength
);
1623 case ICON_TEXTMODE_PLAIN
:
1624 SetAPen(data
->icld_BufferRastPort
, data
->icld_InfoPen
);
1625 Move(data
->icld_BufferRastPort
, tx
, ty
); Text(data
->icld_BufferRastPort
, buf
, ie_LabelLength
);
1630 SetSoftStyle(data
->icld_BufferRastPort
, FSF_BOLD
, AskSoftStyle(data
->icld_BufferRastPort
));
1631 SetAPen(data
->icld_BufferRastPort
, data
->icld_InfoShadowPen
);
1633 Move(data
->icld_BufferRastPort
, tx
+ 1, ty
);
1634 Text(data
->icld_BufferRastPort
, buf
, ie_LabelLength
);
1635 Move(data
->icld_BufferRastPort
, tx
- 1, ty
);
1636 Text(data
->icld_BufferRastPort
, buf
, ie_LabelLength
);
1637 Move(data
->icld_BufferRastPort
, tx
, ty
- 1 );
1638 Text(data
->icld_BufferRastPort
, buf
, ie_LabelLength
);
1639 Move(data
->icld_BufferRastPort
, tx
, ty
+ 1 );
1640 Text(data
->icld_BufferRastPort
, buf
, ie_LabelLength
);
1642 SetAPen(data
->icld_BufferRastPort
, data
->icld_InfoPen
);
1644 Move(data
->icld_BufferRastPort
, tx
, ty
);
1645 Text(data
->icld_BufferRastPort
, buf
, ie_LabelLength
);
1647 SetSoftStyle(data
->icld_BufferRastPort
, FS_NORMAL
, AskSoftStyle(data
->icld_BufferRastPort
));
1657 /**************************************************************************
1659 **************************************************************************/
1660 ///IconList__MUIM_IconList_RethinkDimensions()
1661 IPTR
IconList__MUIM_IconList_RethinkDimensions(struct IClass
*CLASS
, Object
*obj
, struct MUIP_IconList_RethinkDimensions
*message
)
1663 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
1665 struct IconEntry
*entry
= NULL
;
1668 struct Rectangle icon_rect
;
1670 #if defined(DEBUG_ILC_ICONPOSITIONING) || defined(DEBUG_ILC_FUNCS)
1671 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
1674 if (message
->singleicon
!= NULL
)
1676 entry
= message
->singleicon
;
1677 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
1679 maxy
= data
->icld_LVMAttribs
->lmva_RowHeight
;
1680 if ((data
->icld_LVMAttribs
->lvma_Flags
& LVMAF_NOHEADER
) == 0)
1682 maxy
+= data
->icld_LVMAttribs
->lmva_HeaderHeight
;
1687 maxx
= data
->icld_AreaWidth
- 1,
1688 maxy
= data
->icld_AreaHeight
- 1;
1691 #if defined(DEBUG_ILC_ICONPOSITIONING)
1692 D(bug("[IconList] %s: SingleIcon - maxx = %d, maxy = %d\n", __PRETTY_FUNCTION__
, maxx
, maxy
));
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
;
1705 entry
= (struct IconEntry
*)GetHead(&data
->icld_IconList
);
1708 while (entry
!= NULL
)
1710 if (entry
->ie_DiskObj
&&
1711 (entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
))
1713 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
1715 maxy
+= data
->icld_LVMAttribs
->lmva_RowHeight
;
1719 IconList_GetIconAreaRectangle(obj
, data
, entry
, &icon_rect
);
1721 icon_rect
.MaxX
+= entry
->ie_IconX
+ data
->icld__Option_IconHorizontalSpacing
;
1722 if ((data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
) &&
1723 (entry
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
))
1724 icon_rect
.MaxX
+= (data
->icld_IconAreaLargestWidth
- entry
->ie_AreaWidth
);
1726 icon_rect
.MaxY
+= entry
->ie_IconY
+ data
->icld__Option_IconVerticalSpacing
;
1728 if (icon_rect
.MaxX
> maxx
) maxx
= icon_rect
.MaxX
;
1729 if (icon_rect
.MaxY
> maxy
) maxy
= icon_rect
.MaxY
;
1733 if (message
->singleicon
)
1736 entry
= (struct IconEntry
*)GetSucc(&entry
->ie_IconNode
);
1739 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
1743 for(col
= 0; col
< NUM_COLUMNS
; col
++)
1745 LONG index
= data
->icld_LVMAttribs
->lmva_ColumnPos
[col
];
1747 if (!(data
->icld_LVMAttribs
->lmva_ColumnFlags
[index
] & LVMCF_COLVISIBLE
)) continue;
1749 maxx
+= data
->icld_LVMAttribs
->lmva_ColumnWidth
[index
];
1753 /* update our view when max x/y have changed */
1754 if (maxx
+ 1 != data
->icld_AreaWidth
)
1756 data
->icld_AreaWidth
= maxx
+ 1;
1757 SET(obj
, MUIA_IconList_Width
, data
->icld_AreaWidth
);
1759 if (maxy
+ 1 != data
->icld_AreaHeight
)
1761 data
->icld_AreaHeight
= maxy
+ 1;
1762 SET(obj
, MUIA_IconList_Height
, data
->icld_AreaHeight
);
1769 * This function executes the layouting when AutoSort is enabled. This means all icons are layouted regardless if
1770 * they have Provided position or not.
1773 static VOID
IconList_Layout_FullAutoLayout(struct IClass
*CLASS
, Object
*obj
)
1775 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
1776 struct IconEntry
*entry
= NULL
;
1777 struct IconEntry
*pass_first
= NULL
; /* First entry of current column or row */
1779 LONG left
= data
->icld__Option_IconHorizontalSpacing
;
1780 LONG top
= data
->icld__Option_IconVerticalSpacing
;
1785 LONG maxw
= 0; /* Widest & talest entry in a column or row */
1789 struct Rectangle iconrect
;
1791 /* Now go to the actual positioning */
1792 entry
= (struct IconEntry
*)GetHead(&data
->icld_IconList
);
1793 while (entry
!= NULL
)
1795 calcnextpos
= FALSE
;
1796 if ((entry
->ie_DiskObj
!= NULL
) && (entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
))
1800 /* Set previously calculated position to this icon */
1801 entry
->ie_IconX
= cur_x
;
1802 entry
->ie_IconY
= cur_y
;
1804 if (entry
->ie_Flags
& ICONENTRY_FLAG_SELECTED
)
1806 if (data
->icld_SelectionLastClicked
== NULL
) data
->icld_SelectionLastClicked
= entry
;
1807 if (data
->icld_FocusIcon
== NULL
) data
->icld_FocusIcon
= entry
;
1810 /* Calculate grid size to advanced the coordinate in next step */
1811 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
1813 maxw
= data
->icld_IconAreaLargestWidth
+ data
->icld__Option_IconHorizontalSpacing
;
1814 maxh
= data
->icld_IconLargestHeight
+ data
->icld__Option_IconImageSpacing
+ data
->icld_LabelLargestHeight
+ data
->icld__Option_IconVerticalSpacing
;
1820 if (!(pass_first
)) pass_first
= entry
;
1822 IconList_GetIconAreaRectangle(obj
, data
, entry
, &iconrect
);
1824 if ((maxw
< entry
->ie_AreaWidth
) || (maxh
< entry
->ie_AreaHeight
))
1826 if (maxw
< entry
->ie_AreaWidth
) maxw
= entry
->ie_AreaWidth
;
1827 if (maxh
< entry
->ie_AreaHeight
) maxh
= entry
->ie_AreaHeight
;
1828 if (pass_first
!= entry
)
1831 cur_x
= entry
->ie_IconX
;
1832 cur_y
= entry
->ie_IconY
;
1833 /* We detected that the new icon it taller/wider than icons so far in this row/column.
1834 * We need to re-layout this row/column. */
1839 if (data
->icld_DisplayFlags
& ICONLIST_DISP_VERTICAL
)
1842 if (entry
->ie_AreaWidth
< maxw
)
1843 entry
->ie_IconX
+= ( maxw
- entry
->ie_AreaWidth
) / 2;
1846 gridy
= entry
->ie_AreaHeight
+ data
->icld__Option_IconVerticalSpacing
;
1850 /* Centering */ /* Icons look better not centered in this case - disabled */
1851 /* if (entry->ie_AreaHeight < maxh)
1852 entry->ie_IconY += ( maxh - entry->ie_AreaHeight ) / 2; */
1854 gridx
= entry
->ie_AreaWidth
+ data
->icld__Option_IconHorizontalSpacing
;
1861 * Advance to next icon and calculate its position based on grid sizes from previous step.
1862 * Don't set position - it is done at beginning of the loop.
1864 if ((entry
= (struct IconEntry
*)GetSucc(&entry
->ie_IconNode
)) != NULL
)
1868 if (data
->icld_DisplayFlags
& ICONLIST_DISP_VERTICAL
)
1872 if ((cur_y
>= data
->icld_ViewHeight
) ||
1873 ((data
->icld__Option_IconListMode
== ICON_LISTMODE_ROUGH
) && ((cur_y
+ entry
->ie_AreaHeight
- data
->icld__Option_IconBorderOverlap
) >= data
->icld_ViewHeight
)) ||
1874 ((data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
) && ((cur_y
+ data
->icld_IconAreaLargestHeight
- data
->icld__Option_IconBorderOverlap
) >= data
->icld_ViewHeight
)))
1876 /* Wrap "around" if the icon would be below bottom border */
1887 if ((cur_x
>= data
->icld_ViewWidth
) ||
1888 ((data
->icld__Option_IconListMode
== ICON_LISTMODE_ROUGH
) && ((cur_x
+ entry
->ie_AreaWidth
- data
->icld__Option_IconBorderOverlap
) >= data
->icld_ViewWidth
)) ||
1889 ((data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
) && ((cur_x
+ data
->icld_IconAreaLargestWidth
- data
->icld__Option_IconBorderOverlap
) >= data
->icld_ViewWidth
)))
1891 /* Wrap "around" if the icon would be right of right border */
1903 static VOID
IconList_Layout_PartialAutoLayout(struct IClass
*CLASS
, Object
*obj
)
1905 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
1906 struct Region
*occupied
= NewRegion();
1907 struct IconEntry
*entry
= NULL
;
1908 LONG left
= data
->icld__Option_IconHorizontalSpacing
;
1909 LONG top
= data
->icld__Option_IconVerticalSpacing
;
1910 LONG cur_x
= left
, cur_y
= top
;
1912 entry
= (struct IconEntry
*)GetHead(&data
->icld_IconList
);
1913 while (entry
!= NULL
)
1915 if ((entry
->ie_ProvidedIconX
!= NO_ICON_POSITION
) && (entry
->ie_ProvidedIconY
!= NO_ICON_POSITION
)
1916 && (entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
))
1918 struct Rectangle iconrect
= {
1919 entry
->ie_ProvidedIconX
,
1920 entry
->ie_ProvidedIconY
,
1921 entry
->ie_ProvidedIconX
+ entry
->ie_AreaWidth
- 1,
1922 entry
->ie_ProvidedIconY
+ entry
->ie_AreaHeight
- 1
1925 if (data
->icld_DisplayFlags
& ICONLIST_DISP_VERTICAL
)
1926 iconrect
.MaxY
+= data
->icld__Option_IconVerticalSpacing
;
1928 iconrect
.MaxX
+= data
->icld__Option_IconHorizontalSpacing
;
1930 D(bug("Adding %s (%d %d)(%d %d)\n", entry
->ie_TxtBuf_DisplayedLabel
,
1931 (LONG
)iconrect
.MinX
, (LONG
)iconrect
.MinY
, (LONG
)iconrect
.MaxX
, (LONG
)iconrect
.MaxY
));
1933 OrRectRegion(occupied
, &iconrect
);
1935 entry
= (struct IconEntry
*)GetSucc(&entry
->ie_IconNode
);
1938 /* Now go to the actual positioning */
1939 entry
= (struct IconEntry
*)GetHead(&data
->icld_IconList
);
1940 while (entry
!= NULL
)
1942 if ((entry
->ie_DiskObj
!= NULL
) && (entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
))
1944 if ((entry
->ie_ProvidedIconX
!= NO_ICON_POSITION
) && (entry
->ie_ProvidedIconY
!= NO_ICON_POSITION
))
1946 entry
->ie_IconX
= entry
->ie_ProvidedIconX
;
1947 entry
->ie_IconY
= entry
->ie_ProvidedIconY
;
1951 LONG gridx
, gridy
, stepx
, stepy
, addx
= 0;
1952 struct Rectangle iconarea
;
1955 /* Calculate grid size and step */
1956 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
1958 gridx
= data
->icld_IconAreaLargestWidth
+ data
->icld__Option_IconHorizontalSpacing
;
1959 gridy
= data
->icld_IconLargestHeight
+ data
->icld__Option_IconImageSpacing
+ data
->icld_LabelLargestHeight
+ data
->icld__Option_IconVerticalSpacing
;
1965 if (data
->icld_DisplayFlags
& ICONLIST_DISP_VERTICAL
)
1967 gridx
= data
->icld_IconAreaLargestWidth
; /* This gives better centering effect */
1968 gridy
= entry
->ie_AreaHeight
+ data
->icld__Option_IconVerticalSpacing
;
1971 addx
= (gridx
- entry
->ie_AreaWidth
) / 2;
1975 gridx
= entry
->ie_AreaWidth
+ data
->icld__Option_IconHorizontalSpacing
;
1976 gridy
= entry
->ie_AreaHeight
+ data
->icld__Option_IconVerticalSpacing
;
1982 /* Find first not occupied spot matching the calculate rectangle */
1985 if (data
->icld_DisplayFlags
& ICONLIST_DISP_VERTICAL
)
1987 /* Advance to next position */
1988 if (!first
) cur_y
+= stepy
;
1990 if ((cur_y
>= data
->icld_ViewHeight
) ||
1991 ((cur_y
+ gridy
- data
->icld__Option_IconBorderOverlap
) >= data
->icld_ViewHeight
))
1993 /* Wrap "around" if the icon would be below bottom border */
2000 /* Advance to next position */
2001 if (!first
) cur_x
+= stepx
;
2003 if ((cur_x
>= data
->icld_ViewWidth
) ||
2004 ((cur_x
+ gridx
- data
->icld__Option_IconBorderOverlap
) >= data
->icld_ViewWidth
))
2006 /* Wrap "around" if the icon would be right of right border */
2012 iconarea
.MinX
= cur_x
;
2013 iconarea
.MinY
= cur_y
;
2014 iconarea
.MaxX
= cur_x
+ gridx
- 1;
2015 iconarea
.MaxY
= cur_y
+ gridy
- 1;
2019 } while(RegionAndRect(occupied
, &iconarea
));
2021 entry
->ie_IconX
= iconarea
.MinX
+ addx
;
2022 entry
->ie_IconY
= iconarea
.MinY
;
2024 /* Add this area to occupied list */
2025 OrRectRegion(occupied
, &iconarea
);
2027 /* Add spacing to next icon */
2028 if (data
->icld_DisplayFlags
& ICONLIST_DISP_VERTICAL
)
2035 entry
= (struct IconEntry
*)GetSucc(&entry
->ie_IconNode
);
2038 DisposeRegion(occupied
);
2042 ///IconList__MUIM_IconList_PositionIcons()
2043 /**************************************************************************
2044 MUIM_PositionIcons - Place icons with NO_ICON_POSITION coords somewhere
2045 **************************************************************************/
2046 IPTR
IconList__MUIM_IconList_PositionIcons(struct IClass
*CLASS
, Object
*obj
, struct MUIP_IconList_PositionIcons
*message
)
2048 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
2049 struct IconEntry
*entry
= NULL
;
2052 #if defined(DEBUG_ILC_ICONPOSITIONING) || defined(DEBUG_ILC_FUNCS)
2053 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
2055 if ((data
->icld_SortFlags
& MUIV_IconList_Sort_AutoSort
) == 0)
2057 IconList_Layout_PartialAutoLayout(CLASS
, obj
);
2061 IconList_Layout_FullAutoLayout(CLASS
, obj
);
2065 * Set Provided icon position on all icons (this can't be done as part of previous loop!)
2066 * The icons will not no longer be autolayouted unless MUIV_IconList_Sort_AutoSort is set.
2067 * This give the stability that new icons appearing won't make existing icons jump from their places
2069 entry
= (struct IconEntry
*)GetHead(&data
->icld_IconList
);
2070 while (entry
!= NULL
)
2072 if (entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
2073 DoMethod(obj
, MUIM_IconList_PropagateEntryPos
, entry
);
2075 entry
= (struct IconEntry
*)GetSucc(&entry
->ie_IconNode
);
2079 DoMethod(obj
, MUIM_IconList_RethinkDimensions
, NULL
);
2086 #define ICONENTRY_SIZE 16
2088 static inline void CalcHeight(struct ListViewModeAttribs
*LVMAttribs
, struct TextFont
*LabelFont
)
2090 ULONG YSize
= LabelFont
? LabelFont
->tf_YSize
: 0;
2092 LVMAttribs
->lmva_HeaderHeight
= HEADERLINE_EXTRAHEIGHT
+ YSize
;
2093 LVMAttribs
->lmva_RowHeight
= LINE_EXTRAHEIGHT
+ ((ICONENTRY_SIZE
> YSize
) ? ICONENTRY_SIZE
: YSize
);
2096 /**************************************************************************
2098 **************************************************************************/
2099 IPTR
IconList__OM_NEW(struct IClass
*CLASS
, Object
*obj
, struct opSet
*message
)
2101 struct IconList_DATA
*data
= NULL
;
2102 struct TextFont
*icl_WindowFont
= NULL
;
2103 // struct RastPort *icl_RastPort = NULL;
2106 #if defined(DEBUG_ILC_FUNCS)
2107 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
2110 icl_WindowFont
= (struct TextFont
*) GetTagData(MUIA_Font
, (IPTR
) NULL
, message
->ops_AttrList
);
2112 obj
= (Object
*)DoSuperNewTags(CLASS
, obj
, NULL
,
2113 MUIA_FillArea
, FALSE
,
2114 MUIA_Dropable
, TRUE
,
2115 MUIA_Font
, MUIV_Font_Tiny
,
2116 TAG_MORE
, (IPTR
) message
->ops_AttrList
);
2118 if (!obj
) return FALSE
;
2120 data
= INST_DATA(CLASS
, obj
);
2122 data
->icld_Pool
= CreatePool(0,4096,4096);
2123 if (!data
->icld_Pool
)
2125 CoerceMethod(CLASS
,obj
,OM_DISPOSE
);
2129 #if defined(DEBUG_ILC_FUNCS)
2130 D(bug("[IconList] %s: SELF = 0x%p, muiRenderInfo = 0x%p\n", __PRETTY_FUNCTION__
, obj
, muiRenderInfo(obj
)));
2132 NewList((struct List
*)&data
->icld_IconList
);
2133 NewList((struct List
*)&data
->icld_SelectionList
);
2135 data
->icld_IconLabelFont
= icl_WindowFont
;
2137 /* Setup Icon View-Mode options */
2138 data
->icld_IVMAttribs
= AllocMem(sizeof(struct IconViewModeAttribs
), MEMF_CLEAR
);
2139 /* Setup List View-Mode options */
2140 if ((data
->icld_LVMAttribs
= AllocMem(sizeof(struct ListViewModeAttribs
), MEMF_CLEAR
)) != NULL
)
2142 for(i
= 0; i
< NUM_COLUMNS
; i
++)
2144 data
->icld_LVMAttribs
->lmva_ColumnPos
[i
] = i
;
2145 data
->icld_LVMAttribs
->lmva_ColumnFlags
[i
] = LVMCF_COLVISIBLE
;
2146 data
->icld_LVMAttribs
->lmva_ColumnWidth
[i
] = 100;
2147 data
->icld_LVMAttribs
->lmva_ColumnHAlign
[i
] = COLUMN_ALIGN_LEFT
;
2151 data
->icld_LVMAttribs
->lmva_ColumnHAlign
[i
] = COLUMN_ALIGN_RIGHT
;
2152 data
->icld_LVMAttribs
->lmva_ColumnFlags
[i
] |= (LVMCF_COLCLICKABLE
|LVMCF_COLSORTABLE
);
2153 data
->icld_LVMAttribs
->lmva_ColumnTitle
[i
] = "Type";
2154 data
->icld_LVMAttribs
->lmva_ColumnWidth
[i
] = ICONENTRY_SIZE
+ 2;
2158 data
->icld_LVMAttribs
->lmva_ColumnFlags
[i
] |= (LVMCF_COLCLICKABLE
|LVMCF_COLSORTABLE
);
2159 data
->icld_LVMAttribs
->lmva_ColumnTitle
[i
] = "Name";
2163 data
->icld_LVMAttribs
->lmva_ColumnHAlign
[i
] = COLUMN_ALIGN_RIGHT
;
2164 data
->icld_LVMAttribs
->lmva_ColumnFlags
[i
] |= LVMCF_COLSORTABLE
;
2165 data
->icld_LVMAttribs
->lmva_ColumnTitle
[i
] = "Size";
2168 case INDEX_LASTACCESS
:
2169 data
->icld_LVMAttribs
->lmva_ColumnFlags
[i
] |= LVMCF_COLSORTABLE
;
2170 data
->icld_LVMAttribs
->lmva_ColumnTitle
[i
] = "Last Accessed";
2174 data
->icld_LVMAttribs
->lmva_ColumnTitle
[i
] = "Comment";
2177 case INDEX_PROTECTION
:
2178 data
->icld_LVMAttribs
->lmva_ColumnTitle
[i
] = "Protection";
2182 data
->icld_LVMAttribs
->lmva_ColumnTitle
[i
] = "<Unknown>";
2186 data
->icld_LVMAttribs
->lmva_LastSelectedColumn
= -1;
2187 data
->icld_LVMAttribs
->lmva_SortColumn
= INDEX_NAME
;
2188 data
->icld_LVMAttribs
->lvma_Flags
= LVMAF_HEADERDRAWTOEND
;
2190 * Seems to be not needed because it's done in MUIM_Setup. No rendering happens before it.
2191 * Height calculation moved to MUIM_Setup because font pointer can be NULL here (if user-specified
2192 * font failed to open). In this case we fail back to the font specified in MUI's AreaData, but
2193 * it becomes known only in MUIM_Setup
2195 CalcHeight(data->icld_LVMAttribs, data->icld_IconLabelFont); */
2198 /* Get/Set initial values */
2199 /* TODO: TrimVolumeNames should be prefs settable */
2200 data
->icld__Option_TrimVolumeNames
= TRUE
;
2201 /* TODO: Adjust overlap by window border width */
2202 data
->icld__Option_IconBorderOverlap
= 10;
2204 data
->icld__Option_IconListMode
= (UBYTE
)GetTagData(MUIA_IconList_IconListMode
, 0, message
->ops_AttrList
);
2205 data
->icld__Option_LabelTextMode
= (UBYTE
)GetTagData(MUIA_IconList_LabelText_Mode
, 0, message
->ops_AttrList
);
2206 data
->icld__Option_LabelTextMaxLen
= (ULONG
)GetTagData(MUIA_IconList_LabelText_MaxLineLen
, ILC_ICONLABEL_MAXLINELEN_DEFAULT
, message
->ops_AttrList
);
2207 data
->icld__Option_DragImageTransparent
= (BOOL
)GetTagData(MUIA_IconList_DragImageTransparent
, FALSE
, message
->ops_AttrList
);
2209 if ( data
->icld__Option_LabelTextMaxLen
< ILC_ICONLABEL_SHORTEST
)
2210 data
->icld__Option_LabelTextMaxLen
= ILC_ICONLABEL_MAXLINELEN_DEFAULT
;
2212 data
->icld__Option_LastLabelTextMaxLen
= data
->icld__Option_LabelTextMaxLen
;
2214 #if defined(DEBUG_ILC_FUNCS)
2215 D(bug("[IconList] %s: MaxLineLen : %ld\n", __PRETTY_FUNCTION__
, data
->icld__Option_LabelTextMaxLen
));
2217 data
->ehn
.ehn_Events
= IDCMP_MOUSEBUTTONS
| IDCMP_RAWKEY
| IDCMP_NEWSIZE
;
2218 data
->ehn
.ehn_Priority
= 0;
2219 data
->ehn
.ehn_Flags
= 0;
2220 data
->ehn
.ehn_Object
= obj
;
2221 data
->ehn
.ehn_Class
= CLASS
;
2223 data
->icld_SortFlags
= MUIV_IconList_Sort_ByName
;
2224 data
->icld_DisplayFlags
= ICONLIST_DISP_SHOWINFO
;
2226 __iconlist_UpdateLabels_hook
.h_Entry
= (HOOKFUNC
)IconList__HookFunc_UpdateLabelsFunc
;
2230 obj
, MUIM_Notify
, MUIA_IconList_LabelText_MaxLineLen
, MUIV_EveryTime
,
2232 MUIM_CallHook
, &__iconlist_UpdateLabels_hook
, (IPTR
)CLASS
2237 obj
, MUIM_Notify
, MUIA_IconList_LabelText_MultiLine
, MUIV_EveryTime
,
2239 MUIM_CallHook
, &__iconlist_UpdateLabels_hook
, (IPTR
)CLASS
2242 #if defined(DEBUG_ILC_FUNCS)
2243 D(bug("[IconList] obj = %ld\n", obj
));
2250 /**************************************************************************
2252 **************************************************************************/
2253 IPTR
IconList__OM_DISPOSE(struct IClass
*CLASS
, Object
*obj
, Msg message
)
2255 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
2256 struct IconEntry
*node
= NULL
;
2258 #if defined(DEBUG_ILC_FUNCS)
2259 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
2262 #if defined(__AROS__)
2263 ForeachNode(&data
->icld_IconList
, node
)
2265 Foreach_Node(&data
->icld_IconList
, node
);
2268 if (node
->ie_DiskObj
)
2269 FreeDiskObject(node
->ie_DiskObj
);
2272 if (data
->icld_Pool
) DeletePool(data
->icld_Pool
);
2274 DoSuperMethodA(CLASS
,obj
,message
);
2280 /**************************************************************************
2282 **************************************************************************/
2283 IPTR
IconList__OM_SET(struct IClass
*CLASS
, Object
*obj
, struct opSet
*message
)
2285 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
2286 struct TagItem
*tag
= NULL
,
2289 WORD oldleft
= data
->icld_ViewX
,
2290 oldtop
= data
->icld_ViewY
;
2291 //oldwidth = data->icld_ViewWidth,
2292 //oldheight = data->icld_ViewHeight;
2294 #if defined(DEBUG_ILC_FUNCS) || defined(DEBUG_ILC_ATTRIBS)
2295 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
2298 /* parse initial taglist */
2299 for (tags
= message
->ops_AttrList
; (tag
= NextTagItem((TAGITEM
)&tags
)); )
2301 switch (tag
->ti_Tag
)
2303 case MUIA_Virtgroup_Left
:
2304 #if defined(DEBUG_ILC_ATTRIBS)
2305 D(bug("[IconList] %s: MUIA_Virtgroup_Left %ld\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2307 if (data
->icld_ViewX
!= tag
->ti_Data
)
2308 data
->icld_ViewX
= tag
->ti_Data
;
2311 case MUIA_Virtgroup_Top
:
2312 #if defined(DEBUG_ILC_ATTRIBS)
2313 D(bug("[IconList] %s: MUIA_Virtgroup_Top %ld\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2315 if (data
->icld_ViewY
!= tag
->ti_Data
)
2316 data
->icld_ViewY
= tag
->ti_Data
;
2319 case MUIA_IconList_Rastport
:
2320 #if defined(DEBUG_ILC_ATTRIBS)
2321 D(bug("[IconList] %s: MUIA_IconList_Rastport 0x%p\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2323 data
->icld_DisplayRastPort
= (struct RastPort
*)tag
->ti_Data
;
2324 data
->icld_DrawOffsetX
= _mleft(obj
);
2325 data
->icld_DrawOffsetY
= _mtop(obj
);
2326 if (data
->icld_BufferRastPort
!= NULL
)
2328 //Buffer still set!?!?!
2330 SET(obj
, MUIA_IconList_BufferRastport
, tag
->ti_Data
);
2333 case MUIA_IconList_BufferRastport
:
2334 #if defined(DEBUG_ILC_ATTRIBS)
2335 D(bug("[IconList] %s: MUIA_IconList_BufferRastport 0x%p\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2337 data
->icld_BufferRastPort
= (struct RastPort
*)tag
->ti_Data
;
2341 #if defined(DEBUG_ILC_ATTRIBS)
2342 D(bug("[IconList] %s: MUIA_Font 0x%p\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2344 data
->icld_IconLabelFont
= (struct TextFont
*)tag
->ti_Data
;
2345 /* FIXME: Should we call CalcHeight() here because our font changed? */
2348 case MUIA_IconList_LabelInfoText_Font
:
2349 #if defined(DEBUG_ILC_ATTRIBS)
2350 D(bug("[IconList] %s: MUIA_IconList_LabelInfoText_Font 0x%p\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2352 data
->icld_IconInfoFont
= (struct TextFont
*)tag
->ti_Data
;
2355 case MUIA_IconList_DisplayFlags
:
2357 #if defined(DEBUG_ILC_ATTRIBS)
2358 D(bug("[IconList] %s: MUIA_IconList_DisplayFlags %08x\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2360 // ULONG origModeFlags = data->icld_DisplayFlags & (ICONLIST_DISP_MODEDEFAULT|ICONLIST_DISP_MODELABELRIGHT|ICONLIST_DISP_MODELIST);
2361 data
->icld_DisplayFlags
= (ULONG
)tag
->ti_Data
;
2363 if (data
->icld_DisplayFlags
& ICONLIST_DISP_BUFFERED
)
2365 #if defined(DEBUG_ILC_ATTRIBS) || defined(DEBUG_ILC_ICONRENDERING)
2366 D(bug("[IconList] %s: MUIA_IconList_DisplayFlags & ICONLIST_DISP_BUFFERED\n", __PRETTY_FUNCTION__
));
2368 if ((data
->icld_BufferRastPort
!= NULL
)
2369 && (data
->icld_BufferRastPort
!= data
->icld_DisplayRastPort
))
2371 #if defined(DEBUG_ILC_ATTRIBS) || defined(DEBUG_ILC_ICONRENDERING)
2372 D(bug("[IconList] %s: BackLayer @ %p for BackRastport @ %p\n", __PRETTY_FUNCTION__
, data
->icld_BufferRastPort
->Layer
, data
->icld_BufferRastPort
));
2374 if ((GetBitMapAttr(data
->icld_BufferRastPort
->BitMap
, BMA_WIDTH
) != data
->icld_ViewWidth
)
2375 || (GetBitMapAttr(data
->icld_BufferRastPort
->BitMap
, BMA_HEIGHT
) != data
->icld_ViewHeight
))
2377 struct Layer
*oldLayer
= data
->icld_BufferRastPort
->Layer
;
2378 #if defined(DEBUG_ILC_ATTRIBS) || defined(DEBUG_ILC_ICONRENDERING)
2379 D(bug("[IconList] %s: Destroying old BackLayer\n", __PRETTY_FUNCTION__
));
2381 data
->icld_BufferRastPort
= data
->icld_DisplayRastPort
;
2382 DeleteLayer(0, oldLayer
);
2386 if ((data
->icld_BufferRastPort
== NULL
) || (data
->icld_BufferRastPort
== data
->icld_DisplayRastPort
))
2388 struct BitMap
*bitmap_New
= NULL
;
2389 ULONG tmp_RastDepth
;
2390 struct Layer_Info
*li
= NULL
;
2392 tmp_RastDepth
= GetCyberMapAttr(data
->icld_DisplayRastPort
->BitMap
, CYBRMATTR_DEPTH
);
2393 if ((bitmap_New
= AllocBitMap(data
->icld_ViewWidth
,
2394 data
->icld_ViewHeight
,
2397 data
->icld_DisplayRastPort
->BitMap
))!=NULL
)
2399 if ((data
->icld_BufferRastPort
= CreateRastPort())!=NULL
)
2401 data
->icld_BufferRastPort
->BitMap
= bitmap_New
;
2402 if ((li
= NewLayerInfo()))
2404 if ((data
->icld_BufferRastPort
->Layer
= CreateUpfrontLayer(li
, data
->icld_BufferRastPort
->BitMap
, 0, 0, data
->icld_ViewWidth
- 1, data
->icld_ViewHeight
- 1, 0, NULL
)))
2407 * Mark it as a buffered rastport.
2410 #if defined(DEBUG_ILC_ATTRIBS) || defined(DEBUG_ILC_ICONRENDERING)
2411 D(bug("[IconList] %s: FrontRastPort @ %p, New BackLayer @ %p, BackRastport @ %p\n", __PRETTY_FUNCTION__
, data
->icld_DisplayRastPort
, data
->icld_BufferRastPort
->Layer
, data
->icld_BufferRastPort
));
2413 SET(obj
, MUIA_IconList_BufferRastport
, data
->icld_BufferRastPort
);
2414 data
->icld_DrawOffsetX
= 0;
2415 data
->icld_DrawOffsetY
= 0;
2418 data
->icld_BufferRastPort
= data
->icld_DisplayRastPort
;
2421 data
->icld_BufferRastPort
= data
->icld_DisplayRastPort
;
2424 data
->icld_BufferRastPort
= data
->icld_DisplayRastPort
;
2426 if (data
->icld_BufferRastPort
== data
->icld_DisplayRastPort
)
2428 if (bitmap_New
) FreeBitMap(bitmap_New
);
2429 if (li
) DisposeLayerInfo(li
);
2430 data
->icld_DrawOffsetX
= _mleft(obj
);
2431 data
->icld_DrawOffsetY
= _mtop(obj
);
2437 if ((data
->icld_BufferRastPort
) && (data
->icld_BufferRastPort
!= data
->icld_DisplayRastPort
))
2439 //Free up the buffers layer, rastport and bitmap since they are no longer needed ..
2440 struct Layer
*oldLayer
= data
->icld_BufferRastPort
->Layer
;
2441 data
->icld_BufferRastPort
= data
->icld_DisplayRastPort
;
2442 InstallClipRegion(oldLayer
, NULL
);
2443 DeleteLayer(0, oldLayer
);
2444 FreeBitMap(data
->icld_BufferRastPort
->BitMap
);
2445 data
->icld_DrawOffsetX
= _mleft(obj
);
2446 data
->icld_DrawOffsetY
= _mtop(obj
);
2449 SET(obj
, MUIA_IconList_Changed
, TRUE
);
2453 case MUIA_IconList_SortFlags
:
2454 #if defined(DEBUG_ILC_ATTRIBS)
2455 D(bug("[IconList] %s: MUIA_IconList_SortFlags %08x\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2457 data
->icld_SortFlags
= (ULONG
)tag
->ti_Data
;
2460 case MUIA_IconList_DragImageTransparent
:
2461 data
->icld__Option_DragImageTransparent
= (BOOL
)tag
->ti_Data
;
2464 case MUIA_IconList_IconListMode
:
2465 #if defined(DEBUG_ILC_ATTRIBS)
2466 D(bug("[IconList] %s: MUIA_IconList_IconListMode %d\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2468 data
->icld__Option_IconListMode
= (UBYTE
)tag
->ti_Data
;
2471 case MUIA_IconList_LabelText_Mode
:
2472 #if defined(DEBUG_ILC_ATTRIBS)
2473 D(bug("[IconList] %s: MUIA_IconList_LabelText_Mode %d\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2475 data
->icld__Option_LabelTextMode
= (UBYTE
)tag
->ti_Data
;
2478 case MUIA_IconList_LabelText_MaxLineLen
:
2479 #if defined(DEBUG_ILC_ATTRIBS)
2480 D(bug("[IconList] %s: MUIA_IconList_LabelText_MaxLineLen %d\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2482 if (tag
->ti_Data
>= ILC_ICONLABEL_SHORTEST
)
2484 data
->icld__Option_LabelTextMaxLen
= (ULONG
)tag
->ti_Data
;
2488 data
->icld__Option_LabelTextMaxLen
= ILC_ICONLABEL_MAXLINELEN_DEFAULT
;
2492 case MUIA_IconList_LabelText_MultiLine
:
2493 #if defined(DEBUG_ILC_ATTRIBS)
2494 D(bug("[IconList] %s: MUIA_IconList_LabelText_MultiLine %d\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2496 data
->icld__Option_LabelTextMultiLine
= (ULONG
)tag
->ti_Data
;
2497 if (data
->icld__Option_LabelTextMultiLine
== 0)data
->icld__Option_LabelTextMultiLine
= 1;
2500 case MUIA_IconList_LabelText_MultiLineOnFocus
:
2501 #if defined(DEBUG_ILC_ATTRIBS)
2502 D(bug("[IconList] %s: MUIA_IconList_LabelText_MultiLineOnFocus %d\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2504 data
->icld__Option_LabelTextMultiLineOnFocus
= (BOOL
)tag
->ti_Data
;
2507 case MUIA_IconList_Icon_HorizontalSpacing
:
2508 #if defined(DEBUG_ILC_ATTRIBS)
2509 D(bug("[IconList] %s: MUIA_IconList_Icon_HorizontalSpacing %d\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2511 data
->icld__Option_IconHorizontalSpacing
= (UBYTE
)tag
->ti_Data
;
2514 case MUIA_IconList_Icon_VerticalSpacing
:
2515 #if defined(DEBUG_ILC_ATTRIBS)
2516 D(bug("[IconList] %s: MUIA_IconList_Icon_VerticalSpacing %d\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2518 data
->icld__Option_IconVerticalSpacing
= (UBYTE
)tag
->ti_Data
;
2521 case MUIA_IconList_Icon_ImageSpacing
:
2522 #if defined(DEBUG_ILC_ATTRIBS)
2523 D(bug("[IconList] %s: MUIA_IconList_Icon_ImageSpacing %d\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2525 data
->icld__Option_IconImageSpacing
= (UBYTE
)tag
->ti_Data
;
2528 case MUIA_IconList_LabelText_HorizontalPadding
:
2529 #if defined(DEBUG_ILC_ATTRIBS)
2530 D(bug("[IconList] %s: MUIA_IconList_LabelText_HorizontalPadding %d\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2532 data
->icld__Option_LabelTextHorizontalPadding
= (UBYTE
)tag
->ti_Data
;
2535 case MUIA_IconList_LabelText_VerticalPadding
:
2536 #if defined(DEBUG_ILC_ATTRIBS)
2537 D(bug("[IconList] %s: MUIA_IconList_LabelText_VerticalPadding %d\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2539 data
->icld__Option_LabelTextVerticalPadding
= (UBYTE
)tag
->ti_Data
;
2542 case MUIA_IconList_LabelText_BorderWidth
:
2543 #if defined(DEBUG_ILC_ATTRIBS)
2544 D(bug("[IconList] %s: MUIA_IconList_LabelText_BorderWidth %d\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2546 data
->icld__Option_LabelTextBorderWidth
= (UBYTE
)tag
->ti_Data
;
2549 case MUIA_IconList_LabelText_BorderHeight
:
2550 #if defined(DEBUG_ILC_ATTRIBS)
2551 D(bug("[IconList] %s: MUIA_IconList_LabelText_BorderHeight %d\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2553 data
->icld__Option_LabelTextBorderHeight
= (UBYTE
)tag
->ti_Data
;
2556 case MUIA_IconList_LabelText_Pen
:
2557 data
->icld_LabelPen
= (ULONG
)tag
->ti_Data
;
2560 case MUIA_IconList_LabelText_ShadowPen
:
2561 data
->icld_LabelShadowPen
= (ULONG
)tag
->ti_Data
;
2564 case MUIA_IconList_LabelInfoText_Pen
:
2565 data
->icld_InfoPen
= (ULONG
)tag
->ti_Data
;
2568 case MUIA_IconList_LabelInfoText_ShadowPen
:
2569 data
->icld_InfoShadowPen
= (ULONG
)tag
->ti_Data
;
2572 /* Settings defined by the view class */
2573 case MUIA_IconListview_FixedBackground
:
2574 #if defined(DEBUG_ILC_ATTRIBS)
2575 D(bug("[IconList] %s: MUIA_IconListview_FixedBackground\n", __PRETTY_FUNCTION__
));
2577 data
->icld__Option_IconListFixedBackground
= (BOOL
)tag
->ti_Data
;
2580 case MUIA_IconListview_ScaledBackground
:
2581 #if defined(DEBUG_ILC_ATTRIBS)
2582 D(bug("[IconList] %s: MUIA_IconListview_ScaledBackground\n", __PRETTY_FUNCTION__
));
2584 data
->icld__Option_IconListScaledBackground
= (BOOL
)tag
->ti_Data
;
2587 /* We listen for MUIA_Background and set default values for known types */
2588 case MUIA_Background
:
2589 #if defined(DEBUG_ILC_ATTRIBS) || defined(DEBUG_ILC_ICONRENDERING)
2590 D(bug("[IconList] %s: MUIA_Background\n", __PRETTY_FUNCTION__
));
2593 char *bgmode_string
= (char *)tag
->ti_Data
;
2594 BYTE this_mode
= bgmode_string
[0] - 48;
2596 #if defined(DEBUG_ILC_ATTRIBS) || defined(DEBUG_ILC_ICONRENDERING)
2597 D(bug("[IconList] %s: MUIA_Background | MUI BG Mode = %d\n", __PRETTY_FUNCTION__
, this_mode
));
2603 NNSET(obj
, MUIA_IconListview_FixedBackground
, FALSE
);
2604 NNSET(obj
, MUIA_IconListview_ScaledBackground
, FALSE
);
2608 NNSET(obj
, MUIA_IconListview_FixedBackground
, FALSE
);
2609 NNSET(obj
, MUIA_IconListview_ScaledBackground
, FALSE
);
2613 NNSET(obj
, MUIA_IconListview_FixedBackground
, TRUE
);
2614 NNSET(obj
, MUIA_IconListview_ScaledBackground
, TRUE
);
2618 NNSET(obj
, MUIA_IconListview_FixedBackground
, FALSE
);
2619 NNSET(obj
, MUIA_IconListview_ScaledBackground
, FALSE
);
2624 case MUIA_IconList_IconsDropped
:
2625 data
->icld_DragDropEvent
= (struct IconList_Drop_Event
*)tag
->ti_Data
;
2630 #if defined(DEBUG_ILC_ATTRIBS)
2631 D(bug("[IconList] %s(), out of switch\n", __PRETTY_FUNCTION__
));
2633 if ((oldleft
!= data
->icld_ViewX
) || (oldtop
!= data
->icld_ViewY
))
2635 data
->icld_UpdateMode
= UPDATE_SCROLL
;
2636 data
->update_scrolldx
= data
->icld_ViewX
- oldleft
;
2637 data
->update_scrolldy
= data
->icld_ViewY
- oldtop
;
2638 #if defined(DEBUG_ILC_ATTRIBS)
2639 D(bug("[IconList] %s(), call MUI_Redraw()\n", __PRETTY_FUNCTION__
));
2641 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
2644 #if defined(DEBUG_ILC_ATTRIBS)
2645 D(bug("[IconList] %s(), call DoSuperMethodA()\n", __PRETTY_FUNCTION__
));
2647 return DoSuperMethodA(CLASS
, obj
, (Msg
)message
);
2652 /**************************************************************************
2654 **************************************************************************/
2655 IPTR
IconList__OM_GET(struct IClass
*CLASS
, Object
*obj
, struct opGet
*message
)
2657 /* small macro to simplify return value storage */
2658 #define STORE *(message->opg_Storage)
2659 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
2661 #if defined(DEBUG_ILC_FUNCS) || defined(DEBUG_ILC_ATTRIBS)
2662 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
2665 switch (message
->opg_AttrID
)
2667 case MUIA_IconList_Rastport
: STORE
= (IPTR
)data
->icld_DisplayRastPort
; return 1;
2668 case MUIA_IconList_BufferRastport
: STORE
= (IPTR
)data
->icld_BufferRastPort
; return 1;
2669 case MUIA_IconList_BufferLeft
: STORE
= (IPTR
)data
->icld_DrawOffsetX
; return 1;
2670 case MUIA_IconList_BufferTop
: STORE
= (IPTR
)data
->icld_DrawOffsetY
; return 1;
2671 case MUIA_IconList_BufferWidth
:
2672 case MUIA_IconList_Width
: STORE
= (IPTR
)data
->icld_AreaWidth
; return 1;
2673 case MUIA_IconList_BufferHeight
:
2674 case MUIA_IconList_Height
: STORE
= (IPTR
)data
->icld_AreaHeight
; return 1;
2675 case MUIA_IconList_IconsDropped
: STORE
= (IPTR
)data
->icld_DragDropEvent
; return 1;
2676 case MUIA_IconList_Clicked
: STORE
= (IPTR
)&data
->icld_ClickEvent
; return 1;
2677 case MUIA_IconList_IconListMode
: STORE
= (IPTR
)data
->icld__Option_IconListMode
; return 1;
2678 case MUIA_IconList_LabelText_Mode
: STORE
= (IPTR
)data
->icld__Option_LabelTextMode
; return 1;
2679 case MUIA_IconList_LabelText_MaxLineLen
: STORE
= (IPTR
)data
->icld__Option_LabelTextMaxLen
; return 1;
2680 case MUIA_IconList_LabelText_MultiLine
: STORE
= (IPTR
)data
->icld__Option_LabelTextMultiLine
; return 1;
2681 case MUIA_IconList_LabelText_MultiLineOnFocus
: STORE
= (IPTR
)data
->icld__Option_LabelTextMultiLineOnFocus
; return 1;
2682 case MUIA_IconList_DisplayFlags
: STORE
= (IPTR
)data
->icld_DisplayFlags
; return 1;
2683 case MUIA_IconList_SortFlags
: STORE
= (IPTR
)data
->icld_SortFlags
; return 1;
2685 case MUIA_IconList_FocusIcon
: STORE
= (IPTR
)data
->icld_FocusIcon
; return 1;
2687 case MUIA_Font
: STORE
= (IPTR
)data
->icld_IconLabelFont
; return 1;
2688 case MUIA_IconList_LabelText_Pen
: STORE
= (IPTR
)data
->icld_LabelPen
; return 1;
2689 case MUIA_IconList_LabelText_ShadowPen
: STORE
= (IPTR
)data
->icld_LabelShadowPen
; return 1;
2690 case MUIA_IconList_LabelInfoText_Font
: STORE
= (IPTR
)data
->icld_IconInfoFont
; return 1;
2691 case MUIA_IconList_LabelInfoText_Pen
: STORE
= (IPTR
)data
->icld_InfoPen
; return 1;
2692 case MUIA_IconList_LabelInfoText_ShadowPen
: STORE
= (IPTR
)data
->icld_InfoShadowPen
; return 1;
2693 case MUIA_IconList_DragImageTransparent
: STORE
= (IPTR
)data
->icld__Option_DragImageTransparent
; return 1;
2695 case MUIA_IconList_Icon_HorizontalSpacing
: STORE
= (IPTR
)data
->icld__Option_IconHorizontalSpacing
; return 1;
2696 case MUIA_IconList_Icon_VerticalSpacing
: STORE
= (IPTR
)data
->icld__Option_IconVerticalSpacing
; return 1;
2697 case MUIA_IconList_Icon_ImageSpacing
: STORE
= (IPTR
)data
->icld__Option_IconImageSpacing
; return 1;
2698 case MUIA_IconList_LabelText_HorizontalPadding
: STORE
= (IPTR
)data
->icld__Option_LabelTextHorizontalPadding
; return 1;
2699 case MUIA_IconList_LabelText_VerticalPadding
: STORE
= (IPTR
)data
->icld__Option_LabelTextVerticalPadding
; return 1;
2700 case MUIA_IconList_LabelText_BorderWidth
: STORE
= (IPTR
)data
->icld__Option_LabelTextBorderWidth
; return 1;
2701 case MUIA_IconList_LabelText_BorderHeight
: STORE
= (IPTR
)data
->icld__Option_LabelTextBorderHeight
; return 1;
2703 /* Settings defined by the view class */
2704 case MUIA_IconListview_FixedBackground
: STORE
= (IPTR
)data
->icld__Option_IconListFixedBackground
; return 1;
2705 case MUIA_IconListview_ScaledBackground
: STORE
= (IPTR
)data
->icld__Option_IconListScaledBackground
; return 1;
2707 /* ICON obj Changes */
2708 case MUIA_Virtgroup_Left
: STORE
= (IPTR
)data
->icld_ViewX
; return 1;
2709 case MUIA_Virtgroup_Top
: STORE
= (IPTR
)data
->icld_ViewY
; return 1;
2710 case MUIA_Family_List
: STORE
= (IPTR
)&(data
->icld_IconList
); return 1; /* Get our list object */
2712 /* TODO: Get the version/revision from our config.. */
2713 case MUIA_Version
: STORE
= (IPTR
)1; return 1;
2714 case MUIA_Revision
: STORE
= (IPTR
)7; return 1;
2717 return DoSuperMethodA(CLASS
, obj
, (Msg
) message
);
2722 IPTR
IconList__MUIM_Family_AddHead(struct IClass
*CLASS
, Object
*obj
, struct MUIP_Family_AddHead
*message
)
2724 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
2725 #if defined(DEBUG_ILC_FUNCS)
2726 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
2731 /* TODO: Use the correct _OBJECT() code when we switch to icon.mui */
2732 // AddHead(&(data->icld_IconList), (struct Node *)_OBJECT(message->obj));
2733 AddHead(&(data
->icld_IconList
), (struct Node
*)message
->obj
);
2740 IPTR
IconList__MUIM_Family_AddTail(struct IClass
*CLASS
, Object
*obj
, struct MUIP_Family_AddTail
*message
)
2742 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
2743 #if defined(DEBUG_ILC_FUNCS)
2744 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
2747 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
));
2751 /* TODO: Use the correct _OBJECT() code when we switch to icon.mui */
2752 // AddTail(&(data->icld_IconList), (struct Node *)_OBJECT(message->obj));
2753 AddTail(&(data
->icld_IconList
), (struct Node
*)message
->obj
);
2761 #if !defined(WANDERER_BUILTIN_ICONLIST)
2762 IPTR
IconList__OM_ADDMEMBER(struct IClass
*CLASS
, Object
*obj
, struct MUIP_Family_AddTail
*message
)
2764 return IconList__MUIM_Family_AddTail(CLASS
, obj
, message
);
2768 IPTR
IconList__MUIM_Family_Remove(struct IClass
*CLASS
, Object
*obj
, struct MUIP_Family_Remove
*message
)
2770 // struct IconList_DATA *data = INST_DATA(CLASS, obj);
2771 #if defined(DEBUG_ILC_FUNCS)
2772 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
2775 D(bug("[IconList] %s: entry @ 0x%p '%s'\n", __PRETTY_FUNCTION__
, message
->obj
, ((struct IconEntry
*)message
->obj
)->ie_IconNode
.ln_Name
));
2779 /* TODO: Use the correct _OBJECT() code when we switch to icon.mui */
2780 // Remove((struct Node *)_OBJECT(message->obj));
2781 Remove((struct Node
*)message
->obj
);
2789 #if !defined(WANDERER_BUILTIN_ICONLIST)
2790 IPTR
IconList__OM_REMMEMBER(struct IClass
*CLASS
, Object
*obj
, struct MUIP_Family_Remove
*message
)
2792 return IconList__MUIM_Family_Remove(CLASS
, obj
, message
);
2797 /**************************************************************************
2799 **************************************************************************/
2800 IPTR
IconList__MUIM_Setup(struct IClass
*CLASS
, Object
*obj
, struct MUIP_Setup
*message
)
2802 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
2803 struct IconEntry
*node
= NULL
;
2804 IPTR geticon_error
= 0, iconlistScreen
;
2806 #if defined(DEBUG_ILC_FUNCS)
2807 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
2810 if (!DoSuperMethodA(CLASS
, obj
, (Msg
) message
)) return (IPTR
)NULL
;
2812 iconlistScreen
= (IPTR
)_screen(obj
);
2813 #if defined(DEBUG_ILC_ICONRENDERING)
2814 D(bug("[IconList] %s: IconList Screen @ 0x%p)\n", __PRETTY_FUNCTION__
, iconlistScreen
));
2817 DoMethod(_win(obj
), MUIM_Window_AddEventHandler
, (IPTR
)&data
->ehn
);
2819 /* Get Internal Objects to use if not set .. */
2820 data
->icld_DisplayRastPort
= NULL
;
2821 data
->icld_BufferRastPort
= NULL
;
2823 if (data
->icld_IconLabelFont
== NULL
) data
->icld_IconLabelFont
= _font(obj
);
2824 if (data
->icld_IconInfoFont
== NULL
) data
->icld_IconInfoFont
= data
->icld_IconLabelFont
;
2827 * Here we have our font, either from user preferences or from MUI's AreaData.
2828 * It's right time to set up some sizes.
2830 CalcHeight(data
->icld_LVMAttribs
, data
->icld_IconLabelFont
);
2831 #if defined(DEBUG_ILC_ICONRENDERING)
2832 D(bug("[IconList] %s: Use Font @ 0x%p, RastPort @ 0x%p\n", __PRETTY_FUNCTION__
, data
->icld_IconLabelFont
, data
->icld_BufferRastPort
));
2835 /* Set our base options .. */
2836 data
->icld_LabelPen
= _pens(obj
)[MPEN_SHINE
];
2837 data
->icld_LabelShadowPen
= _pens(obj
)[MPEN_SHADOW
];
2838 data
->icld_InfoPen
= _pens(obj
)[MPEN_SHINE
];
2839 data
->icld_InfoShadowPen
= _pens(obj
)[MPEN_SHADOW
];
2841 data
->icld__Option_LabelTextMultiLine
= 1;
2842 data
->icld__Option_LastLabelTextMultiLine
= data
->icld__Option_LabelTextMultiLine
;
2844 data
->icld__Option_LabelTextMultiLineOnFocus
= FALSE
;
2846 data
->icld__Option_IconHorizontalSpacing
= ILC_ICON_HORIZONTALMARGIN_DEFAULT
;
2847 data
->icld__Option_IconVerticalSpacing
= ILC_ICON_VERTICALMARGIN_DEFAULT
;
2848 data
->icld__Option_IconImageSpacing
= ILC_ICONLABEL_IMAGEMARGIN_DEFAULT
;
2849 data
->icld__Option_LabelTextHorizontalPadding
= ILC_ICONLABEL_HORIZONTALTEXTMARGIN_DEFAULT
;
2850 data
->icld__Option_LabelTextVerticalPadding
= ILC_ICONLABEL_VERTICALTEXTMARGIN_DEFAULT
;
2851 data
->icld__Option_LabelTextBorderWidth
= ILC_ICONLABEL_BORDERWIDTH_DEFAULT
;
2852 data
->icld__Option_LabelTextBorderHeight
= ILC_ICONLABEL_BORDERHEIGHT_DEFAULT
;
2854 if (data
->icld_LVMAttribs
)
2856 data
->icld_LVMAttribs
->lvma_IconDrawer
= GetIconTags
2858 "WANDERER:Icons/drawer",
2859 (iconlistScreen
) ? ICONGETA_Screen
: TAG_IGNORE
, iconlistScreen
,
2860 (iconlistScreen
) ? ICONGETA_RemapIcon
: TAG_IGNORE
, TRUE
,
2861 ICONGETA_FailIfUnavailable
, TRUE
,
2862 ICONGETA_GenerateImageMasks
, TRUE
,
2863 ICONA_ErrorCode
, &geticon_error
,
2867 #if defined(DEBUG_ILC_ICONRENDERING)
2868 if (data
->icld_LVMAttribs
->lvma_IconDrawer
== NULL
)
2870 D(bug("[IconList] %s: Couldnt get drawer DiskObject! (error code = 0x%p)\n", __PRETTY_FUNCTION__
, geticon_error
));
2873 data
->icld_LVMAttribs
->lvma_IconFile
= GetIconTags
2875 "WANDERER:Icons/file",
2876 (iconlistScreen
) ? ICONGETA_Screen
: TAG_IGNORE
, iconlistScreen
,
2877 (iconlistScreen
) ? ICONGETA_RemapIcon
: TAG_IGNORE
, TRUE
,
2878 ICONGETA_FailIfUnavailable
, TRUE
,
2879 ICONGETA_GenerateImageMasks
, TRUE
,
2880 ICONA_ErrorCode
, &geticon_error
,
2884 #if defined(DEBUG_ILC_ICONRENDERING)
2885 if (data
->icld_LVMAttribs
->lvma_IconFile
== NULL
)
2887 D(bug("[IconList] %s: Couldnt get file DiskObject! (error code = 0x%p)\n", __PRETTY_FUNCTION__
, geticon_error
));
2892 #if defined(__AROS__)
2893 ForeachNode(&data
->icld_IconList
, node
)
2895 Foreach_Node(&data
->icld_IconList
, node
);
2898 if (!node
->ie_DiskObj
)
2900 if (!(node
->ie_DiskObj
= GetIconTags(node
->ie_IconNode
.ln_Name
,
2901 (iconlistScreen
) ? ICONGETA_Screen
: TAG_IGNORE
, iconlistScreen
,
2902 (iconlistScreen
) ? ICONGETA_RemapIcon
: TAG_IGNORE
, TRUE
,
2903 ICONGETA_GenerateImageMasks
, TRUE
,
2904 ICONGETA_FailIfUnavailable
, FALSE
,
2905 ICONA_ErrorCode
, &geticon_error
,
2908 #if defined(DEBUG_ILC_ICONRENDERING)
2909 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
));
2911 /* We should probably remove this node if the entry cant be obtained ? */
2920 /**************************************************************************
2922 **************************************************************************/
2923 IPTR
IconList__MUIM_Show(struct IClass
*CLASS
, Object
*obj
, struct MUIP_Show
*message
)
2925 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
2930 #if defined(DEBUG_ILC_FUNCS)
2931 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
2934 if ((rc
= DoSuperMethodA(CLASS
, obj
, (Msg
)message
)))
2936 newleft
= data
->icld_ViewX
;
2937 newtop
= data
->icld_ViewY
;
2939 if (newleft
+ _mwidth(obj
) > data
->icld_AreaWidth
)
2940 newleft
= data
->icld_AreaWidth
- _mwidth(obj
);
2944 if (newtop
+ _mheight(obj
) > data
->icld_AreaHeight
)
2945 newtop
= data
->icld_AreaHeight
- _mheight(obj
);
2949 if ((newleft
!= data
->icld_ViewX
) || (newtop
!= data
->icld_ViewY
))
2951 SetAttrs(obj
, MUIA_Virtgroup_Left
, newleft
,
2952 MUIA_Virtgroup_Top
, newtop
,
2956 /* Get Internal Objects to use if not set .. */
2957 if (data
->icld_DisplayRastPort
== NULL
)
2959 if (_rp(obj
) != NULL
)
2961 data
->icld_DisplayRastPort
= CloneRastPort(_rp(obj
));
2963 #if defined(DEBUG_ILC_ICONRENDERING)
2966 D(bug("[IconList] IconList__MUIM_Show: ERROR - NULL RastPort!\n"));
2971 if (data
->icld_DisplayFlags
& ICONLIST_DISP_BUFFERED
)
2973 struct BitMap
*bitmap_New
= NULL
;
2974 struct Layer_Info
*li
= NULL
;
2976 ULONG tmp_RastDepth
= GetCyberMapAttr(data
->icld_DisplayRastPort
->BitMap
, CYBRMATTR_DEPTH
);
2977 if ((bitmap_New
= AllocBitMap(data
->icld_ViewWidth
,
2978 data
->icld_ViewHeight
,
2981 data
->icld_DisplayRastPort
->BitMap
))!=NULL
)
2983 if ((data
->icld_BufferRastPort
= CreateRastPort())!=NULL
)
2985 data
->icld_BufferRastPort
->BitMap
= bitmap_New
;
2986 if ((li
= NewLayerInfo()))
2988 if ((data
->icld_BufferRastPort
->Layer
= CreateUpfrontLayer(li
, data
->icld_BufferRastPort
->BitMap
, 0, 0, data
->icld_ViewWidth
- 1, data
->icld_ViewHeight
- 1, 0, NULL
)))
2991 * Mark it as a buffered rastport.
2994 #if defined(DEBUG_ILC_ATTRIBS) || defined(DEBUG_ILC_ICONRENDERING)
2995 D(bug("[IconList] %s: FrontRastPort @ %p, New BackLayer @ %p, BackRastport @ %p\n", __PRETTY_FUNCTION__
, data
->icld_DisplayRastPort
, data
->icld_BufferRastPort
->Layer
, data
->icld_BufferRastPort
));
2997 SET(obj
, MUIA_IconList_BufferRastport
, data
->icld_BufferRastPort
);
2998 data
->icld_DrawOffsetX
= 0;
2999 data
->icld_DrawOffsetY
= 0;
3002 data
->icld_BufferRastPort
= data
->icld_DisplayRastPort
;
3005 data
->icld_BufferRastPort
= data
->icld_DisplayRastPort
;
3008 data
->icld_BufferRastPort
= data
->icld_DisplayRastPort
;
3010 if (data
->icld_BufferRastPort
== data
->icld_DisplayRastPort
)
3012 if (bitmap_New
) FreeBitMap(bitmap_New
);
3013 if (li
) DisposeLayerInfo(li
);
3014 data
->icld_DrawOffsetX
= _mleft(obj
);
3015 data
->icld_DrawOffsetY
= _mtop(obj
);
3020 data
->icld_BufferRastPort
= data
->icld_DisplayRastPort
;
3021 data
->icld_DrawOffsetX
= _mleft(obj
);
3022 data
->icld_DrawOffsetY
= _mtop(obj
);
3025 if (data
->icld_IconLabelFont
== NULL
) data
->icld_IconLabelFont
= _font(obj
);
3026 if (data
->icld_IconInfoFont
== NULL
) data
->icld_IconInfoFont
= data
->icld_IconLabelFont
;
3027 #if defined(DEBUG_ILC_ICONRENDERING)
3028 D(bug("[IconList] IconList__MUIM_Show: Use Font @ 0x%p, RastPort @ 0x%p\n", data
->icld_IconLabelFont
, data
->icld_BufferRastPort
));
3031 if ((data
->icld_BufferRastPort
) && (data
->icld_IconLabelFont
))
3032 SetFont(data
->icld_BufferRastPort
, data
->icld_IconLabelFont
);
3039 /**************************************************************************
3041 **************************************************************************/
3042 IPTR
IconList__MUIM_Hide(struct IClass
*CLASS
, Object
*obj
, struct MUIP_Hide
*message
)
3044 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
3047 #if defined(DEBUG_ILC_FUNCS)
3048 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
3051 if ((rc
= DoSuperMethodA(CLASS
, obj
, (Msg
)message
)))
3053 if ((data
->icld_BufferRastPort
) && (data
->icld_BufferRastPort
!= data
->icld_DisplayRastPort
))
3055 DeleteLayer(0, data
->icld_BufferRastPort
->Layer
);
3058 data
->icld_BufferRastPort
= NULL
;
3060 if (data
->icld_DisplayRastPort
)
3061 FreeRastPort(data
->icld_DisplayRastPort
);
3063 data
->icld_DisplayRastPort
= NULL
;
3070 /**************************************************************************
3072 **************************************************************************/
3073 IPTR
IconList__MUIM_Cleanup(struct IClass
*CLASS
, Object
*obj
, struct MUIP_Cleanup
*message
)
3075 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
3076 struct IconEntry
*node
= NULL
;
3078 #if defined(DEBUG_ILC_FUNCS)
3079 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
3082 #if defined(__AROS__)
3083 ForeachNode(&data
->icld_IconList
, node
)
3085 Foreach_Node(&data
->icld_IconList
, node
);
3088 if (node
->ie_DiskObj
)
3090 FreeDiskObject(node
->ie_DiskObj
);
3091 node
->ie_DiskObj
= NULL
;
3095 DoMethod(_win(obj
), MUIM_Window_RemEventHandler
, (IPTR
)&data
->ehn
);
3097 return DoSuperMethodA(CLASS
, obj
, (Msg
)message
);
3102 /**************************************************************************
3104 **************************************************************************/
3105 IPTR
IconList__MUIM_AskMinMax(struct IClass
*CLASS
, Object
*obj
, struct MUIP_AskMinMax
*message
)
3107 ULONG rc
= DoSuperMethodA(CLASS
, obj
, (Msg
) message
);
3109 #if defined(DEBUG_ILC_FUNCS)
3110 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
3113 message
->MinMaxInfo
->MinWidth
+= 96;
3114 message
->MinMaxInfo
->MinHeight
+= 64;
3116 message
->MinMaxInfo
->DefWidth
+= 200;
3117 message
->MinMaxInfo
->DefHeight
+= 180;
3119 message
->MinMaxInfo
->MaxWidth
= MUI_MAXMAX
;
3120 message
->MinMaxInfo
->MaxHeight
= MUI_MAXMAX
;
3127 /**************************************************************************
3129 **************************************************************************/
3130 IPTR
IconList__MUIM_Layout(struct IClass
*CLASS
, Object
*obj
,struct MUIP_Layout
*message
)
3132 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
3135 #if defined(DEBUG_ILC_FUNCS)
3136 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
3139 rc
= DoSuperMethodA(CLASS
, obj
, (Msg
)message
);
3141 data
->icld_ViewWidth
= _mwidth(obj
);
3142 data
->icld_ViewHeight
= _mheight(obj
);
3148 static LONG
FirstVisibleLine(struct IconList_DATA
*data
)
3150 return data
->icld_ViewY
/ data
->icld_LVMAttribs
->lmva_RowHeight
;
3153 static LONG
NumVisibleLines(struct IconList_DATA
*data
)
3155 LONG visible
= data
->icld_ViewHeight
+ data
->icld_LVMAttribs
->lmva_RowHeight
- 1 +
3156 (data
->icld_ViewY
% data
->icld_LVMAttribs
->lmva_RowHeight
);
3158 visible
/= data
->icld_LVMAttribs
->lmva_RowHeight
;
3163 static void RenderListViewModeHeaderField(Object
*obj
, struct IconList_DATA
*data
,
3164 struct Rectangle
*rect
, LONG index
, BOOL sel
)
3166 IPTR penFill
, penText
, penDark
, penBright
;
3167 struct Rectangle rendRect
;
3169 struct TextExtent te
;
3174 penFill
= _pens(obj
)[MPEN_HALFSHADOW
];
3175 penBright
= _pens(obj
)[MPEN_SHADOW
];
3176 penDark
= _pens(obj
)[MPEN_HALFSHINE
];
3180 penFill
= _pens(obj
)[MPEN_HALFSHINE
];
3181 penBright
= _pens(obj
)[MPEN_SHINE
];
3182 penDark
= _pens(obj
)[MPEN_HALFSHADOW
];
3184 penText
= _pens(obj
)[MPEN_TEXT
];
3186 rendRect
.MinX
= rect
->MinX
;
3187 rendRect
.MaxX
= rect
->MaxX
;
3188 rendRect
.MinY
= rect
->MinY
;
3189 rendRect
.MaxY
= rect
->MaxY
;
3191 if (data
->icld_DisplayRastPort
!= data
->icld_BufferRastPort
)
3193 rendRect
.MinX
-= _mleft(obj
);
3194 rendRect
.MaxX
-= _mleft(obj
);
3195 rendRect
.MinY
-= _mtop(obj
);
3196 rendRect
.MaxY
-= _mtop(obj
);
3199 #if defined(DEBUG_ILC_FUNCS)
3200 D(bug("[IconList]: %s(obj @ 0x%p)\n", __PRETTY_FUNCTION__
, obj
));
3203 if (((data
->icld_LVMAttribs
->lvma_Flags
& LVMAF_NOHEADER
) == 0) && (index
< NUM_COLUMNS
))
3205 text
= data
->icld_LVMAttribs
->lmva_ColumnTitle
[index
];
3207 SetAPen(data
->icld_BufferRastPort
, penFill
); /* Background */
3208 RectFill(data
->icld_BufferRastPort
, rendRect
.MinX
+ 1, rendRect
.MinY
+ 1,
3209 rendRect
.MaxX
- 1, rendRect
.MaxY
- 1);
3211 SetAPen(data
->icld_BufferRastPort
, penBright
); /* Top/Left */
3212 RectFill(data
->icld_BufferRastPort
, rendRect
.MinX
, rendRect
.MinY
, rendRect
.MinX
, rendRect
.MaxY
);
3213 RectFill(data
->icld_BufferRastPort
, rendRect
.MinX
+ 1, rendRect
.MinY
, rendRect
.MaxX
- 1, rendRect
.MinY
);
3215 SetAPen(data
->icld_BufferRastPort
,penDark
); /* Bottom/Right */
3216 RectFill(data
->icld_BufferRastPort
, rendRect
.MaxX
, rendRect
.MinY
, rendRect
.MaxX
, rendRect
.MaxY
);
3217 RectFill(data
->icld_BufferRastPort
, rendRect
.MinX
+ 1, rendRect
.MaxY
, rendRect
.MaxX
- 1, rendRect
.MaxY
);
3219 /* Draw the Sort indicator .. */
3220 if (index
== data
->icld_LVMAttribs
->lmva_SortColumn
)
3222 LONG x
= rendRect
.MaxX
- 4 - 6;
3223 LONG y
= (rendRect
.MinY
+ rendRect
.MaxY
+ 1) / 2 - 3;
3225 if (x
> rendRect
.MinX
)
3227 SetAPen(data
->icld_BufferRastPort
, _pens(obj
)[sel
? MPEN_SHADOW
: MPEN_HALFSHADOW
]);
3228 if (data
->icld_SortFlags
& MUIV_IconList_Sort_Reverse
)
3230 RectFill(data
->icld_BufferRastPort
, x
, y
, x
+ 5, y
+ 1);
3231 RectFill(data
->icld_BufferRastPort
, x
+ 1, y
+ 2, x
+ 4, y
+ 3);
3232 RectFill(data
->icld_BufferRastPort
, x
+ 2, y
+ 4, x
+ 3, y
+ 5);
3236 RectFill(data
->icld_BufferRastPort
, x
, y
+ 4, x
+ 5, y
+ 5);
3237 RectFill(data
->icld_BufferRastPort
, x
+ 1, y
+ 2, x
+ 4, y
+ 3);
3238 RectFill(data
->icld_BufferRastPort
, x
+ 2, y
, x
+ 3, y
+ 1);
3243 rendRect
.MinX
+= HEADERENTRY_SPACING_LEFT
;
3244 rendRect
.MinY
+= HEADERLINE_SPACING_TOP
;
3245 rendRect
.MaxX
-= HEADERENTRY_SPACING_RIGHT
;
3246 rendRect
.MaxY
-= HEADERLINE_SPACING_BOTTOM
;
3248 if (text
&& text
[0])
3251 fit
= TextFit(data
->icld_BufferRastPort
, text
, strlen(text
), &te
, NULL
, 1,
3252 rendRect
.MaxX
- rendRect
.MinX
+ 1,
3253 rendRect
.MaxY
- rendRect
.MinY
+ 1);
3257 SetABPenDrMd(data
->icld_BufferRastPort
, penText
, 0, JAM1
);
3258 Move(data
->icld_BufferRastPort
, rendRect
.MinX
, rendRect
.MinY
+ data
->icld_BufferRastPort
->TxBaseline
);
3259 Text(data
->icld_BufferRastPort
, text
, fit
);
3264 static void RenderListViewModeHeader(Object
*obj
, struct IconList_DATA
*data
)
3266 struct Rectangle linerect
;
3268 LONG firstvis
, lastvis
;
3270 #if defined(DEBUG_ILC_FUNCS)
3271 D(bug("[IconList]: %s(obj @ 0x%p)\n", __PRETTY_FUNCTION__
, obj
));
3274 if ((data
->icld_LVMAttribs
->lvma_Flags
& LVMAF_NOHEADER
) == 0)
3276 linerect
.MinX
= _mleft(obj
) - data
->icld_ViewX
;
3277 linerect
.MaxX
= _mright(obj
);
3278 linerect
.MinY
= _mtop(obj
);
3279 linerect
.MaxY
= _mtop(obj
) + data
->icld_LVMAttribs
->lmva_HeaderHeight
- 1;
3281 SetFont(data
->icld_BufferRastPort
, data
->icld_IconLabelFont
);
3283 x
= linerect
.MinX
+ HEADERLINE_SPACING_LEFT
;
3285 firstvis
= FirstVisibleColumnNumber(data
);
3286 lastvis
= LastVisibleColumnNumber(data
);
3288 for(i
= 0; i
< NUM_COLUMNS
; i
++)
3290 LONG index
= data
->icld_LVMAttribs
->lmva_ColumnPos
[i
];
3292 if (!(data
->icld_LVMAttribs
->lmva_ColumnFlags
[index
] & LVMCF_COLVISIBLE
)) continue;
3294 BOOL outside
= FALSE
;
3295 struct Rectangle field_rect
;
3297 field_rect
.MinX
= (i
== firstvis
) ? linerect
.MinX
: x
;
3298 field_rect
.MinY
= linerect
.MinY
;
3299 field_rect
.MaxX
= x
+ data
->icld_LVMAttribs
->lmva_ColumnWidth
[index
] - 1 + ((i
== lastvis
) ? HEADERLINE_SPACING_RIGHT
: 0);
3300 field_rect
.MaxY
= linerect
.MaxY
;
3302 /* data->update_rect1 and data->update_rect2 may
3303 point to rectangles to indicate that only icons
3304 in any of this rectangles need to be drawn */
3305 if (data
->update_rect1
)
3307 if (!RectAndRect(&field_rect
, data
->update_rect1
))
3311 if (data
->update_rect2
)
3313 if (data
->update_rect1
)
3315 if ((outside
== TRUE
) && RectAndRect(&field_rect
, data
->update_rect2
))
3320 if (!RectAndRect(&field_rect
, data
->update_rect2
))
3325 if (outside
!= TRUE
)
3327 RenderListViewModeHeaderField(obj
, data
, &field_rect
, index
, FALSE
);
3328 x
+= data
->icld_LVMAttribs
->lmva_ColumnWidth
[index
];
3330 #if defined(DEBUG_ILC_ICONRENDERING)
3333 D(bug("[IconList] %s: Column '%s' outside of update area .. skipping\n", __PRETTY_FUNCTION__
, data
->icld_LVMAttribs
->lmva_ColumnTitle
[i
]));
3338 if ((data
->icld_LVMAttribs
->lvma_Flags
& LVMAF_HEADERDRAWTOEND
) == LVMAF_HEADERDRAWTOEND
)
3340 x
+= HEADERLINE_SPACING_RIGHT
;
3342 if (x
< linerect
.MaxX
)
3346 // if (MustRenderRect(data, &linerect))
3348 SetABPenDrMd(data
->icld_BufferRastPort
, _pens(obj
)[MPEN_HALFSHINE
], 0, JAM1
);
3349 RectFill(data
->icld_BufferRastPort
, linerect
.MinX
, linerect
.MinY
, linerect
.MaxX
, linerect
.MaxY
);
3357 /**************************************************************************
3358 MUIM_Draw - draw the IconList
3359 **************************************************************************/
3361 IPTR
IconList__MUIM_Draw(struct IClass
*CLASS
, Object
*obj
, struct MUIP_Draw
*message
)
3363 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
3364 struct IconEntry
*entry
= NULL
;
3368 ULONG update_oldwidth
= 0,
3369 update_oldheight
= 0;
3371 LONG clear_xoffset
= 0,
3374 __unused IPTR draw_id
= DrawCount
++;
3376 #if defined(DEBUG_ILC_FUNCS)
3377 D(bug("[IconList]: %s(obj @ 0x%p)\n", __PRETTY_FUNCTION__
, obj
));
3379 #if defined(DEBUG_ILC_ICONRENDERING)
3380 D(bug("[IconList] %s: id %d\n", __PRETTY_FUNCTION__
, draw_id
));
3383 DoSuperMethodA(CLASS
, obj
, (Msg
)message
);
3385 if (!(data
->icld__Option_IconListFixedBackground
))
3387 clear_xoffset
= data
->icld_ViewX
;
3388 clear_yoffset
= data
->icld_ViewY
;
3391 // If window size changes, only update needed areas
3392 if (data
->update_oldwidth
== 0) data
->update_oldwidth
= data
->icld_ViewWidth
;
3393 if (data
->update_oldheight
== 0) data
->update_oldheight
= data
->icld_ViewHeight
;
3394 if ((data
->update_oldwidth
!= data
->icld_ViewWidth
) || (data
->update_oldheight
!= data
->icld_ViewHeight
))
3396 if (data
->icld_UpdateMode
!= UPDATE_SCROLL
)
3398 data
->icld_UpdateMode
= UPDATE_RESIZE
;
3399 update_oldwidth
= data
->update_oldwidth
;
3400 update_oldheight
= data
->update_oldheight
;
3401 data
->update_oldwidth
= data
->icld_ViewWidth
;
3402 data
->update_oldheight
= data
->icld_ViewHeight
;
3406 if ((message
->flags
& MADF_DRAWUPDATE
) || (data
->icld_UpdateMode
== UPDATE_RESIZE
))
3408 #if defined(DEBUG_ILC_ICONRENDERING)
3410 if (message
->flags
& MADF_DRAWUPDATE
)
3412 bug("[IconList] %s#%d: MADF_DRAWUPDATE\n", __PRETTY_FUNCTION__
, draw_id
);
3416 bug("[IconList] %s#%d: UPDATE_RESIZE\n", __PRETTY_FUNCTION__
, draw_id
);
3420 if ((data
->icld_UpdateMode
== UPDATE_HEADERENTRY
) && ((IPTR
)data
->update_entry
< NUM_COLUMNS
)) /* draw the header entry */
3422 struct Rectangle field_rect
;
3423 LONG index
, i
, firstvis
, lastvis
;
3425 firstvis
= FirstVisibleColumnNumber(data
);
3426 lastvis
= LastVisibleColumnNumber(data
);
3428 field_rect
.MinX
= _mleft(obj
) - data
->icld_ViewX
;
3430 field_rect
.MinY
= _mtop(obj
);
3431 field_rect
.MaxY
= field_rect
.MinY
+ data
->icld_LVMAttribs
->lmva_HeaderHeight
- 1;
3433 for(i
= 0; i
< NUM_COLUMNS
; i
++)
3435 index
= data
->icld_LVMAttribs
->lmva_ColumnPos
[i
];
3436 if (!(data
->icld_LVMAttribs
->lmva_ColumnFlags
[index
] & LVMCF_COLVISIBLE
)) continue;
3438 field_rect
.MaxX
= field_rect
.MinX
+ data
->icld_LVMAttribs
->lmva_ColumnWidth
[index
] - 1;
3439 if (index
== lastvis
)
3440 field_rect
.MaxX
+= HEADERLINE_SPACING_RIGHT
;
3442 if ((IPTR
)data
->update_entry
!= index
)
3444 field_rect
.MinX
+= data
->icld_LVMAttribs
->lmva_ColumnWidth
[index
];
3445 if (index
== firstvis
)
3446 field_rect
.MinX
+= HEADERLINE_SPACING_LEFT
;
3452 clip
= MUI_AddClipping(muiRenderInfo(obj
), _mleft(obj
), _mtop(obj
), _mright(obj
) - _mleft(obj
) + 1, data
->icld_LVMAttribs
->lmva_HeaderHeight
);
3454 if (data
->icld_LVMAttribs
->lmva_LastSelectedColumn
== (IPTR
)data
->update_entry
)
3455 RenderListViewModeHeaderField(obj
, data
, &field_rect
, (IPTR
)data
->update_entry
, TRUE
);
3457 RenderListViewModeHeaderField(obj
, data
, &field_rect
, (IPTR
)data
->update_entry
, FALSE
);
3459 data
->icld_UpdateMode
= 0;
3460 data
->update_entry
= NULL
;
3462 if (data
->icld_DisplayRastPort
!= data
->icld_BufferRastPort
)
3464 #if defined(DEBUG_ILC_ICONRENDERING)
3465 D(bug("[IconList] %s#%d: UPDATE_HEADERENTRY Blitting to front rastport..\n", __PRETTY_FUNCTION__
, draw_id
));
3467 BltBitMapRastPort(data
->icld_BufferRastPort
->BitMap
,
3468 field_rect
.MinX
- _mleft(obj
), field_rect
.MinY
- _mtop(obj
),
3469 data
->icld_DisplayRastPort
,
3470 field_rect
.MinX
, field_rect
.MinY
,
3471 field_rect
.MaxX
- field_rect
.MinX
+ 1, field_rect
.MaxY
- field_rect
.MinY
+ 1,
3474 MUI_RemoveClipping(muiRenderInfo(obj
), clip
);
3478 else if ((data
->icld_UpdateMode
== UPDATE_SINGLEENTRY
) && (data
->update_entry
!= NULL
)) /* draw only a single entry at update_entry */
3480 struct Rectangle rect
;
3482 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
3484 LONG count
= 0, index
= -1;
3486 #if defined(DEBUG_ILC_ICONRENDERING)
3487 D(bug("[IconList] %s#%d: UPDATE_SINGLEENTRY + ICONLIST_DISP_MODELIST\n", __PRETTY_FUNCTION__
, draw_id
));
3489 rect
.MinX
= _mleft(obj
);
3490 rect
.MaxX
= _mleft(obj
) + _mwidth(obj
) - 1;
3492 ForeachNode(&data
->icld_IconList
, entry
)
3494 if (entry
== data
->update_entry
)
3499 if (entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
3507 rect
.MinY
= _mtop(obj
) + data
->icld_LVMAttribs
->lmva_HeaderHeight
- data
->icld_ViewY
+ (index
* data
->icld_LVMAttribs
->lmva_RowHeight
);
3508 rect
.MaxY
= rect
.MinY
+ data
->icld_LVMAttribs
->lmva_RowHeight
- 1;
3510 if ((rect
.MaxY
< (_mtop(obj
) + data
->icld_LVMAttribs
->lmva_HeaderHeight
))
3511 || (rect
.MinY
> (_mtop(obj
) + _mheight(obj
) - 1)))
3514 if (rect
.MinY
< (_mtop(obj
) + data
->icld_LVMAttribs
->lmva_HeaderHeight
)) rect
.MinY
= _mtop(obj
) + data
->icld_LVMAttribs
->lmva_HeaderHeight
;
3515 if (rect
.MaxY
> (_mtop(obj
) + _mheight(obj
) - 1)) rect
.MaxY
= _mtop(obj
) + _mheight(obj
) - 1;
3517 clip
= MUI_AddClipping(muiRenderInfo(obj
), rect
.MinX
, rect
.MinY
, rect
.MaxX
- rect
.MinX
+ 1, rect
.MaxY
- rect
.MinY
+ 1);
3519 DoMethod(obj
, MUIM_DrawBackground
,
3520 rect
.MinX
, rect
.MinY
,
3521 rect
.MaxX
- rect
.MinX
+ 1, rect
.MaxY
- rect
.MinY
+ 1,
3522 clear_xoffset
, clear_yoffset
,
3525 entry
->ie_Flags
|= ICONENTRY_FLAG_NEEDSUPDATE
;
3526 DoMethod(obj
, MUIM_IconList_DrawEntry
, data
->update_entry
, index
);
3527 entry
->ie_Flags
&= ~ICONENTRY_FLAG_NEEDSUPDATE
;
3528 data
->icld_UpdateMode
= 0;
3529 data
->update_entry
= NULL
;
3534 #if defined(DEBUG_ILC_ICONRENDERING)
3535 D(bug("[IconList] %s#%d: UPDATE_SINGLEENTRY (entry @ 0x%p)\n", __PRETTY_FUNCTION__
, draw_id
, data
->update_entry
));
3537 IconList_GetIconAreaRectangle(obj
, data
, data
->update_entry
, &rect
);
3539 rect
.MinX
+= _mleft(obj
) + (data
->update_entry
->ie_IconX
- data
->icld_ViewX
);
3540 rect
.MaxX
+= _mleft(obj
) + (data
->update_entry
->ie_IconX
- data
->icld_ViewX
);
3541 rect
.MinY
+= _mtop(obj
) + (data
->update_entry
->ie_IconY
- data
->icld_ViewY
);
3542 rect
.MaxY
+= _mtop(obj
) + (data
->update_entry
->ie_IconY
- data
->icld_ViewY
);
3544 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
3546 if (data
->update_entry
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
3548 rect
.MinX
+= ((data
->icld_IconAreaLargestWidth
- data
->update_entry
->ie_AreaWidth
)/2);
3549 rect
.MaxX
+= ((data
->icld_IconAreaLargestWidth
- data
->update_entry
->ie_AreaWidth
)/2);
3552 if (data
->update_entry
->ie_AreaHeight
< data
->icld_IconAreaLargestHeight
)
3554 rect
.MinY
+= ((data
->icld_IconAreaLargestHeight
- data
->update_entry
->ie_AreaHeight
)/2);
3555 rect
.MaxY
+= ((data
->icld_IconAreaLargestHeight
- data
->update_entry
->ie_AreaHeight
)/2);
3559 if (rect
.MinX
< _mleft(obj
)) rect
.MinX
= _mleft(obj
);
3560 if (rect
.MaxX
> _mright(obj
)) rect
.MaxX
=_mright(obj
);
3561 if (rect
.MinY
< _mtop(obj
)) rect
.MinY
= _mtop(obj
);
3562 if (rect
.MaxY
> _mbottom(obj
)) rect
.MaxY
= _mbottom(obj
);
3564 clip
= MUI_AddClipping(muiRenderInfo(obj
), rect
.MinX
, rect
.MinY
, rect
.MaxX
- rect
.MinX
+ 1, rect
.MaxY
- rect
.MinY
+ 1);
3566 #if defined(DEBUG_ILC_ICONRENDERING)
3567 D(bug("[IconList] %s#%d: UPDATE_SINGLEENTRY: Calling MUIM_DrawBackground (A)\n", __PRETTY_FUNCTION__
, draw_id
));
3569 DoMethod(obj
, MUIM_DrawBackground
,
3570 rect
.MinX
, rect
.MinY
,
3571 rect
.MaxX
- rect
.MinX
+ 1, rect
.MaxY
- rect
.MinY
+ 1,
3572 clear_xoffset
, clear_yoffset
,
3575 /* We could have deleted also other icons so they must be redrawn */
3576 #if defined(__AROS__)
3577 ForeachNode(&data
->icld_IconList
, entry
)
3579 Foreach_Node(&data
->icld_IconList
, entry
);
3582 if ((entry
!= data
->update_entry
) && (entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
))
3584 struct Rectangle rect2
;
3585 IconList_GetIconAreaRectangle(obj
, data
, entry
, &rect2
);
3587 rect2
.MinX
+= _mleft(obj
) - data
->icld_ViewX
+ entry
->ie_IconX
;
3588 rect2
.MaxX
+= _mleft(obj
) - data
->icld_ViewX
+ entry
->ie_IconX
;
3589 rect2
.MinY
+= _mtop(obj
) - data
->icld_ViewY
+ entry
->ie_IconY
;
3590 rect2
.MaxY
+= _mtop(obj
) - data
->icld_ViewY
+ entry
->ie_IconY
;
3592 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
3594 if (entry
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
3596 rect2
.MinX
+= ((data
->icld_IconAreaLargestWidth
- entry
->ie_AreaWidth
)/2);
3597 rect2
.MaxX
+= ((data
->icld_IconAreaLargestWidth
- entry
->ie_AreaWidth
)/2);
3600 if (entry
->ie_AreaHeight
< data
->icld_IconAreaLargestHeight
)
3602 rect2
.MinY
+= ((data
->icld_IconAreaLargestHeight
- entry
->ie_AreaHeight
)/2);
3603 rect2
.MaxY
+= ((data
->icld_IconAreaLargestHeight
- entry
->ie_AreaHeight
)/2);
3607 if (RectAndRect(&rect
, &rect2
))
3609 // Update entry here
3610 entry
->ie_Flags
|= ICONENTRY_FLAG_NEEDSUPDATE
;
3611 DoMethod(obj
, MUIM_IconList_DrawEntry
, entry
, ICONENTRY_DRAWMODE_PLAIN
);
3612 DoMethod(obj
, MUIM_IconList_DrawEntryLabel
, entry
, ICONENTRY_DRAWMODE_PLAIN
);
3613 entry
->ie_Flags
&= ~ICONENTRY_FLAG_NEEDSUPDATE
;
3618 entry
->ie_Flags
|= ICONENTRY_FLAG_NEEDSUPDATE
;
3619 DoMethod(obj
, MUIM_IconList_DrawEntry
, data
->update_entry
, ICONENTRY_DRAWMODE_PLAIN
);
3620 DoMethod(obj
, MUIM_IconList_DrawEntryLabel
, data
->update_entry
, ICONENTRY_DRAWMODE_PLAIN
);
3621 entry
->ie_Flags
&= ~ICONENTRY_FLAG_NEEDSUPDATE
;
3622 data
->icld_UpdateMode
= 0;
3623 data
->update_entry
= NULL
;
3625 if (data
->update_entry
== NULL
)
3627 if (data
->icld_DisplayRastPort
!= data
->icld_BufferRastPort
)
3629 #if defined(DEBUG_ILC_ICONRENDERING)
3630 D(bug("[IconList] %s#%d: UPDATE_SINGLEENTRY Blitting to front rastport..\n", __PRETTY_FUNCTION__
, draw_id
));
3632 BltBitMapRastPort(data
->icld_BufferRastPort
->BitMap
,
3633 rect
.MinX
- _mleft(obj
), rect
.MinY
- _mtop(obj
),
3634 data
->icld_DisplayRastPort
,
3635 rect
.MinX
, rect
.MinY
,
3636 rect
.MaxX
- rect
.MinX
+ 1, rect
.MaxY
- rect
.MinY
+ 1,
3639 MUI_RemoveClipping(muiRenderInfo(obj
), clip
);
3643 else if (data
->icld_UpdateMode
== UPDATE_SCROLL
)
3645 struct Region
*region
= NULL
;
3646 struct Rectangle xrect
,
3648 BOOL scroll_caused_damage
= FALSE
;
3650 #if defined(DEBUG_ILC_ICONRENDERING)
3651 D(bug("[IconList] %s#%d: UPDATE_SCROLL.\n", __PRETTY_FUNCTION__
, draw_id
));
3654 if (!data
->icld__Option_IconListFixedBackground
)
3656 scroll_caused_damage
= (_rp(obj
)->Layer
->Flags
& LAYERREFRESH
) ? FALSE
: TRUE
;
3658 data
->icld_UpdateMode
= 0;
3660 if ((abs(data
->update_scrolldx
) >= _mwidth(obj
)) ||
3661 (abs(data
->update_scrolldy
) >= _mheight(obj
)))
3663 #if defined(DEBUG_ILC_ICONRENDERING)
3664 D(bug("[IconList] %s#%d: UPDATE_SCROLL: Moved outside current view -> Causing Redraw .. MADF_DRAWOBJECT\n", __PRETTY_FUNCTION__
, draw_id
));
3666 MUI_Redraw(obj
, MADF_DRAWOBJECT
);
3670 if (!(region
= NewRegion()))
3672 #if defined(DEBUG_ILC_ICONRENDERING)
3673 D(bug("[IconList] %s#%d: UPDATE_SCROLL: Couldnt Alloc Region -> Causing Redraw ...MADF_DRAWOBJECT\n", __PRETTY_FUNCTION__
, draw_id
));
3675 MUI_Redraw(obj
, MADF_DRAWOBJECT
);
3679 if (data
->update_scrolldx
> 0)
3681 xrect
.MinX
= _mright(obj
) - data
->update_scrolldx
;
3682 xrect
.MinY
= _mtop(obj
);
3683 xrect
.MaxX
= _mright(obj
);
3684 xrect
.MaxY
= _mbottom(obj
);
3686 OrRectRegion(region
, &xrect
);
3688 data
->update_rect1
= &xrect
;
3690 else if (data
->update_scrolldx
< 0)
3692 xrect
.MinX
= _mleft(obj
);
3693 xrect
.MinY
= _mtop(obj
);
3694 xrect
.MaxX
= _mleft(obj
) - data
->update_scrolldx
;
3695 xrect
.MaxY
= _mbottom(obj
);
3697 OrRectRegion(region
, &xrect
);
3699 data
->update_rect1
= &xrect
;
3702 if (data
->update_scrolldy
> 0)
3704 yrect
.MinX
= _mleft(obj
);
3705 yrect
.MinY
= _mbottom(obj
) - data
->update_scrolldy
;
3706 if (((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
3707 && (yrect
.MinY
< (_mtop(obj
) + data
->icld_LVMAttribs
->lmva_HeaderHeight
)))
3709 xrect
.MinY
= data
->icld_LVMAttribs
->lmva_HeaderHeight
;
3711 yrect
.MaxX
= _mright(obj
);
3712 yrect
.MaxY
= _mbottom(obj
);
3714 OrRectRegion(region
, &yrect
);
3716 data
->update_rect2
= &yrect
;
3718 else if (data
->update_scrolldy
< 0)
3720 yrect
.MinX
= _mleft(obj
);
3721 yrect
.MinY
= _mtop(obj
);
3722 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
3724 xrect
.MinY
+= data
->icld_LVMAttribs
->lmva_HeaderHeight
;
3726 yrect
.MaxX
= _mright(obj
);
3727 yrect
.MaxY
= _mtop(obj
) - data
->update_scrolldy
;
3729 OrRectRegion(region
, &yrect
);
3731 data
->update_rect2
= &yrect
;
3734 #if defined(DEBUG_ILC_ICONRENDERING)
3735 D(bug("[IconList] %s#%d: UPDATE_SCROLL: Scrolling Raster..\n", __PRETTY_FUNCTION__
, draw_id
));
3737 if (data
->icld_DisplayRastPort
== data
->icld_BufferRastPort
)
3739 ScrollRasterBF(data
->icld_BufferRastPort
,
3740 data
->update_scrolldx
,
3741 data
->update_scrolldy
,
3749 ScrollRasterBF(data
->icld_BufferRastPort
,
3750 data
->update_scrolldx
,
3751 data
->update_scrolldy
,
3758 scroll_caused_damage
= scroll_caused_damage
&& (_rp(obj
)->Layer
->Flags
& LAYERREFRESH
) ? TRUE
: FALSE
;
3760 clip
= MUI_AddClipRegion(muiRenderInfo(obj
), region
);
3763 #if defined(DEBUG_ILC_ICONRENDERING)
3764 D(bug("[IconList] %s#%d: UPDATE_SCROLL: Causing Redraw -> MADF_DRAWOBJECT..\n", __PRETTY_FUNCTION__
, draw_id
));
3766 MUI_Redraw(obj
, MADF_DRAWOBJECT
);
3768 data
->update_rect1
= data
->update_rect2
= NULL
;
3770 if (!data
->icld__Option_IconListFixedBackground
)
3772 MUI_RemoveClipRegion(muiRenderInfo(obj
), clip
);
3774 if (scroll_caused_damage
)
3776 if (MUI_BeginRefresh(muiRenderInfo(obj
), 0))
3778 /* Theoretically it might happen that more damage is caused
3779 after ScrollRaster. By something else, like window movement
3780 in front of our window. Therefore refresh root object of
3781 window, not just this object */
3785 GET(_win(obj
),MUIA_Window_RootObject
, &o
);
3786 MUI_Redraw(o
, MADF_DRAWOBJECT
);
3787 #if defined(DEBUG_ILC_ICONRENDERING)
3788 D(bug("[IconList] %s#%d: UPDATE_SCROLL: Causing Redraw -> MADF_DRAWOBJECT..\n", __PRETTY_FUNCTION__
, draw_id
));
3790 MUI_EndRefresh(muiRenderInfo(obj
), 0);
3794 if (data
->icld_DisplayRastPort
!= data
->icld_BufferRastPort
)
3796 #if defined(DEBUG_ILC_ICONRENDERING)
3797 D(bug("[IconList] %s#%d: UPDATE_SCROLL: Blitting to front rastport..\n", __PRETTY_FUNCTION__
, draw_id
));
3799 BltBitMapRastPort(data
->icld_BufferRastPort
->BitMap
,
3801 data
->icld_DisplayRastPort
,
3802 _mleft(obj
), _mtop(obj
),
3803 _mwidth(obj
), _mheight(obj
),
3808 else if (data
->icld_UpdateMode
== UPDATE_RESIZE
)
3810 struct Region
*region
= NULL
;
3811 struct Rectangle wrect
,
3816 #if defined(DEBUG_ILC_ICONRENDERING)
3817 D(bug("[IconList] %s#%d: UPDATE_RESIZE.\n", __PRETTY_FUNCTION__
, draw_id
));
3820 if ((data
->icld_BufferRastPort
) && (data
->icld_BufferRastPort
!= data
->icld_DisplayRastPort
))
3822 //Free up the buffers Layer, rastport and bitmap so we can replace them ..
3823 if ((GetBitMapAttr(data
->icld_BufferRastPort
->BitMap
, BMA_WIDTH
) != data
->icld_ViewWidth
)
3824 || (GetBitMapAttr(data
->icld_BufferRastPort
->BitMap
, BMA_HEIGHT
) != data
->icld_ViewHeight
))
3826 struct Layer
*oldLayer
= data
->icld_BufferRastPort
->Layer
;
3827 #if defined(DEBUG_ILC_ATTRIBS) || defined(DEBUG_ILC_ICONRENDERING)
3828 D(bug("[IconList] %s: Destroying old BackLayer\n", __PRETTY_FUNCTION__
));
3830 data
->icld_BufferRastPort
= data
->icld_DisplayRastPort
;
3831 DeleteLayer(0, oldLayer
);
3834 if (data
->icld_BufferRastPort
== data
->icld_DisplayRastPort
)
3836 struct BitMap
*bitmap_New
;
3837 ULONG tmp_RastDepth
;
3838 struct Layer_Info
*li
= NULL
;
3840 tmp_RastDepth
= GetCyberMapAttr(data
->icld_DisplayRastPort
->BitMap
, CYBRMATTR_DEPTH
);
3841 if ((bitmap_New
= AllocBitMap(data
->icld_ViewWidth
,
3842 data
->icld_ViewHeight
,
3845 data
->icld_DisplayRastPort
->BitMap
)) != NULL
)
3847 if ((data
->icld_BufferRastPort
= CreateRastPort()) != NULL
)
3849 data
->icld_BufferRastPort
->BitMap
= bitmap_New
;
3850 if ((li
= NewLayerInfo()))
3852 if ((data
->icld_BufferRastPort
->Layer
= CreateUpfrontLayer(li
, data
->icld_BufferRastPort
->BitMap
, 0, 0, data
->icld_ViewWidth
- 1, data
->icld_ViewHeight
- 1, 0, NULL
)))
3855 * Mark it as a buffered rastport.
3858 #if defined(DEBUG_ILC_ATTRIBS) || defined(DEBUG_ILC_ICONRENDERING)
3859 D(bug("[IconList] %s: FrontRastPort @ %p, New BackLayer @ %p, BackRastport @ %p\n", __PRETTY_FUNCTION__
, data
->icld_DisplayRastPort
, data
->icld_BufferRastPort
->Layer
, data
->icld_BufferRastPort
));
3861 SET(obj
, MUIA_IconList_BufferRastport
, data
->icld_BufferRastPort
);
3862 data
->icld_DrawOffsetX
= 0;
3863 data
->icld_DrawOffsetY
= 0;
3866 data
->icld_BufferRastPort
= data
->icld_DisplayRastPort
;
3869 data
->icld_BufferRastPort
= data
->icld_DisplayRastPort
;
3872 data
->icld_BufferRastPort
= data
->icld_DisplayRastPort
;
3875 if (data
->icld_BufferRastPort
== data
->icld_DisplayRastPort
)
3877 if (bitmap_New
) FreeBitMap(bitmap_New
);
3878 if (li
) DisposeLayerInfo(li
);
3879 data
->icld_DrawOffsetX
= _mleft(obj
);
3880 data
->icld_DrawOffsetY
= _mtop(obj
);
3885 data
->icld_UpdateMode
= 0;
3887 if (!data
->icld__Option_IconListScaledBackground
)
3889 if (!(region
= NewRegion()))
3891 #if defined(DEBUG_ILC_ICONRENDERING)
3892 D(bug("[IconList] %s#%d: UPDATE_RESIZE: Causing Redraw -> MADF_DRAWOBJECT..\n", __PRETTY_FUNCTION__
, draw_id
));
3894 MUI_Redraw(obj
, MADF_DRAWOBJECT
);
3898 if ( data
->icld_ViewWidth
> update_oldwidth
)
3899 diffw
= data
->icld_ViewWidth
- update_oldwidth
;
3900 if ( data
->icld_ViewHeight
> update_oldheight
)
3901 diffh
= data
->icld_ViewHeight
- update_oldheight
;
3905 wrect
.MinX
= _mright(obj
) - diffw
;
3906 wrect
.MinY
= _mtop(obj
);
3907 wrect
.MaxX
= _mright(obj
);
3908 wrect
.MaxY
= _mbottom(obj
);
3909 OrRectRegion(region
, &wrect
);
3910 data
->update_rect1
= &wrect
;
3915 hrect
.MinX
= _mleft(obj
);
3916 hrect
.MinY
= _mbottom(obj
) - diffh
;
3917 hrect
.MaxX
= _mright(obj
);
3918 hrect
.MaxX
= _mright(obj
);
3919 hrect
.MaxY
= _mbottom(obj
);
3920 OrRectRegion(region
, &hrect
);
3921 data
->update_rect2
= &hrect
;
3925 clip
= MUI_AddClipRegion(muiRenderInfo(obj
), region
);
3929 /* View became smaller both in horizontal and vertical direction.
3932 DisposeRegion(region
);
3937 #if defined(DEBUG_ILC_ICONRENDERING)
3938 D(bug("[IconList] %s#%d: UPDATE_RESIZE: Causing Redraw -> MADF_DRAWOBJECT..\n", __PRETTY_FUNCTION__
, draw_id
));
3940 MUI_Redraw(obj
, MADF_DRAWOBJECT
);
3942 if (!data
->icld__Option_IconListScaledBackground
)
3946 data
->update_rect1
= data
->update_rect2
= NULL
;
3947 MUI_RemoveClipRegion(muiRenderInfo(obj
), clip
);
3948 } else DisposeRegion(region
);
3955 if (message
->flags
& MADF_DRAWOBJECT
)
3957 struct Rectangle viewrect
;
3958 int current
= 0, first
= 0, visible
= 0;
3960 #if defined(DEBUG_ILC_ICONRENDERING)
3961 D(bug("[IconList] %s#%d: MADF_DRAWOBJECT\n", __PRETTY_FUNCTION__
, draw_id
));
3964 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
3966 clip
= MUI_AddClipping(muiRenderInfo(obj
), _mleft(obj
), _mtop(obj
), _mwidth(obj
), data
->icld_LVMAttribs
->lmva_HeaderHeight
);
3967 RenderListViewModeHeader(obj
, data
);
3969 if (data
->icld_DisplayRastPort
!= data
->icld_BufferRastPort
)
3971 #if defined(DEBUG_ILC_ICONRENDERING)
3972 D(bug("[IconList] %s#%d: MADF_DRAWOBJECT Blitting Header to front rastport..\n", __PRETTY_FUNCTION__
, draw_id
));
3974 BltBitMapRastPort(data
->icld_BufferRastPort
->BitMap
,
3976 data
->icld_DisplayRastPort
,
3977 _mleft(obj
), _mtop(obj
), _mwidth(obj
), data
->icld_LVMAttribs
->lmva_HeaderHeight
,
3981 MUI_RemoveClipping(muiRenderInfo(obj
), clip
);
3983 viewrect
.MinY
= _mtop(obj
) + data
->icld_LVMAttribs
->lmva_HeaderHeight
;
3985 first
= FirstVisibleLine(data
);
3986 visible
= NumVisibleLines(data
);
3988 clip
= MUI_AddClipping(muiRenderInfo(obj
), _mleft(obj
), _mtop(obj
) + data
->icld_LVMAttribs
->lmva_HeaderHeight
, _mwidth(obj
), _mheight(obj
) - data
->icld_LVMAttribs
->lmva_HeaderHeight
);
3992 viewrect
.MinY
= _mtop(obj
);
3993 clip
= MUI_AddClipping(muiRenderInfo(obj
), _mleft(obj
), _mtop(obj
), _mwidth(obj
), _mheight(obj
));
3996 viewrect
.MaxY
= _mtop(obj
) + _mheight(obj
) - 1;
3997 viewrect
.MinX
= _mleft(obj
);
3998 viewrect
.MaxX
= _mleft(obj
) + _mwidth(obj
) - 1;
4000 #if defined(DEBUG_ILC_ICONRENDERING)
4001 D(bug("[IconList] %s#%d: MADF_DRAWOBJECT: Calling MUIM_DrawBackground (B)\n", __PRETTY_FUNCTION__
, draw_id
));
4004 obj
, MUIM_DrawBackground
, viewrect
.MinX
, viewrect
.MinY
, (viewrect
.MaxX
- viewrect
.MinX
) + 1, (viewrect
.MaxY
- viewrect
.MinY
) + 1,
4005 clear_xoffset
, clear_yoffset
, 0
4007 #if defined(__AROS__)
4008 ForeachNode(&data
->icld_IconList
, entry
)
4010 Foreach_Node(&data
->icld_IconList
, entry
);
4013 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
4015 if (entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
4017 if ((current
>= first
) && (current
<= (first
+ visible
)))
4019 DoMethod(obj
, MUIM_IconList_DrawEntry
, entry
, current
);
4026 if ((entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
) &&
4027 (entry
->ie_DiskObj
) &&
4028 (entry
->ie_IconX
!= NO_ICON_POSITION
) &&
4029 (entry
->ie_IconY
!= NO_ICON_POSITION
))
4031 struct Rectangle iconrect
;
4032 IconList_GetIconAreaRectangle(obj
, data
, entry
, &iconrect
);
4034 iconrect
.MinX
+= viewrect
.MinX
- data
->icld_ViewX
+ entry
->ie_IconX
;
4035 iconrect
.MaxX
+= viewrect
.MinX
- data
->icld_ViewX
+ entry
->ie_IconX
;
4036 iconrect
.MinY
+= viewrect
.MinY
- data
->icld_ViewY
+ entry
->ie_IconY
;
4037 iconrect
.MaxY
+= viewrect
.MinY
- data
->icld_ViewY
+ entry
->ie_IconY
;
4039 if (RectAndRect(&viewrect
, &iconrect
))
4041 DoMethod(obj
, MUIM_IconList_DrawEntry
, entry
, ICONENTRY_DRAWMODE_PLAIN
);
4042 DoMethod(obj
, MUIM_IconList_DrawEntryLabel
, entry
, ICONENTRY_DRAWMODE_PLAIN
);
4048 if (data
->icld_DisplayRastPort
!= data
->icld_BufferRastPort
)
4050 #if defined(DEBUG_ILC_ICONRENDERING)
4051 D(bug("[IconList] %s#%d: MADF_DRAWOBJECT: Blitting to front rastport..\n", __PRETTY_FUNCTION__
, draw_id
));
4053 BltBitMapRastPort(data
->icld_BufferRastPort
->BitMap
,
4055 data
->icld_DisplayRastPort
,
4056 _mleft(obj
), _mtop(obj
),
4057 _mwidth(obj
), _mheight(obj
),
4061 MUI_RemoveClipping(muiRenderInfo(obj
), clip
);
4063 data
->icld_UpdateMode
= 0;
4067 #if defined(DEBUG_ILC_ICONRENDERING)
4068 D(bug("[IconList] %s: Draw finished for id %d\n", __PRETTY_FUNCTION__
, draw_id
));
4074 ///IconList__MUIM_IconList_Update()
4075 /**************************************************************************
4076 MUIM_IconList_Refresh
4077 Implemented by subclasses
4078 **************************************************************************/
4079 IPTR
IconList__MUIM_IconList_Update(struct IClass
*CLASS
, Object
*obj
, struct MUIP_IconList_Update
*message
)
4081 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
4083 #if defined(DEBUG_ILC_FUNCS)
4084 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
4087 data
->icld_FocusIcon
= NULL
;
4088 SET(obj
, MUIA_IconList_Changed
, TRUE
);
4094 ///MUIM_IconList_Clear()
4095 /**************************************************************************
4097 **************************************************************************/
4098 IPTR
IconList__MUIM_IconList_Clear(struct IClass
*CLASS
, Object
*obj
, struct MUIP_IconList_Clear
*message
)
4100 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
4101 struct IconEntry
*node
= NULL
;
4103 #if defined(DEBUG_ILC_FUNCS)
4104 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
4107 while ((node
= (struct IconEntry
*)RemTail((struct List
*)&data
->icld_IconList
)))
4109 DoMethod(obj
, MUIM_IconList_DestroyEntry
, node
);
4112 data
->icld_SelectionLastClicked
= NULL
;
4113 data
->icld_FocusIcon
= NULL
;
4115 data
->icld_ViewX
= data
->icld_ViewY
= data
->icld_AreaWidth
= data
->icld_AreaHeight
= 0;
4116 data
->icld_IconAreaLargestWidth
= 0;
4117 data
->icld_IconAreaLargestHeight
= 0;
4118 data
->icld_IconLargestHeight
= 0;
4119 data
->icld_LabelLargestHeight
= 0;
4121 #if defined(DEBUG_ILC_ICONRENDERING)
4122 D(bug("[IconList]: %s: call SetSuperAttrs()\n", __PRETTY_FUNCTION__
));
4124 SetSuperAttrs(CLASS
, obj
, MUIA_Virtgroup_Left
, data
->icld_ViewX
,
4125 MUIA_Virtgroup_Top
, data
->icld_ViewY
,
4128 #if defined(DEBUG_ILC_ICONRENDERING)
4129 D(bug("[IconList]: %s: call SetAttrs()\n", __PRETTY_FUNCTION__
));
4131 SetAttrs(obj
, MUIA_Virtgroup_Left
, data
->icld_ViewX
,
4132 MUIA_Virtgroup_Top
, data
->icld_ViewY
,
4135 #if defined(DEBUG_ILC_ICONRENDERING)
4136 D(bug("[IconList]: %s: Set MUIA_IconList_Width and MUIA_IconList_Height\n", __PRETTY_FUNCTION__
));
4138 SetAttrs(obj
, MUIA_IconList_Width
, data
->icld_AreaWidth
,
4139 MUIA_IconList_Height
, data
->icld_AreaHeight
,
4142 D(bug("[IconList]: %s: call MUI_Redraw()\n", __PRETTY_FUNCTION__
));
4143 MUI_Redraw(obj
,MADF_DRAWOBJECT
);
4148 ///IconList__MUIM_IconList_DestroyEntry()
4149 IPTR
IconList__MUIM_IconList_DestroyEntry(struct IClass
*CLASS
, Object
*obj
, struct MUIP_IconList_DestroyEntry
*message
)
4151 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
4153 #if defined(DEBUG_ILC_FUNCS)
4154 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
4159 if (message
->entry
->ie_Flags
& ICONENTRY_FLAG_SELECTED
)
4161 if (data
->icld_SelectionLastClicked
== message
->entry
)
4163 struct IconList_Entry
*nextentry
= &message
->entry
->ie_IconListEntry
;
4165 /* get selected entries from SOURCE iconlist */
4166 DoMethod(obj
, MUIM_IconList_NextIcon
, MUIV_IconList_NextIcon_Selected
, (IPTR
)&nextentry
);
4167 if ((nextentry
) && ((IPTR
)nextentry
!= MUIV_IconList_NextIcon_End
))
4168 data
->icld_SelectionLastClicked
= (struct IconEntry
*)((IPTR
)nextentry
- ((IPTR
)&message
->entry
->ie_IconListEntry
- (IPTR
)message
->entry
));
4170 data
->icld_SelectionLastClicked
= NULL
;
4172 if (data
->icld_FocusIcon
== message
->entry
)
4173 data
->icld_FocusIcon
= data
->icld_SelectionLastClicked
;
4175 Remove(&message
->entry
->ie_SelectionNode
);
4178 if (message
->entry
->ie_TxtBuf_DisplayedLabel
)
4179 FreeVecPooled(data
->icld_Pool
, message
->entry
->ie_TxtBuf_DisplayedLabel
);
4181 if (message
->entry
->ie_TxtBuf_PROT
)
4182 FreePooled(data
->icld_Pool
, message
->entry
->ie_TxtBuf_PROT
, 8);
4184 if (message
->entry
->ie_TxtBuf_SIZE
)
4185 FreePooled(data
->icld_Pool
, message
->entry
->ie_TxtBuf_SIZE
, 30);
4187 if (message
->entry
->ie_TxtBuf_TIME
)
4188 FreePooled(data
->icld_Pool
, message
->entry
->ie_TxtBuf_TIME
, LEN_DATSTRING
);
4190 if (message
->entry
->ie_TxtBuf_DATE
)
4191 FreePooled(data
->icld_Pool
, message
->entry
->ie_TxtBuf_DATE
, LEN_DATSTRING
);
4193 if (message
->entry
->ie_DiskObj
)
4194 FreeDiskObject(message
->entry
->ie_DiskObj
);
4196 if (message
->entry
->ie_FileInfoBlock
)
4197 FreeMem(message
->entry
->ie_FileInfoBlock
, sizeof(struct FileInfoBlock
));
4199 if (message
->entry
->ie_IconListEntry
.label
)
4200 FreePooled(data
->icld_Pool
, message
->entry
->ie_IconListEntry
.label
, strlen(message
->entry
->ie_IconListEntry
.label
)+1);
4202 if (message
->entry
->ie_IconNode
.ln_Name
)
4203 FreePooled(data
->icld_Pool
, message
->entry
->ie_IconNode
.ln_Name
, strlen(message
->entry
->ie_IconNode
.ln_Name
)+1);
4205 FreePooled(data
->icld_Pool
, message
->entry
, sizeof(struct IconEntry
));
4211 ///IconList__MUIM_IconList_PropagateEntryPos()
4212 IPTR
IconList__MUIM_IconList_PropagateEntryPos(struct IClass
*CLASS
, Object
*obj
,
4213 struct MUIP_IconList_PropagateEntryPos
*message
)
4215 message
->entry
->ie_ProvidedIconX
= message
->entry
->ie_IconX
;
4216 message
->entry
->ie_ProvidedIconY
= message
->entry
->ie_IconY
;
4222 ///IconList__MUIM_IconList_CreateEntry()
4223 /**************************************************************************
4224 MUIM_IconList_CreateEntry.
4225 Returns 0 on failure otherwise it returns the icons entry ..
4226 **************************************************************************/
4227 IPTR
IconList__MUIM_IconList_CreateEntry(struct IClass
*CLASS
, Object
*obj
, struct MUIP_IconList_CreateEntry
*message
)
4229 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
4230 struct IconEntry
*entry
= NULL
;
4232 struct DateStamp now
;
4235 struct DiskObject
*dob
= NULL
;
4236 struct Rectangle rect
;
4238 IPTR geticon_error
= 0;
4240 #if defined(DEBUG_ILC_FUNCS)
4241 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
4244 /*disk object (icon)*/
4245 if (message
->entry_dob
== NULL
)
4247 IPTR iconlistScreen
= (IPTR
)_screen(obj
);
4248 D(bug("[IconList] %s: IconList Screen @ 0x%p)\n", __PRETTY_FUNCTION__
, iconlistScreen
));
4253 (iconlistScreen
) ? ICONGETA_Screen
: TAG_IGNORE
, iconlistScreen
,
4254 (iconlistScreen
) ? ICONGETA_RemapIcon
: TAG_IGNORE
, TRUE
,
4255 ICONGETA_FailIfUnavailable
, FALSE
,
4256 ICONGETA_GenerateImageMasks
, TRUE
,
4257 ICONA_ErrorCode
, &geticon_error
,
4263 D(bug("[IconList] %s: Fatal: Couldnt get DiskObject! (error code = 0x%p)\n", __PRETTY_FUNCTION__
, geticon_error
));
4270 dob
= message
->entry_dob
;
4273 D(bug("[IconList] %s: DiskObject @ 0x%p\n", __PRETTY_FUNCTION__
, dob
));
4275 if ((entry
= AllocPooled(data
->icld_Pool
, sizeof(struct IconEntry
))) == NULL
)
4277 D(bug("[IconList] %s: Failed to Allocate Entry Storage!\n", __PRETTY_FUNCTION__
));
4278 FreeDiskObject(dob
);
4281 memset(entry
, 0, sizeof(struct IconEntry
));
4282 entry
->ie_Flags
|= ICONENTRY_FLAG_NEEDSUPDATE
;
4283 entry
->ie_IconListEntry
.ile_IconEntry
= entry
;
4285 /* Allocate Text Buffers */
4287 if ((entry
->ie_TxtBuf_DATE
= AllocPooled(data
->icld_Pool
, LEN_DATSTRING
)) == NULL
)
4289 D(bug("[IconList] %s: Failed to Allocate Entry DATE Storage!\n", __PRETTY_FUNCTION__
));
4290 DoMethod(obj
, MUIM_IconList_DestroyEntry
, entry
);
4293 memset(entry
->ie_TxtBuf_DATE
, 0, LEN_DATSTRING
);
4295 if ((entry
->ie_TxtBuf_TIME
= AllocPooled(data
->icld_Pool
, LEN_DATSTRING
)) == NULL
)
4297 D(bug("[IconList] %s: Failed to Allocate Entry TIME string Storage!\n", __PRETTY_FUNCTION__
));
4298 DoMethod(obj
, MUIM_IconList_DestroyEntry
, entry
);
4301 memset(entry
->ie_TxtBuf_TIME
, 0, LEN_DATSTRING
);
4303 if ((entry
->ie_TxtBuf_SIZE
= AllocPooled(data
->icld_Pool
, 30)) == NULL
)
4305 D(bug("[IconList] %s: Failed to Allocate Entry SIZE string Storage!\n", __PRETTY_FUNCTION__
));
4306 DoMethod(obj
, MUIM_IconList_DestroyEntry
, entry
);
4309 memset(entry
->ie_TxtBuf_SIZE
, 0, 30);
4311 if ((entry
->ie_TxtBuf_PROT
= AllocPooled(data
->icld_Pool
, 8)) == NULL
)
4313 D(bug("[IconList] %s: Failed to Allocate Entry PROT Flag string Storage!\n", __PRETTY_FUNCTION__
));
4314 DoMethod(obj
, MUIM_IconList_DestroyEntry
, entry
);
4317 memset(entry
->ie_TxtBuf_PROT
, 0, 8);
4320 if ((entry
->ie_IconNode
.ln_Name
= AllocPooled(data
->icld_Pool
, strlen(message
->filename
) + 1)) == NULL
)
4322 D(bug("[IconList] %s: Failed to Allocate Entry filename string Storage!\n", __PRETTY_FUNCTION__
));
4323 DoMethod(obj
, MUIM_IconList_DestroyEntry
, entry
);
4327 /*alloc entry label*/
4328 if ((entry
->ie_IconListEntry
.label
= AllocPooled(data
->icld_Pool
, strlen(message
->label
) + 1)) == NULL
)
4330 D(bug("[IconList] %s: Failed to Allocate Entry label string Storage!\n", __PRETTY_FUNCTION__
));
4331 DoMethod(obj
, MUIM_IconList_DestroyEntry
, entry
);
4336 if(message
->fib
!= NULL
)
4338 if ((entry
->ie_FileInfoBlock
= AllocMem(sizeof(struct FileInfoBlock
), MEMF_CLEAR
)) != NULL
)
4340 CopyMem(message
->fib
, entry
->ie_FileInfoBlock
, sizeof(struct FileInfoBlock
));
4342 if (entry
->ie_FileInfoBlock
->fib_DirEntryType
> 0)
4344 strcpy(entry
->ie_TxtBuf_SIZE
, "Drawer");
4348 FmtSizeToString(entry
->ie_TxtBuf_SIZE
, entry
->ie_FileInfoBlock
->fib_Size
);
4351 dt
.dat_Stamp
= entry
->ie_FileInfoBlock
->fib_Date
;
4352 dt
.dat_Format
= FORMAT_DEF
;
4354 dt
.dat_StrDay
= NULL
;
4355 dt
.dat_StrDate
= entry
->ie_TxtBuf_DATE
;
4356 dt
.dat_StrTime
= entry
->ie_TxtBuf_TIME
;
4361 /*if modified today show time, otherwise just show date*/
4362 if (now
.ds_Days
== entry
->ie_FileInfoBlock
->fib_Date
.ds_Days
)
4363 entry
->ie_Flags
|= ICONENTRY_FLAG_TODAY
;
4365 entry
->ie_Flags
&= ~ICONENTRY_FLAG_TODAY
;
4367 sp
= entry
->ie_TxtBuf_PROT
;
4368 *sp
++ = (entry
->ie_FileInfoBlock
->fib_Protection
& FIBF_SCRIPT
) ? 's' : '-';
4369 *sp
++ = (entry
->ie_FileInfoBlock
->fib_Protection
& FIBF_PURE
) ? 'p' : '-';
4370 *sp
++ = (entry
->ie_FileInfoBlock
->fib_Protection
& FIBF_ARCHIVE
) ? 'a' : '-';
4371 *sp
++ = (entry
->ie_FileInfoBlock
->fib_Protection
& FIBF_READ
) ? '-' : 'r';
4372 *sp
++ = (entry
->ie_FileInfoBlock
->fib_Protection
& FIBF_WRITE
) ? '-' : 'w';
4373 *sp
++ = (entry
->ie_FileInfoBlock
->fib_Protection
& FIBF_EXECUTE
) ? '-' : 'e';
4374 *sp
++ = (entry
->ie_FileInfoBlock
->fib_Protection
& FIBF_DELETE
) ? '-' : 'd';
4377 entry
->ie_IconListEntry
.type
= entry
->ie_FileInfoBlock
->fib_DirEntryType
;
4382 entry
->ie_IconListEntry
.type
= ST_USERDIR
;
4385 /* Override type if specified during createntry */
4386 if (message
->type
!= 0)
4388 entry
->ie_IconListEntry
.type
= message
->type
;
4389 D(bug("[IconList] %s: Overide Entry Type. New Type = %x\n", __PRETTY_FUNCTION__
, entry
->ie_IconListEntry
.type
));
4393 D(bug("[IconList] %s: Entry Type = %x\n", __PRETTY_FUNCTION__
, entry
->ie_IconListEntry
.type
));
4396 strcpy(entry
->ie_IconNode
.ln_Name
, message
->filename
);
4397 strcpy(entry
->ie_IconListEntry
.label
, message
->label
);
4399 entry
->ie_IconListEntry
.udata
= NULL
;
4401 entry
->ie_IconX
= dob
->do_CurrentX
;
4402 entry
->ie_IconY
= dob
->do_CurrentY
;
4404 DoMethod(obj
, MUIM_IconList_PropagateEntryPos
, entry
);
4406 if (IconList__LabelFunc_CreateLabel(obj
, data
, entry
) != (IPTR
)NULL
)
4408 entry
->ie_DiskObj
= dob
;
4410 /* Use a geticonrectangle routine that gets textwidth! */
4411 IconList_GetIconAreaRectangle(obj
, data
, entry
, &rect
);
4416 DoMethod(obj
, MUIM_IconList_DestroyEntry
, entry
);
4421 ///IconList__MUIM_IconList_UpdateEntry()
4422 /**************************************************************************
4423 MUIM_IconList_UpdateEntry.
4424 Returns 0 on failure otherwise it returns the icons entry ..
4425 **************************************************************************/
4426 IPTR
IconList__MUIM_IconList_UpdateEntry(struct IClass
*CLASS
, Object
*obj
, struct MUIP_IconList_UpdateEntry
*message
)
4428 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
4429 // struct DateTime dt;
4430 // struct DateStamp now;
4431 // UBYTE *sp = NULL;
4433 // struct DiskObject *dob = NULL;
4434 struct Rectangle rect
;
4436 // IPTR geticon_error = 0;
4438 #if defined(DEBUG_ILC_FUNCS)
4439 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
4442 /* Update disk object (icon)*/
4443 /* if (message->entry_dob == NULL)
4445 IPTR iconlistScreen = _screen(obj);
4446 D(bug("[IconList] %s: IconList Screen @ 0x%p)\n", __PRETTY_FUNCTION__, iconlistScreen));
4451 (iconlistScreen) ? ICONGETA_Screen : TAG_IGNORE, iconlistScreen,
4452 (iconlistScreen) ? ICONGETA_RemapIcon : TAG_IGNORE, TRUE,
4453 ICONGETA_FailIfUnavailable, FALSE,
4454 ICONGETA_GenerateImageMasks, TRUE,
4455 ICONA_ErrorCode, &geticon_error,
4461 D(bug("[IconList] %s: Fatal: Couldnt get DiskObject! (error code = 0x%p)\n", __PRETTY_FUNCTION__, geticon_error));
4468 dob = message->entry_dob;
4471 D(bug("[IconList] %s: DiskObject @ 0x%p\n", __PRETTY_FUNCTION__, dob));
4474 /* Update filename */
4475 if (strcmp(message
->entry
->ie_IconNode
.ln_Name
, message
->filename
) != 0)
4477 message
->entry
->ie_Flags
|= ICONENTRY_FLAG_NEEDSUPDATE
;
4478 FreePooled(data
->icld_Pool
, message
->entry
->ie_IconNode
.ln_Name
, strlen(message
->entry
->ie_IconNode
.ln_Name
) + 1);
4479 if ((message
->entry
->ie_IconNode
.ln_Name
= AllocPooled(data
->icld_Pool
, strlen(message
->filename
) + 1)) == NULL
)
4481 D(bug("[IconList] %s: Failed to Allocate Entry filename string Storage!\n", __PRETTY_FUNCTION__
));
4482 DoMethod(obj
, MUIM_IconList_DestroyEntry
, message
->entry
);
4485 strcpy(message
->entry
->ie_IconNode
.ln_Name
, message
->filename
);
4488 /* Update entry label */
4489 if (strcmp(message
->entry
->ie_IconListEntry
.label
, message
->label
) != 0)
4491 message
->entry
->ie_Flags
|= ICONENTRY_FLAG_NEEDSUPDATE
;
4492 FreePooled(data
->icld_Pool
, message
->entry
->ie_IconListEntry
.label
, strlen(message
->entry
->ie_IconListEntry
.label
) + 1);
4493 if ((message
->entry
->ie_IconListEntry
.label
= AllocPooled(data
->icld_Pool
, strlen(message
->label
) + 1)) == NULL
)
4495 D(bug("[IconList] %s: Failed to Allocate Entry label string Storage!\n", __PRETTY_FUNCTION__
));
4496 DoMethod(obj
, MUIM_IconList_DestroyEntry
, message
->entry
);
4499 strcpy(message
->entry
->ie_IconListEntry
.label
, message
->label
);
4500 if (IconList__LabelFunc_CreateLabel(obj
, data
, message
->entry
) == (IPTR
)NULL
)
4502 D(bug("[IconList] %s: Failed to create label\n", __PRETTY_FUNCTION__
));
4503 DoMethod(obj
, MUIM_IconList_DestroyEntry
, message
->entry
);
4508 /* Update file info block */
4509 if(message
->fib
!= NULL
)
4511 if (!(message
->entry
->ie_FileInfoBlock
))
4513 if ((message
->entry
->ie_FileInfoBlock
= AllocMem(sizeof(struct FileInfoBlock
), MEMF_CLEAR
)) != NULL
)
4515 CopyMem(message
->fib
, message
->entry
->ie_FileInfoBlock
, sizeof(struct FileInfoBlock
));
4519 /* if (entry->ie_FileInfoBlock->fib_DirEntryType > 0)
4521 strcpy(entry->ie_TxtBuf_SIZE, "Drawer");
4525 FmtSizeToString(entry->ie_TxtBuf_SIZE, entry->ie_FileInfoBlock->fib_Size);
4528 dt.dat_Stamp = entry->ie_FileInfoBlock->fib_Date;
4529 dt.dat_Format = FORMAT_DEF;
4531 dt.dat_StrDay = NULL;
4532 dt.dat_StrDate = entry->ie_TxtBuf_DATE;
4533 dt.dat_StrTime = entry->ie_TxtBuf_TIME;
4538 //if modified today show time, otherwise just show date
4539 if (now.ds_Days == entry->ie_FileInfoBlock->fib_Date.ds_Days)
4540 entry->ie_Flags |= ICONENTRY_FLAG_TODAY;
4542 entry->ie_Flags &= ~ICONENTRY_FLAG_TODAY;
4544 sp = entry->ie_TxtBuf_PROT;
4545 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_SCRIPT) ? 's' : '-';
4546 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_PURE) ? 'p' : '-';
4547 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_ARCHIVE) ? 'a' : '-';
4548 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_READ) ? '-' : 'r';
4549 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_WRITE) ? '-' : 'w';
4550 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_EXECUTE) ? '-' : 'e';
4551 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_DELETE) ? '-' : 'd';
4554 entry->ie_IconListEntry.type = entry->ie_FileInfoBlock->fib_DirEntryType;
4559 if (message
->entry
->ie_FileInfoBlock
)
4560 FreeMem(message
->entry
->ie_FileInfoBlock
, sizeof(struct FileInfoBlock
));
4562 if (message
->entry
->ie_IconListEntry
.type
!= ST_USERDIR
)
4564 message
->entry
->ie_Flags
|= ICONENTRY_FLAG_NEEDSUPDATE
;
4565 message
->entry
->ie_IconListEntry
.type
= ST_USERDIR
;
4569 /* Override type if specified */
4570 if ((message
->type
!= 0) && (message
->entry
->ie_IconListEntry
.type
!= message
->type
))
4572 message
->entry
->ie_Flags
|= ICONENTRY_FLAG_NEEDSUPDATE
;
4573 message
->entry
->ie_IconListEntry
.type
= message
->type
;
4574 D(bug("[IconList] %s: Overide Entry Type. New Type = %x\n", __PRETTY_FUNCTION__
, message
->entry
->ie_IconListEntry
.type
));
4578 D(bug("[IconList] %s: Entry Type = %x\n", __PRETTY_FUNCTION__
, message
->entry
->ie_IconListEntry
.type
));
4581 IconList_GetIconAreaRectangle(obj
, data
, message
->entry
, &rect
);
4583 return (IPTR
)message
->entry
;
4588 static void DoWheelMove(struct IClass
*CLASS
, Object
*obj
, LONG wheelx
, LONG wheely
, UWORD qual
)
4590 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
4592 LONG newleft
= data
->icld_ViewX
,
4593 newtop
= data
->icld_ViewY
;
4595 /* Use horizontal scrolling if any of the following cases are true ...
4597 # vertical wheel is used but there's nothing to scroll
4598 (everything is visible already) ..
4600 # vertical wheel is used and one of the ALT keys is down. */
4602 if ((wheely
&& !wheelx
) &&
4603 ((data
->icld_AreaHeight
<= _mheight(obj
)) || (qual
& (IEQUALIFIER_LALT
| IEQUALIFIER_RALT
))))
4605 wheelx
= wheely
; wheely
= 0;
4608 if (qual
& (IEQUALIFIER_CONTROL
))
4610 if (wheelx
< 0) newleft
= 0;
4611 if (wheelx
> 0) newleft
= data
->icld_AreaWidth
;
4612 if (wheely
< 0) newtop
= 0;
4613 if (wheely
> 0) newtop
= data
->icld_AreaHeight
;
4615 else if (qual
& (IEQUALIFIER_LSHIFT
| IEQUALIFIER_RSHIFT
))
4617 newleft
+= (wheelx
* _mwidth(obj
));
4618 newtop
+= (wheely
* _mheight(obj
));
4622 newleft
+= wheelx
* 30;
4623 newtop
+= wheely
* 30;
4626 if (newleft
+ _mwidth(obj
) > data
->icld_AreaWidth
)
4627 newleft
= data
->icld_AreaWidth
- _mwidth(obj
);
4631 if (newtop
+ _mheight(obj
) > data
->icld_AreaHeight
)
4632 newtop
= data
->icld_AreaHeight
- _mheight(obj
);
4636 if ((newleft
!= data
->icld_ViewX
) || (newtop
!= data
->icld_ViewY
))
4638 SetAttrs(obj
, MUIA_Virtgroup_Left
, newleft
,
4639 MUIA_Virtgroup_Top
, newtop
,
4648 * a) if clicked object is selected, nothing
4649 * b) if clicked object is not selected, unselect all, select object
4650 * c) if no clicked object, start lasso
4652 * a) if in lasso, finish lasso
4654 * a) if object is selected, unselect it (= remove from multiselection)
4655 * b) if object is not selected, select it (= add to multiselection)
4658 * Expected behaviour:
4659 * a) you can only "remove" multiselection by clicking on not selected object or on space where there is no icon
4663 static void IconList_HandleNewIconSelection(struct IClass
*CLASS
, Object
*obj
, struct MUIP_HandleEvent
*message
,
4664 struct IconEntry
*new_selected
, BOOL
*doubleclicked
)
4666 struct IconEntry
*node
= NULL
;
4667 BOOL update_entry
= FALSE
;
4668 LONG mx
= message
->imsg
->MouseX
- _mleft(obj
);
4669 LONG my
= message
->imsg
->MouseY
- _mtop(obj
);
4670 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
4671 BOOL nounselection
= (new_selected
!= NULL
&&
4672 (new_selected
->ie_Flags
& ICONENTRY_FLAG_SELECTED
)); /* see notes above */
4675 /* Check if this is a double click on icon or empty space */
4676 if ((DoubleClick(data
->last_secs
, data
->last_mics
, message
->imsg
->Seconds
, message
->imsg
->Micros
)) && (data
->icld_SelectionLastClicked
== new_selected
))
4678 #if defined(DEBUG_ILC_EVENTS)
4679 D(bug("[IconList] %s: Entry double-clicked\n", __PRETTY_FUNCTION__
));
4681 *doubleclicked
= TRUE
;
4684 /* Deselection lopp */
4685 #if defined(__AROS__)
4686 ForeachNode(&data
->icld_IconList
, node
)
4688 Foreach_Node(&data
->icld_IconList
, node
);
4691 if (node
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
4693 update_entry
= FALSE
;
4695 /* If node that is being checked is selected and it is not the clicked node
4696 * and no shift pressed and
4697 * clicked node is not part of selection (see notes above) or this is a double click */
4698 if (node
->ie_Flags
& ICONENTRY_FLAG_SELECTED
)
4700 if ((new_selected
!= node
) &&
4701 (!(message
->imsg
->Qualifier
& (IEQUALIFIER_LSHIFT
| IEQUALIFIER_RSHIFT
))) &&
4702 (!nounselection
|| *doubleclicked
))
4704 Remove(&node
->ie_SelectionNode
);
4705 node
->ie_Flags
&= ~ICONENTRY_FLAG_SELECTED
;
4706 update_entry
= TRUE
;
4711 if ((node
->ie_Flags
& ICONENTRY_FLAG_FOCUS
) && (new_selected
!= node
))
4713 node
->ie_Flags
&= ~ICONENTRY_FLAG_FOCUS
;
4714 update_entry
= TRUE
;
4720 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
4721 data
->update_entry
= node
;
4722 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
4723 #if defined(DEBUG_ILC_EVENTS)
4724 D(bug("[IconList] %s: Rendered entry '%s'\n", __PRETTY_FUNCTION__
, node
->ie_IconListEntry
.label
));
4730 if (new_selected
!= NULL
)
4732 /* Found clicked entry... */
4733 data
->icld_LassoActive
= FALSE
;
4734 update_entry
= FALSE
;
4736 if (!(new_selected
->ie_Flags
& ICONENTRY_FLAG_SELECTED
))
4738 /* Add new entry to selection */
4739 AddTail(&data
->icld_SelectionList
, &new_selected
->ie_SelectionNode
);
4740 new_selected
->ie_Flags
|= ICONENTRY_FLAG_SELECTED
;
4741 update_entry
= TRUE
;
4743 else if ((*doubleclicked
== FALSE
) && (message
->imsg
->Qualifier
& (IEQUALIFIER_LSHIFT
| IEQUALIFIER_RSHIFT
)))
4745 /* Unselect previously selected entry */
4746 Remove(&new_selected
->ie_SelectionNode
);
4747 new_selected
->ie_Flags
&= ~ICONENTRY_FLAG_SELECTED
;
4748 update_entry
= TRUE
;
4752 if (!(new_selected
->ie_Flags
& ICONENTRY_FLAG_FOCUS
))
4754 new_selected
->ie_Flags
|= ICONENTRY_FLAG_FOCUS
;
4755 data
->icld_FocusIcon
= new_selected
;
4756 update_entry
= TRUE
;
4762 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
4763 data
->update_entry
= new_selected
;
4764 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
4765 #if defined(DEBUG_ILC_EVENTS)
4766 D(bug("[IconList] %s: Rendered 'new_selected' entry '%s'\n", __PRETTY_FUNCTION__
, new_selected
->ie_IconListEntry
.label
));
4772 struct Window
* thisWindow
= NULL
;
4773 #if defined(DEBUG_ILC_EVENTS) || defined(DEBUG_ILC_LASSO)
4774 D(bug("[IconList] %s: Starting Lasso\n", __PRETTY_FUNCTION__
));
4776 /* No entry clicked on ... Start Lasso-selection */
4777 data
->icld_LassoActive
= TRUE
;
4778 if (!(message
->imsg
->Qualifier
& (IEQUALIFIER_LSHIFT
| IEQUALIFIER_RSHIFT
)))
4780 data
->icld_SelectionLastClicked
= NULL
;
4781 data
->icld_FocusIcon
= NULL
;
4783 data
->icld_LassoRectangle
.MinX
= mx
- data
->view_rect
.MinX
+ data
->icld_ViewX
;
4784 data
->icld_LassoRectangle
.MinY
= my
- data
->view_rect
.MinY
+ data
->icld_ViewY
;
4785 data
->icld_LassoRectangle
.MaxX
= mx
- data
->view_rect
.MinX
+ data
->icld_ViewX
;
4786 data
->icld_LassoRectangle
.MaxY
= my
- data
->view_rect
.MinY
+ data
->icld_ViewY
;
4788 /* Draw initial Lasso frame */
4789 IconList_InvertLassoOutlines(obj
, data
, &data
->icld_LassoRectangle
);
4791 /* Start handling INTUITICKS */
4792 GET(obj
, MUIA_Window
, &thisWindow
);
4795 ModifyIDCMP(thisWindow
, (thisWindow
->IDCMPFlags
|IDCMP_INTUITICKS
));
4796 if (!(data
->ehn
.ehn_Events
& IDCMP_INTUITICKS
))
4798 DoMethod(_win(obj
), MUIM_Window_RemEventHandler
, (IPTR
)&data
->ehn
);
4799 data
->ehn
.ehn_Events
|= IDCMP_INTUITICKS
;
4800 DoMethod(_win(obj
), MUIM_Window_AddEventHandler
, (IPTR
)&data
->ehn
);
4806 ///MUIM_HandleEvent()
4807 /**************************************************************************
4809 **************************************************************************/
4810 IPTR
IconList__MUIM_HandleEvent(struct IClass
*CLASS
, Object
*obj
, struct MUIP_HandleEvent
*message
)
4812 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
4814 #if defined(DEBUG_ILC_FUNCS)
4815 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
4820 LONG mx
= message
->imsg
->MouseX
- _mleft(obj
);
4821 LONG my
= message
->imsg
->MouseY
- _mtop(obj
);
4826 switch (message
->imsg
->Class
)
4829 bug("[IconList] %s: IDCMP_NEWSIZE\n", __PRETTY_FUNCTION__
);
4834 #if defined(DEBUG_ILC_EVENTS)
4835 D(bug("[IconList] %s: IDCMP_RAWKEY\n", __PRETTY_FUNCTION__
));
4837 BOOL rawkey_handled
= FALSE
;
4839 switch(message
->imsg
->Code
)
4841 case RAWKEY_NM_WHEEL_UP
:
4843 rawkey_handled
= TRUE
;
4846 case RAWKEY_NM_WHEEL_DOWN
:
4848 rawkey_handled
= TRUE
;
4851 case RAWKEY_NM_WHEEL_LEFT
:
4853 rawkey_handled
= TRUE
;
4856 case RAWKEY_NM_WHEEL_RIGHT
:
4858 rawkey_handled
= TRUE
;
4864 #if defined(DEBUG_ILC_KEYEVENTS)
4865 D(bug("[IconList] %s: Processing mouse wheel event\n", __PRETTY_FUNCTION__
));
4867 if (_isinobject(message
->imsg
->MouseX
, message
->imsg
->MouseY
) &&
4870 DoWheelMove(CLASS
, obj
, wheelx
, wheely
, message
->imsg
->Qualifier
);
4873 else if (!(message
->imsg
->Code
& IECODE_UP_PREFIX
))
4875 LONG new_ViewY
= data
->icld_ViewY
;
4876 struct IconEntry
*start_entry
= NULL
, *active_entry
= NULL
, *entry_next
= NULL
;
4877 IPTR start_X
= 0, start_Y
= 0, active_X
= 0, active_Y
= 0, next_X
= 0, next_Y
= 0;
4880 #if defined(DEBUG_ILC_KEYEVENTS)
4881 D(bug("[IconList] %s: Processing key up event\n", __PRETTY_FUNCTION__
));
4884 switch(message
->imsg
->Code
)
4887 rawkey_handled
= TRUE
;
4889 #if defined(DEBUG_ILC_KEYEVENTS)
4890 D(bug("[IconList] %s: RAWKEY_RETURN\n", __PRETTY_FUNCTION__
));
4893 if (data
->icld_FocusIcon
) active_entry
= data
->icld_FocusIcon
;
4894 else if (data
->icld_SelectionLastClicked
) active_entry
= data
->icld_SelectionLastClicked
;
4898 if (!(active_entry
->ie_Flags
& ICONENTRY_FLAG_SELECTED
))
4900 active_entry
->ie_Flags
|= ICONENTRY_FLAG_SELECTED
;
4901 AddTail(&data
->icld_SelectionList
, &active_entry
->ie_SelectionNode
);
4902 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
4903 data
->update_entry
= active_entry
;
4904 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
4906 data
->icld_SelectionLastClicked
= active_entry
;
4907 data
->icld_FocusIcon
= active_entry
;
4909 SET(obj
, MUIA_IconList_DoubleClick
, TRUE
);
4914 rawkey_handled
= TRUE
;
4916 #if defined(DEBUG_ILC_KEYEVENTS)
4917 D(bug("[IconList] %s: RAWKEY_SPACE\n", __PRETTY_FUNCTION__
));
4920 if (data
->icld_FocusIcon
) active_entry
= data
->icld_FocusIcon
;
4921 else if (data
->icld_SelectionLastClicked
) active_entry
= data
->icld_SelectionLastClicked
;
4923 if (!(message
->imsg
->Qualifier
& IEQUALIFIER_LSHIFT
) && ((data
->icld_SelectionLastClicked
)||(data
->icld_SelectionLastClicked
!= active_entry
)))
4925 #if defined(DEBUG_ILC_KEYEVENTS)
4926 D(bug("[IconList] %s: SPACE: Clearing selected icons ..\n", __PRETTY_FUNCTION__
));
4928 DoMethod(obj
, MUIM_IconList_UnselectAll
);
4933 if (!(active_entry
->ie_Flags
& ICONENTRY_FLAG_SELECTED
))
4935 AddTail(&data
->icld_SelectionList
, &active_entry
->ie_SelectionNode
);
4936 active_entry
->ie_Flags
|= ICONENTRY_FLAG_SELECTED
;
4937 data
->icld_SelectionLastClicked
= active_entry
;
4941 Remove(&active_entry
->ie_SelectionNode
);
4942 active_entry
->ie_Flags
&= ~ICONENTRY_FLAG_SELECTED
;
4945 data
->icld_FocusIcon
= active_entry
;
4947 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
4948 data
->update_entry
= active_entry
;
4949 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
4954 rawkey_handled
= TRUE
;
4956 #if defined(DEBUG_ILC_KEYEVENTS)
4957 D(bug("[IconList] %s: RAWKEY_PAGEUP\n", __PRETTY_FUNCTION__
));
4960 if (data
->icld_AreaHeight
> data
->icld_ViewHeight
)
4962 new_ViewY
-= data
->icld_ViewHeight
;
4967 if (new_ViewY
!= data
->icld_ViewY
)
4969 SET(obj
, MUIA_Virtgroup_Top
, new_ViewY
);
4973 case RAWKEY_PAGEDOWN
:
4974 rawkey_handled
= TRUE
;
4976 #if defined(DEBUG_ILC_KEYEVENTS)
4977 D(bug("[IconList] %s: RAWKEY_PAGEDOWN\n", __PRETTY_FUNCTION__
));
4980 if (data
->icld_AreaHeight
> data
->icld_ViewHeight
)
4982 new_ViewY
+= data
->icld_ViewHeight
;
4983 if (new_ViewY
> (data
->icld_AreaHeight
- data
->icld_ViewHeight
))
4984 new_ViewY
= data
->icld_AreaHeight
- data
->icld_ViewHeight
;
4987 if (new_ViewY
!= data
->icld_ViewY
)
4989 SET(obj
, MUIA_Virtgroup_Top
, new_ViewY
);
4994 rawkey_handled
= TRUE
;
4996 #if defined(DEBUG_ILC_KEYEVENTS)
4997 D(bug("[IconList] %s: RAWKEY_UP\n", __PRETTY_FUNCTION__
));
5000 if (data
->icld_FocusIcon
)
5002 start_entry
= data
->icld_FocusIcon
;
5003 #if defined(DEBUG_ILC_KEYEVENTS)
5004 D(bug("[IconList] %s: UP: Clearing existing focused entry @ 0x%p\n", __PRETTY_FUNCTION__
, start_entry
));
5007 start_entry
->ie_Flags
&= ~ICONENTRY_FLAG_FOCUS
;
5008 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
5009 data
->update_entry
= start_entry
;
5010 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
5012 start_X
= start_entry
->ie_IconX
;
5013 start_Y
= start_entry
->ie_IconY
;
5014 #if defined(DEBUG_ILC_KEYEVENTS)
5015 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
));
5017 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
5019 if (start_entry
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
5021 start_X
= start_X
- ((data
->icld_IconAreaLargestWidth
- start_entry
->ie_AreaWidth
)/2);
5022 #if defined(DEBUG_ILC_KEYEVENTS)
5023 D(bug("[IconList] %s: UP: adjusted start_X for grid = %d\n", __PRETTY_FUNCTION__
, start_X
));
5028 if ((active_entry
= Node_PreviousVisible(start_entry
)) && !(data
->icld_DisplayFlags
& ICONLIST_DISP_VERTICAL
))
5030 //Check if we are at the edge of the entry area ..
5031 #if defined(DEBUG_ILC_KEYEVENTS)
5032 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
));
5034 active_Y
= active_entry
->ie_IconY
;
5036 if (active_Y
== start_Y
)
5039 #if defined(DEBUG_ILC_KEYEVENTS)
5040 D(bug("[IconList] %s: UP: active_entry is on our row (not at the edge)\n", __PRETTY_FUNCTION__
));
5042 entry_next
= active_entry
;
5043 next_X
= entry_next
->ie_IconX
;
5044 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
5046 if (entry_next
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
5047 next_X
= next_X
- ((data
->icld_IconAreaLargestWidth
- entry_next
->ie_AreaWidth
)/2);
5051 #if defined(DEBUG_ILC_KEYEVENTS)
5052 D(bug("[IconList] %s: UP: using start_X %d, start_Y %d\n", __PRETTY_FUNCTION__
, start_X
, start_Y
));
5056 if (!(message
->imsg
->Qualifier
& IEQUALIFIER_LSHIFT
) && ((data
->icld_SelectionLastClicked
)&&(data
->icld_SelectionLastClicked
!= active_entry
)))
5058 #if defined(DEBUG_ILC_KEYEVENTS)
5059 D(bug("[IconList] %s: UP: Clearing selected icons ..\n", __PRETTY_FUNCTION__
));
5061 DoMethod(obj
, MUIM_IconList_UnselectAll
);
5064 #if defined(DEBUG_ILC_KEYEVENTS)
5065 D(bug("[IconList] %s: UP: active = 0x%p, next = 0x%p\n", __PRETTY_FUNCTION__
, active_entry
, entry_next
));
5067 if (!(active_entry
))
5069 // If nothing is selected we will use the last visible entry ..
5070 active_entry
= Node_LastVisible(&data
->icld_IconList
);
5071 start_X
= active_entry
->ie_IconX
;
5072 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
5074 if (active_entry
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
5075 start_X
= start_X
- ((data
->icld_IconAreaLargestWidth
- active_entry
->ie_AreaWidth
)/2);
5077 start_Y
= active_entry
->ie_IconY
;
5080 while (active_entry
!= NULL
)
5082 #if defined(DEBUG_ILC_KEYEVENTS)
5083 D(bug("[IconList] %s: UP: Checking active @ 0x%p\n", __PRETTY_FUNCTION__
, active_entry
));
5085 if (data
->icld_DisplayFlags
& ICONLIST_DISP_VERTICAL
)
5087 // Return the first visible since the list flow direction matches
5088 // our cursor direction
5089 if (active_entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
5094 active_X
= active_entry
->ie_IconX
;
5096 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
5098 if (active_entry
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
5099 x_diff
= ((data
->icld_IconAreaLargestWidth
- active_entry
->ie_AreaWidth
)/2);
5101 active_Y
= active_entry
->ie_IconY
;
5107 if ((active_entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
) &&
5108 (active_Y
< start_Y
) &&
5109 (((active_X
- x_diff
) >= start_X
) &&
5110 ((active_X
- x_diff
) <= (start_X
+ start_entry
->ie_AreaWidth
+ (x_diff
*2)))))
5112 #if defined(DEBUG_ILC_KEYEVENTS)
5113 D(bug("[IconList] %s: UP: (A) entry 0x%p matches\n", __PRETTY_FUNCTION__
, active_entry
));
5117 else if (active_entry
== (struct IconEntry
*)GetHead(&data
->icld_IconList
))
5119 #if defined(DEBUG_ILC_KEYEVENTS)
5120 D(bug("[IconList] %s: UP: (A) reached list start .. restarting from the end ..\n", __PRETTY_FUNCTION__
));
5124 if ((entry_next
= Node_PreviousVisible(entry_next
)))
5126 if (entry_next
->ie_IconX
> start_X
)
5130 next_X
= entry_next
->ie_IconX
;
5131 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
5133 if (entry_next
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
5134 next_X
= next_X
- ((data
->icld_IconAreaLargestWidth
- entry_next
->ie_AreaWidth
)/2);
5139 #if defined(DEBUG_ILC_KEYEVENTS)
5140 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
));
5142 active_entry
= Node_LastVisible(&data
->icld_IconList
);
5147 if ((active_entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
) &&
5148 (active_Y
< start_Y
) &&
5149 ((active_X
+ x_diff
) < (start_X
+ start_entry
->ie_AreaWidth
+ x_diff
)))
5151 #if defined(DEBUG_ILC_KEYEVENTS)
5152 D(bug("[IconList] %s: UP: (B) entry 0x%p matches\n", __PRETTY_FUNCTION__
, active_entry
));
5160 if (active_entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
5162 #if defined(DEBUG_ILC_KEYEVENTS)
5163 D(bug("[IconList] %s: UP: (C) entry 0x%p matches\n", __PRETTY_FUNCTION__
, active_entry
));
5169 active_entry
= (struct IconEntry
*)(((struct Node
*)active_entry
)->ln_Pred
);
5172 if (!(active_entry
))
5174 #if defined(DEBUG_ILC_KEYEVENTS)
5175 D(bug("[IconList] %s: UP: No Next UP Node - Getting Last visible entry ..\n", __PRETTY_FUNCTION__
));
5177 /* We didnt find a "next UP" entry so just use the last visible */
5178 active_entry
= Node_LastVisible(&data
->icld_IconList
);
5183 if (!(active_entry
->ie_Flags
& ICONENTRY_FLAG_FOCUS
))
5185 active_entry
->ie_Flags
|= ICONENTRY_FLAG_FOCUS
;
5186 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
5187 data
->update_entry
= active_entry
;
5188 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
5191 data
->icld_FocusIcon
= active_entry
;
5195 rawkey_handled
= TRUE
;
5197 #if defined(DEBUG_ILC_KEYEVENTS)
5198 D(bug("[IconList] %s: RAWKEY_DOWN\n", __PRETTY_FUNCTION__
));
5200 if (data
->icld_FocusIcon
)
5202 start_entry
= data
->icld_FocusIcon
;
5203 #if defined(DEBUG_ILC_KEYEVENTS)
5204 D(bug("[IconList] %s: DOWN: Clearing existing focused entry @ 0x%p\n", __PRETTY_FUNCTION__
, start_entry
));
5207 start_entry
->ie_Flags
&= ~ICONENTRY_FLAG_FOCUS
;
5208 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
5209 data
->update_entry
= start_entry
;
5210 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
5212 start_X
= start_entry
->ie_IconX
;
5213 start_Y
= start_entry
->ie_IconY
;
5214 #if defined(DEBUG_ILC_KEYEVENTS)
5215 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
));
5217 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
5219 if (start_entry
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
5221 start_X
= start_X
- ((data
->icld_IconAreaLargestWidth
- start_entry
->ie_AreaWidth
)/2);
5222 #if defined(DEBUG_ILC_KEYEVENTS)
5223 D(bug("[IconList] %s: DOWN: adjusted start_X for grid = %d\n", __PRETTY_FUNCTION__
, start_X
));
5228 if ((active_entry
= Node_NextVisible(start_entry
)) &&
5229 (!(data
->icld_DisplayFlags
& ICONLIST_DISP_VERTICAL
)))
5231 #if defined(DEBUG_ILC_KEYEVENTS)
5232 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
));
5234 active_Y
= active_entry
->ie_IconY
;
5236 if (active_Y
== start_Y
)
5239 #if defined(DEBUG_ILC_KEYEVENTS)
5240 D(bug("[IconList] %s: DOWN: active_entry is on our row (not at the edge)\n", __PRETTY_FUNCTION__
));
5242 entry_next
= active_entry
;
5243 next_X
= entry_next
->ie_IconX
;
5244 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
5246 if (entry_next
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
5247 next_X
= next_X
- ((data
->icld_IconAreaLargestWidth
- entry_next
->ie_AreaWidth
)/2);
5251 #if defined(DEBUG_ILC_KEYEVENTS)
5252 D(bug("[IconList] %s: DOWN: using start_X %d, start_Y %d\n", __PRETTY_FUNCTION__
, start_X
, start_Y
));
5256 if (!(message
->imsg
->Qualifier
& IEQUALIFIER_LSHIFT
) && ((data
->icld_SelectionLastClicked
)&&(data
->icld_SelectionLastClicked
!= active_entry
)))
5258 #if defined(DEBUG_ILC_KEYEVENTS)
5259 D(bug("[IconList] %s: DOWN: Clearing selected icons ..\n", __PRETTY_FUNCTION__
));
5261 DoMethod(obj
, MUIM_IconList_UnselectAll
);
5264 #if defined(DEBUG_ILC_KEYEVENTS)
5265 D(bug("[IconList] %s: DOWN: active = 0x%p, next = 0x%p\n", __PRETTY_FUNCTION__
, active_entry
, entry_next
));
5267 if (!(active_entry
))
5269 // If nothing is selected we will use the First visible entry ..
5270 active_entry
= Node_FirstVisible(&data
->icld_IconList
);
5271 start_X
= active_entry
->ie_IconX
;
5272 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
5274 if (active_entry
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
5275 start_X
= start_X
- ((data
->icld_IconAreaLargestWidth
- active_entry
->ie_AreaWidth
)/2);
5277 start_Y
= active_entry
->ie_IconY
;
5280 while (active_entry
!= NULL
)
5282 #if defined(DEBUG_ILC_KEYEVENTS)
5283 D(bug("[IconList] %s: DOWN: Checking active @ 0x%p\n", __PRETTY_FUNCTION__
, active_entry
));
5285 if (data
->icld_DisplayFlags
& ICONLIST_DISP_VERTICAL
)
5287 if (active_entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
5292 active_X
= active_entry
->ie_IconX
;
5294 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
5296 if (active_entry
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
5297 x_diff
= ((data
->icld_IconAreaLargestWidth
- active_entry
->ie_AreaWidth
)/2);
5299 active_Y
= active_entry
->ie_IconY
;
5305 if ((active_entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
) &&
5306 (active_Y
> start_Y
) &&
5307 (((active_X
- x_diff
) >= start_X
) &&
5308 ((active_X
- x_diff
) <= (start_X
+ start_entry
->ie_AreaWidth
+ (x_diff
*2)))))
5310 #if defined(DEBUG_ILC_KEYEVENTS)
5311 D(bug("[IconList] %s: DOWN: (A) entry 0x%p matches\n", __PRETTY_FUNCTION__
, active_entry
));
5315 else if (active_entry
== (struct IconEntry
*)GetTail(&data
->icld_IconList
))
5317 #if defined(DEBUG_ILC_KEYEVENTS)
5318 D(bug("[IconList] %s: DOWN: (A) reached list end .. starting at the beginng ..\n", __PRETTY_FUNCTION__
));
5320 start_X
= entry_next
->ie_IconX
;
5321 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
5323 if (entry_next
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
5324 start_X
= start_X
- ((data
->icld_IconAreaLargestWidth
- entry_next
->ie_AreaWidth
)/2);
5327 if ((entry_next
= (struct IconEntry
*)Node_NextVisible(entry_next
)))
5329 if (entry_next
->ie_IconX
< start_X
)
5333 next_X
= entry_next
->ie_IconX
;
5334 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
5336 if (entry_next
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
5337 next_X
= next_X
+ ((data
->icld_IconAreaLargestWidth
- entry_next
->ie_AreaWidth
)/2);
5342 #if defined(DEBUG_ILC_KEYEVENTS)
5343 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
));
5345 active_entry
= Node_FirstVisible(&data
->icld_IconList
);
5350 if ((active_entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
) &&
5351 (active_Y
> start_Y
) &&
5352 (active_X
> start_X
- 1))
5354 #if defined(DEBUG_ILC_KEYEVENTS)
5355 D(bug("[IconList] %s: DOWN: (B) entry 0x%p matches\n", __PRETTY_FUNCTION__
, active_entry
));
5363 if (active_entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
5365 #if defined(DEBUG_ILC_KEYEVENTS)
5366 D(bug("[IconList] %s: DOWN: (C) entry 0x%p matches\n", __PRETTY_FUNCTION__
, active_entry
));
5372 active_entry
= (struct IconEntry
*)GetSucc(&active_entry
->ie_IconNode
);
5375 if (!(active_entry
))
5377 #if defined(DEBUG_ILC_KEYEVENTS)
5378 D(bug("[IconList] %s: DOWN: No Next DOWN Node - Getting first visable entry ..\n", __PRETTY_FUNCTION__
));
5380 /* We didnt find a "next DOWN" entry so just use the first visible */
5381 active_entry
= Node_FirstVisible(&data
->icld_IconList
);
5386 if (!(active_entry
->ie_Flags
& ICONENTRY_FLAG_FOCUS
))
5388 active_entry
->ie_Flags
|= ICONENTRY_FLAG_FOCUS
;
5389 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
5390 data
->update_entry
= active_entry
;
5391 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
5394 data
->icld_FocusIcon
= active_entry
;
5398 rawkey_handled
= TRUE
;
5400 #if defined(DEBUG_ILC_KEYEVENTS)
5401 D(bug("[IconList] %s: RAWKEY_LEFT\n", __PRETTY_FUNCTION__
));
5403 if (data
->icld_FocusIcon
)
5405 start_entry
= data
->icld_FocusIcon
;
5406 #if defined(DEBUG_ILC_KEYEVENTS)
5407 D(bug("[IconList] %s: LEFT: Clearing existing focused entry @ 0x%p\n", __PRETTY_FUNCTION__
, start_entry
));
5410 start_entry
->ie_Flags
&= ~ICONENTRY_FLAG_FOCUS
;
5411 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
5412 data
->update_entry
= start_entry
;
5413 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
5415 start_X
= start_entry
->ie_IconX
;
5416 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
5418 if (start_entry
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
5419 start_X
= start_X
- ((data
->icld_IconAreaLargestWidth
- start_entry
->ie_AreaWidth
)/2);
5421 start_Y
= start_entry
->ie_IconY
;
5423 #if defined(DEBUG_ILC_KEYEVENTS)
5424 D(bug("[IconList] %s: LEFT: start_X %d, start_Y %d\n", __PRETTY_FUNCTION__
, start_X
, start_Y
));
5427 if (!(active_entry
= Node_NextVisible(start_entry
)) && (!(data
->icld_DisplayFlags
& ICONLIST_DISP_VERTICAL
)))
5429 active_entry
= (struct IconEntry
*)GetHead(&data
->icld_IconList
);
5430 #if defined(DEBUG_ILC_KEYEVENTS)
5431 D(bug("[IconList] %s: LEFT: Start at the beginning (Active @ 0x%p) using entry X + Width\n", __PRETTY_FUNCTION__
, active_entry
));
5433 start_X
= start_X
+ start_entry
->ie_AreaWidth
;
5434 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
5436 if (start_entry
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
5437 start_X
= start_X
+ ((data
->icld_IconAreaLargestWidth
- start_entry
->ie_AreaWidth
)/2);
5443 else if (active_entry
&& (!(data
->icld_DisplayFlags
& ICONLIST_DISP_VERTICAL
)))
5445 #if defined(DEBUG_ILC_KEYEVENTS)
5446 D(bug("[IconList] %s: LEFT: Active @ 0x%p, X %d\n", __PRETTY_FUNCTION__
, active_entry
, active_entry
->ie_IconX
));
5448 if ((entry_next
= Node_NextVisible(start_entry
)))
5450 #if defined(DEBUG_ILC_KEYEVENTS)
5451 D(bug("[IconList] %s: LEFT: Next @ 0x%p, X %d\n", __PRETTY_FUNCTION__
, entry_next
, entry_next
->ie_IconX
));
5454 if (entry_next
->ie_IconX
< start_X
)
5458 next_X
= entry_next
->ie_IconX
;
5459 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
5461 if (entry_next
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
5462 next_X
= next_X
- ((data
->icld_IconAreaLargestWidth
- entry_next
->ie_AreaWidth
)/2);
5467 #if defined(DEBUG_ILC_KEYEVENTS)
5468 D(bug("[IconList] %s: LEFT: using start_X %d, start_Y %d\n", __PRETTY_FUNCTION__
, start_X
, start_Y
));
5472 if (!(message
->imsg
->Qualifier
& IEQUALIFIER_LSHIFT
) && ((data
->icld_SelectionLastClicked
)&&(data
->icld_SelectionLastClicked
!= active_entry
)))
5474 #if defined(DEBUG_ILC_KEYEVENTS)
5475 D(bug("[IconList] %s: LEFT: Clearing selected icons ..\n", __PRETTY_FUNCTION__
));
5477 DoMethod(obj
, MUIM_IconList_UnselectAll
);
5480 #if defined(DEBUG_ILC_KEYEVENTS)
5481 D(bug("[IconList] %s: LEFT: active = 0x%p, next = 0x%p\n", __PRETTY_FUNCTION__
, active_entry
, entry_next
));
5484 if (!(active_entry
))
5486 active_entry
= (struct IconEntry
*)GetHead(&data
->icld_IconList
);
5489 while (active_entry
!= NULL
)
5491 #if defined(DEBUG_ILC_KEYEVENTS)
5492 D(bug("[IconList] %s: LEFT: Checking active @ 0x%p\n", __PRETTY_FUNCTION__
, active_entry
));
5494 if (data
->icld_DisplayFlags
& ICONLIST_DISP_VERTICAL
)
5496 if (active_entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
5501 LONG active_entry_X
= active_entry
->ie_IconX
;
5502 LONG active_entry_Y
;
5503 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
5505 if (active_entry
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
5506 active_entry_X
= active_entry_X
- ((data
->icld_IconAreaLargestWidth
- active_entry
->ie_AreaWidth
)/2);
5508 active_entry_Y
= active_entry
->ie_IconY
;
5514 if ((active_entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
) &&
5515 (active_entry_Y
> start_Y
) &&
5516 ((active_entry_X
> start_X
- 1) &&
5517 (active_entry_X
< next_X
)))
5519 #if defined(DEBUG_ILC_KEYEVENTS)
5520 D(bug("[IconList] %s: LEFT: (A) entry 0x%p matches\n", __PRETTY_FUNCTION__
, active_entry
));
5524 else if (active_entry
== (struct IconEntry
*)GetTail(&data
->icld_IconList
))
5526 #if defined(DEBUG_ILC_KEYEVENTS)
5527 D(bug("[IconList] %s: LEFT: (A) reached list end .. starting at the beginng ..\n", __PRETTY_FUNCTION__
));
5529 start_X
= entry_next
->ie_IconX
;
5530 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
5532 if (entry_next
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
5533 start_X
= start_X
- ((data
->icld_IconAreaLargestWidth
- entry_next
->ie_AreaWidth
)/2);
5536 if ((entry_next
= Node_NextVisible(entry_next
)))
5538 if (entry_next
->ie_IconX
< start_X
)
5542 next_X
= entry_next
->ie_IconX
;
5543 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
5545 if (entry_next
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
5546 next_X
= next_X
+ ((data
->icld_IconAreaLargestWidth
- entry_next
->ie_AreaWidth
)/2);
5551 #if defined(DEBUG_ILC_KEYEVENTS)
5552 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
));
5554 active_entry
= (struct IconEntry
*)GetHead(&data
->icld_IconList
);
5559 if ((active_entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
) &&
5560 (active_entry_Y
> start_Y
) &&
5561 (active_entry_X
> start_X
- 1))
5563 #if defined(DEBUG_ILC_KEYEVENTS)
5564 D(bug("[IconList] %s: LEFT: (B) entry 0x%p matches\n", __PRETTY_FUNCTION__
, active_entry
));
5572 if (active_entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
5574 #if defined(DEBUG_ILC_KEYEVENTS)
5575 D(bug("[IconList] %s: LEFT: (C) entry 0x%p matches\n", __PRETTY_FUNCTION__
, active_entry
));
5581 active_entry
= (struct IconEntry
*)GetSucc(&active_entry
->ie_IconNode
);
5584 if (!(active_entry
))
5586 #if defined(DEBUG_ILC_KEYEVENTS)
5587 D(bug("[IconList] %s: LEFT: No Next LEFT Node - Getting first visable entry ..\n", __PRETTY_FUNCTION__
));
5589 /* We didnt find a "next LEFT" entry so just use the last visible */
5590 active_entry
= (struct IconEntry
*)GetHead(&data
->icld_IconList
);
5591 while ((active_entry
!= NULL
) &&(!(active_entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)))
5593 active_entry
= (struct IconEntry
*)GetSucc(&active_entry
->ie_IconNode
);
5599 if (!(active_entry
->ie_Flags
& ICONENTRY_FLAG_FOCUS
))
5601 active_entry
->ie_Flags
|= ICONENTRY_FLAG_FOCUS
;
5602 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
5603 data
->update_entry
= active_entry
;
5604 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
5607 data
->icld_FocusIcon
= active_entry
;
5611 rawkey_handled
= TRUE
;
5613 #if defined(DEBUG_ILC_KEYEVENTS)
5614 D(bug("[IconList] %s: RAWKEY_RIGHT\n", __PRETTY_FUNCTION__
));
5617 if (data
->icld_FocusIcon
)
5619 start_entry
= data
->icld_FocusIcon
;
5620 #if defined(DEBUG_ILC_KEYEVENTS)
5621 D(bug("[IconList] %s: RIGHT: Clearing existing focused entry @ 0x%p\n", __PRETTY_FUNCTION__
, start_entry
));
5623 start_entry
->ie_Flags
&= ~ICONENTRY_FLAG_FOCUS
;
5624 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
5625 data
->update_entry
= start_entry
;
5626 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
5628 start_X
= start_entry
->ie_IconX
;
5629 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
5631 if (start_entry
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
5632 start_X
= start_X
- ((data
->icld_IconAreaLargestWidth
- start_entry
->ie_AreaWidth
)/2);
5634 start_Y
= start_entry
->ie_IconY
;
5636 #if defined(DEBUG_ILC_KEYEVENTS)
5637 D(bug("[IconList] %s: RIGHT: start_X %d, start_Y %d\n", __PRETTY_FUNCTION__
, start_X
, start_Y
));
5639 if (!(active_entry
= Node_NextVisible(start_entry
)) && (!(data
->icld_DisplayFlags
& ICONLIST_DISP_VERTICAL
)))
5641 active_entry
= (struct IconEntry
*)GetHead(&data
->icld_IconList
);
5642 #if defined(DEBUG_ILC_KEYEVENTS)
5643 D(bug("[IconList] %s: RIGHT: Start at the beginning (Active @ 0x%p) using entry X + Width\n", __PRETTY_FUNCTION__
, active_entry
));
5646 start_Y
= start_Y
+ start_entry
->ie_AreaHeight
;
5649 else if (active_entry
&& (data
->icld_DisplayFlags
& ICONLIST_DISP_VERTICAL
))
5651 #if defined(DEBUG_ILC_KEYEVENTS)
5652 D(bug("[IconList] %s: RIGHT: Active @ 0x%p, X %d\n", __PRETTY_FUNCTION__
, active_entry
, active_entry
->ie_IconX
));
5654 if ((entry_next
= Node_NextVisible(start_entry
)))
5656 #if defined(DEBUG_ILC_KEYEVENTS)
5657 D(bug("[IconList] %s: RIGHT: Next @ 0x%p, X %d\n", __PRETTY_FUNCTION__
, entry_next
, entry_next
->ie_IconX
));
5660 if (entry_next
->ie_IconY
< start_Y
)
5663 next_Y
= entry_next
->ie_IconY
;
5666 #if defined(DEBUG_ILC_KEYEVENTS)
5667 D(bug("[IconList] %s: RIGHT: using start_X %d, start_Y %d\n", __PRETTY_FUNCTION__
, start_X
, start_Y
));
5671 if (!(message
->imsg
->Qualifier
& IEQUALIFIER_LSHIFT
) && ((data
->icld_SelectionLastClicked
)&&(data
->icld_SelectionLastClicked
!= active_entry
)))
5673 #if defined(DEBUG_ILC_KEYEVENTS)
5674 D(bug("[IconList] %s: RIGHT: Clearing selected icons ..\n", __PRETTY_FUNCTION__
));
5676 DoMethod(obj
, MUIM_IconList_UnselectAll
);
5679 #if defined(DEBUG_ILC_KEYEVENTS)
5680 D(bug("[IconList] %s: RIGHT: active = 0x%p, next = 0x%p\n", __PRETTY_FUNCTION__
, active_entry
, entry_next
));
5683 if (!(active_entry
))
5685 active_entry
= (struct IconEntry
*)GetHead(&data
->icld_IconList
);
5688 while (active_entry
!= NULL
)
5690 #if defined(DEBUG_ILC_KEYEVENTS)
5691 D(bug("[IconList] %s: RIGHT: Checking active @ 0x%p\n", __PRETTY_FUNCTION__
, active_entry
));
5693 if (!(data
->icld_DisplayFlags
& ICONLIST_DISP_VERTICAL
))
5695 if (active_entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
5700 LONG active_entry_X
= active_entry
->ie_IconX
;
5701 LONG active_entry_Y
;
5702 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
5704 if (active_entry
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
5705 active_entry_X
= active_entry_X
- ((data
->icld_IconAreaLargestWidth
- active_entry
->ie_AreaWidth
)/2);
5707 active_entry_Y
= active_entry
->ie_IconY
;
5713 if ((active_entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
) &&
5714 (active_entry_X
> start_X
) &&
5715 ((active_entry_Y
> start_Y
- 1) &&
5716 (active_entry_Y
< next_Y
)))
5718 #if defined(DEBUG_ILC_KEYEVENTS)
5719 D(bug("[IconList] %s: RIGHT: (A) entry 0x%p matches\n", __PRETTY_FUNCTION__
, active_entry
));
5723 else if (active_entry
== (struct IconEntry
*)GetTail(&data
->icld_IconList
))
5725 #if defined(DEBUG_ILC_KEYEVENTS)
5726 D(bug("[IconList] %s: RIGHT: (A) reached list end .. starting at the beginng ..\n", __PRETTY_FUNCTION__
));
5728 start_Y
= entry_next
->ie_IconY
;
5730 if ((entry_next
= Node_NextVisible(entry_next
)))
5732 if (entry_next
->ie_IconY
< start_Y
)
5736 next_Y
= entry_next
->ie_IconY
;
5740 #if defined(DEBUG_ILC_KEYEVENTS)
5741 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
));
5743 active_entry
= (struct IconEntry
*)GetHead(&data
->icld_IconList
);
5748 if ((active_entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
) &&
5749 (active_entry_X
> start_X
) &&
5750 (active_entry_Y
> start_Y
- 1))
5752 #if defined(DEBUG_ILC_KEYEVENTS)
5753 D(bug("[IconList] %s: RIGHT: (B) entry 0x%p matches\n", __PRETTY_FUNCTION__
, active_entry
));
5761 if (active_entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
5763 #if defined(DEBUG_ILC_KEYEVENTS)
5764 D(bug("[IconList] %s: RIGHT: (C) entry 0x%p matches\n", __PRETTY_FUNCTION__
, active_entry
));
5770 active_entry
= (struct IconEntry
*)GetSucc(&active_entry
->ie_IconNode
);
5773 if (!(active_entry
))
5775 #if defined(DEBUG_ILC_KEYEVENTS)
5776 D(bug("[IconList] %s: RIGHT: No Next RIGHT Node - Getting first visable entry ..\n", __PRETTY_FUNCTION__
));
5778 /* We didnt find a "next RIGHT" entry so just use the first visible */
5779 active_entry
= (struct IconEntry
*)GetHead(&data
->icld_IconList
);
5780 while ((active_entry
!= NULL
) &&(!(active_entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)))
5782 active_entry
= (struct IconEntry
*)GetSucc(&active_entry
->ie_IconNode
);
5788 if (!(active_entry
->ie_Flags
& ICONENTRY_FLAG_FOCUS
))
5790 active_entry
->ie_Flags
|= ICONENTRY_FLAG_FOCUS
;
5791 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
5792 data
->update_entry
= active_entry
;
5793 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
5796 data
->icld_FocusIcon
= active_entry
;
5800 rawkey_handled
= TRUE
;
5802 #if defined(DEBUG_ILC_KEYEVENTS)
5803 D(bug("[IconList] %s: RAWKEY_HOME\n", __PRETTY_FUNCTION__
));
5806 if (data
->icld_FocusIcon
)
5808 data
->icld_FocusIcon
->ie_Flags
&= ~ICONENTRY_FLAG_FOCUS
;
5809 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
5810 data
->update_entry
= data
->icld_FocusIcon
;
5811 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
5814 active_entry
= Node_FirstVisible(&data
->icld_IconList
);
5816 if ((active_entry
) && (!(active_entry
->ie_Flags
& ICONENTRY_FLAG_FOCUS
)))
5818 active_entry
->ie_Flags
|= ICONENTRY_FLAG_FOCUS
;
5819 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
5820 data
->update_entry
= active_entry
;
5821 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_END\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_LastVisible(&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 if (rawkey_handled
) return MUI_EventHandlerRC_Eat
;
5858 case IDCMP_MOUSEBUTTONS
:
5859 #if defined(DEBUG_ILC_EVENTS)
5860 D(bug("[IconList] %s: IDCMP_MOUSEBUTTONS\n", __PRETTY_FUNCTION__
));
5862 if (message
->imsg
->Code
== SELECTDOWN
)
5864 /* Check if mouse pressed on iconlist area */
5865 if (mx
>= 0 && mx
< _width(obj
) && my
>= 0 && my
< _height(obj
))
5867 BOOL doubleclicked
= FALSE
; /* both icon and empty space */
5868 struct IconEntry
*node
= NULL
;
5869 struct IconEntry
*new_selected
= NULL
;
5871 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
5873 /* LIST-VIEW HANDLING */
5875 LONG clickColumn
= -1;
5877 LONG x
= _mleft(obj
) - data
->icld_ViewX
+ LINE_SPACING_LEFT
;
5880 /* Find column in which click happened */
5881 for(i
= 0; i
< NUM_COLUMNS
; i
++)
5883 index
= data
->icld_LVMAttribs
->lmva_ColumnPos
[i
];
5885 if (!(data
->icld_LVMAttribs
->lmva_ColumnFlags
[index
] & LVMCF_COLVISIBLE
)) continue;
5887 w
= data
->icld_LVMAttribs
->lmva_ColumnWidth
[index
];
5889 if ((mx
>= x
) && (mx
< x
+ w
))
5891 clickColumn
= index
;
5897 if (((data
->icld_LVMAttribs
->lvma_Flags
& LVMAF_NOHEADER
) == 0) && (my
<= data
->icld_LVMAttribs
->lmva_HeaderHeight
))
5899 /* Click on header, update list */
5900 data
->icld_LVMAttribs
->lmva_LastSelectedColumn
= clickColumn
;
5902 data
->icld_UpdateMode
= UPDATE_HEADERENTRY
;
5903 data
->update_entry
= (APTR
)(IPTR
)clickColumn
;
5905 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
5910 LONG current
= 0, index
= (my
- data
->icld_LVMAttribs
->lmva_HeaderHeight
+ data
->icld_ViewY
) / data
->icld_LVMAttribs
->lmva_RowHeight
;
5912 /* Check if clicked on entry */
5913 ForeachNode(&data
->icld_IconList
, node
)
5915 if (node
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
5917 /* Is this node clicked? */
5918 if (current
== index
)
5920 new_selected
= node
;
5928 /* Handle actions */
5929 IconList_HandleNewIconSelection(CLASS
, obj
, message
, new_selected
, &doubleclicked
);
5934 /* ICON-VIEW HANDLING */
5936 struct Rectangle rect
;
5938 /* Check if clicked on entry */
5939 #if defined(__AROS__)
5940 ForeachNode(&data
->icld_IconList
, node
)
5942 Foreach_Node(&data
->icld_IconList
, node
);
5945 if (node
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
5947 /* Is this node clicked? */
5948 rect
.MinX
= node
->ie_IconX
;
5949 rect
.MaxX
= node
->ie_IconX
+ node
->ie_AreaWidth
- 1;
5950 rect
.MinY
= node
->ie_IconY
;
5951 rect
.MaxY
= node
->ie_IconY
+ node
->ie_AreaHeight
- 1;
5953 if ((data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
) &&
5954 (node
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
))
5956 rect
.MinX
+= ((data
->icld_IconAreaLargestWidth
- node
->ie_AreaWidth
)/2);
5957 rect
.MaxX
+= ((data
->icld_IconAreaLargestWidth
- node
->ie_AreaWidth
)/2);
5960 if ((((mx
+ data
->icld_ViewX
) >= rect
.MinX
) && ((mx
+ data
->icld_ViewX
) <= rect
.MaxX
)) &&
5961 (((my
+ data
->icld_ViewY
) >= rect
.MinY
) && ((my
+ data
->icld_ViewY
) <= rect
.MaxY
)))
5963 new_selected
= node
;
5964 #if defined(DEBUG_ILC_EVENTS)
5965 D(bug("[IconList] %s: Entry '%s' clicked on ..\n", __PRETTY_FUNCTION__
, node
->ie_IconListEntry
.label
));
5972 /* Handle actions */
5973 IconList_HandleNewIconSelection(CLASS
, obj
, message
, new_selected
, &doubleclicked
);
5976 if (new_selected
&& (new_selected
->ie_Flags
& ICONENTRY_FLAG_SELECTED
))
5977 data
->icld_SelectionLastClicked
= new_selected
;
5979 data
->icld_SelectionLastClicked
= NULL
;
5984 SET(obj
, MUIA_IconList_SelectionChanged
, TRUE
);
5986 data
->icld_ClickEvent
.shift
= !!(message
->imsg
->Qualifier
& (IEQUALIFIER_LSHIFT
| IEQUALIFIER_RSHIFT
));
5987 data
->icld_ClickEvent
.entry
= data
->icld_SelectionLastClicked
? &data
->icld_SelectionLastClicked
->ie_IconListEntry
: NULL
;
5988 SET(obj
, MUIA_IconList_Clicked
, (IPTR
)&data
->icld_ClickEvent
);
5992 SET(obj
, MUIA_IconList_DoubleClick
, TRUE
);
5995 if ((!data
->mouse_pressed
) &&
5996 (!doubleclicked
|| (doubleclicked
&& (data
->icld_SelectionLastClicked
== NULL
))))
5998 data
->last_secs
= message
->imsg
->Seconds
;
5999 data
->last_mics
= message
->imsg
->Micros
;
6001 /* After a double click you often open a new window
6002 * and since Zune doesn't not support the faking
6003 * of SELECTUP events only change the Events
6004 * if not doubleclicked on an icon */
6006 data
->mouse_pressed
|= LEFT_BUTTON
;
6008 /* Start listening to mouse events */
6009 if (!(data
->ehn
.ehn_Events
& IDCMP_MOUSEMOVE
))
6011 DoMethod(_win(obj
), MUIM_Window_RemEventHandler
, (IPTR
)&data
->ehn
);
6012 data
->ehn
.ehn_Events
|= IDCMP_MOUSEMOVE
;
6013 DoMethod(_win(obj
), MUIM_Window_AddEventHandler
, (IPTR
)&data
->ehn
);
6017 return MUI_EventHandlerRC_Eat
;
6020 else if (message
->imsg
->Code
== MIDDLEDOWN
)
6022 if (!data
->mouse_pressed
)
6024 data
->mouse_pressed
|= MIDDLE_BUTTON
;
6026 data
->click_x
= data
->icld_ViewX
+ mx
;
6027 data
->click_y
= data
->icld_ViewY
+ my
;
6029 /* Start listening to mouse events */
6030 if (!(data
->ehn
.ehn_Events
& IDCMP_MOUSEMOVE
))
6032 DoMethod(_win(obj
), MUIM_Window_RemEventHandler
, (IPTR
)&data
->ehn
);
6033 data
->ehn
.ehn_Events
|= IDCMP_MOUSEMOVE
;
6034 DoMethod(_win(obj
), MUIM_Window_AddEventHandler
, (IPTR
)&data
->ehn
);
6040 if (message
->imsg
->Code
== SELECTUP
)
6042 if (data
->icld_LassoActive
== TRUE
)
6044 #if defined(DEBUG_ILC_EVENTS) || defined(DEBUG_ILC_LASSO)
6045 D(bug("[IconList] %s: Removing Lasso\n", __PRETTY_FUNCTION__
));
6047 /* End Lasso-selection */
6048 struct Rectangle old_lasso
;
6049 struct IconEntry
*node
= NULL
;
6050 struct Window
*thisWindow
= NULL
;
6052 /* Stop handling INTUITICKS */
6053 GET(obj
, MUIA_Window
, &thisWindow
);
6056 ModifyIDCMP(thisWindow
, (thisWindow
->IDCMPFlags
& ~(IDCMP_INTUITICKS
)));
6057 if ((data
->ehn
.ehn_Events
& IDCMP_INTUITICKS
))
6059 DoMethod(_win(obj
), MUIM_Window_RemEventHandler
, (IPTR
)&data
->ehn
);
6060 data
->ehn
.ehn_Events
&= ~IDCMP_INTUITICKS
;
6061 DoMethod(_win(obj
), MUIM_Window_AddEventHandler
, (IPTR
)&data
->ehn
);
6064 /* Clear Lasso Frame.. */
6065 GetAbsoluteLassoRect(data
, &old_lasso
);
6066 IconList_InvertLassoOutlines(obj
, data
, &old_lasso
);
6068 data
->icld_LassoActive
= FALSE
;
6070 /* Remove Lasso flag from affected icons.. */
6071 #if defined(__AROS__)
6072 ForeachNode(&data
->icld_IconList
, node
)
6074 Foreach_Node(&data
->icld_IconList
, node
);
6077 if (node
->ie_Flags
& ICONENTRY_FLAG_LASSO
)
6079 node
->ie_Flags
&= ~ICONENTRY_FLAG_LASSO
;
6082 SET(obj
, MUIA_IconList_SelectionChanged
, TRUE
);
6084 else if (data
->icld_LVMAttribs
->lmva_LastSelectedColumn
!= -1)
6086 ULONG orig_sortflags
= data
->icld_SortFlags
;
6088 if (data
->icld_LVMAttribs
->lmva_SortColumn
== data
->icld_LVMAttribs
->lmva_LastSelectedColumn
)
6090 if (data
->icld_SortFlags
& MUIV_IconList_Sort_Reverse
)
6091 data
->icld_SortFlags
&= ~MUIV_IconList_Sort_Reverse
;
6093 data
->icld_SortFlags
|= MUIV_IconList_Sort_Reverse
;
6096 switch (data
->icld_LVMAttribs
->lmva_LastSelectedColumn
)
6099 data
->icld_SortFlags
&= ~MUIV_IconList_Sort_Orders
;
6100 data
->icld_SortFlags
|= MUIV_IconList_Sort_ByName
;
6104 data
->icld_SortFlags
&= ~MUIV_IconList_Sort_Orders
;
6105 data
->icld_SortFlags
|= MUIV_IconList_Sort_BySize
;
6108 case INDEX_LASTACCESS
:
6109 data
->icld_SortFlags
&= ~MUIV_IconList_Sort_Orders
;
6110 data
->icld_SortFlags
|= MUIV_IconList_Sort_ByDate
;
6114 if (orig_sortflags
!= data
->icld_SortFlags
)
6116 data
->icld_LVMAttribs
->lmva_SortColumn
= data
->icld_LVMAttribs
->lmva_LastSelectedColumn
;
6118 data
->icld_LVMAttribs
->lmva_LastSelectedColumn
= -1;
6120 DoMethod(obj
, MUIM_IconList_Sort
);
6124 data
->mouse_pressed
&= ~LEFT_BUTTON
;
6127 if (message
->imsg
->Code
== MIDDLEUP
)
6129 data
->mouse_pressed
&= ~MIDDLE_BUTTON
;
6132 /* Stop listening to mouse move events is no buttons pressed */
6133 if ((data
->ehn
.ehn_Events
& IDCMP_MOUSEMOVE
) && !data
->mouse_pressed
)
6135 DoMethod(_win(obj
),MUIM_Window_RemEventHandler
, (IPTR
)&data
->ehn
);
6136 data
->ehn
.ehn_Events
&= ~IDCMP_MOUSEMOVE
;
6137 DoMethod(_win(obj
),MUIM_Window_AddEventHandler
, (IPTR
)&data
->ehn
);
6142 case IDCMP_INTUITICKS
:
6144 #if defined(DEBUG_ILC_EVENTS)
6145 D(bug("[IconList] %s: IDCMP_INTUITICKS (%d, %d)\n", __PRETTY_FUNCTION__
, mx
, my
));
6147 if ((data
->icld_LassoActive
== FALSE
)||(!(data
->mouse_pressed
& LEFT_BUTTON
)))
6151 if (((mx
>= 0) && (mx
<= _mwidth(obj
))) &&
6152 ((my
>= 0) && (my
<= _mheight(obj
))))
6156 case IDCMP_MOUSEMOVE
:
6157 #if defined(DEBUG_ILC_EVENTS)
6158 D(bug("[IconList] %s: IDCMP_MOUSEMOVE\n", __PRETTY_FUNCTION__
));
6160 if (data
->mouse_pressed
& LEFT_BUTTON
)
6165 if (data
->icld_SelectionLastClicked
&& (data
->icld_LassoActive
== FALSE
) &&
6166 ((abs(move_x
- data
->click_x
) >= 2) || (abs(move_y
- data
->click_y
) >= 2)))
6168 LONG touch_x
, touch_y
;
6170 /* Entry(s) being dragged .... */
6171 DoMethod(_win(obj
),MUIM_Window_RemEventHandler
, (IPTR
)&data
->ehn
);
6172 data
->ehn
.ehn_Events
&= ~IDCMP_MOUSEMOVE
;
6173 DoMethod(_win(obj
),MUIM_Window_AddEventHandler
, (IPTR
)&data
->ehn
);
6175 data
->mouse_pressed
&= ~LEFT_BUTTON
;
6177 /* Pass view relative coords */
6178 touch_x
= move_x
+ data
->icld_ViewX
;
6179 touch_y
= move_y
+ data
->icld_ViewY
;
6180 DoMethod(obj
,MUIM_DoDrag
, touch_x
, touch_y
, 0);
6182 else if (data
->icld_LassoActive
== TRUE
)
6184 #if defined(DEBUG_ILC_EVENTS) || defined(DEBUG_ILC_LASSO)
6185 D(bug("[IconList] %s: Update Lasso\n", __PRETTY_FUNCTION__
));
6188 struct Rectangle new_lasso
,
6190 struct Rectangle iconrect
;
6192 struct IconEntry
*node
= NULL
;
6193 // struct IconEntry *new_selected = NULL;
6195 /* Remove previous Lasso frame */
6196 GetAbsoluteLassoRect(data
, &old_lasso
);
6197 IconList_InvertLassoOutlines(obj
, data
, &old_lasso
);
6199 /* if the mouse leaves our visible area scroll the view */
6200 if (mx
< 0 || mx
>= _mwidth(obj
) || my
< 0 || my
>= _mheight(obj
))
6202 LONG newleft
= data
->icld_ViewX
;
6203 LONG newtop
= data
->icld_ViewY
;
6205 if (mx
>= _mwidth(obj
)) newleft
+= (mx
- _mwidth(obj
));
6206 else if (mx
< 0) newleft
+= mx
;
6207 if (my
>= _mheight(obj
)) newtop
+= (my
- _mheight(obj
));
6208 else if (my
< 0) newtop
+= my
;
6210 if (newleft
+ _mwidth(obj
) > data
->icld_AreaWidth
) newleft
= data
->icld_AreaWidth
- _mwidth(obj
);
6211 if (newleft
< 0) newleft
= 0;
6213 if (newtop
+ _mheight(obj
) > data
->icld_AreaHeight
) newtop
= data
->icld_AreaHeight
- _mheight(obj
);
6214 if (newtop
< 0) newtop
= 0;
6216 if ((newleft
!= data
->icld_ViewX
) || (newtop
!= data
->icld_ViewY
))
6218 SetAttrs(obj
, MUIA_Virtgroup_Left
, newleft
, MUIA_Virtgroup_Top
, newtop
, TAG_DONE
);
6222 /* update Lasso coordinates */
6223 data
->icld_LassoRectangle
.MaxX
= mx
- data
->view_rect
.MinX
+ data
->icld_ViewX
;
6224 data
->icld_LassoRectangle
.MaxY
= my
- data
->view_rect
.MinY
+ data
->icld_ViewY
;
6226 /* get absolute Lasso coordinates */
6227 GetAbsoluteLassoRect(data
, &new_lasso
);
6229 LONG current
= 0, startIndex
= 0, endIndex
= 0;
6231 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
6233 LONG minY
= data
->icld_LassoRectangle
.MinY
,
6234 maxY
= data
->icld_LassoRectangle
.MaxY
;
6243 startIndex
= ((minY
+ 1) - data
->icld_LVMAttribs
->lmva_HeaderHeight
) / data
->icld_LVMAttribs
->lmva_RowHeight
;
6244 endIndex
= ((maxY
- 1) - data
->icld_LVMAttribs
->lmva_HeaderHeight
) / data
->icld_LVMAttribs
->lmva_RowHeight
;
6247 #if defined(__AROS__)
6248 ForeachNode(&data
->icld_IconList
, node
)
6250 Foreach_Node(&data
->icld_IconList
, node
);
6253 IPTR update_entry
= (IPTR
)NULL
;
6255 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
6257 if (node
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
6259 update_entry
= FALSE
;
6261 if ((current
>= startIndex
) && (current
<= endIndex
))
6263 //Entry is inside our lasso ..
6264 if (!(node
->ie_Flags
& ICONENTRY_FLAG_LASSO
))
6266 /* check if entry was already selected before */
6267 if (node
->ie_Flags
& ICONENTRY_FLAG_SELECTED
)
6269 Remove(&node
->ie_SelectionNode
);
6270 node
->ie_Flags
&= ~ICONENTRY_FLAG_SELECTED
;
6274 AddTail(&data
->icld_SelectionList
, &node
->ie_SelectionNode
);
6275 node
->ie_Flags
|= ICONENTRY_FLAG_SELECTED
;
6277 node
->ie_Flags
|= ICONENTRY_FLAG_LASSO
;
6278 update_entry
= (IPTR
)node
;
6281 else if (node
->ie_Flags
& ICONENTRY_FLAG_LASSO
)
6283 //Entry is no longer inside our lasso - revert its selected state
6284 if (node
->ie_Flags
& ICONENTRY_FLAG_SELECTED
)
6286 Remove(&node
->ie_SelectionNode
);
6287 node
->ie_Flags
&= ~ICONENTRY_FLAG_SELECTED
;
6291 AddTail(&data
->icld_SelectionList
, &node
->ie_SelectionNode
);
6292 node
->ie_Flags
|= ICONENTRY_FLAG_SELECTED
;
6294 node
->ie_Flags
&= ~ICONENTRY_FLAG_LASSO
;
6295 update_entry
= (IPTR
)node
;
6303 if (node
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
6305 iconrect
.MinX
= node
->ie_IconX
;
6306 iconrect
.MaxX
= node
->ie_IconX
+ node
->ie_AreaWidth
- 1;
6307 iconrect
.MinY
= node
->ie_IconY
;
6308 iconrect
.MaxY
= node
->ie_IconY
+ node
->ie_AreaHeight
- 1;
6309 if ((data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
) &&
6310 (node
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
))
6312 iconrect
.MinX
+= ((data
->icld_IconAreaLargestWidth
- node
->ie_AreaWidth
)/2);
6313 iconrect
.MaxX
+= ((data
->icld_IconAreaLargestWidth
- node
->ie_AreaWidth
)/2);
6316 if ((((new_lasso
.MaxX
+ data
->icld_ViewX
) >= iconrect
.MinX
) && ((new_lasso
.MinX
+ data
->icld_ViewX
) <= iconrect
.MaxX
)) &&
6317 (((new_lasso
.MaxY
+ data
->icld_ViewY
) >= iconrect
.MinY
) && ((new_lasso
.MinY
+ data
->icld_ViewY
) <= iconrect
.MaxY
)))
6319 //Entry is inside our lasso ..
6320 if (!(node
->ie_Flags
& ICONENTRY_FLAG_LASSO
))
6322 /* check if entry was already selected before */
6323 if (node
->ie_Flags
& ICONENTRY_FLAG_SELECTED
)
6325 Remove(&node
->ie_SelectionNode
);
6326 node
->ie_Flags
&= ~ICONENTRY_FLAG_SELECTED
;
6330 AddTail(&data
->icld_SelectionList
, &node
->ie_SelectionNode
);
6331 node
->ie_Flags
|= ICONENTRY_FLAG_SELECTED
;
6333 node
->ie_Flags
|= ICONENTRY_FLAG_LASSO
;
6334 update_entry
= (IPTR
)node
;
6337 else if (node
->ie_Flags
& ICONENTRY_FLAG_LASSO
)
6339 //Entry is no longer inside our lasso - revert its selected state
6340 if (node
->ie_Flags
& ICONENTRY_FLAG_SELECTED
)
6342 Remove(&node
->ie_SelectionNode
);
6343 node
->ie_Flags
&= ~ICONENTRY_FLAG_SELECTED
;
6347 AddTail(&data
->icld_SelectionList
, &node
->ie_SelectionNode
);
6348 node
->ie_Flags
|= ICONENTRY_FLAG_SELECTED
;
6350 node
->ie_Flags
&= ~ICONENTRY_FLAG_LASSO
;
6351 update_entry
= (IPTR
)node
;
6357 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
6358 data
->update_entry
= (struct IconEntry
*)update_entry
;
6359 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
6362 /* Draw Lasso frame */
6363 IconList_InvertLassoOutlines(obj
, data
, &new_lasso
);
6366 return MUI_EventHandlerRC_Eat
;
6368 else if (data
->mouse_pressed
& MIDDLE_BUTTON
)
6370 /* Content is being scrolled */
6371 LONG newleft
, newtop
;
6373 newleft
= data
->click_x
- mx
;
6374 newtop
= data
->click_y
- my
;
6376 if (newleft
+ _mwidth(obj
) > data
->icld_AreaWidth
) newleft
= data
->icld_AreaWidth
- _mwidth(obj
);
6377 if (newleft
< 0) newleft
= 0;
6379 if (newtop
+ _mheight(obj
) > data
->icld_AreaHeight
) newtop
= data
->icld_AreaHeight
- _mheight(obj
);
6380 if (newtop
< 0) newtop
= 0;
6382 if ((newleft
!= data
->icld_ViewX
) || (newtop
!= data
->icld_ViewY
))
6384 SetAttrs(obj
, MUIA_Virtgroup_Left
, newleft
,
6385 MUIA_Virtgroup_Top
, newtop
,
6389 return MUI_EventHandlerRC_Eat
;
6400 ///MUIM_IconList_NextIcon()
6401 /**************************************************************************
6402 MUIM_IconList_NextIcon
6403 **************************************************************************/
6404 IPTR
IconList__MUIM_IconList_NextIcon(struct IClass
*CLASS
, Object
*obj
, struct MUIP_IconList_NextIcon
*message
)
6406 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
6407 struct IconEntry
*node
= NULL
;
6408 struct IconList_Entry
*ent
= NULL
;
6409 IPTR node_successor
= (IPTR
)NULL
;
6411 if (message
->entry
== NULL
) return (IPTR
)NULL
;
6412 ent
= *message
->entry
;
6414 #if defined(DEBUG_ILC_FUNCS)
6415 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
6418 if ((IPTR
)ent
== (IPTR
)MUIV_IconList_NextIcon_Start
)
6420 D(bug("[IconList] %s: Finding First Entry ..\n", __PRETTY_FUNCTION__
));
6421 if (message
->nextflag
== MUIV_IconList_NextIcon_Selected
)
6423 node
= (struct IconEntry
*)GetHead(&data
->icld_SelectionList
);
6426 node
= (struct IconEntry
*)((IPTR
)node
- ((IPTR
)&node
->ie_SelectionNode
- (IPTR
)node
));
6429 else if (message
->nextflag
== MUIV_IconList_NextIcon_Visible
)
6431 node
= (struct IconEntry
*)GetHead(&data
->icld_IconList
);
6432 while (node
!= NULL
)
6434 if (node
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
6437 node
= (struct IconEntry
*)GetSucc(&node
->ie_IconNode
);
6441 else if ((IPTR
)ent
!= (IPTR
)MUIV_IconList_NextIcon_End
)
6443 node
= (struct IconEntry
*)((IPTR
)ent
- ((IPTR
)&node
->ie_IconListEntry
- (IPTR
)node
));
6444 if (message
->nextflag
== MUIV_IconList_NextIcon_Selected
)
6446 node_successor
= (IPTR
)GetSucc(&node
->ie_SelectionNode
);
6447 if (node_successor
!= (IPTR
)NULL
)
6448 node
= (struct IconEntry
*)((IPTR
)node_successor
- ((IPTR
)&node
->ie_SelectionNode
- (IPTR
)node
));
6451 D(bug("[IconList] %s: GetSucc() == NULL\n", __PRETTY_FUNCTION__
));
6455 else if (message
->nextflag
== MUIV_IconList_NextIcon_Visible
)
6457 node
= (struct IconEntry
*)GetSucc(&node
->ie_IconNode
);
6458 while (node
!= NULL
)
6460 if (node
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
6463 node
= (struct IconEntry
*)GetSucc(&node
->ie_IconNode
);
6470 D(bug("[IconList] %s: Returning MUIV_IconList_NextIcon_End\n", __PRETTY_FUNCTION__
));
6472 *message
->entry
= (struct IconList_Entry
*)MUIV_IconList_NextIcon_End
;
6476 D(bug("[IconList] %s: Returning entry for '%s'\n", __PRETTY_FUNCTION__
, node
->ie_IconListEntry
.label
));
6478 *message
->entry
= &node
->ie_IconListEntry
;
6485 ///MUIM_IconList_GetIconPrivate()
6486 /**************************************************************************
6487 MUIM_IconList_GetIconPrivate
6488 **************************************************************************/
6489 IPTR
IconList__MUIM_IconList_GetIconPrivate(struct IClass
*CLASS
, Object
*obj
, struct MUIP_IconList_GetIconPrivate
*message
)
6491 // struct IconList_DATA *data = INST_DATA(CLASS, obj);
6492 struct IconEntry
*node
= NULL
;
6494 if (message
->entry
== NULL
) return (IPTR
)NULL
;
6496 node
= (struct IconEntry
*)((IPTR
)message
->entry
- ((IPTR
)&node
->ie_IconListEntry
- (IPTR
)node
));
6501 ///MUIM_CreateDragImage()
6502 /**************************************************************************
6503 MUIM_CreateDragImage
6504 **************************************************************************/
6505 IPTR
IconList__MUIM_CreateDragImage(struct IClass
*CLASS
, Object
*obj
, struct MUIP_CreateDragImage
*message
)
6507 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
6508 struct MUI_DragImage
*img
= NULL
;
6511 BOOL transp
= XGET(obj
, MUIA_IconList_DragImageTransparent
);
6513 #if defined(DEBUG_ILC_FUNCS) || defined(DEBUG_ILC_ICONDRAGDROP)
6514 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
6517 if (!(data
->icld_SelectionLastClicked
))
6518 DoSuperMethodA(CLASS
, obj
, (Msg
)message
);
6520 if ((img
= (struct MUI_DragImage
*)AllocVec(sizeof(struct MUIP_CreateDragImage
), MEMF_CLEAR
)))
6522 struct Node
*node
= NULL
;
6523 struct IconEntry
*entry
= NULL
;
6525 #if defined(CREATE_FULL_DRAGIMAGE)
6526 #if defined(__AROS__)
6527 ForeachNode(&data
->icld_SelectionList
, node
)
6529 Foreach_Node(&data
->icld_SelectionList
, node
);
6532 entry
= (struct IconEntry
*)((IPTR
)node
- ((IPTR
)&entry
->ie_SelectionNode
- (IPTR
)entry
));
6533 if ((entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
) && (entry
->ie_Flags
& ICONENTRY_FLAG_SELECTED
))
6535 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) != ICONLIST_DISP_MODELIST
)
6537 if ((first_x
== -1) || ((first_x
!= -1) && (entry
->ie_IconX
< first_x
))) first_x
= entry
->ie_IconX
;
6538 if ((first_y
== -1) || ((first_y
!= -1) && (entry
->ie_IconY
< first_y
))) first_y
= entry
->ie_IconY
;
6540 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_ROUGH
)
6542 if ((entry
->ie_IconX
+ entry
->ie_AreaWidth
) > img
->width
) img
->width
= entry
->ie_IconX
+ entry
->ie_AreaWidth
;
6543 if ((entry
->ie_IconY
+ entry
->ie_AreaHeight
) > img
->height
) img
->height
= entry
->ie_IconY
+ entry
->ie_AreaHeight
;
6546 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
6548 if ((entry
->ie_IconX
+ data
->icld_IconAreaLargestWidth
) > img
->width
) img
->width
= entry
->ie_IconX
+ data
->icld_IconAreaLargestWidth
;
6549 if ((entry
->ie_IconY
+ data
->icld_IconAreaLargestHeight
) > img
->height
) img
->height
= entry
->ie_IconY
+ data
->icld_IconAreaLargestHeight
;
6554 img
->height
+= data
->icld_LVMAttribs
->lmva_RowHeight
;
6558 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
6561 first_y
= -message
->touchy
;
6562 img
->width
= data
->icld_LVMAttribs
->lmva_ColumnWidth
[data
->icld_LVMAttribs
->lmva_ColumnPos
[INDEX_TYPE
]] +
6563 data
->icld_LVMAttribs
->lmva_ColumnWidth
[data
->icld_LVMAttribs
->lmva_ColumnPos
[INDEX_NAME
]];
6568 img
->width
= (img
->width
- first_x
) + 2;
6569 img
->height
= (img
->height
- first_y
) + 2;
6572 entry
= data
->icld_SelectionLastClicked
;
6573 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
6575 img
->width
= _mright(obj
) - _mleft(obj
);
6576 img
->height
= data
->icld_LVMAttribs
->lmva_RowHeight
;
6582 img
->width
= entry
->ie_IconWidth
;
6583 img
->height
= entry
->ie_IconHeight
;
6584 first_x
= entry
->ie_IconX
;
6585 first_y
= entry
->ie_IconY
;
6591 /* Request 32-bit, because the image will have alpha channel */
6592 img
->bm
= AllocBitMap(img
->width
, img
->height
, 32, BMF_CLEAR
, NULL
);
6596 LONG depth
= GetBitMapAttr(_screen(obj
)->RastPort
.BitMap
, BMA_DEPTH
);
6597 img
->bm
= AllocBitMap(img
->width
, img
->height
, depth
, BMF_CLEAR
, _screen(obj
)->RastPort
.BitMap
);
6602 struct RastPort temprp
;
6603 InitRastPort(&temprp
);
6604 temprp
.BitMap
= img
->bm
;
6607 #if defined(CREATE_FULL_DRAGIMAGE)
6608 ForeachNode(&data
->icld_SelectionList
, node
)
6610 entry
= (struct IconEntry
*)((IPTR
)node
- ((IPTR
)&entry
->ie_SelectionNode
- (IPTR
)entry
));
6611 if ((entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
) && (entry
->ie_Flags
& ICONENTRY_FLAG_SELECTED
))
6613 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
6615 struct Rectangle field_rect
;
6616 ULONG selected
= entry
->ie_Flags
& ICONENTRY_FLAG_SELECTED
;
6617 entry
->ie_Flags
&= ~ICONENTRY_FLAG_SELECTED
; /* Drawing as not selected actually looks better */
6619 field_rect
.MinX
= 0; field_rect
.MaxX
= img
->width
- 1;
6620 field_rect
.MinY
= minY
; field_rect
.MaxY
= field_rect
.MinY
+ data
->icld_LVMAttribs
->lmva_RowHeight
- 1;
6621 RenderEntryField(obj
, data
, entry
, &field_rect
, INDEX_TYPE
, TRUE
, FALSE
, &temprp
);
6623 field_rect
.MinX
= data
->icld_LVMAttribs
->lmva_ColumnWidth
[data
->icld_LVMAttribs
->lmva_ColumnPos
[INDEX_TYPE
]] - 1;
6624 field_rect
.MaxX
= img
->width
- 1;
6625 field_rect
.MinY
= minY
; field_rect
.MaxY
= field_rect
.MinY
+ data
->icld_LVMAttribs
->lmva_RowHeight
- 1;
6626 RenderEntryField(obj
, data
, entry
, &field_rect
, INDEX_NAME
, FALSE
, FALSE
, &temprp
);
6628 minY
+= data
->icld_LVMAttribs
->lmva_RowHeight
;
6630 entry
->ie_Flags
|= selected
;
6634 LONG offsetx
, offsety
;
6636 IconList_GetIconImageOffsets(data
, entry
, &offsetx
, &offsety
);
6640 &temprp
, entry
->ie_DiskObj
, NULL
,
6641 (entry
->ie_IconX
+ 1) - first_x
+ offsetx
, (entry
->ie_IconY
+ 1) - first_y
+ offsety
,
6643 __iconList_DrawIconStateTags
6649 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
6651 SetABPenDrMd(&temprp
, _pens(obj
)[MPEN_SHINE
], 0, JAM1
);
6652 RectFill(&temprp
, 0, 0, img
->width
, img
->height
);
6658 &temprp
, entry
->ie_DiskObj
, NULL
,
6661 __iconList_DrawIconStateTags
6666 RastPortSetAlpha(&temprp
, data
->click_x
, data
->click_y
, img
->width
, img
->height
, 0xC0, RPALPHAFLAT
);
6667 DeinitRastPort(&temprp
);
6670 /* Convert view relative coords to drag image relative. This is done because the "object" that is being
6671 * dragged is virtual (its a collection of icons) and the coords passed to DoDrag are not relative to this
6674 img
->touchx
= first_x
+ message
->touchx
;
6675 img
->touchy
= first_y
+ message
->touchy
;
6678 img
->flags
= MUIF_DRAGIMAGE_SOURCEALPHA
;
6686 ///MUIM_DeleteDragImage()
6687 /**************************************************************************
6688 MUIM_DeleteDragImage
6689 **************************************************************************/
6690 IPTR
IconList__MUIM_DeleteDragImage(struct IClass
*CLASS
, Object
*obj
, struct MUIP_DeleteDragImage
*message
)
6692 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
6694 #if defined(DEBUG_ILC_FUNCS) || defined(DEBUG_ILC_ICONDRAGDROP)
6695 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
6698 if (!(data
->icld_SelectionLastClicked
)) return DoSuperMethodA(CLASS
,obj
,(Msg
)message
);
6702 if (message
->di
->bm
)
6703 FreeBitMap(message
->di
->bm
);
6704 FreeVec(message
->di
);
6711 /**************************************************************************
6713 **************************************************************************/
6714 IPTR
IconList__MUIM_DragQuery(struct IClass
*CLASS
, Object
*obj
, struct MUIP_DragQuery
*message
)
6716 #if defined(DEBUG_ILC_FUNCS) || defined(DEBUG_ILC_ICONDRAGDROP)
6717 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
6720 /* TODO: highlight the possible drop target entry .. */
6722 if (message
->obj
== obj
)
6723 return MUIV_DragQuery_Accept
;
6726 BOOL is_iconlist
= FALSE
;
6727 struct IClass
*msg_cl
= OCLASS(message
->obj
);
6731 if (msg_cl
== CLASS
)
6736 msg_cl
= msg_cl
->cl_Super
;
6739 return MUIV_DragQuery_Accept
;
6742 return MUIV_DragQuery_Refuse
;
6747 /**************************************************************************
6749 **************************************************************************/
6750 IPTR
IconList__MUIM_DragDrop(struct IClass
*CLASS
, Object
*obj
, struct MUIP_DragDrop
*message
)
6752 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
6754 #if defined(DEBUG_ILC_FUNCS) || defined(DEBUG_ILC_ICONDRAGDROP)
6755 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
6758 struct IconList_Entry
*entry
= (IPTR
)MUIV_IconList_NextIcon_Start
;
6760 if (data
->icld_DragDropEvent
)
6762 struct IconList_Drop_SourceEntry
*clean_node
;
6763 #if defined(DEBUG_ILC_ICONDRAGDROP)
6764 D(bug("[IconList] %s: Cleaning existing IconList_Drop_Event @ %p\n", __PRETTY_FUNCTION__
, data
->icld_DragDropEvent
));
6766 while ((clean_node
= (struct IconList_Drop_SourceEntry
*)RemTail(&data
->icld_DragDropEvent
->drop_SourceList
)) != NULL
)
6768 FreeVec(clean_node
->dropse_Node
.ln_Name
);
6769 FreeMem(clean_node
, sizeof(struct IconList_Drop_SourceEntry
));
6771 if (data
->icld_DragDropEvent
->drop_TargetPath
) FreeVec(data
->icld_DragDropEvent
->drop_TargetPath
);
6772 FreeMem(data
->icld_DragDropEvent
, sizeof(struct IconList_Drop_Event
));
6773 data
->icld_DragDropEvent
= NULL
;
6776 /* SANITY CHECK: Get first selected entry from SOURCE iconlist */
6777 DoMethod(message
->obj
, MUIM_IconList_NextIcon
, MUIV_IconList_NextIcon_Selected
, (IPTR
)&entry
);
6779 if ((entry
) && ((IPTR
)entry
!= MUIV_IconList_NextIcon_End
))
6781 /* Ok.. atleast one entry was dropped .. */
6782 char tmp_dirbuff
[256];
6783 BPTR tmp_dirlock
= (BPTR
) NULL
;
6785 BOOL iconMove
= FALSE
;
6786 struct IconEntry
*node
= NULL
;
6787 struct IconEntry
*drop_target_node
= NULL
;
6788 STRPTR directory_path
= NULL
;
6789 struct IconList_Drop_Event
*dragDropEvent
= NULL
;
6791 GET(obj
, MUIA_IconDrawerList_Drawer
, &directory_path
);
6793 /* Properly expand the name incase it uses devices rather than volumes */
6794 if (directory_path
!= NULL
)
6796 tmp_dirlock
= Lock(directory_path
, SHARED_LOCK
);
6799 if (NameFromLock(tmp_dirlock
, tmp_dirbuff
, 256) != 0)
6801 directory_path
= tmp_dirbuff
;
6803 UnLock(tmp_dirlock
);
6806 if ((dragDropEvent
= AllocMem(sizeof(struct IconList_Drop_Event
), MEMF_CLEAR
)) == NULL
)
6808 #if defined(DEBUG_ILC_ICONDRAGDROP)
6809 D(bug("[IconList] %s: Failed to allocate IconList_Drop_Event Storage!\n", __PRETTY_FUNCTION__
));
6813 #if defined(DEBUG_ILC_ICONDRAGDROP)
6814 D(bug("[IconList] %s: Allocated IconList_Drop_Event @ %p\n", __PRETTY_FUNCTION__
, dragDropEvent
));
6817 NewList(&dragDropEvent
->drop_SourceList
);
6819 /* go through list and check if dropped on entry */
6822 #if defined(__AROS__)
6823 ForeachNode(&data
->icld_IconList
, node
)
6825 Foreach_Node(&data
->icld_IconList
, node
);
6828 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
6830 if (node
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
6832 ULONG rowTop
= _mtop(obj
) + (rowCount
* data
->icld_LVMAttribs
->lmva_RowHeight
);
6833 rowTop
+= data
->icld_LVMAttribs
->lmva_HeaderHeight
;
6835 if (((message
->x
> _mleft(obj
)) && (message
->x
< _mright(obj
)))
6836 && ((message
->y
> rowTop
) && (message
->y
< (rowTop
+ data
->icld_LVMAttribs
->lmva_RowHeight
))))
6838 drop_target_node
= node
;
6847 struct Rectangle iconbox
;
6848 LONG click_x
= message
->x
- _mleft(obj
);
6849 LONG click_y
= message
->y
- _mtop(obj
);
6850 iconbox
.MinX
= node
->ie_IconX
- data
->icld_ViewX
;
6851 iconbox
.MaxX
= (node
->ie_IconX
+ node
->ie_AreaWidth
) - data
->icld_ViewX
;
6852 iconbox
.MinY
= node
->ie_IconY
- data
->icld_ViewY
;
6853 iconbox
.MaxY
= (node
->ie_IconY
+ node
->ie_AreaHeight
)- data
->icld_ViewY
;
6855 if ((node
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
) &&
6856 (click_x
>= iconbox
.MinX
) &&
6857 (click_x
< iconbox
.MaxX
) &&
6858 (click_y
>= iconbox
.MinY
) &&
6859 (click_y
< iconbox
.MaxY
))
6861 drop_target_node
= node
;
6867 /* Additional filter - if same window and the target entry is selected (==dragged), then it was intended as a move */
6868 if ((message
->obj
== obj
) && (drop_target_node
) && (drop_target_node
->ie_Flags
& ICONENTRY_FLAG_SELECTED
))
6869 drop_target_node
= NULL
;
6871 if ((drop_target_node
!= NULL
) &&
6872 ((drop_target_node
->ie_IconListEntry
.type
== ST_SOFTLINK
) ||
6873 (drop_target_node
->ie_IconListEntry
.type
== ST_ROOT
) ||
6874 (drop_target_node
->ie_IconListEntry
.type
== ST_USERDIR
) ||
6875 (drop_target_node
->ie_IconListEntry
.type
== ST_LINKDIR
) ||
6876 (drop_target_node
->ie_IconListEntry
.type
== ST_FILE
) ||
6877 (drop_target_node
->ie_IconListEntry
.type
== ST_LINKFILE
)))
6879 /* Dropped on some entry */
6880 if ((drop_target_node
->ie_IconListEntry
.type
!= ST_ROOT
) && (drop_target_node
->ie_IconListEntry
.type
!= ST_SOFTLINK
))
6884 int fulllen
= strlen(directory_path
) + strlen(drop_target_node
->ie_IconListEntry
.label
) + 2;
6886 if ((dragDropEvent
->drop_TargetPath
= AllocVec(fulllen
, MEMF_CLEAR
)) == NULL
)
6888 bug("[IconList] %s: Failed to allocate IconList_Drop_Event->drop_TargetPath Storage!\n", __PRETTY_FUNCTION__
);
6891 strcpy(dragDropEvent
->drop_TargetPath
, directory_path
);
6892 AddPart(dragDropEvent
->drop_TargetPath
, drop_target_node
->ie_IconListEntry
.label
, fulllen
);
6899 if ((dragDropEvent
->drop_TargetPath
= AllocVec(strlen(drop_target_node
->ie_IconListEntry
.label
) + 1, MEMF_CLEAR
)) == NULL
)
6901 bug("[IconList] %s: Failed to allocate IconList_Drop_Event->drop_TargetPath Storage!\n", __PRETTY_FUNCTION__
);
6904 strcpy(dragDropEvent
->drop_TargetPath
, drop_target_node
->ie_IconListEntry
.label
);
6907 #if defined(DEBUG_ILC_ICONDRAGDROP)
6908 D(bug("[IconList] %s: Target Entry Full Path = '%s'\n", __PRETTY_FUNCTION__
, dragDropEvent
->drop_TargetPath
));
6910 /* mark the Entry the selection was dropped on*/
6911 //drop_target_node->ie_Flags |= ICONENTRY_FLAG_SELECTED;
6912 //data->icld_UpdateMode = UPDATE_SINGLEENTRY;
6913 //data->update_entry = drop_target_node;
6914 //MUI_Redraw(obj,MADF_DRAWUPDATE);
6918 /* Not dropped on entry -> get path of DESTINATION iconlist */
6919 /* Note: directory_path is NULL when dropped on Wanderer's desktop */
6920 if ((message
->obj
!= obj
) && directory_path
)
6922 #if defined(DEBUG_ILC_ICONDRAGDROP)
6923 D(bug("[IconList] %s: drop entry: Icons dropped in window '%s'\n", __PRETTY_FUNCTION__
, directory_path
));
6926 if ((dragDropEvent
->drop_TargetPath
= AllocVec(strlen(directory_path
) + 1, MEMF_CLEAR
)) != NULL
)
6928 strcpy(dragDropEvent
->drop_TargetPath
, directory_path
);
6932 #if defined(DEBUG_ILC_ICONDRAGDROP)
6933 D(bug("[IconList] %s: Failed to allocate IconList_Drop_Event->drop_TargetPath Storage!\n", __PRETTY_FUNCTION__
));
6938 else if (message
->obj
== obj
)
6940 #if defined(DEBUG_ILC_ICONDRAGDROP)
6941 D(bug("[IconList] %s: drop entry: Entry Move detected ..\n", __PRETTY_FUNCTION__
));
6945 /* Adjust entry posiions .. */
6946 #if defined(DEBUG_ILC_ICONDRAGDROP)
6947 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
));
6949 LONG offset_x
= message
->x
- (data
->click_x
+ _mleft(obj
));
6950 LONG offset_y
= message
->y
- (data
->click_y
+ _mtop(obj
));
6952 entry
= (IPTR
)MUIV_IconList_NextIcon_Start
;
6953 while ((IPTR
)entry
!= MUIV_IconList_NextIcon_End
)
6955 DoMethod(message
->obj
, MUIM_IconList_NextIcon
, MUIV_IconList_NextIcon_Selected
, (IPTR
)&entry
);
6957 if ((IPTR
)entry
!= MUIV_IconList_NextIcon_End
)
6959 entry
->ile_IconEntry
->ie_IconX
+= offset_x
;
6960 entry
->ile_IconEntry
->ie_IconY
+= offset_y
;
6961 /* Remember new position as provided */
6962 DoMethod(obj
, MUIM_IconList_PropagateEntryPos
, entry
->ile_IconEntry
);
6964 SET(obj
, MUIA_IconList_IconMoved
, (IPTR
)entry
); // Now notify
6966 MUI_Redraw(obj
,MADF_DRAWOBJECT
);
6967 DoMethod(obj
, MUIM_IconList_CoordsSort
);
6971 #if defined(DEBUG_ILC_ICONDRAGDROP)
6972 D(bug("[IconList] %s: Icons Dropped on Wanderer Desktop (unhandled)!\n", __PRETTY_FUNCTION__
));
6982 /* Create list of entries to copy .. */
6983 entry
= (IPTR
)MUIV_IconList_NextIcon_Start
;
6984 while ((IPTR
)entry
!= MUIV_IconList_NextIcon_End
)
6986 DoMethod(message
->obj
, MUIM_IconList_NextIcon
, MUIV_IconList_NextIcon_Selected
, (IPTR
)&entry
);
6988 if ((IPTR
)entry
!= MUIV_IconList_NextIcon_End
)
6990 struct IconList_Drop_SourceEntry
*sourceEntry
= NULL
;
6991 sourceEntry
= AllocMem(sizeof(struct IconList_Drop_SourceEntry
), MEMF_CLEAR
);
6992 if ((entry
->type
!= ST_ROOT
) && (entry
->type
!= ST_SOFTLINK
))
6997 GET(message
->obj
, MUIA_IconDrawerList_Drawer
, &path
);
6998 /* Properly expand the location incase it uses devices rather than volumes */
7001 tmp_dirlock
= Lock(path
, SHARED_LOCK
);
7004 if (NameFromLock(tmp_dirlock
, tmp_dirbuff
, 256))
7008 UnLock(tmp_dirlock
);
7011 if (strcasecmp(dragDropEvent
->drop_TargetPath
, path
) != 0)
7013 fulllen
= strlen(path
) + strlen(entry
->ile_IconEntry
->ie_IconNode
.ln_Name
) + 2;
7014 sourceEntry
->dropse_Node
.ln_Name
= AllocVec(fulllen
, MEMF_CLEAR
);
7015 strcpy(sourceEntry
->dropse_Node
.ln_Name
, path
);
7016 AddPart(sourceEntry
->dropse_Node
.ln_Name
, entry
->label
, fulllen
);
7017 #if defined(DEBUG_ILC_ICONDRAGDROP)
7018 D(bug("[IconList] %s: Source Entry (Full Path) = '%s'\n", __PRETTY_FUNCTION__
, sourceEntry
->dropse_Node
.ln_Name
));
7025 sourceEntry
->dropse_Node
.ln_Name
= AllocVec(strlen(entry
->label
) + 1, MEMF_CLEAR
);
7026 strcpy(sourceEntry
->dropse_Node
.ln_Name
, entry
->label
);
7027 #if defined(DEBUG_ILC_ICONDRAGDROP)
7028 D(bug("[IconList] %s: Source Entry = '%s'\n", __PRETTY_FUNCTION__
, sourceEntry
->dropse_Node
.ln_Name
));
7032 if ((sourceEntry
->dropse_Node
.ln_Name
!= NULL
) && (strcasecmp(dragDropEvent
->drop_TargetPath
, sourceEntry
->dropse_Node
.ln_Name
) != 0))
7035 AddTail(&dragDropEvent
->drop_SourceList
, &sourceEntry
->dropse_Node
);
7039 #if defined(DEBUG_ILC_ICONDRAGDROP)
7040 D(bug("[IconList] %s: Source == Dest, Skipping!\n", __PRETTY_FUNCTION__
));
7042 if ( sourceEntry
->dropse_Node
.ln_Name
) FreeVec(sourceEntry
->dropse_Node
.ln_Name
);
7043 FreeMem(sourceEntry
, sizeof(struct IconList_Drop_SourceEntry
));
7049 dragDropEvent
->drop_TargetObj
= obj
;
7051 #if defined(DEBUG_ILC_ICONDRAGDROP)
7052 D(bug("[IconList] %s: Causing DROP notification..\n", __PRETTY_FUNCTION__
));
7054 SET(obj
, MUIA_IconList_IconsDropped
, (IPTR
)dragDropEvent
);
7055 DoMethod(obj
, MUIM_IconList_CoordsSort
);
7059 if (dragDropEvent
->drop_TargetPath
) FreeVec(dragDropEvent
->drop_TargetPath
);
7060 FreeMem(dragDropEvent
, sizeof(struct IconList_Drop_Event
));
7066 #if defined(DEBUG_ILC_ICONDRAGDROP)
7067 D(bug("[IconList] %s: BUG - DragDrop received with no source icons!\n", __PRETTY_FUNCTION__
));
7069 NNSET(obj
, MUIA_IconList_IconsDropped
, (IPTR
)NULL
);
7073 return DoSuperMethodA(CLASS
, obj
, (Msg
)message
);
7077 ///MUIM_UnselectAll()
7078 /**************************************************************************
7080 **************************************************************************/
7081 IPTR
IconList__MUIM_IconList_UnselectAll(struct IClass
*CLASS
, Object
*obj
, Msg message
)
7083 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
7084 struct Node
*node
= NULL
, *next_node
= NULL
;
7085 BOOL changed
= FALSE
;
7087 #if defined(DEBUG_ILC_FUNCS)
7088 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
7091 data
->icld_SelectionLastClicked
= NULL
;
7092 data
->icld_FocusIcon
= NULL
;
7093 #if defined(__AROS__)
7094 ForeachNodeSafe(&data
->icld_SelectionList
, node
, next_node
)
7096 Foreach_NodeSafe(&data
->icld_SelectionList
, node
, next_node
);
7099 struct IconEntry
*entry
= (struct IconEntry
*)((IPTR
)node
- ((IPTR
)&entry
->ie_SelectionNode
- (IPTR
)entry
));
7100 BOOL update_entry
= FALSE
;
7102 if (entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
7104 if (entry
->ie_Flags
& ICONENTRY_FLAG_SELECTED
)
7107 entry
->ie_Flags
&= ~ICONENTRY_FLAG_SELECTED
;
7108 update_entry
= TRUE
;
7110 if (entry
->ie_Flags
& ICONENTRY_FLAG_FOCUS
)
7112 entry
->ie_Flags
&= ~ICONENTRY_FLAG_FOCUS
;
7113 update_entry
= TRUE
;
7120 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
7121 data
->update_entry
= entry
;
7122 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
7127 SET(obj
, MUIA_IconList_SelectionChanged
, TRUE
);
7134 /**************************************************************************
7136 **************************************************************************/
7137 IPTR
IconList__MUIM_IconList_SelectAll(struct IClass
*CLASS
, Object
*obj
, Msg message
)
7139 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
7140 struct IconEntry
*node
= NULL
;
7141 BOOL changed
= FALSE
;
7143 #if defined(DEBUG_ILC_FUNCS)
7144 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
7147 node
= (struct IconEntry
*)GetHead(&data
->icld_IconList
);
7149 while (node
!= NULL
)
7151 if (node
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
7153 BOOL update_entry
= FALSE
;
7155 if (!(node
->ie_Flags
& ICONENTRY_FLAG_SELECTED
))
7157 AddTail(&data
->icld_SelectionList
, &node
->ie_SelectionNode
);
7158 node
->ie_Flags
|= ICONENTRY_FLAG_SELECTED
;
7159 update_entry
= TRUE
;
7161 data
->icld_SelectionLastClicked
= node
;
7163 else if (node
->ie_Flags
& ICONENTRY_FLAG_FOCUS
)
7165 node
->ie_Flags
&= ~ICONENTRY_FLAG_FOCUS
;
7166 update_entry
= TRUE
;
7172 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
7173 data
->update_entry
= node
;
7174 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
7177 node
= (struct IconEntry
*)GetSucc(&node
->ie_IconNode
);
7180 if ((data
->icld_SelectionLastClicked
) && (data
->icld_SelectionLastClicked
!= data
->icld_FocusIcon
))
7182 data
->icld_FocusIcon
= data
->icld_SelectionLastClicked
;
7183 if (!(data
->icld_FocusIcon
->ie_Flags
& ICONENTRY_FLAG_FOCUS
))
7185 data
->icld_FocusIcon
->ie_Flags
&= ~ICONENTRY_FLAG_FOCUS
;
7186 data
->icld_FocusIcon
->ie_Flags
|= ICONENTRY_FLAG_FOCUS
;
7187 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
7188 data
->update_entry
= data
->icld_FocusIcon
;
7189 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
7194 SET(obj
, MUIA_IconList_SelectionChanged
, TRUE
);
7200 ///IconList__MUIM_IconList_CoordsSort()
7201 IPTR
IconList__MUIM_IconList_CoordsSort(struct IClass
*CLASS
, Object
*obj
, struct MUIP_IconList_Sort
*message
)
7203 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
7205 struct IconEntry
*entry
= NULL
,
7208 struct List list_VisibleIcons
;
7209 struct List list_HiddenIcons
;
7210 // struct List list_UnplacedIcons;
7213 perform a quick sort of the iconlist based on entry coords
7214 this method DOESNT cause any visual output.
7216 #if defined(DEBUG_ILC_FUNCS) || defined(DEBUG_ILC_ICONSORTING)
7217 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
7220 NewList((struct List
*)&list_VisibleIcons
);
7221 NewList((struct List
*)&list_HiddenIcons
);
7223 /*move list into our local list struct(s)*/
7224 while ((entry
= (struct IconEntry
*)RemTail((struct List
*)&data
->icld_IconList
)))
7226 if (entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
7228 AddHead((struct List
*)&list_VisibleIcons
, (struct Node
*)&entry
->ie_IconNode
);
7231 AddHead((struct List
*)&list_HiddenIcons
, (struct Node
*)&entry
->ie_IconNode
);
7234 while ((entry
= (struct IconEntry
*)RemTail((struct List
*)&list_VisibleIcons
)))
7236 if ((test_icon
= (struct IconEntry
*)GetTail(&data
->icld_IconList
)) != NULL
)
7238 while (test_icon
!= NULL
)
7240 if (((data
->icld_DisplayFlags
& ICONLIST_DISP_VERTICAL
) && (test_icon
->ie_IconX
> entry
->ie_IconX
)) ||
7241 (!(data
->icld_DisplayFlags
& ICONLIST_DISP_VERTICAL
) && (test_icon
->ie_IconY
> entry
->ie_IconY
)))
7243 test_icon
= (struct IconEntry
*)GetPred(&test_icon
->ie_IconNode
);
7249 while (test_icon
!= NULL
)
7251 if (((data
->icld_DisplayFlags
& ICONLIST_DISP_VERTICAL
) && (test_icon
->ie_IconY
> entry
->ie_IconY
)) ||
7252 (!(data
->icld_DisplayFlags
& ICONLIST_DISP_VERTICAL
) && (test_icon
->ie_IconX
> entry
->ie_IconX
)))
7254 test_icon
= (struct IconEntry
*)GetPred(&test_icon
->ie_IconNode
);
7259 Insert((struct List
*)&data
->icld_IconList
, (struct Node
*)&entry
->ie_IconNode
, (struct Node
*)&test_icon
->ie_IconNode
);
7262 AddTail((struct List
*)&data
->icld_IconList
, (struct Node
*)&entry
->ie_IconNode
);
7264 #if defined(DEBUG_ILC_ICONSORTING)
7265 D(bug("[IconList] %s: Done\n", __PRETTY_FUNCTION__
));
7268 while ((entry
= (struct IconEntry
*)RemTail((struct List
*)&list_HiddenIcons
)))
7270 AddTail((struct List
*)&data
->icld_IconList
, (struct Node
*)&entry
->ie_IconNode
);
7273 #if defined(DEBUG_ILC_ICONSORTING_DUMP)
7274 #if defined(__AROS__)
7275 ForeachNode(&data
->icld_IconList
, entry
)
7277 Foreach_Node(&data
->icld_IconList
, entry
);
7280 D(bug("[IconList] %s: %d %d '%s'\n", __PRETTY_FUNCTION__
, entry
->ie_IconX
, entry
->ie_IconY
, entry
->ie_IconListEntry
.label
));
7289 /**************************************************************************
7290 MUIM_Sort - sortsort
7291 **************************************************************************/
7292 IPTR
IconList__MUIM_IconList_Sort(struct IClass
*CLASS
, Object
*obj
, struct MUIP_IconList_Sort
*message
)
7294 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
7295 struct IconEntry
*entry
= NULL
,
7299 struct List list_VisibleIcons
,
7303 BOOL sortme
, reversable
= TRUE
, enqueue
= FALSE
;
7304 int i
, visible_count
= 0;
7306 #if defined(DEBUG_ILC_FUNCS) || defined(DEBUG_ILC_ICONSORTING)
7307 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
7310 /* Reset incase view options have changed .. */
7311 data
->icld_IconAreaLargestWidth
= 0;
7312 data
->icld_IconAreaLargestHeight
= 0;
7313 data
->icld_IconLargestHeight
= 0;
7314 data
->icld_LabelLargestHeight
= 0;
7316 #if defined(DEBUG_ILC_ICONSORTING)
7317 D(bug("[IconList] %s: Sort-Flags : %x\n", __PRETTY_FUNCTION__
, (data
->icld_SortFlags
& MUIV_IconList_Sort_MASK
)));
7319 NewList((struct List
*)&list_VisibleIcons
);
7320 NewList((struct List
*)&list_SortedIcons
);
7321 NewList((struct List
*)&list_HiddenIcons
);
7323 /*move list into our local list struct(s)*/
7324 while ((entry
= (struct IconEntry
*)RemTail((struct List
*)&data
->icld_IconList
)))
7326 if (!(entry
->ie_Flags
& ICONENTRY_FLAG_HASICON
))
7328 if (data
->icld_DisplayFlags
& ICONLIST_DISP_SHOWINFO
)
7330 if (entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
7332 entry
->ie_Flags
&= ~(ICONENTRY_FLAG_VISIBLE
|ICONENTRY_FLAG_NEEDSUPDATE
);
7335 else if (!(entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
))
7337 entry
->ie_Flags
|= (ICONENTRY_FLAG_VISIBLE
|ICONENTRY_FLAG_NEEDSUPDATE
);
7342 if (!(entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
))
7344 entry
->ie_Flags
|= (ICONENTRY_FLAG_VISIBLE
|ICONENTRY_FLAG_NEEDSUPDATE
);
7348 /* Now we have fixed visibility lets dump them into the correct list for sorting */
7349 if (entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
7351 if(entry
->ie_AreaWidth
> data
->icld_IconAreaLargestWidth
) data
->icld_IconAreaLargestWidth
= entry
->ie_AreaWidth
;
7352 if(entry
->ie_AreaHeight
> data
->icld_IconAreaLargestHeight
) data
->icld_IconAreaLargestHeight
= entry
->ie_AreaHeight
;
7353 if(entry
->ie_IconHeight
> data
->icld_IconLargestHeight
) data
->icld_IconLargestHeight
= entry
->ie_IconHeight
;
7354 if((entry
->ie_AreaHeight
- entry
->ie_IconHeight
) > data
->icld_LabelLargestHeight
) data
->icld_LabelLargestHeight
= entry
->ie_AreaHeight
- entry
->ie_IconHeight
;
7356 if (((data
->icld_SortFlags
& MUIV_IconList_Sort_AutoSort
) == 0) && (entry
->ie_ProvidedIconX
== NO_ICON_POSITION
))
7357 AddTail((struct List
*)&list_VisibleIcons
, (struct Node
*)&entry
->ie_IconNode
);
7359 AddHead((struct List
*)&list_VisibleIcons
, (struct Node
*)&entry
->ie_IconNode
);
7364 if (entry
->ie_Flags
& ICONENTRY_FLAG_SELECTED
)
7366 Remove(&entry
->ie_SelectionNode
);
7368 entry
->ie_Flags
&= ~(ICONENTRY_FLAG_SELECTED
|ICONENTRY_FLAG_FOCUS
);
7369 if (data
->icld_SelectionLastClicked
== entry
) data
->icld_SelectionLastClicked
= NULL
;
7370 if (data
->icld_FocusIcon
== entry
) data
->icld_FocusIcon
= data
->icld_SelectionLastClicked
;
7371 AddHead((struct List
*)&list_HiddenIcons
, (struct Node
*)&entry
->ie_IconNode
);
7375 /* Copy each visible entry back to the main list, sorting as we go*/
7376 while ((entry
= (struct IconEntry
*)RemHead((struct List
*)&list_VisibleIcons
)))
7378 icon1
= (struct IconEntry
*)GetHead(&list_SortedIcons
);
7383 if (visible_count
> 1)
7385 #if defined(DEBUG_ILC_ICONSORTING)
7386 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
));
7390 if(((icon1
->ie_IconListEntry
.type
== ST_ROOT
) || (icon1
->ie_IconListEntry
.type
== ST_LINKDIR
) || (icon1
->ie_IconListEntry
.type
== ST_LINKFILE
))
7391 || (data
->icld_SortFlags
& MUIV_IconList_Sort_DrawersMixed
))
7393 /*volume list or drawers mixed*/
7399 if ((icon1
->ie_IconListEntry
.type
== ST_USERDIR
) && (entry
->ie_IconListEntry
.type
== ST_USERDIR
))
7405 if ((icon1
->ie_IconListEntry
.type
!= ST_USERDIR
) && (entry
->ie_IconListEntry
.type
!= ST_USERDIR
))
7409 /* we are the first drawer to arrive or we need to insert ourselves
7410 due to being sorted to the end of the drawers*/
7412 if ((!icon2
|| icon2
->ie_IconListEntry
.type
== ST_USERDIR
) &&
7413 (entry
->ie_IconListEntry
.type
== ST_USERDIR
) &&
7414 (icon1
->ie_IconListEntry
.type
!= ST_USERDIR
))
7416 #if defined(DEBUG_ILC_ICONSORTING)
7417 D(bug("[IconList] %s: force %s\n", __PRETTY_FUNCTION__
, entry
->ie_IconListEntry
.label
));
7429 if ((data
->icld_SortFlags
& MUIV_IconList_Sort_AutoSort
) == 0)
7431 if ((entry
->ie_ProvidedIconX
!= NO_ICON_POSITION
) && (entry
->ie_ProvidedIconY
!= NO_ICON_POSITION
))
7439 if (data
->icld_SortFlags
& MUIV_IconList_Sort_ByDate
)
7442 i
= CompareDates((const struct DateStamp
*)&entry
->ie_FileInfoBlock
->fib_Date
,(const struct DateStamp
*)&icon1
->ie_FileInfoBlock
->fib_Date
);
7444 else if (data
->icld_SortFlags
& MUIV_IconList_Sort_BySize
)
7446 /* Sort by Size .. */
7447 i
= entry
->ie_FileInfoBlock
->fib_Size
- icon1
->ie_FileInfoBlock
->fib_Size
;
7449 else if ((data
->icld_SortFlags
& MUIV_IconList_Sort_ByType
) && ((entry
->ie_IconListEntry
.type
== ST_FILE
) || (entry
->ie_IconListEntry
.type
== ST_USERDIR
)))
7451 /* Sort by Type .. */
7452 /* TODO: Sort icons based on type using datatypes */
7456 /* Sort by Name .. */
7457 i
= Stricmp(entry
->ie_IconListEntry
.label
, icon1
->ie_IconListEntry
.label
);
7458 if ((data
->icld_SortFlags
& MUIV_IconList_Sort_DrawersMixed
) == 0) enqueue
= TRUE
;
7462 if ((reversable
) && data
->icld_SortFlags
& MUIV_IconList_Sort_Reverse
)
7471 icon1
= (struct IconEntry
*)GetSucc(&icon1
->ie_IconNode
);
7474 Insert((struct List
*)&list_SortedIcons
, (struct Node
*)&entry
->ie_IconNode
, (struct Node
*)&icon2
->ie_IconNode
);
7478 /* Quickly resort based on node priorities .. */
7479 while ((entry
= (struct IconEntry
*)RemHead((struct List
*)&list_SortedIcons
)))
7481 Enqueue((struct List
*)&data
->icld_IconList
, (struct Node
*)&entry
->ie_IconNode
);
7486 while ((entry
= (struct IconEntry
*)RemHead((struct List
*)&list_SortedIcons
)))
7488 AddTail((struct List
*)&data
->icld_IconList
, (struct Node
*)&entry
->ie_IconNode
);
7492 DoMethod(obj
, MUIM_IconList_PositionIcons
);
7493 MUI_Redraw(obj
, MADF_DRAWOBJECT
);
7495 if ((data
->icld_SortFlags
& MUIV_IconList_Sort_Orders
) != 0)
7497 DoMethod(obj
, MUIM_IconList_CoordsSort
);
7499 /* leave hidden icons on a seperate list to speed up normal list parsing ? */
7500 while ((entry
= (struct IconEntry
*)RemHead((struct List
*)&list_HiddenIcons
)))
7502 AddTail((struct List
*)&data
->icld_IconList
, (struct Node
*)&entry
->ie_IconNode
);
7505 SET(obj
, MUIA_IconList_Changed
, TRUE
);
7511 ///MUIM_DragReport()
7512 /**************************************************************************
7513 MUIM_DragReport. Since MUI doesn't change the drop object if the dragged
7514 object is moved above another window (while still in the bounds of the
7515 orginal drop object) we must do it here manually to be compatible with
7516 MUI. Maybe Zune should fix this bug somewhen.
7517 **************************************************************************/
7518 IPTR
IconList__MUIM_DragReport(struct IClass
*CLASS
, Object
*obj
, struct MUIP_DragReport
*message
)
7520 struct Window
*wnd
= _window(obj
);
7521 struct Layer
*l
= NULL
;
7523 #if defined(DEBUG_ILC_FUNCS) || defined(DEBUG_ILC_ICONDRAGDROP)
7524 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
7527 l
= WhichLayer(&wnd
->WScreen
->LayerInfo
, wnd
->LeftEdge
+ message
->x
, wnd
->TopEdge
+ message
->y
);
7529 if (l
!= wnd
->WLayer
) return MUIV_DragReport_Abort
;
7531 return MUIV_DragReport_Continue
;
7535 ///MUIM_IconList_UnknownDropDestination()
7536 /**************************************************************************
7537 MUIM_IconList_UnknownDropDestination
7538 **************************************************************************/
7539 IPTR
IconList__MUIM_UnknownDropDestination(struct IClass
*CLASS
, Object
*obj
, struct MUIP_UnknownDropDestination
*message
)
7541 #if defined(DEBUG_ILC_FUNCS) || defined(DEBUG_ILC_ICONDRAGDROP)
7542 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
7544 #if defined(DEBUG_ILC_ICONDRAGDROP)
7545 D(bug("[IconList] %s: icons dropped on custom window \n", __PRETTY_FUNCTION__
));
7548 SET(obj
, MUIA_IconList_AppWindowDrop
, (IPTR
)message
); /* Now notify */
7554 ///MUIM_IconList_MakeEntryVisible()
7555 /**************************************************************************
7556 Move the visible area so that the selected entry becomes visible ..
7557 **************************************************************************/
7558 IPTR
IconList__MUIM_IconList_MakeEntryVisible(struct IClass
*CLASS
, Object
*obj
, struct MUIP_IconList_MakeEntryVisible
*message
)
7560 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
7561 BOOL viewmoved
= FALSE
;
7562 struct Rectangle iconrect
, viewrect
;
7564 #if defined(DEBUG_ILC_FUNCS)
7565 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
7568 viewrect
.MinX
= data
->icld_ViewX
;
7569 viewrect
.MaxX
= data
->icld_ViewX
+ data
->icld_AreaWidth
;
7570 viewrect
.MinY
= data
->icld_ViewY
;
7571 viewrect
.MaxY
= data
->icld_ViewY
+ data
->icld_AreaHeight
;
7573 IconList_GetIconAreaRectangle(obj
, data
, message
->entry
, &iconrect
);
7575 if (!(RectAndRect(&viewrect
, &iconrect
)))
7578 if (message
->entry
->ie_IconX
< data
->icld_ViewX
)
7579 data
->icld_ViewX
= message
->entry
->ie_IconX
;
7580 else if (message
->entry
->ie_IconX
> (data
->icld_ViewX
+ data
->icld_AreaWidth
))
7581 data
->icld_ViewX
= (message
->entry
->ie_IconX
+ message
->entry
->ie_AreaWidth
) - data
->icld_AreaWidth
;
7583 if (message
->entry
->ie_IconY
< data
->icld_ViewY
)
7584 data
->icld_ViewY
= message
->entry
->ie_IconX
;
7585 else if (message
->entry
->ie_IconY
> (data
->icld_ViewY
+ data
->icld_AreaHeight
))
7586 data
->icld_ViewY
= (message
->entry
->ie_IconY
+ message
->entry
->ie_AreaHeight
) - data
->icld_AreaHeight
;
7591 #if defined(DEBUG_ILC_ICONRENDERING)
7592 D(bug("[IconList]: %s: call SetSuperAttrs()\n", __PRETTY_FUNCTION__
));
7594 SetSuperAttrs(CLASS
, obj
, MUIA_Virtgroup_Left
, data
->icld_ViewX
,
7595 MUIA_Virtgroup_Top
, data
->icld_ViewY
,
7598 #if defined(DEBUG_ILC_ICONRENDERING)
7599 D(bug("[IconList]: %s: call SetAttrs()\n", __PRETTY_FUNCTION__
));
7601 SetAttrs(obj
, MUIA_Virtgroup_Left
, data
->icld_ViewX
,
7602 MUIA_Virtgroup_Top
, data
->icld_ViewY
,
7605 #if defined(DEBUG_ILC_ICONRENDERING)
7606 D(bug("[IconList]: %s: call MUI_Redraw()\n", __PRETTY_FUNCTION__
));
7608 MUI_Redraw(obj
,MADF_DRAWOBJECT
);
7613 #if defined(WANDERER_BUILTIN_ICONLIST)
7614 BOOPSI_DISPATCHER(IPTR
,IconList_Dispatcher
, CLASS
, obj
, message
)
7616 #if defined(__AROS__)
7617 switch (message
->MethodID
)
7619 struct IClass
*CLASS
= cl
;
7622 switch (msg
->MethodID
)
7625 case OM_NEW
: return IconList__OM_NEW(CLASS
, obj
, (struct opSet
*)message
);
7626 case OM_DISPOSE
: return IconList__OM_DISPOSE(CLASS
, obj
, message
);
7627 case OM_SET
: return IconList__OM_SET(CLASS
, obj
, (struct opSet
*)message
);
7628 case OM_GET
: return IconList__OM_GET(CLASS
, obj
, (struct opGet
*)message
);
7630 case MUIM_Family_AddTail
: return IconList__MUIM_Family_AddTail(CLASS
, obj
, (APTR
)message
);
7631 case MUIM_Family_AddHead
: return IconList__MUIM_Family_AddHead(CLASS
, obj
, (APTR
)message
);
7633 case MUIM_Family_Remove
: return IconList__MUIM_Family_Remove(CLASS
, obj
, (APTR
)message
);
7635 case MUIM_Setup
: return IconList__MUIM_Setup(CLASS
, obj
, (struct MUIP_Setup
*)message
);
7637 case MUIM_Show
: return IconList__MUIM_Show(CLASS
,obj
, (struct MUIP_Show
*)message
);
7638 case MUIM_Hide
: return IconList__MUIM_Hide(CLASS
,obj
, (struct MUIP_Hide
*)message
);
7639 case MUIM_Cleanup
: return IconList__MUIM_Cleanup(CLASS
, obj
, (struct MUIP_Cleanup
*)message
);
7640 case MUIM_AskMinMax
: return IconList__MUIM_AskMinMax(CLASS
, obj
, (struct MUIP_AskMinMax
*)message
);
7641 case MUIM_Draw
: return IconList__MUIM_Draw(CLASS
, obj
, (struct MUIP_Draw
*)message
);
7642 #if defined(__AROS__)
7643 case MUIM_Layout
: return IconList__MUIM_Layout(CLASS
, obj
, (struct MUIP_Layout
*)message
);
7645 case MUIM_HandleEvent
: return IconList__MUIM_HandleEvent(CLASS
, obj
, (struct MUIP_HandleEvent
*)message
);
7646 case MUIM_CreateDragImage
: return IconList__MUIM_CreateDragImage(CLASS
, obj
, (APTR
)message
);
7647 case MUIM_DeleteDragImage
: return IconList__MUIM_DeleteDragImage(CLASS
, obj
, (APTR
)message
);
7648 case MUIM_DragQuery
: return IconList__MUIM_DragQuery(CLASS
, obj
, (APTR
)message
);
7649 case MUIM_DragReport
: return IconList__MUIM_DragReport(CLASS
, obj
, (APTR
)message
);
7650 case MUIM_DragDrop
: return IconList__MUIM_DragDrop(CLASS
, obj
, (APTR
)message
);
7651 #if defined(__AROS__)
7652 case MUIM_UnknownDropDestination
: return IconList__MUIM_UnknownDropDestination(CLASS
, obj
, (APTR
)message
);
7654 case MUIM_IconList_Update
: return IconList__MUIM_IconList_Update(CLASS
, obj
, (APTR
)message
);
7655 case MUIM_IconList_Clear
: return IconList__MUIM_IconList_Clear(CLASS
, obj
, (APTR
)message
);
7656 case MUIM_IconList_RethinkDimensions
: return IconList__MUIM_IconList_RethinkDimensions(CLASS
, obj
, (APTR
)message
);
7657 case MUIM_IconList_CreateEntry
: return IconList__MUIM_IconList_CreateEntry(CLASS
, obj
, (APTR
)message
);
7658 case MUIM_IconList_UpdateEntry
: return IconList__MUIM_IconList_UpdateEntry(CLASS
, obj
, (APTR
)message
);
7659 case MUIM_IconList_DestroyEntry
: return IconList__MUIM_IconList_DestroyEntry(CLASS
, obj
, (APTR
)message
);
7660 case MUIM_IconList_DrawEntry
: return IconList__MUIM_IconList_DrawEntry(CLASS
, obj
, (APTR
)message
);
7661 case MUIM_IconList_DrawEntryLabel
: return IconList__MUIM_IconList_DrawEntryLabel(CLASS
, obj
, (APTR
)message
);
7662 case MUIM_IconList_NextIcon
: return IconList__MUIM_IconList_NextIcon(CLASS
, obj
, (APTR
)message
);
7663 case MUIM_IconList_GetIconPrivate
: return IconList__MUIM_IconList_GetIconPrivate(CLASS
, obj
, (APTR
)message
);
7664 case MUIM_IconList_UnselectAll
: return IconList__MUIM_IconList_UnselectAll(CLASS
, obj
, (APTR
)message
);
7665 case MUIM_IconList_Sort
: return IconList__MUIM_IconList_Sort(CLASS
, obj
, (APTR
)message
);
7666 case MUIM_IconList_CoordsSort
: return IconList__MUIM_IconList_CoordsSort(CLASS
, obj
, (APTR
)message
);
7667 case MUIM_IconList_PositionIcons
: return IconList__MUIM_IconList_PositionIcons(CLASS
, obj
, (APTR
)message
);
7668 case MUIM_IconList_SelectAll
: return IconList__MUIM_IconList_SelectAll(CLASS
, obj
, (APTR
)message
);
7669 case MUIM_IconList_MakeEntryVisible
: return IconList__MUIM_IconList_MakeEntryVisible(CLASS
, obj
, (APTR
)message
);
7672 return DoSuperMethodA(CLASS
, obj
, message
);
7674 BOOPSI_DISPATCHER_END
7676 #if defined(__AROS__)
7677 /* Class descriptor. */
7678 const struct __MUIBuiltinClass _MUI_IconList_desc
= {
7681 sizeof(struct IconList_DATA
),
7682 (void*)IconList_Dispatcher
7685 #endif /* WANDERER_BUILTIN_ICONLIST */
7687 #if !defined(__AROS__)
7688 struct MUI_CustomClass
*initIconListClass(void)
7690 return (struct MUI_CustomClass
*) MUI_CreateCustomClass(NULL
, MUIC_Area
, NULL
, sizeof(struct IconList_DATA
), ENTRY(IconList_Dispatcher
));