File indexing completed on 2024-12-22 04:13:15
0001 /* 0002 * SPDX-FileCopyrightText: 2011 Silvio Heinrich <plassy@web.de> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "kis_widget_chooser.h" 0008 0009 #include <kis_icon.h> 0010 0011 #include <QGridLayout> 0012 #include <QHBoxLayout> 0013 #include <QToolButton> 0014 #include <QApplication> 0015 #include <QDesktopWidget> 0016 #include <QFrame> 0017 #include <QLabel> 0018 #include <QButtonGroup> 0019 #include <QStylePainter> 0020 #include <QStyleOption> 0021 0022 #include "kis_config.h" 0023 0024 KisWidgetChooser::KisWidgetChooser(int id, QWidget* parent) 0025 : QFrame(parent) 0026 , m_chooserid(id) 0027 { 0028 m_acceptIcon = KisIconUtils::loadIcon("list-add"); 0029 m_buttons = new QButtonGroup(); 0030 m_popup = new QFrame(0, Qt::Popup); 0031 m_arrowButton = new QToolButton(); 0032 0033 m_popup->setFrameStyle(QFrame::Panel|QFrame::Raised); 0034 m_arrowButton->setFixedWidth(m_arrowButton->sizeHint().height()); 0035 m_arrowButton->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); 0036 m_arrowButton->setAutoRaise(true); 0037 updateArrowIcon(); 0038 0039 connect(m_arrowButton, SIGNAL(clicked(bool)), SLOT(slotButtonPressed())); 0040 } 0041 0042 KisWidgetChooser::~KisWidgetChooser() 0043 { 0044 delete m_buttons; 0045 delete m_popup; 0046 delete m_arrowButton; 0047 } 0048 0049 void KisWidgetChooser::updateArrowIcon() 0050 { 0051 QImage image(16, 16, QImage::Format_ARGB32); 0052 image.fill(0); 0053 0054 QStylePainter painter(&image, this); 0055 QStyleOption option; 0056 0057 option.rect = image.rect(); 0058 option.palette = palette(); 0059 option.state = QStyle::State_Enabled; 0060 option.palette.setBrush(QPalette::ButtonText, option.palette.text()); 0061 0062 painter.setBrush(option.palette.text().color()); 0063 painter.setPen(option.palette.text().color()); 0064 painter.drawPrimitive(QStyle::PE_IndicatorArrowDown, option); 0065 painter.end(); // Otherwise there will always be a copy 0066 0067 m_arrowButton->setIcon(QIcon(QPixmap::fromImage(image))); 0068 } 0069 0070 void KisWidgetChooser::addLabelWidget(const QString& id, const QString& label, QWidget* widget) 0071 { 0072 removeWidget(id); 0073 0074 if (label.isEmpty()) { 0075 m_widgets.push_back(Data(id, widget, 0)); 0076 } 0077 else { 0078 m_widgets.push_back(Data(id, widget, new QLabel(label))); 0079 } 0080 0081 delete m_popup->layout(); 0082 m_popup->setLayout(createPopupLayout()); 0083 m_popup->adjustSize(); 0084 0085 delete QWidget::layout(); 0086 QWidget::setLayout(createLayout()); 0087 } 0088 0089 QLayout* KisWidgetChooser::createLayout() 0090 { 0091 QHBoxLayout* layout = new QHBoxLayout(); 0092 layout->setContentsMargins(0, 0, 0, 0); 0093 layout->setSpacing(0); 0094 layout->addWidget(m_arrowButton); 0095 0096 for(Iterator i=m_widgets.begin(); i!=m_widgets.end(); ++i) { 0097 if(i->chosen) { 0098 if (i->label) { 0099 layout->addWidget(i->label); 0100 } 0101 layout->addWidget(i->widget); 0102 break; 0103 } 0104 } 0105 return layout; 0106 } 0107 0108 QLayout* KisWidgetChooser::createPopupLayout() 0109 { 0110 QGridLayout* layout = new QGridLayout(); 0111 int row = 0; 0112 int idx = 0; 0113 0114 layout->setContentsMargins(0, 0, 0, 0); 0115 layout->setSpacing(0); 0116 0117 QButtonGroup* group = new QButtonGroup(); 0118 QList<QAbstractButton*> buttons = m_buttons->buttons(); 0119 0120 for(Iterator i=m_widgets.begin(); i!=m_widgets.end(); ++i) { 0121 if(!i->chosen) { 0122 if(row == buttons.size()) { 0123 QToolButton* bn = new QToolButton(); 0124 0125 m_acceptIcon = KisIconUtils::loadIcon("list-add"); 0126 bn->setIcon(m_acceptIcon); 0127 bn->setAutoRaise(true); 0128 buttons.push_back(bn); 0129 } 0130 0131 if (i->label) { 0132 layout->addWidget(i->label , row, 0); 0133 layout->addWidget(i->widget , row, 1); 0134 layout->addWidget(buttons[row], row, 2); 0135 } 0136 else { 0137 layout->addWidget(i->widget , row, 0); 0138 layout->addWidget(buttons[row], row, 1); 0139 } 0140 group->addButton(buttons[row], idx); 0141 ++row; 0142 } 0143 0144 ++idx; 0145 } 0146 0147 for(int i=row; i<buttons.size(); ++i) 0148 delete buttons[i]; 0149 0150 delete m_buttons; 0151 0152 m_buttons = group; 0153 connect(m_buttons, SIGNAL(buttonClicked(int)), SLOT(slotWidgetChosen(int))); 0154 0155 return layout; 0156 } 0157 0158 void KisWidgetChooser::removeWidget(const QString& id) 0159 { 0160 Iterator data = std::find(m_widgets.begin(), m_widgets.end(), Data(id)); 0161 0162 if(data != m_widgets.end()) { 0163 if(!data->chosen) { 0164 delete m_popup->layout(); 0165 m_popup->setLayout(createPopupLayout()); 0166 m_popup->adjustSize(); 0167 } 0168 else delete QWidget::layout(); 0169 0170 if (data->label) { 0171 delete data->label; 0172 } 0173 delete data->widget; 0174 m_widgets.erase(data); 0175 } 0176 } 0177 0178 QWidget* KisWidgetChooser::chooseWidget(const QString& id) 0179 { 0180 QWidget* chosenWidget = 0; 0181 0182 for(Iterator i=m_widgets.begin(); i!=m_widgets.end(); ++i) { 0183 if(i->id == id) { 0184 chosenWidget = i->widget; 0185 i->chosen = true; 0186 } 0187 else i->chosen = false; 0188 } 0189 0190 delete m_popup->layout(); 0191 m_popup->setLayout(createPopupLayout()); 0192 m_popup->adjustSize(); 0193 0194 delete QWidget::layout(); 0195 QWidget::setLayout(createLayout()); 0196 0197 KisConfig cfg(false); 0198 cfg.setToolbarSlider(m_chooserid, id); 0199 0200 return chosenWidget; 0201 } 0202 0203 QWidget* KisWidgetChooser::getWidget(const QString& id) const 0204 { 0205 ConstIterator data = std::find(m_widgets.begin(), m_widgets.end(), Data(id)); 0206 0207 if(data != m_widgets.end()) 0208 return data->widget; 0209 0210 return 0; 0211 } 0212 0213 void KisWidgetChooser::showPopupWidget() 0214 { 0215 QSize popSize = m_popup->size(); 0216 QRect popupRect(QFrame::mapToGlobal(QPoint(-1, QFrame::height())), popSize); 0217 0218 // Get the available geometry of the screen which contains this KisPopupButton 0219 QRect screenRect = QApplication::desktop()->availableGeometry(this); 0220 0221 // Make sure the popup is not drawn outside the screen area 0222 if(popupRect.right() > screenRect.right()) 0223 popupRect.translate(screenRect.right() - popupRect.right(), 0); 0224 if(popupRect.left() < screenRect.left()) 0225 popupRect.translate(screenRect.left() - popupRect.left(), 0); 0226 if(popupRect.bottom() > screenRect.bottom()) 0227 popupRect.translate(0, -popupRect.height()); 0228 0229 m_popup->setGeometry(popupRect); 0230 m_popup->show(); 0231 } 0232 0233 0234 void KisWidgetChooser::updateThemedIcons() 0235 { 0236 for (int i = 0; i < m_buttons->buttons().length(); i++) { 0237 if ( m_buttons->button(i)) { 0238 m_buttons->button(i)->setIcon(KisIconUtils::loadIcon("list-add")); 0239 } 0240 } 0241 } 0242 0243 void KisWidgetChooser::slotButtonPressed() 0244 { 0245 showPopupWidget(); 0246 } 0247 0248 void KisWidgetChooser::slotWidgetChosen(int index) 0249 { 0250 chooseWidget(m_widgets[index].id); 0251 m_popup->hide(); 0252 } 0253 0254 0255 void KisWidgetChooser::changeEvent(QEvent *e) 0256 { 0257 QFrame::changeEvent(e); 0258 0259 switch (e->type()) { 0260 case QEvent::StyleChange: 0261 case QEvent::PaletteChange: 0262 case QEvent::EnabledChange: 0263 updateArrowIcon(); 0264 break; 0265 default: 0266 ; 0267 } 0268 }