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