renaissance1: #i107215# Improved handling of transferables.

This commit is contained in:
Andre Fischer
2010-03-08 11:34:08 +01:00
parent c87f10322a
commit 4b83a7fe57
35 changed files with 1496 additions and 1903 deletions

View File

@@ -46,12 +46,12 @@
#include "controller/SlsScrollBarManager.hxx"
#include "controller/SlsSelectionManager.hxx"
#include "controller/SlsSlotManager.hxx"
#include "controller/SlsTransferable.hxx"
#include "model/SlideSorterModel.hxx"
#include "model/SlsPageEnumerationProvider.hxx"
#include "model/SlsPageDescriptor.hxx"
#include "view/SlideSorterView.hxx"
#include "view/SlsLayouter.hxx"
#include "view/SlsViewOverlay.hxx"
#include "view/SlsFontProvider.hxx"
#include "view/SlsPageObjectLayouter.hxx"
#include "view/SlsPageObjectPainter.hxx"
@@ -209,6 +209,7 @@ SlideSorterController::~SlideSorterController (void)
void SlideSorterController::Dispose (void)
{
mpInsertionIndicatorHandler->End();
mpSelectionManager.reset();
mpAnimator->Dispose();
}
@@ -439,11 +440,12 @@ bool SlideSorterController::Command (
// When there is no selection, then we show the insertion
// indicator so that the user knows where a page insertion
// would take place.
GetInsertionIndicatorHandler()->Start(
GetInsertionIndicatorHandler()->Start(false);
GetInsertionIndicatorHandler()->UpdatePosition(
pWindow->PixelToLogic(rEvent.GetMousePosPixel()),
InsertionIndicatorHandler::MoveMode,
false);
GetInsertionIndicatorHandler()->UpdateIndicatorIcon();
InsertionIndicatorHandler::MoveMode);
GetInsertionIndicatorHandler()->UpdateIndicatorIcon(
dynamic_cast<Transferable*>(SD_MOD()->pTransferClip));
}
pWindow->ReleaseMouse();
@@ -786,6 +788,9 @@ Rectangle SlideSorterController::Rearrange (bool bForce)
{
Rectangle aNewContentArea (maTotalWindowArea);
if (aNewContentArea.IsEmpty())
return aNewContentArea;
SharedSdWindow pWindow (mrSlideSorter.GetContentWindow());
if (pWindow)
{
@@ -812,6 +817,9 @@ Rectangle SlideSorterController::Rearrange (bool bForce)
// Adapt the scroll bars to the new zoom factor of the browser
// window and the arrangement of the page objects.
GetScrollBarManager().UpdateScrollBars(false, !bForce);
// When there is a selection then keep it in the visible area.
GetSelectionManager()->MakeSelectionVisible();
}
return aNewContentArea;
@@ -845,7 +853,7 @@ void SlideSorterController::SetZoom (long int nZoom)
nZoom = 1;
{
SlideSorterView::DrawLock aLock (mrView);
SlideSorterView::DrawLock aLock (mrSlideSorter);
mrView.GetLayouter().SetZoom(nZoom/100.0);
mrView.Layout();
GetScrollBarManager().UpdateScrollBars (false);

View File

@@ -212,6 +212,25 @@ void Animator::RemoveAnimation (const Animator::AnimationId nId)
void Animator::RemoveAllAnimations (void)
{
::std::for_each(
maAnimations.begin(),
maAnimations.end(),
::boost::bind(
&Animation::Expire,
_1));
maAnimations.clear();
mnNextAnimationId = 0;
// No more animations => we do not have to suppress painting
// anymore.
mpDrawLock.reset();
}
bool Animator::ProcessAnimations (const double nTime)
{
bool bExpired (false);

View File

@@ -38,7 +38,6 @@
#include "model/SlsPageDescriptor.hxx"
#include "model/SlsPageEnumerationProvider.hxx"
#include "view/SlideSorterView.hxx"
#include "view/SlsViewOverlay.hxx"
#include "controller/SlideSorterController.hxx"
#include "controller/SlsInsertionIndicatorHandler.hxx"
#include "controller/SlsPageSelector.hxx"
@@ -47,7 +46,8 @@
#include "controller/SlsScrollBarManager.hxx"
#include "controller/SlsFocusManager.hxx"
#include "controller/SlsSelectionManager.hxx"
#include "SlsTransferable.hxx"
#include "controller/SlsTransferable.hxx"
#include "cache/SlsPageCache.hxx"
#include "ViewShellBase.hxx"
#include "DrawViewShell.hxx"
@@ -363,21 +363,40 @@ void Clipboard::CreateSlideTransferable (
maPagesToRemove.push_back (pDescriptor->GetPage());
}
// Create a small set of representatives of the selection for which
// previews are included into the transferable so that an insertion
// indicator can be rendered.
aSelectedPages.Rewind();
::std::vector<Bitmap> aRepresentatives;
aRepresentatives.reserve(3);
::boost::shared_ptr<cache::PageCache> pPreviewCache (
mrSlideSorter.GetView().GetPreviewCache());
while (aSelectedPages.HasMoreElements())
{
model::SharedPageDescriptor pDescriptor (aSelectedPages.GetNextElement());
if ( ! pDescriptor || pDescriptor->GetPage()==NULL)
continue;
Bitmap aPreview (pPreviewCache->GetPreviewBitmap(pDescriptor->GetPage()).GetBitmap());
aRepresentatives.push_back(aPreview);
if (aRepresentatives.size() >= 3)
break;
}
if (aBookmarkList.Count() > 0)
{
mrSlideSorter.GetView().BrkAction();
SdDrawDocument* pDocument = mrSlideSorter.GetModel().GetDocument();
::boost::shared_ptr<SubstitutionHandler> pSubstitutionHandler;
::boost::shared_ptr<DragAndDropContext> pDragAndDropContext;
::rtl::Reference<SelectionFunction> pSelectionFunction (
mrSlideSorter.GetController().GetCurrentSelectionFunction());
if (pSelectionFunction.is())
pSubstitutionHandler = pSelectionFunction->GetSubstitutionHandler();
pDragAndDropContext = pSelectionFunction->GetDragAndDropContext();
SdTransferable* pTransferable = new Transferable (
pDocument,
NULL,
FALSE,
dynamic_cast<SlideSorterViewShell*>(mrSlideSorter.GetViewShell()),
pSubstitutionHandler);
aRepresentatives);
if (bDrag)
SD_MOD()->pTransferDrag = pTransferable;
@@ -540,11 +559,9 @@ sal_Int8 Clipboard::AcceptDrop (
// Show the insertion marker and the substitution for a drop.
Point aPosition = pTargetWindow->PixelToLogic (rEvent.maPosPixel);
view::ViewOverlay& rOverlay (mrSlideSorter.GetView().GetOverlay());
mrController.GetInsertionIndicatorHandler()->UpdatePosition(
aPosition,
rEvent.maDragEvent.DropAction);
rOverlay.GetSubstitutionOverlay()->SetPosition(aPosition);
// Scroll the window when the mouse reaches the window border.
// mrController.GetScrollBarManager().AutoScroll (rEvent.maPosPixel);
@@ -629,7 +646,7 @@ sal_Int8 Clipboard::ExecuteDrop (
else
{
// Handle a general drop operation.
HandlePageDrop (*pDragTransferable);
HandlePageDrop(*pDragTransferable);
nResult = rEvent.mnAction;
}
}

View File

@@ -51,8 +51,10 @@ using namespace ::com::sun::star::uno;
using namespace ::sd::slidesorter::model;
namespace sd { namespace slidesorter { namespace controller {
CurrentSlideManager::CurrentSlideManager (SlideSorter& rSlideSorter)
: mrSlideSorter(rSlideSorter),
mnCurrentSlideIndex(-1),

View File

@@ -6,9 +6,6 @@
*
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: SlsSelectionFunction.cxx,v $
* $Revision: 1.37 $
*
* This file is part of OpenOffice.org.
*
* OpenOffice.org is free software: you can redistribute it and/or modify
@@ -30,59 +27,98 @@
#include "precompiled_sd.hxx"
#include "SlsSubstitutionHandler.hxx"
#include "SlsDragAndDropContext.hxx"
#include "SlideSorter.hxx"
#include "model/SlideSorterModel.hxx"
#include "model/SlsPageEnumerationProvider.hxx"
#include "view/SlideSorterView.hxx"
#include "view/SlsViewOverlay.hxx"
#include "controller/SlideSorterController.hxx"
#include "controller/SlsInsertionIndicatorHandler.hxx"
#include "controller/SlsScrollBarManager.hxx"
#include "controller/SlsProperties.hxx"
#include "controller/SlsSelectionFunction.hxx"
#include "controller/SlsSelectionManager.hxx"
#include "controller/SlsTransferable.hxx"
#include "DrawDocShell.hxx"
#include "DrawDoc.hxx"
#include "app.hrc"
#include <sfx2/bindings.hxx>
#include <boost/bind.hpp>
namespace sd { namespace slidesorter { namespace controller {
SubstitutionHandler::SubstitutionHandler (
DragAndDropContext::DragAndDropContext (
SlideSorter& rSlideSorter,
const model::SharedPageDescriptor& rpHitDescriptor,
const Point& rMouseModelPosition)
const Transferable* pTransferable)
: mpTargetSlideSorter(&rSlideSorter),
mpHitDescriptor(rpHitDescriptor),
mnInsertionIndex(-1)
{
::std::vector<const SdPage*> aPages;
// No Drag-and-Drop for master pages.
if (rSlideSorter.GetModel().GetEditMode() != EM_PAGE)
return;
view::ViewOverlay& rOverlay (rSlideSorter.GetView().GetOverlay());
rSlideSorter.GetController().GetInsertionIndicatorHandler()->UpdateIndicatorIcon(
dynamic_cast<Transferable*>(SD_MOD()->pTransferDrag));
}
if ( ! rOverlay.GetSubstitutionOverlay()->IsVisible())
void DragAndDropContext::GetPagesFromBookmarks (
::std::vector<const SdPage*>& rPages,
sal_Int32& rnSelectionCount,
DrawDocShell* pDocShell,
const List& rBookmarks) const
{
if (pDocShell == NULL)
return;
const SdDrawDocument* pDocument = pDocShell->GetDoc();
if (pDocument == NULL)
return;
for (ULONG nIndex=0,nCount=rBookmarks.Count(); nIndex<nCount; ++nIndex)
{
// Show a new substitution for the selected page objects.
model::PageEnumeration aSelectedPages(
model::PageEnumerationProvider::CreateSelectedPagesEnumeration(
rSlideSorter.GetModel()));
rOverlay.GetSubstitutionOverlay()->SetIsVisible(true);
rSlideSorter.GetController().GetInsertionIndicatorHandler()->Start(
rMouseModelPosition,
InsertionIndicatorHandler::MoveMode,
true);
rSlideSorter.GetController().GetInsertionIndicatorHandler()->UpdateIndicatorIcon(
aSelectedPages);
const String sPageName (*static_cast<String*>(rBookmarks.GetObject(nIndex)));
BOOL bIsMasterPage (FALSE);
const USHORT nPageIndex (pDocument->GetPageByName(sPageName, bIsMasterPage));
if (nPageIndex == SDRPAGE_NOTFOUND)
continue;
const SdPage* pPage = dynamic_cast<const SdPage*>(pDocument->GetPage(nPageIndex));
if (pPage != NULL)
rPages.push_back(pPage);
}
rnSelectionCount = rBookmarks.Count();
}
void DragAndDropContext::GetPagesFromSelection (
::std::vector<const SdPage*>& rPages,
sal_Int32& rnSelectionCount,
model::PageEnumeration& rSelection) const
{
// Show a new substitution for the selected page objects.
rnSelectionCount = 0;
while (rSelection.HasMoreElements())
{
model::SharedPageDescriptor pDescriptor (rSelection.GetNextElement());
if (rPages.size() < 3)
rPages.push_back(pDescriptor->GetPage());
++rnSelectionCount;
}
}
SubstitutionHandler::~SubstitutionHandler (void)
DragAndDropContext::~DragAndDropContext (void)
{
if (mpTargetSlideSorter != NULL)
mpTargetSlideSorter->GetController().GetScrollBarManager().StopAutoScroll();
@@ -91,18 +127,14 @@ SubstitutionHandler::~SubstitutionHandler (void)
if (mpTargetSlideSorter != NULL)
{
view::ViewOverlay& rOverlay (mpTargetSlideSorter->GetView().GetOverlay());
rOverlay.GetSubstitutionOverlay()->SetIsVisible(false);
rOverlay.GetSubstitutionOverlay()->Clear();
mpTargetSlideSorter->GetController().GetInsertionIndicatorHandler()->End();
}
mpHitDescriptor.reset();
}
void SubstitutionHandler::Dispose (void)
void DragAndDropContext::Dispose (void)
{
mnInsertionIndex = -1;
}
@@ -110,7 +142,7 @@ void SubstitutionHandler::Dispose (void)
void SubstitutionHandler::UpdatePosition (
void DragAndDropContext::UpdatePosition (
const Point& rMousePosition,
const InsertionIndicatorHandler::Mode eMode,
const bool bAllowAutoScroll)
@@ -126,39 +158,28 @@ void SubstitutionHandler::UpdatePosition (
// constant while scrolling.)
SharedSdWindow pWindow (mpTargetSlideSorter->GetContentWindow());
const Point aMouseModelPosition (pWindow->PixelToLogic(rMousePosition));
::boost::shared_ptr<InsertionIndicatorHandler> pInsertionIndicatorHandler (
mpTargetSlideSorter->GetController().GetInsertionIndicatorHandler());
if ( ! (bAllowAutoScroll
&& mpTargetSlideSorter->GetController().GetScrollBarManager().AutoScroll(
rMousePosition,
::boost::bind(
&SubstitutionHandler::UpdatePosition,
this,
rMousePosition,
eMode,
false))))
rMousePosition,
::boost::bind(
&DragAndDropContext::UpdatePosition, this, rMousePosition, eMode, false))))
{
view::ViewOverlay& rOverlay (mpTargetSlideSorter->GetView().GetOverlay());
// Move the existing substitution to the new position.
rOverlay.GetSubstitutionOverlay()->SetPosition(aMouseModelPosition);
mpTargetSlideSorter->GetController().GetInsertionIndicatorHandler()->UpdatePosition(
aMouseModelPosition,
eMode);
pInsertionIndicatorHandler->UpdatePosition(aMouseModelPosition, eMode);
// Remember the new insertion index.
if (mpTargetSlideSorter->GetController().GetInsertionIndicatorHandler()->IsInsertionTrivial(eMode))
mnInsertionIndex = pInsertionIndicatorHandler->GetInsertionPageIndex();
if (pInsertionIndicatorHandler->IsInsertionTrivial(mnInsertionIndex, eMode))
mnInsertionIndex = -1;
else
mnInsertionIndex = mpTargetSlideSorter->GetController().GetInsertionIndicatorHandler()
->GetInsertionPageIndex();
}
}
void SubstitutionHandler::Process (void)
void DragAndDropContext::Process (void)
{
if (mpTargetSlideSorter == NULL)
return;
@@ -183,31 +204,21 @@ void SubstitutionHandler::Process (void)
void SubstitutionHandler::Show (void)
void DragAndDropContext::Show (void)
{
if (mpTargetSlideSorter != NULL)
{
view::ViewOverlay& rOverlay (mpTargetSlideSorter->GetView().GetOverlay());
rOverlay.GetSubstitutionOverlay()->SetIsVisible(true);
}
}
void SubstitutionHandler::Hide (void)
void DragAndDropContext::Hide (void)
{
if (mpTargetSlideSorter != NULL)
{
view::ViewOverlay& rOverlay (mpTargetSlideSorter->GetView().GetOverlay());
rOverlay.GetSubstitutionOverlay()->SetIsVisible(false);
}
}
void SubstitutionHandler::SetTargetSlideSorter (
void DragAndDropContext::SetTargetSlideSorter (
SlideSorter* pSlideSorter,
const Point aMousePosition,
const InsertionIndicatorHandler::Mode eMode,
@@ -223,9 +234,11 @@ void SubstitutionHandler::SetTargetSlideSorter (
if (mpTargetSlideSorter != NULL)
{
mpTargetSlideSorter->GetController().GetInsertionIndicatorHandler()->Start(
aMousePosition,
eMode,
bIsOverSourceView);
mpTargetSlideSorter->GetController().GetInsertionIndicatorHandler()->UpdatePosition(
aMousePosition,
eMode);
}
}

View File

@@ -6,9 +6,6 @@
*
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: SlsSelectionFunction.cxx,v $
* $Revision: 1.37 $
*
* This file is part of OpenOffice.org.
*
* OpenOffice.org is free software: you can redistribute it and/or modify
@@ -34,8 +31,9 @@
#include <tools/gen.hxx>
#include "model/SlsSharedPageDescriptor.hxx"
#include "view/SlsViewOverlay.hxx"
#include "controller/SlsInsertionIndicatorHandler.hxx"
#include <vector>
namespace sd { namespace slidesorter {
class SlideSorter;
@@ -45,27 +43,27 @@ class SlideSorter;
namespace sd { namespace slidesorter { namespace controller {
class Transferable;
/** A SubstitutionHandler object handles the display of a number of selected
slides at the mouse position and the insertion or (with or without
removing the pages at their original position) when the object is
destoyed.
/** A DragAndDropContext object handles an active drag and drop operation.
When the mouse is moved from one slide sorter window to another the
target SlideSorter object is exchanged accordingly.
*/
class SubstitutionHandler
class DragAndDropContext
{
public:
/** Create a substitution display of the currently selected pages and
use the given position as the anchor point.
/** Create a substitution display of the currently selected pages or,
when provided, the pages in the transferable.
*/
SubstitutionHandler (
DragAndDropContext (
SlideSorter& rSlideSorter,
const model::SharedPageDescriptor& rpHitDescriptor,
const Point& rMouseModelPosition);
~SubstitutionHandler (void);
const Transferable* pTransferable);
~DragAndDropContext (void);
/** Call this method (for example as reaction to ESC key press) to avoid
processing (ie moving or inserting) the substition when the called
SubstitutionHandler object is destroyed.
DragAndDropContext object is destroyed.
*/
void Dispose (void);
@@ -91,6 +89,16 @@ private:
model::SharedPageDescriptor mpHitDescriptor;
sal_Int32 mnInsertionIndex;
void GetPagesFromBookmarks (
::std::vector<const SdPage*>& rPages,
sal_Int32& rnSelectionCount,
DrawDocShell* pDocShell,
const List& rBookmarks) const;
void GetPagesFromSelection (
::std::vector<const SdPage*>& rPages,
sal_Int32& rnSelectionCount,
model::PageEnumeration& rSelection) const;
/** Move the substitution display of the currently selected pages.
*/
void Process (void);

View File

@@ -33,8 +33,8 @@
#include "controller/SlsInsertionIndicatorHandler.hxx"
#include "controller/SlsProperties.hxx"
#include "view/SlideSorterView.hxx"
#include "view/SlsViewOverlay.hxx"
#include "view/SlsLayouter.hxx"
#include "view/SlsInsertionIndicatorOverlay.hxx"
#include "model/SlideSorterModel.hxx"
#include "model/SlsPageEnumerationProvider.hxx"
#include <com/sun/star/datatransfer/dnd/DNDConstants.hpp>
@@ -49,10 +49,8 @@ namespace sd { namespace slidesorter { namespace controller {
InsertionIndicatorHandler::InsertionIndicatorHandler (SlideSorter& rSlideSorter)
: mrSlideSorter(rSlideSorter),
mpInsertAnimator(),
mpInsertionIndicatorOverlay(
mrSlideSorter.GetView().GetOverlay().GetInsertionIndicatorOverlay()),
mnInsertionIndex(-1),
maVisualInsertionIndices(-1,-1),
mpInsertionIndicatorOverlay(new view::InsertionIndicatorOverlay(rSlideSorter)),
maInsertPosition(),
meMode(MoveMode),
mbIsActive(false),
mbIsReadOnly(mrSlideSorter.GetModel().IsReadOnly()),
@@ -71,10 +69,7 @@ InsertionIndicatorHandler::~InsertionIndicatorHandler (void)
void InsertionIndicatorHandler::Start (
const Point& rMouseModelPosition,
const Mode eMode,
const bool bIsOverSourceView)
void InsertionIndicatorHandler::Start (const bool bIsOverSourceView)
{
if (mbIsActive)
{
@@ -85,8 +80,6 @@ void InsertionIndicatorHandler::Start (
if (mbIsReadOnly)
return;
SetPosition(rMouseModelPosition, eMode);
mbIsActive = true;
mbIsOverSourceView = bIsOverSourceView;
}
@@ -94,19 +87,27 @@ void InsertionIndicatorHandler::Start (
void InsertionIndicatorHandler::UpdateIndicatorIcon (
model::PageEnumeration& rEnumeration)
void InsertionIndicatorHandler::End (void)
{
mpInsertionIndicatorOverlay->Create(rEnumeration);
maIconSize = mpInsertionIndicatorOverlay->GetSize();
if ( ! mbIsActive)
return;
if (mbIsReadOnly)
return;
GetInsertAnimator()->Reset();
mbIsActive = false;
mpInsertionIndicatorOverlay->Hide();
}
void InsertionIndicatorHandler::UpdateIndicatorIcon (void)
void InsertionIndicatorHandler::UpdateIndicatorIcon (const Transferable* pTransferable)
{
mpInsertionIndicatorOverlay->Create();
mpInsertionIndicatorOverlay->Create(pTransferable);
maIconSize = mpInsertionIndicatorOverlay->GetSize();
}
@@ -152,24 +153,6 @@ void InsertionIndicatorHandler::UpdatePosition (
void InsertionIndicatorHandler::End (void)
{
if ( ! mbIsActive)
return;
if (mbIsReadOnly)
return;
GetInsertAnimator()->SetInsertPosition(-1, Pair(-1,-1), Size(0,0));
mbIsActive = false;
mpInsertionIndicatorOverlay->SetIsVisible(false);
GetInsertAnimator()->Reset();
}
bool InsertionIndicatorHandler::IsActive (void) const
{
return mbIsActive;
@@ -183,7 +166,7 @@ sal_Int32 InsertionIndicatorHandler::GetInsertionPageIndex (void) const
if (mbIsReadOnly)
return -1;
else
return mnInsertionIndex;
return maInsertPosition.GetIndex();
}
@@ -197,54 +180,31 @@ void InsertionIndicatorHandler::SetPosition (
view::Layouter& rLayouter (mrSlideSorter.GetView().GetLayouter());
USHORT nPageCount ((USHORT)mrSlideSorter.GetModel().GetPageCount());
sal_Int32 nInsertionIndex (mnInsertionIndex);
Pair aVisualInsertionIndices (maVisualInsertionIndices);
if (rLayouter.GetColumnCount() == 1)
{
// Pages are placed in a single column. Insertion indicator is
// placed between rows.
nInsertionIndex = rLayouter.GetVerticalInsertionIndex(rPoint);
aVisualInsertionIndices = Pair(nInsertionIndex, -1);
}
else
{
// Pages are placed in a grid. Insertion indicator is placed
// between columns.
aVisualInsertionIndices = rLayouter.GetGridInsertionIndices(rPoint);
nInsertionIndex = aVisualInsertionIndices.A() * rLayouter.GetColumnCount()
+ aVisualInsertionIndices.B();
if (aVisualInsertionIndices.B() == rLayouter.GetColumnCount())
--nInsertionIndex;
}
const view::InsertPosition aInsertPosition (rLayouter.GetInsertPosition(
rPoint,
maIconSize));
if (mnInsertionIndex != nInsertionIndex
|| maVisualInsertionIndices != aVisualInsertionIndices
if (maInsertPosition != aInsertPosition
|| meMode != eMode
|| ! mpInsertionIndicatorOverlay->IsVisible())
{
mnInsertionIndex = nInsertionIndex;
maVisualInsertionIndices = aVisualInsertionIndices;
maInsertPosition = aInsertPosition;
meMode = eMode;
mbIsInsertionTrivial = IsInsertionTrivial(eMode);
mbIsInsertionTrivial = IsInsertionTrivial(maInsertPosition.GetIndex(), eMode);
const Point aIndicatorLocation (
rLayouter.GetInsertionIndicatorLocation(
maVisualInsertionIndices,
maIconSize));
mpInsertionIndicatorOverlay->SetLocation(aIndicatorLocation);
if (mnInsertionIndex>=0 && ! mbIsInsertionTrivial)
if (maInsertPosition.GetIndex()>=0 && ! mbIsInsertionTrivial)
{
mpInsertionIndicatorOverlay->SetLocation(maInsertPosition.GetLocation());
GetInsertAnimator()->SetInsertPosition(
mnInsertionIndex,
maVisualInsertionIndices,
maInsertPosition,
maIconSize);
mpInsertionIndicatorOverlay->SetIsVisible(true);
mpInsertionIndicatorOverlay->Show();
}
else
{
GetInsertAnimator()->Reset();
mpInsertionIndicatorOverlay->SetIsVisible(false);
mpInsertionIndicatorOverlay->Hide();
}
}
}
@@ -262,7 +222,9 @@ void InsertionIndicatorHandler::SetPosition (
bool InsertionIndicatorHandler::IsInsertionTrivial (const Mode eMode) const
bool InsertionIndicatorHandler::IsInsertionTrivial (
const sal_Int32 nInsertionIndex,
const Mode eMode) const
{
if (eMode == CopyMode)
return false;
@@ -302,7 +264,7 @@ bool InsertionIndicatorHandler::IsInsertionTrivial (const Mode eMode) const
// to check that the insertion position is not directly in front or
// directly behind the selection and thus moving the selection there
// would not change the model.
if (mnInsertionIndex<nFirstIndex || mnInsertionIndex>(nLastIndex+1))
if (nInsertionIndex<nFirstIndex || nInsertionIndex>(nLastIndex+1))
return false;
return true;

View File

@@ -38,7 +38,6 @@
#include "model/SlsPageDescriptor.hxx"
#include "view/SlideSorterView.hxx"
#include "view/SlsLayouter.hxx"
#include "view/SlsViewOverlay.hxx"
#include "view/SlsTheme.hxx"
#include "Window.hxx"
#include "sdpage.hxx"

File diff suppressed because it is too large Load Diff

View File

@@ -81,8 +81,8 @@ namespace {
private:
SlideSorter& mrSlideSorter;
double mnStart;
double mnEnd;
::boost::function<double(double)> maAccelerationFunction;
const double mnEnd;
const ::boost::function<double(double)> maAccelerationFunction;
};
class HorizontalVisibleAreaScroller
{
@@ -93,8 +93,8 @@ namespace {
private:
SlideSorter& mrSlideSorter;
double mnStart;
double mnEnd;
::boost::function<double(double)> maAccelerationFunction;
const double mnEnd;
const ::boost::function<double(double)> maAccelerationFunction;
};
}
@@ -116,6 +116,8 @@ SelectionManager::SelectionManager (SlideSorter& rSlideSorter)
SelectionManager::~SelectionManager (void)
{
if (mnAnimationId != Animator::NotAnAnimationId)
mrController.GetAnimator()->RemoveAnimation(mnAnimationId);
}
@@ -655,6 +657,8 @@ void SelectionManager::SetInsertionPosition (const sal_Int32 nInsertionPosition)
namespace {
const static sal_Int32 gnMaxScrollDistance = 300;
VerticalVisibleAreaScroller::VerticalVisibleAreaScroller (
SlideSorter& rSlideSorter,
const double nStart,
@@ -666,6 +670,14 @@ VerticalVisibleAreaScroller::VerticalVisibleAreaScroller (
controller::AnimationParametricFunction(
controller::AnimationBezierFunction (0.1,0.6)))
{
// When the distance to scroll is larger than a threshold then first
// jump to within this distance of the final value and start the
// animation from there.
if (abs(nStart-nEnd) > gnMaxScrollDistance)
if (nStart < nEnd)
mnStart = nEnd-gnMaxScrollDistance;
else
mnStart = nEnd+gnMaxScrollDistance;
}

View File

@@ -49,7 +49,6 @@
#include "model/SlsPageDescriptor.hxx"
#include "view/SlideSorterView.hxx"
#include "view/SlsLayouter.hxx"
#include "view/SlsViewOverlay.hxx"
#include "framework/FrameworkHelper.hxx"
#include "Window.hxx"
#include "fupoor.hxx"
@@ -1093,8 +1092,7 @@ void SlotManager::InsertSlide (SfxRequest& rRequest)
}
// No selection. Is there an insertion indicator?
else if (mrSlideSorter.GetView().GetOverlay()
.GetInsertionIndicatorOverlay()->IsVisible())
else if (mrSlideSorter.GetController().GetInsertionIndicatorHandler()->IsActive())
{
// Select the page before the insertion indicator.
nInsertionIndex

View File

@@ -31,7 +31,7 @@
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sd.hxx"
#include "SlsTransferable.hxx"
#include "controller/SlsTransferable.hxx"
#include "SlideSorterViewShell.hxx"
#include "View.hxx"
@@ -43,10 +43,10 @@ Transferable::Transferable (
::sd::View* pWorkView,
BOOL bInitOnGetData,
SlideSorterViewShell* pViewShell,
const ::boost::shared_ptr<SubstitutionHandler>& rpSubstitutionHandler)
const ::std::vector<Bitmap>& rRepresentatives)
: SdTransferable (pSrcDoc, pWorkView, bInitOnGetData),
mpViewShell(pViewShell),
mpSubstitutionHandler(rpSubstitutionHandler)
maRepresentatives(rRepresentatives)
{
if (mpViewShell != NULL)
StartListening(*mpViewShell);
@@ -68,7 +68,6 @@ void Transferable::DragFinished (sal_Int8 nDropAction)
{
if (mpViewShell != NULL)
mpViewShell->DragFinished(nDropAction);
mpSubstitutionHandler.reset();
}
@@ -96,11 +95,10 @@ void Transferable::Notify (SfxBroadcaster& rBroadcaster, const SfxHint& rHint)
::boost::shared_ptr<SubstitutionHandler> Transferable::GetSubstitutionHandler (void) const
const ::std::vector<Bitmap>& Transferable::GetRepresentatives (void) const
{
return mpSubstitutionHandler;
return maRepresentatives;
}
} } } // end of namespace ::sd::slidesorter::controller

View File

@@ -52,6 +52,7 @@ SLOFILES = \
$(SLO)$/SlsAnimationFunction.obj \
$(SLO)$/SlsClipboard.obj \
$(SLO)$/SlsCurrentSlideManager.obj \
$(SLO)$/SlsDragAndDropContext.obj \
$(SLO)$/SlsFocusManager.obj \
$(SLO)$/SlsInsertionIndicatorHandler.obj\
$(SLO)$/SlsListener.obj \
@@ -62,7 +63,6 @@ SLOFILES = \
$(SLO)$/SlsSelectionFunction.obj \
$(SLO)$/SlsSelectionManager.obj \
$(SLO)$/SlsSlotManager.obj \
$(SLO)$/SlsSubstitutionHandler.obj \
$(SLO)$/SlsTransferable.obj
# --- Tagets -------------------------------------------------------

View File

@@ -96,6 +96,12 @@ public:
*/
void RemoveAnimation (const AnimationId nAnimationId);
/** A typical use case for this method is the temporary shutdown of the
slidesorter when the slide sorter bar is put into a cache due to a
change of the edit mode.
*/
void RemoveAllAnimations (void);
private:
SlideSorter& mrSlideSorter;
Timer maTimer;

View File

@@ -33,6 +33,8 @@
#include "view/SlsInsertAnimator.hxx"
#include "view/SlsLayouter.hxx"
namespace sd { namespace slidesorter { class SlideSorter; } }
namespace sd { namespace slidesorter { namespace model {
class PageEnumeration;
@@ -45,6 +47,8 @@ class InsertionIndicatorOverlay;
namespace sd { namespace slidesorter { namespace controller {
class Transferable;
/** Manage the visibility and location of the insertion indicator. Its
actual display is controlled by the InsertionIndicatorOverlay.
@@ -60,13 +64,16 @@ public:
/** Activate the insertion marker at the given coordinates.
*/
void Start (
const Point& rMouseModelPosition,
const Mode eMode,
const bool bIsOverSourceView);
void Start (const bool bIsOverSourceView);
void UpdateIndicatorIcon (model::PageEnumeration& rEnumeration);
void UpdateIndicatorIcon (void);
/** Deactivate the insertion marker.
*/
void End (void);
/** Update the indicator icon from the current transferable (from the
clipboard or an active drag and drop operation.)
*/
void UpdateIndicatorIcon (const Transferable* pTransferable);
/** Set the position of the insertion marker to the given coordinates.
*/
@@ -77,10 +84,6 @@ public:
const Point& rMouseModelPosition,
const sal_Int8 nDndAction);
/** Deactivate the insertion marker.
*/
void End (void);
/** Return whether the insertion marker is active.
*/
bool IsActive (void) const;
@@ -96,14 +99,15 @@ public:
would be the case when the selection is not consecutive or would be
moved to a position outside and not adjacent to the selection.
*/
bool IsInsertionTrivial (const Mode eMode) const;
bool IsInsertionTrivial (
const sal_Int32 nInsertionIndex,
const Mode eMode) const;
private:
SlideSorter& mrSlideSorter;
::boost::shared_ptr<view::InsertAnimator> mpInsertAnimator;
::boost::shared_ptr<view::InsertionIndicatorOverlay> mpInsertionIndicatorOverlay;
sal_Int32 mnInsertionIndex;
Pair maVisualInsertionIndices;
view::InsertPosition maInsertPosition;
Mode meMode;
bool mbIsInsertionTrivial;
bool mbIsActive;

View File

@@ -52,7 +52,7 @@ class SlideSorter;
namespace sd { namespace slidesorter { namespace controller {
class SlideSorterController;
class SubstitutionHandler;
class DragAndDropContext;
class SelectionFunction
@@ -109,7 +109,7 @@ public:
const Point& rMousePosition,
const bool bIsMouseButtonDown);
::boost::shared_ptr<SubstitutionHandler> GetSubstitutionHandler (void) const;
::boost::shared_ptr<DragAndDropContext> GetDragAndDropContext (void) const;
class MouseMultiSelector;
@@ -126,9 +126,6 @@ protected:
private:
class EventDescriptor;
/// Set in MouseButtonDown this flag indicates that a page has been hit.
bool mbPageHit;
/// The rectangle of the mouse drag selection.
Rectangle maDragSelectionRectangle;
bool mbDragSelection;
@@ -144,7 +141,7 @@ private:
*/
bool mbProcessingMouseButtonDown;
::boost::shared_ptr<SubstitutionHandler> mpSubstitutionHandler;
::boost::shared_ptr<DragAndDropContext> mpDragAndDropContext;
::boost::scoped_ptr<MouseMultiSelector> mpMouseMultiSelector;
/** Remember where the left mouse button was pressed.
@@ -159,7 +156,6 @@ private:
*/
sal_Int32 mnShiftKeySelectionAnchor;
DECL_LINK( DragSlideHdl, Timer* );
void StartDrag (
const Point& rMousePosition,
const InsertionIndicatorHandler::Mode eMode);
@@ -192,22 +188,11 @@ private:
/// Deselect all pages.
void DeselectAllPages (void);
/** For a possibly following mouse motion by starting the drag timer
that after a short time of pressed but un-moved mouse starts a drag
operation.
*/
void StartDragTimer (void);
/** Select all pages between and including the selection anchor and the
specified page.
*/
void RangeSelect (const model::SharedPageDescriptor& rpDescriptor);
/** Hide and clear the insertion indiciator, substitution display and
selection rectangle.
*/
void ClearOverlays (void);
/** Compute a numerical code that describes a mouse event and that can
be used for fast look up of the appropriate reaction.
*/
@@ -228,9 +213,13 @@ private:
*/
sal_uInt32 EncodeState (const EventDescriptor& rDescriptor) const;
void EventPreprocessing (const EventDescriptor& rEvent);
bool EventProcessing (const EventDescriptor& rEvent);
void EventPostprocessing (const EventDescriptor& rEvent);
bool ProcessEvent (EventDescriptor& rEvent);
void PostProcessEvent (const EventDescriptor& rEvent);
void ProcessEventWhileDragActive (EventDescriptor& rDescriptor);
void ProcessEventWhileMultiSelectorActive (EventDescriptor& rDescriptor);
void ProcessButtonDownEvent (EventDescriptor& rDescriptor);
void ProcessButtonUpEvent (const EventDescriptor& rDescriptor);
void ProcessMouseMotionEvent (const EventDescriptor& rDescriptor);
void ProcessButtonClick (
const model::SharedPageDescriptor& rpDescriptor,
@@ -245,4 +234,3 @@ private:
} } } // end of namespace ::sd::slidesorter::controller
#endif

View File

@@ -34,19 +34,12 @@
#include "sdxfer.hxx"
class SdDrawDocument;
namespace sd
{
class pWorkView;
namespace slidesorter
{
class SlideSorterViewShell;
}
}
namespace sd { namespace slidesorter {
class SlideSorterViewShell;
} }
namespace sd { namespace slidesorter { namespace controller {
class SubstitutionHandler;
/** This class exists to have DragFinished call the correct object: the
SlideSorterViewShell instead of the old SlideView.
@@ -60,17 +53,17 @@ public:
::sd::View* pWorkView,
BOOL bInitOnGetData,
SlideSorterViewShell* pViewShell,
const ::boost::shared_ptr<SubstitutionHandler>& rpSubstitutionHandler);
const ::std::vector<Bitmap>& rRepresentatives);
virtual ~Transferable (void);
virtual void DragFinished (sal_Int8 nDropAction);
::boost::shared_ptr<SubstitutionHandler> GetSubstitutionHandler (void) const;
const ::std::vector<Bitmap>& GetRepresentatives (void) const;
private:
SlideSorterViewShell* mpViewShell;
::boost::shared_ptr<SubstitutionHandler> mpSubstitutionHandler;
const ::std::vector<Bitmap> maRepresentatives;
virtual void Notify (SfxBroadcaster& rBroadcaster, const SfxHint& rHint);
};

View File

@@ -31,6 +31,7 @@
#ifndef SD_SLIDESORTER_SLIDE_SORTER_VIEW_HXX
#define SD_SLIDESORTER_SLIDE_SORTER_VIEW_HXX
#include "SlideSorter.hxx"
#include "model/SlsPageDescriptor.hxx"
#include "model/SlsSharedPageDescriptor.hxx"
@@ -48,10 +49,6 @@
class Point;
namespace sd { namespace slidesorter {
class SlideSorter;
} }
namespace sd { namespace slidesorter { namespace controller {
class SlideSorterController;
class Properties;
@@ -71,7 +68,6 @@ class LayeredDevice;
class Layouter;
class PageObjectPainter;
class SelectionPainter;
class ViewOverlay;
class SlideSorterView
: public sd::View,
@@ -162,8 +158,6 @@ public:
::boost::shared_ptr<cache::PageCache> GetPreviewCache (void);
view::ViewOverlay& GetOverlay (void);
/** Set the bounding box of the insertion marker in model coordinates.
It will be painted as a dark rectangle that fills the given box.
@@ -209,15 +203,17 @@ public:
const bool bStateValue);
::boost::shared_ptr<PageObjectPainter> GetPageObjectPainter (void);
::boost::shared_ptr<LayeredDevice> GetLayeredDevice (void) const;
class DrawLock
{
public:
DrawLock (view::SlideSorterView& rView);
DrawLock (view::SlideSorterView& rView, const SharedSdWindow& rpWindow);
DrawLock (SlideSorter& rSlideSorter);
~DrawLock (void);
private:
view::SlideSorterView& mrView;
SharedSdWindow mpWindow;
};
protected:
@@ -231,7 +227,6 @@ private:
bool mbPageObjectVisibilitiesValid;
::boost::shared_ptr<cache::PageCache> mpPreviewCache;
::boost::shared_ptr<LayeredDevice> mpLayeredDevice;
::boost::shared_ptr<ViewOverlay> mpViewOverlay;
Range maVisiblePageRange;
bool mbModelChangedWhileModifyEnabled;
Size maPreviewSize;
@@ -242,6 +237,7 @@ private:
sal_Int32 mnButtonUnderMouse;
::boost::shared_ptr<PageObjectPainter> mpPageObjectPainter;
::boost::shared_ptr<SelectionPainter> mpSelectionPainter;
Region maRedrawRegion;
/** Determine the visibility of all page objects.
*/

View File

@@ -38,6 +38,9 @@
namespace sd { namespace slidesorter { namespace view {
class InsertPosition;
/** Animate the positions of page objects to make room at the insert
position while a move or copy operation takes place.
*/
@@ -51,8 +54,7 @@ public:
icon.
*/
void SetInsertPosition (
const sal_Int32 nPageIndex,
const Pair& rVisualInsertionIndices,
const InsertPosition& rInsertPosition,
const Size& rIconSize);
void Reset (void);

View File

@@ -0,0 +1,130 @@
/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright 2008 by Sun Microsystems, Inc.
*
* OpenOffice.org - a multi-platform office productivity suite
*
* This file is part of OpenOffice.org.
*
* OpenOffice.org is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 3
* only, as published by the Free Software Foundation.
*
* OpenOffice.org is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License version 3 for more details
* (a copy is included in the LICENSE file that accompanied this code).
*
* You should have received a copy of the GNU Lesser General Public License
* version 3 along with OpenOffice.org. If not, see
* <http://www.openoffice.org/license.html>
* for a copy of the LGPLv3 License.
*
************************************************************************/
#ifndef SD_SLIDESORTER_INSERTION_INDICATOR_OVERLAY_HXX
#define SD_SLIDESORTER_INSERTION_INDICATOR_OVERLAY_HXX
#include "model/SlsSharedPageDescriptor.hxx"
#include "view/SlsILayerPainter.hxx"
#include <tools/gen.hxx>
#include <vcl/bitmapex.hxx>
#include <boost/scoped_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <vector>
class OutputDevice;
class SdPage;
namespace sd { namespace slidesorter {
class SlideSorter;
} }
namespace sd { namespace slidesorter { namespace model {
class PageEnumeration;
} } }
namespace sd { namespace slidesorter { namespace controller {
class Transferable;
} } }
namespace sd { namespace slidesorter { namespace view {
class FramePainter;
class LayeredDevice;
/** The insertion indicator is painted as a vertical or horizonal bar
in the space between slides.
*/
class InsertionIndicatorOverlay
: public ILayerPainter,
public ::boost::enable_shared_from_this<InsertionIndicatorOverlay>
{
public:
InsertionIndicatorOverlay (SlideSorter& rSlideSorter);
virtual ~InsertionIndicatorOverlay (void);
virtual void SetLayerInvalidator (const SharedILayerInvalidator& rpInvalidator);
void Create (const controller::Transferable* pTransferable);
/** Given a position in model coordinates this method calculates the
insertion marker both as an index in the document and as a location
used for drawing the insertion indicator.
*/
void SetLocation (const Point& rPosition);
Size GetSize (void) const;
virtual void Paint (
OutputDevice& rDevice,
const Rectangle& rRepaintArea);
bool IsVisible (void) const;
void Hide (void);
void Show (void);
Rectangle GetBoundingBox (void) const;
private:
SlideSorter& mrSlideSorter;
bool mbIsVisible;
const sal_Int32 mnLayerIndex;
SharedILayerInvalidator mpLayerInvalidator;
// Center of the insertion indicator.
Point maLocation;
BitmapEx maIcon;
Point maIconOffset;
::boost::scoped_ptr<FramePainter> mpShadowPainter;
void SetPositionAndSize (const Rectangle& rBoundingBox);
void SelectRepresentatives (
model::PageEnumeration& rSelection,
::std::vector<model::SharedPageDescriptor>& rDescriptors) const;
Point PaintRepresentatives (
OutputDevice& rContent,
const Size aPreviewSize,
const sal_Int32 nOffset,
const ::std::vector<Bitmap>& rPages) const;
void PaintPageCount (
OutputDevice& rDevice,
const sal_Int32 nSelectionCount,
const Size aPreviewSize,
const Point aFirstPageOffset) const;
/** Setup the insertion indicator by creating the icon. It consists of
scaled down previews of some of the selected pages.
*/
void Create (
const ::std::vector<Bitmap>& rPages,
const sal_Int32 nSelectionCount);
};
} } } // end of namespace ::sd::slidesorter::view
#endif

View File

@@ -45,6 +45,11 @@ class Size;
namespace sd { namespace slidesorter { namespace view {
class InsertPosition;
/** Calculate the size and position of page objects displayed by a slide
sorter. The layouter takes into account various input values:
1.) Size of the window in which the slide sorter is displayed.
@@ -192,20 +197,6 @@ public:
*/
Rectangle GetPageBox (const sal_Int32 nObjectCount = -1) const;
/** Return the location of the center of the insertion indicator that is
specified by the parameters.
@param aVisualIndicatorIndices
Row and column of where to paint the insertion indicator. Column
is -1 when the indicator is placed between rows of a single
column.
@param rIndicatorSize
The size of the insertion indicator. This size is used to adapt
the location when at the left or right of a row.
*/
Point GetInsertionIndicatorLocation (
const Pair& rVisualIndicatorIndices,
const Size& rIndicatorSize) const;
/** Return the index of the first fully or partially visible page
object. This takes into account only the vertical dimension.
@return
@@ -233,40 +224,22 @@ public:
const Point& rModelPosition,
const bool bIncludePageBorders = false) const;
/** Return the page index of where to do an insert operation when the
user would release the the mouse button at the given position after
a drag operation. This method assumes that pages are placed in a
single column.
/** Return an object that describes the logical and visual properties of
where to do an insert operation when the user would release the the
mouse button at the given position after a drag operation and of
where and how to display an insertion indicator.
@param rPosition
The position in the model coordinate system for which to
determine the insertion page index. The position does not have
to be over a page object to return a valid value.
@return
Returns the page index, as accepted by the slide sorter model,
of the page after which an insertion would take place. An index
of 0 means that insertion will take place before the first page,
An index equal to or greater than the page count means to insert
after the last page.
A value of -1 indicates that no valid insertion index exists for
the given point.
@param rIndicatorSize
The size of the insertion indicator. This size is used to adapt
the location when at the left or right of a row or at the top or
bottom of a column.
*/
sal_Int32 GetVerticalInsertionIndex (const Point& rModelPosition) const;
/** Return a pair of row and column indices of where to do an insert
operation when the user would release the the mouse button at the
given position after a drag operation. This method assumes that
pages are placed in a row-first grid.
@param rPosition
The position in the model coordinate system for which to
determine the insertion page index. The position does not have
to be over a page object to return a valid value.
@return
Returns a pair of (row,column) indices and defines the place of
where to paint the insertion indicator. The column index lies
in the range [0,column count]. A value of (-1,-1) indicates
that no valid insertion index exists for the given point.
*/
Pair GetGridInsertionIndices (const Point& rModelPosition) const;
InsertPosition GetInsertPosition (
const Point& rModelPosition,
const Size& rIndicatorSize) const;
/** Return whether the main orientation of the slides in the slide
sorter is vertical, i.e. all slides are arranged in one column.
@@ -293,6 +266,14 @@ private:
sal_Int32 mnPageCount;
sal_Int32 mnColumnCount;
sal_Int32 mnRowCount;
/// The maximum number of columns. Can only be larger than the current
/// number of columns when there are not enough pages to fill all
/// available columns.
sal_Int32 mnMaxColumnCount;
/// The maximum number of rows. Can only be larger than the current
/// number of rows when there are not enough pages to fill all available
/// rows.
sal_Int32 mnMaxRowCount;
Size maPageObjectSize;
bool mbIsVertical;
@@ -371,6 +352,42 @@ private:
Rectangle GetPreviewBox (const sal_Int32 nIndex) const;
};
/** Collect all values concerning the logical and visual properties of the
insertion position that is used for drag-and-drop and copy-and-past.
*/
class InsertPosition
{
public:
InsertPosition (void);
InsertPosition& operator= (const InsertPosition& rInsertPosition);
bool operator== (const InsertPosition& rInsertPosition) const;
bool operator!= (const InsertPosition& rInsertPosition) const;
sal_Int32 GetRow (void) const { return mnRow; }
sal_Int32 GetColumn (void) const { return mnColumn; }
sal_Int32 GetIndex (void) const { return mnIndex; }
Point GetLocation (void) const { return maLocation; }
bool IsAtRunStart (void) const { return mbIsAtRunStart; }
bool IsAtRunEnd (void) const { return mbIsAtRunEnd; }
bool IsExtraSpaceNeeded (void) const { return mbIsExtraSpaceNeeded; }
private:
sal_Int32 mnRow;
sal_Int32 mnColumn;
sal_Int32 mnIndex;
Point maLocation;
bool mbIsAtRunStart : 1;
bool mbIsAtRunEnd : 1;
bool mbIsExtraSpaceNeeded : 1;
friend class Layouter;
};
} } } // end of namespace ::sd::slidesorter::view
#endif

View File

@@ -1,293 +0,0 @@
/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright 2008 by Sun Microsystems, Inc.
*
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: SlsViewOverlay.hxx,v $
* $Revision: 1.10 $
*
* This file is part of OpenOffice.org.
*
* OpenOffice.org is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 3
* only, as published by the Free Software Foundation.
*
* OpenOffice.org is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License version 3 for more details
* (a copy is included in the LICENSE file that accompanied this code).
*
* You should have received a copy of the GNU Lesser General Public License
* version 3 along with OpenOffice.org. If not, see
* <http://www.openoffice.org/license.html>
* for a copy of the LGPLv3 License.
*
************************************************************************/
#ifndef SD_SLIDESORTER_VIEW_OVERLAY_HXX
#define SD_SLIDESORTER_VIEW_OVERLAY_HXX
#include "model/SlsSharedPageDescriptor.hxx"
#include "view/SlsILayerPainter.hxx"
#include <basegfx/polygon/b2dpolypolygon.hxx>
#include <osl/mutex.hxx>
#include <tools/gen.hxx>
#include <vcl/bitmapex.hxx>
#include <vcl/image.hxx>
#include <basegfx/range/b2drectangle.hxx>
#include <basegfx/polygon/b2dpolygon.hxx>
#include <vector>
#include <boost/scoped_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
class OutputDevice;
class Region;
namespace sd { namespace slidesorter {
class SlideSorter;
} }
namespace sd { namespace slidesorter { namespace model {
class PageEnumeration;
} } }
namespace sd { namespace slidesorter { namespace controller {
class SlideSorterController;
} } }
namespace sd { namespace slidesorter { namespace view {
class LayeredDevice;
class InsertionIndicatorOverlay;
class SelectionRectangleOverlay;
class SubstitutionOverlay;
class ViewOverlay;
class FramePainter;
/** This base class of slide sorter overlays uses the drawing layer overlay
support for the display.
*/
class OverlayBase :
public ILayerPainter,
public ::boost::enable_shared_from_this<OverlayBase>
{
public:
OverlayBase (ViewOverlay& rViewOverlay, const sal_Int32 nLayer);
virtual ~OverlayBase (void);
bool IsVisible (void) const;
void SetIsVisible (const bool bIsVisible);
virtual void SetLayerInvalidator (const SharedILayerInvalidator& rpInvalidator);
sal_Int32 GetLayerIndex (void) const;
protected:
::osl::Mutex maMutex;
ViewOverlay& mrViewOverlay;
SharedILayerInvalidator mpLayerInvalidator;
class Invalidator;
friend class Invalidator;
virtual Rectangle GetBoundingBox (void) const = 0;
private:
bool mbIsVisible;
const sal_Int32 mnLayerIndex;
void Invalidate (const Rectangle& rInvalidationBox);
};
/** During internal drag and drop the outlines of the selected slides are
painted at the mouse position in dashed lines.
*/
class SubstitutionOverlay
: public OverlayBase
{
public:
SubstitutionOverlay (ViewOverlay& rViewOverlay, const sal_Int32 nLayer);
virtual ~SubstitutionOverlay (void);
void SetAnchor (const Point& rAnchor);
/** Clear the substitution display. Until the next call of Create() no
substution is painted.
*/
void Clear (void);
/** Move the substitution display by the given amount of pixels.
*/
void Move (const Point& rPositionOffset);
void SetPosition (const Point& rPosition);
Point GetPosition (void) const;
virtual void Paint (
OutputDevice& rDevice,
const Rectangle& rRepaintArea);
protected:
virtual Rectangle GetBoundingBox (void) const;
private:
/** The current position can be set by calling SetPosition() or Move().
*/
Point maPosition;
/** The substitution paints only the page object under the mouse and the
8-neighborhood around it. It uses different levels of transparency
for the center and the four elements at its sides and the four
elements at its corners. All values between 0 (opaque) and 100
(fully transparent.)
*/
static const sal_Int32 mnCenterTransparency;
static const sal_Int32 mnSideTransparency;
static const sal_Int32 mnCornerTransparency;
};
/** Slides can be selected by drawing a selection rectangle in the slide
sorter. When the left mouse button is released all slides that are at
least partially in the rectangle are selected.
*/
class SelectionRectangleOverlay
: public OverlayBase
{
public:
SelectionRectangleOverlay (ViewOverlay& rViewOverlay, const sal_Int32 nLayer);
void Start (const Point& rAnchor);
void Update (const Point& rSecondCorner);
Rectangle GetSelectionRectangle (void);
virtual void Paint (
OutputDevice& rDevice,
const Rectangle& rRepaintArea);
protected:
virtual Rectangle GetBoundingBox (void) const;
private:
Point maAnchor;
Point maSecondCorner;
};
/** The insertion indicator is painted as a vertical or horizonal bar
in the space between slides.
*/
class InsertionIndicatorOverlay
: public OverlayBase
{
public:
InsertionIndicatorOverlay (ViewOverlay& rViewOverlay, const sal_Int32 nLayer);
/** Setup the insertion indicator by creating the icon. It consists of
scaled down previews of some of the selected pages.
*/
void Create (model::PageEnumeration& rSelection);
void Create (void);
/** Given a position in model coordinates this method calculates the
insertion marker both as an index in the document and as a location
used for drawing the insertion indicator.
*/
void SetLocation (const Point& rPosition);
Size GetSize (void) const;
virtual void Paint (
OutputDevice& rDevice,
const Rectangle& rRepaintArea);
protected:
virtual Rectangle GetBoundingBox (void) const;
private:
// Center of the insertion indicator.
Point maLocation;
/** Remember whether the insertion indicator is displayed before (left
of or above) or after (right of or below) the page at the insertion
index.
*/
bool mbIsBeforePage;
BitmapEx maIcon;
Point maIconOffset;
::boost::scoped_ptr<FramePainter> mpShadowPainter;
void SetPositionAndSize (const Rectangle& rBoundingBox);
void SelectRepresentatives (
model::PageEnumeration& rSelection,
::std::vector<model::SharedPageDescriptor>& rDescriptors) const;
Point PaintRepresentatives (
OutputDevice& rContent,
const Size aPreviewSize,
const sal_Int32 nOffset,
const ::std::vector<model::SharedPageDescriptor>& rDescriptors) const;
void PaintPageCount (
OutputDevice& rDevice,
model::PageEnumeration& rSelection,
const Size aPreviewSize,
const Point aFirstPageOffset) const;
};
/** The view overlay manages and paints some indicators that are painted on
top of the regular view content (the page objects). It is separated
from the view to allow the indicators to be altered in position and size
without repainting the whole view content (inside that the bounding box
of the indicator). This is achieved by using the drawing layer overlay
support.
The view overlay itself simply gives access to the more specialized
classes that handle individual indicators.
*/
class ViewOverlay
{
public:
ViewOverlay (
SlideSorter& rSlideSorter,
const ::boost::shared_ptr<LayeredDevice>& rpLayeredDevice);
virtual ~ViewOverlay (void);
::boost::shared_ptr<SelectionRectangleOverlay> GetSelectionRectangleOverlay (void);
::boost::shared_ptr<InsertionIndicatorOverlay> GetInsertionIndicatorOverlay (void);
::boost::shared_ptr<SubstitutionOverlay> GetSubstitutionOverlay (void);
SlideSorter& GetSlideSorter (void) const;
::boost::shared_ptr<LayeredDevice> GetLayeredDevice (void) const;
private:
SlideSorter& mrSlideSorter;
const ::boost::shared_ptr<LayeredDevice> mpLayeredDevice;
::boost::shared_ptr<SelectionRectangleOverlay> mpSelectionRectangleOverlay;
::boost::shared_ptr<InsertionIndicatorOverlay> mpInsertionIndicatorOverlay;
::boost::shared_ptr<SubstitutionOverlay> mpSubstitutionOverlay;
};
} } } // end of namespace ::sd::slidesorter::view
#endif

View File

@@ -37,6 +37,7 @@
#include "controller/SlideSorterController.hxx"
#include "controller/SlsScrollBarManager.hxx"
#include "controller/SlsProperties.hxx"
#include "controller/SlsAnimator.hxx"
#include "view/SlideSorterView.hxx"
#include "view/SlsTheme.hxx"
#include "model/SlideSorterModel.hxx"
@@ -497,18 +498,19 @@ void SlideSorter::ArrangeGUIElements (
{
Point aOrigin (rOffset);
if (rSize.Width()!=0 && rSize.Height()!=0)
if (rSize.Width()>0
&& rSize.Height()>0
&& GetContentWindow()
&& GetContentWindow()->IsVisible())
{
// Prevent untimely redraws while the view is not yet correctly
// resized.
view::SlideSorterView::DrawLock aLock (*mpSlideSorterView);
if (GetContentWindow())
GetContentWindow()->EnablePaint (FALSE);
view::SlideSorterView::DrawLock aLock (*this);
GetContentWindow()->EnablePaint (FALSE);
mpSlideSorterController->Resize (Rectangle(aOrigin, rSize));
if (GetContentWindow())
GetContentWindow()->EnablePaint (TRUE);
GetContentWindow()->EnablePaint (TRUE);
mbLayoutPending = false;
}
@@ -537,6 +539,9 @@ SvBorder SlideSorter::GetBorder (void)
bool SlideSorter::RelocateToWindow (::Window* pParentWindow)
{
// Stop all animations for they have been started for the old window.
mpSlideSorterController->GetAnimator()->RemoveAllAnimations();
ReleaseListeners();
if (mpViewShell != NULL)
@@ -548,8 +553,8 @@ bool SlideSorter::RelocateToWindow (::Window* pParentWindow)
// For accessibility we have to shortly hide the content window. This
// triggers the construction of a new accessibility object for the new
// view shell. (One is created earlier while the construtor of the base
// class is executed. At that time the correct accessibility object can
// not be constructed.)
// class is executed. But because at that time the correct
// accessibility object can not be constructed we do that now.)
if (mpContentWindow.get() !=NULL)
{
mpContentWindow->Hide();

View File

@@ -397,6 +397,11 @@ SdPage* SlideSorterViewShell::GetActualPage (void)
pCurrentPage = pDescriptor->GetPage();
}
if (pCurrentPage == NULL)
{
}
return pCurrentPage;
}
@@ -531,8 +536,8 @@ void SlideSorterViewShell::Paint (
::sd::Window* pWindow)
{
SetActiveWindow (pWindow);
OSL_ASSERT(mpSlideSorter.get()!=NULL);
if (mpSlideSorter.get() != NULL)
OSL_ASSERT(mpSlideSorter);
if (mpSlideSorter)
mpSlideSorter->GetController().Paint(rBBox,pWindow);
}
@@ -542,9 +547,7 @@ void SlideSorterViewShell::Paint (
void SlideSorterViewShell::ArrangeGUIElements (void)
{
OSL_ASSERT(mpSlideSorter.get()!=NULL);
mpSlideSorter->ArrangeGUIElements(
maViewPos,
maViewSize);
mpSlideSorter->ArrangeGUIElements(maViewPos, maViewSize);
}
@@ -611,6 +614,8 @@ void SlideSorterViewShell::ReadFrameViewData (FrameView* pFrameView)
}
else
rView.GetLayouter().SetColumnCount(nSlidesPerRow,nSlidesPerRow);
mpSlideSorter->GetController().GetCurrentSlideManager()->CurrentSlideHasChanged(
mpFrameView->GetSelectedPage());
mpSlideSorter->GetController().Rearrange(true);
// DrawMode for 'main' window

View File

@@ -41,7 +41,6 @@
#include "view/SlsLayouter.hxx"
#include "view/SlsPageObjectLayouter.hxx"
#include "view/SlsPageObjectPainter.hxx"
#include "view/SlsViewOverlay.hxx"
#include "view/SlsILayerPainter.hxx"
#include "controller/SlideSorterController.hxx"
#include "controller/SlsProperties.hxx"
@@ -331,7 +330,6 @@ SlideSorterView::SlideSorterView (SlideSorter& rSlideSorter)
mbPageObjectVisibilitiesValid (false),
mpPreviewCache(),
mpLayeredDevice(new LayeredDevice(rSlideSorter.GetContentWindow())),
mpViewOverlay (new ViewOverlay(rSlideSorter, mpLayeredDevice)),
maVisiblePageRange(-1,-1),
mbModelChangedWhileModifyEnabled(true),
maPreviewSize(0,0),
@@ -397,9 +395,6 @@ void SlideSorterView::Dispose (void)
// Deletion of the objects and the page will be done in SdrModel
// destructor (as long as objects and pages are added)
OSL_ASSERT(mpViewOverlay.unique());
mpViewOverlay.reset();
OSL_ASSERT(mpLayeredDevice.unique());
mpLayeredDevice.reset();
@@ -828,7 +823,7 @@ void SlideSorterView::CompleteRedraw (
}
else
{
View::CompleteRedraw(pDevice, rPaintArea, pRedirector);
maRedrawRegion.Union(rPaintArea);
}
#ifdef DEBUG_TIMING
@@ -918,14 +913,6 @@ void SlideSorterView::ConfigurationChanged (
ViewOverlay& SlideSorterView::GetOverlay (void)
{
return *mpViewOverlay.get();
}
Pair SlideSorterView::GetVisiblePageRange (void)
{
if ( ! mbPageObjectVisibilitiesValid)
@@ -1120,21 +1107,37 @@ bool SlideSorterView::SetState (
::boost::shared_ptr<LayeredDevice> SlideSorterView::GetLayeredDevice (void) const
{
return mpLayeredDevice;
}
//===== Animator::DrawLock ====================================================
SlideSorterView::DrawLock::DrawLock (view::SlideSorterView& rView)
: mrView(rView)
SlideSorterView::DrawLock::DrawLock (
view::SlideSorterView& rView,
const SharedSdWindow& rpWindow)
: mrView(rView),
mpWindow(rpWindow)
{
mrView.LockRedraw(TRUE);
if (mrView.mnLockRedrawSmph == 0)
mrView.maRedrawRegion.SetEmpty();
++mrView.mnLockRedrawSmph;
}
SlideSorterView::DrawLock::DrawLock (SlideSorter& rSlideSorter)
: mrView(rSlideSorter.GetView())
: mrView(rSlideSorter.GetView()),
mpWindow(rSlideSorter.GetContentWindow())
{
mrView.LockRedraw(TRUE);
if (mrView.mnLockRedrawSmph == 0)
mrView.maRedrawRegion.SetEmpty();
++mrView.mnLockRedrawSmph;
}
@@ -1142,7 +1145,19 @@ SlideSorterView::DrawLock::DrawLock (SlideSorter& rSlideSorter)
SlideSorterView::DrawLock::~DrawLock (void)
{
mrView.LockRedraw(FALSE);
OSL_ASSERT(mrView.mnLockRedrawSmph>0);
--mrView.mnLockRedrawSmph;
if (mrView.mnLockRedrawSmph == 0)
if (mpWindow)
{
mpWindow->Invalidate(mrView.maRedrawRegion);
mpWindow->Update();
}
/*
mrView.CompleteRedraw(
mpWindow.get(),
mrView.maRedrawRegion);
*/
}

View File

@@ -50,6 +50,7 @@ FramePainter::FramePainter (const BitmapEx& rShadowBitmap)
maShadowBottomLeft(rShadowBitmap,-1,+1),
maShadowBottom(rShadowBitmap,0,+1),
maShadowBottomRight(rShadowBitmap,+1,+1),
maShadowCenter(rShadowBitmap,0,0),
mbIsValid(false)
{
if (rShadowBitmap.GetSizePixel().Width() == rShadowBitmap.GetSizePixel().Height()
@@ -100,6 +101,7 @@ void FramePainter::PaintFrame (
maShadowBottom.PaintSide(rDevice,
aBox.BottomLeft(), aBox.BottomRight(),
maShadowBottomLeft, maShadowBottomRight);
maShadowCenter.PaintCenter(rDevice,aBox);
}
@@ -137,13 +139,17 @@ FramePainter::OffsetBitmap::OffsetBitmap (
// Enlarge the side bitmaps so that painting the frame requires less
// paint calls.
const sal_Int32 nSideBitmapSize (64);
if (nHorizontalPosition == 0)
if (nHorizontalPosition == 0 && nVerticalPosition == 0)
{
maBitmap.Scale(Size(nSideBitmapSize,nSideBitmapSize), BMP_SCALE_FAST);
}
else if (nHorizontalPosition == 0)
{
maBitmap.Scale(Size(nSideBitmapSize,aSize.Height()), BMP_SCALE_FAST);
}
else if (nVerticalPosition == 0)
{
maBitmap.Scale(Size(aSize.Width(), nSideBitmapSize), BMP_SCALE_FAST);
maBitmap.Scale(Size(maBitmap.GetSizePixel().Width(), nSideBitmapSize), BMP_SCALE_FAST);
}
}
@@ -216,4 +222,23 @@ void FramePainter::OffsetBitmap::PaintSide (
}
void FramePainter::OffsetBitmap::PaintCenter (
OutputDevice& rDevice,
const Rectangle& rBox) const
{
const Size aBitmapSize (maBitmap.GetSizePixel());
for (sal_Int32 nY=rBox.Top(); nY<=rBox.Bottom(); nY+=aBitmapSize.Height())
for (sal_Int32 nX=rBox.Left(); nX<=rBox.Right(); nX+=aBitmapSize.Width())
rDevice.DrawBitmapEx(
Point(nX,nY),
Size(
::std::min(aBitmapSize.Width(), rBox.Right()-nX+1),
std::min(aBitmapSize.Height(), rBox.Bottom()-nY+1)),
maBitmap);
}
} } } // end of namespace sd::slidesorter::view

View File

@@ -46,6 +46,10 @@ class FramePainter
public:
FramePainter (const BitmapEx& rBitmap);
~FramePainter (void);
/** Paint a border around the given box by using a set of bitmaps for
the corners and sides.
*/
void PaintFrame (OutputDevice&rDevice, const Rectangle aBox) const;
private:
@@ -90,6 +94,12 @@ private:
const OffsetBitmap& rCornerBitmap1,
const OffsetBitmap& rCornerBitmap2) const;
/** Fill the given rectangle with the bitmap.
*/
void PaintCenter (
OutputDevice& rDevice,
const Rectangle& rBox) const;
private:
BitmapEx maBitmap;
Point maOffset;
@@ -102,6 +112,7 @@ private:
OffsetBitmap maShadowBottomLeft;
OffsetBitmap maShadowBottom;
OffsetBitmap maShadowBottomRight;
OffsetBitmap maShadowCenter;
bool mbIsValid;
};

View File

@@ -75,15 +75,16 @@ public:
void operator () (const double nTime);
void UpdateOffsets(
const sal_Int32 nInsertIndex,
const InsertPosition& rInsertPosition,
const Size& rRequiredSpace,
const view::Layouter& GetLayouter);
void ResetOffsets (void);
/// Index of the row or column that this run represents.
sal_Int32 mnRunIndex;
/// The index at which to make place for the insertion indicator (-1 for
/// no indicator).
sal_Int32 mnInsertIndex;
sal_Int32 mnLocalInsertIndex;
/// Index of the first page in the run.
sal_Int32 mnStartIndex;
/// Index of the last page in the run.
@@ -132,8 +133,7 @@ public:
virtual ~Implementation (void);
void SetInsertPosition (
const sal_Int32 nPageIndex,
const Pair& rVisualInsertionIndices,
const InsertPosition& rInsertPosition,
const Size& rIconSize);
void Reset (void);
@@ -150,15 +150,12 @@ private:
::boost::shared_ptr<controller::Animator> mpAnimator;
typedef ::std::set<SharedPageObjectRun, PageObjectRun::Comparator> RunContainer;
RunContainer maRuns;
/// The current insertion index. The special value -1 means that there
/// is no current insertion index.
sal_Int32 mnCurrentInsertPosition;
Pair maVisualInsertionIndices;
InsertPosition maInsertPosition;
void StopAnimation (void);
SharedPageObjectRun GetRun (
view::Layouter& rLayouter,
const sal_Int32 nRowIndex,
const InsertPosition& rInsertPosition,
const bool bCreate = true);
RunContainer::iterator FindRun (const sal_Int32 nRunIndex) const;
};
@@ -178,11 +175,10 @@ InsertAnimator::InsertAnimator (SlideSorter& rSlideSorter)
void InsertAnimator::SetInsertPosition (
const sal_Int32 nPageIndex,
const Pair& rVisualInsertionIndices,
const InsertPosition& rInsertPosition,
const Size& rIconSize)
{
mpImplementation->SetInsertPosition(nPageIndex, rVisualInsertionIndices, rIconSize);
mpImplementation->SetInsertPosition(rInsertPosition, rIconSize);
}
@@ -203,8 +199,7 @@ InsertAnimator::Implementation::Implementation (SlideSorter& rSlideSorter)
mrView(rSlideSorter.GetView()),
mpAnimator(rSlideSorter.GetController().GetAnimator()),
maRuns(),
mnCurrentInsertPosition(-1),
maVisualInsertionIndices()
maInsertPosition()
{
}
@@ -220,17 +215,15 @@ InsertAnimator::Implementation::~Implementation (void)
void InsertAnimator::Implementation::SetInsertPosition (
const sal_Int32 nPageIndex,
const Pair& rVisualInsertionIndices,
const InsertPosition& rInsertPosition,
const Size& rIconSize)
{
if (nPageIndex==mnCurrentInsertPosition && rVisualInsertionIndices==maVisualInsertionIndices)
if (maInsertPosition == rInsertPosition)
return;
SharedPageObjectRun pOldRun (GetRun(mrView.GetLayouter(), maVisualInsertionIndices.A()));
SharedPageObjectRun pCurrentRun (GetRun(mrView.GetLayouter(), rVisualInsertionIndices.A()));
mnCurrentInsertPosition = nPageIndex;
maVisualInsertionIndices = rVisualInsertionIndices;
SharedPageObjectRun pOldRun (GetRun(mrView.GetLayouter(), maInsertPosition));
SharedPageObjectRun pCurrentRun (GetRun(mrView.GetLayouter(), rInsertPosition));
maInsertPosition = rInsertPosition;
// When the new insert position is in a different run then move the page
// objects in the old run to their default positions.
@@ -238,7 +231,7 @@ void InsertAnimator::Implementation::SetInsertPosition (
{
if (pOldRun)
{
pOldRun->UpdateOffsets(-1, Size(0,0), mrView.GetLayouter());
pOldRun->ResetOffsets();
maRuns.insert(pOldRun);
}
}
@@ -247,7 +240,7 @@ void InsertAnimator::Implementation::SetInsertPosition (
{
const sal_Int32 nColumnCount (mrView.GetLayouter().GetColumnCount());
pCurrentRun->UpdateOffsets(
nColumnCount > 1 ? maVisualInsertionIndices.B() : maVisualInsertionIndices.A(),
rInsertPosition,
nColumnCount > 1 ? Size(rIconSize.Width(),0) : Size(0, rIconSize.Height()),
mrView.GetLayouter());
maRuns.insert(pCurrentRun);
@@ -259,7 +252,7 @@ void InsertAnimator::Implementation::SetInsertPosition (
void InsertAnimator::Implementation::Reset (void)
{
SetInsertPosition(-1, Pair(-1,-1), Size(0,0));
SetInsertPosition(InsertPosition(), Size(0,0));
}
@@ -267,10 +260,11 @@ void InsertAnimator::Implementation::Reset (void)
SharedPageObjectRun InsertAnimator::Implementation::GetRun (
view::Layouter& rLayouter,
const sal_Int32 nRowIndex,
const InsertPosition& rInsertPosition,
const bool bCreate)
{
if (nRowIndex < 0)
const sal_Int32 nRow (rInsertPosition.GetRow());
if (nRow < 0)
return SharedPageObjectRun();
RunContainer::iterator iRun (maRuns.end());
@@ -287,17 +281,17 @@ SharedPageObjectRun InsertAnimator::Implementation::GetRun (
}
else
{
iRun = FindRun(nRowIndex);
iRun = FindRun(nRow);
if (iRun == maRuns.end() && bCreate)
{
// Create a new run.
const sal_Int32 nStartIndex (rLayouter.GetIndex(nRowIndex,0));
const sal_Int32 nEndIndex (rLayouter.GetIndex(nRowIndex,rLayouter.GetColumnCount()-1));
const sal_Int32 nStartIndex (rLayouter.GetIndex(nRow, 0));
const sal_Int32 nEndIndex (rLayouter.GetIndex(nRow, rLayouter.GetColumnCount()-1));
if (nStartIndex <= nEndIndex)
{
iRun = maRuns.insert(SharedPageObjectRun(new PageObjectRun(
*this,
nRowIndex,
nRow,
nStartIndex,
nEndIndex))).first;
OSL_ASSERT(iRun != maRuns.end());
@@ -334,7 +328,7 @@ void InsertAnimator::Implementation::RemoveRun (PageObjectRun* pRun)
if (pRun != NULL)
{
// Do not remove runs that show the space for the insertion indicator.
if (pRun->mnInsertIndex == -1)
if (pRun->mnLocalInsertIndex == -1)
maRuns.erase(FindRun(pRun->mnRunIndex));
}
else
@@ -355,7 +349,7 @@ PageObjectRun::PageObjectRun (
const sal_Int32 nStartIndex,
const sal_Int32 nEndIndex)
: mnRunIndex(nRunIndex),
mnInsertIndex(-1),
mnLocalInsertIndex(-1),
mnStartIndex(nStartIndex),
mnEndIndex(nEndIndex),
maStartOffset(),
@@ -382,21 +376,25 @@ PageObjectRun::~PageObjectRun (void)
void PageObjectRun::UpdateOffsets(
const sal_Int32 nInsertIndex,
const InsertPosition& rInsertPosition,
const Size& rRequiredSpace,
const view::Layouter& rLayouter)
{
if (nInsertIndex != mnInsertIndex)
const sal_Int32 nLocalInsertIndex(rLayouter.GetColumnCount()==1
? rInsertPosition.GetRow()
: rInsertPosition.GetColumn());
if (nLocalInsertIndex != mnLocalInsertIndex)
{
mnInsertIndex = nInsertIndex;
mnLocalInsertIndex = nLocalInsertIndex;
model::SlideSorterModel& rModel (mrAnimatorAccess.GetModel());
Point aLeadingOffset;
Point aTrailingOffset;
const sal_Int32 nRunLength (mnEndIndex - mnStartIndex + 1);
const bool bUseX (rLayouter.GetColumnCount() > 1);
if (mnInsertIndex == 0)
const sal_Int32 nRunLength (mnEndIndex - mnStartIndex + 1);
if (rInsertPosition.IsAtRunStart())
{
// Insertion position is at the left or top of the run.
const Rectangle aInnerBox (rLayouter.GetPageObjectLayouter()->GetBoundingBox(
Point(0,0),
PageObjectLayouter::Preview,
@@ -407,8 +405,9 @@ void PageObjectRun::UpdateOffsets(
else
aTrailingOffset.Y() = ::std::max(0L, rRequiredSpace.Height()-aAvailableSpace.Y());
}
else if (mnInsertIndex == nRunLength)
else if (rInsertPosition.IsAtRunEnd() && rInsertPosition.IsExtraSpaceNeeded())
{
// Insertion position is at the right or bottom of the run.
const Rectangle aOuterBox (rLayouter.GetPageObjectBox(mnEndIndex));
const Rectangle aInnerBox (rLayouter.GetPageObjectLayouter()->GetBoundingBox(
aOuterBox.TopLeft(),
@@ -420,14 +419,15 @@ void PageObjectRun::UpdateOffsets(
else
aLeadingOffset.Y() = ::std::min(0L, aAvailableSpace.Y()-rRequiredSpace.Height());
}
else if (mnInsertIndex > 0)
else if ( ! rInsertPosition.IsAtRunEnd())
{
// Insertion position is somewhere in the middle of the run.
const Rectangle aBox1 (rLayouter.GetPageObjectLayouter()->GetBoundingBox(
rModel.GetPageDescriptor(mnStartIndex + nInsertIndex - 1),
rModel.GetPageDescriptor(mnStartIndex + mnLocalInsertIndex - 1),
PageObjectLayouter::Preview,
PageObjectLayouter::WindowCoordinateSystem));
const Rectangle aBox2 (rLayouter.GetPageObjectLayouter()->GetBoundingBox(
rModel.GetPageDescriptor(mnStartIndex + nInsertIndex),
rModel.GetPageDescriptor(mnStartIndex + mnLocalInsertIndex),
PageObjectLayouter::Preview,
PageObjectLayouter::WindowCoordinateSystem));
const Size aDelta (
@@ -449,7 +449,7 @@ void PageObjectRun::UpdateOffsets(
model::SharedPageDescriptor pDescriptor(rModel.GetPageDescriptor(nIndex+mnStartIndex));
if (pDescriptor)
maStartOffset[nIndex] = pDescriptor->GetVisualState().GetLocationOffset();
maEndOffset[nIndex] = nIndex < nInsertIndex
maEndOffset[nIndex] = nIndex < mnLocalInsertIndex
? aLeadingOffset
: aTrailingOffset;
}
@@ -460,6 +460,24 @@ void PageObjectRun::UpdateOffsets(
void PageObjectRun::ResetOffsets (void)
{
mnLocalInsertIndex = -1;
const sal_Int32 nRunLength (mnEndIndex - mnStartIndex + 1);
model::SlideSorterModel& rModel (mrAnimatorAccess.GetModel());
for (sal_Int32 nIndex=0; nIndex<nRunLength; ++nIndex)
{
model::SharedPageDescriptor pDescriptor(rModel.GetPageDescriptor(nIndex+mnStartIndex));
if (pDescriptor)
maStartOffset[nIndex] = pDescriptor->GetVisualState().GetLocationOffset();
maEndOffset[nIndex] = Point(0,0);
}
RestartAnimation();
}
void PageObjectRun::RestartAnimation (void)
{
// Stop the current animation.

View File

@@ -0,0 +1,449 @@
/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright 2008 by Sun Microsystems, Inc.
*
* OpenOffice.org - a multi-platform office productivity suite
*
* This file is part of OpenOffice.org.
*
* OpenOffice.org is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 3
* only, as published by the Free Software Foundation.
*
* OpenOffice.org is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License version 3 for more details
* (a copy is included in the LICENSE file that accompanied this code).
*
* You should have received a copy of the GNU Lesser General Public License
* version 3 along with OpenOffice.org. If not, see
* <http://www.openoffice.org/license.html>
* for a copy of the LGPLv3 License.
*
************************************************************************/
#include "precompiled_sd.hxx"
#include "view/SlsInsertionIndicatorOverlay.hxx"
#include "SlideSorter.hxx"
#include "model/SlsPageEnumeration.hxx"
#include "view/SlideSorterView.hxx"
#include "view/SlsLayouter.hxx"
#include "view/SlsPageObjectLayouter.hxx"
#include "view/SlsTheme.hxx"
#include "cache/SlsPageCache.hxx"
#include "controller/SlsTransferable.hxx"
#include "SlsFramePainter.hxx"
#include "SlsLayeredDevice.hxx"
#include "DrawDocShell.hxx"
#include "drawdoc.hxx"
#include "sdpage.hxx"
#include "sdmod.hxx"
#include <vcl/virdev.hxx>
#include <basegfx/range/b2drectangle.hxx>
#include <basegfx/tools/canvastools.hxx>
#include <basegfx/polygon/b2dpolygon.hxx>
#include <basegfx/polygon/b2dpolygontools.hxx>
namespace {
static const double gnPreviewOffsetScale = 1.0 / 8.0;
Rectangle GrowRectangle (const Rectangle& rBox, const sal_Int32 nOffset)
{
return Rectangle (
rBox.Left() - nOffset,
rBox.Top() - nOffset,
rBox.Right() + nOffset,
rBox.Bottom() + nOffset);
}
sal_Int32 RoundToInt (const double nValue) { return sal_Int32(::rtl::math::round(nValue)); }
} // end of anonymous namespace
namespace sd { namespace slidesorter { namespace view {
//===== InsertionIndicatorOverlay ===========================================
const static sal_Int32 gnShadowBorder = 3;
const static sal_Int32 gnSuperScaleFactor = 1;
const static sal_Int32 gnAngle = 0; // measured in 10th of degrees
InsertionIndicatorOverlay::InsertionIndicatorOverlay (SlideSorter& rSlideSorter)
: mrSlideSorter(rSlideSorter),
mbIsVisible(false),
mnLayerIndex(2),
mpLayerInvalidator(),
maLocation(),
maIcon(),
maIconOffset(),
mpShadowPainter(new FramePainter(mrSlideSorter.GetTheme()->GetIcon(Theme::RawInsertShadow)))
{
}
InsertionIndicatorOverlay::~InsertionIndicatorOverlay (void)
{
Hide();
}
void InsertionIndicatorOverlay::Create (const controller::Transferable* pTransferable)
{
if (pTransferable == NULL)
return;
sal_Int32 nSelectionCount (0);
if (pTransferable->HasPageBookmarks())
nSelectionCount = pTransferable->GetPageBookmarks().Count();
else
{
DrawDocShell* pDataDocShell = dynamic_cast<DrawDocShell*>(&pTransferable->GetDocShell());
if (pDataDocShell != NULL)
{
SdDrawDocument* pDataDocument = pDataDocShell->GetDoc();
if (pDataDocument != NULL)
nSelectionCount = pDataDocument->GetSdPageCount(PK_STANDARD);
}
}
Create(pTransferable->GetRepresentatives(), nSelectionCount);
}
void InsertionIndicatorOverlay::Create (
const ::std::vector<Bitmap>& rRepresentatives,
const sal_Int32 nSelectionCount)
{
view::Layouter& rLayouter (mrSlideSorter.GetView().GetLayouter());
::boost::shared_ptr<view::PageObjectLayouter> pPageObjectLayouter (
rLayouter.GetPageObjectLayouter());
::boost::shared_ptr<view::Theme> pTheme (mrSlideSorter.GetTheme());
const Size aOriginalPreviewSize (pPageObjectLayouter->GetPreviewSize());
const double nPreviewScale (0.5);
const Size aPreviewSize (
RoundToInt(aOriginalPreviewSize.Width()*nPreviewScale),
RoundToInt(aOriginalPreviewSize.Height()*nPreviewScale));
const sal_Int32 nOffset (
RoundToInt(Min(aPreviewSize.Width(),aPreviewSize.Height()) * gnPreviewOffsetScale));
// Determine size and offset depending on the number of previews.
sal_Int32 nCount (rRepresentatives.size());
if (nCount > 0)
--nCount;
Size aIconSize(
aPreviewSize.Width() + 2 * gnShadowBorder + nCount*nOffset,
aPreviewSize.Height() + 2 * gnShadowBorder + nCount*nOffset);
maIconOffset = Point(gnShadowBorder, gnShadowBorder);
// Create virtual devices for bitmap and mask whose bitmaps later be
// combined to form the BitmapEx of the icon.
VirtualDevice aContent (
*mrSlideSorter.GetContentWindow(),
0,
0);
if (gnAngle != 0)
{
aIconSize = Size(
RoundToInt(
cos(gnAngle/1800.0*M_PI) * aIconSize.Width()
+ sin(gnAngle/1800.0*M_PI) * aIconSize.Height()),
RoundToInt(
sin(gnAngle/1800.0*M_PI) * aIconSize.Width()
+ cos(gnAngle/1800.0*M_PI) * aIconSize.Height()));
}
aContent.SetOutputSizePixel(aIconSize);
aContent.SetFillColor();
aContent.SetLineColor(pTheme->GetColor(Theme::PreviewBorder));
const Point aOffset = PaintRepresentatives(aContent, aPreviewSize, nOffset, rRepresentatives);
PaintPageCount(aContent, nSelectionCount, aPreviewSize, aOffset);
maIcon = aContent.GetBitmapEx(Point(0,0), aIconSize);
maIcon.Scale(aIconSize);
}
void InsertionIndicatorOverlay::SelectRepresentatives (
model::PageEnumeration& rSelection,
::std::vector<model::SharedPageDescriptor>& rDescriptors) const
{
sal_Int32 nCount (0);
while (rSelection.HasMoreElements())
{
if (nCount++ >= 3)
break;
rDescriptors.push_back(rSelection.GetNextElement());
}
}
Point InsertionIndicatorOverlay::PaintRepresentatives (
OutputDevice& rContent,
const Size aPreviewSize,
const sal_Int32 nOffset,
const ::std::vector<Bitmap>& rRepresentatives) const
{
const Point aOffset (0,rRepresentatives.size()==1 ? -nOffset : 0);
// Paint the pages.
Point aPageOffset (0,0);
double nTransparency (0);
for (sal_Int32 nIndex=2; nIndex>=0; --nIndex)
{
if (rRepresentatives.size() <= nIndex)
continue;
switch(nIndex)
{
case 0 :
aPageOffset = Point(0, nOffset);
nTransparency = 0.85;
break;
case 1:
aPageOffset = Point(nOffset, 0);
nTransparency = 0.75;
break;
case 2:
aPageOffset = Point(2*nOffset, 2*nOffset);
nTransparency = 0.65;
break;
}
aPageOffset += aOffset;
aPageOffset.X() += gnShadowBorder;
aPageOffset.Y() += gnShadowBorder;
::boost::shared_ptr<cache::PageCache> pPreviewCache (
mrSlideSorter.GetView().GetPreviewCache());
Bitmap aPreview (rRepresentatives[nIndex]);
const double nScale (double(aPreviewSize.Width())/double(aPreview.GetSizePixel().Width()));
const Size aSuperSampleSize(
aPreviewSize.Width()*gnSuperScaleFactor,
aPreviewSize.Height()*gnSuperScaleFactor);
if (gnAngle != 0)
{
aPreview.Scale(aSuperSampleSize, BMP_SCALE_INTERPOLATE);
aPreview.Rotate(gnAngle, Color(128,0,0,255));
aPreview.Scale(1.0/gnSuperScaleFactor,1.0/gnSuperScaleFactor, BMP_SCALE_INTERPOLATE);
}
else
{
aPreview.Scale(aPreviewSize, BMP_SCALE_INTERPOLATE);
}
rContent.DrawBitmapEx(aPageOffset, aPreview);
// Tone down the bitmap. The further back the darker it becomes.
Rectangle aBox (
aPageOffset.X(),
aPageOffset.Y(),
aPageOffset.X()+aPreviewSize.Width()-1,
aPageOffset.Y()+aPreviewSize.Height()-1);
rContent.SetFillColor(COL_BLACK);
rContent.SetLineColor();
rContent.DrawTransparent(
::basegfx::B2DPolyPolygon(::basegfx::tools::createPolygonFromRect(
::basegfx::B2DRectangle(aBox.Left(), aBox.Top(), aBox.Right()+1, aBox.Bottom()+1),
0,
0)),
nTransparency);
// Draw border around preview.
Rectangle aBorderBox (GrowRectangle(aBox, 1));
rContent.SetLineColor(COL_GRAY);
rContent.SetFillColor();
rContent.DrawRect(aBorderBox);
// Draw shadow around preview.
mpShadowPainter->PaintFrame(rContent, aBorderBox);
}
return aPageOffset;
}
void InsertionIndicatorOverlay::PaintPageCount (
OutputDevice& rDevice,
const sal_Int32 nSelectionCount,
const Size aPreviewSize,
const Point aFirstPageOffset) const
{
// Paint the number of slides.
::boost::shared_ptr<view::Theme> pTheme (mrSlideSorter.GetTheme());
::boost::shared_ptr<Font> pFont(Theme::GetFont(Theme::PageCountFont, rDevice));
if (pFont)
{
::rtl::OUString sNumber (::rtl::OUString::valueOf(nSelectionCount));
// Determine the size of the (painted) text and create a bounding
// box that centers the text on the first preview.
rDevice.SetFont(*pFont);
Rectangle aTextBox;
rDevice.GetTextBoundRect(aTextBox, sNumber);
Point aTextOffset (aTextBox.TopLeft());
Size aTextSize (aTextBox.GetSize());
// Place text inside the first page preview.
Point aTextLocation(aFirstPageOffset);
// Center the text.
aTextLocation += Point(
(aPreviewSize.Width()-aTextBox.GetWidth())/2,
(aPreviewSize.Height()-aTextBox.GetHeight())/2);
aTextBox = Rectangle(aTextLocation, aTextSize);
// Paint background, border and text.
static const sal_Int32 nBorder = 5;
rDevice.SetFillColor(pTheme->GetColor(Theme::Selection));
rDevice.SetLineColor(pTheme->GetColor(Theme::Selection));
rDevice.DrawRect(GrowRectangle(aTextBox, nBorder));
rDevice.SetFillColor();
rDevice.SetLineColor(COL_WHITE);
rDevice.DrawRect(GrowRectangle(aTextBox, nBorder-1));
rDevice.SetTextColor(COL_WHITE);
rDevice.DrawText(aTextBox.TopLeft()-aTextOffset, sNumber);
}
}
void InsertionIndicatorOverlay::SetLocation (const Point& rLocation)
{
const Point aTopLeft (
rLocation - Point(
maIcon.GetSizePixel().Width()/2,
maIcon.GetSizePixel().Height()/2));
if (maLocation != aTopLeft)
{
const Rectangle aOldBoundingBox (GetBoundingBox());
maLocation = aTopLeft;
if (mpLayerInvalidator && IsVisible())
{
mpLayerInvalidator->Invalidate(aOldBoundingBox);
mpLayerInvalidator->Invalidate(GetBoundingBox());
}
}
}
void InsertionIndicatorOverlay::Paint (
OutputDevice& rDevice,
const Rectangle& rRepaintArea)
{
(void)rRepaintArea;
if ( ! IsVisible())
return;
rDevice.DrawImage(maLocation, maIcon);
}
void InsertionIndicatorOverlay::SetLayerInvalidator (const SharedILayerInvalidator& rpInvalidator)
{
mpLayerInvalidator = rpInvalidator;
if (mbIsVisible && mpLayerInvalidator)
mpLayerInvalidator->Invalidate(GetBoundingBox());
}
bool InsertionIndicatorOverlay::IsVisible (void) const
{
return mbIsVisible;
}
void InsertionIndicatorOverlay::Show (void)
{
if ( ! mbIsVisible)
{
mbIsVisible = true;
::boost::shared_ptr<LayeredDevice> pLayeredDevice (
mrSlideSorter.GetView().GetLayeredDevice());
if (pLayeredDevice)
{
pLayeredDevice->RegisterPainter(shared_from_this(), mnLayerIndex);
if (mpLayerInvalidator)
mpLayerInvalidator->Invalidate(GetBoundingBox());
}
}
}
void InsertionIndicatorOverlay::Hide (void)
{
if (mbIsVisible)
{
mbIsVisible = false;
::boost::shared_ptr<LayeredDevice> pLayeredDevice (
mrSlideSorter.GetView().GetLayeredDevice());
if (pLayeredDevice)
{
if (mpLayerInvalidator)
mpLayerInvalidator->Invalidate(GetBoundingBox());
pLayeredDevice->RemovePainter(shared_from_this(), mnLayerIndex);
}
}
}
Rectangle InsertionIndicatorOverlay::GetBoundingBox (void) const
{
return Rectangle(maLocation, maIcon.GetSizePixel());
}
Size InsertionIndicatorOverlay::GetSize (void) const
{
return Size(
maIcon.GetSizePixel().Width() + 10,
maIcon.GetSizePixel().Height() + 10);
}
} } } // end of namespace ::sd::slidesorter::view

View File

@@ -91,6 +91,7 @@ private:
};
} } } // end of namespace ::sd::slidesorter::view
#endif

View File

@@ -54,10 +54,12 @@ Layouter::Layouter (const SharedSdWindow& rpWindow)
mnPreferredWidth(200),
mnMaximalWidth(300),
mnMinimalColumnCount(1),
mnMaximalColumnCount(1),
mnMaximalColumnCount(4),
mnPageCount(0),
mnColumnCount(1),
mnRowCount(0),
mnMaxColumnCount(0),
mnMaxRowCount(0),
maPageObjectSize(1,1),
mbIsVertical(true)
{
@@ -211,6 +213,10 @@ bool Layouter::RearrangeHorizontal (
nPageCount));
maPageObjectSize = mpPageObjectLayouter->GetPageObjectSize();
mnMaxColumnCount = (rWindowSize.Width() - mnLeftBorder - mnRightBorder)
/ (maPageObjectSize.Width() + mnHorizontalGap);
mnMaxRowCount = 1;
return true;
}
else
@@ -289,6 +295,11 @@ bool Layouter::RearrangeVertical (
nPageCount));
maPageObjectSize = mpPageObjectLayouter->GetPageObjectSize();
mnMaxColumnCount = (rWindowSize.Width() - mnLeftBorder - mnRightBorder)
/ (maPageObjectSize.Width() + mnHorizontalGap);
mnMaxRowCount = (rWindowSize.Height() - mnTopBorder - mnBottomBorder)
/ (maPageObjectSize.Height() + mnVerticalGap);
return true;
}
else
@@ -462,15 +473,54 @@ Rectangle Layouter::GetPreviewBox (const sal_Int32 nIndex) const
Point Layouter::GetInsertionIndicatorLocation (
const Pair& rVisualIndices,
const Size& rIndicatorSize) const
InsertPosition Layouter::GetInsertPosition (
const Point& rModelPosition,
const Size& rIndicatorSize) const
{
if (rVisualIndices.B() < 0)
InsertPosition aPosition;
// Determine logical position.
if (mnColumnCount == 1)
{
const sal_Int32 nY = rModelPosition.Y() - mnTopBorder + maPageObjectSize.Height()/2;
const sal_Int32 nRowHeight (maPageObjectSize.Height() + mnVerticalGap);
aPosition.mnRow = ::std::min(mnPageCount, nY / nRowHeight);
aPosition.mnColumn = 0;
aPosition.mnIndex = aPosition.mnRow;
aPosition.mbIsAtRunStart = (aPosition.mnRow == 0);
aPosition.mbIsAtRunEnd = (aPosition.mnRow == mnRowCount);
aPosition.mbIsExtraSpaceNeeded = (aPosition.mnRow >= mnMaxRowCount);
}
else
{
aPosition.mnRow = ::std::min(
mnRowCount-1,
GetRowAtPosition (rModelPosition.Y(), true, GM_BOTH));
const sal_Int32 nX = rModelPosition.X() - mnLeftBorder + maPageObjectSize.Width()/2;
const sal_Int32 nRowWidth (maPageObjectSize.Width() + mnHorizontalGap);
aPosition.mnColumn = ::std::min(mnColumnCount, nX / nRowWidth);
aPosition.mnIndex = aPosition.mnRow * mnColumnCount + aPosition.mnColumn;
aPosition.mbIsAtRunStart = (aPosition.mnColumn == 0);
aPosition.mbIsAtRunEnd = (aPosition.mnColumn == mnColumnCount);
if (aPosition.mnIndex >= mnPageCount)
{
aPosition.mnIndex = mnPageCount;
aPosition.mnRow = mnRowCount-1;
aPosition.mnColumn = mnPageCount%mnColumnCount;
aPosition.mbIsAtRunEnd = true;
}
aPosition.mbIsExtraSpaceNeeded = (aPosition.mnColumn >= mnMaxColumnCount);
}
// Determine visual position.
if (mnColumnCount == 1)
{
// Place indicator between rows of a single column of pages.
if (rVisualIndices.A() == 0)
if (aPosition.mbIsAtRunStart)
{
// Place indicator at the top of the column.
const Rectangle aOuterBox (GetPageObjectBox(0));
@@ -478,71 +528,95 @@ Point Layouter::GetInsertionIndicatorLocation (
aOuterBox.TopLeft(),
PageObjectLayouter::Preview,
PageObjectLayouter::WindowCoordinateSystem));
return Point(aPreviewBox.Center().X(), aOuterBox.Top()+rIndicatorSize.Height()/2);
aPosition.maLocation.X() = aPreviewBox.Center().X();
aPosition.maLocation.Y() = aOuterBox.Top()+rIndicatorSize.Height()/2;
}
else if (rVisualIndices.A() == mnRowCount)
else if (aPosition.mbIsAtRunEnd)
{
// Place indicator at the bottom of the column.
const Rectangle aOuterBox (GetPageObjectBox(mnRowCount-1));
const Rectangle aPreviewBox (mpPageObjectLayouter->GetBoundingBox(
aOuterBox.TopLeft(),
PageObjectLayouter::Preview,
PageObjectLayouter::WindowCoordinateSystem));
return Point(aPreviewBox.Center().X(), aOuterBox.Bottom()-rIndicatorSize.Height()/2);
if (aPosition.mbIsExtraSpaceNeeded)
{
// Place indicator at the bottom of the column.
aPosition.maLocation.X() = aPreviewBox.Center().X();
aPosition.maLocation.Y() = aOuterBox.Bottom()-rIndicatorSize.Height()/2;
}
else
{
// Place indicator at the bottom of the column in the space
// that is available below the last page.
aPosition.maLocation.X() = aPreviewBox.Center().X();
aPosition.maLocation.Y() = aOuterBox.Bottom()+rIndicatorSize.Height()/2;
}
}
else
{
// Place indicator between two rows.
const Rectangle aBox1 (mpPageObjectLayouter->GetBoundingBox(
GetPageObjectBox(rVisualIndices.A()-1).TopLeft(),
GetPageObjectBox(aPosition.mnRow-1).TopLeft(),
PageObjectLayouter::Preview,
PageObjectLayouter::WindowCoordinateSystem));
const Rectangle aBox2 (mpPageObjectLayouter->GetBoundingBox(
GetPageObjectBox(rVisualIndices.A()).TopLeft(),
GetPageObjectBox(aPosition.mnRow).TopLeft(),
PageObjectLayouter::Preview,
PageObjectLayouter::WindowCoordinateSystem));
return (aBox1.Center() + aBox2.Center() + Point(1,1)) / 2;
aPosition.maLocation = (aBox1.Center() + aBox2.Center() + Point(1,1)) / 2;
}
}
else
{
// Place indicator between columns in one row.
const sal_Int32 nIndex (rVisualIndices.A() * mnColumnCount + rVisualIndices.B());
if (rVisualIndices.B() == 0)
if (aPosition.mbIsAtRunStart)
{
// Place indicator at the left of the row.
const Rectangle aOuterBox (GetPageObjectBox(nIndex));
const Rectangle aOuterBox (GetPageObjectBox(aPosition.mnIndex));
const Rectangle aPreviewBox (mpPageObjectLayouter->GetBoundingBox(
aOuterBox.TopLeft(),
PageObjectLayouter::Preview,
PageObjectLayouter::WindowCoordinateSystem));
return Point(aOuterBox.Left()+rIndicatorSize.Width()/2, aPreviewBox.Center().Y());
aPosition.maLocation.X() = aOuterBox.Left()+rIndicatorSize.Width()/2;
aPosition.maLocation.Y() = aPreviewBox.Center().Y();
}
else if (rVisualIndices.B() == mnColumnCount)
else if (aPosition.mbIsAtRunEnd)
{
// Place indicator at the end of the row.
const Rectangle aOuterBox (GetPageObjectBox(nIndex-1));
const Rectangle aOuterBox (GetPageObjectBox(aPosition.mnIndex-1));
const Rectangle aPreviewBox (mpPageObjectLayouter->GetBoundingBox(
aOuterBox.TopLeft(),
PageObjectLayouter::Preview,
PageObjectLayouter::WindowCoordinateSystem));
return Point(aOuterBox.Right()-rIndicatorSize.Width()/2, aPreviewBox.Center().Y());
if (aPosition.mbIsExtraSpaceNeeded)
{
// Place indicator at the end of the row.
aPosition.maLocation.X() = aOuterBox.Right()-rIndicatorSize.Width()/2;
aPosition.maLocation.Y() = aPreviewBox.Center().Y();
}
else
{
// Place indicator at the end of the row in the available
// space at its right end.
aPosition.maLocation.X() = aOuterBox.Right()+rIndicatorSize.Width()/2;
aPosition.maLocation.Y() = aPreviewBox.Center().Y();
}
}
else
{
// Place indicator between two columns.
const Rectangle aBox1 (mpPageObjectLayouter->GetBoundingBox(
GetPageObjectBox(nIndex-1).TopLeft(),
GetPageObjectBox(aPosition.mnIndex-1).TopLeft(),
PageObjectLayouter::Preview,
PageObjectLayouter::WindowCoordinateSystem));
const Rectangle aBox2 (mpPageObjectLayouter->GetBoundingBox(
GetPageObjectBox(nIndex).TopLeft(),
GetPageObjectBox(aPosition.mnIndex).TopLeft(),
PageObjectLayouter::Preview,
PageObjectLayouter::WindowCoordinateSystem));
return (aBox1.Center() + aBox2.Center() + Point(1,1)) / 2;
aPosition.maLocation = (aBox1.Center() + aBox2.Center() + Point(1,1)) / 2;
}
}
return aPosition;
}
@@ -581,31 +655,6 @@ sal_Int32 Layouter::GetIndexAtPoint (
sal_Int32 Layouter::GetVerticalInsertionIndex (const Point& rPosition) const
{
OSL_ASSERT(mnColumnCount == 1);
const sal_Int32 nY = rPosition.Y() - mnTopBorder + maPageObjectSize.Height()/2;
const sal_Int32 nRowHeight (maPageObjectSize.Height() + mnVerticalGap);
return nY / nRowHeight;
}
Pair Layouter::GetGridInsertionIndices (const Point& rPosition) const
{
const sal_Int32 nRow = GetRowAtPosition (rPosition.Y(), true, GM_BOTH);
const sal_Int32 nX = rPosition.X() - mnLeftBorder + maPageObjectSize.Width()/2;
const sal_Int32 nRowWidth (maPageObjectSize.Width() + mnHorizontalGap);
return Pair(nRow, nX / nRowWidth);
}
bool Layouter::IsVertical (void) const
{
return mbIsVertical;
@@ -753,4 +802,59 @@ sal_Int32 Layouter::ResolvePositionInGap (
//===== InsertPosition ========================================================
InsertPosition::InsertPosition (void)
: mnRow(-1),
mnColumn(-1),
mnIndex(-1),
maLocation(0,0),
mbIsAtRunStart(false),
mbIsAtRunEnd(false),
mbIsExtraSpaceNeeded(false)
{
}
InsertPosition& InsertPosition::operator= (const InsertPosition& rInsertPosition)
{
if (this != &rInsertPosition)
{
mnRow = rInsertPosition.mnRow;
mnColumn = rInsertPosition.mnColumn;
mnIndex = rInsertPosition.mnIndex;
maLocation = rInsertPosition.maLocation;
mbIsAtRunStart = rInsertPosition.mbIsAtRunStart;
mbIsAtRunEnd = rInsertPosition.mbIsAtRunEnd;
mbIsExtraSpaceNeeded = rInsertPosition.mbIsExtraSpaceNeeded;
}
return *this;
}
bool InsertPosition::operator== (const InsertPosition& rInsertPosition) const
{
// Do not compare the geometrical information (maLocation).
return mnRow==rInsertPosition.mnRow
&& mnColumn==rInsertPosition.mnColumn
&& mnIndex==rInsertPosition.mnIndex
&& mbIsAtRunStart==rInsertPosition.mbIsAtRunStart
&& mbIsAtRunEnd==rInsertPosition.mbIsAtRunEnd
&& mbIsExtraSpaceNeeded==rInsertPosition.mbIsExtraSpaceNeeded;
}
bool InsertPosition::operator!= (const InsertPosition& rInsertPosition) const
{
return !operator==(rInsertPosition);
}
} } } // end of namespace ::sd::slidesorter::namespace

View File

@@ -287,14 +287,14 @@ void PageObjectPainter::PaintPreview (
if (rpDescriptor->GetVisualState().GetCurrentVisualState()
== model::VisualState::VS_Excluded)
{
rDevice.SetFillColor(COL_BLACK);
rDevice.SetFillColor(COL_GRAY);
rDevice.SetLineColor();
rDevice.DrawTransparent(
::basegfx::B2DPolyPolygon(::basegfx::tools::createPolygonFromRect(
::basegfx::B2DRectangle(aBox.Left(), aBox.Top(), aBox.Right()+1, aBox.Bottom()+1),
0,
0)),
0.5);
0.3);
}
}
@@ -506,11 +506,6 @@ Bitmap PageObjectPainter::CreateBackgroundBitmap(
Rectangle aFrameBox (aBox.Left()-1,aBox.Top()-1,aBox.Right()+1,aBox.Bottom()+1);
mpShadowPainter->PaintFrame(aBitmapDevice, aFrameBox);
// Clear the area where the preview will later be painted.
aBitmapDevice.SetFillColor(mpTheme->GetColor(Theme::PageBackground));
aBitmapDevice.SetLineColor(mpTheme->GetColor(Theme::PageBackground));
aBitmapDevice.DrawRect(aBox);
return aBitmapDevice.GetBitmap (Point(0,0),aSize);
}

View File

@@ -1,718 +0,0 @@
/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright 2008 by Sun Microsystems, Inc.
*
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: SlsViewOverlay.cxx,v $
* $Revision: 1.16 $
*
* This file is part of OpenOffice.org.
*
* OpenOffice.org is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 3
* only, as published by the Free Software Foundation.
*
* OpenOffice.org is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License version 3 for more details
* (a copy is included in the LICENSE file that accompanied this code).
*
* You should have received a copy of the GNU Lesser General Public License
* version 3 along with OpenOffice.org. If not, see
* <http://www.openoffice.org/license.html>
* for a copy of the LGPLv3 License.
*
************************************************************************/
#include "precompiled_sd.hxx"
#include "view/SlsViewOverlay.hxx"
#include "SlideSorter.hxx"
#include "SlideSorterViewShell.hxx"
#include "SlsLayeredDevice.hxx"
#include "SlsFramePainter.hxx"
#include "model/SlideSorterModel.hxx"
#include "model/SlsPageDescriptor.hxx"
#include "model/SlsPageEnumeration.hxx"
#include "view/SlideSorterView.hxx"
#include "view/SlsLayouter.hxx"
#include "view/SlsTheme.hxx"
#include "cache/SlsPageCache.hxx"
#include "ViewShell.hxx"
#include "ViewShellBase.hxx"
#include "UpdateLockManager.hxx"
#include "Window.hxx"
#include "sdpage.hxx"
#include "sdresid.hxx"
#include <basegfx/range/b2drectangle.hxx>
#include <basegfx/range/b2drange.hxx>
#include <basegfx/range/b2irange.hxx>
#include <basegfx/matrix/b2dhommatrix.hxx>
#include <basegfx/polygon/b2dpolygontools.hxx>
#include <basegfx/polygon/b2dpolypolygontools.hxx>
#include <basegfx/matrix/b2dhommatrixtools.hxx>
#include <basegfx/tools/canvastools.hxx>
#include <svx/sdr/overlay/overlaymanager.hxx>
#include <svx/svdpagv.hxx>
#include <svx/sdrpagewindow.hxx>
#include <vcl/svapp.hxx>
#include <vcl/bmpacc.hxx>
#include <rtl/math.hxx>
#include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
#include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx>
using namespace ::sdr::overlay;
using namespace ::basegfx;
#define A2S(pString) (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(pString)))
namespace {
#define Amber 0x007fff
static const double gnPreviewOffsetScale = 1.0 / 8.0;
Rectangle GrowRectangle (const Rectangle& rBox, const sal_Int32 nOffset)
{
return Rectangle (
rBox.Left() - nOffset,
rBox.Top() - nOffset,
rBox.Right() + nOffset,
rBox.Bottom() + nOffset);
}
Rectangle ConvertRectangle (const B2DRectangle& rBox)
{
const B2IRange rIntegerBox (unotools::b2ISurroundingRangeFromB2DRange(rBox));
return Rectangle(
rIntegerBox.getMinX(),
rIntegerBox.getMinY(),
rIntegerBox.getMaxX(),
rIntegerBox.getMaxY());
}
sal_Int32 RoundToInt (const double nValue) { return sal_Int32(::rtl::math::round(nValue)); }
} // end of anonymous namespace
namespace sd { namespace slidesorter { namespace view {
//===== ViewOverlay =========================================================
ViewOverlay::ViewOverlay (
SlideSorter& rSlideSorter,
const ::boost::shared_ptr<LayeredDevice>& rpLayeredDevice)
: mrSlideSorter(rSlideSorter),
mpLayeredDevice(rpLayeredDevice),
mpSelectionRectangleOverlay(new SelectionRectangleOverlay(*this, 3)),
mpInsertionIndicatorOverlay(new InsertionIndicatorOverlay(*this, 4)),
mpSubstitutionOverlay(new SubstitutionOverlay(*this, 3))
{
}
ViewOverlay::~ViewOverlay (void)
{
}
::boost::shared_ptr<SelectionRectangleOverlay> ViewOverlay::GetSelectionRectangleOverlay (void)
{
return mpSelectionRectangleOverlay;
}
::boost::shared_ptr<InsertionIndicatorOverlay> ViewOverlay::GetInsertionIndicatorOverlay (void)
{
return mpInsertionIndicatorOverlay;
}
::boost::shared_ptr<SubstitutionOverlay> ViewOverlay::GetSubstitutionOverlay (void)
{
return mpSubstitutionOverlay;
}
SlideSorter& ViewOverlay::GetSlideSorter (void) const
{
return mrSlideSorter;
}
::boost::shared_ptr<LayeredDevice> ViewOverlay::GetLayeredDevice (void) const
{
return mpLayeredDevice;
}
//===== OverlayBase::Invalidator ==============================================
class OverlayBase::Invalidator
{
public:
Invalidator (OverlayBase& rOverlayObject)
: mrOverlayObject(rOverlayObject),
maOldBoundingBox(rOverlayObject.IsVisible()
? rOverlayObject.GetBoundingBox()
: Rectangle())
{
}
~Invalidator (void)
{
if ( ! maOldBoundingBox.IsEmpty())
mrOverlayObject.Invalidate(maOldBoundingBox);
if (mrOverlayObject.IsVisible())
mrOverlayObject.Invalidate(mrOverlayObject.GetBoundingBox());
}
private:
OverlayBase& mrOverlayObject;
const Rectangle maOldBoundingBox;
};
//===== OverlayBase =========================================================
OverlayBase::OverlayBase (
ViewOverlay& rViewOverlay,
const sal_Int32 nLayerIndex)
: mrViewOverlay(rViewOverlay),
mbIsVisible(false),
mnLayerIndex(nLayerIndex)
{
}
OverlayBase::~OverlayBase (void)
{
}
bool OverlayBase::IsVisible (void) const
{
return mbIsVisible;
}
void OverlayBase::SetIsVisible (const bool bIsVisible)
{
if (mbIsVisible != bIsVisible)
{
Invalidator aInvalidator (*this);
mbIsVisible = bIsVisible;
::boost::shared_ptr<LayeredDevice> pDevice (mrViewOverlay.GetLayeredDevice());
if (pDevice)
if (mbIsVisible)
{
pDevice->RegisterPainter(shared_from_this(), GetLayerIndex());
Invalidate(GetBoundingBox());
}
else
{
Invalidate(GetBoundingBox());
pDevice->RemovePainter(shared_from_this(), GetLayerIndex());
}
}
}
void OverlayBase::SetLayerInvalidator (const SharedILayerInvalidator& rpInvalidator)
{
if ( ! rpInvalidator)
Invalidate(GetBoundingBox());
mpLayerInvalidator = rpInvalidator;
if (mbIsVisible)
Invalidate(GetBoundingBox());
}
void OverlayBase::Invalidate (const Rectangle& rInvalidationBox)
{
if (mpLayerInvalidator)
mpLayerInvalidator->Invalidate(rInvalidationBox);
}
sal_Int32 OverlayBase::GetLayerIndex (void) const
{
return mnLayerIndex;
}
//===== SubstitutionOverlay =================================================
const sal_Int32 SubstitutionOverlay::mnCenterTransparency (60);
const sal_Int32 SubstitutionOverlay::mnSideTransparency (85);
const sal_Int32 SubstitutionOverlay::mnCornerTransparency (95);
SubstitutionOverlay::SubstitutionOverlay (
ViewOverlay& rViewOverlay,
const sal_Int32 nLayerIndex)
: OverlayBase(rViewOverlay, nLayerIndex),
maPosition(0,0)
{
}
SubstitutionOverlay::~SubstitutionOverlay (void)
{
}
void SubstitutionOverlay::Clear (void)
{
SetIsVisible(false);
}
void SubstitutionOverlay::SetAnchor (const Point& rAnchor)
{
(void)rAnchor;
}
void SubstitutionOverlay::Move (const Point& rOffset)
{
(void)rOffset;
}
void SubstitutionOverlay::SetPosition (const Point& rPosition)
{
(void)rPosition;
}
Point SubstitutionOverlay::GetPosition (void) const
{
return Point(0,0);
}
void SubstitutionOverlay::Paint (
OutputDevice& rDevice,
const Rectangle& rRepaintArea)
{
(void)rDevice;
(void)rRepaintArea;
}
Rectangle SubstitutionOverlay::GetBoundingBox (void) const
{
return Rectangle();
}
//===== SelectionRectangleOverlay ===========================================
SelectionRectangleOverlay::SelectionRectangleOverlay (
ViewOverlay& rViewOverlay,
const sal_Int32 nLayerIndex)
: OverlayBase (rViewOverlay, nLayerIndex),
maAnchor(0,0),
maSecondCorner(0,0)
{
}
Rectangle SelectionRectangleOverlay::GetSelectionRectangle (void)
{
return Rectangle(maAnchor, maSecondCorner);
}
void SelectionRectangleOverlay::Start (const Point& rAnchor)
{
SetIsVisible(false);
maAnchor = rAnchor;
maSecondCorner = rAnchor;
}
void SelectionRectangleOverlay::Update (const Point& rSecondCorner)
{
Invalidator aInvalidator (*this);
maSecondCorner = rSecondCorner;
SetIsVisible(true);
}
void SelectionRectangleOverlay::Paint (
OutputDevice& rDevice,
const Rectangle& rRepaintArea)
{
if ( ! IsVisible())
return;
rDevice.SetFillColor(Color(Amber));
rDevice.SetLineColor(Color(Amber));
const Rectangle aBox (
::std::min(maAnchor.X(), maSecondCorner.X()),
::std::min(maAnchor.Y(), maSecondCorner.Y()),
::std::max(maAnchor.X(), maSecondCorner.X()),
::std::max(maAnchor.Y(), maSecondCorner.Y()));
if (rRepaintArea.IsOver(aBox))
rDevice.DrawTransparent(
::basegfx::B2DPolyPolygon(
::basegfx::tools::createPolygonFromRect(
::basegfx::B2DRectangle(aBox.Left(), aBox.Top(), aBox.Right(), aBox.Bottom()),
5.0/aBox.GetWidth(),
5.0/aBox.GetHeight())),
0.5);
}
Rectangle SelectionRectangleOverlay::GetBoundingBox (void) const
{
return GrowRectangle(Rectangle(
::std::min(maAnchor.X(), maSecondCorner.X()),
::std::min(maAnchor.Y(), maSecondCorner.Y()),
::std::max(maAnchor.X(), maSecondCorner.X()),
::std::max(maAnchor.Y(), maSecondCorner.Y())),
+1);
}
//===== InsertionIndicatorOverlay ===========================================
const static sal_Int32 gnShadowBorder = 3;
InsertionIndicatorOverlay::InsertionIndicatorOverlay (
ViewOverlay& rViewOverlay,
const sal_Int32 nLayerIndex)
: OverlayBase (rViewOverlay, nLayerIndex),
maLocation(),
maIcon(),
mpShadowPainter(new FramePainter(
rViewOverlay.GetSlideSorter().GetTheme()->GetIcon(Theme::RawInsertShadow)))
{
}
void InsertionIndicatorOverlay::Create (model::PageEnumeration& rSelection)
{
view::Layouter& rLayouter (mrViewOverlay.GetSlideSorter().GetView().GetLayouter());
::boost::shared_ptr<view::PageObjectLayouter> pPageObjectLayouter (
rLayouter.GetPageObjectLayouter());
::boost::shared_ptr<view::Theme> pTheme (mrViewOverlay.GetSlideSorter().GetTheme());
const Size aOriginalPreviewSize (pPageObjectLayouter->GetPreviewSize());
const double nPreviewScale (0.5);
const Size aPreviewSize (
RoundToInt(aOriginalPreviewSize.Width()*nPreviewScale),
RoundToInt(aOriginalPreviewSize.Height()*nPreviewScale));
const sal_Int32 nOffset (
RoundToInt(Min(aPreviewSize.Width(),aPreviewSize.Height()) * gnPreviewOffsetScale));
::std::vector<model::SharedPageDescriptor> aDescriptors;
SelectRepresentatives(rSelection, aDescriptors);
// Determine size and offset depending on the number of previews.
sal_Int32 nCount (aDescriptors.size());
if (nCount > 0)
--nCount;
Size aIconSize(
aPreviewSize.Width() + 2 * gnShadowBorder + nCount*nOffset,
aPreviewSize.Height() + 2 * gnShadowBorder + nCount*nOffset);
maIconOffset = Point(gnShadowBorder, gnShadowBorder);
// Create virtual devices for bitmap and mask whose bitmaps later be
// combined to form the BitmapEx of the icon.
VirtualDevice aContent (
*mrViewOverlay.GetSlideSorter().GetContentWindow(),
0,
0);
aContent.SetOutputSizePixel(aIconSize);
aContent.SetFillColor();
aContent.SetLineColor(pTheme->GetColor(Theme::PreviewBorder));
const Point aOffset = PaintRepresentatives(aContent, aPreviewSize, nOffset, aDescriptors);
PaintPageCount(aContent, rSelection, aPreviewSize, aOffset);
maIcon = aContent.GetBitmapEx(Point(0,0), aIconSize);
}
void InsertionIndicatorOverlay::SelectRepresentatives (
model::PageEnumeration& rSelection,
::std::vector<model::SharedPageDescriptor>& rDescriptors) const
{
sal_Int32 nCount (0);
while (rSelection.HasMoreElements())
{
if (nCount++ >= 3)
break;
rDescriptors.push_back(rSelection.GetNextElement());
}
}
Point InsertionIndicatorOverlay::PaintRepresentatives (
OutputDevice& rContent,
const Size aPreviewSize,
const sal_Int32 nOffset,
const ::std::vector<model::SharedPageDescriptor>& rDescriptors) const
{
const Point aOffset (0,rDescriptors.size()==1 ? -nOffset : 0);
// Paint the pages.
Point aPageOffset (0,0);
double nTransparency (0);
for (sal_Int32 nIndex=2; nIndex>=0; --nIndex)
{
if (rDescriptors.size() <= nIndex)
continue;
switch(nIndex)
{
case 0 :
aPageOffset = Point(0, nOffset);
nTransparency = 0.85;
break;
case 1:
aPageOffset = Point(nOffset, 0);
nTransparency = 0.75;
break;
case 2:
aPageOffset = Point(2*nOffset, 2*nOffset);
nTransparency = 0.65;
break;
}
aPageOffset += aOffset;
aPageOffset.X() += gnShadowBorder;
aPageOffset.Y() += gnShadowBorder;
::boost::shared_ptr<cache::PageCache> pPreviewCache (
mrViewOverlay.GetSlideSorter().GetView().GetPreviewCache());
BitmapEx aPreview (pPreviewCache->GetPreviewBitmap(rDescriptors[nIndex]->GetPage()));
aPreview.Scale(aPreviewSize, BMP_SCALE_INTERPOLATE);
rContent.DrawBitmapEx(aPageOffset, aPreview);
// Tone down the bitmap. The further back the darker it becomes.
Rectangle aBox (
aPageOffset.X(),
aPageOffset.Y(),
aPageOffset.X()+aPreviewSize.Width()-1,
aPageOffset.Y()+aPreviewSize.Height()-1);
rContent.SetFillColor(COL_BLACK);
rContent.SetLineColor();
rContent.DrawTransparent(
::basegfx::B2DPolyPolygon(::basegfx::tools::createPolygonFromRect(
::basegfx::B2DRectangle(aBox.Left(), aBox.Top(), aBox.Right()+1, aBox.Bottom()+1),
0,
0)),
nTransparency);
// Draw border around preview.
Rectangle aBorderBox (GrowRectangle(aBox, 1));
rContent.SetLineColor(COL_GRAY);
rContent.SetFillColor();
rContent.DrawRect(aBorderBox);
// Draw shadow around preview.
mpShadowPainter->PaintFrame(rContent, aBorderBox);
}
return aPageOffset;
}
void InsertionIndicatorOverlay::PaintPageCount (
OutputDevice& rDevice,
model::PageEnumeration& rSelection,
const Size aPreviewSize,
const Point aFirstPageOffset) const
{
// Paint the number of slides.
::boost::shared_ptr<view::Theme> pTheme (mrViewOverlay.GetSlideSorter().GetTheme());
::boost::shared_ptr<Font> pFont(Theme::GetFont(Theme::PageCountFont, rDevice));
if (pFont)
{
// Count the elements in the selection and create a string for the
// result.
sal_Int32 nSelectionCount (0);
rSelection.Rewind();
while (rSelection.HasMoreElements())
{
rSelection.GetNextElement();
++nSelectionCount;
}
::rtl::OUString sNumber (::rtl::OUString::valueOf(nSelectionCount));
// Determine the size of the (painted) text and create a bounding
// box that centers the text on the first preview.
rDevice.SetFont(*pFont);
Rectangle aTextBox;
rDevice.GetTextBoundRect(aTextBox, sNumber);
Point aTextOffset (aTextBox.TopLeft());
Size aTextSize (aTextBox.GetSize());
// Place text inside the first page preview.
Point aTextLocation(aFirstPageOffset);
// Center the text.
aTextLocation += Point(
(aPreviewSize.Width()-aTextBox.GetWidth())/2,
(aPreviewSize.Height()-aTextBox.GetHeight())/2);
aTextBox = Rectangle(aTextLocation, aTextSize);
// Paint background, border and text.
static const sal_Int32 nBorder = 5;
rDevice.SetFillColor(pTheme->GetColor(Theme::Selection));
rDevice.SetLineColor(pTheme->GetColor(Theme::Selection));
rDevice.DrawRect(GrowRectangle(aTextBox, nBorder));
rDevice.SetFillColor();
rDevice.SetLineColor(COL_WHITE);
rDevice.DrawRect(GrowRectangle(aTextBox, nBorder-1));
rDevice.SetTextColor(COL_WHITE);
rDevice.DrawText(aTextBox.TopLeft()-aTextOffset, sNumber);
}
}
void InsertionIndicatorOverlay::Create (void)
{
}
void InsertionIndicatorOverlay::SetLocation (const Point& rLocation)
{
const Point aTopLeft (
rLocation - Point(
maIcon.GetSizePixel().Width()/2,
maIcon.GetSizePixel().Height()/2));
if (maLocation != aTopLeft)
{
Invalidator aInvalidator (*this);
maLocation = aTopLeft;
}
}
void InsertionIndicatorOverlay::Paint (
OutputDevice& rDevice,
const Rectangle& rRepaintArea)
{
(void)rRepaintArea;
if ( ! IsVisible())
return;
rDevice.DrawImage(maLocation, maIcon);
}
Rectangle InsertionIndicatorOverlay::GetBoundingBox (void) const
{
return Rectangle(maLocation, maIcon.GetSizePixel());
}
Size InsertionIndicatorOverlay::GetSize (void) const
{
return Size(
maIcon.GetSizePixel().Width() + 10,
maIcon.GetSizePixel().Height() + 10);
}
} } } // end of namespace ::sd::slidesorter::view

View File

@@ -57,13 +57,13 @@ SLOFILES = \
$(SLO)$/SlsFontProvider.obj \
$(SLO)$/SlsFramePainter.obj \
$(SLO)$/SlsInsertAnimator.obj \
$(SLO)$/SlsInsertionIndicatorOverlay.obj\
$(SLO)$/SlsLayeredDevice.obj \
$(SLO)$/SlsLayouter.obj \
$(SLO)$/SlsPageObjectLayouter.obj \
$(SLO)$/SlsPageObjectPainter.obj \
$(SLO)$/SlsTheme.obj \
$(SLO)$/SlsViewCacheContext.obj \
$(SLO)$/SlsViewOverlay.obj
$(SLO)$/SlsViewCacheContext.obj
# --- Tagets -------------------------------------------------------

View File

@@ -90,7 +90,7 @@
#include "TestPanel.hxx"
#endif
#define SHOW_COLOR_MENU
//#define SHOW_COLOR_MENU
#ifdef SHOW_COLOR_MENU
#include "TestMenu.hxx"
#endif