7 * (C) Copyright 1998 Manuel Lemos.
8 * (C) Copyright 1996-1997 Ian J. Einman.
9 * (C) Copyright 1993-1996 Jaba Development.
10 * (C) Copyright 1993-1996 Jan van den Baard.
11 * All Rights Reserved.
14 * Revision 42.4 2004/06/16 20:16:48 verhaegs
15 * Use METHODPROTO, METHOD_END and REGFUNCPROTOn where needed.
17 * Revision 42.3 2000/08/17 15:09:18 chodorowski
18 * Fixed compiler warnings.
20 * Revision 42.2 2000/05/15 19:27:02 stegerg
21 * another hundreds of REG() macro replacements in func headers/protos.
23 * Revision 42.1 2000/05/14 23:32:48 stegerg
24 * changed over 200 function headers which all use register
25 * parameters (oh boy ...), because the simple REG() macro
26 * doesn't work with AROS. And there are still hundreds
27 * of headers left to be fixed :(
29 * Many of these functions would also work with stack
30 * params, but since i have fixed every single one
31 * I encountered up to now, I guess will have to do
32 * the same for the rest.
34 * Revision 42.0 2000/05/09 22:09:56 mlemos
35 * Bumped to revision 42.0 before handing BGUI to AROS team
37 * Revision 41.11 2000/05/09 19:54:55 mlemos
38 * Merged with the branch Manuel_Lemos_fixes.
40 * Revision 41.10.2.5 2000/01/30 20:41:12 mlemos
41 * Fixed bug of not adding the arrows size to the minimum and nominal
42 * dimensions of the gadget.
44 * Revision 41.10.2.4 1998/12/06 21:40:53 mlemos
45 * Ensured that when the parent view and window are passed to the arrow
46 * gadgets on their creation.
48 * Revision 41.10.2.3 1998/11/13 18:21:53 mlemos
49 * Reverted the workaround patch that set the screen pointer in the BaseInfo
50 * structure as the real problem was fixed AllocBaseInfo function.
52 * Revision 41.10.2.2 1998/11/03 10:45:28 mlemos
53 * Added workaround to avoid enforcer hits cause by ROM propclass looking at
54 * the GadgetInfo Screen pointer inside GM_RENDER method.
56 * Revision 41.10.2.1 1998/10/01 04:38:52 mlemos
57 * Fixed bug of sending interim notifications after adjusting the knob.
59 * Revision 41.10 1998/02/25 21:12:53 mlemos
62 * Revision 1.1 1998/02/25 17:09:29 mlemos
68 /// Class definitions.
70 #include "include/classdefs.h"
73 * Object instance data.
76 ULONG pd_Flags
; /* see below */
77 Object
*pd_Prop
; /* prop gadget object */
78 Object
*pd_Knob
; /* prop gadget knob */
79 Object
*pd_Arrow1
; /* up/left arrow */
80 Object
*pd_Arrow2
; /* down/right arrow */
81 LONG pd_Top
; /* prop to position */
82 LONG pd_Total
; /* prop total range */
83 LONG pd_Visible
; /* prop visible portion */
84 LONG pd_Min
; /* minimum level */
85 LONG pd_Max
; /* maximum level */
86 LONG pd_Level
; /* current level */
87 LONG pd_Reset1
; /* Initial top value */
88 LONG pd_Reset2
; /* Initial top level */
89 UWORD pd_ArrowSize
; /* size of arrows */
90 UWORD pd_RptTicks
; /* repeat treshold */
93 #define PDF_ARROWS (1<<0) /* prop has arrows */
94 #define PDF_NEWLOOK (1<<1) /* prop must be "NewLook" */
95 #define PDF_PROPHORIZ (1<<2) /* prop moves horizontally */
96 #define PDF_PROPACTIVE (1<<3) /* prop is active */
97 #define PDF_LEFT_UP (1<<4) /* left/up gadget active */
98 #define PDF_RIGHT_DOWN (1<<5) /* right/down active */
99 #define PDF_RESET (1<<6) /* Reset to pd_Initial */
100 #define PDF_SLIDER (1<<7) /* Slider mode. */
101 #define PDF_READY (1<<8) /* Created and ready. */
106 * Calculate arrow and prop positions.
108 STATIC VOID
CalcPropMuck(Class
*cl
, Object
*obj
, struct BaseInfo
*bi
)
110 PD
*pd
= INST_DATA(cl
, obj
);
111 BC
*bc
= BASE_DATA(obj
);
112 int size
= pd
->pd_ArrowSize
;
114 struct IBox arrow1
, arrow2
;
117 * Check for arrows and where they are placed.
119 if (pd
->pd_Flags
& PDF_ARROWS
)
122 * Copy the hitbox to the destinations
124 arrow1
= arrow2
= bc
->bc_HitBox
;
127 * FREEHORIZ will get the arrows
128 * on the right side. FREEVERT will
131 if (pd
->pd_Flags
& PDF_PROPHORIZ
)
133 arrow1
.Left
+= bc
->bc_HitBox
.Width
;
134 arrow2
.Left
= arrow1
.Left
+ size
;
135 arrow1
.Width
= arrow2
.Width
= size
;
139 arrow1
.Top
+= bc
->bc_HitBox
.Height
;
140 arrow2
.Top
= arrow1
.Top
+ size
;
141 arrow1
.Height
= arrow2
.Height
= size
;
143 SetGadgetBounds(pd
->pd_Arrow1
, &arrow1
);
144 SetGadgetBounds(pd
->pd_Arrow2
, &arrow2
);
151 if (pd
->pd_Flags
& PDF_SLIDER
)
153 if (pd
->pd_Flags
& PDF_PROPHORIZ
) pd
->pd_Top
= pd
->pd_Level
- pd
->pd_Min
;
154 else pd
->pd_Top
= pd
->pd_Max
- pd
->pd_Level
;
160 DoSetMethodNG(pd
->pd_Prop
, GA_Left
, bc
->bc_InnerBox
.Left
, GA_Top
, bc
->bc_InnerBox
.Top
,
161 GA_Width
, bc
->bc_InnerBox
.Width
, GA_Height
, bc
->bc_InnerBox
.Height
,
162 PGA_Top
, pd
->pd_Top
, PGA_Total
, pd
->pd_Total
,
163 PGA_Visible
, pd
->pd_Visible
, TAG_DONE
);
167 kw
= bc
->bc_InnerBox
.Width
;
168 kh
= bc
->bc_InnerBox
.Height
;
170 if ((pd
->pd_Total
> 0) && (pd
->pd_Total
> pd
->pd_Visible
))
172 if (pd
->pd_Flags
& PDF_PROPHORIZ
)
174 kw
= (kw
* (ULONG
)pd
->pd_Visible
) / pd
->pd_Total
;
179 kh
= (kh
* (ULONG
)pd
->pd_Visible
) / pd
->pd_Total
;
183 DoSetMethodNG(pd
->pd_Knob
, IA_Width
, kw
, IA_Height
, kh
, TAG_DONE
);
189 * Create a shiny new object.
191 METHOD(PropClassNew
, struct opSet
*, ops
)
195 struct TagItem
*tags
;
199 tags
= DefTagList(BGUI_PROP_GADGET
, ops
->ops_AttrList
);
202 * First we let the superclass get us an object.
204 if (rc
= NewSuperObject(cl
, obj
, tags
))
207 * Obtain instance data.
209 pd
= INST_DATA(cl
, rc
);
212 if (!bc
->bc_Frame
) goto failure
;
215 * Make sure we are GACT_RELVERIFY.
217 GADGET(rc
)->Activation
|= GACT_RELVERIFY
;
224 pd
->pd_Flags
= GetTagData(PGA_Slider
, FALSE
, tags
) ? PDF_SLIDER
|PDF_PROPHORIZ
: PDF_ARROWS
;
227 AsmCoerceMethod(cl
, (Object
*)rc
, OM_SET
, tags
, NULL
);
229 horiz
= pd
->pd_Flags
& PDF_PROPHORIZ
;
234 if (pd
->pd_Flags
& PDF_ARROWS
)
236 pd
->pd_Arrow1
= BGUI_NewObject(BGUI_BUTTON_GADGET
,
237 VIT_BuiltIn
, horiz
? BUILTIN_ARROW_LEFT
: BUILTIN_ARROW_UP
,
238 BT_ParentView
,bc
->bc_View
,
239 BT_ParentWindow
,bc
->bc_Window
,
242 pd
->pd_Arrow2
= BGUI_NewObject(BGUI_BUTTON_GADGET
,
243 VIT_BuiltIn
, horiz
? BUILTIN_ARROW_RIGHT
: BUILTIN_ARROW_DOWN
,
244 BT_ParentView
,bc
->bc_View
,
245 BT_ParentWindow
,bc
->bc_Window
,
248 if (!(pd
->pd_Arrow1
&& pd
->pd_Arrow2
)) goto failure
;
251 if (pd
->pd_Prop
= NewObject(NULL
, PropGClass
,
253 PGA_Borderless
, TRUE
,
254 PGA_Freedom
, horiz
? FREEHORIZ
: FREEVERT
,
258 pd->pd_Knob = BGUI_NewObject(BGUI_FRAME_IMAGE,
259 FRM_Type, FRTYPE_FUZZ_RIDGE,
261 //FRM_FrameHeight, 2,
263 FRM_BackFill, SHINE_RASTER,
264 IMAGE_InBorder, GADGET(rc)->Activation & BORDERMASK,
272 DoSetMethodNG(pd
->pd_Prop
, GA_Disabled
, FALSE
, TAG_END
);
276 DoSetMethodNG(pd
->pd_Prop
, GA_Image
, pd
->pd_Knob
, GA_SelectRender
, pd
->pd_Knob
, TAG_DONE
);
280 * We target the IDCMP port (when allowed).
282 if (!GetTagData(PGA_DontTarget
, FALSE
, tags
))
283 DoSuperSetMethodNG(cl
, (Object
*)rc
, ICA_TARGET
, ICTARGET_IDCMP
, TAG_END
);
285 pd
->pd_Flags
|= PDF_READY
;
288 * So far, so good....
295 * Shit! Something screwed up...
297 AsmCoerceMethod(cl
, (Object
*)rc
, OM_DISPOSE
);
304 /// OM_SET, OM_UPDATE
306 * Change some attributes.
308 METHOD(PropClassSetUpdate
, struct opUpdate
*, opu
)
310 PD
*pd
= INST_DATA(cl
, obj
);
311 BC
*bc
= BASE_DATA(obj
);
312 struct TagItem
*tstate
= opu
->opu_AttrList
, *tag
;
313 ULONG data
, type
, redraw
= 0, ho
, vo
;
314 LONG tmp
, val
, omin
, omax
, olev
, oldtop
, oldtot
, oldvis
;
315 BOOL fc
= !(pd
->pd_Flags
& PDF_READY
);
316 WORD dis
= GADGET(obj
)->Flags
& GFLG_DISABLED
;
319 * First we let the superclass do it's thing.
321 AsmDoSuperMethodA(cl
, obj
, (Msg
)opu
);
324 * Make sure we stay GACT_RELVERIFY.
326 GADGET(obj
)->Activation
|= GACT_RELVERIFY
;
328 if (pd
->pd_Flags
& PDF_SLIDER
)
337 oldtot
= pd
->pd_Total
;
338 oldvis
= pd
->pd_Visible
;
342 * Let's see if we need to change
343 * some known attributes ourselves.
345 while (tag
= NextTagItem(&tstate
))
359 pd
->pd_Visible
= data
;
363 if (data
== FREEHORIZ
) pd
->pd_Flags
|= PDF_PROPHORIZ
;
364 else pd
->pd_Flags
&= ~PDF_PROPHORIZ
;
368 if (data
) pd
->pd_Flags
|= PDF_ARROWS
;
369 else pd
->pd_Flags
&= ~PDF_ARROWS
;
373 pd
->pd_ArrowSize
= data
;
389 if (data
) data
= FRTYPE_XEN_BUTTON
;
390 else data
= FRTYPE_BUTTON
;
395 if (data
) data
= FRTYPE_NONE
;
396 else data
= FRTYPE_BUTTON
;
400 DoMultiSet(FRM_Type
, data
, 3, bc
->bc_Frame
, pd
->pd_Arrow1
, pd
->pd_Arrow2
);
405 case SLIDER_ThinFrame
:
407 DoMultiSet(FRM_ThinFrame
, data
, 3, bc
->bc_Frame
, pd
->pd_Arrow1
, pd
->pd_Arrow2
);
412 case GA_BottomBorder
:
415 DoMultiSet(tag
->ti_Tag
, data
, 4, pd
->pd_Arrow1
, pd
->pd_Arrow2
, pd
->pd_Knob
, pd
->pd_Prop
);
419 DoSetMethodNG(bc
->bc_Frame
, FRM_Type
, FRTYPE_BORDER
, FRM_EdgesOnly
, TRUE
, TAG_DONE
);
421 DoSetMethodNG(pd
->pd_Arrow1
, BT_FrameObject
, NULL
,
422 SYSIA_Which
, (pd
->pd_Flags
& PDF_PROPHORIZ
) ? LEFTIMAGE
: UPIMAGE
, TAG_DONE
);
424 DoSetMethodNG(pd
->pd_Arrow2
, BT_FrameObject
, NULL
,
425 SYSIA_Which
, (pd
->pd_Flags
& PDF_PROPHORIZ
) ? RIGHTIMAGE
: DOWNIMAGE
, TAG_DONE
);
430 case BT_ParentWindow
:
432 DoMultiSet(tag
->ti_Tag
, data
, 3, pd
->pd_Arrow1
, pd
->pd_Arrow2
, pd
->pd_Knob
);
437 if (pd
->pd_Flags
& PDF_SLIDER
)
442 if (pd
->pd_Min
> pd
->pd_Max
)
445 pd
->pd_Min
= pd
->pd_Max
;
450 * Calculate the absolute difference between min and max.
452 pd
->pd_Total
= pd
->pd_Max
- pd
->pd_Min
+ 1;
460 pd
->pd_Max
= max(pd
->pd_Total
- pd
->pd_Visible
, 0);
465 if (val
< pd
->pd_Min
) val
= pd
->pd_Min
;
466 else if (val
> pd
->pd_Max
) val
= pd
->pd_Max
;
468 if (pd
->pd_Flags
& PDF_SLIDER
)
473 * Check if any of these values changed.
475 if ((pd
->pd_Min
!= omin
) || (pd
->pd_Max
!= omax
) || (pd
->pd_Level
!= olev
))
476 redraw
= GREDRAW_UPDATE
;
483 * Check if any of these values changed.
485 if ((pd
->pd_Top
!= oldtop
) || (pd
->pd_Total
!= oldtot
) || (pd
->pd_Visible
!= oldvis
))
486 redraw
= GREDRAW_UPDATE
;
491 Get_Attr(bc
->bc_Frame
, FRM_Type
, &data
);
497 if (GADGET(obj
)->Activation
& (GACT_LEFTBORDER
|GACT_RIGHTBORDER
)) { ho
= 4; vo
= 1; };
498 if (GADGET(obj
)->Activation
& (GACT_TOPBORDER
|GACT_BOTTOMBORDER
)) { ho
= 2; vo
= 2; };
499 DoSetMethodNG(bc
->bc_Frame
, FRM_Type
, FRTYPE_NONE
, TAG_DONE
);
502 Get_Attr(bc
->bc_Frame
, FRM_ThinFrame
, &data
);
507 DoSuperSetMethodNG(cl
, obj
, BT_LeftOffset
, ho
, BT_RightOffset
, ho
,
508 BT_TopOffset
, vo
, BT_BottomOffset
, vo
, TAG_DONE
);
510 redraw
= GREDRAW_REDRAW
;
514 if (pd
->pd_Flags
& PDF_READY
)
517 * Disable state changed?
519 if ((GADGET(obj
)->Flags
& GFLG_DISABLED
) != dis
)
520 redraw
= GREDRAW_REDRAW
;
523 * Re-render the gadget.
525 if (redraw
) DoRenderMethod(obj
, opu
->opu_GInfo
, redraw
);
528 * Notify our target if the
531 if (pd
->pd_Flags
& PDF_SLIDER
)
533 type
= (pd
->pd_Level
!= olev
) ? SLIDER_Level
: 0;
537 type
= (pd
->pd_Top
!= oldtop
) ? PGA_Top
: 0;
540 if (type
) DoNotifyMethod(obj
, opu
->opu_GInfo
, opu
->MethodID
== OM_UPDATE
? opu
->opu_Flags
: 0,
541 GA_ID
, GADGET(obj
)->GadgetID
, type
, val
, TAG_DONE
);
551 METHOD(PropClassRender
, struct bmRender
*, bmr
)
553 PD
*pd
= INST_DATA(cl
, obj
);
554 BC
*bc
= BASE_DATA(obj
);
555 struct BaseInfo
*bi
= bmr
->bmr_BInfo
;
556 struct RastPort
*rp
= bi
->bi_RPort
;
559 * Render the baseclass.
561 AsmDoSuperMethodA(cl
, obj
, (Msg
)bmr
);
566 CalcPropMuck(cl
, obj
, bi
);
569 * Complete re-render?
571 if (bmr
->bmr_Flags
== GREDRAW_REDRAW
)
574 * Render the arrow images.
576 if (pd
->pd_Flags
& PDF_ARROWS
)
578 AsmDoMethod(pd
->pd_Arrow1
, GM_RENDER
, bi
, rp
, GREDRAW_REDRAW
);
579 AsmDoMethod(pd
->pd_Arrow2
, GM_RENDER
, bi
, rp
, GREDRAW_REDRAW
);
583 * Then the slider body.
585 AsmDoMethod(pd
->pd_Prop
, GM_RENDER
, bi
, rp
, GREDRAW_REDRAW
);
592 if (pd
->pd_Flags
& PDF_LEFT_UP
)
593 AsmDoMethod(pd
->pd_Arrow1
, GM_RENDER
, bi
, rp
, GREDRAW_REDRAW
);
594 else if (pd
->pd_Flags
& PDF_RIGHT_DOWN
)
595 AsmDoMethod(pd
->pd_Arrow2
, GM_RENDER
, bi
, rp
, GREDRAW_REDRAW
);
598 * Only re-render the slider when it isn't active.
600 if (!(pd
->pd_Flags
& PDF_PROPACTIVE
))
601 AsmDoMethod(pd
->pd_Prop
, GM_RENDER
, bi
, rp
, GREDRAW_UPDATE
);
605 * Ghost the gadget hitbox when it is disabled.
607 if (GADGET(obj
)->Flags
& GFLG_DISABLED
)
609 BDisableBox(bi
, &bc
->bc_HitBox
);
610 if (pd
->pd_Arrow1
) BDisableBox(bi
, GADGETBOX(pd
->pd_Arrow1
));
611 if (pd
->pd_Arrow2
) BDisableBox(bi
, GADGETBOX(pd
->pd_Arrow2
));
619 * They want to know something.
621 METHOD(PropClassGet
, struct opGet
*, opg
)
623 PD
*pd
= INST_DATA(cl
, obj
);
625 ULONG
*store
= opg
->opg_Storage
;
627 switch (opg
->opg_AttrID
)
630 STORE (pd
->pd_Flags
& PDF_PROPHORIZ
) ? FREEHORIZ
: FREEVERT
;
650 rc
= AsmDoSuperMethodA(cl
, obj
, (Msg
)opg
);
659 * Where we hit and if so, what was hit.
661 METHOD(PropClassHitTest
, struct gpHitTest
*, gph
)
663 PD
*pd
= INST_DATA(cl
, obj
);
664 BC
*bc
= BASE_DATA(obj
);
668 * Calculate absolute click position.
670 WORD l
= GADGETBOX(obj
)->Left
+ gph
->gpht_Mouse
.X
;
671 WORD t
= GADGETBOX(obj
)->Top
+ gph
->gpht_Mouse
.Y
;
673 if (PointInBox(&bc
->bc_HitBox
, l
, t
))
676 * Did they click inside the
677 * proportional gadget?
679 rc
= ForwardMsg(obj
, pd
->pd_Prop
, (Msg
)gph
);
681 if (rc
== GMR_GADGETHIT
) pd
->pd_Flags
|= PDF_PROPACTIVE
;
684 if (!rc
&& pd
->pd_Arrow1
)
687 * Clicked in the left/up arrow?
689 rc
= ForwardMsg(obj
, pd
->pd_Arrow1
, (Msg
)gph
);
691 if (rc
== GMR_GADGETHIT
) pd
->pd_Flags
|= PDF_LEFT_UP
;
694 if (!rc
&& pd
->pd_Arrow2
)
697 * Clicked in the down/right arrow?
699 rc
= ForwardMsg(obj
, pd
->pd_Arrow2
, (Msg
)gph
);
701 if (rc
== GMR_GADGETHIT
) pd
->pd_Flags
|= PDF_RIGHT_DOWN
;
704 if (rc
== GMR_GADGETHIT
)
706 pd
->pd_Reset1
= pd
->pd_Top
;
707 pd
->pd_Reset2
= pd
->pd_Level
;
714 //STATIC ASM VOID NotifyChange(REG(a0) Class *cl, REG(a2) Object *obj, REG(a1) struct gpInput *gpi, REG(d0) ULONG flags)
715 STATIC ASM
REGFUNC4(VOID
, NotifyChange
,
716 REGPARAM(A0
, Class
*, cl
),
717 REGPARAM(A2
, Object
*, obj
),
718 REGPARAM(A1
, struct gpInput
*, gpi
),
719 REGPARAM(D0
, ULONG
, flags
))
721 PD
*pd
= INST_DATA(cl
, obj
);
723 LONG val
, oldval
= (pd
->pd_Flags
& PDF_SLIDER
) ? pd
->pd_Level
: pd
->pd_Top
;
728 Get_Attr(pd
->pd_Prop
, PGA_Top
, &val
);
730 if (pd
->pd_Flags
& PDF_SLIDER
)
735 if (pd
->pd_Flags
& PDF_PROPHORIZ
) val
= pd
->pd_Min
+ val
;
736 else val
= pd
->pd_Max
- val
;
750 if ((flags
== OPUF_INTERIM
) && (val
== oldval
)) return;
752 DoNotifyMethod(obj
, gpi
->gpi_GInfo
, flags
, GA_ID
, GADGET(obj
)->GadgetID
, type
, val
, TAG_DONE
);
757 * Adjust knob position in
758 * whatever direction necessary.
760 //STATIC ASM VOID AdjustKnob(REG(a0) Class *cl, REG(a2) Object *obj, REG(a1) struct gpInput *gpi)
761 STATIC ASM
REGFUNC3(VOID
, AdjustKnob
,
762 REGPARAM(A0
, Class
*, cl
),
763 REGPARAM(A2
, Object
*, obj
),
764 REGPARAM(A1
, struct gpInput
*, gpi
))
766 PD
*pd
= INST_DATA(cl
, obj
);
767 LONG top
, total
= max(pd
->pd_Total
- pd
->pd_Visible
, 0);
769 Get_Attr(pd
->pd_Prop
, PGA_Top
, &top
);
771 if (pd
->pd_Flags
& PDF_LEFT_UP
)
775 else if (pd
->pd_Flags
& PDF_RIGHT_DOWN
)
780 if ((top
>= 0) && (top
<= total
))
782 DoSetMethod(pd
->pd_Prop
, gpi
->gpi_GInfo
, PGA_Top
, top
, TAG_DONE
);
783 NotifyChange(cl
, obj
, gpi
, 0L);
790 METHOD(PropClassGoActive
, struct gpInput
*, gpi
)
792 PD
*pd
= INST_DATA(cl
, obj
);
794 ULONG rc
= GMR_NOREUSE
;
797 * We do not go active when we are disabled or was activated
798 * by Activate gadget.
800 if ((GADGET(obj
)->Flags
& GFLG_DISABLED
) || (!gpi
->gpi_IEvent
))
802 pd
->pd_Flags
&= ~(PDF_PROPACTIVE
|PDF_LEFT_UP
|PDF_RIGHT_DOWN
);
807 * Let the superclass have a go...
809 AsmDoSuperMethodA(cl
, obj
, (Msg
)gpi
);
812 * Is the proportional gadget active?
814 if (pd
->pd_Flags
& PDF_PROPACTIVE
)
817 * If so adjust the click
818 * coordinates and route the
819 * message to the proportional gadget.
821 rc
= ForwardMsg(obj
, pd
->pd_Prop
, (Msg
)gpi
);
823 if (rc
& GMR_VERIFY
) NotifyChange(cl
, obj
, gpi
, 0);
825 else if (pd
->pd_Flags
& (PDF_LEFT_UP
|PDF_RIGHT_DOWN
))
828 * Clear timer threshold.
833 * Adjust knob and notify when the knob position changed.
835 AdjustKnob(cl
, obj
, gpi
);
838 * Route the message to the button gadget.
840 arrow
= (pd
->pd_Flags
& PDF_LEFT_UP
) ? pd
->pd_Arrow1
: pd
->pd_Arrow2
;
841 rc
= ForwardMsg(obj
, arrow
, (Msg
)gpi
);
851 METHOD(PropClassHandleInput
, struct gpInput
*, gpi
)
853 PD
*pd
= INST_DATA(cl
, obj
);
856 ULONG rc
= GMR_MEACTIVE
;
859 * Calculate absolute click position.
861 l
= GADGETBOX(obj
)->Left
+ gpi
->gpi_Mouse
.X
;
862 t
= GADGETBOX(obj
)->Top
+ gpi
->gpi_Mouse
.Y
;
865 * Is the proportional gadget active?
867 if (pd
->pd_Flags
& PDF_PROPACTIVE
)
870 * Right mouse button pressed?
872 if (gpi
->gpi_IEvent
->ie_Class
== IECLASS_RAWMOUSE
&& gpi
->gpi_IEvent
->ie_Code
== MENUDOWN
)
875 * Yep. Say we need to reset to
878 pd
->pd_Flags
|= PDF_RESET
;
882 * If so adjust the click
883 * coordinates and rout the
884 * message to the proportional gadget.
886 rc
= ForwardMsg(obj
, pd
->pd_Prop
, (Msg
)gpi
);
888 NotifyChange(cl
, obj
, gpi
, (rc
== GMR_MEACTIVE
) ? OPUF_INTERIM
: 0);
892 arrow
= (pd
->pd_Flags
& PDF_LEFT_UP
) ? pd
->pd_Arrow1
: pd
->pd_Arrow2
;
895 * Check if the mouse is
896 * still over the active arrow.
898 if (PointInBox(GADGETBOX(arrow
), l
, t
))
904 if (gpi
->gpi_IEvent
->ie_Class
== IECLASS_RAWMOUSE
)
906 switch (gpi
->gpi_IEvent
->ie_Code
)
910 * They released the left
913 rc
= GMR_NOREUSE
| GMR_VERIFY
;
916 * Unselect the arrow.
923 * Terminate when they press the menubutton.
926 pd
->pd_Flags
|= PDF_RESET
;
931 else if (gpi
->gpi_IEvent
->ie_Class
== IECLASS_TIMER
)
934 * On every timer event we
935 * increase or decrease the knob
941 * We delay with adjusting the knob position for a little while just
942 * like the key-repeat threshold. Probably should use the system prefs
943 * for determing the delay but this is _so_ much easier.
945 if (pd
->pd_RptTicks
> 3)
948 * Adjust knob and notify when the knob position changed.
950 AdjustKnob(cl
, obj
, gpi
);
955 * Increase repeat treshold.
963 * When the selected state
964 * changed show it visually.
966 if ((GADGET(arrow
)->Flags
& GFLG_SELECTED
) != sel
)
969 * Flip selected bit and re-render.
971 GADGET(arrow
)->Flags
^= GFLG_SELECTED
;
972 DoRenderMethod(arrow
, gpi
->gpi_GInfo
, GREDRAW_REDRAW
);
983 METHOD(PropClassGoInActive
, struct gpGoInactive
*, ggi
)
985 PD
*pd
= INST_DATA(cl
, obj
);
989 * Is the proportional gadget
992 if (pd
->pd_Flags
& PDF_PROPACTIVE
)
995 * If so route the message to
996 * the proportional gadget and
997 * mark it as not active.
999 AsmDoMethodA(pd
->pd_Prop
, (Msg
)ggi
);
1003 * Un-activate our arrows and let the super
1004 * class see what it can do with this message.
1006 pd
->pd_Flags
&= ~(PDF_LEFT_UP
|PDF_RIGHT_DOWN
|PDF_PROPACTIVE
);
1007 rc
= AsmDoSuperMethodA(cl
, obj
, (Msg
)ggi
);
1010 * Reset to the initial value when necessary.
1012 if (pd
->pd_Flags
& PDF_RESET
)
1014 DoSetMethod(obj
, ggi
->gpgi_GInfo
, PGA_Top
, pd
->pd_Reset1
, SLIDER_Level
, pd
->pd_Reset2
, TAG_DONE
);
1015 pd
->pd_Flags
&= ~PDF_RESET
;
1023 * Find out our minumum size.
1025 METHOD(PropClassDimensions
, struct bmDimensions
*, bmd
)
1027 PD
*pd
= INST_DATA(cl
, obj
);
1028 BC
*bc
= BASE_DATA(obj
);
1029 BOOL vborder
= GADGET(obj
)->Activation
& (GACT_LEFTBORDER
|GACT_RIGHTBORDER
);
1030 BOOL hborder
= GADGET(obj
)->Activation
& (GACT_TOPBORDER
|GACT_BOTTOMBORDER
);
1031 BOOL horiz
= pd
->pd_Flags
& PDF_PROPHORIZ
;
1032 int arrowsize
= pd
->pd_ArrowSize
;
1035 if (pd
->pd_Flags
& PDF_ARROWS
)
1039 if (vborder
) arrowsize
= 11;
1040 else if (hborder
) arrowsize
= 16;
1041 else arrowsize
= horiz
? 10 : 9;
1043 pd
->pd_ArrowSize
= arrowsize
;
1045 DoSetMethodNG(bc
->bc_Frame
, horiz
? FRM_OuterOffsetRight
: FRM_OuterOffsetBottom
, arrowsize
<< 1, TAG_DONE
);
1049 * Add these to the superclass results.
1051 rc
= CalcDimensions(cl
, obj
, bmd
, 8+(horiz
? arrowsize
*2 : 0), 8+(horiz
? 0 : arrowsize
*2 ));
1053 if (vborder
) bmd
->bmd_Extent
->be_Min
.Width
= bmd
->bmd_Extent
->be_Nom
.Width
= 18;
1054 if (hborder
) bmd
->bmd_Extent
->be_Min
.Height
= bmd
->bmd_Extent
->be_Nom
.Height
= 10;
1062 * Dispose of ourselves.
1064 METHOD(PropClassDispose
, Msg
, msg
)
1066 PD
*pd
= INST_DATA(cl
, obj
);
1069 * Dispose of the allocated objects.
1071 if (pd
->pd_Arrow1
) DisposeObject(pd
->pd_Arrow1
);
1072 if (pd
->pd_Arrow2
) DisposeObject(pd
->pd_Arrow2
);
1073 if (pd
->pd_Prop
) DisposeObject(pd
->pd_Prop
);
1074 if (pd
->pd_Knob
) DisposeObject(pd
->pd_Knob
);
1076 return AsmDoSuperMethodA(cl
, obj
, msg
);
1082 * We are activated by the keyboard.
1084 METHOD(PropClassKeyActive
, struct wmKeyInput
*, wmki
)
1086 PD
*pd
= ( PD
* )INST_DATA( cl
, obj
);
1087 UWORD qual
= wmki
->wmki_IEvent
->ie_Qualifier
, code
= wmki
->wmki_IEvent
->ie_Code
;
1088 BOOL sl
= pd
->pd_Flags
& PDF_SLIDER
;
1089 LONG otop
= sl
? pd
->pd_Level
: pd
->pd_Top
, ntop
= otop
;
1090 LONG inc
= pd
->pd_Visible
- 1;
1092 if (inc
< 1) inc
= 1;
1097 if (qual
& (IEQUALIFIER_LSHIFT
|IEQUALIFIER_RSHIFT
))
1099 if (ntop
> pd
->pd_Min
) ntop
-= inc
;
1100 if (ntop
< pd
->pd_Min
) ntop
= pd
->pd_Min
;
1104 if (ntop
< pd
->pd_Max
) ntop
+= inc
;
1105 if (ntop
> pd
->pd_Max
) ntop
= pd
->pd_Max
;
1109 * Did the top position change?
1111 if ((ntop
!= otop
) && !(code
& IECODE_UP_PREFIX
))
1114 * Let the slider know about this change.
1116 DoSetMethod(obj
, wmki
->wmki_GInfo
, sl
? SLIDER_Level
: PGA_Top
, ntop
, TAG_END
);
1118 * Skip the ID because the notification
1119 * will handle the change.
1123 * Tell then to ignore this message.
1125 *(wmki
->wmki_ID
) = WMHI_IGNORE
;
1132 /// Class initialization,
1134 * Class function table.
1136 STATIC DPFUNC ClassFunc
[] = {
1137 BASE_RENDER
, (FUNCPTR
)PropClassRender
,
1138 BASE_DIMENSIONS
, (FUNCPTR
)PropClassDimensions
,
1140 OM_NEW
, (FUNCPTR
)PropClassNew
,
1141 OM_SET
, (FUNCPTR
)PropClassSetUpdate
,
1142 OM_UPDATE
, (FUNCPTR
)PropClassSetUpdate
,
1143 OM_GET
, (FUNCPTR
)PropClassGet
,
1144 OM_DISPOSE
, (FUNCPTR
)PropClassDispose
,
1145 GM_HITTEST
, (FUNCPTR
)PropClassHitTest
,
1146 GM_HANDLEINPUT
, (FUNCPTR
)PropClassHandleInput
,
1147 GM_GOACTIVE
, (FUNCPTR
)PropClassGoActive
,
1148 GM_GOINACTIVE
, (FUNCPTR
)PropClassGoInActive
,
1149 WM_KEYACTIVE
, (FUNCPTR
)PropClassKeyActive
,
1154 * Class initialization.
1156 makeproto Class
*InitPropClass(void)
1158 return BGUI_MakeClass(CLASS_SuperClassBGUI
, BGUI_BASE_GADGET
,
1159 CLASS_ObjectSize
, sizeof(PD
),
1160 CLASS_DFTable
, ClassFunc
,