KD Chart 2
[rev.2.5]
|
00001 /**************************************************************************** 00002 ** Copyright (C) 2001-2012 Klaralvdalens Datakonsult AB. All rights reserved. 00003 ** 00004 ** This file is part of the KD Chart library. 00005 ** 00006 ** Licensees holding valid commercial KD Chart licenses may use this file in 00007 ** accordance with the KD Chart Commercial License Agreement provided with 00008 ** the Software. 00009 ** 00010 ** 00011 ** This file may be distributed and/or modified under the terms of the 00012 ** GNU General Public License version 2 and version 3 as published by the 00013 ** Free Software Foundation and appearing in the file LICENSE.GPL.txt included. 00014 ** 00015 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 00016 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 00017 ** 00018 ** Contact info@kdab.com if any conditions of this licensing are not 00019 ** clear to you. 00020 ** 00021 **********************************************************************/ 00022 00023 #include "KDChartAbstractAreaBase.h" 00024 #include "KDChartAbstractAreaBase_p.h" 00025 #include <KDChartBackgroundAttributes.h> 00026 #include <KDChartFrameAttributes.h> 00027 #include <KDChartTextAttributes.h> 00028 #include "KDChartPainterSaver_p.h" 00029 #include "KDChartPrintingParameters.h" 00030 #include <QPainter> 00031 00032 #include <KDABLibFakes> 00033 00034 00035 using namespace KDChart; 00036 00037 AbstractAreaBase::Private::Private() : 00038 visible( true ) 00039 // PENDING(khz) dockingPointToPadding?, alignToDockingPoint? 00040 { 00041 init(); 00042 } 00043 00044 00045 AbstractAreaBase::Private::~Private() {} 00046 00047 00048 void AbstractAreaBase::Private::init() 00049 { 00050 } 00051 00052 00053 AbstractAreaBase::AbstractAreaBase() : 00054 _d( new Private() ) 00055 { 00056 } 00057 00058 AbstractAreaBase::~AbstractAreaBase() 00059 { 00060 delete _d; _d = 0; 00061 } 00062 00063 00064 void AbstractAreaBase::init() 00065 { 00066 } 00067 00068 00069 #define d d_func() 00070 00071 bool AbstractAreaBase::compare( const AbstractAreaBase* other ) const 00072 { 00073 if( other == this ) return true; 00074 if ( !other ) { 00075 return false; 00076 } 00077 return (frameAttributes() == other->frameAttributes()) && 00078 (backgroundAttributes() == other->backgroundAttributes()); 00079 } 00080 00081 void AbstractAreaBase::alignToReferencePoint( const RelativePosition& position ) 00082 { 00083 Q_UNUSED( position ); 00084 // PENDING(kalle) FIXME 00085 qWarning( "Sorry, not implemented: void AbstractAreaBase::alignToReferencePoint( const RelativePosition& position )" ); 00086 } 00087 00088 void AbstractAreaBase::setFrameAttributes( const FrameAttributes &a ) 00089 { 00090 if( d->frameAttributes == a ) 00091 return; 00092 00093 d->frameAttributes = a; 00094 positionHasChanged(); 00095 } 00096 00097 FrameAttributes AbstractAreaBase::frameAttributes() const 00098 { 00099 return d->frameAttributes; 00100 } 00101 00102 void AbstractAreaBase::setBackgroundAttributes( const BackgroundAttributes &a ) 00103 { 00104 if( d->backgroundAttributes == a ) 00105 return; 00106 00107 d->backgroundAttributes = a; 00108 positionHasChanged(); 00109 } 00110 00111 BackgroundAttributes AbstractAreaBase::backgroundAttributes() const 00112 { 00113 return d->backgroundAttributes; 00114 } 00115 00116 00117 /* static */ 00118 void AbstractAreaBase::paintBackgroundAttributes( QPainter& painter, const QRect& rect, 00119 const KDChart::BackgroundAttributes& attributes ) 00120 { 00121 if( !attributes.isVisible() ) return; 00122 00123 /* first draw the brush (may contain a pixmap)*/ 00124 if( Qt::NoBrush != attributes.brush().style() ) { 00125 KDChart::PainterSaver painterSaver( &painter ); 00126 painter.setPen( Qt::NoPen ); 00127 const QPointF newTopLeft( painter.deviceMatrix().map( rect.topLeft() ) ); 00128 painter.setBrushOrigin( newTopLeft ); 00129 painter.setBrush( attributes.brush() ); 00130 painter.drawRect( rect.adjusted( 0, 0, -1, -1 ) ); 00131 } 00132 /* next draw the backPixmap over the brush */ 00133 if( !attributes.pixmap().isNull() && 00134 attributes.pixmapMode() != BackgroundAttributes::BackgroundPixmapModeNone ) { 00135 QPointF ol = rect.topLeft(); 00136 if( BackgroundAttributes::BackgroundPixmapModeCentered == attributes.pixmapMode() ) 00137 { 00138 ol.setX( rect.center().x() - attributes.pixmap().width() / 2 ); 00139 ol.setY( rect.center().y() - attributes.pixmap().height()/ 2 ); 00140 painter.drawPixmap( ol, attributes.pixmap() ); 00141 } else { 00142 QMatrix m; 00143 qreal zW = (qreal)rect.width() / (qreal)attributes.pixmap().width(); 00144 qreal zH = (qreal)rect.height() / (qreal)attributes.pixmap().height(); 00145 switch( attributes.pixmapMode() ) { 00146 case BackgroundAttributes::BackgroundPixmapModeScaled: 00147 { 00148 qreal z; 00149 z = qMin( zW, zH ); 00150 m.scale( z, z ); 00151 } 00152 break; 00153 case BackgroundAttributes::BackgroundPixmapModeStretched: 00154 m.scale( zW, zH ); 00155 break; 00156 default: 00157 ; // Cannot happen, previously checked 00158 } 00159 QPixmap pm = attributes.pixmap().transformed( m ); 00160 ol.setX( rect.center().x() - pm.width() / 2 ); 00161 ol.setY( rect.center().y() - pm.height()/ 2 ); 00162 painter.drawPixmap( ol, pm ); 00163 } 00164 } 00165 } 00166 00167 /* static */ 00168 void AbstractAreaBase::paintFrameAttributes( QPainter& painter, const QRect& rect, 00169 const KDChart::FrameAttributes& attributes ) 00170 { 00171 00172 if( !attributes.isVisible() ) return; 00173 00174 // Note: We set the brush to NoBrush explicitly here. 00175 // Otherwise we might get a filled rectangle, so any 00176 // previously drawn background would be overwritten by that area. 00177 00178 const QPen oldPen( painter.pen() ); 00179 const QBrush oldBrush( painter.brush() ); 00180 00181 painter.setPen( PrintingParameters::scalePen( attributes.pen() ) ); 00182 painter.setBrush( Qt::NoBrush ); 00183 painter.drawRoundedRect( rect.adjusted( 0, 0, -1, -1 ), attributes.cornerRadius(), attributes.cornerRadius() ); 00184 00185 painter.setBrush( oldBrush ); 00186 painter.setPen( oldPen ); 00187 } 00188 00189 void AbstractAreaBase::paintBackground( QPainter& painter, const QRect& rect ) 00190 { 00191 Q_ASSERT_X ( d != 0, "AbstractAreaBase::paintBackground()", 00192 "Private class was not initialized!" ); 00193 00194 PainterSaver painterSaver( &painter ); 00195 00196 const qreal radius = d->frameAttributes.cornerRadius(); 00197 QPainterPath path; 00198 path.addRoundedRect( rect.adjusted( 0, 0, -1, -1 ), radius, radius ); 00199 painter.setClipPath(path); 00200 00201 paintBackgroundAttributes( painter, rect, d->backgroundAttributes ); 00202 } 00203 00204 00205 void AbstractAreaBase::paintFrame( QPainter& painter, const QRect& rect ) 00206 { 00207 Q_ASSERT_X ( d != 0, "AbstractAreaBase::paintFrame()", 00208 "Private class was not initialized!" ); 00209 paintFrameAttributes( painter, rect, d->frameAttributes ); 00210 } 00211 00212 00213 void AbstractAreaBase::getFrameLeadings(int& left, int& top, int& right, int& bottom ) const 00214 { 00215 int padding = 0; 00216 if ( d && d->frameAttributes.isVisible() ) { 00217 padding = qMax( d->frameAttributes.padding(), 0 ); 00218 } 00219 left = padding; 00220 top = padding; 00221 right = padding; 00222 bottom = padding; 00223 } 00224 00225 QRect AbstractAreaBase::innerRect() const 00226 { 00227 int left; 00228 int top; 00229 int right; 00230 int bottom; 00231 getFrameLeadings( left, top, right, bottom ); 00232 return QRect ( QPoint( 0, 0 ), areaGeometry().size() ).adjusted( left, top, -right, -bottom ); 00233 } 00234 00235 void AbstractAreaBase::positionHasChanged() 00236 { 00237 // this bloc left empty intentionally 00238 }