lbajardsilogic@18
|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
|
lbajardsilogic@18
|
2
|
lbajardsilogic@18
|
3 /*
|
lbajardsilogic@18
|
4 Sound Access
|
lbajardsilogic@18
|
5 EASAIER client application.
|
lbajardsilogic@18
|
6 Silogic 2007. Luc Barthélémy.
|
lbajardsilogic@18
|
7
|
lbajardsilogic@18
|
8 This program is free software; you can redistribute it and/or
|
lbajardsilogic@18
|
9 modify it under the terms of the GNU General Public License as
|
lbajardsilogic@18
|
10 published by the Free Software Foundation; either version 2 of the
|
lbajardsilogic@18
|
11 License, or (at your option) any later version. See the file
|
lbajardsilogic@18
|
12 COPYING included with this distribution for more information.
|
lbajardsilogic@18
|
13 */
|
lbajardsilogic@18
|
14
|
lbajardsilogic@18
|
15 #include <QObject>
|
lbajardsilogic@18
|
16 #include <QColor>
|
lbajardsilogic@18
|
17 #include <QPainter>
|
lbajardsilogic@18
|
18 #include <QMouseEvent>
|
lbajardsilogic@18
|
19 #include <QInputDialog>
|
lbajardsilogic@18
|
20
|
lbajardsilogic@18
|
21 #include "layer/IntervalLayer.h"
|
lbajardsilogic@18
|
22 #include "view/View.h"
|
lbajardsilogic@18
|
23 #include "system/System.h"
|
lbajardsilogic@18
|
24 #include "widgets/ItemEditDialog.h"
|
lbajardsilogic@18
|
25
|
lbajardsilogic@18
|
26
|
lbajardsilogic@18
|
27 const int gIntervalHeight = 30;
|
lbajardsilogic@18
|
28
|
lbajardsilogic@18
|
29 //****************************************************************
|
lbajardsilogic@18
|
30 //* Function: Constructor
|
lbajardsilogic@18
|
31 //* Description: declaration and initialisation of all private parameters
|
lbajardsilogic@18
|
32 //****************************************************************
|
lbajardsilogic@18
|
33 IntervalLayer::IntervalLayer():
|
lbajardsilogic@18
|
34 Layer(),
|
lbajardsilogic@18
|
35 m_model(0),
|
lbajardsilogic@18
|
36 m_editing(false),
|
lbajardsilogic@18
|
37 m_colour(Qt::darkRed),
|
lbajardsilogic@18
|
38 m_editingCommand(0)
|
lbajardsilogic@18
|
39 {
|
lbajardsilogic@18
|
40 }
|
lbajardsilogic@18
|
41
|
lbajardsilogic@18
|
42 IntervalLayer::~IntervalLayer()
|
lbajardsilogic@18
|
43 {}
|
lbajardsilogic@18
|
44
|
lbajardsilogic@18
|
45 void IntervalLayer::setModel(IntervalModel* model)
|
lbajardsilogic@18
|
46 {
|
lbajardsilogic@18
|
47 if (m_model == model) return;
|
lbajardsilogic@18
|
48 m_model = model;
|
lbajardsilogic@18
|
49
|
lbajardsilogic@18
|
50 connect(m_model, SIGNAL(modelChanged()), this, SIGNAL(modelChanged()));
|
lbajardsilogic@18
|
51 connect(m_model, SIGNAL(modelChanged(size_t, size_t)),
|
lbajardsilogic@18
|
52 this, SIGNAL(modelChanged(size_t, size_t)));
|
lbajardsilogic@18
|
53
|
lbajardsilogic@18
|
54 connect(m_model, SIGNAL(completionChanged()),
|
lbajardsilogic@18
|
55 this, SIGNAL(modelCompletionChanged()));
|
lbajardsilogic@18
|
56
|
lbajardsilogic@18
|
57 emit modelReplaced();
|
lbajardsilogic@18
|
58 }
|
lbajardsilogic@18
|
59
|
lbajardsilogic@18
|
60 Layer::PropertyList
|
lbajardsilogic@18
|
61 IntervalLayer::getProperties() const
|
lbajardsilogic@18
|
62 {
|
lbajardsilogic@18
|
63 PropertyList list;
|
lbajardsilogic@18
|
64 list.push_back("Colour");
|
lbajardsilogic@18
|
65 return list;
|
lbajardsilogic@18
|
66 }
|
lbajardsilogic@18
|
67
|
lbajardsilogic@18
|
68 Layer::PropertyType
|
lbajardsilogic@18
|
69 IntervalLayer::getPropertyType(const PropertyName &name) const
|
lbajardsilogic@18
|
70 {
|
lbajardsilogic@18
|
71 return ValueProperty;
|
lbajardsilogic@18
|
72 }
|
lbajardsilogic@18
|
73
|
lbajardsilogic@18
|
74 int
|
lbajardsilogic@18
|
75 IntervalLayer::getPropertyRangeAndValue(const PropertyName &name,
|
lbajardsilogic@18
|
76 int *min, int *max, int *deflt) const
|
lbajardsilogic@18
|
77 {
|
lbajardsilogic@18
|
78 //!!! factor this colour handling stuff out into a colour manager class
|
lbajardsilogic@18
|
79 int val = 0;
|
lbajardsilogic@18
|
80
|
lbajardsilogic@18
|
81 if (name == "Colour") {
|
lbajardsilogic@18
|
82
|
lbajardsilogic@18
|
83 if (min) *min = 0;
|
lbajardsilogic@18
|
84 if (max) *max = 5;
|
lbajardsilogic@18
|
85 if (deflt) *deflt = 0;
|
lbajardsilogic@18
|
86
|
lbajardsilogic@18
|
87 if (m_colour == Qt::black) val = 0;
|
lbajardsilogic@18
|
88 else if (m_colour == Qt::darkRed) val = 1;
|
lbajardsilogic@18
|
89 else if (m_colour == Qt::darkBlue) val = 2;
|
lbajardsilogic@18
|
90 else if (m_colour == Qt::darkGreen) val = 3;
|
lbajardsilogic@18
|
91 else if (m_colour == QColor(200, 50, 255)) val = 4;
|
lbajardsilogic@18
|
92 else if (m_colour == QColor(255, 150, 50)) val = 5;
|
lbajardsilogic@18
|
93 }
|
lbajardsilogic@18
|
94
|
lbajardsilogic@18
|
95 return val;
|
lbajardsilogic@18
|
96 }
|
lbajardsilogic@18
|
97
|
lbajardsilogic@18
|
98 QString
|
lbajardsilogic@18
|
99 IntervalLayer::getPropertyValueLabel(const PropertyName &name,
|
lbajardsilogic@18
|
100 int value) const
|
lbajardsilogic@18
|
101 {
|
lbajardsilogic@18
|
102 if (name == "Colour") {
|
lbajardsilogic@18
|
103 switch (value) {
|
lbajardsilogic@18
|
104 default:
|
lbajardsilogic@18
|
105 case 0: return tr("Black");
|
lbajardsilogic@18
|
106 case 1: return tr("Red");
|
lbajardsilogic@18
|
107 case 2: return tr("Blue");
|
lbajardsilogic@18
|
108 case 3: return tr("Green");
|
lbajardsilogic@18
|
109 case 4: return tr("Purple");
|
lbajardsilogic@18
|
110 case 5: return tr("Orange");
|
lbajardsilogic@18
|
111 }
|
lbajardsilogic@18
|
112 }
|
lbajardsilogic@18
|
113 return tr("<unknown>");
|
lbajardsilogic@18
|
114 }
|
lbajardsilogic@18
|
115
|
lbajardsilogic@18
|
116
|
lbajardsilogic@18
|
117 void IntervalLayer::setProperties(const QXmlAttributes &attributes)
|
lbajardsilogic@18
|
118 {
|
lbajardsilogic@18
|
119 QString colourSpec = attributes.value("colour");
|
lbajardsilogic@18
|
120 if (colourSpec != "") {
|
lbajardsilogic@18
|
121 QColor colour(colourSpec);
|
lbajardsilogic@18
|
122 if (colour.isValid()) {
|
lbajardsilogic@18
|
123 setBaseColour(QColor(colourSpec));
|
lbajardsilogic@18
|
124 }
|
lbajardsilogic@18
|
125 }
|
lbajardsilogic@18
|
126
|
lbajardsilogic@18
|
127 }
|
lbajardsilogic@18
|
128
|
lbajardsilogic@18
|
129 void
|
lbajardsilogic@18
|
130 IntervalLayer::setProperty(const PropertyName &name, int value)
|
lbajardsilogic@18
|
131 {
|
lbajardsilogic@18
|
132 if (name == "Colour") {
|
lbajardsilogic@18
|
133 switch (value) {
|
lbajardsilogic@18
|
134 default:
|
lbajardsilogic@18
|
135 case 0: setBaseColour(Qt::black); break;
|
lbajardsilogic@18
|
136 case 1: setBaseColour(Qt::darkRed); break;
|
lbajardsilogic@18
|
137 case 2: setBaseColour(Qt::darkBlue); break;
|
lbajardsilogic@18
|
138 case 3: setBaseColour(Qt::darkGreen); break;
|
lbajardsilogic@18
|
139 case 4: setBaseColour(QColor(200, 50, 255)); break;
|
lbajardsilogic@18
|
140 case 5: setBaseColour(QColor(255, 150, 50)); break;
|
lbajardsilogic@18
|
141 }
|
lbajardsilogic@18
|
142 }
|
lbajardsilogic@18
|
143 }
|
lbajardsilogic@18
|
144
|
lbajardsilogic@18
|
145 void
|
lbajardsilogic@18
|
146 IntervalLayer::setBaseColour(QColor colour)
|
lbajardsilogic@18
|
147 {
|
lbajardsilogic@18
|
148 if (m_colour == colour) return;
|
lbajardsilogic@18
|
149 m_colour = colour;
|
lbajardsilogic@18
|
150 emit layerParametersChanged();
|
lbajardsilogic@18
|
151 }
|
lbajardsilogic@18
|
152
|
lbajardsilogic@18
|
153 QString
|
lbajardsilogic@18
|
154 IntervalLayer::toXmlString(QString indent, QString extraAttributes) const
|
lbajardsilogic@18
|
155 {
|
lbajardsilogic@18
|
156 return Layer::toXmlString(indent, extraAttributes +
|
lbajardsilogic@18
|
157 QString(" colour=\"%1\"")
|
lbajardsilogic@18
|
158 .arg(encodeColour(m_colour)));
|
lbajardsilogic@18
|
159 }
|
lbajardsilogic@18
|
160
|
lbajardsilogic@18
|
161 QString
|
lbajardsilogic@18
|
162 IntervalLayer::toEasaierXmlString(QString indent, QString extraAttributes) const
|
lbajardsilogic@18
|
163 {
|
lbajardsilogic@18
|
164 return Layer::toEasaierXmlString(indent, extraAttributes +
|
lbajardsilogic@18
|
165 QString(" colour=\"%1\"")
|
lbajardsilogic@18
|
166 .arg(encodeColour(m_colour)));
|
lbajardsilogic@18
|
167 }
|
lbajardsilogic@18
|
168
|
lbajardsilogic@18
|
169 QString
|
lbajardsilogic@18
|
170 IntervalLayer::getPropertyLabel(const PropertyName &name) const
|
lbajardsilogic@18
|
171 {
|
lbajardsilogic@18
|
172 if (name == "Colour") return tr("Colour");
|
lbajardsilogic@18
|
173 return "";
|
lbajardsilogic@18
|
174 }
|
lbajardsilogic@18
|
175
|
lbajardsilogic@18
|
176 int
|
lbajardsilogic@18
|
177 IntervalLayer::getYForHeight(View *v, float height) const
|
lbajardsilogic@18
|
178 {
|
lbajardsilogic@18
|
179 int h = v->height();
|
lbajardsilogic@18
|
180 return h - int(height * h);
|
lbajardsilogic@18
|
181 }
|
lbajardsilogic@18
|
182
|
lbajardsilogic@18
|
183 float
|
lbajardsilogic@18
|
184 IntervalLayer::getHeightForY(View *v, int y) const
|
lbajardsilogic@18
|
185 {
|
lbajardsilogic@18
|
186 int h = v->height();
|
lbajardsilogic@18
|
187 return float(h - y) / h;
|
lbajardsilogic@18
|
188 }
|
lbajardsilogic@18
|
189
|
lbajardsilogic@18
|
190
|
lbajardsilogic@18
|
191 void
|
lbajardsilogic@18
|
192 IntervalLayer::paint(View *v, QPainter &paint, QRect rect) const
|
lbajardsilogic@18
|
193 {
|
lbajardsilogic@18
|
194 if (!m_model || !m_model->isOK()) return;
|
lbajardsilogic@18
|
195
|
lbajardsilogic@18
|
196 int sampleRate = m_model->getSampleRate();
|
lbajardsilogic@18
|
197 if (!sampleRate) return;
|
lbajardsilogic@18
|
198
|
lbajardsilogic@18
|
199 int x0 = rect.left(), x1 = rect.right();
|
lbajardsilogic@18
|
200 long frame0 = v->getFrameForX(x0);
|
lbajardsilogic@18
|
201 long frame1 = v->getFrameForX(x1);
|
lbajardsilogic@18
|
202
|
lbajardsilogic@18
|
203 paint.save();
|
lbajardsilogic@18
|
204
|
lbajardsilogic@18
|
205 QColor brushColour(m_colour);
|
lbajardsilogic@18
|
206 brushColour.setAlpha(100);
|
lbajardsilogic@18
|
207 QColor penColour = Qt::black;
|
lbajardsilogic@18
|
208
|
lbajardsilogic@18
|
209 paint.setPen(m_colour);
|
lbajardsilogic@18
|
210
|
lbajardsilogic@18
|
211 IntervalList& intervals = m_model->intervals();
|
lbajardsilogic@18
|
212
|
lbajardsilogic@18
|
213 int xS,xE,y;
|
lbajardsilogic@18
|
214 bool draw, drawText, drawStart, drawEnd;
|
lbajardsilogic@18
|
215
|
lbajardsilogic@18
|
216 QPoint localPos;
|
lbajardsilogic@18
|
217 long illuminateX = -1;
|
lbajardsilogic@18
|
218
|
lbajardsilogic@18
|
219 if (v->shouldIlluminateLocalFeatures(this, localPos)) {
|
lbajardsilogic@18
|
220 // should highlight one endpoint ?
|
lbajardsilogic@18
|
221 illuminateX = localPos.x();
|
lbajardsilogic@18
|
222 }
|
lbajardsilogic@18
|
223
|
lbajardsilogic@18
|
224 for (IntervalListConstIterator i = intervals.begin(); i != intervals.end(); ++i)
|
lbajardsilogic@18
|
225 {
|
lbajardsilogic@18
|
226 draw = drawText = drawStart = drawEnd = false;
|
lbajardsilogic@18
|
227
|
lbajardsilogic@18
|
228 TimeIntervalPtr ti = (*i);
|
lbajardsilogic@18
|
229
|
lbajardsilogic@18
|
230 if (ti->start() >= frame0 && ti->start() < frame1)
|
lbajardsilogic@18
|
231 {
|
lbajardsilogic@18
|
232 xS = v->getXForFrame(ti->start());
|
lbajardsilogic@18
|
233 xE = v->getXForFrame(ti->end());
|
lbajardsilogic@18
|
234 if (xE <= x1)
|
lbajardsilogic@18
|
235 drawEnd = true;
|
lbajardsilogic@18
|
236 else
|
lbajardsilogic@18
|
237 xE = x1;
|
lbajardsilogic@18
|
238 draw = drawText = drawStart = true;
|
lbajardsilogic@18
|
239 }
|
ivand_qmul@125
|
240 else if (ti->end() > frame0 && ti->end() <= frame1)
|
lbajardsilogic@18
|
241 {
|
lbajardsilogic@18
|
242 xS = v->getXForFrame(ti->start());
|
lbajardsilogic@18
|
243 if (xS < x0)
|
lbajardsilogic@18
|
244 xS = x0;
|
lbajardsilogic@18
|
245 xE = v->getXForFrame(ti->end());
|
lbajardsilogic@18
|
246 draw = drawEnd = true;
|
lbajardsilogic@18
|
247 }
|
ivand_qmul@125
|
248 else if (ti->start() <= frame0 && ti->end() >= frame1)
|
lbajardsilogic@18
|
249 {
|
lbajardsilogic@18
|
250 xS = x0;
|
lbajardsilogic@18
|
251 xE = x1;
|
lbajardsilogic@18
|
252 draw = true;
|
lbajardsilogic@18
|
253 }
|
lbajardsilogic@18
|
254 if (draw)
|
lbajardsilogic@18
|
255 {
|
lbajardsilogic@18
|
256 y = getYForHeight(v, ti->value());
|
lbajardsilogic@18
|
257 paint.setBrush(brushColour);
|
lbajardsilogic@18
|
258 paint.fillRect(xS, y-gIntervalHeight/2, (xE-xS+1), gIntervalHeight, brushColour);
|
lbajardsilogic@18
|
259 }
|
lbajardsilogic@18
|
260 if (drawStart)
|
lbajardsilogic@18
|
261 {
|
lbajardsilogic@18
|
262 if (abs(illuminateX - xS) < 3)
|
lbajardsilogic@18
|
263 paint.setPen(Qt::black);
|
lbajardsilogic@18
|
264 else
|
lbajardsilogic@18
|
265 paint.setPen(brushColour);
|
lbajardsilogic@18
|
266 paint.drawLine(xS, 0, xS, v->height() - 1);
|
lbajardsilogic@18
|
267 }
|
lbajardsilogic@18
|
268 if (drawEnd)
|
lbajardsilogic@18
|
269 {
|
lbajardsilogic@18
|
270 if (abs (illuminateX - xE) < 3)
|
lbajardsilogic@18
|
271 paint.setPen(Qt::black);
|
lbajardsilogic@18
|
272 else
|
lbajardsilogic@18
|
273 paint.setPen(brushColour);
|
lbajardsilogic@18
|
274 paint.drawLine(xE, 0, xE, v->height() - 1);
|
lbajardsilogic@18
|
275 }
|
lbajardsilogic@18
|
276 if (drawText)
|
lbajardsilogic@18
|
277 {
|
lbajardsilogic@18
|
278 paint.setPen(penColour);
|
lbajardsilogic@18
|
279 paint.drawText(xS+10, y, ti->label());
|
lbajardsilogic@18
|
280 }
|
lbajardsilogic@18
|
281 }
|
lbajardsilogic@18
|
282
|
lbajardsilogic@18
|
283 paint.restore();
|
lbajardsilogic@18
|
284 }
|
lbajardsilogic@18
|
285
|
lbajardsilogic@18
|
286
|
lbajardsilogic@18
|
287 bool
|
lbajardsilogic@18
|
288 IntervalLayer::getValueExtents(float &min, float &max,
|
lbajardsilogic@18
|
289 bool &logarithmic, QString &unit) const
|
lbajardsilogic@18
|
290 {
|
lbajardsilogic@18
|
291 return false;
|
lbajardsilogic@18
|
292 }
|
lbajardsilogic@18
|
293
|
lbajardsilogic@18
|
294 IntervalList
|
lbajardsilogic@18
|
295 IntervalLayer::getIntervalAt(View *v, int x, int y) // y < 0 means you don't make any test on it
|
lbajardsilogic@18
|
296 {
|
lbajardsilogic@18
|
297 IntervalList result;
|
lbajardsilogic@18
|
298 IntervalList& intervals = m_model->intervals();
|
lbajardsilogic@18
|
299
|
lbajardsilogic@18
|
300 for (IntervalListIterator i = intervals.begin(); i != intervals.end(); ++i)
|
lbajardsilogic@18
|
301 {
|
lbajardsilogic@18
|
302 TimeIntervalPtr ti = (*i);
|
lbajardsilogic@18
|
303
|
lbajardsilogic@18
|
304 int yT = getYForHeight(v, ti->value());
|
lbajardsilogic@18
|
305 int xS = v->getXForFrame(ti->start());
|
lbajardsilogic@18
|
306 int xE = v->getXForFrame(ti->end());
|
lbajardsilogic@18
|
307 if ((x >= xS) && (x <= xE))
|
lbajardsilogic@18
|
308 {
|
lbajardsilogic@18
|
309 if ((y < 0) || (abs(y - yT) <= gIntervalHeight/2))
|
lbajardsilogic@18
|
310 result.push_back(ti);
|
lbajardsilogic@18
|
311 }
|
lbajardsilogic@18
|
312 }
|
lbajardsilogic@18
|
313
|
lbajardsilogic@18
|
314 return result;
|
lbajardsilogic@18
|
315 }
|
lbajardsilogic@18
|
316
|
lbajardsilogic@18
|
317 IntervalList
|
lbajardsilogic@18
|
318 IntervalLayer::getInterval(long start, long end)
|
lbajardsilogic@18
|
319 {
|
lbajardsilogic@18
|
320 IntervalList result;
|
lbajardsilogic@18
|
321 IntervalList& intervals = m_model->intervals();
|
lbajardsilogic@18
|
322
|
lbajardsilogic@18
|
323 for (IntervalListIterator i = intervals.begin(); i != intervals.end(); ++i)
|
lbajardsilogic@18
|
324 {
|
lbajardsilogic@18
|
325 TimeIntervalPtr ti = (*i);
|
lbajardsilogic@18
|
326
|
lbajardsilogic@18
|
327 if ( (start <= ti->start()) && (ti->start() <= end) &&
|
lbajardsilogic@18
|
328 (start <= ti->end()) && (ti->end() <= end) )
|
lbajardsilogic@18
|
329 {
|
lbajardsilogic@18
|
330 result.push_back(ti);
|
lbajardsilogic@18
|
331 }
|
lbajardsilogic@18
|
332 }
|
lbajardsilogic@18
|
333
|
lbajardsilogic@18
|
334 return result;
|
lbajardsilogic@18
|
335 }
|
lbajardsilogic@18
|
336
|
lbajardsilogic@18
|
337 QString
|
lbajardsilogic@18
|
338 IntervalLayer::getFeatureDescription(View *v, QPoint& pos) const
|
lbajardsilogic@18
|
339 {
|
lbajardsilogic@18
|
340 if (!m_model || !m_model->getSampleRate()) return "";
|
lbajardsilogic@18
|
341
|
lbajardsilogic@18
|
342 QString description;
|
lbajardsilogic@18
|
343
|
lbajardsilogic@18
|
344 int x = pos.x();
|
lbajardsilogic@18
|
345 int y = pos.y();
|
lbajardsilogic@18
|
346
|
lbajardsilogic@18
|
347 long frame = v->getFrameForX(x);
|
lbajardsilogic@18
|
348
|
lbajardsilogic@18
|
349 IntervalList& intervals = m_model->intervals();
|
lbajardsilogic@18
|
350 for (IntervalListConstIterator i = intervals.begin(); i != intervals.end(); ++i)
|
lbajardsilogic@18
|
351 {
|
lbajardsilogic@18
|
352 TimeIntervalPtr ti = (*i);
|
lbajardsilogic@18
|
353
|
lbajardsilogic@18
|
354 if (ti->start() <= frame && ti->end() >= frame)
|
lbajardsilogic@18
|
355 {
|
lbajardsilogic@18
|
356 int y = getYForHeight(v, ti->value());
|
lbajardsilogic@18
|
357
|
lbajardsilogic@18
|
358 if (abs(y - pos.y()) <= gIntervalHeight/2)
|
lbajardsilogic@18
|
359 {
|
lbajardsilogic@18
|
360 RealTime rtStart = RealTime::frame2RealTime(ti->start(), m_model->getSampleRate());
|
lbajardsilogic@18
|
361 RealTime rtEnd = RealTime::frame2RealTime(ti->end(), m_model->getSampleRate());
|
lbajardsilogic@18
|
362 RealTime rtDuration = rtEnd - rtStart;
|
lbajardsilogic@18
|
363
|
lbajardsilogic@18
|
364 description = QString(tr("Interval:\t%1\nStart:\t%2 End:\t%3\tDuration:\t%4"))
|
lbajardsilogic@18
|
365 .arg(ti->label())
|
lbajardsilogic@18
|
366 .arg(rtStart.toText(true).c_str())
|
lbajardsilogic@18
|
367 .arg(rtEnd.toText(true).c_str())
|
lbajardsilogic@18
|
368 .arg(rtDuration.toText(true).c_str());
|
lbajardsilogic@18
|
369 break;
|
lbajardsilogic@18
|
370 }
|
lbajardsilogic@18
|
371 }
|
lbajardsilogic@18
|
372 }
|
lbajardsilogic@18
|
373
|
lbajardsilogic@18
|
374 return description;
|
lbajardsilogic@18
|
375 }
|
lbajardsilogic@18
|
376
|
lbajardsilogic@18
|
377
|
lbajardsilogic@18
|
378 void
|
lbajardsilogic@18
|
379 IntervalLayer::drawStart(View *v, QMouseEvent *e)
|
lbajardsilogic@18
|
380 {
|
lbajardsilogic@18
|
381 if (!m_model) {
|
lbajardsilogic@18
|
382 std::cerr << "IntervalLayer::drawStart: no model" << std::endl;
|
lbajardsilogic@18
|
383 return;
|
lbajardsilogic@18
|
384 }
|
lbajardsilogic@18
|
385
|
lbajardsilogic@18
|
386 long frame = v->getFrameForX(e->x());
|
lbajardsilogic@18
|
387
|
lbajardsilogic@18
|
388 if (frame < 0)
|
lbajardsilogic@18
|
389 frame = 0;
|
lbajardsilogic@18
|
390
|
lbajardsilogic@18
|
391 frame = frame / m_model->getResolution() * m_model->getResolution();
|
lbajardsilogic@18
|
392
|
lbajardsilogic@18
|
393 int height = (int) (getHeightForY(v, e->y())*100+0.5);
|
lbajardsilogic@18
|
394 float value = ((float) height)/100;
|
lbajardsilogic@18
|
395
|
lbajardsilogic@18
|
396 m_editingInterval = new TimeInterval(frame, frame, "", value);
|
lbajardsilogic@18
|
397
|
lbajardsilogic@18
|
398 m_model->addInterval(m_editingInterval);
|
lbajardsilogic@18
|
399
|
lbajardsilogic@18
|
400 if (m_editingCommand)
|
lbajardsilogic@18
|
401 {
|
lbajardsilogic@18
|
402 CommandHistory::getInstance()->addCommand(m_editingCommand, false);
|
lbajardsilogic@18
|
403 m_editingCommand = 0;
|
lbajardsilogic@18
|
404 }
|
lbajardsilogic@18
|
405
|
lbajardsilogic@18
|
406 m_editingCommand = new IntervalModel::IntervalCommand(m_model, m_editingInterval,
|
lbajardsilogic@18
|
407 IntervalModel::IntervalCommand::Creation ,
|
lbajardsilogic@18
|
408 frame, frame, value, "");
|
lbajardsilogic@18
|
409
|
lbajardsilogic@18
|
410 m_editing = 1;
|
lbajardsilogic@18
|
411 }
|
lbajardsilogic@18
|
412
|
lbajardsilogic@18
|
413 void
|
lbajardsilogic@18
|
414 IntervalLayer::drawDrag(View *v, QMouseEvent *e)
|
lbajardsilogic@18
|
415 {
|
lbajardsilogic@18
|
416 if (!m_model || !m_editing) return;
|
lbajardsilogic@18
|
417
|
lbajardsilogic@18
|
418 long frame = v->getFrameForX(e->x());
|
lbajardsilogic@18
|
419
|
lbajardsilogic@18
|
420 if (frame < 0)
|
lbajardsilogic@18
|
421 frame = 0;
|
lbajardsilogic@18
|
422
|
lbajardsilogic@18
|
423 frame = frame / m_model->getResolution() * m_model->getResolution();
|
lbajardsilogic@18
|
424
|
lbajardsilogic@18
|
425 long start = m_editingInterval->start();
|
lbajardsilogic@18
|
426 long end = frame;
|
lbajardsilogic@18
|
427
|
lbajardsilogic@18
|
428 if (start < end)
|
lbajardsilogic@18
|
429 {
|
lbajardsilogic@18
|
430 m_editing = 2;
|
lbajardsilogic@18
|
431 m_editingInterval->end(frame);
|
lbajardsilogic@18
|
432 m_editingCommand->newEnd(frame);
|
lbajardsilogic@18
|
433 } else {
|
lbajardsilogic@18
|
434 m_editing = 1;
|
lbajardsilogic@18
|
435 m_editingInterval->start(frame);
|
lbajardsilogic@18
|
436 m_editingCommand->newStart(frame);
|
lbajardsilogic@18
|
437 }
|
lbajardsilogic@18
|
438 }
|
lbajardsilogic@18
|
439
|
lbajardsilogic@18
|
440 void
|
lbajardsilogic@18
|
441 IntervalLayer::drawEnd(View *v, QMouseEvent *e)
|
lbajardsilogic@18
|
442 {
|
lbajardsilogic@18
|
443 if (!m_model || !m_editing)
|
lbajardsilogic@18
|
444 return;
|
lbajardsilogic@18
|
445
|
lbajardsilogic@18
|
446 bool ok = false;
|
lbajardsilogic@18
|
447 QString label = QInputDialog::getText(v, tr("Enter label"),
|
lbajardsilogic@18
|
448 tr("Please enter a new label:"),
|
lbajardsilogic@18
|
449 QLineEdit::Normal, "", &ok);
|
lbajardsilogic@18
|
450
|
lbajardsilogic@18
|
451 if (ok) {
|
lbajardsilogic@18
|
452 m_editingInterval->label(label);
|
lbajardsilogic@18
|
453 m_editingCommand->newLabel(label);
|
lbajardsilogic@18
|
454 }
|
lbajardsilogic@18
|
455
|
lbajardsilogic@18
|
456 if (m_editingCommand)
|
lbajardsilogic@18
|
457 {
|
lbajardsilogic@18
|
458 CommandHistory::getInstance()->addCommand(m_editingCommand, false);
|
lbajardsilogic@18
|
459 m_editingCommand = 0;
|
lbajardsilogic@18
|
460 }
|
lbajardsilogic@18
|
461
|
lbajardsilogic@18
|
462 m_editing = false;
|
lbajardsilogic@18
|
463 }
|
lbajardsilogic@18
|
464
|
lbajardsilogic@18
|
465 void
|
lbajardsilogic@18
|
466 IntervalLayer::editStart(View *view, QMouseEvent *evt)
|
lbajardsilogic@18
|
467 {
|
lbajardsilogic@18
|
468 if (!m_model)
|
lbajardsilogic@18
|
469 return;
|
lbajardsilogic@18
|
470
|
lbajardsilogic@18
|
471 IntervalList intervals = getIntervalAt(view, evt->x(), evt->y());
|
lbajardsilogic@18
|
472
|
lbajardsilogic@18
|
473 for (IntervalListConstIterator i = intervals.begin(); i != intervals.end(); ++i)
|
lbajardsilogic@18
|
474 {
|
lbajardsilogic@18
|
475 TimeIntervalPtr ti = (*i);
|
lbajardsilogic@18
|
476
|
lbajardsilogic@18
|
477 int xS = view->getXForFrame(ti->start());
|
lbajardsilogic@18
|
478 int xE = view->getXForFrame(ti->end());
|
lbajardsilogic@18
|
479
|
lbajardsilogic@18
|
480 if (abs(xS - evt->x()) < 5)
|
lbajardsilogic@18
|
481 {
|
lbajardsilogic@18
|
482 m_editing = 1; // editing start
|
lbajardsilogic@18
|
483 m_editingInterval = ti;
|
lbajardsilogic@18
|
484 break;
|
lbajardsilogic@18
|
485 }
|
lbajardsilogic@18
|
486 else if (abs(xE - evt->x()) < 5)
|
lbajardsilogic@18
|
487 {
|
lbajardsilogic@18
|
488 m_editing = 2; // editing end
|
lbajardsilogic@18
|
489 m_editingInterval = ti;
|
lbajardsilogic@18
|
490 break;
|
lbajardsilogic@18
|
491 }
|
lbajardsilogic@18
|
492 else
|
lbajardsilogic@18
|
493 {
|
lbajardsilogic@18
|
494 m_editing = 0;
|
lbajardsilogic@18
|
495 }
|
lbajardsilogic@18
|
496 }
|
lbajardsilogic@18
|
497
|
lbajardsilogic@18
|
498 if (m_editing)
|
lbajardsilogic@18
|
499 view->setCursor(Qt::SizeHorCursor);
|
lbajardsilogic@18
|
500
|
lbajardsilogic@18
|
501 if (m_editingCommand)
|
lbajardsilogic@18
|
502 {
|
lbajardsilogic@18
|
503 CommandHistory::getInstance()->addCommand(m_editingCommand, false);
|
lbajardsilogic@18
|
504 m_editingCommand = 0;
|
lbajardsilogic@18
|
505 }
|
lbajardsilogic@18
|
506
|
lbajardsilogic@18
|
507 }
|
lbajardsilogic@18
|
508
|
lbajardsilogic@18
|
509 void
|
lbajardsilogic@18
|
510 IntervalLayer::editDrag(View *view, QMouseEvent *evt)
|
lbajardsilogic@18
|
511 {
|
lbajardsilogic@18
|
512 if (!m_model || !m_editing)
|
lbajardsilogic@18
|
513 return;
|
lbajardsilogic@18
|
514
|
lbajardsilogic@18
|
515 long frame = view->getFrameForX(evt->x());
|
lbajardsilogic@18
|
516
|
lbajardsilogic@18
|
517 if (!m_editingCommand)
|
lbajardsilogic@18
|
518 {
|
lbajardsilogic@18
|
519 m_editingCommand = new IntervalModel::IntervalCommand(m_model, m_editingInterval, IntervalModel::IntervalCommand::Edition,
|
lbajardsilogic@18
|
520 m_editingInterval->start(),
|
lbajardsilogic@18
|
521 m_editingInterval->end(),
|
lbajardsilogic@18
|
522 m_editingInterval->value(),
|
lbajardsilogic@18
|
523 m_editingInterval->label());
|
lbajardsilogic@18
|
524 }
|
lbajardsilogic@18
|
525
|
lbajardsilogic@18
|
526 if (m_editing == 1) // start
|
lbajardsilogic@18
|
527 {
|
lbajardsilogic@18
|
528 if (frame < m_editingInterval->end())
|
lbajardsilogic@18
|
529 m_editingCommand->newStart(frame);
|
lbajardsilogic@18
|
530 }
|
lbajardsilogic@18
|
531 else if (m_editing == 2) // end
|
lbajardsilogic@18
|
532 {
|
lbajardsilogic@18
|
533 if (frame > m_editingInterval->start())
|
lbajardsilogic@18
|
534 m_editingCommand->newEnd(frame);
|
lbajardsilogic@18
|
535 }
|
lbajardsilogic@18
|
536 }
|
lbajardsilogic@18
|
537
|
lbajardsilogic@18
|
538 void
|
lbajardsilogic@18
|
539 IntervalLayer::editEnd(View *view, QMouseEvent *evt)
|
lbajardsilogic@18
|
540 {
|
lbajardsilogic@18
|
541 if (!m_model || !m_editing)
|
lbajardsilogic@18
|
542 return;
|
lbajardsilogic@18
|
543
|
lbajardsilogic@18
|
544 view->setCursor(Qt::UpArrowCursor);
|
lbajardsilogic@18
|
545
|
lbajardsilogic@18
|
546 if (m_editingCommand)
|
lbajardsilogic@18
|
547 {
|
lbajardsilogic@18
|
548 CommandHistory::getInstance()->addCommand(m_editingCommand, false);
|
lbajardsilogic@18
|
549 m_editingCommand = 0;
|
lbajardsilogic@18
|
550 }
|
lbajardsilogic@18
|
551
|
lbajardsilogic@18
|
552
|
lbajardsilogic@18
|
553 m_editing = false;
|
lbajardsilogic@18
|
554 }
|
lbajardsilogic@18
|
555
|
lbajardsilogic@18
|
556 void
|
lbajardsilogic@18
|
557 IntervalLayer::editOpen(View *view, QMouseEvent *evt) // on double-click
|
lbajardsilogic@18
|
558 {
|
lbajardsilogic@18
|
559 if (!m_model) return;
|
lbajardsilogic@18
|
560
|
lbajardsilogic@18
|
561 IntervalList intervals = getIntervalAt(view, evt->x(), evt->y());
|
lbajardsilogic@18
|
562 if (! intervals.empty())
|
lbajardsilogic@18
|
563 {
|
lbajardsilogic@18
|
564 TimeIntervalPtr ti = intervals.front();
|
lbajardsilogic@18
|
565
|
lbajardsilogic@18
|
566 bool ok = false;
|
lbajardsilogic@18
|
567 ItemEditDialog *dialog = new ItemEditDialog
|
lbajardsilogic@18
|
568 (m_model->getSampleRate(),
|
lbajardsilogic@18
|
569 ItemEditDialog::ShowTime |
|
lbajardsilogic@18
|
570 ItemEditDialog::ShowDuration |
|
lbajardsilogic@18
|
571 ItemEditDialog::ShowText |
|
lbajardsilogic@18
|
572 ItemEditDialog::ShowValue);
|
lbajardsilogic@18
|
573
|
lbajardsilogic@18
|
574 dialog->setFrameTime(ti->start());
|
lbajardsilogic@18
|
575 dialog->setFrameDuration(ti->end() - ti->start());
|
lbajardsilogic@18
|
576 dialog->setText(ti->label());
|
lbajardsilogic@18
|
577 dialog->setValue((int)(ti->value()*100+0.5));
|
lbajardsilogic@18
|
578
|
lbajardsilogic@18
|
579 if (dialog->exec() == QDialog::Accepted)
|
lbajardsilogic@18
|
580 {
|
lbajardsilogic@18
|
581
|
lbajardsilogic@18
|
582 IntervalModel::IntervalCommand *command =
|
lbajardsilogic@18
|
583 new IntervalModel::IntervalCommand(m_model, ti, IntervalModel::IntervalCommand::Edition,
|
lbajardsilogic@18
|
584 dialog->getFrameTime(),
|
lbajardsilogic@18
|
585 dialog->getFrameTime() + dialog->getFrameDuration(),
|
lbajardsilogic@18
|
586 dialog->getValue()/100,
|
lbajardsilogic@18
|
587 dialog->getText());
|
lbajardsilogic@18
|
588
|
lbajardsilogic@18
|
589 CommandHistory::getInstance()->addCommand(command);
|
lbajardsilogic@18
|
590
|
lbajardsilogic@18
|
591 }
|
lbajardsilogic@18
|
592 }
|
lbajardsilogic@18
|
593 }
|
lbajardsilogic@18
|
594
|
lbajardsilogic@18
|
595 void
|
lbajardsilogic@18
|
596 IntervalLayer::moveSelection(Selection s, size_t newStartFrame)
|
lbajardsilogic@18
|
597 {
|
lbajardsilogic@18
|
598 if (!m_model) return;
|
lbajardsilogic@18
|
599
|
lbajardsilogic@18
|
600 IntervalList intervals = getInterval(s.getStartFrame(), s.getEndFrame());
|
lbajardsilogic@18
|
601
|
lbajardsilogic@18
|
602 MacroCommand * command = new MacroCommand("Drag Selection");
|
lbajardsilogic@18
|
603
|
lbajardsilogic@18
|
604 long newStart = 0;
|
lbajardsilogic@18
|
605 long newEnd = 0;
|
lbajardsilogic@18
|
606
|
lbajardsilogic@18
|
607 for (IntervalListConstIterator i = intervals.begin(); i != intervals.end(); ++i)
|
lbajardsilogic@18
|
608 {
|
lbajardsilogic@18
|
609 TimeIntervalPtr ti = (*i);
|
lbajardsilogic@18
|
610
|
lbajardsilogic@18
|
611 newStart = ti->start() + ((long) (newStartFrame - s.getStartFrame()));
|
lbajardsilogic@18
|
612 newEnd = ti->end() + ((long) (newStartFrame - s.getStartFrame()));
|
lbajardsilogic@18
|
613
|
lbajardsilogic@18
|
614 IntervalModel::IntervalCommand *intervalCommand =
|
lbajardsilogic@18
|
615 new IntervalModel::IntervalCommand(m_model, ti, IntervalModel::IntervalCommand::Edition,
|
lbajardsilogic@18
|
616 newStart,
|
lbajardsilogic@18
|
617 newEnd,
|
lbajardsilogic@18
|
618 ti->value(),
|
lbajardsilogic@18
|
619 ti->label());
|
lbajardsilogic@18
|
620
|
lbajardsilogic@18
|
621 m_model->changeInterval(ti, newStart, newEnd, ti->value(), ti->label() );
|
lbajardsilogic@18
|
622
|
lbajardsilogic@18
|
623 command->addCommand(intervalCommand);
|
lbajardsilogic@18
|
624 }
|
lbajardsilogic@18
|
625
|
lbajardsilogic@18
|
626 CommandHistory::getInstance()->addCommand(command, false);
|
lbajardsilogic@18
|
627 }
|
lbajardsilogic@18
|
628
|
lbajardsilogic@18
|
629 void
|
lbajardsilogic@18
|
630 IntervalLayer::resizeSelection(Selection s, Selection newSize)
|
lbajardsilogic@18
|
631 {
|
lbajardsilogic@18
|
632 if (!m_model) return;
|
lbajardsilogic@18
|
633
|
lbajardsilogic@18
|
634 IntervalList intervals = getInterval(s.getStartFrame(), s.getEndFrame());
|
lbajardsilogic@18
|
635
|
lbajardsilogic@18
|
636 MacroCommand * command = new MacroCommand("Resize Selection");
|
lbajardsilogic@18
|
637
|
lbajardsilogic@18
|
638 long newStart = 0;
|
lbajardsilogic@18
|
639 long newEnd = 0;
|
lbajardsilogic@18
|
640
|
lbajardsilogic@18
|
641 double ratio = ((double) (newSize.getEndFrame() - newSize.getStartFrame())) /
|
lbajardsilogic@18
|
642 ((double) (s.getEndFrame() - s.getStartFrame()));
|
lbajardsilogic@18
|
643
|
lbajardsilogic@18
|
644 for (IntervalListConstIterator i = intervals.begin(); i != intervals.end(); ++i)
|
lbajardsilogic@18
|
645 {
|
lbajardsilogic@18
|
646 TimeIntervalPtr ti = (*i);
|
lbajardsilogic@18
|
647
|
lbajardsilogic@18
|
648 newStart = (long) newSize.getStartFrame() + (long) ( ((double) ti->start() - (double) s.getStartFrame()) * ratio );
|
lbajardsilogic@18
|
649 newEnd = (long) newSize.getStartFrame() + (long) ( ((double) ti->end() - (double) s.getStartFrame()) * ratio );
|
lbajardsilogic@18
|
650
|
lbajardsilogic@18
|
651 IntervalModel::IntervalCommand *intervalCommand =
|
lbajardsilogic@18
|
652 new IntervalModel::IntervalCommand(m_model, ti, IntervalModel::IntervalCommand::Edition,
|
lbajardsilogic@18
|
653 newStart,
|
lbajardsilogic@18
|
654 newEnd,
|
lbajardsilogic@18
|
655 ti->value(),
|
lbajardsilogic@18
|
656 ti->label());
|
lbajardsilogic@18
|
657
|
lbajardsilogic@18
|
658 m_model->changeInterval(ti, newStart, newEnd, ti->value(), ti->label() );
|
lbajardsilogic@18
|
659
|
lbajardsilogic@18
|
660 command->addCommand(intervalCommand);
|
lbajardsilogic@18
|
661 }
|
lbajardsilogic@18
|
662
|
lbajardsilogic@18
|
663 CommandHistory::getInstance()->addCommand(command, false);
|
lbajardsilogic@18
|
664 }
|
lbajardsilogic@18
|
665
|
lbajardsilogic@18
|
666 void
|
lbajardsilogic@18
|
667 IntervalLayer::deleteSelection(Selection s)
|
lbajardsilogic@18
|
668 {
|
lbajardsilogic@18
|
669 if (!m_model) return;
|
lbajardsilogic@18
|
670
|
lbajardsilogic@18
|
671 IntervalList intervals = getInterval(s.getStartFrame(), s.getEndFrame());
|
lbajardsilogic@18
|
672
|
lbajardsilogic@18
|
673 MacroCommand * command = new MacroCommand("Delete Selected Intervals");
|
lbajardsilogic@18
|
674
|
lbajardsilogic@18
|
675 for (IntervalListConstIterator i = intervals.begin(); i != intervals.end(); ++i)
|
lbajardsilogic@18
|
676 {
|
lbajardsilogic@18
|
677 TimeIntervalPtr ti = (*i);
|
lbajardsilogic@18
|
678
|
lbajardsilogic@18
|
679 m_model->removeInterval(ti);
|
lbajardsilogic@18
|
680
|
lbajardsilogic@18
|
681 IntervalModel::IntervalCommand *intervalCommand =
|
lbajardsilogic@18
|
682 new IntervalModel::IntervalCommand(m_model, ti, IntervalModel::IntervalCommand::Deletion,
|
lbajardsilogic@18
|
683 ti->start(),
|
lbajardsilogic@18
|
684 ti->end(),
|
lbajardsilogic@18
|
685 ti->value(),
|
lbajardsilogic@18
|
686 ti->label());
|
lbajardsilogic@18
|
687
|
lbajardsilogic@18
|
688 command->addCommand(intervalCommand);
|
lbajardsilogic@18
|
689 }
|
lbajardsilogic@18
|
690
|
lbajardsilogic@18
|
691 CommandHistory::getInstance()->addCommand(command, false);
|
lbajardsilogic@18
|
692 }
|
lbajardsilogic@18
|
693
|
lbajardsilogic@18
|
694 void
|
lbajardsilogic@18
|
695 IntervalLayer::paste(const Clipboard &from, int frameOffset)
|
lbajardsilogic@18
|
696 {
|
lbajardsilogic@18
|
697 if (!m_model) return;
|
lbajardsilogic@18
|
698
|
lbajardsilogic@18
|
699 const Clipboard::PointList &points = from.getPoints();
|
lbajardsilogic@18
|
700
|
lbajardsilogic@18
|
701 MacroCommand * command = new MacroCommand("Paste");
|
lbajardsilogic@18
|
702
|
lbajardsilogic@18
|
703 for (Clipboard::PointList::const_iterator i = points.begin(); i != points.end(); ++i)
|
lbajardsilogic@18
|
704 {
|
lbajardsilogic@18
|
705 if (!i->haveFrame())
|
lbajardsilogic@18
|
706 continue;
|
lbajardsilogic@18
|
707
|
lbajardsilogic@18
|
708 size_t frame = 0;
|
lbajardsilogic@18
|
709
|
lbajardsilogic@18
|
710 if (frameOffset > 0 || -frameOffset < i->getFrame()) {
|
lbajardsilogic@18
|
711 frame = i->getFrame() + frameOffset;
|
lbajardsilogic@18
|
712 }
|
lbajardsilogic@18
|
713
|
lbajardsilogic@18
|
714 TimeIntervalPtr ti = new TimeInterval((long) frame, (long) (frame+i->getDuration()), i->getLabel(), i->getValue());
|
lbajardsilogic@18
|
715
|
lbajardsilogic@18
|
716 m_model->addInterval(ti);
|
lbajardsilogic@18
|
717
|
lbajardsilogic@18
|
718 IntervalModel::IntervalCommand *intervalCommand =
|
lbajardsilogic@18
|
719 new IntervalModel::IntervalCommand(m_model, ti, IntervalModel::IntervalCommand::Creation,
|
lbajardsilogic@18
|
720 ti->start(),
|
lbajardsilogic@18
|
721 ti->end(),
|
lbajardsilogic@18
|
722 ti->value(),
|
lbajardsilogic@18
|
723 ti->label());
|
lbajardsilogic@18
|
724
|
lbajardsilogic@18
|
725 command->addCommand(intervalCommand);
|
lbajardsilogic@18
|
726
|
lbajardsilogic@18
|
727 }
|
lbajardsilogic@18
|
728
|
lbajardsilogic@18
|
729 CommandHistory::getInstance()->addCommand(command, false);
|
lbajardsilogic@18
|
730 }
|
lbajardsilogic@18
|
731
|
lbajardsilogic@18
|
732 void
|
lbajardsilogic@18
|
733 IntervalLayer::copy(Selection s, Clipboard &to)
|
lbajardsilogic@18
|
734 {
|
lbajardsilogic@18
|
735 if (!m_model) return;
|
lbajardsilogic@18
|
736
|
lbajardsilogic@18
|
737 IntervalList intervals = getInterval(s.getStartFrame(), s.getEndFrame());
|
lbajardsilogic@18
|
738
|
lbajardsilogic@18
|
739 for (IntervalListConstIterator i = intervals.begin(); i != intervals.end(); ++i)
|
lbajardsilogic@18
|
740 {
|
lbajardsilogic@18
|
741 TimeIntervalPtr ti = (*i);
|
lbajardsilogic@18
|
742
|
lbajardsilogic@18
|
743 Clipboard::Point point(ti->start(), ti->value(), ti->end()-ti->start(), ti->label());
|
lbajardsilogic@18
|
744 to.addPoint(point);
|
lbajardsilogic@18
|
745 }
|
lbajardsilogic@18
|
746 }
|
lbajardsilogic@18
|
747
|
lbajardsilogic@18
|
748 bool
|
lbajardsilogic@18
|
749 IntervalLayer::snapToFeatureFrame(View *v, int &frame,
|
lbajardsilogic@18
|
750 size_t &resolution,
|
lbajardsilogic@18
|
751 SnapType snap) const
|
lbajardsilogic@18
|
752 {
|
lbajardsilogic@18
|
753 if (!m_model)
|
lbajardsilogic@18
|
754 return Layer::snapToFeatureFrame(v, frame, resolution, snap);
|
lbajardsilogic@18
|
755
|
lbajardsilogic@18
|
756 resolution = m_model->getResolution();
|
lbajardsilogic@18
|
757
|
lbajardsilogic@18
|
758 IntervalList& intervals = m_model->intervals();
|
lbajardsilogic@18
|
759
|
lbajardsilogic@18
|
760 int snapped, best = frame;
|
lbajardsilogic@18
|
761 bool found = false;
|
lbajardsilogic@18
|
762
|
lbajardsilogic@18
|
763 unsigned int dist, distMin;
|
lbajardsilogic@18
|
764
|
lbajardsilogic@18
|
765 dist = distMin = m_model->getEndFrame();
|
lbajardsilogic@18
|
766
|
lbajardsilogic@18
|
767 for (IntervalListConstIterator i = intervals.begin(); i != intervals.end(); ++i)
|
lbajardsilogic@18
|
768 {
|
lbajardsilogic@18
|
769 TimeIntervalPtr ti = (*i);
|
lbajardsilogic@18
|
770 switch (snap)
|
lbajardsilogic@18
|
771 {
|
lbajardsilogic@18
|
772 case SnapRight:
|
lbajardsilogic@18
|
773 if (ti->start() >= frame)
|
lbajardsilogic@18
|
774 {
|
lbajardsilogic@18
|
775 dist = ti->start() - frame;
|
lbajardsilogic@18
|
776 snapped = ti->start();
|
lbajardsilogic@18
|
777 }
|
lbajardsilogic@18
|
778 else if (ti->end() >= frame)
|
lbajardsilogic@18
|
779 {
|
lbajardsilogic@18
|
780 dist = ti->end() - frame;
|
lbajardsilogic@18
|
781 snapped = ti->end();
|
lbajardsilogic@18
|
782 }
|
lbajardsilogic@18
|
783 break;
|
lbajardsilogic@18
|
784
|
lbajardsilogic@18
|
785 case SnapLeft:
|
lbajardsilogic@18
|
786 if (ti->end() <= frame)
|
lbajardsilogic@18
|
787 {
|
lbajardsilogic@18
|
788 dist = frame - ti->end();
|
lbajardsilogic@18
|
789 snapped = ti->end();
|
lbajardsilogic@18
|
790 }
|
lbajardsilogic@18
|
791 else if (ti->start() <= frame)
|
lbajardsilogic@18
|
792 {
|
lbajardsilogic@18
|
793 dist = frame - ti->start();
|
lbajardsilogic@18
|
794 snapped = ti->start();
|
lbajardsilogic@18
|
795 }
|
lbajardsilogic@18
|
796 break;
|
lbajardsilogic@18
|
797
|
lbajardsilogic@18
|
798 case SnapNearest:
|
lbajardsilogic@18
|
799 {
|
lbajardsilogic@18
|
800 int distS = abs(ti->start() - frame);
|
lbajardsilogic@18
|
801 int distE = abs(ti->end() - frame);
|
lbajardsilogic@18
|
802 if (distS < distE)
|
lbajardsilogic@18
|
803 {
|
lbajardsilogic@18
|
804 dist = distS;
|
lbajardsilogic@18
|
805 snapped = ti->start();
|
lbajardsilogic@18
|
806 } else
|
lbajardsilogic@18
|
807 {
|
lbajardsilogic@18
|
808 dist = distE;
|
lbajardsilogic@18
|
809 snapped = ti->end();
|
lbajardsilogic@18
|
810 }
|
lbajardsilogic@18
|
811 }
|
lbajardsilogic@18
|
812 break;
|
lbajardsilogic@18
|
813
|
lbajardsilogic@18
|
814 case SnapNeighbouring:
|
lbajardsilogic@18
|
815 {
|
lbajardsilogic@18
|
816 int distS = abs(ti->start() - frame);
|
lbajardsilogic@18
|
817 int distE = abs(ti->end() - frame);
|
lbajardsilogic@18
|
818 if (distS < 5)
|
lbajardsilogic@18
|
819 {
|
lbajardsilogic@18
|
820 dist = distS;
|
lbajardsilogic@18
|
821 snapped = ti->start();
|
lbajardsilogic@18
|
822 } else if (distE < 5)
|
lbajardsilogic@18
|
823 {
|
lbajardsilogic@18
|
824 dist = distE;
|
lbajardsilogic@18
|
825 snapped = ti->end();
|
lbajardsilogic@18
|
826 }
|
lbajardsilogic@18
|
827 }
|
lbajardsilogic@18
|
828 break;
|
lbajardsilogic@18
|
829 }
|
lbajardsilogic@18
|
830
|
lbajardsilogic@18
|
831 if (dist < distMin)
|
lbajardsilogic@18
|
832 {
|
lbajardsilogic@18
|
833 found = true;
|
lbajardsilogic@18
|
834 distMin = dist;
|
lbajardsilogic@18
|
835 best = snapped;
|
lbajardsilogic@18
|
836 }
|
lbajardsilogic@18
|
837
|
lbajardsilogic@18
|
838 }
|
lbajardsilogic@18
|
839
|
lbajardsilogic@18
|
840
|
lbajardsilogic@18
|
841 if (found)
|
lbajardsilogic@18
|
842 {
|
lbajardsilogic@18
|
843 frame = best;
|
lbajardsilogic@18
|
844 }
|
lbajardsilogic@18
|
845
|
lbajardsilogic@18
|
846 return found;
|
lbajardsilogic@18
|
847 }
|