Files
oak-editor/app/common/timerange.cpp
T
itsmattkc b713ab47eb keyframes: only update active frames even from curve and param editor
When adjusting a slider, keyframe time, or curve value, it is undesirable to
re-cache the entire affected area while the user is still dragging UI objects.
Since the video is unlikely to be playing, the priority must go to the
currently active frame so the user gets visual feedback on the rendered image
as soon as possible. This was implemented in some areas, but this commit should
have that functionality in all areas.
2020-01-25 17:51:34 +11:00

175 lines
3.9 KiB
C++

#include "timerange.h"
#include <utility>
TimeRange::TimeRange(const rational &in, const rational &out) :
in_(in),
out_(out)
{
normalize();
}
const rational &TimeRange::in() const
{
return in_;
}
const rational &TimeRange::out() const
{
return out_;
}
const rational &TimeRange::length() const
{
return length_;
}
void TimeRange::set_in(const rational &in)
{
in_ = in;
normalize();
}
void TimeRange::set_out(const rational &out)
{
out_ = out;
normalize();
}
void TimeRange::set_range(const rational &in, const rational &out)
{
in_ = in;
out_ = out;
normalize();
}
bool TimeRange::operator==(const TimeRange &r) const
{
return in() == r.in() && out() == r.out();
}
bool TimeRange::OverlapsWith(const TimeRange &a, bool in_inclusive, bool out_inclusive) const
{
bool overlaps_in = (in_inclusive) ? (a.out() < in()) : (a.out() <= in());
bool overlaps_out = (out_inclusive) ? (a.in() > out()) : (a.in() >= out());
return !(overlaps_in || overlaps_out);
}
TimeRange TimeRange::CombineWith(const TimeRange &a) const
{
return Combine(a, *this);
}
bool TimeRange::Contains(const TimeRange &compare, bool in_inclusive, bool out_inclusive) const
{
bool contains_in = (in_inclusive) ? (compare.in() >= in()) : (compare.in() > in());
bool contains_out = (out_inclusive) ? (compare.out() <= out()) : (compare.out() < out());
return contains_in && contains_out;
}
TimeRange TimeRange::Combine(const TimeRange &a, const TimeRange &b)
{
return TimeRange(qMin(a.in(), b.in()),
qMax(a.out(), b.out()));
}
void TimeRange::normalize()
{
// If `out` is earlier than `in`, swap them
if (out_ < in_)
{
std::swap(out_, in_);
}
// Calculate length
length_ = out_ - in_;
}
uint qHash(const TimeRange &r, uint seed)
{
return qHash(r.in(), seed) ^ qHash(r.out(), seed);
}
void TimeRangeList::InsertTimeRange(const TimeRange &range)
{
for (int i=0;i<size();i++) {
const TimeRange& compare = at(i);
if (compare == range) {
return;
} else if (range.OverlapsWith(compare)) {
replace(i, TimeRange::Combine(range, compare));
return;
}
}
append(range);
}
void TimeRangeList::RemoveTimeRange(const TimeRange &range)
{
for (int i=0;i<size();i++) {
const TimeRange& compare = at(i);
if (range.Contains(compare)) {
// This element is entirely encompassed in this range, remove it
removeAt(i);
i--;
} else if (compare.Contains(range, false, false)) {
// The remove range is within this element, only choice is to split the element into two
TimeRange first(compare.in(), range.in());
TimeRange last(range.out(), compare.out());
replace(i, first);
append(last);
} else if (compare.in() < range.in() && compare.out() > range.in()) {
// This element's out point overlaps the range's in, we'll trim it
TimeRange trimmed = compare;
trimmed.set_out(range.in());
replace(i, trimmed);
} else if (compare.in() < range.out() && compare.out() > range.out()) {
// This element's in point overlaps the range's out, we'll trim it
TimeRange trimmed = compare;
trimmed.set_in(range.out());
replace(i, trimmed);
}
}
}
bool TimeRangeList::ContainsTimeRange(const TimeRange &range, bool in_inclusive, bool out_inclusive) const
{
for (int i=0;i<size();i++) {
if (at(i).Contains(range, in_inclusive, out_inclusive)) {
return true;
}
}
return false;
}
TimeRangeList TimeRangeList::Intersects(const TimeRange &range)
{
TimeRangeList intersect_list;
for (int i=0;i<size();i++) {
const TimeRange& compare = at(i);
if (compare.out() <= range.in() || compare.in() >= range.out()) {
// No intersect
continue;
} else {
// Crop the time range to the range and add it to the list
TimeRange cropped(qMax(range.in(), compare.in()),
qMin(range.out(), compare.out()));
intersect_list.append(cropped);
}
}
return intersect_list;
}