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

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: Created 8 years, 8 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') | no next file » | 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/property_util.h" 11 #include "ash/wm/property_util.h"
12 #include "base/auto_reset.h" 12 #include "base/auto_reset.h"
13 #include "third_party/skia/include/core/SkCanvas.h"
14 #include "third_party/skia/include/core/SkColor.h"
15 #include "third_party/skia/include/core/SkPaint.h"
16 #include "third_party/skia/include/core/SkPath.h"
13 #include "ui/aura/client/activation_client.h" 17 #include "ui/aura/client/activation_client.h"
14 #include "ui/aura/client/aura_constants.h" 18 #include "ui/aura/client/aura_constants.h"
15 #include "ui/aura/root_window.h" 19 #include "ui/aura/root_window.h"
16 #include "ui/aura/window.h" 20 #include "ui/aura/window.h"
21 #include "ui/gfx/canvas.h"
17 #include "ui/gfx/rect.h" 22 #include "ui/gfx/rect.h"
18 #include "ui/gfx/size.h" 23 #include "ui/views/background.h"
19 #include "ui/views/widget/widget.h" 24 #include "ui/views/widget/widget.h"
20 25
26 namespace ash {
27 namespace internal {
28
21 namespace { 29 namespace {
22 const int kPanelMarginEdge = 4; 30 const int kPanelMarginEdge = 4;
23 const int kPanelMarginMiddle = 8; 31 const int kPanelMarginMiddle = 8;
24 32
25 const int kMinimizedHeight = 24; 33 const int kMinimizedHeight = 24;
26 34
27 const float kMaxHeightFactor = .80f; 35 const float kMaxHeightFactor = .80f;
28 const float kMaxWidthFactor = .50f; 36 const float kMaxWidthFactor = .50f;
29 }
30 37
31 namespace ash { 38 // Callout arrow dimensions.
32 namespace internal { 39 const int kArrowWidth = 20;
40 const int kArrowHeight = 10;
41
42 class CalloutWidgetBackground : public views::Background{
sky 2012/04/26 15:41:16 nit: space after Background
dcheng 2012/04/27 01:11:35 Done.
43 public:
44 CalloutWidgetBackground() {}
45 virtual void Paint(gfx::Canvas* canvas, views::View* view) const OVERRIDE {
46 SkPath path;
47 // TODO(dcheng): Verify if this results in off by one errors.
48 path.moveTo(SkIntToScalar(0), SkIntToScalar(0));
49 path.lineTo(SkIntToScalar(kArrowWidth / 2), SkIntToScalar(kArrowHeight));
50 path.lineTo(SkIntToScalar(kArrowWidth), SkIntToScalar(0));
51
52 // TODO(dcheng): get real colors, and port this over to use gfx::Canvas
53 // instead.
54 SkPaint paint;
55 paint.setStyle(SkPaint::kFill_Style);
56 paint.setColor(SK_ColorBLUE);
57 canvas->sk_canvas()->drawPath(path, paint);
58
59 paint.setStyle(SkPaint::kStroke_Style);
60 paint.setColor(SK_ColorRED);
61 canvas->sk_canvas()->drawPath(path, paint);
62 }
63
64 private:
65 DISALLOW_COPY_AND_ASSIGN(CalloutWidgetBackground);
66 };
67
68 } // namespace
33 69
34 //////////////////////////////////////////////////////////////////////////////// 70 ////////////////////////////////////////////////////////////////////////////////
35 // PanelLayoutManager public implementation: 71 // PanelLayoutManager public implementation:
36 PanelLayoutManager::PanelLayoutManager(aura::Window* panel_container) 72 PanelLayoutManager::PanelLayoutManager(aura::Window* panel_container)
37 : panel_container_(panel_container), 73 : panel_container_(panel_container),
38 in_layout_(false), 74 in_layout_(false),
39 dragged_panel_(NULL), 75 dragged_panel_(NULL),
40 launcher_(NULL), 76 launcher_(NULL),
41 last_active_panel_(NULL) { 77 last_active_panel_(NULL),
78 callout_widget_(new views::Widget) {
42 DCHECK(panel_container); 79 DCHECK(panel_container);
80 views::Widget::InitParams params;
81 params.type = views::Widget::InitParams::TYPE_POPUP;
82 params.transparent = true;
83 params.can_activate = false;
84 params.keep_on_top = true;
85 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
86 params.parent = panel_container_;
87 params.bounds.set_width(kArrowWidth);
88 params.bounds.set_height(kArrowHeight);
89 // Why do we need this and can_activate = false?
90 callout_widget_->set_focus_on_creation(false);
91 callout_widget_->Init(params);
92 views::View* content_view = new views::View;
93 content_view->set_background(new CalloutWidgetBackground);
94 callout_widget_->SetContentsView(content_view);
95 callout_widget_->Show();
43 Shell::GetRootWindow()->AddObserver(this); 96 Shell::GetRootWindow()->AddObserver(this);
44 } 97 }
45 98
46 PanelLayoutManager::~PanelLayoutManager() { 99 PanelLayoutManager::~PanelLayoutManager() {
47 if (launcher_) 100 if (launcher_)
48 launcher_->RemoveIconObserver(this); 101 launcher_->RemoveIconObserver(this);
49 Shell::GetRootWindow()->RemoveObserver(this); 102 Shell::GetRootWindow()->RemoveObserver(this);
50 } 103 }
51 104
52 void PanelLayoutManager::StartDragging(aura::Window* panel) { 105 void PanelLayoutManager::StartDragging(aura::Window* panel) {
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 Relayout(); 146 Relayout();
94 } 147 }
95 148
96 //////////////////////////////////////////////////////////////////////////////// 149 ////////////////////////////////////////////////////////////////////////////////
97 // PanelLayoutManager, aura::LayoutManager implementation: 150 // PanelLayoutManager, aura::LayoutManager implementation:
98 void PanelLayoutManager::OnWindowResized() { 151 void PanelLayoutManager::OnWindowResized() {
99 Relayout(); 152 Relayout();
100 } 153 }
101 154
102 void PanelLayoutManager::OnWindowAddedToLayout(aura::Window* child) { 155 void PanelLayoutManager::OnWindowAddedToLayout(aura::Window* child) {
156 if (child == callout_widget_->GetNativeWindow())
157 return;
103 panel_windows_.push_back(child); 158 panel_windows_.push_back(child);
104 Relayout(); 159 Relayout();
105 } 160 }
106 161
107 void PanelLayoutManager::OnWillRemoveWindowFromLayout(aura::Window* child) { 162 void PanelLayoutManager::OnWillRemoveWindowFromLayout(aura::Window* child) {
108 PanelList::iterator found = 163 PanelList::iterator found =
109 std::find(panel_windows_.begin(), panel_windows_.end(), child); 164 std::find(panel_windows_.begin(), panel_windows_.end(), child);
110 if (found != panel_windows_.end()) 165 if (found != panel_windows_.end())
111 panel_windows_.erase(found); 166 panel_windows_.erase(found);
112 167
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
167 } 222 }
168 223
169 //////////////////////////////////////////////////////////////////////////////// 224 ////////////////////////////////////////////////////////////////////////////////
170 // PanelLayoutManager, aura::WindowObserver implementation: 225 // PanelLayoutManager, aura::WindowObserver implementation:
171 void PanelLayoutManager::OnWindowPropertyChanged(aura::Window* window, 226 void PanelLayoutManager::OnWindowPropertyChanged(aura::Window* window,
172 const void* key, 227 const void* key,
173 intptr_t old) { 228 intptr_t old) {
174 if (key == aura::client::kRootWindowActiveWindowKey) { 229 if (key == aura::client::kRootWindowActiveWindowKey) {
175 aura::Window* active = window->GetProperty( 230 aura::Window* active = window->GetProperty(
176 aura::client::kRootWindowActiveWindowKey); 231 aura::client::kRootWindowActiveWindowKey);
177 if (active && active->type() == aura::client::WINDOW_TYPE_PANEL) 232 if (active && active->type() == aura::client::WINDOW_TYPE_PANEL) {
178 UpdateStacking(active); 233 UpdateStacking(active);
234 UpdateCallout(active);
235 }
179 } 236 }
180 } 237 }
181 238
182 239
183 //////////////////////////////////////////////////////////////////////////////// 240 ////////////////////////////////////////////////////////////////////////////////
184 // PanelLayoutManager private implementation: 241 // PanelLayoutManager private implementation:
185 void PanelLayoutManager::Relayout() { 242 void PanelLayoutManager::Relayout() {
186 if (in_layout_) 243 if (in_layout_)
187 return; 244 return;
188 AutoReset<bool> auto_reset_in_layout(&in_layout_, true); 245 AutoReset<bool> auto_reset_in_layout(&in_layout_, true);
(...skipping 23 matching lines...) Expand all
212 } 269 }
213 270
214 gfx::Point icon_origin = icon_bounds.origin(); 271 gfx::Point icon_origin = icon_bounds.origin();
215 aura::Window::ConvertPointToWindow(panel_container_->GetRootWindow(), 272 aura::Window::ConvertPointToWindow(panel_container_->GetRootWindow(),
216 panel_container_, &icon_origin); 273 panel_container_, &icon_origin);
217 274
218 // TODO(dcheng): Need to clamp to screen edges. 275 // TODO(dcheng): Need to clamp to screen edges.
219 gfx::Rect bounds = panel->bounds(); 276 gfx::Rect bounds = panel->bounds();
220 bounds.set_x( 277 bounds.set_x(
221 icon_origin.x() + icon_bounds.width() / 2 - bounds.width() / 2); 278 icon_origin.x() + icon_bounds.width() / 2 - bounds.width() / 2);
222 bounds.set_y(icon_origin.y() - bounds.height()); 279 // TODO(dcheng): This is just a random constant so panels don't sit right
280 // on top of the launcher. We should be using the same padding that normal
281 // windows use.
282 bounds.set_y(icon_origin.y() - bounds.height() - 10);
sky 2012/04/26 15:41:16 Normal windows can sit flush to the launcher.
dcheng 2012/04/27 01:11:35 Right now, we're lining things up to the top of th
223 SetChildBoundsDirect(panel, bounds); 283 SetChildBoundsDirect(panel, bounds);
224 } 284 }
225 285
226 UpdateStacking(active_panel); 286 UpdateStacking(active_panel);
287 UpdateCallout(active_panel);
sky 2012/04/26 15:41:16 UpdateStacking might use last_active_panel_, does
dcheng 2012/04/27 01:11:35 No, we only want to decorate a panel with the call
227 } 288 }
228 289
229 void PanelLayoutManager::UpdateStacking(aura::Window* active_panel) { 290 void PanelLayoutManager::UpdateStacking(aura::Window* active_panel) {
230 // We want to to stack the panels like a deck of cards: 291 // We want to to stack the panels like a deck of cards:
231 // ,--,--,--,-------.--.--. 292 // ,--,--,--,-------.--.--.
232 // | | | | | | | 293 // | | | | | | |
233 // | | | | | | | 294 // | | | | | | |
234 // 295 //
235 // Since there's no way of extracting a panel ordering from the launcher, 296 // Since there's no way of extracting a panel ordering from the launcher,
236 // we build an ordering based on the x-coordinate of the panel bounds... 297 // we build an ordering based on the x-coordinate of the panel bounds...
(...skipping 26 matching lines...) Expand all
263 it != window_ordering.rend() && it->second != active_panel; ++it) { 324 it != window_ordering.rend() && it->second != active_panel; ++it) {
264 if (previous_panel) 325 if (previous_panel)
265 panel_container_->StackChildAbove(it->second, previous_panel); 326 panel_container_->StackChildAbove(it->second, previous_panel);
266 previous_panel = it->second; 327 previous_panel = it->second;
267 } 328 }
268 329
269 panel_container_->StackChildAtTop(active_panel); 330 panel_container_->StackChildAtTop(active_panel);
270 last_active_panel_ = active_panel; 331 last_active_panel_ = active_panel;
271 } 332 }
272 333
334 void PanelLayoutManager::UpdateCallout(aura::Window* active_panel) {
335 if (!active_panel) {
336 callout_widget_->Hide();
337 return;
338 }
339 gfx::Rect bounds = active_panel->GetBoundsInRootWindow();
340 gfx::Rect callout_bounds = callout_widget_->GetWindowScreenBounds();
341 callout_bounds.set_x(
342 bounds.x() + (bounds.width() - callout_bounds.width()) / 2);
343 callout_bounds.set_y(bounds.bottom());
344 SetChildBoundsDirect(callout_widget_->GetNativeWindow(), callout_bounds);
345 callout_widget_->Show();
346 panel_container_->StackChildAtTop(callout_widget_->GetNativeWindow());
sky 2012/04/26 15:41:16 I would stack at top first, then show.
dcheng 2012/04/27 01:11:35 Done.
347 }
348
273 } // namespace internal 349 } // namespace internal
274 } // namespace ash 350 } // namespace ash
OLDNEW
« no previous file with comments | « ash/wm/panel_layout_manager.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698