Subversion Repositories tpanel

Rev

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

Rev 20 Rev 21
Line 48... Line 48...
48
using std::map;
48
using std::map;
49
using std::pair;
49
using std::pair;
50
using std::thread;
50
using std::thread;
51
using std::atomic;
51
using std::atomic;
52
using std::mutex;
52
using std::mutex;
-
 
53
using std::bind;
53
using namespace Button;
54
using namespace Button;
54
 
55
 
-
 
56
#define MAX_BUFFER      65536
-
 
57
 
55
extern TIcons *gIcons;
58
extern TIcons *gIcons;
56
extern amx::TAmxNet *gAmxNet;
59
extern amx::TAmxNet *gAmxNet;
57
 
60
 
58
atomic<bool> TButton::mAniRunning = false;
61
atomic<bool> TButton::mAniRunning;
-
 
62
THR_REFRESH_t *TButton::mThrRefresh = nullptr;
-
 
63
 
59
mutex mutex_button;
64
mutex mutex_button;
60
mutex mutex_bargraph;
65
mutex mutex_bargraph;
61
mutex mutex_sysdraw;
66
mutex mutex_sysdraw;
62
 
67
 
63
SYSBORDER_t sysBorders[] = {
68
SYSBORDER_t sysBorders[] = {
Line 119... Line 124...
119
 
124
 
120
TButton::TButton()
125
TButton::TButton()
121
{
126
{
122
    DECL_TRACER("TButton::TButton()");
127
    DECL_TRACER("TButton::TButton()");
123
 
128
 
-
 
129
    mAniRunning = false;
124
    mLastBlink.clear();
130
    mLastBlink.clear();
125
}
131
}
126
 
132
 
127
TButton::~TButton()
133
TButton::~TButton()
128
{
134
{
Line 160... Line 166...
160
        while (mTimer->isRunning())
166
        while (mTimer->isRunning())
161
            usleep(50);
167
            usleep(50);
162
 
168
 
163
        delete mTimer;
169
        delete mTimer;
164
    }
170
    }
-
 
171
 
-
 
172
    THR_REFRESH_t *next, *p = mThrRefresh;
-
 
173
 
-
 
174
    while (p)
-
 
175
    {
-
 
176
        if (p->mImageRefresh)
-
 
177
        {
-
 
178
            p->mImageRefresh->stop();
-
 
179
 
-
 
180
            while (p->mImageRefresh->isRunning())
-
 
181
                usleep(50);
-
 
182
 
-
 
183
            delete p->mImageRefresh;
-
 
184
            p->mImageRefresh = nullptr;
-
 
185
        }
-
 
186
 
-
 
187
        next = p->next;
-
 
188
        delete p;
-
 
189
        p = next;
-
 
190
    }
165
}
191
}
166
 
192
 
167
void TButton::initialize(TReadXML *xml, mxml_node_t *node)
193
void TButton::initialize(TReadXML *xml, mxml_node_t *node)
168
{
194
{
169
    DECL_TRACER("TButton::initialize(TReadXML *xml, mxml_node_t *node)");
195
    DECL_TRACER("TButton::initialize(TReadXML *xml, mxml_node_t *node)");
Line 404... Line 430...
404
    for (srIter = sr.begin(); srIter != sr.end(); srIter++)
430
    for (srIter = sr.begin(); srIter != sr.end(); srIter++)
405
    {
431
    {
406
        int number = srIter->number;
432
        int number = srIter->number;
407
        IMAGE_t img;
433
        IMAGE_t img;
408
 
434
 
-
 
435
        if (srIter->sb > 0)
-
 
436
            continue;
-
 
437
 
409
        if (!srIter->mi.empty())        // Do we have a chameleon image?
438
        if (!srIter->mi.empty())        // Do we have a chameleon image?
410
        {
439
        {
411
            sk_sp<SkData> image;
440
            sk_sp<SkData> image;
412
 
441
 
413
            if (!(image = readImage(srIter->mi)))
442
            if (!(image = readImage(srIter->mi)))
Line 662... Line 691...
662
    lt = left;
691
    lt = left;
663
    tp = top;
692
    tp = top;
664
    makeElement(mActInstance);
693
    makeElement(mActInstance);
665
}
694
}
666
 
695
 
-
 
696
void TButton::setResourceName(const string& name, int instance)
-
 
697
{
-
 
698
    DECL_TRACER("TButton::setResourceName(const string& name, int instance)");
-
 
699
 
-
 
700
    if (instance < 0 || instance >= (int)sr.size())
-
 
701
    {
-
 
702
        MSG_ERROR("Invalid instance " << instance);
-
 
703
        return;
-
 
704
    }
-
 
705
 
-
 
706
    if (!sr[instance].dynamic)
-
 
707
    {
-
 
708
        MSG_ERROR("Button " << bi << ": " << na << " is not a resource button!");
-
 
709
        return;
-
 
710
    }
-
 
711
 
-
 
712
    sr[instance].bm = name;
-
 
713
}
-
 
714
 
667
bool TButton::setWorWrap(bool state, int instance)
715
bool TButton::setWorWrap(bool state, int instance)
668
{
716
{
669
    DECL_TRACER("TButton::setWorWrap(bool state, int instance)");
717
    DECL_TRACER("TButton::setWorWrap(bool state, int instance)");
670
 
718
 
671
    if (instance < 0 || instance >= (int)sr.size())
719
    if (instance < 0 || instance >= (int)sr.size())
Line 721... Line 769...
721
    }
769
    }
722
 
770
 
723
    funcTimer(mLastBlink);
771
    funcTimer(mLastBlink);
724
}
772
}
725
 
773
 
-
 
774
void TButton::_imageRefresh(const string& url)
-
 
775
{
-
 
776
    DECL_TRACER("TButton::_imageRefresh(const string& url)");
-
 
777
 
-
 
778
    ulong parent = mHandle & 0xffff0000;
-
 
779
    getDrawOrder(sr[mActInstance]._do, (DRAW_ORDER *)&mDOrder);
-
 
780
 
-
 
781
    if (TError::isError())
-
 
782
    {
-
 
783
        TError::clear();
-
 
784
        return;
-
 
785
    }
-
 
786
 
-
 
787
    SkBitmap imgButton;
-
 
788
    imgButton.allocN32Pixels(wt, ht);
-
 
789
 
-
 
790
    for (int i = 0; i < ORD_ELEM_COUNT; i++)
-
 
791
    {
-
 
792
        if (mDOrder[i] == ORD_ELEM_FILL)
-
 
793
        {
-
 
794
            if (!buttonFill(&imgButton, mActInstance))
-
 
795
                return;
-
 
796
        }
-
 
797
        else if (mDOrder[i] == ORD_ELEM_BITMAP)
-
 
798
        {
-
 
799
            RESOURCE_T resource = gPrjResources->findResource(sr[mActInstance].bm);
-
 
800
 
-
 
801
            if (resource.protocol.empty())
-
 
802
            {
-
 
803
                MSG_ERROR("Resource " << sr[mActInstance].bm << " not found!");
-
 
804
                return;
-
 
805
            }
-
 
806
 
-
 
807
            try
-
 
808
            {
-
 
809
                char *content = nullptr;
-
 
810
                size_t length = 0, contentlen = 0;
-
 
811
 
-
 
812
                if ((content = gPrjResources->tcall(&length, url, resource.user, resource.password)) == nullptr)
-
 
813
                    return;
-
 
814
 
-
 
815
                contentlen = gPrjResources->getContentSize();
-
 
816
 
-
 
817
                if (content == nullptr)
-
 
818
                {
-
 
819
                    MSG_ERROR("Server returned no or invalid content!");
-
 
820
                    return;
-
 
821
                }
-
 
822
 
-
 
823
                sk_sp<SkData> data = SkData::MakeWithCopy(content, contentlen);
-
 
824
 
-
 
825
                if (!data)
-
 
826
                {
-
 
827
                    MSG_ERROR("Could not make an image!");
-
 
828
                    return;
-
 
829
                }
-
 
830
 
-
 
831
                SkBitmap image;
-
 
832
 
-
 
833
                if (!DecodeDataToBitmap(data, &image))
-
 
834
                {
-
 
835
                    MSG_ERROR("Error creating an image!");
-
 
836
                    return;
-
 
837
                }
-
 
838
 
-
 
839
                loadImage(&imgButton, image, mActInstance);
-
 
840
            }
-
 
841
            catch (std::exception& e)
-
 
842
            {
-
 
843
                MSG_ERROR(e.what());
-
 
844
                return;
-
 
845
            }
-
 
846
        }
-
 
847
        else if (mDOrder[i] == ORD_ELEM_ICON)
-
 
848
        {
-
 
849
            if (!buttonIcon(&imgButton, mActInstance))
-
 
850
                return;
-
 
851
        }
-
 
852
        else if (mDOrder[i] == ORD_ELEM_TEXT)
-
 
853
        {
-
 
854
            if (!buttonText(&imgButton, mActInstance))
-
 
855
                return;
-
 
856
        }
-
 
857
        else if (mDOrder[i] == ORD_ELEM_BORDER)
-
 
858
        {
-
 
859
            if (!buttonBorder(&imgButton, mActInstance))
-
 
860
                return;
-
 
861
        }
-
 
862
    }
-
 
863
 
-
 
864
    if (mGlobalOO >= 0 || sr[mActInstance].oo >= 0) // Take overall opacity into consideration
-
 
865
    {
-
 
866
        SkBitmap ooButton;
-
 
867
        int w = imgButton.width();
-
 
868
        int h = imgButton.height();
-
 
869
        ooButton.allocN32Pixels(w, h, true);
-
 
870
        SkCanvas canvas(ooButton);
-
 
871
        SkIRect irect = SkIRect::MakeXYWH(0, 0, w, h);
-
 
872
        SkRegion region;
-
 
873
        region.setRect(irect);
-
 
874
        SkScalar oo;
-
 
875
 
-
 
876
        if (mGlobalOO >= 0 && sr[mActInstance].oo >= 0)
-
 
877
        {
-
 
878
            oo = std::min((SkScalar)mGlobalOO, (SkScalar)sr[mActInstance].oo);
-
 
879
            MSG_DEBUG("Set global overal opacity to " << oo);
-
 
880
        }
-
 
881
        else if (sr[mActInstance].oo >= 0)
-
 
882
        {
-
 
883
            oo = (SkScalar)sr[mActInstance].oo;
-
 
884
            MSG_DEBUG("Set overal opacity to " << oo);
-
 
885
        }
-
 
886
        else
-
 
887
        {
-
 
888
            oo = (SkScalar)mGlobalOO;
-
 
889
            MSG_DEBUG("Set global overal opacity to " << oo);
-
 
890
        }
-
 
891
 
-
 
892
        SkScalar alpha = 1.0 / 255.0 * oo;
-
 
893
        MSG_DEBUG("Calculated alpha value: " << alpha);
-
 
894
        SkPaint paint;
-
 
895
        paint.setAlphaf(alpha);
-
 
896
        paint.setImageFilter(SkImageFilters::AlphaThreshold(region, 0.0, alpha, nullptr));
-
 
897
        canvas.drawBitmap(imgButton, 0, 0, &paint);
-
 
898
        imgButton.erase(SK_ColorTRANSPARENT, {0, 0, w, h});
-
 
899
        imgButton = ooButton;
-
 
900
    }
-
 
901
 
-
 
902
    mLastImage = imgButton;
-
 
903
    size_t rowBytes = imgButton.info().minRowBytes();
-
 
904
 
-
 
905
    if (!prg_stopped && visible && _displayButton)
-
 
906
        _displayButton(mHandle, parent, (unsigned char *)imgButton.getPixels(), wt, ht, rowBytes, lt, tp);
-
 
907
}
-
 
908
 
726
void TButton::registerSystemButton()
909
void TButton::registerSystemButton()
727
{
910
{
728
    DECL_TRACER("TButton::registerSystemButton()");
911
    DECL_TRACER("TButton::registerSystemButton()");
729
 
912
 
730
    if (mSystemReg)
913
    if (mSystemReg)
Line 883... Line 1066...
883
 
1066
 
884
bool TButton::buttonBitmap(SkBitmap* bm, int instance)
1067
bool TButton::buttonBitmap(SkBitmap* bm, int instance)
885
{
1068
{
886
    DECL_TRACER("TButton::buttonBitmap(SkBitmap* bm, int instane)");
1069
    DECL_TRACER("TButton::buttonBitmap(SkBitmap* bm, int instane)");
887
 
1070
 
-
 
1071
    if (sr[instance].dynamic)
-
 
1072
        return buttonDynamic(bm, instance);
-
 
1073
 
888
    if (!sr[instance].mi.empty() && !sr[instance].bm.empty())       // Chameleon image?
1074
    if (!sr[instance].mi.empty() && !sr[instance].bm.empty())       // Chameleon image?
889
    {
1075
    {
890
        MSG_TRACE("Chameleon image ...");
1076
        MSG_TRACE("Chameleon image ...");
891
        map<int, IMAGE_t>::iterator iterImages = mImages.find(sr[instance].number);
1077
        map<int, IMAGE_t>::iterator iterImages = mImages.find(sr[instance].number);
892
        SkBitmap imgRed(iterImages->second.imageMi);
1078
        SkBitmap imgRed(iterImages->second.imageMi);
Line 916... Line 1102...
916
            return false;
1102
            return false;
917
        }
1103
        }
918
 
1104
 
919
        SkCanvas can(*bm, SkSurfaceProps(1, kUnknown_SkPixelGeometry));
1105
        SkCanvas can(*bm, SkSurfaceProps(1, kUnknown_SkPixelGeometry));
920
        paint.setBlendMode(SkBlendMode::kSrc);
1106
        paint.setBlendMode(SkBlendMode::kSrc);
-
 
1107
 
-
 
1108
        if (sr[instance].sb == 0)
921
        can.drawBitmap(img, position.left, position.top, &paint);
1109
            can.drawBitmap(img, position.left, position.top, &paint);
-
 
1110
        else    // Scale to fit
-
 
1111
        {
-
 
1112
            SkRect rect = SkRect::MakeXYWH(position.left, position.top, position.width, position.height);
-
 
1113
            sk_sp<SkImage> im = SkImage::MakeFromBitmap(img);
-
 
1114
            can.drawImageRect(im, rect, &paint);
-
 
1115
        }
922
    }
1116
    }
923
    else if (!sr[instance].bm.empty())
1117
    else if (!sr[instance].bm.empty())
924
    {
1118
    {
925
        MSG_TRACE("Drawing normal image ...");
1119
        MSG_TRACE("Drawing normal image ...");
926
        map<int, IMAGE_t>::iterator iterImages = mImages.find(sr[instance].number);
1120
        map<int, IMAGE_t>::iterator iterImages = mImages.find(sr[instance].number);
Line 945... Line 1139...
945
 
1139
 
946
        MSG_DEBUG("Putting bitmap on top of image ...");
1140
        MSG_DEBUG("Putting bitmap on top of image ...");
947
        SkPaint paint;
1141
        SkPaint paint;
948
        paint.setBlendMode(SkBlendMode::kSrc);
1142
        paint.setBlendMode(SkBlendMode::kSrc);
949
        SkCanvas can(*bm, SkSurfaceProps(1, kUnknown_SkPixelGeometry));
1143
        SkCanvas can(*bm, SkSurfaceProps(1, kUnknown_SkPixelGeometry));
-
 
1144
 
-
 
1145
        if (sr[instance].sb == 0)
950
        can.drawBitmap(image, position.left, position.top, &paint);
1146
            can.drawBitmap(image, position.left, position.top, &paint);
-
 
1147
        else    // Scale to fit
-
 
1148
        {
-
 
1149
            SkRect rect = SkRect::MakeXYWH(position.left, position.top, position.width, position.height);
-
 
1150
            sk_sp<SkImage> im = SkImage::MakeFromBitmap(image);
-
 
1151
            can.drawImageRect(im, rect, &paint);
-
 
1152
        }
951
    }
1153
    }
952
    else
1154
    else
953
    {
1155
    {
954
        MSG_DEBUG("No bitmap defined.");
1156
        MSG_DEBUG("No bitmap defined.");
955
    }
1157
    }
956
 
1158
 
957
    return true;
1159
    return true;
958
}
1160
}
959
 
1161
 
-
 
1162
bool TButton::buttonDynamic(SkBitmap* bm, int instance)
-
 
1163
{
-
 
1164
    DECL_TRACER("TButton::buttonDynamic(SkBitmap* bm, int instance)");
-
 
1165
 
-
 
1166
    if (!gPrjResources)
-
 
1167
    {
-
 
1168
        MSG_ERROR("Internal error: Global resource class not initialized!");
-
 
1169
        return false;
-
 
1170
    }
-
 
1171
 
-
 
1172
    if (!sr[instance].dynamic)
-
 
1173
    {
-
 
1174
        MSG_WARNING("Button " << bi << ": \"" << na << "\" is not for remote image!");
-
 
1175
        return false;
-
 
1176
    }
-
 
1177
 
-
 
1178
    RESOURCE_T resource = gPrjResources->findResource(1, sr[instance].bm);
-
 
1179
 
-
 
1180
    if (resource.protocol.empty())
-
 
1181
    {
-
 
1182
        MSG_ERROR("Resource " << sr[instance].bm << " not found!");
-
 
1183
        return false;
-
 
1184
    }
-
 
1185
 
-
 
1186
    string path = resource.path;
-
 
1187
 
-
 
1188
    if (!resource.file.empty())
-
 
1189
        path += "/" + resource.file;
-
 
1190
 
-
 
1191
    string url = gPrjResources->makeURL(toLower(resource.protocol), resource.host, 0, path);
-
 
1192
 
-
 
1193
    try
-
 
1194
    {
-
 
1195
        MSG_TRACE("Starting thread for loading a dynamic image ...");
-
 
1196
        mThrRes = std::thread([=] { this->funcResource(&resource, url, bm, instance); });
-
 
1197
        MSG_TRACE("Thread started. Detaching ...");
-
 
1198
        mThrRes.detach();
-
 
1199
        MSG_TRACE("Thread is running and detached.");
-
 
1200
    }
-
 
1201
    catch (std::exception& e)
-
 
1202
    {
-
 
1203
        MSG_ERROR("Error starting the AmxNet thread: " << e.what());
-
 
1204
    }
-
 
1205
 
-
 
1206
    return true;
-
 
1207
}
-
 
1208
 
-
 
1209
void TButton::funcResource(const RESOURCE_T* resource, const std::string& url, SkBitmap* bm, int instance)
-
 
1210
{
-
 
1211
    DECL_TRACER("TButton::funcResource(RESOURCE_T* resource, std::string& url, SkBitmap* bm, int instance)");
-
 
1212
 
-
 
1213
    if (resource->refresh > 0 && !resource->dynamo)      // Periodically refreshing image?
-
 
1214
    {
-
 
1215
        MSG_DEBUG("Retrieving periodicaly refreshed image");
-
 
1216
 
-
 
1217
        ulong parent = (mHandle >> 16) & 0x0000ffff;
-
 
1218
 
-
 
1219
        if (!mHandle || !parent || bi <= 1)
-
 
1220
        {
-
 
1221
            MSG_ERROR("Invalid button. Can't make a dynamo image!");
-
 
1222
            return;
-
 
1223
        }
-
 
1224
 
-
 
1225
        THR_REFRESH_t *thref = _findResource(mHandle, parent, bi);
-
 
1226
        TImageRefresh *mImageRefresh = nullptr;
-
 
1227
 
-
 
1228
        if (!thref)
-
 
1229
        {
-
 
1230
            MSG_DEBUG("Creating a new refresh thread");
-
 
1231
            mImageRefresh = new TImageRefresh();
-
 
1232
            mImageRefresh->registerCallback(bind(&TButton::_imageRefresh, this, std::placeholders::_1));
-
 
1233
            mImageRefresh->setInterval(std::chrono::seconds(resource->refresh));
-
 
1234
            mImageRefresh->setUsername(resource->user);
-
 
1235
            mImageRefresh->setPassword(resource->password);
-
 
1236
 
-
 
1237
            if (resource->preserve)
-
 
1238
                mImageRefresh->setRunOnce();
-
 
1239
 
-
 
1240
            _addResource(mImageRefresh, mHandle, parent, bi);
-
 
1241
        }
-
 
1242
        else
-
 
1243
        {
-
 
1244
            mImageRefresh = thref->mImageRefresh;
-
 
1245
 
-
 
1246
            if (!mImageRefresh)
-
 
1247
            {
-
 
1248
                MSG_ERROR("Error creating a new refresh class!");
-
 
1249
                return;
-
 
1250
            }
-
 
1251
 
-
 
1252
            mImageRefresh->setInterval(std::chrono::seconds(resource->refresh));
-
 
1253
            mImageRefresh->setUsername(resource->user);
-
 
1254
            mImageRefresh->setPassword(resource->password);
-
 
1255
 
-
 
1256
            if (resource->preserve)
-
 
1257
                mImageRefresh->setRunOnce();
-
 
1258
        }
-
 
1259
 
-
 
1260
        if (!mImageRefresh->isRunning())
-
 
1261
        {
-
 
1262
            MSG_DEBUG("Starting a refresh thread.");
-
 
1263
            mImageRefresh->run(url);
-
 
1264
        }
-
 
1265
    }
-
 
1266
    else if (resource->refresh == 0 && !resource->dynamo)
-
 
1267
    {
-
 
1268
        MSG_DEBUG("Retrieving single image");
-
 
1269
 
-
 
1270
        try
-
 
1271
        {
-
 
1272
            char *content = nullptr;
-
 
1273
            size_t length = 0, contentlen = 0;
-
 
1274
 
-
 
1275
            if ((content = gPrjResources->tcall(&length, url, resource->user, resource->password)) == nullptr)
-
 
1276
                return;
-
 
1277
 
-
 
1278
            contentlen = gPrjResources->getContentSize();
-
 
1279
            MSG_DEBUG("Loaded " << contentlen << " bytes:");
-
 
1280
            sk_sp<SkData> data = SkData::MakeWithCopy(content, contentlen);
-
 
1281
 
-
 
1282
            if (!data)
-
 
1283
            {
-
 
1284
                MSG_ERROR("Error making image data!");
-
 
1285
                return;
-
 
1286
            }
-
 
1287
 
-
 
1288
            SkBitmap image;
-
 
1289
 
-
 
1290
            if (!DecodeDataToBitmap(data, &image))
-
 
1291
            {
-
 
1292
                MSG_ERROR("Error creating an image!");
-
 
1293
                return;
-
 
1294
            }
-
 
1295
 
-
 
1296
            loadImage(bm, image, instance);
-
 
1297
            return;
-
 
1298
        }
-
 
1299
        catch (std::exception& e)
-
 
1300
        {
-
 
1301
            MSG_ERROR(e.what());
-
 
1302
            return;
-
 
1303
        }
-
 
1304
    }
-
 
1305
    else
-
 
1306
    {
-
 
1307
        MSG_DEBUG("Retrieving a video");
-
 
1308
 
-
 
1309
        if (_playVideo && !prg_stopped)
-
 
1310
        {
-
 
1311
            ulong parent = (mHandle >> 16) & 0x0000ffff;
-
 
1312
            _playVideo(mHandle, parent, lt, tp, wt, ht, url, resource->user, resource->password);
-
 
1313
        }
-
 
1314
    }
-
 
1315
}
-
 
1316
 
-
 
1317
bool TButton::loadImage(SkBitmap* bm, SkBitmap& image, int instance)
-
 
1318
{
-
 
1319
    DECL_TRACER("TButton::loadImage(SkBitmap* bm, SkBitmap& image, int instance)");
-
 
1320
 
-
 
1321
    SkImageInfo info = image.info();
-
 
1322
    POSITION_t position = calcImagePosition(info.width(), info.height(), SC_BITMAP, instance);
-
 
1323
 
-
 
1324
    if (!position.valid)
-
 
1325
    {
-
 
1326
        MSG_ERROR("Error calculating the position of the image for button number " << bi);
-
 
1327
        return false;
-
 
1328
    }
-
 
1329
 
-
 
1330
    MSG_DEBUG("Putting bitmap on top of image ...");
-
 
1331
    SkPaint paint;
-
 
1332
    paint.setBlendMode(SkBlendMode::kSrc);
-
 
1333
 
-
 
1334
    SkCanvas can(*bm, SkSurfaceProps(1, kUnknown_SkPixelGeometry));
-
 
1335
 
-
 
1336
    if (sr[instance].sb == 0)
-
 
1337
        can.drawBitmap(image, position.left, position.top, &paint);
-
 
1338
    else    // Scale to fit
-
 
1339
    {
-
 
1340
        SkRect rect = SkRect::MakeXYWH(position.left, position.top, position.width, position.height);
-
 
1341
        sk_sp<SkImage> im = SkImage::MakeFromBitmap(image);
-
 
1342
        can.drawImageRect(im, rect, &paint);
-
 
1343
    }
-
 
1344
 
-
 
1345
    return true;
-
 
1346
}
-
 
1347
 
960
bool TButton::barLevel(SkBitmap* bm, int instance, int level)
1348
bool TButton::barLevel(SkBitmap* bm, int instance, int level)
961
{
1349
{
962
    DECL_TRACER("TButton::barLevel(SkBitmap* bm, int instance, int level)");
1350
    DECL_TRACER("TButton::barLevel(SkBitmap* bm, int instance, int level)");
963
 
1351
 
964
    if (!sr[0].mi.empty() && !sr[1].bm.empty())       // Chameleon image?
1352
    if (!sr[0].mi.empty() && !sr[1].bm.empty())       // Chameleon image?
Line 1671... Line 2059...
1671
                return false;
2059
                return false;
1672
            }
2060
            }
1673
        }
2061
        }
1674
        else if (mDOrder[i] == ORD_ELEM_BITMAP)
2062
        else if (mDOrder[i] == ORD_ELEM_BITMAP)
1675
        {
2063
        {
1676
            if (!buttonBitmap(&imgButton, instance))
2064
            if (!sr[instance].dynamic && !buttonBitmap(&imgButton, instance))
-
 
2065
            {
-
 
2066
                mutex_button.unlock();
-
 
2067
                return false;
-
 
2068
            }
-
 
2069
            else if (sr[instance].dynamic && !buttonDynamic(&imgButton, instance))
1677
            {
2070
            {
1678
                mutex_button.unlock();
2071
                mutex_button.unlock();
1679
                return false;
2072
                return false;
1680
            }
2073
            }
1681
        }
2074
        }
Line 1744... Line 2137...
1744
    }
2137
    }
1745
 
2138
 
1746
    mLastImage = imgButton;
2139
    mLastImage = imgButton;
1747
    size_t rowBytes = imgButton.info().minRowBytes();
2140
    size_t rowBytes = imgButton.info().minRowBytes();
1748
 
2141
 
1749
    if (show && visible && instance == mActInstance && _displayButton)
2142
    if (!prg_stopped && show && visible && instance == mActInstance && _displayButton)
1750
        _displayButton(mHandle, parent, (unsigned char *)imgButton.getPixels(), wt, ht, rowBytes, lt, tp);
2143
        _displayButton(mHandle, parent, (unsigned char *)imgButton.getPixels(), wt, ht, rowBytes, lt, tp);
1751
 
2144
 
1752
    mutex_button.unlock();
2145
    mutex_button.unlock();
1753
    return true;
2146
    return true;
1754
}
2147
}
Line 1881... Line 2274...
1881
    }
2274
    }
1882
 
2275
 
1883
    mLastImage = imgButton;
2276
    mLastImage = imgButton;
1884
    size_t rowBytes = imgButton.info().minRowBytes();
2277
    size_t rowBytes = imgButton.info().minRowBytes();
1885
 
2278
 
1886
    if (show && visible && instance == mActInstance && _displayButton)
2279
    if (!prg_stopped && show && visible && instance == mActInstance && _displayButton)
1887
        _displayButton(mHandle, parent, (unsigned char *)imgButton.getPixels(), wt, ht, rowBytes, lt, tp);
2280
        _displayButton(mHandle, parent, (unsigned char *)imgButton.getPixels(), wt, ht, rowBytes, lt, tp);
1888
 
2281
 
1889
    mutex_bargraph.unlock();
2282
    mutex_bargraph.unlock();
1890
    return true;
2283
    return true;
1891
}
2284
}
Line 2145... Line 2538...
2145
    DECL_TRACER("TButton::showLastButton()");
2538
    DECL_TRACER("TButton::showLastButton()");
2146
 
2539
 
2147
    if (mLastImage.empty())
2540
    if (mLastImage.empty())
2148
        return;
2541
        return;
2149
 
2542
 
2150
    if (visible && _displayButton)
2543
    if (!prg_stopped && visible && _displayButton)
2151
    {
2544
    {
2152
        ulong parent = mHandle & 0xffff0000;
2545
        ulong parent = mHandle & 0xffff0000;
2153
        size_t rowBytes = mLastImage.info().minRowBytes();
2546
        size_t rowBytes = mLastImage.info().minRowBytes();
2154
        _displayButton(mHandle, parent, (unsigned char *)mLastImage.getPixels(), wt, ht, rowBytes, lt, tp);
2547
        _displayButton(mHandle, parent, (unsigned char *)mLastImage.getPixels(), wt, ht, rowBytes, lt, tp);
2155
    }
2548
    }
Line 2160... Line 2553...
2160
    DECL_TRACER("TButton::hide()");
2553
    DECL_TRACER("TButton::hide()");
2161
 
2554
 
2162
    if (type == MULTISTATE_GENERAL && ar == 1)
2555
    if (type == MULTISTATE_GENERAL && ar == 1)
2163
        mAniRunning = false;
2556
        mAniRunning = false;
2164
 
2557
 
2165
    if (total)
2558
    if (!prg_stopped && total)
2166
    {
2559
    {
2167
        SkBitmap imgButton;
2560
        SkBitmap imgButton;
2168
        imgButton.allocN32Pixels(wt, ht);
2561
        imgButton.allocN32Pixels(wt, ht);
2169
        imgButton.eraseColor(SK_ColorTRANSPARENT);
2562
        imgButton.eraseColor(SK_ColorTRANSPARENT);
2170
        ulong parent = mHandle & 0xffff0000;
2563
        ulong parent = mHandle & 0xffff0000;
Line 2761... Line 3154...
2761
        i++;
3154
        i++;
2762
    }
3155
    }
2763
 
3156
 
2764
    return false;
3157
    return false;
2765
}
3158
}
-
 
3159
 
-
 
3160
THR_REFRESH_t *TButton::_addResource(TImageRefresh* refr, ulong handle, ulong parent, int bi)
-
 
3161
{
-
 
3162
    DECL_TRACER("TButton::_addResource(TImageRefresh* refr, ulong handle, ulong parent, int bi)");
-
 
3163
 
-
 
3164
    THR_REFRESH_t *p = mThrRefresh;
-
 
3165
    THR_REFRESH_t *r, *last = p;
-
 
3166
 
-
 
3167
    if (!refr || !handle || !parent || bi <= 0)
-
 
3168
    {
-
 
3169
        MSG_ERROR("Invalid parameter!");
-
 
3170
        return nullptr;
-
 
3171
    }
-
 
3172
 
-
 
3173
    r = new THR_REFRESH_t;
-
 
3174
    r->mImageRefresh = refr;
-
 
3175
    r->handle = handle;
-
 
3176
    r->parent = parent;
-
 
3177
    r->bi = bi;
-
 
3178
    r->next = nullptr;
-
 
3179
 
-
 
3180
    // If the chain is empty, add the new item;
-
 
3181
    if (!mThrRefresh)
-
 
3182
        mThrRefresh = r;
-
 
3183
    else    // Find the end and append the item
-
 
3184
    {
-
 
3185
        while (p)
-
 
3186
        {
-
 
3187
            last = p;
-
 
3188
 
-
 
3189
            if (p->handle == handle && p->parent == parent && p->bi == bi)
-
 
3190
            {
-
 
3191
                MSG_WARNING("Duplicate button found! Didn't add it again.");
-
 
3192
                delete r;
-
 
3193
                return p;
-
 
3194
            }
-
 
3195
 
-
 
3196
            p = p->next;
-
 
3197
        }
-
 
3198
 
-
 
3199
        last->next = r;
-
 
3200
    }
-
 
3201
 
-
 
3202
    MSG_DEBUG("New dynamic button added.");
-
 
3203
    return r;
-
 
3204
}
-
 
3205
 
-
 
3206
THR_REFRESH_t *TButton::_findResource(ulong handle, ulong parent, int bi)
-
 
3207
{
-
 
3208
    DECL_TRACER("TButton::_findResource(ulong handle, ulong parent, int bi)");
-
 
3209
 
-
 
3210
    THR_REFRESH_t *p = mThrRefresh;
-
 
3211
 
-
 
3212
    while (p)
-
 
3213
    {
-
 
3214
        if (p->handle == handle && p->parent == parent && p->bi == bi)
-
 
3215
            return p;
-
 
3216
 
-
 
3217
        p = p->next;
-
 
3218
    }
-
 
3219
 
-
 
3220
    return nullptr;
-
 
3221
}