Added cpp ReverseModel (#3132)

This commit is contained in:
Florian Blasius 2023-07-24 11:32:45 +02:00 committed by GitHub
parent 635ecbead6
commit 8ce2620aaa
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 179 additions and 0 deletions

View file

@ -1231,6 +1231,7 @@ struct SortModelInner : private_api::ModelChangeListener
target_model.row_removed(removed_row, 1);
}
}
void reset() override
{
sorted_rows_dirty = true;
@ -1295,6 +1296,7 @@ public:
{
inner->source_model->set_row_data(inner->sorted_rows[i], value);
}
/// Re-applies the model's sort function on each row of the source model. Use this if state
/// external to the sort function has changed.
void reset() { inner->reset(); }
@ -1314,6 +1316,87 @@ private:
std::shared_ptr<private_api::SortModelInner<ModelData>> inner;
};
template<typename ModelData>
class ReverseModel;
namespace private_api {
template<typename ModelData>
struct ReverseModelInner : private_api::ModelChangeListener
{
ReverseModelInner(std::shared_ptr<slint::Model<ModelData>> source_model,
slint::ReverseModel<ModelData> &target_model)
: source_model(source_model), target_model(target_model)
{
}
void row_added(size_t first_inserted_row, size_t count) override
{
auto row_count = source_model->row_count();
auto old_row_count = row_count - count;
auto row = old_row_count - first_inserted_row;
target_model.row_added(row, count);
}
void row_changed(size_t changed_row) override
{
target_model.row_changed(source_model->row_count() - 1 - changed_row);
}
void row_removed(size_t first_removed_row, size_t count) override
{
auto row_count = source_model->row_count();
auto old_row_count = row_count + count;
auto row = old_row_count - first_removed_row - 1;
target_model.row_removed(row, count);
}
void reset() override { source_model.reset(); }
std::shared_ptr<slint::Model<ModelData>> source_model;
slint::ReverseModel<ModelData> &target_model;
};
}
/// The ReverseModel acts as an adapter model for a given source model by reserving all rows.
/// This means that the first row in the source model is the last row of this model, the second
/// row is the second last, and so on.
template<typename ModelData>
class ReverseModel : public Model<ModelData>
{
friend struct private_api::ReverseModelInner<ModelData>;
public:
/// Constructs a new ReverseModel that provides a reversed view on the \a source_model.
ReverseModel(std::shared_ptr<Model<ModelData>> source_model)
: inner(std::make_shared<private_api::ReverseModelInner<ModelData>>(std::move(source_model),
*this))
{
inner->source_model->attach_peer(inner);
}
size_t row_count() const override { return inner->source_model->row_count(); }
std::optional<ModelData> row_data(size_t i) const override
{
auto count = inner->source_model->row_count();
return inner->source_model->row_data(count - i - 1);
}
void set_row_data(size_t i, const ModelData &value) override
{
auto count = inner->source_model->row_count();
inner->source_model->set_row_data(count - i - 1, value);
}
/// Returns the source model of this reserve model.
std::shared_ptr<Model<ModelData>> source_model() const { return inner->source_model; }
private:
std::shared_ptr<private_api::ReverseModelInner<ModelData>> inner;
};
namespace private_api {
template<typename C, typename ModelData>