Skip to content

Commit

Permalink
Tweak CheckList behavior
Browse files Browse the repository at this point in the history
Fixes #417
  • Loading branch information
Admiral-Fish committed Sep 1, 2024
1 parent 5353bcc commit 82aaca0
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 68 deletions.
105 changes: 58 additions & 47 deletions Source/Form/Controls/CheckList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,32 +25,38 @@
#include <QStandardItemModel>
#include <algorithm>

CheckList::CheckList(QWidget *parent) : QComboBox(parent), model(new QStandardItemModel(this))
CheckList::CheckList(QWidget *parent) : QComboBox(parent)
{
setModel(model);
addItem(tr("Any"));
qobject_cast<QListView *>(view())->setRowHidden(0, true);

setEditable(true);
lineEdit()->setReadOnly(true);
lineEdit()->installEventFilter(this);
setToolTip(tr("Click holding ctrl to reset"));

connect(lineEdit(), &QLineEdit::selectionChanged, lineEdit(), &QLineEdit::deselect);
connect(qobject_cast<QListView *>(view()), &QAbstractItemView::pressed, this, &CheckList::itemPressed);
connect(model, &QAbstractItemModel::dataChanged, this, &CheckList::modelDataChanged);
connect(model(), &QAbstractItemModel::dataChanged, this, &CheckList::modelDataChanged);
connect(this, &CheckList::currentIndexChanged, this, [this] {
if (currentIndex() != 0)
{
setCurrentIndex(0);
}
});
}

std::vector<bool> CheckList::getChecked() const
{
std::vector<bool> result;

auto *m = qobject_cast<QStandardItemModel *>(model());
if (checkState() == Qt::PartiallyChecked)
{
for (int i = 0; i < model->rowCount(); i++)
for (int i = 1; i < m->rowCount(); i++)
{
result.emplace_back(model->item(i)->checkState() == Qt::Checked);
result.emplace_back(m->item(i)->checkState() == Qt::Checked);
}
}
else
{
result = std::vector<bool>(model->rowCount(), true);
result = std::vector<bool>(m->rowCount() - 1, true);
}
return result;
}
Expand All @@ -59,7 +65,7 @@ std::vector<u16> CheckList::getCheckedData() const
{
auto checked = getChecked();
std::vector<u16> data;
for (int i = 0; i < checked.size(); i++)
for (int i = 1; i < checked.size(); i++)
{
if (checked[i])
{
Expand All @@ -71,25 +77,29 @@ std::vector<u16> CheckList::getCheckedData() const

void CheckList::resetChecks()
{
for (auto i = 0; i < model->rowCount(); i++)
auto *m = qobject_cast<QStandardItemModel *>(model());
for (auto i = 1; i < m->rowCount(); i++)
{
model->item(i)->setCheckState(Qt::Unchecked);
m->item(i)->setCheckState(Qt::Unchecked);
}
}

void CheckList::setChecks(const std::vector<bool> &flags)
{
for (size_t i = 0; i < flags.size() && i < model->rowCount(); i++)
auto *m = qobject_cast<QStandardItemModel *>(model());
for (size_t i = 1; i < flags.size() && i < m->rowCount(); i++)
{
model->item(i)->setCheckState(flags[i] ? Qt::Checked : Qt::Unchecked);
m->item(i)->setCheckState(flags[i] ? Qt::Checked : Qt::Unchecked);
}
}

void CheckList::setup(const std::vector<std::string> &items)
{
if (!items.empty())
{
clear();
auto *m = qobject_cast<QStandardItemModel *>(model());
m->removeRows(1, m->rowCount() - 1);

for (const auto &item : items)
{
addItem(QString::fromStdString(item));
Expand All @@ -104,7 +114,9 @@ void CheckList::setup(const std::vector<std::string> &items, const std::vector<u
assert(items.size() == data.size());
if (!items.empty())
{
clear();
auto *m = qobject_cast<QStandardItemModel *>(model());
m->removeRows(1, m->rowCount() - 1);

for (int i = 0; i < items.size(); i++)
{
addItem(QString::fromStdString(items[i]), data[i]);
Expand All @@ -114,38 +126,21 @@ void CheckList::setup(const std::vector<std::string> &items, const std::vector<u
setupChecks();
}

bool CheckList::eventFilter(QObject *object, QEvent *event)
{
if (object == lineEdit() && event->type() == QEvent::MouseButtonPress)
{
auto *mouse = reinterpret_cast<QMouseEvent *>(event);
if (mouse->modifiers() == Qt::ControlModifier)
{
resetChecks();
}
else
{
showPopup();
}
return true;
}

return false;
}

Qt::CheckState CheckList::checkState() const
{
int total = model->rowCount();
auto *m = qobject_cast<QStandardItemModel *>(model());

int total = m->rowCount() - 1;
int checked = 0;
int unchecked = 0;

for (int i = 0; i < total; i++)
for (int i = 1; i < total + 1; i++)
{
if (model->item(i)->checkState() == Qt::Checked)
if (m->item(i)->checkState() == Qt::Checked)
{
checked++;
}
else if (model->item(i)->checkState() == Qt::Unchecked)
else if (m->item(i)->checkState() == Qt::Unchecked)
{
unchecked++;
}
Expand All @@ -154,13 +149,27 @@ Qt::CheckState CheckList::checkState() const
return checked == total ? Qt::Checked : unchecked == total ? Qt::Unchecked : Qt::PartiallyChecked;
}

void CheckList::mousePressEvent(QMouseEvent *event)
{
if (event->modifiers() == Qt::ControlModifier)
{
resetChecks();
}
else
{
QComboBox::mousePressEvent(event);
}
}

void CheckList::setupChecks()
{
auto *m = qobject_cast<QStandardItemModel *>(model());

auto font = fontMetrics();
int width = 0;
for (int i = 0; i < model->rowCount(); i++)
for (int i = 1; i < m->rowCount(); i++)
{
QStandardItem *item = model->item(i);
QStandardItem *item = m->item(i);
item->setCheckState(Qt::Unchecked);
item->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled);

Expand All @@ -177,33 +186,35 @@ void CheckList::modelDataChanged()
{
QString text;

auto *m = qobject_cast<QStandardItemModel *>(model());
switch (checkState())
{
case Qt::Checked:
case Qt::Unchecked:
text = tr("Any");
break;
case Qt::PartiallyChecked:
for (int i = 0; i < model->rowCount(); i++)
for (int i = 1; i < m->rowCount(); i++)
{
if (model->item(i)->checkState() == Qt::Checked)
if (m->item(i)->checkState() == Qt::Checked)
{
if (!text.isEmpty())
{
text += ", ";
}

text += model->item(i)->text();
text += m->item(i)->text();
}
}
break;
}

lineEdit()->setText(text);
setItemText(0, text);
}

void CheckList::itemPressed(const QModelIndex &index)
{
QStandardItem *item = model->itemFromIndex(index);
auto *m = qobject_cast<QStandardItemModel *>(model());
QStandardItem *item = m->itemFromIndex(index);
item->setCheckState(item->checkState() == Qt::Checked ? Qt::Unchecked : Qt::Checked);
}
23 changes: 7 additions & 16 deletions Source/Form/Controls/CheckList.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@
#include <Core/Global.hpp>
#include <QComboBox>

class QStandardItemModel;

/**
* @brief Provides a combo box of check boxes
*/
Expand Down Expand Up @@ -110,28 +108,21 @@ class CheckList : public QComboBox
*/
void setup(const std::vector<std::string> &items, const std::vector<u16> &data);

protected:
/**
* @brief Shows the combo box model when clicked
*
* @param object Object that is part of triggered event
* @param event Contains information about the triggered event
*
* @return true Model should be shown
* @return false Model should not be shown
*/
bool eventFilter(QObject *object, QEvent *event) override;

private:
QStandardItemModel *model;

/**
* @brief Determines the check state of the check boxes
*
* @return Checked if all check boxes are checked, PartiallyChecked if some of the check boxes are checked, and Unchecked otherwise
*/
Qt::CheckState checkState() const;

/**
* @brief Handles resetting the check information on ctrl click
*
* @param event Contains mouse event information
*/
void mousePressEvent(QMouseEvent *event) override;

/**
* @brief Setups the model of check boxes to be checkable by the user and sets the minimum width for the popup
*/
Expand Down
6 changes: 1 addition & 5 deletions Source/Form/Controls/Filter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@

#include "Filter.hpp"
#include "ui_Filter.h"
#include <Form/Util/IVCalculator.hpp>
#include <Core/Util/Translator.hpp>
#include <Form/Controls/Controls.hpp>
#include <Form/Util/IVCalculator.hpp>
#include <QMouseEvent>

/**
Expand Down Expand Up @@ -73,10 +73,6 @@ Filter::Filter(QWidget *parent) : QWidget(parent), ui(new Ui::Filter)
ui->checkListNature->setup(Translator::getNatures());
ui->comboBoxShiny->setup({ 255, 1, 2, 3 });

ui->checkListEncounterSlot->setToolTip(tr("Click holding ctrl to reset"));
ui->checkListHiddenPower->setToolTip(tr("Click holding ctrl to reset"));
ui->checkListNature->setToolTip(tr("Click holding ctrl to reset"));

QStringList tips = { tr("Click to clear"), tr("Click holding ctrl to set 31"), tr("Click holding alt to set 30-31"),
tr("Click holding ctrl+alt to set 0") };

Expand Down

0 comments on commit 82aaca0

Please sign in to comment.