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