Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #include "PresenterScrollBar.hxx"
21 : #include "PresenterBitmapContainer.hxx"
22 : #include "PresenterCanvasHelper.hxx"
23 : #include "PresenterGeometryHelper.hxx"
24 : #include "PresenterPaintManager.hxx"
25 : #include "PresenterTimer.hxx"
26 : #include "PresenterUIPainter.hxx"
27 : #include <com/sun/star/awt/PosSize.hpp>
28 : #include <com/sun/star/awt/WindowAttribute.hpp>
29 : #include <com/sun/star/awt/XWindowPeer.hpp>
30 : #include <com/sun/star/awt/XToolkit.hpp>
31 : #include <com/sun/star/rendering/CompositeOperation.hpp>
32 : #include <com/sun/star/rendering/TexturingMode.hpp>
33 : #include <com/sun/star/rendering/XPolyPolygon2D.hpp>
34 : #include <boost/bind.hpp>
35 : #include <boost/enable_shared_from_this.hpp>
36 : #include <boost/weak_ptr.hpp>
37 : #include <math.h>
38 :
39 : using namespace ::com::sun::star;
40 : using namespace ::com::sun::star::uno;
41 : using ::rtl::OUString;
42 :
43 : #define A2S(pString) (::rtl::OUString(pString))
44 :
45 : const static double gnScrollBarGap (10);
46 :
47 : namespace sdext { namespace presenter {
48 :
49 : //===== PresenterScrollBar::MousePressRepeater ================================
50 :
51 0 : class PresenterScrollBar::MousePressRepeater
52 : : public ::boost::enable_shared_from_this<MousePressRepeater>
53 : {
54 : public:
55 : MousePressRepeater (const ::rtl::Reference<PresenterScrollBar>& rpScrollBar);
56 : void Dispose (void);
57 : void Start (const PresenterScrollBar::Area& reArea);
58 : void Stop (void);
59 : void SetMouseArea (const PresenterScrollBar::Area& reArea);
60 :
61 : private:
62 : void Callback (const TimeValue& rCurrentTime);
63 : void Execute (void);
64 :
65 : sal_Int32 mnMousePressRepeaterTaskId;
66 : ::rtl::Reference<PresenterScrollBar> mpScrollBar;
67 : PresenterScrollBar::Area meMouseArea;
68 : };
69 :
70 : //===== PresenterScrollBar ====================================================
71 :
72 0 : boost::weak_ptr<PresenterBitmapContainer> PresenterScrollBar::mpSharedBitmaps;
73 :
74 0 : PresenterScrollBar::PresenterScrollBar (
75 : const Reference<XComponentContext>& rxComponentContext,
76 : const Reference<awt::XWindow>& rxParentWindow,
77 : const ::boost::shared_ptr<PresenterPaintManager>& rpPaintManager,
78 : const ::boost::function<void(double)>& rThumbMotionListener)
79 : : PresenterScrollBarInterfaceBase(m_aMutex),
80 : mxComponentContext(rxComponentContext),
81 : mxParentWindow(rxParentWindow),
82 : mxWindow(),
83 : mxCanvas(),
84 : mxPresenterHelper(),
85 : mpPaintManager(rpPaintManager),
86 : mnThumbPosition(0),
87 : mnTotalSize(0),
88 : mnThumbSize(0),
89 : mnLineHeight(10),
90 : maDragAnchor(-1,-1),
91 : maThumbMotionListener(rThumbMotionListener),
92 : meButtonDownArea(None),
93 : meMouseMoveArea(None),
94 : mbIsNotificationActive(false),
95 : mpBitmaps(),
96 : mpPrevButtonDescriptor(),
97 : mpNextButtonDescriptor(),
98 : mpPagerStartDescriptor(),
99 : mpPagerCenterDescriptor(),
100 : mpPagerEndDescriptor(),
101 : mpThumbStartDescriptor(),
102 : mpThumbCenterDescriptor(),
103 : mpThumbEndDescriptor(),
104 0 : mpMousePressRepeater(new MousePressRepeater(this)),
105 : mpBackgroundBitmap(),
106 0 : mpCanvasHelper(new PresenterCanvasHelper())
107 : {
108 : try
109 : {
110 0 : Reference<lang::XMultiComponentFactory> xFactory (rxComponentContext->getServiceManager());
111 0 : if ( ! xFactory.is())
112 0 : throw RuntimeException();
113 :
114 : mxPresenterHelper = Reference<drawing::XPresenterHelper>(
115 0 : xFactory->createInstanceWithContext(
116 : OUString("com.sun.star.comp.Draw.PresenterHelper"),
117 0 : rxComponentContext),
118 0 : UNO_QUERY_THROW);
119 :
120 0 : if (mxPresenterHelper.is())
121 0 : mxWindow = mxPresenterHelper->createWindow(rxParentWindow,
122 : sal_False,
123 : sal_False,
124 : sal_False,
125 0 : sal_False);
126 :
127 : // Make the background transparent. The slide show paints its own background.
128 0 : Reference<awt::XWindowPeer> xPeer (mxWindow, UNO_QUERY_THROW);
129 0 : if (xPeer.is())
130 : {
131 0 : xPeer->setBackground(0xff000000);
132 : }
133 :
134 0 : mxWindow->setVisible(sal_True);
135 0 : mxWindow->addWindowListener(this);
136 0 : mxWindow->addPaintListener(this);
137 0 : mxWindow->addMouseListener(this);
138 0 : mxWindow->addMouseMotionListener(this);
139 : }
140 0 : catch (RuntimeException&)
141 : {
142 : }
143 0 : }
144 :
145 0 : PresenterScrollBar::~PresenterScrollBar (void)
146 : {
147 0 : }
148 :
149 0 : void SAL_CALL PresenterScrollBar::disposing (void)
150 : {
151 0 : mpMousePressRepeater->Dispose();
152 :
153 0 : if (mxWindow.is())
154 : {
155 0 : mxWindow->removeWindowListener(this);
156 0 : mxWindow->removePaintListener(this);
157 0 : mxWindow->removeMouseListener(this);
158 0 : mxWindow->removeMouseMotionListener(this);
159 :
160 0 : Reference<lang::XComponent> xComponent (mxWindow, UNO_QUERY);
161 0 : mxWindow = NULL;
162 0 : if (xComponent.is())
163 0 : xComponent->dispose();
164 : }
165 :
166 0 : mpBitmaps.reset();
167 0 : }
168 :
169 0 : void PresenterScrollBar::SetVisible (const bool bIsVisible)
170 : {
171 0 : if (mxWindow.is())
172 0 : mxWindow->setVisible(bIsVisible);
173 0 : }
174 :
175 0 : void PresenterScrollBar::SetPosSize (const css::geometry::RealRectangle2D& rBox)
176 : {
177 0 : if (mxWindow.is())
178 : {
179 0 : mxWindow->setPosSize(
180 0 : sal_Int32(floor(rBox.X1)),
181 0 : sal_Int32(ceil(rBox.Y1)),
182 0 : sal_Int32(ceil(rBox.X2-rBox.X1)),
183 0 : sal_Int32(floor(rBox.Y2-rBox.Y1)),
184 0 : awt::PosSize::POSSIZE);
185 0 : UpdateBorders();
186 : }
187 0 : }
188 :
189 0 : void PresenterScrollBar::SetThumbPosition (
190 : double nPosition,
191 : const bool bAsynchronousUpdate)
192 : {
193 0 : SetThumbPosition(nPosition, bAsynchronousUpdate, true, true);
194 0 : }
195 :
196 0 : void PresenterScrollBar::SetThumbPosition (
197 : double nPosition,
198 : const bool bAsynchronousUpdate,
199 : const bool bValidate,
200 : const bool bNotify)
201 : {
202 0 : if (bValidate)
203 0 : nPosition = ValidateThumbPosition(nPosition);
204 :
205 0 : if (nPosition != mnThumbPosition && ! mbIsNotificationActive)
206 : {
207 0 : mnThumbPosition = nPosition;
208 :
209 0 : UpdateBorders();
210 0 : Repaint(GetRectangle(Total), bAsynchronousUpdate);
211 0 : if (bNotify)
212 0 : NotifyThumbPositionChange();
213 : }
214 0 : }
215 :
216 0 : double PresenterScrollBar::GetThumbPosition (void) const
217 : {
218 0 : return mnThumbPosition;
219 : }
220 :
221 0 : void PresenterScrollBar::SetTotalSize (const double nTotalSize)
222 : {
223 0 : if (mnTotalSize != nTotalSize)
224 : {
225 0 : mnTotalSize = nTotalSize + 1;
226 0 : UpdateBorders();
227 0 : Repaint(GetRectangle(Total), false);
228 : }
229 0 : }
230 :
231 0 : void PresenterScrollBar::SetThumbSize (const double nThumbSize)
232 : {
233 : OSL_ASSERT(nThumbSize>=0);
234 0 : if (mnThumbSize != nThumbSize)
235 : {
236 0 : mnThumbSize = nThumbSize;
237 0 : UpdateBorders();
238 0 : Repaint(GetRectangle(Total), false);
239 : }
240 0 : }
241 :
242 0 : double PresenterScrollBar::GetThumbSize (void) const
243 : {
244 0 : return mnThumbSize;
245 : }
246 :
247 0 : void PresenterScrollBar::SetLineHeight (const double nLineHeight)
248 : {
249 0 : mnLineHeight = nLineHeight;
250 0 : }
251 :
252 0 : double PresenterScrollBar::GetLineHeight (void) const
253 : {
254 0 : return mnLineHeight;
255 : }
256 :
257 0 : void PresenterScrollBar::SetCanvas (const Reference<css::rendering::XCanvas>& rxCanvas)
258 : {
259 0 : if (mxCanvas != rxCanvas)
260 : {
261 0 : mxCanvas = rxCanvas;
262 0 : if (mxCanvas.is())
263 : {
264 0 : if (mpBitmaps.get()==NULL)
265 : {
266 0 : if (mpSharedBitmaps.expired())
267 : {
268 : try
269 : {
270 : mpBitmaps.reset(new PresenterBitmapContainer(
271 : OUString("PresenterScreenSettings/ScrollBar/Bitmaps"),
272 : ::boost::shared_ptr<PresenterBitmapContainer>(),
273 : mxComponentContext,
274 0 : mxCanvas));
275 0 : mpSharedBitmaps = mpBitmaps;
276 : }
277 0 : catch(Exception&)
278 : {
279 : OSL_ASSERT(false);
280 : }
281 : }
282 : else
283 0 : mpBitmaps = ::boost::shared_ptr<PresenterBitmapContainer>(mpSharedBitmaps);
284 0 : UpdateBitmaps();
285 0 : UpdateBorders();
286 : }
287 :
288 0 : Repaint(GetRectangle(Total), false);
289 : }
290 : }
291 0 : }
292 :
293 0 : void PresenterScrollBar::SetBackground (const SharedBitmapDescriptor& rpBackgroundBitmap)
294 : {
295 0 : mpBackgroundBitmap = rpBackgroundBitmap;
296 0 : }
297 :
298 0 : void PresenterScrollBar::CheckValues (void)
299 : {
300 0 : mnThumbPosition = ValidateThumbPosition(mnThumbPosition);
301 0 : }
302 :
303 0 : double PresenterScrollBar::ValidateThumbPosition (double nPosition)
304 : {
305 0 : if (nPosition + mnThumbSize > mnTotalSize)
306 0 : nPosition = mnTotalSize - mnThumbSize;
307 0 : if (nPosition < 0)
308 0 : nPosition = 0;
309 0 : return nPosition;
310 : }
311 :
312 0 : void PresenterScrollBar::Paint (
313 : const awt::Rectangle& rUpdateBox,
314 : const bool bNoClip)
315 : {
316 0 : if ( ! mxCanvas.is() || ! mxWindow.is())
317 : {
318 : OSL_ASSERT(mxCanvas.is());
319 : OSL_ASSERT(mxWindow.is());
320 : return;
321 : }
322 :
323 0 : if ( ! bNoClip)
324 : {
325 0 : if (PresenterGeometryHelper::AreRectanglesDisjoint (rUpdateBox, mxWindow->getPosSize()))
326 : return;
327 : }
328 :
329 0 : PaintBackground(rUpdateBox);
330 : PaintComposite(rUpdateBox, PagerUp,
331 0 : mpPagerStartDescriptor, mpPagerCenterDescriptor, SharedBitmapDescriptor());
332 : PaintComposite(rUpdateBox, PagerDown,
333 0 : SharedBitmapDescriptor(), mpPagerCenterDescriptor, mpPagerEndDescriptor);
334 : PaintComposite(rUpdateBox, Thumb,
335 0 : mpThumbStartDescriptor, mpThumbCenterDescriptor, mpThumbEndDescriptor);
336 0 : PaintBitmap(rUpdateBox, PrevButton, mpPrevButtonDescriptor);
337 0 : PaintBitmap(rUpdateBox, NextButton, mpNextButtonDescriptor);
338 :
339 0 : Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxCanvas, UNO_QUERY);
340 0 : if (xSpriteCanvas.is())
341 0 : xSpriteCanvas->updateScreen(sal_False);
342 : }
343 :
344 : //----- XWindowListener -------------------------------------------------------
345 :
346 0 : void SAL_CALL PresenterScrollBar::windowResized (const css::awt::WindowEvent& rEvent)
347 : throw (css::uno::RuntimeException)
348 : {
349 : (void)rEvent;
350 0 : }
351 :
352 0 : void SAL_CALL PresenterScrollBar::windowMoved (const css::awt::WindowEvent& rEvent)
353 : throw (css::uno::RuntimeException)
354 : {
355 : (void)rEvent;
356 0 : }
357 :
358 0 : void SAL_CALL PresenterScrollBar::windowShown (const css::lang::EventObject& rEvent)
359 : throw (css::uno::RuntimeException)
360 : {
361 : (void)rEvent;
362 0 : }
363 :
364 0 : void SAL_CALL PresenterScrollBar::windowHidden (const css::lang::EventObject& rEvent)
365 : throw (css::uno::RuntimeException)
366 : {
367 : (void)rEvent;
368 0 : }
369 :
370 : //----- XPaintListener --------------------------------------------------------
371 :
372 0 : void SAL_CALL PresenterScrollBar::windowPaint (const css::awt::PaintEvent& rEvent)
373 : throw (css::uno::RuntimeException)
374 : {
375 0 : if (mxWindow.is())
376 : {
377 0 : awt::Rectangle aRepaintBox (rEvent.UpdateRect);
378 0 : const awt::Rectangle aWindowBox (mxWindow->getPosSize());
379 0 : aRepaintBox.X += aWindowBox.X;
380 0 : aRepaintBox.Y += aWindowBox.Y;
381 0 : Paint(aRepaintBox);
382 :
383 0 : Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxCanvas, UNO_QUERY);
384 0 : if (xSpriteCanvas.is())
385 0 : xSpriteCanvas->updateScreen(sal_False);
386 : }
387 0 : }
388 :
389 : //----- XMouseListener --------------------------------------------------------
390 :
391 0 : void SAL_CALL PresenterScrollBar::mousePressed (const css::awt::MouseEvent& rEvent)
392 : throw(css::uno::RuntimeException)
393 : {
394 0 : maDragAnchor.X = rEvent.X;
395 0 : maDragAnchor.Y = rEvent.Y;
396 0 : meButtonDownArea = GetArea(rEvent.X, rEvent.Y);
397 :
398 0 : mpMousePressRepeater->Start(meButtonDownArea);
399 0 : }
400 :
401 0 : void SAL_CALL PresenterScrollBar::mouseReleased (const css::awt::MouseEvent& rEvent)
402 : throw(css::uno::RuntimeException)
403 : {
404 : (void)rEvent;
405 :
406 0 : mpMousePressRepeater->Stop();
407 :
408 0 : if (mxPresenterHelper.is())
409 0 : mxPresenterHelper->releaseMouse(mxWindow);
410 0 : }
411 :
412 0 : void SAL_CALL PresenterScrollBar::mouseEntered (const css::awt::MouseEvent& rEvent)
413 : throw(css::uno::RuntimeException)
414 : {
415 : (void)rEvent;
416 0 : }
417 :
418 0 : void SAL_CALL PresenterScrollBar::mouseExited (const css::awt::MouseEvent& rEvent)
419 : throw(css::uno::RuntimeException)
420 : {
421 : (void)rEvent;
422 0 : if (meMouseMoveArea != None)
423 : {
424 0 : const Area eOldMouseMoveArea (meMouseMoveArea);
425 0 : meMouseMoveArea = None;
426 0 : Repaint(GetRectangle(eOldMouseMoveArea), true);
427 : }
428 0 : meButtonDownArea = None;
429 0 : meMouseMoveArea = None;
430 :
431 0 : mpMousePressRepeater->Stop();
432 0 : }
433 :
434 : //----- XMouseMotionListener --------------------------------------------------
435 :
436 0 : void SAL_CALL PresenterScrollBar::mouseMoved (const css::awt::MouseEvent& rEvent)
437 : throw (css::uno::RuntimeException)
438 : {
439 0 : const Area eArea (GetArea(rEvent.X, rEvent.Y));
440 0 : if (eArea != meMouseMoveArea)
441 : {
442 0 : const Area eOldMouseMoveArea (meMouseMoveArea);
443 0 : meMouseMoveArea = eArea;
444 0 : if (eOldMouseMoveArea != None)
445 0 : Repaint(GetRectangle(eOldMouseMoveArea), meMouseMoveArea==None);
446 0 : if (meMouseMoveArea != None)
447 0 : Repaint(GetRectangle(meMouseMoveArea), true);
448 : }
449 0 : mpMousePressRepeater->SetMouseArea(eArea);
450 0 : }
451 :
452 0 : void SAL_CALL PresenterScrollBar::mouseDragged (const css::awt::MouseEvent& rEvent)
453 : throw (css::uno::RuntimeException)
454 : {
455 0 : if (meButtonDownArea != Thumb)
456 0 : return;
457 :
458 0 : mpMousePressRepeater->Stop();
459 :
460 0 : if (mxPresenterHelper.is())
461 0 : mxPresenterHelper->captureMouse(mxWindow);
462 :
463 0 : const double nDragDistance (GetDragDistance(rEvent.X,rEvent.Y));
464 0 : UpdateDragAnchor(nDragDistance);
465 0 : if (nDragDistance != 0)
466 : {
467 0 : SetThumbPosition(mnThumbPosition + nDragDistance, false, true, true);
468 : }
469 : }
470 :
471 : //----- lang::XEventListener --------------------------------------------------
472 :
473 0 : void SAL_CALL PresenterScrollBar::disposing (const css::lang::EventObject& rEvent)
474 : throw (css::uno::RuntimeException)
475 : {
476 0 : if (rEvent.Source == mxWindow)
477 0 : mxWindow = NULL;
478 0 : }
479 :
480 : //-----------------------------------------------------------------------------
481 :
482 0 : geometry::RealRectangle2D PresenterScrollBar::GetRectangle (const Area eArea) const
483 : {
484 : OSL_ASSERT(eArea>=0 && eArea<__AreaCount__);
485 :
486 0 : return maBox[eArea];
487 : }
488 :
489 0 : void PresenterScrollBar::Repaint (
490 : const geometry::RealRectangle2D aBox,
491 : const bool bAsynchronousUpdate)
492 : {
493 0 : if (mpPaintManager.get() != NULL)
494 : mpPaintManager->Invalidate(
495 : mxWindow,
496 : PresenterGeometryHelper::ConvertRectangle(aBox),
497 0 : bAsynchronousUpdate);
498 0 : }
499 :
500 0 : void PresenterScrollBar::PaintBackground(
501 : const css::awt::Rectangle& rUpdateBox)
502 : {
503 0 : if (mpBackgroundBitmap.get() == NULL)
504 0 : return;
505 :
506 0 : const awt::Rectangle aWindowBox (mxWindow->getPosSize());
507 : mpCanvasHelper->Paint(
508 : mpBackgroundBitmap,
509 : mxCanvas,
510 : rUpdateBox,
511 : aWindowBox,
512 0 : awt::Rectangle());
513 : }
514 :
515 0 : void PresenterScrollBar::PaintBitmap(
516 : const css::awt::Rectangle& rUpdateBox,
517 : const Area eArea,
518 : const SharedBitmapDescriptor& rpBitmaps)
519 : {
520 0 : const geometry::RealRectangle2D aLocalBox (GetRectangle(eArea));
521 0 : const awt::Rectangle aWindowBox (mxWindow->getPosSize());
522 0 : geometry::RealRectangle2D aBox (aLocalBox);
523 0 : aBox.X1 += aWindowBox.X;
524 0 : aBox.Y1 += aWindowBox.Y;
525 0 : aBox.X2 += aWindowBox.X;
526 0 : aBox.Y2 += aWindowBox.Y;
527 :
528 0 : Reference<rendering::XBitmap> xBitmap (GetBitmap(eArea,rpBitmaps));
529 :
530 0 : if (xBitmap.is())
531 : {
532 : Reference<rendering::XPolyPolygon2D> xClipPolygon (
533 : PresenterGeometryHelper::CreatePolygon(
534 : PresenterGeometryHelper::Intersection(rUpdateBox,
535 0 : PresenterGeometryHelper::ConvertRectangle(aBox)),
536 0 : mxCanvas->getDevice()));
537 :
538 : const rendering::ViewState aViewState (
539 : geometry::AffineMatrix2D(1,0,0, 0,1,0),
540 0 : xClipPolygon);
541 :
542 0 : const geometry::IntegerSize2D aBitmapSize (xBitmap->getSize());
543 : rendering::RenderState aRenderState (
544 : geometry::AffineMatrix2D(
545 : 1,0,aBox.X1 + (aBox.X2-aBox.X1 - aBitmapSize.Width)/2,
546 : 0,1,aBox.Y1 + (aBox.Y2-aBox.Y1 - aBitmapSize.Height)/2),
547 : NULL,
548 : Sequence<double>(4),
549 0 : rendering::CompositeOperation::SOURCE);
550 :
551 0 : mxCanvas->drawBitmap(
552 : xBitmap,
553 : aViewState,
554 0 : aRenderState);
555 0 : }
556 0 : }
557 :
558 0 : void PresenterScrollBar::NotifyThumbPositionChange (void)
559 : {
560 0 : if ( ! mbIsNotificationActive)
561 : {
562 0 : mbIsNotificationActive = true;
563 :
564 : try
565 : {
566 0 : maThumbMotionListener(mnThumbPosition);
567 : }
568 0 : catch (Exception&)
569 : {
570 : }
571 :
572 0 : mbIsNotificationActive = false;
573 : }
574 0 : }
575 :
576 0 : PresenterScrollBar::Area PresenterScrollBar::GetArea (const double nX, const double nY) const
577 : {
578 0 : const geometry::RealPoint2D aPoint(nX, nY);
579 :
580 0 : if (PresenterGeometryHelper::IsInside(GetRectangle(Pager), aPoint))
581 : {
582 0 : if (PresenterGeometryHelper::IsInside(GetRectangle(Thumb), aPoint))
583 0 : return Thumb;
584 0 : else if (PresenterGeometryHelper::IsInside(GetRectangle(PagerUp), aPoint))
585 0 : return PagerUp;
586 0 : else if (PresenterGeometryHelper::IsInside(GetRectangle(PagerDown), aPoint))
587 0 : return PagerDown;
588 : }
589 0 : else if (PresenterGeometryHelper::IsInside(GetRectangle(PrevButton), aPoint))
590 0 : return PrevButton;
591 0 : else if (PresenterGeometryHelper::IsInside(GetRectangle(NextButton), aPoint))
592 0 : return NextButton;
593 :
594 0 : return None;
595 : }
596 :
597 0 : void PresenterScrollBar::UpdateWidthOrHeight (
598 : sal_Int32& rSize,
599 : const SharedBitmapDescriptor& rpDescriptor)
600 : {
601 0 : if (rpDescriptor.get() != NULL)
602 : {
603 0 : Reference<rendering::XBitmap> xBitmap (rpDescriptor->GetNormalBitmap());
604 0 : if (xBitmap.is())
605 : {
606 0 : const geometry::IntegerSize2D aBitmapSize (xBitmap->getSize());
607 0 : const sal_Int32 nBitmapSize = (sal_Int32)GetMinor(aBitmapSize.Width, aBitmapSize.Height);
608 0 : if (nBitmapSize > rSize)
609 0 : rSize = nBitmapSize;
610 0 : }
611 : }
612 0 : }
613 :
614 0 : css::uno::Reference<css::rendering::XBitmap> PresenterScrollBar::GetBitmap (
615 : const Area eArea,
616 : const SharedBitmapDescriptor& rpBitmaps) const
617 : {
618 0 : if (rpBitmaps.get() == NULL)
619 0 : return NULL;
620 : else
621 0 : return rpBitmaps->GetBitmap(GetBitmapMode(eArea));
622 : }
623 :
624 0 : PresenterBitmapContainer::BitmapDescriptor::Mode PresenterScrollBar::GetBitmapMode (
625 : const Area eArea) const
626 : {
627 0 : if (IsDisabled(eArea))
628 0 : return PresenterBitmapContainer::BitmapDescriptor::Disabled;
629 0 : else if (eArea == meMouseMoveArea)
630 0 : return PresenterBitmapContainer::BitmapDescriptor::MouseOver;
631 : else
632 0 : return PresenterBitmapContainer::BitmapDescriptor::Normal;
633 : }
634 :
635 0 : bool PresenterScrollBar::IsDisabled (const Area eArea) const
636 : {
637 : OSL_ASSERT(eArea>=0 && eArea<__AreaCount__);
638 :
639 0 : return ! maEnabledState[eArea];
640 : }
641 :
642 : //===== PresenterVerticalScrollBar ============================================
643 :
644 0 : PresenterVerticalScrollBar::PresenterVerticalScrollBar (
645 : const Reference<XComponentContext>& rxComponentContext,
646 : const Reference<awt::XWindow>& rxParentWindow,
647 : const ::boost::shared_ptr<PresenterPaintManager>& rpPaintManager,
648 : const ::boost::function<void(double)>& rThumbMotionListener)
649 : : PresenterScrollBar(rxComponentContext, rxParentWindow, rpPaintManager, rThumbMotionListener),
650 0 : mnScrollBarWidth(0)
651 : {
652 0 : }
653 :
654 0 : PresenterVerticalScrollBar::~PresenterVerticalScrollBar (void)
655 : {
656 0 : }
657 :
658 0 : double PresenterVerticalScrollBar::GetDragDistance (const sal_Int32 nX, const sal_Int32 nY) const
659 : {
660 : (void)nX;
661 0 : const double nDistance (nY - maDragAnchor.Y);
662 0 : if (nDistance == 0)
663 0 : return 0;
664 : else
665 : {
666 0 : const awt::Rectangle aWindowBox (mxWindow->getPosSize());
667 0 : const double nBarWidth (aWindowBox.Width);
668 0 : const double nPagerHeight (aWindowBox.Height - 2*nBarWidth);
669 0 : const double nDragDistance (mnTotalSize / nPagerHeight * nDistance);
670 0 : if (nDragDistance + mnThumbPosition < 0)
671 0 : return -mnThumbPosition;
672 0 : else if (mnThumbPosition + nDragDistance > mnTotalSize-mnThumbSize)
673 0 : return mnTotalSize-mnThumbSize-mnThumbPosition;
674 : else
675 0 : return nDragDistance;
676 : }
677 : }
678 :
679 0 : void PresenterVerticalScrollBar::UpdateDragAnchor (const double nDragDistance)
680 : {
681 0 : const awt::Rectangle aWindowBox (mxWindow->getPosSize());
682 0 : const double nBarWidth (aWindowBox.Width);
683 0 : const double nPagerHeight (aWindowBox.Height - 2*nBarWidth);
684 0 : maDragAnchor.Y += nDragDistance * nPagerHeight / mnTotalSize;
685 0 : }
686 :
687 0 : sal_Int32 PresenterVerticalScrollBar::GetSize (void) const
688 : {
689 0 : return mnScrollBarWidth;
690 : }
691 :
692 0 : geometry::RealPoint2D PresenterVerticalScrollBar::GetPoint (
693 : const double nMajor, const double nMinor) const
694 : {
695 0 : return geometry::RealPoint2D(nMinor, nMajor);
696 : }
697 :
698 0 : double PresenterVerticalScrollBar::GetMajor (const double nX, const double nY) const
699 : {
700 : (void)nX;
701 0 : return nY;
702 : }
703 :
704 0 : double PresenterVerticalScrollBar::GetMinor (const double nX, const double nY) const
705 : {
706 : (void)nY;
707 0 : return nX;
708 : }
709 :
710 0 : void PresenterVerticalScrollBar::UpdateBorders (void)
711 : {
712 0 : const awt::Rectangle aWindowBox (mxWindow->getPosSize());
713 0 : double nBottom = aWindowBox.Height;
714 :
715 0 : if (mpNextButtonDescriptor.get() != NULL)
716 : {
717 0 : Reference<rendering::XBitmap> xBitmap (mpNextButtonDescriptor->GetNormalBitmap());
718 0 : if (xBitmap.is())
719 : {
720 0 : geometry::IntegerSize2D aSize (xBitmap->getSize());
721 : maBox[NextButton] = geometry::RealRectangle2D(
722 0 : 0, nBottom - aSize.Height, aWindowBox.Width, nBottom);
723 0 : nBottom -= aSize.Height + gnScrollBarGap;
724 0 : }
725 : }
726 0 : if (mpPrevButtonDescriptor.get() != NULL)
727 : {
728 0 : Reference<rendering::XBitmap> xBitmap (mpPrevButtonDescriptor->GetNormalBitmap());
729 0 : if (xBitmap.is())
730 : {
731 0 : geometry::IntegerSize2D aSize (xBitmap->getSize());
732 : maBox[PrevButton] = geometry::RealRectangle2D(
733 0 : 0, nBottom - aSize.Height, aWindowBox.Width, nBottom);
734 0 : nBottom -= aSize.Height + gnScrollBarGap;
735 0 : }
736 : }
737 0 : const double nPagerHeight (nBottom);
738 : maBox[Pager] = geometry::RealRectangle2D(
739 0 : 0,0, aWindowBox.Width, nBottom);
740 0 : if (mnTotalSize < 1)
741 : {
742 0 : maBox[Thumb] = maBox[Pager];
743 :
744 : // Set up the enabled/disabled states.
745 0 : maEnabledState[PrevButton] = false;
746 0 : maEnabledState[PagerUp] = false;
747 0 : maEnabledState[NextButton] = false;
748 0 : maEnabledState[PagerDown] = false;
749 0 : maEnabledState[Thumb] = false;
750 : }
751 : else
752 : {
753 0 : const double nThumbSize = ::std::min(mnThumbSize,mnTotalSize);
754 0 : const double nThumbPosition = ::std::min(::std::max(0.0,mnThumbPosition), mnTotalSize - nThumbSize);
755 : maBox[Thumb] = geometry::RealRectangle2D(
756 : 0, nThumbPosition / mnTotalSize * nPagerHeight,
757 : aWindowBox.Width,
758 0 : (nThumbPosition+nThumbSize) / mnTotalSize * nPagerHeight);
759 :
760 : // Set up the enabled/disabled states.
761 0 : maEnabledState[PrevButton] = nThumbPosition>0;
762 0 : maEnabledState[PagerUp] = nThumbPosition>0;
763 0 : maEnabledState[NextButton] = nThumbPosition+nThumbSize < mnTotalSize;
764 0 : maEnabledState[PagerDown] = nThumbPosition+nThumbSize < mnTotalSize;
765 0 : maEnabledState[Thumb] = nThumbSize < mnTotalSize;
766 : }
767 : maBox[PagerUp] = geometry::RealRectangle2D(
768 0 : maBox[Pager].X1, maBox[Pager].Y1, maBox[Pager].X2, maBox[Thumb].Y1-1);
769 : maBox[PagerDown] = geometry::RealRectangle2D(
770 0 : maBox[Pager].X1, maBox[Thumb].Y2+1, maBox[Pager].X2, maBox[Pager].Y2);
771 : maBox[Total] = PresenterGeometryHelper::Union(
772 0 : PresenterGeometryHelper::Union(maBox[PrevButton], maBox[NextButton]),
773 0 : maBox[Pager]);
774 0 : }
775 :
776 0 : void PresenterVerticalScrollBar::UpdateBitmaps (void)
777 : {
778 0 : if (mpBitmaps.get() != NULL)
779 : {
780 0 : mpPrevButtonDescriptor = mpBitmaps->GetBitmap(A2S("Up"));
781 0 : mpNextButtonDescriptor = mpBitmaps->GetBitmap(A2S("Down"));
782 0 : mpPagerStartDescriptor = mpBitmaps->GetBitmap(A2S("PagerTop"));
783 0 : mpPagerCenterDescriptor = mpBitmaps->GetBitmap(A2S("PagerVertical"));
784 0 : mpPagerEndDescriptor = mpBitmaps->GetBitmap(A2S("PagerBottom"));
785 0 : mpThumbStartDescriptor = mpBitmaps->GetBitmap(A2S("ThumbTop"));
786 0 : mpThumbCenterDescriptor = mpBitmaps->GetBitmap(A2S("ThumbVertical"));
787 0 : mpThumbEndDescriptor = mpBitmaps->GetBitmap(A2S("ThumbBottom"));
788 :
789 0 : mnScrollBarWidth = 0;
790 0 : UpdateWidthOrHeight(mnScrollBarWidth, mpPrevButtonDescriptor);
791 0 : UpdateWidthOrHeight(mnScrollBarWidth, mpNextButtonDescriptor);
792 0 : UpdateWidthOrHeight(mnScrollBarWidth, mpPagerStartDescriptor);
793 0 : UpdateWidthOrHeight(mnScrollBarWidth, mpPagerCenterDescriptor);
794 0 : UpdateWidthOrHeight(mnScrollBarWidth, mpPagerEndDescriptor);
795 0 : UpdateWidthOrHeight(mnScrollBarWidth, mpThumbStartDescriptor);
796 0 : UpdateWidthOrHeight(mnScrollBarWidth, mpThumbCenterDescriptor);
797 0 : UpdateWidthOrHeight(mnScrollBarWidth, mpThumbEndDescriptor);
798 0 : if (mnScrollBarWidth == 0)
799 0 : mnScrollBarWidth = 20;
800 : }
801 0 : }
802 :
803 0 : void PresenterVerticalScrollBar::PaintComposite(
804 : const css::awt::Rectangle& rUpdateBox,
805 : const Area eArea,
806 : const SharedBitmapDescriptor& rpStartBitmaps,
807 : const SharedBitmapDescriptor& rpCenterBitmaps,
808 : const SharedBitmapDescriptor& rpEndBitmaps)
809 : {
810 0 : const awt::Rectangle aWindowBox (mxWindow->getPosSize());
811 0 : geometry::RealRectangle2D aBox (GetRectangle(eArea));
812 0 : aBox.X1 += aWindowBox.X;
813 0 : aBox.Y1 += aWindowBox.Y;
814 0 : aBox.X2 += aWindowBox.X;
815 0 : aBox.Y2 += aWindowBox.Y;
816 :
817 : // Get bitmaps and sizes.
818 :
819 : PresenterUIPainter::PaintVerticalBitmapComposite(
820 : mxCanvas,
821 : rUpdateBox,
822 : (eArea == Thumb
823 : ? PresenterGeometryHelper::ConvertRectangleWithConstantSize(aBox)
824 : : PresenterGeometryHelper::ConvertRectangle(aBox)),
825 : GetBitmap(eArea, rpStartBitmaps),
826 : GetBitmap(eArea, rpCenterBitmaps),
827 0 : GetBitmap(eArea, rpEndBitmaps));
828 0 : }
829 :
830 : //===== PresenterScrollBar::MousePressRepeater ================================
831 :
832 0 : PresenterScrollBar::MousePressRepeater::MousePressRepeater (
833 : const ::rtl::Reference<PresenterScrollBar>& rpScrollBar)
834 : : mnMousePressRepeaterTaskId(PresenterTimer::NotAValidTaskId),
835 : mpScrollBar(rpScrollBar),
836 0 : meMouseArea(PresenterScrollBar::None)
837 : {
838 0 : }
839 :
840 0 : void PresenterScrollBar::MousePressRepeater::Dispose (void)
841 : {
842 0 : Stop();
843 0 : mpScrollBar = NULL;
844 0 : }
845 :
846 0 : void PresenterScrollBar::MousePressRepeater::Start (const PresenterScrollBar::Area& reArea)
847 : {
848 0 : meMouseArea = reArea;
849 :
850 0 : if (mnMousePressRepeaterTaskId == PresenterTimer::NotAValidTaskId)
851 : {
852 : // Execute key press operation at least this one time.
853 0 : Execute();
854 :
855 : // Schedule repeated executions.
856 : mnMousePressRepeaterTaskId = PresenterTimer::ScheduleRepeatedTask (
857 : ::boost::bind(&PresenterScrollBar::MousePressRepeater::Callback, shared_from_this(), _1),
858 : 500000000,
859 0 : 250000000);
860 : }
861 : else
862 : {
863 : // There is already an active repeating task.
864 : }
865 0 : }
866 :
867 0 : void PresenterScrollBar::MousePressRepeater::Stop (void)
868 : {
869 0 : if (mnMousePressRepeaterTaskId != PresenterTimer::NotAValidTaskId)
870 : {
871 0 : const sal_Int32 nTaskId (mnMousePressRepeaterTaskId);
872 0 : mnMousePressRepeaterTaskId = PresenterTimer::NotAValidTaskId;
873 0 : PresenterTimer::CancelTask(nTaskId);
874 : }
875 0 : }
876 :
877 0 : void PresenterScrollBar::MousePressRepeater::SetMouseArea(const PresenterScrollBar::Area& reArea)
878 : {
879 0 : if (meMouseArea != reArea)
880 : {
881 0 : if (mnMousePressRepeaterTaskId != PresenterTimer::NotAValidTaskId)
882 : {
883 0 : Stop();
884 : }
885 : }
886 0 : }
887 :
888 0 : void PresenterScrollBar::MousePressRepeater::Callback (const TimeValue& rCurrentTime)
889 : {
890 : (void)rCurrentTime;
891 :
892 0 : if (mpScrollBar.get() == NULL)
893 : {
894 0 : Stop();
895 0 : return;
896 : }
897 :
898 0 : Execute();
899 : }
900 :
901 0 : void PresenterScrollBar::MousePressRepeater::Execute (void)
902 : {
903 0 : const double nThumbPosition (mpScrollBar->GetThumbPosition());
904 0 : switch (meMouseArea)
905 : {
906 : case PrevButton:
907 0 : mpScrollBar->SetThumbPosition(nThumbPosition - mpScrollBar->GetLineHeight(), true);
908 0 : break;
909 :
910 : case NextButton:
911 0 : mpScrollBar->SetThumbPosition(nThumbPosition + mpScrollBar->GetLineHeight(), true);
912 0 : break;
913 :
914 : case PagerUp:
915 0 : mpScrollBar->SetThumbPosition(nThumbPosition - mpScrollBar->GetThumbSize()*0.8, true);
916 0 : break;
917 :
918 : case PagerDown:
919 0 : mpScrollBar->SetThumbPosition(nThumbPosition + mpScrollBar->GetThumbSize()*0.8, true);
920 0 : break;
921 :
922 : default:
923 0 : break;
924 : }
925 0 : }
926 :
927 0 : } } // end of namespace ::sdext::presenter
928 :
929 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|