mirror of
https://github.com/devinacker/bsnes-plus.git
synced 2025-04-02 10:52:46 -04:00
95 lines
3.4 KiB
C++
95 lines
3.4 KiB
C++
#ifndef NALL_QT_CHECKDELEGATE_HPP
|
|
#define NALL_QT_CHECKDELEGATE_HPP
|
|
|
|
namespace nall {
|
|
|
|
class CheckDelegate : public QStyledItemDelegate {
|
|
Q_OBJECT
|
|
|
|
public:
|
|
CheckDelegate(QObject *parent = 0);
|
|
|
|
QWidget* createEditor(QWidget*, const QStyleOptionViewItem&, const QModelIndex&) const;
|
|
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
|
|
bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index);
|
|
|
|
private:
|
|
QRect CheckBoxRect(const QStyleOptionViewItem &view_item_style_options) const;
|
|
|
|
QPixmap pixmapOn, pixmapOff;
|
|
QRect check_box_rect;
|
|
};
|
|
|
|
inline CheckDelegate::CheckDelegate(QObject *parent)
|
|
: QStyledItemDelegate(parent) {
|
|
|
|
// Rendering the checkboxes with native OS style is expensive, so just generate
|
|
// two fixed images representing the two main states of the checkbox
|
|
// and render with those instead
|
|
QCheckBox checkbox;
|
|
QStyleOptionButton check_box_style_option;
|
|
check_box_style_option.initFrom(&checkbox);
|
|
check_box_rect = checkbox.style()->subElementRect(
|
|
QStyle::SE_CheckBoxIndicator, &check_box_style_option, &checkbox);
|
|
|
|
pixmapOff = QPixmap(this->check_box_rect.size());
|
|
pixmapOff.fill(QColor(0, 0, 0, 0));
|
|
checkbox.setChecked(false);
|
|
checkbox.render(&this->pixmapOff, QPoint(), QRegion(), QWidget::DrawChildren);
|
|
|
|
pixmapOn = QPixmap(this->check_box_rect.size());
|
|
pixmapOn.fill(QColor(0, 0, 0, 0));
|
|
checkbox.setChecked(true);
|
|
checkbox.render(&this->pixmapOn, QPoint(), QRegion(), QWidget::DrawChildren);
|
|
}
|
|
|
|
inline QRect CheckDelegate::CheckBoxRect(const QStyleOptionViewItem &option) const {
|
|
QPoint check_box_point(option.rect.x() + option.rect.width() / 2 - this->check_box_rect.width() / 2,
|
|
option.rect.y() + option.rect.height() / 2 - this->check_box_rect.height() / 2);
|
|
return QRect(check_box_point, this->check_box_rect.size());
|
|
}
|
|
|
|
inline QWidget* CheckDelegate::createEditor(QWidget *, const QStyleOptionViewItem &, const QModelIndex &) const {
|
|
return 0;
|
|
}
|
|
|
|
inline void CheckDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const {
|
|
// paint the background
|
|
const QWidget *widget = option.widget;
|
|
QStyle *style = widget ? widget->style() : QApplication::style();
|
|
style->drawControl(QStyle::CE_ItemViewItem, &option, painter, widget);
|
|
|
|
// paint the widget
|
|
QRect rect = CheckBoxRect(option);
|
|
|
|
if (index.model()->data(index, Qt::EditRole).toBool())
|
|
painter->drawPixmap(rect, this->pixmapOn);
|
|
else
|
|
painter->drawPixmap(rect, this->pixmapOff);
|
|
}
|
|
|
|
inline bool CheckDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) {
|
|
if ((event->type() == QEvent::MouseButtonRelease) || (event->type() == QEvent::MouseButtonDblClick)) {
|
|
|
|
QMouseEvent *mouse_event = static_cast<QMouseEvent*>(event);
|
|
if (mouse_event->button() != Qt::LeftButton || !CheckBoxRect(option).contains(mouse_event->pos()))
|
|
return false;
|
|
if (event->type() == QEvent::MouseButtonDblClick)
|
|
return true;
|
|
|
|
} else if (event->type() == QEvent::KeyPress) {
|
|
|
|
QKeyEvent *key_event = static_cast<QKeyEvent*>(event);
|
|
if (key_event->key() != Qt::Key_Space && key_event->key() != Qt::Key_Select)
|
|
return false;
|
|
|
|
} else return false;
|
|
|
|
bool checked = index.model()->data(index, Qt::EditRole).toBool();
|
|
model->setData(index, !checked);
|
|
return true;
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|