1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
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 <sal/config.h>
22 #include <eventmultiplexer.hxx>
23 #include "slideoverlaybutton.hxx"
25 #include <canvas/canvastools.hxx>
26 #include <cppcanvas/customsprite.hxx>
27 #include <basegfx/vector/b2dsize.hxx>
28 #include <basegfx/vector/b2dvector.hxx>
29 #include <comphelper/diagnose_ex.hxx>
31 #include <com/sun/star/presentation/XSlideShowView.hpp>
32 #include <com/sun/star/rendering/XCanvas.hpp>
37 namespace slideshow::internal
39 SlideOverlayButtonSharedPtr
40 SlideOverlayButton::create(const css::uno::Reference
<css::rendering::XBitmap
>& xIconBitmap
,
41 const css::awt::Point
& rPosition
,
42 const std::function
<void(basegfx::B2DPoint
)>& clickHandler
,
43 ScreenUpdater
& rScreenUpdater
, EventMultiplexer
& rEventMultiplexer
,
44 const UnoViewContainer
& rViewContainer
)
46 SlideOverlayButtonSharedPtr
pRet(new SlideOverlayButton(
47 xIconBitmap
, rPosition
, clickHandler
, rScreenUpdater
, rEventMultiplexer
, rViewContainer
));
49 rEventMultiplexer
.addViewHandler(pRet
);
50 // Set priority to 1000 so that the handler fires before the click handler on the slide
51 rEventMultiplexer
.addClickHandler(pRet
, 1000);
55 SlideOverlayButton::SlideOverlayButton(css::uno::Reference
<css::rendering::XBitmap
> xIconBitmap
,
56 css::awt::Point pPosition
,
57 std::function
<void(basegfx::B2DPoint
)> clickHandler
,
58 ScreenUpdater
& rScreenUpdater
,
59 EventMultiplexer
& rEventMultiplexer
,
60 const UnoViewContainer
& rViewContainer
)
61 : mxIconBitmap(std::move(xIconBitmap
))
62 , mrEventMultiplexer(rEventMultiplexer
)
63 , mpPosition(std::move(pPosition
))
64 , mClickHandler(std::move(clickHandler
))
65 , mrScreenUpdater(rScreenUpdater
)
67 for (const auto& pView
: rViewContainer
)
71 void SlideOverlayButton::setVisible(const bool bVisible
)
73 if (mbVisible
== bVisible
)
78 for (const auto& rView
: maViews
)
82 // sprites changed, need a screen update for this frame.
83 mrScreenUpdater
.requestImmediateUpdate();
86 css::geometry::IntegerSize2D
SlideOverlayButton::getSize() const { return mxIconBitmap
->getSize(); }
88 basegfx::B2DPoint
SlideOverlayButton::calcSpritePos(UnoViewSharedPtr
const& rView
) const
90 const css::awt::Rectangle
aViewArea(rView
->getUnoView()->getCanvasArea());
91 return basegfx::B2DPoint(
92 aViewArea
.X
+ std::min(aViewArea
.Width
, mpPosition
.X
),
94 + std::max(sal_Int32(0),
95 aViewArea
.Height
- mxIconBitmap
->getSize().Height
- mpPosition
.Y
));
98 void SlideOverlayButton::viewAdded(const UnoViewSharedPtr
& rView
)
100 cppcanvas::CustomSpriteSharedPtr sprite
;
104 const css::geometry::IntegerSize2D
spriteSize(mxIconBitmap
->getSize());
105 sprite
= rView
->createSprite(basegfx::B2DSize(spriteSize
.Width
, spriteSize
.Height
),
106 1000.0); // sprite should be in front of all
108 css::rendering::ViewState viewState
;
109 canvas::tools::initViewState(viewState
);
110 css::rendering::RenderState renderState
;
111 canvas::tools::initRenderState(renderState
);
112 sprite
->getContentCanvas()->getUNOCanvas()->drawBitmap(mxIconBitmap
, viewState
,
115 sprite
->setAlpha(0.9);
116 sprite
->movePixel(calcSpritePos(rView
));
119 catch (css::uno::Exception
&)
121 TOOLS_WARN_EXCEPTION("slideshow", "");
124 maViews
.emplace_back(rView
, sprite
);
127 void SlideOverlayButton::viewRemoved(const UnoViewSharedPtr
& rView
)
129 std::erase_if(maViews
, [&rView
](const ViewsVecT::value_type
& cp
) { return rView
== cp
.first
; });
132 void SlideOverlayButton::viewChanged(const UnoViewSharedPtr
& rView
)
134 // find entry corresponding to modified view
135 ViewsVecT::iterator
aModifiedEntry(
136 std::find_if(maViews
.begin(), maViews
.end(),
137 [&rView
](const ViewsVecT::value_type
& cp
) { return rView
== cp
.first
; }));
139 assert(aModifiedEntry
!= maViews
.end());
140 if (aModifiedEntry
== maViews
.end())
143 if (aModifiedEntry
->second
)
144 aModifiedEntry
->second
->movePixel(calcSpritePos(aModifiedEntry
->first
));
147 void SlideOverlayButton::viewsChanged()
149 // reposition sprites on all views
150 for (const auto& rView
: maViews
)
153 rView
.second
->movePixel(calcSpritePos(rView
.first
));
157 bool SlideOverlayButton::handleMousePressed(const css::awt::MouseEvent
& /*e*/) { return false; }
159 bool SlideOverlayButton::handleMouseReleased(const css::awt::MouseEvent
& e
)
161 css::uno::Reference
<css::presentation::XSlideShowView
> view(e
.Source
,
162 css::uno::UNO_QUERY_THROW
);
163 const basegfx::B2DPoint
btnPnt(
164 view
->getCanvasArea().X
+ std::min(view
->getCanvasArea().Width
, mpPosition
.X
),
165 view
->getCanvasArea().Y
166 + std::max(sal_Int32(0), view
->getCanvasArea().Height
- mxIconBitmap
->getSize().Height
168 const basegfx::B2DPoint clickPnt
169 = mrEventMultiplexer
.toNormalPoint(e
.Source
, basegfx::B2DPoint(e
.X
, e
.Y
));
170 if (clickPnt
.getX() > btnPnt
.getX()
171 && clickPnt
.getX() < btnPnt
.getX() + mxIconBitmap
->getSize().Width
172 && clickPnt
.getY() > btnPnt
.getY()
173 && clickPnt
.getY() < btnPnt
.getY() + mxIconBitmap
->getSize().Height
)
175 if (mnIgnoreClicksCnt
== 0)
177 mnIgnoreClicksCnt
= e
.ClickCount
- 1;
178 mClickHandler(clickPnt
);
189 bool SlideOverlayButton::handleMouseDragged(const css::awt::MouseEvent
& /*e*/) { return false; }
191 bool SlideOverlayButton::handleMouseMoved(const css::awt::MouseEvent
& /*e*/) { return false; }
193 } // namespace slideshow::internal
195 /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */