aseprite/src/doc/selected_frames.cpp

120 lines
2.4 KiB
C++

// Aseprite Document Library
// Copyright (c) 2016 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "doc/selected_frames.h"
#include <algorithm>
namespace doc {
std::size_t SelectedFrames::size() const
{
std::size_t size = 0;
for (auto& range : m_ranges)
size += (range.toFrame - range.fromFrame + 1);
return size;
}
void SelectedFrames::clear()
{
m_ranges.clear();
}
void SelectedFrames::insert(frame_t frame)
{
ASSERT(frame >= 0);
if (m_ranges.empty()) {
m_ranges.push_back(FrameRange(frame));
return;
}
auto it = m_ranges.begin();
auto end = m_ranges.end();
auto next = it;
for (; it!=end; it=next) {
if (frame >= it->fromFrame &&
frame <= it->toFrame)
break;
if (frame < it->fromFrame) {
if (frame == it->fromFrame-1)
--it->fromFrame;
else
m_ranges.insert(it, FrameRange(frame));
break;
}
++next;
if (frame > it->toFrame && (next == end || frame < next->fromFrame-1)) {
if (frame == it->toFrame+1)
++it->toFrame;
else
m_ranges.insert(next, FrameRange(frame));
break;
}
}
}
void SelectedFrames::insert(frame_t fromFrame, frame_t toFrame)
{
if (fromFrame > toFrame)
std::swap(fromFrame, toFrame);
// TODO improve this
for (frame_t frame = fromFrame; frame <= toFrame; ++frame) {
insert(frame);
}
}
void SelectedFrames::filter(frame_t fromFrame, frame_t toFrame)
{
if (fromFrame > toFrame)
std::swap(fromFrame, toFrame);
// TODO improve this, avoid copying
SelectedFrames original = *this;
for (frame_t frame : original) {
if (frame >= fromFrame && frame <= toFrame)
insert(frame);
}
}
bool SelectedFrames::contains(frame_t frame) const
{
return std::binary_search(
m_ranges.begin(),
m_ranges.end(),
FrameRange(frame),
[](const FrameRange& a,
const FrameRange& b) -> bool {
return (a.toFrame < b.fromFrame);
});
}
void SelectedFrames::displace(frame_t frameDelta)
{
// Avoid setting negative numbers in frame ranges
if (firstFrame()+frameDelta < 0)
frameDelta = -firstFrame();
for (auto& range : m_ranges) {
range.fromFrame += frameDelta;
range.toFrame += frameDelta;
ASSERT(range.fromFrame >= 0);
ASSERT(range.toFrame >= 0);
}
}
} // namespace doc