// special thanks to Razor-qt developer Alec Moskvin(amoskvin) for providing the fix! void FolderItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const { Q_ASSERT(index.isValid()); FmFileInfo* file = static_cast<FmFileInfo*>(index.data(FolderModel::FileInfoRole).value<void*>()); bool isSymlink = file && fm_file_info_is_symlink(file); if(option.decorationPosition == QStyleOptionViewItem::Top || option.decorationPosition == QStyleOptionViewItem::Bottom) { painter->save(); painter->setClipRect(option.rect); QStyleOptionViewItemV4 opt = option; initStyleOption(&opt, index); opt.decorationAlignment = Qt::AlignHCenter|Qt::AlignTop; opt.displayAlignment = Qt::AlignTop|Qt::AlignHCenter; // draw the icon QIcon::Mode iconMode = iconModeFromState(opt.state); QPoint iconPos(opt.rect.x() + (opt.rect.width() - opt.decorationSize.width()) / 2, opt.rect.y()); QPixmap pixmap = opt.icon.pixmap(opt.decorationSize, iconMode); painter->drawPixmap(iconPos, pixmap); // draw some emblems for the item if needed // we only support symlink emblem at the moment if(isSymlink) painter->drawPixmap(iconPos, symlinkIcon_.pixmap(opt.decorationSize / 2, iconMode)); // draw the text // The text rect dimensions should be exactly as they were in sizeHint() QRectF textRect(opt.rect.x() - (gridSize_.width() - opt.rect.width()) / 2, opt.rect.y() + opt.decorationSize.height(), gridSize_.width(), gridSize_.height() - opt.decorationSize.height()); drawText(painter, opt, textRect); painter->restore(); } else { // let QStyledItemDelegate does its default painting QStyledItemDelegate::paint(painter, option, index); // draw emblems if needed if(isSymlink) { QStyleOptionViewItemV4 opt = option; initStyleOption(&opt, index); QIcon::Mode iconMode = iconModeFromState(opt.state); QPoint iconPos(opt.rect.x(), opt.rect.y() + (opt.rect.height() - opt.decorationSize.height()) / 2); // draw some emblems for the item if needed // we only support symlink emblem at the moment painter->drawPixmap(iconPos, symlinkIcon_.pixmap(opt.decorationSize / 2, iconMode)); } } }
// -------------------------------------------------------------------------------------------------------- void KIconButton::render () { glPushAttrib(GL_CURRENT_BIT | GL_LIGHTING_BIT); if (getFGColor()) getFGColor()->glColor(); KWidget::render(); KPosition iconPos(1, -size.h); switch (type) { case KDL_ICONBUTTON_CROSS: kDisplayXPMIcon (KDS_BUTTONICON_CROSS, iconPos); break; case KDL_ICONBUTTON_ARROW_UP: kDisplayXPMIcon (KDS_BUTTONICON_ARROW_UP, iconPos); break; case KDL_ICONBUTTON_ARROW_DOWN: kDisplayXPMIcon (KDS_BUTTONICON_ARROW_DOWN, iconPos); break; case KDL_ICONBUTTON_ARROW_LEFT: kDisplayXPMIcon (KDS_BUTTONICON_ARROW_LEFT, iconPos); break; case KDL_ICONBUTTON_ARROW_RIGHT: kDisplayXPMIcon (KDS_BUTTONICON_ARROW_RIGHT, iconPos); break; case KDL_ICONBUTTON_SINGLE_UP: kDisplayXPMIcon (KDS_BUTTONICON_UP, iconPos); break; case KDL_ICONBUTTON_SINGLE_DOWN: kDisplayXPMIcon (KDS_BUTTONICON_DOWN, iconPos); break; case KDL_ICONBUTTON_DOUBLE_UP: kDisplayXPMIcon (KDS_BUTTONICON_DOUBLE_UP, iconPos); break; case KDL_ICONBUTTON_DOUBLE_DOWN: kDisplayXPMIcon (KDS_BUTTONICON_DOUBLE_DOWN, iconPos); break; case KDL_ICONBUTTON_TOP: kDisplayXPMIcon (KDS_BUTTONICON_TOP, iconPos); break; case KDL_ICONBUTTON_BOTTOM: kDisplayXPMIcon (KDS_BUTTONICON_BOTTOM, iconPos); break; case KDL_ICONBUTTON_CLEAR: kDisplayXPMIcon (KDS_BUTTONICON_CLEAR, iconPos); break; default: break; }; glPopAttrib(); }
void WindowPreview::paintEvent(QPaintEvent *event) { Q_UNUSED(event) QPainter painter(this); // draw background (only when previews are used) if (m_previewSpace) { QPixmap backgroundPixmap; qreal normalLeft = 0, normalTop = 0, normalRight = 0, normalBottom = 0; // caching of the pixmap is done by the class FrameSvg m_background->setElementPrefix(NORMAL); m_background->getMargins(normalLeft, normalTop, normalRight, normalBottom); if (m_highlite.atBottom()) { backgroundPixmap = m_background->framePixmap(); } else if (m_highlite.atTop()) { m_background->setElementPrefix(HOVER); backgroundPixmap = m_background->framePixmap(); } else { QPixmap normal(m_background->framePixmap()); m_background->setElementPrefix(HOVER); QPixmap hover(m_background->framePixmap()); backgroundPixmap = Plasma::PaintUtils::transition(normal, hover, m_highlite.value()); } QRect spaceGeom(m_previewSpace->geometry()); QPoint backgroundPos( spaceGeom.left() + (spaceGeom.width() - m_previewSize.width()) / 2 - normalLeft, spaceGeom.top() + (spaceGeom.height() - m_previewSize.height()) / 2 - normalTop); painter.drawPixmap(backgroundPos, backgroundPixmap); // draw icon as fake preview for startup items if (m_task->type() == Task::StartupItem) { painter.drawPixmap(previewRect(0, 0), m_task->icon().pixmap(BIG_ICON_SIZE)); } } // draw icon QPixmap iconPixmap; QRect iconGeom(m_iconSpace->geometry()); QPointF iconPos( iconGeom.left() + (iconGeom.width() - m_icon.width()) * 0.5, iconGeom.top() + (iconGeom.height() - m_icon.height()) * 0.5); if (m_highlite.atBottom()) { iconPixmap = m_icon; } else if (m_highlite.atTop()) { iconPixmap = hoverIcon(); } else { iconPixmap = Plasma::PaintUtils::transition(m_icon, hoverIcon(), m_highlite.value()); } painter.drawPixmap(iconPos, iconPixmap); }
void UILayer::Update(float deltaTime) { Size visibleSize = Director::getInstance()->getVisibleSize(); Rect rect = uiSprites[uiLifeGauge]->getTextureRect(); float wide = uiSprites[uiLifeGauge]->getTexture()->getPixelsWide(); rect.size.width = wide * lifeRate; uiSprites[uiLifeGauge]->setTextureRect(rect); Point iconPos(visibleSize.width/2 - 302 + 604 * distRate, uiPositions[uiProgress].y); progIconSprite->setPosition(iconPos); }
void PopupButton::draw(NVGcontext* ctx) { if (!mEnabled && mPushed) mPushed = false; mPopup->setVisible(mPushed); Button::draw(ctx); auto icon = utf8(ENTYPO_ICON_CHEVRON_SMALL_RIGHT); NVGcolor textColor = mTextColor.w() == 0 ? mTheme->mTextColor : mTextColor; nvgFontSize(ctx, mTheme->mButtonFontSize * 1.5f); nvgFontFace(ctx, "icons"); nvgFillColor(ctx, mEnabled ? textColor : mTheme->mDisabledTextColor); nvgTextAlign(ctx, NVG_ALIGN_LEFT | NVG_ALIGN_MIDDLE); float iw = nvgTextBounds(ctx, 0, 0, icon.data(), nullptr, nullptr); Vector2f iconPos( mPos.x() + mSize.x() - iw - 8, mPos.y() + mSize.y() * 0.5f -1); nvgText(ctx, iconPos.x(), iconPos.y(), icon.data(), nullptr); }
void PopupButton::draw (NVGcontext * ctx) { if (!mEnabled && mPushed) mPushed = false; mPopup->setVisible (mPushed); Button::draw (ctx); if (mChevronIcon) { auto icon = utf8 (mChevronIcon); NVGcolor textColor = mTextColor.a == 0 ? mTheme->mTextColor : mTextColor; nvgFontSize (ctx, (mFontSize < 0 ? mTheme->mButtonFontSize : mFontSize) * 1.5f); nvgFontFace (ctx, "icons"); nvgFillColor (ctx, mEnabled ? textColor : mTheme->mDisabledTextColor); nvgTextAlign (ctx, NVG_ALIGN_LEFT | NVG_ALIGN_MIDDLE); float iw = nvgTextBounds (ctx, 0, 0, icon.data(), nullptr, nullptr); vec2 iconPos (mPos.x + mSize.x - iw - 8, mPos.y + mSize.y * 0.5f - 1); nvgText (ctx, iconPos.x, iconPos.y, icon.data(), nullptr); } }
void WebTabView::DrawContents(BView* owner, BRect frame, const BRect& updateRect, bool isFirst, bool isLast, bool isFront) { if (fController->CloseButtonsAvailable()) _DrawCloseButton(owner, frame, updateRect, isFirst, isLast, isFront); if (fIcon) { BRect iconBounds(0, 0, kIconSize - 1, kIconSize - 1); // clip to icon bounds, if they are smaller if (iconBounds.Contains(fIcon->Bounds())) iconBounds = fIcon->Bounds(); else { // Try to scale down the icon by an even factor so the // final size is between 14 and 18 pixel size. If this fails, // the icon will simply be displayed at 18x18. float scale = 2; while ((fIcon->Bounds().Width() + 1) / scale > kIconSize) scale *= 2; if ((fIcon->Bounds().Width() + 1) / scale >= kIconSize - 4 && (fIcon->Bounds().Height() + 1) / scale >= kIconSize - 4 && (fIcon->Bounds().Height() + 1) / scale <= kIconSize) { iconBounds.right = (fIcon->Bounds().Width() + 1) / scale - 1; iconBounds.bottom = (fIcon->Bounds().Height() + 1) / scale - 1; } } BPoint iconPos(frame.left + kIconInset - 1, frame.top + floorf((frame.Height() - iconBounds.Height()) / 2)); iconBounds.OffsetTo(iconPos); owner->SetDrawingMode(B_OP_ALPHA); owner->SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_OVERLAY); owner->DrawBitmap(fIcon, fIcon->Bounds(), iconBounds, B_FILTER_BITMAP_BILINEAR); owner->SetDrawingMode(B_OP_COPY); frame.left = frame.left + kIconSize + kIconInset * 2; } TabView::DrawContents(owner, frame, updateRect, isFirst, isLast, isFront); }
//------------------------------------------------------------------------ //! Appends the checkbox state images to the list control image list //! //! @param owner The list control adding column //! @param imagelist The image list assigned to the list control //! @return Image index where the two state images (unchecked/checked) was inserted //------------------------------------------------------------------------ int CGridColumnTraitImage::AppendStateImages(CGridListCtrlEx& owner, CImageList& imagelist) { if (!(owner.GetExtendedStyle() & LVS_EX_SUBITEMIMAGES)) owner.SetExtendedStyle(owner.GetExtendedStyle() | LVS_EX_SUBITEMIMAGES); if (!imagelist) imagelist.Create(16, 16, ILC_COLOR16 | ILC_MASK, 1, 0); if (!owner.GetImageList(LVSIL_SMALL)) owner.SetImageList(&imagelist, LVSIL_SMALL); VERIFY(owner.GetImageList(LVSIL_SMALL) == &imagelist); bool createdStateImages = false; CImageList* pStateList = owner.GetImageList(LVSIL_STATE); if (pStateList == NULL) { if (!(owner.GetExtendedStyle() & LVS_EX_CHECKBOXES)) { createdStateImages = true; owner.SetExtendedStyle(owner.GetExtendedStyle() | LVS_EX_CHECKBOXES); pStateList = owner.GetImageList(LVSIL_STATE); } } int imageCount = -1; ASSERT(pStateList != NULL); if (pStateList != NULL && pStateList->GetImageCount() >= 2) { imageCount = imagelist.GetImageCount(); // Get the icon size of current imagelist CSize iconSize(16, 16); if (imageCount > 0) { IMAGEINFO iconSizeInfo = { 0 }; VERIFY(imagelist.GetImageInfo(0, &iconSizeInfo)); iconSize = CSize(iconSizeInfo.rcImage.right - iconSizeInfo.rcImage.left, iconSizeInfo.rcImage.bottom - iconSizeInfo.rcImage.top); } // Scale the icon-position if necessary CPoint iconPos(1, 0); // +1 pixel to avoid overlap with left-grid-line { IMAGEINFO stateSizeInfo = { 0 }; VERIFY(pStateList->GetImageInfo(0, &stateSizeInfo)); int stateIconHeight = stateSizeInfo.rcImage.bottom - stateSizeInfo.rcImage.top; if (iconSize.cy > stateIconHeight) iconPos.y = (iconSize.cy - stateIconHeight) / 2; } // Redraw the state-icon to match the icon size of the current imagelist (without scaling image) CClientDC clienDC(&owner); CDC memDC; VERIFY(memDC.CreateCompatibleDC(&clienDC)); CBitmap dstBmp; VERIFY(dstBmp.CreateCompatibleBitmap(&clienDC, iconSize.cx, iconSize.cy)); CBitmap* pBmpOld = memDC.SelectObject(&dstBmp); COLORREF oldBkColor = pStateList->SetBkColor(imagelist.GetBkColor()); CBrush brush(imagelist.GetBkColor()); memDC.FillRect(CRect(0, 0, iconSize.cx, iconSize.cy), &brush); VERIFY(pStateList->Draw(&memDC, 0, iconPos, ILD_NORMAL)); memDC.SelectObject(pBmpOld); VERIFY(imagelist.Add(&dstBmp, oldBkColor) != -1); pBmpOld = memDC.SelectObject(&dstBmp); memDC.FillRect(CRect(0, 0, iconSize.cx, iconSize.cy), &brush); VERIFY(pStateList->Draw(&memDC, 1, iconPos, ILD_NORMAL)); memDC.SelectObject(pBmpOld); VERIFY(imagelist.Add(&dstBmp, oldBkColor) != -1); pStateList->SetBkColor(oldBkColor); } if (createdStateImages) owner.SetExtendedStyle(owner.GetExtendedStyle() & ~LVS_EX_CHECKBOXES); return imageCount; }
void CAknInputFrame::SizeChanged() { // There are 5 different layouts to be handled by this component: // -------------------------------------------------------------- // Standard ( fixed find pane in column lists ) // PopupLayout ( popup find pane in any mainpane list ) // PinbLayout ( used by pinboard app ) // ClockAppLayout ( has been removed from laf - fall back to standard ) // PopupWindowLayout ( used by list query and popuplist ) _AKNTRACE_FUNC_ENTER; TRect parent( Rect() ); // parent for components TRect editorParent( Rect() ); // parent for the editor TRect rect( Rect() ); // rect of the whole shebang TAknLayoutRect r; // common temporary layout rect TAknWindowComponentLayout outline(0); TAknWindowLineLayout iconPos(0); TAknTextComponentLayout editor(0); TBool apac( AknLayoutUtils::Variant() == EApacVariant && ( iFlags & EShowIndicators ) ); if ( iFlags & EPopupLayout ) // popup find box { _AKNTRACE( "[%s][%s] PopupLayout", "CAknInputFrame", __FUNCTION__ ); r.LayoutRect( parent, AknLayoutScalable_Avkon::find_popup_pane() ); parent = r.Rect(); r.LayoutRect( r.Rect(), AknLayoutScalable_Avkon::input_popup_find_pane_cp() ); editorParent = r.Rect(); outline = AknLayoutScalable_Avkon::input_popup_find_pane_cp(); iconPos = AknLayoutScalable_Avkon::find_popup_pane_g1().LayoutLine(); editor = AknLayoutScalable_Avkon::input_popup_find_pane_t1( apac ? 2 : 0 ); if ( iPopupFindCC ) { r.LayoutRect( rect, AknLayoutScalable_Avkon::find_popup_pane() ); iPopupFindCC->SetFrameRects( rect, r.Rect() ); } } else if ( iFlags & EPinbLayout ) // used by pinboard app { _AKNTRACE( "[%s][%s] PinbLayout", "CAknInputFrame", __FUNCTION__ ); outline = AknLayoutScalable_Apps::input_focus_pane_cp01(0); iconPos = AknLayoutScalable_Apps::find_pinb_pane_g1(0); editor = AknLayoutScalable_Apps::find_pinb_pane_t2( apac ? 1 : 0 ); } else if ( iFlags & EPopupWindowLayout ) // list query or popup list { _AKNTRACE( "[%s][%s] PopupWindowLayout", "CAknInputFrame", __FUNCTION__ ); outline = AknLayoutScalable_Avkon::input_popup_find_pane_cp(); iconPos = AknLayoutScalable_Avkon::find_popup_pane_g1(); TAknTextComponentLayout textComponentLayout( TAknWindowComponentLayout::ComposeText( outline, AknLayoutScalable_Avkon::input_popup_find_pane_t1( apac ? 2 : 0 ) ) ); editor = textComponentLayout; if ( iPopupListCC ) { iPopupListCC->SetRect( rect ); } } else // standard find pane { _AKNTRACE( "[%s][%s] Standard Layout", "CAknInputFrame", __FUNCTION__ ); outline = AknLayoutScalable_Avkon::input_find_pane(); iconPos = AknLayoutScalable_Avkon::find_pane_g1(); editor = AknLayoutScalable_Avkon::input_find_pane_t2( apac ? 1: 0 ); r.LayoutRect( rect, AknLayoutScalable_Avkon::input_find_pane() ); editorParent = r.Rect(); } // --- set size and position of the frame around editor --- r.LayoutRect( parent, outline ); iOutlineRect = r.Rect(); _AKNTRACE( "[%s][%s] iOutlineRect: %s:%d,%d %s:%d,%d", "CAknInputFrame", __FUNCTION__, "LT", iOutlineRect.iTl.iX, iOutlineRect.iTl.iY, "BR", iOutlineRect.iBr.iX, iOutlineRect.iBr.iY ); if ( !iInputContext ) { // we need to provide own context if one does not exist // because old style drawing did kind of work even // without calling SetInputContext( ... ) iInputContext = CAknsFrameBackgroundControlContext::NewL( KAknsIIDQsnFrInput, TRect(0,0,0,0), TRect(0,0,0,0), EFalse ); iFlags = iFlags | EOwnsInputContext; // also need to provide skin for the editor in this case static_cast<CEikEdwin*>( iField )->SetSkinBackgroundControlContextL( iInputContext ); } if ( iInputContext ) { // this layout is actually from form! // there exists no layout for find box :-/ but this should do // no help from adaptation layer either r.LayoutRect( iOutlineRect, AknLayoutScalable_Avkon::input_focus_pane_g1() ); iInputContext->SetFrameRects( iOutlineRect, r.Rect() ); // and chain transparent contexts properly MAknsControlContext* bg = iPopupFindCC ? iPopupFindCC : iPopupListCC; if( !bg ) { bg = AknsDrawUtils::ControlContext( this ); } iInputContext->SetParentContext( bg ); } // --- set magnifying glass icon size & position --- iMagnIconPos.LayoutRect( parent, iconPos); CFbsBitmap* iconBitmap = iIcon->Bitmap(); if ( iconBitmap ) { AknIconUtils::SetSize( iconBitmap, iMagnIconPos.Rect().Size() ); } // --- layout the editor --- AknLayoutUtils::LayoutEdwin( static_cast<CEikEdwin*>( iField ), editorParent, editor.LayoutLine(), EAknsCIQsnTextColorsCG25, 0, ETrue ); AknsUtils::RegisterControlPosition( iField ); // prevent flicker _AKNTRACE_FUNC_EXIT; }
void CollectionTreeItemDelegate::paint( QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index ) const { if( index.parent().isValid() ) // not a root item { QStyledItemDelegate::paint( painter, option, index ); return; } const bool isRTL = QApplication::isRightToLeft(); const QPoint topLeft = option.rect.topLeft(); const int width = m_view->viewport()->size().width() - 4; const int height = sizeHint( option, index ).height(); const int iconWidth = 32; const int iconHeight = 32; const int iconPadX = 4; const bool hasCapacity = index.data( CustomRoles::HasCapacityRole ).toBool(); const int actionCount = index.data( CustomRoles::DecoratorRoleCount ).toInt(); painter->save(); QApplication::style()->drawPrimitive( QStyle::PE_PanelItemViewItem, &option, painter ); if ( option.state & QStyle::State_Selected ) painter->setPen( App::instance()->palette().highlightedText().color() ); else painter->setPen( App::instance()->palette().text().color() ); painter->setRenderHint( QPainter::Antialiasing ); const int iconYPadding = ( height - iconHeight ) / 2; QPoint iconPos( topLeft + QPoint( iconPadX, iconYPadding ) ); if( isRTL ) iconPos.setX( width - iconWidth - iconPadX ); painter->drawPixmap( iconPos, index.data( Qt::DecorationRole ).value<QIcon>().pixmap( iconWidth, iconHeight ) ); QStyleOption expanderOption( option ); QStyle::PrimitiveElement expandedPrimitive; if( isRTL ) { expandedPrimitive = QStyle::PE_IndicatorArrowLeft; expanderOption.rect.setLeft( iconPadX ); } else { expandedPrimitive = QStyle::PE_IndicatorArrowRight; expanderOption.rect.setLeft( option.rect.right() - iconPadX - iconWidth ); } expanderOption.rect.setWidth( iconWidth ); //FIXME: CollectionTreeItemModelBase::hasChildren() returns true for root items regardless if( m_view->model()->hasChildren( index ) ) { if( m_view->isExpanded( index ) ) { QApplication::style()->drawPrimitive( QStyle::PE_IndicatorArrowDown, &expanderOption, painter ); } else { QApplication::style()->drawPrimitive( expandedPrimitive, &expanderOption, painter ); } } const QString collectionName = index.data( Qt::DisplayRole ).toString(); const QString bylineText = index.data( CustomRoles::ByLineRole ).toString(); const int actionsRectWidth = actionCount > 0 ? (ACTIONICON_SIZE * actionCount + 2*2/*margin*/) : 0; const int iconRight = topLeft.x() + iconWidth + iconPadX * 2; const int infoRectLeft = isRTL ? actionsRectWidth : iconRight; const int infoRectWidth = width - iconRight; const int titleRectWidth = infoRectWidth - actionsRectWidth; QRectF titleRect; titleRect.setLeft( infoRectLeft ); titleRect.setTop( option.rect.top() + iconYPadding ); titleRect.setWidth( titleRectWidth ); titleRect.setHeight( m_bigFm->boundingRect( collectionName ).height() ); painter->setFont( m_bigFont ); painter->drawText( titleRect, Qt::AlignLeft, collectionName ); const bool isHover = option.state & QStyle::State_MouseOver; QPoint cursorPos = m_view->mapFromGlobal( QCursor::pos() ); cursorPos.ry() -= 20; // Where the f**k does this offset come from. I have _ZERO_ idea. painter->setFont( m_smallFont ); // we want smaller font for both subtitle and capacity bar //show the bylinetext or the capacity (if available) when hovering if( isHover && hasCapacity ) { qreal bytesUsed = index.data( CustomRoles::UsedCapacityRole ).toReal(); qreal bytesTotal = index.data( CustomRoles::TotalCapacityRole ).toReal(); const int percentage = (bytesTotal > 0.0) ? qRound( 100.0 * bytesUsed / bytesTotal ) : 100; KCapacityBar capacityBar( KCapacityBar::DrawTextInline ); capacityBar.setValue( percentage ); capacityBar.setText( i18nc( "Example: 3.5 GB free (unit is part of %1)", "%1 free", KGlobal::locale()->formatByteSize( bytesTotal - bytesUsed, 1 ) ) ); QRect capacityRect; capacityRect.setLeft( isRTL ? 0 : infoRectLeft ); capacityRect.setTop( titleRect.bottom() ); //makeing sure capacity bar does not overlap expander capacityRect.setWidth( infoRectWidth - iconWidth ); capacityRect.setHeight( qBound( CAPACITYRECT_MIN_HEIGHT, capacityBar.minimumSizeHint().height(), CAPACITYRECT_MAX_HEIGHT ) ); capacityBar.drawCapacityBar( painter, capacityRect ); } else { QRectF textRect; textRect.setLeft( infoRectLeft ); textRect.setTop( titleRect.bottom() ); textRect.setWidth( titleRectWidth ); textRect.setHeight( m_smallFm->boundingRect( bylineText ).height() ); painter->drawText( textRect, Qt::TextWordWrap, bylineText ); } if( isHover && ( actionCount > 0 ) ) { const QList<QAction*> actions = index.data( CustomRoles::DecoratorRole ).value<QList<QAction*> >(); QRect decoratorRect; if( isRTL ) //actions should appear to the right of the expander decoratorRect.setLeft( expanderOption.rect.right() + iconPadX ); else //actions should appear left of the expander decoratorRect.setLeft( expanderOption.rect.left() - actionCount * ( ACTIONICON_SIZE + iconPadX ) ); decoratorRect.setTop( option.rect.top() + iconYPadding ); decoratorRect.setWidth( actionsRectWidth ); decoratorRect.setHeight( ACTIONICON_SIZE ); QPoint actionTopLeftBase = decoratorRect.topLeft(); const QSize iconSize = QSize( ACTIONICON_SIZE, ACTIONICON_SIZE ); int i = 0; foreach( QAction * action, actions ) { QIcon icon = action->icon(); int x = actionTopLeftBase.x() + i * ( ACTIONICON_SIZE + iconPadX ); QPoint actionTopLeft = QPoint( x, actionTopLeftBase.y() ); QRect iconRect( actionTopLeft, iconSize ); const bool isOver = isHover && iconRect.contains( cursorPos ); icon.paint( painter, iconRect, Qt::AlignCenter, isOver ? QIcon::Active : QIcon::Normal, isOver ? QIcon::On : QIcon::Off ); i++; } // Store the Model index for lookups for clicks. FAIL. QPersistentModelIndex persistentIndex( index ); s_indexDecoratorRects.insert( persistentIndex, decoratorRect ); }
void TextBox::draw(NVGcontext* ctx) { Widget::draw(ctx); NVGpaint bg = nvgBoxGradient(ctx, mPos.x() + 1, mPos.y() + 1 + 1.0f, mSize.x() - 2, mSize.y() - 2, 3, 4, Color(255, 32), Color(32, 32)); NVGpaint fg1 = nvgBoxGradient(ctx, mPos.x() + 1, mPos.y() + 1 + 1.0f, mSize.x() - 2, mSize.y() - 2, 3, 4, Color(150, 32), Color(32, 32)); NVGpaint fg2 = nvgBoxGradient(ctx, mPos.x() + 1, mPos.y() + 1 + 1.0f, mSize.x() - 2, mSize.y() - 2, 3, 4, nvgRGBA(255, 0, 0, 100), nvgRGBA(255, 0, 0, 50)); nvgBeginPath(ctx); nvgRoundedRect(ctx, mPos.x() + 1, mPos.y() + 1 + 1.0f, mSize.x() - 2, mSize.y() - 2, 3); if (mEditable && focused()) mValidFormat ? nvgFillPaint(ctx, fg1) : nvgFillPaint(ctx, fg2); else if (mSpinnable && mMouseDownPos.x() != -1) nvgFillPaint(ctx, fg1); else nvgFillPaint(ctx, bg); nvgFill(ctx); nvgBeginPath(ctx); nvgRoundedRect(ctx, mPos.x() + 0.5f, mPos.y() + 0.5f, mSize.x() - 1, mSize.y() - 1, 2.5f); nvgStrokeColor(ctx, Color(0, 48)); nvgStroke(ctx); nvgFontSize(ctx, fontSize()); nvgFontFace(ctx, "sans"); Vector2i drawPos(mPos.x(), mPos.y() + mSize.y() * 0.5f + 1); float xSpacing = mSize.y() * 0.3f; float unitWidth = 0; if (mUnitsImage > 0) { int w, h; nvgImageSize(ctx, mUnitsImage, &w, &h); float unitHeight = mSize.y() * 0.4f; unitWidth = w * unitHeight / h; NVGpaint imgPaint = nvgImagePattern( ctx, mPos.x() + mSize.x() - xSpacing - unitWidth, drawPos.y() - unitHeight * 0.5f, unitWidth, unitHeight, 0, mUnitsImage, mEnabled ? 0.7f : 0.35f); nvgBeginPath(ctx); nvgRect(ctx, mPos.x() + mSize.x() - xSpacing - unitWidth, drawPos.y() - unitHeight * 0.5f, unitWidth, unitHeight); nvgFillPaint(ctx, imgPaint); nvgFill(ctx); unitWidth += 2; } else if (!mUnits.empty()) { unitWidth = nvgTextBounds(ctx, 0, 0, mUnits.c_str(), nullptr, nullptr); nvgFillColor(ctx, Color(255, mEnabled ? 64 : 32)); nvgTextAlign(ctx, NVG_ALIGN_RIGHT | NVG_ALIGN_MIDDLE); nvgText(ctx, mPos.x() + mSize.x() - xSpacing, drawPos.y(), mUnits.c_str(), nullptr); unitWidth += 2; } float spinArrowsWidth = 0.f; if (mSpinnable && !focused()) { spinArrowsWidth = 14.f; nvgFontFace(ctx, "icons"); nvgFontSize(ctx, ((mFontSize < 0) ? mTheme->mButtonFontSize : mFontSize) * 1.2f); bool spinning = mMouseDownPos.x() != -1; { bool hover = mMouseFocus && spinArea(mMousePos) == SpinArea::Top; nvgFillColor(ctx, (mEnabled && (hover || spinning)) ? mTheme->mTextColor : mTheme->mDisabledTextColor); auto icon = utf8(ENTYPO_ICON_CHEVRON_UP); nvgTextAlign(ctx, NVG_ALIGN_LEFT | NVG_ALIGN_MIDDLE); Vector2f iconPos(mPos.x() + 4.f, mPos.y() + mSize.y()/2.f - xSpacing/2.f); nvgText(ctx, iconPos.x(), iconPos.y(), icon.data(), nullptr); } { bool hover = mMouseFocus && spinArea(mMousePos) == SpinArea::Bottom; nvgFillColor(ctx, (mEnabled && (hover || spinning)) ? mTheme->mTextColor : mTheme->mDisabledTextColor); auto icon = utf8(ENTYPO_ICON_CHEVRON_DOWN); nvgTextAlign(ctx, NVG_ALIGN_LEFT | NVG_ALIGN_MIDDLE); Vector2f iconPos(mPos.x() + 4.f, mPos.y() + mSize.y()/2.f + xSpacing/2.f + 1.5f); nvgText(ctx, iconPos.x(), iconPos.y(), icon.data(), nullptr); } nvgFontSize(ctx, fontSize()); nvgFontFace(ctx, "sans"); } switch (mAlignment) { case Alignment::Left: nvgTextAlign(ctx, NVG_ALIGN_LEFT | NVG_ALIGN_MIDDLE); drawPos.x() += xSpacing + spinArrowsWidth; break; case Alignment::Right: nvgTextAlign(ctx, NVG_ALIGN_RIGHT | NVG_ALIGN_MIDDLE); drawPos.x() += mSize.x() - unitWidth - xSpacing; break; case Alignment::Center: nvgTextAlign(ctx, NVG_ALIGN_CENTER | NVG_ALIGN_MIDDLE); drawPos.x() += mSize.x() * 0.5f; break; } nvgFontSize(ctx, fontSize()); nvgFillColor(ctx, mEnabled ? mTheme->mTextColor : mTheme->mDisabledTextColor); // clip visible text area float clipX = mPos.x() + xSpacing + spinArrowsWidth - 1.0f; float clipY = mPos.y() + 1.0f; float clipWidth = mSize.x() - unitWidth - spinArrowsWidth - 2 * xSpacing + 2.0f; float clipHeight = mSize.y() - 3.0f; nvgSave(ctx); nvgIntersectScissor(ctx, clipX, clipY, clipWidth, clipHeight); Vector2i oldDrawPos(drawPos); drawPos.x() += mTextOffset; if (mCommitted) { nvgText(ctx, drawPos.x(), drawPos.y(), mValue.c_str(), nullptr); } else { const int maxGlyphs = 1024; NVGglyphPosition glyphs[maxGlyphs]; float textBound[4]; nvgTextBounds(ctx, drawPos.x(), drawPos.y(), mValueTemp.c_str(), nullptr, textBound); float lineh = textBound[3] - textBound[1]; // find cursor positions int nglyphs = nvgTextGlyphPositions(ctx, drawPos.x(), drawPos.y(), mValueTemp.c_str(), nullptr, glyphs, maxGlyphs); updateCursor(ctx, textBound[2], glyphs, nglyphs); // compute text offset int prevCPos = mCursorPos > 0 ? mCursorPos - 1 : 0; int nextCPos = mCursorPos < nglyphs ? mCursorPos + 1 : nglyphs; float prevCX = cursorIndex2Position(prevCPos, textBound[2], glyphs, nglyphs); float nextCX = cursorIndex2Position(nextCPos, textBound[2], glyphs, nglyphs); if (nextCX > clipX + clipWidth) mTextOffset -= nextCX - (clipX + clipWidth) + 1; if (prevCX < clipX) mTextOffset += clipX - prevCX + 1; drawPos.x() = oldDrawPos.x() + mTextOffset; // draw text with offset nvgText(ctx, drawPos.x(), drawPos.y(), mValueTemp.c_str(), nullptr); nvgTextBounds(ctx, drawPos.x(), drawPos.y(), mValueTemp.c_str(), nullptr, textBound); // recompute cursor positions nglyphs = nvgTextGlyphPositions(ctx, drawPos.x(), drawPos.y(), mValueTemp.c_str(), nullptr, glyphs, maxGlyphs); if (mCursorPos > -1) { if (mSelectionPos > -1) { float caretx = cursorIndex2Position(mCursorPos, textBound[2], glyphs, nglyphs); float selx = cursorIndex2Position(mSelectionPos, textBound[2], glyphs, nglyphs); if (caretx > selx) std::swap(caretx, selx); // draw selection nvgBeginPath(ctx); nvgFillColor(ctx, nvgRGBA(255, 255, 255, 80)); nvgRect(ctx, caretx, drawPos.y() - lineh * 0.5f, selx - caretx, lineh); nvgFill(ctx); } float caretx = cursorIndex2Position(mCursorPos, textBound[2], glyphs, nglyphs); // draw cursor nvgBeginPath(ctx); nvgMoveTo(ctx, caretx, drawPos.y() - lineh * 0.5f); nvgLineTo(ctx, caretx, drawPos.y() + lineh * 0.5f); nvgStrokeColor(ctx, nvgRGBA(255, 192, 0, 255)); nvgStrokeWidth(ctx, 1.0f); nvgStroke(ctx); } } nvgRestore(ctx); }