Adding/Using Widgets
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
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
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
0 Comments
Recommended Comments
There are no comments to display.