You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openoffice.apache.org by af...@apache.org on 2013/05/23 16:30:18 UTC

svn commit: r1485730 - in /openoffice/trunk/main: sd/source/ui/sidebar/NavigatorWrapper.cxx sd/source/ui/sidebar/NavigatorWrapper.hxx sfx2/source/sidebar/FocusManager.cxx sfx2/source/sidebar/FocusManager.hxx

Author: af
Date: Thu May 23 14:30:17 2013
New Revision: 1485730

URL: http://svn.apache.org/r1485730
Log:
122247: Improved focus traveling in sidebar.

Modified:
    openoffice/trunk/main/sd/source/ui/sidebar/NavigatorWrapper.cxx
    openoffice/trunk/main/sd/source/ui/sidebar/NavigatorWrapper.hxx
    openoffice/trunk/main/sfx2/source/sidebar/FocusManager.cxx
    openoffice/trunk/main/sfx2/source/sidebar/FocusManager.hxx

Modified: openoffice/trunk/main/sd/source/ui/sidebar/NavigatorWrapper.cxx
URL: http://svn.apache.org/viewvc/openoffice/trunk/main/sd/source/ui/sidebar/NavigatorWrapper.cxx?rev=1485730&r1=1485729&r2=1485730&view=diff
==============================================================================
--- openoffice/trunk/main/sd/source/ui/sidebar/NavigatorWrapper.cxx (original)
+++ openoffice/trunk/main/sd/source/ui/sidebar/NavigatorWrapper.cxx Thu May 23 14:30:17 2013
@@ -86,4 +86,13 @@ void NavigatorWrapper::UpdateNavigator (
 }
 
 
+
+
+void NavigatorWrapper::GetFocus (void)
+{
+    maNavigator.GrabFocus();
+}
+
+
+
 } } // end of namespace sd::sidebar

Modified: openoffice/trunk/main/sd/source/ui/sidebar/NavigatorWrapper.hxx
URL: http://svn.apache.org/viewvc/openoffice/trunk/main/sd/source/ui/sidebar/NavigatorWrapper.hxx?rev=1485730&r1=1485729&r2=1485730&view=diff
==============================================================================
--- openoffice/trunk/main/sd/source/ui/sidebar/NavigatorWrapper.hxx (original)
+++ openoffice/trunk/main/sd/source/ui/sidebar/NavigatorWrapper.hxx Thu May 23 14:30:17 2013
@@ -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);

Modified: openoffice/trunk/main/sfx2/source/sidebar/FocusManager.cxx
URL: http://svn.apache.org/viewvc/openoffice/trunk/main/sfx2/source/sidebar/FocusManager.cxx?rev=1485730&r1=1485729&r2=1485730&view=diff
==============================================================================
--- openoffice/trunk/main/sfx2/source/sidebar/FocusManager.cxx (original)
+++ openoffice/trunk/main/sfx2/source/sidebar/FocusManager.cxx Thu May 23 14:30:17 2013
@@ -47,7 +47,9 @@ FocusManager::FocusManager (const ::boos
     : mpDeckTitleBar(),
       maPanels(),
       maButtons(),
-      maShowPanelFunctor(rShowPanelFunctor)
+      maShowPanelFunctor(rShowPanelFunctor),
+      mbObservingContentControlFocus(false),
+      mpFirstFocusedContentControl(NULL)
 {
 }
 
@@ -259,17 +261,23 @@ bool FocusManager::IsAnyButtonFocused (v
 
 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 (v
 
 
 
-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
         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 (co
 {
     Window* pWindow = VCLUnoHelper::GetWindow(maPanels[nPanelIndex]->GetElementWindow());
     if (pWindow != NULL)
+    {
+        mbObservingContentControlFocus = true;
         pWindow->GrabFocus();
+        mbObservingContentControlFocus = false;
+    }        
 }
 
 
@@ -327,7 +373,7 @@ void FocusManager::ClickButton (const sa
     maButtons[nButtonIndex]->Click();
     if (nButtonIndex > 0)
         if ( ! maPanels.empty())
-            FocusPanel(0);
+            FocusPanel(0, true);
     maButtons[nButtonIndex]->GetParent()->Invalidate();
 }
 
@@ -391,12 +437,47 @@ 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())
     {
         case KEY_SPACE:
@@ -440,22 +521,30 @@ 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:
             switch (aLocation.meComponent)
@@ -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, ChildEventListen
         {
             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, ChildEventListen
                 {
                     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, ChildEventListen
             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;
     }

Modified: openoffice/trunk/main/sfx2/source/sidebar/FocusManager.hxx
URL: http://svn.apache.org/viewvc/openoffice/trunk/main/sfx2/source/sidebar/FocusManager.hxx?rev=1485730&r1=1485729&r2=1485730&view=diff
==============================================================================
--- openoffice/trunk/main/sfx2/source/sidebar/FocusManager.hxx (original)
+++ openoffice/trunk/main/sfx2/source/sidebar/FocusManager.hxx Thu May 23 14:30:17 2013
@@ -76,7 +76,10 @@ private:
     ::std::vector<Panel*> maPanels;
     ::std::vector<Button*> maButtons;
     const ::boost::function<void(const Panel&)> maShowPanelFunctor;
-    
+    bool mbObservingContentControlFocus;
+    Window* mpFirstFocusedContentControl;
+    Window* mpLastFocusedWindow;
+
     enum PanelComponent
     {
         PC_DeckTitle,
@@ -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,