touch_browser_frame_view.cc revision 21d179b334e59e9a3bfcaed4c4430bef1bc5759d
1// Copyright (c) 2010 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "chrome/browser/ui/touch/frame/touch_browser_frame_view.h" 6 7#include <algorithm> 8 9#include "chrome/browser/profiles/profile.h" 10#include "chrome/browser/renderer_host/render_view_host.h" 11#include "chrome/browser/renderer_host/site_instance.h" 12#include "chrome/browser/tab_contents/navigation_controller.h" 13#include "chrome/browser/tab_contents/tab_contents.h" 14#include "chrome/browser/ui/browser.h" 15#include "chrome/browser/ui/views/dom_view.h" 16#include "chrome/browser/ui/views/frame/browser_view.h" 17#include "chrome/common/notification_service.h" 18#include "chrome/common/notification_type.h" 19#include "chrome/common/url_constants.h" 20#include "gfx/rect.h" 21 22namespace { 23 24const int kKeyboardHeight = 300; 25 26} // namespace 27 28/////////////////////////////////////////////////////////////////////////////// 29// TouchBrowserFrameView, public: 30 31TouchBrowserFrameView::TouchBrowserFrameView(BrowserFrame* frame, 32 BrowserView* browser_view) 33 : OpaqueBrowserFrameView(frame, browser_view), 34 keyboard_showing_(false), 35 keyboard_(NULL) { 36 registrar_.Add(this, 37 NotificationType::NAV_ENTRY_COMMITTED, 38 NotificationService::AllSources()); 39 registrar_.Add(this, 40 NotificationType::FOCUS_CHANGED_IN_PAGE, 41 NotificationService::AllSources()); 42} 43 44TouchBrowserFrameView::~TouchBrowserFrameView() { 45} 46 47void TouchBrowserFrameView::Layout() { 48 OpaqueBrowserFrameView::Layout(); 49 50 if (!keyboard_) 51 return; 52 53 keyboard_->SetBounds(GetBoundsForReservedArea()); 54 keyboard_->SetVisible(keyboard_showing_); 55 keyboard_->Layout(); 56} 57 58/////////////////////////////////////////////////////////////////////////////// 59// TouchBrowserFrameView, protected: 60int TouchBrowserFrameView::GetReservedHeight() const { 61 if (keyboard_showing_) 62 return kKeyboardHeight; 63 64 return 0; 65} 66 67/////////////////////////////////////////////////////////////////////////////// 68// TouchBrowserFrameView, private: 69 70void TouchBrowserFrameView::InitVirtualKeyboard() { 71 if (keyboard_) 72 return; 73 74 keyboard_ = new DOMView; 75 76 Profile* keyboard_profile = browser_view()->browser()->profile(); 77 DCHECK(keyboard_profile) << "Profile required for virtual keyboard."; 78 79 GURL keyboard_url(chrome::kChromeUIKeyboardURL); 80 keyboard_->Init(keyboard_profile, 81 SiteInstance::CreateSiteInstanceForURL(keyboard_profile, keyboard_url)); 82 keyboard_->LoadURL(keyboard_url); 83 84 keyboard_->SetVisible(false); 85 AddChildView(keyboard_); 86} 87 88void TouchBrowserFrameView::UpdateKeyboardAndLayout(bool should_show_keyboard) { 89 if (should_show_keyboard) 90 InitVirtualKeyboard(); 91 92 if (should_show_keyboard == keyboard_showing_) 93 return; 94 95 DCHECK(keyboard_); 96 97 keyboard_showing_ = should_show_keyboard; 98 99 // Because the NonClientFrameView is a sibling of the ClientView, we rely on 100 // the parent to resize the ClientView instead of resizing it directly. 101 GetParent()->Layout(); 102 103 // The keyboard that pops up may end up hiding the text entry. So make sure 104 // the renderer scrolls when necessary to keep the textfield visible. 105 if (keyboard_showing_) { 106 RenderViewHost* host = 107 browser_view()->browser()->GetSelectedTabContents()->render_view_host(); 108 host->ScrollFocusedEditableNodeIntoView(); 109 } 110} 111 112void TouchBrowserFrameView::Observe(NotificationType type, 113 const NotificationSource& source, 114 const NotificationDetails& details) { 115 Browser* browser = browser_view()->browser(); 116 if (type == NotificationType::FOCUS_CHANGED_IN_PAGE) { 117 // Only modify the keyboard state if the currently active tab sent the 118 // notification. 119 if (browser->GetSelectedTabContents()->render_view_host() == 120 Source<RenderViewHost>(source).ptr()) { 121 UpdateKeyboardAndLayout(*Details<const bool>(details).ptr()); 122 } 123 } else if (type == NotificationType::NAV_ENTRY_COMMITTED) { 124 Browser* source_browser = Browser::GetBrowserForController( 125 Source<NavigationController>(source).ptr(), NULL); 126 // If the Browser for the keyboard has navigated, hide the keyboard. 127 if (source_browser == browser) { 128 UpdateKeyboardAndLayout(false); 129 } 130 } 131} 132