Created a combobox widget
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user