| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2012 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 "chrome/browser/ui/panels/panel_browser_view.h" | |
| 6 | |
| 7 #include "base/command_line.h" | |
| 8 #include "base/logging.h" | |
| 9 #include "chrome/browser/native_window_notification_source.h" | |
| 10 #include "chrome/browser/ui/browser_window.h" | |
| 11 #include "chrome/browser/ui/panels/display_settings_provider.h" | |
| 12 #include "chrome/browser/ui/panels/panel.h" | |
| 13 #include "chrome/browser/ui/panels/panel_bounds_animation.h" | |
| 14 #include "chrome/browser/ui/panels/panel_browser_frame_view.h" | |
| 15 #include "chrome/browser/ui/panels/panel_manager.h" | |
| 16 #include "chrome/browser/ui/panels/panel_strip.h" | |
| 17 #include "chrome/browser/ui/views/frame/browser_frame.h" | |
| 18 #include "chrome/common/chrome_notification_types.h" | |
| 19 #include "content/public/browser/native_web_keyboard_event.h" | |
| 20 #include "content/public/browser/notification_service.h" | |
| 21 #include "grit/chromium_strings.h" | |
| 22 #include "ui/base/l10n/l10n_util.h" | |
| 23 #include "ui/gfx/canvas.h" | |
| 24 #include "ui/gfx/screen.h" | |
| 25 #include "ui/views/controls/button/image_button.h" | |
| 26 #include "ui/views/controls/label.h" | |
| 27 #include "ui/views/widget/widget.h" | |
| 28 | |
| 29 #if defined(OS_WIN) && !defined(USE_ASH) && !defined(USE_AURA) | |
| 30 #include "base/win/windows_version.h" | |
| 31 #include "chrome/browser/ui/panels/taskbar_window_thumbnailer_win.h" | |
| 32 #endif | |
| 33 | |
| 34 using content::NativeWebKeyboardEvent; | |
| 35 using content::WebContents; | |
| 36 | |
| 37 NativePanel* Panel::CreateNativePanel(Browser* browser, Panel* panel, | |
| 38 const gfx::Rect& bounds) { | |
| 39 PanelBrowserView* view = new PanelBrowserView(browser, panel, bounds); | |
| 40 (new BrowserFrame(view))->InitBrowserFrame(); | |
| 41 return view; | |
| 42 } | |
| 43 | |
| 44 PanelBrowserView::PanelBrowserView(Browser* browser, Panel* panel, | |
| 45 const gfx::Rect& bounds) | |
| 46 : BrowserView(browser), | |
| 47 panel_(panel), | |
| 48 bounds_(bounds), | |
| 49 closed_(false), | |
| 50 focused_(false), | |
| 51 mouse_pressed_(false), | |
| 52 mouse_dragging_state_(NO_DRAGGING), | |
| 53 is_drawing_attention_(false), | |
| 54 force_to_paint_as_inactive_(false), | |
| 55 #if defined(OS_WIN) && !defined(USE_ASH) && !defined(USE_AURA) | |
| 56 old_focused_view_(NULL), | |
| 57 thumbnailer_(NULL) { | |
| 58 #else | |
| 59 old_focused_view_(NULL) { | |
| 60 #endif | |
| 61 } | |
| 62 | |
| 63 PanelBrowserView::~PanelBrowserView() { | |
| 64 } | |
| 65 | |
| 66 void PanelBrowserView::Init() { | |
| 67 if (!panel_->manager()->display_settings_provider()->is_full_screen()) { | |
| 68 // TODO(prasadt): Implement this code. | |
| 69 // HideThePanel. | |
| 70 } | |
| 71 | |
| 72 BrowserView::Init(); | |
| 73 | |
| 74 GetWidget()->non_client_view()->SetAccessibleName( | |
| 75 l10n_util::GetStringUTF16(IDS_PRODUCT_NAME)); | |
| 76 | |
| 77 registrar_.Add( | |
| 78 this, | |
| 79 chrome::NOTIFICATION_WINDOW_CLOSED, | |
| 80 content::Source<gfx::NativeWindow>(frame()->GetNativeWindow())); | |
| 81 } | |
| 82 | |
| 83 void PanelBrowserView::Show() { | |
| 84 BrowserView::Show(); | |
| 85 } | |
| 86 | |
| 87 void PanelBrowserView::ShowInactive() { | |
| 88 BrowserView::ShowInactive(); | |
| 89 } | |
| 90 | |
| 91 void PanelBrowserView::Close() { | |
| 92 GetWidget()->RemoveObserver(this); | |
| 93 closed_ = true; | |
| 94 | |
| 95 // Cancel any currently running animation since we're closing down. | |
| 96 if (bounds_animator_.get()) | |
| 97 bounds_animator_.reset(); | |
| 98 | |
| 99 ::BrowserView::Close(); | |
| 100 } | |
| 101 | |
| 102 void PanelBrowserView::Deactivate() { | |
| 103 if (!IsActive()) | |
| 104 return; | |
| 105 | |
| 106 #if defined(OS_WIN) && !defined(USE_AURA) | |
| 107 gfx::NativeWindow native_window = NULL; | |
| 108 BrowserWindow* browser_window = | |
| 109 panel_->manager()->GetNextBrowserWindowToActivate(GetPanelBrowser()); | |
| 110 if (browser_window) | |
| 111 native_window = browser_window->GetNativeWindow(); | |
| 112 else | |
| 113 native_window = ::GetDesktopWindow(); | |
| 114 if (native_window) | |
| 115 ::SetForegroundWindow(native_window); | |
| 116 else | |
| 117 ::SetFocus(NULL); | |
| 118 #else | |
| 119 NOTIMPLEMENTED(); | |
| 120 BrowserView::Deactivate(); | |
| 121 #endif | |
| 122 } | |
| 123 | |
| 124 bool PanelBrowserView::CanResize() const { | |
| 125 return true; | |
| 126 } | |
| 127 | |
| 128 bool PanelBrowserView::CanMaximize() const { | |
| 129 return false; | |
| 130 } | |
| 131 | |
| 132 void PanelBrowserView::SetBounds(const gfx::Rect& bounds) { | |
| 133 SetBoundsInternal(bounds, true); | |
| 134 } | |
| 135 | |
| 136 void PanelBrowserView::SetBoundsInternal(const gfx::Rect& new_bounds, | |
| 137 bool animate) { | |
| 138 if (bounds_ == new_bounds) | |
| 139 return; | |
| 140 | |
| 141 bounds_ = new_bounds; | |
| 142 | |
| 143 if (!animate) { | |
| 144 // If no animation is in progress, apply bounds change instantly. Otherwise, | |
| 145 // continue the animation with new target bounds. | |
| 146 if (!IsAnimatingBounds()) | |
| 147 ::BrowserView::SetBounds(new_bounds); | |
| 148 return; | |
| 149 } | |
| 150 | |
| 151 animation_start_bounds_ = GetBounds(); | |
| 152 | |
| 153 bounds_animator_.reset(new PanelBoundsAnimation( | |
| 154 this, panel(), animation_start_bounds_, new_bounds)); | |
| 155 bounds_animator_->Start(); | |
| 156 } | |
| 157 | |
| 158 void PanelBrowserView::UpdateTitleBar() { | |
| 159 ::BrowserView::UpdateTitleBar(); | |
| 160 GetFrameView()->UpdateTitleBar(); | |
| 161 } | |
| 162 | |
| 163 bool PanelBrowserView::IsPanel() const { | |
| 164 return true; | |
| 165 } | |
| 166 | |
| 167 bool PanelBrowserView::GetSavedWindowPlacement( | |
| 168 gfx::Rect* bounds, | |
| 169 ui::WindowShowState* show_state) const { | |
| 170 *bounds = bounds_; | |
| 171 *show_state = ui::SHOW_STATE_NORMAL; | |
| 172 return true; | |
| 173 } | |
| 174 | |
| 175 void PanelBrowserView::OnWidgetActivationChanged(views::Widget* widget, | |
| 176 bool active) { | |
| 177 ::BrowserView::OnWidgetActivationChanged(widget, active); | |
| 178 | |
| 179 #if defined(OS_WIN) && !defined(USE_AURA) | |
| 180 // The panel window is in focus (actually accepting keystrokes) if it is | |
| 181 // active and belongs to a foreground application. | |
| 182 bool focused = active && | |
| 183 GetFrameView()->GetWidget()->GetNativeView() == ::GetForegroundWindow(); | |
| 184 #else | |
| 185 NOTIMPLEMENTED(); | |
| 186 bool focused = active; | |
| 187 #endif | |
| 188 | |
| 189 if (focused_ == focused) | |
| 190 return; | |
| 191 focused_ = focused; | |
| 192 | |
| 193 // Expand the panel if the minimized panel is activated by means other than | |
| 194 // clicking on its titlebar. This is the workaround to support restoring the | |
| 195 // minimized panel by other means, like alt-tabbing, win-tabbing, or clicking | |
| 196 // the taskbar icon. Note that this workaround does not work for one edge | |
| 197 // case: the mouse happens to be at the minimized panel when the user tries to | |
| 198 // bring up the panel with the above alternatives. | |
| 199 // When the user clicks on the minimized panel, the panel expansion will be | |
| 200 // done when we process the mouse button pressed message. | |
| 201 if (focused_ && panel_->IsMinimized() && | |
| 202 gfx::Screen::GetWindowAtCursorScreenPoint() != | |
| 203 widget->GetNativeWindow()) { | |
| 204 panel_->Restore(); | |
| 205 } | |
| 206 | |
| 207 panel()->OnActiveStateChanged(focused); | |
| 208 } | |
| 209 | |
| 210 bool PanelBrowserView::AcceleratorPressed( | |
| 211 const ui::Accelerator& accelerator) { | |
| 212 if (mouse_pressed_ && accelerator.key_code() == ui::VKEY_ESCAPE) { | |
| 213 OnTitlebarMouseCaptureLost(); | |
| 214 return true; | |
| 215 } | |
| 216 | |
| 217 // No other accelerator is allowed when the drag begins. | |
| 218 if (mouse_dragging_state_ == DRAGGING_STARTED) | |
| 219 return true; | |
| 220 | |
| 221 return BrowserView::AcceleratorPressed(accelerator); | |
| 222 } | |
| 223 | |
| 224 void PanelBrowserView::Observe( | |
| 225 int type, | |
| 226 const content::NotificationSource& source, | |
| 227 const content::NotificationDetails& details) { | |
| 228 switch (type) { | |
| 229 case chrome::NOTIFICATION_WINDOW_CLOSED: | |
| 230 panel_->OnNativePanelClosed(); | |
| 231 break; | |
| 232 default: | |
| 233 NOTREACHED(); | |
| 234 } | |
| 235 } | |
| 236 | |
| 237 void PanelBrowserView::AnimationEnded(const ui::Animation* animation) { | |
| 238 panel_->manager()->OnPanelAnimationEnded(panel_.get()); | |
| 239 } | |
| 240 | |
| 241 void PanelBrowserView::AnimationProgressed(const ui::Animation* animation) { | |
| 242 gfx::Rect new_bounds = bounds_animator_->CurrentValueBetween( | |
| 243 animation_start_bounds_, bounds_); | |
| 244 | |
| 245 #if defined(OS_WIN) && !defined(USE_AURA) | |
| 246 // When the panel's height falls below the titlebar height, do not show | |
| 247 // thick frame since otherwise Windows will add extra size to the layout | |
| 248 // computation. | |
| 249 bool use_thick_frame = !GetFrameView()->IsShowingTitlebarOnly(); | |
| 250 UpdateWindowAttribute(GWL_STYLE, WS_THICKFRAME, use_thick_frame); | |
| 251 #endif | |
| 252 | |
| 253 ::BrowserView::SetBounds(new_bounds); | |
| 254 } | |
| 255 | |
| 256 void PanelBrowserView::OnDisplayChanged() { | |
| 257 BrowserView::OnDisplayChanged(); | |
| 258 panel_->manager()->display_settings_provider()->OnDisplaySettingsChanged(); | |
| 259 } | |
| 260 | |
| 261 void PanelBrowserView::OnWorkAreaChanged() { | |
| 262 BrowserView::OnWorkAreaChanged(); | |
| 263 panel_->manager()->display_settings_provider()->OnDisplaySettingsChanged(); | |
| 264 } | |
| 265 | |
| 266 bool PanelBrowserView::WillProcessWorkAreaChange() const { | |
| 267 return true; | |
| 268 } | |
| 269 | |
| 270 void PanelBrowserView::OnWindowBeginUserBoundsChange() { | |
| 271 panel_->OnPanelStartUserResizing(); | |
| 272 } | |
| 273 | |
| 274 void PanelBrowserView::OnWindowEndUserBoundsChange() { | |
| 275 panel_->OnPanelEndUserResizing(); | |
| 276 | |
| 277 // No need to proceed with post-resizing update when there is no size change. | |
| 278 gfx::Rect new_bounds = GetBounds(); | |
| 279 if (bounds_ == new_bounds) | |
| 280 return; | |
| 281 bounds_ = new_bounds; | |
| 282 | |
| 283 panel_->IncreaseMaxSize(bounds_.size()); | |
| 284 panel_->set_full_size(bounds_.size()); | |
| 285 | |
| 286 panel_->panel_strip()->RefreshLayout(); | |
| 287 } | |
| 288 | |
| 289 void PanelBrowserView::ShowPanel() { | |
| 290 Show(); | |
| 291 // No animation is used for initial creation of a panel on Win. | |
| 292 // Signal immediately that pending actions can be performed. | |
| 293 panel_->manager()->OnPanelAnimationEnded(panel_.get()); | |
| 294 } | |
| 295 | |
| 296 void PanelBrowserView::ShowPanelInactive() { | |
| 297 ShowInactive(); | |
| 298 // No animation is used for initial creation of a panel on Win. | |
| 299 // Signal immediately that pending actions can be performed. | |
| 300 panel_->manager()->OnPanelAnimationEnded(panel_.get()); | |
| 301 } | |
| 302 | |
| 303 gfx::Rect PanelBrowserView::GetPanelBounds() const { | |
| 304 return bounds_; | |
| 305 } | |
| 306 | |
| 307 void PanelBrowserView::SetPanelBounds(const gfx::Rect& bounds) { | |
| 308 SetBoundsInternal(bounds, true); | |
| 309 } | |
| 310 | |
| 311 void PanelBrowserView::SetPanelBoundsInstantly(const gfx::Rect& bounds) { | |
| 312 SetBoundsInternal(bounds, false); | |
| 313 } | |
| 314 | |
| 315 void PanelBrowserView::ClosePanel() { | |
| 316 Close(); | |
| 317 } | |
| 318 | |
| 319 void PanelBrowserView::ActivatePanel() { | |
| 320 Activate(); | |
| 321 } | |
| 322 | |
| 323 void PanelBrowserView::DeactivatePanel() { | |
| 324 Deactivate(); | |
| 325 } | |
| 326 | |
| 327 bool PanelBrowserView::IsPanelActive() const { | |
| 328 return IsActive(); | |
| 329 } | |
| 330 | |
| 331 void PanelBrowserView::PreventActivationByOS(bool prevent_activation) { | |
| 332 #if defined(OS_WIN) && !defined(USE_AURA) | |
| 333 // Set the flags "NoActivate" and "AppWindow" to make sure | |
| 334 // the minimized panels do not get activated by the OS, but | |
| 335 // do appear in the taskbar and Alt-Tab menu. | |
| 336 UpdateWindowAttribute(GWL_EXSTYLE, | |
| 337 WS_EX_NOACTIVATE | WS_EX_APPWINDOW, | |
| 338 prevent_activation); | |
| 339 #endif | |
| 340 } | |
| 341 | |
| 342 | |
| 343 gfx::NativeWindow PanelBrowserView::GetNativePanelHandle() { | |
| 344 return GetNativeWindow(); | |
| 345 } | |
| 346 | |
| 347 void PanelBrowserView::UpdatePanelTitleBar() { | |
| 348 UpdateTitleBar(); | |
| 349 } | |
| 350 | |
| 351 void PanelBrowserView::UpdatePanelLoadingAnimations(bool should_animate) { | |
| 352 UpdateLoadingAnimations(should_animate); | |
| 353 } | |
| 354 | |
| 355 void PanelBrowserView::ShowTaskManagerForPanel() { | |
| 356 ShowTaskManager(); | |
| 357 } | |
| 358 | |
| 359 FindBar* PanelBrowserView::CreatePanelFindBar() { | |
| 360 return CreateFindBar(); | |
| 361 } | |
| 362 | |
| 363 void PanelBrowserView::NotifyPanelOnUserChangedTheme() { | |
| 364 UserChangedTheme(); | |
| 365 } | |
| 366 | |
| 367 void PanelBrowserView::PanelWebContentsFocused(WebContents* contents) { | |
| 368 WebContentsFocused(contents); | |
| 369 } | |
| 370 | |
| 371 void PanelBrowserView::PanelCut() { | |
| 372 Cut(); | |
| 373 } | |
| 374 | |
| 375 void PanelBrowserView::PanelCopy() { | |
| 376 Copy(); | |
| 377 } | |
| 378 | |
| 379 void PanelBrowserView::PanelPaste() { | |
| 380 Paste(); | |
| 381 } | |
| 382 | |
| 383 void PanelBrowserView::DrawAttention(bool draw_attention) { | |
| 384 DCHECK((panel_->attention_mode() & Panel::USE_PANEL_ATTENTION) != 0); | |
| 385 | |
| 386 if (is_drawing_attention_ == draw_attention) | |
| 387 return; | |
| 388 is_drawing_attention_ = draw_attention; | |
| 389 GetFrameView()->SchedulePaint(); | |
| 390 | |
| 391 if ((panel_->attention_mode() & Panel::USE_SYSTEM_ATTENTION) != 0) | |
| 392 ::BrowserView::FlashFrame(draw_attention); | |
| 393 } | |
| 394 | |
| 395 bool PanelBrowserView::IsDrawingAttention() const { | |
| 396 return is_drawing_attention_; | |
| 397 } | |
| 398 | |
| 399 bool PanelBrowserView::PreHandlePanelKeyboardEvent( | |
| 400 const NativeWebKeyboardEvent& event, | |
| 401 bool* is_keyboard_shortcut) { | |
| 402 return PreHandleKeyboardEvent(event, is_keyboard_shortcut); | |
| 403 } | |
| 404 | |
| 405 void PanelBrowserView::FullScreenModeChanged(bool is_full_screen) { | |
| 406 if (is_full_screen) { | |
| 407 if (frame()->IsVisible()) { | |
| 408 frame()->Hide(); | |
| 409 } | |
| 410 } else { | |
| 411 ShowInactive(); | |
| 412 } | |
| 413 } | |
| 414 | |
| 415 void PanelBrowserView::HandlePanelKeyboardEvent( | |
| 416 const NativeWebKeyboardEvent& event) { | |
| 417 HandleKeyboardEvent(event); | |
| 418 } | |
| 419 | |
| 420 gfx::Size PanelBrowserView::WindowSizeFromContentSize( | |
| 421 const gfx::Size& content_size) const { | |
| 422 gfx::Size frame = GetFrameView()->NonClientAreaSize(); | |
| 423 return gfx::Size(content_size.width() + frame.width(), | |
| 424 content_size.height() + frame.height()); | |
| 425 } | |
| 426 | |
| 427 gfx::Size PanelBrowserView::ContentSizeFromWindowSize( | |
| 428 const gfx::Size& window_size) const { | |
| 429 gfx::Size frame = GetFrameView()->NonClientAreaSize(); | |
| 430 return gfx::Size(window_size.width() - frame.width(), | |
| 431 window_size.height() - frame.height()); | |
| 432 } | |
| 433 | |
| 434 int PanelBrowserView::TitleOnlyHeight() const { | |
| 435 return GetFrameView()->NonClientTopBorderHeight(); | |
| 436 } | |
| 437 | |
| 438 Browser* PanelBrowserView::GetPanelBrowser() const { | |
| 439 return browser(); | |
| 440 } | |
| 441 | |
| 442 void PanelBrowserView::DestroyPanelBrowser() { | |
| 443 DestroyBrowser(); | |
| 444 } | |
| 445 | |
| 446 void PanelBrowserView::EnsurePanelFullyVisible() { | |
| 447 #if defined(OS_WIN) && !defined(USE_AURA) | |
| 448 ::SetWindowPos(GetNativeWindow(), HWND_TOP, 0, 0, 0, 0, | |
| 449 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); | |
| 450 #else | |
| 451 NOTIMPLEMENTED(); | |
| 452 #endif | |
| 453 } | |
| 454 | |
| 455 PanelBrowserFrameView* PanelBrowserView::GetFrameView() const { | |
| 456 return static_cast<PanelBrowserFrameView*>(frame()->GetFrameView()); | |
| 457 } | |
| 458 | |
| 459 bool PanelBrowserView::OnTitlebarMousePressed( | |
| 460 const gfx::Point& mouse_location) { | |
| 461 mouse_pressed_ = true; | |
| 462 mouse_dragging_state_ = NO_DRAGGING; | |
| 463 last_mouse_location_ = mouse_location; | |
| 464 return true; | |
| 465 } | |
| 466 | |
| 467 bool PanelBrowserView::OnTitlebarMouseDragged( | |
| 468 const gfx::Point& mouse_location) { | |
| 469 if (!mouse_pressed_) | |
| 470 return false; | |
| 471 | |
| 472 int delta_x = mouse_location.x() - last_mouse_location_.x(); | |
| 473 int delta_y = mouse_location.y() - last_mouse_location_.y(); | |
| 474 if (mouse_dragging_state_ == NO_DRAGGING && | |
| 475 ExceededDragThreshold(delta_x, delta_y)) { | |
| 476 // When a drag begins, we do not want to the client area to still receive | |
| 477 // the focus. We do not need to do this for the unfocused minimized panel. | |
| 478 if (!panel_->IsMinimized()) { | |
| 479 old_focused_view_ = GetFocusManager()->GetFocusedView(); | |
| 480 GetFocusManager()->SetFocusedView(GetFrameView()); | |
| 481 } | |
| 482 | |
| 483 panel_->manager()->StartDragging(panel_.get(), last_mouse_location_); | |
| 484 mouse_dragging_state_ = DRAGGING_STARTED; | |
| 485 } | |
| 486 if (mouse_dragging_state_ == DRAGGING_STARTED) { | |
| 487 panel_->manager()->Drag(mouse_location); | |
| 488 | |
| 489 // Once in drag, update |last_mouse_location_| on each drag fragment, since | |
| 490 // we already dragged the panel up to the current mouse location. | |
| 491 last_mouse_location_ = mouse_location; | |
| 492 } | |
| 493 return true; | |
| 494 } | |
| 495 | |
| 496 bool PanelBrowserView::OnTitlebarMouseReleased(panel::ClickModifier modifier) { | |
| 497 if (mouse_dragging_state_ != NO_DRAGGING) { | |
| 498 // Ensure dragging a minimized panel does not leave it activated. | |
| 499 // Windows activates a panel on mouse-down, regardless of our attempts | |
| 500 // to prevent activation of a minimized panel. Now that we know mouse-down | |
| 501 // resulted in a mouse-drag, we need to ensure the minimized panel is | |
| 502 // deactivated. | |
| 503 if (panel_->IsMinimized() && panel_->IsActive()) | |
| 504 panel_->Deactivate(); | |
| 505 | |
| 506 if (mouse_dragging_state_ == DRAGGING_STARTED) { | |
| 507 // When a drag ends, restore the focus. | |
| 508 if (old_focused_view_) { | |
| 509 GetFocusManager()->SetFocusedView(old_focused_view_); | |
| 510 old_focused_view_ = NULL; | |
| 511 } | |
| 512 return EndDragging(false); | |
| 513 } | |
| 514 | |
| 515 // Else, the panel drag was cancelled before the mouse is released. Do not | |
| 516 // treat this as a click. | |
| 517 if (mouse_dragging_state_ != NO_DRAGGING) | |
| 518 return true; | |
| 519 } | |
| 520 | |
| 521 panel_->OnTitlebarClicked(modifier); | |
| 522 return true; | |
| 523 } | |
| 524 | |
| 525 bool PanelBrowserView::OnTitlebarMouseCaptureLost() { | |
| 526 if (mouse_dragging_state_ == DRAGGING_STARTED) | |
| 527 return EndDragging(true); | |
| 528 return true; | |
| 529 } | |
| 530 | |
| 531 bool PanelBrowserView::EndDragging(bool cancelled) { | |
| 532 // Only handle clicks that started in our window. | |
| 533 if (!mouse_pressed_) | |
| 534 return false; | |
| 535 mouse_pressed_ = false; | |
| 536 | |
| 537 mouse_dragging_state_ = DRAGGING_ENDED; | |
| 538 panel_->manager()->EndDragging(cancelled); | |
| 539 return true; | |
| 540 } | |
| 541 | |
| 542 void PanelBrowserView::SetPanelAlwaysOnTop(bool on_top) { | |
| 543 GetWidget()->SetAlwaysOnTop(on_top); | |
| 544 GetWidget()->non_client_view()->Layout(); | |
| 545 GetWidget()->client_view()->Layout(); | |
| 546 } | |
| 547 | |
| 548 bool PanelBrowserView::IsAnimatingBounds() const { | |
| 549 return bounds_animator_.get() && bounds_animator_->is_animating(); | |
| 550 } | |
| 551 | |
| 552 void PanelBrowserView::EnableResizeByMouse(bool enable) { | |
| 553 } | |
| 554 | |
| 555 void PanelBrowserView::UpdatePanelMinimizeRestoreButtonVisibility() { | |
| 556 GetFrameView()->UpdateTitleBarMinimizeRestoreButtonVisibility(); | |
| 557 } | |
| 558 | |
| 559 #if defined(OS_WIN) && !defined(USE_AURA) | |
| 560 void PanelBrowserView::UpdateWindowAttribute(int attribute_index, | |
| 561 int attribute_value, | |
| 562 bool to_set) { | |
| 563 gfx::NativeWindow native_window = GetNativePanelHandle(); | |
| 564 int value = ::GetWindowLong(native_window, attribute_index); | |
| 565 int expected_value; | |
| 566 if (to_set) | |
| 567 expected_value = value | attribute_value; | |
| 568 else | |
| 569 expected_value = value & ~attribute_value; | |
| 570 if (value != expected_value) | |
| 571 ::SetWindowLong(native_window, attribute_index, expected_value); | |
| 572 } | |
| 573 #endif | |
| 574 | |
| 575 void PanelBrowserView::PanelExpansionStateChanging( | |
| 576 Panel::ExpansionState old_state, Panel::ExpansionState new_state) { | |
| 577 #if defined(OS_WIN) && !defined(USE_ASH) && !defined(USE_AURA) | |
| 578 // Live preview is only available since Windows 7. | |
| 579 if (base::win::GetVersion() < base::win::VERSION_WIN7) | |
| 580 return; | |
| 581 | |
| 582 bool is_minimized = old_state != Panel::EXPANDED; | |
| 583 bool will_be_minimized = new_state != Panel::EXPANDED; | |
| 584 if (is_minimized == will_be_minimized) | |
| 585 return; | |
| 586 | |
| 587 HWND native_window = GetNativeWindow(); | |
| 588 | |
| 589 if (!thumbnailer_.get()) { | |
| 590 DCHECK(native_window); | |
| 591 thumbnailer_.reset(new TaskbarWindowThumbnailerWin(native_window)); | |
| 592 ui::HWNDSubclass::AddFilterToTarget(native_window, thumbnailer_.get()); | |
| 593 } | |
| 594 | |
| 595 // Cache the image at this point. | |
| 596 if (will_be_minimized) { | |
| 597 // If the panel is still active (we will deactivate the minimizd panel at | |
| 598 // later time), we need to paint it immediately as inactive so that we can | |
| 599 // take a snapshot of inactive panel. | |
| 600 if (focused_) { | |
| 601 force_to_paint_as_inactive_ = true; | |
| 602 ::RedrawWindow(native_window, NULL, NULL, | |
| 603 RDW_NOCHILDREN | RDW_INVALIDATE | RDW_UPDATENOW); | |
| 604 } | |
| 605 | |
| 606 thumbnailer_->Start(); | |
| 607 } else { | |
| 608 force_to_paint_as_inactive_ = false; | |
| 609 thumbnailer_->Stop(); | |
| 610 } | |
| 611 | |
| 612 #endif | |
| 613 } | |
| 614 | |
| 615 // NativePanelTesting implementation. | |
| 616 class NativePanelTestingWin : public NativePanelTesting { | |
| 617 public: | |
| 618 explicit NativePanelTestingWin(PanelBrowserView* panel_browser_view); | |
| 619 | |
| 620 private: | |
| 621 virtual void PressLeftMouseButtonTitlebar( | |
| 622 const gfx::Point& mouse_location, panel::ClickModifier modifier) OVERRIDE; | |
| 623 virtual void ReleaseMouseButtonTitlebar( | |
| 624 panel::ClickModifier modifier) OVERRIDE; | |
| 625 virtual void DragTitlebar(const gfx::Point& mouse_location) OVERRIDE; | |
| 626 virtual void CancelDragTitlebar() OVERRIDE; | |
| 627 virtual void FinishDragTitlebar() OVERRIDE; | |
| 628 virtual bool VerifyDrawingAttention() const OVERRIDE; | |
| 629 virtual bool VerifyActiveState(bool is_active) OVERRIDE; | |
| 630 virtual bool IsWindowSizeKnown() const OVERRIDE; | |
| 631 virtual bool IsAnimatingBounds() const OVERRIDE; | |
| 632 virtual bool IsButtonVisible( | |
| 633 panel::TitlebarButtonType button_type) const OVERRIDE; | |
| 634 | |
| 635 PanelBrowserView* panel_browser_view_; | |
| 636 }; | |
| 637 | |
| 638 NativePanelTesting* PanelBrowserView::CreateNativePanelTesting() { | |
| 639 return new NativePanelTestingWin(this); | |
| 640 } | |
| 641 | |
| 642 NativePanelTestingWin::NativePanelTestingWin( | |
| 643 PanelBrowserView* panel_browser_view) : | |
| 644 panel_browser_view_(panel_browser_view) { | |
| 645 PanelBrowserFrameView* frame_view = panel_browser_view_->GetFrameView(); | |
| 646 frame_view->title_label_->SetAutoColorReadabilityEnabled(false); | |
| 647 } | |
| 648 | |
| 649 void NativePanelTestingWin::PressLeftMouseButtonTitlebar( | |
| 650 const gfx::Point& mouse_location, panel::ClickModifier modifier) { | |
| 651 panel_browser_view_->OnTitlebarMousePressed(mouse_location); | |
| 652 } | |
| 653 | |
| 654 void NativePanelTestingWin::ReleaseMouseButtonTitlebar( | |
| 655 panel::ClickModifier modifier) { | |
| 656 panel_browser_view_->OnTitlebarMouseReleased(modifier); | |
| 657 } | |
| 658 | |
| 659 void NativePanelTestingWin::DragTitlebar(const gfx::Point& mouse_location) { | |
| 660 panel_browser_view_->OnTitlebarMouseDragged(mouse_location); | |
| 661 } | |
| 662 | |
| 663 void NativePanelTestingWin::CancelDragTitlebar() { | |
| 664 panel_browser_view_->OnTitlebarMouseCaptureLost(); | |
| 665 } | |
| 666 | |
| 667 void NativePanelTestingWin::FinishDragTitlebar() { | |
| 668 panel_browser_view_->OnTitlebarMouseReleased(panel::NO_MODIFIER); | |
| 669 } | |
| 670 | |
| 671 bool NativePanelTestingWin::VerifyDrawingAttention() const { | |
| 672 return panel_browser_view_->GetFrameView()->paint_state_ == | |
| 673 PanelBrowserFrameView::PAINT_FOR_ATTENTION; | |
| 674 } | |
| 675 | |
| 676 bool NativePanelTestingWin::VerifyActiveState(bool is_active) { | |
| 677 return panel_browser_view_->GetFrameView()->paint_state_ == | |
| 678 (is_active ? PanelBrowserFrameView::PAINT_AS_ACTIVE | |
| 679 : PanelBrowserFrameView::PAINT_AS_INACTIVE); | |
| 680 } | |
| 681 | |
| 682 bool NativePanelTestingWin::IsWindowSizeKnown() const { | |
| 683 return true; | |
| 684 } | |
| 685 | |
| 686 bool NativePanelTestingWin::IsAnimatingBounds() const { | |
| 687 return panel_browser_view_->IsAnimatingBounds(); | |
| 688 } | |
| 689 | |
| 690 bool NativePanelTestingWin::IsButtonVisible( | |
| 691 panel::TitlebarButtonType button_type) const { | |
| 692 PanelBrowserFrameView* frame_view = panel_browser_view_->GetFrameView(); | |
| 693 | |
| 694 switch (button_type) { | |
| 695 case panel::CLOSE_BUTTON: | |
| 696 return frame_view->close_button_->visible(); | |
| 697 case panel::MINIMIZE_BUTTON: | |
| 698 return frame_view->minimize_button_->visible(); | |
| 699 case panel::RESTORE_BUTTON: | |
| 700 return frame_view->restore_button_->visible(); | |
| 701 default: | |
| 702 NOTREACHED(); | |
| 703 } | |
| 704 return false; | |
| 705 } | |
| OLD | NEW |