<commit_before>// Copyright (c) 2014 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.

#include "atom/browser/ui/tray_icon_cocoa.h"

#include "atom/browser/ui/cocoa/atom_menu_controller.h"
#include "base/strings/sys_string_conversions.h"
#include "ui/events/cocoa/cocoa_event_utils.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/screen.h"

namespace {

const CGFloat kStatusItemLength = 26;
const CGFloat kMargin = 3;

}  //  namespace

@interface StatusItemView : NSView {
  atom::TrayIconCocoa* trayIcon_; // weak
  AtomMenuController* menuController_; // weak
  BOOL isHighlightEnable_;
  BOOL inMouseEventSequence_;
  base::scoped_nsobject<NSImage> image_;
  base::scoped_nsobject<NSImage> alternateImage_;
  base::scoped_nsobject<NSString> title_;
  base::scoped_nsobject<NSStatusItem> statusItem_;
}

@end  // @interface StatusItemView

@implementation StatusItemView

- (id)initWithIcon:(atom::TrayIconCocoa*)icon {
  trayIcon_ = icon;
  isHighlightEnable_ = YES;
  statusItem_.reset([[[NSStatusBar systemStatusBar] statusItemWithLength:
      NSVariableStatusItemLength] retain]);
  NSRect frame = NSMakeRect(0,
                            0,
                            kStatusItemLength,
                            [[statusItem_ statusBar] thickness]);
  if ((self = [super initWithFrame:frame])) {
    [self registerForDraggedTypes:
        [NSArray arrayWithObjects:NSFilenamesPboardType, nil]];
    [statusItem_ setView:self];
  }
  return self;
}

- (void)removeItem {
  [[NSStatusBar systemStatusBar] removeStatusItem:statusItem_];
  statusItem_.reset();
}

- (void)drawRect:(NSRect)dirtyRect {
  // Draw the tray icon and title that align with NSSStatusItem, layout:
  //   ----------------
  //   | icon | title |
  ///  ----------------
  BOOL highlight = [self shouldHighlight];
  CGFloat titleWidth = [self titleWidth];
  // Calculate the total icon bounds.
  NSRect statusItemBounds = NSMakeRect(0,
                                       0,
                                       kStatusItemLength + titleWidth,
                                       [[statusItem_ statusBar] thickness]);
  [statusItem_ drawStatusBarBackgroundInRect:statusItemBounds
                               withHighlight:highlight];
  [statusItem_ setLength:titleWidth + kStatusItemLength];
  if (title_) {
    NSRect titleDrawRect = NSMakeRect(kStatusItemLength,
                                      0,
                                      titleWidth + kStatusItemLength,
                                      [[statusItem_ statusBar] thickness]);
    [title_ drawInRect:titleDrawRect
        withAttributes:[self titleAttributes]];
  }

  NSRect iconRect = NSMakeRect(0,
                               0,
                               kStatusItemLength,
                               [[statusItem_ statusBar] thickness]);
  if (highlight && alternateImage_) {
    [alternateImage_ drawInRect:NSInsetRect(iconRect, kMargin, kMargin)
                       fromRect:NSZeroRect
                      operation:NSCompositeSourceOver
                       fraction:1];
  } else {
    [image_ drawInRect:NSInsetRect(iconRect, kMargin, kMargin)
              fromRect:NSZeroRect
             operation:NSCompositeSourceOver
              fraction:1];
  }
}

- (CGFloat)titleWidth {
  if (!title_) return 0;
  NSAttributedString* attributes =
      [[NSAttributedString alloc] initWithString:title_
                                      attributes:[self titleAttributes]];
  return [attributes size].width;
}

- (NSDictionary*)titleAttributes {
  NSFont* font = [NSFont menuBarFontOfSize:0];
  NSColor* foregroundColor = [NSColor blackColor];

  return [NSDictionary dictionaryWithObjectsAndKeys:
          font, NSFontAttributeName,
          foregroundColor, NSForegroundColorAttributeName,
          nil];
}

- (void)setImage:(NSImage*)image {
  image_.reset([image copy]);
  [self setNeedsDisplay:YES];
}<commit_msg>Use NSImageView to draw tray icon.<commit_after>// Copyright (c) 2014 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.

#include "atom/browser/ui/tray_icon_cocoa.h"

#include "atom/browser/ui/cocoa/atom_menu_controller.h"
#include "base/strings/sys_string_conversions.h"
#include "ui/events/cocoa/cocoa_event_utils.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/screen.h"

namespace {

// By default, OS X sets 4px to tray image as left and right padding margin.
const CGFloat kHorizontalMargin = 4;

}  //  namespace

@interface StatusItemView : NSView {
  atom::TrayIconCocoa* trayIcon_; // weak
  AtomMenuController* menuController_; // weak
  BOOL isHighlightEnable_;
  BOOL inMouseEventSequence_;
  base::scoped_nsobject<NSImage> image_;
  base::scoped_nsobject<NSImage> alternateImage_;
  base::scoped_nsobject<NSImageView> image_view_;
  base::scoped_nsobject<NSString> title_;
  base::scoped_nsobject<NSStatusItem> statusItem_;
}

@end  // @interface StatusItemView

@implementation StatusItemView

- (id)initWithIcon:(atom::TrayIconCocoa*)icon {
  trayIcon_ = icon;
  isHighlightEnable_ = YES;
  statusItem_.reset([[[NSStatusBar systemStatusBar] statusItemWithLength:
      NSVariableStatusItemLength] retain]);
  CGFloat itemLength = [[statusItem_ statusBar] thickness];
  NSRect frame = NSMakeRect(0,
                            0,
                            itemLength,
                            itemLength);
  if ((self = [super initWithFrame:frame])) {
    image_view_.reset([[[NSImageView alloc] initWithFrame:frame] retain]);
    // Unregister image_view_ as a dragged destination, allows its parent view
    // (StatusItemView) handle dragging events.
    [image_view_ unregisterDraggedTypes];
    [self addSubview:image_view_];
    [self registerForDraggedTypes:
        [NSArray arrayWithObjects:NSFilenamesPboardType, nil]];
    [statusItem_ setView:self];
  }
  return self;
}

- (void)removeItem {
  [[NSStatusBar systemStatusBar] removeStatusItem:statusItem_];
  statusItem_.reset();
}

- (void)drawRect:(NSRect)dirtyRect {
  // Draw the tray icon and title that align with NSStatusItem, layout:
  //   ----------------
  //   | icon | title |
  ///  ----------------
  BOOL highlight = [self shouldHighlight];
  CGFloat titleWidth = [self titleWidth];
  CGFloat statusItemHeight = [[statusItem_ statusBar] thickness];
  CGFloat iconWidth =((highlight && alternateImage_) ?
      [alternateImage_ size].width : [image_ size].width) +
      2 * kHorizontalMargin;
  NSRect iconRect = NSMakeRect(0, 0, iconWidth, statusItemHeight);

  // Calculate the total status item bounds.
  CGFloat statusItemWidth = iconWidth + titleWidth;
  // If title is set, need to add right margin to the title.
  if (title_) {
    statusItemWidth += kHorizontalMargin;
  }
  NSRect statusItemBounds = NSMakeRect(0,
                                       0,
                                       statusItemWidth,
                                       statusItemHeight);
  [statusItem_ drawStatusBarBackgroundInRect:statusItemBounds
                               withHighlight:highlight];
  [statusItem_ setLength:statusItemWidth];

  // Custom ImageView
  [image_view_ setFrame: iconRect];
  if (highlight && alternateImage_) {
    [image_view_ setImage:alternateImage_];
  } else {
    [image_view_ setImage:image_];
  }

  if (title_) {
    NSRect titleDrawRect = NSMakeRect(iconWidth,
                                      0,
                                      statusItemWidth - kHorizontalMargin,
                                      statusItemHeight);
    [title_ drawInRect:titleDrawRect
        withAttributes:[self titleAttributes]];
  }
}

- (BOOL) isDarkMode {
  return [[[NSAppearance currentAppearance] name] hasPrefix:
      NSAppearanceNameVibrantDark];
}

- (CGFloat)titleWidth {
  if (!title_) return 0;
  NSAttributedString* attributes =
      [[NSAttributedString alloc] initWithString:title_
                                      attributes:[self titleAttributes]];
  return [attributes size].width;
}

- (NSDictionary*)titleAttributes {
  NSFont* font = [NSFont menuBarFontOfSize:0];
  NSColor* foregroundColor =
      [self isDarkMode] ? [NSColor whiteColor] : [NSColor blackColor];

  return [NSDictionary dictionaryWithObjectsAndKeys:
          font, NSFontAttributeName,
          foregroundColor, NSForegroundColorAttributeName,
          nil];
}

- (void)setImage:(NSImage*)image {
  image_.reset([image copy]);
  [self setNeedsDisplay:YES];
}
{'fraction_non_alphanumeric': 0.10160553146607289, 'fraction_numerical': 0.003984530645728348, 'mean_word_length': 2.697573656845754, 'pattern_counts': {'":': 0, '<': 12, '<?xml version=': 0, '>': 12, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 14, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4759341', 'n_tokens_mistral': 2520, 'n_tokens_neox': 2437, 'n_words': 536}