1dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// Use of this source code is governed by a BSD-style license that can be
321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// found in the LICENSE file.
421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/ui/touch/frame/touch_browser_frame_view.h"
621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/profiles/profile.h"
872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/renderer_host/render_widget_host_view_views.h"
972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/tabs/tab_strip_model.h"
1021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/ui/browser.h"
1172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
1272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/touch/frame/keyboard_container_view.h"
1321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/ui/views/frame/browser_view.h"
14ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ui/views/tab_contents/tab_contents_view_touch.h"
15dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/renderer_host/render_view_host.h"
16dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/tab_contents/navigation_controller.h"
17dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/tab_contents/tab_contents.h"
18ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/browser/tab_contents/tab_contents_view.h"
19ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_service.h"
20ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_type.h"
21dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "ui/base/animation/slide_animation.h"
2272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/gfx/rect.h"
23ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "views/controls/button/image_button.h"
2472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "views/controls/textfield/textfield.h"
25ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "views/focus/focus_manager.h"
2621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
2721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsennamespace {
2821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
2921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenconst int kKeyboardHeight = 300;
30dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenconst int kKeyboardSlideDuration = 500;  // In milliseconds
3121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
3272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenPropertyAccessor<bool>* GetFocusedStateAccessor() {
3372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  static PropertyAccessor<bool> state;
3472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  return &state;
3572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
3672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
37ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool TabContentsHasFocus(const TabContents* contents) {
38ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  views::View* view = static_cast<TabContentsViewTouch*>(contents->view());
39ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return view->Contains(view->GetFocusManager()->GetFocusedView());
40ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
41ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
4221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}  // namespace
4321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
4421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen///////////////////////////////////////////////////////////////////////////////
4521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// TouchBrowserFrameView, public:
4621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
4721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTouchBrowserFrameView::TouchBrowserFrameView(BrowserFrame* frame,
4821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                                             BrowserView* browser_view)
4921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    : OpaqueBrowserFrameView(frame, browser_view),
5021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      keyboard_showing_(false),
5172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      focus_listener_added_(false),
5221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      keyboard_(NULL) {
5321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  registrar_.Add(this,
5421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                 NotificationType::NAV_ENTRY_COMMITTED,
5521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                 NotificationService::AllSources());
5621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  registrar_.Add(this,
5721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                 NotificationType::FOCUS_CHANGED_IN_PAGE,
5821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                 NotificationService::AllSources());
5972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  registrar_.Add(this,
6072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                 NotificationType::TAB_CONTENTS_DESTROYED,
6172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                 NotificationService::AllSources());
6272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
6372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  browser_view->browser()->tabstrip_model()->AddObserver(this);
64dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
65dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  animation_.reset(new ui::SlideAnimation(this));
66dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  animation_->SetTweenType(ui::Tween::LINEAR);
67dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  animation_->SetSlideDuration(kKeyboardSlideDuration);
6821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
6921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
7021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTouchBrowserFrameView::~TouchBrowserFrameView() {
7172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  browser_view()->browser()->tabstrip_model()->RemoveObserver(this);
7221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
7321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
7421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid TouchBrowserFrameView::Layout() {
7521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  OpaqueBrowserFrameView::Layout();
7621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
7721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (!keyboard_)
7821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    return;
7921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
80dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  keyboard_->SetVisible(keyboard_showing_ || animation_->is_animating());
81dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  gfx::Rect bounds = GetBoundsForReservedArea();
82dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  if (animation_->is_animating() && !keyboard_showing_) {
83dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    // The keyboard is in the process of hiding. So pretend it still has the
84dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    // same bounds as when the keyboard is visible. But
85dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    // |GetBoundsForReservedArea| should not take this into account so that the
86dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    // render view gets the entire area to relayout itself.
87dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    bounds.set_y(bounds.y() - kKeyboardHeight);
88dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    bounds.set_height(kKeyboardHeight);
89dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  }
90dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  keyboard_->SetBoundsRect(bounds);
9172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
9272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
9372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid TouchBrowserFrameView::FocusWillChange(views::View* focused_before,
9472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                            views::View* focused_now) {
9572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  VirtualKeyboardType before = DecideKeyboardStateForView(focused_before);
9672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  VirtualKeyboardType now = DecideKeyboardStateForView(focused_now);
9772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (before != now) {
9872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    // TODO(varunjain): support other types of keyboard.
9972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    UpdateKeyboardAndLayout(now == GENERIC);
10072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
10121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
10221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
10321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen///////////////////////////////////////////////////////////////////////////////
10421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// TouchBrowserFrameView, protected:
10521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenint TouchBrowserFrameView::GetReservedHeight() const {
106dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  return keyboard_showing_ ? kKeyboardHeight : 0;
10721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
10821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
10972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid TouchBrowserFrameView::ViewHierarchyChanged(bool is_add,
11072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                                 View* parent,
11172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                                 View* child) {
11272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  OpaqueBrowserFrameView::ViewHierarchyChanged(is_add, parent, child);
11372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (!GetFocusManager())
11472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return;
11572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
11672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (is_add && !focus_listener_added_) {
11772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    // Add focus listener when this view is added to the hierarchy.
11872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    GetFocusManager()->AddFocusChangeListener(this);
11972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    focus_listener_added_ = true;
12072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  } else if (!is_add && focus_listener_added_) {
12172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    // Remove focus listener when this view is removed from the hierarchy.
12272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    GetFocusManager()->RemoveFocusChangeListener(this);
12372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    focus_listener_added_ = false;
12472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
12572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
12672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
12721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen///////////////////////////////////////////////////////////////////////////////
12821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// TouchBrowserFrameView, private:
12921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
13021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid TouchBrowserFrameView::InitVirtualKeyboard() {
13121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (keyboard_)
13221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    return;
13321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
13421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  Profile* keyboard_profile = browser_view()->browser()->profile();
13521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  DCHECK(keyboard_profile) << "Profile required for virtual keyboard.";
13621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
13772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  keyboard_ = new KeyboardContainerView(keyboard_profile);
13821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  keyboard_->SetVisible(false);
13921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  AddChildView(keyboard_);
14021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
14121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
14221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid TouchBrowserFrameView::UpdateKeyboardAndLayout(bool should_show_keyboard) {
14321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (should_show_keyboard)
14421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    InitVirtualKeyboard();
14521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
14621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (should_show_keyboard == keyboard_showing_)
14721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    return;
14821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
14921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  DCHECK(keyboard_);
15021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
15121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  keyboard_showing_ = should_show_keyboard;
15221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (keyboard_showing_) {
153dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    animation_->Show();
154dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
155dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    // We don't re-layout the client view until the animation ends (see
156dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    // AnimationEnded below) because we want the client view to occupy the
157dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    // entire height during the animation.
158dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    Layout();
159dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  } else {
160dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    animation_->Hide();
161dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
162dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    browser_view()->set_clip_y(ui::Tween::ValueBetween(
163dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen          animation_->GetCurrentValue(), 0, kKeyboardHeight));
164dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    parent()->Layout();
16521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
16621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
16721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
16872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenTouchBrowserFrameView::VirtualKeyboardType
16972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    TouchBrowserFrameView::DecideKeyboardStateForView(views::View* view) {
17072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (!view)
17172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return NONE;
17272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
17372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  std::string cname = view->GetClassName();
17472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (cname == views::Textfield::kViewClassName) {
17572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return GENERIC;
17672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  } else if (cname == RenderWidgetHostViewViews::kViewClassName) {
17772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    TabContents* contents = browser_view()->browser()->GetSelectedTabContents();
17872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    bool* editable = contents ? GetFocusedStateAccessor()->GetProperty(
17972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        contents->property_bag()) : NULL;
18072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    if (editable && *editable)
18172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      return GENERIC;
18272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
18372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  return NONE;
18472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
18572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
186ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool TouchBrowserFrameView::HitTest(const gfx::Point& point) const {
187ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (OpaqueBrowserFrameView::HitTest(point))
188ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return true;
189ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
190ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (close_button()->IsVisible() &&
191ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      close_button()->GetMirroredBounds().Contains(point))
192ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return true;
193ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (restore_button()->IsVisible() &&
194ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      restore_button()->GetMirroredBounds().Contains(point))
195ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return true;
196ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (maximize_button()->IsVisible() &&
197ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      maximize_button()->GetMirroredBounds().Contains(point))
198ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return true;
199ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (minimize_button()->IsVisible() &&
200ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      minimize_button()->GetMirroredBounds().Contains(point))
201ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return true;
202ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
203ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return false;
204ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
205ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
20672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid TouchBrowserFrameView::TabSelectedAt(TabContentsWrapper* old_contents,
20772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                          TabContentsWrapper* new_contents,
20872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                          int index,
20972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                          bool user_gesture) {
210dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  if (new_contents == old_contents)
211dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    return;
212dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
21372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  TabContents* contents = new_contents->tab_contents();
214ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (!TabContentsHasFocus(contents))
215ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return;
216ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
21772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  bool* editable = GetFocusedStateAccessor()->GetProperty(
21872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      contents->property_bag());
21972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  UpdateKeyboardAndLayout(editable ? *editable : false);
22072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
22172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
22272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
22321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid TouchBrowserFrameView::Observe(NotificationType type,
22421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                                    const NotificationSource& source,
22521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                                    const NotificationDetails& details) {
22621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  Browser* browser = browser_view()->browser();
22721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (type == NotificationType::FOCUS_CHANGED_IN_PAGE) {
22821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // Only modify the keyboard state if the currently active tab sent the
22921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // notification.
23072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    const TabContents* current_tab = browser->GetSelectedTabContents();
23172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    TabContents* source_tab = Source<TabContents>(source).ptr();
23272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    const bool editable = *Details<const bool>(details).ptr();
23372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
234ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (current_tab == source_tab && TabContentsHasFocus(source_tab))
23572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      UpdateKeyboardAndLayout(editable);
23672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
23772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    // Save the state of the focused field so that the keyboard visibility
23872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    // can be determined after tab switching.
23972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    GetFocusedStateAccessor()->SetProperty(
24072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        source_tab->property_bag(), editable);
24121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  } else if (type == NotificationType::NAV_ENTRY_COMMITTED) {
24221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    Browser* source_browser = Browser::GetBrowserForController(
24321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        Source<NavigationController>(source).ptr(), NULL);
244ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // If the Browser for the keyboard has navigated, re-evaluate the visibility
245ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // of the keyboard.
2463f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    if (source_browser == browser)
247ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      UpdateKeyboardAndLayout(DecideKeyboardStateForView(
248ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          GetFocusManager()->GetFocusedView()) == GENERIC);
24972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  } else if (type == NotificationType::TAB_CONTENTS_DESTROYED) {
25072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    GetFocusedStateAccessor()->DeleteProperty(
25172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        Source<TabContents>(source).ptr()->property_bag());
25221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
25321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
254dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
255dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen///////////////////////////////////////////////////////////////////////////////
256dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// ui::AnimationDelegate implementation
257dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid TouchBrowserFrameView::AnimationProgressed(const ui::Animation* anim) {
258dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  keyboard_->SetTranslateY(
259dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      ui::Tween::ValueBetween(anim->GetCurrentValue(), kKeyboardHeight, 0));
260dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  browser_view()->set_clip_y(
261dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      ui::Tween::ValueBetween(anim->GetCurrentValue(), 0, kKeyboardHeight));
262dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  SchedulePaint();
263dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
264dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
265dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid TouchBrowserFrameView::AnimationEnded(const ui::Animation* animation) {
266dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  browser_view()->set_clip_y(0);
267dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  if (keyboard_showing_) {
268dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    // Because the NonClientFrameView is a sibling of the ClientView, we rely on
269dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    // the parent to resize the ClientView instead of resizing it directly.
270dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    parent()->Layout();
271dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
272dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    // The keyboard that pops up may end up hiding the text entry. So make sure
273dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    // the renderer scrolls when necessary to keep the textfield visible.
274dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    RenderViewHost* host =
275dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        browser_view()->browser()->GetSelectedTabContents()->render_view_host();
276dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    host->ScrollFocusedEditableNodeIntoView();
277dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  }
278dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  SchedulePaint();
279dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
280