diff options
author | Luke Symes <allsymes@gmail.com> | 2011-06-22 16:40:50 +1200 |
---|---|---|
committer | Tor Lillqvist <tlillqvist@novell.com> | 2011-06-22 13:59:49 +0300 |
commit | e6b064a296e5774f124226575ac3aebb68e31133 (patch) | |
tree | 2f6b2ff3e9cb7373500cf1b2ead29915a1fb1394 | |
parent | 3305a95b2951a7089c268938319552ccda4b5f1c (diff) |
Restore the scroll position of the CustomAnimationList when it is updated.
We save the position of the listview, and also the selection boundary.
We move with the selection if it goes out of view, otherwise we
restore the original scroll position. If the selection was out of view
to start with, we scroll up/down to the first few entries.
Signed-off-by: Tor Lillqvist <tlillqvist@novell.com>
-rw-r--r-- | sd/source/ui/animations/CustomAnimationList.cxx | 86 |
1 files changed, 80 insertions, 6 deletions
diff --git a/sd/source/ui/animations/CustomAnimationList.cxx b/sd/source/ui/animations/CustomAnimationList.cxx index 421344b34cfa..99b68d6711d9 100644 --- a/sd/source/ui/animations/CustomAnimationList.cxx +++ b/sd/source/ui/animations/CustomAnimationList.cxx @@ -587,21 +587,51 @@ void stl_append_effect_func::operator()(CustomAnimationEffectPtr pEffect) void CustomAnimationList::update() { mbIgnorePaint = true; + SetUpdateMode( sal_False ); CustomAnimationListEntry* pEntry = 0; std::list< CustomAnimationEffectPtr > aExpanded; std::list< CustomAnimationEffectPtr > aSelected; - CustomAnimationEffectPtr pFirstVisibleEffect; + CustomAnimationEffectPtr pFirstSelEffect; + CustomAnimationEffectPtr pLastSelEffect; + long nFirstVis = -1; + long nLastVis = -1; + long nFirstSelOld = -1; + long nFirstSelNew = -1; + long nLastSelOld = -1; + long nLastSelNew = -1; + bool bMoved = false; + bool bMovedUp = false; + bool bMovedDown = false; if( mpMainSequence.get() ) { - // save selection and expand states - pEntry = static_cast<CustomAnimationListEntry*>(FirstVisible()); + // save scroll position + pEntry = static_cast<CustomAnimationListEntry*>(GetFirstEntryInView()); + if( pEntry ) + nFirstVis = GetAbsPos( pEntry ); + + pEntry = static_cast<CustomAnimationListEntry*>(GetLastEntryInView()); + if( pEntry ) + nLastVis = GetAbsPos( pEntry ); + + pEntry = static_cast<CustomAnimationListEntry*>(FirstSelected()); if( pEntry ) - pFirstVisibleEffect = pEntry->getEffect(); + { + pFirstSelEffect = pEntry->getEffect(); + nFirstSelOld = GetAbsPos( pEntry ); + } + pEntry = static_cast<CustomAnimationListEntry*>(LastSelected()); + if( pEntry ) + { + pLastSelEffect = pEntry->getEffect(); + nLastSelOld = GetAbsPos( pEntry ); + } + + // save selection and expand states pEntry = static_cast<CustomAnimationListEntry*>(First()); while( pEntry ) @@ -668,15 +698,59 @@ void CustomAnimationList::update() if( std::find( aSelected.begin(), aSelected.end(), pEffect ) != aSelected.end() ) Select( pEntry ); - if( pFirstVisibleEffect == pEffect ) - MakeVisible( pEntry ); + if( pEffect == pFirstSelEffect ) + nFirstSelNew = GetAbsPos( pEntry ); + + if( pEffect == pLastSelEffect ) + nLastSelNew = GetAbsPos( pEntry ); } pEntry = static_cast<CustomAnimationListEntry*>(Next( pEntry )); } + + // Scroll to a selected entry, depending on where the selection moved. + bMoved = nFirstSelNew != nFirstSelOld; + bMovedUp = nFirstSelNew < nFirstSelOld; + bMovedDown = nFirstSelNew > nFirstSelOld; + + if( bMoved && nLastSelOld < nFirstVis && nLastSelNew < nFirstVis ) + { + // The selection is above the visible area. + // Scroll up to show the last few selected entries. + if( nLastSelNew - (nLastVis - nFirstVis) > nFirstSelNew) + { + // The entries in the selection range can't fit in view. + // Scroll so the last selected entry is last in view. + ScrollToAbsPos( nLastSelNew - (nLastVis - nFirstVis) ); + } + else + ScrollToAbsPos( nFirstSelNew ); + } + else if( bMoved && nFirstSelOld > nLastVis && nFirstSelNew > nLastVis ) + { + // The selection is below the visible area. + // Scroll down to the first few selected entries. + ScrollToAbsPos( nFirstSelNew ); + } + else if( bMovedUp && nFirstSelOld <= nFirstVis ) + { + // A visible entry has moved up out of view; scroll up one. + ScrollToAbsPos( nFirstVis - 1 ); + } + else if( bMovedDown && nLastSelOld >= nLastVis ) + { + // An entry has moved down out of view; scroll down one. + ScrollToAbsPos( nFirstVis + 1 ); + } + else + { + // The selection is still in view, or it hasn't moved. + ScrollToAbsPos( nFirstVis ); + } } mbIgnorePaint = false; + SetUpdateMode( sal_True ); Invalidate(); } |