summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2013-03-01 16:15:05 +0000
committerCaolán McNamara <caolanm@redhat.com>2013-03-01 16:36:03 +0000
commit16d7194ee73786c212e8639d41c7c31735ca930a (patch)
tree2aa41764d471319d829b594f20a40e5f58455ced
parentbef96b4c6ed9a286031714b636fdb9f14c7dc7c6 (diff)
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
-rw-r--r--vcl/inc/vcl/layout.hxx13
-rw-r--r--vcl/source/window/builder.cxx24
-rw-r--r--vcl/source/window/layout.cxx43
3 files changed, 67 insertions, 13 deletions
diff --git a/vcl/inc/vcl/layout.hxx b/vcl/inc/vcl/layout.hxx
index 239e84cf60cd..457a389f19b9 100644
--- a/vcl/inc/vcl/layout.hxx
+++ b/vcl/inc/vcl/layout.hxx
@@ -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:
diff --git a/vcl/source/window/builder.cxx b/vcl/source/window/builder.cxx
index 8654b658027d..3716a02bd644 100644
--- a/vcl/source/window/builder.cxx
+++ b/vcl/source/window/builder.cxx
@@ -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;
diff --git a/vcl/source/window/layout.cxx b/vcl/source/window/layout.cxx
index 934e08e8b521..88790f3e6401 100644
--- a/vcl/source/window/layout.cxx
+++ b/vcl/source/window/layout.cxx
@@ -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);