diff --git a/qrenderdoc/Widgets/CollapseGroupBox.cpp b/qrenderdoc/Widgets/CollapseGroupBox.cpp new file mode 100644 index 000000000..373b563f1 --- /dev/null +++ b/qrenderdoc/Widgets/CollapseGroupBox.cpp @@ -0,0 +1,136 @@ +/****************************************************************************** + * The MIT License (MIT) + * + * Copyright (c) 2018 Baldur Karlsson + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + ******************************************************************************/ + +#include "CollapseGroupBox.h" +#include +#include +#include + +CollapseGroupBox::CollapseGroupBox(QWidget *parent) : QGroupBox(parent) +{ +} + +CollapseGroupBox::~CollapseGroupBox() +{ +} + +void CollapseGroupBox::setMaximumSize(const QSize &size) +{ + // if collapsed, silently update the 'original' max height for when we un-collapse. Otherwise + // forward the call + if(m_collapsed) + { + m_prevMaxHeight = size.height(); + QGroupBox::setMaximumSize(QSize(size.width(), maximumHeight())); + } + else + { + QGroupBox::setMaximumSize(size); + } +} + +void CollapseGroupBox::setMaximumHeight(int maxh) +{ + // if collapsed, silently update the 'original' max height for when we un-collapse. Otherwise + // forward the call + if(m_collapsed) + m_prevMaxHeight = maxh; + else + QGroupBox::setMaximumHeight(maxh); +} + +void CollapseGroupBox::setCollapsed(bool coll) +{ + // redundant call + if(m_collapsed == coll) + return; + + // if not collapsed, save the current maximum height so we can restore it again and set the + // 'collapsed' maximum height. If we *are* collapsed, then restore the maximum height + if(m_collapsed) + { + QGroupBox::setMaximumHeight(m_prevMaxHeight); + } + else + { + m_prevMaxHeight = maximumHeight(); + + QStyleOptionGroupBox option; + initStyleOption(&option); + + option.subControls |= QStyle::SC_GroupBoxCheckBox; + + QRect contentsRect = + style()->subControlRect(QStyle::CC_GroupBox, &option, QStyle::SC_GroupBoxContents, this); + + QGroupBox::setMaximumHeight(height() - contentsRect.height()); + } + + m_collapsed = coll; + + update(); +} + +void CollapseGroupBox::paintEvent(QPaintEvent *) +{ + QStylePainter paint(this); + QStyleOptionGroupBox option; + initStyleOption(&option); + + // pretend we have a groupbox so the painting allocates space for it + option.subControls |= QStyle::SC_GroupBoxCheckBox; + + paint.drawComplexControl(QStyle::CC_GroupBox, option); + + // now paint over the checkbox + + QRect checkBoxRect = + style()->subControlRect(QStyle::CC_GroupBox, &option, QStyle::SC_GroupBoxCheckBox, this); + + paint.fillRect(checkBoxRect, palette().brush(QPalette::Window)); + + QStyleOption arrowOpt = option; + arrowOpt.rect = checkBoxRect; + paint.drawPrimitive(m_collapsed ? QStyle::PE_IndicatorArrowRight : QStyle::PE_IndicatorArrowDown, + arrowOpt); +} + +void CollapseGroupBox::mouseReleaseEvent(QMouseEvent *event) +{ + if(event->button() != Qt::LeftButton) + { + event->ignore(); + return; + } + + QStyleOptionGroupBox option; + initStyleOption(&option); + + // pretend we have a groupbox so we can hit-test for it + option.subControls |= QStyle::SC_GroupBoxCheckBox; + + if(style()->hitTestComplexControl(QStyle::CC_GroupBox, &option, event->pos(), this) == + QStyle::SC_GroupBoxCheckBox) + setCollapsed(!m_collapsed); +} diff --git a/qrenderdoc/Widgets/CollapseGroupBox.h b/qrenderdoc/Widgets/CollapseGroupBox.h new file mode 100644 index 000000000..912c447c7 --- /dev/null +++ b/qrenderdoc/Widgets/CollapseGroupBox.h @@ -0,0 +1,52 @@ +/****************************************************************************** + * The MIT License (MIT) + * + * Copyright (c) 2018 Baldur Karlsson + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + ******************************************************************************/ + +#pragma once + +#include + +class CollapseGroupBox : public QGroupBox +{ + Q_OBJECT + +public: + explicit CollapseGroupBox(QWidget *parent = 0); + ~CollapseGroupBox(); + + // not virtual sadly, but at least we can catch code that calls via a CollapseGroupBox* + void setMaximumSize(const QSize &size); + void setMaximumSize(int maxw, int maxh) { setMaximumSize(QSize(maxw, maxh)); } + void setMaximumHeight(int maxh); + + void setCollapsed(bool coll); + bool collapsed() { return m_collapsed; } +protected: + void paintEvent(QPaintEvent *) override; + void mouseReleaseEvent(QMouseEvent *event) override; + +private: + bool m_collapsed = false; + + int m_prevMaxHeight = 0; +}; diff --git a/qrenderdoc/qrenderdoc.pro b/qrenderdoc/qrenderdoc.pro index f8c2069fc..4e182f5da 100644 --- a/qrenderdoc/qrenderdoc.pro +++ b/qrenderdoc/qrenderdoc.pro @@ -193,6 +193,7 @@ SOURCES += Code/qrenderdoc.cpp \ Widgets/ThumbnailStrip.cpp \ Widgets/TextureGoto.cpp \ Widgets/RangeHistogram.cpp \ + Widgets/CollapseGroupBox.cpp \ Windows/Dialogs/TextureSaveDialog.cpp \ Windows/Dialogs/CaptureDialog.cpp \ Windows/Dialogs/LiveCapture.cpp \ @@ -267,6 +268,7 @@ HEADERS += Code/CaptureContext.h \ Widgets/ThumbnailStrip.h \ Widgets/TextureGoto.h \ Widgets/RangeHistogram.h \ + Widgets/CollapseGroupBox.h \ Windows/Dialogs/TextureSaveDialog.h \ Windows/Dialogs/CaptureDialog.h \ Windows/Dialogs/LiveCapture.h \ diff --git a/qrenderdoc/qrenderdoc_local.vcxproj b/qrenderdoc/qrenderdoc_local.vcxproj index 648496a0a..6e2d28a6d 100644 --- a/qrenderdoc/qrenderdoc_local.vcxproj +++ b/qrenderdoc/qrenderdoc_local.vcxproj @@ -621,6 +621,7 @@ + @@ -686,6 +687,7 @@ /bigobj %(AdditionalOptions) + @@ -1083,6 +1085,12 @@ MOC %(Filename).h $(IntDir)generated\moc_%(Filename).cpp + + %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe;%(AdditionalInputs) + "$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe" -DUNICODE -DWIN32 -DWIN64 -D_WIN32 -D_WIN64 -DRENDERDOC_PLATFORM_WIN32 -DSCINTILLA_QT=1 -DSCI_LEXER=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -D_MSC_VER=1900 -I"$(ProjectDir)." -I"$(SolutionDir)\renderdoc\api\replay" -I"$(ProjectDir)3rdparty\qt\$(Platform)\mkspecs/win32-msvc2015" -I"$(ProjectDir)3rdparty\qt\include" -I"$(ProjectDir)3rdparty\qt\include\QtWidgets" -I"$(ProjectDir)3rdparty\qt\include\QtGui" -I"$(ProjectDir)3rdparty\qt\include\QtCore" "%(Fullpath)" -o "$(IntDir)generated\moc_%(Filename).cpp" + MOC %(Filename).h + $(IntDir)generated\moc_%(Filename).cpp + %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe;%(AdditionalInputs) "$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe" -DUNICODE -DWIN32 -DWIN64 -D_WIN32 -D_WIN64 -DRENDERDOC_PLATFORM_WIN32 -DSCINTILLA_QT=1 -DSCI_LEXER=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -D_MSC_VER=1900 -I"$(ProjectDir)." -I"$(SolutionDir)\renderdoc\api\replay" -I"$(ProjectDir)3rdparty\qt\$(Platform)\mkspecs/win32-msvc2015" -I"$(ProjectDir)3rdparty\qt\include" -I"$(ProjectDir)3rdparty\qt\include\QtWidgets" -I"$(ProjectDir)3rdparty\qt\include\QtGui" -I"$(ProjectDir)3rdparty\qt\include\QtCore" "%(Fullpath)" -o "$(IntDir)generated\moc_%(Filename).cpp" diff --git a/qrenderdoc/qrenderdoc_local.vcxproj.filters b/qrenderdoc/qrenderdoc_local.vcxproj.filters index 16ff574f0..aba69aac4 100644 --- a/qrenderdoc/qrenderdoc_local.vcxproj.filters +++ b/qrenderdoc/qrenderdoc_local.vcxproj.filters @@ -706,6 +706,9 @@ Code\Interface + + Widgets + @@ -1057,6 +1060,9 @@ Code\pyrenderdoc + + Widgets +