EnableExplicit Prototype.s AngleGadgetLabel(State.i) Structure AngleGadgetData State.i Min.i Max.i Flags.i Ticks.i NullTick.f Range.f MinorTicks.i MajorTicks.i Change.i CenterX.i CenterY.i Radius.i MajorLabel.AngleGadgetLabel EndStructure Structure AngleGadgetConstant FaceColor.l TextColor.l ShadowColor.l HighlightColor.l FontID.i EndStructure Global AngleGadgetConstant.AngleGadgetConstant With AngleGadgetConstant CompilerIf #PB_Compiler_OS = #PB_OS_Windows \FaceColor = GetSysColor_(#COLOR_3DFACE)|$FF<<24 \TextColor = GetSysColor_(#COLOR_WINDOWTEXT)|$FF<<24 \ShadowColor = GetSysColor_(#COLOR_3DSHADOW)|$FF<<24 \HighlightColor = GetSysColor_(#COLOR_3DHIGHLIGHT)|$FF<<24 CompilerElse \FaceColor = $FFD0D0D0 \TextColor = $FF000000 \ShadowColor = $FF808080 \HighlightColor = $FFFFFFFF CompilerEndIf \FontID = FontID(LoadFont(#PB_Any, "Arial", 8)) EndWith #PB_DefaultColor = -$100000000 #TwoPI = #PI*2.0 #HalfPI = #PI*0.5 Enumeration #True #AngleGadget_MinorTicks #AngleGadget_MajorTicks #AngleGadget_Orientation #AngleGadget_Length #AngleGadget_MajorLabel EndEnumeration Procedure.i AngleGadget_Normalize(Value.i, Min.i, Max.i) Value - Min : Value % (Max-Min) If Value < 0 : ProcedureReturn Value+Max : Else : ProcedureReturn Value+Min : EndIf EndProcedure Procedure.f AngleGadget_NormalizeF(Value.f, Max.f) Value = Mod(Value, Max) If Value < 0 : ProcedureReturn Value+Max : Else : ProcedureReturn Value : EndIf EndProcedure Procedure AngleGadget_LineRA(X.i, Y.i, Radius1.f, Angle1.f, Radius2.f, Angle2.f, Color.q=#PB_DefaultColor) If Color = #PB_DefaultColor LineXY(Cos(Angle1)*Radius1+X, Sin(Angle1)*Radius1+Y, Cos(Angle2)*Radius2+X, Sin(Angle2)*Radius2+Y) Else LineXY(Cos(Angle1)*Radius1+X, Sin(Angle1)*Radius1+Y, Cos(Angle2)*Radius2+X, Sin(Angle2)*Radius2+Y, Color) EndIf EndProcedure Procedure DrawAngleGadget(Gadget.i) Protected *AngleGadgetData.AngleGadgetData = GetGadgetData(Gadget) Protected Tick.i, Angle.f, Radius.i, Text.s, X.i, Y.i, State.i Protected DeltaAngle.f = #PI*0.75, Color.i, MinorTicks.i Protected TextX.i, TextWidth.i, MaxTextWidth.i, MinTextWidth.i Protected TextY.i, TextHeight.i, MaxTextHeight.i, MinTextHeight.i Protected MinRadiusX.f=Infinity(), MaxRadiusX.f=-Infinity(), RadiusX.f Protected MinRadiusY.f=Infinity(), MaxRadiusY.f=-Infinity(), RadiusY.f With *AngleGadgetData If StartDrawing(CanvasOutput(Gadget)) DrawingMode(#PB_2DDrawing_Transparent) DrawingFont(AngleGadgetConstant\FontID) If \Range = #TwoPI MinorTicks = \MinorTicks-1 Else MinorTicks = \MinorTicks EndIf For Tick = 0 To MinorTicks Angle = Tick / \MinorTicks * \Range + \NullTick If \MajorLabel State = Tick*\Ticks/\MinorTicks+\Min If (Tick*\MajorTicks)%\MinorTicks = 0 TextWidth = TextWidth(\MajorLabel(State)) TextHeight = TextHeight(\MajorLabel(State)) TextX = -TextWidth*(1-Cos(Angle))*0.5 TextY = -TextHeight*(1-Sin(Angle))*0.5 If TextX+TextWidth > MaxTextWidth MaxTextWidth = TextX+TextWidth EndIf If TextX < MinTextWidth MinTextWidth = TextX EndIf If TextY+TextHeight > MaxTextHeight MaxTextHeight = TextY+TextHeight EndIf If TextY < MinTextHeight MinTextHeight = TextY EndIf EndIf EndIf RadiusX = Cos(Angle) RadiusY = Sin(Angle) If RadiusX > MaxRadiusX MaxRadiusX = RadiusX EndIf If RadiusX < MinRadiusX MinRadiusX = RadiusX EndIf If RadiusY > MaxRadiusY MaxRadiusY = RadiusY EndIf If RadiusY < MinRadiusY MinRadiusY = RadiusY EndIf Next RadiusX = (OutputWidth()-8+MinTextWidth-MaxTextWidth)/(MaxRadiusX-MinRadiusX) RadiusY = (OutputHeight()-8+MinTextHeight-MaxTextHeight)/(MaxRadiusY-MinRadiusY) If RadiusX < RadiusY : Radius = RadiusX : Else : Radius = RadiusY : EndIf \Radius = Radius \CenterX = (OutputWidth()-MinTextWidth-MaxTextWidth-(MinRadiusX+MaxRadiusX)*Radius)/2 \CenterY = (OutputHeight()-MinTextHeight-MaxTextHeight-(MinRadiusY+MaxRadiusY)*Radius)/2 Box(0, 0, OutputWidth(), OutputHeight(), AngleGadgetConstant\FaceColor) For Tick = 0 To MinorTicks Angle = Tick / \MinorTicks * \Range + \NullTick State = Tick*\Ticks/\MinorTicks+\Min If (Tick*\MajorTicks)%\MinorTicks = 0 AngleGadget_LineRA(\CenterX, \CenterY, Radius-2, Angle, Radius-11, Angle, AngleGadgetConstant\TextColor) If \MajorLabel Text = \MajorLabel(State) X = \CenterX + Cos(Angle)*Radius - TextWidth(Text)*(1-Cos(Angle))*0.5 Y = \CenterY + Sin(Angle)*Radius - TextHeight(Text)*(1-Sin(Angle))*0.5 DrawText(X, Y, Text, AngleGadgetConstant\TextColor) EndIf Else AngleGadget_LineRA(\CenterX, \CenterY, Radius-2, Angle, Radius-5, Angle, AngleGadgetConstant\TextColor) EndIf Next Angle = (\State-\Min) / \Ticks * \Range + \NullTick If Angle < 0 Or Angle => #PI Color = AngleGadgetConstant\ShadowColor Else Color = AngleGadgetConstant\HighlightColor EndIf AngleGadget_LineRA(\CenterX, \CenterY, Radius*0.3, Angle-DeltaAngle, Radius*0.3, Angle+DeltaAngle, Color) If Angle < #HalfPI Or Angle => #PI+#HalfPI Color = AngleGadgetConstant\ShadowColor Else Color = AngleGadgetConstant\HighlightColor EndIf AngleGadget_LineRA(\CenterX, \CenterY, Radius-14, Angle, Radius*0.3, Angle+DeltaAngle, Color) If Angle < #TwoPI-#HalfPI And Angle => #PI-#HalfPI Color = AngleGadgetConstant\ShadowColor Else Color = AngleGadgetConstant\HighlightColor EndIf AngleGadget_LineRA(\CenterX, \CenterY, Radius-14, Angle, Radius*0.3, Angle-DeltaAngle, Color) StopDrawing() EndIf EndWith EndProcedure Procedure AngleGadget(Gadget.i, X.i, Y.i, Width.i, Height.i, Min.i, Max.i) Protected GadgetFlags = #PB_Canvas_GrabMouse|#PB_Canvas_Keyboard|#PB_Canvas_DrawFocus Protected *AngleGadgetData.AngleGadgetData = AllocateMemory(SizeOf(AngleGadgetData)) If IsGadget(Gadget) And GetGadgetData(Gadget) FreeMemory(GetGadgetData(Gadget)) EndIf If Gadget = #PB_Any Gadget = CanvasGadget(Gadget, X, Y, Width, Height, GadgetFlags) Else CanvasGadget(Gadget, X, Y, Width, Height, GadgetFlags) EndIf SetGadgetData(Gadget, *AngleGadgetData) With *AngleGadgetData \Min = Min \Max = Max \Ticks = \Max-\Min \Range = #TwoPI \NullTick = \Min/(\Max-\Min)*\Range \MinorTicks = \Ticks \MajorTicks = 1 EndWith DrawAngleGadget(Gadget) ProcedureReturn Gadget EndProcedure Procedure.i AngleGadgetEvent(Gadget.i, EventType.i) Protected *AngleGadgetData.AngleGadgetData = GetGadgetData(Gadget) Protected X.i, Y.i, Angle.f, State.i With *AngleGadgetData State = \State Select EventType Case #PB_EventType_MouseWheel If \Range = #TwoPI \State = AngleGadget_Normalize(\State+GetGadgetAttribute(Gadget, #PB_Canvas_WheelDelta), \Min, \Max) Else \State + GetGadgetAttribute(Gadget, #PB_Canvas_WheelDelta) If \State < \Min : \State = \Min : ElseIf \State > \Max : \State = \Max : EndIf EndIf DrawAngleGadget(Gadget) Case #PB_EventType_KeyDown Select GetGadgetAttribute(Gadget, #PB_Canvas_Key) Case #PB_Shortcut_Up, #PB_Shortcut_Right If \Range = #TwoPI \State = AngleGadget_Normalize(\State+1, \Min, \Max) Else \State + 1 If \State > \Max : \State = \Max : EndIf EndIf DrawAngleGadget(Gadget) Case #PB_Shortcut_Down, #PB_Shortcut_Left If \Range = #TwoPI \State = AngleGadget_Normalize(\State-1, \Min, \Max) Else \State - 1 If \State < \Min : \State = \Min : EndIf EndIf DrawAngleGadget(Gadget) EndSelect Case #PB_EventType_LeftButtonDown X = GetGadgetAttribute(Gadget, #PB_Canvas_MouseX) - \CenterX Y = GetGadgetAttribute(Gadget, #PB_Canvas_MouseY) - \CenterY If Sqr(X*X+Y*Y) < \Radius \Change = #True EndIf Case #PB_EventType_LeftButtonUp \Change = #False EndSelect If \Change Select EventType Case #PB_EventType_LeftButtonDown, #PB_EventType_MouseMove X = GetGadgetAttribute(Gadget, #PB_Canvas_MouseX) - \CenterX Y = GetGadgetAttribute(Gadget, #PB_Canvas_MouseY) - \CenterY Angle = ATan2(X, Y) If \Range = #TwoPI \State = AngleGadget_Normalize(\Ticks*(Angle-\NullTick)/\Range+\Min, \Min, \Max) Else Angle = AngleGadget_NormalizeF(Angle-\NullTick+(#TwoPI-\Range)*0.5, #TwoPI)-(#TwoPI-\Range)*0.5 \State = \Ticks*Angle/\Range + \Min If \State < \Min : \State = \Min : ElseIf \State > \Max : \State = \Max : EndIf EndIf EndSelect EndIf If State <> \State DrawAngleGadget(Gadget) ProcedureReturn #True EndIf EndWith EndProcedure Procedure SetAngleGadgetAttribute(Gadget.i, Attribute.i, Value.i) Protected *AngleGadgetData.AngleGadgetData = GetGadgetData(Gadget) Protected OldNullTick.f With *AngleGadgetData Select Attribute Case #AngleGadget_MinorTicks \MinorTicks = Value Case #AngleGadget_MajorTicks \MajorTicks = Value Case #AngleGadget_Orientation \NullTick = Radian(Value) Case #AngleGadget_Length \Range = Radian(Value) Case #AngleGadget_MajorLabel \MajorLabel = Value EndSelect EndWith DrawAngleGadget(Gadget) EndProcedure Procedure SetAngleGadgetState(Gadget.i, State.i) Protected *AngleGadgetData.AngleGadgetData = GetGadgetData(Gadget) With *AngleGadgetData \State = AngleGadget_Normalize(State, \Min, \Max) EndWith DrawAngleGadget(Gadget) EndProcedure Procedure GetAngleGadgetState(Gadget.i) Protected *AngleGadgetData.AngleGadgetData = GetGadgetData(Gadget) With *AngleGadgetData ProcedureReturn \State EndWith EndProcedure ;- Beispiel Enumeration #Window #AngleGadget0 #AngleGadget1 #AngleGadget2 #AngleGadget3 #AngleGadget4 #AngleGadget5 EndEnumeration Procedure.s MyLabel2(State.i) ProcedureReturn " "+Str(State*5)+"°" EndProcedure Procedure.s MyLabel3(State.i) ProcedureReturn Str(State*5)+"%" EndProcedure Procedure.s MyLabel4(State.i) ProcedureReturn Str(State*5) EndProcedure Procedure.s MyLabel5(State.i) Select State Case -100 : ProcedureReturn "kalt" Case 100 : ProcedureReturn "warm" EndSelect EndProcedure OpenWindow(#Window, 0, 0, 640, 480, "ColorGadget", #PB_Window_MinimizeGadget|#PB_Window_ScreenCentered) Frame3DGadget(#PB_Any, 5, 5, 140, 150, "Standard (geschlossen)") AngleGadget(#AngleGadget1, 10, 20, 130, 130, 0, 24) Frame3DGadget(#PB_Any, 155, 5, 210, 220, "geschlossen + Beschriftung + Drehung") AngleGadget(#AngleGadget2, 160, 20, 200, 200, 0, 72) SetAngleGadgetAttribute(#AngleGadget2, #AngleGadget_Orientation, -90) SetAngleGadgetAttribute(#AngleGadget2, #AngleGadget_MajorTicks, 12) SetAngleGadgetAttribute(#AngleGadget2, #AngleGadget_MajorLabel, @MyLabel2()) Frame3DGadget(#PB_Any, 375, 5, 160, 170, "geöffne + Beschr. + Drehung") AngleGadget(#AngleGadget3, 380, 20, 150, 150, 0, 20) SetAngleGadgetAttribute(#AngleGadget3, #AngleGadget_Orientation, 120) SetAngleGadgetAttribute(#AngleGadget3, #AngleGadget_Length, 300) SetAngleGadgetAttribute(#AngleGadget3, #AngleGadget_MajorTicks, 5) SetAngleGadgetAttribute(#AngleGadget3, #AngleGadget_MajorLabel, @MyLabel3()) Frame3DGadget(#PB_Any, 155, 235, 410, 180, "der Platz wird immer optimal ausnutzt") AngleGadget(#AngleGadget4, 160, 250, 400, 160, -20, 20) SetAngleGadgetAttribute(#AngleGadget4, #AngleGadget_Length, 90) SetAngleGadgetAttribute(#AngleGadget4, #AngleGadget_Orientation, 225) SetAngleGadgetAttribute(#AngleGadget4, #AngleGadget_MajorTicks, 8) SetAngleGadgetAttribute(#AngleGadget4, #AngleGadget_MajorLabel, @MyLabel4()) Frame3DGadget(#PB_Any, 5, 165, 140, 250, "weiteres Beispiel") AngleGadget(#AngleGadget5, 10, 180, 130, 230, -100, 100) SetAngleGadgetAttribute(#AngleGadget5, #AngleGadget_Orientation, 60) SetAngleGadgetAttribute(#AngleGadget5, #AngleGadget_Length, -120) SetAngleGadgetAttribute(#AngleGadget5, #AngleGadget_MinorTicks, 20) SetAngleGadgetAttribute(#AngleGadget5, #AngleGadget_MajorTicks, 2) SetAngleGadgetAttribute(#AngleGadget5, #AngleGadget_MajorLabel, @MyLabel5()) Repeat Select WaitWindowEvent() Case #PB_Event_CloseWindow End Case #PB_Event_Gadget Select EventGadget() Case #AngleGadget0, #AngleGadget1,#AngleGadget2,#AngleGadget3,#AngleGadget4,#AngleGadget5 If AngleGadgetEvent(EventGadget(), EventType()) Debug GetAngleGadgetState(EventGadget()) EndIf EndSelect EndSelect ForEver ; IDE Options = PureBasic 4.60 Beta 3 (Windows - x86) ; CursorPosition = 317 ; FirstLine = 337 ; EnableXP