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 struct Library
*MUIMasterBase
;
37 struct MUI_CustomClass
*CL_TextIconList
, *CL_TextIconListview
;
39 /*================== TextIconList class =====================*/
43 #define MIN_COLUMN_WIDTH 10
45 #define COLUMN_ALIGN_LEFT 0
46 #define COLUMN_ALIGN_CENTER 1
47 #define COLUMN_ALIGN_RIGHT 2
49 #define LINE_SPACING_TOP 2
50 #define LINE_SPACING_BOTTOM 2
51 #define LINE_EXTRAHEIGHT (LINE_SPACING_TOP + LINE_SPACING_BOTTOM)
53 #define LINE_SPACING_LEFT 1
54 #define LINE_SPACING_RIGHT 1
55 #define LINE_EXTRAWIDTH (LINE_SPACING_LEFT + LINE_SPACING_RIGHT)
57 #define ENTRY_SPACING_LEFT 1
58 #define ENTRY_SPACING_RIGHT 1
59 #define ENTRY_EXTRAWIDTH (ENTRY_SPACING_LEFT + ENTRY_SPACING_RIGHT)
61 #define HEADERLINE_SPACING_TOP 3
62 #define HEADERLINE_SPACING_BOTTOM 3
63 #define HEADERLINE_EXTRAHEIGHT (HEADERLINE_SPACING_TOP + HEADERLINE_SPACING_BOTTOM)
65 #define HEADERLINE_SPACING_LEFT 1
66 #define HEADERLINE_SPACING_RIGHT 1
67 #define HEADERLINE_EXTRAWIDTH (HEADERLINE_SPACING_LEFT + HEADERLINE_SPACING_RIGHT)
69 #define HEADERENTRY_SPACING_LEFT 4
70 #define HEADERENTRY_SPACING_RIGHT 4
71 #define HEADERENTRY_EXTRAWIDTH (HEADERENTRY_SPACING_LEFT + HEADERENTRY_SPACING_RIGHT)
73 #define AUTOSCROLL_MILLIS 20
78 struct MinNode selection_node
;
79 struct FileInfoBlock fib
;
80 LONG field_width
[NUM_COLUMNS
];
81 UBYTE datebuf
[LEN_DATSTRING
];
82 UBYTE timebuf
[LEN_DATSTRING
];
96 #define COLOR_COLUMN_BACKGROUND 0
97 #define COLOR_COLUMN_BACKGROUND_SORTED 1
98 #define COLOR_COLUMN_BACKGROUND_LASSO 2
99 #define COLOR_COLUMN_BACKGROUND_LASSO_SORTED 3
101 #define COLOR_SELECTED_BACKGROUND 4
102 #define COLOR_SELECTED_BACKGROUND_SORTED 5
103 #define COLOR_SELECTED_BACKGROUND_LASSO 6
104 #define COLOR_SELECTED_BACKGROUND_LASSO_SORTED 7
108 static const ULONG rgb_colors
[NUM_COLORS
] =
120 static const ULONG pen_colors
[NUM_COLORS
] =
132 struct TextIconList_DATA
136 LONG view_width
, view_height
;
137 LONG width
, height
, lineheight
, headerheight
;
139 LONG update_scrolldx
;
140 LONG update_scrolldy
;
142 struct MinList entries_list
;
143 struct MinList selection_list
;
144 struct RastPort temprp
;
145 struct Rectangle view_rect
;
146 struct Rectangle header_rect
;
147 struct Rectangle lasso_rect
, old_lasso_rect
;
148 struct Rectangle
*update_rect1
, *update_rect2
;
149 struct MyColor colors
[NUM_COLORS
];
153 LONG click_x
, click_y
, click_column
;
154 LONG column_pos
[NUM_COLUMNS
];
155 LONG column_maxwidth
[NUM_COLUMNS
];
156 LONG column_width
[NUM_COLUMNS
];
157 BYTE column_visible
[NUM_COLUMNS
];
158 BYTE column_align
[NUM_COLUMNS
];
159 BYTE column_clickable
[NUM_COLUMNS
];
160 BYTE column_sortable
[NUM_COLUMNS
];
161 STRPTR column_title
[NUM_COLUMNS
];
173 struct MUI_EventHandlerNode ehn
;
174 struct MUI_InputHandlerNode thn
;
177 #define UPDATE_SCROLL 2
178 #define UPDATE_DIRTY_ENTRIES 3
180 #define UPDATE_HEADER 5
182 #define INPUTSTATE_NONE 0
183 #define INPUTSTATE_PAN 1
184 #define INPUTSTATE_COL_RESIZE 2
185 #define INPUTSTATE_COL_HEADER_CLICK 3
186 #define INPUTSTATE_LASSO 4
188 #define MUIB_TextIconList (MUIB_AROS | 0x00000700)
190 #define MUIA_TextIconList_Left (MUIB_TextIconList | 0x00000000)
191 #define MUIA_TextIconList_Top (MUIB_TextIconList | 0x00000001)
192 #define MUIA_TextIconList_Width (MUIB_TextIconList | 0x00000002)
193 #define MUIA_TextIconList_Height (MUIB_TextIconList | 0x00000003)
194 #define MUIA_TextIconList_VisWidth (MUIB_TextIconList | 0x00000004)
195 #define MUIA_TextIconList_VisHeight (MUIB_TextIconList | 0x00000005)
197 #define MUIM_TextIconList_Clear (MUIB_TextIconList | 0x00000000)
198 #define MUIM_TextIconList_Add (MUIB_TextIconList | 0x00000001)
199 #define MUIM_TextIconList_AutoScroll (MUIB_TextIconList | 0x00000002)
201 struct MUIP_TextIconList_Clear
{STACKULONG MethodID
;};
202 struct MUIP_TextIconList_Add
{STACKULONG MethodID
; struct FileInfoBlock
*fib
;};
204 #define TextIconListObject BOOPSIOBJMACRO_START(CL_TextIconList->mcc_Class)
209 #define INDEX_PROTECTION 2
212 #define INDEX_COMMENT 5
214 #define SORT_DRAWERS_FIRST 0
215 #define SORT_DRAWERS_MIXED 1
216 #define SORT_DRAWERS_LAST 2
218 #define SORT_DIRECTION_UP 0
219 #define SORT_DIRECTION_DOWN 1
221 #define SORT_BY_NAME 0
222 #define SORT_BY_DATE 1
223 #define SORT_BY_SIZE 2
225 static STRPTR
GetTextIconEntryText(struct TextIconList_DATA
*data
, struct TextIconEntry
*entry
,
233 ret
= entry
->fib
.fib_FileName
;
237 ret
= entry
->sizebuf
;
241 ret
= entry
->datebuf
;
245 ret
= entry
->timebuf
;
249 ret
= entry
->fib
.fib_Comment
;
252 case INDEX_PROTECTION
:
253 ret
= entry
->protbuf
;
260 static STRPTR
GetTextIconHeaderText(struct TextIconList_DATA
*data
, LONG index
)
264 ret
= data
->column_title
[index
];
289 case INDEX_PROTECTION
:
297 static void CalcWidth(struct TextIconList_DATA
*data
)
299 LONG i
, width
= LINE_EXTRAWIDTH
;
301 for(i
= 0; i
< NUM_COLUMNS
; i
++)
303 if (data
->column_visible
[i
])
305 width
+= data
->column_width
[i
];
312 static void CalcEntryDimension(struct TextIconList_DATA
*data
, struct TextIconEntry
*entry
)
318 for (i
= 0; i
< NUM_COLUMNS
; i
++)
320 text
= GetTextIconEntryText(data
, entry
, i
);
321 len
= TextLength(&data
->temprp
, text
, strlen(text
));
323 entry
->field_width
[i
] = len
+ ENTRY_EXTRAWIDTH
;
325 if (entry
->field_width
[i
] > data
->column_maxwidth
[i
])
327 data
->column_maxwidth
[i
] = entry
->field_width
[i
];
333 static void CalcAllEntryDimensions(struct TextIconList_DATA
*data
)
335 struct TextIconEntry
*entry
;
337 ForeachNode(&data
->entries_list
, entry
)
339 CalcEntryDimension(data
, entry
);
343 static void RecalcColumnMaxWidths(struct TextIconList_DATA
*data
)
345 struct TextIconEntry
*entry
;
348 for(i
= 0; i
< NUM_COLUMNS
; i
++)
350 data
->column_maxwidth
[i
] = 0;
353 ForeachNode(&data
->entries_list
, entry
)
355 for(i
= 0; i
< NUM_COLUMNS
; i
++)
357 if (entry
->field_width
[i
] > data
->column_maxwidth
[i
])
359 data
->column_maxwidth
[i
] = entry
->field_width
[i
];
365 static LONG
FirstVisibleColumnNumber(struct TextIconList_DATA
*data
)
370 for(i
= 0; i
< NUM_COLUMNS
; i
++)
372 LONG index
= data
->column_pos
[i
];
374 if (data
->column_visible
[index
])
384 static LONG
LastVisibleColumnNumber(struct TextIconList_DATA
*data
)
389 for(i
= 0; i
< NUM_COLUMNS
; i
++)
391 LONG index
= data
->column_pos
[i
];
393 if (data
->column_visible
[index
])
403 static struct TextIconEntry
*GetEntryFromIndex(struct TextIconList_DATA
*data
, LONG index
)
405 struct TextIconEntry
*node
;
406 struct TextIconEntry
*retval
= 0;
409 if (index
>= 0 && index
< data
->num_entries
)
411 ForeachNode(&data
->entries_list
, node
)
425 static LONG
LineUnderMouse(struct TextIconList_DATA
*data
, LONG mx
, LONG my
)
429 if ((mx
>= data
->view_rect
.MinX
) &&
430 (my
>= data
->view_rect
.MinY
) &&
431 (mx
<= data
->view_rect
.MaxX
) &&
432 (my
<= data
->view_rect
.MaxY
))
434 index
= (my
- data
->view_rect
.MinY
+ data
->view_y
) / data
->lineheight
;
436 if ((index
< 0) || (index
>= data
->num_entries
)) index
= -1;
442 static LONG
ColumnUnderMouse(struct TextIconList_DATA
*data
, LONG mx
, LONG my
)
446 if ((mx
>= data
->view_rect
.MinX
) &&
447 (my
>= data
->view_rect
.MinY
- data
->headerheight
) &&
448 (mx
<= data
->view_rect
.MaxX
) &&
449 (my
<= data
->view_rect
.MaxY
))
451 LONG x
= data
->view_rect
.MinX
- data
->view_x
+ LINE_SPACING_LEFT
;
454 for(i
= 0; i
< NUM_COLUMNS
; i
++)
456 LONG index
= data
->column_pos
[i
];
458 if (!data
->column_visible
[index
]) continue;
460 w
= data
->column_width
[index
];
462 if ((mx
>= x
) && (mx
< x
+ w
))
475 static LONG
ColumnHeaderUnderMouse(struct TextIconList_DATA
*data
, LONG mx
, LONG my
)
479 if (data
->show_header
&&
480 (my
>= data
->header_rect
.MinY
) &&
481 (my
<= data
->header_rect
.MaxY
))
483 col
= ColumnUnderMouse(data
, mx
, my
);
489 static LONG
ColumnResizeHandleUnderMouse(struct TextIconList_DATA
*data
, LONG mx
, LONG my
)
493 if ((mx
>= data
->view_rect
.MinX
) &&
494 (my
>= data
->view_rect
.MinY
- data
->headerheight
) &&
495 (mx
<= data
->view_rect
.MaxX
) &&
496 (my
<= data
->view_rect
.MaxY
))
498 LONG x
= data
->view_rect
.MinX
- data
->view_x
+ LINE_SPACING_LEFT
;
501 for(i
= 0; i
< NUM_COLUMNS
; i
++)
503 LONG index
= data
->column_pos
[i
];
505 if (!data
->column_visible
[index
]) continue;
507 w
= data
->column_width
[index
];
509 if (abs(mx
- (x
+ w
- 1)) <= 4)
522 static BOOL
GetColumnCoords(struct TextIconList_DATA
*data
, LONG index
, LONG
*x1
, LONG
*x2
)
526 LONG x
= data
->view_rect
.MinX
- data
->view_x
+ LINE_SPACING_LEFT
;
527 LONG firstvis
, lastvis
;
529 firstvis
= FirstVisibleColumnNumber(data
);
530 lastvis
= LastVisibleColumnNumber(data
);
532 for(i
= 0; i
< NUM_COLUMNS
; i
++)
534 LONG idx
= data
->column_pos
[i
];
537 if (!data
->column_visible
[idx
]) continue;
539 w
= data
->column_width
[idx
];
544 *x1
= x
- ((i
== firstvis
) ? LINE_SPACING_LEFT
: 0);
545 *x2
= x
+ w
- 1 + ((i
== lastvis
) ? LINE_SPACING_RIGHT
: 0);
555 static LONG
CompareNodes(struct TextIconList_DATA
*data
, struct TextIconEntry
*node1
, struct TextIconEntry
*node2
)
557 LONG pri1
= (node1
->fib
.fib_DirEntryType
> 0) ? 1 : 0;
558 LONG pri2
= (node2
->fib
.fib_DirEntryType
> 0) ? 1 : 0;
559 LONG diff
= (pri2
- pri1
) * -(data
->sort_dirs
- 1);
563 switch(data
->sort_column
)
567 diff
= CompareDates((const struct DateStamp
*)&node2
->fib
.fib_Date
,
568 (const struct DateStamp
*)&node1
->fib
.fib_Date
);
573 if (node1
->fib
.fib_Size
< node2
->fib
.fib_Size
)
577 else if (node1
->fib
.fib_Size
> node2
->fib
.fib_Size
)
585 diff
= Stricmp(node1
->fib
.fib_FileName
, node2
->fib
.fib_FileName
);
590 if (data
->sort_direction
== SORT_DIRECTION_DOWN
) diff
= -diff
;
596 static void SortInNode(struct TextIconList_DATA
*data
, struct List
*list
, struct Node
*node
,
597 LONG (*compare
)(APTR data
, APTR node1
, APTR node2
))
599 struct Node
*prevnode
= NULL
;
600 struct Node
*checknode
;
602 ForeachNode(list
, checknode
)
604 if (compare(data
, node
, checknode
) < 0) break;
606 prevnode
= checknode
;
609 Insert(list
, node
, prevnode
);
612 static void ReSortEntries(struct TextIconList_DATA
*data
)
614 struct List templist
;
615 struct Node
*node
, *succ
;
619 ForeachNodeSafe(&data
->entries_list
, node
, succ
)
622 AddTail(&templist
, node
);
625 ForeachNodeSafe(&templist
, node
, succ
)
627 SortInNode(data
, (struct List
*)&data
->entries_list
, node
, (APTR
)CompareNodes
);
631 static BOOL
MustRenderRect(struct TextIconList_DATA
*data
, struct Rectangle
*rect
)
633 if (data
->update_rect1
&& data
->update_rect2
)
635 if (!AndRectRect(rect
, data
->update_rect1
, NULL
) &&
636 !AndRectRect(rect
, data
->update_rect2
, NULL
)) return FALSE
;
638 else if (data
->update_rect1
)
640 if (!AndRectRect(rect
, data
->update_rect1
, NULL
)) return FALSE
;
642 else if (data
->update_rect2
)
644 if (!AndRectRect(rect
, data
->update_rect2
, NULL
)) return FALSE
;
650 static void GetAbsoluteLassoRect(struct TextIconList_DATA
*data
, struct Rectangle
*lasso_rect
)
652 WORD minx
= data
->lasso_rect
.MinX
;
653 WORD miny
= data
->lasso_rect
.MinY
;
654 WORD maxx
= data
->lasso_rect
.MaxX
;
655 WORD maxy
= data
->lasso_rect
.MaxY
;
659 /* Swap minx, maxx */
667 /* Swap miny, maxy */
673 lasso_rect
->MinX
= data
->view_rect
.MinX
- data
->view_x
+ minx
;
674 lasso_rect
->MinY
= data
->view_rect
.MinY
- data
->view_y
+ miny
;
675 lasso_rect
->MaxX
= data
->view_rect
.MinX
- data
->view_x
+ maxx
;
676 lasso_rect
->MaxY
= data
->view_rect
.MinY
- data
->view_y
+ maxy
;
679 static void EnableMouseMoveEvents(Object
*obj
, struct TextIconList_DATA
*data
)
681 if (!(data
->ehn
.ehn_Events
& IDCMP_MOUSEMOVE
))
683 DoMethod(_win(obj
),MUIM_Window_RemEventHandler
, (IPTR
)&data
->ehn
);
684 data
->ehn
.ehn_Events
|= IDCMP_MOUSEMOVE
;
685 DoMethod(_win(obj
),MUIM_Window_AddEventHandler
, (IPTR
)&data
->ehn
);
689 static void DisableMouseMoveEvents(Object
*obj
, struct TextIconList_DATA
*data
)
691 if (data
->ehn
.ehn_Events
& IDCMP_MOUSEMOVE
)
693 DoMethod(_win(obj
),MUIM_Window_RemEventHandler
, (IPTR
)&data
->ehn
);
694 data
->ehn
.ehn_Events
&= ~IDCMP_MOUSEMOVE
;
695 DoMethod(_win(obj
),MUIM_Window_AddEventHandler
, (IPTR
)&data
->ehn
);
699 static void EnableAutoScrollTimer(Object
*obj
, struct TextIconList_DATA
*data
)
701 if (!data
->thn
.ihn_Millis
)
703 data
->thn
.ihn_Millis
= AUTOSCROLL_MILLIS
;
704 DoMethod(_app(obj
), MUIM_Application_AddInputHandler
, (IPTR
)&data
->thn
);
708 static void DisableAutoScrollTimer(Object
*obj
, struct TextIconList_DATA
*data
)
710 if (data
->thn
.ihn_Millis
)
712 data
->thn
.ihn_Millis
= 0;
713 DoMethod(_app(obj
), MUIM_Application_RemInputHandler
, (IPTR
)&data
->thn
);
717 static BOOL
OrRectOutlineRegion(struct Region
*reg
, struct Rectangle
*rect
)
726 result
= OrRectRegion(reg
, &r
);
732 result
= result
&& OrRectRegion(reg
, &r
);
738 result
= result
&& OrRectRegion(reg
, &r
);
744 result
= result
&& OrRectRegion(reg
, &r
);
749 static void MyRectFill(struct TextIconList_DATA
*data
, struct RastPort
*rp
,
750 LONG x1
, LONG y1
, LONG x2
, LONG y2
, LONG mycol
)
768 if (data
->truecolor
&& CyberGfxBase
)
770 FillPixelArray(rp
, x1
, y1
, x2
- x1
+ 1, y2
- y1
+ 1, data
->colors
[mycol
].rgbpixel
);
774 SetAPen(rp
, data
->colors
[mycol
].pixel
);
775 RectFill(rp
, x1
, y1
, x2
, y2
);
779 static void RenderHeaderField(Object
*obj
, struct TextIconList_DATA
*data
,
780 struct Rectangle
*rect
, LONG index
)
783 struct TextExtent te
;
787 if ((data
->inputstate
== INPUTSTATE_COL_HEADER_CLICK
) &&
788 (data
->click_column
== index
))
791 if (ColumnHeaderUnderMouse(data
, data
->click_x
, data
->click_y
) == index
)
797 text
= GetTextIconHeaderText(data
, index
);
799 SetAPen(_rp(obj
), _pens(obj
)[sel
? MPEN_HALFSHADOW
: MPEN_HALFSHINE
]);
800 RectFill(_rp(obj
), rect
->MinX
+ 1, rect
->MinY
+ 1,
801 rect
->MaxX
- 1, rect
->MaxY
- 1);
802 SetAPen(_rp(obj
), _pens(obj
)[sel
? MPEN_SHADOW
: MPEN_SHINE
]);
803 RectFill(_rp(obj
), rect
->MinX
, rect
->MinY
, rect
->MinX
, rect
->MaxY
);
804 RectFill(_rp(obj
), rect
->MinX
+ 1, rect
->MinY
, rect
->MaxX
- 1, rect
->MinY
);
805 SetAPen(_rp(obj
), _pens(obj
)[sel
? MPEN_HALFSHINE
: MPEN_HALFSHADOW
]);
806 RectFill(_rp(obj
), rect
->MaxX
, rect
->MinY
, rect
->MaxX
, rect
->MaxY
);
807 RectFill(_rp(obj
), rect
->MinX
+ 1, rect
->MaxY
, rect
->MaxX
- 1, rect
->MaxY
);
809 if (index
== data
->sort_column
)
811 LONG x
= rect
->MaxX
- 4 - 6;
812 LONG y
= (rect
->MinY
+ rect
->MaxY
+ 1) / 2 - 3;
816 SetAPen(_rp(obj
), _pens(obj
)[sel
? MPEN_SHADOW
: MPEN_HALFSHADOW
]);
817 if (data
->sort_direction
== SORT_DIRECTION_UP
)
819 RectFill(_rp(obj
), x
, y
, x
+ 5, y
+ 1);
820 RectFill(_rp(obj
), x
+ 1, y
+ 2, x
+ 4, y
+ 3);
821 RectFill(_rp(obj
), x
+ 2, y
+ 4, x
+ 3, y
+ 5);
825 RectFill(_rp(obj
), x
, y
+ 4, x
+ 5, y
+ 5);
826 RectFill(_rp(obj
), x
+ 1, y
+ 2, x
+ 4, y
+ 3);
827 RectFill(_rp(obj
), x
+ 2, y
, x
+ 3, y
+ 1);
832 rect
->MinX
+= HEADERENTRY_SPACING_LEFT
;
833 rect
->MinY
+= HEADERLINE_SPACING_TOP
;
834 rect
->MaxX
-= HEADERENTRY_SPACING_RIGHT
;
835 rect
->MaxY
-= HEADERLINE_SPACING_BOTTOM
;
839 fit
= TextFit(_rp(obj
), text
, strlen(text
), &te
, NULL
, 1,
840 rect
->MaxX
- rect
->MinX
+ 1,
841 rect
->MaxY
- rect
->MinY
+ 1);
845 SetABPenDrMd(_rp(obj
), _pens(obj
)[MPEN_TEXT
], 0, JAM1
);
846 Move(_rp(obj
), rect
->MinX
, rect
->MinY
+ _rp(obj
)->TxBaseline
);
847 Text(_rp(obj
), text
, fit
);
852 static void RenderHeaderline(Object
*obj
, struct TextIconList_DATA
*data
)
854 struct Rectangle linerect
;
856 LONG firstvis
, lastvis
;
857 linerect
= data
->header_rect
;
858 linerect
.MinX
-= data
->view_x
;
859 linerect
.MaxX
-= data
->view_x
;
861 linerect
.MinX
= data
->header_rect
.MinX
- data
->view_x
;
862 linerect
.MaxX
= data
->header_rect
.MaxX
; //linerect.MinX + data->width - 1;
863 linerect
.MinY
= data
->header_rect
.MinY
;
864 linerect
.MaxY
= data
->header_rect
.MaxY
;
866 if (!MustRenderRect(data
, &linerect
)) return;
868 SetFont(_rp(obj
), _font(obj
));
870 x
= linerect
.MinX
+ HEADERLINE_SPACING_LEFT
;
872 firstvis
= FirstVisibleColumnNumber(data
);
873 lastvis
= LastVisibleColumnNumber(data
);
875 for(i
= 0; i
< NUM_COLUMNS
; i
++)
877 struct Rectangle field_rect
;
878 LONG index
= data
->column_pos
[i
];
880 if (!data
->column_visible
[index
]) continue;
882 field_rect
.MinX
= (i
== firstvis
) ? linerect
.MinX
: x
;
883 field_rect
.MinY
= linerect
.MinY
;
884 field_rect
.MaxX
= x
+ data
->column_width
[index
] - 1 + ((i
== lastvis
) ? HEADERLINE_SPACING_RIGHT
: 0);
885 field_rect
.MaxY
= linerect
.MaxY
;
887 if (MustRenderRect(data
, &field_rect
))
889 RenderHeaderField(obj
, data
, &field_rect
, index
);
891 x
+= data
->column_width
[index
];
894 x
+= HEADERLINE_SPACING_RIGHT
;
896 if (x
< linerect
.MaxX
)
900 if (MustRenderRect(data
, &linerect
))
902 SetABPenDrMd(_rp(obj
), _pens(obj
)[MPEN_HALFSHINE
], 0, JAM1
);
903 RectFill(_rp(obj
), linerect
.MinX
, linerect
.MinY
, linerect
.MaxX
, linerect
.MaxY
);
909 #define ENTRYPOS_FIRST -1
910 #define ENTRYPOS_MIDDLE 0
911 #define ENTRYPOS_LAST 1
913 static void RenderEntryField(Object
*obj
, struct TextIconList_DATA
*data
,
914 struct TextIconEntry
*entry
, struct Rectangle
*rect
,
915 LONG index
, BOOL firstvis
, BOOL lastvis
)
918 struct TextExtent te
;
922 selected
= (entry
&& data
->column_clickable
[index
]) ? entry
->selected
: FALSE
;
924 fit
= selected
? COLOR_SELECTED_BACKGROUND
: COLOR_COLUMN_BACKGROUND
;
925 if (index
== data
->sort_column
) fit
++;
926 if (data
->lasso_paint
) fit
+= 2;
928 MyRectFill(data
, _rp(obj
), rect
->MinX
, rect
->MinY
, rect
->MaxX
, rect
->MaxY
, fit
);
930 rect
->MinX
+= ENTRY_SPACING_LEFT
;
931 rect
->MaxX
-= ENTRY_SPACING_RIGHT
;
932 rect
->MinY
+= LINE_SPACING_TOP
;
933 rect
->MaxY
-= LINE_SPACING_BOTTOM
;
935 if (firstvis
) rect
->MinX
+= LINE_SPACING_LEFT
;
936 if (lastvis
) rect
->MaxX
-= LINE_SPACING_RIGHT
;
940 text
= GetTextIconEntryText(data
, entry
, index
);
942 if (!text
[0]) return;
944 fit
= TextFit(_rp(obj
), text
, strlen(text
), &te
, NULL
, 1,
945 rect
->MaxX
- rect
->MinX
+ 1,
946 rect
->MaxY
- rect
->MinY
+ 1);
950 SetABPenDrMd(_rp(obj
), _pens(obj
)[selected
? MPEN_SHINE
: MPEN_TEXT
], 0, JAM1
);
952 switch(data
->column_align
[index
])
954 case COLUMN_ALIGN_LEFT
:
955 Move(_rp(obj
), rect
->MinX
, rect
->MinY
+ _rp(obj
)->TxBaseline
);
958 case COLUMN_ALIGN_RIGHT
:
959 Move(_rp(obj
), rect
->MaxX
- te
.te_Width
, rect
->MinY
+ _rp(obj
)->TxBaseline
);
962 case COLUMN_ALIGN_CENTER
:
963 Move(_rp(obj
), rect
->MinX
+ (rect
->MaxX
- rect
->MinX
+ 1 + 1 - te
.te_Width
) / 2,
964 rect
->MinY
+ _rp(obj
)->TxBaseline
);
968 Text(_rp(obj
), text
, fit
);
971 static void RenderEntry(Object
*obj
, struct TextIconList_DATA
*data
, LONG index
)
973 struct TextIconEntry
*entry
= GetEntryFromIndex(data
, index
);
974 struct Rectangle linerect
;
976 LONG firstvis
, lastvis
;
978 linerect
.MinX
= data
->view_rect
.MinX
- data
->view_x
;
979 linerect
.MaxX
= data
->view_rect
.MaxX
; //linerect.MinX + data->width - 1;
980 linerect
.MinY
= data
->view_rect
.MinY
+ index
* data
->lineheight
- data
->view_y
;
981 linerect
.MaxY
= linerect
.MinY
+ data
->lineheight
- 1;
983 if (!AndRectRect(&linerect
, &data
->view_rect
, NULL
)) return;
984 if (!MustRenderRect(data
, &linerect
)) return;
986 SetFont(_rp(obj
), _font(obj
));
988 x
= linerect
.MinX
+ LINE_SPACING_LEFT
;
990 firstvis
= FirstVisibleColumnNumber(data
);
991 lastvis
= LastVisibleColumnNumber(data
);
993 for(i
= 0; i
< NUM_COLUMNS
; i
++)
995 struct Rectangle field_rect
;
996 LONG index
= data
->column_pos
[i
];
998 if (!data
->column_visible
[i
]) continue;
1000 field_rect
.MinX
= (i
== firstvis
) ? linerect
.MinX
: x
;
1001 field_rect
.MinY
= linerect
.MinY
;
1002 field_rect
.MaxX
= x
+ data
->column_width
[index
] - 1 + ((i
== lastvis
) ? LINE_SPACING_RIGHT
: 0);
1003 field_rect
.MaxY
= linerect
.MaxY
;
1005 if (MustRenderRect(data
, &field_rect
))
1007 if (AndRectRect(&field_rect
, &data
->view_rect
, NULL
))
1009 RenderEntryField(obj
, data
, entry
, &field_rect
, index
,
1010 (i
== firstvis
), (i
== lastvis
));
1013 x
+= data
->column_width
[index
];
1016 x
+= LINE_SPACING_RIGHT
;
1018 if (x
< linerect
.MaxX
)
1022 if (MustRenderRect(data
, &linerect
))
1024 SetABPenDrMd(_rp(obj
), _pens(obj
)[data
->lasso_paint
? MPEN_BACKGROUND
: MPEN_SHINE
], 0, JAM1
);
1025 RectFill(_rp(obj
), linerect
.MinX
, linerect
.MinY
, linerect
.MaxX
, linerect
.MaxY
);
1031 static LONG
FirstVisibleLine(struct TextIconList_DATA
*data
)
1033 return data
->view_y
/ data
->lineheight
;
1036 static LONG
NumVisibleLines(struct TextIconList_DATA
*data
)
1038 LONG visible
= data
->view_height
+ data
->lineheight
- 1 +
1039 (data
->view_y
% data
->lineheight
);
1041 visible
/= data
->lineheight
;
1046 static void RenderAllEntries(Object
*obj
, struct TextIconList_DATA
*data
)
1048 LONG first
= FirstVisibleLine(data
);
1049 LONG visible
= NumVisibleLines(data
);
1052 for(i
= 0; i
< visible
; i
++)
1054 RenderEntry(obj
, data
, first
+ i
);
1060 static void RethinkLasso(Object
*obj
, struct TextIconList_DATA
*data
)
1062 struct TextIconEntry
*entry
;
1064 LONG ny1
= data
->lasso_rect
.MinY
;
1065 LONG ny2
= data
->lasso_rect
.MaxY
;
1066 LONG oy1
= data
->old_lasso_rect
.MinY
;
1067 LONG oy2
= data
->old_lasso_rect
.MaxY
;
1073 if (!data
->num_entries
) return;
1089 ny1
/= data
->lineheight
;
1090 ny2
/= data
->lineheight
;
1091 oy1
/= data
->lineheight
;
1092 oy2
/= data
->lineheight
;
1094 y1
= (ny1
< oy1
) ? ny1
: oy1
;
1095 y2
= (ny2
> oy2
) ? ny2
: oy2
;
1101 else if (y1
>= data
->num_entries
)
1103 y1
= data
->num_entries
- 1;
1110 else if (y2
>= data
->num_entries
)
1112 y2
= data
->num_entries
- 1;
1115 GetColumnCoords(data
, INDEX_NAME
, &x1
, &x2
);
1116 x1
+= data
->view_x
- data
->view_rect
.MinX
;
1117 x2
+= data
->view_x
- data
->view_rect
.MinX
;
1119 lasso_hot
= ((data
->lasso_rect
.MinX
>= x1
) && (data
->lasso_rect
.MinX
<= x2
)) ||
1120 ((data
->lasso_rect
.MaxX
>= x1
) && (data
->lasso_rect
.MaxX
<= x2
)) ||
1121 ((data
->lasso_rect
.MinX
< x1
) && (data
->lasso_rect
.MaxX
> x2
)) ||
1122 ((data
->lasso_rect
.MaxX
< x1
) && (data
->lasso_rect
.MinX
> x2
));
1124 entry
= GetEntryFromIndex(data
, y1
);
1125 while(entry
&& entry
->node
.mln_Succ
&& (y1
<= y2
))
1129 select
= (y1
>= ny1
) && (y1
<= ny2
) && lasso_hot
;
1130 if (select
!= entry
->selected
)
1134 AddTail((struct List
*)&data
->selection_list
, (struct Node
*)&entry
->selection_node
);
1135 data
->num_selected
++;
1139 Remove((struct Node
*)&entry
->selection_node
);
1140 data
->num_selected
--;
1142 entry
->selected
= select
;
1143 entry
->dirty
= TRUE
;
1147 entry
= (struct TextIconEntry
*)entry
->node
.mln_Succ
;
1153 data
->update
= UPDATE_DIRTY_ENTRIES
;
1154 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
1159 /**************************************************************************
1161 **************************************************************************/
1162 static IPTR
TextIconList_New(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
)
1164 struct TextIconList_DATA
*data
;
1165 struct TagItem
*tag
, *tags
;
1168 obj
= (Object
*)DoSuperNewTags(cl
, obj
, NULL
,
1169 MUIA_FillArea
, FALSE
,
1170 TAG_MORE
, (IPTR
) msg
->ops_AttrList
);
1171 if (!obj
) return FALSE
;
1173 data
= INST_DATA(cl
, obj
);
1174 NewList((struct List
*)&data
->entries_list
);
1175 NewList((struct List
*)&data
->selection_list
);
1176 data
->show_header
= TRUE
;
1177 data
->active_entry
= -1;
1179 for(i
= 0; i
< NUM_COLUMNS
; i
++)
1181 data
->column_pos
[i
] = i
;
1182 data
->column_visible
[i
] = TRUE
;
1183 data
->column_width
[i
] = 100;
1185 data
->column_align
[INDEX_SIZE
] = COLUMN_ALIGN_RIGHT
;
1186 data
->column_clickable
[INDEX_NAME
] = TRUE
;
1188 data
->column_sortable
[INDEX_NAME
] = TRUE
;
1189 data
->column_sortable
[INDEX_SIZE
] = TRUE
;
1190 data
->column_sortable
[INDEX_DATE
] = TRUE
;
1191 data
->column_sortable
[INDEX_TIME
] = TRUE
;
1193 data
->sort_column
= INDEX_NAME
;
1194 data
->sort_direction
= SORT_DIRECTION_UP
;
1195 data
->sort_dirs
= SORT_DRAWERS_FIRST
;
1197 /* parse initial taglist */
1198 for (tags
= msg
->ops_AttrList
; (tag
= NextTagItem(&tags
)); )
1200 switch (tag
->ti_Tag
)
1205 data
->pool
= CreatePool(0,4096,4096);
1208 CoerceMethod(cl
,obj
,OM_DISPOSE
);
1212 data
->ehn
.ehn_Events
= IDCMP_MOUSEBUTTONS
;
1213 data
->ehn
.ehn_Priority
= 0;
1214 data
->ehn
.ehn_Flags
= 0;
1215 data
->ehn
.ehn_Object
= obj
;
1216 data
->ehn
.ehn_Class
= cl
;
1218 data
->thn
.ihn_Flags
= MUIIHNF_TIMER
;
1219 data
->thn
.ihn_Method
= MUIM_TextIconList_AutoScroll
;
1220 data
->thn
.ihn_Object
= obj
;
1225 /**************************************************************************
1227 **************************************************************************/
1228 static IPTR
TextIconList_Dispose(struct IClass
*cl
, Object
*obj
, Msg msg
)
1230 struct TextIconList_DATA
*data
= INST_DATA(cl
, obj
);
1231 struct TextIconEntry
*node
;
1233 ForeachNode(&data
->entries_list
, node
)
1237 if (data
->pool
) DeletePool(data
->pool
);
1239 DoSuperMethodA(cl
,obj
,msg
);
1243 /**************************************************************************
1245 **************************************************************************/
1246 static IPTR
TextIconList_Set(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
)
1248 struct TextIconList_DATA
*data
= INST_DATA(cl
, obj
);
1249 struct TagItem
*tag
, *tags
;
1250 LONG oldleft
= data
->view_x
, oldtop
= data
->view_y
;
1252 /* parse initial taglist */
1253 for (tags
= msg
->ops_AttrList
; (tag
= NextTagItem(&tags
)); )
1255 switch (tag
->ti_Tag
)
1257 case MUIA_TextIconList_Left
:
1258 if (data
->view_x
!= (LONG
)tag
->ti_Data
)
1260 LONG new_view_x
= (LONG
)tag
->ti_Data
;
1262 if (new_view_x
+ data
->view_width
> data
->width
)
1264 new_view_x
= data
->width
- data
->view_width
;
1266 if (new_view_x
< 0) new_view_x
= 0;
1268 data
->view_x
= new_view_x
;
1269 tag
->ti_Data
= new_view_x
;
1273 case MUIA_TextIconList_Top
:
1274 if (data
->view_y
!= (LONG
)tag
->ti_Data
)
1276 LONG new_view_y
= (LONG
)tag
->ti_Data
;
1278 if (new_view_y
+ data
->view_height
> data
->height
)
1280 new_view_y
= data
->height
- data
->view_height
;
1282 if (new_view_y
< 0) new_view_y
= 0;
1284 data
->view_y
= new_view_y
;
1285 tag
->ti_Data
= new_view_y
;
1291 if ((oldleft
!= data
->view_x
) || (oldtop
!= data
->view_y
))
1293 data
->update
= UPDATE_SCROLL
;
1294 data
->update_scrolldx
= data
->view_x
- oldleft
;
1295 data
->update_scrolldy
= data
->view_y
- oldtop
;
1297 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
1300 return DoSuperMethodA(cl
, obj
, (Msg
)msg
);
1303 /**************************************************************************
1305 **************************************************************************/
1306 static IPTR
TextIconList_Get(struct IClass
*cl
, Object
*obj
, struct opGet
*msg
)
1308 /* small macro to simplify return value storage */
1309 #define STORE *(msg->opg_Storage)
1310 struct TextIconList_DATA
*data
= INST_DATA(cl
, obj
);
1312 switch (msg
->opg_AttrID
)
1314 case MUIA_TextIconList_Left
: STORE
= data
->view_x
; return 1;
1315 case MUIA_TextIconList_Top
: STORE
= data
->view_y
; return 1;
1316 case MUIA_TextIconList_Width
: STORE
= data
->width
; return 1;
1317 case MUIA_TextIconList_Height
: STORE
= data
->height
; return 1;
1320 return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
1324 /**************************************************************************
1326 **************************************************************************/
1327 static IPTR
TextIconList_Setup(struct IClass
*cl
, Object
*obj
, struct MUIP_Setup
*msg
)
1329 struct TextIconList_DATA
*data
= INST_DATA(cl
, obj
);
1332 if (!DoSuperMethodA(cl
, obj
, (Msg
) msg
)) return 0;
1334 DoMethod(_win(obj
),MUIM_Window_AddEventHandler
, (IPTR
)&data
->ehn
);
1336 InitRastPort(&data
->temprp
);
1337 SetFont(&data
->temprp
, _font(obj
));
1338 data
->truecolor
= GetBitMapAttr(_screen(obj
)->RastPort
.BitMap
, BMA_DEPTH
) >= 15;
1340 data
->lineheight
= LINE_EXTRAHEIGHT
+ _font(obj
)->tf_YSize
;
1341 data
->is_setup
= TRUE
;
1343 for(i
= 0; i
< NUM_COLORS
; i
++)
1345 data
->colors
[i
].rgbpixel
= rgb_colors
[i
];
1346 data
->colors
[i
].pixel
= data
->colors
[i
].rgbpixel
;
1348 if (!data
->truecolor
|| !CyberGfxBase
)
1350 ULONG r
= (rgb_colors
[i
] & 0x00FF0000) >> 16;
1351 ULONG g
= (rgb_colors
[i
] & 0x0000FF00) >> 8;
1352 ULONG b
= (rgb_colors
[i
] & 0x000000FF);
1354 LONG pen
= ObtainBestPen(_screen(obj
)->ViewPort
.ColorMap
,
1358 OBP_FailIfBad
, FALSE
,
1359 OBP_Precision
, PRECISION_GUI
,
1364 data
->colors
[i
].pixel
= pen
;
1365 data
->colors
[i
].alloced
= TRUE
;
1369 data
->colors
[i
].pixel
= _pens(obj
)[pen_colors
[i
]];
1370 data
->colors
[i
].alloced
= FALSE
;
1375 if (data
->show_header
)
1377 data
->headerheight
= HEADERLINE_EXTRAHEIGHT
+ _font(obj
)->tf_YSize
;
1381 data
->headerheight
= 0;
1384 if (data
->num_entries
)
1386 CalcAllEntryDimensions(data
);
1388 data
->height
= data
->num_entries
* data
->lineheight
;
1389 RecalcColumnMaxWidths(data
);
1391 SetAttrs(obj
, MUIA_TextIconList_Width
, data
->width
,
1392 MUIA_TextIconList_Height
, data
->height
,
1399 /**************************************************************************
1401 **************************************************************************/
1402 static IPTR
TextIconList_Show(struct IClass
*cl
, Object
*obj
, struct MUIP_Show
*msg
)
1404 struct TextIconList_DATA
*data
= INST_DATA(cl
, obj
);
1405 LONG newleft
, newtop
;
1408 rc
= DoSuperMethodA(cl
, obj
, (Msg
)msg
);
1410 newleft
= data
->view_x
;
1411 newtop
= data
->view_y
;
1413 data
->view_width
= _mwidth(obj
);
1414 data
->view_height
= _mheight(obj
) - data
->headerheight
;
1416 SetAttrs(obj
, MUIA_TextIconList_VisWidth
, data
->view_width
,
1417 MUIA_TextIconList_VisHeight
, data
->view_height
,
1420 data
->view_rect
.MinX
= _mleft(obj
);
1421 data
->view_rect
.MinY
= _mtop(obj
) + data
->headerheight
;
1422 data
->view_rect
.MaxX
= _mright(obj
);
1423 data
->view_rect
.MaxY
= _mbottom(obj
);
1425 data
->header_rect
.MinX
= _mleft(obj
);
1426 data
->header_rect
.MinY
= _mtop(obj
);
1427 data
->header_rect
.MaxX
= _mright(obj
);
1428 data
->header_rect
.MaxY
= _mtop(obj
) + data
->headerheight
- 1;
1430 if (newleft
+ data
->view_width
> data
->width
) newleft
= data
->width
- data
->view_width
;
1431 if (newleft
< 0) newleft
= 0;
1433 if (newtop
+ data
->view_height
> data
->height
) newtop
= data
->height
- data
->view_height
;
1434 if (newtop
< 0) newtop
= 0;
1436 if ((newleft
!= data
->view_x
) || (newtop
!= data
->view_y
))
1438 SetAttrs(obj
, MUIA_TextIconList_Left
, newleft
,
1439 MUIA_TextIconList_Top
, newtop
,
1443 SetFont(_rp(obj
), _font(obj
));
1445 data
->is_shown
= TRUE
;
1450 /**************************************************************************
1452 **************************************************************************/
1453 static IPTR
TextIconList_Hide(struct IClass
*cl
, Object
*obj
, struct MUIP_Hide
*msg
)
1455 struct TextIconList_DATA
*data
= INST_DATA(cl
, obj
);
1458 data
->is_shown
= FALSE
;
1460 rc
= DoSuperMethodA(cl
, obj
, (Msg
)msg
);
1465 /**************************************************************************
1467 **************************************************************************/
1468 static IPTR
TextIconList_Cleanup(struct IClass
*cl
, Object
*obj
, struct MUIP_Cleanup
*msg
)
1470 struct TextIconList_DATA
*data
= INST_DATA(cl
, obj
);
1473 DoMethod(_win(obj
),MUIM_Window_RemEventHandler
, (IPTR
)&data
->ehn
);
1475 DeinitRastPort(&data
->temprp
);
1477 for(i
= 0; i
< NUM_COLORS
; i
++)
1479 if (data
->colors
[i
].alloced
)
1481 ReleasePen(_screen(obj
)->ViewPort
.ColorMap
, data
->colors
[i
].pixel
);
1482 data
->colors
[i
].alloced
= FALSE
;
1486 data
->is_setup
= FALSE
;
1488 return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
1491 /**************************************************************************
1493 **************************************************************************/
1494 static IPTR
TextIconList_AskMinMax(struct IClass
*cl
, Object
*obj
, struct MUIP_AskMinMax
*msg
)
1496 ULONG rc
= DoSuperMethodA(cl
, obj
, (Msg
) msg
);
1498 msg
->MinMaxInfo
->MinWidth
+= 10;
1499 msg
->MinMaxInfo
->MinHeight
+= 10;
1501 msg
->MinMaxInfo
->DefWidth
+= 100;
1502 msg
->MinMaxInfo
->DefHeight
+= 100;
1504 msg
->MinMaxInfo
->MaxWidth
= MUI_MAXMAX
;
1505 msg
->MinMaxInfo
->MaxHeight
= MUI_MAXMAX
;
1510 static void DrawHeaderLine(Object
*obj
, struct TextIconList_DATA
*data
)
1514 if (data
->show_header
&& MustRenderRect(data
, &data
->header_rect
))
1516 clip
= MUI_AddClipping(muiRenderInfo(obj
), data
->header_rect
.MinX
,
1517 data
->header_rect
.MinY
,
1518 data
->header_rect
.MaxX
- data
->header_rect
.MinX
+ 1,
1519 data
->header_rect
.MaxY
- data
->header_rect
.MinY
+ 1);
1521 RenderHeaderline(obj
, data
);
1523 MUI_RemoveClipping(muiRenderInfo(obj
),clip
);
1527 static void DrawLassoOutline(Object
*obj
, struct TextIconList_DATA
*data
)
1529 struct Rectangle lasso
;
1531 GetAbsoluteLassoRect(data
, &lasso
);
1534 MyRectFill(data
, _rp(obj
), lasso
.MinX
, lasso
.MinY
, lasso
.MaxX
, lasso
.MinY
, COLOR_SELECTED_BACKGROUND
);
1535 MyRectFill(data
, _rp(obj
), lasso
.MaxX
, lasso
.MinY
, lasso
.MaxX
, lasso
.MaxY
, COLOR_SELECTED_BACKGROUND
);
1536 MyRectFill(data
, _rp(obj
), lasso
.MinX
, lasso
.MaxY
, lasso
.MaxX
, lasso
.MaxY
, COLOR_SELECTED_BACKGROUND
);
1537 MyRectFill(data
, _rp(obj
), lasso
.MinX
, lasso
.MinY
, lasso
.MinX
, lasso
.MaxY
, COLOR_SELECTED_BACKGROUND
);
1539 SetABPenDrMd(_rp(obj
), _pens(obj
)[MPEN_SHADOW
], 0, JAM1
);
1540 Move(_rp(obj
), lasso
.MinX
, lasso
.MinY
);
1541 Draw(_rp(obj
), lasso
.MaxX
, lasso
.MinY
);
1542 Draw(_rp(obj
), lasso
.MaxX
, lasso
.MaxY
);
1543 Draw(_rp(obj
), lasso
.MinX
, lasso
.MaxY
);
1544 Draw(_rp(obj
), lasso
.MinX
, lasso
.MinY
);
1548 /**************************************************************************
1550 **************************************************************************/
1551 static IPTR
TextIconList_Draw(struct IClass
*cl
, Object
*obj
, struct MUIP_Draw
*msg
)
1553 struct TextIconList_DATA
*data
= INST_DATA(cl
, obj
);
1555 struct TextIconEntry
*entry
;
1557 DoSuperMethodA(cl
, obj
, (Msg
) msg
);
1559 if (msg
->flags
& MADF_DRAWUPDATE
)
1561 if (data
->update
== UPDATE_SCROLL
)
1563 struct Region
*region
;
1564 struct Rectangle xrect
, yrect
;
1565 BOOL scroll_caused_damage
;
1567 scroll_caused_damage
= (_rp(obj
)->Layer
->Flags
& LAYERREFRESH
) ? FALSE
: TRUE
;
1571 if ((abs(data
->update_scrolldx
) >= data
->view_width
) ||
1572 (abs(data
->update_scrolldy
) >= data
->view_height
))
1574 data
->update
= UPDATE_ALL
;
1575 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
1579 region
= NewRegion();
1582 data
->update
= UPDATE_ALL
;
1583 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
1587 if (data
->update_scrolldx
> 0)
1589 xrect
.MinX
= data
->view_rect
.MaxX
- data
->update_scrolldx
;
1590 xrect
.MinY
= data
->view_rect
.MinY
;
1591 xrect
.MaxX
= data
->view_rect
.MaxX
;
1592 xrect
.MaxY
= data
->view_rect
.MaxY
;
1594 OrRectRegion(region
, &xrect
);
1596 data
->update_rect1
= &xrect
;
1598 else if (data
->update_scrolldx
< 0)
1600 xrect
.MinX
= data
->view_rect
.MinX
;
1601 xrect
.MinY
= data
->view_rect
.MinY
;
1602 xrect
.MaxX
= data
->view_rect
.MinX
- data
->update_scrolldx
;
1603 xrect
.MaxY
= data
->view_rect
.MaxY
;
1605 OrRectRegion(region
, &xrect
);
1607 data
->update_rect1
= &xrect
;
1610 if (data
->update_scrolldy
> 0)
1612 yrect
.MinX
= data
->view_rect
.MinX
;
1613 yrect
.MinY
= data
->view_rect
.MaxY
- data
->update_scrolldy
;
1614 yrect
.MaxX
= data
->view_rect
.MaxX
;
1615 yrect
.MaxY
= data
->view_rect
.MaxY
;
1617 OrRectRegion(region
, &yrect
);
1619 data
->update_rect2
= &yrect
;
1621 else if (data
->update_scrolldy
< 0)
1623 yrect
.MinX
= data
->view_rect
.MinX
;
1624 yrect
.MinY
= data
->view_rect
.MinY
;
1625 yrect
.MaxX
= data
->view_rect
.MaxX
;
1626 yrect
.MaxY
= data
->view_rect
.MinY
- data
->update_scrolldy
;
1628 OrRectRegion(region
, &yrect
);
1630 data
->update_rect2
= &yrect
;
1633 ScrollRasterBF(_rp(obj
),
1634 data
->update_scrolldx
,
1635 data
->update_scrolldy
,
1636 data
->view_rect
.MinX
,
1637 data
->view_rect
.MinY
,
1638 data
->view_rect
.MaxX
,
1639 data
->view_rect
.MaxY
);
1641 if (data
->show_header
&& data
->update_scrolldx
)
1643 ScrollRasterBF(_rp(obj
),
1644 data
->update_scrolldx
,
1646 data
->header_rect
.MinX
,
1647 data
->header_rect
.MinY
,
1648 data
->header_rect
.MaxX
,
1649 data
->header_rect
.MaxY
);
1652 scroll_caused_damage
= scroll_caused_damage
&& (_rp(obj
)->Layer
->Flags
& LAYERREFRESH
) ? TRUE
: FALSE
;
1654 clip
= MUI_AddClipRegion(muiRenderInfo(obj
), region
);
1655 data
->update
= UPDATE_ALL
;
1656 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
1657 MUI_RemoveClipRegion(muiRenderInfo(obj
), clip
);
1659 if (data
->show_header
&& data
->update_scrolldx
)
1661 xrect
.MinY
= data
->header_rect
.MinY
;
1662 xrect
.MaxY
= data
->header_rect
.MaxY
;
1664 data
->update_rect1
= &xrect
;
1665 data
->update_rect2
= NULL
;
1667 clip
= MUI_AddClipping(muiRenderInfo(obj
), xrect
.MinX
,
1669 xrect
.MaxX
- xrect
.MinX
+ 1,
1670 xrect
.MaxY
- xrect
.MinY
+ 1);
1672 data
->update
= UPDATE_ALL
;
1673 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
1674 MUI_RemoveClipRegion(muiRenderInfo(obj
), clip
);
1676 data
->update_rect2
= NULL
;
1680 data
->update_rect1
= data
->update_rect2
= NULL
;
1681 data
->update_scrolldx
= data
->update_scrolldy
= 0;
1683 // DisposeRegion(region);
1685 if (scroll_caused_damage
)
1687 if (MUI_BeginRefresh(muiRenderInfo(obj
), 0))
1689 /* Theoretically it might happen that more damage is caused
1690 after ScrollRaster. By something else, like window movement
1691 in front of our window. Therefore refresh root object of
1692 window, not just this object */
1696 get(_win(obj
),MUIA_Window_RootObject
, &o
);
1697 MUI_Redraw(o
, MADF_DRAWOBJECT
);
1699 MUI_EndRefresh(muiRenderInfo(obj
), 0);
1705 } /* if (data->update == UPDATE_SCROLL) */
1706 else if (data
->update
== UPDATE_DIRTY_ENTRIES
)
1708 struct Region
*clipregion
;
1709 LONG first
, numvisible
, index
= 0;
1713 clipregion
= NewRectRegion(data
->view_rect
.MinX
,
1714 data
->view_rect
.MinY
,
1715 data
->view_rect
.MaxX
,
1716 data
->view_rect
.MaxY
);
1720 if (data
->lasso_active
)
1722 struct Rectangle lasso_rect
;
1724 GetAbsoluteLassoRect(data
, &lasso_rect
);
1725 ClearRectRegion(clipregion
, &lasso_rect
);
1728 clip
= MUI_AddClipRegion(muiRenderInfo(obj
), clipregion
);
1730 first
= FirstVisibleLine(data
);
1731 numvisible
= NumVisibleLines(data
);
1733 ForeachNode(&data
->entries_list
, entry
)
1737 if ((index
>= first
) && (index
< first
+ numvisible
))
1739 RenderEntry(obj
, data
, index
);
1745 if (data
->lasso_active
)
1747 struct Rectangle lasso_rect
;
1748 struct Rectangle vis_lasso_rect
;
1750 GetAbsoluteLassoRect(data
, &lasso_rect
);
1752 if (AndRectRect(&data
->view_rect
, &lasso_rect
, &vis_lasso_rect
))
1754 MUI_RemoveClipRegion(muiRenderInfo(obj
),clip
);
1756 clipregion
= NewRectRegion(vis_lasso_rect
.MinX
,
1757 vis_lasso_rect
.MinY
,
1758 vis_lasso_rect
.MaxX
,
1759 vis_lasso_rect
.MaxY
);
1761 data
->lasso_paint
= TRUE
;
1763 clip
= MUI_AddClipRegion(muiRenderInfo(obj
), clipregion
);
1766 ForeachNode(&data
->entries_list
, entry
)
1770 if ((index
>= first
) && (index
< first
+ numvisible
))
1772 RenderEntry(obj
, data
, index
);
1778 data
->lasso_paint
= FALSE
;
1780 DrawLassoOutline(obj
, data
);
1782 } /* if (AndRectRect(&data->view_rect, &lasso_rect, &vis_lasso_rect)) */
1784 } /* if (data->lasso_active) */
1786 MUI_RemoveClipRegion(muiRenderInfo(obj
), clip
);
1788 ForeachNode(&data
->entries_list
, entry
)
1790 if (entry
->dirty
) entry
->dirty
= FALSE
;
1795 } /* else if (data->update == UPDATE_DIRTY_ENTRIES) */
1796 else if (data
->update
== UPDATE_HEADER
)
1800 DrawHeaderLine(obj
, data
);
1805 } /* if (msg->flags & MADF_DRAWUPDATE) */
1807 if (MustRenderRect(data
, &data
->view_rect
))
1809 struct Region
*clipregion
;
1811 clipregion
= NewRectRegion(data
->view_rect
.MinX
,
1812 data
->view_rect
.MinY
,
1813 data
->view_rect
.MaxX
,
1814 data
->view_rect
.MaxY
);
1818 if (data
->lasso_active
)
1820 struct Rectangle lasso_rect
;
1822 GetAbsoluteLassoRect(data
, &lasso_rect
);
1823 ClearRectRegion(clipregion
, &lasso_rect
);
1826 clip
= MUI_AddClipRegion(muiRenderInfo(obj
), clipregion
);
1828 RenderAllEntries(obj
, data
);
1830 if (data
->lasso_active
)
1832 struct Rectangle lasso_rect
;
1833 struct Rectangle vis_lasso_rect
;
1835 GetAbsoluteLassoRect(data
, &lasso_rect
);
1837 if (AndRectRect(&data
->view_rect
, &lasso_rect
, &vis_lasso_rect
))
1839 MUI_RemoveClipRegion(muiRenderInfo(obj
),clip
);
1841 clipregion
= NewRectRegion(vis_lasso_rect
.MinX
,
1842 vis_lasso_rect
.MinY
,
1843 vis_lasso_rect
.MaxX
,
1844 vis_lasso_rect
.MaxY
);
1846 data
->lasso_paint
= TRUE
;
1848 clip
= MUI_AddClipRegion(muiRenderInfo(obj
), clipregion
);
1850 RenderAllEntries(obj
, data
);
1852 data
->lasso_paint
= FALSE
;
1854 DrawLassoOutline(obj
, data
);
1859 MUI_RemoveClipRegion(muiRenderInfo(obj
),clip
);
1861 } /* if (clipregion) */
1863 } /* if (MustRenderRect(data, &data->view_rect)) */
1865 DrawHeaderLine(obj
, data
);
1872 /**************************************************************************
1874 **************************************************************************/
1875 static IPTR
TextIconList_AutoScroll(struct IClass
*cl
, Object
*obj
, Msg msg
)
1877 struct TextIconList_DATA
*data
= INST_DATA(cl
, obj
);
1879 if (data
->lasso_active
)
1881 LONG new_view_x
, new_view_y
;
1883 new_view_x
= data
->view_x
;
1884 new_view_y
= data
->view_y
;
1886 if (data
->click_x
< data
->view_rect
.MinX
)
1888 new_view_x
-= (data
->view_rect
.MinX
- data
->click_x
) / 4;
1890 else if (data
->click_x
> data
->view_rect
.MaxX
)
1892 new_view_x
+= (data
->click_x
- data
->view_rect
.MaxX
) / 4;
1895 if (data
->click_y
< data
->view_rect
.MinY
)
1897 new_view_y
-= (data
->view_rect
.MinY
- data
->click_y
) / 4;
1899 else if (data
->click_y
> data
->view_rect
.MaxY
)
1901 new_view_y
+= (data
->click_y
- data
->view_rect
.MaxY
) / 4;
1904 if (new_view_x
+ data
->view_width
> data
->width
)
1906 new_view_x
= data
->width
- data
->view_width
;
1908 if (new_view_x
< 0) new_view_x
= 0;
1910 if (new_view_y
+ data
->view_height
> data
->height
)
1912 new_view_y
= data
->height
- data
->view_height
;
1914 if (new_view_y
< 0) new_view_y
= 0;
1916 if ((new_view_x
!= data
->view_x
) || (new_view_y
!= data
->view_y
))
1918 data
->old_lasso_rect
= data
->lasso_rect
;
1920 data
->lasso_rect
.MaxX
+= new_view_x
- data
->view_x
;
1921 data
->lasso_rect
.MaxY
+= new_view_y
- data
->view_y
;
1923 RethinkLasso(obj
, data
);
1925 SetAttrs(obj
, MUIA_TextIconList_Left
, new_view_x
,
1926 MUIA_TextIconList_Top
, new_view_y
,
1933 DisableAutoScrollTimer(obj
, data
);
1939 /**************************************************************************
1941 **************************************************************************/
1942 static IPTR
TextIconList_HandleEvent(struct IClass
*cl
, Object
*obj
, struct MUIP_HandleEvent
*msg
)
1944 struct TextIconList_DATA
*data
= INST_DATA(cl
, obj
);
1949 LONG mx
= msg
->imsg
->MouseX
;
1950 LONG my
= msg
->imsg
->MouseY
;
1954 shift_qual
= (msg
->imsg
->Qualifier
& (IEQUALIFIER_LSHIFT
| IEQUALIFIER_RSHIFT
)) ? TRUE
: FALSE
;
1956 switch (msg
->imsg
->Class
)
1958 case IDCMP_MOUSEBUTTONS
:
1959 switch(msg
->imsg
->Code
)
1962 //kprintf("SELECTDOWN\n");
1963 if (data
->inputstate
== INPUTSTATE_NONE
)
1965 if ( ((line
= LineUnderMouse(data
, mx
, my
)) >= 0) &&
1966 ((col
= ColumnUnderMouse(data
, mx
, my
)) >= 0) )
1968 //kprintf("click on line %d col %d\n", line, col);
1970 if (data
->column_clickable
[col
])
1972 if (data
->active_entry
!= line
)
1974 struct TextIconEntry
*old
, *new;
1976 old
= GetEntryFromIndex(data
, data
->active_entry
);
1977 new = GetEntryFromIndex(data
, line
);
1979 data
->active_entry
= line
;
1980 if (old
&& old
->selected
&& !shift_qual
)
1982 Remove((struct Node
*)&old
->selection_node
);
1983 old
->selected
= FALSE
;
1986 data
->num_selected
--;
1989 if (!shift_qual
&& data
->num_selected
)
1991 struct TextIconEntry
*entry
;
1993 ForeachNode(&data
->entries_list
, entry
)
1995 if (entry
->selected
)
1997 Remove((struct Node
*)&entry
->selection_node
);
1998 entry
->selected
= FALSE
;
1999 entry
->dirty
= TRUE
;
2003 data
->num_selected
= 0;
2006 if (new && !new->selected
)
2008 AddTail((struct List
*)&data
->selection_list
, (struct Node
*)&new->selection_node
);
2009 new->selected
= TRUE
;
2012 data
->num_selected
++;
2015 data
->update
= UPDATE_DIRTY_ENTRIES
;
2016 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
2018 } /* if (data->active_entry != line) */
2020 } /* if (data->column_clickable[col]) */
2023 if (!shift_qual
&& data
->num_selected
)
2025 struct TextIconEntry
*entry
;
2027 ForeachNode(&data
->entries_list
, entry
)
2029 if (entry
->selected
)
2031 Remove((struct Node
*)&entry
->selection_node
);
2032 entry
->selected
= FALSE
;
2033 entry
->dirty
= TRUE
;
2037 data
->num_selected
= 0;
2038 data
->update
= UPDATE_DIRTY_ENTRIES
;
2039 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
2042 data
->lasso_rect
.MinX
= mx
- data
->view_rect
.MinX
+ data
->view_x
;
2043 data
->lasso_rect
.MinY
= my
- data
->view_rect
.MinY
+ data
->view_y
;
2044 data
->lasso_rect
.MaxX
= mx
- data
->view_rect
.MinX
+ data
->view_x
;
2045 data
->lasso_rect
.MaxY
= my
- data
->view_rect
.MinY
+ data
->view_y
;
2047 data
->inputstate
= INPUTSTATE_LASSO
;
2048 data
->lasso_active
= TRUE
;
2053 EnableMouseMoveEvents(obj
, data
);
2056 } /* if click on entry */
2057 else if ((col
= ColumnResizeHandleUnderMouse(data
, mx
, my
)) >= 0)
2059 data
->inputstate
= INPUTSTATE_COL_RESIZE
;
2060 data
->click_column
= col
;
2061 data
->click_x
= mx
- data
->column_width
[col
];
2063 EnableMouseMoveEvents(obj
, data
);
2065 } /* else if click on column header entry resize handle */
2066 else if ((col
= ColumnHeaderUnderMouse(data
, mx
, my
)) >= 0)
2068 data
->inputstate
= INPUTSTATE_COL_HEADER_CLICK
;
2069 data
->click_column
= col
;
2073 EnableMouseMoveEvents(obj
, data
);
2075 data
->update
= UPDATE_HEADER
;
2076 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
2079 } /* if (data->inputstate == INPUTSTATE_NONE) */
2083 if (data
->inputstate
== INPUTSTATE_COL_RESIZE
)
2085 DisableMouseMoveEvents(obj
, data
);
2087 data
->inputstate
= INPUTSTATE_NONE
;
2089 else if (data
->inputstate
== INPUTSTATE_COL_HEADER_CLICK
)
2091 DisableMouseMoveEvents(obj
, data
);
2093 data
->inputstate
= INPUTSTATE_NONE
;
2095 if (ColumnHeaderUnderMouse(data
, data
->click_x
, data
->click_y
) == data
->click_column
)
2098 if (data
->column_sortable
[data
->click_column
])
2100 if (data
->sort_column
== data
->click_column
)
2102 data
->sort_direction
= 1 - data
->sort_direction
;
2106 data
->sort_direction
= SORT_DIRECTION_UP
;
2107 data
->sort_column
= data
->click_column
;
2110 ReSortEntries(data
);
2112 data
->update
= UPDATE_ALL
;
2113 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
2118 data
->update
= UPDATE_HEADER
;
2119 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
2122 } /* mouse still over column header */
2124 } /* else if (data->inputstate == INPUTSTATE_COL_HEADER_CLICK) */
2125 else if (data
->inputstate
== INPUTSTATE_LASSO
)
2127 DisableMouseMoveEvents(obj
, data
);
2128 DisableAutoScrollTimer(obj
, data
);
2130 data
->inputstate
= INPUTSTATE_NONE
;
2131 data
->lasso_active
= FALSE
;
2133 data
->update
= UPDATE_ALL
;
2134 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
2139 if (data
->inputstate
== INPUTSTATE_NONE
)
2141 data
->inputstate
= INPUTSTATE_PAN
;
2143 data
->click_x
= mx
- data
->view_rect
.MinX
+ data
->view_x
;
2144 data
->click_y
= my
- data
->view_rect
.MinY
+ data
->view_y
;
2146 EnableMouseMoveEvents(obj
, data
);
2152 if (data
->inputstate
== INPUTSTATE_PAN
)
2154 DisableMouseMoveEvents(obj
, data
);
2156 data
->inputstate
= INPUTSTATE_NONE
;
2160 } /* switch(msg->imsg->Code) */
2163 case IDCMP_MOUSEMOVE
:
2164 if (data
->inputstate
== INPUTSTATE_PAN
)
2166 LONG new_view_x
, new_view_y
;
2168 new_view_x
= data
->click_x
- (mx
- data
->view_rect
.MinX
);
2169 new_view_y
= data
->click_y
- (my
- data
->view_rect
.MinY
);
2171 if (new_view_x
+ data
->view_width
> data
->width
)
2173 new_view_x
= data
->width
- data
->view_width
;
2175 if (new_view_x
< 0) new_view_x
= 0;
2177 if (new_view_y
+ data
->view_height
> data
->height
)
2179 new_view_y
= data
->height
- data
->view_height
;
2181 if (new_view_y
< 0) new_view_y
= 0;
2183 if ((new_view_x
!= data
->view_x
) || (new_view_y
!= data
->view_y
))
2185 SetAttrs(obj
, MUIA_TextIconList_Left
, new_view_x
,
2186 MUIA_TextIconList_Top
, new_view_y
,
2190 } /* if (data->inputstate == INPUTSTATE_PAN) */
2191 else if (data
->inputstate
== INPUTSTATE_COL_RESIZE
)
2193 LONG act_colwidth
= data
->column_width
[data
->click_column
];
2194 LONG new_colwidth
= mx
- data
->click_x
;
2196 if (new_colwidth
< MIN_COLUMN_WIDTH
) new_colwidth
= MIN_COLUMN_WIDTH
;
2198 if (new_colwidth
> act_colwidth
)
2200 data
->column_width
[data
->click_column
] = new_colwidth
;
2201 data
->width
+= new_colwidth
- act_colwidth
;
2202 data
->update
= UPDATE_ALL
;
2203 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
2205 set(obj
, MUIA_TextIconList_Width
, data
->width
);
2207 else if (new_colwidth
< act_colwidth
)
2209 BOOL scroll_left
= FALSE
;
2211 data
->column_width
[data
->click_column
] = new_colwidth
;
2212 data
->width
+= new_colwidth
- act_colwidth
;
2214 if (data
->view_x
+ data
->view_width
> data
->width
)
2216 LONG new_view_x
= data
->width
- data
->view_width
;
2218 if (new_view_x
< 0) new_view_x
= 0;
2219 if (new_view_x
!= data
->view_x
)
2222 data
->view_x
= new_view_x
;
2226 data
->update
= UPDATE_ALL
;
2227 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
2229 SetAttrs(obj
, scroll_left
? MUIA_TextIconList_Left
: TAG_IGNORE
, data
->view_x
,
2230 MUIA_TextIconList_Width
, data
->width
,
2233 } /* else if (new_colwidth < act_colwidth) */
2235 } /* else if (data->inputstate == INPUTSTATE_COL_RESIZE) */
2236 else if (data
->inputstate
== INPUTSTATE_COL_HEADER_CLICK
)
2238 BOOL old
= ColumnHeaderUnderMouse(data
, data
->click_x
, data
->click_y
);
2239 BOOL
new = ColumnHeaderUnderMouse(data
, mx
, my
);
2245 data
->update
= UPDATE_HEADER
;
2246 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
2249 else if (data
->inputstate
== INPUTSTATE_LASSO
)
2251 struct Rectangle old_lasso
, new_lasso
;
2252 struct Region
*region
;
2258 data
->old_lasso_rect
= data
->lasso_rect
;
2259 GetAbsoluteLassoRect(data
, &old_lasso
);
2260 data
->lasso_rect
.MaxX
= mx
- data
->view_rect
.MinX
+ data
->view_x
;
2261 data
->lasso_rect
.MaxY
= my
- data
->view_rect
.MinY
+ data
->view_y
;
2262 GetAbsoluteLassoRect(data
, &new_lasso
);
2264 region
= NewRectRegion(new_lasso
.MinX
, new_lasso
.MinY
, new_lasso
.MaxX
, new_lasso
.MaxY
);
2267 struct Rectangle render_range
;
2269 XorRectRegion(region
, &old_lasso
);
2270 OrRectOutlineRegion(region
, &old_lasso
);
2271 OrRectOutlineRegion(region
, &new_lasso
);
2273 render_range
= region
->bounds
;
2275 clip
= MUI_AddClipRegion(muiRenderInfo(obj
), region
);
2277 data
->update
= UPDATE_ALL
;
2278 data
->update_rect1
= &render_range
;
2279 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
2280 data
->update_rect1
= 0;
2282 MUI_RemoveClipRegion(muiRenderInfo(obj
), clip
);
2285 RethinkLasso(obj
, data
);
2287 if ((mx
>= data
->view_rect
.MinX
) &&
2288 (my
>= data
->view_rect
.MinY
) &&
2289 (mx
<= data
->view_rect
.MaxX
) &&
2290 (my
<= data
->view_rect
.MaxY
))
2292 DisableAutoScrollTimer(obj
, data
);
2296 EnableAutoScrollTimer(obj
, data
);
2303 } /* switch (msg->imsg->Class) */
2305 } /* if (msg->imsg) */
2311 /**************************************************************************
2312 MUIM_TextIconList_Clear
2313 **************************************************************************/
2314 static IPTR
TextIconList_Clear(struct IClass
*cl
, Object
*obj
, struct MUIP_TextIconList_Clear
*msg
)
2316 struct TextIconList_DATA
*data
= INST_DATA(cl
, obj
);
2317 struct TextIconEntry
*node
;
2320 while ((node
= (struct TextIconEntry
*)RemTail((struct List
*)&data
->entries_list
)))
2322 FreePooled(data
->pool
,node
,sizeof(*node
));
2324 NewList((struct List
*)&data
->selection_list
);
2326 data
->view_x
= data
->view_y
= data
->width
= data
->height
= 0;
2327 data
->num_entries
= 0;
2328 data
->active_entry
= -1;
2329 data
->num_selected
= 0;
2332 for(i
= 0; i
< NUM_COLUMNS
; i
++)
2334 data
->column_maxwidth
[i
] = 0;
2337 SetAttrs(obj
, MUIA_TextIconList_Left
, data
->view_x
,
2338 MUIA_TextIconList_Top
, data
->view_y
,
2339 MUIA_TextIconList_Width
, data
->width
,
2340 MUIA_TextIconList_Height
, data
->height
,
2343 data
->update
= UPDATE_ALL
;
2344 MUI_Redraw(obj
,MADF_DRAWUPDATE
);
2348 /**************************************************************************
2349 MUIM_TextIconList_Add.
2350 Returns 0 on failure otherwise 1
2351 **************************************************************************/
2352 static IPTR
TextIconList_Add(struct IClass
*cl
, Object
*obj
, struct MUIP_TextIconList_Add
*msg
)
2354 struct TextIconList_DATA
*data
= INST_DATA(cl
, obj
);
2355 struct TextIconEntry
*entry
;
2359 if (!(entry
= AllocPooled(data
->pool
,sizeof(struct TextIconEntry
))))
2364 memset(entry
, 0, sizeof(struct TextIconEntry
));
2366 entry
->fib
= *msg
->fib
;
2368 if (entry
->fib
.fib_DirEntryType
> 0)
2370 strcpy(GetTextIconEntryText(data
, entry
, INDEX_SIZE
), "Drawer");
2374 sprintf(GetTextIconEntryText(data
, entry
, INDEX_SIZE
), "%ld", entry
->fib
.fib_Size
);
2377 dt
.dat_Stamp
= entry
->fib
.fib_Date
;
2378 dt
.dat_Format
= FORMAT_DOS
;
2380 dt
.dat_StrDay
= NULL
;
2381 dt
.dat_StrDate
= GetTextIconEntryText(data
, entry
, INDEX_DATE
);
2382 dt
.dat_StrTime
= GetTextIconEntryText(data
, entry
, INDEX_TIME
);;
2386 sp
= GetTextIconEntryText(data
, entry
, INDEX_PROTECTION
);
2387 *sp
++ = (entry
->fib
.fib_Protection
& FIBF_SCRIPT
) ? 's' : '-';
2388 *sp
++ = (entry
->fib
.fib_Protection
& FIBF_PURE
) ? 'p' : '-';
2389 *sp
++ = (entry
->fib
.fib_Protection
& FIBF_ARCHIVE
) ? 'a' : '-';
2390 *sp
++ = (entry
->fib
.fib_Protection
& FIBF_READ
) ? '-' : 'r';
2391 *sp
++ = (entry
->fib
.fib_Protection
& FIBF_WRITE
) ? '-' : 'w';
2392 *sp
++ = (entry
->fib
.fib_Protection
& FIBF_EXECUTE
) ? '-' : 'e';
2393 *sp
++ = (entry
->fib
.fib_Protection
& FIBF_DELETE
) ? '-' : 'd';
2396 data
->num_entries
++;
2398 SortInNode(data
, (struct List
*)&data
->entries_list
, (struct Node
*)entry
, (APTR
)CompareNodes
);
2402 CalcEntryDimension(data
, entry
);
2403 data
->height
+= data
->lineheight
;
2407 SetAttrs(obj
, MUIA_TextIconList_Width
, data
->width
,
2408 MUIA_TextIconList_Height
, data
->height
,
2415 BOOPSI_DISPATCHER(IPTR
,TextIconList_Dispatcher
, cl
, obj
, msg
)
2417 switch (msg
->MethodID
)
2420 case OM_NEW
: return TextIconList_New(cl
, obj
, (struct opSet
*)msg
);
2421 case OM_DISPOSE
: return TextIconList_Dispose(cl
,obj
, msg
);
2422 case OM_SET
: return TextIconList_Set(cl
,obj
,(struct opSet
*)msg
);
2423 case OM_GET
: return TextIconList_Get(cl
,obj
,(struct opGet
*)msg
);
2424 case MUIM_Setup
: return TextIconList_Setup(cl
,obj
,(struct MUIP_Setup
*)msg
);
2425 case MUIM_Show
: return TextIconList_Show(cl
,obj
,(struct MUIP_Show
*)msg
);
2426 case MUIM_Hide
: return TextIconList_Hide(cl
,obj
,(struct MUIP_Hide
*)msg
);
2427 case MUIM_Cleanup
: return TextIconList_Cleanup(cl
,obj
,(struct MUIP_Cleanup
*)msg
);
2428 case MUIM_AskMinMax
: return TextIconList_AskMinMax(cl
,obj
,(struct MUIP_AskMinMax
*)msg
);
2429 case MUIM_Draw
: return TextIconList_Draw(cl
,obj
,(struct MUIP_Draw
*)msg
);
2430 // case MUIM_Layout: return TextIconList_Layout(cl,obj,(struct MUIP_Layout *)msg);
2431 case MUIM_HandleEvent
: return TextIconList_HandleEvent(cl
,obj
,(struct MUIP_HandleEvent
*)msg
);
2432 // case MUIM_CreateDragImage: return TextIconList_CreateDragImage(cl,obj,(APTR)msg);
2433 // case MUIM_DeleteDragImage: return TextIconList_DeleteDragImage(cl,obj,(APTR)msg);
2434 // case MUIM_DragQuery: return TextIconList_DragQuery(cl,obj,(APTR)msg);
2435 // case MUIM_DragReport: return TextIconList_DragReport(cl,obj,(APTR)msg);
2436 // case MUIM_DragDrop: return TextIconList_DragDrop(cl,obj,(APTR)msg);
2438 // case MUIM_TextIconList_Update: return TextIconList_Update(cl,obj,(APTR)msg);
2439 case MUIM_TextIconList_Clear
: return TextIconList_Clear(cl
,obj
,(APTR
)msg
);
2440 case MUIM_TextIconList_Add
: return TextIconList_Add(cl
,obj
,(APTR
)msg
);
2441 // case MUIM_TextIconList_NextSelected: return TextIconList_NextSelected(cl,obj,(APTR)msg);
2442 // case MUIM_TextIconList_UnselectAll: return TextIconList_UnselectAll(cl,obj,(APTR)msg);
2444 case MUIM_TextIconList_AutoScroll
: return TextIconList_AutoScroll(cl
,obj
,(APTR
)msg
);
2447 return DoSuperMethodA(cl
, obj
, msg
);
2449 BOOPSI_DISPATCHER_END
2451 /*================ TextIconListview class ===================*/
2453 #define MUIB_TextIconListview (MUIB_AROS | 0x00000800)
2455 #define MUIA_TextIconListview_TextIconList (MUIB_TextIconListview | 0x00000000)
2456 #define MUIA_TextIconListview_UseWinBorder (MUIB_TextIconListview | 0x00000001)
2458 #define TextIconListviewObject BOOPSIOBJMACRO_START(CL_TextIconListview->mcc_Class)
2460 struct TextIconListview_DATA
2462 Object
*texticonlist
;
2463 Object
*vert
, *horiz
, *button
;
2465 struct Hook layout_hook
;
2469 IPTR
TextIconListview_Layout_Function(struct Hook
*hook
, Object
*obj
, struct MUI_LayoutMsg
*lm
)
2471 struct TextIconListview_DATA
*data
= (struct TextIconListview_DATA
*)hook
->h_Data
;
2473 switch (lm
->lm_Type
)
2477 /* Calulate the minmax dimension of the group,
2478 ** We only have a fixed number of children, so we need no NextObject()
2480 WORD maxxxxwidth
= 0;
2481 WORD maxxxxheight
= 0;
2483 maxxxxwidth
= _minwidth(data
->texticonlist
) + _minwidth(data
->vert
);
2484 if (_minwidth(data
->horiz
) > maxxxxwidth
) maxxxxwidth
= _minwidth(data
->horiz
);
2485 lm
->lm_MinMax
.MinWidth
= maxxxxwidth
;
2487 maxxxxheight
= _minheight(data
->texticonlist
) + _minheight(data
->horiz
);
2488 if (_minheight(data
->vert
) > maxxxxheight
) maxxxxheight
= _minheight(data
->vert
);
2489 lm
->lm_MinMax
.MinHeight
= maxxxxheight
;
2491 maxxxxwidth
= _defwidth(data
->texticonlist
) + _defwidth(data
->vert
);
2492 if (_defwidth(data
->horiz
) > maxxxxwidth
) maxxxxwidth
= _defwidth(data
->horiz
);
2493 lm
->lm_MinMax
.DefWidth
= maxxxxwidth
;
2495 maxxxxheight
= _defheight(data
->texticonlist
) + _defheight(data
->horiz
);
2496 if (_defheight(data
->vert
) > maxxxxheight
) maxxxxheight
= _defheight(data
->vert
);
2497 lm
->lm_MinMax
.DefHeight
= maxxxxheight
;
2499 lm
->lm_MinMax
.MaxWidth
= MUI_MAXMAX
;
2500 lm
->lm_MinMax
.MaxHeight
= MUI_MAXMAX
;
2507 /* Now place the objects between (0,0,lm->lm_Layout.Width-1,lm->lm_Layout.Height-1)
2512 LONG vert_width
= _minwidth(data
->vert
);
2513 LONG horiz_height
= _minheight(data
->horiz
);
2514 LONG lay_width
= lm
->lm_Layout
.Width
;
2515 LONG lay_height
= lm
->lm_Layout
.Height
;
2519 /* layout the virtual group a first time, to determine the virtual width/height */
2520 MUI_Layout(data
->texticonlist
,0,0,lay_width
,lay_height
,0);
2522 get(data
->texticonlist
, MUIA_TextIconList_Width
, &virt_width
);
2523 get(data
->texticonlist
, MUIA_TextIconList_Height
, &virt_height
);
2525 virt_width
+= _subwidth(data
->texticonlist
);
2526 virt_height
+= _subheight(data
->texticonlist
);
2528 if (virt_width
> lay_width
&& virt_height
> lay_height
)
2530 /* We need all scrollbars and the button */
2531 set(data
->vert
, MUIA_ShowMe
, TRUE
); /* We could also overload MUIM_Show... */
2532 set(data
->horiz
, MUIA_ShowMe
, TRUE
);
2533 set(data
->button
, MUIA_ShowMe
, TRUE
);
2534 cont_width
= lay_width
- vert_width
;
2535 cont_height
= lay_height
- horiz_height
;
2536 MUI_Layout(data
->vert
, cont_width
, 0, vert_width
, cont_height
,0);
2537 MUI_Layout(data
->horiz
, 0, cont_height
, cont_width
, horiz_height
, 0);
2538 MUI_Layout(data
->button
, cont_width
, cont_height
, vert_width
, horiz_height
, 0);
2541 if (virt_height
> lay_height
)
2543 set(data
->vert
, MUIA_ShowMe
, TRUE
);
2544 set(data
->horiz
, MUIA_ShowMe
, FALSE
);
2545 set(data
->button
, MUIA_ShowMe
, FALSE
);
2547 cont_width
= lay_width
- vert_width
;
2548 cont_height
= lay_height
;
2549 MUI_Layout(data
->vert
, cont_width
, 0, vert_width
, cont_height
,0);
2552 if (virt_width
> lay_width
)
2554 set(data
->vert
, MUIA_ShowMe
, FALSE
);
2555 set(data
->horiz
, MUIA_ShowMe
, TRUE
);
2556 set(data
->button
, MUIA_ShowMe
, FALSE
);
2558 cont_width
= lay_width
;
2559 cont_height
= lay_height
- horiz_height
;
2560 MUI_Layout(data
->horiz
, 0, cont_height
, cont_width
, horiz_height
, 0);
2563 set(data
->vert
, MUIA_ShowMe
, FALSE
);
2564 set(data
->horiz
, MUIA_ShowMe
, FALSE
);
2565 set(data
->button
, MUIA_ShowMe
, FALSE
);
2567 cont_width
= lay_width
;
2568 cont_height
= lay_height
;
2573 /* Layout the group a second time, note that setting _mwidth() and _mheight() should be enough, or we invent a new flag */
2574 MUI_Layout(data
->texticonlist
,0,0,cont_width
,cont_height
,0);
2582 IPTR
TextIconListview_Function(struct Hook
*hook
, APTR dummyobj
, void **msg
)
2584 struct TextIconListview_DATA
*data
= (struct TextIconListview_DATA
*)hook
->h_Data
;
2585 int type
= (int)msg
[0];
2586 LONG val
= (LONG
)msg
[1];
2592 get(data
->vert
,MUIA_Prop_First
,&val
);
2593 SetAttrs(data
->texticonlist
,MUIA_TextIconList_Top
, val
, MUIA_NoNotify
, TRUE
, TAG_DONE
);
2599 get(data
->horiz
,MUIA_Prop_First
,&val
);
2600 SetAttrs(data
->texticonlist
,MUIA_TextIconList_Left
, val
, MUIA_NoNotify
, TRUE
, TAG_DONE
);
2603 case 3: nnset(data
->horiz
, MUIA_Prop_First
, val
); break;
2604 case 4: nnset(data
->vert
, MUIA_Prop_First
, val
); break;
2610 IPTR
TextIconListview__OM_NEW(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
)
2612 struct TextIconListview_DATA
*data
;
2613 //struct TagItem *tags,*tag;
2614 Object
*texticonlist
= (Object
*)GetTagData(MUIA_TextIconListview_TextIconList
, 0, msg
->ops_AttrList
);
2615 Object
*vert
,*horiz
,*button
,*group
;
2619 usewinborder
= GetTagData(MUIA_TextIconListview_UseWinBorder
, FALSE
, msg
->ops_AttrList
);
2621 if (!usewinborder
) button
= ScrollbuttonObject
, End
;
2624 obj
= (Object
*)DoSuperNewTags(cl
, obj
, NULL
,
2625 MUIA_Group_Horiz
, FALSE
,
2626 Child
, (IPTR
) (group
= GroupObject
,
2627 Child
, (IPTR
) texticonlist
,
2628 Child
, (IPTR
) (vert
= ScrollbarObject
,
2629 usewinborder
? MUIA_Prop_UseWinBorder
: TAG_IGNORE
, MUIV_Prop_UseWinBorder_Right
,
2630 MUIA_Prop_DeltaFactor
, 20,
2631 MUIA_Group_Horiz
, FALSE
,
2633 Child
, (IPTR
) (horiz
= ScrollbarObject
,
2634 usewinborder
?MUIA_Prop_UseWinBorder
:TAG_IGNORE
, MUIV_Prop_UseWinBorder_Bottom
,
2635 MUIA_Prop_DeltaFactor
, 20,
2636 MUIA_Group_Horiz
, TRUE
,
2638 usewinborder
? TAG_IGNORE
: Child
, (IPTR
) button
,
2647 data
= INST_DATA(cl
, obj
);
2649 data
->horiz
= horiz
;
2650 data
->button
= button
;
2651 data
->texticonlist
= texticonlist
;
2655 data
->layout_hook
.h_Entry
= HookEntry
;
2656 data
->layout_hook
.h_SubEntry
= (HOOKFUNC
)TextIconListview_Layout_Function
;
2657 data
->layout_hook
.h_Data
= data
;
2659 SetAttrs(group
, MUIA_Group_Forward
, FALSE
,
2660 MUIA_Group_LayoutHook
, (IPTR
) &data
->layout_hook
,
2664 data
->hook
.h_Entry
= HookEntry
;
2665 data
->hook
.h_SubEntry
= (HOOKFUNC
)TextIconListview_Function
;
2666 data
->hook
.h_Data
= data
;
2668 DoMethod(vert
, MUIM_Notify
, MUIA_Prop_First
, MUIV_EveryTime
, (IPTR
)obj
, 4, MUIM_CallHook
, (IPTR
)&data
->hook
, 1, MUIV_TriggerValue
);
2669 DoMethod(horiz
, MUIM_Notify
, MUIA_Prop_First
, MUIV_EveryTime
, (IPTR
)obj
, 4, MUIM_CallHook
, (IPTR
)&data
->hook
, 2, MUIV_TriggerValue
);
2670 DoMethod(texticonlist
, MUIM_Notify
, MUIA_TextIconList_Left
, MUIV_EveryTime
, (IPTR
)obj
, 4, MUIM_CallHook
, (IPTR
)&data
->hook
, 3, MUIV_TriggerValue
);
2671 DoMethod(texticonlist
, MUIM_Notify
, MUIA_TextIconList_Top
, MUIV_EveryTime
, (IPTR
)obj
, 4, MUIM_CallHook
, (IPTR
)&data
->hook
, 4, MUIV_TriggerValue
);
2672 DoMethod(texticonlist
, MUIM_Notify
, MUIA_TextIconList_Width
, MUIV_EveryTime
, (IPTR
)horiz
, 3, MUIM_NoNotifySet
, MUIA_Prop_Entries
, MUIV_TriggerValue
);
2673 DoMethod(texticonlist
, MUIM_Notify
, MUIA_TextIconList_Height
, MUIV_EveryTime
, (IPTR
)vert
, 3, MUIM_NoNotifySet
, MUIA_Prop_Entries
, MUIV_TriggerValue
);
2674 DoMethod(texticonlist
, MUIM_Notify
, MUIA_TextIconList_VisWidth
, MUIV_EveryTime
, (IPTR
)horiz
, 3, MUIM_NoNotifySet
, MUIA_Prop_Visible
, MUIV_TriggerValue
);
2675 DoMethod(texticonlist
, MUIM_Notify
, MUIA_TextIconList_VisHeight
, MUIV_EveryTime
, (IPTR
)vert
, 3, MUIM_NoNotifySet
, MUIA_Prop_Visible
, MUIV_TriggerValue
);
2681 IPTR
TextIconListview__OM_DISPOSE(struct IClass
*cl
, Object
*obj
, Msg msg
)
2683 //struct TextIconListview_DATA *data = INST_DATA(cl, obj);
2685 return DoSuperMethodA(cl
,obj
,msg
);
2688 IPTR
TextIconListview__MUIM_Show(struct IClass
*cl
, Object
*obj
, struct MUIP_Show
*msg
)
2690 struct TextIconListview_DATA
*data
= INST_DATA(cl
, obj
);
2691 IPTR top
,left
,width
,height
,viswidth
,visheight
;
2693 get(data
->texticonlist
, MUIA_TextIconList_Left
, &left
);
2694 get(data
->texticonlist
, MUIA_TextIconList_Top
, &top
);
2695 get(data
->texticonlist
, MUIA_TextIconList_Width
, &width
);
2696 get(data
->texticonlist
, MUIA_TextIconList_Height
, &height
);
2697 get(data
->texticonlist
, MUIA_TextIconList_VisWidth
, &viswidth
);
2698 get(data
->texticonlist
, MUIA_TextIconList_VisHeight
, &visheight
);
2700 SetAttrs(data
->horiz
, MUIA_Prop_First
, left
,
2701 MUIA_Prop_Entries
, width
,
2702 MUIA_Prop_Visible
, viswidth
,
2706 SetAttrs(data
->vert
, MUIA_Prop_First
, top
,
2707 MUIA_Prop_Entries
, height
,
2708 MUIA_Prop_Visible
, visheight
,
2711 return DoSuperMethodA(cl
,obj
,(Msg
)msg
);
2714 BOOPSI_DISPATCHER(IPTR
,TextIconListview_Dispatcher
, cl
, obj
, msg
)
2716 switch (msg
->MethodID
)
2718 case OM_NEW
: return TextIconListview__OM_NEW(cl
, obj
, (struct opSet
*) msg
);
2719 case OM_DISPOSE
: return TextIconListview__OM_DISPOSE(cl
, obj
, msg
);
2720 case MUIM_Show
: return TextIconListview__MUIM_Show(cl
, obj
, (struct MUIP_Show
*)msg
);
2723 return DoSuperMethodA(cl
, obj
, msg
);
2726 BOOPSI_DISPATCHER_END
2731 Object
*wnd
, *texticonlist
;
2736 MUIMasterBase
= (struct Library
*)OpenLibrary("muimaster.library",0);
2738 CL_TextIconListview
= MUI_CreateCustomClass(NULL
,MUIC_Group
,NULL
,sizeof(struct TextIconListview_DATA
), TextIconListview_Dispatcher
);
2739 CL_TextIconList
= MUI_CreateCustomClass(NULL
,MUIC_Area
,NULL
,sizeof(struct TextIconList_DATA
), TextIconList_Dispatcher
);
2741 app
= ApplicationObject
,
2742 SubWindow
, (IPTR
) (wnd
= WindowObject
,
2743 MUIA_Window_Title
, (IPTR
) "texticonlist",
2744 MUIA_Window_Activate
, TRUE
,
2746 WindowContents
, (IPTR
) VGroup
,
2747 MUIA_Background
, MUII_GroupBack
,
2749 Child
, (IPTR
) IconListviewObject
,
2750 MUIA_IconListview_IconList
, (IPTR
) (iconlist
= IconDrawerListObject
,
2752 MUIA_IconDrawerList_Drawer
, (IPTR
) "C:",
2756 Child
, (IPTR
) TextIconListviewObject
,
2757 // MUIA_TextIconListview_UseWinBorder, TRUE,
2758 MUIA_TextIconListview_TextIconList
, (IPTR
) (texticonlist
= TextIconListObject
,
2765 Child, (IPTR) (texticonlist = TextIconListObject, InputListFrame, End),
2777 wnd
, MUIM_Notify
, MUIA_Window_CloseRequest
, TRUE
, (IPTR
) app
,
2778 2, MUIM_Application_ReturnID
, MUIV_Application_ReturnID_Quit
2782 BPTR lock
= Lock("C:", SHARED_LOCK
);
2786 struct FileInfoBlock
*fib
= AllocDosObject(DOS_FIB
, NULL
);
2789 if (Examine(lock
, fib
))
2791 while(ExNext(lock
, fib
))
2793 DoMethod(texticonlist
, MUIM_TextIconList_Add
, (IPTR
) fib
);
2797 FreeDosObject(DOS_FIB
, fib
);
2804 set(wnd
,MUIA_Window_Open
,TRUE
);
2806 set(iconlist
, MUIA_IconDrawerList_Drawer
, "C:");
2809 while (DoMethod(app
, MUIM_Application_NewInput
, (IPTR
) &sigs
) != MUIV_Application_ReturnID_Quit
)
2813 sigs
= Wait(sigs
| SIGBREAKF_CTRL_C
| SIGBREAKF_CTRL_D
);
2814 if (sigs
& SIGBREAKF_CTRL_C
) break;
2815 if (sigs
& SIGBREAKF_CTRL_D
) break;
2819 MUI_DisposeObject(app
);
2822 MUI_DeleteCustomClass(CL_TextIconList
);
2823 MUI_DeleteCustomClass(CL_TextIconListview
);
2825 CloseLibrary(MUIMasterBase
);