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) {
|
2017-10-29 16:03:33 +01:00
|
|
|
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 16:03:33 +01:00
|
|
|
|
2017-10-29 10:28:14 +01:00
|
|
|
valueButtons[i].valueButton = new GuiButton(valueButtons[i].valueButtonImg->getWidth() * imgScale, valueButtons[i].valueButtonImg->getHeight() * imgScale);
|
2020-05-15 11:12:16 +02:00
|
|
|
valueButtons[i].valueButtonText = new GuiText(itr->first.c_str(),32,glm::vec4(1.0f, 1.0f, 1.0f, 1.0f), 1);
|
2017-10-29 10:28:14 +01:00
|
|
|
|
|
|
|
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;
|
2017-10-29 16:03:33 +01:00
|
|
|
|
2018-06-21 20:44:58 +02:00
|
|
|
float topHeight = 0;
|
|
|
|
if(topBackgroundImg != NULL) {
|
2017-10-29 16:03:33 +01:00
|
|
|
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);
|
|
|
|
}
|