Skip to content
Snippets Groups Projects
qwt_text_label.cpp 6.72 KiB
Newer Older
  • Learn to ignore specific revisions
  • pixhawk's avatar
    pixhawk committed
    /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
     * Qwt Widget Library
     * Copyright (C) 1997   Josef Wilgen
     * Copyright (C) 2002   Uwe Rathmann
     *
     * This library is free software; you can redistribute it and/or
     * modify it under the terms of the Qwt License, Version 1.0
     *****************************************************************************/
    
    
    Bryant's avatar
    Bryant committed
    #include "qwt_text_label.h"
    
    pixhawk's avatar
    pixhawk committed
    #include "qwt_text.h"
    #include "qwt_painter.h"
    
    Bryant's avatar
    Bryant committed
    #include <qpainter.h>
    #include <qevent.h>
    #include <qmath.h>
    
    pixhawk's avatar
    pixhawk committed
    
    class QwtTextLabel::PrivateData
    {
    public:
        PrivateData():
    
    Bryant's avatar
    Bryant committed
            indent( 4 ),
            margin( 0 )
        {
    
    pixhawk's avatar
    pixhawk committed
        }
    
        int indent;
        int margin;
        QwtText text;
    };
    
    
    pixhawk's avatar
    pixhawk committed
      Constructs an empty label.
      \param parent Parent widget
    */
    
    Bryant's avatar
    Bryant committed
    QwtTextLabel::QwtTextLabel( QWidget *parent ):
        QFrame( parent )
    
    pixhawk's avatar
    pixhawk committed
    {
        init();
    }
    
    /*!
      Constructs a label that displays the text, text
      \param parent Parent widget
      \param text Text
    */
    
    Bryant's avatar
    Bryant committed
    QwtTextLabel::QwtTextLabel( const QwtText &text, QWidget *parent ):
        QFrame( parent )
    
    pixhawk's avatar
    pixhawk committed
    {
        init();
        d_data->text = text;
    }
    
    //! Destructor
    QwtTextLabel::~QwtTextLabel()
    {
        delete d_data;
    }
    
    void QwtTextLabel::init()
    {
        d_data = new PrivateData();
    
    Bryant's avatar
    Bryant committed
        setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred );
    }
    
    /*!
       Interface for the designer plugin - does the same as setText()
       \sa plainText()
     */
    void QwtTextLabel::setPlainText( const QString &text )
    {
        setText( QwtText( text ) );
    }
    
    /*!
       Interface for the designer plugin
    
       \return Text as plain text
       \sa setPlainText(), text()
     */
    QString QwtTextLabel::plainText() const
    {
        return d_data->text.text();
    
    pixhawk's avatar
    pixhawk committed
    }
    
    /*!
       Change the label's text, keeping all other QwtText attributes
       \param text New text
       \param textFormat Format of text
    
      \sa QwtText
    */
    
    Bryant's avatar
    Bryant committed
    void QwtTextLabel::setText( const QString &text, 
        QwtText::TextFormat textFormat )
    
    pixhawk's avatar
    pixhawk committed
    {
    
    Bryant's avatar
    Bryant committed
        d_data->text.setText( text, textFormat );
    
    pixhawk's avatar
    pixhawk committed
    
        update();
        updateGeometry();
    }
    
    /*!
       Change the label's text
       \param text New text
    */
    
    Bryant's avatar
    Bryant committed
    void QwtTextLabel::setText( const QwtText &text )
    
    pixhawk's avatar
    pixhawk committed
    {
        d_data->text = text;
    
        update();
        updateGeometry();
    }
    
    //! Return the text
    const QwtText &QwtTextLabel::text() const
    {
        return d_data->text;
    }
    
    //! Clear the text and all QwtText attributes
    void QwtTextLabel::clear()
    {
        d_data->text = QwtText();
    
        update();
        updateGeometry();
    }
    
    //! Return label's text indent in pixels
    int QwtTextLabel::indent() const
    {
        return d_data->indent;
    }
    
    /*!
      Set label's text indent in pixels
      \param indent Indentation in pixels
    */
    
    Bryant's avatar
    Bryant committed
    void QwtTextLabel::setIndent( int indent )
    
    pixhawk's avatar
    pixhawk committed
    {
        if ( indent < 0 )
            indent = 0;
    
        d_data->indent = indent;
    
        update();
        updateGeometry();
    }
    
    //! Return label's text indent in pixels
    int QwtTextLabel::margin() const
    {
        return d_data->margin;
    }
    
    /*!
      Set label's margin in pixels
      \param margin Margin in pixels
    */
    
    Bryant's avatar
    Bryant committed
    void QwtTextLabel::setMargin( int margin )
    
    pixhawk's avatar
    pixhawk committed
    {
        d_data->margin = margin;
    
        update();
        updateGeometry();
    }
    
    //! Return label's margin in pixels
    QSize QwtTextLabel::sizeHint() const
    {
        return minimumSizeHint();
    }
    
    //! Return a minimum size hint
    QSize QwtTextLabel::minimumSizeHint() const
    {
    
    Bryant's avatar
    Bryant committed
        QSizeF sz = d_data->text.textSize( font() );
    
    pixhawk's avatar
    pixhawk committed
    
    
    Bryant's avatar
    Bryant committed
        int mw = 2 * ( frameWidth() + d_data->margin );
    
    pixhawk's avatar
    pixhawk committed
        int mh = mw;
    
        int indent = d_data->indent;
        if ( indent <= 0 )
            indent = defaultIndent();
    
    
    Bryant's avatar
    Bryant committed
        if ( indent > 0 )
        {
    
    pixhawk's avatar
    pixhawk committed
            const int align = d_data->text.renderFlags();
            if ( align & Qt::AlignLeft || align & Qt::AlignRight )
                mw += d_data->indent;
            else if ( align & Qt::AlignTop || align & Qt::AlignBottom )
                mh += d_data->indent;
        }
    
    Bryant's avatar
    Bryant committed
        sz += QSizeF( mw, mh );
    
    pixhawk's avatar
    pixhawk committed
    
    
    Bryant's avatar
    Bryant committed
        return QSize( qCeil( sz.width() ), qCeil( sz.height() ) );
    
    pixhawk's avatar
    pixhawk committed
    }
    
    /*!
       \param width Width
    
    Bryant's avatar
    Bryant committed
       \return Preferred height for this widget, given the width.
    
    pixhawk's avatar
    pixhawk committed
    */
    
    Bryant's avatar
    Bryant committed
    int QwtTextLabel::heightForWidth( int width ) const
    
    pixhawk's avatar
    pixhawk committed
    {
        const int renderFlags = d_data->text.renderFlags();
    
        int indent = d_data->indent;
        if ( indent <= 0 )
            indent = defaultIndent();
    
        width -= 2 * frameWidth();
        if ( renderFlags & Qt::AlignLeft || renderFlags & Qt::AlignRight )
            width -= indent;
    
    
    Bryant's avatar
    Bryant committed
        int height = qCeil( d_data->text.heightForWidth( width, font() ) );
        if ( ( renderFlags & Qt::AlignTop ) || ( renderFlags & Qt::AlignBottom ) )
    
    pixhawk's avatar
    pixhawk committed
            height += indent;
    
        height += 2 * frameWidth();
    
        return height;
    }
    
    
    Bryant's avatar
    Bryant committed
    /*!
       Qt paint event
       \param event Paint event
    */
    void QwtTextLabel::paintEvent( QPaintEvent *event )
    
    pixhawk's avatar
    pixhawk committed
    {
    
    Bryant's avatar
    Bryant committed
        QPainter painter( this );
    
    pixhawk's avatar
    pixhawk committed
    
    
    Bryant's avatar
    Bryant committed
        if ( !contentsRect().contains( event->rect() ) )
        {
    
    pixhawk's avatar
    pixhawk committed
            painter.save();
            painter.setClipRegion( event->region() & frameRect() );
            drawFrame( &painter );
            painter.restore();
        }
    
    
    Bryant's avatar
    Bryant committed
        painter.setClipRegion( event->region() & contentsRect() );
    
    pixhawk's avatar
    pixhawk committed
    
        drawContents( &painter );
    }
    
    //! Redraw the text and focus indicator
    
    Bryant's avatar
    Bryant committed
    void QwtTextLabel::drawContents( QPainter *painter )
    
    pixhawk's avatar
    pixhawk committed
    {
        const QRect r = textRect();
        if ( r.isEmpty() )
            return;
    
    
    Bryant's avatar
    Bryant committed
        painter->setFont( font() );
        painter->setPen( palette().color( QPalette::Active, QPalette::Text ) );
    
    pixhawk's avatar
    pixhawk committed
    
    
    Bryant's avatar
    Bryant committed
        drawText( painter, QRectF( r ) );
    
    pixhawk's avatar
    pixhawk committed
    
    
    Bryant's avatar
    Bryant committed
        if ( hasFocus() )
        {
            const int m = 2;
    
    pixhawk's avatar
    pixhawk committed
    
    
    Bryant's avatar
    Bryant committed
            QRect focusRect = contentsRect().adjusted( m, m, -m + 1, -m + 1);
    
    pixhawk's avatar
    pixhawk committed
    
    
    Bryant's avatar
    Bryant committed
            QwtPainter::drawFocusRect( painter, this, focusRect );
    
    pixhawk's avatar
    pixhawk committed
        }
    }
    
    //! Redraw the text
    
    Bryant's avatar
    Bryant committed
    void QwtTextLabel::drawText( QPainter *painter, const QRectF &textRect )
    
    pixhawk's avatar
    pixhawk committed
    {
    
    Bryant's avatar
    Bryant committed
        d_data->text.draw( painter, textRect );
    
    pixhawk's avatar
    pixhawk committed
    }
    
    
    Bryant's avatar
    Bryant committed
      Calculate geometry for the text in widget coordinates
      \return Geometry for the text
    
    pixhawk's avatar
    pixhawk committed
    */
    QRect QwtTextLabel::textRect() const
    {
        QRect r = contentsRect();
    
    
    Bryant's avatar
    Bryant committed
        if ( !r.isEmpty() && d_data->margin > 0 )
        {
            r.setRect( r.x() + d_data->margin, r.y() + d_data->margin,
                r.width() - 2 * d_data->margin, r.height() - 2 * d_data->margin );
    
    pixhawk's avatar
    pixhawk committed
        }
    
    
    Bryant's avatar
    Bryant committed
        if ( !r.isEmpty() )
        {
    
    pixhawk's avatar
    pixhawk committed
            int indent = d_data->indent;
            if ( indent <= 0 )
                indent = defaultIndent();
    
    
    Bryant's avatar
    Bryant committed
            if ( indent > 0 )
            {
    
    pixhawk's avatar
    pixhawk committed
                const int renderFlags = d_data->text.renderFlags();
    
                if ( renderFlags & Qt::AlignLeft )
    
    Bryant's avatar
    Bryant committed
                    r.setX( r.x() + indent );
    
    pixhawk's avatar
    pixhawk committed
                else if ( renderFlags & Qt::AlignRight )
    
    Bryant's avatar
    Bryant committed
                    r.setWidth( r.width() - indent );
    
    pixhawk's avatar
    pixhawk committed
                else if ( renderFlags & Qt::AlignTop )
    
    Bryant's avatar
    Bryant committed
                    r.setY( r.y() + indent );
    
    pixhawk's avatar
    pixhawk committed
                else if ( renderFlags & Qt::AlignBottom )
    
    Bryant's avatar
    Bryant committed
                    r.setHeight( r.height() - indent );
    
    pixhawk's avatar
    pixhawk committed
            }
        }
    
        return r;
    }
    
    int QwtTextLabel::defaultIndent() const
    {
        if ( frameWidth() <= 0 )
            return 0;
    
        QFont fnt;
    
    Bryant's avatar
    Bryant committed
        if ( d_data->text.testPaintAttribute( QwtText::PaintUsingTextFont ) )
    
    pixhawk's avatar
    pixhawk committed
            fnt = d_data->text.font();
        else
            fnt = font();
    
    
    Bryant's avatar
    Bryant committed
        return QFontMetrics( fnt ).width( 'x' ) / 2;
    
    pixhawk's avatar
    pixhawk committed
    }