Reworked OptionListComponent to push a second component when editing the

list to fix the "draw order" problem.
This commit is contained in:
Aloshi 2013-10-12 14:03:32 -05:00
parent ff85f971b2
commit 9b1ba71fa3

View file

@ -15,8 +15,11 @@ class OptionListComponent : public GuiComponent
{ {
public: public:
OptionListComponent(Window* window, bool multiSelect = false) : GuiComponent(window), OptionListComponent(Window* window, bool multiSelect = false) : GuiComponent(window),
mCursor(0), mScrollOffset(0), mMultiSelect(multiSelect), mEditing(false), mBox(window, ":/textbox.png") mMultiSelect(multiSelect)
{ {
if(multiSelect)
setSize(getFont()->sizeText("0 selected"));
else
setSize(getFont()->sizeText("Not set")); setSize(getFont()->sizeText("Not set"));
} }
@ -28,47 +31,16 @@ public:
}; };
bool input(InputConfig* config, Input input) bool input(InputConfig* config, Input input) override
{ {
if(input.value != 0) if(input.value != 0)
{ {
if(config->isMappedTo("b", input))
{
close();
return true;
}
if(config->isMappedTo("a", input)) if(config->isMappedTo("a", input))
{ {
if(mEditing)
{
select(mCursor);
if(!mMultiSelect)
close();
}else{
open(); open();
}
return true;
}
if(mEditing && mEntries.size() > 1)
{
if(config->isMappedTo("up", input))
{
if(mCursor > 0)
mCursor--;
return true;
}
if(config->isMappedTo("down", input))
{
if(mCursor < mEntries.size() - 1)
mCursor++;
return true; return true;
} }
} }
}
return GuiComponent::input(config, input); return GuiComponent::input(config, input);
} }
@ -76,40 +48,6 @@ public:
{ {
std::shared_ptr<Font> font = getFont(); std::shared_ptr<Font> font = getFont();
//draw the option list
if(mEditing)
{
Eigen::Affine3f trans = parentTrans * getTransform();
unsigned int renderCount = mTextCaches.size() - mScrollOffset;
float height = (float)renderCount * font->getHeight();
trans.translate(Eigen::Vector3f(0, -height / 2 + font->getHeight() * 0.5f, 0));
mBox.fitTo(Eigen::Vector2f(mSize.x(), height));
mBox.render(trans);
Renderer::setMatrix(trans);
Renderer::drawRect(0, 0, (int)getSize().x(), (int)height, 0xFFFFFFFF);
for(unsigned int i = mScrollOffset; i < renderCount; i++)
{
Renderer::setMatrix(trans);
char rectOpacity = 0x00;
if(i == mCursor)
rectOpacity += 0x22;
if(mEntries.at(i).selected)
rectOpacity += 0x44;
Renderer::drawRect(0, 0, (int)mSize.x(), font->getHeight(), 0x00000000 | rectOpacity);
Renderer::setMatrix(trans);
font->renderTextCache(mTextCaches.at(i));
trans = trans.translate(Eigen::Vector3f(0, (float)font->getHeight(), 0));
}
}else{
Renderer::setMatrix(parentTrans * getTransform()); Renderer::setMatrix(parentTrans * getTransform());
unsigned int color = 0x000000FF; unsigned int color = 0x000000FF;
@ -144,7 +82,6 @@ public:
if(!found) if(!found)
font->drawText("Not set", Eigen::Vector2f(0, 0), color); font->drawText("Not set", Eigen::Vector2f(0, 0), color);
} }
}
renderChildren(parentTrans * getTransform()); renderChildren(parentTrans * getTransform());
} }
@ -164,16 +101,17 @@ public:
{ {
ListEntry e = selector(*it); ListEntry e = selector(*it);
if(!e.text.empty()) if(!e.text.empty())
mEntries.push_back(e); addEntry(e);
} }
updateTextCaches();
} }
void addEntry(ListEntry e) void addEntry(ListEntry e)
{ {
mEntries.push_back(e); mEntries.push_back(e);
updateTextCaches();
Eigen::Vector2f size = getFont()->sizeText(e.text);
if(size.x() > mSize.x())
setSize(size.x(), mSize.y());
} }
std::vector<const ListEntry*> getSelected() std::vector<const ListEntry*> getSelected()
@ -201,6 +139,11 @@ public:
} }
private: private:
void open()
{
mWindow->pushGui(new OptionListPopup(mWindow, *this));
}
void select(unsigned int i) void select(unsigned int i)
{ {
if(i >= mEntries.size()) if(i >= mEntries.size())
@ -211,18 +154,109 @@ private:
it->selected = false; it->selected = false;
mEntries.at(i).selected = !mEntries.at(i).selected; mEntries.at(i).selected = !mEntries.at(i).selected;
}
std::shared_ptr<Font> getFont()
{
return Font::get(FONT_SIZE_MEDIUM);
}
class OptionListPopup : public GuiComponent
{
public:
OptionListPopup(Window* window, OptionListComponent<T>& optList) : GuiComponent(window),
mOptList(optList), mBox(window, ":/textbox.png"), mCursor(0), mScrollOffset(0)
{
//find global position
GuiComponent* p = &mOptList;
do {
mPosition += p->getPosition();
} while(p = p->getParent());
mSize = mOptList.getSize();
updateTextCaches(); updateTextCaches();
} }
void close() void render(const Eigen::Affine3f& parentTrans) override
{ {
mEditing = false; Eigen::Affine3f trans = parentTrans * getTransform();
std::shared_ptr<Font> font = mOptList.getFont();
unsigned int renderCount = mTextCaches.size() - mScrollOffset;
float height = (float)renderCount * font->getHeight();
trans.translate(Eigen::Vector3f(0, -height / 2 + font->getHeight() * 0.5f, 0));
mBox.fitTo(Eigen::Vector2f(mSize.x(), height));
mBox.render(trans);
Renderer::setMatrix(trans);
Renderer::drawRect(0, 0, (int)getSize().x(), (int)height, 0xFFFFFFFF);
for(unsigned int i = mScrollOffset; i < renderCount; i++)
{
Renderer::setMatrix(trans);
char rectOpacity = 0x00;
if(i == mCursor)
rectOpacity += 0x22;
if(mOptList.mEntries.at(i).selected)
rectOpacity += 0x44;
Renderer::drawRect(0, 0, (int)mSize.x(), font->getHeight(), 0x00000000 | rectOpacity);
Renderer::setMatrix(trans);
font->renderTextCache(mTextCaches.at(i));
trans = trans.translate(Eigen::Vector3f(0, (float)font->getHeight(), 0));
}
} }
void open() bool input(InputConfig* config, Input input)
{ {
mCursor = 0; if(input.value != 0)
mEditing = true; {
if(config->isMappedTo("b", input))
{
close();
return true;
}
if(config->isMappedTo("a", input))
{
mOptList.select(mCursor);
if(!mOptList.mMultiSelect)
close();
return true;
}
if(mOptList.mEntries.size() > 1)
{
if(config->isMappedTo("up", input))
{
if(mCursor > 0)
mCursor--;
return true;
}
if(config->isMappedTo("down", input))
{
if(mCursor < mOptList.mEntries.size() - 1)
mCursor++;
return true;
}
}
}
return GuiComponent::input(config, input);
}
private:
void close()
{
delete this;
} }
void updateTextCaches() void updateTextCaches()
@ -234,34 +268,23 @@ private:
mTextCaches.clear(); mTextCaches.clear();
TextCache* cache; TextCache* cache;
std::shared_ptr<Font> font = getFont(); std::shared_ptr<Font> font = mOptList.getFont();
Eigen::Vector2f newSize = getSize(); for(unsigned int i = 0; i < mOptList.mEntries.size(); i++)
newSize[1] = (float)font->getHeight();
for(unsigned int i = 0; i < mEntries.size(); i++)
{ {
cache = font->buildTextCache(mEntries.at(i).text, 0, 0, 0x000000FF); cache = font->buildTextCache(mOptList.mEntries.at(i).text, 0, 0, 0x000000FF);
mTextCaches.push_back(cache); mTextCaches.push_back(cache);
}
if(cache->metrics.size.x() > newSize.x())
newSize[0] = cache->metrics.size.x();
}
setSize(newSize);
}
std::shared_ptr<Font> getFont()
{
return Font::get(FONT_SIZE_MEDIUM);
} }
OptionListComponent<T>& mOptList;
NinePatchComponent mBox;
unsigned int mCursor; unsigned int mCursor;
unsigned int mScrollOffset; unsigned int mScrollOffset;
bool mMultiSelect; std::vector<TextCache*> mTextCaches;
bool mEditing; };
NinePatchComponent mBox; bool mMultiSelect;
std::vector<ListEntry> mEntries; std::vector<ListEntry> mEntries;
std::vector<TextCache*> mTextCaches;
}; };