Start document model tests
This commit is contained in:
144
src/document/document.cpp
Normal file
144
src/document/document.cpp
Normal file
@@ -0,0 +1,144 @@
|
||||
#include "document/document.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace pp::document {
|
||||
|
||||
namespace {
|
||||
|
||||
[[nodiscard]] pp::foundation::Status validate_config(DocumentConfig config) noexcept
|
||||
{
|
||||
if (config.width == 0 || config.height == 0) {
|
||||
return pp::foundation::Status::invalid_argument("document dimensions must be greater than zero");
|
||||
}
|
||||
|
||||
if (config.width > max_canvas_dimension || config.height > max_canvas_dimension) {
|
||||
return pp::foundation::Status::out_of_range("document dimensions exceed the configured limit");
|
||||
}
|
||||
|
||||
if (config.layer_count == 0) {
|
||||
return pp::foundation::Status::invalid_argument("document must contain at least one layer");
|
||||
}
|
||||
|
||||
if (config.layer_count > max_layer_count) {
|
||||
return pp::foundation::Status::out_of_range("document layer count exceeds the configured limit");
|
||||
}
|
||||
|
||||
return pp::foundation::Status::success();
|
||||
}
|
||||
|
||||
[[nodiscard]] std::string default_layer_name(std::size_t index)
|
||||
{
|
||||
return "Layer " + std::to_string(index + 1U);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
pp::foundation::Result<CanvasDocument> CanvasDocument::create(DocumentConfig config)
|
||||
{
|
||||
const auto status = validate_config(config);
|
||||
if (!status.ok()) {
|
||||
return pp::foundation::Result<CanvasDocument>::failure(status);
|
||||
}
|
||||
|
||||
CanvasDocument document;
|
||||
document.width_ = config.width;
|
||||
document.height_ = config.height;
|
||||
document.layers_.reserve(config.layer_count);
|
||||
for (std::uint32_t i = 0; i < config.layer_count; ++i) {
|
||||
document.layers_.push_back(Layer { .name = default_layer_name(i) });
|
||||
}
|
||||
|
||||
return pp::foundation::Result<CanvasDocument>::success(document);
|
||||
}
|
||||
|
||||
std::uint32_t CanvasDocument::width() const noexcept
|
||||
{
|
||||
return width_;
|
||||
}
|
||||
|
||||
std::uint32_t CanvasDocument::height() const noexcept
|
||||
{
|
||||
return height_;
|
||||
}
|
||||
|
||||
std::size_t CanvasDocument::active_layer_index() const noexcept
|
||||
{
|
||||
return active_layer_index_;
|
||||
}
|
||||
|
||||
std::span<const Layer> CanvasDocument::layers() const noexcept
|
||||
{
|
||||
return layers_;
|
||||
}
|
||||
|
||||
pp::foundation::Result<std::size_t> CanvasDocument::add_layer(std::string_view name)
|
||||
{
|
||||
if (layers_.size() >= max_layer_count) {
|
||||
return pp::foundation::Result<std::size_t>::failure(
|
||||
pp::foundation::Status::out_of_range("document layer count exceeds the configured limit"));
|
||||
}
|
||||
|
||||
Layer layer;
|
||||
layer.name = name.empty() ? default_layer_name(layers_.size()) : std::string(name);
|
||||
layers_.push_back(layer);
|
||||
active_layer_index_ = layers_.size() - 1U;
|
||||
return pp::foundation::Result<std::size_t>::success(active_layer_index_);
|
||||
}
|
||||
|
||||
pp::foundation::Status CanvasDocument::remove_layer(std::size_t index)
|
||||
{
|
||||
if (index >= layers_.size()) {
|
||||
return pp::foundation::Status::out_of_range("layer index is outside the document");
|
||||
}
|
||||
|
||||
if (layers_.size() == 1U) {
|
||||
return pp::foundation::Status::invalid_argument("document must keep at least one layer");
|
||||
}
|
||||
|
||||
layers_.erase(layers_.begin() + static_cast<std::ptrdiff_t>(index));
|
||||
if (active_layer_index_ >= layers_.size()) {
|
||||
active_layer_index_ = layers_.size() - 1U;
|
||||
} else if (active_layer_index_ > index) {
|
||||
--active_layer_index_;
|
||||
}
|
||||
|
||||
return pp::foundation::Status::success();
|
||||
}
|
||||
|
||||
pp::foundation::Status CanvasDocument::move_layer(std::size_t from, std::size_t to)
|
||||
{
|
||||
if (from >= layers_.size() || to >= layers_.size()) {
|
||||
return pp::foundation::Status::out_of_range("layer index is outside the document");
|
||||
}
|
||||
|
||||
if (from == to) {
|
||||
return pp::foundation::Status::success();
|
||||
}
|
||||
|
||||
auto layer = layers_[from];
|
||||
layers_.erase(layers_.begin() + static_cast<std::ptrdiff_t>(from));
|
||||
layers_.insert(layers_.begin() + static_cast<std::ptrdiff_t>(to), layer);
|
||||
|
||||
if (active_layer_index_ == from) {
|
||||
active_layer_index_ = to;
|
||||
} else if (from < active_layer_index_ && active_layer_index_ <= to) {
|
||||
--active_layer_index_;
|
||||
} else if (to <= active_layer_index_ && active_layer_index_ < from) {
|
||||
++active_layer_index_;
|
||||
}
|
||||
|
||||
return pp::foundation::Status::success();
|
||||
}
|
||||
|
||||
pp::foundation::Status CanvasDocument::set_active_layer(std::size_t index) noexcept
|
||||
{
|
||||
if (index >= layers_.size()) {
|
||||
return pp::foundation::Status::out_of_range("layer index is outside the document");
|
||||
}
|
||||
|
||||
active_layer_index_ = index;
|
||||
return pp::foundation::Status::success();
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user