15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/keyboard_overlay/keyboard_overlay_delegate.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/shell.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/weak_ptr.h"
12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_ui.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_ui_message_handler.h"
16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/aura/window_event_dispatcher.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/screen.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/webview/web_dialog_view.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/widget/widget.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::WebContents;
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::WebUIMessageHandler;
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kBaseWidth = 1252;
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kBaseHeight = 516;
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kHorizontalMargin = 28;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A message handler for detecting the timing when the web contents is painted.
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PaintMessageHandler
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : public WebUIMessageHandler,
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      public base::SupportsWeakPtr<PaintMessageHandler> {
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit PaintMessageHandler(views::Widget* widget) : widget_(widget) {}
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~PaintMessageHandler() {}
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // WebUIMessageHandler implementation.
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void RegisterMessages() OVERRIDE;
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void DidPaint(const base::ListValue* args);
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  views::Widget* widget_;
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(PaintMessageHandler);
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PaintMessageHandler::RegisterMessages() {
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  web_ui()->RegisterMessageCallback(
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "didPaint",
53f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      base::Bind(&PaintMessageHandler::DidPaint, AsWeakPtr()));
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void PaintMessageHandler::DidPaint(const base::ListValue* args) {
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Show the widget after the web content has been painted.
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  widget_->Show();
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ash {
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)KeyboardOverlayDelegate::KeyboardOverlayDelegate(const base::string16& title,
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                 const GURL& url)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : title_(title),
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url_(url),
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      widget_(NULL) {
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)KeyboardOverlayDelegate::~KeyboardOverlayDelegate() {
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)views::Widget* KeyboardOverlayDelegate::Show(views::WebDialogView* view) {
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget_ = new views::Widget;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  views::Widget::InitParams params(
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      views::Widget::InitParams::TYPE_WINDOW_FRAMELESS);
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  params.context = Shell::GetPrimaryRootWindow();
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.delegate = view;
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget_->Init(params);
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Show the widget at the bottom of the work area.
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Size size;
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetDialogSize(&size);
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const gfx::Rect& rect = Shell::GetScreen()->GetDisplayNearestWindow(
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      widget_->GetNativeView()).work_area();
884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  gfx::Rect bounds(rect.x() + (rect.width() - size.width()) / 2,
894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                   rect.bottom() - size.height(),
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   size.width(),
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   size.height());
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget_->SetBounds(bounds);
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The widget will be shown when the web contents gets ready to display.
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return widget_;
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ui::ModalType KeyboardOverlayDelegate::GetDialogModalType() const {
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ui::MODAL_TYPE_SYSTEM;
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)base::string16 KeyboardOverlayDelegate::GetDialogTitle() const {
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return title_;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GURL KeyboardOverlayDelegate::GetDialogContentURL() const {
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return url_;
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void KeyboardOverlayDelegate::GetWebUIMessageHandlers(
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::vector<WebUIMessageHandler*>* handlers) const {
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  handlers->push_back(new PaintMessageHandler(widget_));
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void KeyboardOverlayDelegate::GetDialogSize(
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gfx::Size* size) const {
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  using std::min;
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(widget_);
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Rect rect = ash::Shell::GetScreen()->GetDisplayNearestWindow(
1204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      widget_->GetNativeView()).work_area();
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int width = min(kBaseWidth, rect.width() - kHorizontalMargin);
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int height = width * kBaseHeight / kBaseWidth;
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size->SetSize(width, height);
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string KeyboardOverlayDelegate::GetDialogArgs() const {
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return "[]";
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void KeyboardOverlayDelegate::OnDialogClosed(
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& json_retval) {
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delete this;
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return;
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void KeyboardOverlayDelegate::OnCloseContents(WebContents* source,
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              bool* out_close_dialog) {
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool KeyboardOverlayDelegate::ShouldShowDialogTitle() const {
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool KeyboardOverlayDelegate::HandleContextMenu(
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const content::ContextMenuParams& params) {
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace ash
150