/****************************************************************************** * QSkinny - Copyright (C) 2016 Uwe Rathmann * This file may be used under the terms of the QSkinny License, Version 1.0 *****************************************************************************/ #include "QskSubWindowSkinlet.h" #include "QskSubWindow.h" #include "QskAspect.h" #include "QskFrameNode.h" #include "QskSkin.h" #include #include #include QskSubWindowSkinlet::QskSubWindowSkinlet( QskSkin* skin ): Inherited( skin ) { appendNodeRoles( { PanelRole, TitleBarRole } ); } QskSubWindowSkinlet::~QskSubWindowSkinlet() = default; QRectF QskSubWindowSkinlet::subControlRect( const QskSkinnable* skinnable, QskAspect::Subcontrol subControl ) const { const auto subWindow = static_cast< const QskSubWindow* >( skinnable ); if ( subControl == QskSubWindow::TitleBar ) { return titleBarRect( subWindow ); } if ( subControl == QskSubWindow::Panel ) { const qreal off = subControlRect( skinnable, QskSubWindow::TitleBar ).height(); QRectF r = subWindow->contentsRect(); r.setTop( r.top() + off ); return r; } return Inherited::subControlRect( skinnable, subControl ); } QSGNode* QskSubWindowSkinlet::updateSubNode( const QskSkinnable* skinnable, quint8 nodeRole, QSGNode* node ) const { const auto subWindow = static_cast< const QskSubWindow* >( skinnable ); switch( nodeRole ) { case PanelRole: return updatePanelNode( subWindow, node ); case TitleBarRole: return updateTitleBarNode( subWindow, node ); default: return Inherited::updateSubNode( skinnable, nodeRole, node ); } } QSGNode* QskSubWindowSkinlet::updatePanelNode( const QskSubWindow* subWindow, QSGNode* node ) const { using namespace QskAspect; auto panelNode = static_cast< QskFrameNode* >( node ); if ( panelNode == nullptr ) panelNode = new QskFrameNode; const qreal radiusX = subWindow->metric( QskSubWindow::Panel | RadiusX ); const qreal radiusY = subWindow->metric( QskSubWindow::Panel | RadiusY ); panelNode->setRect( subWindow->contentsRect() ); panelNode->setBorderWidth( subWindow->metric( QskSubWindow::Panel | Border ) ); Q_UNUSED( radiusY ); // TODO panelNode->setRadius( radiusX ); panelNode->setShadeFactor( 1.0 ); panelNode->setColors( subWindow->color( QskSubWindow::Panel | Border | RightEdge ), subWindow->color( QskSubWindow::Panel ), subWindow->color( QskSubWindow::Panel | Border | LeftEdge ) ); panelNode->update(); return panelNode; } QSGNode* QskSubWindowSkinlet::updateTitleBarNode( const QskSubWindow* subWindow, QSGNode* node ) const { const QRectF rect = subControlRect( subWindow, QskSubWindow::TitleBar ); if ( rect.isEmpty() ) return nullptr; // should be done by updateBorderGeometry !! #if 1 auto barNode = static_cast< QSGSimpleRectNode* >( node ); if ( barNode == nullptr ) barNode = new QSGSimpleRectNode(); QskAspect::Aspect aspect = QskSubWindow::TitleBar; if ( subWindow->isActive() ) aspect = aspect | QskControl::Focused; barNode->setColor( subWindow->color( aspect ) ); barNode->setRect( rect ); #endif return barNode; } QRectF QskSubWindowSkinlet::titleBarRect( const QskSubWindow* subWindow ) const { const qreal bw = subWindow->metric( QskSubWindow::Panel | QskAspect::Border ); QRectF rect = subWindow->contentsRect().adjusted( bw, bw, -bw, -bw ); rect.setHeight( titleBarHeight( subWindow ) ); return rect; } qreal QskSubWindowSkinlet::titleBarHeight( const QskSubWindow* subWindow ) const { using namespace QskAspect; if ( !subWindow->isDecorated() ) return 0; const QFontMetricsF fm( subWindow->effectiveFont( QskSubWindow::TitleBar ) ); qreal height = fm.height() + subWindow->metric( QskSubWindow::TitleBar | Padding | TopEdge ) + subWindow->metric( QskSubWindow::TitleBar | Padding | BottomEdge ); qreal minHeight = subWindow->metric( QskSubWindow::TitleBar | MinimumHeight ); return qMax( height, minHeight); } #include "moc_QskSubWindowSkinlet.cpp"