mirror of
https://github.com/wiidev/usbloadergx.git
synced 2024-12-23 10:21:55 +01:00
9e79c9d99b
* code cleanup
841 lines
19 KiB
C++
841 lines
19 KiB
C++
/****************************************************************************
|
||
* libwiigui
|
||
*
|
||
* Tantric 2009
|
||
*
|
||
* gui_element.cpp
|
||
*
|
||
* GUI class definitions
|
||
***************************************************************************/
|
||
|
||
#include "gui.h"
|
||
|
||
/**
|
||
* Constructor for the Object class.
|
||
*/
|
||
//mutex_t GuiElement::mutex = LWP_MUTEX_NULL;
|
||
mutex_t GuiElement::_lock_mutex = LWP_MUTEX_NULL;
|
||
GuiElement::GuiElement()
|
||
{
|
||
xoffset = 0;
|
||
yoffset = 0;
|
||
zoffset = 0;
|
||
xmin = 0;
|
||
xmax = 0;
|
||
ymin = 0;
|
||
ymax = 0;
|
||
width = 0;
|
||
height = 0;
|
||
alpha = 255;
|
||
scale = 1;
|
||
state = STATE_DEFAULT;
|
||
stateChan = -1;
|
||
trigger[0] = NULL;
|
||
trigger[1] = NULL;
|
||
trigger[2] = NULL;
|
||
trigger[3] = NULL;
|
||
trigger[4] = NULL;
|
||
trigger[5] = NULL;
|
||
parentElement = NULL;
|
||
rumble = true;
|
||
selectable = false;
|
||
clickable = false;
|
||
holdable = false;
|
||
visible = true;
|
||
focus = -1; // cannot be focused
|
||
updateCB = NULL;
|
||
yoffsetDyn = 0;
|
||
xoffsetDyn = 0;
|
||
yoffsetDynFloat = 0;
|
||
alphaDyn = -1;
|
||
scaleDyn = 1;
|
||
effects = 0;
|
||
effectAmount = 0;
|
||
effectTarget = 0;
|
||
effectsOver = 0;
|
||
effectAmountOver = 0;
|
||
effectTargetOver = 0;
|
||
frequency = 0.0f;
|
||
changervar = 0;
|
||
degree = -90.0f;
|
||
circleamount = 360.0f;
|
||
Radius = 150;
|
||
angleDyn = 0.0f;
|
||
anglespeed = 0.0f;
|
||
|
||
// default alignment - align to top left
|
||
alignmentVert = ALIGN_TOP;
|
||
alignmentHor = ALIGN_LEFT;
|
||
// if(mutex == LWP_MUTEX_NULL) LWP_MutexInit(&mutex, true);
|
||
if ( _lock_mutex == LWP_MUTEX_NULL ) LWP_MutexInit( &_lock_mutex, true );
|
||
_lock_thread = LWP_THREAD_NULL;
|
||
_lock_count = 0;
|
||
_lock_queue = LWP_TQUEUE_NULL;
|
||
|
||
}
|
||
|
||
/**
|
||
* Destructor for the GuiElement class.
|
||
*/
|
||
GuiElement::~GuiElement()
|
||
{
|
||
// LWP_MutexDestroy(mutex);
|
||
}
|
||
|
||
void GuiElement::SetParent( GuiElement * e )
|
||
{
|
||
LOCK( this );
|
||
parentElement = e;
|
||
}
|
||
|
||
GuiElement * GuiElement::GetParent()
|
||
{
|
||
return parentElement;
|
||
}
|
||
/**
|
||
* Get the left position of the GuiElement.
|
||
* @see SetLeft()
|
||
* @return Left position in pixel.
|
||
*/
|
||
int GuiElement::GetLeft()
|
||
{
|
||
int x = 0;
|
||
int pWidth = 0;
|
||
int pLeft = 0;
|
||
|
||
if ( parentElement )
|
||
{
|
||
pWidth = parentElement->GetWidth();
|
||
pLeft = parentElement->GetLeft();
|
||
}
|
||
|
||
if ( effects & ( EFFECT_SLIDE_IN | EFFECT_SLIDE_OUT | EFFECT_GOROUND | EFFECT_ROCK_VERTICLE ) )
|
||
pLeft += xoffsetDyn;
|
||
|
||
switch ( alignmentHor )
|
||
{
|
||
case ALIGN_LEFT:
|
||
x = pLeft;
|
||
break;
|
||
case ALIGN_CENTRE:
|
||
x = pLeft + ( pWidth / 2 ) - ( width / 2 );
|
||
break;
|
||
case ALIGN_RIGHT:
|
||
x = pLeft + pWidth - width;
|
||
break;
|
||
}
|
||
return x + xoffset;
|
||
}
|
||
|
||
/**
|
||
* Get the top position of the GuiElement.
|
||
* @see SetTop()
|
||
* @return Top position in pixel.
|
||
*/
|
||
int GuiElement::GetTop()
|
||
{
|
||
int y = 0;
|
||
int pHeight = 0;
|
||
int pTop = 0;
|
||
|
||
if ( parentElement )
|
||
{
|
||
pHeight = parentElement->GetHeight();
|
||
pTop = parentElement->GetTop();
|
||
}
|
||
|
||
if ( effects & ( EFFECT_SLIDE_IN | EFFECT_SLIDE_OUT | EFFECT_GOROUND | EFFECT_ROCK_VERTICLE ) )
|
||
pTop += yoffsetDyn;
|
||
|
||
|
||
switch ( alignmentVert )
|
||
{
|
||
case ALIGN_TOP:
|
||
y = pTop;
|
||
break;
|
||
case ALIGN_MIDDLE:
|
||
y = pTop + ( pHeight / 2 ) - ( height / 2 );
|
||
break;
|
||
case ALIGN_BOTTOM:
|
||
y = pTop + pHeight - height;
|
||
break;
|
||
}
|
||
return y + yoffset;
|
||
}
|
||
|
||
void GuiElement::SetMinX( int x )
|
||
{
|
||
LOCK( this );
|
||
xmin = x;
|
||
}
|
||
|
||
int GuiElement::GetMinX()
|
||
{
|
||
return xmin;
|
||
}
|
||
|
||
void GuiElement::SetMaxX( int x )
|
||
{
|
||
LOCK( this );
|
||
xmax = x;
|
||
}
|
||
|
||
int GuiElement::GetMaxX()
|
||
{
|
||
return xmax;
|
||
}
|
||
|
||
void GuiElement::SetMinY( int y )
|
||
{
|
||
LOCK( this );
|
||
ymin = y;
|
||
}
|
||
|
||
int GuiElement::GetMinY()
|
||
{
|
||
return ymin;
|
||
}
|
||
|
||
void GuiElement::SetMaxY( int y )
|
||
{
|
||
LOCK( this );
|
||
ymax = y;
|
||
}
|
||
|
||
int GuiElement::GetMaxY()
|
||
{
|
||
return ymax;
|
||
}
|
||
|
||
/**
|
||
* Get the width of the GuiElement.
|
||
* @see SetWidth()
|
||
* @return Width of the GuiElement.
|
||
*/
|
||
int GuiElement::GetWidth()
|
||
{
|
||
return width;
|
||
}
|
||
|
||
/**
|
||
* Get the height of the GuiElement.
|
||
* @see SetHeight()
|
||
* @return Height of the GuiElement.
|
||
*/
|
||
int GuiElement::GetHeight()
|
||
{
|
||
return height;
|
||
}
|
||
|
||
/**
|
||
* Set the width and height of the GuiElement.
|
||
* @param[in] Width Width in pixel.
|
||
* @param[in] Height Height in pixel.
|
||
* @see SetWidth()
|
||
* @see SetHeight()
|
||
*/
|
||
void GuiElement::SetSize( int w, int h )
|
||
{
|
||
LOCK( this );
|
||
|
||
width = w;
|
||
height = h;
|
||
}
|
||
|
||
/**
|
||
* Get visible.
|
||
* @see SetVisible()
|
||
* @return true if visible, false otherwise.
|
||
*/
|
||
bool GuiElement::IsVisible()
|
||
{
|
||
return visible;
|
||
}
|
||
|
||
/**
|
||
* Set visible.
|
||
* @param[in] Visible Set to true to show GuiElement.
|
||
* @see IsVisible()
|
||
*/
|
||
void GuiElement::SetVisible( bool v )
|
||
{
|
||
LOCK( this );
|
||
visible = v;
|
||
}
|
||
|
||
void GuiElement::SetAlpha( int a )
|
||
{
|
||
LOCK( this );
|
||
alpha = a;
|
||
}
|
||
|
||
int GuiElement::GetAlpha()
|
||
{
|
||
int a;
|
||
|
||
if ( alphaDyn >= 0 )
|
||
a = alphaDyn;
|
||
else
|
||
a = alpha;
|
||
|
||
if ( parentElement )
|
||
a *= parentElement->GetAlpha() / 255.0;
|
||
|
||
return a;
|
||
}
|
||
|
||
float GuiElement::GetAngleDyn()
|
||
{
|
||
float a = 0.0;
|
||
|
||
if ( angleDyn )
|
||
a = angleDyn;
|
||
|
||
if ( parentElement && !angleDyn )
|
||
a = parentElement->GetAngleDyn();
|
||
|
||
return a;
|
||
}
|
||
|
||
void GuiElement::SetScale( float s )
|
||
{
|
||
LOCK( this );
|
||
scale = s;
|
||
}
|
||
|
||
float GuiElement::GetScale()
|
||
{
|
||
float s = scale * scaleDyn;
|
||
|
||
if ( parentElement )
|
||
s *= parentElement->GetScale();
|
||
|
||
return s;
|
||
}
|
||
|
||
int GuiElement::GetState()
|
||
{
|
||
return state;
|
||
}
|
||
|
||
int GuiElement::GetStateChan()
|
||
{
|
||
return stateChan;
|
||
}
|
||
|
||
void GuiElement::SetState( int s, int c )
|
||
{
|
||
LOCK( this );
|
||
state = s;
|
||
stateChan = c;
|
||
}
|
||
|
||
void GuiElement::ResetState()
|
||
{
|
||
LOCK( this );
|
||
if ( state != STATE_DISABLED )
|
||
{
|
||
state = STATE_DEFAULT;
|
||
stateChan = -1;
|
||
}
|
||
}
|
||
|
||
void GuiElement::SetClickable( bool c )
|
||
{
|
||
LOCK( this );
|
||
clickable = c;
|
||
}
|
||
|
||
void GuiElement::SetSelectable( bool s )
|
||
{
|
||
LOCK( this );
|
||
selectable = s;
|
||
}
|
||
|
||
void GuiElement::SetHoldable( bool d )
|
||
{
|
||
LOCK( this );
|
||
holdable = d;
|
||
}
|
||
|
||
bool GuiElement::IsSelectable()
|
||
{
|
||
if ( state == STATE_DISABLED || state == STATE_CLICKED )
|
||
return false;
|
||
else
|
||
return selectable;
|
||
}
|
||
|
||
bool GuiElement::IsClickable()
|
||
{
|
||
if ( state == STATE_DISABLED ||
|
||
state == STATE_CLICKED ||
|
||
state == STATE_HELD )
|
||
return false;
|
||
else
|
||
return clickable;
|
||
}
|
||
|
||
bool GuiElement::IsHoldable()
|
||
{
|
||
if ( state == STATE_DISABLED )
|
||
return false;
|
||
else
|
||
return holdable;
|
||
}
|
||
|
||
void GuiElement::SetFocus( int f )
|
||
{
|
||
LOCK( this );
|
||
focus = f;
|
||
}
|
||
|
||
int GuiElement::IsFocused()
|
||
{
|
||
return focus;
|
||
}
|
||
|
||
void GuiElement::SetTrigger( GuiTrigger * t )
|
||
{
|
||
LOCK( this );
|
||
if ( !trigger[0] )
|
||
trigger[0] = t;
|
||
else if ( !trigger[1] )
|
||
trigger[1] = t;
|
||
else if ( !trigger[2] )
|
||
trigger[2] = t;
|
||
else if ( !trigger[3] )
|
||
trigger[3] = t;
|
||
else if ( !trigger[4] )
|
||
trigger[4] = t;
|
||
else if ( !trigger[5] )
|
||
trigger[5] = t;
|
||
else // both were assigned, so we'll just overwrite the first one
|
||
trigger[0] = t;
|
||
}
|
||
|
||
void GuiElement::SetTrigger( u8 i, GuiTrigger * t )
|
||
{
|
||
LOCK( this );
|
||
trigger[i] = t;
|
||
}
|
||
|
||
void GuiElement::RemoveTrigger( u8 i )
|
||
{
|
||
LOCK( this );
|
||
trigger[i] = NULL;
|
||
}
|
||
|
||
bool GuiElement::Rumble()
|
||
{
|
||
return rumble;
|
||
}
|
||
|
||
void GuiElement::SetRumble( bool r )
|
||
{
|
||
LOCK( this );
|
||
rumble = r;
|
||
}
|
||
|
||
int GuiElement::GetEffect()
|
||
{
|
||
LOCK( this );
|
||
return effects;
|
||
}
|
||
|
||
int GuiElement::GetEffectOnOver()
|
||
{
|
||
LOCK( this );
|
||
return effectsOver;
|
||
}
|
||
|
||
float GuiElement::GetFrequency()
|
||
{
|
||
LOCK( this );
|
||
return frequency;
|
||
}
|
||
|
||
void GuiElement::SetEffect( int eff, int speed, f32 circles, int r, f32 startdegree, f32 anglespeedset, int center_x, int center_y )
|
||
{
|
||
|
||
if ( eff & EFFECT_GOROUND )
|
||
{
|
||
xoffsetDyn = 0; //!position of circle in x
|
||
yoffsetDyn = 0; //!position of circle in y
|
||
Radius = r; //!radius of the circle
|
||
degree = startdegree; //!for example -90 (<28>) to start at top of circle
|
||
circleamount = circles; //!circleamoutn in degrees for example 360 for 1 circle
|
||
angleDyn = 0.0f; //!this is used by the code to calc the angle
|
||
anglespeed = anglespeedset; //!This is anglespeed depending on circle speed 1 is same speed and 0.5 half speed
|
||
temp_xoffset = center_x; //!position of center in x
|
||
temp_yoffset = center_y; //!position of center in y
|
||
}
|
||
effects |= eff;
|
||
effectAmount = speed; //!Circlespeed
|
||
}
|
||
|
||
void GuiElement::SetEffect( int eff, int amount, int target )
|
||
{
|
||
LOCK( this );
|
||
if ( eff & EFFECT_SLIDE_IN )
|
||
{
|
||
// these calculations overcompensate a little
|
||
if ( eff & EFFECT_SLIDE_TOP )
|
||
yoffsetDyn = -screenheight;
|
||
else if ( eff & EFFECT_SLIDE_LEFT )
|
||
xoffsetDyn = -screenwidth;
|
||
else if ( eff & EFFECT_SLIDE_BOTTOM )
|
||
yoffsetDyn = screenheight;
|
||
else if ( eff & EFFECT_SLIDE_RIGHT )
|
||
xoffsetDyn = screenwidth;
|
||
}
|
||
|
||
if ( eff & EFFECT_FADE && amount > 0 )
|
||
{
|
||
alphaDyn = 0;
|
||
}
|
||
else if ( eff & EFFECT_FADE && amount < 0 )
|
||
{
|
||
alphaDyn = alpha;
|
||
|
||
}
|
||
else if ( eff & EFFECT_ROCK_VERTICLE )
|
||
{
|
||
changervar = 0;
|
||
yoffsetDyn = 0;
|
||
yoffsetDynFloat = 0.0;
|
||
}
|
||
|
||
effects |= eff;
|
||
effectAmount = amount;
|
||
effectTarget = target;
|
||
}
|
||
|
||
void GuiElement::SetEffectOnOver( int eff, int amount, int target )
|
||
{
|
||
LOCK( this );
|
||
effectsOver |= eff;
|
||
effectAmountOver = amount;
|
||
effectTargetOver = target;
|
||
}
|
||
|
||
void GuiElement::SetEffectGrow()
|
||
{
|
||
SetEffectOnOver( EFFECT_SCALE, 4, 110 );
|
||
}
|
||
|
||
void GuiElement::StopEffect()
|
||
{
|
||
xoffsetDyn = 0;
|
||
yoffsetDyn = 0;
|
||
effects = 0;
|
||
effectsOver = 0;
|
||
effectAmount = 0;
|
||
effectAmountOver = 0;
|
||
effectTarget = 0;
|
||
effectTargetOver = 0;
|
||
scaleDyn = 1;
|
||
frequency = 0.0f;
|
||
changervar = 0;
|
||
//angleDyn = 0.0f;
|
||
anglespeed = 0.0f;
|
||
}
|
||
|
||
void GuiElement::UpdateEffects()
|
||
{
|
||
LOCK( this );
|
||
|
||
if ( effects & ( EFFECT_SLIDE_IN | EFFECT_SLIDE_OUT | EFFECT_GOROUND ) )
|
||
{
|
||
if ( effects & EFFECT_SLIDE_IN )
|
||
{
|
||
if ( effects & EFFECT_SLIDE_LEFT )
|
||
{
|
||
xoffsetDyn += effectAmount;
|
||
|
||
if ( xoffsetDyn >= 0 )
|
||
{
|
||
xoffsetDyn = 0;
|
||
effects = 0;
|
||
}
|
||
}
|
||
else if ( effects & EFFECT_SLIDE_RIGHT )
|
||
{
|
||
xoffsetDyn -= effectAmount;
|
||
|
||
if ( xoffsetDyn <= 0 )
|
||
{
|
||
xoffsetDyn = 0;
|
||
effects = 0;
|
||
}
|
||
}
|
||
else if ( effects & EFFECT_SLIDE_TOP )
|
||
{
|
||
yoffsetDyn += effectAmount;
|
||
|
||
if ( yoffsetDyn >= 0 )
|
||
{
|
||
yoffsetDyn = 0;
|
||
effects = 0;
|
||
}
|
||
}
|
||
else if ( effects & EFFECT_SLIDE_BOTTOM )
|
||
{
|
||
yoffsetDyn -= effectAmount;
|
||
|
||
if ( yoffsetDyn <= 0 )
|
||
{
|
||
yoffsetDyn = 0;
|
||
effects = 0;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if ( effects & EFFECT_SLIDE_LEFT )
|
||
{
|
||
xoffsetDyn -= effectAmount;
|
||
|
||
if ( xoffsetDyn <= -screenwidth )
|
||
effects = 0; // shut off effect
|
||
}
|
||
else if ( effects & EFFECT_SLIDE_RIGHT )
|
||
{
|
||
xoffsetDyn += effectAmount;
|
||
|
||
if ( xoffsetDyn >= screenwidth )
|
||
effects = 0; // shut off effect
|
||
}
|
||
else if ( effects & EFFECT_SLIDE_TOP )
|
||
{
|
||
yoffsetDyn -= effectAmount;
|
||
|
||
if ( yoffsetDyn <= -screenheight )
|
||
effects = 0; // shut off effect
|
||
}
|
||
else if ( effects & EFFECT_SLIDE_BOTTOM )
|
||
{
|
||
yoffsetDyn += effectAmount;
|
||
|
||
if ( yoffsetDyn >= screenheight )
|
||
effects = 0; // shut off effect
|
||
}
|
||
}
|
||
}
|
||
|
||
if ( effects & EFFECT_GOROUND )
|
||
{
|
||
//!< check out gui.h for info
|
||
xoffset = temp_xoffset;
|
||
yoffset = temp_yoffset;
|
||
if ( fabs( frequency ) < circleamount )
|
||
{
|
||
angleDyn = ( frequency + degree + 90.0f ) * anglespeed;
|
||
xoffsetDyn = ( int ) lround( ( ( f32 ) Radius ) * cos( ( frequency + degree ) * PI / 180.0f ) );
|
||
yoffsetDyn = ( int ) lround( ( ( f32 ) Radius ) * sin( ( frequency + degree ) * PI / 180.0f ) );
|
||
frequency += ( ( f32 ) effectAmount ) * 0.01f;
|
||
}
|
||
else
|
||
{
|
||
f32 temp_frequency = ( ( effectAmount < 0 ) ? -1.0f : 1.0f ) * circleamount;
|
||
angleDyn = ( temp_frequency + degree + 90.0f ) * anglespeed;
|
||
xoffsetDyn = ( int ) lround( ( ( f32 ) Radius ) * cos( ( temp_frequency + degree ) * PI / 180.0f ) );
|
||
yoffsetDyn = ( int ) lround( ( ( f32 ) Radius ) * sin( ( temp_frequency + degree ) * PI / 180.0f ) );
|
||
xoffset += xoffsetDyn;
|
||
yoffset += yoffsetDyn;
|
||
effects ^= EFFECT_GOROUND;
|
||
frequency = 0.0f;
|
||
}
|
||
}
|
||
|
||
if ( effects & EFFECT_ROCK_VERTICLE )
|
||
{
|
||
//move up to 10pixel above 0
|
||
if ( changervar == 0 && yoffsetDynFloat < 11.0 )
|
||
{
|
||
yoffsetDynFloat += ( effectAmount * 0.01 );
|
||
}
|
||
else if ( yoffsetDynFloat > 10.0 )
|
||
{
|
||
changervar = 1;
|
||
}
|
||
//move down till 10pixel under 0
|
||
if ( changervar == 1 && yoffsetDynFloat > -11.0 )
|
||
{
|
||
yoffsetDynFloat -= ( effectAmount * 0.01 );
|
||
}
|
||
else if ( yoffsetDynFloat < -10.0 )
|
||
{
|
||
changervar = 0;
|
||
}
|
||
yoffsetDyn = ( int )( yoffsetDynFloat );
|
||
}
|
||
|
||
if ( effects & EFFECT_FADE )
|
||
{
|
||
alphaDyn += effectAmount;
|
||
|
||
if ( effectAmount < 0 && alphaDyn <= 0 )
|
||
{
|
||
alphaDyn = 0;
|
||
effects = 0; // shut off effect
|
||
}
|
||
else if ( effectAmount > 0 && alphaDyn >= alpha )
|
||
{
|
||
alphaDyn = alpha;
|
||
effects = 0; // shut off effect
|
||
}
|
||
}
|
||
if ( effects & EFFECT_SCALE )
|
||
{
|
||
scaleDyn += effectAmount / 100.0;
|
||
|
||
if ( ( effectAmount < 0 && scaleDyn <= effectTarget / 100.0 )
|
||
|| ( effectAmount > 0 && scaleDyn >= effectTarget / 100.0 ) )
|
||
{
|
||
scaleDyn = effectTarget / 100.0;
|
||
effects = 0; // shut off effect
|
||
}
|
||
}
|
||
if ( effects & EFFECT_PULSE )
|
||
{
|
||
int percent = 10; //go down from target by this
|
||
|
||
if ( ( scaleDyn <= ( effectTarget*0.01 ) ) && ( !changervar ) )
|
||
{
|
||
scaleDyn += ( effectAmount * 0.001 );
|
||
}
|
||
else if ( scaleDyn > ( effectTarget*0.01 ) )
|
||
{
|
||
changervar = 1;
|
||
}
|
||
if ( ( scaleDyn >= ( ( effectTarget - percent )*0.01 ) ) && ( changervar ) )
|
||
{
|
||
scaleDyn -= ( effectAmount * 0.001 );
|
||
}
|
||
else if ( scaleDyn < ( ( effectTarget - percent )*0.01 ) )
|
||
{
|
||
changervar = 0;
|
||
}
|
||
}
|
||
}
|
||
|
||
void GuiElement::Update( GuiTrigger * t )
|
||
{
|
||
LOCK( this );
|
||
if ( updateCB )
|
||
updateCB( this );
|
||
}
|
||
|
||
void GuiElement::SetUpdateCallback( UpdateCallback u )
|
||
{
|
||
LOCK( this );
|
||
updateCB = u;
|
||
}
|
||
|
||
void GuiElement::SetPosition( int xoff, int yoff, int zoff )
|
||
{
|
||
LOCK( this );
|
||
xoffset = xoff;
|
||
yoffset = yoff;
|
||
zoffset = zoff;
|
||
}
|
||
|
||
void GuiElement::SetAlignment( int hor, int vert )
|
||
{
|
||
LOCK( this );
|
||
alignmentHor = hor;
|
||
alignmentVert = vert;
|
||
}
|
||
|
||
int GuiElement::GetSelected()
|
||
{
|
||
return -1;
|
||
}
|
||
|
||
/**
|
||
* Draw an element on screen.
|
||
*/
|
||
void GuiElement::Draw()
|
||
{
|
||
}
|
||
|
||
/**
|
||
* Draw Tooltips on screen.
|
||
*/
|
||
void GuiElement::DrawTooltip()
|
||
{
|
||
}
|
||
|
||
/**
|
||
* Check if a position is inside the GuiElement.
|
||
* @param[in] x X position in pixel.
|
||
* @param[in] y Y position in pixel.
|
||
*/
|
||
bool GuiElement::IsInside( int x, int y )
|
||
{
|
||
if ( x > this->GetLeft() && x < ( this->GetLeft() + width )
|
||
&& y > this->GetTop() && y < ( this->GetTop() + height ) )
|
||
return true;
|
||
return false;
|
||
}
|
||
void GuiElement::Lock()
|
||
{
|
||
// LWP_MutexLock(mutex);
|
||
for ( ;; ) // loop while element is locked by self
|
||
{
|
||
LWP_MutexLock( _lock_mutex );
|
||
|
||
if ( _lock_thread == LWP_THREAD_NULL ) // element is not locked
|
||
{
|
||
_lock_thread = LWP_GetSelf(); // mark as locked
|
||
_lock_count = 1; // set count of lock to 1
|
||
LWP_MutexUnlock( _lock_mutex );
|
||
return;
|
||
}
|
||
else if ( _lock_thread == LWP_GetSelf() ) // thread is locked by my self
|
||
{
|
||
_lock_count++; // inc count of locks;
|
||
LWP_MutexUnlock( _lock_mutex );
|
||
return;
|
||
}
|
||
else // otherwise the element is locked by an other thread
|
||
{
|
||
if ( _lock_queue == LWP_TQUEUE_NULL ) // no queue - meens it is the first access to the locked element
|
||
LWP_InitQueue( &_lock_queue ); // init queue
|
||
LWP_MutexUnlock( _lock_mutex );
|
||
LWP_ThreadSleep( _lock_queue ); // and sleep
|
||
// try lock again;
|
||
}
|
||
}
|
||
}
|
||
void GuiElement::Unlock()
|
||
{
|
||
// LWP_MutexUnlock(mutex);
|
||
LWP_MutexLock( _lock_mutex );
|
||
// only the thread was locked this element, can call unlock
|
||
if ( _lock_thread == LWP_GetSelf() ) // but we check it here <20> safe is safe
|
||
{
|
||
if ( --_lock_count == 0 ) // dec count of locks and check if it last lock;
|
||
{
|
||
_lock_thread = LWP_THREAD_NULL; // mark as unlocked
|
||
if ( _lock_queue != LWP_TQUEUE_NULL ) // has a queue
|
||
{
|
||
LWP_CloseQueue( _lock_queue ); // close the queue and wake all waited threads
|
||
_lock_queue = LWP_TQUEUE_NULL;
|
||
}
|
||
}
|
||
}
|
||
LWP_MutexUnlock( _lock_mutex );
|
||
}
|
||
|
||
|
||
SimpleLock::SimpleLock( GuiElement *e ) : element( e )
|
||
{
|
||
element->Lock();
|
||
}
|
||
SimpleLock::~SimpleLock()
|
||
{
|
||
element->Unlock();
|
||
}
|