File indexing completed on 2024-05-19 04:36:39

0001 /* This file is part of the TikZKit project.
0002  *
0003  * Copyright (C) 2014 Dominik Haumann <dhaumann@kde.org>
0004  *
0005  * This library is free software; you can redistribute it and/or modify
0006  * it under the terms of the GNU Library General Public License as published
0007  * by the Free Software Foundation, either version 2 of the License, or
0008  * (at your option) any later version.
0009  *
0010  * This library is distributed in the hope that it will be useful,
0011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0013  * GNU Library General Public License for more details.
0014  *
0015  * You should have received a copy of the GNU Library General Public License
0016  * along with this library; see the file COPYING.LIB.  If not, see
0017  * <http://www.gnu.org/licenses/>.
0018  */
0019 
0020 #include "IconComboBox.h"
0021 
0022 #include <QStyleOptionComboBox>
0023 #include <QStylePainter>
0024 #include <QScreen>
0025 #include <QWindow>
0026 
0027 #include <QDebug>
0028 
0029 IconComboBox::IconComboBox(QWidget *parent)
0030     : QComboBox(parent)
0031 {
0032 }
0033 
0034 QSize IconComboBox::minimumSizeHint() const
0035 {
0036     QSize sh;
0037     QSize is = iconSize();
0038     const QFontMetrics &fm = fontMetrics();
0039 
0040     const int cnt = count();
0041 
0042     for (int i = 0; i < cnt; ++i) {
0043         if (!itemIcon(i).isNull()) {
0044             sh.setWidth(qMax(sh.width(), is.width()));
0045         }
0046     }
0047 
0048     // height
0049     sh.setHeight(qMax(fm.lineSpacing(), 14) + 2);
0050     sh.setHeight(qMax(sh.height(), is.height() + 2));
0051 
0052     // add style and strut values
0053     QStyleOptionComboBox opt;
0054     initStyleOption(&opt);
0055     sh = style()->sizeFromContents(QStyle::CT_ComboBox, &opt, sh, this);
0056     return sh;
0057 }
0058 
0059 QSize IconComboBox::sizeHint() const
0060 {
0061     return minimumSizeHint();
0062 }
0063 
0064 static QRect popupGeometry(QWidget* widget)
0065 {
0066     return widget->window()->windowHandle()->screen()->geometry();
0067 }
0068 
0069 void IconComboBox::showPopup()
0070 {
0071     QComboBox::showPopup();
0072 
0073     // now adapt popup to original QComboBox width
0074     QWidget * popup = findChild<QFrame*>();
0075     popup->resize(QComboBox::sizeHint().width(), popup->height());
0076 
0077     // make sure the popup is on screen
0078     QRect popupRect = popup->rect();
0079     const QRect screen = popupGeometry(this);
0080     const int right = mapToGlobal(popupRect.bottomRight()).x();
0081 
0082     if (right > screen.right()) {
0083         popupRect.moveRight(popupRect.right() - (right - screen.right()));
0084     }
0085     popup->move(mapToGlobal(popupRect.topLeft()).x(), popup->y());
0086 }
0087 
0088 void IconComboBox::paintEvent(QPaintEvent *)
0089 {
0090     QStylePainter painter(this);
0091     painter.setPen(palette().color(QPalette::Text));
0092 
0093     // draw the combobox frame, focusrect and selected etc.
0094     QStyleOptionComboBox opt;
0095     initStyleOption(&opt);
0096     opt.currentText.clear();
0097     painter.drawComplexControl(QStyle::CC_ComboBox, opt);
0098 
0099     // draw the icon and text
0100     painter.drawControl(QStyle::CE_ComboBoxLabel, opt);
0101 }