2 Copyright 2002-2010, 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
},
122 static struct TagItem __iconList_BackBuffLayerTags
[] =
124 { LA_Visible
, FALSE
},
128 #ifndef NO_ICON_POSITION
129 #define NO_ICON_POSITION (0x8000000) /* belongs to workbench/workbench.h */
132 #define UPDATE_HEADERENTRY 1
133 #define UPDATE_SINGLEENTRY 2
134 #define UPDATE_SCROLL 3
135 #define UPDATE_RESIZE 4
137 #define LEFT_BUTTON 1
138 #define RIGHT_BUTTON 2
139 #define MIDDLE_BUTTON 4
141 #define ICONLIST_DRAWMODE_NORMAL 1
142 #define ICONLIST_DRAWMODE_FAST 2
144 /* Values used for List View-Mode */
145 #define COLOR_COLUMN_BACKGROUND 0
146 #define COLOR_COLUMN_BACKGROUND_SORTED 1
147 #define COLOR_COLUMN_BACKGROUND_LASSO 2
148 #define COLOR_COLUMN_BACKGROUND_LASSO_SORTED 3
150 #define COLOR_SELECTED_BACKGROUND 4
151 #define COLOR_SELECTED_BACKGROUND_SORTED 5
153 #define MIN_COLUMN_WIDTH 10
155 #define COLUMN_ALIGN_LEFT 0
156 #define COLUMN_ALIGN_CENTER 1
157 #define COLUMN_ALIGN_RIGHT 2
159 #define LINE_SPACING_TOP 2
160 #define LINE_SPACING_BOTTOM 2
161 #define LINE_EXTRAHEIGHT (LINE_SPACING_TOP + LINE_SPACING_BOTTOM)
163 #define LINE_SPACING_LEFT 1
164 #define LINE_SPACING_RIGHT 1
165 #define LINE_EXTRAWIDTH (LINE_SPACING_LEFT + LINE_SPACING_RIGHT)
167 #define ENTRY_SPACING_LEFT 1
168 #define ENTRY_SPACING_RIGHT 1
169 #define ENTRY_EXTRAWIDTH (ENTRY_SPACING_LEFT + ENTRY_SPACING_RIGHT)
171 #define HEADERLINE_SPACING_TOP 3
172 #define HEADERLINE_SPACING_BOTTOM 3
173 #define HEADERLINE_EXTRAHEIGHT (HEADERLINE_SPACING_TOP + HEADERLINE_SPACING_BOTTOM)
175 #define HEADERLINE_SPACING_LEFT 1
176 #define HEADERLINE_SPACING_RIGHT 1
177 #define HEADERLINE_EXTRAWIDTH (HEADERLINE_SPACING_LEFT + HEADERLINE_SPACING_RIGHT)
179 #define HEADERENTRY_SPACING_LEFT 4
180 #define HEADERENTRY_SPACING_RIGHT 4
181 #define HEADERENTRY_EXTRAWIDTH (HEADERENTRY_SPACING_LEFT + HEADERENTRY_SPACING_RIGHT)
193 /**************************************************************************
195 **************************************************************************/
197 #define ForeachPrevNode(list, node) \
200 node = (void *)(((struct List *)(list))->lh_TailPred); \
201 ((struct Node *)(node))->ln_Pred; \
202 node = (void *)(((struct Node *)(node))->ln_Pred) \
205 #define RPALPHAFLAT (1 << 0)
206 #define RPALPHARADIAL (1 << 1)
208 static void RastPortSetAlpha(struct RastPort
*arport
, ULONG ax
, ULONG ay
, ULONG width
, ULONG height
, UBYTE val
, UBYTE alphamode
)
211 ULONG alphaval
, pixelval
;
213 for (y
= 0; y
< height
; y
++)
215 for (x
= 0; x
< width
; x
++)
217 if ((pixelval
= ReadRGBPixel(arport
, x
, y
)))
219 if (alphamode
== RPALPHARADIAL
){
220 //Set the alpha value based on distance from ax,ay
224 WriteRGBPixel(arport
, x
, y
, ((pixelval
& 0xffffff)|(alphaval
<< 24)));
231 // Entry/Label Area support functions
232 static int RectAndRect(struct Rectangle
*a
, struct Rectangle
*b
)
234 if ((a
->MinX
> b
->MaxX
) || (a
->MinY
> b
->MaxY
) || (a
->MaxX
< b
->MinX
) || (a
->MaxY
< b
->MinY
))
240 ///Node_NextVisible()
241 // IconEntry List navigation functions ..
242 static struct IconEntry
*Node_NextVisible(struct IconEntry
*current_Node
)
244 current_Node
= (struct IconEntry
*)GetSucc(¤t_Node
->ie_IconNode
);
245 while ((current_Node
!= NULL
) && (!(current_Node
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)))
247 current_Node
= (struct IconEntry
*)GetSucc(¤t_Node
->ie_IconNode
);
253 ///Node_FirstVisible()
254 static struct IconEntry
*Node_FirstVisible(struct List
*icon_list
)
256 struct IconEntry
*current_Node
= (struct IconEntry
*)GetHead(icon_list
);
258 if ((current_Node
!= NULL
) && !(current_Node
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
))
259 current_Node
= Node_NextVisible(current_Node
);
265 ///Node_PreviousVisible()
266 static struct IconEntry
*Node_PreviousVisible(struct IconEntry
*current_Node
)
268 current_Node
= (struct IconEntry
*)GetPred(¤t_Node
->ie_IconNode
);
269 while ((current_Node
!= NULL
) && (!(current_Node
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)))
271 current_Node
= (struct IconEntry
*)GetPred(¤t_Node
->ie_IconNode
);
277 ///Node_LastVisible()
278 static struct IconEntry
*Node_LastVisible(struct List
*icon_list
)
280 struct IconEntry
*current_Node
= (struct IconEntry
*)GetTail(icon_list
);
282 if ((current_Node
!= NULL
) && !(current_Node
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
))
283 current_Node
= Node_PreviousVisible(current_Node
);
289 const UBYTE MSG_MEM_G
[] = "GB";
290 const UBYTE MSG_MEM_M
[] = "MB";
291 const UBYTE MSG_MEM_K
[] = "KB";
292 const UBYTE MSG_MEM_B
[] = "Bytes";
295 static void FmtSizeToString(UBYTE
*buf
, ULONG num
)
309 if (num
>= 1073741824)
312 array
.val
= num
>> 30;
313 d
= ((UQUAD
)num
* 10 + 536870912) / 1073741824;
317 else if (num
>= 1048576)
320 array
.val
= num
>> 20;
321 d
= ((UQUAD
)num
* 10 + 524288) / 1048576;
325 else if (num
>= 1024)
328 array
.val
= num
>> 10;
329 d
= (num
* 10 + 512) / 1024;
342 if (!array
.dec
&& (d
> array
.val
* 10))
347 RawDoFmt(array
.dec
? "%lu.%lu" : "%lu", &array
, NULL
, buf
);
354 sprintf(buf
, " %s", ch
);
358 ///GetAbsoluteLassoRect()
359 // get positive lasso coords
360 static void GetAbsoluteLassoRect(struct IconList_DATA
*data
, struct Rectangle
*LassoRectangle
)
362 WORD minx
= data
->icld_LassoRectangle
.MinX
;
363 WORD miny
= data
->icld_LassoRectangle
.MinY
;
364 WORD maxx
= data
->icld_LassoRectangle
.MaxX
;
365 WORD maxy
= data
->icld_LassoRectangle
.MaxY
;
367 #if defined(DEBUG_ILC_LASSO) && defined(DEBUG_ILC_FUNCS)
368 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
373 /* Swap minx, maxx */
381 /* Swap miny, maxy */
387 LassoRectangle
->MinX
= data
->view_rect
.MinX
- data
->icld_ViewX
+ minx
;
388 LassoRectangle
->MinY
= data
->view_rect
.MinY
- data
->icld_ViewY
+ miny
;
389 LassoRectangle
->MaxX
= data
->view_rect
.MinX
- data
->icld_ViewX
+ maxx
;
390 LassoRectangle
->MaxY
= data
->view_rect
.MinY
- data
->icld_ViewY
+ maxy
;
394 ///IconList_InvertPixelRect()
395 static void IconList_InvertPixelRect(struct RastPort
*rp
, WORD minx
, WORD miny
, WORD maxx
, WORD maxy
, struct Rectangle
*clip
)
397 struct Rectangle r
, clipped_r
;
399 #if defined(DEBUG_ILC_RENDERING) && defined(DEBUG_ILC_FUNCS)
400 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
405 /* Swap minx, maxx */
413 /* Swap miny, maxy */
424 if (AndRectRect(&r
, clip
, &clipped_r
))
426 InvertPixelArray(rp
, clipped_r
.MinX
, clipped_r
.MinY
,
427 clipped_r
.MaxX
- clipped_r
.MinX
+ 1, clipped_r
.MaxY
- clipped_r
.MinY
+ 1);
432 ///IconList_InvertLassoOutlines()
433 // Simple lasso drawing by inverting area outlines
434 static void IconList_InvertLassoOutlines(Object
*obj
, struct IconList_DATA
*data
, struct Rectangle
*rect
)
436 struct Rectangle lasso
;
437 struct Rectangle clip
;
439 #if defined(DEBUG_ILC_LASSO) && defined(DEBUG_ILC_FUNCS)
440 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
443 /* get abolute iconlist coords */
444 lasso
.MinX
= rect
->MinX
+ _mleft(obj
);
445 lasso
.MaxX
= rect
->MaxX
+ _mleft(obj
);
446 lasso
.MinY
= rect
->MinY
+ _mtop(obj
);
447 lasso
.MaxY
= rect
->MaxY
+ _mtop(obj
);
449 clip
.MinX
= _mleft(obj
);
450 clip
.MinY
= _mtop(obj
);
451 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
453 clip
.MinY
+= data
->icld_LVMAttribs
->lmva_HeaderHeight
;
455 clip
.MaxX
= _mright(obj
);
456 clip
.MaxY
= _mbottom(obj
);
458 /* horizontal lasso lines */
459 IconList_InvertPixelRect(_rp(obj
), lasso
.MinX
, lasso
.MinY
, lasso
.MaxX
-1, lasso
.MinY
+ 1, &clip
);
460 IconList_InvertPixelRect(_rp(obj
), lasso
.MinX
, lasso
.MaxY
, lasso
.MaxX
-1, lasso
.MaxY
+ 1, &clip
);
462 /* vertical lasso lines */
463 IconList_InvertPixelRect(_rp(obj
), lasso
.MinX
, lasso
.MinY
, lasso
.MinX
+ 1, lasso
.MaxY
- 1, &clip
);
464 IconList_InvertPixelRect(_rp(obj
), lasso
.MaxX
, lasso
.MinY
, lasso
.MaxX
+ 1, lasso
.MaxY
- 1, &clip
);
468 ///IconList_GetIconImageRectangle()
469 //We don't use icon.library's label drawing so we do this by hand
470 static void IconList_GetIconImageRectangle(Object
*obj
, struct IconList_DATA
*data
, struct IconEntry
*entry
, struct Rectangle
*rect
)
472 #if defined(DEBUG_ILC_ICONPOSITIONING) && defined(DEBUG_ILC_FUNCS)
473 D(bug("[IconList]: %s(entry @ %p)\n", __PRETTY_FUNCTION__
, entry
));
476 /* Get basic width/height */
477 GetIconRectangleA(NULL
, entry
->ie_DiskObj
, NULL
, rect
, NULL
);
478 #if defined(DEBUG_ILC_ICONPOSITIONING)
479 D(bug("[IconList] %s: MinX %d, MinY %d MaxX %d, MaxY %d\n", __PRETTY_FUNCTION__
, rect
->MinX
, rect
->MinY
, rect
->MaxX
, rect
->MaxY
));
481 entry
->ie_IconWidth
= (rect
->MaxX
- rect
->MinX
) + 1;
482 entry
->ie_IconHeight
= (rect
->MaxY
- rect
->MinY
) + 1;
484 if (entry
->ie_IconHeight
> data
->icld_IconLargestHeight
)
485 data
->icld_IconLargestHeight
= entry
->ie_IconHeight
;
489 ///IconList_GetIconLabelRectangle()
490 static void IconList_GetIconLabelRectangle(Object
*obj
, struct IconList_DATA
*data
, struct IconEntry
*entry
, struct Rectangle
*rect
)
492 ULONG outline_offset
= 0;
495 #if defined(DEBUG_ILC_ICONPOSITIONING) && defined(DEBUG_ILC_FUNCS)
496 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
499 switch ( data
->icld__Option_LabelTextMode
)
501 case ICON_TEXTMODE_DROPSHADOW
:
505 case ICON_TEXTMODE_PLAIN
:
513 /* Get entry box width including text width */
514 if ((entry
->ie_IconListEntry
.label
!= NULL
) && (entry
->ie_TxtBuf_DisplayedLabel
!= NULL
))
516 ULONG curlabel_TotalLines
;
517 SetFont(data
->icld_BufferRastPort
, data
->icld_IconLabelFont
);
520 rect
->MaxX
= (((data
->icld__Option_LabelTextHorizontalPadding
+ data
->icld__Option_LabelTextBorderWidth
) * 2) + entry
->ie_TxtBuf_DisplayedLabelWidth
+ outline_offset
) - 1;
524 curlabel_TotalLines
= entry
->ie_SplitParts
;
525 if (curlabel_TotalLines
== 0)
526 curlabel_TotalLines
= 1;
527 if (curlabel_TotalLines
> data
->icld__Option_LabelTextMultiLine
)
528 curlabel_TotalLines
= data
->icld__Option_LabelTextMultiLine
;
530 rect
->MaxY
= (((data
->icld__Option_LabelTextBorderHeight
+ data
->icld__Option_LabelTextVerticalPadding
) * 2) +
531 ((data
->icld_IconLabelFont
->tf_YSize
+ outline_offset
) * curlabel_TotalLines
)) - 1;
533 /* Date/size sorting has the date/size appended under the entry label
534 only list regular files like this (drawers have no size/date output) */
536 entry
->ie_IconListEntry
.type
!= ST_USERDIR
&&
537 ((data
->icld_SortFlags
& MUIV_IconList_Sort_BySize
) || (data
->icld_SortFlags
& MUIV_IconList_Sort_ByDate
))
540 SetFont(data
->icld_BufferRastPort
, data
->icld_IconInfoFont
);
542 if( (data
->icld_SortFlags
& MUIV_IconList_Sort_BySize
) && !(data
->icld_SortFlags
& MUIV_IconList_Sort_ByDate
) )
544 entry
->ie_TxtBuf_SIZEWidth
= TextLength(data
->icld_BufferRastPort
, entry
->ie_TxtBuf_SIZE
, strlen(entry
->ie_TxtBuf_SIZE
));
545 textwidth
= entry
->ie_TxtBuf_SIZEWidth
;
549 if( !(data
->icld_SortFlags
& MUIV_IconList_Sort_BySize
) && (data
->icld_SortFlags
& MUIV_IconList_Sort_ByDate
) )
551 if( entry
->ie_Flags
& ICONENTRY_FLAG_TODAY
)
553 entry
->ie_TxtBuf_TIMEWidth
= TextLength(data
->icld_BufferRastPort
, entry
->ie_TxtBuf_TIME
, strlen(entry
->ie_TxtBuf_TIME
));
554 textwidth
= entry
->ie_TxtBuf_TIMEWidth
;
558 entry
->ie_TxtBuf_DATEWidth
= TextLength(data
->icld_BufferRastPort
, entry
->ie_TxtBuf_DATE
, strlen(entry
->ie_TxtBuf_DATE
));
559 textwidth
= entry
->ie_TxtBuf_DATEWidth
;
566 rect
->MaxY
= rect
->MaxY
+ data
->icld_IconInfoFont
->tf_YSize
+ outline_offset
;
567 if ((textwidth
+ outline_offset
+ ((data
->icld__Option_LabelTextHorizontalPadding
+ data
->icld__Option_LabelTextBorderWidth
) * 2)) > ((rect
->MaxX
- rect
->MinX
) + 1))
568 rect
->MaxX
= (textwidth
+ outline_offset
+ ((data
->icld__Option_LabelTextVerticalPadding
+ data
->icld__Option_LabelTextBorderWidth
) * 2)) - 1;
572 if (((rect
->MaxY
- rect
->MinY
) + 1) > data
->icld_LabelLargestHeight
) data
->icld_LabelLargestHeight
= ((rect
->MaxY
- rect
->MinY
) + 1);
576 ///IconList_GetIconAreaRectangle()
577 static void IconList_GetIconAreaRectangle(Object
*obj
, struct IconList_DATA
*data
, struct IconEntry
*entry
, struct Rectangle
*rect
)
579 struct Rectangle labelrect
;
580 ULONG iconlabel_Width
;
581 ULONG iconlabel_Height
;
583 #if defined(DEBUG_ILC_ICONPOSITIONING) && defined(DEBUG_ILC_FUNCS)
584 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
587 /* Get entry box width including text width */
588 memset(rect
, 0, sizeof(struct Rectangle
));
590 IconList_GetIconImageRectangle(obj
, data
, entry
, rect
);
592 entry
->ie_AreaWidth
= entry
->ie_IconWidth
;
593 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
595 entry
->ie_AreaHeight
= data
->icld_IconLargestHeight
;
599 entry
->ie_AreaHeight
= entry
->ie_IconHeight
;
602 IconList_GetIconLabelRectangle(obj
, data
, entry
, &labelrect
);
604 iconlabel_Width
= ((labelrect
.MaxX
- labelrect
.MinX
) + 1);
605 iconlabel_Height
= ((labelrect
.MaxY
- labelrect
.MinY
) + 1);
607 if (iconlabel_Width
> entry
->ie_AreaWidth
)
608 entry
->ie_AreaWidth
= iconlabel_Width
;
610 entry
->ie_AreaHeight
= entry
->ie_AreaHeight
+ data
->icld__Option_IconImageSpacing
+ iconlabel_Height
;
613 rect
->MaxX
= (rect
->MinX
+ entry
->ie_AreaWidth
) - 1;
614 rect
->MaxY
= (rect
->MinY
+ entry
->ie_AreaHeight
) - 1;
616 if (entry
->ie_AreaWidth
> data
->icld_IconAreaLargestWidth
) data
->icld_IconAreaLargestWidth
= entry
->ie_AreaWidth
;
617 if (entry
->ie_AreaHeight
> data
->icld_IconAreaLargestHeight
) data
->icld_IconAreaLargestHeight
= entry
->ie_AreaHeight
;
621 static LONG
FirstVisibleColumnNumber(struct IconList_DATA
*data
)
626 if (data
->icld_LVMAttribs
!= NULL
)
628 for(i
= 0; i
< NUM_COLUMNS
; i
++)
630 LONG index
= data
->icld_LVMAttribs
->lmva_ColumnPos
[i
];
632 if (data
->icld_LVMAttribs
->lmva_ColumnFlags
[index
] & LVMCF_COLVISIBLE
)
643 static LONG
LastVisibleColumnNumber(struct IconList_DATA
*data
)
648 if (data
->icld_LVMAttribs
!= NULL
)
650 for(i
= 0; i
< NUM_COLUMNS
; i
++)
652 LONG index
= data
->icld_LVMAttribs
->lmva_ColumnPos
[i
];
654 if (data
->icld_LVMAttribs
->lmva_ColumnFlags
[index
] & LVMCF_COLVISIBLE
)
665 static void RenderEntryField(Object
*obj
, struct IconList_DATA
*data
,
666 struct IconEntry
*entry
, struct Rectangle
*rect
,
667 LONG index
, BOOL firstvis
, BOOL lastvis
)
670 struct TextExtent te
;
673 if (entry
->ie_Flags
& ICONENTRY_FLAG_SELECTED
)
675 FillPixelArray(data
->icld_BufferRastPort
,
676 rect
->MinX
, rect
->MinY
,
677 rect
->MaxX
- rect
->MinX
+ 1, rect
->MaxY
- rect
->MinY
,
681 rect
->MinX
+= ENTRY_SPACING_LEFT
;
682 rect
->MaxX
-= ENTRY_SPACING_RIGHT
;
683 rect
->MinY
+= LINE_SPACING_TOP
;
684 rect
->MaxY
-= LINE_SPACING_BOTTOM
;
686 if (firstvis
) rect
->MinX
+= LINE_SPACING_LEFT
;
687 if (lastvis
) rect
->MaxX
-= LINE_SPACING_RIGHT
;
694 text
= entry
->ie_IconListEntry
.label
;
698 text
= entry
->ie_TxtBuf_SIZE
;
702 text
= entry
->ie_TxtBuf_DATE
;
706 text
= entry
->ie_TxtBuf_TIME
;
710 text
= entry
->ie_FileInfoBlock
->fib_Comment
;
713 case INDEX_PROTECTION
:
714 text
= entry
->ie_TxtBuf_PROT
;
719 if (!text
[0]) return;
721 fit
= TextFit(data
->icld_BufferRastPort
, text
, strlen(text
), &te
, NULL
, 1,
722 rect
->MaxX
- rect
->MinX
+ 1,
723 rect
->MaxY
- rect
->MinY
+ 1);
727 SetABPenDrMd(data
->icld_BufferRastPort
, _pens(obj
)[(entry
->ie_Flags
& ICONENTRY_FLAG_SELECTED
) ? MPEN_SHINE
: MPEN_TEXT
], 0, JAM1
);
729 switch(data
->icld_LVMAttribs
->lmva_ColumnAlign
[index
])
731 case COLUMN_ALIGN_LEFT
:
732 Move(data
->icld_BufferRastPort
, rect
->MinX
, rect
->MinY
+ data
->icld_BufferRastPort
->TxBaseline
);
735 case COLUMN_ALIGN_RIGHT
:
736 Move(data
->icld_BufferRastPort
, rect
->MaxX
- te
.te_Width
, rect
->MinY
+ data
->icld_BufferRastPort
->TxBaseline
);
739 case COLUMN_ALIGN_CENTER
:
740 Move(data
->icld_BufferRastPort
, rect
->MinX
+ (rect
->MaxX
- rect
->MinX
+ 1 + 1 - te
.te_Width
) / 2,
741 rect
->MinY
+ data
->icld_BufferRastPort
->TxBaseline
);
745 Text(data
->icld_BufferRastPort
, text
, fit
);
748 /**************************************************************************
749 Draw the entry at its position
750 **************************************************************************/
751 ///IconList__MUIM_IconList_DrawEntry()
752 IPTR
IconList__MUIM_IconList_DrawEntry(struct IClass
*CLASS
, Object
*obj
, struct MUIP_IconList_DrawEntry
*message
)
754 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
756 BOOL outside
= FALSE
;
758 struct Rectangle iconrect
;
759 struct Rectangle objrect
;
761 LONG offsetx
,offsety
;
763 ULONG objX
, objY
, objW
, objH
;
767 if (data
->icld_BufferRastPort
== data
->icld_DisplayRastPort
)
776 objW
= _mright(obj
) - _mleft(obj
) + 1;
777 objH
= _mbottom(obj
) - _mtop(obj
) + 1;
779 #if defined(DEBUG_ILC_ICONRENDERING)
780 D(bug("[IconList]: %s(message->entry = 0x%p)\n", __PRETTY_FUNCTION__
, message
->entry
));
783 if ((!(message
->entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)) ||
784 (data
->icld_BufferRastPort
== NULL
) ||
785 (!(message
->entry
->ie_DiskObj
)))
787 #if defined(DEBUG_ILC_ICONRENDERING)
788 D(bug("[IconList] %s: Not visible or missing DOB\n", __PRETTY_FUNCTION__
));
793 /* Set the dimensions of our "view" */
796 objrect
.MaxX
= objX
+ objW
- 1;
797 objrect
.MaxY
= objY
+ objH
- 1;
799 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
801 struct Rectangle linerect
;
803 LONG firstvis
, lastvis
;
805 linerect
.MinX
= objX
- data
->icld_ViewX
;
806 linerect
.MaxX
= objX
+ objW
- 1; //linerect.MinX + data->width - 1;
807 linerect
.MinY
= (objY
- data
->icld_ViewY
) + data
->icld_LVMAttribs
->lmva_HeaderHeight
+ (message
->drawmode
* data
->icld_LVMAttribs
->lmva_RowHeight
);
808 linerect
.MaxY
= linerect
.MinY
+ data
->icld_LVMAttribs
->lmva_RowHeight
- 1;
810 if (!AndRectRect(&linerect
, &objrect
, NULL
)) return;
811 // if (!MustRenderRect(data, &linerect)) return;
813 SetFont(data
->icld_BufferRastPort
, data
->icld_IconLabelFont
);
815 x
= linerect
.MinX
+ LINE_SPACING_LEFT
;
817 firstvis
= FirstVisibleColumnNumber(data
);
818 lastvis
= LastVisibleColumnNumber(data
);
820 for(i
= 0; i
< NUM_COLUMNS
; i
++)
822 struct Rectangle field_rect
;
823 LONG index
= data
->icld_LVMAttribs
->lmva_ColumnPos
[i
];
825 if (!(data
->icld_LVMAttribs
->lmva_ColumnFlags
[i
] & LVMCF_COLVISIBLE
)) continue;
827 field_rect
.MinX
= (i
== firstvis
) ? linerect
.MinX
: x
;
828 field_rect
.MinY
= linerect
.MinY
;
829 field_rect
.MaxX
= x
+ data
->icld_LVMAttribs
->lmva_ColumnWidth
[index
] - 1 + ((i
== lastvis
) ? LINE_SPACING_RIGHT
: 0);
830 field_rect
.MaxY
= linerect
.MaxY
;
832 /* if (MustRenderRect(data, &field_rect))
834 if (AndRectRect(&field_rect
, &objrect
, NULL
))
836 RenderEntryField(obj
, data
, message
->entry
, &field_rect
, index
,
837 (i
== firstvis
), (i
== lastvis
));
840 x
+= data
->icld_LVMAttribs
->lmva_ColumnWidth
[index
];
843 if ((data
->icld_LVMAttribs
->lvma_Flags
& LVMAF_ROWDRAWTOEND
) == LVMAF_ROWDRAWTOEND
)
845 x
+= LINE_SPACING_RIGHT
;
847 if (x
< linerect
.MaxX
)
851 SetABPenDrMd(data
->icld_BufferRastPort
, _pens(obj
)[MPEN_SHINE
], 0, JAM1
);
852 RectFill(data
->icld_BufferRastPort
, linerect
.MinX
, linerect
.MinY
, linerect
.MaxX
, linerect
.MaxY
);
858 /* Get the dimensions and affected area of message->entry */
859 IconList_GetIconImageRectangle(obj
, data
, message
->entry
, &iconrect
);
860 iconW
= iconrect
.MaxX
- iconrect
.MinX
+ 1;
861 iconH
= iconrect
.MaxY
- iconrect
.MinY
+ 1;
863 /* Add the relative position offset of the message->entry */
864 offsetx
= objX
- data
->icld_ViewX
+ message
->entry
->ie_IconX
;
865 /* Centre our image with our text */
866 if (message
->entry
->ie_IconWidth
< message
->entry
->ie_AreaWidth
)
867 offsetx
+= (message
->entry
->ie_AreaWidth
- message
->entry
->ie_IconWidth
)/2;
869 if ((data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
) &&
870 (message
->entry
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
))
871 offsetx
+= ((data
->icld_IconAreaLargestWidth
- message
->entry
->ie_AreaWidth
)/2);
873 iconrect
.MinX
+= offsetx
;
874 iconrect
.MaxX
+= offsetx
;
876 offsety
= objY
- data
->icld_ViewY
+ message
->entry
->ie_IconY
;
877 iconrect
.MinY
+= offsety
;
878 iconrect
.MaxY
+= offsety
;
880 if (!RectAndRect(&iconrect
, &objrect
))
882 #if defined(DEBUG_ILC_ICONRENDERING)
883 D(bug("[IconList] %s: Entry '%s' image outside of visible area .. skipping\n", __PRETTY_FUNCTION__
, message
->entry
->ie_IconListEntry
.label
));
888 /* data->update_rect1 and data->update_rect2 may
889 point to rectangles to indicate that only icons
890 in any of this rectangles need to be drawn */
891 if (data
->update_rect1
)
893 if (!RectAndRect(&iconrect
, data
->update_rect1
)) outside
= TRUE
;
896 if (data
->update_rect2
)
898 if (data
->update_rect1
)
900 if ((outside
== TRUE
) && RectAndRect(&iconrect
, data
->update_rect2
))
905 if (!RectAndRect(&iconrect
, data
->update_rect2
))
912 #if defined(DEBUG_ILC_ICONRENDERING)
913 D(bug("[IconList] %s: Entry '%s' image outside of update area .. skipping\n", __PRETTY_FUNCTION__
, message
->entry
->ie_IconListEntry
.label
));
918 if (message
->drawmode
== ICONENTRY_DRAWMODE_NONE
) return TRUE
;
920 // Center entry image
921 iconX
= iconrect
.MinX
- objX
+ data
->icld_DrawOffsetX
;
922 iconY
= iconrect
.MinY
- objY
+ data
->icld_DrawOffsetY
;
924 #if defined(DEBUG_ILC_ICONRENDERING)
925 D(bug("[IconList] %s: DrawIconState('%s') .. %d, %d\n", __PRETTY_FUNCTION__
, message
->entry
->ie_IconListEntry
.label
, iconX
, iconY
));
929 data
->icld_BufferRastPort
, message
->entry
->ie_DiskObj
, NULL
,
932 (message
->entry
->ie_Flags
& ICONENTRY_FLAG_SELECTED
) ? IDS_SELECTED
: IDS_NORMAL
,
933 __iconList_DrawIconStateTags
935 #if defined(DEBUG_ILC_ICONRENDERING)
936 D(bug("[IconList] %s: DrawIconState Done\n", __PRETTY_FUNCTION__
));
944 ///IconList__LabelFunc_SplitLabel()
945 static void IconList__LabelFunc_SplitLabel(Object
*obj
, struct IconList_DATA
*data
, struct IconEntry
*entry
)
947 ULONG labelSplit_MaxLabelLineLength
= data
->icld__Option_LabelTextMaxLen
;
948 ULONG labelSplit_LabelLength
= strlen(entry
->ie_IconListEntry
.label
);
950 // ULONG labelSplit_FontY = data->icld_IconLabelFont->tf_YSize;
951 int labelSplit_CharsDone
, labelSplit_CharsSplit
;
952 ULONG labelSplit_CurSplitWidth
;
954 if ((data
->icld__Option_TrimVolumeNames
) &&
955 ((entry
->ie_IconListEntry
.type
== ST_ROOT
) && (entry
->ie_IconListEntry
.label
[labelSplit_LabelLength
- 1] == ':')))
956 labelSplit_LabelLength
--;
958 if (labelSplit_MaxLabelLineLength
>= labelSplit_LabelLength
)
960 #if defined(DEBUG_ILC_ICONRENDERING)
961 D(bug("[IconList]: %s: Label'%s' doesnt need split (onyl %d chars)\n", __PRETTY_FUNCTION__
, entry
->ie_IconListEntry
.label
, labelSplit_LabelLength
));
966 SetFont(data
->icld_BufferRastPort
, data
->icld_IconLabelFont
);
967 txwidth
= TextLength(data
->icld_BufferRastPort
, entry
->ie_IconListEntry
.label
, labelSplit_MaxLabelLineLength
);
968 #if defined(DEBUG_ILC_ICONRENDERING)
969 D(bug("[IconList]: %s: txwidth = %d\n", __PRETTY_FUNCTION__
, txwidth
));
971 entry
->ie_TxtBuf_DisplayedLabel
= AllocVecPooled(data
->icld_Pool
, 256);
972 memset(entry
->ie_TxtBuf_DisplayedLabel
, 0, 256);
973 entry
->ie_SplitParts
= 0;
975 labelSplit_CharsDone
= 0;
976 labelSplit_CharsSplit
= 0;
978 while (labelSplit_CharsDone
< labelSplit_LabelLength
)
980 ULONG labelSplit_CurSplitLength
= labelSplit_LabelLength
- labelSplit_CharsDone
;
981 IPTR labelSplit_SplitStart
= (IPTR
)(entry
->ie_IconListEntry
.label
+ labelSplit_CharsDone
);
982 int tmp_checkoffs
= 0;
983 IPTR labelSplit_RemainingCharsAfterSplit
;
984 IPTR labelSplit_CurSplitDest
;
986 while (*(char *)(labelSplit_SplitStart
) == ' ')
988 //Skip preceding spaces..
989 labelSplit_SplitStart
= labelSplit_SplitStart
+ 1;
990 labelSplit_CurSplitLength
= labelSplit_CurSplitLength
- 1;
991 labelSplit_CharsDone
= labelSplit_CharsDone
+ 1;
994 while(TextLength(data
->icld_BufferRastPort
, (char *)labelSplit_SplitStart
, labelSplit_CurSplitLength
) < txwidth
) labelSplit_CurSplitLength
++;
995 while(TextLength(data
->icld_BufferRastPort
, (char *)labelSplit_SplitStart
, labelSplit_CurSplitLength
) > txwidth
) labelSplit_CurSplitLength
--;
996 #if defined(DEBUG_ILC_ICONRENDERING)
997 D(bug("[IconList]: %s: labelSplit_CurSplitLength = %d\n", __PRETTY_FUNCTION__
, labelSplit_CurSplitLength
));
1000 #if defined(DEBUG_ILC_ICONRENDERING)
1001 D(bug("[IconList]: %s: Attempting to find neat split ", __PRETTY_FUNCTION__
));
1003 while(tmp_checkoffs
< (labelSplit_CurSplitLength
- ILC_ICONLABEL_SHORTEST
))
1005 #if defined(DEBUG_ILC_ICONRENDERING)
1006 D(bug("%d", tmp_checkoffs
));
1008 labelSplit_RemainingCharsAfterSplit
= labelSplit_LabelLength
- (labelSplit_CharsDone
+ labelSplit_CurSplitLength
);
1010 if ((labelSplit_CurSplitLength
- tmp_checkoffs
) > ILC_ICONLABEL_SHORTEST
)
1012 #if defined(DEBUG_ILC_ICONRENDERING)
1015 if ((*(char *)(labelSplit_SplitStart
+ labelSplit_CurSplitLength
- tmp_checkoffs
) == ' ') ||
1016 (*(char *)(labelSplit_SplitStart
+ labelSplit_CurSplitLength
- tmp_checkoffs
) == '.') ||
1017 (*(char *)(labelSplit_SplitStart
+ labelSplit_CurSplitLength
- tmp_checkoffs
) == '-'))
1019 #if defined(DEBUG_ILC_ICONRENDERING)
1022 labelSplit_CurSplitLength
= labelSplit_CurSplitLength
- tmp_checkoffs
;
1023 labelSplit_RemainingCharsAfterSplit
= labelSplit_RemainingCharsAfterSplit
- tmp_checkoffs
;
1029 if ((labelSplit_RemainingCharsAfterSplit
- tmp_checkoffs
) < 0)
1031 #if defined(DEBUG_ILC_ICONRENDERING)
1034 labelSplit_CurSplitLength
= labelSplit_CurSplitLength
+ tmp_checkoffs
;
1035 labelSplit_RemainingCharsAfterSplit
= labelSplit_RemainingCharsAfterSplit
+ tmp_checkoffs
;
1040 if ((labelSplit_RemainingCharsAfterSplit
- tmp_checkoffs
) >= ILC_ICONLABEL_SHORTEST
)
1042 #if defined(DEBUG_ILC_ICONRENDERING)
1045 if ((*(char *)(labelSplit_SplitStart
+ labelSplit_CurSplitLength
+ tmp_checkoffs
) == ' ') ||
1046 (*(char *)(labelSplit_SplitStart
+ labelSplit_CurSplitLength
+ tmp_checkoffs
) == '.') ||
1047 (*(char *)(labelSplit_SplitStart
+ labelSplit_CurSplitLength
+ tmp_checkoffs
) == '-'))
1049 #if defined(DEBUG_ILC_ICONRENDERING)
1052 labelSplit_CurSplitLength
= labelSplit_CurSplitLength
+ tmp_checkoffs
;
1053 labelSplit_RemainingCharsAfterSplit
= labelSplit_RemainingCharsAfterSplit
+ tmp_checkoffs
;
1059 tmp_checkoffs
= tmp_checkoffs
+ 1;
1061 #if defined(DEBUG_ILC_ICONRENDERING)
1064 if (tmp_checkoffs
!= 0)
1066 #if defined(DEBUG_ILC_ICONRENDERING)
1067 D(bug("[IconList]: %s: Couldnt find neat split : Still %d chars\n", __PRETTY_FUNCTION__
, labelSplit_RemainingCharsAfterSplit
));
1069 if (labelSplit_RemainingCharsAfterSplit
<= ILC_ICONLABEL_SHORTEST
)
1071 labelSplit_CurSplitLength
= labelSplit_CurSplitLength
+ (labelSplit_RemainingCharsAfterSplit
- ILC_ICONLABEL_SHORTEST
);
1074 if ((labelSplit_CharsDone
+ labelSplit_CurSplitLength
) > labelSplit_LabelLength
) labelSplit_CurSplitLength
= labelSplit_LabelLength
- labelSplit_CharsDone
;
1076 labelSplit_CurSplitDest
= (IPTR
)(entry
->ie_TxtBuf_DisplayedLabel
+ labelSplit_CharsSplit
+ entry
->ie_SplitParts
);
1078 strncpy((char *)labelSplit_CurSplitDest
, (char *)labelSplit_SplitStart
, labelSplit_CurSplitLength
);
1080 labelSplit_CurSplitWidth
= TextLength(data
->icld_BufferRastPort
, (char *)labelSplit_CurSplitDest
, labelSplit_CurSplitLength
);
1082 entry
->ie_SplitParts
= entry
->ie_SplitParts
+ 1;
1084 labelSplit_CharsDone
= labelSplit_CharsDone
+ labelSplit_CurSplitLength
;
1085 labelSplit_CharsSplit
= labelSplit_CharsSplit
+ labelSplit_CurSplitLength
;
1087 if (labelSplit_CurSplitWidth
> entry
->ie_TxtBuf_DisplayedLabelWidth
) entry
->ie_TxtBuf_DisplayedLabelWidth
= labelSplit_CurSplitWidth
;
1089 if ((entry
->ie_SplitParts
<= 1) && entry
->ie_TxtBuf_DisplayedLabel
)
1091 FreeVecPooled(data
->icld_Pool
, entry
->ie_TxtBuf_DisplayedLabel
);
1092 entry
->ie_TxtBuf_DisplayedLabel
= NULL
;
1093 entry
->ie_SplitParts
= 0;
1095 // if ((labelSplit_FontY * entry->ie_SplitParts) > data->icld_LabelLargestHeight) data->icld_LabelLargestHeight = (labelSplit_FontY * entry->ie_SplitParts);
1099 ///IconList__LabelFunc_CreateLabel()
1100 static IPTR
IconList__LabelFunc_CreateLabel(Object
*obj
, struct IconList_DATA
*data
, struct IconEntry
*entry
)
1102 #if defined(DEBUG_ILC_ICONRENDERING) && defined(DEBUG_ILC_FUNCS)
1103 D(bug("[IconList]: %s('%s')\n", __PRETTY_FUNCTION__
, entry
->ie_IconListEntry
.label
));
1105 if (entry
->ie_TxtBuf_DisplayedLabel
)
1107 FreeVecPooled(data
->icld_Pool
, entry
->ie_TxtBuf_DisplayedLabel
);
1108 entry
->ie_TxtBuf_DisplayedLabel
= NULL
;
1109 entry
->ie_SplitParts
= 0;
1112 if (data
->icld__Option_LabelTextMultiLine
> 1)
1114 #if defined(DEBUG_ILC_ICONRENDERING)
1115 D(bug("[IconList]: %s: Attempting to split label ..\n", __PRETTY_FUNCTION__
));
1117 IconList__LabelFunc_SplitLabel(obj
, data
, entry
);
1120 if (entry
->ie_TxtBuf_DisplayedLabel
== NULL
)
1122 ULONG ie_LabelLength
= strlen(entry
->ie_IconListEntry
.label
);
1123 entry
->ie_SplitParts
= 1;
1125 #if defined(DEBUG_ILC_ICONRENDERING)
1126 D(bug("[IconList]: %s: Building unsplit label (len = %d) ..\n", __PRETTY_FUNCTION__
, ie_LabelLength
));
1129 if ((data
->icld__Option_TrimVolumeNames
) &&
1130 ((entry
->ie_IconListEntry
.type
== ST_ROOT
) && (entry
->ie_IconListEntry
.label
[ie_LabelLength
- 1] == ':')))
1133 if(ie_LabelLength
> data
->icld__Option_LabelTextMaxLen
)
1135 if (!(entry
->ie_TxtBuf_DisplayedLabel
= AllocVecPooled(data
->icld_Pool
, data
->icld__Option_LabelTextMaxLen
+ 1)))
1139 memset(entry
->ie_TxtBuf_DisplayedLabel
, 0, data
->icld__Option_LabelTextMaxLen
+ 1);
1140 strncpy(entry
->ie_TxtBuf_DisplayedLabel
, entry
->ie_IconListEntry
.label
, data
->icld__Option_LabelTextMaxLen
- 3);
1141 strcat(entry
->ie_TxtBuf_DisplayedLabel
, " ..");
1145 if (!(entry
->ie_TxtBuf_DisplayedLabel
= AllocVecPooled(data
->icld_Pool
, ie_LabelLength
+ 1)))
1149 memset(entry
->ie_TxtBuf_DisplayedLabel
, 0, ie_LabelLength
+ 1);
1150 strncpy(entry
->ie_TxtBuf_DisplayedLabel
, entry
->ie_IconListEntry
.label
, ie_LabelLength
);
1152 entry
->ie_TxtBuf_DisplayedLabelWidth
= TextLength(data
->icld_BufferRastPort
, entry
->ie_TxtBuf_DisplayedLabel
, strlen(entry
->ie_TxtBuf_DisplayedLabel
));
1153 // if ((data->icld_IconLabelFont->tf_YSize) > data->icld_LabelLargestHeight) data->icld_LabelLargestHeight = data->icld_IconLabelFont->tf_YSize;
1156 // if (entry->ie_TxtBuf_DisplayedLabelWidth > data->icld_LabelLargestWidth) data->icld_LabelLargestWidth = entry->ie_TxtBuf_DisplayedLabelWidth;
1158 return (IPTR
)entry
->ie_TxtBuf_DisplayedLabel
;
1162 ///IconList__HookFunc_UpdateLabelsFunc()
1164 void, IconList__HookFunc_UpdateLabelsFunc
,
1165 AROS_UFHA(struct Hook
*, hook
, A0
),
1166 AROS_UFHA(APTR
*, obj
, A2
),
1167 AROS_UFHA(APTR
, param
, A1
)
1172 /* Get our private data */
1173 Class
*CLASS
= *( Class
**)param
;
1174 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
1176 #if defined(DEBUG_ILC_LASSO) && defined(DEBUG_ILC_FUNCS)
1177 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
1180 if (((data
->icld__Option_LabelTextMaxLen
!= data
->icld__Option_LastLabelTextMaxLen
) &&
1181 (data
->icld__Option_LabelTextMultiLine
> 1)) ||
1182 (data
->icld__Option_LabelTextMultiLine
!= data
->icld__Option_LastLabelTextMultiLine
));
1184 struct IconEntry
*iconentry_Current
= NULL
;
1185 #if defined(__AROS__)
1186 ForeachNode(&data
->icld_IconList
, iconentry_Current
)
1188 Foreach_Node(&data
->icld_IconList
, iconentry_Current
);
1191 IconList__LabelFunc_CreateLabel((Object
*)obj
, data
, iconentry_Current
);
1195 data
->icld__Option_LastLabelTextMaxLen
= data
->icld__Option_LabelTextMaxLen
;
1196 data
->icld__Option_LastLabelTextMultiLine
= data
->icld__Option_LabelTextMultiLine
;
1202 ///IconList__MUIM_IconList_DrawEntryLabel()
1203 IPTR
IconList__MUIM_IconList_DrawEntryLabel(struct IClass
*CLASS
, Object
*obj
, struct MUIP_IconList_DrawEntry
*message
)
1205 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
1208 BOOL outside
= FALSE
;
1210 struct Rectangle iconlabelrect
;
1211 struct Rectangle objrect
;
1213 ULONG txtbox_width
= 0;
1214 LONG tx
,ty
,offsetx
,offsety
;
1215 LONG txwidth
; // txheight;
1217 ULONG objX
, objY
, objW
, objH
;
1218 LONG labelX
, labelY
;
1219 ULONG labelW
, labelH
;
1221 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
1224 if (data
->icld_BufferRastPort
== data
->icld_DisplayRastPort
)
1233 objW
= _mright(obj
) - _mleft(obj
) + 1;
1234 objH
= _mbottom(obj
) - _mtop(obj
) + 1;
1236 ULONG txtarea_width
;
1237 ULONG curlabel_TotalLines
, curlabel_CurrentLine
, offset_y
;
1239 #if defined(DEBUG_ILC_ICONRENDERING) && defined(DEBUG_ILC_FUNCS)
1240 D(bug("[IconList]: %s(message->entry = 0x%p), '%s'\n", __PRETTY_FUNCTION__
, message
->entry
, message
->entry
->ie_IconListEntry
.label
));
1243 if ((!(message
->entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)) ||
1244 (data
->icld_BufferRastPort
== NULL
) ||
1245 (!(message
->entry
->ie_DiskObj
)))
1247 #if defined(DEBUG_ILC_ICONRENDERING)
1248 D(bug("[IconList] %s: Not visible or missing DOB\n", __PRETTY_FUNCTION__
));
1253 /* Get the dimensions and affected area of message->entry's label */
1254 IconList_GetIconLabelRectangle(obj
, data
, message
->entry
, &iconlabelrect
);
1255 labelW
= iconlabelrect
.MaxX
- iconlabelrect
.MinX
+ 1;
1256 labelH
= iconlabelrect
.MaxY
- iconlabelrect
.MinY
+ 1;
1258 /* Add the relative position offset of the message->entry's label */
1259 offsetx
= (objX
- data
->icld_ViewX
) + message
->entry
->ie_IconX
;
1260 txtbox_width
= (iconlabelrect
.MaxX
- iconlabelrect
.MinX
) + 1;
1262 if (txtbox_width
< message
->entry
->ie_AreaWidth
)
1263 offsetx
+= ((message
->entry
->ie_AreaWidth
- txtbox_width
)/2);
1265 if ((data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
) &&
1266 (message
->entry
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
))
1267 offsetx
+= ((data
->icld_IconAreaLargestWidth
- message
->entry
->ie_AreaWidth
)/2);
1269 iconlabelrect
.MinX
+= offsetx
;
1270 iconlabelrect
.MaxX
+= offsetx
;
1272 offsety
= (objY
- data
->icld_ViewY
) + message
->entry
->ie_IconY
+ data
->icld__Option_IconImageSpacing
;
1273 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
1275 offsety
= offsety
+ data
->icld_IconLargestHeight
;
1279 offsety
= offsety
+ message
->entry
->ie_IconHeight
;
1281 iconlabelrect
.MinY
+= offsety
;
1282 iconlabelrect
.MaxY
+= offsety
;
1284 /* Add the relative position of the window */
1285 objrect
.MinX
= objX
;
1286 objrect
.MinY
= objX
;
1287 objrect
.MaxX
= objX
+ objW
;
1288 objrect
.MaxY
= objY
+ objH
;
1290 if (!RectAndRect(&iconlabelrect
, &objrect
))
1292 #if defined(DEBUG_ILC_ICONRENDERING)
1293 (bug("[IconList] %s: Entry '%s' label outside of visible area .. skipping\n", __PRETTY_FUNCTION__
, message
->entry
->ie_IconListEntry
.label
));
1298 /* data->update_rect1 and data->update_rect2 may
1299 point to rectangles to indicate that only icons
1300 in any of this rectangles need to be drawn */
1301 if (data
->update_rect1
)
1303 if (!RectAndRect(&iconlabelrect
, data
->update_rect1
))
1307 if (data
->update_rect2
)
1309 if (data
->update_rect1
)
1311 if ((outside
== TRUE
) && RectAndRect(&iconlabelrect
, data
->update_rect2
))
1316 if (!RectAndRect(&iconlabelrect
, data
->update_rect2
))
1321 if (outside
== TRUE
)
1323 #if defined(DEBUG_ILC_ICONRENDERING)
1324 D(bug("[IconList] %s: Entry '%s' label outside of update area .. skipping\n", __PRETTY_FUNCTION__
, message
->entry
->ie_IconListEntry
.label
));
1329 if (message
->drawmode
== ICONENTRY_DRAWMODE_NONE
)
1332 SetABPenDrMd(data
->icld_BufferRastPort
, _pens(obj
)[MPEN_TEXT
], 0, JAM1
);
1334 iconlabelrect
.MinX
= (iconlabelrect
.MinX
- objX
) + data
->icld_DrawOffsetX
;
1335 iconlabelrect
.MinY
= (iconlabelrect
.MinY
- objY
) + data
->icld_DrawOffsetY
;
1336 iconlabelrect
.MaxX
= (iconlabelrect
.MaxX
- objX
) + data
->icld_DrawOffsetX
;
1337 iconlabelrect
.MaxY
= (iconlabelrect
.MaxY
- objY
) + data
->icld_DrawOffsetY
;
1339 labelX
= iconlabelrect
.MinX
+ data
->icld__Option_LabelTextBorderWidth
+ data
->icld__Option_LabelTextHorizontalPadding
;
1340 labelY
= iconlabelrect
.MinY
+ data
->icld__Option_LabelTextBorderHeight
+ data
->icld__Option_LabelTextVerticalPadding
;
1342 txtarea_width
= txtbox_width
- ((data
->icld__Option_LabelTextBorderWidth
+ data
->icld__Option_LabelTextHorizontalPadding
) * 2);
1344 #if defined(DEBUG_ILC_ICONRENDERING)
1345 D(bug("[IconList] %s: Drawing Label '%s' .. %d, %d\n", __PRETTY_FUNCTION__
, message
->entry
->ie_IconListEntry
.label
, labelX
, labelY
));
1347 if (message
->entry
->ie_IconListEntry
.label
&& message
->entry
->ie_TxtBuf_DisplayedLabel
)
1349 char *curlabel_StrPtr
;
1351 if ((message
->entry
->ie_Flags
& ICONENTRY_FLAG_FOCUS
) && ((BOOL
)XGET(_win(obj
), MUIA_Window_Activate
)))
1353 //Draw the focus box around the selected label ..
1354 if (data
->icld__Option_LabelTextBorderHeight
> 0)
1356 InvertPixelArray(data
->icld_BufferRastPort
,
1357 iconlabelrect
.MinX
, iconlabelrect
.MinY
,
1358 (iconlabelrect
.MaxX
- iconlabelrect
.MinX
) + 1, data
->icld__Option_LabelTextBorderHeight
);
1360 InvertPixelArray(data
->icld_BufferRastPort
,
1361 iconlabelrect
.MinX
, iconlabelrect
.MaxY
- (data
->icld__Option_LabelTextBorderHeight
- 1),
1362 (iconlabelrect
.MaxX
- iconlabelrect
.MinX
) + 1, data
->icld__Option_LabelTextBorderHeight
);
1364 if (data
->icld__Option_LabelTextBorderWidth
> 0)
1366 InvertPixelArray(data
->icld_BufferRastPort
,
1367 iconlabelrect
.MinX
, iconlabelrect
.MinY
+ data
->icld__Option_LabelTextBorderHeight
,
1368 data
->icld__Option_LabelTextBorderWidth
, (((iconlabelrect
.MaxY
- iconlabelrect
.MinY
) + 1) - (data
->icld__Option_LabelTextBorderHeight
* 2)));
1370 InvertPixelArray(data
->icld_BufferRastPort
,
1371 iconlabelrect
.MaxX
- (data
->icld__Option_LabelTextBorderWidth
- 1), iconlabelrect
.MinY
+ data
->icld__Option_LabelTextBorderHeight
,
1372 data
->icld__Option_LabelTextBorderWidth
, (((iconlabelrect
.MaxY
- iconlabelrect
.MinY
) + 1) - (data
->icld__Option_LabelTextBorderHeight
* 2)));
1376 SetFont(data
->icld_BufferRastPort
, data
->icld_IconLabelFont
);
1378 curlabel_TotalLines
= message
->entry
->ie_SplitParts
;
1379 curlabel_CurrentLine
= 0;
1381 if (curlabel_TotalLines
== 0)
1382 curlabel_TotalLines
= 1;
1384 if (!(data
->icld__Option_LabelTextMultiLineOnFocus
) || (data
->icld__Option_LabelTextMultiLineOnFocus
&& (message
->entry
->ie_Flags
& ICONENTRY_FLAG_FOCUS
)))
1386 if (curlabel_TotalLines
> data
->icld__Option_LabelTextMultiLine
)
1387 curlabel_TotalLines
= data
->icld__Option_LabelTextMultiLine
;
1390 curlabel_TotalLines
= 1;
1392 curlabel_StrPtr
= message
->entry
->ie_TxtBuf_DisplayedLabel
;
1396 #if defined(DEBUG_ILC_ICONRENDERING)
1397 D(bug("[IconList] %s: Font YSize %d Baseline %d\n", __PRETTY_FUNCTION__
,data
->icld_IconLabelFont
->tf_YSize
, data
->icld_IconLabelFont
->tf_Baseline
));
1399 for (curlabel_CurrentLine
= 0; curlabel_CurrentLine
< curlabel_TotalLines
; curlabel_CurrentLine
++)
1401 ULONG ie_LabelLength
;
1403 if (curlabel_CurrentLine
> 0) curlabel_StrPtr
= curlabel_StrPtr
+ strlen(curlabel_StrPtr
) + 1;
1404 if ((curlabel_CurrentLine
>= (curlabel_TotalLines
-1)) && (curlabel_TotalLines
< message
->entry
->ie_SplitParts
))
1406 char *tmpLine
= curlabel_StrPtr
;
1407 ULONG tmpLen
= strlen(tmpLine
);
1409 if ((curlabel_StrPtr
= AllocVecPooled(data
->icld_Pool
, tmpLen
+ 1)) != NULL
)
1411 memset(curlabel_StrPtr
, 0, tmpLen
+ 1);
1412 strncpy(curlabel_StrPtr
, tmpLine
, tmpLen
- 3);
1413 strcat(curlabel_StrPtr
, " ..");
1420 ie_LabelLength
= strlen(curlabel_StrPtr
);
1423 // Center message->entry's label
1424 tx
= (labelX
+ (message
->entry
->ie_TxtBuf_DisplayedLabelWidth
/ 2) - (TextLength(data
->icld_BufferRastPort
, curlabel_StrPtr
, strlen(curlabel_StrPtr
)) / 2));
1426 if (message
->entry
->ie_TxtBuf_DisplayedLabelWidth
< txtarea_width
)
1427 tx
+= ((txtarea_width
- message
->entry
->ie_TxtBuf_DisplayedLabelWidth
)/2);
1429 ty
= ty
+ data
->icld_IconLabelFont
->tf_YSize
;
1431 switch ( data
->icld__Option_LabelTextMode
)
1433 case ICON_TEXTMODE_DROPSHADOW
:
1434 SetAPen(data
->icld_BufferRastPort
, data
->icld_LabelShadowPen
);
1435 Move(data
->icld_BufferRastPort
, tx
+ 1, ty
+ 1);
1436 Text(data
->icld_BufferRastPort
, curlabel_StrPtr
, ie_LabelLength
);
1438 case ICON_TEXTMODE_PLAIN
:
1439 SetAPen(data
->icld_BufferRastPort
, data
->icld_LabelPen
);
1440 Move(data
->icld_BufferRastPort
, tx
, ty
);
1441 Text(data
->icld_BufferRastPort
, curlabel_StrPtr
, ie_LabelLength
);
1446 SetSoftStyle(data
->icld_BufferRastPort
, FSF_BOLD
, AskSoftStyle(data
->icld_BufferRastPort
));
1448 SetAPen(data
->icld_BufferRastPort
, data
->icld_LabelShadowPen
);
1449 Move(data
->icld_BufferRastPort
, tx
+ 1, ty
);
1450 Text(data
->icld_BufferRastPort
, curlabel_StrPtr
, ie_LabelLength
);
1451 Move(data
->icld_BufferRastPort
, tx
- 1, ty
);
1452 Text(data
->icld_BufferRastPort
, curlabel_StrPtr
, ie_LabelLength
);
1453 Move(data
->icld_BufferRastPort
, tx
, ty
+ 1);
1454 Text(data
->icld_BufferRastPort
, curlabel_StrPtr
, ie_LabelLength
);
1455 Move(data
->icld_BufferRastPort
, tx
, ty
- 1);
1456 Text(data
->icld_BufferRastPort
, curlabel_StrPtr
, ie_LabelLength
);
1458 SetAPen(data
->icld_BufferRastPort
, data
->icld_LabelPen
);
1459 Move(data
->icld_BufferRastPort
, tx
, ty
);
1460 Text(data
->icld_BufferRastPort
, curlabel_StrPtr
, ie_LabelLength
);
1462 SetSoftStyle(data
->icld_BufferRastPort
, FS_NORMAL
, AskSoftStyle(data
->icld_BufferRastPort
));
1466 if ((curlabel_CurrentLine
>= (curlabel_TotalLines
-1)) && (curlabel_TotalLines
< message
->entry
->ie_SplitParts
))
1468 FreeVecPooled(data
->icld_Pool
, curlabel_StrPtr
);
1473 /*date/size sorting has the date/size appended under the message->entry label*/
1475 if ((message
->entry
->ie_IconListEntry
.type
!= ST_USERDIR
) && ((data
->icld_SortFlags
& (MUIV_IconList_Sort_BySize
|MUIV_IconList_Sort_ByDate
)) != 0))
1478 SetFont(data
->icld_BufferRastPort
, data
->icld_IconInfoFont
);
1480 if ((data
->icld_SortFlags
& MUIV_IconList_Sort_MASK
) == MUIV_IconList_Sort_BySize
)
1482 buf
= message
->entry
->ie_TxtBuf_SIZE
;
1483 txwidth
= message
->entry
->ie_TxtBuf_SIZEWidth
;
1485 else if ((data
->icld_SortFlags
& MUIV_IconList_Sort_MASK
) == MUIV_IconList_Sort_ByDate
)
1487 if (message
->entry
->ie_Flags
& ICONENTRY_FLAG_TODAY
)
1489 buf
= message
->entry
->ie_TxtBuf_TIME
;
1490 txwidth
= message
->entry
->ie_TxtBuf_TIMEWidth
;
1494 buf
= message
->entry
->ie_TxtBuf_DATE
;
1495 txwidth
= message
->entry
->ie_TxtBuf_DATEWidth
;
1501 ULONG ie_LabelLength
= strlen(buf
);
1504 if (txwidth
< txtarea_width
)
1505 tx
+= ((txtarea_width
- txwidth
)/2);
1507 ty
= labelY
+ ((data
->icld__Option_LabelTextVerticalPadding
+ data
->icld_IconLabelFont
->tf_YSize
) * curlabel_TotalLines
) + data
->icld_IconInfoFont
->tf_YSize
;
1509 switch ( data
->icld__Option_LabelTextMode
)
1511 case ICON_TEXTMODE_DROPSHADOW
:
1512 SetAPen(data
->icld_BufferRastPort
, data
->icld_InfoShadowPen
);
1513 Move(data
->icld_BufferRastPort
, tx
+ 1, ty
+ 1); Text(data
->icld_BufferRastPort
, buf
, ie_LabelLength
);
1514 case ICON_TEXTMODE_PLAIN
:
1515 SetAPen(data
->icld_BufferRastPort
, data
->icld_InfoPen
);
1516 Move(data
->icld_BufferRastPort
, tx
, ty
); Text(data
->icld_BufferRastPort
, buf
, ie_LabelLength
);
1521 SetSoftStyle(data
->icld_BufferRastPort
, FSF_BOLD
, AskSoftStyle(data
->icld_BufferRastPort
));
1522 SetAPen(data
->icld_BufferRastPort
, data
->icld_InfoShadowPen
);
1524 Move(data
->icld_BufferRastPort
, tx
+ 1, ty
);
1525 Text(data
->icld_BufferRastPort
, buf
, ie_LabelLength
);
1526 Move(data
->icld_BufferRastPort
, tx
- 1, ty
);
1527 Text(data
->icld_BufferRastPort
, buf
, ie_LabelLength
);
1528 Move(data
->icld_BufferRastPort
, tx
, ty
- 1 );
1529 Text(data
->icld_BufferRastPort
, buf
, ie_LabelLength
);
1530 Move(data
->icld_BufferRastPort
, tx
, ty
+ 1 );
1531 Text(data
->icld_BufferRastPort
, buf
, ie_LabelLength
);
1533 SetAPen(data
->icld_BufferRastPort
, data
->icld_InfoPen
);
1535 Move(data
->icld_BufferRastPort
, tx
, ty
);
1536 Text(data
->icld_BufferRastPort
, buf
, ie_LabelLength
);
1538 SetSoftStyle(data
->icld_BufferRastPort
, FS_NORMAL
, AskSoftStyle(data
->icld_BufferRastPort
));
1548 /**************************************************************************
1550 **************************************************************************/
1551 ///IconList__MUIM_IconList_RethinkDimensions()
1552 IPTR
IconList__MUIM_IconList_RethinkDimensions(struct IClass
*CLASS
, Object
*obj
, struct MUIP_IconList_RethinkDimensions
*message
)
1554 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
1556 struct IconEntry
*entry
= NULL
;
1559 struct Rectangle icon_rect
;
1561 #if defined(DEBUG_ILC_ICONPOSITIONING) && defined(DEBUG_ILC_FUNCS)
1562 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
1565 if (message
->singleicon
!= NULL
)
1567 entry
= message
->singleicon
;
1568 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
1570 maxy
= data
->icld_LVMAttribs
->lmva_RowHeight
;
1571 if ((data
->icld_LVMAttribs
->lvma_Flags
& LVMAF_NOHEADER
) == 0)
1573 maxy
+= data
->icld_LVMAttribs
->lmva_HeaderHeight
;
1578 maxx
= data
->icld_AreaWidth
- 1,
1579 maxy
= data
->icld_AreaHeight
- 1;
1582 #if defined(DEBUG_ILC_ICONPOSITIONING)
1583 D(bug("[IconList] %s: SingleIcon - maxx = %d, maxy = %d\n", __PRETTY_FUNCTION__
, maxx
, maxy
));
1588 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
1590 maxy
= data
->icld_LVMAttribs
->lmva_RowHeight
;
1591 if ((data
->icld_LVMAttribs
->lvma_Flags
& LVMAF_NOHEADER
) == 0)
1593 maxy
+= data
->icld_LVMAttribs
->lmva_HeaderHeight
;
1596 entry
= (struct IconEntry
*)GetHead(&data
->icld_IconList
);
1599 while (entry
!= NULL
)
1601 if (entry
->ie_DiskObj
&&
1602 (entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
))
1604 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
1606 maxy
+= data
->icld_LVMAttribs
->lmva_RowHeight
;
1610 IconList_GetIconAreaRectangle(obj
, data
, entry
, &icon_rect
);
1612 icon_rect
.MaxX
+= entry
->ie_IconX
+ data
->icld__Option_IconHorizontalSpacing
;
1613 if ((data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
) &&
1614 (entry
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
))
1615 icon_rect
.MaxX
+= (data
->icld_IconAreaLargestWidth
- entry
->ie_AreaWidth
);
1617 icon_rect
.MaxY
+= entry
->ie_IconY
+ data
->icld__Option_IconVerticalSpacing
;
1619 if (icon_rect
.MaxX
> maxx
) maxx
= icon_rect
.MaxX
;
1620 if (icon_rect
.MaxY
> maxy
) maxy
= icon_rect
.MaxY
;
1624 if (message
->singleicon
)
1627 entry
= (struct IconEntry
*)GetSucc(&entry
->ie_IconNode
);
1630 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
1634 for(col
= 0; col
< NUM_COLUMNS
; col
++)
1636 LONG index
= data
->icld_LVMAttribs
->lmva_ColumnPos
[col
];
1638 if (!(data
->icld_LVMAttribs
->lmva_ColumnFlags
[index
] & LVMCF_COLVISIBLE
)) continue;
1640 maxx
+= data
->icld_LVMAttribs
->lmva_ColumnWidth
[index
];
1644 /* update our view when max x/y have changed */
1645 if (maxx
+ 1 != data
->icld_AreaWidth
)
1647 data
->icld_AreaWidth
= maxx
+ 1;
1648 SET(obj
, MUIA_IconList_Width
, data
->icld_AreaWidth
);
1650 if (maxy
+ 1 != data
->icld_AreaHeight
)
1652 data
->icld_AreaHeight
= maxy
+ 1;
1653 SET(obj
, MUIA_IconList_Height
, data
->icld_AreaHeight
);
1659 ///IconList__MUIM_IconList_PositionIcons()
1660 /**************************************************************************
1661 MUIM_PositionIcons - Place icons with NO_ICON_POSITION coords somewhere
1662 **************************************************************************/
1663 IPTR
IconList__MUIM_IconList_PositionIcons(struct IClass
*CLASS
, Object
*obj
, struct MUIP_IconList_PositionIcons
*message
)
1665 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
1666 struct IconEntry
*entry
= NULL
, *pass_first
= NULL
;
1668 int left
= data
->icld__Option_IconHorizontalSpacing
;
1669 int top
= data
->icld__Option_IconVerticalSpacing
;
1674 int maxw
= 0; // Widest & Talest entry in a column or row.
1678 struct Rectangle iconrect
;
1680 #if defined(DEBUG_ILC_ICONPOSITIONING) && defined(DEBUG_ILC_FUNCS)
1681 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
1684 // Now go to the actual positioning
1685 entry
= (struct IconEntry
*)GetHead(&data
->icld_IconList
);
1686 while (entry
!= NULL
)
1689 if ((entry
->ie_DiskObj
!= NULL
) && (entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
))
1692 entry
->ie_IconX
= cur_x
;
1693 entry
->ie_IconY
= cur_y
;
1695 if (entry
->ie_Flags
& ICONENTRY_FLAG_SELECTED
)
1697 if (data
->icld_SelectionLastClicked
== NULL
) data
->icld_SelectionLastClicked
= entry
;
1698 if (data
->icld_FocusIcon
== NULL
) data
->icld_FocusIcon
= entry
;
1701 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
1703 maxw
= data
->icld_IconAreaLargestWidth
+ data
->icld__Option_IconHorizontalSpacing
;
1704 maxh
= data
->icld_IconLargestHeight
+ data
->icld__Option_IconImageSpacing
+ data
->icld_LabelLargestHeight
+ data
->icld__Option_IconVerticalSpacing
;
1710 if (!(pass_first
)) pass_first
= entry
;
1712 IconList_GetIconAreaRectangle(obj
, data
, entry
, &iconrect
);
1714 if (entry
->ie_AreaWidth
< maxw
)
1715 entry
->ie_IconX
+= ( maxw
- entry
->ie_AreaWidth
) / 2;
1717 if ((maxw
< entry
->ie_AreaWidth
) || (maxh
< entry
->ie_AreaHeight
))
1719 if (maxw
< entry
->ie_AreaWidth
) maxw
= entry
->ie_AreaWidth
;
1720 if (maxh
< entry
->ie_AreaHeight
) maxh
= entry
->ie_AreaHeight
;
1721 if (pass_first
!= entry
)
1724 cur_x
= entry
->ie_IconX
;
1725 cur_y
= entry
->ie_IconY
;
1730 if (data
->icld_DisplayFlags
& ICONLIST_DISP_VERTICAL
)
1733 gridy
= entry
->ie_AreaHeight
+ data
->icld__Option_IconHorizontalSpacing
;
1737 gridx
= entry
->ie_AreaWidth
+ data
->icld__Option_IconVerticalSpacing
;
1742 if ((entry
= (struct IconEntry
*)GetSucc(&entry
->ie_IconNode
)) != NULL
)
1746 if (data
->icld_DisplayFlags
& ICONLIST_DISP_VERTICAL
)
1750 if ((cur_y
>= data
->icld_ViewHeight
) ||
1751 ((data
->icld__Option_IconListMode
== ICON_LISTMODE_ROUGH
) && ((cur_y
+ entry
->ie_AreaHeight
- data
->icld__Option_IconBorderOverlap
) >= data
->icld_ViewHeight
)) ||
1752 ((data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
) && ((cur_y
+ data
->icld_IconAreaLargestHeight
- data
->icld__Option_IconBorderOverlap
) >= data
->icld_ViewHeight
)))
1764 if ((cur_x
>= data
->icld_ViewWidth
) ||
1765 ((data
->icld__Option_IconListMode
== ICON_LISTMODE_ROUGH
) && ((cur_x
+ entry
->ie_AreaWidth
- data
->icld__Option_IconBorderOverlap
) >= data
->icld_ViewWidth
)) ||
1766 ((data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
) && ((cur_x
+ data
->icld_IconAreaLargestWidth
- data
->icld__Option_IconBorderOverlap
) >= data
->icld_ViewWidth
)))
1773 else if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
1781 DoMethod(obj
, MUIM_IconList_RethinkDimensions
, NULL
);
1787 /**************************************************************************
1789 **************************************************************************/
1790 IPTR
IconList__OM_NEW(struct IClass
*CLASS
, Object
*obj
, struct opSet
*message
)
1792 struct IconList_DATA
*data
= NULL
;
1793 struct TextFont
*icl_WindowFont
= NULL
;
1794 // struct RastPort *icl_RastPort = NULL;
1797 #if defined(DEBUG_ILC_FUNCS)
1798 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
1801 icl_WindowFont
= (struct TextFont
*) GetTagData(MUIA_Font
, (IPTR
) NULL
, message
->ops_AttrList
);
1803 obj
= (Object
*)DoSuperNewTags(CLASS
, obj
, NULL
,
1804 MUIA_FillArea
, FALSE
,
1805 MUIA_Dropable
, TRUE
,
1806 MUIA_Font
, MUIV_Font_Tiny
,
1807 TAG_MORE
, (IPTR
) message
->ops_AttrList
);
1809 if (!obj
) return FALSE
;
1811 data
= INST_DATA(CLASS
, obj
);
1813 data
->icld_Pool
= CreatePool(0,4096,4096);
1814 if (!data
->icld_Pool
)
1816 CoerceMethod(CLASS
,obj
,OM_DISPOSE
);
1820 #if defined(DEBUG_ILC_FUNCS)
1821 D(bug("[IconList] %s: SELF = 0x%p, muiRenderInfo = 0x%p\n", __PRETTY_FUNCTION__
, obj
, muiRenderInfo(obj
)));
1823 NewList((struct List
*)&data
->icld_IconList
);
1824 NewList((struct List
*)&data
->icld_SelectionList
);
1826 data
->icld_IconLabelFont
= icl_WindowFont
;
1828 /* Setup Icon View-Mode options */
1829 data
->icld_IVMAttribs
= AllocMem(sizeof(struct IconViewModeAttribs
), MEMF_CLEAR
);
1830 /* Setup List View-Mode options */
1831 if ((data
->icld_LVMAttribs
= AllocMem(sizeof(struct ListViewModeAttribs
), MEMF_CLEAR
)) != NULL
)
1833 for(i
= 0; i
< NUM_COLUMNS
; i
++)
1835 data
->icld_LVMAttribs
->lmva_ColumnPos
[i
] = i
;
1836 data
->icld_LVMAttribs
->lmva_ColumnFlags
[i
] = LVMCF_COLVISIBLE
;
1837 data
->icld_LVMAttribs
->lmva_ColumnWidth
[i
] = 100;
1838 data
->icld_LVMAttribs
->lmva_ColumnAlign
[i
] = COLUMN_ALIGN_LEFT
;
1842 data
->icld_LVMAttribs
->lmva_ColumnFlags
[i
] |= (LVMCF_COLCLICKABLE
|LVMCF_COLSORTABLE
);
1843 data
->icld_LVMAttribs
->lmva_ColumnTitle
[i
] = "Name";
1847 data
->icld_LVMAttribs
->lmva_ColumnAlign
[i
] = COLUMN_ALIGN_RIGHT
;
1848 data
->icld_LVMAttribs
->lmva_ColumnFlags
[i
] | LVMCF_COLSORTABLE
;
1849 data
->icld_LVMAttribs
->lmva_ColumnTitle
[i
] = "Size";
1853 data
->icld_LVMAttribs
->lmva_ColumnFlags
[i
] |= LVMCF_COLSORTABLE
;
1854 data
->icld_LVMAttribs
->lmva_ColumnTitle
[i
] = "Date";
1858 data
->icld_LVMAttribs
->lmva_ColumnFlags
[i
] |= LVMCF_COLSORTABLE
;
1859 data
->icld_LVMAttribs
->lmva_ColumnTitle
[i
] = "Time";
1863 data
->icld_LVMAttribs
->lmva_ColumnTitle
[i
] = "Comment";
1866 case INDEX_PROTECTION
:
1867 data
->icld_LVMAttribs
->lmva_ColumnTitle
[i
] = "Protection";
1871 data
->icld_LVMAttribs
->lmva_ColumnTitle
[i
] = "<Unknown>";
1875 data
->icld_LVMAttribs
->lmva_LastSelectedColumn
= -1;
1876 data
->icld_LVMAttribs
->lmva_SortColumn
= INDEX_NAME
;
1877 data
->icld_LVMAttribs
->lmva_HeaderHeight
= HEADERLINE_EXTRAHEIGHT
+ data
->icld_IconLabelFont
->tf_YSize
;
1878 data
->icld_LVMAttribs
->lmva_RowHeight
= LINE_EXTRAHEIGHT
+ data
->icld_IconLabelFont
->tf_YSize
;
1879 data
->icld_LVMAttribs
->lvma_Flags
= LVMAF_HEADERDRAWTOEND
;
1882 /* Get/Set initial values */
1883 #warning "TODO: TrimVolumeNames should be prefs settable"
1884 data
->icld__Option_TrimVolumeNames
= TRUE
;
1885 #warning "TODO: Adjust overlap by window border width"
1886 data
->icld__Option_IconBorderOverlap
= 10;
1888 data
->icld__Option_IconListMode
= (UBYTE
)GetTagData(MUIA_IconList_IconListMode
, 0, message
->ops_AttrList
);
1889 data
->icld__Option_LabelTextMode
= (UBYTE
)GetTagData(MUIA_IconList_LabelText_Mode
, 0, message
->ops_AttrList
);
1890 data
->icld__Option_LabelTextMaxLen
= (ULONG
)GetTagData(MUIA_IconList_LabelText_MaxLineLen
, ILC_ICONLABEL_MAXLINELEN_DEFAULT
, message
->ops_AttrList
);
1892 if ( data
->icld__Option_LabelTextMaxLen
< ILC_ICONLABEL_SHORTEST
)
1893 data
->icld__Option_LabelTextMaxLen
= ILC_ICONLABEL_MAXLINELEN_DEFAULT
;
1895 data
->icld__Option_LastLabelTextMaxLen
= data
->icld__Option_LabelTextMaxLen
;
1897 #if defined(DEBUG_ILC_FUNCS)
1898 D(bug("[IconList] %s: MaxLineLen : %ld\n", __PRETTY_FUNCTION__
, data
->icld__Option_LabelTextMaxLen
));
1900 data
->ehn
.ehn_Events
= IDCMP_MOUSEBUTTONS
| IDCMP_RAWKEY
| IDCMP_NEWSIZE
;
1901 data
->ehn
.ehn_Priority
= 0;
1902 data
->ehn
.ehn_Flags
= 0;
1903 data
->ehn
.ehn_Object
= obj
;
1904 data
->ehn
.ehn_Class
= CLASS
;
1906 data
->icld_SortFlags
= MUIV_IconList_Sort_ByName
;
1907 data
->icld_DisplayFlags
= ICONLIST_DISP_SHOWINFO
;
1909 __iconlist_UpdateLabels_hook
.h_Entry
= (HOOKFUNC
)IconList__HookFunc_UpdateLabelsFunc
;
1913 obj
, MUIM_Notify
, MUIA_IconList_LabelText_MaxLineLen
, MUIV_EveryTime
,
1915 MUIM_CallHook
, &__iconlist_UpdateLabels_hook
, (IPTR
)CLASS
1920 obj
, MUIM_Notify
, MUIA_IconList_LabelText_MultiLine
, MUIV_EveryTime
,
1922 MUIM_CallHook
, &__iconlist_UpdateLabels_hook
, (IPTR
)CLASS
1925 #if defined(DEBUG_ILC_FUNCS)
1926 D(bug("[IconList] obj = %ld\n", obj
));
1933 /**************************************************************************
1935 **************************************************************************/
1936 IPTR
IconList__OM_DISPOSE(struct IClass
*CLASS
, Object
*obj
, Msg message
)
1938 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
1939 struct IconEntry
*node
= NULL
;
1941 #if defined(DEBUG_ILC_FUNCS)
1942 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
1945 #if defined(__AROS__)
1946 ForeachNode(&data
->icld_IconList
, node
)
1948 Foreach_Node(&data
->icld_IconList
, node
);
1951 if (node
->ie_DiskObj
)
1952 FreeDiskObject(node
->ie_DiskObj
);
1955 if (data
->icld_Pool
) DeletePool(data
->icld_Pool
);
1957 DoSuperMethodA(CLASS
,obj
,message
);
1963 /**************************************************************************
1965 **************************************************************************/
1966 IPTR
IconList__OM_SET(struct IClass
*CLASS
, Object
*obj
, struct opSet
*message
)
1968 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
1969 struct TagItem
*tag
= NULL
,
1972 WORD oldleft
= data
->icld_ViewX
,
1973 oldtop
= data
->icld_ViewY
;
1974 //oldwidth = data->icld_ViewWidth,
1975 //oldheight = data->icld_ViewHeight;
1977 #if defined(DEBUG_ILC_FUNCS) && defined(DEBUG_ILC_ATTRIBS)
1978 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
1981 /* parse initial taglist */
1982 for (tags
= message
->ops_AttrList
; (tag
= NextTagItem((TAGITEM
)&tags
)); )
1984 switch (tag
->ti_Tag
)
1986 case MUIA_Virtgroup_Left
:
1987 #if defined(DEBUG_ILC_ATTRIBS)
1988 D(bug("[IconList] %s: MUIA_Virtgroup_Left %ld\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
1990 if (data
->icld_ViewX
!= tag
->ti_Data
)
1991 data
->icld_ViewX
= tag
->ti_Data
;
1994 case MUIA_Virtgroup_Top
:
1995 #if defined(DEBUG_ILC_ATTRIBS)
1996 D(bug("[IconList] %s: MUIA_Virtgroup_Top %ld\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
1998 if (data
->icld_ViewY
!= tag
->ti_Data
)
1999 data
->icld_ViewY
= tag
->ti_Data
;
2002 case MUIA_IconList_Rastport
:
2003 #if defined(DEBUG_ILC_ATTRIBS)
2004 D(bug("[IconList] %s: MUIA_IconList_Rastport 0x%p\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2006 data
->icld_DisplayRastPort
= (struct RastPort
*)tag
->ti_Data
;
2007 data
->icld_DrawOffsetX
= _mleft(obj
);
2008 data
->icld_DrawOffsetY
= _mtop(obj
);
2009 if (data
->icld_BufferRastPort
!= NULL
)
2011 //Buffer still set!?!?!
2013 SET(obj
, MUIA_IconList_BufferRastport
, tag
->ti_Data
);
2016 case MUIA_IconList_BufferRastport
:
2017 #if defined(DEBUG_ILC_ATTRIBS)
2018 D(bug("[IconList] %s: MUIA_IconList_BufferRastport 0x%p\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2020 data
->icld_BufferRastPort
= (struct RastPort
*)tag
->ti_Data
;
2024 #if defined(DEBUG_ILC_ATTRIBS)
2025 D(bug("[IconList] %s: MUIA_Font 0x%p\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2027 data
->icld_IconLabelFont
= (struct TextFont
*)tag
->ti_Data
;
2030 case MUIA_IconList_LabelInfoText_Font
:
2031 #if defined(DEBUG_ILC_ATTRIBS)
2032 D(bug("[IconList] %s: MUIA_IconList_LabelInfoText_Font 0x%p\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2034 data
->icld_IconInfoFont
= (struct TextFont
*)tag
->ti_Data
;
2037 case MUIA_IconList_DisplayFlags
:
2039 #if defined(DEBUG_ILC_ATTRIBS)
2040 D(bug("[IconList] %s: MUIA_IconList_DisplayFlags %08x\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2042 ULONG origModeFlags
= data
->icld_DisplayFlags
& (ICONLIST_DISP_MODEDEFAULT
|ICONLIST_DISP_MODELABELRIGHT
|ICONLIST_DISP_MODELIST
);
2043 data
->icld_DisplayFlags
= (ULONG
)tag
->ti_Data
;
2045 if (data
->icld_DisplayFlags
& ICONLIST_DISP_BUFFERED
)
2047 struct BitMap
*bitmap_New
= NULL
;
2048 ULONG tmp_RastDepth
;
2050 #if defined(DEBUG_ILC_ATTRIBS) && defined(DEBUG_ILC_ICONRENDERING)
2051 D(bug("[IconList] %s: MUIA_IconList_DisplayFlags & ICONLIST_DISP_BUFFERED\n", __PRETTY_FUNCTION__
));
2053 if ((data
->icld_BufferRastPort
!= NULL
)
2054 && (data
->icld_BufferRastPort
!= data
->icld_DisplayRastPort
))
2056 #if defined(DEBUG_ILC_ATTRIBS) && defined(DEBUG_ILC_ICONRENDERING)
2057 D(bug("[IconList] %s: BackLayer @ %p for BackRastport @ %p\n", __PRETTY_FUNCTION__
, data
->icld_BufferRastPort
->Layer
, data
->icld_BufferRastPort
));
2059 if ((GetBitMapAttr(data
->icld_BufferRastPort
->BitMap
, BMA_WIDTH
) != data
->icld_ViewWidth
)
2060 || (GetBitMapAttr(data
->icld_BufferRastPort
->BitMap
, BMA_HEIGHT
) != data
->icld_ViewHeight
))
2062 struct Layer
*oldLayer
= data
->icld_BufferRastPort
->Layer
;
2063 #if defined(DEBUG_ILC_ATTRIBS) && defined(DEBUG_ILC_ICONRENDERING)
2064 D(bug("[IconList] %s: Destroying old BackLayer\n", __PRETTY_FUNCTION__
));
2066 data
->icld_BufferRastPort
= data
->icld_DisplayRastPort
;
2067 DeleteLayer(0, oldLayer
);
2071 if ((data
->icld_BufferRastPort
== NULL
) || (data
->icld_BufferRastPort
== data
->icld_DisplayRastPort
))
2073 tmp_RastDepth
= GetCyberMapAttr(data
->icld_DisplayRastPort
->BitMap
, CYBRMATTR_DEPTH
);
2074 if ((bitmap_New
= AllocBitMap(data
->icld_ViewWidth
,
2075 data
->icld_ViewHeight
,
2078 data
->icld_DisplayRastPort
->BitMap
))!=NULL
)
2082 struct Layer
* buffLayer
= CreateLayerTagList(&_screen(obj
)->LayerInfo
,
2086 data
->icld_ViewWidth
,
2087 data
->icld_ViewHeight
,
2089 __iconList_BackBuffLayerTags
);
2091 if (buffLayer
!= NULL
)
2093 data
->icld_BufferRastPort
= buffLayer
->rp
;
2094 #if defined(DEBUG_ILC_ATTRIBS) && defined(DEBUG_ILC_ICONRENDERING)
2095 D(bug("[IconList] %s: FrontRastPort @ %p, New BackLayer @ %p, BackRastport @ %p\n", __PRETTY_FUNCTION__
, data
->icld_DisplayRastPort
, data
->icld_BufferRastPort
->Layer
, data
->icld_BufferRastPort
));
2097 SET(obj
, MUIA_IconList_BufferRastport
, data
->icld_BufferRastPort
);
2098 data
->icld_DrawOffsetX
= 0;
2099 data
->icld_DrawOffsetY
= 0;
2103 FreeBitMap(bitmap_New
);
2104 data
->icld_BufferRastPort
= data
->icld_DisplayRastPort
;
2105 data
->icld_DrawOffsetX
= _mleft(obj
);
2106 data
->icld_DrawOffsetY
= _mtop(obj
);
2113 if ((data
->icld_BufferRastPort
) && (data
->icld_BufferRastPort
!= data
->icld_DisplayRastPort
))
2115 //Free up the buffers layer, rastport and bitmap since they are no longer needed ..
2116 struct Layer
*oldLayer
= data
->icld_BufferRastPort
->Layer
;
2117 data
->icld_BufferRastPort
= data
->icld_DisplayRastPort
;
2118 DeleteLayer(0, oldLayer
);
2119 data
->icld_DrawOffsetX
= _mleft(obj
);
2120 data
->icld_DrawOffsetY
= _mtop(obj
);
2123 SET(obj
, MUIA_IconList_Changed
, TRUE
);
2127 case MUIA_IconList_SortFlags
:
2128 #if defined(DEBUG_ILC_ATTRIBS)
2129 D(bug("[IconList] %s: MUIA_IconList_SortFlags %08x\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2131 data
->icld_SortFlags
= (ULONG
)tag
->ti_Data
;
2134 case MUIA_IconList_IconListMode
:
2135 #if defined(DEBUG_ILC_ATTRIBS)
2136 D(bug("[IconList] %s: MUIA_IconList_IconListMode %d\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2138 data
->icld__Option_IconListMode
= (UBYTE
)tag
->ti_Data
;
2141 case MUIA_IconList_LabelText_Mode
:
2142 #if defined(DEBUG_ILC_ATTRIBS)
2143 D(bug("[IconList] %s: MUIA_IconList_LabelText_Mode %d\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2145 data
->icld__Option_LabelTextMode
= (UBYTE
)tag
->ti_Data
;
2148 case MUIA_IconList_LabelText_MaxLineLen
:
2149 #if defined(DEBUG_ILC_ATTRIBS)
2150 D(bug("[IconList] %s: MUIA_IconList_LabelText_MaxLineLen %d\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2152 if (tag
->ti_Data
>= ILC_ICONLABEL_SHORTEST
)
2154 data
->icld__Option_LabelTextMaxLen
= (ULONG
)tag
->ti_Data
;
2158 data
->icld__Option_LabelTextMaxLen
= ILC_ICONLABEL_MAXLINELEN_DEFAULT
;
2162 case MUIA_IconList_LabelText_MultiLine
:
2163 #if defined(DEBUG_ILC_ATTRIBS)
2164 D(bug("[IconList] %s: MUIA_IconList_LabelText_MultiLine %d\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2166 data
->icld__Option_LabelTextMultiLine
= (ULONG
)tag
->ti_Data
;
2167 if (data
->icld__Option_LabelTextMultiLine
== 0)data
->icld__Option_LabelTextMultiLine
= 1;
2170 case MUIA_IconList_LabelText_MultiLineOnFocus
:
2171 #if defined(DEBUG_ILC_ATTRIBS)
2172 D(bug("[IconList] %s: MUIA_IconList_LabelText_MultiLineOnFocus %d\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2174 data
->icld__Option_LabelTextMultiLineOnFocus
= (BOOL
)tag
->ti_Data
;
2177 case MUIA_IconList_Icon_HorizontalSpacing
:
2178 #if defined(DEBUG_ILC_ATTRIBS)
2179 D(bug("[IconList] %s: MUIA_IconList_Icon_HorizontalSpacing %d\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2181 data
->icld__Option_IconHorizontalSpacing
= (UBYTE
)tag
->ti_Data
;
2184 case MUIA_IconList_Icon_VerticalSpacing
:
2185 #if defined(DEBUG_ILC_ATTRIBS)
2186 D(bug("[IconList] %s: MUIA_IconList_Icon_VerticalSpacing %d\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2188 data
->icld__Option_IconVerticalSpacing
= (UBYTE
)tag
->ti_Data
;
2191 case MUIA_IconList_Icon_ImageSpacing
:
2192 #if defined(DEBUG_ILC_ATTRIBS)
2193 D(bug("[IconList] %s: MUIA_IconList_Icon_ImageSpacing %d\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2195 data
->icld__Option_IconImageSpacing
= (UBYTE
)tag
->ti_Data
;
2198 case MUIA_IconList_LabelText_HorizontalPadding
:
2199 #if defined(DEBUG_ILC_ATTRIBS)
2200 D(bug("[IconList] %s: MUIA_IconList_LabelText_HorizontalPadding %d\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2202 data
->icld__Option_LabelTextHorizontalPadding
= (UBYTE
)tag
->ti_Data
;
2205 case MUIA_IconList_LabelText_VerticalPadding
:
2206 #if defined(DEBUG_ILC_ATTRIBS)
2207 D(bug("[IconList] %s: MUIA_IconList_LabelText_VerticalPadding %d\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2209 data
->icld__Option_LabelTextVerticalPadding
= (UBYTE
)tag
->ti_Data
;
2212 case MUIA_IconList_LabelText_BorderWidth
:
2213 #if defined(DEBUG_ILC_ATTRIBS)
2214 D(bug("[IconList] %s: MUIA_IconList_LabelText_BorderWidth %d\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2216 data
->icld__Option_LabelTextBorderWidth
= (UBYTE
)tag
->ti_Data
;
2219 case MUIA_IconList_LabelText_BorderHeight
:
2220 #if defined(DEBUG_ILC_ATTRIBS)
2221 D(bug("[IconList] %s: MUIA_IconList_LabelText_BorderHeight %d\n", __PRETTY_FUNCTION__
, tag
->ti_Data
));
2223 data
->icld__Option_LabelTextBorderHeight
= (UBYTE
)tag
->ti_Data
;
2226 case MUIA_IconList_LabelText_Pen
:
2227 data
->icld_LabelPen
= (ULONG
)tag
->ti_Data
;
2230 case MUIA_IconList_LabelText_ShadowPen
:
2231 data
->icld_LabelShadowPen
= (ULONG
)tag
->ti_Data
;
2234 case MUIA_IconList_LabelInfoText_Pen
:
2235 data
->icld_InfoPen
= (ULONG
)tag
->ti_Data
;
2238 case MUIA_IconList_LabelInfoText_ShadowPen
:
2239 data
->icld_InfoShadowPen
= (ULONG
)tag
->ti_Data
;
2242 /* Settings defined by the view class */
2243 case MUIA_IconListview_FixedBackground
:
2244 #if defined(DEBUG_ILC_ATTRIBS)
2245 D(bug("[IconList] %s: MUIA_IconListview_FixedBackground\n", __PRETTY_FUNCTION__
));
2247 data
->icld__Option_IconListFixedBackground
= (BOOL
)tag
->ti_Data
;
2250 case MUIA_IconListview_ScaledBackground
:
2251 #if defined(DEBUG_ILC_ATTRIBS)
2252 D(bug("[IconList] %s: MUIA_IconListview_ScaledBackground\n", __PRETTY_FUNCTION__
));
2254 data
->icld__Option_IconListScaledBackground
= (BOOL
)tag
->ti_Data
;
2257 /* We listen for MUIA_Background and set default values for known types */
2258 case MUIA_Background
:
2259 #if defined(DEBUG_ILC_ATTRIBS) && defined(DEBUG_ILC_ICONRENDERING)
2260 D(bug("[IconList] %s: MUIA_Background\n", __PRETTY_FUNCTION__
));
2263 char *bgmode_string
= (char *)tag
->ti_Data
;
2264 BYTE this_mode
= bgmode_string
[0] - 48;
2266 #if defined(DEBUG_ILC_ATTRIBS) && defined(DEBUG_ILC_ICONRENDERING)
2267 D(bug("[IconList] %s: MUIA_Background | MUI BG Mode = %d\n", __PRETTY_FUNCTION__
, this_mode
));
2273 NNSET(obj
, MUIA_IconListview_FixedBackground
, FALSE
);
2274 NNSET(obj
, MUIA_IconListview_ScaledBackground
, FALSE
);
2278 NNSET(obj
, MUIA_IconListview_FixedBackground
, FALSE
);
2279 NNSET(obj
, MUIA_IconListview_ScaledBackground
, FALSE
);
2283 NNSET(obj
, MUIA_IconListview_FixedBackground
, TRUE
);
2284 NNSET(obj
, MUIA_IconListview_ScaledBackground
, TRUE
);
2288 NNSET(obj
, MUIA_IconListview_FixedBackground
, FALSE
);
2289 NNSET(obj
, MUIA_IconListview_ScaledBackground
, FALSE
);
2294 case MUIA_IconList_IconsDropped
:
2295 data
->icld_DragDropEvent
= (struct IconList_Drop_Event
*)tag
->ti_Data
;
2300 #if defined(DEBUG_ILC_ATTRIBS)
2301 D(bug("[IconList] %s(), out of switch\n", __PRETTY_FUNCTION__
));
2303 if ((oldleft
!= data
->icld_ViewX
) || (oldtop
!= data
->icld_ViewY
))
2305 data
->icld_UpdateMode
= UPDATE_SCROLL
;
2306 data
->update_scrolldx
= data
->icld_ViewX
- oldleft
;
2307 data
->update_scrolldy
= data
->icld_ViewY
- oldtop
;
2308 #if defined(DEBUG_ILC_ATTRIBS)
2309 D(bug("[IconList] %s(), call MUI_Redraw()\n", __PRETTY_FUNCTION__
));
2311 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
2314 #if defined(DEBUG_ILC_ATTRIBS)
2315 D(bug("[IconList] %s(), call DoSuperMethodA()\n", __PRETTY_FUNCTION__
));
2317 return DoSuperMethodA(CLASS
, obj
, (Msg
)message
);
2322 /**************************************************************************
2324 **************************************************************************/
2325 IPTR
IconList__OM_GET(struct IClass
*CLASS
, Object
*obj
, struct opGet
*message
)
2327 /* small macro to simplify return value storage */
2328 #define STORE *(message->opg_Storage)
2329 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
2331 #if defined(DEBUG_ILC_FUNCS) && defined(DEBUG_ILC_ATTRIBS)
2332 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
2335 switch (message
->opg_AttrID
)
2337 case MUIA_IconList_Rastport
: STORE
= (IPTR
)data
->icld_DisplayRastPort
; return 1;
2338 case MUIA_IconList_BufferRastport
: STORE
= (IPTR
)data
->icld_BufferRastPort
; return 1;
2339 case MUIA_IconList_BufferLeft
: STORE
= (IPTR
)data
->icld_DrawOffsetX
; return 1;
2340 case MUIA_IconList_BufferTop
: STORE
= (IPTR
)data
->icld_DrawOffsetY
; return 1;
2341 case MUIA_IconList_BufferWidth
:
2342 case MUIA_IconList_Width
: STORE
= (IPTR
)data
->icld_AreaWidth
; return 1;
2343 case MUIA_IconList_BufferHeight
:
2344 case MUIA_IconList_Height
: STORE
= (IPTR
)data
->icld_AreaHeight
; return 1;
2345 case MUIA_IconList_IconsDropped
: STORE
= (IPTR
)data
->icld_DragDropEvent
; return 1;
2346 case MUIA_IconList_Clicked
: STORE
= (IPTR
)&data
->icld_ClickEvent
; return 1;
2347 case MUIA_IconList_IconListMode
: STORE
= (IPTR
)data
->icld__Option_IconListMode
; return 1;
2348 case MUIA_IconList_LabelText_Mode
: STORE
= (IPTR
)data
->icld__Option_LabelTextMode
; return 1;
2349 case MUIA_IconList_LabelText_MaxLineLen
: STORE
= (IPTR
)data
->icld__Option_LabelTextMaxLen
; return 1;
2350 case MUIA_IconList_LabelText_MultiLine
: STORE
= (IPTR
)data
->icld__Option_LabelTextMultiLine
; return 1;
2351 case MUIA_IconList_LabelText_MultiLineOnFocus
: STORE
= (IPTR
)data
->icld__Option_LabelTextMultiLineOnFocus
; return 1;
2352 case MUIA_IconList_DisplayFlags
: STORE
= (IPTR
)data
->icld_DisplayFlags
; return 1;
2353 case MUIA_IconList_SortFlags
: STORE
= (IPTR
)data
->icld_SortFlags
; return 1;
2355 case MUIA_IconList_FocusIcon
: STORE
= (IPTR
)data
->icld_FocusIcon
; return 1;
2357 case MUIA_Font
: STORE
= (IPTR
)data
->icld_IconLabelFont
; return 1;
2358 case MUIA_IconList_LabelText_Pen
: STORE
= (IPTR
)data
->icld_LabelPen
; return 1;
2359 case MUIA_IconList_LabelText_ShadowPen
: STORE
= (IPTR
)data
->icld_LabelShadowPen
; return 1;
2360 case MUIA_IconList_LabelInfoText_Font
: STORE
= (IPTR
)data
->icld_IconInfoFont
; return 1;
2361 case MUIA_IconList_LabelInfoText_Pen
: STORE
= (IPTR
)data
->icld_InfoPen
; return 1;
2362 case MUIA_IconList_LabelInfoText_ShadowPen
: STORE
= (IPTR
)data
->icld_InfoShadowPen
; return 1;
2364 case MUIA_IconList_Icon_HorizontalSpacing
: STORE
= (IPTR
)data
->icld__Option_IconHorizontalSpacing
; return 1;
2365 case MUIA_IconList_Icon_VerticalSpacing
: STORE
= (IPTR
)data
->icld__Option_IconVerticalSpacing
; return 1;
2366 case MUIA_IconList_Icon_ImageSpacing
: STORE
= (IPTR
)data
->icld__Option_IconImageSpacing
; return 1;
2367 case MUIA_IconList_LabelText_HorizontalPadding
: STORE
= (IPTR
)data
->icld__Option_LabelTextHorizontalPadding
; return 1;
2368 case MUIA_IconList_LabelText_VerticalPadding
: STORE
= (IPTR
)data
->icld__Option_LabelTextVerticalPadding
; return 1;
2369 case MUIA_IconList_LabelText_BorderWidth
: STORE
= (IPTR
)data
->icld__Option_LabelTextBorderWidth
; return 1;
2370 case MUIA_IconList_LabelText_BorderHeight
: STORE
= (IPTR
)data
->icld__Option_LabelTextBorderHeight
; return 1;
2372 /* Settings defined by the view class */
2373 case MUIA_IconListview_FixedBackground
: STORE
= (IPTR
)data
->icld__Option_IconListFixedBackground
; return 1;
2374 case MUIA_IconListview_ScaledBackground
: STORE
= (IPTR
)data
->icld__Option_IconListScaledBackground
; return 1;
2376 /* ICON obj Changes */
2377 case MUIA_Virtgroup_Left
: STORE
= (IPTR
)data
->icld_ViewX
; return 1;
2378 case MUIA_Virtgroup_Top
: STORE
= (IPTR
)data
->icld_ViewY
; return 1;
2379 case MUIA_Family_List
: STORE
= (IPTR
)&(data
->icld_IconList
); return 1; /* Get our list object */
2381 #warning "TODO: Get the version/revision from our config.."
2382 case MUIA_Version
: STORE
= (IPTR
)1; return 1;
2383 case MUIA_Revision
: STORE
= (IPTR
)7; return 1;
2386 return DoSuperMethodA(CLASS
, obj
, (Msg
) message
);
2391 IPTR
IconList__MUIM_Family_AddHead(struct IClass
*CLASS
, Object
*obj
, struct MUIP_Family_AddHead
*message
)
2393 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
2394 #if defined(DEBUG_ILC_FUNCS)
2395 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
2400 #warning "TODO: Use the correct _OBJECT() code when we switch to icon.mui"
2401 // AddHead(&(data->icld_IconList), (struct Node *)_OBJECT(message->obj));
2402 AddHead(&(data
->icld_IconList
), (struct Node
*)message
->obj
);
2409 IPTR
IconList__MUIM_Family_AddTail(struct IClass
*CLASS
, Object
*obj
, struct MUIP_Family_AddTail
*message
)
2411 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
2412 #if defined(DEBUG_ILC_FUNCS)
2413 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
2416 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
));
2420 #warning "TODO: Use the correct _OBJECT() code when we switch to icon.mui"
2421 // AddTail(&(data->icld_IconList), (struct Node *)_OBJECT(message->obj));
2422 AddTail(&(data
->icld_IconList
), (struct Node
*)message
->obj
);
2430 #if !defined(WANDERER_BUILTIN_ICONLIST)
2431 IPTR
IconList__OM_ADDMEMBER(struct IClass
*CLASS
, Object
*obj
, struct MUIP_Family_AddTail
*message
)
2433 return IconList__MUIM_Family_AddTail(CLASS
, obj
, message
);
2437 IPTR
IconList__MUIM_Family_Remove(struct IClass
*CLASS
, Object
*obj
, struct MUIP_Family_Remove
*message
)
2439 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
2440 #if defined(DEBUG_ILC_FUNCS)
2441 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
2444 D(bug("[IconList] %s: entry @ 0x%p '%s'\n", __PRETTY_FUNCTION__
, message
->obj
, ((struct IconEntry
*)message
->obj
)->ie_IconNode
.ln_Name
));
2448 #warning "TODO: Use the correct _OBJECT() code when we switch to icon.mui"
2449 // Remove((struct Node *)_OBJECT(message->obj));
2450 Remove((struct Node
*)message
->obj
);
2458 #if !defined(WANDERER_BUILTIN_ICONLIST)
2459 IPTR
IconList__OM_REMMEMBER(struct IClass
*CLASS
, Object
*obj
, struct MUIP_Family_Remove
*message
)
2461 return IconList__MUIM_Family_Remove(CLASS
, obj
, message
);
2466 /**************************************************************************
2468 **************************************************************************/
2469 IPTR
IconList__MUIM_Setup(struct IClass
*CLASS
, Object
*obj
, struct MUIP_Setup
*message
)
2471 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
2472 struct IconEntry
*node
= NULL
;
2473 IPTR geticon_error
= 0;
2475 #if defined(DEBUG_ILC_FUNCS)
2476 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
2479 if (!DoSuperMethodA(CLASS
, obj
, (Msg
) message
)) return (IPTR
)NULL
;
2481 DoMethod(_win(obj
), MUIM_Window_AddEventHandler
, (IPTR
)&data
->ehn
);
2483 /* Get Internal Objects to use if not set .. */
2484 data
->icld_DisplayRastPort
= NULL
;
2485 data
->icld_BufferRastPort
= NULL
;
2487 if (data
->icld_IconLabelFont
== NULL
) data
->icld_IconLabelFont
= _font(obj
);
2488 if (data
->icld_IconInfoFont
== NULL
) data
->icld_IconInfoFont
= data
->icld_IconLabelFont
;
2489 #if defined(DEBUG_ILC_ICONRENDERING)
2490 D(bug("[IconList] %s: Use Font @ 0x%p, RastPort @ 0x%p\n", __PRETTY_FUNCTION__
, data
->icld_IconLabelFont
, data
->icld_BufferRastPort
));
2493 /* Set our base options .. */
2494 data
->icld_LabelPen
= _pens(obj
)[MPEN_SHINE
];
2495 data
->icld_LabelShadowPen
= _pens(obj
)[MPEN_SHADOW
];
2496 data
->icld_InfoPen
= _pens(obj
)[MPEN_SHINE
];
2497 data
->icld_InfoShadowPen
= _pens(obj
)[MPEN_SHADOW
];
2499 data
->icld__Option_LabelTextMultiLine
= 1;
2500 data
->icld__Option_LastLabelTextMultiLine
= data
->icld__Option_LabelTextMultiLine
;
2502 data
->icld__Option_LabelTextMultiLineOnFocus
= FALSE
;
2504 data
->icld__Option_IconHorizontalSpacing
= ILC_ICON_HORIZONTALMARGIN_DEFAULT
;
2505 data
->icld__Option_IconVerticalSpacing
= ILC_ICON_VERTICALMARGIN_DEFAULT
;
2506 data
->icld__Option_IconImageSpacing
= ILC_ICONLABEL_IMAGEMARGIN_DEFAULT
;
2507 data
->icld__Option_LabelTextHorizontalPadding
= ILC_ICONLABEL_HORIZONTALTEXTMARGIN_DEFAULT
;
2508 data
->icld__Option_LabelTextVerticalPadding
= ILC_ICONLABEL_VERTICALTEXTMARGIN_DEFAULT
;
2509 data
->icld__Option_LabelTextBorderWidth
= ILC_ICONLABEL_BORDERWIDTH_DEFAULT
;
2510 data
->icld__Option_LabelTextBorderHeight
= ILC_ICONLABEL_BORDERHEIGHT_DEFAULT
;
2512 #if defined(__AROS__)
2513 ForeachNode(&data
->icld_IconList
, node
)
2515 Foreach_Node(&data
->icld_IconList
, node
);
2518 if (!node
->ie_DiskObj
)
2520 IPTR iconlistScreen
= _screen(obj
);
2521 #if defined(DEBUG_ILC_ICONRENDERING)
2522 D(bug("[IconList] %s: IconList Screen @ 0x%p)\n", __PRETTY_FUNCTION__
, iconlistScreen
));
2524 if (!(node
->ie_DiskObj
= GetIconTags(node
->ie_IconNode
.ln_Name
,
2525 (iconlistScreen
) ? ICONGETA_Screen
: TAG_IGNORE
, iconlistScreen
,
2526 (iconlistScreen
) ? ICONGETA_RemapIcon
: TAG_IGNORE
, TRUE
,
2527 ICONGETA_GenerateImageMasks
, TRUE
,
2528 ICONGETA_FailIfUnavailable
, FALSE
,
2529 ICONA_ErrorCode
, &geticon_error
,
2532 #if defined(DEBUG_ILC_ICONRENDERING)
2533 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
));
2535 /* We should probably remove this node if the entry cant be obtained ? */
2544 /**************************************************************************
2546 **************************************************************************/
2547 IPTR
IconList__MUIM_Show(struct IClass
*CLASS
, Object
*obj
, struct MUIP_Show
*message
)
2549 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
2554 #if defined(DEBUG_ILC_FUNCS)
2555 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
2558 if ((rc
= DoSuperMethodA(CLASS
, obj
, (Msg
)message
)))
2560 newleft
= data
->icld_ViewX
;
2561 newtop
= data
->icld_ViewY
;
2563 if (newleft
+ _mwidth(obj
) > data
->icld_AreaWidth
)
2564 newleft
= data
->icld_AreaWidth
- _mwidth(obj
);
2568 if (newtop
+ _mheight(obj
) > data
->icld_AreaHeight
)
2569 newtop
= data
->icld_AreaHeight
- _mheight(obj
);
2573 if ((newleft
!= data
->icld_ViewX
) || (newtop
!= data
->icld_ViewY
))
2575 SetAttrs(obj
, MUIA_Virtgroup_Left
, newleft
,
2576 MUIA_Virtgroup_Top
, newtop
,
2580 /* Get Internal Objects to use if not set .. */
2581 if (data
->icld_DisplayRastPort
== NULL
)
2583 if (_rp(obj
) != NULL
)
2585 data
->icld_DisplayRastPort
= CloneRastPort(_rp(obj
));
2587 #if defined(DEBUG_ILC_ICONRENDERING)
2590 D(bug("[IconList] IconList__MUIM_Show: ERROR - NULL RastPort!\n"));
2595 if (data
->icld_DisplayFlags
& ICONLIST_DISP_BUFFERED
)
2597 struct BitMap
*bitmap_New
= NULL
;
2598 ULONG tmp_RastDepth
= GetCyberMapAttr(data
->icld_DisplayRastPort
->BitMap
, CYBRMATTR_DEPTH
);
2599 if ((bitmap_New
= AllocBitMap(data
->icld_ViewWidth
,
2600 data
->icld_ViewHeight
,
2603 data
->icld_DisplayRastPort
->BitMap
))!=NULL
)
2605 struct Layer
* buffLayer
= CreateLayerTagList(&_screen(obj
)->LayerInfo
,
2609 data
->icld_ViewWidth
,
2610 data
->icld_ViewHeight
,
2612 __iconList_BackBuffLayerTags
);
2614 if (buffLayer
!= NULL
)
2616 data
->icld_BufferRastPort
= buffLayer
->rp
;
2617 #if defined(DEBUG_ILC_ATTRIBS) && defined(DEBUG_ILC_ICONRENDERING)
2618 D(bug("[IconList] %s: FrontRastPort @ %p, New BackLayer @ %p, BackRastport @ %p\n", __PRETTY_FUNCTION__
, data
->icld_DisplayRastPort
, data
->icld_BufferRastPort
->Layer
, data
->icld_BufferRastPort
));
2620 SET(obj
, MUIA_IconList_BufferRastport
, data
->icld_BufferRastPort
);
2621 data
->icld_DrawOffsetX
= 0;
2622 data
->icld_DrawOffsetY
= 0;
2626 FreeBitMap(bitmap_New
);
2627 data
->icld_BufferRastPort
= data
->icld_DisplayRastPort
;
2628 data
->icld_DrawOffsetX
= _mleft(obj
);
2629 data
->icld_DrawOffsetY
= _mtop(obj
);
2635 data
->icld_BufferRastPort
= data
->icld_DisplayRastPort
;
2636 data
->icld_DrawOffsetX
= _mleft(obj
);
2637 data
->icld_DrawOffsetY
= _mtop(obj
);
2640 if (data
->icld_IconLabelFont
== NULL
) data
->icld_IconLabelFont
= _font(obj
);
2641 if (data
->icld_IconInfoFont
== NULL
) data
->icld_IconInfoFont
= data
->icld_IconLabelFont
;
2642 #if defined(DEBUG_ILC_ICONRENDERING)
2643 D(bug("[IconList] IconList__MUIM_Show: Use Font @ 0x%p, RastPort @ 0x%p\n", data
->icld_IconLabelFont
, data
->icld_BufferRastPort
));
2646 if ((data
->icld_BufferRastPort
) && (data
->icld_IconLabelFont
))
2647 SetFont(data
->icld_BufferRastPort
, data
->icld_IconLabelFont
);
2654 /**************************************************************************
2656 **************************************************************************/
2657 IPTR
IconList__MUIM_Hide(struct IClass
*CLASS
, Object
*obj
, struct MUIP_Hide
*message
)
2659 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
2662 #if defined(DEBUG_ILC_FUNCS)
2663 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
2666 if ((rc
= DoSuperMethodA(CLASS
, obj
, (Msg
)message
)))
2668 if ((data
->icld_BufferRastPort
) && (data
->icld_BufferRastPort
!= data
->icld_DisplayRastPort
))
2670 DeleteLayer(0, data
->icld_BufferRastPort
->Layer
);
2673 data
->icld_BufferRastPort
= NULL
;
2675 if (data
->icld_DisplayRastPort
)
2676 FreeRastPort(data
->icld_DisplayRastPort
);
2678 data
->icld_DisplayRastPort
= NULL
;
2685 /**************************************************************************
2687 **************************************************************************/
2688 IPTR
IconList__MUIM_Cleanup(struct IClass
*CLASS
, Object
*obj
, struct MUIP_Cleanup
*message
)
2690 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
2691 struct IconEntry
*node
= NULL
;
2693 #if defined(DEBUG_ILC_FUNCS)
2694 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
2697 #if defined(__AROS__)
2698 ForeachNode(&data
->icld_IconList
, node
)
2700 Foreach_Node(&data
->icld_IconList
, node
);
2703 if (node
->ie_DiskObj
)
2705 FreeDiskObject(node
->ie_DiskObj
);
2706 node
->ie_DiskObj
= NULL
;
2710 DoMethod(_win(obj
), MUIM_Window_RemEventHandler
, (IPTR
)&data
->ehn
);
2712 return DoSuperMethodA(CLASS
, obj
, (Msg
)message
);
2717 /**************************************************************************
2719 **************************************************************************/
2720 IPTR
IconList__MUIM_AskMinMax(struct IClass
*CLASS
, Object
*obj
, struct MUIP_AskMinMax
*message
)
2722 ULONG rc
= DoSuperMethodA(CLASS
, obj
, (Msg
) message
);
2724 #if defined(DEBUG_ILC_FUNCS)
2725 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
2728 message
->MinMaxInfo
->MinWidth
+= 96;
2729 message
->MinMaxInfo
->MinHeight
+= 64;
2731 message
->MinMaxInfo
->DefWidth
+= 200;
2732 message
->MinMaxInfo
->DefHeight
+= 180;
2734 message
->MinMaxInfo
->MaxWidth
= MUI_MAXMAX
;
2735 message
->MinMaxInfo
->MaxHeight
= MUI_MAXMAX
;
2742 /**************************************************************************
2744 **************************************************************************/
2745 IPTR
IconList__MUIM_Layout(struct IClass
*CLASS
, Object
*obj
,struct MUIP_Layout
*message
)
2747 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
2750 #if defined(DEBUG_ILC_FUNCS)
2751 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
2754 rc
= DoSuperMethodA(CLASS
, obj
, (Msg
)message
);
2756 data
->icld_ViewWidth
= _mwidth(obj
);
2757 data
->icld_ViewHeight
= _mheight(obj
);
2763 static LONG
FirstVisibleLine(struct IconList_DATA
*data
)
2765 return data
->icld_ViewY
/ data
->icld_LVMAttribs
->lmva_RowHeight
;
2768 static LONG
NumVisibleLines(struct IconList_DATA
*data
)
2770 LONG visible
= data
->icld_ViewHeight
+ data
->icld_LVMAttribs
->lmva_RowHeight
- 1 +
2771 (data
->icld_ViewY
% data
->icld_LVMAttribs
->lmva_RowHeight
);
2773 visible
/= data
->icld_LVMAttribs
->lmva_RowHeight
;
2778 static void RenderListViewModeHeaderField(Object
*obj
, struct IconList_DATA
*data
,
2779 struct Rectangle
*rect
, LONG index
, BOOL sel
)
2781 IPTR penFill
, penText
, penDark
, penBright
;
2783 struct TextExtent te
;
2788 penFill
= _pens(obj
)[MPEN_HALFSHADOW
];
2789 penBright
= _pens(obj
)[MPEN_SHADOW
];
2790 penDark
= _pens(obj
)[MPEN_HALFSHINE
];
2794 penFill
= _pens(obj
)[MPEN_HALFSHINE
];
2795 penBright
= _pens(obj
)[MPEN_SHINE
];
2796 penDark
= _pens(obj
)[MPEN_HALFSHADOW
];
2798 penText
= _pens(obj
)[MPEN_TEXT
];
2800 #if defined(DEBUG_ILC_FUNCS)
2801 D(bug("[IconList]: %s(obj @ 0x%p)\n", __PRETTY_FUNCTION__
, obj
));
2804 if (((data
->icld_LVMAttribs
->lvma_Flags
& LVMAF_NOHEADER
) == 0) && (index
< NUM_COLUMNS
))
2806 text
= data
->icld_LVMAttribs
->lmva_ColumnTitle
[index
];
2808 SetAPen(data
->icld_BufferRastPort
, penFill
); /* Background */
2809 RectFill(data
->icld_BufferRastPort
, rect
->MinX
+ 1, rect
->MinY
+ 1,
2810 rect
->MaxX
- 1, rect
->MaxY
- 1);
2812 SetAPen(data
->icld_BufferRastPort
, penBright
); /* Top/Left */
2813 RectFill(data
->icld_BufferRastPort
, rect
->MinX
, rect
->MinY
, rect
->MinX
, rect
->MaxY
);
2814 RectFill(data
->icld_BufferRastPort
, rect
->MinX
+ 1, rect
->MinY
, rect
->MaxX
- 1, rect
->MinY
);
2816 SetAPen(data
->icld_BufferRastPort
,penDark
); /* Bottom/Right */
2817 RectFill(data
->icld_BufferRastPort
, rect
->MaxX
, rect
->MinY
, rect
->MaxX
, rect
->MaxY
);
2818 RectFill(data
->icld_BufferRastPort
, rect
->MinX
+ 1, rect
->MaxY
, rect
->MaxX
- 1, rect
->MaxY
);
2820 /* Draw the Sort indicator .. */
2821 if (index
== data
->icld_LVMAttribs
->lmva_SortColumn
)
2823 LONG x
= rect
->MaxX
- 4 - 6;
2824 LONG y
= (rect
->MinY
+ rect
->MaxY
+ 1) / 2 - 3;
2828 SetAPen(data
->icld_BufferRastPort
, _pens(obj
)[sel
? MPEN_SHADOW
: MPEN_HALFSHADOW
]);
2829 if (data
->icld_SortFlags
& MUIV_IconList_Sort_Reverse
)
2831 RectFill(data
->icld_BufferRastPort
, x
, y
, x
+ 5, y
+ 1);
2832 RectFill(data
->icld_BufferRastPort
, x
+ 1, y
+ 2, x
+ 4, y
+ 3);
2833 RectFill(data
->icld_BufferRastPort
, x
+ 2, y
+ 4, x
+ 3, y
+ 5);
2837 RectFill(data
->icld_BufferRastPort
, x
, y
+ 4, x
+ 5, y
+ 5);
2838 RectFill(data
->icld_BufferRastPort
, x
+ 1, y
+ 2, x
+ 4, y
+ 3);
2839 RectFill(data
->icld_BufferRastPort
, x
+ 2, y
, x
+ 3, y
+ 1);
2844 rect
->MinX
+= HEADERENTRY_SPACING_LEFT
;
2845 rect
->MinY
+= HEADERLINE_SPACING_TOP
;
2846 rect
->MaxX
-= HEADERENTRY_SPACING_RIGHT
;
2847 rect
->MaxY
-= HEADERLINE_SPACING_BOTTOM
;
2849 if (text
&& text
[0])
2852 fit
= TextFit(data
->icld_BufferRastPort
, text
, strlen(text
), &te
, NULL
, 1,
2853 rect
->MaxX
- rect
->MinX
+ 1,
2854 rect
->MaxY
- rect
->MinY
+ 1);
2858 SetABPenDrMd(data
->icld_BufferRastPort
, penText
, 0, JAM1
);
2859 Move(data
->icld_BufferRastPort
, rect
->MinX
, rect
->MinY
+ data
->icld_BufferRastPort
->TxBaseline
);
2860 Text(data
->icld_BufferRastPort
, text
, fit
);
2865 static void RenderListViewModeHeader(Object
*obj
, struct IconList_DATA
*data
)
2867 struct Rectangle linerect
;
2869 LONG firstvis
, lastvis
;
2871 #if defined(DEBUG_ILC_FUNCS)
2872 D(bug("[IconList]: %s(obj @ 0x%p)\n", __PRETTY_FUNCTION__
, obj
));
2875 if ((data
->icld_LVMAttribs
->lvma_Flags
& LVMAF_NOHEADER
) == 0)
2877 linerect
.MinX
= _mleft(obj
) - data
->icld_ViewX
;
2878 linerect
.MaxX
= _mright(obj
);
2879 linerect
.MinY
= _mtop(obj
);
2880 linerect
.MaxY
= _mtop(obj
) + data
->icld_LVMAttribs
->lmva_HeaderHeight
- 1;
2882 SetFont(data
->icld_BufferRastPort
, data
->icld_IconLabelFont
);
2884 x
= linerect
.MinX
+ HEADERLINE_SPACING_LEFT
;
2886 firstvis
= FirstVisibleColumnNumber(data
);
2887 lastvis
= LastVisibleColumnNumber(data
);
2889 for(i
= 0; i
< NUM_COLUMNS
; i
++)
2891 LONG index
= data
->icld_LVMAttribs
->lmva_ColumnPos
[i
];
2893 if (!(data
->icld_LVMAttribs
->lmva_ColumnFlags
[index
] & LVMCF_COLVISIBLE
)) continue;
2895 BOOL outside
= FALSE
;
2896 struct Rectangle field_rect
;
2898 field_rect
.MinX
= (i
== firstvis
) ? linerect
.MinX
: x
;
2899 field_rect
.MinY
= linerect
.MinY
;
2900 field_rect
.MaxX
= x
+ data
->icld_LVMAttribs
->lmva_ColumnWidth
[index
] - 1 + ((i
== lastvis
) ? HEADERLINE_SPACING_RIGHT
: 0);
2901 field_rect
.MaxY
= linerect
.MaxY
;
2903 /* data->update_rect1 and data->update_rect2 may
2904 point to rectangles to indicate that only icons
2905 in any of this rectangles need to be drawn */
2906 if (data
->update_rect1
)
2908 if (!RectAndRect(&field_rect
, data
->update_rect1
))
2912 if (data
->update_rect2
)
2914 if (data
->update_rect1
)
2916 if ((outside
== TRUE
) && RectAndRect(&field_rect
, data
->update_rect2
))
2921 if (!RectAndRect(&field_rect
, data
->update_rect2
))
2926 if (outside
!= TRUE
)
2928 RenderListViewModeHeaderField(obj
, data
, &field_rect
, index
, FALSE
);
2929 x
+= data
->icld_LVMAttribs
->lmva_ColumnWidth
[index
];
2933 D(bug("[IconList] %s: Column '%s' outside of update area .. skipping\n", __PRETTY_FUNCTION__
, data
->icld_LVMAttribs
->lmva_ColumnTitle
[i
]));
2937 if ((data
->icld_LVMAttribs
->lvma_Flags
& LVMAF_HEADERDRAWTOEND
) == LVMAF_HEADERDRAWTOEND
)
2939 x
+= HEADERLINE_SPACING_RIGHT
;
2941 if (x
< linerect
.MaxX
)
2945 // if (MustRenderRect(data, &linerect))
2947 SetABPenDrMd(data
->icld_BufferRastPort
, _pens(obj
)[MPEN_HALFSHINE
], 0, JAM1
);
2948 RectFill(data
->icld_BufferRastPort
, linerect
.MinX
, linerect
.MinY
, linerect
.MaxX
, linerect
.MaxY
);
2956 /**************************************************************************
2957 MUIM_Draw - draw the IconList
2958 **************************************************************************/
2960 IPTR
IconList__MUIM_Draw(struct IClass
*CLASS
, Object
*obj
, struct MUIP_Draw
*message
)
2962 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
2963 struct IconEntry
*entry
= NULL
;
2967 ULONG update_oldwidth
= 0,
2968 update_oldheight
= 0;
2970 LONG clear_xoffset
= 0,
2973 IPTR draw_id
= DrawCount
++;
2975 #if defined(DEBUG_ILC_FUNCS)
2976 D(bug("[IconList]: %s(obj @ 0x%p)\n", __PRETTY_FUNCTION__
, obj
));
2978 #if defined(DEBUG_ILC_ICONRENDERING)
2979 D(bug("[IconList] %s: id %d\n", __PRETTY_FUNCTION__
, draw_id
));
2982 DoSuperMethodA(CLASS
, obj
, (Msg
)message
);
2984 if (!(data
->icld__Option_IconListFixedBackground
))
2986 clear_xoffset
= data
->icld_ViewX
;
2987 clear_yoffset
= data
->icld_ViewY
;
2990 // If window size changes, only update needed areas
2991 if (data
->update_oldwidth
== 0) data
->update_oldwidth
= data
->icld_ViewWidth
;
2992 if (data
->update_oldheight
== 0) data
->update_oldheight
= data
->icld_ViewHeight
;
2993 if ((data
->update_oldwidth
!= data
->icld_ViewWidth
) || (data
->update_oldheight
!= data
->icld_ViewHeight
))
2995 if (data
->icld_UpdateMode
!= UPDATE_SCROLL
)
2997 data
->icld_UpdateMode
= UPDATE_RESIZE
;
2998 update_oldwidth
= data
->update_oldwidth
;
2999 update_oldheight
= data
->update_oldheight
;
3000 data
->update_oldwidth
= data
->icld_ViewWidth
;
3001 data
->update_oldheight
= data
->icld_ViewHeight
;
3005 if ((message
->flags
& MADF_DRAWUPDATE
) || (data
->icld_UpdateMode
== UPDATE_RESIZE
))
3007 #if defined(DEBUG_ILC_ICONRENDERING)
3009 if (message
->flags
& MADF_DRAWUPDATE
)
3011 bug("[IconList] %s#%d: MADF_DRAWUPDATE\n", __PRETTY_FUNCTION__
, draw_id
);
3015 bug("[IconList] %s#%d: UPDATE_RESIZE\n", __PRETTY_FUNCTION__
, draw_id
);
3019 if ((data
->icld_UpdateMode
== UPDATE_HEADERENTRY
) && (data
->update_entry
< NUM_COLUMNS
)) /* draw the header entry */
3021 struct Rectangle field_rect
;
3022 LONG index
, i
, firstvis
, lastvis
;
3024 firstvis
= FirstVisibleColumnNumber(data
);
3025 lastvis
= LastVisibleColumnNumber(data
);
3027 field_rect
.MinX
= _mleft(obj
) - data
->icld_ViewX
;
3029 field_rect
.MinY
= _mtop(obj
);
3030 field_rect
.MaxY
= field_rect
.MinY
+ data
->icld_LVMAttribs
->lmva_HeaderHeight
- 1;
3032 for(i
= 0; i
< NUM_COLUMNS
; i
++)
3034 index
= data
->icld_LVMAttribs
->lmva_ColumnPos
[i
];
3035 if (!(data
->icld_LVMAttribs
->lmva_ColumnFlags
[index
] & LVMCF_COLVISIBLE
)) continue;
3037 field_rect
.MaxX
= field_rect
.MinX
+ data
->icld_LVMAttribs
->lmva_ColumnWidth
[index
] - 1;
3038 if (index
== lastvis
)
3039 field_rect
.MaxX
+= HEADERLINE_SPACING_RIGHT
;
3041 if (data
->update_entry
!= index
)
3043 field_rect
.MinX
+= data
->icld_LVMAttribs
->lmva_ColumnWidth
[index
];
3044 if (index
== firstvis
)
3045 field_rect
.MinX
+= HEADERLINE_SPACING_LEFT
;
3051 clip
= MUI_AddClipping(muiRenderInfo(obj
), _mleft(obj
), _mtop(obj
), _mright(obj
) - _mleft(obj
) + 1, data
->icld_LVMAttribs
->lmva_HeaderHeight
);
3053 if (data
->icld_LVMAttribs
->lmva_LastSelectedColumn
== data
->update_entry
)
3054 RenderListViewModeHeaderField(obj
, data
, &field_rect
, data
->update_entry
, TRUE
);
3056 RenderListViewModeHeaderField(obj
, data
, &field_rect
, data
->update_entry
, FALSE
);
3058 data
->icld_UpdateMode
= 0;
3059 data
->update_entry
= NULL
;
3061 MUI_RemoveClipping(muiRenderInfo(obj
), clip
);
3065 else if ((data
->icld_UpdateMode
== UPDATE_SINGLEENTRY
) && (data
->update_entry
!= NULL
)) /* draw only a single entry at update_entry */
3067 struct Rectangle rect
;
3069 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
3071 LONG count
= 0, index
= -1;
3073 D(bug("[IconList] %s#%d: UPDATE_SINGLEENTRY + ICONLIST_DISP_MODELIST\n", __PRETTY_FUNCTION__
, draw_id
));
3075 rect
.MinX
= _mleft(obj
);
3076 rect
.MaxX
= _mleft(obj
) + _mwidth(obj
) - 1;
3078 ForeachNode(&data
->icld_IconList
, entry
)
3080 if (entry
== data
->update_entry
)
3085 if (entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
3093 rect
.MinY
= _mtop(obj
) + data
->icld_LVMAttribs
->lmva_HeaderHeight
- data
->icld_ViewY
+ (index
* data
->icld_LVMAttribs
->lmva_RowHeight
);
3094 rect
.MaxY
= rect
.MinY
+ data
->icld_LVMAttribs
->lmva_RowHeight
- 1;
3096 if ((rect
.MaxY
< (_mtop(obj
) + data
->icld_LVMAttribs
->lmva_HeaderHeight
))
3097 || (rect
.MinY
> (_mtop(obj
) + _mheight(obj
) - 1)))
3100 if (rect
.MinY
< (_mtop(obj
) + data
->icld_LVMAttribs
->lmva_HeaderHeight
)) rect
.MinY
= _mtop(obj
) + data
->icld_LVMAttribs
->lmva_HeaderHeight
;
3101 if (rect
.MaxY
> (_mtop(obj
) + _mheight(obj
) - 1)) rect
.MaxY
= _mtop(obj
) + _mheight(obj
) - 1;
3103 clip
= MUI_AddClipping(muiRenderInfo(obj
), rect
.MinX
, rect
.MinY
, rect
.MaxX
- rect
.MinX
+ 1, rect
.MaxY
- rect
.MinY
+ 1);
3105 DoMethod(obj
, MUIM_DrawBackground
,
3106 rect
.MinX
, rect
.MinY
,
3107 rect
.MaxX
- rect
.MinX
+ 1, rect
.MaxY
- rect
.MinY
+ 1,
3108 clear_xoffset
, clear_yoffset
,
3111 entry
->ie_Flags
|= ICONENTRY_FLAG_NEEDSUPDATE
;
3112 DoMethod(obj
, MUIM_IconList_DrawEntry
, data
->update_entry
, index
);
3113 entry
->ie_Flags
&= ~ICONENTRY_FLAG_NEEDSUPDATE
;
3114 data
->icld_UpdateMode
= 0;
3115 data
->update_entry
= NULL
;
3120 D(bug("[IconList] %s#%d: UPDATE_SINGLEENTRY (entry @ 0x%p)\n", __PRETTY_FUNCTION__
, draw_id
, data
->update_entry
));
3122 IconList_GetIconAreaRectangle(obj
, data
, data
->update_entry
, &rect
);
3124 rect
.MinX
+= _mleft(obj
) + (data
->update_entry
->ie_IconX
- data
->icld_ViewX
);
3125 rect
.MaxX
+= _mleft(obj
) + (data
->update_entry
->ie_IconX
- data
->icld_ViewX
);
3126 rect
.MinY
+= _mtop(obj
) + (data
->update_entry
->ie_IconY
- data
->icld_ViewY
);
3127 rect
.MaxY
+= _mtop(obj
) + (data
->update_entry
->ie_IconY
- data
->icld_ViewY
);
3129 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
3131 if (data
->update_entry
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
3133 rect
.MinX
+= ((data
->icld_IconAreaLargestWidth
- data
->update_entry
->ie_AreaWidth
)/2);
3134 rect
.MaxX
+= ((data
->icld_IconAreaLargestWidth
- data
->update_entry
->ie_AreaWidth
)/2);
3137 if (data
->update_entry
->ie_AreaHeight
< data
->icld_IconAreaLargestHeight
)
3139 rect
.MinY
+= ((data
->icld_IconAreaLargestHeight
- data
->update_entry
->ie_AreaHeight
)/2);
3140 rect
.MaxY
+= ((data
->icld_IconAreaLargestHeight
- data
->update_entry
->ie_AreaHeight
)/2);
3144 clip
= MUI_AddClipping(muiRenderInfo(obj
), rect
.MinX
, rect
.MinY
, rect
.MaxX
- rect
.MinX
+ 1, rect
.MaxY
- rect
.MinY
+ 1);
3146 #if defined(DEBUG_ILC_ICONRENDERING)
3147 D(bug("[IconList] %s#%d: UPDATE_SINGLEENTRY: Calling MUIM_DrawBackground (A)\n", __PRETTY_FUNCTION__
, draw_id
));
3149 DoMethod(obj
, MUIM_DrawBackground
,
3150 rect
.MinX
, rect
.MinY
,
3151 rect
.MaxX
- rect
.MinX
+ 1, rect
.MaxY
- rect
.MinY
+ 1,
3152 clear_xoffset
, clear_yoffset
,
3155 /* We could have deleted also other icons so they must be redrawn */
3156 #if defined(__AROS__)
3157 ForeachNode(&data
->icld_IconList
, entry
)
3159 Foreach_Node(&data
->icld_IconList
, entry
);
3162 if ((entry
!= data
->update_entry
) && (entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
))
3164 struct Rectangle rect2
;
3165 IconList_GetIconAreaRectangle(obj
, data
, entry
, &rect2
);
3167 rect2
.MinX
+= _mleft(obj
) - data
->icld_ViewX
+ entry
->ie_IconX
;
3168 rect2
.MaxX
+= _mleft(obj
) - data
->icld_ViewX
+ entry
->ie_IconX
;
3169 rect2
.MinY
+= _mtop(obj
) - data
->icld_ViewY
+ entry
->ie_IconY
;
3170 rect2
.MaxY
+= _mtop(obj
) - data
->icld_ViewY
+ entry
->ie_IconY
;
3172 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
3174 if (entry
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
3176 rect2
.MinX
+= ((data
->icld_IconAreaLargestWidth
- entry
->ie_AreaWidth
)/2);
3177 rect2
.MaxX
+= ((data
->icld_IconAreaLargestWidth
- entry
->ie_AreaWidth
)/2);
3180 if (entry
->ie_AreaHeight
< data
->icld_IconAreaLargestHeight
)
3182 rect2
.MinY
+= ((data
->icld_IconAreaLargestHeight
- entry
->ie_AreaHeight
)/2);
3183 rect2
.MaxY
+= ((data
->icld_IconAreaLargestHeight
- entry
->ie_AreaHeight
)/2);
3187 if (RectAndRect(&rect
, &rect2
))
3189 // Update entry here
3190 entry
->ie_Flags
|= ICONENTRY_FLAG_NEEDSUPDATE
;
3191 DoMethod(obj
, MUIM_IconList_DrawEntry
, entry
, ICONENTRY_DRAWMODE_PLAIN
);
3192 DoMethod(obj
, MUIM_IconList_DrawEntryLabel
, entry
, ICONENTRY_DRAWMODE_PLAIN
);
3193 entry
->ie_Flags
&= ~ICONENTRY_FLAG_NEEDSUPDATE
;
3198 entry
->ie_Flags
|= ICONENTRY_FLAG_NEEDSUPDATE
;
3199 DoMethod(obj
, MUIM_IconList_DrawEntry
, data
->update_entry
, ICONENTRY_DRAWMODE_PLAIN
);
3200 DoMethod(obj
, MUIM_IconList_DrawEntryLabel
, data
->update_entry
, ICONENTRY_DRAWMODE_PLAIN
);
3201 entry
->ie_Flags
&= ~ICONENTRY_FLAG_NEEDSUPDATE
;
3202 data
->icld_UpdateMode
= 0;
3203 data
->update_entry
= NULL
;
3205 if (data
->update_entry
== NULL
)
3207 if (data
->icld_DisplayRastPort
!= data
->icld_BufferRastPort
)
3209 #if defined(DEBUG_ILC_ICONRENDERING)
3210 D(bug("[IconList] %s#%d: UPDATE_SINGLEENTRY Blitting to front rastport..\n", __PRETTY_FUNCTION__
, draw_id
));
3212 BltBitMapRastPort(data
->icld_BufferRastPort
->BitMap
,
3213 rect
.MinX
- _mleft(obj
), rect
.MinY
- _mtop(obj
),
3214 data
->icld_DisplayRastPort
,
3215 rect
.MinX
, rect
.MinY
,
3216 rect
.MaxX
- rect
.MinX
+ 1, rect
.MaxY
- rect
.MinY
+ 1,
3219 MUI_RemoveClipping(muiRenderInfo(obj
), clip
);
3223 else if (data
->icld_UpdateMode
== UPDATE_SCROLL
)
3225 struct Region
*region
= NULL
;
3226 struct Rectangle xrect
,
3228 BOOL scroll_caused_damage
;
3230 #if defined(DEBUG_ILC_ICONRENDERING)
3231 D(bug("[IconList] %s#%d: UPDATE_SCROLL.\n", __PRETTY_FUNCTION__
, draw_id
));
3234 if (!data
->icld__Option_IconListFixedBackground
)
3236 scroll_caused_damage
= (_rp(obj
)->Layer
->Flags
& LAYERREFRESH
) ? FALSE
: TRUE
;
3238 data
->icld_UpdateMode
= 0;
3240 if ((abs(data
->update_scrolldx
) >= _mwidth(obj
)) ||
3241 (abs(data
->update_scrolldy
) >= _mheight(obj
)))
3243 #if defined(DEBUG_ILC_ICONRENDERING)
3244 D(bug("[IconList] %s#%d: UPDATE_SCROLL: Moved outside current view -> Causing Redraw .. MADF_DRAWOBJECT\n", __PRETTY_FUNCTION__
, draw_id
));
3246 MUI_Redraw(obj
, MADF_DRAWOBJECT
);
3250 if (!(region
= NewRegion()))
3252 #if defined(DEBUG_ILC_ICONRENDERING)
3253 D(bug("[IconList] %s#%d: UPDATE_SCROLL: Couldnt Alloc Region -> Causing Redraw ...MADF_DRAWOBJECT\n", __PRETTY_FUNCTION__
, draw_id
));
3255 MUI_Redraw(obj
, MADF_DRAWOBJECT
);
3259 if (data
->update_scrolldx
> 0)
3261 xrect
.MinX
= _mright(obj
) - data
->update_scrolldx
;
3262 xrect
.MinY
= _mtop(obj
);
3263 xrect
.MaxX
= _mright(obj
);
3264 xrect
.MaxY
= _mbottom(obj
);
3266 OrRectRegion(region
, &xrect
);
3268 data
->update_rect1
= &xrect
;
3270 else if (data
->update_scrolldx
< 0)
3272 xrect
.MinX
= _mleft(obj
);
3273 xrect
.MinY
= _mtop(obj
);
3274 xrect
.MaxX
= _mleft(obj
) - data
->update_scrolldx
;
3275 xrect
.MaxY
= _mbottom(obj
);
3277 OrRectRegion(region
, &xrect
);
3279 data
->update_rect1
= &xrect
;
3282 if (data
->update_scrolldy
> 0)
3284 yrect
.MinX
= _mleft(obj
);
3285 yrect
.MinY
= _mbottom(obj
) - data
->update_scrolldy
;
3286 if (((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
3287 && (yrect
.MinY
< (_mtop(obj
) + data
->icld_LVMAttribs
->lmva_HeaderHeight
)))
3289 xrect
.MinY
= data
->icld_LVMAttribs
->lmva_HeaderHeight
;
3291 yrect
.MaxX
= _mright(obj
);
3292 yrect
.MaxY
= _mbottom(obj
);
3294 OrRectRegion(region
, &yrect
);
3296 data
->update_rect2
= &yrect
;
3298 else if (data
->update_scrolldy
< 0)
3300 yrect
.MinX
= _mleft(obj
);
3301 yrect
.MinY
= _mtop(obj
);
3302 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
3304 xrect
.MinY
+= data
->icld_LVMAttribs
->lmva_HeaderHeight
;
3306 yrect
.MaxX
= _mright(obj
);
3307 yrect
.MaxY
= _mtop(obj
) - data
->update_scrolldy
;
3309 OrRectRegion(region
, &yrect
);
3311 data
->update_rect2
= &yrect
;
3314 #if defined(DEBUG_ILC_ICONRENDERING)
3315 D(bug("[IconList] %s#%d: UPDATE_SCROLL: Scrolling Raster..\n", __PRETTY_FUNCTION__
, draw_id
));
3317 if (data
->icld_DisplayRastPort
== data
->icld_BufferRastPort
)
3319 ScrollRasterBF(data
->icld_BufferRastPort
,
3320 data
->update_scrolldx
,
3321 data
->update_scrolldy
,
3329 ScrollRasterBF(data
->icld_BufferRastPort
,
3330 data
->update_scrolldx
,
3331 data
->update_scrolldy
,
3338 scroll_caused_damage
= scroll_caused_damage
&& (_rp(obj
)->Layer
->Flags
& LAYERREFRESH
) ? TRUE
: FALSE
;
3340 clip
= MUI_AddClipRegion(muiRenderInfo(obj
), region
);
3343 #if defined(DEBUG_ILC_ICONRENDERING)
3344 D(bug("[IconList] %s#%d: UPDATE_SCROLL: Causing Redraw -> MADF_DRAWOBJECT..\n", __PRETTY_FUNCTION__
, draw_id
));
3346 MUI_Redraw(obj
, MADF_DRAWOBJECT
);
3348 data
->update_rect1
= data
->update_rect2
= NULL
;
3350 if (!data
->icld__Option_IconListFixedBackground
)
3352 MUI_RemoveClipRegion(muiRenderInfo(obj
), clip
);
3354 if (scroll_caused_damage
)
3356 if (MUI_BeginRefresh(muiRenderInfo(obj
), 0))
3358 /* Theoretically it might happen that more damage is caused
3359 after ScrollRaster. By something else, like window movement
3360 in front of our window. Therefore refresh root object of
3361 window, not just this object */
3365 GET(_win(obj
),MUIA_Window_RootObject
, &o
);
3366 MUI_Redraw(o
, MADF_DRAWOBJECT
);
3367 #if defined(DEBUG_ILC_ICONRENDERING)
3368 D(bug("[IconList] %s#%d: UPDATE_SCROLL: Causing Redraw -> MADF_DRAWOBJECT..\n", __PRETTY_FUNCTION__
, draw_id
));
3370 MUI_EndRefresh(muiRenderInfo(obj
), 0);
3374 if (data
->icld_DisplayRastPort
!= data
->icld_BufferRastPort
)
3376 #if defined(DEBUG_ILC_ICONRENDERING)
3377 D(bug("[IconList] %s#%d: UPDATE_SCROLL: Blitting to front rastport..\n", __PRETTY_FUNCTION__
, draw_id
));
3379 BltBitMapRastPort(data
->icld_BufferRastPort
->BitMap
,
3381 data
->icld_DisplayRastPort
,
3382 _mleft(obj
), _mtop(obj
),
3383 _mwidth(obj
), _mheight(obj
),
3388 else if (data
->icld_UpdateMode
== UPDATE_RESIZE
)
3390 struct Region
*region
= NULL
;
3391 struct Rectangle wrect
,
3396 #if defined(DEBUG_ILC_ICONRENDERING)
3397 D(bug("[IconList] %s#%d: UPDATE_RESIZE.\n", __PRETTY_FUNCTION__
, draw_id
));
3400 if ((data
->icld_BufferRastPort
) && (data
->icld_BufferRastPort
!= data
->icld_DisplayRastPort
))
3402 //Free up the buffers Layer, rastport and bitmap so we can replace them ..
3403 if ((GetBitMapAttr(data
->icld_BufferRastPort
->BitMap
, BMA_WIDTH
) != data
->icld_ViewWidth
)
3404 || (GetBitMapAttr(data
->icld_BufferRastPort
->BitMap
, BMA_HEIGHT
) != data
->icld_ViewHeight
))
3406 struct Layer
*oldLayer
= data
->icld_BufferRastPort
->Layer
;
3407 #if defined(DEBUG_ILC_ATTRIBS) && defined(DEBUG_ILC_ICONRENDERING)
3408 D(bug("[IconList] %s: Destroying old BackLayer\n", __PRETTY_FUNCTION__
));
3410 data
->icld_BufferRastPort
= data
->icld_DisplayRastPort
;
3411 DeleteLayer(0, oldLayer
);
3414 if (data
->icld_BufferRastPort
== data
->icld_DisplayRastPort
)
3416 struct Bitmap
*bitmap_New
;
3417 ULONG tmp_RastDepth
;
3419 tmp_RastDepth
= GetCyberMapAttr(data
->icld_DisplayRastPort
->BitMap
, CYBRMATTR_DEPTH
);
3420 if ((bitmap_New
= (struct Bitmap
*)AllocBitMap(data
->icld_ViewWidth
,
3421 data
->icld_ViewHeight
,
3424 data
->icld_DisplayRastPort
->BitMap
))!=NULL
)
3426 struct Layer
* buffLayer
= CreateLayerTagList(&_screen(obj
)->LayerInfo
,
3430 data
->icld_ViewWidth
,
3431 data
->icld_ViewHeight
,
3433 __iconList_BackBuffLayerTags
);
3435 if (buffLayer
!= NULL
)
3437 data
->icld_BufferRastPort
= buffLayer
->rp
;
3438 #if defined(DEBUG_ILC_ATTRIBS) && defined(DEBUG_ILC_ICONRENDERING)
3439 D(bug("[IconList] %s: FrontRastPort @ %p, New BackLayer @ %p, BackRastport @ %p\n", __PRETTY_FUNCTION__
, data
->icld_DisplayRastPort
, data
->icld_BufferRastPort
->Layer
, data
->icld_BufferRastPort
));
3441 SET(obj
, MUIA_IconList_BufferRastport
, data
->icld_BufferRastPort
);
3442 data
->icld_DrawOffsetX
= 0;
3443 data
->icld_DrawOffsetY
= 0;
3447 FreeBitMap(bitmap_New
);
3448 data
->icld_BufferRastPort
= data
->icld_DisplayRastPort
;
3449 data
->icld_DrawOffsetX
= _mleft(obj
);
3450 data
->icld_DrawOffsetY
= _mtop(obj
);
3456 data
->icld_UpdateMode
= 0;
3458 if (!data
->icld__Option_IconListScaledBackground
)
3460 if (!(region
= NewRegion()))
3462 #if defined(DEBUG_ILC_ICONRENDERING)
3463 D(bug("[IconList] %s#%d: UPDATE_RESIZE: Causing Redraw -> MADF_DRAWOBJECT..\n", __PRETTY_FUNCTION__
, draw_id
));
3465 MUI_Redraw(obj
, MADF_DRAWOBJECT
);
3469 if ( data
->icld_ViewWidth
> update_oldwidth
)
3470 diffw
= data
->icld_ViewWidth
- update_oldwidth
;
3471 if ( data
->icld_ViewHeight
> update_oldheight
)
3472 diffh
= data
->icld_ViewHeight
- update_oldheight
;
3476 wrect
.MinX
= _mright(obj
) - diffw
;
3477 wrect
.MinY
= _mtop(obj
);
3478 wrect
.MaxX
= _mright(obj
);
3479 wrect
.MaxY
= _mbottom(obj
);
3480 OrRectRegion(region
, &wrect
);
3481 data
->update_rect1
= &wrect
;
3486 hrect
.MinX
= _mleft(obj
);
3487 hrect
.MinY
= _mbottom(obj
) - diffh
;
3488 hrect
.MaxX
= _mright(obj
);
3489 hrect
.MaxX
= _mright(obj
);
3490 hrect
.MaxY
= _mbottom(obj
);
3491 OrRectRegion(region
, &hrect
);
3492 data
->update_rect2
= &hrect
;
3496 clip
= MUI_AddClipRegion(muiRenderInfo(obj
), region
);
3500 /* View became smaller both in horizontal and vertical direction.
3503 DisposeRegion(region
);
3508 #if defined(DEBUG_ILC_ICONRENDERING)
3509 D(bug("[IconList] %s#%d: UPDATE_RESIZE: Causing Redraw -> MADF_DRAWOBJECT..\n", __PRETTY_FUNCTION__
, draw_id
));
3511 MUI_Redraw(obj
, MADF_DRAWOBJECT
);
3513 if (!data
->icld__Option_IconListScaledBackground
)
3517 data
->update_rect1
= data
->update_rect2
= NULL
;
3518 MUI_RemoveClipRegion(muiRenderInfo(obj
), clip
);
3519 } else DisposeRegion(region
);
3526 if (message
->flags
& MADF_DRAWOBJECT
)
3528 struct Rectangle viewrect
;
3529 int current
= 0, first
= 0, visible
= 0;
3531 #if defined(DEBUG_ILC_ICONRENDERING)
3532 D(bug("[IconList] %s#%d: MADF_DRAWOBJECT\n", __PRETTY_FUNCTION__
, draw_id
));
3535 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
3537 clip
= MUI_AddClipping(muiRenderInfo(obj
), _mleft(obj
), _mtop(obj
), _mwidth(obj
), data
->icld_LVMAttribs
->lmva_HeaderHeight
);
3538 RenderListViewModeHeader(obj
, data
);
3539 MUI_RemoveClipping(muiRenderInfo(obj
), clip
);
3541 viewrect
.MinY
= _mtop(obj
) + data
->icld_LVMAttribs
->lmva_HeaderHeight
;
3543 first
= FirstVisibleLine(data
);
3544 visible
= NumVisibleLines(data
);
3546 clip
= MUI_AddClipping(muiRenderInfo(obj
), _mleft(obj
), _mtop(obj
) + data
->icld_LVMAttribs
->lmva_HeaderHeight
, _mwidth(obj
), _mheight(obj
) - data
->icld_LVMAttribs
->lmva_HeaderHeight
);
3550 viewrect
.MinY
= _mtop(obj
);
3551 clip
= MUI_AddClipping(muiRenderInfo(obj
), _mleft(obj
), _mtop(obj
), _mwidth(obj
), _mheight(obj
));
3554 viewrect
.MaxY
= _mtop(obj
) + _mheight(obj
) - 1;
3555 viewrect
.MinX
= _mleft(obj
);
3556 viewrect
.MaxX
= _mleft(obj
) + _mwidth(obj
) - 1;
3558 #if defined(DEBUG_ILC_ICONRENDERING)
3559 D(bug("[IconList] %s#%d: MADF_DRAWOBJECT: Calling MUIM_DrawBackground (B)\n", __PRETTY_FUNCTION__
, draw_id
));
3562 obj
, MUIM_DrawBackground
, viewrect
.MinX
, viewrect
.MinY
, (viewrect
.MaxX
- viewrect
.MinX
) + 1, (viewrect
.MaxY
- viewrect
.MinY
) + 1,
3563 clear_xoffset
, clear_yoffset
, 0
3565 #if defined(__AROS__)
3566 ForeachNode(&data
->icld_IconList
, entry
)
3568 Foreach_Node(&data
->icld_IconList
, entry
);
3571 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
3573 if (entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
3575 if ((current
>= first
) && (current
<= (first
+ visible
)))
3577 DoMethod(obj
, MUIM_IconList_DrawEntry
, entry
, current
);
3584 if ((entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
) &&
3585 (entry
->ie_DiskObj
) &&
3586 (entry
->ie_IconX
!= NO_ICON_POSITION
) &&
3587 (entry
->ie_IconY
!= NO_ICON_POSITION
))
3589 struct Rectangle iconrect
;
3590 IconList_GetIconAreaRectangle(obj
, data
, entry
, &iconrect
);
3592 iconrect
.MinX
+= viewrect
.MinX
- data
->icld_ViewX
+ entry
->ie_IconX
;
3593 iconrect
.MaxX
+= viewrect
.MinX
- data
->icld_ViewX
+ entry
->ie_IconX
;
3594 iconrect
.MinY
+= viewrect
.MinY
- data
->icld_ViewY
+ entry
->ie_IconY
;
3595 iconrect
.MaxY
+= viewrect
.MinY
- data
->icld_ViewY
+ entry
->ie_IconY
;
3597 if (RectAndRect(&viewrect
, &iconrect
))
3599 DoMethod(obj
, MUIM_IconList_DrawEntry
, entry
, ICONENTRY_DRAWMODE_PLAIN
);
3600 DoMethod(obj
, MUIM_IconList_DrawEntryLabel
, entry
, ICONENTRY_DRAWMODE_PLAIN
);
3606 if (data
->icld_DisplayRastPort
!= data
->icld_BufferRastPort
)
3608 #if defined(DEBUG_ILC_ICONRENDERING)
3609 D(bug("[IconList] %s#%d: MADF_DRAWOBJECT: Blitting to front rastport..\n", __PRETTY_FUNCTION__
, draw_id
));
3611 BltBitMapRastPort(data
->icld_BufferRastPort
->BitMap
,
3613 data
->icld_DisplayRastPort
,
3614 _mleft(obj
), _mtop(obj
),
3615 _mwidth(obj
), _mheight(obj
),
3619 MUI_RemoveClipping(muiRenderInfo(obj
), clip
);
3621 data
->icld_UpdateMode
= 0;
3625 #if defined(DEBUG_ILC_ICONRENDERING)
3626 D(bug("[IconList] %s: Draw finished for id %d\n", __PRETTY_FUNCTION__
, draw_id
));
3632 ///IconList__MUIM_IconList_Update()
3633 /**************************************************************************
3634 MUIM_IconList_Refresh
3635 Implemented by subclasses
3636 **************************************************************************/
3637 IPTR
IconList__MUIM_IconList_Update(struct IClass
*CLASS
, Object
*obj
, struct MUIP_IconList_Update
*message
)
3639 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
3641 #if defined(DEBUG_ILC_FUNCS)
3642 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
3645 data
->icld_FocusIcon
= NULL
;
3646 SET(obj
, MUIA_IconList_Changed
, TRUE
);
3652 ///MUIM_IconList_Clear()
3653 /**************************************************************************
3655 **************************************************************************/
3656 IPTR
IconList__MUIM_IconList_Clear(struct IClass
*CLASS
, Object
*obj
, struct MUIP_IconList_Clear
*message
)
3658 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
3659 struct IconEntry
*node
= NULL
;
3661 #if defined(DEBUG_ILC_FUNCS)
3662 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
3665 while ((node
= (struct IconEntry
*)RemTail((struct List
*)&data
->icld_IconList
)))
3667 DoMethod(obj
, MUIM_IconList_DestroyEntry
, node
);
3670 data
->icld_SelectionLastClicked
= NULL
;
3671 data
->icld_FocusIcon
= NULL
;
3673 data
->icld_ViewX
= data
->icld_ViewY
= data
->icld_AreaWidth
= data
->icld_AreaHeight
= 0;
3675 D(bug("[IconList]: %s: call SetSuperAttrs()\n", __PRETTY_FUNCTION__
));
3676 SetSuperAttrs(CLASS
, obj
, MUIA_Virtgroup_Left
, data
->icld_ViewX
,
3677 MUIA_Virtgroup_Top
, data
->icld_ViewY
,
3680 D(bug("[IconList]: %s: call SetAttrs()\n", __PRETTY_FUNCTION__
));
3681 SetAttrs(obj
, MUIA_Virtgroup_Left
, data
->icld_ViewX
,
3682 MUIA_Virtgroup_Top
, data
->icld_ViewY
,
3685 D(bug("[IconList]: %s: Set MUIA_IconList_Width and MUIA_IconList_Height\n", __PRETTY_FUNCTION__
));
3686 SetAttrs(obj
, MUIA_IconList_Width
, data
->icld_AreaWidth
,
3687 MUIA_IconList_Height
, data
->icld_AreaHeight
,
3690 D(bug("[IconList]: %s: call MUI_Redraw()\n", __PRETTY_FUNCTION__
));
3691 MUI_Redraw(obj
,MADF_DRAWOBJECT
);
3696 ///IconList__MUIM_IconList_DestroyEntry()
3697 IPTR
IconList__MUIM_IconList_DestroyEntry(struct IClass
*CLASS
, Object
*obj
, struct MUIP_IconList_DestroyEntry
*message
)
3699 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
3701 #if defined(DEBUG_ILC_FUNCS)
3702 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
3707 if (message
->entry
->ie_Flags
& ICONENTRY_FLAG_SELECTED
)
3709 if (data
->icld_SelectionLastClicked
== message
->entry
)
3711 struct IconList_Entry
*nextentry
= &message
->entry
->ie_IconListEntry
;
3713 /* get selected entries from SOURCE iconlist */
3714 DoMethod(obj
, MUIM_IconList_NextIcon
, MUIV_IconList_NextIcon_Selected
, (IPTR
)&nextentry
);
3715 if ((nextentry
) && (nextentry
!= (IPTR
)MUIV_IconList_NextIcon_End
))
3716 data
->icld_SelectionLastClicked
= (struct IconEntry
*)((IPTR
)nextentry
- ((IPTR
)&message
->entry
->ie_IconListEntry
- (IPTR
)message
->entry
));
3718 data
->icld_SelectionLastClicked
= NULL
;
3720 if (data
->icld_FocusIcon
== message
->entry
)
3721 data
->icld_FocusIcon
= data
->icld_SelectionLastClicked
;
3723 Remove(&message
->entry
->ie_SelectionNode
);
3726 if (message
->entry
->ie_TxtBuf_DisplayedLabel
)
3727 FreeVecPooled(data
->icld_Pool
, message
->entry
->ie_TxtBuf_DisplayedLabel
);
3729 if (message
->entry
->ie_TxtBuf_PROT
)
3730 FreePooled(data
->icld_Pool
, message
->entry
->ie_TxtBuf_PROT
, 8);
3732 if (message
->entry
->ie_TxtBuf_SIZE
)
3733 FreePooled(data
->icld_Pool
, message
->entry
->ie_TxtBuf_SIZE
, 30);
3735 if (message
->entry
->ie_TxtBuf_TIME
)
3736 FreePooled(data
->icld_Pool
, message
->entry
->ie_TxtBuf_TIME
, LEN_DATSTRING
);
3738 if (message
->entry
->ie_TxtBuf_DATE
)
3739 FreePooled(data
->icld_Pool
, message
->entry
->ie_TxtBuf_DATE
, LEN_DATSTRING
);
3741 if (message
->entry
->ie_DiskObj
)
3742 FreeDiskObject(message
->entry
->ie_DiskObj
);
3744 if (message
->entry
->ie_FileInfoBlock
)
3745 FreeMem(message
->entry
->ie_FileInfoBlock
, sizeof(struct FileInfoBlock
));
3747 if (message
->entry
->ie_IconListEntry
.label
)
3748 FreePooled(data
->icld_Pool
, message
->entry
->ie_IconListEntry
.label
, strlen(message
->entry
->ie_IconListEntry
.label
)+1);
3750 if (message
->entry
->ie_IconNode
.ln_Name
)
3751 FreePooled(data
->icld_Pool
, message
->entry
->ie_IconNode
.ln_Name
, strlen(message
->entry
->ie_IconNode
.ln_Name
)+1);
3753 FreePooled(data
->icld_Pool
, message
->entry
, sizeof(struct IconEntry
));
3759 ///IconList__MUIM_IconList_CreateEntry()
3760 /**************************************************************************
3761 MUIM_IconList_CreateEntry.
3762 Returns 0 on failure otherwise it returns the icons entry ..
3763 **************************************************************************/
3764 IPTR
IconList__MUIM_IconList_CreateEntry(struct IClass
*CLASS
, Object
*obj
, struct MUIP_IconList_CreateEntry
*message
)
3766 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
3767 struct IconEntry
*entry
= NULL
;
3769 struct DateStamp now
;
3772 struct DiskObject
*dob
= NULL
;
3773 struct Rectangle rect
;
3775 IPTR geticon_error
= 0;
3777 #if defined(DEBUG_ILC_FUNCS)
3778 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
3781 /*disk object (icon)*/
3782 if (message
->entry_dob
== NULL
)
3784 IPTR iconlistScreen
= _screen(obj
);
3785 D(bug("[IconList] %s: IconList Screen @ 0x%p)\n", __PRETTY_FUNCTION__
, iconlistScreen
));
3790 (iconlistScreen
) ? ICONGETA_Screen
: TAG_IGNORE
, iconlistScreen
,
3791 (iconlistScreen
) ? ICONGETA_RemapIcon
: TAG_IGNORE
, TRUE
,
3792 ICONGETA_FailIfUnavailable
, FALSE
,
3793 ICONGETA_GenerateImageMasks
, TRUE
,
3794 ICONA_ErrorCode
, &geticon_error
,
3800 D(bug("[IconList] %s: Fatal: Couldnt get DiskObject! (error code = 0x%p)\n", __PRETTY_FUNCTION__
, geticon_error
));
3807 dob
= message
->entry_dob
;
3810 D(bug("[IconList] %s: DiskObject @ 0x%p\n", __PRETTY_FUNCTION__
, dob
));
3812 if ((entry
= AllocPooled(data
->icld_Pool
, sizeof(struct IconEntry
))) == NULL
)
3814 D(bug("[IconList] %s: Failed to Allocate Entry Storage!\n", __PRETTY_FUNCTION__
));
3815 FreeDiskObject(dob
);
3818 memset(entry
, 0, sizeof(struct IconEntry
));
3819 entry
->ie_Flags
|= ICONENTRY_FLAG_NEEDSUPDATE
;
3820 entry
->ie_IconListEntry
.ile_IconEntry
= entry
;
3822 /* Allocate Text Buffers */
3824 if ((entry
->ie_TxtBuf_DATE
= AllocPooled(data
->icld_Pool
, LEN_DATSTRING
)) == NULL
)
3826 D(bug("[IconList] %s: Failed to Allocate Entry DATE Storage!\n", __PRETTY_FUNCTION__
));
3827 DoMethod(obj
, MUIM_IconList_DestroyEntry
, entry
);
3830 memset(entry
->ie_TxtBuf_DATE
, 0, LEN_DATSTRING
);
3832 if ((entry
->ie_TxtBuf_TIME
= AllocPooled(data
->icld_Pool
, LEN_DATSTRING
)) == NULL
)
3834 D(bug("[IconList] %s: Failed to Allocate Entry TIME string Storage!\n", __PRETTY_FUNCTION__
));
3835 DoMethod(obj
, MUIM_IconList_DestroyEntry
, entry
);
3838 memset(entry
->ie_TxtBuf_TIME
, 0, LEN_DATSTRING
);
3840 if ((entry
->ie_TxtBuf_SIZE
= AllocPooled(data
->icld_Pool
, 30)) == NULL
)
3842 D(bug("[IconList] %s: Failed to Allocate Entry SIZE string Storage!\n", __PRETTY_FUNCTION__
));
3843 DoMethod(obj
, MUIM_IconList_DestroyEntry
, entry
);
3846 memset(entry
->ie_TxtBuf_SIZE
, 0, 30);
3848 if ((entry
->ie_TxtBuf_PROT
= AllocPooled(data
->icld_Pool
, 8)) == NULL
)
3850 D(bug("[IconList] %s: Failed to Allocate Entry PROT Flag string Storage!\n", __PRETTY_FUNCTION__
));
3851 DoMethod(obj
, MUIM_IconList_DestroyEntry
, entry
);
3854 memset(entry
->ie_TxtBuf_PROT
, 0, 8);
3857 if ((entry
->ie_IconNode
.ln_Name
= AllocPooled(data
->icld_Pool
, strlen(message
->filename
) + 1)) == NULL
)
3859 D(bug("[IconList] %s: Failed to Allocate Entry filename string Storage!\n", __PRETTY_FUNCTION__
));
3860 DoMethod(obj
, MUIM_IconList_DestroyEntry
, entry
);
3864 /*alloc entry label*/
3865 if ((entry
->ie_IconListEntry
.label
= AllocPooled(data
->icld_Pool
, strlen(message
->label
) + 1)) == NULL
)
3867 D(bug("[IconList] %s: Failed to Allocate Entry label string Storage!\n", __PRETTY_FUNCTION__
));
3868 DoMethod(obj
, MUIM_IconList_DestroyEntry
, entry
);
3873 if(message
->fib
!= NULL
)
3875 if ((entry
->ie_FileInfoBlock
= AllocMem(sizeof(struct FileInfoBlock
), MEMF_CLEAR
)) != NULL
)
3877 CopyMem(message
->fib
, entry
->ie_FileInfoBlock
, sizeof(struct FileInfoBlock
));
3879 if (entry
->ie_FileInfoBlock
->fib_DirEntryType
> 0)
3881 strcpy(entry
->ie_TxtBuf_SIZE
, "Drawer");
3885 FmtSizeToString(entry
->ie_TxtBuf_SIZE
, entry
->ie_FileInfoBlock
->fib_Size
);
3888 dt
.dat_Stamp
= entry
->ie_FileInfoBlock
->fib_Date
;
3889 dt
.dat_Format
= FORMAT_DEF
;
3891 dt
.dat_StrDay
= NULL
;
3892 dt
.dat_StrDate
= entry
->ie_TxtBuf_DATE
;
3893 dt
.dat_StrTime
= entry
->ie_TxtBuf_TIME
;
3898 /*if modified today show time, otherwise just show date*/
3899 if (now
.ds_Days
== entry
->ie_FileInfoBlock
->fib_Date
.ds_Days
)
3900 entry
->ie_Flags
|= ICONENTRY_FLAG_TODAY
;
3902 entry
->ie_Flags
&= ~ICONENTRY_FLAG_TODAY
;
3904 sp
= entry
->ie_TxtBuf_PROT
;
3905 *sp
++ = (entry
->ie_FileInfoBlock
->fib_Protection
& FIBF_SCRIPT
) ? 's' : '-';
3906 *sp
++ = (entry
->ie_FileInfoBlock
->fib_Protection
& FIBF_PURE
) ? 'p' : '-';
3907 *sp
++ = (entry
->ie_FileInfoBlock
->fib_Protection
& FIBF_ARCHIVE
) ? 'a' : '-';
3908 *sp
++ = (entry
->ie_FileInfoBlock
->fib_Protection
& FIBF_READ
) ? '-' : 'r';
3909 *sp
++ = (entry
->ie_FileInfoBlock
->fib_Protection
& FIBF_WRITE
) ? '-' : 'w';
3910 *sp
++ = (entry
->ie_FileInfoBlock
->fib_Protection
& FIBF_EXECUTE
) ? '-' : 'e';
3911 *sp
++ = (entry
->ie_FileInfoBlock
->fib_Protection
& FIBF_DELETE
) ? '-' : 'd';
3914 entry
->ie_IconListEntry
.type
= entry
->ie_FileInfoBlock
->fib_DirEntryType
;
3919 entry
->ie_IconListEntry
.type
= ST_USERDIR
;
3922 /* Override type if specified during createntry */
3923 if (message
->type
!= 0)
3925 entry
->ie_IconListEntry
.type
= message
->type
;
3926 D(bug("[IconList] %s: Overide Entry Type. New Type = %x\n", __PRETTY_FUNCTION__
, entry
->ie_IconListEntry
.type
));
3930 D(bug("[IconList] %s: Entry Type = %x\n", __PRETTY_FUNCTION__
, entry
->ie_IconListEntry
.type
));
3933 strcpy(entry
->ie_IconNode
.ln_Name
, message
->filename
);
3934 strcpy(entry
->ie_IconListEntry
.label
, message
->label
);
3936 entry
->ie_IconListEntry
.udata
= NULL
;
3938 if (IconList__LabelFunc_CreateLabel(obj
, data
, entry
) != (IPTR
)NULL
)
3940 entry
->ie_DiskObj
= dob
;
3942 /* Use a geticonrectangle routine that gets textwidth! */
3943 IconList_GetIconAreaRectangle(obj
, data
, entry
, &rect
);
3948 DoMethod(obj
, MUIM_IconList_DestroyEntry
, entry
);
3953 ///IconList__MUIM_IconList_UpdateEntry()
3954 /**************************************************************************
3955 MUIM_IconList_UpdateEntry.
3956 Returns 0 on failure otherwise it returns the icons entry ..
3957 **************************************************************************/
3958 IPTR
IconList__MUIM_IconList_UpdateEntry(struct IClass
*CLASS
, Object
*obj
, struct MUIP_IconList_UpdateEntry
*message
)
3960 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
3962 struct DateStamp now
;
3965 struct DiskObject
*dob
= NULL
;
3966 struct Rectangle rect
;
3968 IPTR geticon_error
= 0;
3970 #if defined(DEBUG_ILC_FUNCS)
3971 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
3974 /* Update disk object (icon)*/
3975 /* if (message->entry_dob == NULL)
3977 IPTR iconlistScreen = _screen(obj);
3978 D(bug("[IconList] %s: IconList Screen @ 0x%p)\n", __PRETTY_FUNCTION__, iconlistScreen));
3983 (iconlistScreen) ? ICONGETA_Screen : TAG_IGNORE, iconlistScreen,
3984 (iconlistScreen) ? ICONGETA_RemapIcon : TAG_IGNORE, TRUE,
3985 ICONGETA_FailIfUnavailable, FALSE,
3986 ICONGETA_GenerateImageMasks, TRUE,
3987 ICONA_ErrorCode, &geticon_error,
3993 D(bug("[IconList] %s: Fatal: Couldnt get DiskObject! (error code = 0x%p)\n", __PRETTY_FUNCTION__, geticon_error));
4000 dob = message->entry_dob;
4003 D(bug("[IconList] %s: DiskObject @ 0x%p\n", __PRETTY_FUNCTION__, dob));
4006 /* Update filename */
4007 if (strcmp(message
->entry
->ie_IconNode
.ln_Name
, message
->filename
) != 0)
4009 message
->entry
->ie_Flags
|= ICONENTRY_FLAG_NEEDSUPDATE
;
4010 FreePooled(data
->icld_Pool
, message
->entry
->ie_IconNode
.ln_Name
, strlen(message
->entry
->ie_IconNode
.ln_Name
) + 1);
4011 if ((message
->entry
->ie_IconNode
.ln_Name
= AllocPooled(data
->icld_Pool
, strlen(message
->filename
) + 1)) == NULL
)
4013 D(bug("[IconList] %s: Failed to Allocate Entry filename string Storage!\n", __PRETTY_FUNCTION__
));
4014 DoMethod(obj
, MUIM_IconList_DestroyEntry
, message
->entry
);
4017 strcpy(message
->entry
->ie_IconNode
.ln_Name
, message
->filename
);
4020 /* Update entry label */
4021 if (strcmp(message
->entry
->ie_IconListEntry
.label
, message
->label
) != 0)
4023 message
->entry
->ie_Flags
|= ICONENTRY_FLAG_NEEDSUPDATE
;
4024 FreePooled(data
->icld_Pool
, message
->entry
->ie_IconListEntry
.label
, strlen(message
->entry
->ie_IconListEntry
.label
) + 1);
4025 if ((message
->entry
->ie_IconListEntry
.label
= AllocPooled(data
->icld_Pool
, strlen(message
->label
) + 1)) == NULL
)
4027 D(bug("[IconList] %s: Failed to Allocate Entry label string Storage!\n", __PRETTY_FUNCTION__
));
4028 DoMethod(obj
, MUIM_IconList_DestroyEntry
, message
->entry
);
4031 strcpy(message
->entry
->ie_IconListEntry
.label
, message
->label
);
4032 if (IconList__LabelFunc_CreateLabel(obj
, data
, message
->entry
) == (IPTR
)NULL
)
4034 D(bug("[IconList] %s: Failed to create label\n", __PRETTY_FUNCTION__
));
4035 DoMethod(obj
, MUIM_IconList_DestroyEntry
, message
->entry
);
4040 /* Update file info block */
4041 if(message
->fib
!= NULL
)
4043 if (!(message
->entry
->ie_FileInfoBlock
))
4045 if ((message
->entry
->ie_FileInfoBlock
= AllocMem(sizeof(struct FileInfoBlock
), MEMF_CLEAR
)) != NULL
)
4047 CopyMem(message
->fib
, message
->entry
->ie_FileInfoBlock
, sizeof(struct FileInfoBlock
));
4051 /* if (entry->ie_FileInfoBlock->fib_DirEntryType > 0)
4053 strcpy(entry->ie_TxtBuf_SIZE, "Drawer");
4057 FmtSizeToString(entry->ie_TxtBuf_SIZE, entry->ie_FileInfoBlock->fib_Size);
4060 dt.dat_Stamp = entry->ie_FileInfoBlock->fib_Date;
4061 dt.dat_Format = FORMAT_DEF;
4063 dt.dat_StrDay = NULL;
4064 dt.dat_StrDate = entry->ie_TxtBuf_DATE;
4065 dt.dat_StrTime = entry->ie_TxtBuf_TIME;
4070 //if modified today show time, otherwise just show date
4071 if (now.ds_Days == entry->ie_FileInfoBlock->fib_Date.ds_Days)
4072 entry->ie_Flags |= ICONENTRY_FLAG_TODAY;
4074 entry->ie_Flags &= ~ICONENTRY_FLAG_TODAY;
4076 sp = entry->ie_TxtBuf_PROT;
4077 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_SCRIPT) ? 's' : '-';
4078 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_PURE) ? 'p' : '-';
4079 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_ARCHIVE) ? 'a' : '-';
4080 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_READ) ? '-' : 'r';
4081 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_WRITE) ? '-' : 'w';
4082 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_EXECUTE) ? '-' : 'e';
4083 *sp++ = (entry->ie_FileInfoBlock->fib_Protection & FIBF_DELETE) ? '-' : 'd';
4086 entry->ie_IconListEntry.type = entry->ie_FileInfoBlock->fib_DirEntryType;
4091 if (message
->entry
->ie_FileInfoBlock
)
4092 FreeMem(message
->entry
->ie_FileInfoBlock
, sizeof(struct FileInfoBlock
));
4094 if (message
->entry
->ie_IconListEntry
.type
!= ST_USERDIR
)
4096 message
->entry
->ie_Flags
|= ICONENTRY_FLAG_NEEDSUPDATE
;
4097 message
->entry
->ie_IconListEntry
.type
= ST_USERDIR
;
4101 /* Override type if specified */
4102 if ((message
->type
!= 0) && (message
->entry
->ie_IconListEntry
.type
!= message
->type
))
4104 message
->entry
->ie_Flags
|= ICONENTRY_FLAG_NEEDSUPDATE
;
4105 message
->entry
->ie_IconListEntry
.type
= message
->type
;
4106 D(bug("[IconList] %s: Overide Entry Type. New Type = %x\n", __PRETTY_FUNCTION__
, message
->entry
->ie_IconListEntry
.type
));
4110 D(bug("[IconList] %s: Entry Type = %x\n", __PRETTY_FUNCTION__
, message
->entry
->ie_IconListEntry
.type
));
4113 IconList_GetIconAreaRectangle(obj
, data
, message
->entry
, &rect
);
4115 return (IPTR
)message
->entry
;
4120 static void DoWheelMove(struct IClass
*CLASS
, Object
*obj
, LONG wheelx
, LONG wheely
, UWORD qual
)
4122 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
4124 LONG newleft
= data
->icld_ViewX
,
4125 newtop
= data
->icld_ViewY
;
4127 /* Use horizontal scrolling if any of the following cases are true ...
4129 # vertical wheel is used but there's nothing to scroll
4130 (everything is visible already) ..
4132 # vertical wheel is used and one of the ALT keys is down. */
4134 if ((wheely
&& !wheelx
) &&
4135 ((data
->icld_AreaHeight
<= _mheight(obj
)) || (qual
& (IEQUALIFIER_LALT
| IEQUALIFIER_RALT
))))
4137 wheelx
= wheely
; wheely
= 0;
4140 if (qual
& (IEQUALIFIER_CONTROL
))
4142 if (wheelx
< 0) newleft
= 0;
4143 if (wheelx
> 0) newleft
= data
->icld_AreaWidth
;
4144 if (wheely
< 0) newtop
= 0;
4145 if (wheely
> 0) newtop
= data
->icld_AreaHeight
;
4147 else if (qual
& (IEQUALIFIER_LSHIFT
| IEQUALIFIER_RSHIFT
))
4149 newleft
+= (wheelx
* _mwidth(obj
));
4150 newtop
+= (wheely
* _mheight(obj
));
4154 newleft
+= wheelx
* 30;
4155 newtop
+= wheely
* 30;
4158 if (newleft
+ _mwidth(obj
) > data
->icld_AreaWidth
)
4159 newleft
= data
->icld_AreaWidth
- _mwidth(obj
);
4163 if (newtop
+ _mheight(obj
) > data
->icld_AreaHeight
)
4164 newtop
= data
->icld_AreaHeight
- _mheight(obj
);
4168 if ((newleft
!= data
->icld_ViewX
) || (newtop
!= data
->icld_ViewY
))
4170 SetAttrs(obj
, MUIA_Virtgroup_Left
, newleft
,
4171 MUIA_Virtgroup_Top
, newtop
,
4177 ///MUIM_HandleEvent()
4178 /**************************************************************************
4180 **************************************************************************/
4181 IPTR
IconList__MUIM_HandleEvent(struct IClass
*CLASS
, Object
*obj
, struct MUIP_HandleEvent
*message
)
4183 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
4185 #if defined(DEBUG_ILC_FUNCS)
4186 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
4191 LONG mx
= message
->imsg
->MouseX
- _mleft(obj
);
4192 LONG my
= message
->imsg
->MouseY
- _mtop(obj
);
4197 switch (message
->imsg
->Class
)
4200 bug("[IconList] %s: IDCMP_NEWSIZE\n", __PRETTY_FUNCTION__
);
4205 #if defined(DEBUG_ILC_EVENTS)
4206 D(bug("[IconList] %s: IDCMP_RAWKEY\n", __PRETTY_FUNCTION__
));
4208 BOOL rawkey_handled
= FALSE
;
4210 switch(message
->imsg
->Code
)
4212 case RAWKEY_NM_WHEEL_UP
:
4214 rawkey_handled
= TRUE
;
4217 case RAWKEY_NM_WHEEL_DOWN
:
4219 rawkey_handled
= TRUE
;
4222 case RAWKEY_NM_WHEEL_LEFT
:
4224 rawkey_handled
= TRUE
;
4227 case RAWKEY_NM_WHEEL_RIGHT
:
4229 rawkey_handled
= TRUE
;
4235 #if defined(DEBUG_ILC_KEYEVENTS)
4236 D(bug("[IconList] %s: Processing mouse wheel event\n", __PRETTY_FUNCTION__
));
4238 if (_isinobject(message
->imsg
->MouseX
, message
->imsg
->MouseY
) &&
4241 DoWheelMove(CLASS
, obj
, wheelx
, wheely
, message
->imsg
->Qualifier
);
4244 else if (!(message
->imsg
->Code
& IECODE_UP_PREFIX
))
4246 LONG new_ViewY
= data
->icld_ViewY
;
4247 struct IconEntry
*start_entry
= NULL
, *active_entry
= NULL
, *entry_next
= NULL
;
4248 IPTR start_X
= 0, start_Y
= 0, active_X
= 0, active_Y
= 0, next_X
= 0, next_Y
= 0;
4251 #if defined(DEBUG_ILC_KEYEVENTS)
4252 D(bug("[IconList] %s: Processing key up event\n", __PRETTY_FUNCTION__
));
4255 switch(message
->imsg
->Code
)
4258 rawkey_handled
= TRUE
;
4260 #if defined(DEBUG_ILC_KEYEVENTS)
4261 D(bug("[IconList] %s: RAWKEY_RETURN\n", __PRETTY_FUNCTION__
));
4264 if (data
->icld_FocusIcon
) active_entry
= data
->icld_FocusIcon
;
4265 else if (data
->icld_SelectionLastClicked
) active_entry
= data
->icld_SelectionLastClicked
;
4269 if (!(active_entry
->ie_Flags
& ICONENTRY_FLAG_SELECTED
))
4271 active_entry
->ie_Flags
|= ICONENTRY_FLAG_SELECTED
;
4272 AddTail(&data
->icld_SelectionList
, &active_entry
->ie_SelectionNode
);
4273 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
4274 data
->update_entry
= active_entry
;
4275 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
4277 data
->icld_SelectionLastClicked
= active_entry
;
4278 data
->icld_FocusIcon
= active_entry
;
4280 SET(obj
, MUIA_IconList_DoubleClick
, TRUE
);
4285 rawkey_handled
= TRUE
;
4287 #if defined(DEBUG_ILC_KEYEVENTS)
4288 D(bug("[IconList] %s: RAWKEY_SPACE\n", __PRETTY_FUNCTION__
));
4291 if (data
->icld_FocusIcon
) active_entry
= data
->icld_FocusIcon
;
4292 else if (data
->icld_SelectionLastClicked
) active_entry
= data
->icld_SelectionLastClicked
;
4294 if (!(message
->imsg
->Qualifier
& IEQUALIFIER_LSHIFT
) && ((data
->icld_SelectionLastClicked
)||(data
->icld_SelectionLastClicked
!= active_entry
)))
4296 #if defined(DEBUG_ILC_KEYEVENTS)
4297 D(bug("[IconList] %s: SPACE: Clearing selected icons ..\n", __PRETTY_FUNCTION__
));
4299 DoMethod(obj
, MUIM_IconList_UnselectAll
);
4304 if (!(active_entry
->ie_Flags
& ICONENTRY_FLAG_SELECTED
))
4306 AddTail(&data
->icld_SelectionList
, &active_entry
->ie_SelectionNode
);
4307 active_entry
->ie_Flags
|= ICONENTRY_FLAG_SELECTED
;
4308 data
->icld_SelectionLastClicked
= active_entry
;
4312 Remove(&active_entry
->ie_SelectionNode
);
4313 active_entry
->ie_Flags
&= ~ICONENTRY_FLAG_SELECTED
;
4316 data
->icld_FocusIcon
= active_entry
;
4318 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
4319 data
->update_entry
= active_entry
;
4320 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
4325 rawkey_handled
= TRUE
;
4327 #if defined(DEBUG_ILC_KEYEVENTS)
4328 D(bug("[IconList] %s: RAWKEY_PAGEUP\n", __PRETTY_FUNCTION__
));
4331 if (data
->icld_AreaHeight
> data
->icld_ViewHeight
)
4333 new_ViewY
-= data
->icld_ViewHeight
;
4338 if (new_ViewY
!= data
->icld_ViewY
)
4340 SET(obj
, MUIA_Virtgroup_Top
, new_ViewY
);
4344 case RAWKEY_PAGEDOWN
:
4345 rawkey_handled
= TRUE
;
4347 #if defined(DEBUG_ILC_KEYEVENTS)
4348 D(bug("[IconList] %s: RAWKEY_PAGEDOWN\n", __PRETTY_FUNCTION__
));
4351 if (data
->icld_AreaHeight
> data
->icld_ViewHeight
)
4353 new_ViewY
+= data
->icld_ViewHeight
;
4354 if (new_ViewY
> (data
->icld_AreaHeight
- data
->icld_ViewHeight
))
4355 new_ViewY
= data
->icld_AreaHeight
- data
->icld_ViewHeight
;
4358 if (new_ViewY
!= data
->icld_ViewY
)
4360 SET(obj
, MUIA_Virtgroup_Top
, new_ViewY
);
4365 rawkey_handled
= TRUE
;
4367 #if defined(DEBUG_ILC_KEYEVENTS)
4368 D(bug("[IconList] %s: RAWKEY_UP\n", __PRETTY_FUNCTION__
));
4371 if (data
->icld_FocusIcon
)
4373 start_entry
= data
->icld_FocusIcon
;
4374 #if defined(DEBUG_ILC_KEYEVENTS)
4375 D(bug("[IconList] %s: UP: Clearing existing focused entry @ 0x%p\n", __PRETTY_FUNCTION__
, start_entry
));
4378 start_entry
->ie_Flags
&= ~ICONENTRY_FLAG_FOCUS
;
4379 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
4380 data
->update_entry
= start_entry
;
4381 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
4383 start_X
= start_entry
->ie_IconX
;
4384 start_Y
= start_entry
->ie_IconY
;
4385 #if defined(DEBUG_ILC_KEYEVENTS)
4386 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
));
4388 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
4390 if (start_entry
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
4392 start_X
= start_X
- ((data
->icld_IconAreaLargestWidth
- start_entry
->ie_AreaWidth
)/2);
4393 #if defined(DEBUG_ILC_KEYEVENTS)
4394 D(bug("[IconList] %s: UP: adjusted start_X for grid = %d\n", __PRETTY_FUNCTION__
, start_X
));
4399 if ((active_entry
= Node_PreviousVisible(start_entry
)) && !(data
->icld_DisplayFlags
& ICONLIST_DISP_VERTICAL
))
4401 //Check if we are at the edge of the entry area ..
4402 #if defined(DEBUG_ILC_KEYEVENTS)
4403 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
));
4405 active_Y
= active_entry
->ie_IconY
;
4407 if (active_Y
== start_Y
)
4410 #if defined(DEBUG_ILC_KEYEVENTS)
4411 D(bug("[IconList] %s: UP: active_entry is on our row (not at the edge)\n", __PRETTY_FUNCTION__
));
4413 entry_next
= active_entry
;
4414 next_X
= entry_next
->ie_IconX
;
4415 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
4417 if (entry_next
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
4418 next_X
= next_X
- ((data
->icld_IconAreaLargestWidth
- entry_next
->ie_AreaWidth
)/2);
4422 #if defined(DEBUG_ILC_KEYEVENTS)
4423 D(bug("[IconList] %s: UP: using start_X %d, start_Y %d\n", __PRETTY_FUNCTION__
, start_X
, start_Y
));
4427 if (!(message
->imsg
->Qualifier
& IEQUALIFIER_LSHIFT
) && ((data
->icld_SelectionLastClicked
)&&(data
->icld_SelectionLastClicked
!= active_entry
)))
4429 #if defined(DEBUG_ILC_KEYEVENTS)
4430 D(bug("[IconList] %s: UP: Clearing selected icons ..\n", __PRETTY_FUNCTION__
));
4432 DoMethod(obj
, MUIM_IconList_UnselectAll
);
4435 #if defined(DEBUG_ILC_KEYEVENTS)
4436 D(bug("[IconList] %s: UP: active = 0x%p, next = 0x%p\n", __PRETTY_FUNCTION__
, active_entry
, entry_next
));
4438 if (!(active_entry
))
4440 // If nothing is selected we will use the last visible entry ..
4441 active_entry
= Node_LastVisible(&data
->icld_IconList
);
4442 start_X
= active_entry
->ie_IconX
;
4443 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
4445 if (active_entry
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
4446 start_X
= start_X
- ((data
->icld_IconAreaLargestWidth
- active_entry
->ie_AreaWidth
)/2);
4448 start_Y
= active_entry
->ie_IconY
;
4451 while (active_entry
!= NULL
)
4453 #if defined(DEBUG_ILC_KEYEVENTS)
4454 D(bug("[IconList] %s: UP: Checking active @ 0x%p\n", __PRETTY_FUNCTION__
, active_entry
));
4456 if (data
->icld_DisplayFlags
& ICONLIST_DISP_VERTICAL
)
4458 // Return the first visible since the list flow direction matches
4459 // our cursor direction
4460 if (active_entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
4465 active_X
= active_entry
->ie_IconX
;
4467 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
4469 if (active_entry
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
4470 x_diff
= ((data
->icld_IconAreaLargestWidth
- active_entry
->ie_AreaWidth
)/2);
4472 active_Y
= active_entry
->ie_IconY
;
4478 if ((active_entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
) &&
4479 (active_Y
< start_Y
) &&
4480 (((active_X
- x_diff
) >= start_X
) &&
4481 ((active_X
- x_diff
) <= (start_X
+ start_entry
->ie_AreaWidth
+ (x_diff
*2)))))
4483 #if defined(DEBUG_ILC_KEYEVENTS)
4484 D(bug("[IconList] %s: UP: (A) entry 0x%p matches\n", __PRETTY_FUNCTION__
, active_entry
));
4488 else if (active_entry
== (struct IconEntry
*)GetHead(&data
->icld_IconList
))
4490 #if defined(DEBUG_ILC_KEYEVENTS)
4491 D(bug("[IconList] %s: UP: (A) reached list start .. restarting from the end ..\n", __PRETTY_FUNCTION__
));
4495 if ((entry_next
= Node_PreviousVisible(entry_next
)))
4497 if (entry_next
->ie_IconX
> start_X
)
4501 next_X
= entry_next
->ie_IconX
;
4502 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
4504 if (entry_next
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
4505 next_X
= next_X
- ((data
->icld_IconAreaLargestWidth
- entry_next
->ie_AreaWidth
)/2);
4510 #if defined(DEBUG_ILC_KEYEVENTS)
4511 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
));
4513 active_entry
= Node_LastVisible(&data
->icld_IconList
);
4518 if ((active_entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
) &&
4519 (active_Y
< start_Y
) &&
4520 ((active_X
+ x_diff
) < (start_X
+ start_entry
->ie_AreaWidth
+ x_diff
)))
4522 #if defined(DEBUG_ILC_KEYEVENTS)
4523 D(bug("[IconList] %s: UP: (B) entry 0x%p matches\n", __PRETTY_FUNCTION__
, active_entry
));
4531 if (active_entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
4533 #if defined(DEBUG_ILC_KEYEVENTS)
4534 D(bug("[IconList] %s: UP: (C) entry 0x%p matches\n", __PRETTY_FUNCTION__
, active_entry
));
4540 active_entry
= (struct IconEntry
*)(((struct Node
*)active_entry
)->ln_Pred
);
4543 if (!(active_entry
))
4545 #if defined(DEBUG_ILC_KEYEVENTS)
4546 D(bug("[IconList] %s: UP: No Next UP Node - Getting Last visible entry ..\n", __PRETTY_FUNCTION__
));
4548 /* We didnt find a "next UP" entry so just use the last visible */
4549 active_entry
= Node_LastVisible(&data
->icld_IconList
);
4554 if (!(active_entry
->ie_Flags
& ICONENTRY_FLAG_FOCUS
))
4556 active_entry
->ie_Flags
|= ICONENTRY_FLAG_FOCUS
;
4557 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
4558 data
->update_entry
= active_entry
;
4559 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
4562 data
->icld_FocusIcon
= active_entry
;
4566 rawkey_handled
= TRUE
;
4568 #if defined(DEBUG_ILC_KEYEVENTS)
4569 D(bug("[IconList] %s: RAWKEY_DOWN\n", __PRETTY_FUNCTION__
));
4571 if (data
->icld_FocusIcon
)
4573 start_entry
= data
->icld_FocusIcon
;
4574 #if defined(DEBUG_ILC_KEYEVENTS)
4575 D(bug("[IconList] %s: DOWN: Clearing existing focused entry @ 0x%p\n", __PRETTY_FUNCTION__
, start_entry
));
4578 start_entry
->ie_Flags
&= ~ICONENTRY_FLAG_FOCUS
;
4579 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
4580 data
->update_entry
= start_entry
;
4581 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
4583 start_X
= start_entry
->ie_IconX
;
4584 start_Y
= start_entry
->ie_IconY
;
4585 #if defined(DEBUG_ILC_KEYEVENTS)
4586 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
));
4588 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
4590 if (start_entry
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
4592 start_X
= start_X
- ((data
->icld_IconAreaLargestWidth
- start_entry
->ie_AreaWidth
)/2);
4593 #if defined(DEBUG_ILC_KEYEVENTS)
4594 D(bug("[IconList] %s: DOWN: adjusted start_X for grid = %d\n", __PRETTY_FUNCTION__
, start_X
));
4599 if ((active_entry
= Node_NextVisible(start_entry
)) &&
4600 (!(data
->icld_DisplayFlags
& ICONLIST_DISP_VERTICAL
)))
4602 #if defined(DEBUG_ILC_KEYEVENTS)
4603 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
));
4605 active_Y
= active_entry
->ie_IconY
;
4607 if (active_Y
== start_Y
)
4610 #if defined(DEBUG_ILC_KEYEVENTS)
4611 D(bug("[IconList] %s: DOWN: active_entry is on our row (not at the edge)\n", __PRETTY_FUNCTION__
));
4613 entry_next
= active_entry
;
4614 next_X
= entry_next
->ie_IconX
;
4615 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
4617 if (entry_next
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
4618 next_X
= next_X
- ((data
->icld_IconAreaLargestWidth
- entry_next
->ie_AreaWidth
)/2);
4622 #if defined(DEBUG_ILC_KEYEVENTS)
4623 D(bug("[IconList] %s: DOWN: using start_X %d, start_Y %d\n", __PRETTY_FUNCTION__
, start_X
, start_Y
));
4627 if (!(message
->imsg
->Qualifier
& IEQUALIFIER_LSHIFT
) && ((data
->icld_SelectionLastClicked
)&&(data
->icld_SelectionLastClicked
!= active_entry
)))
4629 #if defined(DEBUG_ILC_KEYEVENTS)
4630 D(bug("[IconList] %s: DOWN: Clearing selected icons ..\n", __PRETTY_FUNCTION__
));
4632 DoMethod(obj
, MUIM_IconList_UnselectAll
);
4635 #if defined(DEBUG_ILC_KEYEVENTS)
4636 D(bug("[IconList] %s: DOWN: active = 0x%p, next = 0x%p\n", __PRETTY_FUNCTION__
, active_entry
, entry_next
));
4638 if (!(active_entry
))
4640 // If nothing is selected we will use the First visible entry ..
4641 active_entry
= Node_FirstVisible(&data
->icld_IconList
);
4642 start_X
= active_entry
->ie_IconX
;
4643 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
4645 if (active_entry
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
4646 start_X
= start_X
- ((data
->icld_IconAreaLargestWidth
- active_entry
->ie_AreaWidth
)/2);
4648 start_Y
= active_entry
->ie_IconY
;
4651 while (active_entry
!= NULL
)
4653 #if defined(DEBUG_ILC_KEYEVENTS)
4654 D(bug("[IconList] %s: DOWN: Checking active @ 0x%p\n", __PRETTY_FUNCTION__
, active_entry
));
4656 if (data
->icld_DisplayFlags
& ICONLIST_DISP_VERTICAL
)
4658 if (active_entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
4663 active_X
= active_entry
->ie_IconX
;
4665 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
4667 if (active_entry
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
4668 x_diff
= ((data
->icld_IconAreaLargestWidth
- active_entry
->ie_AreaWidth
)/2);
4670 active_Y
= active_entry
->ie_IconY
;
4676 if ((active_entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
) &&
4677 (active_Y
> start_Y
) &&
4678 (((active_X
- x_diff
) >= start_X
) &&
4679 ((active_X
- x_diff
) <= (start_X
+ start_entry
->ie_AreaWidth
+ (x_diff
*2)))))
4681 #if defined(DEBUG_ILC_KEYEVENTS)
4682 D(bug("[IconList] %s: DOWN: (A) entry 0x%p matches\n", __PRETTY_FUNCTION__
, active_entry
));
4686 else if (active_entry
== (struct IconEntry
*)GetTail(&data
->icld_IconList
))
4688 #if defined(DEBUG_ILC_KEYEVENTS)
4689 D(bug("[IconList] %s: DOWN: (A) reached list end .. starting at the beginng ..\n", __PRETTY_FUNCTION__
));
4691 start_X
= entry_next
->ie_IconX
;
4692 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
4694 if (entry_next
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
4695 start_X
= start_X
- ((data
->icld_IconAreaLargestWidth
- entry_next
->ie_AreaWidth
)/2);
4698 if ((entry_next
= (struct IconEntry
*)Node_NextVisible(entry_next
)))
4700 if (entry_next
->ie_IconX
< start_X
)
4704 next_X
= entry_next
->ie_IconX
;
4705 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
4707 if (entry_next
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
4708 next_X
= next_X
+ ((data
->icld_IconAreaLargestWidth
- entry_next
->ie_AreaWidth
)/2);
4713 #if defined(DEBUG_ILC_KEYEVENTS)
4714 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
));
4716 active_entry
= Node_FirstVisible(&data
->icld_IconList
);
4721 if ((active_entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
) &&
4722 (active_Y
> start_Y
) &&
4723 (active_X
> start_X
- 1))
4725 #if defined(DEBUG_ILC_KEYEVENTS)
4726 D(bug("[IconList] %s: DOWN: (B) entry 0x%p matches\n", __PRETTY_FUNCTION__
, active_entry
));
4734 if (active_entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
4736 #if defined(DEBUG_ILC_KEYEVENTS)
4737 D(bug("[IconList] %s: DOWN: (C) entry 0x%p matches\n", __PRETTY_FUNCTION__
, active_entry
));
4743 active_entry
= (struct IconEntry
*)GetSucc(&active_entry
->ie_IconNode
);
4746 if (!(active_entry
))
4748 #if defined(DEBUG_ILC_KEYEVENTS)
4749 D(bug("[IconList] %s: DOWN: No Next DOWN Node - Getting first visable entry ..\n", __PRETTY_FUNCTION__
));
4751 /* We didnt find a "next DOWN" entry so just use the first visible */
4752 active_entry
= Node_FirstVisible(&data
->icld_IconList
);
4757 if (!(active_entry
->ie_Flags
& ICONENTRY_FLAG_FOCUS
))
4759 active_entry
->ie_Flags
|= ICONENTRY_FLAG_FOCUS
;
4760 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
4761 data
->update_entry
= active_entry
;
4762 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
4765 data
->icld_FocusIcon
= active_entry
;
4769 rawkey_handled
= TRUE
;
4771 #if defined(DEBUG_ILC_KEYEVENTS)
4772 D(bug("[IconList] %s: RAWKEY_LEFT\n", __PRETTY_FUNCTION__
));
4774 if (data
->icld_FocusIcon
)
4776 start_entry
= data
->icld_FocusIcon
;
4777 #if defined(DEBUG_ILC_KEYEVENTS)
4778 D(bug("[IconList] %s: LEFT: Clearing existing focused entry @ 0x%p\n", __PRETTY_FUNCTION__
, start_entry
));
4781 start_entry
->ie_Flags
&= ~ICONENTRY_FLAG_FOCUS
;
4782 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
4783 data
->update_entry
= start_entry
;
4784 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
4786 start_X
= start_entry
->ie_IconX
;
4787 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
4789 if (start_entry
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
4790 start_X
= start_X
- ((data
->icld_IconAreaLargestWidth
- start_entry
->ie_AreaWidth
)/2);
4792 start_Y
= start_entry
->ie_IconY
;
4794 #if defined(DEBUG_ILC_KEYEVENTS)
4795 D(bug("[IconList] %s: LEFT: start_X %d, start_Y %d\n", __PRETTY_FUNCTION__
, start_X
, start_Y
));
4798 if (!(active_entry
= Node_NextVisible(start_entry
)) && (!(data
->icld_DisplayFlags
& ICONLIST_DISP_VERTICAL
)))
4800 active_entry
= (struct IconEntry
*)GetHead(&data
->icld_IconList
);
4801 #if defined(DEBUG_ILC_KEYEVENTS)
4802 D(bug("[IconList] %s: LEFT: Start at the beginning (Active @ 0x%p) using entry X + Width\n", __PRETTY_FUNCTION__
, active_entry
));
4804 start_X
= start_X
+ start_entry
->ie_AreaWidth
;
4805 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
4807 if (start_entry
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
4808 start_X
= start_X
+ ((data
->icld_IconAreaLargestWidth
- start_entry
->ie_AreaWidth
)/2);
4814 else if (active_entry
&& (!(data
->icld_DisplayFlags
& ICONLIST_DISP_VERTICAL
)))
4816 #if defined(DEBUG_ILC_KEYEVENTS)
4817 D(bug("[IconList] %s: LEFT: Active @ 0x%p, X %d\n", __PRETTY_FUNCTION__
, active_entry
, active_entry
->ie_IconX
));
4819 if ((entry_next
= Node_NextVisible(start_entry
)))
4821 #if defined(DEBUG_ILC_KEYEVENTS)
4822 D(bug("[IconList] %s: LEFT: Next @ 0x%p, X %d\n", __PRETTY_FUNCTION__
, entry_next
, entry_next
->ie_IconX
));
4825 if (entry_next
->ie_IconX
< start_X
)
4829 next_X
= entry_next
->ie_IconX
;
4830 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
4832 if (entry_next
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
4833 next_X
= next_X
- ((data
->icld_IconAreaLargestWidth
- entry_next
->ie_AreaWidth
)/2);
4838 #if defined(DEBUG_ILC_KEYEVENTS)
4839 D(bug("[IconList] %s: LEFT: using start_X %d, start_Y %d\n", __PRETTY_FUNCTION__
, start_X
, start_Y
));
4843 if (!(message
->imsg
->Qualifier
& IEQUALIFIER_LSHIFT
) && ((data
->icld_SelectionLastClicked
)&&(data
->icld_SelectionLastClicked
!= active_entry
)))
4845 #if defined(DEBUG_ILC_KEYEVENTS)
4846 D(bug("[IconList] %s: LEFT: Clearing selected icons ..\n", __PRETTY_FUNCTION__
));
4848 DoMethod(obj
, MUIM_IconList_UnselectAll
);
4851 #if defined(DEBUG_ILC_KEYEVENTS)
4852 D(bug("[IconList] %s: LEFT: active = 0x%p, next = 0x%p\n", __PRETTY_FUNCTION__
, active_entry
, entry_next
));
4855 if (!(active_entry
))
4857 active_entry
= (struct IconEntry
*)GetHead(&data
->icld_IconList
);
4860 while (active_entry
!= NULL
)
4862 #if defined(DEBUG_ILC_KEYEVENTS)
4863 D(bug("[IconList] %s: LEFT: Checking active @ 0x%p\n", __PRETTY_FUNCTION__
, active_entry
));
4865 if (data
->icld_DisplayFlags
& ICONLIST_DISP_VERTICAL
)
4867 if (active_entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
4872 LONG active_entry_X
= active_entry
->ie_IconX
;
4873 LONG active_entry_Y
;
4874 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
4876 if (active_entry
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
4877 active_entry_X
= active_entry_X
- ((data
->icld_IconAreaLargestWidth
- active_entry
->ie_AreaWidth
)/2);
4879 active_entry_Y
= active_entry
->ie_IconY
;
4885 if ((active_entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
) &&
4886 (active_entry_Y
> start_Y
) &&
4887 ((active_entry_X
> start_X
- 1) &&
4888 (active_entry_X
< next_X
)))
4890 #if defined(DEBUG_ILC_KEYEVENTS)
4891 D(bug("[IconList] %s: LEFT: (A) entry 0x%p matches\n", __PRETTY_FUNCTION__
, active_entry
));
4895 else if (active_entry
== (struct IconEntry
*)GetTail(&data
->icld_IconList
))
4897 #if defined(DEBUG_ILC_KEYEVENTS)
4898 D(bug("[IconList] %s: LEFT: (A) reached list end .. starting at the beginng ..\n", __PRETTY_FUNCTION__
));
4900 start_X
= entry_next
->ie_IconX
;
4901 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
4903 if (entry_next
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
4904 start_X
= start_X
- ((data
->icld_IconAreaLargestWidth
- entry_next
->ie_AreaWidth
)/2);
4907 if ((entry_next
= Node_NextVisible(entry_next
)))
4909 if (entry_next
->ie_IconX
< start_X
)
4913 next_X
= entry_next
->ie_IconX
;
4914 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
4916 if (entry_next
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
4917 next_X
= next_X
+ ((data
->icld_IconAreaLargestWidth
- entry_next
->ie_AreaWidth
)/2);
4922 #if defined(DEBUG_ILC_KEYEVENTS)
4923 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
));
4925 active_entry
= (struct IconEntry
*)GetHead(&data
->icld_IconList
);
4930 if ((active_entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
) &&
4931 (active_entry_Y
> start_Y
) &&
4932 (active_entry_X
> start_X
- 1))
4934 #if defined(DEBUG_ILC_KEYEVENTS)
4935 D(bug("[IconList] %s: LEFT: (B) entry 0x%p matches\n", __PRETTY_FUNCTION__
, active_entry
));
4943 if (active_entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
4945 #if defined(DEBUG_ILC_KEYEVENTS)
4946 D(bug("[IconList] %s: LEFT: (C) entry 0x%p matches\n", __PRETTY_FUNCTION__
, active_entry
));
4952 active_entry
= (struct IconEntry
*)GetSucc(&active_entry
->ie_IconNode
);
4955 if (!(active_entry
))
4957 #if defined(DEBUG_ILC_KEYEVENTS)
4958 D(bug("[IconList] %s: LEFT: No Next LEFT Node - Getting first visable entry ..\n", __PRETTY_FUNCTION__
));
4960 /* We didnt find a "next LEFT" entry so just use the last visible */
4961 active_entry
= (struct IconEntry
*)GetHead(&data
->icld_IconList
);
4962 while ((active_entry
!= NULL
) &&(!(active_entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)))
4964 active_entry
= (struct IconEntry
*)GetSucc(&active_entry
->ie_IconNode
);
4970 if (!(active_entry
->ie_Flags
& ICONENTRY_FLAG_FOCUS
))
4972 active_entry
->ie_Flags
|= ICONENTRY_FLAG_FOCUS
;
4973 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
4974 data
->update_entry
= active_entry
;
4975 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
4978 data
->icld_FocusIcon
= active_entry
;
4982 rawkey_handled
= TRUE
;
4984 #if defined(DEBUG_ILC_KEYEVENTS)
4985 D(bug("[IconList] %s: RAWKEY_RIGHT\n", __PRETTY_FUNCTION__
));
4988 if (data
->icld_FocusIcon
)
4990 start_entry
= data
->icld_FocusIcon
;
4991 #if defined(DEBUG_ILC_KEYEVENTS)
4992 D(bug("[IconList] %s: RIGHT: Clearing existing focused entry @ 0x%p\n", __PRETTY_FUNCTION__
, start_entry
));
4994 start_entry
->ie_Flags
&= ~ICONENTRY_FLAG_FOCUS
;
4995 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
4996 data
->update_entry
= start_entry
;
4997 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
4999 start_X
= start_entry
->ie_IconX
;
5000 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
5002 if (start_entry
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
5003 start_X
= start_X
- ((data
->icld_IconAreaLargestWidth
- start_entry
->ie_AreaWidth
)/2);
5005 start_Y
= start_entry
->ie_IconY
;
5007 #if defined(DEBUG_ILC_KEYEVENTS)
5008 D(bug("[IconList] %s: RIGHT: start_X %d, start_Y %d\n", __PRETTY_FUNCTION__
, start_X
, start_Y
));
5010 if (!(active_entry
= Node_NextVisible(start_entry
)) && (!(data
->icld_DisplayFlags
& ICONLIST_DISP_VERTICAL
)))
5012 active_entry
= (struct IconEntry
*)GetHead(&data
->icld_IconList
);
5013 #if defined(DEBUG_ILC_KEYEVENTS)
5014 D(bug("[IconList] %s: RIGHT: Start at the beginning (Active @ 0x%p) using entry X + Width\n", __PRETTY_FUNCTION__
, active_entry
));
5017 start_Y
= start_Y
+ start_entry
->ie_AreaHeight
;
5020 else if (active_entry
&& (data
->icld_DisplayFlags
& ICONLIST_DISP_VERTICAL
))
5022 #if defined(DEBUG_ILC_KEYEVENTS)
5023 D(bug("[IconList] %s: RIGHT: Active @ 0x%p, X %d\n", __PRETTY_FUNCTION__
, active_entry
, active_entry
->ie_IconX
));
5025 if ((entry_next
= Node_NextVisible(start_entry
)))
5027 #if defined(DEBUG_ILC_KEYEVENTS)
5028 D(bug("[IconList] %s: RIGHT: Next @ 0x%p, X %d\n", __PRETTY_FUNCTION__
, entry_next
, entry_next
->ie_IconX
));
5031 if (entry_next
->ie_IconY
< start_Y
)
5034 next_Y
= entry_next
->ie_IconY
;
5037 #if defined(DEBUG_ILC_KEYEVENTS)
5038 D(bug("[IconList] %s: RIGHT: using start_X %d, start_Y %d\n", __PRETTY_FUNCTION__
, start_X
, start_Y
));
5042 if (!(message
->imsg
->Qualifier
& IEQUALIFIER_LSHIFT
) && ((data
->icld_SelectionLastClicked
)&&(data
->icld_SelectionLastClicked
!= active_entry
)))
5044 #if defined(DEBUG_ILC_KEYEVENTS)
5045 D(bug("[IconList] %s: RIGHT: Clearing selected icons ..\n", __PRETTY_FUNCTION__
));
5047 DoMethod(obj
, MUIM_IconList_UnselectAll
);
5050 #if defined(DEBUG_ILC_KEYEVENTS)
5051 D(bug("[IconList] %s: RIGHT: active = 0x%p, next = 0x%p\n", __PRETTY_FUNCTION__
, active_entry
, entry_next
));
5054 if (!(active_entry
))
5056 active_entry
= (struct IconEntry
*)GetHead(&data
->icld_IconList
);
5059 while (active_entry
!= NULL
)
5061 #if defined(DEBUG_ILC_KEYEVENTS)
5062 D(bug("[IconList] %s: RIGHT: Checking active @ 0x%p\n", __PRETTY_FUNCTION__
, active_entry
));
5064 if (!(data
->icld_DisplayFlags
& ICONLIST_DISP_VERTICAL
))
5066 if (active_entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
5071 LONG active_entry_X
= active_entry
->ie_IconX
;
5072 LONG active_entry_Y
;
5073 if (data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
)
5075 if (active_entry
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
)
5076 active_entry_X
= active_entry_X
- ((data
->icld_IconAreaLargestWidth
- active_entry
->ie_AreaWidth
)/2);
5078 active_entry_Y
= active_entry
->ie_IconY
;
5084 if ((active_entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
) &&
5085 (active_entry_X
> start_X
) &&
5086 ((active_entry_Y
> start_Y
- 1) &&
5087 (active_entry_Y
< next_Y
)))
5089 #if defined(DEBUG_ILC_KEYEVENTS)
5090 D(bug("[IconList] %s: RIGHT: (A) entry 0x%p matches\n", __PRETTY_FUNCTION__
, active_entry
));
5094 else if (active_entry
== (struct IconEntry
*)GetTail(&data
->icld_IconList
))
5096 #if defined(DEBUG_ILC_KEYEVENTS)
5097 D(bug("[IconList] %s: RIGHT: (A) reached list end .. starting at the beginng ..\n", __PRETTY_FUNCTION__
));
5099 start_Y
= entry_next
->ie_IconY
;
5101 if ((entry_next
= Node_NextVisible(entry_next
)))
5103 if (entry_next
->ie_IconY
< start_Y
)
5107 next_Y
= entry_next
->ie_IconY
;
5111 #if defined(DEBUG_ILC_KEYEVENTS)
5112 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
));
5114 active_entry
= (struct IconEntry
*)GetHead(&data
->icld_IconList
);
5119 if ((active_entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
) &&
5120 (active_entry_X
> start_X
) &&
5121 (active_entry_Y
> start_Y
- 1))
5123 #if defined(DEBUG_ILC_KEYEVENTS)
5124 D(bug("[IconList] %s: RIGHT: (B) entry 0x%p matches\n", __PRETTY_FUNCTION__
, active_entry
));
5132 if (active_entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
5134 #if defined(DEBUG_ILC_KEYEVENTS)
5135 D(bug("[IconList] %s: RIGHT: (C) entry 0x%p matches\n", __PRETTY_FUNCTION__
, active_entry
));
5141 active_entry
= (struct IconEntry
*)GetSucc(&active_entry
->ie_IconNode
);
5144 if (!(active_entry
))
5146 #if defined(DEBUG_ILC_KEYEVENTS)
5147 D(bug("[IconList] %s: RIGHT: No Next RIGHT Node - Getting first visable entry ..\n", __PRETTY_FUNCTION__
));
5149 /* We didnt find a "next RIGHT" entry so just use the first visible */
5150 active_entry
= (struct IconEntry
*)GetHead(&data
->icld_IconList
);
5151 while ((active_entry
!= NULL
) &&(!(active_entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)))
5153 active_entry
= (struct IconEntry
*)GetSucc(&active_entry
->ie_IconNode
);
5159 if (!(active_entry
->ie_Flags
& ICONENTRY_FLAG_FOCUS
))
5161 active_entry
->ie_Flags
|= ICONENTRY_FLAG_FOCUS
;
5162 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
5163 data
->update_entry
= active_entry
;
5164 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
5167 data
->icld_FocusIcon
= active_entry
;
5171 rawkey_handled
= TRUE
;
5173 #if defined(DEBUG_ILC_KEYEVENTS)
5174 D(bug("[IconList] %s: RAWKEY_HOME\n", __PRETTY_FUNCTION__
));
5177 if (data
->icld_FocusIcon
)
5179 data
->icld_FocusIcon
->ie_Flags
&= ~ICONENTRY_FLAG_FOCUS
;
5180 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
5181 data
->update_entry
= data
->icld_FocusIcon
;
5182 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
5185 active_entry
= Node_FirstVisible(&data
->icld_IconList
);
5187 if ((active_entry
) && (!(active_entry
->ie_Flags
& ICONENTRY_FLAG_FOCUS
)))
5189 active_entry
->ie_Flags
|= ICONENTRY_FLAG_FOCUS
;
5190 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
5191 data
->update_entry
= active_entry
;
5192 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
5194 data
->icld_FocusIcon
= active_entry
;
5198 rawkey_handled
= TRUE
;
5200 #if defined(DEBUG_ILC_KEYEVENTS)
5201 D(bug("[IconList] %s: RAWKEY_END\n", __PRETTY_FUNCTION__
));
5204 if (data
->icld_FocusIcon
)
5206 data
->icld_FocusIcon
->ie_Flags
&= ~ICONENTRY_FLAG_FOCUS
;
5207 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
5208 data
->update_entry
= data
->icld_FocusIcon
;
5209 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
5212 active_entry
= Node_LastVisible(&data
->icld_IconList
);
5214 if ((active_entry
) && (!(active_entry
->ie_Flags
& ICONENTRY_FLAG_FOCUS
)))
5216 active_entry
->ie_Flags
|= ICONENTRY_FLAG_FOCUS
;
5217 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
5218 data
->update_entry
= active_entry
;
5219 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
5221 data
->icld_FocusIcon
= active_entry
;
5225 if (rawkey_handled
) return MUI_EventHandlerRC_Eat
;
5229 case IDCMP_MOUSEBUTTONS
:
5230 #if defined(DEBUG_ILC_EVENTS)
5231 D(bug("[IconList] %s: IDCMP_MOUSEBUTTONS\n", __PRETTY_FUNCTION__
));
5233 if (message
->imsg
->Code
== SELECTDOWN
)
5235 /* check if mouse pressed on iconlist area */
5236 if (mx
>= 0 && mx
< _width(obj
) && my
>= 0 && my
< _height(obj
))
5238 BOOL icon_doubleclicked
= FALSE
;
5240 struct IconEntry
*node
= NULL
;
5241 struct IconEntry
*new_selected
= NULL
;
5243 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
5245 LONG clickColumn
= -1, clickRow
= -1;
5247 LONG x
= _mleft(obj
) - data
->icld_ViewX
+ LINE_SPACING_LEFT
;
5250 for(i
= 0; i
< NUM_COLUMNS
; i
++)
5252 index
= data
->icld_LVMAttribs
->lmva_ColumnPos
[i
];
5254 if (!(data
->icld_LVMAttribs
->lmva_ColumnFlags
[index
] & LVMCF_COLVISIBLE
)) continue;
5256 w
= data
->icld_LVMAttribs
->lmva_ColumnWidth
[index
];
5258 if ((mx
>= x
) && (mx
< x
+ w
))
5260 clickColumn
= index
;
5266 if (((data
->icld_LVMAttribs
->lvma_Flags
& LVMAF_NOHEADER
) == 0) && (my
<= data
->icld_LVMAttribs
->lmva_HeaderHeight
))
5268 data
->icld_LVMAttribs
->lmva_LastSelectedColumn
= clickColumn
;
5270 data
->icld_UpdateMode
= UPDATE_HEADERENTRY
;
5271 data
->update_entry
= clickColumn
;
5273 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
5278 LONG current
= 0, index
= (my
- data
->icld_LVMAttribs
->lmva_HeaderHeight
+ data
->icld_ViewY
) / data
->icld_LVMAttribs
->lmva_RowHeight
;
5280 ForeachNode(&data
->icld_IconList
, node
)
5282 if (node
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
5284 update_entry
= FALSE
;
5286 if (current
== index
)
5289 new_selected
= node
;
5293 if (node
->ie_Flags
& ICONENTRY_FLAG_SELECTED
)
5295 if (!(message
->imsg
->Qualifier
& (IEQUALIFIER_LSHIFT
| IEQUALIFIER_RSHIFT
)))
5297 Remove(&node
->ie_SelectionNode
);
5298 node
->ie_Flags
&= ~ICONENTRY_FLAG_SELECTED
;
5299 update_entry
= TRUE
;
5303 if (node
->ie_Flags
& ICONENTRY_FLAG_FOCUS
)
5305 node
->ie_Flags
&= ~ICONENTRY_FLAG_FOCUS
;
5306 update_entry
= TRUE
;
5311 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
5312 data
->update_entry
= node
;
5313 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
5314 D(bug("[IconList] %s: Rendered entry '%s'\n", __PRETTY_FUNCTION__
, node
->ie_IconListEntry
.label
));
5321 if ((DoubleClick(data
->last_secs
, data
->last_mics
, message
->imsg
->Seconds
, message
->imsg
->Micros
)) && (data
->icld_SelectionLastClicked
== new_selected
))
5323 D(bug("[IconList] %s: Entry double-clicked\n", __PRETTY_FUNCTION__
));
5324 icon_doubleclicked
= TRUE
;
5327 if ((new_selected
!= NULL
) && (clickRow
!= -1) && (clickColumn
!= -1))
5329 D(bug("[IconList] %s: Clicked on Row %d Column %d ..\n", __PRETTY_FUNCTION__
, clickRow
, clickColumn
));
5331 data
->icld_LassoActive
= FALSE
;
5332 update_entry
= FALSE
;
5334 if (!(new_selected
->ie_Flags
& ICONENTRY_FLAG_SELECTED
))
5336 AddTail(&data
->icld_SelectionList
, &new_selected
->ie_SelectionNode
);
5337 new_selected
->ie_Flags
|= ICONENTRY_FLAG_SELECTED
;
5338 update_entry
= TRUE
;
5340 if (!(new_selected
->ie_Flags
& ICONENTRY_FLAG_FOCUS
))
5342 new_selected
->ie_Flags
|= ICONENTRY_FLAG_FOCUS
;
5343 data
->icld_FocusIcon
= new_selected
;
5346 else if ((icon_doubleclicked
== FALSE
) && (message
->imsg
->Qualifier
& (IEQUALIFIER_LSHIFT
| IEQUALIFIER_RSHIFT
)))
5348 Remove(&new_selected
->ie_SelectionNode
);
5349 new_selected
->ie_Flags
&= ~ICONENTRY_FLAG_SELECTED
;
5350 update_entry
= TRUE
;
5355 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
5356 data
->update_entry
= new_selected
;
5357 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
5358 D(bug("[IconList] %s: Rendered 'new_selected' entry '%s'\n", __PRETTY_FUNCTION__
, new_selected
->ie_IconListEntry
.label
));
5363 struct Window
* thisWindow
= NULL
;
5364 #if defined(DEBUG_ILC_EVENTS) && defined(DEBUG_ILC_LASSO)
5365 D(bug("[IconList] %s: Starting Lasso\n", __PRETTY_FUNCTION__
));
5367 /* No entry clicked on ... Start Lasso-selection */
5368 data
->icld_LassoActive
= TRUE
;
5369 if (!(message
->imsg
->Qualifier
& (IEQUALIFIER_LSHIFT
| IEQUALIFIER_RSHIFT
)))
5371 data
->icld_SelectionLastClicked
= NULL
;
5372 data
->icld_FocusIcon
= NULL
;
5374 data
->icld_LassoRectangle
.MinX
= mx
- data
->view_rect
.MinX
+ data
->icld_ViewX
;
5375 data
->icld_LassoRectangle
.MinY
= my
- data
->view_rect
.MinY
+ data
->icld_ViewY
;
5376 data
->icld_LassoRectangle
.MaxX
= mx
- data
->view_rect
.MinX
+ data
->icld_ViewX
;
5377 data
->icld_LassoRectangle
.MaxY
= my
- data
->view_rect
.MinY
+ data
->icld_ViewY
;
5379 /* Draw initial Lasso frame */
5380 IconList_InvertLassoOutlines(obj
, data
, &data
->icld_LassoRectangle
);
5382 GET(obj
, MUIA_Window
, &thisWindow
);
5385 ModifyIDCMP(thisWindow
, (thisWindow
->IDCMPFlags
|IDCMP_INTUITICKS
));
5386 if (!(data
->ehn
.ehn_Events
& IDCMP_INTUITICKS
))
5388 DoMethod(_win(obj
), MUIM_Window_RemEventHandler
, (IPTR
)&data
->ehn
);
5389 data
->ehn
.ehn_Events
|= IDCMP_INTUITICKS
;
5390 DoMethod(_win(obj
), MUIM_Window_AddEventHandler
, (IPTR
)&data
->ehn
);
5398 struct Rectangle rect
;
5400 /* check if clicked on entry */
5401 #if defined(__AROS__)
5402 ForeachNode(&data
->icld_IconList
, node
)
5404 Foreach_Node(&data
->icld_IconList
, node
);
5407 if (node
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
5409 update_entry
= FALSE
;
5411 rect
.MinX
= node
->ie_IconX
;
5412 rect
.MaxX
= node
->ie_IconX
+ node
->ie_AreaWidth
- 1;
5413 rect
.MinY
= node
->ie_IconY
;
5414 rect
.MaxY
= node
->ie_IconY
+ node
->ie_AreaHeight
- 1;
5416 if ((data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
) &&
5417 (node
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
))
5419 rect
.MinX
+= ((data
->icld_IconAreaLargestWidth
- node
->ie_AreaWidth
)/2);
5420 rect
.MaxX
+= ((data
->icld_IconAreaLargestWidth
- node
->ie_AreaWidth
)/2);
5423 if ((((mx
+ data
->icld_ViewX
) >= rect
.MinX
) && ((mx
+ data
->icld_ViewX
) <= rect
.MaxX
)) &&
5424 (((my
+ data
->icld_ViewY
) >= rect
.MinY
) && ((my
+ data
->icld_ViewY
) <= rect
.MaxY
)) &&
5427 new_selected
= node
;
5428 #if defined(DEBUG_ILC_EVENTS)
5429 D(bug("[IconList] %s: Entry '%s' clicked on ..\n", __PRETTY_FUNCTION__
, node
->ie_IconListEntry
.label
));
5433 if (node
->ie_Flags
& ICONENTRY_FLAG_SELECTED
)
5435 if ((new_selected
!= node
) &&
5436 (!(message
->imsg
->Qualifier
& (IEQUALIFIER_LSHIFT
| IEQUALIFIER_RSHIFT
))))
5438 Remove(&node
->ie_SelectionNode
);
5439 node
->ie_Flags
&= ~ICONENTRY_FLAG_SELECTED
;
5440 update_entry
= TRUE
;
5444 if ((node
->ie_Flags
& ICONENTRY_FLAG_FOCUS
) && (new_selected
!= node
))
5446 node
->ie_Flags
&= ~ICONENTRY_FLAG_FOCUS
;
5447 update_entry
= TRUE
;
5452 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
5453 data
->update_entry
= node
;
5454 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
5455 #if defined(DEBUG_ILC_EVENTS)
5456 D(bug("[IconList] %s: Rendered entry '%s'\n", __PRETTY_FUNCTION__
, node
->ie_IconListEntry
.label
));
5462 if ((DoubleClick(data
->last_secs
, data
->last_mics
, message
->imsg
->Seconds
, message
->imsg
->Micros
)) && (data
->icld_SelectionLastClicked
== new_selected
))
5464 #if defined(DEBUG_ILC_EVENTS)
5465 D(bug("[IconList] %s: Entry double-clicked\n", __PRETTY_FUNCTION__
));
5467 icon_doubleclicked
= TRUE
;
5470 if (new_selected
!= NULL
)
5472 data
->icld_LassoActive
= FALSE
;
5473 update_entry
= FALSE
;
5475 if (!(new_selected
->ie_Flags
& ICONENTRY_FLAG_SELECTED
))
5477 AddTail(&data
->icld_SelectionList
, &new_selected
->ie_SelectionNode
);
5478 new_selected
->ie_Flags
|= ICONENTRY_FLAG_SELECTED
;
5479 update_entry
= TRUE
;
5481 if (!(new_selected
->ie_Flags
& ICONENTRY_FLAG_FOCUS
))
5483 new_selected
->ie_Flags
|= ICONENTRY_FLAG_FOCUS
;
5484 data
->icld_FocusIcon
= new_selected
;
5487 else if ((icon_doubleclicked
== FALSE
) && (message
->imsg
->Qualifier
& (IEQUALIFIER_LSHIFT
| IEQUALIFIER_RSHIFT
)))
5489 Remove(&new_selected
->ie_SelectionNode
);
5490 new_selected
->ie_Flags
&= ~ICONENTRY_FLAG_SELECTED
;
5491 update_entry
= TRUE
;
5494 if (update_entry
!= NULL
)
5496 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
5497 data
->update_entry
= new_selected
;
5498 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
5499 #if defined(DEBUG_ILC_EVENTS)
5500 D(bug("[IconList] %s: Rendered 'new_selected' entry '%s'\n", __PRETTY_FUNCTION__
, new_selected
->ie_IconListEntry
.label
));
5506 struct Window
* thisWindow
= NULL
;
5507 #if defined(DEBUG_ILC_EVENTS) && defined(DEBUG_ILC_LASSO)
5508 D(bug("[IconList] %s: Starting Lasso\n", __PRETTY_FUNCTION__
));
5510 /* No entry clicked on ... Start Lasso-selection */
5511 data
->icld_LassoActive
= TRUE
;
5512 if (!(message
->imsg
->Qualifier
& (IEQUALIFIER_LSHIFT
| IEQUALIFIER_RSHIFT
)))
5514 data
->icld_SelectionLastClicked
= NULL
;
5515 data
->icld_FocusIcon
= NULL
;
5517 data
->icld_LassoRectangle
.MinX
= mx
- data
->view_rect
.MinX
+ data
->icld_ViewX
;
5518 data
->icld_LassoRectangle
.MinY
= my
- data
->view_rect
.MinY
+ data
->icld_ViewY
;
5519 data
->icld_LassoRectangle
.MaxX
= mx
- data
->view_rect
.MinX
+ data
->icld_ViewX
;
5520 data
->icld_LassoRectangle
.MaxY
= my
- data
->view_rect
.MinY
+ data
->icld_ViewY
;
5522 /* Draw initial Lasso frame */
5523 IconList_InvertLassoOutlines(obj
, data
, &data
->icld_LassoRectangle
);
5525 GET(obj
, MUIA_Window
, &thisWindow
);
5528 ModifyIDCMP(thisWindow
, (thisWindow
->IDCMPFlags
|IDCMP_INTUITICKS
));
5529 if (!(data
->ehn
.ehn_Events
& IDCMP_INTUITICKS
))
5531 DoMethod(_win(obj
), MUIM_Window_RemEventHandler
, (IPTR
)&data
->ehn
);
5532 data
->ehn
.ehn_Events
|= IDCMP_INTUITICKS
;
5533 DoMethod(_win(obj
), MUIM_Window_AddEventHandler
, (IPTR
)&data
->ehn
);
5539 if (new_selected
&& (new_selected
->ie_Flags
& ICONENTRY_FLAG_SELECTED
))
5540 data
->icld_SelectionLastClicked
= new_selected
;
5542 data
->icld_SelectionLastClicked
= NULL
;
5547 SET(obj
, MUIA_IconList_SelectionChanged
, TRUE
);
5549 data
->icld_ClickEvent
.shift
= !!(message
->imsg
->Qualifier
& (IEQUALIFIER_LSHIFT
| IEQUALIFIER_RSHIFT
));
5550 data
->icld_ClickEvent
.entry
= data
->icld_SelectionLastClicked
? &data
->icld_SelectionLastClicked
->ie_IconListEntry
: NULL
;
5551 SET(obj
, MUIA_IconList_Clicked
, (IPTR
)&data
->icld_ClickEvent
);
5553 if (icon_doubleclicked
)
5555 SET(obj
, MUIA_IconList_DoubleClick
, TRUE
);
5557 else if (!data
->mouse_pressed
)
5559 data
->last_secs
= message
->imsg
->Seconds
;
5560 data
->last_mics
= message
->imsg
->Micros
;
5562 /* After a double click you often open a new window
5563 * and since Zune doesn't not support the faking
5564 * of SELECTUP events only change the Events
5565 * if not doubleclicked */
5567 data
->mouse_pressed
|= LEFT_BUTTON
;
5569 if (!(data
->ehn
.ehn_Events
& IDCMP_MOUSEMOVE
))
5571 DoMethod(_win(obj
), MUIM_Window_RemEventHandler
, (IPTR
)&data
->ehn
);
5572 data
->ehn
.ehn_Events
|= IDCMP_MOUSEMOVE
;
5573 DoMethod(_win(obj
), MUIM_Window_AddEventHandler
, (IPTR
)&data
->ehn
);
5577 return MUI_EventHandlerRC_Eat
;
5580 else if (message
->imsg
->Code
== MIDDLEDOWN
)
5582 if (!data
->mouse_pressed
)
5584 data
->mouse_pressed
|= MIDDLE_BUTTON
;
5586 data
->click_x
= data
->icld_ViewX
+ mx
;
5587 data
->click_y
= data
->icld_ViewY
+ my
;
5589 if (!(data
->ehn
.ehn_Events
& IDCMP_MOUSEMOVE
))
5591 DoMethod(_win(obj
), MUIM_Window_RemEventHandler
, (IPTR
)&data
->ehn
);
5592 data
->ehn
.ehn_Events
|= IDCMP_MOUSEMOVE
;
5593 DoMethod(_win(obj
), MUIM_Window_AddEventHandler
, (IPTR
)&data
->ehn
);
5599 if (message
->imsg
->Code
== SELECTUP
)
5601 if (data
->icld_LassoActive
== TRUE
)
5603 #if defined(DEBUG_ILC_EVENTS) && defined(DEBUG_ILC_LASSO)
5604 D(bug("[IconList] %s: Removing Lasso\n", __PRETTY_FUNCTION__
));
5606 // End Lasso-selection
5607 struct Rectangle old_lasso
;
5608 struct IconEntry
*node
= NULL
;
5609 struct Window
*thisWindow
= NULL
;
5611 GET(obj
, MUIA_Window
, &thisWindow
);
5614 ModifyIDCMP(thisWindow
, (thisWindow
->IDCMPFlags
& ~(IDCMP_INTUITICKS
)));
5615 if ((data
->ehn
.ehn_Events
& IDCMP_INTUITICKS
))
5617 DoMethod(_win(obj
), MUIM_Window_RemEventHandler
, (IPTR
)&data
->ehn
);
5618 data
->ehn
.ehn_Events
&= ~IDCMP_INTUITICKS
;
5619 DoMethod(_win(obj
), MUIM_Window_AddEventHandler
, (IPTR
)&data
->ehn
);
5622 //Clear Lasso Frame..
5623 GetAbsoluteLassoRect(data
, &old_lasso
);
5624 IconList_InvertLassoOutlines(obj
, data
, &old_lasso
);
5626 data
->icld_LassoActive
= FALSE
;
5628 //Remove Lasso flag from affected icons..
5629 #if defined(__AROS__)
5630 ForeachNode(&data
->icld_IconList
, node
)
5632 Foreach_Node(&data
->icld_IconList
, node
);
5635 if (node
->ie_Flags
& ICONENTRY_FLAG_LASSO
)
5637 node
->ie_Flags
&= ~ICONENTRY_FLAG_LASSO
;
5640 SET(obj
, MUIA_IconList_SelectionChanged
, TRUE
);
5642 else if (data
->icld_LVMAttribs
->lmva_LastSelectedColumn
!= -1)
5644 ULONG orig_sortflags
= data
->icld_SortFlags
;
5646 if (data
->icld_LVMAttribs
->lmva_SortColumn
== data
->icld_LVMAttribs
->lmva_LastSelectedColumn
)
5648 if (data
->icld_SortFlags
& MUIV_IconList_Sort_Reverse
)
5649 data
->icld_SortFlags
&= ~MUIV_IconList_Sort_Reverse
;
5651 data
->icld_SortFlags
|= MUIV_IconList_Sort_Reverse
;
5654 switch (data
->icld_LVMAttribs
->lmva_LastSelectedColumn
)
5657 data
->icld_SortFlags
&= ~MUIV_IconList_Sort_MASK
;
5658 data
->icld_SortFlags
|= MUIV_IconList_Sort_ByName
;
5662 data
->icld_SortFlags
&= ~MUIV_IconList_Sort_MASK
;
5663 data
->icld_SortFlags
|= MUIV_IconList_Sort_BySize
;
5667 data
->icld_SortFlags
&= ~MUIV_IconList_Sort_MASK
;
5668 data
->icld_SortFlags
|= MUIV_IconList_Sort_ByDate
;
5672 if (orig_sortflags
!= data
->icld_SortFlags
)
5674 data
->icld_LVMAttribs
->lmva_SortColumn
= data
->icld_LVMAttribs
->lmva_LastSelectedColumn
;
5676 data
->icld_LVMAttribs
->lmva_LastSelectedColumn
= -1;
5678 DoMethod(obj
, MUIM_IconList_Sort
);
5682 data
->mouse_pressed
&= ~LEFT_BUTTON
;
5685 if (message
->imsg
->Code
== MIDDLEUP
)
5687 data
->mouse_pressed
&= ~MIDDLE_BUTTON
;
5690 if ((data
->ehn
.ehn_Events
& IDCMP_MOUSEMOVE
) && !data
->mouse_pressed
)
5692 DoMethod(_win(obj
),MUIM_Window_RemEventHandler
, (IPTR
)&data
->ehn
);
5693 data
->ehn
.ehn_Events
&= ~IDCMP_MOUSEMOVE
;
5694 DoMethod(_win(obj
),MUIM_Window_AddEventHandler
, (IPTR
)&data
->ehn
);
5699 case IDCMP_INTUITICKS
:
5701 #if defined(DEBUG_ILC_EVENTS)
5702 D(bug("[IconList] %s: IDCMP_INTUITICKS (%d, %d)\n", __PRETTY_FUNCTION__
, mx
, my
));
5704 if ((data
->icld_LassoActive
== FALSE
)||(!(data
->mouse_pressed
& LEFT_BUTTON
)))
5708 if (((mx
>= 0) && (mx
<= _mwidth(obj
))) &&
5709 ((my
>= 0) && (my
<= _mheight(obj
))))
5713 case IDCMP_MOUSEMOVE
:
5714 #if defined(DEBUG_ILC_EVENTS)
5715 D(bug("[IconList] %s: IDCMP_MOUSEMOVE\n", __PRETTY_FUNCTION__
));
5717 if (data
->mouse_pressed
& LEFT_BUTTON
)
5722 if (data
->icld_SelectionLastClicked
&& (data
->icld_LassoActive
== FALSE
) &&
5723 ((abs(move_x
- data
->click_x
) >= 2) || (abs(move_y
- data
->click_y
) >= 2)))
5725 // Entry(s) being dragged ....
5726 DoMethod(_win(obj
),MUIM_Window_RemEventHandler
, (IPTR
)&data
->ehn
);
5727 data
->ehn
.ehn_Events
&= ~IDCMP_MOUSEMOVE
;
5728 DoMethod(_win(obj
),MUIM_Window_AddEventHandler
, (IPTR
)&data
->ehn
);
5730 data
->mouse_pressed
&= ~LEFT_BUTTON
;
5732 data
->touch_x
= move_x
+ data
->icld_ViewX
- data
->icld_SelectionLastClicked
->ie_IconX
;
5733 data
->touch_y
= move_y
+ data
->icld_ViewY
- data
->icld_SelectionLastClicked
->ie_IconY
;
5734 DoMethod(obj
,MUIM_DoDrag
, data
->touch_x
, data
->touch_y
, 0);
5736 else if (data
->icld_LassoActive
== TRUE
)
5738 #if defined(DEBUG_ILC_EVENTS) && defined(DEBUG_ILC_LASSO)
5739 D(bug("[IconList] %s: Update Lasso\n", __PRETTY_FUNCTION__
));
5742 struct Rectangle new_lasso
,
5744 struct Rectangle iconrect
;
5746 struct IconEntry
*node
= NULL
;
5747 // struct IconEntry *new_selected = NULL;
5749 /* Remove previous Lasso frame */
5750 GetAbsoluteLassoRect(data
, &old_lasso
);
5751 IconList_InvertLassoOutlines(obj
, data
, &old_lasso
);
5753 /* if the mouse leaves our visible area scroll the view */
5754 if (mx
< 0 || mx
>= _mwidth(obj
) || my
< 0 || my
>= _mheight(obj
))
5756 LONG newleft
= data
->icld_ViewX
;
5757 LONG newtop
= data
->icld_ViewY
;
5759 if (mx
>= _mwidth(obj
)) newleft
+= (mx
- _mwidth(obj
));
5760 else if (mx
< 0) newleft
+= mx
;
5761 if (my
>= _mheight(obj
)) newtop
+= (my
- _mheight(obj
));
5762 else if (my
< 0) newtop
+= my
;
5764 if (newleft
+ _mwidth(obj
) > data
->icld_AreaWidth
) newleft
= data
->icld_AreaWidth
- _mwidth(obj
);
5765 if (newleft
< 0) newleft
= 0;
5767 if (newtop
+ _mheight(obj
) > data
->icld_AreaHeight
) newtop
= data
->icld_AreaHeight
- _mheight(obj
);
5768 if (newtop
< 0) newtop
= 0;
5770 if ((newleft
!= data
->icld_ViewX
) || (newtop
!= data
->icld_ViewY
))
5772 SetAttrs(obj
, MUIA_Virtgroup_Left
, newleft
, MUIA_Virtgroup_Top
, newtop
, TAG_DONE
);
5776 /* update Lasso coordinates */
5777 data
->icld_LassoRectangle
.MaxX
= mx
- data
->view_rect
.MinX
+ data
->icld_ViewX
;
5778 data
->icld_LassoRectangle
.MaxY
= my
- data
->view_rect
.MinY
+ data
->icld_ViewY
;
5780 /* get absolute Lasso coordinates */
5781 GetAbsoluteLassoRect(data
, &new_lasso
);
5783 LONG current
= 0, startIndex
= 0, endIndex
= 0;
5785 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
5787 LONG minY
= data
->icld_LassoRectangle
.MinY
,
5788 maxY
= data
->icld_LassoRectangle
.MaxY
;
5797 startIndex
= ((minY
+ 1) - data
->icld_LVMAttribs
->lmva_HeaderHeight
) / data
->icld_LVMAttribs
->lmva_RowHeight
;
5798 endIndex
= ((maxY
- 1) - data
->icld_LVMAttribs
->lmva_HeaderHeight
) / data
->icld_LVMAttribs
->lmva_RowHeight
;
5801 #if defined(__AROS__)
5802 ForeachNode(&data
->icld_IconList
, node
)
5804 Foreach_Node(&data
->icld_IconList
, node
);
5807 IPTR update_entry
= (IPTR
)NULL
;
5809 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
5811 if (node
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
5813 update_entry
= FALSE
;
5815 if ((current
>= startIndex
) && (current
<= endIndex
))
5817 //Entry is inside our lasso ..
5818 if (!(node
->ie_Flags
& ICONENTRY_FLAG_LASSO
))
5820 /* check if entry was already selected before */
5821 if (node
->ie_Flags
& ICONENTRY_FLAG_SELECTED
)
5823 Remove(&node
->ie_SelectionNode
);
5824 node
->ie_Flags
&= ~ICONENTRY_FLAG_SELECTED
;
5828 AddTail(&data
->icld_SelectionList
, &node
->ie_SelectionNode
);
5829 node
->ie_Flags
|= ICONENTRY_FLAG_SELECTED
;
5831 node
->ie_Flags
|= ICONENTRY_FLAG_LASSO
;
5832 update_entry
= (IPTR
)node
;
5835 else if (node
->ie_Flags
& ICONENTRY_FLAG_LASSO
)
5837 //Entry is no longer inside our lasso - revert its selected state
5838 if (node
->ie_Flags
& ICONENTRY_FLAG_SELECTED
)
5840 Remove(&node
->ie_SelectionNode
);
5841 node
->ie_Flags
&= ~ICONENTRY_FLAG_SELECTED
;
5845 AddTail(&data
->icld_SelectionList
, &node
->ie_SelectionNode
);
5846 node
->ie_Flags
|= ICONENTRY_FLAG_SELECTED
;
5848 node
->ie_Flags
&= ~ICONENTRY_FLAG_LASSO
;
5849 update_entry
= (IPTR
)node
;
5857 if (node
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
5859 iconrect
.MinX
= node
->ie_IconX
;
5860 iconrect
.MaxX
= node
->ie_IconX
+ node
->ie_AreaWidth
- 1;
5861 iconrect
.MinY
= node
->ie_IconY
;
5862 iconrect
.MaxY
= node
->ie_IconY
+ node
->ie_AreaHeight
- 1;
5863 if ((data
->icld__Option_IconListMode
== ICON_LISTMODE_GRID
) &&
5864 (node
->ie_AreaWidth
< data
->icld_IconAreaLargestWidth
))
5866 iconrect
.MinX
+= ((data
->icld_IconAreaLargestWidth
- node
->ie_AreaWidth
)/2);
5867 iconrect
.MaxX
+= ((data
->icld_IconAreaLargestWidth
- node
->ie_AreaWidth
)/2);
5870 if ((((new_lasso
.MaxX
+ data
->icld_ViewX
) >= iconrect
.MinX
) && ((new_lasso
.MinX
+ data
->icld_ViewX
) <= iconrect
.MaxX
)) &&
5871 (((new_lasso
.MaxY
+ data
->icld_ViewY
) >= iconrect
.MinY
) && ((new_lasso
.MinY
+ data
->icld_ViewY
) <= iconrect
.MaxY
)))
5873 //Entry is inside our lasso ..
5874 if (!(node
->ie_Flags
& ICONENTRY_FLAG_LASSO
))
5876 /* check if entry was already selected before */
5877 if (node
->ie_Flags
& ICONENTRY_FLAG_SELECTED
)
5879 Remove(&node
->ie_SelectionNode
);
5880 node
->ie_Flags
&= ~ICONENTRY_FLAG_SELECTED
;
5884 AddTail(&data
->icld_SelectionList
, &node
->ie_SelectionNode
);
5885 node
->ie_Flags
|= ICONENTRY_FLAG_SELECTED
;
5887 node
->ie_Flags
|= ICONENTRY_FLAG_LASSO
;
5888 update_entry
= (IPTR
)node
;
5891 else if (node
->ie_Flags
& ICONENTRY_FLAG_LASSO
)
5893 //Entry is no longer inside our lasso - revert its selected state
5894 if (node
->ie_Flags
& ICONENTRY_FLAG_SELECTED
)
5896 Remove(&node
->ie_SelectionNode
);
5897 node
->ie_Flags
&= ~ICONENTRY_FLAG_SELECTED
;
5901 AddTail(&data
->icld_SelectionList
, &node
->ie_SelectionNode
);
5902 node
->ie_Flags
|= ICONENTRY_FLAG_SELECTED
;
5904 node
->ie_Flags
&= ~ICONENTRY_FLAG_LASSO
;
5905 update_entry
= (IPTR
)node
;
5911 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
5912 data
->update_entry
= (struct IconEntry
*)update_entry
;
5913 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
5916 /* Draw Lasso frame */
5917 IconList_InvertLassoOutlines(obj
, data
, &new_lasso
);
5920 return MUI_EventHandlerRC_Eat
;
5922 else if (data
->mouse_pressed
& MIDDLE_BUTTON
)
5927 newleft
= data
->click_x
- mx
;
5928 newtop
= data
->click_y
- my
;
5930 if (newleft
+ _mwidth(obj
) > data
->icld_AreaWidth
) newleft
= data
->icld_AreaWidth
- _mwidth(obj
);
5931 if (newleft
< 0) newleft
= 0;
5933 if (newtop
+ _mheight(obj
) > data
->icld_AreaHeight
) newtop
= data
->icld_AreaHeight
- _mheight(obj
);
5934 if (newtop
< 0) newtop
= 0;
5936 if ((newleft
!= data
->icld_ViewX
) || (newtop
!= data
->icld_ViewY
))
5938 SetAttrs(obj
, MUIA_Virtgroup_Left
, newleft
,
5939 MUIA_Virtgroup_Top
, newtop
,
5943 return MUI_EventHandlerRC_Eat
;
5954 ///MUIM_IconList_NextIcon()
5955 /**************************************************************************
5956 MUIM_IconList_NextIcon
5957 **************************************************************************/
5958 IPTR
IconList__MUIM_IconList_NextIcon(struct IClass
*CLASS
, Object
*obj
, struct MUIP_IconList_NextIcon
*message
)
5960 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
5961 struct IconEntry
*node
= NULL
;
5962 struct IconList_Entry
*ent
= NULL
;
5963 IPTR node_successor
= (IPTR
)NULL
;
5965 if (message
->entry
== NULL
) return (IPTR
)NULL
;
5966 ent
= *message
->entry
;
5968 #if defined(DEBUG_ILC_FUNCS)
5969 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
5972 if ((IPTR
)ent
== (IPTR
)MUIV_IconList_NextIcon_Start
)
5974 D(bug("[IconList] %s: Finding First Entry ..\n", __PRETTY_FUNCTION__
));
5975 if (message
->nextflag
== MUIV_IconList_NextIcon_Selected
)
5977 node
= (struct IconEntry
*)GetHead(&data
->icld_SelectionList
);
5980 node
= (struct IconEntry
*)((IPTR
)node
- ((IPTR
)&node
->ie_SelectionNode
- (IPTR
)node
));
5983 else if (message
->nextflag
== MUIV_IconList_NextIcon_Visible
)
5985 node
= (struct IconEntry
*)GetHead(&data
->icld_IconList
);
5986 while (node
!= NULL
)
5988 if (node
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
5991 node
= (struct IconEntry
*)GetSucc(&node
->ie_IconNode
);
5995 else if ((IPTR
)ent
!= (IPTR
)MUIV_IconList_NextIcon_End
)
5997 node
= (struct IconEntry
*)((IPTR
)ent
- ((IPTR
)&node
->ie_IconListEntry
- (IPTR
)node
));
5998 if (message
->nextflag
== MUIV_IconList_NextIcon_Selected
)
6000 node_successor
= (IPTR
)GetSucc(&node
->ie_SelectionNode
);
6001 if (node_successor
!= (IPTR
)NULL
)
6002 node
= (struct IconEntry
*)((IPTR
)node_successor
- ((IPTR
)&node
->ie_SelectionNode
- (IPTR
)node
));
6005 D(bug("[IconList] %s: GetSucc() == NULL\n", __PRETTY_FUNCTION__
));
6009 else if (message
->nextflag
== MUIV_IconList_NextIcon_Visible
)
6011 node
= (struct IconEntry
*)GetSucc(&node
->ie_IconNode
);
6012 while (node
!= NULL
)
6014 if (node
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
6017 node
= (struct IconEntry
*)GetSucc(&node
->ie_IconNode
);
6024 D(bug("[IconList] %s: Returning MUIV_IconList_NextIcon_End\n", __PRETTY_FUNCTION__
));
6026 *message
->entry
= (struct IconList_Entry
*)MUIV_IconList_NextIcon_End
;
6030 D(bug("[IconList] %s: Returning entry for '%s'\n", __PRETTY_FUNCTION__
, node
->ie_IconListEntry
.label
));
6032 *message
->entry
= &node
->ie_IconListEntry
;
6039 ///MUIM_IconList_GetIconPrivate()
6040 /**************************************************************************
6041 MUIM_IconList_GetIconPrivate
6042 **************************************************************************/
6043 IPTR
IconList__MUIM_IconList_GetIconPrivate(struct IClass
*CLASS
, Object
*obj
, struct MUIP_IconList_GetIconPrivate
*message
)
6045 // struct IconList_DATA *data = INST_DATA(CLASS, obj);
6046 struct IconEntry
*node
= NULL
;
6048 if (message
->entry
== NULL
) return (IPTR
)NULL
;
6050 node
= (struct IconEntry
*)((IPTR
)message
->entry
- ((IPTR
)&node
->ie_IconListEntry
- (IPTR
)node
));
6055 ///MUIM_CreateDragImage()
6056 /**************************************************************************
6057 MUIM_CreateDragImage
6058 **************************************************************************/
6059 IPTR
IconList__MUIM_CreateDragImage(struct IClass
*CLASS
, Object
*obj
, struct MUIP_CreateDragImage
*message
)
6061 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
6062 struct MUI_DragImage
*img
= NULL
;
6066 #if defined(DEBUG_ILC_FUNCS)
6067 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
6070 if (!(data
->icld_SelectionLastClicked
))
6071 DoSuperMethodA(CLASS
, obj
, (Msg
)message
);
6073 if ((img
= (struct MUI_DragImage
*)AllocVec(sizeof(struct MUIP_CreateDragImage
), MEMF_CLEAR
)))
6075 struct Node
*node
= NULL
;
6076 struct IconEntry
*entry
= NULL
;
6078 LONG depth
= GetBitMapAttr(_screen(obj
)->RastPort
.BitMap
, BMA_DEPTH
);
6080 #if defined(CREATE_FULL_DRAGIMAGE)
6081 #if defined(__AROS__)
6082 ForeachNode(&data
->icld_SelectionList
, node
)
6084 Foreach_Node(&data
->icld_SelectionList
, node
);
6087 entry
= (struct IconEntry
*)((IPTR
)node
- ((IPTR
)&entry
->ie_SelectionNode
- (IPTR
)entry
));
6088 if ((entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
) && (entry
->ie_Flags
& ICONENTRY_FLAG_SELECTED
))
6090 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) != ICONLIST_DISP_MODELIST
)
6092 if ((first_x
== -1) || ((first_x
!= -1) && (entry
->ie_IconX
< first_x
))) first_x
= entry
->ie_IconX
;
6093 if ((first_y
== -1) || ((first_y
!= -1) && (entry
->ie_IconY
< first_y
))) first_y
= entry
->ie_IconY
;
6094 if ((entry
->ie_IconX
+ entry
->ie_IconWidth
) > img
->width
) img
->width
= entry
->ie_IconX
+ entry
->ie_IconWidth
;
6095 if ((entry
->ie_IconY
+ entry
->ie_IconHeight
) > img
->height
) img
->height
= entry
->ie_IconY
+ entry
->ie_IconHeight
;
6099 img
->height
+= data
->icld_LVMAttribs
->lmva_RowHeight
;
6103 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
6107 img
->width
= _mright(obj
) - _mleft(obj
);
6110 img
->width
= (img
->width
- first_x
) + 2;
6112 img
->height
= (img
->height
- first_y
) + 2;
6114 entry
= data
->icld_SelectionLastClicked
;
6115 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
6117 img
->width
= _mright(obj
) - _mleft(obj
);
6118 img
->height
= data
->icld_LVMAttribs
->lmva_RowHeight
;
6124 img
->width
= entry
->ie_IconWidth
;
6125 img
->height
= entry
->ie_IconHeight
;
6126 first_x
= entry
->ie_IconX
;
6127 first_y
= entry
->ie_IconY
;
6131 img
->touchx
= data
->click_x
- first_x
;
6132 img
->touchy
= data
->click_y
- first_y
;
6134 if ((img
->bm
= AllocBitMap(img
->width
, img
->height
, depth
, BMF_CLEAR
, _screen(obj
)->RastPort
.BitMap
)))
6136 struct RastPort temprp
;
6137 InitRastPort(&temprp
);
6138 temprp
.BitMap
= img
->bm
;
6140 #if defined(CREATE_FULL_DRAGIMAGE)
6141 ForeachNode(&data
->icld_SelectionList
, node
)
6143 entry
= (struct IconEntry
*)((IPTR
)node
- ((IPTR
)&entry
->ie_SelectionNode
- (IPTR
)entry
));
6144 if ((entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
) && (entry
->ie_Flags
& ICONENTRY_FLAG_SELECTED
))
6146 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
6153 &temprp
, entry
->ie_DiskObj
, NULL
,
6154 (entry
->ie_IconX
+ 1) - first_x
, (entry
->ie_IconY
+ 1) - first_y
,
6156 __iconList_DrawIconStateTags
6162 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
6164 SetABPenDrMd(&temprp
, _pens(obj
)[MPEN_SHINE
], 0, JAM1
);
6165 RectFill(&temprp
, 0, 0, img
->width
, img
->height
);
6171 &temprp
, entry
->ie_DiskObj
, NULL
,
6174 __iconList_DrawIconStateTags
6178 RastPortSetAlpha(&temprp
, data
->click_x
, data
->click_y
, img
->width
, img
->height
, 0x80, RPALPHAFLAT
);
6179 DeinitRastPort(&temprp
);
6182 img
->touchx
= message
->touchx
;
6183 img
->touchy
= message
->touchy
;
6186 #if defined(__MORPHOS__)
6187 img
->dragmode
= DD_TRANSPARENT
;
6194 ///MUIM_DeleteDragImage()
6195 /**************************************************************************
6196 MUIM_DeleteDragImage
6197 **************************************************************************/
6198 IPTR
IconList__MUIM_DeleteDragImage(struct IClass
*CLASS
, Object
*obj
, struct MUIP_DeleteDragImage
*message
)
6200 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
6202 #if defined(DEBUG_ILC_FUNCS)
6203 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
6206 if (!(data
->icld_SelectionLastClicked
)) return DoSuperMethodA(CLASS
,obj
,(Msg
)message
);
6210 if (message
->di
->bm
)
6211 FreeBitMap(message
->di
->bm
);
6212 FreeVec(message
->di
);
6219 /**************************************************************************
6221 **************************************************************************/
6222 IPTR
IconList__MUIM_DragQuery(struct IClass
*CLASS
, Object
*obj
, struct MUIP_DragQuery
*message
)
6224 #if defined(DEBUG_ILC_FUNCS)
6225 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
6228 #warning "TODO: highlight the possible drop target entry .."
6230 if (message
->obj
== obj
)
6231 return MUIV_DragQuery_Accept
;
6234 BOOL is_iconlist
= FALSE
;
6235 struct IClass
*msg_cl
= OCLASS(message
->obj
);
6239 if (msg_cl
== CLASS
)
6244 msg_cl
= msg_cl
->cl_Super
;
6247 return MUIV_DragQuery_Accept
;
6250 return MUIV_DragQuery_Refuse
;
6255 /**************************************************************************
6257 **************************************************************************/
6258 IPTR
IconList__MUIM_DragDrop(struct IClass
*CLASS
, Object
*obj
, struct MUIP_DragDrop
*message
)
6260 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
6262 #if defined(DEBUG_ILC_FUNCS)
6263 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
6266 struct IconList_Entry
*entry
= (IPTR
)MUIV_IconList_NextIcon_Start
;
6268 if (data
->icld_DragDropEvent
)
6270 struct IconList_Drop_SourceEntry
*clean_node
;
6271 #if defined(DEBUG_ILC_ICONDRAGDROP)
6272 D(bug("[IconList] %s: Cleaning existing IconList_Drop_Event @ %p\n", __PRETTY_FUNCTION__
, data
->icld_DragDropEvent
));
6274 while ((clean_node
= (struct IconList_Drop_SourceEntry
*)RemTail(&data
->icld_DragDropEvent
->drop_SourceList
)) != NULL
)
6276 FreeVec(clean_node
->dropse_Node
.ln_Name
);
6277 FreeMem(clean_node
, sizeof(struct IconList_Drop_SourceEntry
));
6279 if (data
->icld_DragDropEvent
->drop_TargetPath
) FreeVec(data
->icld_DragDropEvent
->drop_TargetPath
);
6280 FreeMem(data
->icld_DragDropEvent
, sizeof(struct IconList_Drop_Event
));
6281 data
->icld_DragDropEvent
= NULL
;
6284 /* SANITY CHECK: Get first selected entry from SOURCE iconlist */
6285 DoMethod(message
->obj
, MUIM_IconList_NextIcon
, MUIV_IconList_NextIcon_Selected
, (IPTR
)&entry
);
6287 if ((entry
) && (entry
!= (IPTR
)MUIV_IconList_NextIcon_End
))
6289 /* Ok.. atleast one entry was dropped .. */
6290 char tmp_dirbuff
[256];
6291 BPTR tmp_dirlock
= (BPTR
) NULL
;
6293 BOOL iconMove
= FALSE
;
6294 struct IconEntry
*node
= NULL
;
6295 struct IconEntry
*drop_target_node
= NULL
;
6296 STRPTR directory_path
= NULL
;
6297 struct IconList_Drop_Event
*dragDropEvent
= NULL
;
6299 GET(obj
, MUIA_IconDrawerList_Drawer
, &directory_path
);
6301 /* Properly expand the name incase it uses devices rather than volumes */
6302 if (directory_path
!= NULL
)
6304 tmp_dirlock
= Lock(directory_path
, SHARED_LOCK
);
6307 if (NameFromLock(tmp_dirlock
, tmp_dirbuff
, 256) != 0)
6309 directory_path
= tmp_dirbuff
;
6311 UnLock(tmp_dirlock
);
6314 if ((dragDropEvent
= AllocMem(sizeof(struct IconList_Drop_Event
), MEMF_CLEAR
)) == NULL
)
6316 #if defined(DEBUG_ILC_ICONDRAGDROP)
6317 D(bug("[IconList] %s: Failed to allocate IconList_Drop_Event Storage!\n", __PRETTY_FUNCTION__
));
6321 D(bug("[IconList] %s: Allocated IconList_Drop_Event @ %p\n", __PRETTY_FUNCTION__
, dragDropEvent
));
6323 NewList(&dragDropEvent
->drop_SourceList
);
6325 /* go through list and check if dropped on entry */
6328 #if defined(__AROS__)
6329 ForeachNode(&data
->icld_IconList
, node
)
6331 Foreach_Node(&data
->icld_IconList
, node
);
6334 if ((data
->icld_DisplayFlags
& ICONLIST_DISP_MODELIST
) == ICONLIST_DISP_MODELIST
)
6336 if (node
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
6338 ULONG rowTop
= _mtop(obj
) + (rowCount
* data
->icld_LVMAttribs
->lmva_RowHeight
);
6339 rowTop
+= data
->icld_LVMAttribs
->lmva_HeaderHeight
;
6341 if (((message
->x
> _mleft(obj
)) && (message
->x
< _mright(obj
)))
6342 && ((message
->y
> rowTop
) && (message
->y
< (rowTop
+ data
->icld_LVMAttribs
->lmva_RowHeight
))))
6344 drop_target_node
= node
;
6353 struct Rectangle iconbox
;
6354 LONG click_x
= message
->x
- _mleft(obj
);
6355 LONG click_y
= message
->y
- _mtop(obj
);
6356 iconbox
.MinX
= node
->ie_IconX
- data
->icld_ViewX
;
6357 iconbox
.MaxX
= (node
->ie_IconX
+ node
->ie_AreaWidth
) - data
->icld_ViewX
;
6358 iconbox
.MinY
= node
->ie_IconY
- data
->icld_ViewY
;
6359 iconbox
.MaxY
= (node
->ie_IconY
+ node
->ie_AreaHeight
)- data
->icld_ViewY
;
6361 if ((node
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
) &&
6362 (click_x
>= iconbox
.MinX
) &&
6363 (click_x
< iconbox
.MaxX
) &&
6364 (click_y
>= iconbox
.MinY
) &&
6365 (click_y
< iconbox
.MaxY
))
6367 drop_target_node
= node
;
6373 if ((drop_target_node
!= NULL
) &&
6374 ((drop_target_node
->ie_IconListEntry
.type
== ST_SOFTLINK
) ||
6375 (drop_target_node
->ie_IconListEntry
.type
== ST_ROOT
) ||
6376 (drop_target_node
->ie_IconListEntry
.type
== ST_USERDIR
) ||
6377 (drop_target_node
->ie_IconListEntry
.type
== ST_LINKDIR
) ||
6378 (drop_target_node
->ie_IconListEntry
.type
== ST_FILE
) ||
6379 (drop_target_node
->ie_IconListEntry
.type
== ST_LINKFILE
)))
6381 if ((drop_target_node
->ie_IconListEntry
.type
!= ST_ROOT
) && (drop_target_node
->ie_IconListEntry
.type
!= ST_SOFTLINK
))
6385 int fulllen
= strlen(directory_path
) + strlen(drop_target_node
->ie_IconListEntry
.label
) + 2;
6387 if ((dragDropEvent
->drop_TargetPath
= AllocVec(fulllen
, MEMF_CLEAR
)) == NULL
)
6389 bug("[IconList] %s: Failed to allocate IconList_Drop_Event->drop_TargetPath Storage!\n", __PRETTY_FUNCTION__
);
6392 strcpy(dragDropEvent
->drop_TargetPath
, directory_path
);
6393 AddPart(dragDropEvent
->drop_TargetPath
, drop_target_node
->ie_IconListEntry
.label
, fulllen
);
6398 if ((dragDropEvent
->drop_TargetPath
= AllocVec(strlen(drop_target_node
->ie_IconListEntry
.label
) + 1, MEMF_CLEAR
)) == NULL
)
6400 bug("[IconList] %s: Failed to allocate IconList_Drop_Event->drop_TargetPath Storage!\n", __PRETTY_FUNCTION__
);
6403 strcpy(dragDropEvent
->drop_TargetPath
, drop_target_node
->ie_IconListEntry
.label
);
6406 #if defined(DEBUG_ILC_ICONDRAGDROP)
6407 D(bug("[IconList] %s: Target Entry Full Path = '%s'\n", __PRETTY_FUNCTION__
, dragDropEvent
->drop_TargetPath
));
6409 /* mark the Entry the selection was dropped on*/
6410 //drop_target_node->ie_Flags |= ICONENTRY_FLAG_SELECTED;
6411 //data->icld_UpdateMode = UPDATE_SINGLEENTRY;
6412 //data->update_entry = drop_target_node;
6413 //MUI_Redraw(obj,MADF_DRAWUPDATE);
6417 /* not dropped on entry -> get path of DESTINATION iconlist */
6418 /* Note: directory_path is NULL when dropped on Wanderer's desktop */
6419 if ((message
->obj
!= obj
) && directory_path
)
6421 #if defined(DEBUG_ILC_ICONDRAGDROP)
6422 D(bug("[IconList] %s: drop entry: Icons dropped in window '%s'\n", __PRETTY_FUNCTION__
, directory_path
));
6425 if ((dragDropEvent
->drop_TargetPath
= AllocVec(strlen(directory_path
) + 1, MEMF_CLEAR
)) != NULL
)
6427 strcpy(dragDropEvent
->drop_TargetPath
, directory_path
);
6431 #if defined(DEBUG_ILC_ICONDRAGDROP)
6432 D(bug("[IconList] %s: Failed to allocate IconList_Drop_Event->drop_TargetPath Storage!\n", __PRETTY_FUNCTION__
));
6437 else if (message
->obj
== obj
)
6439 #if defined(DEBUG_ILC_ICONDRAGDROP)
6440 D(bug("[IconList] %s: drop entry: Entry Move detected ..\n", __PRETTY_FUNCTION__
));
6443 SET(obj
, MUIA_IconList_IconsMoved
, (IPTR
)entry
); // Now notify
6444 MUI_Redraw(obj
,MADF_DRAWOBJECT
);
6445 DoMethod(obj
, MUIM_IconList_CoordsSort
);
6449 #if defined(DEBUG_ILC_ICONDRAGDROP)
6450 D(bug("[IconList] %s: Icons Dropped on Wanderer Desktop (unhandled)!\n", __PRETTY_FUNCTION__
));
6458 /* Create list of entries to copy .. */
6459 entry
= (IPTR
)MUIV_IconList_NextIcon_Start
;
6460 while (entry
!= (IPTR
)MUIV_IconList_NextIcon_End
)
6462 DoMethod(message
->obj
, MUIM_IconList_NextIcon
, MUIV_IconList_NextIcon_Selected
, (IPTR
)&entry
);
6464 if (entry
!= (IPTR
)MUIV_IconList_NextIcon_End
)
6466 struct IconList_Drop_SourceEntry
*sourceEntry
= NULL
;
6467 sourceEntry
= AllocMem(sizeof(struct IconList_Drop_SourceEntry
), MEMF_CLEAR
);
6468 if ((entry
->type
!= ST_ROOT
) && (entry
->type
!= ST_SOFTLINK
))
6473 GET(message
->obj
, MUIA_IconDrawerList_Drawer
, &path
);
6474 /* Properly expand the location incase it uses devices rather than volumes */
6477 tmp_dirlock
= Lock(path
, SHARED_LOCK
);
6480 if (NameFromLock(tmp_dirlock
, tmp_dirbuff
, 256))
6484 UnLock(tmp_dirlock
);
6487 if (strcasecmp(dragDropEvent
->drop_TargetPath
, path
) != 0)
6489 fulllen
= strlen(path
) + strlen(entry
->ile_IconEntry
->ie_IconNode
.ln_Name
) + 2;
6490 sourceEntry
->dropse_Node
.ln_Name
= AllocVec(fulllen
, MEMF_CLEAR
);
6491 strcpy(sourceEntry
->dropse_Node
.ln_Name
, path
);
6492 AddPart(sourceEntry
->dropse_Node
.ln_Name
, entry
->label
, fulllen
);
6493 #if defined(DEBUG_ILC_ICONDRAGDROP)
6494 D(bug("[IconList] %s: Source Entry (Full Path) = '%s'\n", __PRETTY_FUNCTION__
, sourceEntry
->dropse_Node
.ln_Name
));
6501 sourceEntry
->dropse_Node
.ln_Name
= AllocVec(strlen(entry
->label
) + 1, MEMF_CLEAR
);
6502 strcpy(sourceEntry
->dropse_Node
.ln_Name
, entry
->label
);
6503 #if defined(DEBUG_ILC_ICONDRAGDROP)
6504 D(bug("[IconList] %s: Source Entry = '%s'\n", __PRETTY_FUNCTION__
, sourceEntry
->dropse_Node
.ln_Name
));
6508 if ((sourceEntry
->dropse_Node
.ln_Name
!= NULL
) && (strcasecmp(dragDropEvent
->drop_TargetPath
, sourceEntry
->dropse_Node
.ln_Name
) != 0))
6511 AddTail(&dragDropEvent
->drop_SourceList
, &sourceEntry
->dropse_Node
);
6515 #if defined(DEBUG_ILC_ICONDRAGDROP)
6516 D(bug("[IconList] %s: Source == Dest, Skipping!\n", __PRETTY_FUNCTION__
));
6518 if ( sourceEntry
->dropse_Node
.ln_Name
) FreeVec(sourceEntry
->dropse_Node
.ln_Name
);
6519 FreeMem(sourceEntry
, sizeof(struct IconList_Drop_SourceEntry
));
6525 dragDropEvent
->drop_TargetObj
= (IPTR
)obj
;
6527 #if defined(DEBUG_ILC_ICONDRAGDROP)
6528 D(bug("[IconList] %s: Causing DROP notification..\n", __PRETTY_FUNCTION__
));
6530 SET(obj
, MUIA_IconList_IconsDropped
, (IPTR
)dragDropEvent
);
6531 DoMethod(obj
, MUIM_IconList_CoordsSort
);
6535 if (dragDropEvent
->drop_TargetPath
) FreeVec(dragDropEvent
->drop_TargetPath
);
6536 FreeMem(dragDropEvent
, sizeof(struct IconList_Drop_Event
));
6542 #if defined(DEBUG_ILC_ICONDRAGDROP)
6543 D(bug("[IconList] %s: BUG - DragDrop recieved with no source icons!\n", __PRETTY_FUNCTION__
));
6545 NNSET(obj
, MUIA_IconList_IconsDropped
, (IPTR
)NULL
);
6549 return DoSuperMethodA(CLASS
, obj
, (Msg
)message
);
6553 ///MUIM_UnselectAll()
6554 /**************************************************************************
6556 **************************************************************************/
6557 IPTR
IconList__MUIM_IconList_UnselectAll(struct IClass
*CLASS
, Object
*obj
, Msg message
)
6559 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
6560 struct Node
*node
= NULL
, *next_node
= NULL
;
6561 BOOL changed
= FALSE
;
6563 #if defined(DEBUG_ILC_FUNCS)
6564 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
6567 data
->icld_SelectionLastClicked
= NULL
;
6568 data
->icld_FocusIcon
= NULL
;
6569 #if defined(__AROS__)
6570 ForeachNodeSafe(&data
->icld_SelectionList
, node
, next_node
)
6572 Foreach_NodeSafe(&data
->icld_SelectionList
, node
, next_node
);
6575 struct IconEntry
*entry
= (struct IconEntry
*)((IPTR
)node
- ((IPTR
)&entry
->ie_SelectionNode
- (IPTR
)entry
));
6576 BOOL update_entry
= FALSE
;
6578 if (entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
6580 if (entry
->ie_Flags
& ICONENTRY_FLAG_SELECTED
)
6583 entry
->ie_Flags
&= ~ICONENTRY_FLAG_SELECTED
;
6584 update_entry
= TRUE
;
6586 if (entry
->ie_Flags
& ICONENTRY_FLAG_FOCUS
)
6588 entry
->ie_Flags
&= ~ICONENTRY_FLAG_FOCUS
;
6589 update_entry
= TRUE
;
6596 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
6597 data
->update_entry
= entry
;
6598 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
6603 SET(obj
, MUIA_IconList_SelectionChanged
, TRUE
);
6610 /**************************************************************************
6612 **************************************************************************/
6613 IPTR
IconList__MUIM_IconList_SelectAll(struct IClass
*CLASS
, Object
*obj
, Msg message
)
6615 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
6616 struct IconEntry
*node
= NULL
;
6617 BOOL changed
= FALSE
;
6619 #if defined(DEBUG_ILC_FUNCS)
6620 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
6623 node
= (struct IconEntry
*)GetHead(&data
->icld_IconList
);
6625 while (node
!= NULL
)
6627 if (node
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
6629 BOOL update_entry
= FALSE
;
6631 if (!(node
->ie_Flags
& ICONENTRY_FLAG_SELECTED
))
6633 AddTail(&data
->icld_SelectionList
, &node
->ie_SelectionNode
);
6634 node
->ie_Flags
|= ICONENTRY_FLAG_SELECTED
;
6635 update_entry
= TRUE
;
6637 data
->icld_SelectionLastClicked
= node
;
6639 else if (node
->ie_Flags
& ICONENTRY_FLAG_FOCUS
)
6641 node
->ie_Flags
&= ~ICONENTRY_FLAG_FOCUS
;
6642 update_entry
= TRUE
;
6648 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
6649 data
->update_entry
= node
;
6650 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
6653 node
= (struct IconEntry
*)GetSucc(&node
->ie_IconNode
);
6656 if ((data
->icld_SelectionLastClicked
) && (data
->icld_SelectionLastClicked
!= data
->icld_FocusIcon
))
6658 data
->icld_FocusIcon
= data
->icld_SelectionLastClicked
;
6659 if (!(data
->icld_FocusIcon
->ie_Flags
& ICONENTRY_FLAG_FOCUS
))
6661 data
->icld_FocusIcon
->ie_Flags
&= ~ICONENTRY_FLAG_FOCUS
;
6662 data
->icld_FocusIcon
->ie_Flags
|= ICONENTRY_FLAG_FOCUS
;
6663 data
->icld_UpdateMode
= UPDATE_SINGLEENTRY
;
6664 data
->update_entry
= data
->icld_FocusIcon
;
6665 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
6670 SET(obj
, MUIA_IconList_SelectionChanged
, TRUE
);
6676 ///IconList__MUIM_IconList_CoordsSort()
6677 IPTR
IconList__MUIM_IconList_CoordsSort(struct IClass
*CLASS
, Object
*obj
, struct MUIP_IconList_Sort
*message
)
6679 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
6681 struct IconEntry
*entry
= NULL
,
6684 struct List list_VisibleIcons
;
6685 struct List list_HiddenIcons
;
6688 perform a quick sort of the iconlist based on entry coords
6689 this method DOESNT cause any visual output.
6691 #if defined(DEBUG_ILC_FUNCS) && defined(DEBUG_ILC_ICONSORTING)
6692 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
6695 NewList((struct List
*)&list_VisibleIcons
);
6696 NewList((struct List
*)&list_HiddenIcons
);
6698 /*move list into our local list struct(s)*/
6699 while ((entry
= (struct IconEntry
*)RemTail((struct List
*)&data
->icld_IconList
)))
6701 if (entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
6702 AddHead((struct List
*)&list_VisibleIcons
, (struct Node
*)&entry
->ie_IconNode
);
6704 AddHead((struct List
*)&list_HiddenIcons
, (struct Node
*)&entry
->ie_IconNode
);
6707 while ((entry
= (struct IconEntry
*)RemTail((struct List
*)&list_VisibleIcons
)))
6709 if ((test_icon
= (struct IconEntry
*)GetTail(&data
->icld_IconList
)) != NULL
)
6711 while (test_icon
!= NULL
)
6713 if (((data
->icld_DisplayFlags
& ICONLIST_DISP_VERTICAL
) && (test_icon
->ie_IconX
> entry
->ie_IconX
)) ||
6714 (!(data
->icld_DisplayFlags
& ICONLIST_DISP_VERTICAL
) && (test_icon
->ie_IconY
> entry
->ie_IconY
)))
6716 test_icon
= (struct IconEntry
*)GetPred(&test_icon
->ie_IconNode
);
6722 while (test_icon
!= NULL
)
6724 if (((data
->icld_DisplayFlags
& ICONLIST_DISP_VERTICAL
) && (test_icon
->ie_IconY
> entry
->ie_IconY
)) ||
6725 (!(data
->icld_DisplayFlags
& ICONLIST_DISP_VERTICAL
) && (test_icon
->ie_IconX
> entry
->ie_IconX
)))
6727 test_icon
= (struct IconEntry
*)GetPred(&test_icon
->ie_IconNode
);
6732 Insert((struct List
*)&data
->icld_IconList
, (struct Node
*)&entry
->ie_IconNode
, (struct Node
*)&test_icon
->ie_IconNode
);
6735 AddTail((struct List
*)&data
->icld_IconList
, (struct Node
*)&entry
->ie_IconNode
);
6737 #if defined(DEBUG_ILC_ICONSORTING)
6738 D(bug("[IconList] %s: Done\n", __PRETTY_FUNCTION__
));
6741 while ((entry
= (struct IconEntry
*)RemTail((struct List
*)&list_HiddenIcons
)))
6743 AddTail((struct List
*)&data
->icld_IconList
, (struct Node
*)&entry
->ie_IconNode
);
6746 #if defined(DEBUG_ILC_ICONSORTING_DUMP)
6747 #if defined(__AROS__)
6748 ForeachNode(&data
->icld_IconList
, entry
)
6750 Foreach_Node(&data
->icld_IconList
, entry
);
6753 D(bug("[IconList] %s: %d %d '%s'\n", __PRETTY_FUNCTION__
, entry
->ie_IconX
, entry
->ie_IconY
, entry
->ie_IconListEntry
.label
));
6762 /**************************************************************************
6763 MUIM_Sort - sortsort
6764 **************************************************************************/
6765 IPTR
IconList__MUIM_IconList_Sort(struct IClass
*CLASS
, Object
*obj
, struct MUIP_IconList_Sort
*message
)
6767 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
6768 struct IconEntry
*entry
= NULL
,
6772 struct List list_VisibleIcons
,
6776 BOOL sortme
, enqueue
= FALSE
;
6777 int i
, visible_count
= 0;
6779 #if defined(DEBUG_ILC_FUNCS) && defined(DEBUG_ILC_ICONSORTING)
6780 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
6783 /* Reset incase view options have changed .. */
6784 data
->icld_IconAreaLargestWidth
= 0;
6785 data
->icld_IconAreaLargestHeight
= 0;
6786 data
->icld_IconLargestHeight
= 0;
6787 data
->icld_LabelLargestHeight
= 0;
6789 if ((data
->icld_SortFlags
& MUIV_IconList_Sort_MASK
) != 0)
6791 #if defined(DEBUG_ILC_ICONSORTING)
6792 D(bug("[IconList] %s: Sorting (Flags %x)\n", __PRETTY_FUNCTION__
, (data
->icld_SortFlags
& MUIV_IconList_Sort_MASK
)));
6794 NewList((struct List
*)&list_VisibleIcons
);
6795 NewList((struct List
*)&list_SortedIcons
);
6796 NewList((struct List
*)&list_HiddenIcons
);
6798 /*move list into our local list struct(s)*/
6799 while ((entry
= (struct IconEntry
*)RemTail((struct List
*)&data
->icld_IconList
)))
6801 if (entry
->ie_DiskObj
)
6803 if (entry
->ie_IconX
!= entry
->ie_DiskObj
->do_CurrentX
)
6805 entry
->ie_IconX
= entry
->ie_DiskObj
->do_CurrentX
;
6806 if ((data
->icld_SortFlags
& MUIV_IconList_Sort_MASK
) == 0)
6807 entry
->ie_Flags
|= ICONENTRY_FLAG_NEEDSUPDATE
;
6809 if (entry
->ie_IconY
!= entry
->ie_DiskObj
->do_CurrentY
)
6811 entry
->ie_IconY
= entry
->ie_DiskObj
->do_CurrentY
;
6812 if ((data
->icld_SortFlags
& MUIV_IconList_Sort_MASK
) == 0)
6813 entry
->ie_Flags
|= ICONENTRY_FLAG_NEEDSUPDATE
;
6817 if (!(entry
->ie_Flags
& ICONENTRY_FLAG_HASICON
))
6819 if (data
->icld_DisplayFlags
& ICONLIST_DISP_SHOWINFO
)
6821 if (entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
6823 entry
->ie_Flags
&= ~(ICONENTRY_FLAG_VISIBLE
|ICONENTRY_FLAG_NEEDSUPDATE
);
6826 else if (!(entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
))
6828 entry
->ie_Flags
|= (ICONENTRY_FLAG_VISIBLE
|ICONENTRY_FLAG_NEEDSUPDATE
);
6833 if (!(entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
))
6835 entry
->ie_Flags
|= (ICONENTRY_FLAG_VISIBLE
|ICONENTRY_FLAG_NEEDSUPDATE
);
6839 /* Now we have fixed visibility lets dump them into the correct list for sorting */
6840 if (entry
->ie_Flags
& ICONENTRY_FLAG_VISIBLE
)
6842 if(entry
->ie_AreaWidth
> data
->icld_IconAreaLargestWidth
) data
->icld_IconAreaLargestWidth
= entry
->ie_AreaWidth
;
6843 if(entry
->ie_AreaHeight
> data
->icld_IconAreaLargestHeight
) data
->icld_IconAreaLargestHeight
= entry
->ie_AreaHeight
;
6844 if(entry
->ie_IconHeight
> data
->icld_IconLargestHeight
) data
->icld_IconLargestHeight
= entry
->ie_IconHeight
;
6845 if((entry
->ie_AreaHeight
- entry
->ie_IconHeight
) > data
->icld_LabelLargestHeight
) data
->icld_LabelLargestHeight
= entry
->ie_AreaHeight
- entry
->ie_IconHeight
;
6847 if (((data
->icld_SortFlags
& MUIV_IconList_Sort_MASK
) == 0) && (entry
->ie_IconX
== NO_ICON_POSITION
))
6848 AddTail((struct List
*)&list_VisibleIcons
, (struct Node
*)&entry
->ie_IconNode
);
6850 AddHead((struct List
*)&list_VisibleIcons
, (struct Node
*)&entry
->ie_IconNode
);
6855 if (entry
->ie_Flags
& ICONENTRY_FLAG_SELECTED
)
6857 Remove(&entry
->ie_SelectionNode
);
6859 entry
->ie_Flags
&= ~(ICONENTRY_FLAG_SELECTED
|ICONENTRY_FLAG_FOCUS
);
6860 if (data
->icld_SelectionLastClicked
== entry
) data
->icld_SelectionLastClicked
= NULL
;
6861 if (data
->icld_FocusIcon
== entry
) data
->icld_FocusIcon
= data
->icld_SelectionLastClicked
;
6862 AddHead((struct List
*)&list_HiddenIcons
, (struct Node
*)&entry
->ie_IconNode
);
6866 /* Copy each visible entry back to the main list, sorting as we go*/
6868 while ((entry
= (struct IconEntry
*)RemHead((struct List
*)&list_VisibleIcons
)))
6870 icon1
= (struct IconEntry
*)GetHead(&list_SortedIcons
);
6875 if (visible_count
> 1)
6877 // D(bug(" - %s %s %s %i\n",entry->ie_IconListEntry.label,entry->ie_TxtBuf_DATE,entry->ie_TxtBuf_TIME,entry->ie_FileInfoBlock->fib_Size));
6881 if(((icon1
->ie_IconListEntry
.type
== ST_ROOT
) || (icon1
->ie_IconListEntry
.type
== ST_LINKDIR
) || (icon1
->ie_IconListEntry
.type
== ST_LINKFILE
))
6882 || (data
->icld_SortFlags
& MUIV_IconList_Sort_DrawersMixed
))
6884 /*volume list or drawers mixed*/
6890 if ((icon1
->ie_IconListEntry
.type
== ST_USERDIR
) && (entry
->ie_IconListEntry
.type
== ST_USERDIR
))
6896 if ((icon1
->ie_IconListEntry
.type
!= ST_USERDIR
) && (entry
->ie_IconListEntry
.type
!= ST_USERDIR
))
6900 /* we are the first drawer to arrive or we need to insert ourselves
6901 due to being sorted to the end of the drawers*/
6903 if ((!icon2
|| icon2
->ie_IconListEntry
.type
== ST_USERDIR
) &&
6904 (entry
->ie_IconListEntry
.type
== ST_USERDIR
) &&
6905 (icon1
->ie_IconListEntry
.type
!= ST_USERDIR
))
6907 // D(bug("force %s\n",entry->ie_IconListEntry.label));
6918 if ((data
->icld_SortFlags
& MUIV_IconList_Sort_MASK
) == MUIV_IconList_Sort_ByDate
)
6921 i
= CompareDates((const struct DateStamp
*)&entry
->ie_FileInfoBlock
->fib_Date
,(const struct DateStamp
*)&icon1
->ie_FileInfoBlock
->fib_Date
);
6923 else if ((data
->icld_SortFlags
& MUIV_IconList_Sort_MASK
) == MUIV_IconList_Sort_BySize
)
6925 /* Sort by Size .. */
6926 i
= entry
->ie_FileInfoBlock
->fib_Size
- icon1
->ie_FileInfoBlock
->fib_Size
;
6928 else if (((data
->icld_SortFlags
& MUIV_IconList_Sort_MASK
) == MUIV_IconList_Sort_MASK
) && ((entry
->ie_IconListEntry
.type
== ST_FILE
) || (entry
->ie_IconListEntry
.type
== ST_USERDIR
)))
6930 /* Sort by Type .. */
6931 #warning "TODO: Sort icons based on type using datatypes"
6936 ((data
->icld_SortFlags
& MUIV_IconList_Sort_MASK
) == MUIV_IconList_Sort_MASK
) ||
6937 ((data
->icld_SortFlags
& MUIV_IconList_Sort_MASK
) == MUIV_IconList_Sort_ByName
) ||
6938 (entry
->ie_IconX
== NO_ICON_POSITION
)
6941 /* Sort by Name .. */
6942 i
= Stricmp(entry
->ie_IconListEntry
.label
, icon1
->ie_IconListEntry
.label
);
6943 if ((data
->icld_SortFlags
& MUIV_IconList_Sort_MASK
) == MUIV_IconList_Sort_MASK
)
6949 #warning "TODO: Implement default coord sorting.."
6953 if (data
->icld_SortFlags
& MUIV_IconList_Sort_Reverse
)
6962 icon1
= (struct IconEntry
*)GetSucc(&icon1
->ie_IconNode
);
6965 Insert((struct List
*)&list_SortedIcons
, (struct Node
*)&entry
->ie_IconNode
, (struct Node
*)&icon2
->ie_IconNode
);
6969 /* Quickly resort based on node priorities .. */
6970 while ((entry
= (struct IconEntry
*)RemHead((struct List
*)&list_SortedIcons
)))
6972 Enqueue((struct List
*)&data
->icld_IconList
, (struct Node
*)&entry
->ie_IconNode
);
6977 while ((entry
= (struct IconEntry
*)RemHead((struct List
*)&list_SortedIcons
)))
6979 AddTail((struct List
*)&data
->icld_IconList
, (struct Node
*)&entry
->ie_IconNode
);
6985 #if defined(DEBUG_ILC_ICONSORTING)
6986 D(bug("[IconList] %s: Coord Sorting\n", __PRETTY_FUNCTION__
));
6988 DoMethod(obj
, MUIM_IconList_CoordsSort
);
6991 DoMethod(obj
, MUIM_IconList_PositionIcons
);
6992 MUI_Redraw(obj
, MADF_DRAWOBJECT
);
6994 if ((data
->icld_SortFlags
& MUIV_IconList_Sort_MASK
) != 0)
6996 DoMethod(obj
, MUIM_IconList_CoordsSort
);
6998 /* leave hidden icons on a seperate list to speed up normal list parsing ? */
6999 while ((entry
= (struct IconEntry
*)RemHead((struct List
*)&list_HiddenIcons
)))
7001 AddTail((struct List
*)&data
->icld_IconList
, (struct Node
*)&entry
->ie_IconNode
);
7004 SET(obj
, MUIA_IconList_Changed
, TRUE
);
7010 ///MUIM_DragReport()
7011 /**************************************************************************
7012 MUIM_DragReport. Since MUI doesn't change the drop object if the dragged
7013 object is moved above another window (while still in the bounds of the
7014 orginal drop object) we must do it here manually to be compatible with
7015 MUI. Maybe Zune should fix this bug somewhen.
7016 **************************************************************************/
7017 IPTR
IconList__MUIM_DragReport(struct IClass
*CLASS
, Object
*obj
, struct MUIP_DragReport
*message
)
7019 struct Window
*wnd
= _window(obj
);
7020 struct Layer
*l
= NULL
;
7022 #if defined(DEBUG_ILC_FUNCS)
7023 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
7026 l
= WhichLayer(&wnd
->WScreen
->LayerInfo
, wnd
->LeftEdge
+ message
->x
, wnd
->TopEdge
+ message
->y
);
7028 if (l
!= wnd
->WLayer
) return MUIV_DragReport_Abort
;
7030 return MUIV_DragReport_Continue
;
7034 ///MUIM_IconList_UnknownDropDestination()
7035 /**************************************************************************
7036 MUIM_IconList_UnknownDropDestination
7037 **************************************************************************/
7038 IPTR
IconList__MUIM_UnknownDropDestination(struct IClass
*CLASS
, Object
*obj
, struct MUIP_UnknownDropDestination
*message
)
7040 #if defined(DEBUG_ILC_FUNCS)
7041 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
7043 D(bug("[IconList] %s: icons dropped on custom window \n", __PRETTY_FUNCTION__
));
7045 SET(obj
, MUIA_IconList_AppWindowDrop
, (IPTR
)message
); /* Now notify */
7051 ///MUIM_IconList_MakeEntryVisible()
7052 /**************************************************************************
7053 Move the visible area so that the selected entry becomes visible ..
7054 **************************************************************************/
7055 IPTR
IconList__MUIM_IconList_MakeEntryVisible(struct IClass
*CLASS
, Object
*obj
, struct MUIP_IconList_MakeEntryVisible
*message
)
7057 struct IconList_DATA
*data
= INST_DATA(CLASS
, obj
);
7058 BOOL viewmoved
= FALSE
;
7059 struct Rectangle iconrect
, viewrect
;
7061 #if defined(DEBUG_ILC_FUNCS)
7062 D(bug("[IconList]: %s()\n", __PRETTY_FUNCTION__
));
7065 viewrect
.MinX
= data
->icld_ViewX
;
7066 viewrect
.MaxX
= data
->icld_ViewX
+ data
->icld_AreaWidth
;
7067 viewrect
.MinY
= data
->icld_ViewY
;
7068 viewrect
.MaxY
= data
->icld_ViewY
+ data
->icld_AreaHeight
;
7070 IconList_GetIconAreaRectangle(obj
, data
, message
->entry
, &iconrect
);
7072 if (!(RectAndRect(&viewrect
, &iconrect
)))
7075 if (message
->entry
->ie_IconX
< data
->icld_ViewX
)
7076 data
->icld_ViewX
= message
->entry
->ie_IconX
;
7077 else if (message
->entry
->ie_IconX
> (data
->icld_ViewX
+ data
->icld_AreaWidth
))
7078 data
->icld_ViewX
= (message
->entry
->ie_IconX
+ message
->entry
->ie_AreaWidth
) - data
->icld_AreaWidth
;
7080 if (message
->entry
->ie_IconY
< data
->icld_ViewY
)
7081 data
->icld_ViewY
= message
->entry
->ie_IconX
;
7082 else if (message
->entry
->ie_IconY
> (data
->icld_ViewY
+ data
->icld_AreaHeight
))
7083 data
->icld_ViewY
= (message
->entry
->ie_IconY
+ message
->entry
->ie_AreaHeight
) - data
->icld_AreaHeight
;
7088 D(bug("[IconList]: %s: call SetSuperAttrs()\n", __PRETTY_FUNCTION__
));
7089 SetSuperAttrs(CLASS
, obj
, MUIA_Virtgroup_Left
, data
->icld_ViewX
,
7090 MUIA_Virtgroup_Top
, data
->icld_ViewY
,
7093 D(bug("[IconList]: %s: call SetAttrs()\n", __PRETTY_FUNCTION__
));
7094 SetAttrs(obj
, MUIA_Virtgroup_Left
, data
->icld_ViewX
,
7095 MUIA_Virtgroup_Top
, data
->icld_ViewY
,
7098 D(bug("[IconList]: %s: call MUI_Redraw()\n", __PRETTY_FUNCTION__
));
7099 MUI_Redraw(obj
,MADF_DRAWOBJECT
);
7104 #if defined(WANDERER_BUILTIN_ICONLIST)
7105 BOOPSI_DISPATCHER(IPTR
,IconList_Dispatcher
, CLASS
, obj
, message
)
7107 #if defined(__AROS__)
7108 switch (message
->MethodID
)
7110 struct IClass
*CLASS
= cl
;
7113 switch (msg
->MethodID
)
7116 case OM_NEW
: return IconList__OM_NEW(CLASS
, obj
, (struct opSet
*)message
);
7117 case OM_DISPOSE
: return IconList__OM_DISPOSE(CLASS
, obj
, message
);
7118 case OM_SET
: return IconList__OM_SET(CLASS
, obj
, (struct opSet
*)message
);
7119 case OM_GET
: return IconList__OM_GET(CLASS
, obj
, (struct opGet
*)message
);
7121 case MUIM_Family_AddTail
: return IconList__MUIM_Family_AddTail(CLASS
, obj
, (APTR
)message
);
7122 case MUIM_Family_AddHead
: return IconList__MUIM_Family_AddHead(CLASS
, obj
, (APTR
)message
);
7124 case MUIM_Family_Remove
: return IconList__MUIM_Family_Remove(CLASS
, obj
, (APTR
)message
);
7126 case MUIM_Setup
: return IconList__MUIM_Setup(CLASS
, obj
, (struct MUIP_Setup
*)message
);
7128 case MUIM_Show
: return IconList__MUIM_Show(CLASS
,obj
, (struct MUIP_Show
*)message
);
7129 case MUIM_Hide
: return IconList__MUIM_Hide(CLASS
,obj
, (struct MUIP_Hide
*)message
);
7130 case MUIM_Cleanup
: return IconList__MUIM_Cleanup(CLASS
, obj
, (struct MUIP_Cleanup
*)message
);
7131 case MUIM_AskMinMax
: return IconList__MUIM_AskMinMax(CLASS
, obj
, (struct MUIP_AskMinMax
*)message
);
7132 case MUIM_Draw
: return IconList__MUIM_Draw(CLASS
, obj
, (struct MUIP_Draw
*)message
);
7133 #if defined(__AROS__)
7134 case MUIM_Layout
: return IconList__MUIM_Layout(CLASS
, obj
, (struct MUIP_Layout
*)message
);
7136 case MUIM_HandleEvent
: return IconList__MUIM_HandleEvent(CLASS
, obj
, (struct MUIP_HandleEvent
*)message
);
7137 case MUIM_CreateDragImage
: return IconList__MUIM_CreateDragImage(CLASS
, obj
, (APTR
)message
);
7138 case MUIM_DeleteDragImage
: return IconList__MUIM_DeleteDragImage(CLASS
, obj
, (APTR
)message
);
7139 case MUIM_DragQuery
: return IconList__MUIM_DragQuery(CLASS
, obj
, (APTR
)message
);
7140 case MUIM_DragReport
: return IconList__MUIM_DragReport(CLASS
, obj
, (APTR
)message
);
7141 case MUIM_DragDrop
: return IconList__MUIM_DragDrop(CLASS
, obj
, (APTR
)message
);
7142 #if defined(__AROS__)
7143 case MUIM_UnknownDropDestination
: return IconList__MUIM_UnknownDropDestination(CLASS
, obj
, (APTR
)message
);
7145 case MUIM_IconList_Update
: return IconList__MUIM_IconList_Update(CLASS
, obj
, (APTR
)message
);
7146 case MUIM_IconList_Clear
: return IconList__MUIM_IconList_Clear(CLASS
, obj
, (APTR
)message
);
7147 case MUIM_IconList_RethinkDimensions
: return IconList__MUIM_IconList_RethinkDimensions(CLASS
, obj
, (APTR
)message
);
7148 case MUIM_IconList_CreateEntry
: return IconList__MUIM_IconList_CreateEntry(CLASS
, obj
, (APTR
)message
);
7149 case MUIM_IconList_UpdateEntry
: return IconList__MUIM_IconList_UpdateEntry(CLASS
, obj
, (APTR
)message
);
7150 case MUIM_IconList_DestroyEntry
: return IconList__MUIM_IconList_DestroyEntry(CLASS
, obj
, (APTR
)message
);
7151 case MUIM_IconList_DrawEntry
: return IconList__MUIM_IconList_DrawEntry(CLASS
, obj
, (APTR
)message
);
7152 case MUIM_IconList_DrawEntryLabel
: return IconList__MUIM_IconList_DrawEntryLabel(CLASS
, obj
, (APTR
)message
);
7153 case MUIM_IconList_NextIcon
: return IconList__MUIM_IconList_NextIcon(CLASS
, obj
, (APTR
)message
);
7154 case MUIM_IconList_GetIconPrivate
: return IconList__MUIM_IconList_GetIconPrivate(CLASS
, obj
, (APTR
)message
);
7155 case MUIM_IconList_UnselectAll
: return IconList__MUIM_IconList_UnselectAll(CLASS
, obj
, (APTR
)message
);
7156 case MUIM_IconList_Sort
: return IconList__MUIM_IconList_Sort(CLASS
, obj
, (APTR
)message
);
7157 case MUIM_IconList_CoordsSort
: return IconList__MUIM_IconList_CoordsSort(CLASS
, obj
, (APTR
)message
);
7158 case MUIM_IconList_PositionIcons
: return IconList__MUIM_IconList_PositionIcons(CLASS
, obj
, (APTR
)message
);
7159 case MUIM_IconList_SelectAll
: return IconList__MUIM_IconList_SelectAll(CLASS
, obj
, (APTR
)message
);
7160 case MUIM_IconList_MakeEntryVisible
: return IconList__MUIM_IconList_MakeEntryVisible(CLASS
, obj
, (APTR
)message
);
7163 return DoSuperMethodA(CLASS
, obj
, message
);
7165 BOOPSI_DISPATCHER_END
7167 #if defined(__AROS__)
7168 /* Class descriptor. */
7169 const struct __MUIBuiltinClass _MUI_IconList_desc
= {
7172 sizeof(struct IconList_DATA
),
7173 (void*)IconList_Dispatcher
7176 #endif /* WANDERER_BUILTIN_ICONLIST */
7178 #if !defined(__AROS__)
7179 struct MUI_CustomClass
*initIconListClass(void)
7181 return (struct MUI_CustomClass
*) MUI_CreateCustomClass(NULL
, MUIC_Area
, NULL
, sizeof(struct IconList_DATA
), ENTRY(IconList_Dispatcher
));