| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2011 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 "ui/views/desktop/desktop_window_manager.h" | |
| 6 | |
| 7 #include "ui/base/hit_test.h" | |
| 8 #include "ui/gfx/point.h" | |
| 9 #include "ui/gfx/rect.h" | |
| 10 #include "ui/views/events/event.h" | |
| 11 #include "ui/views/window/non_client_view.h" | |
| 12 #include "views/widget/native_widget_private.h" | |
| 13 #include "views/widget/native_widget_view.h" | |
| 14 #include "views/widget/native_widget_views.h" | |
| 15 #include "views/widget/widget_delegate.h" | |
| 16 | |
| 17 namespace { | |
| 18 | |
| 19 class MoveWindowController : public views::desktop::WindowController { | |
| 20 public: | |
| 21 MoveWindowController(views::Widget* widget, const gfx::Point& start) | |
| 22 : target_(widget), | |
| 23 offset_(start) { | |
| 24 } | |
| 25 | |
| 26 virtual ~MoveWindowController() { | |
| 27 } | |
| 28 | |
| 29 bool OnMouseEvent(const views::MouseEvent& event) { | |
| 30 if (event.type()== ui::ET_MOUSE_DRAGGED) { | |
| 31 gfx::Point origin = event.location().Subtract(offset_); | |
| 32 gfx::Rect rect = target_->GetWindowScreenBounds(); | |
| 33 rect.set_origin(origin); | |
| 34 target_->SetBounds(rect); | |
| 35 return true; | |
| 36 } | |
| 37 return false; | |
| 38 } | |
| 39 | |
| 40 private: | |
| 41 views::Widget* target_; | |
| 42 gfx::Point offset_; | |
| 43 | |
| 44 DISALLOW_COPY_AND_ASSIGN(MoveWindowController); | |
| 45 }; | |
| 46 | |
| 47 // Simple resize controller that handle all resize as if the bottom | |
| 48 // right corner is selected. | |
| 49 class ResizeWindowController : public views::desktop::WindowController { | |
| 50 public: | |
| 51 ResizeWindowController(views::Widget* widget) | |
| 52 : target_(widget) { | |
| 53 } | |
| 54 | |
| 55 virtual ~ResizeWindowController() { | |
| 56 } | |
| 57 | |
| 58 bool OnMouseEvent(const views::MouseEvent& event) OVERRIDE { | |
| 59 if (event.type()== ui::ET_MOUSE_DRAGGED) { | |
| 60 gfx::Point location = event.location(); | |
| 61 gfx::Rect rect = target_->GetWindowScreenBounds(); | |
| 62 gfx::Point size = location.Subtract(rect.origin()); | |
| 63 target_->SetSize(gfx::Size(std::max(10, size.x()), | |
| 64 std::max(10, size.y()))); | |
| 65 return true; | |
| 66 } | |
| 67 return false; | |
| 68 } | |
| 69 | |
| 70 private: | |
| 71 views::Widget* target_; | |
| 72 | |
| 73 DISALLOW_COPY_AND_ASSIGN(ResizeWindowController); | |
| 74 }; | |
| 75 | |
| 76 } // namespace | |
| 77 | |
| 78 namespace views { | |
| 79 namespace desktop { | |
| 80 | |
| 81 WindowController::WindowController() { | |
| 82 } | |
| 83 | |
| 84 WindowController::~WindowController() { | |
| 85 } | |
| 86 | |
| 87 //////////////////////////////////////////////////////////////////////////////// | |
| 88 // DesktopWindowManager, public: | |
| 89 | |
| 90 DesktopWindowManager::DesktopWindowManager(Widget* desktop) | |
| 91 : desktop_(desktop), | |
| 92 mouse_capture_(NULL), | |
| 93 active_widget_(NULL) { | |
| 94 } | |
| 95 | |
| 96 DesktopWindowManager::~DesktopWindowManager() { | |
| 97 DCHECK_EQ(0U, toplevels_.size()) << "Window manager getting destroyed " | |
| 98 << "before all the windows are closed."; | |
| 99 } | |
| 100 | |
| 101 void DesktopWindowManager::UpdateWindowsAfterScreenSizeChanged( | |
| 102 const gfx::Rect& new_size) { | |
| 103 for (std::vector<Widget*>::iterator i = toplevels_.begin(); | |
| 104 i != toplevels_.end(); ++i) { | |
| 105 Widget* toplevel = *i; | |
| 106 if (!toplevel->IsMaximized()) | |
| 107 continue; | |
| 108 | |
| 109 // If the window is maximized, then resize it! | |
| 110 toplevel->SetSize(new_size.size()); | |
| 111 } | |
| 112 } | |
| 113 | |
| 114 //////////////////////////////////////////////////////////////////////////////// | |
| 115 // DesktopWindowManager, WindowManager implementation: | |
| 116 | |
| 117 void DesktopWindowManager::StartMoveDrag( | |
| 118 views::Widget* widget, | |
| 119 const gfx::Point& point) { | |
| 120 DCHECK(!window_controller_.get()); | |
| 121 DCHECK(!HasMouseCapture()); | |
| 122 if (!widget->IsMaximized() && !widget->IsMinimized()) { | |
| 123 gfx::Point new_point = point; | |
| 124 if (desktop_->non_client_view()) { | |
| 125 gfx::Rect client = | |
| 126 desktop_->non_client_view()->frame_view()->GetBoundsForClientView(); | |
| 127 new_point.Offset(client.x(), client.y()); | |
| 128 } | |
| 129 SetMouseCapture(); | |
| 130 window_controller_.reset(new MoveWindowController(widget, new_point)); | |
| 131 } | |
| 132 } | |
| 133 | |
| 134 void DesktopWindowManager::StartResizeDrag( | |
| 135 views::Widget* widget, const gfx::Point& point, int hittest_code) { | |
| 136 DCHECK(!window_controller_.get()); | |
| 137 DCHECK(!HasMouseCapture()); | |
| 138 if (!widget->IsMaximized() && | |
| 139 !widget->IsMinimized() && | |
| 140 (widget->widget_delegate() || widget->widget_delegate()->CanResize())) { | |
| 141 SetMouseCapture(); | |
| 142 window_controller_.reset(new ResizeWindowController(widget)); | |
| 143 } | |
| 144 } | |
| 145 | |
| 146 bool DesktopWindowManager::SetMouseCapture(views::Widget* widget) { | |
| 147 if (mouse_capture_) | |
| 148 return false; | |
| 149 if (mouse_capture_ == widget) | |
| 150 return true; | |
| 151 DCHECK(!HasMouseCapture()); | |
| 152 SetMouseCapture(); | |
| 153 mouse_capture_ = widget; | |
| 154 return true; | |
| 155 } | |
| 156 | |
| 157 bool DesktopWindowManager::ReleaseMouseCapture(views::Widget* widget) { | |
| 158 if (!widget || mouse_capture_ != widget) | |
| 159 return false; | |
| 160 DCHECK(HasMouseCapture()); | |
| 161 ReleaseMouseCapture(); | |
| 162 mouse_capture_ = NULL; | |
| 163 return true; | |
| 164 } | |
| 165 | |
| 166 bool DesktopWindowManager::HasMouseCapture(const views::Widget* widget) const { | |
| 167 return widget && mouse_capture_ == widget; | |
| 168 } | |
| 169 | |
| 170 bool DesktopWindowManager::HandleKeyEvent( | |
| 171 views::Widget* widget, const views::KeyEvent& event) { | |
| 172 return active_widget_ ? | |
| 173 static_cast<NativeWidgetViews*>(active_widget_->native_widget_private()) | |
| 174 ->OnKeyEvent(event) : false; | |
| 175 } | |
| 176 | |
| 177 bool DesktopWindowManager::HandleMouseEvent( | |
| 178 views::Widget* widget, const views::MouseEvent& event) { | |
| 179 if (mouse_capture_) { | |
| 180 views::MouseEvent translated(event, widget->GetRootView(), | |
| 181 mouse_capture_->GetRootView()); | |
| 182 mouse_capture_->OnMouseEvent(translated); | |
| 183 return true; | |
| 184 } | |
| 185 | |
| 186 if (event.type() == ui::ET_MOUSE_PRESSED) | |
| 187 ActivateWidgetAtLocation(widget, event.location()); | |
| 188 else if (event.type() == ui::ET_MOUSEWHEEL && active_widget_) | |
| 189 return active_widget_->OnMouseEvent(event); | |
| 190 | |
| 191 if (window_controller_.get()) { | |
| 192 if (!window_controller_->OnMouseEvent(event)) { | |
| 193 ReleaseMouseCapture(); | |
| 194 window_controller_.reset(); | |
| 195 } | |
| 196 return true; | |
| 197 } | |
| 198 | |
| 199 return false; | |
| 200 } | |
| 201 | |
| 202 ui::TouchStatus DesktopWindowManager::HandleTouchEvent(Widget* widget, | |
| 203 const TouchEvent& event) { | |
| 204 // If there is a widget capturing mouse events, the widget should also receive | |
| 205 // touch events. | |
| 206 if (mouse_capture_) { | |
| 207 views::TouchEvent translated(event, widget->GetRootView(), | |
| 208 mouse_capture_->GetRootView()); | |
| 209 return mouse_capture_->OnTouchEvent(translated); | |
| 210 } | |
| 211 | |
| 212 // If a touch event activates a Widget, let the event still go through to the | |
| 213 // activated Widget. | |
| 214 if (event.type() == ui::ET_TOUCH_PRESSED) | |
| 215 ActivateWidgetAtLocation(widget, event.location()); | |
| 216 return ui::TOUCH_STATUS_UNKNOWN; | |
| 217 } | |
| 218 | |
| 219 void DesktopWindowManager::Register(Widget* widget) { | |
| 220 DCHECK(!widget->HasObserver(this)); | |
| 221 if (widget->is_top_level()) | |
| 222 toplevels_.push_back(widget); | |
| 223 widget->AddObserver(this); | |
| 224 } | |
| 225 | |
| 226 //////////////////////////////////////////////////////////////////////////////// | |
| 227 // DesktopWindowManager, private: | |
| 228 | |
| 229 void DesktopWindowManager::OnWidgetClosing(Widget* widget) { | |
| 230 if (active_widget_ && active_widget_ == widget) | |
| 231 active_widget_ = NULL; | |
| 232 if (widget->is_top_level()) { | |
| 233 for (std::vector<Widget*>::iterator i = toplevels_.begin(); | |
| 234 i != toplevels_.end(); ++i) { | |
| 235 if (*i == widget) { | |
| 236 toplevels_.erase(i); | |
| 237 break; | |
| 238 } | |
| 239 } | |
| 240 } | |
| 241 } | |
| 242 | |
| 243 void DesktopWindowManager::OnWidgetVisibilityChanged(Widget* widget, | |
| 244 bool visible) { | |
| 245 // If there's no active Widget, then activate the first visible toplevel | |
| 246 // Widget. | |
| 247 if (widget->is_top_level() && widget->CanActivate() && visible && | |
| 248 active_widget_ == NULL) { | |
| 249 Activate(widget); | |
| 250 } | |
| 251 } | |
| 252 | |
| 253 void DesktopWindowManager::OnWidgetActivationChanged(Widget* widget, | |
| 254 bool active) { | |
| 255 if (active) { | |
| 256 if (active_widget_) | |
| 257 active_widget_->Deactivate(); | |
| 258 active_widget_ = widget; | |
| 259 } else if (widget == active_widget_) { | |
| 260 active_widget_ = NULL; | |
| 261 } | |
| 262 } | |
| 263 | |
| 264 void DesktopWindowManager::SetMouseCapture() { | |
| 265 return desktop_->native_widget_private()->SetMouseCapture(); | |
| 266 } | |
| 267 | |
| 268 void DesktopWindowManager::ReleaseMouseCapture() { | |
| 269 return desktop_->native_widget_private()->ReleaseMouseCapture(); | |
| 270 } | |
| 271 | |
| 272 bool DesktopWindowManager::HasMouseCapture() const { | |
| 273 return desktop_->native_widget_private()->HasMouseCapture(); | |
| 274 } | |
| 275 | |
| 276 void DesktopWindowManager::Activate(Widget* widget) { | |
| 277 if (widget && widget->IsActive()) | |
| 278 return; | |
| 279 | |
| 280 if (widget) { | |
| 281 if (!widget->HasObserver(this)) | |
| 282 widget->AddObserver(this); | |
| 283 widget->Activate(); | |
| 284 } | |
| 285 } | |
| 286 | |
| 287 bool DesktopWindowManager::ActivateWidgetAtLocation(Widget* widget, | |
| 288 const gfx::Point& point) { | |
| 289 View* target = widget->GetRootView()->GetEventHandlerForPoint(point); | |
| 290 | |
| 291 if (target->GetClassName() == internal::NativeWidgetView::kViewClassName) { | |
| 292 internal::NativeWidgetView* native_widget_view = | |
| 293 static_cast<internal::NativeWidgetView*>(target); | |
| 294 views::Widget* target_widget = native_widget_view->GetAssociatedWidget(); | |
| 295 if (!target_widget->IsActive() && target_widget->CanActivate()) { | |
| 296 Activate(target_widget); | |
| 297 return true; | |
| 298 } | |
| 299 } | |
| 300 | |
| 301 return false; | |
| 302 } | |
| 303 | |
| 304 } // namespace desktop | |
| 305 } // namespace views | |
| OLD | NEW |