merge the formfield patch from ooo-build
[ooovba.git] / sdext / source / presenter / PresenterButton.cxx
blobb6faffc5130a80e563b4c35c880fdd6a71d6de47
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 if (rpFont.get()==NULL || ! rpFont->mxFont.is())
485 return;
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;
498 rxCanvas->drawText(
499 aContext,
500 rpFont->mxFont,
501 rendering::ViewState(geometry::AffineMatrix2D(1,0,0, 0,1,0), NULL),
502 aRenderState,
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);
523 else
525 OSL_ASSERT(mpIcon.get()!=NULL);
526 return NULL;
533 void PresenterButton::SetupButtonBitmaps (void)
535 if ( ! mxCanvas.is())
536 return;
537 if ( ! mxCanvas->getDevice().is())
538 return;
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)
548 return;
550 mxNormalBitmap = mxCanvas->getDevice()->createCompatibleAlphaBitmap(maButtonSize);
551 Reference<rendering::XCanvas> xCanvas (mxNormalBitmap, UNO_QUERY);
552 if (xCanvas.is())
553 RenderButton(
554 xCanvas,
555 maButtonSize,
556 mpFont,
557 PresenterBitmapDescriptor::Normal,
558 pLeftBitmap,
559 pCenterBitmap,
560 pRightBitmap);
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);
566 if (xCanvas.is())
567 RenderButton(
568 xCanvas,
569 maButtonSize,
570 mpMouseOverFont,
571 PresenterBitmapDescriptor::MouseOver,
572 pLeftBitmap,
573 pCenterBitmap,
574 pRightBitmap);
580 Reference<beans::XPropertySet> PresenterButton::GetConfigurationProperties (
581 const css::uno::Reference<css::uno::XComponentContext>& rxComponentContext,
582 const OUString& rsConfgurationName)
584 PresenterConfigurationAccess aConfiguration (
585 rxComponentContext,
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")),
592 UNO_QUERY),
593 ::boost::bind(&PresenterConfigurationAccess::IsStringPropertyEqual,
594 rsConfgurationName,
595 A2S("Name"),
596 _2)),
597 UNO_QUERY);
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