| OLD | NEW |
| 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/common/system/tray/tray_details_view.h" | 5 #include "ash/common/system/tray/tray_details_view.h" |
| 6 | 6 |
| 7 #include "ash/common/ash_view_ids.h" | 7 #include "ash/common/ash_view_ids.h" |
| 8 #include "ash/common/material_design/material_design_controller.h" | 8 #include "ash/common/material_design/material_design_controller.h" |
| 9 #include "ash/common/system/tray/fixed_sized_scroll_view.h" | 9 #include "ash/common/system/tray/fixed_sized_scroll_view.h" |
| 10 #include "ash/common/system/tray/system_menu_button.h" | 10 #include "ash/common/system/tray/system_menu_button.h" |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 141 const int kShadowOffsetY = 2; | 141 const int kShadowOffsetY = 2; |
| 142 const int kShadowBlur = 2; | 142 const int kShadowBlur = 2; |
| 143 // TODO(fukino): Remove this constant once we stop maintaining pre-MD design. | 143 // TODO(fukino): Remove this constant once we stop maintaining pre-MD design. |
| 144 // crbug.com/614453. | 144 // crbug.com/614453. |
| 145 const int kContentsBetweenChildSpacingNonMd = 1; | 145 const int kContentsBetweenChildSpacingNonMd = 1; |
| 146 | 146 |
| 147 // A structure that keeps the original offset of each header between the | 147 // A structure that keeps the original offset of each header between the |
| 148 // calls to Layout() to allow keeping track of which view should be sticky. | 148 // calls to Layout() to allow keeping track of which view should be sticky. |
| 149 struct Header { | 149 struct Header { |
| 150 explicit Header(views::View* view) | 150 explicit Header(views::View* view) |
| 151 : view(view), natural_offset(view->y()) {} | 151 : view(view), natural_offset(view->y()), draw_separator_below(false) {} |
| 152 | 152 |
| 153 // A header View that can be decorated as sticky. | 153 // A header View that can be decorated as sticky. |
| 154 views::View* view; | 154 views::View* view; |
| 155 | 155 |
| 156 // Offset from the top of ScrollContentsView to |view|'s original vertical | 156 // Offset from the top of ScrollContentsView to |view|'s original vertical |
| 157 // position. | 157 // position. |
| 158 int natural_offset; | 158 int natural_offset; |
| 159 |
| 160 // True when a separator needs to be painted below the header when another |
| 161 // header is pushing |this| header up. |
| 162 bool draw_separator_below; |
| 159 }; | 163 }; |
| 160 | 164 |
| 161 // Adjusts y-position of header rows allowing one or two rows to stick to the | 165 // Adjusts y-position of header rows allowing one or two rows to stick to the |
| 162 // top of the visible viewport. | 166 // top of the visible viewport. |
| 163 void PositionHeaderRows() { | 167 void PositionHeaderRows() { |
| 164 const int scroll_offset = -y(); | 168 const int scroll_offset = -y(); |
| 165 Header* previous_header = nullptr; | 169 Header* previous_header = nullptr; |
| 166 for (auto& header : base::Reversed(headers_)) { | 170 for (auto& header : base::Reversed(headers_)) { |
| 167 views::View* header_view = header.view; | 171 views::View* header_view = header.view; |
| 172 header.draw_separator_below = false; |
| 168 if (header.natural_offset >= scroll_offset) { | 173 if (header.natural_offset >= scroll_offset) { |
| 169 previous_header = &header; | 174 previous_header = &header; |
| 170 header_view->SetY(header.natural_offset); | 175 header_view->SetY(header.natural_offset); |
| 171 continue; | 176 continue; |
| 172 } | 177 } |
| 173 if (previous_header && | 178 if (previous_header && |
| 174 previous_header->view->y() < scroll_offset + header_view->height()) { | 179 previous_header->view->y() <= scroll_offset + header_view->height()) { |
| 175 // Lower header displacing the header above. | 180 // Lower header displacing the header above. |
| 181 header.draw_separator_below = true; |
| 176 header_view->SetY(previous_header->view->y() - header_view->height()); | 182 header_view->SetY(previous_header->view->y() - header_view->height()); |
| 177 } else { | 183 } else { |
| 178 // A header becomes sticky. | 184 // A header becomes sticky. |
| 179 header_view->SetY(scroll_offset); | 185 header_view->SetY(scroll_offset); |
| 180 header_view->Layout(); | 186 header_view->Layout(); |
| 181 header_view->SchedulePaint(); | 187 header_view->SchedulePaint(); |
| 182 } | 188 } |
| 183 break; | 189 break; |
| 184 } | 190 } |
| 185 } | 191 } |
| 186 | 192 |
| 187 // Paints a separator for a header view. The separator can be a horizontal | 193 // Paints a separator for a header view. The separator can be a horizontal |
| 188 // rule or a horizontal shadow, depending on whether the header is sticking to | 194 // rule or a horizontal shadow, depending on whether the header is sticking to |
| 189 // the top of the scroll viewport. The return value indicates whether a shadow | 195 // the top of the scroll viewport. The return value indicates whether a shadow |
| 190 // was drawn. | 196 // was drawn. |
| 191 bool PaintDelineation(const Header& header, const ui::PaintContext& context) { | 197 bool PaintDelineation(const Header& header, const ui::PaintContext& context) { |
| 192 const View* view = header.view; | 198 const View* view = header.view; |
| 193 const bool at_top = view->y() == -y(); | |
| 194 | 199 |
| 195 // If the header is where it normally belongs, draw a separator above. | 200 // If the header is where it normally belongs, draw nothing. |
| 196 if (view->y() == header.natural_offset) { | 201 if (view->y() == header.natural_offset) |
| 197 // But if the header is at the very top of the viewport, draw nothing. | 202 return false; |
| 198 if (at_top) | |
| 199 return false; | |
| 200 | 203 |
| 204 // If the header is pushed by a header directly below it, draw a separator. |
| 205 if (header.draw_separator_below) { |
| 201 // TODO(estade): look better at 1.5x scale. | 206 // TODO(estade): look better at 1.5x scale. |
| 202 ui::PaintRecorder recorder(context, size()); | 207 ui::PaintRecorder recorder(context, size()); |
| 203 gfx::Canvas* canvas = recorder.canvas(); | 208 gfx::Canvas* canvas = recorder.canvas(); |
| 204 gfx::Rect separator = view->bounds(); | 209 gfx::Rect separator = view->bounds(); |
| 210 separator.set_y(separator.bottom() - kSeparatorWidth); |
| 205 separator.set_height(kSeparatorWidth); | 211 separator.set_height(kSeparatorWidth); |
| 206 canvas->FillRect(separator, kSeparatorColor); | 212 canvas->FillRect(separator, kSeparatorColor); |
| 207 return false; | 213 return false; |
| 208 } | 214 } |
| 209 | 215 |
| 210 // If the header is displaced but is not at the top of the viewport, it's | |
| 211 // being pushed out by another header. Draw nothing. | |
| 212 if (!at_top) | |
| 213 return false; | |
| 214 | |
| 215 // Otherwise, draw a shadow below. | 216 // Otherwise, draw a shadow below. |
| 216 DrawShadow(context, | 217 DrawShadow(context, |
| 217 gfx::Rect(0, 0, view->width(), view->bounds().bottom())); | 218 gfx::Rect(0, 0, view->width(), view->bounds().bottom())); |
| 218 return true; | 219 return true; |
| 219 } | 220 } |
| 220 | 221 |
| 221 // Draws a drop shadow below |shadowed_area|. | 222 // Draws a drop shadow below |shadowed_area|. |
| 222 void DrawShadow(const ui::PaintContext& context, | 223 void DrawShadow(const ui::PaintContext& context, |
| 223 const gfx::Rect& shadowed_area) { | 224 const gfx::Rect& shadowed_area) { |
| 224 ui::PaintRecorder recorder(context, size()); | 225 ui::PaintRecorder recorder(context, size()); |
| (...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 565 if (index < child_count() - 1 && child_at(index + 1) != title_row_) | 566 if (index < child_count() - 1 && child_at(index + 1) != title_row_) |
| 566 scroll_border_->set_visible(true); | 567 scroll_border_->set_visible(true); |
| 567 else | 568 else |
| 568 scroll_border_->set_visible(false); | 569 scroll_border_->set_visible(false); |
| 569 } | 570 } |
| 570 | 571 |
| 571 views::View::OnPaintBorder(canvas); | 572 views::View::OnPaintBorder(canvas); |
| 572 } | 573 } |
| 573 | 574 |
| 574 } // namespace ash | 575 } // namespace ash |
| OLD | NEW |