Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(615)

Side by Side Diff: ash/wm/panel_layout_manager.cc

Issue 10174037: Implement a callout widget for the active panel. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase? Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « ash/wm/panel_layout_manager.h ('k') | ash/wm/panel_layout_manager_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 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 "ash/wm/panel_layout_manager.h" 5 #include "ash/wm/panel_layout_manager.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "ash/launcher/launcher.h" 9 #include "ash/launcher/launcher.h"
10 #include "ash/shell.h" 10 #include "ash/shell.h"
11 #include "ash/wm/frame_painter.h"
11 #include "ash/wm/property_util.h" 12 #include "ash/wm/property_util.h"
12 #include "base/auto_reset.h" 13 #include "base/auto_reset.h"
14 #include "base/bind.h"
15 #include "base/bind_helpers.h"
16 #include "third_party/skia/include/core/SkColor.h"
17 #include "third_party/skia/include/core/SkPaint.h"
18 #include "third_party/skia/include/core/SkPath.h"
13 #include "ui/aura/client/activation_client.h" 19 #include "ui/aura/client/activation_client.h"
14 #include "ui/aura/client/aura_constants.h" 20 #include "ui/aura/client/aura_constants.h"
15 #include "ui/aura/root_window.h" 21 #include "ui/aura/root_window.h"
16 #include "ui/aura/window.h" 22 #include "ui/aura/window.h"
23 #include "ui/gfx/canvas.h"
17 #include "ui/gfx/rect.h" 24 #include "ui/gfx/rect.h"
18 #include "ui/gfx/size.h" 25 #include "ui/views/background.h"
19 #include "ui/views/widget/widget.h" 26 #include "ui/views/widget/widget.h"
20 27
28 namespace ash {
29 namespace internal {
30
21 namespace { 31 namespace {
22 const int kPanelMarginEdge = 4; 32 const int kPanelMarginEdge = 4;
23 const int kPanelMarginMiddle = 8; 33 const int kPanelMarginMiddle = 8;
24 34
25 const int kMinimizedHeight = 24; 35 const int kMinimizedHeight = 24;
26 36
27 const float kMaxHeightFactor = .80f; 37 const float kMaxHeightFactor = .80f;
28 const float kMaxWidthFactor = .50f; 38 const float kMaxWidthFactor = .50f;
29 }
30 39
31 namespace ash { 40 // Callout arrow dimensions.
32 namespace internal { 41 const int kArrowWidth = 20;
42 const int kArrowHeight = 10;
43
44 class CalloutWidgetBackground : public views::Background {
45 public:
46 CalloutWidgetBackground() {}
47 virtual void Paint(gfx::Canvas* canvas, views::View* view) const OVERRIDE {
48 SkPath path;
49 // TODO(dcheng): Verify if this results in off by one errors.
50 path.moveTo(SkIntToScalar(0), SkIntToScalar(0));
51 path.lineTo(SkIntToScalar(kArrowWidth / 2), SkIntToScalar(kArrowHeight));
52 path.lineTo(SkIntToScalar(kArrowWidth), SkIntToScalar(0));
53
54 // Use the same opacity and colors as the header for now.
55 SkPaint paint;
56 paint.setStyle(SkPaint::kFill_Style);
57 paint.setColor(
58 SkColorSetARGB(FramePainter::kActiveWindowOpacity, 189, 189, 189));
59 canvas->DrawPath(path, paint);
60 }
61
62 private:
63 DISALLOW_COPY_AND_ASSIGN(CalloutWidgetBackground);
64 };
65
66 } // namespace
33 67
34 //////////////////////////////////////////////////////////////////////////////// 68 ////////////////////////////////////////////////////////////////////////////////
35 // PanelLayoutManager public implementation: 69 // PanelLayoutManager public implementation:
36 PanelLayoutManager::PanelLayoutManager(aura::Window* panel_container) 70 PanelLayoutManager::PanelLayoutManager(aura::Window* panel_container)
37 : panel_container_(panel_container), 71 : panel_container_(panel_container),
38 in_layout_(false), 72 in_layout_(false),
39 dragged_panel_(NULL), 73 dragged_panel_(NULL),
40 launcher_(NULL), 74 launcher_(NULL),
41 last_active_panel_(NULL) { 75 last_active_panel_(NULL),
76 callout_widget_(new views::Widget),
77 weak_factory_(this) {
42 DCHECK(panel_container); 78 DCHECK(panel_container);
79 views::Widget::InitParams params;
80 params.type = views::Widget::InitParams::TYPE_POPUP;
81 params.transparent = true;
82 params.can_activate = false;
83 params.keep_on_top = true;
84 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
85 params.parent = panel_container_;
86 params.bounds.set_width(kArrowWidth);
87 params.bounds.set_height(kArrowHeight);
88 // Why do we need this and can_activate = false?
89 callout_widget_->set_focus_on_creation(false);
90 callout_widget_->Init(params);
91 views::View* content_view = new views::View;
92 content_view->set_background(new CalloutWidgetBackground);
93 callout_widget_->SetContentsView(content_view);
43 Shell::GetRootWindow()->AddObserver(this); 94 Shell::GetRootWindow()->AddObserver(this);
44 } 95 }
45 96
46 PanelLayoutManager::~PanelLayoutManager() { 97 PanelLayoutManager::~PanelLayoutManager() {
47 if (launcher_) 98 if (launcher_)
48 launcher_->RemoveIconObserver(this); 99 launcher_->RemoveIconObserver(this);
49 Shell::GetRootWindow()->RemoveObserver(this); 100 Shell::GetRootWindow()->RemoveObserver(this);
50 } 101 }
51 102
52 void PanelLayoutManager::StartDragging(aura::Window* panel) { 103 void PanelLayoutManager::StartDragging(aura::Window* panel) {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
94 Relayout(); 145 Relayout();
95 } 146 }
96 147
97 //////////////////////////////////////////////////////////////////////////////// 148 ////////////////////////////////////////////////////////////////////////////////
98 // PanelLayoutManager, aura::LayoutManager implementation: 149 // PanelLayoutManager, aura::LayoutManager implementation:
99 void PanelLayoutManager::OnWindowResized() { 150 void PanelLayoutManager::OnWindowResized() {
100 Relayout(); 151 Relayout();
101 } 152 }
102 153
103 void PanelLayoutManager::OnWindowAddedToLayout(aura::Window* child) { 154 void PanelLayoutManager::OnWindowAddedToLayout(aura::Window* child) {
155 if (child == callout_widget_->GetNativeWindow())
156 return;
104 panel_windows_.push_back(child); 157 panel_windows_.push_back(child);
105 Relayout(); 158 Relayout();
106 } 159 }
107 160
108 void PanelLayoutManager::OnWillRemoveWindowFromLayout(aura::Window* child) { 161 void PanelLayoutManager::OnWillRemoveWindowFromLayout(aura::Window* child) {
109 PanelList::iterator found = 162 PanelList::iterator found =
110 std::find(panel_windows_.begin(), panel_windows_.end(), child); 163 std::find(panel_windows_.begin(), panel_windows_.end(), child);
111 if (found != panel_windows_.end()) 164 if (found != panel_windows_.end())
112 panel_windows_.erase(found); 165 panel_windows_.erase(found);
113 166
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 } 221 }
169 222
170 //////////////////////////////////////////////////////////////////////////////// 223 ////////////////////////////////////////////////////////////////////////////////
171 // PanelLayoutManager, aura::WindowObserver implementation: 224 // PanelLayoutManager, aura::WindowObserver implementation:
172 void PanelLayoutManager::OnWindowPropertyChanged(aura::Window* window, 225 void PanelLayoutManager::OnWindowPropertyChanged(aura::Window* window,
173 const void* key, 226 const void* key,
174 intptr_t old) { 227 intptr_t old) {
175 if (key == aura::client::kRootWindowActiveWindowKey) { 228 if (key == aura::client::kRootWindowActiveWindowKey) {
176 aura::Window* active = window->GetProperty( 229 aura::Window* active = window->GetProperty(
177 aura::client::kRootWindowActiveWindowKey); 230 aura::client::kRootWindowActiveWindowKey);
178 if (active && active->type() == aura::client::WINDOW_TYPE_PANEL) 231 if (active && active->type() == aura::client::WINDOW_TYPE_PANEL) {
179 UpdateStacking(active); 232 UpdateStacking(active);
233 UpdateCallout(active);
234 } else {
235 UpdateCallout(NULL);
236 }
180 } 237 }
181 } 238 }
182 239
183 240
184 //////////////////////////////////////////////////////////////////////////////// 241 ////////////////////////////////////////////////////////////////////////////////
185 // PanelLayoutManager private implementation: 242 // PanelLayoutManager private implementation:
186 void PanelLayoutManager::Relayout() { 243 void PanelLayoutManager::Relayout() {
187 if (in_layout_) 244 if (in_layout_)
188 return; 245 return;
189 AutoReset<bool> auto_reset_in_layout(&in_layout_, true); 246 AutoReset<bool> auto_reset_in_layout(&in_layout_, true);
190 247
248 int launcher_top = launcher_->widget()->GetWindowScreenBounds().y();
191 aura::Window* active_panel = NULL; 249 aura::Window* active_panel = NULL;
192 for (PanelList::iterator iter = panel_windows_.begin(); 250 for (PanelList::iterator iter = panel_windows_.begin();
193 iter != panel_windows_.end(); ++iter) { 251 iter != panel_windows_.end(); ++iter) {
194 aura::Window* panel = *iter; 252 aura::Window* panel = *iter;
195 if (!panel->IsVisible() || panel == dragged_panel_) 253 if (!panel->IsVisible() || panel == dragged_panel_)
196 continue; 254 continue;
197 255
198 gfx::Rect icon_bounds = 256 gfx::Rect icon_bounds =
199 launcher_->GetScreenBoundsOfItemIconForWindow(panel); 257 launcher_->GetScreenBoundsOfItemIconForWindow(panel);
200 258
(...skipping 10 matching lines...) Expand all
211 } 269 }
212 270
213 gfx::Point icon_origin = icon_bounds.origin(); 271 gfx::Point icon_origin = icon_bounds.origin();
214 aura::Window::ConvertPointToWindow(panel_container_->GetRootWindow(), 272 aura::Window::ConvertPointToWindow(panel_container_->GetRootWindow(),
215 panel_container_, &icon_origin); 273 panel_container_, &icon_origin);
216 274
217 // TODO(dcheng): Need to clamp to screen edges. 275 // TODO(dcheng): Need to clamp to screen edges.
218 gfx::Rect bounds = panel->bounds(); 276 gfx::Rect bounds = panel->bounds();
219 bounds.set_x( 277 bounds.set_x(
220 icon_origin.x() + icon_bounds.width() / 2 - bounds.width() / 2); 278 icon_origin.x() + icon_bounds.width() / 2 - bounds.width() / 2);
221 bounds.set_y(icon_origin.y() - bounds.height()); 279 bounds.set_y(launcher_top - bounds.height());
222 SetChildBoundsDirect(panel, bounds); 280 SetChildBoundsDirect(panel, bounds);
223 } 281 }
224 282
225 UpdateStacking(active_panel); 283 UpdateStacking(active_panel);
284 UpdateCallout(active_panel);
226 } 285 }
227 286
228 void PanelLayoutManager::UpdateStacking(aura::Window* active_panel) { 287 void PanelLayoutManager::UpdateStacking(aura::Window* active_panel) {
229 if (!active_panel) { 288 if (!active_panel) {
230 if (!last_active_panel_) 289 if (!last_active_panel_)
231 return; 290 return;
232 active_panel = last_active_panel_; 291 active_panel = last_active_panel_;
233 } 292 }
234 293
235 // We want to to stack the panels like a deck of cards: 294 // We want to to stack the panels like a deck of cards:
(...skipping 28 matching lines...) Expand all
264 it != window_ordering.rend() && it->second != active_panel; ++it) { 323 it != window_ordering.rend() && it->second != active_panel; ++it) {
265 if (previous_panel) 324 if (previous_panel)
266 panel_container_->StackChildAbove(it->second, previous_panel); 325 panel_container_->StackChildAbove(it->second, previous_panel);
267 previous_panel = it->second; 326 previous_panel = it->second;
268 } 327 }
269 328
270 panel_container_->StackChildAtTop(active_panel); 329 panel_container_->StackChildAtTop(active_panel);
271 last_active_panel_ = active_panel; 330 last_active_panel_ = active_panel;
272 } 331 }
273 332
333 void PanelLayoutManager::UpdateCallout(aura::Window* active_panel) {
334 weak_factory_.InvalidateWeakPtrs();
335 // TODO(dcheng): This doesn't account for panels in overflow. They should have
336 // a callout as well.
337 if (!active_panel ||
338 launcher_->GetScreenBoundsOfItemIconForWindow(active_panel).IsEmpty()) {
339 callout_widget_->Hide();
340 return;
341 }
342 MessageLoop::current()->PostTask(
343 FROM_HERE,
344 base::Bind(&PanelLayoutManager::ShowCalloutHelper,
345 weak_factory_.GetWeakPtr(),
346 active_panel));
347 }
348
349 void PanelLayoutManager::ShowCalloutHelper(aura::Window* active_panel) {
350 DCHECK(active_panel);
351 gfx::Rect bounds = active_panel->GetBoundsInRootWindow();
352 gfx::Rect callout_bounds = callout_widget_->GetWindowScreenBounds();
353 callout_bounds.set_x(
354 bounds.x() + (bounds.width() - callout_bounds.width()) / 2);
355 callout_bounds.set_y(bounds.bottom());
356 SetChildBoundsDirect(callout_widget_->GetNativeWindow(), callout_bounds);
357 panel_container_->StackChildAtTop(callout_widget_->GetNativeWindow());
358 callout_widget_->Show();
359 }
360
274 } // namespace internal 361 } // namespace internal
275 } // namespace ash 362 } // namespace ash
OLDNEW
« no previous file with comments | « ash/wm/panel_layout_manager.h ('k') | ash/wm/panel_layout_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698