168 lines
4.9 KiB
C++
168 lines
4.9 KiB
C++
//
|
|
// Created by Krad on 2021/12/16.
|
|
//
|
|
|
|
#include "RollingMessageWidget.h"
|
|
|
|
#include <QLabel>
|
|
#include <QThread>
|
|
#include <QDebug>
|
|
#include <QShowEvent>
|
|
|
|
namespace {
|
|
const int WAIT_TIMES = 60;
|
|
const int LABEL_MARGIN_TOP = 2;
|
|
const int LABEL_MARGIN_LEFT = 5;
|
|
const int LABEL_FONT_WIDTH = 16;
|
|
const int MOVING_STEP = 2;
|
|
}
|
|
|
|
RollingMessageWidget::RollingMessageWidget(QWidget *parent)
|
|
: QWidget(parent)
|
|
, mCurrentLabel(new QLabel(this))
|
|
, mNextLabel(new QLabel(this))
|
|
{
|
|
this->setFixedHeight(36);
|
|
this->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Preferred);
|
|
}
|
|
|
|
RollingMessageWidget::~RollingMessageWidget() {
|
|
if (mTimerId >= 0) killTimer(mTimerId);
|
|
}
|
|
|
|
void RollingMessageWidget::timerEvent(QTimerEvent *e) {
|
|
if (!this->isVisible()) return;
|
|
//滚动
|
|
if (mRolling) {
|
|
//end rolling, reset next
|
|
if (mRolledDistance == TOTAL_ROLL_DISTANCE){
|
|
mWaitStep = 0;
|
|
mRolling = false;
|
|
QPoint p3 = {TOTAL_ROLL_DISTANCE + LABEL_MARGIN_LEFT, LABEL_MARGIN_TOP};
|
|
mCurrentLabel->move(p3);
|
|
std::swap(mCurrentLabel, mNextLabel);
|
|
return;
|
|
}
|
|
//rolling
|
|
mRolledDistance += 2;
|
|
QPoint p1 = {TOTAL_ROLL_DISTANCE + LABEL_MARGIN_LEFT - mRolledDistance, LABEL_MARGIN_TOP};
|
|
mNextLabel->move(p1);
|
|
if (p1.x() - mCurrentLabel->geometry().x() <= mCurrentLabel->width() + 20)
|
|
{
|
|
QPoint p2 = {mCurrentLabel->geometry().x() - MOVING_STEP, LABEL_MARGIN_TOP};
|
|
mCurrentLabel->move(p2);
|
|
}
|
|
return ;
|
|
}
|
|
else{
|
|
|
|
//有等待的高优先级消息时,不停顿
|
|
if (mWaitStep == WAIT_TIMES || (mWaitPriorityCount > 0 && mWaitStep == WAIT_TIMES / 3)){
|
|
mLocker.lock();
|
|
mNextLabel->setText(getNextMessage());
|
|
mNextLabel->setFixedWidth(mNextLabel->text().length() * LABEL_FONT_WIDTH);
|
|
mLocker.unlock();
|
|
} else{
|
|
mWaitStep++;
|
|
}
|
|
}
|
|
}
|
|
|
|
void RollingMessageWidget::setMessageList(const QStringList &message) {
|
|
//empty, don't set
|
|
if (message.isEmpty()) return;
|
|
mMessages.clear();
|
|
// set default label
|
|
mCurrentLabel->setText(message[0]);
|
|
mMessages.push_back({0, message[0], 0});
|
|
//add list
|
|
if (message.length()>0)
|
|
{
|
|
for (int k = 1; k < message.length(); ++k) {
|
|
mMessages.push_front({k, message[k], -1});
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
void RollingMessageWidget::updateMessagePriority(int innerIndex, int priority) {
|
|
//lock thread
|
|
mLocker.lock();
|
|
//高优先级,需要插入
|
|
if (priority > 0)
|
|
{
|
|
int idx = -1, insertIdx = -1;
|
|
for (int i = 0; i < mMessages.length(); ++i) {
|
|
if (mMessages[i].innerId == innerIndex)
|
|
{
|
|
mMessages[i].priority = priority;
|
|
idx = i;
|
|
}
|
|
else if (insertIdx < 0 && mMessages[i].priority < 1)
|
|
{
|
|
insertIdx = i;
|
|
}
|
|
if (idx>=0 && insertIdx >= 0) break;
|
|
}
|
|
insertIdx = insertIdx == -1 ? 0 : insertIdx;
|
|
//move
|
|
if(insertIdx < idx)mMessages.move(idx, insertIdx);
|
|
mWaitPriorityCount++;
|
|
}
|
|
// 低优先级,更新状态即可
|
|
else{
|
|
for (WarnMessage & message : mMessages) {
|
|
if (message.innerId == innerIndex) {
|
|
message.priority = -1;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
mLocker.unlock();
|
|
}
|
|
|
|
QString RollingMessageWidget::getNextMessage() {
|
|
|
|
QString ret = "No message";
|
|
int retryCount = 0;
|
|
bool priorityFlag = false;
|
|
while (retryCount < mMessages.length()){
|
|
mMessages.move(0, mMessages.length() - 1);
|
|
retryCount++;
|
|
if(mMessages.last().priority >= 0)
|
|
{
|
|
priorityFlag = mMessages.last().priority > 0;
|
|
ret = mMessages.last().msg;
|
|
mMessages.last().priority = 0;
|
|
break;
|
|
}
|
|
}
|
|
if (priorityFlag && mWaitPriorityCount > 0) mWaitPriorityCount--;
|
|
mRolledDistance = 0;
|
|
mRolling = true;
|
|
mWaitStep = 0;
|
|
return ret;
|
|
}
|
|
|
|
void RollingMessageWidget::showEvent(QShowEvent *event) {
|
|
QWidget::showEvent(event);
|
|
if (!mInitFlag)
|
|
{
|
|
TOTAL_ROLL_DISTANCE = this->width();
|
|
QPoint p1 = {LABEL_MARGIN_LEFT,LABEL_MARGIN_TOP};
|
|
mCurrentLabel->setFixedHeight(30);
|
|
mCurrentLabel->show();
|
|
mCurrentLabel->move(p1);
|
|
mCurrentLabel->setText(tr("Message of warn!"));
|
|
mCurrentLabel->setFixedWidth(mCurrentLabel->text().length() * LABEL_FONT_WIDTH);
|
|
QPoint p2 = {TOTAL_ROLL_DISTANCE + LABEL_MARGIN_LEFT, LABEL_MARGIN_TOP};
|
|
mNextLabel->setFixedHeight(30);
|
|
mNextLabel->show();
|
|
mNextLabel->move(p2);
|
|
mNextLabel->setText(tr("Message2 of warn!"));
|
|
mNextLabel->setFixedWidth(mNextLabel->text().length() * LABEL_FONT_WIDTH);
|
|
mTimerId = startTimer(40);
|
|
mInitFlag = true;
|
|
}
|
|
}
|