diff --git a/plugins/dockers/animation/timeline_frames_item_delegate.cpp b/plugins/dockers/animation/timeline_frames_item_delegate.cpp --- a/plugins/dockers/animation/timeline_frames_item_delegate.cpp +++ b/plugins/dockers/animation/timeline_frames_item_delegate.cpp @@ -108,7 +108,7 @@ bool active = index.data(TimelineFramesModel::ActiveLayerRole).toBool(); bool present = index.data(TimelineFramesModel::FrameExistsRole).toBool(); bool editable = index.data(TimelineFramesModel::FrameEditableRole).toBool(); - QVariant colorLabel = index.data(TimelineFramesModel::ColorLabel); + QVariant colorLabel = index.data(TimelineFramesModel::FrameColorLabelIndexRole); QColor color = colorLabel.isValid() ? labelColors.at(colorLabel.toInt()) : TimelineColorScheme::instance()->frameColor(present, active); diff --git a/plugins/dockers/animation/timeline_frames_model.h b/plugins/dockers/animation/timeline_frames_model.h --- a/plugins/dockers/animation/timeline_frames_model.h +++ b/plugins/dockers/animation/timeline_frames_model.h @@ -84,7 +84,8 @@ TimelinePropertiesRole, OtherLayersRole, LayerUsedInTimelineRole, - ColorLabel + FrameColorLabelIndexRole, + LayerColorLabelIndexRole }; // metatype is added by the original implementation diff --git a/plugins/dockers/animation/timeline_frames_model.cpp b/plugins/dockers/animation/timeline_frames_model.cpp --- a/plugins/dockers/animation/timeline_frames_model.cpp +++ b/plugins/dockers/animation/timeline_frames_model.cpp @@ -134,6 +134,12 @@ frame->setColorLabel(color); } + int layerColorLabel(int row) const { + KisNodeDummy *dummy = converter->dummyFromRow(row); + if (!dummy) return -1; + return dummy->node()->colorLabelIndex(); + } + QVariant layerProperties(int row) const { KisNodeDummy *dummy = converter->dummyFromRow(row); if (!dummy) return QVariant(); @@ -321,7 +327,7 @@ case SpecialKeyframeExists: { return m_d->specialKeyframeExists(index.row(), index.column()); } - case ColorLabel: { + case FrameColorLabelIndexRole: { int label = m_d->frameColorLabel(index.row(), index.column()); return label > 0 ? label : QVariant(); } @@ -362,7 +368,7 @@ } break; } - case ColorLabel: { + case FrameColorLabelIndexRole: { m_d->setFrameColorLabel(index.row(), index.column(), value.toInt()); } break; @@ -428,6 +434,10 @@ if (!dummy) return QVariant(); return dummy->node()->useInTimeline(); } + case LayerColorLabelIndexRole:{ + int label = m_d->layerColorLabel(section); + return label > 0 ? label : QVariant(); + } } } diff --git a/plugins/dockers/animation/timeline_frames_view.cpp b/plugins/dockers/animation/timeline_frames_view.cpp --- a/plugins/dockers/animation/timeline_frames_view.cpp +++ b/plugins/dockers/animation/timeline_frames_view.cpp @@ -387,7 +387,7 @@ void TimelineFramesView::slotColorLabelChanged(int label) { Q_FOREACH(QModelIndex index, selectedIndexes()) { - m_d->model->setData(index, label, TimelineFramesModel::ColorLabel); + m_d->model->setData(index, label, TimelineFramesModel::FrameColorLabelIndexRole); } KisImageConfig config; @@ -861,7 +861,7 @@ { KisSignalsBlocker b(m_d->colorSelector); - QVariant colorLabel = index.data(TimelineFramesModel::ColorLabel); + QVariant colorLabel = index.data(TimelineFramesModel::FrameColorLabelIndexRole); int labelIndex = colorLabel.isValid() ? colorLabel.toInt() : 0; m_d->colorSelector->setCurrentIndex(labelIndex); } @@ -875,7 +875,7 @@ bool haveFrames = false; Q_FOREACH(QModelIndex index, selectedIndexes()) { haveFrames |= index.data(TimelineFramesModel::FrameExistsRole).toBool(); - QVariant colorLabel = index.data(TimelineFramesModel::ColorLabel); + QVariant colorLabel = index.data(TimelineFramesModel::FrameColorLabelIndexRole); if (colorLabel.isValid()) { if (labelIndex == 0) { labelIndex = colorLabel.toInt(); diff --git a/plugins/dockers/animation/timeline_layers_header.h b/plugins/dockers/animation/timeline_layers_header.h --- a/plugins/dockers/animation/timeline_layers_header.h +++ b/plugins/dockers/animation/timeline_layers_header.h @@ -36,6 +36,8 @@ void paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const; bool viewportEvent(QEvent *e); void mousePressEvent(QMouseEvent *e); + void paintSectionWithCustomPalette(QPainter *painter, const QRect &rect, + int logicalIndex, const QPalette & customPalette) const; Q_SIGNALS: void sigRequestContextMenu(const QPoint &pos); diff --git a/plugins/dockers/animation/timeline_layers_header.cpp b/plugins/dockers/animation/timeline_layers_header.cpp --- a/plugins/dockers/animation/timeline_layers_header.cpp +++ b/plugins/dockers/animation/timeline_layers_header.cpp @@ -23,10 +23,16 @@ #include #include #include +#include +#include +#include #include "timeline_frames_model.h" #include "timeline_color_scheme.h" +#include "kis_node_view_color_scheme.h" +#include "krita_utils.h" + struct TimelineLayersHeader::Private { @@ -39,6 +45,9 @@ int iconAt(int logicalIndex, const QPoint &pt); TimelineFramesModel::Property* getPropertyAt(TimelineFramesModel::PropertyList &props, int index); + bool isSectionSelected(int visualIndex) const; + bool isFirstVisibleSection(int visualIndex) const; + bool isLastVisibleSection(int visualIndex) const; }; @@ -87,6 +96,23 @@ return result; } + +bool TimelineLayersHeader::Private::isSectionSelected(int logicalIndex) const +{ + //change in future to allow multiple selection support + return q->model()->headerData(logicalIndex, q->orientation(), TimelineFramesModel::ActiveLayerRole).toBool(); +} + +bool TimelineLayersHeader::Private::isFirstVisibleSection(int visualIndex) const +{ + return q->visualIndexAt(0) == visualIndex; +} + +bool TimelineLayersHeader::Private::isLastVisibleSection(int visualIndex) const +{ + return q->visualIndexAt( q->count() - q->hiddenSectionCount() -1 ) == visualIndex; +} + QSize TimelineLayersHeader::sectionSizeFromContents(int logicalIndex) const { QSize baseSize = QHeaderView::sectionSizeFromContents(logicalIndex); @@ -113,8 +139,28 @@ void TimelineLayersHeader::paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const { + KisNodeViewColorScheme scm; + int colorIndex = model()->headerData(logicalIndex, orientation(), + TimelineFramesModel::LayerColorLabelIndexRole + ).toInt(); + QColor color = scm.colorLabel(colorIndex); + QPalette plt = QWidget::palette(); + + if (color.alpha()>0){ + QPalette::ColorRole rolesToChange[] = {QPalette::Light,QPalette::Midlight ,QPalette::Button, + QPalette::Dark ,QPalette::Mid ,QPalette::Base, + QPalette::AlternateBase}; + QColor oldColor, newcolor; + for (QPalette::ColorRole role : rolesToChange) + { + oldColor = plt.color(plt.currentColorGroup(), role); + newcolor = KritaUtils::blendColors(color, oldColor, 0.3); + plt.setColor(plt.currentColorGroup(), role, newcolor); + } + + } painter->save(); - QHeaderView::paintSection(painter, rect, logicalIndex); + paintSectionWithCustomPalette(painter, rect, logicalIndex, plt); painter->restore(); bool isLayerActive = model()->headerData(logicalIndex, orientation(), TimelineFramesModel::ActiveLayerRole).toBool(); @@ -136,7 +182,7 @@ QVector lines; lines << QLine(x0, y0 + lineWidth / 2, x1, y0 + lineWidth / 2); - lines << QLine(x0, y1 - lineWidth / 2, x1, y1 - lineWidth / 2); + lines << QLine(x0, y1 - lineWidth / 2, x1, y1 - lineWidth / 2); painter->drawLines(lines); @@ -159,6 +205,105 @@ } } + +void TimelineLayersHeader::paintSectionWithCustomPalette(QPainter *painter, const QRect &rect, + int logicalIndex, const QPalette & customPalette) const +{ + //"fork" of QHeaderView::paintSection method, but it changed to use custom palette + //and it does not use QHeaderViewPrivate (because I can't access it) + //also it ignores whether or not mouse pointer is over it|mouse button is pressed + if (!rect.isValid()) + return; + + // get the state of the section + QStyleOptionHeader opt; + initStyleOption(&opt); + opt.palette = customPalette; + QStyle::State state = QStyle::State_None; + if (isEnabled()) + state |= QStyle::State_Enabled; + if (window()->isActiveWindow()) + state |= QStyle::State_Active; + + if (isSortIndicatorShown() && sortIndicatorSection() == logicalIndex) + opt.sortIndicator = (sortIndicatorOrder() == Qt::AscendingOrder) + ? QStyleOptionHeader::SortDown : QStyleOptionHeader::SortUp; + + // setup the style options structure + QVariant textAlignment = this->model()->headerData(logicalIndex, this->orientation(), + Qt::TextAlignmentRole); + opt.rect = rect; + opt.section = logicalIndex; + opt.state |= state; + opt.textAlignment = Qt::Alignment(textAlignment.isValid() + ? Qt::Alignment(textAlignment.toInt()) + : this->defaultAlignment()); + + opt.iconAlignment = Qt::AlignVCenter; + opt.text = this->model()->headerData(logicalIndex, this->orientation(), + Qt::DisplayRole).toString(); + + int margin = 2 * style()->pixelMetric(QStyle::PM_HeaderMargin, 0, this); + + const Qt::Alignment headerArrowAlignment = static_cast(style()->styleHint(QStyle::SH_Header_ArrowAlignment, 0, this)); + const bool isHeaderArrowOnTheSide = headerArrowAlignment & Qt::AlignVCenter; + if (isSortIndicatorShown() && sortIndicatorSection() == logicalIndex && isHeaderArrowOnTheSide) + margin += style()->pixelMetric(QStyle::PM_HeaderMarkSize, 0, this); + + if (this->textElideMode() != Qt::ElideNone) + opt.text = opt.fontMetrics.elidedText(opt.text, this->textElideMode() , rect.width() - margin); + + QVariant variant = this->model()->headerData(logicalIndex, this->orientation(), + Qt::DecorationRole); + opt.icon = qvariant_cast(variant); + if (opt.icon.isNull()) + opt.icon = qvariant_cast(variant); + QVariant foregroundBrush = this->model()->headerData(logicalIndex, this->orientation(), + Qt::ForegroundRole); + if (foregroundBrush.canConvert()) + opt.palette.setBrush(QPalette::ButtonText, qvariant_cast(foregroundBrush)); + + QPointF oldBO = painter->brushOrigin(); + QVariant backgroundBrush = this->model()->headerData(logicalIndex, this->orientation(), + Qt::BackgroundRole); + if (backgroundBrush.canConvert()) { + opt.palette.setBrush(QPalette::Button, qvariant_cast(backgroundBrush)); + opt.palette.setBrush(QPalette::Window, qvariant_cast(backgroundBrush)); + painter->setBrushOrigin(opt.rect.topLeft()); + } + + // the section position + int visual = visualIndex(logicalIndex); + Q_ASSERT(visual != -1); + bool first = m_d->isFirstVisibleSection(visual); + bool last = m_d->isLastVisibleSection(visual); + if (first && last) + opt.position = QStyleOptionHeader::OnlyOneSection; + else if (first) + opt.position = QStyleOptionHeader::Beginning; + else if (last) + opt.position = QStyleOptionHeader::End; + else + opt.position = QStyleOptionHeader::Middle; + opt.orientation = this->orientation(); + // the selected position + bool previousSelected = m_d->isSectionSelected(this->logicalIndex(visual - 1)); + bool nextSelected = m_d->isSectionSelected(this->logicalIndex(visual + 1)); + if (previousSelected && nextSelected) + opt.selectedPosition = QStyleOptionHeader::NextAndPreviousAreSelected; + else if (previousSelected) + opt.selectedPosition = QStyleOptionHeader::PreviousIsSelected; + else if (nextSelected) + opt.selectedPosition = QStyleOptionHeader::NextIsSelected; + else + opt.selectedPosition = QStyleOptionHeader::NotAdjacent; + // draw the section + style()->drawControl(QStyle::CE_Header, &opt, painter, this); + + painter->setBrushOrigin(oldBO); +} + + int TimelineLayersHeader::Private::iconAt(int logicalIndex, const QPoint &pt) { QPoint sectionTopLeft(0,