OLD | NEW |
(Empty) | |
| 1 // Copyright 2014 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 #include "ui/app_list/views/views_demo_app.h" |
| 6 |
| 7 #import <Cocoa/Cocoa.h> |
| 8 |
| 9 #include "base/logging.h" |
| 10 #include "base/mac/scoped_nsobject.h" |
| 11 #include "base/message_loop/message_loop.h" |
| 12 #include "base/strings/sys_string_conversions.h" |
| 13 |
| 14 @interface CocoaDemoAppImpl : NSObject<NSApplicationDelegate> { |
| 15 @private |
| 16 ViewsDemoApp* app_; // Weak. Owns us. |
| 17 ViewsDemoAppDelegate* delegate_; // Explicit ownership. |
| 18 base::scoped_nsobject<NSMenu> options_; |
| 19 base::scoped_nsobject<NSMutableArray> optionTargets_; |
| 20 } |
| 21 |
| 22 @property(assign, nonatomic) ViewsDemoApp* app; |
| 23 @property(assign, nonatomic) ViewsDemoAppDelegate* delegate; |
| 24 |
| 25 - (void)addOption:(const char*)description |
| 26 withCallback:(const base::Callback<void(bool)>&)callback |
| 27 initialState:(BOOL)isOn; |
| 28 |
| 29 @end |
| 30 |
| 31 @interface CallbackBridge : NSObject { |
| 32 @private |
| 33 NSMenuItem* menuItem_; |
| 34 base::Callback<void(bool)> callback_; |
| 35 } |
| 36 |
| 37 - (id)initWithCallback:(const base::Callback<void(bool)>&)callback |
| 38 forMenuItem:(NSMenuItem*)menuItem; |
| 39 |
| 40 - (void)run:(id)sender; |
| 41 |
| 42 @end |
| 43 |
| 44 namespace { |
| 45 |
| 46 class ViewsDemoAppMac : public ViewsDemoApp { |
| 47 public: |
| 48 ViewsDemoAppMac(ViewsDemoAppDelegate* delegate) |
| 49 : impl_([[CocoaDemoAppImpl alloc] init]) { |
| 50 [impl_ setApp:this]; |
| 51 [impl_ setDelegate:delegate]; |
| 52 [[NSApplication sharedApplication] setDelegate:impl_]; |
| 53 } |
| 54 |
| 55 virtual ~ViewsDemoAppMac() { |
| 56 [[NSApplication sharedApplication] setDelegate:nil]; |
| 57 ViewsDemoAppDelegate* delegate = [impl_ delegate]; |
| 58 [impl_ setDelegate:nil]; |
| 59 impl_.reset(); |
| 60 delete delegate; |
| 61 } |
| 62 |
| 63 virtual void Run() OVERRIDE { |
| 64 base::MessageLoopForUI message_loop; |
| 65 DCHECK([impl_ delegate]); |
| 66 [impl_ delegate]->Run(); |
| 67 } |
| 68 |
| 69 virtual void AddOption(const char* description, |
| 70 const base::Callback<void(bool)>& callback, |
| 71 bool initial_state) OVERRIDE { |
| 72 [impl_ addOption:description |
| 73 withCallback:callback |
| 74 initialState:initial_state]; |
| 75 } |
| 76 |
| 77 private: |
| 78 base::scoped_nsobject<CocoaDemoAppImpl> impl_; |
| 79 |
| 80 DISALLOW_COPY_AND_ASSIGN(ViewsDemoAppMac); |
| 81 }; |
| 82 } |
| 83 |
| 84 @implementation CocoaDemoAppImpl |
| 85 |
| 86 @synthesize app = app_; |
| 87 @synthesize delegate = delegate_; |
| 88 |
| 89 - (void)addOption:(const char*)description |
| 90 withCallback:(const base::Callback<void(bool)>&)callback |
| 91 initialState:(BOOL)isOn { |
| 92 if (!options_) { |
| 93 options_.reset([[NSMenu alloc] initWithTitle:@"Options"]); |
| 94 optionTargets_.reset([[NSMutableArray alloc] initWithCapacity:1]); |
| 95 } |
| 96 |
| 97 NSString* title = base::SysUTF8ToNSString(description); |
| 98 NSMenuItem* item = [options_ addItemWithTitle:title |
| 99 action:@selector(run:) |
| 100 keyEquivalent:@""]; |
| 101 base::scoped_nsobject<CallbackBridge> bridge( |
| 102 [[CallbackBridge alloc] initWithCallback:callback forMenuItem:item]); |
| 103 [item setTarget:bridge]; |
| 104 [item setState:isOn ? NSOnState : NSOffState]; |
| 105 [optionTargets_ addObject:bridge]; |
| 106 } |
| 107 |
| 108 - (void)applicationDidFinishLaunching:(NSNotification*)aNotification { |
| 109 // To get key events, we need to set a main menu and have an activation |
| 110 // policy. |
| 111 [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; |
| 112 base::scoped_nsobject<NSMenu> mainMenu([[NSMenu alloc] initWithTitle:@""]); |
| 113 NSMenuItem* appMenuItem = |
| 114 [mainMenu addItemWithTitle:@"" action:NULL keyEquivalent:@""]; |
| 115 [NSApp setMainMenu:mainMenu]; |
| 116 |
| 117 base::scoped_nsobject<NSMenu> appMenu([[NSMenu alloc] initWithTitle:@""]); |
| 118 NSString* appName = [[NSProcessInfo processInfo] processName]; |
| 119 NSString* quitTitle = [@"Quit " stringByAppendingString:appName]; |
| 120 [appMenu addItemWithTitle:quitTitle |
| 121 action:@selector(terminate:) |
| 122 keyEquivalent:@"q"]; |
| 123 [appMenuItem setSubmenu:appMenu]; |
| 124 |
| 125 app_->InitOnMainThread(); |
| 126 if (delegate_) |
| 127 delegate_->Init(); |
| 128 |
| 129 if (options_) { |
| 130 NSMenuItem* optionsMenuItem = |
| 131 [mainMenu addItemWithTitle:@"" action:NULL keyEquivalent:@""]; |
| 132 [optionsMenuItem setSubmenu:options_]; |
| 133 options_.reset(); |
| 134 } |
| 135 } |
| 136 |
| 137 @end |
| 138 |
| 139 @implementation CallbackBridge |
| 140 |
| 141 - (id)initWithCallback:(const base::Callback<void(bool)>&)callback |
| 142 forMenuItem:(NSMenuItem*)menuItem { |
| 143 if ((self = [super init])) { |
| 144 callback_ = callback; |
| 145 menuItem_ = menuItem; |
| 146 } |
| 147 return self; |
| 148 } |
| 149 |
| 150 - (void)run:(id)sender { |
| 151 BOOL newState = [menuItem_ state] == NSOnState ? NSOffState : NSOnState; |
| 152 [menuItem_ setState:newState]; |
| 153 callback_.Run(newState == NSOnState); |
| 154 } |
| 155 |
| 156 @end |
| 157 |
| 158 // static |
| 159 scoped_ptr<ViewsDemoApp> ViewsDemoApp::Create( |
| 160 scoped_ptr<ViewsDemoAppDelegate> delegate) { |
| 161 return scoped_ptr<ViewsDemoApp>(new ViewsDemoAppMac(delegate.release())); |
| 162 } |
OLD | NEW |