Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "setsaveboxtool.h"
Toshihiro Shimizu 890ddd
#include "tgl.h"
Toshihiro Shimizu 890ddd
#include "tundo.h"
Toshihiro Shimizu 890ddd
#include "trop.h"
Toshihiro Shimizu 890ddd
#include "toonz/toonzimageutils.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshlevelhandle.h"
Toshihiro Shimizu 890ddd
#include "toonz/txsheethandle.h"
Toshihiro Shimizu 890ddd
#include "toonz/ttileset.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshsimplelevel.h"
Toshihiro Shimizu 890ddd
#include "toonz/preferences.h"
Toshihiro Shimizu 890ddd
#include "tools/toolutils.h"
Toshihiro Shimizu 890ddd
#include "tools/cursors.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
using namespace ToolUtils;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class SetSaveboxUndo final : public TRasterUndo {
Shinya Kitaoka 120a6e
  TRect m_modifiedSavebox;
Shinya Kitaoka 120a6e
  TRect m_originalSavebox;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  SetSaveboxUndo(TTileSetCM32 *tileSet, const TRect &modifiedSavebox,
Shinya Kitaoka 120a6e
                 const TRect &originalSavebox, TXshSimpleLevel *level,
Shinya Kitaoka 120a6e
                 const TFrameId &frameId)
Shinya Kitaoka 120a6e
      : TRasterUndo(tileSet, level, frameId, false, false, 0)
Shinya Kitaoka 120a6e
      , m_modifiedSavebox(modifiedSavebox)
Shinya Kitaoka 120a6e
      , m_originalSavebox(originalSavebox) {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  void redo() const override {
Shinya Kitaoka 120a6e
    TToonzImageP ti = getImage();
Shinya Kitaoka 120a6e
    if (!ti) return;
Shinya Kitaoka 120a6e
    TTool::getApplication()->getCurrentXsheet()->notifyXsheetChanged();
Shinya Kitaoka 120a6e
    ti->getRaster()->clearOutside(m_modifiedSavebox);
Shinya Kitaoka 120a6e
    ti->setSavebox(m_modifiedSavebox);
Shinya Kitaoka 120a6e
    notifyImageChanged();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  void undo() const override {
Shinya Kitaoka 120a6e
    TRasterUndo::undo();
Shinya Kitaoka 120a6e
    TToonzImageP ti = getImage();
Shinya Kitaoka 120a6e
    if (!ti) return;
Shinya Kitaoka 120a6e
    ti->setSavebox(m_originalSavebox);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 38fd86
  int getSize() const override {
Shinya Kitaoka 38fd86
    return TRasterUndo::getSize() + sizeof(this) + 100;
Shinya Kitaoka 38fd86
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  ~SetSaveboxUndo() {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  QString getHistoryString() override {
Shinya Kitaoka 120a6e
    return QObject::tr("Set Save Box : (X%1,Y%2,W%3,H%4)->(X%5,Y%6,W%7,H%8)")
Shinya Kitaoka 120a6e
        .arg(QString::number(m_originalSavebox.x0))
Shinya Kitaoka 120a6e
        .arg(QString::number(m_originalSavebox.y0))
Shinya Kitaoka 120a6e
        .arg(QString::number(m_originalSavebox.getLx()))
Shinya Kitaoka 120a6e
        .arg(QString::number(m_originalSavebox.getLy()))
Shinya Kitaoka 120a6e
        .arg(QString::number(m_modifiedSavebox.x0))
Shinya Kitaoka 120a6e
        .arg(QString::number(m_modifiedSavebox.y0))
Shinya Kitaoka 120a6e
        .arg(QString::number(m_modifiedSavebox.getLx()))
Shinya Kitaoka 120a6e
        .arg(QString::number(m_modifiedSavebox.getLy()));
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
}  // namespace
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// SetSaveboxTool
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
SetSaveboxTool::SetSaveboxTool(TTool *tool)
Shinya Kitaoka 120a6e
    : m_tool(tool), m_pos(), m_modifiedRect() {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TToonzImage *SetSaveboxTool::getImage() {
Shinya Kitaoka 120a6e
  TImageP image = m_tool->getImage(true);
Shinya Kitaoka 120a6e
  if (!image) return 0;
Shinya Kitaoka 120a6e
  TToonzImageP ti = TToonzImageP(image);
Shinya Kitaoka 120a6e
  if (!ti) return 0;
Shinya Kitaoka 120a6e
  return ti.getPointer();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int SetSaveboxTool::getDragType(const TPointD &pos) {
Shinya Kitaoka 120a6e
  TToonzImageP image = getImage();
Shinya Kitaoka 120a6e
  if (!image) return eNone;
Shinya Kitaoka 120a6e
  TRectD bbox =
Shinya Kitaoka 120a6e
      ToonzImageUtils::convertRasterToWorld(convert(image->getBBox()), image);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int ret = 0;
Shinya Kitaoka 120a6e
  int dx  = std::min(fabs(bbox.x0 - pos.x), fabs(bbox.x1 - pos.x));
Shinya Kitaoka 120a6e
  int dy  = std::min(fabs(bbox.y0 - pos.y), fabs(bbox.y1 - pos.y));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  double maxDist = 5 * m_tool->getPixelSize();
Shinya Kitaoka 120a6e
  if (dx > maxDist && dy > maxDist)
Shinya Kitaoka 120a6e
    return (bbox.contains(pos)) ? eMoveRect : eNone;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (dx <= maxDist && pos.y >= bbox.y0 - maxDist &&
Shinya Kitaoka 120a6e
      pos.y <= bbox.y1 + maxDist) {
Shinya Kitaoka 120a6e
    if (areAlmostEqual(dx, fabs(bbox.x0 - pos.x), maxDist))
Shinya Kitaoka 120a6e
      ret = eMoveLeft;
Shinya Kitaoka 120a6e
    else if (areAlmostEqual(dx, fabs(bbox.x1 - pos.x), maxDist))
Shinya Kitaoka 120a6e
      ret = eMoveRight;
Shinya Kitaoka 120a6e
  } else if (dy <= maxDist && pos.x >= bbox.x0 - maxDist &&
Shinya Kitaoka 120a6e
             pos.x <= bbox.x1 + maxDist) {
Shinya Kitaoka 120a6e
    if (areAlmostEqual(dy, fabs(bbox.y0 - pos.y), maxDist))
Shinya Kitaoka 120a6e
      return eMoveDown;
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      return eMoveUp;
Shinya Kitaoka 120a6e
  } else
Shinya Kitaoka 120a6e
    return eNone;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (dy > maxDist) return ret;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return (areAlmostEqual(dy, fabs(bbox.y0 - pos.y), maxDist)) ? ret | eMoveDown
Shinya Kitaoka 120a6e
                                                              : ret | eMoveUp;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int SetSaveboxTool::getCursorId(const TPointD &pos) {
Shinya Kitaoka 120a6e
  int dragType = getDragType(pos);
Shinya Kitaoka 120a6e
  switch (dragType) {
Shinya Kitaoka 120a6e
  case eMoveRect:
Shinya Kitaoka 120a6e
    return ToolCursor::MoveCursor;
Shinya Kitaoka 120a6e
  case eMoveLeft:
Shinya Kitaoka 120a6e
  case eMoveRight:
Shinya Kitaoka 120a6e
    return ToolCursor::ScaleHCursor;
Shinya Kitaoka 120a6e
  case eMoveDown:
Shinya Kitaoka 120a6e
  case eMoveUp:
Shinya Kitaoka 120a6e
    return ToolCursor::ScaleVCursor;
Shinya Kitaoka 120a6e
  case eMoveLeft | eMoveUp:
Shinya Kitaoka 120a6e
  case eMoveRight | eMoveDown:
Shinya Kitaoka 120a6e
    return ToolCursor::ScaleInvCursor;
Shinya Kitaoka 120a6e
  case eMoveLeft | eMoveDown:
Shinya Kitaoka 120a6e
  case eMoveRight | eMoveUp:
Shinya Kitaoka 120a6e
    return ToolCursor::ScaleCursor;
Shinya Kitaoka 120a6e
  default:
Shinya Kitaoka 120a6e
    return ToolCursor::StrokeSelectCursor;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return ToolCursor::StrokeSelectCursor;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void SetSaveboxTool::leftButtonDown(const TPointD &pos) {
Shinya Kitaoka 120a6e
  TToonzImageP image = getImage();
Shinya Kitaoka 120a6e
  if (!image) return;
Shinya Kitaoka 120a6e
  m_modifiedRect =
Shinya Kitaoka 120a6e
      ToonzImageUtils::convertRasterToWorld(convert(image->getBBox()), image);
Shinya Kitaoka 120a6e
  m_pos          = pos;
Shinya Kitaoka 120a6e
  m_movementType = (SetSaveboxTool::Moviment)getDragType(pos);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void SetSaveboxTool::leftButtonDrag(const TPointD &pos) {
Shinya Kitaoka 120a6e
  TToonzImageP image = getImage();
Shinya Kitaoka 120a6e
  if (!image) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (m_movementType == eNone) return;
Shinya Kitaoka 120a6e
  if (m_movementType == eMoveRect)
Shinya Kitaoka 120a6e
    m_modifiedRect = m_modifiedRect + (pos - m_pos);
Shinya Kitaoka 120a6e
  else {
Shinya Kitaoka 120a6e
    if (m_movementType & eMoveLeft) m_modifiedRect.x0 += pos.x - m_pos.x;
Shinya Kitaoka 120a6e
    if (m_movementType & eMoveRight) m_modifiedRect.x1 += pos.x - m_pos.x;
Shinya Kitaoka 120a6e
    if (m_movementType & eMoveDown) m_modifiedRect.y0 += pos.y - m_pos.y;
Shinya Kitaoka 120a6e
    if (m_movementType & eMoveUp) m_modifiedRect.y1 += pos.y - m_pos.y;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  m_pos = pos;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void SetSaveboxTool::leftButtonUp(const TPointD &pos) {
Shinya Kitaoka 120a6e
  TToonzImageP image = getImage();
Shinya Kitaoka 120a6e
  if (!image) return;
Shinya Kitaoka 120a6e
  m_pos                  = TPointD();
Shinya Kitaoka 120a6e
  TRectD originalSavebox = image->getBBox();
Shinya Kitaoka 120a6e
  TRect savebox = ToonzImageUtils::convertWorldToRaster(m_modifiedRect, image);
Shinya Kitaoka 120a6e
  if (savebox.isEmpty()) {
Shinya Kitaoka 120a6e
    m_modifiedRect = TRectD();
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  TRasterCM32P ras      = image->getRaster();
Shinya Kitaoka 120a6e
  TTileSetCM32 *tileSet = new TTileSetCM32(ras->getSize());
Shinya Kitaoka 120a6e
  tileSet->add(ras, image->getSavebox());
Shinya Kitaoka 120a6e
  /*-- 以下を有効にすると、SaveBoxの外の絵のデータが失われる --*/
Shinya Kitaoka 120a6e
  // ras->clearOutside(savebox);
Shinya Kitaoka 120a6e
  // if(Preferences::instance()->isMinimizeSaveboxAfterEditing())
Shinya Kitaoka 120a6e
  //	TRop::computeBBox(ras, savebox);
Shinya Kitaoka 120a6e
  image->setSavebox(savebox);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TXshSimpleLevel *level =
Shinya Kitaoka 120a6e
      m_tool->getApplication()->getCurrentLevel()->getSimpleLevel();
Shinya Kitaoka 120a6e
  TUndoManager::manager()->add(
Shinya Kitaoka 120a6e
      new SetSaveboxUndo(tileSet, savebox, convert(originalSavebox), level,
Shinya Kitaoka 120a6e
                         m_tool->getCurrentFid()));
Shinya Kitaoka 120a6e
  m_modifiedRect = TRectD();
Shinya Kitaoka 120a6e
  m_tool->notifyImageChanged();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void SetSaveboxTool::draw() {
Shinya Kitaoka 120a6e
  TToonzImageP image = getImage();
Shinya Kitaoka 120a6e
  if (!image) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TRectD bbox;
Shinya Kitaoka 120a6e
  if (m_modifiedRect == TRectD())
Shinya Kitaoka 120a6e
    bbox =
Shinya Kitaoka 120a6e
        ToonzImageUtils::convertRasterToWorld(convert(image->getBBox()), image);
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    bbox = m_modifiedRect;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  drawRect(bbox * image->getSubsampling(), TPixel32::Black, 0x5555, true);
Shinya Kitaoka 120a6e
  tglColor(TPixel32(90, 90, 90));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  double pixelSize = m_tool->getPixelSize();
Shinya Kitaoka 120a6e
  TPointD p00      = bbox.getP00();
Shinya Kitaoka 120a6e
  TPointD p11      = bbox.getP11();
Shinya Kitaoka 120a6e
  TPointD p01      = bbox.getP01();
Shinya Kitaoka 120a6e
  TPointD p10      = bbox.getP10();
Shinya Kitaoka 120a6e
  TPointD p11_01   = (bbox.getP11() + bbox.getP01()) * 0.5;
Shinya Kitaoka 120a6e
  TPointD p11_10   = (bbox.getP11() + bbox.getP10()) * 0.5;
Shinya Kitaoka 120a6e
  TPointD p00_01   = (bbox.getP00() + bbox.getP01()) * 0.5;
Shinya Kitaoka 120a6e
  TPointD p00_10   = (bbox.getP00() + bbox.getP10()) * 0.5;
Shinya Kitaoka 120a6e
  TPointD size(pixelSize * 4, pixelSize * 4);
Shinya Kitaoka 120a6e
  tglDrawRect(TRectD(p00 - size, p00 + size));
Shinya Kitaoka 120a6e
  tglDrawRect(TRectD(p11 - size, p11 + size));
Shinya Kitaoka 120a6e
  tglDrawRect(TRectD(p01 - size, p01 + size));
Shinya Kitaoka 120a6e
  tglDrawRect(TRectD(p10 - size, p10 + size));
Shinya Kitaoka 120a6e
  tglDrawRect(TRectD(p11_01 - size, p11_01 + size));
Shinya Kitaoka 120a6e
  tglDrawRect(TRectD(p11_10 - size, p11_10 + size));
Shinya Kitaoka 120a6e
  tglDrawRect(TRectD(p00_01 - size, p00_01 + size));
Shinya Kitaoka 120a6e
  tglDrawRect(TRectD(p00_10 - size, p00_10 + size));
Toshihiro Shimizu 890ddd
}