summaryrefslogtreecommitdiff
path: root/sfx2/source
diff options
context:
space:
mode:
authorAndre Fischer <af@apache.org>2013-05-23 14:30:17 +0000
committerCaolán McNamara <caolanm@redhat.com>2013-05-23 20:00:50 +0100
commitce7dafae81f226bd441723df49f68005919df91f (patch)
treea8beb52b0f4ace2682acd1e8cacd1696ff7dd524 /sfx2/source
parentac2bac4a8d5c7e1593f19a18ca0b5a65e1a3fd82 (diff)
Resolves: #i122247# Improved focus traveling in sidebar
(cherry picked from commit 4b0aafb8182b1f86b9edf947a4c62ff9948c6676) Change-Id: Ieae8e44fe147309cc3ff447a6dbc375d1b2f34d0 (cherry picked from commit ab0360c309adcd131a9e6c1f02abc82486d09a46)
Diffstat (limited to 'sfx2/source')
-rw-r--r--sfx2/source/sidebar/FocusManager.cxx150
-rw-r--r--sfx2/source/sidebar/FocusManager.hxx18
2 files changed, 148 insertions, 20 deletions
diff --git a/sfx2/source/sidebar/FocusManager.cxx b/sfx2/source/sidebar/FocusManager.cxx
index 51d4c5e51b21..69c2e53ef887 100644
--- a/sfx2/source/sidebar/FocusManager.cxx
+++ b/sfx2/source/sidebar/FocusManager.cxx
@@ -42,7 +42,9 @@ FocusManager::FocusManager (const ::boost::function<void(const Panel&)>& rShowPa
: mpDeckTitleBar(),
maPanels(),
maButtons(),
- maShowPanelFunctor(rShowPanelFunctor)
+ maShowPanelFunctor(rShowPanelFunctor),
+ mbObservingContentControlFocus(false),
+ mpFirstFocusedContentControl(NULL)
{
}
@@ -254,17 +256,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);
}
@@ -278,10 +286,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())
@@ -289,8 +318,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);
}
@@ -302,7 +344,11 @@ void FocusManager::FocusPanelContent (const sal_Int32 nPanelIndex)
{
Window* pWindow = VCLUnoHelper::GetWindow(maPanels[nPanelIndex]->GetElementWindow());
if (pWindow != NULL)
+ {
+ mbObservingContentControlFocus = true;
pWindow->GrabFocus();
+ mbObservingContentControlFocus = false;
+ }
}
@@ -322,7 +368,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();
}
@@ -386,11 +432,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())
{
@@ -435,21 +516,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:
@@ -460,7 +549,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
@@ -476,7 +565,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;
@@ -495,7 +584,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;
@@ -503,7 +592,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:
@@ -513,7 +605,7 @@ void FocusManager::HandleKeyEvent (
else if (IsDeckTitleVisible())
FocusDeckTitle();
else
- FocusPanel(0);
+ FocusPanel(0, true);
break;
default:
@@ -586,8 +678,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)
@@ -606,7 +698,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:
@@ -616,6 +718,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 c06642f39497..54135cc39cff 100644
--- a/sfx2/source/sidebar/FocusManager.hxx
+++ b/sfx2/source/sidebar/FocusManager.hxx
@@ -72,6 +72,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
{
@@ -114,17 +117,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,