Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tools/tool.h"
Toshihiro Shimizu 890ddd
#include "tools/cursors.h"
Toshihiro Shimizu 890ddd
#include "tools/stylepicker.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshsimplelevel.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshlevelhandle.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "drawutil.h"
Toshihiro Shimizu 890ddd
#include "tvectorimage.h"
Toshihiro Shimizu 890ddd
#include "ttoonzimage.h"
Toshihiro Shimizu 890ddd
#include "tundo.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "toonz/tpalettehandle.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "toonz/stage2.h"
Toshihiro Shimizu 890ddd
#include "tproperty.h"
Toshihiro Shimizu 890ddd
#include "toonzqt/tselectionhandle.h"
Toshihiro Shimizu 890ddd
#include "toonzqt/styleselection.h"
Toshihiro Shimizu 890ddd
#include "tools/toolhandle.h"
Toshihiro Shimizu 890ddd
#include "toonz/tframehandle.h"
Toshihiro Shimizu 890ddd
#include "toonz/txsheethandle.h"
Toshihiro Shimizu 890ddd
#include "toonz/preferences.h"
Toshihiro Shimizu 890ddd
#include "toonz/tcolumnhandle.h"
Toshihiro Shimizu 890ddd
#include "toonz/dpiscale.h"
Toshihiro Shimizu 890ddd
#include "toonz/palettecontroller.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#define LINES L"Lines"
Toshihiro Shimizu 890ddd
#define AREAS L"Areas"
Toshihiro Shimizu 890ddd
#define ALL L"Lines & Areas"
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//========================================================================
Toshihiro Shimizu 890ddd
// Pick Style Tool
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
class StylePickerTool : public TTool {
Shinya Kitaoka 120a6e
  int m_oldStyleId, m_currentStyleId;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TEnumProperty m_colorType;
Shinya Kitaoka 120a6e
  TPropertyGroup m_prop;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TBoolProperty m_passivePick;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 473e70
  TPropertyGroup *getProperties(int targetType) override { return &m_prop; }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  StylePickerTool()
Shinya Kitaoka 120a6e
      : TTool("T_StylePicker")
Shinya Kitaoka 120a6e
      , m_currentStyleId(0)
Shinya Kitaoka 120a6e
      , m_colorType("Mode:")
Shinya Kitaoka 120a6e
      , m_passivePick("Passive Pick", false) {
Shinya Kitaoka 120a6e
    m_prop.bind(m_colorType);
Shinya Kitaoka 120a6e
    m_colorType.addValue(AREAS);
Shinya Kitaoka 120a6e
    m_colorType.addValue(LINES);
Shinya Kitaoka 120a6e
    m_colorType.addValue(ALL);
Shinya Kitaoka 120a6e
    m_colorType.setId("Mode");
Shinya Kitaoka 120a6e
    bind(TTool::CommonLevels);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    m_prop.bind(m_passivePick);
Shinya Kitaoka 120a6e
    m_passivePick.setId("PassivePick");
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  ToolType getToolType() const override { return TTool::LevelReadTool; }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  void draw() override {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  void leftButtonDown(const TPointD &pos, const TMouseEvent &e) override {
Shinya Kitaoka 120a6e
    m_oldStyleId = m_currentStyleId =
Shinya Kitaoka 120a6e
        getApplication()->getCurrentLevelStyleIndex();
Shinya Kitaoka 120a6e
    pick(pos, e);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 473e70
  void leftButtonDrag(const TPointD &pos, const TMouseEvent &e) override {
Shinya Kitaoka 120a6e
    pick(pos, e);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void pick(const TPointD &pos, const TMouseEvent &e) {
Shinya Kitaoka 120a6e
    // Area = 0, Line = 1, All = 2
Shinya Kitaoka 120a6e
    int modeValue = m_colorType.getIndex();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    //------------------------------------
Shinya Kitaoka 120a6e
    // MultiLayerStylePicker
Shinya Kitaoka 120a6e
    /*---
Shinya Kitaoka 120a6e
                    PickしたStyleId = 0、かつ
Shinya Kitaoka 120a6e
                    Preference で MultiLayerStylePickerが有効、かつ
Shinya Kitaoka 120a6e
                    Scene編集モード、かつ
Shinya Kitaoka 120a6e
                    下のカラムから拾った色がTransparentでない場合、
Shinya Kitaoka 120a6e
                    → カレントLevelを移動する。
Shinya Kitaoka 120a6e
    ---*/
Shinya Kitaoka 120a6e
    if (Preferences::instance()->isMultiLayerStylePickerEnabled() &&
Shinya Kitaoka 120a6e
        getApplication()->getCurrentFrame()->isEditingScene()) {
Shinya Kitaoka 120a6e
      int superPickedColumnId = getViewer()->posToColumnIndex(
Shinya Kitaoka 120a6e
          e.m_pos, getPixelSize() * getPixelSize(), false);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      if (superPickedColumnId >= 0 /*-- 何かColumnに当たった場合 --*/
Shinya Kitaoka 120a6e
          &&
Shinya Kitaoka 120a6e
          getApplication()->getCurrentColumn()->getColumnIndex() !=
Shinya Kitaoka 120a6e
              superPickedColumnId) /*-- かつ、Current Columnでない場合 --*/
Shinya Kitaoka 120a6e
      {
Shinya Kitaoka 120a6e
        /*-- そのColumnからPickを試みる --*/
Shinya Kitaoka 120a6e
        int currentFrame = getApplication()->getCurrentFrame()->getFrame();
Shinya Kitaoka 120a6e
        TXshCell pickedCell =
Shinya Kitaoka 120a6e
            getApplication()->getCurrentXsheet()->getXsheet()->getCell(
Shinya Kitaoka 120a6e
                currentFrame, superPickedColumnId);
Shinya Kitaoka 120a6e
        TImageP pickedImage           = pickedCell.getImage(false).getPointer();
Shinya Kitaoka 120a6e
        TToonzImageP picked_ti        = pickedImage;
Shinya Kitaoka 120a6e
        TVectorImageP picked_vi       = pickedImage;
Shinya Kitaoka 120a6e
        TXshSimpleLevel *picked_level = pickedCell.getSimpleLevel();
Shinya Kitaoka 120a6e
        if ((picked_ti || picked_vi) && picked_level) {
Shinya Kitaoka 120a6e
          TPointD tmpMousePosition =
Shinya Kitaoka 120a6e
              getColumnMatrix(superPickedColumnId).inv() *
Shinya Kitaoka 120a6e
              getViewer()->winToWorld(e.m_pos);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          TPointD tmpDpiScale =
Shinya Kitaoka 120a6e
              getCurrentDpiScale(picked_level, getCurrentFid());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          tmpMousePosition.x /= tmpDpiScale.x;
Shinya Kitaoka 120a6e
          tmpMousePosition.y /= tmpDpiScale.y;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          StylePicker superPicker(pickedImage);
Shinya Kitaoka 120a6e
          int picked_subsampling =
Shinya Kitaoka 120a6e
              picked_level->getImageSubsampling(pickedCell.getFrameId());
Shinya Kitaoka 120a6e
          int superPicked_StyleId = superPicker.pickStyleId(
Shinya Kitaoka 120a6e
              TScale(1.0 / picked_subsampling) * tmpMousePosition +
Shinya Kitaoka 120a6e
                  TPointD(-0.5, -0.5),
Shinya Kitaoka 120a6e
              getPixelSize() * getPixelSize(), modeValue);
Shinya Kitaoka 120a6e
          /*-- 何かStyleが拾えて、Transparentでない場合 --*/
Shinya Kitaoka 120a6e
          if (superPicked_StyleId > 0) {
Shinya Kitaoka 120a6e
            /*-- Levelの移動 --*/
Shinya Kitaoka 120a6e
            getApplication()->getCurrentLevel()->setLevel(picked_level);
Shinya Kitaoka 120a6e
            /*-- Columnの移動 --*/
Shinya Kitaoka 120a6e
            getApplication()->getCurrentColumn()->setColumnIndex(
Shinya Kitaoka 120a6e
                superPickedColumnId);
Shinya Kitaoka 120a6e
            /*-- 選択の解除 --*/
Shinya Kitaoka 120a6e
            if (getApplication()->getCurrentSelection()->getSelection())
Shinya Kitaoka 120a6e
              getApplication()
Shinya Kitaoka 120a6e
                  ->getCurrentSelection()
Shinya Kitaoka 120a6e
                  ->getSelection()
Shinya Kitaoka 120a6e
                  ->selectNone();
Shinya Kitaoka 120a6e
            /*-- StyleIdの移動 --*/
Shinya Kitaoka 120a6e
            getApplication()->setCurrentLevelStyleIndex(superPicked_StyleId);
Shinya Kitaoka 120a6e
            return;
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    /*-- MultiLayerStylePicker ここまで --*/
Shinya Kitaoka 120a6e
    //------------------------------------
Shinya Kitaoka 120a6e
    TImageP image    = getImage(false);
Shinya Kitaoka 120a6e
    TToonzImageP ti  = image;
Shinya Kitaoka 120a6e
    TVectorImageP vi = image;
Shinya Kitaoka 120a6e
    TXshSimpleLevel *level =
Shinya Kitaoka 120a6e
        getApplication()->getCurrentLevel()->getSimpleLevel();
Shinya Kitaoka 120a6e
    if ((!ti && !vi) || !level) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    /*-- 画面外をpickしても拾えないようにする --*/
Shinya Kitaoka 120a6e
    if (!m_viewer->getGeometry().contains(pos)) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    int subsampling = level->getImageSubsampling(getCurrentFid());
Shinya Kitaoka 120a6e
    StylePicker picker(image);
Shinya Kitaoka 120a6e
    int styleId = picker.pickStyleId(
Shinya Kitaoka 120a6e
        TScale(1.0 / subsampling) * pos + TPointD(-0.5, -0.5),
Shinya Kitaoka 120a6e
        getPixelSize() * getPixelSize(), modeValue);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (styleId < 0) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (modeValue == 1)  // LINES
Shinya Kitaoka 120a6e
    {
Shinya Kitaoka 120a6e
      /*-- pickLineモードのとき、取得Styleが0の場合はカレントStyleを変えない。
Shinya Kitaoka 120a6e
       * --*/
Shinya Kitaoka 120a6e
      if (styleId == 0) return;
Shinya Kitaoka 120a6e
      /*--
Shinya Kitaoka 120a6e
       * pickLineモードのとき、PurePaintの部分をクリックしてもカレントStyleを変えない
Shinya Kitaoka 120a6e
       * --*/
Shinya Kitaoka 120a6e
      if (ti &&
Shinya Kitaoka 120a6e
          picker.pickTone(TScale(1.0 / subsampling) * pos +
Shinya Kitaoka 120a6e
                          TPointD(-0.5, -0.5)) == 255)
Shinya Kitaoka 120a6e
        return;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    /*--- Styleを選択している場合は選択を解除する ---*/
Shinya Kitaoka 120a6e
    TSelection *selection =
Shinya Kitaoka 120a6e
        TTool::getApplication()->getCurrentSelection()->getSelection();
Shinya Kitaoka 120a6e
    if (selection) {
Shinya Kitaoka 120a6e
      TStyleSelection *styleSelection =
Shinya Kitaoka 120a6e
          dynamic_cast<tstyleselection *="">(selection);</tstyleselection>
Shinya Kitaoka 120a6e
      if (styleSelection) styleSelection->selectNone();
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    getApplication()->setCurrentLevelStyleIndex(styleId);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  void mouseMove(const TPointD &pos, const TMouseEvent &e) override {
Shinya Kitaoka 120a6e
    if (!m_passivePick.getValue()) return;
Shinya Kitaoka 120a6e
    /*--- PassiveにStyleを拾う機能 ---*/
Shinya Kitaoka 120a6e
    PaletteController *controller =
Shinya Kitaoka 120a6e
        TTool::getApplication()->getPaletteController();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TImageP image    = getImage(false);
Shinya Kitaoka 120a6e
    TToonzImageP ti  = image;
Shinya Kitaoka 120a6e
    TVectorImageP vi = image;
Shinya Kitaoka 120a6e
    TXshSimpleLevel *level =
Shinya Kitaoka 120a6e
        getApplication()->getCurrentLevel()->getSimpleLevel();
Shinya Kitaoka 120a6e
    if ((!ti && !vi) || !level || !m_viewer->getGeometry().contains(pos)) {
Shinya Kitaoka 120a6e
      controller->notifyStylePassivePicked(-1, -1, -1);
Shinya Kitaoka 120a6e
      return;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    int subsampling = level->getImageSubsampling(getCurrentFid());
Shinya Kitaoka 120a6e
    StylePicker picker(image);
Shinya Kitaoka 120a6e
    TPointD pickPos(TScale(1.0 / subsampling) * pos + TPointD(-0.5, -0.5));
Shinya Kitaoka 120a6e
    int inkStyleId =
Shinya Kitaoka 120a6e
        picker.pickStyleId(pickPos, getPixelSize() * getPixelSize(), 1);
Shinya Kitaoka 120a6e
    int paintStyleId =
Shinya Kitaoka 120a6e
        picker.pickStyleId(pickPos, getPixelSize() * getPixelSize(), 0);
Shinya Kitaoka 120a6e
    int tone = picker.pickTone(pickPos);
Shinya Kitaoka 120a6e
    controller->notifyStylePassivePicked(inkStyleId, paintStyleId, tone);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  void onActivate() override {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  int getCursorId() const override {
Shinya Kitaoka 120a6e
    bool isBlackBG = ToonzCheck::instance()->getChecks() & ToonzCheck::eBlackBg;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (m_colorType.getValue() == LINES)
Shinya Kitaoka 120a6e
      return (isBlackBG) ? ToolCursor::PickerCursorWhiteLine
Shinya Kitaoka 120a6e
                         : ToolCursor::PickerCursorLine;
Shinya Kitaoka 120a6e
    else if (m_colorType.getValue() == AREAS)
Shinya Kitaoka 120a6e
      return (isBlackBG) ? ToolCursor::PickerCursorWhiteArea
Shinya Kitaoka 120a6e
                         : ToolCursor::PickerCursorArea;
Shinya Kitaoka 120a6e
    else  // line&areas
Shinya Kitaoka 120a6e
      return (isBlackBG) ? ToolCursor::PickerCursorWhite
Shinya Kitaoka 120a6e
                         : ToolCursor::PickerCursor;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
} stylePickerTool;
Toshihiro Shimizu 890ddd
}