Subversion Repositories tpanel

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
446 andreas 1
/*
2
 * Copyright (C) 2023 by Andreas Theofilu <andreas@theosys.at>
3
 *
4
 * This program is free software; you can redistribute it and/or modify
5
 * it under the terms of the GNU General Public License as published by
6
 * the Free Software Foundation; either version 3 of the License, or
7
 * (at your option) any later version.
8
 *
9
 * This program is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 * GNU General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU General Public License
15
 * along with this program; if not, write to the Free Software Foundation,
16
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
17
 */
18
#include <QPainter>
19
#include <QString>
20
#include <QStaticText>
21
#include <QRegion>
22
#include <QApplication>
23
 
24
#include <vector>
25
#include <chrono>
26
 
27
#include "tqmarquee.h"
28
#include "terror.h"
29
 
30
using std::vector;
31
 
32
TQMarquee::TQMarquee(QWidget* parent)
33
    : QLabel(parent),
34
      mParent(parent)
35
{
36
    DECL_TRACER("TQMarquee::TQMarquee(QWidget* parent)");
37
 
38
    init();
39
}
40
 
41
TQMarquee::TQMarquee(QWidget* parent, int msec, MQ_TYPES type, bool enable)
42
    : QLabel(parent),
43
      mParent(parent),
44
      mScrollEnabled(enable),
45
      mType(type)
46
{
47
    DECL_TRACER("TQMarquee::TQMarquee(QWidget* parent, int msec, MQ_TYPES type, bool enable)");
48
 
49
    if (msec >= 1 && msec <= 10)
50
        mInterval = BASE_SPEED - 2 + msec * 2;
51
 
52
    init();
53
}
54
 
55
TQMarquee::~TQMarquee()
56
{
57
    DECL_TRACER("TQMarquee::~TQMarquee()");
58
 
59
    if (mTimer)
60
    {
61
        if (mTimer->isActive())
62
            mTimer->stop();
63
 
64
        delete mTimer;
65
    }
66
}
67
 
68
void TQMarquee::init()
69
{
70
    DECL_TRACER("TQMarquee::init()");
71
 
72
    switch(mType)
73
    {
74
        case MQ_LEFT:   mDirection = Qt::RightToLeft; break;
75
        case MQ_RIGHT:  mDirection = Qt::LeftToRight; break;
76
 
77
        default:
78
            mDirection = Qt::RightToLeft;
79
    }
80
 
81
//    setAutoFillBackground(false);
82
    mTimer = new QTimer(this);
83
    mTimer->setTimerType(Qt::CoarseTimer);
84
    connect(mTimer, &QTimer::timeout, this, &TQMarquee::refreshLabel);
85
    // By default the background is transparent
86
    setBackgroundColor(mBgColor);
87
    mFontPointSize = font().pointSize() / 2;
88
    mTextLength = fontMetrics().horizontalAdvance(mText);
89
    mTextHeight = fontMetrics().height();
90
    mTimer->start(mInterval);
91
}
92
 
93
void TQMarquee::setAlignment(Qt::Alignment al)
94
{
95
    DECL_TRACER("TQMarquee::setAlignment(Qt::Alignment al)");
96
 
97
    mAlign = al;
98
    updateCoordinates();
99
}
100
 
101
void TQMarquee::setFrame(int left, int top, int right, int bottom)
102
{
103
    DECL_TRACER("TQMarquee::setFrame(int left, int top, int right, int bottom)");
104
 
105
    mFrameLeft = (left > 0 && left < width() ? left : 0);
106
    mFrameTop = (top > 0 && top < height() ? top : 0);
107
    mFrameRight = (right > 0 && right < width() ? right : 0);
108
    mFrameBottom = (bottom > 0 && bottom < height() ? bottom : 0);
109
 
110
    if ((mFrameLeft + mFrameRight) > width())
111
        mFrameLeft = mFrameRight = 0;
112
 
113
    if ((mFrameTop + mFrameBottom) > height())
114
        mFrameTop = mFrameBottom = 0;
115
 
116
    update();
117
}
118
 
119
void TQMarquee::setText(const QString& text)
120
{
121
    DECL_TRACER("TQMarquee::setText(const QString& text)");
122
 
123
    mText = text;
124
    mFontPointSize = font().pointSize() / 2;
125
    mTextLength = fontMetrics().horizontalAdvance(mText);
126
    mTextHeight = fontMetrics().height();
127
    refreshLabel();
128
    update();
129
}
130
 
131
void TQMarquee::setFont(const QFont &f)
132
{
133
    DECL_TRACER("TQMarquee::setFont(const QFont &font)");
134
 
135
    QLabel::setFont(f);
136
    mFontPointSize = font().pointSize() / 2;
137
    mTextLength = fontMetrics().horizontalAdvance(mText);
138
    mTextHeight = fontMetrics().height();
139
}
140
 
141
void TQMarquee::setSpeed(int msec)
142
{
143
    DECL_TRACER("TQMarquee::setSpeed(int msec)");
144
 
145
    if (msec < 1 || msec > 10)
146
    {
147
        MSG_WARNING("Wrong speed " << msec << "! The speed must be between 1 and 10.");
148
        return;
149
    }
150
 
151
    if (!mTimer)
152
    {
153
        MSG_ERROR("Timer is not initialized!");
154
        return;
155
    }
156
 
157
    mInterval = BASE_SPEED - 2 + msec * 2;
158
 
159
    if (mTimer->isActive())
160
        mTimer->start(mInterval);
161
    else
162
        mTimer->setInterval(mInterval);
163
}
164
 
165
void TQMarquee::pause()
166
{
167
    DECL_TRACER("TQMarquee::pause()");
168
 
169
    if (!mTimer)
170
        return;
171
 
172
    if (mTimer->isActive())
173
        mTimer->stop();
174
 
175
    mPaused = true;
176
}
177
 
178
void TQMarquee::resume()
179
{
180
    DECL_TRACER("TQMarquee::resume()");
181
 
182
    if (!mTimer)
183
        return;
184
 
185
    if (!mTimer->isActive())
186
        mTimer->start(mInterval);
187
 
188
    mPaused = false;
189
}
190
 
191
QColor TQMarquee::backgroundColor()
192
{
193
    DECL_TRACER("TQMarquee::backgroundColor()");
194
 
195
    QPalette::ColorRole colorRole = backgroundRole();
196
    QBrush brush = palette().brush(colorRole);
197
    return brush.color();
198
}
199
 
200
void TQMarquee::setBackgroundColor(QColor& color)
201
{
202
    DECL_TRACER("TQMarquee::setBackgroundColor(QColor& color)");
203
 
204
    QBrush brush;
205
    brush.setColor(color);
206
    QPalette pal;
207
    pal.setBrush(backgroundRole(), brush);
208
    setPalette(pal);
209
}
210
 
211
QPixmap TQMarquee::background()
212
{
213
    DECL_TRACER("TQMarquee::background()");
214
 
215
    return mBackgroundImage;
216
}
217
 
218
void TQMarquee::setBackground(QPixmap& image)
219
{
220
    DECL_TRACER("TQMarquee::setBackground(QPixmap& image)");
221
 
222
    mBackgroundImage = image;
223
    setPixmap(mBackgroundImage);
224
    update();
225
}
226
 
227
void TQMarquee::setDirection(MQ_TYPES type)
228
{
229
    DECL_TRACER("TQMarquee::setDirection(MQ_TYPES type)");
230
 
231
    mType = type;
232
 
233
    switch(type)
234
    {
235
        case MQ_LEFT:   mDirection = Qt::RightToLeft; break;
236
        case MQ_RIGHT:  mDirection = Qt::LeftToRight; break;
237
 
238
        default:
239
            mDirection = Qt::RightToLeft;
240
    }
241
 
242
    if (mType == MQ_RIGHT || mType == MQ_PONG)
243
        px = width() - (mTextLength + mFrameLeft + mFrameRight);
244
    else if (mType == MQ_LEFT)
245
        px = mFrameLeft;
246
    else if (mType == MQ_DOWN)
247
    {
248
        py = height() - (mTextHeight + mFrameTop + mFrameBottom);
249
        px = width() / 2 - mTextLength / 2;
250
    }
251
    else if (mType == MQ_UP)
252
    {
253
        py = mFrameTop;
254
        px = width() / 2 - mTextLength / 2;
255
    }
256
 
257
    refreshLabel();
258
}
259
 
260
void TQMarquee::refreshLabel()
261
{
262
//    DECL_TRACER("TQMarquee::refreshLabel()");       // This would fill up a logfile, if there is one.
263
 
264
    update();
265
}
266
 
267
void TQMarquee::hideEvent(QHideEvent *e)
268
{
269
    DECL_TRACER("TQMarquee::hideEvent(QHideEvent*)");
270
 
271
    pause();
272
    QLabel::hideEvent(e);
273
}
274
 
275
void TQMarquee::showEvent(QShowEvent *e)
276
{
277
    DECL_TRACER("TQMarquee::showEvent(QShowEvent*)");
278
 
279
    resume();
280
    QLabel::showEvent(e);
281
}
282
 
283
bool TQMarquee::testVisibility(const QRegion& region)
284
{
285
    if (region.isEmpty() || region.isNull())
286
        return false;
287
 
288
    return true;
289
}
290
 
291
void TQMarquee::paintEvent(QPaintEvent*)
292
{
293
//    DECL_TRACER("TQMarquee::paintEvent(QPaintEvent*)");   // This would fill up a logfile, if there is one.
294
 
295
    if (!testVisibility(visibleRegion()))
296
        return;
297
 
298
    QPainter p(this);
299
    p.drawPixmap(0, 0, mBackgroundImage);
300
 
301
    if (mScrollEnabled && !mPaused)
302
    {
303
        if(mType == MQ_LEFT)
304
        {
305
            px -= mSpeed;
306
 
307
            if(px <= (-mTextLength))
308
                px = width();
309
        }
310
        else if (mType == MQ_RIGHT)
311
        {
312
            px += mSpeed;
313
 
314
            if(px >= width())
315
                px = -mTextLength;
316
        }
317
        else if (mType == MQ_PONG)
318
        {
319
            if (mDirection == Qt::LeftToRight)
320
            {
321
                px -= mSpeed;
322
                bool changeDirection = false;
323
 
324
                if (mTextLength > width())
325
                    changeDirection = (px <= (width() - mTextLength - mFrameLeft));
326
                else
327
                    changeDirection = (px <= mFrameLeft);
328
 
329
                if (changeDirection)
330
                    mDirection = Qt::RightToLeft;
331
            }
332
            else
333
            {
334
                px += mSpeed;
335
                bool changeDirection = false;
336
 
337
                if (mTextLength > width())
338
                    changeDirection = (px >= mFrameLeft);
339
                else
340
                    changeDirection = (px >= (width() - mTextLength - mFrameRight));
341
 
342
                if (changeDirection)
343
                    mDirection = Qt::LeftToRight;
344
            }
345
        }
346
        else if (mType == MQ_DOWN)
347
        {
348
            py += mSpeed;
349
 
350
            if (py >= height())
351
                py = -mTextHeight;
352
        }
353
        else if (mType == MQ_UP)
354
        {
355
            py -= mSpeed;
356
 
357
            if (py <= (-mTextHeight))
358
                py = height();
359
        }
360
 
361
        if (mFrameLeft || mFrameRight || mFrameTop || mFrameBottom)
362
            p.setClipRect(QRect(mFrameLeft, mFrameTop, width() - mFrameLeft - mFrameRight, height() - mFrameBottom - mFrameTop), Qt::ReplaceClip);
363
 
364
        p.drawText(px, py + mFontPointSize, mText);
365
        p.translate(px,0);
366
    }
367
//    else
368
//        QLabel::setText(mText);
369
}
370
 
371
void TQMarquee::resizeEvent(QResizeEvent* evt)
372
{
373
    DECL_TRACER("TQMarquee::resizeEvent(QResizeEvent* evt)");
374
 
375
    updateCoordinates();
376
    QLabel::resizeEvent(evt);
377
}
378
 
379
void TQMarquee::updateCoordinates()
380
{
381
    DECL_TRACER("TQMarquee::updateCoordinates()");
382
 
383
//    mFontPointSize = font().pointSize() / 2;
384
//    mTextLength = fontMetrics().horizontalAdvance(mText);
385
//    mTextHeight = fontMetrics().height();
386
 
387
    vector<Qt::Alignment> alignList = {
388
        Qt::AlignLeft, Qt::AlignHCenter, Qt::AlignRight,
389
        Qt::AlignTop, Qt::AlignVCenter, Qt::AlignBottom };
390
    vector<Qt::Alignment>::iterator iter;
391
 
392
    for (iter = alignList.begin(); iter != alignList.end(); ++iter)
393
    {
394
        bool al = (mAlign & *iter) == *iter;
395
 
396
        if (al)
397
        {
398
            switch(*iter)
399
            {
400
                case Qt::AlignTop:      py = mFrameTop + mTextHeight / 2; break;
401
                case Qt::AlignBottom:   py = height() - (mFrameTop + mFrameBottom + mTextHeight / 2); break;
402
                case Qt::AlignVCenter:  py = height() / 2; break;
403
 
404
                case Qt::AlignLeft:     px = mFrameLeft; break;
405
                case Qt::AlignRight:    px = width() - mTextLength - mFrameRight; break;
406
                case Qt::AlignHCenter:  px = width() / 2 - mTextLength / 2; break;
407
 
408
                default:
409
                    px = width() / 2 - mTextLength / 2;
410
                    py = height() / 2;
411
            }
412
        }
413
    }
414
}