Subversion Repositories AndroidProjects

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
244 chris 1
#include "ListWidget.h"
2
#include "Font.h"
3
#include "WidgetManager.h"
4
#include "ScrollbarWidget.h"
5
#include "ListListener.h"
6
#include "SexyAppBase.h"
7
 
8
using namespace Sexy;
9
 
10
static int gInitialListWidgetColors[][3] = {{255, 255, 255}, {255, 255, 255}, {0, 0, 0}, {0, 192, 0}, {0, 0, 128}, {255, 255, 255}};
11
 
12
ListWidget::ListWidget(int theId, Font *theFont, ListListener *theListListener)
13
{
14
        mJustify = JUSTIFY_LEFT;
15
        mHiliteIdx = -1;
16
        mSelectIdx = -1;
17
 
18
        if (theFont != NULL)
19
                mItemHeight = theFont->GetHeight();
20
        else
21
                mItemHeight = -1;
22
 
23
        SetColors(gInitialListWidgetColors, 6);
24
 
25
        mId = theId;
26
        mFont = theFont;
27
        mListListener = theListListener;
28
        mParent = NULL;
29
        mChild = NULL;
30
        mScrollbar = NULL;
31
        mPosition = 0;
32
        mPageSize = 0;
33
        mSortFromChild = false;
34
        mDrawOutline = true;
35
        mMaxNumericPlaces = 0; 
36
        mDrawSelectWhenHilited = false;
37
        mDoFingerWhenHilited = true;
38
}
39
 
40
ListWidget::~ListWidget()
41
{
42
}
43
 
44
void ListWidget::RemovedFromManager(WidgetManager *theManager)
45
{
46
        Widget::RemovedFromManager(theManager);
47
        if (mListListener)
48
                mListListener->ListClosed(mId);
49
}
50
 
51
SexyString ListWidget::GetSortKey(int theIdx)
52
{
53
        SexyString aString = mLines[theIdx];
54
 
55
        while (aString.length() < (ulong) mMaxNumericPlaces)
56
                aString = _S("0") + aString;
57
 
58
        if (mSortFromChild)
59
                return mChild->GetSortKey(theIdx) + aString;
60
        else
61
        {
62
                if (mChild == NULL)    
63
                        return aString;
64
                else
65
                        return aString + mChild->GetSortKey(theIdx);
66
        }
67
 
68
        return _S("");
69
}
70
 
71
void ListWidget::Sort(bool ascending)
72
{
73
        int aCount = mLines.size();
74
        int* aMap = new int[aCount];
75
        SexyString* aKeys = new SexyString[aCount];
76
 
77
        int i;
78
        for (i = 0; i < aCount; i++)
79
        {
80
                aMap[i] = i;
81
                aKeys[i] = GetSortKey(i);              
82
        }
83
 
84
        for (i = 1; i < aCount; i++)
85
                for (int j = 0; j < aCount - i; j++)
86
                {
87
                        int aComp = aKeys[j].compare(aKeys[j+1]);
88
                        if ((ascending && (aComp > 0)) || (!ascending && (aComp < 0)))
89
                        {
90
                                int aSwapInt = aMap[j];
91
                                aMap[j] = aMap[j+1];
92
                                aMap[j+1] = aSwapInt;
93
 
94
                                SexyString aSwapKey = aKeys[j];
95
                                aKeys[j] = aKeys[j+1];
96
                                aKeys[j+1] = aSwapKey;
97
                        }
98
                }
99
 
100
        ListWidget *aListWidget = this;
101
        while (aListWidget->mParent != NULL)   
102
                aListWidget = aListWidget->mParent;
103
 
104
        while (aListWidget != NULL)
105
        {
106
                SexyStringVector aNewLines;
107
                ColorVector aNewLineColors;
108
 
109
                for (int i = 0; i < aCount; i++)
110
                {
111
                        aNewLines.push_back(aListWidget->mLines[aMap[i]]);
112
                        aNewLineColors.push_back(aListWidget->mLineColors[aMap[i]]);
113
                }
114
 
115
                aListWidget->mLines = aNewLines;
116
                aListWidget->mLineColors = aNewLineColors;
117
 
118
                aListWidget->MarkDirty();
119
 
120
                aListWidget = aListWidget->mChild;
121
        }
122
 
123
        delete aMap;
124
        delete aKeys;
125
}
126
 
127
SexyString ListWidget::GetStringAt(int theIdx)
128
{
129
        return
130
                mLines[theIdx];
131
}
132
 
133
void ListWidget::Resize(int theX, int theY, int theWidth, int theHeight)
134
{
135
        Widget::Resize(theX, theY, theWidth, theHeight);
136
 
137
        double aPageSize = 1;                  
138
        int anItemHeight = (mItemHeight != -1) ? mItemHeight : mFont->GetHeight();
139
 
140
        if (mHeight > anItemHeight+8)
141
                aPageSize = (mHeight - 8.0) / anItemHeight;
142
 
143
        mPageSize = aPageSize;
144
 
145
        if (mScrollbar != NULL)
146
                mScrollbar->SetPageSize(aPageSize);
147
}
148
 
149
int ListWidget::AddLine(const SexyString& theLine, bool alphabetical)
150
{      
151
        int anIdx = -1;
152
        bool inserted = false;
153
 
154
        if (alphabetical)
155
        {      
156
                for (int i = 0; i < (int) mLines.size(); i++)          
157
                        if (sexystrcmp(theLine.c_str(), mLines[i].c_str()) < 0)
158
                        {
159
                                anIdx = i;
160
 
161
                                ListWidget *aListWidget = this;
162
 
163
                                while (aListWidget->mParent != NULL)
164
                                        aListWidget = aListWidget->mParent;
165
 
166
                                while (aListWidget != NULL)
167
                                {
168
                                        if (aListWidget == this)
169
                                                aListWidget->mLines.insert(aListWidget->mLines.begin() + i, theLine);
170
                                        else
171
                                                aListWidget->mLines.insert(aListWidget->mLines.begin() + i, _S("-"));
172
 
173
                                        aListWidget->mLineColors.insert(aListWidget->mLineColors.begin() + i, mColors[COLOR_TEXT]);
174
                                        aListWidget->MarkDirty();
175
 
176
                                        aListWidget = aListWidget->mChild;
177
                                }
178
 
179
                                inserted = true;
180
                                break;
181
                        }
182
        }
183
 
184
        if (!inserted)
185
        {
186
                anIdx = mLines.size();
187
 
188
                ListWidget *aListWidget = this;
189
 
190
                while (aListWidget->mParent!=NULL)
191
                        aListWidget = aListWidget->mParent;
192
 
193
                while (aListWidget!=NULL)
194
                {
195
                        if (aListWidget==this)
196
                                aListWidget->mLines.push_back(theLine);
197
                        else
198
                                aListWidget->mLines.push_back(_S("-"));
199
 
200
                        aListWidget->mLineColors.push_back(mColors[COLOR_TEXT]);
201
                        aListWidget->MarkDirty();
202
 
203
                        aListWidget = aListWidget->mChild;
204
                }
205
        }
206
 
207
        if (mScrollbar!=NULL)
208
                mScrollbar->SetMaxValue(mLines.size());        
209
 
210
        return anIdx;
211
}
212
 
213
 
214
void ListWidget::SetLine(int theIdx, const SexyString& theString)
215
{
216
        mLines[theIdx] = theString;    
217
        MarkDirty();
218
}
219
 
220
int ListWidget::GetLineCount()
221
{
222
        return mLines.size();  
223
}
224
 
225
int ListWidget::GetLineIdx(const SexyString& theLine)
226
{      
227
        for (ulong i = 0; i < mLines.size(); i++)      
228
                if (sexystrcmp(mLines[i].c_str(), theLine.c_str()) == 0)
229
                        return i;
230
 
231
        return -1;
232
}
233
 
234
void ListWidget::SetColor(const SexyString& theLine, const Color& theColor)
235
{
236
        int anIdx = GetLineIdx(theLine);
237
        SetLineColor(anIdx, theColor); 
238
}
239
 
240
void ListWidget::SetColor(int theIdx, const Color& theColor)
241
{
242
        Widget::SetColor(theIdx, theColor);
243
}
244
 
245
void ListWidget::SetLineColor(int theIdx, const Color& theColor)
246
{
247
        if ((theIdx >= 0) && (theIdx < (int)mLines.size()))
248
        {
249
                ListWidget *aListWidget = this;
250
 
251
                while (aListWidget->mParent != NULL)
252
                        aListWidget = aListWidget->mParent;
253
 
254
                while (aListWidget != NULL)
255
                {
256
                        aListWidget->mLineColors[theIdx] = theColor;
257
                        aListWidget->MarkDirty();
258
 
259
                        aListWidget = aListWidget->mChild;
260
                }                      
261
        }
262
}
263
 
264
void ListWidget::RemoveLine(int theIdx)
265
{
266
        if (theIdx != -1)
267
        {
268
                ListWidget *aListWidget = this;
269
 
270
                while (aListWidget->mParent != NULL)
271
                        aListWidget = aListWidget->mParent;
272
 
273
                while (aListWidget != NULL)
274
                {
275
                        aListWidget->mLines.erase(aListWidget->mLines.begin() + theIdx);
276
                        aListWidget->mLineColors.erase(aListWidget->mLineColors.begin() + theIdx);
277
 
278
                        aListWidget->MarkDirty();
279
                        aListWidget = aListWidget->mChild;     
280
                }
281
        }
282
 
283
        if (mScrollbar != NULL)
284
                mScrollbar->SetMaxValue(mLines.size());
285
}
286
 
287
void ListWidget::RemoveAll()
288
{
289
        ListWidget *aListWidget = this;
290
 
291
        while (aListWidget->mParent != NULL)
292
                aListWidget = aListWidget->mParent;                    
293
 
294
        while (aListWidget != NULL)
295
        {
296
                aListWidget->mLines.clear();
297
                aListWidget->mLineColors.clear();
298
                aListWidget->mSelectIdx = -1;
299
                aListWidget->mHiliteIdx = -1;
300
 
301
                aListWidget->MarkDirty();
302
                aListWidget = aListWidget->mChild;     
303
        }
304
 
305
        if (mScrollbar != NULL)
306
                mScrollbar->SetMaxValue(mLines.size());
307
}
308
 
309
int ListWidget::GetOptimalWidth()
310
{
311
        int aMaxWidth = 0;
312
 
313
        for (ulong i = 0; i < mLines.size(); i++)
314
                aMaxWidth = max(aMaxWidth, mFont->StringWidth(mLines[i]));
315
 
316
        return aMaxWidth + 16;
317
}
318
 
319
int ListWidget::GetOptimalHeight()
320
{
321
        int anItemHeight = (mItemHeight != -1) ? mItemHeight : mFont->GetHeight();
322
 
323
        return anItemHeight * mLines.size() + 8;
324
}
325
 
326
void ListWidget::OrderInManagerChanged()
327
{
328
        Widget::OrderInManagerChanged();
329
 
330
        if (mChild != NULL)
331
                gSexyAppBase->mWidgetManager->PutInfront(mChild, this);
332
        if (mScrollbar != NULL)
333
                gSexyAppBase->mWidgetManager->PutInfront(mScrollbar, this);
334
}
335
 
336
void ListWidget::Draw(Graphics *g)
337
{
338
        g->SetColor(mColors[COLOR_BKG]);
339
        g->FillRect(0, 0, mWidth, mHeight);
340
 
341
        Graphics aClipG(*g);
342
        aClipG.ClipRect(4, 4, mWidth - 8, mHeight - 8);
343
 
344
        Graphics aSelectClipG(*g);
345
        aSelectClipG.ClipRect(0, 4, mWidth, mHeight - 8);
346
 
347
        aClipG.SetFont(mFont);
348
 
349
        int aFirstLine = (int) mPosition;
350
        int aLastLine = min((int) mLines.size()-1, (int) mPosition + (int) mPageSize + 1);
351
 
352
        int anItemHeight, anItemOffset;
353
        if (mItemHeight != -1)
354
        {
355
                anItemHeight = mItemHeight;
356
                anItemOffset = (anItemHeight-mFont->GetHeight())/2;
357
        }
358
        else
359
        {
360
                anItemHeight = mFont->GetHeight();
361
                anItemOffset = 0;
362
        }
363
 
364
        for (int i = aFirstLine; i <= aLastLine; i++)
365
        {
366
                int aDrawY = 4 + (int) ((i - mPosition)*anItemHeight);
367
 
368
                if (i == mSelectIdx || (i==mHiliteIdx && mDrawSelectWhenHilited))
369
                {
370
                        aSelectClipG.SetColor(mColors[COLOR_SELECT]);
371
                        aSelectClipG.FillRect(0, aDrawY, mWidth, anItemHeight);
372
                }
373
 
374
                if (i == mHiliteIdx)
375
                        aClipG.SetColor(mColors[COLOR_HILITE]);
376
                else if ((i == mSelectIdx) && (mColors.size() > COLOR_SELECT_TEXT))
377
                        aClipG.SetColor(mColors[COLOR_SELECT_TEXT]);
378
                else
379
                        aClipG.SetColor(mLineColors[i]);
380
 
381
                SexyString aString = mLines[i];
382
                int aFontX;
383
                switch (mJustify)
384
                {
385
                case JUSTIFY_LEFT:
386
                        aFontX = 4;
387
                        break;
388
                case JUSTIFY_CENTER:
389
                        aFontX = (mWidth - mFont->StringWidth(aString))/2;
390
                        break;
391
                default:
392
                        aFontX = mWidth - mFont->StringWidth(aString) - 4;
393
                        break;
394
                }
395
 
396
                aClipG.DrawString(aString, aFontX, aDrawY + mFont->GetAscent() + anItemOffset);
397
        }
398
 
399
        if (mDrawOutline)
400
        {
401
                g->SetColor(mColors[COLOR_OUTLINE]);           
402
                g->DrawRect(0, 0, mWidth-1, mHeight-1);
403
        }
404
}
405
 
406
void ListWidget::ScrollPosition(int theId, double thePosition)
407
{
408
        if (mChild != NULL)    
409
                mChild->ScrollPosition(theId, thePosition);
410
 
411
        mPosition = thePosition;                                               
412
        MarkDirty();
413
}
414
 
415
void ListWidget::SetHilite(int theHiliteIdx, bool notifyListener)
416
{
417
        int anOldIdx = mHiliteIdx;
418
        mHiliteIdx = theHiliteIdx;
419
        if (anOldIdx!=mHiliteIdx && notifyListener && mListListener!=NULL)
420
                mListListener->ListHiliteChanged(mId,anOldIdx,mHiliteIdx);
421
}
422
 
423
 
424
void ListWidget::MouseMove(int x, int y)
425
{
426
        int anItemHeight = (mItemHeight != -1) ? mItemHeight : mFont->GetHeight();
427
 
428
        int aNewHilite = (int) (((y - 4) / (double) anItemHeight) + mPosition);
429
        if ((aNewHilite < 0) || (aNewHilite >= (int) mLines.size()))
430
                aNewHilite = -1;
431
 
432
        if (aNewHilite != mHiliteIdx)
433
        {
434
                ListWidget* aListWidget = this;
435
 
436
                while (aListWidget->mParent != NULL)
437
                        aListWidget = aListWidget->mParent;
438
 
439
                while (aListWidget != NULL)
440
                {
441
                        aListWidget->SetHilite(aNewHilite,true);
442
                        aListWidget->MarkDirty();
443
                        aListWidget = aListWidget->mChild;     
444
                }
445
 
446
                if (mHiliteIdx == -1 || !mDoFingerWhenHilited)
447
                        mWidgetManager->mApp->SetCursor(CURSOR_POINTER);
448
                else
449
                        mWidgetManager->mApp->SetCursor(CURSOR_HAND);
450
        }
451
}
452
 
453
void ListWidget::MouseDown(int x, int y, int theBtnNum, int theClickCount)
454
{
455
        if ((mHiliteIdx != -1) && (mListListener != NULL))
456
                mListListener->ListClicked(mId, mHiliteIdx, theClickCount);
457
}
458
 
459
void ListWidget::MouseLeave()
460
{
461
        ListWidget *aListWidget = this;
462
 
463
        while (aListWidget->mParent != NULL)
464
                aListWidget = aListWidget->mParent;                    
465
 
466
        while (aListWidget != NULL)
467
        {
468
                aListWidget->SetHilite(-1,true);       
469
                aListWidget->MarkDirty();      
470
                aListWidget = aListWidget->mChild;
471
        }
472
 
473
        mWidgetManager->mApp->SetCursor(CURSOR_POINTER);
474
}
475
 
476
void ListWidget::SetSelect(int theSelectIdx)
477
{
478
        ListWidget *aListWidget = this;
479
 
480
        while (aListWidget->mParent != NULL)
481
                aListWidget = aListWidget->mParent;
482
 
483
        while (aListWidget != NULL)    
484
        {
485
                aListWidget->mSelectIdx = theSelectIdx;
486
                aListWidget->MarkDirty();      
487
                aListWidget = aListWidget->mChild;
488
        }
489
}
490
 
491
 
492
void ListWidget::MouseWheel(int theDelta)
493
{
494
        if (mScrollbar != NULL)
495
        {
496
                int aScrollAmount = 5;
497
                if (theDelta > 0)
498
                {
499
                        mScrollbar->SetValue(mScrollbar->mValue - aScrollAmount);
500
//                      mScrollbar->mUpdateMode = ScrollbarWidget::UPDATE_MODE_PGUP;
501
//                      mScrollbar->mUpdateAcc = 0;
502
                }
503
                else if (theDelta < 0)
504
                {
505
                        mScrollbar->SetValue(mScrollbar->mValue + aScrollAmount);
506
//                      mScrollbar->mUpdateMode = ScrollbarWidget::UPDATE_MODE_PGDN;
507
//                      mScrollbar->mUpdateAcc = 0;
508
                }
509
        }
510
}