mirror of
https://github.com/wiidev/usbloadergx.git
synced 2024-11-22 11:19:17 +01:00
a66a30a771
*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
330 lines
5.9 KiB
C++
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);
|
|
}
|