Created a combobox widget

This commit is contained in:
turanszkij
2017-01-22 15:58:48 +01:00
parent bcfb5d5de3
commit 0495e9b49b
4 changed files with 355 additions and 29 deletions
+69 -29
View File
@@ -10,16 +10,17 @@ LightWindow::LightWindow(wiGUI* gui) : GUI(gui), light(nullptr)
float screenH = (float)wiRenderer::GetDevice()->GetScreenHeight();
lightWindow = new wiWindow(GUI, "Light Window");
lightWindow->SetSize(XMFLOAT2(400, 300));
lightWindow->SetSize(XMFLOAT2(400, 420));
//lightWindow->SetEnabled(false);
GUI->AddWidget(lightWindow);
float x = 200;
float y = 0;
float step = 35;
energySlider = new wiSlider(0.1f, 64, 0, 100000, "Energy: ");
energySlider->SetSize(XMFLOAT2(100, 30));
energySlider->SetPos(XMFLOAT2(x, y += 30));
energySlider->SetPos(XMFLOAT2(x, y += step));
energySlider->OnSlide([&](wiEventArgs args) {
if (light != nullptr)
{
@@ -27,11 +28,12 @@ LightWindow::LightWindow(wiGUI* gui) : GUI(gui), light(nullptr)
}
});
energySlider->SetEnabled(false);
energySlider->SetTooltip("Adjust the light radiation amount inside the maximum range");
lightWindow->AddWidget(energySlider);
distanceSlider = new wiSlider(1, 1000, 0, 100000, "Distance: ");
distanceSlider->SetSize(XMFLOAT2(100, 30));
distanceSlider->SetPos(XMFLOAT2(x, y += 30));
distanceSlider->SetPos(XMFLOAT2(x, y += step));
distanceSlider->OnSlide([&](wiEventArgs args) {
if (light != nullptr)
{
@@ -39,11 +41,12 @@ LightWindow::LightWindow(wiGUI* gui) : GUI(gui), light(nullptr)
}
});
distanceSlider->SetEnabled(false);
distanceSlider->SetTooltip("Adjust the maximum range the light can affect.");
lightWindow->AddWidget(distanceSlider);
fovSlider = new wiSlider(0.1f, XM_PI - 0.01f, 0, 100000, "FOV: ");
fovSlider->SetSize(XMFLOAT2(100, 30));
fovSlider->SetPos(XMFLOAT2(x, y += 30));
fovSlider->SetPos(XMFLOAT2(x, y += step));
fovSlider->OnSlide([&](wiEventArgs args) {
if (light != nullptr)
{
@@ -51,11 +54,12 @@ LightWindow::LightWindow(wiGUI* gui) : GUI(gui), light(nullptr)
}
});
fovSlider->SetEnabled(false);
fovSlider->SetTooltip("Adjust the cone aperture for spotlight.");
lightWindow->AddWidget(fovSlider);
biasSlider = new wiSlider(0.0f, 0.01f, 0, 100000, "ShadowBias: ");
biasSlider->SetSize(XMFLOAT2(100, 30));
biasSlider->SetPos(XMFLOAT2(x, y += 30));
biasSlider->SetPos(XMFLOAT2(x, y += step));
biasSlider->OnSlide([&](wiEventArgs args) {
if (light != nullptr)
{
@@ -63,10 +67,11 @@ LightWindow::LightWindow(wiGUI* gui) : GUI(gui), light(nullptr)
}
});
biasSlider->SetEnabled(false);
biasSlider->SetTooltip("Adjust the shadow bias if shadow artifacts occur.");
lightWindow->AddWidget(biasSlider);
shadowCheckBox = new wiCheckBox("Shadow: ");
shadowCheckBox->SetPos(XMFLOAT2(x, y += 30));
shadowCheckBox->SetPos(XMFLOAT2(x, y += step));
shadowCheckBox->OnClick([&](wiEventArgs args) {
if (light != nullptr)
{
@@ -74,10 +79,11 @@ LightWindow::LightWindow(wiGUI* gui) : GUI(gui), light(nullptr)
}
});
shadowCheckBox->SetEnabled(false);
shadowCheckBox->SetTooltip("Set light as shadow caster. Many shadow casters can affect performance!");
lightWindow->AddWidget(shadowCheckBox);
haloCheckBox = new wiCheckBox("Halo: ");
haloCheckBox->SetPos(XMFLOAT2(x, y += 30));
haloCheckBox->SetPos(XMFLOAT2(x, y += step));
haloCheckBox->OnClick([&](wiEventArgs args) {
if (light != nullptr)
{
@@ -85,10 +91,11 @@ LightWindow::LightWindow(wiGUI* gui) : GUI(gui), light(nullptr)
}
});
haloCheckBox->SetEnabled(false);
haloCheckBox->SetTooltip("Visualize light source emission");
lightWindow->AddWidget(haloCheckBox);
addLightButton = new wiButton("Add Light");
addLightButton->SetPos(XMFLOAT2(x, y += 30));
addLightButton->SetPos(XMFLOAT2(x, y += step));
addLightButton->SetSize(XMFLOAT2(180, 30));
addLightButton->OnClick([&](wiEventArgs args) {
Model* model = new Model;
@@ -99,14 +106,16 @@ LightWindow::LightWindow(wiGUI* gui) : GUI(gui), light(nullptr)
model->lights.push_back(light);
wiRenderer::AddModel(model);
});
addLightButton->SetTooltip("Add a light to the scene. It will be added to the origin.");
lightWindow->AddWidget(addLightButton);
colorPickerToggleButton = new wiButton("Color");
colorPickerToggleButton->SetPos(XMFLOAT2(x, y += 30));
colorPickerToggleButton->SetPos(XMFLOAT2(x, y += step));
colorPickerToggleButton->OnClick([&](wiEventArgs args) {
colorPicker->SetVisible(!colorPicker->IsVisible());
});
colorPickerToggleButton->SetTooltip("Toggle the light color picker.");
lightWindow->AddWidget(colorPickerToggleButton);
@@ -118,9 +127,27 @@ LightWindow::LightWindow(wiGUI* gui) : GUI(gui), light(nullptr)
});
GUI->AddWidget(colorPicker);
typeSelectorComboBox = new wiComboBox("Type: ");
typeSelectorComboBox->SetPos(XMFLOAT2(x, y += step));
typeSelectorComboBox->OnSelect([&](wiEventArgs args) {
if (light != nullptr && args.iValue >= 0)
{
light->type = (Light::LightType)args.iValue;
SetLightType(light->type); // for the gui changes to apply to the new type
}
});
typeSelectorComboBox->SetEnabled(false);
typeSelectorComboBox->AddItem("Directional");
typeSelectorComboBox->AddItem("Point");
typeSelectorComboBox->AddItem("Spot");
typeSelectorComboBox->SetTooltip("Choose the light source type...");
lightWindow->AddWidget(typeSelectorComboBox);
lightWindow->Translate(XMFLOAT3(30, 30, 0));
lightWindow->SetVisible(false);
SetLight(nullptr);
}
@@ -136,6 +163,7 @@ LightWindow::~LightWindow()
SAFE_DELETE(addLightButton);
SAFE_DELETE(colorPickerToggleButton);
SAFE_DELETE(colorPicker);
SAFE_DELETE(typeSelectorComboBox);
}
void LightWindow::SetLight(Light* light)
@@ -146,38 +174,50 @@ void LightWindow::SetLight(Light* light)
//lightWindow->SetEnabled(true);
energySlider->SetEnabled(true);
energySlider->SetValue(light->enerDis.x);
if (light->type == Light::DIRECTIONAL)
{
distanceSlider->SetEnabled(false);
fovSlider->SetEnabled(false);
}
else
{
distanceSlider->SetEnabled(true);
distanceSlider->SetValue(light->enerDis.y);
if (light->type == Light::SPOT)
{
fovSlider->SetEnabled(true);
fovSlider->SetValue(light->enerDis.z);
}
else
{
fovSlider->SetEnabled(false);
}
}
distanceSlider->SetValue(light->enerDis.y);
fovSlider->SetValue(light->enerDis.z);
biasSlider->SetEnabled(true);
biasSlider->SetValue(light->shadowBias);
shadowCheckBox->SetEnabled(true);
shadowCheckBox->SetCheck(light->shadow);
haloCheckBox->SetEnabled(true);
haloCheckBox->SetCheck(!light->noHalo);
colorPicker->SetEnabled(true);
typeSelectorComboBox->SetEnabled(true);
typeSelectorComboBox->SetSelected((int)light->type);
SetLightType(light->type);
}
else
{
distanceSlider->SetEnabled(false);
fovSlider->SetEnabled(false);
biasSlider->SetEnabled(false);
shadowCheckBox->SetEnabled(false);
haloCheckBox->SetEnabled(false);
energySlider->SetEnabled(false);
//lightWindow->SetEnabled(false);
colorPicker->SetEnabled(false);
typeSelectorComboBox->SetEnabled(false);
//lightWindow->SetEnabled(false);
}
}
void LightWindow::SetLightType(Light::LightType type)
{
if (type == Light::DIRECTIONAL)
{
distanceSlider->SetEnabled(false);
fovSlider->SetEnabled(false);
}
else
{
distanceSlider->SetEnabled(true);
if (type == Light::SPOT)
{
fovSlider->SetEnabled(true);
}
else
{
fovSlider->SetEnabled(false);
}
}
}
+3
View File
@@ -8,6 +8,7 @@ class wiCheckBox;
class wiSlider;
class wiButton;
class wiColorPicker;
class wiComboBox;
struct Light;
@@ -20,6 +21,7 @@ public:
wiGUI* GUI;
void SetLight(Light* light);
void SetLightType(Light::LightType type);
Light* light;
@@ -33,5 +35,6 @@ public:
wiButton* addLightButton;
wiButton* colorPickerToggleButton;
wiColorPicker* colorPicker;
wiComboBox* typeSelectorComboBox;
};
+241
View File
@@ -661,6 +661,247 @@ bool wiCheckBox::GetCheck()
wiComboBox::wiComboBox(const string& name) :wiWidget()
, selected(-1), combostate(COMBOSTATE_INACTIVE), hovered(-1)
{
SetName(name);
SetText(fastName.GetString());
OnSelect([](wiEventArgs args) {});
SetSize(XMFLOAT2(100, 20));
}
wiComboBox::~wiComboBox()
{
}
const float wiComboBox::_GetItemOffset(int index) const
{
return scale.y * (index + 1) + 1;
}
void wiComboBox::Update(wiGUI* gui)
{
wiWidget::Update(gui);
if (!IsEnabled())
{
return;
}
if (gui->IsWidgetDisabled(this))
{
return;
}
if (state == FOCUS)
{
state = IDLE;
}
if (state == DEACTIVATING)
{
state = IDLE;
}
if (state == ACTIVE && combostate == COMBOSTATE_SELECTING)
{
gui->DeactivateWidget(this);
}
hitBox.pos.x = Transform::translation.x;
hitBox.pos.y = Transform::translation.y;
hitBox.siz.x = Transform::scale.x + scale.y + 1; // + drop-down indicator arrow + little offset
hitBox.siz.y = Transform::scale.y;
Hitbox2D pointerHitbox = Hitbox2D(gui->GetPointerPos(), XMFLOAT2(1, 1));
bool clicked = false;
// hover the button
if (pointerHitbox.intersects(hitBox))
{
if (state == IDLE)
{
state = FOCUS;
}
}
if (wiInputManager::GetInstance()->press(VK_LBUTTON, wiInputManager::KEYBOARD))
{
// activate
clicked = true;
}
if (wiInputManager::GetInstance()->down(VK_LBUTTON, wiInputManager::KEYBOARD))
{
if (state == DEACTIVATING)
{
// Keep pressed until mouse is released
gui->ActivateWidget(this);
}
}
if (clicked && state == FOCUS)
{
gui->ActivateWidget(this);
}
if (state == ACTIVE)
{
if (combostate == COMBOSTATE_INACTIVE)
{
combostate = COMBOSTATE_HOVER;
}
else if (combostate == COMBOSTATE_SELECTING)
{
gui->DeactivateWidget(this);
combostate = COMBOSTATE_INACTIVE;
}
else
{
hovered = -1;
for (size_t i = 0; i < items.size(); ++i)
{
Hitbox2D itembox;
itembox.pos.x = Transform::translation.x;
itembox.pos.y = Transform::translation.y + _GetItemOffset((int)i);
itembox.siz.x = Transform::scale.x;
itembox.siz.y = Transform::scale.y;
if (pointerHitbox.intersects(itembox))
{
hovered = (int)i;
break;
}
}
if (clicked)
{
combostate = COMBOSTATE_SELECTING;
if (hovered >= 0)
{
SetSelected(hovered);
}
}
}
}
}
void wiComboBox::Render(wiGUI* gui)
{
assert(gui != nullptr && "Ivalid GUI!");
if (!IsVisible())
{
return;
}
wiColor color = GetColor();
if (combostate != COMBOSTATE_INACTIVE)
{
color = colors[FOCUS];
}
// control-base
wiImage::Draw(wiTextureHelper::getInstance()->getColor(color)
, wiImageEffects(translation.x, translation.y, scale.x, scale.y), gui->GetGraphicsThread());
// control-arrow
wiImage::Draw(wiTextureHelper::getInstance()->getColor(color)
, wiImageEffects(translation.x+scale.x+1, translation.y, scale.y, scale.y), gui->GetGraphicsThread());
wiFont("V", wiFontProps((int)(translation.x+scale.x+scale.y*0.5f), (int)(translation.y + scale.y*0.5f), -1, WIFALIGN_CENTER, WIFALIGN_CENTER)).Draw(gui->GetGraphicsThread(), false);
if (parent != nullptr)
{
wiRenderer::GetDevice()->SetScissorRects(1, &scissorRect, gui->GetGraphicsThread());
}
wiFont(text, wiFontProps((int)(translation.x), (int)(translation.y + scale.y*0.5f), -1, WIFALIGN_RIGHT, WIFALIGN_CENTER)).Draw(gui->GetGraphicsThread(), parent != nullptr);
if (selected >= 0)
{
wiFont(items[selected], wiFontProps((int)(translation.x + scale.x*0.5f), (int)(translation.y + scale.y*0.5f), -1, WIFALIGN_CENTER, WIFALIGN_CENTER)).Draw(gui->GetGraphicsThread(), parent != nullptr);
}
// drop-down
if (state == ACTIVE)
{
// control-list
int i = 0;
for (auto& x : items)
{
wiColor col = colors[IDLE];
if (hovered == i)
{
if (combostate == COMBOSTATE_HOVER)
{
col = colors[FOCUS];
}
else if (combostate == COMBOSTATE_SELECTING)
{
col = colors[ACTIVE];
}
}
wiImage::Draw(wiTextureHelper::getInstance()->getColor(col)
, wiImageEffects(translation.x, translation.y + _GetItemOffset(i), scale.x, scale.y), gui->GetGraphicsThread());
wiFont(x, wiFontProps((int)(translation.x + scale.x*0.5f), (int)(translation.y + scale.y*0.5f +_GetItemOffset(i)), -1, WIFALIGN_CENTER, WIFALIGN_CENTER)).Draw(gui->GetGraphicsThread(), false);
i++;
}
}
}
void wiComboBox::OnSelect(function<void(wiEventArgs args)> func)
{
onSelect = move(func);
}
void wiComboBox::AddItem(const string& item)
{
items.push_back(item);
if (selected < 0)
{
selected = 0;
}
}
void wiComboBox::RemoveItem(int index)
{
vector<string> newItems(0);
newItems.reserve(items.size());
for (size_t i = 0; i < items.size(); ++i)
{
if (i != index)
{
newItems.push_back(items[i]);
}
}
items = newItems;
if (items.empty())
{
selected = -1;
}
else if (selected > index)
{
selected--;
}
}
void wiComboBox::ClearItems()
{
items.clear();
selected = -1;
}
void wiComboBox::SetSelected(int index)
{
selected = index;
wiEventArgs args;
args.iValue = selected;
onSelect(args);
}
int wiComboBox::GetSelected()
{
return selected;
}
static const float windowcontrolSize = 20.0f;
wiWindow::wiWindow(wiGUI* gui, const string& name) :wiWidget()
, gui(gui)
+42
View File
@@ -16,6 +16,7 @@ struct wiEventArgs
XMFLOAT2 endPos;
float fValue;
bool bValue;
int iValue;
XMFLOAT4 color;
};
@@ -160,6 +161,47 @@ public:
void OnClick(function<void(wiEventArgs args)> func);
};
// Drop-down list
class wiComboBox :public wiWidget
{
protected:
function<void(wiEventArgs args)> onSelect;
Hitbox2D hitBox;
int selected;
// While the widget is active (rolled down) these are the inner states that control behaviour
enum COMBOSTATE
{
// When the list is just being dropped down, or the widget is not active
COMBOSTATE_INACTIVE,
// The widget is in drop-down state with the last item hovered highlited
COMBOSTATE_HOVER,
// The hovered item is clicked
COMBOSTATE_SELECTING,
COMBOSTATE_COUNT,
} combostate;
int hovered;
vector<string> items;
const float _GetItemOffset(int index) const;
public:
wiComboBox(const string& name = "");
virtual ~wiComboBox();
void AddItem(const string& item);
void RemoveItem(int index);
void ClearItems();
void SetSelected(int index);
int GetSelected();
virtual void Update(wiGUI* gui) override;
virtual void Render(wiGUI* gui) override;
void OnSelect(function<void(wiEventArgs args)> func);
};
// Widget container
class wiWindow :public wiWidget
{