mirror of
https://github.com/crystalidea/qt6windows7.git
synced 2025-07-02 15:26:00 +08:00
6.5.3 clean
This commit is contained in:
@ -0,0 +1,54 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
project(mainwindow LANGUAGES CXX)
|
||||
|
||||
if(NOT DEFINED INSTALL_EXAMPLESDIR)
|
||||
set(INSTALL_EXAMPLESDIR "examples")
|
||||
endif()
|
||||
|
||||
set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/widgets/mainwindows/mainwindow")
|
||||
|
||||
find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets)
|
||||
|
||||
qt_standard_project_setup()
|
||||
|
||||
qt_add_executable(mainwindow
|
||||
colorswatch.cpp colorswatch.h
|
||||
main.cpp
|
||||
mainwindow.cpp mainwindow.h
|
||||
toolbar.cpp toolbar.h
|
||||
)
|
||||
|
||||
set_target_properties(mainwindow PROPERTIES
|
||||
WIN32_EXECUTABLE TRUE
|
||||
MACOSX_BUNDLE TRUE
|
||||
)
|
||||
|
||||
target_link_libraries(mainwindow PRIVATE
|
||||
Qt6::Core
|
||||
Qt6::Gui
|
||||
Qt6::Widgets
|
||||
)
|
||||
|
||||
# Resources:
|
||||
set(mainwindow_resource_files
|
||||
"qt.png"
|
||||
"titlebarCenter.png"
|
||||
"titlebarLeft.png"
|
||||
"titlebarRight.png"
|
||||
)
|
||||
|
||||
qt_add_resources(mainwindow "mainwindow"
|
||||
PREFIX
|
||||
"/res"
|
||||
FILES
|
||||
${mainwindow_resource_files}
|
||||
)
|
||||
|
||||
install(TARGETS mainwindow
|
||||
RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
|
||||
BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
|
||||
LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
|
||||
)
|
@ -0,0 +1,685 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#include "colorswatch.h"
|
||||
|
||||
#include <QActionGroup>
|
||||
#include <QtEvents>
|
||||
#include <QFrame>
|
||||
#include <QMainWindow>
|
||||
#include <QMenu>
|
||||
#include <QPainter>
|
||||
#include <QImage>
|
||||
#include <QColor>
|
||||
#include <QDialog>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QGridLayout>
|
||||
#include <QSignalBlocker>
|
||||
#include <QSpinBox>
|
||||
#include <QLabel>
|
||||
#include <QPainterPath>
|
||||
#include <QPushButton>
|
||||
#include <QHBoxLayout>
|
||||
#include <QBitmap>
|
||||
#include <QtDebug>
|
||||
|
||||
#undef DEBUG_SIZEHINTS
|
||||
|
||||
QColor bgColorForName(const QString &name)
|
||||
{
|
||||
if (name == "Black")
|
||||
return QColor("#D8D8D8");
|
||||
if (name == "White")
|
||||
return QColor("#F1F1F1");
|
||||
if (name == "Red")
|
||||
return QColor("#F1D8D8");
|
||||
if (name == "Green")
|
||||
return QColor("#D8E4D8");
|
||||
if (name == "Blue")
|
||||
return QColor("#D8D8F1");
|
||||
if (name == "Yellow")
|
||||
return QColor("#F1F0D8");
|
||||
return QColor(name).lighter(110);
|
||||
}
|
||||
|
||||
QColor fgColorForName(const QString &name)
|
||||
{
|
||||
if (name == "Black")
|
||||
return QColor("#6C6C6C");
|
||||
if (name == "White")
|
||||
return QColor("#F8F8F8");
|
||||
if (name == "Red")
|
||||
return QColor("#F86C6C");
|
||||
if (name == "Green")
|
||||
return QColor("#6CB26C");
|
||||
if (name == "Blue")
|
||||
return QColor("#6C6CF8");
|
||||
if (name == "Yellow")
|
||||
return QColor("#F8F76C");
|
||||
return QColor(name);
|
||||
}
|
||||
|
||||
class ColorDock : public QFrame
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ColorDock(const QString &c, QWidget *parent);
|
||||
|
||||
QSize sizeHint() const override { return szHint; }
|
||||
QSize minimumSizeHint() const override { return minSzHint; }
|
||||
|
||||
void setCustomSizeHint(const QSize &size);
|
||||
|
||||
public slots:
|
||||
void changeSizeHints();
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *) override;
|
||||
|
||||
private:
|
||||
const QString color;
|
||||
QSize szHint;
|
||||
QSize minSzHint;
|
||||
};
|
||||
|
||||
ColorDock::ColorDock(const QString &c, QWidget *parent)
|
||||
: QFrame(parent)
|
||||
, color(c)
|
||||
, szHint(-1, -1)
|
||||
, minSzHint(125, 75)
|
||||
{
|
||||
QFont font = this->font();
|
||||
font.setPointSize(8);
|
||||
setFont(font);
|
||||
}
|
||||
|
||||
void ColorDock::paintEvent(QPaintEvent *)
|
||||
{
|
||||
QPainter p(this);
|
||||
p.setRenderHint(QPainter::Antialiasing);
|
||||
p.fillRect(rect(), bgColorForName(color));
|
||||
|
||||
p.save();
|
||||
|
||||
extern void render_qt_text(QPainter *, int, int, const QColor &);
|
||||
render_qt_text(&p, width(), height(), fgColorForName(color));
|
||||
|
||||
p.restore();
|
||||
|
||||
#ifdef DEBUG_SIZEHINTS
|
||||
p.setRenderHint(QPainter::Antialiasing, false);
|
||||
|
||||
QSize sz = size();
|
||||
QSize szHint = sizeHint();
|
||||
QSize minSzHint = minimumSizeHint();
|
||||
QSize maxSz = maximumSize();
|
||||
QString text = QString::fromLatin1("sz: %1x%2\nszHint: %3x%4\nminSzHint: %5x%6\n"
|
||||
"maxSz: %8x%9")
|
||||
.arg(sz.width()).arg(sz.height())
|
||||
.arg(szHint.width()).arg(szHint.height())
|
||||
.arg(minSzHint.width()).arg(minSzHint.height())
|
||||
.arg(maxSz.width()).arg(maxSz.height());
|
||||
|
||||
QRect r = fontMetrics().boundingRect(rect(), Qt::AlignLeft|Qt::AlignTop, text);
|
||||
r.adjust(-2, -2, 1, 1);
|
||||
p.translate(4, 4);
|
||||
QColor bg = Qt::yellow;
|
||||
bg.setAlpha(120);
|
||||
p.setBrush(bg);
|
||||
p.setPen(Qt::black);
|
||||
p.drawRect(r);
|
||||
p.drawText(rect(), Qt::AlignLeft|Qt::AlignTop, text);
|
||||
#endif // DEBUG_SIZEHINTS
|
||||
}
|
||||
|
||||
static QSpinBox *createSpinBox(int value, QWidget *parent, int max = 1000)
|
||||
{
|
||||
QSpinBox *result = new QSpinBox(parent);
|
||||
result->setMinimum(-1);
|
||||
result->setMaximum(max);
|
||||
result->setValue(value);
|
||||
return result;
|
||||
}
|
||||
|
||||
void ColorDock::changeSizeHints()
|
||||
{
|
||||
QDialog dialog(this);
|
||||
dialog.setWindowFlags(dialog.windowFlags() & ~Qt::WindowContextHelpButtonHint);
|
||||
dialog.setWindowTitle(color);
|
||||
|
||||
QVBoxLayout *topLayout = new QVBoxLayout(&dialog);
|
||||
|
||||
QGridLayout *inputLayout = new QGridLayout();
|
||||
topLayout->addLayout(inputLayout);
|
||||
|
||||
inputLayout->addWidget(new QLabel(tr("Size Hint:"), &dialog), 0, 0);
|
||||
inputLayout->addWidget(new QLabel(tr("Min Size Hint:"), &dialog), 1, 0);
|
||||
inputLayout->addWidget(new QLabel(tr("Max Size:"), &dialog), 2, 0);
|
||||
inputLayout->addWidget(new QLabel(tr("Dock Widget Max Size:"), &dialog), 3, 0);
|
||||
|
||||
QSpinBox *szHintW = createSpinBox(szHint.width(), &dialog);
|
||||
inputLayout->addWidget(szHintW, 0, 1);
|
||||
QSpinBox *szHintH = createSpinBox(szHint.height(), &dialog);
|
||||
inputLayout->addWidget(szHintH, 0, 2);
|
||||
|
||||
QSpinBox *minSzHintW = createSpinBox(minSzHint.width(), &dialog);
|
||||
inputLayout->addWidget(minSzHintW, 1, 1);
|
||||
QSpinBox *minSzHintH = createSpinBox(minSzHint.height(), &dialog);
|
||||
inputLayout->addWidget(minSzHintH, 1, 2);
|
||||
|
||||
QSize maxSz = maximumSize();
|
||||
QSpinBox *maxSzW = createSpinBox(maxSz.width(), &dialog, QWIDGETSIZE_MAX);
|
||||
inputLayout->addWidget(maxSzW, 2, 1);
|
||||
QSpinBox *maxSzH = createSpinBox(maxSz.height(), &dialog, QWIDGETSIZE_MAX);
|
||||
inputLayout->addWidget(maxSzH, 2, 2);
|
||||
|
||||
QSize dwMaxSz = parentWidget()->maximumSize();
|
||||
QSpinBox *dwMaxSzW = createSpinBox(dwMaxSz.width(), &dialog, QWIDGETSIZE_MAX);
|
||||
inputLayout->addWidget(dwMaxSzW, 3, 1);
|
||||
QSpinBox *dwMaxSzH = createSpinBox(dwMaxSz.height(), &dialog, QWIDGETSIZE_MAX);
|
||||
inputLayout->addWidget(dwMaxSzH, 3, 2);
|
||||
|
||||
inputLayout->setColumnStretch(1, 1);
|
||||
inputLayout->setColumnStretch(2, 1);
|
||||
|
||||
topLayout->addStretch();
|
||||
|
||||
QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this);
|
||||
connect(buttonBox, &QDialogButtonBox::rejected, &dialog, &QDialog::reject);
|
||||
connect(buttonBox, &QDialogButtonBox::accepted, &dialog, &QDialog::accept);
|
||||
|
||||
topLayout->addWidget(buttonBox);
|
||||
|
||||
if (dialog.exec() != QDialog::Accepted)
|
||||
return;
|
||||
|
||||
szHint = QSize(szHintW->value(), szHintH->value());
|
||||
minSzHint = QSize(minSzHintW->value(), minSzHintH->value());
|
||||
maxSz = QSize(maxSzW->value(), maxSzH->value());
|
||||
setMaximumSize(maxSz);
|
||||
dwMaxSz = QSize(dwMaxSzW->value(), dwMaxSzH->value());
|
||||
parentWidget()->setMaximumSize(dwMaxSz);
|
||||
updateGeometry();
|
||||
update();
|
||||
}
|
||||
|
||||
void ColorDock::setCustomSizeHint(const QSize &size)
|
||||
{
|
||||
if (szHint != size) {
|
||||
szHint = size;
|
||||
updateGeometry();
|
||||
}
|
||||
}
|
||||
|
||||
ColorSwatch::ColorSwatch(const QString &colorName, QMainWindow *parent, Qt::WindowFlags flags)
|
||||
: QDockWidget(parent, flags), mainWindow(parent)
|
||||
{
|
||||
setObjectName(colorName + QLatin1String(" Dock Widget"));
|
||||
setWindowTitle(objectName() + QLatin1String(" [*]"));
|
||||
|
||||
ColorDock *swatch = new ColorDock(colorName, this);
|
||||
swatch->setFrameStyle(QFrame::Box | QFrame::Sunken);
|
||||
|
||||
setWidget(swatch);
|
||||
|
||||
closableAction = new QAction(tr("Closable"), this);
|
||||
closableAction->setCheckable(true);
|
||||
connect(closableAction, &QAction::triggered, this, &ColorSwatch::changeClosable);
|
||||
|
||||
movableAction = new QAction(tr("Movable"), this);
|
||||
movableAction->setCheckable(true);
|
||||
connect(movableAction, &QAction::triggered, this, &ColorSwatch::changeMovable);
|
||||
|
||||
floatableAction = new QAction(tr("Floatable"), this);
|
||||
floatableAction->setCheckable(true);
|
||||
connect(floatableAction, &QAction::triggered, this, &ColorSwatch::changeFloatable);
|
||||
|
||||
verticalTitleBarAction = new QAction(tr("Vertical title bar"), this);
|
||||
verticalTitleBarAction->setCheckable(true);
|
||||
connect(verticalTitleBarAction, &QAction::triggered,
|
||||
this, &ColorSwatch::changeVerticalTitleBar);
|
||||
|
||||
floatingAction = new QAction(tr("Floating"), this);
|
||||
floatingAction->setCheckable(true);
|
||||
connect(floatingAction, &QAction::triggered, this, &ColorSwatch::changeFloating);
|
||||
|
||||
allowedAreasActions = new QActionGroup(this);
|
||||
allowedAreasActions->setExclusive(false);
|
||||
|
||||
allowLeftAction = new QAction(tr("Allow on Left"), this);
|
||||
allowLeftAction->setCheckable(true);
|
||||
connect(allowLeftAction, &QAction::triggered, this, &ColorSwatch::allowLeft);
|
||||
|
||||
allowRightAction = new QAction(tr("Allow on Right"), this);
|
||||
allowRightAction->setCheckable(true);
|
||||
connect(allowRightAction, &QAction::triggered, this, &ColorSwatch::allowRight);
|
||||
|
||||
allowTopAction = new QAction(tr("Allow on Top"), this);
|
||||
allowTopAction->setCheckable(true);
|
||||
connect(allowTopAction, &QAction::triggered, this, &ColorSwatch::allowTop);
|
||||
|
||||
allowBottomAction = new QAction(tr("Allow on Bottom"), this);
|
||||
allowBottomAction->setCheckable(true);
|
||||
connect(allowBottomAction, &QAction::triggered, this, &ColorSwatch::allowBottom);
|
||||
|
||||
allowedAreasActions->addAction(allowLeftAction);
|
||||
allowedAreasActions->addAction(allowRightAction);
|
||||
allowedAreasActions->addAction(allowTopAction);
|
||||
allowedAreasActions->addAction(allowBottomAction);
|
||||
|
||||
areaActions = new QActionGroup(this);
|
||||
areaActions->setExclusive(true);
|
||||
|
||||
leftAction = new QAction(tr("Place on Left") , this);
|
||||
leftAction->setCheckable(true);
|
||||
connect(leftAction, &QAction::triggered, this, &ColorSwatch::placeLeft);
|
||||
|
||||
rightAction = new QAction(tr("Place on Right") , this);
|
||||
rightAction->setCheckable(true);
|
||||
connect(rightAction, &QAction::triggered, this, &ColorSwatch::placeRight);
|
||||
|
||||
topAction = new QAction(tr("Place on Top") , this);
|
||||
topAction->setCheckable(true);
|
||||
connect(topAction, &QAction::triggered, this, &ColorSwatch::placeTop);
|
||||
|
||||
bottomAction = new QAction(tr("Place on Bottom") , this);
|
||||
bottomAction->setCheckable(true);
|
||||
connect(bottomAction, &QAction::triggered, this, &ColorSwatch::placeBottom);
|
||||
|
||||
areaActions->addAction(leftAction);
|
||||
areaActions->addAction(rightAction);
|
||||
areaActions->addAction(topAction);
|
||||
areaActions->addAction(bottomAction);
|
||||
|
||||
connect(movableAction, &QAction::triggered, areaActions, &QActionGroup::setEnabled);
|
||||
|
||||
connect(movableAction, &QAction::triggered, allowedAreasActions, &QActionGroup::setEnabled);
|
||||
|
||||
connect(floatableAction, &QAction::triggered, floatingAction, &QAction::setEnabled);
|
||||
|
||||
connect(floatingAction, &QAction::triggered, floatableAction, &QAction::setDisabled);
|
||||
connect(movableAction, &QAction::triggered, floatableAction, &QAction::setEnabled);
|
||||
|
||||
tabMenu = new QMenu(this);
|
||||
tabMenu->setTitle(tr("Tab into"));
|
||||
connect(tabMenu, &QMenu::triggered, this, &ColorSwatch::tabInto);
|
||||
|
||||
splitHMenu = new QMenu(this);
|
||||
splitHMenu->setTitle(tr("Split horizontally into"));
|
||||
connect(splitHMenu, &QMenu::triggered, this, &ColorSwatch::splitInto);
|
||||
|
||||
splitVMenu = new QMenu(this);
|
||||
splitVMenu->setTitle(tr("Split vertically into"));
|
||||
connect(splitVMenu, &QMenu::triggered, this, &ColorSwatch::splitInto);
|
||||
|
||||
QAction *windowModifiedAction = new QAction(tr("Modified"), this);
|
||||
windowModifiedAction->setCheckable(true);
|
||||
windowModifiedAction->setChecked(false);
|
||||
connect(windowModifiedAction, &QAction::toggled, this, &QWidget::setWindowModified);
|
||||
|
||||
menu = new QMenu(colorName, this);
|
||||
menu->addAction(toggleViewAction());
|
||||
menu->addAction(tr("Raise"), this, &QWidget::raise);
|
||||
menu->addAction(tr("Change Size Hints..."), swatch, &ColorDock::changeSizeHints);
|
||||
|
||||
menu->addSeparator();
|
||||
menu->addAction(closableAction);
|
||||
menu->addAction(movableAction);
|
||||
menu->addAction(floatableAction);
|
||||
menu->addAction(floatingAction);
|
||||
menu->addAction(verticalTitleBarAction);
|
||||
menu->addSeparator();
|
||||
menu->addActions(allowedAreasActions->actions());
|
||||
menu->addSeparator();
|
||||
menu->addActions(areaActions->actions());
|
||||
menu->addSeparator();
|
||||
menu->addMenu(splitHMenu);
|
||||
menu->addMenu(splitVMenu);
|
||||
menu->addMenu(tabMenu);
|
||||
menu->addSeparator();
|
||||
menu->addAction(windowModifiedAction);
|
||||
|
||||
connect(menu, &QMenu::aboutToShow, this, &ColorSwatch::updateContextMenu);
|
||||
|
||||
if (colorName == QLatin1String("Black")) {
|
||||
leftAction->setShortcut(Qt::CTRL | Qt::Key_W);
|
||||
rightAction->setShortcut(Qt::CTRL | Qt::Key_E);
|
||||
toggleViewAction()->setShortcut(Qt::CTRL | Qt::Key_R);
|
||||
}
|
||||
}
|
||||
|
||||
void ColorSwatch::updateContextMenu()
|
||||
{
|
||||
const Qt::DockWidgetArea area = mainWindow->dockWidgetArea(this);
|
||||
const Qt::DockWidgetAreas areas = allowedAreas();
|
||||
|
||||
closableAction->setChecked(features() & QDockWidget::DockWidgetClosable);
|
||||
if (windowType() == Qt::Drawer) {
|
||||
floatableAction->setEnabled(false);
|
||||
floatingAction->setEnabled(false);
|
||||
movableAction->setEnabled(false);
|
||||
verticalTitleBarAction->setChecked(false);
|
||||
} else {
|
||||
floatableAction->setChecked(features() & QDockWidget::DockWidgetFloatable);
|
||||
floatingAction->setChecked(isWindow());
|
||||
// done after floating, to get 'floatable' correctly initialized
|
||||
movableAction->setChecked(features() & QDockWidget::DockWidgetMovable);
|
||||
verticalTitleBarAction
|
||||
->setChecked(features() & QDockWidget::DockWidgetVerticalTitleBar);
|
||||
}
|
||||
|
||||
allowLeftAction->setChecked(isAreaAllowed(Qt::LeftDockWidgetArea));
|
||||
allowRightAction->setChecked(isAreaAllowed(Qt::RightDockWidgetArea));
|
||||
allowTopAction->setChecked(isAreaAllowed(Qt::TopDockWidgetArea));
|
||||
allowBottomAction->setChecked(isAreaAllowed(Qt::BottomDockWidgetArea));
|
||||
|
||||
if (allowedAreasActions->isEnabled()) {
|
||||
allowLeftAction->setEnabled(area != Qt::LeftDockWidgetArea);
|
||||
allowRightAction->setEnabled(area != Qt::RightDockWidgetArea);
|
||||
allowTopAction->setEnabled(area != Qt::TopDockWidgetArea);
|
||||
allowBottomAction->setEnabled(area != Qt::BottomDockWidgetArea);
|
||||
}
|
||||
|
||||
{
|
||||
const QSignalBlocker blocker(leftAction);
|
||||
leftAction->setChecked(area == Qt::LeftDockWidgetArea);
|
||||
}
|
||||
{
|
||||
const QSignalBlocker blocker(rightAction);
|
||||
rightAction->setChecked(area == Qt::RightDockWidgetArea);
|
||||
}
|
||||
{
|
||||
const QSignalBlocker blocker(topAction);
|
||||
topAction->setChecked(area == Qt::TopDockWidgetArea);
|
||||
}
|
||||
{
|
||||
const QSignalBlocker blocker(bottomAction);
|
||||
bottomAction->setChecked(area == Qt::BottomDockWidgetArea);
|
||||
}
|
||||
|
||||
if (areaActions->isEnabled()) {
|
||||
leftAction->setEnabled(areas & Qt::LeftDockWidgetArea);
|
||||
rightAction->setEnabled(areas & Qt::RightDockWidgetArea);
|
||||
topAction->setEnabled(areas & Qt::TopDockWidgetArea);
|
||||
bottomAction->setEnabled(areas & Qt::BottomDockWidgetArea);
|
||||
}
|
||||
|
||||
tabMenu->clear();
|
||||
splitHMenu->clear();
|
||||
splitVMenu->clear();
|
||||
const QList<ColorSwatch *> dockList = mainWindow->findChildren<ColorSwatch*>();
|
||||
for (const ColorSwatch *dock : dockList) {
|
||||
tabMenu->addAction(dock->objectName());
|
||||
splitHMenu->addAction(dock->objectName());
|
||||
splitVMenu->addAction(dock->objectName());
|
||||
}
|
||||
}
|
||||
|
||||
static ColorSwatch *findByName(const QMainWindow *mainWindow, const QString &name)
|
||||
{
|
||||
const QList<ColorSwatch *> dockList = mainWindow->findChildren<ColorSwatch*>();
|
||||
for (ColorSwatch *dock : dockList) {
|
||||
if (name == dock->objectName())
|
||||
return dock;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void ColorSwatch::splitInto(QAction *action)
|
||||
{
|
||||
ColorSwatch *target = findByName(mainWindow, action->text());
|
||||
if (!target)
|
||||
return;
|
||||
|
||||
const Qt::Orientation o = action->parent() == splitHMenu
|
||||
? Qt::Horizontal : Qt::Vertical;
|
||||
mainWindow->splitDockWidget(target, this, o);
|
||||
}
|
||||
|
||||
void ColorSwatch::tabInto(QAction *action)
|
||||
{
|
||||
if (ColorSwatch *target = findByName(mainWindow, action->text()))
|
||||
mainWindow->tabifyDockWidget(target, this);
|
||||
}
|
||||
|
||||
#ifndef QT_NO_CONTEXTMENU
|
||||
void ColorSwatch::contextMenuEvent(QContextMenuEvent *event)
|
||||
{
|
||||
event->accept();
|
||||
menu->popup(event->globalPos());
|
||||
}
|
||||
#endif // QT_NO_CONTEXTMENU
|
||||
|
||||
void ColorSwatch::resizeEvent(QResizeEvent *e)
|
||||
{
|
||||
if (BlueTitleBar *btb = qobject_cast<BlueTitleBar*>(titleBarWidget()))
|
||||
btb->updateMask();
|
||||
|
||||
QDockWidget::resizeEvent(e);
|
||||
}
|
||||
|
||||
void ColorSwatch::allow(Qt::DockWidgetArea area, bool a)
|
||||
{
|
||||
Qt::DockWidgetAreas areas = allowedAreas();
|
||||
areas = a ? areas | area : areas & ~area;
|
||||
setAllowedAreas(areas);
|
||||
|
||||
if (areaActions->isEnabled()) {
|
||||
leftAction->setEnabled(areas & Qt::LeftDockWidgetArea);
|
||||
rightAction->setEnabled(areas & Qt::RightDockWidgetArea);
|
||||
topAction->setEnabled(areas & Qt::TopDockWidgetArea);
|
||||
bottomAction->setEnabled(areas & Qt::BottomDockWidgetArea);
|
||||
}
|
||||
}
|
||||
|
||||
void ColorSwatch::place(Qt::DockWidgetArea area, bool p)
|
||||
{
|
||||
if (!p)
|
||||
return;
|
||||
|
||||
mainWindow->addDockWidget(area, this);
|
||||
|
||||
if (allowedAreasActions->isEnabled()) {
|
||||
allowLeftAction->setEnabled(area != Qt::LeftDockWidgetArea);
|
||||
allowRightAction->setEnabled(area != Qt::RightDockWidgetArea);
|
||||
allowTopAction->setEnabled(area != Qt::TopDockWidgetArea);
|
||||
allowBottomAction->setEnabled(area != Qt::BottomDockWidgetArea);
|
||||
}
|
||||
}
|
||||
|
||||
void ColorSwatch::setCustomSizeHint(const QSize &size)
|
||||
{
|
||||
if (ColorDock *dock = qobject_cast<ColorDock*>(widget()))
|
||||
dock->setCustomSizeHint(size);
|
||||
}
|
||||
|
||||
void ColorSwatch::changeClosable(bool on)
|
||||
{ setFeatures(on ? features() | DockWidgetClosable : features() & ~DockWidgetClosable); }
|
||||
|
||||
void ColorSwatch::changeMovable(bool on)
|
||||
{ setFeatures(on ? features() | DockWidgetMovable : features() & ~DockWidgetMovable); }
|
||||
|
||||
void ColorSwatch::changeFloatable(bool on)
|
||||
{ setFeatures(on ? features() | DockWidgetFloatable : features() & ~DockWidgetFloatable); }
|
||||
|
||||
void ColorSwatch::changeFloating(bool floating)
|
||||
{ setFloating(floating); }
|
||||
|
||||
void ColorSwatch::allowLeft(bool a)
|
||||
{ allow(Qt::LeftDockWidgetArea, a); }
|
||||
|
||||
void ColorSwatch::allowRight(bool a)
|
||||
{ allow(Qt::RightDockWidgetArea, a); }
|
||||
|
||||
void ColorSwatch::allowTop(bool a)
|
||||
{ allow(Qt::TopDockWidgetArea, a); }
|
||||
|
||||
void ColorSwatch::allowBottom(bool a)
|
||||
{ allow(Qt::BottomDockWidgetArea, a); }
|
||||
|
||||
void ColorSwatch::placeLeft(bool p)
|
||||
{ place(Qt::LeftDockWidgetArea, p); }
|
||||
|
||||
void ColorSwatch::placeRight(bool p)
|
||||
{ place(Qt::RightDockWidgetArea, p); }
|
||||
|
||||
void ColorSwatch::placeTop(bool p)
|
||||
{ place(Qt::TopDockWidgetArea, p); }
|
||||
|
||||
void ColorSwatch::placeBottom(bool p)
|
||||
{ place(Qt::BottomDockWidgetArea, p); }
|
||||
|
||||
void ColorSwatch::changeVerticalTitleBar(bool on)
|
||||
{
|
||||
setFeatures(on ? features() | DockWidgetVerticalTitleBar
|
||||
: features() & ~DockWidgetVerticalTitleBar);
|
||||
}
|
||||
|
||||
QSize BlueTitleBar::minimumSizeHint() const
|
||||
{
|
||||
QDockWidget *dw = qobject_cast<QDockWidget*>(parentWidget());
|
||||
Q_ASSERT(dw);
|
||||
QSize result(leftPm.width() + rightPm.width(), centerPm.height());
|
||||
if (dw->features() & QDockWidget::DockWidgetVerticalTitleBar)
|
||||
result.transpose();
|
||||
return result;
|
||||
}
|
||||
|
||||
BlueTitleBar::BlueTitleBar(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, leftPm(QPixmap(":/res/titlebarLeft.png"))
|
||||
, centerPm(QPixmap(":/res/titlebarCenter.png"))
|
||||
, rightPm(QPixmap(":/res/titlebarRight.png"))
|
||||
{
|
||||
}
|
||||
|
||||
void BlueTitleBar::paintEvent(QPaintEvent*)
|
||||
{
|
||||
QPainter painter(this);
|
||||
QRect rect = this->rect();
|
||||
|
||||
QDockWidget *dw = qobject_cast<QDockWidget*>(parentWidget());
|
||||
Q_ASSERT(dw);
|
||||
|
||||
if (dw->features() & QDockWidget::DockWidgetVerticalTitleBar) {
|
||||
QSize s = rect.size();
|
||||
s.transpose();
|
||||
rect.setSize(s);
|
||||
|
||||
painter.translate(rect.left(), rect.top() + rect.width());
|
||||
painter.rotate(-90);
|
||||
painter.translate(-rect.left(), -rect.top());
|
||||
}
|
||||
|
||||
painter.drawPixmap(rect.topLeft(), leftPm);
|
||||
painter.drawPixmap(rect.topRight() - QPoint(rightPm.width() - 1, 0), rightPm);
|
||||
QBrush brush(centerPm);
|
||||
painter.fillRect(rect.left() + leftPm.width(), rect.top(),
|
||||
rect.width() - leftPm.width() - rightPm.width(),
|
||||
centerPm.height(), centerPm);
|
||||
}
|
||||
|
||||
void BlueTitleBar::mouseReleaseEvent(QMouseEvent *event)
|
||||
{
|
||||
QPoint pos = event->position().toPoint();
|
||||
|
||||
QRect rect = this->rect();
|
||||
|
||||
QDockWidget *dw = qobject_cast<QDockWidget*>(parentWidget());
|
||||
Q_ASSERT(dw);
|
||||
|
||||
if (dw->features() & QDockWidget::DockWidgetVerticalTitleBar) {
|
||||
QPoint p = pos;
|
||||
pos.setX(rect.left() + rect.bottom() - p.y());
|
||||
pos.setY(rect.top() + p.x() - rect.left());
|
||||
|
||||
QSize s = rect.size();
|
||||
s.transpose();
|
||||
rect.setSize(s);
|
||||
}
|
||||
|
||||
const int buttonRight = 7;
|
||||
const int buttonWidth = 20;
|
||||
int right = rect.right() - pos.x();
|
||||
int button = (right - buttonRight)/buttonWidth;
|
||||
switch (button) {
|
||||
case 0:
|
||||
event->accept();
|
||||
dw->close();
|
||||
break;
|
||||
case 1:
|
||||
event->accept();
|
||||
dw->setFloating(!dw->isFloating());
|
||||
break;
|
||||
case 2: {
|
||||
event->accept();
|
||||
QDockWidget::DockWidgetFeatures features = dw->features();
|
||||
if (features & QDockWidget::DockWidgetVerticalTitleBar)
|
||||
features &= ~QDockWidget::DockWidgetVerticalTitleBar;
|
||||
else
|
||||
features |= QDockWidget::DockWidgetVerticalTitleBar;
|
||||
dw->setFeatures(features);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
event->ignore();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void BlueTitleBar::updateMask()
|
||||
{
|
||||
QDockWidget *dw = qobject_cast<QDockWidget*>(parent());
|
||||
Q_ASSERT(dw);
|
||||
|
||||
QRect rect = dw->rect();
|
||||
QBitmap bitmap(dw->size());
|
||||
|
||||
{
|
||||
QPainter painter(&bitmap);
|
||||
|
||||
// initialize to transparent
|
||||
painter.fillRect(rect, Qt::color0);
|
||||
|
||||
QRect contents = rect;
|
||||
contents.setTopLeft(geometry().bottomLeft());
|
||||
contents.setRight(geometry().right());
|
||||
contents.setBottom(contents.bottom()-y());
|
||||
painter.fillRect(contents, Qt::color1);
|
||||
|
||||
// let's paint the titlebar
|
||||
QRect titleRect = this->geometry();
|
||||
|
||||
if (dw->features() & QDockWidget::DockWidgetVerticalTitleBar) {
|
||||
QSize s = rect.size();
|
||||
s.transpose();
|
||||
rect.setSize(s);
|
||||
|
||||
QSize s2 = size();
|
||||
s2.transpose();
|
||||
titleRect.setSize(s2);
|
||||
|
||||
painter.translate(rect.left(), rect.top() + rect.width());
|
||||
painter.rotate(-90);
|
||||
painter.translate(-rect.left(), -rect.top());
|
||||
}
|
||||
|
||||
contents.setTopLeft(titleRect.bottomLeft());
|
||||
contents.setRight(titleRect.right());
|
||||
contents.setBottom(rect.bottom()-y());
|
||||
|
||||
QRect rect = titleRect;
|
||||
|
||||
painter.drawPixmap(rect.topLeft(), leftPm.mask());
|
||||
painter.fillRect(rect.left() + leftPm.width(), rect.top(),
|
||||
rect.width() - leftPm.width() - rightPm.width(),
|
||||
centerPm.height(), Qt::color1);
|
||||
painter.drawPixmap(rect.topRight() - QPoint(rightPm.width() - 1, 0), rightPm.mask());
|
||||
|
||||
painter.fillRect(contents, Qt::color1);
|
||||
}
|
||||
|
||||
dw->setMask(bitmap);
|
||||
}
|
||||
|
||||
#include "colorswatch.moc"
|
@ -0,0 +1,102 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#ifndef COLORSWATCH_H
|
||||
#define COLORSWATCH_H
|
||||
|
||||
#include <QDockWidget>
|
||||
|
||||
QT_FORWARD_DECLARE_CLASS(QAction)
|
||||
QT_FORWARD_DECLARE_CLASS(QActionGroup)
|
||||
QT_FORWARD_DECLARE_CLASS(QMenu)
|
||||
|
||||
class ColorSwatch : public QDockWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ColorSwatch(const QString &colorName, QMainWindow *parent = nullptr, Qt::WindowFlags flags = { });
|
||||
|
||||
void setCustomSizeHint(const QSize &size);
|
||||
QMenu *colorSwatchMenu() const { return menu; }
|
||||
|
||||
protected:
|
||||
#ifndef QT_NO_CONTEXTMENU
|
||||
void contextMenuEvent(QContextMenuEvent *event) override;
|
||||
#endif // QT_NO_CONTEXTMENU
|
||||
void resizeEvent(QResizeEvent *e) override;
|
||||
|
||||
private slots:
|
||||
void changeClosable(bool on);
|
||||
void changeMovable(bool on);
|
||||
void changeFloatable(bool on);
|
||||
void changeFloating(bool on);
|
||||
void changeVerticalTitleBar(bool on);
|
||||
void updateContextMenu();
|
||||
|
||||
void allowLeft(bool a);
|
||||
void allowRight(bool a);
|
||||
void allowTop(bool a);
|
||||
void allowBottom(bool a);
|
||||
|
||||
void placeLeft(bool p);
|
||||
void placeRight(bool p);
|
||||
void placeTop(bool p);
|
||||
void placeBottom(bool p);
|
||||
|
||||
void splitInto(QAction *action);
|
||||
void tabInto(QAction *action);
|
||||
|
||||
private:
|
||||
void allow(Qt::DockWidgetArea area, bool allow);
|
||||
void place(Qt::DockWidgetArea area, bool place);
|
||||
|
||||
QAction *closableAction;
|
||||
QAction *movableAction;
|
||||
QAction *floatableAction;
|
||||
QAction *floatingAction;
|
||||
QAction *verticalTitleBarAction;
|
||||
|
||||
QActionGroup *allowedAreasActions;
|
||||
QAction *allowLeftAction;
|
||||
QAction *allowRightAction;
|
||||
QAction *allowTopAction;
|
||||
QAction *allowBottomAction;
|
||||
|
||||
QActionGroup *areaActions;
|
||||
QAction *leftAction;
|
||||
QAction *rightAction;
|
||||
QAction *topAction;
|
||||
QAction *bottomAction;
|
||||
|
||||
QMenu *tabMenu;
|
||||
QMenu *splitHMenu;
|
||||
QMenu *splitVMenu;
|
||||
QMenu *menu;
|
||||
|
||||
QMainWindow *mainWindow;
|
||||
};
|
||||
|
||||
class BlueTitleBar : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit BlueTitleBar(QWidget *parent = nullptr);
|
||||
|
||||
QSize sizeHint() const override { return minimumSizeHint(); }
|
||||
QSize minimumSizeHint() const override;
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *event) override;
|
||||
void mouseReleaseEvent(QMouseEvent *event) override;
|
||||
|
||||
public slots:
|
||||
void updateMask();
|
||||
|
||||
private:
|
||||
const QPixmap leftPm;
|
||||
const QPixmap centerPm;
|
||||
const QPixmap rightPm;
|
||||
};
|
||||
|
||||
#endif // COLORSWATCH_H
|
147
tests/manual/examples/widgets/mainwindows/mainwindow/main.cpp
Normal file
147
tests/manual/examples/widgets/mainwindows/mainwindow/main.cpp
Normal file
@ -0,0 +1,147 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#include "mainwindow.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QPainterPath>
|
||||
#include <QPainter>
|
||||
#include <QMap>
|
||||
#include <QDebug>
|
||||
|
||||
void render_qt_text(QPainter *painter, int w, int h, const QColor &color)
|
||||
{
|
||||
QPainterPath path;
|
||||
path.moveTo(-0.083695, 0.283849);
|
||||
path.cubicTo(-0.049581, 0.349613, -0.012720, 0.397969, 0.026886, 0.428917);
|
||||
path.cubicTo(0.066493, 0.459865, 0.111593, 0.477595, 0.162186, 0.482108);
|
||||
path.lineTo(0.162186, 0.500000);
|
||||
path.cubicTo(0.115929, 0.498066, 0.066565, 0.487669, 0.014094, 0.468810);
|
||||
path.cubicTo(-0.038378, 0.449952, -0.088103, 0.423839, -0.135082, 0.390474);
|
||||
path.cubicTo(-0.182061, 0.357108, -0.222608, 0.321567, -0.256722, 0.283849);
|
||||
path.cubicTo(-0.304712, 0.262250, -0.342874, 0.239362, -0.371206, 0.215184);
|
||||
path.cubicTo(-0.411969, 0.179078, -0.443625, 0.134671, -0.466175, 0.081963);
|
||||
path.cubicTo(-0.488725, 0.029255, -0.500000, -0.033043, -0.500000, -0.104932);
|
||||
path.cubicTo(-0.500000, -0.218407, -0.467042, -0.312621, -0.401127, -0.387573);
|
||||
path.cubicTo(-0.335212, -0.462524, -0.255421, -0.500000, -0.161752, -0.500000);
|
||||
path.cubicTo(-0.072998, -0.500000, 0.003903, -0.462444, 0.068951, -0.387331);
|
||||
path.cubicTo(0.133998, -0.312218, 0.166522, -0.217440, 0.166522, -0.102998);
|
||||
path.cubicTo(0.166522, -0.010155, 0.143394, 0.071325, 0.097138, 0.141441);
|
||||
path.cubicTo(0.050882, 0.211557, -0.009396, 0.259026, -0.083695, 0.283849);
|
||||
path.moveTo(-0.167823, -0.456963);
|
||||
path.cubicTo(-0.228823, -0.456963, -0.277826, -0.432624, -0.314831, -0.383946);
|
||||
path.cubicTo(-0.361665, -0.323340, -0.385082, -0.230335, -0.385082, -0.104932);
|
||||
path.cubicTo(-0.385082, 0.017569, -0.361376, 0.112025, -0.313964, 0.178433);
|
||||
path.cubicTo(-0.277248, 0.229368, -0.228534, 0.254836, -0.167823, 0.254836);
|
||||
path.cubicTo(-0.105088, 0.254836, -0.054496, 0.229368, -0.016045, 0.178433);
|
||||
path.cubicTo(0.029055, 0.117827, 0.051605, 0.028691, 0.051605, -0.088975);
|
||||
path.cubicTo(0.051605, -0.179562, 0.039318, -0.255803, 0.014744, -0.317698);
|
||||
path.cubicTo(-0.004337, -0.365409, -0.029705, -0.400548, -0.061362, -0.423114);
|
||||
path.cubicTo(-0.093018, -0.445680, -0.128505, -0.456963, -0.167823, -0.456963);
|
||||
path.moveTo(0.379011, -0.404739);
|
||||
path.lineTo(0.379011, -0.236460);
|
||||
path.lineTo(0.486123, -0.236460);
|
||||
path.lineTo(0.486123, -0.197292);
|
||||
path.lineTo(0.379011, -0.197292);
|
||||
path.lineTo(0.379011, 0.134913);
|
||||
path.cubicTo(0.379011, 0.168117, 0.383276, 0.190442, 0.391804, 0.201886);
|
||||
path.cubicTo(0.400332, 0.213330, 0.411246, 0.219052, 0.424545, 0.219052);
|
||||
path.cubicTo(0.435531, 0.219052, 0.446227, 0.215264, 0.456635, 0.207689);
|
||||
path.cubicTo(0.467042, 0.200113, 0.474993, 0.188910, 0.480486, 0.174081);
|
||||
path.lineTo(0.500000, 0.174081);
|
||||
path.cubicTo(0.488436, 0.210509, 0.471957, 0.237911, 0.450564, 0.256286);
|
||||
path.cubicTo(0.429170, 0.274662, 0.407054, 0.283849, 0.384215, 0.283849);
|
||||
path.cubicTo(0.368893, 0.283849, 0.353859, 0.279094, 0.339115, 0.269584);
|
||||
path.cubicTo(0.324371, 0.260074, 0.313530, 0.246534, 0.306592, 0.228965);
|
||||
path.cubicTo(0.299653, 0.211396, 0.296184, 0.184075, 0.296184, 0.147002);
|
||||
path.lineTo(0.296184, -0.197292);
|
||||
path.lineTo(0.223330, -0.197292);
|
||||
path.lineTo(0.223330, -0.215667);
|
||||
path.cubicTo(0.241833, -0.224049, 0.260697, -0.237992, 0.279922, -0.257495);
|
||||
path.cubicTo(0.299147, -0.276999, 0.316276, -0.300129, 0.331310, -0.326886);
|
||||
path.cubicTo(0.338826, -0.341070, 0.349523, -0.367021, 0.363400, -0.404739);
|
||||
path.lineTo(0.379011, -0.404739);
|
||||
path.moveTo(-0.535993, 0.275629);
|
||||
|
||||
painter->translate(w / 2, h / 2);
|
||||
double scale = qMin(w, h) * 8 / 10.0;
|
||||
painter->scale(scale, scale);
|
||||
|
||||
painter->setRenderHint(QPainter::Antialiasing);
|
||||
|
||||
painter->save();
|
||||
painter->translate(.1, .1);
|
||||
painter->fillPath(path, QColor(0, 0, 0, 63));
|
||||
painter->restore();
|
||||
|
||||
painter->setBrush(color);
|
||||
painter->setPen(QPen(Qt::black, 0.02, Qt::SolidLine, Qt::FlatCap, Qt::RoundJoin));
|
||||
painter->drawPath(path);
|
||||
}
|
||||
|
||||
static void usage()
|
||||
{
|
||||
qWarning() << "Usage: mainwindow [-SizeHint<color> <width>x<height>] ...";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
enum ParseCommandLineArgumentsResult {
|
||||
CommandLineArgumentsOk,
|
||||
CommandLineArgumentsError,
|
||||
HelpRequested
|
||||
};
|
||||
|
||||
static ParseCommandLineArgumentsResult
|
||||
parseCustomSizeHints(const QStringList &arguments, MainWindow::CustomSizeHintMap *result)
|
||||
{
|
||||
result->clear();
|
||||
const auto argumentCount = arguments.size();
|
||||
for (int i = 1; i < argumentCount; ++i) {
|
||||
const QString &arg = arguments.at(i);
|
||||
if (arg.startsWith(QLatin1String("-SizeHint"))) {
|
||||
const QString name = arg.mid(9);
|
||||
if (name.isEmpty())
|
||||
return CommandLineArgumentsError;
|
||||
if (++i == argumentCount)
|
||||
return CommandLineArgumentsError;
|
||||
const QStringView sizeStr{ arguments.at(i) };
|
||||
const auto idx = sizeStr.indexOf(QLatin1Char('x'));
|
||||
if (idx == -1)
|
||||
return CommandLineArgumentsError;
|
||||
bool ok;
|
||||
const int w = sizeStr.left(idx).toInt(&ok);
|
||||
if (!ok)
|
||||
return CommandLineArgumentsError;
|
||||
const int h = sizeStr.mid(idx + 1).toInt(&ok);
|
||||
if (!ok)
|
||||
return CommandLineArgumentsError;
|
||||
result->insert(name, QSize(w, h));
|
||||
} else if (arg == QLatin1String("-h") || arg == QLatin1String("--help")) {
|
||||
return HelpRequested;
|
||||
} else {
|
||||
return CommandLineArgumentsError;
|
||||
}
|
||||
}
|
||||
|
||||
return CommandLineArgumentsOk;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
QApplication app(argc, argv);
|
||||
MainWindow::CustomSizeHintMap customSizeHints;
|
||||
switch (parseCustomSizeHints(QCoreApplication::arguments(), &customSizeHints)) {
|
||||
case CommandLineArgumentsOk:
|
||||
break;
|
||||
case CommandLineArgumentsError:
|
||||
usage();
|
||||
return -1;
|
||||
case HelpRequested:
|
||||
usage();
|
||||
return 0;
|
||||
}
|
||||
MainWindow mainWin(customSizeHints);
|
||||
mainWin.resize(800, 600);
|
||||
mainWin.show();
|
||||
return app.exec();
|
||||
}
|
@ -0,0 +1,444 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#include "mainwindow.h"
|
||||
#include "colorswatch.h"
|
||||
#include "toolbar.h"
|
||||
|
||||
#include <QActionGroup>
|
||||
#include <QLayout>
|
||||
#include <QMenu>
|
||||
#include <QMenuBar>
|
||||
#include <QStatusBar>
|
||||
#include <QTextEdit>
|
||||
#include <QFile>
|
||||
#include <QDataStream>
|
||||
#include <QFileDialog>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QMessageBox>
|
||||
#include <QApplication>
|
||||
#include <QPainter>
|
||||
#include <QMouseEvent>
|
||||
#include <QLineEdit>
|
||||
#include <QComboBox>
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
#include <QTextEdit>
|
||||
#include <QDebug>
|
||||
|
||||
static const char message[] =
|
||||
"<p><b>Qt Main Window Example</b></p>"
|
||||
|
||||
"<p>This is a demonstration of the QMainWindow, QToolBar and "
|
||||
"QDockWidget classes.</p>"
|
||||
|
||||
"<p>The tool bar and dock widgets can be dragged around and rearranged "
|
||||
"using the mouse or via the menu.</p>"
|
||||
|
||||
"<p>Each dock widget contains a colored frame and a context "
|
||||
"(right-click) menu.</p>"
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
"<p>On OS X, the \"Black\" dock widget has been created as a "
|
||||
"<em>Drawer</em>, which is a special kind of QDockWidget.</p>"
|
||||
#endif
|
||||
;
|
||||
|
||||
Q_DECLARE_METATYPE(QDockWidget::DockWidgetFeatures)
|
||||
|
||||
MainWindow::MainWindow(const CustomSizeHintMap &customSizeHints,
|
||||
QWidget *parent, Qt::WindowFlags flags)
|
||||
: QMainWindow(parent, flags)
|
||||
{
|
||||
Q_UNUSED(message);
|
||||
setObjectName("MainWindow");
|
||||
setWindowTitle("Qt Main Window Example");
|
||||
|
||||
QTextEdit *center = new QTextEdit(this);
|
||||
center->setReadOnly(true);
|
||||
center->setMinimumSize(400, 205);
|
||||
setCentralWidget(center);
|
||||
|
||||
setupToolBar();
|
||||
setupMenuBar();
|
||||
setupDockWidgets(customSizeHints);
|
||||
|
||||
statusBar()->showMessage(tr("Status Bar"));
|
||||
}
|
||||
|
||||
void MainWindow::actionTriggered(QAction *action)
|
||||
{
|
||||
qDebug("action '%s' triggered", action->text().toLocal8Bit().data());
|
||||
}
|
||||
|
||||
void MainWindow::setupToolBar()
|
||||
{
|
||||
#ifdef Q_OS_MACOS
|
||||
setUnifiedTitleAndToolBarOnMac(true);
|
||||
#endif
|
||||
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
ToolBar *tb = new ToolBar(QString::fromLatin1("Tool Bar %1").arg(i + 1), this);
|
||||
toolBars.append(tb);
|
||||
addToolBar(tb);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::setupMenuBar()
|
||||
{
|
||||
QMenu *menu = menuBar()->addMenu(tr("&File"));
|
||||
|
||||
menu->addAction(tr("Save layout..."), this, &MainWindow::saveLayout);
|
||||
menu->addAction(tr("Load layout..."), this, &MainWindow::loadLayout);
|
||||
menu->addAction(tr("Switch layout direction"),this, &MainWindow::switchLayoutDirection);
|
||||
|
||||
menu->addSeparator();
|
||||
menu->addAction(tr("&Quit"), qApp, &QCoreApplication::quit);
|
||||
|
||||
mainWindowMenu = menuBar()->addMenu(tr("Main window"));
|
||||
|
||||
QAction *action = mainWindowMenu->addAction(tr("Animated docks"));
|
||||
action->setCheckable(true);
|
||||
action->setChecked(dockOptions() & AnimatedDocks);
|
||||
connect(action, &QAction::toggled, this, &MainWindow::setDockOptions);
|
||||
|
||||
action = mainWindowMenu->addAction(tr("Allow nested docks"));
|
||||
action->setCheckable(true);
|
||||
action->setChecked(dockOptions() & AllowNestedDocks);
|
||||
connect(action, &QAction::toggled, this, &MainWindow::setDockOptions);
|
||||
|
||||
action = mainWindowMenu->addAction(tr("Allow tabbed docks"));
|
||||
action->setCheckable(true);
|
||||
action->setChecked(dockOptions() & AllowTabbedDocks);
|
||||
connect(action, &QAction::toggled, this, &MainWindow::setDockOptions);
|
||||
|
||||
action = mainWindowMenu->addAction(tr("Force tabbed docks"));
|
||||
action->setCheckable(true);
|
||||
action->setChecked(dockOptions() & ForceTabbedDocks);
|
||||
connect(action, &QAction::toggled, this, &MainWindow::setDockOptions);
|
||||
|
||||
action = mainWindowMenu->addAction(tr("Vertical tabs"));
|
||||
action->setCheckable(true);
|
||||
action->setChecked(dockOptions() & VerticalTabs);
|
||||
connect(action, &QAction::toggled, this, &MainWindow::setDockOptions);
|
||||
|
||||
action = mainWindowMenu->addAction(tr("Grouped dragging"));
|
||||
action->setCheckable(true);
|
||||
action->setChecked(dockOptions() & GroupedDragging);
|
||||
connect(action, &QAction::toggled, this, &MainWindow::setDockOptions);
|
||||
|
||||
QMenu *toolBarMenu = menuBar()->addMenu(tr("Tool bars"));
|
||||
for (int i = 0; i < toolBars.count(); ++i)
|
||||
toolBarMenu->addMenu(toolBars.at(i)->toolbarMenu());
|
||||
|
||||
#ifdef Q_OS_MACOS
|
||||
toolBarMenu->addSeparator();
|
||||
|
||||
action = toolBarMenu->addAction(tr("Unified"));
|
||||
action->setCheckable(true);
|
||||
action->setChecked(unifiedTitleAndToolBarOnMac());
|
||||
connect(action, &QAction::toggled, this, &QMainWindow::setUnifiedTitleAndToolBarOnMac);
|
||||
#endif
|
||||
|
||||
dockWidgetMenu = menuBar()->addMenu(tr("&Dock Widgets"));
|
||||
|
||||
QMenu *aboutMenu = menuBar()->addMenu(tr("About"));
|
||||
QAction *aboutAct = aboutMenu->addAction(tr("&About"), this, &MainWindow::about);
|
||||
aboutAct->setStatusTip(tr("Show the application's About box"));
|
||||
|
||||
QAction *aboutQtAct = aboutMenu->addAction(tr("About &Qt"), qApp, &QApplication::aboutQt);
|
||||
aboutQtAct->setStatusTip(tr("Show the Qt library's About box"));
|
||||
}
|
||||
|
||||
void MainWindow::setDockOptions()
|
||||
{
|
||||
DockOptions opts;
|
||||
QList<QAction*> actions = mainWindowMenu->actions();
|
||||
|
||||
if (actions.at(0)->isChecked())
|
||||
opts |= AnimatedDocks;
|
||||
if (actions.at(1)->isChecked())
|
||||
opts |= AllowNestedDocks;
|
||||
if (actions.at(2)->isChecked())
|
||||
opts |= AllowTabbedDocks;
|
||||
if (actions.at(3)->isChecked())
|
||||
opts |= ForceTabbedDocks;
|
||||
if (actions.at(4)->isChecked())
|
||||
opts |= VerticalTabs;
|
||||
if (actions.at(5)->isChecked())
|
||||
opts |= GroupedDragging;
|
||||
|
||||
QMainWindow::setDockOptions(opts);
|
||||
}
|
||||
|
||||
void MainWindow::saveLayout()
|
||||
{
|
||||
QString fileName
|
||||
= QFileDialog::getSaveFileName(this, tr("Save layout"));
|
||||
if (fileName.isEmpty())
|
||||
return;
|
||||
QFile file(fileName);
|
||||
if (!file.open(QFile::WriteOnly)) {
|
||||
QString msg = tr("Failed to open %1\n%2")
|
||||
.arg(QDir::toNativeSeparators(fileName), file.errorString());
|
||||
QMessageBox::warning(this, tr("Error"), msg);
|
||||
return;
|
||||
}
|
||||
|
||||
QByteArray geo_data = saveGeometry();
|
||||
QByteArray layout_data = saveState();
|
||||
|
||||
bool ok = file.putChar((uchar)geo_data.size());
|
||||
if (ok)
|
||||
ok = file.write(geo_data) == geo_data.size();
|
||||
if (ok)
|
||||
ok = file.write(layout_data) == layout_data.size();
|
||||
|
||||
if (!ok) {
|
||||
QString msg = tr("Error writing to %1\n%2")
|
||||
.arg(QDir::toNativeSeparators(fileName), file.errorString());
|
||||
QMessageBox::warning(this, tr("Error"), msg);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::loadLayout()
|
||||
{
|
||||
QString fileName
|
||||
= QFileDialog::getOpenFileName(this, tr("Load layout"));
|
||||
if (fileName.isEmpty())
|
||||
return;
|
||||
QFile file(fileName);
|
||||
if (!file.open(QFile::ReadOnly)) {
|
||||
QString msg = tr("Failed to open %1\n%2")
|
||||
.arg(QDir::toNativeSeparators(fileName), file.errorString());
|
||||
QMessageBox::warning(this, tr("Error"), msg);
|
||||
return;
|
||||
}
|
||||
|
||||
uchar geo_size;
|
||||
QByteArray geo_data;
|
||||
QByteArray layout_data;
|
||||
|
||||
bool ok = file.getChar((char*)&geo_size);
|
||||
if (ok) {
|
||||
geo_data = file.read(geo_size);
|
||||
ok = geo_data.size() == geo_size;
|
||||
}
|
||||
if (ok) {
|
||||
layout_data = file.readAll();
|
||||
ok = layout_data.size() > 0;
|
||||
}
|
||||
|
||||
if (ok)
|
||||
ok = restoreGeometry(geo_data);
|
||||
if (ok)
|
||||
ok = restoreState(layout_data);
|
||||
|
||||
if (!ok) {
|
||||
QString msg = tr("Error reading %1").arg(QDir::toNativeSeparators(fileName));
|
||||
QMessageBox::warning(this, tr("Error"), msg);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static QAction *addCornerAction(const QString &text, QMainWindow *mw, QMenu *menu, QActionGroup *group,
|
||||
Qt::Corner c, Qt::DockWidgetArea a)
|
||||
{
|
||||
QAction *result = menu->addAction(text, mw, [=]() { mw->setCorner(c, a); });
|
||||
result->setCheckable(true);
|
||||
group->addAction(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
void MainWindow::setupDockWidgets(const CustomSizeHintMap &customSizeHints)
|
||||
{
|
||||
qRegisterMetaType<QDockWidget::DockWidgetFeatures>();
|
||||
|
||||
QMenu *cornerMenu = dockWidgetMenu->addMenu(tr("Top left corner"));
|
||||
QActionGroup *group = new QActionGroup(this);
|
||||
group->setExclusive(true);
|
||||
QAction *cornerAction = addCornerAction(tr("Top dock area"), this, cornerMenu, group, Qt::TopLeftCorner, Qt::TopDockWidgetArea);
|
||||
cornerAction->setChecked(true);
|
||||
addCornerAction(tr("Left dock area"), this, cornerMenu, group, Qt::TopLeftCorner, Qt::LeftDockWidgetArea);
|
||||
|
||||
cornerMenu = dockWidgetMenu->addMenu(tr("Top right corner"));
|
||||
group = new QActionGroup(this);
|
||||
group->setExclusive(true);
|
||||
cornerAction = addCornerAction(tr("Top dock area"), this, cornerMenu, group, Qt::TopRightCorner, Qt::TopDockWidgetArea);
|
||||
cornerAction->setChecked(true);
|
||||
addCornerAction(tr("Right dock area"), this, cornerMenu, group, Qt::TopRightCorner, Qt::RightDockWidgetArea);
|
||||
|
||||
cornerMenu = dockWidgetMenu->addMenu(tr("Bottom left corner"));
|
||||
group = new QActionGroup(this);
|
||||
group->setExclusive(true);
|
||||
cornerAction = addCornerAction(tr("Bottom dock area"), this, cornerMenu, group, Qt::BottomLeftCorner, Qt::BottomDockWidgetArea);
|
||||
cornerAction->setChecked(true);
|
||||
addCornerAction(tr("Left dock area"), this, cornerMenu, group, Qt::BottomLeftCorner, Qt::LeftDockWidgetArea);
|
||||
|
||||
cornerMenu = dockWidgetMenu->addMenu(tr("Bottom right corner"));
|
||||
group = new QActionGroup(this);
|
||||
group->setExclusive(true);
|
||||
cornerAction = addCornerAction(tr("Bottom dock area"), this, cornerMenu, group, Qt::BottomRightCorner, Qt::BottomDockWidgetArea);
|
||||
cornerAction->setChecked(true);
|
||||
addCornerAction(tr("Right dock area"), this, cornerMenu, group, Qt::BottomRightCorner, Qt::RightDockWidgetArea);
|
||||
|
||||
dockWidgetMenu->addSeparator();
|
||||
|
||||
static const struct Set {
|
||||
const char * name;
|
||||
uint flags;
|
||||
Qt::DockWidgetArea area;
|
||||
} sets [] = {
|
||||
#ifndef Q_OS_MAC
|
||||
{ "Black", 0, Qt::LeftDockWidgetArea },
|
||||
#else
|
||||
{ "Black", Qt::Drawer, Qt::LeftDockWidgetArea },
|
||||
#endif
|
||||
{ "White", 0, Qt::RightDockWidgetArea },
|
||||
{ "Red", 0, Qt::TopDockWidgetArea },
|
||||
{ "Green", 0, Qt::TopDockWidgetArea },
|
||||
{ "Blue", 0, Qt::BottomDockWidgetArea },
|
||||
{ "Yellow", 0, Qt::BottomDockWidgetArea }
|
||||
};
|
||||
const int setCount = sizeof(sets) / sizeof(Set);
|
||||
|
||||
const QIcon qtIcon(QPixmap(":/res/qt.png"));
|
||||
for (int i = 0; i < setCount; ++i) {
|
||||
ColorSwatch *swatch = new ColorSwatch(tr(sets[i].name), this, Qt::WindowFlags(sets[i].flags));
|
||||
if (i % 2)
|
||||
swatch->setWindowIcon(qtIcon);
|
||||
if (qstrcmp(sets[i].name, "Blue") == 0) {
|
||||
BlueTitleBar *titlebar = new BlueTitleBar(swatch);
|
||||
swatch->setTitleBarWidget(titlebar);
|
||||
connect(swatch, &QDockWidget::topLevelChanged, titlebar, &BlueTitleBar::updateMask);
|
||||
connect(swatch, &QDockWidget::featuresChanged, titlebar, &BlueTitleBar::updateMask, Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
QString name = QString::fromLatin1(sets[i].name);
|
||||
if (customSizeHints.contains(name))
|
||||
swatch->setCustomSizeHint(customSizeHints.value(name));
|
||||
|
||||
addDockWidget(sets[i].area, swatch);
|
||||
dockWidgetMenu->addMenu(swatch->colorSwatchMenu());
|
||||
}
|
||||
|
||||
destroyDockWidgetMenu = new QMenu(tr("Destroy dock widget"), this);
|
||||
destroyDockWidgetMenu->setEnabled(false);
|
||||
connect(destroyDockWidgetMenu, &QMenu::triggered, this, &MainWindow::destroyDockWidget);
|
||||
|
||||
dockWidgetMenu->addSeparator();
|
||||
dockWidgetMenu->addAction(tr("Add dock widget..."), this, &MainWindow::createDockWidget);
|
||||
dockWidgetMenu->addMenu(destroyDockWidgetMenu);
|
||||
}
|
||||
|
||||
void MainWindow::switchLayoutDirection()
|
||||
{
|
||||
if (layoutDirection() == Qt::LeftToRight)
|
||||
QApplication::setLayoutDirection(Qt::RightToLeft);
|
||||
else
|
||||
QApplication::setLayoutDirection(Qt::LeftToRight);
|
||||
}
|
||||
|
||||
class CreateDockWidgetDialog : public QDialog
|
||||
{
|
||||
public:
|
||||
explicit CreateDockWidgetDialog(QWidget *parent = nullptr);
|
||||
|
||||
QString enteredObjectName() const { return m_objectName->text(); }
|
||||
Qt::DockWidgetArea location() const;
|
||||
|
||||
private:
|
||||
QLineEdit *m_objectName;
|
||||
QComboBox *m_location;
|
||||
};
|
||||
|
||||
CreateDockWidgetDialog::CreateDockWidgetDialog(QWidget *parent)
|
||||
: QDialog(parent)
|
||||
, m_objectName(new QLineEdit(this))
|
||||
, m_location(new QComboBox(this))
|
||||
{
|
||||
setWindowTitle(tr("Add Dock Widget"));
|
||||
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
|
||||
QGridLayout *layout = new QGridLayout(this);
|
||||
|
||||
layout->addWidget(new QLabel(tr("Object name:")), 0, 0);
|
||||
layout->addWidget(m_objectName, 0, 1);
|
||||
|
||||
layout->addWidget(new QLabel(tr("Location:")), 1, 0);
|
||||
m_location->setEditable(false);
|
||||
m_location->addItem(tr("Top"));
|
||||
m_location->addItem(tr("Left"));
|
||||
m_location->addItem(tr("Right"));
|
||||
m_location->addItem(tr("Bottom"));
|
||||
m_location->addItem(tr("Restore"));
|
||||
layout->addWidget(m_location, 1, 1);
|
||||
|
||||
QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this);
|
||||
connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
|
||||
connect(buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
|
||||
layout->addWidget(buttonBox, 2, 0, 1, 2);
|
||||
}
|
||||
|
||||
Qt::DockWidgetArea CreateDockWidgetDialog::location() const
|
||||
{
|
||||
switch (m_location->currentIndex()) {
|
||||
case 0: return Qt::TopDockWidgetArea;
|
||||
case 1: return Qt::LeftDockWidgetArea;
|
||||
case 2: return Qt::RightDockWidgetArea;
|
||||
case 3: return Qt::BottomDockWidgetArea;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return Qt::NoDockWidgetArea;
|
||||
}
|
||||
|
||||
void MainWindow::createDockWidget()
|
||||
{
|
||||
CreateDockWidgetDialog dialog(this);
|
||||
if (dialog.exec() == QDialog::Rejected)
|
||||
return;
|
||||
|
||||
QDockWidget *dw = new QDockWidget;
|
||||
const QString name = dialog.enteredObjectName();
|
||||
dw->setObjectName(name);
|
||||
dw->setWindowTitle(name);
|
||||
dw->setWidget(new QTextEdit);
|
||||
|
||||
Qt::DockWidgetArea area = dialog.location();
|
||||
switch (area) {
|
||||
case Qt::LeftDockWidgetArea:
|
||||
case Qt::RightDockWidgetArea:
|
||||
case Qt::TopDockWidgetArea:
|
||||
case Qt::BottomDockWidgetArea:
|
||||
addDockWidget(area, dw);
|
||||
break;
|
||||
default:
|
||||
if (!restoreDockWidget(dw)) {
|
||||
QMessageBox::warning(this, QString(), tr("Failed to restore dock widget"));
|
||||
delete dw;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
extraDockWidgets.append(dw);
|
||||
destroyDockWidgetMenu->setEnabled(true);
|
||||
destroyDockWidgetMenu->addAction(new QAction(name, this));
|
||||
}
|
||||
|
||||
void MainWindow::destroyDockWidget(QAction *action)
|
||||
{
|
||||
auto index = destroyDockWidgetMenu->actions().indexOf(action);
|
||||
delete extraDockWidgets.takeAt(index);
|
||||
destroyDockWidgetMenu->removeAction(action);
|
||||
action->deleteLater();
|
||||
|
||||
if (destroyDockWidgetMenu->isEmpty())
|
||||
destroyDockWidgetMenu->setEnabled(false);
|
||||
}
|
||||
|
||||
void MainWindow::about()
|
||||
{
|
||||
QMessageBox::about(this, tr("About MainWindows"), message);
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#ifndef MAINWINDOW_H
|
||||
#define MAINWINDOW_H
|
||||
|
||||
#include <QMainWindow>
|
||||
#include <QMap>
|
||||
#include <QString>
|
||||
#include <QSize>
|
||||
|
||||
class ToolBar;
|
||||
QT_FORWARD_DECLARE_CLASS(QMenu)
|
||||
|
||||
class MainWindow : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
typedef QMap<QString, QSize> CustomSizeHintMap;
|
||||
|
||||
explicit MainWindow(const CustomSizeHintMap &customSizeHints,
|
||||
QWidget *parent = nullptr,
|
||||
Qt::WindowFlags flags = { });
|
||||
|
||||
public slots:
|
||||
void actionTriggered(QAction *action);
|
||||
void saveLayout();
|
||||
void loadLayout();
|
||||
void switchLayoutDirection();
|
||||
void setDockOptions();
|
||||
|
||||
void createDockWidget();
|
||||
void destroyDockWidget(QAction *action);
|
||||
|
||||
void about();
|
||||
|
||||
private:
|
||||
void setupToolBar();
|
||||
void setupMenuBar();
|
||||
void setupDockWidgets(const CustomSizeHintMap &customSizeHints);
|
||||
|
||||
QList<ToolBar*> toolBars;
|
||||
QMenu *dockWidgetMenu;
|
||||
QMenu *mainWindowMenu;
|
||||
QList<QDockWidget *> extraDockWidgets;
|
||||
QMenu *destroyDockWidgetMenu;
|
||||
};
|
||||
|
||||
#endif // MAINWINDOW_H
|
@ -0,0 +1,18 @@
|
||||
TEMPLATE = app
|
||||
QT += widgets
|
||||
requires(qtConfig(combobox))
|
||||
|
||||
HEADERS += colorswatch.h mainwindow.h toolbar.h
|
||||
SOURCES += colorswatch.cpp mainwindow.cpp toolbar.cpp main.cpp
|
||||
build_all:!build_pass {
|
||||
CONFIG -= build_all
|
||||
CONFIG += release
|
||||
}
|
||||
|
||||
#! [qrc]
|
||||
RESOURCES += mainwindow.qrc
|
||||
#! [qrc]
|
||||
|
||||
# install
|
||||
target.path = $$[QT_INSTALL_EXAMPLES]/widgets/mainwindows/mainwindow
|
||||
INSTALLS += target
|
@ -0,0 +1,8 @@
|
||||
<!DOCTYPE RCC><RCC version="1.0">
|
||||
<qresource prefix="/res">
|
||||
<file>qt.png</file>
|
||||
<file>titlebarLeft.png</file>
|
||||
<file>titlebarCenter.png</file>
|
||||
<file>titlebarRight.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
BIN
tests/manual/examples/widgets/mainwindows/mainwindow/qt.png
Normal file
BIN
tests/manual/examples/widgets/mainwindows/mainwindow/qt.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.9 KiB |
Binary file not shown.
After Width: | Height: | Size: 146 B |
Binary file not shown.
After Width: | Height: | Size: 5.0 KiB |
Binary file not shown.
After Width: | Height: | Size: 2.6 KiB |
308
tests/manual/examples/widgets/mainwindows/mainwindow/toolbar.cpp
Normal file
308
tests/manual/examples/widgets/mainwindows/mainwindow/toolbar.cpp
Normal file
@ -0,0 +1,308 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#include "toolbar.h"
|
||||
|
||||
#include <QRandomGenerator>
|
||||
|
||||
#include <QActionGroup>
|
||||
#include <QMainWindow>
|
||||
#include <QMenu>
|
||||
#include <QPainter>
|
||||
#include <QPainterPath>
|
||||
#include <QSpinBox>
|
||||
#include <QLabel>
|
||||
#include <QToolTip>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
static QPixmap genIcon(const QSize &iconSize, const QString &, const QColor &color, qreal pixelRatio)
|
||||
{
|
||||
int w = qRound(iconSize.width() * pixelRatio);
|
||||
int h = qRound(iconSize.height() * pixelRatio);
|
||||
|
||||
QImage image(w, h, QImage::Format_ARGB32_Premultiplied);
|
||||
image.fill(0);
|
||||
|
||||
QPainter p(&image);
|
||||
|
||||
extern void render_qt_text(QPainter *, int, int, const QColor &);
|
||||
render_qt_text(&p, w, h, color);
|
||||
|
||||
QPixmap pm = QPixmap::fromImage(image, Qt::DiffuseDither | Qt::DiffuseAlphaDither);
|
||||
pm.setDevicePixelRatio(pixelRatio);
|
||||
return pm;
|
||||
}
|
||||
|
||||
static QPixmap genIcon(const QSize &iconSize, int number, const QColor &color, qreal pixelRatio)
|
||||
{ return genIcon(iconSize, QString::number(number), color, pixelRatio); }
|
||||
|
||||
ToolBar::ToolBar(const QString &title, QMainWindow *mainWindow)
|
||||
: QToolBar(mainWindow)
|
||||
, mainWindow(mainWindow)
|
||||
, spinbox(nullptr)
|
||||
, spinboxAction(nullptr)
|
||||
{
|
||||
setWindowTitle(title);
|
||||
setObjectName(title);
|
||||
|
||||
setIconSize(QSize(32, 32));
|
||||
|
||||
qreal dpr = devicePixelRatio();
|
||||
menu = new QMenu("One", this);
|
||||
menu->setIcon(genIcon(iconSize(), 1, Qt::black, dpr));
|
||||
menu->addAction(genIcon(iconSize(), "A", Qt::blue, dpr), "A");
|
||||
menu->addAction(genIcon(iconSize(), "B", Qt::blue, dpr), "B");
|
||||
menu->addAction(genIcon(iconSize(), "C", Qt::blue, dpr), "C");
|
||||
addAction(menu->menuAction());
|
||||
|
||||
QAction *two = addAction(genIcon(iconSize(), 2, Qt::white, dpr), "Two");
|
||||
QFont boldFont;
|
||||
boldFont.setBold(true);
|
||||
two->setFont(boldFont);
|
||||
|
||||
addAction(genIcon(iconSize(), 3, Qt::red, dpr), "Three");
|
||||
addAction(genIcon(iconSize(), 4, Qt::green, dpr), "Four");
|
||||
addAction(genIcon(iconSize(), 5, Qt::blue, dpr), "Five");
|
||||
addAction(genIcon(iconSize(), 6, Qt::yellow, dpr), "Six");
|
||||
orderAction = new QAction(this);
|
||||
orderAction->setText(tr("Order Items in Tool Bar"));
|
||||
connect(orderAction, &QAction::triggered, this, &ToolBar::order);
|
||||
|
||||
randomizeAction = new QAction(this);
|
||||
randomizeAction->setText(tr("Randomize Items in Tool Bar"));
|
||||
connect(randomizeAction, &QAction::triggered, this, &ToolBar::randomize);
|
||||
|
||||
addSpinBoxAction = new QAction(this);
|
||||
addSpinBoxAction->setText(tr("Add Spin Box"));
|
||||
connect(addSpinBoxAction, &QAction::triggered, this, &ToolBar::addSpinBox);
|
||||
|
||||
removeSpinBoxAction = new QAction(this);
|
||||
removeSpinBoxAction->setText(tr("Remove Spin Box"));
|
||||
removeSpinBoxAction->setEnabled(false);
|
||||
connect(removeSpinBoxAction, &QAction::triggered, this, &ToolBar::removeSpinBox);
|
||||
|
||||
movableAction = new QAction(tr("Movable"), this);
|
||||
movableAction->setCheckable(true);
|
||||
connect(movableAction, &QAction::triggered, this, &ToolBar::changeMovable);
|
||||
|
||||
allowedAreasActions = new QActionGroup(this);
|
||||
allowedAreasActions->setExclusive(false);
|
||||
|
||||
allowLeftAction = new QAction(tr("Allow on Left"), this);
|
||||
allowLeftAction->setCheckable(true);
|
||||
connect(allowLeftAction, &QAction::triggered, this, &ToolBar::allowLeft);
|
||||
|
||||
allowRightAction = new QAction(tr("Allow on Right"), this);
|
||||
allowRightAction->setCheckable(true);
|
||||
connect(allowRightAction, &QAction::triggered, this, &ToolBar::allowRight);
|
||||
|
||||
allowTopAction = new QAction(tr("Allow on Top"), this);
|
||||
allowTopAction->setCheckable(true);
|
||||
connect(allowTopAction, &QAction::triggered, this, &ToolBar::allowTop);
|
||||
|
||||
allowBottomAction = new QAction(tr("Allow on Bottom"), this);
|
||||
allowBottomAction->setCheckable(true);
|
||||
connect(allowBottomAction, &QAction::triggered, this, &ToolBar::allowBottom);
|
||||
|
||||
allowedAreasActions->addAction(allowLeftAction);
|
||||
allowedAreasActions->addAction(allowRightAction);
|
||||
allowedAreasActions->addAction(allowTopAction);
|
||||
allowedAreasActions->addAction(allowBottomAction);
|
||||
|
||||
areaActions = new QActionGroup(this);
|
||||
areaActions->setExclusive(true);
|
||||
|
||||
leftAction = new QAction(tr("Place on Left") , this);
|
||||
leftAction->setCheckable(true);
|
||||
connect(leftAction, &QAction::triggered, this, &ToolBar::placeLeft);
|
||||
|
||||
rightAction = new QAction(tr("Place on Right") , this);
|
||||
rightAction->setCheckable(true);
|
||||
connect(rightAction, &QAction::triggered, this, &ToolBar::placeRight);
|
||||
|
||||
topAction = new QAction(tr("Place on Top") , this);
|
||||
topAction->setCheckable(true);
|
||||
connect(topAction, &QAction::triggered, this, &ToolBar::placeTop);
|
||||
|
||||
bottomAction = new QAction(tr("Place on Bottom") , this);
|
||||
bottomAction->setCheckable(true);
|
||||
connect(bottomAction, &QAction::triggered, this, &ToolBar::placeBottom);
|
||||
|
||||
areaActions->addAction(leftAction);
|
||||
areaActions->addAction(rightAction);
|
||||
areaActions->addAction(topAction);
|
||||
areaActions->addAction(bottomAction);
|
||||
|
||||
connect(movableAction, &QAction::triggered, areaActions, &QActionGroup::setEnabled);
|
||||
|
||||
connect(movableAction, &QAction::triggered, allowedAreasActions, &QActionGroup::setEnabled);
|
||||
|
||||
menu = new QMenu(title, this);
|
||||
menu->addAction(toggleViewAction());
|
||||
menu->addSeparator();
|
||||
menu->addAction(orderAction);
|
||||
menu->addAction(randomizeAction);
|
||||
menu->addSeparator();
|
||||
menu->addAction(addSpinBoxAction);
|
||||
menu->addAction(removeSpinBoxAction);
|
||||
menu->addSeparator();
|
||||
menu->addAction(movableAction);
|
||||
menu->addSeparator();
|
||||
menu->addActions(allowedAreasActions->actions());
|
||||
menu->addSeparator();
|
||||
menu->addActions(areaActions->actions());
|
||||
menu->addSeparator();
|
||||
menu->addAction(tr("Insert break"), this, &ToolBar::insertToolBarBreak);
|
||||
|
||||
connect(menu, &QMenu::aboutToShow, this, &ToolBar::updateMenu);
|
||||
|
||||
randomize();
|
||||
}
|
||||
|
||||
void ToolBar::updateMenu()
|
||||
{
|
||||
const Qt::ToolBarArea area = mainWindow->toolBarArea(this);
|
||||
const Qt::ToolBarAreas areas = allowedAreas();
|
||||
|
||||
movableAction->setChecked(isMovable());
|
||||
|
||||
allowLeftAction->setChecked(isAreaAllowed(Qt::LeftToolBarArea));
|
||||
allowRightAction->setChecked(isAreaAllowed(Qt::RightToolBarArea));
|
||||
allowTopAction->setChecked(isAreaAllowed(Qt::TopToolBarArea));
|
||||
allowBottomAction->setChecked(isAreaAllowed(Qt::BottomToolBarArea));
|
||||
|
||||
if (allowedAreasActions->isEnabled()) {
|
||||
allowLeftAction->setEnabled(area != Qt::LeftToolBarArea);
|
||||
allowRightAction->setEnabled(area != Qt::RightToolBarArea);
|
||||
allowTopAction->setEnabled(area != Qt::TopToolBarArea);
|
||||
allowBottomAction->setEnabled(area != Qt::BottomToolBarArea);
|
||||
}
|
||||
|
||||
leftAction->setChecked(area == Qt::LeftToolBarArea);
|
||||
rightAction->setChecked(area == Qt::RightToolBarArea);
|
||||
topAction->setChecked(area == Qt::TopToolBarArea);
|
||||
bottomAction->setChecked(area == Qt::BottomToolBarArea);
|
||||
|
||||
if (areaActions->isEnabled()) {
|
||||
leftAction->setEnabled(areas & Qt::LeftToolBarArea);
|
||||
rightAction->setEnabled(areas & Qt::RightToolBarArea);
|
||||
topAction->setEnabled(areas & Qt::TopToolBarArea);
|
||||
bottomAction->setEnabled(areas & Qt::BottomToolBarArea);
|
||||
}
|
||||
}
|
||||
|
||||
void ToolBar::order()
|
||||
{
|
||||
QList<QAction *> ordered;
|
||||
QList<QAction *> actions1 = actions();
|
||||
const QList<QAction *> childActions = findChildren<QAction *>();
|
||||
for (QAction *action : childActions) {
|
||||
if (!actions1.contains(action))
|
||||
continue;
|
||||
actions1.removeAll(action);
|
||||
ordered.append(action);
|
||||
}
|
||||
|
||||
clear();
|
||||
addActions(ordered);
|
||||
|
||||
orderAction->setEnabled(false);
|
||||
}
|
||||
|
||||
void ToolBar::randomize()
|
||||
{
|
||||
QList<QAction *> randomized;
|
||||
QList<QAction *> actions = this->actions();
|
||||
while (!actions.isEmpty()) {
|
||||
QAction *action = actions.takeAt(QRandomGenerator::global()->bounded(actions.size()));
|
||||
randomized.append(action);
|
||||
}
|
||||
clear();
|
||||
addActions(randomized);
|
||||
|
||||
orderAction->setEnabled(true);
|
||||
}
|
||||
|
||||
void ToolBar::addSpinBox()
|
||||
{
|
||||
if (!spinbox)
|
||||
spinbox = new QSpinBox(this);
|
||||
if (!spinboxAction)
|
||||
spinboxAction = addWidget(spinbox);
|
||||
else
|
||||
addAction(spinboxAction);
|
||||
|
||||
addSpinBoxAction->setEnabled(false);
|
||||
removeSpinBoxAction->setEnabled(true);
|
||||
}
|
||||
|
||||
void ToolBar::removeSpinBox()
|
||||
{
|
||||
if (spinboxAction)
|
||||
removeAction(spinboxAction);
|
||||
|
||||
addSpinBoxAction->setEnabled(true);
|
||||
removeSpinBoxAction->setEnabled(false);
|
||||
}
|
||||
|
||||
void ToolBar::allow(Qt::ToolBarArea area, bool a)
|
||||
{
|
||||
Qt::ToolBarAreas areas = allowedAreas();
|
||||
areas = a ? areas | area : areas & ~area;
|
||||
setAllowedAreas(areas);
|
||||
|
||||
if (areaActions->isEnabled()) {
|
||||
leftAction->setEnabled(areas & Qt::LeftToolBarArea);
|
||||
rightAction->setEnabled(areas & Qt::RightToolBarArea);
|
||||
topAction->setEnabled(areas & Qt::TopToolBarArea);
|
||||
bottomAction->setEnabled(areas & Qt::BottomToolBarArea);
|
||||
}
|
||||
}
|
||||
|
||||
void ToolBar::place(Qt::ToolBarArea area, bool p)
|
||||
{
|
||||
if (!p)
|
||||
return;
|
||||
|
||||
mainWindow->addToolBar(area, this);
|
||||
|
||||
if (allowedAreasActions->isEnabled()) {
|
||||
allowLeftAction->setEnabled(area != Qt::LeftToolBarArea);
|
||||
allowRightAction->setEnabled(area != Qt::RightToolBarArea);
|
||||
allowTopAction->setEnabled(area != Qt::TopToolBarArea);
|
||||
allowBottomAction->setEnabled(area != Qt::BottomToolBarArea);
|
||||
}
|
||||
}
|
||||
|
||||
void ToolBar::changeMovable(bool movable)
|
||||
{ setMovable(movable); }
|
||||
|
||||
void ToolBar::allowLeft(bool a)
|
||||
{ allow(Qt::LeftToolBarArea, a); }
|
||||
|
||||
void ToolBar::allowRight(bool a)
|
||||
{ allow(Qt::RightToolBarArea, a); }
|
||||
|
||||
void ToolBar::allowTop(bool a)
|
||||
{ allow(Qt::TopToolBarArea, a); }
|
||||
|
||||
void ToolBar::allowBottom(bool a)
|
||||
{ allow(Qt::BottomToolBarArea, a); }
|
||||
|
||||
void ToolBar::placeLeft(bool p)
|
||||
{ place(Qt::LeftToolBarArea, p); }
|
||||
|
||||
void ToolBar::placeRight(bool p)
|
||||
{ place(Qt::RightToolBarArea, p); }
|
||||
|
||||
void ToolBar::placeTop(bool p)
|
||||
{ place(Qt::TopToolBarArea, p); }
|
||||
|
||||
void ToolBar::placeBottom(bool p)
|
||||
{ place(Qt::BottomToolBarArea, p); }
|
||||
|
||||
void ToolBar::insertToolBarBreak()
|
||||
{
|
||||
mainWindow->insertToolBarBreak(this);
|
||||
}
|
@ -0,0 +1,74 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#ifndef TOOLBAR_H
|
||||
#define TOOLBAR_H
|
||||
|
||||
#include <QToolBar>
|
||||
|
||||
QT_FORWARD_DECLARE_CLASS(QAction)
|
||||
QT_FORWARD_DECLARE_CLASS(QActionGroup)
|
||||
QT_FORWARD_DECLARE_CLASS(QMenu)
|
||||
QT_FORWARD_DECLARE_CLASS(QSpinBox)
|
||||
|
||||
class ToolBar : public QToolBar
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ToolBar(const QString &title, QMainWindow *mainWindow);
|
||||
|
||||
QMenu *toolbarMenu() const { return menu; }
|
||||
|
||||
private slots:
|
||||
void order();
|
||||
void randomize();
|
||||
void addSpinBox();
|
||||
void removeSpinBox();
|
||||
|
||||
void changeMovable(bool movable);
|
||||
|
||||
void allowLeft(bool a);
|
||||
void allowRight(bool a);
|
||||
void allowTop(bool a);
|
||||
void allowBottom(bool a);
|
||||
|
||||
void placeLeft(bool p);
|
||||
void placeRight(bool p);
|
||||
void placeTop(bool p);
|
||||
void placeBottom(bool p);
|
||||
|
||||
void updateMenu();
|
||||
void insertToolBarBreak();
|
||||
|
||||
private:
|
||||
void allow(Qt::ToolBarArea area, bool allow);
|
||||
void place(Qt::ToolBarArea area, bool place);
|
||||
|
||||
QMainWindow *mainWindow;
|
||||
|
||||
QSpinBox *spinbox;
|
||||
QAction *spinboxAction;
|
||||
|
||||
QMenu *menu;
|
||||
QAction *orderAction;
|
||||
QAction *randomizeAction;
|
||||
QAction *addSpinBoxAction;
|
||||
QAction *removeSpinBoxAction;
|
||||
|
||||
QAction *movableAction;
|
||||
|
||||
QActionGroup *allowedAreasActions;
|
||||
QAction *allowLeftAction;
|
||||
QAction *allowRightAction;
|
||||
QAction *allowTopAction;
|
||||
QAction *allowBottomAction;
|
||||
|
||||
QActionGroup *areaActions;
|
||||
QAction *leftAction;
|
||||
QAction *rightAction;
|
||||
QAction *topAction;
|
||||
QAction *bottomAction;
|
||||
};
|
||||
|
||||
#endif // TOOLBAR_H
|
Reference in New Issue
Block a user