From ce24f5cc4eb879f248f3363663c5330a06b1046f Mon Sep 17 00:00:00 2001 From: Joe Wreschnig Date: Wed, 6 Mar 2013 01:04:31 +0100 Subject: [PATCH] Start help book. Tweak UI to deal with issues discovered trying to explain it. --- English.lproj/MainMenu.xib | 321 ++++++++++++++++-------- Enjoyable Help/Enjoyable Help.helpindex | Bin 0 -> 11228 bytes Enjoyable Help/Enjoyable Help.html | 73 ++++++ Enjoyable Help/gfx/Icon.png | Bin 0 -> 18084 bytes Enjoyable Help/pgs/keyboard.html | 59 +++++ Enjoyable Help/pgs/mappings.html | 49 ++++ Enjoyable Help/pgs/template.html | 41 +++ Enjoyable Help/sty/default.css | 1 + Enjoyable.xcodeproj/project.pbxproj | 4 + Info.plist | 4 + NJDeviceController.h | 3 +- NJDeviceController.m | 8 +- NJKeyInputField.m | 8 +- 13 files changed, 460 insertions(+), 111 deletions(-) create mode 100644 Enjoyable Help/Enjoyable Help.helpindex create mode 100644 Enjoyable Help/Enjoyable Help.html create mode 100644 Enjoyable Help/gfx/Icon.png create mode 100644 Enjoyable Help/pgs/keyboard.html create mode 100644 Enjoyable Help/pgs/mappings.html create mode 100644 Enjoyable Help/pgs/template.html create mode 100644 Enjoyable Help/sty/default.css diff --git a/English.lproj/MainMenu.xib b/English.lproj/MainMenu.xib index cc6ba01..402d345 100644 --- a/English.lproj/MainMenu.xib +++ b/English.lproj/MainMenu.xib @@ -62,7 +62,7 @@ Enjoyable - + CA 1048576 2147483647 @@ -299,6 +299,30 @@ _NSWindowsMenu + + + Help + + 2147483647 + + + submenuAction: + + Help + + + + Enjoyable Help + ? + 1048576 + 2147483647 + + + + + _NSHelpMenu + + _NSMainMenu @@ -321,106 +345,100 @@ 2 1 - + - 4AC66688-76E8-47ED-AC0A-7462220A4019 + 2CB21E35-9CF1-4C67-9670-31139C914D10 - Mapping Selector - Mapping Selector + Enabled + Enabled - - + + 268 - {{0, 14}, {140, 25}} + {{7, 14}, {36, 25}} + + + _NS:9 YES - + 67108864 134217728 - (default) + LucidaGrande 13 1044 _NS:9 - - 918306816 + + -1228128256 163 - + NSImage - NSListViewTemplate + NSRightFacingTriangleTemplate - 400 - 75 + 200 + 25 NO - + - {13, 25} - {141, 25} + {36, 25} + {36, 25} YES - NO + YES 0 YES 0 - + - 94389EFE-310F-4DB5-95F6-D4AEE8839979 + 4AC66688-76E8-47ED-AC0A-7462220A4019 - Translation Switch - Translation Switch + Mapping Selector + Mapping Selector - - + + 268 - {{19, 14}, {67, 25}} + {{0, 14}, {140, 25}} + + + _NS:9 YES - + 67108864 - 0 + 134217728 + (default) _NS:9 - - - - 32 - - NSImage - NSActionTemplate - - Show and remap inputs - YES - 0 - - - 32 - - NSImage - NSRightFacingTriangleTemplate - - Run mapped actions - 1 - 0 - - - 4 + + 918306816 + 163 + + NSImage + NSListViewTemplate + + + + 400 + 75 NO - + - {67, 25} - {67, 25} + {13, 25} + {141, 25} YES - YES + NO 0 YES 0 @@ -455,13 +473,13 @@ - + - + @@ -493,7 +511,7 @@ {200, 298} - + YES NO YES @@ -623,7 +641,7 @@ {202, 300} - + 150034 @@ -687,6 +705,7 @@ {{227, 55}, {180, 24}} + _NS:9 YES @@ -824,7 +843,7 @@ 603979776 0 - Press a key: + Press a key 1211912448 @@ -852,7 +871,7 @@ 603979776 0 - Mouse movement + Move the mouse 1211912448 @@ -866,7 +885,7 @@ 603979776 0 - Mouse button + Press a mouse button 1211912448 @@ -880,7 +899,7 @@ 603979776 0 - Mouse scroll + Scroll the mouse 1211912448 @@ -1031,7 +1050,7 @@ {198, 198} - + YES NO YES @@ -1123,7 +1142,7 @@ {{0, 20}, {200, 200}} - + 150034 @@ -1139,6 +1158,7 @@ {{66, -1}, {134, 23}} + _NS:22 YES @@ -1270,6 +1290,14 @@ 732 + + + showHelp: + + + + 870 + orderFrontStandardAboutPanel: @@ -1366,21 +1394,29 @@ 826 + + + translatingEventsMenu + + + + 877 + translatingEventsChanged: - + - 858 + 878 - translatingEventsSetting + translatingEventsButton - + - 859 + 879 @@ -1622,6 +1658,14 @@ 818 + + + performClick: + + + + 871 + view @@ -1646,6 +1690,14 @@ 853 + + + performClick: + + + + 880 + @@ -1680,6 +1732,7 @@ + Main Menu @@ -1903,8 +1956,8 @@ - + @@ -2213,28 +2266,6 @@ - - 842 - - - - - - Translation Switch - - - 840 - - - - - - - - 841 - - - 849 @@ -2285,6 +2316,48 @@ + + 866 + + + + + + + + 867 + + + + + + + + 868 + + + + + 874 + + + + + + + + 872 + + + + + + + + 873 + + + @@ -2322,8 +2395,24 @@ com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin + + ToolTip + + ToolTip + + Create a new mapping + + com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin + + ToolTip + + ToolTip + + Remove the selected mapping + + com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin @@ -2373,26 +2462,44 @@ com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin + + ToolTip + + ToolTip + + Change the active mapping + + com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + ToolTip + + ToolTip + + Enable mapped actions + + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - 865 + 880 @@ -2446,7 +2553,8 @@ NJMappingsController NSOutlineView NJOutputController - NSSegmentedControl + NSButton + NSMenuItem @@ -2461,9 +2569,13 @@ outputController NJOutputController - - translatingEventsSetting - NSSegmentedControl + + translatingEventsButton + NSButton + + + translatingEventsMenu + NSMenuItem @@ -2644,7 +2756,6 @@ YES 3 - {15, 15} {8, 8} {11, 10} {11, 11} diff --git a/Enjoyable Help/Enjoyable Help.helpindex b/Enjoyable Help/Enjoyable Help.helpindex new file mode 100644 index 0000000000000000000000000000000000000000..54568b58fb0d72f2eb677575a670416ab7917f89 GIT binary patch literal 11228 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 IcIwoB0R^QXSpWb4 literal 0 HcmV?d00001 diff --git a/Enjoyable Help/Enjoyable Help.html b/Enjoyable Help/Enjoyable Help.html new file mode 100644 index 0000000..6a78ca4 --- /dev/null +++ b/Enjoyable Help/Enjoyable Help.html @@ -0,0 +1,73 @@ + + + + + Enjoyable Help + + + + + + + + + + + + +
+
+ Enjoyable Icon +
+
+

Enjoyable Help

+
+
+ +

+ Enjoyable helps you use a joystick or gamepad to control + applications which normally require a keyboard and mouse. +

+ +
+

Quick Start

+
    +
  • Connect a joystick or gamepad.
  • +
  • Press a button on it, then the keyboard key you want to use.
  • +
  • Press the ▶ button in the upper-right.
  • +
  • Start up your game and use your gamepad!
  • + +
+ +
+

+ + Keyboard Events +
+ Map buttons to keys on a keyboard. +

+

+ + Mouse Events +
+ Use analog axes and buttons to simulate a mouse. +

+

+ + Application Mappings +
+ Create and share mappings for different applications. +

+
+ +

+ + Visit the Enjoyable website. + +

+ + + diff --git a/Enjoyable Help/gfx/Icon.png b/Enjoyable Help/gfx/Icon.png new file mode 100644 index 0000000000000000000000000000000000000000..36c4254a4eee7b7befe274333196bca2a6bcc0e7 GIT binary patch literal 18084 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 gh!7z{gfv$Ee^rP_!{7+&8vpk literal 0 HcmV?d00001 diff --git a/Enjoyable Help/pgs/keyboard.html b/Enjoyable Help/pgs/keyboard.html new file mode 100644 index 0000000..99c414d --- /dev/null +++ b/Enjoyable Help/pgs/keyboard.html @@ -0,0 +1,59 @@ + + + + + Keyboard Events + + + + + + + + + + +
+
+ Enjoyable Icon +
+

Keyboard Events

+
+ +

+ Enjoyable supports mapping joystick buttons, hat switches, and + axis thresholds to simulate keyboard keys. To do this, first + press the button on the joystick you want to map. This will + select it on the left-hand side of the screen. +

+ +

+ If the button wasn't mapped, or was mapped to a key press + already, the key input field activates and you can simply press + the key you want to use. Otherwise, click on the Press a + key label or input field, then press the key. +

+ +

Clearing the Selection

+

+ To clear a mapped key, either select the Do nothing + option, or press ⌥⌫ when the key input field is selected. +

+ +

Cancelling the Selection

+

+ If you select the key input field by mistake, you can press ⌥⎋ + to cancel the selection without changing the current setting. +

+ + diff --git a/Enjoyable Help/pgs/mappings.html b/Enjoyable Help/pgs/mappings.html new file mode 100644 index 0000000..c6d8af4 --- /dev/null +++ b/Enjoyable Help/pgs/mappings.html @@ -0,0 +1,49 @@ + + + + + Discover Sample App + + + + + + + + + +
+
+$APPNAME$$ Icon +
+
+

Manage Application Mappings

+
+
+ +

Changing Dynamically

+Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas auctor leo in lorem dapibus eu tincidunt lacus viverra. Integer auctor tortor vel mauris pellentesque ultricies. Nulla lobortis, leo in facilisis cursus, elit felis viverra orci, ac luctus tellus sapien vel lectus. Aliquam ac accumsan risus. Nullam posuere, lectus commodo vestibulum luctus, mauris quam porta velit, ut pretium purus quam eu lacus. Nam in dui a sapien viverra euismod. Proin vel mauris nisi, sed tincidunt mi. Phasellus id ligula vitae mauris dapibus suscipit. Sed id erat nunc, in ultricies arcu. + +Nulla semper, magna non aliquam fringilla, turpis est convallis tortor, ut blandit elit orci nec elit. Phasellus id urna justo, a tristique mauris. Morbi sed nulla et lacus facilisis posuere et a purus. Morbi a dui quam. Nunc luctus ipsum ut purus sollicitudin cursus. Nulla facilisi. In vestibulum orci eu nunc euismod ut iaculis lacus commodo. Sed leo dolor, sagittis eu vulputate eget, accumsan eu leo. + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas auctor leo in lorem dapibus eu tincidunt lacus viverra. Integer auctor tortor vel mauris pellentesque ultricies. Nulla lobortis, leo in facilisis cursus, elit felis viverra orci, ac luctus tellus sapien vel lectus. Aliquam ac accumsan risus. Nullam posuere, lectus commodo vestibulum luctus, mauris quam porta velit, ut pretium purus quam eu lacus. Nam in dui a sapien viverra euismod. Proin vel mauris nisi, sed tincidunt mi. Phasellus id ligula vitae mauris dapibus suscipit. Sed id erat nunc, in ultricies arcu. + +Nulla semper, magna non aliquam fringilla, turpis est convallis tortor, ut blandit elit orci nec elit. Phasellus id urna justo, a tristique mauris. Morbi sed nulla et lacus facilisis posuere et a purus. Morbi a dui quam. Nunc luctus ipsum ut purus sollicitudin cursus. Nulla facilisi. In vestibulum orci eu nunc euismod ut iaculis lacus commodo. Sed leo dolor, sagittis eu vulputate eget, accumsan eu leo. + + + +

Automatic Switching

+ +

Sharing Mappings

+ + + diff --git a/Enjoyable Help/pgs/template.html b/Enjoyable Help/pgs/template.html new file mode 100644 index 0000000..daba5e5 --- /dev/null +++ b/Enjoyable Help/pgs/template.html @@ -0,0 +1,41 @@ + + + + + Title + + + + + + + + + + +
+
+ Icon +
+

Title

+
+ +

+ Content starts here. +

+ + diff --git a/Enjoyable Help/sty/default.css b/Enjoyable Help/sty/default.css new file mode 100644 index 0000000..58b7747 --- /dev/null +++ b/Enjoyable Help/sty/default.css @@ -0,0 +1 @@ +body { font-size: 8pt; font-family: "Lucida Grande", Arial, sans-serif; line-height: 12pt; text-decoration: none; margin-right: 1em; margin-left: 1em; } #navbox { background-color: #f2f2f2; position: fixed; top: 0; left: 0; width: 100%; height: 1.5em; float: left; border-bottom: 1px solid #bfbfbf } #navleftbox { position: absolute; top: 1px; left: 15px } #navrightbox { background-color: #f2f2f2; padding-right: 25px; float: right; padding-bottom: 1px; border-left: 1px solid #bfbfbf } #navbox a { font-size: 8pt; color: #666; font-weight: normal; margin: -9px 0 -6px; } #headerbox { margin-top: 36px; padding-right: 6px; margin-bottom: 2em; } #iconbox { float: left; } h1 { margin-left: 40px; width: 88%; font-size: 15pt; line-height: 15pt; font-weight: bold; padding-top: 6px; margin-bottom: 0; } h2 { font-size: 11pt; line-height: 12pt; font-weight: bold; color: black; margin-top: 0; margin-bottom: 11px; } h3 { font-size: 8pt; font-weight: bold; letter-spacing: 0.1em; line-height: 8pt; color: #666; margin-top: 1em; margin-bottom: 0px; padding-bottom: 0.5em; } p { margin-left: 0px; margin-top: 0px; margin-bottom: 0.5em; } ul { margin-left: 2em; margin-top: 6px; margin-bottom: 0px; padding-left: 0px; } li { margin-left: 0px; } a { color: #778fbd; font-size: 9pt; font-weight: bold; text-decoration: none; } a:hover { text-decoration: underline; } .weblink { color: #666; font-weight: normal; } \ No newline at end of file diff --git a/Enjoyable.xcodeproj/project.pbxproj b/Enjoyable.xcodeproj/project.pbxproj index c2f3246..4537688 100644 --- a/Enjoyable.xcodeproj/project.pbxproj +++ b/Enjoyable.xcodeproj/project.pbxproj @@ -32,6 +32,7 @@ D594BF830FAE9661007A85F2 /* EnjoyableApplicationDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = D594BF820FAE9661007A85F2 /* EnjoyableApplicationDelegate.m */; }; D5F809710FB093400006A4DE /* NJOutputMapping.m in Sources */ = {isa = PBXBuildFile; fileRef = D5F809700FB093400006A4DE /* NJOutputMapping.m */; }; D5F80A9D0FB0A2FF0006A4DE /* icon.icns in Resources */ = {isa = PBXBuildFile; fileRef = D5617A080FAEAF8300928B3A /* icon.icns */; }; + EE03150D16E63481002B2DCE /* Enjoyable Help in Resources */ = {isa = PBXBuildFile; fileRef = EE03150C16E63481002B2DCE /* Enjoyable Help */; }; EE1D7C9216E01E7000B000EB /* NSView+FirstResponder.m in Sources */ = {isa = PBXBuildFile; fileRef = EE1D7C9116E01E7000B000EB /* NSView+FirstResponder.m */; }; EE1D7C9616E0ECCF00B000EB /* NSError+Description.m in Sources */ = {isa = PBXBuildFile; fileRef = EE1D7C9516E0ECCF00B000EB /* NSError+Description.m */; }; EE96929416E54B480054A3C8 /* NSMenu+RepresentedObjectAccessors.m in Sources */ = {isa = PBXBuildFile; fileRef = EE96929316E54B480054A3C8 /* NSMenu+RepresentedObjectAccessors.m */; }; @@ -86,6 +87,7 @@ D594BF820FAE9661007A85F2 /* EnjoyableApplicationDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EnjoyableApplicationDelegate.m; sourceTree = ""; }; D5F8096F0FB093400006A4DE /* NJOutputMapping.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NJOutputMapping.h; sourceTree = ""; }; D5F809700FB093400006A4DE /* NJOutputMapping.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NJOutputMapping.m; sourceTree = ""; }; + EE03150C16E63481002B2DCE /* Enjoyable Help */ = {isa = PBXFileReference; lastKnownFileType = folder; path = "Enjoyable Help"; sourceTree = ""; }; EE1D7C9016E01E7000B000EB /* NSView+FirstResponder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSView+FirstResponder.h"; sourceTree = ""; }; EE1D7C9116E01E7000B000EB /* NSView+FirstResponder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSView+FirstResponder.m"; sourceTree = ""; }; EE1D7C9416E0ECCF00B000EB /* NSError+Description.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSError+Description.h"; sourceTree = ""; }; @@ -205,6 +207,7 @@ 29B97317FDCFA39411CA2CEA /* Resources */ = { isa = PBXGroup; children = ( + EE03150C16E63481002B2DCE /* Enjoyable Help */, D549CA4B0FBB441B00BC8203 /* Credits.rtf */, D5617A080FAEAF8300928B3A /* icon.icns */, 8D1107310486CEB800E47090 /* Info.plist */, @@ -293,6 +296,7 @@ 1DDD58160DA1D0A300B32029 /* MainMenu.xib in Resources */, D5F80A9D0FB0A2FF0006A4DE /* icon.icns in Resources */, D549CA4C0FBB441B00BC8203 /* Credits.rtf in Resources */, + EE03150D16E63481002B2DCE /* Enjoyable Help in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Info.plist b/Info.plist index 2940aaf..4a530d9 100644 --- a/Info.plist +++ b/Info.plist @@ -2,6 +2,10 @@ + CFBundleHelpBookName + Enjoyable Help + CFBundleHelpBookFolder + Enjoyable Help NSSupportsAutomaticTermination YES NSSupportsSuddenTermination diff --git a/NJDeviceController.h b/NJDeviceController.h index cfa6d99..4e50fa4 100644 --- a/NJDeviceController.h +++ b/NJDeviceController.h @@ -15,7 +15,8 @@ IBOutlet NSOutlineView *outlineView; IBOutlet NJOutputController *outputController; IBOutlet NJMappingsController *mappingsController; - IBOutlet NSSegmentedControl *translatingEventsSetting; + IBOutlet NSButton *translatingEventsButton; + IBOutlet NSMenuItem *translatingEventsMenu; } @property (nonatomic, readonly) NJInput *selectedInput; diff --git a/NJDeviceController.m b/NJDeviceController.m index f5da6dd..7993842 100644 --- a/NJDeviceController.m +++ b/NJDeviceController.m @@ -224,7 +224,9 @@ objectValueForTableColumn:(NSTableColumn *)tableColumn - (void)setTranslatingEvents:(BOOL)translatingEvents { if (translatingEvents != _translatingEvents) { _translatingEvents = translatingEvents; - translatingEventsSetting.selectedSegment = !!translatingEvents; + NSInteger state = translatingEvents ? NSOnState : NSOffState; + translatingEventsButton.state = state; + translatingEventsMenu.title = translatingEvents ? @"Disable" : @"Enable"; NSString *name = translatingEvents ? NJEventTranslationActivated : NJEventTranslationDeactivated; @@ -233,8 +235,8 @@ objectValueForTableColumn:(NSTableColumn *)tableColumn } } -- (IBAction)translatingEventsChanged:(id)sender { - self.translatingEvents = translatingEventsSetting.selectedSegment; +- (IBAction)translatingEventsChanged:(NSButton *)sender { + self.translatingEvents = sender.state == NSOnState; } diff --git a/NJKeyInputField.m b/NJKeyInputField.m index b159aa3..ec08150 100644 --- a/NJKeyInputField.m +++ b/NJKeyInputField.m @@ -176,10 +176,14 @@ CGKeyCode NJKeyInputFieldEmpty = 0xFFFF; - (void)keyDown:(NSEvent *)theEvent { if (!theEvent.isARepeat) { if ((theEvent.modifierFlags & NSAlternateKeyMask) - && theEvent.keyCode == 0x35) { - // Allow Alt+Escape to clear the field. + && theEvent.keyCode == 0x33) { + // Allow Alt+Backspace to clear the field. self.keyCode = NJKeyInputFieldEmpty; [self.keyDelegate keyInputFieldDidClear:self]; + } else if ((theEvent.modifierFlags & NSAlternateKeyMask) + && theEvent.keyCode == 0x35) { + // Allow Alt+Escape to cancel. + ; } else { self.keyCode = theEvent.keyCode; [self.keyDelegate keyInputField:self didChangeKey:_keyCode]; -- 2.30.2