usbloadergx/source/libwiigui/gui_button.cpp
dimok321 e11901bc09 *Changed FreeTypeGX to use IA4 textures for font glyphs (saves a bit memory)
*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.
2011-02-21 19:41:48 +00:00

512 lines
13 KiB
C++
Raw Blame History

/****************************************************************************
* 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);
}