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)); }
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()); }