diff --git a/libs/ui/KisNodeDelegate.h b/libs/ui/KisNodeDelegate.h --- a/libs/ui/KisNodeDelegate.h +++ b/libs/ui/KisNodeDelegate.h @@ -66,15 +66,19 @@ void drawBranch(QPainter *p, const QStyleOptionViewItem &option, const QModelIndex &index) const; void drawColorLabel(QPainter *p, const QStyleOptionViewItem &option, const QModelIndex &index) const; void drawFrame(QPainter *p, const QStyleOptionViewItem &option, const QModelIndex &index) const; + + QRect thumbnailClickRect(const QStyleOptionViewItem &option, const QModelIndex &index) const; void drawThumbnail(QPainter *p, const QStyleOptionViewItem &option, const QModelIndex &index) const; + QRect iconsRect(const QStyleOptionViewItem &option, const QModelIndex &index) const; QRect textRect(const QStyleOptionViewItem &option, const QModelIndex &index) const; void drawText(QPainter *p, const QStyleOptionViewItem &option, const QModelIndex &index) const; void drawIcons(QPainter *p, const QStyleOptionViewItem &option, const QModelIndex &index) const; + QRect visibilityClickRect(const QStyleOptionViewItem &option, const QModelIndex &index) const; - QRect decorationClickRect(const QStyleOptionViewItem &option, const QModelIndex &index) const; - QRect thumbnailClickRect(const QStyleOptionViewItem &option, const QModelIndex &index) const; void drawVisibilityIconHijack(QPainter *p, const QStyleOptionViewItem &option, const QModelIndex &index) const; + + QRect decorationClickRect(const QStyleOptionViewItem &option, const QModelIndex &index) const; void drawDecoration(QPainter *p, const QStyleOptionViewItem &option, const QModelIndex &index) const; void drawExpandButton(QPainter *p, const QStyleOptionViewItem &option, const QModelIndex &index) const; diff --git a/libs/ui/KisNodeDelegate.cpp b/libs/ui/KisNodeDelegate.cpp --- a/libs/ui/KisNodeDelegate.cpp +++ b/libs/ui/KisNodeDelegate.cpp @@ -106,13 +106,12 @@ } p->setFont(option.font); - drawColorLabel(p, option, index); drawFrame(p, option, index); drawThumbnail(p, option, index); - drawText(p, option, index); + drawText(p, option, index); // BUG: Creating group moves things around (RTL-layout alignment) drawIcons(p, option, index); - drawVisibilityIconHijack(p, option, index); + drawVisibilityIconHijack(p, option, index); // TODO hide when dragging drawDecoration(p, option, index); drawExpandButton(p, option, index); drawBranch(p, option, index); @@ -122,17 +121,30 @@ p->restore(); } -void KisNodeDelegate::drawBranch(QPainter *p, const QStyleOptionViewItem &option, const QModelIndex &index) const { - Q_UNUSED(index); +void KisNodeDelegate::drawBranch(QPainter *p, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + QModelIndex tmp = index.parent(); + + // there is no indention if we have no parent group, so don't draw a branch + if (!tmp.isValid()) return; KisNodeViewColorScheme scm; - const QPoint base = scm.relThumbnailRect().translated(option.rect.topLeft()).topLeft() - QPoint( scm.indentation(), 0); - // there is no indention if we are starting negative, so don't draw a branch - if (base.x() < 0) { - return; + int rtlNum = (option.direction == Qt::RightToLeft) ? 1 : -1; + + QRect baseRect = scm.relThumbnailRect(); + + // Move to current index + baseRect.moveTop(option.rect.topLeft().y()); + // Move to correct location. + if (option.direction == Qt::RightToLeft) { + baseRect.moveLeft(option.rect.topRight().x()); + } else { + baseRect.moveRight(option.rect.topLeft().x()); } + QPoint base = baseRect.adjusted(rtlNum*scm.indentation(), 0, + rtlNum*scm.indentation(), 0).center() + QPoint(0, scm.iconSize()/4); QPen oldPen = p->pen(); const qreal oldOpacity = p->opacity(); // remember previous opacity @@ -144,39 +156,34 @@ qApp->palette().color(QPalette::Text); color = KritaUtils::blendColors(color, bgColor, 0.9); - // TODO: if we are a mask type, use dotted lines for the branch style // p->setPen(QPen(p->pen().color(), 2, Qt::DashLine, Qt::RoundCap, Qt::RoundJoin)); p->setPen(QPen(color, 0, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)); - QPoint p2 = base + QPoint(scm.iconSize() - scm.decorationMargin()*2, scm.iconSize()*0.45); - QPoint p3 = base + QPoint(scm.iconSize() - scm.decorationMargin()*2, scm.iconSize()); - QPoint p4 = base + QPoint(scm.iconSize()*1.4, scm.iconSize()); - p->drawLine(p2, p3); - p->drawLine(p3, p4); - - + QPoint p2 = base - QPoint(rtlNum*(scm.iconSize()/2), 0); + QPoint p3 = base - QPoint(0, scm.iconSize()/2); + p->drawLine(base, p2); + p->drawLine(base, p3); // draw parent lines (keep drawing until x position is less than 0 - QPoint p5 = p2 - QPoint(scm.indentation(), 0); - QPoint p6 = p3 - QPoint(scm.indentation(), 0); - - QPoint parentBase1 = p5; - QPoint parentBase2 = p6; + QPoint parentBase1 = base + QPoint(rtlNum*scm.indentation(), 0); + QPoint parentBase2 = p3 + QPoint(rtlNum*scm.indentation(), 0); // indent lines needs to be very subtle to avoid making the docker busy looking color = KritaUtils::blendColors(color, bgColor, 0.9); // makes it a little lighter than L lines p->setPen(QPen(color, 0, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)); - while (parentBase1.x() > scm.visibilityColumnWidth()) { - p->drawLine(parentBase1, parentBase2); - - parentBase1 = parentBase1 - QPoint(scm.indentation(), 0); - parentBase2 = parentBase2 - QPoint(scm.indentation(), 0); + if (tmp.isValid()) { + tmp = tmp.parent(); // Ignore the first group as it was already painted } + while (tmp.isValid()) { + p->drawLine(parentBase1, parentBase2); + parentBase1 += QPoint(rtlNum*scm.indentation(), 0); + parentBase2 += QPoint(rtlNum*scm.indentation(), 0); - + tmp = tmp.parent(); + } p->setPen(oldPen); p->setOpacity(oldOpacity); @@ -190,13 +197,24 @@ if (color.alpha() <= 0) return; QColor bgColor = qApp->palette().color(QPalette::Base); - color = KritaUtils::blendColors(color, bgColor, 0.3); + if ((option.state & QStyle::State_MouseOver) && (!option.state & QStyle::State_Selected)) { + color = KritaUtils::blendColors(color, bgColor, 0.6); + } else { + color = KritaUtils::blendColors(color, bgColor, 0.3); + } + + QRect optionRect = option.rect.adjusted(0, 0, scm.indentation(), 0); + if (option.state & QStyle::State_Selected) { + optionRect = iconsRect(option, index); + } - const QRect rect = option.state & QStyle::State_Selected ? - iconsRect(option, index) : - option.rect.adjusted(-scm.indentation(), 0, 0, 0); + if (option.direction == Qt::RightToLeft) { + optionRect.moveLeft(option.rect.topLeft().x()); + } else { + optionRect.moveRight(option.rect.topRight().x()); + } - p->fillRect(rect, color); + p->fillRect(optionRect, color); } void KisNodeDelegate::drawFrame(QPainter *p, const QStyleOptionViewItem &option, const QModelIndex &index) const @@ -206,82 +224,85 @@ QPen oldPen = p->pen(); p->setPen(scm.gridColor(option, d->view)); - const QPoint base = option.rect.topLeft(); + const QRect visibilityRect = visibilityClickRect(option, index); + const QRect thumbnailRect = thumbnailClickRect(option, index); + const QRect decorationRect = decorationClickRect(option, index); + const QRect iconsRectR = iconsRect(option, index); - QPoint p2 = base + QPoint(-scm.indentation() - 1, 0); - QPoint p3 = base + QPoint(2 * scm.decorationMargin() + scm.decorationSize(), 0); - QPoint p4 = base + QPoint(-1, 0); - QPoint p5(iconsRect(option, - index).left() - 1, base.y()); - QPoint p6(option.rect.right(), base.y()); + const float topY = thumbnailRect.topLeft().y(); + const float bottomY = thumbnailRect.bottomLeft().y(); - QPoint v(0, option.rect.height()); + QPoint bottomLeftP; + QPoint bottomRightP; + if (option.direction == Qt::RightToLeft) { + bottomLeftP = iconsRectR.bottomLeft(); + bottomRightP = visibilityRect.bottomRight(); + } else { + bottomLeftP = visibilityRect.bottomLeft(); + bottomRightP = iconsRectR.bottomRight(); + } + // top running horizontal line, do not double at top + if (!index.row() != 0) + p->drawLine(bottomLeftP.x(), topY, + bottomRightP.x(), topY); - // draw a line that goes the length of the entire frame. one for the - // top, and one for the bottom - QPoint pTopLeft(0, option.rect.topLeft().y()); - QPoint pTopRight(option.rect.bottomRight().x(),option.rect.topLeft().y() ); - p->drawLine(pTopLeft, pTopRight); + // bottom running horizontal line + p->drawLine(bottomLeftP.x(), bottomY, + bottomRightP.x(), bottomY); - QPoint pBottomLeft(0, option.rect.topLeft().y() + scm.rowHeight()); - QPoint pBottomRight(option.rect.bottomRight().x(),option.rect.topLeft().y() + scm.rowHeight() ); - p->drawLine(pBottomLeft, pBottomRight); + // visiblity icon vertical line - left + p->drawLine(visibilityRect.topLeft().x()-1, topY, + visibilityRect.bottomLeft().x()-1, bottomY); + // visiblity icon vertical line - right + p->drawLine(visibilityRect.topRight().x()+1, topY, + visibilityRect.bottomRight().x()+1, bottomY); - const bool paintForParent = - index.parent().isValid() && - !index.row(); + // thumbnail vertical line - left + p->drawLine(thumbnailRect.topLeft().x(), topY, + thumbnailRect.bottomLeft().x(), bottomY); - if (paintForParent) { - QPoint p1(-2 * scm.indentation() - 1, 0); - p1 += base; - p->drawLine(p1, p2); - } + // thumbnail vertical line - right + p->drawLine(thumbnailRect.topRight().x(), topY, + thumbnailRect.bottomRight().x(), bottomY); + // decoration vertical line - left + p->drawLine(decorationRect.topLeft().x(), topY, + decorationRect.bottomLeft().x(), bottomY); - QPoint k0(0, base.y()); - QPoint k1(1 * scm.border() + 2 * scm.visibilityMargin() + scm.visibilitySize(), base.y()); - p->drawLine(k0, k1); - p->drawLine(k0 + v, k1 + v); - p->drawLine(k0, k0 + v); - p->drawLine(k1, k1 + v); + // decoration vertical line - right + p->drawLine(decorationRect.topRight().x(), topY, + decorationRect.bottomRight().x(), bottomY); - p->drawLine(p2, p6); - p->drawLine(p2 + v, p6 + v); - p->drawLine(p2, p2 + v); - p->drawLine(p3, p3 + v); - p->drawLine(p4, p4 + v); - p->drawLine(p5, p5 + v); - p->drawLine(p6, p6 + v); + // icons' lines are drawn by drawIcons //// For debugging purposes only - //p->setPen(Qt::blue); - //KritaUtils::renderExactRect(p, iconsRect(option, index)); + p->setPen(Qt::blue); + //KritaUtils::renderExactRect(p, iconsRectR); //KritaUtils::renderExactRect(p, textRect(option, index)); - //KritaUtils::renderExactRect(p, scm.relThumbnailRect().translated(option.rect.topLeft())); + //KritaUtils::renderExactRect(p, visibilityRect); p->setPen(oldPen); } QRect KisNodeDelegate::thumbnailClickRect(const QStyleOptionViewItem &option, const QModelIndex &index) const { Q_UNUSED(index); + KisNodeViewColorScheme scm; - int steps = 0; - QModelIndex tmp = index.parent(); - while (tmp.isValid()) { - steps++; - tmp = tmp.parent(); + QRect rc = scm.relThumbnailRect(); + + // Move to current index + rc.moveTop(option.rect.topLeft().y()); + // Move to correct location. + if (option.direction == Qt::RightToLeft) { + rc.moveLeft(option.rect.topRight().x()); + } else { + rc.moveRight(option.rect.topLeft().x()); } - KisNodeViewColorScheme scm; - return QRect(scm.border() + - 2 * scm.visibilityMargin() + scm.visibilitySize() + - scm.border() + steps * scm.indentation(), - scm.border() + option.rect.top(), - 2 * scm.thumbnailMargin() + scm.thumbnailSize(), - scm.rowHeight() - scm.border()); + return rc; } void KisNodeDelegate::drawThumbnail(QPainter *p, const QStyleOptionViewItem &option, const QModelIndex &index) const @@ -296,12 +317,9 @@ p->setOpacity(0.35); } - QRect fitRect = scm.relThumbnailRect().translated(option.rect.topLeft()); - - QPoint offset; - offset.setX((fitRect.width() - img.width()) / 2); - offset.setY((fitRect.height() - img.height()) / 2); - offset += fitRect.topLeft(); + QRect fitRect = thumbnailClickRect(option, index); + // Shrink to to-be-visible rect + fitRect = kisGrowRect(fitRect, -(scm.thumbnailMargin()+scm.border())); // paint in a checkerboard pattern behind the layer contents to represent transparent const int step = scm.thumbnailSize() / 6; @@ -313,13 +331,13 @@ gc.fillRect(QRect(0, step, step, step), d->checkersColor2); QBrush brush(checkers); - p->setBrushOrigin(offset); - p->fillRect(img.rect().translated(offset), brush); + //p->setBrushOrigin(QPoint(fitRect.x(), fitRect.y())); + p->fillRect(fitRect, brush); - p->drawImage(offset, img); + p->drawImage(fitRect, img); p->setOpacity(oldOpacity); // restore old opacity - QRect borderRect = kisGrowRect(img.rect(), 1).translated(offset); + QRect borderRect = kisGrowRect(fitRect, 1); KritaUtils::renderExactRect(p, borderRect, scm.gridColor(option, d->view)); } @@ -333,13 +351,15 @@ propCount * (scm.iconSize() + 2 * scm.iconMargin()) + (propCount - 1) * scm.border(); - const int x = option.rect.x() + option.rect.width() - - (iconsWidth + scm.border()); - const int y = option.rect.y() + scm.border(); + QRect fitRect = QRect(0, option.rect.y() + scm.border(), + iconsWidth, scm.rowHeight() - scm.border()); + if (option.direction == Qt::RightToLeft) { + fitRect.moveLeft(option.rect.topLeft().x()); + } else { + fitRect.moveRight(option.rect.topRight().x()); + } - return QRect(x, y, - iconsWidth, - scm.rowHeight() - scm.border()); + return fitRect; } QRect KisNodeDelegate::textRect(const QStyleOptionViewItem &option, const QModelIndex &index) const @@ -353,41 +373,34 @@ minbearing = option.fontMetrics.minLeftBearing() + option.fontMetrics.minRightBearing(); } - const int decorationOffset = - 2 * scm.border() + - 2 * scm.decorationMargin() + - scm.decorationSize(); + const QRect decoRect = decorationClickRect(option, index); + const QRect iconRect = iconsRect(option, index); - const int width = - iconsRect(option, index).left() - option.rect.x() - - scm.border() + minbearing - decorationOffset; + QRect rc = QRect((option.direction == Qt::RightToLeft) ? iconRect.topRight() : decoRect.topRight(), + (option.direction == Qt::RightToLeft) ? decoRect.bottomLeft() : iconRect.bottomLeft()); + rc.adjust(-(scm.border()+minbearing), 0, + (scm.border()+minbearing), 0); - return QRect(option.rect.x() - minbearing + decorationOffset, - option.rect.y() + scm.border(), - width, - scm.rowHeight() - scm.border()); + return rc; } void KisNodeDelegate::drawText(QPainter *p, const QStyleOptionViewItem &option, const QModelIndex &index) const { KisNodeViewColorScheme scm; - const QRect rc = textRect(option, index) - .adjusted(scm.textMargin(), 0, -scm.textMargin(), 0); + const QRect rc = textRect(option, index).adjusted(scm.textMargin(), 0, + -scm.textMargin(), 0); QPen oldPen = p->pen(); const qreal oldOpacity = p->opacity(); // remember previous opacity p->setPen(option.palette.color(QPalette::Active,QPalette::Text )); - - if (!(option.state & QStyle::State_Enabled)) { p->setOpacity(0.55); } - const QString text = index.data(Qt::DisplayRole).toString(); - const QString elided = elidedText(p->fontMetrics(), rc.width(), Qt::ElideRight, text); + const QString elided = p->fontMetrics().elidedText(text, Qt::ElideRight, rc.width()); p->drawText(rc, Qt::AlignLeft | Qt::AlignVCenter, elided); p->setPen(oldPen); // restore pen settings @@ -473,19 +486,25 @@ void KisNodeDelegate::drawIcons(QPainter *p, const QStyleOptionViewItem &option, const QModelIndex &index) const { KisNodeViewColorScheme scm; - const QRect r = iconsRect(option, index); + const QRect rc = iconsRect(option, index); QTransform oldTransform = p->transform(); QPen oldPen = p->pen(); - p->setTransform(QTransform::fromTranslate(r.x(), r.y())); + p->setTransform(QTransform::fromTranslate(rc.x(), rc.y())); p->setPen(scm.gridColor(option, d->view)); int x = 0; const int y = (scm.rowHeight() - scm.border() - scm.iconSize()) / 2; KisBaseNode::PropertyList props = index.data(KisNodeModel::PropertiesRole).value(); QList realProps = d->rightmostProperties(props); + if (option.direction == Qt::RightToLeft) { + std::reverse(realProps.begin(), realProps.end()); + } + Q_FOREACH (OptionalProperty prop, realProps) { + if (prop == realProps.first() && option.direction == Qt::LeftToRight) + p->drawLine(x, 0, x, scm.rowHeight() - scm.border()); x += scm.iconMargin(); if (prop) { QIcon icon = prop->state.toBool() ? prop->onIcon : prop->offIcon; @@ -506,7 +525,8 @@ } x += scm.iconSize() + scm.iconMargin(); - p->drawLine(x, 0, x, scm.rowHeight() - scm.border()); + if (!(prop == realProps.last() && option.direction == Qt::LeftToRight)) + p->drawLine(x, 0, x, scm.rowHeight() - scm.border()); x += scm.border(); } @@ -518,22 +538,40 @@ { Q_UNUSED(index); KisNodeViewColorScheme scm; - return QRect(scm.border(), scm.border() + option.rect.top(), - 2 * scm.visibilityMargin() + scm.visibilitySize(), - scm.rowHeight() - scm.border()); + + QRect rc = scm.relVisibilityRect(); + rc.setHeight(scm.rowHeight()); + + // Move to current index + rc.moveCenter(option.rect.center()); + // Move to correct location. + if (option.direction == Qt::RightToLeft) { + rc.moveRight(d->view->width()-5); // HACK: Without the -5, the right edge is outside the view + } else { + rc.moveLeft(0); + } + + return rc; } QRect KisNodeDelegate::decorationClickRect(const QStyleOptionViewItem &option, const QModelIndex &index) const { - Q_UNUSED(option); Q_UNUSED(index); KisNodeViewColorScheme scm; - QRect realVisualRect = d->view->originalVisualRect(index); + QRect rc = scm.relDecorationRect(); - return QRect(realVisualRect.left(), scm.border() + realVisualRect.top(), - 2 * scm.decorationMargin() + scm.decorationSize(), - scm.rowHeight() - scm.border()); + // Move to current index + rc.moveTop(option.rect.topLeft().y()); + rc.setHeight(scm.rowHeight()); + // Move to correct location. + if (option.direction == Qt::RightToLeft) { + rc.moveRight(option.rect.topRight().x()); + } else { + rc.moveLeft(option.rect.topLeft().x()); + } + + return rc; } void KisNodeDelegate::drawVisibilityIconHijack(QPainter *p, const QStyleOptionViewItem &option, const QModelIndex &index) const @@ -551,49 +589,51 @@ OptionalProperty prop = d->findVisibilityProperty(props); if (!prop) return; - const int x = scm.border() + scm.visibilityMargin(); - const int y = option.rect.top() + (scm.rowHeight() - scm.border() - scm.visibilitySize()) / 2; + QRect fitRect = visibilityClickRect(option, index); + // Shrink to to-be-visible rect + fitRect = kisGrowRect(fitRect, -(scm.visibilityMargin()+scm.border())); QIcon icon = prop->state.toBool() ? prop->onIcon : prop->offIcon; // if we are not showing the layer, make the icon slightly transparent like other inactive icons const qreal oldOpacity = p->opacity(); - if (prop->state.toBool() == true) { - p->setOpacity(1.0); - } - else { + + if (!prop->state.toBool()) { p->setOpacity(0.35); } - p->drawPixmap(x, y, icon.pixmap(scm.visibilitySize(), QIcon::Normal)); + p->drawPixmap(fitRect.x(), fitRect.center().y() - scm.visibilitySize() / 2, + icon.pixmap(scm.visibilitySize(), QIcon::Normal)); p->setOpacity(oldOpacity); //// For debugging purposes only - // p->save(); - // p->setPen(Qt::blue); - // KritaUtils::renderExactRect(p, visibilityClickRect(option, index)); - // p->restore(); +// // // p->save(); +// // // p->setPen(Qt::blue); +// // // KritaUtils::renderExactRect(p, visibilityClickRect(option, index)); +// // // p->restore(); } void KisNodeDelegate::drawDecoration(QPainter *p, const QStyleOptionViewItem &option, const QModelIndex &index) const { KisNodeViewColorScheme scm; QIcon icon = index.data(Qt::DecorationRole).value(); if (!icon.isNull()) { - QPixmap pixmap = - icon.pixmap(scm.decorationSize(), - (option.state & QStyle::State_Enabled) ? - QIcon::Normal : QIcon::Disabled); + QPixmap pixmap = icon.pixmap(scm.decorationSize(), + (option.state & QStyle::State_Enabled) ? + QIcon::Normal : QIcon::Disabled); + + QRect rc = decorationClickRect(option, index); + + // Shrink to to-be-visible rect + rc = kisGrowRect(rc, -(scm.decorationMargin()+scm.border())); - const QRect rc = scm.relDecorationRect().translated(option.rect.topLeft()); const qreal oldOpacity = p->opacity(); // remember previous opacity if (!(option.state & QStyle::State_Enabled)) { p->setOpacity(0.35); } - p->drawPixmap(rc.topLeft(), pixmap); p->setOpacity(oldOpacity); // restore old opacity } @@ -603,19 +643,24 @@ { Q_UNUSED(index); KisNodeViewColorScheme scm; - QRect rc = scm.relExpandButtonRect().translated(option.rect.topLeft()); - rc = kisGrowRect(rc, 0); - if (!(option.state & QStyle::State_Children)) { - return; - } + QRect rc = decorationClickRect(option, index); - QString iconName = option.state & QStyle::State_Open ? "arrow-down" : "arrow-right"; + // Move to current index + rc.moveTop(option.rect.topLeft().y()); + // Shrink to to-be-visible rect + rc = kisGrowRect(rc, -(scm.decorationMargin()+scm.border())); + + if (!(option.state & QStyle::State_Children)) return; + + + QString iconName = option.state & QStyle::State_Open ? + "arrow-down" : ((option.direction == Qt::RightToLeft) ? "arrow-left" : "arrow-right"); QIcon icon = KisIconUtils::loadIcon(iconName); QPixmap pixmap = icon.pixmap(rc.width(), (option.state & QStyle::State_Enabled) ? QIcon::Normal : QIcon::Disabled); - p->drawPixmap(rc.topLeft(), pixmap); + p->drawPixmap(rc.bottomLeft()-QPoint(0, scm.decorationSize()), pixmap); } void KisNodeDelegate::Private::toggleProperty(KisBaseNode::PropertyList &props, OptionalProperty clickedProperty, bool controlPressed, const QModelIndex &index) @@ -674,6 +719,9 @@ { KisNodeViewColorScheme scm; + QStyleOptionViewItem newOption = option; + newOption.rect = d->view->originalVisualRect(index); + if ((event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonDblClick) && (index.flags() & Qt::ItemIsEnabled)) { @@ -690,26 +738,30 @@ * handle it. */ - const QRect iconsRect = this->iconsRect(option, index); - const bool iconsClicked = iconsRect.isValid() && - iconsRect.contains(mouseEvent->pos()); - - const QRect visibilityRect = visibilityClickRect(option, index); + const QRect visibilityRect = visibilityClickRect(newOption, index); const bool visibilityClicked = visibilityRect.isValid() && visibilityRect.contains(mouseEvent->pos()); - const QRect decorationRect = decorationClickRect(option, index); + const QRect thumbnailRect = thumbnailClickRect(newOption, index); + const bool thumbnailClicked = thumbnailRect.isValid() && + thumbnailRect.contains(mouseEvent->pos()); + + const QRect decorationRect = decorationClickRect(newOption, index); const bool decorationClicked = decorationRect.isValid() && decorationRect.contains(mouseEvent->pos()); - const bool leftButton = mouseEvent->buttons() & Qt::LeftButton; + const QRect iconsRect = this->iconsRect(newOption, index); + const bool iconsClicked = iconsRect.isValid() && + iconsRect.contains(mouseEvent->pos()); - const QRect thumbnailRect = thumbnailClickRect(option, index); - const bool thumbnailClicked = thumbnailRect.contains(mouseEvent->pos()); + const bool leftButton = mouseEvent->buttons() & Qt::LeftButton; if (leftButton && iconsClicked) { KisBaseNode::PropertyList props = index.data(KisNodeModel::PropertiesRole).value(); QList realProps = d->rightmostProperties(props); + if (newOption.direction == Qt::RightToLeft) { + std::reverse(realProps.begin(), realProps.end()); + } const int numProps = realProps.size(); const int iconWidth = scm.iconSize() + 2 * scm.iconMargin() + scm.border(); @@ -760,8 +812,8 @@ if (hasCorrectModifier) { model->setData(index, QVariant(int(action)), KisNodeModel::SelectOpaqueRole); - return true; } + return true; //TODO: If not here then the item is !expanded when reaching return false; } if (mouseEvent->button() == Qt::LeftButton && @@ -775,7 +827,7 @@ else if (event->type() == QEvent::ToolTip) { if (!KisConfig(true).hidePopups()) { QHelpEvent *helpEvent = static_cast(event); - d->tip.showTip(d->view, helpEvent->pos(), option, index); + d->tip.showTip(d->view, helpEvent->pos(), newOption, index); } return true; } else if (event->type() == QEvent::Leave) { @@ -921,14 +973,19 @@ /// probably don't need to also show the actual number for % complete KisNodeViewColorScheme scm; - const int width = textRect(option, index).width() + scm.iconSize()*2; + + const QRect thumbnailRect = thumbnailClickRect(option, index); + const QRect iconsRectR = iconsRect(option, index); const int height = 5; - const QPoint base = option.rect.bottomLeft() - QPoint(0, height ); - const QRect r = QRect(base.x(), base.y(), width, height); + const QRect rc = QRect( + ((option.direction == Qt::RightToLeft) ? iconsRectR.bottomRight() + : thumbnailRect.bottomRight()) - QPoint(0, height), + ((option.direction == Qt::RightToLeft) ? thumbnailRect.bottomLeft() + : iconsRectR.bottomLeft())); p->save(); { - p->setClipRect(r); + p->setClipRect(rc); QStyle* style = QApplication::style(); QStyleOptionProgressBar opt; @@ -938,7 +995,6 @@ opt.textVisible = false; opt.textAlignment = Qt::AlignHCenter; opt.text = i18n("%1 %", opt.progress); - opt.rect = r; opt.orientation = Qt::Horizontal; opt.state = option.state; style->drawControl(QStyle::CE_ProgressBar, &opt, p, 0); diff --git a/libs/ui/KisNodeView.cpp b/libs/ui/KisNodeView.cpp --- a/libs/ui/KisNodeView.cpp +++ b/libs/ui/KisNodeView.cpp @@ -194,10 +194,14 @@ return QAbstractItemView::selectionCommand(index, event); } + QRect KisNodeView::visualRect(const QModelIndex &index) const { QRect rc = QTreeView::visualRect(index); - rc.setLeft(0); + if (layoutDirection() == Qt::RightToLeft) + rc.setRight(width()); + else + rc.setLeft(0); return rc; } @@ -211,8 +215,10 @@ KisNodeViewColorScheme scm; QModelIndex index = QTreeView::indexAt(point); - if (!index.isValid() && point.x() < scm.visibilityColumnWidth()) { - index = QTreeView::indexAt(point + QPoint(scm.visibilityColumnWidth(), 0)); + if (!index.isValid()) { + // Middle is a good position for both LTR and RTL layouts + // First reset x, then get the x in the middle + index = QTreeView::indexAt(point - QPoint(point.x(), 0) + QPoint(width() / 2, 0)); } return index; diff --git a/libs/ui/kis_node_view_color_scheme.h b/libs/ui/kis_node_view_color_scheme.h --- a/libs/ui/kis_node_view_color_scheme.h +++ b/libs/ui/kis_node_view_color_scheme.h @@ -58,6 +58,7 @@ int visibilityColumnWidth() const; int indentation() const; + QRect relVisibilityRect() const; QRect relThumbnailRect() const; QRect relDecorationRect() const; QRect relExpandButtonRect() const; diff --git a/libs/ui/kis_node_view_color_scheme.cpp b/libs/ui/kis_node_view_color_scheme.cpp --- a/libs/ui/kis_node_view_color_scheme.cpp +++ b/libs/ui/kis_node_view_color_scheme.cpp @@ -149,20 +149,25 @@ border(); } +QRect KisNodeViewColorScheme::relVisibilityRect() const +{ + return QRect(0, 0, + visibilitySize() + 2 * visibilityMargin() + 2 * border(), + visibilitySize() + 2 * visibilityMargin() + 2 * border()); +} + QRect KisNodeViewColorScheme::relThumbnailRect() const { - return QRect(-indentation(), - border(), - thumbnailSize() + 2 * thumbnailMargin(), - thumbnailSize() + 2 * thumbnailMargin()); + return QRect(0, 0, + thumbnailSize() + 2 * thumbnailMargin() + 2 * border(), + thumbnailSize() + 2 * thumbnailMargin() + 2 * border()); // 2 * was off } QRect KisNodeViewColorScheme::relDecorationRect() const { - return QRect(border() + decorationMargin(), - border() + decorationMargin(), - decorationSize(), - decorationSize()); + return QRect(0, 0, + decorationSize() + 2 * decorationMargin() + 2 * border(), + decorationSize() + 2 * decorationMargin() + 2 * border()); } QRect KisNodeViewColorScheme::relExpandButtonRect() const