Verteilungs "Gadget" für Screens
Verfasst: 20.03.2007 16:38
So, ich möchte euch ein Stück Code vorstellen, das ich für mein Projektchen geschrieben habe.
Ich hoffe das der Name nicht zu exotisch gewählt ist.
Es geht darum, 100% auf verschiedene Blöcke aufzuteilen. Die Balkenlänge kann für ein "Gadget" mit der Maus gesetzt werden. Die jeweils anderen passen sich dann an. Man kann zwischen gleichmässiger oder proportionaler Anpassung wählen.
So, noch ein Bild:

Ich hoffe der Code ist ansonsten halbwegs leserlich (auch wenn sie manche über die vielen Falten wundern - mir hilfts den Überblick über den Code zu bewahren - ihr könnt ja die anderen löschen...
)
Würde mich ansonsten über Rückmeldungen freuen.
Ich hoffe das der Name nicht zu exotisch gewählt ist.
Es geht darum, 100% auf verschiedene Blöcke aufzuteilen. Die Balkenlänge kann für ein "Gadget" mit der Maus gesetzt werden. Die jeweils anderen passen sich dann an. Man kann zwischen gleichmässiger oder proportionaler Anpassung wählen.
So, noch ein Bild:
Ich hoffe der Code ist ansonsten halbwegs leserlich (auch wenn sie manche über die vielen Falten wundern - mir hilfts den Überblick über den Code zu bewahren - ihr könnt ja die anderen löschen...

Würde mich ansonsten über Rückmeldungen freuen.
Code: Alles auswählen
; Distribution-gadgets
; coded 2007 by Dostej
; published under the LGPL
; What does it do
; You can create some grouped Progressbar-like "gadgets" for a screen enviroment
; Each group has together a max value of 100.
; If you change one gadget, the others of this group change their values, too
Structure VTGdgt
Number_L.l
Group_L.l
X_Pos_L.l
Y_Pos_L.l
Width_L.l
Height_L.l
Value_L.l
ImageNr_L.l
EndStructure
Global NewList DSTGadget.VTGdgt()
Global DSTGadget_Mode_GL.l = 1 ; mode 0: equal Mode 1: proportional
Global MouseX_GL.l
Global MouseY_GL.l
Global MouseButton_GL.l
Procedure Free_DSTGadget(Number_L.l) ; free the gadget
ForEach DSTGadget()
If DSTGadget()\Number_L = Number_L
DeleteElement(DSTGadget())
EndIf
Next
EndProcedure
Procedure Create_DSTGadget(Number_L.l, Group_L.l, X_Pos_L.l, Y_Pos_L.l, Width_L.l, Height_L.l, ImageNr_L.l) ; create a new VT gadget
; free an other gadget with the same number
Free_DSTGadget(Number_L)
AddElement(DSTGadget())
With DSTGadget()
\Number_L = Number_L
\Group_L = Group_L
\X_Pos_L = X_Pos_L
\Y_Pos_L = Y_Pos_L
\Width_L = Width_L
\Height_L = Height_L
\Value_L = 0
\ImageNr_L = ImageNr_L
EndWith
EndProcedure
Procedure Draw_DSTGadgets() ; Draw all DST-gadgets
If StartDrawing(ScreenOutput())
With DSTGadget()
ForEach DSTGadget()
DrawingMode(#PB_2DDrawing_Outlined)
Box(\X_Pos_L, \Y_Pos_L, \Width_L, \Height_L, $FFFF00) ; #Col_Gadget_Text)
; draw the image depending on the value given
w = ((\Width_L-2) * \Value_L) / 100
If w > 0
DrawImage(ImageID(\ImageNr_L), \X_Pos_L + 1, \Y_Pos_L + 1, w, \Height_L - 2)
EndIf
Next
EndWith
StopDrawing()
EndIf
EndProcedure
Procedure Distribute_DSTGadgets(Group_L.l, Number_L.l, Diff_L.l) ; distribute the Difference to all gadgets but the "number_L" one
a = 0
With DSTGadget()
;{ count how many gadgets are in this group
ForEach DSTGadget()
If \Group_L = Group_L
If \Number_L <> Number_L
a + 1
Else
Value = \Value_L
EndIf
EndIf
Next
a-1
;}
If a > -1 ; if at least one other gadget
;{ shuffle all elements of these group in an array
Dim Temp.POINT(a)
Count_L = 0
Sum_L = 0
ForEach DSTGadget()
If \Group_L = Group_L And \Number_L <> Number_L
Temp(Count_L)\x = @DSTGadget()
Temp(Count_L)\y = \Value_L
Sum_L + \Value_L
Count_L + 1
EndIf
Next
;}
;{ Distribute the difference
; equal
If DSTGadget_Mode_GL = 1
; proportional
If Sum_L > 0
f.f = Diff_L / Sum_L
For x = 0 To a
Temp(x)\y + (Temp(x)\y * f)
Next
Else ; if all other values are 0 -> distribute equal
Mode = 1
EndIf
EndIf
If DSTGadget_Mode_GL = 0 Or Mode = 1
Rest = Diff_L
Repeat
; calc one share
d = Int(Rest / (a+1))
Rest = 0
For x = 0 To a
If Temp(x)\y >= d Or d > 0
n = d
Else
n = Temp(x)\y
EndIf
Temp(x)\y + n
Rest + (d - n)
Next
Until Rest = 0
EndIf
;}
;{ check for value of 100
n = -100 + Value
For x = 0 To a
n + Temp(x)\y
Next
If n <> 0
x = Random(a)
Repeat
If n > 0
If Temp(x)\y > 0
Temp(x)\y - 1
n - 1
EndIf
Else
If Temp(x)\y < 100
Temp(x)\y + 1
n + 1
EndIf
EndIf
x + 1
If x > a
x = 0
EndIf
Until n = 0
EndIf
;}
;{ wrote the values back to the LL
For x = 0 To a
ChangeCurrentElement(DSTGadget(), Temp(x)\x)
\Value_L = Temp(x)\y
Next
;}
EndIf
EndWith
EndProcedure
Procedure.l GetValue_DSTGadget(Number_L.l) ; returns the value of the gadget
Back_L.l
ForEach DSTGadget()
If DSTGadget()\Number_L = Number_L
Back_L = DSTGadget()\Value_L
Break
EndIf
Next
ProcedureReturn Back_L
EndProcedure
Procedure.l SetValue_DSTGadget(Number_L.l, Value_L.l) ; set the value of the gadget and change the other ones
Back_L.l
ForEach DSTGadget()
If DSTGadget()\Number_L = Number_L
If Value_L < 0
Value_L = 0
ElseIf Value_L > 100
Value_L = 100
EndIf
Diff_L = DSTGadget()\Value_L - Value_L
DSTGadget()\Value_L = Value_L
Distribute_DSTGadgets(DSTGadget()\Group_L, Number_L, Diff_L)
Break
EndIf
Next
ProcedureReturn Back_L
EndProcedure
Procedure.l DSTGadgetEvents() ; handle Mouseevents with the DSTGadgets, returns the number of the DSTGadget currently klicked
Back_L.l = -1
; check which Gadget is clicked and set the new value
With DSTGadget()
ForEach DSTGadget()
If MouseX_GL >= \X_Pos_L And MouseX_GL <= \X_Pos_L + \Width_L
If MouseY_GL >= \Y_Pos_L And MouseY_GL <= \Y_Pos_L + \Height_L
If MouseButton_GL ; if left or right button was pressed
Back_L = \Number_L
t = ((MouseX_GL - \X_Pos_L) * 100) / \Width_L
Diff_L = \Value_L - t ; calc the difference
\Value_L = t
Group_L = \Group_L
Number_L = \Number_L
Break
EndIf
EndIf
EndIf
Next
If Back_L <> -1 And Diff_L <> 0 ; a gadget was klicked - set the other values
Distribute_DSTGadgets(Group_L, Number_L, Diff_L)
EndIf
EndWith
ProcedureReturn Back_L
EndProcedure
If InitSprite() = 0 Or InitKeyboard() = 0 Or InitMouse()= 0
MessageRequester("Fehler", "init")
End
EndIf
If OpenWindow(1, 0, 0, 1024, 768, "", #PB_Window_BorderLess)
If OpenWindowedScreen(WindowID(1), 0, 0, 1024, 768, 0, 0, 0)
; create a mouse
If CreateSprite(0, 8, 8)
If StartDrawing(SpriteOutput(0))
Circle(4, 4, 4, $FFFF80)
StopDrawing()
EndIf
EndIf
If CreateImage(1, 198, 18)
If StartDrawing(ImageOutput(1))
Box(0, 0, 198, 18, $0080FF)
StopDrawing()
EndIf
EndIf
Create_DSTGadget(1, 1, 100, 200, 200, 20, 1)
Create_DSTGadget(2, 1, 100, 230, 200, 20, 1)
Create_DSTGadget(3, 1, 100, 260, 200, 20, 1)
Create_DSTGadget(4, 1, 100, 290, 200, 20, 1)
ForEach DSTGadget()
DSTGadget()\Value_L = 25
Next
;{ Eventloop
Repeat ; Start of the event loop
ClearScreen(0)
ExamineMouse()
MouseX_GL = MouseX()
MouseY_GL = MouseY()
MouseButton_GL = MouseButton(1) | MouseButton(2)<<1
GadgetClicked = DSTGadgetEvents() ; handles the gadgets
If GadgetClicked > -1
; show all values
Debug "used gadget: " + Str(GadgetClicked) + " new values"
ForEach DSTGadget()
Debug DSTGadget()\Value_L
Next
EndIf
Draw_DSTGadgets()
DisplaySprite(0, MouseX_GL, MouseY_GL)
FlipBuffers(0)
Delay(30)
ExamineMouse()
Until Event = #PB_Event_CloseWindow Or MouseButton(2) ; End of the event loop
;}
EndIf
EndIf