From 21b29899fdcb082bf9a4fac48b34dd824dde6346 Mon Sep 17 00:00:00 2001 From: Raphael Coeffic Date: Mon, 13 Sep 2021 12:18:46 +0200 Subject: [PATCH] Moved LcdWidget implementation into own .cpp file --- companion/src/simulation/CMakeLists.txt | 1 + .../src/simulation/widgets/lcdwidget.cpp | 173 ++++++++++++++ companion/src/simulation/widgets/lcdwidget.h | 226 +++--------------- 3 files changed, 210 insertions(+), 190 deletions(-) create mode 100644 companion/src/simulation/widgets/lcdwidget.cpp diff --git a/companion/src/simulation/CMakeLists.txt b/companion/src/simulation/CMakeLists.txt index 209f38517..8963c0ef5 100644 --- a/companion/src/simulation/CMakeLists.txt +++ b/companion/src/simulation/CMakeLists.txt @@ -28,6 +28,7 @@ set(simulation_SRCS trainersimu.cpp widgets/radiowidget.cpp widgets/virtualjoystickwidget.cpp + widgets/lcdwidget.cpp ) set(simulation_UIS diff --git a/companion/src/simulation/widgets/lcdwidget.cpp b/companion/src/simulation/widgets/lcdwidget.cpp new file mode 100644 index 000000000..b01e0e62a --- /dev/null +++ b/companion/src/simulation/widgets/lcdwidget.cpp @@ -0,0 +1,173 @@ +/* + * Copyright (C) EdgeTX + * + * Based on code named + * opentx - https://github.com/opentx/opentx + * th9x - http://code.google.com/p/th9x + * er9x - http://code.google.com/p/er9x + * gruvin9x - http://code.google.com/p/gruvin9x + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "lcdwidget.h" + +void LcdWidget::setData(unsigned char *buf, int width, int height, int depth) +{ + lcdBuf = buf; + lcdWidth = width; + lcdHeight = height; + lcdDepth = depth; + if (depth >= 8) + lcdSize = (width * height) * ((depth + 7) / 8); + else + lcdSize = (width * ((height + 7) / 8)) * depth; + + localBuf = (unsigned char *)malloc(lcdSize); + memset(localBuf, 0, lcdSize); +} + +void LcdWidget::setBgDefaultColor(const QColor &color) +{ + bgDefaultColor = color; +} + +void LcdWidget::setBackgroundColor(const QColor &color) { bgColor = color; } + +void LcdWidget::makeScreenshot(const QString &fileName) +{ + int width, height; + if (lcdDepth < 12) { + width = 2 * lcdWidth; + height = 2 * lcdHeight; + } else { + width = lcdWidth; + height = lcdHeight; + } + QPixmap buffer(width, height); + QPainter p(&buffer); + doPaint(p); + if (fileName.isEmpty()) { + QApplication::clipboard()->setPixmap(buffer); + qInfo() << "Screenshot saved to clipboard"; + } else { + buffer.toImage().save(fileName); + qInfo() << "Screenshot saved to:" << fileName; + } +} + +void LcdWidget::onLcdChanged(bool light) +{ + QMutexLocker locker(&lcdMtx); + lightEnable = light; + memcpy(localBuf, lcdBuf, lcdSize); + if (!redrawTimer.isValid() || + redrawTimer.hasExpired(LCD_WIDGET_REFRESH_PERIOD)) { + update(); + redrawTimer.start(); + } +} + +void LcdWidget::doPaint(QPainter &p) +{ + QRgb rgb; + uint16_t z; + + if (!localBuf) return; + + if (lcdDepth == 16) { + for (int x = 0; x < lcdWidth; x++) { + for (int y = 0; y < lcdHeight; y++) { + z = ((uint16_t *)localBuf)[y * lcdWidth + x]; + rgb = qRgb(255 * ((z & 0xF800) >> 11) / 0x1F, + 255 * ((z & 0x07E0) >> 5) / 0x3F, 255 * (z & 0x001F) / 0x1F); + p.setPen(rgb); + p.drawPoint(x, y); + } + } + return; + } + if (lcdDepth == 12) { + for (int x = 0; x < lcdWidth; x++) { + for (int y = 0; y < lcdHeight; y++) { + z = ((uint16_t *)localBuf)[y * lcdWidth + x]; + rgb = qRgb(255 * ((z & 0xF00) >> 8) / 0x0F, + 255 * ((z & 0x0F0) >> 4) / 0x0F, 255 * (z & 0x00F) / 0x0F); + p.setPen(rgb); + p.drawPoint(x, y); + } + } + return; + } + + QColor bg; + if (lightEnable) + bg = bgColor; + else + bg = bgDefaultColor; + + p.setBackground(QBrush(bg)); + p.eraseRect(0, 0, 2 * lcdWidth, 2 * lcdHeight); + + if (lcdDepth == 1) { + rgb = qRgb(0, 0, 0); + p.setPen(rgb); + p.setBrush(QBrush(rgb)); + } + + uint16_t idx, mask; + uint16_t previousDepth = 0xFF; + + for (int y = 0; y < lcdHeight; y++) { + idx = (y * lcdDepth / 8) * lcdWidth; + mask = (1 << (y % 8)); + for (int x = 0; x < lcdWidth; x++, idx++) { + if (lcdDepth == 1) { + if (localBuf[idx] & mask) p.drawRect(2 * x, 2 * y, 1, 1); + continue; + } + // lcdDepth == 4 + z = (y & 1) ? (localBuf[idx] >> 4) : (localBuf[idx] & 0x0F); + if (!z) continue; + if (z != previousDepth) { + previousDepth = z; + rgb = qRgb(bg.red() - (z * bg.red()) / 15, + bg.green() - (z * bg.green()) / 15, + bg.blue() - (z * bg.blue()) / 15); + p.setPen(rgb); + p.setBrush(QBrush(rgb)); + } + p.drawRect(2 * x, 2 * y, 1, 1); + } + } +} + +void LcdWidget::paintEvent(QPaintEvent *) +{ + QPainter p(this); + doPaint(p); +} + +void LcdWidget::mouseMoveEvent(QMouseEvent *event) +{ + emit touchEvent(TouchSlide, event->pos().x(), event->pos().y()); +} + +void LcdWidget::mousePressEvent(QMouseEvent *event) +{ + emit touchEvent(TouchDown, event->pos().x(), event->pos().y()); +} + +void LcdWidget::mouseReleaseEvent(QMouseEvent *event) +{ + emit touchEvent(TouchUp, event->pos().x(), event->pos().y()); +} diff --git a/companion/src/simulation/widgets/lcdwidget.h b/companion/src/simulation/widgets/lcdwidget.h index 35f88cf27..107b94866 100644 --- a/companion/src/simulation/widgets/lcdwidget.h +++ b/companion/src/simulation/widgets/lcdwidget.h @@ -18,8 +18,7 @@ * GNU General Public License for more details. */ -#ifndef _LCDWIDGET_H_ -#define _LCDWIDGET_H_ +#pragma once #include #include @@ -40,209 +39,56 @@ class LcdWidget : public QWidget { Q_OBJECT - public: + public: + enum TouchEvent { TouchUp = 0, TouchDown, TouchSlide }; - enum TouchEvent { - TouchUp=0, - TouchDown, - TouchSlide - }; - - LcdWidget(QWidget * parent = 0): + LcdWidget(QWidget *parent = 0) : QWidget(parent), lcdBuf(NULL), localBuf(NULL), lightEnable(false), bgDefaultColor(QColor(198, 208, 199)) - { + { + } + + ~LcdWidget() + { + if (localBuf) { + free(localBuf); } + } - ~LcdWidget() - { - if (localBuf) { - free(localBuf); - } - } + void setData(unsigned char *buf, int width, int height, int depth = 1); + void setBgDefaultColor(const QColor &color); + void setBackgroundColor(const QColor &color); - void setData(unsigned char *buf, int width, int height, int depth=1) - { - lcdBuf = buf; - lcdWidth = width; - lcdHeight = height; - lcdDepth = depth; - if (depth >= 8) - lcdSize = (width * height) * ((depth+7) / 8); - else - lcdSize = (width * ((height+7)/8)) * depth; + void makeScreenshot(const QString &fileName); - localBuf = (unsigned char *)malloc(lcdSize); - memset(localBuf, 0, lcdSize); - } + void onLcdChanged(bool light); - void setBgDefaultColor(const QColor & color) - { - bgDefaultColor = color; - } + signals: + void touchEvent(int type, int x, int y); - void setBackgroundColor(const QColor & color) - { - bgColor = color; - } + protected: + int lcdWidth; + int lcdHeight; + int lcdDepth; + int lcdSize; - void makeScreenshot(const QString & fileName) - { - int width, height; - if (lcdDepth < 12) { - width = 2 * lcdWidth; - height = 2 * lcdHeight; - } - else { - width = lcdWidth; - height = lcdHeight; - } - QPixmap buffer(width, height); - QPainter p(&buffer); - doPaint(p); - if (fileName.isEmpty()) { - QApplication::clipboard()->setPixmap( buffer ); - qInfo() << "Screenshot saved to clipboard"; - } - else { - buffer.toImage().save(fileName); - qInfo() << "Screenshot saved to:" << fileName; - } - } + unsigned char *lcdBuf; + unsigned char *localBuf; - void onLcdChanged(bool light) - { - QMutexLocker locker(&lcdMtx); - lightEnable = light; - memcpy(localBuf, lcdBuf, lcdSize); - if (!redrawTimer.isValid() || redrawTimer.hasExpired(LCD_WIDGET_REFRESH_PERIOD)) { - update(); - redrawTimer.start(); - } - } + bool lightEnable; + QColor bgColor; + QColor bgDefaultColor; + QMutex lcdMtx; + QElapsedTimer redrawTimer; - signals: - void touchEvent(int type, int x, int y); - - protected: + void doPaint(QPainter &p); - int lcdWidth; - int lcdHeight; - int lcdDepth; - int lcdSize; + void paintEvent(QPaintEvent *) override; - unsigned char *lcdBuf; - unsigned char *localBuf; - - bool lightEnable; - QColor bgColor; - QColor bgDefaultColor; - QMutex lcdMtx; - QElapsedTimer redrawTimer; - - inline void doPaint(QPainter & p) - { - QRgb rgb; - uint16_t z; - - if (!localBuf) - return; - - if (lcdDepth == 16) { - for (int x = 0; x < lcdWidth; x++) { - for (int y = 0; y < lcdHeight; y++) { - z = ((uint16_t *)localBuf)[y * lcdWidth + x]; - rgb = qRgb(255 * ((z & 0xF800) >> 11) / 0x1F, - 255 * ((z & 0x07E0) >> 5) / 0x3F, - 255 * (z & 0x001F) / 0x1F); - p.setPen(rgb); - p.drawPoint(x, y); - } - } - return; - } - if (lcdDepth == 12) { - for (int x = 0; x < lcdWidth; x++) { - for (int y = 0; y < lcdHeight; y++) { - z = ((uint16_t *)localBuf)[y * lcdWidth + x]; - rgb = qRgb(255 * ((z & 0xF00) >> 8) / 0x0F, - 255 * ((z & 0x0F0) >> 4) / 0x0F, - 255 * (z & 0x00F) / 0x0F); - p.setPen(rgb); - p.drawPoint(x, y); - } - } - return; - } - - QColor bg; - if (lightEnable) - bg = bgColor; - else - bg = bgDefaultColor; - - p.setBackground(QBrush(bg)); - p.eraseRect(0, 0, 2*lcdWidth, 2*lcdHeight); - - if (lcdDepth == 1) { - rgb = qRgb(0, 0, 0); - p.setPen(rgb); - p.setBrush(QBrush(rgb)); - } - - uint16_t idx, mask; - uint16_t previousDepth = 0xFF; - - for (int y = 0; y < lcdHeight; y++) { - idx = (y * lcdDepth / 8) * lcdWidth; - mask = (1 << (y % 8)); - for (int x = 0; x < lcdWidth; x++, idx++) { - if (lcdDepth == 1) { - if (localBuf[idx] & mask) - p.drawRect(2 * x, 2 * y, 1, 1); - continue; - } - // lcdDepth == 4 - z = (y & 1) ? (localBuf[idx] >> 4) : (localBuf[idx] & 0x0F); - if (!z) - continue; - if (z != previousDepth) { - previousDepth = z; - rgb = qRgb(bg.red() - (z * bg.red()) / 15, - bg.green() - (z * bg.green()) / 15, - bg.blue() - (z * bg.blue()) / 15); - p.setPen(rgb); - p.setBrush(QBrush(rgb)); - } - p.drawRect(2*x, 2*y, 1, 1); - } - } - - } - - void paintEvent(QPaintEvent*) override - { - QPainter p(this); - doPaint(p); - } - - void mouseMoveEvent(QMouseEvent *event) override - { - emit touchEvent(TouchSlide, event->pos().x(), event->pos().y()); - } - - void mousePressEvent(QMouseEvent *event) override - { - emit touchEvent(TouchDown, event->pos().x(), event->pos().y()); - } - - void mouseReleaseEvent(QMouseEvent *event) override - { - emit touchEvent(TouchUp, event->pos().x(), event->pos().y()); - } + void mouseMoveEvent(QMouseEvent *event) override; + void mousePressEvent(QMouseEvent *event) override; + void mouseReleaseEvent(QMouseEvent *event) override; }; - -#endif // _LCDWIDGET_H_