update dev300-m58
[ooovba.git] / sdext / source / presenter / PresenterButton.cxx
blob292aefb6144d64994941a7b888c0d1593b2120d8
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: PresenterButton.cxx,v $
11 * $Revision: 1.6 $
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(
70 rxComponentContext,
71 rsConfigurationName));
72 if (xProperties.is())
74 OUString sText;
75 OUString sAction;
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 (
88 new PresenterButton(
89 rxComponentContext,
90 rpPresenterController,
91 rpTheme,
92 rxParentWindow,
93 pFont,
94 pMouseOverFont,
95 sText,
96 sAction));
97 pButton->SetCanvas(rxParentCanvas, rxParentWindow);
98 return pButton;
100 else
101 return NULL;
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),
118 mpTheme(rpTheme),
119 mxWindow(),
120 mxCanvas(),
121 mxPresenterHelper(),
122 msText(rsText),
123 mpFont(rpFont),
124 mpMouseOverFont(rpMouseOverFont),
125 msAction(rsAction),
126 maCenter(),
127 maButtonSize(-1,-1),
128 meState(PresenterBitmapDescriptor::Normal),
129 mxNormalBitmap(),
130 mxMouseOverBitmap()
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"),
141 rxComponentContext),
142 UNO_QUERY_THROW);
144 if (mxPresenterHelper.is())
145 mxWindow = mxPresenterHelper->createWindow(rxParentWindow,
146 sal_False,
147 sal_False,
148 sal_False,
149 sal_False);
151 // Make the background transparent.
152 Reference<awt::XWindowPeer> xPeer (mxWindow, UNO_QUERY_THROW);
153 if (xPeer.is())
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)
181 if (mxCanvas.is())
183 Reference<lang::XComponent> xComponent (mxCanvas, UNO_QUERY);
184 mxCanvas = NULL;
185 if (xComponent.is())
186 xComponent->dispose();
189 if (mxWindow.is())
191 mxWindow->removeWindowListener(this);
192 mxWindow->removePaintListener(this);
193 mxWindow->removeMouseListener(this);
194 mxWindow->removeMouseMotionListener(this);
195 Reference<lang::XComponent> xComponent (mxWindow, UNO_QUERY);
196 mxWindow = NULL;
197 if (xComponent.is())
198 xComponent->dispose();
205 void PresenterButton::SetCenter (const css::geometry::RealPoint2D& rLocation)
207 if (mxCanvas.is())
209 Invalidate();
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),
215 maButtonSize.Width,
216 maButtonSize.Height,
217 awt::PosSize::POSSIZE);
219 Invalidate();
221 else
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)
235 if (mxCanvas.is())
237 Reference<lang::XComponent> xComponent (mxCanvas, UNO_QUERY);
238 mxCanvas = NULL;
239 if (xComponent.is())
240 xComponent->dispose();
243 if (mxPresenterHelper.is() && rxParentCanvas.is() && rxParentWindow.is())
245 mxCanvas = mxPresenterHelper->createSharedCanvas (
246 Reference<rendering::XSpriteCanvas>(rxParentCanvas, UNO_QUERY),
247 rxParentWindow,
248 rxParentCanvas,
249 rxParentWindow,
250 mxWindow);
251 if (mxCanvas.is())
253 SetupButtonBitmaps();
254 SetCenter(maCenter);
262 css::geometry::IntegerSize2D PresenterButton::GetSize (void)
264 if (maButtonSize.Width < 0)
265 CalculateButtonSize();
266 return maButtonSize;
272 //----- XWindowListener -------------------------------------------------------
274 void SAL_CALL PresenterButton::windowResized (const css::awt::WindowEvent& rEvent)
275 throw (css::uno::RuntimeException)
277 (void)rEvent;
278 ThrowIfDisposed();
285 void SAL_CALL PresenterButton::windowMoved (const css::awt::WindowEvent& rEvent)
286 throw (css::uno::RuntimeException)
288 (void)rEvent;
289 ThrowIfDisposed();
295 void SAL_CALL PresenterButton::windowShown (const css::lang::EventObject& rEvent)
296 throw (css::uno::RuntimeException)
298 (void)rEvent;
299 ThrowIfDisposed();
305 void SAL_CALL PresenterButton::windowHidden (const css::lang::EventObject& rEvent)
306 throw (css::uno::RuntimeException)
308 (void)rEvent;
309 ThrowIfDisposed();
315 //----- XPaintListener --------------------------------------------------------
317 void SAL_CALL PresenterButton::windowPaint (const css::awt::PaintEvent& rEvent)
318 throw (css::uno::RuntimeException)
320 ThrowIfDisposed();
321 if (mxWindow.is() && mxCanvas.is())
323 Reference<rendering::XBitmap> xBitmap;
324 if (meState == PresenterBitmapDescriptor::MouseOver)
325 xBitmap = mxMouseOverBitmap;
326 else
327 xBitmap = mxNormalBitmap;
328 if ( ! xBitmap.is())
329 return;
331 rendering::ViewState aViewState(
332 geometry::AffineMatrix2D(1,0,0, 0,1,0),
333 NULL);
334 rendering::RenderState aRenderState(
335 geometry::AffineMatrix2D(1,0,0, 0,1,0),
336 PresenterGeometryHelper::CreatePolygon(rEvent.UpdateRect, mxCanvas->getDevice()),
337 Sequence<double>(4),
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)
356 (void)rEvent;
357 ThrowIfDisposed();
359 meState = PresenterBitmapDescriptor::ButtonDown;
365 void SAL_CALL PresenterButton::mouseReleased (const css::awt::MouseEvent& rEvent)
366 throw(css::uno::RuntimeException)
368 (void)rEvent;
369 ThrowIfDisposed();
371 if (meState == PresenterBitmapDescriptor::ButtonDown)
373 OSL_ASSERT(mpPresenterController.get()!=NULL);
374 mpPresenterController->DispatchUnoCommand(msAction);
376 meState = PresenterBitmapDescriptor::Normal;
377 Invalidate();
384 void SAL_CALL PresenterButton::mouseEntered (const css::awt::MouseEvent& rEvent)
385 throw(css::uno::RuntimeException)
387 (void)rEvent;
388 ThrowIfDisposed();
389 meState = PresenterBitmapDescriptor::MouseOver;
390 Invalidate();
396 void SAL_CALL PresenterButton::mouseExited (const css::awt::MouseEvent& rEvent)
397 throw(css::uno::RuntimeException)
399 (void)rEvent;
400 ThrowIfDisposed();
401 meState = PresenterBitmapDescriptor::Normal;
402 Invalidate();
409 //----- XMouseMotionListener --------------------------------------------------
411 void SAL_CALL PresenterButton::mouseMoved (const css::awt::MouseEvent& rEvent)
412 throw (css::uno::RuntimeException)
414 (void)rEvent;
415 ThrowIfDisposed();
421 void SAL_CALL PresenterButton::mouseDragged (const css::awt::MouseEvent& rEvent)
422 throw (css::uno::RuntimeException)
424 (void)rEvent;
425 ThrowIfDisposed();
431 //----- lang::XEventListener --------------------------------------------------
433 void SAL_CALL PresenterButton::disposing (const css::lang::EventObject& rEvent)
434 throw (css::uno::RuntimeException)
436 if (rEvent.Source == mxWindow)
437 mxWindow = NULL;
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())
472 return;
474 const awt::Rectangle aBox(0,0, rSize.Width, rSize.Height);
476 PresenterUIPainter::PaintHorizontalBitmapComposite (
477 rxCanvas,
478 aBox,
479 aBox,
480 GetBitmap(rpLeft, eMode),
481 GetBitmap(rpCenter, eMode),
482 GetBitmap(rpRight, eMode));
484 sal_Int32 nBottomOffset (
485 ::std::max(rpLeft->mnYOffset, ::std::max(rpCenter->mnYOffset, rpRight->mnYOffset)));
486 if (rpFont.get()==NULL || ! rpFont->mxFont.is())
487 return;
489 const rendering::StringContext aContext (msText, 0, msText.getLength());
490 const Reference<rendering::XTextLayout> xLayout (
491 rpFont->mxFont->createTextLayout(aContext,rendering::TextDirection::WEAK_LEFT_TO_RIGHT,0));
492 const geometry::RealRectangle2D aTextBBox (xLayout->queryTextBounds());
494 rendering::RenderState aRenderState (geometry::AffineMatrix2D(1,0,0, 0,1,0), NULL,
495 Sequence<double>(4), rendering::CompositeOperation::SOURCE);
496 PresenterCanvasHelper::SetDeviceColor(aRenderState, rpFont->mnColor);
497 aRenderState.AffineTransform.m02 = (rSize.Width - aTextBBox.X2 + aTextBBox.X1)/2;
498 aRenderState.AffineTransform.m12 = rSize.Height - aTextBBox.Y2 - gnVerticalBorder - nBottomOffset;
500 rxCanvas->drawText(
501 aContext,
502 rpFont->mxFont,
503 rendering::ViewState(geometry::AffineMatrix2D(1,0,0, 0,1,0), NULL),
504 aRenderState,
505 rendering::TextDirection::WEAK_LEFT_TO_RIGHT);
511 void PresenterButton::Invalidate (void)
513 mpPresenterController->GetPaintManager()->Invalidate(mxWindow);
519 Reference<rendering::XBitmap> PresenterButton::GetBitmap (
520 const SharedBitmapDescriptor& mpIcon,
521 const PresenterBitmapDescriptor::Mode eMode)
523 if (mpIcon.get() != NULL)
524 return mpIcon->GetBitmap(eMode);
525 else
527 OSL_ASSERT(mpIcon.get()!=NULL);
528 return NULL;
535 void PresenterButton::SetupButtonBitmaps (void)
537 if ( ! mxCanvas.is())
538 return;
539 if ( ! mxCanvas->getDevice().is())
540 return;
542 // Get the bitmaps for the button border.
543 SharedBitmapDescriptor pLeftBitmap (mpTheme->GetBitmap(A2S("ButtonFrameLeft")));
544 SharedBitmapDescriptor pCenterBitmap(mpTheme->GetBitmap(A2S("ButtonFrameCenter")));
545 SharedBitmapDescriptor pRightBitmap(mpTheme->GetBitmap(A2S("ButtonFrameRight")));
547 maButtonSize = CalculateButtonSize();
549 if (maButtonSize.Height<=0 && maButtonSize.Width<= 0)
550 return;
552 mxNormalBitmap = mxCanvas->getDevice()->createCompatibleAlphaBitmap(maButtonSize);
553 Reference<rendering::XCanvas> xCanvas (mxNormalBitmap, UNO_QUERY);
554 if (xCanvas.is())
555 RenderButton(
556 xCanvas,
557 maButtonSize,
558 mpFont,
559 PresenterBitmapDescriptor::Normal,
560 pLeftBitmap,
561 pCenterBitmap,
562 pRightBitmap);
564 mxMouseOverBitmap = mxCanvas->getDevice()->createCompatibleAlphaBitmap(maButtonSize);
565 xCanvas = Reference<rendering::XCanvas>(mxMouseOverBitmap, UNO_QUERY);
566 if (mpMouseOverFont.get()!=NULL && !mpMouseOverFont->mxFont.is() && mxCanvas.is())
567 mpMouseOverFont->PrepareFont(mxCanvas);
568 if (xCanvas.is())
569 RenderButton(
570 xCanvas,
571 maButtonSize,
572 mpMouseOverFont,
573 PresenterBitmapDescriptor::MouseOver,
574 pLeftBitmap,
575 pCenterBitmap,
576 pRightBitmap);
582 Reference<beans::XPropertySet> PresenterButton::GetConfigurationProperties (
583 const css::uno::Reference<css::uno::XComponentContext>& rxComponentContext,
584 const OUString& rsConfgurationName)
586 PresenterConfigurationAccess aConfiguration (
587 rxComponentContext,
588 PresenterConfigurationAccess::msPresenterScreenRootName,
589 PresenterConfigurationAccess::READ_ONLY);
590 return Reference<beans::XPropertySet>(
591 PresenterConfigurationAccess::Find (
592 Reference<container::XNameAccess>(
593 aConfiguration.GetConfigurationNode(A2S("PresenterScreenSettings/Buttons")),
594 UNO_QUERY),
595 ::boost::bind(&PresenterConfigurationAccess::IsStringPropertyEqual,
596 rsConfgurationName,
597 A2S("Name"),
598 _2)),
599 UNO_QUERY);
605 void PresenterButton::ThrowIfDisposed (void) const
606 throw (::com::sun::star::lang::DisposedException)
608 if (rBHelper.bDisposed || rBHelper.bInDispose)
610 throw lang::DisposedException (
611 OUString(RTL_CONSTASCII_USTRINGPARAM(
612 "PresenterButton object has already been disposed")),
613 const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this)));
618 } } // end of namespace sdext::presenter