usbloadergx/source/GUI/gui_window.cpp
strtoul a66a30a771 *removed buggy focus system completely (it was never working correct)
*added support to control screen pointer with gc pad or classic controller. you are always able to control as long as the corresponding wii control does not point to the screen (e.g. wiimote 1 not pointing to screen -> gcpad/classic controller 1 can control pointer 1). a speed factor is added to the gui option. need feedback about a proper default value, currently 15% (only tested gc pad on dolphin-emu)
*fix reinit of cheatcount on download of new file
*moved installation window to be on top of main window
*added game installation cancel
*added nand extract cancel
*added back extract of save feature for a real nand channels
*added auto position of progress window messages in vertical direction depending of how many are used at the same time
2011-12-28 16:27:30 +00:00

330 lines
5.9 KiB
C++

/****************************************************************************
* libwiigui
*
* Tantric 2009
*
* gui_window.cpp
*
* GUI class definitions
***************************************************************************/
#include "gui.h"
GuiWindow::GuiWindow()
{
width = 0;
height = 0;
forceDim = false;
allowDim = true;
}
GuiWindow::GuiWindow(int w, int h)
{
width = w;
height = h;
forceDim = false;
allowDim = true;
}
GuiWindow::~GuiWindow()
{
}
void GuiWindow::Append(GuiElement* e)
{
LOCK( this );
if (e == NULL) return;
Remove(e);
_elements.push_back(e);
e->SetParent(this);
}
void GuiWindow::Insert(GuiElement* e, u32 index)
{
LOCK( this );
if (e == NULL || index > (_elements.size() - 1)) return;
Remove(e);
_elements.insert(_elements.begin() + index, e);
e->SetParent(this);
}
void GuiWindow::Remove(GuiElement* e)
{
LOCK( this );
if (e == NULL) return;
for (u8 i = 0; i < _elements.size(); i++)
{
if (e == _elements.at(i))
{
_elements.erase(_elements.begin() + i);
break;
}
}
}
void GuiWindow::RemoveAll()
{
LOCK( this );
_elements.clear();
}
GuiElement* GuiWindow::GetGuiElementAt(u32 index) const
{
if (index >= _elements.size()) return NULL;
return _elements.at(index);
}
u32 GuiWindow::GetSize()
{
return _elements.size();
}
void GuiWindow::Draw()
{
LOCK( this );
if (_elements.size() == 0 || !this->IsVisible()) return;
for (u8 i = 0; i < _elements.size(); i++)
{
try
{
_elements.at(i)->Draw();
}
catch (const std::exception& e)
{
}
}
this->UpdateEffects();
if ((parentElement && state == STATE_DISABLED && allowDim) || forceDim)
Menu_DrawRectangle(0, 0, screenwidth, screenheight, (GXColor) {0, 0, 0, 0x70}, 1);
}
void GuiWindow::DrawTooltip()
{
LOCK( this );
if (_elements.size() == 0 || !this->IsVisible()) return;
for (u8 i = 0; i < _elements.size(); i++)
{
try
{
_elements.at(i)->DrawTooltip();
}
catch (const std::exception& e)
{
}
}
}
void GuiWindow::ResetState()
{
LOCK( this );
if (state != STATE_DISABLED) state = STATE_DEFAULT;
for (u8 i = 0; i < _elements.size(); i++)
{
try
{
_elements.at(i)->ResetState();
}
catch (const std::exception& e)
{
}
}
}
void GuiWindow::SetState(int s)
{
LOCK( this );
state = s;
for (u8 i = 0; i < _elements.size(); i++)
{
try
{
_elements.at(i)->SetState(s);
}
catch (const std::exception& e)
{
}
}
}
void GuiWindow::SetVisible(bool v)
{
LOCK( this );
visible = v;
for (u8 i = 0; i < _elements.size(); i++)
{
try
{
_elements.at(i)->SetVisible(v);
}
catch (const std::exception& e)
{
}
}
}
int GuiWindow::GetSelected()
{
// find selected element
int found = -1;
for (u8 i = 0; i < _elements.size(); i++)
{
try
{
if (_elements.at(i)->GetState() == STATE_SELECTED)
{
found = i;
break;
}
}
catch (const std::exception& e)
{
}
}
return found;
}
// set element to left/right as selected
// there's probably a more clever way to do this, but this way works
void GuiWindow::MoveSelectionHor(int dir)
{
LOCK( this );
int found = -1;
u16 left = 0;
u16 top = 0;
u8 i = 0;
int selected = this->GetSelected();
if (selected >= 0)
{
left = _elements.at(selected)->GetLeft();
top = _elements.at(selected)->GetTop();
}
// look for a button on the same row, to the left/right
for (i = 0; i < _elements.size(); i++)
{
try
{
if (_elements.at(i)->IsSelectable())
{
if (_elements.at(i)->GetLeft() * dir > left * dir && _elements.at(i)->GetTop() == top)
{
if (found == -1)
found = i;
else if (_elements.at(i)->GetLeft() * dir < _elements.at(found)->GetLeft() * dir) found = i; // this is a better match
}
}
}
catch (const std::exception& e)
{
}
}
if (found >= 0) goto matchfound;
// match still not found, let's try the first button in the next row
for (i = 0; i < _elements.size(); i++)
{
try
{
if (_elements.at(i)->IsSelectable())
{
if (_elements.at(i)->GetTop() * dir > top * dir)
{
if (found == -1)
found = i;
else if (_elements.at(i)->GetTop() * dir < _elements.at(found)->GetTop() * dir)
found = i; // this is a better match
else if (_elements.at(i)->GetTop() * dir == _elements.at(found)->GetTop() * dir
&& _elements.at(i)->GetLeft() * dir < _elements.at(found)->GetLeft() * dir) found = i; // this is a better match
}
}
}
catch (const std::exception& e)
{
}
}
// match found
matchfound: if (found >= 0)
{
_elements.at(found)->SetState(STATE_SELECTED);
if (selected >= 0) _elements.at(selected)->ResetState();
}
}
void GuiWindow::MoveSelectionVert(int dir)
{
LOCK( this );
int found = -1;
u16 left = 0;
u16 top = 0;
u8 i = 0;
int selected = this->GetSelected();
if (selected >= 0)
{
left = _elements.at(selected)->GetLeft();
top = _elements.at(selected)->GetTop();
}
// look for a button above/below, with the least horizontal difference
for (i = 0; i < _elements.size(); i++)
{
try
{
if (_elements.at(i)->IsSelectable())
{
if (_elements.at(i)->GetTop() * dir > top * dir)
{
if (found == -1)
found = i;
else if (_elements.at(i)->GetTop() * dir < _elements.at(found)->GetTop() * dir)
found = i; // this is a better match
else if (_elements.at(i)->GetTop() * dir == _elements.at(found)->GetTop() * dir && abs(
_elements.at(i)->GetLeft() - left) < abs(_elements.at(found)->GetLeft() - left)) found = i;
}
}
}
catch (const std::exception& e)
{
}
}
if (found >= 0) goto matchfound;
// match found
matchfound: if (found >= 0)
{
_elements.at(found)->SetState(STATE_SELECTED);
if (selected >= 0) _elements.at(selected)->ResetState();
}
}
void GuiWindow::Update(GuiTrigger * t)
{
LOCK( this );
if (_elements.size() == 0 || (state == STATE_DISABLED && parentElement)) return;
for (u8 i = 0; i < _elements.size(); i++)
{
try
{
_elements.at(i)->Update(t);
}
catch (const std::exception& e)
{
}
}
if (updateCB) updateCB(this);
}