File indexing completed on 2024-05-19 15:44:20
0001 /* 0002 SPDX-FileCopyrightText: 2007 Roberto Raggi <roberto@kdevelop.org> 0003 SPDX-FileCopyrightText: 2007 Hamish Rodda <rodda@kde.org> 0004 SPDX-FileCopyrightText: 2011 Alexander Dymo <adymo@kdevelop.org> 0005 SPDX-FileCopyrightText: 2018 Amish Naidu <amhndu@gmail.com> 0006 0007 SPDX-License-Identifier: LicenseRef-MIT-KDevelop-Ideal 0008 */ 0009 0010 #include "idealtoolbutton.h" 0011 #include <KAcceleratorManager> 0012 #include <QStyleOption> 0013 #include <QStylePainter> 0014 #include <QApplication> 0015 0016 IdealToolButton::IdealToolButton(Qt::DockWidgetArea area, QWidget *parent) 0017 : QToolButton(parent), _area(area) 0018 { 0019 setFocusPolicy(Qt::NoFocus); 0020 KAcceleratorManager::setNoAccel(this); 0021 setCheckable(true); 0022 setAutoRaise(true); 0023 setToolButtonStyle(Qt::ToolButtonTextBesideIcon); 0024 0025 setContextMenuPolicy(Qt::CustomContextMenu); 0026 0027 QSizePolicy sizePolicy = this->sizePolicy(); 0028 if (orientation() == Qt::Horizontal) { 0029 sizePolicy.setHorizontalPolicy(QSizePolicy::Maximum); 0030 } else { 0031 sizePolicy.setVerticalPolicy(QSizePolicy::Maximum); 0032 } 0033 setSizePolicy(sizePolicy); 0034 } 0035 0036 Qt::Orientation IdealToolButton::orientation() const 0037 { 0038 if (_area == Qt::LeftDockWidgetArea || _area == Qt::RightDockWidgetArea) 0039 return Qt::Vertical; 0040 0041 return Qt::Horizontal; 0042 } 0043 0044 QSize IdealToolButton::sizeHint() const 0045 { 0046 ensurePolished(); 0047 0048 QStyleOptionToolButton opt; 0049 initStyleOption(&opt); 0050 0051 QFontMetrics fm = fontMetrics(); 0052 0053 const int charWidth = fm.horizontalAdvance(QLatin1Char('x')); 0054 QSize textSize; 0055 // Use text size only if we request text 0056 if (toolButtonStyle() != Qt::ToolButtonIconOnly || opt.icon.isNull()) { 0057 textSize = fm.size(Qt::TextShowMnemonic, opt.text); 0058 textSize.rwidth() += 2 * charWidth; 0059 } 0060 0061 int iconwidth = 0, iconheight = 0; 0062 // Use icon size only if it's requested and the icon is valid 0063 if (toolButtonStyle() != Qt::ToolButtonTextOnly && !opt.icon.isNull()) { 0064 if (_area == Qt::TopDockWidgetArea || _area == Qt::BottomDockWidgetArea) { 0065 iconwidth = opt.iconSize.width(); 0066 iconheight = opt.iconSize.height(); 0067 } else { 0068 iconwidth = opt.iconSize.height(); 0069 iconheight = opt.iconSize.width(); 0070 } 0071 } 0072 // adding +4 to be consistent with qtoolbutton 0073 int width = textSize.width() + iconwidth + 4; 0074 int height = qMax(textSize.height(), iconheight); 0075 QSize size = style()->sizeFromContents(QStyle::CT_ToolButton, &opt, QSize(width, height), this); 0076 0077 if (orientation() == Qt::Vertical) { 0078 return QSize(size.height(), size.width()); // transposed 0079 } else { 0080 return size; 0081 } 0082 } 0083 0084 QSize IdealToolButton::minimumSizeHint() const 0085 { 0086 ensurePolished(); 0087 0088 QStyleOptionToolButton opt; 0089 initStyleOption(&opt); 0090 0091 QSize minimumSize; 0092 // if style has icons, minimumSize is the size of the icon 0093 if (toolButtonStyle() != Qt::ToolButtonTextOnly && !opt.icon.isNull()) { 0094 minimumSize = opt.iconSize; 0095 if (_area == Qt::LeftDockWidgetArea || _area == Qt::RightDockWidgetArea) { 0096 minimumSize.transpose(); 0097 } 0098 } else { 0099 // if no icon, set an arbitrary minimum size 0100 QFontMetrics fm = fontMetrics(); 0101 minimumSize = fm.size(Qt::TextShowMnemonic, opt.text.left(4)); 0102 } 0103 0104 minimumSize = style()->sizeFromContents(QStyle::CT_ToolButton, &opt, minimumSize, this); 0105 0106 if (_area == Qt::TopDockWidgetArea || _area == Qt::BottomDockWidgetArea) { 0107 return minimumSize; 0108 } 0109 return minimumSize.transposed(); 0110 } 0111 0112 0113 void IdealToolButton::paintEvent(QPaintEvent *event) 0114 { 0115 Q_UNUSED(event); 0116 0117 QStylePainter painter(this); 0118 QStyleOptionToolButton option; 0119 initStyleOption(&option); 0120 0121 if (_area == Qt::TopDockWidgetArea || _area == Qt::BottomDockWidgetArea) { 0122 // elide text 0123 int iconWidth = 0; 0124 if (toolButtonStyle() != Qt::ToolButtonTextOnly && !option.icon.isNull()) { 0125 iconWidth = option.iconSize.width(); 0126 } 0127 0128 // subtract 4 to be consistent with the size calculated by sizeHint, which adds 4, 0129 // again to be consistent with QToolButton 0130 option.text = fontMetrics().elidedText(text(), Qt::ElideRight, contentsRect().width() - iconWidth - 4); 0131 painter.drawComplexControl(QStyle::CC_ToolButton, option); 0132 } else { 0133 // rotated paint 0134 // elide text 0135 int iconHeight = 0; 0136 if (toolButtonStyle() != Qt::ToolButtonTextOnly && !option.icon.isNull()) { 0137 iconHeight = option.iconSize.height(); 0138 } 0139 QString textToDraw = fontMetrics().elidedText(text(), Qt::ElideRight, contentsRect().height() - iconHeight - 4); 0140 // first draw normal frame and not text/icon 0141 option.text = QString(); 0142 option.icon = QIcon(); 0143 painter.drawComplexControl(QStyle::CC_ToolButton, option); 0144 0145 // rotate the options 0146 QSize size( option.rect.size() ); 0147 size.transpose(); 0148 option.rect.setSize( size ); 0149 0150 // rotate the painter 0151 if(_area == Qt::LeftDockWidgetArea) { 0152 painter.translate( 0, height() ); 0153 painter.rotate( -90 ); 0154 } else { 0155 painter.translate( width(), 0 ); 0156 painter.rotate( 90 ); 0157 } 0158 0159 // paint text and icon 0160 option.text = textToDraw; 0161 0162 QIcon::Mode iconMode = (option.state & QStyle::State_MouseOver) ? QIcon::Active : QIcon::Normal; 0163 QPixmap ic = icon().pixmap(option.iconSize, iconMode, QIcon::On); 0164 QTransform tf; 0165 if(_area == Qt::LeftDockWidgetArea) { 0166 tf.rotate(90); 0167 } else { 0168 tf.rotate(-90); 0169 } 0170 option.icon = ic.transformed( tf, Qt::SmoothTransformation ); 0171 painter.drawControl(QStyle::CE_ToolButtonLabel, option); 0172 painter.end(); 0173 } 0174 } 0175 0176 #include "moc_idealtoolbutton.cpp"