| OLD | NEW |
| (Empty) |
| 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 | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "ash/system/tray/tray_details_view.h" | |
| 6 | |
| 7 #include "ash/common/system/tray/fixed_sized_scroll_view.h" | |
| 8 #include "ash/common/system/tray/system_tray_item.h" | |
| 9 #include "ash/common/system/tray/tray_constants.h" | |
| 10 #include "ash/system/tray/system_tray.h" | |
| 11 #include "ui/gfx/canvas.h" | |
| 12 #include "ui/views/background.h" | |
| 13 #include "ui/views/border.h" | |
| 14 #include "ui/views/controls/scroll_view.h" | |
| 15 #include "ui/views/layout/box_layout.h" | |
| 16 | |
| 17 namespace ash { | |
| 18 | |
| 19 class ScrollSeparator : public views::View { | |
| 20 public: | |
| 21 ScrollSeparator() {} | |
| 22 | |
| 23 ~ScrollSeparator() override {} | |
| 24 | |
| 25 private: | |
| 26 // Overriden from views::View. | |
| 27 void OnPaint(gfx::Canvas* canvas) override { | |
| 28 canvas->FillRect(gfx::Rect(0, height() / 2, width(), 1), kBorderLightColor); | |
| 29 } | |
| 30 gfx::Size GetPreferredSize() const override { | |
| 31 return gfx::Size(1, kTrayPopupScrollSeparatorHeight); | |
| 32 } | |
| 33 | |
| 34 DISALLOW_COPY_AND_ASSIGN(ScrollSeparator); | |
| 35 }; | |
| 36 | |
| 37 class ScrollBorder : public views::Border { | |
| 38 public: | |
| 39 ScrollBorder() {} | |
| 40 ~ScrollBorder() override {} | |
| 41 | |
| 42 void set_visible(bool visible) { visible_ = visible; } | |
| 43 | |
| 44 private: | |
| 45 // Overridden from views::Border. | |
| 46 void Paint(const views::View& view, gfx::Canvas* canvas) override { | |
| 47 if (!visible_) | |
| 48 return; | |
| 49 canvas->FillRect(gfx::Rect(0, view.height() - 1, view.width(), 1), | |
| 50 kBorderLightColor); | |
| 51 } | |
| 52 | |
| 53 gfx::Insets GetInsets() const override { return gfx::Insets(0, 0, 1, 0); } | |
| 54 | |
| 55 gfx::Size GetMinimumSize() const override { return gfx::Size(0, 1); } | |
| 56 | |
| 57 bool visible_; | |
| 58 | |
| 59 DISALLOW_COPY_AND_ASSIGN(ScrollBorder); | |
| 60 }; | |
| 61 | |
| 62 TrayDetailsView::TrayDetailsView(SystemTrayItem* owner) | |
| 63 : owner_(owner), | |
| 64 footer_(NULL), | |
| 65 scroller_(NULL), | |
| 66 scroll_content_(NULL), | |
| 67 scroll_border_(NULL) { | |
| 68 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical, | |
| 69 0, 0, 0)); | |
| 70 set_background(views::Background::CreateSolidBackground(kBackgroundColor)); | |
| 71 } | |
| 72 | |
| 73 TrayDetailsView::~TrayDetailsView() { | |
| 74 } | |
| 75 | |
| 76 void TrayDetailsView::CreateSpecialRow(int string_id, | |
| 77 ViewClickListener* listener) { | |
| 78 DCHECK(!footer_); | |
| 79 footer_ = new SpecialPopupRow(); | |
| 80 footer_->SetTextLabel(string_id, listener); | |
| 81 AddChildViewAt(footer_, child_count()); | |
| 82 } | |
| 83 | |
| 84 void TrayDetailsView::CreateScrollableList() { | |
| 85 DCHECK(!scroller_); | |
| 86 scroll_content_ = new views::View; | |
| 87 scroll_content_->SetLayoutManager(new views::BoxLayout( | |
| 88 views::BoxLayout::kVertical, 0, 0, 1)); | |
| 89 scroller_ = new FixedSizedScrollView; | |
| 90 scroller_->SetContentsView(scroll_content_); | |
| 91 | |
| 92 // Note: |scroller_| takes ownership of |scroll_border_|. | |
| 93 scroll_border_ = new ScrollBorder; | |
| 94 scroller_->SetBorder(std::unique_ptr<views::Border>(scroll_border_)); | |
| 95 | |
| 96 AddChildView(scroller_); | |
| 97 } | |
| 98 | |
| 99 void TrayDetailsView::AddScrollSeparator() { | |
| 100 DCHECK(scroll_content_); | |
| 101 // Do not draw the separator if it is the very first item | |
| 102 // in the scrollable list. | |
| 103 if (scroll_content_->has_children()) | |
| 104 scroll_content_->AddChildView(new ScrollSeparator); | |
| 105 } | |
| 106 | |
| 107 void TrayDetailsView::Reset() { | |
| 108 RemoveAllChildViews(true); | |
| 109 footer_ = NULL; | |
| 110 scroller_ = NULL; | |
| 111 scroll_content_ = NULL; | |
| 112 } | |
| 113 | |
| 114 void TrayDetailsView::TransitionToDefaultView() { | |
| 115 // Cache pointer to owner in this function scope. TrayDetailsView will be | |
| 116 // deleted after called ShowDefaultView. | |
| 117 SystemTrayItem* owner = owner_; | |
| 118 if (footer_ && footer_->content() && footer_->content()->HasFocus()) | |
| 119 owner->set_restore_focus(true); | |
| 120 owner->system_tray()->ShowDefaultView(BUBBLE_USE_EXISTING); | |
| 121 owner->set_restore_focus(false); | |
| 122 } | |
| 123 | |
| 124 void TrayDetailsView::Layout() { | |
| 125 if (bounds().IsEmpty()) { | |
| 126 views::View::Layout(); | |
| 127 return; | |
| 128 } | |
| 129 | |
| 130 if (scroller_) { | |
| 131 scroller_->set_fixed_size(gfx::Size()); | |
| 132 gfx::Size size = GetPreferredSize(); | |
| 133 | |
| 134 // Set the scroller to fill the space above the bottom row, so that the | |
| 135 // bottom row of the detailed view will always stay just above the footer. | |
| 136 gfx::Size scroller_size = scroll_content_->GetPreferredSize(); | |
| 137 scroller_->set_fixed_size( | |
| 138 gfx::Size(width() + scroller_->GetScrollBarWidth(), | |
| 139 scroller_size.height() - (size.height() - height()))); | |
| 140 } | |
| 141 | |
| 142 views::View::Layout(); | |
| 143 | |
| 144 if (footer_) { | |
| 145 // Always make sure the footer element is bottom aligned. | |
| 146 gfx::Rect fbounds = footer_->bounds(); | |
| 147 fbounds.set_y(height() - footer_->height()); | |
| 148 footer_->SetBoundsRect(fbounds); | |
| 149 } | |
| 150 } | |
| 151 | |
| 152 void TrayDetailsView::OnPaintBorder(gfx::Canvas* canvas) { | |
| 153 if (scroll_border_) { | |
| 154 int index = GetIndexOf(scroller_); | |
| 155 if (index < child_count() - 1 && child_at(index + 1) != footer_) | |
| 156 scroll_border_->set_visible(true); | |
| 157 else | |
| 158 scroll_border_->set_visible(false); | |
| 159 } | |
| 160 | |
| 161 views::View::OnPaintBorder(canvas); | |
| 162 } | |
| 163 | |
| 164 } // namespace ash | |
| OLD | NEW |