Home | History | Annotate | Download | only in location_bar
      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