Kaydet (Commit) 16d7194e authored tarafından Caolán McNamara's avatar Caolán McNamara

sort frame labels before frame contents for tab traversal

If there is more than one widget with the same mnemonic, and one is a frame
label, then we need to sort frame labels before frame bodies in the tab
traversal order. Otherwise if the focus is in the body of a frame whose label
has that shortcut and the shortcut is pressed again, the traversal through
following widgets will encounter the frame label as the next candidate, leading
back to the starting point and not onwards to the next widget using that
shortcut.

Frame labels have type "label" in the .ui, so suck that out to designate which
widget is the frame label at load time.

Change-Id: Ie21ed87867bd0c983981a3a8f3318b3cf598c1d6
üst bef96b4c
......@@ -436,9 +436,20 @@ public:
class VCL_DLLPUBLIC VclFrame : public VclBin
{
private:
Window *m_pLabel;
private:
friend class VclBuilder;
void designate_label(Window *pWindow);
public:
VclFrame(Window *pParent) : VclBin(pParent) {}
VclFrame(Window *pParent)
: VclBin(pParent)
, m_pLabel(NULL)
{
}
void set_label(const OUString &rLabel);
virtual Window *get_child();
virtual const Window *get_child() const;
Window *get_label_widget();
const Window *get_label_widget() const;
protected:
......
......@@ -1425,7 +1425,20 @@ bool VclBuilder::sortIntoBestTabTraversalOrder::operator()(const Window *pA, con
return false;
}
//honour relative box positions with pack group
return m_pBuilder->get_window_packing_data(pA).m_nPosition < m_pBuilder->get_window_packing_data(pB).m_nPosition;
bPackA = m_pBuilder->get_window_packing_data(pA).m_nPosition;
bPackB = m_pBuilder->get_window_packing_data(pB).m_nPosition;
if (bPackA < bPackB)
return true;
if (bPackA > bPackB)
return false;
//sort labels of Frames before body
if (pA->GetParent() == pB->GetParent())
{
const VclFrame *pFrameParent = dynamic_cast<const VclFrame*>(pA->GetParent());
if (pFrameParent && pA == pFrameParent->get_label_widget())
return true;
}
return false;
}
void VclBuilder::handleChild(Window *pParent, xmlreader::XmlReader &reader)
......@@ -1487,6 +1500,15 @@ void VclBuilder::handleChild(Window *pParent, xmlreader::XmlReader &reader)
}
else
{
// We want to sort labels before contents of frames
// for key board traversal, especially if there
// are multiple widgets using the same mnemonic
if (sType.equals("label"))
{
if (VclFrame *pFrameParent = dynamic_cast<VclFrame*>(pParent))
pFrameParent->designate_label(pCurrentChild);
}
//To-Do make reorder a virtual in Window, move this foo
//there and see above
std::vector<Window*> aChilds;
......
......@@ -1088,10 +1088,8 @@ Size VclFrame::calculateRequisition() const
{
Size aRet(0, 0);
WindowImpl* pWindowImpl = ImplGetWindowImpl();
const Window *pChild = get_child();
const Window *pLabel = pChild != pWindowImpl->mpLastChild ? pWindowImpl->mpLastChild : NULL;
const Window *pLabel = get_label_widget();
if (pChild && pChild->IsVisible())
aRet = getLayoutRequisition(*pChild);
......@@ -1121,11 +1119,8 @@ void VclFrame::setAllocation(const Size &rAllocation)
rAllocation.Height() - rFrameStyle.top - rFrameStyle.bottom);
Point aChildPos(rFrameStyle.left, rFrameStyle.top);
WindowImpl* pWindowImpl = ImplGetWindowImpl();
//The label widget is the last (of two) children
Window *pChild = get_child();
Window *pLabel = pChild != pWindowImpl->mpLastChild ? pWindowImpl->mpLastChild : NULL;
Window *pLabel = get_label_widget();
if (pLabel && pLabel->IsVisible())
{
......@@ -1141,12 +1136,22 @@ void VclFrame::setAllocation(const Size &rAllocation)
setLayoutAllocation(*pChild, aChildPos, aAllocation);
}
void VclFrame::designate_label(Window *pWindow)
{
assert(pWindow->GetParent() == this);
m_pLabel = pWindow;
}
const Window *VclFrame::get_label_widget() const
{
//The label widget is the last (of two) children
const Window *pChild = get_child();
assert(GetChildCount() == 2);
if (m_pLabel)
return m_pLabel;
//The label widget is normally the first (of two) children
const WindowImpl* pWindowImpl = ImplGetWindowImpl();
return pChild != pWindowImpl->mpLastChild ? pWindowImpl->mpLastChild : NULL;
if (pWindowImpl->mpFirstChild == pWindowImpl->mpLastChild) //no label exists
return NULL;
return pWindowImpl->mpFirstChild;
}
Window *VclFrame::get_label_widget()
......@@ -1154,9 +1159,25 @@ Window *VclFrame::get_label_widget()
return const_cast<Window*>(const_cast<const VclFrame*>(this)->get_label_widget());
}
const Window *VclFrame::get_child() const
{
assert(GetChildCount() == 2);
//The child widget is the normally the last (of two) children
const WindowImpl* pWindowImpl = ImplGetWindowImpl();
if (!m_pLabel)
return pWindowImpl->mpLastChild;
if (pWindowImpl->mpFirstChild == pWindowImpl->mpLastChild) //only label exists
return NULL;
return pWindowImpl->mpLastChild;
}
Window *VclFrame::get_child()
{
return const_cast<Window*>(const_cast<const VclFrame*>(this)->get_child());
}
void VclFrame::set_label(const rtl::OUString &rLabel)
{
//The label widget is the last (of two) children
Window *pLabel = get_label_widget();
assert(pLabel);
pLabel->SetText(rLabel);
......
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