summaryrefslogtreecommitdiff
path: root/starmath
diff options
context:
space:
mode:
authorJan-Marek Glogowski <glogow@fbihome.de>2019-05-17 02:38:43 +0200
committerJan-Marek Glogowski <glogow@fbihome.de>2019-05-23 07:02:45 +0200
commit73f8222109c3091d5119ed47eac5cad4a55b2212 (patch)
tree42ae5a80036c88ec7d10b92221c0927fddec578f /starmath
parent2fdcd86ac08c0ed033398bdb85ed04b64f50c633 (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.hxx5
-rw-r--r--starmath/source/ElementsDockingWindow.cxx111
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;