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
;
314 ULONG type
, redraw
= 0, ho
, vo
;
315 LONG tmp
, val
, omin
= 0, omax
= 0, olev
= 0, oldtop
= 0, oldtot
= 0, oldvis
= 0;
316 BOOL fc
= !(pd
->pd_Flags
& PDF_READY
);
317 WORD dis
= GADGET(obj
)->Flags
& GFLG_DISABLED
;
321 * First we let the superclass do it's thing.
323 AsmDoSuperMethodA(cl
, obj
, (Msg
)opu
);
326 * Make sure we stay GACT_RELVERIFY.
328 GADGET(obj
)->Activation
|= GACT_RELVERIFY
;
330 if (pd
->pd_Flags
& PDF_SLIDER
)
339 oldtot
= pd
->pd_Total
;
340 oldvis
= pd
->pd_Visible
;
344 * Let's see if we need to change
345 * some known attributes ourselves.
347 while ((tag
= NextTagItem(&tstate
)))
361 pd
->pd_Visible
= data
;
365 if (data
== FREEHORIZ
) pd
->pd_Flags
|= PDF_PROPHORIZ
;
366 else pd
->pd_Flags
&= ~PDF_PROPHORIZ
;
370 if (data
) pd
->pd_Flags
|= PDF_ARROWS
;
371 else pd
->pd_Flags
&= ~PDF_ARROWS
;
375 pd
->pd_ArrowSize
= data
;
391 if (data
) data
= FRTYPE_XEN_BUTTON
;
392 else data
= FRTYPE_BUTTON
;
397 if (data
) data
= FRTYPE_NONE
;
398 else data
= FRTYPE_BUTTON
;
402 DoMultiSet(FRM_Type
, data
, 3, bc
->bc_Frame
, pd
->pd_Arrow1
, pd
->pd_Arrow2
);
407 case SLIDER_ThinFrame
:
409 DoMultiSet(FRM_ThinFrame
, data
, 3, bc
->bc_Frame
, pd
->pd_Arrow1
, pd
->pd_Arrow2
);
414 case GA_BottomBorder
:
417 DoMultiSet(tag
->ti_Tag
, data
, 4, pd
->pd_Arrow1
, pd
->pd_Arrow2
, pd
->pd_Knob
, pd
->pd_Prop
);
421 DoSetMethodNG(bc
->bc_Frame
, FRM_Type
, FRTYPE_BORDER
, FRM_EdgesOnly
, TRUE
, TAG_DONE
);
423 DoSetMethodNG(pd
->pd_Arrow1
, BT_FrameObject
, NULL
,
424 SYSIA_Which
, (pd
->pd_Flags
& PDF_PROPHORIZ
) ? LEFTIMAGE
: UPIMAGE
, TAG_DONE
);
426 DoSetMethodNG(pd
->pd_Arrow2
, BT_FrameObject
, NULL
,
427 SYSIA_Which
, (pd
->pd_Flags
& PDF_PROPHORIZ
) ? RIGHTIMAGE
: DOWNIMAGE
, TAG_DONE
);
432 case BT_ParentWindow
:
434 DoMultiSet(tag
->ti_Tag
, data
, 3, pd
->pd_Arrow1
, pd
->pd_Arrow2
, pd
->pd_Knob
);
439 if (pd
->pd_Flags
& PDF_SLIDER
)
444 if (pd
->pd_Min
> pd
->pd_Max
)
447 pd
->pd_Min
= pd
->pd_Max
;
452 * Calculate the absolute difference between min and max.
454 pd
->pd_Total
= pd
->pd_Max
- pd
->pd_Min
+ 1;
462 pd
->pd_Max
= max(pd
->pd_Total
- pd
->pd_Visible
, 0);
467 if (val
< pd
->pd_Min
) val
= pd
->pd_Min
;
468 else if (val
> pd
->pd_Max
) val
= pd
->pd_Max
;
470 if (pd
->pd_Flags
& PDF_SLIDER
)
475 * Check if any of these values changed.
477 if ((pd
->pd_Min
!= omin
) || (pd
->pd_Max
!= omax
) || (pd
->pd_Level
!= olev
))
478 redraw
= GREDRAW_UPDATE
;
485 * Check if any of these values changed.
487 if ((pd
->pd_Top
!= oldtop
) || (pd
->pd_Total
!= oldtot
) || (pd
->pd_Visible
!= oldvis
))
488 redraw
= GREDRAW_UPDATE
;
493 Get_Attr(bc
->bc_Frame
, FRM_Type
, &data
);
499 if (GADGET(obj
)->Activation
& (GACT_LEFTBORDER
|GACT_RIGHTBORDER
)) { ho
= 4; vo
= 1; };
500 if (GADGET(obj
)->Activation
& (GACT_TOPBORDER
|GACT_BOTTOMBORDER
)) { ho
= 2; vo
= 2; };
501 DoSetMethodNG(bc
->bc_Frame
, FRM_Type
, FRTYPE_NONE
, TAG_DONE
);
504 Get_Attr(bc
->bc_Frame
, FRM_ThinFrame
, &data
);
509 DoSuperSetMethodNG(cl
, obj
, BT_LeftOffset
, ho
, BT_RightOffset
, ho
,
510 BT_TopOffset
, vo
, BT_BottomOffset
, vo
, TAG_DONE
);
512 redraw
= GREDRAW_REDRAW
;
516 if (pd
->pd_Flags
& PDF_READY
)
519 * Disable state changed?
521 if ((GADGET(obj
)->Flags
& GFLG_DISABLED
) != dis
)
522 redraw
= GREDRAW_REDRAW
;
525 * Re-render the gadget.
527 if (redraw
) DoRenderMethod(obj
, opu
->opu_GInfo
, redraw
);
530 * Notify our target if the
533 if (pd
->pd_Flags
& PDF_SLIDER
)
535 type
= (pd
->pd_Level
!= olev
) ? SLIDER_Level
: 0;
539 type
= (pd
->pd_Top
!= oldtop
) ? PGA_Top
: 0;
542 if (type
) DoNotifyMethod(obj
, opu
->opu_GInfo
, opu
->MethodID
== OM_UPDATE
? opu
->opu_Flags
: 0,
543 GA_ID
, GADGET(obj
)->GadgetID
, type
, val
, TAG_DONE
);
553 METHOD(PropClassRender
, struct bmRender
*, bmr
)
555 PD
*pd
= INST_DATA(cl
, obj
);
556 BC
*bc
= BASE_DATA(obj
);
557 struct BaseInfo
*bi
= bmr
->bmr_BInfo
;
558 struct RastPort
*rp
= bi
->bi_RPort
;
561 * Render the baseclass.
563 AsmDoSuperMethodA(cl
, obj
, (Msg
)bmr
);
568 CalcPropMuck(cl
, obj
, bi
);
571 * Complete re-render?
573 if (bmr
->bmr_Flags
== GREDRAW_REDRAW
)
576 * Render the arrow images.
578 if (pd
->pd_Flags
& PDF_ARROWS
)
580 AsmDoMethod(pd
->pd_Arrow1
, GM_RENDER
, bi
, rp
, GREDRAW_REDRAW
);
581 AsmDoMethod(pd
->pd_Arrow2
, GM_RENDER
, bi
, rp
, GREDRAW_REDRAW
);
585 * Then the slider body.
587 AsmDoMethod(pd
->pd_Prop
, GM_RENDER
, bi
, rp
, GREDRAW_REDRAW
);
594 if (pd
->pd_Flags
& PDF_LEFT_UP
)
595 AsmDoMethod(pd
->pd_Arrow1
, GM_RENDER
, bi
, rp
, GREDRAW_REDRAW
);
596 else if (pd
->pd_Flags
& PDF_RIGHT_DOWN
)
597 AsmDoMethod(pd
->pd_Arrow2
, GM_RENDER
, bi
, rp
, GREDRAW_REDRAW
);
600 * Only re-render the slider when it isn't active.
602 if (!(pd
->pd_Flags
& PDF_PROPACTIVE
))
603 AsmDoMethod(pd
->pd_Prop
, GM_RENDER
, bi
, rp
, GREDRAW_UPDATE
);
607 * Ghost the gadget hitbox when it is disabled.
609 if (GADGET(obj
)->Flags
& GFLG_DISABLED
)
611 BDisableBox(bi
, &bc
->bc_HitBox
);
612 if (pd
->pd_Arrow1
) BDisableBox(bi
, GADGETBOX(pd
->pd_Arrow1
));
613 if (pd
->pd_Arrow2
) BDisableBox(bi
, GADGETBOX(pd
->pd_Arrow2
));
621 * They want to know something.
623 METHOD(PropClassGet
, struct opGet
*, opg
)
625 PD
*pd
= INST_DATA(cl
, obj
);
627 IPTR
*store
= opg
->opg_Storage
;
629 switch (opg
->opg_AttrID
)
632 STORE (pd
->pd_Flags
& PDF_PROPHORIZ
) ? FREEHORIZ
: FREEVERT
;
652 rc
= AsmDoSuperMethodA(cl
, obj
, (Msg
)opg
);
661 * Where we hit and if so, what was hit.
663 METHOD(PropClassHitTest
, struct gpHitTest
*, gph
)
665 PD
*pd
= INST_DATA(cl
, obj
);
666 BC
*bc
= BASE_DATA(obj
);
670 * Calculate absolute click position.
672 WORD l
= GADGETBOX(obj
)->Left
+ gph
->gpht_Mouse
.X
;
673 WORD t
= GADGETBOX(obj
)->Top
+ gph
->gpht_Mouse
.Y
;
675 if (PointInBox(&bc
->bc_HitBox
, l
, t
))
678 * Did they click inside the
679 * proportional gadget?
681 rc
= ForwardMsg(obj
, pd
->pd_Prop
, (Msg
)gph
);
683 if (rc
== GMR_GADGETHIT
) pd
->pd_Flags
|= PDF_PROPACTIVE
;
686 if (!rc
&& pd
->pd_Arrow1
)
689 * Clicked in the left/up arrow?
691 rc
= ForwardMsg(obj
, pd
->pd_Arrow1
, (Msg
)gph
);
693 if (rc
== GMR_GADGETHIT
) pd
->pd_Flags
|= PDF_LEFT_UP
;
696 if (!rc
&& pd
->pd_Arrow2
)
699 * Clicked in the down/right arrow?
701 rc
= ForwardMsg(obj
, pd
->pd_Arrow2
, (Msg
)gph
);
703 if (rc
== GMR_GADGETHIT
) pd
->pd_Flags
|= PDF_RIGHT_DOWN
;
706 if (rc
== GMR_GADGETHIT
)
708 pd
->pd_Reset1
= pd
->pd_Top
;
709 pd
->pd_Reset2
= pd
->pd_Level
;
716 STATIC ASM VOID
NotifyChange(REG(a0
) Class
*cl
, REG(a2
) Object
*obj
, REG(a1
) struct gpInput
*gpi
, REG(d0
) ULONG flags
)
718 PD
*pd
= INST_DATA(cl
, obj
);
720 LONG val
, oldval
= (pd
->pd_Flags
& PDF_SLIDER
) ? pd
->pd_Level
: pd
->pd_Top
;
726 Get_Attr(pd
->pd_Prop
, PGA_Top
, &tmp
);
729 if (pd
->pd_Flags
& PDF_SLIDER
)
734 if (pd
->pd_Flags
& PDF_PROPHORIZ
) val
= pd
->pd_Min
+ val
;
735 else val
= pd
->pd_Max
- val
;
749 if ((flags
== OPUF_INTERIM
) && (val
== oldval
)) return;
751 DoNotifyMethod(obj
, gpi
->gpi_GInfo
, flags
, GA_ID
, GADGET(obj
)->GadgetID
, type
, val
, TAG_DONE
);
755 * Adjust knob position in
756 * whatever direction necessary.
758 STATIC ASM VOID
AdjustKnob(REG(a0
) Class
*cl
, REG(a2
) Object
*obj
, REG(a1
) struct gpInput
*gpi
)
760 PD
*pd
= INST_DATA(cl
, obj
);
761 LONG top
, total
= max(pd
->pd_Total
- pd
->pd_Visible
, 0);
764 Get_Attr(pd
->pd_Prop
, PGA_Top
, &tmp
);
767 if (pd
->pd_Flags
& PDF_LEFT_UP
)
771 else if (pd
->pd_Flags
& PDF_RIGHT_DOWN
)
776 if ((top
>= 0) && (top
<= total
))
778 DoSetMethod(pd
->pd_Prop
, gpi
->gpi_GInfo
, PGA_Top
, top
, TAG_DONE
);
779 NotifyChange(cl
, obj
, gpi
, 0L);
785 METHOD(PropClassGoActive
, struct gpInput
*, gpi
)
787 PD
*pd
= INST_DATA(cl
, obj
);
789 ULONG rc
= GMR_NOREUSE
;
792 * We do not go active when we are disabled or was activated
793 * by Activate gadget.
795 if ((GADGET(obj
)->Flags
& GFLG_DISABLED
) || (!gpi
->gpi_IEvent
))
797 pd
->pd_Flags
&= ~(PDF_PROPACTIVE
|PDF_LEFT_UP
|PDF_RIGHT_DOWN
);
802 * Let the superclass have a go...
804 AsmDoSuperMethodA(cl
, obj
, (Msg
)gpi
);
807 * Is the proportional gadget active?
809 if (pd
->pd_Flags
& PDF_PROPACTIVE
)
812 * If so adjust the click
813 * coordinates and route the
814 * message to the proportional gadget.
816 rc
= ForwardMsg(obj
, pd
->pd_Prop
, (Msg
)gpi
);
818 if (rc
& GMR_VERIFY
) NotifyChange(cl
, obj
, gpi
, 0);
820 else if (pd
->pd_Flags
& (PDF_LEFT_UP
|PDF_RIGHT_DOWN
))
823 * Clear timer threshold.
828 * Adjust knob and notify when the knob position changed.
830 AdjustKnob(cl
, obj
, gpi
);
833 * Route the message to the button gadget.
835 arrow
= (pd
->pd_Flags
& PDF_LEFT_UP
) ? pd
->pd_Arrow1
: pd
->pd_Arrow2
;
836 rc
= ForwardMsg(obj
, arrow
, (Msg
)gpi
);
846 METHOD(PropClassHandleInput
, struct gpInput
*, gpi
)
848 PD
*pd
= INST_DATA(cl
, obj
);
851 ULONG rc
= GMR_MEACTIVE
;
854 * Calculate absolute click position.
856 l
= GADGETBOX(obj
)->Left
+ gpi
->gpi_Mouse
.X
;
857 t
= GADGETBOX(obj
)->Top
+ gpi
->gpi_Mouse
.Y
;
860 * Is the proportional gadget active?
862 if (pd
->pd_Flags
& PDF_PROPACTIVE
)
865 * Right mouse button pressed?
867 if (gpi
->gpi_IEvent
->ie_Class
== IECLASS_RAWMOUSE
&& gpi
->gpi_IEvent
->ie_Code
== MENUDOWN
)
870 * Yep. Say we need to reset to
873 pd
->pd_Flags
|= PDF_RESET
;
877 * If so adjust the click
878 * coordinates and rout the
879 * message to the proportional gadget.
881 rc
= ForwardMsg(obj
, pd
->pd_Prop
, (Msg
)gpi
);
883 NotifyChange(cl
, obj
, gpi
, (rc
== GMR_MEACTIVE
) ? OPUF_INTERIM
: 0);
887 arrow
= (pd
->pd_Flags
& PDF_LEFT_UP
) ? pd
->pd_Arrow1
: pd
->pd_Arrow2
;
890 * Check if the mouse is
891 * still over the active arrow.
893 if (PointInBox(GADGETBOX(arrow
), l
, t
))
899 if (gpi
->gpi_IEvent
->ie_Class
== IECLASS_RAWMOUSE
)
901 switch (gpi
->gpi_IEvent
->ie_Code
)
905 * They released the left
908 rc
= GMR_NOREUSE
| GMR_VERIFY
;
911 * Unselect the arrow.
918 * Terminate when they press the menubutton.
921 pd
->pd_Flags
|= PDF_RESET
;
926 else if (gpi
->gpi_IEvent
->ie_Class
== IECLASS_TIMER
)
929 * On every timer event we
930 * increase or decrease the knob
936 * We delay with adjusting the knob position for a little while just
937 * like the key-repeat threshold. Probably should use the system prefs
938 * for determing the delay but this is _so_ much easier.
940 if (pd
->pd_RptTicks
> 3)
943 * Adjust knob and notify when the knob position changed.
945 AdjustKnob(cl
, obj
, gpi
);
950 * Increase repeat treshold.
958 * When the selected state
959 * changed show it visually.
961 if ((GADGET(arrow
)->Flags
& GFLG_SELECTED
) != sel
)
964 * Flip selected bit and re-render.
966 GADGET(arrow
)->Flags
^= GFLG_SELECTED
;
967 DoRenderMethod(arrow
, gpi
->gpi_GInfo
, GREDRAW_REDRAW
);
978 METHOD(PropClassGoInActive
, struct gpGoInactive
*, ggi
)
980 PD
*pd
= INST_DATA(cl
, obj
);
984 * Is the proportional gadget
987 if (pd
->pd_Flags
& PDF_PROPACTIVE
)
990 * If so route the message to
991 * the proportional gadget and
992 * mark it as not active.
994 AsmDoMethodA(pd
->pd_Prop
, (Msg
)ggi
);
998 * Un-activate our arrows and let the super
999 * class see what it can do with this message.
1001 pd
->pd_Flags
&= ~(PDF_LEFT_UP
|PDF_RIGHT_DOWN
|PDF_PROPACTIVE
);
1002 rc
= AsmDoSuperMethodA(cl
, obj
, (Msg
)ggi
);
1005 * Reset to the initial value when necessary.
1007 if (pd
->pd_Flags
& PDF_RESET
)
1009 DoSetMethod(obj
, ggi
->gpgi_GInfo
, PGA_Top
, pd
->pd_Reset1
, SLIDER_Level
, pd
->pd_Reset2
, TAG_DONE
);
1010 pd
->pd_Flags
&= ~PDF_RESET
;
1018 * Find out our minumum size.
1020 METHOD(PropClassDimensions
, struct bmDimensions
*, bmd
)
1022 PD
*pd
= INST_DATA(cl
, obj
);
1023 BC
*bc
= BASE_DATA(obj
);
1024 BOOL vborder
= GADGET(obj
)->Activation
& (GACT_LEFTBORDER
|GACT_RIGHTBORDER
);
1025 BOOL hborder
= GADGET(obj
)->Activation
& (GACT_TOPBORDER
|GACT_BOTTOMBORDER
);
1026 BOOL horiz
= pd
->pd_Flags
& PDF_PROPHORIZ
;
1027 int arrowsize
= pd
->pd_ArrowSize
;
1030 if (pd
->pd_Flags
& PDF_ARROWS
)
1034 if (vborder
) arrowsize
= 11;
1035 else if (hborder
) arrowsize
= 16;
1036 else arrowsize
= horiz
? 10 : 9;
1038 pd
->pd_ArrowSize
= arrowsize
;
1040 DoSetMethodNG(bc
->bc_Frame
, horiz
? FRM_OuterOffsetRight
: FRM_OuterOffsetBottom
, arrowsize
<< 1, TAG_DONE
);
1044 * Add these to the superclass results.
1046 rc
= CalcDimensions(cl
, obj
, bmd
, 8+(horiz
? arrowsize
*2 : 0), 8+(horiz
? 0 : arrowsize
*2 ));
1048 if (vborder
) bmd
->bmd_Extent
->be_Min
.Width
= bmd
->bmd_Extent
->be_Nom
.Width
= 18;
1049 if (hborder
) bmd
->bmd_Extent
->be_Min
.Height
= bmd
->bmd_Extent
->be_Nom
.Height
= 10;
1057 * Dispose of ourselves.
1059 METHOD(PropClassDispose
, Msg
, msg
)
1061 PD
*pd
= INST_DATA(cl
, obj
);
1064 * Dispose of the allocated objects.
1066 if (pd
->pd_Arrow1
) DisposeObject(pd
->pd_Arrow1
);
1067 if (pd
->pd_Arrow2
) DisposeObject(pd
->pd_Arrow2
);
1068 if (pd
->pd_Prop
) DisposeObject(pd
->pd_Prop
);
1069 if (pd
->pd_Knob
) DisposeObject(pd
->pd_Knob
);
1071 return AsmDoSuperMethodA(cl
, obj
, msg
);
1077 * We are activated by the keyboard.
1079 METHOD(PropClassKeyActive
, struct wmKeyInput
*, wmki
)
1081 PD
*pd
= ( PD
* )INST_DATA( cl
, obj
);
1082 UWORD qual
= wmki
->wmki_IEvent
->ie_Qualifier
, code
= wmki
->wmki_IEvent
->ie_Code
;
1083 BOOL sl
= pd
->pd_Flags
& PDF_SLIDER
;
1084 LONG otop
= sl
? pd
->pd_Level
: pd
->pd_Top
, ntop
= otop
;
1085 LONG inc
= pd
->pd_Visible
- 1;
1087 if (inc
< 1) inc
= 1;
1092 if (qual
& (IEQUALIFIER_LSHIFT
|IEQUALIFIER_RSHIFT
))
1094 if (ntop
> pd
->pd_Min
) ntop
-= inc
;
1095 if (ntop
< pd
->pd_Min
) ntop
= pd
->pd_Min
;
1099 if (ntop
< pd
->pd_Max
) ntop
+= inc
;
1100 if (ntop
> pd
->pd_Max
) ntop
= pd
->pd_Max
;
1104 * Did the top position change?
1106 if ((ntop
!= otop
) && !(code
& IECODE_UP_PREFIX
))
1109 * Let the slider know about this change.
1111 DoSetMethod(obj
, wmki
->wmki_GInfo
, sl
? SLIDER_Level
: PGA_Top
, ntop
, TAG_END
);
1113 * Skip the ID because the notification
1114 * will handle the change.
1118 * Tell then to ignore this message.
1120 *(wmki
->wmki_ID
) = WMHI_IGNORE
;
1127 /// Class initialization,
1129 * Class function table.
1131 STATIC DPFUNC ClassFunc
[] = {
1132 { BASE_RENDER
, PropClassRender
, },
1133 { BASE_DIMENSIONS
, PropClassDimensions
, },
1135 { OM_NEW
, PropClassNew
, },
1136 { OM_SET
, PropClassSetUpdate
, },
1137 { OM_UPDATE
, PropClassSetUpdate
, },
1138 { OM_GET
, PropClassGet
, },
1139 { OM_DISPOSE
, PropClassDispose
, },
1140 { GM_HITTEST
, PropClassHitTest
, },
1141 { GM_HANDLEINPUT
, PropClassHandleInput
, },
1142 { GM_GOACTIVE
, PropClassGoActive
, },
1143 { GM_GOINACTIVE
, PropClassGoInActive
, },
1144 { WM_KEYACTIVE
, PropClassKeyActive
, },
1149 * Class initialization.
1151 makeproto Class
*InitPropClass(void)
1153 return BGUI_MakeClass(CLASS_SuperClassBGUI
, BGUI_BASE_GADGET
,
1154 CLASS_ObjectSize
, sizeof(PD
),
1155 CLASS_DFTable
, ClassFunc
,