From 74b8e41e1b7ebb105c81809a8ea3635813b4d772 Mon Sep 17 00:00:00 2001 From: Nav Date: Wed, 6 Oct 2021 00:27:49 +0100 Subject: [PATCH] New panel widget --- CMakeLists.txt | 1 + .../InsightWindow/Widgets/PanelWidget.cpp | 125 ++++++++++++++++++ .../InsightWindow/Widgets/PanelWidget.hpp | 77 +++++++++++ 3 files changed, 203 insertions(+) create mode 100644 src/Insight/UserInterfaces/InsightWindow/Widgets/PanelWidget.cpp create mode 100644 src/Insight/UserInterfaces/InsightWindow/Widgets/PanelWidget.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 3c8845a1..790593c4 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -123,6 +123,7 @@ add_executable(Bloom src/Insight/UserInterfaces/InsightWindow/UiLoader.cpp src/Insight/UserInterfaces/InsightWindow/InsightWindow.cpp src/Insight/UserInterfaces/InsightWindow/AboutWindow.cpp + src/Insight/UserInterfaces/InsightWindow/Widgets/PanelWidget.cpp src/Insight/UserInterfaces/InsightWindow/Widgets/RotatableLabel.cpp src/Insight/UserInterfaces/InsightWindow/Widgets/SvgWidget.cpp src/Insight/UserInterfaces/InsightWindow/Widgets/SvgToolButton.hpp diff --git a/src/Insight/UserInterfaces/InsightWindow/Widgets/PanelWidget.cpp b/src/Insight/UserInterfaces/InsightWindow/Widgets/PanelWidget.cpp new file mode 100644 index 00000000..4f5eac54 --- /dev/null +++ b/src/Insight/UserInterfaces/InsightWindow/Widgets/PanelWidget.cpp @@ -0,0 +1,125 @@ +#include "PanelWidget.hpp" + +#include + +using namespace Bloom::Widgets; + +PanelWidget::PanelWidget(QWidget* parent): QFrame(parent) { + this->setMouseTracking(false); + this->setAttribute(Qt::WA_Hover, true); +} + +void PanelWidget::setMinimumResize(int minimumResize) { + this->minimumResize = minimumResize; + + const auto currentSize = this->size(); + + if (this->panelType == PanelWidgetType::LEFT && currentSize.width() < this->minimumResize) { + this->setFixedWidth(this->minimumResize); + + } else if (this->panelType == PanelWidgetType::BOTTOM && currentSize.height() < this->minimumResize) { + this->setFixedHeight(this->minimumResize); + } +} + +void PanelWidget::setMaximumResize(int maximumResize) { + this->maximumResize = maximumResize; + + const auto currentSize = this->size(); + + if (this->panelType == PanelWidgetType::LEFT && currentSize.width() > this->maximumResize) { + this->setFixedWidth(this->maximumResize); + + } else if (this->panelType == PanelWidgetType::BOTTOM && currentSize.height() > this->maximumResize) { + this->setFixedHeight(this->maximumResize); + } +} + +void PanelWidget::mousePressEvent(QMouseEvent* event) { + const auto position = event->pos(); + + if (event->buttons() & Qt::LeftButton && this->isPositionWithinHandleArea(position)) { + this->resizingActive = true; + + switch (this->panelType) { + case PanelWidgetType::LEFT: { + this->resizingOffset = this->width() - position.x(); + break; + } + case PanelWidgetType::BOTTOM: { + this->resizingOffset = position.y(); + break; + } + } + } +} + +void PanelWidget::mouseReleaseEvent(QMouseEvent* event) { + if (this->resizingActive) { + this->resizingActive = false; + this->resizingOffset = 0; + } +} + +bool PanelWidget::event(QEvent* event) { + if (event->type() == QEvent::Type::HoverMove) { + auto hoverEvent = static_cast(event); + if (this->resizingActive || this->isPositionWithinHandleArea(hoverEvent->position().toPoint())) { + this->setCursor(this->resizeCursor); + + } else { + this->setCursor(Qt::ArrowCursor); + } + } + + return QFrame::event(event); +} + +void PanelWidget::mouseMoveEvent(QMouseEvent* event) { + const auto position = event->pos(); + + if (this->resizingActive) { + if (this->panelType == PanelWidgetType::LEFT) { + this->setFixedWidth( + std::max( + this->minimumResize, + std::min(this->maximumResize, position.x() + this->resizingOffset) + ) + ); + + } else if (this->panelType == PanelWidgetType::BOTTOM) { + this->setFixedHeight( + std::max( + this->minimumResize, + std::min(this->maximumResize, this->height() + (-position.y()) + this->resizingOffset) + ) + ); + } + } +} + +std::pair PanelWidget::getHandleArea() const { + const auto currentSize = this->size(); + + if (this->panelType == PanelWidgetType::LEFT) { + return std::pair( + QPoint(currentSize.width() - this->handleSize, 0), + QPoint(currentSize.width(), currentSize.height()) + ); + + } else { + return std::pair( + QPoint(0, 0), + QPoint(currentSize.width(), this->handleSize) + ); + } +} + +bool PanelWidget::isPositionWithinHandleArea(const QPoint& position) const { + const auto handleArea = this->getHandleArea(); + + return ( + position.x() >= handleArea.first.x() && position.x() <= handleArea.second.x() + && position.y() >= handleArea.first.y() && position.y() <= handleArea.second.y() + ); +} diff --git a/src/Insight/UserInterfaces/InsightWindow/Widgets/PanelWidget.hpp b/src/Insight/UserInterfaces/InsightWindow/Widgets/PanelWidget.hpp new file mode 100644 index 00000000..fd4df456 --- /dev/null +++ b/src/Insight/UserInterfaces/InsightWindow/Widgets/PanelWidget.hpp @@ -0,0 +1,77 @@ +#pragma once + +#include +#include +#include +#include +#include + +namespace Bloom::Widgets +{ + Q_NAMESPACE + + enum class PanelWidgetType: int + { + LEFT, + BOTTOM, + }; + Q_ENUM_NS(PanelWidgetType) + + class Q_WIDGETS_EXPORT PanelWidget: public QFrame + { + Q_OBJECT + Q_PROPERTY(int handleSize READ getHandleSize WRITE setHandleSize DESIGNABLE true) + Q_PROPERTY(int minimumResize READ getMinimumResize WRITE setMinimumResize DESIGNABLE true) + Q_PROPERTY(Bloom::Widgets::PanelWidgetType panelType READ getPanelType WRITE setPanelType DESIGNABLE true) + + protected: + int handleSize = 10; + int minimumResize = 10; + int maximumResize = 500; + + PanelWidgetType panelType = PanelWidgetType::LEFT; + QCursor resizeCursor = Qt::SplitHCursor; + bool resizingActive = false; + int resizingOffset = 0; + + void mousePressEvent(QMouseEvent* event) override; + void mouseReleaseEvent(QMouseEvent* event) override; + bool event(QEvent* event) override; + void mouseMoveEvent(QMouseEvent* event) override; + + std::pair getHandleArea() const; + bool isPositionWithinHandleArea(const QPoint& position) const; + + public: + explicit PanelWidget(QWidget* parent); + + void setHandleSize(int handleSize) { + this->handleSize = handleSize; + } + + void setMinimumResize(int minimumResize); + + void setMaximumResize(int maximumResize); + + void setPanelType(PanelWidgetType panelType) { + this->panelType = panelType; + this->resizeCursor = this->panelType == PanelWidgetType::LEFT ? Qt::SplitHCursor : Qt::SplitVCursor; + } + + int getHandleSize() { + return this->handleSize; + } + + int getMinimumResize() { + return this->minimumResize; + } + + int getMaximumResize() { + return this->maximumResize; + } + + PanelWidgetType getPanelType() { + return this->panelType; + } + }; +}