From 68c6a79c86c595fa2ec5a7109568d5baefc50afd Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Fri, 26 Aug 2016 14:17:27 +0300 Subject: [PATCH] Add another example application to demonstrate various widgets --- .gitignore | 1 + Build | 7 +++ basic.skin | 12 +++-- examples/widgetdemo/buttondemo.cpp | 52 +++++++++++++++++++++ examples/widgetdemo/buttondemo.h | 12 +++++ examples/widgetdemo/demoselector.cpp | 45 ++++++++++++++++++ examples/widgetdemo/demoselector.h | 30 ++++++++++++ examples/widgetdemo/dropdowndemo.cpp | 68 ++++++++++++++++++++++++++++ examples/widgetdemo/dropdowndemo.h | 20 ++++++++ examples/widgetdemo/entrydemo.cpp | 34 ++++++++++++++ examples/widgetdemo/entrydemo.h | 12 +++++ examples/widgetdemo/toggledemo.cpp | 57 +++++++++++++++++++++++ examples/widgetdemo/toggledemo.h | 13 ++++++ examples/widgetdemo/widgetdemo.cpp | 53 ++++++++++++++++++++++ examples/widgetdemo/widgetdemo.h | 28 ++++++++++++ 15 files changed, 440 insertions(+), 4 deletions(-) create mode 100644 examples/widgetdemo/buttondemo.cpp create mode 100644 examples/widgetdemo/buttondemo.h create mode 100644 examples/widgetdemo/demoselector.cpp create mode 100644 examples/widgetdemo/demoselector.h create mode 100644 examples/widgetdemo/dropdowndemo.cpp create mode 100644 examples/widgetdemo/dropdowndemo.h create mode 100644 examples/widgetdemo/entrydemo.cpp create mode 100644 examples/widgetdemo/entrydemo.h create mode 100644 examples/widgetdemo/toggledemo.cpp create mode 100644 examples/widgetdemo/toggledemo.h create mode 100644 examples/widgetdemo/widgetdemo.cpp create mode 100644 examples/widgetdemo/widgetdemo.h diff --git a/.gitignore b/.gitignore index 39b4d84..ebbe143 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ temp /libmspgltk.a /libmspgltk.so /mspgltk.pc +/widgetdemo diff --git a/Build b/Build index 969993e..e320c39 100644 --- a/Build +++ b/Build @@ -25,6 +25,13 @@ package "mspgltk" use "mspgltk"; }; + program "widgetdemo" + { + source "examples/widgetdemo"; + require "sigc++-2.0"; + use "mspgltk"; + }; + source_tarball { source "License.txt"; diff --git a/basic.skin b/basic.skin index 39a900d..5d9c8b6 100644 --- a/basic.skin +++ b/basic.skin @@ -268,16 +268,20 @@ style "list" //margin { right 1; top 1; bottom 1; }; }; - part "selection" + part "items" { - graphic NORMAL "blue_flat"; margin { left 3; right 14; top 3; bottom 3; }; }; +}; - part "items" +style "listitem" +{ + part { - margin { left 3; right 14; top 3; bottom 3; }; + graphic ACTIVE "blue_flat"; }; + + part "children"; }; graphic "grey_raised_divided" diff --git a/examples/widgetdemo/buttondemo.cpp b/examples/widgetdemo/buttondemo.cpp new file mode 100644 index 0000000..f189056 --- /dev/null +++ b/examples/widgetdemo/buttondemo.cpp @@ -0,0 +1,52 @@ +#include +#include +#include +#include "buttondemo.h" + +using namespace std; +using namespace Msp; + +ButtonDemo::ButtonDemo() +{ + set_layout(new GLtk::Layout); + + GLtk::Label *lbl_message = new GLtk::Label; + add(*lbl_message); + + vector buttons; + for(unsigned i=0; i<5; ++i) + { + string text = format("Button %d", i+1); + GLtk::Button *btn = new GLtk::Button(text); + btn->signal_clicked.connect(sigc::bind(sigc::mem_fun(lbl_message, &GLtk::Label::set_text), text+" was clicked")); + buttons.push_back(btn); + add(*btn); + if(i>0) + { + layout->add_constraint(*btn, GLtk::Layout::COPY_WIDTH, *buttons[0]); + layout->add_constraint(*btn, GLtk::Layout::COPY_HEIGHT, *buttons[0]); + + if(i>=3) + { + layout->add_constraint(*btn, GLtk::Layout::RIGHT_OF, *buttons[i-1]); + layout->add_constraint(*btn, GLtk::Layout::ALIGN_TOP, *buttons[i-1]); + } + else + { + layout->add_constraint(*btn, GLtk::Layout::BELOW, *buttons[i-1]); + layout->add_constraint(*btn, GLtk::Layout::ALIGN_LEFT, *buttons[i-1]); + } + } + } + + layout->add_constraint(*buttons[0], GLtk::Layout::BELOW, *lbl_message); + + GLtk::Button *btn = new GLtk::Button("A big one"); + btn->signal_clicked.connect(sigc::bind(sigc::mem_fun(lbl_message, &GLtk::Label::set_text), "The big button was clicked")); + buttons.push_back(btn); + add(*btn); + layout->add_constraint(*btn, GLtk::Layout::ALIGN_TOP, *buttons[0]); + layout->add_constraint(*btn, GLtk::Layout::ALIGN_BOTTOM, *buttons[1]); + layout->add_constraint(*btn, GLtk::Layout::ALIGN_LEFT, *buttons[3]); + layout->add_constraint(*btn, GLtk::Layout::ALIGN_RIGHT, *buttons[4]); +} diff --git a/examples/widgetdemo/buttondemo.h b/examples/widgetdemo/buttondemo.h new file mode 100644 index 0000000..532ab21 --- /dev/null +++ b/examples/widgetdemo/buttondemo.h @@ -0,0 +1,12 @@ +#ifndef BUTTONDEMO_H_ +#define BUTTONDEMO_H_ + +#include + +class ButtonDemo: public Msp::GLtk::Panel +{ +public: + ButtonDemo(); +}; + +#endif diff --git a/examples/widgetdemo/demoselector.cpp b/examples/widgetdemo/demoselector.cpp new file mode 100644 index 0000000..de8d027 --- /dev/null +++ b/examples/widgetdemo/demoselector.cpp @@ -0,0 +1,45 @@ +#include +#include +#include "demoselector.h" + +using namespace std; +using namespace Msp; + +DemoSelector::DemoSelector(): + demos(&get_demo_title), + current_demo(0) +{ + set_layout(new GLtk::Layout); + layout->set_margin(GLtk::Sides(8)); + + GLtk::Column col(*layout); + + GLtk::Label *lbl = new GLtk::Label("Select a widget:"); + add(*lbl); + + list.set_data(demos); + list.signal_item_selected.connect(sigc::mem_fun(this, &DemoSelector::item_selected)); + add(list); + layout->set_expand(list, true, true); +} + +void DemoSelector::add_demo(const string &t, GLtk::Panel *p) +{ + Demo demo; + demo.title = t; + demo.panel = p; + demos.append(demo); +} + +void DemoSelector::item_selected(unsigned i) +{ + if(current_demo) + current_demo->panel->set_visible(false); + current_demo = &demos.get(i); + current_demo->panel->set_visible(true); +} + +string DemoSelector::get_demo_title(const Demo &demo) +{ + return demo.title; +} diff --git a/examples/widgetdemo/demoselector.h b/examples/widgetdemo/demoselector.h new file mode 100644 index 0000000..96cfbac --- /dev/null +++ b/examples/widgetdemo/demoselector.h @@ -0,0 +1,30 @@ +#ifndef DEMOSELECTOR_H_ +#define DEMOSELECTOR_H_ + +#include +#include + +class DemoSelector: public Msp::GLtk::Panel +{ +private: + struct Demo + { + std::string title; + Msp::GLtk::Panel *panel; + }; + + Msp::GLtk::List list; + Msp::GLtk::FunctionListData demos; + const Demo *current_demo; + +public: + DemoSelector(); + + void add_demo(const std::string &, Msp::GLtk::Panel *); +private: + void item_selected(unsigned); + + static std::string get_demo_title(const Demo &); +}; + +#endif diff --git a/examples/widgetdemo/dropdowndemo.cpp b/examples/widgetdemo/dropdowndemo.cpp new file mode 100644 index 0000000..6ee33e0 --- /dev/null +++ b/examples/widgetdemo/dropdowndemo.cpp @@ -0,0 +1,68 @@ +#include +#include +#include "dropdowndemo.h" + +using namespace std; +using namespace Msp; + +DropdownDemo::DropdownDemo() +{ + set_layout(new GLtk::Layout); + + GLtk::Dropdown *drp = new GLtk::Dropdown(categories); + drp->signal_item_selected.connect(sigc::mem_fun(this, &DropdownDemo::category_selected)); + add(*drp); + + categories.append("Arabic numerals"); + categories.append("Roman numerals"); + categories.append("Lowercase letters"); + categories.append("Uppercase letters"); + + GLtk::Widget *prev = drp; + drp = new GLtk::Dropdown(values); + add(*drp); + + layout->add_constraint(*drp, GLtk::Layout::BELOW, *prev); + layout->add_constraint(*drp, GLtk::Layout::ALIGN_LEFT, *prev); + layout->add_constraint(*drp, GLtk::Layout::ALIGN_RIGHT, *prev); +} + +void DropdownDemo::category_selected(unsigned i) +{ + values.clear(); + if(i==0) + { + for(unsigned j=0; j<=26; ++j) + values.append(format("%d", j)); + } + else if(i==1) + { + for(unsigned j=1; j<=26; ++j) + { + string r = string(j/10, 'X'); + if(j%10==9) + r += "IX"; + else if(j%10>=4) + { + if(j%10==4) + r += 'I'; + r += 'V'; + } + + if(j%5<=3) + r += string(j%5, 'I'); + + values.append(r); + } + } + else if(i==2) + { + for(unsigned j=0; j<26; ++j) + values.append(string(1, 'a'+j)); + } + else if(i==3) + { + for(unsigned j=0; j<26; ++j) + values.append(string(1, 'A'+j)); + } +} diff --git a/examples/widgetdemo/dropdowndemo.h b/examples/widgetdemo/dropdowndemo.h new file mode 100644 index 0000000..afa7e7c --- /dev/null +++ b/examples/widgetdemo/dropdowndemo.h @@ -0,0 +1,20 @@ +#ifndef DROPDOWNDEMO_H_ +#define DROPDOWNDEMO_H_ + +#include +#include + +class DropdownDemo: public Msp::GLtk::Panel +{ +private: + Msp::GLtk::BasicListData categories; + Msp::GLtk::BasicListData values; + +public: + DropdownDemo(); + +private: + void category_selected(unsigned); +}; + +#endif diff --git a/examples/widgetdemo/entrydemo.cpp b/examples/widgetdemo/entrydemo.cpp new file mode 100644 index 0000000..64a7bcb --- /dev/null +++ b/examples/widgetdemo/entrydemo.cpp @@ -0,0 +1,34 @@ +#include +#include +#include "entrydemo.h" + +using namespace Msp; + +EntryDemo::EntryDemo() +{ + set_layout(new GLtk::Layout); + + GLtk::Label *lbl = new GLtk::Label("Single-line entries:"); + add(*lbl); + + GLtk::Widget *prev = lbl; + for(unsigned i=0; i<2; ++i) + { + GLtk::Entry *ent = new GLtk::Entry; + ent->set_edit_size(20+i*40, 1); + add(*ent); + layout->add_constraint(*ent, GLtk::Layout::BELOW, *prev); + prev = ent; + } + + lbl = new GLtk::Label("Multi-line entry:"); + add(*lbl); + layout->add_constraint(*lbl, GLtk::Layout::BELOW, *prev); + prev = lbl; + + GLtk::Entry *ent = new GLtk::Entry; + ent->set_multiline(true); + ent->set_edit_size(60, 5); + add(*ent); + layout->add_constraint(*ent, GLtk::Layout::BELOW, *prev); +} diff --git a/examples/widgetdemo/entrydemo.h b/examples/widgetdemo/entrydemo.h new file mode 100644 index 0000000..c1cdbce --- /dev/null +++ b/examples/widgetdemo/entrydemo.h @@ -0,0 +1,12 @@ +#ifndef ENTRYDEMO_H_ +#define ENTRYDEMO_H_ + +#include + +class EntryDemo: public Msp::GLtk::Panel +{ +public: + EntryDemo(); +}; + +#endif diff --git a/examples/widgetdemo/toggledemo.cpp b/examples/widgetdemo/toggledemo.cpp new file mode 100644 index 0000000..cc928a0 --- /dev/null +++ b/examples/widgetdemo/toggledemo.cpp @@ -0,0 +1,57 @@ +#include +#include +#include +#include "toggledemo.h" + +using namespace Msp; + +ToggleDemo::ToggleDemo() +{ + set_layout(new GLtk::Layout); + + GLtk::Label *lbl = new GLtk::Label("Standalone toggles:"); + add(*lbl); + + GLtk::Widget *prev = lbl; + for(unsigned i=0; i<4; ++i) + { + GLtk::Toggle *tgl = new GLtk::Toggle(format("Toggle %d", i+1)); + add(*tgl); + + layout->add_constraint(*tgl, GLtk::Layout::BELOW, *prev); + layout->add_constraint(*tgl, GLtk::Layout::ALIGN_LEFT, *prev); + layout->add_constraint(*tgl, GLtk::Layout::ALIGN_RIGHT, *prev); + + prev = tgl; + } + + for(unsigned i=0; i<2; ++i) + { + GLtk::Panel *group = new GLtk::Panel; + add(*group); + layout->add_constraint(*group, (i==0 ? GLtk::Layout::BELOW : GLtk::Layout::RIGHT_OF), *prev); + if(i>0) + layout->add_constraint(*group, GLtk::Layout::ALIGN_TOP, *prev); + group->set_layout(new GLtk::Layout); + + lbl = new GLtk::Label(format("Group %d:", i+1)); + group->add(*lbl); + + prev = lbl; + for(unsigned j=0; j<4; ++j) + { + GLtk::Toggle *tgl = new GLtk::Toggle(format("Option %d", j+1)); + tgl->set_style("option"); + tgl->set_exclusive(true); + group->add(*tgl); + + group->get_layout()->add_constraint(*tgl, GLtk::Layout::BELOW, *prev); + group->get_layout()->add_constraint(*tgl, GLtk::Layout::ALIGN_LEFT, *prev); + group->get_layout()->add_constraint(*tgl, GLtk::Layout::ALIGN_RIGHT, *prev); + + prev = tgl; + } + + prev = group; + } +} diff --git a/examples/widgetdemo/toggledemo.h b/examples/widgetdemo/toggledemo.h new file mode 100644 index 0000000..9e64f9e --- /dev/null +++ b/examples/widgetdemo/toggledemo.h @@ -0,0 +1,13 @@ +#ifndef TOGGLEDEMO_H_ +#define TOGGLEDEMO_H_ + +#include + +class ToggleDemo: public Msp::GLtk::Panel +{ +private: +public: + ToggleDemo(); +}; + +#endif diff --git a/examples/widgetdemo/widgetdemo.cpp b/examples/widgetdemo/widgetdemo.cpp new file mode 100644 index 0000000..fd52bf6 --- /dev/null +++ b/examples/widgetdemo/widgetdemo.cpp @@ -0,0 +1,53 @@ +#include +#include +#include "buttondemo.h" +#include "dropdowndemo.h" +#include "entrydemo.h" +#include "toggledemo.h" +#include "widgetdemo.h" + +using namespace std; +using namespace Msp; + +WidgetDemo::WidgetDemo(int, char **): + window(800, 600), + resources("basic.skin"), + root(resources, window) +{ + window.set_title("GLtk widget demo"); + window.signal_close.connect(sigc::bind(sigc::mem_fun(this, &WidgetDemo::exit), 0)); + + root.set_layout(new GLtk::Layout); + + root.add(selector); + root.get_layout()->set_expand(selector, false, true); + + add_demo("Button", new ButtonDemo); + add_demo("Dropdown", new DropdownDemo); + add_demo("Entry", new EntryDemo); + add_demo("Toggle", new ToggleDemo); +} + +int WidgetDemo::main() +{ + window.show(); + return Application::main(); +} + +void WidgetDemo::tick() +{ + window.tick(); + GL::Framebuffer::system().clear(GL::COLOR_BUFFER_BIT); + root.render(); + window.swap_buffers(); +} + +void WidgetDemo::add_demo(const string &title, GLtk::Panel *demo) +{ + demo->set_visible(false); + root.add(*demo); + root.get_layout()->add_constraint(*demo, GLtk::Layout::RIGHT_OF, selector); + root.get_layout()->set_expand(*demo, true, true); + + selector.add_demo(title, demo); +} diff --git a/examples/widgetdemo/widgetdemo.h b/examples/widgetdemo/widgetdemo.h new file mode 100644 index 0000000..f582724 --- /dev/null +++ b/examples/widgetdemo/widgetdemo.h @@ -0,0 +1,28 @@ +#ifndef WIDGETDEMO_H_ +#define WIDGETDEMO_H_ + +#include +#include +#include +#include +#include "demoselector.h" + +class WidgetDemo: public Msp::RegisteredApplication +{ +private: + Msp::Graphics::SimpleGLWindow window; + Msp::GLtk::Resources resources; + Msp::GLtk::Root root; + DemoSelector selector; + +public: + WidgetDemo(int, char **); + + virtual int main(); +private: + virtual void tick(); + + void add_demo(const std::string &, Msp::GLtk::Panel *); +}; + +#endif -- 2.43.0