Kaydet (Commit) 4b0aafb8 authored tarafından Andre Fischer's avatar Andre Fischer

122247: Improved focus traveling in sidebar.

üst 13458077
......@@ -86,4 +86,13 @@ void NavigatorWrapper::UpdateNavigator (void)
}
void NavigatorWrapper::GetFocus (void)
{
maNavigator.GrabFocus();
}
} } // end of namespace sd::sidebar
......@@ -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);
......
......@@ -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;
}
......
......@@ -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,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment