This source file includes following definitions.
- IsValidTarget
- GetTooltipTarget
- tooltips_enabled_
- UpdateTooltip
- SetTooltipShownTimeout
- SetTooltipsEnabled
- OnKeyEvent
- OnMouseEvent
- OnTouchEvent
- OnCancelMode
- OnWindowDestroyed
- TooltipTimerFired
- TooltipShownTimerFired
- UpdateIfRequired
- IsTooltipVisible
- IsDragDropInProgress
- IsCursorVisible
- GetTooltipShownTimeout
- SetTooltipWindow
#include "ui/views/corewm/tooltip_controller.h"
#include <vector>
#include "base/strings/string_util.h"
#include "base/time/time.h"
#include "ui/aura/client/capture_client.h"
#include "ui/aura/client/cursor_client.h"
#include "ui/aura/client/screen_position_client.h"
#include "ui/aura/env.h"
#include "ui/aura/window.h"
#include "ui/events/event.h"
#include "ui/gfx/font.h"
#include "ui/gfx/rect.h"
#include "ui/gfx/screen.h"
#include "ui/views/corewm/tooltip.h"
#include "ui/views/widget/tooltip_manager.h"
#include "ui/wm/public/drag_drop_client.h"
namespace views {
namespace corewm {
namespace {
const int kTooltipTimeoutMs = 500;
const int kDefaultTooltipShownTimeoutMs = 10000;
bool IsValidTarget(aura::Window* event_target, aura::Window* target) {
if (!target || (event_target == target))
return true;
void* event_target_grouping_id = event_target->GetNativeWindowProperty(
TooltipManager::kGroupingPropertyKey);
void* target_grouping_id = target->GetNativeWindowProperty(
TooltipManager::kGroupingPropertyKey);
return event_target_grouping_id &&
event_target_grouping_id == target_grouping_id;
}
aura::Window* GetTooltipTarget(const ui::MouseEvent& event,
gfx::Point* location) {
switch (event.type()) {
case ui::ET_MOUSE_CAPTURE_CHANGED:
return NULL;
case ui::ET_MOUSE_EXITED:
return NULL;
case ui::ET_MOUSE_MOVED:
case ui::ET_MOUSE_DRAGGED: {
aura::Window* event_target = static_cast<aura::Window*>(event.target());
if (!event_target)
return NULL;
if (!event_target->HasCapture()) {
aura::Window* root = event_target->GetRootWindow();
if (root) {
aura::client::CaptureClient* capture_client =
aura::client::GetCaptureClient(root);
if (capture_client) {
aura::Window* capture_window =
capture_client->GetGlobalCaptureWindow();
if (capture_window && event_target != capture_window)
return NULL;
}
}
return event_target;
}
gfx::Point screen_loc(event.location());
aura::client::GetScreenPositionClient(event_target->GetRootWindow())->
ConvertPointToScreen(event_target, &screen_loc);
gfx::Screen* screen = gfx::Screen::GetScreenFor(event_target);
aura::Window* target = screen->GetWindowAtScreenPoint(screen_loc);
if (!target)
return NULL;
gfx::Point target_loc(screen_loc);
aura::client::GetScreenPositionClient(target->GetRootWindow())->
ConvertPointFromScreen(target, &target_loc);
aura::Window* screen_target = target->GetEventHandlerForPoint(target_loc);
if (!IsValidTarget(event_target, screen_target))
return NULL;
aura::Window::ConvertPointToTarget(screen_target, target, &target_loc);
*location = target_loc;
return screen_target;
}
default:
NOTREACHED();
break;
}
return NULL;
}
}
TooltipController::TooltipController(scoped_ptr<Tooltip> tooltip)
: tooltip_window_(NULL),
tooltip_window_at_mouse_press_(NULL),
tooltip_(tooltip.Pass()),
tooltips_enabled_(true) {
tooltip_timer_.Start(FROM_HERE,
base::TimeDelta::FromMilliseconds(kTooltipTimeoutMs),
this, &TooltipController::TooltipTimerFired);
}
TooltipController::~TooltipController() {
if (tooltip_window_)
tooltip_window_->RemoveObserver(this);
}
void TooltipController::UpdateTooltip(aura::Window* target) {
if (tooltip_window_ == target && tooltip_->IsVisible())
UpdateIfRequired();
if (tooltip_window_at_mouse_press_ &&
target == tooltip_window_at_mouse_press_ &&
aura::client::GetTooltipText(target) != tooltip_text_at_mouse_press_) {
tooltip_window_at_mouse_press_ = NULL;
}
if (!tooltip_timer_.IsRunning()) {
if (tooltip_window_ != target || (tooltip_window_ &&
tooltip_text_ != aura::client::GetTooltipText(tooltip_window_))) {
tooltip_timer_.Start(FROM_HERE,
base::TimeDelta::FromMilliseconds(kTooltipTimeoutMs),
this, &TooltipController::TooltipTimerFired);
}
}
}
void TooltipController::SetTooltipShownTimeout(aura::Window* target,
int timeout_in_ms) {
tooltip_shown_timeout_map_[target] = timeout_in_ms;
}
void TooltipController::SetTooltipsEnabled(bool enable) {
if (tooltips_enabled_ == enable)
return;
tooltips_enabled_ = enable;
UpdateTooltip(tooltip_window_);
}
void TooltipController::OnKeyEvent(ui::KeyEvent* event) {
if (tooltip_shown_timer_.IsRunning()) {
tooltip_shown_timer_.Stop();
TooltipShownTimerFired();
}
}
void TooltipController::OnMouseEvent(ui::MouseEvent* event) {
switch (event->type()) {
case ui::ET_MOUSE_CAPTURE_CHANGED:
case ui::ET_MOUSE_EXITED:
case ui::ET_MOUSE_MOVED:
case ui::ET_MOUSE_DRAGGED: {
curr_mouse_loc_ = event->location();
aura::Window* target = GetTooltipTarget(*event, &curr_mouse_loc_);
SetTooltipWindow(target);
if (tooltip_timer_.IsRunning())
tooltip_timer_.Reset();
if (tooltip_->IsVisible())
UpdateIfRequired();
break;
}
case ui::ET_MOUSE_PRESSED:
if ((event->flags() & ui::EF_IS_NON_CLIENT) == 0) {
aura::Window* target = static_cast<aura::Window*>(event->target());
tooltip_window_at_mouse_press_ = target;
if (target)
tooltip_text_at_mouse_press_ = aura::client::GetTooltipText(target);
}
tooltip_->Hide();
break;
case ui::ET_MOUSEWHEEL:
if (tooltip_->IsVisible())
tooltip_->Hide();
break;
default:
break;
}
}
void TooltipController::OnTouchEvent(ui::TouchEvent* event) {
tooltip_->Hide();
SetTooltipWindow(NULL);
}
void TooltipController::OnCancelMode(ui::CancelModeEvent* event) {
tooltip_->Hide();
SetTooltipWindow(NULL);
}
void TooltipController::OnWindowDestroyed(aura::Window* window) {
if (tooltip_window_ == window) {
tooltip_->Hide();
tooltip_shown_timeout_map_.erase(tooltip_window_);
tooltip_window_ = NULL;
}
}
void TooltipController::TooltipTimerFired() {
UpdateIfRequired();
}
void TooltipController::TooltipShownTimerFired() {
tooltip_->Hide();
tooltip_timer_.Stop();
}
void TooltipController::UpdateIfRequired() {
if (!tooltips_enabled_ ||
aura::Env::GetInstance()->IsMouseButtonDown() ||
IsDragDropInProgress() || !IsCursorVisible()) {
tooltip_->Hide();
return;
}
base::string16 tooltip_text;
if (tooltip_window_)
tooltip_text = aura::client::GetTooltipText(tooltip_window_);
if (tooltip_window_at_mouse_press_) {
if (tooltip_window_ == tooltip_window_at_mouse_press_ &&
tooltip_text == tooltip_text_at_mouse_press_) {
tooltip_->Hide();
return;
}
tooltip_window_at_mouse_press_ = NULL;
}
if (tooltip_text_ != tooltip_text || !tooltip_->IsVisible()) {
tooltip_shown_timer_.Stop();
tooltip_text_ = tooltip_text;
base::string16 trimmed_text(tooltip_text_);
views::TooltipManager::TrimTooltipText(&trimmed_text);
base::string16 whitespace_removed_text;
base::TrimWhitespace(trimmed_text, base::TRIM_ALL,
&whitespace_removed_text);
if (whitespace_removed_text.empty()) {
tooltip_->Hide();
} else {
gfx::Point widget_loc = curr_mouse_loc_ +
tooltip_window_->GetBoundsInScreen().OffsetFromOrigin();
tooltip_->SetText(tooltip_window_, whitespace_removed_text, widget_loc);
tooltip_->Show();
int timeout = GetTooltipShownTimeout();
if (timeout > 0) {
tooltip_shown_timer_.Start(FROM_HERE,
base::TimeDelta::FromMilliseconds(timeout),
this, &TooltipController::TooltipShownTimerFired);
}
}
}
}
bool TooltipController::IsTooltipVisible() {
return tooltip_->IsVisible();
}
bool TooltipController::IsDragDropInProgress() {
if (!tooltip_window_)
return false;
aura::client::DragDropClient* client =
aura::client::GetDragDropClient(tooltip_window_->GetRootWindow());
return client && client->IsDragDropInProgress();
}
bool TooltipController::IsCursorVisible() {
if (!tooltip_window_)
return false;
aura::Window* root = tooltip_window_->GetRootWindow();
if (!root)
return false;
aura::client::CursorClient* cursor_client =
aura::client::GetCursorClient(root);
return !cursor_client || cursor_client->IsCursorVisible();
}
int TooltipController::GetTooltipShownTimeout() {
std::map<aura::Window*, int>::const_iterator it =
tooltip_shown_timeout_map_.find(tooltip_window_);
if (it == tooltip_shown_timeout_map_.end())
return kDefaultTooltipShownTimeoutMs;
return it->second;
}
void TooltipController::SetTooltipWindow(aura::Window* target) {
if (tooltip_window_ == target)
return;
if (tooltip_window_)
tooltip_window_->RemoveObserver(this);
tooltip_window_ = target;
if (tooltip_window_)
tooltip_window_->AddObserver(this);
}
}
}