| 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 "views/widget/native_widget_views.h" |  | 
| 6 |  | 
| 7 #include "base/bind.h" |  | 
| 8 #include "ui/base/hit_test.h" |  | 
| 9 #include "ui/gfx/compositor/compositor.h" |  | 
| 10 #include "ui/gfx/compositor/layer.h" |  | 
| 11 #include "ui/gfx/compositor/layer_animator.h" |  | 
| 12 #include "views/view.h" |  | 
| 13 #include "views/views_delegate.h" |  | 
| 14 #include "views/widget/native_widget_view.h" |  | 
| 15 #include "views/widget/root_view.h" |  | 
| 16 #include "views/widget/tooltip_manager_views.h" |  | 
| 17 #include "views/widget/window_manager.h" |  | 
| 18 |  | 
| 19 #if defined(HAVE_IBUS) |  | 
| 20 #include "ui/views/ime/input_method_ibus.h" |  | 
| 21 #else |  | 
| 22 #include "ui/views/ime/mock_input_method.h" |  | 
| 23 #endif |  | 
| 24 |  | 
| 25 namespace { |  | 
| 26 |  | 
| 27 gfx::Rect AdjustRectOriginForParentWidget(const gfx::Rect& rect, |  | 
| 28                                           const views::Widget* parent) { |  | 
| 29   if (!parent) |  | 
| 30     return rect; |  | 
| 31 |  | 
| 32   gfx::Rect adjusted = rect; |  | 
| 33   gfx::Rect parent_bounds = parent->GetWindowScreenBounds(); |  | 
| 34   adjusted.Offset(-parent_bounds.x(), -parent_bounds.y()); |  | 
| 35   return adjusted; |  | 
| 36 } |  | 
| 37 |  | 
| 38 }  // namespace |  | 
| 39 |  | 
| 40 namespace views { |  | 
| 41 |  | 
| 42 //////////////////////////////////////////////////////////////////////////////// |  | 
| 43 // NativeWidgetViews, public: |  | 
| 44 |  | 
| 45 NativeWidgetViews::NativeWidgetViews(internal::NativeWidgetDelegate* delegate) |  | 
| 46     : delegate_(delegate), |  | 
| 47       parent_(NULL), |  | 
| 48       view_(NULL), |  | 
| 49       active_(false), |  | 
| 50       window_state_(ui::SHOW_STATE_DEFAULT), |  | 
| 51       always_on_top_(false), |  | 
| 52       ALLOW_THIS_IN_INITIALIZER_LIST(close_widget_factory_(this)), |  | 
| 53       ownership_(Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET), |  | 
| 54       delete_native_view_(true) { |  | 
| 55 } |  | 
| 56 |  | 
| 57 NativeWidgetViews::~NativeWidgetViews() { |  | 
| 58   delegate_->OnNativeWidgetDestroying(); |  | 
| 59 |  | 
| 60   if (view_ && delete_native_view_) { |  | 
| 61     // We must prevent the NativeWidgetView from attempting to delete us. |  | 
| 62     view_->set_delete_native_widget(false); |  | 
| 63     delete view_; |  | 
| 64   } |  | 
| 65 |  | 
| 66   delegate_->OnNativeWidgetDestroyed(); |  | 
| 67   if (ownership_ == Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET) |  | 
| 68     delete delegate_; |  | 
| 69 } |  | 
| 70 |  | 
| 71 View* NativeWidgetViews::GetView() { |  | 
| 72   return view_; |  | 
| 73 } |  | 
| 74 |  | 
| 75 const View* NativeWidgetViews::GetView() const { |  | 
| 76   return view_; |  | 
| 77 } |  | 
| 78 |  | 
| 79 void NativeWidgetViews::OnActivate(bool active) { |  | 
| 80   // TODO(oshima): find out if we should check toplevel here. |  | 
| 81   if (active_ == active) |  | 
| 82     return; |  | 
| 83   active_ = active; |  | 
| 84   delegate_->OnNativeWidgetActivationChanged(active); |  | 
| 85 |  | 
| 86   // TODO(oshima): Focus change should be separated from window activation. |  | 
| 87   // This will be fixed when we have WM API. |  | 
| 88   Widget* widget = GetWidget(); |  | 
| 89   if (widget->is_top_level()) { |  | 
| 90     InputMethod* input_method = widget->GetInputMethod(); |  | 
| 91     if (active) { |  | 
| 92       input_method->OnFocus(); |  | 
| 93       // See description of got_initial_focus_in_ for details on this. |  | 
| 94       widget->GetFocusManager()->RestoreFocusedView(); |  | 
| 95     } else { |  | 
| 96       input_method->OnBlur(); |  | 
| 97       widget->GetFocusManager()->StoreFocusedView(); |  | 
| 98     } |  | 
| 99   } |  | 
| 100   view_->SchedulePaint(); |  | 
| 101 } |  | 
| 102 |  | 
| 103 bool NativeWidgetViews::OnKeyEvent(const KeyEvent& key_event) { |  | 
| 104   InputMethod* input_method = GetWidget()->GetInputMethod(); |  | 
| 105   DCHECK(input_method); |  | 
| 106   input_method->DispatchKeyEvent(key_event); |  | 
| 107   return true; |  | 
| 108 } |  | 
| 109 |  | 
| 110 void NativeWidgetViews::DispatchKeyEventPostIME(const KeyEvent& key) { |  | 
| 111   // TODO(oshima): GTK impl handles menu_key in special way. This may be |  | 
| 112   // necessary when running under NativeWidgetX. |  | 
| 113   if (delegate_->OnKeyEvent(key)) |  | 
| 114     return; |  | 
| 115   if (key.type() == ui::ET_KEY_PRESSED && GetWidget()->GetFocusManager()) |  | 
| 116     GetWidget()->GetFocusManager()->OnKeyEvent(key); |  | 
| 117 } |  | 
| 118 |  | 
| 119 //////////////////////////////////////////////////////////////////////////////// |  | 
| 120 // NativeWidgetViews, protected: |  | 
| 121 |  | 
| 122 void NativeWidgetViews::OnBoundsChanged(const gfx::Rect& new_bounds, |  | 
| 123                                         const gfx::Rect& old_bounds) { |  | 
| 124   delegate_->OnNativeWidgetSizeChanged(new_bounds.size()); |  | 
| 125 } |  | 
| 126 |  | 
| 127 bool NativeWidgetViews::OnMouseEvent(const MouseEvent& event) { |  | 
| 128 #if defined(TOUCH_UI) || defined(USE_AURA) |  | 
| 129   TooltipManagerViews* tooltip_manager = |  | 
| 130       static_cast<TooltipManagerViews*>(GetTooltipManager()); |  | 
| 131   if (tooltip_manager) |  | 
| 132     tooltip_manager->UpdateForMouseEvent(event); |  | 
| 133 #endif |  | 
| 134   return HandleWindowOperation(event) ? true : delegate_->OnMouseEvent(event); |  | 
| 135 } |  | 
| 136 |  | 
| 137 //////////////////////////////////////////////////////////////////////////////// |  | 
| 138 // NativeWidgetViews, NativeWidget implementation: |  | 
| 139 |  | 
| 140 void NativeWidgetViews::InitNativeWidget(const Widget::InitParams& params) { |  | 
| 141   parent_ = params.parent_widget; |  | 
| 142   ownership_ = params.ownership; |  | 
| 143   always_on_top_ = params.keep_on_top; |  | 
| 144   View* parent_view = NULL; |  | 
| 145   if (params.parent_widget) { |  | 
| 146     parent_view = params.parent_widget->GetChildViewParent(); |  | 
| 147   } else if (ViewsDelegate::views_delegate && |  | 
| 148              ViewsDelegate::views_delegate->GetDefaultParentView() && |  | 
| 149              !params.child) { |  | 
| 150     parent_view = ViewsDelegate::views_delegate->GetDefaultParentView(); |  | 
| 151   } else if (params.parent) { |  | 
| 152     Widget* widget = Widget::GetWidgetForNativeView(params.parent); |  | 
| 153     parent_view = widget->GetChildViewParent(); |  | 
| 154   } |  | 
| 155 |  | 
| 156   gfx::Rect bounds = GetWidget()->is_top_level() ? |  | 
| 157       AdjustRectOriginForParentWidget(params.bounds, parent_) : params.bounds; |  | 
| 158   view_ = new internal::NativeWidgetView(this); |  | 
| 159   view_->SetBoundsRect(bounds); |  | 
| 160   view_->SetVisible(params.type == Widget::InitParams::TYPE_CONTROL); |  | 
| 161 |  | 
| 162   // With the default NATIVE_WIDGET_OWNS_WIDGET ownership, the |  | 
| 163   // deletion of either of the NativeWidgetViews or NativeWidgetView |  | 
| 164   // (e.g. via View hierarchy destruction) will delete the other. |  | 
| 165   // With WIDGET_OWNS_NATIVE_WIDGET, NativeWidgetViews should only |  | 
| 166   // be deleted by its Widget. |  | 
| 167   if (ownership_ == Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET) |  | 
| 168     view_->set_delete_native_widget(false); |  | 
| 169 |  | 
| 170   if (parent_view) |  | 
| 171     parent_view->AddChildView(view_); |  | 
| 172   view_->SetPaintToLayer(true); |  | 
| 173   if (View::get_use_acceleration_when_possible()) |  | 
| 174     view_->SetFillsBoundsOpaquely(!params.transparent); |  | 
| 175   // TODO(beng): SetInitParams(). |  | 
| 176 } |  | 
| 177 |  | 
| 178 NonClientFrameView* NativeWidgetViews::CreateNonClientFrameView() { |  | 
| 179   return NULL; |  | 
| 180 } |  | 
| 181 |  | 
| 182 void NativeWidgetViews::UpdateFrameAfterFrameChange() { |  | 
| 183 } |  | 
| 184 |  | 
| 185 bool NativeWidgetViews::ShouldUseNativeFrame() const { |  | 
| 186 //  NOTIMPLEMENTED(); |  | 
| 187   return false; |  | 
| 188 } |  | 
| 189 |  | 
| 190 void NativeWidgetViews::FrameTypeChanged() { |  | 
| 191 } |  | 
| 192 |  | 
| 193 Widget* NativeWidgetViews::GetWidget() { |  | 
| 194   return delegate_->AsWidget(); |  | 
| 195 } |  | 
| 196 |  | 
| 197 const Widget* NativeWidgetViews::GetWidget() const { |  | 
| 198   return delegate_->AsWidget(); |  | 
| 199 } |  | 
| 200 |  | 
| 201 gfx::NativeView NativeWidgetViews::GetNativeView() const { |  | 
| 202   return GetParentNativeWidget() ? |  | 
| 203       GetParentNativeWidget()->GetNativeView() : NULL; |  | 
| 204 } |  | 
| 205 |  | 
| 206 gfx::NativeWindow NativeWidgetViews::GetNativeWindow() const { |  | 
| 207   return GetParentNativeWidget() ? |  | 
| 208       GetParentNativeWidget()->GetNativeWindow() : NULL; |  | 
| 209 } |  | 
| 210 |  | 
| 211 Widget* NativeWidgetViews::GetTopLevelWidget() { |  | 
| 212   // This can get called when this is in the process of being destroyed, and |  | 
| 213   // view_ has already been unset. |  | 
| 214   if (!view_) |  | 
| 215     return GetWidget(); |  | 
| 216   if (ViewsDelegate::views_delegate && |  | 
| 217       view_->parent() == ViewsDelegate::views_delegate->GetDefaultParentView()) |  | 
| 218     return GetWidget(); |  | 
| 219   // During Widget destruction, this function may be called after |view_| is |  | 
| 220   // detached from a Widget, at which point this NativeWidget's Widget becomes |  | 
| 221   // the effective toplevel. |  | 
| 222   Widget* containing_widget = view_->GetWidget(); |  | 
| 223   return containing_widget ? containing_widget->GetTopLevelWidget() |  | 
| 224                            : GetWidget(); |  | 
| 225 } |  | 
| 226 |  | 
| 227 const ui::Compositor* NativeWidgetViews::GetCompositor() const { |  | 
| 228   return view_->GetWidget() ? view_->GetWidget()->GetCompositor() : NULL; |  | 
| 229 } |  | 
| 230 |  | 
| 231 ui::Compositor* NativeWidgetViews::GetCompositor() { |  | 
| 232   return view_->GetWidget() ? view_->GetWidget()->GetCompositor() : NULL; |  | 
| 233 } |  | 
| 234 |  | 
| 235 void NativeWidgetViews::CalculateOffsetToAncestorWithLayer( |  | 
| 236     gfx::Point* offset, |  | 
| 237     ui::Layer** layer_parent) { |  | 
| 238   view_->CalculateOffsetToAncestorWithLayer(offset, layer_parent); |  | 
| 239 } |  | 
| 240 |  | 
| 241 void NativeWidgetViews::ReorderLayers() { |  | 
| 242   view_->ReorderLayers(); |  | 
| 243 } |  | 
| 244 |  | 
| 245 void NativeWidgetViews::ViewRemoved(View* view) { |  | 
| 246   internal::NativeWidgetPrivate* parent = GetParentNativeWidget(); |  | 
| 247   if (parent) |  | 
| 248     parent->ViewRemoved(view); |  | 
| 249 } |  | 
| 250 |  | 
| 251 void NativeWidgetViews::SetNativeWindowProperty(const char* name, void* value) { |  | 
| 252   if (value) |  | 
| 253     props_map_[name] = value; |  | 
| 254   else |  | 
| 255     props_map_.erase(name); |  | 
| 256 } |  | 
| 257 |  | 
| 258 void* NativeWidgetViews::GetNativeWindowProperty(const char* name) const { |  | 
| 259   PropsMap::const_iterator iter = props_map_.find(name); |  | 
| 260   return iter != props_map_.end() ? iter->second : NULL; |  | 
| 261 } |  | 
| 262 |  | 
| 263 TooltipManager* NativeWidgetViews::GetTooltipManager() const { |  | 
| 264   const internal::NativeWidgetPrivate* parent = GetParentNativeWidget(); |  | 
| 265   return parent ? parent->GetTooltipManager() : NULL; |  | 
| 266 } |  | 
| 267 |  | 
| 268 bool NativeWidgetViews::IsScreenReaderActive() const { |  | 
| 269   return GetParentNativeWidget()->IsScreenReaderActive(); |  | 
| 270 } |  | 
| 271 |  | 
| 272 void NativeWidgetViews::SendNativeAccessibilityEvent( |  | 
| 273     View* view, |  | 
| 274     ui::AccessibilityTypes::Event event_type) { |  | 
| 275   return GetParentNativeWidget()->SendNativeAccessibilityEvent(view, |  | 
| 276                                                                event_type); |  | 
| 277 } |  | 
| 278 |  | 
| 279 void NativeWidgetViews::SetMouseCapture() { |  | 
| 280   WindowManager::Get()->SetMouseCapture(GetWidget()); |  | 
| 281 } |  | 
| 282 |  | 
| 283 void NativeWidgetViews::ReleaseMouseCapture() { |  | 
| 284   WindowManager::Get()->ReleaseMouseCapture(GetWidget()); |  | 
| 285 } |  | 
| 286 |  | 
| 287 bool NativeWidgetViews::HasMouseCapture() const { |  | 
| 288   return WindowManager::Get()->HasMouseCapture(GetWidget()); |  | 
| 289 } |  | 
| 290 |  | 
| 291 InputMethod* NativeWidgetViews::CreateInputMethod() { |  | 
| 292 #if defined(HAVE_IBUS) |  | 
| 293   InputMethod* input_method = new InputMethodIBus(this); |  | 
| 294 #else |  | 
| 295   InputMethod* input_method = new MockInputMethod(this); |  | 
| 296 #endif |  | 
| 297   input_method->Init(GetWidget()); |  | 
| 298   return input_method; |  | 
| 299 } |  | 
| 300 |  | 
| 301 void NativeWidgetViews::CenterWindow(const gfx::Size& size) { |  | 
| 302   const gfx::Size parent_size = GetView()->parent()->size(); |  | 
| 303   GetView()->SetBounds((parent_size.width() - size.width())/2, |  | 
| 304                        (parent_size.height() - size.height())/2, |  | 
| 305                        size.width(), size.height()); |  | 
| 306 } |  | 
| 307 |  | 
| 308 void NativeWidgetViews::GetWindowPlacement( |  | 
| 309     gfx::Rect* bounds, |  | 
| 310     ui::WindowShowState* show_state) const { |  | 
| 311   *bounds = GetView()->bounds(); |  | 
| 312   *show_state = ui::SHOW_STATE_NORMAL; |  | 
| 313 } |  | 
| 314 |  | 
| 315 void NativeWidgetViews::SetWindowTitle(const string16& title) { |  | 
| 316 } |  | 
| 317 |  | 
| 318 void NativeWidgetViews::SetWindowIcons(const SkBitmap& window_icon, |  | 
| 319                                        const SkBitmap& app_icon) { |  | 
| 320 } |  | 
| 321 |  | 
| 322 void NativeWidgetViews::SetAccessibleName(const string16& name) { |  | 
| 323 } |  | 
| 324 |  | 
| 325 void NativeWidgetViews::SetAccessibleRole(ui::AccessibilityTypes::Role role) { |  | 
| 326 } |  | 
| 327 |  | 
| 328 void NativeWidgetViews::SetAccessibleState( |  | 
| 329     ui::AccessibilityTypes::State state) { |  | 
| 330 } |  | 
| 331 |  | 
| 332 void NativeWidgetViews::BecomeModal() { |  | 
| 333   NOTIMPLEMENTED(); |  | 
| 334 } |  | 
| 335 |  | 
| 336 gfx::Rect NativeWidgetViews::GetWindowScreenBounds() const { |  | 
| 337   if (GetWidget() == GetWidget()->GetTopLevelWidget() && |  | 
| 338       !parent_) |  | 
| 339     return view_->bounds(); |  | 
| 340   gfx::Point origin = view_->bounds().origin(); |  | 
| 341   View::ConvertPointToScreen(view_->parent(), &origin); |  | 
| 342   return gfx::Rect(origin.x(), origin.y(), view_->width(), view_->height()); |  | 
| 343 } |  | 
| 344 |  | 
| 345 gfx::Rect NativeWidgetViews::GetClientAreaScreenBounds() const { |  | 
| 346   return GetWindowScreenBounds(); |  | 
| 347 } |  | 
| 348 |  | 
| 349 gfx::Rect NativeWidgetViews::GetRestoredBounds() const { |  | 
| 350   return GetWindowScreenBounds(); |  | 
| 351 } |  | 
| 352 |  | 
| 353 void NativeWidgetViews::SetBounds(const gfx::Rect& bounds) { |  | 
| 354   // |bounds| are supplied in the coordinates of the parent. |  | 
| 355   if (GetWidget()->is_top_level()) |  | 
| 356     view_->SetBoundsRect(AdjustRectOriginForParentWidget(bounds, parent_)); |  | 
| 357   else |  | 
| 358     view_->SetBoundsRect(bounds); |  | 
| 359 } |  | 
| 360 |  | 
| 361 void NativeWidgetViews::SetSize(const gfx::Size& size) { |  | 
| 362   view_->SetSize(size); |  | 
| 363 } |  | 
| 364 |  | 
| 365 void NativeWidgetViews::MoveAbove(gfx::NativeView native_view) { |  | 
| 366   NOTIMPLEMENTED(); |  | 
| 367 } |  | 
| 368 |  | 
| 369 void NativeWidgetViews::MoveToTop() { |  | 
| 370   view_->parent()->ReorderChildView(view_, -1); |  | 
| 371 } |  | 
| 372 |  | 
| 373 void NativeWidgetViews::SetShape(gfx::NativeRegion region) { |  | 
| 374   NOTIMPLEMENTED(); |  | 
| 375 } |  | 
| 376 |  | 
| 377 void NativeWidgetViews::Close() { |  | 
| 378   Hide(); |  | 
| 379   if (!close_widget_factory_.HasWeakPtrs()) { |  | 
| 380     MessageLoop::current()->PostTask( |  | 
| 381         FROM_HERE, |  | 
| 382         base::Bind(&NativeWidgetViews::CloseNow, |  | 
| 383                    close_widget_factory_.GetWeakPtr())); |  | 
| 384   } |  | 
| 385 } |  | 
| 386 |  | 
| 387 void NativeWidgetViews::CloseNow() { |  | 
| 388   delete view_; |  | 
| 389   view_ = NULL; |  | 
| 390 } |  | 
| 391 |  | 
| 392 void NativeWidgetViews::EnableClose(bool enable) { |  | 
| 393 } |  | 
| 394 |  | 
| 395 void NativeWidgetViews::Show() { |  | 
| 396   if (always_on_top_) |  | 
| 397     MoveToTop(); |  | 
| 398   view_->SetVisible(true); |  | 
| 399   GetWidget()->SetInitialFocus(); |  | 
| 400 } |  | 
| 401 |  | 
| 402 void NativeWidgetViews::Hide() { |  | 
| 403   view_->SetVisible(false); |  | 
| 404   if (HasMouseCapture()) |  | 
| 405     ReleaseMouseCapture(); |  | 
| 406 |  | 
| 407   // This is necessary because views desktop's window manager doesn't |  | 
| 408   // set the focus back to parent. |  | 
| 409   if (GetWidget()->is_top_level()) { |  | 
| 410     Widget* parent_widget = view_->GetWidget(); |  | 
| 411     if (parent_widget && parent_widget->GetInputMethod()) |  | 
| 412       parent_widget->GetInputMethod()->OnFocus(); |  | 
| 413   } |  | 
| 414 } |  | 
| 415 |  | 
| 416 void NativeWidgetViews::ShowWithWindowState(ui::WindowShowState show_state) { |  | 
| 417   Show(); |  | 
| 418 } |  | 
| 419 |  | 
| 420 void NativeWidgetViews::ShowMaximizedWithBounds( |  | 
| 421     const gfx::Rect& restored_bounds) { |  | 
| 422   Show(); |  | 
| 423 } |  | 
| 424 |  | 
| 425 bool NativeWidgetViews::IsVisible() const { |  | 
| 426   return view_->IsVisible() && (GetWidget()->is_top_level() || |  | 
| 427                                 GetWidget()->GetTopLevelWidget()->IsVisible()); |  | 
| 428 } |  | 
| 429 |  | 
| 430 void NativeWidgetViews::Activate() { |  | 
| 431   // Enable WidgetObserverTest.ActivationChange when this is implemented. |  | 
| 432   MoveToTop(); |  | 
| 433   OnActivate(true); |  | 
| 434 } |  | 
| 435 |  | 
| 436 void NativeWidgetViews::Deactivate() { |  | 
| 437   OnActivate(false); |  | 
| 438 } |  | 
| 439 |  | 
| 440 bool NativeWidgetViews::IsActive() const { |  | 
| 441   return active_; |  | 
| 442 } |  | 
| 443 |  | 
| 444 void NativeWidgetViews::SetAlwaysOnTop(bool on_top) { |  | 
| 445   always_on_top_ = on_top; |  | 
| 446   // This is not complete yet. At least |MoveToTop| will need to be updated to |  | 
| 447   // make sure a 'normal' window does not get on top of a window with |  | 
| 448   // |always_on_top_| set. |  | 
| 449   NOTIMPLEMENTED(); |  | 
| 450 } |  | 
| 451 |  | 
| 452 void NativeWidgetViews::Maximize() { |  | 
| 453   if (window_state_ == ui::SHOW_STATE_MAXIMIZED) |  | 
| 454     return; |  | 
| 455 |  | 
| 456   if (window_state_ != ui::SHOW_STATE_MINIMIZED) { |  | 
| 457     // Remember bounds and transform to use when unmaximized. |  | 
| 458     restored_bounds_ = view_->bounds(); |  | 
| 459     restored_transform_ = view_->GetTransform(); |  | 
| 460   } |  | 
| 461 |  | 
| 462   window_state_ = ui::SHOW_STATE_MAXIMIZED; |  | 
| 463   gfx::Size size = GetParentNativeWidget()->GetWindowScreenBounds().size(); |  | 
| 464   SetBounds(gfx::Rect(gfx::Point(), size)); |  | 
| 465 } |  | 
| 466 |  | 
| 467 void NativeWidgetViews::Minimize() { |  | 
| 468   if (view_->layer() && view_->layer()->GetAnimator()->is_animating()) |  | 
| 469     return; |  | 
| 470 |  | 
| 471   gfx::Rect view_bounds = view_->bounds(); |  | 
| 472   gfx::Rect parent_bounds = view_->parent()->bounds(); |  | 
| 473 |  | 
| 474   if (window_state_ != ui::SHOW_STATE_MAXIMIZED) { |  | 
| 475     restored_bounds_ = view_bounds; |  | 
| 476     restored_transform_ = view_->GetTransform(); |  | 
| 477   } |  | 
| 478 |  | 
| 479   float aspect_ratio = static_cast<float>(view_bounds.width()) / |  | 
| 480                        static_cast<float>(view_bounds.height()); |  | 
| 481   int target_size = 100; |  | 
| 482   int target_height = target_size; |  | 
| 483   int target_width = static_cast<int>(aspect_ratio * target_height); |  | 
| 484   if (target_width > target_size) { |  | 
| 485     target_width = target_size; |  | 
| 486     target_height = static_cast<int>(target_width / aspect_ratio); |  | 
| 487   } |  | 
| 488 |  | 
| 489   int target_x = 20; |  | 
| 490   int target_y = parent_bounds.height() - target_size - 20; |  | 
| 491 |  | 
| 492   view_->SetBounds( |  | 
| 493       target_x, target_y, view_bounds.width(), view_bounds.height()); |  | 
| 494 |  | 
| 495   ui::Transform transform; |  | 
| 496   transform.SetScale((float)target_width / (float)view_bounds.width(), |  | 
| 497                      (float)target_height / (float)view_bounds.height()); |  | 
| 498   view_->SetTransform(transform); |  | 
| 499 |  | 
| 500   window_state_ = ui::SHOW_STATE_MINIMIZED; |  | 
| 501 } |  | 
| 502 |  | 
| 503 bool NativeWidgetViews::IsMaximized() const { |  | 
| 504   return window_state_ == ui::SHOW_STATE_MAXIMIZED; |  | 
| 505 } |  | 
| 506 |  | 
| 507 bool NativeWidgetViews::IsMinimized() const { |  | 
| 508   return window_state_ == ui::SHOW_STATE_MINIMIZED; |  | 
| 509 } |  | 
| 510 |  | 
| 511 void NativeWidgetViews::Restore() { |  | 
| 512   if (view_->layer() && view_->layer()->GetAnimator()->is_animating()) |  | 
| 513     return; |  | 
| 514 |  | 
| 515   window_state_ = ui::SHOW_STATE_NORMAL; |  | 
| 516   view_->SetBoundsRect(restored_bounds_); |  | 
| 517   view_->SetTransform(restored_transform_); |  | 
| 518 } |  | 
| 519 |  | 
| 520 void NativeWidgetViews::SetFullscreen(bool fullscreen) { |  | 
| 521   NOTIMPLEMENTED(); |  | 
| 522 } |  | 
| 523 |  | 
| 524 bool NativeWidgetViews::IsFullscreen() const { |  | 
| 525   // NOTIMPLEMENTED(); |  | 
| 526   return false; |  | 
| 527 } |  | 
| 528 |  | 
| 529 void NativeWidgetViews::SetOpacity(unsigned char opacity) { |  | 
| 530   NOTIMPLEMENTED(); |  | 
| 531 } |  | 
| 532 |  | 
| 533 void NativeWidgetViews::SetUseDragFrame(bool use_drag_frame) { |  | 
| 534   NOTIMPLEMENTED(); |  | 
| 535 } |  | 
| 536 |  | 
| 537 bool NativeWidgetViews::IsAccessibleWidget() const { |  | 
| 538   NOTIMPLEMENTED(); |  | 
| 539   return false; |  | 
| 540 } |  | 
| 541 |  | 
| 542 void NativeWidgetViews::RunShellDrag(View* view, |  | 
| 543                                      const ui::OSExchangeData& data, |  | 
| 544                                      int operation) { |  | 
| 545   GetParentNativeWidget()->RunShellDrag(view, data, operation); |  | 
| 546 } |  | 
| 547 |  | 
| 548 void NativeWidgetViews::SchedulePaintInRect(const gfx::Rect& rect) { |  | 
| 549   view_->SchedulePaintInRect(rect); |  | 
| 550 } |  | 
| 551 |  | 
| 552 void NativeWidgetViews::SetCursor(gfx::NativeCursor cursor) { |  | 
| 553   view_->set_cursor(cursor); |  | 
| 554   GetParentNativeWidget()->SetCursor(cursor); |  | 
| 555 } |  | 
| 556 |  | 
| 557 void NativeWidgetViews::ClearNativeFocus() { |  | 
| 558   GetParentNativeWidget()->ClearNativeFocus(); |  | 
| 559 } |  | 
| 560 |  | 
| 561 void NativeWidgetViews::FocusNativeView(gfx::NativeView native_view) { |  | 
| 562   GetParentNativeWidget()->FocusNativeView(native_view); |  | 
| 563 } |  | 
| 564 |  | 
| 565 bool NativeWidgetViews::ConvertPointFromAncestor( |  | 
| 566     const Widget* ancestor, gfx::Point* point) const { |  | 
| 567   // This method converts the point from ancestor's coordinates to |  | 
| 568   // this widget's coordinate using recursion as the widget hierachy |  | 
| 569   // is usually shallow. |  | 
| 570 |  | 
| 571   if (ancestor == GetWidget()) |  | 
| 572     return true;  // no conversion necessary |  | 
| 573 |  | 
| 574   const Widget* parent_widget = view_->GetWidget(); |  | 
| 575   if (!parent_widget)  // couldn't reach the ancestor. |  | 
| 576     return false; |  | 
| 577 |  | 
| 578   if (parent_widget == ancestor || |  | 
| 579       parent_widget->ConvertPointFromAncestor(ancestor, point)) { |  | 
| 580     View::ConvertPointToView(parent_widget->GetRootView(), GetView(), point); |  | 
| 581     return true; |  | 
| 582   } |  | 
| 583   return false; |  | 
| 584 } |  | 
| 585 |  | 
| 586 gfx::Rect NativeWidgetViews::GetWorkAreaBoundsInScreen() const { |  | 
| 587   return GetParentNativeWidget()->GetWorkAreaBoundsInScreen(); |  | 
| 588 } |  | 
| 589 |  | 
| 590 void NativeWidgetViews::SetInactiveRenderingDisabled(bool value) { |  | 
| 591 } |  | 
| 592 |  | 
| 593 //////////////////////////////////////////////////////////////////////////////// |  | 
| 594 // NativeWidgetViews, private: |  | 
| 595 |  | 
| 596 internal::NativeWidgetPrivate* NativeWidgetViews::GetParentNativeWidget() { |  | 
| 597   Widget* containing_widget = view_ ? view_->GetWidget() : NULL; |  | 
| 598   return containing_widget ? static_cast<internal::NativeWidgetPrivate*>( |  | 
| 599       containing_widget->native_widget()) : |  | 
| 600       NULL; |  | 
| 601 } |  | 
| 602 |  | 
| 603 const internal::NativeWidgetPrivate* |  | 
| 604     NativeWidgetViews::GetParentNativeWidget() const { |  | 
| 605   const Widget* containing_widget = view_ ? view_->GetWidget() : NULL; |  | 
| 606   return containing_widget ? static_cast<const internal::NativeWidgetPrivate*>( |  | 
| 607       containing_widget->native_widget()) : |  | 
| 608       NULL; |  | 
| 609 } |  | 
| 610 |  | 
| 611 bool NativeWidgetViews::HandleWindowOperation(const MouseEvent& event) { |  | 
| 612   if (event.type() != ui::ET_MOUSE_PRESSED) |  | 
| 613     return false; |  | 
| 614 |  | 
| 615   Widget* widget = GetWidget(); |  | 
| 616   if (widget->non_client_view()) { |  | 
| 617     int hittest_code = widget->non_client_view()->NonClientHitTest( |  | 
| 618         event.location()); |  | 
| 619     switch (hittest_code) { |  | 
| 620       case HTCAPTION: { |  | 
| 621         if (!event.IsOnlyRightMouseButton()) { |  | 
| 622           WindowManager::Get()->StartMoveDrag(widget, event.location()); |  | 
| 623           return true; |  | 
| 624         } |  | 
| 625         break; |  | 
| 626       } |  | 
| 627       case HTBOTTOM: |  | 
| 628       case HTBOTTOMLEFT: |  | 
| 629       case HTBOTTOMRIGHT: |  | 
| 630       case HTGROWBOX: |  | 
| 631       case HTLEFT: |  | 
| 632       case HTRIGHT: |  | 
| 633       case HTTOP: |  | 
| 634       case HTTOPLEFT: |  | 
| 635       case HTTOPRIGHT: { |  | 
| 636         WindowManager::Get()->StartResizeDrag( |  | 
| 637             widget, event.location(), hittest_code); |  | 
| 638         return true; |  | 
| 639       } |  | 
| 640       default: |  | 
| 641         // Everything else falls into standard client event handling. |  | 
| 642         break; |  | 
| 643     } |  | 
| 644   } |  | 
| 645   return false; |  | 
| 646 } |  | 
| 647 |  | 
| 648 }  // namespace views |  | 
| OLD | NEW | 
|---|