VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/src/widgets/UIPopupPaneDetails.cpp

Last change on this file was 100064, checked in by vboxsync, 12 months ago

FE/Qt: bugref:10421. Replacing VBOX_WS_X11 with VBOX_WS_NIX.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.2 KB
Line 
1/* $Id: UIPopupPaneDetails.cpp 100064 2023-06-04 09:10:01Z vboxsync $ */
2/** @file
3 * VBox Qt GUI - UIPopupPaneDetails class implementation.
4 */
5
6/*
7 * Copyright (C) 2013-2023 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28/* Qt includes: */
29#include <QCheckBox>
30#include <QTextDocument>
31#include <QTextEdit>
32
33/* GUI includes: */
34#include "UIAnimationFramework.h"
35#include "UIPopupPane.h"
36#include "UIPopupPaneDetails.h"
37
38/* Other VBox includes: */
39#include <iprt/assert.h>
40
41UIPopupPaneDetails::UIPopupPaneDetails(QWidget *pParent, const QString &strText, bool fFocused)
42 : QWidget(pParent)
43 , m_iLayoutMargin(5)
44 , m_iLayoutSpacing(10)
45 , m_strText(strText)
46 , m_pTextEdit(0)
47 , m_iDesiredTextEditWidth(-1)
48 , m_iMaximumPaneHeight(-1)
49 , m_iMaximumTextEditHeight(0)
50 , m_iTextContentMargin(5)
51 , m_fFocused(fFocused)
52 , m_pAnimation(0)
53{
54 /* Prepare: */
55 prepare();
56}
57
58void UIPopupPaneDetails::setText(const QString &strText)
59{
60 /* Make sure the text has changed: */
61 if (m_strText == strText)
62 return;
63
64 /* Fetch new text: */
65 m_strText = strText;
66 m_pTextEdit->setText(m_strText);
67
68 /* Update size-hint/visibility: */
69 updateSizeHint();
70 updateVisibility();
71}
72
73QSize UIPopupPaneDetails::minimumSizeHint() const
74{
75 /* Check if desired-width set: */
76 if (m_iDesiredTextEditWidth >= 0)
77 /* Dependent size-hint: */
78 return m_minimumSizeHint;
79 /* Golden-rule size-hint by default: */
80 return QWidget::minimumSizeHint();
81}
82
83void UIPopupPaneDetails::setMinimumSizeHint(const QSize &minimumSizeHint)
84{
85 /* Make sure the size-hint has changed: */
86 if (m_minimumSizeHint == minimumSizeHint)
87 return;
88
89 /* Fetch new size-hint: */
90 m_minimumSizeHint = minimumSizeHint;
91
92 /* Notify parent popup-pane: */
93 emit sigSizeHintChanged();
94}
95
96void UIPopupPaneDetails::layoutContent()
97{
98 /* Variables: */
99 const int iWidth = width();
100 const int iHeight = height();
101 const int iTextEditWidth = m_textEditSizeHint.width();
102 const int iTextEditHeight = m_textEditSizeHint.height();
103
104 /* TextEdit: */
105 m_pTextEdit->move(m_iLayoutMargin, m_iLayoutMargin);
106 m_pTextEdit->resize(qMin(iWidth, iTextEditWidth), qMin(iHeight, iTextEditHeight));
107 /* Text-document: */
108 QTextDocument *pTextDocument = m_pTextEdit->document();
109 if (pTextDocument)
110 {
111 pTextDocument->adjustSize();
112 pTextDocument->setTextWidth(m_pTextEdit->width() - m_iTextContentMargin);
113 }
114}
115
116void UIPopupPaneDetails::sltHandleProposalForWidth(int iWidth)
117{
118 /* Make sure the desired-width has changed: */
119 if (m_iDesiredTextEditWidth == iWidth)
120 return;
121
122 /* Fetch new desired-width: */
123 m_iDesiredTextEditWidth = iWidth;
124
125 /* Update size-hint: */
126 updateSizeHint();
127}
128
129void UIPopupPaneDetails::sltHandleProposalForHeight(int iHeight)
130{
131 /* Make sure the desired-height has changed: */
132 if (m_iMaximumPaneHeight == iHeight)
133 return;
134
135 /* Fetch new desired-height: */
136 m_iMaximumPaneHeight = iHeight;
137 m_iMaximumTextEditHeight = m_iMaximumPaneHeight - 2 * m_iLayoutMargin;
138
139 /* Update size-hint: */
140 updateSizeHint();
141}
142
143void UIPopupPaneDetails::sltFocusEnter()
144{
145 /* Ignore if already focused: */
146 if (m_fFocused)
147 return;
148
149 /* Update focus state: */
150 m_fFocused = true;
151
152 /* Update visibility: */
153 updateVisibility();
154
155 /* Notify listeners: */
156 emit sigFocusEnter();
157}
158
159void UIPopupPaneDetails::sltFocusLeave()
160{
161 /* Ignore if already unfocused: */
162 if (!m_fFocused)
163 return;
164
165 /* Update focus state: */
166 m_fFocused = false;
167
168 /* Update visibility: */
169 updateVisibility();
170
171 /* Notify listeners: */
172 emit sigFocusLeave();
173}
174
175void UIPopupPaneDetails::prepare()
176{
177 /* Prepare content: */
178 prepareContent();
179 /* Prepare animation: */
180 prepareAnimation();
181
182 /* Update size-hint/visibility: */
183 updateSizeHint();
184 updateVisibility();
185}
186
187void UIPopupPaneDetails::prepareContent()
188{
189 /* Create text-editor: */
190 m_pTextEdit = new QTextEdit(this);
191 if (m_pTextEdit)
192 {
193 /* Configure text-editor: */
194 m_pTextEdit->setFont(tuneFont(m_pTextEdit->font()));
195 m_pTextEdit->setText(m_strText);
196 m_pTextEdit->setFocusProxy(this);
197 }
198}
199
200void UIPopupPaneDetails::prepareAnimation()
201{
202 UIPopupPane *pPopupPane = qobject_cast<UIPopupPane*>(parent());
203 AssertReturnVoid(pPopupPane);
204 {
205 /* Propagate parent signals: */
206 connect(pPopupPane, &UIPopupPane::sigFocusEnter, this, &UIPopupPaneDetails::sltFocusEnter);
207 connect(pPopupPane, &UIPopupPane::sigFocusLeave, this, &UIPopupPaneDetails::sltFocusLeave);
208 }
209 /* Install geometry animation for 'minimumSizeHint' property: */
210 m_pAnimation = UIAnimation::installPropertyAnimation(this, "minimumSizeHint", "collapsedSizeHint", "expandedSizeHint",
211 SIGNAL(sigFocusEnter()), SIGNAL(sigFocusLeave()), m_fFocused);
212}
213
214void UIPopupPaneDetails::updateSizeHint()
215{
216 /* Recalculate collapsed size-hint: */
217 {
218 /* Collapsed size-hint with 0 height: */
219 m_collapsedSizeHint = QSize(m_iDesiredTextEditWidth, 0);
220 }
221
222 /* Recalculate expanded size-hint: */
223 {
224 int iNewHeight = m_iMaximumPaneHeight;
225 QTextDocument *pTextDocument = m_pTextEdit->document();
226 if (pTextDocument)
227 {
228 /* Adjust text-edit size: */
229 pTextDocument->adjustSize();
230 /* Get corresponding QTextDocument size: */
231 QSize textSize = pTextDocument->size().toSize();
232 /* Make sure the text edits height is no larger than that of container widget: */
233 iNewHeight = qMin(m_iMaximumTextEditHeight, textSize.height() + 2 * m_iLayoutMargin);
234 }
235 /* Recalculate label size-hint: */
236 m_textEditSizeHint = QSize(m_iDesiredTextEditWidth, iNewHeight);
237 /* Expanded size-hint contains full-size label: */
238 m_expandedSizeHint = m_textEditSizeHint;
239 }
240
241 /* Update current size-hint: */
242 m_minimumSizeHint = m_fFocused ? m_expandedSizeHint : m_collapsedSizeHint;
243
244 /* Update animation: */
245 if (m_pAnimation)
246 m_pAnimation->update();
247
248 /* Notify parent popup-pane: */
249 emit sigSizeHintChanged();
250}
251
252void UIPopupPaneDetails::updateVisibility()
253{
254 if (m_fFocused && !m_strText.isEmpty())
255 show();
256 else
257 hide();
258}
259
260/* static */
261QFont UIPopupPaneDetails::tuneFont(QFont font)
262{
263#if defined(VBOX_WS_MAC)
264 font.setPointSize(font.pointSize() - 2);
265#elif defined(VBOX_WS_NIX)
266 font.setPointSize(font.pointSize() - 1);
267#endif
268 return font;
269}
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use