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 21 using content::WebContents; 22 using content::WebUIMessageHandler; 23 24 namespace { 25 26 const int kBaseWidth = 1252; 27 const int kBaseHeight = 516; 28 const int kHorizontalMargin = 28; 29 30 // A message handler for detecting the timing when the web contents is painted. 31 class 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 49 void PaintMessageHandler::RegisterMessages() { 50 web_ui()->RegisterMessageCallback( 51 "didPaint", 52 base::Bind(&PaintMessageHandler::DidPaint, AsWeakPtr())); 53 } 54 55 void 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 62 namespace ash { 63 64 KeyboardOverlayDelegate::KeyboardOverlayDelegate(const base::string16& title, 65 const GURL& url) 66 : title_(title), 67 url_(url), 68 widget_(NULL) { 69 } 70 71 KeyboardOverlayDelegate::~KeyboardOverlayDelegate() { 72 } 73 74 views::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 97 ui::ModalType KeyboardOverlayDelegate::GetDialogModalType() const { 98 return ui::MODAL_TYPE_SYSTEM; 99 } 100 101 base::string16 KeyboardOverlayDelegate::GetDialogTitle() const { 102 return title_; 103 } 104 105 GURL KeyboardOverlayDelegate::GetDialogContentURL() const { 106 return url_; 107 } 108 109 void KeyboardOverlayDelegate::GetWebUIMessageHandlers( 110 std::vector<WebUIMessageHandler*>* handlers) const { 111 handlers->push_back(new PaintMessageHandler(widget_)); 112 } 113 114 void 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 125 std::string KeyboardOverlayDelegate::GetDialogArgs() const { 126 return "[]"; 127 } 128 129 void KeyboardOverlayDelegate::OnDialogClosed( 130 const std::string& json_retval) { 131 delete this; 132 return; 133 } 134 135 void KeyboardOverlayDelegate::OnCloseContents(WebContents* source, 136 bool* out_close_dialog) { 137 } 138 139 bool KeyboardOverlayDelegate::ShouldShowDialogTitle() const { 140 return false; 141 } 142 143 bool KeyboardOverlayDelegate::HandleContextMenu( 144 const content::ContextMenuParams& params) { 145 return true; 146 } 147 148 } // namespace ash 149