Subversion Repositories AndroidProjects

Rev

Blame | Last modification | View Log | RSS feed

#include "Widget.h"
#include "WidgetManager.h"
#include "Graphics.h"
#include "Font.h"
#include "Image.h"
#include "SexyAppBase.h"
#include "debug.h"

using namespace Sexy;

bool Widget::mWriteColoredString = true;

Widget::Widget()
{
        mWidgetManager = NULL; 
        mVisible = true;
        mDisabled = false;
        mIsDown = false;
        mIsOver = false;
        mDoFinger = false;     
        mMouseVisible = true;          
        mHasFocus = false;
        mHasTransparencies = false;    
        mWantsFocus = false;
        mTabPrev = NULL;
        mTabNext = NULL;
}

Widget::~Widget()
{      
        mColors.clear();
}

void Widget::WidgetRemovedHelper()
{
        if (mWidgetManager==NULL)
                return;

        // Call RemovedFromManager on all child widgets and disable them and stuff like that
        for (WidgetList::iterator aWidgetItr = mWidgets.begin(); aWidgetItr != mWidgets.end(); ++aWidgetItr)
        {
                Widget *aWidget = *aWidgetItr;
                aWidget->WidgetRemovedHelper();
        }      

        mWidgetManager->DisableWidget(this);

        PreModalInfoList::iterator anItr = mWidgetManager->mPreModalInfoList.begin();
        while (anItr != mWidgetManager->mPreModalInfoList.end())
        {
                PreModalInfo* aPreModalInfo = &(*anItr);
                if (aPreModalInfo->mPrevBaseModalWidget == this)
                        aPreModalInfo->mPrevBaseModalWidget = NULL;
                if (aPreModalInfo->mPrevFocusWidget == this)
                        aPreModalInfo->mPrevFocusWidget = NULL;
                ++anItr;
        }
       
        RemovedFromManager(mWidgetManager);
        MarkDirtyFull(this);

        mWidgetManager = NULL;
}

void Widget::OrderInManagerChanged()
{
}

bool Widget::IsPointVisible(int x, int y)
{
        return true;
}

void Widget::SetVisible(bool isVisible)
{
        if (mVisible == isVisible)
                return;
       
        mVisible = isVisible;
       
        if (mVisible)
                MarkDirty();
        else
                MarkDirtyFull();

        if (mWidgetManager != NULL)
                mWidgetManager->RehupMouse();
}

void Widget::Draw(Graphics* g) // Already translated
{
}

void Widget::DrawOverlay(Graphics* g)
{
}

void Widget::DrawOverlay(Graphics* g, int thePriority)
{
        DrawOverlay(g);
}

void Widget::SetColors(int theColors[][3], int theNumColors)
{
        mColors.clear();

        for (int i = 0; i < theNumColors; i++)
                SetColor(i, Color(theColors[i][0], theColors[i][1], theColors[i][2]));
        MarkDirty();
}

void Widget::SetColors(int theColors[][4], int theNumColors)
{      
        mColors.clear();

        for (int i = 0; i < theNumColors; i++)
                SetColor(i, Color(theColors[i][0], theColors[i][1], theColors[i][2], theColors[i][3]));        

        MarkDirty();
}

void Widget::SetColor(int theIdx, const Color& theColor)
{
        if (theIdx >= (int)mColors.size())
                mColors.resize(theIdx + 1);

        mColors[theIdx] = theColor;
        MarkDirty();
}

const Color& Widget::GetColor(int theIdx)
{
        static Color aColor;
        if (theIdx < (int) mColors.size())
                return mColors[theIdx];
        return aColor;
}

Color Widget::GetColor(int theIdx, const Color& theDefaultColor)
{
        if (theIdx < (int) mColors.size())
                return mColors[theIdx];
        return theDefaultColor;
}

void Widget::Resize(int theX, int theY, int theWidth, int theHeight)
{
        if ((mX == theX) && (mY == theY) && (mWidth == theWidth) && (mHeight == theHeight))
                return;

        // Mark everything dirty that is over or under the old position
        MarkDirtyFull();
       
        mX = theX;
        mY = theY;
        mWidth = theWidth;
        mHeight = theHeight;
               
        // Mark things dirty that are over the new position
        MarkDirty();

        if (mWidgetManager != NULL)
                mWidgetManager->RehupMouse();
}

void Widget::Resize(const Rect& theRect)
{
        Resize(theRect.mX, theRect.mY, theRect.mWidth, theRect.mHeight);
}

void Widget::Move(int theNewX, int theNewY)
{
        Resize(theNewX, theNewY, mWidth, mHeight);
}

bool Widget::WantsFocus()
{
        return mWantsFocus;
}

void Widget::SetDisabled(bool isDisabled)
{
        if (mDisabled == isDisabled)
                return;

        mDisabled = isDisabled;

        if ((isDisabled) && (mWidgetManager != NULL))
                mWidgetManager->DisableWidget(this);
               
        MarkDirty();
       
        // Incase a widget is enabled right under our cursor
        if ((!isDisabled) && (mWidgetManager != NULL) && (Contains(mWidgetManager->mLastMouseX, mWidgetManager->mLastMouseY)))
                mWidgetManager->MousePosition(mWidgetManager->mLastMouseX, mWidgetManager->mLastMouseY);
}

void Widget::GotFocus()
{
        mHasFocus = true;              
}

void Widget::LostFocus()
{
        mHasFocus = false;             
}

void Widget::Update()
{
        WidgetContainer::Update();
}

void Widget::UpdateF(float theFrac)
{
}

void Widget::KeyChar(SexyChar theChar)
{
}

void Widget::KeyDown(KeyCode theKey)
{
        if (theKey == KEYCODE_TAB)
        {
                if (mWidgetManager->mKeyDown[KEYCODE_SHIFT])
                {
                        if (mTabPrev != NULL)
                                mWidgetManager->SetFocus(mTabPrev);
                }
                else
                {
                        if (mTabNext != NULL)
                                mWidgetManager->SetFocus(mTabNext);
                }
        }
}

void Widget::KeyUp(KeyCode theKey)
{              
}

void Widget::ShowFinger(bool on)
{
        if (mWidgetManager == NULL)
                return;

        if (on)
                mWidgetManager->mApp->SetCursor(CURSOR_HAND);
        else
                mWidgetManager->mApp->SetCursor(CURSOR_POINTER);

        /*if (on)
                mWidgetManager->mApplet.setCursor(new Cursor(Cursor.HAND_CURSOR));
        else
                mWidgetManager->mApplet.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));*/

}

void Widget::MouseEnter()
{
       
}

void Widget::MouseLeave()
{
       
}

void Widget::MouseMove(int x, int y)
{
}

void Widget::MouseDown(int x, int y, int theClickCount)
{
        if (theClickCount == 3)
                MouseDown(x, y, 2, 1);
        else if (theClickCount >= 0)
                MouseDown(x, y, 0, theClickCount);
        else
                MouseDown(x, y, 1, -theClickCount);
}

void Widget::MouseDown(int x, int y, int theBtnNum, int theClickCount)
{
}

void Widget::MouseUp(int x, int y)
{
}

void Widget::MouseUp(int x, int y, int theLastDownButtonId)
{
        MouseUp(x, y);

        if (theLastDownButtonId == 3)
                MouseUp(x, y, 2, 1);
        else if (theLastDownButtonId >= 0)
                MouseUp(x, y, 0, theLastDownButtonId);
        else
                MouseUp(x, y, 1, -theLastDownButtonId);
}

void Widget::MouseUp(int x, int y, int theBtnNum, int theClickCount)
{
}

void Widget::MouseDrag(int x, int y)
{
}

void Widget::MouseWheel(int theDelta)
{
}

//////// Helper functions

Rect Widget::WriteCenteredLine(Graphics* g, int anOffset, const SexyString& theLine)
{
        Font* aFont = g->GetFont();
        int aWidth = aFont->StringWidth(theLine);
        int aX = (mWidth - aWidth) / 2;

        g->DrawString(theLine, aX, anOffset);

        return Rect(aX, anOffset - aFont->GetAscent(), aWidth, aFont->GetHeight());
}

Rect Widget::WriteCenteredLine(Graphics* g, int anOffset, const SexyString& theLine, Color theColor1, Color theColor2, const Point& theShadowOffset)
{
        Font* aFont = g->GetFont();
        int aWidth = aFont->StringWidth(theLine);
        int aX = (mWidth - aWidth) / 2;
       
        g->SetColor(theColor2);
        g->DrawString(theLine, (mWidth - aWidth)/2 + theShadowOffset.mX, anOffset + theShadowOffset.mY);
       
        g->SetColor(theColor1);
        g->DrawString(theLine, (mWidth - aWidth)/2, anOffset);

        // account for shadow in position and size
        // TODO: this may not be necessary.
        return Rect(
                aX + min(0,theShadowOffset.mX),
                anOffset - aFont->GetAscent() + min(0,theShadowOffset.mY),
                aWidth + abs(theShadowOffset.mX),
                aFont->GetHeight() + abs(theShadowOffset.mY));
}

int Widget::WriteString(Graphics* g, const SexyString& theString, int theX, int theY, int theWidth, int theJustification, bool drawString, int theOffset, int theLength)
{
        bool oldColored = g->mWriteColoredString;
        g->mWriteColoredString = mWriteColoredString;
        int aXOffset = g->WriteString(theString,theX,theY,theWidth,theJustification,drawString,theOffset,theLength);
        g->mWriteColoredString = oldColored;

        return aXOffset;
}

int     Widget::WriteWordWrapped(Graphics* g, const Rect& theRect, const SexyString& theLine, int theLineSpacing, int theJustification)
{
        bool oldColored = g->mWriteColoredString;
        g->mWriteColoredString = mWriteColoredString;
        int aReturn = g->WriteWordWrapped(theRect,theLine,theLineSpacing,theJustification);
        g->mWriteColoredString = oldColored;

        return aReturn;
}

int Widget::GetWordWrappedHeight(Graphics* g, int theWidth, const SexyString& theLine, int aLineSpacing)
{
        return g->GetWordWrappedHeight(theWidth,theLine,aLineSpacing);
}

int Widget::GetNumDigits(int theNumber)
{              
        int aDivisor = 10;
        int aNumDigits = 1;
        while (theNumber >= aDivisor)
        {
                aNumDigits++;
                aDivisor *= 10;
        }                      
               
        return aNumDigits;
}

void Widget::WriteNumberFromStrip(Graphics* g, int theNumber, int theX, int theY, Image* theNumberStrip, int aSpacing)
{
        int aDivisor = 10;
        int aNumDigits = 1;
        while (theNumber >= aDivisor)
        {
                aNumDigits++;
                aDivisor *= 10;
        }
        if (theNumber == 0)
                aDivisor = 10;

        int aDigitLen = theNumberStrip->GetWidth() / 10;
       
        for (int aDigitIdx = 0; aDigitIdx < aNumDigits; aDigitIdx++)
        {                              
                aDivisor /= 10;
                int aDigit = (theNumber / aDivisor) % 10;                              
                       
                Graphics* aClipG = g->Create();
                aClipG->ClipRect(theX + aDigitIdx*(aDigitLen + aSpacing), theY, aDigitLen, theNumberStrip->GetHeight());
                aClipG->DrawImage(theNumberStrip, theX + aDigitIdx*(aDigitLen + aSpacing) - aDigit*aDigitLen, theY);           
                delete aClipG;
        }
}                                                                                
                                                                 
bool Widget::Contains(int theX, int theY)
{
        return ((theX >= mX) && (theX < mX + mWidth) &&
                        (theY >= mY) && (theY < mY + mHeight));
}

Rect Widget::GetInsetRect()
{
        return Rect(mX + mMouseInsets.mLeft, mY + mMouseInsets.mTop,
                                                 mWidth - mMouseInsets.mLeft - mMouseInsets.mRight,
                                                 mHeight - mMouseInsets.mTop - mMouseInsets.mBottom);
}

void Widget::DeferOverlay(int thePriority)
{
        mWidgetManager->DeferOverlay(this, thePriority);
}

void Widget::Layout(int theLayoutFlags, Widget *theRelativeWidget, int theLeftPad, int theTopPad, int theWidthPad, int theHeightPad)
{
        int aRelLeft = theRelativeWidget->Left();
        int aRelTop = theRelativeWidget->Top();
        if (theRelativeWidget==mParent)
        {
                aRelLeft = 0;
                aRelTop = 0;
        }

        int aRelWidth = theRelativeWidget->Width();
        int aRelHeight = theRelativeWidget->Height();
        int aRelRight = aRelLeft + aRelWidth;
        int aRelBottom = aRelTop + aRelHeight;

        int aLeft = Left();
        int aTop = Top();
        int aWidth = Width();
        int aHeight = Height();

        int aType = 1;
        while(aType<LAY_Max)
        {
                if(theLayoutFlags&aType)
                {
                        switch(aType)
                        {
                                case LAY_SameWidth: aWidth = aRelWidth+theWidthPad; break;
                                case LAY_SameHeight: aHeight = aRelHeight+theHeightPad; break;
       
                                case LAY_Above: aTop = aRelTop-aHeight+theTopPad; break;
                                case LAY_Below: aTop = aRelBottom+theTopPad; break;
                                case LAY_Right: aLeft = aRelRight+theLeftPad; break;
                                case LAY_Left:  aLeft = aRelLeft-aWidth+theLeftPad; break;
                       
                                case LAY_SameLeft: aLeft = aRelLeft+theLeftPad; break;
                                case LAY_SameRight: aLeft = aRelRight-aWidth+theLeftPad; break;
                                case LAY_SameTop: aTop = aRelTop+theTopPad; break;
                                case LAY_SameBottom: aTop = aRelBottom-aHeight+theTopPad; break;

                                case LAY_GrowToRight: aWidth = aRelRight-aLeft+theWidthPad; break;
                                case LAY_GrowToLeft: aWidth = aRelLeft-aLeft+theWidthPad; break;
                                case LAY_GrowToTop: aHeight = aRelTop-aTop+theHeightPad; break;
                                case LAY_GrowToBottom: aHeight = aRelBottom-aTop+theHeightPad; break;

                                case LAY_SetLeft: aLeft = theLeftPad; break;
                                case LAY_SetTop: aTop = theTopPad; break;
                                case LAY_SetWidth: aWidth = theWidthPad; break;
                                case LAY_SetHeight: aHeight = theHeightPad; break;

                                case LAY_HCenter: aLeft = aRelLeft+(aRelWidth-aWidth)/2 + theLeftPad; break;
                                case LAY_VCenter: aTop = aRelTop+(aRelHeight-aHeight)/2 + theTopPad; break;
                        }
                }

                aType<<=1;
        }

        Resize(aLeft,aTop,aWidth,aHeight);
}