usbloadergx/source/GUI/gui_button.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

538 lines
11 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);
}
void GuiButton::SetState(int s, int c)
{
GuiElement::SetState(s, c);
if(c < 0 || c > 3)
return;
if (s == STATE_CLICKED)
{
POINT p = {0, 0};
if (userInput[c].wpad.ir.valid)
{
p.x = userInput[c].wpad.ir.x;
p.y = userInput[c].wpad.ir.y;
}
Clicked(this, c, p);
}
}
/**
* 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();
}
}
}
}
}
}
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);
}
else if (held && state == STATE_HELD && Held.connected())
{
POINT p = {0, 0};
if (userInput[t->chan].wpad.ir.valid)
{
p.x = userInput[t->chan].wpad.ir.x;
p.y = userInput[t->chan].wpad.ir.y;
}
Held(this, t->chan, p);
}
}
}
}
if (updateCB) updateCB(this);
}