Subversion Repositories AndroidProjects

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
244 chris 1
#include "Widget.h"
2
#include "WidgetManager.h"
3
#include "Graphics.h"
4
#include "Font.h"
5
#include "Image.h"
6
#include "SexyAppBase.h"
7
#include "debug.h"
8
 
9
using namespace Sexy;
10
 
11
bool Widget::mWriteColoredString = true;
12
 
13
Widget::Widget()
14
{
15
        mWidgetManager = NULL; 
16
        mVisible = true;
17
        mDisabled = false;
18
        mIsDown = false;
19
        mIsOver = false;
20
        mDoFinger = false;     
21
        mMouseVisible = true;          
22
        mHasFocus = false;
23
        mHasTransparencies = false;    
24
        mWantsFocus = false;
25
        mTabPrev = NULL;
26
        mTabNext = NULL;
27
}
28
 
29
Widget::~Widget()
30
{      
31
        mColors.clear();
32
}
33
 
34
void Widget::WidgetRemovedHelper()
35
{
36
        if (mWidgetManager==NULL)
37
                return;
38
 
39
        // Call RemovedFromManager on all child widgets and disable them and stuff like that
40
        for (WidgetList::iterator aWidgetItr = mWidgets.begin(); aWidgetItr != mWidgets.end(); ++aWidgetItr)
41
        {
42
                Widget *aWidget = *aWidgetItr;
43
                aWidget->WidgetRemovedHelper();
44
        }      
45
 
46
        mWidgetManager->DisableWidget(this);
47
 
48
        PreModalInfoList::iterator anItr = mWidgetManager->mPreModalInfoList.begin();
49
        while (anItr != mWidgetManager->mPreModalInfoList.end())
50
        {
51
                PreModalInfo* aPreModalInfo = &(*anItr);
52
                if (aPreModalInfo->mPrevBaseModalWidget == this)
53
                        aPreModalInfo->mPrevBaseModalWidget = NULL;
54
                if (aPreModalInfo->mPrevFocusWidget == this)
55
                        aPreModalInfo->mPrevFocusWidget = NULL;
56
                ++anItr;
57
        }
58
 
59
        RemovedFromManager(mWidgetManager);
60
        MarkDirtyFull(this);
61
 
62
        mWidgetManager = NULL;
63
}
64
 
65
void Widget::OrderInManagerChanged()
66
{
67
}
68
 
69
bool Widget::IsPointVisible(int x, int y)
70
{
71
        return true;
72
}
73
 
74
void Widget::SetVisible(bool isVisible)
75
{
76
        if (mVisible == isVisible)
77
                return;
78
 
79
        mVisible = isVisible;
80
 
81
        if (mVisible)
82
                MarkDirty();
83
        else
84
                MarkDirtyFull();
85
 
86
        if (mWidgetManager != NULL)
87
                mWidgetManager->RehupMouse();
88
}
89
 
90
void Widget::Draw(Graphics* g) // Already translated
91
{
92
}
93
 
94
void Widget::DrawOverlay(Graphics* g)
95
{
96
}
97
 
98
void Widget::DrawOverlay(Graphics* g, int thePriority)
99
{
100
        DrawOverlay(g);
101
}
102
 
103
void Widget::SetColors(int theColors[][3], int theNumColors)
104
{
105
        mColors.clear();
106
 
107
        for (int i = 0; i < theNumColors; i++)
108
                SetColor(i, Color(theColors[i][0], theColors[i][1], theColors[i][2]));
109
        MarkDirty();
110
}
111
 
112
void Widget::SetColors(int theColors[][4], int theNumColors)
113
{      
114
        mColors.clear();
115
 
116
        for (int i = 0; i < theNumColors; i++)
117
                SetColor(i, Color(theColors[i][0], theColors[i][1], theColors[i][2], theColors[i][3]));        
118
 
119
        MarkDirty();
120
}
121
 
122
void Widget::SetColor(int theIdx, const Color& theColor)
123
{
124
        if (theIdx >= (int)mColors.size())
125
                mColors.resize(theIdx + 1);
126
 
127
        mColors[theIdx] = theColor;
128
        MarkDirty();
129
}
130
 
131
const Color& Widget::GetColor(int theIdx)
132
{
133
        static Color aColor;
134
        if (theIdx < (int) mColors.size())
135
                return mColors[theIdx];
136
        return aColor;
137
}
138
 
139
Color Widget::GetColor(int theIdx, const Color& theDefaultColor)
140
{
141
        if (theIdx < (int) mColors.size())
142
                return mColors[theIdx];
143
        return theDefaultColor;
144
}
145
 
146
void Widget::Resize(int theX, int theY, int theWidth, int theHeight)
147
{
148
        if ((mX == theX) && (mY == theY) && (mWidth == theWidth) && (mHeight == theHeight))
149
                return;
150
 
151
        // Mark everything dirty that is over or under the old position
152
        MarkDirtyFull();
153
 
154
        mX = theX;
155
        mY = theY;
156
        mWidth = theWidth;
157
        mHeight = theHeight;
158
 
159
        // Mark things dirty that are over the new position
160
        MarkDirty();
161
 
162
        if (mWidgetManager != NULL)
163
                mWidgetManager->RehupMouse();
164
}
165
 
166
void Widget::Resize(const Rect& theRect)
167
{
168
        Resize(theRect.mX, theRect.mY, theRect.mWidth, theRect.mHeight);
169
}
170
 
171
void Widget::Move(int theNewX, int theNewY)
172
{
173
        Resize(theNewX, theNewY, mWidth, mHeight);
174
}
175
 
176
bool Widget::WantsFocus()
177
{
178
        return mWantsFocus;
179
}
180
 
181
void Widget::SetDisabled(bool isDisabled)
182
{
183
        if (mDisabled == isDisabled)
184
                return;
185
 
186
        mDisabled = isDisabled;
187
 
188
        if ((isDisabled) && (mWidgetManager != NULL))
189
                mWidgetManager->DisableWidget(this);
190
 
191
        MarkDirty();
192
 
193
        // Incase a widget is enabled right under our cursor
194
        if ((!isDisabled) && (mWidgetManager != NULL) && (Contains(mWidgetManager->mLastMouseX, mWidgetManager->mLastMouseY)))
195
                mWidgetManager->MousePosition(mWidgetManager->mLastMouseX, mWidgetManager->mLastMouseY);
196
}
197
 
198
void Widget::GotFocus()
199
{
200
        mHasFocus = true;              
201
}
202
 
203
void Widget::LostFocus()
204
{
205
        mHasFocus = false;             
206
}
207
 
208
void Widget::Update()
209
{
210
        WidgetContainer::Update();
211
}
212
 
213
void Widget::UpdateF(float theFrac)
214
{
215
}
216
 
217
void Widget::KeyChar(SexyChar theChar)
218
{
219
}
220
 
221
void Widget::KeyDown(KeyCode theKey)
222
{
223
        if (theKey == KEYCODE_TAB)
224
        {
225
                if (mWidgetManager->mKeyDown[KEYCODE_SHIFT])
226
                {
227
                        if (mTabPrev != NULL)
228
                                mWidgetManager->SetFocus(mTabPrev);
229
                }
230
                else
231
                {
232
                        if (mTabNext != NULL)
233
                                mWidgetManager->SetFocus(mTabNext);
234
                }
235
        }
236
}
237
 
238
void Widget::KeyUp(KeyCode theKey)
239
{              
240
}
241
 
242
void Widget::ShowFinger(bool on)
243
{
244
        if (mWidgetManager == NULL)
245
                return;
246
 
247
        if (on)
248
                mWidgetManager->mApp->SetCursor(CURSOR_HAND);
249
        else
250
                mWidgetManager->mApp->SetCursor(CURSOR_POINTER);
251
 
252
        /*if (on)
253
                mWidgetManager->mApplet.setCursor(new Cursor(Cursor.HAND_CURSOR));
254
        else
255
                mWidgetManager->mApplet.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));*/
256
}
257
 
258
void Widget::MouseEnter()
259
{
260
 
261
}
262
 
263
void Widget::MouseLeave()
264
{
265
 
266
}
267
 
268
void Widget::MouseMove(int x, int y)
269
{
270
}
271
 
272
void Widget::MouseDown(int x, int y, int theClickCount)
273
{
274
        if (theClickCount == 3)
275
                MouseDown(x, y, 2, 1);
276
        else if (theClickCount >= 0)
277
                MouseDown(x, y, 0, theClickCount);
278
        else
279
                MouseDown(x, y, 1, -theClickCount);
280
}
281
 
282
void Widget::MouseDown(int x, int y, int theBtnNum, int theClickCount)
283
{
284
}
285
 
286
void Widget::MouseUp(int x, int y)
287
{
288
}
289
 
290
void Widget::MouseUp(int x, int y, int theLastDownButtonId)
291
{
292
        MouseUp(x, y);
293
 
294
        if (theLastDownButtonId == 3)
295
                MouseUp(x, y, 2, 1);
296
        else if (theLastDownButtonId >= 0)
297
                MouseUp(x, y, 0, theLastDownButtonId);
298
        else
299
                MouseUp(x, y, 1, -theLastDownButtonId);
300
}
301
 
302
void Widget::MouseUp(int x, int y, int theBtnNum, int theClickCount)
303
{
304
}
305
 
306
void Widget::MouseDrag(int x, int y)
307
{
308
}
309
 
310
void Widget::MouseWheel(int theDelta)
311
{
312
}
313
 
314
//////// Helper functions
315
 
316
Rect Widget::WriteCenteredLine(Graphics* g, int anOffset, const SexyString& theLine)
317
{
318
        Font* aFont = g->GetFont();
319
        int aWidth = aFont->StringWidth(theLine);
320
        int aX = (mWidth - aWidth) / 2;
321
 
322
        g->DrawString(theLine, aX, anOffset);
323
 
324
        return Rect(aX, anOffset - aFont->GetAscent(), aWidth, aFont->GetHeight());
325
}
326
 
327
Rect Widget::WriteCenteredLine(Graphics* g, int anOffset, const SexyString& theLine, Color theColor1, Color theColor2, const Point& theShadowOffset)
328
{
329
        Font* aFont = g->GetFont();
330
        int aWidth = aFont->StringWidth(theLine);
331
        int aX = (mWidth - aWidth) / 2;
332
 
333
        g->SetColor(theColor2);
334
        g->DrawString(theLine, (mWidth - aWidth)/2 + theShadowOffset.mX, anOffset + theShadowOffset.mY);
335
 
336
        g->SetColor(theColor1);
337
        g->DrawString(theLine, (mWidth - aWidth)/2, anOffset);
338
 
339
        // account for shadow in position and size
340
        // TODO: this may not be necessary.
341
        return Rect(
342
                aX + min(0,theShadowOffset.mX),
343
                anOffset - aFont->GetAscent() + min(0,theShadowOffset.mY),
344
                aWidth + abs(theShadowOffset.mX),
345
                aFont->GetHeight() + abs(theShadowOffset.mY));
346
}
347
 
348
int Widget::WriteString(Graphics* g, const SexyString& theString, int theX, int theY, int theWidth, int theJustification, bool drawString, int theOffset, int theLength)
349
{
350
        bool oldColored = g->mWriteColoredString;
351
        g->mWriteColoredString = mWriteColoredString;
352
        int aXOffset = g->WriteString(theString,theX,theY,theWidth,theJustification,drawString,theOffset,theLength);
353
        g->mWriteColoredString = oldColored;
354
 
355
        return aXOffset;
356
}
357
 
358
int     Widget::WriteWordWrapped(Graphics* g, const Rect& theRect, const SexyString& theLine, int theLineSpacing, int theJustification)
359
{
360
        bool oldColored = g->mWriteColoredString;
361
        g->mWriteColoredString = mWriteColoredString;
362
        int aReturn = g->WriteWordWrapped(theRect,theLine,theLineSpacing,theJustification);
363
        g->mWriteColoredString = oldColored;
364
 
365
        return aReturn;
366
}
367
 
368
int Widget::GetWordWrappedHeight(Graphics* g, int theWidth, const SexyString& theLine, int aLineSpacing)
369
{
370
        return g->GetWordWrappedHeight(theWidth,theLine,aLineSpacing);
371
}
372
 
373
int Widget::GetNumDigits(int theNumber)
374
{              
375
        int aDivisor = 10;
376
        int aNumDigits = 1;
377
        while (theNumber >= aDivisor)
378
        {
379
                aNumDigits++;
380
                aDivisor *= 10;
381
        }                      
382
 
383
        return aNumDigits;
384
}
385
 
386
void Widget::WriteNumberFromStrip(Graphics* g, int theNumber, int theX, int theY, Image* theNumberStrip, int aSpacing)
387
{
388
        int aDivisor = 10;
389
        int aNumDigits = 1;
390
        while (theNumber >= aDivisor)
391
        {
392
                aNumDigits++;
393
                aDivisor *= 10;
394
        }
395
        if (theNumber == 0)
396
                aDivisor = 10;
397
 
398
        int aDigitLen = theNumberStrip->GetWidth() / 10;
399
 
400
        for (int aDigitIdx = 0; aDigitIdx < aNumDigits; aDigitIdx++)
401
        {                              
402
                aDivisor /= 10;
403
                int aDigit = (theNumber / aDivisor) % 10;                              
404
 
405
                Graphics* aClipG = g->Create();
406
                aClipG->ClipRect(theX + aDigitIdx*(aDigitLen + aSpacing), theY, aDigitLen, theNumberStrip->GetHeight());
407
                aClipG->DrawImage(theNumberStrip, theX + aDigitIdx*(aDigitLen + aSpacing) - aDigit*aDigitLen, theY);           
408
                delete aClipG;
409
        }
410
}                                                                                
411
 
412
bool Widget::Contains(int theX, int theY)
413
{
414
        return ((theX >= mX) && (theX < mX + mWidth) &&
415
                        (theY >= mY) && (theY < mY + mHeight));
416
}
417
 
418
Rect Widget::GetInsetRect()
419
{
420
        return Rect(mX + mMouseInsets.mLeft, mY + mMouseInsets.mTop,
421
                                                 mWidth - mMouseInsets.mLeft - mMouseInsets.mRight,
422
                                                 mHeight - mMouseInsets.mTop - mMouseInsets.mBottom);
423
}
424
 
425
void Widget::DeferOverlay(int thePriority)
426
{
427
        mWidgetManager->DeferOverlay(this, thePriority);
428
}
429
 
430
void Widget::Layout(int theLayoutFlags, Widget *theRelativeWidget, int theLeftPad, int theTopPad, int theWidthPad, int theHeightPad)
431
{
432
        int aRelLeft = theRelativeWidget->Left();
433
        int aRelTop = theRelativeWidget->Top();
434
        if (theRelativeWidget==mParent)
435
        {
436
                aRelLeft = 0;
437
                aRelTop = 0;
438
        }
439
 
440
        int aRelWidth = theRelativeWidget->Width();
441
        int aRelHeight = theRelativeWidget->Height();
442
        int aRelRight = aRelLeft + aRelWidth;
443
        int aRelBottom = aRelTop + aRelHeight;
444
 
445
        int aLeft = Left();
446
        int aTop = Top();
447
        int aWidth = Width();
448
        int aHeight = Height();
449
 
450
        int aType = 1;
451
        while(aType<LAY_Max)
452
        {
453
                if(theLayoutFlags&aType)
454
                {
455
                        switch(aType)
456
                        {
457
                                case LAY_SameWidth: aWidth = aRelWidth+theWidthPad; break;
458
                                case LAY_SameHeight: aHeight = aRelHeight+theHeightPad; break;
459
 
460
                                case LAY_Above: aTop = aRelTop-aHeight+theTopPad; break;
461
                                case LAY_Below: aTop = aRelBottom+theTopPad; break;
462
                                case LAY_Right: aLeft = aRelRight+theLeftPad; break;
463
                                case LAY_Left:  aLeft = aRelLeft-aWidth+theLeftPad; break;
464
 
465
                                case LAY_SameLeft: aLeft = aRelLeft+theLeftPad; break;
466
                                case LAY_SameRight: aLeft = aRelRight-aWidth+theLeftPad; break;
467
                                case LAY_SameTop: aTop = aRelTop+theTopPad; break;
468
                                case LAY_SameBottom: aTop = aRelBottom-aHeight+theTopPad; break;
469
 
470
                                case LAY_GrowToRight: aWidth = aRelRight-aLeft+theWidthPad; break;
471
                                case LAY_GrowToLeft: aWidth = aRelLeft-aLeft+theWidthPad; break;
472
                                case LAY_GrowToTop: aHeight = aRelTop-aTop+theHeightPad; break;
473
                                case LAY_GrowToBottom: aHeight = aRelBottom-aTop+theHeightPad; break;
474
 
475
                                case LAY_SetLeft: aLeft = theLeftPad; break;
476
                                case LAY_SetTop: aTop = theTopPad; break;
477
                                case LAY_SetWidth: aWidth = theWidthPad; break;
478
                                case LAY_SetHeight: aHeight = theHeightPad; break;
479
 
480
                                case LAY_HCenter: aLeft = aRelLeft+(aRelWidth-aWidth)/2 + theLeftPad; break;
481
                                case LAY_VCenter: aTop = aRelTop+(aRelHeight-aHeight)/2 + theTopPad; break;
482
                        }
483
                }
484
 
485
                aType<<=1;
486
        }
487
 
488
        Resize(aLeft,aTop,aWidth,aHeight);
489
}