| |
| |
| #include "toonz/tframehandle.h" |
| #include "toonz/toonzscene.h" |
| #include "toonz/txshsimplelevel.h" |
| #include "toonz/txsheet.h" |
| #include "toonz/txshcell.h" |
| #include "toonz/sceneproperties.h" |
| #include "toutputproperties.h" |
| |
| #include "toonz/txsheethandle.h" |
| |
| |
| |
| namespace |
| { |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| bool getCurrentLevelFids(std::vector<TFrameId> &fids) |
| { |
| |
| |
| |
| |
| |
| fids.push_back(TFrameId(1)); |
| return !fids.empty(); |
| } |
| |
| TFrameId getLastLevelFid() |
| { |
| return TFrameId(1); |
| } |
| |
| } |
| |
| |
| |
| |
| |
| TFrameHandle::TFrameHandle() |
| : m_frame(-1), m_fid(), m_timerId(0), m_previewFrameRate(25), m_frameType(SceneFrame), m_looping(false), m_isPlaying(false), m_scrubRange(0, -1), m_audioColumn(0), m_xsheet(0), m_fps(0), m_frame0(-1), m_frame1(-1) |
| { |
| } |
| |
| |
| |
| TFrameHandle::~TFrameHandle() |
| { |
| } |
| |
| |
| |
| int TFrameHandle::getFrame() const |
| { |
| return m_frame; |
| } |
| |
| |
| |
| void TFrameHandle::setCurrentFrame(int frame) |
| { |
| if (m_frameType == LevelFrame) { |
| |
| |
| |
| if (m_fids.size() <= 0) |
| return; |
| if (frame - 1 >= (int)m_fids.size()) |
| setFid(m_fids.back()); |
| else |
| setFid(m_fids[frame - 1]); |
| } else |
| setFrame(frame - 1); |
| } |
| |
| |
| |
| void TFrameHandle::setFrame(int frame) |
| { |
| if (m_frame == frame && m_frameType == SceneFrame) |
| return; |
| m_frame = frame; |
| if (m_frameType != SceneFrame) { |
| m_frameType = SceneFrame; |
| emit frameTypeChanged(); |
| } |
| emit frameSwitched(); |
| } |
| |
| |
| |
| TFrameId TFrameHandle::getFid() const |
| { |
| return m_fid; |
| } |
| |
| |
| |
| void TFrameHandle::setFid(const TFrameId &fid) |
| { |
| if (m_fid == fid && m_frameType == LevelFrame) |
| return; |
| m_fid = fid; |
| if (m_frameType != LevelFrame) { |
| m_frameType = LevelFrame; |
| emit frameTypeChanged(); |
| } |
| emit frameSwitched(); |
| } |
| |
| |
| |
| void TFrameHandle::nextFrame() |
| { |
| if (m_frameType == LevelFrame) { |
| |
| |
| if (m_fids.size() <= 0) |
| return; |
| std::vector<TFrameId>::iterator it; |
| it = std::upper_bound(m_fids.begin(), m_fids.end(), m_fid); |
| if (it == m_fids.end()) { |
| |
| |
| |
| TFrameId fid = m_fids.back(); |
| setFid(fid); |
| } else |
| setFid(*it); |
| } else { |
| setFrame(m_frame + 1); |
| } |
| } |
| |
| |
| |
| void TFrameHandle::prevFrame() |
| { |
| if (m_frameType == LevelFrame) { |
| |
| if (m_fids.size() <= 0) |
| return; |
| std::vector<TFrameId>::iterator it; |
| it = std::lower_bound(m_fids.begin(), m_fids.end(), m_fid); |
| |
| if (it != m_fids.end() && it != m_fids.begin()) { |
| --it; |
| setFid(*it); |
| } else { |
| |
| if (!m_fids.empty() && m_fid > m_fids.back()) |
| setFid(m_fids.back()); |
| } |
| } else { |
| if (m_frame > 0) |
| setFrame(m_frame - 1); |
| } |
| } |
| |
| |
| |
| void TFrameHandle::firstFrame() |
| { |
| if (m_frameType == LevelFrame) { |
| |
| if (m_fids.size() <= 0) |
| return; |
| setFid(m_fids.front()); |
| } else { |
| |
| |
| setFrame(m_frame0); |
| } |
| } |
| |
| |
| |
| void TFrameHandle::lastFrame() |
| { |
| if (m_frameType == LevelFrame) { |
| |
| if (m_fids.size() <= 0) |
| return; |
| setFid(m_fids.back()); |
| } else { |
| |
| |
| if (m_frame1 > 0) |
| setFrame(m_frame1); |
| } |
| } |
| |
| |
| |
| void TFrameHandle::setPlaying(bool isPlaying) |
| { |
| if (m_isPlaying == isPlaying) |
| return; |
| m_isPlaying = isPlaying; |
| emit isPlayingStatusChanged(); |
| } |
| |
| |
| #ifdef LEVO |
| |
| void TFrameHandle::startPlaying(bool looping) |
| { |
| if (m_previewFrameRate == 0) |
| return; |
| if (isScrubbing()) |
| stopScrubbing(); |
| setTimer(m_previewFrameRate); |
| m_looping = looping; |
| emit playStarted(); |
| } |
| |
| |
| |
| void TFrameHandle::stopPlaying() |
| { |
| if (m_timerId != 0) |
| killTimer(m_timerId); |
| m_timerId = 0; |
| m_looping = false; |
| emit playStopped(); |
| } |
| |
| |
| #endif |
| |
| void TFrameHandle::setTimer(int frameRate) |
| { |
| m_previewFrameRate = frameRate; |
| if (m_timerId != 0) |
| killTimer(m_timerId); |
| int interval = troundp(1000.0 / double(m_previewFrameRate)); |
| m_timerId = startTimer(interval); |
| } |
| |
| |
| |
| void TFrameHandle::timerEvent(QTimerEvent *event) |
| { |
| assert(isScrubbing()); |
| |
| int elapsedTime = m_clock.elapsed(); |
| int frame = m_scrubRange.first + elapsedTime * m_fps / 1000; |
| int lastFrame = m_scrubRange.second; |
| if (frame >= lastFrame) { |
| if (m_frame != lastFrame) |
| setFrame(lastFrame); |
| stopScrubbing(); |
| } else |
| setFrame(frame); |
| } |
| |
| |
| |
| int TFrameHandle::getMaxFrameIndex() const |
| { |
| if (m_frameType == LevelFrame) { |
| |
| if (m_fids.size() <= 0) |
| return -1; |
| else |
| return m_fids.size() - 1; |
| } else |
| |
| return m_sceneFrameSize - 1; |
| } |
| |
| |
| |
| int TFrameHandle::getFrameIndex() const |
| { |
| if (m_frameType == LevelFrame) { |
| |
| if (m_fids.size() > 0) { |
| std::vector<TFrameId>::const_iterator it = std::find(m_fids.begin(), m_fids.end(), m_fid); |
| if (it != m_fids.end()) |
| return std::distance(m_fids.begin(), it); |
| else { |
| if (m_fid > m_fids.back()) |
| return m_fids.size(); |
| else |
| return -1; |
| } |
| } else |
| return -1; |
| } else |
| return m_frame; |
| } |
| |
| |
| |
| QString TFrameHandle::getFrameIndexName(int index) const |
| { |
| if (m_frameType == LevelFrame) { |
| if (m_fid.getNumber() <= 0) |
| return ""; |
| else { |
| return QString::number(m_fid.getNumber()); |
| } |
| } else |
| return QString::number(m_frame + 1); |
| } |
| |
| void TFrameHandle::setFrameIndex(int index) |
| { |
| if (m_frameType == LevelFrame) { |
| |
| if (m_fids.size() > 0 && 0 <= index && index < (int)m_fids.size()) |
| setFid(m_fids[index]); |
| } else |
| setFrame(index); |
| } |
| |
| void TFrameHandle::setFrameIndexByName(const QString &str) |
| { |
| int num = str.toInt(); |
| if (m_frameType == LevelFrame) { |
| setFid(TFrameId(num)); |
| } else |
| setFrame(num - 1); |
| } |
| |
| void TFrameHandle::scrubColumn(int r0, int r1, TXshSoundColumn *audioColumn, double framePerSecond) |
| { |
| m_audioColumn = audioColumn; |
| if (!scrub(r0, r1, framePerSecond)) |
| m_audioColumn = 0; |
| } |
| |
| void TFrameHandle::scrubXsheet(int r0, int r1, TXsheet *xsheet, double framePerSecond) |
| { |
| m_xsheet = xsheet; |
| if (!scrub(r0, r1, framePerSecond)) |
| m_xsheet = 0; |
| } |
| |
| bool TFrameHandle::scrub(int r0, int r1, double framePerSecond) |
| { |
| if (isPlaying() || isScrubbing()) |
| return false; |
| bool onlyOneFrame = (r0 == r1); |
| |
| if (!isScrubbing() || !onlyOneFrame) |
| emit scrubStarted(); |
| if (!onlyOneFrame) { |
| m_fps = framePerSecond; |
| m_scrubRange = std::make_pair(r0, r1); |
| } |
| setFrame(r0); |
| |
| if (m_audioColumn) |
| m_audioColumn->scrub(r0, r1); |
| else if (m_xsheet) { |
| int i; |
| for (i = r0; i <= r1; i++) |
| m_xsheet->scrub(i); |
| } |
| |
| if (onlyOneFrame) |
| return false; |
| |
| m_clock.start(); |
| m_timerId = startTimer(40); |
| return true; |
| } |
| |
| void TFrameHandle::stopScrubbing() |
| { |
| if (!isScrubbing()) |
| return; |
| if (m_timerId > 0) |
| killTimer(m_timerId); |
| m_timerId = 0; |
| m_scrubRange = std::make_pair(0, -1); |
| if (m_audioColumn) |
| m_audioColumn = 0; |
| if (m_xsheet) |
| m_xsheet = 0; |
| m_fps = 0; |
| emit scrubStopped(); |
| } |
| |