Jump to content

GorzenDev

Members
  • Posts

    141
  • Joined

  • Last visited

Blog Entries posted by GorzenDev

  1. GorzenDev
    I decided to release the source/project for my GUIEditor.
    its an unfinished project and not at all optimized, although it is usable.
    you mite have to upgrade the source project to the latest version.
    written in c++.
    the project includes some custom gui scripts found in /Scripts/GUI/Custom.
    and a FileDialog i designed using widgets.

    GUIEditor.rar

    enjoy
  2. GorzenDev
    Remember that a widget's behaviour is dictated by the script that is attached to it.
    Well its that simple just use a custom script for your widget and your done.

    I will show you how to create a simple ColorLabel.
    First copy the default Label.lua script and rename it to Colorlabel.lua
    Now lets make some changes in your Colorlabel.lua so open it up.
    We will add 2 variables to the script called bordercolor and textcolor they will be of type Vec4().
    Script.bordercolor = Vec4(0.2,0.2,0.2,1) Script.textcolor = Vec4(0.7,0.7,0.7,1) Now lets change the draw function to use our color variables.
    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 if self.border==true then --set border color gui:SetColor(self.bordercolor.r, self.bordercolor.g, self.bordercolor.b, self.bordercolor.a) gui:DrawRect(pos.x,pos.y,sz.width,sz.height,1) end --set text color gui:SetColor(self.textcolor.r,self.textcolor.g,self.textcolor.b,self.textcolor.a) 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
    Now lets change the label in our UI_Interface class to use our custom script.
    Theres 2 ways to set a widget's script as i hinted earlier.
    //option 1 label = Widget::Label("label", guiScale * 15, guiScale * 15, guiScale *80, guiScale * 20, panel); label->SetScript("Scripts/GUI/Colorlabel.lua"); //option 2 label = Widget::Create("label", guiScale * 15, guiScale * 15, guiScale * 80, guiScale * 20, panel, "Scripts/GUI/Colorlabel.lua"); Offcourse option 1 is quite silly when you have option 2 but it works.
    Now lets set the text color for our newly created custom widget.
    label->SetObject("textcolor", new Vec4(1.0, 0.0, 0.0, 1.0)); Notice the undocumented SetObject() function which basicly sets variables of type Leadwerks::Object.

    Theres not much more i can say about custom widgets other than, "Your imagination is the limit".
    This concludes the tutorial part.
    I hope it is of some use to anybody.
  3. GorzenDev
    Bare with me im not a very good story teller  .
    I will not be focusing on basic leadwerks usage and assume the reader knows a thing or 2 about leadwerks.

    So lets start with the basics,
    Create a window and context.
    bool App::Start() { window = Leadwerks::Window::Create("GUI Tutorial", 0, 0, 1024, 768); context = Leadwerks::Context::Create(window); return true; } bool App::Loop() { if (window->Closed() || window->KeyHit(Key::Escape)) return false; return true; } Now i personally like to use classes for my GUI so thats what we are gonna do.
    Create a new class called "UI_Interface".

    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; 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) { } UI_Interface::~UI_Interface() { } void UI_Interface::Process() { while (EventQueue::Peek()) { Event event = EventQueue::Wait(); ProcessEvent(event); } } bool UI_Interface::ProcessEvent(Event event) { if (event.id == Event::WidgetSelect) { } // if (event.id == Event::WidgetAction) { } // return false; } now that we have a interface class lets first make sure it is created and called in your main function or app.

    App.h
    #pragma once #include "Leadwerks.h" #include "UI_Interface.h" #undef GetFileType using namespace Leadwerks; class App { public: Leadwerks::Window* window; Context* context; World* world; Camera* camera; UI_Interface* ui_Interface = NULL; App(); virtual ~App(); bool Start(); bool Loop(); }; App.cpp
    #include "App.h" using namespace Leadwerks; App::App() : window(NULL), context(NULL), world(NULL), camera(NULL) {} App::~App() { delete ui_Interface; delete world; delete window; } bool App::Start() { window = Leadwerks::Window::Create("GUI Tutorial", 0, 0, 1024, 768); context = Leadwerks::Context::Create(window); //create GUI ui_Interface = new UI_Interface(this); return true; } bool App::Loop() { if (window->Closed() || window->KeyHit(Key::Escape)) { return false; } context->SetColor(0.0, 0.0, 0.0); context->Clear(); // ui_Interface->Process(); // Time::Update(); // //world->Update(); // //world->Render(); // context->Sync(); return true; }
    Now lets create the GUI in the UI_Interface class.
    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)); }
    This will result in a window with a panel as background.
    Next blog entry we will be focusing on adding widgets to the GUI.



     
  4. GorzenDev
    There is a problem with the default TextArea.lua widget script.
    Your game will crash when you click on an empty TextArea.

    Fix:
    look for the Function "Script:GetCaretCoord(caret)"
    after:
    local text = self.lines[self.currentline]--self.widget:GetText() add:
    if text == nil then return 0 end  
     
    More will be added when/if discovered...
  5. GorzenDev
    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
  6. GorzenDev
    Finished and added Field functionality meaning its now possible to set the Fields for each widget.
    for example the style for a button (Push,Link,Checkbox), or backgroundcolor for panels etc.

    below is a screenshot of the fields in action

     
    Next will be finishing support for custom widgets which i already started on as you can see in the screenshot above(colorlabel).

    At the moment the way to add your custom widgets is a 3 step process.

    First step is adding the widget name to the config.ini like
    [DefineTypes] CustomTypeCount=2 name_0=ColorLabel name_1=MultiListView
    Next is adding a type_file with content like so
    [Base] name=ColorLabel ;allow other widgets to use this as a parent allowparent=false ;allow addItem islistType=false ;location of the widget script in your leadwerks project - only used while exporting wScript=Scripts/GUI/ColorLabel.lua ;location of the widget script for this editor eScript=ElementTypes/Custom/Editor/editorColorLabel.lua ;default size defWidth=80 defHeight=20 ;amount of 'extras' defined dCount=6 [Define_0] name=align type=String [Define_1] name=valign type=String [Define_2] name=wordwrap type=Bool [Define_3] name=border type=Bool [Define_4] name=bordercolor type=Vec4 [Define_5] name=textcolor type=Vec4
    And last but not least you need to edit a copy of your script and disable any EventQueue::Emit events,
    and add some mouseMove,mousDown,mouseUp events for the editor to interact with the widget.
     
    So a custom widget colorlabel would look like this when exported.
    //GUI Editor Generated #include "MenuClass.h" MenuClass::MenuClass(Context* context) { gui = GUI::Create(context); //Panel Panel = Widget::Create("", 0, 0, 1024, 100, gui->GetBase(), "Scripts/GUI/Panel.lua"); Panel->SetAlignment(false, false, false, false); //Button Button = Widget::Create("Template", 81, 38, 150, 20, Panel, "Scripts/GUI/Button.lua"); Button->SetAlignment(false, false, false, false); //Button1 Button1 = Widget::Create("Template", 338, 38, 150, 20, Panel, "Scripts/GUI/Button.lua"); Button1->SetAlignment(false, false, false, false); //ColorLabel ColorLabel = Widget::Create("colorlabel", 710, 39, 80, 20, Panel, "Scripts/GUI/ColorLabel.lua"); ColorLabel->SetAlignment(false, false, false, false); ColorLabel->SetString("align","Center"); ColorLabel->SetString("valign","Center"); ColorLabel->SetBool("border",true); ColorLabel->SetObject("bordercolor", new Vec3(1,0,0,0)); ColorLabel->SetObject("textcolor", new Vec3(0,0,1,1)); //Panel1 Panel1 = Widget::Create("", 342, 328, 300, 200, gui->GetBase(), "Scripts/GUI/Panel.lua"); Panel1->SetAlignment(false, false, false, false); Panel1->SetObject("backgroundcolor", new Vec3(0.2,0.2,0.2,1)); //Button2 Button2 = Widget::Create("exit", 80, 156, 150, 20, Panel1, "Scripts/GUI/Button.lua"); Button2->SetAlignment(false, false, false, false); //Button3 Button3 = Widget::Create("options", 77, 98, 150, 20, Panel1, "Scripts/GUI/Button.lua"); Button3->SetAlignment(false, false, false, false); //Button4 Button4 = Widget::Create("load", 76, 33, 150, 20, Panel1, "Scripts/GUI/Button.lua"); Button4->SetAlignment(false, false, false, false); } MenuClass::~MenuClass() { Button4->Release(); Button3->Release(); Button2->Release(); Panel1->Release(); ColorLabel->Release(); Button1->Release(); Button->Release(); Panel->Release(); gui->Release(); } // bool MenuClass::ProcessEvent(Event event) { if (event.id == Event::WidgetAction) { // } return true; } // bool MenuClass::Update() { return true; }
     
  7. GorzenDev
    finished basic exporting to lua or c++ code.
    the screenshot below results in the following files based on ExportType.

    Menu.lua
    --GUI Editor Generated function BuildMenu(context) local Menu = {} local scale = 1 --GUI local gui = GUI:Create(context) gui : SetScale(scale) Menu.gui=gui Menu.context=context --Panel Menu.Panel = Widget:Create("", 0, 0, 1024, 80, gui:GetBase(), "Scripts/GUI/Panel.lua") Menu.Panel:SetAlignment(true, true, true, false) --Button Menu.Button = Widget:Create("Template", 104, 32, 150, 20, Panel, "Scripts/GUI/Button.lua") Menu.Button:SetAlignment(false, false, false, false) --Button1 Menu.Button1 = Widget:Create("Template", 409, 33, 150, 20, Panel, "Scripts/GUI/Button.lua") Menu.Button1:SetAlignment(false, false, false, false) --Button2 Menu.Button2 = Widget:Create("Template", 782, 34, 150, 20, Panel, "Scripts/GUI/Button.lua") Menu.Button2:SetAlignment(false, false, false, false) --MenuPanel Menu.MenuPanel = Widget:Create("", 250, 249, 500, 300, gui:GetBase(), "Scripts/GUI/Panel.lua") Menu.MenuPanel:SetAlignment(true, true, true, true) --Button3 Menu.Button3 = Widget:Create("Start", 172, 52, 150, 20, MenuPanel, "Scripts/GUI/Button.lua") Menu.Button3:SetAlignment(false, false, false, false) --Button4 Menu.Button4 = Widget:Create("Exit", 167, 238, 150, 20, MenuPanel, "Scripts/GUI/Button.lua") Menu.Button4:SetAlignment(false, false, false, false) --Button5 Menu.Button5 = Widget:Create("Options", 168, 145, 150, 20, MenuPanel, "Scripts/GUI/Button.lua") Menu.Button5:SetAlignment(false, false, false, false) --Button6 Menu.Button6 = Widget:Create("adwadwdaw", 169, 98, 150, 20, MenuPanel, "Scripts/GUI/Button.lua") Menu.Button6:SetAlignment(false, false, false, false) -- function Menu:Show() self.gui:Show() end -- function Menu:Hidden() return self.gui:Hidden() end -- function Menu:Hide() return self.gui:Hide() end -- function Menu:ProcessEvent(event) if event.id == Event.WindowSize then -- elseif event.id == Event.WidgetAction -- end end -- return Menu end  
    Menu.h
    //GUI Editor Generated #pragma once #include "Leadwerks.h" using namespace Leadwerks; class MenuClass { public: GUI* gui; // Widget* Panel; Widget* Button; Widget* Button1; Widget* Button2; Widget* MenuPanel; Widget* Button3; Widget* Button4; Widget* Button5; Widget* Button6; // MenuClass(); ~MenuClass(); // bool ProcessEvent(Event event); bool Update(); };
    Menu.cpp
    //GUI Editor Generated #include "MenuClass.h" MenuClass::MenuClass(Context* context) { gui = GUI::Create(context) //Panel Panel = Widget::Create("", 0, 0, 1024, 80, gui->GetBase(), "Scripts/GUI/Panel.lua") Panel->SetAlignment(true, true, true, false) //Button Button = Widget::Create("Template", 104, 32, 150, 20, Panel, "Scripts/GUI/Button.lua") Button->SetAlignment(false, false, false, false) //Button1 Button1 = Widget::Create("Template", 409, 33, 150, 20, Panel, "Scripts/GUI/Button.lua") Button1->SetAlignment(false, false, false, false) //Button2 Button2 = Widget::Create("Template", 782, 34, 150, 20, Panel, "Scripts/GUI/Button.lua") Button2->SetAlignment(false, false, false, false) //MenuPanel MenuPanel = Widget::Create("", 250, 249, 500, 300, gui->GetBase(), "Scripts/GUI/Panel.lua") MenuPanel->SetAlignment(true, true, true, true) //Button3 Button3 = Widget::Create("Start", 172, 52, 150, 20, MenuPanel, "Scripts/GUI/Button.lua") Button3->SetAlignment(false, false, false, false) //Button4 Button4 = Widget::Create("Exit", 167, 238, 150, 20, MenuPanel, "Scripts/GUI/Button.lua") Button4->SetAlignment(false, false, false, false) //Button5 Button5 = Widget::Create("Options", 168, 145, 150, 20, MenuPanel, "Scripts/GUI/Button.lua") Button5->SetAlignment(false, false, false, false) //Button6 Button6 = Widget::Create("adwadwdaw", 169, 98, 150, 20, MenuPanel, "Scripts/GUI/Button.lua") Button6->SetAlignment(false, false, false, false) } MenuClass::~MenuClass() { Button6->Release(); Button5->Release(); Button4->Release(); Button3->Release(); MenuPanel->Release(); Button2->Release(); Button1->Release(); Button->Release(); Panel->Release(); gui->Release(); } // bool MenuClass::ProcessEvent(Event event) { if (event.id == Event::WidgetAction) { // } return true; } // bool MenuClass::Update() { return true; }  
    next step will be adding stuff like Widget->SetString(), Widget->SetBool(), Widget->SetObject() and list type Widgets.
    after that i will be adding support for custom widgets.
     
     
×
×
  • Create New...