Initial commit
rodzic
3cfa77426d
commit
4155acfde7
|
@ -30,3 +30,5 @@
|
|||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
|
||||
*.pro.user
|
||||
|
|
|
@ -0,0 +1,90 @@
|
|||
//
|
||||
// (c)2021 by Lucky Resistor. https://luckyresistor.me/
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
#include "BitmapPanel.hpp"
|
||||
|
||||
|
||||
#include "Converter.hpp"
|
||||
#include "BitmapPreview.hpp"
|
||||
|
||||
#include <QComboBox>
|
||||
#include <QLabel>
|
||||
#include <QScrollArea>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
|
||||
BitmapPanel::BitmapPanel(QWidget *parent) : QWidget(parent)
|
||||
{
|
||||
initializeUi();
|
||||
}
|
||||
|
||||
|
||||
void BitmapPanel::setImage(const QImage &image)
|
||||
{
|
||||
_bitmapPreview->setImage(image);
|
||||
}
|
||||
|
||||
|
||||
void BitmapPanel::setConverter(const Converter *converter)
|
||||
{
|
||||
_bitmapPreview->setConverter(converter);
|
||||
_bitmapPreview->setFixedSize(_bitmapPreview->sizeHint());
|
||||
}
|
||||
|
||||
|
||||
void BitmapPanel::initializeUi()
|
||||
{
|
||||
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
setMinimumHeight(300);
|
||||
|
||||
auto mainLayout = new QVBoxLayout(this);
|
||||
mainLayout->setContentsMargins(16, 16, 16, 4);
|
||||
mainLayout->setSpacing(4);
|
||||
mainLayout->addWidget(new QLabel(tr("Loaded Bitmap:")));
|
||||
|
||||
auto scrollArea = new QScrollArea();
|
||||
QPalette imagePalette = palette();
|
||||
imagePalette.setColor(QPalette::Window, QColor::fromRgb(32, 32, 32));
|
||||
scrollArea->setPalette(imagePalette);
|
||||
scrollArea->setBackgroundRole(QPalette::Window);
|
||||
mainLayout->addWidget(scrollArea);
|
||||
|
||||
_bitmapPreview = new BitmapPreview();
|
||||
_bitmapPreview->setFixedSize(_bitmapPreview->sizeHint());
|
||||
_bitmapPreview->setPalette(imagePalette);
|
||||
scrollArea->setWidget(_bitmapPreview);
|
||||
scrollArea->setAlignment(Qt::AlignCenter);
|
||||
|
||||
auto previewSettingsPanel = new QFrame();
|
||||
auto previewSettingsLayout = new QHBoxLayout(previewSettingsPanel);
|
||||
previewSettingsLayout->setContentsMargins(0, 0, 0, 0);
|
||||
previewSettingsLayout->setSpacing(4);
|
||||
previewSettingsLayout->addStretch();
|
||||
previewSettingsLayout->addWidget(new QLabel(tr("Overlay Mode:")));
|
||||
_overlaySelector = new QComboBox();
|
||||
_overlaySelector->addItem(tr("None"), static_cast<int>(OverlayMode::None));
|
||||
_overlaySelector->addItem(tr("Bit Assignments"), static_cast<int>(OverlayMode::BitAssigments));
|
||||
_overlaySelector->addItem(tr("Pixel Interpretation"), static_cast<int>(OverlayMode::PixelInterpretation));
|
||||
_overlaySelector->setCurrentIndex(0);
|
||||
previewSettingsLayout->addWidget(_overlaySelector);
|
||||
mainLayout->addWidget(previewSettingsPanel);
|
||||
|
||||
connect(_overlaySelector, &QComboBox::currentIndexChanged, [=]{
|
||||
_bitmapPreview->setOverlayMode(static_cast<OverlayMode>(_overlaySelector->currentData().toInt()));
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
//
|
||||
// (c)2021 by Lucky Resistor. https://luckyresistor.me/
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <QtWidgets/QWidget>
|
||||
|
||||
|
||||
class BitmapPreview;
|
||||
class Converter;
|
||||
class QComboBox;
|
||||
|
||||
|
||||
class BitmapPanel : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit BitmapPanel(QWidget *parent = nullptr);
|
||||
|
||||
public:
|
||||
/// Assign a new image.
|
||||
///
|
||||
void setImage(const QImage &image);
|
||||
|
||||
/// Set the current converter.
|
||||
///
|
||||
void setConverter(const Converter *converter);
|
||||
|
||||
private:
|
||||
void initializeUi();
|
||||
|
||||
private:
|
||||
BitmapPreview *_bitmapPreview; ///< The bitmap preview;
|
||||
QComboBox *_overlaySelector; ///< The selector for the overlays.
|
||||
};
|
||||
|
|
@ -0,0 +1,154 @@
|
|||
//
|
||||
// (c)2021 by Lucky Resistor. https://luckyresistor.me/
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
#include "BitmapPreview.hpp"
|
||||
|
||||
|
||||
#include "Converter.hpp"
|
||||
#include "OverlayPainter.hpp"
|
||||
|
||||
#include <QtGui/QPainter>
|
||||
#include <QtGui/QPaintEvent>
|
||||
|
||||
|
||||
namespace {
|
||||
const int cImagePadding = 32;
|
||||
const int cMinimumDisplayFactor = 12;
|
||||
const int cMinimumWidth = 400;
|
||||
const int cMinimumHeight = 200;
|
||||
}
|
||||
|
||||
|
||||
BitmapPreview::BitmapPreview(QWidget *parent)
|
||||
:
|
||||
QWidget(parent),
|
||||
_displayFactor(cMinimumDisplayFactor),
|
||||
_minimumSize(cMinimumWidth, cMinimumHeight),
|
||||
_overlayMode(OverlayMode::None),
|
||||
_converter(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void BitmapPreview::setImage(const QImage &image)
|
||||
{
|
||||
if (_image != image) {
|
||||
_image = image;
|
||||
_pixmap = QPixmap::fromImage(image);
|
||||
if (_converter != nullptr) {
|
||||
setGeneratedSize(_converter->generatedSize(_image.size()));
|
||||
}
|
||||
recalculate();
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BitmapPreview::setGeneratedSize(const QSize &size)
|
||||
{
|
||||
if (_generatedSize != size) {
|
||||
_generatedSize = size;
|
||||
recalculate();
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BitmapPreview::setOverlayMode(OverlayMode overlayMode)
|
||||
{
|
||||
if (_overlayMode != overlayMode) {
|
||||
_overlayMode = overlayMode;
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BitmapPreview::setConverter(const Converter *converter)
|
||||
{
|
||||
if (_converter != converter) {
|
||||
_converter = converter;
|
||||
if (_converter != nullptr) {
|
||||
setGeneratedSize(_converter->generatedSize(_image.size()));
|
||||
}
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
QSize BitmapPreview::sizeHint() const
|
||||
{
|
||||
return _minimumSize;
|
||||
}
|
||||
|
||||
|
||||
QSize BitmapPreview::minimumSizeHint() const
|
||||
{
|
||||
return _minimumSize;
|
||||
}
|
||||
|
||||
|
||||
void BitmapPreview::paintEvent(QPaintEvent *pe)
|
||||
{
|
||||
QPainter p(this);
|
||||
if (!_pixmap.isNull()) {
|
||||
qreal x = (width() - _minimumSize.width())/2 + cImagePadding;
|
||||
qreal y = (height() - _minimumSize.height())/2 + cImagePadding;
|
||||
qreal width = (_pixmap.width()*_displayFactor);
|
||||
qreal height = (_pixmap.height()*_displayFactor);
|
||||
p.fillRect(QRectF(x, y, width, height), Qt::white);
|
||||
p.drawPixmap(QRectF(x, y, width, height), _pixmap, _pixmap.rect());
|
||||
if (_converter != nullptr) {
|
||||
if (_overlayMode != OverlayMode::None) {
|
||||
p.setOpacity(0.75);
|
||||
p.fillRect(rect(), palette().window());
|
||||
}
|
||||
p.setOpacity(1.0);
|
||||
p.translate(x, y);
|
||||
OverlayPainter op(&p, pe->rect(), _displayFactor, _pixmap.size(), _generatedSize);
|
||||
_converter->paintOverlay(op, _overlayMode, _image);
|
||||
}
|
||||
} else {
|
||||
p.drawText(QRect(0, 0, width(), height()), Qt::AlignCenter, tr("No Bitmap Loaded"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BitmapPreview::resizeEvent(QResizeEvent *e)
|
||||
{
|
||||
recalculate();
|
||||
QWidget::resizeEvent(e);
|
||||
}
|
||||
|
||||
|
||||
void BitmapPreview::recalculate()
|
||||
{
|
||||
if (_pixmap.isNull()) {
|
||||
_displayFactor = cMinimumDisplayFactor;
|
||||
_minimumSize = QSize(cMinimumWidth, cMinimumHeight);
|
||||
} else {
|
||||
auto calculationSize = _pixmap.size();
|
||||
if (_generatedSize.width() > calculationSize.width() || _generatedSize.height() > calculationSize.height()) {
|
||||
calculationSize = _generatedSize;
|
||||
}
|
||||
int factorX = qMax(cMinimumWidth / calculationSize.width(), cMinimumDisplayFactor);
|
||||
int factorY = qMax(cMinimumWidth / calculationSize.height(), cMinimumDisplayFactor);
|
||||
_displayFactor = qMin(factorX, factorY);
|
||||
_minimumSize = QSize(calculationSize.width()*_displayFactor, calculationSize.height()*_displayFactor)
|
||||
+ QSize(cImagePadding*2, cImagePadding*2);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
//
|
||||
// (c)2021 by Lucky Resistor. https://luckyresistor.me/
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "OverlayMode.hpp"
|
||||
|
||||
#include <QtWidgets/QWidget>
|
||||
#include <QtGui/QImage>
|
||||
#include <QtGui/QPixmap>
|
||||
|
||||
|
||||
class Converter;
|
||||
|
||||
|
||||
/// Preview the bitmap.
|
||||
///
|
||||
class BitmapPreview : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit BitmapPreview(QWidget *parent = nullptr);
|
||||
|
||||
public:
|
||||
/// Assign a new image.
|
||||
///
|
||||
void setImage(const QImage &image);
|
||||
|
||||
/// Set the overlay mode.
|
||||
///
|
||||
void setOverlayMode(OverlayMode overlayMode);
|
||||
|
||||
/// Set the current converter.
|
||||
///
|
||||
void setConverter(const Converter *converter);
|
||||
|
||||
public:
|
||||
QSize sizeHint() const override;
|
||||
QSize minimumSizeHint() const override;
|
||||
|
||||
protected: // QWidget interface
|
||||
void paintEvent(QPaintEvent *event) override;
|
||||
void resizeEvent(QResizeEvent *event) override;
|
||||
|
||||
private:
|
||||
/// Recalculate all sizes
|
||||
///
|
||||
void recalculate();
|
||||
|
||||
/// Set the generated image size.
|
||||
///
|
||||
void setGeneratedSize(const QSize &size);
|
||||
|
||||
private:
|
||||
QImage _image; ///< The current image.
|
||||
QSize _generatedSize; ///< The generated image size.
|
||||
QPixmap _pixmap; ///< QPixmap representation of the image.
|
||||
int _displayFactor; ///< The display factor.
|
||||
QSize _minimumSize; ///< The preferred size of this widget.
|
||||
OverlayMode _overlayMode; ///< The overlay mode.
|
||||
const Converter *_converter; ///< The current converter.
|
||||
};
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
//
|
||||
// (c)2021 by Lucky Resistor. https://luckyresistor.me/
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
#include "Converter.hpp"
|
||||
|
||||
|
||||
Converter::Converter(const QString &displayName)
|
||||
: _displayName(displayName)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
QString Converter::displayName() const
|
||||
{
|
||||
return _displayName;
|
||||
}
|
||||
|
||||
|
||||
QSize Converter::generatedSize(const QSize &imageSize) const
|
||||
{
|
||||
return imageSize;
|
||||
}
|
||||
|
||||
|
||||
LegendDataPtr Converter::legendData(OverlayMode) const
|
||||
{
|
||||
auto ld = LegendData::create();
|
||||
ld->addEntry(colorBitmapSizeOriginal, colorBitmapSizeGenerated, QObject::tr("Bitmap Size Original/Generated"));
|
||||
return ld;
|
||||
}
|
||||
|
||||
|
||||
void Converter::paintOverlay(OverlayPainter &op, OverlayMode, const QImage&) const
|
||||
{
|
||||
op.drawPixelOutline(op.imageRect(), colorBitmapSizeOriginal, 1, 2);
|
||||
if (op.generatedSize().isValid() && !op.generatedSize().isEmpty()) {
|
||||
op.drawPixelOutline(op.generatedRect(), colorBitmapSizeGenerated, 1, 2);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
//
|
||||
// (c)2021 by Lucky Resistor. https://luckyresistor.me/
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "LegendData.hpp"
|
||||
#include "OverlayPainter.hpp"
|
||||
#include "OverlayMode.hpp"
|
||||
|
||||
#include <QtGui/QImage>
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QString>
|
||||
|
||||
|
||||
/// Base class for all converters
|
||||
///
|
||||
class Converter
|
||||
{
|
||||
public:
|
||||
/// Create a new converter.
|
||||
///
|
||||
/// @param displayName The name displayed in the UI for this coonverter.
|
||||
///
|
||||
Converter(const QString &displayName);
|
||||
|
||||
/// dtor
|
||||
///
|
||||
virtual ~Converter() = default;
|
||||
|
||||
public:
|
||||
/// Get the display name for the converter.
|
||||
///
|
||||
QString displayName() const;
|
||||
|
||||
public:
|
||||
/// Return the size of the generated bitmap data.
|
||||
///
|
||||
/// @param imageSize The size of the image.
|
||||
/// @return The size of the generated bitmap data.
|
||||
///
|
||||
virtual QSize generatedSize(const QSize &imageSize) const;
|
||||
|
||||
/// Generate the code from the given image.
|
||||
///
|
||||
/// @param image The image to convert.
|
||||
/// @param parameter A map with parameters passed to this converter.
|
||||
/// @return The generated code.
|
||||
///
|
||||
virtual QString generateCode(const QImage &image, const QVariantMap ¶meter) const = 0;
|
||||
|
||||
/// Return a legend for the bitmap preview.
|
||||
///
|
||||
virtual LegendDataPtr legendData(OverlayMode mode) const;
|
||||
|
||||
/// Draw the bitmap overlay.
|
||||
///
|
||||
/// @param p The painter.
|
||||
/// @param mode The overlay mode (never `None`).
|
||||
/// @param image The image.
|
||||
///
|
||||
virtual void paintOverlay(OverlayPainter &p, OverlayMode mode, const QImage &image) const;
|
||||
|
||||
protected:
|
||||
/// The color for the image frame.
|
||||
///
|
||||
static constexpr QColor colorBitmapSizeOriginal = QColor(64, 64, 255);
|
||||
|
||||
/// The color for the generated frame.
|
||||
///
|
||||
static constexpr QColor colorBitmapSizeGenerated = QColor(128, 128, 255);
|
||||
|
||||
private:
|
||||
QString _displayName; ///< The displayed name.
|
||||
};
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
//
|
||||
// (c)2021 by Lucky Resistor. https://luckyresistor.me/
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
#include "ConverterFramebuf.hpp"
|
||||
|
||||
|
||||
#include <QtCore/QTextStream>
|
||||
|
||||
|
||||
ConverterFramebuf::ConverterFramebuf(const QString &displayName)
|
||||
: Converter(displayName)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
QString ConverterFramebuf::createCode(const QByteArray &data, const QSize &size, const QString &format)
|
||||
{
|
||||
QString result;
|
||||
QTextStream ts(&result);
|
||||
ts << "fb = framebuf.FrameBuffer(bytearray(\n";
|
||||
for (int i = 0; i < data.size(); ++i) {
|
||||
if ((i & 0x1f) == 0) {
|
||||
if (i > 0) {
|
||||
ts << "'\n";
|
||||
}
|
||||
ts << " b'";
|
||||
}
|
||||
ts << QString("\\x%1").arg(static_cast<uint32_t>(data.at(i))&0xff, 2, 16, QChar('0'));
|
||||
}
|
||||
ts << "'),\n";
|
||||
ts << " " << size.width() << ", " << size.height() << ", framebuf." << format << ")\n";
|
||||
return result;
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
//
|
||||
// (c)2021 by Lucky Resistor. https://luckyresistor.me/
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "Converter.hpp"
|
||||
|
||||
|
||||
/// Base class of framebuf converters.
|
||||
///
|
||||
class ConverterFramebuf : public Converter
|
||||
{
|
||||
public:
|
||||
ConverterFramebuf(const QString &displayName);
|
||||
|
||||
protected:
|
||||
/// Create a framebuf code segment.
|
||||
///
|
||||
/// @param data The byte data.
|
||||
/// @param size The buffer size.
|
||||
/// @param format The name of the format.
|
||||
///
|
||||
static QString createCode(const QByteArray &data, const QSize &size, const QString &format);
|
||||
};
|
||||
|
|
@ -0,0 +1,148 @@
|
|||
//
|
||||
// (c)2021 by Lucky Resistor. https://luckyresistor.me/
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
#include "ConverterFramebufMono.hpp"
|
||||
|
||||
|
||||
|
||||
ConverterFramebufMono::ConverterFramebufMono(
|
||||
const QString &displayName,
|
||||
UnitOrientation unitOrientation,
|
||||
BitDirection bitDirection,
|
||||
int unitSize)
|
||||
:
|
||||
ConverterFramebuf(displayName),
|
||||
_unitOrientation(unitOrientation),
|
||||
_bitDirection(bitDirection),
|
||||
_unitSize(unitSize)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
QSize ConverterFramebufMono::generatedSize(const QSize &imageSize) const
|
||||
{
|
||||
if (_unitOrientation == UnitOrientation::Vertical) {
|
||||
if ((imageSize.height() % _unitSize) != 0) {
|
||||
return QSize(imageSize.width(), ((imageSize.height()/_unitSize)+1)*_unitSize);
|
||||
} else {
|
||||
return imageSize;
|
||||
}
|
||||
} else {
|
||||
if ((imageSize.width() % _unitSize) != 0) {
|
||||
return QSize(((imageSize.width()/_unitSize)+1)*_unitSize, imageSize.height());
|
||||
} else {
|
||||
return imageSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
LegendDataPtr ConverterFramebufMono::legendData(OverlayMode mode) const
|
||||
{
|
||||
auto data = ConverterFramebuf::legendData(mode);
|
||||
if (mode == OverlayMode::BitAssigments) {
|
||||
data->addEntry(colorBitAssignment1, colorBitAssignment2, QObject::tr("Bit Assignment"));
|
||||
} else {
|
||||
data->addEntry(colorPixelInterpretation, QObject::tr("Pixel Interpretation"));
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
void ConverterFramebufMono::paintOverlay(OverlayPainter &p, OverlayMode mode, const QImage &image) const
|
||||
{
|
||||
ConverterFramebuf::paintOverlay(p, mode, image);
|
||||
if (mode == OverlayMode::BitAssigments) {
|
||||
const auto bitL = (_bitDirection == BitDirection::LSB ? "0" : QString::number(_unitSize-1));
|
||||
const auto bitH = (_bitDirection == BitDirection::LSB ? QString::number(_unitSize-1) : "0");
|
||||
bool colorFlag = false;
|
||||
if (_unitOrientation == UnitOrientation::Vertical) {
|
||||
for (int y = 0; y < p.imageSize().height(); y += _unitSize) {
|
||||
for (int x = 0; x < p.imageSize().width(); ++x) {
|
||||
QRect rect(x, y, 1, _unitSize);
|
||||
if (p.arePixelUpdated(rect)) {
|
||||
const auto color = colorFlag ? colorBitAssignment1 : colorBitAssignment2;
|
||||
p.drawPixelOutline(rect, color, 1);
|
||||
p.drawPixelText(QRect(x, y, 1, 1), color, bitL);
|
||||
p.drawPixelText(QRect(x, y+_unitSize-1, 1, 1), color, bitH);
|
||||
}
|
||||
colorFlag = !colorFlag;
|
||||
}
|
||||
if (p.imageSize().width() % 2 == 0) {
|
||||
colorFlag = !colorFlag;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int y = 0; y < p.imageSize().height(); ++y) {
|
||||
for (int x = 0; x < p.imageSize().width(); x += _unitSize) {
|
||||
QRect rect(x, y, _unitSize, 1);
|
||||
if (p.arePixelUpdated(rect)) {
|
||||
const auto color = colorFlag ? colorBitAssignment1 : colorBitAssignment2;
|
||||
p.drawPixelOutline(rect, color, 1);
|
||||
p.drawPixelText(QRect(x, y, 1, 1), color, bitH);
|
||||
p.drawPixelText(QRect(x+_unitSize-1, y, 1, 1), color, bitL);
|
||||
}
|
||||
colorFlag = !colorFlag;
|
||||
}
|
||||
if ((p.imageSize().width()/_unitSize) % 2 == 0) {
|
||||
colorFlag = !colorFlag;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (mode == OverlayMode::PixelInterpretation) {
|
||||
for (int y = 0; y < p.generatedSize().height(); ++y) {
|
||||
for (int x = 0; x < p.generatedSize().width(); ++x) {
|
||||
auto text = (getPixel(x, y, image) ? "1" : "0");
|
||||
const QRect rect(x, y, 1, 1);
|
||||
if (p.arePixelUpdated(rect)) {
|
||||
p.drawPixelText(rect, colorPixelInterpretation, text);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool ConverterFramebufMono::getPixel(int x, int y, const QImage &image)
|
||||
{
|
||||
if (x < 0 || y < 0 || x >= image.width() || y >= image.height()) {
|
||||
return false;
|
||||
}
|
||||
auto color = image.pixelColor(x, y);
|
||||
float h, s, l, a;
|
||||
color.getHslF(&h, &s, &l, &a);
|
||||
if (a < 0.5) {
|
||||
return false;
|
||||
}
|
||||
return l < 0.5;
|
||||
}
|
||||
|
||||
|
||||
uint32_t ConverterFramebufMono::readUnit(int x, int y, int dx, int dy, int count, const QImage &image)
|
||||
{
|
||||
uint32_t result = 0;
|
||||
for (int i = 0; i < count; ++i) {
|
||||
result <<= 1;
|
||||
if (getPixel(x, y, image)) {
|
||||
result |= 0b1;
|
||||
}
|
||||
x += dx;
|
||||
y += dy;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
//
|
||||
// (c)2021 by Lucky Resistor. https://luckyresistor.me/
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "ConverterFramebuf.hpp"
|
||||
|
||||
|
||||
/// The base class of all mono converters
|
||||
///
|
||||
class ConverterFramebufMono : public ConverterFramebuf
|
||||
{
|
||||
protected:
|
||||
enum class UnitOrientation {
|
||||
Horizontal,
|
||||
Vertical
|
||||
};
|
||||
|
||||
enum class BitDirection {
|
||||
LSB,
|
||||
MSB
|
||||
};
|
||||
|
||||
public:
|
||||
/// Create a new mono converter.
|
||||
///
|
||||
/// @param displayName The display name.
|
||||
/// @param unitOrientation The unit direction.
|
||||
/// @param unitSize The number of bits per unit.
|
||||
///
|
||||
ConverterFramebufMono(
|
||||
const QString &displayName,
|
||||
UnitOrientation unitOrientation,
|
||||
BitDirection bitDirection,
|
||||
int unitSize);
|
||||
|
||||
public: // Converter interface
|
||||
QSize generatedSize(const QSize &imageSize) const override;
|
||||
LegendDataPtr legendData(OverlayMode mode) const override;
|
||||
void paintOverlay(OverlayPainter &p, OverlayMode mode, const QImage &image) const override;
|
||||
|
||||
protected:
|
||||
/// Interpret a single pixel.
|
||||
///
|
||||
/// Returns `false` if the pixel is out of bounds.
|
||||
///
|
||||
static bool getPixel(int x, int y, const QImage &image);
|
||||
|
||||
/// Read a single unit.
|
||||
///
|
||||
static uint32_t readUnit(int x, int y, int dx, int dy, int count, const QImage &image);
|
||||
|
||||
/// The colors for the bit assignments
|
||||
///
|
||||
static constexpr QColor colorBitAssignment1 = QColor(240, 40, 40);
|
||||
static constexpr QColor colorBitAssignment2 = QColor(240, 80, 80);
|
||||
static constexpr QColor colorPixelInterpretation = QColor(240, 240, 40);
|
||||
|
||||
protected:
|
||||
UnitOrientation _unitOrientation; ///< The unit orientatioon.
|
||||
BitDirection _bitDirection; ///< The bit direction.
|
||||
int _unitSize; ///< The number of bits per unit.
|
||||
};
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
//
|
||||
// (c)2021 by Lucky Resistor. https://luckyresistor.me/
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
#include "ConverterFramebufMonoHLSB.hpp"
|
||||
|
||||
|
||||
#include <QtCore/QTextStream>
|
||||
|
||||
|
||||
ConverterFramebufMonoHLSB::ConverterFramebufMonoHLSB()
|
||||
: ConverterFramebufMono("MicroPython Framebuf Mono HLSB", UnitOrientation::Horizontal, BitDirection::LSB, 8)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
QString ConverterFramebufMonoHLSB::generateCode(const QImage &image, const QVariantMap&) const
|
||||
{
|
||||
QByteArray data;
|
||||
for (int y = 0; y < image.height(); ++y) {
|
||||
for (int x = 0; x < image.width(); x += 8) {
|
||||
data.append(static_cast<uint8_t>(readUnit(x, y, 1, 0, 8, image)));
|
||||
}
|
||||
}
|
||||
return createCode(data, generatedSize(image.size()), "MONO_HLSB");
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
//
|
||||
// (c)2021 by Lucky Resistor. https://luckyresistor.me/
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "ConverterFramebufMono.hpp"
|
||||
|
||||
|
||||
class ConverterFramebufMonoHLSB : public ConverterFramebufMono
|
||||
{
|
||||
public:
|
||||
ConverterFramebufMonoHLSB();
|
||||
|
||||
public: // Converter interface
|
||||
QString generateCode(const QImage &image, const QVariantMap ¶meter) const override;
|
||||
};
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
//
|
||||
// (c)2021 by Lucky Resistor. https://luckyresistor.me/
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
#include "ConverterFramebufMonoHMSB.hpp"
|
||||
|
||||
|
||||
ConverterFramebufMonoHMSB::ConverterFramebufMonoHMSB()
|
||||
: ConverterFramebufMono("MicroPython Framebuf Mono HMSB", UnitOrientation::Horizontal,BitDirection::MSB, 8)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
QString ConverterFramebufMonoHMSB::generateCode(const QImage &image, const QVariantMap&) const
|
||||
{
|
||||
QByteArray data;
|
||||
for (int y = 0; y < image.height(); ++y) {
|
||||
for (int x = 0; x < image.width(); x += 8) {
|
||||
data.append(static_cast<uint8_t>(readUnit(x+7, y, -1, 0, 8, image)));
|
||||
}
|
||||
}
|
||||
return createCode(data, generatedSize(image.size()), "MONO_HMSB");
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
//
|
||||
// (c)2021 by Lucky Resistor. https://luckyresistor.me/
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "ConverterFramebufMono.hpp"
|
||||
|
||||
|
||||
class ConverterFramebufMonoHMSB : public ConverterFramebufMono
|
||||
{
|
||||
public:
|
||||
ConverterFramebufMonoHMSB();
|
||||
|
||||
public: // Converter interface
|
||||
QString generateCode(const QImage &image, const QVariantMap ¶meter) const override;
|
||||
};
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
//
|
||||
// (c)2021 by Lucky Resistor. https://luckyresistor.me/
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
#include "ConverterFramebufMonoVLSB.hpp"
|
||||
|
||||
|
||||
ConverterFramebufMonoVLSB::ConverterFramebufMonoVLSB()
|
||||
: ConverterFramebufMono("MicroPython Framebuf Mono VLSB", UnitOrientation::Vertical, BitDirection::LSB, 8)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
QString ConverterFramebufMonoVLSB::generateCode(const QImage &image, const QVariantMap&) const
|
||||
{
|
||||
QByteArray data;
|
||||
for (int y = 0; y < image.height(); y += 8) {
|
||||
for (int x = 0; x < image.width(); ++x) {
|
||||
data.append(static_cast<uint8_t>(readUnit(x, y+7, 0, -1, 8, image)));
|
||||
}
|
||||
}
|
||||
return createCode(data, generatedSize(image.size()), "MONO_VLSB");
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
//
|
||||
// (c)2021 by Lucky Resistor. https://luckyresistor.me/
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "ConverterFramebufMono.hpp"
|
||||
|
||||
|
||||
class ConverterFramebufMonoVLSB : public ConverterFramebufMono
|
||||
{
|
||||
public:
|
||||
ConverterFramebufMonoVLSB();
|
||||
|
||||
public: // Converter interface
|
||||
QString generateCode(const QImage &image, const QVariantMap ¶meter) const override;
|
||||
};
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
//
|
||||
// (c)2021 by Lucky Resistor. https://luckyresistor.me/
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
#include "LegendData.hpp"
|
||||
|
||||
|
||||
#include "LegendEntry.hpp"
|
||||
|
||||
|
||||
LegendDataPtr LegendData::create()
|
||||
{
|
||||
return LegendDataPtr(new LegendData());
|
||||
}
|
||||
|
||||
|
||||
LegendData::~LegendData()
|
||||
{
|
||||
qDeleteAll(_entryList);
|
||||
}
|
||||
|
||||
|
||||
void LegendData::addEntry(const QColor &color, const QString &text)
|
||||
{
|
||||
_entryList.append(new LegendEntry(color, text));
|
||||
}
|
||||
|
||||
|
||||
void LegendData::addEntry(const QColor &color1, const QColor &color2, const QString &text)
|
||||
{
|
||||
_entryList.append(new LegendEntry(color1, color2, text));
|
||||
}
|
||||
|
||||
|
||||
const QList<const LegendEntry*>& LegendData::entryList() const
|
||||
{
|
||||
return _entryList;
|
||||
}
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
//
|
||||
// (c)2021 by Lucky Resistor. https://luckyresistor.me/
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <QtGui/QColor>
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QSharedPointer>
|
||||
|
||||
|
||||
class LegendEntry;
|
||||
|
||||
|
||||
class LegendData;
|
||||
using LegendDataPtr = QSharedPointer<LegendData>;
|
||||
|
||||
|
||||
/// Legend data.
|
||||
///
|
||||
class LegendData
|
||||
{
|
||||
public:
|
||||
/// Create a new legend data object.
|
||||
///
|
||||
static LegendDataPtr create();
|
||||
|
||||
private:
|
||||
/// private ctor
|
||||
///
|
||||
LegendData() = default;
|
||||
|
||||
public:
|
||||
/// dtor
|
||||
///
|
||||
~LegendData();
|
||||
|
||||
public:
|
||||
/// Add a new entry to the legend.
|
||||
///
|
||||
/// @param color The color.
|
||||
/// @param text The text for the entry.
|
||||
///
|
||||
void addEntry(const QColor &color, const QString &text);
|
||||
|
||||
/// Add a new entry to the legend.
|
||||
///
|
||||
/// @param color1 The first color.
|
||||
/// @param color2 The second color.
|
||||
/// @param text The text for the entry.
|
||||
///
|
||||
void addEntry(const QColor &color1, const QColor &color2, const QString &text);
|
||||
|
||||
/// Get the list with all entries.
|
||||
///
|
||||
const QList<const LegendEntry*>& entryList() const;
|
||||
|
||||
private:
|
||||
QList<const LegendEntry*> _entryList; ///< The list with all entries.
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
//
|
||||
// (c)2021 by Lucky Resistor. https://luckyresistor.me/
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
#include "LegendEntry.hpp"
|
||||
|
||||
|
||||
LegendEntry::LegendEntry(const QColor &color, const QString &text)
|
||||
: _color1(color), _text(text)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
LegendEntry::LegendEntry(const QColor &color1, const QColor &color2, const QString &text)
|
||||
: _color1(color1), _color2(color2), _text(text)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
QColor LegendEntry::color1() const
|
||||
{
|
||||
return _color1;
|
||||
}
|
||||
|
||||
|
||||
QColor LegendEntry::color2() const
|
||||
{
|
||||
return _color2;
|
||||
}
|
||||
|
||||
|
||||
QString LegendEntry::text() const
|
||||
{
|
||||
return _text;
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
//
|
||||
// (c)2021 by Lucky Resistor. https://luckyresistor.me/
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <QtGui/QColor>
|
||||
#include <QtCore/QString>
|
||||
|
||||
|
||||
/// A entry in the legend data.
|
||||
///
|
||||
class LegendEntry
|
||||
{
|
||||
public:
|
||||
enum Identifier : int {
|
||||
BitmapSize = 0,
|
||||
BitAssignment = 1,
|
||||
ReadDirection = 2,
|
||||
};
|
||||
|
||||
public:
|
||||
LegendEntry(const QColor &color, const QString &text);
|
||||
LegendEntry(const QColor &color1, const QColor &color2, const QString &text);
|
||||
|
||||
public:
|
||||
QColor color1() const;
|
||||
QColor color2() const;
|
||||
QString text() const;
|
||||
|
||||
private:
|
||||
QColor _color1;
|
||||
QColor _color2;
|
||||
QString _text;
|
||||
};
|
||||
|
|
@ -0,0 +1,303 @@
|
|||
//
|
||||
// (c)2021 by Lucky Resistor. https://luckyresistor.me/
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
#include "MainWindow.hpp"
|
||||
|
||||
|
||||
#include "BitmapPanel.hpp"
|
||||
#include "ConverterFramebufMonoVLSB.hpp"
|
||||
#include "ConverterFramebufMonoHLSB.hpp"
|
||||
#include "ConverterFramebufMonoHMSB.hpp"
|
||||
|
||||
#include <QtCore/QSettings>
|
||||
#include <QtGui/QAction>
|
||||
#include <QtGui/QClipboard>
|
||||
#include <QtWidgets/QComboBox>
|
||||
#include <QtWidgets/QFrame>
|
||||
#include <QtWidgets/QLabel>
|
||||
#include <QtWidgets/QPushButton>
|
||||
#include <QtWidgets/QVBoxLayout>
|
||||
#include <QtWidgets/QMenuBar>
|
||||
#include <QtWidgets/QMessageBox>
|
||||
#include <QtWidgets/QApplication>
|
||||
#include <QtWidgets/QFileDialog>
|
||||
#include <QtWidgets/QPlainTextEdit>
|
||||
#include <QtWidgets/QScrollArea>
|
||||
#include <QtWidgets/QSplitter>
|
||||
|
||||
|
||||
MainWindow::MainWindow(QWidget *parent)
|
||||
: QMainWindow(parent)
|
||||
{
|
||||
initializeConverterList();
|
||||
initializeUi();
|
||||
initializeMenu();
|
||||
loadSettings();
|
||||
}
|
||||
|
||||
|
||||
MainWindow::~MainWindow()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::initializeConverterList()
|
||||
{
|
||||
_converterList.append(new ConverterFramebufMonoVLSB());
|
||||
_converterList.append(new ConverterFramebufMonoHMSB());
|
||||
_converterList.append(new ConverterFramebufMonoHLSB());
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::initializeUi()
|
||||
{
|
||||
setMinimumSize(800, 600);
|
||||
setWindowTitle(tr("Micropython Bitmap Tool by Lucky Resistor"));
|
||||
|
||||
auto centralWidget = new QWidget();
|
||||
centralWidget->setObjectName("CentralWidget");
|
||||
setCentralWidget(centralWidget);
|
||||
|
||||
auto mainLayout = new QHBoxLayout(centralWidget);
|
||||
mainLayout->setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
auto settingsPanel = new QFrame();
|
||||
settingsPanel->setObjectName("SettingsPanel");
|
||||
mainLayout->addWidget(settingsPanel);
|
||||
|
||||
auto settingsLayout = new QVBoxLayout(settingsPanel);
|
||||
settingsLayout->setSpacing(4);
|
||||
|
||||
auto logo = new QLabel();
|
||||
logo->setFixedSize(300, 250);
|
||||
logo->setPixmap(QPixmap(":/images/AppLogo.png"));
|
||||
settingsLayout->addWidget(logo);
|
||||
auto versionLabel = new QLabel(tr("<b>Version %1</b>").arg(qApp->applicationVersion()));
|
||||
versionLabel->setAlignment(Qt::AlignCenter);
|
||||
settingsLayout->addWidget(versionLabel);
|
||||
settingsLayout->addSpacing(16);
|
||||
|
||||
settingsLayout->addWidget(new QLabel(tr("Generated Format:")));
|
||||
_formatSelector = new QComboBox();
|
||||
for (auto converter : _converterList) {
|
||||
_formatSelector->addItem(converter->displayName());
|
||||
}
|
||||
_formatSelector->setCurrentIndex(0);
|
||||
settingsLayout->addWidget(_formatSelector);
|
||||
|
||||
settingsLayout->addStretch();
|
||||
|
||||
settingsLayout->addWidget(new QLabel(tr("<b>Loaded Bitmap Info:</b>")));
|
||||
_bitmapInfo = new QLabel(tr("No Bitmap Loaded"));
|
||||
_bitmapInfo->setObjectName("BitmapInfo");
|
||||
_bitmapInfo->setMinimumHeight(200);
|
||||
_bitmapInfo->setAlignment(Qt::AlignTop|Qt::AlignLeft);
|
||||
settingsLayout->addWidget(_bitmapInfo);
|
||||
|
||||
auto loadButton = new QPushButton();
|
||||
loadButton->setText(tr("Load Bitmap"));
|
||||
settingsLayout->addWidget(loadButton);
|
||||
connect(loadButton, &QPushButton::clicked, this, &MainWindow::onLoadBitmap);
|
||||
|
||||
auto previewSplittter = new QSplitter(Qt::Vertical);
|
||||
previewSplittter->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
previewSplittter->setChildrenCollapsible(false);
|
||||
mainLayout->addWidget(previewSplittter);
|
||||
|
||||
_bitmapPanel = new BitmapPanel();
|
||||
previewSplittter->addWidget(_bitmapPanel);
|
||||
|
||||
auto codePanel = new QWidget();
|
||||
codePanel->setMinimumHeight(200);
|
||||
auto codeLayout = new QVBoxLayout(codePanel);
|
||||
codeLayout->setContentsMargins(16, 4, 16, 16);
|
||||
codeLayout->setSpacing(4);
|
||||
codeLayout->addWidget(new QLabel(tr("Generated Code:")));
|
||||
_codePreview = new QPlainTextEdit();
|
||||
_codePreview->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
_codePreview->setReadOnly(true);
|
||||
_codePreview->setWordWrapMode(QTextOption::NoWrap);
|
||||
codeLayout->addWidget(_codePreview);
|
||||
|
||||
#ifdef Q_OS_WIN32
|
||||
_codePreview->setFont(QFont("Consolas", 12));
|
||||
#else
|
||||
#ifdef Q_OS_MAC
|
||||
_codePreview->setFont(QFont("Menlo", 12));
|
||||
#else
|
||||
_codePreview->setFont(QFont("Lucida Console", 12));
|
||||
#endif
|
||||
#endif
|
||||
|
||||
auto codeActions = new QFrame();
|
||||
auto codeActionsLayout = new QHBoxLayout(codeActions);
|
||||
codeActionsLayout->setContentsMargins(0, 0, 0, 0);
|
||||
codeActionsLayout->setSpacing(4);
|
||||
codeActionsLayout->addStretch();
|
||||
|
||||
auto copyCodeButton = new QPushButton();
|
||||
copyCodeButton->setText(tr("Copy Code"));
|
||||
codeActionsLayout->addWidget(copyCodeButton);
|
||||
connect(copyCodeButton, &QPushButton::clicked, [=]{
|
||||
qApp->clipboard()->setText(_codePreview->toPlainText());
|
||||
});
|
||||
codeLayout->addWidget(codeActions);
|
||||
|
||||
previewSplittter->addWidget(codePanel);
|
||||
previewSplittter->setStretchFactor(0, 4);
|
||||
previewSplittter->setStretchFactor(1, 1);
|
||||
|
||||
connect(_formatSelector, &QComboBox::currentIndexChanged, [=]{
|
||||
_bitmapPanel->setConverter(selectedConverter());
|
||||
updateBitmapInfo();
|
||||
updateCode();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::initializeMenu()
|
||||
{
|
||||
auto menuFile = menuBar()->addMenu(tr("File"));
|
||||
auto actionLoadBitmap = menuFile->addAction(tr("Load Bitmap..."));
|
||||
actionLoadBitmap->setShortcut(QKeySequence("Ctrl+O"));
|
||||
connect(actionLoadBitmap, &QAction::triggered, this, &MainWindow::onLoadBitmap);
|
||||
auto actionQuit = menuFile->addAction(tr("Quit"));
|
||||
connect(actionQuit, &QAction::triggered, [=]{
|
||||
qApp->quit();
|
||||
});
|
||||
|
||||
auto menuHelp = menuBar()->addMenu(tr("Help"));
|
||||
auto actionAbout = menuHelp->addAction(tr("About..."));
|
||||
connect(actionAbout, &QAction::triggered, [=]{
|
||||
QMessageBox::about(this, tr("Micropython Bitmap Tool by Lucky Resistor"),
|
||||
tr("<h1>Micropython Bitmap Tool</h1><p>(c)2021 by Lucky Resistor</p>"
|
||||
"<p><b>Version %1</b></p>").arg(qApp->applicationVersion()));
|
||||
});
|
||||
auto actionAboutQt = menuHelp->addAction(tr("Information About Qt..."));
|
||||
connect(actionAboutQt, &QAction::triggered, [=]{
|
||||
QMessageBox::aboutQt(this);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::loadSettings()
|
||||
{
|
||||
QSettings settings;
|
||||
restoreGeometry(settings.value("mainWindow.geometry").toByteArray());
|
||||
restoreState(settings.value("mainWindow.state").toByteArray());
|
||||
_formatSelector->setCurrentIndex(settings.value("format.index").toInt(0));
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::saveSettings()
|
||||
{
|
||||
QSettings settings;
|
||||
settings.setValue("mainWindow.geometry", saveGeometry());
|
||||
settings.setValue("mainWindow.state", saveState());
|
||||
settings.setValue("format.index", _formatSelector->currentIndex());
|
||||
}
|
||||
|
||||
|
||||
Converter *MainWindow::selectedConverter() const
|
||||
{
|
||||
auto converter = _converterList.value(_formatSelector->currentIndex());
|
||||
if (converter == nullptr) {
|
||||
converter = _converterList.first();
|
||||
}
|
||||
return converter;
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::updateBitmapInfo()
|
||||
{
|
||||
QString text;
|
||||
QTextStream ts(&text);
|
||||
ts << "<p>";
|
||||
ts << "Bitmap Size: " << _currentImage.width() << "x" << _currentImage.height() << "<br>";
|
||||
ts << "Bit Depth: " << _currentImage.depth() << "<br>";
|
||||
ts << "Color Format: ";
|
||||
switch (_currentImage.pixelFormat().colorModel()) {
|
||||
case QPixelFormat::RGB: ts << "RGB"; break;
|
||||
case QPixelFormat::BGR: ts << "BGR"; break;
|
||||
case QPixelFormat::Indexed: ts << "Indexed"; break;
|
||||
case QPixelFormat::Grayscale: ts << "Grayscale"; break;
|
||||
case QPixelFormat::CMYK: ts << "CMYK"; break;
|
||||
case QPixelFormat::HSL: ts << "HSL"; break;
|
||||
case QPixelFormat::HSV: ts << "HSV"; break;
|
||||
case QPixelFormat::YUV: ts << "YUV"; break;
|
||||
case QPixelFormat::Alpha: ts << "Alpha"; break;
|
||||
}
|
||||
ts << "<br>";
|
||||
const auto gs = selectedConverter()->generatedSize(_currentImage.size());
|
||||
ts << "Generated Size: " << gs.width() << "x" << gs.height() << "</p>";
|
||||
_bitmapInfo->setText(text);
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::updateCode()
|
||||
{
|
||||
QString code;
|
||||
if (!_currentImage.isNull()) {
|
||||
code = selectedConverter()->generateCode(_currentImage, QVariantMap());
|
||||
}
|
||||
_codePreview->setPlainText(code);
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::onLoadBitmap()
|
||||
{
|
||||
QSettings settings;
|
||||
auto lastDir = settings.value("bitmap.lastDir").toString();
|
||||
auto fileName = QFileDialog::getOpenFileName(
|
||||
this,
|
||||
tr("Open Bitmap"),
|
||||
lastDir,
|
||||
tr("Images (*.png *.jpg *.jpeg *.gif *.pbm *.pgm *.ppm *.xbm *.xpm *.bpm)"));
|
||||
if (fileName.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
QFileInfo fileInfo(fileName);
|
||||
settings.setValue("bitmap.lastDir", fileInfo.absoluteDir().path());
|
||||
QImage newImage;
|
||||
if (!newImage.load(fileName)) {
|
||||
QMessageBox::warning(this, tr("Loading Image Failed"),
|
||||
tr("<h1>Failed to load the image</h1>"
|
||||
"<p>Could not load the specified image file. "
|
||||
"Make sure the image is in a supported format.</p>"));
|
||||
return;
|
||||
}
|
||||
if (newImage.width() > 0x100 || newImage.height() > 0x100) {
|
||||
QMessageBox::warning(this, tr("Image is Too Large"),
|
||||
tr("<h1>Image is Too Large</h1>"
|
||||
"<p>One dimension of the loaded image is larger than "
|
||||
"256 pixel. This software is designed for small bitmaps.</p>"));
|
||||
return;
|
||||
}
|
||||
|
||||
_currentImage = newImage;
|
||||
_bitmapPanel->setImage(newImage);
|
||||
_bitmapPanel->setConverter(selectedConverter());
|
||||
updateBitmapInfo();
|
||||
updateCode();
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::closeEvent(QCloseEvent *event)
|
||||
{
|
||||
saveSettings();
|
||||
QMainWindow::closeEvent(event);
|
||||
}
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
//
|
||||
// (c)2021 by Lucky Resistor. https://luckyresistor.me/
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <QtWidgets/QMainWindow>
|
||||
|
||||
|
||||
class Converter;
|
||||
class QPlainTextEdit;
|
||||
class QComboBox;
|
||||
class QLabel;
|
||||
class BitmapPanel;
|
||||
|
||||
|
||||
/// The main widnow
|
||||
///
|
||||
class MainWindow : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
MainWindow(QWidget *parent = nullptr);
|
||||
~MainWindow() override;
|
||||
|
||||
private:
|
||||
/// Initialize the converter list
|
||||
///
|
||||
void initializeConverterList();
|
||||
|
||||
/// Initialize the user interface.
|
||||
///
|
||||
void initializeUi();
|
||||
|
||||
/// Initialize the menu
|
||||
///
|
||||
void initializeMenu();
|
||||
|
||||
/// Load all settings
|
||||
///
|
||||
void loadSettings();
|
||||
|
||||
/// Save all settings.
|
||||
///
|
||||
void saveSettings();
|
||||
|
||||
/// The current converter.
|
||||
///
|
||||
Converter* selectedConverter() const;
|
||||
|
||||
/// Update the bitmap info.
|
||||
///
|
||||
void updateBitmapInfo();
|
||||
|
||||
/// Update the code.
|
||||
///
|
||||
void updateCode();
|
||||
|
||||
private Q_SLOTS:
|
||||
/// Load a bitmap.
|
||||
///
|
||||
void onLoadBitmap();
|
||||
|
||||
protected: // Implement QWidget
|
||||
void closeEvent(QCloseEvent *event) override;
|
||||
|
||||
private:
|
||||
QComboBox *_formatSelector; ///< The format selector.
|
||||
QPlainTextEdit *_codePreview; ///< The generated code.
|
||||
BitmapPanel *_bitmapPanel; ///< The bitmap panel.
|
||||
QImage _currentImage; ///< The current loaded image
|
||||
QLabel *_bitmapInfo; ///< The label with the image info.
|
||||
QList<Converter*> _converterList; ///< A list of available converters.
|
||||
};
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
QT += core gui
|
||||
|
||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||
|
||||
CONFIG += c++17
|
||||
|
||||
TARGET = "MicroPython Bitmap Tool"
|
||||
|
||||
# You can make your code fail to compile if it uses deprecated APIs.
|
||||
# In order to do so, uncomment the following line.
|
||||
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
||||
|
||||
SOURCES += \
|
||||
BitmapPanel.cpp \
|
||||
BitmapPreview.cpp \
|
||||
Converter.cpp \
|
||||
ConverterFramebuf.cpp \
|
||||
ConverterFramebufMono.cpp \
|
||||
ConverterFramebufMonoHLSB.cpp \
|
||||
ConverterFramebufMonoHMSB.cpp \
|
||||
ConverterFramebufMonoVLSB.cpp \
|
||||
LegendData.cpp \
|
||||
LegendEntry.cpp \
|
||||
OverlayPainter.cpp \
|
||||
main.cpp \
|
||||
MainWindow.cpp
|
||||
|
||||
HEADERS += \
|
||||
BitmapPanel.hpp \
|
||||
BitmapPreview.hpp \
|
||||
Converter.hpp \
|
||||
ConverterFramebuf.hpp \
|
||||
ConverterFramebufMono.hpp \
|
||||
ConverterFramebufMonoHLSB.hpp \
|
||||
ConverterFramebufMonoHMSB.hpp \
|
||||
ConverterFramebufMonoVLSB.hpp \
|
||||
LegendData.hpp \
|
||||
LegendEntry.hpp \
|
||||
MainWindow.hpp \
|
||||
OverlayMode.hpp \
|
||||
OverlayPainter.hpp
|
||||
|
||||
RESOURCES += \
|
||||
data/data.qrc
|
||||
|
||||
macos:ICON = data/AppIcon.icns
|
||||
win32:RC_ICONS = data/AppIcon.ico
|
||||
|
||||
# Default rules for deployment.
|
||||
qnx: target.path = /tmp/$${TARGET}/bin
|
||||
else: unix:!android: target.path = /opt/$${TARGET}/bin
|
||||
!isEmpty(target.path): INSTALLS += target
|
||||
|
||||
DISTFILES += \
|
||||
data/application.css
|
|
@ -0,0 +1,25 @@
|
|||
//
|
||||
// (c)2021 by Lucky Resistor. https://luckyresistor.me/
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
#pragma once
|
||||
|
||||
|
||||
enum class OverlayMode : int {
|
||||
None = 0,
|
||||
BitAssigments = 1,
|
||||
PixelInterpretation = 2
|
||||
};
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
//
|
||||
// (c)2021 by Lucky Resistor. https://luckyresistor.me/
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
#include "OverlayPainter.hpp"
|
||||
|
||||
|
||||
OverlayPainter::OverlayPainter(
|
||||
QPainter *painter,
|
||||
const QRect &updateRect,
|
||||
int displayFactor,
|
||||
const QSize &imageSize,
|
||||
const QSize &generatedSize)
|
||||
:
|
||||
_p(painter),
|
||||
_updateRect(updateRect),
|
||||
_displayFactor(displayFactor),
|
||||
_imageSize(imageSize),
|
||||
_generatedSize(generatedSize)
|
||||
{
|
||||
#ifdef Q_OS_WIN32
|
||||
_pixelFont = QFont("Consolas");
|
||||
#else
|
||||
#ifdef Q_OS_MAC
|
||||
_pixelFont = QFont("Menlo");
|
||||
#else
|
||||
_pixelFont = QFont("Lucida Console");
|
||||
#endif
|
||||
#endif
|
||||
_pixelFont.setPixelSize(displayFactor - 1);
|
||||
_p->setFont(_pixelFont);
|
||||
}
|
||||
|
||||
|
||||
void OverlayPainter::drawPixelOutline(const QRect &rect, const QColor &outlineColor, int outlineWidth, int offset)
|
||||
{
|
||||
_p->setBrush(QBrush());
|
||||
_p->setPen(QPen(outlineColor, outlineWidth, Qt::SolidLine, Qt::SquareCap, Qt::MiterJoin));
|
||||
const qreal offset1 = static_cast<qreal>(outlineWidth)/2 - static_cast<qreal>(offset);
|
||||
const qreal offset2 = -static_cast<qreal>(outlineWidth)/2 + static_cast<qreal>(offset);
|
||||
const auto rectToDraw = pixelRectF(rect).adjusted(offset1, offset1, offset2, offset2);
|
||||
_p->drawRect(rectToDraw);
|
||||
}
|
||||
|
||||
|
||||
void OverlayPainter::drawPixelText(const QRect &rect, const QColor &textColor, const QString &text)
|
||||
{
|
||||
_p->setBrush(QBrush());
|
||||
_p->setPen(QPen(textColor));
|
||||
_p->drawText(pixelRectF(rect), Qt::AlignCenter, text);
|
||||
}
|
||||
|
||||
|
||||
bool OverlayPainter::arePixelUpdated(const QRect &rect) const
|
||||
{
|
||||
const auto rectToDraw = pixelRectF(rect).adjusted(-64, -64, 64, 64);
|
||||
return rectToDraw.intersects(_updateRect);
|
||||
}
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
//
|
||||
// (c)2021 by Lucky Resistor. https://luckyresistor.me/
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <QtGui/QPainter>
|
||||
|
||||
|
||||
/// The overlay painter.
|
||||
///
|
||||
class OverlayPainter
|
||||
{
|
||||
public:
|
||||
/// ctor
|
||||
///
|
||||
OverlayPainter(
|
||||
QPainter *painter,
|
||||
const QRect &updateRect,
|
||||
int displayFactor,
|
||||
const QSize &imageSize,
|
||||
const QSize &generatedSize);
|
||||
|
||||
public:
|
||||
/// Access the painter.
|
||||
///
|
||||
inline QPainter *painter() const { return _p; };
|
||||
|
||||
/// Access the display factor.
|
||||
///
|
||||
inline int displayFactor() const { return _displayFactor; };
|
||||
|
||||
/// Access the image size.
|
||||
///
|
||||
inline const QSize& imageSize() const { return _imageSize; }
|
||||
|
||||
/// Access the generated size.
|
||||
///
|
||||
inline const QSize& generatedSize() const { return _generatedSize; }
|
||||
|
||||
/// Access the image rect.
|
||||
///
|
||||
inline const QRect imageRect() const { return QRect(QPoint(0, 0), imageSize()); }
|
||||
|
||||
/// Access the generated rect
|
||||
///
|
||||
inline const QRect generatedRect() const { return QRect(QPoint(0, 0), generatedSize()); }
|
||||
|
||||
/// Get a rectangle for a pixal area.
|
||||
///
|
||||
inline QRectF pixelRectF(int x, int y, int width, int height) const {
|
||||
return QRectF(x * _displayFactor, y * _displayFactor, width * _displayFactor, height * _displayFactor);
|
||||
}
|
||||
|
||||
/// Get a rectangle for a pixel rect.
|
||||
///
|
||||
inline QRectF pixelRectF(const QRect &rect) const {
|
||||
return pixelRectF(rect.x(), rect.y(), rect.width(), rect.height());
|
||||
}
|
||||
|
||||
/// Draw a outline around a pixel area.
|
||||
///
|
||||
/// @param rect The rect for the pixel area.
|
||||
/// @param outlineColor The color of the outline.
|
||||
/// @param outlineWidth THe width of the outline in pixels.
|
||||
/// @param offset The offset of the outline. +1 = around the area, 0 in the area.
|
||||
///
|
||||
void drawPixelOutline(
|
||||
const QRect &rect,
|
||||
const QColor &outlineColor,
|
||||
int outlineWidth = 1,
|
||||
int offset = 0);
|
||||
|
||||
/// Write text into a pixel area
|
||||
///
|
||||
void drawPixelText(
|
||||
const QRect &rect,
|
||||
const QColor &textColor,
|
||||
const QString &text);
|
||||
|
||||
/// Check if a pixel region ready for repaint.
|
||||
///
|
||||
bool arePixelUpdated(const QRect &rect) const;
|
||||
|
||||
private:
|
||||
QPainter *_p; ///< The painter used.
|
||||
QRect _updateRect; ///< The update rect.
|
||||
int _displayFactor; ///< The display factor.
|
||||
QSize _imageSize; ///< The size of the image.
|
||||
QSize _generatedSize; ///< The generated size.
|
||||
QFont _pixelFont; ///< The font used to draw into the pixels.
|
||||
};
|
||||
|
|
@ -1 +1,5 @@
|
|||
# MicroPythonBitmapTool
|
||||
# MicroPython Bitmap Tool
|
||||
|
||||
https://luckyresistor.me/applications/micropython-bitmap-tool/
|
||||
|
||||
|
||||
|
|
Plik binarny nie jest wyświetlany.
Plik binarny nie jest wyświetlany.
Po Szerokość: | Wysokość: | Rozmiar: 126 KiB |
Plik binarny nie jest wyświetlany.
Po Szerokość: | Wysokość: | Rozmiar: 8.6 KiB |
Plik binarny nie jest wyświetlany.
Po Szerokość: | Wysokość: | Rozmiar: 19 KiB |
Plik binarny nie jest wyświetlany.
Po Szerokość: | Wysokość: | Rozmiar: 30 KiB |
|
@ -0,0 +1,16 @@
|
|||
|
||||
#CentralWidget, QMainWindow {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#SettingsPanel {
|
||||
background-color: #616875;
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
#BitmapInfo {
|
||||
border: 1px solid rgba(0,0,0,0.25);
|
||||
padding: 8px;
|
||||
margin: 0px 0px 16px 0px;
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
<RCC>
|
||||
<qresource prefix="/images">
|
||||
<file>AppLogo.png</file>
|
||||
<file>AppLogo@2x.png</file>
|
||||
<file>AppLogo@3x.png</file>
|
||||
</qresource>
|
||||
<qresource prefix="/stylesheet">
|
||||
<file>application.css</file>
|
||||
</qresource>
|
||||
</RCC>
|
|
@ -0,0 +1,38 @@
|
|||
//
|
||||
// (c)2021 by Lucky Resistor. https://luckyresistor.me/
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
#include "MainWindow.hpp"
|
||||
|
||||
#include <QtWidgets/QApplication>
|
||||
#include <QtCore/QFile>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication a(argc, argv);
|
||||
a.setApplicationName("MicroPython Bitmap Tool");
|
||||
a.setApplicationVersion("1.0");
|
||||
a.setApplicationDisplayName("MicroPython Bitmap Tool");
|
||||
a.setOrganizationDomain("luckyresistor.me");
|
||||
a.setOrganizationName("Lucky Resistoor");
|
||||
QFile styleSheet(":/stylesheet/application.css");
|
||||
styleSheet.open(QIODevice::ReadOnly);
|
||||
a.setStyleSheet(QString::fromUtf8(styleSheet.readAll()));
|
||||
styleSheet.close();
|
||||
|
||||
MainWindow w;
|
||||
w.show();
|
||||
return a.exec();
|
||||
}
|
Ładowanie…
Reference in New Issue