PeriDyno 1.0.0
Loading...
Searching...
No Matches
PDockWidget.cpp
Go to the documentation of this file.
1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the demonstration applications of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:BSD$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** BSD License Usage
18** Alternatively, you may use this file under the terms of the BSD license
19** as follows:
20**
21** "Redistribution and use in source and binary forms, with or without
22** modification, are permitted provided that the following conditions are
23** met:
24** * Redistributions of source code must retain the above copyright
25** notice, this list of conditions and the following disclaimer.
26** * Redistributions in binary form must reproduce the above copyright
27** notice, this list of conditions and the following disclaimer in
28** the documentation and/or other materials provided with the
29** distribution.
30** * Neither the name of The Qt Company Ltd nor the names of its
31** contributors may be used to endorse or promote products derived
32** from this software without specific prior written permission.
33**
34**
35** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
36** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
37** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
38** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
39** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
41** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
42** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
43** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
44** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
45** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
46**
47** $QT_END_LICENSE$
48**
49****************************************************************************/
50
51#include "PDockWidget.h"
52
53#include <QAction>
54#include <QtEvents>
55#include <QFrame>
56#include <QMainWindow>
57#include <QMenu>
58#include <QPainter>
59#include <QImage>
60#include <QColor>
61#include <QActionGroup>
62#include <QDialog>
63#include <QDialogButtonBox>
64#include <QGridLayout>
65#include <QSignalBlocker>
66#include <QSpinBox>
67#include <QLabel>
68#include <QPainterPath>
69#include <QPushButton>
70#include <QHBoxLayout>
71#include <QBitmap>
72#include <QtDebug>
73
74#undef DEBUG_SIZEHINTS
75
76namespace dyno
77{
78 PDockWidget::PDockWidget(const QString &colorName, QMainWindow *parent, Qt::WindowFlags flags) :
79 QDockWidget(parent, flags),
80 mainWindow(parent)
81 {
82 setObjectName(colorName + QLatin1String(" Dock Widget"));
83 setWindowTitle(objectName() + QLatin1String(" [*]"));
84
85 closableAction = new QAction(tr("Closable"), this);
86 closableAction->setCheckable(true);
87 connect(closableAction, &QAction::triggered, this, &PDockWidget::changeClosable);
88
89 movableAction = new QAction(tr("Movable"), this);
90 movableAction->setCheckable(true);
91 connect(movableAction, &QAction::triggered, this, &PDockWidget::changeMovable);
92
93 floatableAction = new QAction(tr("Floatable"), this);
94 floatableAction->setCheckable(true);
95 connect(floatableAction, &QAction::triggered, this, &PDockWidget::changeFloatable);
96
97 verticalTitleBarAction = new QAction(tr("Vertical title bar"), this);
98 verticalTitleBarAction->setCheckable(true);
99 connect(verticalTitleBarAction, &QAction::triggered,
101
102 floatingAction = new QAction(tr("Floating"), this);
103 floatingAction->setCheckable(true);
104 connect(floatingAction, &QAction::triggered, this, &PDockWidget::changeFloating);
105
106 allowedAreasActions = new QActionGroup(this);
107 allowedAreasActions->setExclusive(false);
108
109 allowLeftAction = new QAction(tr("Allow on Left"), this);
110 allowLeftAction->setCheckable(true);
111 connect(allowLeftAction, &QAction::triggered, this, &PDockWidget::allowLeft);
112
113 allowRightAction = new QAction(tr("Allow on Right"), this);
114 allowRightAction->setCheckable(true);
115 connect(allowRightAction, &QAction::triggered, this, &PDockWidget::allowRight);
116
117 allowTopAction = new QAction(tr("Allow on Top"), this);
118 allowTopAction->setCheckable(true);
119 connect(allowTopAction, &QAction::triggered, this, &PDockWidget::allowTop);
120
121 allowBottomAction = new QAction(tr("Allow on Bottom"), this);
122 allowBottomAction->setCheckable(true);
123 connect(allowBottomAction, &QAction::triggered, this, &PDockWidget::allowBottom);
124
129
130 areaActions = new QActionGroup(this);
131 areaActions->setExclusive(true);
132
133 leftAction = new QAction(tr("Place on Left"), this);
134 leftAction->setCheckable(true);
135 connect(leftAction, &QAction::triggered, this, &PDockWidget::placeLeft);
136
137 rightAction = new QAction(tr("Place on Right"), this);
138 rightAction->setCheckable(true);
139 connect(rightAction, &QAction::triggered, this, &PDockWidget::placeRight);
140
141 topAction = new QAction(tr("Place on Top"), this);
142 topAction->setCheckable(true);
143 connect(topAction, &QAction::triggered, this, &PDockWidget::placeTop);
144
145 bottomAction = new QAction(tr("Place on Bottom"), this);
146 bottomAction->setCheckable(true);
147 connect(bottomAction, &QAction::triggered, this, &PDockWidget::placeBottom);
148
149 areaActions->addAction(leftAction);
150 areaActions->addAction(rightAction);
151 areaActions->addAction(topAction);
152 areaActions->addAction(bottomAction);
153
154 connect(movableAction, &QAction::triggered, areaActions, &QActionGroup::setEnabled);
155
156 connect(movableAction, &QAction::triggered, allowedAreasActions, &QActionGroup::setEnabled);
157
158 connect(floatableAction, &QAction::triggered, floatingAction, &QAction::setEnabled);
159
160 connect(floatingAction, &QAction::triggered, floatableAction, &QAction::setDisabled);
161 connect(movableAction, &QAction::triggered, floatableAction, &QAction::setEnabled);
162
163 tabMenu = new QMenu(this);
164 tabMenu->setTitle(tr("Tab into"));
165 connect(tabMenu, &QMenu::triggered, this, &PDockWidget::tabInto);
166
167 splitHMenu = new QMenu(this);
168 splitHMenu->setTitle(tr("Split horizontally into"));
169 connect(splitHMenu, &QMenu::triggered, this, &PDockWidget::splitInto);
170
171 splitVMenu = new QMenu(this);
172 splitVMenu->setTitle(tr("Split vertically into"));
173 connect(splitVMenu, &QMenu::triggered, this, &PDockWidget::splitInto);
174
175 QAction *windowModifiedAction = new QAction(tr("Modified"), this);
176 windowModifiedAction->setCheckable(true);
177 windowModifiedAction->setChecked(false);
178 connect(windowModifiedAction, &QAction::toggled, this, &QWidget::setWindowModified);
179
180 menu = new QMenu(colorName, this);
181 menu->addAction(toggleViewAction());
182 menu->addAction(tr("Raise"), this, &QWidget::raise);
183 // menu->addAction(tr("Change Size Hints..."), swatch, &ColorDock::changeSizeHints);
184
185 menu->addSeparator();
186 menu->addAction(closableAction);
187 menu->addAction(movableAction);
188 menu->addAction(floatableAction);
189 menu->addAction(floatingAction);
190 menu->addAction(verticalTitleBarAction);
191 menu->addSeparator();
192 menu->addActions(allowedAreasActions->actions());
193 menu->addSeparator();
194 menu->addActions(areaActions->actions());
195 menu->addSeparator();
196 menu->addMenu(splitHMenu);
197 menu->addMenu(splitVMenu);
198 menu->addMenu(tabMenu);
199 menu->addSeparator();
200 menu->addAction(windowModifiedAction);
201
202 connect(menu, &QMenu::aboutToShow, this, &PDockWidget::updateContextMenu);
203
204 if (colorName == QLatin1String("Black")) {
205 leftAction->setShortcut(Qt::CTRL | Qt::Key_W);
206 rightAction->setShortcut(Qt::CTRL | Qt::Key_E);
207 toggleViewAction()->setShortcut(Qt::CTRL | Qt::Key_R);
208 }
209 }
210
212 {
213 const Qt::DockWidgetArea area = mainWindow->dockWidgetArea(this);
214 const Qt::DockWidgetAreas areas = allowedAreas();
215
216 closableAction->setChecked(features() & QDockWidget::DockWidgetClosable);
217 if (windowType() == Qt::Drawer) {
218 floatableAction->setEnabled(false);
219 floatingAction->setEnabled(false);
220 movableAction->setEnabled(false);
221 verticalTitleBarAction->setChecked(false);
222 }
223 else {
224 floatableAction->setChecked(features() & QDockWidget::DockWidgetFloatable);
225 floatingAction->setChecked(isWindow());
226 // done after floating, to get 'floatable' correctly initialized
227 movableAction->setChecked(features() & QDockWidget::DockWidgetMovable);
229 ->setChecked(features() & QDockWidget::DockWidgetVerticalTitleBar);
230 }
231
232 allowLeftAction->setChecked(isAreaAllowed(Qt::LeftDockWidgetArea));
233 allowRightAction->setChecked(isAreaAllowed(Qt::RightDockWidgetArea));
234 allowTopAction->setChecked(isAreaAllowed(Qt::TopDockWidgetArea));
235 allowBottomAction->setChecked(isAreaAllowed(Qt::BottomDockWidgetArea));
236
237 if (allowedAreasActions->isEnabled()) {
238 allowLeftAction->setEnabled(area != Qt::LeftDockWidgetArea);
239 allowRightAction->setEnabled(area != Qt::RightDockWidgetArea);
240 allowTopAction->setEnabled(area != Qt::TopDockWidgetArea);
241 allowBottomAction->setEnabled(area != Qt::BottomDockWidgetArea);
242 }
243
244 {
245 const QSignalBlocker blocker(leftAction);
246 leftAction->setChecked(area == Qt::LeftDockWidgetArea);
247 }
248 {
249 const QSignalBlocker blocker(rightAction);
250 rightAction->setChecked(area == Qt::RightDockWidgetArea);
251 }
252 {
253 const QSignalBlocker blocker(topAction);
254 topAction->setChecked(area == Qt::TopDockWidgetArea);
255 }
256 {
257 const QSignalBlocker blocker(bottomAction);
258 bottomAction->setChecked(area == Qt::BottomDockWidgetArea);
259 }
260
261 if (areaActions->isEnabled()) {
262 leftAction->setEnabled(areas & Qt::LeftDockWidgetArea);
263 rightAction->setEnabled(areas & Qt::RightDockWidgetArea);
264 topAction->setEnabled(areas & Qt::TopDockWidgetArea);
265 bottomAction->setEnabled(areas & Qt::BottomDockWidgetArea);
266 }
267
268 tabMenu->clear();
269 splitHMenu->clear();
270 splitVMenu->clear();
271 QList<PDockWidget*> dock_list = mainWindow->findChildren<PDockWidget*>();
272 foreach(PDockWidget *dock, dock_list) {
273 tabMenu->addAction(dock->objectName());
274 splitHMenu->addAction(dock->objectName());
275 splitVMenu->addAction(dock->objectName());
276 }
277 }
278
279 static PDockWidget *findByName(const QMainWindow *mainWindow, const QString &name)
280 {
281 foreach(PDockWidget *dock, mainWindow->findChildren<PDockWidget*>()) {
282 if (name == dock->objectName())
283 return dock;
284 }
285 return Q_NULLPTR;
286 }
287
288 void PDockWidget::splitInto(QAction *action)
289 {
290 PDockWidget *target = findByName(mainWindow, action->text());
291 if (!target)
292 return;
293
294 const Qt::Orientation o = action->parent() == splitHMenu
295 ? Qt::Horizontal : Qt::Vertical;
296 mainWindow->splitDockWidget(target, this, o);
297 }
298
299 void PDockWidget::tabInto(QAction *action)
300 {
301 if (PDockWidget *target = findByName(mainWindow, action->text()))
302 mainWindow->tabifyDockWidget(target, this);
303 }
304
305#ifndef QT_NO_CONTEXTMENU
306 void PDockWidget::contextMenuEvent(QContextMenuEvent *event)
307 {
308 event->accept();
309 //menu->exec(event->globalPos());
310 }
311#endif // QT_NO_CONTEXTMENU
312
313 void PDockWidget::resizeEvent(QResizeEvent *e)
314 {
315 QDockWidget::resizeEvent(e);
316 }
317
318 void PDockWidget::allow(Qt::DockWidgetArea area, bool a)
319 {
320 Qt::DockWidgetAreas areas = allowedAreas();
321 areas = a ? areas | area : areas & ~area;
322 setAllowedAreas(areas);
323
324 if (areaActions->isEnabled()) {
325 leftAction->setEnabled(areas & Qt::LeftDockWidgetArea);
326 rightAction->setEnabled(areas & Qt::RightDockWidgetArea);
327 topAction->setEnabled(areas & Qt::TopDockWidgetArea);
328 bottomAction->setEnabled(areas & Qt::BottomDockWidgetArea);
329 }
330 }
331
332 void PDockWidget::place(Qt::DockWidgetArea area, bool p)
333 {
334 if (!p)
335 return;
336
337 mainWindow->addDockWidget(area, this);
338
339 if (allowedAreasActions->isEnabled()) {
340 allowLeftAction->setEnabled(area != Qt::LeftDockWidgetArea);
341 allowRightAction->setEnabled(area != Qt::RightDockWidgetArea);
342 allowTopAction->setEnabled(area != Qt::TopDockWidgetArea);
343 allowBottomAction->setEnabled(area != Qt::BottomDockWidgetArea);
344 }
345 }
346
347 void PDockWidget::setCustomSizeHint(const QSize &size)
348 {
349 // if (ColorDock *dock = qobject_cast<ColorDock*>(widget()))
350 // dock->setCustomSizeHint(size);
351 }
352
354 {
355 setFeatures(on ? features() | DockWidgetClosable : features() & ~DockWidgetClosable);
356 }
357
359 {
360 setFeatures(on ? features() | DockWidgetMovable : features() & ~DockWidgetMovable);
361 }
362
364 {
365 setFeatures(on ? features() | DockWidgetFloatable : features() & ~DockWidgetFloatable);
366 }
367
368 void PDockWidget::changeFloating(bool floating)
369 {
370 setFloating(floating);
371 }
372
374 {
375 allow(Qt::LeftDockWidgetArea, a);
376 }
377
379 {
380 allow(Qt::RightDockWidgetArea, a);
381 }
382
384 {
385 allow(Qt::TopDockWidgetArea, a);
386 }
387
389 {
390 allow(Qt::BottomDockWidgetArea, a);
391 }
392
394 {
395 place(Qt::LeftDockWidgetArea, p);
396 }
397
399 {
400 place(Qt::RightDockWidgetArea, p);
401 }
402
404 {
405 place(Qt::TopDockWidgetArea, p);
406 }
407
409 {
410 place(Qt::BottomDockWidgetArea, p);
411 }
412
414 {
415 setFeatures(on ? features() | DockWidgetVerticalTitleBar
416 : features() & ~DockWidgetVerticalTitleBar);
417 }
418}
void placeRight(bool p)
QAction * allowTopAction
void placeBottom(bool p)
QAction * rightAction
void allowBottom(bool a)
void changeVerticalTitleBar(bool on)
void placeTop(bool p)
void placeLeft(bool p)
void changeFloating(bool on)
QAction * topAction
void allow(Qt::DockWidgetArea area, bool allow)
QMainWindow * mainWindow
void allowTop(bool a)
void allowRight(bool a)
QAction * floatableAction
QAction * closableAction
PDockWidget(const QString &colorName, QMainWindow *parent=Q_NULLPTR, Qt::WindowFlags flags=Qt::WindowFlags())
void changeFloatable(bool on)
QAction * allowLeftAction
QAction * bottomAction
void contextMenuEvent(QContextMenuEvent *event) override
QAction * allowBottomAction
void place(Qt::DockWidgetArea area, bool place)
void resizeEvent(QResizeEvent *e) override
QAction * movableAction
void changeMovable(bool on)
QAction * leftAction
QAction * floatingAction
void changeClosable(bool on)
QAction * verticalTitleBarAction
void tabInto(QAction *action)
QAction * allowRightAction
QActionGroup * areaActions
void splitInto(QAction *action)
void allowLeft(bool a)
void setCustomSizeHint(const QSize &size)
QActionGroup * allowedAreasActions
This is an implementation of AdditiveCCD based on peridyno.
Definition Array.h:25
static PDockWidget * findByName(const QMainWindow *mainWindow, const QString &name)