Mercurial > hg > svcore
comparison base/Selection.cpp @ 24:bb9291d84810
* Add ffwd/rewind
* Abstract out MultiSelection
author | Chris Cannam |
---|---|
date | Wed, 08 Feb 2006 17:59:16 +0000 |
parents | 73d85d19919f |
children | 935a2419a77c |
comparison
equal
deleted
inserted
replaced
23:6ace4286ba06 | 24:bb9291d84810 |
---|---|
89 | 89 |
90 return (m_startFrame == s.m_startFrame && | 90 return (m_startFrame == s.m_startFrame && |
91 m_endFrame == s.m_endFrame); | 91 m_endFrame == s.m_endFrame); |
92 } | 92 } |
93 | 93 |
94 | |
95 MultiSelection::MultiSelection() | |
96 { | |
97 } | |
98 | |
99 MultiSelection::~MultiSelection() | |
100 { | |
101 } | |
102 | |
103 const MultiSelection::SelectionList & | |
104 MultiSelection::getSelections() const | |
105 { | |
106 return m_selections; | |
107 } | |
108 | |
109 void | |
110 MultiSelection::setSelection(const Selection &selection) | |
111 { | |
112 clearSelections(); | |
113 addSelection(selection); | |
114 } | |
115 | |
116 void | |
117 MultiSelection::addSelection(const Selection &selection) | |
118 { | |
119 m_selections.insert(selection); | |
120 | |
121 // Cope with a sitation where the new selection overlaps one or | |
122 // more existing ones. This is a terribly inefficient way to do | |
123 // this, but that probably isn't significant in real life. | |
124 | |
125 // It's essential for the correct operation of | |
126 // getContainingSelection that the selections do not overlap, so | |
127 // this is not just a frill. | |
128 | |
129 for (SelectionList::iterator i = m_selections.begin(); | |
130 i != m_selections.end(); ) { | |
131 | |
132 SelectionList::iterator j = i; | |
133 if (++j == m_selections.end()) break; | |
134 | |
135 if (i->getEndFrame() >= j->getStartFrame()) { | |
136 Selection merged(i->getStartFrame(), | |
137 std::max(i->getEndFrame(), j->getEndFrame())); | |
138 m_selections.erase(i); | |
139 m_selections.erase(j); | |
140 m_selections.insert(merged); | |
141 i = m_selections.begin(); | |
142 } else { | |
143 ++i; | |
144 } | |
145 } | |
146 } | |
147 | |
148 void | |
149 MultiSelection::removeSelection(const Selection &selection) | |
150 { | |
151 //!!! Likewise this needs to cope correctly with the situation | |
152 //where selection is not one of the original selection set but | |
153 //simply overlaps one of them (cutting down the original selection | |
154 //appropriately) | |
155 | |
156 if (m_selections.find(selection) != m_selections.end()) { | |
157 m_selections.erase(selection); | |
158 } | |
159 } | |
160 | |
161 void | |
162 MultiSelection::clearSelections() | |
163 { | |
164 if (!m_selections.empty()) { | |
165 m_selections.clear(); | |
166 } | |
167 } | |
168 | |
169 Selection | |
170 MultiSelection::getContainingSelection(size_t frame, bool defaultToFollowing) | |
171 { | |
172 // This scales very badly with the number of selections, but it's | |
173 // more efficient for very small numbers of selections than a more | |
174 // scalable method, and I think that may be what we need | |
175 | |
176 for (SelectionList::const_iterator i = m_selections.begin(); | |
177 i != m_selections.end(); ++i) { | |
178 | |
179 if (i->contains(frame)) return *i; | |
180 | |
181 if (i->getStartFrame() > frame) { | |
182 if (defaultToFollowing) return *i; | |
183 else return Selection(); | |
184 } | |
185 } | |
186 | |
187 return Selection(); | |
188 } |