1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: PresenterButton.cxx,v $
13 * This file is part of OpenOffice.org.
15 * OpenOffice.org is free software: you can redistribute it and/or modify
16 * it under the terms of the GNU Lesser General Public License version 3
17 * only, as published by the Free Software Foundation.
19 * OpenOffice.org is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU Lesser General Public License version 3 for more details
23 * (a copy is included in the LICENSE file that accompanied this code).
25 * You should have received a copy of the GNU Lesser General Public License
26 * version 3 along with OpenOffice.org. If not, see
27 * <http://www.openoffice.org/license.html>
28 * for a copy of the LGPLv3 License.
30 ************************************************************************/
32 // MARKER(update_precomp.py): autogen include statement, do not remove
33 #include "precompiled_sdext.hxx"
35 #include "PresenterButton.hxx"
36 #include "PresenterCanvasHelper.hxx"
37 #include "PresenterController.hxx"
38 #include "PresenterGeometryHelper.hxx"
39 #include "PresenterPaintManager.hxx"
40 #include "PresenterUIPainter.hxx"
41 #include <com/sun/star/awt/PosSize.hpp>
42 #include <com/sun/star/awt/XWindowPeer.hpp>
43 #include <com/sun/star/drawing/XPresenterHelper.hpp>
44 #include <com/sun/star/rendering/CompositeOperation.hpp>
45 #include <com/sun/star/rendering/TextDirection.hpp>
46 #include <boost/bind.hpp>
48 using namespace ::com::sun::star
;
49 using namespace ::com::sun::star::uno
;
50 using ::rtl::OUString
;
52 #define A2S(pString) (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(pString)))
54 namespace sdext
{ namespace presenter
{
56 const static double gnHorizontalBorder (15);
57 const static double gnVerticalBorder (5);
61 ::rtl::Reference
<PresenterButton
> PresenterButton::Create (
62 const css::uno::Reference
<css::uno::XComponentContext
>& rxComponentContext
,
63 const ::rtl::Reference
<PresenterController
>& rpPresenterController
,
64 const ::boost::shared_ptr
<PresenterTheme
>& rpTheme
,
65 const css::uno::Reference
<css::awt::XWindow
>& rxParentWindow
,
66 const css::uno::Reference
<css::rendering::XCanvas
>& rxParentCanvas
,
67 const OUString
& rsConfigurationName
)
69 Reference
<beans::XPropertySet
> xProperties (GetConfigurationProperties(
71 rsConfigurationName
));
76 PresenterConfigurationAccess::GetProperty(xProperties
, A2S("Text")) >>= sText
;
77 PresenterConfigurationAccess::GetProperty(xProperties
, A2S("Action")) >>= sAction
;
79 PresenterTheme::SharedFontDescriptor pFont
;
80 if (rpTheme
.get() != NULL
)
81 pFont
= rpTheme
->GetFont(A2S("ButtonFont"));
83 PresenterTheme::SharedFontDescriptor pMouseOverFont
;
84 if (rpTheme
.get() != NULL
)
85 pMouseOverFont
= rpTheme
->GetFont(A2S("ButtonMouseOverFont"));
87 rtl::Reference
<PresenterButton
> pButton (
90 rpPresenterController
,
97 pButton
->SetCanvas(rxParentCanvas
, rxParentWindow
);
107 PresenterButton::PresenterButton (
108 const css::uno::Reference
<css::uno::XComponentContext
>& rxComponentContext
,
109 const ::rtl::Reference
<PresenterController
>& rpPresenterController
,
110 const ::boost::shared_ptr
<PresenterTheme
>& rpTheme
,
111 const css::uno::Reference
<css::awt::XWindow
>& rxParentWindow
,
112 const PresenterTheme::SharedFontDescriptor
& rpFont
,
113 const PresenterTheme::SharedFontDescriptor
& rpMouseOverFont
,
114 const OUString
& rsText
,
115 const OUString
& rsAction
)
116 : PresenterButtonInterfaceBase(m_aMutex
),
117 mpPresenterController(rpPresenterController
),
124 mpMouseOverFont(rpMouseOverFont
),
128 meState(PresenterBitmapDescriptor::Normal
),
134 Reference
<lang::XMultiComponentFactory
> xFactory (rxComponentContext
->getServiceManager());
135 if ( ! xFactory
.is())
136 throw RuntimeException();
138 mxPresenterHelper
= Reference
<drawing::XPresenterHelper
>(
139 xFactory
->createInstanceWithContext(
140 OUString::createFromAscii("com.sun.star.comp.Draw.PresenterHelper"),
144 if (mxPresenterHelper
.is())
145 mxWindow
= mxPresenterHelper
->createWindow(rxParentWindow
,
151 // Make the background transparent.
152 Reference
<awt::XWindowPeer
> xPeer (mxWindow
, UNO_QUERY_THROW
);
155 xPeer
->setBackground(0xff000000);
158 mxWindow
->setVisible(sal_True
);
159 mxWindow
->addWindowListener(this);
160 mxWindow
->addPaintListener(this);
161 mxWindow
->addMouseListener(this);
162 mxWindow
->addMouseMotionListener(this);
164 catch (RuntimeException
&)
172 PresenterButton::~PresenterButton (void)
179 void SAL_CALL
PresenterButton::disposing (void)
183 Reference
<lang::XComponent
> xComponent (mxCanvas
, UNO_QUERY
);
186 xComponent
->dispose();
191 mxWindow
->removeWindowListener(this);
192 mxWindow
->removePaintListener(this);
193 mxWindow
->removeMouseListener(this);
194 mxWindow
->removeMouseMotionListener(this);
195 Reference
<lang::XComponent
> xComponent (mxWindow
, UNO_QUERY
);
198 xComponent
->dispose();
205 void PresenterButton::SetCenter (const css::geometry::RealPoint2D
& rLocation
)
211 maCenter
= rLocation
;
212 mxWindow
->setPosSize(
213 sal_Int32(0.5 + maCenter
.X
- maButtonSize
.Width
/2),
214 sal_Int32(0.5 + maCenter
.Y
- maButtonSize
.Height
/2),
217 awt::PosSize::POSSIZE
);
223 // The button can not be painted but we can at least store the new center.
224 maCenter
= rLocation
;
231 void PresenterButton::SetCanvas (
232 const css::uno::Reference
<css::rendering::XCanvas
>& rxParentCanvas
,
233 const css::uno::Reference
<css::awt::XWindow
>& rxParentWindow
)
237 Reference
<lang::XComponent
> xComponent (mxCanvas
, UNO_QUERY
);
240 xComponent
->dispose();
243 if (mxPresenterHelper
.is() && rxParentCanvas
.is() && rxParentWindow
.is())
245 mxCanvas
= mxPresenterHelper
->createSharedCanvas (
246 Reference
<rendering::XSpriteCanvas
>(rxParentCanvas
, UNO_QUERY
),
253 SetupButtonBitmaps();
262 css::geometry::IntegerSize2D
PresenterButton::GetSize (void)
264 if (maButtonSize
.Width
< 0)
265 CalculateButtonSize();
272 //----- XWindowListener -------------------------------------------------------
274 void SAL_CALL
PresenterButton::windowResized (const css::awt::WindowEvent
& rEvent
)
275 throw (css::uno::RuntimeException
)
285 void SAL_CALL
PresenterButton::windowMoved (const css::awt::WindowEvent
& rEvent
)
286 throw (css::uno::RuntimeException
)
295 void SAL_CALL
PresenterButton::windowShown (const css::lang::EventObject
& rEvent
)
296 throw (css::uno::RuntimeException
)
305 void SAL_CALL
PresenterButton::windowHidden (const css::lang::EventObject
& rEvent
)
306 throw (css::uno::RuntimeException
)
315 //----- XPaintListener --------------------------------------------------------
317 void SAL_CALL
PresenterButton::windowPaint (const css::awt::PaintEvent
& rEvent
)
318 throw (css::uno::RuntimeException
)
321 if (mxWindow
.is() && mxCanvas
.is())
323 Reference
<rendering::XBitmap
> xBitmap
;
324 if (meState
== PresenterBitmapDescriptor::MouseOver
)
325 xBitmap
= mxMouseOverBitmap
;
327 xBitmap
= mxNormalBitmap
;
331 rendering::ViewState
aViewState(
332 geometry::AffineMatrix2D(1,0,0, 0,1,0),
334 rendering::RenderState
aRenderState(
335 geometry::AffineMatrix2D(1,0,0, 0,1,0),
336 PresenterGeometryHelper::CreatePolygon(rEvent
.UpdateRect
, mxCanvas
->getDevice()),
338 rendering::CompositeOperation::SOURCE
);
340 mxCanvas
->drawBitmap(xBitmap
, aViewState
, aRenderState
);
342 Reference
<rendering::XSpriteCanvas
> xSpriteCanvas (mxCanvas
, UNO_QUERY
);
343 if (xSpriteCanvas
.is())
344 xSpriteCanvas
->updateScreen(sal_False
);
351 //----- XMouseListener --------------------------------------------------------
353 void SAL_CALL
PresenterButton::mousePressed (const css::awt::MouseEvent
& rEvent
)
354 throw(css::uno::RuntimeException
)
359 meState
= PresenterBitmapDescriptor::ButtonDown
;
365 void SAL_CALL
PresenterButton::mouseReleased (const css::awt::MouseEvent
& rEvent
)
366 throw(css::uno::RuntimeException
)
371 if (meState
== PresenterBitmapDescriptor::ButtonDown
)
373 OSL_ASSERT(mpPresenterController
.get()!=NULL
);
374 mpPresenterController
->DispatchUnoCommand(msAction
);
376 meState
= PresenterBitmapDescriptor::Normal
;
384 void SAL_CALL
PresenterButton::mouseEntered (const css::awt::MouseEvent
& rEvent
)
385 throw(css::uno::RuntimeException
)
389 meState
= PresenterBitmapDescriptor::MouseOver
;
396 void SAL_CALL
PresenterButton::mouseExited (const css::awt::MouseEvent
& rEvent
)
397 throw(css::uno::RuntimeException
)
401 meState
= PresenterBitmapDescriptor::Normal
;
409 //----- XMouseMotionListener --------------------------------------------------
411 void SAL_CALL
PresenterButton::mouseMoved (const css::awt::MouseEvent
& rEvent
)
412 throw (css::uno::RuntimeException
)
421 void SAL_CALL
PresenterButton::mouseDragged (const css::awt::MouseEvent
& rEvent
)
422 throw (css::uno::RuntimeException
)
431 //----- lang::XEventListener --------------------------------------------------
433 void SAL_CALL
PresenterButton::disposing (const css::lang::EventObject
& rEvent
)
434 throw (css::uno::RuntimeException
)
436 if (rEvent
.Source
== mxWindow
)
443 //-----------------------------------------------------------------------------
445 css::geometry::IntegerSize2D
PresenterButton::CalculateButtonSize (void)
447 if (mpFont
.get()!=NULL
&& !mpFont
->mxFont
.is() && mxCanvas
.is())
448 mpFont
->PrepareFont(mxCanvas
);
449 if (mpFont
.get()==NULL
|| !mpFont
->mxFont
.is())
450 return geometry::IntegerSize2D(-1,-1);
452 geometry::RealSize2D
aTextSize (PresenterCanvasHelper::GetTextSize(mpFont
->mxFont
,msText
));
454 return geometry::IntegerSize2D (
455 sal_Int32(0.5 + aTextSize
.Width
+ 2*gnHorizontalBorder
),
456 sal_Int32(0.5 + aTextSize
.Height
+ 2*gnVerticalBorder
));
462 void PresenterButton::RenderButton (
463 const Reference
<rendering::XCanvas
>& rxCanvas
,
464 const geometry::IntegerSize2D
& rSize
,
465 const PresenterTheme::SharedFontDescriptor
& rpFont
,
466 const PresenterBitmapDescriptor::Mode eMode
,
467 const SharedBitmapDescriptor
& rpLeft
,
468 const SharedBitmapDescriptor
& rpCenter
,
469 const SharedBitmapDescriptor
& rpRight
)
471 if ( ! rxCanvas
.is())
474 const awt::Rectangle
aBox(0,0, rSize
.Width
, rSize
.Height
);
476 PresenterUIPainter::PaintHorizontalBitmapComposite (
480 GetBitmap(rpLeft
, eMode
),
481 GetBitmap(rpCenter
, eMode
),
482 GetBitmap(rpRight
, eMode
));
484 if (rpFont
.get()==NULL
|| ! rpFont
->mxFont
.is())
487 const rendering::StringContext
aContext (msText
, 0, msText
.getLength());
488 const Reference
<rendering::XTextLayout
> xLayout (
489 rpFont
->mxFont
->createTextLayout(aContext
,rendering::TextDirection::WEAK_LEFT_TO_RIGHT
,0));
490 const geometry::RealRectangle2D
aTextBBox (xLayout
->queryTextBounds());
492 rendering::RenderState
aRenderState (geometry::AffineMatrix2D(1,0,0, 0,1,0), NULL
,
493 Sequence
<double>(4), rendering::CompositeOperation::SOURCE
);
494 PresenterCanvasHelper::SetDeviceColor(aRenderState
, rpFont
->mnColor
);
495 aRenderState
.AffineTransform
.m02
= (rSize
.Width
- aTextBBox
.X2
+ aTextBBox
.X1
)/2;
496 aRenderState
.AffineTransform
.m12
= (rSize
.Height
- aTextBBox
.Y2
+ aTextBBox
.Y1
)/2 - aTextBBox
.Y1
;
501 rendering::ViewState(geometry::AffineMatrix2D(1,0,0, 0,1,0), NULL
),
503 rendering::TextDirection::WEAK_LEFT_TO_RIGHT
);
509 void PresenterButton::Invalidate (void)
511 mpPresenterController
->GetPaintManager()->Invalidate(mxWindow
);
517 Reference
<rendering::XBitmap
> PresenterButton::GetBitmap (
518 const SharedBitmapDescriptor
& mpIcon
,
519 const PresenterBitmapDescriptor::Mode eMode
)
521 if (mpIcon
.get() != NULL
)
522 return mpIcon
->GetBitmap(eMode
);
525 OSL_ASSERT(mpIcon
.get()!=NULL
);
533 void PresenterButton::SetupButtonBitmaps (void)
535 if ( ! mxCanvas
.is())
537 if ( ! mxCanvas
->getDevice().is())
540 // Get the bitmaps for the button border.
541 SharedBitmapDescriptor
pLeftBitmap (mpTheme
->GetBitmap(A2S("ButtonFrameLeft")));
542 SharedBitmapDescriptor
pCenterBitmap(mpTheme
->GetBitmap(A2S("ButtonFrameCenter")));
543 SharedBitmapDescriptor
pRightBitmap(mpTheme
->GetBitmap(A2S("ButtonFrameRight")));
545 maButtonSize
= CalculateButtonSize();
547 if (maButtonSize
.Height
<=0 && maButtonSize
.Width
<= 0)
550 mxNormalBitmap
= mxCanvas
->getDevice()->createCompatibleAlphaBitmap(maButtonSize
);
551 Reference
<rendering::XCanvas
> xCanvas (mxNormalBitmap
, UNO_QUERY
);
557 PresenterBitmapDescriptor::Normal
,
562 mxMouseOverBitmap
= mxCanvas
->getDevice()->createCompatibleAlphaBitmap(maButtonSize
);
563 xCanvas
= Reference
<rendering::XCanvas
>(mxMouseOverBitmap
, UNO_QUERY
);
564 if (mpMouseOverFont
.get()!=NULL
&& !mpMouseOverFont
->mxFont
.is() && mxCanvas
.is())
565 mpMouseOverFont
->PrepareFont(mxCanvas
);
571 PresenterBitmapDescriptor::MouseOver
,
580 Reference
<beans::XPropertySet
> PresenterButton::GetConfigurationProperties (
581 const css::uno::Reference
<css::uno::XComponentContext
>& rxComponentContext
,
582 const OUString
& rsConfgurationName
)
584 PresenterConfigurationAccess
aConfiguration (
586 PresenterConfigurationAccess::msPresenterScreenRootName
,
587 PresenterConfigurationAccess::READ_ONLY
);
588 return Reference
<beans::XPropertySet
>(
589 PresenterConfigurationAccess::Find (
590 Reference
<container::XNameAccess
>(
591 aConfiguration
.GetConfigurationNode(A2S("PresenterScreenSettings/Buttons")),
593 ::boost::bind(&PresenterConfigurationAccess::IsStringPropertyEqual
,
603 void PresenterButton::ThrowIfDisposed (void) const
604 throw (::com::sun::star::lang::DisposedException
)
606 if (rBHelper
.bDisposed
|| rBHelper
.bInDispose
)
608 throw lang::DisposedException (
609 OUString(RTL_CONSTASCII_USTRINGPARAM(
610 "PresenterButton object has already been disposed")),
611 const_cast<uno::XWeak
*>(static_cast<const uno::XWeak
*>(this)));
616 } } // end of namespace sdext::presenter