1 // Copyright (c) 2013 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 #ifndef CHROME_BROWSER_UI_VIEWS_PANELS_PANEL_STACK_VIEW_H_ 6 #define CHROME_BROWSER_UI_VIEWS_PANELS_PANEL_STACK_VIEW_H_ 7 8 #include <list> 9 #include <map> 10 #include "base/basictypes.h" 11 #include "base/memory/scoped_ptr.h" 12 #include "chrome/browser/ui/panels/native_panel_stack_window.h" 13 #include "ui/gfx/animation/animation_delegate.h" 14 #include "ui/views/focus/widget_focus_manager.h" 15 #include "ui/views/widget/widget_delegate.h" 16 #include "ui/views/widget/widget_observer.h" 17 18 #if defined(OS_WIN) 19 #include "chrome/browser/ui/views/panels/taskbar_window_thumbnailer_win.h" 20 #include "ui/base/win/hwnd_subclass.h" 21 #endif 22 23 namespace gfx { 24 class LinearAnimation; 25 } 26 namespace views { 27 class Widget; 28 } 29 30 // A native window that acts as the owner of all panels in the stack, in order 31 // to make all panels appear as a single window on the taskbar or launcher. 32 class PanelStackView : public NativePanelStackWindow, 33 public views::WidgetFocusChangeListener, 34 #if defined(OS_WIN) 35 public ui::HWNDMessageFilter, 36 public TaskbarWindowThumbnailerDelegateWin, 37 #endif 38 public gfx::AnimationDelegate { 39 public: 40 explicit PanelStackView(NativePanelStackWindowDelegate* delegate); 41 virtual ~PanelStackView(); 42 43 protected: 44 // Overridden from NativePanelStackWindow: 45 virtual void Close() OVERRIDE; 46 virtual void AddPanel(Panel* panel) OVERRIDE; 47 virtual void RemovePanel(Panel* panel) OVERRIDE; 48 virtual void MergeWith(NativePanelStackWindow* another) OVERRIDE; 49 virtual bool IsEmpty() const OVERRIDE; 50 virtual bool HasPanel(Panel* panel) const OVERRIDE; 51 virtual void MovePanelsBy(const gfx::Vector2d& delta) OVERRIDE; 52 virtual void BeginBatchUpdatePanelBounds(bool animate) OVERRIDE; 53 virtual void AddPanelBoundsForBatchUpdate( 54 Panel* panel, const gfx::Rect& new_bounds) OVERRIDE; 55 virtual void EndBatchUpdatePanelBounds() OVERRIDE; 56 virtual bool IsAnimatingPanelBounds() const OVERRIDE; 57 virtual void Minimize() OVERRIDE; 58 virtual bool IsMinimized() const OVERRIDE; 59 virtual void DrawSystemAttention(bool draw_attention) OVERRIDE; 60 virtual void OnPanelActivated(Panel* panel) OVERRIDE; 61 62 private: 63 typedef std::list<Panel*> Panels; 64 65 // The map value is old bounds of the panel. 66 typedef std::map<Panel*, gfx::Rect> BoundsUpdates; 67 68 // Overridden from views::WidgetFocusChangeListener: 69 virtual void OnNativeFocusChange(gfx::NativeView focused_before, 70 gfx::NativeView focused_now) OVERRIDE; 71 72 // Overridden from AnimationDelegate: 73 virtual void AnimationEnded(const gfx::Animation* animation) OVERRIDE; 74 virtual void AnimationProgressed(const gfx::Animation* animation) OVERRIDE; 75 virtual void AnimationCanceled(const gfx::Animation* animation) OVERRIDE; 76 77 // Updates the bounds of panels as specified in batch update data. 78 void UpdatePanelsBounds(); 79 80 // Notifies the delegate that the updates of the panel bounds are completed. 81 void NotifyBoundsUpdateCompleted(); 82 83 // Computes/updates the minimum bounds that could fit all panels. 84 gfx::Rect GetStackWindowBounds() const; 85 void UpdateStackWindowBounds(); 86 87 views::Widget* CreateWindowWithBounds(const gfx::Rect& bounds); 88 void EnsureWindowCreated(); 89 90 // Makes the stack window own the panel window such that multiple panels 91 // stacked together could appear as a single window on the taskbar or 92 // launcher. 93 static void MakeStackWindowOwnPanelWindow(Panel* panel, 94 PanelStackView* stack_window); 95 96 #if defined(OS_WIN) 97 // Overridden from ui::HWNDMessageFilter: 98 virtual bool FilterMessage(HWND hwnd, 99 UINT message, 100 WPARAM w_param, 101 LPARAM l_param, 102 LRESULT* l_result) OVERRIDE; 103 104 // Overridden from TaskbarWindowThumbnailerDelegateWin: 105 virtual std::vector<HWND> GetSnapshotWindowHandles() const OVERRIDE; 106 107 // Updates the live preview snapshot when something changes, like 108 // adding/removing/moving/resizing a stacked panel. 109 void RefreshLivePreviewThumbnail(); 110 111 // Updates the bounds of the widget window in a deferred way. 112 void DeferUpdateNativeWindowBounds(HDWP defer_window_pos_info, 113 views::Widget* window, 114 const gfx::Rect& bounds); 115 #endif 116 117 NativePanelStackWindowDelegate* delegate_; 118 119 views::Widget* window_; // Weak pointer, own us. 120 121 // Tracks all panels that are enclosed by this window. 122 Panels panels_; 123 124 // Is the taskbar icon of the underlying window being flashed in order to 125 // draw the user's attention? 126 bool is_drawing_attention_; 127 128 #if defined(OS_WIN) 129 // The custom live preview snapshot is always provided for the stack window. 130 // This is because the system might not show the snapshot correctly for 131 // a small window, like collapsed panel. 132 scoped_ptr<TaskbarWindowThumbnailerWin> thumbnailer_; 133 #endif 134 135 // For batch bounds update. 136 bool animate_bounds_updates_; 137 bool bounds_updates_started_; 138 BoundsUpdates bounds_updates_; 139 140 // Used to animate the bounds changes at a synchronized pace. 141 scoped_ptr<gfx::LinearAnimation> bounds_animator_; 142 143 DISALLOW_COPY_AND_ASSIGN(PanelStackView); 144 }; 145 146 #endif // CHROME_BROWSER_UI_VIEWS_PANELS_PANEL_STACK_VIEW_H_ 147