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 "vcl/svapp.hxx"
21 #include "PresenterButton.hxx"
22 #include "PresenterCanvasHelper.hxx"
23 #include "PresenterController.hxx"
24 #include "PresenterGeometryHelper.hxx"
25 #include "PresenterPaintManager.hxx"
26 #include "PresenterUIPainter.hxx"
27 #include <com/sun/star/awt/PosSize.hpp>
28 #include <com/sun/star/awt/XWindowPeer.hpp>
29 #include <com/sun/star/drawing/XPresenterHelper.hpp>
30 #include <com/sun/star/rendering/CompositeOperation.hpp>
31 #include <com/sun/star/rendering/TextDirection.hpp>
32 #include <boost/bind.hpp>
34 using namespace ::com::sun::star
;
35 using namespace ::com::sun::star::uno
;
37 namespace sdext
{ namespace presenter
{
39 const static double gnHorizontalBorder (15);
40 const static double gnVerticalBorder (5);
42 ::rtl::Reference
<PresenterButton
> PresenterButton::Create (
43 const css::uno::Reference
<css::uno::XComponentContext
>& rxComponentContext
,
44 const ::rtl::Reference
<PresenterController
>& rpPresenterController
,
45 const ::boost::shared_ptr
<PresenterTheme
>& rpTheme
,
46 const css::uno::Reference
<css::awt::XWindow
>& rxParentWindow
,
47 const css::uno::Reference
<css::rendering::XCanvas
>& rxParentCanvas
,
48 const OUString
& rsConfigurationName
)
50 Reference
<beans::XPropertySet
> xProperties (GetConfigurationProperties(
52 rsConfigurationName
));
57 PresenterConfigurationAccess::GetProperty(xProperties
, "Text") >>= sText
;
58 PresenterConfigurationAccess::GetProperty(xProperties
, "Action") >>= sAction
;
60 PresenterTheme::SharedFontDescriptor pFont
;
61 if (rpTheme
.get() != NULL
)
62 pFont
= rpTheme
->GetFont("ButtonFont");
64 PresenterTheme::SharedFontDescriptor pMouseOverFont
;
65 if (rpTheme
.get() != NULL
)
66 pMouseOverFont
= rpTheme
->GetFont("ButtonMouseOverFont");
68 rtl::Reference
<PresenterButton
> pButton (
71 rpPresenterController
,
78 pButton
->SetCanvas(rxParentCanvas
, rxParentWindow
);
85 PresenterButton::PresenterButton (
86 const css::uno::Reference
<css::uno::XComponentContext
>& rxComponentContext
,
87 const ::rtl::Reference
<PresenterController
>& rpPresenterController
,
88 const ::boost::shared_ptr
<PresenterTheme
>& rpTheme
,
89 const css::uno::Reference
<css::awt::XWindow
>& rxParentWindow
,
90 const PresenterTheme::SharedFontDescriptor
& rpFont
,
91 const PresenterTheme::SharedFontDescriptor
& rpMouseOverFont
,
92 const OUString
& rsText
,
93 const OUString
& rsAction
)
94 : PresenterButtonInterfaceBase(m_aMutex
),
95 mpPresenterController(rpPresenterController
),
102 mpMouseOverFont(rpMouseOverFont
),
106 meState(PresenterBitmapDescriptor::Normal
),
112 Reference
<lang::XMultiComponentFactory
> xFactory (rxComponentContext
->getServiceManager());
113 if ( ! xFactory
.is())
114 throw RuntimeException();
116 mxPresenterHelper
= Reference
<drawing::XPresenterHelper
>(
117 xFactory
->createInstanceWithContext(
118 OUString("com.sun.star.comp.Draw.PresenterHelper"),
122 if (mxPresenterHelper
.is())
123 mxWindow
= mxPresenterHelper
->createWindow(rxParentWindow
,
129 // Make the background transparent.
130 Reference
<awt::XWindowPeer
> xPeer (mxWindow
, UNO_QUERY_THROW
);
133 xPeer
->setBackground(0xff000000);
136 mxWindow
->setVisible(sal_True
);
137 mxWindow
->addWindowListener(this);
138 mxWindow
->addPaintListener(this);
139 mxWindow
->addMouseListener(this);
140 mxWindow
->addMouseMotionListener(this);
142 catch (RuntimeException
&)
147 PresenterButton::~PresenterButton()
151 void SAL_CALL
PresenterButton::disposing()
155 Reference
<lang::XComponent
> xComponent (mxCanvas
, UNO_QUERY
);
158 xComponent
->dispose();
163 mxWindow
->removeWindowListener(this);
164 mxWindow
->removePaintListener(this);
165 mxWindow
->removeMouseListener(this);
166 mxWindow
->removeMouseMotionListener(this);
167 Reference
<lang::XComponent
> xComponent (mxWindow
, UNO_QUERY
);
170 xComponent
->dispose();
174 void PresenterButton::SetCenter (const css::geometry::RealPoint2D
& rLocation
)
180 maCenter
= rLocation
;
181 mxWindow
->setPosSize(
182 sal_Int32(0.5 + maCenter
.X
- maButtonSize
.Width
/2),
183 sal_Int32(0.5 + maCenter
.Y
- maButtonSize
.Height
/2),
186 awt::PosSize::POSSIZE
);
192 // The button can not be painted but we can at least store the new center.
193 maCenter
= rLocation
;
197 void PresenterButton::SetCanvas (
198 const css::uno::Reference
<css::rendering::XCanvas
>& rxParentCanvas
,
199 const css::uno::Reference
<css::awt::XWindow
>& rxParentWindow
)
203 Reference
<lang::XComponent
> xComponent (mxCanvas
, UNO_QUERY
);
206 xComponent
->dispose();
209 if (mxPresenterHelper
.is() && rxParentCanvas
.is() && rxParentWindow
.is())
211 mxCanvas
= mxPresenterHelper
->createSharedCanvas (
212 Reference
<rendering::XSpriteCanvas
>(rxParentCanvas
, UNO_QUERY
),
219 SetupButtonBitmaps();
225 css::geometry::IntegerSize2D
PresenterButton::GetSize()
227 if (maButtonSize
.Width
< 0)
228 CalculateButtonSize();
232 //----- XWindowListener -------------------------------------------------------
234 void SAL_CALL
PresenterButton::windowResized (const css::awt::WindowEvent
& rEvent
)
235 throw (css::uno::RuntimeException
, std::exception
)
241 void SAL_CALL
PresenterButton::windowMoved (const css::awt::WindowEvent
& rEvent
)
242 throw (css::uno::RuntimeException
, std::exception
)
248 void SAL_CALL
PresenterButton::windowShown (const css::lang::EventObject
& rEvent
)
249 throw (css::uno::RuntimeException
, std::exception
)
255 void SAL_CALL
PresenterButton::windowHidden (const css::lang::EventObject
& rEvent
)
256 throw (css::uno::RuntimeException
, std::exception
)
262 //----- XPaintListener --------------------------------------------------------
264 void SAL_CALL
PresenterButton::windowPaint (const css::awt::PaintEvent
& rEvent
)
265 throw (css::uno::RuntimeException
, std::exception
)
268 if (mxWindow
.is() && mxCanvas
.is())
270 Reference
<rendering::XBitmap
> xBitmap
;
271 if (meState
== PresenterBitmapDescriptor::MouseOver
)
272 xBitmap
= mxMouseOverBitmap
;
274 xBitmap
= mxNormalBitmap
;
278 rendering::ViewState
aViewState(
279 geometry::AffineMatrix2D(1,0,0, 0,1,0),
281 rendering::RenderState
aRenderState(
282 geometry::AffineMatrix2D(1,0,0, 0,1,0),
283 PresenterGeometryHelper::CreatePolygon(rEvent
.UpdateRect
, mxCanvas
->getDevice()),
285 rendering::CompositeOperation::SOURCE
);
287 mxCanvas
->drawBitmap(xBitmap
, aViewState
, aRenderState
);
289 Reference
<rendering::XSpriteCanvas
> xSpriteCanvas (mxCanvas
, UNO_QUERY
);
290 if (xSpriteCanvas
.is())
291 xSpriteCanvas
->updateScreen(sal_False
);
295 //----- XMouseListener --------------------------------------------------------
297 void SAL_CALL
PresenterButton::mousePressed (const css::awt::MouseEvent
& rEvent
)
298 throw(css::uno::RuntimeException
, std::exception
)
302 meState
= PresenterBitmapDescriptor::ButtonDown
;
305 void SAL_CALL
PresenterButton::mouseReleased (const css::awt::MouseEvent
& rEvent
)
306 throw(css::uno::RuntimeException
, std::exception
)
311 if (meState
== PresenterBitmapDescriptor::ButtonDown
)
313 OSL_ASSERT(mpPresenterController
.get()!=NULL
);
314 mpPresenterController
->DispatchUnoCommand(msAction
);
316 meState
= PresenterBitmapDescriptor::Normal
;
321 void SAL_CALL
PresenterButton::mouseEntered (const css::awt::MouseEvent
& rEvent
)
322 throw(css::uno::RuntimeException
, std::exception
)
326 meState
= PresenterBitmapDescriptor::MouseOver
;
330 void SAL_CALL
PresenterButton::mouseExited (const css::awt::MouseEvent
& rEvent
)
331 throw(css::uno::RuntimeException
, std::exception
)
335 meState
= PresenterBitmapDescriptor::Normal
;
339 //----- XMouseMotionListener --------------------------------------------------
341 void SAL_CALL
PresenterButton::mouseMoved (const css::awt::MouseEvent
& rEvent
)
342 throw (css::uno::RuntimeException
, std::exception
)
348 void SAL_CALL
PresenterButton::mouseDragged (const css::awt::MouseEvent
& rEvent
)
349 throw (css::uno::RuntimeException
, std::exception
)
355 //----- lang::XEventListener --------------------------------------------------
357 void SAL_CALL
PresenterButton::disposing (const css::lang::EventObject
& rEvent
)
358 throw (css::uno::RuntimeException
, std::exception
)
360 if (rEvent
.Source
== mxWindow
)
366 css::geometry::IntegerSize2D
PresenterButton::CalculateButtonSize()
368 if (mpFont
.get()!=NULL
&& !mpFont
->mxFont
.is() && mxCanvas
.is())
369 mpFont
->PrepareFont(mxCanvas
);
370 if (mpFont
.get()==NULL
|| !mpFont
->mxFont
.is())
371 return geometry::IntegerSize2D(-1,-1);
373 geometry::RealSize2D
aTextSize (PresenterCanvasHelper::GetTextSize(mpFont
->mxFont
,msText
));
375 return geometry::IntegerSize2D (
376 sal_Int32(0.5 + aTextSize
.Width
+ 2*gnHorizontalBorder
),
377 sal_Int32(0.5 + aTextSize
.Height
+ 2*gnVerticalBorder
));
380 void PresenterButton::RenderButton (
381 const Reference
<rendering::XCanvas
>& rxCanvas
,
382 const geometry::IntegerSize2D
& rSize
,
383 const PresenterTheme::SharedFontDescriptor
& rpFont
,
384 const PresenterBitmapDescriptor::Mode eMode
,
385 const SharedBitmapDescriptor
& rpLeft
,
386 const SharedBitmapDescriptor
& rpCenter
,
387 const SharedBitmapDescriptor
& rpRight
)
389 if ( ! rxCanvas
.is())
392 const awt::Rectangle
aBox(0,0, rSize
.Width
, rSize
.Height
);
394 PresenterUIPainter::PaintHorizontalBitmapComposite (
398 GetBitmap(rpLeft
, eMode
),
399 GetBitmap(rpCenter
, eMode
),
400 GetBitmap(rpRight
, eMode
));
402 if (rpFont
.get()==NULL
|| ! rpFont
->mxFont
.is())
405 const rendering::StringContext
aContext (msText
, 0, msText
.getLength());
406 const Reference
<rendering::XTextLayout
> xLayout (
407 rpFont
->mxFont
->createTextLayout(aContext
,rendering::TextDirection::WEAK_LEFT_TO_RIGHT
,0));
408 const geometry::RealRectangle2D
aTextBBox (xLayout
->queryTextBounds());
410 rendering::RenderState
aRenderState (geometry::AffineMatrix2D(1,0,0, 0,1,0), NULL
,
411 Sequence
<double>(4), rendering::CompositeOperation::SOURCE
);
412 PresenterCanvasHelper::SetDeviceColor(aRenderState
, rpFont
->mnColor
);
414 aRenderState
.AffineTransform
.m02
= (rSize
.Width
- aTextBBox
.X2
+ aTextBBox
.X1
)/2;
415 aRenderState
.AffineTransform
.m12
= (rSize
.Height
- aTextBBox
.Y2
+ aTextBBox
.Y1
)/2 - aTextBBox
.Y1
;
417 /// this is responsible of the close button
418 rxCanvas
->drawTextLayout(
420 rendering::ViewState(geometry::AffineMatrix2D(1,0,0, 0,1,0), NULL
),
424 void PresenterButton::Invalidate()
426 mpPresenterController
->GetPaintManager()->Invalidate(mxWindow
);
429 Reference
<rendering::XBitmap
> PresenterButton::GetBitmap (
430 const SharedBitmapDescriptor
& mpIcon
,
431 const PresenterBitmapDescriptor::Mode eMode
)
433 if (mpIcon
.get() != NULL
)
434 return mpIcon
->GetBitmap(eMode
);
437 OSL_ASSERT(mpIcon
.get()!=NULL
);
442 void PresenterButton::SetupButtonBitmaps()
444 if ( ! mxCanvas
.is())
446 if ( ! mxCanvas
->getDevice().is())
449 // Get the bitmaps for the button border.
450 SharedBitmapDescriptor
pLeftBitmap (mpTheme
->GetBitmap("ButtonFrameLeft"));
451 SharedBitmapDescriptor
pCenterBitmap(mpTheme
->GetBitmap("ButtonFrameCenter"));
452 SharedBitmapDescriptor
pRightBitmap(mpTheme
->GetBitmap("ButtonFrameRight"));
454 maButtonSize
= CalculateButtonSize();
456 if (maButtonSize
.Height
<=0 && maButtonSize
.Width
<= 0)
459 mxNormalBitmap
= mxCanvas
->getDevice()->createCompatibleAlphaBitmap(maButtonSize
);
460 Reference
<rendering::XCanvas
> xCanvas (mxNormalBitmap
, UNO_QUERY
);
466 PresenterBitmapDescriptor::Normal
,
471 mxMouseOverBitmap
= mxCanvas
->getDevice()->createCompatibleAlphaBitmap(maButtonSize
);
472 xCanvas
= Reference
<rendering::XCanvas
>(mxMouseOverBitmap
, UNO_QUERY
);
473 if (mpMouseOverFont
.get()!=NULL
&& !mpMouseOverFont
->mxFont
.is() && mxCanvas
.is())
474 mpMouseOverFont
->PrepareFont(mxCanvas
);
480 PresenterBitmapDescriptor::MouseOver
,
486 Reference
<beans::XPropertySet
> PresenterButton::GetConfigurationProperties (
487 const css::uno::Reference
<css::uno::XComponentContext
>& rxComponentContext
,
488 const OUString
& rsConfgurationName
)
490 PresenterConfigurationAccess
aConfiguration (
492 PresenterConfigurationAccess::msPresenterScreenRootName
,
493 PresenterConfigurationAccess::READ_ONLY
);
494 return Reference
<beans::XPropertySet
>(
495 PresenterConfigurationAccess::Find (
496 Reference
<container::XNameAccess
>(
497 aConfiguration
.GetConfigurationNode("PresenterScreenSettings/Buttons"),
499 ::boost::bind(&PresenterConfigurationAccess::IsStringPropertyEqual
,
506 void PresenterButton::ThrowIfDisposed() const
507 throw (::com::sun::star::lang::DisposedException
)
509 if (rBHelper
.bDisposed
|| rBHelper
.bInDispose
)
511 throw lang::DisposedException (
512 OUString( "PresenterButton object has already been disposed"),
513 const_cast<uno::XWeak
*>(static_cast<const uno::XWeak
*>(this)));
517 } } // end of namespace sdext::presenter
519 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */