190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved.
290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// found in the LICENSE file.
490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "ash/popup_message.h"
690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "ash/wm/window_animations.h"
890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "grit/ash_resources.h"
990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "ui/base/resource/resource_bundle.h"
1090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "ui/gfx/insets.h"
1190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "ui/views/bubble/bubble_delegate.h"
1290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "ui/views/bubble/bubble_frame_view.h"
1390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "ui/views/controls/image_view.h"
1490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "ui/views/controls/label.h"
1590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "ui/views/layout/box_layout.h"
1690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "ui/views/widget/widget.h"
1790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
1890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)namespace ash {
1990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)namespace {
2090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)const int kMessageTopBottomMargin = 10;
2190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)const int kMessageLeftRightMargin = 10;
2290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)const int kMessageMinHeight = 29 - 2 * kMessageTopBottomMargin;
2390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)const SkColor kMessageTextColor = SkColorSetRGB(0x22, 0x22, 0x22);
2490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
2590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// The maximum width of the Message bubble.  Borrowed the value from
2690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// ash/message/message_controller.cc
2790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)const int kMessageMaxWidth = 250;
2890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
2990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// The offset for the Message bubble - making sure that the bubble is flush
3090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// with the shelf. The offset includes the arrow size in pixels as well as
3190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// the activation bar and other spacing elements.
3290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)const int kArrowOffsetLeftRight = 11;
3390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)const int kArrowOffsetTopBottom = 7;
3490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
3590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// The number of pixels between the icon and the text.
3690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)const int kHorizontalPopupPaddingBetweenItems = 10;
3790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
3890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// The number of pixels between the text items.
3990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)const int kVerticalPopupPaddingBetweenItems = 10;
4090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}  // namespace
4190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
4290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// The implementation of Message of the launcher.
4390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)class PopupMessage::MessageBubble : public views::BubbleDelegateView {
4490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) public:
4590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  MessageBubble(const base::string16& caption,
4690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                const base::string16& message,
4790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                IconType message_type,
4890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                views::View* anchor,
4990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                views::BubbleBorder::Arrow arrow_orientation,
5090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                const gfx::Size& size_override,
5190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                int arrow_offset);
5290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
5390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  void Close();
5490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
5590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) private:
5690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // views::View overrides:
57cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual gfx::Size GetPreferredSize() const OVERRIDE;
5890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
5990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Each component (width/height) can force a size override for that component
6090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // if not 0.
6190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  gfx::Size size_override_;
6290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
6390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(MessageBubble);
6490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)};
6590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
6690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)PopupMessage::MessageBubble::MessageBubble(const base::string16& caption,
6790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                           const base::string16& message,
6890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                           IconType message_type,
6990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                           views::View* anchor,
7090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                           views::BubbleBorder::Arrow arrow,
7190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                           const gfx::Size& size_override,
7290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                           int arrow_offset)
7390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    : views::BubbleDelegateView(anchor, arrow),
7490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      size_override_(size_override) {
7590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  gfx::Insets insets = gfx::Insets(kArrowOffsetTopBottom,
7690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                   kArrowOffsetLeftRight,
7790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                   kArrowOffsetTopBottom,
7890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                   kArrowOffsetLeftRight);
7990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // An anchor can have an asymmetrical border for spacing reasons. Adjust the
8090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // anchor location for this.
8190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (anchor->border())
8290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    insets += anchor->border()->GetInsets();
8390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
8490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  set_anchor_view_insets(insets);
8590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  set_close_on_esc(false);
8690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  set_close_on_deactivate(false);
8790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  set_use_focusless(true);
8890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  set_accept_events(false);
8990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
9090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  set_margins(gfx::Insets(kMessageTopBottomMargin, kMessageLeftRightMargin,
9190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                          kMessageTopBottomMargin, kMessageLeftRightMargin));
9290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  set_shadow(views::BubbleBorder::SMALL_SHADOW);
9390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
9490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
9590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  SetLayoutManager(new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0,
9690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                        kHorizontalPopupPaddingBetweenItems));
9790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
9890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Here is the layout:
9990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  //         arrow_offset (if not 0)
10090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  //       |-------------|
10190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  //       |             ^
10290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  //       +-------------------------------------------------+
10390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  //      -|                                                 |-
10490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  //  icon |  [!]  Caption in bold which can be multi line   | caption_label
10590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  //      -|                                                 |-
10690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  //       |       Message text which can be multi line      | message_label
10790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  //       |       as well.                                  |
10890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  //       |                                                 |-
10990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  //       +-------------------------------------------------+
11090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  //             |------------details container--------------|
11190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Note that the icon, caption and massage are optional.
11290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
11390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Add the icon to the first column (if there is one).
11490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (message_type != ICON_NONE) {
11590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    views::ImageView* icon = new views::ImageView();
11690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    icon->SetImage(
11790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        bundle.GetImageNamed(IDR_AURA_WARNING_ICON).ToImageSkia());
11890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    icon->SetVerticalAlignment(views::ImageView::LEADING);
11990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    AddChildView(icon);
12090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
12190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
12290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Create a container for the text items and use it as second column.
12390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  views::View* details = new views::View();
12490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  AddChildView(details);
12590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  details->SetLayoutManager(new views::BoxLayout(
12690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      views::BoxLayout::kVertical, 0, 0, kVerticalPopupPaddingBetweenItems));
12790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
12890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // The caption label.
12990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (!caption.empty()) {
13090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    views::Label* caption_label = new views::Label(caption);
13190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    caption_label->SetMultiLine(true);
13290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    caption_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    caption_label->SetFontList(
1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        bundle.GetFontList(ui::ResourceBundle::BoldFont));
13590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    caption_label->SetEnabledColor(kMessageTextColor);
13690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    details->AddChildView(caption_label);
13790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
13890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
13990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // The message label.
14090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (!message.empty()) {
14190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    views::Label* message_label = new views::Label(message);
14290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    message_label->SetMultiLine(true);
14390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    message_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
14490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    message_label->SetEnabledColor(kMessageTextColor);
14590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    details->AddChildView(message_label);
14690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
14790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  views::BubbleDelegateView::CreateBubble(this);
14890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
14990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Change the arrow offset if needed.
15090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (arrow_offset) {
15190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // With the creation of the bubble, the bubble got already placed (and
15290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // possibly re-oriented to fit on the screen). Since it is not possible to
15390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // set the arrow offset before the creation, we need to set the offset,
15490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // and the orientation variables again and force a re-placement.
15590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    GetBubbleFrameView()->bubble_border()->set_arrow_offset(arrow_offset);
15690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    GetBubbleFrameView()->bubble_border()->set_arrow(arrow);
15790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    SetAlignment(views::BubbleBorder::ALIGN_ARROW_TO_MID_ANCHOR);
15890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
15990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
16090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
16190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void PopupMessage::MessageBubble::Close() {
16290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (GetWidget())
16390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    GetWidget()->Close();
16490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
16590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
166cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)gfx::Size PopupMessage::MessageBubble::GetPreferredSize() const {
16790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  gfx::Size pref_size = views::BubbleDelegateView::GetPreferredSize();
16890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Override the size with either the provided size or adjust it to not
16990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // violate our minimum / maximum sizes.
17090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (size_override_.height())
17190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    pref_size.set_height(size_override_.height());
17290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  else if (pref_size.height() < kMessageMinHeight)
17390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    pref_size.set_height(kMessageMinHeight);
17490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
17590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (size_override_.width())
17690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    pref_size.set_width(size_override_.width());
17790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  else if (pref_size.width() > kMessageMaxWidth)
17890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    pref_size.set_width(kMessageMaxWidth);
17990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
18090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return pref_size;
18190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
18290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
18390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)PopupMessage::PopupMessage(const base::string16& caption,
18490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                           const base::string16& message,
18590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                           IconType message_type,
18690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                           views::View* anchor,
18790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                           views::BubbleBorder::Arrow arrow,
18890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                           const gfx::Size& size_override,
18990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                           int arrow_offset)
19090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    : view_(NULL) {
19190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  view_ = new MessageBubble(
19290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      caption, message, message_type, anchor, arrow, size_override,
19390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      arrow_offset);
19490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  widget_ = view_->GetWidget();
19590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
19690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  gfx::NativeView native_view = widget_->GetNativeView();
197a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  wm::SetWindowVisibilityAnimationType(
198a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      native_view, wm::WINDOW_VISIBILITY_ANIMATION_TYPE_VERTICAL);
199a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  wm::SetWindowVisibilityAnimationTransition(
200a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      native_view, wm::ANIMATE_HIDE);
20190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  view_->GetWidget()->Show();
20290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
20390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
20490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)PopupMessage::~PopupMessage() {
20590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  CancelHidingAnimation();
20690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  Close();
20790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
20890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
20990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void PopupMessage::Close() {
21090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (view_) {
21190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    view_->Close();
21290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    view_ = NULL;
21390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    widget_ = NULL;
21490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
21590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
21690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
21790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void PopupMessage::CancelHidingAnimation() {
21890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (!widget_ || !widget_->GetNativeView())
21990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return;
22090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
22190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  gfx::NativeView native_view = widget_->GetNativeView();
222a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  wm::SetWindowVisibilityAnimationTransition(
223a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      native_view, wm::ANIMATE_NONE);
22490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
22590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
22690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}  // namespace ash
227