2 Copyright © 2002-2004, The AROS Development Team. All rights reserved.
6 #define MUIMASTER_YES_INLINE_STDARG
8 #include <exec/types.h>
14 #include <dos/datetime.h>
15 #include <intuition/gadgetclass.h>
16 #include <intuition/icclass.h>
17 #include <proto/exec.h>
18 #include <proto/dos.h>
19 #include <proto/intuition.h>
20 #include <proto/muimaster.h>
21 #include <proto/utility.h>
22 #include <proto/graphics.h>
23 #include <proto/cybergraphics.h>
24 #include <clib/alib_protos.h>
26 #include <aros/debug.h>
28 /* the following should go in a single include file which then only
29 ** constits of the public constants and members. Actually this is easiey
32 #include <libraries/mui.h>
34 #include "../../workbench/system/Wanderer/Classes/iconlist_attributes.h"
35 #include "../../workbench/system/Wanderer/Classes/iconlist.h"
37 struct Library
*MUIMasterBase
;
40 struct MUI_CustomClass
*CL_TextIconList
, *CL_TextIconListview
;
42 /*================== TextIconList class =====================*/
46 #define MIN_COLUMN_WIDTH 10
48 #define COLUMN_ALIGN_LEFT 0
49 #define COLUMN_ALIGN_CENTER 1
50 #define COLUMN_ALIGN_RIGHT 2
52 #define LINE_SPACING_TOP 2
53 #define LINE_SPACING_BOTTOM 2
54 #define LINE_EXTRAHEIGHT (LINE_SPACING_TOP + LINE_SPACING_BOTTOM)
56 #define LINE_SPACING_LEFT 1
57 #define LINE_SPACING_RIGHT 1
58 #define LINE_EXTRAWIDTH (LINE_SPACING_LEFT + LINE_SPACING_RIGHT)
60 #define ENTRY_SPACING_LEFT 1
61 #define ENTRY_SPACING_RIGHT 1
62 #define ENTRY_EXTRAWIDTH (ENTRY_SPACING_LEFT + ENTRY_SPACING_RIGHT)
64 #define HEADERLINE_SPACING_TOP 3
65 #define HEADERLINE_SPACING_BOTTOM 3
66 #define HEADERLINE_EXTRAHEIGHT (HEADERLINE_SPACING_TOP + HEADERLINE_SPACING_BOTTOM)
68 #define HEADERLINE_SPACING_LEFT 1
69 #define HEADERLINE_SPACING_RIGHT 1
70 #define HEADERLINE_EXTRAWIDTH (HEADERLINE_SPACING_LEFT + HEADERLINE_SPACING_RIGHT)
72 #define HEADERENTRY_SPACING_LEFT 4
73 #define HEADERENTRY_SPACING_RIGHT 4
74 #define HEADERENTRY_EXTRAWIDTH (HEADERENTRY_SPACING_LEFT + HEADERENTRY_SPACING_RIGHT)
76 #define AUTOSCROLL_MILLIS 20
81 struct MinNode selection_node
;
82 struct FileInfoBlock fib
;
83 LONG field_width
[NUM_COLUMNS
];
84 UBYTE datebuf
[LEN_DATSTRING
];
85 UBYTE timebuf
[LEN_DATSTRING
];
99 #define COLOR_COLUMN_BACKGROUND 0
100 #define COLOR_COLUMN_BACKGROUND_SORTED 1
101 #define COLOR_COLUMN_BACKGROUND_LASSO 2
102 #define COLOR_COLUMN_BACKGROUND_LASSO_SORTED 3
104 #define COLOR_SELECTED_BACKGROUND 4
105 #define COLOR_SELECTED_BACKGROUND_SORTED 5
106 #define COLOR_SELECTED_BACKGROUND_LASSO 6
107 #define COLOR_SELECTED_BACKGROUND_LASSO_SORTED 7
111 static const ULONG rgb_colors
[NUM_COLORS
] =
123 static const ULONG pen_colors
[NUM_COLORS
] =
135 struct TextIconList_DATA
139 LONG view_width
, view_height
;
140 LONG width
, height
, lineheight
, headerheight
;
142 LONG update_scrolldx
;
143 LONG update_scrolldy
;
145 struct MinList entries_list
;
146 struct MinList selection_list
;
147 struct RastPort temprp
;
148 struct Rectangle view_rect
;
149 struct Rectangle header_rect
;
150 struct Rectangle lasso_rect
, old_lasso_rect
;
151 struct Rectangle
*update_rect1
, *update_rect2
;
152 struct MyColor colors
[NUM_COLORS
];
156 LONG click_x
, click_y
, click_column
;
157 LONG column_pos
[NUM_COLUMNS
];
158 LONG column_maxwidth
[NUM_COLUMNS
];
159 LONG column_width
[NUM_COLUMNS
];
160 BYTE column_visible
[NUM_COLUMNS
];
161 BYTE column_align
[NUM_COLUMNS
];
162 BYTE column_clickable
[NUM_COLUMNS
];
163 BYTE column_sortable
[NUM_COLUMNS
];
164 STRPTR column_title
[NUM_COLUMNS
];
176 struct MUI_EventHandlerNode ehn
;
177 struct MUI_InputHandlerNode thn
;
180 #define UPDATE_SCROLL 2
181 #define UPDATE_DIRTY_ENTRIES 3
183 #define UPDATE_HEADER 5
185 #define INPUTSTATE_NONE 0
186 #define INPUTSTATE_PAN 1
187 #define INPUTSTATE_COL_RESIZE 2
188 #define INPUTSTATE_COL_HEADER_CLICK 3
189 #define INPUTSTATE_LASSO 4
191 #define MUIB_TextIconList (MUIB_AROS | 0x00000700)
193 #define MUIA_TextIconList_Left (MUIB_TextIconList | 0x00000000)
194 #define MUIA_TextIconList_Top (MUIB_TextIconList | 0x00000001)
195 #define MUIA_TextIconList_Width (MUIB_TextIconList | 0x00000002)
196 #define MUIA_TextIconList_Height (MUIB_TextIconList | 0x00000003)
197 #define MUIA_TextIconList_VisWidth (MUIB_TextIconList | 0x00000004)
198 #define MUIA_TextIconList_VisHeight (MUIB_TextIconList | 0x00000005)
200 #define MUIM_TextIconList_Clear (MUIB_TextIconList | 0x00000000)
201 #define MUIM_TextIconList_Add (MUIB_TextIconList | 0x00000001)
202 #define MUIM_TextIconList_AutoScroll (MUIB_TextIconList | 0x00000002)
204 struct MUIP_TextIconList_Clear
{STACKULONG MethodID
;};
205 struct MUIP_TextIconList_Add
{STACKULONG MethodID
; struct FileInfoBlock
*fib
;};
207 #define TextIconListObject BOOPSIOBJMACRO_START(CL_TextIconList->mcc_Class)
212 #define INDEX_PROTECTION 2
215 #define INDEX_COMMENT 5
217 #define SORT_DRAWERS_FIRST 0
218 #define SORT_DRAWERS_MIXED 1
219 #define SORT_DRAWERS_LAST 2
221 #define SORT_DIRECTION_UP 0
222 #define SORT_DIRECTION_DOWN 1
224 #define SORT_BY_NAME 0
225 #define SORT_BY_DATE 1
226 #define SORT_BY_SIZE 2
228 static STRPTR
GetTextIconEntryText(struct TextIconList_DATA
*data
, struct TextIconEntry
*entry
,
236 ret
= entry
->fib
.fib_FileName
;
240 ret
= entry
->sizebuf
;
244 ret
= entry
->datebuf
;
248 ret
= entry
->timebuf
;
252 ret
= entry
->fib
.fib_Comment
;
255 case INDEX_PROTECTION
:
256 ret
= entry
->protbuf
;
263 static STRPTR
GetTextIconHeaderText(struct TextIconList_DATA
*data
, LONG index
)
267 ret
= data
->column_title
[index
];
292 case INDEX_PROTECTION
:
300 static void CalcWidth(struct TextIconList_DATA
*data
)
302 LONG i
, width
= LINE_EXTRAWIDTH
;
304 for(i
= 0; i
< NUM_COLUMNS
; i
++)
306 if (data
->column_visible
[i
])
308 width
+= data
->column_width
[i
];
315 static void CalcEntryDimension(struct TextIconList_DATA
*data
, struct TextIconEntry
*entry
)
321 for (i
= 0; i
< NUM_COLUMNS
; i
++)
323 text
= GetTextIconEntryText(data
, entry
, i
);
324 len
= TextLength(&data
->temprp
, text
, strlen(text
));
326 entry
->field_width
[i
] = len
+ ENTRY_EXTRAWIDTH
;
328 if (entry
->field_width
[i
] > data
->column_maxwidth
[i
])
330 data
->column_maxwidth
[i
] = entry
->field_width
[i
];
336 static void CalcAllEntryDimensions(struct TextIconList_DATA
*data
)
338 struct TextIconEntry
*entry
;
340 ForeachNode(&data
->entries_list
, entry
)
342 CalcEntryDimension(data
, entry
);
346 static void RecalcColumnMaxWidths(struct TextIconList_DATA
*data
)
348 struct TextIconEntry
*entry
;
351 for(i
= 0; i
< NUM_COLUMNS
; i
++)
353 data
->column_maxwidth
[i
] = 0;
356 ForeachNode(&data
->entries_list
, entry
)
358 for(i
= 0; i
< NUM_COLUMNS
; i
++)
360 if (entry
->field_width
[i
] > data
->column_maxwidth
[i
])
362 data
->column_maxwidth
[i
] = entry
->field_width
[i
];
368 static LONG
FirstVisibleColumnNumber(struct TextIconList_DATA
*data
)
373 for(i
= 0; i
< NUM_COLUMNS
; i
++)
375 LONG index
= data
->column_pos
[i
];
377 if (data
->column_visible
[index
])
387 static LONG
LastVisibleColumnNumber(struct TextIconList_DATA
*data
)
392 for(i
= 0; i
< NUM_COLUMNS
; i
++)
394 LONG index
= data
->column_pos
[i
];
396 if (data
->column_visible
[index
])
406 static struct TextIconEntry
*GetEntryFromIndex(struct TextIconList_DATA
*data
, LONG index
)
408 struct TextIconEntry
*node
;
409 struct TextIconEntry
*retval
= 0;
412 if (index
>= 0 && index
< data
->num_entries
)
414 ForeachNode(&data
->entries_list
, node
)
428 static LONG
LineUnderMouse(struct TextIconList_DATA
*data
, LONG mx
, LONG my
)
432 if ((mx
>= data
->view_rect
.MinX
) &&
433 (my
>= data
->view_rect
.MinY
) &&
434 (mx
<= data
->view_rect
.MaxX
) &&
435 (my
<= data
->view_rect
.MaxY
))
437 index
= (my
- data
->view_rect
.MinY
+ data
->view_y
) / data
->lineheight
;
439 if ((index
< 0) || (index
>= data
->num_entries
)) index
= -1;
445 static LONG
ColumnUnderMouse(struct TextIconList_DATA
*data
, LONG mx
, LONG my
)
449 if ((mx
>= data
->view_rect
.MinX
) &&
450 (my
>= data
->view_rect
.MinY
- data
->headerheight
) &&
451 (mx
<= data
->view_rect
.MaxX
) &&
452 (my
<= data
->view_rect
.MaxY
))
454 LONG x
= data
->view_rect
.MinX
- data
->view_x
+ LINE_SPACING_LEFT
;
457 for(i
= 0; i
< NUM_COLUMNS
; i
++)
459 LONG index
= data
->column_pos
[i
];
461 if (!data
->column_visible
[index
]) continue;
463 w
= data
->column_width
[index
];
465 if ((mx
>= x
) && (mx
< x
+ w
))
478 static LONG
ColumnHeaderUnderMouse(struct TextIconList_DATA
*data
, LONG mx
, LONG my
)
482 if (data
->show_header
&&
483 (my
>= data
->header_rect
.MinY
) &&
484 (my
<= data
->header_rect
.MaxY
))
486 col
= ColumnUnderMouse(data
, mx
, my
);
492 static LONG
ColumnResizeHandleUnderMouse(struct TextIconList_DATA
*data
, LONG mx
, LONG my
)
496 if ((mx
>= data
->view_rect
.MinX
) &&
497 (my
>= data
->view_rect
.MinY
- data
->headerheight
) &&
498 (mx
<= data
->view_rect
.MaxX
) &&
499 (my
<= data
->view_rect
.MaxY
))
501 LONG x
= data
->view_rect
.MinX
- data
->view_x
+ LINE_SPACING_LEFT
;
504 for(i
= 0; i
< NUM_COLUMNS
; i
++)
506 LONG index
= data
->column_pos
[i
];
508 if (!data
->column_visible
[index
]) continue;
510 w
= data
->column_width
[index
];
512 if (abs(mx
- (x
+ w
- 1)) <= 4)
525 static BOOL
GetColumnCoords(struct TextIconList_DATA
*data
, LONG index
, LONG
*x1
, LONG
*x2
)
529 LONG x
= data
->view_rect
.MinX
- data
->view_x
+ LINE_SPACING_LEFT
;
530 LONG firstvis
, lastvis
;
532 firstvis
= FirstVisibleColumnNumber(data
);
533 lastvis
= LastVisibleColumnNumber(data
);
535 for(i
= 0; i
< NUM_COLUMNS
; i
++)
537 LONG idx
= data
->column_pos
[i
];
540 if (!data
->column_visible
[idx
]) continue;
542 w
= data
->column_width
[idx
];
547 *x1
= x
- ((i
== firstvis
) ? LINE_SPACING_LEFT
: 0);
548 *x2
= x
+ w
- 1 + ((i
== lastvis
) ? LINE_SPACING_RIGHT
: 0);
558 static LONG
CompareNodes(struct TextIconList_DATA
*data
, struct TextIconEntry
*node1
, struct TextIconEntry
*node2
)
560 LONG pri1
= (node1
->fib
.fib_DirEntryType
> 0) ? 1 : 0;
561 LONG pri2
= (node2
->fib
.fib_DirEntryType
> 0) ? 1 : 0;
562 LONG diff
= (pri2
- pri1
) * -(data
->sort_dirs
- 1);
566 switch(data
->sort_column
)
570 diff
= CompareDates((const struct DateStamp
*)&node2
->fib
.fib_Date
,
571 (const struct DateStamp
*)&node1
->fib
.fib_Date
);
576 if (node1
->fib
.fib_Size
< node2
->fib
.fib_Size
)
580 else if (node1
->fib
.fib_Size
> node2
->fib
.fib_Size
)
588 diff
= Stricmp(node1
->fib
.fib_FileName
, node2
->fib
.fib_FileName
);
593 if (data
->sort_direction
== SORT_DIRECTION_DOWN
) diff
= -diff
;
599 static void SortInNode(struct TextIconList_DATA
*data
, struct List
*list
, struct Node
*node
,
600 LONG (*compare
)(APTR data
, APTR node1
, APTR node2
))
602 struct Node
*prevnode
= NULL
;
603 struct Node
*checknode
;
605 ForeachNode(list
, checknode
)
607 if (compare(data
, node
, checknode
) < 0) break;
609 prevnode
= checknode
;
612 Insert(list
, node
, prevnode
);
615 static void ReSortEntries(struct TextIconList_DATA
*data
)
617 struct List templist
;
618 struct Node
*node
, *succ
;
622 ForeachNodeSafe(&data
->entries_list
, node
, succ
)
625 AddTail(&templist
, node
);
628 ForeachNodeSafe(&templist
, node
, succ
)
630 SortInNode(data
, (struct List
*)&data
->entries_list
, node
, (APTR
)CompareNodes
);
634 static BOOL
MustRenderRect(struct TextIconList_DATA
*data
, struct Rectangle
*rect
)
636 if (data
->update_rect1
&& data
->update_rect2
)
638 if (!AndRectRect(rect
, data
->update_rect1
, NULL
) &&
639 !AndRectRect(rect
, data
->update_rect2
, NULL
)) return FALSE
;
641 else if (data
->update_rect1
)
643 if (!AndRectRect(rect
, data
->update_rect1
, NULL
)) return FALSE
;
645 else if (data
->update_rect2
)
647 if (!AndRectRect(rect
, data
->update_rect2
, NULL
)) return FALSE
;
653 static void GetAbsoluteLassoRect(struct TextIconList_DATA
*data
, struct Rectangle
*lasso_rect
)
655 WORD minx
= data
->lasso_rect
.MinX
;
656 WORD miny
= data
->lasso_rect
.MinY
;
657 WORD maxx
= data
->lasso_rect
.MaxX
;
658 WORD maxy
= data
->lasso_rect
.MaxY
;
662 /* Swap minx, maxx */
670 /* Swap miny, maxy */
676 lasso_rect
->MinX
= data
->view_rect
.MinX
- data
->view_x
+ minx
;
677 lasso_rect
->MinY
= data
->view_rect
.MinY
- data
->view_y
+ miny
;
678 lasso_rect
->MaxX
= data
->view_rect
.MinX
- data
->view_x
+ maxx
;
679 lasso_rect
->MaxY
= data
->view_rect
.MinY
- data
->view_y
+ maxy
;
682 static void EnableMouseMoveEvents(Object
*obj
, struct TextIconList_DATA
*data
)
684 if (!(data
->ehn
.ehn_Events
& IDCMP_MOUSEMOVE
))
686 DoMethod(_win(obj
),MUIM_Window_RemEventHandler
, (IPTR
)&data
->ehn
);
687 data
->ehn
.ehn_Events
|= IDCMP_MOUSEMOVE
;
688 DoMethod(_win(obj
),MUIM_Window_AddEventHandler
, (IPTR
)&data
->ehn
);
692 static void DisableMouseMoveEvents(Object
*obj
, struct TextIconList_DATA
*data
)
694 if (data
->ehn
.ehn_Events
& IDCMP_MOUSEMOVE
)
696 DoMethod(_win(obj
),MUIM_Window_RemEventHandler
, (IPTR
)&data
->ehn
);
697 data
->ehn
.ehn_Events
&= ~IDCMP_MOUSEMOVE
;
698 DoMethod(_win(obj
),MUIM_Window_AddEventHandler
, (IPTR
)&data
->ehn
);
702 static void EnableAutoScrollTimer(Object
*obj
, struct TextIconList_DATA
*data
)
704 if (!data
->thn
.ihn_Millis
)
706 data
->thn
.ihn_Millis
= AUTOSCROLL_MILLIS
;
707 DoMethod(_app(obj
), MUIM_Application_AddInputHandler
, (IPTR
)&data
->thn
);
711 static void DisableAutoScrollTimer(Object
*obj
, struct TextIconList_DATA
*data
)
713 if (data
->thn
.ihn_Millis
)
715 data
->thn
.ihn_Millis
= 0;
716 DoMethod(_app(obj
), MUIM_Application_RemInputHandler
, (IPTR
)&data
->thn
);
720 static BOOL
OrRectOutlineRegion(struct Region
*reg
, struct Rectangle
*rect
)
729 result
= OrRectRegion(reg
, &r
);
735 result
= result
&& OrRectRegion(reg
, &r
);
741 result
= result
&& OrRectRegion(reg
, &r
);
747 result
= result
&& OrRectRegion(reg
, &r
);
752 static void MyRectFill(struct TextIconList_DATA
*data
, struct RastPort
*rp
,
753 LONG x1
, LONG y1
, LONG x2
, LONG y2
, LONG mycol
)
771 if (data
->truecolor
&& CyberGfxBase
)
773 FillPixelArray(rp
, x1
, y1
, x2
- x1
+ 1, y2
- y1
+ 1, data
->colors
[mycol
].rgbpixel
);
777 SetAPen(rp
, data
->colors
[mycol
].pixel
);
778 RectFill(rp
, x1
, y1
, x2
, y2
);
782 static void RenderHeaderField(Object
*obj
, struct TextIconList_DATA
*data
,
783 struct Rectangle
*rect
, LONG index
)
786 struct TextExtent te
;
790 if ((data
->inputstate
== INPUTSTATE_COL_HEADER_CLICK
) &&
791 (data
->click_column
== index
))
794 if (ColumnHeaderUnderMouse(data
, data
->click_x
, data
->click_y
) == index
)
800 text
= GetTextIconHeaderText(data
, index
);
802 SetAPen(_rp(obj
), _pens(obj
)[sel
? MPEN_HALFSHADOW
: MPEN_HALFSHINE
]);
803 RectFill(_rp(obj
), rect
->MinX
+ 1, rect
->MinY
+ 1,
804 rect
->MaxX
- 1, rect
->MaxY
- 1);
805 SetAPen(_rp(obj
), _pens(obj
)[sel
? MPEN_SHADOW
: MPEN_SHINE
]);
806 RectFill(_rp(obj
), rect
->MinX
, rect
->MinY
, rect
->MinX
, rect
->MaxY
);
807 RectFill(_rp(obj
), rect
->MinX
+ 1, rect
->MinY
, rect
->MaxX
- 1, rect
->MinY
);
808 SetAPen(_rp(obj
), _pens(obj
)[sel
? MPEN_HALFSHINE
: MPEN_HALFSHADOW
]);
809 RectFill(_rp(obj
), rect
->MaxX
, rect
->MinY
, rect
->MaxX
, rect
->MaxY
);
810 RectFill(_rp(obj
), rect
->MinX
+ 1, rect
->MaxY
, rect
->MaxX
- 1, rect
->MaxY
);
812 if (index
== data
->sort_column
)
814 LONG x
= rect
->MaxX
- 4 - 6;
815 LONG y
= (rect
->MinY
+ rect
->MaxY
+ 1) / 2 - 3;
819 SetAPen(_rp(obj
), _pens(obj
)[sel
? MPEN_SHADOW
: MPEN_HALFSHADOW
]);
820 if (data
->sort_direction
== SORT_DIRECTION_UP
)
822 RectFill(_rp(obj
), x
, y
, x
+ 5, y
+ 1);
823 RectFill(_rp(obj
), x
+ 1, y
+ 2, x
+ 4, y
+ 3);
824 RectFill(_rp(obj
), x
+ 2, y
+ 4, x
+ 3, y
+ 5);
828 RectFill(_rp(obj
), x
, y
+ 4, x
+ 5, y
+ 5);
829 RectFill(_rp(obj
), x
+ 1, y
+ 2, x
+ 4, y
+ 3);
830 RectFill(_rp(obj
), x
+ 2, y
, x
+ 3, y
+ 1);
835 rect
->MinX
+= HEADERENTRY_SPACING_LEFT
;
836 rect
->MinY
+= HEADERLINE_SPACING_TOP
;
837 rect
->MaxX
-= HEADERENTRY_SPACING_RIGHT
;
838 rect
->MaxY
-= HEADERLINE_SPACING_BOTTOM
;
842 fit
= TextFit(_rp(obj
), text
, strlen(text
), &te
, NULL
, 1,
843 rect
->MaxX
- rect
->MinX
+ 1,
844 rect
->MaxY
- rect
->MinY
+ 1);
848 SetABPenDrMd(_rp(obj
), _pens(obj
)[MPEN_TEXT
], 0, JAM1
);
849 Move(_rp(obj
), rect
->MinX
, rect
->MinY
+ _rp(obj
)->TxBaseline
);
850 Text(_rp(obj
), text
, fit
);
855 static void RenderHeaderline(Object
*obj
, struct TextIconList_DATA
*data
)
857 struct Rectangle linerect
;
859 LONG firstvis
, lastvis
;
860 linerect
= data
->header_rect
;
861 linerect
.MinX
-= data
->view_x
;
862 linerect
.MaxX
-= data
->view_x
;
864 linerect
.MinX
= data
->header_rect
.MinX
- data
->view_x
;
865 linerect
.MaxX
= data
->header_rect
.MaxX
; //linerect.MinX + data->width - 1;
866 linerect
.MinY
= data
->header_rect
.MinY
;
867 linerect
.MaxY
= data
->header_rect
.MaxY
;
869 if (!MustRenderRect(data
, &linerect
)) return;
871 SetFont(_rp(obj
), _font(obj
));
873 x
= linerect
.MinX
+ HEADERLINE_SPACING_LEFT
;
875 firstvis
= FirstVisibleColumnNumber(data
);
876 lastvis
= LastVisibleColumnNumber(data
);
878 for(i
= 0; i
< NUM_COLUMNS
; i
++)
880 struct Rectangle field_rect
;
881 LONG index
= data
->column_pos
[i
];
883 if (!data
->column_visible
[index
]) continue;
885 field_rect
.MinX
= (i
== firstvis
) ? linerect
.MinX
: x
;
886 field_rect
.MinY
= linerect
.MinY
;
887 field_rect
.MaxX
= x
+ data
->column_width
[index
] - 1 + ((i
== lastvis
) ? HEADERLINE_SPACING_RIGHT
: 0);
888 field_rect
.MaxY
= linerect
.MaxY
;
890 if (MustRenderRect(data
, &field_rect
))
892 RenderHeaderField(obj
, data
, &field_rect
, index
);
894 x
+= data
->column_width
[index
];
897 x
+= HEADERLINE_SPACING_RIGHT
;
899 if (x
< linerect
.MaxX
)
903 if (MustRenderRect(data
, &linerect
))
905 SetABPenDrMd(_rp(obj
), _pens(obj
)[MPEN_HALFSHINE
], 0, JAM1
);
906 RectFill(_rp(obj
), linerect
.MinX
, linerect
.MinY
, linerect
.MaxX
, linerect
.MaxY
);
912 #define ENTRYPOS_FIRST -1
913 #define ENTRYPOS_MIDDLE 0
914 #define ENTRYPOS_LAST 1
916 static void RenderEntryField(Object
*obj
, struct TextIconList_DATA
*data
,
917 struct TextIconEntry
*entry
, struct Rectangle
*rect
,
918 LONG index
, BOOL firstvis
, BOOL lastvis
)
921 struct TextExtent te
;
925 selected
= (entry
&& data
->column_clickable
[index
]) ? entry
->selected
: FALSE
;
927 fit
= selected
? COLOR_SELECTED_BACKGROUND
: COLOR_COLUMN_BACKGROUND
;
928 if (index
== data
->sort_column
) fit
++;
929 if (data
->lasso_paint
) fit
+= 2;
931 MyRectFill(data
, _rp(obj
), rect
->MinX
, rect
->MinY
, rect
->MaxX
, rect
->MaxY
, fit
);
933 rect
->MinX
+= ENTRY_SPACING_LEFT
;
934 rect
->MaxX
-= ENTRY_SPACING_RIGHT
;
935 rect
->MinY
+= LINE_SPACING_TOP
;
936 rect
->MaxY
-= LINE_SPACING_BOTTOM
;
938 if (firstvis
) rect
->MinX
+= LINE_SPACING_LEFT
;
939 if (lastvis
) rect
->MaxX
-= LINE_SPACING_RIGHT
;
943 text
= GetTextIconEntryText(data
, entry
, index
);
945 if (!text
[0]) return;
947 fit
= TextFit(_rp(obj
), text
, strlen(text
), &te
, NULL
, 1,
948 rect
->MaxX
- rect
->MinX
+ 1,
949 rect
->MaxY
- rect
->MinY
+ 1);
953 SetABPenDrMd(_rp(obj
), _pens(obj
)[selected
? MPEN_SHINE
: MPEN_TEXT
], 0, JAM1
);
955 switch(data
->column_align
[index
])
957 case COLUMN_ALIGN_LEFT
:
958 Move(_rp(obj
), rect
->MinX
, rect
->MinY
+ _rp(obj
)->TxBaseline
);
961 case COLUMN_ALIGN_RIGHT
:
962 Move(_rp(obj
), rect
->MaxX
- te
.te_Width
, rect
->MinY
+ _rp(obj
)->TxBaseline
);
965 case COLUMN_ALIGN_CENTER
:
966 Move(_rp(obj
), rect
->MinX
+ (rect
->MaxX
- rect
->MinX
+ 1 + 1 - te
.te_Width
) / 2,
967 rect
->MinY
+ _rp(obj
)->TxBaseline
);
971 Text(_rp(obj
), text
, fit
);
974 static void RenderEntry(Object
*obj
, struct TextIconList_DATA
*data
, LONG index
)
976 struct TextIconEntry
*entry
= GetEntryFromIndex(data
, index
);
977 struct Rectangle linerect
;
979 LONG firstvis
, lastvis
;
981 linerect
.MinX
= data
->view_rect
.MinX
- data
->view_x
;
982 linerect
.MaxX
= data
->view_rect
.MaxX
; //linerect.MinX + data->width - 1;
983 linerect
.MinY
= data
->view_rect
.MinY
+ index
* data
->lineheight
- data
->view_y
;
984 linerect
.MaxY
= linerect
.MinY
+ data
->lineheight
- 1;
986 if (!AndRectRect(&linerect
, &data
->view_rect
, NULL
)) return;
987 if (!MustRenderRect(data
, &linerect
)) return;
989 SetFont(_rp(obj
), _font(obj
));
991 x
= linerect
.MinX
+ LINE_SPACING_LEFT
;
993 firstvis
= FirstVisibleColumnNumber(data
);
994 lastvis
= LastVisibleColumnNumber(data
);
996 for(i
= 0; i
< NUM_COLUMNS
; i
++)
998 struct Rectangle field_rect
;
999 LONG index
= data
->column_pos
[i
];
1001 if (!data
->column_visible
[i
]) continue;
1003 field_rect
.MinX
= (i
== firstvis
) ? linerect
.MinX
: x
;
1004 field_rect
.MinY
= linerect
.MinY
;
1005 field_rect
.MaxX
= x
+ data
->column_width
[index
] - 1 + ((i
== lastvis
) ? LINE_SPACING_RIGHT
: 0);
1006 field_rect
.MaxY
= linerect
.MaxY
;
1008 if (MustRenderRect(data
, &field_rect
))
1010 if (AndRectRect(&field_rect
, &data
->view_rect
, NULL
))
1012 RenderEntryField(obj
, data
, entry
, &field_rect
, index
,
1013 (i
== firstvis
), (i
== lastvis
));
1016 x
+= data
->column_width
[index
];
1019 x
+= LINE_SPACING_RIGHT
;
1021 if (x
< linerect
.MaxX
)
1025 if (MustRenderRect(data
, &linerect
))
1027 SetABPenDrMd(_rp(obj
), _pens(obj
)[data
->lasso_paint
? MPEN_BACKGROUND
: MPEN_SHINE
], 0, JAM1
);
1028 RectFill(_rp(obj
), linerect
.MinX
, linerect
.MinY
, linerect
.MaxX
, linerect
.MaxY
);
1034 static LONG
FirstVisibleLine(struct TextIconList_DATA
*data
)
1036 return data
->view_y
/ data
->lineheight
;
1039 static LONG
NumVisibleLines(struct TextIconList_DATA
*data
)
1041 LONG visible
= data
->view_height
+ data
->lineheight
- 1 +
1042 (data
->view_y
% data
->lineheight
);
1044 visible
/= data
->lineheight
;
1049 static void RenderAllEntries(Object
*obj
, struct TextIconList_DATA
*data
)
1051 LONG first
= FirstVisibleLine(data
);
1052 LONG visible
= NumVisibleLines(data
);
1055 for(i
= 0; i
< visible
; i
++)
1057 RenderEntry(obj
, data
, first
+ i
);
1063 static void RethinkLasso(Object
*obj
, struct TextIconList_DATA
*data
)
1065 struct TextIconEntry
*entry
;
1067 LONG ny1
= data
->lasso_rect
.MinY
;
1068 LONG ny2
= data
->lasso_rect
.MaxY
;
1069 LONG oy1
= data
->old_lasso_rect
.MinY
;
1070 LONG oy2
= data
->old_lasso_rect
.MaxY
;
1076 if (!data
->num_entries
) return;
1092 ny1
/= data
->lineheight
;
1093 ny2
/= data
->lineheight
;
1094 oy1
/= data
->lineheight
;
1095 oy2
/= data
->lineheight
;
1097 y1
= (ny1
< oy1
) ? ny1
: oy1
;
1098 y2
= (ny2
> oy2
) ? ny2
: oy2
;
1104 else if (y1
>= data
->num_entries
)
1106 y1
= data
->num_entries
- 1;
1113 else if (y2
>= data
->num_entries
)
1115 y2
= data
->num_entries
- 1;
1118 GetColumnCoords(data
, INDEX_NAME
, &x1
, &x2
);
1119 x1
+= data
->view_x
- data
->view_rect
.MinX
;
1120 x2
+= data
->view_x
- data
->view_rect
.MinX
;
1122 lasso_hot
= ((data
->lasso_rect
.MinX
>= x1
) && (data
->lasso_rect
.MinX
<= x2
)) ||
1123 ((data
->lasso_rect
.MaxX
>= x1
) && (data
->lasso_rect
.MaxX
<= x2
)) ||
1124 ((data
->lasso_rect
.MinX
< x1
) && (data
->lasso_rect
.MaxX
> x2
)) ||
1125 ((data
->lasso_rect
.MaxX
< x1
) && (data
->lasso_rect
.MinX
> x2
));
1127 entry
= GetEntryFromIndex(data
, y1
);
1128 while(entry
&& entry
->node
.mln_Succ
&& (y1
<= y2
))
1132 select
= (y1
>= ny1
) && (y1
<= ny2
) && lasso_hot
;
1133 if (select
!= entry
->selected
)
1137 AddTail((struct List
*)&data
->selection_list
, (struct Node
*)&entry
->selection_node
);
1138 data
->num_selected
++;
1142 Remove((struct Node
*)&entry
->selection_node
);
1143 data
->num_selected
--;
1145 entry
->selected
= select
;
1146 entry
->dirty
= TRUE
;
1150 entry
= (struct TextIconEntry
*)entry
->node
.mln_Succ
;
1156 data
->update
= UPDATE_DIRTY_ENTRIES
;
1157 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
1162 /**************************************************************************
1164 **************************************************************************/
1165 static IPTR
TextIconList_New(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
)
1167 struct TextIconList_DATA
*data
;
1168 struct TagItem
*tag
, *tags
;
1171 obj
= (Object
*)DoSuperNewTags(cl
, obj
, NULL
,
1172 MUIA_FillArea
, FALSE
,
1173 TAG_MORE
, (IPTR
) msg
->ops_AttrList
);
1174 if (!obj
) return FALSE
;
1176 data
= INST_DATA(cl
, obj
);
1177 NewList((struct List
*)&data
->entries_list
);
1178 NewList((struct List
*)&data
->selection_list
);
1179 data
->show_header
= TRUE
;
1180 data
->active_entry
= -1;
1182 for(i
= 0; i
< NUM_COLUMNS
; i
++)
1184 data
->column_pos
[i
] = i
;
1185 data
->column_visible
[i
] = TRUE
;
1186 data
->column_width
[i
] = 100;
1188 data
->column_align
[INDEX_SIZE
] = COLUMN_ALIGN_RIGHT
;
1189 data
->column_clickable
[INDEX_NAME
] = TRUE
;
1191 data
->column_sortable
[INDEX_NAME
] = TRUE
;
1192 data
->column_sortable
[INDEX_SIZE
] = TRUE
;
1193 data
->column_sortable
[INDEX_DATE
] = TRUE
;
1194 data
->column_sortable
[INDEX_TIME
] = TRUE
;
1196 data
->sort_column
= INDEX_NAME
;
1197 data
->sort_direction
= SORT_DIRECTION_UP
;
1198 data
->sort_dirs
= SORT_DRAWERS_FIRST
;
1200 /* parse initial taglist */
1201 for (tags
= msg
->ops_AttrList
; (tag
= NextTagItem(&tags
)); )
1203 switch (tag
->ti_Tag
)
1208 data
->pool
= CreatePool(0,4096,4096);
1211 CoerceMethod(cl
,obj
,OM_DISPOSE
);
1215 data
->ehn
.ehn_Events
= IDCMP_MOUSEBUTTONS
;
1216 data
->ehn
.ehn_Priority
= 0;
1217 data
->ehn
.ehn_Flags
= 0;
1218 data
->ehn
.ehn_Object
= obj
;
1219 data
->ehn
.ehn_Class
= cl
;
1221 data
->thn
.ihn_Flags
= MUIIHNF_TIMER
;
1222 data
->thn
.ihn_Method
= MUIM_TextIconList_AutoScroll
;
1223 data
->thn
.ihn_Object
= obj
;
1228 /**************************************************************************
1230 **************************************************************************/
1231 static IPTR
TextIconList_Dispose(struct IClass
*cl
, Object
*obj
, Msg msg
)
1233 struct TextIconList_DATA
*data
= INST_DATA(cl
, obj
);
1234 struct TextIconEntry
*node
;
1236 ForeachNode(&data
->entries_list
, node
)
1240 if (data
->pool
) DeletePool(data
->pool
);
1242 DoSuperMethodA(cl
,obj
,msg
);
1246 /**************************************************************************
1248 **************************************************************************/
1249 static IPTR
TextIconList_Set(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
)
1251 struct TextIconList_DATA
*data
= INST_DATA(cl
, obj
);
1252 struct TagItem
*tag
, *tags
;
1253 LONG oldleft
= data
->view_x
, oldtop
= data
->view_y
;
1255 /* parse initial taglist */
1256 for (tags
= msg
->ops_AttrList
; (tag
= NextTagItem(&tags
)); )
1258 switch (tag
->ti_Tag
)
1260 case MUIA_TextIconList_Left
:
1261 if (data
->view_x
!= (LONG
)tag
->ti_Data
)
1263 LONG new_view_x
= (LONG
)tag
->ti_Data
;
1265 if (new_view_x
+ data
->view_width
> data
->width
)
1267 new_view_x
= data
->width
- data
->view_width
;
1269 if (new_view_x
< 0) new_view_x
= 0;
1271 data
->view_x
= new_view_x
;
1272 tag
->ti_Data
= new_view_x
;
1276 case MUIA_TextIconList_Top
:
1277 if (data
->view_y
!= (LONG
)tag
->ti_Data
)
1279 LONG new_view_y
= (LONG
)tag
->ti_Data
;
1281 if (new_view_y
+ data
->view_height
> data
->height
)
1283 new_view_y
= data
->height
- data
->view_height
;
1285 if (new_view_y
< 0) new_view_y
= 0;
1287 data
->view_y
= new_view_y
;
1288 tag
->ti_Data
= new_view_y
;
1294 if ((oldleft
!= data
->view_x
) || (oldtop
!= data
->view_y
))
1296 data
->update
= UPDATE_SCROLL
;
1297 data
->update_scrolldx
= data
->view_x
- oldleft
;
1298 data
->update_scrolldy
= data
->view_y
- oldtop
;
1300 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
1303 return DoSuperMethodA(cl
, obj
, (Msg
)msg
);
1306 /**************************************************************************
1308 **************************************************************************/
1309 static IPTR
TextIconList_Get(struct IClass
*cl
, Object
*obj
, struct opGet
*msg
)
1311 /* small macro to simplify return value storage */
1312 #define STORE *(msg->opg_Storage)
1313 struct TextIconList_DATA
*data
= INST_DATA(cl
, obj
);
1315 switch (msg
->opg_AttrID
)
1317 case MUIA_TextIconList_Left
: STORE
= data
->view_x
; return 1;
1318 case MUIA_TextIconList_Top
: STORE
= data
->view_y
; return 1;
1319 case MUIA_TextIconList_Width
: STORE
= data
->width
; return 1;
1320 case MUIA_TextIconList_Height
: STORE
= data
->height
; return 1;
1323 return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
1327 /**************************************************************************
1329 **************************************************************************/
1330 static IPTR
TextIconList_Setup(struct IClass
*cl
, Object
*obj
, struct MUIP_Setup
*msg
)
1332 struct TextIconList_DATA
*data
= INST_DATA(cl
, obj
);
1335 if (!DoSuperMethodA(cl
, obj
, (Msg
) msg
)) return 0;
1337 DoMethod(_win(obj
),MUIM_Window_AddEventHandler
, (IPTR
)&data
->ehn
);
1339 InitRastPort(&data
->temprp
);
1340 SetFont(&data
->temprp
, _font(obj
));
1341 data
->truecolor
= GetBitMapAttr(_screen(obj
)->RastPort
.BitMap
, BMA_DEPTH
) >= 15;
1343 data
->lineheight
= LINE_EXTRAHEIGHT
+ _font(obj
)->tf_YSize
;
1344 data
->is_setup
= TRUE
;
1346 for(i
= 0; i
< NUM_COLORS
; i
++)
1348 data
->colors
[i
].rgbpixel
= rgb_colors
[i
];
1349 data
->colors
[i
].pixel
= data
->colors
[i
].rgbpixel
;
1351 if (!data
->truecolor
|| !CyberGfxBase
)
1353 ULONG r
= (rgb_colors
[i
] & 0x00FF0000) >> 16;
1354 ULONG g
= (rgb_colors
[i
] & 0x0000FF00) >> 8;
1355 ULONG b
= (rgb_colors
[i
] & 0x000000FF);
1357 LONG pen
= ObtainBestPen(_screen(obj
)->ViewPort
.ColorMap
,
1361 OBP_FailIfBad
, FALSE
,
1362 OBP_Precision
, PRECISION_GUI
,
1367 data
->colors
[i
].pixel
= pen
;
1368 data
->colors
[i
].alloced
= TRUE
;
1372 data
->colors
[i
].pixel
= _pens(obj
)[pen_colors
[i
]];
1373 data
->colors
[i
].alloced
= FALSE
;
1378 if (data
->show_header
)
1380 data
->headerheight
= HEADERLINE_EXTRAHEIGHT
+ _font(obj
)->tf_YSize
;
1384 data
->headerheight
= 0;
1387 if (data
->num_entries
)
1389 CalcAllEntryDimensions(data
);
1391 data
->height
= data
->num_entries
* data
->lineheight
;
1392 RecalcColumnMaxWidths(data
);
1394 SetAttrs(obj
, MUIA_TextIconList_Width
, data
->width
,
1395 MUIA_TextIconList_Height
, data
->height
,
1402 /**************************************************************************
1404 **************************************************************************/
1405 static IPTR
TextIconList_Show(struct IClass
*cl
, Object
*obj
, struct MUIP_Show
*msg
)
1407 struct TextIconList_DATA
*data
= INST_DATA(cl
, obj
);
1408 LONG newleft
, newtop
;
1411 rc
= DoSuperMethodA(cl
, obj
, (Msg
)msg
);
1413 newleft
= data
->view_x
;
1414 newtop
= data
->view_y
;
1416 data
->view_width
= _mwidth(obj
);
1417 data
->view_height
= _mheight(obj
) - data
->headerheight
;
1419 SetAttrs(obj
, MUIA_TextIconList_VisWidth
, data
->view_width
,
1420 MUIA_TextIconList_VisHeight
, data
->view_height
,
1423 data
->view_rect
.MinX
= _mleft(obj
);
1424 data
->view_rect
.MinY
= _mtop(obj
) + data
->headerheight
;
1425 data
->view_rect
.MaxX
= _mright(obj
);
1426 data
->view_rect
.MaxY
= _mbottom(obj
);
1428 data
->header_rect
.MinX
= _mleft(obj
);
1429 data
->header_rect
.MinY
= _mtop(obj
);
1430 data
->header_rect
.MaxX
= _mright(obj
);
1431 data
->header_rect
.MaxY
= _mtop(obj
) + data
->headerheight
- 1;
1433 if (newleft
+ data
->view_width
> data
->width
) newleft
= data
->width
- data
->view_width
;
1434 if (newleft
< 0) newleft
= 0;
1436 if (newtop
+ data
->view_height
> data
->height
) newtop
= data
->height
- data
->view_height
;
1437 if (newtop
< 0) newtop
= 0;
1439 if ((newleft
!= data
->view_x
) || (newtop
!= data
->view_y
))
1441 SetAttrs(obj
, MUIA_TextIconList_Left
, newleft
,
1442 MUIA_TextIconList_Top
, newtop
,
1446 SetFont(_rp(obj
), _font(obj
));
1448 data
->is_shown
= TRUE
;
1453 /**************************************************************************
1455 **************************************************************************/
1456 static IPTR
TextIconList_Hide(struct IClass
*cl
, Object
*obj
, struct MUIP_Hide
*msg
)
1458 struct TextIconList_DATA
*data
= INST_DATA(cl
, obj
);
1461 data
->is_shown
= FALSE
;
1463 rc
= DoSuperMethodA(cl
, obj
, (Msg
)msg
);
1468 /**************************************************************************
1470 **************************************************************************/
1471 static IPTR
TextIconList_Cleanup(struct IClass
*cl
, Object
*obj
, struct MUIP_Cleanup
*msg
)
1473 struct TextIconList_DATA
*data
= INST_DATA(cl
, obj
);
1476 DoMethod(_win(obj
),MUIM_Window_RemEventHandler
, (IPTR
)&data
->ehn
);
1478 DeinitRastPort(&data
->temprp
);
1480 for(i
= 0; i
< NUM_COLORS
; i
++)
1482 if (data
->colors
[i
].alloced
)
1484 ReleasePen(_screen(obj
)->ViewPort
.ColorMap
, data
->colors
[i
].pixel
);
1485 data
->colors
[i
].alloced
= FALSE
;
1489 data
->is_setup
= FALSE
;
1491 return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
1494 /**************************************************************************
1496 **************************************************************************/
1497 static IPTR
TextIconList_AskMinMax(struct IClass
*cl
, Object
*obj
, struct MUIP_AskMinMax
*msg
)
1499 ULONG rc
= DoSuperMethodA(cl
, obj
, (Msg
) msg
);
1501 msg
->MinMaxInfo
->MinWidth
+= 10;
1502 msg
->MinMaxInfo
->MinHeight
+= 10;
1504 msg
->MinMaxInfo
->DefWidth
+= 100;
1505 msg
->MinMaxInfo
->DefHeight
+= 100;
1507 msg
->MinMaxInfo
->MaxWidth
= MUI_MAXMAX
;
1508 msg
->MinMaxInfo
->MaxHeight
= MUI_MAXMAX
;
1513 static void DrawHeaderLine(Object
*obj
, struct TextIconList_DATA
*data
)
1517 if (data
->show_header
&& MustRenderRect(data
, &data
->header_rect
))
1519 clip
= MUI_AddClipping(muiRenderInfo(obj
), data
->header_rect
.MinX
,
1520 data
->header_rect
.MinY
,
1521 data
->header_rect
.MaxX
- data
->header_rect
.MinX
+ 1,
1522 data
->header_rect
.MaxY
- data
->header_rect
.MinY
+ 1);
1524 RenderHeaderline(obj
, data
);
1526 MUI_RemoveClipping(muiRenderInfo(obj
),clip
);
1530 static void DrawLassoOutline(Object
*obj
, struct TextIconList_DATA
*data
)
1532 struct Rectangle lasso
;
1534 GetAbsoluteLassoRect(data
, &lasso
);
1537 MyRectFill(data
, _rp(obj
), lasso
.MinX
, lasso
.MinY
, lasso
.MaxX
, lasso
.MinY
, COLOR_SELECTED_BACKGROUND
);
1538 MyRectFill(data
, _rp(obj
), lasso
.MaxX
, lasso
.MinY
, lasso
.MaxX
, lasso
.MaxY
, COLOR_SELECTED_BACKGROUND
);
1539 MyRectFill(data
, _rp(obj
), lasso
.MinX
, lasso
.MaxY
, lasso
.MaxX
, lasso
.MaxY
, COLOR_SELECTED_BACKGROUND
);
1540 MyRectFill(data
, _rp(obj
), lasso
.MinX
, lasso
.MinY
, lasso
.MinX
, lasso
.MaxY
, COLOR_SELECTED_BACKGROUND
);
1542 SetABPenDrMd(_rp(obj
), _pens(obj
)[MPEN_SHADOW
], 0, JAM1
);
1543 Move(_rp(obj
), lasso
.MinX
, lasso
.MinY
);
1544 Draw(_rp(obj
), lasso
.MaxX
, lasso
.MinY
);
1545 Draw(_rp(obj
), lasso
.MaxX
, lasso
.MaxY
);
1546 Draw(_rp(obj
), lasso
.MinX
, lasso
.MaxY
);
1547 Draw(_rp(obj
), lasso
.MinX
, lasso
.MinY
);
1551 /**************************************************************************
1553 **************************************************************************/
1554 static IPTR
TextIconList_Draw(struct IClass
*cl
, Object
*obj
, struct MUIP_Draw
*msg
)
1556 struct TextIconList_DATA
*data
= INST_DATA(cl
, obj
);
1558 struct TextIconEntry
*entry
;
1560 DoSuperMethodA(cl
, obj
, (Msg
) msg
);
1562 if (msg
->flags
& MADF_DRAWUPDATE
)
1564 if (data
->update
== UPDATE_SCROLL
)
1566 struct Region
*region
;
1567 struct Rectangle xrect
, yrect
;
1568 BOOL scroll_caused_damage
;
1570 scroll_caused_damage
= (_rp(obj
)->Layer
->Flags
& LAYERREFRESH
) ? FALSE
: TRUE
;
1574 if ((abs(data
->update_scrolldx
) >= data
->view_width
) ||
1575 (abs(data
->update_scrolldy
) >= data
->view_height
))
1577 data
->update
= UPDATE_ALL
;
1578 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
1582 region
= NewRegion();
1585 data
->update
= UPDATE_ALL
;
1586 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
1590 if (data
->update_scrolldx
> 0)
1592 xrect
.MinX
= data
->view_rect
.MaxX
- data
->update_scrolldx
;
1593 xrect
.MinY
= data
->view_rect
.MinY
;
1594 xrect
.MaxX
= data
->view_rect
.MaxX
;
1595 xrect
.MaxY
= data
->view_rect
.MaxY
;
1597 OrRectRegion(region
, &xrect
);
1599 data
->update_rect1
= &xrect
;
1601 else if (data
->update_scrolldx
< 0)
1603 xrect
.MinX
= data
->view_rect
.MinX
;
1604 xrect
.MinY
= data
->view_rect
.MinY
;
1605 xrect
.MaxX
= data
->view_rect
.MinX
- data
->update_scrolldx
;
1606 xrect
.MaxY
= data
->view_rect
.MaxY
;
1608 OrRectRegion(region
, &xrect
);
1610 data
->update_rect1
= &xrect
;
1613 if (data
->update_scrolldy
> 0)
1615 yrect
.MinX
= data
->view_rect
.MinX
;
1616 yrect
.MinY
= data
->view_rect
.MaxY
- data
->update_scrolldy
;
1617 yrect
.MaxX
= data
->view_rect
.MaxX
;
1618 yrect
.MaxY
= data
->view_rect
.MaxY
;
1620 OrRectRegion(region
, &yrect
);
1622 data
->update_rect2
= &yrect
;
1624 else if (data
->update_scrolldy
< 0)
1626 yrect
.MinX
= data
->view_rect
.MinX
;
1627 yrect
.MinY
= data
->view_rect
.MinY
;
1628 yrect
.MaxX
= data
->view_rect
.MaxX
;
1629 yrect
.MaxY
= data
->view_rect
.MinY
- data
->update_scrolldy
;
1631 OrRectRegion(region
, &yrect
);
1633 data
->update_rect2
= &yrect
;
1636 ScrollRasterBF(_rp(obj
),
1637 data
->update_scrolldx
,
1638 data
->update_scrolldy
,
1639 data
->view_rect
.MinX
,
1640 data
->view_rect
.MinY
,
1641 data
->view_rect
.MaxX
,
1642 data
->view_rect
.MaxY
);
1644 if (data
->show_header
&& data
->update_scrolldx
)
1646 ScrollRasterBF(_rp(obj
),
1647 data
->update_scrolldx
,
1649 data
->header_rect
.MinX
,
1650 data
->header_rect
.MinY
,
1651 data
->header_rect
.MaxX
,
1652 data
->header_rect
.MaxY
);
1655 scroll_caused_damage
= scroll_caused_damage
&& (_rp(obj
)->Layer
->Flags
& LAYERREFRESH
) ? TRUE
: FALSE
;
1657 clip
= MUI_AddClipRegion(muiRenderInfo(obj
), region
);
1658 data
->update
= UPDATE_ALL
;
1659 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
1660 MUI_RemoveClipRegion(muiRenderInfo(obj
), clip
);
1662 if (data
->show_header
&& data
->update_scrolldx
)
1664 xrect
.MinY
= data
->header_rect
.MinY
;
1665 xrect
.MaxY
= data
->header_rect
.MaxY
;
1667 data
->update_rect1
= &xrect
;
1668 data
->update_rect2
= NULL
;
1670 clip
= MUI_AddClipping(muiRenderInfo(obj
), xrect
.MinX
,
1672 xrect
.MaxX
- xrect
.MinX
+ 1,
1673 xrect
.MaxY
- xrect
.MinY
+ 1);
1675 data
->update
= UPDATE_ALL
;
1676 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
1677 MUI_RemoveClipRegion(muiRenderInfo(obj
), clip
);
1679 data
->update_rect2
= NULL
;
1683 data
->update_rect1
= data
->update_rect2
= NULL
;
1684 data
->update_scrolldx
= data
->update_scrolldy
= 0;
1686 // DisposeRegion(region);
1688 if (scroll_caused_damage
)
1690 if (MUI_BeginRefresh(muiRenderInfo(obj
), 0))
1692 /* Theoretically it might happen that more damage is caused
1693 after ScrollRaster. By something else, like window movement
1694 in front of our window. Therefore refresh root object of
1695 window, not just this object */
1699 get(_win(obj
),MUIA_Window_RootObject
, &o
);
1700 MUI_Redraw(o
, MADF_DRAWOBJECT
);
1702 MUI_EndRefresh(muiRenderInfo(obj
), 0);
1708 } /* if (data->update == UPDATE_SCROLL) */
1709 else if (data
->update
== UPDATE_DIRTY_ENTRIES
)
1711 struct Region
*clipregion
;
1712 LONG first
, numvisible
, index
= 0;
1716 clipregion
= NewRectRegion(data
->view_rect
.MinX
,
1717 data
->view_rect
.MinY
,
1718 data
->view_rect
.MaxX
,
1719 data
->view_rect
.MaxY
);
1723 if (data
->lasso_active
)
1725 struct Rectangle lasso_rect
;
1727 GetAbsoluteLassoRect(data
, &lasso_rect
);
1728 ClearRectRegion(clipregion
, &lasso_rect
);
1731 clip
= MUI_AddClipRegion(muiRenderInfo(obj
), clipregion
);
1733 first
= FirstVisibleLine(data
);
1734 numvisible
= NumVisibleLines(data
);
1736 ForeachNode(&data
->entries_list
, entry
)
1740 if ((index
>= first
) && (index
< first
+ numvisible
))
1742 RenderEntry(obj
, data
, index
);
1748 if (data
->lasso_active
)
1750 struct Rectangle lasso_rect
;
1751 struct Rectangle vis_lasso_rect
;
1753 GetAbsoluteLassoRect(data
, &lasso_rect
);
1755 if (AndRectRect(&data
->view_rect
, &lasso_rect
, &vis_lasso_rect
))
1757 MUI_RemoveClipRegion(muiRenderInfo(obj
),clip
);
1759 clipregion
= NewRectRegion(vis_lasso_rect
.MinX
,
1760 vis_lasso_rect
.MinY
,
1761 vis_lasso_rect
.MaxX
,
1762 vis_lasso_rect
.MaxY
);
1764 data
->lasso_paint
= TRUE
;
1766 clip
= MUI_AddClipRegion(muiRenderInfo(obj
), clipregion
);
1769 ForeachNode(&data
->entries_list
, entry
)
1773 if ((index
>= first
) && (index
< first
+ numvisible
))
1775 RenderEntry(obj
, data
, index
);
1781 data
->lasso_paint
= FALSE
;
1783 DrawLassoOutline(obj
, data
);
1785 } /* if (AndRectRect(&data->view_rect, &lasso_rect, &vis_lasso_rect)) */
1787 } /* if (data->lasso_active) */
1789 MUI_RemoveClipRegion(muiRenderInfo(obj
), clip
);
1791 ForeachNode(&data
->entries_list
, entry
)
1793 if (entry
->dirty
) entry
->dirty
= FALSE
;
1798 } /* else if (data->update == UPDATE_DIRTY_ENTRIES) */
1799 else if (data
->update
== UPDATE_HEADER
)
1803 DrawHeaderLine(obj
, data
);
1808 } /* if (msg->flags & MADF_DRAWUPDATE) */
1810 if (MustRenderRect(data
, &data
->view_rect
))
1812 struct Region
*clipregion
;
1814 clipregion
= NewRectRegion(data
->view_rect
.MinX
,
1815 data
->view_rect
.MinY
,
1816 data
->view_rect
.MaxX
,
1817 data
->view_rect
.MaxY
);
1821 if (data
->lasso_active
)
1823 struct Rectangle lasso_rect
;
1825 GetAbsoluteLassoRect(data
, &lasso_rect
);
1826 ClearRectRegion(clipregion
, &lasso_rect
);
1829 clip
= MUI_AddClipRegion(muiRenderInfo(obj
), clipregion
);
1831 RenderAllEntries(obj
, data
);
1833 if (data
->lasso_active
)
1835 struct Rectangle lasso_rect
;
1836 struct Rectangle vis_lasso_rect
;
1838 GetAbsoluteLassoRect(data
, &lasso_rect
);
1840 if (AndRectRect(&data
->view_rect
, &lasso_rect
, &vis_lasso_rect
))
1842 MUI_RemoveClipRegion(muiRenderInfo(obj
),clip
);
1844 clipregion
= NewRectRegion(vis_lasso_rect
.MinX
,
1845 vis_lasso_rect
.MinY
,
1846 vis_lasso_rect
.MaxX
,
1847 vis_lasso_rect
.MaxY
);
1849 data
->lasso_paint
= TRUE
;
1851 clip
= MUI_AddClipRegion(muiRenderInfo(obj
), clipregion
);
1853 RenderAllEntries(obj
, data
);
1855 data
->lasso_paint
= FALSE
;
1857 DrawLassoOutline(obj
, data
);
1862 MUI_RemoveClipRegion(muiRenderInfo(obj
),clip
);
1864 } /* if (clipregion) */
1866 } /* if (MustRenderRect(data, &data->view_rect)) */
1868 DrawHeaderLine(obj
, data
);
1875 /**************************************************************************
1877 **************************************************************************/
1878 static IPTR
TextIconList_AutoScroll(struct IClass
*cl
, Object
*obj
, Msg msg
)
1880 struct TextIconList_DATA
*data
= INST_DATA(cl
, obj
);
1882 if (data
->lasso_active
)
1884 LONG new_view_x
, new_view_y
;
1886 new_view_x
= data
->view_x
;
1887 new_view_y
= data
->view_y
;
1889 if (data
->click_x
< data
->view_rect
.MinX
)
1891 new_view_x
-= (data
->view_rect
.MinX
- data
->click_x
) / 4;
1893 else if (data
->click_x
> data
->view_rect
.MaxX
)
1895 new_view_x
+= (data
->click_x
- data
->view_rect
.MaxX
) / 4;
1898 if (data
->click_y
< data
->view_rect
.MinY
)
1900 new_view_y
-= (data
->view_rect
.MinY
- data
->click_y
) / 4;
1902 else if (data
->click_y
> data
->view_rect
.MaxY
)
1904 new_view_y
+= (data
->click_y
- data
->view_rect
.MaxY
) / 4;
1907 if (new_view_x
+ data
->view_width
> data
->width
)
1909 new_view_x
= data
->width
- data
->view_width
;
1911 if (new_view_x
< 0) new_view_x
= 0;
1913 if (new_view_y
+ data
->view_height
> data
->height
)
1915 new_view_y
= data
->height
- data
->view_height
;
1917 if (new_view_y
< 0) new_view_y
= 0;
1919 if ((new_view_x
!= data
->view_x
) || (new_view_y
!= data
->view_y
))
1921 data
->old_lasso_rect
= data
->lasso_rect
;
1923 data
->lasso_rect
.MaxX
+= new_view_x
- data
->view_x
;
1924 data
->lasso_rect
.MaxY
+= new_view_y
- data
->view_y
;
1926 RethinkLasso(obj
, data
);
1928 SetAttrs(obj
, MUIA_TextIconList_Left
, new_view_x
,
1929 MUIA_TextIconList_Top
, new_view_y
,
1936 DisableAutoScrollTimer(obj
, data
);
1942 /**************************************************************************
1944 **************************************************************************/
1945 static IPTR
TextIconList_HandleEvent(struct IClass
*cl
, Object
*obj
, struct MUIP_HandleEvent
*msg
)
1947 struct TextIconList_DATA
*data
= INST_DATA(cl
, obj
);
1952 LONG mx
= msg
->imsg
->MouseX
;
1953 LONG my
= msg
->imsg
->MouseY
;
1957 shift_qual
= (msg
->imsg
->Qualifier
& (IEQUALIFIER_LSHIFT
| IEQUALIFIER_RSHIFT
)) ? TRUE
: FALSE
;
1959 switch (msg
->imsg
->Class
)
1961 case IDCMP_MOUSEBUTTONS
:
1962 switch(msg
->imsg
->Code
)
1965 //kprintf("SELECTDOWN\n");
1966 if (data
->inputstate
== INPUTSTATE_NONE
)
1968 if ( ((line
= LineUnderMouse(data
, mx
, my
)) >= 0) &&
1969 ((col
= ColumnUnderMouse(data
, mx
, my
)) >= 0) )
1971 //kprintf("click on line %d col %d\n", line, col);
1973 if (data
->column_clickable
[col
])
1975 if (data
->active_entry
!= line
)
1977 struct TextIconEntry
*old
, *new;
1979 old
= GetEntryFromIndex(data
, data
->active_entry
);
1980 new = GetEntryFromIndex(data
, line
);
1982 data
->active_entry
= line
;
1983 if (old
&& old
->selected
&& !shift_qual
)
1985 Remove((struct Node
*)&old
->selection_node
);
1986 old
->selected
= FALSE
;
1989 data
->num_selected
--;
1992 if (!shift_qual
&& data
->num_selected
)
1994 struct TextIconEntry
*entry
;
1996 ForeachNode(&data
->entries_list
, entry
)
1998 if (entry
->selected
)
2000 Remove((struct Node
*)&entry
->selection_node
);
2001 entry
->selected
= FALSE
;
2002 entry
->dirty
= TRUE
;
2006 data
->num_selected
= 0;
2009 if (new && !new->selected
)
2011 AddTail((struct List
*)&data
->selection_list
, (struct Node
*)&new->selection_node
);
2012 new->selected
= TRUE
;
2015 data
->num_selected
++;
2018 data
->update
= UPDATE_DIRTY_ENTRIES
;
2019 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
2021 } /* if (data->active_entry != line) */
2023 } /* if (data->column_clickable[col]) */
2026 if (!shift_qual
&& data
->num_selected
)
2028 struct TextIconEntry
*entry
;
2030 ForeachNode(&data
->entries_list
, entry
)
2032 if (entry
->selected
)
2034 Remove((struct Node
*)&entry
->selection_node
);
2035 entry
->selected
= FALSE
;
2036 entry
->dirty
= TRUE
;
2040 data
->num_selected
= 0;
2041 data
->update
= UPDATE_DIRTY_ENTRIES
;
2042 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
2045 data
->lasso_rect
.MinX
= mx
- data
->view_rect
.MinX
+ data
->view_x
;
2046 data
->lasso_rect
.MinY
= my
- data
->view_rect
.MinY
+ data
->view_y
;
2047 data
->lasso_rect
.MaxX
= mx
- data
->view_rect
.MinX
+ data
->view_x
;
2048 data
->lasso_rect
.MaxY
= my
- data
->view_rect
.MinY
+ data
->view_y
;
2050 data
->inputstate
= INPUTSTATE_LASSO
;
2051 data
->lasso_active
= TRUE
;
2056 EnableMouseMoveEvents(obj
, data
);
2059 } /* if click on entry */
2060 else if ((col
= ColumnResizeHandleUnderMouse(data
, mx
, my
)) >= 0)
2062 data
->inputstate
= INPUTSTATE_COL_RESIZE
;
2063 data
->click_column
= col
;
2064 data
->click_x
= mx
- data
->column_width
[col
];
2066 EnableMouseMoveEvents(obj
, data
);
2068 } /* else if click on column header entry resize handle */
2069 else if ((col
= ColumnHeaderUnderMouse(data
, mx
, my
)) >= 0)
2071 data
->inputstate
= INPUTSTATE_COL_HEADER_CLICK
;
2072 data
->click_column
= col
;
2076 EnableMouseMoveEvents(obj
, data
);
2078 data
->update
= UPDATE_HEADER
;
2079 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
2082 } /* if (data->inputstate == INPUTSTATE_NONE) */
2086 if (data
->inputstate
== INPUTSTATE_COL_RESIZE
)
2088 DisableMouseMoveEvents(obj
, data
);
2090 data
->inputstate
= INPUTSTATE_NONE
;
2092 else if (data
->inputstate
== INPUTSTATE_COL_HEADER_CLICK
)
2094 DisableMouseMoveEvents(obj
, data
);
2096 data
->inputstate
= INPUTSTATE_NONE
;
2098 if (ColumnHeaderUnderMouse(data
, data
->click_x
, data
->click_y
) == data
->click_column
)
2101 if (data
->column_sortable
[data
->click_column
])
2103 if (data
->sort_column
== data
->click_column
)
2105 data
->sort_direction
= 1 - data
->sort_direction
;
2109 data
->sort_direction
= SORT_DIRECTION_UP
;
2110 data
->sort_column
= data
->click_column
;
2113 ReSortEntries(data
);
2115 data
->update
= UPDATE_ALL
;
2116 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
2121 data
->update
= UPDATE_HEADER
;
2122 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
2125 } /* mouse still over column header */
2127 } /* else if (data->inputstate == INPUTSTATE_COL_HEADER_CLICK) */
2128 else if (data
->inputstate
== INPUTSTATE_LASSO
)
2130 DisableMouseMoveEvents(obj
, data
);
2131 DisableAutoScrollTimer(obj
, data
);
2133 data
->inputstate
= INPUTSTATE_NONE
;
2134 data
->lasso_active
= FALSE
;
2136 data
->update
= UPDATE_ALL
;
2137 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
2142 if (data
->inputstate
== INPUTSTATE_NONE
)
2144 data
->inputstate
= INPUTSTATE_PAN
;
2146 data
->click_x
= mx
- data
->view_rect
.MinX
+ data
->view_x
;
2147 data
->click_y
= my
- data
->view_rect
.MinY
+ data
->view_y
;
2149 EnableMouseMoveEvents(obj
, data
);
2155 if (data
->inputstate
== INPUTSTATE_PAN
)
2157 DisableMouseMoveEvents(obj
, data
);
2159 data
->inputstate
= INPUTSTATE_NONE
;
2163 } /* switch(msg->imsg->Code) */
2166 case IDCMP_MOUSEMOVE
:
2167 if (data
->inputstate
== INPUTSTATE_PAN
)
2169 LONG new_view_x
, new_view_y
;
2171 new_view_x
= data
->click_x
- (mx
- data
->view_rect
.MinX
);
2172 new_view_y
= data
->click_y
- (my
- data
->view_rect
.MinY
);
2174 if (new_view_x
+ data
->view_width
> data
->width
)
2176 new_view_x
= data
->width
- data
->view_width
;
2178 if (new_view_x
< 0) new_view_x
= 0;
2180 if (new_view_y
+ data
->view_height
> data
->height
)
2182 new_view_y
= data
->height
- data
->view_height
;
2184 if (new_view_y
< 0) new_view_y
= 0;
2186 if ((new_view_x
!= data
->view_x
) || (new_view_y
!= data
->view_y
))
2188 SetAttrs(obj
, MUIA_TextIconList_Left
, new_view_x
,
2189 MUIA_TextIconList_Top
, new_view_y
,
2193 } /* if (data->inputstate == INPUTSTATE_PAN) */
2194 else if (data
->inputstate
== INPUTSTATE_COL_RESIZE
)
2196 LONG act_colwidth
= data
->column_width
[data
->click_column
];
2197 LONG new_colwidth
= mx
- data
->click_x
;
2199 if (new_colwidth
< MIN_COLUMN_WIDTH
) new_colwidth
= MIN_COLUMN_WIDTH
;
2201 if (new_colwidth
> act_colwidth
)
2203 data
->column_width
[data
->click_column
] = new_colwidth
;
2204 data
->width
+= new_colwidth
- act_colwidth
;
2205 data
->update
= UPDATE_ALL
;
2206 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
2208 set(obj
, MUIA_TextIconList_Width
, data
->width
);
2210 else if (new_colwidth
< act_colwidth
)
2212 BOOL scroll_left
= FALSE
;
2214 data
->column_width
[data
->click_column
] = new_colwidth
;
2215 data
->width
+= new_colwidth
- act_colwidth
;
2217 if (data
->view_x
+ data
->view_width
> data
->width
)
2219 LONG new_view_x
= data
->width
- data
->view_width
;
2221 if (new_view_x
< 0) new_view_x
= 0;
2222 if (new_view_x
!= data
->view_x
)
2225 data
->view_x
= new_view_x
;
2229 data
->update
= UPDATE_ALL
;
2230 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
2232 SetAttrs(obj
, scroll_left
? MUIA_TextIconList_Left
: TAG_IGNORE
, data
->view_x
,
2233 MUIA_TextIconList_Width
, data
->width
,
2236 } /* else if (new_colwidth < act_colwidth) */
2238 } /* else if (data->inputstate == INPUTSTATE_COL_RESIZE) */
2239 else if (data
->inputstate
== INPUTSTATE_COL_HEADER_CLICK
)
2241 BOOL old
= ColumnHeaderUnderMouse(data
, data
->click_x
, data
->click_y
);
2242 BOOL
new = ColumnHeaderUnderMouse(data
, mx
, my
);
2248 data
->update
= UPDATE_HEADER
;
2249 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
2252 else if (data
->inputstate
== INPUTSTATE_LASSO
)
2254 struct Rectangle old_lasso
, new_lasso
;
2255 struct Region
*region
;
2261 data
->old_lasso_rect
= data
->lasso_rect
;
2262 GetAbsoluteLassoRect(data
, &old_lasso
);
2263 data
->lasso_rect
.MaxX
= mx
- data
->view_rect
.MinX
+ data
->view_x
;
2264 data
->lasso_rect
.MaxY
= my
- data
->view_rect
.MinY
+ data
->view_y
;
2265 GetAbsoluteLassoRect(data
, &new_lasso
);
2267 region
= NewRectRegion(new_lasso
.MinX
, new_lasso
.MinY
, new_lasso
.MaxX
, new_lasso
.MaxY
);
2270 struct Rectangle render_range
;
2272 XorRectRegion(region
, &old_lasso
);
2273 OrRectOutlineRegion(region
, &old_lasso
);
2274 OrRectOutlineRegion(region
, &new_lasso
);
2276 render_range
= region
->bounds
;
2278 clip
= MUI_AddClipRegion(muiRenderInfo(obj
), region
);
2280 data
->update
= UPDATE_ALL
;
2281 data
->update_rect1
= &render_range
;
2282 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
2283 data
->update_rect1
= 0;
2285 MUI_RemoveClipRegion(muiRenderInfo(obj
), clip
);
2288 RethinkLasso(obj
, data
);
2290 if ((mx
>= data
->view_rect
.MinX
) &&
2291 (my
>= data
->view_rect
.MinY
) &&
2292 (mx
<= data
->view_rect
.MaxX
) &&
2293 (my
<= data
->view_rect
.MaxY
))
2295 DisableAutoScrollTimer(obj
, data
);
2299 EnableAutoScrollTimer(obj
, data
);
2306 } /* switch (msg->imsg->Class) */
2308 } /* if (msg->imsg) */
2314 /**************************************************************************
2315 MUIM_TextIconList_Clear
2316 **************************************************************************/
2317 static IPTR
TextIconList_Clear(struct IClass
*cl
, Object
*obj
, struct MUIP_TextIconList_Clear
*msg
)
2319 struct TextIconList_DATA
*data
= INST_DATA(cl
, obj
);
2320 struct TextIconEntry
*node
;
2323 while ((node
= (struct TextIconEntry
*)RemTail((struct List
*)&data
->entries_list
)))
2325 FreePooled(data
->pool
,node
,sizeof(*node
));
2327 NewList((struct List
*)&data
->selection_list
);
2329 data
->view_x
= data
->view_y
= data
->width
= data
->height
= 0;
2330 data
->num_entries
= 0;
2331 data
->active_entry
= -1;
2332 data
->num_selected
= 0;
2335 for(i
= 0; i
< NUM_COLUMNS
; i
++)
2337 data
->column_maxwidth
[i
] = 0;
2340 SetAttrs(obj
, MUIA_TextIconList_Left
, data
->view_x
,
2341 MUIA_TextIconList_Top
, data
->view_y
,
2342 MUIA_TextIconList_Width
, data
->width
,
2343 MUIA_TextIconList_Height
, data
->height
,
2346 data
->update
= UPDATE_ALL
;
2347 MUI_Redraw(obj
,MADF_DRAWUPDATE
);
2351 /**************************************************************************
2352 MUIM_TextIconList_Add.
2353 Returns 0 on failure otherwise 1
2354 **************************************************************************/
2355 static IPTR
TextIconList_Add(struct IClass
*cl
, Object
*obj
, struct MUIP_TextIconList_Add
*msg
)
2357 struct TextIconList_DATA
*data
= INST_DATA(cl
, obj
);
2358 struct TextIconEntry
*entry
;
2362 if (!(entry
= AllocPooled(data
->pool
,sizeof(struct TextIconEntry
))))
2367 memset(entry
, 0, sizeof(struct TextIconEntry
));
2369 entry
->fib
= *msg
->fib
;
2371 if (entry
->fib
.fib_DirEntryType
> 0)
2373 strcpy(GetTextIconEntryText(data
, entry
, INDEX_SIZE
), "Drawer");
2377 sprintf(GetTextIconEntryText(data
, entry
, INDEX_SIZE
), "%ld", entry
->fib
.fib_Size
);
2380 dt
.dat_Stamp
= entry
->fib
.fib_Date
;
2381 dt
.dat_Format
= FORMAT_DOS
;
2383 dt
.dat_StrDay
= NULL
;
2384 dt
.dat_StrDate
= GetTextIconEntryText(data
, entry
, INDEX_DATE
);
2385 dt
.dat_StrTime
= GetTextIconEntryText(data
, entry
, INDEX_TIME
);;
2389 sp
= GetTextIconEntryText(data
, entry
, INDEX_PROTECTION
);
2390 *sp
++ = (entry
->fib
.fib_Protection
& FIBF_SCRIPT
) ? 's' : '-';
2391 *sp
++ = (entry
->fib
.fib_Protection
& FIBF_PURE
) ? 'p' : '-';
2392 *sp
++ = (entry
->fib
.fib_Protection
& FIBF_ARCHIVE
) ? 'a' : '-';
2393 *sp
++ = (entry
->fib
.fib_Protection
& FIBF_READ
) ? '-' : 'r';
2394 *sp
++ = (entry
->fib
.fib_Protection
& FIBF_WRITE
) ? '-' : 'w';
2395 *sp
++ = (entry
->fib
.fib_Protection
& FIBF_EXECUTE
) ? '-' : 'e';
2396 *sp
++ = (entry
->fib
.fib_Protection
& FIBF_DELETE
) ? '-' : 'd';
2399 data
->num_entries
++;
2401 SortInNode(data
, (struct List
*)&data
->entries_list
, (struct Node
*)entry
, (APTR
)CompareNodes
);
2405 CalcEntryDimension(data
, entry
);
2406 data
->height
+= data
->lineheight
;
2410 SetAttrs(obj
, MUIA_TextIconList_Width
, data
->width
,
2411 MUIA_TextIconList_Height
, data
->height
,
2418 BOOPSI_DISPATCHER(IPTR
,TextIconList_Dispatcher
, cl
, obj
, msg
)
2420 switch (msg
->MethodID
)
2423 case OM_NEW
: return TextIconList_New(cl
, obj
, (struct opSet
*)msg
);
2424 case OM_DISPOSE
: return TextIconList_Dispose(cl
,obj
, msg
);
2425 case OM_SET
: return TextIconList_Set(cl
,obj
,(struct opSet
*)msg
);
2426 case OM_GET
: return TextIconList_Get(cl
,obj
,(struct opGet
*)msg
);
2427 case MUIM_Setup
: return TextIconList_Setup(cl
,obj
,(struct MUIP_Setup
*)msg
);
2428 case MUIM_Show
: return TextIconList_Show(cl
,obj
,(struct MUIP_Show
*)msg
);
2429 case MUIM_Hide
: return TextIconList_Hide(cl
,obj
,(struct MUIP_Hide
*)msg
);
2430 case MUIM_Cleanup
: return TextIconList_Cleanup(cl
,obj
,(struct MUIP_Cleanup
*)msg
);
2431 case MUIM_AskMinMax
: return TextIconList_AskMinMax(cl
,obj
,(struct MUIP_AskMinMax
*)msg
);
2432 case MUIM_Draw
: return TextIconList_Draw(cl
,obj
,(struct MUIP_Draw
*)msg
);
2433 // case MUIM_Layout: return TextIconList_Layout(cl,obj,(struct MUIP_Layout *)msg);
2434 case MUIM_HandleEvent
: return TextIconList_HandleEvent(cl
,obj
,(struct MUIP_HandleEvent
*)msg
);
2435 // case MUIM_CreateDragImage: return TextIconList_CreateDragImage(cl,obj,(APTR)msg);
2436 // case MUIM_DeleteDragImage: return TextIconList_DeleteDragImage(cl,obj,(APTR)msg);
2437 // case MUIM_DragQuery: return TextIconList_DragQuery(cl,obj,(APTR)msg);
2438 // case MUIM_DragReport: return TextIconList_DragReport(cl,obj,(APTR)msg);
2439 // case MUIM_DragDrop: return TextIconList_DragDrop(cl,obj,(APTR)msg);
2441 // case MUIM_TextIconList_Update: return TextIconList_Update(cl,obj,(APTR)msg);
2442 case MUIM_TextIconList_Clear
: return TextIconList_Clear(cl
,obj
,(APTR
)msg
);
2443 case MUIM_TextIconList_Add
: return TextIconList_Add(cl
,obj
,(APTR
)msg
);
2444 // case MUIM_TextIconList_NextSelected: return TextIconList_NextSelected(cl,obj,(APTR)msg);
2445 // case MUIM_TextIconList_UnselectAll: return TextIconList_UnselectAll(cl,obj,(APTR)msg);
2447 case MUIM_TextIconList_AutoScroll
: return TextIconList_AutoScroll(cl
,obj
,(APTR
)msg
);
2450 return DoSuperMethodA(cl
, obj
, msg
);
2452 BOOPSI_DISPATCHER_END
2454 /*================ TextIconListview class ===================*/
2456 #define MUIB_TextIconListview (MUIB_AROS | 0x00000800)
2458 #define MUIA_TextIconListview_TextIconList (MUIB_TextIconListview | 0x00000000)
2459 #define MUIA_TextIconListview_UseWinBorder (MUIB_TextIconListview | 0x00000001)
2461 #define TextIconListviewObject BOOPSIOBJMACRO_START(CL_TextIconListview->mcc_Class)
2463 struct TextIconListview_DATA
2465 Object
*texticonlist
;
2466 Object
*vert
, *horiz
, *button
;
2468 struct Hook layout_hook
;
2472 IPTR
TextIconListview_Layout_Function(struct Hook
*hook
, Object
*obj
, struct MUI_LayoutMsg
*lm
)
2474 struct TextIconListview_DATA
*data
= (struct TextIconListview_DATA
*)hook
->h_Data
;
2476 switch (lm
->lm_Type
)
2480 /* Calulate the minmax dimension of the group,
2481 ** We only have a fixed number of children, so we need no NextObject()
2483 WORD maxxxxwidth
= 0;
2484 WORD maxxxxheight
= 0;
2486 maxxxxwidth
= _minwidth(data
->texticonlist
) + _minwidth(data
->vert
);
2487 if (_minwidth(data
->horiz
) > maxxxxwidth
) maxxxxwidth
= _minwidth(data
->horiz
);
2488 lm
->lm_MinMax
.MinWidth
= maxxxxwidth
;
2490 maxxxxheight
= _minheight(data
->texticonlist
) + _minheight(data
->horiz
);
2491 if (_minheight(data
->vert
) > maxxxxheight
) maxxxxheight
= _minheight(data
->vert
);
2492 lm
->lm_MinMax
.MinHeight
= maxxxxheight
;
2494 maxxxxwidth
= _defwidth(data
->texticonlist
) + _defwidth(data
->vert
);
2495 if (_defwidth(data
->horiz
) > maxxxxwidth
) maxxxxwidth
= _defwidth(data
->horiz
);
2496 lm
->lm_MinMax
.DefWidth
= maxxxxwidth
;
2498 maxxxxheight
= _defheight(data
->texticonlist
) + _defheight(data
->horiz
);
2499 if (_defheight(data
->vert
) > maxxxxheight
) maxxxxheight
= _defheight(data
->vert
);
2500 lm
->lm_MinMax
.DefHeight
= maxxxxheight
;
2502 lm
->lm_MinMax
.MaxWidth
= MUI_MAXMAX
;
2503 lm
->lm_MinMax
.MaxHeight
= MUI_MAXMAX
;
2510 /* Now place the objects between (0,0,lm->lm_Layout.Width-1,lm->lm_Layout.Height-1)
2515 LONG vert_width
= _minwidth(data
->vert
);
2516 LONG horiz_height
= _minheight(data
->horiz
);
2517 LONG lay_width
= lm
->lm_Layout
.Width
;
2518 LONG lay_height
= lm
->lm_Layout
.Height
;
2522 /* layout the virtual group a first time, to determine the virtual width/height */
2523 MUI_Layout(data
->texticonlist
,0,0,lay_width
,lay_height
,0);
2525 get(data
->texticonlist
, MUIA_TextIconList_Width
, &virt_width
);
2526 get(data
->texticonlist
, MUIA_TextIconList_Height
, &virt_height
);
2528 virt_width
+= _subwidth(data
->texticonlist
);
2529 virt_height
+= _subheight(data
->texticonlist
);
2531 if (virt_width
> lay_width
&& virt_height
> lay_height
)
2533 /* We need all scrollbars and the button */
2534 set(data
->vert
, MUIA_ShowMe
, TRUE
); /* We could also overload MUIM_Show... */
2535 set(data
->horiz
, MUIA_ShowMe
, TRUE
);
2536 set(data
->button
, MUIA_ShowMe
, TRUE
);
2537 cont_width
= lay_width
- vert_width
;
2538 cont_height
= lay_height
- horiz_height
;
2539 MUI_Layout(data
->vert
, cont_width
, 0, vert_width
, cont_height
,0);
2540 MUI_Layout(data
->horiz
, 0, cont_height
, cont_width
, horiz_height
, 0);
2541 MUI_Layout(data
->button
, cont_width
, cont_height
, vert_width
, horiz_height
, 0);
2544 if (virt_height
> lay_height
)
2546 set(data
->vert
, MUIA_ShowMe
, TRUE
);
2547 set(data
->horiz
, MUIA_ShowMe
, FALSE
);
2548 set(data
->button
, MUIA_ShowMe
, FALSE
);
2550 cont_width
= lay_width
- vert_width
;
2551 cont_height
= lay_height
;
2552 MUI_Layout(data
->vert
, cont_width
, 0, vert_width
, cont_height
,0);
2555 if (virt_width
> lay_width
)
2557 set(data
->vert
, MUIA_ShowMe
, FALSE
);
2558 set(data
->horiz
, MUIA_ShowMe
, TRUE
);
2559 set(data
->button
, MUIA_ShowMe
, FALSE
);
2561 cont_width
= lay_width
;
2562 cont_height
= lay_height
- horiz_height
;
2563 MUI_Layout(data
->horiz
, 0, cont_height
, cont_width
, horiz_height
, 0);
2566 set(data
->vert
, MUIA_ShowMe
, FALSE
);
2567 set(data
->horiz
, MUIA_ShowMe
, FALSE
);
2568 set(data
->button
, MUIA_ShowMe
, FALSE
);
2570 cont_width
= lay_width
;
2571 cont_height
= lay_height
;
2576 /* Layout the group a second time, note that setting _mwidth() and _mheight() should be enough, or we invent a new flag */
2577 MUI_Layout(data
->texticonlist
,0,0,cont_width
,cont_height
,0);
2585 IPTR
TextIconListview_Function(struct Hook
*hook
, APTR dummyobj
, void **msg
)
2587 struct TextIconListview_DATA
*data
= (struct TextIconListview_DATA
*)hook
->h_Data
;
2588 int type
= (int)msg
[0];
2589 LONG val
= (LONG
)msg
[1];
2595 get(data
->vert
,MUIA_Prop_First
,&val
);
2596 SetAttrs(data
->texticonlist
,MUIA_TextIconList_Top
, val
, MUIA_NoNotify
, TRUE
, TAG_DONE
);
2602 get(data
->horiz
,MUIA_Prop_First
,&val
);
2603 SetAttrs(data
->texticonlist
,MUIA_TextIconList_Left
, val
, MUIA_NoNotify
, TRUE
, TAG_DONE
);
2606 case 3: nnset(data
->horiz
, MUIA_Prop_First
, val
); break;
2607 case 4: nnset(data
->vert
, MUIA_Prop_First
, val
); break;
2613 IPTR
TextIconListview__OM_NEW(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
)
2615 struct TextIconListview_DATA
*data
;
2616 //struct TagItem *tags,*tag;
2617 Object
*texticonlist
= (Object
*)GetTagData(MUIA_TextIconListview_TextIconList
, 0, msg
->ops_AttrList
);
2618 Object
*vert
,*horiz
,*button
,*group
;
2622 usewinborder
= GetTagData(MUIA_TextIconListview_UseWinBorder
, FALSE
, msg
->ops_AttrList
);
2624 if (!usewinborder
) button
= ScrollbuttonObject
, End
;
2627 obj
= (Object
*)DoSuperNewTags(cl
, obj
, NULL
,
2628 MUIA_Group_Horiz
, FALSE
,
2629 Child
, (IPTR
) (group
= GroupObject
,
2630 Child
, (IPTR
) texticonlist
,
2631 Child
, (IPTR
) (vert
= ScrollbarObject
,
2632 usewinborder
? MUIA_Prop_UseWinBorder
: TAG_IGNORE
, MUIV_Prop_UseWinBorder_Right
,
2633 MUIA_Prop_DeltaFactor
, 20,
2634 MUIA_Group_Horiz
, FALSE
,
2636 Child
, (IPTR
) (horiz
= ScrollbarObject
,
2637 usewinborder
?MUIA_Prop_UseWinBorder
:TAG_IGNORE
, MUIV_Prop_UseWinBorder_Bottom
,
2638 MUIA_Prop_DeltaFactor
, 20,
2639 MUIA_Group_Horiz
, TRUE
,
2641 usewinborder
? TAG_IGNORE
: Child
, (IPTR
) button
,
2650 data
= INST_DATA(cl
, obj
);
2652 data
->horiz
= horiz
;
2653 data
->button
= button
;
2654 data
->texticonlist
= texticonlist
;
2658 data
->layout_hook
.h_Entry
= HookEntry
;
2659 data
->layout_hook
.h_SubEntry
= (HOOKFUNC
)TextIconListview_Layout_Function
;
2660 data
->layout_hook
.h_Data
= data
;
2662 SetAttrs(group
, MUIA_Group_Forward
, FALSE
,
2663 MUIA_Group_LayoutHook
, (IPTR
) &data
->layout_hook
,
2667 data
->hook
.h_Entry
= HookEntry
;
2668 data
->hook
.h_SubEntry
= (HOOKFUNC
)TextIconListview_Function
;
2669 data
->hook
.h_Data
= data
;
2671 DoMethod(vert
, MUIM_Notify
, MUIA_Prop_First
, MUIV_EveryTime
, (IPTR
)obj
, 4, MUIM_CallHook
, (IPTR
)&data
->hook
, 1, MUIV_TriggerValue
);
2672 DoMethod(horiz
, MUIM_Notify
, MUIA_Prop_First
, MUIV_EveryTime
, (IPTR
)obj
, 4, MUIM_CallHook
, (IPTR
)&data
->hook
, 2, MUIV_TriggerValue
);
2673 DoMethod(texticonlist
, MUIM_Notify
, MUIA_TextIconList_Left
, MUIV_EveryTime
, (IPTR
)obj
, 4, MUIM_CallHook
, (IPTR
)&data
->hook
, 3, MUIV_TriggerValue
);
2674 DoMethod(texticonlist
, MUIM_Notify
, MUIA_TextIconList_Top
, MUIV_EveryTime
, (IPTR
)obj
, 4, MUIM_CallHook
, (IPTR
)&data
->hook
, 4, MUIV_TriggerValue
);
2675 DoMethod(texticonlist
, MUIM_Notify
, MUIA_TextIconList_Width
, MUIV_EveryTime
, (IPTR
)horiz
, 3, MUIM_NoNotifySet
, MUIA_Prop_Entries
, MUIV_TriggerValue
);
2676 DoMethod(texticonlist
, MUIM_Notify
, MUIA_TextIconList_Height
, MUIV_EveryTime
, (IPTR
)vert
, 3, MUIM_NoNotifySet
, MUIA_Prop_Entries
, MUIV_TriggerValue
);
2677 DoMethod(texticonlist
, MUIM_Notify
, MUIA_TextIconList_VisWidth
, MUIV_EveryTime
, (IPTR
)horiz
, 3, MUIM_NoNotifySet
, MUIA_Prop_Visible
, MUIV_TriggerValue
);
2678 DoMethod(texticonlist
, MUIM_Notify
, MUIA_TextIconList_VisHeight
, MUIV_EveryTime
, (IPTR
)vert
, 3, MUIM_NoNotifySet
, MUIA_Prop_Visible
, MUIV_TriggerValue
);
2684 IPTR
TextIconListview__OM_DISPOSE(struct IClass
*cl
, Object
*obj
, Msg msg
)
2686 //struct TextIconListview_DATA *data = INST_DATA(cl, obj);
2688 return DoSuperMethodA(cl
,obj
,msg
);
2691 IPTR
TextIconListview__MUIM_Show(struct IClass
*cl
, Object
*obj
, struct MUIP_Show
*msg
)
2693 struct TextIconListview_DATA
*data
= INST_DATA(cl
, obj
);
2694 IPTR top
,left
,width
,height
,viswidth
,visheight
;
2696 get(data
->texticonlist
, MUIA_TextIconList_Left
, &left
);
2697 get(data
->texticonlist
, MUIA_TextIconList_Top
, &top
);
2698 get(data
->texticonlist
, MUIA_TextIconList_Width
, &width
);
2699 get(data
->texticonlist
, MUIA_TextIconList_Height
, &height
);
2700 get(data
->texticonlist
, MUIA_TextIconList_VisWidth
, &viswidth
);
2701 get(data
->texticonlist
, MUIA_TextIconList_VisHeight
, &visheight
);
2703 SetAttrs(data
->horiz
, MUIA_Prop_First
, left
,
2704 MUIA_Prop_Entries
, width
,
2705 MUIA_Prop_Visible
, viswidth
,
2709 SetAttrs(data
->vert
, MUIA_Prop_First
, top
,
2710 MUIA_Prop_Entries
, height
,
2711 MUIA_Prop_Visible
, visheight
,
2714 return DoSuperMethodA(cl
,obj
,(Msg
)msg
);
2717 BOOPSI_DISPATCHER(IPTR
,TextIconListview_Dispatcher
, cl
, obj
, msg
)
2719 switch (msg
->MethodID
)
2721 case OM_NEW
: return TextIconListview__OM_NEW(cl
, obj
, (struct opSet
*) msg
);
2722 case OM_DISPOSE
: return TextIconListview__OM_DISPOSE(cl
, obj
, msg
);
2723 case MUIM_Show
: return TextIconListview__MUIM_Show(cl
, obj
, (struct MUIP_Show
*)msg
);
2726 return DoSuperMethodA(cl
, obj
, msg
);
2729 BOOPSI_DISPATCHER_END
2734 Object
*wnd
, *texticonlist
;
2739 MUIMasterBase
= (struct Library
*)OpenLibrary("muimaster.library",0);
2741 CL_TextIconListview
= MUI_CreateCustomClass(NULL
,MUIC_Group
,NULL
,sizeof(struct TextIconListview_DATA
), TextIconListview_Dispatcher
);
2742 CL_TextIconList
= MUI_CreateCustomClass(NULL
,MUIC_Area
,NULL
,sizeof(struct TextIconList_DATA
), TextIconList_Dispatcher
);
2744 app
= ApplicationObject
,
2745 SubWindow
, (IPTR
) (wnd
= WindowObject
,
2746 MUIA_Window_Title
, (IPTR
) "texticonlist",
2747 MUIA_Window_Activate
, TRUE
,
2749 WindowContents
, (IPTR
) VGroup
,
2750 MUIA_Background
, MUII_GroupBack
,
2752 Child
, (IPTR
) IconListviewObject
,
2753 MUIA_IconListview_IconList
, (IPTR
) (iconlist
= IconDrawerListObject
,
2755 MUIA_IconDrawerList_Drawer
, (IPTR
) "C:",
2759 Child
, (IPTR
) TextIconListviewObject
,
2760 // MUIA_TextIconListview_UseWinBorder, TRUE,
2761 MUIA_TextIconListview_TextIconList
, (IPTR
) (texticonlist
= TextIconListObject
,
2768 Child, (IPTR) (texticonlist = TextIconListObject, InputListFrame, End),
2780 wnd
, MUIM_Notify
, MUIA_Window_CloseRequest
, TRUE
, (IPTR
) app
,
2781 2, MUIM_Application_ReturnID
, MUIV_Application_ReturnID_Quit
2785 BPTR lock
= Lock("C:", SHARED_LOCK
);
2789 struct FileInfoBlock
*fib
= AllocDosObject(DOS_FIB
, NULL
);
2792 if (Examine(lock
, fib
))
2794 while(ExNext(lock
, fib
))
2796 DoMethod(texticonlist
, MUIM_TextIconList_Add
, (IPTR
) fib
);
2800 FreeDosObject(DOS_FIB
, fib
);
2807 set(wnd
,MUIA_Window_Open
,TRUE
);
2809 set(iconlist
, MUIA_IconDrawerList_Drawer
, "C:");
2812 while (DoMethod(app
, MUIM_Application_NewInput
, (IPTR
) &sigs
) != MUIV_Application_ReturnID_Quit
)
2816 sigs
= Wait(sigs
| SIGBREAKF_CTRL_C
| SIGBREAKF_CTRL_D
);
2817 if (sigs
& SIGBREAKF_CTRL_C
) break;
2818 if (sigs
& SIGBREAKF_CTRL_D
) break;
2822 MUI_DisposeObject(app
);
2825 MUI_DeleteCustomClass(CL_TextIconList
);
2826 MUI_DeleteCustomClass(CL_TextIconListview
);
2828 CloseLibrary(MUIMasterBase
);