From ba92676987f7a806b70924a55cfc82c2ea5255ab Mon Sep 17 00:00:00 2001 From: MrStevns Date: Mon, 21 Apr 2025 16:53:08 +0200 Subject: [PATCH 1/7] FlowLayout: rewrite for maintainability sake --- core_lib/src/interface/flowlayout.cpp | 221 +++++++++++++++++++++----- core_lib/src/interface/flowlayout.h | 43 ++++- 2 files changed, 218 insertions(+), 46 deletions(-) diff --git a/core_lib/src/interface/flowlayout.cpp b/core_lib/src/interface/flowlayout.cpp index 032f065c81..135f279a55 100644 --- a/core_lib/src/interface/flowlayout.cpp +++ b/core_lib/src/interface/flowlayout.cpp @@ -47,10 +47,28 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ +/* + +Pencil2D - Traditional Animation Software +Copyright (C) 2005-2007 Patrick Corrieri & Pascal Naidon +Copyright (C) 2012-2020 Matthew Chiawen Chang + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; version 2 of the License. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +*/ #include #include #include +#include +#include #include "flowlayout.h" @@ -61,10 +79,8 @@ FlowLayout::FlowLayout(QWidget *parent, int margin, int hSpacing, int vSpacing) } FlowLayout::FlowLayout(int margin, int hSpacing, int vSpacing) - : m_hSpace(hSpacing), m_vSpace(vSpacing) -{ - setContentsMargins(margin, margin, margin, margin); -} + : FlowLayout(nullptr, margin, hSpacing, vSpacing) +{} FlowLayout::~FlowLayout() { @@ -114,26 +130,25 @@ QLayoutItem *FlowLayout::takeAt(int index) return nullptr; } -Qt::Orientations FlowLayout::expandingDirections() const +bool FlowLayout::hasHeightForWidth() const { - return {}; + return true; } -bool FlowLayout::hasHeightForWidth() const +Qt::Orientations FlowLayout::expandingDirections() const { - return true; + return {}; } int FlowLayout::heightForWidth(int width) const { - int height = doLayout(QRect(0, 0, width, 0), true); - return height; + return calculateHeightForWidth(width); } void FlowLayout::setGeometry(const QRect &rect) { QLayout::setGeometry(rect); - doLayout(rect, false); + mNumberOfRows = applyLayout(rect); } QSize FlowLayout::sizeHint() const @@ -153,65 +168,187 @@ QSize FlowLayout::minimumSize() const return size; } -int FlowLayout::doLayout(const QRect &rect, bool testOnly) const +RowLayoutInfo FlowLayout::alignJustifiedRow(int startIndex, int count, const QRect& effectiveRect, int spaceX) const +{ + + int spacing = 0; + if (count > 0) { + int gapCount = count + 1; + int rowWidth = calculateRowWidth(startIndex, count, spaceX); + int availableSpace = effectiveRect.width() - rowWidth; + + spacing = (gapCount > 0 && availableSpace > 0) + ? availableSpace / gapCount + : 0; + } + + int itemX = effectiveRect.left() + spacing; + + RowLayoutInfo row; + + row.startX = itemX; + row.startIndex = startIndex; + row.spacing = spaceX + spacing; + + for (int j = startIndex; j < startIndex + count; j += 1) { + QLayoutItem *rowItem = itemList.at(j); + const QSize& itemSize = rowItem->sizeHint(); + rowItem->setGeometry(QRect(QPoint(itemX, rowItem->geometry().y()), itemSize)); + itemX += row.spacing + itemSize.width(); + } + + return row; +} + +RowLayoutInfo FlowLayout::alignHCenterRow(int startIndex, int count, const QRect &effectiveRect, int spaceX) const +{ + int rowWidth = calculateRowWidth(startIndex, count, spaceX); + int offset = (effectiveRect.width() - rowWidth) / 2; + int rowOffsetX = effectiveRect.left() + offset; + + RowLayoutInfo row; + + row.startX = rowOffsetX; + row.startIndex = startIndex; + row.spacing = spaceX; + + for (int i = startIndex; i < startIndex + count; i += 1) { + QLayoutItem *rowItem = itemList.at(i); + + const QSize& itemSize = rowItem->sizeHint(); + rowItem->setGeometry(QRect(QPoint(rowOffsetX, rowItem->geometry().y()), itemSize)); + rowOffsetX += spaceX + itemSize.width(); + } + + return row; +} + +int FlowLayout::calculateHeightForWidth(int width) const { int left, top, right, bottom; getContentsMargins(&left, &top, &right, &bottom); - QRect effectiveRect = rect.adjusted(+left, +top, -right, -bottom); - int x = effectiveRect.x(); - int y = effectiveRect.y(); int lineHeight = 0; int rowCount = 0; + int totalRows = 0; + + int spaceX = horizontalSpacing(); + int spaceY = verticalSpacing(); + + int y = 0; - QLayoutItem *item; - int spaceX = 0; for (int i = 0; i < itemList.length(); i++) { - item = itemList.at(i); + QLayoutItem* item = itemList.at(i); QWidget *wid = item->widget(); - spaceX = horizontalSpacing(); + int rowWidth = calculateRowWidth(0, rowCount, spaceX); + if (spaceX == -1) spaceX = wid->style()->layoutSpacing( QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Horizontal); - int spaceY = verticalSpacing(); if (spaceY == -1) spaceY = wid->style()->layoutSpacing( QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Vertical); - int nextX = x + item->sizeHint().width() + spaceX; - if (nextX - spaceX > effectiveRect.right() && lineHeight > 0) { - if(!testOnly && alignment() & Qt::AlignHCenter) { - int offset = qFloor((effectiveRect.right() + spaceX - x) / 2); - for(int j = i-1; j > i-1-rowCount; j--) { - auto rowItem = itemList.at(j); - rowItem->setGeometry(rowItem->geometry().adjusted(offset, 0, offset, 0)); - } - } + if (rowWidth + item->sizeHint().width() + spaceX >= width && lineHeight > 0) { + totalRows++; - x = effectiveRect.x(); - y = y + lineHeight + spaceY; - nextX = x + item->sizeHint().width() + spaceX; + y += lineHeight + spaceY; lineHeight = 0; rowCount = 0; } + + lineHeight = qMax(lineHeight, item->sizeHint().height()); rowCount++; + } + + + return lineHeight + y + top + bottom; +} + +int FlowLayout::applyLayout(const QRect &rect) const +{ + int left, top, right, bottom; + getContentsMargins(&left, &top, &right, &bottom); + + int spaceX = horizontalSpacing(); + int spaceY = verticalSpacing(); + + QRect effectiveRect = rect.adjusted(+left, +top, -right, -bottom); + int x = effectiveRect.x(); + int y = effectiveRect.y(); + int lineHeight = 0; + + QLayoutItem *item; + + QVector rowAlignments; + + int currentRowCount = 0; + int maxRowCount = 0; + + for (int i = 0; i < itemList.length(); i += 1) { + item = itemList.at(i); + QWidget *wid = item->widget(); + + if (spaceX == -1) + spaceX = wid->style()->layoutSpacing( + QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Horizontal); + if (spaceY == -1) + spaceY = wid->style()->layoutSpacing( + QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Vertical); - if (!testOnly) { - item->setGeometry(QRect(QPoint(x, y), item->sizeHint())); + int rowWidth = calculateRowWidth(0, currentRowCount, spaceX); + + if (currentRowCount > 0) { + int startRowIndex = i - currentRowCount; + maxRowCount = qMax(currentRowCount, maxRowCount); + + if (rowWidth + item->sizeHint().width() + spaceX >= effectiveRect.width()) { + if (alignment() & Qt::AlignHCenter) { + rowAlignments.append(alignHCenterRow(startRowIndex, currentRowCount, effectiveRect, spaceX)); + } else if (alignment() & Qt::AlignJustify) { + rowAlignments.append(alignJustifiedRow(startRowIndex, currentRowCount, effectiveRect, spaceX)); + } + + y = y + lineHeight + spaceY; + lineHeight = 0; + currentRowCount = 0; + } else if (maxRowCount == itemList.length() - 1) { + rowAlignments.append(alignHCenterRow(startRowIndex, currentRowCount, effectiveRect, spaceX)); + } } - x = nextX; + item->setGeometry(QRect(QPoint(x, y), item->sizeHint())); + lineHeight = qMax(lineHeight, item->sizeHint().height()); + currentRowCount += 1; } - if (!testOnly && alignment() & Qt::AlignHCenter) { - int offset = qFloor((effectiveRect.right() + spaceX - x) / 2); - for (int j = itemList.length()-1; j > itemList.length()-1-rowCount; j--) { - auto rowItem = itemList.at(j); - rowItem->setGeometry(rowItem->geometry().adjusted(offset, 0, offset, 0)); - } + if (currentRowCount > 0) { + lastLineAlignment(itemList.length() - currentRowCount, currentRowCount, rowAlignments.last(), effectiveRect); + } + + return maxRowCount; +} + +void FlowLayout::lastLineAlignment(int startIndex, int count, RowLayoutInfo rowInfo, const QRect& effectiveRect) const +{ + if (alignment() & Qt::AlignHCenter) { + alignHCenterRow(startIndex, count, effectiveRect, rowInfo.spacing); + } else if (alignment() & Qt::AlignJustify) { + alignJustifiedRow(startIndex, count, effectiveRect, rowInfo.spacing); + } +} + +int FlowLayout::calculateRowWidth(int start, int end, int spacing) const +{ + if (itemList.isEmpty()) { return 0; } + + int totalWidth = 0; + // Calculate the total width of all item in row including spacing + for (int i = start; i < start + end; i += 1) { + totalWidth += itemList.at(i)->sizeHint().width(); } - return y + lineHeight - rect.y() + bottom; + return totalWidth + (spacing * (end - 1)); } int FlowLayout::smartSpacing(QStyle::PixelMetric pm) const diff --git a/core_lib/src/interface/flowlayout.h b/core_lib/src/interface/flowlayout.h index 9909336493..6a0677b4f7 100644 --- a/core_lib/src/interface/flowlayout.h +++ b/core_lib/src/interface/flowlayout.h @@ -47,6 +47,22 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ +/* + +Pencil2D - Traditional Animation Software +Copyright (C) 2005-2007 Patrick Corrieri & Pascal Naidon +Copyright (C) 2012-2020 Matthew Chiawen Chang + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; version 2 of the License. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +*/ #ifndef FLOWLAYOUT_H #define FLOWLAYOUT_H @@ -55,6 +71,12 @@ #include #include +struct RowLayoutInfo { + int startIndex; + int startX; + int spacing; +}; + class FlowLayout : public QLayout { public: @@ -75,13 +97,26 @@ class FlowLayout : public QLayout QSize sizeHint() const override; QLayoutItem *takeAt(int index) override; + int rows() const { return mNumberOfRows; } + +protected: + virtual void lastLineAlignment(int startIndex, int count, RowLayoutInfo rowInfo, const QRect& effectiveRect) const; + + QList itemList; + int m_hSpace = 0; + int m_vSpace = 0; + private: - int doLayout(const QRect &rect, bool testOnly) const; + RowLayoutInfo alignHCenterRow(int startIndex, int count, const QRect &effectiveRect, int spaceX) const; + RowLayoutInfo alignJustifiedRow(int startIndex, int count, const QRect& effectiveRect, int spaceX) const; + + int calculateHeightForWidth(int width) const; + int calculateRowWidth(int start, int end, int spacing) const; + + int applyLayout(const QRect &rect) const; int smartSpacing(QStyle::PixelMetric pm) const; - QList itemList; - int m_hSpace; - int m_vSpace; + int mNumberOfRows = 0; }; #endif // FLOWLAYOUT_H From fd6c3e319548588d53707a842e07c5fb68e35d10 Mon Sep 17 00:00:00 2001 From: MrStevns Date: Sun, 27 Apr 2025 10:18:04 +0200 Subject: [PATCH 2/7] Introduce customised flow layout for toolbox Because I would like to change the alignment of the items on the last line Also fixed a bunch of layout spacing inconsistencies --- app/src/toolbox.cpp | 82 +++++++++++++++--------- app/src/toolbox.h | 7 ++ core_lib/core_lib.pro | 2 + core_lib/src/interface/toolboxlayout.cpp | 28 ++++++++ core_lib/src/interface/toolboxlayout.h | 18 ++++++ 5 files changed, 105 insertions(+), 32 deletions(-) create mode 100644 core_lib/src/interface/toolboxlayout.cpp create mode 100644 core_lib/src/interface/toolboxlayout.h diff --git a/app/src/toolbox.cpp b/app/src/toolbox.cpp index 653172cff7..bedd34d116 100644 --- a/app/src/toolbox.cpp +++ b/app/src/toolbox.cpp @@ -24,6 +24,7 @@ GNU General Public License for more details. #include #include #include +#include #include "flowlayout.h" #include "spinslider.h" @@ -31,6 +32,7 @@ GNU General Public License for more details. #include "toolmanager.h" #include "layermanager.h" #include "pencilsettings.h" +#include "toolboxlayout.h" // ---------------------------------------------------------------------------------- QString GetToolTips(QString strCommandName) @@ -137,50 +139,66 @@ void ToolBoxWidget::initUI() connect(editor()->layers(), &LayerManager::currentLayerChanged, this, &ToolBoxWidget::onLayerDidChange); - connect(this, &QDockWidget::dockLocationChanged, this, [=](Qt::DockWidgetArea area) { - if (area == Qt::DockWidgetArea::TopDockWidgetArea || area == Qt::BottomDockWidgetArea) { - const int minimumHeight = ui->scrollAreaWidgetContents_2->layout()->heightForWidth(width()); - ui->scrollArea->setMinimumHeight(minimumHeight); - setMinimumHeight(minimumHeight); - } else { - ui->scrollArea->setMinimumHeight(0); // Default value - // Don't set own minimum height and let Qt come up with a sensible value - } - }); - - FlowLayout* flowlayout = new FlowLayout(3,3,3); - - flowlayout->addWidget(ui->pencilButton); - flowlayout->addWidget(ui->eraserButton); - flowlayout->addWidget(ui->selectButton); - flowlayout->addWidget(ui->moveButton); - flowlayout->addWidget(ui->penButton); - flowlayout->addWidget(ui->handButton); - flowlayout->addWidget(ui->polylineButton); - flowlayout->addWidget(ui->bucketButton); - flowlayout->addWidget(ui->eyedropperButton); - flowlayout->addWidget(ui->brushButton); - flowlayout->addWidget(ui->smudgeButton); + mFlowlayout = new ToolBoxLayout(nullptr, 3,3,3); + + mFlowlayout->addWidget(ui->pencilButton); + mFlowlayout->addWidget(ui->eraserButton); + mFlowlayout->addWidget(ui->selectButton); + mFlowlayout->addWidget(ui->moveButton); + mFlowlayout->addWidget(ui->penButton); + mFlowlayout->addWidget(ui->handButton); + mFlowlayout->addWidget(ui->polylineButton); + mFlowlayout->addWidget(ui->bucketButton); + mFlowlayout->addWidget(ui->eyedropperButton); + mFlowlayout->addWidget(ui->brushButton); + mFlowlayout->addWidget(ui->smudgeButton); delete ui->scrollAreaWidgetContents_2->layout(); - ui->scrollAreaWidgetContents_2->setLayout(flowlayout); - ui->scrollAreaWidgetContents_2->setContentsMargins(0,0,0,0); + ui->scrollAreaWidgetContents_2->setLayout(mFlowlayout); QSettings settings(PENCIL2D, PENCIL2D); restoreGeometry(settings.value("ToolBoxGeom").toByteArray()); + + // Important to set the proper minimumSize; + ui->scrollArea->setMinimumSize(minimumSizeHint()); } -void ToolBoxWidget::updateUI() +int ToolBoxWidget::getMinHeightForWidth(int width) const +{ + int layoutHeight = mFlowlayout->heightForWidth(width); + if (this->isFloating()) { + return layoutHeight; + } else { + return layoutHeight + BaseDockWidget::minimumSizeHint().height(); + } +} + +QSize ToolBoxWidget::minimumSizeHint() const +{ + return QSize(mFlowlayout->minimumSize().width(), getMinHeightForWidth(width())); +} + +void ToolBoxWidget::resizeEvent(QResizeEvent *event) { + BaseDockWidget::resizeEvent(event); + + updateLayoutAlignment(); } -void ToolBoxWidget::resizeEvent(QResizeEvent* event) +void ToolBoxWidget::updateLayoutAlignment() { - QDockWidget::resizeEvent(event); + mFlowlayout->invalidate(); + if (mFlowlayout->rows() > 1) { + mFlowlayout->setAlignment(Qt::AlignJustify); + } else { + mFlowlayout->setAlignment(Qt::AlignHCenter); + } - const int minimumHeight = ui->scrollArea->minimumHeight(); - if (minimumHeight <= 0) { return; } - setMinimumHeight(minimumHeight); + mFlowlayout->activate(); +} + +void ToolBoxWidget::updateUI() +{ } void ToolBoxWidget::onToolSetActive(ToolType toolType) diff --git a/app/src/toolbox.h b/app/src/toolbox.h index 617d9b07a1..7e9ffb4f6a 100644 --- a/app/src/toolbox.h +++ b/app/src/toolbox.h @@ -27,6 +27,7 @@ class SpinSlider; class DisplayOptionWidget; class ToolOptionWidget; class Editor; +class ToolBoxLayout; namespace Ui { class ToolBoxWidget; @@ -60,12 +61,18 @@ public slots: protected: void resizeEvent(QResizeEvent* event) override; + QSize minimumSizeHint() const override; private: + void updateLayoutAlignment(); void deselectAllTools(); void toolOn(ToolType toolType, QToolButton* toolButton); + int getMinHeightForWidth(int width) const; + Ui::ToolBoxWidget* ui = nullptr; + + ToolBoxLayout* mFlowlayout = nullptr; }; #endif diff --git a/core_lib/core_lib.pro b/core_lib/core_lib.pro index 9df20cb015..a7248881c1 100644 --- a/core_lib/core_lib.pro +++ b/core_lib/core_lib.pro @@ -44,6 +44,7 @@ HEADERS += \ src/interface/recentfilemenu.h \ src/interface/scribblearea.h \ src/interface/backgroundwidget.h \ + src/interface/toolboxlayout.h \ src/interface/undoredocommand.h \ src/managers/basemanager.h \ src/managers/overlaymanager.h \ @@ -135,6 +136,7 @@ SOURCES += src/graphics/bitmap/bitmapimage.cpp \ src/interface/recentfilemenu.cpp \ src/interface/scribblearea.cpp \ src/interface/backgroundwidget.cpp \ + src/interface/toolboxlayout.cpp \ src/interface/undoredocommand.cpp \ src/managers/basemanager.cpp \ src/managers/overlaymanager.cpp \ diff --git a/core_lib/src/interface/toolboxlayout.cpp b/core_lib/src/interface/toolboxlayout.cpp new file mode 100644 index 0000000000..85bedb1e7c --- /dev/null +++ b/core_lib/src/interface/toolboxlayout.cpp @@ -0,0 +1,28 @@ +#include "toolboxlayout.h" + +ToolBoxLayout::ToolBoxLayout(QWidget* parent, int margin, int hSpacing, int vSpacing) + : FlowLayout(parent, margin, hSpacing, vSpacing) +{ + +} + +void ToolBoxLayout::lastLineAlignment(int startIndex, int count, RowLayoutInfo rowInfo, const QRect &effectiveRect) const +{ + alignRowFromRowInfo(startIndex, count, rowInfo); +} + +void ToolBoxLayout::alignRowFromRowInfo(int startIndex, int count, RowLayoutInfo rowInfo) const +{ + int x = rowInfo.startX; + + for (int i = startIndex; i < startIndex + count; i += 1) { + + if (i > itemList.length() - 1) { + break; + } + QLayoutItem *item = itemList.at(i); + QSize size = item->geometry().size(); + item->setGeometry(QRect(QPoint(x, item->geometry().y()), size)); + x += size.width() + rowInfo.spacing; + } +} diff --git a/core_lib/src/interface/toolboxlayout.h b/core_lib/src/interface/toolboxlayout.h new file mode 100644 index 0000000000..4d06159523 --- /dev/null +++ b/core_lib/src/interface/toolboxlayout.h @@ -0,0 +1,18 @@ +#ifndef TOOLBOXLAYOUT_H +#define TOOLBOXLAYOUT_H + +#include "flowlayout.h" + +class ToolBoxLayout : public FlowLayout +{ +public: + ToolBoxLayout(QWidget* parent, int margin, int hSpacing, int vSpacing); + +protected: + void lastLineAlignment(int startIndex, int count, RowLayoutInfo rowInfo, const QRect& effectiveRect) const override; + +private: + void alignRowFromRowInfo(int startIndex, int count, RowLayoutInfo rowInfo) const; +}; + +#endif // TOOLBOXLAYOUT_H From a2810012d964016575b5a9d271e0341de7c685b7 Mon Sep 17 00:00:00 2001 From: MrStevns Date: Mon, 28 Apr 2025 17:57:23 +0200 Subject: [PATCH 3/7] Fix center alignment issue being off by one item --- core_lib/src/interface/flowlayout.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/core_lib/src/interface/flowlayout.cpp b/core_lib/src/interface/flowlayout.cpp index 135f279a55..d98a7f8d67 100644 --- a/core_lib/src/interface/flowlayout.cpp +++ b/core_lib/src/interface/flowlayout.cpp @@ -217,7 +217,7 @@ RowLayoutInfo FlowLayout::alignHCenterRow(int startIndex, int count, const QRect const QSize& itemSize = rowItem->sizeHint(); rowItem->setGeometry(QRect(QPoint(rowOffsetX, rowItem->geometry().y()), itemSize)); - rowOffsetX += spaceX + itemSize.width(); + rowOffsetX += row.spacing + itemSize.width(); } return row; @@ -295,10 +295,10 @@ int FlowLayout::applyLayout(const QRect &rect) const spaceY = wid->style()->layoutSpacing( QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Vertical); - int rowWidth = calculateRowWidth(0, currentRowCount, spaceX); + int startRowIndex = i - currentRowCount; + int rowWidth = calculateRowWidth(startRowIndex, currentRowCount, spaceX); if (currentRowCount > 0) { - int startRowIndex = i - currentRowCount; maxRowCount = qMax(currentRowCount, maxRowCount); if (rowWidth + item->sizeHint().width() + spaceX >= effectiveRect.width()) { @@ -311,8 +311,6 @@ int FlowLayout::applyLayout(const QRect &rect) const y = y + lineHeight + spaceY; lineHeight = 0; currentRowCount = 0; - } else if (maxRowCount == itemList.length() - 1) { - rowAlignments.append(alignHCenterRow(startRowIndex, currentRowCount, effectiveRect, spaceX)); } } @@ -322,7 +320,9 @@ int FlowLayout::applyLayout(const QRect &rect) const currentRowCount += 1; } - if (currentRowCount > 0) { + if (maxRowCount == itemList.length() - 1) { + alignHCenterRow(itemList.length() - currentRowCount, currentRowCount, effectiveRect, spaceX); + } else if (currentRowCount > 0) { lastLineAlignment(itemList.length() - currentRowCount, currentRowCount, rowAlignments.last(), effectiveRect); } From 95b9de690de543e2369cda7c0cd0898968def838 Mon Sep 17 00:00:00 2001 From: MrStevns Date: Mon, 28 Apr 2025 18:36:12 +0200 Subject: [PATCH 4/7] Move Toolbox into own widget for more control of sizing --- app/app.pro | 2 + app/src/actioncommands.cpp | 7 + app/src/actioncommands.h | 2 + app/src/mainwindow2.cpp | 48 ++- app/src/mainwindow2.h | 4 +- app/src/toolbox.cpp | 298 +------------ app/src/toolbox.h | 47 +-- app/src/toolboxwidget.cpp | 330 +++++++++++++++ app/src/toolboxwidget.h | 61 +++ app/ui/toolboxwidget.ui | 834 ++++++++++++++++++------------------- 10 files changed, 884 insertions(+), 749 deletions(-) create mode 100644 app/src/toolboxwidget.cpp create mode 100644 app/src/toolboxwidget.h diff --git a/app/app.pro b/app/app.pro index bbce4cb2f1..c109d73e22 100644 --- a/app/app.pro +++ b/app/app.pro @@ -90,6 +90,7 @@ HEADERS += \ src/generalpage.h \ src/shortcutspage.h \ src/timelinepage.h \ + src/toolboxwidget.h \ src/toolspage.h \ src/basedockwidget.h \ src/colorbox.h \ @@ -142,6 +143,7 @@ SOURCES += \ src/generalpage.cpp \ src/shortcutspage.cpp \ src/timelinepage.cpp \ + src/toolboxwidget.cpp \ src/toolspage.cpp \ src/basedockwidget.cpp \ src/colorbox.cpp \ diff --git a/app/src/actioncommands.cpp b/app/src/actioncommands.cpp index 11fba978c9..30a42434e7 100644 --- a/app/src/actioncommands.cpp +++ b/app/src/actioncommands.cpp @@ -30,6 +30,7 @@ GNU General Public License for more details. #include "viewmanager.h" #include "layermanager.h" #include "scribblearea.h" +#include "toolmanager.h" #include "soundmanager.h" #include "playbackmanager.h" #include "colormanager.h" @@ -942,6 +943,12 @@ void ActionCommands::changeallKeyframeLineColor() } } + +void ActionCommands::resetAllTools() +{ + mEditor->tools()->resetAllTools(); +} + void ActionCommands::help() { QString url = "http://www.pencil2d.org/doc/"; diff --git a/app/src/actioncommands.h b/app/src/actioncommands.h index 6d8ac3e340..27a9b705c5 100644 --- a/app/src/actioncommands.h +++ b/app/src/actioncommands.h @@ -65,6 +65,8 @@ class ActionCommands : public QObject void GotoPrevKeyFrame(); Status addNewKey(); + void resetAllTools(); + /** Will insert a keyframe at the current position and push connected frames to the right */ Status insertKeyFrameAtCurrentPosition(); void removeKey(); diff --git a/app/src/mainwindow2.cpp b/app/src/mainwindow2.cpp index a6d4a34f21..ba05e3338c 100644 --- a/app/src/mainwindow2.cpp +++ b/app/src/mainwindow2.cpp @@ -170,7 +170,7 @@ void MainWindow2::createDockWidgets() mToolOptions = new ToolOptionWidget(this); mToolOptions->setObjectName("ToolOption"); - mToolBox = new ToolBoxWidget(this); + mToolBox = new ToolBoxDockWidget(this); mToolBox->setObjectName("ToolBox"); mDockWidgets @@ -409,19 +409,37 @@ void MainWindow2::createMenus() connect(ui->actionReverse_Frames_Order, &QAction::triggered, mCommands, &ActionCommands::reverseSelectedFrames); connect(ui->actionRemove_Frames, &QAction::triggered, mCommands, &ActionCommands::removeSelectedFrames); - //--- Tool Menu --- - connect(ui->actionMove, &QAction::triggered, mToolBox, &ToolBoxWidget::moveOn); - connect(ui->actionSelect, &QAction::triggered, mToolBox, &ToolBoxWidget::selectOn); - connect(ui->actionBrush, &QAction::triggered, mToolBox, &ToolBoxWidget::brushOn); - connect(ui->actionPolyline, &QAction::triggered, mToolBox, &ToolBoxWidget::polylineOn); - connect(ui->actionSmudge, &QAction::triggered, mToolBox, &ToolBoxWidget::smudgeOn); - connect(ui->actionPen, &QAction::triggered, mToolBox, &ToolBoxWidget::penOn); - connect(ui->actionHand, &QAction::triggered, mToolBox, &ToolBoxWidget::handOn); - connect(ui->actionPencil, &QAction::triggered, mToolBox, &ToolBoxWidget::pencilOn); - connect(ui->actionBucket, &QAction::triggered, mToolBox, &ToolBoxWidget::bucketOn); - connect(ui->actionEyedropper, &QAction::triggered, mToolBox, &ToolBoxWidget::eyedropperOn); - connect(ui->actionEraser, &QAction::triggered, mToolBox, &ToolBoxWidget::eraserOn); - connect(ui->actionResetToolsDefault, &QAction::triggered, mEditor->tools(), &ToolManager::resetAllTools); + + auto toolsActionGroup = new QActionGroup(this); + toolsActionGroup->setExclusive(true); + toolsActionGroup->addAction(ui->actionMove); + toolsActionGroup->addAction(ui->actionSelect); + toolsActionGroup->addAction(ui->actionBrush); + toolsActionGroup->addAction(ui->actionPolyline); + toolsActionGroup->addAction(ui->actionSmudge); + toolsActionGroup->addAction(ui->actionPen); + toolsActionGroup->addAction(ui->actionHand); + toolsActionGroup->addAction(ui->actionPencil); + toolsActionGroup->addAction(ui->actionBucket); + toolsActionGroup->addAction(ui->actionEyedropper); + toolsActionGroup->addAction(ui->actionEraser); + toolsActionGroup->addAction(ui->actionResetToolsDefault); + + connect(toolsActionGroup, &QActionGroup::triggered, this, [&](QAction* action) { + if (action == ui->actionMove) mToolBox->setActiveTool(MOVE); + else if (action == ui->actionSelect) mToolBox->setActiveTool(SELECT); + else if (action == ui->actionBrush) mToolBox->setActiveTool(BRUSH); + else if (action == ui->actionPolyline) mToolBox->setActiveTool(POLYLINE); + else if (action == ui->actionSmudge) mToolBox->setActiveTool(SMUDGE); + else if (action == ui->actionPen) mToolBox->setActiveTool(PEN); + else if (action == ui->actionHand) mToolBox->setActiveTool(HAND); + else if (action == ui->actionPencil) mToolBox->setActiveTool(PENCIL); + else if (action == ui->actionBucket) mToolBox->setActiveTool(BUCKET); + else if (action == ui->actionEyedropper) mToolBox->setActiveTool(EYEDROPPER); + else if (action == ui->actionEraser) mToolBox->setActiveTool(ERASER); + else if (action == ui->actionResetToolsDefault) mCommands->resetAllTools(); + else Q_UNREACHABLE(); + }); //--- Window Menu --- QMenu* winMenu = ui->menuWindows; @@ -1446,7 +1464,7 @@ void MainWindow2::makeConnections(Editor* editor, ColorInspector* colorInspector void MainWindow2::makeConnections(Editor* editor, ScribbleArea* scribbleArea) { connect(editor->tools(), &ToolManager::toolChanged, scribbleArea, &ScribbleArea::updateToolCursor); - connect(editor->tools(), &ToolManager::toolChanged, mToolBox, &ToolBoxWidget::onToolSetActive); + connect(editor->tools(), &ToolManager::toolChanged, mToolBox, &ToolBoxDockWidget::setActiveTool); connect(editor->tools(), &ToolManager::toolPropertyChanged, scribbleArea, &ScribbleArea::updateToolCursor); diff --git a/app/src/mainwindow2.h b/app/src/mainwindow2.h index d85d400a22..c65870258b 100644 --- a/app/src/mainwindow2.h +++ b/app/src/mainwindow2.h @@ -31,7 +31,7 @@ class ColorPaletteWidget; class OnionSkinWidget; class ToolOptionWidget; class TimeLine; -class ToolBoxWidget; +class ToolBoxDockWidget; class PreferencesDialog; class PreviewWidget; class ColorBox; @@ -157,7 +157,7 @@ private slots: ColorBox* mColorBox = nullptr; ColorPaletteWidget* mColorPalette = nullptr; ToolOptionWidget* mToolOptions = nullptr; - ToolBoxWidget* mToolBox = nullptr; + ToolBoxDockWidget* mToolBox = nullptr; RecentFileMenu* mRecentFileMenu = nullptr; PreferencesDialog* mPrefDialog = nullptr; //PreviewWidget* mPreview = nullptr; diff --git a/app/src/toolbox.cpp b/app/src/toolbox.cpp index bedd34d116..ac746c29f8 100644 --- a/app/src/toolbox.cpp +++ b/app/src/toolbox.cpp @@ -16,7 +16,6 @@ GNU General Public License for more details. */ #include "toolbox.h" -#include "ui_toolboxwidget.h" #include @@ -25,6 +24,8 @@ GNU General Public License for more details. #include #include #include +#include +#include #include "flowlayout.h" #include "spinslider.h" @@ -32,312 +33,53 @@ GNU General Public License for more details. #include "toolmanager.h" #include "layermanager.h" #include "pencilsettings.h" -#include "toolboxlayout.h" -// ---------------------------------------------------------------------------------- -QString GetToolTips(QString strCommandName) +ToolBoxDockWidget::ToolBoxDockWidget(QWidget* parent) : + BaseDockWidget(parent) { - strCommandName = QString("shortcuts/") + strCommandName; - QKeySequence keySequence(pencilSettings().value(strCommandName).toString()); - return QString("%1").arg(keySequence.toString()); // don't tr() this string. -} + mWidget = new ToolBoxWidget(this); -ToolBoxWidget::ToolBoxWidget(QWidget* parent) : - BaseDockWidget(parent), - ui(new Ui::ToolBoxWidget) -{ - ui->setupUi(this); + setWindowTitle(tr("Tools", "Window title of Tools")); } -ToolBoxWidget::~ToolBoxWidget() +ToolBoxDockWidget::~ToolBoxDockWidget() { QSettings settings(PENCIL2D, PENCIL2D); settings.setValue("ToolBoxGeom", this->saveGeometry()); - delete ui; } -void ToolBoxWidget::initUI() +void ToolBoxDockWidget::initUI() { -#ifdef __APPLE__ - // Only Mac needs this. ToolButton is naturally borderless on Win/Linux. - QString sStyle = - "QToolButton { border: 0px; }" - "QToolButton:pressed { border: 1px solid #ADADAD; border-radius: 2px; background-color: #D5D5D5; }" - "QToolButton:checked { border: 1px solid #ADADAD; border-radius: 2px; background-color: #D5D5D5; }"; - ui->pencilButton->setStyleSheet(sStyle); - ui->selectButton->setStyleSheet(sStyle); - ui->moveButton->setStyleSheet(sStyle); - ui->handButton->setStyleSheet(sStyle); - ui->penButton->setStyleSheet(sStyle); - ui->eraserButton->setStyleSheet(sStyle); - ui->polylineButton->setStyleSheet(sStyle); - ui->bucketButton->setStyleSheet(sStyle); - ui->brushButton->setStyleSheet(sStyle); - ui->eyedropperButton->setStyleSheet(sStyle); - ui->smudgeButton->setStyleSheet(sStyle); -#endif - - ui->pencilButton->setToolTip( tr( "Pencil Tool (%1): Sketch with pencil" ) - .arg( GetToolTips( CMD_TOOL_PENCIL ) ) ); - ui->selectButton->setToolTip( tr( "Select Tool (%1): Select an object" ) - .arg( GetToolTips( CMD_TOOL_SELECT ) ) ); - ui->moveButton->setToolTip( tr( "Move Tool (%1): Move an object" ) - .arg( GetToolTips( CMD_TOOL_MOVE ) ) ); - ui->handButton->setToolTip( tr( "Hand Tool (%1): Move the canvas" ) - .arg( GetToolTips( CMD_TOOL_HAND ) ) ); - ui->penButton->setToolTip( tr( "Pen Tool (%1): Sketch with pen" ) - .arg( GetToolTips( CMD_TOOL_PEN ) ) ); - ui->eraserButton->setToolTip( tr( "Eraser Tool (%1): Erase" ) - .arg( GetToolTips( CMD_TOOL_ERASER ) ) ); - ui->polylineButton->setToolTip( tr( "Polyline Tool (%1): Create line/curves" ) - .arg( GetToolTips( CMD_TOOL_POLYLINE ) ) ); - ui->bucketButton->setToolTip( tr( "Paint Bucket Tool (%1): Fill selected area with a color" ) - .arg( GetToolTips( CMD_TOOL_BUCKET ) ) ); - ui->brushButton->setToolTip( tr( "Brush Tool (%1): Paint smooth stroke with a brush" ) - .arg( GetToolTips( CMD_TOOL_BRUSH ) ) ); - ui->eyedropperButton->setToolTip( tr( "Eyedropper Tool (%1): " - "Set color from the stage
[ALT] for instant access" ) - .arg( GetToolTips( CMD_TOOL_EYEDROPPER ) ) ); - ui->smudgeButton->setToolTip( tr( "Smudge Tool (%1):
Edit polyline/curves
" - "Liquify bitmap pixels
(%1)+[Alt]: Smooth" ) - .arg( GetToolTips( CMD_TOOL_SMUDGE ) ) ); - - ui->pencilButton->setWhatsThis( tr( "Pencil Tool (%1)" ) - .arg( GetToolTips( CMD_TOOL_PENCIL ) ) ); - ui->selectButton->setWhatsThis( tr( "Select Tool (%1)" ) - .arg( GetToolTips( CMD_TOOL_SELECT ) ) ); - ui->moveButton->setWhatsThis( tr( "Move Tool (%1)" ) - .arg( GetToolTips( CMD_TOOL_MOVE ) ) ); - ui->handButton->setWhatsThis( tr( "Hand Tool (%1)" ) - .arg( GetToolTips( CMD_TOOL_HAND ) ) ); - ui->penButton->setWhatsThis( tr( "Pen Tool (%1)" ) - .arg( GetToolTips( CMD_TOOL_PEN ) ) ); - ui->eraserButton->setWhatsThis( tr( "Eraser Tool (%1)" ) - .arg( GetToolTips( CMD_TOOL_ERASER ) ) ); - ui->polylineButton->setWhatsThis( tr( "Polyline Tool (%1)" ) - .arg( GetToolTips( CMD_TOOL_POLYLINE ) ) ); - ui->bucketButton->setWhatsThis( tr( "Paint Bucket Tool (%1)" ) - .arg( GetToolTips( CMD_TOOL_BUCKET ) ) ); - ui->brushButton->setWhatsThis( tr( "Brush Tool (%1)" ) - .arg( GetToolTips( CMD_TOOL_BRUSH ) ) ); - ui->eyedropperButton->setWhatsThis( tr( "Eyedropper Tool (%1)" ) - .arg( GetToolTips( CMD_TOOL_EYEDROPPER ) ) ); - ui->smudgeButton->setWhatsThis( tr( "Smudge Tool (%1)" ) - .arg( GetToolTips( CMD_TOOL_SMUDGE ) ) ); - - connect(ui->pencilButton, &QToolButton::clicked, this, &ToolBoxWidget::pencilOn); - connect(ui->eraserButton, &QToolButton::clicked, this, &ToolBoxWidget::eraserOn); - connect(ui->selectButton, &QToolButton::clicked, this, &ToolBoxWidget::selectOn); - connect(ui->moveButton, &QToolButton::clicked, this, &ToolBoxWidget::moveOn); - connect(ui->penButton, &QToolButton::clicked, this, &ToolBoxWidget::penOn); - connect(ui->handButton, &QToolButton::clicked, this, &ToolBoxWidget::handOn); - connect(ui->polylineButton, &QToolButton::clicked, this, &ToolBoxWidget::polylineOn); - connect(ui->bucketButton, &QToolButton::clicked, this, &ToolBoxWidget::bucketOn); - connect(ui->eyedropperButton, &QToolButton::clicked, this, &ToolBoxWidget::eyedropperOn); - connect(ui->brushButton, &QToolButton::clicked, this, &ToolBoxWidget::brushOn); - connect(ui->smudgeButton, &QToolButton::clicked, this, &ToolBoxWidget::smudgeOn); + mWidget->setEditor(editor()); + mWidget->initUI(); - connect(editor()->layers(), &LayerManager::currentLayerChanged, this, &ToolBoxWidget::onLayerDidChange); + setWidget(mWidget); + setContentsMargins(0,0,0,0); - mFlowlayout = new ToolBoxLayout(nullptr, 3,3,3); - - mFlowlayout->addWidget(ui->pencilButton); - mFlowlayout->addWidget(ui->eraserButton); - mFlowlayout->addWidget(ui->selectButton); - mFlowlayout->addWidget(ui->moveButton); - mFlowlayout->addWidget(ui->penButton); - mFlowlayout->addWidget(ui->handButton); - mFlowlayout->addWidget(ui->polylineButton); - mFlowlayout->addWidget(ui->bucketButton); - mFlowlayout->addWidget(ui->eyedropperButton); - mFlowlayout->addWidget(ui->brushButton); - mFlowlayout->addWidget(ui->smudgeButton); - - delete ui->scrollAreaWidgetContents_2->layout(); - ui->scrollAreaWidgetContents_2->setLayout(mFlowlayout); + connect(editor()->layers(), &LayerManager::currentLayerChanged, this, &ToolBoxDockWidget::onLayerDidChange); QSettings settings(PENCIL2D, PENCIL2D); restoreGeometry(settings.value("ToolBoxGeom").toByteArray()); // Important to set the proper minimumSize; - ui->scrollArea->setMinimumSize(minimumSizeHint()); -} - -int ToolBoxWidget::getMinHeightForWidth(int width) const -{ - int layoutHeight = mFlowlayout->heightForWidth(width); - if (this->isFloating()) { - return layoutHeight; - } else { - return layoutHeight + BaseDockWidget::minimumSizeHint().height(); - } -} - -QSize ToolBoxWidget::minimumSizeHint() const -{ - return QSize(mFlowlayout->minimumSize().width(), getMinHeightForWidth(width())); -} - -void ToolBoxWidget::resizeEvent(QResizeEvent *event) -{ - BaseDockWidget::resizeEvent(event); - - updateLayoutAlignment(); + setMinimumSize(mWidget->minimumSize()); } -void ToolBoxWidget::updateLayoutAlignment() +void ToolBoxDockWidget::setActiveTool(ToolType type) { - mFlowlayout->invalidate(); - if (mFlowlayout->rows() > 1) { - mFlowlayout->setAlignment(Qt::AlignJustify); - } else { - mFlowlayout->setAlignment(Qt::AlignHCenter); - } - - mFlowlayout->activate(); + mWidget->setToolChecked(type); } -void ToolBoxWidget::updateUI() +void ToolBoxDockWidget::updateUI() { + mWidget->updateUI(); } -void ToolBoxWidget::onToolSetActive(ToolType toolType) -{ - deselectAllTools(); - switch (toolType) { - case ToolType::BRUSH: - ui->brushButton->setChecked(true); - break; - case ToolType::PEN: - ui->penButton->setChecked(true); - break; - case ToolType::PENCIL: - ui->pencilButton->setChecked(true); - break; - case ToolType::SELECT: - ui->selectButton->setChecked(true); - break; - case ToolType::HAND: - ui->handButton->setChecked(true); - break; - case ToolType::MOVE: - case ToolType::CAMERA: - ui->moveButton->setChecked(true); - break; - case ToolType::ERASER: - ui->eraserButton->setChecked(true); - break; - case ToolType::POLYLINE: - ui->polylineButton->setChecked(true); - break; - case ToolType::SMUDGE: - ui->smudgeButton->setChecked(true); - break; - case ToolType::BUCKET: - ui->bucketButton->setChecked(true); - break; - case ToolType::EYEDROPPER: - ui->eyedropperButton->setChecked(true); - break; - default: - break; - } -} - -void ToolBoxWidget::pencilOn() -{ - toolOn(PENCIL, ui->pencilButton); -} - -void ToolBoxWidget::eraserOn() -{ - toolOn(ERASER, ui->eraserButton); -} - -void ToolBoxWidget::selectOn() -{ - toolOn(SELECT, ui->selectButton); -} - -void ToolBoxWidget::moveOn() -{ - if (editor()->layers()->currentLayer()->type() == Layer::CAMERA) { - toolOn(CAMERA, ui->moveButton); - } else { - toolOn(MOVE, ui->moveButton); - } -} - -void ToolBoxWidget::penOn() -{ - toolOn(PEN, ui->penButton); -} - -void ToolBoxWidget::handOn() -{ - toolOn(HAND, ui->handButton); -} - -void ToolBoxWidget::polylineOn() -{ - toolOn(POLYLINE, ui->polylineButton); -} - -void ToolBoxWidget::bucketOn() -{ - toolOn(BUCKET, ui->bucketButton); -} - -void ToolBoxWidget::eyedropperOn() -{ - toolOn(EYEDROPPER, ui->eyedropperButton); -} - -void ToolBoxWidget::brushOn() -{ - toolOn(BRUSH, ui->brushButton); -} - -void ToolBoxWidget::smudgeOn() -{ - toolOn(SMUDGE, ui->smudgeButton); -} - -void ToolBoxWidget::deselectAllTools() -{ - ui->pencilButton->setChecked(false); - ui->eraserButton->setChecked(false); - ui->selectButton->setChecked(false); - ui->moveButton->setChecked(false); - ui->handButton->setChecked(false); - ui->penButton->setChecked(false); - ui->polylineButton->setChecked(false); - ui->bucketButton->setChecked(false); - ui->eyedropperButton->setChecked(false); - ui->brushButton->setChecked(false); - ui->smudgeButton->setChecked(false); -} - -void ToolBoxWidget::toolOn(ToolType toolType, QToolButton* toolButton) -{ - if (editor()->tools()->currentTool()->type() == toolType) { - // Prevent un-checking the current tool and do nothing - toolButton->setChecked(true); - return; - } - if (!editor()->tools()->leavingThisTool()) - { - toolButton->setChecked(false); - return; - } - editor()->tools()->setCurrentTool(toolType); -} - -void ToolBoxWidget::onLayerDidChange(int) +void ToolBoxDockWidget::onLayerDidChange(int) { BaseTool* currentTool = editor()->tools()->currentTool(); if (currentTool->type() == MOVE || currentTool->type() == CAMERA) { - moveOn(); + mWidget->moveOn(); } } diff --git a/app/src/toolbox.h b/app/src/toolbox.h index 7e9ffb4f6a..b312397455 100644 --- a/app/src/toolbox.h +++ b/app/src/toolbox.h @@ -14,12 +14,14 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. */ -#ifndef TOOLBOXWIDGET_H -#define TOOLBOXWIDGET_H +#ifndef TOOLBOXDOCKWIDGET_H +#define TOOLBOXDOCKWIDGET_H #include "pencildef.h" #include "basedockwidget.h" +#include "toolboxwidget.h" + class QToolButton; class QGridLayout; class QIcon; @@ -27,52 +29,25 @@ class SpinSlider; class DisplayOptionWidget; class ToolOptionWidget; class Editor; -class ToolBoxLayout; - -namespace Ui { -class ToolBoxWidget; -} +class FlowLayout; -class ToolBoxWidget : public BaseDockWidget +class ToolBoxDockWidget : public BaseDockWidget { Q_OBJECT public: - ToolBoxWidget(QWidget* parent); - ~ToolBoxWidget() override; + ToolBoxDockWidget(QWidget* parent); + ~ToolBoxDockWidget() override; void initUI() override; void updateUI() override; -public slots: - void onToolSetActive(ToolType toolType); - void onLayerDidChange(int index); - void pencilOn(); - void eraserOn(); - void selectOn(); - void moveOn(); - void penOn(); - void handOn(); - void polylineOn(); - void bucketOn(); - void eyedropperOn(); - void brushOn(); - void smudgeOn(); - -protected: - void resizeEvent(QResizeEvent* event) override; - QSize minimumSizeHint() const override; + void setActiveTool(ToolType type); private: - void updateLayoutAlignment(); - void deselectAllTools(); - void toolOn(ToolType toolType, QToolButton* toolButton); - - int getMinHeightForWidth(int width) const; - - Ui::ToolBoxWidget* ui = nullptr; + void onLayerDidChange(int); - ToolBoxLayout* mFlowlayout = nullptr; + ToolBoxWidget* mWidget = nullptr; }; #endif diff --git a/app/src/toolboxwidget.cpp b/app/src/toolboxwidget.cpp new file mode 100644 index 0000000000..95bb7878e5 --- /dev/null +++ b/app/src/toolboxwidget.cpp @@ -0,0 +1,330 @@ +#include "toolboxwidget.h" +#include "ui_toolboxwidget.h" + +#include +#include +#include +#include + +#include "layermanager.h" +#include "toolmanager.h" +#include "editor.h" +#include "pencilsettings.h" + +// ---------------------------------------------------------------------------------- +QString GetToolTips(QString strCommandName) +{ + strCommandName = QString("shortcuts/") + strCommandName; + QKeySequence keySequence(pencilSettings().value(strCommandName).toString()); + return QString("%1").arg(keySequence.toString()); // don't tr() this string. +} + +ToolBoxWidget::ToolBoxWidget(QWidget* parent) + : QWidget(parent), ui(new Ui::ToolBoxWidget) +{ + ui->setupUi(this); +} + +ToolBoxWidget::~ToolBoxWidget() +{ + delete ui; +} + +void ToolBoxWidget::initUI() +{ + +#ifdef __APPLE__ + // Only Mac needs this. ToolButton is naturally borderless on Win/Linux. + QString sStyle = + "QToolButton { border: 0px; }" + "QToolButton:pressed { border: 1px solid #ADADAD; border-radius: 2px; background-color: #D5D5D5; }" + "QToolButton:checked { border: 1px solid #ADADAD; border-radius: 2px; background-color: #D5D5D5; }"; + ui->pencilButton->setStyleSheet(sStyle); + ui->selectButton->setStyleSheet(sStyle); + ui->moveButton->setStyleSheet(sStyle); + ui->handButton->setStyleSheet(sStyle); + ui->penButton->setStyleSheet(sStyle); + ui->eraserButton->setStyleSheet(sStyle); + ui->polylineButton->setStyleSheet(sStyle); + ui->bucketButton->setStyleSheet(sStyle); + ui->brushButton->setStyleSheet(sStyle); + ui->eyedropperButton->setStyleSheet(sStyle); + ui->smudgeButton->setStyleSheet(sStyle); +#endif + + ui->pencilButton->setToolTip( tr( "Pencil Tool (%1): Sketch with pencil" ) + .arg( GetToolTips( CMD_TOOL_PENCIL ) ) ); + ui->selectButton->setToolTip( tr( "Select Tool (%1): Select an object" ) + .arg( GetToolTips( CMD_TOOL_SELECT ) ) ); + ui->moveButton->setToolTip( tr( "Move Tool (%1): Move an object" ) + .arg( GetToolTips( CMD_TOOL_MOVE ) ) ); + ui->handButton->setToolTip( tr( "Hand Tool (%1): Move the canvas" ) + .arg( GetToolTips( CMD_TOOL_HAND ) ) ); + ui->penButton->setToolTip( tr( "Pen Tool (%1): Sketch with pen" ) + .arg( GetToolTips( CMD_TOOL_PEN ) ) ); + ui->eraserButton->setToolTip( tr( "Eraser Tool (%1): Erase" ) + .arg( GetToolTips( CMD_TOOL_ERASER ) ) ); + ui->polylineButton->setToolTip( tr( "Polyline Tool (%1): Create line/curves" ) + .arg( GetToolTips( CMD_TOOL_POLYLINE ) ) ); + ui->bucketButton->setToolTip( tr( "Paint Bucket Tool (%1): Fill selected area with a color" ) + .arg( GetToolTips( CMD_TOOL_BUCKET ) ) ); + ui->brushButton->setToolTip( tr( "Brush Tool (%1): Paint smooth stroke with a brush" ) + .arg( GetToolTips( CMD_TOOL_BRUSH ) ) ); + ui->eyedropperButton->setToolTip( tr( "Eyedropper Tool (%1): " + "Set color from the stage
[ALT] for instant access" ) + .arg( GetToolTips( CMD_TOOL_EYEDROPPER ) ) ); + ui->smudgeButton->setToolTip( tr( "Smudge Tool (%1):
Edit polyline/curves
" + "Liquify bitmap pixels
(%1)+[Alt]: Smooth" ) + .arg( GetToolTips( CMD_TOOL_SMUDGE ) ) ); + + ui->pencilButton->setWhatsThis( tr( "Pencil Tool (%1)" ) + .arg( GetToolTips( CMD_TOOL_PENCIL ) ) ); + ui->selectButton->setWhatsThis( tr( "Select Tool (%1)" ) + .arg( GetToolTips( CMD_TOOL_SELECT ) ) ); + ui->moveButton->setWhatsThis( tr( "Move Tool (%1)" ) + .arg( GetToolTips( CMD_TOOL_MOVE ) ) ); + ui->handButton->setWhatsThis( tr( "Hand Tool (%1)" ) + .arg( GetToolTips( CMD_TOOL_HAND ) ) ); + ui->penButton->setWhatsThis( tr( "Pen Tool (%1)" ) + .arg( GetToolTips( CMD_TOOL_PEN ) ) ); + ui->eraserButton->setWhatsThis( tr( "Eraser Tool (%1)" ) + .arg( GetToolTips( CMD_TOOL_ERASER ) ) ); + ui->polylineButton->setWhatsThis( tr( "Polyline Tool (%1)" ) + .arg( GetToolTips( CMD_TOOL_POLYLINE ) ) ); + ui->bucketButton->setWhatsThis( tr( "Paint Bucket Tool (%1)" ) + .arg( GetToolTips( CMD_TOOL_BUCKET ) ) ); + ui->brushButton->setWhatsThis( tr( "Brush Tool (%1)" ) + .arg( GetToolTips( CMD_TOOL_BRUSH ) ) ); + ui->eyedropperButton->setWhatsThis( tr( "Eyedropper Tool (%1)" ) + .arg( GetToolTips( CMD_TOOL_EYEDROPPER ) ) ); + ui->smudgeButton->setWhatsThis( tr( "Smudge Tool (%1)" ) + .arg( GetToolTips( CMD_TOOL_SMUDGE ) ) ); + + connect(ui->pencilButton, &QToolButton::clicked, this, &ToolBoxWidget::pencilOn); + connect(ui->eraserButton, &QToolButton::clicked, this, &ToolBoxWidget::eraserOn); + connect(ui->selectButton, &QToolButton::clicked, this, &ToolBoxWidget::selectOn); + connect(ui->moveButton, &QToolButton::clicked, this, &ToolBoxWidget::moveOn); + connect(ui->penButton, &QToolButton::clicked, this, &ToolBoxWidget::penOn); + connect(ui->handButton, &QToolButton::clicked, this, &ToolBoxWidget::handOn); + connect(ui->polylineButton, &QToolButton::clicked, this, &ToolBoxWidget::polylineOn); + connect(ui->bucketButton, &QToolButton::clicked, this, &ToolBoxWidget::bucketOn); + connect(ui->eyedropperButton, &QToolButton::clicked, this, &ToolBoxWidget::eyedropperOn); + connect(ui->brushButton, &QToolButton::clicked, this, &ToolBoxWidget::brushOn); + connect(ui->smudgeButton, &QToolButton::clicked, this, &ToolBoxWidget::smudgeOn); + + connect(mEditor->layers(), &LayerManager::currentLayerChanged, this, &ToolBoxWidget::onLayerDidChange); + + mFlowlayout = new ToolBoxLayout(nullptr, 3,3,3); + + mFlowlayout->addWidget(ui->pencilButton); + mFlowlayout->addWidget(ui->eraserButton); + mFlowlayout->addWidget(ui->selectButton); + mFlowlayout->addWidget(ui->moveButton); + mFlowlayout->addWidget(ui->penButton); + mFlowlayout->addWidget(ui->handButton); + mFlowlayout->addWidget(ui->polylineButton); + mFlowlayout->addWidget(ui->bucketButton); + mFlowlayout->addWidget(ui->eyedropperButton); + mFlowlayout->addWidget(ui->brushButton); + mFlowlayout->addWidget(ui->smudgeButton); + + delete ui->scrollAreaWidgetContents_2->layout(); + ui->scrollAreaWidgetContents_2->setLayout(mFlowlayout); + + // Important to set the proper minimumSize; + ui->scrollArea->setMinimumSize(QSize(1,1)); + setMinimumSize(mFlowlayout->minimumSize()); + + QButtonGroup* buttonGroup = new QButtonGroup(this); + buttonGroup->addButton(ui->pencilButton); + buttonGroup->addButton(ui->eraserButton); + buttonGroup->addButton(ui->selectButton); + buttonGroup->addButton(ui->moveButton); + buttonGroup->addButton(ui->penButton); + buttonGroup->addButton(ui->handButton); + buttonGroup->addButton(ui->polylineButton); + buttonGroup->addButton(ui->bucketButton); + buttonGroup->addButton(ui->eyedropperButton); + buttonGroup->addButton(ui->brushButton); + buttonGroup->addButton(ui->smudgeButton); +} + +int ToolBoxWidget::getMinHeightForWidth(int width) const +{ + return mFlowlayout->heightForWidth(width); +} + +QSize ToolBoxWidget::sizeHint() const +{ + return minimumSizeHint(); +} + +QSize ToolBoxWidget::minimumSizeHint() const +{ + int minWidth = mFlowlayout->minimumSize().width(); + return QSize(minWidth, getMinHeightForWidth(width())); +} + +void ToolBoxWidget::resizeEvent(QResizeEvent *event) +{ + QWidget::resizeEvent(event); + + updateLayoutAlignment(); +} + +void ToolBoxWidget::updateLayoutAlignment() +{ + mFlowlayout->invalidate(); + if (mFlowlayout->rows() > 1) { + mFlowlayout->setAlignment(Qt::AlignJustify); + } else { + mFlowlayout->setAlignment(Qt::AlignHCenter); + } + + mFlowlayout->activate(); +} + +void ToolBoxWidget::updateUI() +{ +} + +void ToolBoxWidget::setToolChecked(ToolType toolType) +{ + QToolButton* button = nullptr; + switch (toolType) { + case ToolType::BRUSH: + brushOn(); + break; + case ToolType::PEN: + penOn(); + break; + case ToolType::PENCIL: + pencilOn(); + break; + case ToolType::SELECT: + selectOn(); + break; + case ToolType::HAND: + handOn(); + break; + case ToolType::MOVE: + case ToolType::CAMERA: + moveOn(); + break; + case ToolType::ERASER: + eraserOn(); + break; + case ToolType::POLYLINE: + polylineOn(); + break; + case ToolType::SMUDGE: + smudgeOn(); + break; + case ToolType::BUCKET: + bucketOn(); + break; + case ToolType::EYEDROPPER: + eyedropperOn(); + break; + default: + break; + } +} + +void ToolBoxWidget::pencilOn() +{ + toolOn(PENCIL, ui->pencilButton); +} + +void ToolBoxWidget::eraserOn() +{ + toolOn(ERASER, ui->eraserButton); +} + +void ToolBoxWidget::selectOn() +{ + toolOn(SELECT, ui->selectButton); +} + +void ToolBoxWidget::moveOn() +{ + if (mEditor->layers()->currentLayer()->type() == Layer::CAMERA) { + toolOn(CAMERA, ui->moveButton); + } else { + toolOn(MOVE, ui->moveButton); + } +} + +void ToolBoxWidget::penOn() +{ + toolOn(PEN, ui->penButton); +} + +void ToolBoxWidget::handOn() +{ + toolOn(HAND, ui->handButton); +} + +void ToolBoxWidget::polylineOn() +{ + toolOn(POLYLINE, ui->polylineButton); +} + +void ToolBoxWidget::bucketOn() +{ + toolOn(BUCKET, ui->bucketButton); +} + +void ToolBoxWidget::eyedropperOn() +{ + toolOn(EYEDROPPER, ui->eyedropperButton); +} + +void ToolBoxWidget::brushOn() +{ + toolOn(BRUSH, ui->brushButton); +} + +void ToolBoxWidget::smudgeOn() +{ + toolOn(SMUDGE, ui->smudgeButton); +} + +void ToolBoxWidget::deselectAllTools() +{ + ui->pencilButton->setChecked(false); + ui->eraserButton->setChecked(false); + ui->selectButton->setChecked(false); + ui->moveButton->setChecked(false); + ui->handButton->setChecked(false); + ui->penButton->setChecked(false); + ui->polylineButton->setChecked(false); + ui->bucketButton->setChecked(false); + ui->eyedropperButton->setChecked(false); + ui->brushButton->setChecked(false); + ui->smudgeButton->setChecked(false); +} + +void ToolBoxWidget::toolOn(ToolType toolType, QToolButton* toolButton) +{ + if (mEditor->tools()->currentTool()->type() == toolType) { + // Prevent un-checking the current tool and do nothing + toolButton->setChecked(true); + return; + } + if (!mEditor->tools()->leavingThisTool()) + { + toolButton->setChecked(false); + return; + } + mEditor->tools()->setCurrentTool(toolType); +} + +void ToolBoxWidget::onLayerDidChange(int) +{ + BaseTool* currentTool = mEditor->tools()->currentTool(); + if (currentTool->type() == MOVE || currentTool->type() == CAMERA) + { + moveOn(); + } +} diff --git a/app/src/toolboxwidget.h b/app/src/toolboxwidget.h new file mode 100644 index 0000000000..1cc6848ee7 --- /dev/null +++ b/app/src/toolboxwidget.h @@ -0,0 +1,61 @@ +#ifndef TOOLBOXWIDGET_H +#define TOOLBOXWIDGET_H + +#include +#include +#include + +#include "flowlayout.h" +#include "pencildef.h" +#include "toolboxlayout.h" + +class Editor; + +namespace Ui { +class ToolBoxWidget; +} + +class ToolBoxWidget : public QWidget +{ + Q_OBJECT +public: + ToolBoxWidget(QWidget* parent = nullptr); + ~ToolBoxWidget() override; + + void setEditor(Editor* editor) { mEditor = editor; } + void initUI(); + void updateUI(); + +public slots: + void setToolChecked(ToolType toolType); + void onLayerDidChange(int index); + void pencilOn(); + void eraserOn(); + void selectOn(); + void moveOn(); + void penOn(); + void handOn(); + void polylineOn(); + void bucketOn(); + void eyedropperOn(); + void brushOn(); + void smudgeOn(); + +protected: + int getMinHeightForWidth(int width) const; + QSize minimumSizeHint() const override; + QSize sizeHint() const override; + void resizeEvent(QResizeEvent* event) override; + +private: + void updateLayoutAlignment(); + void deselectAllTools(); + void toolOn(ToolType toolType, QToolButton* toolButton); + + FlowLayout* mFlowlayout = nullptr; + + Ui::ToolBoxWidget* ui = nullptr; + Editor* mEditor = nullptr; +}; + +#endif // TOOLBOXWIDGET_H diff --git a/app/ui/toolboxwidget.ui b/app/ui/toolboxwidget.ui index a2449d45f8..4c63c548ca 100644 --- a/app/ui/toolboxwidget.ui +++ b/app/ui/toolboxwidget.ui @@ -1,7 +1,7 @@ ToolBoxWidget - + 0 @@ -19,426 +19,424 @@ Tools - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - QFrame::NoFrame - - - QFrame::Plain - - - 1 - - - true - - - - - 0 - 0 - 32 - 477 - + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QFrame::Shape::NoFrame - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 + + QFrame::Shadow::Plain + + + 1 + + + true + + + + + 0 + 0 + 32 + 461 + - - - - - 32 - 32 - - - - - 32 - 32 - - - - - :/icons/themes/playful/tools/tool-pencil.svg:/icons/themes/playful/tools/tool-pencil.svg - - - - 22 - 22 - - - - true - - - true - - - true - - - - - - - - 32 - 32 - - - - - 32 - 32 - - - - - :/icons/themes/playful/tools/tool-eraser.svg:/icons/themes/playful/tools/tool-eraser.svg - - - - 22 - 22 - - - - true - - - true - - - - - - - - 32 - 32 - - - - - 32 - 32 - - - - - :/icons/themes/playful/tools/tool-select.svg:/icons/themes/playful/tools/tool-select.svg - - - - 22 - 22 - - - - true - - - true - - - - - - - - 32 - 32 - - - - - 32 - 32 - - - - - :/icons/themes/playful/tools/tool-move.svg:/icons/themes/playful/tools/tool-move.svg - - - - 22 - 22 - - - - true - - - true - - - - - - - - 32 - 32 - - - - - 32 - 32 - - - - - :/icons/themes/playful/tools/tool-pen.svg:/icons/themes/playful/tools/tool-pen.svg - - - - 22 - 22 - - - - true - - - true - - - - - - - - 32 - 32 - - - - - 32 - 32 - - - - - :/icons/themes/playful/tools/tool-hand.svg:/icons/themes/playful/tools/tool-hand.svg - - - - 22 - 22 - - - - true - - - true - - - - - - - - 32 - 32 - - - - - 32 - 32 - - - - - :/icons/themes/playful/tools/tool-polyline.svg:/icons/themes/playful/tools/tool-polyline.svg - - - - 22 - 22 - - - - true - - - true - - - - - - - - 32 - 32 - - - - - 32 - 32 - - - - - :/icons/themes/playful/tools/tool-bucket.svg:/icons/themes/playful/tools/tool-bucket.svg - - - - 22 - 22 - - - - true - - - true - - - - - - - - 32 - 32 - - - - - 32 - 32 - - - - - :/icons/themes/playful/tools/tool-eyedropper.svg:/icons/themes/playful/tools/tool-eyedropper.svg - - - - 22 - 22 - - - - true - - - true - - - - - - - - 32 - 32 - - - - - 32 - 32 - - - - - :/icons/themes/playful/tools/tool-brush.svg:/icons/themes/playful/tools/tool-brush.svg - - - - 22 - 22 - - - - true - - - true - - - - - - - - 32 - 32 - - - - - 32 - 32 - - - - Smudge - - - - :/icons/themes/playful/tools/tool-smudge.svg:/icons/themes/playful/tools/tool-smudge.svg - - - - 22 - 22 - - - - true - - - true - - - - + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 32 + 32 + + + + + 32 + 32 + + + + + :/icons/themes/playful/tools/tool-pencil.svg:/icons/themes/playful/tools/tool-pencil.svg + + + + 22 + 22 + + + + true + + + true + + + true + + + + + + + + 32 + 32 + + + + + 32 + 32 + + + + + :/icons/themes/playful/tools/tool-eraser.svg:/icons/themes/playful/tools/tool-eraser.svg + + + + 22 + 22 + + + + true + + + true + + + + + + + + 32 + 32 + + + + + 32 + 32 + + + + + :/icons/themes/playful/tools/tool-select.svg:/icons/themes/playful/tools/tool-select.svg + + + + 22 + 22 + + + + true + + + true + + + + + + + + 32 + 32 + + + + + 32 + 32 + + + + + :/icons/themes/playful/tools/tool-move.svg:/icons/themes/playful/tools/tool-move.svg + + + + 22 + 22 + + + + true + + + true + + + + + + + + 32 + 32 + + + + + 32 + 32 + + + + + :/icons/themes/playful/tools/tool-pen.svg:/icons/themes/playful/tools/tool-pen.svg + + + + 22 + 22 + + + + true + + + true + + + + + + + + 32 + 32 + + + + + 32 + 32 + + + + + :/icons/themes/playful/tools/tool-hand.svg:/icons/themes/playful/tools/tool-hand.svg + + + + 22 + 22 + + + + true + + + true + + + + + + + + 32 + 32 + + + + + 32 + 32 + + + + + :/icons/themes/playful/tools/tool-polyline.svg:/icons/themes/playful/tools/tool-polyline.svg + + + + 22 + 22 + + + + true + + + true + + + + + + + + 32 + 32 + + + + + 32 + 32 + + + + + :/icons/themes/playful/tools/tool-bucket.svg:/icons/themes/playful/tools/tool-bucket.svg + + + + 22 + 22 + + + + true + + + true + + + + + + + + 32 + 32 + + + + + 32 + 32 + + + + + :/icons/themes/playful/tools/tool-eyedropper.svg:/icons/themes/playful/tools/tool-eyedropper.svg + + + + 22 + 22 + + + + true + + + true + + + + + + + + 32 + 32 + + + + + 32 + 32 + + + + + :/icons/themes/playful/tools/tool-brush.svg:/icons/themes/playful/tools/tool-brush.svg + + + + 22 + 22 + + + + true + + + true + + + + + + + + 32 + 32 + + + + + 32 + 32 + + + + Smudge + + + + :/icons/themes/playful/tools/tool-smudge.svg:/icons/themes/playful/tools/tool-smudge.svg + + + + 22 + 22 + + + + true + + + true + + + + + - - - - + + From 2d229e0de394635cb059251a5489a151c5986c93 Mon Sep 17 00:00:00 2001 From: MrStevns Date: Mon, 28 Apr 2025 18:25:03 +0200 Subject: [PATCH 5/7] Fix dock widget expansion caused by bucket and camera tools being layout This happens because they will appear next to each other initially but then hidden away. The consequence of that is the dockwidget sizes itself based on that, even if it they are removed right after. --- app/src/tooloptionwidget.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/src/tooloptionwidget.cpp b/app/src/tooloptionwidget.cpp index e435fabee8..efa434a338 100644 --- a/app/src/tooloptionwidget.cpp +++ b/app/src/tooloptionwidget.cpp @@ -52,6 +52,9 @@ void ToolOptionWidget::initUI() ui->horizontalLayout_2->addWidget(mBucketOptionsWidget); ui->horizontalLayout_2->addWidget(mCameraOptionsWidget); + mBucketOptionsWidget->setHidden(true); + mCameraOptionsWidget->setHidden(true); + QSettings settings(PENCIL2D, PENCIL2D); ui->sizeSlider->init(tr("Width"), SpinSlider::EXPONENT, SpinSlider::INTEGER, StrokeTool::WIDTH_MIN, StrokeTool::WIDTH_MAX); From aae00e430b0224d2c3a85aad802025bfb4d6167e Mon Sep 17 00:00:00 2001 From: MrStevns Date: Mon, 28 Apr 2025 18:32:11 +0200 Subject: [PATCH 6/7] Add missing license header --- app/src/toolboxwidget.cpp | 17 +++++++++++++++++ app/src/toolboxwidget.h | 17 +++++++++++++++++ core_lib/src/interface/toolboxlayout.cpp | 17 +++++++++++++++++ core_lib/src/interface/toolboxlayout.h | 17 +++++++++++++++++ 4 files changed, 68 insertions(+) diff --git a/app/src/toolboxwidget.cpp b/app/src/toolboxwidget.cpp index 95bb7878e5..b7590a8497 100644 --- a/app/src/toolboxwidget.cpp +++ b/app/src/toolboxwidget.cpp @@ -1,3 +1,20 @@ +/* + +Pencil2D - Traditional Animation Software +Copyright (C) 2005-2007 Patrick Corrieri & Pascal Naidon +Copyright (C) 2012-2020 Matthew Chiawen Chang +Copyright (C) 2024-2099 Oliver S. Larsen + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; version 2 of the License. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +*/ #include "toolboxwidget.h" #include "ui_toolboxwidget.h" diff --git a/app/src/toolboxwidget.h b/app/src/toolboxwidget.h index 1cc6848ee7..f0539819e2 100644 --- a/app/src/toolboxwidget.h +++ b/app/src/toolboxwidget.h @@ -1,3 +1,20 @@ +/* + +Pencil2D - Traditional Animation Software +Copyright (C) 2005-2007 Patrick Corrieri & Pascal Naidon +Copyright (C) 2012-2020 Matthew Chiawen Chang +Copyright (C) 2024-2099 Oliver S. Larsen + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; version 2 of the License. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +*/ #ifndef TOOLBOXWIDGET_H #define TOOLBOXWIDGET_H diff --git a/core_lib/src/interface/toolboxlayout.cpp b/core_lib/src/interface/toolboxlayout.cpp index 85bedb1e7c..7fff8b8afb 100644 --- a/core_lib/src/interface/toolboxlayout.cpp +++ b/core_lib/src/interface/toolboxlayout.cpp @@ -1,3 +1,20 @@ +/* + +Pencil2D - Traditional Animation Software +Copyright (C) 2005-2007 Patrick Corrieri & Pascal Naidon +Copyright (C) 2012-2020 Matthew Chiawen Chang +Copyright (C) 2024-2099 Oliver S. Larsen + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; version 2 of the License. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +*/ #include "toolboxlayout.h" ToolBoxLayout::ToolBoxLayout(QWidget* parent, int margin, int hSpacing, int vSpacing) diff --git a/core_lib/src/interface/toolboxlayout.h b/core_lib/src/interface/toolboxlayout.h index 4d06159523..bb0aa5266c 100644 --- a/core_lib/src/interface/toolboxlayout.h +++ b/core_lib/src/interface/toolboxlayout.h @@ -1,3 +1,20 @@ +/* + +Pencil2D - Traditional Animation Software +Copyright (C) 2005-2007 Patrick Corrieri & Pascal Naidon +Copyright (C) 2012-2020 Matthew Chiawen Chang +Copyright (C) 2024-2099 Oliver S. Larsen + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; version 2 of the License. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +*/ #ifndef TOOLBOXLAYOUT_H #define TOOLBOXLAYOUT_H From 60e7093e56c7efd7e9b96220246a23bf32170415 Mon Sep 17 00:00:00 2001 From: MrStevns Date: Tue, 3 Jun 2025 14:07:56 +0200 Subject: [PATCH 7/7] Cleanup --- app/src/toolbox.cpp | 2 +- app/src/toolboxwidget.cpp | 14 +------------- app/src/toolboxwidget.h | 14 ++++++++------ 3 files changed, 10 insertions(+), 20 deletions(-) diff --git a/app/src/toolbox.cpp b/app/src/toolbox.cpp index ac746c29f8..8d94cc2564 100644 --- a/app/src/toolbox.cpp +++ b/app/src/toolbox.cpp @@ -67,7 +67,7 @@ void ToolBoxDockWidget::initUI() void ToolBoxDockWidget::setActiveTool(ToolType type) { - mWidget->setToolChecked(type); + mWidget->setActiveTool(type); } void ToolBoxDockWidget::updateUI() diff --git a/app/src/toolboxwidget.cpp b/app/src/toolboxwidget.cpp index b7590a8497..292c11a772 100644 --- a/app/src/toolboxwidget.cpp +++ b/app/src/toolboxwidget.cpp @@ -129,8 +129,6 @@ void ToolBoxWidget::initUI() connect(ui->brushButton, &QToolButton::clicked, this, &ToolBoxWidget::brushOn); connect(ui->smudgeButton, &QToolButton::clicked, this, &ToolBoxWidget::smudgeOn); - connect(mEditor->layers(), &LayerManager::currentLayerChanged, this, &ToolBoxWidget::onLayerDidChange); - mFlowlayout = new ToolBoxLayout(nullptr, 3,3,3); mFlowlayout->addWidget(ui->pencilButton); @@ -205,9 +203,8 @@ void ToolBoxWidget::updateUI() { } -void ToolBoxWidget::setToolChecked(ToolType toolType) +void ToolBoxWidget::setActiveTool(ToolType toolType) { - QToolButton* button = nullptr; switch (toolType) { case ToolType::BRUSH: brushOn(); @@ -336,12 +333,3 @@ void ToolBoxWidget::toolOn(ToolType toolType, QToolButton* toolButton) } mEditor->tools()->setCurrentTool(toolType); } - -void ToolBoxWidget::onLayerDidChange(int) -{ - BaseTool* currentTool = mEditor->tools()->currentTool(); - if (currentTool->type() == MOVE || currentTool->type() == CAMERA) - { - moveOn(); - } -} diff --git a/app/src/toolboxwidget.h b/app/src/toolboxwidget.h index f0539819e2..9a5d86819d 100644 --- a/app/src/toolboxwidget.h +++ b/app/src/toolboxwidget.h @@ -44,8 +44,10 @@ class ToolBoxWidget : public QWidget void updateUI(); public slots: - void setToolChecked(ToolType toolType); - void onLayerDidChange(int index); + void setActiveTool(ToolType toolType); + +public: + void pencilOn(); void eraserOn(); void selectOn(); @@ -58,6 +60,10 @@ public slots: void brushOn(); void smudgeOn(); + void updateLayoutAlignment(); + void deselectAllTools(); + void toolOn(ToolType toolType, QToolButton* toolButton); + protected: int getMinHeightForWidth(int width) const; QSize minimumSizeHint() const override; @@ -65,10 +71,6 @@ public slots: void resizeEvent(QResizeEvent* event) override; private: - void updateLayoutAlignment(); - void deselectAllTools(); - void toolOn(ToolType toolType, QToolButton* toolButton); - FlowLayout* mFlowlayout = nullptr; Ui::ToolBoxWidget* ui = nullptr;