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