ToolbarSample: Version 3.0, 2016-10-27

Update to Swift, uses Storyboard, and now includes NSTouchBar.

This sample shows how to use the AppKit's NSToolbar and NSToolbarItem classes. These are used to add customizable toolbars to windows. This sample also includes more advanced use of custom views in NSToolbarItems, where you can put a variety of controls, given a little more coding.
This commit is contained in:
Liu Lantao 2016-12-24 12:02:25 +08:00
parent d16de83c51
commit b05769f6be
12 changed files with 1578 additions and 0 deletions

42
ToolbarSample/LICENSE.txt Normal file
View File

@ -0,0 +1,42 @@
Sample code project: ToolbarSample: Using NSToolbar to construct a window toolbar
Version: 3.0
IMPORTANT: This Apple software is supplied to you by Apple
Inc. ("Apple") in consideration of your agreement to the following
terms, and your use, installation, modification or redistribution of
this Apple software constitutes acceptance of these terms. If you do
not agree with these terms, please do not use, install, modify or
redistribute this Apple software.
In consideration of your agreement to abide by the following terms, and
subject to these terms, Apple grants you a personal, non-exclusive
license, under Apple's copyrights in this original Apple software (the
"Apple Software"), to use, reproduce, modify and redistribute the Apple
Software, with or without modifications, in source and/or binary forms;
provided that if you redistribute the Apple Software in its entirety and
without modifications, you must retain this notice and the following
text and disclaimers in all such redistributions of the Apple Software.
Neither the name, trademarks, service marks or logos of Apple Inc. may
be used to endorse or promote products derived from the Apple Software
without specific prior written permission from Apple. Except as
expressly stated in this notice, no other rights or licenses, express or
implied, are granted by Apple herein, including but not limited to any
patent rights that may be infringed by your derivative works or by other
works in which the Apple Software may be incorporated.
The Apple Software is provided by Apple on an "AS IS" basis. APPLE
MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
Copyright (C) 2016 Apple Inc. All Rights Reserved.

17
ToolbarSample/ReadMe.md Normal file
View File

@ -0,0 +1,17 @@
# ToolbarSample: Using NSToolbar to construct a window toolbar
## Description
This sample shows how to use the AppKit's NSToolbar and NSToolbarItem classes. These are used to add customizable toolbars to windows. This sample also includes more advanced use of custom views in NSToolbarItems, where you can put a variety of controls, given a little more coding. This sample implements the NSTouchBar API to work in conjunction with the toolbar.
## Requirements
### Build
Xcode 8.1, macOS 10.12.1 SDK or later
### Runtime
macOS 10.11 or later
Copyright (C) 2001-2016 Apple Inc. All rights reserved.

View File

@ -0,0 +1,335 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
536F82381D8862FA0029689C /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 536F82371D8862FA0029689C /* AppDelegate.swift */; };
536F823A1D8863010029689C /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 536F82391D8863010029689C /* ViewController.swift */; };
536F823D1D88630C0029689C /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 536F823B1D88630C0029689C /* Main.storyboard */; };
536F82421D8863110029689C /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 536F823E1D8863110029689C /* Credits.rtf */; };
536F82431D8863110029689C /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 536F82401D8863110029689C /* InfoPlist.strings */; };
536F82461D88631C0029689C /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 536F82451D88631C0029689C /* Images.xcassets */; };
53A35EAD1D88677A00A84CDE /* WindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53A35EAC1D88677A00A84CDE /* WindowController.swift */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
533FE5AD1DA86A0A0042B582 /* ReadMe.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = ReadMe.md; sourceTree = "<group>"; };
5341010D1AFD23B2003BC1D6 /* ToolbarSample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ToolbarSample.app; sourceTree = BUILT_PRODUCTS_DIR; };
536F82371D8862FA0029689C /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = AppDelegate.swift; path = ToolbarSample/AppDelegate.swift; sourceTree = SOURCE_ROOT; };
536F82391D8863010029689C /* ViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ViewController.swift; path = ToolbarSample/ViewController.swift; sourceTree = SOURCE_ROOT; };
536F823C1D88630C0029689C /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = ToolbarSample/Base.lproj/Main.storyboard; sourceTree = SOURCE_ROOT; };
536F823F1D8863110029689C /* en */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; name = en; path = ToolbarSample/en.lproj/Credits.rtf; sourceTree = SOURCE_ROOT; };
536F82411D8863110029689C /* en */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = en; path = ToolbarSample/en.lproj/InfoPlist.strings; sourceTree = SOURCE_ROOT; };
536F82441D8863170029689C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = ToolbarSample/Info.plist; sourceTree = SOURCE_ROOT; };
536F82451D88631C0029689C /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = ToolbarSample/Images.xcassets; sourceTree = SOURCE_ROOT; };
53A35EAC1D88677A00A84CDE /* WindowController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = WindowController.swift; path = ToolbarSample/WindowController.swift; sourceTree = SOURCE_ROOT; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
5341010A1AFD23B2003BC1D6 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
534101041AFD23B2003BC1D6 = {
isa = PBXGroup;
children = (
533FE5AD1DA86A0A0042B582 /* ReadMe.md */,
5341010F1AFD23B2003BC1D6 /* ToolbarSample */,
5341010E1AFD23B2003BC1D6 /* Products */,
);
sourceTree = "<group>";
};
5341010E1AFD23B2003BC1D6 /* Products */ = {
isa = PBXGroup;
children = (
5341010D1AFD23B2003BC1D6 /* ToolbarSample.app */,
);
name = Products;
sourceTree = "<group>";
};
5341010F1AFD23B2003BC1D6 /* ToolbarSample */ = {
isa = PBXGroup;
children = (
536F82371D8862FA0029689C /* AppDelegate.swift */,
53A35EAC1D88677A00A84CDE /* WindowController.swift */,
536F82391D8863010029689C /* ViewController.swift */,
534101101AFD23B2003BC1D6 /* Supporting Files */,
);
name = ToolbarSample;
path = SimpleApp;
sourceTree = "<group>";
};
534101101AFD23B2003BC1D6 /* Supporting Files */ = {
isa = PBXGroup;
children = (
536F82451D88631C0029689C /* Images.xcassets */,
536F82441D8863170029689C /* Info.plist */,
536F823B1D88630C0029689C /* Main.storyboard */,
536F823E1D8863110029689C /* Credits.rtf */,
536F82401D8863110029689C /* InfoPlist.strings */,
);
name = "Supporting Files";
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
5341010C1AFD23B2003BC1D6 /* ToolbarSample */ = {
isa = PBXNativeTarget;
buildConfigurationList = 534101291AFD23B3003BC1D6 /* Build configuration list for PBXNativeTarget "ToolbarSample" */;
buildPhases = (
534101091AFD23B2003BC1D6 /* Sources */,
5341010A1AFD23B2003BC1D6 /* Frameworks */,
5341010B1AFD23B2003BC1D6 /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = ToolbarSample;
productName = SimpleApp;
productReference = 5341010D1AFD23B2003BC1D6 /* ToolbarSample.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
534101051AFD23B2003BC1D6 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0810;
ORGANIZATIONNAME = keith;
TargetAttributes = {
5341010C1AFD23B2003BC1D6 = {
CreatedOnToolsVersion = 6.3.1;
LastSwiftMigration = 0810;
};
};
};
buildConfigurationList = 534101081AFD23B2003BC1D6 /* Build configuration list for PBXProject "ToolbarSample" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = 534101041AFD23B2003BC1D6;
productRefGroup = 5341010E1AFD23B2003BC1D6 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
5341010C1AFD23B2003BC1D6 /* ToolbarSample */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
5341010B1AFD23B2003BC1D6 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
536F823D1D88630C0029689C /* Main.storyboard in Resources */,
536F82461D88631C0029689C /* Images.xcassets in Resources */,
536F82431D8863110029689C /* InfoPlist.strings in Resources */,
536F82421D8863110029689C /* Credits.rtf in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
534101091AFD23B2003BC1D6 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
536F823A1D8863010029689C /* ViewController.swift in Sources */,
53A35EAD1D88677A00A84CDE /* WindowController.swift in Sources */,
536F82381D8862FA0029689C /* AppDelegate.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
536F823B1D88630C0029689C /* Main.storyboard */ = {
isa = PBXVariantGroup;
children = (
536F823C1D88630C0029689C /* Base */,
);
name = Main.storyboard;
sourceTree = "<group>";
};
536F823E1D8863110029689C /* Credits.rtf */ = {
isa = PBXVariantGroup;
children = (
536F823F1D8863110029689C /* en */,
);
name = Credits.rtf;
sourceTree = "<group>";
};
536F82401D8863110029689C /* InfoPlist.strings */ = {
isa = PBXVariantGroup;
children = (
536F82411D8863110029689C /* en */,
);
name = InfoPlist.strings;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
534101271AFD23B3003BC1D6 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "-";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.11;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
};
name = Debug;
};
534101281AFD23B3003BC1D6 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "-";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.11;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = macosx;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
};
name = Release;
};
5341012A1AFD23B3003BC1D6 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
COMBINE_HIDPI_IMAGES = YES;
INFOPLIST_FILE = ToolbarSample/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
MACOSX_DEPLOYMENT_TARGET = 10.11;
PRODUCT_BUNDLE_IDENTIFIER = "com.example.apple-samplecode.ToolbarSample";
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = macosx;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 3.0;
};
name = Debug;
};
5341012B1AFD23B3003BC1D6 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
COMBINE_HIDPI_IMAGES = YES;
INFOPLIST_FILE = ToolbarSample/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
MACOSX_DEPLOYMENT_TARGET = 10.11;
PRODUCT_BUNDLE_IDENTIFIER = "com.example.apple-samplecode.ToolbarSample";
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = macosx;
SWIFT_VERSION = 3.0;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
534101081AFD23B2003BC1D6 /* Build configuration list for PBXProject "ToolbarSample" */ = {
isa = XCConfigurationList;
buildConfigurations = (
534101271AFD23B3003BC1D6 /* Debug */,
534101281AFD23B3003BC1D6 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
534101291AFD23B3003BC1D6 /* Build configuration list for PBXNativeTarget "ToolbarSample" */ = {
isa = XCConfigurationList;
buildConfigurations = (
5341012A1AFD23B3003BC1D6 /* Debug */,
5341012B1AFD23B3003BC1D6 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 534101051AFD23B2003BC1D6 /* Project object */;
}

View File

@ -0,0 +1,29 @@
/*
Copyright (C) 2016 Apple Inc. All Rights Reserved.
See LICENSE.txt for this samples licensing information
Abstract:
The main NSApplicationDelegate to this sample.
*/
import Cocoa
@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
func applicationDidFinishLaunching(_ aNotification: Notification) {
// Insert code here to initialize your application
// Here we just opt-in for allowing our instance of the NSTouchBar class to be customized throughout the app.
if #available(OSX 10.12.1, *) {
if ((NSClassFromString("NSTouchBar")) != nil) {
NSApplication.shared().isAutomaticCustomizeTouchBarMenuItemEnabled = true
}
}
}
func applicationWillTerminate(_ aNotification: Notification) {
// Insert code here to tear down your application
}
}

View File

@ -0,0 +1,581 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="11539" systemVersion="16B2656" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" initialViewController="B8D-0N-5wS">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="11539"/>
<capability name="Alignment constraints to the first baseline" minToolsVersion="6.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--Application-->
<scene sceneID="JPo-4y-FX3">
<objects>
<application id="hnw-xV-0zn" sceneMemberID="viewController">
<menu key="mainMenu" title="Main Menu" systemMenu="main" id="AYu-sK-qS6">
<items>
<menuItem title="ToolbarSample" id="1Xt-HY-uBw">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="ToolbarSample" systemMenu="apple" id="uQy-DD-JDr">
<items>
<menuItem title="About ToolbarSample" id="5kV-Vb-QxS">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="orderFrontStandardAboutPanel:" target="Ady-hI-5gd" id="Exp-CZ-Vem"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="VOq-y0-SEH"/>
<menuItem title="Preferences…" keyEquivalent="," id="BOF-NM-1cW"/>
<menuItem isSeparatorItem="YES" id="wFC-TO-SCJ"/>
<menuItem title="Services" id="NMo-om-nkz">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Services" systemMenu="services" id="hz9-B4-Xy5"/>
</menuItem>
<menuItem isSeparatorItem="YES" id="4je-JR-u6R"/>
<menuItem title="Hide ToolbarSample" keyEquivalent="h" id="Olw-nP-bQN">
<connections>
<action selector="hide:" target="Ady-hI-5gd" id="PnN-Uc-m68"/>
</connections>
</menuItem>
<menuItem title="Hide Others" keyEquivalent="h" id="Vdr-fp-XzO">
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
<connections>
<action selector="hideOtherApplications:" target="Ady-hI-5gd" id="VT4-aY-XCT"/>
</connections>
</menuItem>
<menuItem title="Show All" id="Kd2-mp-pUS">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="unhideAllApplications:" target="Ady-hI-5gd" id="Dhg-Le-xox"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="kCx-OE-vgT"/>
<menuItem title="Quit ToolbarSample" keyEquivalent="q" id="4sb-4s-VLi">
<connections>
<action selector="terminate:" target="Ady-hI-5gd" id="Te7-pn-YzF"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="File" id="dMs-cI-mzQ">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="File" id="bib-Uj-vzu">
<items>
<menuItem title="New" keyEquivalent="n" id="Was-JA-tGl">
<connections>
<action selector="newDocument:" target="Ady-hI-5gd" id="4Si-XN-c54"/>
</connections>
</menuItem>
<menuItem title="Open…" keyEquivalent="o" id="IAo-SY-fd9">
<connections>
<action selector="openDocument:" target="Ady-hI-5gd" id="bVn-NM-KNZ"/>
</connections>
</menuItem>
<menuItem title="Open Recent" id="tXI-mr-wws">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Open Recent" systemMenu="recentDocuments" id="oas-Oc-fiZ">
<items>
<menuItem title="Clear Menu" id="vNY-rz-j42">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="clearRecentDocuments:" target="Ady-hI-5gd" id="Daa-9d-B3U"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem isSeparatorItem="YES" id="m54-Is-iLE"/>
<menuItem title="Close" keyEquivalent="w" id="DVo-aG-piG">
<connections>
<action selector="performClose:" target="Ady-hI-5gd" id="HmO-Ls-i7Q"/>
</connections>
</menuItem>
<menuItem title="Save…" keyEquivalent="s" id="pxx-59-PXV">
<connections>
<action selector="saveDocument:" target="Ady-hI-5gd" id="teZ-XB-qJY"/>
</connections>
</menuItem>
<menuItem title="Save As…" keyEquivalent="S" id="Bw7-FT-i3A">
<connections>
<action selector="saveDocumentAs:" target="Ady-hI-5gd" id="mDf-zr-I0C"/>
</connections>
</menuItem>
<menuItem title="Revert to Saved" id="KaW-ft-85H">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="revertDocumentToSaved:" target="Ady-hI-5gd" id="iJ3-Pv-kwq"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="aJh-i4-bef"/>
<menuItem title="Page Setup…" keyEquivalent="P" id="qIS-W8-SiK">
<modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
<connections>
<action selector="runPageLayout:" target="Ady-hI-5gd" id="Din-rz-gC5"/>
</connections>
</menuItem>
<menuItem title="Print…" keyEquivalent="p" id="aTl-1u-JFS">
<connections>
<action selector="print:" target="Ady-hI-5gd" id="qaZ-4w-aoO"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Edit" id="5QF-Oa-p0T">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Edit" id="W48-6f-4Dl">
<items>
<menuItem title="Undo" keyEquivalent="z" id="dRJ-4n-Yzg">
<connections>
<action selector="undo:" target="Ady-hI-5gd" id="M6e-cu-g7V"/>
</connections>
</menuItem>
<menuItem title="Redo" keyEquivalent="Z" id="6dh-zS-Vam">
<connections>
<action selector="redo:" target="Ady-hI-5gd" id="oIA-Rs-6OD"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="WRV-NI-Exz"/>
<menuItem title="Cut" keyEquivalent="x" id="uRl-iY-unG">
<connections>
<action selector="cut:" target="Ady-hI-5gd" id="YJe-68-I9s"/>
</connections>
</menuItem>
<menuItem title="Copy" keyEquivalent="c" id="x3v-GG-iWU">
<connections>
<action selector="copy:" target="Ady-hI-5gd" id="G1f-GL-Joy"/>
</connections>
</menuItem>
<menuItem title="Paste" keyEquivalent="v" id="gVA-U4-sdL">
<connections>
<action selector="paste:" target="Ady-hI-5gd" id="UvS-8e-Qdg"/>
</connections>
</menuItem>
<menuItem title="Paste and Match Style" keyEquivalent="V" id="WeT-3V-zwk">
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
<connections>
<action selector="pasteAsPlainText:" target="Ady-hI-5gd" id="cEh-KX-wJQ"/>
</connections>
</menuItem>
<menuItem title="Delete" id="pa3-QI-u2k">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="delete:" target="Ady-hI-5gd" id="0Mk-Ml-PaM"/>
</connections>
</menuItem>
<menuItem title="Select All" keyEquivalent="a" id="Ruw-6m-B2m">
<connections>
<action selector="selectAll:" target="Ady-hI-5gd" id="VNm-Mi-diN"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="uyl-h8-XO2"/>
<menuItem title="Find" id="4EN-yA-p0u">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Find" id="1b7-l0-nxx">
<items>
<menuItem title="Find…" tag="1" keyEquivalent="f" id="Xz5-n4-O0W">
<connections>
<action selector="performFindPanelAction:" target="Ady-hI-5gd" id="cD7-Qs-BN4"/>
</connections>
</menuItem>
<menuItem title="Find and Replace…" tag="12" keyEquivalent="f" id="YEy-JH-Tfz">
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
<connections>
<action selector="performFindPanelAction:" target="Ady-hI-5gd" id="WD3-Gg-5AJ"/>
</connections>
</menuItem>
<menuItem title="Find Next" tag="2" keyEquivalent="g" id="q09-fT-Sye">
<connections>
<action selector="performFindPanelAction:" target="Ady-hI-5gd" id="NDo-RZ-v9R"/>
</connections>
</menuItem>
<menuItem title="Find Previous" tag="3" keyEquivalent="G" id="OwM-mh-QMV">
<connections>
<action selector="performFindPanelAction:" target="Ady-hI-5gd" id="HOh-sY-3ay"/>
</connections>
</menuItem>
<menuItem title="Use Selection for Find" tag="7" keyEquivalent="e" id="buJ-ug-pKt">
<connections>
<action selector="performFindPanelAction:" target="Ady-hI-5gd" id="U76-nv-p5D"/>
</connections>
</menuItem>
<menuItem title="Jump to Selection" keyEquivalent="j" id="S0p-oC-mLd">
<connections>
<action selector="centerSelectionInVisibleArea:" target="Ady-hI-5gd" id="IOG-6D-g5B"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Spelling and Grammar" id="Dv1-io-Yv7">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Spelling" id="3IN-sU-3Bg">
<items>
<menuItem title="Show Spelling and Grammar" keyEquivalent=":" id="HFo-cy-zxI">
<connections>
<action selector="showGuessPanel:" target="Ady-hI-5gd" id="vFj-Ks-hy3"/>
</connections>
</menuItem>
<menuItem title="Check Document Now" keyEquivalent=";" id="hz2-CU-CR7">
<connections>
<action selector="checkSpelling:" target="Ady-hI-5gd" id="fz7-VC-reM"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="bNw-od-mp5"/>
<menuItem title="Check Spelling While Typing" id="rbD-Rh-wIN">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleContinuousSpellChecking:" target="Ady-hI-5gd" id="7w6-Qz-0kB"/>
</connections>
</menuItem>
<menuItem title="Check Grammar With Spelling" id="mK6-2p-4JG">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleGrammarChecking:" target="Ady-hI-5gd" id="muD-Qn-j4w"/>
</connections>
</menuItem>
<menuItem title="Correct Spelling Automatically" id="78Y-hA-62v">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleAutomaticSpellingCorrection:" target="Ady-hI-5gd" id="2lM-Qi-WAP"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Substitutions" id="9ic-FL-obx">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Substitutions" id="FeM-D8-WVr">
<items>
<menuItem title="Show Substitutions" id="z6F-FW-3nz">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="orderFrontSubstitutionsPanel:" target="Ady-hI-5gd" id="oku-mr-iSq"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="gPx-C9-uUO"/>
<menuItem title="Smart Copy/Paste" id="9yt-4B-nSM">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleSmartInsertDelete:" target="Ady-hI-5gd" id="3IJ-Se-DZD"/>
</connections>
</menuItem>
<menuItem title="Smart Quotes" id="hQb-2v-fYv">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleAutomaticQuoteSubstitution:" target="Ady-hI-5gd" id="ptq-xd-QOA"/>
</connections>
</menuItem>
<menuItem title="Smart Dashes" id="rgM-f4-ycn">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleAutomaticDashSubstitution:" target="Ady-hI-5gd" id="oCt-pO-9gS"/>
</connections>
</menuItem>
<menuItem title="Smart Links" id="cwL-P1-jid">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleAutomaticLinkDetection:" target="Ady-hI-5gd" id="Gip-E3-Fov"/>
</connections>
</menuItem>
<menuItem title="Data Detectors" id="tRr-pd-1PS">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleAutomaticDataDetection:" target="Ady-hI-5gd" id="R1I-Nq-Kbl"/>
</connections>
</menuItem>
<menuItem title="Text Replacement" id="HFQ-gK-NFA">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleAutomaticTextReplacement:" target="Ady-hI-5gd" id="DvP-Fe-Py6"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Transformations" id="2oI-Rn-ZJC">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Transformations" id="c8a-y6-VQd">
<items>
<menuItem title="Make Upper Case" id="vmV-6d-7jI">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="uppercaseWord:" target="Ady-hI-5gd" id="sPh-Tk-edu"/>
</connections>
</menuItem>
<menuItem title="Make Lower Case" id="d9M-CD-aMd">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="lowercaseWord:" target="Ady-hI-5gd" id="iUZ-b5-hil"/>
</connections>
</menuItem>
<menuItem title="Capitalize" id="UEZ-Bs-lqG">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="capitalizeWord:" target="Ady-hI-5gd" id="26H-TL-nsh"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Speech" id="xrE-MZ-jX0">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Speech" id="3rS-ZA-NoH">
<items>
<menuItem title="Start Speaking" id="Ynk-f8-cLZ">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="startSpeaking:" target="Ady-hI-5gd" id="654-Ng-kyl"/>
</connections>
</menuItem>
<menuItem title="Stop Speaking" id="Oyz-dy-DGm">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="stopSpeaking:" target="Ady-hI-5gd" id="dX8-6p-jy9"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="View" id="nS5-Px-4EY">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="View" id="C2T-yi-Hre">
<items>
<menuItem title="Show Toolbar" keyEquivalent="t" id="wwP-s1-PoA">
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
<connections>
<action selector="toggleToolbarShown:" target="Ady-hI-5gd" id="jSK-6R-NOk"/>
</connections>
</menuItem>
<menuItem title="Customize Toolbar…" id="paG-Oo-HPx">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="runToolbarCustomizationPalette:" target="Ady-hI-5gd" id="pHz-7a-muD"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="Y6i-Qv-Kwb"/>
<menuItem title="Enter Full Screen" keyEquivalent="f" id="ifB-0x-Hff">
<modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
<connections>
<action selector="toggleFullScreen:" target="Ady-hI-5gd" id="fMm-h6-iQ4"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Window" id="aUF-d1-5bR">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Window" systemMenu="window" id="Td7-aD-5lo">
<items>
<menuItem title="Minimize" keyEquivalent="m" id="OY7-WF-poV">
<connections>
<action selector="performMiniaturize:" target="Ady-hI-5gd" id="VwT-WD-YPe"/>
</connections>
</menuItem>
<menuItem title="Zoom" id="R4o-n2-Eq4">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="performZoom:" target="Ady-hI-5gd" id="DIl-cC-cCs"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="eu3-7i-yIM"/>
<menuItem title="Bring All to Front" id="LE2-aR-0XJ">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="arrangeInFront:" target="Ady-hI-5gd" id="DRN-fu-gQh"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Help" id="wpr-3q-Mcd">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Help" systemMenu="help" id="F2S-fz-NVQ">
<items>
<menuItem title="ToolbarSample Help" keyEquivalent="?" id="FKE-Sm-Kum">
<connections>
<action selector="showHelp:" target="Ady-hI-5gd" id="y7X-2Q-9no"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
</items>
</menu>
<connections>
<outlet property="delegate" destination="Voe-Tx-rLC" id="PrD-fu-P6m"/>
</connections>
</application>
<customObject id="Voe-Tx-rLC" customClass="AppDelegate" customModule="ToolbarSample" customModuleProvider="target"/>
<customObject id="Ady-hI-5gd" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="61" y="-330"/>
</scene>
<!--Window Controller-->
<scene sceneID="R2V-B0-nI4">
<objects>
<windowController id="B8D-0N-5wS" customClass="WindowController" customModule="ToolbarSample" customModuleProvider="target" sceneMemberID="viewController">
<window key="window" title="ToolbarSample" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" oneShot="NO" releasedWhenClosed="NO" showsToolbarButton="NO" visibleAtLaunch="NO" frameAutosaveName="ToolbarSample" animationBehavior="default" id="IQv-IB-iLA">
<windowStyleMask key="styleMask" titled="YES" miniaturizable="YES" resizable="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="196" y="240" width="480" height="270"/>
<rect key="screenRect" x="0.0" y="0.0" width="1440" height="877"/>
<toolbar key="toolbar" implicitIdentifier="F8CA7AA2-5A62-473D-B222-1F11EF7E3026" autosavesConfiguration="NO" displayMode="iconAndLabel" sizeMode="regular" id="NEu-kE-jCa">
<allowedToolbarItems>
<toolbarItem implicitItemIdentifier="NSToolbarPrintItem" id="oLG-k5-dmS"/>
<toolbarItem implicitItemIdentifier="NSToolbarSpaceItem" id="pPS-R7-wPH"/>
<toolbarItem implicitItemIdentifier="NSToolbarFlexibleSpaceItem" id="ZiS-fg-jPF"/>
</allowedToolbarItems>
<defaultToolbarItems>
<toolbarItem reference="ZiS-fg-jPF"/>
</defaultToolbarItems>
<connections>
<outlet property="delegate" destination="B8D-0N-5wS" id="aY6-vG-xqY"/>
</connections>
</toolbar>
</window>
<connections>
<outlet property="fontSizeField" destination="O13-Lp-9wy" id="sry-7R-lna"/>
<outlet property="fontSizeStepper" destination="6Ik-fl-t4C" id="rpq-xN-Wqd"/>
<outlet property="fontSizeView" destination="M8v-Hh-NCb" id="sOT-xO-dvJ"/>
<outlet property="styleSegmentView" destination="qfS-eS-YW1" id="1nv-W8-scO"/>
<outlet property="toolbar" destination="NEu-kE-jCa" id="0er-cX-7dq"/>
<segue destination="XfG-lQ-9wD" kind="relationship" relationship="window.shadowedContentViewController" id="tBF-l5-AU8"/>
</connections>
</windowController>
<customView id="M8v-Hh-NCb" userLabel="FontSizeView">
<rect key="frame" x="0.0" y="0.0" width="135" height="32"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="2OG-pA-l2L">
<rect key="frame" x="4" y="6" width="64" height="20"/>
<textFieldCell key="cell" sendsActionOnEndEditing="YES" alignment="left" title="Font Size:" id="qDh-6i-VFR">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="O13-Lp-9wy">
<rect key="frame" x="91" y="4" width="39" height="24"/>
<constraints>
<constraint firstAttribute="width" constant="39" id="0b0-R4-ClH"/>
</constraints>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" alignment="left" title="12" drawsBackground="YES" id="FIG-K8-SKG">
<font key="font" metaFont="system"/>
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<stepper horizontalHuggingPriority="750" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="6Ik-fl-t4C">
<rect key="frame" x="68" y="3" width="19" height="27"/>
<constraints>
<constraint firstAttribute="height" constant="23" id="jTq-Mo-5zL"/>
</constraints>
<stepperCell key="cell" continuous="YES" alignment="left" minValue="6" maxValue="128" doubleValue="12" valueWraps="YES" id="eUV-3P-WTN"/>
<connections>
<action selector="changeFontSize:" target="B8D-0N-5wS" id="nSK-jo-xbF"/>
<binding destination="B8D-0N-5wS" name="value" keyPath="self.currentFontSize" id="9RJ-Dy-LFR"/>
</connections>
</stepper>
</subviews>
<constraints>
<constraint firstItem="6Ik-fl-t4C" firstAttribute="centerY" secondItem="O13-Lp-9wy" secondAttribute="centerY" id="1aA-0m-hVX"/>
<constraint firstItem="6Ik-fl-t4C" firstAttribute="leading" secondItem="2OG-pA-l2L" secondAttribute="trailing" constant="5" id="8FP-hX-GYz"/>
<constraint firstItem="O13-Lp-9wy" firstAttribute="firstBaseline" secondItem="2OG-pA-l2L" secondAttribute="firstBaseline" id="Pz8-50-onC"/>
<constraint firstItem="6Ik-fl-t4C" firstAttribute="top" secondItem="O13-Lp-9wy" secondAttribute="top" id="gNU-LE-yi4"/>
<constraint firstItem="O13-Lp-9wy" firstAttribute="leading" secondItem="6Ik-fl-t4C" secondAttribute="trailing" constant="7" id="pzJ-DY-aZS"/>
<constraint firstItem="2OG-pA-l2L" firstAttribute="leading" secondItem="M8v-Hh-NCb" secondAttribute="leading" constant="6" id="s53-Rg-ZLW"/>
<constraint firstItem="6Ik-fl-t4C" firstAttribute="centerY" secondItem="2OG-pA-l2L" secondAttribute="centerY" id="t1C-f3-8Vz"/>
<constraint firstItem="2OG-pA-l2L" firstAttribute="centerY" secondItem="M8v-Hh-NCb" secondAttribute="centerY" id="tCg-zE-3qo"/>
</constraints>
</customView>
<customView id="qfS-eS-YW1" userLabel="FontStyleView">
<rect key="frame" x="0.0" y="0.0" width="180" height="32"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<segmentedControl verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="EeD-gK-loT">
<rect key="frame" x="4" y="4" width="172" height="24"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<segmentedCell key="cell" borderStyle="border" alignment="left" style="rounded" trackingMode="momentary" id="gCR-40-2gS">
<font key="font" metaFont="system"/>
<segments>
<segment label="Plain" width="55"/>
<segment label="Bold" width="55" tag="1"/>
<segment label="Italic" width="54"/>
</segments>
</segmentedCell>
<connections>
<action selector="changeFontStyleBySegment:" target="B8D-0N-5wS" id="ltU-wg-HkW"/>
</connections>
</segmentedControl>
</subviews>
</customView>
<customObject id="Oky-zY-oP4" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
<menu title="Menu" id="HLa-Sh-YdR" userLabel="Font Style Menu">
<items>
<menuItem title="Plain Text" tag="1" id="loP-Kq-bCu"/>
<menuItem title="Bold" tag="2" id="2aH-Fe-eye"/>
<menuItem title="Italic" tag="3" id="FCe-0M-1jl"/>
</items>
</menu>
</objects>
<point key="canvasLocation" x="75" y="250"/>
</scene>
<!--View Controller-->
<scene sceneID="hIz-AP-VOD">
<objects>
<viewController id="XfG-lQ-9wD" customClass="ViewController" customModule="ToolbarSample" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" id="m2S-Jp-Qdl">
<rect key="frame" x="0.0" y="0.0" width="480" height="270"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<scrollView horizontalLineScroll="10" horizontalPageScroll="10" verticalLineScroll="10" verticalPageScroll="10" hasHorizontalScroller="NO" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="xBx-mF-oRY">
<rect key="frame" x="0.0" y="0.0" width="480" height="270"/>
<clipView key="contentView" id="vdA-vl-fbY">
<rect key="frame" x="1" y="1" width="463" height="268"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textView importsGraphics="NO" usesFontPanel="YES" findStyle="panel" continuousSpellChecking="YES" allowsUndo="YES" usesRuler="YES" allowsNonContiguousLayout="YES" quoteSubstitution="YES" dashSubstitution="YES" spellingCorrection="YES" smartInsertDelete="YES" id="5cg-ux-stu">
<rect key="frame" x="0.0" y="0.0" width="463" height="268"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<size key="minSize" width="463" height="268"/>
<size key="maxSize" width="503" height="10000000"/>
<color key="insertionPointColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<connections>
<outlet property="delegate" destination="XfG-lQ-9wD" id="eb2-tK-hFy"/>
</connections>
</textView>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
</clipView>
<scroller key="horizontalScroller" hidden="YES" verticalHuggingPriority="750" doubleValue="1" horizontal="YES" id="8ph-gU-IEz">
<rect key="frame" x="-100" y="-100" width="87" height="18"/>
<autoresizingMask key="autoresizingMask"/>
</scroller>
<scroller key="verticalScroller" verticalHuggingPriority="750" doubleValue="1" horizontal="NO" id="l21-yu-v6h">
<rect key="frame" x="464" y="1" width="15" height="268"/>
<autoresizingMask key="autoresizingMask"/>
</scroller>
</scrollView>
</subviews>
<constraints>
<constraint firstItem="xBx-mF-oRY" firstAttribute="top" secondItem="m2S-Jp-Qdl" secondAttribute="top" id="gRP-Gd-nLT"/>
<constraint firstItem="xBx-mF-oRY" firstAttribute="leading" secondItem="m2S-Jp-Qdl" secondAttribute="leading" id="kZA-kp-Suv"/>
<constraint firstAttribute="bottom" secondItem="xBx-mF-oRY" secondAttribute="bottom" id="oJZ-oJ-vW2"/>
<constraint firstAttribute="trailing" secondItem="xBx-mF-oRY" secondAttribute="trailing" id="zjh-n1-oMa"/>
</constraints>
</view>
<connections>
<outlet property="textView" destination="5cg-ux-stu" id="lM5-rk-mp2"/>
</connections>
</viewController>
<customObject id="rPt-NT-nkU" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="75" y="789"/>
</scene>
</scenes>
</document>

View File

@ -0,0 +1,58 @@
{
"images" : [
{
"idiom" : "mac",
"size" : "16x16",
"scale" : "1x"
},
{
"idiom" : "mac",
"size" : "16x16",
"scale" : "2x"
},
{
"idiom" : "mac",
"size" : "32x32",
"scale" : "1x"
},
{
"idiom" : "mac",
"size" : "32x32",
"scale" : "2x"
},
{
"idiom" : "mac",
"size" : "128x128",
"scale" : "1x"
},
{
"idiom" : "mac",
"size" : "128x128",
"scale" : "2x"
},
{
"idiom" : "mac",
"size" : "256x256",
"scale" : "1x"
},
{
"idiom" : "mac",
"size" : "256x256",
"scale" : "2x"
},
{
"idiom" : "mac",
"size" : "512x512",
"scale" : "1x"
},
{
"idiom" : "mac",
"size" : "512x512",
"scale" : "2x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@ -0,0 +1,6 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIconFile</key>
<string></string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>3.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSMinimumSystemVersion</key>
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
<key>NSMainStoryboardFile</key>
<string>Main</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
</dict>
</plist>

View File

@ -0,0 +1,50 @@
/*
Copyright (C) 2016 Apple Inc. All Rights Reserved.
See LICENSE.txt for this samples licensing information
Abstract:
The primary view controller holding the toolbar and text view.
*/
import Cocoa
class ViewController: NSViewController, NSTextViewDelegate {
@IBOutlet var textView: NSTextView!
// MARK: - View Controller Life Cycle
override func viewDidLoad()
{
super.viewDidLoad()
self.textView.delegate = self
if #available(OSX 10.12.1, *) {
// Opt-out of text completion in this simplified version.
if ((NSClassFromString("NSTouchBar")) != nil) {
self.textView?.isAutomaticTextCompletionEnabled = false
}
} else {
// Fallback on earlier versions
}
self.view.window?.makeFirstResponder(self.textView)
// Do any additional setup after loading the view.
}
override var representedObject: Any?
{
didSet {
// Update the view, if already loaded.
}
}
// MARK: - NSTextViewDelegate
func textView(_ textView: NSTextView, shouldUpdateTouchBarItemIdentifiers identifiers: [NSTouchBarItemIdentifier]) -> [NSTouchBarItemIdentifier] {
return [] // We want to show only our NSTouchBarItem instances.
}
}

View File

@ -0,0 +1,419 @@
/*
Copyright (C) 2016 Apple Inc. All Rights Reserved.
See LICENSE.txt for this samples licensing information
Abstract:
The primary window controller for this sample.
*/
import Cocoa
fileprivate extension NSTouchBarCustomizationIdentifier {
static let touchBar = NSTouchBarCustomizationIdentifier("com.ToolbarSample.touchBar")
}
fileprivate extension NSTouchBarItemIdentifier {
static let popover = NSTouchBarItemIdentifier("com.ToolbarSample.TouchBarItem.popover")
static let fontStyle = NSTouchBarItemIdentifier("com.ToolbarSample.TouchBarItem.fontStyle")
static let popoverSlider = NSTouchBarItemIdentifier("com.ToolbarSample.popoverBar.slider")
}
class WindowController: NSWindowController, NSToolbarDelegate {
let FontSizeToolbarItemID = "FontSize"
let FontStyleToolbarItemID = "FontStyle"
let DefaultFontSize : Int = 18
@IBOutlet weak var toolbar: NSToolbar!
// Font style toolbar item.
@IBOutlet var styleSegmentView: NSView! // The font style changing view (ends up in an NSToolbarItem).
// Font size toolbar item.
@IBOutlet var fontSizeView: NSView! // The font size changing view (ends up in an NSToolbarItem).
@IBOutlet var fontSizeStepper: NSStepper!
@IBOutlet var fontSizeField: NSTextField!
var currentFontSize: Int = 0
// MARK: - Window Controller Life Cycle
override func windowDidLoad() {
super.windowDidLoad()
self.currentFontSize = DefaultFontSize
// Configure our toolbar (note: this can also be done in Interface Builder).
/* If you pass NO here, you turn off the customization palette. The palette is normally handled
automatically for you by NSWindow's -runToolbarCustomizationPalette: function; you'll notice
that the "Customize Toolbar" menu item is hooked up to that method in Interface Builder.
*/
self.toolbar.allowsUserCustomization = true
/* Tell the toolbar that it should save any configuration changes to user defaults, i.e. mode
changes, or reordering will persist. Specifically they will be written in the app domain using
the toolbar identifier as the key.
*/
self.toolbar.autosavesConfiguration = true
// Tell the toolbar to show icons only by default.
self.toolbar.displayMode = .iconOnly
// Initialize our font size control here to 18-point font, and set our view controller's NSTextView to that size.
self.fontSizeStepper.integerValue = Int(DefaultFontSize)
self.fontSizeField.stringValue = String(DefaultFontSize)
let font = NSFont(name: "Helvetica", size: CGFloat(DefaultFontSize))
self.contentTextView().font = font
if #available(OSX 10.12.1, *) {
if ((NSClassFromString("NSTouchBar")) != nil) {
let fontSizeTouchBarItem = self.touchBar!.item(forIdentifier: .popover) as! NSPopoverTouchBarItem
let sliderTouchBar = fontSizeTouchBarItem.popoverTouchBar
let sliderTouchBarItem = sliderTouchBar.item(forIdentifier: .popoverSlider) as! NSSliderTouchBarItem
let slider = sliderTouchBarItem.slider
// Make the font size slider a bit narrowed, about 250 pixels.
let views = ["slider" : slider]
let theConstraints = NSLayoutConstraint.constraints(withVisualFormat: "H:[slider(250)]", options: NSLayoutFormatOptions(), metrics: nil, views:views)
NSLayoutConstraint.activate(theConstraints)
// Set the font size for the slider item to the same value as the stepper.
slider.integerValue = DefaultFontSize
}
}
}
// Convenince accessor to our NSTextView found in our content view controller.
func contentTextView() -> NSTextView {
return (self.contentViewController as! ViewController).textView
}
// MARK: - Font and Size setters
func setTextViewFontSize(fontSize: Float) {
fontSizeField.floatValue = round(fontSize)
let attrs = self.contentTextView().typingAttributes
var theFont : NSFont = attrs["NSFont"] as! NSFont
theFont = NSFontManager.shared().convert(theFont, toSize: CGFloat(fontSize))
if (self.contentTextView().selectedRange().length > 0) {
// We have a selection, change the selected text
self.contentTextView().setFont(theFont, range: self.contentTextView().selectedRange())
}
else {
// No selection, so just change the font size at insertion.
let attributesDict = [ NSFontAttributeName: theFont ]
self.contentTextView().typingAttributes = attributesDict
}
}
/**
This action is called to change the font style.
It is called through it's popup toolbar item and segmented control item.
*/
func setTextViewFont(index: Int) {
let attrs = self.contentTextView().typingAttributes
var theFont : NSFont = attrs["NSFont"] as! NSFont
// Set the font properties depending upon what was selected.
switch (index) {
case 0: // plain
theFont = NSFontManager.shared().convert(theFont, toNotHaveTrait:.italicFontMask)
theFont = NSFontManager.shared().convert(theFont, toNotHaveTrait:.boldFontMask)
theFont = NSFontManager.shared().convert(theFont, toNotHaveTrait:.boldFontMask)
// No underline attribute.
let selectedRange = self.contentTextView().selectedRange()
let textStorage = self.contentTextView().textStorage
textStorage?.removeAttribute(NSForegroundColorAttributeName, range: selectedRange)
textStorage?.addAttribute(NSUnderlineStyleAttributeName, value: NSNumber.init(value: 0), range: selectedRange)
case 1: // bold
theFont = NSFontManager.shared().convert(theFont, toNotHaveTrait:.italicFontMask)
theFont = NSFontManager.shared().convert(theFont, toHaveTrait:.boldFontMask)
case 2: // italic
theFont = NSFontManager.shared().convert(theFont, toNotHaveTrait:.boldFontMask)
theFont = NSFontManager.shared().convert(theFont, toHaveTrait:.italicFontMask)
default:
print("invalid selection")
}
if (self.contentTextView().selectedRange().length > 0) {
// We have a selection, change the selected text
self.contentTextView().setFont(theFont, range: self.contentTextView().selectedRange())
}
else {
// No selection, so just change the font style at insertion.
let attributesDict = [ NSFontAttributeName: theFont ]
self.contentTextView().typingAttributes = attributesDict
}
}
// MARK: - Action Functions
/**
This action is called to change the font size.
It is called by the NSStepper in the toolbar item's custom view and the slider item.
*/
@IBAction func changeFontSize(_ sender: NSStepper) {
self.setTextViewFontSize(fontSize: sender.floatValue)
}
/// This action is called to change the font size from the slider item found in the NSTouchBar instance.
@IBAction func changeFontSizeBySlider(_ sender: NSSlider) {
self.setTextViewFontSize(fontSize: sender.floatValue)
}
/// This action is called from the change font style toolbar item, from the segmented control in the custom view.
@IBAction func changeFontStyleBySegment(_ sender: NSSegmentedControl) {
let style = sender.selectedSegment
self.setTextViewFont(index: style)
}
/// This is called by the appropriate toolbar item to toggle blue text on/off.
@IBAction func blueText(_ sender: AnyObject) {
if (self.contentTextView().selectedRange().length > 0) {
// We have a selection, change the selected text
let textStorage = self.contentTextView().textStorage
textStorage?.removeAttribute(NSForegroundColorAttributeName, range: self.contentTextView().selectedRange())
textStorage?.addAttribute(NSForegroundColorAttributeName, value: NSColor.blue, range: self.contentTextView().selectedRange())
}
else {
// No selection, so just change the font size at insertion.
var attrs = self.contentTextView().typingAttributes
attrs["NSColor"] = NSColor.blue
self.contentTextView().typingAttributes = attrs
}
}
/**
The NSToolbarPrintItem NSToolbarItem will send the -printDocument: message to its target.
Since we wired its target to be ourselves in -toolbarWillAddItem:, we get called here when
the user tries to print by clicking the toolbar item.
*/
func printDocument(_ sender: AnyObject) {
let printOperation = NSPrintOperation(view: self.contentTextView())
printOperation.runModal(for: self.window!, delegate: nil, didRun: nil, contextInfo: nil)
}
// Called when the user chooses a font style from the segmented control inside the NSTouchBar instance.
@IBAction func touchBarFontStyleAction(_ sender: NSSegmentedControl) {
self.setTextViewFont(index: sender.selectedSegment)
}
// MARK: - NSToolbarDelegate
/**
Factory method to create NSToolbarItems.
All NSToolbarItems have a unique identifer associated with them, used to tell your delegate/controller
what toolbar items to initialize and return at various points. Typically, for a given identifier,
you need to generate a copy of your "master" toolbar item, and return. The function
creates an NSToolbarItem with a bunch of NSToolbarItem paramenters.
It's easy to call this function repeatedly to generate lots of NSToolbarItems for your toolbar.
The label, palettelabel, toolTip, action, and menu can all be nil, depending upon what you want
the item to do.
*/
func customToolbarItem(itemForItemIdentifier itemIdentifier: String, label: String, paletteLabel: String, toolTip: String, target: AnyObject, itemContent: AnyObject, action: Selector?, menu: NSMenu?) -> NSToolbarItem? {
let toolbarItem = NSToolbarItem(itemIdentifier: itemIdentifier)
toolbarItem.label = label
toolbarItem.paletteLabel = paletteLabel
toolbarItem.toolTip = toolTip
toolbarItem.target = target
toolbarItem.action = action
// Set the right attribute, depending on if we were given an image or a view.
if (itemContent is NSImage) {
let image: NSImage = itemContent as! NSImage
toolbarItem.image = image
}
else if (itemContent is NSView) {
let view: NSView = itemContent as! NSView
toolbarItem.view = view
}
else {
assertionFailure("Invalid itemContent: object")
}
/* If this NSToolbarItem is supposed to have a menu "form representation" associated with it
(for text-only mode), we set it up here. Actually, you have to hand an NSMenuItem
(not a complete NSMenu) to the toolbar item, so we create a dummy NSMenuItem that has our real
menu as a submenu.
*/
// We actually need an NSMenuItem here, so we construct one.
let menuItem: NSMenuItem = NSMenuItem()
menuItem.submenu = menu
menuItem.title = label
toolbarItem.menuFormRepresentation = menuItem
return toolbarItem
}
/**
This is an optional delegate function, called when a new item is about to be added to the toolbar.
This is a good spot to set up initial state information for toolbar items, particularly items
that you don't directly control yourself (like with NSToolbarPrintItemIdentifier here).
The notification's object is the toolbar, and the "item" key in the userInfo is the toolbar item
being added.
*/
func toolbarWillAddItem(_ notification: Notification) {
let userInfo = notification.userInfo!
let addedItem = userInfo["item"] as! NSToolbarItem
let itemIdentifier = addedItem.itemIdentifier
if itemIdentifier == "NSToolbarPrintItem" {
addedItem.toolTip = "Print your document"
addedItem.target = self
}
}
/**
NSToolbar delegates require this function.
It takes an identifier, and returns the matching NSToolbarItem. It also takes a parameter telling
whether this toolbar item is going into an actual toolbar, or whether it's going to be displayed
in a customization palette.
*/
func toolbar(_ toolbar: NSToolbar, itemForItemIdentifier itemIdentifier: String, willBeInsertedIntoToolbar flag: Bool) -> NSToolbarItem? {
var toolbarItem: NSToolbarItem = NSToolbarItem()
/* We create a new NSToolbarItem, and then go through the process of setting up its
attributes from the master toolbar item matching that identifier in our dictionary of items.
*/
if (itemIdentifier == FontStyleToolbarItemID) {
// 1) Font style toolbar item.
toolbarItem = customToolbarItem(itemForItemIdentifier: FontStyleToolbarItemID, label: "Font Style", paletteLabel:"Font Style", toolTip: "Change your font style", target: self, itemContent: self.styleSegmentView, action: nil, menu: nil)!
}
else if (itemIdentifier == FontSizeToolbarItemID) {
// 2) Font size toolbar item.
toolbarItem = customToolbarItem(itemForItemIdentifier: FontSizeToolbarItemID, label: "Font Size", paletteLabel: "Font Size", toolTip: "Grow or shrink the size of your font", target: self, itemContent: self.fontSizeView, action: nil, menu: nil)!
}
return toolbarItem
}
/**
NSToolbar delegates require this function. It returns an array holding identifiers for the default
set of toolbar items. It can also be called by the customization palette to display the default toolbar.
*/
func toolbarDefaultItemIdentifiers(_ toolbar: NSToolbar) -> [String] {
return [FontStyleToolbarItemID, FontSizeToolbarItemID]
/* Note:
That since our toolbar is defined from Interface Builder, an additional separator and customize
toolbar items will be automatically added to the "default" list of items.
*/
}
/**
NSToolbar delegates require this function. It returns an array holding identifiers for all allowed
toolbar items in this toolbar. Any not listed here will not be available in the customization palette.
*/
func toolbarAllowedItemIdentifiers(_ toolbar: NSToolbar) -> [String] {
return [ FontStyleToolbarItemID,
FontSizeToolbarItemID,
NSToolbarSpaceItemIdentifier,
NSToolbarFlexibleSpaceItemIdentifier,
NSToolbarPrintItemIdentifier ]
}
// MARK: - NSTouchBar
@available(OSX 10.12.1, *)
override func makeTouchBar() -> NSTouchBar? {
let touchBar = NSTouchBar()
touchBar.delegate = self
touchBar.customizationIdentifier = .touchBar
touchBar.defaultItemIdentifiers = [.fontStyle, .popover, .otherItemsProxy]
touchBar.customizationAllowedItemIdentifiers = [.fontStyle, .popover]
return touchBar
}
}
extension WindowController: NSTouchBarDelegate {
@available(OSX 10.12.1, *)
func touchBar(_ touchBar: NSTouchBar, makeItemForIdentifier identifier: NSTouchBarItemIdentifier) -> NSTouchBarItem? {
switch identifier {
case NSTouchBarItemIdentifier.popover:
let popoverItem = NSPopoverTouchBarItem(identifier: identifier)
popoverItem.customizationLabel = "Font Size"
popoverItem.collapsedRepresentationLabel = "Font Size"
let secondaryTouchBar = NSTouchBar()
secondaryTouchBar.delegate = self
secondaryTouchBar.defaultItemIdentifiers = [.popoverSlider];
// We can setup a different NSTouchBar instance for popoverTouchBar and pressAndHoldTouchBar property
// Here we just use the same instance.
//
popoverItem.pressAndHoldTouchBar = secondaryTouchBar
popoverItem.popoverTouchBar = secondaryTouchBar
return popoverItem
case NSTouchBarItemIdentifier.fontStyle:
let fontStyleItem = NSCustomTouchBarItem(identifier: identifier)
fontStyleItem.customizationLabel = "Font Style"
let fontStyleSegment = NSSegmentedControl(labels: ["Plain", "Bold", "Italic"], trackingMode: .momentary, target: self, action: #selector(changeFontStyleBySegment))
fontStyleItem.view = fontStyleSegment
return fontStyleItem;
case NSTouchBarItemIdentifier.popoverSlider:
let sliderItem = NSSliderTouchBarItem(identifier: identifier)
sliderItem.label = "Size"
sliderItem.customizationLabel = "Font Size"
let slider = sliderItem.slider
slider.minValue = 6.0
slider.maxValue = 100.0
slider.target = self
slider.action = #selector(changeFontSizeBySlider)
// Set the font size for the slider item to the same value as the stepper.
slider.integerValue = DefaultFontSize
slider.bind(NSValueBinding, to: self, withKeyPath: "currentFontSize", options: nil)
return sliderItem
default: return nil
}
}
}

View File

@ -0,0 +1,9 @@
{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf350
{\fonttbl\f0\fnil\fcharset0 LucidaGrande;}
{\colortbl;\red255\green255\blue255;}
\pard\tx960\tx1920\tx2880\tx3840\tx4800\tx5760\tx6720\tx7680\tx8640\tx9600\qc
\f0\fs20 \cf0 Demonstrates how to use\
NSToolbar and NSToolbarItem\
to build a toolbar in your application.\
}

Binary file not shown.