/****************************************************************************** * The MIT License (MIT) * * Copyright (c) 2019-2021 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 | QStyle::SC_GroupBoxLabel)) { setCollapsed(!m_collapsed); } }