File: app_list_pager_view.mm

package info (click to toggle)
chromium-browser 41.0.2272.118-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie-kfreebsd
  • size: 2,189,132 kB
  • sloc: cpp: 9,691,462; ansic: 3,341,451; python: 712,689; asm: 518,779; xml: 208,926; java: 169,820; sh: 119,353; perl: 68,907; makefile: 28,311; yacc: 13,305; objc: 11,385; tcl: 3,186; cs: 2,225; sql: 2,217; lex: 2,215; lisp: 1,349; pascal: 1,256; awk: 407; ruby: 155; sed: 53; php: 14; exp: 11
file content (167 lines) | stat: -rw-r--r-- 4,912 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#import "ui/app_list/cocoa/app_list_pager_view.h"

#include "base/mac/foundation_util.h"
#include "skia/ext/skia_utils_mac.h"
#include "ui/app_list/app_list_constants.h"
#include "ui/gfx/scoped_ns_graphics_context_save_gstate_mac.h"

namespace {

const CGFloat kButtonHeight = 6;
const CGFloat kButtonCornerRadius = 2;
const CGFloat kButtonStripPadding = 20;

}  // namespace

@interface AppListPagerView ()

@property(assign, nonatomic) NSInteger hoveredSegment;

- (NSInteger)segmentUnderLocation:(NSPoint)locationInWindow;

@end

@interface AppListPagerCell : NSSegmentedCell;
@end

@implementation AppListPagerView

@synthesize hoveredSegment = hoveredSegment_;

+ (Class)cellClass {
  return [AppListPagerCell class];
}

- (id)init {
  if ((self = [super initWithFrame:NSZeroRect])) {
    trackingArea_.reset(
        [[CrTrackingArea alloc] initWithRect:NSZeroRect
                                     options:NSTrackingInVisibleRect |
                                             NSTrackingMouseEnteredAndExited |
                                             NSTrackingMouseMoved |
                                             NSTrackingActiveInKeyWindow
                                       owner:self
                                    userInfo:nil]);
    [self addTrackingArea:trackingArea_.get()];
    hoveredSegment_ = -1;
  }
  return self;
}

- (NSInteger)findAndHighlightSegmentAtLocation:(NSPoint)locationInWindow {
  NSInteger segment = [self segmentUnderLocation:locationInWindow];
  [self setHoveredSegment:segment];
  return segment;
}

- (void)setHoveredSegment:(NSInteger)segment {
  if (segment == hoveredSegment_)
    return;

  hoveredSegment_ = segment;
  [self setNeedsDisplay:YES];
  return;
}

- (NSInteger)segmentUnderLocation:(NSPoint)locationInWindow {
  if ([self segmentCount] == 0)
    return -1;

  NSPoint pointInView = [self convertPoint:locationInWindow
                                  fromView:nil];
  if (![self mouse:pointInView inRect:[self bounds]])
    return -1;

  CGFloat segmentWidth = [self bounds].size.width / [self segmentCount];
  return pointInView.x / segmentWidth;
}

- (BOOL)isHoveredForSegment:(NSInteger)segment {
  return segment == hoveredSegment_;
}

- (void)mouseExited:(NSEvent*)theEvent {
  [self setHoveredSegment:-1];
}

- (void)mouseMoved:(NSEvent*)theEvent {
  [self findAndHighlightSegmentAtLocation:[theEvent locationInWindow]];
}

- (void)mouseDown:(NSEvent*)theEvent {
  // Temporarily clear the highlight to give feedback.
  [self setHoveredSegment:-1];
}

// The stock NSSegmentedControl ignores any clicks outside the non-default
// control height, so process all clicks here.
- (void)mouseUp:(NSEvent*)theEvent {
  [self findAndHighlightSegmentAtLocation:[theEvent locationInWindow]];
  if (hoveredSegment_ < 0)
    return;

  [self setSelectedSegment:hoveredSegment_];
  [[self target] performSelector:[self action]
                      withObject:self];
}

@end

@implementation AppListPagerCell

- (void)drawWithFrame:(NSRect)cellFrame
               inView:(NSView*)controlView {
  // Draw nothing if there are less than two segments.
  if ([self segmentCount] < 2)
    return;

  cellFrame.size.width /= [self segmentCount];
  for (NSInteger i = 0; i < [self segmentCount]; ++i) {
    [self drawSegment:i
              inFrame:cellFrame
             withView:controlView];
    cellFrame.origin.x += cellFrame.size.width;
  }
}

- (void)drawSegment:(NSInteger)segment
            inFrame:(NSRect)frame
           withView:(NSView*)controlView {
  gfx::ScopedNSGraphicsContextSaveGState context;
  NSRect clipRect = NSMakeRect(
      frame.origin.x + kButtonStripPadding / 2,
      floor(frame.origin.y + (frame.size.height - kButtonHeight) / 2),
      frame.size.width - kButtonStripPadding,
      kButtonHeight);
  [[NSBezierPath bezierPathWithRoundedRect:clipRect
                                   xRadius:kButtonCornerRadius
                                   yRadius:kButtonCornerRadius] addClip];

  AppListPagerView* pagerControl =
      base::mac::ObjCCastStrict<AppListPagerView>(controlView);
  SkColor backgroundColor = [pagerControl hoveredSegment] == segment ?
      app_list::kPagerHoverColor :
      app_list::kPagerNormalColor;

  [gfx::SkColorToSRGBNSColor(backgroundColor) set];
  NSRectFill(frame);

  if (![[self target] conformsToProtocol:@protocol(AppListPagerDelegate)])
    return;

  CGFloat selectedRatio = [[self target] visiblePortionOfPage:segment];
  if (selectedRatio == 0.0)
    return;

  [gfx::SkColorToSRGBNSColor(app_list::kPagerSelectedColor) set];
  if (selectedRatio < 0)
    frame.origin.x += frame.size.width + frame.size.width * selectedRatio;
  frame.size.width *= fabs(selectedRatio);
  NSRectFill(frame);
}

@end