Subversion Repositories tpanel

Rev

Rev 482 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 482 Rev 486
Line 1... Line 1...
1
/*
1
/*
2
 * Copyright (C) 2020 to 2024 by Andreas Theofilu <andreas@theosys.at>
2
 * Copyright (C) 2020 to 2025 by Andreas Theofilu <andreas@theosys.at>
3
 *
3
 *
4
 * This program is free software; you can redistribute it and/or modify
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
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
6
 * the Free Software Foundation; either version 3 of the License, or
7
 * (at your option) any later version.
7
 * (at your option) any later version.
Line 20... Line 20...
20
#include <memory>
20
#include <memory>
21
#include <algorithm>
21
#include <algorithm>
22
#include <codecvt>
22
#include <codecvt>
23
#include <fstream>
23
#include <fstream>
24
 
24
 
-
 
25
#include <unistd.h>
-
 
26
 
25
#include <include/core/SkPixmap.h>
27
#include <include/core/SkPixmap.h>
26
#include <include/core/SkSize.h>
28
#include <include/core/SkSize.h>
27
#include <include/core/SkColor.h>
29
#include <include/core/SkColor.h>
28
#include <include/core/SkFont.h>
30
#include <include/core/SkFont.h>
29
#include <include/core/SkTypeface.h>
31
#include <include/core/SkTypeface.h>
Line 59... Line 61...
59
#include "tsystemsound.h"
61
#include "tsystemsound.h"
60
#include "timgcache.h"
62
#include "timgcache.h"
61
#include "turl.h"
63
#include "turl.h"
62
#include "tlock.h"
64
#include "tlock.h"
63
#include "ttpinit.h"
65
#include "ttpinit.h"
-
 
66
#include "tlauncher.h"
64
#if TESTMODE == 1
67
#if TESTMODE == 1
65
#include "testmode.h"
68
#include "testmode.h"
66
#endif
69
#endif
67
 
70
 
68
#if __cplusplus < 201402L
71
#if __cplusplus < 201402L
Line 259... Line 262...
259
        MSG_ERROR("Invalid NULL parameter passed!");
262
        MSG_ERROR("Invalid NULL parameter passed!");
260
        TError::setError();
263
        TError::setError();
261
        return TExpat::npos;
264
        return TExpat::npos;
262
    }
265
    }
263
 
266
 
-
 
267
    vector<string> guestures = { "ga", "gu", "gd", "gr", "gl", "gt", "tu", "td", "tr", "tl" };
264
    mChanged = true;
268
    mChanged = true;
265
    int lastLevel = 0;
269
    int lastLevel = 0;
266
    int lastJoyX = 0;
270
    int lastJoyX = 0;
267
    int lastJoyY = 0;
271
    int lastJoyY = 0;
268
    vector<ATTRIBUTE_t> attrs = xml->getAttributes(index);
272
    vector<ATTRIBUTE_t> attrs = xml->getAttributes(index);
Line 272... Line 276...
272
    string ename, content;
276
    string ename, content;
273
    size_t oldIndex = index;
277
    size_t oldIndex = index;
274
 
278
 
275
    while((index = xml->getNextElementFromIndex(index, &ename, &content, &attrs)) != TExpat::npos)
279
    while((index = xml->getNextElementFromIndex(index, &ename, &content, &attrs)) != TExpat::npos)
276
    {
280
    {
-
 
281
        MSG_DEBUG("Element: " << ename << " at index " << index);
-
 
282
 
277
        if (ename.compare("bi") == 0)
283
        if (ename.compare("bi") == 0)               // Button index
278
        {
284
        {
279
            bi = xml->convertElementToInt(content);
285
            bi = xml->convertElementToInt(content);
280
            MSG_DEBUG("Processing button index: " << bi);
286
            MSG_DEBUG("Processing button index: " << bi);
281
        }
287
        }
282
        else if (ename.compare("na") == 0)          // Name
288
        else if (ename.compare("na") == 0)          // Name
Line 445... Line 451...
445
            PUSH_FUNC_T pf;
451
            PUSH_FUNC_T pf;
446
            pf.pfName = content;
452
            pf.pfName = content;
447
            pf.pfType = xml->getAttribute("type", attrs);
453
            pf.pfType = xml->getAttribute("type", attrs);
448
            pushFunc.push_back(pf);
454
            pushFunc.push_back(pf);
449
        }
455
        }
450
        else if (ename.compare("er") == 0)          // Function call TP5
456
        else if ((ename.compare("ep") == 0 || ename.compare("er") == 0) && xml->isElementTypeStart(index))          // Function call TP5: Event on press/release
451
        {
457
        {
452
            PUSH_FUNC_T pf;
458
            PUSH_FUNC_T pf;
-
 
459
            pf.event = ename.compare("ep") == 0 ? EVENT_PRESS : EVENT_RELEASE;
453
            string e;
460
            string e;
454
 
461
 
455
            while ((index = xml->getNextElementFromIndex(index, &e, &content, &attrs)) != TExpat::npos)
462
            while ((index = xml->getNextElementFromIndex(index, &e, &content, &attrs)) != TExpat::npos)
456
            {
463
            {
457
                if (e.compare("pgFlip") == 0)
464
                if (e.compare("pgFlip") == 0)
458
                {
465
                {
-
 
466
                    pf.action = BT_ACTION_PGFLIP;
459
                    pf.item = xml->getAttributeInt("item", attrs);
467
                    pf.item = xml->getAttributeInt("item", attrs);
460
                    pf.pfType = xml->getAttribute("type", attrs);
468
                    pf.pfType = xml->getAttribute("type", attrs);
461
                    pf.pfName = content;
469
                    pf.pfName = content;
462
                    pushFunc.push_back(pf);
470
                    pushFunc.push_back(pf);
463
                }
471
                }
-
 
472
                else if (e.compare("launch") == 0)
-
 
473
                {
-
 
474
                    pf.action = BT_ACTION_LAUNCH;
-
 
475
                    pf.item = xml->getAttributeInt("item", attrs);
-
 
476
                    pf.ID = xml->getAttributeInt("id", attrs);
-
 
477
                    pf.pfAction = xml->getAttribute("action", attrs);
-
 
478
                    pf.pfName = content;
-
 
479
                    pushFunc.push_back(pf);
-
 
480
                }
-
 
481
 
-
 
482
                oldIndex = index;
464
            }
483
            }
-
 
484
 
-
 
485
            index = oldIndex + 1;
465
        }
486
        }
466
        else if (ename.compare("ep") == 0)          // TP5: Call an application
487
        else if (isButtonEvent(ename, guestures) && xml->isElementTypeStart(index))     // Fuction call TP5: Event on guesture
467
        {
488
        {
468
            CALL_APP_t ep;
489
            PUSH_FUNC pf;
-
 
490
            pf.event = getButtonEvent(ename);
469
            string e;
491
            string e;
470
 
492
 
471
            while ((index = xml->getNextElementFromIndex(index, &e, &content, &attrs)) != TExpat::npos)
493
            while ((index = xml->getNextElementFromIndex(index, &e, &content, &attrs)) != TExpat::npos)
472
            {
494
            {
473
                if (e.compare("launch") == 0)
495
                if (e.compare("pgFlip") == 0)
474
                {
496
                {
475
                    ep.item = xml->getAttributeInt("item", attrs);
497
                    pf.action = BT_ACTION_PGFLIP;
476
                    ep.action = xml->getAttribute("action", attrs);
498
                    pf.item = xml->getAttributeInt("item", attrs);
477
                    ep.id = xml->getAttributeInt("id", attrs);
499
                    pf.pfType = xml->getAttribute("type", attrs);
478
                    ep.name = content;
500
                    pf.pfName = content;
479
                    callApp.push_back(ep);
501
                    pushFunc.push_back(pf);
480
                }
502
                }
-
 
503
                else if (e.compare("launch") == 0)
-
 
504
                {
-
 
505
                    pf.action = BT_ACTION_LAUNCH;
-
 
506
                    pf.item = xml->getAttributeInt("item", attrs);
-
 
507
                    pf.ID = xml->getAttributeInt("id", attrs);
-
 
508
                    pf.pfAction = xml->getAttribute("action", attrs);
-
 
509
                    pf.pfName = content;
-
 
510
                    pushFunc.push_back(pf);
-
 
511
                }
-
 
512
 
-
 
513
                oldIndex = index;
481
            }
514
            }
-
 
515
 
-
 
516
            index = oldIndex + 1;
482
        }
517
        }
483
        else if (ename.compare("sr") == 0)          // Section state resources
518
        else if (ename.compare("sr") == 0)          // Section state resources
484
        {
519
        {
485
            SR_T bsr;
520
            SR_T bsr;
486
            bsr.number = xml->getAttributeInt("number", attrs); // State number
521
            bsr.number = xml->getAttributeInt("number", attrs); // State number
-
 
522
            MSG_DEBUG("Button: " << na << ": State element: " << bsr.number);
487
            string e;
523
            string e;
488
 
524
 
489
            while ((index = xml->getNextElementFromIndex(index, &e, &content, &attrs)) != TExpat::npos)
525
            while ((index = xml->getNextElementFromIndex(index, &e, &content, &attrs)) != TExpat::npos)
490
            {
526
            {
491
                if (e.compare("do") == 0)           // Draw order
527
                if (e.compare("do") == 0)           // Draw order
Line 509... Line 545...
509
                }
545
                }
510
                else if (e.compare("bitmapEntry") == 0) // G5 start of bitmap table
546
                else if (e.compare("bitmapEntry") == 0) // G5 start of bitmap table
511
                {
547
                {
512
                    string fname;
548
                    string fname;
513
                    BITMAPS_t bitmapEntry;
549
                    BITMAPS_t bitmapEntry;
-
 
550
                    MSG_DEBUG("Section: " << e);
514
 
551
 
515
                    while ((index = xml->getNextElementFromIndex(index, &fname, &content, &attrs)) != TExpat::npos)
552
                    while ((index = xml->getNextElementFromIndex(index, &fname, &content, &attrs)) != TExpat::npos)
516
                    {
553
                    {
517
                        if (fname.compare("fileName") == 0)
554
                        if (fname.compare("fileName") == 0)
518
                            bitmapEntry.fileName = content;
555
                            bitmapEntry.fileName = content;
Line 520... Line 557...
520
                            bitmapEntry.justification = static_cast<ORIENTATION>(xml->convertElementToInt(content));
557
                            bitmapEntry.justification = static_cast<ORIENTATION>(xml->convertElementToInt(content));
521
                        else if (fname.compare("offsetX") == 0)
558
                        else if (fname.compare("offsetX") == 0)
522
                            bitmapEntry.offsetX = xml->convertElementToInt(content);
559
                            bitmapEntry.offsetX = xml->convertElementToInt(content);
523
                        else if (fname.compare("offsetY") == 0)
560
                        else if (fname.compare("offsetY") == 0)
524
                            bitmapEntry.offsetY = xml->convertElementToInt(content);
561
                            bitmapEntry.offsetY = xml->convertElementToInt(content);
-
 
562
 
-
 
563
                        oldIndex = index;
525
                    }
564
                    }
526
 
565
 
527
                    bsr.bitmaps.push_back(bitmapEntry);
566
                    bsr.bitmaps.push_back(bitmapEntry);
-
 
567
 
-
 
568
                    if (index == TExpat::npos)
-
 
569
                        index = oldIndex + 1;
528
                }
570
                }
529
                else if (e.compare("sd") == 0)      // Sound file
571
                else if (e.compare("sd") == 0)      // Sound file
530
                    bsr.sd = content;
572
                    bsr.sd = content;
531
                else if (e.compare("sb") == 0)      // index external graphic
573
                else if (e.compare("sb") == 0)      // index external graphic
532
                    bsr.sb = xml->convertElementToInt(content);
574
                    bsr.sb = xml->convertElementToInt(content);
Line 571... Line 613...
571
 
613
 
572
                oldIndex = index;
614
                oldIndex = index;
573
            }
615
            }
574
 
616
 
575
            sr.push_back(bsr);
617
            sr.push_back(bsr);
-
 
618
 
-
 
619
            if (index == TExpat::npos)
-
 
620
                index = oldIndex + 1;
576
        }
621
        }
577
 
622
 
578
        if (index == TExpat::npos)
623
        if (index == TExpat::npos)
579
            index = oldIndex + 1;
624
            index = oldIndex + 1;
-
 
625
        else if (index > oldIndex)
-
 
626
            oldIndex = index;
580
    }
627
    }
581
 
628
 
-
 
629
    MSG_DEBUG("Index after loop: " << (index == TExpat::npos ? 0 : index) << ", old index: " << oldIndex);
582
    visible = !hd;  // set the initial visibility
630
    visible = !hd;  // set the initial visibility
583
 
631
 
584
    if (gPageManager)
632
    if (gPageManager)
585
    {
633
    {
586
        TButtonStates *pbs = gPageManager->addButtonState(type, ap, ad, ch, cp, lp, lv);
634
        TButtonStates *pbs = gPageManager->addButtonState(type, ap, ad, ch, cp, lp, lv);
Line 629... Line 677...
629
    }
677
    }
630
*/
678
*/
631
    MSG_DEBUG("Added button " << bi << " --> " << na);
679
    MSG_DEBUG("Added button " << bi << " --> " << na);
632
 
680
 
633
    if (index == TExpat::npos)
681
    if (index == TExpat::npos)
634
        return oldIndex + 1;
682
        index = oldIndex + 1;
635
 
683
 
-
 
684
    MSG_DEBUG("Returning index " << index);
636
    return index;
685
    return index;
637
}
686
}
638
 
687
 
639
bool TButton::createSoftButton(const EXTBUTTON_t& bt)
688
bool TButton::createSoftButton(const EXTBUTTON_t& bt)
640
{
689
{
Line 1099... Line 1148...
1099
        int number = srIter->number;
1148
        int number = srIter->number;
1100
 
1149
 
1101
        if (srIter->sb > 0)
1150
        if (srIter->sb > 0)
1102
            continue;
1151
            continue;
1103
 
1152
 
1104
        bool bmExistMi = false;
-
 
1105
        bool bmExistBm = false;
-
 
1106
        bool reload = false;
-
 
1107
 
-
 
1108
        if (!srIter->mi.empty())
1153
        if (!TTPInit::isTP5())
1109
        {
1154
        {
-
 
1155
            bool bmExistMi = false;
1110
            if ((bmExistMi = TImgCache::existBitmap(srIter->mi, _BMTYPE_CHAMELEON)) == false)
1156
            bool bmExistBm = false;
-
 
1157
            bool reload = false;
-
 
1158
 
-
 
1159
            if (!srIter->mi.empty())
1111
            {
1160
            {
-
 
1161
                if ((bmExistMi = TImgCache::existBitmap(srIter->mi, _BMTYPE_CHAMELEON)) == false)
-
 
1162
                {
1112
                mChanged = true;
1163
                    mChanged = true;
1113
                reload = true;
1164
                    reload = true;
-
 
1165
                }
1114
            }
1166
            }
1115
        }
-
 
1116
 
1167
 
1117
        if (!srIter->bm.empty())
1168
            if (!srIter->bm.empty())
1118
        {
-
 
1119
            if ((bmExistBm = TImgCache::existBitmap(srIter->bm, _BMTYPE_BITMAP)) == false)
-
 
1120
            {
1169
            {
-
 
1170
                if ((bmExistBm = TImgCache::existBitmap(srIter->bm, _BMTYPE_BITMAP)) == false)
-
 
1171
                {
1121
                mChanged = true;
1172
                    mChanged = true;
1122
                reload = true;
1173
                    reload = true;
-
 
1174
                }
1123
            }
1175
            }
1124
        }
-
 
1125
 
1176
 
1126
        if (!force)
1177
            if (!force)
1127
        {
1178
            {
1128
            if (!reload)   // If the image already exist, do not load it again.
1179
                if (!reload)   // If the image already exist, do not load it again.
1129
                continue;
1180
                    continue;
1130
        }
1181
            }
1131
 
1182
 
1132
        if (!bmExistMi && !srIter->mi.empty())        // Do we have a chameleon image?
1183
            if (!bmExistMi && !srIter->mi.empty())        // Do we have a chameleon image?
1133
        {
1184
            {
1134
            sk_sp<SkData> image;
1185
                sk_sp<SkData> image;
1135
            SkBitmap bm;
1186
                SkBitmap bm;
1136
 
1187
 
1137
            if (!(image = readImage(srIter->mi)))
1188
                if (!(image = readImage(srIter->mi)))
1138
                return false;
1189
                    return false;
1139
 
1190
 
1140
            DecodeDataToBitmap(image, &bm);
1191
                DecodeDataToBitmap(image, &bm);
1141
 
1192
 
1142
            if (bm.empty())
1193
                if (bm.empty())
1143
            {
1194
                {
1144
                MSG_WARNING("Could not create a picture for element " << number << " on button " << bi << " (" << na << ")");
1195
                    MSG_WARNING("Could not create a picture for element " << number << " on button " << bi << " (" << na << ")");
1145
                return false;
1196
                    return false;
-
 
1197
                }
-
 
1198
 
-
 
1199
                TImgCache::addImage(srIter->mi, bm, _BMTYPE_CHAMELEON);
-
 
1200
                srIter->mi_width = bm.info().width();
-
 
1201
                srIter->mi_height = bm.info().height();
-
 
1202
                mChanged = true;
1146
            }
1203
            }
1147
 
1204
 
1148
            TImgCache::addImage(srIter->mi, bm, _BMTYPE_CHAMELEON);
1205
            if (!bmExistBm && !srIter->bm.empty())        // Do we have a bitmap?
1149
            srIter->mi_width = bm.info().width();
1206
            {
1150
            srIter->mi_height = bm.info().height();
1207
                sk_sp<SkData> image;
1151
            mChanged = true;
1208
                SkBitmap bm;
1152
        }
-
 
1153
 
1209
 
1154
        if (!bmExistBm && !srIter->bm.empty())        // Do we have a bitmap?
1210
                if (!(image = readImage(srIter->bm)))
1155
        {
-
 
1156
            sk_sp<SkData> image;
1211
                    return false;
1157
            SkBitmap bm;
-
 
1158
 
1212
 
1159
            if (!(image = readImage(srIter->bm)))
1213
                DecodeDataToBitmap(image, &bm);
1160
                return false;
-
 
1161
 
1214
 
1162
            DecodeDataToBitmap(image, &bm);
1215
                if (bm.empty())
-
 
1216
                {
-
 
1217
                    MSG_WARNING("Could not create a picture for element " << number << " on button " << bi << " (" << na << ")");
-
 
1218
                    return false;
-
 
1219
                }
1163
 
1220
 
1164
            if (bm.empty())
1221
                TImgCache::addImage(srIter->bm, bm, _BMTYPE_BITMAP);
1165
            {
1222
                srIter->bm_width = bm.info().width();
1166
                MSG_WARNING("Could not create a picture for element " << number << " on button " << bi << " (" << na << ")");
1223
                srIter->bm_height = bm.info().height();
1167
                return false;
1224
                mChanged = true;
1168
            }
1225
            }
-
 
1226
        }
-
 
1227
        else
-
 
1228
        {
-
 
1229
            if (srIter->bitmaps.size() > 0)
-
 
1230
            {
-
 
1231
                vector<BITMAPS_t>::iterator bmIter;
-
 
1232
                sk_sp<SkData> image;
-
 
1233
                SkBitmap bm;
1169
 
1234
 
-
 
1235
                for (bmIter = srIter->bitmaps.begin(); bmIter != srIter->bitmaps.end(); ++bmIter)
-
 
1236
                {
-
 
1237
                    if (force || !TImgCache::existBitmap(bmIter->fileName, _BMTYPE_BITMAP))
-
 
1238
                    {
-
 
1239
                        if (!(image = readImage(bmIter->fileName)))
-
 
1240
                        {
-
 
1241
                            MSG_WARNING("Error reading image " << bmIter->fileName << "!");
-
 
1242
                            continue;
-
 
1243
                        }
-
 
1244
 
-
 
1245
                        DecodeDataToBitmap(image, &bm);
-
 
1246
 
-
 
1247
                        if (bm.empty())
-
 
1248
                        {
-
 
1249
                            MSG_WARNING("Could not create a picture for element " << number << " on button " << bi << " (" << na << ")");
-
 
1250
                            continue;
-
 
1251
                        }
-
 
1252
 
1170
            TImgCache::addImage(srIter->bm, bm, _BMTYPE_BITMAP);
1253
                        TImgCache::addImage(bmIter->fileName, bm, _BMTYPE_BITMAP);
1171
            srIter->bm_width = bm.info().width();
1254
                        bmIter->width = bm.info().width();
1172
            srIter->bm_height = bm.info().height();
1255
                        bmIter->height = bm.info().height();
1173
            mChanged = true;
1256
                        mChanged = true;
-
 
1257
                    }
-
 
1258
                }
-
 
1259
            }
1174
        }
1260
        }
1175
    }
1261
    }
1176
 
1262
 
1177
    return true;
1263
    return true;
1178
}
1264
}
Line 2328... Line 2414...
2328
    setScreenDone();
2414
    setScreenDone();
2329
#endif
2415
#endif
2330
    return true;
2416
    return true;
2331
}
2417
}
2332
 
2418
 
2333
bool TButton::setBitmap(const string& file, int instance)
2419
bool TButton::setBitmap(const string& file, int instance, int index, int justify, int x, int y)
2334
{
2420
{
2335
    DECL_TRACER("TButton::setBitmap(const string& file, int instance)");
2421
    DECL_TRACER("TButton::setBitmap(const string& file, int instance, int index, int justify, int x, int y)");
2336
 
2422
 
2337
    if (instance >= (int)sr.size())
2423
    if (instance >= (int)sr.size())
2338
    {
2424
    {
2339
        MSG_ERROR("Invalid parameters!");
2425
        MSG_ERROR("Invalid parameters!");
2340
        return false;
2426
        return false;
Line 2347... Line 2433...
2347
    {
2433
    {
2348
        loop = (int)sr.size();
2434
        loop = (int)sr.size();
2349
        inst = 0;
2435
        inst = 0;
2350
    }
2436
    }
2351
 
2437
 
2352
    for (int i = 0; i < loop; ++i)
2438
    if (!TTPInit::isTP5())
2353
    {
2439
    {
2354
        if (sr[inst].bm == file)
2440
        for (int i = 0; i < loop; ++i)
2355
        {
2441
        {
-
 
2442
            if (!TTPInit::isTP5())
-
 
2443
            {
-
 
2444
                if (sr[inst].bm == file)
-
 
2445
                {
-
 
2446
                    inst++;
-
 
2447
                    continue;
-
 
2448
                }
-
 
2449
            }
-
 
2450
 
-
 
2451
            mChanged = true;
-
 
2452
 
-
 
2453
            sr[inst].bm = file;
-
 
2454
 
-
 
2455
            if (!file.empty() && !TImgCache::existBitmap(file, _BMTYPE_BITMAP))
-
 
2456
            {
-
 
2457
                sk_sp<SkData> image;
-
 
2458
                SkBitmap bm;
-
 
2459
 
-
 
2460
                image = readImage(file);
-
 
2461
 
-
 
2462
                if (image)
-
 
2463
                {
-
 
2464
                    DecodeDataToBitmap(image, &bm);
-
 
2465
 
-
 
2466
                    if (!bm.empty())
-
 
2467
                    {
-
 
2468
                        TImgCache::addImage(file, bm, _BMTYPE_BITMAP);
-
 
2469
                        sr[inst].bm_width = bm.info().width();
-
 
2470
                        sr[inst].bm_height = bm.info().height();
-
 
2471
                    }
-
 
2472
                }
-
 
2473
            }
-
 
2474
 
2356
            inst++;
2475
            inst++;
2357
            continue;
-
 
2358
        }
2476
        }
-
 
2477
    }
-
 
2478
    else    // TP5
-
 
2479
    {
-
 
2480
        ORIENTATION just = ORI_CENTER_MIDDLE;
2359
 
2481
 
-
 
2482
        if (justify < 0 || justify > 11)
2360
        mChanged = true;
2483
            just = ORI_CENTER_MIDDLE;
2361
        sr[inst].bm = file;
2484
        else
-
 
2485
            just = static_cast<ORIENTATION>(justify);
2362
 
2486
 
2363
        if (!file.empty() && !TImgCache::existBitmap(file, _BMTYPE_BITMAP))
2487
        // Index 0 = Chameleon image
-
 
2488
        if (index == 0)
2364
        {
2489
        {
2365
            sk_sp<SkData> image;
-
 
2366
            SkBitmap bm;
2490
            SkBitmap bm;
2367
 
2491
 
-
 
2492
            if (!file.empty() && !TImgCache::existBitmap(file, _BMTYPE_CHAMELEON))
-
 
2493
            {
2368
            image = readImage(file);
2494
                sk_sp<SkData> image;
2369
 
2495
 
-
 
2496
                image = readImage(file);
-
 
2497
 
2370
            if (image)
2498
                if (image)
-
 
2499
                {
-
 
2500
                    DecodeDataToBitmap(image, &bm);
-
 
2501
 
-
 
2502
                    if (!bm.empty())
-
 
2503
                        TImgCache::addImage(file, bm, _BMTYPE_BITMAP);
-
 
2504
                }
-
 
2505
            }
-
 
2506
 
-
 
2507
            if (instance < 0)   // Set to all instances?
2371
            {
2508
            {
-
 
2509
                for (size_t i = 0; i < sr.size(); ++i)
-
 
2510
                {
-
 
2511
                    if (sr[i].mi != file)
-
 
2512
                    {
2372
                DecodeDataToBitmap(image, &bm);
2513
                        sr[i].mi = file;
2373
 
2514
 
2374
                if (!bm.empty())
2515
                        if (!bm.empty())
-
 
2516
                        {
-
 
2517
                            sr[i].mi_width = bm.info().width();
-
 
2518
                            sr[i].mi_height = bm.info().height();
-
 
2519
                        }
-
 
2520
 
-
 
2521
                        mChanged = true;
-
 
2522
                    }
-
 
2523
                }
-
 
2524
            }
-
 
2525
            else
-
 
2526
            {
-
 
2527
                if (sr[inst].mi != file)
2375
                {
2528
                {
2376
                    TImgCache::addImage(sr[inst].bm, bm, _BMTYPE_BITMAP);
2529
                    sr[inst].mi = file;
-
 
2530
 
-
 
2531
                    if (!bm.empty())
-
 
2532
                    {
2377
                    sr[inst].bm_width = bm.info().width();
2533
                        sr[inst].mi_width = bm.info().width();
2378
                    sr[inst].bm_height = bm.info().height();
2534
                        sr[inst].mi_height = bm.info().height();
-
 
2535
                    }
-
 
2536
 
-
 
2537
                    mChanged = true;
2379
                }
2538
                }
2380
            }
2539
            }
2381
        }
2540
        }
-
 
2541
        else if (instance > 0)
-
 
2542
        {
-
 
2543
            if (!file.empty() && !TImgCache::existBitmap(file, _BMTYPE_BITMAP))
-
 
2544
            {
-
 
2545
                sk_sp<SkData> image;
-
 
2546
                SkBitmap bm;
2382
 
2547
 
-
 
2548
                image = readImage(file);
-
 
2549
 
-
 
2550
                if (image)
-
 
2551
                {
-
 
2552
                    DecodeDataToBitmap(image, &bm);
-
 
2553
 
-
 
2554
                    if (!bm.empty())
-
 
2555
                    {
-
 
2556
                        TImgCache::addImage(file, bm, _BMTYPE_BITMAP);
-
 
2557
                        sr[inst].bm_width = bm.info().width();
-
 
2558
                        sr[inst].bm_height = bm.info().height();
-
 
2559
                    }
-
 
2560
                }
-
 
2561
            }
-
 
2562
 
-
 
2563
            for (size_t i = 0; i < 5; ++i)
-
 
2564
            {
-
 
2565
                if (i >= sr[inst].bitmaps.size() && !file.empty())
-
 
2566
                {
-
 
2567
                    BITMAPS_t bm;
-
 
2568
 
-
 
2569
                    if (i == (static_cast<size_t>(index - 1)))
-
 
2570
                    {
-
 
2571
                        bm.fileName = file;
-
 
2572
                        bm.justification = just;
-
 
2573
                        bm.offsetX = x;
-
 
2574
                        bm.offsetY = y;
-
 
2575
                        mChanged = true;
-
 
2576
                    }
-
 
2577
 
-
 
2578
                    sr[inst].bitmaps.push_back(bm);
-
 
2579
                }
-
 
2580
                else if (i == static_cast<size_t>(index - 1))
-
 
2581
                {
-
 
2582
                    BITMAPS_t bm = sr[inst].bitmaps[i];
-
 
2583
 
-
 
2584
                    if (bm.fileName != file)
-
 
2585
                    {
-
 
2586
                        bm.fileName = file;
-
 
2587
                        bm.justification = just;
-
 
2588
                        bm.offsetX = x;
-
 
2589
                        bm.offsetY = y;
-
 
2590
                        sr[inst].bitmaps[i] = bm;
-
 
2591
                        mChanged = true;
-
 
2592
                    }
-
 
2593
                }
2383
        inst++;
2594
            }
-
 
2595
        }
2384
    }
2596
    }
2385
 
2597
 
2386
    if (!createButtons(true))   // We're forcing the image to load
2598
    if (!createButtons(true))   // We're forcing the image to load
2387
        return false;
2599
        return false;
2388
 
2600
 
Line 3995... Line 4207...
3995
    if (inst < 0)
4207
    if (inst < 0)
3996
        instance = 0;
4208
        instance = 0;
3997
    else if ((size_t)inst >= sr.size())
4209
    else if ((size_t)inst >= sr.size())
3998
        instance = (int)(sr.size() - 1);
4210
        instance = (int)(sr.size() - 1);
3999
 
4211
 
-
 
4212
    bool tp5 = TTPInit::isTP5();   // TRUE = TP5
-
 
4213
    string bmFile;
-
 
4214
 
4000
    /*
4215
    /*
4001
     * Here we test if we have a cameleon image. If there is a mask (sr[].mi)
4216
     * Here we test if we have a cameleon image. If there is a mask (sr[].mi)
4002
     * and no frame (sr[].bs) then we have a cameleon image. A bitmap is
4217
     * and no frame (sr[].bs) then we have a cameleon image. A bitmap is
4003
     * optional. If there is one it will be used to draw with the mask.
4218
     * optional. If there is one it will be used to draw with the mask.
4004
     * Otherwise the mask may be used as an overlay for a bitmap on another
4219
     * Otherwise the mask may be used as an overlay for a bitmap on another
4005
     * button below the mask.
4220
     * button below the mask.
4006
     */
4221
     */
4007
    if (!sr[instance].mi.empty() && sr[instance].bs.empty())       // Chameleon image?
4222
    if ((!tp5 && !sr[instance].mi.empty() && sr[instance].bs.empty()) || (tp5 && !sr[instance].mi.empty()))       // Chameleon image?
4008
    {
4223
    {
-
 
4224
        if (tp5)
-
 
4225
        {
-
 
4226
            if (sr[instance].bitmaps.size() > 0)
4009
        MSG_DEBUG("Chameleon image consisting of mask " << sr[instance].mi << " and bitmap " << (sr[instance].bm.empty() ? "NONE" : sr[instance].bm) << " ...");
4227
                bmFile = sr[instance].bitmaps[0].fileName;
-
 
4228
        }
-
 
4229
        else
-
 
4230
            bmFile = sr[instance].bm;
4010
 
4231
 
-
 
4232
        MSG_DEBUG("Chameleon image consisting of mask " << sr[instance].mi << " and bitmap " << (bmFile.empty() ? "NONE" : bmFile) << " ...");
4011
        SkBitmap bmMi;
4233
        SkBitmap bmMi;
4012
        SkBitmap bmBm;
4234
        SkBitmap bmBm;
4013
 
4235
 
4014
        if (!TImgCache::getBitmap(sr[instance].mi, &bmMi, _BMTYPE_CHAMELEON, &sr[instance].mi_width, &sr[instance].mi_height))
4236
        if (!TImgCache::getBitmap(sr[instance].mi, &bmMi, _BMTYPE_CHAMELEON, &sr[instance].mi_width, &sr[instance].mi_height))
4015
        {
4237
        {
Line 4039... Line 4261...
4039
 
4261
 
4040
        MSG_DEBUG("Chameleon image size: " << bmMi.info().width() << " x " << bmMi.info().height());
4262
        MSG_DEBUG("Chameleon image size: " << bmMi.info().width() << " x " << bmMi.info().height());
4041
        SkBitmap imgRed(bmMi);
4263
        SkBitmap imgRed(bmMi);
4042
        SkBitmap imgMask;
4264
        SkBitmap imgMask;
4043
        bool haveBothImages = true;
4265
        bool haveBothImages = true;
-
 
4266
        // On TP5:
-
 
4267
        // If we have a chameleon image the base is in field "mi", as it was it TP4 already,
-
 
4268
        // and the first image in the list of images is the mask. This means that we must
-
 
4269
        // first create the chameleon image out of this images the same as we did for TP4.
-
 
4270
        // The other images, if there any, will be put on top of the chameleon image.
4044
 
4271
 
4045
        if (!sr[instance].bm.empty() || (TTPInit::getTP5() && !sr[instance].bitmaps.empty()))
4272
        if (!bmFile.empty())
4046
        {
4273
        {
4047
            if (TTPInit::getTP5())
4274
            if (!TImgCache::getBitmap(bmFile, &bmBm, _BMTYPE_BITMAP, &sr[instance].bm_width, &sr[instance].bm_height))
4048
            {
4275
            {
4049
                if (!buttonBitmap5(&bmBm, instance))
4276
                sk_sp<SkData> data = readImage(bmFile);
4050
                    haveBothImages = false;
4277
                bool loaded = false;
-
 
4278
 
4051
                else
4279
                if (data)
4052
                {
4280
                {
4053
                    sr[instance].bm_width = bm->info().width();
4281
                    DecodeDataToBitmap(data, &bmBm);
4054
                    sr[instance].bm_height = bm->info().height();
-
 
4055
 
4282
 
4056
                    if (!imgMask.installPixels(bmBm.pixmap()))
4283
                    if (!bmBm.empty())
4057
                    {
4284
                    {
4058
                        MSG_ERROR("Error installing pixmap " << sr[instance].bm << " for chameleon image!");
-
 
4059
 
-
 
4060
                        if (!allocPixels(imgRed.info().width(), imgRed.info().height(), &imgMask))
4285
                        TImgCache::addImage(bmFile, bmBm, _BMTYPE_BITMAP);
4061
                            return false;
4286
                        loaded = true;
4062
 
-
 
4063
                        imgMask.eraseColor(SK_ColorTRANSPARENT);
4287
                        sr[instance].bm_width = bmBm.info().width();
4064
                        haveBothImages = false;
4288
                        sr[instance].bm_height = bmBm.info().height();
4065
                    }
4289
                    }
4066
                }
4290
                }
-
 
4291
 
-
 
4292
                if (!loaded)
-
 
4293
                {
-
 
4294
                    MSG_ERROR("Missing image " << bmFile << "!");
-
 
4295
                    TError::setError();
-
 
4296
                    return false;
-
 
4297
                }
4067
            }
4298
            }
-
 
4299
/*
-
 
4300
            if (!buttonBitmap5(&bmBm, instance))
-
 
4301
                haveBothImages = false;
4068
            else
4302
            else
4069
            {
4303
            {
4070
                if (!TImgCache::getBitmap(sr[instance].bm, &bmBm, _BMTYPE_BITMAP, &sr[instance].bm_width, &sr[instance].bm_height))
-
 
4071
                {
-
 
4072
                    sk_sp<SkData> data = readImage(sr[instance].bm);
4304
                sr[instance].bm_width = bm->info().width();
4073
                    bool loaded = false;
-
 
4074
 
-
 
4075
                    if (data)
-
 
4076
                    {
-
 
4077
                        DecodeDataToBitmap(data, &bmBm);
4305
                sr[instance].bm_height = bm->info().height();
4078
 
4306
 
4079
                        if (!bmBm.empty())
-
 
4080
                        {
-
 
4081
                            TImgCache::addImage(sr[instance].bm, bmBm, _BMTYPE_BITMAP);
-
 
4082
                            loaded = true;
-
 
4083
                            sr[instance].bm_width = bmBm.info().width();
-
 
4084
                            sr[instance].bm_height = bmBm.info().height();
-
 
4085
                        }
-
 
4086
                    }
-
 
4087
 
-
 
4088
                    if (!loaded)
-
 
4089
                    {
-
 
4090
                        MSG_ERROR("Missing image " << sr[instance].bm << "!");
-
 
4091
                        TError::setError();
-
 
4092
                        return false;
-
 
4093
                    }
-
 
4094
                }
-
 
4095
 
-
 
4096
                if (!bmBm.empty())
4307
                if (!imgMask.installPixels(bmBm.pixmap()))
4097
                {
4308
                {
4098
                    if (!imgMask.installPixels(bmBm.pixmap()))
-
 
4099
                    {
-
 
4100
                        MSG_ERROR("Error installing pixmap " << sr[instance].bm << " for chameleon image!");
4309
                    MSG_ERROR("Error installing pixmap " << sr[instance].bm << " for chameleon image!");
4101
 
4310
 
4102
                        if (!allocPixels(imgRed.info().width(), imgRed.info().height(), &imgMask))
4311
                    if (!allocPixels(imgRed.info().width(), imgRed.info().height(), &imgMask))
4103
                            return false;
4312
                        return false;
4104
 
4313
 
4105
                        imgMask.eraseColor(SK_ColorTRANSPARENT);
4314
                    imgMask.eraseColor(SK_ColorTRANSPARENT);
4106
                        haveBothImages = false;
4315
                    haveBothImages = false;
4107
                    }
-
 
4108
                }
4316
                }
4109
                else
4317
            }
-
 
4318
*/
-
 
4319
 
-
 
4320
            if (!bmBm.empty())
-
 
4321
            {
-
 
4322
                if (!imgMask.installPixels(bmBm.pixmap()))
4110
                {
4323
                {
4111
                    MSG_WARNING("No or invalid bitmap! Ignoring bitmap for cameleon image.");
4324
                    MSG_ERROR("Error installing pixmap " << bmFile << " for chameleon image!");
4112
 
4325
 
4113
                    if (!allocPixels(imgRed.info().width(), imgRed.info().height(), &imgMask))
4326
                    if (!allocPixels(imgRed.info().width(), imgRed.info().height(), &imgMask))
4114
                        return false;
4327
                        return false;
4115
 
4328
 
4116
                    imgMask.eraseColor(SK_ColorTRANSPARENT);
4329
                    imgMask.eraseColor(SK_ColorTRANSPARENT);
4117
                    haveBothImages = false;
4330
                    haveBothImages = false;
4118
                }
4331
                }
4119
            }
4332
            }
-
 
4333
            else
-
 
4334
            {
-
 
4335
                MSG_WARNING("No or invalid bitmap! Ignoring bitmap for cameleon image.");
-
 
4336
 
-
 
4337
                if (!allocPixels(imgRed.info().width(), imgRed.info().height(), &imgMask))
-
 
4338
                    return false;
-
 
4339
 
-
 
4340
                imgMask.eraseColor(SK_ColorTRANSPARENT);
-
 
4341
                haveBothImages = false;
-
 
4342
            }
4120
        }
4343
        }
4121
        else
4344
        else
4122
            haveBothImages = false;
4345
            haveBothImages = false;
4123
 
4346
 
4124
        MSG_DEBUG("Bitmap image size: " << bmBm.info().width() << " x " << bmBm.info().height());
4347
        MSG_DEBUG("Bitmap image size: " << bmBm.info().width() << " x " << bmBm.info().height());
4125
        MSG_DEBUG("Bitmap mask size: " << imgMask.info().width() << " x " << imgMask.info().height());
4348
        MSG_DEBUG("Bitmap mask size: " << imgMask.info().width() << " x " << imgMask.info().height());
4126
        SkBitmap img = drawImageButton(imgRed, imgMask, sr[instance].mi_width, sr[instance].mi_height, TColor::getSkiaColor(sr[instance].cf), TColor::getSkiaColor(sr[instance].cb));
4349
        SkBitmap img = drawImageButton(imgRed, imgMask, sr[instance].mi_width, sr[instance].mi_height, TColor::getSkiaColor(sr[instance].cf), TColor::getSkiaColor(sr[instance].cb));
4127
 
4350
 
4128
        if (img.empty())
4351
        if (img.empty())
4129
        {
4352
        {
4130
            MSG_ERROR("Error creating the cameleon image \"" << sr[instance].mi << "\" / \"" << sr[instance].bm << "\"!");
4353
            MSG_ERROR("Error creating the cameleon image \"" << sr[instance].mi << "\" / \"" << bmFile << "\"!");
4131
            TError::setError();
4354
            TError::setError();
4132
            return false;
4355
            return false;
4133
        }
4356
        }
4134
 
4357
 
4135
        MSG_DEBUG("Have both images: " << (haveBothImages ? "YES" : "NO"));
4358
        MSG_DEBUG("Have both images: " << (haveBothImages ? "YES" : "NO"));
Line 4157... Line 4380...
4157
            if (!haveBothImages)
4380
            if (!haveBothImages)
4158
            {
4381
            {
4159
                sk_sp<SkImage> _image = SkImages::RasterFromBitmap(img);
4382
                sk_sp<SkImage> _image = SkImages::RasterFromBitmap(img);
4160
                can.drawImage(_image, 0, 0, SkSamplingOptions(), &paint);
4383
                can.drawImage(_image, 0, 0, SkSamplingOptions(), &paint);
4161
 
4384
 
4162
                if (!sr[instance].bm.empty())
4385
                if (!bmFile.empty())
4163
                {
4386
                {
4164
                    imgMask.installPixels(bmBm.pixmap());
4387
                    imgMask.installPixels(bmBm.pixmap());
4165
                    paint.setBlendMode(SkBlendMode::kSrcOver);
4388
                    paint.setBlendMode(SkBlendMode::kSrcOver);
4166
                    _image = SkImages::RasterFromBitmap(imgMask);
4389
                    _image = SkImages::RasterFromBitmap(imgMask);
4167
                    can.drawImage(_image, position.left, position.top, SkSamplingOptions(), &paint);
4390
                    can.drawImage(_image, position.left, position.top, SkSamplingOptions(), &paint);
Line 4169... Line 4392...
4169
            }
4392
            }
4170
            else
4393
            else
4171
            {
4394
            {
4172
                sk_sp<SkImage> _image = SkImages::RasterFromBitmap(img);
4395
                sk_sp<SkImage> _image = SkImages::RasterFromBitmap(img);
4173
                can.drawImage(_image, position.left, position.top, SkSamplingOptions(), &paint);
4396
                can.drawImage(_image, position.left, position.top, SkSamplingOptions(), &paint);
-
 
4397
                // On TP5 we must draw the other images, if there are any, on top of the one we have already.
-
 
4398
                if (!buttonBitmap5(bm, instance, true))
-
 
4399
                {
-
 
4400
                    MSG_WARNING("Couldn't draw all bitmaps!");
-
 
4401
                }
4174
            }
4402
            }
4175
        }
4403
        }
4176
        else    // Scale to fit
4404
        else    // Scale to fit
4177
        {
4405
        {
4178
            if (!haveBothImages)
4406
            if (!haveBothImages)
Line 4180... Line 4408...
4180
                SkRect rect;
4408
                SkRect rect;
4181
                rect.setXYWH(0, 0, imgRed.info().width(), imgRed.info().height());
4409
                rect.setXYWH(0, 0, imgRed.info().width(), imgRed.info().height());
4182
                sk_sp<SkImage> im = SkImages::RasterFromBitmap(img);
4410
                sk_sp<SkImage> im = SkImages::RasterFromBitmap(img);
4183
                can.drawImageRect(im, rect, SkSamplingOptions(), &paint);
4411
                can.drawImageRect(im, rect, SkSamplingOptions(), &paint);
4184
 
4412
 
4185
                if (!sr[instance].bm.empty())
4413
                if (!bmFile.empty())
4186
                {
4414
                {
4187
                    imgMask.installPixels(bmBm.pixmap());
4415
                    imgMask.installPixels(bmBm.pixmap());
4188
                    rect.setXYWH(position.left, position.top, position.width, position.height);
4416
                    rect.setXYWH(position.left, position.top, position.width, position.height);
4189
                    im = SkImages::RasterFromBitmap(imgMask);
4417
                    im = SkImages::RasterFromBitmap(imgMask);
4190
                    paint.setBlendMode(SkBlendMode::kSrcOver);
4418
                    paint.setBlendMode(SkBlendMode::kSrcOver);
Line 4194... Line 4422...
4194
            else
4422
            else
4195
            {
4423
            {
4196
                SkRect rect = SkRect::MakeXYWH(position.left, position.top, position.width, position.height);
4424
                SkRect rect = SkRect::MakeXYWH(position.left, position.top, position.width, position.height);
4197
                sk_sp<SkImage> im = SkImages::RasterFromBitmap(img);
4425
                sk_sp<SkImage> im = SkImages::RasterFromBitmap(img);
4198
                can.drawImageRect(im, rect, SkSamplingOptions(), &paint);
4426
                can.drawImageRect(im, rect, SkSamplingOptions(), &paint);
-
 
4427
                // On TP5 we must draw the other images, if there are any, on top of the one we have already.
-
 
4428
                if (!buttonBitmap5(bm, instance, true))
-
 
4429
                {
-
 
4430
                    MSG_WARNING("Couldn't draw all bitmaps!");
-
 
4431
                }
4199
            }
4432
            }
4200
        }
4433
        }
4201
    }
4434
    }
4202
    else if (!sr[instance].bm.empty())
4435
    else if (!tp5 && !sr[instance].bm.empty())
4203
    {
4436
    {
4204
        MSG_TRACE("Drawing normal image " << sr[instance].bm << " ...");
4437
        MSG_TRACE("Drawing normal image " << sr[instance].bm << " ...");
4205
 
4438
 
4206
        SkBitmap image;
4439
        SkBitmap image;
4207
 
4440
 
Line 4287... Line 4520...
4287
            SkRect rect = SkRect::MakeXYWH(position.left, position.top, isize.width, isize.height);
4520
            SkRect rect = SkRect::MakeXYWH(position.left, position.top, isize.width, isize.height);
4288
            sk_sp<SkImage> im = SkImages::RasterFromBitmap(image);
4521
            sk_sp<SkImage> im = SkImages::RasterFromBitmap(image);
4289
            can.drawImageRect(im, rect, SkSamplingOptions(), &paint);
4522
            can.drawImageRect(im, rect, SkSamplingOptions(), &paint);
4290
        }
4523
        }
4291
    }
4524
    }
-
 
4525
    else if (tp5 && sr[instance].bitmaps.size() > 0)    // TP5: Put all images together
-
 
4526
    {
-
 
4527
        MSG_TRACE("Draw TP5 image stack.");
-
 
4528
 
-
 
4529
        vector<BITMAPS_t>::iterator bmIter;
-
 
4530
 
-
 
4531
        for (bmIter = sr[instance].bitmaps.begin(); bmIter != sr[instance].bitmaps.end(); ++bmIter)
-
 
4532
        {
-
 
4533
            SkBitmap image;
-
 
4534
 
-
 
4535
            if (!TImgCache::getBitmap(bmIter->fileName, &image, _BMTYPE_BITMAP, &bmIter->width, &bmIter->height))
-
 
4536
            {
-
 
4537
                sk_sp<SkData> data = readImage(sr[instance].bm);
-
 
4538
                bool loaded = false;
-
 
4539
 
-
 
4540
                if (data)
-
 
4541
                {
-
 
4542
                    DecodeDataToBitmap(data, &image);
-
 
4543
 
-
 
4544
                    if (!image.empty())
-
 
4545
                    {
-
 
4546
                        TImgCache::addImage(bmIter->fileName, image, _BMTYPE_BITMAP);
-
 
4547
                        loaded = true;
-
 
4548
                        bmIter->width = image.info().width();
-
 
4549
                        bmIter->height = image.info().height();
-
 
4550
                    }
-
 
4551
                }
-
 
4552
 
-
 
4553
                if (!loaded)
-
 
4554
                {
-
 
4555
                    MSG_ERROR("Missing image " << bmIter->fileName << "!");
-
 
4556
                    continue;        // We want the button even without an image
-
 
4557
                }
-
 
4558
            }
-
 
4559
 
-
 
4560
            if (image.empty())
-
 
4561
            {
-
 
4562
                MSG_ERROR("Error creating the image \"" << bmIter->fileName << "\"!");
-
 
4563
                continue;
-
 
4564
            }
-
 
4565
 
-
 
4566
            IMAGE_SIZE_t isize = calcImageSize(image.info().width(), image.info().height(), instance, true);
-
 
4567
            POSITION_t position = calcImagePosition((sr[instance].sb ? isize.width : image.info().width()), (sr[instance].sb ? isize.height : image.info().height()), SC_BITMAP, instance);
-
 
4568
 
-
 
4569
            if (!position.valid)
-
 
4570
            {
-
 
4571
                MSG_ERROR("Error calculating the position of the image for button number " << bi);
-
 
4572
                continue;
-
 
4573
            }
-
 
4574
 
-
 
4575
            MSG_DEBUG("Putting bitmap on top of image ...");
-
 
4576
            SkPaint paint;
-
 
4577
            paint.setBlendMode(SkBlendMode::kSrcOver);
-
 
4578
            SkCanvas can(*bm, SkSurfaceProps());
-
 
4579
 
-
 
4580
            if (sr[instance].sb == 0)   // Scale bitmap?
-
 
4581
            {                           // No, keep size
-
 
4582
                if ((bmIter->justification == ORI_ABSOLUT && bmIter->offsetX >= 0 && bmIter->offsetY >= 0) || bmIter->justification != ORI_ABSOLUT)  // Draw the full image
-
 
4583
                {
-
 
4584
                    sk_sp<SkImage> _image = SkImages::RasterFromBitmap(image);
-
 
4585
                    can.drawImage(_image, position.left, position.top, SkSamplingOptions(), &paint);
-
 
4586
                }
-
 
4587
                else    // We need only a subset of the image
-
 
4588
                {
-
 
4589
                    MSG_DEBUG("Create a subset of an image ...");
-
 
4590
 
-
 
4591
                    // Create a new Info to have the size of the subset.
-
 
4592
                    SkImageInfo info = SkImageInfo::Make(position.width, position.height, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
-
 
4593
                    size_t byteSize = info.computeMinByteSize();
-
 
4594
 
-
 
4595
                    if (byteSize == 0)
-
 
4596
                    {
-
 
4597
                        MSG_ERROR("Unable to calculate size of image!");
-
 
4598
                        continue;
-
 
4599
                    }
-
 
4600
 
-
 
4601
                    MSG_DEBUG("Rectangle of part: x: " << position.left << ", y: " << position.top << ", w: " << position.width << ", h: " << position.height);
-
 
4602
                    SkBitmap part;      // Bitmap receiving the wanted part from the whole image
-
 
4603
                    SkIRect irect = SkIRect::MakeXYWH(position.left, position.top, position.width, position.height);
-
 
4604
                    image.extractSubset(&part, irect);  // Extract the part of the image containg the pixels we want
-
 
4605
                    sk_sp<SkImage> _image = SkImages::RasterFromBitmap(part);
-
 
4606
                    can.drawImage(_image, 0, 0, SkSamplingOptions(), &paint); // Draw the image
-
 
4607
                }
-
 
4608
            }
-
 
4609
            else    // Scale to fit
-
 
4610
            {
-
 
4611
                SkRect rect = SkRect::MakeXYWH(position.left, position.top, isize.width, isize.height);
-
 
4612
                sk_sp<SkImage> im = SkImages::RasterFromBitmap(image);
-
 
4613
                can.drawImageRect(im, rect, SkSamplingOptions(), &paint);
-
 
4614
            }
-
 
4615
        }
-
 
4616
    }
4292
    else
4617
    else
4293
    {
4618
    {
4294
        MSG_DEBUG("No bitmap defined.");
4619
        MSG_DEBUG("No bitmap defined.");
4295
    }
4620
    }
4296
 
4621
 
Line 4303... Line 4628...
4303
 * The result could be combinated with an chameleon image, if there is one.
4628
 * The result could be combinated with an chameleon image, if there is one.
4304
 *
4629
 *
4305
 * @param bm        A pointer to the bitmap where the result shuld be drawn.
4630
 * @param bm        A pointer to the bitmap where the result shuld be drawn.
4306
 *                  This pointer must not be NULL.
4631
 *                  This pointer must not be NULL.
4307
 * @param instances The instance where the bitmaps should be taken from.
4632
 * @param instances The instance where the bitmaps should be taken from.
-
 
4633
 * @param ignFirst  TRUE = the 1st image in list is ignored.
-
 
4634
 * @return TRUE on success
4308
 */
4635
 */
4309
bool TButton::buttonBitmap5(SkBitmap* bm, int instance)
4636
bool TButton::buttonBitmap5(SkBitmap* bm, int instance, bool ignFirst)
4310
{
4637
{
4311
    DECL_TRACER("TButton::buttonBitmap5(SkBitmap* bm, int instance)");
4638
    DECL_TRACER("TButton::buttonBitmap5(SkBitmap* bm, int instance, bool ignFirst)");
4312
 
4639
 
4313
    if (!bm)
4640
    if (!bm)
4314
    {
4641
    {
4315
        MSG_WARNING("Method parameter was NULL!");
4642
        MSG_WARNING("Method parameter was NULL!");
4316
        return false;
4643
        return false;
Line 4318... Line 4645...
4318
 
4645
 
4319
    if (sr[instance].bitmaps.empty())
4646
    if (sr[instance].bitmaps.empty())
4320
        return true;
4647
        return true;
4321
 
4648
 
4322
    vector<BITMAPS_t>::iterator iter;
4649
    vector<BITMAPS_t>::iterator iter;
-
 
4650
    bool first = true;
4323
 
4651
 
4324
    for (iter = sr[instance].bitmaps.begin(); iter != sr[instance].bitmaps.end(); ++iter)
4652
    for (iter = sr[instance].bitmaps.begin(); iter != sr[instance].bitmaps.end(); ++iter)
4325
    {
4653
    {
-
 
4654
        if (ignFirst && first)
-
 
4655
        {
-
 
4656
            first = false;
-
 
4657
            continue;
-
 
4658
        }
-
 
4659
 
4326
        SkBitmap bmBm;
4660
        SkBitmap bmBm;
4327
        int width, height;
4661
        int width, height;
4328
 
4662
 
4329
        if (!TImgCache::getBitmap(iter->fileName, &bmBm, _BMTYPE_BITMAP, &width, &height))
4663
        if (!TImgCache::getBitmap(iter->fileName, &bmBm, _BMTYPE_BITMAP, &width, &height))
4330
        {
4664
        {
Line 6436... Line 6770...
6436
                setScreenDone();
6770
                setScreenDone();
6437
#endif
6771
#endif
6438
                return false;
6772
                return false;
6439
            }
6773
            }
6440
        }
6774
        }
6441
        else if (!TTPInit::getTP5() && mDOrder[i] == ORD_ELEM_ICON)
6775
        else if (!TTPInit::isTP5() && mDOrder[i] == ORD_ELEM_ICON)
6442
        {
6776
        {
6443
            if (!buttonIcon(&imgButton, instance))
6777
            if (!buttonIcon(&imgButton, instance))
6444
            {
6778
            {
6445
#if TESTMODE == 1
6779
#if TESTMODE == 1
6446
                setScreenDone();
6780
                setScreenDone();
Line 10308... Line 10642...
10308
        MSG_DEBUG("Executing a push function ...");
10642
        MSG_DEBUG("Executing a push function ...");
10309
        vector<PUSH_FUNC_T>::iterator iter;
10643
        vector<PUSH_FUNC_T>::iterator iter;
10310
 
10644
 
10311
        for (iter = pushFunc.begin(); iter != pushFunc.end(); ++iter)
10645
        for (iter = pushFunc.begin(); iter != pushFunc.end(); ++iter)
10312
        {
10646
        {
10313
            MSG_DEBUG("Testing for function \"" << iter->pfType << "\"");
-
 
10314
 
-
 
10315
            if (fb == FB_MOMENTARY || fb == FB_NONE)
10647
            if (fb == FB_MOMENTARY || fb == FB_NONE)
10316
                mActInstance = 0;
10648
                mActInstance = 0;
10317
            else if (fb == FB_ALWAYS_ON || fb == FB_INV_CHANNEL)
10649
            else if (fb == FB_ALWAYS_ON || fb == FB_INV_CHANNEL)
10318
                mActInstance = 1;
10650
                mActInstance = 1;
10319
 
10651
 
10320
            if (strCaseCompare(iter->pfType, "SSHOW") == 0)            // show popup
-
 
10321
            {
-
 
10322
                if (gPageManager)
-
 
10323
                    gPageManager->showSubPage(iter->pfName);
10652
            if (!TTPInit::isTP5() || iter->action == BT_ACTION_PGFLIP)
10324
            }
-
 
10325
            else if (strCaseCompare(iter->pfType, "SHIDE") == 0)       // hide popup
-
 
10326
            {
10653
            {
10327
                if (gPageManager)
-
 
10328
                    gPageManager->hideSubPage(iter->pfName);
-
 
10329
            }
-
 
10330
            else if (strCaseCompare(iter->pfType, "SCGROUP") == 0)     // hide group
-
 
10331
            {
-
 
10332
                if (gPageManager)
-
 
10333
                    gPageManager->closeGroup(iter->pfName);
10654
                MSG_DEBUG("Testing for function \"" << iter->pfType << "\"");
10334
            }
10655
 
10335
            else if (strCaseCompare(iter->pfType, "SCPAGE") == 0)      // flip to page
10656
                if (strCaseCompare(iter->pfType, "SSHOW") == 0)            // show popup
10336
            {
-
 
10337
                if (gPageManager && !iter->pfName.empty())
-
 
10338
                    gPageManager->setPage(iter->pfName);
-
 
10339
            }
-
 
10340
            else if (strCaseCompare(iter->pfType, "STAN") == 0)        // Flip to standard page
-
 
10341
            {
-
 
10342
                if (gPageManager)
-
 
10343
                {
10657
                {
-
 
10658
                    if (gPageManager)
-
 
10659
                        gPageManager->showSubPage(iter->pfName);
-
 
10660
                }
-
 
10661
                else if (strCaseCompare(iter->pfType, "SHIDE") == 0)       // hide popup
-
 
10662
                {
-
 
10663
                    if (gPageManager)
-
 
10664
                        gPageManager->hideSubPage(iter->pfName);
-
 
10665
                }
-
 
10666
                else if (strCaseCompare(iter->pfType, "SCGROUP") == 0)     // hide group
-
 
10667
                {
-
 
10668
                    if (gPageManager)
-
 
10669
                        gPageManager->closeGroup(iter->pfName);
-
 
10670
                }
-
 
10671
                else if (strCaseCompare(iter->pfType, "SCPAGE") == 0)      // flip to page
-
 
10672
                {
10344
                    if (!iter->pfName.empty())
10673
                    if (gPageManager && !iter->pfName.empty())
10345
                        gPageManager->setPage(iter->pfName);
10674
                        gPageManager->setPage(iter->pfName);
-
 
10675
                }
-
 
10676
                else if (strCaseCompare(iter->pfType, "STAN") == 0)        // Flip to standard page
10346
                    else
10677
                {
-
 
10678
                    if (gPageManager)
10347
                    {
10679
                    {
-
 
10680
                        if (!iter->pfName.empty())
10348
                        TPage *page = gPageManager->getActualPage();
10681
                            gPageManager->setPage(iter->pfName);
10349
 
-
 
10350
                        if (!page)
10682
                        else
10351
                        {
10683
                        {
-
 
10684
                            TPage *page = gPageManager->getActualPage();
-
 
10685
 
-
 
10686
                            if (!page)
-
 
10687
                            {
10352
                            MSG_DEBUG("Internal error: No actual page found!");
10688
                                MSG_DEBUG("Internal error: No actual page found!");
10353
                            return false;
10689
                                return false;
10354
                        }
10690
                            }
10355
 
10691
 
10356
                        TSettings *settings = gPageManager->getSettings();
10692
                            TSettings *settings = gPageManager->getSettings();
10357
 
10693
 
10358
                        if (settings && settings->getPowerUpPage().compare(page->getName()) != 0)
10694
                            if (settings && settings->getPowerUpPage().compare(page->getName()) != 0)
10359
                            gPageManager->setPage(settings->getPowerUpPage());
10695
                                gPageManager->setPage(settings->getPowerUpPage());
-
 
10696
                        }
10360
                    }
10697
                    }
10361
                }
10698
                }
10362
            }
-
 
10363
            else if (strCaseCompare(iter->pfType, "FORGET") == 0)      // Flip to page and forget
10699
                else if (strCaseCompare(iter->pfType, "FORGET") == 0)      // Flip to page and forget
10364
            {
-
 
10365
                if (gPageManager && !iter->pfName.empty())
-
 
10366
                        gPageManager->setPage(iter->pfName, true);
-
 
10367
            }
-
 
10368
            else if (strCaseCompare(iter->pfType, "PREV") == 0)        // Flip to previous page
-
 
10369
            {
-
 
10370
                if (gPageManager)
-
 
10371
                {
10700
                {
10372
                    int old = gPageManager->getPreviousPageNumber();
10701
                    if (gPageManager && !iter->pfName.empty())
10373
 
-
 
10374
                    if (old > 0)
-
 
10375
                        gPageManager->setPage(old);
10702
                            gPageManager->setPage(iter->pfName, true);
10376
                }
10703
                }
10377
            }
-
 
10378
            else if (strCaseCompare(iter->pfType, "STOGGLE") == 0)     // Toggle popup state
10704
                else if (strCaseCompare(iter->pfType, "PREV") == 0)        // Flip to previous page
10379
            {
-
 
10380
                if (!iter->pfName.empty() && gPageManager)
-
 
10381
                {
10705
                {
-
 
10706
                    if (gPageManager)
-
 
10707
                    {
10382
                    TSubPage *page = gPageManager->getSubPage(iter->pfName);
10708
                        int old = gPageManager->getPreviousPageNumber();
10383
 
10709
 
10384
                    if (!page)      // Is the page not in cache?
-
 
10385
                    {               // No, then load it
10710
                        if (old > 0)
10386
                        gPageManager->showSubPage(iter->pfName);
10711
                            gPageManager->setPage(old);
10387
                        return true;
-
 
10388
                    }
10712
                    }
10389
 
-
 
10390
                    if (page->isVisible())
-
 
10391
                        gPageManager->hideSubPage(iter->pfName);
-
 
10392
                    else
-
 
10393
                        gPageManager->showSubPage(iter->pfName);
-
 
10394
                }
10713
                }
10395
            }
-
 
10396
            else if (strCaseCompare(iter->pfType, "SCPANEL") == 0)   // Hide all popups
10714
                else if (strCaseCompare(iter->pfType, "STOGGLE") == 0)     // Toggle popup state
10397
            {
-
 
10398
                if (gPageManager)
-
 
10399
                {
10715
                {
-
 
10716
                    if (!iter->pfName.empty() && gPageManager)
-
 
10717
                    {
10400
                    TSubPage *page = gPageManager->getFirstSubPage();
10718
                        TSubPage *page = gPageManager->getSubPage(iter->pfName);
-
 
10719
 
-
 
10720
                        if (!page)      // Is the page not in cache?
-
 
10721
                        {               // No, then load it
-
 
10722
                            gPageManager->showSubPage(iter->pfName);
-
 
10723
                            return true;
-
 
10724
                        }
10401
 
10725
 
-
 
10726
                        if (page->isVisible())
-
 
10727
                            gPageManager->hideSubPage(iter->pfName);
10402
                    while (page)
10728
                        else
-
 
10729
                            gPageManager->showSubPage(iter->pfName);
-
 
10730
                    }
-
 
10731
                }
-
 
10732
                else if (strCaseCompare(iter->pfType, "SCPANEL") == 0)   // Hide all popups
-
 
10733
                {
-
 
10734
                    if (gPageManager)
10403
                    {
10735
                    {
-
 
10736
                        TSubPage *page = gPageManager->getFirstSubPage();
-
 
10737
 
-
 
10738
                        while (page)
-
 
10739
                        {
10404
                        page->drop();
10740
                            page->drop();
10405
                        page = gPageManager->getNextSubPage();
10741
                            page = gPageManager->getNextSubPage();
-
 
10742
                        }
10406
                    }
10743
                    }
10407
                }
10744
                }
-
 
10745
                else
-
 
10746
                {
-
 
10747
                    MSG_WARNING("Unknown page flip command " << iter->pfType);
-
 
10748
                }
10408
            }
10749
            }
10409
            else
10750
            else if (iter->action == BT_ACTION_LAUNCH)
10410
            {
10751
            {
-
 
10752
#ifdef __ANDROID__
-
 
10753
                MSG_DEBUG("Launching the external program " << iter->pfName << "...");
-
 
10754
#else
-
 
10755
 
10411
                MSG_WARNING("Unknown page flip command " << iter->pfType);
10756
                MSG_DEBUG("Launching the external program " << iter->pfName << "...");
-
 
10757
                TLauncher::launch(iter->pfName);
-
 
10758
#endif  // __ANDROID__
10412
            }
10759
            }
10413
        }
10760
        }
10414
    }
10761
    }
10415
 
10762
 
10416
    if (!cm.empty() && co == 0 && pressed)      // Feed command to ourself?
10763
    if (!cm.empty() && co == 0 && pressed)      // Feed command to ourself?
Line 11068... Line 11415...
11068
    TButtonStates *s = gPageManager->getButtonState(type, mButtonID);
11415
    TButtonStates *s = gPageManager->getButtonState(type, mButtonID);
11069
    MSG_DEBUG("Found button ID: " << getButtonIDstr(s->getID()) << ", type: " << buttonTypeToString(s->getType()) << ", lastLevel: " << s->getLastLevel() << ", lastJoyX: " << s->getLastJoyX() << ", lasJoyY: " << s->getLastJoyY());
11416
    MSG_DEBUG("Found button ID: " << getButtonIDstr(s->getID()) << ", type: " << buttonTypeToString(s->getType()) << ", lastLevel: " << s->getLastLevel() << ", lastJoyX: " << s->getLastJoyX() << ", lasJoyY: " << s->getLastJoyY());
11070
    return s;
11417
    return s;
11071
}
11418
}
11072
 
11419
 
-
 
11420
bool TButton::isButtonEvent(const string& token, const vector<string>& events)
-
 
11421
{
-
 
11422
    DECL_TRACER("TButton::isButtonEvent(const string& token, const vector<string>& events)");
-
 
11423
 
-
 
11424
    if (events.empty() || token.empty())
-
 
11425
        return false;
-
 
11426
 
-
 
11427
    vector<string>::const_iterator iter;
-
 
11428
 
-
 
11429
    for (iter = events.cbegin(); iter != events.cend(); ++iter)
-
 
11430
    {
-
 
11431
        if (*iter == token)
-
 
11432
            return true;
-
 
11433
    }
-
 
11434
 
-
 
11435
    return false;
-
 
11436
}
-
 
11437
 
-
 
11438
BUTTON_EVENT_t TButton::getButtonEvent(const string& token)
-
 
11439
{
-
 
11440
    DECL_TRACER("TButton::getButtonEvent(const string& token)");
-
 
11441
 
-
 
11442
    if (token == "ga")
-
 
11443
        return EVENT_GUESTURE_ANY;
-
 
11444
    else if (token == "gu")
-
 
11445
        return EVENT_GUESTURE_UP;
-
 
11446
    else if (token == "gd")
-
 
11447
        return EVENT_GUESTURE_DOWN;
-
 
11448
    else if (token == "gr")
-
 
11449
        return EVENT_GUESTURE_RIGHT;
-
 
11450
    else if (token == "gl")
-
 
11451
        return EVENT_GUESTURE_LEFT;
-
 
11452
    else if (token == "gt")
-
 
11453
        return EVENT_GUESTURE_DBLTAP;
-
 
11454
    else if (token == "tu")
-
 
11455
        return EVENT_GUESTURE_2FUP;
-
 
11456
    else if (token == "td")
-
 
11457
        return EVENT_GUESTURE_2FDN;
-
 
11458
    else if (token == "tr")
-
 
11459
        return EVENT_GUESTURE_2FRT;
-
 
11460
    else if (token == "tl")
-
 
11461
        return EVENT_GUESTURE_2FLT;
-
 
11462
 
-
 
11463
    return EVENT_NONE;
-
 
11464
}
-
 
11465
 
11073
int TButton::getLevelValue()
11466
int TButton::getLevelValue()
11074
{
11467
{
11075
    DECL_TRACER("TButton::getLevelValue()");
11468
    DECL_TRACER("TButton::getLevelValue()");
11076
 
11469
 
11077
    TButtonStates *buttonStates = getButtonState();
11470
    TButtonStates *buttonStates = getButtonState();