00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include <qpainter.h>
00031 #include <qbrush.h>
00032
00033 #include <KDFrame.h>
00034 #include <KDFrameProfileSection.h>
00035 #include <KDXMLTools.h>
00036
00037 #if defined( SUN7 ) || defined( _SGIAPI )
00038 #include <math.h>
00039 #else
00040 #include <cmath>
00041 #endif
00042 #ifdef Q_WS_WIN
00043 #define M_PI 3.14159265358979323846
00044 #endif
00045
00046
00047 KDFrame::~KDFrame()
00048 {
00049 _profileSections.clear();
00050 }
00051
00052 KDFrame::KDFrameCorner::~KDFrameCorner()
00053 {
00054
00055 }
00056
00057
00058
00059
00060
00061 void KDFrame::paintBackground( QPainter& painter, const QRect& innerRect ) const
00062 {
00063
00064 if( Qt::NoBrush != _background.style() ) {
00065 QPen oldPen( painter.pen() );
00066 QPoint oldOrig( painter.brushOrigin() );
00067 QBrush oldBrush( painter.brush() );
00068 painter.setPen( Qt::NoPen );
00069 const QPoint newTopLeft( painter.xForm( innerRect.topLeft() ) );
00070 painter.setBrushOrigin( newTopLeft.x(), newTopLeft.y() );
00071 painter.setBrush( _background );
00072 painter.drawRect( innerRect.x(), innerRect.y(),
00073 innerRect.width(), innerRect.height() );
00074 painter.setPen( oldPen );
00075 painter.setBrushOrigin( oldOrig );
00076 painter.setBrush( oldBrush );
00077 }
00078
00079 if( ! _backPixmap.isNull() ) {
00080 QPoint ol = innerRect.topLeft();
00081 if( PixCentered == _backPixmapMode )
00082 {
00083 ol.setX( innerRect.center().x() - _backPixmap.width() / 2 );
00084 ol.setY( innerRect.center().y() - _backPixmap.height()/ 2 );
00085 bitBlt( painter.device(), ol, &_backPixmap );
00086 } else {
00087 QWMatrix m;
00088 double zW = (double)innerRect.width() / (double)_backPixmap.width();
00089 double zH = (double)innerRect.height() / (double)_backPixmap.height();
00090 switch ( _backPixmapMode ) {
00091 case PixCentered:
00092 break;
00093 case PixScaled: {
00094 double z;
00095 z = QMIN( zW, zH );
00096 m.scale( z, z );
00097 }
00098 break;
00099 case PixStretched:
00100 m.scale( zW, zH );
00101 break;
00102 }
00103 QPixmap pm = _backPixmap.xForm( m );
00104 ol.setX( innerRect.center().x() - pm.width() / 2 );
00105 ol.setY( innerRect.center().y() - pm.height()/ 2 );
00106 bitBlt( painter.device(), ol, &pm );
00107 }
00108 }
00109 }
00110
00111
00112 void KDFrame::paintEdges( QPainter& painter, const QRect& innerRect ) const
00113 {
00114
00115
00116
00117
00118
00119
00120
00121 if( !_topProfile.isEmpty() ){
00122
00123 KDFrameProfileSection* section;
00124 for ( section = ((KDFrameProfile)_topProfile).last(); section; section = ((KDFrameProfile)_topProfile).prev() ){
00125 const QPen oldPen = painter.pen();
00126 const QBrush oldBrush = painter.brush();
00127 QPen thePen;
00128 thePen = section->pen();
00129 int penWidth = QMAX(thePen.width(), 1) * QMAX(section->width(), 1);
00130
00131
00132
00133 thePen.setWidth( penWidth );
00134 painter.setPen( thePen );
00135 painter.setBrush( Qt::NoBrush );
00136 painter.drawRect( innerRect.x()-penWidth,
00137 innerRect.y()-penWidth,
00138 innerRect.width() +2*penWidth,
00139 innerRect.height() +2*penWidth );
00140 painter.setBrush( oldBrush );
00141 painter.setPen( oldPen );
00142 }
00143 }
00144 }
00145
00146
00147 void KDFrame::paintCorners( QPainter& , const QRect& ) const
00148 {
00149
00150
00151
00152 ;
00153 }
00154
00155
00156 void KDFrame::paint( QPainter* painter,
00157 KDFramePaintSteps steps,
00158 QRect innerRect ) const
00159 {
00160 if( painter ) {
00161 const QRect& rect = innerRect.isValid() ? innerRect : _innerRect;
00162 switch( steps ) {
00163 case PaintBackground:
00164 paintBackground( *painter, rect );
00165 break;
00166 case PaintEdges:
00167 paintEdges( *painter, rect );
00168 break;
00169 case PaintCorners:
00170 paintCorners( *painter, rect );
00171 break;
00172 case PaintBorder:
00173 paintEdges( *painter, rect );
00174 paintCorners( *painter, rect );
00175 break;
00176 case PaintAll:
00177 paintBackground( *painter, rect );
00178 paintEdges( *painter, rect );
00179 paintCorners( *painter, rect );
00180 break;
00181 }
00182 }
00183 }
00184
00185
00186 void KDFrame::clearProfile( ProfileName name )
00187 {
00188 switch( name ) {
00189 case ProfileTop: _topProfile.clear();
00190 break;
00191 case ProfileRight: _rightProfile.clear();
00192 break;
00193 case ProfileBottom:_bottomProfile.clear();
00194 break;
00195 case ProfileLeft: _leftProfile.clear();
00196 break;
00197 }
00198 }
00199
00200 void KDFrame::addProfileSection( ProfileName name,
00201 int wid,
00202 QPen pen,
00203 KDFrameProfileSection::Direction dir,
00204 KDFrameProfileSection::Curvature curv )
00205 {
00206 switch( name ) {
00207 case ProfileTop: _topProfile.append( new KDFrameProfileSection( dir, curv, wid, pen ) );
00208 break;
00209 case ProfileRight: _rightProfile.append( new KDFrameProfileSection( dir, curv, wid, pen ) );
00210 break;
00211 case ProfileBottom:_bottomProfile.append(new KDFrameProfileSection( dir, curv, wid, pen ) );
00212 break;
00213 case ProfileLeft: _leftProfile.append( new KDFrameProfileSection( dir, curv, wid, pen ) );
00214 break;
00215 }
00216 }
00217
00218 void KDFrame::setProfile( ProfileName name, const KDFrameProfile& profile )
00219 {
00220 switch( name ) {
00221 case ProfileTop: _topProfile = profile;
00222 break;
00223 case ProfileRight: _rightProfile = profile;
00224 break;
00225 case ProfileBottom:_bottomProfile = profile;
00226 break;
00227 case ProfileLeft: _leftProfile = profile;
00228 break;
00229 }
00230 }
00231
00232 const KDFrameProfile& KDFrame::profile( ProfileName name ) const
00233 {
00234 switch( name ) {
00235 case ProfileTop: return _topProfile;
00236 break;
00237 case ProfileRight: return _rightProfile;
00238 break;
00239 case ProfileBottom:return _bottomProfile;
00240 break;
00241 default: return _leftProfile;
00242 }
00243
00244 return _leftProfile;
00245 }
00246
00247
00248 void KDFrame::setSimpleFrame( SimpleFrame frame,
00249 int lineWidth,
00250 int midLineWidth,
00251 QPen pen,
00252 QBrush background,
00253 const QPixmap* backPixmap,
00254 BackPixmapMode backPixmapMode )
00255 {
00256 _profileSections.clear();
00257 _topProfile.clear();
00258 _rightProfile.clear();
00259 _bottomProfile.clear();
00260 _leftProfile.clear();
00261 _background = background;
00262 _backPixmap = backPixmap ? *backPixmap : QPixmap();
00263 _backPixmapMode = backPixmapMode;
00264 if( FrameFlat == frame ) {
00265
00266 KDFrameProfileSection* newsection =
00267 new KDFrameProfileSection( KDFrameProfileSection::DirPlain,
00268 KDFrameProfileSection::CvtPlain,
00269 lineWidth, pen );
00270 _profileSections.append( newsection );
00271
00272
00273
00274 _topProfile.append( newsection );
00275 _rightProfile = _topProfile;
00276 _bottomProfile = _topProfile;
00277 _leftProfile = _topProfile;
00278 }
00279 else {
00280 switch( frame ) {
00281 case FrameElegance: {
00282 int line1 = lineWidth / 8;
00283 int line2 = lineWidth / 16;
00284 int line3 = line2;
00285 int gap2 = line2 * 4;
00286 int gap1 = lineWidth - line1 - line2 - line3 - gap2;
00287 QPen noP( Qt::NoPen );
00288 KDFrameProfileSection* newsection;
00289 newsection = new KDFrameProfileSection( KDFrameProfileSection::DirPlain,
00290 KDFrameProfileSection::CvtPlain,
00291 line1, pen );
00292 _profileSections.append( newsection );
00293 _topProfile.append( newsection );
00294 newsection = new KDFrameProfileSection( KDFrameProfileSection::DirPlain,
00295 KDFrameProfileSection::CvtPlain,
00296 gap1, noP );
00297 _profileSections.append( newsection );
00298 _topProfile.append( newsection );
00299 newsection = new KDFrameProfileSection( KDFrameProfileSection::DirPlain,
00300 KDFrameProfileSection::CvtPlain,
00301 line2, pen );
00302 _profileSections.append( newsection );
00303 _topProfile.append( newsection );
00304 newsection = new KDFrameProfileSection( KDFrameProfileSection::DirPlain,
00305 KDFrameProfileSection::CvtPlain,
00306 gap2, noP );
00307 _profileSections.append( newsection );
00308 _topProfile.append( newsection );
00309 newsection = new KDFrameProfileSection( KDFrameProfileSection::DirPlain,
00310 KDFrameProfileSection::CvtPlain,
00311 line3, pen );
00312 _profileSections.append( newsection );
00313 _topProfile.append( newsection );
00314 }
00315 break;
00316 case FrameBoxRaized:
00317 {
00318 KDFrameProfileSection* newsection;
00319 newsection = new KDFrameProfileSection( KDFrameProfileSection::DirRaising,
00320 KDFrameProfileSection::CvtPlain,
00321 lineWidth, pen );
00322 _profileSections.append( newsection );
00323 _topProfile.append( newsection );
00324 newsection = new KDFrameProfileSection( KDFrameProfileSection::DirPlain,
00325 KDFrameProfileSection::CvtPlain,
00326 midLineWidth, pen );
00327 _profileSections.append( newsection );
00328 _topProfile.append( newsection );
00329 newsection = new KDFrameProfileSection( KDFrameProfileSection::DirSinking,
00330 KDFrameProfileSection::CvtPlain,
00331 lineWidth, pen );
00332 _profileSections.append( newsection );
00333 _topProfile.append( newsection );
00334 break;
00335 }
00336 case FrameBoxSunken:
00337 {
00338 KDFrameProfileSection* newsection;
00339 newsection = new KDFrameProfileSection( KDFrameProfileSection::DirSinking,
00340 KDFrameProfileSection::CvtPlain,
00341 lineWidth, pen );
00342 _profileSections.append( newsection );
00343 _topProfile.append( newsection );
00344 newsection = new KDFrameProfileSection( KDFrameProfileSection::DirPlain,
00345 KDFrameProfileSection::CvtPlain,
00346 midLineWidth, pen );
00347 _profileSections.append( newsection );
00348 _topProfile.append( newsection );
00349 newsection = new KDFrameProfileSection( KDFrameProfileSection::DirRaising,
00350 KDFrameProfileSection::CvtPlain,
00351 lineWidth, pen );
00352 _profileSections.append( newsection );
00353 _topProfile.append( newsection );
00354 }
00355 break;
00356 case FramePanelRaized:
00357 {
00358 KDFrameProfileSection* newsection;
00359 newsection = new KDFrameProfileSection( KDFrameProfileSection::DirRaising,
00360 KDFrameProfileSection::CvtPlain,
00361 lineWidth, pen );
00362 _profileSections.append( newsection );
00363 _topProfile.append( newsection );
00364 break;
00365 }
00366 case FramePanelSunken:
00367 {
00368 KDFrameProfileSection* newsection;
00369 newsection = new KDFrameProfileSection( KDFrameProfileSection::DirSinking,
00370 KDFrameProfileSection::CvtPlain,
00371 lineWidth, pen );
00372 _profileSections.append( newsection );
00373 _topProfile.append( newsection );
00374 }
00375 break;
00376 case FrameSemicircular:
00377 {
00378 KDFrameProfileSection* newsection;
00379 newsection = new KDFrameProfileSection( KDFrameProfileSection::DirRaising,
00380 KDFrameProfileSection::CvtConvex,
00381 lineWidth, pen );
00382 _profileSections.append( newsection );
00383 _topProfile.append( newsection );
00384 newsection = new KDFrameProfileSection( KDFrameProfileSection::DirPlain,
00385 KDFrameProfileSection::CvtPlain,
00386 midLineWidth, pen );
00387 _profileSections.append( newsection );
00388 _topProfile.append( newsection );
00389 newsection = new KDFrameProfileSection( KDFrameProfileSection::DirSinking,
00390 KDFrameProfileSection::CvtConcave,
00391 lineWidth, pen );
00392 _profileSections.append( newsection );
00393 _topProfile.append( newsection );
00394 }
00395 break;
00396 default:
00397 break;
00398 }
00399 }
00400 _rightProfile = _topProfile;
00401 _bottomProfile = _topProfile;
00402 _leftProfile = _topProfile;
00403 setCorners( CornerNormal, 0 );
00404 }
00405
00406
00407 void KDFrame::createFrameNode( QDomDocument& document, QDomNode& parent,
00408 const QString& elementName,
00409 const KDFrame& frame )
00410 {
00411 QDomElement frameElement = document.createElement( elementName );
00412 parent.appendChild( frameElement );
00413 KDXML::createIntNode( document, frameElement, "ShadowWidth",
00414 frame._shadowWidth );
00415 KDXML::createStringNode( document, frameElement, "CornerName",
00416 cornerNameToString( frame._sunPos ) );
00417
00418 KDXML::createBrushNode( document, frameElement, "Background",
00419 frame._background );
00420 KDXML::createPixmapNode( document, frameElement, "BackPixmap",
00421 frame._backPixmap );
00422 KDXML::createStringNode( document, frameElement, "BackPixmapMode",
00423 backPixmapModeToString( frame._backPixmapMode ) );
00424
00425 KDXML::createRectNode( document, frameElement, "InnerRect",
00426 frame._innerRect );
00427 createFrameProfileNode( document, frameElement, "TopProfile",
00428 frame._topProfile );
00429 createFrameProfileNode( document, frameElement, "RightProfile",
00430 frame._rightProfile );
00431 createFrameProfileNode( document, frameElement, "BottomProfile",
00432 frame._bottomProfile );
00433 createFrameProfileNode( document, frameElement, "LeftProfile",
00434 frame._leftProfile );
00435 KDFrameCorner::createFrameCornerNode( document, frameElement, "CornerTL",
00436 frame._cornerTL );
00437 KDFrameCorner::createFrameCornerNode( document, frameElement, "CornerTR",
00438 frame._cornerTR );
00439 KDFrameCorner::createFrameCornerNode( document, frameElement, "CornerBL",
00440 frame._cornerBL );
00441 KDFrameCorner::createFrameCornerNode( document, frameElement, "CornerBR",
00442 frame._cornerBR );
00443 }
00444
00445 void KDFrame::createFrameProfileNode( QDomDocument& document, QDomNode& parent,
00446 const QString& elementName,
00447 KDFrameProfile profile )
00448 {
00449 QDomElement profileElement = document.createElement( elementName );
00450 parent.appendChild( profileElement );
00451 for( const KDFrameProfileSection* section = profile.first(); section != 0;
00452 section = profile.next() )
00453 KDFrameProfileSection::createFrameProfileSectionNode( document,
00454 profileElement,
00455 "ProfileSection",
00456 section );
00457 }
00458
00459
00460 void KDFrame::KDFrameCorner::createFrameCornerNode( QDomDocument& document,
00461 QDomNode& parent,
00462 const QString& elementName,
00463 const KDFrameCorner& corner )
00464 {
00465 QDomElement cornerElement = document.createElement( elementName );
00466 parent.appendChild( cornerElement );
00467 KDXML::createStringNode( document, cornerElement, "Style",
00468 KDFrame::cornerStyleToString( corner._style ) );
00469 KDXML::createIntNode( document, cornerElement, "Width",
00470 corner._width );
00471 createFrameProfileNode( document, cornerElement, "Profile",
00472 corner._profile );
00473 }
00474
00475 bool KDFrame::readFrameNode( const QDomElement& element, KDFrame& frame )
00476 {
00477 bool ok = true;
00478 int tempShadowWidth;
00479 CornerName tempCornerName=CornerTopLeft;
00480 QBrush tempBackground;
00481 QPixmap tempBackPixmap;
00482 BackPixmapMode tempBackPixmapMode=PixStretched;
00483 QRect tempInnerRect;
00484 KDFrameProfile tempTopProfile, tempRightProfile,
00485 tempBottomProfile, tempLeftProfile;
00486 KDFrameCorner tempCornerTL, tempCornerTR, tempCornerBL, tempCornerBR;
00487 QDomNode node = element.firstChild();
00488 while( !node.isNull() ) {
00489 QDomElement element = node.toElement();
00490 if( !element.isNull() ) {
00491 QString tagName = element.tagName();
00492 if( tagName == "ShadowWidth" ) {
00493 ok = ok & KDXML::readIntNode( element, tempShadowWidth );
00494 } else if( tagName == "CornerName" ) {
00495 QString value;
00496 ok = ok & KDXML::readStringNode( element, value );
00497 tempCornerName = stringToCornerName( value );
00498 } else if( tagName == "Background" ) {
00499 ok = ok & KDXML::readBrushNode( element, tempBackground );
00500 } else if( tagName == "BackPixmap" ) {
00501 ok = ok & KDXML::readPixmapNode( element, tempBackPixmap );
00502 } else if( tagName == "BackPixmapMode" ) {
00503 QString value;
00504 ok = ok & KDXML::readStringNode( element, value );
00505 tempBackPixmapMode = stringToBackPixmapMode( value );
00506 } else if( tagName == "InnerRect" ) {
00507 ok = ok & KDXML::readRectNode( element, tempInnerRect );
00508 } else if( tagName == "TopProfile" ) {
00509 ok = ok & readFrameProfileNode( element, tempTopProfile );
00510 } else if( tagName == "RightProfile" ) {
00511 ok = ok & readFrameProfileNode( element, tempRightProfile );
00512 } else if( tagName == "BottomProfile" ) {
00513 ok = ok & readFrameProfileNode( element, tempBottomProfile );
00514 } else if( tagName == "LeftProfile" ) {
00515 ok = ok & readFrameProfileNode( element, tempLeftProfile );
00516 } else if( tagName == "CornerTL" ) {
00517 ok = ok & KDFrameCorner::readFrameCornerNode( element,
00518 tempCornerTL );
00519 } else if( tagName == "CornerTR" ) {
00520 ok = ok & KDFrameCorner::readFrameCornerNode( element,
00521 tempCornerTR );
00522 } else if( tagName == "CornerBL" ) {
00523 ok = ok & KDFrameCorner::readFrameCornerNode( element,
00524 tempCornerBL );
00525 } else if( tagName == "CornerBR" ) {
00526 ok = ok & KDFrameCorner::readFrameCornerNode( element,
00527 tempCornerBR );
00528 } else {
00529 qDebug( "Unknown tag in frame" );
00530 }
00531 }
00532 node = node.nextSibling();
00533 }
00534
00535 if( ok ) {
00536 frame._shadowWidth = tempShadowWidth;
00537 frame._sunPos = tempCornerName;
00538 frame._background = tempBackground;
00539 frame._backPixmap = tempBackPixmap;
00540 frame._backPixmapMode = tempBackPixmapMode;
00541 frame._innerRect = tempInnerRect;
00542 frame._topProfile = tempTopProfile;
00543 frame._rightProfile = tempRightProfile;
00544 frame._bottomProfile = tempBottomProfile;
00545 frame._leftProfile = tempLeftProfile;
00546 frame._cornerTL = tempCornerTL;
00547 frame._cornerTR = tempCornerTR;
00548 frame._cornerBL = tempCornerBL;
00549 frame._cornerBR = tempCornerBR;
00550 }
00551
00552 return ok;
00553 }
00554
00555
00556 bool KDFrame::readFrameProfileNode( const QDomElement& element,
00557 KDFrameProfile& profile )
00558 {
00559 QDomNode node = element.firstChild();
00560 while( !node.isNull() ) {
00561 QDomElement element = node.toElement();
00562 if( !element.isNull() ) {
00563 QString tagName = element.tagName();
00564 if( tagName == "ProfileSection" ) {
00565 KDFrameProfileSection* section = new KDFrameProfileSection();
00566 KDFrameProfileSection::readFrameProfileSectionNode( element,
00567 section );
00568 profile.append( section );
00569 } else {
00570 qDebug( "Unknown tag in double map" );
00571 return false;
00572 }
00573 }
00574 node = node.nextSibling();
00575 }
00576
00577 return true;
00578 }
00579
00580
00581 bool KDFrame::KDFrameCorner::readFrameCornerNode( const QDomElement& element,
00582 KDFrameCorner& corner )
00583 {
00584 bool ok = true;
00585 CornerStyle tempStyle=CornerNormal;
00586 int tempWidth;
00587 KDFrameProfile tempProfile;
00588 QDomNode node = element.firstChild();
00589 while( !node.isNull() ) {
00590 QDomElement element = node.toElement();
00591 if( !element.isNull() ) {
00592 QString tagName = element.tagName();
00593 if( tagName == "Style" ) {
00594 QString value;
00595 ok = ok & KDXML::readStringNode( element, value );
00596 tempStyle = stringToCornerStyle( value );
00597 } else if( tagName == "Width" ) {
00598 ok = ok & KDXML::readIntNode( element, tempWidth );
00599 } else if( tagName == "Profile" ) {
00600 KDFrameProfile profile;
00601 ok = ok & readFrameProfileNode( element, profile );
00602 } else {
00603 qDebug( "Unknown tag in frame" );
00604 }
00605 }
00606 node = node.nextSibling();
00607 }
00608
00609 if( ok ) {
00610 corner._style = tempStyle;
00611 corner._width = tempWidth;
00612 corner._profile = tempProfile;
00613 }
00614
00615 return ok;
00616 }
00617
00618 #include "KDFrame.moc"