root/chrome/browser/ui/views/autofill/tooltip_icon.cc

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. GetPreferredInsets
  2. GetAnchorRect
  3. observer_
  4. GetClassName
  5. OnMouseEntered
  6. OnMouseExited
  7. OnGestureEvent
  8. GetAccessibleState
  9. MouseMovedOutOfHost
  10. ChangeImageTo
  11. ShowBubble
  12. HideBubble
  13. OnWidgetDestroyed

// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/ui/views/autofill/tooltip_icon.h"

#include "base/basictypes.h"
#include "base/timer/timer.h"
#include "chrome/browser/ui/views/autofill/info_bubble.h"
#include "grit/theme_resources.h"
#include "ui/accessibility/ax_view_state.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/views/bubble/bubble_frame_view.h"
#include "ui/views/mouse_watcher_view_host.h"
#include "ui/views/painter.h"

namespace autofill {

namespace {

gfx::Insets GetPreferredInsets(views::View* view) {
  gfx::Size pref_size = view->GetPreferredSize();
  gfx::Rect local_bounds = view->GetLocalBounds();
  gfx::Point origin = local_bounds.CenterPoint();
  origin.Offset(-pref_size.width() / 2, -pref_size.height() / 2);
  return gfx::Insets(origin.y(),
                     origin.x(),
                     local_bounds.bottom() - (origin.y() + pref_size.height()),
                     local_bounds.right() - (origin.x() + pref_size.width()));
}

// An info bubble with some extra positioning magic for tooltip icons.
class TooltipBubble : public InfoBubble {
 public:
  TooltipBubble(views::View* anchor, const base::string16& message)
      : InfoBubble(anchor, message) {}
  virtual ~TooltipBubble() {}

 protected:
  // InfoBubble:
  virtual gfx::Rect GetAnchorRect() OVERRIDE {
    gfx::Rect bounds = views::BubbleDelegateView::GetAnchorRect();
    bounds.Inset(GetPreferredInsets(anchor()));
    return bounds;
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(TooltipBubble);
};

}  // namespace

TooltipIcon::TooltipIcon(const base::string16& tooltip)
    : tooltip_(tooltip),
      mouse_inside_(false),
      bubble_(NULL),
      observer_(this) {
  ChangeImageTo(IDR_AUTOFILL_TOOLTIP_ICON);
}

TooltipIcon::~TooltipIcon() {
  HideBubble();
}

// static
const char TooltipIcon::kViewClassName[] = "autofill/TooltipIcon";

const char* TooltipIcon::GetClassName() const {
  return TooltipIcon::kViewClassName;
}

void TooltipIcon::OnMouseEntered(const ui::MouseEvent& event) {
  mouse_inside_ = true;
  show_timer_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(150), this,
                    &TooltipIcon::ShowBubble);
}

void TooltipIcon::OnMouseExited(const ui::MouseEvent& event) {
  show_timer_.Stop();
}

void TooltipIcon::OnGestureEvent(ui::GestureEvent* event) {
  if (event->type() == ui::ET_GESTURE_TAP) {
    ShowBubble();
    event->SetHandled();
  }
}

void TooltipIcon::GetAccessibleState(ui::AXViewState* state) {
  state->name = tooltip_;
}

void TooltipIcon::MouseMovedOutOfHost() {
  if (IsMouseHovered()) {
    mouse_watcher_->Start();
    return;
  }

  mouse_inside_ = false;
  HideBubble();
}

void TooltipIcon::ChangeImageTo(int idr) {
  ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
  SetImage(rb.GetImageNamed(idr).ToImageSkia());
}

void TooltipIcon::ShowBubble() {
  if (bubble_)
    return;

  ChangeImageTo(IDR_AUTOFILL_TOOLTIP_ICON_H);

  bubble_ = new TooltipBubble(this, tooltip_);
  // When shown due to a gesture event, close on deactivate (i.e. don't use
  // "focusless").
  bubble_->set_use_focusless(mouse_inside_);

  bubble_->Show();
  observer_.Add(bubble_->GetWidget());

  if (mouse_inside_) {
    views::View* frame = bubble_->GetWidget()->non_client_view()->frame_view();
    scoped_ptr<views::MouseWatcherHost> host(
        new views::MouseWatcherViewHost(frame, gfx::Insets()));
    mouse_watcher_.reset(new views::MouseWatcher(host.release(), this));
    mouse_watcher_->Start();
  }
}

void TooltipIcon::HideBubble() {
  if (bubble_)
    bubble_->Hide();
}

void TooltipIcon::OnWidgetDestroyed(views::Widget* widget) {
  observer_.Remove(widget);

  ChangeImageTo(IDR_AUTOFILL_TOOLTIP_ICON);
  mouse_watcher_.reset();
  bubble_ = NULL;
}

}  // namespace autofill

/* [<][>][^][v][top][bottom][index][help] */