mirror of
https://github.com/wiidev/usbloadergx.git
synced 2024-11-04 18:45:05 +01:00
e11901bc09
*Fixed cutoff of box cover when it is too near and increased zoom range of the box cover. Reworked the move/zoom of the cover. *Change wiimote icon when grabbing and dragging the box cover to grab icon *Fixed bug in homebrew browser (crash) *Changed a few default GX view configurations *Use proper size of wiimote pointer image instead of hard coded values *Reworked scroll/B hold movement stuff from the game list layout *Removed buildtype.sh and added the define directly in makefile. No need to make an extra header for that. *Changed makefile a to allow different IOS build modes. The build IOS is used at the start of the loader to load the settings under. If the build IOS is the same as the settings boot IOS the startup is a lot faster since no IOS reload is required. To build yourself a special IOS build version type:"make IOS=XXX" where XXX is the number of the IOS (CSettings.cp has to be recompiled for that at least). If nothing is defined IOS222 is taken. There will now be always two versions supplied (IOS222 and IOS249 version). If another build is required build it yourself. You can see the revisions until now as the "IOS249 build version" since they behaved like that.
512 lines
13 KiB
C++
512 lines
13 KiB
C++
/****************************************************************************
|
||
* libwiigui
|
||
*
|
||
* Tantric 2009
|
||
*
|
||
* gui_button.cpp
|
||
*
|
||
* GUI class definitions
|
||
***************************************************************************/
|
||
|
||
#include "gui.h"
|
||
|
||
static int scrollison = 0;
|
||
|
||
/**
|
||
* Constructor for the GuiButton class.
|
||
*/
|
||
|
||
GuiButton::GuiButton(int w, int h)
|
||
{
|
||
width = w;
|
||
height = h;
|
||
image = NULL;
|
||
imageOver = NULL;
|
||
imageHold = NULL;
|
||
imageClick = NULL;
|
||
icon = NULL;
|
||
iconOver = NULL;
|
||
iconHold = NULL;
|
||
iconClick = NULL;
|
||
toolTip = NULL;
|
||
|
||
for (int i = 0; i < 3; i++)
|
||
{
|
||
label[i] = NULL;
|
||
labelOver[i] = NULL;
|
||
labelHold[i] = NULL;
|
||
labelClick[i] = NULL;
|
||
}
|
||
|
||
soundOver = NULL;
|
||
soundHold = NULL;
|
||
soundClick = NULL;
|
||
selectable = true;
|
||
holdable = false;
|
||
clickable = true;
|
||
|
||
time1 = time2 = 0;
|
||
}
|
||
|
||
GuiButton::GuiButton(GuiImage* img, GuiImage* imgOver, int hor, int vert, int x, int y, GuiTrigger* trig,
|
||
GuiSound* sndOver, GuiSound* sndClick, u8 grow)
|
||
{
|
||
width = img ? img->GetWidth() : 0;
|
||
height = img ? img->GetHeight() : 0;
|
||
image = img;
|
||
if(image) image->SetParent(this);
|
||
imageOver = imgOver;
|
||
if (imageOver) imageOver->SetParent(this);
|
||
imageHold = NULL;
|
||
imageClick = NULL;
|
||
icon = NULL;
|
||
iconOver = NULL;
|
||
iconHold = NULL;
|
||
iconClick = NULL;
|
||
toolTip = NULL;
|
||
alignmentHor = hor;
|
||
alignmentVert = vert;
|
||
xoffset = x;
|
||
yoffset = y;
|
||
trigger[0] = trig;
|
||
|
||
for (int i = 0; i < 3; i++)
|
||
{
|
||
label[i] = NULL;
|
||
labelOver[i] = NULL;
|
||
labelHold[i] = NULL;
|
||
labelClick[i] = NULL;
|
||
}
|
||
|
||
soundOver = sndOver;
|
||
soundHold = NULL;
|
||
soundClick = sndClick;
|
||
selectable = true;
|
||
holdable = false;
|
||
clickable = true;
|
||
|
||
if (grow == 1)
|
||
{
|
||
effectsOver |= EFFECT_SCALE;
|
||
effectAmountOver = 4;
|
||
effectTargetOver = 110;
|
||
}
|
||
time1 = time2 = 0;
|
||
}
|
||
|
||
GuiButton::GuiButton(GuiImage* img, GuiImage* imgOver, int hor, int vert, int x, int y, GuiTrigger* trig,
|
||
GuiSound* sndOver, GuiSound* sndClick, u8 grow, GuiTooltip* tt, int ttx, int tty, int h_align, int v_align)
|
||
{
|
||
width = img ? img->GetWidth() : 0;
|
||
height = img ? img->GetHeight() : 0;
|
||
image = img;
|
||
if(image) image->SetParent(this);
|
||
imageOver = imgOver;
|
||
if (imageOver) imageOver->SetParent(this);
|
||
imageHold = NULL;
|
||
imageClick = NULL;
|
||
icon = NULL;
|
||
iconOver = NULL;
|
||
iconHold = NULL;
|
||
iconClick = NULL;
|
||
toolTip = NULL;
|
||
alignmentHor = hor;
|
||
alignmentVert = vert;
|
||
xoffset = x;
|
||
yoffset = y;
|
||
trigger[0] = trig;
|
||
|
||
for (int i = 0; i < 3; i++)
|
||
{
|
||
label[i] = NULL;
|
||
labelOver[i] = NULL;
|
||
labelHold[i] = NULL;
|
||
labelClick[i] = NULL;
|
||
}
|
||
|
||
soundOver = sndOver;
|
||
soundHold = NULL;
|
||
soundClick = sndClick;
|
||
selectable = true;
|
||
holdable = false;
|
||
clickable = true;
|
||
|
||
if (grow == 1)
|
||
{
|
||
effectsOver |= EFFECT_SCALE;
|
||
effectAmountOver = 4;
|
||
effectTargetOver = 110;
|
||
}
|
||
|
||
toolTip = tt;
|
||
if(toolTip)
|
||
{
|
||
toolTip->SetParent(this);
|
||
toolTip->SetAlignment(h_align, v_align);
|
||
toolTip->SetPosition(ttx, tty);
|
||
}
|
||
|
||
time1 = time2 = 0;
|
||
}
|
||
|
||
/**
|
||
* Destructor for the GuiButton class.
|
||
*/
|
||
GuiButton::~GuiButton()
|
||
{
|
||
}
|
||
|
||
void GuiButton::SetImage(GuiImage* img)
|
||
{
|
||
LOCK( this );
|
||
image = img;
|
||
if (img) img->SetParent(this);
|
||
}
|
||
void GuiButton::SetImageOver(GuiImage* img)
|
||
{
|
||
LOCK( this );
|
||
imageOver = img;
|
||
if (img) img->SetParent(this);
|
||
}
|
||
void GuiButton::SetImageHold(GuiImage* img)
|
||
{
|
||
LOCK( this );
|
||
imageHold = img;
|
||
if (img) img->SetParent(this);
|
||
}
|
||
void GuiButton::SetImageClick(GuiImage* img)
|
||
{
|
||
LOCK( this );
|
||
imageClick = img;
|
||
if (img) img->SetParent(this);
|
||
}
|
||
void GuiButton::SetIcon(GuiImage* img)
|
||
{
|
||
LOCK( this );
|
||
icon = img;
|
||
if (img) img->SetParent(this);
|
||
}
|
||
void GuiButton::SetIconOver(GuiImage* img)
|
||
{
|
||
LOCK( this );
|
||
iconOver = img;
|
||
if (img) img->SetParent(this);
|
||
}
|
||
void GuiButton::SetIconHold(GuiImage* img)
|
||
{
|
||
LOCK( this );
|
||
iconHold = img;
|
||
if (img) img->SetParent(this);
|
||
}
|
||
void GuiButton::SetIconClick(GuiImage* img)
|
||
{
|
||
LOCK( this );
|
||
iconClick = img;
|
||
if (img) img->SetParent(this);
|
||
}
|
||
void GuiButton::SetLabel(GuiText* txt, int n)
|
||
{
|
||
LOCK( this );
|
||
label[n] = txt;
|
||
if (txt) txt->SetParent(this);
|
||
}
|
||
void GuiButton::SetLabelOver(GuiText* txt, int n)
|
||
{
|
||
LOCK( this );
|
||
labelOver[n] = txt;
|
||
if (txt) txt->SetParent(this);
|
||
}
|
||
void GuiButton::SetLabelHold(GuiText* txt, int n)
|
||
{
|
||
LOCK( this );
|
||
labelHold[n] = txt;
|
||
if (txt) txt->SetParent(this);
|
||
}
|
||
void GuiButton::SetLabelClick(GuiText* txt, int n)
|
||
{
|
||
LOCK( this );
|
||
labelClick[n] = txt;
|
||
if (txt) txt->SetParent(this);
|
||
}
|
||
void GuiButton::SetSoundOver(GuiSound * snd)
|
||
{
|
||
LOCK( this );
|
||
soundOver = snd;
|
||
}
|
||
void GuiButton::SetSoundHold(GuiSound * snd)
|
||
{
|
||
LOCK( this );
|
||
soundHold = snd;
|
||
}
|
||
void GuiButton::SetSoundClick(GuiSound * snd)
|
||
{
|
||
LOCK( this );
|
||
soundClick = snd;
|
||
}
|
||
|
||
void GuiButton::SetToolTip(GuiTooltip* tt, int x, int y, int h_align, int v_align)
|
||
{
|
||
LOCK( this );
|
||
if (tt)
|
||
{
|
||
toolTip = tt;
|
||
toolTip->SetParent(this);
|
||
toolTip->SetAlignment(h_align, v_align);
|
||
toolTip->SetPosition(x, y);
|
||
|
||
}
|
||
}
|
||
|
||
void GuiButton::RemoveToolTip()
|
||
{
|
||
LOCK( this );
|
||
toolTip = NULL;
|
||
}
|
||
|
||
void GuiButton::RemoveSoundOver()
|
||
{
|
||
LOCK( this );
|
||
soundOver = NULL;
|
||
}
|
||
void GuiButton::RemoveSoundClick()
|
||
{
|
||
LOCK( this );
|
||
soundClick = NULL;
|
||
}
|
||
void GuiButton::SetSkew(int XX1, int YY1, int XX2, int YY2, int XX3, int YY3, int XX4, int YY4)
|
||
{
|
||
if (image)
|
||
{
|
||
image->xx1 = XX1;
|
||
image->yy1 = YY1;
|
||
image->xx2 = XX2;
|
||
image->yy2 = YY2;
|
||
image->xx3 = XX3;
|
||
image->yy3 = YY3;
|
||
image->xx4 = XX4;
|
||
image->yy4 = YY4;
|
||
}
|
||
}
|
||
|
||
void GuiButton::SetSkew(int *skew)
|
||
{
|
||
if (image) image->SetSkew(skew);
|
||
}
|
||
|
||
/**
|
||
* Draw the button on screen
|
||
*/
|
||
void GuiButton::Draw()
|
||
{
|
||
LOCK( this );
|
||
if (!this->IsVisible()) return;
|
||
|
||
// draw image
|
||
if ((state == STATE_SELECTED || state == STATE_HELD) && imageOver)
|
||
imageOver->Draw();
|
||
else if (image) image->Draw();
|
||
// draw icon
|
||
if ((state == STATE_SELECTED || state == STATE_HELD) && iconOver)
|
||
iconOver->Draw();
|
||
else if (icon) icon->Draw();
|
||
// draw text
|
||
for (int i = 0; i < 3; i++)
|
||
{
|
||
if ((state == STATE_SELECTED || state == STATE_HELD) && labelOver[i])
|
||
labelOver[i]->Draw();
|
||
else if (label[i]) label[i]->Draw();
|
||
}
|
||
|
||
this->UpdateEffects();
|
||
}
|
||
void GuiButton::DrawTooltip()
|
||
{
|
||
LOCK( this );
|
||
if (this->IsVisible() && state == STATE_SELECTED && toolTip)
|
||
{
|
||
if (time2 == 0)
|
||
{
|
||
time(&time1);
|
||
time2 = time1;
|
||
}
|
||
if (time1 != 0) // timer l<>uft
|
||
time(&time1);
|
||
|
||
if (time1 == 0 || difftime(time1, time2) >= 2)
|
||
{
|
||
if (time1 != 0) // timer gerade abgelaufen
|
||
toolTip->SetEffect(EFFECT_FADE, 20);
|
||
time1 = 0;
|
||
toolTip->Draw();
|
||
return;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (time2 != 0 && time1 == 0) // timer abgelaufen, gerade DESELECT
|
||
if (toolTip) toolTip->SetEffect(EFFECT_FADE, -20);
|
||
time2 = 0;
|
||
}
|
||
if (toolTip && toolTip->GetEffect()) toolTip->Draw();
|
||
}
|
||
void GuiButton::ScrollIsOn(int f)
|
||
{
|
||
scrollison = f;
|
||
}
|
||
|
||
void GuiButton::Update(GuiTrigger * t)
|
||
{
|
||
LOCK( this );
|
||
if (!this->IsVisible() || state == STATE_CLICKED || state == STATE_DISABLED || !t)
|
||
return;
|
||
else if (parentElement && parentElement->GetState() == STATE_DISABLED) return;
|
||
|
||
#ifdef HW_RVL
|
||
// cursor
|
||
if ( t->wpad.ir.valid )
|
||
{
|
||
if ( this->IsInside( t->wpad.ir.x, t->wpad.ir.y ) )
|
||
{
|
||
if ( state == STATE_DEFAULT ) // we weren't on the button before!
|
||
|
||
{
|
||
if ( scrollison == 0 )
|
||
{
|
||
this->SetState( STATE_SELECTED, t->chan );
|
||
}
|
||
|
||
if ( this->Rumble() && scrollison == 0 )
|
||
rumbleRequest[t->chan] = 1;
|
||
|
||
if ( soundOver && scrollison == 0 )
|
||
soundOver->Play();
|
||
|
||
if ( effectsOver && !effects && scrollison == 0 )
|
||
{
|
||
// initiate effects
|
||
effects = effectsOver;
|
||
effectAmount = effectAmountOver;
|
||
effectTarget = effectTargetOver;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if ( state == STATE_SELECTED && ( stateChan == t->chan || stateChan == -1 ) )
|
||
this->ResetState();
|
||
|
||
if ( effectTarget == effectTargetOver && effectAmount == effectAmountOver )
|
||
{
|
||
// initiate effects (in reverse)
|
||
effects = effectsOver;
|
||
effectAmount = -effectAmountOver;
|
||
effectTarget = 100;
|
||
}
|
||
}
|
||
}
|
||
#else
|
||
|
||
if (state == STATE_SELECTED && (stateChan == t->chan || stateChan == -1)) this->ResetState();
|
||
|
||
if (effectTarget == effectTargetOver && effectAmount == effectAmountOver)
|
||
{
|
||
// initiate effects (in reverse)
|
||
effects = effectsOver;
|
||
effectAmount = -effectAmountOver;
|
||
effectTarget = 100;
|
||
}
|
||
|
||
#endif
|
||
|
||
// button triggers
|
||
if (this->IsClickable() && scrollison == 0)
|
||
{
|
||
s32 wm_btns, wm_btns_trig, cc_btns, cc_btns_trig;
|
||
for (int i = 0; i < 6; i++)
|
||
{
|
||
if (trigger[i] && (trigger[i]->chan == -1 || trigger[i]->chan == t->chan))
|
||
{
|
||
// higher 16 bits only (wiimote)
|
||
wm_btns = t->wpad.btns_d << 16;
|
||
wm_btns_trig = trigger[i]->wpad.btns_d << 16;
|
||
|
||
// lower 16 bits only (classic controller)
|
||
cc_btns = t->wpad.btns_d >> 16;
|
||
cc_btns_trig = trigger[i]->wpad.btns_d >> 16;
|
||
|
||
if (((t->wpad.btns_d > 0 && wm_btns == wm_btns_trig) || (cc_btns == cc_btns_trig && t->wpad.exp.type
|
||
== EXP_CLASSIC)) || (t->pad.btns_d == trigger[i]->pad.btns_d && t->pad.btns_d > 0))
|
||
{
|
||
if (t->chan == stateChan || stateChan == -1)
|
||
{
|
||
if (state == STATE_SELECTED)
|
||
{
|
||
this->SetState(STATE_CLICKED, t->chan);
|
||
|
||
if (soundClick) soundClick->Play();
|
||
}
|
||
else if (trigger[i]->type == TRIGGER_BUTTON_ONLY)
|
||
{
|
||
this->SetState(STATE_CLICKED, t->chan);
|
||
if (soundClick) soundClick->Play();
|
||
}
|
||
else if (trigger[i]->type == TRIGGER_BUTTON_ONLY_IN_FOCUS && parentElement->IsFocused())
|
||
{
|
||
this->SetState(STATE_CLICKED, t->chan);
|
||
if (soundClick) soundClick->Play();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
if (this->IsHoldable())
|
||
{
|
||
bool held = false;
|
||
s32 wm_btns, wm_btns_h, wm_btns_trig, cc_btns, cc_btns_h, cc_btns_trig;
|
||
|
||
for (int i = 0; i < 6; i++)
|
||
{
|
||
if (trigger[i] && (trigger[i]->chan == -1 || trigger[i]->chan == t->chan))
|
||
{
|
||
// higher 16 bits only (wiimote)
|
||
wm_btns = t->wpad.btns_d << 16;
|
||
wm_btns_h = t->wpad.btns_h << 16;
|
||
wm_btns_trig = trigger[i]->wpad.btns_h << 16;
|
||
|
||
// lower 16 bits only (classic controller)
|
||
cc_btns = t->wpad.btns_d >> 16;
|
||
cc_btns_h = t->wpad.btns_h >> 16;
|
||
cc_btns_trig = trigger[i]->wpad.btns_h >> 16;
|
||
|
||
if (((t->wpad.btns_d > 0 && wm_btns == wm_btns_trig) || (cc_btns == cc_btns_trig && t->wpad.exp.type
|
||
== EXP_CLASSIC)) || (t->pad.btns_d == trigger[i]->pad.btns_h && t->pad.btns_d > 0))
|
||
{
|
||
if (trigger[i]->type == TRIGGER_HELD && state == STATE_SELECTED && (t->chan == stateChan
|
||
|| stateChan == -1)) this->SetState(STATE_CLICKED, t->chan);
|
||
}
|
||
|
||
if (((t->wpad.btns_h > 0 && wm_btns_h == wm_btns_trig) || (cc_btns_h == cc_btns_trig
|
||
&& t->wpad.exp.type == EXP_CLASSIC)) || (t->pad.btns_h == trigger[i]->pad.btns_h
|
||
&& t->pad.btns_h > 0))
|
||
{
|
||
if (trigger[i]->type == TRIGGER_HELD) held = true;
|
||
}
|
||
|
||
if (!held && state == STATE_HELD && stateChan == t->chan)
|
||
{
|
||
this->ResetState();
|
||
}
|
||
else if (held && state == STATE_CLICKED && stateChan == t->chan)
|
||
{
|
||
this->SetState(STATE_HELD, t->chan);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
if (updateCB) updateCB(this);
|
||
}
|
||
|