xref: /trunk/main/sdext/source/presenter/PresenterPaneBase.cxx (revision 45c5a00162811bd03b87fcb4fe9996782f2b59ec)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sdext.hxx"
26 
27 #include "PresenterPaneBase.hxx"
28 #include "PresenterCanvasHelper.hxx"
29 #include "PresenterController.hxx"
30 #include "PresenterGeometryHelper.hxx"
31 #include "PresenterPaintManager.hxx"
32 #include "PresenterTextView.hxx"
33 #include <com/sun/star/awt/PosSize.hpp>
34 #include <com/sun/star/awt/XWindow2.hpp>
35 #include <com/sun/star/awt/XWindowPeer.hpp>
36 #include <com/sun/star/lang/XMultiComponentFactory.hpp>
37 #include <com/sun/star/drawing/CanvasFeature.hpp>
38 #include <com/sun/star/rendering/CompositeOperation.hpp>
39 #include <com/sun/star/rendering/TexturingMode.hpp>
40 #include <osl/mutex.hxx>
41 
42 using namespace ::com::sun::star;
43 using namespace ::com::sun::star::uno;
44 using namespace ::com::sun::star::drawing::framework;
45 using ::rtl::OUString;
46 
47 namespace sdext { namespace presenter {
48 
49 //===== PresenterPaneBase =====================================================
50 
51 PresenterPaneBase::PresenterPaneBase (
52     const Reference<XComponentContext>& rxContext,
53     const ::rtl::Reference<PresenterController>& rpPresenterController)
54     : PresenterPaneBaseInterfaceBase(m_aMutex),
55       mpPresenterController(rpPresenterController),
56       mxParentWindow(),
57       mxBorderWindow(),
58       mxBorderCanvas(),
59       mxContentWindow(),
60       mxContentCanvas(),
61       mxPaneId(),
62       mxBorderPainter(),
63       mxPresenterHelper(),
64       msTitle(),
65       mxComponentContext(rxContext),
66       mpViewBackground(),
67       mbHasCallout(false),
68       maCalloutAnchor()
69 {
70     if (mpPresenterController.get() != NULL)
71         mxPresenterHelper = mpPresenterController->GetPresenterHelper();
72 }
73 
74 
75 
76 
77 PresenterPaneBase::~PresenterPaneBase (void)
78 {
79 }
80 
81 
82 
83 
84 void PresenterPaneBase::disposing (void)
85 {
86     if (mxBorderWindow.is())
87     {
88         mxBorderWindow->removeWindowListener(this);
89         mxBorderWindow->removePaintListener(this);
90     }
91 
92     {
93         Reference<XComponent> xComponent (mxContentCanvas, UNO_QUERY);
94         mxContentCanvas = NULL;
95         if (xComponent.is())
96             xComponent->dispose();
97     }
98 
99     {
100         Reference<XComponent> xComponent (mxContentWindow, UNO_QUERY);
101         mxContentWindow = NULL;
102         if (xComponent.is())
103             xComponent->dispose();
104     }
105 
106     {
107         Reference<XComponent> xComponent (mxBorderCanvas, UNO_QUERY);
108         mxBorderCanvas = NULL;
109         if (xComponent.is())
110             xComponent->dispose();
111     }
112 
113     {
114         Reference<XComponent> xComponent (mxBorderWindow, UNO_QUERY);
115         mxBorderWindow = NULL;
116         if (xComponent.is())
117             xComponent->dispose();
118     }
119 
120     mxComponentContext = NULL;
121 }
122 
123 
124 
125 
126 void PresenterPaneBase::SetTitle (const OUString& rsTitle)
127 {
128     msTitle = rsTitle;
129 
130     OSL_ASSERT(mpPresenterController.get()!=NULL);
131     OSL_ASSERT(mpPresenterController->GetPaintManager().get()!=NULL);
132 
133     mpPresenterController->GetPaintManager()->Invalidate(mxBorderWindow);
134 }
135 
136 
137 
138 
139 ::rtl::OUString PresenterPaneBase::GetTitle (void) const
140 {
141     return msTitle;
142 }
143 
144 
145 
146 
147 Reference<drawing::framework::XPaneBorderPainter>
148     PresenterPaneBase::GetPaneBorderPainter (void) const
149 {
150     return mxBorderPainter;
151 }
152 
153 
154 
155 
156 void PresenterPaneBase::SetCalloutAnchor (const css::awt::Point& rCalloutAnchor)
157 {
158     mbHasCallout = true;
159     // Anchor is given in the coorindate system of the parent window.
160     // Transform it into the local coordinate system.
161     maCalloutAnchor = rCalloutAnchor;
162     const awt::Rectangle aBorderBox (mxBorderWindow->getPosSize());
163     maCalloutAnchor.X -= aBorderBox.X;
164     maCalloutAnchor.Y -= aBorderBox.Y;
165 
166     // Move the bottom of the border window so that it goes through the
167     // callout anchor (special case for bottom callout).
168     sal_Int32 nHeight (rCalloutAnchor.Y - aBorderBox.Y);
169     if (mxBorderPainter.is() && mxPaneId.is())
170         nHeight += mxBorderPainter->getCalloutOffset(mxPaneId->getResourceURL()).Y;
171 
172     if (nHeight != aBorderBox.Height)
173     {
174         mxBorderWindow->setPosSize(
175             aBorderBox.X,
176             aBorderBox.Y,
177             aBorderBox.Width,
178             nHeight,
179             awt::PosSize::HEIGHT);
180     }
181 
182     mpPresenterController->GetPaintManager()->Invalidate(mxBorderWindow);
183 }
184 
185 
186 
187 
188 awt::Point PresenterPaneBase::GetCalloutAnchor (void) const
189 {
190     return maCalloutAnchor;
191 }
192 
193 
194 
195 
196 ::boost::shared_ptr<PresenterTextView> PresenterPaneBase::GetTextViewForTitle (void)
197 {
198     ::boost::shared_ptr<PresenterTextView> pTextView(
199         new PresenterTextView(
200             mxComponentContext,
201             mxBorderCanvas));
202     pTextView->SetText(msTitle);
203     return pTextView;
204 }
205 
206 
207 
208 
209 //----- XInitialization -------------------------------------------------------
210 
211 void SAL_CALL PresenterPaneBase::initialize (const Sequence<Any>& rArguments)
212 {
213     ThrowIfDisposed();
214 
215     if ( ! mxComponentContext.is())
216     {
217         throw RuntimeException(
218             OUString::createFromAscii("PresenterSpritePane: missing component context"),
219             static_cast<XWeak*>(this));
220     }
221 
222     if (rArguments.getLength() == 5 || rArguments.getLength() == 6)
223     {
224         try
225         {
226             // Get the resource id from the first argument.
227             if ( ! (rArguments[0] >>= mxPaneId))
228             {
229                 throw lang::IllegalArgumentException(
230                     OUString::createFromAscii("PresenterPane: invalid pane id"),
231                     static_cast<XWeak*>(this),
232                     0);
233             }
234 
235             if ( ! (rArguments[1] >>= mxParentWindow))
236             {
237                 throw lang::IllegalArgumentException(
238                     OUString::createFromAscii("PresenterPane: invalid parent window"),
239                     static_cast<XWeak*>(this),
240                     1);
241             }
242 
243             Reference<rendering::XSpriteCanvas> xParentCanvas;
244             if ( ! (rArguments[2] >>= xParentCanvas))
245             {
246                 throw lang::IllegalArgumentException(
247                     OUString::createFromAscii("PresenterPane: invalid parent canvas"),
248                     static_cast<XWeak*>(this),
249                     2);
250             }
251 
252             if ( ! (rArguments[3] >>= msTitle))
253             {
254                 throw lang::IllegalArgumentException(
255                     OUString::createFromAscii("PresenterPane: invalid title"),
256                     static_cast<XWeak*>(this),
257                     3);
258             }
259 
260             if ( ! (rArguments[4] >>= mxBorderPainter))
261             {
262                 throw lang::IllegalArgumentException(
263                     OUString::createFromAscii("PresenterPane: invalid border painter"),
264                     static_cast<XWeak*>(this),
265                     4);
266             }
267 
268             bool bIsWindowVisibleOnCreation (true);
269             if (rArguments.getLength()>5 && ! (rArguments[5] >>= bIsWindowVisibleOnCreation))
270             {
271                 throw lang::IllegalArgumentException(
272                     OUString::createFromAscii("PresenterPane: invalid window visibility flag"),
273                     static_cast<XWeak*>(this),
274                     5);
275             }
276 
277             CreateWindows(mxParentWindow, bIsWindowVisibleOnCreation);
278 
279             if (mxBorderWindow.is())
280             {
281                 mxBorderWindow->addWindowListener(this);
282                 mxBorderWindow->addPaintListener(this);
283             }
284 
285             CreateCanvases(mxParentWindow, xParentCanvas);
286 
287             // Raise new windows.
288             ToTop();
289         }
290         catch (Exception&)
291         {
292             mxContentWindow = NULL;
293             mxComponentContext = NULL;
294             throw;
295         }
296     }
297     else
298     {
299         throw RuntimeException(
300             OUString::createFromAscii("PresenterSpritePane: invalid number of arguments"),
301                 static_cast<XWeak*>(this));
302     }
303 }
304 
305 
306 
307 
308 //----- XResourceId -----------------------------------------------------------
309 
310 Reference<XResourceId> SAL_CALL PresenterPaneBase::getResourceId (void)
311 {
312     ThrowIfDisposed();
313     return mxPaneId;
314 }
315 
316 
317 
318 
319 sal_Bool SAL_CALL PresenterPaneBase::isAnchorOnly (void)
320 {
321     return true;
322 }
323 
324 
325 
326 
327 //----- XWindowListener -------------------------------------------------------
328 
329 void SAL_CALL PresenterPaneBase::windowResized (const awt::WindowEvent& rEvent)
330 {
331     (void)rEvent;
332     ThrowIfDisposed();
333 }
334 
335 
336 
337 
338 
339 void SAL_CALL PresenterPaneBase::windowMoved (const awt::WindowEvent& rEvent)
340 {
341     (void)rEvent;
342     ThrowIfDisposed();
343 }
344 
345 
346 
347 
348 void SAL_CALL PresenterPaneBase::windowShown (const lang::EventObject& rEvent)
349 {
350     (void)rEvent;
351     ThrowIfDisposed();
352 }
353 
354 
355 
356 
357 void SAL_CALL PresenterPaneBase::windowHidden (const lang::EventObject& rEvent)
358 {
359     (void)rEvent;
360     ThrowIfDisposed();
361 }
362 
363 
364 
365 
366 //----- lang::XEventListener --------------------------------------------------
367 
368 void SAL_CALL PresenterPaneBase::disposing (const lang::EventObject& rEvent)
369 {
370     if (rEvent.Source == mxBorderWindow)
371     {
372         mxBorderWindow = NULL;
373     }
374 }
375 
376 
377 
378 
379 //-----------------------------------------------------------------------------
380 
381 
382 void PresenterPaneBase::CreateWindows (
383     const Reference<awt::XWindow>& rxParentWindow,
384     const bool bIsWindowVisibleOnCreation)
385 {
386     if (mxPresenterHelper.is() && rxParentWindow.is())
387     {
388 
389         mxBorderWindow = mxPresenterHelper->createWindow(
390             rxParentWindow,
391             sal_False,
392             bIsWindowVisibleOnCreation,
393             sal_False,
394             sal_False);
395         mxContentWindow = mxPresenterHelper->createWindow(
396             mxBorderWindow,
397             sal_False,
398             bIsWindowVisibleOnCreation,
399             sal_False,
400             sal_False);
401     }
402 }
403 
404 
405 
406 
407 Reference<awt::XWindow> PresenterPaneBase::GetBorderWindow (void) const
408 {
409     return mxBorderWindow;
410 }
411 
412 
413 
414 
415 void PresenterPaneBase::ToTop (void)
416 {
417     if (mxPresenterHelper.is())
418         mxPresenterHelper->toTop(mxContentWindow);
419 }
420 
421 
422 
423 
424 void PresenterPaneBase::SetBackground (const SharedBitmapDescriptor& rpBackground)
425 {
426     mpViewBackground = rpBackground;
427 }
428 
429 
430 
431 
432 void PresenterPaneBase::PaintBorderBackground (
433     const awt::Rectangle& rBorderBox,
434     const awt::Rectangle& rUpdateBox)
435 {
436     (void)rBorderBox;
437     (void)rUpdateBox;
438     /*
439     // The outer box of the border is given.  We need the center and inner
440     // box as well.
441     awt::Rectangle aCenterBox (
442         mxBorderPainter->removeBorder(
443             mxPaneId->getResourceURL(),
444             rBorderBox,
445             drawing::framework::BorderType_OUTER_BORDER));
446     awt::Rectangle aInnerBox (
447         mxBorderPainter->removeBorder(
448             mxPaneId->getResourceURL(),
449             rBorderBox,
450             drawing::framework::BorderType_TOTAL_BORDER));
451     mpPresenterController->GetCanvasHelper()->Paint(
452         mpViewBackground,
453         mxBorderCanvas,
454         rUpdateBox,
455         aCenterBox,
456         aInnerBox);
457     */
458 }
459 
460 
461 
462 
463 void PresenterPaneBase::PaintBorder (const awt::Rectangle& rUpdateBox)
464 {
465     OSL_ASSERT(mxPaneId.is());
466 
467     if (mxBorderPainter.is() && mxBorderWindow.is() && mxBorderCanvas.is())
468     {
469         awt::Rectangle aBorderBox (mxBorderWindow->getPosSize());
470         awt::Rectangle aLocalBorderBox (0,0, aBorderBox.Width, aBorderBox.Height);
471 
472         PaintBorderBackground(aLocalBorderBox, rUpdateBox);
473 
474         if (mbHasCallout)
475             mxBorderPainter->paintBorderWithCallout(
476                 mxPaneId->getResourceURL(),
477                 mxBorderCanvas,
478                 aLocalBorderBox,
479                 rUpdateBox,
480                 msTitle,
481                 maCalloutAnchor);
482         else
483             mxBorderPainter->paintBorder(
484                 mxPaneId->getResourceURL(),
485                 mxBorderCanvas,
486                 aLocalBorderBox,
487                 rUpdateBox,
488                 msTitle);
489     }
490 }
491 
492 
493 
494 
495 void PresenterPaneBase::LayoutContextWindow (void)
496 {
497     OSL_ASSERT(mxPaneId.is());
498     OSL_ASSERT(mxBorderWindow.is());
499     OSL_ASSERT(mxContentWindow.is());
500     if (mxBorderPainter.is() && mxPaneId.is() && mxBorderWindow.is() && mxContentWindow.is())
501     {
502         const awt::Rectangle aBorderBox (mxBorderWindow->getPosSize());
503         const awt::Rectangle aInnerBox (mxBorderPainter->removeBorder(
504             mxPaneId->getResourceURL(),
505             aBorderBox,
506             drawing::framework::BorderType_TOTAL_BORDER));
507         mxContentWindow->setPosSize(
508             aInnerBox.X - aBorderBox.X,
509             aInnerBox.Y - aBorderBox.Y,
510             aInnerBox.Width,
511             aInnerBox.Height,
512             awt::PosSize::POSSIZE);
513     }
514 }
515 
516 
517 
518 
519 bool PresenterPaneBase::IsVisible (void) const
520 {
521     Reference<awt::XWindow2> xWindow2 (mxBorderPainter, UNO_QUERY);
522     if (xWindow2.is())
523         return xWindow2->isVisible();
524 
525     return false;
526 }
527 
528 
529 
530 
531 void PresenterPaneBase::ThrowIfDisposed (void)
532 {
533     if (rBHelper.bDisposed || rBHelper.bInDispose)
534     {
535         throw lang::DisposedException (
536             ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
537                 "PresenterPane object has already been disposed")),
538             static_cast<uno::XWeak*>(this));
539     }
540 }
541 
542 
543 
544 
545 } } // end of namespace ::sd::presenter
546