Beispiel #1
0
void TextContent::setShapeEditing(bool enabled)
{
    if (enabled) {
        // shape editor on
        if (!m_shapeEditor->isVisible()) {
            m_shapeEditor->show();
            emit notifyShapeEditing(true);
        }

        // begin new shape
        if (!hasShape()) {
            // use caching only when drawing shaped [disabled because updates are wrong when cached!]
            //setCacheMode(enabled ? QGraphicsItem::DeviceCoordinateCache : QGraphicsItem::NoCache);

            // use new shape
            setShapePath(m_shapeEditor->shape());
            emit notifyHasShape(true);
        }
    } else {
        // shape editor off
        if (m_shapeEditor->isVisible()) {
            m_shapeEditor->hide();
            emit notifyShapeEditing(false);
        }
    }
}
Beispiel #2
0
void SelectedItem::updateGeometry(int, int)
{
	if (hasShape())
	{
		getShape()->setInnerSize(selectedItem_->width(), selectedItem_->height());
		QPointF pos = QPointF( getShape()->contentLeft(), getShape()->contentTop() );

		setPos(selectedItem_->mapToScene(0,0) - pos);
	}
}
Beispiel #3
0
void TextContent::toXml(QDomElement & contentElement, const QDir & baseDir) const
{
    AbstractContent::toXml(contentElement, baseDir);
    contentElement.setTagName("text");

    // save text properties
    QDomDocument doc = contentElement.ownerDocument();
    QDomElement domElement;
    QDomText text;

    // save text (in html)
    domElement = doc.createElement("html-text");
    contentElement.appendChild(domElement);
    text = doc.createTextNode(m_text->toHtml());
    domElement.appendChild(text);

    // save default font
    domElement = doc.createElement("default-font");
    domElement.setAttribute("font-family", m_text->defaultFont().family());
    domElement.setAttribute("font-size", m_text->defaultFont().pointSize());
    contentElement.appendChild(domElement);

    // save shape and control points
    QDomElement shapeElement = doc.createElement("shape");
    shapeElement.setAttribute("enabled", hasShape());
    contentElement.appendChild(shapeElement);
    if (hasShape()) {
        QList<QPointF> cp = m_shapeEditor->controlPoints();
        domElement = doc.createElement("control-points");
        shapeElement.appendChild(domElement);
        domElement.setAttribute("one", QString::number(cp[0].x())
                + " " + QString::number(cp[0].y()));
        domElement.setAttribute("two", QString::number(cp[1].x())
                + " " + QString::number(cp[1].y()));
        domElement.setAttribute("three", QString::number(cp[2].x())
                + " " + QString::number(cp[2].y()));
        domElement.setAttribute("four", QString::number(cp[3].x())
                + " " + QString::number(cp[3].y()));
    }
}
Beispiel #4
0
void CursorShapeItem::updateGeometry(int, int)
{
    if (hasShape())
    {
        getShape()->setInnerSize(size_.width(), size_.height());


        if (useCenter_)
        {
            QPointF pos = QPointF( getShape()->contentLeft(), getShape()->contentTop() );
            setPos(center_ - pos);
        }
        else setPos(topLeft_);
    }
}
vec2 SpriteDef::calculateSizeFromShapeData () const
{
	if (_shapeSizeCalculated)
		return _cachedShapeSize;

	if (!hasShape()) {
		_cachedShapeSize = vec2_zero;
		_shapeSizeCalculated = true;
		return _cachedShapeSize;
	}

	const vec2 mins = getMins();
	const vec2 maxs = getMaxs();
	_cachedShapeSize = vec2(maxs.x - mins.x, maxs.y - mins.y);
	_shapeSizeCalculated = true;
	return _cachedShapeSize;
}
Beispiel #6
0
QWidget * TextContent::createPropertyWidget(ContentProperties * __p)
{
    TextProperties * tp = __p ? (TextProperties *)__p : new TextProperties;
    AbstractContent::createPropertyWidget(tp);

    // remove for 0.9 ### put this back for 1.0
    delete tp->tShakeLess;
    delete tp->tShakeMore;

    // properties link
    new PE_AbstractButton(tp->tEditShape, this, "shapeEditing", tp);
    tp->tClearShape->setVisible(hasShape()); // link "hasShape" in a custom way
    connect(this, SIGNAL(notifyHasShape(bool)), tp->tClearShape, SLOT(setVisible(bool)));
    connect(tp->tClearShape, SIGNAL(clicked()), this, SLOT(clearShape()));

    return tp;
}
Beispiel #7
0
void Layout::setInnerSize(int width_, int height_)
{
	if (isEmpty() && !style()->drawShapeWhenEmpty()) setSize(0,0);
	else
	{
		if ( hasShape() )
		{
			getShape()->setOffset(style()->leftMargin(), style()->topMargin());
			getShape()->setInnerSize(width_, height_);
			setWidth(width() + style()->rightMargin());
			setHeight(height() + style()->bottomMargin());
		}
		else
		{
			setWidth(width_ + style()->leftMargin() + style()->rightMargin());
			setHeight(height_ + style()->topMargin() + style()->bottomMargin());
		}
	}
}
Beispiel #8
0
void ControlFlowItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
	Item::paint(painter, option, widget);

	int xOffset = 0;
	int yOffset = 0;
	if (hasShape())
	{
		xOffset = getShape()->contentLeft();
		yOffset = getShape()->contentTop();
	}

	painter->setPen( style()->pin());
	painter->translate( xOffset + style()->pin().width()/2.0, yOffset + style()->pin().width()/2.0);

	for(int i = 0; i < connectors_.size(); ++i)
	{
		painter->drawPath( connector(connectors_.at(i), arrowEndings_.at(i)) );
	}
}
Beispiel #9
0
int Layout::yOffset() const
{
	if ( hasShape() ) return getShape()->contentTop();
	else return style()->topMargin();
}
Beispiel #10
0
int Layout::xOffset() const
{
	if ( hasShape() ) return getShape()->contentLeft();
	else return style()->leftMargin();
}
Beispiel #11
0
void TextContent::updateTextConstraints()
{
    // 1. actual content stretch
    double prevXScale = 1.0;
    double prevYScale = 1.0;
   /* if (m_textRect.width() > 0 && m_textRect.height() > 0) {
        QRect cRect = contentRect();
        prevXScale = (qreal)cRect.width() / (qreal)m_textRect.width();
        prevYScale = (qreal)cRect.height() / (qreal)m_textRect.height();
    }*/

    // 2. LAYOUT TEXT. find out Block rects and Document rect
    int minCharSide = 0;
    m_blockRects.clear();
    m_textRect = QRect(0, 0, 0, 0);
    for (QTextBlock tb = m_text->begin(); tb.isValid(); tb = tb.next()) {
        if (!tb.isVisible())
            continue;

        // 2.1.A. calc the Block size uniting Fragments bounding rects
        QRect blockRect(0, 0, 0, 0);
        for (QTextBlock::iterator tbIt = tb.begin(); !(tbIt.atEnd()); ++tbIt) {
            QTextFragment frag = tbIt.fragment();
            if (!frag.isValid())
                continue;

            QString text = frag.text();
            if (text.trimmed().isEmpty())
                continue;

            QFontMetrics metrics(frag.charFormat().font());
            if (!minCharSide || metrics.height() > minCharSide)
                minCharSide = metrics.height();

            // TODO: implement superscript / subscript (it's in charFormat's alignment)
            // it must be implemented in paint too

            QRect textRect = metrics.boundingRect(text);
            if (textRect.left() > 9999)
                continue;
            if (textRect.top() < blockRect.top())
                blockRect.setTop(textRect.top());
            if (textRect.bottom() > blockRect.bottom())
                blockRect.setBottom(textRect.bottom());

            int textWidth = metrics.width(text);
            blockRect.setWidth(blockRect.width() + textWidth);
        }
        // 2.1.B. calc the Block size of blank lines
        if (tb.begin() == tb.end()) {
            QFontMetrics metrics(tb.charFormat().font());
            int textHeight = metrics.height();
            blockRect.setWidth(1);
            blockRect.setHeight(textHeight);
        }

        // 2.2. add the Block's margins
        QTextBlockFormat tbFormat = tb.blockFormat();
        blockRect.adjust(-tbFormat.leftMargin(), -tbFormat.topMargin(), tbFormat.rightMargin(), tbFormat.bottomMargin());

        // 2.3. store the original block rect
        m_blockRects.append(blockRect);

        // 2.4. enlarge the Document rect (uniting the Block rect)
        blockRect.translate(0, m_textRect.bottom() - blockRect.top() + 1);
        if (blockRect.left() < m_textRect.left())
            m_textRect.setLeft(blockRect.left());
        if (blockRect.right() > m_textRect.right())
            m_textRect.setRight(blockRect.right());
        if (blockRect.top() < m_textRect.top())
            m_textRect.setTop(blockRect.top());
        if (blockRect.bottom() > m_textRect.bottom())
            m_textRect.setBottom(blockRect.bottom());
    }
    m_textRect.adjust(-m_textMargin, -m_textMargin, m_textMargin, m_textMargin);

    // 3. use shape-based rendering
    if (hasShape()) {
#if 1
        // more precise, but too close to the path
        m_shapeRect = m_shapePath.boundingRect().toRect();
#else
        // faster, but less precise (as it uses the controls points to determine
        // the path rect, instead of the path itself)
        m_shapeRect = m_shapePath.controlPointRect().toRect();
#endif
        minCharSide = qBound(10, minCharSide, 500);
        m_shapeRect.adjust(-minCharSide, -minCharSide, minCharSide, minCharSide);

        // FIXME: layout, save layouting and calc the exact size!
        //int w = m_shapeRect.width();
        //int h = m_shapeRect.height();
        //resizeContents(QRect(-w / 2, -h / 2, w, h));
        resizeContents(m_shapeRect);

  //      moveBy(m_shapeRect.left(), m_shapeRect.top());
//        m_shapePath.translate(-m_shapeRect.left(), -m_shapeRect.top());
        //setPos(m_shapeRect.center());
        return;
    }

    // 4. resize content keeping stretch
    int w = (int)(prevXScale * (qreal)m_textRect.width());
    int h = (int)(prevYScale * (qreal)m_textRect.height());
    resizeContents(QRect(-w / 2, -h / 2, w, h));
}
Beispiel #12
0
void TextContent::drawContent(QPainter * painter, const QRect & targetRect, Qt::AspectRatioMode ratio)
{
    Q_UNUSED(ratio)

    // check whether we're drawing shaped
    const bool shapedPaint = hasShape() && !m_shapeRect.isEmpty();
    QPointF shapeOffset = m_shapeRect.topLeft();

    // scale painter for adapting the Text Rect to the Contents Rect
    QRect sourceRect = shapedPaint ? m_shapeRect : m_textRect;
    painter->save();
    painter->translate(targetRect.topLeft());
    if (sourceRect.width() > 0 && sourceRect.height() > 0) {
        qreal xScale = (qreal)targetRect.width() / (qreal)sourceRect.width();
        qreal yScale = (qreal)targetRect.height() / (qreal)sourceRect.height();
        if (!qFuzzyCompare(xScale, (qreal)1.0) || !qFuzzyCompare(yScale, (qreal)1.0))
            painter->scale(xScale, yScale);
    }

    // shape
    //const bool drawHovering = RenderOpts::HQRendering ? false : isSelected();
    if (shapedPaint)
        painter->translate(-shapeOffset);
    //if (shapedPaint && drawHovering)
    //    painter->strokePath(m_shapePath, QPen(Qt::red, 0));

    // TEMP - for PDF exporting - standard rich text document drawing
    if (RenderOpts::PDFExporting) {
        if (shapedPaint)
            QMessageBox::information(0, tr("PDF Export Warning"), tr("Shaped text could not be exported in PDF"), QMessageBox::Ok);
        QAbstractTextDocumentLayout::PaintContext pCtx;
        m_text->documentLayout()->draw(painter, pCtx);
    } else {
        // manual drawing
        QPointF blockPos = shapedPaint ? QPointF(0, 0) : -m_textRect.topLeft();

        // 1. for each Text Block
        int blockRectIdx = 0;
        for (QTextBlock tb = m_text->begin(); tb.isValid(); tb = tb.next()) {
            if (!tb.isVisible() || blockRectIdx > m_blockRects.size())
                continue;

            // 1.1. compute text insertion position
            const QRect & blockRect = m_blockRects[blockRectIdx++];
            QPointF iPos = shapedPaint ? blockPos : blockPos - blockRect.topLeft();
            blockPos += QPointF(0, blockRect.height());

            qreal curLen = 8;

            // 1.2. iterate over text fragments
            for (QTextBlock::iterator tbIt = tb.begin(); !(tbIt.atEnd()); ++tbIt) {
                QTextFragment frag = tbIt.fragment();
                if (!frag.isValid())
                    continue;

                // 1.2.1. setup painter and metrics for text fragment
                QTextCharFormat format = frag.charFormat();
                QFont font = format.font();
                painter->setFont(font);
                painter->setPen(format.foreground().color());
                painter->setBrush(Qt::NoBrush);
                QFontMetrics metrics(font);

                // 1.2.2. draw each character
                QString text = frag.text();
                foreach (const QChar & textChar, text) {
                    const qreal charWidth = metrics.width(textChar);
                    if (shapedPaint) {
                        // find point on shape and angle
                        qreal t = m_shapePath.percentAtLength(curLen);
                        QPointF pt = m_shapePath.pointAtPercent(t);
                        qreal angle = -m_shapePath.angleAtPercent(t);
                        if (m_shakeRadius > 0)
                            pt += QPointF(1 + (qrand() % m_shakeRadius) - m_shakeRadius/2, 1 + (qrand() % (2*m_shakeRadius)) - m_shakeRadius);

                        // draw rotated letter
                        painter->save();
                        painter->translate(pt);
                        painter->rotate(angle);
                        painter->drawText(iPos, textChar);
                        painter->restore();

                        curLen += charWidth;
                    } else {
                        painter->drawText(iPos, textChar);
                        iPos += QPointF(charWidth, 0);
                    }
                }
            }
        }
    }

    painter->restore();
}
Beispiel #13
0
void PanelBorderLayout::updateGeometry(int, int)
{
	//TODO: Find a generic way of doing this and consider performance
	//Set Styles
	if (top_) top_->setStyle(&style()->topStyle());
	if (left_) left_->setStyle(&style()->leftStyle());
	if (right_) right_->setStyle(&style()->rightStyle());
	if (bottom_) bottom_->setStyle(&style()->bottomStyle());

	// Get content size
	int contentWidth = content_ ? content_->width() : 0;
	int contentHeight = content_ ? content_->height() : 0;

	// Compute middle sizes
	int middleWidth = contentWidth + style()->leftInnerMargin() + style()->rightInnerMargin();
	if ( left_ && !style()->isLeftProtrusionFixed()) middleWidth += left_->width() / 2;
	if ( right_ ) middleWidth += right_->width() / 2;

	if (style()->isLeftProtrusionFixed())
	{
		int extra = (left_ ? left_->width() : 0) - style()->leftProtrusion();
		if (extra > 0) middleWidth += extra;
	}

	int maxMiddleWidth = middleWidth;
	if ( top_ && top_->width() > maxMiddleWidth ) maxMiddleWidth = top_->width();
	if ( bottom_ && bottom_->width() > maxMiddleWidth ) maxMiddleWidth = bottom_->width();

	if ( left_ && left_->height() > contentHeight ) contentHeight = left_->height();
	if ( right_ && right_->height() > contentHeight ) contentHeight = right_->height();

	//Adjust the size of the content if necessary
	if (content_ && content_->sizeDependsOnParent())
		content_->changeGeometry(contentWidth + (maxMiddleWidth - middleWidth), contentHeight);

	//Adjust panels and/or the inner size
	if ( maxMiddleWidth > middleWidth ) contentWidth += maxMiddleWidth - middleWidth;
	if ( top_ && maxMiddleWidth > top_->width() ) top_->changeGeometry(maxMiddleWidth, 0);
	if ( bottom_ && maxMiddleWidth > bottom_->width() ) bottom_->changeGeometry(maxMiddleWidth, 0);
	if ( left_ && contentHeight > left_->height() ) left_->changeGeometry(0, contentHeight);
	if ( right_ && contentHeight > right_->height() ) right_->changeGeometry(0, contentHeight);

	// Compute outter sizes
	int outterWidth = contentWidth + style()->leftInnerMargin() + style()->rightInnerMargin();

	int extraLeft = 0;
	if ( style()->isLeftProtrusionFixed() && style()->leftProtrusion() > 0) extraLeft = style()->leftProtrusion();
	if ( left_ && left_->width() > extraLeft) extraLeft = left_->width();
	outterWidth += extraLeft;

	if ( right_ ) outterWidth += right_->width();
	int outterHeight = contentHeight + style()->topInnerMargin() + style()->bottomInnerMargin();
	if ( top_ ) outterHeight += top_->height();
	if ( bottom_ ) outterHeight += bottom_->height();


	if (hasShape() && style()->shapeOnlyOnContent())
	{
		// If the shape must cover only the content manually set the way it should look.

		// Set shape position
		int x = style()->leftMargin();
		if (style()->isLeftProtrusionFixed())
		{
			if (style()->leftProtrusion() > 0) x += style()->leftProtrusion();
		}
		else x += left_ ? left_->width() / 2 : 0;

		int y = style()->topMargin() + (top_ ? top_->height() / 2 : 0);
		getShape()->setOffset(x, y);

		// Set shape size
		int middleHeight = outterHeight - y - (bottom_? (bottom_->height()/2) :0);
		getShape()->setOutterSize(maxMiddleWidth, middleHeight);

		// Set Layout size
		setWidth(outterWidth + style()->leftMargin() + style()->rightMargin());
		setHeight(outterHeight + style()->topMargin() + style()->bottomMargin());
	}
	else setInnerSize(outterWidth, outterHeight); // Use the default method when the shape must cover the entire layout.

	// Determine the right offset to use.
	int xOffset = style()->leftMargin();
	int yOffset = style()->rightMargin();
	if (hasShape() && !style()->shapeOnlyOnContent())
	{
		xOffset = getShape()->contentLeft();
		yOffset = getShape()->contentTop();
	}

	// Set positions
	int xLeft = xOffset;
	int xTop = xLeft;
	int xContent;
	int xRight;

	if (style()->isLeftProtrusionFixed())
	{
		if ( style()->leftProtrusion() < 0) xLeft -= style()->leftProtrusion();
		else xTop += style()->leftProtrusion();

		xContent = xLeft + (left_ ? left_->width() : 0) + style()->leftInnerMargin();
		if (xContent < xOffset + style()->leftProtrusion() + style()->leftInnerMargin())
			xContent = xOffset + style()->leftProtrusion() + style()->leftInnerMargin();
	}
	else
	{
		xTop = xLeft + (left_ ? left_->width() / 2 : 0);
		xContent = xLeft + (left_ ? left_->width() : 0) + style()->leftInnerMargin();
	}

	xRight = xContent + (content_ ? content_->width() : 0) + style()->rightInnerMargin();

	int yTop = yOffset;
	int yContent = yTop + (top_ ? top_->height() : 0) + style()->topInnerMargin();
	int yBottom = yContent + contentHeight + style()->bottomInnerMargin();

	if ( top_ ) top_->setPos(xTop, yTop);
	if ( left_ ) left_->setPos(xLeft, yContent);
	if ( content_ ) content_->setPos(xContent, yContent);
	if ( right_ ) right_->setPos(xRight, yContent);
	if ( bottom_ ) bottom_->setPos(xTop, yBottom);
}