diff options
-rw-r--r-- | content/browser/renderer_host/render_widget_host_view_aura.cc | 7 | ||||
-rw-r--r-- | ui/aura/aura.gyp | 1 | ||||
-rw-r--r-- | ui/aura/client/aura_constants.cc | 1 | ||||
-rw-r--r-- | ui/aura/client/aura_constants.h | 4 | ||||
-rw-r--r-- | ui/aura/client/tooltip_client.h | 32 | ||||
-rw-r--r-- | ui/aura_shell/aura_shell.gyp | 2 | ||||
-rw-r--r-- | ui/aura_shell/shell.cc | 14 | ||||
-rw-r--r-- | ui/aura_shell/shell.h | 7 | ||||
-rw-r--r-- | ui/aura_shell/shell_tooltip_manager.cc | 281 | ||||
-rw-r--r-- | ui/aura_shell/shell_tooltip_manager.h | 71 | ||||
-rw-r--r-- | ui/views/test/test_tooltip_client.cc | 28 | ||||
-rw-r--r-- | ui/views/test/test_tooltip_client.h | 32 | ||||
-rw-r--r-- | ui/views/widget/native_widget_aura.cc | 13 | ||||
-rw-r--r-- | ui/views/widget/native_widget_aura.h | 4 | ||||
-rw-r--r-- | ui/views/widget/tooltip_manager_aura.cc | 107 | ||||
-rw-r--r-- | ui/views/widget/tooltip_manager_aura.h | 42 | ||||
-rw-r--r-- | ui/views/widget/tooltip_manager_views.cc | 239 | ||||
-rw-r--r-- | ui/views/widget/tooltip_manager_views.h | 80 | ||||
-rw-r--r-- | views/views.gyp | 7 |
19 files changed, 641 insertions, 331 deletions
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc index 8c4288a..c642aca 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura.cc +++ b/content/browser/renderer_host/render_widget_host_view_aura.cc @@ -13,6 +13,7 @@ #include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebScreenInfo.h" #include "ui/aura/client/aura_constants.h" +#include "ui/aura/client/tooltip_client.h" #include "ui/aura/desktop.h" #include "ui/aura/event.h" #include "ui/aura/window.h" @@ -272,6 +273,12 @@ void RenderWidgetHostViewAura::Destroy() { void RenderWidgetHostViewAura::SetTooltipText(const string16& tooltip_text) { tooltip_ = tooltip_text; + void* property = aura::Desktop::GetInstance()->GetProperty( + aura::kDesktopTooltipClientKey); + if (property) { + aura::TooltipClient* tc = static_cast<aura::TooltipClient*>(property); + tc->UpdateTooltip(window_); + } } BackingStore* RenderWidgetHostViewAura::AllocBackingStore( diff --git a/ui/aura/aura.gyp b/ui/aura/aura.gyp index fe41495..6d98b42 100644 --- a/ui/aura/aura.gyp +++ b/ui/aura/aura.gyp @@ -29,6 +29,7 @@ 'client/aura_constants.h', 'client/drag_drop_client.h', 'client/stacking_client.h', + 'client/tooltip_client.h', 'client/window_drag_drop_delegate.h', 'cursor.h', 'desktop_host.h', diff --git a/ui/aura/client/aura_constants.cc b/ui/aura/client/aura_constants.cc index f0a651a..e23b7a0 100644 --- a/ui/aura/client/aura_constants.cc +++ b/ui/aura/client/aura_constants.cc @@ -14,5 +14,6 @@ const char kModalKey[] = "Modal"; const char kShadowTypeKey[] = "ShadowType"; const char kDesktopDragDropClientKey[] = "DesktopDragDropClient"; const char kDragDropDelegateKey[] = "DragDropDelegate"; +const char kDesktopTooltipClientKey[] = "DesktopTooltipClient"; } // namespace aura diff --git a/ui/aura/client/aura_constants.h b/ui/aura/client/aura_constants.h index 363c420..dbc321d 100644 --- a/ui/aura/client/aura_constants.h +++ b/ui/aura/client/aura_constants.h @@ -40,6 +40,10 @@ AURA_EXPORT extern const char kDesktopDragDropClientKey[]; // A property key to store the drag and drop delegate for a window. The type of // the value is |aura::WindowDragDropDelegate*|. AURA_EXPORT extern const char kDragDropDelegateKey[]; + +// A property key to store the tooltip client for the desktop. The type of +// the value is |aura::TooltipClient*|. +AURA_EXPORT extern const char kDesktopTooltipClientKey[]; } // namespace aura #endif // UI_AURA_CLIENT_AURA_CONSTANTS_H_ diff --git a/ui/aura/client/tooltip_client.h b/ui/aura/client/tooltip_client.h new file mode 100644 index 0000000..eb6db2c --- /dev/null +++ b/ui/aura/client/tooltip_client.h @@ -0,0 +1,32 @@ +// Copyright (c) 2011 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. + +#ifndef UI_AURA_CLIENT_TOOLTIP_CLIENT_H_ +#define UI_AURA_CLIENT_TOOLTIP_CLIENT_H_ +#pragma once + +#include "ui/aura/aura_export.h" +#include "ui/aura/event.h" +#include "ui/gfx/font.h" + +namespace aura { + +class Window; + +class AURA_EXPORT TooltipClient { + public: + // Returns the default font used by tooltips. + static gfx::Font GetDefaultFont(); + + // Returns the maximum width of the tooltip. |x| and |y| give the location + // the tooltip is to be displayed on in screen coordinates. + static int GetMaxWidth(int x, int y); + + // Informs the shell tooltip manager of change in tooltip for window |target|. + virtual void UpdateTooltip(Window* target) = 0; +}; + +} // namespace aura + +#endif // UI_AURA_CLIENT_TOOLTIP_CLIENT_H_ diff --git a/ui/aura_shell/aura_shell.gyp b/ui/aura_shell/aura_shell.gyp index 729ba1f..a15be0c 100644 --- a/ui/aura_shell/aura_shell.gyp +++ b/ui/aura_shell/aura_shell.gyp @@ -90,6 +90,8 @@ 'shell_accelerator_filter.h', 'shell_delegate.h', 'shell_factory.h', + 'shell_tooltip_manager.cc', + 'shell_tooltip_manager.h', 'shell_window_ids.h', 'show_state_controller.h', 'show_state_controller.cc', diff --git a/ui/aura_shell/shell.cc b/ui/aura_shell/shell.cc index 3e42cdc..32c84bd 100644 --- a/ui/aura_shell/shell.cc +++ b/ui/aura_shell/shell.cc @@ -26,6 +26,7 @@ #include "ui/aura_shell/shell_accelerator_filter.h" #include "ui/aura_shell/shell_delegate.h" #include "ui/aura_shell/shell_factory.h" +#include "ui/aura_shell/shell_tooltip_manager.h" #include "ui/aura_shell/shell_window_ids.h" #include "ui/aura_shell/stacking_controller.h" #include "ui/aura_shell/toplevel_layout_manager.h" @@ -121,6 +122,13 @@ Shell::Shell(ShellDelegate* delegate) Shell::~Shell() { RemoveDesktopEventFilter(accelerator_filter_.get()); + // ShellTooltipManager needs a valid shell instance. We delete it before + // deleting the shell |instance_|. + RemoveDesktopEventFilter(tooltip_manager_.get()); + aura::Desktop::GetInstance()->SetProperty(aura::kDesktopTooltipClientKey, + NULL); + tooltip_manager_.reset(); + // Drag drop controller needs a valid shell instance. We destroy it first. drag_drop_controller_.reset(); @@ -208,6 +216,12 @@ void Shell::Init() { accelerator_filter_.reset(new internal::ShellAcceleratorFilter); AddDesktopEventFilter(accelerator_filter_.get()); + // Initialize ShellTooltipManager + tooltip_manager_.reset(new ShellTooltipManager); + aura::Desktop::GetInstance()->SetProperty(aura::kDesktopTooltipClientKey, + static_cast<aura::TooltipClient*>(tooltip_manager_.get())); + AddDesktopEventFilter(tooltip_manager_.get()); + // Initialize drag drop controller. drag_drop_controller_.reset(new internal::DragDropController); aura::Desktop::GetInstance()->SetProperty(aura::kDesktopDragDropClientKey, diff --git a/ui/aura_shell/shell.h b/ui/aura_shell/shell.h index 228c00f..53a3c3b 100644 --- a/ui/aura_shell/shell.h +++ b/ui/aura_shell/shell.h @@ -29,6 +29,7 @@ namespace aura_shell { class Launcher; class ShellAcceleratorController; class ShellDelegate; +class ShellTooltipManager; namespace internal { class AppList; @@ -72,6 +73,10 @@ class AURA_SHELL_EXPORT Shell { return accelerator_controller_.get(); } + ShellTooltipManager* tooltip_manager() { + return tooltip_manager_.get(); + } + ShellDelegate* delegate() { return delegate_.get(); } Launcher* launcher() { return launcher_.get(); } @@ -113,6 +118,8 @@ class AURA_SHELL_EXPORT Shell { // An event filter that pre-handles global accelerators. scoped_ptr<internal::ShellAcceleratorFilter> accelerator_filter_; + scoped_ptr<ShellTooltipManager> tooltip_manager_; + DISALLOW_COPY_AND_ASSIGN(Shell); }; diff --git a/ui/aura_shell/shell_tooltip_manager.cc b/ui/aura_shell/shell_tooltip_manager.cc new file mode 100644 index 0000000..0544ca8 --- /dev/null +++ b/ui/aura_shell/shell_tooltip_manager.cc @@ -0,0 +1,281 @@ +// Copyright (c) 2011 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 "ui/aura_shell/shell_tooltip_manager.h" + +#include <vector> + +#include "base/location.h" +#include "base/string_split.h" +#include "base/time.h" +#include "ui/aura/client/aura_constants.h" +#include "ui/aura/event.h" +#include "ui/aura/window.h" +#include "ui/aura_shell/shell.h" +#include "ui/base/resource/resource_bundle.h" +#include "ui/base/text/text_elider.h" +#include "ui/gfx/font.h" +#include "ui/gfx/point.h" +#include "ui/gfx/rect.h" +#include "ui/gfx/screen.h" +#include "ui/views/background.h" +#include "ui/views/border.h" +#include "ui/views/controls/label.h" +#include "ui/views/widget/widget.h" + +namespace { + +SkColor kTooltipBackground = 0xFFFFFFCC; +SkColor kTooltipBorder = 0xFF000000; +int kTooltipBorderWidth = 1; +int kTooltipTimeoutMs = 500; + +// FIXME: get cursor offset from actual cursor size. +int kCursorOffsetX = 10; +int kCursorOffsetY = 15; + +// Maximum number of characters we allow in a tooltip. +const size_t kMaxTooltipLength = 1024; + +// Maximum number of lines we allow in the tooltip. +const size_t kMaxLines = 6; + +// Trims the tooltip to fit, setting |text| to the clipped result, +// |max_width| to the width (in pixels) of the clipped text and |line_count| +// to the number of lines of text in the tooltip. |x| and |y| give the +// location of the tooltip in screen coordinates. +void TrimTooltipToFit(string16* text, + int* max_width, + int* line_count, + int x, + int y) { + *max_width = 0; + *line_count = 0; + + // Clamp the tooltip length to kMaxTooltipLength so that we don't + // accidentally DOS the user with a mega tooltip. + if (text->length() > kMaxTooltipLength) + *text = text->substr(0, kMaxTooltipLength); + + // Determine the available width for the tooltip. + int available_width = aura::TooltipClient::GetMaxWidth(x, y); + + // Split the string into at most kMaxLines lines. + std::vector<string16> lines; + base::SplitString(*text, '\n', &lines); + if (lines.size() > kMaxLines) + lines.resize(kMaxLines); + *line_count = static_cast<int>(lines.size()); + + // Format each line to fit. + gfx::Font font = aura::TooltipClient::GetDefaultFont(); + string16 result; + for (std::vector<string16>::iterator i = lines.begin(); i != lines.end(); + ++i) { + string16 elided_text = ui::ElideText(*i, font, available_width, false); + *max_width = std::max(*max_width, font.GetStringWidth(elided_text)); + if (!result.empty()) + result.push_back('\n'); + result.append(elided_text); + } + *text = result; +} + +// Creates a widget of type TYPE_TOOLTIP +views::Widget* CreateTooltip() { + views::Widget* widget = new views::Widget; + views::Widget::InitParams params; + // For aura, since we set the type to TOOLTIP_TYPE, the widget will get + // auto-parented to the MenuAndTooltipsContainer. + params.type = views::Widget::InitParams::TYPE_TOOLTIP; + params.keep_on_top = true; + params.accept_events = false; + params.transparent = true; + params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; + widget->Init(params); + return widget; +} + +} // namespace + +namespace aura_shell { + +// Displays a widget with tooltip using a views::Label. +class ShellTooltipManager::Tooltip { + public: + Tooltip() { + label_.set_background( + views::Background::CreateSolidBackground(kTooltipBackground)); + label_.set_border( + views::Border::CreateSolidBorder(kTooltipBorderWidth, kTooltipBorder)); + label_.set_parent_owned(false); + widget_.reset(CreateTooltip()); + widget_->SetContentsView(&label_); + widget_->Activate(); + } + + ~Tooltip() { + widget_->Close(); + } + + // Updates the text on the tooltip and resizes to fit. + void SetText(string16 tooltip_text, gfx::Point location) { + int max_width, line_count; + TrimTooltipToFit(&tooltip_text, &max_width, &line_count, + location.x(), location.y()); + label_.SetText(tooltip_text); + + SetTooltipBounds(location, max_width + 2 * kTooltipBorderWidth, + label_.GetPreferredSize().height()); + } + + // Shows the tooltip. + void Show() { + widget_->Show(); + } + + // Hides the tooltip. + void Hide() { + widget_->Hide(); + } + + bool IsVisible() { + return widget_->IsVisible(); + } + + private: + views::Label label_; + scoped_ptr<views::Widget> widget_; + + // Adjusts the bounds given by the arguments to fit inside the desktop + // and applies the adjusted bounds to the label_. + void SetTooltipBounds(gfx::Point mouse_pos, + int tooltip_width, + int tooltip_height) { + gfx::Rect tooltip_rect(mouse_pos.x(), mouse_pos.y(), tooltip_width, + tooltip_height); + + tooltip_rect.Offset(kCursorOffsetX, kCursorOffsetY); + gfx::Rect monitor_bounds = + gfx::Screen::GetMonitorAreaNearestPoint(tooltip_rect.origin()); + widget_->SetBounds(tooltip_rect.AdjustToFit(monitor_bounds)); + } + +}; + +//////////////////////////////////////////////////////////////////////////////// +// ShellTooltipManager public: + +ShellTooltipManager::ShellTooltipManager() : aura::EventFilter(NULL), + tooltip_window_(NULL), + tooltip_(new Tooltip) { + tooltip_timer_.Start(FROM_HERE, + base::TimeDelta::FromMilliseconds(kTooltipTimeoutMs), + this, &ShellTooltipManager::TooltipTimerFired); +} + +ShellTooltipManager::~ShellTooltipManager() { + if (tooltip_window_) + tooltip_window_->RemoveObserver(this); +} + +void ShellTooltipManager::UpdateTooltip(aura::Window* target) { + // If tooltip is visible, we may want to hide it. If it is not, we are ok. + if (tooltip_window_ == target && tooltip_->IsVisible()) + UpdateIfRequired(); +} + +bool ShellTooltipManager::PreHandleKeyEvent(aura::Window* target, + aura::KeyEvent* event) { + return false; +} + +bool ShellTooltipManager::PreHandleMouseEvent(aura::Window* target, + aura::MouseEvent* event) { + switch (event->type()) { + case ui::ET_MOUSE_MOVED: + if (tooltip_window_ != target) { + if (tooltip_window_) + tooltip_window_->RemoveObserver(this); + tooltip_window_ = target; + tooltip_window_->AddObserver(this); + } + curr_mouse_loc_ = event->location(); + if (tooltip_timer_.IsRunning()) + tooltip_timer_.Reset(); + + if (tooltip_->IsVisible()) + UpdateIfRequired(); + break; + case ui::ET_MOUSE_PRESSED: + case ui::ET_MOUSE_RELEASED: + case ui::ET_MOUSE_DRAGGED: + case ui::ET_MOUSEWHEEL: + // Hide the tooltip for click, release, drag, wheel events. + if (tooltip_->IsVisible()) + tooltip_->Hide(); + break; + default: + break; + } + return false; +} + +ui::TouchStatus ShellTooltipManager::PreHandleTouchEvent( + aura::Window* target, + aura::TouchEvent* event) { + return ui::TOUCH_STATUS_UNKNOWN; +} + +void ShellTooltipManager::OnWindowDestroyed(aura::Window* window) { + if (tooltip_window_ == window) { + tooltip_window_->RemoveObserver(this); + tooltip_window_ = NULL; + } +} + +void ShellTooltipManager::TooltipTimerFired() { + UpdateIfRequired(); +} + +void ShellTooltipManager::UpdateIfRequired() { + string16 tooltip_text; + if (tooltip_window_) { + void* property = tooltip_window_->GetProperty(aura::kTooltipTextKey); + if (property) + tooltip_text = *static_cast<string16*>(property); + } + + if (tooltip_text_ != tooltip_text) { + tooltip_text_ = tooltip_text; + if (tooltip_text_.empty()) { + tooltip_->Hide(); + } else { + string16 tooltip_text(tooltip_text_); + gfx::Point widget_loc = curr_mouse_loc_; + widget_loc = widget_loc.Add(tooltip_window_->GetScreenBounds().origin()); + tooltip_->SetText(tooltip_text, widget_loc); + tooltip_->Show(); + } + } +} + +} // namespace aura_shell + +namespace aura { + +// static +gfx::Font TooltipClient::GetDefaultFont() { + return ui::ResourceBundle::GetSharedInstance().GetFont( + ui::ResourceBundle::BaseFont); +} + +// static +int TooltipClient::GetMaxWidth(int x, int y) { + gfx::Rect monitor_bounds = + gfx::Screen::GetMonitorAreaNearestPoint(gfx::Point(x, y)); + return (monitor_bounds.width() + 1) / 2; +} + +} // namespace aura diff --git a/ui/aura_shell/shell_tooltip_manager.h b/ui/aura_shell/shell_tooltip_manager.h new file mode 100644 index 0000000..a9b301b --- /dev/null +++ b/ui/aura_shell/shell_tooltip_manager.h @@ -0,0 +1,71 @@ +// Copyright (c) 2011 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. + +#ifndef UI_AURA_SHELL_SHELL_TOOLTIP_MANAGER_H_ +#define UI_AURA_SHELL_SHELL_TOOLTIP_MANAGER_H_ +#pragma once + +#include "base/memory/scoped_ptr.h" +#include "base/string16.h" +#include "base/timer.h" +#include "ui/aura/client/tooltip_client.h" +#include "ui/aura/event_filter.h" +#include "ui/aura/window_observer.h" +#include "ui/aura_shell/aura_shell_export.h" +#include "ui/gfx/point.h" + +namespace aura { +class KeyEvent; +class MouseEvent; +class TouchEvent; +class Window; +} + +namespace aura_shell { + +// ShellTooltipManager provides tooltip functionality for aura shell. +class AURA_SHELL_EXPORT ShellTooltipManager : public aura::TooltipClient, + public aura::EventFilter, + public aura::WindowObserver { + public: + ShellTooltipManager(); + virtual ~ShellTooltipManager(); + + // Overridden from aura::TooltipClient. + void UpdateTooltip(aura::Window* target); + + // Overridden from aura::EventFilter. + virtual bool PreHandleKeyEvent(aura::Window* target, + aura::KeyEvent* event) OVERRIDE; + virtual bool PreHandleMouseEvent(aura::Window* target, + aura::MouseEvent* event) OVERRIDE; + virtual ui::TouchStatus PreHandleTouchEvent(aura::Window* target, + aura::TouchEvent* event) OVERRIDE; + + // Overridden from aura::WindowObserver. + virtual void OnWindowDestroyed(aura::Window* window) OVERRIDE; + + private: + class Tooltip; + + void TooltipTimerFired(); + + // Updates the tooltip if required (if there is any change in the tooltip + // text or the aura::Window. + void UpdateIfRequired(); + + aura::Window* tooltip_window_; + string16 tooltip_text_; + scoped_ptr<Tooltip> tooltip_; + + base::RepeatingTimer<ShellTooltipManager> tooltip_timer_; + + gfx::Point curr_mouse_loc_; + + DISALLOW_COPY_AND_ASSIGN(ShellTooltipManager); +}; + +} // namespace aura_shell + +#endif // UI_AURA_SHELL_SHELL_TOOLTIP_MANAGER_H_ diff --git a/ui/views/test/test_tooltip_client.cc b/ui/views/test/test_tooltip_client.cc new file mode 100644 index 0000000..e7ea34d --- /dev/null +++ b/ui/views/test/test_tooltip_client.cc @@ -0,0 +1,28 @@ +// Copyright (c) 2011 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 "ui/views/test/test_tooltip_client.h" + +#include "ui/base/resource/resource_bundle.h" +#include "ui/gfx/font.h" +#include "ui/gfx/point.h" +#include "ui/gfx/rect.h" +#include "ui/gfx/screen.h" + +namespace aura { + +// static +gfx::Font TooltipClient::GetDefaultFont() { + return ui::ResourceBundle::GetSharedInstance().GetFont( + ui::ResourceBundle::BaseFont); +} + +// static +int TooltipClient::GetMaxWidth(int x, int y) { + gfx::Rect monitor_bounds = + gfx::Screen::GetMonitorAreaNearestPoint(gfx::Point(x, y)); + return (monitor_bounds.width() + 1) / 2; +} + +} // namespace aura diff --git a/ui/views/test/test_tooltip_client.h b/ui/views/test/test_tooltip_client.h new file mode 100644 index 0000000..f6502ed --- /dev/null +++ b/ui/views/test/test_tooltip_client.h @@ -0,0 +1,32 @@ +// Copyright (c) 2011 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. + +#ifndef UI_AURA_TEST_TEST_TOOLTIP_CLIENT_H_ +#define UI_AURA_TEST_TEST_TOOLTIP_CLIENT_H_ +#pragma once + +#include "base/compiler_specific.h" +#include "ui/aura/client/tooltip_client.h" + +namespace aura { +class Window; + +namespace test { + +class TestTooltipClient : public TooltipClient { + public: + TestTooltipClient(); + virtual ~TestTooltipClient(); + + private: + // Overridden from TooltipClient: + virtual void UpdateTooltip(Window* target) OVERRIDE {} + + DISALLOW_COPY_AND_ASSIGN(TestTooltipClient); +}; + +} // namespace test +} // namespace aura + +#endif // UI_AURA_TEST_TEST_TOOLTIP_CLIENT_H_ diff --git a/ui/views/widget/native_widget_aura.cc b/ui/views/widget/native_widget_aura.cc index bcb14a7..8308a45 100644 --- a/ui/views/widget/native_widget_aura.cc +++ b/ui/views/widget/native_widget_aura.cc @@ -22,7 +22,8 @@ #include "ui/gfx/screen.h" #include "ui/views/widget/drop_helper.h" #include "ui/views/widget/native_widget_delegate.h" -#include "ui/views/widget/tooltip_manager_views.h" +#include "ui/views/widget/tooltip_manager_aura.h" +#include "ui/views/widget/widget_delegate.h" #if defined(OS_WIN) #include "base/win/scoped_gdi_object.h" @@ -156,10 +157,8 @@ void NativeWidgetAura::InitNativeWidget(const Widget::InitParams& params) { delegate_->OnNativeWidgetSizeChanged(params.bounds.size()); can_activate_ = params.can_activate; DCHECK(GetWidget()->GetRootView()); - if (params.type != Widget::InitParams::TYPE_TOOLTIP && !params.child) { - views::TooltipManagerViews* manager = new views::TooltipManagerViews( - GetWidget()->GetRootView()); - tooltip_manager_.reset(manager); + if (params.type != Widget::InitParams::TYPE_TOOLTIP) { + tooltip_manager_.reset(new views::TooltipManagerAura(this)); } drop_helper_.reset(new DropHelper(GetWidget()->GetRootView())); @@ -598,13 +597,11 @@ bool NativeWidgetAura::OnMouseEvent(aura::MouseEvent* event) { DCHECK(window_->IsVisible()); if (event->type() == ui::ET_MOUSEWHEEL) { MouseWheelEvent wheel_event(event); - if (tooltip_manager_.get()) - tooltip_manager_->UpdateForMouseEvent(wheel_event); return delegate_->OnMouseEvent(wheel_event); } MouseEvent mouse_event(event); if (tooltip_manager_.get()) - tooltip_manager_->UpdateForMouseEvent(mouse_event); + tooltip_manager_->UpdateTooltip(); return delegate_->OnMouseEvent(mouse_event); } diff --git a/ui/views/widget/native_widget_aura.h b/ui/views/widget/native_widget_aura.h index a911fec..16c1bef 100644 --- a/ui/views/widget/native_widget_aura.h +++ b/ui/views/widget/native_widget_aura.h @@ -24,7 +24,7 @@ class Font; namespace views { class DropHelper; -class TooltipManagerViews; +class TooltipManagerAura; class VIEWS_EXPORT NativeWidgetAura : public internal::NativeWidgetPrivate, public aura::WindowDelegate, @@ -168,7 +168,7 @@ class VIEWS_EXPORT NativeWidgetAura : public internal::NativeWidgetPrivate, gfx::NativeCursor cursor_; - scoped_ptr<TooltipManagerViews> tooltip_manager_; + scoped_ptr<TooltipManagerAura> tooltip_manager_; scoped_ptr<DesktopObserverImpl> desktop_observer_; diff --git a/ui/views/widget/tooltip_manager_aura.cc b/ui/views/widget/tooltip_manager_aura.cc new file mode 100644 index 0000000..0847ed3 --- /dev/null +++ b/ui/views/widget/tooltip_manager_aura.cc @@ -0,0 +1,107 @@ +// Copyright (c) 2011 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 "base/logging.h" +#include "ui/aura/client/aura_constants.h" +#include "ui/aura/client/tooltip_client.h" +#include "ui/aura/desktop.h" +#include "ui/base/resource/resource_bundle.h" +#include "ui/gfx/font.h" +#include "ui/gfx/rect.h" +#include "ui/gfx/screen.h" +#include "ui/views/widget/native_widget_aura.h" +#include "ui/views/widget/tooltip_manager_aura.h" + +namespace views { + +// static +int TooltipManager::GetTooltipHeight() { + // Not used for linux and chromeos. + NOTIMPLEMENTED(); + return 0; +} + +// static +gfx::Font TooltipManager::GetDefaultFont() { + return aura::TooltipClient::GetDefaultFont(); +} + +// static +int TooltipManager::GetMaxWidth(int x, int y) { + return aura::TooltipClient::GetMaxWidth(x, y); +} + +//////////////////////////////////////////////////////////////////////////////// +// TooltipManagerAura public: + +TooltipManagerAura::TooltipManagerAura(NativeWidgetAura* native_widget_aura) + : native_widget_aura_(native_widget_aura) { + native_widget_aura_->GetNativeView()->SetProperty(aura::kTooltipTextKey, + &tooltip_text_); +} + +TooltipManagerAura::~TooltipManagerAura() { + native_widget_aura_->GetNativeView()->SetProperty(aura::kTooltipTextKey, + NULL); +} + +//////////////////////////////////////////////////////////////////////////////// +// TooltipManagerAura, TooltipManager implementation: + +void TooltipManagerAura::UpdateTooltip() { + void* property = aura::Desktop::GetInstance()->GetProperty( + aura::kDesktopTooltipClientKey); + if (property) { + gfx::Point view_point = aura::Desktop::GetInstance()->last_mouse_location(); + aura::Window::ConvertPointToWindow(aura::Desktop::GetInstance(), + native_widget_aura_->GetNativeView(), &view_point); + View* view = GetViewUnderPoint(view_point); + if (view) { + View::ConvertPointFromWidget(view, &view_point); + if (!view->GetTooltipText(view_point, &tooltip_text_)) + tooltip_text_.clear(); + } else { + tooltip_text_.clear(); + } + aura::TooltipClient* tc = static_cast<aura::TooltipClient*>(property); + tc->UpdateTooltip(native_widget_aura_->GetNativeView()); + } +} + +void TooltipManagerAura::TooltipTextChanged(View* view) { + void* property = aura::Desktop::GetInstance()->GetProperty( + aura::kDesktopTooltipClientKey); + if (property) { + gfx::Point view_point = aura::Desktop::GetInstance()->last_mouse_location(); + aura::Window::ConvertPointToWindow(aura::Desktop::GetInstance(), + native_widget_aura_->GetNativeView(), &view_point); + View* target = GetViewUnderPoint(view_point); + if (target != view) + return; + if (target) { + View::ConvertPointFromWidget(view, &view_point); + if (!view->GetTooltipText(view_point, &tooltip_text_)) + tooltip_text_.clear(); + } else { + tooltip_text_.clear(); + } + aura::TooltipClient* tc = static_cast<aura::TooltipClient*>(property); + tc->UpdateTooltip(native_widget_aura_->GetNativeView()); + } +} + +void TooltipManagerAura::ShowKeyboardTooltip(View* view) { + NOTREACHED(); +} + +void TooltipManagerAura::HideKeyboardTooltip() { + NOTREACHED(); +} + +View* TooltipManagerAura::GetViewUnderPoint(const gfx::Point& point) { + View* root_view = native_widget_aura_->GetWidget()->GetRootView(); + return root_view->GetEventHandlerForPoint(point); +} + +} // namespace views. diff --git a/ui/views/widget/tooltip_manager_aura.h b/ui/views/widget/tooltip_manager_aura.h new file mode 100644 index 0000000..0ee7d6e --- /dev/null +++ b/ui/views/widget/tooltip_manager_aura.h @@ -0,0 +1,42 @@ +// Copyright (c) 2011 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. + +#ifndef UI_VIEWS_WIDGET_TOOLTIP_MANAGER_AURA_H_ +#define UI_VIEWS_WIDGET_TOOLTIP_MANAGER_AURA_H_ +#pragma once + +#include "base/compiler_specific.h" +#include "base/string16.h" +#include "ui/gfx/point.h" +#include "ui/views/widget/tooltip_manager.h" + +namespace views { + +class NativeWidgetAura; +class View; + +// TooltipManager implementation for Aura. +class TooltipManagerAura : public TooltipManager { + public: + explicit TooltipManagerAura(NativeWidgetAura* native_widget_aura); + virtual ~TooltipManagerAura(); + + // TooltipManager. + virtual void UpdateTooltip() OVERRIDE; + virtual void TooltipTextChanged(View* view) OVERRIDE; + virtual void ShowKeyboardTooltip(View* view) OVERRIDE; + virtual void HideKeyboardTooltip() OVERRIDE; + + private: + View* GetViewUnderPoint(const gfx::Point& point); + + NativeWidgetAura* native_widget_aura_; + string16 tooltip_text_; + + DISALLOW_COPY_AND_ASSIGN(TooltipManagerAura); +}; + +} // namespace views + +#endif // UI_VIEWS_WIDGET_TOOLTIP_MANAGER_AURA_H_ diff --git a/ui/views/widget/tooltip_manager_views.cc b/ui/views/widget/tooltip_manager_views.cc deleted file mode 100644 index 3b2d677..0000000 --- a/ui/views/widget/tooltip_manager_views.cc +++ /dev/null @@ -1,239 +0,0 @@ -// Copyright (c) 2011 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 "ui/views/widget/tooltip_manager_views.h" - -#if defined(USE_X11) -#include <X11/Xlib.h> -#include <X11/extensions/XInput2.h> -#endif - -#if defined(OS_WIN) -#include <windowsx.h> -#endif - -#include "base/event_types.h" -#include "base/logging.h" -#include "base/time.h" -#include "base/utf_string_conversions.h" -#include "third_party/skia/include/core/SkColor.h" -#if defined(USE_AURA) -#include "ui/aura/client/aura_constants.h" -#include "ui/aura/event.h" -#include "ui/aura/window.h" -#endif -#include "ui/base/resource/resource_bundle.h" -#include "ui/gfx/font.h" -#include "ui/gfx/screen.h" -#include "ui/views/background.h" -#include "ui/views/border.h" -#include "ui/views/events/event.h" -#include "ui/views/focus/focus_manager.h" -#include "ui/views/view.h" -#include "ui/views/widget/native_widget.h" - -namespace { -SkColor kTooltipBackground = 0xFF7F7F00; -int kTooltipTimeoutMs = 500; - -// FIXME: get cursor offset from actual cursor size. -int kCursorOffsetX = 10; -int kCursorOffsetY = 15; -} - -namespace views { - -// static -int TooltipManager::GetTooltipHeight() { - // Not used for linux and chromeos. - NOTREACHED(); - return 0; -} - -// static -gfx::Font TooltipManager::GetDefaultFont() { - return ResourceBundle::GetSharedInstance().GetFont(ResourceBundle::BaseFont); -} - -// static -int TooltipManager::GetMaxWidth(int x, int y) { - // FIXME: change this. This is for now just copied from TooltipManagerGtk. - - // We always display the tooltip inside the root view. So the max width is - // the width of the view. - gfx::Rect monitor_bounds = - gfx::Screen::GetMonitorAreaNearestPoint(gfx::Point(x, y)); - // GtkLabel (gtk_label_ensure_layout) forces wrapping at this size. We mirror - // the size here otherwise tooltips wider than the size used by gtklabel end - // up with extraneous empty lines. - return monitor_bounds.width() == 0 ? 800 : (monitor_bounds.width() + 1) / 2; -} - -TooltipManagerViews::TooltipManagerViews(views::View* root_view) - : root_view_(root_view), - tooltip_view_(NULL) { - tooltip_label_.set_background( - views::Background::CreateSolidBackground(kTooltipBackground)); - tooltip_widget_.reset(CreateTooltip()); - tooltip_widget_->SetContentsView(&tooltip_label_); - tooltip_widget_->Activate(); - tooltip_widget_->SetAlwaysOnTop(true); -} - -TooltipManagerViews::~TooltipManagerViews() { - tooltip_widget_->CloseNow(); -} - -void TooltipManagerViews::UpdateForMouseEvent(const MouseEvent& event) { - switch (event.type()) { - case ui::ET_MOUSE_EXITED: - // Mouse is exiting this widget. Stop showing the tooltip and the timer. - if (tooltip_timer_.IsRunning()) - tooltip_timer_.Stop(); - if (tooltip_widget_->IsVisible()) - tooltip_widget_->Hide(); - break; - case ui::ET_MOUSE_ENTERED: - // Mouse just entered this widget. Start the timer to show the tooltip. - if (tooltip_timer_.IsRunning()) - tooltip_timer_.Stop(); - tooltip_timer_.Start(FROM_HERE, - base::TimeDelta::FromMilliseconds(kTooltipTimeoutMs), - this, &TooltipManagerViews::TooltipTimerFired); - break; - case ui::ET_MOUSE_MOVED: - OnMouseMoved(event.location().x(), event.location().y()); - break; - case ui::ET_MOUSE_PRESSED: - case ui::ET_MOUSE_RELEASED: - case ui::ET_MOUSE_DRAGGED: - case ui::ET_MOUSEWHEEL: - // Hide the tooltip for click, release, drag, wheel events. - if (tooltip_widget_->IsVisible()) - tooltip_widget_->Hide(); - break; - default: - NOTIMPLEMENTED(); - } -} - -void TooltipManagerViews::UpdateTooltip() { - UpdateIfRequired(curr_mouse_pos_.x(), curr_mouse_pos_.y(), false); -} - -void TooltipManagerViews::TooltipTextChanged(View* view) { - if (tooltip_widget_->IsVisible()) - UpdateIfRequired(curr_mouse_pos_.x(), curr_mouse_pos_.y(), false); -} - -void TooltipManagerViews::ShowKeyboardTooltip(View* view) { - NOTREACHED(); -} - -void TooltipManagerViews::HideKeyboardTooltip() { - NOTREACHED(); -} - -void TooltipManagerViews::TooltipTimerFired() { - UpdateIfRequired(curr_mouse_pos_.x(), curr_mouse_pos_.y(), false); -} - -View* TooltipManagerViews::GetViewForTooltip(int x, int y, bool for_keyboard) { - View* view = NULL; - if (!for_keyboard) { - // Convert x,y from screen coordinates to |root_view_| coordinates. - gfx::Point point(x, y); - View::ConvertPointFromWidget(root_view_, &point); - view = root_view_->GetEventHandlerForPoint(point); - } else { - FocusManager* focus_manager = root_view_->GetFocusManager(); - if (focus_manager) - view = focus_manager->GetFocusedView(); - } - return view; -} - -void TooltipManagerViews::UpdateIfRequired(int x, int y, bool for_keyboard) { - View* view = GetViewForTooltip(x, y, for_keyboard); - string16 tooltip_text; - if (view) - view->GetTooltipText(gfx::Point(x, y), &tooltip_text); - -#if defined(USE_AURA) - // In aura, and aura::Window can also have a tooltip. If the view doesnot have - // a tooltip, we must also check for the aura::Window underneath the cursor. - if (tooltip_text.empty()) { - aura::Window* root = reinterpret_cast<aura::Window*>( - root_view_->GetWidget()->GetNativeView()); - if (root) { - aura::Window* window = root->GetEventHandlerForPoint(gfx::Point(x, y)); - if (window) { - void* property = window->GetProperty(aura::kTooltipTextKey); - if (property) - tooltip_text = *reinterpret_cast<string16*>(property); - } - } - } -#endif - - if (tooltip_view_ != view || tooltip_text_ != tooltip_text) { - tooltip_view_ = view; - tooltip_text_ = tooltip_text; - Update(); - } -} - -void TooltipManagerViews::Update() { - if (tooltip_text_.empty()) { - tooltip_widget_->Hide(); - } else { - int max_width, line_count; - string16 tooltip_text(tooltip_text_); - TrimTooltipToFit(&tooltip_text, &max_width, &line_count, - curr_mouse_pos_.x(), curr_mouse_pos_.y()); - tooltip_label_.SetText(tooltip_text); - - SetTooltipBounds(curr_mouse_pos_, max_width, - tooltip_label_.GetPreferredSize().height()); - tooltip_widget_->Show(); - } -} - -void TooltipManagerViews::SetTooltipBounds(gfx::Point mouse_pos, - int tooltip_width, - int tooltip_height) { - gfx::Rect tooltip_rect(mouse_pos.x(), mouse_pos.y(), tooltip_width, - tooltip_height); - - tooltip_rect.Offset(kCursorOffsetX, kCursorOffsetY); - gfx::Rect monitor_bounds = - gfx::Screen::GetMonitorAreaNearestPoint(tooltip_rect.origin()); - tooltip_widget_->SetBounds(tooltip_rect.AdjustToFit(monitor_bounds)); -} - -Widget* TooltipManagerViews::CreateTooltip() { - Widget* widget = new Widget; - Widget::InitParams params; - // For aura, since we set the type to TOOLTIP_TYPE, the widget will get - // auto-parented to the MenuAndTooltipsContainer. - params.type = Widget::InitParams::TYPE_TOOLTIP; - params.keep_on_top = true; - params.accept_events = false; - params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; - widget->Init(params); - widget->SetOpacity(0xFF); - return widget; -} - -void TooltipManagerViews::OnMouseMoved(int x, int y) { - if (tooltip_timer_.IsRunning()) - tooltip_timer_.Reset(); - curr_mouse_pos_.SetPoint(x, y); - - // If tooltip is visible, we may want to hide it. If it is not, we are ok. - if (tooltip_widget_->IsVisible()) - UpdateIfRequired(curr_mouse_pos_.x(), curr_mouse_pos_.y(), false); -} - -} // namespace views diff --git a/ui/views/widget/tooltip_manager_views.h b/ui/views/widget/tooltip_manager_views.h deleted file mode 100644 index 1a6ef18..0000000 --- a/ui/views/widget/tooltip_manager_views.h +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright (c) 2011 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. - -#ifndef UI_VIEWS_WIDGET_TOOLTIP_MANAGER_VIEWS_H_ -#define UI_VIEWS_WIDGET_TOOLTIP_MANAGER_VIEWS_H_ -#pragma once - -#include "base/message_loop.h" -#include "base/timer.h" -#include "ui/views/controls/label.h" -#include "ui/views/view.h" -#include "ui/views/widget/native_widget.h" -#include "ui/views/widget/tooltip_manager.h" -#include "ui/views/widget/widget_delegate.h" - -#if defined(USE_X11) -typedef union _XEvent XEvent; -#endif - -namespace views { - -class MouseEvent; -class Widget; - -// TooltipManager implementation for Views. -class TooltipManagerViews : public TooltipManager { - public: - explicit TooltipManagerViews(views::View* root_view); - virtual ~TooltipManagerViews(); - - // Updates the state of the tooltip based on the mouse event. The mouse event - // is the same event that goes to a Widget (i.e. it is in the Widget's - // coordinate system). - void UpdateForMouseEvent(const MouseEvent& event); - - // TooltipManager. - virtual void UpdateTooltip() OVERRIDE; - virtual void TooltipTextChanged(View* view) OVERRIDE; - virtual void ShowKeyboardTooltip(View* view) OVERRIDE; - virtual void HideKeyboardTooltip() OVERRIDE; - - private: - void TooltipTimerFired(); - View* GetViewForTooltip(int x, int y, bool for_keyboard); - - // Updates the tooltip if required (if there is any change in the tooltip - // text or the view. - void UpdateIfRequired(int x, int y, bool for_keyboard); - - // Updates the tooltip. Gets the tooltip text from tooltip_view_ and displays - // it at the current mouse position. - void Update(); - - // Adjusts the bounds given by the arguments to fit inside the parent view - // and applies the adjusted bounds to the tooltip_label_. - void SetTooltipBounds(gfx::Point mouse_pos, int tooltip_width, - int tooltip_height); - - // Creates a widget of type TYPE_TOOLTIP - Widget* CreateTooltip(); - - // Invoked when the mose moves. - void OnMouseMoved(int x, int y); - - scoped_ptr<Widget> tooltip_widget_; - views::View* root_view_; - View* tooltip_view_; - string16 tooltip_text_; - Label tooltip_label_; - - gfx::Point curr_mouse_pos_; - base::RepeatingTimer<TooltipManagerViews> tooltip_timer_; - - DISALLOW_COPY_AND_ASSIGN(TooltipManagerViews); -}; - -} // namespace views - -#endif // UI_VIEWS_WIDGET_TOOLTIP_MANAGER_VIEWS_H_ diff --git a/views/views.gyp b/views/views.gyp index 3a47930..140822e 100644 --- a/views/views.gyp +++ b/views/views.gyp @@ -343,10 +343,10 @@ '../ui/views/widget/gtk_views_window.h', '../ui/views/widget/root_view.cc', '../ui/views/widget/root_view.h', + '../ui/views/widget/tooltip_manager_aura.cc', + '../ui/views/widget/tooltip_manager_aura.h', '../ui/views/widget/tooltip_manager_gtk.cc', '../ui/views/widget/tooltip_manager_gtk.h', - '../ui/views/widget/tooltip_manager_views.cc', - '../ui/views/widget/tooltip_manager_views.h', '../ui/views/widget/tooltip_manager_win.cc', '../ui/views/widget/tooltip_manager_win.h', '../ui/views/widget/tooltip_manager.cc', @@ -531,6 +531,8 @@ '../ui/views/focus/focus_traversal_unittest.cc', '../ui/views/layout/box_layout_unittest.cc', '../ui/views/layout/grid_layout_unittest.cc', + '../ui/views/test/test_tooltip_client.cc', + '../ui/views/test/test_tooltip_client.h', '../ui/views/test/test_views_delegate.cc', '../ui/views/test/test_views_delegate.h', '../ui/views/test/views_test_base.cc', @@ -587,6 +589,7 @@ 'sources/': [ ['exclude', '../ui/aura/test/test_desktop_delegate.cc'], ['exclude', '../ui/aura/test/test_desktop_delegate.h'], + ['exclude', '../ui/views/test/test_tooltip_client.cc'], ], }], ], |