Easy GUI System

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)