Commit 7bbf392a authored by t.artikov's avatar t.artikov

[VNQ-6373] QQuickAndroidOffscreenEditText improvements

* Information about the selection bounds
* Ability to disable vertical scrolling
* Auto position tracking
parent abc5308c
......@@ -34,6 +34,7 @@
THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <QtCore/QMetaObject>
#include <QJniHelpers/QAndroidQPAPluginGap.h>
#include "QAndroidOffscreenEditText.h"
......@@ -84,7 +85,20 @@ Q_DECL_EXPORT void JNICALL Java_AndroidOffscreenEditText_nativeOnEditorAction(JN
qWarning()<<__FUNCTION__<<"Zero param!";
}
Q_DECL_EXPORT void JNICALL Java_AndroidOffscreenEditText_nativeSetSelectionInfo(JNIEnv *, jobject, jlong param, jint top, jint bottom)
{
if (param)
{
void * vp = reinterpret_cast<void*>(param);
QAndroidOffscreenEditText * edit = qobject_cast<QAndroidOffscreenEditText*>(reinterpret_cast<QAndroidOffscreenView*>(vp));
if (edit)
{
QMetaObject::invokeMethod(edit, "javaSetSelectionInfo", Q_ARG(int, top), Q_ARG(int, bottom));
return;
}
}
qWarning()<<__FUNCTION__<<"Zero param!";
}
QAndroidOffscreenEditText::QAndroidOffscreenEditText(const QString & object_name, const QSize & def_size, QObject * parent)
......@@ -98,6 +112,7 @@ QAndroidOffscreenEditText::QAndroidOffscreenEditText(const QString & object_name
{"nativeOnTextChanged", "(JLjava/lang/String;III)V", reinterpret_cast<void*>(Java_AndroidOffscreenEditText_nativeOnTextChanged)},
{"nativeOnKey", "(JZI)Z", reinterpret_cast<void*>(Java_AndroidOffscreenEditText_nativeOnKey)},
{"nativeOnEditorAction", "(JI)V", reinterpret_cast<void*>(Java_AndroidOffscreenEditText_nativeOnEditorAction)},
{"nativeSetSelectionInfo", "(JII)V", reinterpret_cast<void*>(Java_AndroidOffscreenEditText_nativeSetSelectionInfo)},
};
view->registerNativeMethods(methods, sizeof(methods));
}
......@@ -157,6 +172,13 @@ void QAndroidOffscreenEditText::javaOnEditorAction(int action)
}
}
void QAndroidOffscreenEditText::javaSetSelectionInfo(int top, int bottom)
{
selection_top_ = top;
selection_bottom_ = bottom;
emit selectionChanged();
}
void QAndroidOffscreenEditText::setText(const QString & text)
{
if (QJniObject * view = offscreenView())
......@@ -436,6 +458,14 @@ void QAndroidOffscreenEditText::setHorizontallyScrolling(bool whether)
}
}
void QAndroidOffscreenEditText::setVerticallyScrolling(bool whether)
{
if (QJniObject * view = offscreenView())
{
view->callVoid("setVerticallyScrolling", jboolean(whether));
}
}
void QAndroidOffscreenEditText::setAllCaps(bool allCaps)
{
if (QJniObject * view = offscreenView())
......@@ -534,6 +564,16 @@ int QAndroidOffscreenEditText::getSelectionEnd()
return 0; // No selection end
}
int QAndroidOffscreenEditText::getSelectionTop() const
{
return selection_top_;
}
int QAndroidOffscreenEditText::getSelectionBottom() const
{
return selection_bottom_;
}
void QAndroidOffscreenEditText::setTextColor(const QColor & color)
{
setTextColor(QColorToAndroidColor(color));
......
......@@ -279,6 +279,8 @@ public:
//! Sets whether the text should be allowed to be wider than the View is.
void setHorizontallyScrolling(bool whether);
void setVerticallyScrolling(bool whether);
//! Sets the properties of this field to transform input to ALL CAPS display.
void setAllCaps(bool allCaps);
......@@ -325,6 +327,8 @@ public:
void setSelection(int start, int stop);
int getSelectionStart();
int getSelectionEnd();
int getSelectionTop() const;
int getSelectionBottom() const;
void setHorizontalScrollBarEnabled(bool horizontalScrollBarEnabled);
void setVerticalScrollBarEnabled (bool verticalScrollBarEnabled);
......@@ -355,6 +359,8 @@ signals:
//! Emitted when KEYCODE_DPAD_CENTER or KEYCODE_ENTER has been released.
void onEnter();
void selectionChanged();
public:
static const int
ANDROID_EDITORINFO_IME_ACTION_DONE = 0x00000006,
......@@ -558,12 +564,18 @@ protected:
virtual bool javaOnKey(bool down, int androidKey);
virtual void javaOnEditorAction(int action);
private slots:
void javaSetSelectionInfo(int top, int bottom);
private:
friend void JNICALL Java_AndroidOffscreenEditText_nativeOnTextChanged(JNIEnv * env, jobject jo, jlong param, jstring str, jint start, jint before, jint count);
friend jboolean JNICALL Java_AndroidOffscreenEditText_nativeOnKey(JNIEnv * env, jobject jo, jlong param, jboolean down, jint keycode);
friend void JNICALL Java_AndroidOffscreenEditText_nativeOnEditorAction(JNIEnv *, jobject, jlong param, jint action);
friend void JNICALL Java_AndroidOffscreenEditText_nativeSetSelectionInfo(JNIEnv *, jobject, jlong param, jint top, jint bottom);
private:
int paint_flags_;
int selection_top_ = 0;
int selection_bottom_ = 0;
};
......@@ -95,6 +95,7 @@ QQuickAndroidOffscreenView::QQuickAndroidOffscreenView(QAndroidOffscreenView * a
, mouse_tracking_(false)
, redraw_texture_needed_(true)
, last_set_position_(0, 0) // View always at (0, 0) by default.
, auto_position_tracking_(false)
{
setFlag(QQuickItem::ItemHasContents, true);
setAcceptedMouseButtons(Qt::LeftButton);
......@@ -144,6 +145,10 @@ void QQuickAndroidOffscreenView::focusInEvent(QFocusEvent * event)
// qDebug()<<__PRETTY_FUNCTION__;
QQuickItem::focusInEvent(event);
aview_->setFocused(true);
if (auto_position_tracking_)
{
beginAutoPositionTracking();
}
}
void QQuickAndroidOffscreenView::focusOutEvent(QFocusEvent * event)
......@@ -151,6 +156,10 @@ void QQuickAndroidOffscreenView::focusOutEvent(QFocusEvent * event)
// qDebug()<<__PRETTY_FUNCTION__;
QQuickItem::focusOutEvent(event);
aview_->setFocused(false);
if (auto_position_tracking_)
{
endAutoPositionTracking();
}
}
void QQuickAndroidOffscreenView::mouseMoveEvent(QMouseEvent * event)
......@@ -314,6 +323,24 @@ void QQuickAndroidOffscreenView::updateAndroidViewPosition()
}
}
void QQuickAndroidOffscreenView::setAutoPositionTracking(bool enabled)
{
if (auto_position_tracking_ == enabled)
{
return;
}
auto_position_tracking_ = enabled;
if (enabled && hasActiveFocus())
{
beginAutoPositionTracking();
}
else
{
endAutoPositionTracking();
}
}
void QQuickAndroidOffscreenView::requestVisibleRect()
{
aview_->requestVisibleRect();
......@@ -330,3 +357,21 @@ void QQuickAndroidOffscreenView::onViewCreated()
qDebug() << __PRETTY_FUNCTION__;
emit viewCreated();
}
void QQuickAndroidOffscreenView::beginAutoPositionTracking()
{
if (auto_position_tracking_connection_)
{
return;
}
auto_position_tracking_connection_ = connect(window(), SIGNAL(afterAnimating()), this, SLOT(updateAndroidViewPosition()));
}
void QQuickAndroidOffscreenView::endAutoPositionTracking()
{
if (!auto_position_tracking_connection_)
{
return;
}
disconnect(auto_position_tracking_connection_);
}
......@@ -36,6 +36,7 @@
#pragma once
#include <QtCore/QSharedPointer>
#include <QtCore/QMetaObject>
#include <QtGui/QFocusEvent>
#include <QtQuick/QQuickItem>
#include <QtOffscreenViews/QAndroidOffscreenView.h>
......@@ -63,6 +64,12 @@ public slots:
*/
void updateAndroidViewPosition();
/*!
* Update the Android view position automatically.
* The position is checked every frame, which is less efficient than manually calling updateAndroidViewPosition.
*/
void setAutoPositionTracking(bool enabled);
void requestVisibleRect();
//! Make sure software keyboard is hidden for this control.
......@@ -117,9 +124,14 @@ protected slots:
virtual void onViewCreated();
private:
void beginAutoPositionTracking();
void endAutoPositionTracking();
QSharedPointer<QAndroidOffscreenView> aview_;
bool is_interactive_;
bool mouse_tracking_;
bool redraw_texture_needed_;
QPoint last_set_position_;
bool auto_position_tracking_;
QMetaObject::Connection auto_position_tracking_connection_;
};
......@@ -40,6 +40,7 @@ QQuickAndroidOffscreenEditText::QQuickAndroidOffscreenEditText()
: QQuickAndroidOffscreenView(new QAndroidOffscreenEditText("EditTextInQuick", QSize(512, 64)))
{
connect(androidEditText(), SIGNAL(onTextChanged(QString,int,int,int)), this, SLOT(etTextChanged(QString,int,int,int)));
connect(androidEditText(), SIGNAL(selectionChanged()), this, SIGNAL(selectionChanged()));
connect(androidEditText(), SIGNAL(onKeyBack(bool)), this, SLOT(etKeyBack(bool)));
connect(androidEditText(), SIGNAL(onEnterOrPositiveAction()), this, SLOT(etEnter()));
}
......
......@@ -42,6 +42,8 @@ class QQuickAndroidOffscreenEditText: public QQuickAndroidOffscreenView
{
Q_OBJECT
Q_PROPERTY(QString text READ getText WRITE setText NOTIFY onTextChanged)
Q_PROPERTY(int selectionTop READ getSelectionTop NOTIFY selectionChanged)
Q_PROPERTY(int selectionBottom READ getSelectionBottom NOTIFY selectionChanged)
public:
QQuickAndroidOffscreenEditText();
......@@ -171,6 +173,9 @@ public slots:
//! Sets whether the text should be allowed to be wider than the View is.
void setHorizontallyScrolling(bool whether) { androidEditText()->setHorizontallyScrolling(whether); }
//! Allows to scroll the text vertically.
void setVerticallyScrolling(bool whether) { androidEditText()->setVerticallyScrolling(whether); }
//! Sets the properties of this field to transform input to ALL CAPS display.
void setAllCaps(bool allCaps) { androidEditText()->setAllCaps(allCaps); }
......@@ -180,6 +185,12 @@ public slots:
void setSelection(int start, int stop) { androidEditText()->setSelection(start, stop); }
//! Y coordinate(in pixels) of the selection/cursor upper bound.
int getSelectionTop() const { return androidEditText()->getSelectionTop(); }
//! Y coordinate(in pixels) of the selection/cursor lower bound.
int getSelectionBottom() const { return androidEditText()->getSelectionBottom(); }
void setAllowFullscreenKeyboard(bool allow) { androidEditText()->setAllowFullscreenKeyboard(allow); }
void setHorizontalScrollBarEnabled(bool horizontalScrollBarEnabled) { androidEditText()->setHorizontalScrollBarEnabled(horizontalScrollBarEnabled); }
......@@ -206,6 +217,7 @@ public slots:
signals:
void onTextChanged(QString text);
void selectionChanged();
//! Wraps QAndroidOffscreenEditText::onEnterOrPositiveAction().
void returnPressed();
......
......@@ -57,6 +57,7 @@ import android.graphics.PorterDuff;
import android.graphics.Color;
import android.text.TextUtils;
import android.text.InputFilter;
import android.text.Layout;
import ru.dublgis.androidhelpers.Log;
......@@ -67,6 +68,7 @@ class OffscreenEditText extends OffscreenView
boolean single_line_ = false;
boolean need_to_reflow_text_ = false, need_to_reflow_hint_ = false;
int selection_start_ = 0, selection_end_ = 0;
int selection_top_ = 0, selection_bottom_ = 0;
private Object variables_mutex_ = new Object();
static final int
......@@ -77,6 +79,7 @@ class OffscreenEditText extends OffscreenView
class MyEditText extends EditText
{
private boolean vertically_scrolling_ = false;
class MyTextWatcher implements TextWatcher
{
......@@ -250,6 +253,26 @@ class OffscreenEditText extends OffscreenView
text_layout_width_ = w;
reflowWorkaround();
}
updateSelectionInfo();
}
private void updateSelectionInfo() {
Layout layout = getLayout();
if (layout == null) {
return;
}
int start = Math.max(getSelectionStart(), 0);
int end = Math.max(getSelectionEnd(), 0);
int top = layout.getLineTop(layout.getLineForOffset(start));
int bottom = layout.getLineBottom(layout.getLineForOffset(end));
if (selection_top_ == top && selection_bottom_ == bottom) {
return;
}
selection_top_ = top;
selection_bottom_ = bottom;
nativeSetSelectionInfo(getNativePtr(), top, bottom);
}
protected void reflowWorkaround()
......@@ -353,6 +376,16 @@ class OffscreenEditText extends OffscreenView
selection_end_ = selEnd;
}
}
@Override
public void scrollTo(int x, int y) {
super.scrollTo(x, vertically_scrolling_ ? y : 0);
}
public void setVerticallyScrolling(final boolean whether)
{
vertically_scrolling_ = whether;
}
}
OffscreenEditText()
......@@ -378,6 +411,7 @@ class OffscreenEditText extends OffscreenView
public native void nativeOnTextChanged(long nativePtr, String s, int start, int before, int count);
public native boolean nativeOnKey(long nativePtr, boolean down, int keyCode);
public native void nativeOnEditorAction(long nativePtr, int action);
public native void nativeSetSelectionInfo(long nativePtr, int top, int bottom);
......@@ -771,6 +805,16 @@ class OffscreenEditText extends OffscreenView
});
}
void setVerticallyScrolling(final boolean whether)
{
runViewAction(new Runnable(){
@Override
public void run(){
((MyEditText)getView()).setVerticallyScrolling(whether);
}
});
}
void setAllCaps(final boolean allCaps)
{
runViewAction(new Runnable(){
......
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