| |
| |
| #include "tools/tool.h" |
| #include "tools/toolutils.h" |
| #include "tools/cursors.h" |
| |
| #include "toonz/tframehandle.h" |
| #include "toonz/txshlevelhandle.h" |
| #include "toonz/tscenehandle.h" |
| #include "toonzqt/selectioncommandids.h" |
| |
| #include "toonzqt/selection.h" |
| #include "tproperty.h" |
| #include "tdata.h" |
| #include "tconvert.h" |
| #include "tgl.h" |
| #include "tstroke.h" |
| #include "tvectorimage.h" |
| |
| #include "toonz/hook.h" |
| #include "toonz/txshlevel.h" |
| #include "toonz/toonzscene.h" |
| #include "toonz/txsheet.h" |
| #include "toonz/txshcell.h" |
| #include "toonz/txshcolumn.h" |
| #include "toonz/tstageobjecttree.h" |
| #include "toonz/txshsimplelevel.h" |
| #include "toonz/levelproperties.h" |
| #include "toonz/txsheethandle.h" |
| |
| #include <QMessageBox> |
| #include <math.h> |
| |
| |
| #include <QCoreApplication> |
| #include <QKeyEvent> |
| |
| using namespace ToolUtils; |
| |
| class TrackerTool; |
| |
| |
| namespace { |
| |
| |
| |
| |
| |
| |
| class TrackerRegionSelection final : public TSelection { |
| TXshLevelP m_level; |
| std::set<std::pair<int, int>> |
| m_objtp; |
| TrackerTool *m_tool; |
| |
| public: |
| TrackerRegionSelection() : m_tool(0) {} |
| |
| void setTool(TrackerTool *tool) { m_tool = tool; } |
| |
| TSelection *clone() const { return new TrackerRegionSelection(*this); } |
| void setLevel(const TXshLevelP &level) { m_level = level; } |
| |
| void select(int objectId, int trackerRegionIndex) { |
| m_objtp.insert(std::make_pair(objectId, trackerRegionIndex)); |
| } |
| void deselect(int objectId, int trackerRegionIndex) { |
| m_objtp.erase(std::make_pair(objectId, trackerRegionIndex)); |
| } |
| |
| bool isSelected(int objectId, int trackerRegionIndex) const { |
| return m_objtp.count(std::make_pair(objectId, trackerRegionIndex)) > 0; |
| } |
| void invertSelection(int objectId, int trackerRegionIndex) { |
| if (isSelected(objectId, trackerRegionIndex)) |
| deselect(objectId, trackerRegionIndex); |
| else |
| select(objectId, trackerRegionIndex); |
| } |
| |
| bool isEmpty() const override { return m_objtp.empty(); } |
| |
| void selectNone() override { m_objtp.clear(); } |
| |
| HookSet *getHookSet() const { |
| TXshLevel *xl = TTool::getApplication()->getCurrentLevel()->getLevel(); |
| |
| if (!xl) return 0; |
| return xl->getHookSet(); |
| } |
| |
| TDataP getData() { return TDataP(); } |
| TDataP cutData() { return TDataP(); } |
| |
| TDataP clearData() { |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| } |
| |
| TDataP pasteData(const TDataP &data) { return TDataP(); } |
| |
| void resetData(const TDataP &data, bool insert) {} |
| |
| bool select(const TSelection *s) { |
| if (const TrackerRegionSelection *hs = |
| dynamic_cast<const TrackerRegionSelection *>(s)) { |
| m_level = hs->m_level; |
| m_objtp = hs->m_objtp; |
| return true; |
| } else |
| return false; |
| } |
| |
| void enableCommands() override; |
| void convertToRegion(); |
| }; |
| |
| } |
| |
| |
| |
| |
| |
| class TrackerTool final : public TTool { |
| Q_DECLARE_TR_FUNCTIONS(TrackerTool) |
| |
| TrackerRegionSelection m_selection; |
| TPointD m_firstPos, m_lastPos; |
| |
| int m_hookSelectedIndex; |
| int m_lastHookSelectedIndex; |
| bool m_deselectArmed; |
| bool m_newObjectAdded; |
| |
| |
| |
| TPropertyGroup m_prop; |
| TDoubleProperty m_toolSizeWidth; |
| TDoubleProperty m_toolSizeHeight; |
| TIntProperty m_toolPosX; |
| TIntProperty m_toolPosY; |
| TRectD m_shapeBBox; |
| |
| bool m_buttonDown; |
| bool m_dragged; |
| bool m_picked; |
| TPointD m_pos; |
| TPointD m_oldPos; |
| |
| int m_what; |
| enum { |
| Outside, |
| Inside, |
| P00, |
| P01, |
| P10, |
| P11, |
| P1M, |
| PM1, |
| P0M, |
| PM0, |
| ADD_OBJECT, |
| NormalHook |
| }; |
| |
| public: |
| TrackerTool(); |
| |
| ToolType getToolType() const override { return TTool::LevelReadTool; } |
| |
| void updateTranslation() override; |
| |
| TrackerObjectsSet *getTrackerObjectsSet() const; |
| HookSet *getHookSet() const; |
| void draw() override; |
| |
| void deleteSelectedTrackerRegion(); |
| |
| void leftButtonDown(const TPointD &pos, const TMouseEvent &e) override; |
| void leftButtonDrag(const TPointD &pos, const TMouseEvent &e) override; |
| void leftButtonUp(const TPointD &pos, const TMouseEvent &) override; |
| void mouseMove(const TPointD &pos, const TMouseEvent &e) override; |
| |
| bool keyDown(QKeyEvent *event) override; |
| |
| void onEnter() override; |
| void onLeave() override; |
| void onActivate() override; |
| void onDeactivate() override; |
| |
| void onImageChanged() override {} |
| void reset() override; |
| TPropertyGroup *getProperties(int targetType) override { return &m_prop; } |
| |
| void onSelectionChanged() { invalidate(); } |
| bool onPropertyChanged(std::string propertyName) override; |
| bool select(const TSelection *) { return false; } |
| |
| bool pick(int &hookIndex, const TPointD &pos); |
| |
| int getCursorId() const override; |
| |
| |
| bool isEventAcceptable(QEvent *e) override; |
| |
| } trackerTool; |
| |
| |
| |
| |
| |
| TrackerTool::TrackerTool() |
| : TTool("T_Tracker") |
| , m_hookSelectedIndex(-1) |
| , m_lastHookSelectedIndex(-1) |
| , m_deselectArmed(false) |
| , m_toolSizeWidth("Width:", 0, 1000, 10) |
| , m_toolSizeHeight("Height:", 0, 1000, 10) |
| , m_toolPosX("X:", -9000, 9000, 10) |
| , m_toolPosY("Y:", -9000, 9000, 10) |
| , m_shapeBBox() |
| , m_buttonDown(false) |
| , m_dragged(false) |
| , m_oldPos(TPointD(0, 0)) |
| , m_newObjectAdded(false) { |
| bind(TTool::CommonLevels); |
| m_prop.bind(m_toolSizeWidth); |
| m_prop.bind(m_toolSizeHeight); |
| m_prop.bind(m_toolPosX); |
| m_prop.bind(m_toolPosY); |
| m_selection.setTool(this); |
| } |
| |
| |
| |
| void TrackerTool::updateTranslation() { |
| m_toolSizeWidth.setQStringName(tr("Width:")); |
| m_toolSizeHeight.setQStringName(tr("Height:")); |
| m_toolPosX.setQStringName(tr("X:")); |
| m_toolPosY.setQStringName(tr("Y:")); |
| } |
| |
| |
| |
| TrackerObjectsSet *TrackerTool::getTrackerObjectsSet() const { |
| HookSet *hookSet = getHookSet(); |
| if (!hookSet) return 0; |
| return hookSet->getTrackerObjectsSet(); |
| } |
| HookSet *TrackerTool::getHookSet() const { |
| TXshLevel *xl = TTool::getApplication()->getCurrentLevel()->getLevel(); |
| if (!xl) return 0; |
| return xl->getHookSet(); |
| } |
| |
| |
| |
| void TrackerTool::draw() { |
| HookSet *hookSet = getHookSet(); |
| if (!hookSet) return; |
| if (hookSet->getHookCount() <= m_hookSelectedIndex) m_hookSelectedIndex = -1; |
| |
| TFrameId fid = getCurrentFid(); |
| int selectedObjectId; |
| if (m_hookSelectedIndex >= 0 && hookSet->getHook(m_hookSelectedIndex)) |
| selectedObjectId = |
| hookSet->getHook(m_hookSelectedIndex)->getTrackerObjectId(); |
| else |
| selectedObjectId = -1; |
| int i = 0; |
| double pixelSize = getPixelSize(); |
| |
| std::vector<TRectD> balloons; |
| |
| for (i = 0; i < hookSet->getHookCount(); i++) { |
| Hook *hook = hookSet->getHook(i); |
| if (!hook || hook->isEmpty()) continue; |
| assert(hook); |
| |
| if (hook->getTrackerObjectId() >= 0) { |
| TRectD rect; |
| rect = hook->getTrackerRegion(fid); |
| TPixel32 textColor(127, 127, 127); |
| TPixel32 trackerObjectColor(0, 0, 0); |
| |
| if (hook->getTrackerObjectId() == selectedObjectId) { |
| if (m_hookSelectedIndex == i) { |
| TPixel32 frameColor(127, 127, 127); |
| drawSquare(0.5 * (rect.getP01() + rect.getP11()), pixelSize * 4, |
| frameColor); |
| drawSquare(0.5 * (rect.getP11() + rect.getP10()), pixelSize * 4, |
| frameColor); |
| drawSquare(rect.getP00(), pixelSize * 4, frameColor); |
| drawSquare(rect.getP10(), pixelSize * 4, frameColor); |
| trackerObjectColor = TPixel32(183, 227, 0); |
| textColor = TPixel32(155, 213, 219); |
| } else { |
| textColor = TPixel32(183, 227, 0); |
| trackerObjectColor = TPixel32(155, 213, 219); |
| } |
| } else |
| trackerObjectColor = TPixel32(0, 0, 0); |
| |
| tglColor(trackerObjectColor); |
| tglDrawRect(rect); |
| tglColor(textColor); |
| glPushMatrix(); |
| glTranslated(hook->getPos(fid).x, hook->getPos(fid).y, 0); |
| glScaled(pixelSize, pixelSize, 1); |
| int objectId = hook->getTrackerObjectId(); |
| std::string text({static_cast<char>('A' + objectId)}); |
| tglDrawText(TPointD(-15, 10), text); |
| glPopMatrix(); |
| } |
| |
| TPointD p0 = hook->getAPos(fid); |
| TPointD p1 = hook->getBPos(fid); |
| bool linked = p0 == p1; |
| drawHook(p0, linked ? ToolUtils::NormalHook : ToolUtils::PassHookA, |
| m_hookSelectedIndex == i); |
| std::string hookName = std::to_string(i + 1); |
| TPixel32 balloonColor(200, 220, 205, 200); |
| TPoint balloonOffset(20, 20); |
| drawBalloon(p0, hookName, balloonColor, balloonOffset, pixelSize, false, |
| &balloons); |
| if (!linked) { |
| drawHook(p1, PassHookB, m_selection.isSelected(i, 2)); |
| drawBalloon(p1, hookName, balloonColor, balloonOffset, pixelSize, false, |
| &balloons); |
| } |
| } |
| } |
| |
| |
| |
| bool TrackerTool::pick(int &hookIndex, const TPointD &pos) { |
| double minDistance = -1; |
| m_what = Outside; |
| |
| HookSet *hookSet = getHookSet(); |
| if (!hookSet) return false; |
| TFrameId fid = getCurrentFid(); |
| |
| double pixelSize = getPixelSize(); |
| int i = 0; |
| for (i = 0; i < (int)hookSet->getHookCount(); i++) { |
| Hook *hook = hookSet->getHook(i); |
| if (!hook || hook->isEmpty()) continue; |
| int trackerObjectId = hook->getTrackerObjectId(); |
| if (trackerObjectId < 0) |
| { |
| TPointD hookPos = hook->getPos(fid); |
| TRectD overArea = |
| TRectD(hookPos.x - 20 * pixelSize, hookPos.y - 20 * pixelSize, |
| hookPos.x + 20 * pixelSize, hookPos.y + 20 * pixelSize); |
| if (overArea.contains(pos)) { |
| hookIndex = i; |
| m_what = NormalHook; |
| return true; |
| } |
| } else { |
| |
| |
| |
| |
| |
| |
| |
| TPointD centerPos = hook->getPos(fid); |
| double width = hook->getTrackerRegionWidth(); |
| double height = hook->getTrackerRegionHeight(); |
| double distance = tdistance2(centerPos, pos); |
| TPointD localPos = pos - centerPos; |
| TRectD rect = hook->getTrackerRegion(fid); |
| TRectD overArea = TRectD( |
| rect.getP00().x - 4 * pixelSize, rect.getP00().y - 4 * pixelSize, |
| rect.getP11().x + 4 * pixelSize, rect.getP11().y + 4 * pixelSize); |
| |
| if (overArea.contains(pos)) { |
| if (distance < minDistance || minDistance == -1) { |
| minDistance = distance; |
| hookIndex = i; |
| |
| m_what = Inside; |
| |
| |
| double x = |
| 0.5 * (rect.getP01().x + rect.getP11().x); |
| TPointD my = TPointD(x, rect.getP11().y); |
| TRectD scaleYArea = |
| TRectD(my.x - 4 * pixelSize, my.y - 4 * pixelSize, |
| my.x + 4 * pixelSize, my.y + 4 * pixelSize); |
| if (scaleYArea.contains(pos)) m_what = PM1; |
| |
| double y = 0.5 * (rect.getP11().y + |
| rect.getP10().y); |
| TPointD mx = TPointD(rect.getP10().x, y); |
| TRectD scaleXArea = |
| TRectD(mx.x - 4 * pixelSize, mx.y - 4 * pixelSize, |
| mx.x + 4 * pixelSize, mx.y + 4 * pixelSize); |
| if (scaleXArea.contains(pos)) m_what = P1M; |
| |
| TRectD resizeArea = TRectD( |
| rect.getP10().x - 4 * pixelSize, rect.getP10().y - 4 * pixelSize, |
| rect.getP10().x + 4 * pixelSize, rect.getP10().y + 4 * pixelSize); |
| if (resizeArea.contains(pos)) m_what = P10; |
| |
| |
| TRectD scaleArea = TRectD( |
| rect.getP00().x - 4 * pixelSize, rect.getP00().y - 4 * pixelSize, |
| rect.getP00().x + 4 * pixelSize, rect.getP00().y + 4 * pixelSize); |
| if (scaleArea.contains(pos)) m_what = P00; |
| } |
| } |
| |
| } |
| } |
| return (minDistance != -1); |
| } |
| |
| |
| |
| void TrackerTool::leftButtonDown(const TPointD &pos, const TMouseEvent &e) { |
| m_buttonDown = true; |
| m_picked = true; |
| TXshLevel *xl = TTool::getApplication()->getCurrentLevel()->getLevel(); |
| if (!xl) return; |
| m_selection.setLevel(xl); |
| m_firstPos = m_lastPos = pos; |
| |
| m_deselectArmed = false; |
| |
| m_oldPos = pos; |
| double pixelSize = getPixelSize(); |
| |
| HookSet *hookSet = xl->getHookSet(); |
| if (!hookSet) return; |
| TrackerObjectsSet *trackerObjectsSet = getTrackerObjectsSet(); |
| TFrameId fid = getCurrentFid(); |
| if (!trackerObjectsSet) return; |
| if (pick(m_hookSelectedIndex, pos)) { |
| if (m_what == NormalHook) { |
| invalidate(); |
| return; |
| } |
| Hook *hook = hookSet->getHook(m_hookSelectedIndex); |
| if (!hook) return; |
| m_selection.selectNone(); |
| m_selection.select(m_hookSelectedIndex, m_hookSelectedIndex); |
| m_toolSizeWidth.setValue(hook->getTrackerRegionWidth()); |
| m_toolSizeHeight.setValue(hook->getTrackerRegionHeight()); |
| m_toolPosX.setValue(hook->getPos(fid).x); |
| m_toolPosY.setValue(hook->getPos(fid).y); |
| m_toolSizeWidth.notifyListeners(); |
| m_toolSizeHeight.notifyListeners(); |
| m_toolPosX.notifyListeners(); |
| m_toolPosY.notifyListeners(); |
| } else { |
| m_selection.selectNone(); |
| |
| if (xl->getSimpleLevel() && !xl->getSimpleLevel()->isReadOnly()) { |
| TFrameId fid = getCurrentFid(); |
| m_what = P10; |
| |
| |
| |
| |
| int trackerObjectId; |
| if (m_hookSelectedIndex == -1 || |
| hookSet->getHook(m_hookSelectedIndex) == 0) { |
| trackerObjectId = trackerObjectsSet->addObject(); |
| m_newObjectAdded = true; |
| } else |
| trackerObjectId = |
| hookSet->getHook(m_hookSelectedIndex)->getTrackerObjectId(); |
| |
| |
| if (trackerObjectId == -1) { |
| trackerObjectId = trackerObjectsSet->addObject(); |
| m_newObjectAdded = true; |
| } |
| |
| |
| Hook *newHook = hookSet->addHook(); |
| if (newHook) { |
| newHook->setTrackerObjectId(trackerObjectId); |
| newHook->setAPos(fid, pos); |
| newHook->setTrackerRegionHeight(pixelSize * 10); |
| newHook->setTrackerRegionWidth(pixelSize * 10); |
| |
| m_hookSelectedIndex = newHook->getId(); |
| } else { |
| if (hookSet->getHookCount() >= 20) |
| QMessageBox::warning(0, "TrackerTool Error", |
| "Hooks number must be at most 20"); |
| m_hookSelectedIndex = -1; |
| } |
| } |
| } |
| m_selection.makeCurrent(); |
| invalidate(); |
| return; |
| } |
| |
| |
| |
| void TrackerTool::leftButtonDrag(const TPointD &pp, const TMouseEvent &e) { |
| if (!m_buttonDown) return; |
| if (m_hookSelectedIndex < 0 && m_what != NormalHook) return; |
| HookSet *hookSet = getHookSet(); |
| if (!hookSet) return; |
| assert(hookSet->getHook(m_hookSelectedIndex) != 0); |
| TrackerObjectsSet *trackerObjectsSet = getTrackerObjectsSet(); |
| TFrameId fid = getCurrentFid(); |
| if (!trackerObjectsSet) return; |
| |
| if (m_dragged == false) { |
| m_dragged = true; |
| } |
| |
| TXshLevel *xl = TTool::getApplication()->getCurrentLevel()->getLevel(); |
| if (xl->getSimpleLevel() && xl->getSimpleLevel()->isReadOnly() && |
| m_what != Inside && m_what != NormalHook) |
| return; |
| |
| if (m_dragged == true) { |
| Hook *hook = new Hook(); |
| hook = getHookSet()->getHook(m_hookSelectedIndex); |
| if (!hook || hook->isEmpty()) return; |
| TPointD deltaPos = pp - m_oldPos; |
| m_oldPos = pp; |
| double newWidth = hook->getTrackerRegionWidth(); |
| double newHeight = hook->getTrackerRegionHeight(); |
| TAffine aff; |
| const double epsilon = 1e-2; |
| TPointD posCenter = hook->getPos(fid); |
| double a = norm2(pp - posCenter); |
| double b = norm2(pp - deltaPos - posCenter); |
| switch (m_what) { |
| case Inside: |
| hook->setAPos(fid, hook->getPos(fid) + deltaPos); |
| break; |
| case NormalHook: |
| { |
| hook->setAPos(fid, hook->getPos(fid) + deltaPos); |
| invalidate(); |
| return; |
| } |
| case P00: |
| { |
| if (a <= epsilon || b <= epsilon) return; |
| aff = TScale(posCenter, sqrt(a / b)); |
| TRectD rect = hook->getTrackerRegion(fid); |
| TPointD av(hook->getTrackerRegion(fid).getP00()); |
| TPointD av2(hook->getTrackerRegion(fid).getP11()); |
| av = aff * av; |
| av2 = aff * av2; |
| rect = TRectD(av, av2); |
| newWidth = rect.getLx(); |
| newHeight = rect.getLy(); |
| break; |
| } |
| case P10: |
| { |
| TPointD pos = hook->getPos(fid); |
| TPointD diffPos = pp - pos; |
| int signumx = 1; |
| int signumy = 1; |
| if (diffPos.x < 0) signumx = -1; |
| if (diffPos.y < 0) signumy = -1; |
| newWidth = fabs(hook->getTrackerRegionWidth() + 2 * signumx * deltaPos.x); |
| newHeight = |
| fabs(hook->getTrackerRegionHeight() + 2 * signumy * deltaPos.y); |
| |
| |
| break; |
| } |
| case P1M: |
| { |
| TRectD rect = hook->getTrackerRegion(fid); |
| rect = rect.enlarge(deltaPos.x, 0); |
| newWidth = rect.getLx(); |
| break; |
| } |
| case PM1: |
| { |
| TRectD rect = hook->getTrackerRegion(fid); |
| rect = rect.enlarge(0, deltaPos.y); |
| newHeight = rect.getLy(); |
| break; |
| } |
| default: |
| break; |
| } |
| if (newWidth > m_toolSizeWidth.getRange().second || |
| newHeight > m_toolSizeHeight.getRange().second) |
| return; |
| hook->setTrackerRegionWidth(newWidth); |
| hook->setTrackerRegionHeight(newHeight); |
| m_toolSizeWidth.setValue(hook->getTrackerRegionWidth()); |
| m_toolSizeHeight.setValue(hook->getTrackerRegionHeight()); |
| m_toolPosX.setValue(hook->getPos(fid).x); |
| m_toolPosY.setValue(hook->getPos(fid).y); |
| m_toolPosX.notifyListeners(); |
| m_toolPosY.notifyListeners(); |
| m_toolSizeWidth.notifyListeners(); |
| m_toolSizeHeight.notifyListeners(); |
| } |
| |
| |
| invalidate(); |
| } |
| |
| |
| |
| void TrackerTool::leftButtonUp(const TPointD &pos, const TMouseEvent &) { |
| |
| |
| if (!m_buttonDown) return; |
| |
| |
| |
| if (m_dragged == false && m_hookSelectedIndex == m_lastHookSelectedIndex) { |
| m_hookSelectedIndex = -1; |
| } |
| if (m_newObjectAdded) { |
| m_hookSelectedIndex = -1; |
| m_newObjectAdded = false; |
| |
| TTool::getApplication()->getCurrentXsheet()->notifyXsheetChanged(); |
| } |
| m_lastHookSelectedIndex = m_hookSelectedIndex; |
| |
| m_dragged = false; |
| m_buttonDown = false; |
| |
| TXshLevel *xl = TTool::getApplication()->getCurrentLevel()->getLevel(); |
| if (!xl || !xl->getSimpleLevel()) return; |
| xl->getSimpleLevel()->getProperties()->setDirtyFlag(true); |
| |
| |
| return; |
| } |
| |
| |
| |
| void TrackerTool::deleteSelectedTrackerRegion() { |
| TTool::Application *app = TTool::getApplication(); |
| TXshLevel *xl = app->getCurrentLevel()->getLevel(); |
| HookSet *hookSet = xl->getHookSet(); |
| if (!xl || !xl->getSimpleLevel() || !hookSet || |
| xl->getSimpleLevel()->isReadOnly()) |
| return; |
| |
| |
| TFrameId fid = getCurrentFid(); |
| |
| Hook *hook = hookSet->getHook(m_hookSelectedIndex); |
| m_hookSelectedIndex = -1; |
| if (!hook || hook->isEmpty()) return; |
| |
| hookSet->clearHook(hook); |
| |
| |
| app->getCurrentScene() |
| ->getScene() |
| ->getXsheet() |
| ->getStageObjectTree() |
| ->invalidateAll(); |
| invalidate(); |
| |
| |
| TTool::getApplication()->getCurrentXsheet()->notifyXsheetChanged(); |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| } |
| |
| |
| |
| void TrackerTool::mouseMove(const TPointD &pos, const TMouseEvent &e) { |
| m_picked = true; |
| if (m_dragged == false) { |
| int hookSelectedIndex; |
| pick(hookSelectedIndex, pos); |
| if (hookSelectedIndex < 0) { |
| m_pos = pos; |
| m_picked = false; |
| } |
| invalidate(); |
| } |
| } |
| |
| |
| bool TrackerTool::onPropertyChanged(std::string propertyName) { |
| HookSet *hookSet = getHookSet(); |
| if (!hookSet || m_hookSelectedIndex < 0) return false; |
| TFrameId fid = getCurrentFid(); |
| Hook *hook = hookSet->getHook(m_hookSelectedIndex); |
| if (!hook || hook->isEmpty()) return false; |
| if (propertyName == "Width:") { |
| double width = m_toolSizeWidth.getValue(); |
| hook->setTrackerRegionWidth(width); |
| } |
| if (propertyName == "Height:") { |
| double height = m_toolSizeHeight.getValue(); |
| hook->setTrackerRegionHeight(height); |
| } |
| if (propertyName == "X:") { |
| double x = m_toolPosX.getValue(); |
| TPointD pos = hook->getPos(fid); |
| pos.x = x; |
| hook->setAPos(fid, pos); |
| } |
| if (propertyName == "Y:") { |
| double y = m_toolPosY.getValue(); |
| TPointD pos = hook->getPos(fid); |
| pos.y = y; |
| hook->setAPos(fid, pos); |
| } |
| invalidate(); |
| return true; |
| } |
| void TrackerTool::reset() { m_hookSelectedIndex = -1; } |
| int TrackerTool::getCursorId() const { |
| switch (m_what) { |
| case Outside: |
| return ToolCursor::TrackerCursor; |
| case Inside: |
| return ToolCursor::MoveCursor; |
| case NormalHook: |
| return ToolCursor::MoveCursor; |
| case P00: |
| return ToolCursor::ScaleCursor; |
| case P01: |
| return ToolCursor::MoveCursor; |
| case P10: |
| return ToolCursor::ScaleCursor; |
| case P1M: |
| return ToolCursor::ScaleHCursor; |
| case PM1: |
| return ToolCursor::ScaleVCursor; |
| case ADD_OBJECT: |
| return ToolCursor::SplineEditorCursorAdd; |
| default: |
| return ToolCursor::TrackerCursor; |
| } |
| return ToolCursor::TrackerCursor; |
| } |
| bool TrackerTool::keyDown(QKeyEvent *event) { |
| TXshLevel *xl = TTool::getApplication()->getCurrentLevel()->getLevel(); |
| if (!xl) return false; |
| HookSet *hookSet = xl->getHookSet(); |
| if (!hookSet) return false; |
| TFrameId fid = getCurrentFid(); |
| Hook *hook = hookSet->getHook(m_hookSelectedIndex); |
| if (!hook || hook->isEmpty()) return false; |
| TPointD hookPos = hook->getPos(fid); |
| TPointD delta(0, 0); |
| double pixelSize = getPixelSize(); |
| |
| switch (event->key()) { |
| case Qt::Key_Up: |
| delta.y = 1; |
| break; |
| case Qt::Key_Down: |
| delta.y = -1; |
| break; |
| case Qt::Key_Left: |
| delta.x = -1; |
| break; |
| case Qt::Key_0: |
| delta.x = 1; |
| break; |
| case Qt::Key_PageUp: |
| hook->setTrackerObjectId(-1); |
| break; |
| case Qt::Key_PageDown: |
| { |
| TrackerObjectsSet *trackerObjectsSet = getTrackerObjectsSet(); |
| if (!trackerObjectsSet) return false; |
| int trackerObjectId = hook->getTrackerObjectId(); |
| if (trackerObjectId != -1) return false; |
| trackerObjectId = trackerObjectsSet->addObject(); |
| hook->setTrackerObjectId(trackerObjectId); |
| hook->setTrackerRegionHeight(pixelSize * 20); |
| hook->setTrackerRegionWidth(pixelSize * 20); |
| } break; |
| default: |
| return false; |
| break; |
| } |
| |
| hookPos += delta; |
| hook->setAPos(fid, hookPos); |
| |
| |
| |
| return true; |
| } |
| |
| void TrackerTool::onEnter() { |
| HookSet *hookSet = getHookSet(); |
| if (!hookSet || hookSet->getHookCount() <= m_hookSelectedIndex) |
| m_hookSelectedIndex = -1; |
| } |
| |
| |
| |
| void TrackerTool::onLeave() { |
| TrackerObjectsSet *trackerObjectsSet = getTrackerObjectsSet(); |
| if (trackerObjectsSet) trackerObjectsSet->clearAll(); |
| } |
| |
| |
| |
| void TrackerTool::onActivate() {} |
| |
| |
| |
| void TrackerTool::onDeactivate() { |
| |
| |
| } |
| |
| |
| |
| |
| |
| bool TrackerTool::isEventAcceptable(QEvent *e) { |
| if (!isEnabled()) return false; |
| TXshLevel *xl = TTool::getApplication()->getCurrentLevel()->getLevel(); |
| if (!xl) return false; |
| HookSet *hookSet = xl->getHookSet(); |
| if (!hookSet) return false; |
| Hook *hook = hookSet->getHook(m_hookSelectedIndex); |
| if (!hook || hook->isEmpty()) return false; |
| |
| QKeyEvent *keyEvent = static_cast<QKeyEvent *>(e); |
| |
| if (keyEvent->modifiers() & Qt::ShiftModifier) return false; |
| int key = keyEvent->key(); |
| return (key == Qt::Key_Up || key == Qt::Key_Down || key == Qt::Key_Left || |
| key == Qt::Key_Right); |
| |
| |
| } |
| |
| |
| |
| static TTool *getTrackerToolTool() { return &trackerTool; } |
| |
| |
| |
| void TrackerRegionSelection::enableCommands() { |
| enableCommand(m_tool, MI_Clear, &TrackerTool::deleteSelectedTrackerRegion); |
| |
| |
| } |
| |
| void TrackerRegionSelection::convertToRegion() { |
| int i = 0; |
| TXshLevel *xl = TTool::getApplication()->getCurrentLevel()->getLevel(); |
| if (!xl) return; |
| HookSet *hookSet = xl->getHookSet(); |
| if (!hookSet) return; |
| for (i = 0; i < hookSet->getHookCount(); i++) { |
| if (isSelected(i, i)) { |
| int trackerObjectId = hookSet->getTrackerObjectsSet()->addObject(); |
| Hook *hook = hookSet->getHook(i); |
| if (!hook || hook->isEmpty()) continue; |
| hook->setTrackerObjectId(trackerObjectId); |
| } |
| } |
| } |
| |