shun_iwasawa 06bcc2
#include "stylepickertool.h"
Toshihiro Shimizu 890ddd
shun_iwasawa e897af
// TnzTools includes
Toshihiro Shimizu 890ddd
#include "tools/tool.h"
Toshihiro Shimizu 890ddd
#include "tools/cursors.h"
Toshihiro Shimizu 890ddd
#include "tools/stylepicker.h"
shun_iwasawa 06bcc2
#include "tools/toolhandle.h"
Toshihiro Shimizu 890ddd
shun_iwasawa e897af
// TnzQt includes
shun_iwasawa 06bcc2
#include "toonzqt/tselectionhandle.h"
shun_iwasawa 06bcc2
#include "toonzqt/styleselection.h"
Toshihiro Shimizu 890ddd
shun_iwasawa e897af
// TnzLib includes
shun_iwasawa 06bcc2
#include "toonz/txshsimplelevel.h"
shun_iwasawa 06bcc2
#include "toonz/txshlevelhandle.h"
Toshihiro Shimizu 890ddd
#include "toonz/tpalettehandle.h"
Toshihiro Shimizu 890ddd
#include "toonz/stage2.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"
shun_iwasawa 06bcc2
#include "toonz/txshleveltypes.h"
shun_iwasawa 06bcc2
#include "toonz/txshpalettelevel.h"
shun_iwasawa 06bcc2
shun_iwasawa 06bcc2
// TnzCore includes
shun_iwasawa 06bcc2
#include "drawutil.h"
shun_iwasawa 06bcc2
#include "tvectorimage.h"
shun_iwasawa 06bcc2
#include "ttoonzimage.h"
shun_iwasawa 06bcc2
#include "tundo.h"
shun_iwasawa 06bcc2
#include "tmsgcore.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
Toshihiro Shimizu 890ddd
//========================================================================
Toshihiro Shimizu 890ddd
// Pick Style Tool
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
shun_iwasawa 06bcc2
StylePickerTool::StylePickerTool()
shun_iwasawa 06bcc2
    : TTool("T_StylePicker")
shun_iwasawa 06bcc2
    , m_currentStyleId(0)
shun_iwasawa 06bcc2
    , m_colorType("Mode:")
shun_iwasawa e897af
    , m_passivePick("Passive Pick", false)
shun_iwasawa 06bcc2
    , m_organizePalette("Organize Palette", false)
shun_iwasawa 06bcc2
    , m_paletteToBeOrganized(NULL) {
shun_iwasawa 06bcc2
  m_prop.bind(m_colorType);
shun_iwasawa 06bcc2
  m_colorType.addValue(AREAS);
shun_iwasawa 06bcc2
  m_colorType.addValue(LINES);
shun_iwasawa 06bcc2
  m_colorType.addValue(ALL);
shun_iwasawa 06bcc2
  m_colorType.setId("Mode");
shun_iwasawa 06bcc2
  bind(TTool::CommonLevels);
shun_iwasawa 06bcc2
shun_iwasawa 06bcc2
  m_prop.bind(m_passivePick);
shun_iwasawa 06bcc2
  m_passivePick.setId("PassivePick");
shun_iwasawa 06bcc2
shun_iwasawa 06bcc2
  m_prop.bind(m_organizePalette);
shun_iwasawa 06bcc2
  m_organizePalette.setId("OrganizePalette");
shun_iwasawa 06bcc2
}
Toshihiro Shimizu 890ddd
shun_iwasawa 06bcc2
void StylePickerTool::leftButtonDown(const TPointD &pos, const TMouseEvent &e) {
shun_iwasawa 06bcc2
  m_oldStyleId = m_currentStyleId =
shun_iwasawa 06bcc2
      getApplication()->getCurrentLevelStyleIndex();
shun-iwasawa 558228
  pick(pos, e, false);
shun_iwasawa 06bcc2
}
shun_iwasawa e897af
shun_iwasawa 06bcc2
void StylePickerTool::leftButtonDrag(const TPointD &pos, const TMouseEvent &e) {
shun_iwasawa 06bcc2
  pick(pos, e);
shun_iwasawa 06bcc2
}
Shinya Kitaoka 120a6e
shun-iwasawa 558228
void StylePickerTool::pick(const TPointD &pos, const TMouseEvent &e,
shun-iwasawa 558228
                           bool isDragging) {
shun_iwasawa 06bcc2
  // Area = 0, Line = 1, All = 2
shun_iwasawa 06bcc2
  int modeValue = m_colorType.getIndex();
shun_iwasawa 06bcc2
shun_iwasawa 06bcc2
  //------------------------------------
shun_iwasawa 06bcc2
  // MultiLayerStylePicker
shun_iwasawa 06bcc2
  /*---
shun_iwasawa 06bcc2
                  PickしたStyleId = 0、かつ
shun_iwasawa 06bcc2
                  Preference で MultiLayerStylePickerが有効、かつ
shun_iwasawa 06bcc2
                  Scene編集モード、かつ
shun_iwasawa 06bcc2
                  下のカラムから拾った色がTransparentでない場合、
shun_iwasawa 06bcc2
                  → カレントLevelを移動する。
shun_iwasawa 06bcc2
  ---*/
shun_iwasawa 06bcc2
  if (Preferences::instance()->isMultiLayerStylePickerEnabled() &&
shun_iwasawa 06bcc2
      getApplication()->getCurrentFrame()->isEditingScene()) {
shun_iwasawa 06bcc2
    int superPickedColumnId = getViewer()->posToColumnIndex(
shun_iwasawa 06bcc2
        e.m_pos, getPixelSize() * getPixelSize(), false);
shun_iwasawa 06bcc2
shun_iwasawa 06bcc2
    if (superPickedColumnId >= 0 /*-- 何かColumnに当たった場合 --*/
shun_iwasawa 06bcc2
        &&
shun_iwasawa 06bcc2
        getApplication()->getCurrentColumn()->getColumnIndex() !=
shun_iwasawa 06bcc2
            superPickedColumnId) /*-- かつ、Current Columnでない場合 --*/
shun_iwasawa 06bcc2
    {
shun_iwasawa 06bcc2
      /*-- そのColumnからPickを試みる --*/
shun_iwasawa 06bcc2
      int currentFrame = getApplication()->getCurrentFrame()->getFrame();
shun_iwasawa 06bcc2
      TXshCell pickedCell =
shun_iwasawa 06bcc2
          getApplication()->getCurrentXsheet()->getXsheet()->getCell(
shun_iwasawa 06bcc2
              currentFrame, superPickedColumnId);
shun_iwasawa 06bcc2
      TImageP pickedImage           = pickedCell.getImage(false).getPointer();
shun_iwasawa 06bcc2
      TToonzImageP picked_ti        = pickedImage;
shun_iwasawa 06bcc2
      TVectorImageP picked_vi       = pickedImage;
shun_iwasawa 06bcc2
      TXshSimpleLevel *picked_level = pickedCell.getSimpleLevel();
shun_iwasawa 06bcc2
      if ((picked_ti || picked_vi) && picked_level) {
shun_iwasawa e897af
        TPointD tmpMousePosition = getColumnMatrix(superPickedColumnId).inv() *
shun_iwasawa e897af
                                   getViewer()->winToWorld(e.m_pos);
shun_iwasawa 06bcc2
shun_iwasawa e897af
        TPointD tmpDpiScale = getCurrentDpiScale(picked_level, getCurrentFid());
shun_iwasawa 06bcc2
shun_iwasawa 06bcc2
        tmpMousePosition.x /= tmpDpiScale.x;
shun_iwasawa 06bcc2
        tmpMousePosition.y /= tmpDpiScale.y;
shun_iwasawa 06bcc2
shun_iwasawa 06bcc2
        StylePicker superPicker(pickedImage);
shun_iwasawa 06bcc2
        int picked_subsampling =
shun_iwasawa 06bcc2
            picked_level->getImageSubsampling(pickedCell.getFrameId());
shun_iwasawa 06bcc2
        int superPicked_StyleId = superPicker.pickStyleId(
shun_iwasawa 06bcc2
            TScale(1.0 / picked_subsampling) * tmpMousePosition +
shun_iwasawa 06bcc2
                TPointD(-0.5, -0.5),
shun_iwasawa 06bcc2
            getPixelSize() * getPixelSize(), modeValue);
shun_iwasawa 06bcc2
        /*-- 何かStyleが拾えて、Transparentでない場合 --*/
shun_iwasawa 06bcc2
        if (superPicked_StyleId > 0) {
shun_iwasawa 06bcc2
          /*-- Levelの移動 --*/
shun_iwasawa 06bcc2
          getApplication()->getCurrentLevel()->setLevel(picked_level);
shun_iwasawa 06bcc2
          /*-- Columnの移動 --*/
shun_iwasawa 06bcc2
          getApplication()->getCurrentColumn()->setColumnIndex(
shun_iwasawa 06bcc2
              superPickedColumnId);
shun_iwasawa 06bcc2
          /*-- 選択の解除 --*/
shun_iwasawa 06bcc2
          if (getApplication()->getCurrentSelection()->getSelection())
shun_iwasawa 06bcc2
            getApplication()
shun_iwasawa 06bcc2
                ->getCurrentSelection()
shun_iwasawa 06bcc2
                ->getSelection()
shun_iwasawa 06bcc2
                ->selectNone();
shun_iwasawa 06bcc2
          /*-- StyleIdの移動 --*/
shun-iwasawa 558228
          getApplication()->setCurrentLevelStyleIndex(superPicked_StyleId,
shun-iwasawa 558228
                                                      !isDragging);
shun_iwasawa 06bcc2
          return;
shun_iwasawa 06bcc2
        }
shun_iwasawa 06bcc2
      }
shun_iwasawa 06bcc2
    }
shun_iwasawa 06bcc2
  }
shun_iwasawa 06bcc2
  /*-- MultiLayerStylePicker ここまで --*/
shun_iwasawa 06bcc2
  //------------------------------------
shun_iwasawa 06bcc2
  TImageP image    = getImage(false);
shun_iwasawa 06bcc2
  TToonzImageP ti  = image;
shun_iwasawa 06bcc2
  TVectorImageP vi = image;
shun_iwasawa 06bcc2
  TXshSimpleLevel *level =
shun_iwasawa 06bcc2
      getApplication()->getCurrentLevel()->getSimpleLevel();
shun_iwasawa 06bcc2
  if ((!ti && !vi) || !level) return;
shun_iwasawa 06bcc2
shun_iwasawa 06bcc2
  /*-- 画面外をpickしても拾えないようにする --*/
shun_iwasawa 06bcc2
  if (!m_viewer->getGeometry().contains(pos)) return;
shun_iwasawa 06bcc2
shun_iwasawa 06bcc2
  int subsampling = level->getImageSubsampling(getCurrentFid());
shun_iwasawa 06bcc2
  StylePicker picker(image);
shun_iwasawa e897af
  int styleId =
shun_iwasawa e897af
      picker.pickStyleId(TScale(1.0 / subsampling) * pos + TPointD(-0.5, -0.5),
shun_iwasawa e897af
                         getPixelSize() * getPixelSize(), modeValue);
shun_iwasawa 06bcc2
shun_iwasawa 06bcc2
  if (styleId < 0) return;
shun_iwasawa 06bcc2
shun_iwasawa 06bcc2
  if (modeValue == 1)  // LINES
shun_iwasawa 06bcc2
  {
shun_iwasawa 06bcc2
    /*-- pickLineモードのとき、取得Styleが0の場合はカレントStyleを変えない。
shun_iwasawa 06bcc2
      * --*/
shun_iwasawa 06bcc2
    if (styleId == 0) return;
shun_iwasawa 06bcc2
    /*--
shun_iwasawa 06bcc2
      * pickLineモードのとき、PurePaintの部分をクリックしてもカレントStyleを変えない
shun_iwasawa 06bcc2
      * --*/
shun_iwasawa 06bcc2
    if (ti &&
shun_iwasawa 06bcc2
        picker.pickTone(TScale(1.0 / subsampling) * pos +
shun_iwasawa 06bcc2
                        TPointD(-0.5, -0.5)) == 255)
shun_iwasawa 06bcc2
      return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
shun_iwasawa 06bcc2
  /*--- Styleを選択している場合は選択を解除する ---*/
shun_iwasawa 06bcc2
  TSelection *selection =
shun_iwasawa 06bcc2
      TTool::getApplication()->getCurrentSelection()->getSelection();
shun_iwasawa 06bcc2
  if (selection) {
shun_iwasawa 06bcc2
    TStyleSelection *styleSelection =
shun_iwasawa 06bcc2
        dynamic_cast<tstyleselection *="">(selection);</tstyleselection>
shun_iwasawa 06bcc2
    if (styleSelection) styleSelection->selectNone();
shun_iwasawa 06bcc2
  }
Shinya Kitaoka 120a6e
shun-iwasawa 558228
  // When clicking and switching between studio palette and level palette, the
shun-iwasawa 558228
  // signal broadcastColorStyleSwitched is not emitted if the picked style is
shun-iwasawa 558228
  // previously selected one.
shun-iwasawa 558228
  // Therefore here I set the "forceEmit" flag to true in order to emit the
shun-iwasawa 558228
  // signal whenever the picking with mouse press.
shun-iwasawa 558228
  getApplication()->setCurrentLevelStyleIndex(styleId, !isDragging);
shun_iwasawa 06bcc2
}
Shinya Kitaoka 120a6e
shun_iwasawa 06bcc2
void StylePickerTool::mouseMove(const TPointD &pos, const TMouseEvent &e) {
shun_iwasawa 06bcc2
  if (!m_passivePick.getValue()) return;
shun_iwasawa 06bcc2
  /*--- PassiveにStyleを拾う機能 ---*/
shun_iwasawa 06bcc2
  PaletteController *controller =
shun_iwasawa 06bcc2
      TTool::getApplication()->getPaletteController();
shun_iwasawa 06bcc2
shun_iwasawa 06bcc2
  TImageP image    = getImage(false);
shun_iwasawa 06bcc2
  TToonzImageP ti  = image;
shun_iwasawa 06bcc2
  TVectorImageP vi = image;
shun_iwasawa 06bcc2
  TXshSimpleLevel *level =
shun_iwasawa 06bcc2
      getApplication()->getCurrentLevel()->getSimpleLevel();
shun_iwasawa 06bcc2
  if ((!ti && !vi) || !level || !m_viewer->getGeometry().contains(pos)) {
shun_iwasawa 06bcc2
    controller->notifyStylePassivePicked(-1, -1, -1);
shun_iwasawa 06bcc2
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
shun_iwasawa 06bcc2
  int subsampling = level->getImageSubsampling(getCurrentFid());
shun_iwasawa 06bcc2
  StylePicker picker(image);
shun_iwasawa 06bcc2
  TPointD pickPos(TScale(1.0 / subsampling) * pos + TPointD(-0.5, -0.5));
shun_iwasawa 06bcc2
  int inkStyleId =
shun_iwasawa 06bcc2
      picker.pickStyleId(pickPos, getPixelSize() * getPixelSize(), 1);
shun_iwasawa 06bcc2
  int paintStyleId =
shun_iwasawa 06bcc2
      picker.pickStyleId(pickPos, getPixelSize() * getPixelSize(), 0);
shun_iwasawa 06bcc2
  int tone = picker.pickTone(pickPos);
shun_iwasawa 06bcc2
  controller->notifyStylePassivePicked(inkStyleId, paintStyleId, tone);
shun_iwasawa 06bcc2
}
Shinya Kitaoka 120a6e
shun_iwasawa 06bcc2
int StylePickerTool::getCursorId() const {
shun_iwasawa 009457
  int ret;
manongjohn 8f8437
manongjohn 8f8437
  if (!Preferences::instance()->isMultiLayerStylePickerEnabled()) {
manongjohn 8f8437
    TImageP img      = getImage(false);
manongjohn 8f8437
    TVectorImageP vi = img;
manongjohn 8f8437
    TToonzImageP ti  = img;
manongjohn 8f8437
manongjohn 8f8437
    if (!vi && !ti) return ToolCursor::CURSOR_NO;
manongjohn 8f8437
  }
manongjohn 8f8437
shun_iwasawa 06bcc2
  /* in case the "organize palette" option is active */
shun_iwasawa 06bcc2
  if (m_organizePalette.getValue())
shun_iwasawa 009457
    ret = ToolCursor::PickerCursorOrganize;
shun_iwasawa 009457
  else if (m_colorType.getValue() == LINES)
shun_iwasawa 009457
    ret = ToolCursor::PickerCursorLine;
shun_iwasawa 06bcc2
  else if (m_colorType.getValue() == AREAS)
shun_iwasawa 009457
    ret = ToolCursor::PickerCursorArea;
shun_iwasawa 06bcc2
  else  // line&areas
shun_iwasawa 009457
    ret = ToolCursor::PickerCursor;
shun_iwasawa 009457
shun_iwasawa 009457
  if (ToonzCheck::instance()->getChecks() & ToonzCheck::eBlackBg)
shun_iwasawa 009457
    ret = ret | ToolCursor::Ex_Negate;
shun_iwasawa 009457
  return ret;
shun_iwasawa 06bcc2
}
Shinya Kitaoka 120a6e
shun_iwasawa 06bcc2
bool StylePickerTool::onPropertyChanged(std::string propertyName) {
shun_iwasawa e897af
  if (propertyName == m_organizePalette.getName()) {
shun_iwasawa 06bcc2
    if (m_organizePalette.getValue()) {
shun_iwasawa e897af
      if (!startOrganizePalette()) {
shun_iwasawa 06bcc2
        m_organizePalette.setValue(false);
shun_iwasawa 06bcc2
        getApplication()->getCurrentTool()->notifyToolChanged();
shun_iwasawa 06bcc2
        return false;
shun_iwasawa 06bcc2
      }
shun_iwasawa 06bcc2
    } else {
shun_iwasawa 06bcc2
      std::cout << "End Organize Palette" << std::endl;
shun_iwasawa 06bcc2
      m_paletteToBeOrganized = NULL;
Shinya Kitaoka 120a6e
    }
shun_iwasawa 06bcc2
  }
shun_iwasawa 06bcc2
  return true;
shun_iwasawa 06bcc2
}
Shinya Kitaoka 120a6e
shun_iwasawa 06bcc2
bool StylePickerTool::startOrganizePalette() {
shun_iwasawa 06bcc2
  /* Check if the organizing operation is available */
shun_iwasawa e897af
  TXshLevel *level = getApplication()->getCurrentLevel()->getLevel();
shun_iwasawa 06bcc2
  if (!level) {
shun_iwasawa 06bcc2
    DVGui::error(tr("No current level."));
shun_iwasawa 06bcc2
    return false;
shun_iwasawa 06bcc2
  }
shun_iwasawa e897af
  if (level->getType() != PLI_XSHLEVEL && level->getType() != TZP_XSHLEVEL &&
shun_iwasawa e897af
      level->getType() != PLT_XSHLEVEL) {
shun_iwasawa 06bcc2
    DVGui::error(tr("Current level has no available palette."));
shun_iwasawa 06bcc2
    return false;
shun_iwasawa 06bcc2
  }
shun_iwasawa 06bcc2
  /* palette should have more than one page to organize */
shun_iwasawa e897af
  TPalette *pal = NULL;
shun_iwasawa 06bcc2
  if (level->getType() == PLT_XSHLEVEL)
shun_iwasawa 06bcc2
    pal = level->getPaletteLevel()->getPalette();
shun_iwasawa 06bcc2
  else
shun_iwasawa 06bcc2
    pal = level->getSimpleLevel()->getPalette();
shun_iwasawa e897af
  if (!pal || pal->getPageCount() < 2) {
shun_iwasawa e897af
    DVGui::error(
shun_iwasawa e897af
        tr("Palette must have more than one palette to be organized."));
shun_iwasawa 06bcc2
    return false;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
shun_iwasawa 06bcc2
  m_paletteToBeOrganized = pal;
shun_iwasawa e897af
shun_iwasawa 06bcc2
  std::cout << "Start Organize Palette" << std::endl;
Shinya Kitaoka 120a6e
shun_iwasawa 06bcc2
  return true;
shun_iwasawa 06bcc2
}
Shinya Kitaoka 120a6e
shun_iwasawa 06bcc2
/*
shun_iwasawa e897af
  If the working palette is changed, then deactivate the "organize palette"
shun_iwasawa e897af
  toggle.
shun_iwasawa 06bcc2
*/
shun_iwasawa 06bcc2
void StylePickerTool::onImageChanged() {
shun_iwasawa 06bcc2
  std::cout << "StylePickerTool::onImageChanged" << std::endl;
shun_iwasawa e897af
  if (!m_organizePalette.getValue() || !m_paletteToBeOrganized) return;
shun_iwasawa 06bcc2
shun_iwasawa e897af
  TXshLevel *level = getApplication()->getCurrentLevel()->getLevel();
shun_iwasawa 06bcc2
  if (!level) {
shun_iwasawa 06bcc2
    m_organizePalette.setValue(false);
shun_iwasawa 06bcc2
    getApplication()->getCurrentTool()->notifyToolChanged();
shun_iwasawa 06bcc2
    return;
shun_iwasawa 06bcc2
  }
shun_iwasawa e897af
  TPalette *pal = NULL;
shun_iwasawa 06bcc2
  if (level->getType() == PLT_XSHLEVEL)
shun_iwasawa 06bcc2
    pal = level->getPaletteLevel()->getPalette();
shun_iwasawa 06bcc2
  else if (level->getSimpleLevel()) {
shun_iwasawa 06bcc2
    pal = level->getSimpleLevel()->getPalette();
shun_iwasawa 06bcc2
  }
shun_iwasawa 06bcc2
  if (!pal || pal != m_paletteToBeOrganized) {
shun_iwasawa 06bcc2
    m_organizePalette.setValue(false);
shun_iwasawa 06bcc2
    getApplication()->getCurrentTool()->notifyToolChanged();
shun_iwasawa 06bcc2
    return;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
shun_iwasawa 06bcc2
shun-iwasawa 031c3b
//-------------------------------------------------------------------------------------------------------
shun-iwasawa 031c3b
shun-iwasawa 031c3b
void StylePickerTool::updateTranslation() {
shun-iwasawa 031c3b
  m_colorType.setQStringName(tr("Mode:"));
shun-iwasawa df7bb0
  m_colorType.setItemUIName(LINES, tr("Lines"));
shun-iwasawa df7bb0
  m_colorType.setItemUIName(AREAS, tr("Areas"));
shun-iwasawa df7bb0
  m_colorType.setItemUIName(ALL, tr("Lines & Areas"));
shun-iwasawa 031c3b
  m_passivePick.setQStringName(tr("Passive Pick"));
shun-iwasawa 031c3b
  m_organizePalette.setQStringName(tr("Organize Palette"));
shun-iwasawa 031c3b
}
shun-iwasawa 031c3b
shun-iwasawa 031c3b
//-------------------------------------------------------------------------------------------------------
shun-iwasawa 031c3b
shun_iwasawa 06bcc2
StylePickerTool stylePickerTool;