2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
6 #include <proto/alib.h>
7 #include <proto/exec.h>
9 #include <proto/utility.h>
10 #include <proto/intuition.h>
11 #include <proto/graphics.h>
12 #include <proto/cybergraphics.h>
13 #include <proto/layers.h>
14 #include <exec/memory.h>
15 #include <intuition/screens.h>
16 #include <intuition/icclass.h>
17 #include <intuition/cghooks.h>
18 #include <intuition/imageclass.h>
19 #include <intuition/gadgetclass.h>
20 #include <graphics/gfx.h>
21 #include <cybergraphx/cybergraphics.h>
25 #include "asl_intern.h"
31 #include <aros/debug.h>
33 #define CLASS_ASLBASE ((struct AslBase_intern *)cl->cl_UserData)
34 #define HOOK_ASLBASE ((struct AslBase_intern *)hook->h_Data)
36 #define AslBase CLASS_ASLBASE
38 /***********************************************************************************/
41 #define AslBase HOOK_ASLBASE
43 /************************
44 ** ASLLVRenderHook() **
45 ************************/
46 AROS_UFH3(IPTR
, ASLLVRenderHook
,
47 AROS_UFHA(struct Hook
*, hook
, A0
),
48 AROS_UFHA(struct Node
*, node
, A2
),
49 AROS_UFHA(struct ASLLVDrawMsg
*, msg
, A1
)
56 if (msg
->lvdm_MethodID
== LV_DRAW
)
58 struct DrawInfo
*dri
= msg
->lvdm_DrawInfo
;
59 struct RastPort
*rp
= msg
->lvdm_RastPort
;
61 WORD min_x
= msg
->lvdm_Bounds
.MinX
;
62 WORD min_y
= msg
->lvdm_Bounds
.MinY
;
63 WORD max_x
= msg
->lvdm_Bounds
.MaxX
;
64 WORD max_y
= msg
->lvdm_Bounds
.MaxY
;
66 UWORD erasepen
= BACKGROUNDPEN
;
67 UWORD textpen
= TEXTPEN
;
72 switch (msg
->lvdm_State
)
76 textpen
= FILLTEXTPEN
;
85 SetAPen(rp
, dri
->dri_Pens
[erasepen
]);
86 RectFill(rp
, min_x
, min_y
, max_x
, max_y
);
88 if (node
) if (node
->ln_Name
)
90 UWORD len
= strlen(node
->ln_Name
);
98 max_x
- min_x
+ 1 - BORDERLVITEMSPACINGX
* 2,
101 if (numfit
< len
) numfit
++;
103 SetAPen(rp
, dri
->dri_Pens
[textpen
]);
106 Move(rp
, min_x
+ BORDERLVITEMSPACINGX
,
107 min_y
+ BORDERLVITEMSPACINGY
+ rp
->Font
->tf_Baseline
);
108 Text(rp
, node
->ln_Name
, numfit
);
118 retval
= ASLLVCB_UNKNOWN
;
126 /***********************************************************************************/
129 #define AslBase CLASS_ASLBASE
131 static struct Node
*findnode(Class
*cl
, Object
*o
, WORD which
)
133 struct AslListViewData
*data
;
134 struct Node
*node
= NULL
;
136 data
= INST_DATA(cl
, o
);
140 if ((which
< data
->total
) && (which
>= 0)) node
= data
->nodetable
[which
];
142 node
= FindListNode(data
->labels
, which
);
148 /***********************************************************************************/
150 static void makenodetable(Class
*cl
, Object
*o
)
152 struct AslListViewData
*data
;
154 data
= INST_DATA(cl
, o
);
158 FreeVec(data
->nodetable
);
159 data
->nodetable
= NULL
;
162 /* data->total must be correct here */
166 if ((data
->nodetable
= AllocVec(sizeof(struct Node
*) * data
->total
, MEMF_PUBLIC
)))
168 struct Node
*node
, **nodeptr
= data
->nodetable
;
169 ForeachNode(data
->labels
, node
)
177 /***********************************************************************************/
179 static void renderitem(Class
*cl
, Object
*o
, struct Node
*node
, WORD liney
, struct RastPort
*rp
)
181 struct AslListViewData
*data
;
182 struct ASLLVDrawMsg msg
;
184 data
= INST_DATA(cl
, o
);
186 if (data
->font
) SetFont(rp
, data
->font
);
188 msg
.lvdm_MethodID
= ASLLV_DRAW
;
189 msg
.lvdm_RastPort
= rp
;
190 msg
.lvdm_DrawInfo
= data
->ld
->ld_Dri
;
191 msg
.lvdm_Bounds
.MinX
= data
->minx
+ BORDERLVSPACINGX
;
192 msg
.lvdm_Bounds
.MaxX
= data
->maxx
- BORDERLVSPACINGX
;
193 msg
.lvdm_Bounds
.MinY
= data
->miny
+ BORDERLVSPACINGY
+ liney
* data
->lineheight
-
194 (data
->toppixel
% data
->lineheight
);
195 msg
.lvdm_Bounds
.MaxY
= msg
.lvdm_Bounds
.MinY
+ data
->lineheight
- 1;
196 msg
.lvdm_State
= node
? (IS_SELECTED(node
) ? ASLLVR_SELECTED
: ASLLVR_NORMAL
) : ASLLVR_NORMAL
;
198 if (data
->renderrect
)
200 if (!AndRectRect(data
->renderrect
, &msg
.lvdm_Bounds
, NULL
)) return;
203 CallHookPkt(data
->renderhook
, node
, &msg
);
206 /***********************************************************************************/
208 static void renderallitems(Class
*cl
, Object
*o
, struct RastPort
*rp
)
210 struct AslListViewData
*data
;
214 data
= INST_DATA(cl
, o
);
216 node
= findnode(cl
, o
, data
->top
);
218 visible
= data
->visiblepixels
+ data
->lineheight
- 1 + (data
->toppixel
% data
->lineheight
);
219 visible
/= data
->lineheight
;
221 //kprintf("renderallitem: lineheight %d visible %d visiblepixels %d toppixel %d\n",
222 // data->lineheight, visible, data->visiblepixels, data->toppixel);
224 for(i
= 0; i
< visible
; i
++)
226 if (node
) if (!node
->ln_Succ
) node
= NULL
;
228 renderitem(cl
, o
, node
, i
, rp
);
230 if (node
) node
= node
->ln_Succ
;
234 /***********************************************************************************/
236 static void rendersingleitem(Class
*cl
, Object
*o
, struct GadgetInfo
*gi
, WORD which
)
238 struct AslListViewData
*data
;
240 data
= INST_DATA(cl
, o
);
243 if (which
< data
->top
) return;
244 if (which
>= data
->total
) return;
246 if ((which
- data
->top
) <
247 (data
->visiblepixels
+ data
->lineheight
- 1 + (data
->toppixel
% data
->lineheight
)) / data
->lineheight
)
251 if ((rp
= ObtainGIRPort(gi
)))
255 data
->rendersingleitem
= which
;
257 gpr
.MethodID
= GM_RENDER
;
260 gpr
.gpr_Redraw
= GREDRAW_UPDATE
;
262 DoMethodA(o
, (Msg
)&gpr
);
266 } /* if ((rp = ObtainGIRPort(msg->gpi_GInfo))) */
268 } /* if ((which >= data->top) && ... */
272 /***********************************************************************************/
274 static WORD
mouseitem(Class
*cl
, Object
*o
, WORD mousex
, WORD mousey
)
276 struct AslListViewData
*data
;
279 data
= INST_DATA(cl
, o
);
281 if (mousey
< BORDERLVSPACINGY
)
285 else if (mousey
> data
->maxy
- data
->miny
- BORDERLVSPACINGY
)
289 else if (mousex
< BORDERLVSPACINGX
)
293 else if (mousex
> data
->maxx
- data
->minx
- BORDERLVSPACINGX
)
299 LONG i
= (mousey
- BORDERLVSPACINGY
+ (data
->toppixel
% data
->lineheight
)) / data
->lineheight
;
302 visible
= data
->visiblepixels
+ data
->lineheight
- 1 + (data
->toppixel
% data
->lineheight
);
303 visible
/= data
->lineheight
;
311 if ((node
= findnode(cl
, o
, i
)))
318 //kprintf("mouseitem : %d\n", result);
323 /***********************************************************************************/
325 static void notifyall(Class
*cl
, Object
*o
, struct GadgetInfo
*gi
, STACKULONG flags
)
327 struct AslListViewData
*data
= INST_DATA(cl
, o
);
328 struct TagItem tags
[] =
330 {ASLLV_Top
, data
->top
},
331 {ASLLV_TopPixel
, data
->toppixel
},
332 {ASLLV_Total
, data
->total
},
333 {ASLLV_TotalPixels
, data
->totalpixels
},
334 {ASLLV_Visible
, data
->visible
},
335 {ASLLV_VisiblePixels
, data
->visiblepixels
},
336 {ASLLV_DeltaFactor
, data
->lineheight
},
341 opu
.MethodID
= OM_NOTIFY
;
342 opu
.opu_AttrList
= tags
;
344 opu
.opu_Flags
= flags
;
346 D(bug("asl listview notify all: top = %d (%d) total = %d (%d) visible = %d (%d)\n",
347 data
->top
, data
->toppixel
,
348 data
->total
, data
->totalpixels
,
349 data
->visible
, data
->visiblepixels
));
351 DoSuperMethodA(cl
, o
, (Msg
)&opu
);
355 /***********************************************************************************/
357 static void notifytop(Class
*cl
, Object
*o
, struct GadgetInfo
*gi
, STACKULONG flags
)
359 struct AslListViewData
*data
= INST_DATA(cl
, o
);
360 struct TagItem tags
[] =
362 {ASLLV_Top
, data
->top
},
363 {ASLLV_TopPixel
, data
->toppixel
},
368 opu
.MethodID
= OM_NOTIFY
;
369 opu
.opu_AttrList
= tags
;
371 opu
.opu_Flags
= flags
;
373 D(bug("asl listview notify top: top = %d\n", data
->top
));
375 DoSuperMethodA(cl
, o
, (Msg
)&opu
);
379 /***********************************************************************************/
381 IPTR
AslListView__OM_SET(Class
* cl
, Object
* o
, struct opSet
* msg
)
383 struct AslListViewData
*data
= INST_DATA(cl
, o
);
384 struct TagItem
*tag
, *tstate
= msg
->ops_AttrList
;
386 BOOL redraw
= FALSE
, notify_all
= FALSE
, notify_top
= FALSE
;
389 retval
= DoSuperMethod(cl
, o
, OM_SET
, (IPTR
) msg
->ops_AttrList
, (IPTR
) msg
->ops_GInfo
);
391 while((tag
= NextTagItem(&tstate
)))
393 tidata
= tag
->ti_Data
;
398 tidata
*= data
->lineheight
;
403 if (newtop
+ data
->visiblepixels
> data
->totalpixels
)
405 newtop
= data
->totalpixels
- data
->visiblepixels
;
407 if (newtop
< 0) newtop
= 0;
409 if (newtop
!= data
->toppixel
)
411 data
->scroll
= redraw
? 0 : newtop
- data
->toppixel
;
412 data
->top
= newtop
/ data
->lineheight
;
413 data
->toppixel
= newtop
;
419 case ASLLV_MakeVisible
:
420 newtop
= (LONG
)tidata
* data
->lineheight
;
426 else if (newtop
>= data
->totalpixels
)
428 newtop
= data
->totalpixels
- 1;
429 if (newtop
< 0) newtop
= 0;
432 /* No need to do anything if it is already visible */
434 if (newtop
< data
->toppixel
)
436 /* new_top already okay */
438 data
->scroll
= redraw
? 0 : newtop
- data
->toppixel
;
439 data
->top
= newtop
/ data
->lineheight
;
440 data
->toppixel
= newtop
;
444 else if (newtop
> data
->toppixel
+ data
->visiblepixels
- data
->lineheight
)
446 newtop
-= (data
->visiblepixels
- data
->lineheight
);
447 data
->scroll
= redraw
? 0 : newtop
- data
->toppixel
;
448 data
->top
= newtop
/ data
->lineheight
;
449 data
->toppixel
= newtop
;
459 WORD old_active
= data
->active
;
461 data
->active
= (WORD
)tidata
;
463 if (data
->domultiselect
)
465 ForeachNode(data
->labels
, node
)
467 if (IS_MULTISEL(node
) && IS_SELECTED(node
) && (n
!= data
->active
))
469 MARK_UNSELECTED(node
);
470 rendersingleitem(cl
, o
, msg
->ops_GInfo
, n
);
475 if ((node
= findnode(cl
, o
, old_active
)))
477 MARK_UNSELECTED(node
);
478 rendersingleitem(cl
, o
, msg
->ops_GInfo
, old_active
);
482 if ((node
= findnode(cl
, o
, data
->active
)))
484 if (!data
->domultiselect
|| IS_MULTISEL(node
))
487 rendersingleitem(cl
, o
, msg
->ops_GInfo
, data
->active
);
495 data
->labels
= tidata
? (struct List
*)tidata
: &data
->emptylist
;
496 data
->total
= CountNodes(data
->labels
, 0);
497 data
->totalpixels
= data
->total
* data
->lineheight
;
502 data
->visible
= data
->total
;
503 data
->visiblepixels
= data
->visible
* data
->lineheight
;
506 if (data
->toppixel
+ data
->visiblepixels
> data
->totalpixels
)
508 data
->toppixel
= data
->totalpixels
- data
->visiblepixels
;
510 if (data
->toppixel
< 0) data
->toppixel
= 0;
511 data
->top
= data
->toppixel
/ data
->lineheight
;
515 data
->visiblepixels
= data
->totalpixels
;
516 data
->visible
= data
->total
;
519 makenodetable(cl
, o
);
525 case ASLLV_DoMultiSelect
:
526 data
->domultiselect
= tidata
? TRUE
: FALSE
;
529 case ASLLV_DoSaveMode
:
530 data
->dosavemode
= tidata
? TRUE
: FALSE
;
534 data
->readonly
= tidata
? TRUE
: FALSE
;
538 data
->font
= (struct TextFont
*)tidata
;
541 } /* switch(tag->ti_Tag) */
543 } /* while((tag = NextTagItem(&tsate))) */
550 if ((rp
= ObtainGIRPort(msg
->ops_GInfo
)))
552 gpr
.MethodID
= GM_RENDER
;
553 gpr
.gpr_GInfo
= msg
->ops_GInfo
;
555 gpr
.gpr_Redraw
= GREDRAW_UPDATE
;
557 DoMethodA(o
, (Msg
)&gpr
);
565 notifyall(cl
, o
, msg
->ops_GInfo
, 0);
569 notifytop(cl
, o
, msg
->ops_GInfo
, 0);
575 /***********************************************************************************/
577 IPTR
AslListView__OM_NEW(Class
* cl
, Object
* o
, struct opSet
* msg
)
579 struct AslListViewData
*data
;
580 struct TagItem fitags
[] =
582 {IA_FrameType
, FRAME_BUTTON
},
583 {IA_EdgesOnly
, TRUE
},
587 struct Gadget
*g
= (struct Gadget
*)DoSuperMethodA(cl
, o
, (Msg
)msg
);
590 data
= INST_DATA(cl
, g
);
592 /* We want to get a GM_LAYOUT message, no matter if gadget is GFLG_RELRIGHT/RELBOTTOM/
593 RELWIDTH/RELHEIGHT or not */
594 g
->Flags
|= GFLG_RELSPECIAL
;
596 data
->frame
= NewObjectA(NULL
, FRAMEICLASS
, fitags
);
597 data
->ld
= (struct LayoutData
*)GetTagData(GA_UserData
, 0, msg
->ops_AttrList
);
599 if (!data
->ld
|| !data
->frame
)
601 CoerceMethod(cl
, (Object
*)g
, OM_DISPOSE
);
606 data
->itemheight
= GetTagData(ASLLV_ItemHeight
, data
->ld
->ld_Font
->tf_YSize
, msg
->ops_AttrList
);
607 data
->spacing
= GetTagData(ASLLV_Spacing
, BORDERLVITEMSPACINGY
* 2, msg
->ops_AttrList
);
609 data
->lineheight
= data
->itemheight
+ data
->spacing
;
611 NEWLIST(&data
->emptylist
);
612 data
->labels
= &data
->emptylist
;
614 data
->rendersingleitem
= -1;
616 data
->renderhook
= (struct Hook
*)GetTagData(ASLLV_CallBack
, 0, msg
->ops_AttrList
);
617 data
->default_renderhook
.h_Entry
= (APTR
) AROS_ASMSYMNAME(ASLLVRenderHook
);
618 data
->default_renderhook
.h_SubEntry
= NULL
;
619 data
->default_renderhook
.h_Data
= (APTR
)AslBase
;
620 if (!data
->renderhook
) data
->renderhook
= &data
->default_renderhook
;
622 AslListView__OM_SET(cl
, (Object
*)g
, msg
);
629 /***********************************************************************************/
631 IPTR
AslListView__OM_GET(Class
* cl
, Object
* o
, struct opGet
*msg
)
633 struct AslListViewData
*data
;
636 data
= INST_DATA(cl
, o
);
638 switch(msg
->opg_AttrID
)
641 *msg
->opg_Storage
= data
->active
;
645 *msg
->opg_Storage
= data
->top
;
649 *msg
->opg_Storage
= data
->toppixel
;
653 *msg
->opg_Storage
= data
->total
;
656 case ASLLV_TotalPixels
:
657 *msg
->opg_Storage
= data
->totalpixels
;
661 *msg
->opg_Storage
= data
->visible
;
664 case ASLLV_VisiblePixels
:
665 *msg
->opg_Storage
= data
->visiblepixels
;
669 retval
= DoSuperMethodA(cl
, o
, (Msg
)msg
);
672 } /* switch(msg->opg_AttrID) */
677 /***********************************************************************************/
679 IPTR
AslListView__OM_DISPOSE(Class
* cl
, Object
* o
, Msg msg
)
681 struct AslListViewData
*data
;
684 data
= INST_DATA(cl
, o
);
685 if (data
->frame
) DisposeObject(data
->frame
);
686 if (data
->nodetable
) FreeVec(data
->nodetable
);
687 retval
= DoSuperMethodA(cl
, o
, msg
);
692 /***********************************************************************************/
694 IPTR
AslListView__GM_GOACTIVE(Class
*cl
, Object
*o
, struct gpInput
*msg
)
696 struct AslListViewData
*data
;
698 IPTR retval
= GMR_NOREUSE
;
700 data
= INST_DATA(cl
, o
);
701 if ((data
->total
< 1) || (data
->readonly
)) return retval
;
703 i
= mouseitem(cl
, o
, msg
->gpi_Mouse
.X
, msg
->gpi_Mouse
.Y
);
709 if ((node
= findnode(cl
, o
, i
)))
713 CurrentTime(&sec
, µ
);
715 if (data
->domultiselect
&& IS_MULTISEL(node
) &&
716 (msg
->gpi_IEvent
->ie_Qualifier
& (IEQUALIFIER_LSHIFT
| IEQUALIFIER_RSHIFT
)))
718 data
->multiselecting
= TRUE
;
722 data
->multiselecting
= FALSE
;
724 if (data
->domultiselect
)
729 ForeachNode(data
->labels
, node
)
731 if (IS_MULTISEL(node
) && IS_SELECTED(node
) && (n
!= data
->active
))
733 MARK_UNSELECTED(node
);
734 rendersingleitem(cl
, o
, msg
->gpi_GInfo
, n
);
741 data
->doubleclicked
= FALSE
;
742 if (data
->active
== i
)
744 if (DoubleClick(data
->clicksec
, data
->clickmicro
, sec
, micro
))
746 data
->doubleclicked
= TRUE
;
751 if (!data
->multiselecting
&& (data
->active
>= 0))
753 struct Node
*oldnode
= findnode(cl
, o
, data
->active
);
755 MARK_UNSELECTED(oldnode
);
756 rendersingleitem(cl
, o
, msg
->gpi_GInfo
, data
->active
);
760 rendersingleitem(cl
, o
, msg
->gpi_GInfo
, i
);
764 } /* if (data->active != i) */
766 data
->clicksec
= sec
;
767 data
->clickmicro
= micro
;
769 retval
= GMR_MEACTIVE
;
771 } /* if ((node = findnode(cl, o, i))) */
778 /***********************************************************************************/
780 IPTR
AslListView__GM_HANDLEINPUT(Class
*cl
, Object
*o
, struct gpInput
*msg
)
782 struct AslListViewData
*data
;
784 IPTR retval
= GMR_MEACTIVE
;
786 data
= INST_DATA(cl
, o
);
788 switch(msg
->gpi_IEvent
->ie_Class
)
791 code
= IECODE_NOBUTTON
;
794 case IECLASS_RAWMOUSE
:
795 code
= msg
->gpi_IEvent
->ie_Code
;
800 *msg
->gpi_Termination
= data
->doubleclicked
;
801 retval
= GMR_VERIFY
| GMR_NOREUSE
;
804 case IECODE_NOBUTTON
:
806 WORD n
= mouseitem(cl
, o
, msg
->gpi_Mouse
.X
, msg
->gpi_Mouse
.Y
);
808 if ((n
== -1) && (data
->active
> 0)) n
= data
->active
- 1;
809 if ((n
== -2) && (data
->active
< data
->total
- 1)) n
= data
->active
+ 1;
811 if ((n
>= 0) && (n
!= data
->active
))
813 struct Node
*old
= findnode(cl
, o
, data
->active
);
814 struct Node
*new = findnode(cl
, o
, n
);
816 if (data
->multiselecting
&& new)
818 if (!IS_MULTISEL(new)) new = NULL
;
823 if (!data
->multiselecting
)
825 MARK_UNSELECTED(old
);
826 rendersingleitem(cl
, o
, msg
->gpi_GInfo
, data
->active
);
830 rendersingleitem(cl
, o
, msg
->gpi_GInfo
, n
);
835 if ((n
* data
->lineheight
< data
->toppixel
) ||
836 (n
* data
->lineheight
> data
->toppixel
+ data
->visiblepixels
- data
->lineheight
))
840 if (n
* data
->lineheight
< data
->toppixel
)
842 LONG newtop
= n
* data
->lineheight
;
843 data
->scroll
= newtop
- data
->toppixel
;
844 data
->toppixel
= newtop
;
845 data
->top
= newtop
/ data
->lineheight
;
849 LONG newtop
= n
* data
->lineheight
- (data
->visiblepixels
- data
->lineheight
);
851 data
->scroll
= newtop
- data
->toppixel
;
852 data
->toppixel
= newtop
;
853 data
->top
= newtop
/ data
->lineheight
;
856 if ((rp
= ObtainGIRPort(msg
->gpi_GInfo
)))
860 gpr
.MethodID
= GM_RENDER
;
861 gpr
.gpr_GInfo
= msg
->gpi_GInfo
;
863 gpr
.gpr_Redraw
= GREDRAW_UPDATE
;
865 DoMethodA(o
, (Msg
)&gpr
);
870 notifytop(cl
, o
, msg
->gpi_GInfo
, OPUF_INTERIM
);
872 } /* if ((n < data->top) || (n >= data->top + data->visible)) */
874 } /* if ((n >= 0) && (n != data->active)) */
878 } /* switch(msg->gpi_IEvent->ie_Code) */
881 } /* switch(msg->gpi_IEvent->ie_Class) */
886 /***********************************************************************************/
888 IPTR
AslListView__GM_LAYOUT(Class
*cl
, struct Gadget
*g
, struct gpLayout
*msg
)
890 struct AslListViewData
*data
;
893 data
= INST_DATA(cl
, g
);
897 LONG newtop
= data
->toppixel
;
898 LONG newvisible
= data
->visiblepixels
;
900 getgadgetcoords(g
, msg
->gpl_GInfo
, &data
->minx
, &data
->miny
, &data
->width
, &data
->height
);
902 data
->maxx
= data
->minx
+ data
->width
- 1;
903 data
->maxy
= data
->miny
+ data
->height
- 1;
905 newvisible
= (data
->height
- BORDERLVSPACINGY
* 2);
906 if (newtop
+ newvisible
> data
->totalpixels
)
908 newtop
= data
->totalpixels
- newvisible
;
910 if (newtop
< 0) newtop
= 0;
912 if ((newtop
!= data
->toppixel
) || (newvisible
!= data
->visiblepixels
) || (!data
->layouted
))
914 data
->toppixel
= newtop
;
915 data
->top
= newtop
/ data
->lineheight
;
916 data
->visiblepixels
= newvisible
;
917 data
->visible
= newvisible
/ data
->lineheight
;
919 notifyall(cl
, (Object
*)g
, msg
->gpl_GInfo
, 0);
922 data
->layouted
= TRUE
;
930 /***********************************************************************************/
932 IPTR
AslListView__GM_RENDER(Class
*cl
, Object
*o
, struct gpRender
*msg
)
934 struct AslListViewData
*data
;
935 struct Region
*clip
, *oldclip
= NULL
;
936 BOOL updating
= FALSE
;
939 data
= INST_DATA(cl
, o
);
941 if (msg
->gpr_Redraw
== GREDRAW_REDRAW
)
943 struct TagItem im_tags
[] =
945 {IA_Width
, data
->width
},
946 {IA_Height
, data
->height
},
947 {IA_Recessed
, data
->readonly
},
951 SetAttrsA(data
->frame
, im_tags
);
953 DrawImageState(msg
->gpr_RPort
,
954 (struct Image
*)data
->frame
,
958 msg
->gpr_GInfo
->gi_DrInfo
);
961 struct IBox ibox
, fbox
;
963 fbox
.Left
= data
->minx
;
964 fbox
.Top
= data
->miny
;
965 fbox
.Width
= data
->maxx
- data
->minx
+ 1;
966 fbox
.Height
= data
->maxy
- data
->miny
+ 1;
968 ibox
.Left
= data
->minx
+ BORDERLVSPACINGX
;
969 ibox
.Top
= data
->miny
+ BORDERLVSPACINGY
;
970 ibox
.Width
= (data
->maxx
- data
->minx
+ 1) - BORDERLVSPACINGX
* 2;
971 ibox
.Height
= (data
->maxy
- data
->miny
+ 1) - BORDERLVSPACINGY
* 2;
973 PaintInnerFrame(msg
->gpr_RPort
,
974 msg
->gpr_GInfo
->gi_DrInfo
,
978 msg
->gpr_GInfo
->gi_DrInfo
->dri_Pens
[data
->dosavemode
? TEXTPEN
: BACKGROUNDPEN
],
987 if ((clip
= NewRectRegion(data
->minx
+ BORDERLVSPACINGX
,
988 data
->miny
+ BORDERLVSPACINGY
,
989 data
->maxx
- BORDERLVSPACINGX
,
990 data
->maxy
- BORDERLVSPACINGY
)))
992 struct Layer
*lay
= msg
->gpr_GInfo
->gi_Layer
;
994 updating
= (lay
->Flags
& LAYERUPDATING
) != 0;
996 if (updating
) EndUpdate(lay
, FALSE
);
997 oldclip
= InstallClipRegion(lay
, clip
);
998 if (updating
) BeginUpdate(lay
);
1001 if (msg
->gpr_Redraw
== GREDRAW_REDRAW
)
1003 renderallitems(cl
, o
, msg
->gpr_RPort
);
1005 } /* if (msg->gpr_Redraw == GREDRAW_REDRAW) */
1006 else if (msg
->gpr_Redraw
== GREDRAW_UPDATE
)
1008 if (data
->rendersingleitem
== -1)
1010 WORD abs_scroll
= (data
->scroll
>= 0) ? data
->scroll
: -data
->scroll
;
1012 if ((abs_scroll
== 0) || (abs_scroll
> data
->visiblepixels
/ 2))
1014 renderallitems(cl
, o
, msg
->gpr_RPort
);
1018 struct Rectangle rect
;
1019 WORD scrollx1
= data
->minx
+ BORDERLVSPACINGX
;
1020 WORD scrolly1
= data
->miny
+ BORDERLVSPACINGY
;
1021 WORD scrollx2
= data
->maxx
- BORDERLVSPACINGX
;
1022 WORD scrolly2
= data
->maxy
- BORDERLVSPACINGY
;
1023 BOOL mustrefresh
, update
;
1025 ScrollRaster(msg
->gpr_RPort
, 0, data
->scroll
,
1026 scrollx1
, scrolly1
, scrollx2
, scrolly2
);
1028 mustrefresh
= (msg
->gpr_GInfo
->gi_Layer
->Flags
& LAYERREFRESH
) != 0;
1030 rect
.MinX
= scrollx1
;
1031 rect
.MaxX
= scrollx2
;
1033 if (data
->scroll
>= 0)
1035 rect
.MinY
= scrolly2
- abs_scroll
;
1036 rect
.MaxY
= scrolly2
;
1040 rect
.MinY
= scrolly1
;
1041 rect
.MaxY
= scrolly1
+ abs_scroll
;
1044 data
->renderrect
= &rect
;
1045 renderallitems(cl
, o
, msg
->gpr_RPort
);
1046 data
->renderrect
= NULL
;
1048 /* the LAYERUPDATING check should not be necessary,
1049 as then we should always have a GREDRAW_REDRAW,
1050 while here we are in GREDRAW_UPDATE. But just
1053 if (mustrefresh
&& !(msg
->gpr_GInfo
->gi_Layer
->Flags
& LAYERUPDATING
))
1055 if(!(update
= BeginUpdate(msg
->gpr_GInfo
->gi_Layer
)))
1057 EndUpdate(msg
->gpr_GInfo
->gi_Layer
, FALSE
);
1060 renderallitems(cl
, o
, msg
->gpr_RPort
);
1062 if(update
) EndUpdate(msg
->gpr_GInfo
->gi_Layer
, TRUE
);
1069 if (data
->rendersingleitem
>= data
->top
)
1071 struct Node
*node
= findnode(cl
, o
, data
->rendersingleitem
);
1073 renderitem(cl
, o
, node
, data
->rendersingleitem
- data
->top
, msg
->gpr_RPort
);
1078 data
->rendersingleitem
= -1;
1080 } /* if (msg->gpr_Redraw == GREDRAW_UPDATE) */
1084 struct Layer
*lay
= msg
->gpr_GInfo
->gi_Layer
;
1086 if (updating
) EndUpdate(lay
, FALSE
);
1087 InstallClipRegion(lay
, oldclip
);
1088 if (updating
) BeginUpdate(lay
);
1090 DisposeRegion(clip
);
1096 /***********************************************************************************/