Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #include "taskpane/ScrollPanel.hxx"
31 : :
32 : : #include "taskpane/ControlContainer.hxx"
33 : : #include "TaskPaneFocusManager.hxx"
34 : : #include "taskpane/TitledControl.hxx"
35 : : #include "AccessibleScrollPanel.hxx"
36 : :
37 : : #include <vcl/svapp.hxx>
38 : : #include <svtools/valueset.hxx>
39 : :
40 : : namespace sd { namespace toolpanel {
41 : :
42 : 15 : ScrollPanel::ScrollPanel (
43 : : ::Window& i_rParentWindow)
44 : : : Control (&i_rParentWindow, WB_DIALOGCONTROL),
45 : : TreeNode(NULL),
46 : : maScrollWindow(this, WB_DIALOGCONTROL),
47 : : maVerticalScrollBar(this, WB_VERT),
48 : : maHorizontalScrollBar(this, WB_HORZ),
49 : : maScrollBarFiller(this),
50 : : maScrollWindowFiller(&maScrollWindow),
51 : : mbIsRearrangePending(true),
52 : : mbIsLayoutPending(true),
53 : : mnChildrenWidth(0),
54 : : mnVerticalBorder(2),
55 : : mnVerticalGap(3),
56 [ + - ][ + - ]: 15 : mnHorizontalBorder(2)
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
57 : : {
58 [ + - ]: 15 : Construct();
59 : 15 : }
60 : :
61 : 15 : void ScrollPanel::Construct()
62 : : {
63 [ + - ][ + - ]: 15 : SetAccessibleName (::rtl::OUString("Sub Task Panel"));
[ + - ]
64 : 15 : mpControlContainer->SetMultiSelection (true);
65 : :
66 : 15 : SetBorderStyle (WINDOW_BORDER_NORMAL);
67 [ + - ]: 15 : SetMapMode (MapMode(MAP_PIXEL));
68 : :
69 : : // To reduce flickering during repaints make the container windows
70 : : // transparent and rely on their children to paint the whole area.
71 [ + - ]: 15 : SetBackground(Wallpaper());
72 [ + - ]: 15 : maScrollWindow.SetBackground(Wallpaper());
73 : : maScrollWindowFiller.SetBackground(
74 [ + - ]: 15 : Application::GetSettings().GetStyleSettings().GetWindowColor());
75 : :
76 : 15 : maScrollWindow.Show();
77 : :
78 : : // Initialize the scroll bars.
79 : : maVerticalScrollBar.SetScrollHdl (
80 : 15 : LINK(this, ScrollPanel, ScrollBarHandler));
81 : 15 : maVerticalScrollBar.EnableDrag (sal_True);
82 : : maHorizontalScrollBar.SetScrollHdl (
83 : 15 : LINK(this, ScrollPanel, ScrollBarHandler));
84 : 15 : maHorizontalScrollBar.EnableDrag (sal_True);
85 : 15 : }
86 : :
87 : :
88 : :
89 : :
90 [ + - ][ + - ]: 15 : ScrollPanel::~ScrollPanel (void)
[ + - ][ + - ]
[ + - ][ + - ]
91 : : {
92 [ + - ]: 15 : sal_uInt32 nCount = mpControlContainer->GetControlCount();
93 [ + + ]: 30 : for (sal_uInt32 nIndex=0; nIndex<nCount; nIndex++)
94 : : {
95 [ + - ]: 15 : TreeNode* pNode = mpControlContainer->GetControl(nIndex);
96 : 15 : TreeNode* pControl = pNode;
97 : : // When the node has been created as TitledControl then use its
98 : : // control instead of pNode directly.
99 [ - + ]: 15 : TitledControl* pTitledControl = dynamic_cast<TitledControl*>(pNode);
100 [ - + ]: 15 : if (pTitledControl != NULL)
101 [ # # ]: 0 : pControl = pTitledControl->GetControl();
102 : :
103 : : // Remove this object as listener from the control.
104 [ + - ][ + - ]: 15 : if (pControl != NULL && pControl->GetWindow()!=NULL)
[ + - ][ + - ]
105 : : {
106 : 15 : pControl->GetWindow()->RemoveEventListener(
107 [ + - ][ + - ]: 15 : LINK(this,ScrollPanel,WindowEventListener));
[ + - ]
108 : : }
109 : : }
110 [ + - ]: 15 : mpControlContainer->DeleteChildren();
111 [ - + ]: 30 : }
112 : :
113 : :
114 : :
115 : : SAL_WNODEPRECATED_DECLARATIONS_PUSH
116 : 0 : TitledControl* ScrollPanel::AddControl (
117 : : ::std::auto_ptr<TreeNode> pControl,
118 : : const String& rTitle,
119 : : const rtl::OString& rHelpId)
120 : : {
121 : : // We are interested only in the title. The control itself is
122 : : // managed by the content object.
123 : : TitledControl* pTitledControl = new TitledControl(
124 : : this,
125 : : pControl,
126 : : rTitle,
127 [ # # ]: 0 : TitledControlStandardClickHandler(GetControlContainer(), ControlContainer::ES_TOGGLE),
128 [ # # ][ # # ]: 0 : TitleBar::TBT_SUB_CONTROL_HEADLINE);
[ # # ][ # # ]
[ # # ]
129 : 0 : pTitledControl->GetTitleBar()->SetHelpId(rHelpId);
130 : :
131 [ # # ][ # # ]: 0 : AddControl(::std::auto_ptr<TreeNode>(pTitledControl));
[ # # ]
132 : :
133 : 0 : return pTitledControl;
134 : : }
135 : : SAL_WNODEPRECATED_DECLARATIONS_POP
136 : :
137 : :
138 : : SAL_WNODEPRECATED_DECLARATIONS_PUSH
139 : 15 : void ScrollPanel::AddControl (::std::auto_ptr<TreeNode> pControl)
140 : : {
141 [ + - ]: 15 : if (pControl.get() != NULL)
142 : : {
143 : : // Add a window event listener which does two things:
144 : : // 1. Listen for controls being shown or hidden so that the layout
145 : : // can be adapted.
146 : : // 2. Track selection changes in order to make the selected elements
147 : : // visible.
148 [ + - ]: 15 : const Link aWindowListener(LINK(this,ScrollPanel,WindowEventListener));
149 : : OSL_ASSERT(pControl->GetWindow()!=NULL);
150 [ + - ][ + - ]: 15 : pControl->GetWindow()->AddEventListener(aWindowListener);
151 : :
152 [ - + ]: 15 : TitledControl* pTitledControl = dynamic_cast<TitledControl*>(pControl.get());
153 [ - + ]: 15 : if (pTitledControl != NULL)
154 : : {
155 : : OSL_ASSERT(pTitledControl->GetControl()!=NULL);
156 : : OSL_ASSERT(pTitledControl->GetControl()->GetWindow()!=NULL);
157 [ # # ][ # # ]: 0 : pTitledControl->GetControl()->GetWindow()->AddEventListener(aWindowListener);
[ # # ]
158 : : }
159 : :
160 [ + - ]: 15 : FocusManager& rFocusManager (FocusManager::Instance());
161 [ + - ]: 15 : int nControlCount (mpControlContainer->GetControlCount());
162 : : // Replace the old links for cycling between first and last child by
163 : : // current ones.
164 [ - + ]: 15 : if (nControlCount > 0)
165 : : {
166 [ # # ][ # # ]: 0 : ::Window* pFirst = mpControlContainer->GetControl(0)->GetWindow();
167 [ # # ][ # # ]: 0 : ::Window* pLast = mpControlContainer->GetControl(nControlCount-1)->GetWindow();
168 [ # # ]: 0 : rFocusManager.RemoveLinks(pFirst,pLast);
169 [ # # ]: 0 : rFocusManager.RemoveLinks(pLast,pFirst);
170 : :
171 [ # # ][ # # ]: 0 : rFocusManager.RegisterLink(pFirst,pControl->GetWindow(), KEY_UP);
172 [ # # ][ # # ]: 0 : rFocusManager.RegisterLink(pControl->GetWindow(),pFirst, KEY_DOWN);
173 : : }
174 : :
175 : :
176 : : // Add a down link only for the first control so that when entering
177 : : // the sub tool panel the focus is set to the first control.
178 [ + - ]: 15 : if (nControlCount == 0)
179 [ + - ][ + - ]: 15 : rFocusManager.RegisterDownLink(GetParent(), pControl->GetWindow());
[ + - ]
180 [ + - ][ + - ]: 15 : rFocusManager.RegisterUpLink(pControl->GetWindow(), GetParent());
[ + - ]
181 : :
182 [ + - ][ + - ]: 15 : pControl->GetWindow()->SetParent(&maScrollWindow);
183 [ + - ][ + - ]: 15 : mpControlContainer->AddControl (pControl);
184 : 15 : mpControlContainer->SetExpansionState(
185 [ + - ]: 15 : mpControlContainer->GetControlCount()-1,
186 [ + - ]: 15 : ControlContainer::ES_EXPAND);
187 : : }
188 : 15 : }
189 : : SAL_WNODEPRECATED_DECLARATIONS_POP
190 : :
191 : :
192 : :
193 : 36 : void ScrollPanel::Paint (const Rectangle& rRect)
194 : : {
195 [ + + ]: 36 : if (mbIsRearrangePending)
196 [ + - ]: 23 : Rearrange();
197 [ - + ]: 36 : if (mbIsLayoutPending)
198 [ # # ]: 0 : LayoutChildren();
199 [ + - ]: 36 : ::Window::Paint (rRect);
200 : :
201 : : // Paint the outer border and the space between every two children.
202 : 36 : Color aOriginalLineColor (maScrollWindow.GetLineColor());
203 : 36 : Color aOriginalFillColor (maScrollWindow.GetFillColor());
204 : :
205 [ + - ]: 36 : maScrollWindow.SetLineColor ();
206 : : maScrollWindow.SetFillColor (
207 [ + - ]: 36 : GetSettings().GetStyleSettings().GetWindowColor());
208 : :
209 : 36 : Size aSize (maScrollWindow.GetOutputSizePixel());
210 : : // Paint left and right vertical border.
211 : : Rectangle aVerticalArea (
212 : : Point(0,0),
213 [ + - ]: 36 : Size(mnHorizontalBorder,aSize.Height()));
214 [ + - ]: 36 : maScrollWindow.DrawRect (aVerticalArea);
215 : 36 : aVerticalArea.Right() += mnHorizontalBorder + mnChildrenWidth - 1;
216 : 36 : aVerticalArea.Left() = aVerticalArea.Right() + mnHorizontalBorder;
217 [ + - ]: 36 : maScrollWindow.DrawRect (aVerticalArea);
218 : :
219 : : // Paint horizontal stripes.
220 : : Rectangle aStripeArea (
221 : : Point (mnHorizontalBorder,0),
222 [ + - ]: 36 : Size(mnChildrenWidth,0));
223 : 36 : StripeList::const_iterator iStripe;
224 [ + - ][ + - ]: 74 : for (iStripe=maStripeList.begin(); iStripe!=maStripeList.end(); ++iStripe)
[ + - ][ + + ]
225 : : {
226 [ + - ]: 38 : aStripeArea.Top() = iStripe->first;
227 [ + - ]: 38 : aStripeArea.Bottom() = iStripe->second;
228 [ - + ]: 38 : if (aStripeArea.Bottom() < 0)
229 : 0 : continue;
230 [ - + ]: 38 : if (aStripeArea.Top() >= aSize.Height())
231 : 0 : break;
232 [ + - ]: 38 : maScrollWindow.DrawRect (aStripeArea);
233 : : }
234 : :
235 [ + - ]: 36 : maScrollWindow.SetLineColor (aOriginalLineColor);
236 [ + - ]: 36 : maScrollWindow.SetFillColor (aOriginalFillColor);
237 : 36 : }
238 : :
239 : :
240 : :
241 : :
242 : 34 : void ScrollPanel::Resize (void)
243 : : {
244 : 34 : ::Window::Resize();
245 : 34 : mbIsRearrangePending = true;
246 : 34 : mbIsLayoutPending = true;
247 : 34 : }
248 : :
249 : :
250 : :
251 : :
252 : 125 : void ScrollPanel::RequestResize (void)
253 : : {
254 : 125 : mbIsRearrangePending = true;
255 : 125 : mbIsLayoutPending = true;
256 : 125 : Invalidate();
257 : 125 : }
258 : :
259 : :
260 : :
261 : :
262 : 0 : Size ScrollPanel::GetPreferredSize (void)
263 : : {
264 : 0 : return GetRequiredSize();
265 : : }
266 : :
267 : :
268 : :
269 : :
270 : 0 : sal_Int32 ScrollPanel::GetPreferredWidth (sal_Int32 )
271 : : {
272 : 0 : return GetPreferredSize().Width();
273 : : }
274 : :
275 : :
276 : :
277 : :
278 : 0 : sal_Int32 ScrollPanel::GetPreferredHeight (sal_Int32 )
279 : : {
280 : 0 : return GetPreferredSize().Height();
281 : : }
282 : :
283 : :
284 : :
285 : :
286 : 0 : bool ScrollPanel::IsResizable (void)
287 : : {
288 : 0 : return true;
289 : : }
290 : :
291 : :
292 : :
293 : :
294 : 60 : ::Window* ScrollPanel::GetWindow (void)
295 : : {
296 : 60 : return this;
297 : : }
298 : :
299 : :
300 : :
301 : :
302 : 21 : sal_Int32 ScrollPanel::GetMinimumWidth (void)
303 : : {
304 : 21 : return TreeNode::GetMinimumWidth();
305 : : }
306 : :
307 : :
308 : :
309 : :
310 : 0 : void ScrollPanel::ExpandControl (
311 : : TreeNode* pControl,
312 : : bool bExpansionState)
313 : : {
314 : : // Toggle expand status.
315 : 0 : pControl->Expand (bExpansionState);
316 : :
317 : 0 : Rearrange ();
318 : 0 : Invalidate ();
319 : 0 : }
320 : :
321 : :
322 : :
323 : :
324 : 0 : bool ScrollPanel::IsVerticalScrollBarVisible (void) const
325 : : {
326 : 0 : return maVerticalScrollBar.IsReallyVisible();
327 : : }
328 : :
329 : :
330 : :
331 : :
332 : 0 : bool ScrollPanel::IsHorizontalScrollBarVisible (void) const
333 : : {
334 : 0 : return maHorizontalScrollBar.IsReallyVisible();
335 : : }
336 : :
337 : :
338 : :
339 : :
340 : 0 : ScrollBar& ScrollPanel::GetVerticalScrollBar (void)
341 : : {
342 : 0 : return maVerticalScrollBar;
343 : : }
344 : :
345 : :
346 : :
347 : :
348 : 0 : ScrollBar& ScrollPanel::GetHorizontalScrollBar (void)
349 : : {
350 : 0 : return maHorizontalScrollBar;
351 : : }
352 : :
353 : :
354 : :
355 : :
356 : : /** This control shows an expansion bar for every control and in a
357 : : separate area below that expansion area it shows all controls each
358 : : with its title bar. When there is not enough space then show a
359 : : scroll bar in the control area.
360 : : */
361 : 23 : void ScrollPanel::Rearrange (void)
362 : : {
363 [ + - ]: 23 : Size aRequiredSize (GetRequiredSize());
364 [ + - ][ + - ]: 23 : if (aRequiredSize.Width()>0 && aRequiredSize.Height()>0)
[ + - ]
365 : : {
366 [ + - ]: 23 : Size aAvailableSize (SetupScrollBars (aRequiredSize));
367 : : maScrollWindow.SetPosSizePixel(
368 : : Point(0,0),
369 [ + - ]: 23 : aAvailableSize);
370 : :
371 : : // Make the children at least as wide as the sub tool panel.
372 [ + + ]: 23 : if (aRequiredSize.Width() < aAvailableSize.Width())
373 : 2 : aRequiredSize.Width() = aAvailableSize.Width();
374 : 23 : mnChildrenWidth = -2*mnHorizontalBorder;
375 [ + - ][ - + ]: 23 : if (maHorizontalScrollBar.IsVisible())
376 : 0 : mnChildrenWidth += aRequiredSize.Width();
377 : : else
378 : 23 : mnChildrenWidth += aAvailableSize.Width();
379 : :
380 [ + - ]: 23 : sal_Int32 nChildrenHeight (LayoutChildren());
381 : : maVerticalScrollBar.SetRangeMax (
382 [ + - ]: 23 : nChildrenHeight + mnVerticalBorder);
383 : :
384 : 23 : mbIsRearrangePending = false;
385 : : }
386 : 23 : }
387 : :
388 : :
389 : :
390 : :
391 : 23 : Size ScrollPanel::GetRequiredSize (void)
392 : : {
393 : : // First determine the width of the children. This is the maximum of
394 : : // the current window width and the individual minimum widths of the
395 : : // children.
396 : 23 : int nChildrenWidth (GetSizePixel().Width());
397 : 23 : unsigned int nCount = mpControlContainer->GetControlCount();
398 : : unsigned int nIndex;
399 [ + + ]: 46 : for (nIndex=0; nIndex<nCount; nIndex++)
400 : : {
401 : 23 : TreeNode* pChild = mpControlContainer->GetControl (nIndex);
402 : 23 : int nMinimumWidth (pChild->GetMinimumWidth());
403 [ - + ]: 23 : if (nMinimumWidth > nChildrenWidth)
404 : 0 : nChildrenWidth = nMinimumWidth;
405 : : }
406 : :
407 : : // Determine the accumulated width of all children when scaled to the
408 : : // minimum width.
409 : 23 : nChildrenWidth -= 2*mnHorizontalBorder;
410 : : Size aTotalSize (nChildrenWidth,
411 : 23 : 2*mnVerticalBorder + (nCount-1) * mnVerticalGap);
412 [ + + ]: 46 : for (nIndex=0; nIndex<nCount; nIndex++)
413 : : {
414 : 23 : TreeNode* pChild = mpControlContainer->GetControl (nIndex);
415 : 23 : sal_Int32 nHeight = pChild->GetPreferredHeight(nChildrenWidth);
416 : 23 : aTotalSize.Height() += nHeight;
417 : : }
418 : :
419 : 23 : return aTotalSize;
420 : : }
421 : :
422 : :
423 : :
424 : :
425 : 23 : sal_Int32 ScrollPanel::LayoutChildren (void)
426 : : {
427 : 23 : maStripeList.clear();
428 : :
429 : 23 : Point aPosition (maScrollOffset);
430 : 23 : aPosition.X() += mnHorizontalBorder;
431 : : maStripeList.push_back( ::std::pair<int,int>(
432 : 23 : aPosition.Y(),
433 [ + - ][ + - ]: 46 : aPosition.Y() + mnVerticalBorder - 1));
434 : 23 : aPosition.Y() += mnVerticalBorder;
435 : :
436 : : // Place the controls one over the other.
437 [ + - ]: 23 : unsigned int nCount (mpControlContainer->GetControlCount());
438 [ + + ]: 46 : for (unsigned int nIndex=0; nIndex<nCount; nIndex++)
439 : : {
440 [ - + ]: 23 : if (nIndex > 0)
441 : : {
442 : : maStripeList.push_back( ::std::pair<int,int>(
443 : 0 : aPosition.Y(),
444 [ # # ][ # # ]: 0 : aPosition.Y() + mnVerticalGap - 1));
445 : 0 : aPosition.Y() += mnVerticalGap;
446 : : }
447 [ + - ]: 23 : TreeNode* pChild = mpControlContainer->GetControl (nIndex);
448 [ + - ]: 23 : int nControlHeight = pChild->GetPreferredHeight(mnChildrenWidth);
449 [ + - ]: 23 : pChild->GetWindow()->SetPosSizePixel(
450 : : aPosition,
451 [ + - ]: 23 : Size(mnChildrenWidth, nControlHeight));
452 : 23 : aPosition.Y() += nControlHeight;
453 : : }
454 : :
455 : : // If the children do not cover their parent window completely
456 : : // (regarding the height) we put a filler below that is responsible for
457 : : // painting the remaining space.
458 [ + - ]: 23 : int nWindowHeight = maScrollWindow.GetSizePixel().Height();
459 [ + + ]: 23 : if (aPosition.Y() < nWindowHeight)
460 : : {
461 : : maScrollWindowFiller.SetPosSizePixel (
462 : : aPosition,
463 [ + - ]: 2 : Size(mnChildrenWidth, nWindowHeight-aPosition.Y()));
464 : : maStripeList.push_back( ::std::pair<int,int>(
465 : 2 : aPosition.Y(),
466 [ + - ][ + - ]: 2 : nWindowHeight-1));
467 : : // maScrollWindowFiller.Show();
468 : 2 : aPosition.Y() = nWindowHeight;
469 : : }
470 : : else
471 [ + - ]: 21 : maScrollWindowFiller.Hide();
472 : :
473 : 23 : aPosition.Y() += mnVerticalBorder;
474 : 23 : mbIsLayoutPending = false;
475 : :
476 : 23 : return aPosition.Y()-maScrollOffset.Y();
477 : : }
478 : :
479 : :
480 : :
481 : :
482 : 23 : Size ScrollPanel::SetupScrollBars (const Size& rRequiredSize)
483 : : {
484 [ + - ]: 23 : Size aWindowSize (GetSizePixel());
485 : : Size aScrollBarSize (
486 [ + - ]: 23 : maVerticalScrollBar.GetSizePixel().Width(),
487 [ + - ]: 46 : maHorizontalScrollBar.GetSizePixel().Height());
488 : 23 : Size aRemainingSize (aWindowSize);
489 : :
490 : : // Determine which scroll bars have to be shown.
491 : 23 : bool bShowHorizontal = false;
492 [ - + ]: 23 : if (rRequiredSize.Width() > aWindowSize.Width())
493 : 0 : bShowHorizontal = true;
494 : 23 : bool bShowVertical = false;
495 [ + + ]: 23 : if (rRequiredSize.Height() > aWindowSize.Height())
496 : 21 : bShowVertical = true;
497 : : // Showing one scroll bar may reduce the available size so that the
498 : : // other one has to be shown as well.
499 [ - + ][ # # ]: 23 : if (bShowHorizontal && ! bShowVertical)
500 : : {
501 [ # # ]: 0 : if ((rRequiredSize.Height() + aScrollBarSize.Height())
502 : 0 : > aWindowSize.Height())
503 : 0 : bShowVertical = true;
504 : : }
505 [ + + ][ + - ]: 23 : else if (bShowVertical && ! bShowHorizontal)
506 : : {
507 [ + - ][ - + ]: 21 : if (GetMinimumWidth() + aScrollBarSize.Width() > aWindowSize.Width())
508 : 0 : bShowHorizontal = true;
509 : : }
510 : :
511 : : // Setup the scroll bars.
512 : 23 : aRemainingSize.Width()
513 [ + - ]: 23 : = SetupVerticalScrollBar (bShowVertical, rRequiredSize.Height());
514 : 23 : aRemainingSize.Height()
515 [ + - ]: 23 : = SetupHorizontalScrollBar (bShowHorizontal, rRequiredSize.Width());
516 : :
517 : : // Place the filler.
518 [ - + ][ # # ]: 23 : if (bShowHorizontal && bShowVertical)
519 : : {
520 : : maScrollBarFiller.SetPosSizePixel (
521 : 0 : Point(aWindowSize.Width(), aWindowSize.Height()),
522 [ # # ]: 0 : aScrollBarSize);
523 [ # # ]: 0 : maScrollBarFiller.Show();
524 : : }
525 : : else
526 [ + - ]: 23 : maScrollBarFiller.Hide();
527 : :
528 : :
529 : 23 : return aRemainingSize;
530 : : }
531 : :
532 : :
533 : :
534 : :
535 : 23 : sal_Int32 ScrollPanel::SetupVerticalScrollBar (bool bShow, sal_Int32 nRange)
536 : : {
537 : : Size aScrollBarSize (
538 [ + - ]: 23 : maVerticalScrollBar.GetSizePixel().Width(),
539 [ + - ]: 46 : maHorizontalScrollBar.GetSizePixel().Height());
540 : 23 : Size aWindowSize (GetOutputSizePixel());
541 : 23 : sal_Int32 nRemainingWidth (aWindowSize.Width());
542 : :
543 : : // Setup the verical scroll bar.
544 [ + + ]: 23 : if (bShow)
545 : : {
546 : 21 : int nWidth = aScrollBarSize.Width();
547 : 21 : int nHeight = aWindowSize.Height();
548 : : maVerticalScrollBar.SetPosSizePixel(
549 : 21 : Point(aWindowSize.Width()-nWidth,0),
550 [ + - ]: 42 : Size(nWidth, nHeight));
551 [ + - ]: 21 : maVerticalScrollBar.Show();
552 : :
553 : : // Set the scroll bar range and thumb size.
554 [ + - ]: 21 : maVerticalScrollBar.SetRangeMin (0);
555 : : maVerticalScrollBar.SetRangeMax (
556 [ + - ]: 21 : nRange + 2*mnVerticalBorder);
557 [ + - ]: 21 : maVerticalScrollBar.SetVisibleSize (aWindowSize.Height());
558 : : // Make page size approx. 10% of visible area.
559 : 21 : maVerticalScrollBar.SetLineSize (aWindowSize.Height()/10);
560 : : // Make page size approx. 100% of visible area.
561 : 21 : maVerticalScrollBar.SetPageSize (aWindowSize.Height());
562 : : // Make sure that thumb is inside the valid range.
563 [ + - ]: 21 : maVerticalScrollBar.SetThumbPos(-maScrollOffset.Y());
564 : 21 : long nMinPos = maVerticalScrollBar.GetRangeMin();
565 [ - + ]: 21 : if (maVerticalScrollBar.GetThumbPos() < nMinPos)
566 [ # # ]: 0 : maVerticalScrollBar.SetThumbPos(nMinPos);
567 : 21 : long nMaxPos = maVerticalScrollBar.GetRangeMax()
568 : 21 : - maVerticalScrollBar.GetVisibleSize();
569 [ - + ]: 21 : if (maVerticalScrollBar.GetThumbPos() >= nMaxPos)
570 [ # # ]: 0 : maVerticalScrollBar.SetThumbPos(nMaxPos);
571 : : // Set offset to match thumb pos.
572 : 21 : maScrollOffset.Y() = -maVerticalScrollBar.GetThumbPos();
573 : :
574 : 21 : nRemainingWidth -= aScrollBarSize.Width();
575 : : }
576 : : else
577 : : {
578 [ + - ]: 2 : maVerticalScrollBar.Hide();
579 : 2 : maScrollOffset.Y() = 0;
580 : : }
581 : :
582 : 23 : return nRemainingWidth;
583 : : }
584 : :
585 : :
586 : :
587 : :
588 : 23 : sal_Int32 ScrollPanel::SetupHorizontalScrollBar (bool bShow, sal_Int32 nRange)
589 : : {
590 : : Size aScrollBarSize (
591 [ + - ]: 23 : maVerticalScrollBar.GetSizePixel().Width(),
592 [ + - ]: 46 : maHorizontalScrollBar.GetSizePixel().Height());
593 : 23 : Size aWindowSize (GetOutputSizePixel());
594 : 23 : sal_Int32 nRemainingHeight (aWindowSize.Height());
595 : :
596 : : // Setup the horizontal scroll bar.
597 [ - + ]: 23 : if (bShow)
598 : : {
599 : 0 : int nHeight = aScrollBarSize.Height();
600 : 0 : int nWidth = GetOutputSizePixel().Width();
601 : : maHorizontalScrollBar.SetPosSizePixel(
602 : 0 : Point(0, aWindowSize.Height()-nHeight),
603 [ # # ]: 0 : Size(nWidth,nHeight));
604 [ # # ]: 0 : maHorizontalScrollBar.Show();
605 : :
606 : : // Set the scroll bar range and thumb size.
607 [ # # ]: 0 : maHorizontalScrollBar.SetRangeMin (0);
608 : : maHorizontalScrollBar.SetRangeMax (
609 [ # # ]: 0 : nRange + 2*mnHorizontalBorder);
610 [ # # ]: 0 : maHorizontalScrollBar.SetVisibleSize (aWindowSize.Width());
611 : : // Make page size approx. 5% of visible area.
612 : 0 : maHorizontalScrollBar.SetLineSize (aWindowSize.Width()/20+1);
613 : : // Make page size approx. 50% of visible area.
614 : 0 : maHorizontalScrollBar.SetPageSize (aWindowSize.Width()/2+1);
615 : : // Make sure that thumb is inside the valid range.
616 [ # # ]: 0 : maHorizontalScrollBar.SetThumbPos(-maScrollOffset.X());
617 : 0 : long nMinPos = maHorizontalScrollBar.GetRangeMin();
618 [ # # ]: 0 : if (maHorizontalScrollBar.GetThumbPos() < nMinPos)
619 [ # # ]: 0 : maHorizontalScrollBar.SetThumbPos(nMinPos);
620 : 0 : long nMaxPos = maHorizontalScrollBar.GetRangeMax()
621 : 0 : - maHorizontalScrollBar.GetVisibleSize();
622 [ # # ]: 0 : if (maHorizontalScrollBar.GetThumbPos() >= nMaxPos)
623 [ # # ]: 0 : maHorizontalScrollBar.SetThumbPos(nMaxPos);
624 : : // Set offset to match thumb pos.
625 : 0 : maScrollOffset.X() = -maHorizontalScrollBar.GetThumbPos();
626 : :
627 : 0 : nRemainingHeight -= aScrollBarSize.Height();
628 : : }
629 : : else
630 : : {
631 [ + - ]: 23 : maHorizontalScrollBar.Hide();
632 : 23 : maScrollOffset.X() = 0;
633 : : }
634 : :
635 : 23 : return nRemainingHeight;
636 : : }
637 : :
638 : :
639 : 0 : IMPL_LINK_NOARG(ScrollPanel, ScrollBarHandler)
640 : : {
641 : 0 : maScrollOffset.X() -= maHorizontalScrollBar.GetDelta();
642 : 0 : maScrollOffset.Y() -= maVerticalScrollBar.GetDelta();
643 : :
644 : : // Scrolling is done by moving the child windows up or down.
645 : 0 : mbIsLayoutPending = true;
646 : 0 : Invalidate();
647 : : // LayoutChildren();
648 : :
649 : 0 : return 0;
650 : : }
651 : :
652 : :
653 : :
654 : :
655 : 135 : long ScrollPanel::Notify( NotifyEvent& rNEvt )
656 : : {
657 : 135 : long nRet = sal_False;
658 [ - + ]: 135 : if( rNEvt.GetType() == EVENT_COMMAND )
659 : : {
660 : : // note: dynamic_cast is not possible as GetData() returns a void*
661 : 0 : CommandEvent* pCmdEvent = reinterpret_cast< CommandEvent* >(rNEvt.GetData());
662 : : DBG_ASSERT( pCmdEvent!=0 &&
663 : : ( pCmdEvent->IsMouseEvent() == sal_True ||
664 : : pCmdEvent->IsMouseEvent() == sal_False ),
665 : : "Invalid CommandEvent" );
666 [ # # ]: 0 : if (pCmdEvent)
667 [ # # ]: 0 : switch (pCmdEvent->GetCommand())
668 : : {
669 : : case COMMAND_WHEEL:
670 : : case COMMAND_STARTAUTOSCROLL:
671 : : case COMMAND_AUTOSCROLL:
672 : : {
673 : 0 : nRet = HandleScrollCommand (*pCmdEvent, &maHorizontalScrollBar, &maVerticalScrollBar);
674 : 0 : break;
675 : : }
676 : : }
677 : : }
678 : :
679 [ + - ]: 135 : if( ! nRet )
680 : 135 : nRet = ::Window::Notify( rNEvt );
681 : :
682 : 135 : return nRet;
683 : : }
684 : :
685 : :
686 : :
687 : :
688 : : ::com::sun::star::uno::Reference<
689 : 0 : ::com::sun::star::accessibility::XAccessible> ScrollPanel::CreateAccessibleObject (
690 : : const ::com::sun::star::uno::Reference<
691 : : ::com::sun::star::accessibility::XAccessible>& )
692 : : {
693 : : return new ::accessibility::AccessibleScrollPanel (
694 : : *this,
695 : : "Scroll Panel",
696 [ # # ][ # # ]: 0 : "Scroll Panel");
[ # # ]
697 : : }
698 : :
699 : :
700 : :
701 : :
702 : 0 : void ScrollPanel::MakeRectangleVisible (
703 : : Rectangle& aRectangle,
704 : : ::Window* pWindow)
705 : : {
706 [ # # ][ # # ]: 0 : if (maVerticalScrollBar.IsVisible() && aRectangle.GetWidth()>0 && aRectangle.GetHeight()>0)
[ # # ][ # # ]
707 : : {
708 [ # # ]: 0 : const Rectangle aRelativeBox (pWindow->GetWindowExtentsRelative(&maScrollWindow));
709 : :
710 : : aRectangle.Move(
711 : 0 : -maScrollOffset.X() + aRelativeBox.Left(),
712 [ # # ]: 0 : -maScrollOffset.Y() + aRelativeBox.Top());
713 : :
714 : 0 : const int nVisibleHeight (maVerticalScrollBar.GetVisibleSize());
715 : 0 : const int nVisibleTop (maVerticalScrollBar.GetThumbPos());
716 [ # # ]: 0 : if (aRectangle.Bottom() >= nVisibleTop+nVisibleHeight)
717 [ # # ]: 0 : maVerticalScrollBar.DoScroll(aRectangle.Bottom() - nVisibleHeight);
718 [ # # ]: 0 : else if (aRectangle.Top() < nVisibleTop)
719 [ # # ]: 0 : maVerticalScrollBar.DoScroll(aRectangle.Top());
720 : : }
721 : 0 : }
722 : :
723 : :
724 : :
725 : :
726 : 160 : IMPL_LINK(ScrollPanel,WindowEventListener,VclSimpleEvent*,pEvent)
727 : : {
728 [ - + ]: 160 : VclWindowEvent* pWindowEvent = dynamic_cast<VclWindowEvent*>(pEvent);
729 [ + - ]: 160 : if (pWindowEvent != NULL)
730 : : {
731 [ - - + + : 160 : switch (pWindowEvent->GetId())
+ ]
732 : : {
733 : : case VCLEVENT_WINDOW_KEYUP:
734 : : case VCLEVENT_WINDOW_MOUSEBUTTONUP:
735 : : {
736 : : // Make the currently selected item visible.
737 [ # # ]: 0 : ValueSet* pControl = dynamic_cast<ValueSet*>(pWindowEvent->GetWindow());
738 [ # # ]: 0 : if (pControl != NULL)
739 : : {
740 : : // Get the bounding box of the currently selected item
741 : : // and enlarge this so that the selection frame is
742 : : // inside as well.
743 [ # # ]: 0 : Rectangle aBox (pControl->GetItemRect(pControl->GetSelectItemId()));
744 : 0 : aBox.Top()-=4;
745 : 0 : aBox.Bottom()+=4;
746 : :
747 [ # # ]: 0 : MakeRectangleVisible(aBox, pControl);
748 : : }
749 : : }
750 : 0 : break;
751 : :
752 : : case VCLEVENT_WINDOW_MOUSEBUTTONDOWN:
753 : : {
754 : : // Make the item under the mouse visible. We need this case
755 : : // for right clicks that open context menus. For these we
756 : : // only get the mouse down event. The following mouse up
757 : : // event is sent to the context menu.
758 [ # # ]: 0 : ValueSet* pControl = dynamic_cast<ValueSet*>(pWindowEvent->GetWindow());
759 [ # # ]: 0 : if (pControl != NULL)
760 : : {
761 : : // Get the bounding box of the item at the mouse
762 : : // position and enlarge this so that the selection frame
763 : : // is inside as well.
764 : : MouseEvent* pMouseEvent
765 : 0 : = reinterpret_cast<MouseEvent*>(pWindowEvent->GetData());
766 [ # # ]: 0 : if (pMouseEvent != NULL)
767 : : {
768 : 0 : Point aPosition (pMouseEvent->GetPosPixel());
769 [ # # ][ # # ]: 0 : Rectangle aBox (pControl->GetItemRect(pControl->GetItemId(aPosition)));
770 : 0 : aBox.Top()-=4;
771 : 0 : aBox.Bottom()+=4;
772 : :
773 [ # # ]: 0 : MakeRectangleVisible(aBox, pControl);
774 : : }
775 : : }
776 : : }
777 : 0 : break;
778 : :
779 : :
780 : : case VCLEVENT_WINDOW_GETFOCUS:
781 : : {
782 : : // Move title bars into the visible area when they get the
783 : : // focus (::Window wise their enclosing TitledControl gets
784 : : // the focus.)
785 [ - + ]: 15 : TitledControl* pTitledControl = dynamic_cast<TitledControl*>(pWindowEvent->GetWindow());
786 [ - + ][ # # ]: 15 : if (pTitledControl!=NULL && pTitledControl->GetTitleBar()!=NULL)
[ - + ]
787 : : {
788 [ # # ][ # # ]: 0 : ::Window* pTitleBarWindow = pTitledControl->GetTitleBar()->GetWindow();
789 [ # # ][ # # ]: 0 : Rectangle aBox(pTitleBarWindow->GetPosPixel(),pTitleBarWindow->GetSizePixel());
[ # # ]
790 : : MakeRectangleVisible(
791 : : aBox,
792 [ # # ]: 0 : pTitleBarWindow);
793 : : }
794 : : }
795 : 15 : break;
796 : :
797 : : case VCLEVENT_WINDOW_SHOW:
798 : : case VCLEVENT_WINDOW_HIDE:
799 : : case VCLEVENT_WINDOW_ACTIVATE:
800 : : case VCLEVENT_WINDOW_RESIZE:
801 : : // Rearrange the children of the scroll panel when one of
802 : : // the children changes its size or visibility.
803 : 92 : RequestResize();
804 : 160 : break;
805 : : }
806 : : }
807 : 160 : return 0;
808 : : }
809 : :
810 : :
811 : :
812 : :
813 : : } } // end of namespace ::sd::toolpanel
814 : :
815 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|