1 // Aseprite Document Library 2 // Copyright (c) 2016-2018 David Capello 3 // 4 // This file is released under the terms of the MIT license. 5 // Read LICENSE.txt for more information. 6 7 #ifndef DOC_SELECTED_FRAMES_H_INCLUDED 8 #define DOC_SELECTED_FRAMES_H_INCLUDED 9 #pragma once 10 11 #include "doc/frame_range.h" 12 13 #include <iosfwd> 14 #include <iterator> 15 #include <vector> 16 17 namespace doc { 18 19 class SelectedFrames { 20 typedef std::vector<FrameRange> Ranges; 21 22 public: 23 class const_iterator : public std::iterator<std::forward_iterator_tag, frame_t> { 24 static const int kNullFrame = -2; 25 public: const_iterator(const Ranges::const_iterator & it)26 const_iterator(const Ranges::const_iterator& it) 27 : m_it(it), m_frame(kNullFrame) { 28 } 29 30 const_iterator& operator++() { 31 if (m_frame == kNullFrame) 32 m_frame = m_it->fromFrame; 33 34 if (m_it->fromFrame <= m_it->toFrame) { 35 if (m_frame < m_it->toFrame) 36 ++m_frame; 37 else { 38 m_frame = kNullFrame; 39 ++m_it; 40 } 41 } 42 else { 43 if (m_frame > m_it->toFrame) 44 --m_frame; 45 else { 46 m_frame = kNullFrame; 47 ++m_it; 48 } 49 } 50 51 return *this; 52 } 53 54 frame_t operator*() const { 55 if (m_frame == kNullFrame) 56 m_frame = m_it->fromFrame; 57 return m_frame; 58 } 59 60 bool operator==(const const_iterator& o) const { 61 return (m_it == o.m_it && m_frame == o.m_frame); 62 } 63 64 bool operator!=(const const_iterator& it) const { 65 return !operator==(it); 66 } 67 68 private: 69 mutable Ranges::const_iterator m_it; 70 mutable frame_t m_frame; 71 }; 72 73 class const_reverse_iterator : public std::iterator<std::forward_iterator_tag, frame_t> { 74 public: const_reverse_iterator(const Ranges::const_reverse_iterator & it)75 const_reverse_iterator(const Ranges::const_reverse_iterator& it) 76 : m_it(it), m_frame(-1) { 77 } 78 79 const_reverse_iterator& operator++() { 80 if (m_frame < 0) 81 m_frame = m_it->toFrame; 82 83 if (m_frame > m_it->fromFrame) 84 --m_frame; 85 else { 86 m_frame = -1; 87 ++m_it; 88 } 89 90 return *this; 91 } 92 93 frame_t operator*() const { 94 if (m_frame < 0) 95 m_frame = m_it->toFrame; 96 return m_frame; 97 } 98 99 bool operator==(const const_reverse_iterator& o) const { 100 return (m_it == o.m_it && m_frame == o.m_frame); 101 } 102 103 bool operator!=(const const_reverse_iterator& it) const { 104 return !operator==(it); 105 } 106 107 private: 108 mutable Ranges::const_reverse_iterator m_it; 109 mutable frame_t m_frame; 110 }; 111 112 class Reversed { 113 public: 114 typedef const_reverse_iterator const_iterator; 115 begin()116 const_iterator begin() const { return m_selectedFrames.rbegin(); } end()117 const_iterator end() const { return m_selectedFrames.rend(); } 118 Reversed(const SelectedFrames & selectedFrames)119 Reversed(const SelectedFrames& selectedFrames) 120 : m_selectedFrames(selectedFrames) { 121 } 122 123 private: 124 const SelectedFrames& m_selectedFrames; 125 }; 126 begin()127 const_iterator begin() const { return const_iterator(m_ranges.begin()); } end()128 const_iterator end() const { return const_iterator(m_ranges.end()); } rbegin()129 const_reverse_iterator rbegin() const { return const_reverse_iterator(m_ranges.rbegin()); } rend()130 const_reverse_iterator rend() const { return const_reverse_iterator(m_ranges.rend()); } 131 132 std::size_t size() const; ranges()133 std::size_t ranges() const { return m_ranges.size(); } empty()134 bool empty() const { return m_ranges.empty(); } 135 136 void clear(); 137 void insert(frame_t frame); 138 void insert(frame_t fromFrame, frame_t toFrame); 139 SelectedFrames filter(frame_t fromFrame, frame_t toFrame) const; 140 141 bool contains(frame_t frame) const; 142 firstFrame()143 frame_t firstFrame() const { return (!m_ranges.empty() ? m_ranges.front().fromFrame: -1); } lastFrame()144 frame_t lastFrame() const { return (!m_ranges.empty() ? m_ranges.back().toFrame: -1); } 145 146 void displace(frame_t frameDelta); reversed()147 Reversed reversed() const { return Reversed(*this); } 148 149 SelectedFrames makeReverse() const; 150 SelectedFrames makePingPong() const; 151 152 bool operator==(const SelectedFrames& o) const { 153 return m_ranges == o.m_ranges; 154 } 155 156 bool operator!=(const SelectedFrames& o) const { 157 return !operator==(o); 158 } 159 160 bool write(std::ostream& os) const; 161 bool read(std::istream& is); 162 163 private: 164 Ranges m_ranges; 165 }; 166 167 } // namespace doc 168 169 #endif // DOC_SELECTED_FRAMES_H_INCLUDED 170