2 Copyright © 1995-2005, The AROS Development Team. All rights reserved.
6 #include <proto/exec.h>
8 #include <proto/utility.h>
9 #include <proto/intuition.h>
10 #include <proto/graphics.h>
11 #include <proto/cybergraphics.h>
12 #include <proto/layers.h>
13 #include <exec/memory.h>
14 #include <intuition/screens.h>
15 #include <intuition/icclass.h>
16 #include <intuition/cghooks.h>
17 #include <intuition/imageclass.h>
18 #include <intuition/gadgetclass.h>
19 #include <graphics/gfx.h>
20 #include <cybergraphx/cybergraphics.h>
24 #include "asl_intern.h"
30 #include <aros/debug.h>
32 #define CLASS_ASLBASE ((struct AslBase_intern *)cl->cl_UserData)
33 #define HOOK_ASLBASE ((struct AslBase_intern *)hook->h_Data)
35 #define AslBase CLASS_ASLBASE
37 /***********************************************************************************/
40 #define AslBase HOOK_ASLBASE
42 /************************
43 ** ASLLVRenderHook() **
44 ************************/
45 AROS_UFH3(IPTR
, ASLLVRenderHook
,
46 AROS_UFHA(struct Hook
*, hook
, A0
),
47 AROS_UFHA(struct Node
*, node
, A2
),
48 AROS_UFHA(struct ASLLVDrawMsg
*, msg
, A1
)
55 if (msg
->lvdm_MethodID
== LV_DRAW
)
57 struct DrawInfo
*dri
= msg
->lvdm_DrawInfo
;
58 struct RastPort
*rp
= msg
->lvdm_RastPort
;
60 WORD min_x
= msg
->lvdm_Bounds
.MinX
;
61 WORD min_y
= msg
->lvdm_Bounds
.MinY
;
62 WORD max_x
= msg
->lvdm_Bounds
.MaxX
;
63 WORD max_y
= msg
->lvdm_Bounds
.MaxY
;
65 UWORD erasepen
= BACKGROUNDPEN
;
66 UWORD textpen
= TEXTPEN
;
71 switch (msg
->lvdm_State
)
75 textpen
= FILLTEXTPEN
;
84 SetAPen(rp
, dri
->dri_Pens
[erasepen
]);
85 RectFill(rp
, min_x
, min_y
, max_x
, max_y
);
87 if (node
) if (node
->ln_Name
)
89 UWORD len
= strlen(node
->ln_Name
);
97 max_x
- min_x
+ 1 - BORDERLVITEMSPACINGX
* 2,
100 if (numfit
< len
) numfit
++;
102 SetAPen(rp
, dri
->dri_Pens
[textpen
]);
105 Move(rp
, min_x
+ BORDERLVITEMSPACINGX
,
106 min_y
+ BORDERLVITEMSPACINGY
+ rp
->Font
->tf_Baseline
);
107 Text(rp
, node
->ln_Name
, numfit
);
117 retval
= ASLLVCB_UNKNOWN
;
125 /***********************************************************************************/
128 #define AslBase CLASS_ASLBASE
130 static struct Node
*findnode(Class
*cl
, Object
*o
, WORD which
)
132 struct AslListViewData
*data
;
133 struct Node
*node
= NULL
;
135 data
= INST_DATA(cl
, o
);
139 if ((which
< data
->total
) && (which
>= 0)) node
= data
->nodetable
[which
];
141 node
= FindListNode(data
->labels
, which
);
147 /***********************************************************************************/
149 static void makenodetable(Class
*cl
, Object
*o
)
151 struct AslListViewData
*data
;
153 data
= INST_DATA(cl
, o
);
157 FreeVec(data
->nodetable
);
158 data
->nodetable
= NULL
;
161 /* data->total must be correct here */
165 if ((data
->nodetable
= AllocVec(sizeof(struct Node
*) * data
->total
, MEMF_PUBLIC
)))
167 struct Node
*node
, **nodeptr
= data
->nodetable
;
168 ForeachNode(data
->labels
, node
)
176 /***********************************************************************************/
178 static void renderitem(Class
*cl
, Object
*o
, struct Node
*node
, WORD liney
, struct RastPort
*rp
)
180 struct AslListViewData
*data
;
181 struct ASLLVDrawMsg msg
;
183 data
= INST_DATA(cl
, o
);
185 if (data
->font
) SetFont(rp
, data
->font
);
187 msg
.lvdm_MethodID
= ASLLV_DRAW
;
188 msg
.lvdm_RastPort
= rp
;
189 msg
.lvdm_DrawInfo
= data
->ld
->ld_Dri
;
190 msg
.lvdm_Bounds
.MinX
= data
->minx
+ BORDERLVSPACINGX
;
191 msg
.lvdm_Bounds
.MaxX
= data
->maxx
- BORDERLVSPACINGX
;
192 msg
.lvdm_Bounds
.MinY
= data
->miny
+ BORDERLVSPACINGY
+ liney
* data
->lineheight
-
193 (data
->toppixel
% data
->lineheight
);
194 msg
.lvdm_Bounds
.MaxY
= msg
.lvdm_Bounds
.MinY
+ data
->lineheight
- 1;
195 msg
.lvdm_State
= node
? (IS_SELECTED(node
) ? ASLLVR_SELECTED
: ASLLVR_NORMAL
) : ASLLVR_NORMAL
;
197 if (data
->renderrect
)
199 if (!AndRectRect(data
->renderrect
, &msg
.lvdm_Bounds
, NULL
)) return;
202 CallHookPkt(data
->renderhook
, node
, &msg
);
205 /***********************************************************************************/
207 static void renderallitems(Class
*cl
, Object
*o
, struct RastPort
*rp
)
209 struct AslListViewData
*data
;
213 data
= INST_DATA(cl
, o
);
215 node
= findnode(cl
, o
, data
->top
);
217 visible
= data
->visiblepixels
+ data
->lineheight
- 1 + (data
->toppixel
% data
->lineheight
);
218 visible
/= data
->lineheight
;
220 //kprintf("renderallitem: lineheight %d visible %d visiblepixels %d toppixel %d\n",
221 // data->lineheight, visible, data->visiblepixels, data->toppixel);
223 for(i
= 0; i
< visible
; i
++)
225 if (node
) if (!node
->ln_Succ
) node
= NULL
;
227 renderitem(cl
, o
, node
, i
, rp
);
229 if (node
) node
= node
->ln_Succ
;
233 /***********************************************************************************/
235 static void rendersingleitem(Class
*cl
, Object
*o
, struct GadgetInfo
*gi
, WORD which
)
237 struct AslListViewData
*data
;
239 data
= INST_DATA(cl
, o
);
242 if (which
< data
->top
) return;
243 if (which
>= data
->total
) return;
245 if ((which
- data
->top
) <
246 (data
->visiblepixels
+ data
->lineheight
- 1 + (data
->toppixel
% data
->lineheight
)) / data
->lineheight
)
251 node
= findnode(cl
, o
, which
);
253 if ((rp
= ObtainGIRPort(gi
)))
257 data
->rendersingleitem
= which
;
259 gpr
.MethodID
= GM_RENDER
;
262 gpr
.gpr_Redraw
= GREDRAW_UPDATE
;
264 DoMethodA(o
, (Msg
)&gpr
);
268 } /* if ((rp = ObtainGIRPort(msg->gpi_GInfo))) */
270 } /* if ((which >= data->top) && ... */
274 /***********************************************************************************/
276 static WORD
mouseitem(Class
*cl
, Object
*o
, WORD mousex
, WORD mousey
)
278 struct AslListViewData
*data
;
281 data
= INST_DATA(cl
, o
);
283 if (mousey
< BORDERLVSPACINGY
)
287 else if (mousey
> data
->maxy
- data
->miny
- BORDERLVSPACINGY
)
291 else if (mousex
< BORDERLVSPACINGX
)
295 else if (mousex
> data
->maxx
- data
->minx
- BORDERLVSPACINGX
)
301 LONG i
= (mousey
- BORDERLVSPACINGY
+ (data
->toppixel
% data
->lineheight
)) / data
->lineheight
;
304 visible
= data
->visiblepixels
+ data
->lineheight
- 1 + (data
->toppixel
% data
->lineheight
);
305 visible
/= data
->lineheight
;
313 if ((node
= findnode(cl
, o
, i
)))
320 //kprintf("mouseitem : %d\n", result);
325 /***********************************************************************************/
327 static void notifyall(Class
*cl
, Object
*o
, struct GadgetInfo
*gi
, STACKULONG flags
)
329 struct AslListViewData
*data
= INST_DATA(cl
, o
);
330 struct TagItem tags
[] =
332 {ASLLV_Top
, data
->top
},
333 {ASLLV_TopPixel
, data
->toppixel
},
334 {ASLLV_Total
, data
->total
},
335 {ASLLV_TotalPixels
, data
->totalpixels
},
336 {ASLLV_Visible
, data
->visible
},
337 {ASLLV_VisiblePixels
, data
->visiblepixels
},
338 {ASLLV_DeltaFactor
, data
->lineheight
},
343 opu
.MethodID
= OM_NOTIFY
;
344 opu
.opu_AttrList
= tags
;
346 opu
.opu_Flags
= flags
;
348 D(bug("asl listview notify all: top = %d (%d) total = %d (%d) visible = %d (%d)\n",
349 data
->top
, data
->toppixel
,
350 data
->total
, data
->totalpixels
,
351 data
->visible
, data
->visiblepixels
));
353 DoSuperMethodA(cl
, o
, (Msg
)&opu
);
357 /***********************************************************************************/
359 static void notifytop(Class
*cl
, Object
*o
, struct GadgetInfo
*gi
, STACKULONG flags
)
361 struct AslListViewData
*data
= INST_DATA(cl
, o
);
362 struct TagItem tags
[] =
364 {ASLLV_Top
, data
->top
},
365 {ASLLV_TopPixel
, data
->toppixel
},
370 opu
.MethodID
= OM_NOTIFY
;
371 opu
.opu_AttrList
= tags
;
373 opu
.opu_Flags
= flags
;
375 D(bug("asl listview notify top: top = %d\n", data
->top
));
377 DoSuperMethodA(cl
, o
, (Msg
)&opu
);
381 /***********************************************************************************/
383 IPTR
AslListView__OM_SET(Class
* cl
, Object
* o
, struct opSet
* msg
)
385 struct AslListViewData
*data
= INST_DATA(cl
, o
);
387 const struct TagItem
*tstate
= msg
->ops_AttrList
;
389 BOOL redraw
= FALSE
, notify_all
= FALSE
, notify_top
= FALSE
;
392 retval
= DoSuperMethod(cl
, o
, OM_SET
, (IPTR
) msg
->ops_AttrList
, (IPTR
) msg
->ops_GInfo
);
394 while((tag
= NextTagItem(&tstate
)))
396 tidata
= tag
->ti_Data
;
401 tidata
*= data
->lineheight
;
406 if (newtop
+ data
->visiblepixels
> data
->totalpixels
)
408 newtop
= data
->totalpixels
- data
->visiblepixels
;
410 if (newtop
< 0) newtop
= 0;
412 if (newtop
!= data
->toppixel
)
414 data
->scroll
= redraw
? 0 : newtop
- data
->toppixel
;
415 data
->top
= newtop
/ data
->lineheight
;
416 data
->toppixel
= newtop
;
422 case ASLLV_MakeVisible
:
423 newtop
= (LONG
)tidata
* data
->lineheight
;
429 else if (newtop
>= data
->totalpixels
)
431 newtop
= data
->totalpixels
- 1;
432 if (newtop
< 0) newtop
= 0;
435 /* No need to do anything if it is already visible */
437 if (newtop
< data
->toppixel
)
439 /* new_top already okay */
441 data
->scroll
= redraw
? 0 : newtop
- data
->toppixel
;
442 data
->top
= newtop
/ data
->lineheight
;
443 data
->toppixel
= newtop
;
447 else if (newtop
> data
->toppixel
+ data
->visiblepixels
- data
->lineheight
)
449 newtop
-= (data
->visiblepixels
- data
->lineheight
);
450 data
->scroll
= redraw
? 0 : newtop
- data
->toppixel
;
451 data
->top
= newtop
/ data
->lineheight
;
452 data
->toppixel
= newtop
;
462 WORD old_active
= data
->active
;
464 data
->active
= (WORD
)tidata
;
466 if (data
->domultiselect
)
468 ForeachNode(data
->labels
, node
)
470 if (IS_MULTISEL(node
) && IS_SELECTED(node
) && (n
!= data
->active
))
472 MARK_UNSELECTED(node
);
473 rendersingleitem(cl
, o
, msg
->ops_GInfo
, n
);
478 if ((node
= findnode(cl
, o
, old_active
)))
480 MARK_UNSELECTED(node
);
481 rendersingleitem(cl
, o
, msg
->ops_GInfo
, old_active
);
485 if ((node
= findnode(cl
, o
, data
->active
)))
487 if (!data
->domultiselect
|| IS_MULTISEL(node
))
490 rendersingleitem(cl
, o
, msg
->ops_GInfo
, data
->active
);
498 data
->labels
= tidata
? (struct List
*)tidata
: &data
->emptylist
;
499 data
->total
= CountNodes(data
->labels
, 0);
500 data
->totalpixels
= data
->total
* data
->lineheight
;
505 data
->visible
= data
->total
;
506 data
->visiblepixels
= data
->visible
* data
->lineheight
;
509 if (data
->toppixel
+ data
->visiblepixels
> data
->totalpixels
)
511 data
->toppixel
= data
->totalpixels
- data
->visiblepixels
;
513 if (data
->toppixel
< 0) data
->toppixel
= 0;
514 data
->top
= data
->toppixel
/ data
->lineheight
;
518 data
->visiblepixels
= data
->totalpixels
;
519 data
->visible
= data
->total
;
522 makenodetable(cl
, o
);
528 case ASLLV_DoMultiSelect
:
529 data
->domultiselect
= tidata
? TRUE
: FALSE
;
533 data
->readonly
= tidata
? TRUE
: FALSE
;
537 data
->font
= (struct TextFont
*)tidata
;
540 } /* switch(tag->ti_Tag) */
542 } /* while((tag = NextTagItem(&tsate))) */
549 if ((rp
= ObtainGIRPort(msg
->ops_GInfo
)))
551 gpr
.MethodID
= GM_RENDER
;
552 gpr
.gpr_GInfo
= msg
->ops_GInfo
;
554 gpr
.gpr_Redraw
= GREDRAW_UPDATE
;
556 DoMethodA(o
, (Msg
)&gpr
);
564 notifyall(cl
, o
, msg
->ops_GInfo
, 0);
568 notifytop(cl
, o
, msg
->ops_GInfo
, 0);
574 /***********************************************************************************/
576 IPTR
AslListView__OM_NEW(Class
* cl
, Object
* o
, struct opSet
* msg
)
578 struct AslListViewData
*data
;
579 struct TagItem fitags
[] =
581 {IA_FrameType
, FRAME_BUTTON
},
582 {IA_EdgesOnly
, TRUE
},
586 struct Gadget
*g
= (struct Gadget
*)DoSuperMethodA(cl
, o
, (Msg
)msg
);
589 data
= INST_DATA(cl
, g
);
591 /* We want to get a GM_LAYOUT message, no matter if gadget is GFLG_RELRIGHT/RELBOTTOM/
592 RELWIDTH/RELHEIGHT or not */
593 g
->Flags
|= GFLG_RELSPECIAL
;
595 data
->frame
= NewObjectA(NULL
, FRAMEICLASS
, fitags
);
596 data
->ld
= (struct LayoutData
*)GetTagData(GA_UserData
, 0, msg
->ops_AttrList
);
598 if (!data
->ld
|| !data
->frame
)
600 CoerceMethod(cl
, (Object
*)g
, OM_DISPOSE
);
605 data
->itemheight
= GetTagData(ASLLV_ItemHeight
, data
->ld
->ld_Font
->tf_YSize
, msg
->ops_AttrList
);
606 data
->spacing
= GetTagData(ASLLV_Spacing
, BORDERLVITEMSPACINGY
* 2, msg
->ops_AttrList
);
608 data
->lineheight
= data
->itemheight
+ data
->spacing
;
610 NEWLIST(&data
->emptylist
);
611 data
->labels
= &data
->emptylist
;
613 data
->rendersingleitem
= -1;
615 data
->renderhook
= (struct Hook
*)GetTagData(ASLLV_CallBack
, 0, msg
->ops_AttrList
);
616 data
->default_renderhook
.h_Entry
= (APTR
) AROS_ASMSYMNAME(ASLLVRenderHook
);
617 data
->default_renderhook
.h_SubEntry
= NULL
;
618 data
->default_renderhook
.h_Data
= (APTR
)AslBase
;
619 if (!data
->renderhook
) data
->renderhook
= &data
->default_renderhook
;
621 AslListView__OM_SET(cl
, (Object
*)g
, msg
);
628 /***********************************************************************************/
630 IPTR
AslListView__OM_GET(Class
* cl
, Object
* o
, struct opGet
*msg
)
632 struct AslListViewData
*data
;
635 data
= INST_DATA(cl
, o
);
637 switch(msg
->opg_AttrID
)
640 *msg
->opg_Storage
= data
->active
;
644 *msg
->opg_Storage
= data
->top
;
648 *msg
->opg_Storage
= data
->toppixel
;
652 *msg
->opg_Storage
= data
->total
;
655 case ASLLV_TotalPixels
:
656 *msg
->opg_Storage
= data
->totalpixels
;
660 *msg
->opg_Storage
= data
->visible
;
663 case ASLLV_VisiblePixels
:
664 *msg
->opg_Storage
= data
->visiblepixels
;
668 retval
= DoSuperMethodA(cl
, o
, (Msg
)msg
);
671 } /* switch(msg->opg_AttrID) */
676 /***********************************************************************************/
678 IPTR
AslListView__OM_DISPOSE(Class
* cl
, Object
* o
, Msg msg
)
680 struct AslListViewData
*data
;
683 data
= INST_DATA(cl
, o
);
684 if (data
->frame
) DisposeObject(data
->frame
);
685 if (data
->nodetable
) FreeVec(data
->nodetable
);
686 retval
= DoSuperMethodA(cl
, o
, msg
);
691 /***********************************************************************************/
693 IPTR
AslListView__GM_GOACTIVE(Class
*cl
, Object
*o
, struct gpInput
*msg
)
695 struct AslListViewData
*data
;
697 IPTR retval
= GMR_NOREUSE
;
699 data
= INST_DATA(cl
, o
);
700 if ((data
->total
< 1) || (data
->readonly
)) return retval
;
702 i
= mouseitem(cl
, o
, msg
->gpi_Mouse
.X
, msg
->gpi_Mouse
.Y
);
708 if ((node
= findnode(cl
, o
, i
)))
712 CurrentTime(&sec
, µ
);
714 if (data
->domultiselect
&& IS_MULTISEL(node
) &&
715 (msg
->gpi_IEvent
->ie_Qualifier
& (IEQUALIFIER_LSHIFT
| IEQUALIFIER_RSHIFT
)))
717 data
->multiselecting
= TRUE
;
721 data
->multiselecting
= FALSE
;
723 if (data
->domultiselect
)
728 ForeachNode(data
->labels
, node
)
730 if (IS_MULTISEL(node
) && IS_SELECTED(node
) && (n
!= data
->active
))
732 MARK_UNSELECTED(node
);
733 rendersingleitem(cl
, o
, msg
->gpi_GInfo
, n
);
740 data
->doubleclicked
= FALSE
;
741 if (data
->active
== i
)
743 if (DoubleClick(data
->clicksec
, data
->clickmicro
, sec
, micro
))
745 data
->doubleclicked
= TRUE
;
750 if (!data
->multiselecting
&& (data
->active
>= 0))
752 struct Node
*oldnode
= findnode(cl
, o
, data
->active
);
754 MARK_UNSELECTED(oldnode
);
755 rendersingleitem(cl
, o
, msg
->gpi_GInfo
, data
->active
);
759 rendersingleitem(cl
, o
, msg
->gpi_GInfo
, i
);
763 } /* if (data->active != i) */
765 data
->clicksec
= sec
;
766 data
->clickmicro
= micro
;
768 retval
= GMR_MEACTIVE
;
770 } /* if ((node = findnode(cl, o, i))) */
777 /***********************************************************************************/
779 IPTR
AslListView__GM_HANDLEINPUT(Class
*cl
, Object
*o
, struct gpInput
*msg
)
781 struct AslListViewData
*data
;
783 IPTR retval
= GMR_MEACTIVE
;
785 data
= INST_DATA(cl
, o
);
787 switch(msg
->gpi_IEvent
->ie_Class
)
790 code
= IECODE_NOBUTTON
;
793 case IECLASS_RAWMOUSE
:
794 code
= msg
->gpi_IEvent
->ie_Code
;
799 *msg
->gpi_Termination
= data
->doubleclicked
;
800 retval
= GMR_VERIFY
| GMR_NOREUSE
;
803 case IECODE_NOBUTTON
:
805 WORD n
= mouseitem(cl
, o
, msg
->gpi_Mouse
.X
, msg
->gpi_Mouse
.Y
);
807 if ((n
== -1) && (data
->active
> 0)) n
= data
->active
- 1;
808 if ((n
== -2) && (data
->active
< data
->total
- 1)) n
= data
->active
+ 1;
810 if ((n
>= 0) && (n
!= data
->active
))
812 struct Node
*old
= findnode(cl
, o
, data
->active
);
813 struct Node
*new = findnode(cl
, o
, n
);
815 if (data
->multiselecting
&& new)
817 if (!IS_MULTISEL(new)) new = NULL
;
822 if (!data
->multiselecting
)
824 MARK_UNSELECTED(old
);
825 rendersingleitem(cl
, o
, msg
->gpi_GInfo
, data
->active
);
829 rendersingleitem(cl
, o
, msg
->gpi_GInfo
, n
);
834 if ((n
* data
->lineheight
< data
->toppixel
) ||
835 (n
* data
->lineheight
> data
->toppixel
+ data
->visiblepixels
- data
->lineheight
))
839 if (n
* data
->lineheight
< data
->toppixel
)
841 LONG newtop
= n
* data
->lineheight
;
842 data
->scroll
= newtop
- data
->toppixel
;
843 data
->toppixel
= newtop
;
844 data
->top
= newtop
/ data
->lineheight
;
848 LONG newtop
= n
* data
->lineheight
- (data
->visiblepixels
- data
->lineheight
);
850 data
->scroll
= newtop
- data
->toppixel
;
851 data
->toppixel
= newtop
;
852 data
->top
= newtop
/ data
->lineheight
;
855 if ((rp
= ObtainGIRPort(msg
->gpi_GInfo
)))
859 gpr
.MethodID
= GM_RENDER
;
860 gpr
.gpr_GInfo
= msg
->gpi_GInfo
;
862 gpr
.gpr_Redraw
= GREDRAW_UPDATE
;
864 DoMethodA(o
, (Msg
)&gpr
);
869 notifytop(cl
, o
, msg
->gpi_GInfo
, OPUF_INTERIM
);
871 } /* if ((n < data->top) || (n >= data->top + data->visible)) */
873 } /* if ((n >= 0) && (n != data->active)) */
877 } /* switch(msg->gpi_IEvent->ie_Code) */
880 } /* switch(msg->gpi_IEvent->ie_Class) */
885 /***********************************************************************************/
887 IPTR
AslListView__GM_LAYOUT(Class
*cl
, struct Gadget
*g
, struct gpLayout
*msg
)
889 struct AslListViewData
*data
;
892 data
= INST_DATA(cl
, g
);
896 LONG newtop
= data
->toppixel
;
897 LONG newvisible
= data
->visiblepixels
;
899 getgadgetcoords(g
, msg
->gpl_GInfo
, &data
->minx
, &data
->miny
, &data
->width
, &data
->height
);
901 data
->maxx
= data
->minx
+ data
->width
- 1;
902 data
->maxy
= data
->miny
+ data
->height
- 1;
904 newvisible
= (data
->height
- BORDERLVSPACINGY
* 2);
905 if (newtop
+ newvisible
> data
->totalpixels
)
907 newtop
= data
->totalpixels
- newvisible
;
909 if (newtop
< 0) newtop
= 0;
911 if ((newtop
!= data
->toppixel
) || (newvisible
!= data
->visiblepixels
) || (!data
->layouted
))
913 data
->toppixel
= newtop
;
914 data
->top
= newtop
/ data
->lineheight
;
915 data
->visiblepixels
= newvisible
;
916 data
->visible
= newvisible
/ data
->lineheight
;
918 notifyall(cl
, (Object
*)g
, msg
->gpl_GInfo
, 0);
921 data
->layouted
= TRUE
;
929 /***********************************************************************************/
931 IPTR
AslListView__GM_RENDER(Class
*cl
, Object
*o
, struct gpRender
*msg
)
933 struct AslListViewData
*data
;
934 struct Region
*clip
, *oldclip
;
938 data
= INST_DATA(cl
, o
);
940 if (msg
->gpr_Redraw
== GREDRAW_REDRAW
)
942 struct TagItem im_tags
[] =
944 {IA_Width
, data
->width
},
945 {IA_Height
, data
->height
},
946 {IA_Recessed
, data
->readonly
},
950 SetAttrsA(data
->frame
, im_tags
);
952 DrawImageState(msg
->gpr_RPort
,
953 (struct Image
*)data
->frame
,
957 msg
->gpr_GInfo
->gi_DrInfo
);
960 struct IBox ibox
, fbox
;
962 fbox
.Left
= data
->minx
;
963 fbox
.Top
= data
->miny
;
964 fbox
.Width
= data
->maxx
- data
->minx
+ 1;
965 fbox
.Height
= data
->maxy
- data
->miny
+ 1;
967 ibox
.Left
= data
->minx
+ BORDERLVSPACINGX
;
968 ibox
.Top
= data
->miny
+ BORDERLVSPACINGY
;
969 ibox
.Width
= (data
->maxx
- data
->minx
+ 1) - BORDERLVSPACINGX
* 2;
970 ibox
.Height
= (data
->maxy
- data
->miny
+ 1) - BORDERLVSPACINGY
* 2;
972 PaintInnerFrame(msg
->gpr_RPort
,
973 msg
->gpr_GInfo
->gi_DrInfo
,
977 msg
->gpr_GInfo
->gi_DrInfo
->dri_Pens
[BACKGROUNDPEN
],
986 if ((clip
= NewRectRegion(data
->minx
+ BORDERLVSPACINGX
,
987 data
->miny
+ BORDERLVSPACINGY
,
988 data
->maxx
- BORDERLVSPACINGX
,
989 data
->maxy
- BORDERLVSPACINGY
)))
991 struct Layer
*lay
= msg
->gpr_GInfo
->gi_Layer
;
993 updating
= (lay
->Flags
& LAYERUPDATING
) != 0;
995 if (updating
) EndUpdate(lay
, FALSE
);
996 oldclip
= InstallClipRegion(lay
, clip
);
997 if (updating
) BeginUpdate(lay
);
1000 if (msg
->gpr_Redraw
== GREDRAW_REDRAW
)
1002 renderallitems(cl
, o
, msg
->gpr_RPort
);
1004 } /* if (msg->gpr_Redraw == GREDRAW_REDRAW) */
1005 else if (msg
->gpr_Redraw
== GREDRAW_UPDATE
)
1007 if (data
->rendersingleitem
== -1)
1009 WORD abs_scroll
= (data
->scroll
>= 0) ? data
->scroll
: -data
->scroll
;
1011 if ((abs_scroll
== 0) || (abs_scroll
> data
->visiblepixels
/ 2))
1013 renderallitems(cl
, o
, msg
->gpr_RPort
);
1017 struct Rectangle rect
;
1018 WORD scrollx1
= data
->minx
+ BORDERLVSPACINGX
;
1019 WORD scrolly1
= data
->miny
+ BORDERLVSPACINGY
;
1020 WORD scrollx2
= data
->maxx
- BORDERLVSPACINGX
;
1021 WORD scrolly2
= data
->maxy
- BORDERLVSPACINGY
;
1022 BOOL mustrefresh
, update
;
1024 ScrollRaster(msg
->gpr_RPort
, 0, data
->scroll
,
1025 scrollx1
, scrolly1
, scrollx2
, scrolly2
);
1027 mustrefresh
= (msg
->gpr_GInfo
->gi_Layer
->Flags
& LAYERREFRESH
) != 0;
1029 rect
.MinX
= scrollx1
;
1030 rect
.MaxX
= scrollx2
;
1032 if (data
->scroll
>= 0)
1034 rect
.MinY
= scrolly2
- abs_scroll
;
1035 rect
.MaxY
= scrolly2
;
1039 rect
.MinY
= scrolly1
;
1040 rect
.MaxY
= scrolly1
+ abs_scroll
;
1043 data
->renderrect
= &rect
;
1044 renderallitems(cl
, o
, msg
->gpr_RPort
);
1045 data
->renderrect
= NULL
;
1047 /* the LAYERUPDATING check should not be necessary,
1048 as then we should always have a GREDRAW_REDRAW,
1049 while here we are in GREDRAW_UPDATE. But just
1052 if (mustrefresh
&& !(msg
->gpr_GInfo
->gi_Layer
->Flags
& LAYERUPDATING
))
1054 if(!(update
= BeginUpdate(msg
->gpr_GInfo
->gi_Layer
)))
1056 EndUpdate(msg
->gpr_GInfo
->gi_Layer
, FALSE
);
1059 renderallitems(cl
, o
, msg
->gpr_RPort
);
1061 if(update
) EndUpdate(msg
->gpr_GInfo
->gi_Layer
, TRUE
);
1068 if (data
->rendersingleitem
>= data
->top
)
1070 struct Node
*node
= findnode(cl
, o
, data
->rendersingleitem
);
1072 renderitem(cl
, o
, node
, data
->rendersingleitem
- data
->top
, msg
->gpr_RPort
);
1077 data
->rendersingleitem
= -1;
1079 } /* if (msg->gpr_Redraw == GREDRAW_UPDATE) */
1083 struct Layer
*lay
= msg
->gpr_GInfo
->gi_Layer
;
1085 if (updating
) EndUpdate(lay
, FALSE
);
1086 InstallClipRegion(lay
, oldclip
);
1087 if (updating
) BeginUpdate(lay
);
1089 DisposeRegion(clip
);
1095 /***********************************************************************************/