summaryrefslogtreecommitdiffstats
path: root/chrome/browser/ui/touch/frame/touch_browser_frame_view.cc
blob: d3c960ee48a3c3f2e796aae03c4f110ebf762c7a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/ui/touch/frame/touch_browser_frame_view.h"

#include <algorithm>

#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/renderer_host/site_instance.h"
#include "chrome/browser/tab_contents/navigation_controller.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/views/dom_view.h"
#include "chrome/browser/ui/views/frame/browser_view.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/notification_type.h"
#include "chrome/common/url_constants.h"
#include "gfx/rect.h"

namespace {

const int kKeyboardHeight = 300;

}  // namespace

///////////////////////////////////////////////////////////////////////////////
// TouchBrowserFrameView, public:

TouchBrowserFrameView::TouchBrowserFrameView(BrowserFrame* frame,
                                             BrowserView* browser_view)
    : OpaqueBrowserFrameView(frame, browser_view),
      keyboard_showing_(false),
      keyboard_(NULL) {
  registrar_.Add(this,
                 NotificationType::NAV_ENTRY_COMMITTED,
                 NotificationService::AllSources());
  registrar_.Add(this,
                 NotificationType::FOCUS_CHANGED_IN_PAGE,
                 NotificationService::AllSources());
}

TouchBrowserFrameView::~TouchBrowserFrameView() {
}

///////////////////////////////////////////////////////////////////////////////
// TouchBrowserFrameView, protected:
int TouchBrowserFrameView::GetReservedHeight() const {
  if (keyboard_showing_)
    return kKeyboardHeight;

  return 0;
}

///////////////////////////////////////////////////////////////////////////////
// TouchBrowserFrameView, private:

void TouchBrowserFrameView::InitVirtualKeyboard() {
  if (keyboard_)
    return;

  keyboard_ = new DOMView;

  Profile* keyboard_profile = browser_view()->browser()->profile();
  DCHECK(keyboard_profile) << "Profile required for virtual keyboard.";

  GURL keyboard_url(chrome::kChromeUIKeyboardURL);
  keyboard_->Init(keyboard_profile,
      SiteInstance::CreateSiteInstanceForURL(keyboard_profile, keyboard_url));
  keyboard_->LoadURL(keyboard_url);

  keyboard_->SetVisible(false);
  AddChildView(keyboard_);
}

void TouchBrowserFrameView::UpdateKeyboardAndLayout(bool should_show_keyboard) {
  if (should_show_keyboard)
    InitVirtualKeyboard();

  if (should_show_keyboard == keyboard_showing_)
    return;

  DCHECK(keyboard_);

  keyboard_showing_ = should_show_keyboard;

  keyboard_->SetBounds(GetBoundsForReservedArea());
  keyboard_->SetVisible(should_show_keyboard);

  // Because the NonClientFrameView is a sibling of the ClientView, we rely on
  // the parent to resize the ClientView instead of resizing it directly.
  GetParent()->Layout();
}

void TouchBrowserFrameView::Observe(NotificationType type,
                                    const NotificationSource& source,
                                    const NotificationDetails& details) {
  Browser* browser = browser_view()->browser();
  if (type == NotificationType::FOCUS_CHANGED_IN_PAGE) {
    // Only modify the keyboard state if the notification is coming from
    // a source within the same Browser.
    Source<RenderViewHost> specific_source(source);
    for (int i = 0; i < browser->tab_count(); ++i) {
      if (browser->GetTabContentsAt(i)->render_view_host() ==
          specific_source.ptr()) {
        UpdateKeyboardAndLayout(*Details<const bool>(details).ptr());
        break;
      }
    }
  } else if (type == NotificationType::NAV_ENTRY_COMMITTED) {
    Browser* source_browser = Browser::GetBrowserForController(
        Source<NavigationController>(source).ptr(), NULL);
    // If the Browser for the keyboard has navigated, hide the keyboard.
    if (source_browser == browser) {
      UpdateKeyboardAndLayout(false);
    }
  }
}