OLD | NEW |
(Empty) | |
| 1 // Copyright 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 #include "ash/wm/caption_buttons/hideable_caption_button_container.h" |
| 6 |
| 7 #include "ash/wm/caption_buttons/frame_caption_button_container_view.h" |
| 8 #include "base/i18n/rtl.h" |
| 9 #include "grit/ash_resources.h" |
| 10 #include "ui/aura/window.h" |
| 11 #include "ui/base/resource/resource_bundle.h" |
| 12 #include "ui/gfx/canvas.h" |
| 13 #include "ui/gfx/image/image.h" |
| 14 #include "ui/gfx/rect.h" |
| 15 #include "ui/views/background.h" |
| 16 #include "ui/views/border.h" |
| 17 #include "ui/views/widget/widget.h" |
| 18 |
| 19 namespace ash { |
| 20 |
| 21 namespace { |
| 22 |
| 23 // The size of the shadow around the caption buttons. The size is based on |
| 24 // IDR_AURA_WINDOW_FULLSCREEN_SHADOW. |
| 25 const int kShadowSizeX = 16; |
| 26 const int kShadowSizeBottom = 21; |
| 27 |
| 28 // The border for |button_widget_|. |
| 29 class HideableCaptionButtonContainerBorder : public views::Border { |
| 30 public: |
| 31 HideableCaptionButtonContainerBorder() { |
| 32 int border_id = base::i18n::IsRTL() ? |
| 33 IDR_AURA_WINDOW_FULLSCREEN_SHADOW_RTL : |
| 34 IDR_AURA_WINDOW_FULLSCREEN_SHADOW; |
| 35 border_ = ui::ResourceBundle::GetSharedInstance().GetImageNamed( |
| 36 border_id).AsImageSkia(); |
| 37 } |
| 38 |
| 39 virtual ~HideableCaptionButtonContainerBorder() { |
| 40 } |
| 41 |
| 42 private: |
| 43 // views::Border overrides: |
| 44 virtual void Paint(const views::View& view, gfx::Canvas* canvas) OVERRIDE { |
| 45 canvas->DrawImageInt(border_, 0, view.height() - border_.height()); |
| 46 } |
| 47 |
| 48 virtual gfx::Insets GetInsets() const OVERRIDE { |
| 49 return gfx::Insets(0, kShadowSizeX, kShadowSizeBottom, 0); |
| 50 } |
| 51 |
| 52 gfx::ImageSkia border_; |
| 53 |
| 54 DISALLOW_COPY_AND_ASSIGN(HideableCaptionButtonContainerBorder); |
| 55 }; |
| 56 |
| 57 // The background for |button_widget_|. |
| 58 class HideableCaptionButtonContainerBackground : public views::Background { |
| 59 public: |
| 60 explicit HideableCaptionButtonContainerBackground(int background_id) { |
| 61 background_ = ui::ResourceBundle::GetSharedInstance().GetImageNamed( |
| 62 background_id).AsImageSkia(); |
| 63 } |
| 64 |
| 65 virtual ~HideableCaptionButtonContainerBackground() { |
| 66 } |
| 67 |
| 68 private: |
| 69 // views::Background override: |
| 70 virtual void Paint(gfx::Canvas* canvas, views::View* view) const OVERRIDE { |
| 71 gfx::Rect paint_bounds(view->GetContentsBounds()); |
| 72 paint_bounds.set_x(view->GetMirroredXForRect(paint_bounds)); |
| 73 canvas->TileImageInt(background_, paint_bounds.x(), paint_bounds.y(), |
| 74 paint_bounds.width(), paint_bounds.height()); |
| 75 } |
| 76 |
| 77 gfx::ImageSkia background_; |
| 78 |
| 79 DISALLOW_COPY_AND_ASSIGN(HideableCaptionButtonContainerBackground); |
| 80 }; |
| 81 |
| 82 } // namespace |
| 83 |
| 84 // static |
| 85 const char HideableCaptionButtonContainer::kButtonWindowName[] = |
| 86 "HideableCaptionButtonContainerWidget"; |
| 87 |
| 88 HideableCaptionButtonContainer::HideableCaptionButtonContainer( |
| 89 int background_id, |
| 90 views::Widget* frame) |
| 91 : background_id_(background_id), |
| 92 frame_(frame) { |
| 93 } |
| 94 |
| 95 HideableCaptionButtonContainer::~HideableCaptionButtonContainer() { |
| 96 frame_->RemoveObserver(this); |
| 97 } |
| 98 |
| 99 void HideableCaptionButtonContainer::ShowButtonWidget() { |
| 100 DCHECK(frame_->IsMaximized()); |
| 101 |
| 102 // Create view with the caption buttons and a widget to host it. |
| 103 // |
| 104 // Unfortunately, there is no views::WidgetDelegate::CanMinimize(). Assume |
| 105 // that the |frame_| can be minimized because it can be maximized. |
| 106 button_container_ = new FrameCaptionButtonContainerView(frame_, |
| 107 ash::FrameCaptionButtonContainerView::MINIMIZE_ALLOWED); |
| 108 button_container_->set_header_style( |
| 109 ash::FrameCaptionButtonContainerView::HEADER_STYLE_MAXIMIZED_HOSTED_APP); |
| 110 button_container_->set_border(new HideableCaptionButtonContainerBorder()); |
| 111 button_container_->set_background( |
| 112 new HideableCaptionButtonContainerBackground(background_id_)); |
| 113 |
| 114 button_widget_.reset(new views::Widget); |
| 115 views::Widget::InitParams params(views::Widget::InitParams::TYPE_CONTROL); |
| 116 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; |
| 117 params.parent = frame_->GetNativeWindow(); |
| 118 params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; |
| 119 button_widget_->Init(params); |
| 120 button_widget_->SetContentsView(button_container_); |
| 121 button_widget_->GetNativeWindow()->SetName(kButtonWindowName); |
| 122 |
| 123 // The shadow border needs to be excluded from the hit test area. |
| 124 gfx::Insets hit_test_insets(button_container_->GetInsets()); |
| 125 if (base::i18n::IsRTL()) { |
| 126 hit_test_insets = gfx::Insets(hit_test_insets.top(), |
| 127 hit_test_insets.right(), |
| 128 hit_test_insets.bottom(), |
| 129 hit_test_insets.left()); |
| 130 } |
| 131 button_widget_->GetNativeWindow()->SetHitTestBoundsOverrideOuter( |
| 132 hit_test_insets, hit_test_insets); |
| 133 |
| 134 button_widget_->SetBounds(GetButtonWidgetBounds()); |
| 135 button_widget_->Show(); |
| 136 |
| 137 frame_->AddObserver(this); |
| 138 } |
| 139 |
| 140 gfx::Rect HideableCaptionButtonContainer::GetButtonWidgetBounds() const { |
| 141 gfx::Size size(button_container_->GetPreferredSize()); |
| 142 gfx::Rect frame_bounds(frame_->GetNativeWindow()->bounds()); |
| 143 int x = base::i18n::IsRTL() ? 0 : frame_bounds.width() - size.width(); |
| 144 return gfx::Rect(x, 0, size.width(), size.height()); |
| 145 } |
| 146 |
| 147 void HideableCaptionButtonContainer::OnWidgetBoundsChanged( |
| 148 views::Widget* widget, |
| 149 const gfx::Rect& new_bounds) { |
| 150 DCHECK_EQ(frame_, widget); |
| 151 button_widget_->SetBounds(GetButtonWidgetBounds()); |
| 152 } |
| 153 |
| 154 } // namespace ash |
OLD | NEW |