示例#1
0
void FilmstripFrames::paintEvent(QPaintEvent *evt) {
  QPainter p(this);

  // p.setRenderHint(QPainter::Antialiasing, true);

  QRect clipRect = evt->rect();

  p.fillRect(clipRect, Qt::black);
  // thumbnail rect, including offsets
  QRect iconImgRect = QRect(QPoint(fs_leftMargin + fs_iconMarginLR,
                                   fs_frameSpacing / 2 + fs_iconMarginTop),
                            m_iconSize);
  // frame size with margins
  QSize frameSize = m_iconSize + QSize(fs_iconMarginLR * 2,
                                       fs_iconMarginTop + fs_iconMarginBottom);
  //  .. and with offset
  QRect frameRect =
      QRect(QPoint(fs_leftMargin, fs_frameSpacing / 2), frameSize);

  int oneFrameHeight = frameSize.height() + fs_frameSpacing;

  // visible frame index range
  int i0 = y2index(clipRect.top());
  int i1 = y2index(clipRect.bottom());

  // fids, frameCount <- frames del livello
  std::vector<TFrameId> fids;
  TXshSimpleLevel *sl = getLevel();
  if (sl)
    sl->getFids(fids);
  else {
    for (int i = i0; i <= i1; i++) {
      // draw white rectangles if obtaining the level is failed
      QRect iconRect = frameRect.translated(QPoint(0, oneFrameHeight * i));
      p.setBrush(QColor(192, 192, 192));
      p.setPen(Qt::NoPen);
      p.drawRect(iconRect);
    }
    return;
  }

  //--- compute navigator rect ---

  QRect naviRect;
  ComboViewerPanel *inknPaintViewerPanel =
      TApp::instance()->getInknPaintViewerPanel();
  if (sl->getType() == TZP_XSHLEVEL && inknPaintViewerPanel) {
    // show navigator only if the inknpaint viewer is visible
    if (inknPaintViewerPanel->isVisible()) {
      SceneViewer *viewer = inknPaintViewerPanel->getSceneViewer();
      // imgSize: image's pixel size
      QSize imgSize(sl->getProperties()->getImageRes().lx,
                    sl->getProperties()->getImageRes().ly);
      // Viewer affine
      TAffine viewerAff =
          inknPaintViewerPanel->getSceneViewer()->getViewMatrix();
      // pixel size which will be displayed with 100% scale in Viewer Stage
      TFrameId currentId = TApp::instance()->getCurrentFrame()->getFid();
      double imgPixelWidth =
          (double)(imgSize.width()) / sl->getDpi(currentId).x * Stage::inch;
      double imgPixelHeight =
          (double)(imgSize.height()) / sl->getDpi(currentId).y * Stage::inch;

      // get the image's corner positions in viewer matrix (with current zoom
      // scale)
      TPointD imgTopRight =
          viewerAff * TPointD(imgPixelWidth / 2.0f, imgPixelHeight / 2.0f);
      TPointD imgBottomLeft =
          viewerAff * TPointD(-imgPixelWidth / 2.0f, -imgPixelHeight / 2.0f);

      // pixel size in viewer matrix ( with current zoom scale )
      QSizeF imgSizeInViewer(imgTopRight.x - imgBottomLeft.x,
                             imgTopRight.y - imgBottomLeft.y);

      // ratio of the Viewer frame's position and size
      QRectF naviRatio(
          (-(float)viewer->width() * 0.5f - (float)imgBottomLeft.x) /
              imgSizeInViewer.width(),
          1.0f -
              ((float)viewer->height() * 0.5f - (float)imgBottomLeft.y) /
                  imgSizeInViewer.height(),
          (float)viewer->width() / imgSizeInViewer.width(),
          (float)viewer->height() / imgSizeInViewer.height());

      naviRect = QRect(iconImgRect.left() +
                           (int)(naviRatio.left() * (float)iconImgRect.width()),
                       iconImgRect.top() +
                           (int)(naviRatio.top() * (float)iconImgRect.height()),
                       (int)((float)iconImgRect.width() * naviRatio.width()),
                       (int)((float)iconImgRect.height() * naviRatio.height()));
      // for drag move
      m_naviRectPos = naviRect.center();

      naviRect = naviRect.intersected(frameRect);

      m_icon2ViewerRatio.setX(imgSizeInViewer.width() /
                              (float)iconImgRect.width());
      m_icon2ViewerRatio.setY(imgSizeInViewer.height() /
                              (float)iconImgRect.height());
    }
  }

  //--- compute navigator rect end ---

  int frameCount = (int)fids.size();

  std::set<TFrameId> editableFrameRange;

  if (sl) editableFrameRange = sl->getEditableRange();

  bool isReadOnly    = false;
  if (sl) isReadOnly = sl->isReadOnly();

  int i;
  int iconWidth   = m_iconSize.width();
  int x0          = m_frameLabelWidth;
  int x1          = x0 + iconWidth;
  int frameHeight = m_iconSize.height();

  // linee orizzontali che separano i frames
  p.setPen(getLightLineColor());
  for (i = i0; i <= i1; i++) {
    int y = index2y(i) + frameHeight;
    p.drawLine(0, y, x1, y);
  }

  TFilmstripSelection::InbetweenRange range = m_selection->getInbetweenRange();

  // draw for each frames
  for (i = i0; i <= i1; i++) {
    QRect tmp_iconImgRect =
        iconImgRect.translated(QPoint(0, oneFrameHeight * i));
    QRect tmp_frameRect = frameRect.translated(QPoint(0, oneFrameHeight * i));

    bool isCurrentFrame =
        (i == sl->fid2index(TApp::instance()->getCurrentFrame()->getFid()));
    bool isSelected =
        (0 <= i && i < frameCount && m_selection->isSelected(fids[i]));

    if (0 <= i && i < frameCount) {
      TFrameId fid = fids[i];

      // normal or inbetween (for vector levels)
      int flags = (sl->getType() == PLI_XSHLEVEL && range.first < fid &&
                   fid < range.second)
                      ? F_INBETWEEN_RANGE
                      : F_NORMAL;

      // draw icons
      drawFrameIcon(p, tmp_iconImgRect, i, fid, flags);

      p.setPen(Qt::NoPen);
      p.setBrush(Qt::NoBrush);
      p.drawRect(tmp_iconImgRect);

      // Frame number
      if (m_selection->isSelected(fids[i])) {
        if (TApp::instance()->getCurrentFrame()->isEditingLevel() &&
            isCurrentFrame)
          p.setPen(Qt::red);
        else
          p.setPen(Qt::white);
      } else
        p.setPen(QColor(192, 192, 192));

      p.setBrush(Qt::NoBrush);
      // for single frame
      QString text;
      if (fid.getNumber() == TFrameId::EMPTY_FRAME ||
          fid.getNumber() == TFrameId::NO_FRAME) {
        text = QString("Single Frame");
      }
      // for sequencial frame (with letter)
      else if (Preferences::instance()->isShowFrameNumberWithLettersEnabled()) {
        text = fidToFrameNumberWithLetter(fid.getNumber());
      }
      // for sequencial frame
      else {
        text = QString::number(fid.getNumber()).rightJustified(4, '0');
      }
      p.drawText(tmp_frameRect.adjusted(0, 0, -3, 2), text,
                 QTextOption(Qt::AlignRight | Qt::AlignBottom));
      p.setPen(Qt::NoPen);

      // Read-only frames (lock)
      if (0 <= i && i < frameCount) {
        if ((editableFrameRange.empty() && isReadOnly) ||
            (isReadOnly && (!editableFrameRange.empty() &&
                            editableFrameRange.count(fids[i]) == 0))) {
          static QPixmap lockPixmap(":Resources/forbidden.png");
          p.drawPixmap(tmp_frameRect.bottomLeft() + QPoint(3, -13), lockPixmap);
        }
      }
    }

    // navigator rect
    if (naviRect.isValid() && isCurrentFrame) {
      p.setPen(QPen(Qt::red, 1));
      p.drawRect(naviRect.translated(0, oneFrameHeight * i));
      p.setPen(Qt::NoPen);
    }

    // red frame for the current frame
    if (TApp::instance()->getCurrentFrame()->isEditingLevel() &&
        (isCurrentFrame || isSelected)) {
      QPen pen;
      pen.setColor(Qt::red);
      pen.setWidth(2);
      pen.setJoinStyle(Qt::RoundJoin);
      p.setPen(pen);

      p.drawRect(tmp_frameRect.adjusted(-1, -1, 2, 2));
      p.setPen(Qt::NoPen);
    }
  }

  // se sono in modalita' level edit faccio vedere la freccia che indica il
  // frame corrente
  if (TApp::instance()->getCurrentFrame()->isEditingLevel())
    m_frameHeadGadget->draw(p, QColor(Qt::white), QColor(Qt::black));
}
示例#2
0
QString TTool::updateEnabled() {
  // Disable every tool during playback
  if (m_application->getCurrentFrame()->isPlaying())
    return (enable(false), QString());

  // Release Generic tools at once
  int toolType   = getToolType();
  int targetType = getTargetType();

  if (toolType == TTool::GenericTool) return (enable(true), QString());

  // Retrieve vars and view modes
  TXsheet *xsh = m_application->getCurrentXsheet()->getXsheet();

  int rowIndex       = m_application->getCurrentFrame()->getFrame();
  int columnIndex    = m_application->getCurrentColumn()->getColumnIndex();
  TXshColumn *column = (columnIndex >= 0) ? xsh->getColumn(columnIndex) : 0;

  TXshLevel *xl       = m_application->getCurrentLevel()->getLevel();
  TXshSimpleLevel *sl = xl ? xl->getSimpleLevel() : 0;
  int levelType       = sl ? sl->getType() : NO_XSHLEVEL;

  TStageObject *obj =
      xsh->getStageObject(TStageObjectId::ColumnId(columnIndex));
  bool spline = m_application->getCurrentObject()->isSpline();

  bool filmstrip = m_application->getCurrentFrame()->isEditingLevel();

  /*-- MultiLayerStylePickerONのときは、現状に関わらず使用可能 --*/
  if (m_name == T_StylePicker &&
      Preferences::instance()->isMultiLayerStylePickerEnabled())
    return (enable(true), QString());

  // Check against unplaced columns (not in filmstrip mode)
  if (column && !filmstrip) {
    if (column->isLocked())
      return (enable(false), QObject::tr("The current column is locked."));

    else if (!column->isCamstandVisible())
      return (enable(false), QObject::tr("The current column is hidden."));

    else if (column->getSoundColumn())
      return (enable(false),
              QObject::tr("It is not possible to edit the audio column."));

    else if (column->getSoundTextColumn())
      return (
          enable(false),
          QObject::tr(
              "Note columns can only be edited in the xsheet or timeline."));

    if (toolType == TTool::ColumnTool) {
      // Check column target
      if (column->getLevelColumn() && !(targetType & LevelColumns))
        return (
            enable(false),
            QObject::tr("The current tool cannot be used on a Level column."));

      if (column->getMeshColumn() && !(targetType & MeshColumns))
        return (
            enable(false),
            QObject::tr("The current tool cannot be used on a Mesh column."));
    }
  }

  // Check column tools
  if (toolType == TTool::ColumnTool) {
    if (filmstrip)
      return (
          enable(false),
          QObject::tr("The current tool cannot be used in Level Strip mode."));

    if ((!column || column->isEmpty()) && !(targetType & TTool::EmptyTarget))
      return (enable(false), QString());
  }

  // Check LevelRead & LevelWrite tools
  if (toolType & TTool::LevelTool) {
    // Check against splines
    if (spline) {
      return (targetType & Splines)
                 ? (enable(true), QString())
                 : (enable(false), QObject::tr("The current tool cannot be "
                                               "used to edit a motion path."));
    }

    // Check against empty levels
    if (!xl)
      return (targetType & EmptyTarget) ? (enable(true), QString())
                                        : (enable(false), QString());

    // Check against simple-level-edness
    if (!sl)
      return (enable(false),
              QObject::tr("The current level is not editable."));  // Does it
                                                                   // happen at
                                                                   // all btw?

    // Check against level types
    {
      if ((levelType == PLI_XSHLEVEL) && !(targetType & VectorImage))
        return (
            enable(false),
            QObject::tr("The current tool cannot be used on a Vector Level."));

      if ((levelType == TZP_XSHLEVEL) && !(targetType & ToonzImage))
        return (
            enable(false),
            QObject::tr("The current tool cannot be used on a Toonz Level."));

      if ((levelType == OVL_XSHLEVEL) && !(targetType & RasterImage))
        return (
            enable(false),
            QObject::tr("The current tool cannot be used on a Raster Level."));

      if ((levelType == MESH_XSHLEVEL) && !(targetType & MeshImage))
        return (
            enable(false),
            QObject::tr("The current tool cannot be used on a Mesh Level."));
    }

    // Check against impossibly traceable movements on the column
    if ((levelType & LEVELCOLUMN_XSHLEVEL) && !filmstrip) {
      // Test for Mesh-deformed levels
      const TStageObjectId &parentId = obj->getParent();
      if (parentId.isColumn() && obj->getParentHandle()[0] != 'H') {
        TXshSimpleLevel *parentSl =
            xsh->getCell(rowIndex, parentId.getIndex()).getSimpleLevel();
        if (parentSl && parentSl->getType() == MESH_XSHLEVEL)
          return (
              enable(false),
              QObject::tr(
                  "The current tool cannot be used on a mesh-deformed level"));
      }
    }

    // Check TTool::ImageType tools
    if (toolType == TTool::LevelWriteTool) {
      // Check level against read-only status
      if (sl->isReadOnly()) {
        const std::set<TFrameId> &editableFrames = sl->getEditableRange();
        TFrameId currentFid                      = getCurrentFid();

        if (editableFrames.find(currentFid) == editableFrames.end())
          return (
              enable(false),
              QObject::tr(
                  "The current frame is locked: any editing is forbidden."));
      }

      // Check level type write support
      if (sl->getPath().getType() ==
              "psd" ||  // We don't have the API to write psd files
          sl->is16BitChannelLevel() ||  // Inherited by previous implementation.
                                        // Could be fixed?
          sl->getProperties()->getBpp() ==
              1)  // Black & White images. Again, could be fixed?

        return (enable(false),
                QObject::tr("The current level is not editable."));
    }
  }

  return (enable(true), QString());
}