qt/LedOK/program/etext.cpp

732 lines
26 KiB
C++
Raw Permalink Normal View History

2024-08-07 18:18:37 +08:00
#include "etext.h"
#include "base/locolorselector.h"
#include "main.h"
#include "gutil/qgui.h"
2023-04-18 14:14:46 +08:00
#include <QButtonGroup>
#include <QFontComboBox>
#include <QMessageBox>
#include <QRadioButton>
#include <QSpinBox>
2024-08-07 18:18:37 +08:00
#include <QFileDialog>
2023-04-18 14:14:46 +08:00
#include <QStackedLayout>
#include <QTextBlock>
2023-10-23 14:58:29 +08:00
#if(QT_VERSION_MAJOR > 5)
#include <QStringConverter>
#else
2023-04-18 14:14:46 +08:00
#include <QTextCodec>
2023-10-23 14:58:29 +08:00
#endif
2023-04-18 14:14:46 +08:00
#include <QTimeEdit>
#include <QToolButton>
2023-05-15 16:06:10 +08:00
#include <QPainter>
2023-04-18 14:14:46 +08:00
static QColor charColors[]{"#fff","#f00","#f00","#f0f","#c0c","#ff0","#f80","#0f0","#0f0","#0a0","#0a0","#7b0","#00f","#00f","#0af","#0ef"};
2024-02-21 18:08:50 +08:00
QString playModes[]{"Flip", "Scroll", "Static"};
2023-04-18 14:14:46 +08:00
EText::EText(EBase *multiWin) : EBase(multiWin) {
mType = EBase::Text;
2024-02-21 18:08:50 +08:00
text = "<body>"+tr("Enter your text")+"</body>";
2023-04-18 14:14:46 +08:00
connect(this, &EText::sizeChanged, this, &EText::updImg);
updImg();
}
2023-10-23 14:58:29 +08:00
EText::EText(const JObj &json, EBase *multiWin) : EBase(multiWin) {
2023-04-18 14:14:46 +08:00
mType = EBase::Text;
setBaseAttr(json);
auto widget = json["widget"];
2024-02-21 18:08:50 +08:00
if(widget.isNull()) widget = json;
text = widget["text"].toString();
align = (Qt::Alignment) widget["align"].toInt();
backColor = widget["backColor"].toString("#00000000");
2023-04-18 14:14:46 +08:00
auto play = json["play"];
2024-02-21 18:08:50 +08:00
if(play.isNull()) {
playMode = json["playMode"].toString();
if(playMode=="Scroll") {
direction = json["direction"].toString();
speed = json["speed"].toInt();
headTailSpacing = json["headTailSpacing"].toInt();
}
} else {
playMode = playModes[play["style"].toInt()];
auto rolling = play["rolling"];
QString ds[]{"left", "top", "right", "bottom"};
direction = ds[rolling["rollingStyle"].toInt()];
speed = 1000/rolling["rollingSpeed"].toInt(33);
headTailSpacing = rolling["headTailSpacing"].toInt();
}
connect(this, &EText::sizeChanged, this, &EText::updImg);
updImg();
2023-04-18 14:14:46 +08:00
}
class TTextEdit : public QTextEdit {
public:
TTextEdit() {}
explicit TTextEdit(const QString &text) : QTextEdit(text){}
QSize minimumSizeHint() const override {
return sizeHint();
};
QSize sizeHint() const override {
auto size = QTextEdit::sizeHint();
auto minH = minimumHeight();
if(minH > 0) size.setHeight(minH+0xfff);
return size;
};
};
QWidget* EText::attrWgt() {
auto wgtAttr = new QWidget;
auto vBox = new QVBoxLayout(wgtAttr);
vBox->setContentsMargins(4, 0, 4, 0);
vBox->setSpacing(3);
addBaseAttrWgt(vBox);
2024-08-07 18:18:37 +08:00
auto hBox = new HBox(vBox);
hBox->addLabel(tr("Basic Properties"));
2023-04-18 14:14:46 +08:00
auto line = new QFrame;
line->setFrameShape(QFrame::HLine);
line->setFrameShadow(QFrame::Sunken);
hBox->addWidget(line, 1);
2024-08-07 18:18:37 +08:00
hBox = new HBox(vBox);
2023-04-18 14:14:46 +08:00
auto fdText = new TTextEdit("");
auto fdFontFamily = new QFontComboBox;
fdFontFamily->setEditable(false);
fdFontFamily->setCurrentFont(QFont("黑体"));
connect(fdFontFamily, &QFontComboBox::currentFontChanged, fdText, [fdText](const QFont &f) {
QTextCharFormat fmt;
fmt.setFontFamilies({f.family()});
QTextCursor cursor = fdText->textCursor();
if(! cursor.hasSelection()) cursor.select(QTextCursor::WordUnderCursor);
cursor.mergeCharFormat(fmt);
});
hBox->addWidget(fdFontFamily);
hBox->addStretch();
auto fdFontSize = new QSpinBox;
fdFontSize->setRange(4, 9999);
fdFontSize->setValue(16);
connect(fdFontSize, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, fdText, [fdText](int value) {
if(value <= 0) return;
QTextCharFormat fmt;
fmt.setProperty(QTextFormat::FontPixelSize, value);
QTextCursor cursor = fdText->textCursor();
if(! cursor.hasSelection()) cursor.select(QTextCursor::WordUnderCursor);
cursor.mergeCharFormat(fmt);
});
hBox->addWidget(fdFontSize);
2024-08-07 18:18:37 +08:00
hBox = new HBox(vBox);
2023-04-18 14:14:46 +08:00
hBox->setSpacing(3);
auto wTextAlignHL = new QPushButton(QIcon(":/res/program/TextAlignHL.png"), "");
wTextAlignHL->setStyleSheet("QPushButton{border: none; background: #bbb;} QPushButton:checked{background: #29c;}");
wTextAlignHL->setFixedSize(30, 30);
wTextAlignHL->setIconSize(QSize(30, 30));
wTextAlignHL->setCheckable(true);
wTextAlignHL->setChecked(true);
hBox->addWidget(wTextAlignHL);
auto wTextAlignHC = new QPushButton(QIcon(":/res/program/TextAlignHC.png"), "");
wTextAlignHC->setStyleSheet("QPushButton{border: none; background: #bbb;} QPushButton:checked{background: #29c;}");
wTextAlignHC->setFixedSize(30, 30);
wTextAlignHC->setIconSize(QSize(30, 30));
wTextAlignHC->setCheckable(true);
hBox->addWidget(wTextAlignHC);
auto wTextAlignHR = new QPushButton(QIcon(":/res/program/TextAlignHR.png"), "");
wTextAlignHR->setStyleSheet("QPushButton{border: none; background: #bbb;} QPushButton:checked{background: #29c;}");
wTextAlignHR->setFixedSize(30, 30);
wTextAlignHR->setIconSize(QSize(30, 30));
wTextAlignHR->setCheckable(true);
hBox->addWidget(wTextAlignHR);
hBox->addStretch();
auto fdFontBold = new QPushButton("B");
fdFontBold->setStyleSheet("QPushButton{background: #bbb; color: #888; font-size: 20px; font-weight: bold;} QPushButton:checked{background: #29c; color: #fff;}");
fdFontBold->setFixedSize(30, 30);
fdFontBold->setCheckable(true);
connect(fdFontBold, &QToolButton::toggled, fdText, [fdText](bool checked) {
QTextCharFormat fmt;
fmt.setFontWeight(checked ? QFont::Bold : QFont::Normal);
2024-08-07 18:18:37 +08:00
MergeFmt(fdText, fmt);
2023-04-18 14:14:46 +08:00
});
hBox->addWidget(fdFontBold);
auto fdFontItalic = new QPushButton("I");
fdFontItalic->setStyleSheet("QPushButton{background: #bbb; color: #888; font-size: 20px; font-style: italic;} QPushButton:checked{background: #29c; color: #fff;}");
fdFontItalic->setFixedSize(30, 30);
fdFontItalic->setCheckable(true);
connect(fdFontItalic, &QToolButton::toggled, fdText, [fdText](bool checked) {
QTextCharFormat fmt;
fmt.setFontItalic(checked);
2024-08-07 18:18:37 +08:00
MergeFmt(fdText, fmt);
2023-04-18 14:14:46 +08:00
});
hBox->addWidget(fdFontItalic);
auto fdFontUnderline = new QPushButton("U");
fdFontUnderline->setStyleSheet("QPushButton{background: #bbb; color: #888; font-size: 20px; text-decoration: underline;} QPushButton:checked{background: #29c; color: #fff;}");
fdFontUnderline->setFixedSize(30, 30);
fdFontUnderline->setCheckable(true);
connect(fdFontUnderline, &QToolButton::toggled, fdText, [fdText](bool checked) {
QTextCharFormat fmt;
fmt.setFontUnderline(checked);
2024-08-07 18:18:37 +08:00
MergeFmt(fdText, fmt);
2023-04-18 14:14:46 +08:00
});
hBox->addWidget(fdFontUnderline);
hBox->addStretch();
auto fdTextColor = new LoColorSelector("T", Qt::white);
fdTextColor->setToolTip(tr("Text Color"));
fdTextColor->setFixedSize(30, 30);
connect(fdTextColor, &LoColorSelector::sColorChanged, fdText, [fdText](const QColor &color) {
if(! color.isValid()) return;
QTextCharFormat fmt;
fmt.setForeground(color);
2024-08-07 18:18:37 +08:00
MergeFmt(fdText, fmt);
2023-04-18 14:14:46 +08:00
});
hBox->addWidget(fdTextColor);
2024-02-21 18:08:50 +08:00
auto fdBackColor = new LoColorSelector("B", backColor);
2023-04-18 14:14:46 +08:00
fdBackColor->setToolTip(tr("Back Color"));
fdBackColor->setFixedSize(30, 30);
connect(fdBackColor, &LoColorSelector::sColorChanged, this, [this](const QColor &color) {
if(! color.isValid()) return;
2024-02-21 18:08:50 +08:00
backColor = color;
2023-04-18 14:14:46 +08:00
updImg();
});
hBox->addWidget(fdBackColor);
auto fdRandomColor = new QPushButton(QIcon(":/res/random.png"), "");
fdRandomColor->setToolTip(tr("Colorful Text"));
fdRandomColor->setFixedSize(30, 30);
fdRandomColor->setIconSize(QSize(30, 30));
connect(fdRandomColor, &QPushButton::clicked, fdText, [fdText] {
auto cursor = fdText->textCursor();
auto len = fdText->document()->characterCount();
QTextCharFormat fmt;
int last = -1, idx;
for(int i=0; i<len; i++) {
cursor.setPosition(i, QTextCursor::MoveAnchor);
cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor);
while((idx = rand()%(sizeof(charColors)/sizeof(charColors[0])))==last) ;
last = idx;
fmt.setForeground(charColors[idx]);
cursor.mergeCharFormat(fmt);
}
});
hBox->addWidget(fdRandomColor);
2024-08-07 18:18:37 +08:00
hBox = new HBox(vBox);
2023-04-18 14:14:46 +08:00
hBox->setSpacing(3);
auto wTextAlignVT = new QPushButton(QIcon(":/res/program/TextAlignVT.png"), "");
wTextAlignVT->setStyleSheet("QPushButton{border: none; background: #bbb;} QPushButton:checked{background: #29c;}");
wTextAlignVT->setFixedSize(30, 30);
wTextAlignVT->setIconSize(QSize(30, 30));
wTextAlignVT->setCheckable(true);
hBox->addWidget(wTextAlignVT);
auto wTextAlignVC = new QPushButton(QIcon(":/res/program/TextAlignVC.png"), "");
wTextAlignVC->setStyleSheet("QPushButton{border: none; background: #bbb;} QPushButton:checked{background: #29c;}");
wTextAlignVC->setFixedSize(30, 30);
wTextAlignVC->setIconSize(QSize(30, 30));
wTextAlignVC->setCheckable(true);
hBox->addWidget(wTextAlignVC);
auto wTextAlignVB = new QPushButton(QIcon(":/res/program/TextAlignVB.png"), "");
wTextAlignVB->setStyleSheet("QPushButton{border: none; background: #bbb;} QPushButton:checked{background: #29c;}");
wTextAlignVB->setFixedSize(30, 30);
wTextAlignVB->setIconSize(QSize(30, 30));
wTextAlignVB->setCheckable(true);
hBox->addWidget(wTextAlignVB);
hBox->addStretch();
auto lb = new QLabel(tr("Kerning"));
lb->setToolTip(lb->text());
hBox->addWidget(lb);
2024-08-07 18:18:37 +08:00
auto edLetterSpacing = new QSpinBox;
edLetterSpacing->setMaximum(9999);
edLetterSpacing->setValue(100);
connect(edLetterSpacing, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this, fdText](int value) {
2023-04-18 14:14:46 +08:00
QTextCharFormat fmt;
fmt.setFontLetterSpacing(value);
2024-08-07 18:18:37 +08:00
auto cursor = fdText->textCursor();
2023-04-18 14:14:46 +08:00
if(! cursor.hasSelection()) cursor.select(QTextCursor::WordUnderCursor);
cursor.mergeCharFormat(fmt);
updImg();
});
2024-08-07 18:18:37 +08:00
hBox->addWidget(edLetterSpacing);
2023-04-18 14:14:46 +08:00
2024-08-07 18:18:37 +08:00
lb = new QLabel(tr("Line Height"));
2023-04-18 14:14:46 +08:00
lb->setToolTip(lb->text());
hBox->addWidget(lb);
2024-08-07 18:18:37 +08:00
auto edLineHeight = new QSpinBox;
edLineHeight->setRange(-999, 9999);
edLineHeight->setValue(100);
connect(edLineHeight, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this, fdText](int value) {
2023-04-18 14:14:46 +08:00
QTextBlockFormat fmt;
2024-08-07 18:18:37 +08:00
fmt.setLineHeight(value, QTextBlockFormat::ProportionalHeight);
2024-02-21 18:08:50 +08:00
auto cursor = fdText->textCursor();
2023-04-18 14:14:46 +08:00
if(! cursor.hasSelection()) cursor.select(QTextCursor::WordUnderCursor);
cursor.mergeBlockFormat(fmt);
updImg();
});
2024-08-07 18:18:37 +08:00
hBox->addWidget(edLineHeight);
hBox->addSpacing(-2);
hBox->addLabel("%");
2023-04-18 14:14:46 +08:00
2024-02-21 18:08:50 +08:00
auto fdAlignH = new QButtonGroup(wgtAttr);
fdAlignH->addButton(wTextAlignHL, Qt::AlignLeft);
fdAlignH->addButton(wTextAlignHC, Qt::AlignHCenter);
fdAlignH->addButton(wTextAlignHR, Qt::AlignRight);
connect(fdAlignH, &QButtonGroup::idClicked, this, [this, fdText](int value) {
2023-04-18 14:14:46 +08:00
QTextBlockFormat fmt;
fmt.setAlignment((Qt::Alignment) value);
QTextCursor cursor = fdText->textCursor();
cursor.mergeBlockFormat(fmt);
updImg();
});
2024-02-21 18:08:50 +08:00
auto fdAlignV = new QButtonGroup(wgtAttr);
fdAlignV->addButton(wTextAlignVT, Qt::AlignTop);
fdAlignV->addButton(wTextAlignVC, Qt::AlignVCenter);
fdAlignV->addButton(wTextAlignVB, Qt::AlignBottom);
connect(fdAlignV, &QButtonGroup::idClicked, this, [this](int value) {
align = (Qt::Alignment) value;
2023-04-18 14:14:46 +08:00
updImg();
});
2024-02-21 18:08:50 +08:00
auto v_align = align & Qt::AlignVertical_Mask;
2023-04-18 14:14:46 +08:00
if(v_align==Qt::AlignTop) wTextAlignVT->setChecked(true);
if(v_align==Qt::AlignVCenter) wTextAlignVC->setChecked(true);
if(v_align==Qt::AlignBottom) wTextAlignVB->setChecked(true);
fdText->setMinimumHeight(160);
auto doc = fdText->document();
if(doc) doc->setDocumentMargin(2);
auto font = fdText->font();
font.setFamilies({"Arial","黑体"});
font.setPixelSize(16);
if(! gTextAntialiasing) font.setStyleStrategy(QFont::NoAntialias);
fdText->setFont(font);
auto pal = fdText->palette();
pal.setColor(QPalette::Base, Qt::black);
pal.setColor(QPalette::Text, Qt::white);
fdText->setPalette(pal);
fdText->setFrameShape(QFrame::NoFrame);
fdText->setAcceptRichText(false);
2024-02-21 18:08:50 +08:00
fdText->setHtml(text);
2023-04-18 14:14:46 +08:00
connect(fdText, &QTextEdit::textChanged, this, [this, fdText] {
2024-02-21 18:08:50 +08:00
text = fdText->toHtml();
2023-04-18 14:14:46 +08:00
updImg();
});
2023-10-23 14:58:29 +08:00
connect(fdText, &QTextEdit::currentCharFormatChanged, this, [=](const QTextCharFormat &format) {
fdFontSize->blockSignals(true);
fdFontSize->setValue(format.font().pixelSize());
fdFontSize->blockSignals(false);
auto foreground = format.foreground();
fdTextColor->blockSignals(true);
fdTextColor->setColor(foreground.style()==Qt::NoBrush ? Qt::white : foreground.color());
fdTextColor->blockSignals(false);
2024-02-21 18:08:50 +08:00
2024-08-07 18:18:37 +08:00
auto spa = format.fontLetterSpacing();
edLetterSpacing->blockSignals(true);
edLetterSpacing->setValue(spa==0 ? 100 : spa);
edLetterSpacing->blockSignals(false);
2024-02-21 18:08:50 +08:00
auto cursor = fdText->textCursor();
auto blockFormat = cursor.blockFormat();
auto btn = fdAlignH->button(blockFormat.alignment() & Qt::AlignHorizontal_Mask);
if(btn) btn->setChecked(true);
2024-08-07 18:18:37 +08:00
edLineHeight->blockSignals(true);
edLineHeight->setValue(blockFormat.lineHeightType()==QTextBlockFormat::ProportionalHeight ? blockFormat.lineHeight() : 100);
edLineHeight->blockSignals(false);
2023-10-23 14:58:29 +08:00
});
2023-04-18 14:14:46 +08:00
vBox->addWidget(fdText);
2024-08-07 18:18:37 +08:00
hBox = new HBox(vBox);
2023-04-18 14:14:46 +08:00
hBox->addStretch();
auto pageInfoWgt = new QWidget;
auto hhh = new QHBoxLayout(pageInfoWgt);
hhh->setContentsMargins(0,0,0,0);
hhh->addWidget(new QLabel(tr("PageCount:")));
auto fdPageCnt = new QLabel(QString::number(mImgs.size()));
hhh->addWidget(fdPageCnt);
hhh->addSpacing(20);
hhh->addWidget(new QLabel(tr("page")));
auto fdPageIdx = new QSpinBox();
fdPageIdx->setRange(1, mImgs.size());
connect(fdPageIdx, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this](int idx) {
curIdx = idx - 1;
update();
});
hhh->addWidget(fdPageIdx);
hBox->addWidget(pageInfoWgt);
hBox->addStretch();
auto btnImport = new QPushButton(tr("Import txt File"));
btnImport->setProperty("ssType", "progManageTool");
2023-05-11 11:47:00 +08:00
connect(btnImport, &QPushButton::clicked, fdText, [=] {
auto filePath = QFileDialog::getOpenFileName(wgtAttr, tr("Select File"), gFileHome, "Txt(*.txt)");
2023-04-18 14:14:46 +08:00
if(filePath.isEmpty()) return;
2023-05-18 18:24:40 +08:00
QFile qFile(filePath);
if(! qFile.open(QFile::ReadOnly)) {
QMessageBox::critical(wgtAttr, tr("Fail"), tr("Cannot Open File")+": "+qFile.errorString()+"\n"+filePath);
2023-04-18 14:14:46 +08:00
return;
}
2023-05-18 18:24:40 +08:00
auto data = qFile.readAll();
qFile.close();
2023-10-23 14:58:29 +08:00
#if(QT_VERSION_MAJOR > 5)
#include <QStringConverter>
QStringDecoder decoder(QStringDecoder::Utf8);
QString text = decoder(data);
if(decoder.hasError()) text = QStringDecoder(QStringDecoder::System)(data);
#else
2023-04-18 14:14:46 +08:00
QTextCodec::ConverterState state;
2023-10-23 14:58:29 +08:00
auto text = QTextCodec::codecForName("UTF-8")->toUnicode(data.constData(), data.size(), &state);
2023-04-18 14:14:46 +08:00
if(state.invalidChars > 0) text = QString::fromLocal8Bit(data);
2023-10-23 14:58:29 +08:00
#endif
2023-04-18 14:14:46 +08:00
fdText->setText(text);
});
hBox->addWidget(btnImport);
2024-08-07 18:18:37 +08:00
hBox = new HBox(vBox);
2023-04-18 14:14:46 +08:00
hBox->addWidget(new QLabel(tr("Play Properties")));
line = new QFrame();
line->setFrameShape(QFrame::HLine);
line->setFrameShadow(QFrame::Sunken);
hBox->addWidget(line, 1);
2024-08-07 18:18:37 +08:00
hBox = new HBox(vBox);
2023-04-18 14:14:46 +08:00
hBox->addStretch();
auto fdFlip = new QRadioButton(tr("Flip"));
hBox->addWidget(fdFlip);
hBox->addStretch();
auto fdScroll = new QRadioButton(tr("Scroll"));
hBox->addWidget(fdScroll);
hBox->addStretch();
auto fdStatic = new QRadioButton(tr("Static"));
hBox->addWidget(fdStatic);
hBox->addStretch();
auto fdPlayStyle = new QButtonGroup(wgtAttr);
2024-02-21 18:08:50 +08:00
fdPlayStyle->addButton(fdFlip, 0);
fdPlayStyle->addButton(fdScroll, 1);
fdPlayStyle->addButton(fdStatic, 2);
if(playMode=="Flip") fdFlip->setChecked(true);
else if(playMode=="Scroll") fdScroll->setChecked(true);
else if(playMode=="Static") fdStatic->setChecked(true);
auto wgtAttrFlip = new QWidget;
auto wgtAttrScroll = new QWidget;
2023-04-18 14:14:46 +08:00
{
2024-02-21 18:08:50 +08:00
auto vBox = new VBox(wgtAttrScroll);
2023-04-18 14:14:46 +08:00
vBox->setContentsMargins(2, 0, 2, 0);
vBox->setSpacing(3);
2024-02-21 18:08:50 +08:00
auto hBox = new HBox(vBox);
auto label = new QLabel(tr("Head-Tail Spacing"));
2023-04-18 14:14:46 +08:00
label->setMinimumWidth(100);
hBox->addWidget(label);
2024-02-21 18:08:50 +08:00
auto fdHeadTailSpacing = new QSpinBox;
fdHeadTailSpacing->setRange(0, 9999);
fdHeadTailSpacing->setValue(headTailSpacing);
connect(fdHeadTailSpacing, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this](int value) {
headTailSpacing = value;
updImg();
2023-04-18 14:14:46 +08:00
});
2024-02-21 18:08:50 +08:00
hBox->addWidget(fdHeadTailSpacing);
2023-04-18 14:14:46 +08:00
hBox->addStretch();
2024-02-21 18:08:50 +08:00
hBox = new HBox(vBox);
2023-04-18 14:14:46 +08:00
label = new QLabel(tr("Scroll Style"));
label->setMinimumWidth(100);
hBox->addWidget(label);
2024-02-21 18:08:50 +08:00
auto fdDirection = new QComboBox;
fdDirection->addItem(tr("Right -> Left"), "left");
fdDirection->addItem(tr("Bottom -> Top"), "top");
fdDirection->addItem(tr("Left -> Right"), "right");
fdDirection->addItem(tr("Top -> Bottom"), "bottom");
SetCurData(fdDirection, direction);
connect(fdDirection, (void(QComboBox::*)(int))&QComboBox::currentIndexChanged, this, [=] {
direction = fdDirection->currentData().toString();
2023-04-18 14:14:46 +08:00
updImg();
});
2024-02-21 18:08:50 +08:00
hBox->addWidget(fdDirection);
2023-04-18 14:14:46 +08:00
hBox->addStretch();
2024-02-21 18:08:50 +08:00
hBox = new HBox(vBox);
2023-04-18 14:14:46 +08:00
label = new QLabel(tr("Scroll Speed"));
label->setMinimumWidth(100);
hBox->addWidget(label);
2024-02-21 18:08:50 +08:00
auto fd = new QComboBox;
fd->setEditable(true);
fd->setMinimumWidth(50);
fd->addItem("600");
fd->addItem("540");
fd->addItem("480");
fd->addItem("420");
fd->addItem("360");
fd->addItem("300");
fd->addItem("240");
fd->addItem("180");
fd->addItem("120");
fd->addItem("60");
fd->addItem("30");
fd->setMaxVisibleItems(fd->count());
auto text = QString::number(speed);
if(SetCurText(fd, text)==-1) {
SetCurText(fd, "60");
fd->setCurrentText(text);
}
connect(fd, &QComboBox::editTextChanged, this, [=](const QString &text) {
bool ok;
auto speed = text.toInt(&ok);
if(ok) this->speed = speed;
2023-04-18 14:14:46 +08:00
});
2024-02-21 18:08:50 +08:00
hBox->addWidget(fd);
hBox->addLabel("px/s");
2023-04-18 14:14:46 +08:00
hBox->addStretch();
vBox->addStretch();
}
auto stackBox = new QStackedLayout;
vBox->addLayout(stackBox);
stackBox->addWidget(wgtAttrFlip);
stackBox->addWidget(wgtAttrScroll);
2024-02-21 18:08:50 +08:00
stackBox->addWidget(new QWidget);
auto idx = std::find(playModes, playModes+3, playMode)-playModes;
if(idx>2) idx = 0;
stackBox->setCurrentIndex(idx);
connect(fdPlayStyle, &QButtonGroup::idToggled, this, [=](int value, bool checked) {
2023-04-18 14:14:46 +08:00
if(! checked) return;
2024-02-21 18:08:50 +08:00
playMode = playModes[value];
2023-04-18 14:14:46 +08:00
updImg();
stackBox->setCurrentIndex(value);
2024-02-21 18:08:50 +08:00
pageInfoWgt->setVisible(playMode=="Flip");
2023-04-18 14:14:46 +08:00
});
2024-02-21 18:08:50 +08:00
connect(this, &EText::updPageCnt, wgtAttr, [=] {
2023-04-18 14:14:46 +08:00
fdPageCnt->setText(QString::number(mImgs.size()));
fdPageIdx->setRange(1, mImgs.size());
fdPageIdx->setValue(1);
});
return wgtAttr;
}
bool EText::save(const QString &pageDir) {
QString idDir = pageDir + QString("/%1-%2-%3-%4-%5").arg(zValue()).arg((int)x()).arg((int)y()).arg((int)mWidth).arg((int)mHeight);
2023-04-28 16:02:14 +08:00
QDir().mkpath(idDir);
2023-04-18 14:14:46 +08:00
for(int i=0; i<mImgs.count(); i++) mImgs[i].save(idDir + QString("/text%1.png").arg(i));
return true;
}
2023-10-23 14:58:29 +08:00
JObj EText::attrJson() const {
JArray files;
2023-04-18 14:14:46 +08:00
for(int i=0; i<mImgs.count(); i++) files.append(QString("text%1.png").arg(i)); //上下滚动,生成一张纵向长图
2024-02-21 18:08:50 +08:00
JObj obj{
{"elementType", "Text"},
{"playMode", playMode},
{"text", text},
{"align", (int) align},
{"backColor", backColor.name(QColor::HexArgb)},
2023-04-18 14:14:46 +08:00
{"files", files},
{"idDir", QString("%1-%2-%3-%4-%5").arg(zValue()).arg((int)x()).arg((int)y()).arg((int)mWidth).arg((int)mHeight)}
};
2024-02-21 18:08:50 +08:00
addBaseAttr(obj);
if(playMode=="Scroll") {
obj["direction"] = direction;
obj["speed"] = speed;
obj["headTailSpacing"] = headTailSpacing;
}
2023-04-18 14:14:46 +08:00
return obj;
}
void EText::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){
painter->save();
auto rect = innerRect();
2024-02-21 18:08:50 +08:00
if(playMode!="Flip") curIdx = 0;
2023-04-18 14:14:46 +08:00
else if(curIdx>=mImgs.size()) curIdx = mImgs.size() - 1;
else if(curIdx < 0) curIdx = 0;
2024-02-21 18:08:50 +08:00
if(playMode=="Scroll") painter->drawImage(rect.x(), rect.y(), mImgs[0], 0, 0, rect.width(), rect.height());
2023-04-18 14:14:46 +08:00
else painter->drawImage(rect.x(), rect.y(), mImgs[curIdx]);
painter->restore();
EBase::paint(painter, option, widget);
}
void EText::updImg() {
auto innerRect = this->innerRect();
int width = innerRect.width();
int height = innerRect.height();
if(width<1 || height<1) return;
QTextDocument doc;
doc.setDocumentMargin(0);
QFont font;
font.setFamilies({"Arial","黑体"});
font.setPixelSize(16);
if(! gTextAntialiasing) font.setStyleStrategy(QFont::NoAntialias);
doc.setDefaultFont(font);
doc.setDefaultStyleSheet("body {color: #fff;}");
2024-02-21 18:08:50 +08:00
if(playMode=="Flip") {
doc.setHtml(text);
2023-04-18 14:14:46 +08:00
doc.setPageSize(innerRect.size());
auto pageHeight = height;
auto pageCnt = doc.pageCount();
QImage img(width, pageHeight*pageCnt, QImage::Format_ARGB32);
2024-02-21 18:08:50 +08:00
img.fill(backColor);
2023-04-18 14:14:46 +08:00
{
QPainter painter(&img);
doc.drawContents(&painter);
}
if(pageCnt > 1) {
check:
2024-02-21 18:08:50 +08:00
for(int y=pageHeight-1; y<img.height(); y+=pageHeight) for(int x=0; x<width; x++) if(img.pixelColor(x, y)!=backColor) {
2023-04-18 14:14:46 +08:00
pageHeight *= 2;
doc.setPageSize(QSizeF(width, pageHeight));
pageCnt = doc.pageCount();
img = QImage(width, pageHeight*pageCnt, QImage::Format_ARGB32);
2024-02-21 18:08:50 +08:00
img.fill(backColor);
2023-04-18 14:14:46 +08:00
{
QPainter painter(&img);
doc.drawContents(&painter);
}
if(pageHeight/height <= 16) goto check;
else goto forend;
}
if(pageCnt > 1) {
2024-02-21 18:08:50 +08:00
for(int y=img.height()-pageHeight; y<img.height(); y++) for(int x=0; x<width; x++) if(img.pixelColor(x, y)!=backColor) goto forend;
2023-04-18 14:14:46 +08:00
pageCnt--;
}
}
forend:
QRect rect(0, 0, width, pageHeight);
mImgs.clear();
for(int i=0; i<pageCnt; i++) {
auto pageImg = img.copy(rect);
alignV(pageImg, height);
mImgs.append(pageImg);
rect.translate(0, pageHeight);
}
emit updPageCnt();
2024-02-21 18:08:50 +08:00
} else if(playMode=="Scroll") {//生成一张大图
if(direction=="left" || direction=="right") {
doc.setHtml(text.replace("<p ", "<span ").replace("</p>", "</span>").replace("<br />", " "));
width = ceil(doc.idealWidth()) + headTailSpacing;
} else {
2023-04-18 14:14:46 +08:00
doc.setTextWidth(width);
2024-02-21 18:08:50 +08:00
doc.setHtml(text);
height = doc.size().height() + headTailSpacing;
2023-04-18 14:14:46 +08:00
}
QImage img(width, height, QImage::Format_ARGB32);
2024-02-21 18:08:50 +08:00
img.fill(backColor);
2023-04-18 14:14:46 +08:00
{
QPainter painter(&img);
doc.drawContents(&painter);
}
2024-02-21 18:08:50 +08:00
if(direction=="left" || direction=="right") {
alignV(img);
if(width < innerRect.width()) {
auto newWidth = width*2;
while(newWidth<innerRect.width()) newWidth += width;
QImage newImg(newWidth, height, QImage::Format_ARGB32);
newImg.fill(Qt::transparent);
{
QPainter painter(&newImg);
for(int x=0; x<newWidth; x+=width) painter.drawImage(x, 0, img);
}
img = newImg;
}
}
2023-04-18 14:14:46 +08:00
mImgs.clear();
mImgs.append(img);
// if(img.width()<=8192) mImgs.append(img);
// else {
// for(int i=0; i<img.width(); i+=8192) {
// QImage imgpart(8192, height, QImage::Format_ARGB32);
// imgpart.fill(m_attr.backColor);
// {
// QPainter painter(&imgpart);
// painter.drawImage(-i, 0, img);
// }
// mImgs.append(imgpart);
// }
// }
2024-02-21 18:08:50 +08:00
} else if(playMode=="Static") {//生成一张图
doc.setHtml(text);
2023-04-18 14:14:46 +08:00
doc.setTextWidth(width);
QImage img(width, height, QImage::Format_ARGB32);
2024-02-21 18:08:50 +08:00
img.fill(backColor);
2023-04-18 14:14:46 +08:00
{
QPainter painter(&img);
doc.drawContents(&painter);
}
alignV(img);
mImgs.clear();
mImgs.append(img);
}
update();
}
void EText::alignV(QImage &img, int cutHeight) {
int width = img.width(), height = img.height();
if(cutHeight==0) cutHeight = height;
2024-02-21 18:08:50 +08:00
if(align & Qt::AlignTop) {
2023-04-18 14:14:46 +08:00
int ss = 0;
2024-02-21 18:08:50 +08:00
for(; ss<height; ss++) for(int i=0; i<width; i++) if(img.pixelColor(i, ss)!=backColor) goto l12;
2023-04-18 14:14:46 +08:00
if(cutHeight==height) return;
ss = 0;
l12:
img = copy(img, 0, ss, width, cutHeight);
2024-02-21 18:08:50 +08:00
} else if(align & Qt::AlignVCenter) {
2023-04-18 14:14:46 +08:00
int ss = 0, ee = height - 1;
2024-02-21 18:08:50 +08:00
for(; ss<height; ss++) for(int i=0; i<width; i++) if(img.pixelColor(i, ss)!=backColor) goto l2;
2023-04-18 14:14:46 +08:00
if(cutHeight==height) return;
ss = 0;
goto l3;
l2:
2024-02-21 18:08:50 +08:00
for(; ee>ss; ee--) for(int i=0; i<width; i++) if(img.pixelColor(i, ee)!=backColor) goto l3;
2023-04-18 14:14:46 +08:00
l3:
img = copy(img, 0, (ss+ee-cutHeight+2)/2, width, cutHeight);
2024-02-21 18:08:50 +08:00
} else if(align & Qt::AlignBottom) {
2023-04-18 14:14:46 +08:00
int ee = height - 1;
2024-02-21 18:08:50 +08:00
for(; ee>=0; ee--) for(int i=0; i<width; i++) if(img.pixelColor(i, ee)!=backColor) goto l32;
2023-04-18 14:14:46 +08:00
if(cutHeight==height) return;
ee = height - 1;
l32:
img = copy(img, 0, ee+1-cutHeight, width, cutHeight);
} else if(cutHeight != height) img = copy(img, 0, 0, width, cutHeight);
}
QImage EText::copy(QImage &img, int x, int y, int w, int h) {
QImage imgpart(w, h, QImage::Format_ARGB32);
2024-02-21 18:08:50 +08:00
imgpart.fill(backColor);
2023-04-18 14:14:46 +08:00
{
QPainter painter(&imgpart);
painter.drawImage(-x, -y, img);
}
return imgpart;
}