1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #import "chrome/browser/ui/cocoa/location_bar/ev_bubble_decoration.h"
7 #import "base/logging.h"
8 #include "base/strings/sys_string_conversions.h"
9 #import "chrome/browser/ui/cocoa/location_bar/location_icon_decoration.h"
10 #include "grit/theme_resources.h"
11 #include "ui/gfx/font_list.h"
12 #include "ui/gfx/text_elider.h"
16 // TODO(shess): In general, decorations that don't fit in the
17 // available space are omitted. This one never goes to omitted, it
18 // sticks at 150px, which AFAICT follows the Windows code. Since the
19 // Layout() code doesn't take this into account, it's possible the
20 // control could end up with display artifacts, though things still
21 // work (and don't crash).
22 // http://crbug.com/49822
24 // Minimum acceptable width for the ev bubble.
25 const CGFloat kMinElidedBubbleWidth = 150.0;
27 // Maximum amount of available space to make the bubble, subject to
28 // |kMinElidedBubbleWidth|.
29 const float kMaxBubbleFraction = 0.5;
31 // The info-bubble point should look like it points to the bottom of the lock
32 // icon. Determined with Pixie.app.
33 const CGFloat kPageInfoBubblePointYOffset = 6.0;
35 // TODO(shess): This is ugly, find a better way. Using it right now
36 // so that I can crib from gtk and still be able to see that I'm using
37 // the same values easily.
38 NSColor* ColorWithRGBBytes(int rr, int gg, int bb) {
42 return [NSColor colorWithCalibratedRed:static_cast<float>(rr)/255.0
43 green:static_cast<float>(gg)/255.0
44 blue:static_cast<float>(bb)/255.0
50 EVBubbleDecoration::EVBubbleDecoration(LocationIconDecoration* location_icon)
51 : location_icon_(location_icon) {
52 // Color tuples stolen from location_bar_view_gtk.cc.
53 SetTextColor(ColorWithRGBBytes(0x07, 0x95, 0x00));
56 EVBubbleDecoration::~EVBubbleDecoration() {}
58 void EVBubbleDecoration::SetFullLabel(NSString* label) {
59 full_label_.reset([label retain]);
60 SetLabel(full_label_);
63 NSPoint EVBubbleDecoration::GetBubblePointInFrame(NSRect frame) {
64 NSRect image_rect = GetImageRectInFrame(frame);
65 return NSMakePoint(NSMidX(image_rect),
66 NSMaxY(image_rect) - kPageInfoBubblePointYOffset);
69 CGFloat EVBubbleDecoration::GetWidthForSpace(CGFloat width) {
70 // Limit with to not take up too much of the available width, but
71 // also don't let it shrink too much.
72 width = std::max(width * kMaxBubbleFraction, kMinElidedBubbleWidth);
74 // Use the full label if it fits.
75 NSImage* image = GetImage();
76 const CGFloat all_width = GetWidthForImageAndLabel(image, full_label_);
77 if (all_width <= width) {
78 SetLabel(full_label_);
82 // Width left for laying out the label.
83 const CGFloat width_left = width - GetWidthForImageAndLabel(image, @"");
85 // Middle-elide the label to fit |width_left|. This leaves the
86 // prefix and the trailing country code in place.
87 NSString* elided_label = base::SysUTF16ToNSString(
88 gfx::ElideText(base::SysNSStringToUTF16(full_label_),
89 gfx::FontList(gfx::Font(GetFont())),
91 gfx::ELIDE_IN_MIDDLE));
93 // Use the elided label.
94 SetLabel(elided_label);
95 return GetWidthForImageAndLabel(image, elided_label);
98 // Pass mouse operations through to location icon.
99 bool EVBubbleDecoration::IsDraggable() {
100 return location_icon_->IsDraggable();
103 NSPasteboard* EVBubbleDecoration::GetDragPasteboard() {
104 return location_icon_->GetDragPasteboard();
107 NSImage* EVBubbleDecoration::GetDragImage() {
108 return location_icon_->GetDragImage();
111 NSRect EVBubbleDecoration::GetDragImageFrame(NSRect frame) {
112 return GetImageRectInFrame(frame);
115 bool EVBubbleDecoration::OnMousePressed(NSRect frame) {
116 return location_icon_->OnMousePressed(frame);
119 bool EVBubbleDecoration::AcceptsMousePress() {
123 ui::NinePartImageIds EVBubbleDecoration::GetBubbleImageIds() {
124 return IMAGE_GRID(IDR_OMNIBOX_EV_BUBBLE);