| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/chromeos/app_launcher.h" | 5 #include "chrome/browser/views/app_launcher.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "app/gfx/canvas.h" | |
| 11 #include "app/gfx/insets.h" | |
| 12 #include "app/resource_bundle.h" | 10 #include "app/resource_bundle.h" |
| 13 #include "base/command_line.h" | 11 #include "base/command_line.h" |
| 14 #include "base/message_loop.h" | 12 #include "base/message_loop.h" |
| 15 #include "base/string_util.h" | 13 #include "base/string_util.h" |
| 14 #include "base/task.h" |
| 16 #include "chrome/browser/autocomplete/autocomplete_edit.h" | 15 #include "chrome/browser/autocomplete/autocomplete_edit.h" |
| 17 #include "chrome/browser/autocomplete/autocomplete_edit_view_gtk.h" | 16 #include "chrome/browser/autocomplete/autocomplete_edit_view.h" |
| 18 #include "chrome/browser/browser.h" | 17 #include "chrome/browser/browser.h" |
| 19 #include "chrome/browser/browser_list.h" | |
| 20 #include "chrome/browser/browser_window.h" | 18 #include "chrome/browser/browser_window.h" |
| 21 #include "chrome/browser/bubble_positioner.h" | 19 #include "chrome/browser/bubble_positioner.h" |
| 22 #include "chrome/browser/chromeos/frame/browser_view.h" | |
| 23 #include "chrome/browser/chromeos/status/status_area_view.h" | |
| 24 #include "chrome/browser/chromeos/wm_ipc.h" | |
| 25 #include "chrome/browser/in_process_webkit/dom_storage_context.h" | |
| 26 #include "chrome/browser/in_process_webkit/webkit_context.h" | 20 #include "chrome/browser/in_process_webkit/webkit_context.h" |
| 27 #include "chrome/browser/profile.h" | 21 #include "chrome/browser/profile.h" |
| 28 #include "chrome/browser/renderer_host/render_view_host.h" | 22 #include "chrome/browser/renderer_host/render_view_host.h" |
| 29 #include "chrome/browser/renderer_host/render_view_host_factory.h" | 23 #include "chrome/browser/renderer_host/render_view_host_factory.h" |
| 30 #include "chrome/browser/renderer_host/render_widget_host_view.h" | 24 #include "chrome/browser/renderer_host/render_widget_host_view.h" |
| 31 #include "chrome/browser/renderer_host/render_widget_host_view_gtk.h" | |
| 32 #include "chrome/browser/renderer_host/site_instance.h" | 25 #include "chrome/browser/renderer_host/site_instance.h" |
| 33 #include "chrome/browser/renderer_preferences_util.h" | 26 #include "chrome/browser/renderer_preferences_util.h" |
| 34 #include "chrome/browser/tab_contents/render_view_host_delegate_helper.h" | 27 #include "chrome/browser/tab_contents/render_view_host_delegate_helper.h" |
| 35 #include "chrome/browser/tab_contents/tab_contents.h" | 28 #include "chrome/browser/tab_contents/tab_contents.h" |
| 36 #include "chrome/browser/views/bubble_border.h" | 29 #include "chrome/browser/views/info_bubble.h" |
| 37 #include "grit/app_resources.h" | 30 #include "chrome/browser/views/frame/browser_view.h" |
| 38 #include "grit/generated_resources.h" | |
| 39 #include "grit/theme_resources.h" | |
| 40 #include "third_party/skia/include/core/SkBitmap.h" | |
| 41 #include "views/background.h" | |
| 42 #include "views/controls/native/native_view_host.h" | 31 #include "views/controls/native/native_view_host.h" |
| 43 #include "views/painter.h" | |
| 44 #include "views/screen.h" | |
| 45 #include "views/widget/root_view.h" | 32 #include "views/widget/root_view.h" |
| 46 #include "views/widget/widget_gtk.h" | 33 #include "views/widget/widget.h" |
| 34 |
| 35 #if defined(OS_WIN) |
| 36 #include "chrome/browser/autocomplete/autocomplete_edit_view_win.h" |
| 37 #include "chrome/browser/renderer_host/render_widget_host_view_win.h" |
| 38 #elif defined(OS_LINUX) |
| 39 #include "chrome/browser/autocomplete/autocomplete_edit_view_gtk.h" |
| 40 #include "chrome/browser/renderer_host/render_widget_host_view_gtk.h" |
| 41 #endif |
| 42 #if defined(OS_CHROMEOS) |
| 43 #include "chrome/browser/chromeos/status/status_area_view.h" |
| 44 #endif |
| 47 | 45 |
| 48 namespace { | 46 namespace { |
| 49 | 47 |
| 50 // Padding & margins for the navigation entry. | 48 // Padding & margins for the navigation entry. |
| 51 const int kNavigationEntryPadding = 2; | 49 const int kNavigationEntryPadding = 2; |
| 52 const int kNavigationEntryXMargin = 3; | 50 const int kNavigationEntryXMargin = 3; |
| 53 const int kNavigationEntryYMargin = 1; | 51 const int kNavigationEntryYMargin = 1; |
| 54 | 52 |
| 55 // NavigationBar size. | 53 // NavigationBar size. |
| 56 const int kNavigationBarHeight = 25; | 54 const int kNavigationBarHeight = 25; |
| 57 | 55 |
| 58 // Padding for the bubble info window. | 56 // The delta applied to the default font size for the omnibox. |
| 59 const int kBubbleWindowXPadding = 6; | 57 const int kAutocompleteEditFontDelta = 3; |
| 60 const int kBubbleWindowYPadding = 16; | |
| 61 | 58 |
| 62 // Command line switch for specifying url of the page. | 59 // Command line switch for specifying url of the page. |
| 63 const wchar_t kURLSwitch[] = L"main-menu-url"; | 60 const wchar_t kURLSwitch[] = L"main-menu-url"; |
| 64 | 61 |
| 65 // Command line switch for specifying the size of the main menu. The default is | |
| 66 // full screen. | |
| 67 const wchar_t kMenuSizeSwitch[] = L"main-menu-size"; | |
| 68 | |
| 69 // URL of the page to load. This is ignored if kURLSwitch is specified. | 62 // URL of the page to load. This is ignored if kURLSwitch is specified. |
| 70 const char kMenuURL[] = "http://goto.ext.google.com/crux-home"; | 63 const char kMenuURL[] = "http://goto.ext.google.com/crux-home"; |
| 71 | 64 |
| 72 // Returns the URL of the menu. | 65 // Returns the URL of the menu. |
| 73 static GURL GetMenuURL() { | 66 static GURL GetMenuURL() { |
| 74 std::wstring url_string = | 67 std::wstring url_string = |
| 75 CommandLine::ForCurrentProcess()->GetSwitchValue(kURLSwitch); | 68 CommandLine::ForCurrentProcess()->GetSwitchValue(kURLSwitch); |
| 76 if (!url_string.empty()) | 69 if (!url_string.empty()) |
| 77 return GURL(WideToUTF8(url_string)); | 70 return GURL(WideToUTF8(url_string)); |
| 78 return GURL(kMenuURL); | 71 return GURL(kMenuURL); |
| 79 } | 72 } |
| 80 | 73 |
| 81 // RenderWidgetHostViewGtk propagates the mouse press events (see | 74 // RenderWidgetHostViewGtk propagates the mouse press events (see |
| 82 // render_widget_host_view_gtk.cc). We subclass to stop the propagation here, | 75 // render_widget_host_view_gtk.cc). We subclass to stop the propagation here, |
| 83 // as if the click event was propagated it would reach the TopContainer view and | 76 // as if the click event was propagated it would reach the TopContainer view and |
| 84 // it would close the popup. | 77 // it would close the popup. |
| 85 class RWHVNativeViewHost : public views::NativeViewHost { | 78 class RWHVNativeViewHost : public views::NativeViewHost { |
| 86 public: | 79 public: |
| 87 RWHVNativeViewHost() {} | 80 RWHVNativeViewHost() {} |
| 88 | 81 |
| 89 virtual bool OnMousePressed(const views::MouseEvent& event) { return true; } | 82 virtual bool OnMousePressed(const views::MouseEvent& event) { return true; } |
| 90 | 83 |
| 91 private: | 84 private: |
| 92 DISALLOW_COPY_AND_ASSIGN(RWHVNativeViewHost); | 85 DISALLOW_COPY_AND_ASSIGN(RWHVNativeViewHost); |
| 93 }; | 86 }; |
| 94 | 87 |
| 95 } // namspace | 88 } // namespace |
| 96 | 89 |
| 97 namespace chromeos { | 90 //////////////////////////////////////////////////////////////////////////////// |
| 91 // TabContentsDelegateImpl |
| 92 // |
| 93 // TabContentsDelegate and RenderViewHostDelegate::View have some methods |
| 94 // in common (with differing signatures). The TabContentsDelegate methods are |
| 95 // implemented by this class. |
| 96 |
| 97 class TabContentsDelegateImpl : public TabContentsDelegate { |
| 98 public: |
| 99 explicit TabContentsDelegateImpl(AppLauncher* app_launcher); |
| 100 |
| 101 // TabContentsDelegate. |
| 102 virtual void OpenURLFromTab(TabContents* source, |
| 103 const GURL& url, const GURL& referrer, |
| 104 WindowOpenDisposition disposition, |
| 105 PageTransition::Type transition); |
| 106 virtual void NavigationStateChanged(const TabContents* source, |
| 107 unsigned changed_flags) {} |
| 108 virtual void AddNewContents(TabContents* source, |
| 109 TabContents* new_contents, |
| 110 WindowOpenDisposition disposition, |
| 111 const gfx::Rect& initial_pos, |
| 112 bool user_gesture) {} |
| 113 virtual void ActivateContents(TabContents* contents) {} |
| 114 virtual void LoadingStateChanged(TabContents* source) {} |
| 115 virtual void CloseContents(TabContents* source) {} |
| 116 virtual void MoveContents(TabContents* source, const gfx::Rect& pos) {} |
| 117 virtual bool IsPopup(TabContents* source) { return false; } |
| 118 virtual void ToolbarSizeChanged(TabContents* source, bool is_animating) {} |
| 119 virtual void URLStarredChanged(TabContents* source, bool starred) {} |
| 120 virtual void UpdateTargetURL(TabContents* source, const GURL& url) {} |
| 121 |
| 122 private: |
| 123 AppLauncher* app_launcher_; |
| 124 |
| 125 DISALLOW_COPY_AND_ASSIGN(TabContentsDelegateImpl); |
| 126 }; |
| 127 |
| 128 TabContentsDelegateImpl::TabContentsDelegateImpl(AppLauncher* app_launcher) |
| 129 : app_launcher_(app_launcher) { |
| 130 } |
| 131 |
| 132 void TabContentsDelegateImpl::OpenURLFromTab(TabContents* source, |
| 133 const GURL& url, |
| 134 const GURL& referrer, |
| 135 WindowOpenDisposition disposition, |
| 136 PageTransition::Type transition) { |
| 137 app_launcher_->browser()->OpenURL(url, referrer, NEW_FOREGROUND_TAB, |
| 138 PageTransition::LINK); |
| 139 app_launcher_->Hide(); |
| 140 } |
| 98 | 141 |
| 99 //////////////////////////////////////////////////////////////////////////////// | 142 //////////////////////////////////////////////////////////////////////////////// |
| 100 // NavigationBar | 143 // NavigationBar |
| 101 // | 144 // |
| 102 // A navigation bar that is shown in the app launcher in compact navigation bar | 145 // A navigation bar that is shown in the app launcher in compact navigation bar |
| 103 // mode. | 146 // mode. |
| 104 | 147 |
| 105 class NavigationBar : public views::View, | 148 class NavigationBar : public views::View, |
| 106 public AutocompleteEditController, | 149 public AutocompleteEditController, |
| 107 public BubblePositioner { | 150 public BubblePositioner { |
| 108 public: | 151 public: |
| 109 explicit NavigationBar(AppLauncher* app_launcher) | 152 explicit NavigationBar(AppLauncher* app_launcher) |
| 110 : views::View(), | 153 : app_launcher_(app_launcher), |
| 111 app_launcher_(app_launcher), | |
| 112 location_entry_view_(NULL) { | 154 location_entry_view_(NULL) { |
| 113 SetFocusable(true); | 155 SetFocusable(true); |
| 114 location_entry_view_ = new views::NativeViewHost; | 156 location_entry_view_ = new views::NativeViewHost; |
| 115 AddChildView(location_entry_view_); | 157 AddChildView(location_entry_view_); |
| 158 set_border(views::Border::CreateSolidBorder(1, SK_ColorGRAY)); |
| 116 } | 159 } |
| 117 | 160 |
| 118 virtual ~NavigationBar() { | 161 virtual ~NavigationBar() { |
| 119 if (location_entry_view_->native_view()) | 162 if (location_entry_view_->native_view()) |
| 120 location_entry_view_->Detach(); | 163 location_entry_view_->Detach(); |
| 121 } | 164 } |
| 122 | 165 |
| 123 // views::View overrides. | 166 // views::View overrides. |
| 124 virtual void Focus() { | 167 virtual void Focus() { |
| 125 location_entry_->SetFocus(); | 168 location_entry_->SetFocus(); |
| 126 location_entry_->SelectAll(true); | 169 location_entry_->SelectAll(true); |
| 127 } | 170 } |
| 128 | 171 |
| 172 virtual void ViewHierarchyChanged(bool is_add, |
| 173 views::View* parent, |
| 174 views::View* child) { |
| 175 if (!is_add || child != this) |
| 176 return; |
| 177 |
| 178 DCHECK(!location_entry_.get()); |
| 179 |
| 180 Browser* browser = app_launcher_->browser(); |
| 181 #if defined (OS_WIN) |
| 182 gfx::Font font; |
| 183 font = font.DeriveFont(kAutocompleteEditFontDelta); |
| 184 AutocompleteEditViewWin* autocomplete_view = |
| 185 new AutocompleteEditViewWin(font, this, browser->toolbar_model(), |
| 186 this, GetWidget()->GetNativeView(), |
| 187 browser->profile(), |
| 188 browser->command_updater(), false, this); |
| 189 location_entry_.reset(autocomplete_view); |
| 190 autocomplete_view->Update(NULL); |
| 191 // The Update call above sets the autocomplete text to the current one in |
| 192 // the location bar, make sure to clear it. |
| 193 autocomplete_view->SetUserText(std::wstring()); |
| 194 #elif defined(OS_LINUX) && defined(TOOLKIT_VIEWS) |
| 195 AutocompleteEditViewGtk* autocomplete_view = |
| 196 new AutocompleteEditViewGtk(this, browser->toolbar_model(), |
| 197 browser->profile(), |
| 198 browser->command_updater(), false, this); |
| 199 autocomplete_view->Init(); |
| 200 gtk_widget_show_all(autocomplete_view->widget()); |
| 201 gtk_widget_hide(autocomplete_view->widget()); |
| 202 location_entry_.reset(autocomplete_view); |
| 203 #else |
| 204 NOTIMPLEMENTED(); |
| 205 #endif |
| 206 location_entry_view_->set_focus_view(this); |
| 207 location_entry_view_->Attach(location_entry_->GetNativeView()); |
| 208 } |
| 209 |
| 129 virtual void Layout() { | 210 virtual void Layout() { |
| 130 gfx::Rect bounds = GetLocalBounds(false); | 211 gfx::Rect bounds = GetLocalBounds(false); |
| 131 | |
| 132 const int vertical_margin = | |
| 133 kNavigationEntryPadding + kNavigationEntryYMargin; | |
| 134 | |
| 135 location_entry_view_->SetBounds( | 212 location_entry_view_->SetBounds( |
| 136 bounds.x() + kNavigationEntryXMargin + kNavigationEntryPadding, | 213 bounds.x() + kNavigationEntryXMargin + kNavigationEntryPadding, |
| 137 bounds.y() + vertical_margin, | 214 bounds.y() + kNavigationEntryYMargin, |
| 138 bounds.width() - 2 * (kNavigationEntryPadding + | 215 bounds.width() - 2 * (kNavigationEntryPadding + |
| 139 kNavigationEntryXMargin), | 216 kNavigationEntryXMargin), |
| 140 bounds.height() - vertical_margin * 2); | 217 bounds.height() - kNavigationEntryYMargin * 2); |
| 141 } | |
| 142 | |
| 143 virtual void Paint(gfx::Canvas* canvas) { | |
| 144 const int padding = kNavigationEntryPadding; | |
| 145 canvas->FillRectInt(SK_ColorWHITE, 0, 0, width(), height()); | |
| 146 // Draw border around the entry. | |
| 147 gfx::Rect bounds = location_entry_view_->GetBounds( | |
| 148 views::View::APPLY_MIRRORING_TRANSFORMATION); | |
| 149 canvas->DrawRectInt(SK_ColorGRAY, | |
| 150 bounds.x() - padding, | |
| 151 bounds.y() - padding, | |
| 152 bounds.width() + padding * 2, | |
| 153 bounds.height() + padding * 2); | |
| 154 } | 218 } |
| 155 | 219 |
| 156 // BubblePositioner implementation. | 220 // BubblePositioner implementation. |
| 157 virtual gfx::Rect GetLocationStackBounds() const { | 221 virtual gfx::Rect GetLocationStackBounds() const { |
| 158 gfx::Rect bounds = location_entry_view_->GetBounds( | 222 gfx::Rect bounds = location_entry_view_->GetBounds( |
| 159 views::View::APPLY_MIRRORING_TRANSFORMATION); | 223 views::View::APPLY_MIRRORING_TRANSFORMATION); |
| 160 gfx::Point origin(bounds.x(), bounds.bottom() + kNavigationEntryPadding); | 224 gfx::Point origin(bounds.x(), bounds.bottom() + kNavigationEntryPadding); |
| 161 views::View::ConvertPointToScreen(this, &origin); | 225 views::View::ConvertPointToScreen(this, &origin); |
| 162 gfx::Rect rect = gfx::Rect(origin, gfx::Size(500, 0)); | 226 gfx::Rect rect = gfx::Rect(origin, gfx::Size(500, 0)); |
| 163 if (UILayoutIsRightToLeft()) { | 227 if (UILayoutIsRightToLeft()) { |
| (...skipping 23 matching lines...) Expand all Loading... |
| 187 } | 251 } |
| 188 focus_manager->SetFocusedView(this); | 252 focus_manager->SetFocusedView(this); |
| 189 } | 253 } |
| 190 virtual SkBitmap GetFavIcon() const { | 254 virtual SkBitmap GetFavIcon() const { |
| 191 return SkBitmap(); | 255 return SkBitmap(); |
| 192 } | 256 } |
| 193 virtual std::wstring GetTitle() const { | 257 virtual std::wstring GetTitle() const { |
| 194 return std::wstring(); | 258 return std::wstring(); |
| 195 } | 259 } |
| 196 | 260 |
| 197 // AutocompleteEditView depends on the browser instance. | |
| 198 // Create new one when the browser instance changes. | |
| 199 void Update(Browser* browser) { | |
| 200 // Detach the native view if any. | |
| 201 if (location_entry_view_ && location_entry_view_->native_view()) | |
| 202 location_entry_view_->Detach(); | |
| 203 | |
| 204 location_entry_.reset(new AutocompleteEditViewGtk( | |
| 205 this, browser->toolbar_model(), browser->profile(), | |
| 206 browser->command_updater(), false, this)); | |
| 207 location_entry_->Init(); | |
| 208 gtk_widget_show_all(location_entry_->widget()); | |
| 209 gtk_widget_hide(location_entry_->widget()); | |
| 210 | |
| 211 location_entry_view_->set_focus_view(this); | |
| 212 location_entry_view_->Attach(location_entry_->widget()); | |
| 213 } | |
| 214 | |
| 215 private: | 261 private: |
| 216 AppLauncher* app_launcher_; | 262 AppLauncher* app_launcher_; |
| 217 views::NativeViewHost* location_entry_view_; | 263 views::NativeViewHost* location_entry_view_; |
| 264 #if defined(OS_WIN) |
| 265 scoped_ptr<AutocompleteEditViewWin> location_entry_; |
| 266 #elif defined(OS_LINUX) && defined(TOOLKIT_VIEWS) |
| 218 scoped_ptr<AutocompleteEditViewGtk> location_entry_; | 267 scoped_ptr<AutocompleteEditViewGtk> location_entry_; |
| 268 #else |
| 269 NOTIMPLEMENTED(); |
| 270 #endif |
| 219 | 271 |
| 220 DISALLOW_COPY_AND_ASSIGN(NavigationBar); | 272 DISALLOW_COPY_AND_ASSIGN(NavigationBar); |
| 221 }; | 273 }; |
| 222 | 274 |
| 223 //////////////////////////////////////////////////////////////////////////////// | 275 //////////////////////////////////////////////////////////////////////////////// |
| 224 // TopContainer | 276 // InfoBubbleContentsView |
| 225 // | 277 // |
| 226 // A view that grays-out the browser and contains the navigation bar and | 278 // The view that contains the navigation bar and render view. |
| 227 // renderer view. | 279 // It is displayed in an info-bubble. |
| 228 | 280 |
| 229 AppLauncher::TopContainer::TopContainer(AppLauncher* app_launcher) | 281 class InfoBubbleContentsView : public views::View { |
| 230 : app_launcher_(app_launcher) { | 282 public: |
| 231 // Use a transparent black background so the browser appears grayed-out. | 283 explicit InfoBubbleContentsView(AppLauncher* app_launcher); |
| 232 set_background(views::Background::CreateSolidBackground(0, 0, 0, 100)); | 284 ~InfoBubbleContentsView(); |
| 285 |
| 286 // Sets the initial focus. |
| 287 // Should be called when the bubble that contains us is shown. |
| 288 void BubbleShown(); |
| 289 |
| 290 // views::View override: |
| 291 virtual gfx::Size GetPreferredSize(); |
| 292 virtual void Layout(); |
| 293 virtual void ViewHierarchyChanged(bool is_add, |
| 294 views::View* parent, |
| 295 views::View* child); |
| 296 |
| 297 private: |
| 298 // The application launcher displaying this info bubble. |
| 299 AppLauncher* app_launcher_; |
| 300 |
| 301 // The navigation bar. |
| 302 NavigationBar* navigation_bar_; |
| 303 |
| 304 // The view containing the renderer view. |
| 305 views::NativeViewHost* render_view_container_; |
| 306 |
| 307 DISALLOW_COPY_AND_ASSIGN(InfoBubbleContentsView); |
| 308 }; |
| 309 |
| 310 InfoBubbleContentsView::InfoBubbleContentsView(AppLauncher* app_launcher) |
| 311 : app_launcher_(app_launcher), |
| 312 navigation_bar_(NULL), |
| 313 render_view_container_(NULL) { |
| 233 } | 314 } |
| 234 | 315 |
| 235 void AppLauncher::TopContainer::Layout() { | 316 InfoBubbleContentsView::~InfoBubbleContentsView() { |
| 236 if (bounds().IsEmpty()) | 317 } |
| 318 |
| 319 void InfoBubbleContentsView::BubbleShown() { |
| 320 navigation_bar_->RequestFocus(); |
| 321 } |
| 322 |
| 323 void InfoBubbleContentsView::ViewHierarchyChanged( |
| 324 bool is_add, views::View* parent, views::View* child) { |
| 325 if (!is_add || child != this) |
| 237 return; | 326 return; |
| 238 | 327 |
| 239 // We only expect to contain the BubbleContents. | 328 DCHECK(!render_view_container_); |
| 240 DCHECK(GetChildViewCount() == 1); | 329 render_view_container_ = new RWHVNativeViewHost; |
| 241 GetChildViewAt(0)->SetBounds(kBubbleWindowXPadding, kBubbleWindowYPadding, | 330 AddChildView(render_view_container_); |
| 242 width() * 2 / 3, height() * 4 / 5); | 331 #if defined(OS_WIN) |
| 332 RenderWidgetHostViewWin* view_win = |
| 333 static_cast<RenderWidgetHostViewWin*>(app_launcher_->rwhv_); |
| 334 // Create the HWND now that we are parented. |
| 335 HWND hwnd = view_win->Create(GetWidget()->GetNativeView()); |
| 336 view_win->ShowWindow(SW_SHOW); |
| 337 #endif |
| 338 render_view_container_->Attach(app_launcher_->rwhv_->GetNativeView()); |
| 339 |
| 340 navigation_bar_ = new NavigationBar(app_launcher_); |
| 341 AddChildView(navigation_bar_); |
| 243 } | 342 } |
| 244 | 343 |
| 245 bool AppLauncher::TopContainer::OnMousePressed(const views::MouseEvent& event) { | 344 gfx::Size InfoBubbleContentsView::GetPreferredSize() { |
| 246 // Clicking outside the bubble closes the bubble. | 345 gfx::Rect bounds = app_launcher_->browser()->window()->GetRestoredBounds(); |
| 247 app_launcher_->Hide(); | 346 return gfx::Size(bounds.width() * 2 / 3, bounds.width() * 4 / 5); |
| 248 return false; | |
| 249 } | 347 } |
| 250 | 348 |
| 251 //////////////////////////////////////////////////////////////////////////////// | 349 void InfoBubbleContentsView::Layout() { |
| 252 // BubbleContainer | |
| 253 // | |
| 254 // The view that contains the navigation bar and render view. It has a bubble | |
| 255 // border. | |
| 256 | |
| 257 AppLauncher::BubbleContainer::BubbleContainer(AppLauncher* app_launcher) | |
| 258 : app_launcher_(app_launcher) { | |
| 259 BubbleBorder* bubble_border = new BubbleBorder(); | |
| 260 bubble_border->set_arrow_location(BubbleBorder::TOP_LEFT); | |
| 261 set_border(bubble_border); | |
| 262 set_background(new BubbleBackground(bubble_border)); | |
| 263 } | |
| 264 | |
| 265 void AppLauncher::BubbleContainer::Layout() { | |
| 266 if (bounds().IsEmpty() || GetChildViewCount() == 0) | 350 if (bounds().IsEmpty() || GetChildViewCount() == 0) |
| 267 return; | 351 return; |
| 268 | 352 |
| 269 gfx::Rect bounds = GetLocalBounds(false); | 353 int navigation_bar_height = |
| 270 // TODO(jcampan): figure-out why we need to inset for the contained view not | 354 kNavigationBarHeight + kNavigationEntryYMargin * 2; |
| 271 // to paint over the bubble border. | 355 const views::Border* border = navigation_bar_->border(); |
| 272 bounds.Inset(2, 2); | 356 if (border) { |
| 273 | 357 gfx::Insets insets; |
| 274 app_launcher_->navigation_bar_->SetBounds(bounds.x(), bounds.y(), | 358 border->GetInsets(&insets); |
| 275 bounds.width(), | 359 navigation_bar_height += insets.height(); |
| 276 kNavigationBarHeight); | 360 } |
| 277 int render_y = app_launcher_->navigation_bar_->bounds().bottom(); | 361 navigation_bar_->SetBounds(x(), y(), width(), navigation_bar_height); |
| 362 int render_y = navigation_bar_->bounds().bottom(); |
| 278 gfx::Size rwhv_size = | 363 gfx::Size rwhv_size = |
| 279 gfx::Size(bounds.width(), | 364 gfx::Size(width(), std::max(0, height() - render_y + y())); |
| 280 std::max(0, bounds.height() - render_y + bounds.y())); | 365 render_view_container_->SetBounds(x(), render_y, |
| 281 app_launcher_->render_view_container_->SetBounds(bounds.x(), render_y, | 366 rwhv_size.width(), rwhv_size.height()); |
| 282 rwhv_size.width(), | |
| 283 rwhv_size.height()); | |
| 284 app_launcher_->rwhv_->SetSize(rwhv_size); | 367 app_launcher_->rwhv_->SetSize(rwhv_size); |
| 285 } | 368 } |
| 286 | 369 |
| 287 //////////////////////////////////////////////////////////////////////////////// | 370 //////////////////////////////////////////////////////////////////////////////// |
| 288 // AppLauncher | 371 // AppLauncher |
| 289 | 372 |
| 290 AppLauncher::AppLauncher() | 373 AppLauncher::AppLauncher(Browser* browser) |
| 291 : browser_(NULL), | 374 : browser_(browser), |
| 292 popup_(NULL), | 375 info_bubble_(NULL), |
| 293 site_instance_(NULL), | 376 site_instance_(NULL), |
| 294 contents_rvh_(NULL), | 377 contents_rvh_(NULL), |
| 295 rwhv_(NULL), | 378 rwhv_(NULL), |
| 296 ALLOW_THIS_IN_INITIALIZER_LIST(tab_contents_delegate_(this)), | 379 ALLOW_THIS_IN_INITIALIZER_LIST( |
| 297 ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)), | 380 tab_contents_delegate_(new TabContentsDelegateImpl(this))) { |
| 298 top_container_(NULL), | 381 info_bubble_content_ = new InfoBubbleContentsView(this); |
| 299 bubble_container_(NULL), | |
| 300 navigation_bar_(NULL), | |
| 301 render_view_container_(NULL), | |
| 302 has_shown_(false) { | |
| 303 popup_ = new views::WidgetGtk(views::WidgetGtk::TYPE_WINDOW); | |
| 304 // The background image has transparency, so we make the window transparent. | |
| 305 popup_->MakeTransparent(); | |
| 306 popup_->Init(NULL, gfx::Rect()); | |
| 307 WmIpc::instance()->SetWindowType( | |
| 308 popup_->GetNativeView(), | |
| 309 WmIpc::WINDOW_TYPE_CHROME_INFO_BUBBLE, | |
| 310 NULL); | |
| 311 | 382 |
| 312 // Register Esc as an accelerator for closing the app launcher. | 383 Profile* profile = browser_->profile(); |
| 313 views::FocusManager* focus_manager = popup_->GetFocusManager(); | |
| 314 focus_manager->RegisterAccelerator(views::Accelerator(base::VKEY_ESCAPE, | |
| 315 false, false, false), | |
| 316 this); | |
| 317 | |
| 318 top_container_ = new TopContainer(this); | |
| 319 popup_->SetContentsView(top_container_); | |
| 320 | |
| 321 bubble_container_ = new BubbleContainer(this); | |
| 322 top_container_->AddChildView(bubble_container_); | |
| 323 navigation_bar_ = new NavigationBar(this); | |
| 324 bubble_container_->AddChildView(navigation_bar_); | |
| 325 | |
| 326 GURL menu_url(GetMenuURL()); | |
| 327 DCHECK(BrowserList::begin() != BrowserList::end()); | |
| 328 // TODO(sky): this shouldn't pick a random profile to use. | |
| 329 Profile* profile = (*BrowserList::begin())->profile(); | |
| 330 int64 session_storage_namespace_id = profile->GetWebKitContext()-> | 384 int64 session_storage_namespace_id = profile->GetWebKitContext()-> |
| 331 dom_storage_context()->AllocateSessionStorageNamespaceId(); | 385 dom_storage_context()->AllocateSessionStorageNamespaceId(); |
| 332 site_instance_ = SiteInstance::CreateSiteInstanceForURL(profile, menu_url); | 386 site_instance_ = SiteInstance::CreateSiteInstanceForURL(profile, |
| 387 GetMenuURL()); |
| 333 contents_rvh_ = new RenderViewHost(site_instance_, this, MSG_ROUTING_NONE, | 388 contents_rvh_ = new RenderViewHost(site_instance_, this, MSG_ROUTING_NONE, |
| 334 session_storage_namespace_id); | 389 session_storage_namespace_id); |
| 390 rwhv_ = RenderWidgetHostView::CreateViewForWidget(contents_rvh_); |
| 391 contents_rvh_->set_view(rwhv_); |
| 335 | 392 |
| 336 rwhv_ = new RenderWidgetHostViewGtk(contents_rvh_); | 393 // On Windows, we'll create the RWHV HWND once we are attached as we need |
| 337 rwhv_->InitAsChild(); | 394 // to be parented for CreateWindow to work. |
| 395 #if defined(OS_LINUX) |
| 396 RenderWidgetHostViewGtk* view_gtk = |
| 397 static_cast<RenderWidgetHostViewGtk*>(rwhv_); |
| 398 view_gtk->InitAsChild(); |
| 399 #endif |
| 400 |
| 338 contents_rvh_->CreateRenderView(profile->GetRequestContext()); | 401 contents_rvh_->CreateRenderView(profile->GetRequestContext()); |
| 339 | 402 DCHECK(contents_rvh_->IsRenderViewLive()); |
| 340 render_view_container_ = new RWHVNativeViewHost; | 403 contents_rvh_->NavigateToURL(GetMenuURL()); |
| 341 bubble_container_->AddChildView(render_view_container_); | |
| 342 render_view_container_->Attach(rwhv_->GetNativeView()); | |
| 343 contents_rvh_->NavigateToURL(menu_url); | |
| 344 | |
| 345 ActiveWindowWatcherX::AddObserver(this); | |
| 346 } | 404 } |
| 347 | 405 |
| 348 AppLauncher::~AppLauncher() { | 406 AppLauncher::~AppLauncher() { |
| 349 contents_rvh_->Shutdown(); | 407 contents_rvh_->Shutdown(); |
| 350 popup_->CloseNow(); | |
| 351 ActiveWindowWatcherX::RemoveObserver(this); | |
| 352 } | 408 } |
| 353 | 409 |
| 354 void AppLauncher::Update(Browser* browser) { | 410 // static |
| 355 if (browser_ != browser) { | 411 AppLauncher* AppLauncher::Show(Browser* browser) { |
| 356 browser_ = browser; | 412 AppLauncher* app_launcher = new AppLauncher(browser); |
| 357 navigation_bar_->Update(browser); | 413 |
| 358 // Set the transient window so that ChromeOS WM treat this | 414 BrowserView* browser_view = static_cast<BrowserView*>(browser->window()); |
| 359 // as if a popup window. | 415 TabStrip* tabstrip = browser_view->tabstrip()->AsTabStrip(); |
| 360 gtk_window_set_transient_for( | 416 if (!tabstrip) { |
| 361 GTK_WINDOW(popup_->GetNativeView()), | 417 delete app_launcher; |
| 362 GTK_WINDOW(browser_->window()->GetNativeHandle())); | 418 return NULL; |
| 363 } | 419 } |
| 364 | 420 gfx::Rect bounds = tabstrip->GetNewTabButtonBounds(); |
| 365 popup_->SetBounds(browser_->window()->GetRestoredBounds()); | 421 gfx::Point origin = bounds.origin(); |
| 366 top_container_->Layout(); | 422 views::RootView::ConvertPointToScreen(tabstrip, &origin); |
| 367 } | 423 bounds.set_origin(origin); |
| 368 | 424 app_launcher->info_bubble_ = |
| 369 void AppLauncher::Show(Browser* browser) { | 425 InfoBubble::Show(browser_view->frame()->GetWindow(), bounds, |
| 370 Cleanup(); | 426 app_launcher->info_bubble_content_, app_launcher); |
| 371 | 427 app_launcher->info_bubble_content_->BubbleShown(); |
| 372 Update(browser); | 428 return app_launcher; |
| 373 popup_->Show(); | |
| 374 | |
| 375 GtkWidget* rwhv_widget = rwhv_->GetNativeView(); | |
| 376 if (!has_shown_) { | |
| 377 has_shown_ = true; | |
| 378 gtk_widget_realize(rwhv_widget); | |
| 379 } | |
| 380 } | |
| 381 | |
| 382 void AppLauncher::ActiveWindowChanged(GdkWindow* active_window) { | |
| 383 if (!popup_->IsActive()) | |
| 384 Hide(); | |
| 385 else | |
| 386 navigation_bar_->RequestFocus(); | |
| 387 } | |
| 388 | |
| 389 bool AppLauncher::AcceleratorPressed(const views::Accelerator& accelerator) { | |
| 390 DCHECK(accelerator.GetKeyCode() == base::VKEY_ESCAPE); | |
| 391 popup_->Hide(); | |
| 392 return true; | |
| 393 } | 429 } |
| 394 | 430 |
| 395 void AppLauncher::Hide() { | 431 void AppLauncher::Hide() { |
| 396 popup_->Hide(); | 432 info_bubble_->Close(); |
| 433 } |
| 434 |
| 435 void AppLauncher::InfoBubbleClosing(InfoBubble* info_bubble, |
| 436 bool closed_by_escape) { |
| 397 // The stack may have pending_contents_ on it. Delay deleting the | 437 // The stack may have pending_contents_ on it. Delay deleting the |
| 398 // pending_contents_ as TabContents doesn't deal well with being deleted | 438 // pending_contents_ as TabContents doesn't deal well with being deleted |
| 399 // while on the stack. | 439 // while on the stack. |
| 400 MessageLoop::current()->PostTask(FROM_HERE, | 440 MessageLoop::current()->PostTask(FROM_HERE, |
| 401 method_factory_.NewRunnableMethod(&AppLauncher::Cleanup)); | 441 new DeleteTask<AppLauncher>(this)); |
| 402 } | |
| 403 | |
| 404 void AppLauncher::Cleanup() { | |
| 405 pending_contents_.reset(NULL); | |
| 406 method_factory_.RevokeAll(); | |
| 407 } | 442 } |
| 408 | 443 |
| 409 void AppLauncher::RequestMove(const gfx::Rect& new_bounds) { | 444 void AppLauncher::RequestMove(const gfx::Rect& new_bounds) { |
| 445 #if defined(OS_LINUX) |
| 410 // Invoking PositionChild results in a gtk signal that triggers attempting to | 446 // Invoking PositionChild results in a gtk signal that triggers attempting to |
| 411 // to resize the window. We need to set the size request so that it resizes | 447 // to resize the window. We need to set the size request so that it resizes |
| 412 // correctly when this happens. | 448 // correctly when this happens. |
| 413 gtk_widget_set_size_request(popup_->GetNativeView(), | 449 gtk_widget_set_size_request(info_bubble_->GetNativeView(), |
| 414 new_bounds.width(), new_bounds.height()); | 450 new_bounds.width(), new_bounds.height()); |
| 415 popup_->SetBounds(new_bounds); | 451 info_bubble_->SetBounds(new_bounds); |
| 452 #endif |
| 416 } | 453 } |
| 417 | 454 |
| 418 RendererPreferences AppLauncher::GetRendererPrefs(Profile* profile) const { | 455 RendererPreferences AppLauncher::GetRendererPrefs(Profile* profile) const { |
| 419 RendererPreferences preferences; | 456 RendererPreferences preferences; |
| 420 renderer_preferences_util::UpdateFromSystemSettings(&preferences, profile); | 457 renderer_preferences_util::UpdateFromSystemSettings(&preferences, profile); |
| 421 return preferences; | 458 return preferences; |
| 422 } | 459 } |
| 423 | 460 |
| 424 void AppLauncher::AddTabWithURL(const GURL& url, | |
| 425 PageTransition::Type transition) { | |
| 426 switch (StatusAreaView::GetOpenTabsMode()) { | |
| 427 case StatusAreaView::OPEN_TABS_ON_LEFT: { | |
| 428 // Add the new tab at the first non-pinned location. | |
| 429 int index = browser_->tabstrip_model()->IndexOfFirstNonMiniTab(); | |
| 430 browser_->AddTabWithURL(url, GURL(), transition, | |
| 431 true, index, true, NULL); | |
| 432 break; | |
| 433 } | |
| 434 case StatusAreaView::OPEN_TABS_CLOBBER: { | |
| 435 browser_->GetSelectedTabContents()->controller().LoadURL( | |
| 436 url, GURL(), transition); | |
| 437 break; | |
| 438 } | |
| 439 case StatusAreaView::OPEN_TABS_ON_RIGHT: { | |
| 440 browser_->AddTabWithURL(url, GURL(), transition, true, -1, true, NULL); | |
| 441 break; | |
| 442 } | |
| 443 } | |
| 444 } | |
| 445 | |
| 446 void AppLauncher::CreateNewWindow(int route_id) { | 461 void AppLauncher::CreateNewWindow(int route_id) { |
| 447 if (pending_contents_.get()) { | 462 if (pending_contents_.get()) { |
| 448 NOTREACHED(); | 463 NOTREACHED(); |
| 449 return; | 464 return; |
| 450 } | 465 } |
| 451 | 466 |
| 452 helper_.CreateNewWindow(route_id, browser_->profile(), site_instance_, | 467 helper_.CreateNewWindow(route_id, browser_->profile(), site_instance_, |
| 453 DOMUIFactory::GetDOMUIType(GURL(GetMenuURL())), | 468 DOMUIFactory::GetDOMUIType(GURL(GetMenuURL())), |
| 454 NULL); | 469 NULL); |
| 455 pending_contents_.reset(helper_.GetCreatedWindow(route_id)); | 470 pending_contents_.reset(helper_.GetCreatedWindow(route_id)); |
| 456 pending_contents_->set_delegate(&tab_contents_delegate_); | 471 pending_contents_->set_delegate(tab_contents_delegate_.get()); |
| 457 } | 472 } |
| 458 | 473 |
| 459 void AppLauncher::ShowCreatedWindow(int route_id, | 474 void AppLauncher::ShowCreatedWindow(int route_id, |
| 460 WindowOpenDisposition disposition, | 475 WindowOpenDisposition disposition, |
| 461 const gfx::Rect& initial_pos, | 476 const gfx::Rect& initial_pos, |
| 462 bool user_gesture) { | 477 bool user_gesture) { |
| 463 if (disposition == NEW_POPUP) { | 478 if (disposition == NEW_POPUP) { |
| 464 pending_contents_->set_delegate(NULL); | 479 pending_contents_->set_delegate(NULL); |
| 465 browser_->GetSelectedTabContents()->AddNewContents( | 480 browser_->GetSelectedTabContents()->AddNewContents( |
| 466 pending_contents_.release(), disposition, initial_pos, user_gesture); | 481 pending_contents_.release(), disposition, initial_pos, user_gesture); |
| 467 Hide(); | 482 Hide(); |
| 468 } | 483 } |
| 469 } | 484 } |
| 470 | 485 |
| 471 void AppLauncher::StartDragging(const WebDropData& drop_data, | 486 void AppLauncher::StartDragging(const WebDropData& drop_data, |
| 472 WebKit::WebDragOperationsMask allowed_ops) { | 487 WebKit::WebDragOperationsMask allowed_ops, |
| 488 const SkBitmap& image, |
| 489 const gfx::Point& image_offset) { |
| 473 // We're not going to do any drag & drop, but we have to tell the renderer the | 490 // We're not going to do any drag & drop, but we have to tell the renderer the |
| 474 // drag & drop ended, othewise the renderer thinks the drag operation is | 491 // drag & drop ended, othewise the renderer thinks the drag operation is |
| 475 // underway and mouse events won't work. | 492 // underway and mouse events won't work. |
| 476 contents_rvh_->DragSourceSystemDragEnded(); | 493 contents_rvh_->DragSourceSystemDragEnded(); |
| 477 } | 494 } |
| 478 | 495 |
| 479 AppLauncher::TabContentsDelegateImpl::TabContentsDelegateImpl( | 496 void AppLauncher::AddTabWithURL(const GURL& url, |
| 480 AppLauncher* app_launcher) | 497 PageTransition::Type transition) { |
| 481 : app_launcher_(app_launcher) { | 498 #if defined(OS_CHROMEOS) |
| 499 switch (chromeos::StatusAreaView::GetOpenTabsMode()) { |
| 500 case chromeos::StatusAreaView::OPEN_TABS_ON_LEFT: { |
| 501 // Add the new tab at the first non-pinned location. |
| 502 int index = browser_->tabstrip_model()->IndexOfFirstNonMiniTab(); |
| 503 browser_->AddTabWithURL(url, GURL(), transition, |
| 504 true, index, true, NULL); |
| 505 break; |
| 506 } |
| 507 case chromeos::StatusAreaView::OPEN_TABS_CLOBBER: { |
| 508 browser_->GetSelectedTabContents()->controller().LoadURL( |
| 509 url, GURL(), transition); |
| 510 break; |
| 511 } |
| 512 case chromeos::StatusAreaView::OPEN_TABS_ON_RIGHT: { |
| 513 browser_->AddTabWithURL(url, GURL(), transition, true, -1, true, NULL); |
| 514 break; |
| 515 } |
| 516 } |
| 517 #else |
| 518 browser_->AddTabWithURL(url, GURL(), transition, true, -1, true, NULL); |
| 519 #endif |
| 482 } | 520 } |
| 483 | |
| 484 void AppLauncher::TabContentsDelegateImpl::OpenURLFromTab( | |
| 485 TabContents* source, | |
| 486 const GURL& url, | |
| 487 const GURL& referrer, | |
| 488 WindowOpenDisposition disposition, | |
| 489 PageTransition::Type transition) { | |
| 490 app_launcher_->browser_->OpenURL(url, referrer, NEW_FOREGROUND_TAB, | |
| 491 PageTransition::LINK); | |
| 492 app_launcher_->Hide(); | |
| 493 } | |
| 494 | |
| 495 } // namespace chromeos | |
| OLD | NEW |