fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / sdext / source / presenter / PresenterButton.cxx
bloba4c23d28dcffb2e4e0b8215445ed823577231f98
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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(
51 rxComponentContext,
52 rsConfigurationName));
53 if (xProperties.is())
55 OUString sText;
56 OUString sAction;
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 (
69 new PresenterButton(
70 rxComponentContext,
71 rpPresenterController,
72 rpTheme,
73 rxParentWindow,
74 pFont,
75 pMouseOverFont,
76 sText,
77 sAction));
78 pButton->SetCanvas(rxParentCanvas, rxParentWindow);
79 return pButton;
81 else
82 return NULL;
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),
96 mpTheme(rpTheme),
97 mxWindow(),
98 mxCanvas(),
99 mxPresenterHelper(),
100 msText(rsText),
101 mpFont(rpFont),
102 mpMouseOverFont(rpMouseOverFont),
103 msAction(rsAction),
104 maCenter(),
105 maButtonSize(-1,-1),
106 meState(PresenterBitmapDescriptor::Normal),
107 mxNormalBitmap(),
108 mxMouseOverBitmap()
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"),
119 rxComponentContext),
120 UNO_QUERY_THROW);
122 if (mxPresenterHelper.is())
123 mxWindow = mxPresenterHelper->createWindow(rxParentWindow,
124 sal_False,
125 sal_False,
126 sal_False,
127 sal_False);
129 // Make the background transparent.
130 Reference<awt::XWindowPeer> xPeer (mxWindow, UNO_QUERY_THROW);
131 if (xPeer.is())
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()
153 if (mxCanvas.is())
155 Reference<lang::XComponent> xComponent (mxCanvas, UNO_QUERY);
156 mxCanvas = NULL;
157 if (xComponent.is())
158 xComponent->dispose();
161 if (mxWindow.is())
163 mxWindow->removeWindowListener(this);
164 mxWindow->removePaintListener(this);
165 mxWindow->removeMouseListener(this);
166 mxWindow->removeMouseMotionListener(this);
167 Reference<lang::XComponent> xComponent (mxWindow, UNO_QUERY);
168 mxWindow = NULL;
169 if (xComponent.is())
170 xComponent->dispose();
174 void PresenterButton::SetCenter (const css::geometry::RealPoint2D& rLocation)
176 if (mxCanvas.is())
178 Invalidate();
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),
184 maButtonSize.Width,
185 maButtonSize.Height,
186 awt::PosSize::POSSIZE);
188 Invalidate();
190 else
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)
201 if (mxCanvas.is())
203 Reference<lang::XComponent> xComponent (mxCanvas, UNO_QUERY);
204 mxCanvas = NULL;
205 if (xComponent.is())
206 xComponent->dispose();
209 if (mxPresenterHelper.is() && rxParentCanvas.is() && rxParentWindow.is())
211 mxCanvas = mxPresenterHelper->createSharedCanvas (
212 Reference<rendering::XSpriteCanvas>(rxParentCanvas, UNO_QUERY),
213 rxParentWindow,
214 rxParentCanvas,
215 rxParentWindow,
216 mxWindow);
217 if (mxCanvas.is())
219 SetupButtonBitmaps();
220 SetCenter(maCenter);
225 css::geometry::IntegerSize2D PresenterButton::GetSize()
227 if (maButtonSize.Width < 0)
228 CalculateButtonSize();
229 return maButtonSize;
232 //----- XWindowListener -------------------------------------------------------
234 void SAL_CALL PresenterButton::windowResized (const css::awt::WindowEvent& rEvent)
235 throw (css::uno::RuntimeException, std::exception)
237 (void)rEvent;
238 ThrowIfDisposed();
241 void SAL_CALL PresenterButton::windowMoved (const css::awt::WindowEvent& rEvent)
242 throw (css::uno::RuntimeException, std::exception)
244 (void)rEvent;
245 ThrowIfDisposed();
248 void SAL_CALL PresenterButton::windowShown (const css::lang::EventObject& rEvent)
249 throw (css::uno::RuntimeException, std::exception)
251 (void)rEvent;
252 ThrowIfDisposed();
255 void SAL_CALL PresenterButton::windowHidden (const css::lang::EventObject& rEvent)
256 throw (css::uno::RuntimeException, std::exception)
258 (void)rEvent;
259 ThrowIfDisposed();
262 //----- XPaintListener --------------------------------------------------------
264 void SAL_CALL PresenterButton::windowPaint (const css::awt::PaintEvent& rEvent)
265 throw (css::uno::RuntimeException, std::exception)
267 ThrowIfDisposed();
268 if (mxWindow.is() && mxCanvas.is())
270 Reference<rendering::XBitmap> xBitmap;
271 if (meState == PresenterBitmapDescriptor::MouseOver)
272 xBitmap = mxMouseOverBitmap;
273 else
274 xBitmap = mxNormalBitmap;
275 if ( ! xBitmap.is())
276 return;
278 rendering::ViewState aViewState(
279 geometry::AffineMatrix2D(1,0,0, 0,1,0),
280 NULL);
281 rendering::RenderState aRenderState(
282 geometry::AffineMatrix2D(1,0,0, 0,1,0),
283 PresenterGeometryHelper::CreatePolygon(rEvent.UpdateRect, mxCanvas->getDevice()),
284 Sequence<double>(4),
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)
300 (void)rEvent;
301 ThrowIfDisposed();
302 meState = PresenterBitmapDescriptor::ButtonDown;
305 void SAL_CALL PresenterButton::mouseReleased (const css::awt::MouseEvent& rEvent)
306 throw(css::uno::RuntimeException, std::exception)
308 (void)rEvent;
309 ThrowIfDisposed();
311 if (meState == PresenterBitmapDescriptor::ButtonDown)
313 OSL_ASSERT(mpPresenterController.get()!=NULL);
314 mpPresenterController->DispatchUnoCommand(msAction);
316 meState = PresenterBitmapDescriptor::Normal;
317 Invalidate();
321 void SAL_CALL PresenterButton::mouseEntered (const css::awt::MouseEvent& rEvent)
322 throw(css::uno::RuntimeException, std::exception)
324 (void)rEvent;
325 ThrowIfDisposed();
326 meState = PresenterBitmapDescriptor::MouseOver;
327 Invalidate();
330 void SAL_CALL PresenterButton::mouseExited (const css::awt::MouseEvent& rEvent)
331 throw(css::uno::RuntimeException, std::exception)
333 (void)rEvent;
334 ThrowIfDisposed();
335 meState = PresenterBitmapDescriptor::Normal;
336 Invalidate();
339 //----- XMouseMotionListener --------------------------------------------------
341 void SAL_CALL PresenterButton::mouseMoved (const css::awt::MouseEvent& rEvent)
342 throw (css::uno::RuntimeException, std::exception)
344 (void)rEvent;
345 ThrowIfDisposed();
348 void SAL_CALL PresenterButton::mouseDragged (const css::awt::MouseEvent& rEvent)
349 throw (css::uno::RuntimeException, std::exception)
351 (void)rEvent;
352 ThrowIfDisposed();
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)
361 mxWindow = NULL;
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())
390 return;
392 const awt::Rectangle aBox(0,0, rSize.Width, rSize.Height);
394 PresenterUIPainter::PaintHorizontalBitmapComposite (
395 rxCanvas,
396 aBox,
397 aBox,
398 GetBitmap(rpLeft, eMode),
399 GetBitmap(rpCenter, eMode),
400 GetBitmap(rpRight, eMode));
402 if (rpFont.get()==NULL || ! rpFont->mxFont.is())
403 return;
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(
419 xLayout,
420 rendering::ViewState(geometry::AffineMatrix2D(1,0,0, 0,1,0), NULL),
421 aRenderState);
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);
435 else
437 OSL_ASSERT(mpIcon.get()!=NULL);
438 return NULL;
442 void PresenterButton::SetupButtonBitmaps()
444 if ( ! mxCanvas.is())
445 return;
446 if ( ! mxCanvas->getDevice().is())
447 return;
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)
457 return;
459 mxNormalBitmap = mxCanvas->getDevice()->createCompatibleAlphaBitmap(maButtonSize);
460 Reference<rendering::XCanvas> xCanvas (mxNormalBitmap, UNO_QUERY);
461 if (xCanvas.is())
462 RenderButton(
463 xCanvas,
464 maButtonSize,
465 mpFont,
466 PresenterBitmapDescriptor::Normal,
467 pLeftBitmap,
468 pCenterBitmap,
469 pRightBitmap);
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);
475 if (xCanvas.is())
476 RenderButton(
477 xCanvas,
478 maButtonSize,
479 mpMouseOverFont,
480 PresenterBitmapDescriptor::MouseOver,
481 pLeftBitmap,
482 pCenterBitmap,
483 pRightBitmap);
486 Reference<beans::XPropertySet> PresenterButton::GetConfigurationProperties (
487 const css::uno::Reference<css::uno::XComponentContext>& rxComponentContext,
488 const OUString& rsConfgurationName)
490 PresenterConfigurationAccess aConfiguration (
491 rxComponentContext,
492 PresenterConfigurationAccess::msPresenterScreenRootName,
493 PresenterConfigurationAccess::READ_ONLY);
494 return Reference<beans::XPropertySet>(
495 PresenterConfigurationAccess::Find (
496 Reference<container::XNameAccess>(
497 aConfiguration.GetConfigurationNode("PresenterScreenSettings/Buttons"),
498 UNO_QUERY),
499 ::boost::bind(&PresenterConfigurationAccess::IsStringPropertyEqual,
500 rsConfgurationName,
501 OUString("Name"),
502 _2)),
503 UNO_QUERY);
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: */