| 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_background_view.h" | |
| 6 | |
| 7 #include "ash/common/material_design/material_design_controller.h" | |
| 8 #include "ash/common/shelf/shelf_constants.h" | |
| 9 #include "ash/common/shelf/wm_shelf.h" | |
| 10 #include "ash/common/shelf/wm_shelf_util.h" | |
| 11 #include "ash/common/shell_window_ids.h" | |
| 12 #include "ash/common/system/tray/tray_constants.h" | |
| 13 #include "ash/screen_util.h" | |
| 14 #include "ash/shell.h" | |
| 15 #include "ash/system/status_area_widget.h" | |
| 16 #include "ash/system/status_area_widget_delegate.h" | |
| 17 #include "ash/system/tray/system_tray.h" | |
| 18 #include "ash/system/tray/tray_event_filter.h" | |
| 19 #include "ash/wm/window_animations.h" | |
| 20 #include "base/command_line.h" | |
| 21 #include "grit/ash_resources.h" | |
| 22 #include "ui/accessibility/ax_view_state.h" | |
| 23 #include "ui/aura/window.h" | |
| 24 #include "ui/aura/window_event_dispatcher.h" | |
| 25 #include "ui/base/nine_image_painter_factory.h" | |
| 26 #include "ui/base/ui_base_switches_util.h" | |
| 27 #include "ui/compositor/layer.h" | |
| 28 #include "ui/compositor/layer_animation_element.h" | |
| 29 #include "ui/compositor/scoped_layer_animation_settings.h" | |
| 30 #include "ui/events/event_constants.h" | |
| 31 #include "ui/gfx/animation/tween.h" | |
| 32 #include "ui/gfx/canvas.h" | |
| 33 #include "ui/gfx/geometry/rect.h" | |
| 34 #include "ui/gfx/image/image_skia.h" | |
| 35 #include "ui/gfx/image/image_skia_operations.h" | |
| 36 #include "ui/gfx/nine_image_painter.h" | |
| 37 #include "ui/gfx/skia_util.h" | |
| 38 #include "ui/gfx/transform.h" | |
| 39 #include "ui/views/background.h" | |
| 40 #include "ui/views/layout/box_layout.h" | |
| 41 #include "ui/wm/core/window_animations.h" | |
| 42 | |
| 43 namespace { | |
| 44 | |
| 45 const int kAnimationDurationForPopupMs = 200; | |
| 46 | |
| 47 // Duration of opacity animation for visibility changes. | |
| 48 const int kAnimationDurationForVisibilityMs = 250; | |
| 49 | |
| 50 // When becoming visible delay the animation so that StatusAreaWidgetDelegate | |
| 51 // can animate sibling views out of the position to be occuped by the | |
| 52 // TrayBackgroundView. | |
| 53 const int kShowAnimationDelayMs = 100; | |
| 54 | |
| 55 } // namespace | |
| 56 | |
| 57 using views::TrayBubbleView; | |
| 58 | |
| 59 namespace ash { | |
| 60 | |
| 61 // static | |
| 62 const char TrayBackgroundView::kViewClassName[] = "tray/TrayBackgroundView"; | |
| 63 | |
| 64 // Used to track when the anchor widget changes position on screen so that the | |
| 65 // bubble position can be updated. | |
| 66 class TrayBackgroundView::TrayWidgetObserver : public views::WidgetObserver { | |
| 67 public: | |
| 68 explicit TrayWidgetObserver(TrayBackgroundView* host) | |
| 69 : host_(host) { | |
| 70 } | |
| 71 | |
| 72 void OnWidgetBoundsChanged(views::Widget* widget, | |
| 73 const gfx::Rect& new_bounds) override { | |
| 74 host_->AnchorUpdated(); | |
| 75 } | |
| 76 | |
| 77 void OnWidgetVisibilityChanged(views::Widget* widget, bool visible) override { | |
| 78 host_->AnchorUpdated(); | |
| 79 } | |
| 80 | |
| 81 private: | |
| 82 TrayBackgroundView* host_; | |
| 83 | |
| 84 DISALLOW_COPY_AND_ASSIGN(TrayWidgetObserver); | |
| 85 }; | |
| 86 | |
| 87 class TrayBackground : public views::Background { | |
| 88 public: | |
| 89 const static int kImageTypeDefault = 0; | |
| 90 const static int kImageTypeOnBlack = 1; | |
| 91 const static int kImageTypePressed = 2; | |
| 92 const static int kNumStates = 3; | |
| 93 | |
| 94 const static int kImageHorizontal = 0; | |
| 95 const static int kImageVertical = 1; | |
| 96 const static int kNumOrientations = 2; | |
| 97 | |
| 98 explicit TrayBackground(TrayBackgroundView* tray_background_view) : | |
| 99 tray_background_view_(tray_background_view) { | |
| 100 } | |
| 101 | |
| 102 ~TrayBackground() override {} | |
| 103 | |
| 104 private: | |
| 105 WmShelf* GetShelf() const { | |
| 106 return tray_background_view_->GetShelf(); | |
| 107 } | |
| 108 | |
| 109 void PaintMaterial(gfx::Canvas* canvas, views::View* view) const { | |
| 110 SkColor background_color = SK_ColorTRANSPARENT; | |
| 111 if (GetShelf()->GetBackgroundType() == | |
| 112 ShelfBackgroundType::SHELF_BACKGROUND_DEFAULT) { | |
| 113 background_color = SkColorSetA(kShelfBaseColor, | |
| 114 GetShelfConstant(SHELF_BACKGROUND_ALPHA)); | |
| 115 } | |
| 116 | |
| 117 // TODO(bruthig|tdanderson): The background should be changed using a | |
| 118 // fade in/out animation. | |
| 119 const int kCornerRadius = 2; | |
| 120 | |
| 121 SkPaint background_paint; | |
| 122 background_paint.setFlags(SkPaint::kAntiAlias_Flag); | |
| 123 background_paint.setColor(background_color); | |
| 124 canvas->DrawRoundRect(view->GetLocalBounds(), kCornerRadius, | |
| 125 background_paint); | |
| 126 | |
| 127 if (tray_background_view_->draw_background_as_active()) { | |
| 128 SkPaint highlight_paint; | |
| 129 highlight_paint.setFlags(SkPaint::kAntiAlias_Flag); | |
| 130 highlight_paint.setColor(kShelfButtonActivatedHighlightColor); | |
| 131 canvas->DrawRoundRect(view->GetLocalBounds(), kCornerRadius, | |
| 132 highlight_paint); | |
| 133 } | |
| 134 } | |
| 135 | |
| 136 void PaintNonMaterial(gfx::Canvas* canvas, views::View* view) const { | |
| 137 const int kGridSizeForPainter = 9; | |
| 138 const int kImages[kNumOrientations][kNumStates][kGridSizeForPainter] = { | |
| 139 { // Horizontal | |
| 140 IMAGE_GRID_HORIZONTAL(IDR_AURA_TRAY_BG_HORIZ), | |
| 141 IMAGE_GRID_HORIZONTAL(IDR_AURA_TRAY_BG_HORIZ_ONBLACK), | |
| 142 IMAGE_GRID_HORIZONTAL(IDR_AURA_TRAY_BG_HORIZ_PRESSED), | |
| 143 }, | |
| 144 { // Vertical | |
| 145 IMAGE_GRID_VERTICAL(IDR_AURA_TRAY_BG_VERTICAL), | |
| 146 IMAGE_GRID_VERTICAL(IDR_AURA_TRAY_BG_VERTICAL_ONBLACK), | |
| 147 IMAGE_GRID_VERTICAL(IDR_AURA_TRAY_BG_VERTICAL_PRESSED), | |
| 148 } | |
| 149 }; | |
| 150 | |
| 151 WmShelf* shelf = GetShelf(); | |
| 152 const int orientation = IsHorizontalAlignment(shelf->GetAlignment()) | |
| 153 ? kImageHorizontal | |
| 154 : kImageVertical; | |
| 155 | |
| 156 int state = kImageTypeDefault; | |
| 157 if (tray_background_view_->draw_background_as_active()) | |
| 158 state = kImageTypePressed; | |
| 159 else if (shelf->IsDimmed()) | |
| 160 state = kImageTypeOnBlack; | |
| 161 else | |
| 162 state = kImageTypeDefault; | |
| 163 | |
| 164 ui::CreateNineImagePainter(kImages[orientation][state]) | |
| 165 ->Paint(canvas, view->GetLocalBounds()); | |
| 166 } | |
| 167 | |
| 168 // Overridden from views::Background. | |
| 169 void Paint(gfx::Canvas* canvas, views::View* view) const override { | |
| 170 if (MaterialDesignController::IsShelfMaterial()) | |
| 171 PaintMaterial(canvas, view); | |
| 172 else | |
| 173 PaintNonMaterial(canvas, view); | |
| 174 } | |
| 175 | |
| 176 // Reference to the TrayBackgroundView for which this is a background. | |
| 177 TrayBackgroundView* tray_background_view_; | |
| 178 | |
| 179 DISALLOW_COPY_AND_ASSIGN(TrayBackground); | |
| 180 }; | |
| 181 | |
| 182 TrayBackgroundView::TrayContainer::TrayContainer(ShelfAlignment alignment) | |
| 183 : alignment_(alignment) { | |
| 184 UpdateLayout(); | |
| 185 } | |
| 186 | |
| 187 void TrayBackgroundView::TrayContainer::SetAlignment(ShelfAlignment alignment) { | |
| 188 if (alignment_ == alignment) | |
| 189 return; | |
| 190 alignment_ = alignment; | |
| 191 UpdateLayout(); | |
| 192 } | |
| 193 | |
| 194 gfx::Size TrayBackgroundView::TrayContainer::GetPreferredSize() const { | |
| 195 if (size_.IsEmpty()) | |
| 196 return views::View::GetPreferredSize(); | |
| 197 return size_; | |
| 198 } | |
| 199 | |
| 200 void TrayBackgroundView::TrayContainer::ChildPreferredSizeChanged( | |
| 201 views::View* child) { | |
| 202 PreferredSizeChanged(); | |
| 203 } | |
| 204 | |
| 205 void TrayBackgroundView::TrayContainer::ChildVisibilityChanged(View* child) { | |
| 206 PreferredSizeChanged(); | |
| 207 } | |
| 208 | |
| 209 void TrayBackgroundView::TrayContainer::ViewHierarchyChanged( | |
| 210 const ViewHierarchyChangedDetails& details) { | |
| 211 if (details.parent == this) | |
| 212 PreferredSizeChanged(); | |
| 213 } | |
| 214 | |
| 215 // TODO(tdanderson): Adjust TrayContainer borders according to the material | |
| 216 // design specs. See crbug.com/617295. | |
| 217 void TrayBackgroundView::TrayContainer::UpdateLayout() { | |
| 218 // Adjust the size of status tray dark background by adding additional | |
| 219 // empty border. | |
| 220 views::BoxLayout::Orientation orientation = | |
| 221 IsHorizontalAlignment(alignment_) ? views::BoxLayout::kHorizontal | |
| 222 : views::BoxLayout::kVertical; | |
| 223 SetBorder(views::Border::CreateEmptyBorder( | |
| 224 kAdjustBackgroundPadding, kAdjustBackgroundPadding, | |
| 225 kAdjustBackgroundPadding, kAdjustBackgroundPadding)); | |
| 226 | |
| 227 views::BoxLayout* layout = new views::BoxLayout(orientation, 0, 0, 0); | |
| 228 layout->SetDefaultFlex(1); | |
| 229 views::View::SetLayoutManager(layout); | |
| 230 PreferredSizeChanged(); | |
| 231 } | |
| 232 | |
| 233 //////////////////////////////////////////////////////////////////////////////// | |
| 234 // TrayBackgroundView | |
| 235 | |
| 236 TrayBackgroundView::TrayBackgroundView(StatusAreaWidget* status_area_widget) | |
| 237 : status_area_widget_(status_area_widget), | |
| 238 tray_container_(NULL), | |
| 239 shelf_alignment_(SHELF_ALIGNMENT_BOTTOM), | |
| 240 background_(NULL), | |
| 241 draw_background_as_active_(false), | |
| 242 widget_observer_(new TrayWidgetObserver(this)) { | |
| 243 DCHECK(status_area_widget->wm_shelf()); | |
| 244 set_notify_enter_exit_on_child(true); | |
| 245 | |
| 246 tray_container_ = new TrayContainer(shelf_alignment_); | |
| 247 SetContents(tray_container_); | |
| 248 tray_event_filter_.reset(new TrayEventFilter); | |
| 249 | |
| 250 SetPaintToLayer(true); | |
| 251 layer()->SetFillsBoundsOpaquely(false); | |
| 252 // Start the tray items not visible, because visibility changes are animated. | |
| 253 views::View::SetVisible(false); | |
| 254 } | |
| 255 | |
| 256 TrayBackgroundView::~TrayBackgroundView() { | |
| 257 if (GetWidget()) | |
| 258 GetWidget()->RemoveObserver(widget_observer_.get()); | |
| 259 StopObservingImplicitAnimations(); | |
| 260 } | |
| 261 | |
| 262 void TrayBackgroundView::Initialize() { | |
| 263 GetWidget()->AddObserver(widget_observer_.get()); | |
| 264 } | |
| 265 | |
| 266 // static | |
| 267 void TrayBackgroundView::InitializeBubbleAnimations( | |
| 268 views::Widget* bubble_widget) { | |
| 269 aura::Window* window = bubble_widget->GetNativeWindow(); | |
| 270 ::wm::SetWindowVisibilityAnimationType( | |
| 271 window, ::wm::WINDOW_VISIBILITY_ANIMATION_TYPE_FADE); | |
| 272 ::wm::SetWindowVisibilityAnimationTransition(window, ::wm::ANIMATE_HIDE); | |
| 273 ::wm::SetWindowVisibilityAnimationDuration( | |
| 274 window, base::TimeDelta::FromMilliseconds(kAnimationDurationForPopupMs)); | |
| 275 } | |
| 276 | |
| 277 void TrayBackgroundView::SetVisible(bool visible) { | |
| 278 if (visible == layer()->GetTargetVisibility()) | |
| 279 return; | |
| 280 | |
| 281 if (visible) { | |
| 282 // The alignment of the shelf can change while the TrayBackgroundView is | |
| 283 // hidden. Reset the offscreen transform so that the animation to becoming | |
| 284 // visible reflects the current layout. | |
| 285 HideTransformation(); | |
| 286 // SetVisible(false) is defered until the animation for hiding is done. | |
| 287 // Otherwise the view is immediately hidden and the animation does not | |
| 288 // render. | |
| 289 views::View::SetVisible(true); | |
| 290 // If SetVisible(true) is called while animating to not visible, then | |
| 291 // views::View::SetVisible(true) is a no-op. When the previous animation | |
| 292 // ends layer->SetVisible(false) is called. To prevent this | |
| 293 // layer->SetVisible(true) immediately interrupts the animation of this | |
| 294 // property, and keeps the layer visible. | |
| 295 layer()->SetVisible(true); | |
| 296 } | |
| 297 | |
| 298 ui::ScopedLayerAnimationSettings animation(layer()->GetAnimator()); | |
| 299 animation.SetTransitionDuration(base::TimeDelta::FromMilliseconds( | |
| 300 kAnimationDurationForVisibilityMs)); | |
| 301 animation.SetPreemptionStrategy( | |
| 302 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); | |
| 303 | |
| 304 if (visible) { | |
| 305 animation.SetTweenType(gfx::Tween::EASE_OUT); | |
| 306 // Show is delayed so as to allow time for other children of | |
| 307 // StatusAreaWidget to begin animating to their new positions. | |
| 308 layer()->GetAnimator()->SchedulePauseForProperties( | |
| 309 base::TimeDelta::FromMilliseconds(kShowAnimationDelayMs), | |
| 310 ui::LayerAnimationElement::OPACITY | | |
| 311 ui::LayerAnimationElement::TRANSFORM); | |
| 312 layer()->SetOpacity(1.0f); | |
| 313 gfx::Transform transform; | |
| 314 transform.Translate(0.0f, 0.0f); | |
| 315 layer()->SetTransform(transform); | |
| 316 } else { | |
| 317 // Listen only to the hide animation. As we cannot turn off visibility | |
| 318 // until the animation is over. | |
| 319 animation.AddObserver(this); | |
| 320 animation.SetTweenType(gfx::Tween::EASE_IN); | |
| 321 layer()->SetOpacity(0.0f); | |
| 322 layer()->SetVisible(false); | |
| 323 HideTransformation(); | |
| 324 } | |
| 325 } | |
| 326 | |
| 327 const char* TrayBackgroundView::GetClassName() const { | |
| 328 return kViewClassName; | |
| 329 } | |
| 330 | |
| 331 void TrayBackgroundView::ChildPreferredSizeChanged(views::View* child) { | |
| 332 PreferredSizeChanged(); | |
| 333 } | |
| 334 | |
| 335 void TrayBackgroundView::GetAccessibleState(ui::AXViewState* state) { | |
| 336 ActionableView::GetAccessibleState(state); | |
| 337 state->name = GetAccessibleNameForTray(); | |
| 338 } | |
| 339 | |
| 340 void TrayBackgroundView::AboutToRequestFocusFromTabTraversal(bool reverse) { | |
| 341 // Return focus to the login view. See crbug.com/120500. | |
| 342 views::View* v = GetNextFocusableView(); | |
| 343 if (v) | |
| 344 v->AboutToRequestFocusFromTabTraversal(reverse); | |
| 345 } | |
| 346 | |
| 347 bool TrayBackgroundView::PerformAction(const ui::Event& event) { | |
| 348 return false; | |
| 349 } | |
| 350 | |
| 351 gfx::Rect TrayBackgroundView::GetFocusBounds() { | |
| 352 // The tray itself expands to the right and bottom edge of the screen to make | |
| 353 // sure clicking on the edges brings up the popup. However, the focus border | |
| 354 // should be only around the container. | |
| 355 return GetContentsBounds(); | |
| 356 } | |
| 357 | |
| 358 void TrayBackgroundView::OnGestureEvent(ui::GestureEvent* event) { | |
| 359 if (switches::IsTouchFeedbackEnabled()) { | |
| 360 if (event->type() == ui::ET_GESTURE_TAP_DOWN) { | |
| 361 SetDrawBackgroundAsActive(true); | |
| 362 } else if (event->type() == ui::ET_GESTURE_SCROLL_BEGIN || | |
| 363 event->type() == ui::ET_GESTURE_TAP_CANCEL) { | |
| 364 SetDrawBackgroundAsActive(false); | |
| 365 } | |
| 366 } | |
| 367 ActionableView::OnGestureEvent(event); | |
| 368 } | |
| 369 | |
| 370 void TrayBackgroundView::UpdateBackground(int alpha) { | |
| 371 // The animator should never fire when the alternate shelf layout is used. | |
| 372 if (!background_ || draw_background_as_active_) | |
| 373 return; | |
| 374 SchedulePaint(); | |
| 375 } | |
| 376 | |
| 377 void TrayBackgroundView::SetContents(views::View* contents) { | |
| 378 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0)); | |
| 379 AddChildView(contents); | |
| 380 } | |
| 381 void TrayBackgroundView::SetContentsBackground() { | |
| 382 background_ = new TrayBackground(this); | |
| 383 tray_container_->set_background(background_); | |
| 384 } | |
| 385 | |
| 386 WmShelf* TrayBackgroundView::GetShelf() { | |
| 387 return status_area_widget_->wm_shelf(); | |
| 388 } | |
| 389 | |
| 390 void TrayBackgroundView::SetShelfAlignment(ShelfAlignment alignment) { | |
| 391 shelf_alignment_ = alignment; | |
| 392 tray_container_->SetAlignment(alignment); | |
| 393 } | |
| 394 | |
| 395 void TrayBackgroundView::OnImplicitAnimationsCompleted() { | |
| 396 // If there is another animation in the queue, the reverse animation was | |
| 397 // triggered before the completion of animating to invisible. Do not turn off | |
| 398 // the visibility so that the next animation may render. The value of | |
| 399 // layer()->GetTargetVisibility() can be incorrect if the hide animation was | |
| 400 // aborted to schedule an animation to become visible. As the new animation | |
| 401 // is not yet added to the queue. crbug.com/374236 | |
| 402 if(layer()->GetAnimator()->is_animating() || | |
| 403 layer()->GetTargetVisibility()) | |
| 404 return; | |
| 405 views::View::SetVisible(false); | |
| 406 } | |
| 407 | |
| 408 bool TrayBackgroundView::RequiresNotificationWhenAnimatorDestroyed() const { | |
| 409 // This is needed so that OnImplicitAnimationsCompleted() is called even upon | |
| 410 // destruction of the animator. This can occure when parallel animations | |
| 411 // caused by ScreenRotationAnimator end before the animations of | |
| 412 // TrayBackgroundView. This allows for a proper update to the visual state of | |
| 413 // the view. (crbug.com/476667) | |
| 414 return true; | |
| 415 } | |
| 416 | |
| 417 void TrayBackgroundView::HideTransformation() { | |
| 418 gfx::Transform transform; | |
| 419 if (IsHorizontalAlignment(shelf_alignment_)) | |
| 420 transform.Translate(width(), 0.0f); | |
| 421 else | |
| 422 transform.Translate(0.0f, height()); | |
| 423 layer()->SetTransform(transform); | |
| 424 } | |
| 425 | |
| 426 gfx::Rect TrayBackgroundView::GetBubbleAnchorRect( | |
| 427 views::Widget* anchor_widget, | |
| 428 TrayBubbleView::AnchorType anchor_type, | |
| 429 TrayBubbleView::AnchorAlignment anchor_alignment) const { | |
| 430 gfx::Rect rect; | |
| 431 if (anchor_widget && anchor_widget->IsVisible()) { | |
| 432 rect = anchor_widget->GetWindowBoundsInScreen(); | |
| 433 if (anchor_type == TrayBubbleView::ANCHOR_TYPE_TRAY) { | |
| 434 if (anchor_alignment == TrayBubbleView::ANCHOR_ALIGNMENT_BOTTOM) { | |
| 435 bool rtl = base::i18n::IsRTL(); | |
| 436 rect.Inset( | |
| 437 rtl ? kBubblePaddingHorizontalSide : 0, | |
| 438 kBubblePaddingHorizontalBottom, | |
| 439 rtl ? 0 : kBubblePaddingHorizontalSide, | |
| 440 0); | |
| 441 } else if (anchor_alignment == TrayBubbleView::ANCHOR_ALIGNMENT_LEFT) { | |
| 442 rect.Inset(0, 0, kBubblePaddingVerticalSide + 4, | |
| 443 kBubblePaddingVerticalBottom); | |
| 444 } else if (anchor_alignment == TrayBubbleView::ANCHOR_ALIGNMENT_RIGHT) { | |
| 445 rect.Inset(kBubblePaddingVerticalSide, 0, 0, | |
| 446 kBubblePaddingVerticalBottom); | |
| 447 } else { | |
| 448 // TODO(bruthig) May need to handle other ANCHOR_ALIGNMENT_ values. | |
| 449 // ie. ANCHOR_ALIGNMENT_TOP | |
| 450 DCHECK(false) << "Unhandled anchor alignment."; | |
| 451 } | |
| 452 } else if (anchor_type == TrayBubbleView::ANCHOR_TYPE_BUBBLE) { | |
| 453 // Invert the offsets to align with the bubble below. | |
| 454 // Note that with the alternate shelf layout the tips are not shown and | |
| 455 // the offsets for left and right alignment do not need to be applied. | |
| 456 int vertical_alignment = 0; | |
| 457 int horizontal_alignment = kBubblePaddingVerticalBottom; | |
| 458 if (anchor_alignment == TrayBubbleView::ANCHOR_ALIGNMENT_LEFT) | |
| 459 rect.Inset(vertical_alignment, 0, 0, horizontal_alignment); | |
| 460 else if (anchor_alignment == TrayBubbleView::ANCHOR_ALIGNMENT_RIGHT) | |
| 461 rect.Inset(0, 0, vertical_alignment, horizontal_alignment); | |
| 462 } else { | |
| 463 DCHECK(false) << "Unhandled anchor type."; | |
| 464 } | |
| 465 } else { | |
| 466 aura::Window* target_root = anchor_widget ? | |
| 467 anchor_widget->GetNativeView()->GetRootWindow() : | |
| 468 Shell::GetPrimaryRootWindow(); | |
| 469 rect = target_root->bounds(); | |
| 470 if (anchor_type == TrayBubbleView::ANCHOR_TYPE_TRAY) { | |
| 471 if (anchor_alignment == TrayBubbleView::ANCHOR_ALIGNMENT_BOTTOM) { | |
| 472 rect = gfx::Rect( | |
| 473 base::i18n::IsRTL() ? | |
| 474 kPaddingFromRightEdgeOfScreenBottomAlignment : | |
| 475 rect.width() - kPaddingFromRightEdgeOfScreenBottomAlignment, | |
| 476 rect.height() - kPaddingFromBottomOfScreenBottomAlignment, | |
| 477 0, 0); | |
| 478 rect = ScreenUtil::ConvertRectToScreen(target_root, rect); | |
| 479 } else if (anchor_alignment == TrayBubbleView::ANCHOR_ALIGNMENT_LEFT) { | |
| 480 rect = gfx::Rect( | |
| 481 kPaddingFromRightEdgeOfScreenBottomAlignment, | |
| 482 rect.height() - kPaddingFromBottomOfScreenBottomAlignment, | |
| 483 1, 1); | |
| 484 rect = ScreenUtil::ConvertRectToScreen(target_root, rect); | |
| 485 } else if (anchor_alignment == TrayBubbleView::ANCHOR_ALIGNMENT_RIGHT) { | |
| 486 rect = gfx::Rect( | |
| 487 rect.width() - kPaddingFromRightEdgeOfScreenBottomAlignment, | |
| 488 rect.height() - kPaddingFromBottomOfScreenBottomAlignment, | |
| 489 1, 1); | |
| 490 rect = ScreenUtil::ConvertRectToScreen(target_root, rect); | |
| 491 } else { | |
| 492 // TODO(bruthig) May need to handle other ANCHOR_ALIGNMENT_ values. | |
| 493 // ie. ANCHOR_ALIGNMENT_TOP | |
| 494 DCHECK(false) << "Unhandled anchor alignment."; | |
| 495 } | |
| 496 } else { | |
| 497 rect = gfx::Rect( | |
| 498 base::i18n::IsRTL() ? | |
| 499 kPaddingFromRightEdgeOfScreenBottomAlignment : | |
| 500 rect.width() - kPaddingFromRightEdgeOfScreenBottomAlignment, | |
| 501 rect.height() - kPaddingFromBottomOfScreenBottomAlignment, | |
| 502 0, 0); | |
| 503 } | |
| 504 } | |
| 505 return rect; | |
| 506 } | |
| 507 | |
| 508 TrayBubbleView::AnchorAlignment TrayBackgroundView::GetAnchorAlignment() const { | |
| 509 if (shelf_alignment_ == SHELF_ALIGNMENT_LEFT) | |
| 510 return TrayBubbleView::ANCHOR_ALIGNMENT_LEFT; | |
| 511 if (shelf_alignment_ == SHELF_ALIGNMENT_RIGHT) | |
| 512 return TrayBubbleView::ANCHOR_ALIGNMENT_RIGHT; | |
| 513 return TrayBubbleView::ANCHOR_ALIGNMENT_BOTTOM; | |
| 514 } | |
| 515 | |
| 516 void TrayBackgroundView::SetDrawBackgroundAsActive(bool visible) { | |
| 517 if (draw_background_as_active_ == visible) | |
| 518 return; | |
| 519 draw_background_as_active_ = visible; | |
| 520 if (!background_) | |
| 521 return; | |
| 522 SchedulePaint(); | |
| 523 } | |
| 524 | |
| 525 void TrayBackgroundView::UpdateBubbleViewArrow( | |
| 526 views::TrayBubbleView* bubble_view) { | |
| 527 // Nothing to do here. | |
| 528 } | |
| 529 | |
| 530 } // namespace ash | |
| OLD | NEW |