From 4ab61286e438a5a391795caf534191d4566b92c9 Mon Sep 17 00:00:00 2001 From: Dimitris Kapnopoulos Date: Mon, 13 Mar 2017 18:00:44 +0200 Subject: [PATCH] Added custom Splitter class, RDSplitter, with titles in the handles --- qrenderdoc/Widgets/Extended/RDSplitter.cpp | 199 +++++++++++++++++++++ qrenderdoc/Widgets/Extended/RDSplitter.h | 78 ++++++++ qrenderdoc/Windows/APIInspector.cpp | 7 +- qrenderdoc/Windows/APIInspector.ui | 12 +- qrenderdoc/qrenderdoc.pro | 6 +- 5 files changed, 297 insertions(+), 5 deletions(-) create mode 100644 qrenderdoc/Widgets/Extended/RDSplitter.cpp create mode 100644 qrenderdoc/Widgets/Extended/RDSplitter.h diff --git a/qrenderdoc/Widgets/Extended/RDSplitter.cpp b/qrenderdoc/Widgets/Extended/RDSplitter.cpp new file mode 100644 index 000000000..9072a24bc --- /dev/null +++ b/qrenderdoc/Widgets/Extended/RDSplitter.cpp @@ -0,0 +1,199 @@ +/****************************************************************************** + * The MIT License (MIT) + * + * Copyright (c) 2017 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 "RDSplitter.h" + +#include +#include + +RDSplitterHandle::RDSplitterHandle(Qt::Orientation orientation, QSplitter *parent) + : QSplitterHandle(orientation, parent), m_index(-1), m_isCollapsed(false) +{ +} + +void RDSplitterHandle::setIndex(int index) +{ + m_index = index; +} + +int RDSplitterHandle::index() const +{ + return m_index; +} + +void RDSplitterHandle::setTitle(const QString &title) +{ + m_title = title; +} + +const QString &RDSplitterHandle::title() const +{ + return m_title; +} + +void RDSplitterHandle::setCollapsed(bool collapsed) +{ + m_isCollapsed = collapsed; +} + +bool RDSplitterHandle::collapsed() const +{ + return m_isCollapsed; +} + +void RDSplitterHandle::paintEvent(QPaintEvent *event) +{ + QPainter painter(this); + painter.setPen(Qt::black); + painter.setBrush(Qt::SolidPattern); + + int w = width(); + int h = height(); + + if(orientation() == Qt::Vertical) + { + painter.drawText(QRect(0, 0, w, 25), Qt::AlignHCenter, m_title); + } + else + { + painter.drawText(QRect(0, h / 2 - 12, w, 25), Qt::AlignHCenter, m_title); + } + + painter.setRenderHint(QPainter::Antialiasing, true); + + // draw the arrow + if(orientation() == Qt::Vertical) + { + if(m_isCollapsed) + { + m_arrowPoints[0] = QPoint(w / 2, h - 9); + m_arrowPoints[1] = QPoint(w / 2 - 10, h - 1); + m_arrowPoints[2] = QPoint(w / 2 + 10, h - 1); + } + else + { + m_arrowPoints[0] = QPoint(w / 2, h - 1); + m_arrowPoints[1] = QPoint(w / 2 - 10, h - 9); + m_arrowPoints[2] = QPoint(w / 2 + 10, h - 9); + } + } + else + { + if(m_isCollapsed) + { + m_arrowPoints[0] = QPoint(w - 9, h / 2 + 15); + m_arrowPoints[1] = QPoint(w - 1, h / 2 + 5); + m_arrowPoints[2] = QPoint(w - 1, h / 2 + 20); + } + else + { + m_arrowPoints[0] = QPoint(w - 1, h / 2 + 15); + m_arrowPoints[1] = QPoint(w - 9, h / 2 + 5); + m_arrowPoints[2] = QPoint(w - 9, h / 2 + 25); + } + } + + painter.drawPolygon(m_arrowPoints, 3); + + // draw the bullets + if(orientation() == Qt::Vertical) + { + painter.drawEllipse(QPoint(w / 4 - 10, h - 10), 3, 3); + painter.drawEllipse(QPoint(w / 4, h - 10), 3, 3); + painter.drawEllipse(QPoint(w / 4 + 10, h - 10), 3, 3); + + painter.drawEllipse(QPoint(3 * w / 4 - 10, h - 10), 3, 3); + painter.drawEllipse(QPoint(3 * w / 4, h - 10), 3, 3); + painter.drawEllipse(QPoint(3 * w / 4 + 10, h - 10), 3, 3); + } + else + { + painter.drawEllipse(QPoint(w - 10, h / 4 - 10), 3, 3); + painter.drawEllipse(QPoint(w - 10, h / 4), 3, 3); + painter.drawEllipse(QPoint(w - 10, h / 4 + 10), 3, 3); + + painter.drawEllipse(QPoint(w - 10, 3 * h / 4 - 10), 3, 3); + painter.drawEllipse(QPoint(w - 10, 3 * h / 4), 3, 3); + painter.drawEllipse(QPoint(w - 10, 3 * h / 4 + 10), 3, 3); + } +} + +void RDSplitterHandle::mouseDoubleClickEvent(QMouseEvent *event) +{ + RDSplitter *par = (RDSplitter *)splitter(); + par->handleDoubleClicked(m_index); +} + +RDSplitter::RDSplitter(Qt::Orientation orientation, QWidget *parent) + : QSplitter(orientation, parent) +{ + initialize(); +} + +RDSplitter::RDSplitter(QWidget *parent) : QSplitter(parent) +{ + initialize(); +} + +void RDSplitter::handleDoubleClicked(int index) +{ + RDSplitterHandle *rdHandle = (RDSplitterHandle *)handle(index); + QList totalSizes = sizes(); + if(totalSizes[index] > 0) + { + // add to the previous handle the size of the current one + totalSizes[index - 1] += totalSizes[index]; + // set the current handle's size to 0 + totalSizes[index] = 0; + rdHandle->setCollapsed(true); + } + else + { + // split the sizes in half + int s = totalSizes[index - 1] / 2; + totalSizes[index] = totalSizes[index - 1] = s; + rdHandle->setCollapsed(false); + } + setSizes(totalSizes); +} + +void RDSplitter::setHandleCollapsed(int pos, int index) +{ + QList totalSizes = sizes(); + RDSplitterHandle *rdHandle = (RDSplitterHandle *)handle(index); + if(totalSizes[index] == 0) + rdHandle->setCollapsed(true); + else + rdHandle->setCollapsed(false); +} + +void RDSplitter::initialize() +{ + connect(this, &RDSplitter::splitterMoved, this, &RDSplitter::setHandleCollapsed); +} + +QSplitterHandle *RDSplitter::createHandle() +{ + return new RDSplitterHandle(orientation(), this); +} diff --git a/qrenderdoc/Widgets/Extended/RDSplitter.h b/qrenderdoc/Widgets/Extended/RDSplitter.h new file mode 100644 index 000000000..1f598f452 --- /dev/null +++ b/qrenderdoc/Widgets/Extended/RDSplitter.h @@ -0,0 +1,78 @@ +/****************************************************************************** + * The MIT License (MIT) + * + * Copyright (c) 2017 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 +#include + +// a splitter handle. +// it draws a text as the title and an arrow indicating if it's collapsed +// You need to set a title and its index. +class RDSplitterHandle : public QSplitterHandle +{ + Q_OBJECT + +public: + RDSplitterHandle(Qt::Orientation orientation, QSplitter *parent); + + void setIndex(int index); + int index() const; + + void setTitle(const QString &title); + const QString &title() const; + + void setCollapsed(bool collapsed); + bool collapsed() const; + +protected: + virtual void paintEvent(QPaintEvent *event); + virtual void mouseDoubleClickEvent(QMouseEvent *event); + + QString m_title; + int m_index; + bool m_isCollapsed; + QPoint m_arrowPoints[3]; +}; + +// A Splitter that contains RDSplitterHandles +// when setting up, you need to get the handles for every index +// and set their title as well as their indexes +class RDSplitter : public QSplitter +{ + Q_OBJECT + +public: + RDSplitter(QWidget *parent = 0); + RDSplitter(Qt::Orientation orientation, QWidget *parent = 0); + + void handleDoubleClicked(int index); + +protected slots: + void setHandleCollapsed(int pos, int index); + +protected: + void initialize(); + virtual QSplitterHandle *createHandle(); +}; diff --git a/qrenderdoc/Windows/APIInspector.cpp b/qrenderdoc/Windows/APIInspector.cpp index 903da6984..0f50c9648 100644 --- a/qrenderdoc/Windows/APIInspector.cpp +++ b/qrenderdoc/Windows/APIInspector.cpp @@ -39,6 +39,11 @@ APIInspector::APIInspector(CaptureContext &ctx, QWidget *parent) ui->splitter->setCollapsible(1, true); ui->splitter->setSizes({1, 0}); + RDSplitterHandle *handle = (RDSplitterHandle *)ui->splitter->handle(1); + handle->setTitle("Callstack"); + handle->setIndex(1); + handle->setCollapsed(true); + m_Ctx.AddLogViewer(this); } @@ -167,4 +172,4 @@ void APIInspector::fillAPIView() } } ui->apiEvents->setUpdatesEnabled(true); -} \ No newline at end of file +} diff --git a/qrenderdoc/Windows/APIInspector.ui b/qrenderdoc/Windows/APIInspector.ui index d1f2eeefa..4b1c74da2 100644 --- a/qrenderdoc/Windows/APIInspector.ui +++ b/qrenderdoc/Windows/APIInspector.ui @@ -30,12 +30,12 @@ 0 - + Qt::Vertical - 16 + 27 @@ -85,6 +85,14 @@ + + + RDSplitter + QSplitter +
Widgets/Extended/RDSplitter.h
+ 1 +
+
diff --git a/qrenderdoc/qrenderdoc.pro b/qrenderdoc/qrenderdoc.pro index 52324bd04..f3cac95f1 100644 --- a/qrenderdoc/qrenderdoc.pro +++ b/qrenderdoc/qrenderdoc.pro @@ -162,7 +162,8 @@ SOURCES += Code/qrenderdoc.cpp \ Windows/PixelHistoryView.cpp \ Widgets/PipelineFlowChart.cpp \ Windows/Dialogs/EnvironmentEditor.cpp \ - Widgets/FindReplace.cpp + Widgets/FindReplace.cpp \ + Widgets/Extended/RDSplitter.cpp HEADERS += Code/CaptureContext.h \ Code/qprocessinfo.h \ @@ -213,7 +214,8 @@ HEADERS += Code/CaptureContext.h \ Windows/PixelHistoryView.h \ Widgets/PipelineFlowChart.h \ Windows/Dialogs/EnvironmentEditor.h \ - Widgets/FindReplace.h + Widgets/FindReplace.h \ + Widgets/Extended/RDSplitter.h FORMS += Windows/Dialogs/AboutDialog.ui \ Windows/MainWindow.ui \