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/b2dvector.hxx>
28 #include <comphelper/diagnose_ex.hxx>
30 #include <com/sun/star/presentation/XSlideShowView.hpp>
31 #include <com/sun/star/rendering/XCanvas.hpp>
36 namespace slideshow::internal
38 SlideOverlayButtonSharedPtr
SlideOverlayButton::create(
39 const css::uno::Reference
<css::rendering::XBitmap
>& xIconBitmap
, css::awt::Point pPosition
,
40 std::function
<void(basegfx::B2DPoint
)> clickHandler
, ScreenUpdater
& rScreenUpdater
,
41 EventMultiplexer
& rEventMultiplexer
, const UnoViewContainer
& rViewContainer
)
43 SlideOverlayButtonSharedPtr
pRet(new SlideOverlayButton(
44 xIconBitmap
, pPosition
, clickHandler
, rScreenUpdater
, rEventMultiplexer
, rViewContainer
));
46 rEventMultiplexer
.addViewHandler(pRet
);
47 // Set priority to 1000 so that the handler fires before the click handler on the slide
48 rEventMultiplexer
.addClickHandler(pRet
, 1000);
52 SlideOverlayButton::SlideOverlayButton(css::uno::Reference
<css::rendering::XBitmap
> xIconBitmap
,
53 css::awt::Point pPosition
,
54 std::function
<void(basegfx::B2DPoint
)> clickHandler
,
55 ScreenUpdater
& rScreenUpdater
,
56 EventMultiplexer
& rEventMultiplexer
,
57 const UnoViewContainer
& rViewContainer
)
58 : mxIconBitmap(std::move(xIconBitmap
))
59 , mrEventMultiplexer(rEventMultiplexer
)
60 , mpPosition(pPosition
)
61 , mClickHandler(clickHandler
)
62 , mrScreenUpdater(rScreenUpdater
)
64 for (const auto& pView
: rViewContainer
)
68 void SlideOverlayButton::setVisible(const bool bVisible
)
70 if (mbVisible
== bVisible
)
75 for (const auto& rView
: maViews
)
79 // sprites changed, need a screen update for this frame.
80 mrScreenUpdater
.requestImmediateUpdate();
83 css::geometry::IntegerSize2D
SlideOverlayButton::getSize() const { return mxIconBitmap
->getSize(); }
85 basegfx::B2DPoint
SlideOverlayButton::calcSpritePos(UnoViewSharedPtr
const& rView
) const
87 const css::awt::Rectangle
aViewArea(rView
->getUnoView()->getCanvasArea());
88 return basegfx::B2DPoint(
89 aViewArea
.X
+ std::min(aViewArea
.Width
, mpPosition
.X
),
91 + std::max(sal_Int32(0),
92 aViewArea
.Height
- mxIconBitmap
->getSize().Height
- mpPosition
.Y
));
95 void SlideOverlayButton::viewAdded(const UnoViewSharedPtr
& rView
)
97 cppcanvas::CustomSpriteSharedPtr sprite
;
101 const css::geometry::IntegerSize2D
spriteSize(mxIconBitmap
->getSize());
102 sprite
= rView
->createSprite(basegfx::B2DSize(spriteSize
.Width
, spriteSize
.Height
),
103 1000.0); // sprite should be in front of all
105 css::rendering::ViewState viewState
;
106 canvas::tools::initViewState(viewState
);
107 css::rendering::RenderState renderState
;
108 canvas::tools::initRenderState(renderState
);
109 sprite
->getContentCanvas()->getUNOCanvas()->drawBitmap(mxIconBitmap
, viewState
,
112 sprite
->setAlpha(0.9);
113 sprite
->movePixel(calcSpritePos(rView
));
116 catch (css::uno::Exception
&)
118 TOOLS_WARN_EXCEPTION("slideshow", "");
121 maViews
.emplace_back(rView
, sprite
);
124 void SlideOverlayButton::viewRemoved(const UnoViewSharedPtr
& rView
)
127 std::remove_if(maViews
.begin(), maViews
.end(),
128 [&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 mClickHandler(clickPnt
);
181 bool SlideOverlayButton::handleMouseDragged(const css::awt::MouseEvent
& /*e*/) { return false; }
183 bool SlideOverlayButton::handleMouseMoved(const css::awt::MouseEvent
& /*e*/) { return false; }
185 } // namespace slideshow::internal
187 /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */