aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPavel Pisa <pisa@cmp.felk.cvut.cz>2019-06-28 13:04:50 +0200
committerPavel Pisa <pisa@cmp.felk.cvut.cz>2019-06-28 13:04:50 +0200
commit22bf928025e0b289cb18b3624081055f96e645c9 (patch)
tree2d591b52566dea91703d4ae1f92fc614ce141480
parentedabdffead6d33a4e6a0e5a84d9e15f25a6acf83 (diff)
downloadqtmips-22bf928025e0b289cb18b3624081055f96e645c9.tar.gz
qtmips-22bf928025e0b289cb18b3624081055f96e645c9.tar.bz2
qtmips-22bf928025e0b289cb18b3624081055f96e645c9.zip
LCD display emulation updated to keep aspect ratio.
Signed-off-by: Pavel Pisa <pisa@cmp.felk.cvut.cz>
-rw-r--r--qtmips_gui/lcddisplaydock.cpp49
-rw-r--r--qtmips_gui/lcddisplaydock.h8
-rw-r--r--qtmips_gui/lcddisplayview.cpp65
-rw-r--r--qtmips_gui/lcddisplayview.h8
4 files changed, 117 insertions, 13 deletions
diff --git a/qtmips_gui/lcddisplaydock.cpp b/qtmips_gui/lcddisplaydock.cpp
index 6517f4a..1109efd 100644
--- a/qtmips_gui/lcddisplaydock.cpp
+++ b/qtmips_gui/lcddisplaydock.cpp
@@ -40,9 +40,17 @@
#include "lcddisplaydock.h"
#include "lcddisplayview.h"
-LcdDisplayDock::LcdDisplayDock(QWidget *parent, QSettings *settings) : QDockWidget(parent) {
+LcdDisplayDock::LcdDisplayDock(QWidget *parent, QSettings *settings) : Super(parent) {
lcd_display_widget = new LcdDisplayView(this);
- setWidget(lcd_display_widget);
+ QWidget *fill_widget = new QWidget(this);
+
+ layout = new QBoxLayout(QBoxLayout::LeftToRight, fill_widget);
+ // add spacer, then your widget, then spacer
+ layout->addItem(new QSpacerItem(0, 0));
+ layout->addWidget(lcd_display_widget);
+ layout->addItem(new QSpacerItem(0, 0));
+ fill_widget->setLayout(layout);
+ setWidget(fill_widget);
setObjectName("LCD Display");
setWindowTitle("LCD Display");
@@ -54,4 +62,41 @@ LcdDisplayDock::~LcdDisplayDock() {
void LcdDisplayDock::setup(machine::LcdDisplay *lcd_display) {
lcd_display_widget->setup(lcd_display);
+ update_layout(width(), height());
+}
+
+void LcdDisplayDock::update_layout(int w, int h) {
+ // Keeping aspect ratio based on
+ // https://stackoverflow.com/questions/30005540/keeping-the-aspect-ratio-of-a-sub-classed-qwidget-during-resize
+
+ float thisAspectRatio = (float)w / h;
+ int widgetStretch, outerStretch;
+ float arWidth = lcd_display_widget->fb_width(); // aspect ratio width
+ float arHeight = lcd_display_widget->fb_height(); // aspect ratio height
+
+ if ((arWidth == 0) || (arHeight == 0)) {
+ outerStretch = 0;
+ widgetStretch = 1;
+ } else if (thisAspectRatio > (arWidth/arHeight)) { // too wide
+ layout->setDirection(QBoxLayout::LeftToRight);
+ widgetStretch = height() * (arWidth/arHeight); // i.e., my width
+ outerStretch = (width() - widgetStretch) / 2 + 0.5;
+ } else { // too tall
+ layout->setDirection(QBoxLayout::TopToBottom);
+ widgetStretch = width() * (arHeight/arWidth); // i.e., my height
+ outerStretch = (height() - widgetStretch) / 2 + 0.5;
+ }
+
+ layout->setStretch(0, outerStretch);
+ layout->setStretch(1, widgetStretch);
+ layout->setStretch(2, outerStretch);
+}
+
+void LcdDisplayDock::resizeEvent(QResizeEvent *event) {
+ // Keeping aspect ratio based on
+ // https://stackoverflow.com/questions/30005540/keeping-the-aspect-ratio-of-a-sub-classed-qwidget-during-resize
+
+ update_layout(event->size().width(), event->size().height());
+
+ Super::resizeEvent(event);
}
diff --git a/qtmips_gui/lcddisplaydock.h b/qtmips_gui/lcddisplaydock.h
index 9a4f866..4659fa5 100644
--- a/qtmips_gui/lcddisplaydock.h
+++ b/qtmips_gui/lcddisplaydock.h
@@ -37,20 +37,28 @@
#define LCDDISPLAYDOCK_H
#include <QDockWidget>
+#include <QBoxLayout>
#include "lcddisplayview.h"
#include "qtmipsmachine.h"
class LcdDisplayDock : public QDockWidget {
Q_OBJECT
+
+ using Super = QDockWidget;
+
public:
LcdDisplayDock(QWidget *parent, QSettings *settings);
~LcdDisplayDock();
+ virtual void resizeEvent(QResizeEvent *event) override;
void setup(machine::LcdDisplay *lcd_display);
//public slots:
private:
+ void update_layout(int w, int h);
+
+ QBoxLayout *layout;
LcdDisplayView *lcd_display_widget;
};
diff --git a/qtmips_gui/lcddisplayview.cpp b/qtmips_gui/lcddisplayview.cpp
index 450e7d4..b186610 100644
--- a/qtmips_gui/lcddisplayview.cpp
+++ b/qtmips_gui/lcddisplayview.cpp
@@ -1,4 +1,5 @@
#include <QPainter>
+#include <QPaintEvent>
#include <QStyle>
#include "lcddisplay.h"
#include "lcddisplayview.h"
@@ -6,6 +7,8 @@
LcdDisplayView::LcdDisplayView(QWidget *parent) : Super(parent) {
setMinimumSize(100, 100);
fb_pixels = nullptr;
+ scale_x = 1.0;
+ scale_y = 1.0;
}
LcdDisplayView::~LcdDisplayView() {
@@ -21,19 +24,45 @@ void LcdDisplayView::setup(machine::LcdDisplay *lcd_display) {
if (fb_pixels != nullptr)
delete fb_pixels;
fb_pixels = nullptr;
- fb_pixels = new QImage(lcd_display->height(),
- lcd_display->width(), QImage::Format_RGB32);
+ fb_pixels = new QImage(lcd_display->width(),
+ lcd_display->height(), QImage::Format_RGB32);
fb_pixels->fill(qRgb(0, 0, 0));
+ update_scale();
update();
}
void LcdDisplayView::pixel_update(uint x, uint y, uint r, uint g, uint b) {
+ int x1, y1, x2, y2;
if (fb_pixels != nullptr) {
fb_pixels->setPixel(x, y, qRgb(r, g, b));
- update();
+ x1 = x * scale_x - 2;
+ if (x1 < 0)
+ x1 = 0;
+ x2 = x * scale_x + 2;
+ if (x2 > width())
+ x2 = width();
+ y1 = y * scale_y - 2;
+ if (y1 < 0)
+ y1 = 0;
+ y2 = y * scale_y + 2;
+ if (y2 > height())
+ y2 = height();
+ update(x1, y1, x2 - x1, y2 - y1);
}
}
+void LcdDisplayView::update_scale() {
+ if (fb_pixels != nullptr) {
+ if ((fb_pixels->width() != 0) && (fb_pixels->height() != 0)) {
+ scale_x = (float)width() / fb_pixels->width();
+ scale_y = (float)height() / fb_pixels->height();
+ return;
+ }
+ }
+ scale_x = 1.0;
+ scale_y = 1.0;
+}
+
void LcdDisplayView::paintEvent(QPaintEvent *event) {
if (fb_pixels == nullptr)
return Super::paintEvent(event);
@@ -41,12 +70,28 @@ void LcdDisplayView::paintEvent(QPaintEvent *event) {
return Super::paintEvent(event);
QPainter painter(this);
- QSize widgetSize = rect().size();
- const auto newHeight = widgetSize.width() * fb_pixels->height() / fb_pixels->width();
- if(newHeight <= widgetSize.height())
- widgetSize.setHeight(newHeight);
- else
- widgetSize.setWidth(widgetSize.height() * fb_pixels->width() / fb_pixels->height());
- painter.drawImage(rect(), fb_pixels->scaled(widgetSize));
+ painter.drawImage(rect(), *fb_pixels);
+#if 0
+ painter.setPen(QPen(QColor(255, 255, 0)));
+ painter.drawLine(event->rect().topLeft(),event->rect().topRight());
+ painter.drawLine(event->rect().topLeft(),event->rect().bottomLeft());
+ painter.drawLine(event->rect().topLeft(),event->rect().bottomRight());
+#endif
+}
+
+void LcdDisplayView::resizeEvent(QResizeEvent *event) {
+ Super::resizeEvent(event);
+ update_scale();
}
+uint LcdDisplayView::fb_width() {
+ if (fb_pixels == nullptr)
+ return 0;
+ return fb_pixels->width();
+}
+
+uint LcdDisplayView::fb_height() {
+ if (fb_pixels == nullptr)
+ return 0;
+ return fb_pixels->height();
+}
diff --git a/qtmips_gui/lcddisplayview.h b/qtmips_gui/lcddisplayview.h
index 010a106..461bffc 100644
--- a/qtmips_gui/lcddisplayview.h
+++ b/qtmips_gui/lcddisplayview.h
@@ -17,15 +17,21 @@ public:
~LcdDisplayView();
void setup(machine::LcdDisplay *lcd_display);
+ uint fb_width();
+ uint fb_height();
public slots:
void pixel_update(uint x, uint y, uint r, uint g, uint b);
protected:
virtual void paintEvent(QPaintEvent *event) override;
+ virtual void resizeEvent(QResizeEvent *event) override;
private:
- QImage *fb_pixels;
+ void update_scale();
+ float scale_x;
+ float scale_y;
+ QImage *fb_pixels;
};
#endif // LCDDISPLAYVIEW_H