427 lines
10 KiB
C++
427 lines
10 KiB
C++
#include <QtGui>
|
|
#include "pictextitem.h"
|
|
#include "picscene.h"
|
|
#include <cmath>
|
|
#include <QPainter>
|
|
//#include "moveinput.h"
|
|
#include <QStyleOptionGraphicsItem>
|
|
#include "ItemCommon.h"
|
|
|
|
//extern MoveInput* moveInput;
|
|
PicTextItem::PicTextItem(QGraphicsItem *parent, QGraphicsScene *scene, const SourceType t) :
|
|
QGraphicsTextItem(parent), //edit@02-07
|
|
m_sourceType(t)
|
|
{
|
|
setFlag(QGraphicsItem::ItemIsMovable);
|
|
setFlag(QGraphicsItem::ItemIsSelectable);
|
|
setFlag(QGraphicsItem::ItemIsFocusable);
|
|
setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
|
|
QFont f("Dinkie9");
|
|
// font.setFamily("wenquanyi");
|
|
// font.setPixelSize(5);
|
|
f.setLetterSpacing(QFont::AbsoluteSpacing, 1);
|
|
setFont(f);
|
|
|
|
document()->setDefaultStyleSheet("p { margin: 0; }");
|
|
document()->setDocumentMargin(0);
|
|
SpecialConditions = false;
|
|
CatchCnt1CurrValue = -1;
|
|
CatchCnt1StartValue = -1;
|
|
}
|
|
|
|
PicTextItem::~PicTextItem()
|
|
{
|
|
|
|
}
|
|
|
|
QVariant PicTextItem::source()
|
|
{
|
|
return m_source;
|
|
}
|
|
|
|
QImage PicTextItem::applyImgeTranslation(QImage img)
|
|
{
|
|
auto scaledWidth = boldMultiple() * img.width();
|
|
QImage ret = img.scaled(QSize(scaledWidth, img.height()));
|
|
switch(direction()) {
|
|
case NORMAL:
|
|
break;
|
|
case MIRROR_V:
|
|
ret = ret.mirrored(false, true);
|
|
break;
|
|
case MIRROR_H:
|
|
ret = ret.mirrored(true, false);
|
|
break;
|
|
case MIRROR_VH:
|
|
ret = ret.mirrored(true, true);
|
|
break;
|
|
case MIRROR_H_R270: {
|
|
QTransform trans;
|
|
trans.rotate(180, Qt::YAxis);
|
|
trans.rotate(270.0);
|
|
ret = ret.transformed(trans);
|
|
break;
|
|
}
|
|
case R90:
|
|
{
|
|
QTransform trans;
|
|
trans.rotate(90.0);
|
|
ret = ret.transformed(trans);
|
|
break;
|
|
}
|
|
case R270:
|
|
{
|
|
QTransform trans;
|
|
trans.rotate(270.0);
|
|
ret = ret.transformed(trans);
|
|
break;
|
|
}
|
|
case MIRROR_V_R270:
|
|
{
|
|
QTransform trans;
|
|
trans.rotate(180, Qt::XAxis);
|
|
trans.rotate(270.0);
|
|
ret = ret.transformed(trans);
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
|
|
// TODOD:: 添加颜色翻转功能
|
|
return ret;
|
|
}
|
|
|
|
void PicTextItem::setSource(QVariant var)
|
|
{
|
|
m_source = var;
|
|
|
|
if(SourceType::TEXT != sourceType())
|
|
return;
|
|
|
|
m_untransImage = strToImage(m_source.toString());
|
|
applyModify();
|
|
}
|
|
|
|
int PicTextItem::setBoldMultiple(int multiple)
|
|
{
|
|
m_boldMultiple = multiple;
|
|
}
|
|
|
|
void PicTextItem::setDirection(ItemDirectionType dir)
|
|
{
|
|
m_direction = dir;
|
|
}
|
|
|
|
void PicTextItem::setColorReversal(bool b)
|
|
{
|
|
m_colorReversal = b;
|
|
colorReversalChanged();
|
|
}
|
|
|
|
void PicTextItem::setCustomFont(QString name)
|
|
{
|
|
auto newFont = QFont(name);
|
|
newFont.setLetterSpacing(QFont::AbsoluteSpacing, letterSpace());
|
|
newFont.setStyleStrategy(QFont::NoAntialias);
|
|
setFont(newFont);
|
|
setSource(source());
|
|
}
|
|
|
|
int PicTextItem::letterSpace()
|
|
{
|
|
return int(font().letterSpacing());
|
|
}
|
|
|
|
void PicTextItem::setLetterSpace(int space)
|
|
{
|
|
auto f = font();
|
|
f.setLetterSpacing(QFont::AbsoluteSpacing, space);
|
|
setFont(f);
|
|
|
|
letterSpaceChanged();
|
|
}
|
|
|
|
void PicTextItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
|
|
{
|
|
if(sourceType() == SourceType::UNKNOWN) {
|
|
QGraphicsTextItem::paint(painter, option, widget);
|
|
return;
|
|
}
|
|
|
|
painter->save();
|
|
auto r = option->rect;
|
|
painter->setFont(font());
|
|
painter->drawImage(r, m_itemImage);
|
|
if(isSelected()) {
|
|
painter->setPen("red");
|
|
painter->drawRect(r);
|
|
}
|
|
painter->restore();
|
|
}
|
|
|
|
QRectF PicTextItem::boundingRect() const
|
|
{
|
|
if(sourceType() == SourceType::UNKNOWN)
|
|
return QGraphicsTextItem::boundingRect();
|
|
|
|
QRectF fr(0, 0, m_itemImage.width(), m_itemImage.height());
|
|
return fr;
|
|
}
|
|
|
|
QPainterPath PicTextItem::shape() const
|
|
{
|
|
QPainterPath path;
|
|
path.addRect(boundingRect());
|
|
return path;
|
|
}
|
|
|
|
void PicTextItem::setAttrs(const QXmlStreamAttributes &attrs)
|
|
{
|
|
auto dirRef = attrs.value("dir");
|
|
if(!dirRef.isEmpty()) {
|
|
bool ok = false;
|
|
auto d = dirRef.toInt(&ok);
|
|
if(ok)
|
|
setDirection((ItemDirectionType)d);
|
|
}
|
|
|
|
auto boldMultipleRef = attrs.value("boldMultiple");
|
|
if(!boldMultipleRef.isEmpty()) {
|
|
bool ok = false;
|
|
auto b = boldMultipleRef.toInt(&ok);
|
|
if(ok)
|
|
setBoldMultiple(b);
|
|
}
|
|
|
|
auto colorReversalRef = attrs.value("colorReversal");
|
|
if(!colorReversalRef.isEmpty()) {
|
|
auto s = colorReversalRef.toString().toLower();
|
|
if(s == "true" || s == "false") {
|
|
setColorReversal(s == "true");
|
|
}
|
|
}
|
|
|
|
auto letterSpaceRef = attrs.value("letterSpace");
|
|
if(!letterSpaceRef.isEmpty()) {
|
|
bool ok = false;
|
|
auto l = letterSpaceRef.toInt(&ok);
|
|
if(ok) {
|
|
QFont f = font();
|
|
f.setLetterSpacing(QFont::AbsoluteSpacing, l);
|
|
setFont(f);
|
|
}
|
|
}
|
|
|
|
auto fontFamilyRef = attrs.value("fontFamilay");
|
|
if(!fontFamilyRef.isEmpty()) {
|
|
setCustomFont(fontFamilyRef.toString());
|
|
}
|
|
|
|
qDebug() << "Text item properties: \r\n"
|
|
<< "\t direction: " << direction()
|
|
<< "\t boldMultiple: " << boldMultiple()
|
|
<< "\t colorReversal: " << colorReversal()
|
|
<< "\t letterSpace: " << letterSpace()
|
|
<< "\t fontFamily: " << font().family();
|
|
|
|
setCustomAttrs(attrs);
|
|
}
|
|
|
|
void PicTextItem::saveAttrs(QXmlStreamAttributes &attrs)
|
|
{
|
|
attrs.append("dir", QString::number(direction()));
|
|
attrs.append("boldMultiple", QString::number(boldMultiple()));
|
|
attrs.append("colorReversal", colorReversal() ? "true" : "false");
|
|
attrs.append("letterSpace", QString::number(int(font().letterSpacing())));
|
|
attrs.append("fontFamilay", font().family());
|
|
saveCustomAttrs(attrs);
|
|
}
|
|
|
|
void PicTextItem::applyModify()
|
|
{
|
|
auto img = itemImage();
|
|
|
|
if(img.isNull()) {
|
|
img = emptyImage();
|
|
}
|
|
|
|
prepareGeometryChange();
|
|
|
|
m_itemImage = applyImgeTranslation(img);
|
|
|
|
update();
|
|
|
|
if(scene())
|
|
scene()->update();
|
|
}
|
|
|
|
QImage PicTextItem::preview()
|
|
{
|
|
return m_itemImage;
|
|
}
|
|
void PicTextItem::setTextItemModel(const TextItemModel &model)
|
|
{
|
|
setLetterSpace(model.letterSpace);
|
|
setBoldMultiple(model.boldMultiple);
|
|
setDirection(model.direction);
|
|
setColorReversal(model.colorReversal);
|
|
}
|
|
|
|
TextItemModel PicTextItem::textItemModel()
|
|
{
|
|
return TextItemModel::fromItem(this);
|
|
}
|
|
|
|
//! [1]
|
|
QVariant PicTextItem::itemChange(GraphicsItemChange change,
|
|
const QVariant &value)
|
|
{
|
|
if (change == ItemSceneChange && scene()) {
|
|
QPointF newPos = value.toPoint();
|
|
QRectF rect = scene()->sceneRect();
|
|
if (!rect.contains(newPos)) {
|
|
newPos.setX(qMin(rect.right(), qMax(newPos.x(), rect.left())));
|
|
newPos.setY(qMin(rect.bottom(), qMax(newPos.y(), rect.top())));
|
|
}
|
|
}
|
|
return QGraphicsItem::itemChange(change, value);
|
|
}
|
|
//! [1]
|
|
|
|
//! [2]
|
|
void PicTextItem::focusOutEvent(QFocusEvent *event)
|
|
{
|
|
// moveInput->hide();
|
|
emit lostFocus(this);
|
|
QGraphicsTextItem::focusOutEvent(event);
|
|
//
|
|
}
|
|
//! [2]
|
|
|
|
//! [5]
|
|
void PicTextItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
|
|
{
|
|
//if (textInteractionFlags() == Qt::NoTextInteraction)
|
|
// setTextInteractionFlags(Qt::TextEditorInteraction);
|
|
//setTextInteractionFlags(Qt::TextBrowserInteraction);
|
|
QGraphicsTextItem::mouseDoubleClickEvent(event);
|
|
//emit itemEdit(toHtml());
|
|
}
|
|
//! [5]
|
|
|
|
//限制图元拖动范围
|
|
void PicTextItem::mouseReleaseEvent ( QGraphicsSceneMouseEvent * event )
|
|
{
|
|
auto newPos = clampItemPos(pos());
|
|
this->setPos(qCeil(newPos.x()),qCeil(newPos.y()));
|
|
|
|
scene()->update();
|
|
QGraphicsTextItem::mouseReleaseEvent(event);
|
|
}
|
|
|
|
void PicTextItem::keyPressEvent(QKeyEvent *event)
|
|
{
|
|
foreach (QGraphicsItem *item, scene()->selectedItems()) {
|
|
QPointF newPos = item->pos();
|
|
switch(event->key()) {
|
|
case Qt::Key_Left:
|
|
newPos += QPointF(-1.0, 0.0);
|
|
break;
|
|
case Qt::Key_Right:
|
|
newPos += QPointF(1.0, 0.0);
|
|
break;
|
|
case Qt::Key_Up:
|
|
newPos += QPointF(0.0, -1.0);
|
|
break;
|
|
case Qt::Key_Down:
|
|
newPos += QPointF(0.0, 1.0);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
newPos = clampItemPos(newPos);
|
|
setPos(qCeil(newPos.x()),qCeil(newPos.y()));
|
|
|
|
}
|
|
if(!scene()->selectedItems().empty())
|
|
{
|
|
scene()->update();
|
|
}
|
|
QGraphicsTextItem::keyPressEvent(event);
|
|
}
|
|
|
|
QImage PicTextItem::emptyImage()
|
|
{
|
|
QImage img(10, 10, QImage::Format_ARGB32);
|
|
img.fill(Qt::white);
|
|
return img;
|
|
}
|
|
|
|
QImage PicTextItem::itemImage()
|
|
{
|
|
return m_untransImage;
|
|
}
|
|
|
|
void PicTextItem::setCustomAttrs(const QXmlStreamAttributes &attrs)
|
|
{
|
|
auto sourceVar = attrs.value("source").toString();
|
|
PicTextItem::setSource(sourceVar);
|
|
}
|
|
|
|
void PicTextItem::saveCustomAttrs(QXmlStreamAttributes &attrs)
|
|
{
|
|
attrs.append("source", PicTextItem::source().toString());
|
|
}
|
|
|
|
void PicTextItem::colorReversalChanged()
|
|
{
|
|
setSource(source());
|
|
}
|
|
|
|
void PicTextItem::letterSpaceChanged()
|
|
{
|
|
setSource(source());
|
|
}
|
|
|
|
QImage PicTextItem::strToImage(const QString &str)
|
|
{
|
|
if(str.isEmpty())
|
|
return QImage();
|
|
|
|
QColor txtColor = colorReversal() ? QColor(255, 255, 255) : QColor(0, 0, 0);
|
|
QColor bgColor = colorReversal() ? QColor(0, 0, 0) : QColor(0, 0, 0, 0);
|
|
|
|
return ItemUtils::txtToImage(str, font(), txtColor, bgColor);
|
|
}
|
|
|
|
/**
|
|
* @brief 限制item的位置,以保证整个item都在scene以内
|
|
* @param p 要设置的item的新位置
|
|
* @return 被clamp之后的新位置
|
|
*/
|
|
QPointF PicTextItem::clampItemPos(const QPointF &p)
|
|
{
|
|
return QPointF (std::min(qreal(scene()->width() - boundingRect().width()), std::max(0.0, p.x())),
|
|
std::min((qreal(scene()->height()) - boundingRect().height()), std::max(0.0, p.y())));
|
|
}
|
|
|
|
TextItemModel TextItemModel::fromItem(PicTextItem *item)
|
|
{
|
|
TextItemModel vm;
|
|
if (item) {
|
|
vm.sourceType = item->sourceType();
|
|
vm.direction = item->direction();
|
|
vm.boldMultiple = item->boldMultiple();
|
|
vm.letterSpace = item->letterSpace();
|
|
vm.colorReversal = item->colorReversal();
|
|
}
|
|
return vm;
|
|
}
|
|
|
|
QString TextItemModel::toString(const TextItemModel &model)
|
|
{
|
|
return QString("type: %1, letterSpace: %2, dir: %3, bold: %4, coloReversal: %5")
|
|
.arg(model.sourceType).arg(model.letterSpace).arg(model.direction).arg(model.boldMultiple).arg(model.colorReversal);
|
|
} |