fdo#74697 Add Bluez 5 support for impress remote.
[LibreOffice.git] / sd / source / ui / dlg / RemoteDialogClientBox.cxx
blobbc9b508feed2d43b3b80c5d0ab0be8f4d4b49479
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include "svtools/controldims.hrc"
22 #include "RemoteDialogClientBox.hxx"
23 #include "RemoteDialog.hrc"
25 #include "comphelper/processfactory.hxx"
26 #include "com/sun/star/i18n/CollatorOptions.hpp"
27 #include "com/sun/star/deployment/DependencyException.hpp"
28 #include "com/sun/star/deployment/DeploymentException.hpp"
30 using namespace ::com::sun::star;
32 namespace sd {
34 //------------------------------------------------------------------------------
35 // struct ClientBoxEntry
36 //------------------------------------------------------------------------------
37 ClientBoxEntry::ClientBoxEntry( ClientInfo* pClientInfo ) :
38 m_bActive( false ),
39 m_pClientInfo( pClientInfo )
43 //------------------------------------------------------------------------------
44 ClientBoxEntry::~ClientBoxEntry()
48 //------------------------------------------------------------------------------
49 // ClientRemovedListener
50 //------------------------------------------------------------------------------
51 void ClientRemovedListener::disposing( lang::EventObject const & rEvt )
52 throw ( uno::RuntimeException )
54 (void) rEvt;
57 //------------------------------------------------------------------------------
58 ClientRemovedListener::~ClientRemovedListener()
62 //------------------------------------------------------------------------------
63 // ClientBox
64 //------------------------------------------------------------------------------
65 ClientBox::ClientBox( Dialog* pParent, RemoteServer *pServer,
66 const SdResId& aId ) :
67 Control( pParent, aId ),
68 m_bHasScrollBar( false ),
69 m_bHasActive( false ),
70 m_bNeedsRecalc( true ),
71 m_bInCheckMode( false ),
72 m_bAdjustActive( false ),
73 m_bInDelete( false ),
74 m_nActive( 0 ),
75 m_nTopIndex( 0 ),
76 m_nActiveHeight( 0 ),
77 m_nExtraHeight( 2 ),
78 m_aPinBox( this, SdResId( INPUT_PIN ) ),
79 m_aPinDescription( this, SdResId( TEXT_PIN ) ),
80 m_pScrollBar( new ScrollBar( this, WB_VERT ) ),
81 m_pServer( pServer )
83 m_pScrollBar->SetScrollHdl( LINK( this, ClientBox, ScrollHdl ) );
84 m_pScrollBar->EnableDrag();
86 m_aPinBox.SetUseThousandSep(false);
87 // m_aPinDescription.SetText( String( SdResId( STR_ENTER_PIN ) ) );
89 SetPaintTransparent( true );
90 SetPosPixel( Point( RSC_SP_DLG_INNERBORDER_LEFT, RSC_SP_DLG_INNERBORDER_TOP ) );
91 long nIconHeight = 2*TOP_OFFSET + SMALL_ICON_SIZE;
92 long nTitleHeight = 2*TOP_OFFSET + GetTextHeight();
93 if ( nIconHeight < nTitleHeight )
94 m_nStdHeight = nTitleHeight;
95 else
96 m_nStdHeight = nIconHeight;
97 m_nStdHeight += GetTextHeight() + TOP_OFFSET;
99 // nIconHeight = ICON_HEIGHT + 2*TOP_OFFSET + 1;
100 // if ( m_nStdHeight < nIconHeight )
101 // m_nStdHeight = nIconHeight;
103 m_nActiveHeight = m_nStdHeight;
105 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
106 if( IsControlBackground() )
107 SetBackground( GetControlBackground() );
108 else
109 SetBackground( rStyleSettings.GetFieldColor() );
111 m_xRemoveListener = new ClientRemovedListener( this );
113 Show();
116 //------------------------------------------------------------------------------
117 ClientBox::~ClientBox()
119 if ( ! m_bInDelete )
120 DeleteRemoved();
122 m_bInDelete = true;
124 typedef std::vector< TClientBoxEntry >::iterator ITER;
126 for ( ITER iIndex = m_vEntries.begin(); iIndex < m_vEntries.end(); ++iIndex )
128 // (*iIndex)->m_xPackage->removeEventListener( uno::Reference< lang::XEventListener > ( m_xRemoveListener, uno::UNO_QUERY ) );
131 m_vEntries.clear();
133 m_xRemoveListener.clear();
136 //------------------------------------------------------------------------------
137 // Title + description
138 void ClientBox::CalcActiveHeight( const long nPos )
140 (void) nPos;
141 const ::osl::MutexGuard aGuard( m_entriesMutex );
143 // get title height
144 long aTextHeight;
145 long nIconHeight = 2*TOP_OFFSET + SMALL_ICON_SIZE;
146 long nTitleHeight = 2*TOP_OFFSET + GetTextHeight();
147 if ( nIconHeight < nTitleHeight )
148 aTextHeight = nTitleHeight;
149 else
150 aTextHeight = nIconHeight;
152 // Text entry height
153 Size aSize = GetOutputSizePixel();
154 if ( m_bHasScrollBar )
155 aSize.Width() -= m_pScrollBar->GetSizePixel().Width();
157 aSize.Width() -= ICON_OFFSET;
159 aSize = LogicToPixel( Size( RSC_CD_PUSHBUTTON_WIDTH, RSC_CD_PUSHBUTTON_HEIGHT ),
160 MapMode( MAP_APPFONT ) );
161 aTextHeight += aSize.Height();
163 if ( aTextHeight < m_nStdHeight )
164 aTextHeight = m_nStdHeight;
166 m_nActiveHeight = aTextHeight + 2;
169 //------------------------------------------------------------------------------
170 Rectangle ClientBox::GetEntryRect( const long nPos ) const
172 const ::osl::MutexGuard aGuard( m_entriesMutex );
174 Size aSize( GetOutputSizePixel() );
176 if ( m_bHasScrollBar )
177 aSize.Width() -= m_pScrollBar->GetSizePixel().Width();
179 if ( m_vEntries[ nPos ]->m_bActive )
180 aSize.Height() = m_nActiveHeight;
181 else
182 aSize.Height() = m_nStdHeight;
184 Point aPos( 0, -m_nTopIndex + nPos * m_nStdHeight );
185 if ( m_bHasActive && ( nPos < m_nActive ) )
186 aPos.Y() += m_nActiveHeight - m_nStdHeight;
188 return Rectangle( aPos, aSize );
191 //------------------------------------------------------------------------------
192 void ClientBox::DeleteRemoved()
194 const ::osl::MutexGuard aGuard( m_entriesMutex );
196 m_bInDelete = true;
198 if ( ! m_vRemovedEntries.empty() )
200 m_vRemovedEntries.clear();
203 m_bInDelete = false;
206 long ClientBox::GetActiveEntryIndex()
208 if ( m_bHasActive )
209 return m_nActive;
210 else
211 return -1;
214 //------------------------------------------------------------------------------
215 //This function may be called with nPos < 0
216 void ClientBox::selectEntry( const long nPos )
218 //ToDo whe should not use the guard at such a big scope here.
219 //Currently it is used to gard m_vEntries and m_nActive. m_nActive will be
220 //modified in this function.
221 //It would be probably best to always use a copy of m_vEntries
222 //and some other state variables from ClientBox for
223 //the whole painting operation. See issue i86993
224 ::osl::ClearableMutexGuard guard(m_entriesMutex);
226 if ( m_bInCheckMode )
227 return;
229 if ( m_bHasActive )
231 if ( nPos == m_nActive )
232 return;
234 m_bHasActive = false;
235 m_vEntries[ m_nActive ]->m_bActive = false;
238 if ( ( nPos >= 0 ) && ( nPos < (long) m_vEntries.size() ) )
240 m_bHasActive = true;
241 m_nActive = nPos;
242 m_vEntries[ nPos ]->m_bActive = true;
244 if ( IsReallyVisible() )
246 m_bAdjustActive = true;
250 if ( IsReallyVisible() )
252 m_bNeedsRecalc = true;
253 Invalidate();
256 guard.clear();
259 // -----------------------------------------------------------------------
260 void ClientBox::DrawRow( const Rectangle& rRect, const TClientBoxEntry pEntry )
262 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
264 if ( pEntry->m_bActive )
265 SetTextColor( rStyleSettings.GetHighlightTextColor() );
266 else
267 SetTextColor( rStyleSettings.GetFieldTextColor() );
269 if ( pEntry->m_bActive )
271 SetLineColor();
272 SetFillColor( rStyleSettings.GetHighlightColor() );
273 DrawRect( rRect );
275 else
277 if( IsControlBackground() )
278 SetBackground( GetControlBackground() );
279 else
280 SetBackground( rStyleSettings.GetFieldColor() );
282 SetTextFillColor();
283 Erase( rRect );
286 // FIXME: draw bluetooth or wifi icon
287 Point aPos( rRect.TopLeft() );
288 // aPos += Point( TOP_OFFSET, TOP_OFFSET );
289 // Image aImage;
290 // if ( ! pEntry->m_aIcon )
291 // aImage = m_aDefaultImage;
292 // else
293 // aImage = pEntry->m_aIcon;
294 // Size aImageSize = aImage.GetSizePixel();
295 // if ( ( aImageSize.Width() <= ICON_WIDTH ) && ( aImageSize.Height() <= ICON_HEIGHT ) )
296 // DrawImage( Point( aPos.X()+((ICON_WIDTH-aImageSize.Width())/2), aPos.Y()+((ICON_HEIGHT-aImageSize.Height())/2) ), aImage );
297 // else
298 // DrawImage( aPos, Size( ICON_WIDTH, ICON_HEIGHT ), aImage );
300 // Setup fonts
301 Font aStdFont( GetFont() );
302 Font aBoldFont( aStdFont );
303 aBoldFont.SetWeight( WEIGHT_BOLD );
304 SetFont( aBoldFont );
305 long aTextHeight = GetTextHeight();
307 // Get max title width
308 long nMaxTitleWidth = rRect.GetWidth() - ICON_OFFSET;
309 nMaxTitleWidth -= ( 2 * SMALL_ICON_SIZE ) + ( 4 * SPACE_BETWEEN );
311 long aTitleWidth = GetTextWidth( String( pEntry->m_pClientInfo->mName ) ) + (aTextHeight / 3);
313 aPos = rRect.TopLeft() + Point( ICON_OFFSET, TOP_OFFSET );
315 if ( aTitleWidth > nMaxTitleWidth )
317 aTitleWidth = nMaxTitleWidth - (aTextHeight / 3);
318 String aShortTitle = GetEllipsisString( pEntry->m_pClientInfo->mName,
319 aTitleWidth );
320 DrawText( aPos, aShortTitle );
321 aTitleWidth += (aTextHeight / 3);
323 else
324 DrawText( aPos, pEntry->m_pClientInfo->mName );
326 SetFont( aStdFont );
328 aPos.Y() += aTextHeight;
329 if ( pEntry->m_bActive )
331 Size aSize = LogicToPixel( Size( RSC_CD_PUSHBUTTON_WIDTH, RSC_CD_PUSHBUTTON_HEIGHT ),
332 MapMode( MAP_APPFONT ) );
333 m_aPinBox.SetSizePixel( aSize );
334 const Rectangle aRect( GetEntryRect( m_nActive ) );
335 Size aBtnSize( m_aPinBox.GetSizePixel() );
336 Point aBtnPos( aRect.Left(),
337 aRect.Bottom() - TOP_OFFSET - aBtnSize.Height() );
338 // m_aPinDescription.SetPosPixel( aBtnPos );
339 DrawText( Rectangle( aBtnPos.X(), aBtnPos.Y(), rRect.Right(), rRect.Bottom() - TOP_OFFSET),
340 String( SdResId( STR_ENTER_PIN ) ), 0 );
342 aBtnPos = Point( aRect.Left() + GetTextWidth( String( SdResId( STR_ENTER_PIN ) ) ),
343 aRect.Bottom() - TOP_OFFSET - aBtnSize.Height() );
345 m_aPinBox.SetPosPixel( aBtnPos );
351 // long nExtraHeight = 0;
353 // if ( pEntry->m_bHasButtons )
354 // nExtraHeight = m_nExtraHeight;
356 // DrawText( Rectangle( aPos.X(), aPos.Y(), rRect.Right(), rRect.Bottom() - nExtraHeight ),
357 // sDescription, TEXT_DRAW_MULTILINE | TEXT_DRAW_WORDBREAK );
359 else
363 SetLineColor( Color( COL_LIGHTGRAY ) );
364 DrawLine( rRect.BottomLeft(), rRect.BottomRight() );
367 // -----------------------------------------------------------------------
368 void ClientBox::RecalcAll()
370 if ( m_bHasActive )
371 CalcActiveHeight( m_nActive );
373 SetupScrollBar();
375 if ( m_bHasActive )
377 Rectangle aEntryRect = GetEntryRect( m_nActive );
379 if ( m_bAdjustActive )
381 m_bAdjustActive = false;
383 // If the top of the selected entry isn't visible, make it visible
384 if ( aEntryRect.Top() < 0 )
386 m_nTopIndex += aEntryRect.Top();
387 aEntryRect.Move( 0, -aEntryRect.Top() );
390 // If the bottom of the selected entry isn't visible, make it visible even if now the top
391 // isn't visible any longer ( the buttons are more important )
392 Size aOutputSize = GetOutputSizePixel();
393 if ( aEntryRect.Bottom() > aOutputSize.Height() )
395 m_nTopIndex += ( aEntryRect.Bottom() - aOutputSize.Height() );
396 aEntryRect.Move( 0, -( aEntryRect.Bottom() - aOutputSize.Height() ) );
399 // If there is unused space below the last entry but all entries don't fit into the box,
400 // move the content down to use the whole space
401 const long nTotalHeight = GetTotalHeight();
402 if ( m_bHasScrollBar && ( aOutputSize.Height() + m_nTopIndex > nTotalHeight ) )
404 long nOffset = m_nTopIndex;
405 m_nTopIndex = nTotalHeight - aOutputSize.Height();
406 nOffset -= m_nTopIndex;
407 aEntryRect.Move( 0, nOffset );
410 if ( m_bHasScrollBar )
411 m_pScrollBar->SetThumbPos( m_nTopIndex );
415 m_bNeedsRecalc = false;
418 // -----------------------------------------------------------------------
419 bool ClientBox::HandleTabKey( bool )
421 return false;
424 // -----------------------------------------------------------------------
425 bool ClientBox::HandleCursorKey( sal_uInt16 nKeyCode )
427 if ( m_vEntries.empty() )
428 return true;
430 long nSelect = 0;
432 if ( m_bHasActive )
434 long nPageSize = GetOutputSizePixel().Height() / m_nStdHeight;
435 if ( nPageSize < 2 )
436 nPageSize = 2;
438 if ( ( nKeyCode == KEY_DOWN ) || ( nKeyCode == KEY_RIGHT ) )
439 nSelect = m_nActive + 1;
440 else if ( ( nKeyCode == KEY_UP ) || ( nKeyCode == KEY_LEFT ) )
441 nSelect = m_nActive - 1;
442 else if ( nKeyCode == KEY_HOME )
443 nSelect = 0;
444 else if ( nKeyCode == KEY_END )
445 nSelect = m_vEntries.size() - 1;
446 else if ( nKeyCode == KEY_PAGEUP )
447 nSelect = m_nActive - nPageSize + 1;
448 else if ( nKeyCode == KEY_PAGEDOWN )
449 nSelect = m_nActive + nPageSize - 1;
451 else // when there is no selected entry, we will select the first or the last.
453 if ( ( nKeyCode == KEY_DOWN ) || ( nKeyCode == KEY_PAGEDOWN ) || ( nKeyCode == KEY_HOME ) )
454 nSelect = 0;
455 else if ( ( nKeyCode == KEY_UP ) || ( nKeyCode == KEY_PAGEUP ) || ( nKeyCode == KEY_END ) )
456 nSelect = m_vEntries.size() - 1;
459 if ( nSelect < 0 )
460 nSelect = 0;
461 if ( nSelect >= (long) m_vEntries.size() )
462 nSelect = m_vEntries.size() - 1;
464 selectEntry( nSelect );
466 return true;
469 // -----------------------------------------------------------------------
470 void ClientBox::Paint( const Rectangle &/*rPaintRect*/ )
472 if ( !m_bInDelete )
473 DeleteRemoved();
475 if ( m_bNeedsRecalc )
476 RecalcAll();
478 Point aStart( 0, -m_nTopIndex );
479 Size aSize( GetOutputSizePixel() );
481 if ( m_bHasScrollBar )
482 aSize.Width() -= m_pScrollBar->GetSizePixel().Width();
484 const ::osl::MutexGuard aGuard( m_entriesMutex );
486 typedef std::vector< TClientBoxEntry >::iterator ITER;
487 for ( ITER iIndex = m_vEntries.begin(); iIndex < m_vEntries.end(); ++iIndex )
489 aSize.Height() = (*iIndex)->m_bActive ? m_nActiveHeight : m_nStdHeight;
490 Rectangle aEntryRect( aStart, aSize );
491 DrawRow( aEntryRect, *iIndex );
492 aStart.Y() += aSize.Height();
496 // -----------------------------------------------------------------------
497 long ClientBox::GetTotalHeight() const
499 long nHeight = m_vEntries.size() * m_nStdHeight;
501 if ( m_bHasActive )
503 nHeight += m_nActiveHeight - m_nStdHeight;
506 return nHeight;
509 // -----------------------------------------------------------------------
510 void ClientBox::SetupScrollBar()
512 const Size aSize = GetOutputSizePixel();
513 const long nScrBarSize = GetSettings().GetStyleSettings().GetScrollBarSize();
514 const long nTotalHeight = GetTotalHeight();
515 const bool bNeedsScrollBar = ( nTotalHeight > aSize.Height() );
517 if ( bNeedsScrollBar )
519 if ( m_nTopIndex + aSize.Height() > nTotalHeight )
520 m_nTopIndex = nTotalHeight - aSize.Height();
522 m_pScrollBar->SetPosSizePixel( Point( aSize.Width() - nScrBarSize, 0 ),
523 Size( nScrBarSize, aSize.Height() ) );
524 m_pScrollBar->SetRangeMax( nTotalHeight );
525 m_pScrollBar->SetVisibleSize( aSize.Height() );
526 m_pScrollBar->SetPageSize( ( aSize.Height() * 4 ) / 5 );
527 m_pScrollBar->SetLineSize( m_nStdHeight );
528 m_pScrollBar->SetThumbPos( m_nTopIndex );
530 if ( !m_bHasScrollBar )
531 m_pScrollBar->Show();
533 else if ( m_bHasScrollBar )
535 m_pScrollBar->Hide();
536 m_nTopIndex = 0;
539 m_bHasScrollBar = bNeedsScrollBar;
542 // -----------------------------------------------------------------------
543 void ClientBox::Resize()
545 RecalcAll();
548 //------------------------------------------------------------------------------
549 long ClientBox::PointToPos( const Point& rPos )
551 long nPos = ( rPos.Y() + m_nTopIndex ) / m_nStdHeight;
553 if ( m_bHasActive && ( nPos > m_nActive ) )
555 if ( rPos.Y() + m_nTopIndex <= m_nActive*m_nStdHeight + m_nActiveHeight )
556 nPos = m_nActive;
557 else
558 nPos = ( rPos.Y() + m_nTopIndex - (m_nActiveHeight - m_nStdHeight) ) / m_nStdHeight;
561 return nPos;
564 OUString ClientBox::getPin()
566 return OUString::valueOf( m_aPinBox.GetValue() );
569 //------------------------------------------------------------------------------
570 void ClientBox::MouseButtonDown( const MouseEvent& rMEvt )
572 long nPos = PointToPos( rMEvt.GetPosPixel() );
574 if ( rMEvt.IsLeft() )
576 if ( rMEvt.IsMod1() && m_bHasActive )
577 selectEntry( m_vEntries.size() ); // Selecting an not existing entry will deselect the current one
578 else
579 selectEntry( nPos );
583 //------------------------------------------------------------------------------
584 long ClientBox::Notify( NotifyEvent& rNEvt )
586 if ( !m_bInDelete )
587 DeleteRemoved();
589 bool bHandled = false;
591 if ( rNEvt.GetType() == EVENT_KEYINPUT )
593 const KeyEvent* pKEvt = rNEvt.GetKeyEvent();
594 KeyCode aKeyCode = pKEvt->GetKeyCode();
595 sal_uInt16 nKeyCode = aKeyCode.GetCode();
597 if ( nKeyCode == KEY_TAB )
598 bHandled = HandleTabKey( aKeyCode.IsShift() );
599 else if ( aKeyCode.GetGroup() == KEYGROUP_CURSOR )
600 bHandled = HandleCursorKey( nKeyCode );
603 if ( rNEvt.GetType() == EVENT_COMMAND )
605 if ( m_bHasScrollBar &&
606 ( rNEvt.GetCommandEvent()->GetCommand() == COMMAND_WHEEL ) )
608 const CommandWheelData* pData = rNEvt.GetCommandEvent()->GetWheelData();
609 if ( pData->GetMode() == COMMAND_WHEEL_SCROLL )
611 long nThumbPos = m_pScrollBar->GetThumbPos();
612 if ( pData->GetDelta() < 0 )
613 m_pScrollBar->DoScroll( nThumbPos + m_nStdHeight );
614 else
615 m_pScrollBar->DoScroll( nThumbPos - m_nStdHeight );
616 bHandled = true;
621 if ( !bHandled )
622 return Control::Notify( rNEvt );
623 else
624 return true;
628 //------------------------------------------------------------------------------
629 long ClientBox::addEntry( ClientInfo* pClientInfo )
631 long nPos = 0;
632 // PackageState eState = m_pManager->getPackageState( xPackage );
633 // bool bLocked = m_pManager->isReadOnly( xPackage );
635 TClientBoxEntry pEntry( new ClientBoxEntry( pClientInfo ) );
637 bool bNewEntryInserted = false;
639 ::osl::ClearableMutexGuard guard(m_entriesMutex);
640 if ( m_vEntries.empty() )
642 m_vEntries.push_back( pEntry );
643 bNewEntryInserted = true;
645 else
647 // if ( !FindEntryPos( pEntry, 0, m_vEntries.size()-1, nPos ) )
648 // {
649 m_vEntries.insert( m_vEntries.begin()+nPos, pEntry );
650 bNewEntryInserted = true;
651 // }
652 // else if ( !m_bInCheckMode )
653 // {
654 // OSL_FAIL( "ClientBox::addEntry(): Will not add duplicate entries" );
655 // }
658 //Related: rhbz#702833 Only add a Listener if we're adding a new entry, to
659 //keep in sync with removeEventListener logic
660 if (bNewEntryInserted)
663 // pEntry->m_xPackage->addEventListener(uno::Reference< lang::XEventListener > ( m_xRemoveListener, uno::UNO_QUERY ) );
667 // pEntry->m_bHasOptions = m_pManager->supportsOptions( xPackage );
668 // pEntry->m_bUser = xPackage->getRepositoryName().equals( USER_PACKAGE_MANAGER );
669 // pEntry->m_bShared = xPackage->getRepositoryName().equals( SHARED_PACKAGE_MANAGER );
670 // pEntry->m_bNew = m_bInCheckMode;
671 // pEntry->m_bMissingLic = bLicenseMissing;
673 // if ( bLicenseMissing )
674 // pEntry->m_sErrorText = DialogHelper::getResourceString( RID_STR_ERROR_MISSING_LICENSE );
676 //access to m_nActive must be guarded
677 if ( !m_bInCheckMode && m_bHasActive && ( m_nActive >= nPos ) )
678 m_nActive += 1;
680 guard.clear();
682 if ( IsReallyVisible() )
683 Invalidate();
685 m_bNeedsRecalc = true;
687 return nPos;
690 // -----------------------------------------------------------------------
691 void ClientBox::DoScroll( long nDelta )
693 m_nTopIndex += nDelta;
694 Point aNewSBPt( m_pScrollBar->GetPosPixel() );
696 Rectangle aScrRect( Point(), GetOutputSizePixel() );
697 aScrRect.Right() -= m_pScrollBar->GetSizePixel().Width();
698 Scroll( 0, -nDelta, aScrRect );
700 m_pScrollBar->SetPosPixel( aNewSBPt );
703 // -----------------------------------------------------------------------
704 IMPL_LINK( ClientBox, ScrollHdl, ScrollBar*, pScrBar )
706 DoScroll( pScrBar->GetDelta() );
708 return 1;
711 } //namespace dp_gui
713 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */