diff options
author | Jan-Marek Glogowski <glogow@fbihome.de> | 2019-05-17 02:38:43 +0200 |
---|---|---|
committer | Jan-Marek Glogowski <glogow@fbihome.de> | 2019-05-23 07:02:45 +0200 |
commit | 73f8222109c3091d5119ed47eac5cad4a55b2212 (patch) | |
tree | 42ae5a80036c88ec7d10b92221c0927fddec578f /starmath | |
parent | 2fdcd86ac08c0ed033398bdb85ed04b64f50c633 (diff) |
tdf#65587 SM handle page keys in the ElementControl
The page handling implementation is a little bit tricky, because
the elemnt list is not handled like a grid but a list. Normally
one would keep the horizontal cell and just scroll vertically.
Instead this implements a kind of circle.
Vertical offset is consistet, so you have the same amount of
steps for up and down, but up runs left and down runs right.
Change-Id: I296a46e98f7e00a59fd0a0ba358c981b49ac86cd
Reviewed-on: https://gerrit.libreoffice.org/72793
Tested-by: Jenkins
Reviewed-by: Jan-Marek Glogowski <glogow@fbihome.de>
Diffstat (limited to 'starmath')
-rw-r--r-- | starmath/inc/ElementsDockingWindow.hxx | 5 | ||||
-rw-r--r-- | starmath/source/ElementsDockingWindow.cxx | 111 |
2 files changed, 98 insertions, 18 deletions
diff --git a/starmath/inc/ElementsDockingWindow.hxx b/starmath/inc/ElementsDockingWindow.hxx index e102250652c0..874735a8a44f 100644 --- a/starmath/inc/ElementsDockingWindow.hxx +++ b/starmath/inc/ElementsDockingWindow.hxx @@ -99,7 +99,12 @@ class SmElementsControl : public Control void addElements(const std::pair<const char*, const char*> aElementsArray[], sal_uInt16 size); SmElement* current() const; bool hasRollover() const { return m_nCurrentRolloverElement != SAL_MAX_UINT16; } + void stepFocus(const bool bBackward); + void pageFocus(const bool bBackward); + // common code of page and step focus + inline void scrollToElement(const bool, const SmElement*); + inline sal_uInt16 nextElement(const bool, const sal_uInt16, const sal_uInt16); void build(); diff --git a/starmath/source/ElementsDockingWindow.cxx b/starmath/source/ElementsDockingWindow.cxx index cbf8c80865b0..385d33d795b5 100644 --- a/starmath/source/ElementsDockingWindow.cxx +++ b/starmath/source/ElementsDockingWindow.cxx @@ -601,27 +601,23 @@ void SmElementsControl::LoseFocus() Invalidate(); } -void SmElementsControl::stepFocus(const bool bBackward) +sal_uInt16 SmElementsControl::nextElement(const bool bBackward, const sal_uInt16 nStartPos, const sal_uInt16 nLastElement) { - const sal_uInt16 nStartPos = m_nCurrentElement; - const sal_uInt16 nElementCount = maElementList.size(); sal_uInt16 nPos = nStartPos; - assert(nPos < nElementCount); while (true) { if (bBackward) { if (nPos == 0) - nPos = nElementCount - 1; - else - nPos--; + break; + nPos--; } else { + if (nPos == nLastElement) + break; nPos++; - if (nPos == nElementCount) - nPos = 0; } if (nStartPos == nPos) @@ -630,22 +626,94 @@ void SmElementsControl::stepFocus(const bool bBackward) break; } + return nPos; +} + +void SmElementsControl::scrollToElement(const bool bBackward, const SmElement *pCur) +{ + long nScrollPos = mxScroll->GetThumbPos(); + if (mbVerticalMode) + { + nScrollPos += pCur->mBoxLocation.X(); + if (!bBackward) + nScrollPos += pCur->mBoxSize.Width() - GetOutputSizePixel().Width(); + } + else + { + nScrollPos += pCur->mBoxLocation.Y(); + if (!bBackward) + nScrollPos += pCur->mBoxSize.Height() - GetOutputSizePixel().Height(); + } + mxScroll->DoScroll(nScrollPos); +} + +void SmElementsControl::stepFocus(const bool bBackward) +{ + const sal_uInt16 nStartPos = m_nCurrentElement; + const sal_uInt16 nLastElement = (maElementList.size() ? maElementList.size() - 1 : 0); + assert(nStartPos <= nLastElement); + + sal_uInt16 nPos = nextElement(bBackward, nStartPos, nLastElement); if (nStartPos != nPos) { m_nCurrentElement = nPos; - if (!hasRollover()) + m_nCurrentRolloverElement = SAL_MAX_UINT16; + + const tools::Rectangle outputRect(Point(0,0), GetOutputSizePixel()); + const SmElement *pCur = maElementList[nPos].get(); + tools::Rectangle elementRect(pCur->mBoxLocation, pCur->mBoxSize); + if (!outputRect.IsInside(elementRect)) + scrollToElement(bBackward, pCur); + Invalidate(); + } +} + +void SmElementsControl::pageFocus(const bool bBackward) +{ + const sal_uInt16 nStartPos = m_nCurrentElement; + const sal_uInt16 nLastElement = (maElementList.size() ? maElementList.size() - 1 : 0); + assert(nStartPos <= nLastElement); + tools::Rectangle outputRect(Point(0,0), GetOutputSizePixel()); + sal_uInt16 nPrevPos = nStartPos; + sal_uInt16 nPos = nPrevPos; + + bool bMoved = false; + while (true) + { + nPrevPos = nPos; + nPos = nextElement(bBackward, nPrevPos, nLastElement); + if (nPrevPos == nPos) + break; + + m_nCurrentRolloverElement = SAL_MAX_UINT16; + + SmElement *pCur = maElementList[nPos].get(); + tools::Rectangle elementRect(pCur->mBoxLocation, pCur->mBoxSize); + if (!outputRect.IsInside(elementRect)) { - const SmElement *pCur = current(); - tools::Rectangle elementRect(pCur->mBoxLocation, pCur->mBoxSize); - tools::Rectangle outputRect(Point(0,0), GetOutputSizePixel()); - if (!outputRect.IsInside(elementRect)) + if (nPrevPos != nStartPos) { - long nScrollPos = mxScroll->GetThumbPos() + pCur->mBoxLocation.Y(); - if (!bBackward) - nScrollPos += pCur->mBoxSize.Height() - GetOutputSizePixel().Height(); - mxScroll->DoScroll(nScrollPos); + nPos = nPrevPos; + break; } + if (bMoved) + break; + pCur = maElementList[nPrevPos].get(); + + elementRect = tools::Rectangle(pCur->mBoxLocation, pCur->mBoxSize); + if (mbVerticalMode) + outputRect.Move(bBackward ? -outputRect.GetWidth() + elementRect.Right() : elementRect.Left(), 0); + else + outputRect.Move(0, bBackward ? -outputRect.GetHeight() + elementRect.Bottom() : elementRect.Top()); + bMoved = true; } + } + + if (nStartPos != nPos) + { + m_nCurrentElement = nPos; + if (bMoved) + scrollToElement(bBackward, maElementList[nPos].get()); Invalidate(); } } @@ -692,6 +760,13 @@ void SmElementsControl::KeyInput(const KeyEvent& rKEvt) mxScroll->DoScroll(mxScroll->GetRangeMax()); break; + case KEY_PAGEUP: + pageFocus(true); + break; + case KEY_PAGEDOWN: + pageFocus(false); + break; + default: Control::KeyInput( rKEvt ); break; |