Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tools/toolutils.h"
Toshihiro Shimizu 890ddd
#include "tools/toolhandle.h"
Toshihiro Shimizu 890ddd
#include "toonzqt/imageutils.h"
Toshihiro Shimizu 890ddd
#include "trop.h"
Toshihiro Shimizu 890ddd
#include "tools/tool.h"
Toshihiro Shimizu 890ddd
#include "tstroke.h"
Toshihiro Shimizu 890ddd
#include "timageinfo.h"
Toshihiro Shimizu 890ddd
#include "timagecache.h"
Toshihiro Shimizu 890ddd
#include "tgl.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "toonz/txsheethandle.h"
Toshihiro Shimizu 890ddd
#include "toonz/tframehandle.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshlevelhandle.h"
Toshihiro Shimizu 890ddd
#include "toonz/tscenehandle.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshleveltypes.h"
Toshihiro Shimizu 890ddd
#include "toonz/tcolumnhandle.h"
Toshihiro Shimizu 890ddd
#include "toonz/tpalettehandle.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshlevel.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshcell.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshsimplelevel.h"
Toshihiro Shimizu 890ddd
#include "toonz/imagemanager.h"
Toshihiro Shimizu 890ddd
#include "toonz/ttileset.h"
Toshihiro Shimizu 890ddd
#include "toonz/toonzimageutils.h"
Toshihiro Shimizu 890ddd
#include "toonz/levelproperties.h"
Toshihiro Shimizu 890ddd
#include "toonz/tstageobjectspline.h"
Toshihiro Shimizu 890ddd
#include "toonz/tobjecthandle.h"
Toshihiro Shimizu 890ddd
#include "toonz/tstageobject.h"
Toshihiro Shimizu 890ddd
#include "toonz/trasterimageutils.h"
Toshihiro Shimizu 890ddd
#include "toonz/levelset.h"
Toshihiro Shimizu 890ddd
#include "toonz/toonzscene.h"
Toshihiro Shimizu 890ddd
#include "toonz/preferences.h"
Toshihiro Shimizu 890ddd
#include "toonz/palettecontroller.h"
shun-iwasawa 536025
#include "toonz/txshchildlevel.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "toonzqt/tselectionhandle.h"
Toshihiro Shimizu 890ddd
#include "toonzqt/icongenerator.h"
Toshihiro Shimizu 890ddd
#include "toonzqt/selection.h"
Toshihiro Shimizu 890ddd
#include "toonzqt/gutil.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tools/strokeselection.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include <qpainter></qpainter>
Christophe Giboudeaux 3ccd50
#include <qpainterpath></qpainterpath>
Shinya Kitaoka 120a6e
#include <qglwidget>  // for QGLWidget::convertToGLFormat</qglwidget>
Toshihiro Shimizu 890ddd
#include <qfont></qfont>
Toshihiro Shimizu 890ddd
#include <qfontmetrics></qfontmetrics>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//****************************************************************************************
Toshihiro Shimizu 890ddd
//    Local namespace
Toshihiro Shimizu 890ddd
//****************************************************************************************
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
//! Riempie il vettore \b theVect con gli indici degli stroke contenuti nel
Shinya Kitaoka 120a6e
//! mapping \b theMap.
Shinya Kitaoka 120a6e
void mapToVector(const std::map<int, *="" vistroke=""> &theMap,</int,>
Shinya Kitaoka 120a6e
                 std::vector<int> &theVect) {</int>
Shinya Kitaoka 120a6e
  assert(theMap.size() == theVect.size());
Shinya Kitaoka 120a6e
  std::map<int, *="" vistroke="">::const_iterator it = theMap.begin();</int,>
shun-iwasawa d02ca1
  UINT i                                       = 0;
Shinya Kitaoka 120a6e
  for (; it != theMap.end(); ++it) {
Shinya Kitaoka 120a6e
    theVect[i++] = it->first;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void updateSaveBox(const TToonzImageP &ti) {
Shinya Kitaoka 120a6e
  if (ti) {
Shinya Kitaoka 120a6e
    assert(ti->getRaster());            // Image should have a raster
Shinya Kitaoka 120a6e
    assert(ti->getSubsampling() == 1);  // Image should not be subsampled -
Shinya Kitaoka 120a6e
                                        // modified images must be the ORIGINAL
Shinya Kitaoka 120a6e
                                        // ones
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    const TRect &savebox = ti->getSavebox();
Shinya Kitaoka 120a6e
    {
Shinya Kitaoka 120a6e
      TRect newSaveBox;
Shinya Kitaoka 120a6e
      TRop::computeBBox(ti->getRaster(), newSaveBox);  // This iterates the
Shinya Kitaoka 120a6e
                                                       // WHOLE raster to find
Shinya Kitaoka 120a6e
                                                       // its new savebox!
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      if (!Preferences::instance()->isMinimizeSaveboxAfterEditing())
Shinya Kitaoka 120a6e
        newSaveBox +=
Shinya Kitaoka 120a6e
            savebox;  // If not minimizing the savebox, it cannot be shrunk.
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      ti->setSavebox(newSaveBox);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
}  // namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//****************************************************************************************
Toshihiro Shimizu 890ddd
//    ToolUtils namespace
Toshihiro Shimizu 890ddd
//****************************************************************************************
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void ToolUtils::updateSaveBox(const TXshSimpleLevelP &sl, const TFrameId &fid) {
Shinya Kitaoka 120a6e
  // TODO: Savebox updates should not happen on mouse updates. This is,
Shinya Kitaoka 120a6e
  // unfortunately, what currently happens.
Shinya Kitaoka 120a6e
  sl->setDirtyFlag(true);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TImageP img = sl->getFrame(fid, true);  // The image will be modified (it
Shinya Kitaoka 120a6e
                                          // should already have been, though)
shun_iwasawa 0788f1
  if (!img) return;
Shinya Kitaoka 120a6e
  // Observe that the returned image will forcedly have subsampling 1
Shinya Kitaoka 120a6e
  ::updateSaveBox(img);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TImageInfo *info = sl->getFrameInfo(fid, true);
Shinya Kitaoka 120a6e
  ImageBuilder::setImageInfo(*info, img.getPointer());
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void ToolUtils::updateSaveBox(const TXshSimpleLevelP &sl, const TFrameId &fid,
Shinya Kitaoka 120a6e
                              TImageP img) {
Shinya Kitaoka 120a6e
  sl->setFrame(fid, img);
Shinya Kitaoka 120a6e
  ToolUtils::updateSaveBox(sl, fid);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void ToolUtils::updateSaveBox() {
Shinya Kitaoka 120a6e
  TTool::Application *application = TTool::getApplication();
Shinya Kitaoka 120a6e
  if (!application) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TXshLevel *xl = application->getCurrentLevel()->getLevel();
Shinya Kitaoka 120a6e
  if (!xl) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TXshSimpleLevel *sl = xl->getSimpleLevel();
Shinya Kitaoka 120a6e
  if (!sl || sl->getType() != TZP_XSHLEVEL) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TFrameId fid = getFrameId();
Shinya Kitaoka 120a6e
  ToolUtils::updateSaveBox(sl, fid);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
//! Return the right value in both case: LevelFrame and SceneFrame.
Shinya Kitaoka 120a6e
TFrameId ToolUtils::getFrameId() {
Shinya Kitaoka 120a6e
  TTool::Application *app = TTool::getApplication();
Shinya Kitaoka 120a6e
  if (!app) return TFrameId();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TFrameHandle *frameHandle = app->getCurrentFrame();
Shinya Kitaoka 120a6e
  if (frameHandle->isEditingScene()) {
Shinya Kitaoka 120a6e
    TXsheet *xsh = app->getCurrentXsheet()->getXsheet();
Shinya Kitaoka 120a6e
    if (!xsh) return 0;
Shinya Kitaoka 120a6e
    int row = frameHandle->getFrame();
Shinya Kitaoka 120a6e
    int col = app->getCurrentColumn()->getColumnIndex();
Shinya Kitaoka 120a6e
    if (col < 0) return 0;
Shinya Kitaoka 120a6e
    TXshCell cell = xsh->getCell(row, col);
Shinya Kitaoka 120a6e
    return cell.getFrameId();
Shinya Kitaoka 120a6e
  } else
Shinya Kitaoka 120a6e
    return frameHandle->getFid();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void ToolUtils::drawRect(const TRectD &rect, const TPixel32 &color,
Shinya Kitaoka 120a6e
                         unsigned short stipple, bool doContrast) {
Shinya Kitaoka 120a6e
  GLint src, dst;
Shinya Kitaoka 120a6e
  bool isEnabled;
Shinya Kitaoka 120a6e
  tglColor(color);
Shinya Kitaoka 120a6e
  if (doContrast) {
Shinya Kitaoka 120a6e
    if (color == TPixel32::Black) tglColor(TPixel32(90, 90, 90));
Shinya Kitaoka 120a6e
    isEnabled = glIsEnabled(GL_BLEND);
Shinya Kitaoka 120a6e
    glGetIntegerv(GL_BLEND_SRC, &src);
Shinya Kitaoka 120a6e
    glGetIntegerv(GL_BLEND_DST, &dst);
Shinya Kitaoka 120a6e
    glEnable(GL_BLEND);
Shinya Kitaoka 120a6e
    glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ONE_MINUS_SRC_ALPHA);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (stipple != 0xffff) {
Shinya Kitaoka 120a6e
    glLineStipple(1, stipple);
Shinya Kitaoka 120a6e
    glEnable(GL_LINE_STIPPLE);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  glBegin(GL_LINE_STRIP);
Shinya Kitaoka 120a6e
  tglVertex(rect.getP00());
Shinya Kitaoka 120a6e
  tglVertex(rect.getP01());
Shinya Kitaoka 120a6e
  tglVertex(rect.getP11());
Shinya Kitaoka 120a6e
  tglVertex(rect.getP10());
Shinya Kitaoka 120a6e
  tglVertex(rect.getP00());
Shinya Kitaoka 120a6e
  glEnd();
Shinya Kitaoka 120a6e
  glDisable(GL_LINE_STIPPLE);
Shinya Kitaoka 120a6e
  if (doContrast) {
Shinya Kitaoka 120a6e
    if (!isEnabled) glDisable(GL_BLEND);
Shinya Kitaoka 120a6e
    glBlendFunc(src, dst);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void ToolUtils::fillRect(const TRectD &rect, const TPixel32 &color) {
Shinya Kitaoka 120a6e
  tglColor(color);
Shinya Kitaoka 120a6e
  glBegin(GL_QUADS);
Shinya Kitaoka 120a6e
  tglVertex(rect.getP00());
Shinya Kitaoka 120a6e
  tglVertex(rect.getP01());
Shinya Kitaoka 120a6e
  tglVertex(rect.getP11());
Shinya Kitaoka 120a6e
  tglVertex(rect.getP10());
Shinya Kitaoka 120a6e
  tglVertex(rect.getP00());
Shinya Kitaoka 120a6e
  glEnd();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void ToolUtils::drawPoint(const TPointD &q, double pixelSize) {
Shinya Kitaoka 120a6e
  double size = pixelSize * 2.0;
Shinya Kitaoka 120a6e
  glBegin(GL_QUADS);
Shinya Kitaoka 120a6e
  glVertex2d(q.x - size, q.y - size);
Shinya Kitaoka 120a6e
  glVertex2d(q.x - size, q.y + size);
Shinya Kitaoka 120a6e
  glVertex2d(q.x + size, q.y + size);
Shinya Kitaoka 120a6e
  glVertex2d(q.x + size, q.y - size);
Shinya Kitaoka 120a6e
  glEnd();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void ToolUtils::drawCross(const TPointD &q, double pixelSize) {
Shinya Kitaoka 120a6e
  double size = pixelSize;
Shinya Kitaoka 120a6e
  glBegin(GL_LINES);
Shinya Kitaoka 120a6e
  glVertex2d(q.x - size, q.y);
Shinya Kitaoka 120a6e
  glVertex2d(q.x + size, q.y);
Shinya Kitaoka 120a6e
  glEnd();
Shinya Kitaoka 120a6e
  glBegin(GL_LINES);
Shinya Kitaoka 120a6e
  glVertex2d(q.x, q.y - size);
Shinya Kitaoka 120a6e
  glVertex2d(q.x, q.y + size);
Shinya Kitaoka 120a6e
  glEnd();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void ToolUtils::drawArrow(const TSegment &s, double pixelSize) {
Shinya Kitaoka 120a6e
  TPointD v, vn;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  double length = s.getLength() * pixelSize;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (length == 0) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  v  = normalize(s.getSpeed());
Shinya Kitaoka 120a6e
  vn = v;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TPointD p1 = s.getP0() + v * length;
Shinya Kitaoka 120a6e
  glBegin(GL_LINES);
Shinya Kitaoka 120a6e
  tglVertex(s.getP0());
Shinya Kitaoka 120a6e
  tglVertex(p1);
Shinya Kitaoka 120a6e
  glEnd();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  v = v * length * 0.7;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  vn = vn * length * 0.2;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TPointD p;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  glBegin(GL_TRIANGLES);
Shinya Kitaoka 120a6e
  p = s.getP0() + v + rotate90(vn);
Shinya Kitaoka 120a6e
  tglVertex(p);
Shinya Kitaoka 120a6e
  tglVertex(p1);
Shinya Kitaoka 120a6e
  p = s.getP0() + v + rotate270(vn);
Shinya Kitaoka 120a6e
  tglVertex(p);
Shinya Kitaoka 120a6e
  glEnd();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void ToolUtils::drawSquare(const TPointD &pos, double r,
Shinya Kitaoka 120a6e
                           const TPixel32 &color) {
Shinya Kitaoka 120a6e
  TRectD rect(pos - TPointD(r, r), pos + TPointD(r, r));
Shinya Kitaoka 120a6e
  tglColor(color);
Shinya Kitaoka 120a6e
  glBegin(GL_LINE_STRIP);
Shinya Kitaoka 120a6e
  tglVertex(rect.getP00());
Shinya Kitaoka 120a6e
  tglVertex(rect.getP01());
Shinya Kitaoka 120a6e
  tglVertex(rect.getP11());
Shinya Kitaoka 120a6e
  tglVertex(rect.getP10());
Shinya Kitaoka 120a6e
  tglVertex(rect.getP00());
Shinya Kitaoka 120a6e
  glEnd();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void ToolUtils::drawRectWhitArrow(const TPointD &pos, double r) {
Shinya Kitaoka 120a6e
  if (TTool::getApplication()->getCurrentObject()->isSpline()) return;
Shinya Kitaoka 120a6e
  TRectD rect(pos - TPointD(14 * r, 2 * r), pos + TPointD(14 * r, 2 * r));
Shinya Kitaoka 120a6e
  tglColor(TPixel32::Black);
Shinya Kitaoka 120a6e
  glBegin(GL_POLYGON);
Shinya Kitaoka 120a6e
  tglVertex(rect.getP00());
Shinya Kitaoka 120a6e
  tglVertex(rect.getP10());
Shinya Kitaoka 120a6e
  tglVertex(rect.getP11());
Shinya Kitaoka 120a6e
  tglVertex(rect.getP01());
Shinya Kitaoka 120a6e
  glEnd();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  double par = 5 * r;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TPointD p01 = 0.5 * (rect.getP00() + rect.getP10());
Shinya Kitaoka 120a6e
  TPointD p02 = 0.5 * (rect.getP01() + rect.getP11());
Shinya Kitaoka 120a6e
  TPointD p11 = TPointD(p01.x, p01.y - par);
Shinya Kitaoka 120a6e
  TPointD p12 = TPointD(p02.x, p02.y + par);
Shinya Kitaoka 120a6e
  TPointD p;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  tglColor(TPixel32(130, 130, 130));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  glBegin(GL_TRIANGLES);
Shinya Kitaoka 120a6e
  p = p11 + rotate90(TPointD(0, par));
Shinya Kitaoka 120a6e
  tglVertex(p);
Shinya Kitaoka 120a6e
  tglVertex(p01);
Shinya Kitaoka 120a6e
  p = p11 + rotate270(TPointD(0, par));
Shinya Kitaoka 120a6e
  tglVertex(p);
Shinya Kitaoka 120a6e
  glEnd();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  glBegin(GL_TRIANGLES);
Shinya Kitaoka 120a6e
  p = p12 + rotate90(TPointD(0, -par));
Shinya Kitaoka 120a6e
  tglVertex(p);
Shinya Kitaoka 120a6e
  tglVertex(p02);
Shinya Kitaoka 120a6e
  p = p12 + rotate270(TPointD(0, -par));
Shinya Kitaoka 120a6e
  tglVertex(p);
Shinya Kitaoka 120a6e
  glEnd();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
QRadialGradient ToolUtils::getBrushPad(int size, double hardness) {
Shinya Kitaoka 120a6e
  hardness        = tcrop(hardness, 0.0, 0.97);
Shinya Kitaoka 120a6e
  double halfSize = size * 0.5;
Shinya Kitaoka 120a6e
  double x        = halfSize * hardness;
Shinya Kitaoka 120a6e
  TQuadratic q(TPointD(x, 1.0), TPointD((halfSize + x) * 0.5, 0.0),
Shinya Kitaoka 120a6e
               TPointD(halfSize, 0.0));
Shinya Kitaoka 120a6e
  QRadialGradient rd(QPointF(halfSize, halfSize), halfSize,
Shinya Kitaoka 120a6e
                     QPointF(halfSize, halfSize));
Shinya Kitaoka 120a6e
  rd.setColorAt(0, QColor(0, 0, 0));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  double t;
Shinya Kitaoka 120a6e
  double offset = halfSize - x;
Shinya Kitaoka 120a6e
  assert(offset > 0);
Shinya Kitaoka 120a6e
  for (t = 0; t <= 1; t += 1.0 / offset) {
Shinya Kitaoka 120a6e
    TPointD p = q.getPoint(t);
Shinya Kitaoka 120a6e
    int value = 255 * p.y;
Shinya Kitaoka 120a6e
    rd.setColorAt(p.x / halfSize, QColor(0, 0, 0, value));
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return rd;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
QList<trect> ToolUtils::splitRect(const TRect &first, const TRect &second) {</trect>
Shinya Kitaoka 120a6e
  TRect intersection = first * second;
Shinya Kitaoka 120a6e
  QList<trect> rects;</trect>
Shinya Kitaoka 120a6e
  if (intersection.isEmpty()) {
Shinya Kitaoka 120a6e
    rects.append(first);
Shinya Kitaoka 120a6e
    return rects;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TRect rect;
Shinya Kitaoka 120a6e
  if (first.x0 < intersection.x0) {
Shinya Kitaoka 120a6e
    rect = TRect(first.getP00(), TPoint(intersection.x0 - 1, first.y1));
Shinya Kitaoka 120a6e
    rects.append(rect);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (intersection.x1 < first.x1) {
Shinya Kitaoka 120a6e
    rect = TRect(TPoint(intersection.x1 + 1, first.y0), first.getP11());
Shinya Kitaoka 120a6e
    rects.append(rect);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (intersection.y1 < first.y1) {
Shinya Kitaoka 120a6e
    rect =
Shinya Kitaoka 120a6e
        TRect(intersection.x0, intersection.y1 + 1, intersection.x1, first.y1);
Shinya Kitaoka 120a6e
    rects.append(rect);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (first.y0 < intersection.y0) {
Shinya Kitaoka 120a6e
    rect =
Shinya Kitaoka 120a6e
        TRect(intersection.x0, first.y0, intersection.x1, intersection.y0 - 1);
Shinya Kitaoka 120a6e
    rects.append(rect);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return rects;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TRaster32P ToolUtils::convertStrokeToImage(TStroke *stroke,
Shinya Kitaoka 120a6e
                                           const TRect &imageBounds,
shun-iwasawa d02ca1
                                           TPoint &pos, bool pencilMode) {
Shinya Kitaoka 120a6e
  int count = stroke->getControlPointCount();
Shinya Kitaoka 120a6e
  if (count == 0) return TRaster32P();
Shinya Kitaoka 120a6e
  TPointD imgCenter = TPointD((imageBounds.x0 + imageBounds.x1) * 0.5,
Shinya Kitaoka 120a6e
                              (imageBounds.y0 + imageBounds.y1) * 0.5);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TStroke s(*stroke);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // check self looped stroke
Shinya Kitaoka 120a6e
  TThickPoint first = s.getControlPoint(0);
Shinya Kitaoka 120a6e
  TThickPoint back  = s.getControlPoint(count - 1);
Shinya Kitaoka 120a6e
  if (first != back) {
Shinya Kitaoka 120a6e
    TPointD mid = (first + back) * 0.5;
Shinya Kitaoka 120a6e
    s.setControlPoint(count, mid);
Shinya Kitaoka 120a6e
    s.setControlPoint(count + 1, first);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // check bounds intersection
Shinya Kitaoka 120a6e
  s.transform(TTranslation(imgCenter));
Shinya Kitaoka 120a6e
  TRectD bbox = s.getBBox();
Shinya Kitaoka 120a6e
  TRect rect(tfloor(bbox.x0), tfloor(bbox.y0), tfloor(bbox.x1),
Shinya Kitaoka 120a6e
             tfloor(bbox.y1));
Shinya Kitaoka 120a6e
  pos = rect.getP00();
Shinya Kitaoka 120a6e
  pos = TPoint(pos.x > 0 ? pos.x : 0, pos.y > 0 ? pos.y : 0);
Shinya Kitaoka 120a6e
  rect *= imageBounds;
Shinya Kitaoka 120a6e
  if (rect.isEmpty()) return TRaster32P();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // creates the image
Shinya Kitaoka 120a6e
  QImage img(rect.getLx(), rect.getLy(), QImage::Format_ARGB32);
Shinya Kitaoka 120a6e
  img.fill(Qt::transparent);
Shinya Kitaoka 120a6e
  QColor color = Qt::black;
Shinya Kitaoka 120a6e
  QPainter p(&img);
Shinya Kitaoka 120a6e
  p.setPen(QPen(color, 1, Qt::SolidLine));
Shinya Kitaoka 120a6e
  p.setBrush(color);
shun-iwasawa d02ca1
  p.setRenderHint(QPainter::Antialiasing, !pencilMode);
Shinya Kitaoka 120a6e
  QPainterPath path = strokeToPainterPath(&s);
Shinya Kitaoka 120a6e
  QRectF pathRect   = path.boundingRect();
Shinya Kitaoka 120a6e
  p.translate(-toQPoint(pos));
Shinya Kitaoka 120a6e
  p.drawPath(path);
Shinya Kitaoka 120a6e
  return rasterFromQImage(img, true, false);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TStroke *ToolUtils::merge(const ArrayOfStroke &a) {
Shinya Kitaoka 120a6e
  std::vector<tthickpoint> v;</tthickpoint>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TStroke *ref      = 0;
Shinya Kitaoka 120a6e
  int controlPoints = 0;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  for (UINT i = 0; i < a.size(); ++i) {
Shinya Kitaoka 120a6e
    ref = a[i];
Shinya Kitaoka 120a6e
    assert(ref);
Shinya Kitaoka 120a6e
    if (!ref) continue;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    controlPoints = ref->getControlPointCount() - 1;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    for (int j = 0; j < controlPoints; ++j)
Shinya Kitaoka 120a6e
      v.push_back(ref->getControlPoint(j));
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (controlPoints > 0) v.push_back(ref->getControlPoint(controlPoints));
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TStroke *out = new TStroke(v);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return out;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//================================================================================================
Toshihiro Shimizu 890ddd
//
Shinya Kitaoka 120a6e
// TToolUndo
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//================================================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
ToolUtils::TToolUndo::TToolUndo(TXshSimpleLevel *level, const TFrameId &frameId,
Shinya Kitaoka 120a6e
                                bool createdFrame, bool createdLevel,
Shinya Kitaoka 120a6e
                                const TPaletteP &oldPalette)
Shinya Kitaoka 120a6e
    : TUndo()
Shinya Kitaoka 120a6e
    , m_level(level)
Shinya Kitaoka 120a6e
    , m_frameId(frameId)
Shinya Kitaoka 120a6e
    , m_oldPalette(oldPalette)
Shinya Kitaoka 120a6e
    , m_col(-2)
Shinya Kitaoka 120a6e
    , m_row(-1)
Shinya Kitaoka 120a6e
    , m_isEditingLevel(false)
Shinya Kitaoka 120a6e
    , m_createdFrame(createdFrame)
Shinya Kitaoka 120a6e
    , m_createdLevel(createdLevel)
shun-iwasawa 536025
    , m_renumberedLevel(TTool::m_isLevelRenumbererd)
Shinya Kitaoka 120a6e
    , m_imageId("") {
Shinya Kitaoka 120a6e
  TTool::Application *app = TTool::getApplication();
Shinya Kitaoka 120a6e
  m_isEditingLevel        = app->getCurrentFrame()->isEditingLevel();
Shinya Kitaoka 120a6e
  if (!m_isEditingLevel) {
shun-iwasawa 536025
    m_col       = app->getCurrentColumn()->getColumnIndex();
shun-iwasawa 536025
    m_row       = app->getCurrentFrame()->getFrameIndex();
shun-iwasawa 536025
    m_cellsData = TTool::m_cellsData;
shun-iwasawa 536025
  }
shun-iwasawa 536025
  if (m_renumberedLevel) {
shun-iwasawa 536025
    m_oldFids = TTool::m_oldFids;
shun-iwasawa 536025
    m_newFids = TTool::m_newFids;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (createdFrame) {
Shinya Kitaoka 120a6e
    m_imageId = "TToolUndo" + std::to_string(m_idCount++);
Shinya Kitaoka 120a6e
    TImageCache::instance()->add(m_imageId, level->getFrame(frameId, false),
Shinya Kitaoka 120a6e
                                 false);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
ToolUtils::TToolUndo::~TToolUndo() {
Shinya Kitaoka 120a6e
  TImageCache::instance()->remove(m_imageId);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void ToolUtils::TToolUndo::insertLevelAndFrameIfNeeded() const {
Shinya Kitaoka 120a6e
  TTool::Application *app = TTool::getApplication();
shun-iwasawa 536025
  if (m_renumberedLevel) {
shun-iwasawa 536025
    TXsheet *xsh = app->getCurrentScene()->getScene()->getTopXsheet();
shun-iwasawa 536025
    std::vector<txshchildlevel *=""> childLevels;</txshchildlevel>
shun-iwasawa 536025
    ToolUtils::doUpdateXSheet(m_level.getPointer(), m_oldFids, m_newFids, xsh,
shun-iwasawa 536025
                              childLevels);
shun-iwasawa 536025
    m_level->renumber(m_newFids);
shun-iwasawa 536025
    app->getCurrentXsheet()->notifyXsheetChanged();
shun-iwasawa 536025
  }
Shinya Kitaoka 120a6e
  if (m_createdLevel) {
Shinya Kitaoka 120a6e
    TLevelSet *levelSet = app->getCurrentScene()->getScene()->getLevelSet();
Shinya Kitaoka 120a6e
    if (levelSet) {
Shinya Kitaoka 120a6e
      levelSet->insertLevel(m_level.getPointer());
Shinya Kitaoka 120a6e
      app->getCurrentScene()->notifyCastChange();
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (m_createdFrame) {
Shinya Kitaoka 120a6e
    TXsheet *xsh = app->getCurrentXsheet()->getXsheet();
Shinya Kitaoka 120a6e
    TImageP img  = TImageCache::instance()->get(m_imageId, false);
Shinya Kitaoka 120a6e
    m_level->setFrame(m_frameId, img);
Shinya Kitaoka 120a6e
    if (!m_isEditingLevel) {
shun-iwasawa 536025
      for (const TTool::CellOps &cellOps : m_cellsData) {
shun-iwasawa 536025
        TXshCell cell;
shun-iwasawa 536025
        if (cellOps.type == TTool::CellOps::BlankToExisting)
shun-iwasawa 536025
          cell = xsh->getCell(cellOps.r0 - 1, m_col);
shun-iwasawa 536025
        else
shun-iwasawa 536025
          cell = TXshCell(m_level.getPointer(), m_frameId);
shun-iwasawa 536025
        for (int r = cellOps.r0; r <= cellOps.r1; r++)
shun-iwasawa 536025
          xsh->setCell(r, m_col, cell);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    app->getCurrentLevel()->notifyLevelChange();
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void ToolUtils::TToolUndo::removeLevelAndFrameIfNeeded() const {
Shinya Kitaoka 120a6e
  TTool::Application *app = TTool::getApplication();
Shinya Kitaoka 120a6e
  if (m_createdFrame) {
Shinya Kitaoka 120a6e
    m_level->eraseFrame(m_frameId);
Shinya Kitaoka 120a6e
    if (!m_isEditingLevel) {
Shinya Kitaoka 120a6e
      TXsheet *xsh = app->getCurrentXsheet()->getXsheet();
justburner 2975e1
      TXshCell cell;
shun-iwasawa 536025
      for (const TTool::CellOps &cellOps : m_cellsData) {
shun-iwasawa 536025
        if (cellOps.type == TTool::CellOps::ExistingToNew)
shun-iwasawa 536025
          cell = xsh->getCell(cellOps.r0 - 1, m_col);
shun-iwasawa 536025
        for (int r = cellOps.r0; r <= cellOps.r1; r++)
shun-iwasawa 536025
          xsh->setCell(r, m_col, cell);
Shinya Kitaoka 120a6e
      }
justburner 2975e1
      if (m_cellsData.size() < 1) {
justburner 2975e1
        xsh->setCell(m_row, m_col, cell);
justburner 2975e1
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    if (m_createdLevel) {
Shinya Kitaoka 120a6e
      // butta il livello
Shinya Kitaoka 120a6e
      TLevelSet *levelSet = app->getCurrentScene()->getScene()->getLevelSet();
Shinya Kitaoka 120a6e
      if (levelSet) {
Shinya Kitaoka 120a6e
        levelSet->removeLevel(m_level.getPointer());
Shinya Kitaoka 120a6e
        app->getCurrentScene()->notifyCastChange();
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    app->getCurrentLevel()->notifyLevelChange();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (m_oldPalette.getPointer()) {
Shinya Kitaoka 120a6e
    m_level->getPalette()->assign(m_oldPalette->clone());
Shinya Kitaoka 120a6e
    app->getPaletteController()
Shinya Kitaoka 120a6e
        ->getCurrentLevelPalette()
Shinya Kitaoka 120a6e
        ->notifyPaletteChanged();
Shinya Kitaoka 120a6e
  }
shun-iwasawa 536025
  if (m_renumberedLevel) {
shun-iwasawa 536025
    TXsheet *xsh = app->getCurrentScene()->getScene()->getTopXsheet();
shun-iwasawa 536025
    std::vector<txshchildlevel *=""> childLevels;</txshchildlevel>
shun-iwasawa 536025
    ToolUtils::doUpdateXSheet(m_level.getPointer(), m_newFids, m_oldFids, xsh,
shun-iwasawa 536025
                              childLevels);
shun-iwasawa 536025
    m_level->renumber(m_oldFids);
shun-iwasawa 536025
    app->getCurrentXsheet()->notifyXsheetChanged();
shun-iwasawa 536025
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void ToolUtils::TToolUndo::notifyImageChanged() const {
Shinya Kitaoka 120a6e
  TTool::Application *app = TTool::getApplication();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TXshSimpleLevel *currentSl = 0;
Shinya Kitaoka 120a6e
  TFrameId currentFrameId;
Shinya Kitaoka 120a6e
  if (app->getCurrentFrame()->isEditingLevel()) {
Shinya Kitaoka 120a6e
    TXshLevel *xl = app->getCurrentLevel()->getLevel();
Shinya Kitaoka 120a6e
    if (!xl) return;
Shinya Kitaoka 120a6e
    currentSl      = xl->getSimpleLevel();
Shinya Kitaoka 120a6e
    currentFrameId = app->getCurrentFrame()->getFid();
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    int row = app->getCurrentFrame()->getFrame();
Shinya Kitaoka 120a6e
    int col = app->getCurrentColumn()->getColumnIndex();
Shinya Kitaoka 120a6e
    if (col < 0) return;
Shinya Kitaoka 120a6e
    TXsheet *xsh = app->getCurrentXsheet()->getXsheet();
Shinya Kitaoka 120a6e
    if (!xsh) return;
Shinya Kitaoka 120a6e
    TXshCell cell  = xsh->getCell(row, col);
Shinya Kitaoka 120a6e
    currentSl      = cell.getSimpleLevel();
Shinya Kitaoka 120a6e
    currentFrameId = cell.getFrameId();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (currentSl == m_level.getPointer() && currentFrameId == m_frameId) {
Shinya Kitaoka 120a6e
    TTool *tool = app->getCurrentTool()->getTool();
Shinya Kitaoka 120a6e
    if (tool) tool->onImageChanged();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  IconGenerator::instance()->invalidate(m_level.getPointer(), m_frameId);
Shinya Kitaoka 120a6e
  IconGenerator::instance()->invalidateSceneIcon();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (m_level && m_level->getType() == PLI_XSHLEVEL) {
Shinya Kitaoka 120a6e
    std::string id = m_level->getImageId(m_frameId) + "_rasterized";
Shinya Kitaoka 120a6e
    ImageManager::instance()->invalidate(id);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
shun-iwasawa 530bef
//------------------------------------------------------------------------------------------
shun-iwasawa 530bef
shun-iwasawa 530bef
void ToolUtils::TToolUndo::onAdd() {
shun-iwasawa 530bef
  // clean up the flags after registering undo
shun-iwasawa 530bef
  TTool::m_isLevelCreated     = false;
shun-iwasawa 530bef
  TTool::m_isFrameCreated     = false;
shun-iwasawa 530bef
  TTool::m_isLevelRenumbererd = false;
shun-iwasawa 530bef
}
shun-iwasawa 530bef
shun-iwasawa 530bef
//------------------------------------------------------------------------------------------
shun-iwasawa 530bef
Toshihiro Shimizu 890ddd
int ToolUtils::TToolUndo::m_idCount = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//================================================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//================================================================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
ToolUtils::TRasterUndo::TRasterUndo(TTileSetCM32 *tiles, TXshSimpleLevel *level,
Shinya Kitaoka 120a6e
                                    const TFrameId &frameId, bool createdFrame,
Shinya Kitaoka 120a6e
                                    bool createdLevel,
Shinya Kitaoka 120a6e
                                    const TPaletteP &oldPalette)
Shinya Kitaoka 120a6e
    : TToolUndo(level, frameId, createdFrame, createdLevel, oldPalette)
Shinya Kitaoka 120a6e
    , m_tiles(tiles) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
ToolUtils::TRasterUndo::~TRasterUndo() {
Shinya Kitaoka 120a6e
  if (m_tiles) delete m_tiles;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TToonzImageP ToolUtils::TRasterUndo::getImage() const {
Shinya Kitaoka 120a6e
  if (m_level->isFid(m_frameId))
Shinya Kitaoka 120a6e
    return (TToonzImageP)m_level->getFrame(m_frameId, true);
Shinya Kitaoka 120a6e
  return 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int ToolUtils::TRasterUndo::getSize() const {
Shinya Kitaoka 120a6e
  int size = sizeof(*this);
Shinya Kitaoka 120a6e
  size += sizeof(*(m_level.getPointer()));
Shinya Kitaoka 120a6e
  size += sizeof(*(m_oldPalette.getPointer()));
Shinya Kitaoka 120a6e
  return m_tiles ? m_tiles->getMemorySize() + size : size;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void ToolUtils::TRasterUndo::undo() const {
Shinya Kitaoka 120a6e
  TTool::Application *app = TTool::getApplication();
Shinya Kitaoka 120a6e
  if (!app) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (m_tiles && m_tiles->getTileCount() > 0) {
Shinya Kitaoka 120a6e
    TToonzImageP image = getImage();
Shinya Kitaoka 120a6e
    if (!image) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    ToonzImageUtils::paste(image, m_tiles);
Shinya Kitaoka 120a6e
    ToolUtils::updateSaveBox(m_level, m_frameId);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  removeLevelAndFrameIfNeeded();
Toshihiro Shimizu 890ddd
justburner 2975e1
  if (m_level) {
justburner 2975e1
    m_level->setDirtyFlag(true);
justburner 2975e1
  }
Shinya Kitaoka 120a6e
  app->getCurrentXsheet()->notifyXsheetChanged();
Shinya Kitaoka 120a6e
  notifyImageChanged();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//================================================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//================================================================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
ToolUtils::TFullColorRasterUndo::TFullColorRasterUndo(
Shinya Kitaoka 120a6e
    TTileSetFullColor *tiles, TXshSimpleLevel *level, const TFrameId &frameId,
Shinya Kitaoka 120a6e
    bool createdFrame, bool createdLevel, const TPaletteP &oldPalette)
Shinya Kitaoka 120a6e
    : TToolUndo(level, frameId, createdFrame, createdLevel, oldPalette)
Shinya Kitaoka 120a6e
    , m_tiles(tiles) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
ToolUtils::TFullColorRasterUndo::~TFullColorRasterUndo() { delete m_tiles; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TRasterImageP ToolUtils::TFullColorRasterUndo::getImage() const {
Shinya Kitaoka 120a6e
  if (m_level->isFid(m_frameId))
Shinya Kitaoka 120a6e
    return (TRasterImageP)m_level->getFrame(m_frameId, true);
Shinya Kitaoka 120a6e
  return 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int ToolUtils::TFullColorRasterUndo::getSize() const {
Shinya Kitaoka 120a6e
  int size = sizeof(*this);
Shinya Kitaoka 120a6e
  size += sizeof(*(m_level.getPointer()));
Shinya Kitaoka 120a6e
  size += sizeof(*(m_oldPalette.getPointer()));
Shinya Kitaoka 120a6e
  return m_tiles ? m_tiles->getMemorySize() + size : size;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void ToolUtils::TFullColorRasterUndo::undo() const {
Shinya Kitaoka 120a6e
  TTool::Application *app = TTool::getApplication();
Shinya Kitaoka 120a6e
  if (!app) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (m_tiles && m_tiles->getTileCount() > 0) {
Shinya Kitaoka 120a6e
    TRasterImageP image = getImage();
Shinya Kitaoka 120a6e
    if (!image) return;
Shinya Kitaoka 120a6e
    std::vector<trect> rects = paste(image, m_tiles);</trect>
Shinya Kitaoka 120a6e
    int i;
Shinya Kitaoka 120a6e
    TRect resRect = rects[0];
Shinya Kitaoka 120a6e
    for (i = 1; i < (int)rects.size(); i++) resRect += rects[i];
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  removeLevelAndFrameIfNeeded();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  app->getCurrentXsheet()->notifyXsheetChanged();
Shinya Kitaoka 120a6e
  notifyImageChanged();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
std::vector<trect> ToolUtils::TFullColorRasterUndo::paste(</trect>
Shinya Kitaoka 120a6e
    const TRasterImageP &ti, const TTileSetFullColor *tileSet) const {
Shinya Kitaoka 120a6e
  std::vector<trect> rects;</trect>
Shinya Kitaoka 120a6e
  TRasterP raster = ti->getRaster();
Shinya Kitaoka 120a6e
  for (int i = 0; i < tileSet->getTileCount(); i++) {
Shinya Kitaoka 120a6e
    const TTileSetFullColor::Tile *tile = tileSet->getTile(i);
Shinya Kitaoka 120a6e
    TRasterP ras;
Shinya Kitaoka 120a6e
    tile->getRaster(ras);
Shinya Kitaoka 120a6e
    assert(!!ras);
Shinya Kitaoka 120a6e
    raster->copy(ras, tile->m_rasterBounds.getP00());
Shinya Kitaoka 120a6e
    rects.push_back(tile->m_rasterBounds);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return rects;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//================================================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//================================================================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
ToolUtils::UndoModifyStroke::UndoModifyStroke(TXshSimpleLevel *level,
Shinya Kitaoka 120a6e
                                              const TFrameId &frameId,
Shinya Kitaoka 120a6e
                                              int strokeIndex)
Shinya Kitaoka 120a6e
    : TToolUndo(level, frameId), m_strokeIndex(strokeIndex) {
Shinya Kitaoka 120a6e
  TVectorImageP image = level->getFrame(frameId, true);
Shinya Kitaoka 120a6e
  assert(image);
Shinya Kitaoka 120a6e
  TStroke *stroke = image->getStroke(m_strokeIndex);
Shinya Kitaoka 120a6e
  int n           = stroke->getControlPointCount();
Shinya Kitaoka 120a6e
  for (int i = 0; i < n; i++) m_before.push_back(stroke->getControlPoint(i));
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_selfLoopBefore = stroke->isSelfLoop();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TTool::Application *app = TTool::getApplication();
Shinya Kitaoka 120a6e
  m_row                   = app->getCurrentFrame()->getFrame();
Shinya Kitaoka 120a6e
  m_column                = app->getCurrentColumn()->getColumnIndex();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
ToolUtils::UndoModifyStroke::~UndoModifyStroke() {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void ToolUtils::UndoModifyStroke::onAdd() {
Shinya Kitaoka 120a6e
  TVectorImageP image = m_level->getFrame(m_frameId, true);
Shinya Kitaoka 120a6e
  assert(image);
Shinya Kitaoka 120a6e
  if (!image) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TStroke *stroke = image->getStroke(m_strokeIndex);
Shinya Kitaoka 120a6e
  assert(stroke);
Shinya Kitaoka 120a6e
  int n = stroke->getControlPointCount();
Shinya Kitaoka 120a6e
  for (int i = 0; i < n; i++) m_after.push_back(stroke->getControlPoint(i));
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_selfLoopAfter = stroke->isSelfLoop();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void ToolUtils::UndoModifyStroke::undo() const {
Shinya Kitaoka 120a6e
  TTool::Application *app = TTool::getApplication();
Shinya Kitaoka 120a6e
  if (!app) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (app->getCurrentFrame()->isEditingScene()) {
Shinya Kitaoka 120a6e
    app->getCurrentColumn()->setColumnIndex(m_column);
Shinya Kitaoka 120a6e
    app->getCurrentFrame()->setFrame(m_row);
Shinya Kitaoka 120a6e
  } else
Shinya Kitaoka 120a6e
    app->getCurrentFrame()->setFid(m_frameId);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TSelection *selection = app->getCurrentSelection()->getSelection();
Shinya Kitaoka 120a6e
  if (selection) selection->selectNone();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TVectorImageP image = m_level->getFrame(m_frameId, true);
Shinya Kitaoka 120a6e
  assert(image);
Shinya Kitaoka 120a6e
  if (!image) return;
Shinya Kitaoka 120a6e
  QMutexLocker lock(image->getMutex());
Shinya Kitaoka 120a6e
  TStroke *stroke = 0;
Shinya Kitaoka 120a6e
  if (image->getStrokeCount() ==
Shinya Kitaoka 120a6e
      1)  // && image->getStroke(0)->getStyle()==SplineStyle)
Shinya Kitaoka 120a6e
    stroke = image->getStroke(0);
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    stroke = image->getStroke(m_strokeIndex);
Shinya Kitaoka 120a6e
  if (!stroke) return;
Shinya Kitaoka 120a6e
  TStroke *oldStroke = new TStroke(*stroke);
Shinya Kitaoka 120a6e
  stroke->reshape(&m_before[0], m_before.size());
Shinya Kitaoka 120a6e
  stroke->setSelfLoop(m_selfLoopBefore);
Shinya Kitaoka 120a6e
  image->notifyChangedStrokes(m_strokeIndex, oldStroke);
Shinya Kitaoka 120a6e
  notifyImageChanged();
Shinya Kitaoka 120a6e
  delete oldStroke;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void ToolUtils::UndoModifyStroke::redo() const {
Shinya Kitaoka 120a6e
  TTool::Application *app = TTool::getApplication();
Shinya Kitaoka 120a6e
  if (!app) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (app->getCurrentFrame()->isEditingScene()) {
Shinya Kitaoka 120a6e
    app->getCurrentColumn()->setColumnIndex(m_column);
Shinya Kitaoka 120a6e
    app->getCurrentFrame()->setFrame(m_row);
Shinya Kitaoka 120a6e
  } else
Shinya Kitaoka 120a6e
    app->getCurrentFrame()->setFid(m_frameId);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TSelection *selection = app->getCurrentSelection()->getSelection();
Shinya Kitaoka 120a6e
  if (selection) selection->selectNone();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TVectorImageP image = m_level->getFrame(m_frameId, true);
Shinya Kitaoka 120a6e
  assert(image);
Shinya Kitaoka 120a6e
  if (!image) return;
Shinya Kitaoka 120a6e
  QMutexLocker lock(image->getMutex());
Shinya Kitaoka 120a6e
  TStroke *stroke = 0;
Shinya Kitaoka 120a6e
  if (image->getStrokeCount() ==
Shinya Kitaoka 120a6e
      1)  //&& image->getStroke(0)->getStyle()==SplineStyle)
Shinya Kitaoka 120a6e
    stroke = image->getStroke(0);
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    stroke = image->getStroke(m_strokeIndex);
Shinya Kitaoka 120a6e
  if (!stroke) return;
Shinya Kitaoka 120a6e
  TStroke *oldStroke = new TStroke(*stroke);
Shinya Kitaoka 120a6e
  stroke->reshape(&m_after[0], m_after.size());
Shinya Kitaoka 120a6e
  stroke->setSelfLoop(m_selfLoopAfter);
Shinya Kitaoka 120a6e
  image->notifyChangedStrokes(m_strokeIndex, oldStroke);
Shinya Kitaoka 120a6e
  delete oldStroke;
Shinya Kitaoka 120a6e
  app->getCurrentXsheet()->notifyXsheetChanged();
Shinya Kitaoka 120a6e
  notifyImageChanged();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int ToolUtils::UndoModifyStroke::getSize() const {
Shinya Kitaoka 120a6e
  return (m_before.capacity() + m_after.capacity()) * sizeof(TThickPoint) +
Shinya Kitaoka 120a6e
         sizeof(*this) + 500;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
ToolUtils::UndoModifyStrokeAndPaint::UndoModifyStrokeAndPaint(
Shinya Kitaoka 120a6e
    TXshSimpleLevel *level, const TFrameId &frameId, int strokeIndex)
Shinya Kitaoka 120a6e
    : UndoModifyStroke(level, frameId, strokeIndex), m_fillInformation(0) {
Shinya Kitaoka 120a6e
  TVectorImageP image = level->getFrame(frameId, true);
Shinya Kitaoka 120a6e
  assert(image);
Shinya Kitaoka 120a6e
  TStroke *stroke = image->getStroke(strokeIndex);
Shinya Kitaoka 120a6e
  m_oldBBox       = stroke->getBBox();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void ToolUtils::UndoModifyStrokeAndPaint::onAdd() {
Shinya Kitaoka 120a6e
  TVectorImageP image = m_level->getFrame(m_frameId, true);
Shinya Kitaoka 120a6e
  assert(!!image);
Shinya Kitaoka 120a6e
  if (!image) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  UndoModifyStroke::onAdd();
Shinya Kitaoka 120a6e
  TStroke *stroke   = image->getStroke(m_strokeIndex);
Shinya Kitaoka 120a6e
  m_fillInformation = new std::vector<tfilledregioninf>;</tfilledregioninf>
Shinya Kitaoka 120a6e
  ImageUtils::getFillingInformationOverlappingArea(
Shinya Kitaoka 120a6e
      image, *m_fillInformation, m_oldBBox, stroke->getBBox());
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void ToolUtils::UndoModifyStrokeAndPaint::undo() const {
Shinya Kitaoka 120a6e
  TTool::Application *application = TTool::getApplication();
Shinya Kitaoka 120a6e
  if (!application) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  UndoModifyStroke::undo();
Shinya Kitaoka 120a6e
  TRegion *reg;
Shinya Kitaoka 120a6e
  UINT size = m_fillInformation->size();
Shinya Kitaoka 120a6e
  if (!size) {
Shinya Kitaoka 120a6e
    application->getCurrentXsheet()->notifyXsheetChanged();
Shinya Kitaoka 120a6e
    notifyImageChanged();
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TVectorImageP image = m_level->getFrame(m_frameId, true);
Shinya Kitaoka 120a6e
  assert(!!image);
Shinya Kitaoka 120a6e
  if (!image) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // image->validateRegions();
Shinya Kitaoka 120a6e
  image->findRegions();
Shinya Kitaoka 120a6e
  for (UINT i = 0; i < size; i++) {
Shinya Kitaoka 120a6e
    reg = image->getRegion((*m_fillInformation)[i].m_regionId);
Shinya Kitaoka 120a6e
    assert(reg);
Shinya Kitaoka 120a6e
    if (reg) reg->setStyle((*m_fillInformation)[i].m_styleId);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  application->getCurrentXsheet()->notifyXsheetChanged();
Shinya Kitaoka 120a6e
  notifyImageChanged();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
ToolUtils::UndoModifyStrokeAndPaint::~UndoModifyStrokeAndPaint() {
Shinya Kitaoka 120a6e
  delete m_fillInformation;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int ToolUtils::UndoModifyStrokeAndPaint::getSize() const {
Shinya Kitaoka 120a6e
  int size = m_fillInformation
Shinya Kitaoka 120a6e
                 ? m_fillInformation->size() * sizeof(TFilledRegionInf)
Shinya Kitaoka 120a6e
                 : 0;
Shinya Kitaoka 120a6e
  return UndoModifyStroke::getSize() + size;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
ToolUtils::UndoModifyListStroke::UndoModifyListStroke(
Shinya Kitaoka 120a6e
    TXshSimpleLevel *level, const TFrameId &frameId,
Shinya Kitaoka 120a6e
    const std::vector<tstroke *=""> &strokeVect)</tstroke>
Shinya Kitaoka 120a6e
    : TToolUndo(level, frameId), m_fillInformation(0) {
Shinya Kitaoka 120a6e
  UINT strokeNum      = strokeVect.size();
Shinya Kitaoka 120a6e
  TVectorImageP image = level->getFrame(frameId, true);
Shinya Kitaoka 120a6e
  assert(image);
Shinya Kitaoka 120a6e
  for (UINT i = 0; i < strokeNum; i++) {
Shinya Kitaoka 120a6e
    m_oldBBox += (strokeVect[i])->getBBox();
Shinya Kitaoka 120a6e
    int strokeIndex = image->getStrokeIndex(strokeVect[i]);
Shinya Kitaoka 120a6e
    m_strokeList.push_back(new UndoModifyStroke(level, frameId, strokeIndex));
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_beginIt = m_strokeList.begin();
Shinya Kitaoka 120a6e
  m_endIt   = m_strokeList.end();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
ToolUtils::UndoModifyListStroke::~UndoModifyListStroke() {
Shinya Kitaoka 120a6e
  clearPointerContainer(m_strokeList);
Shinya Kitaoka 120a6e
  delete m_fillInformation;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void ToolUtils::UndoModifyListStroke::onAdd() {
Shinya Kitaoka 120a6e
  std::list<undomodifystroke *="">::iterator it = m_beginIt;</undomodifystroke>
Shinya Kitaoka 120a6e
  TRectD newBBox;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TVectorImageP image = m_level->getFrame(m_frameId, true);
Shinya Kitaoka 120a6e
  assert(!!image);
Shinya Kitaoka 120a6e
  if (!image) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  for (; it != m_endIt; ++it) {
Shinya Kitaoka 120a6e
    TStroke *s = image->getStroke((*it)->m_strokeIndex);
Shinya Kitaoka 120a6e
    (*it)->onAdd();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  m_fillInformation = new std::vector<tfilledregioninf>;</tfilledregioninf>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (m_beginIt != m_endIt)
Shinya Kitaoka 120a6e
    ImageUtils::getFillingInformationOverlappingArea(image, *m_fillInformation,
Shinya Kitaoka 120a6e
                                                     m_oldBBox, newBBox);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void ToolUtils::UndoModifyListStroke::undo() const {
Shinya Kitaoka 120a6e
  TTool::Application *app = TTool::getApplication();
Shinya Kitaoka 120a6e
  if (!app) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::list<undomodifystroke *="">::iterator stroke_it = m_beginIt;</undomodifystroke>
Shinya Kitaoka 120a6e
  if (m_beginIt == m_endIt) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (; stroke_it != m_endIt; ++stroke_it) {
Shinya Kitaoka 120a6e
    (*stroke_it)->undo();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  UINT size = m_fillInformation->size();
Shinya Kitaoka 120a6e
  if (!size) {
Shinya Kitaoka 120a6e
    app->getCurrentXsheet()->notifyXsheetChanged();
Shinya Kitaoka 120a6e
    app->getCurrentTool()->getTool()->notifyImageChanged();
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TVectorImageP image = m_level->getFrame(m_frameId, true);
Shinya Kitaoka 120a6e
  assert(!!image);
Shinya Kitaoka 120a6e
  if (!image) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  image->findRegions();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TRegion *reg;
Shinya Kitaoka 120a6e
  for (UINT i = 0; i < size; i++) {
Shinya Kitaoka 120a6e
    reg = image->getRegion((*m_fillInformation)[i].m_regionId);
Shinya Kitaoka 120a6e
    assert(reg);
Shinya Kitaoka 120a6e
    if (reg) reg->setStyle((*m_fillInformation)[i].m_styleId);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  app->getCurrentXsheet()->notifyXsheetChanged();
Shinya Kitaoka 120a6e
  notifyImageChanged();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void ToolUtils::UndoModifyListStroke::redo() const {
Shinya Kitaoka 120a6e
  TTool::Application *app = TTool::getApplication();
Shinya Kitaoka 120a6e
  if (!app) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  std::list<undomodifystroke *="">::iterator it = m_beginIt;</undomodifystroke>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  for (; it != m_endIt; ++it) {
Shinya Kitaoka 120a6e
    (*it)->redo();
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  app->getCurrentXsheet()->notifyXsheetChanged();
Shinya Kitaoka 120a6e
  notifyImageChanged();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int ToolUtils::UndoModifyListStroke::getSize() const {
Shinya Kitaoka 120a6e
  int sum = 0;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  std::list<undomodifystroke *="">::iterator it = m_beginIt;</undomodifystroke>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  for (; it != m_endIt; ++it) {
Shinya Kitaoka 120a6e
    sum += (*it)->getSize();
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (m_fillInformation)
Shinya Kitaoka 120a6e
    sum += m_fillInformation->capacity() * sizeof(TFilledRegionInf);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return sum;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
ToolUtils::UndoPencil::UndoPencil(
Shinya Kitaoka 120a6e
    TStroke *stroke, std::vector<tfilledregioninf> *fillInformation,</tfilledregioninf>
Shinya Kitaoka 120a6e
    TXshSimpleLevel *level, const TFrameId &frameId, bool createdFrame,
Shinya Kitaoka 120a6e
    bool createdLevel, bool autogroup, bool autofill)
Shinya Kitaoka 120a6e
    : TToolUndo(level, frameId, createdFrame, createdLevel, 0)
Shinya Kitaoka 120a6e
    , m_strokeId(stroke->getId())
Shinya Kitaoka 120a6e
    , m_fillInformation(fillInformation)
Shinya Kitaoka 120a6e
    , m_autogroup(autogroup)
Shinya Kitaoka 120a6e
    , m_autofill(autofill) {
Shinya Kitaoka 120a6e
  m_stroke = new TStroke(*stroke);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
ToolUtils::UndoPencil::~UndoPencil() {
Shinya Kitaoka 120a6e
  delete m_fillInformation;
Shinya Kitaoka 120a6e
  delete m_stroke;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void ToolUtils::UndoPencil::undo() const {
Shinya Kitaoka 120a6e
  TTool::Application *app = TTool::getApplication();
Shinya Kitaoka 120a6e
  if (!app) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*if(app->getCurrentFrame()->isEditingScene() && m_col!=-2 && m_row!=-1)
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
          app->getCurrentColumn()->setColumnIndex(m_col);
Shinya Kitaoka 120a6e
          app->getCurrentFrame()->setFrame(m_row);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
          app->getCurrentFrame()->setFid(m_frameId);*/
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TVectorImageP image = m_level->getFrame(m_frameId, true);
Shinya Kitaoka 120a6e
  assert(image);
Shinya Kitaoka 120a6e
  if (!image) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  QMutexLocker sl(image->getMutex());
Shinya Kitaoka 120a6e
  VIStroke *stroke = image->getStrokeById(m_strokeId);
Shinya Kitaoka 120a6e
  if (!stroke) return;
Shinya Kitaoka 120a6e
  image->deleteStroke(stroke);
Shinya Kitaoka 2a7129
  TSelection *selection            = app->getCurrentSelection()->getSelection();
shun_iwasawa c7aa6f
  StrokeSelection *strokeSelection = dynamic_cast<strokeselection *="">(selection);</strokeselection>
Shinya Kitaoka 2a7129
  if (strokeSelection) strokeSelection->selectNone();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  UINT size = m_fillInformation->size();
Shinya Kitaoka 120a6e
  TRegion *reg;
Shinya Kitaoka 120a6e
  for (UINT i = 0; i < size; i++) {
Shinya Kitaoka 120a6e
    reg = image->getRegion((*m_fillInformation)[i].m_regionId);
Shinya Kitaoka 120a6e
    assert(reg);
Shinya Kitaoka 120a6e
    if (reg) reg->setStyle((*m_fillInformation)[i].m_styleId);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  removeLevelAndFrameIfNeeded();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  app->getCurrentXsheet()->notifyXsheetChanged();
Shinya Kitaoka 120a6e
  notifyImageChanged();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void ToolUtils::UndoPencil::redo() const {
Shinya Kitaoka 120a6e
  TTool::Application *app = TTool::getApplication();
Shinya Kitaoka 120a6e
  if (!app) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  insertLevelAndFrameIfNeeded();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*if(app->getCurrentFrame()->isEditingScene())
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
          app->getCurrentColumn()->setColumnIndex(m_col);
Shinya Kitaoka 120a6e
          app->getCurrentFrame()->setFrame(m_row);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
          app->getCurrentFrame()->setFid(m_frameId);*/
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TVectorImageP image = m_level->getFrame(m_frameId, true);
Shinya Kitaoka 120a6e
  if (!image) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  QMutexLocker sl(image->getMutex());
Shinya Kitaoka 120a6e
  TStroke *stroke = new TStroke(*m_stroke);
Shinya Kitaoka 120a6e
  stroke->setId(m_strokeId);
Shinya Kitaoka 120a6e
  image->addStroke(stroke);
Shinya Kitaoka 120a6e
  if (image->isComputedRegionAlmostOnce()) image->findRegions();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (m_autogroup && stroke->isSelfLoop()) {
Shinya Kitaoka 120a6e
    int index = image->getStrokeCount() - 1;
Shinya Kitaoka 120a6e
    image->group(index, 1);
Shinya Kitaoka 120a6e
    if (m_autofill) {
Shinya Kitaoka 120a6e
      // to avoid filling other strokes, I enter into the new stroke group
Shinya Kitaoka 120a6e
      int currentGroup = image->exitGroup();
Shinya Kitaoka 120a6e
      image->enterGroup(index);
Shinya Kitaoka 120a6e
      image->selectFill(stroke->getBBox().enlarge(1, 1), 0, stroke->getStyle(),
Shinya Kitaoka 120a6e
                        false, true, false);
Shinya Kitaoka 120a6e
      if (currentGroup != -1)
Shinya Kitaoka 120a6e
        image->enterGroup(currentGroup);
Shinya Kitaoka 120a6e
      else
Shinya Kitaoka 120a6e
        image->exitGroup();
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  app->getCurrentXsheet()->notifyXsheetChanged();
Shinya Kitaoka 120a6e
  notifyImageChanged();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int ToolUtils::UndoPencil::getSize() const {
Shinya Kitaoka 120a6e
  return sizeof(*this) +
Shinya Kitaoka 120a6e
         m_fillInformation->capacity() * sizeof(TFilledRegionInf) + 500;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
ToolUtils::UndoRasterPencil::UndoRasterPencil(
Shinya Kitaoka 120a6e
    TXshSimpleLevel *level, const TFrameId &frameId, TStroke *stroke,
Shinya Kitaoka 120a6e
    bool selective, bool filled, bool doAntialias, bool createdFrame,
Shinya Kitaoka 120a6e
    bool createdLevel, std::string primitiveName)
Shinya Kitaoka 120a6e
    : TRasterUndo(0, level, frameId, createdFrame, createdLevel, 0)
Shinya Kitaoka 120a6e
    , m_selective(selective)
Shinya Kitaoka 120a6e
    , m_filled(filled)
Shinya Kitaoka 120a6e
    , m_doAntialias(doAntialias)
Shinya Kitaoka 120a6e
    , m_primitiveName(primitiveName) {
Shinya Kitaoka 120a6e
  TRasterCM32P raster = getImage()->getRaster();
Shinya Kitaoka 120a6e
  TDimension d        = raster->getSize();
Shinya Kitaoka 120a6e
  m_tiles             = new TTileSetCM32(d);
Shinya Kitaoka 120a6e
  TRect rect =
Shinya Kitaoka 120a6e
      convert(stroke->getBBox()) + TPoint((int)(d.lx * 0.5), (int)(d.ly * 0.5));
Shinya Kitaoka 120a6e
  m_tiles->add(raster, rect.enlarge(2));
Shinya Kitaoka 120a6e
  m_stroke = new TStroke(*stroke);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
ToolUtils::UndoRasterPencil::~UndoRasterPencil() { delete m_stroke; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void ToolUtils::UndoRasterPencil::redo() const {
Shinya Kitaoka 120a6e
  insertLevelAndFrameIfNeeded();
Shinya Kitaoka 120a6e
  TToonzImageP image = getImage();
Shinya Kitaoka 120a6e
  if (!image) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  ToonzImageUtils::addInkStroke(image, m_stroke, m_stroke->getStyle(),
Shinya Kitaoka 120a6e
                                m_selective, m_filled, TConsts::infiniteRectD,
Shinya Kitaoka 120a6e
                                m_doAntialias);
Shinya Kitaoka 120a6e
  ToolUtils::updateSaveBox();
Shinya Kitaoka 120a6e
  TTool::getApplication()->getCurrentXsheet()->notifyXsheetChanged();
Shinya Kitaoka 120a6e
  notifyImageChanged();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int ToolUtils::UndoRasterPencil::getSize() const {
Shinya Kitaoka 120a6e
  return TRasterUndo::getSize() +
Shinya Kitaoka 120a6e
         m_stroke->getControlPointCount() * sizeof(TThickPoint) + 100 +
Shinya Kitaoka 120a6e
         sizeof(this);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
ToolUtils::UndoFullColorPencil::UndoFullColorPencil(
Shinya Kitaoka 120a6e
    TXshSimpleLevel *level, const TFrameId &frameId, TStroke *stroke,
Shinya Kitaoka 120a6e
    double opacity, bool doAntialias, bool createdFrame, bool createdLevel)
Shinya Kitaoka 120a6e
    : TFullColorRasterUndo(0, level, frameId, createdFrame, createdLevel, 0)
Shinya Kitaoka 120a6e
    , m_opacity(opacity)
Shinya Kitaoka 120a6e
    , m_doAntialias(doAntialias) {
Shinya Kitaoka 120a6e
  TRasterP raster = getImage()->getRaster();
Shinya Kitaoka 120a6e
  TDimension d    = raster->getSize();
Shinya Kitaoka 120a6e
  m_tiles         = new TTileSetFullColor(d);
Shinya Kitaoka 120a6e
  TRect rect =
Shinya Kitaoka 120a6e
      convert(stroke->getBBox()) + TPoint((int)(d.lx * 0.5), (int)(d.ly * 0.5));
Shinya Kitaoka 120a6e
  m_tiles->add(raster, rect.enlarge(2));
Shinya Kitaoka 120a6e
  m_stroke = new TStroke(*stroke);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
ToolUtils::UndoFullColorPencil::~UndoFullColorPencil() { delete m_stroke; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void ToolUtils::UndoFullColorPencil::redo() const {
Shinya Kitaoka 120a6e
  insertLevelAndFrameIfNeeded();
Shinya Kitaoka 120a6e
  TRasterImageP image = getImage();
Shinya Kitaoka 120a6e
  if (!image) return;
Shinya Kitaoka 120a6e
  TRasterImageUtils::addStroke(image, m_stroke, TRectD(), m_opacity,
Shinya Kitaoka 120a6e
                               m_doAntialias);
Shinya Kitaoka 120a6e
  TTool::getApplication()->getCurrentXsheet()->notifyXsheetChanged();
Shinya Kitaoka 120a6e
  notifyImageChanged();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int ToolUtils::UndoFullColorPencil::getSize() const {
Shinya Kitaoka 120a6e
  return TFullColorRasterUndo::getSize() +
Shinya Kitaoka 120a6e
         m_stroke->getControlPointCount() * sizeof(TThickPoint) + 100 +
Shinya Kitaoka 120a6e
         sizeof(this);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// undo class (path strokes). call it BEFORE and register it AFTER path change
Toshihiro Shimizu 890ddd
//
Shinya Kitaoka 120a6e
ToolUtils::UndoPath::UndoPath(TStageObjectSpline *spline) : m_spline(spline) {
Shinya Kitaoka 120a6e
  assert(!!m_spline);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  const TStroke *stroke = m_spline->getStroke();
Shinya Kitaoka 120a6e
  assert(stroke);
Shinya Kitaoka 120a6e
  int n = stroke->getControlPointCount();
Shinya Kitaoka 120a6e
  for (int i = 0; i < n; i++) m_before.push_back(stroke->getControlPoint(i));
Shinya Kitaoka 120a6e
  m_selfLoopBefore = stroke->isSelfLoop();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
ToolUtils::UndoPath::~UndoPath() {}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void ToolUtils::UndoPath::onAdd() {
Shinya Kitaoka 120a6e
  assert(!!m_spline);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  const TStroke *stroke = m_spline->getStroke();
Shinya Kitaoka 120a6e
  assert(stroke);
Shinya Kitaoka 120a6e
  int n = stroke->getControlPointCount();
Shinya Kitaoka 120a6e
  for (int i = 0; i < n; i++) m_after.push_back(stroke->getControlPoint(i));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void ToolUtils::UndoPath::undo() const {
Shinya Kitaoka 120a6e
  assert(!!m_spline);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TTool::Application *app = TTool::getApplication();
Shinya Kitaoka 120a6e
  TSelection *selection   = app->getCurrentSelection()->getSelection();
Shinya Kitaoka 120a6e
  if (selection) selection->selectNone();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TStroke *stroke = new TStroke(*m_spline->getStroke());
Shinya Kitaoka 120a6e
  stroke->reshape(&m_before[0], m_before.size());
Shinya Kitaoka 120a6e
  stroke->setSelfLoop(m_selfLoopBefore);
Shinya Kitaoka 120a6e
  m_spline->setStroke(stroke);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (!app->getCurrentObject()->isSpline()) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TStageObjectId currentObjectId = app->getCurrentObject()->getObjectId();
Shinya Kitaoka 120a6e
  TStageObject *stageObject =
Shinya Kitaoka 120a6e
      app->getCurrentXsheet()->getXsheet()->getStageObject(currentObjectId);
Shinya Kitaoka 120a6e
  if (stageObject->getSpline()->getId() == m_spline->getId())
Shinya Kitaoka 120a6e
    app->getCurrentObject()->setSplineObject(m_spline);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  app->getCurrentTool()->getTool()->notifyImageChanged();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void ToolUtils::UndoPath::redo() const {
Shinya Kitaoka 120a6e
  assert(!!m_spline);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TTool::Application *app = TTool::getApplication();
Shinya Kitaoka 120a6e
  TSelection *selection   = app->getCurrentSelection()->getSelection();
Shinya Kitaoka 120a6e
  if (selection) selection->selectNone();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TStroke *stroke = new TStroke(*m_spline->getStroke());
Shinya Kitaoka 120a6e
  stroke->reshape(&m_after[0], m_after.size());
Shinya Kitaoka 120a6e
  stroke->setSelfLoop(m_selfLoopBefore);
Shinya Kitaoka 120a6e
  m_spline->setStroke(stroke);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (!app->getCurrentObject()->isSpline()) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TStageObjectId currentObjectId = app->getCurrentObject()->getObjectId();
Shinya Kitaoka 120a6e
  TStageObject *stageObject =
Shinya Kitaoka 120a6e
      app->getCurrentXsheet()->getXsheet()->getStageObject(currentObjectId);
Shinya Kitaoka 120a6e
  if (stageObject->getSpline()->getId() == m_spline->getId())
Shinya Kitaoka 120a6e
    app->getCurrentObject()->setSplineObject(m_spline);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  app->getCurrentTool()->getTool()->notifyImageChanged();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int ToolUtils::UndoPath::getSize() const { return sizeof(*this) + 500; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// UndoControlPointEditor
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
ToolUtils::UndoControlPointEditor::UndoControlPointEditor(
Shinya Kitaoka 120a6e
    TXshSimpleLevel *level, const TFrameId &frameId)
Shinya Kitaoka 120a6e
    : TToolUndo(level, frameId), m_isStrokeDelete(false) {
Shinya Kitaoka 120a6e
  TVectorImageP image = level->getFrame(frameId, true);
Shinya Kitaoka 120a6e
  assert(image);
Shinya Kitaoka 120a6e
  if (!image) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TTool::Application *app = TTool::getApplication();
Shinya Kitaoka 120a6e
  if (!app) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_row    = app->getCurrentFrame()->getFrame();
Shinya Kitaoka 120a6e
  m_column = app->getCurrentColumn()->getColumnIndex();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
ToolUtils::UndoControlPointEditor::~UndoControlPointEditor() {
Shinya Kitaoka 120a6e
  deleteVIStroke(m_oldStroke.second);
Shinya Kitaoka 120a6e
  if (!m_isStrokeDelete) deleteVIStroke(m_newStroke.second);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void ToolUtils::UndoControlPointEditor::onAdd() {
Shinya Kitaoka 120a6e
  TVectorImageP image = m_level->getFrame(m_frameId, true);
Shinya Kitaoka 120a6e
  assert(image);
Shinya Kitaoka 120a6e
  if (!image) return;
Shinya Kitaoka 120a6e
  QMutexLocker lock(image->getMutex());
Shinya Kitaoka 120a6e
  if (m_isStrokeDelete) return;
Shinya Kitaoka 120a6e
  addNewStroke(m_oldStroke.first, image->getVIStroke(m_oldStroke.first));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void ToolUtils::UndoControlPointEditor::addOldStroke(int index, VIStroke *vs) {
Shinya Kitaoka 120a6e
  VIStroke *s = cloneVIStroke(vs);
Shinya Kitaoka 120a6e
  m_oldStroke = std::make_pair(index, s);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void ToolUtils::UndoControlPointEditor::addNewStroke(int index, VIStroke *vs) {
Shinya Kitaoka 120a6e
  VIStroke *s = cloneVIStroke(vs);
Shinya Kitaoka 120a6e
  m_newStroke = std::make_pair(index, s);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void ToolUtils::UndoControlPointEditor::undo() const {
Shinya Kitaoka 120a6e
  TTool::Application *app = TTool::getApplication();
Shinya Kitaoka 120a6e
  if (!app) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (app->getCurrentFrame()->isEditingScene()) {
Shinya Kitaoka 120a6e
    app->getCurrentColumn()->setColumnIndex(m_column);
Shinya Kitaoka 120a6e
    app->getCurrentFrame()->setFrame(m_row);
Shinya Kitaoka 120a6e
  } else
Shinya Kitaoka 120a6e
    app->getCurrentFrame()->setFid(m_frameId);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TSelection *selection = app->getCurrentSelection()->getSelection();
Shinya Kitaoka 120a6e
  if (selection) selection->selectNone();
Shinya Kitaoka 120a6e
  TVectorImageP image = m_level->getFrame(m_frameId, true);
Shinya Kitaoka 120a6e
  assert(image);
Shinya Kitaoka 120a6e
  if (!image) return;
Shinya Kitaoka 120a6e
  QMutexLocker lock(image->getMutex());
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (!m_isStrokeDelete) image->removeStroke(m_newStroke.first, false);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  UINT i      = 0;
Shinya Kitaoka 120a6e
  VIStroke *s = cloneVIStroke(m_oldStroke.second);
Shinya Kitaoka 120a6e
  image->insertStrokeAt(s, m_oldStroke.first);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (image->isComputedRegionAlmostOnce())
Shinya Kitaoka 120a6e
    image->findRegions();  // in futuro togliere. Serve perche' la
Shinya Kitaoka 120a6e
                           // removeStrokes, se gli si dice
Shinya Kitaoka 120a6e
  // di non calcolare le regioni, e' piu' veloce ma poi chrash tutto
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  app->getCurrentXsheet()->notifyXsheetChanged();
Shinya Kitaoka 120a6e
  notifyImageChanged();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void ToolUtils::UndoControlPointEditor::redo() const {
Shinya Kitaoka 120a6e
  TTool::Application *app = TTool::getApplication();
Shinya Kitaoka 120a6e
  if (!app) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (app->getCurrentFrame()->isEditingScene()) {
Shinya Kitaoka 120a6e
    app->getCurrentColumn()->setColumnIndex(m_column);
Shinya Kitaoka 120a6e
    app->getCurrentFrame()->setFrame(m_row);
Shinya Kitaoka 120a6e
  } else
Shinya Kitaoka 120a6e
    app->getCurrentFrame()->setFid(m_frameId);
Shinya Kitaoka 120a6e
  TSelection *selection = app->getCurrentSelection()->getSelection();
Shinya Kitaoka 120a6e
  if (selection) selection->selectNone();
Shinya Kitaoka 120a6e
  TVectorImageP image = m_level->getFrame(m_frameId, true);
Shinya Kitaoka 120a6e
  assert(image);
Shinya Kitaoka 120a6e
  if (!image) return;
Shinya Kitaoka 120a6e
  QMutexLocker lock(image->getMutex());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  image->removeStroke(m_oldStroke.first, false);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (!m_isStrokeDelete) {
Shinya Kitaoka 120a6e
    VIStroke *s = cloneVIStroke(m_newStroke.second);
Shinya Kitaoka 120a6e
    image->insertStrokeAt(s, m_newStroke.first);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (image->isComputedRegionAlmostOnce())
Shinya Kitaoka 120a6e
    image->findRegions();  // in futuro togliere. Serve perche' la
Shinya Kitaoka 120a6e
                           // removeStrokes, se gli si dice
Shinya Kitaoka 120a6e
  // di non calcolare le regioni, e' piu' veloce ma poi chrash tutto
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  app->getCurrentXsheet()->notifyXsheetChanged();
Shinya Kitaoka 120a6e
  notifyImageChanged();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// Menu
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
ToolUtils::DragMenu::DragMenu() : QMenu() {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
QAction *ToolUtils::DragMenu::exec(const QPoint &p, QAction *action) {
Shinya Kitaoka 120a6e
  QAction *execAct = QMenu::exec(p, action);
Shinya Kitaoka 120a6e
  if (execAct) return execAct;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return defaultAction();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void ToolUtils::DragMenu::mouseReleaseEvent(QMouseEvent *e) {
Shinya Kitaoka 120a6e
  QMenu::mouseReleaseEvent(e);
Shinya Kitaoka 120a6e
  hide();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// ColumChooserMenu
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
ToolUtils::ColumChooserMenu::ColumChooserMenu(
Shinya Kitaoka 120a6e
    TXsheet *xsh, const std::vector<int> &columnIndexes)</int>
Shinya Kitaoka 120a6e
    : DragMenu() {
Shinya Kitaoka 120a6e
  int size = columnIndexes.size();
Shinya Kitaoka 120a6e
  int i;
Shinya Kitaoka 120a6e
  for (i = size - 1; i >= 0; i--) {
Shinya Kitaoka 120a6e
    int index                 = columnIndexes[i];
Shinya Kitaoka 120a6e
    TStageObjectId id         = TStageObjectId::ColumnId(index);
Shinya Kitaoka 120a6e
    TStageObject *stageObject = xsh->getStageObject(id);
Shinya Kitaoka 120a6e
    QString cmdStr = "Column " + QString::fromStdString(stageObject->getName());
Shinya Kitaoka 120a6e
    QAction *act   = new QAction(cmdStr, this);
Shinya Kitaoka 120a6e
    act->setData(index);
Shinya Kitaoka 120a6e
    addAction(act);
Shinya Kitaoka 120a6e
    if (size - 1 == i) {
Shinya Kitaoka 120a6e
      setDefaultAction(act);
Shinya Kitaoka 120a6e
      setActiveAction(act);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int ToolUtils::ColumChooserMenu::execute() {
Shinya Kitaoka 120a6e
  QAction *executeAct = exec(QCursor::pos());
Shinya Kitaoka 120a6e
  return (!executeAct) ? -1 : executeAct->data().toInt();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
double ToolUtils::ConeSubVolume::compute(double cover) {
Shinya Kitaoka 120a6e
  double x = (10 * tcrop(cover, -1.0, 1.0)) + 10;
Shinya Kitaoka 120a6e
  assert(0 <= x && x <= 20);
Shinya Kitaoka 120a6e
  int i = tfloor(x);
Shinya Kitaoka 120a6e
  if (i == 20)
Shinya Kitaoka 120a6e
    return m_values[i];
Shinya Kitaoka 120a6e
  else
luz paz 266edb
    // Linear interpolation.
Shinya Kitaoka 120a6e
    return (-(x - (i + 1)) * m_values[i]) - (-(x - i) * m_values[i + 1]);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
const double ToolUtils::ConeSubVolume::m_values[] = {
Shinya Kitaoka 120a6e
    1.0,      0.99778,  0.987779,  0.967282,  0.934874,  0.889929,   0.832457,
Shinya Kitaoka 120a6e
    0.763067, 0.683002, 0.594266,  0.5,       0.405734,  0.316998,   0.236933,
Shinya Kitaoka 120a6e
    0.167543, 0.110071, 0.0651259, 0.0327182, 0.0122208, 0.00221986, 0.0};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void ToolUtils::drawBalloon(const TPointD &pos, std::string text,
shun_iwasawa 1fbdc9
                            const TPixel32 &color, TPoint delta,
shun_iwasawa 1fbdc9
                            double pixelSize, bool isPicking,
Shinya Kitaoka 120a6e
                            std::vector<trectd> *otherBalloons) {</trectd>
shun-iwasawa f2e168
  TTool::Viewer *viewer =
shun-iwasawa f2e168
      TTool::getApplication()->getCurrentTool()->getTool()->getViewer();
shun-iwasawa f2e168
  int devPixRatio = getDevicePixelRatio(viewer->viewerWidget());
shun-iwasawa 78454d
  QString qText   = QString::fromStdString(text);
shun_iwasawa 1fbdc9
  QFont font("Arial");  // ,QFont::Bold);
shun-iwasawa 78454d
  font.setPixelSize(13 * devPixRatio);
Shinya Kitaoka 120a6e
  QFontMetrics fm(font);
Shinya Kitaoka 120a6e
  QRect textRect = fm.boundingRect(qText);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int baseLine = -textRect.top();
shun-iwasawa 78454d
  int mrg      = 3 * devPixRatio;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // avoid other balloons
Shinya Kitaoka 120a6e
  if (otherBalloons) {
shun-iwasawa 78454d
    QRect tmpTextRect = textRect;
shun-iwasawa 78454d
    int tmpMrg        = mrg;
shun-iwasawa 78454d
    // for high dpi monitors
shun-iwasawa 78454d
    if (devPixRatio != 1) {
shun-iwasawa 78454d
      QFont tmpFont = font;
shun-iwasawa 78454d
      tmpFont.setPixelSize(13);
shun-iwasawa 78454d
      QFontMetrics tmpFm(tmpFont);
shun-iwasawa 78454d
      tmpTextRect = tmpFm.boundingRect(qText);
shun-iwasawa 78454d
      tmpMrg      = 3;
shun-iwasawa 78454d
    }
shun-iwasawa 78454d
Shinya Kitaoka 120a6e
    std::vector<trectd> &balloons = *otherBalloons;</trectd>
Shinya Kitaoka 120a6e
    int n                         = (int)balloons.size();
shun-iwasawa 78454d
    TDimensionD balloonSize(pixelSize * (tmpTextRect.width() + tmpMrg * 2),
shun-iwasawa 78454d
                            pixelSize * (tmpTextRect.height() + tmpMrg * 2));
Shinya Kitaoka 120a6e
    TRectD balloonRect;
Shinya Kitaoka 120a6e
    for (;;) {
Shinya Kitaoka 120a6e
      balloonRect = TRectD(
Shinya Kitaoka 120a6e
          pos + TPointD(delta.x * pixelSize, delta.y * pixelSize), balloonSize);
Shinya Kitaoka 120a6e
      int i = 0;
Shinya Kitaoka 120a6e
      while (i < n && !balloons[i].overlaps(balloonRect)) i++;
Shinya Kitaoka 120a6e
      if (i == n) break;
shun-iwasawa 78454d
      double y = balloons[i].y0 - balloonSize.ly - 2 * tmpMrg * pixelSize;
Shinya Kitaoka 120a6e
      delta.y  = (y - pos.y) / pixelSize;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    balloons.push_back(balloonRect);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
shun-iwasawa 78454d
  delta.x *= devPixRatio;
shun-iwasawa 78454d
  delta.y *= devPixRatio;
shun-iwasawa 78454d
shun-iwasawa a0d489
  textRect.moveTo(std::max(delta.x, 10 * devPixRatio + mrg),
shun-iwasawa a0d489
                  std::max(mrg + 2 * devPixRatio, -delta.y - baseLine));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int y  = textRect.top() + baseLine;
Shinya Kitaoka 120a6e
  int x0 = textRect.left() - mrg;
Shinya Kitaoka 120a6e
  int x1 = textRect.right() + mrg;
Shinya Kitaoka 120a6e
  int y0 = textRect.top() - mrg;
Shinya Kitaoka 120a6e
  int y1 = textRect.bottom() + mrg;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (isPicking) {
Shinya Kitaoka 120a6e
    if (viewer->is3DView()) {
Shinya Kitaoka 120a6e
      double x0 = pos.x + textRect.left() * pixelSize,
Shinya Kitaoka 120a6e
             y0 = pos.y + delta.y * pixelSize;
Shinya Kitaoka 120a6e
      double x1 = x0 + pixelSize * textRect.width();
Shinya Kitaoka 120a6e
      double y1 = y0 + pixelSize * textRect.height();
Shinya Kitaoka 120a6e
      double d  = pixelSize * 5;
Shinya Kitaoka 120a6e
      glRectd(x0 - d, y0 - d, x1 + d, y1 + d);
Shinya Kitaoka 120a6e
    } else {
shun_iwasawa bc352c
      TPointD posBalloon = viewer->worldToPos(pos);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      double d  = 5;
Shinya Kitaoka 120a6e
      double x0 = posBalloon.x + textRect.left() - d;
Shinya Kitaoka 120a6e
      double y0 = posBalloon.y + delta.y - d;
Shinya Kitaoka 120a6e
      double x1 = x0 + textRect.width() + d;
Shinya Kitaoka 120a6e
      double y1 = y0 + textRect.height() + d;
Shinya Kitaoka 120a6e
shun_iwasawa bc352c
      TPointD p1(x0, y0);
shun_iwasawa bc352c
      TPointD p2(x1, y0);
shun_iwasawa bc352c
      TPointD p3(x0, y1);
shun_iwasawa bc352c
      TPointD p4(x1, y1);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      TPointD w1(viewer->winToWorld(p1));
Shinya Kitaoka 120a6e
      TPointD w2(viewer->winToWorld(p2));
Shinya Kitaoka 120a6e
      TPointD w3(viewer->winToWorld(p3));
Shinya Kitaoka 120a6e
      TPointD w4(viewer->winToWorld(p4));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      glBegin(GL_QUADS);
Shinya Kitaoka 120a6e
      glVertex2d(w1.x, w1.y);
Shinya Kitaoka 120a6e
      glVertex2d(w2.x, w2.y);
Shinya Kitaoka 120a6e
      glVertex2d(w4.x, w4.y);
Shinya Kitaoka 120a6e
      glVertex2d(w3.x, w3.y);
Shinya Kitaoka 120a6e
      glEnd();
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  QSize size(textRect.width() + textRect.left() + mrg,
shun-iwasawa a0d489
             std::max(textRect.bottom() + mrg, y + delta.y) + 3 * devPixRatio);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  QImage label(size.width(), size.height(), QImage::Format_ARGB32);
Shinya Kitaoka 120a6e
  label.fill(Qt::transparent);
Shinya Kitaoka 120a6e
  // label.fill(qRgba(200,200,0,200));
Shinya Kitaoka 120a6e
  QPainter p(&label);
Shinya Kitaoka 120a6e
  p.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
Shinya Kitaoka 120a6e
  p.setBrush(QColor(color.r, color.g, color.b, color.m));
Shinya Kitaoka 120a6e
  p.setPen(Qt::NoPen);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  QPainterPath pp;
shun-iwasawa 78454d
  pp.moveTo(x0, y - 8 * devPixRatio);
Shinya Kitaoka 120a6e
  pp.lineTo(0, y + delta.y);
Shinya Kitaoka 120a6e
  pp.lineTo(x0, y);
luz paz e59b53
  /* rounded edges
shun-iwasawa 78454d
  int arcSize = 10;
shun-iwasawa 78454d
  pp.arcTo(x0,y1-arcSize,arcSize,arcSize,180,90);
shun-iwasawa 78454d
  pp.arcTo(x1-arcSize,y1-arcSize,arcSize,arcSize,270,90);
shun-iwasawa 78454d
  pp.arcTo(x1-arcSize,y0,arcSize,arcSize,0,90);
shun-iwasawa 78454d
  pp.arcTo(x0,y0,arcSize,arcSize,90,90);
shun-iwasawa 78454d
  */
luz paz 266edb
  // sharp edges
Shinya Kitaoka 120a6e
  pp.lineTo(x0, y1);
Shinya Kitaoka 120a6e
  pp.lineTo(x1, y1);
Shinya Kitaoka 120a6e
  pp.lineTo(x1, y0);
Shinya Kitaoka 120a6e
  pp.lineTo(x0, y0);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  pp.closeSubpath();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  p.drawPath(pp);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  p.setPen(Qt::black);
Shinya Kitaoka 120a6e
  p.setFont(font);
Shinya Kitaoka 120a6e
  p.drawText(textRect, Qt::AlignCenter | Qt::TextDontClip, qText);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  QImage texture = QGLWidget::convertToGLFormat(label);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  glRasterPos2f(pos.x, pos.y);
Shinya Kitaoka 120a6e
  glBitmap(0, 0, 0, 0, 0, -size.height() + (y + delta.y), NULL);  //
Shinya Kitaoka 120a6e
  glEnable(GL_BLEND);
Shinya Kitaoka 120a6e
  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
Shinya Kitaoka 120a6e
  glDrawPixels(texture.width(), texture.height(), GL_RGBA, GL_UNSIGNED_BYTE,
Shinya Kitaoka 120a6e
               texture.bits());
Shinya Kitaoka 120a6e
  glDisable(GL_BLEND);
Shinya Kitaoka 120a6e
  glColor3d(0, 0, 0);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void ToolUtils::drawHook(const TPointD &pos, ToolUtils::HookType type,
Shinya Kitaoka 120a6e
                         bool highlighted, bool onionSkin) {
shun-iwasawa f2e168
  TTool::Viewer *viewer =
shun-iwasawa f2e168
      TTool::getApplication()->getCurrentTool()->getTool()->getViewer();
shun-iwasawa f2e168
  int devPixRatio = getDevicePixelRatio(viewer->viewerWidget());
Shinya Kitaoka 120a6e
  int r = 10, d = r + r;
shun-iwasawa 78454d
  QImage image(d * devPixRatio, d * devPixRatio, QImage::Format_ARGB32);
Shinya Kitaoka 120a6e
  image.fill(Qt::transparent);
Shinya Kitaoka 120a6e
  // image.fill(qRgba(200,200,0,200));
Shinya Kitaoka 120a6e
  QPainter painter(&image);
shun-iwasawa 78454d
  painter.scale(devPixRatio, devPixRatio);
Shinya Kitaoka 120a6e
  // painter.setRenderHints(QPainter::Antialiasing|QPainter::TextAntialiasing);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int matte = onionSkin ? 100 : 255;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  QColor color(0, 0, 0, matte);
Shinya Kitaoka 120a6e
  if (highlighted) color = QColor(0, 175, 175, matte);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (type == NormalHook || type == PassHookA) {
Shinya Kitaoka 120a6e
    painter.setPen(QPen(QColor(255, 255, 255, matte), 3));
Shinya Kitaoka 120a6e
    painter.drawEllipse(5, 5, d - 10, d - 10);
Shinya Kitaoka 120a6e
    painter.setPen(color);
Shinya Kitaoka 120a6e
    painter.drawEllipse(5, 5, d - 10, d - 10);
Shinya Kitaoka 120a6e
  } else if (type == OtherLevelHook) {
Shinya Kitaoka 120a6e
    QColor color(0, 200, 200, 200);
Shinya Kitaoka 120a6e
    // painter.setPen(QPen(Qt::white,3));
Shinya Kitaoka 120a6e
    // painter.drawEllipse(5,5,d-10,d-10);
Shinya Kitaoka 120a6e
    painter.setPen(Qt::white);
Shinya Kitaoka 120a6e
    painter.setBrush(color);
Shinya Kitaoka 120a6e
    painter.drawEllipse(6, 6, d - 12, d - 12);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (type == NormalHook || type == PassHookB) {
Shinya Kitaoka 120a6e
    painter.setPen(QPen(QColor(255, 255, 255, matte), 3));
Shinya Kitaoka 120a6e
    painter.drawLine(0, r, d, r);
Shinya Kitaoka 120a6e
    painter.drawLine(r, 0, r, d);
Shinya Kitaoka 120a6e
    painter.setPen(color);
Shinya Kitaoka 120a6e
    painter.drawLine(0, r, d, r);
Shinya Kitaoka 120a6e
    painter.drawLine(r, 0, r, d);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  QImage texture = QGLWidget::convertToGLFormat(image);
Shinya Kitaoka 120a6e
  glRasterPos2f(pos.x, pos.y);
shun-iwasawa 78454d
  glBitmap(0, 0, 0, 0, -r * devPixRatio, -r * devPixRatio, NULL);
Shinya Kitaoka 120a6e
  glEnable(GL_BLEND);
Shinya Kitaoka 120a6e
  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
Shinya Kitaoka 120a6e
  glDrawPixels(texture.width(), texture.height(), GL_RGBA, GL_UNSIGNED_BYTE,
Shinya Kitaoka 120a6e
               texture.bits());
Shinya Kitaoka 120a6e
  glDisable(GL_BLEND);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool ToolUtils::isJustCreatedSpline(TImage *image) {
Shinya Kitaoka 120a6e
  TVectorImageP vi = image;
Shinya Kitaoka 120a6e
  if (!vi) return false;
Shinya Kitaoka 120a6e
  if (vi->getStrokeCount() != 1) return false;
Shinya Kitaoka 120a6e
  TStroke *stroke = vi->getStroke(0);
Shinya Kitaoka 120a6e
  if (stroke->getControlPointCount() != 3) return false;
Shinya Kitaoka 120a6e
  TPointD p0 = stroke->getControlPoint(0);
Shinya Kitaoka 120a6e
  TPointD p1 = stroke->getControlPoint(1);
Shinya Kitaoka 120a6e
  TPointD p2 = stroke->getControlPoint(2);
Shinya Kitaoka 120a6e
  double d   = 30.0;
Shinya Kitaoka 120a6e
  return p0 == TPointD(-d, 0) && p1 == TPointD(0, 0) && p2 == TPointD(d, 0);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TRectD ToolUtils::interpolateRect(const TRectD &rect1, const TRectD &rect2,
Shinya Kitaoka 120a6e
                                  double t) {
Shinya Kitaoka 120a6e
  assert(rect1.x0 <= rect1.x1);
Shinya Kitaoka 120a6e
  assert(rect1.y0 <= rect1.y1);
Shinya Kitaoka 120a6e
  assert(rect2.x0 <= rect2.x1);
Shinya Kitaoka 120a6e
  assert(rect2.y0 <= rect2.y1);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return TRectD(rect1.x0 + (rect2.x0 - rect1.x0) * t,
Shinya Kitaoka 120a6e
                rect1.y0 + (rect2.y0 - rect1.y0) * t,
Shinya Kitaoka 120a6e
                rect1.x1 + (rect2.x1 - rect1.x1) * t,
Shinya Kitaoka 120a6e
                rect1.y1 + (rect2.y1 - rect1.y1) * t);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
/*
Shinya Kitaoka 3bfa54
bool ToolUtils::isASubRegion(int reg, const std::vector<tregion*> ®ions)</tregion*>
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
        TRegion *region=regions[reg];
Shinya Kitaoka 120a6e
        for (int i=0; i<(int)regions.size(); i++)
Shinya Kitaoka 120a6e
        {
Shinya Kitaoka 120a6e
                if(i!=reg)
Shinya Kitaoka 120a6e
                        if(region->isSubRegionOf(*regions[i]))
Shinya Kitaoka 120a6e
                                return true;
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
        return false;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TRectD ToolUtils::getBounds(const std::vector<tthickpoint> &points,</tthickpoint>
Shinya Kitaoka 120a6e
                            double maxThickness) {
Shinya Kitaoka 120a6e
  TThickPoint p = points[0];
Shinya Kitaoka 120a6e
  double radius = maxThickness == 0 ? p.thick * 0.5 : maxThickness * 0.5;
Shinya Kitaoka 120a6e
  TRectD rect(p - TPointD(radius, radius), p + TPointD(radius, radius));
Shinya Kitaoka 120a6e
  int i;
Shinya Kitaoka 120a6e
  for (i = 1; i < (int)points.size(); i++) {
Shinya Kitaoka 120a6e
    p      = points[i];
Shinya Kitaoka 120a6e
    radius = maxThickness == 0 ? p.thick * 0.5 : maxThickness * 0.5;
Shinya Kitaoka 120a6e
    rect =
Shinya Kitaoka 120a6e
        rect + TRectD(p - TPointD(radius, radius), p + TPointD(radius, radius));
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return rect;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
/*
Toshihiro Shimizu 890ddd
template <typename pixel=""></typename>
Toshihiro Shimizu 890ddd
TRasterPT<pixel> ToolUtils::rotate90(const TRasterPT<pixel> &ras, bool toRight)</pixel></pixel>
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
        if(!ras)
Shinya Kitaoka 120a6e
                return 0;
Shinya Kitaoka 120a6e
        int lx=ras->getLy();
Shinya Kitaoka 120a6e
        int ly=ras->getLx();
Shinya Kitaoka 120a6e
        TRasterPT<pixel> workRas(lx,ly);</pixel>
Shinya Kitaoka 120a6e
        for (int i=0; i<ras->getLx(); i++)</ras->
Shinya Kitaoka 120a6e
        {
Shinya Kitaoka 120a6e
                for (int j=0; j<ras->getLy(); j++)</ras->
Shinya Kitaoka 120a6e
                {
Shinya Kitaoka 120a6e
                        if(toRight)
Shinya Kitaoka 120a6e
                                workRas->pixels(ly-1-i)[j]=ras->pixels(j)[i];
Shinya Kitaoka 120a6e
                        else
Shinya Kitaoka 120a6e
                                workRas->pixels(i)[lx-1-j]=ras->pixels(j)[i];
Shinya Kitaoka 120a6e
                }
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
        return workRas;
Toshihiro Shimizu 890ddd
}*/
shun-iwasawa 536025
shun-iwasawa 536025
//-----------------------------------------------------------------------------
shun-iwasawa 536025
shun-iwasawa 536025
bool ToolUtils::doUpdateXSheet(TXshSimpleLevel *sl,
shun-iwasawa 536025
                               std::vector<tframeid> oldFids,</tframeid>
shun-iwasawa 536025
                               std::vector<tframeid> newFids, TXsheet *xsh,</tframeid>
shun-iwasawa 536025
                               std::vector<txshchildlevel *=""> &childLevels) {</txshchildlevel>
shun-iwasawa 536025
  bool ret = false;
shun-iwasawa 536025
  for (int c = 0; c < xsh->getColumnCount(); ++c) {
shun-iwasawa 536025
    int r0, r1;
shun-iwasawa 536025
    int n = xsh->getCellRange(c, r0, r1);
shun-iwasawa 536025
    if (n > 0) {
shun-iwasawa 536025
      bool changed = false;
shun-iwasawa 536025
      std::vector<txshcell> cells(n);</txshcell>
shun-iwasawa 536025
      xsh->getCells(r0, c, n, &cells[0]);
shun-iwasawa 536025
      for (int i = 0; i < n; i++) {
shun-iwasawa 536025
        TXshCell currCell = cells[i];
shun-iwasawa 536025
        // check the sub xsheets too
shun-iwasawa 536025
        if (!cells[i].isEmpty() &&
shun-iwasawa 536025
            cells[i].m_level->getType() == CHILD_XSHLEVEL) {
shun-iwasawa 536025
          TXshChildLevel *level = cells[i].m_level->getChildLevel();
shun-iwasawa 536025
          // make sure we haven't already checked the level
shun-iwasawa 536025
          if (level && std::find(childLevels.begin(), childLevels.end(),
shun-iwasawa 536025
                                 level) == childLevels.end()) {
shun-iwasawa 536025
            childLevels.push_back(level);
shun-iwasawa 536025
            TXsheet *subXsh = level->getXsheet();
shun-iwasawa 536025
            ret |= doUpdateXSheet(sl, oldFids, newFids, subXsh, childLevels);
shun-iwasawa 536025
          }
shun-iwasawa 536025
        }
shun-iwasawa 536025
        for (int j = 0; j < oldFids.size(); j++) {
shun-iwasawa 536025
          if (oldFids.at(j) == newFids.at(j)) continue;
shun-iwasawa 536025
          TXshCell tempCell(sl, oldFids.at(j));
shun-iwasawa 536025
          bool sameSl  = tempCell.getSimpleLevel() == currCell.getSimpleLevel();
shun-iwasawa 536025
          bool sameFid = tempCell.getFrameId() == currCell.getFrameId();
shun-iwasawa 536025
          if (sameSl && sameFid) {
shun-iwasawa 536025
            TXshCell newCell(sl, newFids.at(j));
shun-iwasawa 536025
            cells[i] = newCell;
shun-iwasawa 536025
            changed  = true;
shun-iwasawa 536025
            break;
shun-iwasawa 536025
          }
shun-iwasawa 536025
        }
shun-iwasawa 536025
      }
shun-iwasawa 536025
      if (changed) {
shun-iwasawa 536025
        xsh->setCells(r0, c, n, &cells[0]);
shun-iwasawa 536025
        ret = true;
shun-iwasawa 536025
        // TApp::instance()->getCurrentXsheet()->notifyXsheetChanged();
shun-iwasawa 536025
      }
shun-iwasawa 536025
    }
shun-iwasawa 536025
  }
shun-iwasawa 536025
  return ret;
shun-iwasawa 536025
}
shun-iwasawa 536025
shun-iwasawa 536025
//-----------------------------------------------------------------------------
shun-iwasawa 536025
shun-iwasawa 536025
bool ToolUtils::renumberForInsertFId(TXshSimpleLevel *sl, const TFrameId &fid,
shun-iwasawa 536025
                                     const TFrameId &maxFid, TXsheet *xsh) {
shun-iwasawa ef0f8b
  auto getNextLetter = [](const QString &letter) {
shun-iwasawa ef0f8b
    if (letter.isEmpty()) return QString('a');
shun-iwasawa ef0f8b
    if (letter == 'z' || letter == 'Z') return QString();
shun-iwasawa ef0f8b
    QByteArray byteArray = letter.toUtf8();
shun-iwasawa ef0f8b
    // return incrementing the last letter
shun-iwasawa ef0f8b
    byteArray.data()[byteArray.size() - 1]++;
shun-iwasawa ef0f8b
    return QString::fromUtf8(byteArray);
shun-iwasawa ef0f8b
  };
shun-iwasawa ef0f8b
shun-iwasawa 536025
  std::vector<tframeid> fids;</tframeid>
shun-iwasawa 536025
  std::vector<tframeid> oldFrames;</tframeid>
shun-iwasawa 536025
  sl->getFids(oldFrames);
shun-iwasawa 536025
  sl->getFids(fids);
shun-iwasawa 536025
  std::vector<tframeid>::iterator it = std::find(fids.begin(), fids.end(), fid);</tframeid>
shun-iwasawa 536025
  if (it == fids.end()) return false;
shun-iwasawa 536025
shun-iwasawa 536025
  std::set<tframeid> fidsSet(fids.begin(), fids.end());</tframeid>
shun-iwasawa 536025
  QList<tframeid> fIdsToBeShifted;</tframeid>
shun-iwasawa 536025
  TFrameId tmpFid = fid;
shun-iwasawa 536025
  for (auto itr = fidsSet.upper_bound(maxFid); itr != fidsSet.end(); ++itr) {
shun-iwasawa 536025
    if (*itr > tmpFid) break;
shun-iwasawa 536025
    fIdsToBeShifted.push_back(*itr);
shun-iwasawa ef0f8b
    if (!fid.getLetter().isEmpty()) {
shun-iwasawa ef0f8b
      QString nextLetter = getNextLetter((*itr).getLetter());
shun-iwasawa ef0f8b
      if (!nextLetter.isEmpty())
shun-iwasawa ef0f8b
        tmpFid = TFrameId((*itr).getNumber(), nextLetter);
shun-iwasawa 536025
      else
shun-iwasawa 536025
        tmpFid = TFrameId((*itr).getNumber() + 1);
shun-iwasawa 536025
    } else
shun-iwasawa 536025
      tmpFid = TFrameId((*itr).getNumber() + 1, (*itr).getLetter());
shun-iwasawa 536025
  }
shun-iwasawa 536025
shun-iwasawa 536025
  if (fIdsToBeShifted.isEmpty()) return false;
shun-iwasawa 536025
shun-iwasawa 536025
  for (TFrameId &tmpFid : fids) {
shun-iwasawa 536025
    if (fIdsToBeShifted.contains(tmpFid)) {
shun-iwasawa ef0f8b
      if (!fid.getLetter().isEmpty()) {
shun-iwasawa ef0f8b
        QString nextLetter = getNextLetter(tmpFid.getLetter());
shun-iwasawa ef0f8b
        if (!nextLetter.isEmpty())
shun-iwasawa ef0f8b
          tmpFid = TFrameId(tmpFid.getNumber(), nextLetter);
shun-iwasawa 536025
        else
shun-iwasawa 536025
          tmpFid = TFrameId(tmpFid.getNumber() + 1);
shun-iwasawa 536025
      } else
shun-iwasawa 536025
        tmpFid = TFrameId(tmpFid.getNumber() + 1, tmpFid.getLetter());
shun-iwasawa 536025
    }
shun-iwasawa 536025
  }
shun-iwasawa 536025
shun-iwasawa 536025
  std::vector<txshchildlevel *=""> childLevels;</txshchildlevel>
shun-iwasawa 536025
  doUpdateXSheet(sl, oldFrames, fids, xsh, childLevels);
shun-iwasawa 536025
  sl->renumber(fids);
shun-iwasawa 536025
shun-iwasawa 536025
  return true;
shun-iwasawa 536025
}