2 Copyright © 2011, The AROS Development Team. All rights reserved.
5 Desc: Workbook Virtual Area Class
10 #include <aros/debug.h>
15 #include <proto/dos.h>
16 #include <proto/exec.h>
17 #include <proto/intuition.h>
18 #include <proto/utility.h>
19 #include <proto/gadtools.h>
20 #include <proto/workbench.h>
21 #include <proto/graphics.h>
22 #include <proto/layers.h>
24 #include <intuition/classusr.h>
25 #include <intuition/icclass.h>
26 #include <intuition/cghooks.h>
27 #include <libraries/gadtools.h>
29 #include "workbook_intern.h"
32 static inline WORD
max(WORD a
, WORD b
)
34 return (a
> b
) ? a
: b
;
39 struct IBox Virt
; /* Virtual pos in, and total size of the scroll area */
42 static BOOL
wbRedimension(Class
*cl
, Object
*obj
, WORD vwidth
, WORD vheight
)
44 struct WorkbookBase
*wb
= (APTR
)cl
->cl_UserData
;
45 struct wbVirtual
*my
= INST_DATA(cl
, obj
);
46 struct Gadget
*gadget
= (struct Gadget
*)obj
;
49 if ((my
->Virt
.Width
!= vwidth
) ||
50 (my
->Virt
.Height
!= vheight
))
53 my
->Virt
.Width
= vwidth
;
54 my
->Virt
.Height
= vheight
;
56 if (my
->Virt
.Left
> (my
->Virt
.Width
- gadget
->Width
)) {
57 my
->Virt
.Left
= max(0, my
->Virt
.Width
- gadget
->Width
);
61 if (my
->Virt
.Top
> (my
->Virt
.Height
- gadget
->Height
)) {
62 my
->Virt
.Top
= max(0, my
->Virt
.Height
- gadget
->Height
);
66 D(bug("WBVirtual: wbRedimension(%d,%d) = (%d,%d) %dx%d\n",
67 vwidth
,vheight
,my
->Virt
.Left
,my
->Virt
.Top
,
68 my
->Virt
.Width
, my
->Virt
.Height
));
69 D(bug("WBVirtual: Frame at: (%d,%d) %dx%d\n",
70 gadget
->TopEdge
, gadget
->LeftEdge
,
71 gadget
->Width
, gadget
->Height
));
74 SetAttrs(my
->Gadget
, GA_Top
, gadget
->TopEdge
- my
->Virt
.Top
,
75 GA_Left
, gadget
->LeftEdge
- my
->Virt
.Left
,
82 static BOOL
wbMoveTo(Class
*cl
, Object
*obj
, WORD left
, WORD top
)
84 struct WorkbookBase
*wb
= (APTR
)cl
->cl_UserData
;
85 struct wbVirtual
*my
= INST_DATA(cl
, obj
);
86 struct Gadget
*gadget
= (struct Gadget
*)obj
;
89 D(bug("GadgetSize %dx%d\n", gadget
->Width
, gadget
->Width
));
90 D(bug(" VirtSize %dx%d\n", my
->Virt
.Width
, my
->Virt
.Height
));
91 D(bug(" wbMoveTo(%d,%d) =", left
,top
));
93 if (left
> (my
->Virt
.Width
- gadget
->Width
))
94 left
= max(0, my
->Virt
.Width
- gadget
->Width
);
95 if (top
> (my
->Virt
.Height
- gadget
->Height
))
96 top
= max(0, my
->Virt
.Height
- gadget
->Height
);
98 dLeft
= left
- my
->Virt
.Left
;
99 dTop
= top
- my
->Virt
.Top
;
101 D(bug(" (%d,%d) %dx%d\n",
103 my
->Virt
.Width
, my
->Virt
.Height
));
105 if (dLeft
== 0 && dTop
== 0)
108 my
->Virt
.Left
= left
;
111 D(bug("Frame at: (%d,%d) %dx%d\n",
112 gadget
->TopEdge
, gadget
->LeftEdge
,
113 gadget
->Width
, gadget
->Height
));
115 /* Set the position of the child */
117 SetAttrs(my
->Gadget
, GA_Top
, gadget
->TopEdge
- my
->Virt
.Top
,
118 GA_Left
, gadget
->LeftEdge
- my
->Virt
.Left
);
125 static IPTR
WBVirtualNew(Class
*cl
, Object
*obj
, struct opSet
*ops
)
129 rc
= DoSuperMethodA(cl
, obj
, (Msg
)ops
);
135 DoMethod(obj
, OM_SET
, ops
->ops_AttrList
, ops
->ops_GInfo
);
141 static IPTR
WBVirtualGet(Class
*cl
, Object
*obj
, struct opGet
*opg
)
143 struct wbVirtual
*my
= INST_DATA(cl
, obj
);
146 switch (opg
->opg_AttrID
) {
148 *(opg
->opg_Storage
) = (IPTR
)(my
->Gadget
);
151 *(opg
->opg_Storage
) = (IPTR
)(SIPTR
)(my
->Virt
.Left
);
154 *(opg
->opg_Storage
) = (IPTR
)(SIPTR
)(my
->Virt
.Top
);
157 *(opg
->opg_Storage
) = (IPTR
)(SIPTR
)(my
->Virt
.Width
);
159 case WBVA_VirtHeight
:
160 *(opg
->opg_Storage
) = (IPTR
)(SIPTR
)(my
->Virt
.Height
);
163 rc
= DoSuperMethodA(cl
, obj
, (Msg
)opg
);
171 static IPTR
WBVirtualSetUpdate(Class
*cl
, Object
*obj
, struct opUpdate
*opu
)
173 struct WorkbookBase
*wb
= (APTR
)cl
->cl_UserData
;
174 struct wbVirtual
*my
= INST_DATA(cl
, obj
);
176 struct TagItem
*tstate
;
180 rc
= DoSuperMethodA(cl
, obj
, (Msg
)opu
);
182 if ((opu
->MethodID
== OM_UPDATE
) && (opu
->opu_Flags
& OPUF_INTERIM
))
185 tstate
= opu
->opu_AttrList
;
186 while ((tag
= NextTagItem(&tstate
))) {
187 val
= (WORD
)tag
->ti_Data
;
188 D(bug("%s: Tag=0x%x, val=%d\n", __func__
, tag
->ti_Tag
, val
));
189 switch (tag
->ti_Tag
) {
191 if (my
->Gadget
!= (Object
*)tag
->ti_Data
) {
192 my
->Gadget
= (Object
*)tag
->ti_Data
;
193 IPTR vwidth
= 0, vheight
= 0;
194 GetAttr(GA_Width
, my
->Gadget
, &vwidth
);
195 GetAttr(GA_Height
, my
->Gadget
, &vheight
);
196 rc
|= wbRedimension(cl
, obj
, vwidth
, vheight
);
200 rc
|= wbMoveTo(cl
, obj
, my
->Virt
.Left
, val
);
203 rc
|= wbMoveTo(cl
, obj
, val
, my
->Virt
.Top
);
205 case WBVA_VirtHeight
:
206 rc
|= wbRedimension(cl
, obj
, my
->Virt
.Width
, val
);
209 rc
|= wbRedimension(cl
, obj
, val
, my
->Virt
.Height
);
213 rc
|= wbRedimension(cl
, obj
, my
->Virt
.Width
, my
->Virt
.Height
);
224 static IPTR
WBVirtualHitTest(Class
*cl
, Object
*obj
, struct gpHitTest
*gph
)
226 struct wbVirtual
*my
= INST_DATA(cl
, obj
);
227 struct gpHitTest subtest
= *gph
;
232 /* Forward to our client */
233 subtest
.gpht_Mouse
.X
+= my
->Virt
.Left
;
234 subtest
.gpht_Mouse
.Y
+= my
->Virt
.Top
;
236 return DoMethodA(my
->Gadget
, (Msg
)&subtest
);
240 static IPTR
WBVirtualRender(Class
*cl
, Object
*obj
, struct gpRender
*gpr
)
242 struct WorkbookBase
*wb
= (APTR
)cl
->cl_UserData
;
243 struct wbVirtual
*my
= INST_DATA(cl
, obj
);
244 struct Gadget
*gadget
= (struct Gadget
*)obj
;
245 struct GadgetInfo
*ginfo
= gpr
->gpr_GInfo
;
247 if (my
->Gadget
== NULL
)
253 /* Redraw the child */
254 struct Region
*region
, *old
;
255 if ((region
= NewRegion())) {
256 struct Rectangle rect
= {
257 .MinX
= gadget
->LeftEdge
,
258 .MinY
= gadget
->TopEdge
,
259 .MaxX
= gadget
->LeftEdge
+ gadget
->Width
- 1,
260 .MaxY
= gadget
->TopEdge
+ gadget
->Height
- 1,
262 OrRectRegion(region
, &rect
);
263 old
= InstallClipRegion(ginfo
->gi_Layer
, region
);
264 AddGadget(ginfo
->gi_Window
, (struct Gadget
*)my
->Gadget
, 0);
265 RefreshGList((struct Gadget
*)my
->Gadget
, ginfo
->gi_Window
, ginfo
->gi_Requester
, 1);
266 RemoveGadget(ginfo
->gi_Window
, (struct Gadget
*)my
->Gadget
);
267 InstallClipRegion(ginfo
->gi_Layer
, old
);
268 DisposeRegion(region
);
275 static IPTR
WBVirtualGoActive(Class
*cl
, Object
*obj
, struct gpInput
*gpi
)
277 struct wbVirtual
*my
= INST_DATA(cl
, obj
);
281 m
.gpi_Mouse
.X
+= my
->Virt
.Left
;
282 m
.gpi_Mouse
.Y
+= my
->Virt
.Top
;
284 return DoMethodA(my
->Gadget
, (Msg
)&m
);
288 static IPTR
WBVirtualGoInactive(Class
*cl
, Object
*obj
, struct gpGoInactive
*gpgi
)
290 struct wbVirtual
*my
= INST_DATA(cl
, obj
);
292 return DoMethodA(my
->Gadget
, (Msg
)gpgi
);
296 static IPTR
WBVirtualHandleInput(Class
*cl
, Object
*obj
, struct gpInput
*gpi
)
298 struct wbVirtual
*my
= INST_DATA(cl
, obj
);
302 m
.gpi_Mouse
.X
+= my
->Virt
.Left
;
303 m
.gpi_Mouse
.Y
+= my
->Virt
.Top
;
305 return DoMethodA(my
->Gadget
, (Msg
)&m
);
308 static IPTR
dispatcher(Class
*cl
, Object
*obj
, Msg msg
)
312 switch (msg
->MethodID
) {
313 case OM_NEW
: rc
= WBVirtualNew(cl
, obj
, (APTR
)msg
); break;
314 case OM_GET
: rc
= WBVirtualGet(cl
, obj
, (APTR
)msg
); break;
316 case OM_UPDATE
: rc
= WBVirtualSetUpdate(cl
, obj
, (APTR
)msg
); break;
317 case GM_RENDER
: rc
= WBVirtualRender(cl
, obj
, (APTR
)msg
); break;
318 case GM_HITTEST
: rc
= WBVirtualHitTest(cl
, obj
, (APTR
)msg
); break;
319 case GM_GOACTIVE
: rc
= WBVirtualGoActive(cl
, obj
, (APTR
)msg
); break;
320 case GM_GOINACTIVE
: rc
= WBVirtualGoInactive(cl
, obj
, (APTR
)msg
); break;
321 case GM_HANDLEINPUT
: rc
= WBVirtualHandleInput(cl
, obj
, (APTR
)msg
); break;
322 default: rc
= DoSuperMethodA(cl
, obj
, msg
); break;
328 Class
*WBVirtual_MakeClass(struct WorkbookBase
*wb
)
332 cl
= MakeClass( NULL
, "gadgetclass", NULL
,
333 sizeof(struct wbVirtual
),
336 cl
->cl_Dispatcher
.h_Entry
= HookEntry
;
337 cl
->cl_Dispatcher
.h_SubEntry
= dispatcher
;
338 cl
->cl_Dispatcher
.h_Data
= NULL
;
339 cl
->cl_UserData
= (IPTR
)wb
;