Subversion Repositories tpanel

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 andreas 1
/*
258 andreas 2
 * Copyright (C) 2020 to 2023 by Andreas Theofilu <andreas@theosys.at>
2 andreas 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 <sys/types.h>
20
#include <sys/stat.h>
21
#include <unistd.h>
55 andreas 22
 
23
#include <include/core/SkFont.h>
24
#include <include/core/SkFontMetrics.h>
25
#include <include/core/SkTextBlob.h>
26
 
5 andreas 27
#include "tresources.h"
26 andreas 28
#include "tpagemanager.h"
2 andreas 29
#include "tpage.h"
66 andreas 30
#include "tdrawimage.h"
76 andreas 31
#include "texpat++.h"
211 andreas 32
#include "tconfig.h"
303 andreas 33
#include "terror.h"
343 andreas 34
#if TESTMODE == 1
35
#include "testmode.h"
36
#endif
2 andreas 37
 
186 andreas 38
#if __cplusplus < 201402L
39
#   error "This module requires at least C++14 standard!"
40
#else
41
#   if __cplusplus < 201703L
42
#       include <experimental/filesystem>
43
namespace fs = std::experimental::filesystem;
44
#       warning "Support for C++14 and experimental filesystem will be removed in a future version!"
45
#   else
46
#       include <filesystem>
47
#       ifdef __ANDROID__
48
namespace fs = std::__fs::filesystem;
49
#       else
50
namespace fs = std::filesystem;
51
#       endif
52
#   endif
53
#endif
54
 
3 andreas 55
using std::string;
55 andreas 56
using std::vector;
151 andreas 57
using std::map;
58
using std::pair;
3 andreas 59
using namespace Button;
76 andreas 60
using namespace Expat;
3 andreas 61
 
26 andreas 62
extern TPageManager *gPageManager;
63
 
3 andreas 64
TPage::TPage(const string& name)
2 andreas 65
{
3 andreas 66
    DECL_TRACER("TPage::TPage(const string& name)");
14 andreas 67
    TError::clear();
38 andreas 68
 
69
    if (gPageManager)
70
    {
71
        if (!_setBackground)
72
            _setBackground = gPageManager->getCallbackBG();
73
 
74
        if (!_displayButton)
75
            _displayButton = gPageManager->getCallbackDB();
76
 
77
        if (!_callDropPage)
78
            _callDropPage = gPageManager->getCallDropPage();
79
 
80
        if (!_callDropSubPage)
81
            _callDropSubPage = gPageManager->getCallDropSubPage();
82
 
83
        if (!_playVideo)
84
            _playVideo = gPageManager->getCallbackPV();
85
    }
86
 
43 andreas 87
    if (name.compare("_progress") == 0)
88
    {
89
        addProgress();
90
        return ;
91
    }
92
 
3 andreas 93
    initialize(name);
94
}
2 andreas 95
 
3 andreas 96
TPage::~TPage()
97
{
5 andreas 98
    DECL_TRACER("TPage::~TPage()");
99
 
201 andreas 100
    MSG_DEBUG("Destroing page " << mPage.pageID << ": " << mPage.name);
101
    BUTTONS_T *p = getButtons();
3 andreas 102
    BUTTONS_T *next = nullptr;
2 andreas 103
 
3 andreas 104
    while (p)
105
    {
106
        next = p->next;
107
        delete p->button;
108
        delete p;
109
        p = next;
110
    }
2 andreas 111
 
201 andreas 112
    setButtons(nullptr);
349 andreas 113
    mSubPages.clear();
114
/*
3 andreas 115
    PAGECHAIN_T *pc = mSubPages;
116
    PAGECHAIN_T *pc_next = nullptr;
117
 
118
    // We're not allowd to delete the subpages here, because they're managed
119
    // by the TPageManager.
120
    while (pc)
121
    {
122
        pc_next = pc->next;
123
        delete pc;
124
        pc = pc_next;
125
    }
126
 
127
    mSubPages = nullptr;
349 andreas 128
*/
3 andreas 129
}
130
 
131
void TPage::initialize(const string& nm)
132
{
133
    DECL_TRACER("TPage::initialize(const string& name)");
134
 
197 andreas 135
    string projectPath = ((gPageManager && gPageManager->isSetupActive()) ? TConfig::getSystemProjectPath() : TConfig::getProjectPath());
186 andreas 136
 
137
    if (!fs::exists(projectPath + "/prj.xma"))
197 andreas 138
    {
139
        MSG_ERROR("Directory " << projectPath << " doesn't exist!");
140
        return;
141
    }
186 andreas 142
 
143
    makeFileName(projectPath, nm);
144
 
194 andreas 145
    MSG_DEBUG("Using path: " << projectPath << " and file: " << nm);
146
 
3 andreas 147
    if (isValidFile())
148
        mPath = getFileName();
149
 
76 andreas 150
    TExpat xml(mPath);
151
    xml.setEncoding(ENC_CP1250);
3 andreas 152
 
76 andreas 153
    if (!xml.parse())
3 andreas 154
        return;
155
 
76 andreas 156
    int depth = 0;
157
    size_t index = 0;
158
    size_t oldIndex = 0;
159
    vector<ATTRIBUTE_t> attrs;
3 andreas 160
 
76 andreas 161
    if ((index = xml.getElementIndex("page", &depth)) == TExpat::npos)
3 andreas 162
    {
163
        MSG_ERROR("Element \"page\" with attribute \"type\" was not found!");
164
        TError::setError();
165
        return;
166
    }
167
 
76 andreas 168
    attrs = xml.getAttributes();
169
    string type = xml.getAttribute("type", attrs);
3 andreas 170
 
171
    if (type.compare("page") != 0)
172
    {
173
        MSG_ERROR("Invalid page type \"" << type << "\"!");
174
        TError::setError();
175
        return;
176
    }
177
 
76 andreas 178
    depth++;
179
    string ename, content;
3 andreas 180
 
76 andreas 181
    while ((index = xml.getNextElementFromIndex(index, &ename, &content, &attrs)) != TExpat::npos)
3 andreas 182
    {
76 andreas 183
        string e = ename;
3 andreas 184
 
185
        if (e.compare("pageID") == 0)
201 andreas 186
            mPage.pageID = xml.convertElementToInt(content);
3 andreas 187
        else if (e.compare("name") == 0)
201 andreas 188
            mPage.name = content;
3 andreas 189
        else if (e.compare("width") == 0)
201 andreas 190
            mPage.width = xml.convertElementToInt(content);
3 andreas 191
        else if (e.compare("height") == 0)
201 andreas 192
            mPage.height = xml.convertElementToInt(content);
3 andreas 193
        else if (e.compare("button") == 0)
194
        {
195
            TButton *button = new TButton();
204 andreas 196
            TPageInterface::registerListCallback<TPage>(button, this);
198 andreas 197
 
4 andreas 198
            button->setPalette(mPalette);
201 andreas 199
            button->setFonts(getFonts());
7 andreas 200
            button->registerCallback(_displayButton);
21 andreas 201
            button->regCallPlayVideo(_playVideo);
76 andreas 202
            index = button->initialize(&xml, index);
201 andreas 203
            button->setParentSize(mPage.width, mPage.height);
3 andreas 204
 
205
            if (TError::isError())
206
            {
23 andreas 207
                MSG_WARNING("Button \"" << button->getButtonName() << "\" deleted because of an error!");
3 andreas 208
                delete button;
209
                return;
210
            }
211
 
201 andreas 212
            button->setHandle(((mPage.pageID << 16) & 0xffff0000) | button->getButtonIndex());
14 andreas 213
            button->createButtons();
3 andreas 214
            addButton(button);
76 andreas 215
            index++;        // Jump over the end tag of the button.
3 andreas 216
        }
217
        else if (e.compare("sr") == 0)
218
        {
219
            SR_T bsr;
76 andreas 220
            bsr.number = xml.getAttributeInt("number", attrs);
221
            index++;
3 andreas 222
 
76 andreas 223
            while ((index = xml.getNextElementFromIndex(index, &ename, &content, &attrs)) != TExpat::npos)
3 andreas 224
            {
225
                if (ename.compare("bs") == 0)
76 andreas 226
                    bsr.bs = content;
3 andreas 227
                else if (ename.compare("cb") == 0)
76 andreas 228
                    bsr.cb = content;
3 andreas 229
                else if (ename.compare("cf") == 0)
76 andreas 230
                    bsr.cf = content;
3 andreas 231
                else if (ename.compare("ct") == 0)
76 andreas 232
                    bsr.ct = content;
3 andreas 233
                else if (ename.compare("ec") == 0)
76 andreas 234
                    bsr.ec = content;
3 andreas 235
                else if (ename.compare("bm") == 0)
76 andreas 236
                    bsr.bm = content;
65 andreas 237
                else if (ename.compare("mi") == 0)
76 andreas 238
                    bsr.mi = content;
3 andreas 239
                else if (ename.compare("fi") == 0)
76 andreas 240
                    bsr.fi = xml.convertElementToInt(content);
55 andreas 241
                else if (ename.compare("te") == 0)
76 andreas 242
                    bsr.te = content;
55 andreas 243
                else if (ename.compare("tx") == 0)
76 andreas 244
                    bsr.tx = xml.convertElementToInt(content);
55 andreas 245
                else if (ename.compare("ty") == 0)
76 andreas 246
                    bsr.ty = xml.convertElementToInt(content);
55 andreas 247
                else if (ename.compare("et") == 0)
76 andreas 248
                    bsr.et = xml.convertElementToInt(content);
55 andreas 249
                else if (ename.compare("ww") == 0)
76 andreas 250
                    bsr.ww = xml.convertElementToInt(content);
55 andreas 251
                else if (ename.compare("jt") == 0)
76 andreas 252
                    bsr.jt = (Button::TEXT_ORIENTATION)xml.convertElementToInt(content);
65 andreas 253
                else if (ename.compare("jb") == 0)
76 andreas 254
                    bsr.jb = (Button::TEXT_ORIENTATION)xml.convertElementToInt(content);
3 andreas 255
 
76 andreas 256
                oldIndex = index;
3 andreas 257
            }
258
 
259
            sr.push_back(bsr);
76 andreas 260
 
261
            if (index == TExpat::npos)
262
                index = oldIndex + 1;
3 andreas 263
        }
76 andreas 264
    }
3 andreas 265
 
204 andreas 266
    setSR(sr);
349 andreas 267
/*
76 andreas 268
    if (TStreamError::checkFilter(HLOG_DEBUG))
269
    {
201 andreas 270
        MSG_DEBUG("PageID: " << mPage.pageID);
271
        MSG_DEBUG("Name  : " << mPage.name);
272
        MSG_DEBUG("Width : " << mPage.width);
273
        MSG_DEBUG("Height: " << mPage.height);
76 andreas 274
 
275
        vector<SR_T>::iterator iter;
276
        size_t pos = 1;
277
 
278
        for (iter = sr.begin(); iter != sr.end(); ++iter)
279
        {
280
            MSG_DEBUG("   " << pos << ": bs: " << iter->bs);
281
            MSG_DEBUG("   " << pos << ": cb: " << iter->cb);
282
            MSG_DEBUG("   " << pos << ": cf: " << iter->cf);
283
            MSG_DEBUG("   " << pos << ": ct: " << iter->ct);
284
            MSG_DEBUG("   " << pos << ": ec: " << iter->ec);
285
            MSG_DEBUG("   " << pos << ": bm: " << iter->bm);
286
            MSG_DEBUG("   " << pos << ": mi: " << iter->mi);
287
            MSG_DEBUG("   " << pos << ": fi: " << iter->fi);
288
            pos++;
289
        }
3 andreas 290
    }
349 andreas 291
*/
203 andreas 292
    if (TPageInterface::getButtons())
76 andreas 293
        sortButtons();
3 andreas 294
}
199 andreas 295
 
43 andreas 296
void TPage::addProgress()
297
{
298
    DECL_TRACER("TPage::addProgress()");
299
 
300
    if (!gPageManager)
301
    {
302
        MSG_WARNING("The page manager is still not initialized!");
303
        return;
304
    }
305
 
306
    Button::SR_T bsr;
201 andreas 307
    mPage.pageID = 300;
308
    mPage.name = "_progress";
217 andreas 309
    mPage.width = gPageManager->getSettings()->getWidth();
201 andreas 310
    mPage.height = gPageManager->getSettings()->getHeight();
311
    double unit = (double)mPage.height / 10.0;
43 andreas 312
    MSG_DEBUG("One unit is " << unit);
313
    // Background of page
314
    bsr.number = 1;
315
    bsr.cf = "#106010ff";
316
    bsr.ct = "#ffffffff";
317
    bsr.cb = "#009000ff";
318
    bsr.ec = "#ffffffff";
319
    bsr.fi = 21;
320
    sr.push_back(bsr);
321
    // Text field 1 to show status messages
322
    Button::EXTBUTTON_t bt;
195 andreas 323
    bt.type = GENERAL;
43 andreas 324
    bt.bi = 1;
325
    bt.na = "Line1";
326
    bt.tp = (int)(unit * 2.0);
201 andreas 327
    bt.lt = (int)(((double)mPage.width - ((double)mPage.width / 100.0 * 80.0)) / 2.0);
328
    bt.wt = (int)((double)mPage.width / 100.0 * 80.0);    // Line take 80% of available width
43 andreas 329
    bt.ht = (int)(unit / 100.0 * 80.0);
330
    MSG_DEBUG("Dimensions button 1: lt: " << bt.lt << ", tp: " << bt.tp << ", wt: " << bt.wt << ", ht: " << bt.ht);
331
    bt.zo = 1;
332
    bt.ap = 0;
333
    bt.ad = 160;
334
    bsr.cf = "#000000ff";
335
    bt.sr.push_back(bsr);
336
    bsr.number = 2;
337
    bt.sr.push_back(bsr);
338
    TButton *button = new TButton();
339
    button->setPalette(mPalette);
201 andreas 340
    button->setFonts(getFonts());
43 andreas 341
    button->registerCallback(_displayButton);
342
    button->regCallPlayVideo(_playVideo);
343
    button->createSoftButton(bt);
201 andreas 344
    button->setParentSize(mPage.width, mPage.height);
43 andreas 345
 
346
    if (TError::isError())
347
    {
348
        MSG_WARNING("Button \"" << button->getButtonName() << "\" deleted because of an error!");
349
        delete button;
350
        return;
351
    }
352
 
201 andreas 353
    button->setHandle(((mPage.pageID << 16) & 0xffff0000) | bt.bi);
43 andreas 354
    button->createButtons();
355
    addButton(button);
356
    // Text field 2 to show status messages
357
    bt.bi = 2;
358
    bt.na = "Line2";
359
    bt.tp = (int)(unit * 7.0);
360
    MSG_DEBUG("Dimensions button 2: lt: " << bt.lt << ", tp: " << bt.tp << ", wt: " << bt.wt << ", ht: " << bt.ht);
361
    bt.zo = 2;
362
    bt.ad = 161;
363
    button = new TButton();
364
    button->setPalette(mPalette);
201 andreas 365
    button->setFonts(getFonts());
43 andreas 366
    button->registerCallback(_displayButton);
367
    button->regCallPlayVideo(_playVideo);
368
    button->createSoftButton(bt);
201 andreas 369
    button->setParentSize(mPage.width, mPage.height);
43 andreas 370
 
371
    if (TError::isError())
372
    {
373
        MSG_WARNING("Button \"" << button->getButtonName() << "\" deleted because of an error!");
374
        delete button;
375
        return;
376
    }
377
 
201 andreas 378
    button->setHandle(((mPage.pageID << 16) & 0xffff0000) | bt.bi);
43 andreas 379
    button->createButtons();
380
    addButton(button);
381
    // Progress bar 1 (overall status)
195 andreas 382
    bt.type = BARGRAPH;
43 andreas 383
    bt.bi = 3;
384
    bt.na = "Bar1";
385
    bt.tp = (int)(unit * 3.0);
201 andreas 386
    bt.lt = (int)(((double)mPage.width - ((double)mPage.width / 100.0 * 80.0)) / 2.0);
387
    bt.wt = (int)((double)mPage.width / 100.0 * 80.0);    // Line take 80% of available width
43 andreas 388
    bt.ht = (int)unit;
389
    MSG_DEBUG("Dimensions bargraph 1: lt: " << bt.lt << ", tp: " << bt.tp << ", wt: " << bt.wt << ", ht: " << bt.ht);
390
    bt.zo = 3;
391
    bt.ap = 0;
392
    bt.ad = 162;
393
    bt.lp = 0;
394
    bt.lv = 162;
395
    bt.rl = 1;
396
    bt.rh = 100;
397
    bt.sc = "#ffffffff";
398
    bt.dr = "horizontal";
399
    bsr.number = 1;
400
    bsr.cf = "#0e0e0eff";
401
    bsr.ct = "#ffffffff";
402
    bsr.cb = "#009000ff";
403
    bt.sr.clear();
404
    bt.sr.push_back(bsr);
405
    bsr.number = 2;
406
    bsr.cf = "#ffffffff";
407
    bt.sr.push_back(bsr);
408
    button = new TButton();
409
    button->setPalette(mPalette);
201 andreas 410
    button->setFonts(getFonts());
43 andreas 411
    button->registerCallback(_displayButton);
412
    button->regCallPlayVideo(_playVideo);
413
    button->createSoftButton(bt);
201 andreas 414
    button->setParentSize(mPage.width, mPage.height);
43 andreas 415
 
416
    if (TError::isError())
417
    {
418
        MSG_WARNING("Button \"" << button->getButtonName() << "\" deleted because of an error!");
419
        delete button;
420
        return;
421
    }
422
 
203 andreas 423
    button->setHandle(((mPage.pageID << 16) & 0xffff0000) | bt.bi);
43 andreas 424
    button->createButtons();
425
    addButton(button);
426
    // Progress bar 2 (details)
427
    bt.bi = 4;
428
    bt.na = "Bar2";
429
    bt.tp = (int)(unit * 5.0);
430
    MSG_DEBUG("Dimensions bargraph 2: lt: " << bt.lt << ", tp: " << bt.tp << ", wt: " << bt.wt << ", ht: " << bt.ht);
431
    bt.zo = 4;
432
    bt.ad = 163;
433
    bt.lv = 163;
434
    button = new TButton();
435
    button->setPalette(mPalette);
201 andreas 436
    button->setFonts(getFonts());
43 andreas 437
    button->registerCallback(_displayButton);
438
    button->regCallPlayVideo(_playVideo);
439
    button->createSoftButton(bt);
201 andreas 440
    button->setParentSize(mPage.width, mPage.height);
43 andreas 441
 
442
    if (TError::isError())
443
    {
444
        MSG_WARNING("Button \"" << button->getButtonName() << "\" deleted because of an error!");
445
        delete button;
446
        return;
447
    }
448
 
201 andreas 449
    button->setHandle(((mPage.pageID << 16) & 0xffff0000) | bt.bi);
43 andreas 450
    button->createButtons();
451
    addButton(button);
452
}
453
 
300 andreas 454
SkBitmap& TPage::getBgImage()
455
{
456
    DECL_TRACER("TPage::getBgImage()");
457
 
458
    if (!mBgImage.empty())
459
        return mBgImage;
460
 
461
    bool haveImage = false;
462
    MSG_DEBUG("Creating image for page " << mPage.pageID << ": " << mPage.name);
463
    SkBitmap target;
464
 
465
    if (!allocPixels(mPage.width, mPage.height, &target))
466
        return mBgImage;
467
 
468
    target.eraseColor(TColor::getSkiaColor(mPage.sr[0].cf));
469
    // Draw the background, if any
470
    if (mPage.sr.size() > 0 && (!mPage.sr[0].bm.empty() || !mPage.sr[0].mi.empty()))
471
    {
472
        TDrawImage dImage;
473
        dImage.setWidth(mPage.width);
474
        dImage.setHeight(mPage.height);
475
 
476
        if (!mPage.sr[0].bm.empty())
477
        {
478
            MSG_DEBUG("Loading image " << mPage.sr[0].bm);
479
            sk_sp<SkData> rawImage = readImage(mPage.sr[0].bm);
480
            SkBitmap bm;
481
 
482
            if (rawImage)
483
            {
484
                MSG_DEBUG("Decoding image BM ...");
485
 
486
                if (!DecodeDataToBitmap(rawImage, &bm))
487
                {
488
                    MSG_WARNING("Problem while decoding image " << mPage.sr[0].bm);
489
                }
490
                else if (!bm.empty())
491
                {
492
                    dImage.setImageBm(bm);
493
                    SkImageInfo info = bm.info();
494
                    mPage.sr[0].bm_width = info.width();
495
                    mPage.sr[0].bm_height = info.height();
496
                    haveImage = true;
497
                }
498
                else
499
                {
500
                    MSG_WARNING("BM image " << mPage.sr[0].bm << " seems to be empty!");
501
                }
502
            }
503
        }
504
 
505
        if (!mPage.sr[0].mi.empty())
506
        {
507
            MSG_DEBUG("Loading image " << mPage.sr[0].mi);
508
            sk_sp<SkData> rawImage = readImage(mPage.sr[0].mi);
509
            SkBitmap mi;
510
 
511
            if (rawImage)
512
            {
513
                MSG_DEBUG("Decoding image MI ...");
514
 
515
                if (!DecodeDataToBitmap(rawImage, &mi))
516
                {
517
                    MSG_WARNING("Problem while decoding image " << mPage.sr[0].mi);
518
                }
519
                else if (!mi.empty())
520
                {
521
                    dImage.setImageMi(mi);
522
                    SkImageInfo info = mi.info();
523
                    mPage.sr[0].mi_width = info.width();
524
                    mPage.sr[0].mi_height = info.height();
525
                    haveImage = true;
526
                }
527
                else
528
                {
529
                    MSG_WARNING("MI image " << mPage.sr[0].mi << " seems to be empty!");
530
                }
531
            }
532
        }
533
 
534
        if (haveImage)
535
        {
536
            dImage.setSr(mPage.sr);
537
 
538
            if (!dImage.drawImage(&target))
539
                return mBgImage;
540
 
541
            if (!mPage.sr[0].te.empty())
542
            {
543
                if (!drawText(mPage, &target))
544
                    return mBgImage;
545
            }
546
 
547
            if (mPage.sr[0].oo < 255 && mPage.sr[0].te.empty() && mPage.sr[0].bs.empty())
548
                setOpacity(&target, mPage.sr[0].oo);
549
 
550
#ifdef _SCALE_SKIA_
551
            size_t rowBytes = info.minRowBytes();
552
            size_t size = info.computeByteSize(rowBytes);
553
            SkImageInfo info = target.info();
554
 
555
            if (gPageManager && gPageManager->getScaleFactor() != 1.0)
556
            {
557
                SkPaint paint;
558
                int left, top;
559
 
560
                paint.setBlendMode(SkBlendMode::kSrc);
561
                paint.setFilterQuality(kHigh_SkFilterQuality);
562
                // Calculate new dimension
563
                double scaleFactor = gPageManager->getScaleFactor();
564
                MSG_DEBUG("Using scale factor " << scaleFactor);
565
                int lwidth = (int)((double)info.width() * scaleFactor);
566
                int lheight = (int)((double)info.height() * scaleFactor);
567
                int twidth = (int)((double)mPage.width * scaleFactor);
568
                int theight = (int)((double)mPage.height * scaleFactor);
569
                calcPosition(lwidth, lheight, &left, &top);
570
                // Create a canvas and draw new image
571
                sk_sp<SkImage> im = SkImage::MakeFromBitmap(target);
572
 
573
                if (!allocPixels(twidth, theight, &target))
574
                    return;
575
 
576
                target.eraseColor(TColor::getSkiaColor(mPage.sr[0].cf));
577
                SkCanvas can(target, SkSurfaceProps());
578
                SkRect rect = SkRect::MakeXYWH(left, top, lwidth, lheight);
579
                can.drawImageRect(im, rect, &paint);
580
                MSG_DEBUG("Scaled size of background image: " << left << ", " << top << ", " << lwidth << ", " << lheight);
581
            }
582
#endif
583
        }
584
    }
585
 
586
    if (mPage.sr.size() > 0 && !mPage.sr[0].te.empty())
587
    {
588
        MSG_DEBUG("Drawing a text only on background image ...");
589
 
590
        if (drawText(mPage, &target))
591
            haveImage = true;
592
    }
593
 
594
    // Check for a frame and draw it if there is one.
595
    if (!mPage.sr[0].bs.empty())
596
    {
597
        if (drawFrame(mPage, &target))
598
            haveImage = true;
599
    }
600
 
601
    if (haveImage)
602
    {
603
        if (mPage.sr[0].oo < 255)
604
            setOpacity(&target, mPage.sr[0].oo);
605
 
606
        mBgImage = target;
607
    }
608
 
609
    return mBgImage;
610
}
611
 
5 andreas 612
void TPage::show()
613
{
614
    DECL_TRACER("TPage::show()");
615
 
616
    if (!_setBackground)
617
    {
31 andreas 618
        if (gPageManager && gPageManager->getCallbackBG())
619
            _setBackground = gPageManager->getCallbackBG();
620
        else
621
        {
622
            MSG_WARNING("No callback \"setBackground\" was set!");
343 andreas 623
#if TESTMODE == 1
624
            setScreenDone();
625
#endif
31 andreas 626
            return;
627
        }
5 andreas 628
    }
629
 
217 andreas 630
    bool haveImage = false;
201 andreas 631
    ulong handle = (mPage.pageID << 16) & 0xffff0000;
632
    MSG_DEBUG("Processing page " << mPage.pageID);
66 andreas 633
    SkBitmap target;
254 andreas 634
 
635
    if (!allocPixels(mPage.width, mPage.height, &target))
343 andreas 636
    {
637
#if TESTMODE == 1
638
        setScreenDone();
639
#endif
254 andreas 640
        return;
343 andreas 641
    }
254 andreas 642
 
66 andreas 643
    target.eraseColor(TColor::getSkiaColor(sr[0].cf));
644
    // Draw the background, if any
645
    if (sr.size() > 0 && (!sr[0].bm.empty() || !sr[0].mi.empty()))
5 andreas 646
    {
66 andreas 647
        TDrawImage dImage;
201 andreas 648
        dImage.setWidth(mPage.width);
649
        dImage.setHeight(mPage.height);
5 andreas 650
 
66 andreas 651
        if (!sr[0].bm.empty())
5 andreas 652
        {
66 andreas 653
            MSG_DEBUG("Loading image " << sr[0].bm);
654
            sk_sp<SkData> rawImage = readImage(sr[0].bm);
5 andreas 655
            SkBitmap bm;
28 andreas 656
 
66 andreas 657
            if (rawImage)
658
            {
659
                MSG_DEBUG("Decoding image BM ...");
55 andreas 660
 
66 andreas 661
                if (!DecodeDataToBitmap(rawImage, &bm))
662
                {
663
                    MSG_WARNING("Problem while decoding image " << sr[0].bm);
664
                }
665
                else if (!bm.empty())
666
                {
667
                    dImage.setImageBm(bm);
668
                    SkImageInfo info = bm.info();
669
                    sr[0].bm_width = info.width();
670
                    sr[0].bm_height = info.height();
671
                    haveImage = true;
672
                }
673
                else
674
                {
675
                    MSG_WARNING("BM image " << sr[0].bm << " seems to be empty!");
676
                }
677
            }
678
        }
679
 
680
        if (!sr[0].mi.empty())
681
        {
682
            MSG_DEBUG("Loading image " << sr[0].mi);
683
            sk_sp<SkData> rawImage = readImage(sr[0].mi);
684
            SkBitmap mi;
685
 
686
            if (rawImage)
687
            {
688
                MSG_DEBUG("Decoding image MI ...");
689
 
690
                if (!DecodeDataToBitmap(rawImage, &mi))
691
                {
692
                    MSG_WARNING("Problem while decoding image " << sr[0].mi);
693
                }
694
                else if (!mi.empty())
695
                {
696
                    dImage.setImageMi(mi);
697
                    SkImageInfo info = mi.info();
698
                    sr[0].mi_width = info.width();
699
                    sr[0].mi_height = info.height();
700
                    haveImage = true;
701
                }
702
                else
703
                {
704
                    MSG_WARNING("MI image " << sr[0].mi << " seems to be empty!");
705
                }
706
            }
707
        }
708
 
709
        if (haveImage)
710
        {
711
            dImage.setSr(sr);
712
 
713
            if (!dImage.drawImage(&target))
343 andreas 714
            {
715
#if TESTMODE == 1
716
                setScreenDone();
717
#endif
66 andreas 718
                return;
343 andreas 719
            }
66 andreas 720
 
55 andreas 721
            if (!sr[0].te.empty())
722
            {
201 andreas 723
                if (!drawText(mPage, &target))
343 andreas 724
                {
725
#if TESTMODE == 1
726
                    setScreenDone();
727
#endif
55 andreas 728
                    return;
343 andreas 729
                }
55 andreas 730
            }
66 andreas 731
 
43 andreas 732
#ifdef _SCALE_SKIA_
26 andreas 733
            if (gPageManager && gPageManager->getScaleFactor() != 1.0)
734
            {
66 andreas 735
                SkPaint paint;
736
                int left, top;
289 andreas 737
                SkImageInfo info = target.info();
66 andreas 738
 
739
                paint.setBlendMode(SkBlendMode::kSrc);
26 andreas 740
                paint.setFilterQuality(kHigh_SkFilterQuality);
28 andreas 741
                // Calculate new dimension
31 andreas 742
                double scaleFactor = gPageManager->getScaleFactor();
743
                MSG_DEBUG("Using scale factor " << scaleFactor);
744
                int lwidth = (int)((double)info.width() * scaleFactor);
745
                int lheight = (int)((double)info.height() * scaleFactor);
746
                int twidth = (int)((double)width * scaleFactor);
747
                int theight = (int)((double)height * scaleFactor);
66 andreas 748
                calcPosition(lwidth, lheight, &left, &top);
28 andreas 749
                // Create a canvas and draw new image
66 andreas 750
                sk_sp<SkImage> im = SkImage::MakeFromBitmap(target);
254 andreas 751
 
752
                if (!allocPixels(twidth, theight, &target))
343 andreas 753
                {
754
#if TESTMODE == 1
755
                    setScreenDone();
756
#endif
254 andreas 757
                    return;
343 andreas 758
                }
254 andreas 759
 
66 andreas 760
                target.eraseColor(TColor::getSkiaColor(sr[0].cf));
254 andreas 761
                SkCanvas can(target, SkSurfaceProps());
66 andreas 762
                SkRect rect = SkRect::MakeXYWH(left, top, lwidth, lheight);
763
                can.drawImageRect(im, rect, &paint);
764
                MSG_DEBUG("Scaled size of background image: " << left << ", " << top << ", " << lwidth << ", " << lheight);
26 andreas 765
            }
43 andreas 766
#endif
277 andreas 767
/*
289 andreas 768
            TBitmap image((unsigned char *)target.getPixels(), target.info().width(), target.info().height());
262 andreas 769
#ifdef _OPAQUE_SKIA_
258 andreas 770
            if (sr[0].te.empty() && sr[0].bs.empty())
289 andreas 771
                _setBackground(handle, image, target.info().width(), target.info().height(), TColor::getColor(sr[0].cf));
262 andreas 772
#else
773
            if (sr[0].te.empty() && sr[0].bs.empty())
289 andreas 774
                _setBackground(handle, image, target.info().width(), target.info().height(), TColor::getColor(sr[0].cf), sr[0].oo);
262 andreas 775
#endif
277 andreas 776
*/
5 andreas 777
        }
778
    }
66 andreas 779
 
780
    if (sr.size() > 0 && !sr[0].te.empty())
55 andreas 781
    {
66 andreas 782
        MSG_DEBUG("Drawing text on background image ...");
55 andreas 783
 
258 andreas 784
        if (drawText(mPage, &target))
785
            haveImage = true;
786
    }
55 andreas 787
 
258 andreas 788
    // Check for a frame and draw it if there is one.
789
    if (!sr[0].bs.empty())
790
    {
791
        if (drawFrame(mPage, &target))
792
            haveImage = true;
793
    }
794
 
795
    if (haveImage)
796
    {
66 andreas 797
        SkImageInfo info = target.info();
289 andreas 798
        TBitmap image((unsigned char *)target.getPixels(), info.width(), info.height());
262 andreas 799
#ifdef _OPAQUE_SKIA_
289 andreas 800
        _setBackground(handle, image, target.info().width(), target.info().height(), TColor::getColor(sr[0].cf));
262 andreas 801
#else
289 andreas 802
        _setBackground(handle, image, target.info().width(), target.info().height(), TColor::getColor(sr[0].cf), sr[0].oo);
262 andreas 803
#endif
55 andreas 804
    }
258 andreas 805
    else if (sr.size() > 0 && !haveImage)
5 andreas 806
    {
26 andreas 807
        MSG_DEBUG("Calling \"setBackground\" with no image ...");
262 andreas 808
#ifdef _OPAQUE_SKIA_
289 andreas 809
        _setBackground(handle, TBitmap(), 0, 0, TColor::getColor(sr[0].cf));
262 andreas 810
#else
289 andreas 811
        _setBackground(handle, TBitmap(), 0, 0, TColor::getColor(sr[0].cf), sr[0].oo);
262 andreas 812
#endif
5 andreas 813
    }
814
 
26 andreas 815
    // Draw the buttons
201 andreas 816
    BUTTONS_T *button = TPageInterface::getButtons();
26 andreas 817
 
818
    while (button)
819
    {
820
        if (button->button)
821
        {
822
            MSG_DEBUG("Drawing button " << button->button->getButtonIndex() << ": " << button->button->getButtonName());
823
            button->button->registerCallback(_displayButton);
824
            button->button->regCallPlayVideo(_playVideo);
204 andreas 825
            TPageInterface::registerListCallback<TPage>(button->button, this);
201 andreas 826
            button->button->setFonts(getFonts());
26 andreas 827
            button->button->setPalette(mPalette);
828
            button->button->createButtons();
829
 
830
            if (sr.size() > 0)
831
                button->button->setGlobalOpacity(sr[0].oo);
832
 
833
            button->button->show();
834
        }
835
 
836
        button = button->next;
837
    }
838
 
66 andreas 839
    // Mark page as visible
14 andreas 840
    mVisible = true;
271 andreas 841
 
842
    if (gPageManager && gPageManager->getPageFinished())
843
        gPageManager->getPageFinished()(handle);
5 andreas 844
}
845
 
349 andreas 846
bool TPage::addSubPage(TSubPage* pg)
3 andreas 847
{
14 andreas 848
    DECL_TRACER("TPage::addSubPage(TSubPage* pg)");
3 andreas 849
 
850
    if (!pg)
851
    {
852
        MSG_ERROR("Parameter is NULL!");
853
        TError::setError();
349 andreas 854
        return false;
3 andreas 855
    }
856
 
349 andreas 857
    if (mSubPages.empty())
858
        mZOrder = 0;
3 andreas 859
 
349 andreas 860
#if __cplusplus < 201703L
861
    map<int, TSubPage *>::iterator iter = mSubPages.find(pg->getNumber());
3 andreas 862
 
349 andreas 863
    if (iter != mSubPages.end() && iter->second != pg)
864
        iter->second = pg;
3 andreas 865
    else
349 andreas 866
        mSubPages.insert(pair<int, TSubPage *>(pg->getNumber(), pg));
867
#else
868
    mSubPages.insert_or_assign(pg->getNumber(), pg);
869
#endif
5 andreas 870
    mLastSubPage = 0;
349 andreas 871
    return true;
3 andreas 872
}
873
 
874
bool TPage::removeSubPage(int ID)
875
{
876
    DECL_TRACER("TPage::removeSubPage(int ID)");
877
 
349 andreas 878
    map<int, TSubPage *>::iterator iter = mSubPages.find(ID);
3 andreas 879
 
349 andreas 880
    if (iter != mSubPages.end())
3 andreas 881
    {
349 andreas 882
        mSubPages.erase(iter);
883
        return true;
3 andreas 884
    }
885
 
886
    return false;
887
}
888
 
889
bool TPage::removeSubPage(const std::string& nm)
890
{
891
    DECL_TRACER("TPage::removeSubPage(const std::string& nm)");
892
 
349 andreas 893
    if (mSubPages.empty())
894
        return false;
3 andreas 895
 
349 andreas 896
    map<int, TSubPage *>::iterator iter;
897
 
898
    for (iter = mSubPages.begin(); iter != mSubPages.end(); ++iter)
3 andreas 899
    {
349 andreas 900
        if (iter->second->getName() == nm)
3 andreas 901
        {
349 andreas 902
            mSubPages.erase(iter);
3 andreas 903
            return true;
904
        }
905
    }
906
 
907
    return false;
908
}
909
 
4 andreas 910
TSubPage *TPage::getSubPage(int pageID)
911
{
912
    DECL_TRACER("TPage::getSubPage(int pageID)");
913
 
349 andreas 914
    map<int, TSubPage *>::iterator iter = mSubPages.find(pageID);
4 andreas 915
 
349 andreas 916
    if (iter != mSubPages.end())
917
        return iter->second;
4 andreas 918
 
5 andreas 919
    mLastSubPage = 0;
4 andreas 920
    return nullptr;
921
}
922
 
923
TSubPage *TPage::getSubPage(const std::string& name)
924
{
925
    DECL_TRACER("TPage::getSubPage(const std::string& name)");
926
 
349 andreas 927
    if (mSubPages.empty())
928
        return nullptr;
4 andreas 929
 
349 andreas 930
    map<int, TSubPage *>::iterator iter;
931
 
932
    for (iter = mSubPages.begin(); iter != mSubPages.end(); ++iter)
4 andreas 933
    {
349 andreas 934
        if (iter->second->getName() == name)
935
            return iter->second;
4 andreas 936
    }
937
 
5 andreas 938
    mLastSubPage = 0;
4 andreas 939
    return nullptr;
940
}
941
 
942
TSubPage *TPage::getFirstSubPage()
943
{
944
    DECL_TRACER("TPage::getFirstSubPage()");
945
 
349 andreas 946
    if (mSubPages.empty())
947
    {
948
        MSG_DEBUG("No subpages in chain.");
949
        mLastSubPage = 0;
950
        return nullptr;
951
    }
14 andreas 952
 
349 andreas 953
    TSubPage *pg = mSubPages.begin()->second;
954
 
955
    if (!pg)
4 andreas 956
    {
349 andreas 957
        MSG_ERROR("The pointer to the subpage " << mSubPages.begin()->first << " is NULL!");
958
        return nullptr;
4 andreas 959
    }
960
 
349 andreas 961
    mLastSubPage = pg->getNumber();
962
    MSG_DEBUG("Subpage (Z: " << pg->getZOrder() << "): " << pg->getNumber() << ". " << pg->getName());
963
    return pg;
4 andreas 964
}
965
 
966
TSubPage *TPage::getNextSubPage()
967
{
968
    DECL_TRACER("TPage::getNextSubPage()");
969
 
349 andreas 970
    if (mSubPages.empty())
4 andreas 971
    {
349 andreas 972
        MSG_DEBUG("No subpages in chain.");
973
        mLastSubPage = 0;
974
        return nullptr;
975
    }
4 andreas 976
 
349 andreas 977
    if (mLastSubPage <= 0)
978
        mLastSubPage = mSubPages.begin()->second->getNumber();
4 andreas 979
 
349 andreas 980
    map<int, TSubPage *>::iterator iter = mSubPages.find(mLastSubPage);
981
 
982
    if (iter != mSubPages.end())
983
        iter++;
984
    else
985
    {
986
        MSG_DEBUG("No more subpages in chain.");
987
        mLastSubPage = 0;
988
        return nullptr;
4 andreas 989
    }
990
 
349 andreas 991
    if (iter != mSubPages.end())
992
    {
993
        TSubPage *page = iter->second;
994
        mLastSubPage = page->getNumber();
995
        MSG_DEBUG("Subpage (Z: " << page->getZOrder() << "): " << page->getNumber() << ". " << page->getName());
996
        return page;
997
    }
998
 
14 andreas 999
    MSG_DEBUG("No more subpages in chain.");
5 andreas 1000
    mLastSubPage = 0;
4 andreas 1001
    return nullptr;
1002
}
1003
 
154 andreas 1004
TSubPage *TPage::getPrevSubPage()
1005
{
1006
    DECL_TRACER("TPage::getPrevSubPage()");
1007
 
349 andreas 1008
    if (mSubPages.empty())
1009
    {
1010
        MSG_DEBUG("No last subpage or no subpages at all!");
1011
        mLastSubPage = 0;
154 andreas 1012
        return nullptr;
349 andreas 1013
    }
154 andreas 1014
 
349 andreas 1015
    if (mLastSubPage < MAX_PAGE_ID)
154 andreas 1016
    {
349 andreas 1017
        map<int, TSubPage *>::iterator iter = mSubPages.end();
1018
        iter--;
1019
        mLastSubPage = iter->first;
1020
    }
154 andreas 1021
 
349 andreas 1022
    map<int, TSubPage *>::iterator iter = mSubPages.find(mLastSubPage);
154 andreas 1023
 
349 andreas 1024
    if (iter != mSubPages.end() && iter != mSubPages.begin())
1025
        iter--;
1026
    else
1027
    {
1028
        MSG_DEBUG("No more subpages in chain.");
1029
        mLastSubPage = 0;
1030
        return nullptr;
154 andreas 1031
    }
1032
 
349 andreas 1033
    TSubPage *page = iter->second;
1034
    mLastSubPage = page->getNumber();
1035
    MSG_DEBUG("Subpage (Z: " << page->getZOrder() << "): " << page->getNumber() << ". " << page->getName());
1036
    return page;
154 andreas 1037
}
1038
 
1039
TSubPage *TPage::getLastSubPage()
1040
{
1041
    DECL_TRACER("TPage::getLastSubPage()");
1042
 
349 andreas 1043
    if (mSubPages.empty())
154 andreas 1044
    {
1045
        mLastSubPage = 0;
1046
        MSG_DEBUG("No subpages in cache!");
1047
        return nullptr;
1048
    }
1049
 
349 andreas 1050
    map<int, TSubPage *>::iterator iter = mSubPages.end();
1051
    iter--;
1052
    TSubPage *pg = iter->second;
1053
    mLastSubPage = pg->getNumber();
1054
    MSG_DEBUG("Subpage (Z: " << pg->getZOrder() << "): " << pg->getNumber() << ". " << pg->getName());
1055
    return pg;
154 andreas 1056
}
1057
 
12 andreas 1058
void TPage::drop()
1059
{
1060
    DECL_TRACER("TPage::drop()");
1061
 
147 andreas 1062
    // remove all subpages, if there are any
348 andreas 1063
#if TESTMODE == 1
1064
    _block_screen = true;
1065
#endif
349 andreas 1066
    if (!mSubPages.empty())
12 andreas 1067
    {
349 andreas 1068
        map<int, TSubPage *>::iterator iter;
1069
 
1070
        for (iter = mSubPages.begin(); iter != mSubPages.end(); ++iter)
295 andreas 1071
        {
349 andreas 1072
            if (iter->second)
1073
                iter->second->drop();
295 andreas 1074
        }
12 andreas 1075
    }
348 andreas 1076
#if TESTMODE == 1
1077
    _block_screen = false;
1078
#endif
14 andreas 1079
 
147 andreas 1080
    // remove all buttons, if there are any
201 andreas 1081
    BUTTONS_T *bt = TPageInterface::getButtons();
147 andreas 1082
 
1083
    while (bt)
1084
    {
271 andreas 1085
        MSG_DEBUG("Dropping button " << handleToString(bt->button->getHandle()));
1086
        bt->button->invalidate();
147 andreas 1087
        bt = bt->next;
1088
    }
1089
 
271 andreas 1090
    if (gPageManager && gPageManager->getCallDropPage())
1091
    {
1092
        ulong handle = (mPage.pageID << 16) & 0xffff0000;
1093
        gPageManager->getCallDropPage()(handle);
1094
    }
1095
 
14 andreas 1096
    mZOrder = ZORDER_INVALID;
1097
    mVisible = false;
12 andreas 1098
}
43 andreas 1099
#ifdef _SCALE_SKIA_
31 andreas 1100
void TPage::calcPosition(int im_width, int im_height, int *left, int *top, bool scale)
43 andreas 1101
#else
1102
void TPage::calcPosition(int im_width, int im_height, int *left, int *top)
1103
#endif
28 andreas 1104
{
1105
    DECL_TRACER("TPage::calcPosition(int im_width, int im_height, int *left, int *top)");
1106
 
201 andreas 1107
    int nw = mPage.width;
1108
    int nh = mPage.height;
43 andreas 1109
#ifdef _SCALE_SKIA_
31 andreas 1110
    if (scale && gPageManager && gPageManager->getScaleFactor() != 1.0)
28 andreas 1111
    {
1112
        nw = (int)((double)width * gPageManager->getScaleFactor());
1113
        nh = (int)((double)height * gPageManager->getScaleFactor());
1114
    }
43 andreas 1115
#endif
28 andreas 1116
    switch (sr[0].jb)
1117
    {
1118
        case 0: // absolute position
1119
            *left = sr[0].bx;
1120
            *top = sr[0].by;
43 andreas 1121
#ifdef _SCALE_SKIA_
31 andreas 1122
            if (scale && gPageManager && gPageManager->getScaleFactor() != 1.0)
28 andreas 1123
            {
1124
                *left = (int)((double)sr[0].bx * gPageManager->getScaleFactor());
1125
                *left = (int)((double)sr[0].by * gPageManager->getScaleFactor());
1126
            }
43 andreas 1127
#endif
28 andreas 1128
        break;
1129
 
1130
        case 1: // top, left
1131
            *left = 0;
1132
            *top = 0;
1133
        break;
1134
 
1135
        case 2: // center, top
1136
            *left = (nw - im_width) / 2;
1137
            *top = 0;
1138
        break;
1139
 
1140
        case 3: // right, top
1141
            *left = nw - im_width;
1142
            *top = 0;
1143
        break;
1144
 
1145
        case 4: // left, middle
1146
            *left = 0;
1147
            *top = (nh - im_height) / 2;
1148
        break;
1149
 
1150
        case 6: // right, middle
1151
            *left = nw - im_width;
1152
            *top = (nh - im_height) / 2;
1153
        break;
1154
 
1155
        case 7: // left, bottom
1156
            *left = 0;
1157
            *top = nh - im_height;
1158
        break;
1159
 
1160
        case 8: // center, bottom
1161
            *left = (nw - im_width) / 2;
1162
            *top = nh - im_height;
1163
        break;
1164
 
1165
        case 9: // right, bottom
1166
            *left = nw - im_width;
1167
            *top = nh - im_height;
1168
        break;
31 andreas 1169
 
1170
        default:    // center middle
1171
            *left = (nw - im_width) / 2;
1172
            *top = (nh - im_height) / 2;
28 andreas 1173
    }
1174
 
1175
    if (*left < 0)
1176
        *left = 0;
1177
 
1178
    if (*top < 0)
1179
        *top = 0;
1180
}
1181
 
151 andreas 1182
void TPage::sortSubpages()
1183
{
1184
    DECL_TRACER("TPage::sortSubpage()");
1185
 
349 andreas 1186
    mSubPagesSorted.clear();
151 andreas 1187
 
349 andreas 1188
    if (mSubPages.empty())
1189
        return;
1190
 
1191
    map<int, TSubPage *>::iterator iter;
1192
 
1193
    for (iter = mSubPages.begin(); iter != mSubPages.end(); ++iter)
151 andreas 1194
    {
349 andreas 1195
        if (iter->second->getZOrder() >= 0)
154 andreas 1196
        {
349 andreas 1197
            mSubPagesSorted.insert(pair<int, TSubPage *>(iter->second->getZOrder(), iter->second));
1198
            MSG_DEBUG("Page " << iter->second->getNumber() << " (" << iter->second->getName() << "): sorted in with Z-Order " << iter->second->getZOrder());
1199
        }
1200
    }
1201
}
151 andreas 1202
 
349 andreas 1203
map<int, TSubPage *>& TPage::getSortedSubpages(bool force)
1204
{
1205
    DECL_TRACER("TPage::getSortedSubpages(bool force)");
151 andreas 1206
 
349 andreas 1207
    if (mSubPagesSorted.empty() || force)
1208
        sortSubpages();
151 andreas 1209
 
349 andreas 1210
    return mSubPagesSorted;
151 andreas 1211
}
1212
 
152 andreas 1213
int TPage::getNextZOrder()
1214
{
1215
    DECL_TRACER("TPage::getNextZOrder()");
1216
 
1217
    // Find highest z-order number
154 andreas 1218
    int cnt = 0;
349 andreas 1219
    map<int, TSubPage *>::iterator iter;
152 andreas 1220
 
349 andreas 1221
    for (iter = mSubPages.begin(); iter != mSubPages.end(); ++iter)
152 andreas 1222
    {
349 andreas 1223
        int zo = iter->second->getZOrder();
1224
 
1225
        if (iter->second && zo != ZORDER_INVALID)
154 andreas 1226
        {
349 andreas 1227
            if (cnt < zo)
1228
                cnt = zo;
154 andreas 1229
        }
152 andreas 1230
    }
1231
 
154 andreas 1232
    mZOrder = cnt + 1;
152 andreas 1233
    MSG_DEBUG("New Z-order: " << mZOrder);
1234
    return mZOrder;
1235
}
1236
 
151 andreas 1237
int TPage::decZOrder()
1238
{
1239
    DECL_TRACER("TPage::decZOrder()");
1240
 
1241
    // Find highest z-order number
349 andreas 1242
    int cnt = 0;
1243
    map<int, TSubPage *>::iterator iter;
151 andreas 1244
 
349 andreas 1245
    for (iter = mSubPages.begin(); iter != mSubPages.end(); ++iter)
151 andreas 1246
    {
349 andreas 1247
        int zo = iter->second->getZOrder();
1248
 
1249
        if (iter->second && zo != ZORDER_INVALID)
154 andreas 1250
        {
349 andreas 1251
            if (cnt < zo)
1252
                cnt = zo;
154 andreas 1253
        }
151 andreas 1254
    }
1255
 
349 andreas 1256
    mZOrder = cnt;
151 andreas 1257
    return mZOrder;
1258
}