1// Copyright (c) 2012 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 "ash/keyboard_overlay/keyboard_overlay_delegate.h" 6 7#include <algorithm> 8 9#include "ash/shell.h" 10#include "base/bind.h" 11#include "base/memory/weak_ptr.h" 12#include "base/strings/utf_string_conversions.h" 13#include "base/values.h" 14#include "content/public/browser/web_ui.h" 15#include "content/public/browser/web_ui_message_handler.h" 16#include "ui/aura/window_event_dispatcher.h" 17#include "ui/gfx/screen.h" 18#include "ui/views/controls/webview/web_dialog_view.h" 19#include "ui/views/widget/widget.h" 20 21using content::WebContents; 22using content::WebUIMessageHandler; 23 24namespace { 25 26const int kBaseWidth = 1252; 27const int kBaseHeight = 516; 28const int kHorizontalMargin = 28; 29 30// A message handler for detecting the timing when the web contents is painted. 31class PaintMessageHandler 32 : public WebUIMessageHandler, 33 public base::SupportsWeakPtr<PaintMessageHandler> { 34 public: 35 explicit PaintMessageHandler(views::Widget* widget) : widget_(widget) {} 36 virtual ~PaintMessageHandler() {} 37 38 // WebUIMessageHandler implementation. 39 virtual void RegisterMessages() OVERRIDE; 40 41 private: 42 void DidPaint(const base::ListValue* args); 43 44 views::Widget* widget_; 45 46 DISALLOW_COPY_AND_ASSIGN(PaintMessageHandler); 47}; 48 49void PaintMessageHandler::RegisterMessages() { 50 web_ui()->RegisterMessageCallback( 51 "didPaint", 52 base::Bind(&PaintMessageHandler::DidPaint, AsWeakPtr())); 53} 54 55void PaintMessageHandler::DidPaint(const base::ListValue* args) { 56 // Show the widget after the web content has been painted. 57 widget_->Show(); 58} 59 60} // namespace 61 62namespace ash { 63 64KeyboardOverlayDelegate::KeyboardOverlayDelegate(const base::string16& title, 65 const GURL& url) 66 : title_(title), 67 url_(url), 68 widget_(NULL) { 69} 70 71KeyboardOverlayDelegate::~KeyboardOverlayDelegate() { 72} 73 74views::Widget* KeyboardOverlayDelegate::Show(views::WebDialogView* view) { 75 widget_ = new views::Widget; 76 views::Widget::InitParams params( 77 views::Widget::InitParams::TYPE_WINDOW_FRAMELESS); 78 params.context = Shell::GetPrimaryRootWindow(); 79 params.delegate = view; 80 widget_->Init(params); 81 82 // Show the widget at the bottom of the work area. 83 gfx::Size size; 84 GetDialogSize(&size); 85 const gfx::Rect& rect = Shell::GetScreen()->GetDisplayNearestWindow( 86 widget_->GetNativeView()).work_area(); 87 gfx::Rect bounds(rect.x() + (rect.width() - size.width()) / 2, 88 rect.bottom() - size.height(), 89 size.width(), 90 size.height()); 91 widget_->SetBounds(bounds); 92 93 // The widget will be shown when the web contents gets ready to display. 94 return widget_; 95} 96 97ui::ModalType KeyboardOverlayDelegate::GetDialogModalType() const { 98 return ui::MODAL_TYPE_SYSTEM; 99} 100 101base::string16 KeyboardOverlayDelegate::GetDialogTitle() const { 102 return title_; 103} 104 105GURL KeyboardOverlayDelegate::GetDialogContentURL() const { 106 return url_; 107} 108 109void KeyboardOverlayDelegate::GetWebUIMessageHandlers( 110 std::vector<WebUIMessageHandler*>* handlers) const { 111 handlers->push_back(new PaintMessageHandler(widget_)); 112} 113 114void KeyboardOverlayDelegate::GetDialogSize( 115 gfx::Size* size) const { 116 using std::min; 117 DCHECK(widget_); 118 gfx::Rect rect = ash::Shell::GetScreen()->GetDisplayNearestWindow( 119 widget_->GetNativeView()).work_area(); 120 const int width = min(kBaseWidth, rect.width() - kHorizontalMargin); 121 const int height = width * kBaseHeight / kBaseWidth; 122 size->SetSize(width, height); 123} 124 125std::string KeyboardOverlayDelegate::GetDialogArgs() const { 126 return "[]"; 127} 128 129void KeyboardOverlayDelegate::OnDialogClosed( 130 const std::string& json_retval) { 131 delete this; 132 return; 133} 134 135void KeyboardOverlayDelegate::OnCloseContents(WebContents* source, 136 bool* out_close_dialog) { 137} 138 139bool KeyboardOverlayDelegate::ShouldShowDialogTitle() const { 140 return false; 141} 142 143bool KeyboardOverlayDelegate::HandleContextMenu( 144 const content::ContextMenuParams& params) { 145 return true; 146} 147 148} // namespace ash 149