android/README | 6 android/experimental/LOAndroid3/res/layout/text_selection_handles.xml | 2 android/experimental/LOAndroid3/res/menu/main.xml | 12 android/experimental/LOAndroid3/src/java/org/libreoffice/InvalidationHandler.java | 108 ++ android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitShell.java | 13 android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java | 1 android/experimental/LOAndroid3/src/java/org/libreoffice/LibreOfficeMainActivity.java | 10 android/experimental/LOAndroid3/src/java/org/libreoffice/canvas/Cursor.java | 38 android/experimental/LOAndroid3/src/java/org/libreoffice/overlay/DocumentOverlay.java | 210 +++++ android/experimental/LOAndroid3/src/java/org/libreoffice/overlay/DocumentOverlayView.java | 373 +++++++++ android/experimental/LOAndroid3/src/java/org/libreoffice/overlay/TextCursorLayer.java | 200 ----- android/experimental/LOAndroid3/src/java/org/libreoffice/overlay/TextCursorView.java | 381 ---------- android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/GeckoLayerClient.java | 9 android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/JavaPanZoomController.java | 24 android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/ScrollbarLayer.java | 2 editeng/source/editeng/editview.cxx | 3 sd/qa/unit/tiledrendering/tiledrendering.cxx | 28 sd/source/ui/inc/ViewShell.hxx | 2 sd/source/ui/unoidl/unomodel.cxx | 6 sd/source/ui/view/viewshel.cxx | 2 sw/qa/extras/tiledrendering/tiledrendering.cxx | 18 sw/source/uibase/docvw/edtwin.cxx | 2 sw/source/uibase/inc/edtwin.hxx | 2 sw/source/uibase/uno/unotxdoc.cxx | 6 24 files changed, 819 insertions(+), 639 deletions(-)
New commits: commit 6eaf6c8d2344fb4ef55c8d1178433588701bdd6b Author: Miklos Vajna <vmik...@collabora.co.uk> Date: Fri Apr 10 16:36:42 2015 +0200 android: move strikeout button after underline So that it matches the order we show on the desktop. Change-Id: Ia5be2a233bc4ab3adc37b013b22784032d58a174 diff --git a/android/experimental/LOAndroid3/res/menu/main.xml b/android/experimental/LOAndroid3/res/menu/main.xml index 09314f5..1ab1ef1 100644 --- a/android/experimental/LOAndroid3/res/menu/main.xml +++ b/android/experimental/LOAndroid3/res/menu/main.xml @@ -16,18 +16,18 @@ android:orderInCategory="100" app:showAsAction="always"/> - <item android:id="@+id/action_strikeout" - android:title="@string/action_strikeout" - android:icon="@drawable/action_strikeout" - android:orderInCategory="100" - app:showAsAction="always"/> - <item android:id="@+id/action_underline" android:title="@string/action_underline" android:icon="@drawable/action_underline" android:orderInCategory="100" app:showAsAction="always"/> + <item android:id="@+id/action_strikeout" + android:title="@string/action_strikeout" + android:icon="@drawable/action_strikeout" + android:orderInCategory="100" + app:showAsAction="always"/> + <item android:id="@+id/action_keyboard" android:title="@string/action_keyboard" android:icon="@drawable/ic_format_keyboard_grey600_24dp" commit 54eaeabdf7d90ee05e9eb8d4deab8d7e1d8ed150 Author: Miklos Vajna <vmik...@collabora.co.uk> Date: Fri Apr 10 16:09:20 2015 +0200 Add SdXImpressDocument::postKeyEvent() testcase. Change-Id: I87edb9c4693b1634942d8dbda4050920f439cbbf diff --git a/sd/qa/unit/tiledrendering/tiledrendering.cxx b/sd/qa/unit/tiledrendering/tiledrendering.cxx index 5a364c4..1b87768 100644 --- a/sd/qa/unit/tiledrendering/tiledrendering.cxx +++ b/sd/qa/unit/tiledrendering/tiledrendering.cxx @@ -40,6 +40,7 @@ public: #if !defined(WNT) && !defined(MACOSX) void testRegisterCallback(); + void testPostKeyEvent(); void testPostMouseEvent(); void testSetTextSelection(); #endif @@ -47,6 +48,7 @@ public: CPPUNIT_TEST_SUITE(SdTiledRenderingTest); #if !defined(WNT) && !defined(MACOSX) CPPUNIT_TEST(testRegisterCallback); + CPPUNIT_TEST(testPostKeyEvent); CPPUNIT_TEST(testPostMouseEvent); CPPUNIT_TEST(testSetTextSelection); #endif @@ -137,6 +139,32 @@ void SdTiledRenderingTest::testRegisterCallback() CPPUNIT_ASSERT(m_aInvalidation.IsOver(aTopLeft)); } +void SdTiledRenderingTest::testPostKeyEvent() +{ + SdXImpressDocument* pXImpressDocument = createDoc("dummy.odp"); + sd::ViewShell* pViewShell = pXImpressDocument->GetDocShell()->GetViewShell(); + SdPage* pActualPage = pViewShell->GetActualPage(); + SdrObject* pObject = pActualPage->GetObj(0); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16>(OBJ_TITLETEXT), pObject->GetObjIdentifier()); + SdrTextObj* pTextObj = static_cast<SdrTextObj*>(pObject); + SdrView* pView = pViewShell->GetView(); + pView->MarkObj(pTextObj, pView->GetSdrPageView()); + SfxStringItem aInputString(SID_ATTR_CHAR, "x"); + pViewShell->GetViewFrame()->GetDispatcher()->Execute(SID_ATTR_CHAR, SfxCallMode::SYNCHRON, &aInputString, 0); + + pXImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 'x', 0); + pXImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 'x', 0); + + CPPUNIT_ASSERT(pView->GetTextEditObject()); + EditView& rEditView = pView->GetTextEditOutlinerView()->GetEditView(); + // Did we manage to enter a second character? + CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2), rEditView.GetSelection().nStartPos); + ESelection aWordSelection(0, 0, 0, 2); // start para, start char, end para, end char. + rEditView.SetSelection(aWordSelection); + // Did we enter the expected character? + CPPUNIT_ASSERT_EQUAL(OUString("xx"), rEditView.GetSelected()); +} + void SdTiledRenderingTest::testPostMouseEvent() { SdXImpressDocument* pXImpressDocument = createDoc("dummy.odp"); commit c09c3559f011e89ae45c16e5cf0bb085e127f0ea Author: Miklos Vajna <vmik...@collabora.co.uk> Date: Fri Apr 10 16:15:27 2015 +0200 Fix failing SdTiledRenderingTest::testSetTextSelection(). Change-Id: Ieaeaef249ea15de7cebc1cdb60b4d6130a6b5616 diff --git a/editeng/source/editeng/editview.cxx b/editeng/source/editeng/editview.cxx index 6d0c556..d407e4e 100644 --- a/editeng/source/editeng/editview.cxx +++ b/editeng/source/editeng/editview.cxx @@ -1323,14 +1323,17 @@ void EditView::SetCursorLogicPosition(const Point& rPosition, bool bPoint, bool { Point aDocPos(pImpEditView->GetDocPos(rPosition)); EditPaM aPaM = pImpEditView->pEditEngine->GetPaM(aDocPos); + EditSelection aSelection(pImpEditView->GetEditSelection()); // Explicitly create or delete the selection. if (bClearMark) + { pImpEditView->DeselectAll(); + aSelection = pImpEditView->GetEditSelection(); + } else pImpEditView->CreateAnchor(); - EditSelection aSelection(pImpEditView->GetEditSelection()); if (bPoint) aSelection.Max() = aPaM; else commit 060dcbf6d118cef164c75a8cb603d6a4179abf53 Author: Miklos Vajna <vmik...@collabora.co.uk> Date: Fri Apr 10 15:23:29 2015 +0200 EditView::SetCursorLogicPosition: first deselect, then get the selection If you tap to nearly the end of an editeng paragraph, then drag the cursor using EditView::SetCursorLogicPosition(bPoint=true, bClearMark=true) to the end of the paragraph, finally hit enter, the text between the tap position and the end of the paragraph gets deleted. Fix this by calling GetEditSelection() after DeselectAll(), so that the original cursor position (before the drag started) never survives, which gives back the lost text, too. Change-Id: I777256765f1c8f1a7f22c549eaca19e575fdae21 diff --git a/editeng/source/editeng/editview.cxx b/editeng/source/editeng/editview.cxx index 11d041d..6d0c556 100644 --- a/editeng/source/editeng/editview.cxx +++ b/editeng/source/editeng/editview.cxx @@ -1323,7 +1323,6 @@ void EditView::SetCursorLogicPosition(const Point& rPosition, bool bPoint, bool { Point aDocPos(pImpEditView->GetDocPos(rPosition)); EditPaM aPaM = pImpEditView->pEditEngine->GetPaM(aDocPos); - EditSelection aSelection(pImpEditView->GetEditSelection()); // Explicitly create or delete the selection. if (bClearMark) @@ -1331,6 +1330,7 @@ void EditView::SetCursorLogicPosition(const Point& rPosition, bool bPoint, bool else pImpEditView->CreateAnchor(); + EditSelection aSelection(pImpEditView->GetEditSelection()); if (bPoint) aSelection.Max() = aPaM; else commit 2cd35b8ddfe8fa6504cea0cf55f8dbaf15c9e530 Author: Miklos Vajna <vmik...@collabora.co.uk> Date: Fri Apr 10 15:15:41 2015 +0200 sw: SetCursorLogicPosition -> SetCursorTwipPosition Again, to be consistent with SetGraphicTwipPosition. Change-Id: Id2134de9ec8467b890ff6f26a3d538fbb45ad3e0 diff --git a/sw/source/uibase/docvw/edtwin.cxx b/sw/source/uibase/docvw/edtwin.cxx index 42c41f3..14c45ed 100644 --- a/sw/source/uibase/docvw/edtwin.cxx +++ b/sw/source/uibase/docvw/edtwin.cxx @@ -6209,7 +6209,7 @@ void SwEditWin::LogicMouseButtonUp(const MouseEvent& rMouseEvent) SetPointerPosPixel(aPoint); } -void SwEditWin::SetCursorLogicPosition(const Point& rPosition, bool bPoint, bool bClearMark) +void SwEditWin::SetCursorTwipPosition(const Point& rPosition, bool bPoint, bool bClearMark) { if (SdrView* pSdrView = m_rView.GetWrtShell().GetDrawView()) { diff --git a/sw/source/uibase/inc/edtwin.hxx b/sw/source/uibase/inc/edtwin.hxx index e8c2e5e..ae96136 100644 --- a/sw/source/uibase/inc/edtwin.hxx +++ b/sw/source/uibase/inc/edtwin.hxx @@ -303,7 +303,7 @@ public: /// Same as MouseButtonUp(), but coordinates are in logic unit. void LogicMouseButtonUp(const MouseEvent& rMouseEvent); /// Allows adjusting the point or mark of the selection to a document coordinate. - void SetCursorLogicPosition(const Point& rPosition, bool bPoint, bool bClearMark); + void SetCursorTwipPosition(const Point& rPosition, bool bPoint, bool bClearMark); /// Allows starting or ending a graphic move or resize action. void SetGraphicTwipPosition(bool bStart, const Point& rPosition); }; diff --git a/sw/source/uibase/uno/unotxdoc.cxx b/sw/source/uibase/uno/unotxdoc.cxx index 5feadbf..0dca9b0 100644 --- a/sw/source/uibase/uno/unotxdoc.cxx +++ b/sw/source/uibase/uno/unotxdoc.cxx @@ -3233,13 +3233,13 @@ void SwXTextDocument::setTextSelection(int nType, int nX, int nY) switch (nType) { case LOK_SETTEXTSELECTION_START: - rEditWin.SetCursorLogicPosition(Point(nX, nY), /*bPoint=*/false, /*bClearMark=*/false); + rEditWin.SetCursorTwipPosition(Point(nX, nY), /*bPoint=*/false, /*bClearMark=*/false); break; case LOK_SETTEXTSELECTION_END: - rEditWin.SetCursorLogicPosition(Point(nX, nY), /*bPoint=*/true, /*bClearMark=*/false); + rEditWin.SetCursorTwipPosition(Point(nX, nY), /*bPoint=*/true, /*bClearMark=*/false); break; case LOK_SETTEXTSELECTION_RESET: - rEditWin.SetCursorLogicPosition(Point(nX, nY), /*bPoint=*/true, /*bClearMark=*/true); + rEditWin.SetCursorTwipPosition(Point(nX, nY), /*bPoint=*/true, /*bClearMark=*/true); break; default: assert(false); commit f37952bb2531f8fe25fc6f793bf85280fa774356 Author: Miklos Vajna <vmik...@collabora.co.uk> Date: Fri Apr 10 14:58:53 2015 +0200 sd: SetCursorLogicPosition -> SetCursorMm100Position To be consistent with SetGraphicMm100Position. Change-Id: Ic6775f9f1350ceb41381b4090cd32c4bd4393e67 diff --git a/sd/source/ui/inc/ViewShell.hxx b/sd/source/ui/inc/ViewShell.hxx index 93bb0f9..6d8ba40 100644 --- a/sd/source/ui/inc/ViewShell.hxx +++ b/sd/source/ui/inc/ViewShell.hxx @@ -448,7 +448,7 @@ public: /// Same as MouseButtonUp(), but coordinates are in logic unit. void LogicMouseButtonUp(const MouseEvent& rMouseEvent); /// Allows adjusting the point or mark of the selection to a document coordinate. - void SetCursorLogicPosition(const Point& rPosition, bool bPoint, bool bClearMark); + void SetCursorMm100Position(const Point& rPosition, bool bPoint, bool bClearMark); /// Allows starting or ending a graphic move or resize action. void SetGraphicMm100Position(bool bStart, const Point& rPosition); diff --git a/sd/source/ui/unoidl/unomodel.cxx b/sd/source/ui/unoidl/unomodel.cxx index bdf49e9..bc2c3e0 100644 --- a/sd/source/ui/unoidl/unomodel.cxx +++ b/sd/source/ui/unoidl/unomodel.cxx @@ -2442,13 +2442,13 @@ void SdXImpressDocument::setTextSelection(int nType, int nX, int nY) switch (nType) { case LOK_SETTEXTSELECTION_START: - pViewShell->SetCursorLogicPosition(aPoint, /*bPoint=*/false, /*bClearMark=*/false); + pViewShell->SetCursorMm100Position(aPoint, /*bPoint=*/false, /*bClearMark=*/false); break; case LOK_SETTEXTSELECTION_END: - pViewShell->SetCursorLogicPosition(aPoint, /*bPoint=*/true, /*bClearMark=*/false); + pViewShell->SetCursorMm100Position(aPoint, /*bPoint=*/true, /*bClearMark=*/false); break; case LOK_SETTEXTSELECTION_RESET: - pViewShell->SetCursorLogicPosition(aPoint, /*bPoint=*/true, /*bClearMark=*/true); + pViewShell->SetCursorMm100Position(aPoint, /*bPoint=*/true, /*bClearMark=*/true); break; default: assert(false); diff --git a/sd/source/ui/view/viewshel.cxx b/sd/source/ui/view/viewshel.cxx index 4016503..4e51b2e 100644 --- a/sd/source/ui/view/viewshel.cxx +++ b/sd/source/ui/view/viewshel.cxx @@ -532,7 +532,7 @@ void ViewShell::LogicMouseButtonUp(const MouseEvent& rMouseEvent) mpActiveWindow->SetPointerPosPixel(aPoint); } -void ViewShell::SetCursorLogicPosition(const Point& rPosition, bool bPoint, bool bClearMark) +void ViewShell::SetCursorMm100Position(const Point& rPosition, bool bPoint, bool bClearMark) { if (SdrView* pSdrView = GetView()) { commit 7f0dfb3ae67bd8ce64fbbea3b418071faee1a6a0 Author: Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk> Date: Thu Apr 9 17:27:31 2015 +0900 android: tune the viewport moving to cursor position on key input Change-Id: Ie420307f28cc05ca03fabe47f46712f67c6f18fa diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/InvalidationHandler.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/InvalidationHandler.java index 9f83006..1fdc681 100644 --- a/android/experimental/LOAndroid3/src/java/org/libreoffice/InvalidationHandler.java +++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/InvalidationHandler.java @@ -8,6 +8,8 @@ import android.net.Uri; import org.libreoffice.canvas.SelectionHandle; import org.libreoffice.kit.Document; import org.libreoffice.overlay.DocumentOverlay; +import org.mozilla.gecko.gfx.GeckoLayerClient; +import org.mozilla.gecko.gfx.ImmutableViewportMetrics; import java.util.ArrayList; import java.util.Collections; @@ -19,11 +21,13 @@ import java.util.List; public class InvalidationHandler implements Document.MessageCallback { private static String LOGTAG = InvalidationHandler.class.getSimpleName(); private final DocumentOverlay mDocumentOverlay; + private final GeckoLayerClient mLayerClient; private OverlayState mState; private boolean mKeyEvent = false; public InvalidationHandler(LibreOfficeMainActivity mainActivity) { mDocumentOverlay = mainActivity.getDocumentOverlay(); + mLayerClient = mainActivity.getLayerClient(); mState = OverlayState.NONE; } @@ -153,8 +157,7 @@ public class InvalidationHandler implements Document.MessageCallback { mDocumentOverlay.positionHandle(SelectionHandle.HandleType.MIDDLE, cursorRectangle); if (mKeyEvent) { - PointF point = new PointF(cursorRectangle.centerX(), cursorRectangle.centerY()); - LOKitShell.moveViewportTo(point, null); + moveViewportToMakeCursorVisible(cursorRectangle); mKeyEvent = false; } @@ -165,6 +168,37 @@ public class InvalidationHandler implements Document.MessageCallback { } /** + * Move the viewport to show the cursor. The cursor will appear at the + * viewport position depending on where the cursor is relative to the + * viewport (either cursor is above, below, on left or right). + * + * @param cursorRectangle - cursor position on the document + */ + public void moveViewportToMakeCursorVisible(RectF cursorRectangle) { + RectF moveToRect = mLayerClient.getViewportMetrics().getCssViewport(); + if (moveToRect.contains(cursorRectangle)) { + return; + } + + float newLeft = moveToRect.left; + float newTop = moveToRect.top; + + if (cursorRectangle.right < moveToRect.left || cursorRectangle.left < moveToRect.left) { + newLeft = cursorRectangle.left - (moveToRect.width() * 0.1f); + } else if (cursorRectangle.right > moveToRect.right || cursorRectangle.left > moveToRect.right) { + newLeft = cursorRectangle.right - (moveToRect.width() * 0.9f); + } + + if (cursorRectangle.top < moveToRect.top || cursorRectangle.bottom < moveToRect.top) { + newTop = cursorRectangle.top - (moveToRect.height() * 0.1f); + } else if (cursorRectangle.bottom > moveToRect.bottom || cursorRectangle.top > moveToRect.bottom) { + newTop = cursorRectangle.bottom - (moveToRect.height() / 2.0f); + } + + LOKitShell.moveViewportTo(new PointF(newLeft, newTop), null); + } + + /** * Handles the text selection start message * * @param payload diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitShell.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitShell.java index 99f9948..d9a20d8 100644 --- a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitShell.java +++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitShell.java @@ -158,7 +158,7 @@ public class LOKitShell { } /** - * Move the viewport to the desired point, and change the zoom level. + * Move the viewport to the desired point (top-left), and change the zoom level. * Ensure this runs on the UI thread. */ public static void moveViewportTo(final PointF position, final Float zoom) { diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/JavaPanZoomController.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/JavaPanZoomController.java index f758681..f8b39b4 100644 --- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/JavaPanZoomController.java +++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/JavaPanZoomController.java @@ -418,7 +418,7 @@ public class JavaPanZoomController } else { setState(PanZoomState.PANNING); } - LibreOfficeMainActivity.mAppContext.hideSoftKeyboard(); + //LibreOfficeMainActivity.mAppContext.hideSoftKeyboard(); } private float panDistance(MotionEvent move) { @@ -1023,16 +1023,15 @@ public class JavaPanZoomController } /** - * Move to centerPosition and zoom to the desired input zoom factor. Input zoom - * factor can be null, in this case leave the zoom unchanged. + * Move the viewport to the top-left point to and zoom to the desired + * zoom factor. Input zoom factor can be null, in this case leave the zoom unchanged. */ - public boolean animatedMove(PointF centerPoint, Float zoom) { + public boolean animatedMove(PointF topLeft, Float zoom) { RectF moveToRect = getMetrics().getCssViewport(); - moveToRect.offsetTo( - centerPoint.x - moveToRect.width() / 2.0f, - centerPoint.y - moveToRect.height() / 2.0f); + moveToRect.offsetTo(topLeft.x, topLeft.y); ImmutableViewportMetrics finalMetrics = getMetrics(); + finalMetrics = finalMetrics.setViewportOrigin( moveToRect.left * finalMetrics.zoomFactor, moveToRect.top * finalMetrics.zoomFactor); commit 207142748b095252f5c9bfd1b418a892823304d0 Author: Miklos Vajna <vmik...@collabora.co.uk> Date: Wed Apr 8 17:48:21 2015 +0200 Add SwXTextDocument::postKeyEvent() testcase. Change-Id: I76904ed9596dcb0b6aa70bccd19279573687d30c diff --git a/sw/qa/extras/tiledrendering/tiledrendering.cxx b/sw/qa/extras/tiledrendering/tiledrendering.cxx index 23d3fe2..67c04db 100644 --- a/sw/qa/extras/tiledrendering/tiledrendering.cxx +++ b/sw/qa/extras/tiledrendering/tiledrendering.cxx @@ -15,6 +15,7 @@ #include <vcl/svapp.hxx> #include <crsskip.hxx> #include <drawdoc.hxx> +#include <ndtxt.hxx> #include <wrtsh.hxx> static const char* DATA_DIRECTORY = "/sw/qa/extras/tiledrendering/data/"; @@ -24,6 +25,7 @@ class SwTiledRenderingTest : public SwModelTestBase { public: void testRegisterCallback(); + void testPostKeyEvent(); void testPostMouseEvent(); void testSetTextSelection(); void testSetGraphicSelection(); @@ -31,6 +33,7 @@ public: CPPUNIT_TEST_SUITE(SwTiledRenderingTest); CPPUNIT_TEST(testRegisterCallback); + CPPUNIT_TEST(testPostKeyEvent); CPPUNIT_TEST(testPostMouseEvent); CPPUNIT_TEST(testSetTextSelection); CPPUNIT_TEST(testSetGraphicSelection); @@ -110,6 +113,21 @@ void SwTiledRenderingTest::testRegisterCallback() #endif } +void SwTiledRenderingTest::testPostKeyEvent() +{ + SwXTextDocument* pXTextDocument = createDoc("dummy.fodt"); + SwWrtShell* pWrtShell = pXTextDocument->GetDocShell()->GetWrtShell(); + pWrtShell->Right(CRSR_SKIP_CHARS, /*bSelect=*/false, 1, /*bBasicCall=*/false); + SwShellCrsr* pShellCrsr = pWrtShell->getShellCrsr(false); + // Did we manage to go after the first character? + CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), pShellCrsr->GetPoint()->nContent.GetIndex()); + + pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 'x', 0); + pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 'x', 0); + // Did we manage to insert the character after the first one? + CPPUNIT_ASSERT_EQUAL(OUString("Axaa bbb."), pShellCrsr->GetPoint()->nNode.GetNode().GetTxtNode()->GetTxt()); +} + void SwTiledRenderingTest::testPostMouseEvent() { SwXTextDocument* pXTextDocument = createDoc("dummy.fodt"); commit 3e6d192b048b4742a5cf522c1414aaa6a7ed3dee Author: Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk> Date: Wed Apr 8 18:57:55 2015 +0900 android: hide keyboard on scrolling at a more correct location When animation happens the scrollbars appear. This hides the keyboard when the user types and the viewport is repositioned. With this change, trigger the keyboard hiding only when we really do scrolling (panning). Change-Id: I17dc651a6641e807a386d5184868412dd6710a28 diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/JavaPanZoomController.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/JavaPanZoomController.java index 0811c26..f758681 100644 --- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/JavaPanZoomController.java +++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/JavaPanZoomController.java @@ -418,6 +418,7 @@ public class JavaPanZoomController } else { setState(PanZoomState.PANNING); } + LibreOfficeMainActivity.mAppContext.hideSoftKeyboard(); } private float panDistance(MotionEvent move) { diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/ScrollbarLayer.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/ScrollbarLayer.java index 589bc7a..09229d8 100644 --- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/ScrollbarLayer.java +++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/ScrollbarLayer.java @@ -208,8 +208,6 @@ public class ScrollbarLayer extends TileLayer { mOpacity = 1.0f; endTransaction(); - // Scrollbar is now visible, scrolling will start: hide the soft keyboard. - LibreOfficeMainActivity.mAppContext.hideSoftKeyboard(); return true; } commit 5d7a203bdae1940e4846c4c42f5d733e4ffa4160 Author: Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk> Date: Wed Apr 8 18:24:48 2015 +0900 android: reposition the viewport to the cursor at key event Change-Id: I9b18001d0629e203bee41ebbf4a3bd57adfea88e diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/InvalidationHandler.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/InvalidationHandler.java index 7aeb573..9f83006 100644 --- a/android/experimental/LOAndroid3/src/java/org/libreoffice/InvalidationHandler.java +++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/InvalidationHandler.java @@ -1,6 +1,7 @@ package org.libreoffice; import android.content.Intent; +import android.graphics.PointF; import android.graphics.RectF; import android.net.Uri; @@ -19,6 +20,7 @@ public class InvalidationHandler implements Document.MessageCallback { private static String LOGTAG = InvalidationHandler.class.getSimpleName(); private final DocumentOverlay mDocumentOverlay; private OverlayState mState; + private boolean mKeyEvent = false; public InvalidationHandler(LibreOfficeMainActivity mainActivity) { mDocumentOverlay = mainActivity.getDocumentOverlay(); @@ -150,6 +152,12 @@ public class InvalidationHandler implements Document.MessageCallback { mDocumentOverlay.positionCursor(cursorRectangle); mDocumentOverlay.positionHandle(SelectionHandle.HandleType.MIDDLE, cursorRectangle); + if (mKeyEvent) { + PointF point = new PointF(cursorRectangle.centerX(), cursorRectangle.centerY()); + LOKitShell.moveViewportTo(point, null); + mKeyEvent = false; + } + if (mState == OverlayState.TRANSITION || mState == OverlayState.CURSOR) { changeStateTo(OverlayState.CURSOR); } @@ -352,6 +360,10 @@ public class InvalidationHandler implements Document.MessageCallback { return mState; } + public void keyEvent() { + mKeyEvent = true; + } + public enum OverlayState { /** * State where the overlay is empty diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java index 1da85f3..cc21840 100644 --- a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java +++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java @@ -271,6 +271,7 @@ public class LOKitThread extends Thread { if (mTileProvider == null) { return; } + mInvalidationHandler.keyEvent(); mTileProvider.sendKeyEvent(keyEvent); } commit e585b1206905ba57e98483b8295f78a384291b01 Author: Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk> Date: Wed Apr 8 18:23:16 2015 +0900 android: don't need the cursor position from DocumentOverlay Change-Id: I79155f9c5c8df211b35137cc61430cebccb4cfe3 diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/overlay/DocumentOverlay.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/overlay/DocumentOverlay.java index d949a6b..40e4eaa 100644 --- a/android/experimental/LOAndroid3/src/java/org/libreoffice/overlay/DocumentOverlay.java +++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/overlay/DocumentOverlay.java @@ -205,10 +205,6 @@ public class DocumentOverlay { } }); } - - public RectF getCursorPosition() { - return mDocumentOverlayView.getCursorPosition(); - } } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/overlay/DocumentOverlayView.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/overlay/DocumentOverlayView.java index 7d72d3e..c4866df 100644 --- a/android/experimental/LOAndroid3/src/java/org/libreoffice/overlay/DocumentOverlayView.java +++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/overlay/DocumentOverlayView.java @@ -368,10 +368,6 @@ public class DocumentOverlayView extends View implements View.OnTouchListener { } return null; } - - public RectF getCursorPosition() { - return mCursor.mPosition; - } } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ commit 20382895558479a7a89a9893c2379b5dbdb0a64f Author: Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk> Date: Wed Apr 8 18:21:11 2015 +0900 android: add possibility to move the viewport and zoom + animation Change-Id: I294ad30b1fdd7f1a3d5099304cc4f077034567b7 diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitShell.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitShell.java index 38c13ca..99f9948 100644 --- a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitShell.java +++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitShell.java @@ -156,6 +156,19 @@ public class LOKitShell { public static void sendNavigationClickEvent() { LOKitShell.sendEvent(new LOEvent(LOEvent.NAVIGATION_CLICK)); } + + /** + * Move the viewport to the desired point, and change the zoom level. + * Ensure this runs on the UI thread. + */ + public static void moveViewportTo(final PointF position, final Float zoom) { + getLayerView().getLayerClient().post(new Runnable() { + @Override + public void run() { + getLayerView().getLayerClient().moveTo(position, zoom); + } + }); + } } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/GeckoLayerClient.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/GeckoLayerClient.java index 40fb8bb..bb6e3d0 100644 --- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/GeckoLayerClient.java +++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/GeckoLayerClient.java @@ -324,6 +324,15 @@ public class GeckoLayerClient implements PanZoomTarget { } } + /** + * Move the viewport to the desired point, and change the zoom level. + */ + public void moveTo(PointF point, Float zoom) { + if (mPanZoomController instanceof JavaPanZoomController) { + ((JavaPanZoomController) mPanZoomController).animatedMove(point, zoom); + } + } + public void zoomTo(float pageWidth, float pageHeight) { zoomTo(new RectF(0, 0, pageWidth, pageHeight)); } diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/JavaPanZoomController.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/JavaPanZoomController.java index adae23a..0811c26 100644 --- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/JavaPanZoomController.java +++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/JavaPanZoomController.java @@ -1021,6 +1021,30 @@ public class JavaPanZoomController return true; } + /** + * Move to centerPosition and zoom to the desired input zoom factor. Input zoom + * factor can be null, in this case leave the zoom unchanged. + */ + public boolean animatedMove(PointF centerPoint, Float zoom) { + RectF moveToRect = getMetrics().getCssViewport(); + moveToRect.offsetTo( + centerPoint.x - moveToRect.width() / 2.0f, + centerPoint.y - moveToRect.height() / 2.0f); + + ImmutableViewportMetrics finalMetrics = getMetrics(); + finalMetrics = finalMetrics.setViewportOrigin( + moveToRect.left * finalMetrics.zoomFactor, + moveToRect.top * finalMetrics.zoomFactor); + + if (zoom != null) { + finalMetrics = finalMetrics.scaleTo(zoom, new PointF(0.0f, 0.0f)); + } + finalMetrics = getValidViewportMetrics(finalMetrics); + + bounce(finalMetrics, PanZoomState.ANIMATED_ZOOM); + return true; + } + /** This function must be called from the UI thread. */ public void abortPanning() { checkMainThread(); commit 6cbcde026784ab279e2ea2e03d65e992fb7cb110 Author: Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk> Date: Wed Apr 8 13:27:36 2015 +0900 android: separate layer functionality to DocumentOverlayLayer Change-Id: Ie69259dbc5826dafbaebc8eec08163256b459337 diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/overlay/DocumentOverlay.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/overlay/DocumentOverlay.java index d28f33d..d949a6b 100644 --- a/android/experimental/LOAndroid3/src/java/org/libreoffice/overlay/DocumentOverlay.java +++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/overlay/DocumentOverlay.java @@ -26,43 +26,52 @@ import java.util.List; * to setup the document overlay view, report visibility and position of its elements * when they change and report any changes to the viewport. */ -public class DocumentOverlay extends Layer { +public class DocumentOverlay { private static final String LOGTAG = DocumentOverlay.class.getSimpleName(); - private final DocumentOverlayView mCursorView; - private float mViewLeft; - private float mViewTop; - private float mViewZoom; - - public DocumentOverlay(Activity context, LayerView layerView) { - mCursorView = (DocumentOverlayView) context.findViewById(R.id.text_cursor_view); - if (mCursorView == null) { - Log.e(LOGTAG, "Failed to initialize TextCursorLayer - CursorView is null"); - } - layerView.addLayer(this); - mCursorView.initialize(layerView); - } + private final DocumentOverlayView mDocumentOverlayView; + private final DocumentOverlayLayer mDocumentOverlayLayer; /** - * @see Layer#draw(org.mozilla.gecko.gfx.Layer.RenderContext) + * DocumentOverlayLayer responsibility is to get the changes to the viewport + * and report them to DocumentOverlayView. */ - @Override - public void draw(final RenderContext context) { - if (FloatUtils.fuzzyEquals(mViewLeft, context.viewport.left) - && FloatUtils.fuzzyEquals(mViewTop, context.viewport.top) - && FloatUtils.fuzzyEquals(mViewZoom, context.zoomFactor)) { - return; - } + private class DocumentOverlayLayer extends Layer { + private float mViewLeft; + private float mViewTop; + private float mViewZoom; + + /** + * @see Layer#draw(org.mozilla.gecko.gfx.Layer.RenderContext) + */ + @Override + public void draw(final RenderContext context) { + if (FloatUtils.fuzzyEquals(mViewLeft, context.viewport.left) + && FloatUtils.fuzzyEquals(mViewTop, context.viewport.top) + && FloatUtils.fuzzyEquals(mViewZoom, context.zoomFactor)) { + return; + } - mViewLeft = context.viewport.left; - mViewTop = context.viewport.top; - mViewZoom = context.zoomFactor; + mViewLeft = context.viewport.left; + mViewTop = context.viewport.top; + mViewZoom = context.zoomFactor; - LOKitShell.getMainHandler().post(new Runnable() { - public void run() { - mCursorView.repositionWithViewport(mViewLeft, mViewTop, mViewZoom); - } - }); + LOKitShell.getMainHandler().post(new Runnable() { + public void run() { + mDocumentOverlayView.repositionWithViewport(mViewLeft, mViewTop, mViewZoom); + } + }); + } + } + + public DocumentOverlay(Activity context, LayerView layerView) { + mDocumentOverlayView = (DocumentOverlayView) context.findViewById(R.id.text_cursor_view); + mDocumentOverlayLayer = new DocumentOverlayLayer(); + if (mDocumentOverlayView == null) { + Log.e(LOGTAG, "Failed to initialize TextCursorLayer - CursorView is null"); + } + layerView.addLayer(mDocumentOverlayLayer); + mDocumentOverlayView.initialize(layerView); } /** @@ -71,7 +80,7 @@ public class DocumentOverlay extends Layer { public void showCursor() { LOKitShell.getMainHandler().post(new Runnable() { public void run() { - mCursorView.showCursor(); + mDocumentOverlayView.showCursor(); } }); } @@ -82,7 +91,7 @@ public class DocumentOverlay extends Layer { public void hideCursor() { LOKitShell.getMainHandler().post(new Runnable() { public void run() { - mCursorView.hideCursor(); + mDocumentOverlayView.hideCursor(); } }); } @@ -93,7 +102,7 @@ public class DocumentOverlay extends Layer { public void positionCursor(final RectF position) { LOKitShell.getMainHandler().post(new Runnable() { public void run() { - mCursorView.changeCursorPosition(position); + mDocumentOverlayView.changeCursorPosition(position); } }); } @@ -104,7 +113,7 @@ public class DocumentOverlay extends Layer { public void showSelections() { LOKitShell.getMainHandler().post(new Runnable() { public void run() { - mCursorView.showSelections(); + mDocumentOverlayView.showSelections(); } }); } @@ -115,7 +124,7 @@ public class DocumentOverlay extends Layer { public void hideSelections() { LOKitShell.getMainHandler().post(new Runnable() { public void run() { - mCursorView.hideSelections(); + mDocumentOverlayView.hideSelections(); } }); } @@ -126,7 +135,7 @@ public class DocumentOverlay extends Layer { public void changeSelections(final List<RectF> selections) { LOKitShell.getMainHandler().post(new Runnable() { public void run() { - mCursorView.changeSelections(selections); + mDocumentOverlayView.changeSelections(selections); } }); } @@ -137,7 +146,7 @@ public class DocumentOverlay extends Layer { public void showGraphicSelection() { LOKitShell.getMainHandler().post(new Runnable() { public void run() { - mCursorView.showGraphicSelection(); + mDocumentOverlayView.showGraphicSelection(); } }); } @@ -148,7 +157,7 @@ public class DocumentOverlay extends Layer { public void hideGraphicSelection() { LOKitShell.getMainHandler().post(new Runnable() { public void run() { - mCursorView.hideGraphicSelection(); + mDocumentOverlayView.hideGraphicSelection(); } }); } @@ -159,7 +168,7 @@ public class DocumentOverlay extends Layer { public void changeGraphicSelection(final RectF rectangle) { LOKitShell.getMainHandler().post(new Runnable() { public void run() { - mCursorView.changeGraphicSelection(rectangle); + mDocumentOverlayView.changeGraphicSelection(rectangle); } }); } @@ -170,7 +179,7 @@ public class DocumentOverlay extends Layer { public void showHandle(final SelectionHandle.HandleType type) { LOKitShell.getMainHandler().post(new Runnable() { public void run() { - mCursorView.showHandle(type); + mDocumentOverlayView.showHandle(type); } }); } @@ -181,7 +190,7 @@ public class DocumentOverlay extends Layer { public void hideHandle(final SelectionHandle.HandleType type) { LOKitShell.getMainHandler().post(new Runnable() { public void run() { - mCursorView.hideHandle(type); + mDocumentOverlayView.hideHandle(type); } }); } @@ -192,13 +201,13 @@ public class DocumentOverlay extends Layer { public void positionHandle(final SelectionHandle.HandleType type, final RectF rectangle) { LOKitShell.getMainHandler().post(new Runnable() { public void run() { - mCursorView.positionHandle(type, rectangle); + mDocumentOverlayView.positionHandle(type, rectangle); } }); } public RectF getCursorPosition() { - return mCursorView.getCursorPosition(); + return mDocumentOverlayView.getCursorPosition(); } } commit 5707813c075cdbccaf74dbdcb623dcf0149d5d1d Author: Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk> Date: Wed Apr 8 13:17:00 2015 +0900 android: rename TextCursorLayer{View} -> DocumentOverlay{View} Change-Id: I53a55e2d30c298e7c34f18b7713de91f3c77d5f2 diff --git a/android/README b/android/README index 0837900..0989cf6 100644 --- a/android/README +++ b/android/README @@ -144,9 +144,9 @@ Overlay Overlay elements like cursor and selections aren't drawn by the LO core, instead the core only provides data (cursor position, selection rectangles) and the app needs to draw them. -TextCursorView (org.libreoffice.overlay.TextCursorView) and TextCursorLayer -(org.libreoffice.overlay.TextCursorLayer) are the classes that provide the overlay over the -document, where selections and the cursor is drawn. +DocumentOverlay (org.libreoffice.overlay.DocumentOverlay) and DocumentOverlayView +(org.libreoffice.overlay.DocumentOverlayView) are the classes that provide the overlay over +the document, where selections and the cursor is drawn. Emulator and debugging notes **************************** diff --git a/android/experimental/LOAndroid3/res/layout/text_selection_handles.xml b/android/experimental/LOAndroid3/res/layout/text_selection_handles.xml index b75ffd9..0be954d 100644 --- a/android/experimental/LOAndroid3/res/layout/text_selection_handles.xml +++ b/android/experimental/LOAndroid3/res/layout/text_selection_handles.xml @@ -6,7 +6,7 @@ <merge xmlns:android="http://schemas.android.com/apk/res/android" xmlns:gecko="http://schemas.android.com/apk/res-auto"> - <org.libreoffice.overlay.TextCursorView + <org.libreoffice.overlay.DocumentOverlayView android:id="@+id/text_cursor_view" android:layout_width="fill_parent" android:layout_height="fill_parent"/> diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/InvalidationHandler.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/InvalidationHandler.java index a49b32d..7aeb573 100644 --- a/android/experimental/LOAndroid3/src/java/org/libreoffice/InvalidationHandler.java +++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/InvalidationHandler.java @@ -6,7 +6,7 @@ import android.net.Uri; import org.libreoffice.canvas.SelectionHandle; import org.libreoffice.kit.Document; -import org.libreoffice.overlay.TextCursorLayer; +import org.libreoffice.overlay.DocumentOverlay; import java.util.ArrayList; import java.util.Collections; @@ -17,11 +17,11 @@ import java.util.List; */ public class InvalidationHandler implements Document.MessageCallback { private static String LOGTAG = InvalidationHandler.class.getSimpleName(); - private final TextCursorLayer mTextCursorLayer; + private final DocumentOverlay mDocumentOverlay; private OverlayState mState; public InvalidationHandler(LibreOfficeMainActivity mainActivity) { - mTextCursorLayer = mainActivity.getTextCursorLayer(); + mDocumentOverlay = mainActivity.getDocumentOverlay(); mState = OverlayState.NONE; } @@ -147,8 +147,8 @@ public class InvalidationHandler implements Document.MessageCallback { private synchronized void invalidateCursor(String payload) { RectF cursorRectangle = convertPayloadToRectangle(payload); if (cursorRectangle != null) { - mTextCursorLayer.positionCursor(cursorRectangle); - mTextCursorLayer.positionHandle(SelectionHandle.HandleType.MIDDLE, cursorRectangle); + mDocumentOverlay.positionCursor(cursorRectangle); + mDocumentOverlay.positionHandle(SelectionHandle.HandleType.MIDDLE, cursorRectangle); if (mState == OverlayState.TRANSITION || mState == OverlayState.CURSOR) { changeStateTo(OverlayState.CURSOR); @@ -164,7 +164,7 @@ public class InvalidationHandler implements Document.MessageCallback { private synchronized void textSelectionStart(String payload) { RectF selectionRect = convertPayloadToRectangle(payload); if (selectionRect != null) { - mTextCursorLayer.positionHandle(SelectionHandle.HandleType.START, selectionRect); + mDocumentOverlay.positionHandle(SelectionHandle.HandleType.START, selectionRect); } } @@ -176,7 +176,7 @@ public class InvalidationHandler implements Document.MessageCallback { private synchronized void textSelectionEnd(String payload) { RectF selectionRect = convertPayloadToRectangle(payload); if (selectionRect != null) { - mTextCursorLayer.positionHandle(SelectionHandle.HandleType.END, selectionRect); + mDocumentOverlay.positionHandle(SelectionHandle.HandleType.END, selectionRect); } } @@ -190,14 +190,14 @@ public class InvalidationHandler implements Document.MessageCallback { if (mState == OverlayState.SELECTION) { changeStateTo(OverlayState.TRANSITION); } - mTextCursorLayer.changeSelections(Collections.EMPTY_LIST); + mDocumentOverlay.changeSelections(Collections.EMPTY_LIST); } else { List<RectF> rectangles = convertPayloadToRectangles(payload); if (mState != OverlayState.SELECTION) { changeStateTo(OverlayState.TRANSITION); } changeStateTo(OverlayState.SELECTION); - mTextCursorLayer.changeSelections(rectangles); + mDocumentOverlay.changeSelections(rectangles); } } @@ -208,13 +208,13 @@ public class InvalidationHandler implements Document.MessageCallback { */ private synchronized void cursorVisibility(String payload) { if (payload.equals("true")) { - mTextCursorLayer.showCursor(); + mDocumentOverlay.showCursor(); if (mState != OverlayState.SELECTION) { - mTextCursorLayer.showHandle(SelectionHandle.HandleType.MIDDLE); + mDocumentOverlay.showHandle(SelectionHandle.HandleType.MIDDLE); } } else if (payload.equals("false")) { - mTextCursorLayer.hideCursor(); - mTextCursorLayer.hideHandle(SelectionHandle.HandleType.MIDDLE); + mDocumentOverlay.hideCursor(); + mDocumentOverlay.hideHandle(SelectionHandle.HandleType.MIDDLE); } } @@ -230,7 +230,7 @@ public class InvalidationHandler implements Document.MessageCallback { } } else { RectF rectangle = convertPayloadToRectangle(payload); - mTextCursorLayer.changeGraphicSelection(rectangle); + mDocumentOverlay.changeGraphicSelection(rectangle); if (mState != OverlayState.GRAPHIC_SELECTION) { changeStateTo(OverlayState.TRANSITION); } @@ -293,12 +293,12 @@ public class InvalidationHandler implements Document.MessageCallback { } // Just hide everything - mTextCursorLayer.hideHandle(SelectionHandle.HandleType.START); - mTextCursorLayer.hideHandle(SelectionHandle.HandleType.END); - mTextCursorLayer.hideHandle(SelectionHandle.HandleType.MIDDLE); - mTextCursorLayer.hideSelections(); - mTextCursorLayer.hideCursor(); - mTextCursorLayer.hideGraphicSelection(); + mDocumentOverlay.hideHandle(SelectionHandle.HandleType.START); + mDocumentOverlay.hideHandle(SelectionHandle.HandleType.END); + mDocumentOverlay.hideHandle(SelectionHandle.HandleType.MIDDLE); + mDocumentOverlay.hideSelections(); + mDocumentOverlay.hideCursor(); + mDocumentOverlay.hideGraphicSelection(); LibreOfficeMainActivity.mAppContext.hideSoftKeyboard(); } @@ -306,9 +306,9 @@ public class InvalidationHandler implements Document.MessageCallback { * Handle a transition to OverlayState.SELECTION state. */ private void handleSelectionState(OverlayState previous) { - mTextCursorLayer.showHandle(SelectionHandle.HandleType.START); - mTextCursorLayer.showHandle(SelectionHandle.HandleType.END); - mTextCursorLayer.showSelections(); + mDocumentOverlay.showHandle(SelectionHandle.HandleType.START); + mDocumentOverlay.showHandle(SelectionHandle.HandleType.END); + mDocumentOverlay.showSelections(); } /** @@ -317,8 +317,8 @@ public class InvalidationHandler implements Document.MessageCallback { private void handleCursorState(OverlayState previous) { LibreOfficeMainActivity.mAppContext.showSoftKeyboard(); if (previous == OverlayState.TRANSITION) { - mTextCursorLayer.showHandle(SelectionHandle.HandleType.MIDDLE); - mTextCursorLayer.showCursor(); + mDocumentOverlay.showHandle(SelectionHandle.HandleType.MIDDLE); + mDocumentOverlay.showCursor(); } } @@ -327,13 +327,13 @@ public class InvalidationHandler implements Document.MessageCallback { */ private void handleTransitionState(OverlayState previous) { if (previous == OverlayState.SELECTION) { - mTextCursorLayer.hideHandle(SelectionHandle.HandleType.START); - mTextCursorLayer.hideHandle(SelectionHandle.HandleType.END); - mTextCursorLayer.hideSelections(); + mDocumentOverlay.hideHandle(SelectionHandle.HandleType.START); + mDocumentOverlay.hideHandle(SelectionHandle.HandleType.END); + mDocumentOverlay.hideSelections(); } else if (previous == OverlayState.CURSOR) { - mTextCursorLayer.hideHandle(SelectionHandle.HandleType.MIDDLE); + mDocumentOverlay.hideHandle(SelectionHandle.HandleType.MIDDLE); } else if (previous == OverlayState.GRAPHIC_SELECTION) { - mTextCursorLayer.hideGraphicSelection(); + mDocumentOverlay.hideGraphicSelection(); } } @@ -341,7 +341,7 @@ public class InvalidationHandler implements Document.MessageCallback { * Handle a transition to OverlayState.GRAPHIC_SELECTION state. */ private void handleGraphicSelectionState(OverlayState previous) { - mTextCursorLayer.showGraphicSelection(); + mDocumentOverlay.showGraphicSelection(); LibreOfficeMainActivity.mAppContext.hideSoftKeyboard(); } diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LibreOfficeMainActivity.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LibreOfficeMainActivity.java index c831977..61ec014 100644 --- a/android/experimental/LOAndroid3/src/java/org/libreoffice/LibreOfficeMainActivity.java +++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/LibreOfficeMainActivity.java @@ -18,7 +18,7 @@ import android.widget.AdapterView; import android.widget.ListView; import android.widget.Toast; -import org.libreoffice.overlay.TextCursorLayer; +import org.libreoffice.overlay.DocumentOverlay; import org.mozilla.gecko.ZoomConstraints; import org.mozilla.gecko.gfx.GeckoLayerClient; import org.mozilla.gecko.gfx.LayerView; @@ -52,7 +52,7 @@ public class LibreOfficeMainActivity extends ActionBarActivity { private List<DocumentPartView> mDocumentPartView = new ArrayList<DocumentPartView>(); private DocumentPartViewListAdapter mDocumentPartViewListAdapter; private String mInputFile; - private TextCursorLayer mTextCursorLayer; + private DocumentOverlay mDocumentOverlay; private File mTempFile = null; private LOAbout mAbout; private ToolbarController mToolbarController; @@ -175,7 +175,7 @@ public class LibreOfficeMainActivity extends ActionBarActivity { mLayerClient.notifyReady(); // create TextCursorLayer - mTextCursorLayer = new TextCursorLayer(mAppContext, layerView); + mDocumentOverlay = new DocumentOverlay(mAppContext, layerView); } private boolean copyFileToTemp() { @@ -342,8 +342,8 @@ public class LibreOfficeMainActivity extends ActionBarActivity { alertDialog.show(); } - public TextCursorLayer getTextCursorLayer() { - return mTextCursorLayer; + public DocumentOverlay getDocumentOverlay() { + return mDocumentOverlay; } public ToolbarController getToolbarController() { diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/overlay/TextCursorLayer.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/overlay/DocumentOverlay.java similarity index 91% rename from android/experimental/LOAndroid3/src/java/org/libreoffice/overlay/TextCursorLayer.java rename to android/experimental/LOAndroid3/src/java/org/libreoffice/overlay/DocumentOverlay.java index 6624c66..d28f33d 100644 --- a/android/experimental/LOAndroid3/src/java/org/libreoffice/overlay/TextCursorLayer.java +++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/overlay/DocumentOverlay.java @@ -22,19 +22,20 @@ import org.mozilla.gecko.util.FloatUtils; import java.util.List; /** - * The TextCursorLayer is a layer which is responsible for showing the cursor and - * controls its position, height and visibility. + * The DocumentOverlay is an overlay over the document. This class is responsible + * to setup the document overlay view, report visibility and position of its elements + * when they change and report any changes to the viewport. */ -public class TextCursorLayer extends Layer { - private static final String LOGTAG = TextCursorLayer.class.getSimpleName(); +public class DocumentOverlay extends Layer { + private static final String LOGTAG = DocumentOverlay.class.getSimpleName(); - private final TextCursorView mCursorView; + private final DocumentOverlayView mCursorView; private float mViewLeft; private float mViewTop; private float mViewZoom; - public TextCursorLayer(Activity context, LayerView layerView) { - mCursorView = (TextCursorView) context.findViewById(R.id.text_cursor_view); + public DocumentOverlay(Activity context, LayerView layerView) { + mCursorView = (DocumentOverlayView) context.findViewById(R.id.text_cursor_view); if (mCursorView == null) { Log.e(LOGTAG, "Failed to initialize TextCursorLayer - CursorView is null"); } diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/overlay/TextCursorView.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/overlay/DocumentOverlayView.java similarity index 95% rename from android/experimental/LOAndroid3/src/java/org/libreoffice/overlay/TextCursorView.java rename to android/experimental/LOAndroid3/src/java/org/libreoffice/overlay/DocumentOverlayView.java index ff11dc5..7d72d3e 100644 --- a/android/experimental/LOAndroid3/src/java/org/libreoffice/overlay/TextCursorView.java +++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/overlay/DocumentOverlayView.java @@ -9,20 +9,15 @@ package org.libreoffice.overlay; import android.content.Context; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.PointF; import android.graphics.RectF; import android.util.AttributeSet; -import android.util.Log; import android.view.MotionEvent; import android.view.View; -import org.libreoffice.LOKitShell; -import org.libreoffice.R; import org.libreoffice.canvas.Cursor; import org.libreoffice.canvas.GraphicSelection; import org.libreoffice.canvas.SelectionHandle; @@ -37,10 +32,11 @@ import java.util.ArrayList; import java.util.List; /** - * Text cursor view responsible to show the cursor drawable on the screen. + * Document overlay view is responsible for showing the client drawn overlay + * elements like cursor, selection and graphic selection, and manipulate them. */ -public class TextCursorView extends View implements View.OnTouchListener { - private static final String LOGTAG = TextCursorView.class.getSimpleName(); +public class DocumentOverlayView extends View implements View.OnTouchListener { + private static final String LOGTAG = DocumentOverlayView.class.getSimpleName(); private static final int CURSOR_BLINK_TIME = 500; @@ -65,15 +61,15 @@ public class TextCursorView extends View implements View.OnTouchListener { private SelectionHandle mDragHandle = null; - public TextCursorView(Context context) { + public DocumentOverlayView(Context context) { super(context); } - public TextCursorView(Context context, AttributeSet attrs) { + public DocumentOverlayView(Context context, AttributeSet attrs) { super(context, attrs); } - public TextCursorView(Context context, AttributeSet attrs, int defStyleAttr) { + public DocumentOverlayView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } commit 4fb38c6f6668badcea8c12d574e97bfc4faed671 Author: Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk> Date: Wed Apr 8 12:55:14 2015 +0900 android: get cursor position from TextCursorLayer/View Change-Id: I7629deb6e01ace052ac8bec70202844bc627ea85 diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/overlay/TextCursorLayer.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/overlay/TextCursorLayer.java index 55ebfde..6624c66 100644 --- a/android/experimental/LOAndroid3/src/java/org/libreoffice/overlay/TextCursorLayer.java +++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/overlay/TextCursorLayer.java @@ -195,6 +195,10 @@ public class TextCursorLayer extends Layer { } }); } + + public RectF getCursorPosition() { + return mCursorView.getCursorPosition(); + } } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/overlay/TextCursorView.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/overlay/TextCursorView.java index 4e52f6e..ff11dc5 100644 --- a/android/experimental/LOAndroid3/src/java/org/libreoffice/overlay/TextCursorView.java +++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/overlay/TextCursorView.java @@ -372,6 +372,10 @@ public class TextCursorView extends View implements View.OnTouchListener { } return null; } + + public RectF getCursorPosition() { + return mCursor.mPosition; + } } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ commit 6d9af889984cf047f4724cc6087b4b4cfda2a6c3 Author: Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk> Date: Wed Apr 8 12:18:44 2015 +0900 android: add Cursor class for drawing the cursor to the canvas Change-Id: I5d8191ffb3d3dd3d3ab11c757a3b7d5dc3fb2e82 diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/canvas/Cursor.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/canvas/Cursor.java new file mode 100644 index 0000000..bdb8e09 --- /dev/null +++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/canvas/Cursor.java @@ -0,0 +1,38 @@ +package org.libreoffice.canvas; + +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.RectF; + +public class Cursor extends CommonCanvasElement { + private static final float CURSOR_WIDTH = 2f; + private final Paint mCursorPaint = new Paint(); + public RectF mPosition = new RectF(); + public RectF mScaledPosition = new RectF(); + public int mAlpha = 0; + + public Cursor() { + mCursorPaint.setColor(Color.BLACK); + mCursorPaint.setAlpha(0xFF); + } + + @Override + public boolean onHitTest(float x, float y) { + return false; + } + + @Override + public void onDraw(Canvas canvas) { + canvas.drawRect(mScaledPosition, mCursorPaint); + } + + public void reposition(RectF rect) { + mScaledPosition = rect; + mScaledPosition.right = mScaledPosition.left + CURSOR_WIDTH; + } + + public void cycleAlpha() { + mCursorPaint.setAlpha(mCursorPaint.getAlpha() == 0 ? 0xFF : 0); + } +} diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/overlay/TextCursorView.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/overlay/TextCursorView.java index 44d0d51..4e52f6e 100644 --- a/android/experimental/LOAndroid3/src/java/org/libreoffice/overlay/TextCursorView.java +++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/overlay/TextCursorView.java @@ -23,6 +23,7 @@ import android.view.View; import org.libreoffice.LOKitShell; import org.libreoffice.R; +import org.libreoffice.canvas.Cursor; import org.libreoffice.canvas.GraphicSelection; import org.libreoffice.canvas.SelectionHandle; import org.libreoffice.canvas.SelectionHandleEnd; @@ -40,15 +41,10 @@ import java.util.List; */ public class TextCursorView extends View implements View.OnTouchListener { private static final String LOGTAG = TextCursorView.class.getSimpleName(); - private static final float CURSOR_WIDTH = 2f; + private static final int CURSOR_BLINK_TIME = 500; private boolean mInitialized = false; - private RectF mCursorPosition = new RectF(); - private RectF mCursorScaledPosition = new RectF(); - private Paint mCursorPaint = new Paint(); - private int mCursorAlpha = 0; - private boolean mCursorVisible; private List<RectF> mSelections = new ArrayList<RectF>(); private List<RectF> mScaledSelections = new ArrayList<RectF>(); @@ -65,6 +61,8 @@ public class TextCursorView extends View implements View.OnTouchListener { private SelectionHandle mHandleStart; private SelectionHandle mHandleEnd; + private Cursor mCursor; + private SelectionHandle mDragHandle = null; public TextCursorView(Context context) { @@ -87,9 +85,8 @@ public class TextCursorView extends View implements View.OnTouchListener { setOnTouchListener(this); mLayerView = layerView; - mCursorPaint.setColor(Color.BLACK); - mCursorPaint.setAlpha(0xFF); - mCursorVisible = false; + mCursor = new Cursor(); + mCursor.setVisible(false); mSelectionPaint.setColor(Color.BLUE); mSelectionPaint.setAlpha(50); @@ -113,10 +110,10 @@ public class TextCursorView extends View implements View.OnTouchListener { * @param position - new position of the cursor */ public void changeCursorPosition(RectF position) { - if (RectUtils.fuzzyEquals(mCursorPosition, position)) { + if (RectUtils.fuzzyEquals(mCursor.mPosition, position)) { return; } - mCursorPosition = position; + mCursor.mPosition = position; ImmutableViewportMetrics metrics = mLayerView.getViewportMetrics(); repositionWithViewport(metrics.viewportRectLeft, metrics.viewportRectTop, metrics.zoomFactor); @@ -149,10 +146,10 @@ public class TextCursorView extends View implements View.OnTouchListener { } public void repositionWithViewport(float x, float y, float zoom) { - mCursorScaledPosition = convertToScreen(mCursorPosition, x, y, zoom); - mCursorScaledPosition.right = mCursorScaledPosition.left + CURSOR_WIDTH; + RectF rect = convertToScreen(mCursor.mPosition, x, y, zoom); + mCursor.reposition(rect); - RectF rect = convertToScreen(mHandleMiddle.mDocumentPosition, x, y, zoom); + rect = convertToScreen(mHandleMiddle.mDocumentPosition, x, y, zoom); mHandleMiddle.reposition(rect.left, rect.bottom); rect = convertToScreen(mHandleStart.mDocumentPosition, x, y, zoom); @@ -189,9 +186,8 @@ public class TextCursorView extends View implements View.OnTouchListener { protected void onDraw(Canvas canvas) { super.onDraw(canvas); - if (mCursorVisible) { - canvas.drawRect(mCursorScaledPosition, mCursorPaint); - } + mCursor.draw(canvas); + mHandleMiddle.draw(canvas); mHandleStart.draw(canvas); mHandleEnd.draw(canvas); @@ -211,8 +207,8 @@ public class TextCursorView extends View implements View.OnTouchListener { */ private Runnable cursorAnimation = new Runnable() { public void run() { - if (mCursorVisible) { - mCursorPaint.setAlpha(mCursorPaint.getAlpha() == 0 ? 0xFF : 0); + if (mCursor.isVisible()) { + mCursor.cycleAlpha(); invalidate(); } postDelayed(cursorAnimation, CURSOR_BLINK_TIME); @@ -223,8 +219,8 @@ public class TextCursorView extends View implements View.OnTouchListener { * Show the cursor on the view. */ public void showCursor() { - if (!mCursorVisible) { - mCursorVisible = true; + if (!mCursor.isVisible()) { + mCursor.setVisible(true); invalidate(); } } @@ -233,8 +229,8 @@ public class TextCursorView extends View implements View.OnTouchListener { * Hide the cursor. */ public void hideCursor() { - if (mCursorVisible) { - mCursorVisible = false; + if (mCursor.isVisible()) { + mCursor.setVisible(false); invalidate(); } }
_______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits