Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tools/cursormanager.h"
Toshihiro Shimizu 890ddd
#include "tools/tool.h"
Toshihiro Shimizu 890ddd
#include "tools/cursors.h"
Toshihiro Shimizu 890ddd
manongjohn da05a0
#ifdef TOONZQT_EXPORTS
manongjohn da05a0
#include "toonz/preferences.h"
manongjohn da05a0
#else
manongjohn 75da26
#include "../toonz/preferences.h"
manongjohn da05a0
#endif
manongjohn 75da26
Toshihiro Shimizu 890ddd
#include <qwidget></qwidget>
Toshihiro Shimizu 890ddd
#include <qpixmap></qpixmap>
Toshihiro Shimizu 890ddd
#include <assert.h></assert.h>
Toshihiro Shimizu 890ddd
#include <map></map>
Toshihiro Shimizu 890ddd
#include <qdebug></qdebug>
shun_iwasawa 009457
#include <qpainter></qpainter>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
const struct {
Shinya Kitaoka 120a6e
  int cursorType;
Shinya Kitaoka 120a6e
  const char *pixmapFilename;
Shinya Kitaoka 120a6e
  int x, y;
manongjohn 75da26
  bool flippable;
Toshihiro Shimizu 890ddd
} cursorInfo[] = {
manongjohn 75da26
    {ToolCursor::PenCursor, "brush", 16, 15, false},
manongjohn 75da26
    {ToolCursor::PenLargeCursor, "brush_large", 16, 15, false},
manongjohn 75da26
    {ToolCursor::PenCrosshairCursor, "brush_crosshair", 16, 15, false},
manongjohn 75da26
    {ToolCursor::BenderCursor, "bender", 9, 7, true},
manongjohn 75da26
    {ToolCursor::CutterCursor, "cutter", 6, 24, true},  // 12,20, ???},
manongjohn 75da26
    {ToolCursor::EraserCursor, "eraser", 7, 21, true},  // 15,16, ???},
manongjohn 75da26
    {ToolCursor::DistortCursor, "selection_distort", 11, 6, true},
manongjohn 75da26
    {ToolCursor::FillCursor, "fill", 3, 26, true},
manongjohn 75da26
    {ToolCursor::MoveCursor, "move", 15, 15, false},
manongjohn 75da26
    {ToolCursor::MoveEWCursor, "move_ew", 15, 15, false},
manongjohn 75da26
    {ToolCursor::MoveNSCursor, "move_ns", 15, 15, false},
manongjohn 75da26
    {ToolCursor::DisableCursor, "disable", 15, 15, false},
manongjohn 75da26
    {ToolCursor::MoveZCursor, "", 0, 0, false},
manongjohn 75da26
    {ToolCursor::MoveZCursorBase, "move_z_notext", 15, 15, false},
manongjohn 75da26
    {ToolCursor::FxGadgetCursor, "", 0, 0, false},
manongjohn 75da26
    {ToolCursor::FxGadgetCursorBase, "edit_FX_notext", 11, 6, true},
manongjohn 75da26
    {ToolCursor::FlipHCursor, "flip_h", 15, 15, false},
manongjohn 75da26
    {ToolCursor::FlipVCursor, "flip_v", 15, 15, false},
manongjohn 75da26
    {ToolCursor::IronCursor, "iron", 15, 15, true},
manongjohn 75da26
    {ToolCursor::LevelSelectCursor, "level_select", 7, 3, true},
manongjohn 75da26
    {ToolCursor::MagnetCursor, "magnet", 18, 18, true},
manongjohn 75da26
    {ToolCursor::PanCursor, "pan", 17, 17, true},
manongjohn 75da26
manongjohn 75da26
    {ToolCursor::PickerCursorLine, "", 0, 0, false},
manongjohn 75da26
    {ToolCursor::PickerCursorLineBase, "picker_style", 7, 22, true},
manongjohn 75da26
    {ToolCursor::PickerCursorArea, "", 0, 0, false},
manongjohn 75da26
    {ToolCursor::PickerCursorAreaBase, "picker_style", 7, 22, true},
manongjohn 75da26
    {ToolCursor::PickerCursor, "picker_style", 7, 22, true},
manongjohn 75da26
manongjohn 75da26
    {ToolCursor::PumpCursor, "pump", 16, 23, false},
manongjohn 75da26
    {ToolCursor::RotCursor, "rot", 15, 15, false},
manongjohn 75da26
    {ToolCursor::RotTopLeft, "rot_top_left", 15, 15, false},
manongjohn 75da26
    {ToolCursor::RotBottomRight, "rot_bottom_right", 15, 15, false},
manongjohn 75da26
    {ToolCursor::RotBottomLeft, "rot_bottom_left", 15, 15, false},
manongjohn 75da26
    {ToolCursor::RotateCursor, "rotate", 15, 19, true},
manongjohn 75da26
    {ToolCursor::ScaleCursor, "scale", 15, 15, false},
manongjohn 75da26
    {ToolCursor::ScaleInvCursor, "scale_inv", 15, 15, false},
manongjohn 75da26
    {ToolCursor::ScaleHCursor, "scale_h", 15, 15, false},
manongjohn 75da26
    {ToolCursor::ScaleVCursor, "scale_v", 15, 15, false},
manongjohn 75da26
    {ToolCursor::EditFxCursor, "", 0, 0, false},
manongjohn 75da26
    {ToolCursor::EditFxCursorBase, "edit_FX_notext", 11, 6, true},
manongjohn 75da26
    {ToolCursor::ScaleGlobalCursor, "scale_global", 15, 15, false},
manongjohn 75da26
    {ToolCursor::ScaleHVCursor, "", 0, 0, false},
manongjohn 75da26
    {ToolCursor::ScaleHVCursorBase, "scale_hv_notext", 15, 15, false},
manongjohn 75da26
    {ToolCursor::StrokeSelectCursor, "stroke_select", 11, 6, true},
manongjohn 75da26
    {ToolCursor::TapeCursor, "tape", 4, 23, true},
manongjohn 75da26
    {ToolCursor::TrackerCursor, "tracker", 16, 15, false},
manongjohn 75da26
    {ToolCursor::TypeInCursor, "type_in", 16, 19, false},
manongjohn 75da26
    {ToolCursor::TypeOutCursor, "type_out", 16, 19, false},
manongjohn 75da26
    {ToolCursor::ZoomCursor, "zoom", 14, 14, true},
manongjohn 75da26
    {ToolCursor::PinchCursor, "pinch_curve", 6, 16, true},
manongjohn 75da26
    {ToolCursor::PinchAngleCursor, "pinch_angle", 6, 16, true},
manongjohn 75da26
    {ToolCursor::PinchWaveCursor, "pinch_wave", 6, 16, true},
manongjohn 75da26
    {ToolCursor::SplineEditorCursor, "stroke_select", 11, 6, true},
manongjohn 75da26
    {ToolCursor::SplineEditorCursorAdd, "selection_add", 11, 6, true},
manongjohn 75da26
    {ToolCursor::SplineEditorCursorSelect, "selection_convert", 11, 6, true},
manongjohn 75da26
    {ToolCursor::NormalEraserCursor, "normaleraser", 7, 19, true},
manongjohn 75da26
    {ToolCursor::RectEraserCursor, "recteraser", 3, 26, true},
manongjohn 75da26
    {ToolCursor::PickerCursorOrganize, "picker_style_organize", 7, 22, true},
manongjohn 75da26
    {ToolCursor::PickerRGB, "", 0, 0, false},
manongjohn 75da26
    {ToolCursor::PickerRGBBase, "picker_style", 7, 22, true},
manongjohn 75da26
    {ToolCursor::PickerRGBWhite, "picker_rgb_white", 7, 22, true},
manongjohn 75da26
    {ToolCursor::FillCursorL, "karasu", 7, 25, true},
manongjohn 75da26
    {ToolCursor::RulerModifyCursor, "ruler_modify", 7, 7, true},
manongjohn 75da26
    {ToolCursor::RulerNewCursor, "ruler_new", 7, 7, true},
manongjohn 75da26
    {0, 0, 0, 0, false}};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
struct CursorData {
Shinya Kitaoka 120a6e
  QPixmap pixmap;
Shinya Kitaoka 120a6e
  int x, y;
Toshihiro Shimizu 890ddd
};
shun_iwasawa 009457
shun_iwasawa 009457
const struct {
shun_iwasawa 009457
  int decorateType;
shun_iwasawa 009457
  const char *pixmapFilename;
shun_iwasawa 009457
} decorateInfo[] = {{ToolCursor::Ex_FreeHand, "ex_freehand"},
shun_iwasawa 009457
                    {ToolCursor::Ex_PolyLine, "ex_polyline"},
shun_iwasawa 009457
                    {ToolCursor::Ex_Rectangle, "ex_rectangle"},
shun_iwasawa 009457
                    {ToolCursor::Ex_Line, "ex_line"},
shun_iwasawa 009457
                    {ToolCursor::Ex_Area, "ex_area"},
shun-iwasawa 43640b
                    {ToolCursor::Ex_Fill_NoAutopaint, "ex_fill_no_autopaint"},
manongjohn 75da26
                    {ToolCursor::Ex_FX, "ex_FX"},
manongjohn 75da26
                    {ToolCursor::Ex_Z, "ex_z"},
manongjohn 75da26
                    {ToolCursor::Ex_StyleLine, "ex_style_line"},
manongjohn 75da26
                    {ToolCursor::Ex_StyleArea, "ex_style_area"},
manongjohn 75da26
                    {ToolCursor::Ex_RGB, "ex_rgb"},
manongjohn 75da26
                    {ToolCursor::Ex_HV, "ex_hv"},
shun_iwasawa 009457
                    {0, 0}};
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// CursorManager
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
class CursorManager {  // singleton
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  std::map<int, cursordata=""> m_cursors;</int,>
manongjohn 75da26
  std::map<int, cursordata=""> m_cursorsLeft;</int,>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  CursorManager() {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  static CursorManager *instance() {
Shinya Kitaoka 120a6e
    static CursorManager _instance;
Shinya Kitaoka 120a6e
    return &_instance;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
manongjohn 75da26
  void doDecoration(QPixmap &pixmap, int decorationFlag, bool useLeft) {
shun_iwasawa 009457
    if (decorationFlag == 0) return;
shun_iwasawa 009457
    if (decorationFlag > ToolCursor::Ex_Negate) {
shun_iwasawa 009457
      QPainter p(&pixmap);
shun_iwasawa 009457
      p.setCompositionMode(QPainter::CompositionMode_SourceOver);
shun_iwasawa 009457
      for (int i = 0; decorateInfo[i].pixmapFilename; i++)
shun_iwasawa 009457
        if (decorationFlag & decorateInfo[i].decorateType) {
manongjohn 75da26
          QString leftStr      = "";
manongjohn 75da26
          if (useLeft) leftStr = "_left";
manongjohn 75da26
          QString path         = QString(":Resources/") +
manongjohn 75da26
                         decorateInfo[i].pixmapFilename + leftStr + ".png";
shun_iwasawa 009457
          p.drawPixmap(0, 0, QPixmap(path));
shun_iwasawa 009457
        }
shun_iwasawa 009457
    }
shun_iwasawa 009457
    // negate
shun_iwasawa 009457
    if (decorationFlag & ToolCursor::Ex_Negate) {
shun_iwasawa 009457
      QImage img = pixmap.toImage();
shun_iwasawa 009457
      img.invertPixels(QImage::InvertRgb);  // leave the alpha channel unchanged
shun_iwasawa 009457
      pixmap = QPixmap::fromImage(img);
shun_iwasawa 009457
    }
shun_iwasawa 009457
  }
shun_iwasawa 009457
Shinya Kitaoka 120a6e
  const CursorData &getCursorData(int cursorType) {
Shinya Kitaoka 120a6e
    // se e' gia' in tabella lo restituisco
Shinya Kitaoka 120a6e
    std::map<int, cursordata="">::iterator it;</int,>
manongjohn 75da26
manongjohn 75da26
    if (Preferences::instance()->getCursorBrushStyle() == "Simple")
manongjohn 75da26
      cursorType = ToolCursor::PenCursor;
manongjohn 75da26
manongjohn 75da26
    if (cursorType == ToolCursor::PenCursor) {
manongjohn 75da26
      QString brushType = Preferences::instance()->getCursorBrushType();
manongjohn 75da26
      if (brushType == "Large")
manongjohn 75da26
        cursorType = ToolCursor::PenLargeCursor;
manongjohn 75da26
      else if (brushType == "Crosshair")
manongjohn 75da26
        cursorType = ToolCursor::PenCrosshairCursor;
manongjohn 75da26
    }
manongjohn 75da26
manongjohn 75da26
    bool useLeft =
manongjohn 75da26
        (Preferences::instance()->getCursorBrushStyle() == "Left-Handed");
manongjohn 75da26
    if (useLeft) {
manongjohn 75da26
      it = m_cursorsLeft.find(cursorType);
manongjohn 75da26
      if (it != m_cursorsLeft.end()) return it->second;
manongjohn 75da26
    } else {
manongjohn 75da26
      it = m_cursors.find(cursorType);
manongjohn 75da26
      if (it != m_cursors.end()) return it->second;
manongjohn 75da26
    }
shun_iwasawa 009457
shun_iwasawa 009457
    int decorationsFlag = cursorType & ~(0xFF);
shun_iwasawa 009457
    int baseCursorType  = cursorType & 0xFF;
shun_iwasawa 009457
manongjohn 75da26
    if (baseCursorType == ToolCursor::CURSOR_ARROW) {
manongjohn 75da26
      CursorData data;
manongjohn 75da26
      QCursor leftArrow(Qt::ArrowCursor);
manongjohn 75da26
      data.pixmap = leftArrow.pixmap();
manongjohn 75da26
      data.x      = leftArrow.hotSpot().x();
manongjohn 75da26
      data.y      = leftArrow.hotSpot().y();
manongjohn 75da26
manongjohn 75da26
      if (useLeft) {
manongjohn 75da26
        QImage target = (&data.pixmap)->toImage();
manongjohn 75da26
        (&data.pixmap)->convertFromImage(target.mirrored(true, false));
manongjohn 75da26
        data.x = data.pixmap.width() - data.x - 1;
manongjohn 75da26
        it     = m_cursorsLeft.insert(std::make_pair(cursorType, data)).first;
manongjohn 75da26
      } else
manongjohn 75da26
        it = m_cursors.insert(std::make_pair(cursorType, data)).first;
manongjohn 75da26
manongjohn 75da26
      return it->second;
manongjohn 75da26
    }
manongjohn 75da26
Shinya Kitaoka 120a6e
    // provo a cercarlo in cursorInfo[]
Shinya Kitaoka 120a6e
    int i;
Shinya Kitaoka 120a6e
    for (i = 0; cursorInfo[i].pixmapFilename; i++)
shun_iwasawa 009457
      if (baseCursorType == cursorInfo[i].cursorType) {
Shinya Kitaoka 120a6e
        QString path =
Shinya Kitaoka 120a6e
            QString(":Resources/") + cursorInfo[i].pixmapFilename + ".png";
Shinya Kitaoka 120a6e
        CursorData data;
Shinya Kitaoka 120a6e
        data.pixmap = QPixmap(path);
manongjohn 75da26
        if (data.pixmap.isNull())
manongjohn 75da26
          data = getCursorData(ToolCursor::CURSOR_ARROW);
manongjohn 75da26
        else {
manongjohn 75da26
          data.x = cursorInfo[i].x;
manongjohn 75da26
          data.y = cursorInfo[i].y;
manongjohn 75da26
          if (useLeft && cursorInfo[i].flippable) {
manongjohn 75da26
            QImage target = (&data.pixmap)->toImage();
manongjohn 75da26
            (&data.pixmap)->convertFromImage(target.mirrored(true, false));
manongjohn 75da26
            data.x = data.pixmap.width() - cursorInfo[i].x - 1;
manongjohn 75da26
          }
manongjohn 75da26
          if (decorationsFlag != 0)
manongjohn 75da26
            doDecoration(data.pixmap, decorationsFlag, useLeft);
manongjohn 75da26
        }
manongjohn 75da26
        if (useLeft)
manongjohn 75da26
          it = m_cursorsLeft.insert(std::make_pair(cursorType, data)).first;
manongjohn 75da26
        else
manongjohn 75da26
          it = m_cursors.insert(std::make_pair(cursorType, data)).first;
Shinya Kitaoka 120a6e
        return it->second;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    // niente da fare. uso un default
Shinya Kitaoka 120a6e
    CursorData data;
Shinya Kitaoka 120a6e
    static const QPixmap standardCursorPixmap("cursors/hook.png");
Shinya Kitaoka 120a6e
    data.pixmap = standardCursorPixmap;
Shinya Kitaoka 120a6e
    data.x = data.y = 0;
manongjohn 75da26
    if (useLeft)
manongjohn 75da26
      it = m_cursorsLeft.insert(std::make_pair(cursorType, data)).first;
manongjohn 75da26
    else
manongjohn 75da26
      it = m_cursors.insert(std::make_pair(cursorType, data)).first;
Shinya Kitaoka 120a6e
    return it->second;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  QCursor getCursor(int cursorType) {
Shinya Kitaoka 120a6e
    // assert(cursorType!=0);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    QCursor cursor;
manongjohn 75da26
    /*
manongjohn 75da26
if (cursorType == ToolCursor::CURSOR_ARROW)
manongjohn 75da26
  cursor = Qt::ArrowCursor;
manongjohn 75da26
else */
manongjohn 75da26
    if (cursorType == ToolCursor::ForbiddenCursor)
Shinya Kitaoka 120a6e
      cursor = Qt::ForbiddenCursor;
Shinya Kitaoka 120a6e
    else {
Shinya Kitaoka 120a6e
      const CursorData &data = getCursorData(cursorType);
Shinya Kitaoka 120a6e
      cursor                 = QCursor(data.pixmap, data.x, data.y);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    return cursor;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void setToolCursor(QWidget *viewer, int cursorType) {
Shinya Kitaoka 120a6e
  viewer->setCursor(CursorManager::instance()->getCursor(cursorType));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
QCursor getToolCursor(int cursorType) {
Shinya Kitaoka 120a6e
  return CursorManager::instance()->getCursor(cursorType);
Toshihiro Shimizu 890ddd
}