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
;
1072 LONG x1
= 0, x2
= 0;
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
;
1253 struct TagItem
*tags
;
1254 LONG oldleft
= data
->view_x
, oldtop
= data
->view_y
;
1256 /* parse initial taglist */
1257 for (tags
= msg
->ops_AttrList
; (tag
= NextTagItem(&tags
)); )
1259 switch (tag
->ti_Tag
)
1261 case MUIA_TextIconList_Left
:
1262 if (data
->view_x
!= (LONG
)tag
->ti_Data
)
1264 LONG new_view_x
= (LONG
)tag
->ti_Data
;
1266 if (new_view_x
+ data
->view_width
> data
->width
)
1268 new_view_x
= data
->width
- data
->view_width
;
1270 if (new_view_x
< 0) new_view_x
= 0;
1272 data
->view_x
= new_view_x
;
1273 tag
->ti_Data
= new_view_x
;
1277 case MUIA_TextIconList_Top
:
1278 if (data
->view_y
!= (LONG
)tag
->ti_Data
)
1280 LONG new_view_y
= (LONG
)tag
->ti_Data
;
1282 if (new_view_y
+ data
->view_height
> data
->height
)
1284 new_view_y
= data
->height
- data
->view_height
;
1286 if (new_view_y
< 0) new_view_y
= 0;
1288 data
->view_y
= new_view_y
;
1289 tag
->ti_Data
= new_view_y
;
1295 if ((oldleft
!= data
->view_x
) || (oldtop
!= data
->view_y
))
1297 data
->update
= UPDATE_SCROLL
;
1298 data
->update_scrolldx
= data
->view_x
- oldleft
;
1299 data
->update_scrolldy
= data
->view_y
- oldtop
;
1301 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
1304 return DoSuperMethodA(cl
, obj
, (Msg
)msg
);
1307 /**************************************************************************
1309 **************************************************************************/
1310 static IPTR
TextIconList_Get(struct IClass
*cl
, Object
*obj
, struct opGet
*msg
)
1312 /* small macro to simplify return value storage */
1313 #define STORE *(msg->opg_Storage)
1314 struct TextIconList_DATA
*data
= INST_DATA(cl
, obj
);
1316 switch (msg
->opg_AttrID
)
1318 case MUIA_TextIconList_Left
: STORE
= data
->view_x
; return 1;
1319 case MUIA_TextIconList_Top
: STORE
= data
->view_y
; return 1;
1320 case MUIA_TextIconList_Width
: STORE
= data
->width
; return 1;
1321 case MUIA_TextIconList_Height
: STORE
= data
->height
; return 1;
1324 return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
1328 /**************************************************************************
1330 **************************************************************************/
1331 static IPTR
TextIconList_Setup(struct IClass
*cl
, Object
*obj
, struct MUIP_Setup
*msg
)
1333 struct TextIconList_DATA
*data
= INST_DATA(cl
, obj
);
1336 if (!DoSuperMethodA(cl
, obj
, (Msg
) msg
)) return 0;
1338 DoMethod(_win(obj
),MUIM_Window_AddEventHandler
, (IPTR
)&data
->ehn
);
1340 InitRastPort(&data
->temprp
);
1341 SetFont(&data
->temprp
, _font(obj
));
1342 data
->truecolor
= GetBitMapAttr(_screen(obj
)->RastPort
.BitMap
, BMA_DEPTH
) >= 15;
1344 data
->lineheight
= LINE_EXTRAHEIGHT
+ _font(obj
)->tf_YSize
;
1345 data
->is_setup
= TRUE
;
1347 for(i
= 0; i
< NUM_COLORS
; i
++)
1349 data
->colors
[i
].rgbpixel
= rgb_colors
[i
];
1350 data
->colors
[i
].pixel
= data
->colors
[i
].rgbpixel
;
1352 if (!data
->truecolor
|| !CyberGfxBase
)
1354 ULONG r
= (rgb_colors
[i
] & 0x00FF0000) >> 16;
1355 ULONG g
= (rgb_colors
[i
] & 0x0000FF00) >> 8;
1356 ULONG b
= (rgb_colors
[i
] & 0x000000FF);
1358 LONG pen
= ObtainBestPen(_screen(obj
)->ViewPort
.ColorMap
,
1362 OBP_FailIfBad
, FALSE
,
1363 OBP_Precision
, PRECISION_GUI
,
1368 data
->colors
[i
].pixel
= pen
;
1369 data
->colors
[i
].alloced
= TRUE
;
1373 data
->colors
[i
].pixel
= _pens(obj
)[pen_colors
[i
]];
1374 data
->colors
[i
].alloced
= FALSE
;
1379 if (data
->show_header
)
1381 data
->headerheight
= HEADERLINE_EXTRAHEIGHT
+ _font(obj
)->tf_YSize
;
1385 data
->headerheight
= 0;
1388 if (data
->num_entries
)
1390 CalcAllEntryDimensions(data
);
1392 data
->height
= data
->num_entries
* data
->lineheight
;
1393 RecalcColumnMaxWidths(data
);
1395 SetAttrs(obj
, MUIA_TextIconList_Width
, data
->width
,
1396 MUIA_TextIconList_Height
, data
->height
,
1403 /**************************************************************************
1405 **************************************************************************/
1406 static IPTR
TextIconList_Show(struct IClass
*cl
, Object
*obj
, struct MUIP_Show
*msg
)
1408 struct TextIconList_DATA
*data
= INST_DATA(cl
, obj
);
1409 LONG newleft
, newtop
;
1412 rc
= DoSuperMethodA(cl
, obj
, (Msg
)msg
);
1414 newleft
= data
->view_x
;
1415 newtop
= data
->view_y
;
1417 data
->view_width
= _mwidth(obj
);
1418 data
->view_height
= _mheight(obj
) - data
->headerheight
;
1420 SetAttrs(obj
, MUIA_TextIconList_VisWidth
, data
->view_width
,
1421 MUIA_TextIconList_VisHeight
, data
->view_height
,
1424 data
->view_rect
.MinX
= _mleft(obj
);
1425 data
->view_rect
.MinY
= _mtop(obj
) + data
->headerheight
;
1426 data
->view_rect
.MaxX
= _mright(obj
);
1427 data
->view_rect
.MaxY
= _mbottom(obj
);
1429 data
->header_rect
.MinX
= _mleft(obj
);
1430 data
->header_rect
.MinY
= _mtop(obj
);
1431 data
->header_rect
.MaxX
= _mright(obj
);
1432 data
->header_rect
.MaxY
= _mtop(obj
) + data
->headerheight
- 1;
1434 if (newleft
+ data
->view_width
> data
->width
) newleft
= data
->width
- data
->view_width
;
1435 if (newleft
< 0) newleft
= 0;
1437 if (newtop
+ data
->view_height
> data
->height
) newtop
= data
->height
- data
->view_height
;
1438 if (newtop
< 0) newtop
= 0;
1440 if ((newleft
!= data
->view_x
) || (newtop
!= data
->view_y
))
1442 SetAttrs(obj
, MUIA_TextIconList_Left
, newleft
,
1443 MUIA_TextIconList_Top
, newtop
,
1447 SetFont(_rp(obj
), _font(obj
));
1449 data
->is_shown
= TRUE
;
1454 /**************************************************************************
1456 **************************************************************************/
1457 static IPTR
TextIconList_Hide(struct IClass
*cl
, Object
*obj
, struct MUIP_Hide
*msg
)
1459 struct TextIconList_DATA
*data
= INST_DATA(cl
, obj
);
1462 data
->is_shown
= FALSE
;
1464 rc
= DoSuperMethodA(cl
, obj
, (Msg
)msg
);
1469 /**************************************************************************
1471 **************************************************************************/
1472 static IPTR
TextIconList_Cleanup(struct IClass
*cl
, Object
*obj
, struct MUIP_Cleanup
*msg
)
1474 struct TextIconList_DATA
*data
= INST_DATA(cl
, obj
);
1477 DoMethod(_win(obj
),MUIM_Window_RemEventHandler
, (IPTR
)&data
->ehn
);
1479 for(i
= 0; i
< NUM_COLORS
; i
++)
1481 if (data
->colors
[i
].alloced
)
1483 ReleasePen(_screen(obj
)->ViewPort
.ColorMap
, data
->colors
[i
].pixel
);
1484 data
->colors
[i
].alloced
= FALSE
;
1488 data
->is_setup
= FALSE
;
1490 return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
1493 /**************************************************************************
1495 **************************************************************************/
1496 static IPTR
TextIconList_AskMinMax(struct IClass
*cl
, Object
*obj
, struct MUIP_AskMinMax
*msg
)
1498 ULONG rc
= DoSuperMethodA(cl
, obj
, (Msg
) msg
);
1500 msg
->MinMaxInfo
->MinWidth
+= 10;
1501 msg
->MinMaxInfo
->MinHeight
+= 10;
1503 msg
->MinMaxInfo
->DefWidth
+= 100;
1504 msg
->MinMaxInfo
->DefHeight
+= 100;
1506 msg
->MinMaxInfo
->MaxWidth
= MUI_MAXMAX
;
1507 msg
->MinMaxInfo
->MaxHeight
= MUI_MAXMAX
;
1512 static void DrawHeaderLine(Object
*obj
, struct TextIconList_DATA
*data
)
1516 if (data
->show_header
&& MustRenderRect(data
, &data
->header_rect
))
1518 clip
= MUI_AddClipping(muiRenderInfo(obj
), data
->header_rect
.MinX
,
1519 data
->header_rect
.MinY
,
1520 data
->header_rect
.MaxX
- data
->header_rect
.MinX
+ 1,
1521 data
->header_rect
.MaxY
- data
->header_rect
.MinY
+ 1);
1523 RenderHeaderline(obj
, data
);
1525 MUI_RemoveClipping(muiRenderInfo(obj
),clip
);
1529 static void DrawLassoOutline(Object
*obj
, struct TextIconList_DATA
*data
)
1531 struct Rectangle lasso
;
1533 GetAbsoluteLassoRect(data
, &lasso
);
1536 MyRectFill(data
, _rp(obj
), lasso
.MinX
, lasso
.MinY
, lasso
.MaxX
, lasso
.MinY
, COLOR_SELECTED_BACKGROUND
);
1537 MyRectFill(data
, _rp(obj
), lasso
.MaxX
, lasso
.MinY
, lasso
.MaxX
, lasso
.MaxY
, COLOR_SELECTED_BACKGROUND
);
1538 MyRectFill(data
, _rp(obj
), lasso
.MinX
, lasso
.MaxY
, lasso
.MaxX
, lasso
.MaxY
, COLOR_SELECTED_BACKGROUND
);
1539 MyRectFill(data
, _rp(obj
), lasso
.MinX
, lasso
.MinY
, lasso
.MinX
, lasso
.MaxY
, COLOR_SELECTED_BACKGROUND
);
1541 SetABPenDrMd(_rp(obj
), _pens(obj
)[MPEN_SHADOW
], 0, JAM1
);
1542 Move(_rp(obj
), lasso
.MinX
, lasso
.MinY
);
1543 Draw(_rp(obj
), lasso
.MaxX
, lasso
.MinY
);
1544 Draw(_rp(obj
), lasso
.MaxX
, lasso
.MaxY
);
1545 Draw(_rp(obj
), lasso
.MinX
, lasso
.MaxY
);
1546 Draw(_rp(obj
), lasso
.MinX
, lasso
.MinY
);
1550 /**************************************************************************
1552 **************************************************************************/
1553 static IPTR
TextIconList_Draw(struct IClass
*cl
, Object
*obj
, struct MUIP_Draw
*msg
)
1555 struct TextIconList_DATA
*data
= INST_DATA(cl
, obj
);
1557 struct TextIconEntry
*entry
;
1559 DoSuperMethodA(cl
, obj
, (Msg
) msg
);
1561 if (msg
->flags
& MADF_DRAWUPDATE
)
1563 if (data
->update
== UPDATE_SCROLL
)
1565 struct Region
*region
;
1566 struct Rectangle xrect
, yrect
;
1567 BOOL scroll_caused_damage
;
1569 scroll_caused_damage
= (_rp(obj
)->Layer
->Flags
& LAYERREFRESH
) ? FALSE
: TRUE
;
1573 if ((abs(data
->update_scrolldx
) >= data
->view_width
) ||
1574 (abs(data
->update_scrolldy
) >= data
->view_height
))
1576 data
->update
= UPDATE_ALL
;
1577 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
1581 region
= NewRegion();
1584 data
->update
= UPDATE_ALL
;
1585 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
1589 if (data
->update_scrolldx
> 0)
1591 xrect
.MinX
= data
->view_rect
.MaxX
- data
->update_scrolldx
;
1592 xrect
.MinY
= data
->view_rect
.MinY
;
1593 xrect
.MaxX
= data
->view_rect
.MaxX
;
1594 xrect
.MaxY
= data
->view_rect
.MaxY
;
1596 OrRectRegion(region
, &xrect
);
1598 data
->update_rect1
= &xrect
;
1600 else if (data
->update_scrolldx
< 0)
1602 xrect
.MinX
= data
->view_rect
.MinX
;
1603 xrect
.MinY
= data
->view_rect
.MinY
;
1604 xrect
.MaxX
= data
->view_rect
.MinX
- data
->update_scrolldx
;
1605 xrect
.MaxY
= data
->view_rect
.MaxY
;
1607 OrRectRegion(region
, &xrect
);
1609 data
->update_rect1
= &xrect
;
1612 if (data
->update_scrolldy
> 0)
1614 yrect
.MinX
= data
->view_rect
.MinX
;
1615 yrect
.MinY
= data
->view_rect
.MaxY
- data
->update_scrolldy
;
1616 yrect
.MaxX
= data
->view_rect
.MaxX
;
1617 yrect
.MaxY
= data
->view_rect
.MaxY
;
1619 OrRectRegion(region
, &yrect
);
1621 data
->update_rect2
= &yrect
;
1623 else if (data
->update_scrolldy
< 0)
1625 yrect
.MinX
= data
->view_rect
.MinX
;
1626 yrect
.MinY
= data
->view_rect
.MinY
;
1627 yrect
.MaxX
= data
->view_rect
.MaxX
;
1628 yrect
.MaxY
= data
->view_rect
.MinY
- data
->update_scrolldy
;
1630 OrRectRegion(region
, &yrect
);
1632 data
->update_rect2
= &yrect
;
1635 ScrollRasterBF(_rp(obj
),
1636 data
->update_scrolldx
,
1637 data
->update_scrolldy
,
1638 data
->view_rect
.MinX
,
1639 data
->view_rect
.MinY
,
1640 data
->view_rect
.MaxX
,
1641 data
->view_rect
.MaxY
);
1643 if (data
->show_header
&& data
->update_scrolldx
)
1645 ScrollRasterBF(_rp(obj
),
1646 data
->update_scrolldx
,
1648 data
->header_rect
.MinX
,
1649 data
->header_rect
.MinY
,
1650 data
->header_rect
.MaxX
,
1651 data
->header_rect
.MaxY
);
1654 scroll_caused_damage
= scroll_caused_damage
&& (_rp(obj
)->Layer
->Flags
& LAYERREFRESH
) ? TRUE
: FALSE
;
1656 clip
= MUI_AddClipRegion(muiRenderInfo(obj
), region
);
1657 data
->update
= UPDATE_ALL
;
1658 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
1659 MUI_RemoveClipRegion(muiRenderInfo(obj
), clip
);
1661 if (data
->show_header
&& data
->update_scrolldx
)
1663 xrect
.MinY
= data
->header_rect
.MinY
;
1664 xrect
.MaxY
= data
->header_rect
.MaxY
;
1666 data
->update_rect1
= &xrect
;
1667 data
->update_rect2
= NULL
;
1669 clip
= MUI_AddClipping(muiRenderInfo(obj
), xrect
.MinX
,
1671 xrect
.MaxX
- xrect
.MinX
+ 1,
1672 xrect
.MaxY
- xrect
.MinY
+ 1);
1674 data
->update
= UPDATE_ALL
;
1675 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
1676 MUI_RemoveClipRegion(muiRenderInfo(obj
), clip
);
1678 data
->update_rect2
= NULL
;
1682 data
->update_rect1
= data
->update_rect2
= NULL
;
1683 data
->update_scrolldx
= data
->update_scrolldy
= 0;
1685 // DisposeRegion(region);
1687 if (scroll_caused_damage
)
1689 if (MUI_BeginRefresh(muiRenderInfo(obj
), 0))
1691 /* Theoretically it might happen that more damage is caused
1692 after ScrollRaster. By something else, like window movement
1693 in front of our window. Therefore refresh root object of
1694 window, not just this object */
1698 get(_win(obj
),MUIA_Window_RootObject
, &o
);
1699 MUI_Redraw(o
, MADF_DRAWOBJECT
);
1701 MUI_EndRefresh(muiRenderInfo(obj
), 0);
1707 } /* if (data->update == UPDATE_SCROLL) */
1708 else if (data
->update
== UPDATE_DIRTY_ENTRIES
)
1710 struct Region
*clipregion
;
1711 LONG first
, numvisible
, index
= 0;
1715 clipregion
= NewRectRegion(data
->view_rect
.MinX
,
1716 data
->view_rect
.MinY
,
1717 data
->view_rect
.MaxX
,
1718 data
->view_rect
.MaxY
);
1722 if (data
->lasso_active
)
1724 struct Rectangle lasso_rect
;
1726 GetAbsoluteLassoRect(data
, &lasso_rect
);
1727 ClearRectRegion(clipregion
, &lasso_rect
);
1730 clip
= MUI_AddClipRegion(muiRenderInfo(obj
), clipregion
);
1732 first
= FirstVisibleLine(data
);
1733 numvisible
= NumVisibleLines(data
);
1735 ForeachNode(&data
->entries_list
, entry
)
1739 if ((index
>= first
) && (index
< first
+ numvisible
))
1741 RenderEntry(obj
, data
, index
);
1747 if (data
->lasso_active
)
1749 struct Rectangle lasso_rect
;
1750 struct Rectangle vis_lasso_rect
;
1752 GetAbsoluteLassoRect(data
, &lasso_rect
);
1754 if (AndRectRect(&data
->view_rect
, &lasso_rect
, &vis_lasso_rect
))
1756 MUI_RemoveClipRegion(muiRenderInfo(obj
),clip
);
1758 clipregion
= NewRectRegion(vis_lasso_rect
.MinX
,
1759 vis_lasso_rect
.MinY
,
1760 vis_lasso_rect
.MaxX
,
1761 vis_lasso_rect
.MaxY
);
1763 data
->lasso_paint
= TRUE
;
1765 clip
= MUI_AddClipRegion(muiRenderInfo(obj
), clipregion
);
1768 ForeachNode(&data
->entries_list
, entry
)
1772 if ((index
>= first
) && (index
< first
+ numvisible
))
1774 RenderEntry(obj
, data
, index
);
1780 data
->lasso_paint
= FALSE
;
1782 DrawLassoOutline(obj
, data
);
1784 } /* if (AndRectRect(&data->view_rect, &lasso_rect, &vis_lasso_rect)) */
1786 } /* if (data->lasso_active) */
1788 MUI_RemoveClipRegion(muiRenderInfo(obj
), clip
);
1790 ForeachNode(&data
->entries_list
, entry
)
1792 if (entry
->dirty
) entry
->dirty
= FALSE
;
1797 } /* else if (data->update == UPDATE_DIRTY_ENTRIES) */
1798 else if (data
->update
== UPDATE_HEADER
)
1802 DrawHeaderLine(obj
, data
);
1807 } /* if (msg->flags & MADF_DRAWUPDATE) */
1809 if (MustRenderRect(data
, &data
->view_rect
))
1811 struct Region
*clipregion
;
1813 clipregion
= NewRectRegion(data
->view_rect
.MinX
,
1814 data
->view_rect
.MinY
,
1815 data
->view_rect
.MaxX
,
1816 data
->view_rect
.MaxY
);
1820 if (data
->lasso_active
)
1822 struct Rectangle lasso_rect
;
1824 GetAbsoluteLassoRect(data
, &lasso_rect
);
1825 ClearRectRegion(clipregion
, &lasso_rect
);
1828 clip
= MUI_AddClipRegion(muiRenderInfo(obj
), clipregion
);
1830 RenderAllEntries(obj
, data
);
1832 if (data
->lasso_active
)
1834 struct Rectangle lasso_rect
;
1835 struct Rectangle vis_lasso_rect
;
1837 GetAbsoluteLassoRect(data
, &lasso_rect
);
1839 if (AndRectRect(&data
->view_rect
, &lasso_rect
, &vis_lasso_rect
))
1841 MUI_RemoveClipRegion(muiRenderInfo(obj
),clip
);
1843 clipregion
= NewRectRegion(vis_lasso_rect
.MinX
,
1844 vis_lasso_rect
.MinY
,
1845 vis_lasso_rect
.MaxX
,
1846 vis_lasso_rect
.MaxY
);
1848 data
->lasso_paint
= TRUE
;
1850 clip
= MUI_AddClipRegion(muiRenderInfo(obj
), clipregion
);
1852 RenderAllEntries(obj
, data
);
1854 data
->lasso_paint
= FALSE
;
1856 DrawLassoOutline(obj
, data
);
1861 MUI_RemoveClipRegion(muiRenderInfo(obj
),clip
);
1863 } /* if (clipregion) */
1865 } /* if (MustRenderRect(data, &data->view_rect)) */
1867 DrawHeaderLine(obj
, data
);
1874 /**************************************************************************
1876 **************************************************************************/
1877 static IPTR
TextIconList_AutoScroll(struct IClass
*cl
, Object
*obj
, Msg msg
)
1879 struct TextIconList_DATA
*data
= INST_DATA(cl
, obj
);
1881 if (data
->lasso_active
)
1883 LONG new_view_x
, new_view_y
;
1885 new_view_x
= data
->view_x
;
1886 new_view_y
= data
->view_y
;
1888 if (data
->click_x
< data
->view_rect
.MinX
)
1890 new_view_x
-= (data
->view_rect
.MinX
- data
->click_x
) / 4;
1892 else if (data
->click_x
> data
->view_rect
.MaxX
)
1894 new_view_x
+= (data
->click_x
- data
->view_rect
.MaxX
) / 4;
1897 if (data
->click_y
< data
->view_rect
.MinY
)
1899 new_view_y
-= (data
->view_rect
.MinY
- data
->click_y
) / 4;
1901 else if (data
->click_y
> data
->view_rect
.MaxY
)
1903 new_view_y
+= (data
->click_y
- data
->view_rect
.MaxY
) / 4;
1906 if (new_view_x
+ data
->view_width
> data
->width
)
1908 new_view_x
= data
->width
- data
->view_width
;
1910 if (new_view_x
< 0) new_view_x
= 0;
1912 if (new_view_y
+ data
->view_height
> data
->height
)
1914 new_view_y
= data
->height
- data
->view_height
;
1916 if (new_view_y
< 0) new_view_y
= 0;
1918 if ((new_view_x
!= data
->view_x
) || (new_view_y
!= data
->view_y
))
1920 data
->old_lasso_rect
= data
->lasso_rect
;
1922 data
->lasso_rect
.MaxX
+= new_view_x
- data
->view_x
;
1923 data
->lasso_rect
.MaxY
+= new_view_y
- data
->view_y
;
1925 RethinkLasso(obj
, data
);
1927 SetAttrs(obj
, MUIA_TextIconList_Left
, new_view_x
,
1928 MUIA_TextIconList_Top
, new_view_y
,
1935 DisableAutoScrollTimer(obj
, data
);
1941 /**************************************************************************
1943 **************************************************************************/
1944 static IPTR
TextIconList_HandleEvent(struct IClass
*cl
, Object
*obj
, struct MUIP_HandleEvent
*msg
)
1946 struct TextIconList_DATA
*data
= INST_DATA(cl
, obj
);
1951 LONG mx
= msg
->imsg
->MouseX
;
1952 LONG my
= msg
->imsg
->MouseY
;
1956 shift_qual
= (msg
->imsg
->Qualifier
& (IEQUALIFIER_LSHIFT
| IEQUALIFIER_RSHIFT
)) ? TRUE
: FALSE
;
1958 switch (msg
->imsg
->Class
)
1960 case IDCMP_MOUSEBUTTONS
:
1961 switch(msg
->imsg
->Code
)
1964 //kprintf("SELECTDOWN\n");
1965 if (data
->inputstate
== INPUTSTATE_NONE
)
1967 if ( ((line
= LineUnderMouse(data
, mx
, my
)) >= 0) &&
1968 ((col
= ColumnUnderMouse(data
, mx
, my
)) >= 0) )
1970 //kprintf("click on line %d col %d\n", line, col);
1972 if (data
->column_clickable
[col
])
1974 if (data
->active_entry
!= line
)
1976 struct TextIconEntry
*old
, *new;
1978 old
= GetEntryFromIndex(data
, data
->active_entry
);
1979 new = GetEntryFromIndex(data
, line
);
1981 data
->active_entry
= line
;
1982 if (old
&& old
->selected
&& !shift_qual
)
1984 Remove((struct Node
*)&old
->selection_node
);
1985 old
->selected
= FALSE
;
1988 data
->num_selected
--;
1991 if (!shift_qual
&& data
->num_selected
)
1993 struct TextIconEntry
*entry
;
1995 ForeachNode(&data
->entries_list
, entry
)
1997 if (entry
->selected
)
1999 Remove((struct Node
*)&entry
->selection_node
);
2000 entry
->selected
= FALSE
;
2001 entry
->dirty
= TRUE
;
2005 data
->num_selected
= 0;
2008 if (new && !new->selected
)
2010 AddTail((struct List
*)&data
->selection_list
, (struct Node
*)&new->selection_node
);
2011 new->selected
= TRUE
;
2014 data
->num_selected
++;
2017 data
->update
= UPDATE_DIRTY_ENTRIES
;
2018 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
2020 } /* if (data->active_entry != line) */
2022 } /* if (data->column_clickable[col]) */
2025 if (!shift_qual
&& data
->num_selected
)
2027 struct TextIconEntry
*entry
;
2029 ForeachNode(&data
->entries_list
, entry
)
2031 if (entry
->selected
)
2033 Remove((struct Node
*)&entry
->selection_node
);
2034 entry
->selected
= FALSE
;
2035 entry
->dirty
= TRUE
;
2039 data
->num_selected
= 0;
2040 data
->update
= UPDATE_DIRTY_ENTRIES
;
2041 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
2044 data
->lasso_rect
.MinX
= mx
- data
->view_rect
.MinX
+ data
->view_x
;
2045 data
->lasso_rect
.MinY
= my
- data
->view_rect
.MinY
+ data
->view_y
;
2046 data
->lasso_rect
.MaxX
= mx
- data
->view_rect
.MinX
+ data
->view_x
;
2047 data
->lasso_rect
.MaxY
= my
- data
->view_rect
.MinY
+ data
->view_y
;
2049 data
->inputstate
= INPUTSTATE_LASSO
;
2050 data
->lasso_active
= TRUE
;
2055 EnableMouseMoveEvents(obj
, data
);
2058 } /* if click on entry */
2059 else if ((col
= ColumnResizeHandleUnderMouse(data
, mx
, my
)) >= 0)
2061 data
->inputstate
= INPUTSTATE_COL_RESIZE
;
2062 data
->click_column
= col
;
2063 data
->click_x
= mx
- data
->column_width
[col
];
2065 EnableMouseMoveEvents(obj
, data
);
2067 } /* else if click on column header entry resize handle */
2068 else if ((col
= ColumnHeaderUnderMouse(data
, mx
, my
)) >= 0)
2070 data
->inputstate
= INPUTSTATE_COL_HEADER_CLICK
;
2071 data
->click_column
= col
;
2075 EnableMouseMoveEvents(obj
, data
);
2077 data
->update
= UPDATE_HEADER
;
2078 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
2081 } /* if (data->inputstate == INPUTSTATE_NONE) */
2085 if (data
->inputstate
== INPUTSTATE_COL_RESIZE
)
2087 DisableMouseMoveEvents(obj
, data
);
2089 data
->inputstate
= INPUTSTATE_NONE
;
2091 else if (data
->inputstate
== INPUTSTATE_COL_HEADER_CLICK
)
2093 DisableMouseMoveEvents(obj
, data
);
2095 data
->inputstate
= INPUTSTATE_NONE
;
2097 if (ColumnHeaderUnderMouse(data
, data
->click_x
, data
->click_y
) == data
->click_column
)
2100 if (data
->column_sortable
[data
->click_column
])
2102 if (data
->sort_column
== data
->click_column
)
2104 data
->sort_direction
= 1 - data
->sort_direction
;
2108 data
->sort_direction
= SORT_DIRECTION_UP
;
2109 data
->sort_column
= data
->click_column
;
2112 ReSortEntries(data
);
2114 data
->update
= UPDATE_ALL
;
2115 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
2120 data
->update
= UPDATE_HEADER
;
2121 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
2124 } /* mouse still over column header */
2126 } /* else if (data->inputstate == INPUTSTATE_COL_HEADER_CLICK) */
2127 else if (data
->inputstate
== INPUTSTATE_LASSO
)
2129 DisableMouseMoveEvents(obj
, data
);
2130 DisableAutoScrollTimer(obj
, data
);
2132 data
->inputstate
= INPUTSTATE_NONE
;
2133 data
->lasso_active
= FALSE
;
2135 data
->update
= UPDATE_ALL
;
2136 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
2141 if (data
->inputstate
== INPUTSTATE_NONE
)
2143 data
->inputstate
= INPUTSTATE_PAN
;
2145 data
->click_x
= mx
- data
->view_rect
.MinX
+ data
->view_x
;
2146 data
->click_y
= my
- data
->view_rect
.MinY
+ data
->view_y
;
2148 EnableMouseMoveEvents(obj
, data
);
2154 if (data
->inputstate
== INPUTSTATE_PAN
)
2156 DisableMouseMoveEvents(obj
, data
);
2158 data
->inputstate
= INPUTSTATE_NONE
;
2162 } /* switch(msg->imsg->Code) */
2165 case IDCMP_MOUSEMOVE
:
2166 if (data
->inputstate
== INPUTSTATE_PAN
)
2168 LONG new_view_x
, new_view_y
;
2170 new_view_x
= data
->click_x
- (mx
- data
->view_rect
.MinX
);
2171 new_view_y
= data
->click_y
- (my
- data
->view_rect
.MinY
);
2173 if (new_view_x
+ data
->view_width
> data
->width
)
2175 new_view_x
= data
->width
- data
->view_width
;
2177 if (new_view_x
< 0) new_view_x
= 0;
2179 if (new_view_y
+ data
->view_height
> data
->height
)
2181 new_view_y
= data
->height
- data
->view_height
;
2183 if (new_view_y
< 0) new_view_y
= 0;
2185 if ((new_view_x
!= data
->view_x
) || (new_view_y
!= data
->view_y
))
2187 SetAttrs(obj
, MUIA_TextIconList_Left
, new_view_x
,
2188 MUIA_TextIconList_Top
, new_view_y
,
2192 } /* if (data->inputstate == INPUTSTATE_PAN) */
2193 else if (data
->inputstate
== INPUTSTATE_COL_RESIZE
)
2195 LONG act_colwidth
= data
->column_width
[data
->click_column
];
2196 LONG new_colwidth
= mx
- data
->click_x
;
2198 if (new_colwidth
< MIN_COLUMN_WIDTH
) new_colwidth
= MIN_COLUMN_WIDTH
;
2200 if (new_colwidth
> act_colwidth
)
2202 data
->column_width
[data
->click_column
] = new_colwidth
;
2203 data
->width
+= new_colwidth
- act_colwidth
;
2204 data
->update
= UPDATE_ALL
;
2205 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
2207 set(obj
, MUIA_TextIconList_Width
, data
->width
);
2209 else if (new_colwidth
< act_colwidth
)
2211 BOOL scroll_left
= FALSE
;
2213 data
->column_width
[data
->click_column
] = new_colwidth
;
2214 data
->width
+= new_colwidth
- act_colwidth
;
2216 if (data
->view_x
+ data
->view_width
> data
->width
)
2218 LONG new_view_x
= data
->width
- data
->view_width
;
2220 if (new_view_x
< 0) new_view_x
= 0;
2221 if (new_view_x
!= data
->view_x
)
2224 data
->view_x
= new_view_x
;
2228 data
->update
= UPDATE_ALL
;
2229 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
2231 SetAttrs(obj
, scroll_left
? MUIA_TextIconList_Left
: TAG_IGNORE
, data
->view_x
,
2232 MUIA_TextIconList_Width
, data
->width
,
2235 } /* else if (new_colwidth < act_colwidth) */
2237 } /* else if (data->inputstate == INPUTSTATE_COL_RESIZE) */
2238 else if (data
->inputstate
== INPUTSTATE_COL_HEADER_CLICK
)
2240 BOOL old
= ColumnHeaderUnderMouse(data
, data
->click_x
, data
->click_y
);
2241 BOOL
new = ColumnHeaderUnderMouse(data
, mx
, my
);
2247 data
->update
= UPDATE_HEADER
;
2248 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
2251 else if (data
->inputstate
== INPUTSTATE_LASSO
)
2253 struct Rectangle old_lasso
, new_lasso
;
2254 struct Region
*region
;
2260 data
->old_lasso_rect
= data
->lasso_rect
;
2261 GetAbsoluteLassoRect(data
, &old_lasso
);
2262 data
->lasso_rect
.MaxX
= mx
- data
->view_rect
.MinX
+ data
->view_x
;
2263 data
->lasso_rect
.MaxY
= my
- data
->view_rect
.MinY
+ data
->view_y
;
2264 GetAbsoluteLassoRect(data
, &new_lasso
);
2266 region
= NewRectRegion(new_lasso
.MinX
, new_lasso
.MinY
, new_lasso
.MaxX
, new_lasso
.MaxY
);
2269 struct Rectangle render_range
;
2271 XorRectRegion(region
, &old_lasso
);
2272 OrRectOutlineRegion(region
, &old_lasso
);
2273 OrRectOutlineRegion(region
, &new_lasso
);
2275 render_range
= region
->bounds
;
2277 clip
= MUI_AddClipRegion(muiRenderInfo(obj
), region
);
2279 data
->update
= UPDATE_ALL
;
2280 data
->update_rect1
= &render_range
;
2281 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
2282 data
->update_rect1
= 0;
2284 MUI_RemoveClipRegion(muiRenderInfo(obj
), clip
);
2287 RethinkLasso(obj
, data
);
2289 if ((mx
>= data
->view_rect
.MinX
) &&
2290 (my
>= data
->view_rect
.MinY
) &&
2291 (mx
<= data
->view_rect
.MaxX
) &&
2292 (my
<= data
->view_rect
.MaxY
))
2294 DisableAutoScrollTimer(obj
, data
);
2298 EnableAutoScrollTimer(obj
, data
);
2305 } /* switch (msg->imsg->Class) */
2307 } /* if (msg->imsg) */
2313 /**************************************************************************
2314 MUIM_TextIconList_Clear
2315 **************************************************************************/
2316 static IPTR
TextIconList_Clear(struct IClass
*cl
, Object
*obj
, struct MUIP_TextIconList_Clear
*msg
)
2318 struct TextIconList_DATA
*data
= INST_DATA(cl
, obj
);
2319 struct TextIconEntry
*node
;
2322 while ((node
= (struct TextIconEntry
*)RemTail((struct List
*)&data
->entries_list
)))
2324 FreePooled(data
->pool
,node
,sizeof(*node
));
2326 NewList((struct List
*)&data
->selection_list
);
2328 data
->view_x
= data
->view_y
= data
->width
= data
->height
= 0;
2329 data
->num_entries
= 0;
2330 data
->active_entry
= -1;
2331 data
->num_selected
= 0;
2334 for(i
= 0; i
< NUM_COLUMNS
; i
++)
2336 data
->column_maxwidth
[i
] = 0;
2339 SetAttrs(obj
, MUIA_TextIconList_Left
, data
->view_x
,
2340 MUIA_TextIconList_Top
, data
->view_y
,
2341 MUIA_TextIconList_Width
, data
->width
,
2342 MUIA_TextIconList_Height
, data
->height
,
2345 data
->update
= UPDATE_ALL
;
2346 MUI_Redraw(obj
,MADF_DRAWUPDATE
);
2350 /**************************************************************************
2351 MUIM_TextIconList_Add.
2352 Returns 0 on failure otherwise 1
2353 **************************************************************************/
2354 static IPTR
TextIconList_Add(struct IClass
*cl
, Object
*obj
, struct MUIP_TextIconList_Add
*msg
)
2356 struct TextIconList_DATA
*data
= INST_DATA(cl
, obj
);
2357 struct TextIconEntry
*entry
;
2361 if (!(entry
= AllocPooled(data
->pool
,sizeof(struct TextIconEntry
))))
2366 memset(entry
, 0, sizeof(struct TextIconEntry
));
2368 entry
->fib
= *msg
->fib
;
2370 if (entry
->fib
.fib_DirEntryType
> 0)
2372 strcpy(GetTextIconEntryText(data
, entry
, INDEX_SIZE
), "Drawer");
2376 sprintf(GetTextIconEntryText(data
, entry
, INDEX_SIZE
), "%ld", (long)entry
->fib
.fib_Size
);
2379 dt
.dat_Stamp
= entry
->fib
.fib_Date
;
2380 dt
.dat_Format
= FORMAT_DOS
;
2382 dt
.dat_StrDay
= NULL
;
2383 dt
.dat_StrDate
= GetTextIconEntryText(data
, entry
, INDEX_DATE
);
2384 dt
.dat_StrTime
= GetTextIconEntryText(data
, entry
, INDEX_TIME
);;
2388 sp
= GetTextIconEntryText(data
, entry
, INDEX_PROTECTION
);
2389 *sp
++ = (entry
->fib
.fib_Protection
& FIBF_SCRIPT
) ? 's' : '-';
2390 *sp
++ = (entry
->fib
.fib_Protection
& FIBF_PURE
) ? 'p' : '-';
2391 *sp
++ = (entry
->fib
.fib_Protection
& FIBF_ARCHIVE
) ? 'a' : '-';
2392 *sp
++ = (entry
->fib
.fib_Protection
& FIBF_READ
) ? '-' : 'r';
2393 *sp
++ = (entry
->fib
.fib_Protection
& FIBF_WRITE
) ? '-' : 'w';
2394 *sp
++ = (entry
->fib
.fib_Protection
& FIBF_EXECUTE
) ? '-' : 'e';
2395 *sp
++ = (entry
->fib
.fib_Protection
& FIBF_DELETE
) ? '-' : 'd';
2398 data
->num_entries
++;
2400 SortInNode(data
, (struct List
*)&data
->entries_list
, (struct Node
*)entry
, (APTR
)CompareNodes
);
2404 CalcEntryDimension(data
, entry
);
2405 data
->height
+= data
->lineheight
;
2409 SetAttrs(obj
, MUIA_TextIconList_Width
, data
->width
,
2410 MUIA_TextIconList_Height
, data
->height
,
2417 BOOPSI_DISPATCHER(IPTR
,TextIconList_Dispatcher
, cl
, obj
, msg
)
2419 switch (msg
->MethodID
)
2422 case OM_NEW
: return TextIconList_New(cl
, obj
, (struct opSet
*)msg
);
2423 case OM_DISPOSE
: return TextIconList_Dispose(cl
,obj
, msg
);
2424 case OM_SET
: return TextIconList_Set(cl
,obj
,(struct opSet
*)msg
);
2425 case OM_GET
: return TextIconList_Get(cl
,obj
,(struct opGet
*)msg
);
2426 case MUIM_Setup
: return TextIconList_Setup(cl
,obj
,(struct MUIP_Setup
*)msg
);
2427 case MUIM_Show
: return TextIconList_Show(cl
,obj
,(struct MUIP_Show
*)msg
);
2428 case MUIM_Hide
: return TextIconList_Hide(cl
,obj
,(struct MUIP_Hide
*)msg
);
2429 case MUIM_Cleanup
: return TextIconList_Cleanup(cl
,obj
,(struct MUIP_Cleanup
*)msg
);
2430 case MUIM_AskMinMax
: return TextIconList_AskMinMax(cl
,obj
,(struct MUIP_AskMinMax
*)msg
);
2431 case MUIM_Draw
: return TextIconList_Draw(cl
,obj
,(struct MUIP_Draw
*)msg
);
2432 // case MUIM_Layout: return TextIconList_Layout(cl,obj,(struct MUIP_Layout *)msg);
2433 case MUIM_HandleEvent
: return TextIconList_HandleEvent(cl
,obj
,(struct MUIP_HandleEvent
*)msg
);
2434 // case MUIM_CreateDragImage: return TextIconList_CreateDragImage(cl,obj,(APTR)msg);
2435 // case MUIM_DeleteDragImage: return TextIconList_DeleteDragImage(cl,obj,(APTR)msg);
2436 // case MUIM_DragQuery: return TextIconList_DragQuery(cl,obj,(APTR)msg);
2437 // case MUIM_DragReport: return TextIconList_DragReport(cl,obj,(APTR)msg);
2438 // case MUIM_DragDrop: return TextIconList_DragDrop(cl,obj,(APTR)msg);
2440 // case MUIM_TextIconList_Update: return TextIconList_Update(cl,obj,(APTR)msg);
2441 case MUIM_TextIconList_Clear
: return TextIconList_Clear(cl
,obj
,(APTR
)msg
);
2442 case MUIM_TextIconList_Add
: return TextIconList_Add(cl
,obj
,(APTR
)msg
);
2443 // case MUIM_TextIconList_NextSelected: return TextIconList_NextSelected(cl,obj,(APTR)msg);
2444 // case MUIM_TextIconList_UnselectAll: return TextIconList_UnselectAll(cl,obj,(APTR)msg);
2446 case MUIM_TextIconList_AutoScroll
: return TextIconList_AutoScroll(cl
,obj
,(APTR
)msg
);
2449 return DoSuperMethodA(cl
, obj
, msg
);
2451 BOOPSI_DISPATCHER_END
2453 /*================ TextIconListview class ===================*/
2455 #define MUIB_TextIconListview (MUIB_AROS | 0x00000800)
2457 #define MUIA_TextIconListview_TextIconList (MUIB_TextIconListview | 0x00000000)
2458 #define MUIA_TextIconListview_UseWinBorder (MUIB_TextIconListview | 0x00000001)
2460 #define TextIconListviewObject BOOPSIOBJMACRO_START(CL_TextIconListview->mcc_Class)
2462 struct TextIconListview_DATA
2464 Object
*texticonlist
;
2465 Object
*vert
, *horiz
, *button
;
2467 struct Hook layout_hook
;
2471 IPTR
TextIconListview_Layout_Function(struct Hook
*hook
, Object
*obj
, struct MUI_LayoutMsg
*lm
)
2473 struct TextIconListview_DATA
*data
= (struct TextIconListview_DATA
*)hook
->h_Data
;
2475 switch (lm
->lm_Type
)
2479 /* Calulate the minmax dimension of the group,
2480 ** We only have a fixed number of children, so we need no NextObject()
2482 WORD maxxxxwidth
= 0;
2483 WORD maxxxxheight
= 0;
2485 maxxxxwidth
= _minwidth(data
->texticonlist
) + _minwidth(data
->vert
);
2486 if (_minwidth(data
->horiz
) > maxxxxwidth
) maxxxxwidth
= _minwidth(data
->horiz
);
2487 lm
->lm_MinMax
.MinWidth
= maxxxxwidth
;
2489 maxxxxheight
= _minheight(data
->texticonlist
) + _minheight(data
->horiz
);
2490 if (_minheight(data
->vert
) > maxxxxheight
) maxxxxheight
= _minheight(data
->vert
);
2491 lm
->lm_MinMax
.MinHeight
= maxxxxheight
;
2493 maxxxxwidth
= _defwidth(data
->texticonlist
) + _defwidth(data
->vert
);
2494 if (_defwidth(data
->horiz
) > maxxxxwidth
) maxxxxwidth
= _defwidth(data
->horiz
);
2495 lm
->lm_MinMax
.DefWidth
= maxxxxwidth
;
2497 maxxxxheight
= _defheight(data
->texticonlist
) + _defheight(data
->horiz
);
2498 if (_defheight(data
->vert
) > maxxxxheight
) maxxxxheight
= _defheight(data
->vert
);
2499 lm
->lm_MinMax
.DefHeight
= maxxxxheight
;
2501 lm
->lm_MinMax
.MaxWidth
= MUI_MAXMAX
;
2502 lm
->lm_MinMax
.MaxHeight
= MUI_MAXMAX
;
2509 /* Now place the objects between (0,0,lm->lm_Layout.Width-1,lm->lm_Layout.Height-1)
2512 LONG virt_width
= 0;
2513 LONG virt_height
= 0;
2514 LONG vert_width
= _minwidth(data
->vert
);
2515 LONG horiz_height
= _minheight(data
->horiz
);
2516 LONG lay_width
= lm
->lm_Layout
.Width
;
2517 LONG lay_height
= lm
->lm_Layout
.Height
;
2521 /* layout the virtual group a first time, to determine the virtual width/height */
2522 MUI_Layout(data
->texticonlist
,0,0,lay_width
,lay_height
,0);
2524 get(data
->texticonlist
, MUIA_TextIconList_Width
, &virt_width
);
2525 get(data
->texticonlist
, MUIA_TextIconList_Height
, &virt_height
);
2527 virt_width
+= _subwidth(data
->texticonlist
);
2528 virt_height
+= _subheight(data
->texticonlist
);
2530 if (virt_width
> lay_width
&& virt_height
> lay_height
)
2532 /* We need all scrollbars and the button */
2533 set(data
->vert
, MUIA_ShowMe
, TRUE
); /* We could also overload MUIM_Show... */
2534 set(data
->horiz
, MUIA_ShowMe
, TRUE
);
2535 set(data
->button
, MUIA_ShowMe
, TRUE
);
2536 cont_width
= lay_width
- vert_width
;
2537 cont_height
= lay_height
- horiz_height
;
2538 MUI_Layout(data
->vert
, cont_width
, 0, vert_width
, cont_height
,0);
2539 MUI_Layout(data
->horiz
, 0, cont_height
, cont_width
, horiz_height
, 0);
2540 MUI_Layout(data
->button
, cont_width
, cont_height
, vert_width
, horiz_height
, 0);
2543 if (virt_height
> lay_height
)
2545 set(data
->vert
, MUIA_ShowMe
, TRUE
);
2546 set(data
->horiz
, MUIA_ShowMe
, FALSE
);
2547 set(data
->button
, MUIA_ShowMe
, FALSE
);
2549 cont_width
= lay_width
- vert_width
;
2550 cont_height
= lay_height
;
2551 MUI_Layout(data
->vert
, cont_width
, 0, vert_width
, cont_height
,0);
2554 if (virt_width
> lay_width
)
2556 set(data
->vert
, MUIA_ShowMe
, FALSE
);
2557 set(data
->horiz
, MUIA_ShowMe
, TRUE
);
2558 set(data
->button
, MUIA_ShowMe
, FALSE
);
2560 cont_width
= lay_width
;
2561 cont_height
= lay_height
- horiz_height
;
2562 MUI_Layout(data
->horiz
, 0, cont_height
, cont_width
, horiz_height
, 0);
2565 set(data
->vert
, MUIA_ShowMe
, FALSE
);
2566 set(data
->horiz
, MUIA_ShowMe
, FALSE
);
2567 set(data
->button
, MUIA_ShowMe
, FALSE
);
2569 cont_width
= lay_width
;
2570 cont_height
= lay_height
;
2575 /* Layout the group a second time, note that setting _mwidth() and _mheight() should be enough, or we invent a new flag */
2576 MUI_Layout(data
->texticonlist
,0,0,cont_width
,cont_height
,0);
2584 IPTR
TextIconListview_Function(struct Hook
*hook
, APTR dummyobj
, void **msg
)
2586 struct TextIconListview_DATA
*data
= (struct TextIconListview_DATA
*)hook
->h_Data
;
2587 int type
= (int)(IPTR
)msg
[0];
2588 LONG val
= (LONG
)(IPTR
)msg
[1];
2594 get(data
->vert
,MUIA_Prop_First
,&val
);
2595 SetAttrs(data
->texticonlist
,MUIA_TextIconList_Top
, val
, MUIA_NoNotify
, TRUE
, TAG_DONE
);
2601 get(data
->horiz
,MUIA_Prop_First
,&val
);
2602 SetAttrs(data
->texticonlist
,MUIA_TextIconList_Left
, val
, MUIA_NoNotify
, TRUE
, TAG_DONE
);
2605 case 3: nnset(data
->horiz
, MUIA_Prop_First
, val
); break;
2606 case 4: nnset(data
->vert
, MUIA_Prop_First
, val
); break;
2612 IPTR
TextIconListview__OM_NEW(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
)
2614 struct TextIconListview_DATA
*data
;
2615 //struct TagItem *tags,*tag;
2616 Object
*texticonlist
= (Object
*)GetTagData(MUIA_TextIconListview_TextIconList
, 0, msg
->ops_AttrList
);
2617 Object
*vert
,*horiz
,*button
,*group
;
2621 usewinborder
= GetTagData(MUIA_TextIconListview_UseWinBorder
, FALSE
, msg
->ops_AttrList
);
2623 if (!usewinborder
) button
= ScrollbuttonObject
, End
;
2626 obj
= (Object
*)DoSuperNewTags(cl
, obj
, NULL
,
2627 MUIA_Group_Horiz
, FALSE
,
2628 Child
, (IPTR
) (group
= GroupObject
,
2629 Child
, (IPTR
) texticonlist
,
2630 Child
, (IPTR
) (vert
= ScrollbarObject
,
2631 usewinborder
? MUIA_Prop_UseWinBorder
: TAG_IGNORE
, MUIV_Prop_UseWinBorder_Right
,
2632 MUIA_Prop_DeltaFactor
, 20,
2633 MUIA_Group_Horiz
, FALSE
,
2635 Child
, (IPTR
) (horiz
= ScrollbarObject
,
2636 usewinborder
?MUIA_Prop_UseWinBorder
:TAG_IGNORE
, MUIV_Prop_UseWinBorder_Bottom
,
2637 MUIA_Prop_DeltaFactor
, 20,
2638 MUIA_Group_Horiz
, TRUE
,
2640 usewinborder
? TAG_IGNORE
: Child
, (IPTR
) button
,
2649 data
= INST_DATA(cl
, obj
);
2651 data
->horiz
= horiz
;
2652 data
->button
= button
;
2653 data
->texticonlist
= texticonlist
;
2657 data
->layout_hook
.h_Entry
= HookEntry
;
2658 data
->layout_hook
.h_SubEntry
= (HOOKFUNC
)TextIconListview_Layout_Function
;
2659 data
->layout_hook
.h_Data
= data
;
2661 SetAttrs(group
, MUIA_Group_Forward
, FALSE
,
2662 MUIA_Group_LayoutHook
, (IPTR
) &data
->layout_hook
,
2666 data
->hook
.h_Entry
= HookEntry
;
2667 data
->hook
.h_SubEntry
= (HOOKFUNC
)TextIconListview_Function
;
2668 data
->hook
.h_Data
= data
;
2670 DoMethod(vert
, MUIM_Notify
, MUIA_Prop_First
, MUIV_EveryTime
, (IPTR
)obj
, 4, MUIM_CallHook
, (IPTR
)&data
->hook
, 1, MUIV_TriggerValue
);
2671 DoMethod(horiz
, MUIM_Notify
, MUIA_Prop_First
, MUIV_EveryTime
, (IPTR
)obj
, 4, MUIM_CallHook
, (IPTR
)&data
->hook
, 2, MUIV_TriggerValue
);
2672 DoMethod(texticonlist
, MUIM_Notify
, MUIA_TextIconList_Left
, MUIV_EveryTime
, (IPTR
)obj
, 4, MUIM_CallHook
, (IPTR
)&data
->hook
, 3, MUIV_TriggerValue
);
2673 DoMethod(texticonlist
, MUIM_Notify
, MUIA_TextIconList_Top
, MUIV_EveryTime
, (IPTR
)obj
, 4, MUIM_CallHook
, (IPTR
)&data
->hook
, 4, MUIV_TriggerValue
);
2674 DoMethod(texticonlist
, MUIM_Notify
, MUIA_TextIconList_Width
, MUIV_EveryTime
, (IPTR
)horiz
, 3, MUIM_NoNotifySet
, MUIA_Prop_Entries
, MUIV_TriggerValue
);
2675 DoMethod(texticonlist
, MUIM_Notify
, MUIA_TextIconList_Height
, MUIV_EveryTime
, (IPTR
)vert
, 3, MUIM_NoNotifySet
, MUIA_Prop_Entries
, MUIV_TriggerValue
);
2676 DoMethod(texticonlist
, MUIM_Notify
, MUIA_TextIconList_VisWidth
, MUIV_EveryTime
, (IPTR
)horiz
, 3, MUIM_NoNotifySet
, MUIA_Prop_Visible
, MUIV_TriggerValue
);
2677 DoMethod(texticonlist
, MUIM_Notify
, MUIA_TextIconList_VisHeight
, MUIV_EveryTime
, (IPTR
)vert
, 3, MUIM_NoNotifySet
, MUIA_Prop_Visible
, MUIV_TriggerValue
);
2683 IPTR
TextIconListview__OM_DISPOSE(struct IClass
*cl
, Object
*obj
, Msg msg
)
2685 //struct TextIconListview_DATA *data = INST_DATA(cl, obj);
2687 return DoSuperMethodA(cl
,obj
,msg
);
2690 IPTR
TextIconListview__MUIM_Show(struct IClass
*cl
, Object
*obj
, struct MUIP_Show
*msg
)
2692 struct TextIconListview_DATA
*data
= INST_DATA(cl
, obj
);
2693 IPTR top
= 0,left
= 0,width
= 0,height
= 0,viswidth
= 0,visheight
= 0;
2695 get(data
->texticonlist
, MUIA_TextIconList_Left
, &left
);
2696 get(data
->texticonlist
, MUIA_TextIconList_Top
, &top
);
2697 get(data
->texticonlist
, MUIA_TextIconList_Width
, &width
);
2698 get(data
->texticonlist
, MUIA_TextIconList_Height
, &height
);
2699 get(data
->texticonlist
, MUIA_TextIconList_VisWidth
, &viswidth
);
2700 get(data
->texticonlist
, MUIA_TextIconList_VisHeight
, &visheight
);
2702 SetAttrs(data
->horiz
, MUIA_Prop_First
, left
,
2703 MUIA_Prop_Entries
, width
,
2704 MUIA_Prop_Visible
, viswidth
,
2708 SetAttrs(data
->vert
, MUIA_Prop_First
, top
,
2709 MUIA_Prop_Entries
, height
,
2710 MUIA_Prop_Visible
, visheight
,
2713 return DoSuperMethodA(cl
,obj
,(Msg
)msg
);
2716 BOOPSI_DISPATCHER(IPTR
,TextIconListview_Dispatcher
, cl
, obj
, msg
)
2718 switch (msg
->MethodID
)
2720 case OM_NEW
: return TextIconListview__OM_NEW(cl
, obj
, (struct opSet
*) msg
);
2721 case OM_DISPOSE
: return TextIconListview__OM_DISPOSE(cl
, obj
, msg
);
2722 case MUIM_Show
: return TextIconListview__MUIM_Show(cl
, obj
, (struct MUIP_Show
*)msg
);
2725 return DoSuperMethodA(cl
, obj
, msg
);
2728 BOOPSI_DISPATCHER_END
2733 Object
*wnd
, *texticonlist
;
2738 MUIMasterBase
= (struct Library
*)OpenLibrary("muimaster.library",0);
2740 CL_TextIconListview
= MUI_CreateCustomClass(NULL
,MUIC_Group
,NULL
,sizeof(struct TextIconListview_DATA
), TextIconListview_Dispatcher
);
2741 CL_TextIconList
= MUI_CreateCustomClass(NULL
,MUIC_Area
,NULL
,sizeof(struct TextIconList_DATA
), TextIconList_Dispatcher
);
2743 app
= ApplicationObject
,
2744 SubWindow
, (IPTR
) (wnd
= WindowObject
,
2745 MUIA_Window_Title
, (IPTR
) "texticonlist",
2746 MUIA_Window_Activate
, TRUE
,
2748 WindowContents
, (IPTR
) VGroup
,
2749 MUIA_Background
, MUII_GroupBack
,
2751 Child
, (IPTR
) IconListviewObject
,
2752 MUIA_IconListview_IconList
, (IPTR
) (iconlist
= IconDrawerListObject
,
2754 MUIA_IconDrawerList_Drawer
, (IPTR
) "C:",
2758 Child
, (IPTR
) TextIconListviewObject
,
2759 // MUIA_TextIconListview_UseWinBorder, TRUE,
2760 MUIA_TextIconListview_TextIconList
, (IPTR
) (texticonlist
= TextIconListObject
,
2767 Child, (IPTR) (texticonlist = TextIconListObject, InputListFrame, End),
2779 wnd
, MUIM_Notify
, MUIA_Window_CloseRequest
, TRUE
, (IPTR
) app
,
2780 2, MUIM_Application_ReturnID
, MUIV_Application_ReturnID_Quit
2784 BPTR lock
= Lock("C:", SHARED_LOCK
);
2788 struct FileInfoBlock
*fib
= AllocDosObject(DOS_FIB
, NULL
);
2791 if (Examine(lock
, fib
))
2793 while(ExNext(lock
, fib
))
2795 DoMethod(texticonlist
, MUIM_TextIconList_Add
, (IPTR
) fib
);
2799 FreeDosObject(DOS_FIB
, fib
);
2806 set(wnd
,MUIA_Window_Open
,TRUE
);
2808 set(iconlist
, MUIA_IconDrawerList_Drawer
, "C:");
2811 while (DoMethod(app
, MUIM_Application_NewInput
, (IPTR
) &sigs
) != MUIV_Application_ReturnID_Quit
)
2815 sigs
= Wait(sigs
| SIGBREAKF_CTRL_C
| SIGBREAKF_CTRL_D
);
2816 if (sigs
& SIGBREAKF_CTRL_C
) break;
2817 if (sigs
& SIGBREAKF_CTRL_D
) break;
2821 MUI_DisposeObject(app
);
2824 MUI_DeleteCustomClass(CL_TextIconList
);
2825 MUI_DeleteCustomClass(CL_TextIconListview
);
2827 CloseLibrary(MUIMasterBase
);