QSkinny 0.8.0
C++/Qt UI toolkit
Loading...
Searching...
No Matches
QskSubWindowSkinlet.cpp
1/******************************************************************************
2 * QSkinny - Copyright (C) The authors
3 * SPDX-License-Identifier: BSD-3-Clause
4 *****************************************************************************/
5
6#include "QskSubWindowSkinlet.h"
7#include "QskSubWindow.h"
8
9#include "QskAspect.h"
10#include "QskBoxBorderMetrics.h"
11#include "QskGraphic.h"
12#include "QskTextOptions.h"
13
14#include <qfontmetrics.h>
15
16QskSubWindowSkinlet::QskSubWindowSkinlet( QskSkin* skin )
17 : Inherited( skin )
18{
19 appendNodeRoles( { PanelRole, TitleBarRole, SymbolRole, TitleRole } );
20}
21
22QskSubWindowSkinlet::~QskSubWindowSkinlet() = default;
23
24QRectF QskSubWindowSkinlet::subControlRect( const QskSkinnable* skinnable,
25 const QRectF& contentsRect, QskAspect::Subcontrol subControl ) const
26{
27 using Q = QskSubWindow;
28
29 const auto subWindow = static_cast< const QskSubWindow* >( skinnable );
30
31 if ( subControl == Q::Panel )
32 {
33 return contentsRect;
34 }
35 else if ( subControl == Q::TitleBarPanel )
36 {
37 return titleBarRect( subWindow, contentsRect );
38 }
39 else if ( subControl == Q::TitleBarSymbol )
40 {
41 return symbolRect( subWindow, contentsRect );
42 }
43 else if ( subControl == Q::TitleBarText )
44 {
45 return titleRect( subWindow, contentsRect );
46 }
47
48 return Inherited::subControlRect( skinnable, contentsRect, subControl );
49}
50
51QSGNode* QskSubWindowSkinlet::updateSubNode(
52 const QskSkinnable* skinnable, quint8 nodeRole, QSGNode* node ) const
53{
54 using Q = QskSubWindow;
55
56 const auto subWindow = static_cast< const QskSubWindow* >( skinnable );
57
58 switch ( nodeRole )
59 {
60 case PanelRole:
61 {
62 return updateBoxNode( subWindow, node, Q::Panel );
63 }
64 case TitleBarRole:
65 {
66 const auto decorations = subWindow->decorations();
67
68 if ( decorations & Q::TitleBar )
69 return updateBoxNode( subWindow, node, Q::TitleBarPanel );
70
71 return nullptr;
72 }
73 case SymbolRole:
74 {
75 const auto decorations = subWindow->decorations();
76
77 if ( ( decorations & Q::TitleBar ) && ( decorations & Q::Symbol ) )
78 {
79 return updateGraphicNode( subWindow, node,
80 subWindow->windowIcon(), Q::TitleBarSymbol );
81 }
82
83 return nullptr;
84 }
85 case TitleRole:
86 {
87 const auto decorations = subWindow->decorations();
88
89 if ( ( decorations & Q::TitleBar ) && ( decorations & Q::Title ) )
90 {
91 return updateTextNode( subWindow, node,
92 subWindow->windowTitle(), Q::TitleBarText );
93 }
94
95 return nullptr;
96 }
97 case OverlayRole:
98 {
99 /*
100 Overloading QskPopupSkinlet: as the opacity of the subwindow already
101 depends on the fadingFactor we do not want the additional opacity
102 adjustments for the overlay node.
103 Maybe we should have a flag that indicates if the popup does
104 opacity or geometry transitions, when fading TODO ...
105 */
106 updateBoxNode( subWindow, node, Q::Overlay );
107 break;
108 }
109 }
110
111 return Inherited::updateSubNode( skinnable, nodeRole, node );
112}
113
114QRectF QskSubWindowSkinlet::titleBarRect(
115 const QskSubWindow* subWindow, const QRectF& contentsRect ) const
116{
117 const auto border = subWindow->boxBorderMetricsHint( QskSubWindow::Panel );
118
119 QRectF r = contentsRect.marginsRemoved( border.widths() );
120 r.setHeight( titleBarHeight( subWindow ) );
121
122 return r;
123}
124
125qreal QskSubWindowSkinlet::titleBarHeight( const QskSubWindow* subWindow ) const
126{
127 using Q = QskSubWindow;
128
129 const auto decorations = subWindow->decorations();
130 if ( !( decorations & Q::TitleBar ) )
131 return 0;
132
133 auto height = subWindow->strutSizeHint( Q::TitleBarPanel ).height();
134
135 if ( decorations & Q::Title )
136 {
137 const auto padding = subWindow->paddingHint( Q::TitleBarPanel );
138 const QFontMetricsF fm( subWindow->effectiveFont( Q::TitleBarText ) );
139
140 const qreal h = fm.height() + padding.top() + padding.bottom();
141 if ( h > height )
142 height = h;
143 }
144
145 return height;
146}
147
148QRectF QskSubWindowSkinlet::symbolRect(
149 const QskSubWindow* subWindow, const QRectF& contentsRect ) const
150{
151 using Q = QskSubWindow;
152
153 if ( !subWindow->hasDecoration( Q::Symbol ) )
154 return QRectF();
155
156 auto rect = subWindow->subControlContentsRect( contentsRect, Q::TitleBarPanel );
157
158 if ( !rect.isEmpty() )
159 {
160 const auto symbol = subWindow->windowIcon();
161
162 int w = 0;
163 if ( !symbol.isNull() )
164 w = symbol.widthForHeight( rect.height() );
165
166 rect.setWidth( w );
167 }
168
169 return rect;
170}
171
172QRectF QskSubWindowSkinlet::titleRect(
173 const QskSubWindow* subWindow, const QRectF& contentsRect ) const
174{
175 using Q = QskSubWindow;
176
177 if ( !subWindow->hasDecoration( Q::Title ) )
178 return QRectF();
179
180 auto rect = subWindow->subControlContentsRect( contentsRect, Q::TitleBarPanel );
181
182 if ( !rect.isEmpty() )
183 {
184 const auto symbolRect = subControlRect( subWindow, rect, Q::TitleBarSymbol );
185 if ( !symbolRect.isEmpty() )
186 {
187 const auto spacing = subWindow->spacingHint( Q::TitleBarPanel );
188 rect.setX( symbolRect.right() + spacing );
189 }
190
191#if 0
192 const QFontMetricsF fm( subWindow->effectiveFont( Q::TitleBarText ) );
193 rect.setHeight( fm.height() ); // TitleBarText | Alignment
194#endif
195 }
196
197 return rect;
198}
199
200QSizeF QskSubWindowSkinlet::sizeHint( const QskSkinnable* skinnable,
201 Qt::SizeHint which, const QSizeF& ) const
202{
203 using Q = QskSubWindow;
204
205 if ( which != Qt::MinimumSize )
206 return QSizeF();
207
208 const auto subWindow = static_cast< const QskSubWindow* >( skinnable );
209
210 auto hint = subWindow->strutSizeHint( Q::Panel );
211
212 if ( subWindow->decorations() != Q::NoDecoration )
213 {
214 const auto size = subWindow->strutSizeHint( Q::TitleBarPanel );
215
216 hint.rwidth() = qMax( hint.width(), size.width() );
217
218 if ( size.height() >= 0 )
219 {
220 hint.rheight() = qMax( hint.height(), 0.0 );
221 hint.rheight() += size.height();
222 }
223 }
224
225 return hint;
226}
227
228#include "moc_QskSubWindowSkinlet.cpp"
Subcontrol
For use within the rendering or lay-outing of a specific QskSkinnable.
Definition QskAspect.h:104
QRectF subControlContentsRect(QskAspect::Subcontrol) const
qreal spacingHint(QskAspect, QskSkinHintStatus *=nullptr) const
Retrieves a spacing hint.
QMarginsF paddingHint(QskAspect, QskSkinHintStatus *=nullptr) const
Retrieves a padding hint.
QFont effectiveFont(QskAspect) const
QSizeF strutSizeHint(QskAspect, QskSkinHintStatus *=nullptr) const
Retrieves a strut size hint.
QskBoxBorderMetrics boxBorderMetricsHint(QskAspect, QskSkinHintStatus *=nullptr) const
Retrieves a border hint.