qt/LedOK/wProgramManager/wEditProgram/wElement/backup/etext.cpp

279 lines
11 KiB
C++
Raw Normal View History

2022-01-04 18:11:48 +08:00
#include "etext.h"
#include "etextattr.h"
#include "etextinput.h"
eText::eText(InteractiveType type, QGraphicsItem *parent) :
eObject(QRectF(0, 0, 120, 100), type, parent),
m_wAttr(nullptr),
m_wTextInput(nullptr)
{
// Widget
m_attr.text = tr("Hello Text !");
m_attr.opt.setAlignment(Qt::AlignCenter);
m_attr.opt.setWrapMode(QTextOption::WrapAnywhere);
m_attr.cText = Qt::red;
m_attr.cTextShadow = QColor(0,0,0,0);
m_attr.cBackground = QColor(0,0,0,0);
m_attr.lineSpacing = 0;
//Play
m_attr.playStyle = Static;
m_attr.headTailConnected = false;
m_attr.headTailSpacing = 0;
m_attr.rollingSpeed = 0;
m_attr.rollingStyle = Left2Right;
m_attr.playDuration = 0;
}
eText::eText(const QJsonObject &json, InteractiveType type, QGraphicsItem *parent) :
eObject(json["geometry"].toObject(), type, parent),
m_wAttr(nullptr),
m_wTextInput(nullptr)
{
QJsonDocument jRoot;
jRoot.setObject(json);
// Widget
m_attr.text = jRoot["widget"]["text"] .toString();
m_attr.font.setFamily( jRoot["widget"]["font"]["family"] .toString());
m_attr.font.setPointSize( jRoot["widget"]["font"]["size"] .toInt());
m_attr.font.setBold( jRoot["widget"]["font"]["bold"] .toBool());
m_attr.font.setItalic( jRoot["widget"]["font"]["italic"] .toBool());
m_attr.font.setUnderline( jRoot["widget"]["font"]["underline"] .toBool());
m_attr.font.setLetterSpacing(QFont::AbsoluteSpacing, jRoot["widget"]["font"]["letterSpacing"].toInt());
m_attr.opt.setAlignment(static_cast<Qt::Alignment>( jRoot["widget"]["align"] .toInt()));
m_attr.cText = LoAppTools::getInstance()->int2Color(jRoot["widget"]["color"]["text"] .toInt());
m_attr.cTextShadow = LoAppTools::getInstance()->int2Color(jRoot["widget"]["color"]["shadow"] .toInt());
m_attr.cBackground = LoAppTools::getInstance()->int2Color(jRoot["widget"]["color"]["background"] .toInt());
m_attr.lineSpacing = jRoot["widget"]["lineSpacing"] .toInt();
// Play
m_attr.playStyle = jRoot["play"]["style"] .toInt();
m_attr.headTailConnected = jRoot["play"]["headTailConnected"].toBool();
m_attr.headTailSpacing = jRoot["play"]["headTailSpacing"] .toInt();
m_attr.rollingSpeed = jRoot["play"]["rollingSpeed"] .toInt();
m_attr.rollingStyle = jRoot["play"]["rollingStyle"] .toInt();
m_attr.playDuration = jRoot["play"]["duration"] .toInt();
}
QWidget* eText::wAttr()
{
QWidget *wObj = eObject::wAttr();
QWidget *w = wAttrElement();
static_cast<QBoxLayout*>(w->layout())->insertWidget(0, wObj);
return w;
}
QWidget* eText::wAttrElement()
{
eTextAttr *w = new eTextAttr(m_attr);
connect(w, SIGNAL(destroyed(QObject*)), this, SLOT(onWAttrClosed()));
// Widget
connect(w, SIGNAL(sFontFamilyChanged(const QString&)), this, SLOT(onFontFamilyChanged(const QString&)));
connect(w, SIGNAL(sFontSizeChanged(int)), this, SLOT(onFontSizeChanged(int)));
connect(w, SIGNAL(sFontBoldChanged(bool)), this, SLOT(onFontBoldChanged(bool)));
connect(w, SIGNAL(sFontItalicsChanged(bool)), this, SLOT(onFontItalicsChanged(bool)));
connect(w, SIGNAL(sFontUnderlineChanged(bool)), this, SLOT(onFontUnderlineChanged(bool)));
connect(w, SIGNAL(sTextHAlignChanged(int)), this, SLOT(onTextHAlignChanged(int)));
connect(w, SIGNAL(sTextVAlignChanged(int)), this, SLOT(onTextVAlignChanged(int)));
connect(w, SIGNAL(sTextColorChanged(const QColor&)), this, SLOT(onTextColorChanged(const QColor&)));
connect(w, SIGNAL(sTextShadowColorChanged(const QColor&)), this, SLOT(onTextShadowColorChanged(const QColor&)));
connect(w, SIGNAL(sBackgroundColorChanged(const QColor&)), this, SLOT(onBackgroundColorChanged(const QColor&)));
connect(w, SIGNAL(sTextLetterSpacingChanged(int)), this, SLOT(onTextLetterSpacingChanged(int)));
connect(w, SIGNAL(sTextLineSpacingChanged(int)), this, SLOT(onTextLineSpacingChanged(int)));
// Play
connect(w, SIGNAL(sPlayStyleChanged(int)), this, SLOT(onPlayStyleChanged(int)));
connect(w, SIGNAL(sHeadTailConnected(bool)), this, SLOT(onHeadTailConnected(bool)));
connect(w, SIGNAL(sHeadTailSpacingChanged(int)), this, SLOT(onHeadTailSpacingChanged(int)));
connect(w, SIGNAL(sRollingSpeedChanged(int)), this, SLOT(onRollingSpeedChanged(int)));
connect(w, SIGNAL(sRollingStyleChanged(int)), this, SLOT(onRollingStyleChanged(int)));
connect(w, SIGNAL(sPlayDurationChanged(int)), this, SLOT(onPlayDurationChanged(int)));
m_wAttr = w;
return w;
}
QJsonObject eText::elementJson() const
{
QJsonObject oRoot;
QJsonObject oWidget;
QJsonObject oColor;
QJsonObject oFont;
QJsonObject oPlay;
// Interior
oRoot["elementType"] = "Text";
oRoot["elementTypeId"] = type();
oRoot["geometry"] = eObject::elementJson();
// Widget
oWidget["text"] = m_attr.text;
oFont["family"] = m_attr.font.family();
oFont["size"] = m_attr.font.pointSize();
oFont["bold"] = m_attr.font.bold();
oFont["italic"] = m_attr.font.italic();
oFont["underline"] = m_attr.font.underline();
oFont["letterSpacing"] = m_attr.font.letterSpacing();
oWidget["font"] = oFont;
oWidget["align"] = static_cast<int>(m_attr.opt.alignment());
oColor["text"] = LoAppTools::getInstance()->color2Int(m_attr.cText);
oColor["shadow"] = LoAppTools::getInstance()->color2Int(m_attr.cTextShadow);
oColor["background"] = LoAppTools::getInstance()->color2Int(m_attr.cBackground);
oWidget["color"] = oColor;
oWidget["lineSpacing"] = m_attr.lineSpacing;
oRoot["widget"] = oWidget;
// Play
oPlay["style"] = m_attr.playStyle;
oPlay["headTailConnected"] = m_attr.headTailConnected;
oPlay["headTailSpacing"] = m_attr.headTailSpacing;
oPlay["rollingSpeed"] = m_attr.rollingSpeed;
oPlay["rollingStyle"] = m_attr.rollingStyle;
oPlay["duration"] = m_attr.playDuration;
oRoot["play"] = oPlay;
return oRoot;
}
void eText::setTextContents(QTextDocument &doc)
{
const int lineSpacing = QFontMetrics(m_attr.font).lineSpacing();
m_lineH = m_attr.lineSpacing + lineSpacing;
QString ctx = QString("<style>p{"
"color:rgba(%1,%2,%3,%4);"
"line-height:%5px;"
"white-space:pre-wrap;"
"}</style>"
"<p>%6</p>")
.arg(m_attr.cText.red()).arg(m_attr.cText.green())
.arg(m_attr.cText.blue()).arg(m_attr.cText.alpha())
.arg(m_lineH)
.arg(m_attr.text);
doc.setHtml(ctx);
}
void eText::setTextVAlign(int align, QTextDocument &doc)
{
qreal ls, ofs_h, ofs_v;
qreal painter_x, painter_y;
qreal clip_x, clip_y, clip_w, clip_h;
QRectF r = rect();
QSizeF s = doc.size();
align &= Qt::AlignVertical_Mask;
if(s.height() > r.height()) {
int num = static_cast<int>(r.height()) / m_lineH;
ofs_h = r.height() - m_lineH * num;
clip_x = r.x();
clip_y = r.y();
clip_w = r.width();
clip_h = num ? m_lineH * num : 0.000001;
r = QRectF(clip_x, clip_y, clip_w, clip_h);
ls = rect().height() - clip_h + QFontMetrics(m_attr.font).leading();
} else {
ls = QFontMetrics(m_attr.font).leading() + m_attr.lineSpacing;
}
clip_x = 0;
clip_y = 0;
clip_w = r.width();
clip_h = (s.height() < r.height()) ? s.height() : r.height();
painter_x = r.x();
switch (align) {
case Qt::AlignTop:
ofs_v = 0;
painter_y = 0;
break;
case Qt::AlignVCenter:
ofs_v = (r.height() - s.height()) / 2;
painter_y = (s.height() < r.height()) ? r.y() + ofs_v : 0;
painter_y += ls / 2;
break;
case Qt::AlignBottom:
ofs_v = r.height() - s.height();
painter_y = (s.height() < r.height()) ? r.y() + ofs_v : 0;
painter_y += ls;
break;
default:
return;
}
m_pText = QPointF(painter_x, painter_y);
m_rClip = QRectF(clip_x, clip_y, clip_w, clip_h);
}
void eText::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
painter->save();
QBrush bshBackground = LoAppTools::getInstance()->getBrush(m_attr.cBackground);
if(bshBackground != Qt::NoBrush) {
#if 1
painter->fillRect(rect(), bshBackground);
#else
QRectF r = rect();
qreal x, y, w, h;
x = r.x() - 1;
y = r.y() - 1;
w = r.width() + 2;
h = r.height() + 2;
r = QRectF(x, y, w, h);
painter->fillRect(r, bshBackground);
#endif
}
QBrush bshTextShadow = LoAppTools::getInstance()->getBrush(m_attr.cTextShadow);
if(bshTextShadow != Qt::NoBrush) {
painter->setBackgroundMode(Qt::OpaqueMode);
painter->setBackground(bshTextShadow);
}
#if 0
painter->setPen(m_attr.pen);
painter->setFont(m_attr.font);
painter->drawText(rect(), m_attr.text, m_attr.opt);
#else
QTextDocument doc;
doc.setDefaultFont(m_attr.font);
doc.setDefaultTextOption(m_attr.opt);
doc.setDocumentMargin(0);
doc.setTextWidth(rect().width());
setTextContents(doc);
setTextVAlign(m_attr.opt.alignment(), doc);
painter->translate(m_pText);
doc.drawContents(painter, m_rClip);
// qDebug() << "Block Count:" << doc.blockCount();
#endif
painter->restore();
LoQGraphicsObject::paint(painter, option, widget);
}
void eText::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
{
if(Qt::LeftButton == event->button()) {
setInput();
}
}
void eText::setInput()
{
if(nullptr == m_wTextInput && nullptr != m_wAttr) {
m_wTextInput = new eTextInput(m_attr.text, m_wAttr);
connect(m_wTextInput, SIGNAL(sTextChanged(const QString &)), this, SLOT(onTextChanged(const QString &)));
connect(m_wTextInput, SIGNAL(destroyed(QObject*)), this, SLOT(onInputClosed()));
m_wTextInput->show();
}
}
void eText::onTextHAlignChanged(int align)
{
int res = m_attr.opt.alignment();
res &= ~Qt::AlignHorizontal_Mask;
res |= align;
m_attr.opt.setAlignment(static_cast<Qt::Alignment>(res));
updateGeometry();
}
void eText::onTextVAlignChanged(int align)
{
int res = m_attr.opt.alignment();
res &= ~Qt::AlignVertical_Mask;
res |= align;
m_attr.opt.setAlignment(static_cast<Qt::Alignment>(res));
updateGeometry();
}