mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2025-01-18 07:05:39 +00:00
Reworked OptionListComponent to push a second component when editing the
list to fix the "draw order" problem.
This commit is contained in:
parent
ff85f971b2
commit
9b1ba71fa3
|
@ -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;
|
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue