/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ #include #include #include "thumbnailviewacc.hxx" #include #include #include #include #include #include #include #include #include #include #include using namespace basegfx; using namespace basegfx::utils; using namespace ::com::sun::star; using namespace drawinglayer::attribute; using namespace drawinglayer::primitive2d; ThumbnailViewItem::ThumbnailViewItem(ThumbnailViewBase &rView, sal_uInt16 nId) : mrParent(rView) , mnId(nId) , mbVisible(true) , mbSelected(false) , mbHover(false) , mxAcc() { } ThumbnailViewItem::~ThumbnailViewItem() { if( mxAcc.is() ) { static_cast< ThumbnailViewItemAcc* >( mxAcc.get() )->ParentDestroyed(); } } void ThumbnailViewItem::show (bool bVisible) { mbVisible = bVisible; } void ThumbnailViewItem::setSelection (bool state) { mbSelected = state; } void ThumbnailViewItem::setHighlight (bool state) { mbHover = state; } ::tools::Rectangle ThumbnailViewItem::updateHighlight(bool bVisible, const Point& rPoint) { bool bNeedsPaint = false; if (bVisible && getDrawArea().IsInside(rPoint)) { if (!isHighlighted()) bNeedsPaint = true; setHighlight(true); } else { if (isHighlighted()) bNeedsPaint = true; setHighlight(false); } if (bNeedsPaint) return getDrawArea(); return ::tools::Rectangle(); } void ThumbnailViewItem::setTitle (const OUString& rTitle) { if (mrParent.renameItem(this, rTitle)) maTitle = rTitle; } uno::Reference< accessibility::XAccessible > const & ThumbnailViewItem::GetAccessible( bool bIsTransientChildrenDisabled ) { if( !mxAcc.is() ) mxAcc = new ThumbnailViewItemAcc( this, bIsTransientChildrenDisabled ); return mxAcc; } void ThumbnailViewItem::setDrawArea (const ::tools::Rectangle &area) { maDrawArea = area; } void ThumbnailViewItem::calculateItemsPosition (const long nThumbnailHeight, const long nPadding, sal_uInt32 nMaxTextLength, const ThumbnailItemAttributes *pAttrs) { drawinglayer::primitive2d::TextLayouterDevice aTextDev; aTextDev.setFontAttribute(pAttrs->aFontAttr, pAttrs->aFontSize.getX(), pAttrs->aFontSize.getY(), css::lang::Locale() ); Size aRectSize = maDrawArea.GetSize(); Size aImageSize = maPreview1.GetSizePixel(); // Calculate thumbnail position Point aPos = maDrawArea.TopLeft(); aPos.setX( maDrawArea.getX() + (aRectSize.Width()-aImageSize.Width())/2 ); aPos.setY( maDrawArea.getY() + nPadding + (nThumbnailHeight-aImageSize.Height())/2 ); maPrev1Pos = aPos; // Calculate text position aPos.setY( maDrawArea.getY() + nThumbnailHeight + nPadding * 2 ); aPos.setX( maDrawArea.Left() + (aRectSize.Width() - aTextDev.getTextWidth(maTitle,0,nMaxTextLength))/2 ); maTextPos = aPos; } void ThumbnailViewItem::Paint (drawinglayer::processor2d::BaseProcessor2D *pProcessor, const ThumbnailItemAttributes *pAttrs) { BColor aFillColor = pAttrs->aFillColor; drawinglayer::primitive2d::Primitive2DContainer aSeq(4); double fTransparence = 0.0; // Draw background if( mbSelected && mbHover) aFillColor = pAttrs->aSelectHighlightColor; else if (mbSelected || mbHover) aFillColor = pAttrs->aHighlightColor; if (mbHover) fTransparence = pAttrs->fHighlightTransparence; sal_uInt32 nPrimitive = 0; aSeq[nPrimitive++] = drawinglayer::primitive2d::Primitive2DReference( new PolyPolygonSelectionPrimitive2D( B2DPolyPolygon(::tools::Polygon(maDrawArea, THUMBNAILVIEW_ITEM_CORNER, THUMBNAILVIEW_ITEM_CORNER).getB2DPolygon()), aFillColor, fTransparence, 0.0, true)); // Draw thumbnail Point aPos = maPrev1Pos; Size aImageSize = maPreview1.GetSizePixel(); aSeq[nPrimitive++] = drawinglayer::primitive2d::Primitive2DReference( new FillGraphicPrimitive2D( createTranslateB2DHomMatrix(aPos.X(),aPos.Y()), FillGraphicAttribute(Graphic(maPreview1), B2DRange( B2DPoint(0,0), B2DPoint(aImageSize.Width(),aImageSize.Height())), false) )); // draw thumbnail borders float fWidth = aImageSize.Width() - 1; float fHeight = aImageSize.Height() - 1; float fPosX = maPrev1Pos.getX(); float fPosY = maPrev1Pos.getY(); B2DPolygon aBounds; aBounds.append(B2DPoint(fPosX,fPosY)); aBounds.append(B2DPoint(fPosX+fWidth,fPosY)); aBounds.append(B2DPoint(fPosX+fWidth,fPosY+fHeight)); aBounds.append(B2DPoint(fPosX,fPosY+fHeight)); aBounds.setClosed(true); aSeq[nPrimitive++] = drawinglayer::primitive2d::Primitive2DReference(createBorderLine(aBounds)); // Draw text below thumbnail addTextPrimitives(maTitle, pAttrs, maTextPos, aSeq); pProcessor->process(aSeq); } void ThumbnailViewItem::addTextPrimitives (const OUString& rText, const ThumbnailItemAttributes *pAttrs, Point aPos, drawinglayer::primitive2d::Primitive2DContainer& rSeq) { // adjust text drawing position according to text font drawinglayer::primitive2d::TextLayouterDevice aTextDev; aTextDev.setFontAttribute( pAttrs->aFontAttr, pAttrs->aFontSize.getX(), pAttrs->aFontSize.getY(), css::lang::Locale()); aPos.setY(aPos.getY() + aTextDev.getTextHeight()); OUString aText (rText); TextEngine aTextEngine; aTextEngine.SetMaxTextWidth(maDrawArea.getWidth()); aTextEngine.SetText(rText); sal_Int32 nPrimitives = rSeq.size(); rSeq.resize(nPrimitives + aTextEngine.GetLineCount(0)); // Create the text primitives sal_uInt16 nLineStart = 0; for (sal_uInt16 i=0; i < aTextEngine.GetLineCount(0); ++i) { sal_Int32 nLineLength = aTextEngine.GetLineLen(0, i); double nLineWidth = aTextDev.getTextWidth (aText, nLineStart, nLineLength); bool bTooLong = (aPos.getY() + aTextEngine.GetCharHeight()) > maDrawArea.Bottom(); if (bTooLong && (nLineLength + nLineStart) < rText.getLength()) { // Add the '...' to the last line to show, even though it may require to shorten the line double nDotsWidth = aTextDev.getTextWidth("...",0,3); sal_Int32 nLength = nLineLength - 1; while ( nDotsWidth + aTextDev.getTextWidth(aText, nLineStart, nLength) > maDrawArea.getWidth() && nLength > 0) { --nLength; } aText = aText.copy(0, nLineStart+nLength) + "..."; nLineLength = nLength + 3; } double nLineX = maDrawArea.Left() + (maDrawArea.getWidth() - nLineWidth) / 2.0; basegfx::B2DHomMatrix aTextMatrix( createScaleTranslateB2DHomMatrix( pAttrs->aFontSize.getX(), pAttrs->aFontSize.getY(), nLineX, double( aPos.Y() ) ) ); // setup color BColor aTextColor = pAttrs->aTextColor; if( mbSelected && mbHover) aTextColor = pAttrs->aSelectHighlightTextColor; else if (mbSelected || mbHover) aTextColor = pAttrs->aHighlightTextColor; rSeq[nPrimitives++] = drawinglayer::primitive2d::Primitive2DReference( new TextSimplePortionPrimitive2D(aTextMatrix, aText, nLineStart, nLineLength, std::vector(), pAttrs->aFontAttr, css::lang::Locale(), aTextColor)); nLineStart += nLineLength; aPos.setY(aPos.getY() + aTextEngine.GetCharHeight()); if (bTooLong) break; } } drawinglayer::primitive2d::PolygonHairlinePrimitive2D* ThumbnailViewItem::createBorderLine (const basegfx::B2DPolygon& rPolygon) { return new PolygonHairlinePrimitive2D(rPolygon, Color(128, 128, 128).getBColor()); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */