X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fmojo%2Fexamples%2Fbrowser%2Fbrowser.cc;h=bd854949ca658642df1247fc541f51ea89c2f474;hb=4a1a0bdd01eef90b0826a0e761d3379d3715c10f;hp=d5b6caeeead7b44f8eca7cfb518fb32a87444b9b;hpb=b1be5ca53587d23e7aeb77b26861fdc0a181ffd8;p=platform%2Fframework%2Fweb%2Fcrosswalk.git diff --git a/src/mojo/examples/browser/browser.cc b/src/mojo/examples/browser/browser.cc index d5b6cae..bd85494 100644 --- a/src/mojo/examples/browser/browser.cc +++ b/src/mojo/examples/browser/browser.cc @@ -5,21 +5,30 @@ #include "base/basictypes.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" -#include "mojo/public/cpp/application/application.h" -#include "mojo/services/public/cpp/view_manager/node.h" +#include "mojo/common/common_type_converters.h" +#include "mojo/examples/window_manager/window_manager.mojom.h" +#include "mojo/public/cpp/application/application_connection.h" +#include "mojo/public/cpp/application/application_delegate.h" +#include "mojo/public/cpp/application/application_impl.h" +#include "mojo/services/public/cpp/geometry/geometry_type_converters.h" #include "mojo/services/public/cpp/view_manager/view.h" #include "mojo/services/public/cpp/view_manager/view_manager.h" +#include "mojo/services/public/cpp/view_manager/view_manager_client_factory.h" #include "mojo/services/public/cpp/view_manager/view_manager_delegate.h" -#include "mojo/services/public/cpp/view_manager/view_observer.h" #include "mojo/services/public/interfaces/navigation/navigation.mojom.h" #include "mojo/views/native_widget_view_manager.h" #include "mojo/views/views_init.h" +#include "ui/aura/client/focus_client.h" +#include "ui/aura/window.h" #include "ui/events/event.h" +#include "ui/views/background.h" #include "ui/views/controls/textfield/textfield.h" #include "ui/views/controls/textfield/textfield_controller.h" +#include "ui/views/focus/focus_manager.h" #include "ui/views/layout/layout_manager.h" #include "ui/views/widget/widget.h" #include "ui/views/widget/widget_delegate.h" +#include "ui/views/widget/widget_observer.h" #include "url/gurl.h" namespace mojo { @@ -46,53 +55,168 @@ class BrowserLayoutManager : public views::LayoutManager { DISALLOW_COPY_AND_ASSIGN(BrowserLayoutManager); }; +// KeyboardManager handles notifying the windowmanager when views are focused. +// To use create one and KeyboardManager will take care of all other details. +// +// TODO(sky): it would be nice if this were put in NativeWidgetViewManager, but +// that requires NativeWidgetViewManager to take an IWindowManager. That may be +// desirable anyway... +class KeyboardManager + : public views::FocusChangeListener, + public ui::EventHandler, + public views::WidgetObserver { + public: + KeyboardManager(views::Widget* widget, + IWindowManager* window_manager, + View* view) + : widget_(widget), + window_manager_(window_manager), + view_(view), + last_view_id_(0), + focused_view_(NULL) { + widget_->GetFocusManager()->AddFocusChangeListener(this); + widget_->AddObserver(this); + widget_->GetNativeView()->AddPostTargetHandler(this); + } + + private: + virtual ~KeyboardManager() { + widget_->GetFocusManager()->RemoveFocusChangeListener(this); + widget_->GetNativeView()->RemovePostTargetHandler(this); + widget_->RemoveObserver(this); + + HideKeyboard(); + } + + void ShowKeyboard(views::View* view) { + if (focused_view_ == view) + return; + + const gfx::Rect bounds_in_widget = + view->ConvertRectToWidget(gfx::Rect(view->bounds().size())); + last_view_id_ = view_->id(); + window_manager_->ShowKeyboard(last_view_id_, + Rect::From(bounds_in_widget)); + // TODO(sky): listen for view to be removed. + focused_view_ = view; + } + + void HideKeyboard() { + if (!focused_view_) + return; + + window_manager_->HideKeyboard(last_view_id_); + last_view_id_ = 0; + focused_view_ = NULL; + } + + // views::FocusChangeListener: + virtual void OnWillChangeFocus(views::View* focused_before, + views::View* focused_now) OVERRIDE { + } + virtual void OnDidChangeFocus(views::View* focused_before, + views::View* focused_now) OVERRIDE { + if (focused_view_ && focused_now != focused_view_) + HideKeyboard(); + } + + // ui::EventHandler: + virtual void OnMouseEvent(ui::MouseEvent* event) OVERRIDE { + views::View* focused_now = widget_->GetFocusManager()->GetFocusedView(); + if (focused_now && + focused_now->GetClassName() == views::Textfield::kViewClassName && + (event->flags() & ui::EF_FROM_TOUCH) != 0) { + ShowKeyboard(focused_now); + } + } + + // views::WidgetObserver: + virtual void OnWidgetDestroying(views::Widget* widget) OVERRIDE { + delete this; + } + + views::Widget* widget_; + IWindowManager* window_manager_; + View* view_; + Id last_view_id_; + views::View* focused_view_; + + DISALLOW_COPY_AND_ASSIGN(KeyboardManager); +}; + // This is the basics of creating a views widget with a textfield. // TODO: cleanup! -class Browser : public Application, - public view_manager::ViewManagerDelegate, - public views::TextfieldController { +class Browser : public ApplicationDelegate, + public ViewManagerDelegate, + public views::TextfieldController, + public ViewObserver { public: - Browser() : view_manager_(NULL) {} + Browser() + : view_manager_(NULL), + view_manager_client_factory_(this), + root_(NULL), + widget_(NULL) {} virtual ~Browser() { + if (root_) + root_->RemoveObserver(this); } private: - // Overridden from Application: - virtual void Initialize() MOJO_OVERRIDE { + // Overridden from ApplicationDelegate: + virtual void Initialize(ApplicationImpl* app) MOJO_OVERRIDE { views_init_.reset(new ViewsInit); - view_manager::ViewManager::Create(this, this); - ConnectTo("mojo:mojo_window_manager", &navigator_host_); + app->ConnectToService("mojo:mojo_window_manager", &navigator_host_); + app->ConnectToService("mojo:mojo_window_manager", &window_manager_); + } + + virtual bool ConfigureIncomingConnection(ApplicationConnection* connection) + MOJO_OVERRIDE { + connection->AddService(&view_manager_client_factory_); + return true; } - void CreateWidget(view_manager::Node* node) { + void CreateWidget(View* view) { views::Textfield* textfield = new views::Textfield; textfield->set_controller(this); views::WidgetDelegateView* widget_delegate = new views::WidgetDelegateView; + widget_delegate->GetContentsView()->set_background( + views::Background::CreateSolidBackground(SK_ColorBLUE)); widget_delegate->GetContentsView()->AddChildView(textfield); widget_delegate->GetContentsView()->SetLayoutManager( new BrowserLayoutManager); - views::Widget* widget = new views::Widget; + widget_ = new views::Widget; views::Widget::InitParams params( views::Widget::InitParams::TYPE_WINDOW_FRAMELESS); - params.native_widget = new NativeWidgetViewManager(widget, node); + params.native_widget = new NativeWidgetViewManager(widget_, view); params.delegate = widget_delegate; - params.bounds = gfx::Rect(node->bounds().width(), node->bounds().height()); - widget->Init(params); - widget->Show(); + params.bounds = gfx::Rect(view->bounds().width(), view->bounds().height()); + widget_->Init(params); + // KeyboardManager handles deleting itself when the widget is destroyed. + new KeyboardManager(widget_, window_manager_.get(), view); + widget_->Show(); textfield->RequestFocus(); } - // view_manager::ViewManagerDelegate: - virtual void OnRootAdded(view_manager::ViewManager* view_manager, - view_manager::Node* root) OVERRIDE { - // TODO: deal with OnRootAdded() being invoked multiple times. + // ViewManagerDelegate: + virtual void OnEmbed(ViewManager* view_manager, + View* root, + ServiceProviderImpl* exported_services, + scoped_ptr imported_services) OVERRIDE { + // TODO: deal with OnEmbed() being invoked multiple times. view_manager_ = view_manager; - root->SetActiveView(view_manager::View::Create(view_manager)); - root->SetFocus(); - CreateWidget(root); + root_ = root; + root_->AddObserver(this); + root_->SetFocus(); + CreateWidget(root_); + } + virtual void OnViewManagerDisconnected( + ViewManager* view_manager) OVERRIDE { + DCHECK_EQ(view_manager_, view_manager); + view_manager_ = NULL; + base::MessageLoop::current()->Quit(); } // views::TextfieldController: @@ -101,19 +225,39 @@ class Browser : public Application, if (key_event.key_code() == ui::VKEY_RETURN) { GURL url(sender->text()); printf("User entered this URL: %s\n", url.spec().c_str()); - navigation::NavigationDetailsPtr nav_details( - navigation::NavigationDetails::New()); - nav_details->url = url.spec(); + NavigationDetailsPtr nav_details(NavigationDetails::New()); + nav_details->request->url = String::From(url); navigator_host_->RequestNavigate(view_manager_->GetRoots().front()->id(), + TARGET_NEW_NODE, nav_details.Pass()); } return false; } + // ViewObserver: + virtual void OnViewFocusChanged(View* gained_focus, + View* lost_focus) OVERRIDE { + aura::client::FocusClient* focus_client = + aura::client::GetFocusClient(widget_->GetNativeView()); + if (lost_focus == root_) + focus_client->FocusWindow(NULL); + else if (gained_focus == root_) + focus_client->FocusWindow(widget_->GetNativeView()); + } + virtual void OnViewDestroyed(View* view) OVERRIDE { + DCHECK_EQ(root_, view); + view->RemoveObserver(this); + root_ = NULL; + } + scoped_ptr views_init_; - view_manager::ViewManager* view_manager_; - navigation::NavigatorHostPtr navigator_host_; + ViewManager* view_manager_; + ViewManagerClientFactory view_manager_client_factory_; + View* root_; + views::Widget* widget_; + NavigatorHostPtr navigator_host_; + IWindowManagerPtr window_manager_; DISALLOW_COPY_AND_ASSIGN(Browser); }; @@ -121,7 +265,7 @@ class Browser : public Application, } // namespace examples // static -Application* Application::Create() { +ApplicationDelegate* ApplicationDelegate::Create() { return new examples::Browser; }