QRect KisNodeDelegate::textRect(const QStyleOptionViewItem &option, const QModelIndex &index) const { KisNodeViewColorScheme scm; static QFont f; static int minbearing = 1337 + 666; //can be 0 or negative, 2003 is less likely if (minbearing == 2003 || f != option.font) { f = option.font; //getting your bearings can be expensive, so we cache them minbearing = option.fontMetrics.minLeftBearing() + option.fontMetrics.minRightBearing(); } const int decorationOffset = 2 * scm.border() + 2 * scm.decorationMargin() + scm.decorationSize(); const int width = iconsRect(option, index).left() - option.rect.x() - scm.border() + minbearing - decorationOffset; return QRect(option.rect.x() - minbearing + decorationOffset, option.rect.y() + scm.border(), width, scm.rowHeight() - scm.border()); }
void KisNodeDelegate::drawFrame(QPainter *p, const QStyleOptionViewItem &option, const QModelIndex &index) const { KisNodeViewColorScheme scm; QPen oldPen = p->pen(); p->setPen(scm.gridColor(option, d->view)); const QPoint base = option.rect.topLeft(); QPoint p2 = base + QPoint(-scm.indentation() - 1, 0); QPoint p3 = base + QPoint(-2 * scm.border() - 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()); QPoint v(0, option.rect.height()); const bool paintForParent = index.parent().isValid() && !index.row(); if (paintForParent) { QPoint p1(-2 * scm.indentation() - 1, 0); p1 += base; p->drawLine(p1, p2); } 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); 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); //// For debugging purposes only //p->setPen(Qt::blue); //KritaUtils::renderExactRect(p, iconsRect(option, index)); //KritaUtils::renderExactRect(p, textRect(option, index)); //KritaUtils::renderExactRect(p, scm.relThumbnailRect().translated(option.rect.topLeft())); p->setPen(oldPen); }
QRect KoDocumentSectionDelegate::progressBarRect(const QStyleOptionViewItem &option, const QModelIndex &index) const { if (d->view->displayMode() == View::ThumbnailMode) return QRect(); QRect iconsRect_ = iconsRect(option, index); int width = d->view->width() / 4; if (d->view->displayMode() == View::DetailedMode) { // In detailed mode the progress bar take 50% width on the right of the icons return QRect(option.rect.width() - width - d->margin, iconsRect_.top(), width, iconsRect_.height()) ; } else { // In minimal mode the progress bar take 50% width on the left of icons return QRect(iconsRect_.left() - width - d->margin , iconsRect_.top(), width, iconsRect_.height()); } }
void KisNodeDelegate::drawColorLabel(QPainter *p, const QStyleOptionViewItem &option, const QModelIndex &index) const { KisNodeViewColorScheme scm; const int label = index.data(KisNodeModel::ColorLabelIndexRole).toInt(); QColor color = scm.colorLabel(label); if (color.alpha() <= 0) return; QColor bgColor = qApp->palette().color(QPalette::Base); color = KritaUtils::blendColors(color, bgColor, 0.2); const QRect rect = option.state & QStyle::State_Selected ? iconsRect(option, index) : option.rect.adjusted(-scm.indentation(), 0, 0, 0); p->fillRect(rect, color); }
void KoDocumentSectionDelegate::drawIcons(QPainter *p, const QStyleOptionViewItem &option, const QModelIndex &index) const { const QRect r = iconsRect(option, index).translated(option.rect.topLeft()); p->save(); { p->setClipRect(r); p->translate(r.left(), r.top()); int x = 0; Model::PropertyList lp = index.data(Model::PropertiesRole).value<Model::PropertyList>(); for(int i = 0, n = lp.count(); i < n; ++i) { if (lp[i].isMutable) { QIcon icon = lp[i].state.toBool() ? lp[i].onIcon : lp[i].offIcon; p->drawPixmap(x, 0, icon.pixmap(option.decorationSize, (option.state & QStyle::State_Enabled) ? QIcon::Normal : QIcon::Disabled)); x += option.decorationSize.width() + d->margin; } } } p->restore(); }
void KisNodeDelegate::drawIcons(QPainter *p, const QStyleOptionViewItem &option, const QModelIndex &index) const { KisNodeViewColorScheme scm; const QRect r = iconsRect(option, index); QTransform oldTransform = p->transform(); QPen oldPen = p->pen(); p->setTransform(QTransform::fromTranslate(r.x(), r.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<KisBaseNode::PropertyList>(); QList<OptionalProperty> realProps = d->rightmostProperties(props); Q_FOREACH (OptionalProperty prop, realProps) { x += scm.iconMargin(); if (prop) { QIcon icon = prop->state.toBool() ? prop->onIcon : prop->offIcon; bool fullColor = prop->state.toBool() && option.state & QStyle::State_Enabled; const qreal oldOpacity = p->opacity(); // remember previous opacity if (fullColor) { p->setOpacity(1.0); } else { p->setOpacity(0.35); } p->drawPixmap(x, y, icon.pixmap(scm.iconSize(), QIcon::Normal)); p->setOpacity(oldOpacity); // restore old opacity } x += scm.iconSize() + scm.iconMargin(); p->drawLine(x, 0, x, scm.rowHeight() - scm.border()); x += scm.border(); }
QRect KoDocumentSectionDelegate::textRect(const QStyleOptionViewItem &option, const QModelIndex &index) const { if (d->view->displayMode() == View::ThumbnailMode) { const QRect r = decorationRect(option, index); const int left = r.right() + d->margin; return QRect(left, r.top(), option.rect.width() - left, textBoxHeight(option)); } else { static QFont f; static int minbearing = 1337 + 666; //can be 0 or negative, 2003 is less likely if (minbearing == 2003 || f != option.font) { f = option.font; //getting your bearings can be expensive, so we cache them minbearing = option.fontMetrics.minLeftBearing() + option.fontMetrics.minRightBearing(); } int indent = decorationRect(option, index).right() + d->margin; const int width = (d->view->displayMode() == View::DetailedMode ? option.rect.width() : iconsRect(option, index).left()) - indent - d->margin + minbearing; return QRect(indent, 0, width, textBoxHeight(option)); } }
bool KoDocumentSectionDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) { if ((event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonDblClick) && (index.flags() & Qt::ItemIsEnabled)) { QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event); const QRect iconsRect_ = iconsRect(option, index).translated(option.rect.topLeft()); if (iconsRect_.isValid() && iconsRect_.contains(mouseEvent->pos())) { const int iconWidth = option.decorationSize.width(); int xPos = mouseEvent->pos().x() - iconsRect_.left(); if (xPos % (iconWidth + d->margin) < iconWidth) { //it's on an icon, not a margin Model::PropertyList propertyList = index.data(Model::PropertiesRole).value<Model::PropertyList>(); int clickedProperty = -1; // Discover which of all properties was clicked for (int i = 0; i < propertyList.count(); ++i) { if (propertyList[i].isMutable) { xPos -= iconWidth + d->margin; } ++clickedProperty; if (xPos < 0) break; } // Using Ctrl+click to enter stasis if (mouseEvent->modifiers() == Qt::ControlModifier && propertyList[clickedProperty].canHaveStasis) { // STEP 0: Prepare to Enter or Leave control key stasis quint16 numberOfLeaves = model->rowCount(index.parent()); QModelIndex eachItem; // STEP 1: Go. if (propertyList[clickedProperty].isInStasis == false) { // Enter /* Make every leaf of this node go State = False, saving the old property value to stateInStasis */ for (quint16 i = 0; i < numberOfLeaves; ++i) { // Foreach leaf in the node (index.parent()) eachItem = model->index(i, 0, index.parent()); // The entire property list has to be altered because model->setData cannot set individual properties Model::PropertyList eachPropertyList = eachItem.data(Model::PropertiesRole).value<Model::PropertyList>(); eachPropertyList[clickedProperty].stateInStasis = eachPropertyList[clickedProperty].state.toBool(); eachPropertyList[clickedProperty].state = false; eachPropertyList[clickedProperty].isInStasis = true; model->setData(eachItem, QVariant::fromValue(eachPropertyList), Model::PropertiesRole); } /* Now set the current node's clickedProperty back to True, to save the user time (obviously, if the user is clicking one item with ctrl+click, he's interested in that item to have a True property value while the others are in stasis and set to False) */ // First refresh propertyList, otherwise old data will be saved back causing bugs propertyList = index.data(Model::PropertiesRole).value<Model::PropertyList>(); propertyList[clickedProperty].state = true; model->setData(index, QVariant::fromValue(propertyList), Model::PropertiesRole); } else { // Leave /* Make every leaf of this node go State = stateInStasis */ for (quint16 i = 0; i < numberOfLeaves; ++i) { eachItem = model->index(i, 0, index.parent()); // The entire property list has to be altered because model->setData cannot set individual properties Model::PropertyList eachPropertyList = eachItem.data(Model::PropertiesRole).value<Model::PropertyList>(); eachPropertyList[clickedProperty].state = eachPropertyList[clickedProperty].stateInStasis; eachPropertyList[clickedProperty].isInStasis = false; model->setData(eachItem, QVariant::fromValue(eachPropertyList), Model::PropertiesRole); } } } else { propertyList[clickedProperty].state = !propertyList[clickedProperty].state.toBool(); model->setData(index, QVariant::fromValue(propertyList), Model::PropertiesRole); } } return true; } if (mouseEvent->button() != Qt::LeftButton) { d->view->setCurrentIndex(index); return false; } } else if (event->type() == QEvent::ToolTip) { QHelpEvent *helpEvent = static_cast<QHelpEvent*>(event); d->tip.showTip(d->view, helpEvent->pos(), option, index); return true; } else if (event->type() == QEvent::Leave) { d->tip.hide(); } return false; }