[Libreoffice-commits] core.git: Branch 'aoo/trunk' - sd/source sfx2/source

Andre Fischer af at apache.org
Thu May 23 09:07:26 PDT 2013


 sd/source/ui/sidebar/NavigatorWrapper.cxx |    9 +
 sd/source/ui/sidebar/NavigatorWrapper.hxx |    1 
 sfx2/source/sidebar/FocusManager.cxx      |  150 ++++++++++++++++++++++++++----
 sfx2/source/sidebar/FocusManager.hxx      |   18 +++
 4 files changed, 158 insertions(+), 20 deletions(-)

New commits:
commit 4b0aafb8182b1f86b9edf947a4c62ff9948c6676
Author: Andre Fischer <af at apache.org>
Date:   Thu May 23 14:30:17 2013 +0000

    122247: Improved focus traveling in sidebar.

diff --git a/sd/source/ui/sidebar/NavigatorWrapper.cxx b/sd/source/ui/sidebar/NavigatorWrapper.cxx
index 6a4f3bc..eeaa7d4 100644
--- a/sd/source/ui/sidebar/NavigatorWrapper.cxx
+++ b/sd/source/ui/sidebar/NavigatorWrapper.cxx
@@ -86,4 +86,13 @@ void NavigatorWrapper::UpdateNavigator (void)
 }
 
 
+
+
+void NavigatorWrapper::GetFocus (void)
+{
+    maNavigator.GrabFocus();
+}
+
+
+
 } } // end of namespace sd::sidebar
diff --git a/sd/source/ui/sidebar/NavigatorWrapper.hxx b/sd/source/ui/sidebar/NavigatorWrapper.hxx
index 83370d1..16ee30a 100644
--- a/sd/source/ui/sidebar/NavigatorWrapper.hxx
+++ b/sd/source/ui/sidebar/NavigatorWrapper.hxx
@@ -55,6 +55,7 @@ public:
 
     // Control
     virtual void Resize (void);
+    virtual void GetFocus (void);
 
     // From ILayoutableWindow
     virtual css::ui::LayoutSize GetHeightForWidth (const sal_Int32 nWidth);
diff --git a/sfx2/source/sidebar/FocusManager.cxx b/sfx2/source/sidebar/FocusManager.cxx
index 9d29355..f568e52 100644
--- a/sfx2/source/sidebar/FocusManager.cxx
+++ b/sfx2/source/sidebar/FocusManager.cxx
@@ -47,7 +47,9 @@ FocusManager::FocusManager (const ::boost::function<void(const Panel&)>& rShowPa
     : mpDeckTitleBar(),
       maPanels(),
       maButtons(),
-      maShowPanelFunctor(rShowPanelFunctor)
+      maShowPanelFunctor(rShowPanelFunctor),
+      mbObservingContentControlFocus(false),
+      mpFirstFocusedContentControl(NULL)
 {
 }
 
@@ -259,17 +261,23 @@ bool FocusManager::IsAnyButtonFocused (void) const
 
 void FocusManager::FocusDeckTitle (void)
 {
-    if (IsDeckTitleVisible())
+    if (mpDeckTitleBar != NULL)
     {
-        ToolBox& rToolBox = mpDeckTitleBar->GetToolBox();
-        if (rToolBox.GetItemCount() > 0)
+        if (IsDeckTitleVisible())
+        {
+            mpDeckTitleBar->GrabFocus();
+        }
+        else if (mpDeckTitleBar->GetToolBox().GetItemCount() > 0)
         {
+            ToolBox& rToolBox = mpDeckTitleBar->GetToolBox();
             rToolBox.GrabFocus();
             rToolBox.Invalidate();
         }
+        else
+            FocusPanel(0, false);
     }
     else
-        FocusPanel(0);
+        FocusPanel(0, false);
 }
 
 
@@ -283,10 +291,31 @@ bool FocusManager::IsDeckTitleVisible (void) const
 
 
 
-void FocusManager::FocusPanel (const sal_Int32 nPanelIndex)
+bool FocusManager::IsPanelTitleVisible (const sal_Int32 nPanelIndex) const
 {
     if (nPanelIndex<0 || nPanelIndex>=static_cast<sal_Int32>(maPanels.size()))
+        return false;
+
+    TitleBar* pTitleBar = maPanels[nPanelIndex]->GetTitleBar();
+    if (pTitleBar==NULL)
+        return false;
+    return pTitleBar->IsVisible();
+}
+
+
+
+
+void FocusManager::FocusPanel (
+    const sal_Int32 nPanelIndex,
+    const bool bFallbackToDeckTitle)
+{
+    if (nPanelIndex<0 || nPanelIndex>=static_cast<sal_Int32>(maPanels.size()))
+    {
+        if (bFallbackToDeckTitle)
+            FocusDeckTitle();
         return;
+    }
+
     Panel& rPanel (*maPanels[nPanelIndex]);
     TitleBar* pTitleBar = rPanel.GetTitleBar();
     if (pTitleBar!=NULL && pTitleBar->IsVisible())
@@ -294,8 +323,21 @@ void FocusManager::FocusPanel (const sal_Int32 nPanelIndex)
         rPanel.SetExpanded(true);
         pTitleBar->GrabFocus();
     }
+    else if (bFallbackToDeckTitle)
+    {
+        // The panel title is not visible, fall back to the deck
+        // title.
+        // Make sure that the desk title is visible here to prevent a
+        // loop when both the title of panel 0 and the deck title are
+        // not present.
+        if (IsDeckTitleVisible())
+            FocusDeckTitle();
+        else
+            FocusPanelContent(nPanelIndex);
+    }
     else
         FocusPanelContent(nPanelIndex);
+
     if (maShowPanelFunctor)
         maShowPanelFunctor(rPanel);
 }
@@ -307,7 +349,11 @@ void FocusManager::FocusPanelContent (const sal_Int32 nPanelIndex)
 {
     Window* pWindow = VCLUnoHelper::GetWindow(maPanels[nPanelIndex]->GetElementWindow());
     if (pWindow != NULL)
+    {
+        mbObservingContentControlFocus = true;
         pWindow->GrabFocus();
+        mbObservingContentControlFocus = false;
+    }
 }
 
 
@@ -327,7 +373,7 @@ void FocusManager::ClickButton (const sal_Int32 nButtonIndex)
     maButtons[nButtonIndex]->Click();
     if (nButtonIndex > 0)
         if ( ! maPanels.empty())
-            FocusPanel(0);
+            FocusPanel(0, true);
     maButtons[nButtonIndex]->GetParent()->Invalidate();
 }
 
@@ -391,11 +437,46 @@ bool FocusManager::MoveFocusInsidePanel (
 
 
 
+bool FocusManager::MoveFocusInsideDeckTitle (
+    const FocusLocation aFocusLocation,
+    const sal_Int32 nDirection)
+{
+    // Note that when the title bar of the first (and only) panel is
+    // not visible then the deck title takes its place and the focus
+    // is moved between a) deck title, b) deck closer and c) content
+    // of panel 0.
+    const bool bHasToolBoxItem (
+        mpDeckTitleBar->GetToolBox().GetItemCount() > 0);
+    switch (aFocusLocation.meComponent)
+    {
+        case  PC_DeckTitle:
+            if (nDirection<0 && ! IsPanelTitleVisible(0))
+                FocusPanelContent(0);
+            else if (bHasToolBoxItem)
+                mpDeckTitleBar->GetToolBox().GrabFocus();
+            return true;
+
+        case PC_DeckToolBox:
+            if (nDirection>0 && ! IsPanelTitleVisible(0))
+                FocusPanelContent(0);
+            else
+                mpDeckTitleBar->GrabFocus();
+            return true;
+
+        default:
+            return false;
+    }
+}
+
+
+
+
 void FocusManager::HandleKeyEvent (
     const KeyCode& rKeyCode,
     const Window& rWindow)
 {
     const FocusLocation aLocation (GetFocusLocation(rWindow));
+    mpLastFocusedWindow = NULL;
 
     switch (rKeyCode.GetCode())
     {
@@ -440,21 +521,29 @@ void FocusManager::HandleKeyEvent (
             return;
 
         case KEY_TAB:
+        {
+            const sal_Int32 nDirection (
+                rKeyCode.IsShift()
+                    ? -1
+                    : +1);
             switch (aLocation.meComponent)
             {
                 case PC_PanelTitle:
                 case PC_PanelToolBox:
                 case PC_PanelContent:
-                    if (rKeyCode.IsShift())
-                        MoveFocusInsidePanel(aLocation, -1);
-                    else
-                        MoveFocusInsidePanel(aLocation, +1);
+                    MoveFocusInsidePanel(aLocation, nDirection);
+                    break;
+
+                case PC_DeckTitle:
+                case PC_DeckToolBox:
+                    MoveFocusInsideDeckTitle(aLocation, nDirection);
                     break;
 
                 default:
                     break;
             }
             break;
+        }
 
         case KEY_LEFT:
         case KEY_UP:
@@ -465,7 +554,7 @@ void FocusManager::HandleKeyEvent (
                 case PC_PanelContent:
                     // Go to previous panel or the deck title.
                     if (aLocation.mnIndex > 0)
-                        FocusPanel(aLocation.mnIndex-1);
+                        FocusPanel(aLocation.mnIndex-1, true);
                     else if (IsDeckTitleVisible())
                         FocusDeckTitle();
                     else
@@ -481,7 +570,7 @@ void FocusManager::HandleKeyEvent (
                 case PC_TabBar:
                     // Go to previous tab bar item.
                     if (aLocation.mnIndex == 0)
-                        FocusPanel(maPanels.size()-1);
+                        FocusPanel(maPanels.size()-1, true);
                     else
                         FocusButton((aLocation.mnIndex + maButtons.size() - 1) % maButtons.size());
                     break;
@@ -500,7 +589,7 @@ void FocusManager::HandleKeyEvent (
                 case PC_PanelContent:
                     // Go to next panel.
                     if (aLocation.mnIndex < static_cast<sal_Int32>(maPanels.size())-1)
-                        FocusPanel(aLocation.mnIndex+1);
+                        FocusPanel(aLocation.mnIndex+1, false);
                     else
                         FocusButton(0);
                     break;
@@ -508,7 +597,10 @@ void FocusManager::HandleKeyEvent (
                 case PC_DeckTitle:
                 case PC_DeckToolBox:
                     // Focus the first panel.
-                    FocusPanel(0);
+                    if (IsPanelTitleVisible(0))
+                        FocusPanel(0, false);
+                    else
+                        FocusButton(0);
                     break;
 
                 case PC_TabBar:
@@ -518,7 +610,7 @@ void FocusManager::HandleKeyEvent (
                     else if (IsDeckTitleVisible())
                         FocusDeckTitle();
                     else
-                        FocusPanel(0);
+                        FocusPanel(0, true);
                     break;
 
                 default:
@@ -591,8 +683,8 @@ IMPL_LINK(FocusManager, ChildEventListener, VclSimpleEvent*, pEvent)
         {
             KeyEvent* pKeyEvent = static_cast<KeyEvent*>(pWindowEvent->GetData());
 
-            // Go up the window hierarchy to find the parent of the
-            // event source which is known to us.
+            // Go up the window hierarchy to find out whether the
+            // parent of the event source is known to us.
             Window* pWindow = pSource;
             FocusLocation aLocation (PC_None, -1);
             while (true)
@@ -611,7 +703,17 @@ IMPL_LINK(FocusManager, ChildEventListener, VclSimpleEvent*, pEvent)
                 {
                     case KEY_ESCAPE:
                         // Return focus back to the panel title.
-                        FocusPanel(aLocation.mnIndex);
+                        FocusPanel(aLocation.mnIndex, true);
+                        break;
+
+                    case KEY_TAB:
+                        if (mpFirstFocusedContentControl!=NULL
+                            && mpLastFocusedWindow == mpFirstFocusedContentControl)
+                        {
+                            // Move focus back to panel (or deck)
+                            // title.
+                            FocusPanel(aLocation.mnIndex, true);
+                        }
                         break;
 
                     default:
@@ -621,6 +723,16 @@ IMPL_LINK(FocusManager, ChildEventListener, VclSimpleEvent*, pEvent)
             return 1;
         }
 
+        case VCLEVENT_WINDOW_GETFOCUS:
+            // Keep track of focused controls in panel content.
+            // Remember the first focused control.  When it is later
+            // focused again due to pressing the TAB key then the
+            // focus is moved to the panel or deck title.
+            mpLastFocusedWindow = pSource;
+            if (mbObservingContentControlFocus)
+                mpFirstFocusedContentControl = pSource;
+            break;
+
         default:
             break;
     }
diff --git a/sfx2/source/sidebar/FocusManager.hxx b/sfx2/source/sidebar/FocusManager.hxx
index 019b50c..4ca5b92 100644
--- a/sfx2/source/sidebar/FocusManager.hxx
+++ b/sfx2/source/sidebar/FocusManager.hxx
@@ -76,6 +76,9 @@ private:
     ::std::vector<Panel*> maPanels;
     ::std::vector<Button*> maButtons;
     const ::boost::function<void(const Panel&)> maShowPanelFunctor;
+    bool mbObservingContentControlFocus;
+    Window* mpFirstFocusedContentControl;
+    Window* mpLastFocusedWindow;
 
     enum PanelComponent
     {
@@ -118,17 +121,30 @@ private:
 
     void FocusDeckTitle (void);
     bool IsDeckTitleVisible (void) const;
+    bool IsPanelTitleVisible (const sal_Int32 nPanelIndex) const;
 
     /** Set the focus to the title bar of the panel or, if the the
         title bar is not visible, directly to the panel.
+        @param nPanelIndex
+            Index of the panel to focus.
+        @param bFallbackToDeckTitle
+            When the panel title bar is not visible then The fallback
+            bias defines whether to focus the deck (true) or the panel
+            content (false) will be focused instead.
     */
-    void FocusPanel (const sal_Int32 nPanelIndex);
+    void FocusPanel (
+        const sal_Int32 nPanelIndex,
+        const bool bFallbackToDeckTitle);
+
     void FocusPanelContent (const sal_Int32 nPanelIndex);
     void FocusButton (const sal_Int32 nButtonIndex);
     void ClickButton (const sal_Int32 nButtonIndex);
     bool MoveFocusInsidePanel (
         const FocusLocation aLocation,
         const sal_Int32 nDirection);
+    bool MoveFocusInsideDeckTitle (
+        const FocusLocation aLocation,
+        const sal_Int32 nDirection);
 
     void HandleKeyEvent (
         const KeyCode& rKeyCode,


More information about the Libreoffice-commits mailing list