Distribution "gadgets"
Posted: Thu Mar 22, 2007 9:30 am
I hope the name fits what it does...
Its a couple of procs to create and manage some kind of "trackbargadgets", which together sums up to 100 (percent). Its not perfectly balanced, cos I use sometimes a random method to ditribute the rest...
A pic:

I hope the code is more or less understandable...
Maybe its useful for someone
Its a couple of procs to create and manage some kind of "trackbargadgets", which together sums up to 100 (percent). Its not perfectly balanced, cos I use sometimes a random method to ditribute the rest...
A pic:
I hope the code is more or less understandable...

Maybe its useful for someone
Code: Select all
; 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