1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <view/SlideSorterView.hxx>
22 #include <SlideSorter.hxx>
23 #include <ViewShell.hxx>
24 #include "SlsViewCacheContext.hxx"
25 #include "SlsLayeredDevice.hxx"
26 #include <view/SlsLayouter.hxx>
27 #include <view/SlsPageObjectLayouter.hxx>
28 #include <view/SlsPageObjectPainter.hxx>
29 #include <view/SlsILayerPainter.hxx>
30 #include <view/SlsToolTip.hxx>
31 #include <controller/SlideSorterController.hxx>
32 #include <controller/SlsClipboard.hxx>
33 #include <model/SlideSorterModel.hxx>
34 #include <model/SlsPageEnumerationProvider.hxx>
35 #include <model/SlsPageDescriptor.hxx>
36 #include <cache/SlsPageCache.hxx>
37 #include <cache/SlsPageCacheManager.hxx>
38 #include <titledockwin.hxx>
43 #include <comphelper/lok.hxx>
44 #include <osl/diagnose.h>
45 #include <vcl/svapp.hxx>
46 #include <vcl/settings.hxx>
47 #include <vcl/graphicfilter.hxx>
51 //#define DEBUG_TIMING
57 using namespace ::sd::slidesorter::model
;
58 using namespace ::drawinglayer::primitive2d
;
60 namespace sd::slidesorter::view
{
63 /** Wrapper around the SlideSorterView that supports the IPainter
64 interface and that allows the LayeredDevice to hold the
65 SlideSorterView (held as unique_ptr by the SlideSorter) as
68 class Painter
: public ILayerPainter
71 explicit Painter (SlideSorterView
& rView
) : mrView(rView
) {}
73 virtual void Paint (OutputDevice
& rDevice
, const ::tools::Rectangle
& rRepaintArea
) override
75 mrView
.Paint(rDevice
,rRepaintArea
);
78 virtual void SetLayerInvalidator (const SharedILayerInvalidator
&) override
{}
81 SlideSorterView
& mrView
;
87 class BackgroundPainter
88 : public ILayerPainter
91 explicit BackgroundPainter (const Color
& rBackgroundColor
) : maBackgroundColor(rBackgroundColor
) {}
92 BackgroundPainter(const BackgroundPainter
&) = delete;
93 BackgroundPainter
& operator=(const BackgroundPainter
&) = delete;
95 virtual void Paint (OutputDevice
& rDevice
, const ::tools::Rectangle
& rRepaintArea
) override
97 rDevice
.SetFillColor(maBackgroundColor
);
98 rDevice
.SetLineColor();
99 rDevice
.DrawRect(rRepaintArea
);
102 virtual void SetLayerInvalidator (const SharedILayerInvalidator
&) override
{}
104 void SetColor (const Color
& rColor
) { maBackgroundColor
= rColor
; }
107 Color maBackgroundColor
;
112 SlideSorterView::SlideSorterView (SlideSorter
& rSlideSorter
)
114 *rSlideSorter
.GetModel().GetDocument(),
115 rSlideSorter
.GetContentWindow()->GetOutDev(),
116 rSlideSorter
.GetViewShell()),
117 mrSlideSorter(rSlideSorter
),
118 mrModel(rSlideSorter
.GetModel()),
120 mpLayouter (new Layouter(rSlideSorter
.GetContentWindow(), rSlideSorter
.GetTheme())),
121 mbPageObjectVisibilitiesValid (false),
122 mpLayeredDevice(std::make_shared
<LayeredDevice
>(rSlideSorter
.GetContentWindow())),
123 maVisiblePageRange(-1,-1),
125 mbPreciousFlagUpdatePending(true),
126 meOrientation(Layouter::GRID
),
128 std::make_shared
<BackgroundPainter
>(mrSlideSorter
.GetTheme()->GetColor(Theme::Color_Background
))),
129 mpToolTip(new ToolTip(mrSlideSorter
)),
130 mbIsRearrangePending(true)
132 // Hide the page that contains the page objects.
133 SetPageVisible (false);
135 // Register the background painter on level 1 to avoid the creation of a
136 // background buffer.
137 mpLayeredDevice
->RegisterPainter(mpBackgroundPainter
, 1);
139 // Wrap a shared_ptr-held-wrapper around this view and register it as
140 // painter at the layered device. There is no explicit destruction: in
141 // the SlideSorterView destructor the layered device is destroyed and
142 // with it the only reference to the wrapper which therefore is also
144 SharedILayerPainter pPainter
= std::make_shared
<Painter
>(*this);
146 // The painter is placed on level 1 to avoid buffering. This should be
147 // a little faster during animations because the previews are painted
148 // directly into the window, not via the buffer.
149 mpLayeredDevice
->RegisterPainter(pPainter
, 1);
152 SlideSorterView::~SlideSorterView()
156 OSL_ASSERT(mbIsDisposed
);
161 void SlideSorterView::Init()
166 void SlideSorterView::Dispose()
168 mpLayeredDevice
->Dispose();
169 mpPreviewCache
.reset();
171 SetPageUnderMouse(SharedPageDescriptor());
173 // Hide the page to avoid problems in the view when deleting
174 // visualized objects
177 // Deletion of the objects and the page will be done in SdrModel
178 // destructor (as long as objects and pages are added)
180 OSL_ASSERT(mpLayeredDevice
.use_count() == 1);
181 mpLayeredDevice
.reset();
186 sal_Int32
SlideSorterView::GetPageIndexAtPoint (const Point
& rWindowPosition
) const
188 sal_Int32
nIndex (-1);
190 sd::Window
*pWindow (mrSlideSorter
.GetContentWindow().get());
193 nIndex
= mpLayouter
->GetIndexAtPoint(pWindow
->PixelToLogic(rWindowPosition
), false, false);
195 // Clip the page index against the page count.
196 if (nIndex
>= mrModel
.GetPageCount())
203 Layouter
& SlideSorterView::GetLayouter() { return *mpLayouter
; }
205 void SlideSorterView::ModelHasChanged()
207 // Ignore this call. Rely on hints sent by the model to get informed of
211 void SlideSorterView::PreModelChange()
213 // Reset the slide under the mouse. It will be re-set in PostModelChange().
214 SetPageUnderMouse(SharedPageDescriptor());
217 void SlideSorterView::PostModelChange()
219 // In PreModelChange() the page objects have been released. Here we
221 ::osl::MutexGuard
aGuard (mrModel
.GetMutex());
223 model::PageEnumerationProvider::CreateAllPagesEnumeration(mrModel
);
225 // The new page objects have to be scaled and positioned.
230 /** At the moment for every model change all page objects are destroyed and
231 re-created again. This can be optimized by accepting hints that
232 describe the type of change so that existing page objects can be
235 void SlideSorterView::HandleModelChange()
241 void SlideSorterView::HandleDrawModeChange()
243 // Replace the preview cache with a new and empty one. The
244 // PreviewRenderer that is used by the cache is replaced by this as
246 mpPreviewCache
.reset();
247 GetPreviewCache()->InvalidateCache();
252 void SlideSorterView::HandleDataChangeEvent()
254 GetPageObjectPainter()->SetTheme(mrSlideSorter
.GetTheme());
256 // Update the color used by the background painter.
257 std::shared_ptr
<BackgroundPainter
> pPainter (
258 std::dynamic_pointer_cast
<BackgroundPainter
>(mpBackgroundPainter
));
260 pPainter
->SetColor(mrSlideSorter
.GetTheme()->GetColor(Theme::Color_Background
));
265 void SlideSorterView::Resize()
269 mpLayeredDevice
->Resize();
273 void SlideSorterView::RequestRearrange()
275 mbIsRearrangePending
= true;
279 void SlideSorterView::Rearrange()
281 if ( ! mbIsRearrangePending
)
283 if (mrModel
.GetPageCount() <= 0)
286 sd::Window
*pWindow (mrSlideSorter
.GetContentWindow().get());
289 const Size
aWindowSize (pWindow
->GetSizePixel());
290 if (aWindowSize
.IsEmpty())
293 const bool bRearrangeSuccess (
294 mpLayouter
->Rearrange (
297 mrModel
.GetPageDescriptor(0)->GetPage()->GetSize(),
298 mrModel
.GetPageCount()));
299 if (bRearrangeSuccess
)
301 mbIsRearrangePending
= false;
303 UpdatePageUnderMouse();
308 void SlideSorterView::UpdateOrientation()
310 // The layout of slides depends on whether the slide sorter is
311 // displayed in the center or the side pane.
312 if (mrSlideSorter
.GetViewShell()->IsMainViewShell())
313 SetOrientation(Layouter::GRID
);
316 // Get access to the docking window.
317 vcl::Window
* pWindow
= mrSlideSorter
.GetContentWindow();
318 TitledDockingWindow
* pDockingWindow
= nullptr;
319 while (pWindow
!=nullptr && pDockingWindow
==nullptr)
321 pDockingWindow
= dynamic_cast<TitledDockingWindow
*>(pWindow
);
322 pWindow
= pWindow
->GetParent();
325 if (pDockingWindow
!= nullptr)
327 const ::tools::Long
nScrollBarSize (
328 Application::GetSettings().GetStyleSettings().GetScrollBarSize());
329 switch (pDockingWindow
->GetOrientation())
331 case TitledDockingWindow::HorizontalOrientation
:
332 if (SetOrientation(Layouter::HORIZONTAL
))
334 const Range
aRange (mpLayouter
->GetValidVerticalSizeRange());
335 pDockingWindow
->SetValidSizeRange(Range(
336 aRange
.Min() + nScrollBarSize
,
337 aRange
.Max() + nScrollBarSize
));
341 case TitledDockingWindow::VerticalOrientation
:
342 if (SetOrientation(Layouter::VERTICAL
))
344 const Range
aRange (mpLayouter
->GetValidHorizontalSizeRange());
345 pDockingWindow
->SetValidSizeRange(Range(
346 aRange
.Min() + nScrollBarSize
,
347 aRange
.Max() + nScrollBarSize
));
351 case TitledDockingWindow::UnknownOrientation
:
352 if (SetOrientation(Layouter::GRID
))
354 const sal_Int32
nAdditionalSize (10);
355 pDockingWindow
->SetMinOutputSizePixel(Size(
356 mpLayouter
->GetValidHorizontalSizeRange().Min()
359 mpLayouter
->GetValidVerticalSizeRange().Min()
368 // We are not placed in a docking window. One possible reason
369 // is that the slide sorter is temporarily into a cache and was
370 // reparented to a non-docking window.
371 SetOrientation(Layouter::GRID
);
376 void SlideSorterView::Layout ()
378 sd::Window
*pWindow (mrSlideSorter
.GetContentWindow().get());
381 // Set the model area, i.e. the smallest rectangle that includes all
383 const ::tools::Rectangle
aViewBox (mpLayouter
->GetTotalBoundingBox());
384 pWindow
->SetViewOrigin (aViewBox
.TopLeft());
385 pWindow
->SetViewSize (aViewBox
.GetSize());
387 std::shared_ptr
<PageObjectLayouter
> pPageObjectLayouter(
388 mpLayouter
->GetPageObjectLayouter());
389 if (pPageObjectLayouter
)
391 const Size
aNewPreviewSize (mpLayouter
->GetPageObjectLayouter()->GetPreviewSize());
392 if (maPreviewSize
!= aNewPreviewSize
&& GetPreviewCache())
394 mpPreviewCache
->ChangeSize(aNewPreviewSize
, Bitmap::HasFastScale());
395 maPreviewSize
= aNewPreviewSize
;
399 // Iterate over all page objects and place them relative to the
401 model::PageEnumeration
aPageEnumeration (
402 model::PageEnumerationProvider::CreateAllPagesEnumeration(mrModel
));
403 while (aPageEnumeration
.HasMoreElements())
405 model::SharedPageDescriptor
pDescriptor (aPageEnumeration
.GetNextElement());
406 pDescriptor
->SetBoundingBox(mpLayouter
->GetPageObjectBox(pDescriptor
->GetPageIndex(), false));
410 InvalidatePageObjectVisibilities ();
413 void SlideSorterView::InvalidatePageObjectVisibilities()
415 mbPageObjectVisibilitiesValid
= false;
418 void SlideSorterView::DeterminePageObjectVisibilities()
420 sd::Window
*pWindow (mrSlideSorter
.GetContentWindow().get());
424 // Set this flag to true here so that an invalidate during the
425 // visibility calculation can correctly invalidate it again.
426 mbPageObjectVisibilitiesValid
= true;
428 ::tools::Rectangle
aViewArea (pWindow
->PixelToLogic(::tools::Rectangle(Point(0,0),pWindow
->GetSizePixel())));
429 const Range
aRange (mpLayouter
->GetRangeOfVisiblePageObjects(aViewArea
));
431 ::std::min(maVisiblePageRange
.Min(), aRange
.Min()),
432 ::std::max(maVisiblePageRange
.Max(), aRange
.Max()));
434 // For page objects that just dropped off the visible area we
435 // decrease the priority of pending requests for preview bitmaps.
436 if (maVisiblePageRange
!= aRange
)
437 mbPreciousFlagUpdatePending
|= true;
439 model::SharedPageDescriptor pDescriptor
;
440 for (::tools::Long nIndex
=aUnion
.Min(); nIndex
<=aUnion
.Max(); nIndex
++)
442 pDescriptor
= mrModel
.GetPageDescriptor(nIndex
);
446 PageDescriptor::ST_Visible
,
447 aRange
.Contains(nIndex
));
450 // Broadcast a change of the set of visible page objects.
451 if (maVisiblePageRange
!= aRange
)
453 maVisiblePageRange
= aRange
;
455 // Tell the listeners that the visibility of some objects has
457 ::std::vector
<Link
<LinkParamNone
*,void>>& aChangeListeners (maVisibilityChangeListeners
);
458 for (const auto& rLink
: aChangeListeners
)
464 // Restore the mouse over state.
465 UpdatePageUnderMouse();
468 void SlideSorterView::UpdatePreciousFlags()
470 if (!mbPreciousFlagUpdatePending
)
473 mbPreciousFlagUpdatePending
= false;
475 model::SharedPageDescriptor pDescriptor
;
476 std::shared_ptr
<cache::PageCache
> pCache
= GetPreviewCache();
477 sal_Int32
nPageCount (mrModel
.GetPageCount());
479 for (int nIndex
=0; nIndex
<=nPageCount
; ++nIndex
)
481 pDescriptor
= mrModel
.GetPageDescriptor(nIndex
);
484 pCache
->SetPreciousFlag(
485 pDescriptor
->GetPage(),
486 maVisiblePageRange
.Contains(nIndex
));
490 // At least one cache entry can not be updated. Remember to
491 // repeat the whole updating later and leave the loop now.
492 mbPreciousFlagUpdatePending
= true;
498 bool SlideSorterView::SetOrientation (const Layouter::Orientation eOrientation
)
500 if (meOrientation
!= eOrientation
)
502 meOrientation
= eOrientation
;
509 void SlideSorterView::RequestRepaint()
511 sd::Window
*pWindow (mrSlideSorter
.GetContentWindow().get());
514 mpLayeredDevice
->InvalidateAllLayers(
516 pWindow
->PixelToLogic(Point(0,0)),
517 pWindow
->PixelToLogic(pWindow
->GetSizePixel())));
518 pWindow
->Invalidate();
522 void SlideSorterView::RequestRepaint (const model::SharedPageDescriptor
& rpDescriptor
)
525 RequestRepaint(rpDescriptor
->GetBoundingBox());
528 void SlideSorterView::RequestRepaint (const ::tools::Rectangle
& rRepaintBox
)
530 sd::Window
*pWindow (mrSlideSorter
.GetContentWindow().get());
533 mpLayeredDevice
->InvalidateAllLayers(rRepaintBox
);
534 pWindow
->Invalidate(rRepaintBox
);
538 void SlideSorterView::RequestRepaint (const vcl::Region
& rRepaintRegion
)
540 sd::Window
*pWindow (mrSlideSorter
.GetContentWindow().get());
543 mpLayeredDevice
->InvalidateAllLayers(rRepaintRegion
);
544 pWindow
->Invalidate(rRepaintRegion
);
548 ::tools::Rectangle
SlideSorterView::GetModelArea() const
550 return mpLayouter
->GetTotalBoundingBox();
554 static ::canvas::tools::ElapsedTime gaTimer
;
555 static const size_t gFrameTimeCount (10);
556 static size_t gFrameTimeIndex (0);
557 static ::std::vector
<double> gFrameTimes (gFrameTimeCount
, 0);
558 static double gFrameTimeSum (0);
559 static const ::tools::Rectangle
gFrameTimeBox (10,10,150,20);
560 static double gnLastFrameStart
= 0;
563 void SlideSorterView::CompleteRedraw (
564 OutputDevice
* pDevice
,
565 const vcl::Region
& rPaintArea
,
566 sdr::contact::ViewObjectContactRedirector
* pRedirector
)
570 if (comphelper::LibreOfficeKit::isActive())
573 if (pDevice
== nullptr || pDevice
!=mrSlideSorter
.GetContentWindow()->GetOutDev())
577 const double nStartTime (gaTimer
.getElapsedTime());
578 SAL_INFO("sd.timing", "SlideSorterView::CompleteRedraw start" << (mnLockRedrawSmph
? " locked" : ""));
581 // The parent implementation of CompleteRedraw is called only when
582 // painting is locked. We do all the painting ourself. When painting
583 // is locked the parent implementation keeps track of the repaint
584 // requests and later, when painting is unlocked, calls CompleteRedraw
585 // for all missed repaints.
587 if (mnLockRedrawSmph
== 0)
589 if (mpLayeredDevice
->HandleMapModeChange())
590 DeterminePageObjectVisibilities();
591 mpLayeredDevice
->Repaint(rPaintArea
);
595 maRedrawRegion
.Union(rPaintArea
);
599 const double nEndTime (gaTimer
.getElapsedTime());
600 SAL_INFO("sd.timing", "SlideSorterView::CompleteRedraw end after " << (nEndTime
-nStartTime
)*1000 << " ms");
601 gFrameTimeSum
-= gFrameTimes
[gFrameTimeIndex
];
602 gFrameTimes
[gFrameTimeIndex
] = nStartTime
- gnLastFrameStart
;
603 gnLastFrameStart
= nStartTime
;
604 gFrameTimeSum
+= gFrameTimes
[gFrameTimeIndex
];
605 gFrameTimeIndex
= (gFrameTimeIndex
+1) % gFrameTimeCount
;
607 mrSlideSorter
.GetContentWindow()->SetFillColor(COL_BLUE
);
608 mrSlideSorter
.GetContentWindow()->DrawRect(gFrameTimeBox
);
609 mrSlideSorter
.GetContentWindow()->SetTextColor(COL_WHITE
);
610 mrSlideSorter
.GetContentWindow()->DrawText(
612 OUString::number(1 / (gFrameTimeSum
/ gFrameTimeCount
)),
613 DrawTextFlags::Right
| DrawTextFlags::VCenter
);
614 // mrSlideSorter.GetContentWindow()->Invalidate(gFrameTimeBox);
618 void SlideSorterView::Paint (
619 OutputDevice
& rDevice
,
620 const ::tools::Rectangle
& rRepaintArea
)
622 if (rRepaintArea
.IsEmpty())
625 if ( ! mpPageObjectPainter
)
626 if ( ! GetPageObjectPainter())
629 // Update the page visibilities when they have been invalidated.
630 if ( ! mbPageObjectVisibilitiesValid
)
631 DeterminePageObjectVisibilities();
633 if (mbPreciousFlagUpdatePending
)
634 UpdatePreciousFlags();
636 if (mbIsRearrangePending
)
639 // Paint all page objects that are fully or partially inside the
641 const Range
aRange (mpLayouter
->GetRangeOfVisiblePageObjects(rRepaintArea
));
642 // Try to prefetch all graphics from the pages to paint. This will be done
643 // in threads to be more efficient than loading them on-demand one by one.
644 std::vector
<Graphic
*> graphics
;
645 for (::tools::Long nIndex
=aRange
.Min(); nIndex
<=aRange
.Max(); ++nIndex
)
647 model::SharedPageDescriptor
pDescriptor (mrModel
.GetPageDescriptor(nIndex
));
648 if (!pDescriptor
|| ! pDescriptor
->HasState(PageDescriptor::ST_Visible
))
650 pDescriptor
->GetPage()->getGraphicsForPrefetch(graphics
);
652 // Handle also one page before and after to have those in advance on scrolling.
653 for (::tools::Long nIndex
: { aRange
.Min() - 1, aRange
.Max() + 1 })
655 model::SharedPageDescriptor
pDescriptor (mrModel
.GetPageDescriptor(nIndex
));
658 pDescriptor
->GetPage()->getGraphicsForPrefetch(graphics
);
660 if(graphics
.size() > 1) // threading does not help with loading just one
661 GraphicFilter::GetGraphicFilter().MakeGraphicsAvailableThreaded(graphics
);
663 for (::tools::Long nIndex
=aRange
.Min(); nIndex
<=aRange
.Max(); ++nIndex
)
665 model::SharedPageDescriptor
pDescriptor (mrModel
.GetPageDescriptor(nIndex
));
666 if (!pDescriptor
|| ! pDescriptor
->HasState(PageDescriptor::ST_Visible
))
669 mpPageObjectPainter
->PaintPageObject(rDevice
, pDescriptor
);
673 void SlideSorterView::ConfigurationChanged (
674 utl::ConfigurationBroadcaster
* pBroadcaster
,
675 ConfigurationHints nHint
)
677 // Some changes of the configuration (some of the colors for example)
678 // may affect the previews. Throw away the old ones and create new ones.
679 cache::PageCacheManager::Instance()->InvalidateAllCaches();
681 ::sd::View::ConfigurationChanged(pBroadcaster
, nHint
);
686 std::shared_ptr
<cache::PageCache
> const & SlideSorterView::GetPreviewCache()
688 sd::Window
*pWindow (mrSlideSorter
.GetContentWindow().get());
689 if (pWindow
&& mpPreviewCache
== nullptr)
692 std::make_shared
<cache::PageCache
>(
693 mpLayouter
->GetPageObjectSize(),
694 Bitmap::HasFastScale(),
695 std::make_shared
<ViewCacheContext
>(mrSlideSorter
));
698 return mpPreviewCache
;
701 Range
const & SlideSorterView::GetVisiblePageRange()
703 if ( ! mbPageObjectVisibilitiesValid
)
704 DeterminePageObjectVisibilities();
705 return maVisiblePageRange
;
708 void SlideSorterView::AddVisibilityChangeListener (const Link
<LinkParamNone
*,void>& rListener
)
711 maVisibilityChangeListeners
.begin(),
712 maVisibilityChangeListeners
.end(),
713 rListener
) == maVisibilityChangeListeners
.end())
715 maVisibilityChangeListeners
.push_back(rListener
);
719 void SlideSorterView::RemoveVisibilityChangeListener(const Link
<LinkParamNone
*,void>&rListener
)
721 maVisibilityChangeListeners
.erase (
723 maVisibilityChangeListeners
.begin(),
724 maVisibilityChangeListeners
.end(),
728 ToolTip
& SlideSorterView::GetToolTip() const
730 OSL_ASSERT(mpToolTip
);
734 void SlideSorterView::DragFinished (sal_Int8 nDropAction
)
736 mrSlideSorter
.GetController().GetClipboard().DragFinished(nDropAction
);
738 View::DragFinished(nDropAction
);
741 void SlideSorterView::UpdatePageUnderMouse ()
743 // Tracking TODO check
744 VclPtr
<ScrollAdaptor
> pVScrollBar (mrSlideSorter
.GetVerticalScrollBar());
745 VclPtr
<ScrollAdaptor
> pHScrollBar (mrSlideSorter
.GetHorizontalScrollBar());
746 if ((pVScrollBar
&& pVScrollBar
->IsVisible() && pVScrollBar
->HasGrab())
747 || (pHScrollBar
&& pHScrollBar
->IsVisible() && pHScrollBar
->HasGrab()))
749 // One of the scroll bars is tracking mouse movement. Do not
750 // highlight the slide under the mouse in this case.
751 SetPageUnderMouse(SharedPageDescriptor());
755 sd::Window
*pWindow (mrSlideSorter
.GetContentWindow().get());
756 if (pWindow
&& pWindow
->IsVisible() && ! pWindow
->IsMouseCaptured())
758 const Window::PointerState
aPointerState (pWindow
->GetPointerState());
759 const ::tools::Rectangle
aWindowBox (pWindow
->GetPosPixel(), pWindow
->GetSizePixel());
760 if (aWindowBox
.Contains(aPointerState
.maPos
))
762 UpdatePageUnderMouse(aPointerState
.maPos
);
767 SetPageUnderMouse(SharedPageDescriptor());
770 void SlideSorterView::UpdatePageUnderMouse (
771 const Point
& rMousePosition
)
773 SetPageUnderMouse(mrSlideSorter
.GetController().GetPageAt(rMousePosition
));
776 void SlideSorterView::SetPageUnderMouse (
777 const model::SharedPageDescriptor
& rpDescriptor
)
779 if (mpPageUnderMouse
== rpDescriptor
)
782 if (mpPageUnderMouse
)
783 SetState(mpPageUnderMouse
, PageDescriptor::ST_MouseOver
, false);
785 mpPageUnderMouse
= rpDescriptor
;
787 if (mpPageUnderMouse
)
788 SetState(mpPageUnderMouse
, PageDescriptor::ST_MouseOver
, true);
790 // Change the quick help text to display the name of the page under
792 mpToolTip
->SetPage(rpDescriptor
);
795 bool SlideSorterView::SetState (
796 const model::SharedPageDescriptor
& rpDescriptor
,
797 const PageDescriptor::State eState
,
798 const bool bStateValue
)
803 const bool bModified (rpDescriptor
->SetState(eState
, bStateValue
));
807 // When the page object is not visible (i.e. not on the screen then
808 // nothing has to be painted.
809 if (rpDescriptor
->HasState(PageDescriptor::ST_Visible
))
811 // For most states a change of that state leads to visible
812 // difference and we have to request a repaint.
813 if (eState
!= PageDescriptor::ST_WasSelected
)
814 RequestRepaint(rpDescriptor
);
820 std::shared_ptr
<PageObjectPainter
> const & SlideSorterView::GetPageObjectPainter()
822 if ( ! mpPageObjectPainter
)
823 mpPageObjectPainter
= std::make_shared
<PageObjectPainter
>(mrSlideSorter
);
824 return mpPageObjectPainter
;
827 //===== SlideSorterView::DrawLock =============================================
829 SlideSorterView::DrawLock::DrawLock (SlideSorter
const & rSlideSorter
)
830 : mrView(rSlideSorter
.GetView()),
831 mpWindow(rSlideSorter
.GetContentWindow())
833 if (mrView
.mnLockRedrawSmph
== 0)
834 mrView
.maRedrawRegion
.SetEmpty();
835 ++mrView
.mnLockRedrawSmph
;
838 SlideSorterView::DrawLock::~DrawLock()
840 OSL_ASSERT(mrView
.mnLockRedrawSmph
>0);
841 --mrView
.mnLockRedrawSmph
;
842 if (mrView
.mnLockRedrawSmph
== 0)
845 mpWindow
->Invalidate(mrView
.maRedrawRegion
);
849 void SlideSorterView::DrawLock::Dispose()
854 } // end of namespace ::sd::slidesorter::view
856 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */