Difference between revisions of "Easy GUI System"
(Rewrite to be more concise and mature. Additionally, add note that I'm considering maintaining this again.) |
|||
(One intermediate revision by one other user not shown) | |||
Line 1: | Line 1: | ||
− | + | Easy GUI System is an easy-to-use GUI system made by [https://github.com/ashleydavies Ashley Davies]. It is available on its [https://github.com/ashleydavies/EGS/ Github page]. EGS is not currently maintained, but functions on the current versions of LÖVE, thanks to contributions by buckle2000 on GitHub. Ashley is considering maintaining, tidying, and expanding on this library. If you would like for this to happen, please see further detail on the GitHub page for the repository. | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
__TOC__ | __TOC__ | ||
Line 17: | Line 6: | ||
= General tutorial = | = General tutorial = | ||
− | == Class.lua | + | == Class.lua == |
− | My class system is | + | My class system is simple to use. The following few tutorials will teach you the basics. |
=== Defining a class === | === Defining a class === | ||
Line 26: | Line 15: | ||
Class "ClassName" {Properties} | Class "ClassName" {Properties} | ||
</source> | </source> | ||
− | + | Here we have a basic class called 'ClassName'. It has a property called "Properties", with a default value of an empty string (We didn't give it a default value). | |
Line 37: | Line 26: | ||
} | } | ||
</source> | </source> | ||
− | + | Here's another basic class. It just creates a class with two properties. | |
− | |||
=== Defining a class with multiple properties with default values === | === Defining a class with multiple properties with default values === | ||
Line 48: | Line 36: | ||
} | } | ||
</source> | </source> | ||
− | To give a property a default value, | + | To give a property a default value, make it a key instead of a value, as above, and give it a value of the default value. Default values can be any type. |
− | |||
− | Default values can be | ||
− | |||
− | |||
− | + | === Instantiating a class === | |
<source lang="lua"> | <source lang="lua"> | ||
Line 64: | Line 48: | ||
ClassName:new("InstanceName") | ClassName:new("InstanceName") | ||
+ | |||
print(InstanceName.Property1) | print(InstanceName.Property1) | ||
− | |||
>7 | >7 | ||
</source> | </source> | ||
− | As you can see | + | |
+ | As you can see, we pass in the names, rather than getting a return value, so we do the above, as opposed to: | ||
<source lang="lua"> | <source lang="lua"> | ||
Line 77: | Line 62: | ||
InstanceName = ClassName:new() | InstanceName = ClassName:new() | ||
</source> | </source> | ||
− | The class function makes use of the | + | |
+ | The class function makes use of the `getfenv()` function, which allows it to define variables in the calling environment. Classes are not local variables, they are global. So are instances. | ||
Line 89: | Line 75: | ||
ClassName:new("InstanceName") | ClassName:new("InstanceName") | ||
− | InstanceName.Property2 = " | + | InstanceName.Property2 = "Hello world" |
− | print("InstanceName1 says: "..InstanceName.Property2) | + | print("InstanceName1 says: " .. InstanceName.Property2) |
ClassName:new("InstanceName2") | ClassName:new("InstanceName2") | ||
− | print("InstanceName2 says: "..InstanceName2.Property2) | + | print("InstanceName2 says: " .. InstanceName2.Property2) |
− | >InstanceName1 says: | + | >InstanceName1 says: Hello world |
>InstanceName2 says: | >InstanceName2 says: | ||
</source> | </source> | ||
− | + | ||
+ | If no default is set, a class property will get a default value of an empty string, instead of nil, so it won't error if you try to concatenate it. | ||
=== Inheriting properties === | === Inheriting properties === | ||
Line 103: | Line 90: | ||
<source lang="lua"> | <source lang="lua"> | ||
Class "ClassName" { | Class "ClassName" { | ||
− | [" | + | ["val"] = true, |
} | } | ||
Line 112: | Line 99: | ||
ClassName2:new("InstanceName") | ClassName2:new("InstanceName") | ||
− | print(tostring(InstanceName. | + | print(tostring(InstanceName.val)) |
>true | >true | ||
</source> | </source> | ||
Line 132: | Line 119: | ||
<source lang="lua"> | <source lang="lua"> | ||
− | Class "cName" {["Prop1"] = " | + | Class "cName" {["Prop1"] = "val1"} |
− | Class "cName2" ({["Prop1"] = " | + | Class "cName2" ({["Prop1"] = "val2"}, {cName}) |
</source> | </source> | ||
− | + | It inherits from an object with a property the same, the second class (cName2)'s Prop1 will become it's default, as it overrides the inherited value. | |
− | So if I instanced "cName", and printed it's Prop1, it'd print | + | So if I instanced "cName", and printed it's Prop1, it'd print val1, but doing the same to cName2 would print val2. This mean you can make classes that inherit the majority of things from another, but change or completely destroy (just set it to nil) some, you can. |
− | === End | + | === End note === |
− | |||
− | |||
+ | You can get by without understanding this object system, so long as you understand the examples below. | ||
== Using my GUI library == | == Using my GUI library == | ||
− | By now you should be familiar with | + | By now you should be familiar with the class system. |
My GUI library classes are organised into two sections: Structural and Non-Structural classes. | My GUI library classes are organised into two sections: Structural and Non-Structural classes. | ||
Line 154: | Line 140: | ||
=== Events === | === Events === | ||
− | Events | + | Events behave identically to those found on [[http://roblox.com Roblox]]. |
<source lang="lua"> | <source lang="lua"> | ||
Object.Event:connect(function) | Object.Event:connect(function) | ||
Line 170: | Line 156: | ||
=== What are Structural Classes? === | === What are Structural Classes? === | ||
− | In | + | In this library, structural classes are classes whose only purpose is for other classes to inherit from. They are not all entirely documented as they should not be instanced. |
− | |||
− | |||
=== What are Non-Structural Classes? === | === What are Non-Structural Classes? === | ||
Non-Structural classes are things like [[#Checkbox|Checkboxes.]] You can instance them, and they are mainly GUI items. | Non-Structural classes are things like [[#Checkbox|Checkboxes.]] You can instance them, and they are mainly GUI items. | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
= Examples = | = Examples = | ||
− | |||
− | |||
== Buttons == | == Buttons == | ||
Line 208: | Line 168: | ||
=== Making a TextLabel appear when a Button is hovered === | === Making a TextLabel appear when a Button is hovered === | ||
− | Note that since TextLabel only | + | Note that since TextLabel only loses the events 'mouseClicked', 'mousePressed', and 'mouseReleased', but not 'mouseEntered' and 'mouseExited', it's possible to do this with two TextLabels with identical results. However TextLabels were not made to be functional so it's not recommended. |
First we need a TextLabel and a TextButton. Put these lines in love.load: | First we need a TextLabel and a TextButton. Put these lines in love.load: | ||
Line 244: | Line 204: | ||
</source> | </source> | ||
− | Now if we run that, it's a functional example! | + | Now if we run that, it's a functional example! |
− | + | It is straightforward, as EGS was made to be easy, and achieves this while maintaining a good range of customisability. For example, the shading when you hover on the button can be turned off by just adding: | |
− | |||
− | |||
<source lang="lua"> | <source lang="lua"> | ||
Line 256: | Line 214: | ||
=== Making a button respond to hovering === | === Making a button respond to hovering === | ||
− | In this tutorial we'll make a button respond to hovering. The | + | In this tutorial we'll make a button respond to hovering. The purpose is to explore more properties of GUI elements. For example, all three color properties (textColor, borderColor, backgroundColor) are just a table with three values in, {R, G, B}, for example, {255, 0, 0} represents pure red. |
I recommend you set the window backgroundColor to white for this tutorial! (love.graphic.setBackgroundColor(255,255,255)) | I recommend you set the window backgroundColor to white for this tutorial! (love.graphic.setBackgroundColor(255,255,255)) | ||
Line 268: | Line 226: | ||
TB.size = {100,20} | TB.size = {100,20} | ||
TB.position = {10,10} | TB.position = {10,10} | ||
− | TB.backgroundColor = {0,200,255} | + | TB.backgroundColor = {0,200,255} |
− | + | --Aligns text to center on Y and X axis. | |
+ | TB:centerText() | ||
</source> | </source> | ||
− | + | Let's mix it up a little. | |
<source lang="lua"> | <source lang="lua"> | ||
Line 285: | Line 244: | ||
</source> | </source> | ||
− | + | It looks much nicer with the thinner border! We'll now try changing the color a little. Replace those two events you did with this: | |
<source lang="lua"> | <source lang="lua"> | ||
Line 315: | Line 274: | ||
end) | end) | ||
</source> | </source> | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
=== Making a TextLabel with a message when you hover === | === Making a TextLabel with a message when you hover === | ||
− | + | It's simple to achieve this, as ALL GUIElements have this feature, called ''Caption''. | |
− | |||
− | It's | ||
<source lang="lua"> | <source lang="lua"> | ||
Line 359: | Line 303: | ||
<source lang="lua"> | <source lang="lua"> | ||
− | |||
--Will wait 3 seconds of mouse hovering to display caption. | --Will wait 3 seconds of mouse hovering to display caption. | ||
+ | TL:setSecondsForCaption(3) | ||
</source> | </source> | ||
[[Category: Libraries]] | [[Category: Libraries]] | ||
+ | {{#set:Name=Easy GUI System (EGS)}} | ||
+ | {{#set:LOVE Version=0.10.x}} | ||
+ | {{#set:Description=EGS is a simple GUI system with events and multiple controls, without over-complicating things.}} | ||
+ | {{#set:Keyword=GUI}} |
Latest revision as of 18:19, 17 August 2016
Easy GUI System is an easy-to-use GUI system made by Ashley Davies. It is available on its Github page. EGS is not currently maintained, but functions on the current versions of LÖVE, thanks to contributions by buckle2000 on GitHub. Ashley is considering maintaining, tidying, and expanding on this library. If you would like for this to happen, please see further detail on the GitHub page for the repository.
General tutorial
Class.lua
My class system is simple to use. The following few tutorials will teach you the basics.
Defining a class
Class "ClassName" {Properties}
Here we have a basic class called 'ClassName'. It has a property called "Properties", with a default value of an empty string (We didn't give it a default value).
Defining a class with multiple properties
Class "ClassName" {
Property1,
Property2,
}
Here's another basic class. It just creates a class with two properties.
Defining a class with multiple properties with default values
Class "ClassName" {
["Property1"] = 7,
Property2,
}
To give a property a default value, make it a key instead of a value, as above, and give it a value of the default value. Default values can be any type.
Instantiating a class
Class "ClassName" {
["Property1"] = 7,
Property2,
}
ClassName:new("InstanceName")
print(InstanceName.Property1)
>7
As you can see, we pass in the names, rather than getting a return value, so we do the above, as opposed to:
ClassName = Class {
["Property1"] = 7,
Property2,
}
InstanceName = ClassName:new()
The class function makes use of the `getfenv()` function, which allows it to define variables in the calling environment. Classes are not local variables, they are global. So are instances.
Creating multiple intances of a class
Class "ClassName" {
["Property1"] = 7,
Property2,
}
ClassName:new("InstanceName")
InstanceName.Property2 = "Hello world"
print("InstanceName1 says: " .. InstanceName.Property2)
ClassName:new("InstanceName2")
print("InstanceName2 says: " .. InstanceName2.Property2)
>InstanceName1 says: Hello world
>InstanceName2 says:
If no default is set, a class property will get a default value of an empty string, instead of nil, so it won't error if you try to concatenate it.
Inheriting properties
Class "ClassName" {
["val"] = true,
}
Class "ClassName2" ({
["Property1"] = 7,
Property2,
}, {ClassName})
ClassName2:new("InstanceName")
print(tostring(InstanceName.val))
>true
To inherit, instead of typing
Class "cName" {Properties}
We type
Class "cName" ({Properties}, {Which classes to inherit from})
As it's a table you can inherit from multiple classes.
If you have the same property in both classes, for example
Class "cName" {["Prop1"] = "val1"}
Class "cName2" ({["Prop1"] = "val2"}, {cName})
It inherits from an object with a property the same, the second class (cName2)'s Prop1 will become it's default, as it overrides the inherited value.
So if I instanced "cName", and printed it's Prop1, it'd print val1, but doing the same to cName2 would print val2. This mean you can make classes that inherit the majority of things from another, but change or completely destroy (just set it to nil) some, you can.
End note
You can get by without understanding this object system, so long as you understand the examples below.
Using my GUI library
By now you should be familiar with the class system.
My GUI library classes are organised into two sections: Structural and Non-Structural classes.
Events
Events behave identically to those found on [Roblox].
Object.Event:connect(function)
For example:
CheckBox:new("Checkbox1")
Checkbox1.checkStateChanged:connect(function()
print("Checkbox1's state was changed by the :changeState() function. It fires on mouse click automatically but can be fired manually.")
end)
What are Structural Classes?
In this library, structural classes are classes whose only purpose is for other classes to inherit from. They are not all entirely documented as they should not be instanced.
What are Non-Structural Classes?
Non-Structural classes are things like Checkboxes. You can instance them, and they are mainly GUI items.
Examples
Buttons
Making a TextLabel appear when a Button is hovered
Note that since TextLabel only loses the events 'mouseClicked', 'mousePressed', and 'mouseReleased', but not 'mouseEntered' and 'mouseExited', it's possible to do this with two TextLabels with identical results. However TextLabels were not made to be functional so it's not recommended.
First we need a TextLabel and a TextButton. Put these lines in love.load:
TextButton:new("HoverButton")
TextLabel:new("Display")
Now that we've got them we can define some variables. Also put these lines below the ones you just did in love.load:
HoverButton.text = "Hover me to see the TextLabel."
HoverButton.autoSize = false
HoverButton.size = {100,20}
HoverButton:centerText()--Aligns text to center on Y and X axis.
HoverButton.hasBorder = false
Display.text = ":o"
Display.visible = false
Display.size = {100,20}
Display:centerText()
Display.position = {0,20}
Display.hasBorder = false
Now we need #Events. These are also in love.load.
HoverButton.mouseEntered:connect(function()
Display.visible = true
end)
HoverButton.mouseExited:connect(function()
Display.visible = false
end)
Now if we run that, it's a functional example!
It is straightforward, as EGS was made to be easy, and achieves this while maintaining a good range of customisability. For example, the shading when you hover on the button can be turned off by just adding:
HoverButton.hasShading = false
Making a button respond to hovering
In this tutorial we'll make a button respond to hovering. The purpose is to explore more properties of GUI elements. For example, all three color properties (textColor, borderColor, backgroundColor) are just a table with three values in, {R, G, B}, for example, {255, 0, 0} represents pure red.
I recommend you set the window backgroundColor to white for this tutorial! (love.graphic.setBackgroundColor(255,255,255))
First we make the button and initialise some values:
TextButton:new("TB")
TB.text = "Hover me!"
TB.autoSize = false
TB.size = {100,20}
TB.position = {10,10}
TB.backgroundColor = {0,200,255}
--Aligns text to center on Y and X axis.
TB:centerText()
Let's mix it up a little.
TB.hasShading = false --Get rid of shading.
TB.borderWidth = 1 --Make the border thinner.
TB.mouseEntered:connect(function()
TB.borderWidth = 2
end)
TB.mouseExited:connect(function()
TB.borderWidth = 1
end)
It looks much nicer with the thinner border! We'll now try changing the color a little. Replace those two events you did with this:
TB.mouseEntered:connect(function()
TB.borderWidth = 2
TB.backgroundColor = {0,150,255} --Less green!
end)
TB.mouseExited:connect(function()
TB.borderWidth = 1
TB.backgroundColor = {0,200,255} --Back to skyblue.
end)
Getting better, but still not perfect. How about making the borderColor and textColors change too?
TB.mouseEntered:connect(function()
TB.borderWidth = 2
TB.backgroundColor = {0,150,255} --Less green!
TB.textColor = {50,100,50}
TB.borderColor = TB.textColor
end)
TB.mouseExited:connect(function()
TB.borderWidth = 1
TB.backgroundColor = {0,200,255} --Back to skyblue.
TB.textColor = {0,0,0}
TB.borderColor = TB.textColor
end)
Making a TextLabel with a message when you hover
It's simple to achieve this, as ALL GUIElements have this feature, called Caption.
TextLabel:new("TL")
TL.text = "Hover me!"
TL.autoSize = false
TL.size = {100,20}
TL.position = {10,10}
TL.backgroundColor = {0,200,255}
TL:centerText()
TL.hasShading = false
TL.borderWidth = 1
We're going to stick with the nice style we made in the last tutorial. But we need a few more variables for a caption. Add this:
TL.hasCaption = true
TL.caption = "This is a caption!"
Execute it, and huzzah!
If you want the caption to come up quicker or slower, there's a neat function for that, add this just below TL.caption = "This is a caption!":
--Will wait 3 seconds of mouse hovering to display caption.
TL:setSecondsForCaption(3)