@Andreas, Problem is that I am trying to make a Slider Button that I wouldn't need to worry about much.
Right now I cant figure out a way where I could use NIL for it, which means that I need to keep track of button IDs one way or other, to not accidentally using same ID for two buttons.
Idea is following (didnt test code, just wrote here)
Code: Select all
SliderButtonID
Function NewSliderButton(SliderX, SliderY, SliderW, SliderH)
SliderButtonID = MakeButton(NIL, #SIMPLEBUTTON, sliderX, SliderY, SliderW, SliderH, {OnMouseDown = Function()
SetInterval = (1, OnContinousMouseDown)
EndFunction)
Return(SliderButtonID)
EndFunction
Function OnContinuousMouseDown()
SliderX = MouseX
SliderY = MouseY
If IsMouseDown() = False
ClearInterval(1)
MakeButton(NIL, #SIMPLEBUTTON, SliderX, SliderY, SliderW, SliderH, {OnMouseDown = Function()
SetInterval = (1, OnContinousMouseDown)
EndFunction)
EndIf
EndFunction
ID = NewSliderButton(100, 100, 200, 200)
SetInterval(2, function()
if IsRightMouseDown() = True then DeleteButton(ID)
EndFunction)
Repeat
WaitEvent()
Forever
This isnt enough in reality, but gives you the idea.
Now problem is, I want to delete that Slider Button, if Right mouse button is clicked (just example, not reality), But how do I know its ID, if I used NIL to create it, I don't.
problem here is that when I move sliders positions, buttons position will change too. Since I used #SIMPLEBUTTON option, it means that after Sliders position have changed, the button is in wrong place.
Therefore when I stop moving the slider button, I have to also delete the current button, and create new #SIMPLEBUTTON to new location, or otherwise button is in wrong place.
This once again alone isnt the problem, but problem is that when I use NIL to create a button, I also want to create that ID to the program flow, to be later used to Delete that button.
And this is where the problem comes. When I finally push that rightmouse button, there is already new NIL button created, with new address, and when I use DeleteBuotton, it wont work since that button was already deleted long ago.
Only way I can keep track of that button, is by using Numbers, which means that I then need to keep track of all the button numbers.
Notice also that this isnt a problem if I use Layers On approach, since then the buttons location moves as the layer moves, but since I am doing this without Layers, this is a problem, as I can only use #SIMPLEBUTTON option to create buttons, and therefore, every time location of that button changes, I have to recreate that #SIMPLEBUTTON.
Another solution to this problem would be if I could somehow change #SIMPLEBUTTONS location on the fly. Since instead of recreating the button, I could instead just change its X and Y location, but I couldn't figure out a way to do that.
In case you want to check the real case, here is copy-paste of the current version. However, notice this is not the final version yet. I am planning on putting the final version here to forum, but this is its current state:
Code: Select all
/*
BUTTONS How to use:
there is more specific explanation for each Button type (currently SLIDERBUTTON and CHECKBOXBUTTON)
NOTICE: For each button you need to send a table that contains the buttons specifically named variable.
As Example: varTable.SliderVar
same table could contain Variables for more than one button type:
Example: VarTable = {SliderVar, CheckBoxVar}
however, each Table can contain only one Variable of each type. If you want to have two different Sliders, you need two different Tables both containing SliderVar in them.
This is due to a limit in Hollywood in that you cant send reference of a variable to a function.
You however can get around this by sending a table containing a variable into a function, since when you send a table, it will send a reference to a table.
Therefore touching variables inside that table reference will do same as having sent a reference to a variable had done, meaning that if you change the value of variable SliderVar inside Sliderbutton, it will also change the value of the variable SliderVar in the original table. (or technically speaking, only the original tables SliderVar ever changes, since Sliderbuttons SliderVar is only a reference to that one)
For Buttons to draw themselves, you need to do something like:
SetInterval(1, Function()
Cls(0)
Buttons.Draw(Buttons)
EndFunction, 10)
Repeat
It is currently assumed you will simply get rid of all buttons at once one way or other yourself, therefore there are no functions which would delete button or even keep track of them.
There is however an option to empty the list to stop drawing all the buttons: Buttons.EmptyList
SLIDERBUTTON: (VarTable, X, Y, SliderBrushID, ButtonID, OptionalArguments)
VarTable - Contains variable SliderVar inside it, ie. MyTbl.SliderVar
X and Y - normally BGBrush X and Y, but if there is no BGBrush, then Sliders X and Y without taking into consideration XOffset or YOffset or Sliders current position.
SliderBrushID - ID of the Brush to use for Slider image.
ButtonID - ID to be used for the Button that is going to be created now, notice that you cant use NIL for this in Sliders case, this is due to Slider recreating new button each time slider is moved for buttons location to change, and Hollywood doesnt let you use NILs userdata for new buttons ID, therefore in current system I couldnt figure out a sensible way to keep track of NIL id.
OptionalArguments:
SliderXMinXOffset, how much + or - will Slider X be able to go from the beginning (usually from BGBrush) - if not using BGBrush, then this in practice decides how much SliderX can move
SliderXMaxXOffset, how much + or - will Slider X be able to go from the end (usually from BGBrush) - of not using BGBrush, then this in practice decides how much SliderX can move
BGBrushID, If you want to use BGBrush graphics to determine where sliedr will be moving at, then use this.
SliderYRelatevitoBGBrush, this lets you set the Slider Y Relative to BGBrush, only useful if there is BGBrush, and makes it possible to have for example oversized button in Height to look properly relative to BGBrush
VariableAccuracy, usually Variables accuracy is based upon 0-100 (100), but using this accuracy can be changed to be something else from 0 to accuracy.
FuncContinuousMouseDown, this lets you set a Function that will be executed as long as left mouse is down on top of the slider.
FuncDraw, this lets you set a Function that will be executed everytime this slider is drawn - meaning in practice a function that will be executed all the time as long as the Slider exists.
To Use:
SliderButton is meant to be created in one of two ways: Either by using just the Slider, or with Slider and BGBrush.
Although OptionalArguments are Optional, in practice some of them are necessary, and necessary ones depend upon which of the before mentioned ways you are making the SliderButton.
What every SliderButton needs is following:
BeforeMentioned Table containing SliderVar variable.
X-spot you wish SliderButton to appear
Y-spot location you wish Sliderbutton to appear
Notice about X and Y-location that if BGBrush is used, then X and Y refer to X and Y location of BGBrush, not the Slider.
If no BGBrush is used, then X and Y location refer to the minimum X and Y location that Slidebutton can appear at. (notice that SliderButton will be set to the position reflecting its current valuke)
SliderBrushID, this is the Brush used for the SliderButton image, you always have to use Brush for that.
ButtonID, notice this doesnt automatically take care of the ButtonID, but you need to take care of it yourself, and sending "nil" wont work.
If using BGBrush, then only OptionalArgument needed is "BGBrushID", which will be the Brush used for Sliders Background image.
If not using BGBrush, then you have to set SliderXMinXOffset or SliderXMaxXOffset at minimum for Slider to have some movement space, otherwise Slider will be still.
CHECKBOXBUTTON: (VarTable, X, Y, OffBrushID, OnBrushID, ButtonID, OptionalArguments)
VarTable - Contains variable CheckBoxVar inside it, ie. MyTbl.CheckBoxVar
X and Y - Location where CheckboxButton when OFF/FALSE will be displayed at
OFFBrushID and ONBrushID - IDs for Brushes to use as ON/TRUE and OFF/FALSE images.
ButtonID - ID to be used for the Button that is going to be created now, you can use NIL as well to create a uniqueID which will be returned.
example: ButtonID = CheckBoxButton.New(Vartable2, 500, 400, 3, 4, 4, {})
OptionalArguments:
XOnOffSet and YOnOffSet, if these are used, then Button on "ON/TRUE" state will be displayed in location X + XOnOffSet, notice that XOnOffSet can be negative value, and usually is.
Notice also that if OffBrush and OnBrush are of different Width and/or Height, it will automatically be assumed that XOnOffSet and YOnOffSet are wanted.
This XOnOffSet value is then determined by (OnBrushWidth - OffBrushWidth) / 2, which usually results in a negative value.
If XOnOffset or YOnOffSet is determined in OptionalArguments, then these values will be used instead of the automatically calculated value.
FuncDraw, this lets you set a Function that will be executed everytime this Button is drawn - meaning in practice a function that will be executed all the time as long as the Button exists.
*/
Buttons = { List = {} }
SliderButton = {}
CheckBoxButton = {}
Function Buttons.Draw(Self)
ForEach(self.list, Function (Notused, SingleButton)
SingleButton.Draw(SingleButton)
EndFunction)
EndFunction
Function Buttons.Emptylist(self)
self.list = {}
EndFunction
Function CheckBoxButton.New(VarTable, X, Y, OffBrushID, OnBrushID, ButtonID, OptionalArguments)
Local o = {x = X, y = Y, SliderX = X, SliderY = Y, VarTable = Vartable, OffBrushID = OffBrushID, OnBrushID = OnBrushID, ButtonID = ButtonID}
If GetType(OptionalArguments) = #NIL Then OptionalArguments = {}
o.Draw = CheckBoxButton.Draw
o.Vartable = VarTable
o.OffBrushWidth = GetAttribute(#BRUSH, o.OffBrushID, #ATTRWIDTH)
o.OffBrushHeight = GetAttribute(#BRUSH, o.OffBrushID, #ATTRHEIGHT)
o.OnBrushWidth = GetAttribute(#BRUSH, o.OnBrushID, #ATTRWIDTH)
o.OnBrushHeight = GetAttribute(#BRUSH, o.OnBrushID, #ATTRHEIGHT)
Local WidthToUse = o.OffBrushWidth
Local HeightToUse = o.OffBrushHeight
If o.VarTable.CheckBoxVar = True
WidthToUse = o.OnBrushWidth
HeightToUse = o.OnBrushHeight
EndIf
o.XOnOffSet = 0
o.YOnOffSet = 0
If o.OffBrushWidth <> o.OnBrushWidth
If HasItem(OptionalArguments, "xonoffset")
o.XOnOffset = OptionalArguments.XOnOffset
Else
o.XOnOffset = (o.OffBrushWidth - o.OnBrushWidth) / 2
EndIf
EndIf
If o.OffBrushHeight <> o.OnBrushHeight
If HasItem(OptionalArguments, "yonoffset")
o.YOnOffset = OptionalArguments.YOnOffset
Else
o.YOnOffset = (o.OffBrushHeight - o.OnBrushHeight) / 2
EndIf
EndIf
If HasItem(OptionalArguments, "funcdraw") Then o.funcdraw = OptionalArguments.funcdraw
ToReturnButtonID = MakeButton(ButtonID, #SIMPLEBUTTON, o.X, o.Y, WidthToUse, HeightToUse, {OnMouseDown = Function ()
CheckBoxButton.OnMouseDown(o)
EndFunction})
If GetType(ToReturnButtonID) = #NIL
ToReturnButtonID = ButtonID
Else
o.ButtonID = ToReturnButtonID
EndIf
InsertItem(Buttons.list, o)
Return(ToReturnButtonID)
EndFunction
Function CheckBoxButton.OnMouseDown(self)
Self.Vartable.CheckBoxVar = 1 - Self.Vartable.CheckBoxVar
EndFunction
Function CheckBoxButton.Draw(self)
Local BrushIDtoDraw = self.OffBrushID
If self.Vartable.CheckBoxVar = True Then BrushIDtoDraw = self.OnBrushID
Local XtoUse = self.x
Local YtoUse = self.y
If Self.VarTable.CheckBoxVar = True
XtoUse = self.x + self.XOnOffset
YtoUse = self.y + self.YOnOffset
EndIf
DisplayBrush(BrushIDtoDraw, XtoUse, YtoUse)
If HasItem(self, "funcdraw") Then self.FuncDraw
EndFunction
Function SliderButton.New(VarTable, X, Y, SliderBrushID, ButtonID, OptionalArguments)
Local o = {x = X, y = Y, SliderX = X, SliderY = Y, VarTable = VarTable, SliderBrushID = SliderBrushID, ButtonID = ButtonID}
o.SliderWidth = GetAttribute(#BRUSH, SliderBrushID, #ATTRWIDTH)
o.SliderHeight = GetAttribute(#BRUSH, SliderBrushID, #ATTRHEIGHT)
o.SliderXMinValue = 0
o.SliderXMaxValue = o.SliderWidth
If HasItem(OptionalArguments, "bgbrushid")
o.BGBrushID = OptionalArguments.BGBrushID
o.BGBrushWidth = GetAttribute(#BRUSH, OptionalArguments.BGBrushID, #ATTRWIDTH)
o.SliderXMaxValue = o.BGBrushWidth - o.SliderWidth
EndIf
o.SliderXMinOffset = 0
o.SliderXMaxOffset = 0
If HasItem(OptionalArguments, "sliderxminoffset") Then o.SliderXMinValue = o.SliderXMinValue + OptionalArguments.SliderXMinOffset
If HasItem(OptionalArguments, "sliderxmaxoffset") Then o.SliderXMaxValue = o.SliderXMaxValue + OptionalArguments.SliderXMaxOffset
o.VariableAccuracy = 100
If HasItem(OptionalArguments, "variableaccuracy") Then o.VariableAccuracy = OptionalArguments.VariableAccuracy
Local TotalLength = o.SliderXMaxValue - o.SliderXMinValue
Local CurrentX = (TotalLength/o.VariableAccuracy) * o.VarTable.SliderVar
o.SliderX = CurrentX + o.SliderXMinvalue + o.X
If HasItem(OptionalArguments, "slideryrelativetobgbrush")
o.SliderYRelativeToBGBrush = OptionalArguments.SliderYRelativeToBGBrush
o.SliderY = o.SliderY + o.SliderYRelativeToBGBrush
EndIf
If HasItem(OptionalArguments, "funccontinuousmousedown") Then o.funccontinuousmousedown = OptionalArguments.funccontinuousmousedown
If HasItem(OptionalArguments, "funcdraw") Then o.funcdraw = OptionalArguments.funcdraw
o.Draw = SliderButton.Draw
ToReturnButtonID = MakeButton(o.ButtonID, #SIMPLEBUTTON, o.SliderX, o.SliderY, o.SliderWidth, o.SliderHeight, {OnMouseDown = Function ()
SliderButton.OnMouseDown(o)
EndFunction})
InsertItem(Buttons.list, o)
Return(ToReturnButtonID)
EndFunction
Function SliderButton.Draw(self)
If HasItem(self, "bgbrushid") Then DisplayBrush(self.BgBrushID, self.X, self.Y)
DisplayBrush(self.SliderBrushID, self.SliderX, self.SliderY)
If HasItem(self, "funcdraw") Then self.FuncDraw()
EndFunction
Function SliderButton.Update(self)
Return( Function(IntervalData)
Local MX = MouseX() - Self.MouseXEXtra
If MX < self.X + Self.SliderXMinValue Then MX = self.X + Self.SliderXMinValue
If MX > Self.X + Self.SliderXMaxValue Then MX = Self.X + Self.SliderXMaxValue
Self.SliderX = MX
Local TotalLength = Self.SliderXMaxValue - Self.SliderXMinValue
Local CurrentX = Self.SliderX - Self.X - Self.SliderXMinvalue
Self.VarTable.SliderVar = (CurrentX / TotalLength) * Self.VariableAccuracy
If HasItem(self, "funccontinuousmousedown") Then self.funccontinuousmousedown()
If IsLeftMouse() = False
ClearInterval(IntervalData.ID)
DeleteButton(Self.ButtonID)
MakeButton(Self.ButtonID, #SIMPLEBUTTON, self.SliderX, self.SliderY, Self.SliderWidth, Self.SliderHeight, {OnMouseDown = Function ()
SliderButton.OnMouseDown(self)
EndFunction})
EndIf
EndFunction )
EndFunction
Function SliderButton.OnMouseDown(Self, ButtonID)
self.MouseXExtra = MouseX() - self.SliderX
SetInterval(Nil, SliderButton.Update(self), 10)
EndFunction
CreateBrush(1, 50, 160, #RED)
CreateBrush(2, 300, 100, #BLUE)
CreateBrush(3, 100, 100, #YELLOW)
CreateBrush(4, 120, 120, #GREEN)
VarTable = {}
VarTable.SliderVar = 30
VarTable.CheckBoxVar = False
VarTable2 = {}
VarTable2.SliderVar = 10
Vartable2.CheckBoxVar = True
SliderButton.New(VarTable, 100, 100, 1, 1, {SliderXMinOffset = -20, SliderXMaxOffset = 20, BGBrushID=2, SliderYRelativeToBGBrush = -30, funcmousedown=Function() TextOut(100, 200, "Volume:"..Vartable.SliderVar) EndFunction})
CheckBoxButton.New(Vartable, 300, 400, 3, 4, 2, {})
SliderButton.New(VarTable2, 100, 250, 1, 3, {SliderXMinOffset = -20, SliderXMaxOffset = 20, BGBrushID=2, SliderYRelativeToBGBrush = -30})
CheckBoxButton.New(Vartable2, 500, 400, 3, 4, Nil, {})
SetInterval(1, Function()
Cls(0)
Buttons.Draw(Buttons)
EndFunction, 10)
Repeat
WaitEvent()
Forever