shun-iwasawa 1d5937
#pragma once
shun-iwasawa 1d5937
shun-iwasawa 1d5937
#include "tools/tool.h"
shun-iwasawa 1d5937
shun-iwasawa 1d5937
class ShiftTraceTool final : public TTool {
shun-iwasawa 1d5937
public:
shun-iwasawa 1d5937
  enum CurveStatus {
shun-iwasawa 1d5937
    NoCurve,
shun-iwasawa 1d5937
    TwoPointsCurve,  // just during the first click&drag
shun-iwasawa 1d5937
    ThreePointsCurve
shun-iwasawa 1d5937
  };
shun-iwasawa 1d5937
shun-iwasawa 1d5937
  enum GadgetId {
shun-iwasawa 1d5937
    NoGadget,
shun-iwasawa 1d5937
    NoGadget_InBox,
shun-iwasawa 1d5937
    CurveP0Gadget,
shun-iwasawa 1d5937
    CurveP1Gadget,
shun-iwasawa 1d5937
    CurvePmGadget,
shun-iwasawa 1d5937
    MoveCenterGadget,
shun-iwasawa 1d5937
    RotateGadget,
shun-iwasawa 1d5937
    TranslateGadget,
shun-iwasawa 1d5937
    ScaleGadget
shun-iwasawa 1d5937
  };
shun-iwasawa 1d5937
  inline bool isCurveGadget(GadgetId id) const {
shun-iwasawa 1d5937
    return CurveP0Gadget <= id && id <= CurvePmGadget;
shun-iwasawa 1d5937
  }
shun-iwasawa 1d5937
shun-iwasawa 1d5937
private:
shun-iwasawa 1d5937
  TPointD m_oldPos, m_startPos;
shun-iwasawa 1d5937
  int m_ghostIndex;
shun-iwasawa 1d5937
  TPointD m_p0, m_p1, m_p2;
shun-iwasawa 1d5937
shun-iwasawa 1d5937
  CurveStatus m_curveStatus;
shun-iwasawa 1d5937
  GadgetId m_gadget;
shun-iwasawa 1d5937
  GadgetId m_highlightedGadget;
shun-iwasawa 1d5937
shun-iwasawa 1d5937
  TRectD m_box;
shun-iwasawa 1d5937
  TAffine m_dpiAff;
shun-iwasawa 1d5937
  int m_row[2];
shun-iwasawa 1d5937
  TAffine m_aff[2];
shun-iwasawa 1d5937
  TPointD m_center[2];
shun-iwasawa 1d5937
shun-iwasawa 1d5937
  TAffine m_oldAff;
shun-iwasawa 1d5937
shun-iwasawa 1d5937
public:
shun-iwasawa 1d5937
  ShiftTraceTool();
shun-iwasawa 1d5937
shun-iwasawa 1d5937
  ToolType getToolType() const override { return GenericTool; }
shun-iwasawa 1d5937
shun-iwasawa 1d5937
  void clearData();
shun-iwasawa 1d5937
  void updateData();
shun-iwasawa 1d5937
  void updateBox();
shun-iwasawa 1d5937
  void updateCurveAffs();
shun-iwasawa 1d5937
  void updateGhost();
shun-iwasawa 1d5937
shun-iwasawa 1d5937
  void reset() override;
shun-iwasawa 1d5937
shun-iwasawa 1d5937
  void mouseMove(const TPointD &, const TMouseEvent &e) override;
shun-iwasawa 1d5937
  void leftButtonDown(const TPointD &, const TMouseEvent &) override;
shun-iwasawa 1d5937
  void leftButtonDrag(const TPointD &, const TMouseEvent &) override;
shun-iwasawa 1d5937
  void leftButtonUp(const TPointD &, const TMouseEvent &) override;
shun-iwasawa 1d5937
  void draw() override;
shun-iwasawa 1d5937
shun-iwasawa 1d5937
  TAffine getGhostAff();
shun-iwasawa 1d5937
  GadgetId getGadget(const TPointD &);
shun-iwasawa 1d5937
  void drawDot(const TPointD ¢er, double r,
shun-iwasawa 1d5937
               const TPixel32 &color = TPixel32::White);
shun-iwasawa 1d5937
  void drawControlRect();
shun-iwasawa 1d5937
  void drawCurve();
shun-iwasawa 1d5937
shun-iwasawa 1d5937
  void onActivate() override;
shun-iwasawa 1d5937
  void onDeactivate() override;
shun-iwasawa 1d5937
shun-iwasawa 1d5937
  void onLeave() override;
shun-iwasawa 1d5937
shun-iwasawa 1d5937
  bool isEventAcceptable(QEvent *e) override;
shun-iwasawa 1d5937
shun-iwasawa 1d5937
  int getCursorId() const override;
shun-iwasawa 1d5937
shun-iwasawa 1d5937
  int getCurrentGhostIndex() { return m_ghostIndex; }
shun-iwasawa 1d5937
  void setCurrentGhostIndex(int index);
shun-iwasawa 1d5937
};