Skip to content

Commit

Permalink
Working on flow of data between Qt widgets and models
Browse files Browse the repository at this point in the history
  • Loading branch information
raccog committed Feb 3, 2024
1 parent baf1b7e commit f3951ee
Show file tree
Hide file tree
Showing 5 changed files with 146 additions and 229 deletions.
40 changes: 19 additions & 21 deletions src/sliderulesmodels.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,27 +7,6 @@ namespace Ripes {
ISAEncodingTableModel::ISAEncodingTableModel(QObject *parent)
: QAbstractTableModel(parent) {}

void ISAEncodingTableModel::setFamily(ISAFamily family) {
if (!m_isaInfo || m_isaInfo->isaFamily() != family) {
m_isaInfo = ISAInfoRegistry::getISA(*ISAFamilySets.at(family).begin(),
QStringList());
emit familyChanged(family);
}
}

void ISAEncodingTableModel::setISA(ISA isa) {
if (!m_isaInfo || m_isaInfo->isaID() != isa) {
auto extensions = QStringList();
// NOTE: This assumes that all ISAs within a single family have the same
// supported extensions. Change this logic if that statement is not true.
if (m_isaInfo && m_isaInfo->isaFamily() == ISAFamilies.at(isa)) {
extensions = m_isaInfo->enabledExtensions();
}
m_isaInfo = ISAInfoRegistry::getISA(isa, extensions);
emit isaChanged(isa);
}
}

int ISAEncodingTableModel::rowCount(const QModelIndex &) const { return 1; }

int ISAEncodingTableModel::columnCount(const QModelIndex &) const { return 1; }
Expand All @@ -44,4 +23,23 @@ QVariant ISAEncodingTableModel::data(const QModelIndex &index, int role) const {
return QVariant();
}

void ISAEncodingTableModel::setISAInfo(
std::shared_ptr<const ISAInfoBase> isaInfo) {
bool initialize = m_isaInfo == nullptr;
m_prevIsaInfo = initialize ? isaInfo : m_isaInfo;
m_isaInfo = isaInfo;
if (initialize) {
emit isaInfoInitialized(*m_isaInfo.get());
} else {
emit isaInfoChanged(*m_isaInfo.get(), *m_prevIsaInfo.get());
}
}

void ISAEncodingTableModel::setISAFamily(ISAFamily isaFamily) {
if (m_isaInfo->isaFamily() != isaFamily) {
setISAInfo(ISAInfoRegistry::getISA(*ISAFamilySets.at(isaFamily).begin(),
QStringList()));
}
}

} // namespace Ripes
18 changes: 6 additions & 12 deletions src/sliderulesmodels.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,23 +36,17 @@ class ISAEncodingTableModel : public QAbstractTableModel {
// int role = Qt::DisplayRole) const override;

public slots:
/// Updates the Model and emits `familyChanged()` signal if the model's ISA
/// family has changed.
///
/// This should only be `connect()`ed to UI signals whose function names end
/// in `Activated`. Can also be `connect()`ed to
/// `ProcessorHandler::processorChanged()`.
void setFamily(ISAFamily family);
void setISA(ISA isa);
void setISAInfo(std::shared_ptr<const ISAInfoBase> isaInfo);
void setISAFamily(ISAFamily isaFamily);

signals:
/// Called when the ISA family of the model changes. Use this to update UI.
void familyChanged(ISAFamily family);
/// Called when the ISA of the model changes. Use this to update UI.
void isaChanged(ISA isa);
void isaInfoInitialized(const ISAInfoBase &isaInfo);
void isaInfoChanged(const ISAInfoBase &isaInfo,
const ISAInfoBase &prevISAInfo);

protected:
std::shared_ptr<const ISAInfoBase> m_isaInfo = nullptr;
std::shared_ptr<const ISAInfoBase> m_prevIsaInfo = nullptr;
};

} // namespace Ripes
168 changes: 102 additions & 66 deletions src/sliderulestab.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,95 +6,131 @@

namespace Ripes {

ISAFamilyComboBox::ISAFamilyComboBox(QWidget *parent) : QComboBox(parent) {
for (const auto &p : ISAFamilyNames) {
addItem(p.second, QVariant::fromValue(p.first));
ISAEncodingFilters::ISAEncodingFilters(QWidget *parent) : QFrame(parent) {
setLayout(new QHBoxLayout(this));

auto *isaFamilyFilter = new QFrame(this);
isaFamilyFilter->setLayout(new QVBoxLayout(isaFamilyFilter));
isaFamilyFilter->layout()->addWidget(new QLabel("ISA Family"));
isaFamilyBox = new QComboBox();
for (const auto &familyName : ISAFamilyNames) {
isaFamilyBox->addItem(familyName.second,
QVariant(static_cast<int>(familyName.first)));
}
isaFamilyFilter->layout()->addWidget(isaFamilyBox);
layout()->addWidget(isaFamilyFilter);
connect(isaFamilyBox, &QComboBox::activated, this, [=] {
emit isaFamilyChanged(
static_cast<ISAFamily>(isaFamilyBox->currentData().toInt()));
});

auto *isaFilter = new QFrame(this);
isaFilter->setLayout(new QVBoxLayout(isaFilter));
isaFilter->layout()->addWidget(new QLabel("ISA"));
isaBox = new QComboBox();
isaFilter->layout()->addWidget(isaBox);
layout()->addWidget(isaFilter);

auto *mainExtFilter = new QFrame(this);
mainExtFilter->setLayout(new QVBoxLayout(mainExtFilter));
mainExtFilter->layout()->addWidget(new QLabel("Main Extension"));
mainExtBox = new QComboBox();
mainExtFilter->layout()->addWidget(mainExtBox);
layout()->addWidget(mainExtFilter);
}

void ISAFamilyComboBox::setFamily(ISAFamily family) {
setCurrentIndex(findData(QVariant::fromValue(family)));
emit familyChanged(family);
void ISAEncodingFilters::initializeView(const ISAInfoBase &isaInfo) {
isaBox->clear();
for (const auto &isa : ISAFamilySets.at(isaInfo.isaFamily())) {
isaBox->addItem(ISANames.at(isa), QVariant(static_cast<int>(isa)));
}
isaBox->setCurrentIndex(
isaBox->findData(QVariant(static_cast<int>(isaInfo.isaID()))));

mainExtBox->clear();
for (const auto &ext :
QStringList(isaInfo.baseExtension()) + isaInfo.supportedExtensions()) {
mainExtBox->addItem(ext, ext);
}
}

ISAComboBox::ISAComboBox(QWidget *parent) : QComboBox(parent) {}
void ISAEncodingFilters::updateView(const ISAInfoBase &isaInfo,
const ISAInfoBase &prevISAInfo) {
if (isaInfo.isaFamily() != prevISAInfo.isaFamily()) {
isaFamilyBox->setCurrentIndex(isaFamilyBox->findData(
QVariant(static_cast<int>(isaInfo.isaFamily()))));

void ISAComboBox::setFamily(ISAFamily family) {
ISA prevISA = currentData().value<ISA>();
clear();
for (const auto isa : ISAFamilySets.at(family)) {
addItem(ISANames.at(isa), QVariant::fromValue(isa));
isaBox->clear();
for (const auto &isa : ISAFamilySets.at(isaInfo.isaFamily())) {
isaBox->addItem(ISANames.at(isa), QVariant(static_cast<int>(isa)));
}
}
ISA isa = currentData().value<ISA>();
if (prevISA != isa) {
emit isaChanged(isa);

if (isaInfo.isaID() != prevISAInfo.isaID()) {
isaBox->setCurrentIndex(
isaBox->findData(QVariant(static_cast<int>(isaInfo.isaID()))));
}
}

void ISAComboBox::setISA(ISA isa) {
setCurrentIndex(findData(QVariant::fromValue(isa)));
emit isaChanged(isa);
mainExtBox->clear();
for (const auto &ext :
QStringList(isaInfo.baseExtension()) + isaInfo.supportedExtensions()) {
mainExtBox->addItem(ext, ext);
}
}

ISAEncodingTableView::ISAEncodingTableView(QWidget *parent)
: QTableView(parent) {}

void ISAEncodingTableView::setFamily(ISAFamily family) {
emit familyChanged(family);
}
void ISAEncodingTableView::updateView(const ISAInfoBase &isaInfo,
const ISAInfoBase &prevISAInfo) {}

void ISAEncodingTableView::initializeView(const ISAInfoBase &isaInfo) {}

SliderulesTab::SliderulesTab(QToolBar *toolbar, QWidget *parent)
: RipesTab(toolbar, parent), ui(new Ui::SliderulesTab) {
ui->setupUi(this);

// Set initial model
m_encodingModel = std::make_unique<ISAEncodingTableModel>();
ui->encodingTable->setModel(m_encodingModel.get());

// Helper signals
connect(ui->isaFamilySelector, &QComboBox::activated, ui->isaFamilySelector,
[=](int index) {
emit ui->isaFamilySelector->familyActivated(
static_cast<ISAFamily>(index));
});
connect(ui->isaSelector, &QComboBox::activated, ui->isaSelector,
[=](int index) {
emit ui->isaSelector->isaActivated(static_cast<ISA>(index));
});

// UI -> Model signals
connect(ui->isaFamilySelector, &ISAFamilyComboBox::familyActivated,
m_encodingModel.get(), &ISAEncodingTableModel::setFamily);
connect(ui->isaSelector, &ISAComboBox::isaActivated, m_encodingModel.get(),
&ISAEncodingTableModel::setISA);

// Model -> UI signals
connect(m_encodingModel.get(), &ISAEncodingTableModel::familyChanged,
ui->encodingTable, &ISAEncodingTableView::setFamily);
connect(m_encodingModel.get(), &ISAEncodingTableModel::familyChanged,
ui->isaFamilySelector, &ISAFamilyComboBox::setFamily);
connect(m_encodingModel.get(), &ISAEncodingTableModel::familyChanged,
ui->isaSelector, &ISAComboBox::setFamily);
connect(m_encodingModel.get(), &ISAEncodingTableModel::isaChanged,
ui->isaSelector, &ISAComboBox::setISA);

// Model data changed
connect(m_encodingModel.get(), &ISAEncodingTableModel::familyChanged,
m_encodingModel.get(),
[=] { emit m_encodingModel->layoutChanged(); });
connect(m_encodingModel.get(), &ISAEncodingTableModel::isaChanged,
m_encodingModel.get(),
[=] { emit m_encodingModel->layoutChanged(); });

// Processor changed signal
auto setISAFromProcessor = [=] {
const auto *currentISA = ProcessorHandler::currentISA();
auto isaInfo = ISAInfoRegistry::getISA(currentISA->isaID(),
currentISA->enabledExtensions());
m_encodingModel->setISAInfo(isaInfo);
};

// Initialize the views when the model is initialized
connect(m_encodingModel.get(), &ISAEncodingTableModel::isaInfoInitialized,
this, &SliderulesTab::initializeView);

// Update the views when the model changes
connect(m_encodingModel.get(), &ISAEncodingTableModel::isaInfoChanged, this,
&SliderulesTab::updateView);

// Update the model when the processor is changed
connect(ProcessorHandler::get(), &ProcessorHandler::processorChanged,
m_encodingModel.get(), [=] {
m_encodingModel->setFamily(
ProcessorHandler::currentISA()->isaFamily());
});
m_encodingModel.get(), setISAFromProcessor);

// Update the model when the user changes the filters
connect(ui->encodingFilters, &ISAEncodingFilters::isaFamilyChanged,
m_encodingModel.get(), &ISAEncodingTableModel::setISAFamily);

// Initialize model
setISAFromProcessor();

m_encodingModel->setFamily(ProcessorHandler::currentISA()->isaFamily());
ui->encodingTable->setModel(m_encodingModel.get());
}

SliderulesTab::~SliderulesTab() { delete ui; }

void SliderulesTab::initializeView(const ISAInfoBase &isaInfo) {
ui->encodingFilters->initializeView(isaInfo);
ui->encodingTable->initializeView(isaInfo);
}

void SliderulesTab::updateView(const ISAInfoBase &isaInfo,
const ISAInfoBase &prevISAInfo) {
ui->encodingFilters->updateView(isaInfo, prevISAInfo);
ui->encodingTable->updateView(isaInfo, prevISAInfo);
}

} // namespace Ripes
52 changes: 14 additions & 38 deletions src/sliderulestab.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,44 +18,21 @@ namespace Ui {
class SliderulesTab;
}

class ISAFamilyComboBox : public QComboBox {
class ISAEncodingFilters : public QFrame {
Q_OBJECT
public:
ISAFamilyComboBox(QWidget *parent = nullptr);
ISAEncodingFilters(QWidget *parent = nullptr);

ISAFamily currentFamily() const { return currentData().value<ISAFamily>(); }

public slots:
/// Updates the UI and emits `familyChanged()` signal.
void setFamily(ISAFamily family);
QComboBox *isaFamilyBox;
QComboBox *isaBox;
QComboBox *mainExtBox;

signals:
/// Called when the family is changed in the UI directly by the user.
void familyActivated(ISAFamily family);
/// Called when any time the family is changed, including during
/// `setFamily()`.
void familyChanged(ISAFamily family);
};

class ISAComboBox : public QComboBox {
Q_OBJECT
public:
ISAComboBox(QWidget *parent = nullptr);

ISA currentISA() const { return currentData().value<ISA>(); }
void isaFamilyChanged(ISAFamily isaFamily);

public slots:
/// Updates the UI and emits `isaChanged()` signal.
void setISA(ISA isa);
/// Updates the UI using the new family and emits `isaChanged()` signal.
void setFamily(ISAFamily family);

signals:
/// Called when the isa is changed in the UI directly by the user.
void isaActivated(ISA isa);
/// Called when any time the isa is changed, including during
/// `setFamily()`.
void isaChanged(ISA isa);
void initializeView(const ISAInfoBase &isaInfo);
void updateView(const ISAInfoBase &isaInfo, const ISAInfoBase &prevISAInfo);
};

class ISAEncodingTableView : public QTableView {
Expand All @@ -64,13 +41,8 @@ class ISAEncodingTableView : public QTableView {
ISAEncodingTableView(QWidget *parent = nullptr);

public slots:
/// Updates the UI and emits `familyChanged()` signal.
void setFamily(ISAFamily family);
// void setISA(ISA isa);
// void setExtension(QString ext, bool enabled);

signals:
void familyChanged(ISAFamily family);
void initializeView(const ISAInfoBase &isaInfo);
void updateView(const ISAInfoBase &isaInfo, const ISAInfoBase &prevISAInfo);
};

class SliderulesTab : public RipesTab {
Expand All @@ -79,6 +51,10 @@ class SliderulesTab : public RipesTab {
explicit SliderulesTab(QToolBar *toolbar, QWidget *parent = nullptr);
~SliderulesTab();

public slots:
void initializeView(const ISAInfoBase &isaInfo);
void updateView(const ISAInfoBase &isaInfo, const ISAInfoBase &prevISAInfo);

private:
Ui::SliderulesTab *ui;
std::unique_ptr<ISAEncodingTableModel> m_encodingModel = nullptr;
Expand Down
Loading

0 comments on commit f3951ee

Please # to comment.