• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright (c) 2012 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/toolbar/back_forward_menu_controller.h"
6
7#include "base/logging.h"
8#include "base/memory/scoped_ptr.h"
9#include "base/strings/sys_string_conversions.h"
10#import "chrome/browser/ui/cocoa/menu_button.h"
11#include "chrome/browser/ui/toolbar/back_forward_menu_model.h"
12#import "ui/events/event_utils.h"
13#include "ui/gfx/image/image.h"
14
15using base::SysUTF16ToNSString;
16
17@implementation BackForwardMenuController
18
19// Accessors and mutators:
20
21@synthesize type = type_;
22
23// Own methods:
24
25- (id)initWithBrowser:(Browser*)browser
26            modelType:(BackForwardMenuType)type
27               button:(MenuButton*)button {
28  if ((self = [super init])) {
29    type_ = type;
30    button_ = button;
31    model_.reset(new BackForwardMenuModel(browser, type_));
32    DCHECK(model_.get());
33    backForwardMenu_.reset([[NSMenu alloc] initWithTitle:@""]);
34    DCHECK(backForwardMenu_.get());
35    [backForwardMenu_ setDelegate:self];
36
37    [button_ setAttachedMenu:backForwardMenu_];
38    [button_ setOpenMenuOnClick:NO];
39  }
40  return self;
41}
42
43// Methods as delegate:
44
45// Called by backForwardMenu_ just before tracking begins.
46//TODO(viettrungluu): should we do anything for chapter stops (see model)?
47- (void)menuNeedsUpdate:(NSMenu*)menu {
48  DCHECK(menu == backForwardMenu_);
49
50  // Remove old menu items (backwards order is as good as any).
51  for (NSInteger i = [menu numberOfItems]; i > 0; i--)
52    [menu removeItemAtIndex:(i - 1)];
53
54  // 0-th item must be blank. (This is because we use a pulldown list, for which
55  // Cocoa uses the 0-th item as "title" in the button.)
56  [menu insertItemWithTitle:@""
57                     action:nil
58              keyEquivalent:@""
59                    atIndex:0];
60  for (int menuID = 0; menuID < model_->GetItemCount(); menuID++) {
61    if (model_->IsSeparator(menuID)) {
62      [menu insertItem:[NSMenuItem separatorItem]
63               atIndex:(menuID + 1)];
64    } else {
65      // Create a menu item with the right label.
66      NSMenuItem* menuItem = [[NSMenuItem alloc]
67              initWithTitle:SysUTF16ToNSString(model_->GetLabelAt(menuID))
68                     action:nil
69              keyEquivalent:@""];
70      [menuItem autorelease];
71
72      gfx::Image icon;
73      // Icon (if it has one).
74      if (model_->GetIconAt(menuID, &icon))
75        [menuItem setImage:icon.ToNSImage()];
76
77      // This will make it call our |-executeMenuItem:| method. We store the
78      // |menuID| (or |menu_id|) in the tag.
79      [menuItem setTag:menuID];
80      [menuItem setTarget:self];
81      [menuItem setAction:@selector(executeMenuItem:)];
82
83      // Put it in the menu!
84      [menu insertItem:menuItem
85               atIndex:(menuID + 1)];
86    }
87  }
88}
89
90// Action methods:
91
92- (void)executeMenuItem:(id)sender {
93  DCHECK([sender isKindOfClass:[NSMenuItem class]]);
94  int menuID = [sender tag];
95  int event_flags = ui::EventFlagsFromNative([NSApp currentEvent]);
96  model_->ActivatedAt(menuID, event_flags);
97}
98
99@end  // @implementation BackForwardMenuController
100