Subversion Repositories tpanel

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
202 andreas 1
/*
2
 * Copyright (C) 2022 by Andreas Theofilu <andreas@theosys.at>
3
 *
4
 * This program is free software; you can redistribute it and/or modify
5
 * it under the terms of the GNU General Public License as published by
6
 * the Free Software Foundation; either version 3 of the License, or
7
 * (at your option) any later version.
8
 *
9
 * This program is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 * GNU General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU General Public License
15
 * along with this program; if not, write to the Free Software Foundation,
16
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
17
 */
18
 
19
#include <string>
20
 
203 andreas 21
#include <include/core/SkFont.h>
22
#include <include/core/SkFontMetrics.h>
23
#include <include/core/SkTextBlob.h>
24
 
202 andreas 25
#include "tpageinterface.h"
205 andreas 26
#include "tsystemsound.h"
206 andreas 27
#include "tobject.h"
28
#include "ttpinit.h"
204 andreas 29
#include "tconfig.h"
203 andreas 30
#include "tresources.h"
206 andreas 31
#include "tpagemanager.h"
203 andreas 32
#include "terror.h"
202 andreas 33
 
34
using std::string;
35
using std::vector;
36
 
37
bool TPageInterface::drawText(PAGE_T& pinfo, SkBitmap *img)
38
{
39
    MSG_TRACE("TPageInterface::drawText(PAGE_T& pinfo, SkImage& img)");
40
 
41
    if (pinfo.sr[0].te.empty())
42
        return true;
43
 
44
    MSG_DEBUG("Searching for font number " << pinfo.sr[0].fi << " with text " << pinfo.sr[0].te);
45
    FONT_T font = mFonts->getFont(pinfo.sr[0].fi);
46
 
47
    if (!font.file.empty())
48
    {
49
        SkCanvas canvas(*img, SkSurfaceProps(1, kUnknown_SkPixelGeometry));
50
        sk_sp<SkTypeface> typeFace = mFonts->getTypeFace(pinfo.sr[0].fi);
51
 
52
        if (!typeFace)
53
        {
54
            MSG_ERROR("Error creating type face " << font.fullName);
55
            TError::setError();
56
            return false;
57
        }
58
 
205 andreas 59
        SkScalar fontSizePt = ((SkScalar)font.size * 1.322);    // Calculate points from pixels (close up)
60
        SkFont skFont(typeFace, fontSizePt);                    // Skia require the font size in points
202 andreas 61
 
62
        SkPaint paint;
63
        paint.setAntiAlias(true);
64
        SkColor color = TColor::getSkiaColor(pinfo.sr[0].ct);
65
        paint.setColor(color);
66
        paint.setStyle(SkPaint::kFill_Style);
67
 
68
        SkFontMetrics metrics;
69
        skFont.getMetrics(&metrics);
70
        int lines = numberLines(pinfo.sr[0].te);
71
 
72
        if (lines > 1 || pinfo.sr[0].ww)
73
        {
74
            vector<string> textLines;
75
 
76
            if (!pinfo.sr[0].ww)
77
                textLines = ::splitLine(pinfo.sr[0].te);
78
            else
79
            {
80
                textLines = splitLine(pinfo.sr[0].te, pinfo.width, pinfo.height, skFont, paint);
81
                lines = textLines.size();
82
            }
83
 
84
            int lineHeight = calcLineHeight(pinfo.sr[0].te, skFont);
85
            int totalHeight = lineHeight * lines;
86
 
87
            if (totalHeight > pinfo.height)
88
            {
89
                lines = pinfo.height / lineHeight;
90
                totalHeight = lineHeight * lines;
91
            }
92
 
93
            MSG_DEBUG("Line height: " << lineHeight);
203 andreas 94
            Button::POSITION_t position = calcImagePosition(&pinfo, pinfo.width, totalHeight, Button::SC_TEXT, 1);
202 andreas 95
            MSG_DEBUG("Position frame: l: " << position.left << ", t: " << position.top << ", w: " << position.width << ", h: " << position.height);
96
 
97
            if (!position.valid)
98
            {
99
                MSG_ERROR("Error calculating the text position!");
100
                TError::setError();
101
                return false;
102
            }
103
 
104
            vector<string>::iterator iter;
105
            int line = 0;
106
 
107
            for (iter = textLines.begin(); iter != textLines.end(); iter++)
108
            {
109
                sk_sp<SkTextBlob> blob = SkTextBlob::MakeFromString(iter->c_str(), skFont);
110
                SkRect rect;
111
                skFont.measureText(iter->c_str(), iter->length(), SkTextEncoding::kUTF8, &rect, &paint);
203 andreas 112
                Button::POSITION_t pos = calcImagePosition(&pinfo, rect.width(), lineHeight, Button::SC_TEXT, 1);
202 andreas 113
 
114
                if (!pos.valid)
115
                {
116
                    MSG_ERROR("Error calculating the text position!");
117
                    TError::setError();
118
                    return false;
119
                }
120
                MSG_DEBUG("Triing to print line: " << *iter);
121
 
122
                SkScalar startX = (SkScalar)pos.left;
123
                SkScalar startY = (SkScalar)position.top + lineHeight * line;
124
                MSG_DEBUG("x=" << startX << ", y=" << startY);
125
                canvas.drawTextBlob(blob, startX, startY + lineHeight / 2 + 4, paint);
126
                line++;
127
 
128
                if (line > lines)
129
                    break;
130
            }
131
        }
132
        else    // single line
133
        {
134
            sk_sp<SkTextBlob> blob = SkTextBlob::MakeFromString(pinfo.sr[0].te.c_str(), skFont);
135
            SkRect rect;
136
            skFont.measureText(pinfo.sr[0].te.c_str(), pinfo.sr[0].te.length(), SkTextEncoding::kUTF8, &rect, &paint);
203 andreas 137
            Button::POSITION_t position = calcImagePosition(&pinfo, rect.width(), (rect.height() * (float)lines), Button::SC_TEXT, 0);
202 andreas 138
 
139
            if (!position.valid)
140
            {
141
                MSG_ERROR("Error calculating the text position!");
142
                TError::setError();
143
                return false;
144
            }
145
 
146
            MSG_DEBUG("Printing line " << pinfo.sr[0].te);
147
            SkScalar startX = (SkScalar)position.left;
148
            SkScalar startY = (SkScalar)position.top + metrics.fCapHeight; // + metrics.fLeading; // (metrics.fAscent * -1.0);
149
            canvas.drawTextBlob(blob, startX, startY, paint);
150
        }
151
    }
152
    else
153
    {
154
        MSG_WARNING("No font file name found for font " << pinfo.sr[0].fi);
155
    }
156
 
157
    return true;
158
}
159
 
203 andreas 160
Button::POSITION_t TPageInterface::calcImagePosition(PAGE_T *page, int width, int height, Button::CENTER_CODE cc, int line)
202 andreas 161
{
203 andreas 162
    DECL_TRACER("TPageInterface::calcImagePosition(PAGE_T *page, int with, int height, CENTER_CODE code, int number)");
202 andreas 163
 
203 andreas 164
    Button::SR_T act_sr;
165
    Button::POSITION_t position;
202 andreas 166
    int ix, iy;
167
 
168
    if (sr.size() == 0)
169
        return position;
170
 
171
    act_sr = sr.at(0);
172
    //    int border_size = getBorderSize(act_sr.bs);
173
    int border_size = 0;
174
    int code, border = border_size;
175
    string dbgCC;
176
    int rwt = 0, rht = 0;
177
 
178
    switch (cc)
179
    {
203 andreas 180
        case Button::SC_ICON:
202 andreas 181
            code = act_sr.ji;
182
            ix = act_sr.ix;
183
            iy = act_sr.iy;
184
            border = border_size = 0;
185
            dbgCC = "ICON";
186
            rwt = width;
187
            rht = height;
188
            break;
189
 
203 andreas 190
        case Button::SC_BITMAP:
202 andreas 191
            code = act_sr.jb;
192
            ix = act_sr.bx;
193
            iy = act_sr.by;
194
            dbgCC = "BITMAP";
203 andreas 195
            rwt = std::min(page->width - border * 2, width);
196
            rht = std::min(page->height - border_size * 2, height);
202 andreas 197
            break;
198
 
203 andreas 199
        case Button::SC_TEXT:
202 andreas 200
            code = act_sr.jt;
201
            ix = act_sr.tx;
202
            iy = act_sr.ty;
203
            dbgCC = "TEXT";
204
            border += 4;
203 andreas 205
            rwt = std::min(page->width - border * 2, width);
206
            rht = std::min(page->height - border_size * 2, height);
202 andreas 207
            break;
208
    }
209
 
210
    if (width > rwt || height > rht)
211
        position.overflow = true;
212
 
213
    switch (code)
214
    {
215
        case 0: // absolute position
216
            position.left = ix;
217
 
203 andreas 218
            if (cc == Button::SC_TEXT)
202 andreas 219
                position.top = iy + height * line;
220
        else
221
            position.top = iy;
222
 
203 andreas 223
        if (cc == Button::SC_BITMAP && ix < 0 && rwt < width)
202 andreas 224
            position.left *= -1;
225
 
203 andreas 226
        if (cc == Button::SC_BITMAP && iy < 0 && rht < height)
202 andreas 227
            position.top += -1;
228
 
229
        position.width = rwt;
230
        position.height = rht;
231
        break;
232
 
233
        case 1: // top, left
203 andreas 234
            if (cc == Button::SC_TEXT)
202 andreas 235
            {
236
                position.left = border;
237
                position.top = height * line;
238
            }
239
 
240
            position.width = rwt;
241
            position.height = rht;
242
            break;
243
 
244
        case 2: // center, top
203 andreas 245
            if (cc == Button::SC_TEXT)
202 andreas 246
                position.top = height * line;
247
 
203 andreas 248
        position.left = (page->width - rwt) / 2;
202 andreas 249
        position.height = rht;
250
        position.width = rwt;
251
        break;
252
 
253
        case 3: // right, top
203 andreas 254
            position.left = page->width - rwt;
202 andreas 255
 
203 andreas 256
            if (cc == Button::SC_TEXT)
202 andreas 257
            {
258
                position.left = (((position.left - border) < 0) ? 0 : position.left - border);
259
                position.top = height * line;
260
            }
261
 
262
            position.width = rwt;
263
            position.height = rht;
264
            break;
265
 
266
        case 4: // left, middle
203 andreas 267
            if (cc == Button::SC_TEXT)
202 andreas 268
            {
269
                position.left = border;
203 andreas 270
                position.top = ((page->height - rht) / 2) + (height / 2 * line);
202 andreas 271
            }
272
            else
203 andreas 273
                position.top = (page->height - rht) / 2;
202 andreas 274
 
275
        position.width = rwt;
276
        position.height = rht;
277
        break;
278
 
279
        case 6: // right, middle
203 andreas 280
            position.left = page->width - rwt;
202 andreas 281
 
203 andreas 282
            if (cc == Button::SC_TEXT)
202 andreas 283
            {
284
                position.left = (((position.left - border) < 0) ? 0 : position.left - border);
203 andreas 285
                position.top = ((page->height - rht) / 2) + (height / 2 * line);
202 andreas 286
            }
287
            else
203 andreas 288
                position.top = (page->height - rht) / 2;
202 andreas 289
 
290
        position.width = rwt;
291
        position.height = rht;
292
        break;
293
 
294
        case 7: // left, bottom
203 andreas 295
            if (cc == Button::SC_TEXT)
202 andreas 296
            {
297
                position.left = border_size;
203 andreas 298
                position.top = (page->height - rht) - height * line;
202 andreas 299
            }
300
            else
203 andreas 301
                position.top = page->height - rht;
202 andreas 302
 
303
        position.width = rwt;
304
        position.height = rht;
305
        break;
306
 
307
        case 8: // center, bottom
203 andreas 308
            position.left = (page->width - rwt) / 2;
202 andreas 309
 
203 andreas 310
            if (cc == Button::SC_TEXT)
311
                position.top = (page->height - rht) - height * line;
202 andreas 312
        else
203 andreas 313
            position.top = page->height - rht;
202 andreas 314
 
315
        position.width = rwt;
316
        position.height = rht;
317
        break;
318
 
319
        case 9: // right, bottom
203 andreas 320
            position.left = page->width - rwt;
202 andreas 321
 
203 andreas 322
            if (cc == Button::SC_TEXT)
202 andreas 323
            {
324
                position.left = (((position.left - border) < 0) ? 0 : position.left - border);
203 andreas 325
                position.top = (page->height - rht) - height * line;
202 andreas 326
            }
327
            else
203 andreas 328
                position.top = page->height - rht;
202 andreas 329
        break;
330
 
331
        default: // center, middle
203 andreas 332
            position.left = (page->width - rwt) / 2;
202 andreas 333
 
203 andreas 334
            if (cc == Button::SC_TEXT)
335
                position.top = ((page->height - rht) / 2) + (height / 2 * line);
202 andreas 336
        else
203 andreas 337
            position.top = (page->height - rht) / 2;
202 andreas 338
 
339
        position.width = rwt;
340
        position.height = rht;
341
    }
342
 
343
    MSG_DEBUG("Type: " << dbgCC << ", PosType=" << code << ", Position: x=" << position.left << ", y=" << position.top << ", w=" << position.width << ", h=" << position.height << ", Overflow: " << (position.overflow ? "YES" : "NO"));
344
    position.valid = true;
345
    return position;
346
}
347
 
348
int TPageInterface::calcLineHeight(const string& text, SkFont& font)
349
{
350
    DECL_TRACER("TPageInterface::calcLineHeight(const string& text, SkFont& font)");
351
 
352
    sk_sp<SkTextBlob> blob = SkTextBlob::MakeFromString(text.c_str(), font);
353
    SkRect rect = blob.get()->bounds();
354
    return rect.height();
355
}
356
 
357
int TPageInterface::numberLines(const string& str)
358
{
359
    DECL_TRACER("TPageInterface::numberLines(const string& str)");
360
 
361
    int lines = 1;
362
 
363
    for (size_t i = 0; i < str.length(); i++)
364
    {
365
        if (str.at(i) == '\n')
366
            lines++;
367
    }
368
 
369
    return lines;
370
}
203 andreas 371
 
372
Button::BUTTONS_T *TPageInterface::addButton(Button::TButton* button)
373
{
374
    DECL_TRACER("*TPageInterface::addButton(TButton* button)");
375
 
376
    if (!button)
377
    {
378
        MSG_ERROR("Parameter is NULL!");
379
        TError::setError();
380
        return nullptr;
381
    }
382
 
383
    try
384
    {
385
        Button::BUTTONS_T *chain = new Button::BUTTONS_T;
386
        chain->button = button;
387
        chain->next = nullptr;
388
        chain->previous = nullptr;
389
        Button::BUTTONS_T *bts = mButtons;
390
 
391
        if (bts)
392
        {
393
            Button::BUTTONS_T *p = bts;
394
 
395
            while (p && p->next)
396
                p = p->next;
397
 
398
            p->next = chain;
399
            chain->previous = p;
400
        }
401
        else
402
            mButtons = chain;
403
 
404
        return chain;
405
    }
406
    catch (std::exception& e)
407
    {
408
        MSG_ERROR("Memory error: " << e.what());
409
        TError::setError();
410
    }
411
 
412
    return nullptr;
413
}
414
 
415
bool TPageInterface::hasButton(int id)
416
{
417
    DECL_TRACER("TPageInterface::hasButton(int id)");
418
 
419
    Button::BUTTONS_T *bt = mButtons;
420
 
421
    while (bt)
422
    {
423
        if (bt->button && bt->button->getButtonIndex() == id)
424
            return true;
425
 
426
        bt = bt->next;
427
    }
428
 
429
    return false;
430
}
431
 
432
Button::TButton *TPageInterface::getButton(int id)
433
{
434
    DECL_TRACER("TPageInterface::getButton(int id)");
435
 
436
    Button::BUTTONS_T *bt = mButtons;
437
 
438
    while (bt)
439
    {
440
        if (bt->button && bt->button->getButtonIndex() == id)
441
            return bt->button;
442
 
443
        bt = bt->next;
444
    }
445
 
446
    return nullptr;
447
}
448
 
449
vector<Button::TButton *> TPageInterface::getButtons(int ap, int ad)
450
{
451
    DECL_TRACER("TPageInterface::getButtons(int ap, int ad)");
452
 
453
    vector<Button::TButton *> list;
454
    Button::BUTTONS_T *bt = mButtons;
455
 
456
    while (bt)
457
    {
458
        if (bt->button->getAddressPort() == ap && bt->button->getAddressChannel() == ad)
459
            list.push_back(bt->button);
460
 
461
        bt = bt->next;
462
    }
463
 
464
    return list;
465
}
466
 
467
vector<Button::TButton *> TPageInterface::getAllButtons()
468
{
469
    DECL_TRACER("TPageInterface::getAllButtons()");
470
 
471
    vector<Button::TButton *> list;
472
    Button::BUTTONS_T *bt = mButtons;
473
 
474
    while(bt)
475
    {
476
        list.push_back(bt->button);
477
        bt = bt->next;
478
    }
479
 
480
    return list;
481
}
482
 
483
Button::TButton *TPageInterface::getFirstButton()
484
{
485
    DECL_TRACER("TPageInterface::getFirstButton()");
486
 
487
    mLastButton = 0;
488
 
489
    if (mButtons)
490
        return mButtons->button;
491
 
492
    return nullptr;
493
}
494
 
495
Button::TButton *TPageInterface::getNextButton()
496
{
497
    DECL_TRACER("TPageInterface::getNextButton()");
498
 
499
    Button::BUTTONS_T *but = mButtons;
500
    int count = 0;
501
    mLastButton++;
502
 
503
    while (but)
504
    {
505
        if (but->button && count == mLastButton)
506
            return but->button;
507
 
508
        but = but->next;
509
        count++;
510
    }
511
 
512
    return nullptr;
513
}
514
 
515
Button::TButton *TPageInterface::getLastButton()
516
{
517
    DECL_TRACER("TPageInterface::getLastButton()");
518
 
519
    Button::BUTTONS_T *but = mButtons;
520
    mLastButton = 0;
521
 
522
    while (but && but->next)
523
    {
524
        mLastButton++;
525
        but = but->next;
526
    }
527
 
528
    if (!but)
529
        return nullptr;
530
 
531
    return but->button;
532
}
533
 
534
Button::TButton *TPageInterface::getPreviousButton()
535
{
536
    DECL_TRACER("TPageInterface::getPreviousButton()");
537
 
538
    Button::BUTTONS_T *but = mButtons;
539
    int count = 0;
540
 
541
    if (mLastButton)
542
        mLastButton--;
543
    else
544
        return nullptr;
545
 
546
    while (but)
547
    {
548
        if (but->button && count == mLastButton)
549
            return but->button;
550
 
551
        but = but->next;
552
        count++;
553
    }
554
 
555
    return nullptr;
556
}
557
 
558
/*
559
 * Sort the button according to their Z-order.
560
 * The button with the highest Z-order will be the last button in the chain.
561
 * The algorithm is a bubble sort algorithm.
562
 */
563
bool TPageInterface::sortButtons()
564
{
565
    DECL_TRACER("TPageInterface::sortButtons()");
566
 
567
    bool turned = true;
568
 
569
    while (turned)
570
    {
571
        Button::BUTTONS_T *button = mButtons;
572
        turned = false;
573
 
574
        while (button)
575
        {
576
            int zo = button->button->getZOrder();
577
 
578
            if (button->previous)
579
            {
580
                if (zo < button->previous->button->getZOrder())
581
                {
582
                    Button::BUTTONS_T *pprev = button->previous->previous;
583
                    Button::BUTTONS_T *prev = button->previous;
584
                    Button::BUTTONS_T *next = button->next;
585
 
586
                    if (pprev)
587
                        pprev->next = button;
588
 
589
                    prev->next = next;
590
                    prev->previous = button;
591
                    button->next = prev;
592
                    button->previous = pprev;
593
 
594
                    if (!pprev)
595
                        setButtons(button);
596
 
597
                    button = next;
598
 
599
                    if (next)
600
                        next->previous = prev;
601
 
602
                    turned = true;
603
                    continue;
604
                }
605
            }
606
 
607
            button = button->next;
608
        }
609
    }
610
 
611
    return true;
612
}
204 andreas 613
 
614
vector<string> TPageInterface::getListContent(ulong handle, int ap, int ta, int ti, int rows, int columns)
615
{
616
    DECL_TRACER("TPageInterface::getListContent(ulong handle, int ap, int ta, int ti, int rows, int columns)");
617
 
618
    if (ap == 0 && ta == 0 && ti == 0)
619
    {
620
        vector<LIST_t>::iterator iter;
621
 
622
        for (iter = mLists.begin(); iter != mLists.end(); ++iter)
623
        {
624
            if (iter->handle == handle)
625
            {
626
                return iter->list;
627
            }
628
        }
629
 
630
        return vector<string>();
631
    }
632
 
206 andreas 633
    if (ap == 0 && (ta == SYSTEM_LIST_SYSTEMSOUND || ta == SYSTEM_LIST_SINGLEBEEP)) // System listbox: system sounds and system single beeps
204 andreas 634
    {
205 andreas 635
        vector<LIST_t>::iterator iter;
204 andreas 636
 
205 andreas 637
        for (iter = mLists.begin(); iter != mLists.end(); ++iter)
204 andreas 638
        {
205 andreas 639
            if (iter->handle == handle)
640
            {
641
                iter->ap = ap;
642
                iter->ta = ta;
643
                iter->ti = ti;
644
                iter->rows = rows;
645
                iter->columns = columns;
204 andreas 646
 
205 andreas 647
                if (iter->selected < 0 && !iter->list.empty())
648
                {
649
                    int row = getSystemSelection(ta, iter->list);
204 andreas 650
 
205 andreas 651
                    if (row > 0)
652
                        iter->selected = row;
653
                }
204 andreas 654
 
205 andreas 655
                return iter->list;
656
            }
204 andreas 657
        }
658
 
205 andreas 659
        TSystemSound sysSound(TConfig::getSystemProjectPath() + "/graphics/sounds");
660
        vector<string> tmpFiles = sysSound.getAllSingleBeep();
661
        LIST_t list;
662
        list.handle = handle;
663
        list.ap = ap;
664
        list.ta = ta;
665
        list.ti = ti;
666
        list.rows = rows;
667
        list.columns = columns;
668
        list.list = tmpFiles;
669
        list.selected = getSystemSelection(ta, tmpFiles);
670
        mLists.push_back(list);
671
        return tmpFiles;
672
    }
206 andreas 673
    else if (ap == 0 && ta == SYSTEM_LIST_DOUBLEBEEP)   // System listbox: double beeps
205 andreas 674
    {
204 andreas 675
        vector<LIST_t>::iterator iter;
676
 
677
        for (iter = mLists.begin(); iter != mLists.end(); ++iter)
678
        {
679
            if (iter->handle == handle)
680
            {
681
                iter->ap = ap;
682
                iter->ta = ta;
683
                iter->ti = ti;
684
                iter->rows = rows;
685
                iter->columns = columns;
205 andreas 686
 
687
                if (iter->selected < 0 && !iter->list.empty())
688
                {
689
                    int row = getSystemSelection(ta, iter->list);
690
 
691
                    if (row > 0)
692
                        iter->selected = row;
693
                }
694
 
695
                return iter->list;
204 andreas 696
            }
697
        }
698
 
205 andreas 699
        TSystemSound sysSound(TConfig::getSystemProjectPath() + "/graphics/sounds");
700
        vector<string> tmpFiles = sysSound.getAllDoubleBeep();
204 andreas 701
        LIST_t list;
702
        list.handle = handle;
703
        list.ap = ap;
704
        list.ta = ta;
705
        list.ti = ti;
706
        list.rows = rows;
707
        list.columns = columns;
708
        list.list = tmpFiles;
205 andreas 709
        list.selected = getSystemSelection(ta, tmpFiles);
204 andreas 710
        mLists.push_back(list);
711
        return tmpFiles;
712
    }
206 andreas 713
    else if (ap == 0 && ta == SYSTEM_LIST_SURFACE)  // System listbox: TP4 file (surface file)
714
    {
715
        vector<LIST_t>::iterator iter;
204 andreas 716
 
206 andreas 717
        for (iter = mLists.begin(); iter != mLists.end(); ++iter)
718
        {
719
            if (iter->handle == handle)
720
            {
721
                iter->ap = ap;
722
                iter->ta = ta;
723
                iter->ti = ti;
724
                iter->rows = rows;
725
                iter->columns = columns;
726
 
727
                if (iter->selected < 0 && !iter->list.empty())
728
                {
729
                    int row = getSystemSelection(ta, iter->list);
730
 
731
                    if (row > 0)
732
                        iter->selected = row;
733
                }
734
 
735
                return iter->list;
736
            }
737
        }
738
 
739
        // Load surface file names from NetLinx over FTP
740
        TTPInit tt;
741
        vector<TTPInit::FILELIST_t> fileList = tt.getFileList(".tp4");
742
        vector<string> tmpFiles;
743
 
744
        if (!fileList.empty())
745
        {
746
            vector<TTPInit::FILELIST_t>::iterator iter;
747
 
748
            if (gPageManager)
749
                gPageManager->clearFtpSurface();
750
 
751
            for (iter = fileList.begin(); iter != fileList.end(); ++iter)
752
            {
753
                tmpFiles.push_back(iter->fname);
754
 
755
                if (gPageManager)
756
                    gPageManager->addFtpSurface(iter->fname, iter->size);
757
            }
758
        }
759
 
760
        LIST_t list;
761
        list.handle = handle;
762
        list.ap = ap;
763
        list.ta = ta;
764
        list.ti = ti;
765
        list.rows = rows;
766
        list.columns = columns;
767
        list.list = tmpFiles;
768
        list.selected = getSystemSelection(ta, tmpFiles);
769
        mLists.push_back(list);
770
        return tmpFiles;
771
    }
772
 
204 andreas 773
    return vector<string>();
774
}
775
 
205 andreas 776
int TPageInterface::getSystemSelection(int ta, vector<string>& list)
777
{
778
    DECL_TRACER("TPageInterface::setSystemSelection(int ta, vector<string>* list)");
779
 
780
    vector<string>::iterator iterSel;
781
    string sel;
782
 
206 andreas 783
    if (ta == SYSTEM_LIST_SURFACE)
784
        sel = TConfig::getFtpSurface();
785
    if (ta == SYSTEM_LIST_SYSTEMSOUND)
205 andreas 786
        sel = TConfig::getSystemSound();
206 andreas 787
    else if (ta == SYSTEM_LIST_SINGLEBEEP)
205 andreas 788
        sel = TConfig::getSingleBeepSound();
206 andreas 789
    else if (ta == SYSTEM_LIST_DOUBLEBEEP)
205 andreas 790
        sel = TConfig::getDoubleBeepSound();
791
    else
792
        return -1;
793
 
794
    int row = 1;
795
 
796
    for (iterSel = list.begin(); iterSel != list.end(); ++iterSel)
797
    {
798
        if (iterSel->compare(sel) == 0)
799
            return row;
800
 
801
        row++;
802
    }
803
 
804
    return -1;
805
}
806
 
204 andreas 807
string TPageInterface::getListRow(int ti, int row)
808
{
809
    DECL_TRACER("TPageInterface::getListRow(ulong handle, int ti, int row)");
810
 
811
    vector<LIST_t>::iterator iter;
812
 
813
    for (iter = mLists.begin(); iter != mLists.end(); ++iter)
814
    {
815
        if (iter->ti == ti)
816
        {
817
            if (row < 1 || (size_t)row > iter->list.size())
818
                return string();
819
 
820
            return iter->list[row-1];
821
        }
822
    }
823
 
824
    return string();
825
}
826
 
827
void TPageInterface::setGlobalSettings(Button::TButton* button)
828
{
829
    DECL_TRACER("TPageInterface::setGlobalSettings(TButton* button)");
830
 
831
    if (!button)
832
        return;
833
 
205 andreas 834
    button->setFontOnly(sr[0].fi, 0);
835
    button->setTextColorOnly(sr[0].ct, 0);
836
    button->setTextEffectColorOnly(sr[0].ec, 0);
204 andreas 837
 
206 andreas 838
    if (button->getListAp() == 0 && button->getListTi() >= SYSTEM_PAGE_START)
205 andreas 839
        button->setTextJustificationOnly(4, 0, 0, 0);
204 andreas 840
}
205 andreas 841
 
842
void TPageInterface::setSelectedRow(ulong handle, int row)
843
{
844
    DECL_TRACER("TPageInterface::setSelectedRow(ulong handle, int row)");
845
 
846
    if (row < 1)
847
        return;
848
 
849
    vector<LIST_t>::iterator iter;
850
 
851
    for (iter = mLists.begin(); iter != mLists.end(); ++iter)
852
    {
853
        if (iter->handle == handle)
854
        {
855
            if ((size_t)row <= iter->list.size())
856
                iter->selected = row;
857
 
206 andreas 858
            MSG_DEBUG("Row was set to " << row << " for item " << TObject::handleToString(handle));
205 andreas 859
            return;
860
        }
861
    }
862
}
863
 
864
int TPageInterface::getSelectedRow(ulong handle)
865
{
866
    DECL_TRACER("TPageInterface::getSelectedRow(ulong handle)");
867
 
868
    vector<LIST_t>::iterator iter;
869
 
870
    for (iter = mLists.begin(); iter != mLists.end(); ++iter)
871
    {
872
        if (iter->handle == handle)
873
            return iter->selected;
874
    }
875
 
876
    return -1;
877
}
878
 
879
string TPageInterface::getSelectedItem(ulong handle)
880
{
881
    DECL_TRACER("TPageInterface::getSelectedItem(ulong handle)");
882
 
883
    vector<LIST_t>::iterator iter;
884
 
885
    for (iter = mLists.begin(); iter != mLists.end(); ++iter)
886
    {
887
        if (iter->handle == handle)
888
        {
889
            if (iter->selected > 0 && (size_t)iter->selected <= iter->list.size())
890
                return iter->list[iter->selected-1];
891
 
892
            ulong nPage = (handle >> 16) & 0x0000ffff;
893
            ulong nButt = handle & 0x0000ffff;
894
            string sel;
895
 
206 andreas 896
            if (nPage == SYSTEM_SUBPAGE_SURFACE && nButt == 1)
897
                sel = TConfig::getFtpSurface();
898
            if (nPage == SYSTEM_SUBPAGE_SYSTEMSOUND && nButt == 1)
205 andreas 899
                sel = TConfig::getSystemSound();
206 andreas 900
            else if (nPage == SYSTEM_SUBPAGE_SINGLEBEEP && nButt == 1)
205 andreas 901
                sel = TConfig::getSingleBeepSound();
206 andreas 902
            else if (nPage == SYSTEM_SUBPAGE_DOUBLEBEEP && nButt == 1)
205 andreas 903
                sel = TConfig::getDoubleBeepSound();
904
            else
905
                return string();
906
 
907
            if (iter->list.empty())
908
                return string();
909
 
910
            vector<string>::iterator iterSel;
911
            int row = 1;
912
 
913
            for (iterSel = iter->list.begin(); iterSel != iter->list.end(); ++iterSel)
914
            {
915
                if (iterSel->compare(sel) == 0)
916
                {
917
                    iter->selected = row;
918
                    return sel;
919
                }
920
 
921
                row++;
922
            }
923
        }
924
    }
925
 
926
    return string();
927
}