Chromium Code Reviews| Index: ash/wm/panel_layout_manager.cc |
| diff --git a/ash/wm/panel_layout_manager.cc b/ash/wm/panel_layout_manager.cc |
| index 4080a4e044312ff1feb57b64ccb6d16bf3436a21..1dd770173870e38af7dec1f10742a1e4b59c0590 100644 |
| --- a/ash/wm/panel_layout_manager.cc |
| +++ b/ash/wm/panel_layout_manager.cc |
| @@ -10,14 +10,22 @@ |
| #include "ash/shell.h" |
| #include "ash/wm/property_util.h" |
| #include "base/auto_reset.h" |
| +#include "third_party/skia/include/core/SkCanvas.h" |
| +#include "third_party/skia/include/core/SkColor.h" |
| +#include "third_party/skia/include/core/SkPaint.h" |
| +#include "third_party/skia/include/core/SkPath.h" |
| #include "ui/aura/client/activation_client.h" |
| #include "ui/aura/client/aura_constants.h" |
| #include "ui/aura/root_window.h" |
| #include "ui/aura/window.h" |
| +#include "ui/gfx/canvas.h" |
| #include "ui/gfx/rect.h" |
| -#include "ui/gfx/size.h" |
| +#include "ui/views/background.h" |
| #include "ui/views/widget/widget.h" |
| +namespace ash { |
| +namespace internal { |
| + |
| namespace { |
| const int kPanelMarginEdge = 4; |
| const int kPanelMarginMiddle = 8; |
| @@ -26,10 +34,38 @@ const int kMinimizedHeight = 24; |
| const float kMaxHeightFactor = .80f; |
| const float kMaxWidthFactor = .50f; |
| -} |
| -namespace ash { |
| -namespace internal { |
| +// Callout arrow dimensions. |
| +const int kArrowWidth = 20; |
| +const int kArrowHeight = 10; |
| + |
| +class CalloutWidgetBackground : public views::Background{ |
|
sky
2012/04/26 15:41:16
nit: space after Background
dcheng
2012/04/27 01:11:35
Done.
|
| + public: |
| + CalloutWidgetBackground() {} |
| + virtual void Paint(gfx::Canvas* canvas, views::View* view) const OVERRIDE { |
| + SkPath path; |
| + // TODO(dcheng): Verify if this results in off by one errors. |
| + path.moveTo(SkIntToScalar(0), SkIntToScalar(0)); |
| + path.lineTo(SkIntToScalar(kArrowWidth / 2), SkIntToScalar(kArrowHeight)); |
| + path.lineTo(SkIntToScalar(kArrowWidth), SkIntToScalar(0)); |
| + |
| + // TODO(dcheng): get real colors, and port this over to use gfx::Canvas |
| + // instead. |
| + SkPaint paint; |
| + paint.setStyle(SkPaint::kFill_Style); |
| + paint.setColor(SK_ColorBLUE); |
| + canvas->sk_canvas()->drawPath(path, paint); |
| + |
| + paint.setStyle(SkPaint::kStroke_Style); |
| + paint.setColor(SK_ColorRED); |
| + canvas->sk_canvas()->drawPath(path, paint); |
| + } |
| + |
| + private: |
| + DISALLOW_COPY_AND_ASSIGN(CalloutWidgetBackground); |
| +}; |
| + |
| +} // namespace |
| //////////////////////////////////////////////////////////////////////////////// |
| // PanelLayoutManager public implementation: |
| @@ -38,8 +74,25 @@ PanelLayoutManager::PanelLayoutManager(aura::Window* panel_container) |
| in_layout_(false), |
| dragged_panel_(NULL), |
| launcher_(NULL), |
| - last_active_panel_(NULL) { |
| + last_active_panel_(NULL), |
| + callout_widget_(new views::Widget) { |
| DCHECK(panel_container); |
| + views::Widget::InitParams params; |
| + params.type = views::Widget::InitParams::TYPE_POPUP; |
| + params.transparent = true; |
| + params.can_activate = false; |
| + params.keep_on_top = true; |
| + params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; |
| + params.parent = panel_container_; |
| + params.bounds.set_width(kArrowWidth); |
| + params.bounds.set_height(kArrowHeight); |
| + // Why do we need this and can_activate = false? |
| + callout_widget_->set_focus_on_creation(false); |
| + callout_widget_->Init(params); |
| + views::View* content_view = new views::View; |
| + content_view->set_background(new CalloutWidgetBackground); |
| + callout_widget_->SetContentsView(content_view); |
| + callout_widget_->Show(); |
| Shell::GetRootWindow()->AddObserver(this); |
| } |
| @@ -100,6 +153,8 @@ void PanelLayoutManager::OnWindowResized() { |
| } |
| void PanelLayoutManager::OnWindowAddedToLayout(aura::Window* child) { |
| + if (child == callout_widget_->GetNativeWindow()) |
| + return; |
| panel_windows_.push_back(child); |
| Relayout(); |
| } |
| @@ -174,8 +229,10 @@ void PanelLayoutManager::OnWindowPropertyChanged(aura::Window* window, |
| if (key == aura::client::kRootWindowActiveWindowKey) { |
| aura::Window* active = window->GetProperty( |
| aura::client::kRootWindowActiveWindowKey); |
| - if (active && active->type() == aura::client::WINDOW_TYPE_PANEL) |
| + if (active && active->type() == aura::client::WINDOW_TYPE_PANEL) { |
| UpdateStacking(active); |
| + UpdateCallout(active); |
| + } |
| } |
| } |
| @@ -219,11 +276,15 @@ void PanelLayoutManager::Relayout() { |
| gfx::Rect bounds = panel->bounds(); |
| bounds.set_x( |
| icon_origin.x() + icon_bounds.width() / 2 - bounds.width() / 2); |
| - bounds.set_y(icon_origin.y() - bounds.height()); |
| + // TODO(dcheng): This is just a random constant so panels don't sit right |
| + // on top of the launcher. We should be using the same padding that normal |
| + // windows use. |
| + 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
|
| SetChildBoundsDirect(panel, bounds); |
| } |
| UpdateStacking(active_panel); |
| + 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
|
| } |
| void PanelLayoutManager::UpdateStacking(aura::Window* active_panel) { |
| @@ -270,5 +331,20 @@ void PanelLayoutManager::UpdateStacking(aura::Window* active_panel) { |
| last_active_panel_ = active_panel; |
| } |
| +void PanelLayoutManager::UpdateCallout(aura::Window* active_panel) { |
| + if (!active_panel) { |
| + callout_widget_->Hide(); |
| + return; |
| + } |
| + gfx::Rect bounds = active_panel->GetBoundsInRootWindow(); |
| + gfx::Rect callout_bounds = callout_widget_->GetWindowScreenBounds(); |
| + callout_bounds.set_x( |
| + bounds.x() + (bounds.width() - callout_bounds.width()) / 2); |
| + callout_bounds.set_y(bounds.bottom()); |
| + SetChildBoundsDirect(callout_widget_->GetNativeWindow(), callout_bounds); |
| + callout_widget_->Show(); |
| + 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.
|
| +} |
| + |
| } // namespace internal |
| } // namespace ash |