#include "lc_global.h" #include "lc_timelinewidget.h" #include "lc_model.h" #include "project.h" #include "piece.h" #include "pieceinf.h" #include "lc_mainwindow.h" lcTimelineWidget::lcTimelineWidget(QWidget* Parent) : QTreeWidget(Parent) { mIgnoreUpdates = false; setSelectionMode(QAbstractItemView::ExtendedSelection); setDragEnabled(true); setDragDropMode(QAbstractItemView::InternalMove); setUniformRowHeights(true); setHeaderHidden(true); setContextMenuPolicy(Qt::CustomContextMenu); invisibleRootItem()->setFlags(invisibleRootItem()->flags() & ~Qt::ItemIsDropEnabled); connect(this, SIGNAL(itemSelectionChanged()), SLOT(ItemSelectionChanged())); connect(this, SIGNAL(customContextMenuRequested(QPoint)), SLOT(CustomMenuRequested(QPoint))); } lcTimelineWidget::~lcTimelineWidget() { } void lcTimelineWidget::CustomMenuRequested(QPoint Pos) { QMenu* Menu = new QMenu(this); lcObject* FocusObject = lcGetActiveModel()->GetFocusObject(); if (FocusObject && FocusObject->IsPiece()) { lcPiece* Piece = (lcPiece*)FocusObject; if (Piece->mPieceInfo->IsModel()) { Menu->addAction(gMainWindow->mActions[LC_MODEL_EDIT_FOCUS]); Menu->addSeparator(); } } Menu->addAction(gMainWindow->mActions[LC_TIMELINE_SET_CURRENT]); Menu->addAction(gMainWindow->mActions[LC_TIMELINE_INSERT]); Menu->addAction(gMainWindow->mActions[LC_TIMELINE_DELETE]); Menu->addAction(gMainWindow->mActions[LC_TIMELINE_MOVE_SELECTION]); Menu->addSeparator(); Menu->addAction(gMainWindow->mActions[LC_PIECE_HIDE_SELECTED]); Menu->addAction(gMainWindow->mActions[LC_PIECE_HIDE_UNSELECTED]); Menu->addAction(gMainWindow->mActions[LC_PIECE_UNHIDE_SELECTED]); Menu->addAction(gMainWindow->mActions[LC_PIECE_UNHIDE_ALL]); Menu->popup(viewport()->mapToGlobal(Pos)); } void lcTimelineWidget::Update(bool Clear, bool UpdateItems) { if (mIgnoreUpdates) return; lcModel* Model = lcGetActiveModel(); if (!Model) { mItems.clear(); clear(); return; } bool Blocked = blockSignals(true); if (Clear) { mItems.clear(); clear(); } lcStep LastStep = lcMax(Model->GetLastStep(), Model->GetCurrentStep()); for (int TopLevelItemIdx = LastStep; TopLevelItemIdx < topLevelItemCount(); ) { QTreeWidgetItem* StepItem = topLevelItem(TopLevelItemIdx); while (StepItem->childCount()) { QTreeWidgetItem* PieceItem = StepItem->child(0); lcPiece* Piece = (lcPiece*)PieceItem->data(0, Qt::UserRole).value(); mItems.remove(Piece); delete PieceItem; } delete StepItem; } for (unsigned int TopLevelItemIdx = topLevelItemCount(); TopLevelItemIdx < LastStep; TopLevelItemIdx++) { QTreeWidgetItem* StepItem = new QTreeWidgetItem(this, QStringList(tr("Step %1").arg(TopLevelItemIdx + 1))); StepItem->setFlags(Qt::ItemIsEnabled | Qt::ItemIsDropEnabled); addTopLevelItem(StepItem); StepItem->setExpanded(true); } const lcArray& Pieces = Model->GetPieces(); QTreeWidgetItem* StepItem = nullptr; int PieceItemIndex = 0; lcStep Step = 0; for (int PieceIdx = 0; PieceIdx != Pieces.GetSize(); PieceIdx++) { lcPiece* Piece = Pieces[PieceIdx]; while (Step != Piece->GetStepShow()) { if (StepItem) { while (PieceItemIndex < StepItem->childCount()) { QTreeWidgetItem* PieceItem = StepItem->child(PieceItemIndex); lcPiece* RemovePiece = (lcPiece*)PieceItem->data(0, Qt::UserRole).value(); if (Pieces.FindIndex(RemovePiece) == -1) { mItems.remove(RemovePiece); delete PieceItem; } else { PieceItem->parent()->removeChild(PieceItem); topLevelItem(RemovePiece->GetStepShow() - 1)->addChild(PieceItem); } } } Step++; StepItem = topLevelItem(Step - 1); PieceItemIndex = 0; } QTreeWidgetItem* PieceItem = mItems.value(Piece); bool UpdateItem = UpdateItems; if (StepItem) { if (!PieceItem) { PieceItem = new QTreeWidgetItem(); PieceItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled); PieceItem->setData(0, Qt::UserRole, qVariantFromValue((uintptr_t)Piece)); StepItem->insertChild(PieceItemIndex, PieceItem); mItems[Piece] = PieceItem; UpdateItem = true; } else { if (PieceItemIndex >= StepItem->childCount() || PieceItem != StepItem->child(PieceItemIndex)) { QTreeWidgetItem* PieceParent = PieceItem->parent(); if (PieceParent) PieceParent->removeChild(PieceItem); StepItem->insertChild(PieceItemIndex, PieceItem); } } } if (UpdateItem) { PieceItem->setText(0, Piece->mPieceInfo->m_strDescription); int ColorIndex = Piece->mColorIndex; if (!mIcons.contains(ColorIndex)) { int Size = rowHeight(indexFromItem(PieceItem)); QImage Image(Size, Size, QImage::Format_ARGB32); Image.fill(0); float* Color = gColorList[ColorIndex].Value; QPainter Painter(&Image); Painter.setPen(Qt::darkGray); Painter.setBrush(QColor::fromRgbF(Color[0], Color[1], Color[2])); Painter.drawEllipse(0, 0, Size - 1, Size - 1); mIcons[ColorIndex] = QIcon(QPixmap::fromImage(Image)); } PieceItem->setIcon(0, mIcons[ColorIndex]); QColor Color = palette().text().color(); if (Piece->IsHidden()) Color.setAlpha(128); PieceItem->setTextColor(0, Color); } PieceItem->setSelected(Piece->IsSelected()); PieceItemIndex++; } if (Step == 0) { Step = 1; StepItem = topLevelItem(0); } while (Step <= LastStep && StepItem) { while (PieceItemIndex < StepItem->childCount()) { QTreeWidgetItem* PieceItem = StepItem->child(PieceItemIndex); lcPiece* RemovePiece = (lcPiece*)PieceItem->data(0, Qt::UserRole).value(); mItems.remove(RemovePiece); delete PieceItem; } Step++; StepItem = topLevelItem(Step - 1); PieceItemIndex = 0; } blockSignals(Blocked); } void lcTimelineWidget::UpdateSelection() { if (mIgnoreUpdates) return; QItemSelection ItemSelection; for (int TopLevelItemIdx = 0; TopLevelItemIdx < topLevelItemCount(); TopLevelItemIdx++) { QTreeWidgetItem* StepItem = topLevelItem(TopLevelItemIdx); for (int PieceItemIdx = 0; PieceItemIdx < StepItem->childCount(); PieceItemIdx++) { QTreeWidgetItem* PieceItem = StepItem->child(PieceItemIdx); lcPiece* Piece = (lcPiece*)PieceItem->data(0, Qt::UserRole).value(); if (Piece && Piece->IsSelected()) { QModelIndex Index = indexFromItem(PieceItem); ItemSelection.select(Index, Index); } } } bool Blocked = blockSignals(true); selectionModel()->select(ItemSelection, QItemSelectionModel::ClearAndSelect); blockSignals(Blocked); } void lcTimelineWidget::InsertStep() { QTreeWidgetItem* CurrentItem = currentItem(); if (!CurrentItem) return; if (CurrentItem->parent()) CurrentItem = CurrentItem->parent(); int Step = indexOfTopLevelItem(CurrentItem); if (Step == -1) return; lcGetActiveModel()->InsertStep(Step + 1); } void lcTimelineWidget::RemoveStep() { QTreeWidgetItem* CurrentItem = currentItem(); if (!CurrentItem) return; if (CurrentItem->parent()) CurrentItem = CurrentItem->parent(); int Step = indexOfTopLevelItem(CurrentItem); if (Step == -1) return; lcGetActiveModel()->RemoveStep(Step + 1); } void lcTimelineWidget::MoveSelection() { QTreeWidgetItem* CurrentItem = currentItem(); if (!CurrentItem) return; if (CurrentItem->parent()) CurrentItem = CurrentItem->parent(); int Step = indexOfTopLevelItem(CurrentItem); if (Step == -1) return; QList SelectedItems = selectedItems(); foreach(QTreeWidgetItem* PieceItem, SelectedItems) { QTreeWidgetItem* Parent = PieceItem->parent(); if (!Parent) continue; int ChildIndex = Parent->indexOfChild(PieceItem); CurrentItem->addChild(Parent->takeChild(ChildIndex)); } UpdateModel(); } void lcTimelineWidget::SetCurrentStep() { QTreeWidgetItem* CurrentItem = currentItem(); if (!CurrentItem) return; if (CurrentItem->parent()) CurrentItem = CurrentItem->parent(); int Step = indexOfTopLevelItem(CurrentItem); if (Step == -1) return; lcGetActiveModel()->SetCurrentStep(Step + 1); } void lcTimelineWidget::ItemSelectionChanged() { lcArray Selection; lcStep LastStep = 1; foreach (QTreeWidgetItem* PieceItem, selectedItems()) { lcPiece* Piece = (lcPiece*)PieceItem->data(0, Qt::UserRole).value(); if (Piece) { LastStep = lcMax(LastStep, Piece->GetStepShow()); Selection.Add(Piece); } } lcPiece* CurrentPiece = nullptr; QTreeWidgetItem* CurrentItem = currentItem(); if (CurrentItem && CurrentItem->isSelected()) CurrentPiece = (lcPiece*)CurrentItem->data(0, Qt::UserRole).value(); bool Blocked = blockSignals(true); mIgnoreUpdates = true; lcModel* Model = lcGetActiveModel(); if (LastStep > Model->GetCurrentStep()) Model->SetCurrentStep(LastStep); Model->SetSelectionAndFocus(Selection, CurrentPiece, LC_PIECE_SECTION_POSITION); mIgnoreUpdates = false; blockSignals(Blocked); } void lcTimelineWidget::dropEvent(QDropEvent* Event) { QTreeWidget::dropEvent(Event); UpdateModel(); } void lcTimelineWidget::mousePressEvent(QMouseEvent* Event) { if (Event->button() == Qt::RightButton) { QItemSelection Selection = selectionModel()->selection(); bool Blocked = blockSignals(true); QTreeWidget::mousePressEvent(Event); blockSignals(Blocked); selectionModel()->select(Selection, QItemSelectionModel::ClearAndSelect); } else QTreeWidget::mousePressEvent(Event); } void lcTimelineWidget::UpdateModel() { QList> PieceSteps; for (int TopLevelItemIdx = 0; TopLevelItemIdx < topLevelItemCount(); TopLevelItemIdx++) { QTreeWidgetItem* StepItem = topLevelItem(TopLevelItemIdx); for (int PieceItemIdx = 0; PieceItemIdx < StepItem->childCount(); PieceItemIdx++) { QTreeWidgetItem* PieceItem = StepItem->child(PieceItemIdx); lcPiece* Piece = (lcPiece*)PieceItem->data(0, Qt::UserRole).value(); PieceSteps.append(QPair(Piece, TopLevelItemIdx + 1)); } } mIgnoreUpdates = true; lcGetActiveModel()->SetPieceSteps(PieceSteps); mIgnoreUpdates = false; }