libgui/source/gui/GuiSelectBox.cpp

297 lines
10 KiB
C++
Raw Normal View History

2017-10-29 10:28:14 +01:00
/****************************************************************************
* Copyright (C) 2016 Maschell
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/
#include <vector>
#include <string>
2017-10-31 17:18:42 +01:00
2018-06-21 20:44:58 +02:00
#include <gui/GuiSelectBox.h>
#include <gui/GuiImage.h>
#include <gui/GuiTrigger.h>
#include <gui/GuiImageData.h>
2017-10-31 17:18:42 +01:00
2017-10-29 10:28:14 +01:00
/**
* Constructor for the GuiCheckBox class.
*/
2018-06-21 20:44:58 +02:00
GuiSelectBox::GuiSelectBox(GuiImage * background,std::string caption,float width,float height,GuiFrame *parent)
: GuiFrame(width,height,parent)
,selected(0)
,captionText(caption)
,topValueButton(0,0)
,touchTrigger(GuiTrigger::CHANNEL_1, GuiTrigger::VPAD_TOUCH)
,wpadTouchTrigger(GuiTrigger::CHANNEL_2 | GuiTrigger::CHANNEL_3 | GuiTrigger::CHANNEL_4 | GuiTrigger::CHANNEL_5, GuiTrigger::BUTTON_A)
,buttonATrigger(GuiTrigger::CHANNEL_ALL, GuiTrigger::BUTTON_A, true)
,buttonBTrigger(GuiTrigger::CHANNEL_ALL, GuiTrigger::BUTTON_B, true)
,buttonUpTrigger(GuiTrigger::CHANNEL_ALL, GuiTrigger::BUTTON_UP | GuiTrigger::STICK_L_UP, true)
,buttonDownTrigger(GuiTrigger::CHANNEL_ALL, GuiTrigger::BUTTON_DOWN | GuiTrigger::STICK_L_DOWN, true)
,DPADButtons(0,0) {
2017-10-31 17:18:42 +01:00
setImageTopBackground(background);
2017-10-29 10:28:14 +01:00
showValues = false;
bChanged = false;
bSelectedChanged = false;
opened = false;
topValueText.setFontSize(32);
topValueText.setAlignment(ALIGN_LEFT);
topValueText.setPosition(10,-7);
topValueButton.setLabel(&topValueText);
topValueButton.setTrigger(&touchTrigger);
topValueButton.setTrigger(&wpadTouchTrigger);
topValueButton.clicked.connect(this, &GuiSelectBox::OnTopValueClicked);
valuesFrame.setState(STATE_HIDDEN);
DPADButtons.setTrigger(&buttonBTrigger);
DPADButtons.setTrigger(&buttonATrigger);
DPADButtons.setTrigger(&buttonDownTrigger);
DPADButtons.setTrigger(&buttonUpTrigger);
DPADButtons.clicked.connect(this, &GuiSelectBox::OnDPADClick);
DPADButtons.setState(STATE_DISABLE_INPUT);
append(&DPADButtons);
append(&valuesFrame);
append(&topValueButton);
showValues = false;
bChanged = true;
}
2018-06-21 20:44:58 +02:00
void GuiSelectBox::setSize(float width,float height) {
2017-10-31 17:18:42 +01:00
GuiFrame::setSize(width,height);
topValueButton.setSize(width,height);
}
2018-06-21 20:44:58 +02:00
void GuiSelectBox::OnValueClicked(GuiButton *button, const GuiController *controller, GuiTrigger *trigger) {
for(uint32_t i = 0; i < valueButtons.size(); ++i) {
if(valueButtons[i].valueButton == button) {
selected = i;
SelectValue(i);
break;
}
2017-10-29 10:28:14 +01:00
}
}
2018-06-21 20:44:58 +02:00
void GuiSelectBox::SelectValue(uint32_t value) {
if(value < valueButtons.size()) {
2017-10-29 10:28:14 +01:00
const wchar_t* w_text = valueButtons[value].valueButtonText->getText();
std::wstring ws(w_text);
std::string text(ws.begin(), ws.end());
topValueText.setText(text.c_str());
std::string real_value = buttonToValue[valueButtons[value].valueButton];
if(real_value.compare(std::string()) == 0) real_value = "<error>";
valueChanged(this,real_value);
ShowHideValues(false);
}
}
2018-06-21 20:44:58 +02:00
void GuiSelectBox::OnTopValueClicked(GuiButton *button, const GuiController *controller, GuiTrigger *trigger) {
2017-10-29 10:28:14 +01:00
ShowHideValues(!showValues);
}
2018-06-21 20:44:58 +02:00
void GuiSelectBox::ShowHideValues(bool showhide) {
2017-10-29 10:28:14 +01:00
showValues = showhide;
bChanged = true;
}
2018-06-21 20:44:58 +02:00
void GuiSelectBox::OnDPADClick(GuiButton *button, const GuiController *controller, GuiTrigger *trigger) {
if(opened == true) {
if(trigger == &buttonATrigger) {
2017-10-29 10:28:14 +01:00
//! do not auto launch when wiimote is pointing to screen and presses A
2018-06-21 20:44:58 +02:00
if((controller->chan & (GuiTrigger::CHANNEL_2 | GuiTrigger::CHANNEL_3 | GuiTrigger::CHANNEL_4 | GuiTrigger::CHANNEL_5)) && controller->data.validPointer) {
2017-10-29 10:28:14 +01:00
return;
}
SelectValue(selected);
2018-06-21 20:44:58 +02:00
} else if(trigger == &buttonBTrigger) {
if(button == &DPADButtons) {
2017-10-29 10:28:14 +01:00
ShowHideValues(false);
2018-06-21 20:44:58 +02:00
} else {
}
} else if(trigger == &buttonUpTrigger) {
2017-10-29 10:28:14 +01:00
if(selected > 0 ) selected--;
bSelectedChanged = true;
2018-06-21 20:44:58 +02:00
} else if(trigger == &buttonDownTrigger) {
2017-10-29 10:28:14 +01:00
selected++;
if(selected >= valueButtons.size()) selected = valueButtons.size() - 1;
bSelectedChanged = true;
}
}
}
2018-06-21 20:44:58 +02:00
void GuiSelectBox::Init(std::map<std::string,std::string> values, int32_t valueID) {
if((uint32_t)valueID >= values.size()) {
2017-10-29 10:28:14 +01:00
valueID = 0;
}
selected = valueID;
bSelectedChanged = true;
DeleteValueData();
2018-06-21 20:44:58 +02:00
if(valueImageData == NULL || valueSelectedImageData == NULL || valueHighlightedImageData == NULL) {
return;
}
2017-10-29 10:28:14 +01:00
valueButtons.resize(values.size());
2018-06-21 20:44:58 +02:00
int32_t i = 0;
float imgScale = 1.0f;
2017-10-29 10:28:14 +01:00
std::map<std::string, std::string>::iterator itr;
for(itr = values.begin(); itr != values.end(); itr++) {
2018-06-21 20:44:58 +02:00
if(i == valueID) {
2017-10-29 10:28:14 +01:00
topValueText.setText(itr->first.c_str());
}
valueButtons[i].valueButtonImg = new GuiImage(valueImageData);
valueButtons[i].valueButtonCheckedImg = new GuiImage(valueSelectedImageData);
valueButtons[i].valueButtonHighlightedImg = new GuiImage(valueHighlightedImageData);
2017-10-29 10:28:14 +01:00
valueButtons[i].valueButton = new GuiButton(valueButtons[i].valueButtonImg->getWidth() * imgScale, valueButtons[i].valueButtonImg->getHeight() * imgScale);
valueButtons[i].valueButtonText = new GuiText(itr->first.c_str(),32,glm::vec4(1.0f, 1.0f, 1.0f, 1.0f));
valueButtons[i].valueButtonText->setMaxWidth(valueButtons[i].valueButtonImg->getWidth() * imgScale - 20.0f, GuiText::WRAP);
valueButtons[i].valueButtonText->setPosition(0, 0);
valueButtons[i].valueButtonImg->setScale(imgScale);
valueButtons[i].valueButtonCheckedImg->setScale(imgScale);
valueButtons[i].valueButton->setImage(valueButtons[i].valueButtonImg);
valueButtons[i].valueButton->setIconOver(valueButtons[i].valueButtonHighlightedImg);
valueButtons[i].valueButton->setTrigger(&touchTrigger);
valueButtons[i].valueButton->setTrigger(&wpadTouchTrigger);
valueButtons[i].valueButton->clicked.connect(this,&GuiSelectBox::OnValueClicked);
valueButtons[i].valueButton->setSoundClick(buttonClickSound);
valueButtons[i].valueButton->setLabel(valueButtons[i].valueButtonText);
//valueButtons[i].valueButton->setState(STATE_HIDDEN); //Wont get disabled soon enough
buttonToValue[valueButtons[i].valueButton] = itr->second;
2018-06-21 20:44:58 +02:00
float topHeight = 0;
if(topBackgroundImg != NULL) {
topHeight = topBackgroundImg->getHeight();
}
2018-06-21 20:44:58 +02:00
int32_t ypos = (((valueButtons[i].valueButtonImg->getHeight()*getScale()) * (i))+ (topHeight-5)*getScale())*-1.0f;
2017-10-29 10:28:14 +01:00
valueButtons[i].valueButton->setPosition(0, ypos);
valuesFrame.append(valueButtons[i].valueButton);
i++;
}
//Collapse the thing!
showValues = false;
bChanged = true;
}
2018-06-21 20:44:58 +02:00
void GuiSelectBox::DeleteValueData() {
for(uint32_t i = 0; i < valueButtons.size(); ++i) {
2017-10-29 10:28:14 +01:00
valuesFrame.remove(valueButtons[i].valueButton);
delete valueButtons[i].valueButtonImg;
delete valueButtons[i].valueButtonCheckedImg;
delete valueButtons[i].valueButtonHighlightedImg;
delete valueButtons[i].valueButton;
delete valueButtons[i].valueButtonText;
}
buttonToValue.clear();
valueButtons.clear();
}
/**
* Destructor for the GuiButton class.
*/
2018-06-21 20:44:58 +02:00
GuiSelectBox::~GuiSelectBox() {
2017-10-29 10:28:14 +01:00
DeleteValueData();
bChanged = false;
selected = 0;
showValues = false;
}
2018-06-21 20:44:58 +02:00
void GuiSelectBox::setState(int32_t s, int32_t c) {
GuiElement::setState(s, c);
2017-10-29 10:28:14 +01:00
}
2018-06-21 20:44:58 +02:00
void GuiSelectBox::OnValueCloseEffectFinish(GuiElement *element) {
2017-10-29 10:28:14 +01:00
valuesFrame.effectFinished.disconnect(this);
}
2018-06-21 20:44:58 +02:00
float GuiSelectBox::getTopValueHeight() {
if(topBackgroundImg == NULL) {
2017-10-31 17:18:42 +01:00
return 0.0f;
}
return topBackgroundImg->getHeight();
2017-10-29 10:28:14 +01:00
}
2018-06-21 20:44:58 +02:00
float GuiSelectBox::getTopValueWidth() {
if(topBackgroundImg == NULL) {
2017-10-31 17:18:42 +01:00
return 0.0f;
}
return topBackgroundImg->getWidth();
2017-10-29 10:28:14 +01:00
}
2018-06-21 20:44:58 +02:00
float GuiSelectBox::getHeight() {
2017-10-29 10:28:14 +01:00
return getTopValueHeight();
}
2018-06-21 20:44:58 +02:00
float GuiSelectBox::getWidth() {
2017-10-29 10:28:14 +01:00
return getTopValueWidth();
}
2018-06-21 20:44:58 +02:00
void GuiSelectBox::OnValueOpenEffectFinish(GuiElement *element) {
2017-10-29 10:28:14 +01:00
valuesFrame.effectFinished.disconnect(this);
opened = true;
}
2018-06-21 20:44:58 +02:00
void GuiSelectBox::update(GuiController * c) {
if(bChanged) {
2017-10-29 10:28:14 +01:00
showhide(this,showValues);
2018-06-21 20:44:58 +02:00
if(showValues) {
for(uint32_t i = 0; i < valueButtons.size(); ++i) { //TODO: only set when it really changed
if(i == selected) {
2017-10-29 10:28:14 +01:00
valueButtons[i].valueButton->setImage(valueButtons[i].valueButtonCheckedImg);
2018-06-21 20:44:58 +02:00
} else {
valueButtons[i].valueButton->setImage(valueButtons[i].valueButtonImg);
2017-10-29 10:28:14 +01:00
}
}
valuesFrame.clearState(STATE_HIDDEN);
DPADButtons.clearState(STATE_DISABLE_INPUT);
valuesFrame.setEffect(EFFECT_FADE, 10, 255);
valuesFrame.effectFinished.connect(this, &GuiSelectBox::OnValueCloseEffectFinish);
2018-06-21 20:44:58 +02:00
} else {
2017-10-29 10:28:14 +01:00
opened = false;
valuesFrame.setState(STATE_HIDDEN);
DPADButtons.setState(STATE_DISABLE_INPUT);
valuesFrame.setEffect(EFFECT_FADE, -10, 0);
valuesFrame.effectFinished.connect(this, &GuiSelectBox::OnValueOpenEffectFinish);
}
bChanged = false;
}
2018-06-21 20:44:58 +02:00
if(bSelectedChanged) {
for(uint32_t i = 0; i < valueButtons.size(); ++i) {
if(i == selected) {
valueButtons[i].valueButton->setState(STATE_SELECTED);
} else {
valueButtons[i].valueButton->clearState(STATE_SELECTED);
2017-10-29 10:28:14 +01:00
}
}
}
topValueButton.setState(getState());
GuiFrame::update(c);
}