first commit
This commit is contained in:
@@ -0,0 +1,443 @@
|
||||
#include <QtGui>
|
||||
#include "pictextitem.h"
|
||||
#include "picscene.h"
|
||||
#include <cmath>
|
||||
#include <QPainter>
|
||||
//#include "moveinput.h"
|
||||
#include <QStyleOptionGraphicsItem>
|
||||
|
||||
//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 clipImage(QImage img, const QRgb bg)
|
||||
{
|
||||
QRect clipRect;
|
||||
for(int x = 0; x < img.width(); ++x) {
|
||||
for(int y = 0; y < img.height(); ++y) {
|
||||
auto rgb = img.pixel(x, y);
|
||||
if(rgb != bg) {
|
||||
clipRect.setLeft(x);
|
||||
goto top;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
top:
|
||||
for(int y = 0; y < img.height(); ++y) {
|
||||
for(int x = 0; x < img.width(); ++x) {
|
||||
if(img.pixel(x, y) != bg) {
|
||||
clipRect.setTop(y);
|
||||
goto right;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
right:
|
||||
for(int x = img.width() - 1; x >= 0; --x) {
|
||||
for(int y = 0; y < img.height(); ++y) {
|
||||
if(img.pixel(x, y) != bg) {
|
||||
clipRect.setRight(x + 1);
|
||||
goto bottom;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bottom:
|
||||
for(int y = img.height() - 1; y >= 0; --y) {
|
||||
for(int x = 0; x < img.width(); ++x) {
|
||||
if(img.pixel(x, y) != bg) {
|
||||
clipRect.setBottom(y + 1);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
QRect originRect = img.rect();
|
||||
return img.copy(clipRect);
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
const 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());
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
//! [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)
|
||||
{
|
||||
QPainter painter;
|
||||
QFontMetrics fm(font());
|
||||
QImage img(fm.horizontalAdvance(str), fm.height(), QImage::Format_ARGB32);
|
||||
|
||||
QRgb txtColor = colorReversal() ? 0xffffffff : 0xff000000;
|
||||
QRgb bgColor = colorReversal() ? 0xff000000 : 0x00000000;
|
||||
|
||||
img.fill(bgColor);
|
||||
painter.begin(&img);
|
||||
painter.setFont(font());
|
||||
painter.setPen(txtColor);
|
||||
painter.drawText(img.rect(), str);
|
||||
painter.end();
|
||||
|
||||
return clipImage(img, 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())));
|
||||
}
|
||||
Reference in New Issue
Block a user