Home | History | Annotate | Download | only in toolbar
      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/base/cocoa/cocoa_event_utils.h"
     13 #include "ui/gfx/image/image.h"
     14 
     15 using 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::EventFlagsFromNSEvent([NSApp currentEvent]);
     96   model_->ActivatedAt(menuID, event_flags);
     97 }
     98 
     99 @end  // @implementation BackForwardMenuController
    100