Gui: Property editor use a checkbox instead of a combobox for booleans (#21555)
* Gui: property-editor add property copy context menu * Gui: Property editor checkbox brighter border * Gui: Property editor refactor optimize * Gui: Property editor checkbox react to first click and add label * Gui: Property editor remove auto-inserted include * Gui: property-checkbox fix not painting the grid
This commit is contained in:
@@ -29,6 +29,7 @@
|
||||
#include <limits>
|
||||
#include <QApplication>
|
||||
#include <QComboBox>
|
||||
#include <QCheckBox>
|
||||
#include <QFontDatabase>
|
||||
#include <QLocale>
|
||||
#include <QMessageBox>
|
||||
@@ -1376,26 +1377,25 @@ void PropertyBoolItem::setValue(const QVariant& value)
|
||||
|
||||
QWidget* PropertyBoolItem::createEditor(QWidget* parent,
|
||||
const std::function<void()>& method,
|
||||
FrameOption frameOption) const
|
||||
FrameOption /*frameOption*/) const
|
||||
{
|
||||
auto cb = new QComboBox(parent);
|
||||
cb->setFrame(static_cast<bool>(frameOption));
|
||||
cb->addItem(QLatin1String("false"));
|
||||
cb->addItem(QLatin1String("true"));
|
||||
QObject::connect(cb, qOverload<int>(&QComboBox::activated), method);
|
||||
return cb;
|
||||
auto checkbox = new QCheckBox(parent);
|
||||
return checkbox;
|
||||
}
|
||||
|
||||
void PropertyBoolItem::setEditorData(QWidget* editor, const QVariant& data) const
|
||||
{
|
||||
auto cb = qobject_cast<QComboBox*>(editor);
|
||||
cb->setCurrentIndex(cb->findText(data.toString()));
|
||||
if (auto checkbox = qobject_cast<QCheckBox*>(editor)) {
|
||||
checkbox->setChecked(data.toBool());
|
||||
}
|
||||
}
|
||||
|
||||
QVariant PropertyBoolItem::editorData(QWidget* editor) const
|
||||
{
|
||||
auto cb = qobject_cast<QComboBox*>(editor);
|
||||
return {cb->currentText()};
|
||||
if (auto checkbox = qobject_cast<QCheckBox*>(editor)) {
|
||||
return checkbox->isChecked();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
@@ -25,9 +25,11 @@
|
||||
|
||||
#ifndef _PreComp_
|
||||
# include <QApplication>
|
||||
# include <QCheckBox>
|
||||
# include <QComboBox>
|
||||
# include <QModelIndex>
|
||||
# include <QPainter>
|
||||
# include <QTimer>
|
||||
#endif
|
||||
|
||||
#include <Base/Tools.h>
|
||||
@@ -103,7 +105,44 @@ void PropertyItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &
|
||||
|
||||
QPen savedPen = painter->pen();
|
||||
|
||||
QItemDelegate::paint(painter, option, index);
|
||||
if (index.column() == 1 && property && dynamic_cast<PropertyBoolItem*>(property)) {
|
||||
bool checked = index.data(Qt::EditRole).toBool();
|
||||
QStyleOptionButton checkboxOption;
|
||||
if (property->isReadOnly()) {
|
||||
checkboxOption.state |= QStyle::State_ReadOnly;
|
||||
} else {
|
||||
checkboxOption.state |= QStyle::State_Enabled;
|
||||
}
|
||||
checkboxOption.state |= checked ? QStyle::State_On : QStyle::State_Off;
|
||||
// Draw the checkbox
|
||||
checkboxOption.rect = QApplication::style()->subElementRect(QStyle::SE_CheckBoxIndicator, &checkboxOption);
|
||||
int leftSpacing = QApplication::style()->pixelMetric(QStyle::PM_FocusFrameHMargin, nullptr);
|
||||
QRect checkboxRect = QStyle::alignedRect(
|
||||
option.direction, Qt::AlignVCenter,
|
||||
checkboxOption.rect.size(),
|
||||
option.rect.adjusted(leftSpacing, 0, -leftSpacing, 0)
|
||||
);
|
||||
checkboxOption.rect = checkboxRect;
|
||||
QApplication::style()->drawPrimitive(QStyle::PE_IndicatorCheckBox, &checkboxOption, painter);
|
||||
// Draw a bright border on the checkbox to stand out
|
||||
QColor borderColor = QApplication::palette().color(QPalette::BrightText);
|
||||
painter->setPen(borderColor);
|
||||
painter->drawRect(checkboxOption.rect.adjusted(0, 0, -1, -1));
|
||||
// Draw the label of the checkbox
|
||||
QString labelText = checked ? tr("Yes") : tr("No");
|
||||
int spacing = QApplication::style()->pixelMetric(QStyle::PM_CheckBoxLabelSpacing, nullptr);
|
||||
QRect textRect(
|
||||
checkboxOption.rect.right() + spacing,
|
||||
checkboxOption.rect.top(),
|
||||
option.rect.right() - (checkboxOption.rect.right() + spacing),
|
||||
checkboxOption.rect.height()
|
||||
);
|
||||
painter->setPen(option.palette.color(QPalette::Text));
|
||||
painter->drawText(textRect, Qt::AlignVCenter | Qt::AlignLeft, labelText);
|
||||
}
|
||||
else {
|
||||
QItemDelegate::paint(painter, option, index);
|
||||
}
|
||||
|
||||
QColor color = static_cast<QRgb>(QApplication::style()->styleHint(QStyle::SH_Table_GridLineColor, &opt, qobject_cast<QWidget*>(parent())));
|
||||
painter->setPen(QPen(color));
|
||||
@@ -136,6 +175,17 @@ bool PropertyItemDelegate::eventFilter(QObject *o, QEvent *ev)
|
||||
comboBox->showPopup();
|
||||
}
|
||||
}
|
||||
auto *checkBox = qobject_cast<QCheckBox*>(o);
|
||||
if (checkBox) {
|
||||
auto parentEditor = qobject_cast<PropertyEditor*>(this->parent());
|
||||
if (parentEditor && parentEditor->activeEditor == checkBox) {
|
||||
checkBox->toggle();
|
||||
// Delay valueChanged to ensure proper recomputation
|
||||
QTimer::singleShot(0, this, [this]() {
|
||||
valueChanged();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (ev->type() == QEvent::FocusOut) {
|
||||
auto parentEditor = qobject_cast<PropertyEditor*>(this->parent());
|
||||
@@ -233,9 +283,11 @@ void PropertyItemDelegate::valueChanged()
|
||||
if (propertyEditor) {
|
||||
Base::FlagToggler<> flag(changed);
|
||||
Q_EMIT commitData(propertyEditor);
|
||||
auto *comboBox = qobject_cast<QComboBox*>(propertyEditor);
|
||||
if (comboBox) {
|
||||
if (qobject_cast<QComboBox*>(propertyEditor)
|
||||
|| qobject_cast<QCheckBox*>(propertyEditor))
|
||||
{
|
||||
Q_EMIT closeEditor(propertyEditor);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user