How to code sliders in Hollywood using Hollywood’s Layer Engine
a week ago @Bugala requested me informations about some Hollywood libraries I’m working on, he was willing to support my work (thank you Bugala!) and he also asked for something able to handle sliders using layers for his own purposes.
He also asked me to share this work with all of you so that every one can benefit from it.
So LSliders library was born.
WHAT IS LSliders?
LSliders is an include file with no dependancies that uses layers to implement horizontal and vertical sliders with custom graphics, it is particularly useful in games that use the Hollywood’s Layer Engine.
To achieve the requested features I’ve first splitted the slider object in small units, these units are:
– Background : it is a background layer showing the slider’s body
– Cursor : it is the slider’s handle layer that the user can drag with his mouse to change the slider position/value.
– BackLayer : it is an additional layer in the back of the other two that is used to apply a color gradient which hilight the area between the beginning of the slider and the cursor position.
This is particularly useful with sliders that have a background with transparent areas, this third item is optional.
Here is a screenshot of the test program included with the library:
CODING THE LIBRARY
I’ve built this library creating an object called LSlider, basically it is a table with all possible values defined as default values, it also includes all needed methods to interact with it.
There is another table used by this library named LSliders, it holds the subtable List with all the defined sliders, and it also holds a couple of global functions that will be used to handle the slider’s events.
When the user creates a new LSlider object with the LSlider:New(args) method, the code duplicates the default object (and all its methods) and initialize the arguments specified in the args table.
In this phase all the involved layers will be created and showed on the screen.
To handle the events I have attached to each slider’s layer a button using MakeButton() and the #LAYERBUTTON type, this way moving the layer will automatically move the attached button; this is particularly useful to manage the cursor’s handle.
The nice part was to code the cursor’s ‘dragging’ action!
Here is a brief chart of my implementation:
Initially the CURSOR is in NORMAL state -- The mouse goes over the cursor CURSOR get the HILIGHTED state -- The left mouse button is pressed >> A dragging action begins -- The left mouse button is released >> The dragging action ends -- The mouse goes outside the cursor CURSOR get the NORMAL state
But how to handle the dragging?
Well, when I detect a left mouse click over the slider’s handle I start an interval function that will monitor the mouse position (every 15ms) to check if we need to update the handle’s position and the slider’s value.
This interval function also checks the left mouse button and if it is still down continue to monitor otherwise (if released) clear the interval function that has called itself.
Also the OnMouseUp event attached to the handle layer will do the same.
Those two does not interfere each other because the slider state changes from “hilighted” to “dragging” and vice-versa.
Ok, that’s basically how I have implemented the slider object.
The rest is just math to calculate the cursor position, to setup the slider scale, and so on.
The source code includes tons of comments.
The very last thing is that I also listen for the Backgrund layer events (I created a button on it) but I do nothing with them, it is just a placeholder for future extensions, for example to change the slider value clicking on the left or on the right of the handle, or to hilight the background when the mouse goes over it.
HOW TO GET THE SLIDER VALUE?
Suppose you have created a slider and you have stored the new object in the mySliderObject variable.
There are two ways to read the current value, the first one is to attach a callback function at creation time that will be called whenever the slider value changes, the callback function will receive the slider object as unique argument so the only thing you have to do is to read the mySliderObject.Value field.
In the included example you can see in details how it works.
The second way is to read at your will the mySliderObject.Value field directly.
Anywhere you need to show a slider using the Hollywood’s Layer Engine.
WHAT LSliders offers
Here are all methods and functions available:
- LSlider:New(args) Create a new slider object (SliderObj) - SliderObj:Decrease(v) Decrease the slider's value - SliderObj:Free() Free all slider's resources - SliderObj:Increase(v) Increase the slider's value - SliderObj:Move(x, y, r) Move the slider object - SliderObj:SetValue(v) Set the slider's value - SliderObj:Update() Update slider state (used internally)
- Sliders.HandleDragging(m) Used internally to handle the dragging event - Sliders.HandleEvents(m) Used internally to handle the slider's events
ABOUT THE INCLUDED EXAMPLE
Included in the archive you will find an example, the one that produces the screenshot you have seen at the beginning of this post.
The example is plenty of comments, have a look at it and if something is not clear just ask.
Here I will explain only a generic usage.
To build a slider you have to call:
Local mySlider = LSliders:New(args)
args is a table you have to fill with all the needed informations to build the slider, you will get the new slider object in mySlider.
From now on you can intercat with the slider using the returned object, for example if you want to set the value of your new object you have to:
mySlider:SetValue(v) ; where 'v' is your new value
The :Increase() and :Deacrese() methods are particularly useful if you whan to add a [+] and [-] buttons to let the user to interact with the slider without moving the cursor, maybe if you want to give the user more precision increasing the slider value by 0.01 unit.
Click here to download the LSliders library and the included example.
That’s all for now!
Please download the archive and have a look at the code :
- Something isn’t clear? Let me know!
- Did you found a bug? Let me know!
- Do you want to support what I do on Patreon? Don’t say a word: I do like surprises