| Index: ui/app_list/views/views_demo_app_mac.mm
|
| diff --git a/ui/app_list/views/views_demo_app_mac.mm b/ui/app_list/views/views_demo_app_mac.mm
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..095d5edabf0966d3781c95ab5cda3c5a8ac35dd0
|
| --- /dev/null
|
| +++ b/ui/app_list/views/views_demo_app_mac.mm
|
| @@ -0,0 +1,162 @@
|
| +// Copyright 2014 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.
|
| +
|
| +#include "ui/app_list/views/views_demo_app.h"
|
| +
|
| +#import <Cocoa/Cocoa.h>
|
| +
|
| +#include "base/logging.h"
|
| +#include "base/mac/scoped_nsobject.h"
|
| +#include "base/message_loop/message_loop.h"
|
| +#include "base/strings/sys_string_conversions.h"
|
| +
|
| +@interface CocoaDemoAppImpl : NSObject<NSApplicationDelegate> {
|
| + @private
|
| + ViewsDemoApp* app_; // Weak. Owns us.
|
| + ViewsDemoAppDelegate* delegate_; // Explicit ownership.
|
| + base::scoped_nsobject<NSMenu> options_;
|
| + base::scoped_nsobject<NSMutableArray> optionTargets_;
|
| +}
|
| +
|
| +@property(assign, nonatomic) ViewsDemoApp* app;
|
| +@property(assign, nonatomic) ViewsDemoAppDelegate* delegate;
|
| +
|
| +- (void)addOption:(const char*)description
|
| + withCallback:(const base::Callback<void(bool)>&)callback
|
| + initialState:(BOOL)isOn;
|
| +
|
| +@end
|
| +
|
| +@interface CallbackBridge : NSObject {
|
| + @private
|
| + NSMenuItem* menuItem_;
|
| + base::Callback<void(bool)> callback_;
|
| +}
|
| +
|
| +- (id)initWithCallback:(const base::Callback<void(bool)>&)callback
|
| + forMenuItem:(NSMenuItem*)menuItem;
|
| +
|
| +- (void)run:(id)sender;
|
| +
|
| +@end
|
| +
|
| +namespace {
|
| +
|
| +class ViewsDemoAppMac : public ViewsDemoApp {
|
| + public:
|
| + ViewsDemoAppMac(ViewsDemoAppDelegate* delegate)
|
| + : impl_([[CocoaDemoAppImpl alloc] init]) {
|
| + [impl_ setApp:this];
|
| + [impl_ setDelegate:delegate];
|
| + [[NSApplication sharedApplication] setDelegate:impl_];
|
| + }
|
| +
|
| + virtual ~ViewsDemoAppMac() {
|
| + [[NSApplication sharedApplication] setDelegate:nil];
|
| + ViewsDemoAppDelegate* delegate = [impl_ delegate];
|
| + [impl_ setDelegate:nil];
|
| + impl_.reset();
|
| + delete delegate;
|
| + }
|
| +
|
| + virtual void Run() OVERRIDE {
|
| + base::MessageLoopForUI message_loop;
|
| + DCHECK([impl_ delegate]);
|
| + [impl_ delegate]->Run();
|
| + }
|
| +
|
| + virtual void AddOption(const char* description,
|
| + const base::Callback<void(bool)>& callback,
|
| + bool initial_state) OVERRIDE {
|
| + [impl_ addOption:description
|
| + withCallback:callback
|
| + initialState:initial_state];
|
| + }
|
| +
|
| + private:
|
| + base::scoped_nsobject<CocoaDemoAppImpl> impl_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(ViewsDemoAppMac);
|
| +};
|
| +}
|
| +
|
| +@implementation CocoaDemoAppImpl
|
| +
|
| +@synthesize app = app_;
|
| +@synthesize delegate = delegate_;
|
| +
|
| +- (void)addOption:(const char*)description
|
| + withCallback:(const base::Callback<void(bool)>&)callback
|
| + initialState:(BOOL)isOn {
|
| + if (!options_) {
|
| + options_.reset([[NSMenu alloc] initWithTitle:@"Options"]);
|
| + optionTargets_.reset([[NSMutableArray alloc] initWithCapacity:1]);
|
| + }
|
| +
|
| + NSString* title = base::SysUTF8ToNSString(description);
|
| + NSMenuItem* item = [options_ addItemWithTitle:title
|
| + action:@selector(run:)
|
| + keyEquivalent:@""];
|
| + base::scoped_nsobject<CallbackBridge> bridge(
|
| + [[CallbackBridge alloc] initWithCallback:callback forMenuItem:item]);
|
| + [item setTarget:bridge];
|
| + [item setState:isOn ? NSOnState : NSOffState];
|
| + [optionTargets_ addObject:bridge];
|
| +}
|
| +
|
| +- (void)applicationDidFinishLaunching:(NSNotification*)aNotification {
|
| + // To get key events, we need to set a main menu and have an activation
|
| + // policy.
|
| + [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
|
| + base::scoped_nsobject<NSMenu> mainMenu([[NSMenu alloc] initWithTitle:@""]);
|
| + NSMenuItem* appMenuItem =
|
| + [mainMenu addItemWithTitle:@"" action:NULL keyEquivalent:@""];
|
| + [NSApp setMainMenu:mainMenu];
|
| +
|
| + base::scoped_nsobject<NSMenu> appMenu([[NSMenu alloc] initWithTitle:@""]);
|
| + NSString* appName = [[NSProcessInfo processInfo] processName];
|
| + NSString* quitTitle = [@"Quit " stringByAppendingString:appName];
|
| + [appMenu addItemWithTitle:quitTitle
|
| + action:@selector(terminate:)
|
| + keyEquivalent:@"q"];
|
| + [appMenuItem setSubmenu:appMenu];
|
| +
|
| + app_->InitOnMainThread();
|
| + if (delegate_)
|
| + delegate_->Init();
|
| +
|
| + if (options_) {
|
| + NSMenuItem* optionsMenuItem =
|
| + [mainMenu addItemWithTitle:@"" action:NULL keyEquivalent:@""];
|
| + [optionsMenuItem setSubmenu:options_];
|
| + options_.reset();
|
| + }
|
| +}
|
| +
|
| +@end
|
| +
|
| +@implementation CallbackBridge
|
| +
|
| +- (id)initWithCallback:(const base::Callback<void(bool)>&)callback
|
| + forMenuItem:(NSMenuItem*)menuItem {
|
| + if ((self = [super init])) {
|
| + callback_ = callback;
|
| + menuItem_ = menuItem;
|
| + }
|
| + return self;
|
| +}
|
| +
|
| +- (void)run:(id)sender {
|
| + BOOL newState = [menuItem_ state] == NSOnState ? NSOffState : NSOnState;
|
| + [menuItem_ setState:newState];
|
| + callback_.Run(newState == NSOnState);
|
| +}
|
| +
|
| +@end
|
| +
|
| +// static
|
| +scoped_ptr<ViewsDemoApp> ViewsDemoApp::Create(
|
| + scoped_ptr<ViewsDemoAppDelegate> delegate) {
|
| + return scoped_ptr<ViewsDemoApp>(new ViewsDemoAppMac(delegate.release()));
|
| +}
|
|
|