Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "ui/views/corewm/tooltip_aura.h" | 5 #include "ui/views/corewm/tooltip_aura.h" |
| 6 | 6 |
| 7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
| 8 #include "base/strings/string_split.h" | 8 #include "base/strings/string_split.h" |
| 9 #include "ui/aura/window.h" | 9 #include "ui/aura/window.h" |
| 10 #include "ui/aura/window_tree_host.h" | 10 #include "ui/aura/window_tree_host.h" |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 140 *width = std::max(*width, line_width); | 140 *width = std::max(*width, line_width); |
| 141 result.append(*l); | 141 result.append(*l); |
| 142 } | 142 } |
| 143 } | 143 } |
| 144 *text = result; | 144 *text = result; |
| 145 } | 145 } |
| 146 | 146 |
| 147 int TooltipAura::GetMaxWidth(const gfx::Point& location) const { | 147 int TooltipAura::GetMaxWidth(const gfx::Point& location) const { |
| 148 // TODO(varunjain): implementation duplicated in tooltip_manager_aura. Figure | 148 // TODO(varunjain): implementation duplicated in tooltip_manager_aura. Figure |
| 149 // out a way to merge. | 149 // out a way to merge. |
| 150 gfx::Rect display_bounds = GetBoundsForTooltip(location); | 150 gfx::Screen* screen = gfx::Screen::GetScreenByType(screen_type_); |
| 151 gfx::Rect display_bounds(screen->GetDisplayNearestPoint(location).bounds()); | |
| 151 return (display_bounds.width() + 1) / 2; | 152 return (display_bounds.width() + 1) / 2; |
| 152 } | 153 } |
| 153 | 154 |
| 154 gfx::Rect TooltipAura::GetBoundsForTooltip( | |
| 155 const gfx::Point& origin) const { | |
| 156 DCHECK(tooltip_window_); | |
| 157 gfx::Rect widget_bounds; | |
| 158 // For Desktop aura we constrain the tooltip to the bounds of the Widget | |
| 159 // (which comes from the RootWindow). | |
| 160 if (screen_type_ == gfx::SCREEN_TYPE_NATIVE && | |
| 161 gfx::SCREEN_TYPE_NATIVE != gfx::SCREEN_TYPE_ALTERNATE) { | |
| 162 widget_bounds = tooltip_window_->GetHost()->GetBounds(); | |
| 163 } | |
| 164 gfx::Screen* screen = gfx::Screen::GetScreenByType(screen_type_); | |
| 165 gfx::Rect bounds(screen->GetDisplayNearestPoint(origin).bounds()); | |
| 166 if (!widget_bounds.IsEmpty()) | |
| 167 bounds.Intersect(widget_bounds); | |
| 168 return bounds; | |
| 169 } | |
| 170 | |
| 171 void TooltipAura::SetTooltipBounds(const gfx::Point& mouse_pos, | 155 void TooltipAura::SetTooltipBounds(const gfx::Point& mouse_pos, |
| 172 int tooltip_width, | 156 int tooltip_width, |
| 173 int tooltip_height) { | 157 int tooltip_height) { |
| 174 gfx::Rect tooltip_rect(mouse_pos.x(), mouse_pos.y(), tooltip_width, | 158 gfx::Rect tooltip_rect(mouse_pos.x(), mouse_pos.y(), tooltip_width, |
| 175 tooltip_height); | 159 tooltip_height); |
| 176 | 160 |
| 177 tooltip_rect.Offset(kCursorOffsetX, kCursorOffsetY); | 161 tooltip_rect.Offset(kCursorOffsetX, kCursorOffsetY); |
| 178 gfx::Rect display_bounds = GetBoundsForTooltip(mouse_pos); | 162 gfx::Screen* screen = gfx::Screen::GetScreenByType(screen_type_); |
| 163 gfx::Rect display_bounds(screen->GetDisplayNearestPoint(mouse_pos).bounds()); | |
| 179 | 164 |
| 180 // If tooltip is out of bounds on the x axis, we simply shift it | 165 // If tooltip is out of bounds on the x axis, we simply shift it |
| 181 // horizontally by the offset. | 166 // horizontally by the offset. |
| 182 if (tooltip_rect.right() > display_bounds.right()) { | 167 if (tooltip_rect.right() > display_bounds.right()) { |
| 183 int h_offset = tooltip_rect.right() - display_bounds.right(); | 168 int h_offset = tooltip_rect.right() - display_bounds.right(); |
| 184 tooltip_rect.Offset(-h_offset, 0); | 169 tooltip_rect.Offset(-h_offset, 0); |
| 185 } | 170 } |
| 186 | 171 |
| 187 // If tooltip is out of bounds on the y axis, we flip it to appear above the | 172 // If tooltip is out of bounds on the y axis, we flip it to appear above the |
| 188 // mouse cursor instead of below. | 173 // mouse cursor instead of below. |
| 189 if (tooltip_rect.bottom() > display_bounds.bottom()) | 174 if (tooltip_rect.bottom() > display_bounds.bottom()) |
| 190 tooltip_rect.set_y(mouse_pos.y() - tooltip_height); | 175 tooltip_rect.set_y(mouse_pos.y() - tooltip_height); |
| 191 | 176 |
| 192 tooltip_rect.AdjustToFit(display_bounds); | 177 tooltip_rect.AdjustToFit(display_bounds); |
| 193 widget_->SetBounds(tooltip_rect); | 178 widget_->SetBounds(tooltip_rect); |
| 194 } | 179 } |
| 195 | 180 |
| 196 void TooltipAura::CreateWidget() { | |
| 197 if (widget_) { | |
| 198 // If the window for which the tooltip is being displayed changes and if the | |
| 199 // tooltip window and the tooltip widget belong to different rootwindows | |
| 200 // then we need to recreate the tooltip widget under the active root window | |
| 201 // hierarchy to get it to display. | |
| 202 if (widget_->GetNativeWindow()->GetRootWindow() == | |
| 203 tooltip_window_->GetRootWindow()) | |
| 204 return; | |
| 205 DestroyWidget(); | |
| 206 } | |
| 207 widget_ = CreateTooltipWidget(tooltip_window_); | |
| 208 widget_->SetContentsView(&label_); | |
| 209 widget_->AddObserver(this); | |
| 210 } | |
| 211 | |
| 212 void TooltipAura::DestroyWidget() { | 181 void TooltipAura::DestroyWidget() { |
| 213 if (widget_) { | 182 if (widget_) { |
| 214 widget_->RemoveObserver(this); | 183 widget_->RemoveObserver(this); |
| 215 widget_->Close(); | 184 widget_->Close(); |
| 216 widget_ = NULL; | 185 widget_ = NULL; |
| 217 } | 186 } |
| 218 } | 187 } |
| 219 | 188 |
| 220 void TooltipAura::SetText(aura::Window* window, | 189 void TooltipAura::SetText(aura::Window* window, |
| 221 const base::string16& tooltip_text, | 190 const base::string16& tooltip_text, |
| 222 const gfx::Point& location) { | 191 const gfx::Point& location) { |
| 223 tooltip_window_ = window; | 192 tooltip_window_ = window; |
| 224 int max_width, line_count; | 193 int max_width, line_count; |
| 225 base::string16 trimmed_text(tooltip_text); | 194 base::string16 trimmed_text(tooltip_text); |
| 226 TrimTooltipToFit(label_.font_list(), GetMaxWidth(location), &trimmed_text, | 195 TrimTooltipToFit(label_.font_list(), GetMaxWidth(location), &trimmed_text, |
| 227 &max_width, &line_count); | 196 &max_width, &line_count); |
| 228 label_.SetText(trimmed_text); | 197 label_.SetText(trimmed_text); |
| 229 | 198 |
| 230 int width = max_width + 2 * kTooltipHorizontalPadding; | 199 int width = max_width + 2 * kTooltipHorizontalPadding; |
| 231 int height = label_.GetHeightForWidth(max_width) + | 200 int height = label_.GetHeightForWidth(max_width) + |
| 232 2 * kTooltipVerticalPadding; | 201 2 * kTooltipVerticalPadding; |
| 233 CreateWidget(); | 202 |
| 203 if (!widget_) { | |
|
pkotwicz
2014/05/16 02:22:53
Is it worth adding a comment as to why we want to
Elliot Glaysher
2014/05/16 19:39:42
I'm not sure if this is safe; IIRC, chromeos can h
oshima
2014/05/16 19:49:49
yes, erg@ is correct.
https://code.google.com/p/c
pkotwicz
2014/05/16 20:02:16
My understanding is that views::Widget::SetBounds(
Elliot Glaysher
2014/05/16 20:07:20
Huh, it looks like you're right. ash::ScreenPositi
oshima
2014/05/16 20:11:12
It does, but doe it based on the best matching dis
| |
| 204 widget_ = CreateTooltipWidget(tooltip_window_); | |
| 205 widget_->SetContentsView(&label_); | |
| 206 widget_->AddObserver(this); | |
| 207 } | |
| 208 | |
| 234 SetTooltipBounds(location, width, height); | 209 SetTooltipBounds(location, width, height); |
| 235 | 210 |
| 211 ui::NativeTheme* native_theme = widget_->GetNativeTheme(); | |
| 236 label_.set_background( | 212 label_.set_background( |
| 237 views::Background::CreateSolidBackground( | 213 views::Background::CreateSolidBackground( |
| 238 widget_->GetNativeTheme()->GetSystemColor( | 214 native_theme->GetSystemColor( |
| 239 ui::NativeTheme::kColorId_TooltipBackground))); | 215 ui::NativeTheme::kColorId_TooltipBackground))); |
| 216 | |
| 217 label_.SetAutoColorReadabilityEnabled(false); | |
| 218 label_.SetEnabledColor(native_theme->GetSystemColor( | |
| 219 ui::NativeTheme::kColorId_TooltipText)); | |
| 240 } | 220 } |
| 241 | 221 |
| 242 void TooltipAura::Show() { | 222 void TooltipAura::Show() { |
| 243 if (widget_) | 223 if (widget_) { |
| 244 widget_->Show(); | 224 widget_->Show(); |
| 225 widget_->StackAtTop(); | |
| 226 } | |
| 245 } | 227 } |
| 246 | 228 |
| 247 void TooltipAura::Hide() { | 229 void TooltipAura::Hide() { |
| 248 tooltip_window_ = NULL; | 230 tooltip_window_ = NULL; |
| 249 if (widget_) | 231 if (widget_) |
| 250 widget_->Hide(); | 232 widget_->Hide(); |
| 251 } | 233 } |
| 252 | 234 |
| 253 bool TooltipAura::IsVisible() { | 235 bool TooltipAura::IsVisible() { |
| 254 return widget_ && widget_->IsVisible(); | 236 return widget_ && widget_->IsVisible(); |
| 255 } | 237 } |
| 256 | 238 |
| 257 void TooltipAura::OnWidgetDestroying(views::Widget* widget) { | 239 void TooltipAura::OnWidgetDestroying(views::Widget* widget) { |
| 258 DCHECK_EQ(widget_, widget); | 240 DCHECK_EQ(widget_, widget); |
| 259 widget_ = NULL; | 241 widget_ = NULL; |
| 260 tooltip_window_ = NULL; | 242 tooltip_window_ = NULL; |
| 261 } | 243 } |
| 262 | 244 |
| 263 } // namespace corewm | 245 } // namespace corewm |
| 264 } // namespace views | 246 } // namespace views |
| OLD | NEW |