| Index: ui/android/view_android.cc
|
| diff --git a/ui/android/view_android.cc b/ui/android/view_android.cc
|
| index 6c55a7bf9df724ce0eea47170c138cd146ba2d85..43f084fcf737da20491fae94808a83471544bcda 100644
|
| --- a/ui/android/view_android.cc
|
| +++ b/ui/android/view_android.cc
|
| @@ -18,6 +18,7 @@ namespace ui {
|
| using base::android::JavaRef;
|
| using base::android::ScopedJavaLocalRef;
|
|
|
| +// ViewAndroid::ScopedAndroidView
|
| ViewAndroid::ScopedAnchorView::ScopedAnchorView(
|
| JNIEnv* env,
|
| const JavaRef<jobject>& jview,
|
| @@ -68,44 +69,65 @@ ViewAndroid::ScopedAnchorView::view() const {
|
| return view_.get(env);
|
| }
|
|
|
| -ViewAndroid::ViewAndroid(const JavaRef<jobject>& delegate)
|
| - : parent_(nullptr)
|
| - , delegate_(base::android::AttachCurrentThread(),
|
| - delegate.obj()) {}
|
| -
|
| -ViewAndroid::ViewAndroid() : parent_(nullptr) {}
|
| +// ViewAndroid
|
| +ViewAndroid::ViewAndroid(ViewClient* client) : parent_(nullptr),
|
| + client_(client) {}
|
| +ViewAndroid::ViewAndroid() : ViewAndroid(nullptr) {}
|
|
|
| ViewAndroid::~ViewAndroid() {
|
| RemoveFromParent();
|
|
|
| - for (std::list<ViewAndroid*>::iterator it = children_.begin();
|
| - it != children_.end(); it++) {
|
| - DCHECK_EQ((*it)->parent_, this);
|
| - (*it)->parent_ = nullptr;
|
| - }
|
| + auto children_copy = std::list<ViewAndroid*>(children_);
|
| + for (auto& child : children_copy)
|
| + RemoveChild(child);
|
| }
|
|
|
| void ViewAndroid::SetDelegate(const JavaRef<jobject>& delegate) {
|
| + // A ViewAndroid may have its own delegate or otherwise will
|
| + // use the next available parent's delegate.
|
| JNIEnv* env = base::android::AttachCurrentThread();
|
| delegate_ = JavaObjectWeakGlobalRef(env, delegate);
|
| }
|
|
|
| void ViewAndroid::AddChild(ViewAndroid* child) {
|
| DCHECK(child);
|
| + DCHECK(!child->IsViewRoot()); // ViewRoot cannot be a child.
|
| DCHECK(std::find(children_.begin(), children_.end(), child) ==
|
| children_.end());
|
|
|
| + // The new child goes to the top, which is the end of the list.
|
| children_.push_back(child);
|
| if (child->parent_)
|
| child->RemoveFromParent();
|
| child->parent_ = this;
|
| }
|
|
|
| +void ViewAndroid::MoveToTop(ViewAndroid* child) {
|
| + DCHECK(child);
|
| + auto it = std::find(children_.begin(), children_.end(), child);
|
| + DCHECK(it != children_.end());
|
| +
|
| + // Top element is placed at the end of the list.
|
| + if (*it != children_.back())
|
| + children_.splice(children_.rbegin().base(), children_, it);
|
| +}
|
| +
|
| void ViewAndroid::RemoveFromParent() {
|
| if (parent_)
|
| parent_->RemoveChild(this);
|
| }
|
|
|
| +void ViewAndroid::SetLayout(int x,
|
| + int y,
|
| + int width,
|
| + int height,
|
| + bool match_parent) {
|
| + DCHECK(!match_parent || (x == 0 && y == 0 && width == 0 && height == 0));
|
| + origin_.SetPoint(x, y);
|
| + size_.SetSize(width, height);
|
| + match_parent_ = match_parent;
|
| +}
|
| +
|
| ViewAndroid::ScopedAnchorView ViewAndroid::AcquireAnchorView() {
|
| ScopedJavaLocalRef<jobject> delegate(GetViewAndroidDelegate());
|
| if (delegate.is_null())
|
| @@ -116,15 +138,19 @@ ViewAndroid::ScopedAnchorView ViewAndroid::AcquireAnchorView() {
|
| env, Java_ViewAndroidDelegate_acquireView(env, delegate), delegate);
|
| }
|
|
|
| +float ViewAndroid::GetDipScale() {
|
| + return display::Screen::GetScreen()
|
| + ->GetDisplayNearestWindow(this)
|
| + .device_scale_factor();
|
| +}
|
| +
|
| void ViewAndroid::SetAnchorRect(const JavaRef<jobject>& anchor,
|
| const gfx::RectF& bounds) {
|
| ScopedJavaLocalRef<jobject> delegate(GetViewAndroidDelegate());
|
| if (delegate.is_null())
|
| return;
|
|
|
| - float scale = display::Screen::GetScreen()
|
| - ->GetDisplayNearestWindow(this)
|
| - .device_scale_factor();
|
| + float scale = GetDipScale();
|
| int left_margin = std::round(bounds.x() * scale);
|
| int top_margin = std::round((content_offset().y() + bounds.y()) * scale);
|
| JNIEnv* env = base::android::AttachCurrentThread();
|
| @@ -175,6 +201,14 @@ void ViewAndroid::SetLayer(scoped_refptr<cc::Layer> layer) {
|
| layer_ = layer;
|
| }
|
|
|
| +ViewAndroid* ViewAndroid::GetViewRoot() {
|
| + return parent_ ? parent_->GetViewRoot() : nullptr;
|
| +}
|
| +
|
| +bool ViewAndroid::IsViewRoot() {
|
| + return GetViewRoot() == this;
|
| +}
|
| +
|
| bool ViewAndroid::StartDragAndDrop(const JavaRef<jstring>& jtext,
|
| const JavaRef<jobject>& jimage) {
|
| ScopedJavaLocalRef<jobject> delegate(GetViewAndroidDelegate());
|
| @@ -185,4 +219,26 @@ bool ViewAndroid::StartDragAndDrop(const JavaRef<jstring>& jtext,
|
| jimage);
|
| }
|
|
|
| +bool ViewAndroid::OnTouchEventInternal(const MotionEventData& event) {
|
| + if (!children_.empty()) {
|
| + const MotionEventData& e =
|
| + origin_.IsOrigin() ? event : event.Offset(-origin_.x(), -origin_.y());
|
| +
|
| + for (auto it = children_.rbegin(); it != children_.rend(); ++it) {
|
| + bool matched = (*it)->match_parent_;
|
| + if (!matched) {
|
| + gfx::Rect bound((*it)->origin_, (*it)->size_);
|
| + matched = bound.Contains(e.GetX(), e.GetY());
|
| + }
|
| + if (matched && (*it)->OnTouchEventInternal(e))
|
| + return true;
|
| + }
|
| + }
|
| +
|
| + if (client_ && client_->OnTouchEvent(event))
|
| + return true;
|
| +
|
| + return false;
|
| +}
|
| +
|
| } // namespace ui
|
|
|