Add SelectedFrames into doc::Site

This commit is contained in:
David Capello 2016-06-13 16:30:03 -03:00
parent 9307c12174
commit 0713fb8db0
6 changed files with 281 additions and 1 deletions

View File

@ -55,6 +55,7 @@ add_library(doc-lib
primitives.cpp
remap.cpp
rgbmap.cpp
selected_frames.cpp
selected_layers.cpp
site.cpp
sort_palette.cpp

32
src/doc/frame_range.h Normal file
View File

@ -0,0 +1,32 @@
// 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.
#ifndef DOC_FRAME_RANGE_H_INCLUDED
#define DOC_FRAME_RANGE_H_INCLUDED
#pragma once
#include "doc/frame.h"
namespace doc {
struct FrameRange {
frame_t fromFrame, toFrame;
FrameRange() : fromFrame(0), toFrame(0) {
}
explicit FrameRange(frame_t frame)
: fromFrame(frame), toFrame(frame) {
}
FrameRange(frame_t fromFrame, frame_t toFrame)
: fromFrame(fromFrame), toFrame(toFrame) {
}
};
} // namespace doc
#endif

View File

@ -0,0 +1,71 @@
// 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"
namespace doc {
void SelectedFrames::insert(frame_t frame)
{
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)
{
// TODO improve this
for (frame_t frame = fromFrame; frame <= toFrame; ++frame) {
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);
});
}
} // namespace doc

75
src/doc/selected_frames.h Normal file
View File

@ -0,0 +1,75 @@
// 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.
#ifndef DOC_SELECTED_FRAMES_H_INCLUDED
#define DOC_SELECTED_FRAMES_H_INCLUDED
#pragma once
#include "doc/frame_range.h"
#include <iterator>
#include <vector>
namespace doc {
class SelectedFrames {
typedef std::vector<FrameRange> Ranges;
public:
class const_iterator : public std::iterator<std::forward_iterator_tag, frame_t> {
public:
const_iterator(const Ranges::const_iterator& it)
: m_it(it), m_frame(-1) {
}
const_iterator& operator++() {
if (m_frame < 0)
m_frame = m_it->fromFrame;
if (m_frame < m_it->toFrame)
++m_frame;
else {
m_frame = -1;
++m_it;
}
return *this;
}
frame_t operator*() const {
if (m_frame < 0)
m_frame = m_it->fromFrame;
return m_frame;
}
bool operator==(const const_iterator& o) const {
return (m_it == o.m_it && m_frame == o.m_frame);
}
bool operator!=(const const_iterator& it) const {
return !operator==(it);
}
private:
mutable Ranges::const_iterator m_it;
mutable frame_t m_frame;
};
const_iterator begin() const { return const_iterator(m_ranges.begin()); }
const_iterator end() const { return const_iterator(m_ranges.end()); }
void insert(frame_t frame);
void insert(frame_t fromFrame, frame_t toFrame);
bool contains(frame_t frame) const;
private:
Ranges m_ranges;
};
} // namespace doc
#endif // DOC_LAYER_LIST_H_INCLUDED

View File

@ -0,0 +1,94 @@
// 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 <gtest/gtest.h>
#include "doc/selected_frames.h"
#include <algorithm>
#include <iterator>
using namespace doc;
TEST(SelectedFrames, BasicOneRange)
{
SelectedFrames f;
f.insert(1);
f.insert(2);
f.insert(3);
std::vector<frame_t> res;
std::copy(f.begin(), f.end(), std::back_inserter(res));
ASSERT_EQ(3, res.size());
EXPECT_EQ(1, res[0]);
EXPECT_EQ(2, res[1]);
EXPECT_EQ(3, res[2]);
}
TEST(SelectedFrames, BasicThreeRanges)
{
SelectedFrames f;
f.insert(1);
f.insert(3);
f.insert(5);
std::vector<frame_t> res;
std::copy(f.begin(), f.end(), std::back_inserter(res));
ASSERT_EQ(3, res.size());
EXPECT_EQ(1, res[0]);
EXPECT_EQ(3, res[1]);
EXPECT_EQ(5, res[2]);
}
TEST(SelectedFrames, InsertSelectedFrameInsideSelectedRange)
{
SelectedFrames f;
f.insert(3);
f.insert(5, 8);
f.insert(7);
std::vector<frame_t> res;
std::copy(f.begin(), f.end(), std::back_inserter(res));
ASSERT_EQ(5, res.size());
EXPECT_EQ(3, res[0]);
EXPECT_EQ(5, res[1]);
EXPECT_EQ(6, res[2]);
EXPECT_EQ(7, res[3]);
EXPECT_EQ(8, res[4]);
}
TEST(SelectedFrames, Contains)
{
SelectedFrames f;
f.insert(1);
f.insert(4, 5);
f.insert(7, 9);
EXPECT_FALSE(f.contains(0));
EXPECT_TRUE(f.contains(1));
EXPECT_FALSE(f.contains(2));
EXPECT_FALSE(f.contains(3));
EXPECT_TRUE(f.contains(4));
EXPECT_TRUE(f.contains(5));
EXPECT_FALSE(f.contains(6));
EXPECT_TRUE(f.contains(7));
EXPECT_TRUE(f.contains(8));
EXPECT_TRUE(f.contains(9));
EXPECT_FALSE(f.contains(10));
}
int main(int argc, char** argv)
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

View File

@ -9,6 +9,7 @@
#pragma once
#include "doc/frame.h"
#include "doc/selected_frames.h"
#include "doc/selected_layers.h"
namespace doc {
@ -62,11 +63,16 @@ namespace doc {
const SelectedLayers& selectedLayers() const { return m_selectedLayers; }
SelectedLayers& selectedLayers() { return m_selectedLayers; }
void selectedLayers(const SelectedLayers& selectedLayers) {
m_selectedLayers = selectedLayers;
}
const SelectedFrames& selectedFrames() const { return m_selectedFrames; }
SelectedFrames& selectedFrames() { return m_selectedFrames; }
void selectedFrames(const SelectedFrames& selectedFrames) {
m_selectedFrames = selectedFrames;
}
Palette* palette();
Image* image(int* x = nullptr, int* y = nullptr, int* opacity = nullptr) const;
Palette* palette() const;
@ -78,6 +84,7 @@ namespace doc {
Layer* m_layer;
frame_t m_frame;
SelectedLayers m_selectedLayers;
SelectedFrames m_selectedFrames;
};
} // namespace app