mirror of
https://github.com/ApfelTeeSaft/vb01.git
synced 2026-08-26 19:33:45 +00:00
merged GUI elements into vb01
This commit is contained in:
@@ -7,6 +7,7 @@ set(BUILD_SHARED_LIBS OFF)
|
||||
set(BUILD_TESTS OFF)
|
||||
set(BUILD_SAMPLES OFF)
|
||||
set(BUILD_WITH_ASSIMP OFF)
|
||||
set(BUILD_GUI_ELEMENTS ON)
|
||||
set(LIB_NAME vb01)
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
@@ -25,6 +26,10 @@ if(BUILD_WITH_ASSIMP)
|
||||
set(ASSET_READERS ${ASSET_READERS} assimpModelReader.cpp)
|
||||
endif()
|
||||
|
||||
if(BUILD_GUI_ELEMENTS)
|
||||
set(GUI ${GUI} button.cpp listbox.cpp textbox.cpp checkbox.cpp slider.cpp)
|
||||
endif()
|
||||
|
||||
set(LIB_SRC ${RENDER} ${MATH} ${UTILS} ${GUI} ${ARMATURE} ${ASSET_MANAGER} ${ASSET_READERS} ${ANIM})
|
||||
|
||||
include_directories(external/tinydir)
|
||||
|
||||
+156
@@ -0,0 +1,156 @@
|
||||
#include <locale>
|
||||
#include <codecvt>
|
||||
#include <glfw3.h>
|
||||
|
||||
#include "root.h"
|
||||
#include "quad.h"
|
||||
#include "node.h"
|
||||
#include "material.h"
|
||||
#include "text.h"
|
||||
#include "texture.h"
|
||||
#include "util.h"
|
||||
#include "button.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace vb01;
|
||||
|
||||
namespace vb01Gui{
|
||||
Button::Button(Vector2 pos, Vector2 size, string name, string fontPath, int trigger, bool separate, string imagePath){
|
||||
this->pos = pos;
|
||||
this->size = size;
|
||||
this->name = name;
|
||||
this->separate = separate;
|
||||
this->imagePath = imagePath;
|
||||
this->trigger = trigger;
|
||||
|
||||
Root *root = Root::getSingleton();
|
||||
guiNode = root->getGuiNode();
|
||||
rect = new Quad(Vector3(size.x, size.y, 0), false);
|
||||
rectNode = new Node(Vector3(pos.x, pos.y, 0));
|
||||
Material *mat = new Material(root->getLibPath() + "gui");
|
||||
|
||||
if(imagePath == ""){
|
||||
mat->addBoolUniform(texUni, false);
|
||||
mat->addVec4Uniform(diffColUni, color);
|
||||
}
|
||||
else{
|
||||
mat->addBoolUniform(texUni, true);
|
||||
string frame[]{imagePath};
|
||||
Texture *tex = new Texture(frame, 1, false);
|
||||
mat->addTexUniform("diffuseMap", tex, false);
|
||||
textures.push_back(tex);
|
||||
}
|
||||
|
||||
rect->setMaterial(mat);
|
||||
rectNode->attachMesh(rect);
|
||||
guiNode->attachChild(rectNode);
|
||||
|
||||
if(separate){
|
||||
text = new Text(fontPath, stringToWstring(name));
|
||||
text->setScale(.2);
|
||||
|
||||
textNode = new Node(Vector3(pos.x, pos.y + size.y, - .1));
|
||||
textNode->addText(text);
|
||||
|
||||
Material *textMat = new Material(root->getLibPath() + "text");
|
||||
textMat->addBoolUniform(texUni, false);
|
||||
textMat->addVec4Uniform(diffColUni, Vector4::VEC_IJKL);
|
||||
text->setMaterial(textMat);
|
||||
|
||||
guiNode->attachChild(textNode);
|
||||
}
|
||||
|
||||
initWindowSize[0] = Root::getSingleton()->getWidth();
|
||||
initWindowSize[1] = Root::getSingleton()->getHeight();
|
||||
}
|
||||
|
||||
Button::~Button(){
|
||||
if(textNode){
|
||||
guiNode->dettachChild(textNode);
|
||||
delete textNode;
|
||||
}
|
||||
|
||||
guiNode->dettachChild(rectNode);
|
||||
delete rectNode;
|
||||
}
|
||||
|
||||
void Button::update(){
|
||||
int width, height;
|
||||
GLFWwindow *window = Root::getSingleton()->getWindow();
|
||||
glfwGetWindowSize(window, &width, &height);
|
||||
|
||||
float posRatio[] = {pos.x / initWindowSize[0], pos.y / initWindowSize[1]};
|
||||
float sizeRatio[] = {size.x / initWindowSize[0], size.y / initWindowSize[1]};
|
||||
|
||||
pos = Vector2(width * posRatio[0], height * posRatio[1]);
|
||||
size = Vector2(width * sizeRatio[0], height * sizeRatio[1]);
|
||||
|
||||
initWindowSize[0] = width;
|
||||
initWindowSize[1] = height;
|
||||
|
||||
if(textNode)
|
||||
textNode->setVisible(active);
|
||||
|
||||
rectNode->setVisible(active);
|
||||
}
|
||||
|
||||
void Button::onMouseOver(){
|
||||
mouseOver = true;
|
||||
}
|
||||
|
||||
void Button::onMouseOff(){
|
||||
mouseOver = false;
|
||||
}
|
||||
|
||||
void Button::setPos(Vector2 pos){
|
||||
this->pos = pos;
|
||||
float z1 = rectNode->getPosition().z;
|
||||
rectNode->setPosition(Vector3(pos.x, pos.y, z1));
|
||||
|
||||
if(textNode){
|
||||
float z2 = textNode->getPosition().z;
|
||||
textNode->setPosition(Vector3(pos.x, pos.y + size.y, z2));
|
||||
}
|
||||
}
|
||||
|
||||
void Button::setSize(Vector2 size){
|
||||
this->size = size;
|
||||
rect->setSize(Vector3(size.x, size.y, 0));
|
||||
}
|
||||
|
||||
void Button::setColor(Vector4 c){
|
||||
this->color = c;
|
||||
((Material::Vector4Uniform*)rect->getMaterial()->getUniform(diffColUni))->value = color;
|
||||
}
|
||||
|
||||
void Button::setZOrder(float zOrder){
|
||||
Vector3 rectPos = rectNode->getPosition();
|
||||
rectNode->setPosition(Vector3(rectPos.x, rectPos.y, zOrder));
|
||||
|
||||
if(textNode){
|
||||
Vector3 textPos = textNode->getPosition();
|
||||
textNode->setPosition(Vector3(textPos.x, textPos.y, zOrder - .1));
|
||||
}
|
||||
}
|
||||
|
||||
void Button::setImage(string image){
|
||||
int texId = -1;
|
||||
Material *mat = rect->getMaterial();
|
||||
|
||||
for(int i = 0; i < textures.size(); i++)
|
||||
if(textures[i]->getPath()[0] == image)
|
||||
texId = i;
|
||||
|
||||
/*
|
||||
if(texId == -1){
|
||||
string p[]{image};
|
||||
textures.push_back(new Texture(p, 1));
|
||||
mat->setDiffuseMap(textures[textures.size() - 1], 0);
|
||||
}
|
||||
else
|
||||
mat->setDiffuseMap(textures[texId], 0);
|
||||
*/
|
||||
|
||||
this->imagePath = image;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
#ifndef BUTTON_H
|
||||
#define BUTTON_H
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include "vector.h"
|
||||
|
||||
class GLFWwindow;
|
||||
|
||||
namespace vb01{
|
||||
class Quad;
|
||||
class Node;
|
||||
class Text;
|
||||
class Texture;
|
||||
}
|
||||
|
||||
namespace vb01Gui{
|
||||
class Button{
|
||||
public:
|
||||
Button(vb01::Vector2, vb01::Vector2, std::string, std::string, int = -1, bool = true, std::string = "");
|
||||
virtual ~Button();
|
||||
void update();
|
||||
virtual void onMouseOver();
|
||||
virtual void onMouseOff();
|
||||
virtual void onClick(){}
|
||||
inline vb01::Vector2 getPos(){return pos;}
|
||||
void setPos(vb01::Vector2);
|
||||
inline vb01::Vector2 getSize(){return size;}
|
||||
void setSize(vb01::Vector2);
|
||||
inline std::string getName(){return name;}
|
||||
inline void setActive(bool active){this->active = active;}
|
||||
inline bool isSeparate(){return separate;}
|
||||
inline bool isActive(){return active;}
|
||||
inline vb01::Vector4 getColor(){return color;}
|
||||
inline int getTrigger(){return trigger;}
|
||||
void setColor(vb01::Vector4);
|
||||
void setZOrder(float);
|
||||
void setImage(std::string);
|
||||
protected:
|
||||
int trigger, initWindowSize[2];
|
||||
bool separate, active = true, mouseOver = false;
|
||||
vb01::Quad *rect;
|
||||
vb01::Node *rectNode, *textNode = nullptr, *guiNode;
|
||||
vb01::Vector2 pos, size;
|
||||
vb01::Text *text = nullptr;
|
||||
std::string name, imagePath, texUni = "texturingEnabled", diffColUni = "diffuseColor";
|
||||
std::vector<vb01::Texture*> textures;
|
||||
vb01::Vector4 color = vb01::Vector4(.6, .6, .6, 1);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,47 @@
|
||||
#include "checkbox.h"
|
||||
#include "text.h"
|
||||
#include "node.h"
|
||||
#include "material.h"
|
||||
|
||||
using namespace vb01;
|
||||
using namespace std;
|
||||
|
||||
namespace vb01Gui{
|
||||
Checkbox::CheckboxButton::CheckboxButton(Checkbox *ch, Vector2 pos, Vector2 size, string name, bool separate) : Button(pos, size, name, "", -1, separate) {
|
||||
checkbox = ch;
|
||||
}
|
||||
|
||||
void Checkbox::CheckboxButton::onClick() {
|
||||
checkbox->check();
|
||||
float col = (checkbox->isChecked() ? .6 : .2);
|
||||
setColor(Vector4(col, col, col, 1));
|
||||
}
|
||||
|
||||
Checkbox::Checkbox(Vector2 pos, string fontPath){
|
||||
this->pos = pos;
|
||||
checkboxButton = new CheckboxButton(this, pos, Vector2(length,length), "CheckboxButton", false);
|
||||
|
||||
/*
|
||||
Root *root = Root::getSingleton();
|
||||
checkNode = new Node();
|
||||
Text *check = new Text(fontPath, L"X");
|
||||
Material *mat = new Material(root->getLibPath() + "text");
|
||||
mat->addBoolUniform("texturingEnabled", false);
|
||||
mat->addVec4Uniform("diffuseColor", Vector4::VEC_IJKL);
|
||||
check->setMaterial(mat);
|
||||
checkNode->addText(check);
|
||||
checkNode->setVisible(false);
|
||||
root->getGuiNode()->attachChild(checkNode);
|
||||
checkNode->setPosition(Vector3(pos.x, pos.y, 0.1f));
|
||||
*/
|
||||
}
|
||||
|
||||
Checkbox::~Checkbox() {
|
||||
|
||||
}
|
||||
|
||||
void Checkbox::check() {
|
||||
checked = !checked;
|
||||
//checkNode->setVisible(checked);
|
||||
}
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
#ifndef CHECKBOX_H
|
||||
#define CHECKBOX_H
|
||||
|
||||
#include "button.h"
|
||||
|
||||
namespace vb01{
|
||||
class Quad;
|
||||
class Node;
|
||||
class Text;
|
||||
}
|
||||
|
||||
namespace vb01Gui{
|
||||
class Checkbox {
|
||||
public:
|
||||
Checkbox(vb01::Vector2, std::string);
|
||||
~Checkbox();
|
||||
void update(){}
|
||||
virtual void check();
|
||||
virtual bool isChecked(){return checked;}
|
||||
private:
|
||||
class CheckboxButton : public Button {
|
||||
public:
|
||||
CheckboxButton(Checkbox*, vb01::Vector2, vb01::Vector2, std::string, bool);
|
||||
void onClick();
|
||||
private:
|
||||
Checkbox *checkbox = nullptr;
|
||||
};
|
||||
|
||||
const int length = 15;
|
||||
bool checked = false;
|
||||
vb01::Vector2 pos;
|
||||
CheckboxButton *checkboxButton;
|
||||
vb01::Node *checkNode = nullptr;
|
||||
public:
|
||||
inline CheckboxButton* getCheckboxButton(){return checkboxButton;}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
+234
@@ -0,0 +1,234 @@
|
||||
#include <glfw3.h>
|
||||
|
||||
#include "listbox.h"
|
||||
#include "util.h"
|
||||
#include "node.h"
|
||||
#include "text.h"
|
||||
#include "quad.h"
|
||||
#include "root.h"
|
||||
#include "material.h"
|
||||
|
||||
using namespace vb01;
|
||||
using namespace std;
|
||||
|
||||
namespace vb01Gui{
|
||||
Listbox::ListboxButton::ListboxButton(Listbox *l, Vector2 pos, Vector2 size, string name) : Button(pos, size, name, "", -1, false){listbox = l;}
|
||||
|
||||
void Listbox::ListboxButton::onClick(){
|
||||
if(!listbox->isOpen())
|
||||
listbox->openUp();
|
||||
else{
|
||||
Vector2 cursorPos = getCursorPos();
|
||||
|
||||
if(cursorPos.x < listbox->getScrollingButton()->getPos().x){
|
||||
if(listbox->isCloseable())
|
||||
listbox->close();
|
||||
}
|
||||
else
|
||||
listbox->scrollToHeight(cursorPos.y);
|
||||
}
|
||||
}
|
||||
|
||||
Listbox::ScrollingButton::ScrollingButton(Vector2 pos, Vector2 size, string name) : Button(pos, size, name, "", -1, false){}
|
||||
|
||||
void Listbox::ScrollingButton::onClick(){}
|
||||
|
||||
Listbox::Listbox(Vector2 pos, Vector2 size, std::vector<string> &lines, int maxDisplay, string fontPath, bool closeable){
|
||||
this->pos = pos;
|
||||
this->size = size;
|
||||
this->maxDisplay = maxDisplay;
|
||||
this->fontPath = fontPath;
|
||||
this->lineHeight = size.y;
|
||||
this->closeable = closeable;
|
||||
|
||||
Root *root = Root::getSingleton();
|
||||
Vector2 mousePos = getCursorPos();
|
||||
guiNode = Root::getSingleton()->getGuiNode();
|
||||
string texUni = "texturingEnabled", diffColUni = "diffuseColor";
|
||||
|
||||
for(int i = 0; i < lines.size(); i++){
|
||||
Text *text = new Text(fontPath, stringToWstring(lines[i]));
|
||||
text->setScale(.2);
|
||||
|
||||
Material *textMat = new Material(root->getLibPath() + "text");
|
||||
textMat->addBoolUniform(texUni, false);
|
||||
textMat->addVec4Uniform(diffColUni, Vector4::VEC_IJKL);
|
||||
text->setMaterial(textMat);
|
||||
|
||||
Node *node = new Node(Vector3(pos.x, pos.y + size.y * (i + 1), textZCoord));
|
||||
node->addText(text);
|
||||
guiNode->attachChild(node);
|
||||
node->setVisible(false);
|
||||
|
||||
this->lines.push_back(text);
|
||||
}
|
||||
|
||||
this->lines[0]->getNode()->setVisible(true);
|
||||
|
||||
listboxButton = new ListboxButton(this, pos, size, "ListboxButton");
|
||||
|
||||
scrollingButton = new ScrollingButton(Vector2(pos.x + size.x - 20, pos.y + lineHeight), Vector2(20, lineHeight * (maxDisplay - 2) / (maxDisplay + 1)), "scrollingButton");
|
||||
scrollingButton->setColor(Vector4(.2, .2, .2, 1));
|
||||
scrollingButton->setZOrder(-.05);
|
||||
scrollingButton->setActive(false);
|
||||
|
||||
Quad *selRect = new Quad(Vector3(size.x, size.y, 0), false);
|
||||
selRectNode = new Node(Vector3(size.x, size.y, -.05));
|
||||
Material *mat = new Material(root->getLibPath() + "gui");
|
||||
mat->addBoolUniform(texUni, false);
|
||||
mat->addVec4Uniform(diffColUni, Vector4(.6, .35, .05, 1));
|
||||
selRect->setMaterial(mat);
|
||||
selRectNode->attachMesh(selRect);
|
||||
selRectNode->setVisible(false);
|
||||
guiNode->attachChild(selRectNode);
|
||||
|
||||
if(!closeable)
|
||||
openUp();
|
||||
}
|
||||
|
||||
Listbox::~Listbox(){
|
||||
while(!lines.empty()){
|
||||
int id = lines.size() - 1;
|
||||
Node *textNode = lines[id]->getNode();
|
||||
guiNode->dettachChild(textNode);
|
||||
delete textNode;
|
||||
lines.pop_back();
|
||||
}
|
||||
|
||||
guiNode->dettachChild(selRectNode);
|
||||
delete selRectNode;
|
||||
}
|
||||
|
||||
void Listbox::update(){
|
||||
scrollingButton->update();
|
||||
listboxButton->update();
|
||||
|
||||
if(open){
|
||||
Vector2 mousePos = getCursorPos();
|
||||
Vector2 p = pos;
|
||||
|
||||
if(mousePos.y > pos.y && mousePos.y < pos.y + size.y * maxDisplay){
|
||||
selectedOption = scrollOffset + ((int)(mousePos.y - pos.y) / ((int)size.y));
|
||||
p.y = pos.y + size.y * ((int)(mousePos.y - pos.y) / ((int)size.y));
|
||||
}
|
||||
else if(mousePos.y < pos.y){
|
||||
selectedOption = 0;
|
||||
p.y = pos.y;
|
||||
}
|
||||
else{
|
||||
selectedOption = (maxDisplay + scrollOffset) - 1;
|
||||
p.y = pos.y + size.y * (maxDisplay - 1);
|
||||
}
|
||||
|
||||
selRectNode->setPosition(Vector3(p.x, p.y, -.05));
|
||||
|
||||
Vector2 scrollButtonPos = Vector2(pos.x + size.x - 20, pos.y + lineHeight + lineHeight * scrollOffset * (double(maxDisplay - 2) / (maxDisplay + 1)));
|
||||
scrollingButton->setPos(scrollButtonPos);
|
||||
}
|
||||
}
|
||||
|
||||
void Listbox::scrollToHeight(float clickPos){
|
||||
float clickHeight = clickPos - (pos.y + lineHeight);
|
||||
int newOffset = clickHeight / (lineHeight * (maxDisplay - 2) / (maxDisplay + 1));
|
||||
int diffOffset = scrollOffset - newOffset;
|
||||
|
||||
for(int i = 0; i < abs(diffOffset); ++i){
|
||||
if(diffOffset > 0)
|
||||
scrollUp();
|
||||
else
|
||||
scrollDown();
|
||||
}
|
||||
}
|
||||
|
||||
void Listbox::openUp(){
|
||||
open = true;
|
||||
lines[selectedOption]->getNode()->setPosition(Vector3(pos.x, pos.y + size.y * (selectedOption-scrollOffset + 1), textZCoord));
|
||||
lines[selectedOption]->getNode()->setVisible(false);
|
||||
Vector2 size = listboxButton->getSize();
|
||||
size.y *= maxDisplay;
|
||||
listboxButton->setSize(size);
|
||||
selRectNode->setVisible(true);
|
||||
scrollingButton->setActive(true);
|
||||
|
||||
for(int i = scrollOffset; i < scrollOffset + maxDisplay; i++)
|
||||
lines[i]->getNode()->setVisible(true);
|
||||
|
||||
onOpen();
|
||||
}
|
||||
|
||||
void Listbox::close(){
|
||||
open = false;
|
||||
Vector2 size = listboxButton->getSize();
|
||||
size.y /= maxDisplay;
|
||||
listboxButton->setSize(size);
|
||||
selRectNode->setVisible(false);
|
||||
scrollingButton->setActive(false);
|
||||
|
||||
for(int i = scrollOffset; i < scrollOffset + maxDisplay; i++)
|
||||
lines[i]->getNode()->setVisible(false);
|
||||
|
||||
lines[selectedOption]->getNode()->setPosition(Vector3(pos.x, pos.y + size.y, textZCoord));
|
||||
lines[selectedOption]->getNode()->setVisible(true);
|
||||
|
||||
onClose();
|
||||
}
|
||||
|
||||
void Listbox::scrollUp(){
|
||||
if(scrollOffset > 0){
|
||||
scrollOffset--;
|
||||
|
||||
for(Text *l : lines){
|
||||
Node *node = l->getNode();
|
||||
Vector3 p = node->getPosition();
|
||||
node->setPosition(Vector3(p.x, p.y + size.y, p.z));
|
||||
|
||||
if(node->getPosition().y > pos.y + size.y * maxDisplay)
|
||||
node->setVisible(false);
|
||||
else if(node->getPosition().y > pos.y)
|
||||
node->setVisible(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Listbox::scrollDown(){
|
||||
if (scrollOffset < lines.size() - maxDisplay){
|
||||
scrollOffset++;
|
||||
|
||||
for(Text *l : lines){
|
||||
Node *node = l->getNode();
|
||||
Vector3 p = node->getPosition();
|
||||
node->setPosition(Vector3(p.x, p.y - size.y, p.z));
|
||||
|
||||
if(node->getPosition().y - size.y < pos.y)
|
||||
node->setVisible(false);
|
||||
else if(node->getPosition().y < pos.y + size.y * (maxDisplay + 1))
|
||||
node->setVisible(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Listbox::changeLine(int id, wstring change){
|
||||
lines[id]->setText(change);
|
||||
}
|
||||
|
||||
std::vector<wstring> Listbox::getContents(){
|
||||
std::vector<wstring> lines;
|
||||
|
||||
for(Text *t : this->lines)
|
||||
lines.push_back(t->getText());
|
||||
|
||||
return lines;
|
||||
}
|
||||
|
||||
void Listbox::addLine(wstring line){
|
||||
Text *t = new Text(fontPath, line);
|
||||
Node *node = new Node(Vector3(pos.x, pos.y - size.y * lines.size(), textZCoord));
|
||||
node->addText(t);
|
||||
guiNode->attachChild(node);
|
||||
lines.push_back(t);
|
||||
}
|
||||
|
||||
string Listbox::convert(string str){
|
||||
return str;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
#ifndef LISTBOX_H
|
||||
#define LISTBOX_H
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "button.h"
|
||||
#include "vector.h"
|
||||
|
||||
namespace vb01{
|
||||
class Node;
|
||||
class Text;
|
||||
}
|
||||
|
||||
namespace vb01Gui{
|
||||
class Listbox{
|
||||
public:
|
||||
class ListboxButton : public Button{
|
||||
public:
|
||||
ListboxButton(Listbox*, vb01::Vector2, vb01::Vector2, std::string);
|
||||
void onClick();
|
||||
private:
|
||||
Listbox *listbox = nullptr;
|
||||
};
|
||||
|
||||
Listbox(vb01::Vector2, vb01::Vector2, std::vector<std::string>&, int, std::string, bool = true);
|
||||
~Listbox();
|
||||
void update();
|
||||
void openUp();
|
||||
void close();
|
||||
void scrollUp();
|
||||
void scrollDown();
|
||||
void addLine(std::wstring);
|
||||
void changeLine(int, std::wstring);
|
||||
void scrollToHeight(float);
|
||||
virtual void onOpen(){}
|
||||
virtual void onClose(){}
|
||||
inline int getScrollOffset(){return scrollOffset;}
|
||||
inline float getLineHeight(){return lineHeight;}
|
||||
inline bool isOpen(){return open;}
|
||||
inline bool isCloseable(){return closeable;}
|
||||
void appendLines(std::vector<std::wstring>&);
|
||||
inline int getSelectedOption(){return selectedOption;}
|
||||
inline int getMaxDisplay(){return maxDisplay;}
|
||||
inline int getNumLines(){return lines.size();}
|
||||
std::vector<std::wstring> getContents();
|
||||
inline vb01::Vector2 getPos(){return pos;}
|
||||
inline vb01::Vector2 getSize(){return size;}
|
||||
private:
|
||||
class ScrollingButton : public Button{
|
||||
public:
|
||||
ScrollingButton(vb01::Vector2, vb01::Vector2, std::string);
|
||||
void onClick();
|
||||
private:
|
||||
};
|
||||
|
||||
std::string convert(std::string);
|
||||
|
||||
float textZCoord = -.3, lineHeight;
|
||||
int maxDisplay, scrollOffset = 0;
|
||||
bool open = false, closeable = false;
|
||||
std::string fontPath;
|
||||
vb01::Vector2 pos, size;
|
||||
ListboxButton *listboxButton;
|
||||
ScrollingButton *scrollingButton;
|
||||
vb01::Node *selRectNode, *guiNode;
|
||||
std::vector<vb01::Text*> lines;
|
||||
protected:
|
||||
int selectedOption = 0;
|
||||
public:
|
||||
inline ListboxButton* getListboxButton(){return listboxButton;}
|
||||
inline ScrollingButton* getScrollingButton(){return scrollingButton;}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
#include <glfw3.h>
|
||||
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
|
||||
#include "slider.h"
|
||||
#include "root.h"
|
||||
#include "util.h"
|
||||
|
||||
|
||||
using namespace std;
|
||||
using namespace vb01;
|
||||
|
||||
namespace vb01Gui{
|
||||
Slider::MovableSliderButton::MovableSliderButton(Slider *slider, Vector2 pos, Vector2 size, string name, bool separate) : Button(pos, size, name, "", -1, separate) {
|
||||
this->slider = slider;
|
||||
}
|
||||
|
||||
void Slider::MovableSliderButton::onClick() {
|
||||
clicked = !clicked;
|
||||
}
|
||||
|
||||
void Slider::MovableSliderButton::update() {
|
||||
Vector2 cursorPos;
|
||||
|
||||
if (clicked && cursorPos.y > slider->getPos().y && cursorPos.y < slider->getPos().y + slider->getSize().y) {
|
||||
if (cursorPos.x < slider->getPos().x)
|
||||
cursorPos.x = slider->getPos().x;
|
||||
else if (cursorPos.x > slider->getPos().x + slider->getSize().x)
|
||||
cursorPos.x = slider->getPos().x + slider->getSize().x;
|
||||
|
||||
slider->setValue((((double) cursorPos.x - slider->getPos().x) / slider->getSize().x) * slider->getMaxValue());
|
||||
}
|
||||
}
|
||||
|
||||
Slider::StaticSliderButton::StaticSliderButton(Slider *slider, Vector2 pos, Vector2 size, string name, bool separate) : Button(pos, size, name, "", -1, separate) {
|
||||
this->slider = slider;
|
||||
}
|
||||
|
||||
void Slider::StaticSliderButton::onClick() {
|
||||
Vector2 cursorPos = getCursorPos();
|
||||
s16 buttonClickPoint = -slider->getPos().x + cursorPos.x;
|
||||
slider->setValue(((double) buttonClickPoint / slider->getSize().x) * slider->getMaxValue());
|
||||
}
|
||||
|
||||
Slider::Slider(Vector2 pos, Vector2 size, double minValue, double maxValue) {
|
||||
this->pos = pos;
|
||||
this->size = size;
|
||||
this->minValue = minValue;
|
||||
this->maxValue = maxValue;
|
||||
|
||||
staticSliderButton = new StaticSliderButton(this, pos, size, "StaticSliderButton", false);
|
||||
movableSliderButton = new MovableSliderButton(this, Vector2(pos.x + staticSliderButton->getSize().x / 1, pos.y - 15), Vector2(10, 40), "MovableSliderButton", false);
|
||||
|
||||
value = (maxValue - minValue) / 2;
|
||||
}
|
||||
|
||||
Slider::~Slider() {
|
||||
}
|
||||
|
||||
void Slider::update() {
|
||||
if (value < minValue)
|
||||
value = minValue;
|
||||
else if (value > maxValue)
|
||||
value = maxValue;
|
||||
|
||||
Vector2 p = movableSliderButton->getPos(), s = movableSliderButton->getSize();
|
||||
p.x = pos.x + (double) size.x / maxValue * value;
|
||||
movableSliderButton->update();
|
||||
movableSliderButton->setPos(p);
|
||||
|
||||
if(textbox && !textbox->isEnabled()){
|
||||
ostringstream ss;
|
||||
ss << value;
|
||||
textbox->setEntry(stringToWstring(ss.str()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
#ifndef SLIDER_H
|
||||
#define SLIDER_H
|
||||
|
||||
#include "vector.h"
|
||||
#include "button.h"
|
||||
#include "textbox.h"
|
||||
|
||||
namespace vb01Gui{
|
||||
class Slider {
|
||||
public:
|
||||
Slider(vb01::Vector2, vb01::Vector2, double, double);
|
||||
~Slider();
|
||||
void update();
|
||||
inline void setTextbox(Textbox *t){this->textbox=t;}
|
||||
inline double getMinValue(){return minValue;}
|
||||
inline double getValue(){return value;}
|
||||
inline double getMaxValue(){return maxValue;}
|
||||
inline void setValue(double v){this->value=v;}
|
||||
inline vb01::Vector2 getPos(){return pos;}
|
||||
inline vb01::Vector2 getSize(){return size;}
|
||||
inline Textbox* getTextbox(){return textbox;}
|
||||
private:
|
||||
class MovableSliderButton : public Button {
|
||||
public:
|
||||
MovableSliderButton(Slider*, vb01::Vector2, vb01::Vector2, std::string, bool);
|
||||
void onClick();
|
||||
void update();
|
||||
private:
|
||||
Slider *slider;
|
||||
bool clicked = false;
|
||||
};
|
||||
|
||||
class StaticSliderButton : public Button {
|
||||
public:
|
||||
StaticSliderButton(Slider*, vb01::Vector2, vb01::Vector2, std::string, bool);
|
||||
void onClick();
|
||||
private:
|
||||
Slider *slider;
|
||||
};
|
||||
|
||||
MovableSliderButton *movableSliderButton = nullptr;
|
||||
StaticSliderButton *staticSliderButton = nullptr;
|
||||
double minValue, value, maxValue;
|
||||
vb01::Vector2 pos, size;
|
||||
Textbox *textbox = nullptr;
|
||||
public:
|
||||
inline MovableSliderButton* getMovableSliderButton(){return movableSliderButton;}
|
||||
inline StaticSliderButton* getStaticSliderButton(){return staticSliderButton;}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
+131
@@ -0,0 +1,131 @@
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
#include <ostream>
|
||||
|
||||
#include "textbox.h"
|
||||
#include "slider.h"
|
||||
#include "root.h"
|
||||
#include "node.h"
|
||||
#include "quad.h"
|
||||
#include "material.h"
|
||||
#include "util.h"
|
||||
|
||||
using namespace vb01;
|
||||
using namespace std;
|
||||
|
||||
namespace vb01Gui{
|
||||
Textbox::TextboxButton::TextboxButton(Textbox *t, Vector2 pos, Vector2 size, string name) : Button(pos, size, name, "", -1, false) {textbox = t;}
|
||||
|
||||
void Textbox::TextboxButton::onClick(){
|
||||
if(!textbox->isEnabled())
|
||||
textbox->enable();
|
||||
else
|
||||
textbox->disable();
|
||||
}
|
||||
|
||||
Textbox::Textbox(Vector2 pos, Vector2 size, string fontPath, wstring entry){
|
||||
this->pos = pos;
|
||||
this->size = size;
|
||||
this->fontPath = fontPath;
|
||||
|
||||
textboxButton = new TextboxButton(this, pos, size, "TextboxButton");
|
||||
string libPath = Root::getSingleton()->getLibPath();
|
||||
|
||||
guiNode = Root::getSingleton()->getGuiNode();
|
||||
text = new Text(fontPath, entry);
|
||||
text->setScale(.5);
|
||||
Material *textMat = new Material(libPath + "text");
|
||||
textMat->addBoolUniform("texturingEnabled", false);
|
||||
textMat->addVec4Uniform("diffuseColor", Vector4(1, 1, 1, 1));
|
||||
text->setMaterial(textMat);
|
||||
textNode = new Node(Vector3(pos.x, pos.y + size.y, -.1));
|
||||
textNode->addText(text);
|
||||
guiNode->attachChild(textNode);
|
||||
|
||||
cursorPosOffset = entry.length();
|
||||
cursorRect = new Quad(Vector3(cursorWidth, size.y, 0), false);
|
||||
cursorNode = new Node(Vector3(pos.x + text->getLength(), pos.y, cursorZCoord));
|
||||
Material *mat = new Material(libPath + "gui");
|
||||
mat->addBoolUniform("texturingEnabled", false);
|
||||
mat->addVec4Uniform("diffuseColor", Vector4(1, 1, 1, 1));
|
||||
cursorRect->setMaterial(mat);
|
||||
cursorNode->attachMesh(cursorRect);
|
||||
cursorNode->setVisible(false);
|
||||
guiNode->attachChild(cursorNode);
|
||||
}
|
||||
|
||||
Textbox::~Textbox(){
|
||||
guiNode->dettachChild(textNode);
|
||||
guiNode->dettachChild(cursorNode);
|
||||
delete textNode;
|
||||
delete cursorNode;
|
||||
}
|
||||
|
||||
void Textbox::update(){
|
||||
if(enabled){
|
||||
if(canChangeCursor()){
|
||||
canShowCursor = !canShowCursor;
|
||||
lastBlinkTime = getTime();
|
||||
cursorNode->setVisible(canShowCursor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Textbox::type(u32 c, bool capitalLetters){
|
||||
entry += c;
|
||||
text->setText(entry);
|
||||
moveCursor(false, text->getGlyph(c)->size.x);
|
||||
}
|
||||
|
||||
void Textbox::moveCursor(bool left, float charWidth){
|
||||
Vector3 p = cursorNode->getPosition();
|
||||
|
||||
if(left && entry.size() - cursorPosOffset > 0){
|
||||
cursorPosOffset--;
|
||||
cursorNode->setPosition(Vector3(p.x - charWidth, p.y, p.z));
|
||||
}
|
||||
else if(!left){
|
||||
cursorPosOffset++;
|
||||
cursorNode->setPosition(Vector3(p.x + charWidth, p.y, p.z));
|
||||
}
|
||||
}
|
||||
|
||||
void Textbox::deleteCharacter(){
|
||||
if(entry.length() > 0 && canDeleteChar()){
|
||||
char c = entry.c_str()[entry.length() - 1];
|
||||
entry = entry.substr(0, entry.length() - 1);
|
||||
text->setText(entry);
|
||||
moveCursor(true, text->getGlyph(c)->size.x);
|
||||
lastDeleteTime = getTime();
|
||||
}
|
||||
}
|
||||
|
||||
void Textbox::enable(){
|
||||
enabled = true;
|
||||
lastBlinkTime = getTime();
|
||||
cursorNode->setVisible(true);
|
||||
}
|
||||
|
||||
void Textbox::disable(){
|
||||
enabled = false;
|
||||
cursorNode->setVisible(false);
|
||||
|
||||
if(slider){
|
||||
float val = strtof(wstringToString(entry).c_str(), nullptr);
|
||||
|
||||
if(val < slider->getMinValue())
|
||||
val = slider->getMinValue();
|
||||
else if(val > slider->getMaxValue())
|
||||
val = slider->getMaxValue();
|
||||
|
||||
slider->setValue(val);
|
||||
}
|
||||
}
|
||||
|
||||
void Textbox::setEntry(wstring entry){
|
||||
this->entry = entry;
|
||||
text->setText(entry);
|
||||
cursorNode->setPosition(Vector3(pos.x + text->getLength(), pos.y, cursorZCoord));
|
||||
cursorPosOffset = entry.length();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
#ifndef TEXTBOX_H
|
||||
#define TEXTBOX_H
|
||||
|
||||
#include "util.h"
|
||||
#include "text.h"
|
||||
#include "button.h"
|
||||
|
||||
namespace vb01{
|
||||
class Node;
|
||||
class Quad;
|
||||
}
|
||||
|
||||
namespace vb01Gui{
|
||||
class Slider;
|
||||
|
||||
class Textbox{
|
||||
public:
|
||||
Textbox(vb01::Vector2, vb01::Vector2, std::string, std::wstring = L"");
|
||||
~Textbox();
|
||||
void update();
|
||||
void enable();
|
||||
void disable();
|
||||
void type(vb01::u32, bool = false);
|
||||
void moveCursor(bool, float);
|
||||
void deleteCharacter();
|
||||
void setSlider(Slider *s){this->slider = s;}
|
||||
void setEntry(std::wstring);
|
||||
inline bool isEnabled(){return enabled;}
|
||||
inline std::wstring getText(){return text->getText();}
|
||||
void remove();
|
||||
private:
|
||||
class TextboxButton : public Button{
|
||||
public:
|
||||
TextboxButton(Textbox*, vb01::Vector2, vb01::Vector2, std::string);
|
||||
void onClick();
|
||||
private:
|
||||
Textbox *textbox;
|
||||
};
|
||||
inline bool canChangeCursor(){return vb01::getTime() - lastBlinkTime > 250;}
|
||||
inline bool canDeleteChar(){return vb01::getTime() - lastDeleteTime > 50;}
|
||||
|
||||
float cursorZCoord = -.2;
|
||||
const int cursorWidth = 5;
|
||||
vb01::Vector2 pos, size;
|
||||
std::wstring entry = L"";
|
||||
std::string fontPath = "";
|
||||
bool enabled = false, canShowCursor = false, capitalLeters = false;
|
||||
vb01::s64 lastBlinkTime = 0, lastDeleteTime = 0, cursorPosOffset = 0;
|
||||
vb01::Quad *cursorRect;
|
||||
vb01::Text *text;
|
||||
vb01::Node *guiNode, *textNode, *cursorNode;
|
||||
TextboxButton *textboxButton;
|
||||
Slider *slider = nullptr;
|
||||
public:
|
||||
inline TextboxButton* getTextboxButton(){return textboxButton;}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user