Jump to content
  • entries
    4
  • comments
    2
  • views
    4,080

Adding/Using Widgets


GorzenDev

1,696 views

 Share

Previously we created a custom class and a basic GUI.
Now its time to add some basic widgets to our class and show how to use them.
 

Lets start with a simple Panel that has a Label, a TextField and a Button.

// UI_Interface.h

Widget* panel = NULL;
Widget* label = NULL;
Widget* textField = NULL;
Widget* button = NULL;


// UI_Interface.cpp

//create gui
//....
//
//panel	= Widget::Panel(guiScale * 100, guiScale * 100, guiScale * 300, guiScale * 80, gui->GetBase());
panel	= Widget::Create("", guiScale * 100, guiScale * 100, guiScale * 300, guiScale * 80, gui->GetBase(), "Scripts/GUI/Panel.lua");
//children of panel
label	= Widget::Label("label", guiScale * 15, guiScale * 15, guiScale *80, guiScale * 20, panel);
textField= Widget::TextField("text", guiScale * 15, guiScale * 35, guiScale * 150, guiScale * 20, panel);
button	= Widget::Button("button", guiScale * 175, guiScale * 10, guiScale * 80, guiScale * 20, panel);
btn_Fun	= Widget::Button("Fun", guiScale * 175, guiScale * 35, guiScale * 80, guiScale * 20, panel);

Forget about btn_Fun for now :D 
You probably noticed that Widget::Create() is used for the panel.
I did this to show you that any widget can be created by referencing the lua script path.
Even your own custom widgets, but we will come to that later.


Dont forget to release your widgets.

//UI_Interface.cpp

UI_Interface::~UI_Interface()
{
	btn_Fun->Release();
	button->Release();
	textField->Release();
	label->Release();
	panel->Release();
	gui->Release();
}


Now lets add some functionality.
Lets say we want to show our textField input in our label.

// UI_Interface.cpp

bool UI_Interface::ProcessEvent(Event event)
{
	if (event.id == Event::WidgetAction)
	{
		if (event.source == button)
		{
			string text = textField->GetText();
			label->SetText(text);
			return true;
		}
	}
	//
	return false;
}


Now we know how to create and catch widget events.
But what about those extra widget functions?
Lets delve into that now.

A widget's behaviour is represented by a lua script, much like how a entity has a script attached or like the c++ Actor class even.
It has callbacks to script functions like mouseDown(), mouseUp(), Draw() etc.
Checkout any script in the GUI folder for examples.

Lets take the Label for example, Open the file "Scripts/GUI/Label.lua".
You can see it has no real functionality other then just draw the widget Text.
But there's more to it.
Lets look at the draw function for Label.lua:

function Script:Draw(x,y,width,height)
	local gui = self.widget:GetGUI()
	local pos = self.widget:GetPosition(true)
	local sz = self.widget:GetSize(true)
	local scale = gui:GetScale()
	local text = self.widget:GetText()
	local indent=4
	
	gui:SetColor(0.7,0.7,0.7)

	if self.border==true then
		gui:DrawRect(pos.x,pos.y,sz.width,sz.height,1)
	end

	if text~="" then
		local style=0
		if self.align=="Left" then style = Text.Left end
		if self.align=="Center" then style = Text.Center end
		if self.align=="Right" then style = Text.Right end
		if self.valign=="Center" then style = style + Text.VCenter end
		
		if self.wordwrap==true then style = style + Text.WordWrap end
		
		if self.border==true then
			gui:DrawText(text,pos.x+scale*indent,pos.y+scale*indent,sz.width-scale*indent*2,sz.height-scale*indent*2,style)	
		else
			gui:DrawText(text,pos.x,pos.y,sz.width,sz.height,style)	
		end
	end
end

There are some variables used like self.border, self.align, self.valign and self.wordwrap.
Any variable used in a widget script can be Set/Get.
You can find most of these in the Documentation for Widget, although not all are documented like SetObject() and GetObject().

So to set our label style we would do something like this:

label = Widget::Label("label", guiScale * 15, guiScale * 15, guiScale *80, guiScale * 20, panel);
label->SetString("align", "Left");		//align horizontal
label->SetString("valign", "Center");		//align vertical
label->SetBool("wordwrap", false);		//wordwrap
label->SetBool("border", true);			//show border

Noticed we used SetString for a string variable and SetBool for a boolean variable.
The first argument is always the variable name used in the widget script.

Lets give you another example to make it a bit more clear.
Open the file "Scripts/GUI/Button.lua" and look at the Draw function.
Did you notice the variable "self.style" being used to dictate what type of button this is?
Interesting right :cool:

Do you remember our btn_Fun?
Lets set our bnt_Fun's style to a checkbox and see what happens.

btn_Fun	= Widget::Button("Fun", guiScale * 175, guiScale * 35, guiScale * 80, guiScale * 20, panel);
btn_Fun->SetString("style", "Checkbox");

And add some functionality.

if (event.source == btn_Fun)
{
  if (btn_Fun->GetState())
    label->SetText("enabled");
  else
    label->SetText("disabled");
  return true;
}


By now your UI_Interface class should look something like this.

UI_Interface.h

#pragma once

#include "Leadwerks.h"

//Forward declare
class App;

using namespace Leadwerks;

class UI_Interface
{
private:
	App* app = NULL;
	//
	GUI* gui = NULL;
	//
	Widget* panel = NULL;
	Widget* label = NULL;
	Widget* textField = NULL;
	Widget* button = NULL;
	Widget* btn_Fun = NULL;
public:
	UI_Interface();
	UI_Interface(App* pApp);
	~UI_Interface();

	void Process();
	bool ProcessEvent(Event event);
};

UI_Interface.cpp
 

#include "UI_Interface.h"

//Forward declares
#include "App.h"

UI_Interface::UI_Interface() {}

UI_Interface::UI_Interface(App* pApp)
{
	app = pApp;
	//
	//create gui
	gui = GUI::Create(app->context);
	float guiScale = gui->GetScale();
	gui->GetBase()->SetScript("Scripts/GUI/Panel.lua");
	//make the base gui invisible if you want
	//gui->GetBase()->SetObject("backgroundcolor", new Vec4(0, 0, 0, 0));

	//
	panel = Widget::Panel(guiScale * 100, guiScale * 100, guiScale * 300, guiScale * 80, gui->GetBase());
	panel = Widget::Create("", guiScale * 100, guiScale * 100, guiScale * 300, guiScale * 80, gui->GetBase(), "Scripts/GUI/Panel.lua");
	//
	label = Widget::Label("label", guiScale * 15, guiScale * 15, guiScale *80, guiScale * 20, panel);
	label->SetString("align", "Left");		//align horizontal
	label->SetString("valign", "Center");	//align vertical
	label->SetBool("wordwrap", false);		//wordwrap
	label->SetBool("border", true);			//show border
	//
	textField = Widget::TextField("text", guiScale * 15, guiScale * 35, guiScale * 150, guiScale * 20, panel);
	button = Widget::Button("button", guiScale * 175, guiScale * 10, guiScale * 80, guiScale * 20, panel);
	//
	btn_Fun = Widget::Button("Fun", guiScale * 175, guiScale * 35, guiScale * 80, guiScale * 20, panel);
	btn_Fun->SetString("style", "Checkbox");
}

UI_Interface::~UI_Interface()
{
	btn_Fun->Release();
	button->Release();
	textField->Release();
	label->Release();
	panel->Release();
	gui->Release();
}

void UI_Interface::Process()
{
	while (EventQueue::Peek())
	{
		Event event = EventQueue::Wait();
		ProcessEvent(event);
	}
}

bool UI_Interface::ProcessEvent(Event event)
{
	if (event.id == Event::WidgetSelect)
	{
		//list type widgets
	}
	//
	if (event.id == Event::WidgetAction)
	{
		if (event.source == button)
		{
			string text = textField->GetText();
			label->SetText(text);
			return true;
		}
		else if (event.source == btn_Fun)
		{
			if (btn_Fun->GetState())
				label->SetText("enabled");
			else
				label->SetText("disabled");
			return true;
		}
	}
	//
	return false;
}




Next blog entry we will be focusing on custom widgets

 Share

0 Comments


Recommended Comments

There are no comments to display.

Guest
Add a comment...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...