1 // Copyright (c) 2010 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. 4 5 #import "chrome/browser/ui/cocoa/location_bar/ev_bubble_decoration.h" 6 7 #import "base/logging.h" 8 #include "base/sys_string_conversions.h" 9 #import "chrome/browser/ui/cocoa/image_utils.h" 10 #import "chrome/browser/ui/cocoa/location_bar/location_icon_decoration.h" 11 #include "ui/base/text/text_elider.h" 12 #include "ui/gfx/font.h" 13 14 namespace { 15 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 23 24 // Minimum acceptable width for the ev bubble. 25 const CGFloat kMinElidedBubbleWidth = 150.0; 26 27 // Maximum amount of available space to make the bubble, subject to 28 // |kMinElidedBubbleWidth|. 29 const float kMaxBubbleFraction = 0.5; 30 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; 34 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) { 39 DCHECK_LE(rr, 255); 40 DCHECK_LE(bb, 255); 41 DCHECK_LE(gg, 255); 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 45 alpha:1.0]; 46 } 47 48 } // namespace 49 50 EVBubbleDecoration::EVBubbleDecoration( 51 LocationIconDecoration* location_icon, 52 NSFont* font) 53 : BubbleDecoration(font), 54 font_([font retain]), 55 location_icon_(location_icon) { 56 // Color tuples stolen from location_bar_view_gtk.cc. 57 NSColor* border_color = ColorWithRGBBytes(0x90, 0xc3, 0x90); 58 NSColor* background_color = ColorWithRGBBytes(0xef, 0xfc, 0xef); 59 NSColor* text_color = ColorWithRGBBytes(0x07, 0x95, 0x00); 60 SetColors(border_color, background_color, text_color); 61 } 62 63 EVBubbleDecoration::~EVBubbleDecoration() {} 64 65 void EVBubbleDecoration::SetFullLabel(NSString* label) { 66 full_label_.reset([label retain]); 67 SetLabel(full_label_); 68 } 69 70 NSPoint EVBubbleDecoration::GetBubblePointInFrame(NSRect frame) { 71 NSRect image_rect = GetImageRectInFrame(frame); 72 return NSMakePoint(NSMidX(image_rect), 73 NSMaxY(image_rect) - kPageInfoBubblePointYOffset); 74 } 75 76 CGFloat EVBubbleDecoration::GetWidthForSpace(CGFloat width) { 77 // Limit with to not take up too much of the available width, but 78 // also don't let it shrink too much. 79 width = std::max(width * kMaxBubbleFraction, kMinElidedBubbleWidth); 80 81 // Use the full label if it fits. 82 NSImage* image = GetImage(); 83 const CGFloat all_width = GetWidthForImageAndLabel(image, full_label_); 84 if (all_width <= width) { 85 SetLabel(full_label_); 86 return all_width; 87 } 88 89 // Width left for laying out the label. 90 const CGFloat width_left = width - GetWidthForImageAndLabel(image, @""); 91 92 // Middle-elide the label to fit |width_left|. This leaves the 93 // prefix and the trailing country code in place. 94 gfx::Font font(base::SysNSStringToUTF16([font_ fontName]), 95 [font_ pointSize]); 96 NSString* elided_label = base::SysUTF16ToNSString( 97 ui::ElideText(base::SysNSStringToUTF16(full_label_), font, width_left, 98 true)); 99 100 // Use the elided label. 101 SetLabel(elided_label); 102 return GetWidthForImageAndLabel(image, elided_label); 103 } 104 105 // Pass mouse operations through to location icon. 106 bool EVBubbleDecoration::IsDraggable() { 107 return location_icon_->IsDraggable(); 108 } 109 110 NSPasteboard* EVBubbleDecoration::GetDragPasteboard() { 111 return location_icon_->GetDragPasteboard(); 112 } 113 114 NSImage* EVBubbleDecoration::GetDragImage() { 115 return location_icon_->GetDragImage(); 116 } 117 118 NSRect EVBubbleDecoration::GetDragImageFrame(NSRect frame) { 119 return GetImageRectInFrame(frame); 120 } 121 122 bool EVBubbleDecoration::OnMousePressed(NSRect frame) { 123 return location_icon_->OnMousePressed(frame); 124 } 125 126 bool EVBubbleDecoration::AcceptsMousePress() { 127 return true; 128 } 129