mirror of
https://github.com/ksherlock/ample.git
synced 2024-06-08 02:29:37 +00:00
add midi input/output menu.
This commit is contained in:
parent
026a9e7704
commit
70f4738264
|
@ -149,6 +149,10 @@
|
||||||
B6841BD7251EC926006A5C39 /* vmnet_helper.c in Sources */ = {isa = PBXBuildFile; fileRef = B6841BCA251EC88E006A5C39 /* vmnet_helper.c */; };
|
B6841BD7251EC926006A5C39 /* vmnet_helper.c in Sources */ = {isa = PBXBuildFile; fileRef = B6841BCA251EC88E006A5C39 /* vmnet_helper.c */; };
|
||||||
B6841BDA251ECB1C006A5C39 /* mame64 in CopyFiles */ = {isa = PBXBuildFile; fileRef = B66236B824FDA698006CABD7 /* mame64 */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
B6841BDA251ECB1C006A5C39 /* mame64 in CopyFiles */ = {isa = PBXBuildFile; fileRef = B66236B824FDA698006CABD7 /* mame64 */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||||
B6841BDE251ECC29006A5C39 /* vmnet.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B6841BDD251ECC29006A5C39 /* vmnet.framework */; };
|
B6841BDE251ECC29006A5C39 /* vmnet.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B6841BDD251ECC29006A5C39 /* vmnet.framework */; };
|
||||||
|
B68A899026BE18E000B2C8C6 /* MidiManager.m in Sources */ = {isa = PBXBuildFile; fileRef = B68A898F26BE18E000B2C8C6 /* MidiManager.m */; };
|
||||||
|
B68A899126BE18E000B2C8C6 /* MidiManager.m in Sources */ = {isa = PBXBuildFile; fileRef = B68A898F26BE18E000B2C8C6 /* MidiManager.m */; };
|
||||||
|
B68A899426BF124B00B2C8C6 /* CoreMIDI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B68A899326BF124B00B2C8C6 /* CoreMIDI.framework */; };
|
||||||
|
B68A899526BF12A600B2C8C6 /* CoreMIDI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B68A899326BF124B00B2C8C6 /* CoreMIDI.framework */; };
|
||||||
B6A1A1942528EB1700DB0FD7 /* Menu.m in Sources */ = {isa = PBXBuildFile; fileRef = B6A1A1932528EB1700DB0FD7 /* Menu.m */; };
|
B6A1A1942528EB1700DB0FD7 /* Menu.m in Sources */ = {isa = PBXBuildFile; fileRef = B6A1A1932528EB1700DB0FD7 /* Menu.m */; };
|
||||||
B6A1A1952528EB1700DB0FD7 /* Menu.m in Sources */ = {isa = PBXBuildFile; fileRef = B6A1A1932528EB1700DB0FD7 /* Menu.m */; };
|
B6A1A1952528EB1700DB0FD7 /* Menu.m in Sources */ = {isa = PBXBuildFile; fileRef = B6A1A1932528EB1700DB0FD7 /* Menu.m */; };
|
||||||
B6B9EA662506A5550080E70D /* EjectButton.m in Sources */ = {isa = PBXBuildFile; fileRef = B6B9EA642506A5550080E70D /* EjectButton.m */; };
|
B6B9EA662506A5550080E70D /* EjectButton.m in Sources */ = {isa = PBXBuildFile; fileRef = B6B9EA642506A5550080E70D /* EjectButton.m */; };
|
||||||
|
@ -449,6 +453,9 @@
|
||||||
B6841BCA251EC88E006A5C39 /* vmnet_helper.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = vmnet_helper.c; sourceTree = "<group>"; };
|
B6841BCA251EC88E006A5C39 /* vmnet_helper.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = vmnet_helper.c; sourceTree = "<group>"; };
|
||||||
B6841BD0251EC913006A5C39 /* vmnet_helper */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = vmnet_helper; sourceTree = BUILT_PRODUCTS_DIR; };
|
B6841BD0251EC913006A5C39 /* vmnet_helper */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = vmnet_helper; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
B6841BDD251ECC29006A5C39 /* vmnet.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = vmnet.framework; path = System/Library/Frameworks/vmnet.framework; sourceTree = SDKROOT; };
|
B6841BDD251ECC29006A5C39 /* vmnet.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = vmnet.framework; path = System/Library/Frameworks/vmnet.framework; sourceTree = SDKROOT; };
|
||||||
|
B68A898F26BE18E000B2C8C6 /* MidiManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MidiManager.m; sourceTree = "<group>"; };
|
||||||
|
B68A899226BE320200B2C8C6 /* MidiManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MidiManager.h; sourceTree = "<group>"; };
|
||||||
|
B68A899326BF124B00B2C8C6 /* CoreMIDI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMIDI.framework; path = System/Library/Frameworks/CoreMIDI.framework; sourceTree = SDKROOT; };
|
||||||
B6A1A1932528EB1700DB0FD7 /* Menu.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Menu.m; sourceTree = "<group>"; };
|
B6A1A1932528EB1700DB0FD7 /* Menu.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Menu.m; sourceTree = "<group>"; };
|
||||||
B6A1A1962528EB4600DB0FD7 /* Menu.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Menu.h; sourceTree = "<group>"; };
|
B6A1A1962528EB4600DB0FD7 /* Menu.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Menu.h; sourceTree = "<group>"; };
|
||||||
B6B9EA642506A5550080E70D /* EjectButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EjectButton.m; sourceTree = "<group>"; };
|
B6B9EA642506A5550080E70D /* EjectButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EjectButton.m; sourceTree = "<group>"; };
|
||||||
|
@ -518,6 +525,7 @@
|
||||||
files = (
|
files = (
|
||||||
B65D718625E70BD5008C5F87 /* WebKit.framework in Frameworks */,
|
B65D718625E70BD5008C5F87 /* WebKit.framework in Frameworks */,
|
||||||
B635C09D26784A4800B23BFD /* Sparkle.framework in Frameworks */,
|
B635C09D26784A4800B23BFD /* Sparkle.framework in Frameworks */,
|
||||||
|
B68A899426BF124B00B2C8C6 /* CoreMIDI.framework in Frameworks */,
|
||||||
B635C09A26784A1200B23BFD /* Sparkle.framework in Frameworks */,
|
B635C09A26784A1200B23BFD /* Sparkle.framework in Frameworks */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
@ -526,6 +534,7 @@
|
||||||
isa = PBXFrameworksBuildPhase;
|
isa = PBXFrameworksBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
B68A899526BF12A600B2C8C6 /* CoreMIDI.framework in Frameworks */,
|
||||||
B65D718725E70BE5008C5F87 /* WebKit.framework in Frameworks */,
|
B65D718725E70BE5008C5F87 /* WebKit.framework in Frameworks */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
@ -635,6 +644,7 @@
|
||||||
B66236B624FDA686006CABD7 /* Frameworks */ = {
|
B66236B624FDA686006CABD7 /* Frameworks */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
B68A899326BF124B00B2C8C6 /* CoreMIDI.framework */,
|
||||||
B635C09926784A1200B23BFD /* Sparkle.framework */,
|
B635C09926784A1200B23BFD /* Sparkle.framework */,
|
||||||
B65D718525E70BD5008C5F87 /* WebKit.framework */,
|
B65D718525E70BD5008C5F87 /* WebKit.framework */,
|
||||||
B6841BDD251ECC29006A5C39 /* vmnet.framework */,
|
B6841BDD251ECC29006A5C39 /* vmnet.framework */,
|
||||||
|
@ -725,6 +735,8 @@
|
||||||
B6B9EA642506A5550080E70D /* EjectButton.m */,
|
B6B9EA642506A5550080E70D /* EjectButton.m */,
|
||||||
B64AF1F8250EF6A500A09B9B /* Transformers.h */,
|
B64AF1F8250EF6A500A09B9B /* Transformers.h */,
|
||||||
B64AF1F9250EF6A500A09B9B /* Transformers.m */,
|
B64AF1F9250EF6A500A09B9B /* Transformers.m */,
|
||||||
|
B68A898F26BE18E000B2C8C6 /* MidiManager.m */,
|
||||||
|
B68A899226BE320200B2C8C6 /* MidiManager.h */,
|
||||||
B6BA258124E99BEB005FB8FF /* Assets.xcassets */,
|
B6BA258124E99BEB005FB8FF /* Assets.xcassets */,
|
||||||
B64E15AF24EA365E00E8AD3D /* Resources */,
|
B64E15AF24EA365E00E8AD3D /* Resources */,
|
||||||
B6BA258624E99BEB005FB8FF /* Info.plist */,
|
B6BA258624E99BEB005FB8FF /* Info.plist */,
|
||||||
|
@ -1205,6 +1217,7 @@
|
||||||
B6665C14265A0E3E00254939 /* AutocompleteControl.m in Sources */,
|
B6665C14265A0E3E00254939 /* AutocompleteControl.m in Sources */,
|
||||||
B64979C224EF6703008ABD20 /* MediaViewController.m in Sources */,
|
B64979C224EF6703008ABD20 /* MediaViewController.m in Sources */,
|
||||||
B60A6E1424EE0AE2004B7EEF /* FlippedView.m in Sources */,
|
B60A6E1424EE0AE2004B7EEF /* FlippedView.m in Sources */,
|
||||||
|
B68A899026BE18E000B2C8C6 /* MidiManager.m in Sources */,
|
||||||
B6BA258024E99BE9005FB8FF /* AppDelegate.m in Sources */,
|
B6BA258024E99BE9005FB8FF /* AppDelegate.m in Sources */,
|
||||||
B6004DF024FB05D600D38596 /* LogWindowController.m in Sources */,
|
B6004DF024FB05D600D38596 /* LogWindowController.m in Sources */,
|
||||||
B63005332666D6940014C381 /* BookmarkManager.m in Sources */,
|
B63005332666D6940014C381 /* BookmarkManager.m in Sources */,
|
||||||
|
@ -1223,6 +1236,7 @@
|
||||||
isa = PBXSourcesBuildPhase;
|
isa = PBXSourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
B68A899126BE18E000B2C8C6 /* MidiManager.m in Sources */,
|
||||||
B608E1802502FE0C00D53465 /* TransparentScroller.m in Sources */,
|
B608E1802502FE0C00D53465 /* TransparentScroller.m in Sources */,
|
||||||
B64AF1FB250EF6A500A09B9B /* Transformers.m in Sources */,
|
B64AF1FB250EF6A500A09B9B /* Transformers.m in Sources */,
|
||||||
B6E4B5B024FDE2670094A35C /* main.m in Sources */,
|
B6E4B5B024FDE2670094A35C /* main.m in Sources */,
|
||||||
|
|
|
@ -61,7 +61,7 @@
|
||||||
<outlet property="textField" destination="Pep-mX-LHY" id="hUe-cf-6vq"/>
|
<outlet property="textField" destination="Pep-mX-LHY" id="hUe-cf-6vq"/>
|
||||||
</connections>
|
</connections>
|
||||||
</tableCellView>
|
</tableCellView>
|
||||||
<tableCellView identifier="ItemView" translatesAutoresizingMaskIntoConstraints="NO" id="yGq-lc-RCM" customClass="TablePathView">
|
<tableCellView identifier="ItemView" translatesAutoresizingMaskIntoConstraints="NO" id="yGq-lc-RCM" customClass="PathTableCellView">
|
||||||
<rect key="frame" x="1" y="21" width="296" height="22"/>
|
<rect key="frame" x="1" y="21" width="296" height="22"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
|
@ -101,7 +101,7 @@
|
||||||
<outlet property="pathControl" destination="f7R-TO-fmF" id="oH7-N3-JC7"/>
|
<outlet property="pathControl" destination="f7R-TO-fmF" id="oH7-N3-JC7"/>
|
||||||
</connections>
|
</connections>
|
||||||
</tableCellView>
|
</tableCellView>
|
||||||
<tableCellView identifier="BBItemView" id="2Nq-Xz-tkV" customClass="TablePathView">
|
<tableCellView identifier="BBItemView" id="2Nq-Xz-tkV" customClass="PathTableCellView">
|
||||||
<rect key="frame" x="1" y="46" width="296" height="22"/>
|
<rect key="frame" x="1" y="46" width="296" height="22"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
|
@ -146,7 +146,7 @@
|
||||||
<outlet property="ejectButton" destination="zxn-1E-o34" id="eC6-Mf-tN6"/>
|
<outlet property="ejectButton" destination="zxn-1E-o34" id="eC6-Mf-tN6"/>
|
||||||
</connections>
|
</connections>
|
||||||
</tableCellView>
|
</tableCellView>
|
||||||
<tableCellView identifier="OutputItemView" id="jQd-Ar-5uf" customClass="TablePathView">
|
<tableCellView identifier="OutputItemView" id="jQd-Ar-5uf" customClass="PathTableCellView">
|
||||||
<rect key="frame" x="1" y="71" width="296" height="22"/>
|
<rect key="frame" x="1" y="71" width="296" height="22"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
|
@ -177,12 +177,12 @@
|
||||||
</textFieldCell>
|
</textFieldCell>
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="textAction:" target="-2" id="N7h-6y-D8W"/>
|
<action selector="textAction:" target="-2" id="N7h-6y-D8W"/>
|
||||||
<binding destination="jQd-Ar-5uf" name="enabled" keyPath="objectValue.valid" id="1wE-NY-Vb2"/>
|
|
||||||
<binding destination="jQd-Ar-5uf" name="value" keyPath="objectValue.string" id="kXU-qJ-HKa">
|
<binding destination="jQd-Ar-5uf" name="value" keyPath="objectValue.string" id="kXU-qJ-HKa">
|
||||||
<dictionary key="options">
|
<dictionary key="options">
|
||||||
<string key="NSNullPlaceholder">/path/to/file</string>
|
<string key="NSNullPlaceholder">/path/to/file</string>
|
||||||
</dictionary>
|
</dictionary>
|
||||||
</binding>
|
</binding>
|
||||||
|
<binding destination="jQd-Ar-5uf" name="enabled" keyPath="objectValue.valid" id="1wE-NY-Vb2"/>
|
||||||
</connections>
|
</connections>
|
||||||
</textField>
|
</textField>
|
||||||
</subviews>
|
</subviews>
|
||||||
|
@ -191,6 +191,57 @@
|
||||||
<outlet property="ejectButton" destination="vG4-PP-efF" id="X2I-2N-t5r"/>
|
<outlet property="ejectButton" destination="vG4-PP-efF" id="X2I-2N-t5r"/>
|
||||||
</connections>
|
</connections>
|
||||||
</tableCellView>
|
</tableCellView>
|
||||||
|
<tableCellView identifier="MidiItemView" id="HDi-YM-iKn" customClass="MidiTableCellView">
|
||||||
|
<rect key="frame" x="1" y="96" width="296" height="22"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
|
<subviews>
|
||||||
|
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" id="XcO-0S-W4c">
|
||||||
|
<rect key="frame" x="0.0" y="1" width="20" height="20"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
|
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageAlignment="left" image="drag-handle-4x10" id="4a2-So-rxD"/>
|
||||||
|
</imageView>
|
||||||
|
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="F3v-8Z-LaF" customClass="EjectButton">
|
||||||
|
<rect key="frame" x="277" y="3" width="16" height="16"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
|
||||||
|
<buttonCell key="cell" type="bevel" bezelStyle="regularSquare" image="eject-16x16" imagePosition="only" alignment="center" alternateImage="eject-hover-16x16" imageScaling="proportionallyDown" inset="2" id="b3t-Zp-2si">
|
||||||
|
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||||
|
<font key="font" metaFont="system"/>
|
||||||
|
</buttonCell>
|
||||||
|
<connections>
|
||||||
|
<action selector="ejectAction:" target="-2" id="AvU-Sz-QKJ"/>
|
||||||
|
<binding destination="HDi-YM-iKn" name="enabled" keyPath="objectValue.occupied" id="ERy-Iz-T9Q"/>
|
||||||
|
</connections>
|
||||||
|
</button>
|
||||||
|
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="L2F-mj-lkr">
|
||||||
|
<rect key="frame" x="20" y="-3" width="244" height="25"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
||||||
|
<popUpButtonCell key="cell" type="push" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="CaJ-NG-vbR" id="Rac-za-bEQ">
|
||||||
|
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||||
|
<font key="font" metaFont="system"/>
|
||||||
|
<menu key="menu" id="I55-5S-oM2">
|
||||||
|
<items>
|
||||||
|
<menuItem state="on" id="CaJ-NG-vbR">
|
||||||
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
|
</menuItem>
|
||||||
|
</items>
|
||||||
|
</menu>
|
||||||
|
</popUpButtonCell>
|
||||||
|
<connections>
|
||||||
|
<action selector="midiAction:" target="-2" id="LDL-4h-xUR"/>
|
||||||
|
<binding destination="HDi-YM-iKn" name="selectedValue" keyPath="objectValue.string" id="xjL-hx-VG3">
|
||||||
|
<dictionary key="options">
|
||||||
|
<string key="NSValueTransformerName">EmptyStringTransformer</string>
|
||||||
|
</dictionary>
|
||||||
|
</binding>
|
||||||
|
</connections>
|
||||||
|
</popUpButton>
|
||||||
|
</subviews>
|
||||||
|
<connections>
|
||||||
|
<outlet property="dragHandle" destination="XcO-0S-W4c" id="oKY-UF-LkW"/>
|
||||||
|
<outlet property="ejectButton" destination="F3v-8Z-LaF" id="ql8-4u-qCA"/>
|
||||||
|
<outlet property="popUpButton" destination="L2F-mj-lkr" id="Ktx-Yc-DIp"/>
|
||||||
|
</connections>
|
||||||
|
</tableCellView>
|
||||||
</prototypeCellViews>
|
</prototypeCellViews>
|
||||||
</tableColumn>
|
</tableColumn>
|
||||||
</tableColumns>
|
</tableColumns>
|
||||||
|
|
|
@ -9,26 +9,8 @@
|
||||||
#import "MediaViewController.h"
|
#import "MediaViewController.h"
|
||||||
#import "TableCellView.h"
|
#import "TableCellView.h"
|
||||||
|
|
||||||
enum {
|
|
||||||
kIndexFloppy525 = 0,
|
|
||||||
kIndexFloppy35,
|
|
||||||
kIndexHardDrive,
|
|
||||||
kIndexCDROM,
|
|
||||||
kIndexCassette,
|
|
||||||
kIndexDiskImage,
|
|
||||||
kIndexBitBanger,
|
|
||||||
kIndexMidiIn,
|
|
||||||
kIndexMidiOut,
|
|
||||||
kIndexPicture, // computer eyes -pic, .png only.
|
|
||||||
// kIndexPrintout // -prin, .prn extension only?
|
|
||||||
|
|
||||||
kIndexLast
|
|
||||||
};
|
|
||||||
|
|
||||||
#define CATEGORY_COUNT 10
|
|
||||||
#define SIZEOF(x) (sizeof(x) / sizeof(x[0]))
|
#define SIZEOF(x) (sizeof(x) / sizeof(x[0]))
|
||||||
|
|
||||||
static_assert(kIndexLast == CATEGORY_COUNT, "Invalid Category Count");
|
|
||||||
|
|
||||||
@protocol MediaNode
|
@protocol MediaNode
|
||||||
-(BOOL)isGroupItem;
|
-(BOOL)isGroupItem;
|
||||||
|
@ -285,15 +267,23 @@ static_assert(kIndexLast == CATEGORY_COUNT, "Invalid Category Count");
|
||||||
|
|
||||||
-(NSString *)viewIdentifier {
|
-(NSString *)viewIdentifier {
|
||||||
if (_category == kIndexBitBanger) return @"BBItemView";
|
if (_category == kIndexBitBanger) return @"BBItemView";
|
||||||
if (_category == kIndexMidiOut) return @"OutputItemView";
|
if (_category == kIndexMidiOut) return @"MidiItemView";
|
||||||
if (_category == kIndexMidiIn) return @"OutputItemView";
|
if (_category == kIndexMidiIn) return @"MidiItemView";
|
||||||
return @"ItemView";
|
return @"ItemView";
|
||||||
}
|
}
|
||||||
|
|
||||||
-(void)prepareView: (TablePathView *)view {
|
-(void)prepareView: (MediaTableCellView *)view {
|
||||||
/* set the path tag = category. */
|
/* set the path tag = category. */
|
||||||
|
|
||||||
|
[view prepareView: _category];
|
||||||
|
#if 0
|
||||||
|
if (_category == kIndexMidiIn || _category == kIndexMidiOut || _category == kIndexBitBanger) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
NSPathControl *pc = [view pathControl];
|
NSPathControl *pc = [view pathControl];
|
||||||
[pc setTag: _category + 1]; // to differentiate 0 / no path control.
|
[pc setTag: _category + 1]; // to differentiate 0 / no path control.
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
-(CGFloat)height {
|
-(CGFloat)height {
|
||||||
|
@ -437,7 +427,7 @@ x = media.name; cat = _data[index]; delta |= [cat setItemCount: x]
|
||||||
// So we should build a device list (and pre-populate the default one)
|
// So we should build a device list (and pre-populate the default one)
|
||||||
// another approach is a separate utility to act as a midi/serial input converter
|
// another approach is a separate utility to act as a midi/serial input converter
|
||||||
// and midi file / serial converter so the modem/serial port could be used.
|
// and midi file / serial converter so the modem/serial port could be used.
|
||||||
#if 0
|
#if 1
|
||||||
_(midiin, kIndexMidiIn);
|
_(midiin, kIndexMidiIn);
|
||||||
_(midiout, kIndexMidiOut);
|
_(midiout, kIndexMidiOut);
|
||||||
#endif
|
#endif
|
||||||
|
@ -782,6 +772,9 @@ static NSString *kDragType = @"private.ample.media";
|
||||||
-(IBAction)textAction: (id)sender {
|
-(IBAction)textAction: (id)sender {
|
||||||
[self rebuildArgs];
|
[self rebuildArgs];
|
||||||
}
|
}
|
||||||
|
- (IBAction)midiAction:(id)sender {
|
||||||
|
[self rebuildArgs];
|
||||||
|
}
|
||||||
|
|
||||||
-(IBAction)resetMedia:(id)sender {
|
-(IBAction)resetMedia:(id)sender {
|
||||||
[self resetDiskImages];
|
[self resetDiskImages];
|
||||||
|
|
25
Ample/MidiManager.h
Normal file
25
Ample/MidiManager.h
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
//
|
||||||
|
// MidiManager.h
|
||||||
|
// Ample
|
||||||
|
//
|
||||||
|
// Created by Kelvin Sherlock on 8/6/2021.
|
||||||
|
// Copyright © 2021 Kelvin Sherlock. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef MidiManager_h
|
||||||
|
#define MidiManager_h
|
||||||
|
|
||||||
|
|
||||||
|
extern NSString *kMidiSourcesChangedNotification;
|
||||||
|
extern NSString *kMidiDestinationsChangedNotification;
|
||||||
|
|
||||||
|
@interface MidiManager : NSObject
|
||||||
|
|
||||||
|
@property NSArray *sources;
|
||||||
|
@property NSArray *destinations;
|
||||||
|
|
||||||
|
+(instancetype)sharedManager;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
#endif /* MidiManager_h */
|
153
Ample/MidiManager.m
Normal file
153
Ample/MidiManager.m
Normal file
|
@ -0,0 +1,153 @@
|
||||||
|
//
|
||||||
|
// Midi.m
|
||||||
|
// Ample
|
||||||
|
//
|
||||||
|
// Created by Kelvin Sherlock on 8/6/2021.
|
||||||
|
// Copyright © 2021 Kelvin Sherlock. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
#import <CoreMIDI/CoreMIDI.h>
|
||||||
|
|
||||||
|
#import "MidiManager.h"
|
||||||
|
|
||||||
|
static NSArray *MidiSources(void) {
|
||||||
|
|
||||||
|
ItemCount count = MIDIGetNumberOfSources();
|
||||||
|
if (count <= 0) return @[];
|
||||||
|
|
||||||
|
NSMutableArray *rv = [NSMutableArray arrayWithCapacity: count + 1];
|
||||||
|
|
||||||
|
MIDIEndpointRef ep;
|
||||||
|
for(int i = 0; i < count; ++i) {
|
||||||
|
ep = MIDIGetSource(i);
|
||||||
|
if (!ep) continue;
|
||||||
|
|
||||||
|
// https://developer.apple.com/library/archive/qa/qa1374/_index.html
|
||||||
|
CFStringRef str = NULL;
|
||||||
|
MIDIObjectGetStringProperty(ep, kMIDIPropertyDisplayName, &str);
|
||||||
|
|
||||||
|
if (str) {
|
||||||
|
[rv addObject: (__bridge id _Nonnull)(str)];
|
||||||
|
CFRelease(str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static NSArray *MidiDestinations(void) {
|
||||||
|
|
||||||
|
ItemCount count = MIDIGetNumberOfDestinations();
|
||||||
|
if (count <= 0) return @[];
|
||||||
|
|
||||||
|
NSMutableArray *rv = [NSMutableArray arrayWithCapacity: count + 1];
|
||||||
|
|
||||||
|
MIDIEndpointRef ep;
|
||||||
|
for(int i = 0; i < count; ++i) {
|
||||||
|
ep = MIDIGetDestination(i);
|
||||||
|
if (!ep) continue;
|
||||||
|
|
||||||
|
// https://developer.apple.com/library/archive/qa/qa1374/_index.html
|
||||||
|
CFStringRef str = NULL;
|
||||||
|
MIDIObjectGetStringProperty(ep, kMIDIPropertyDisplayName, &str);
|
||||||
|
|
||||||
|
if (str) {
|
||||||
|
[rv addObject: (__bridge id _Nonnull)(str)];
|
||||||
|
CFRelease(str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
NSString *kMidiSourcesChangedNotification = @"Midi Sources Changed";
|
||||||
|
NSString *kMidiDestinationsChangedNotification = @"Midi Destinations Changed";
|
||||||
|
|
||||||
|
|
||||||
|
@interface MidiManager () {
|
||||||
|
MIDIClientRef _client;
|
||||||
|
}
|
||||||
|
|
||||||
|
-(void)objectAddRemove: (const MIDIObjectAddRemoveNotification *)message;
|
||||||
|
-(void)objectPropertyChanged: (const MIDIObjectPropertyChangeNotification *)message;
|
||||||
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
static MidiManager *singleton = nil;
|
||||||
|
@implementation MidiManager
|
||||||
|
|
||||||
|
-(void)awakeFromNib {
|
||||||
|
if (!singleton) singleton = self;
|
||||||
|
}
|
||||||
|
|
||||||
|
+(instancetype)sharedManager {
|
||||||
|
if (!singleton) singleton = [MidiManager new];
|
||||||
|
return singleton;
|
||||||
|
}
|
||||||
|
|
||||||
|
-(instancetype)init {
|
||||||
|
|
||||||
|
if (singleton) return singleton;
|
||||||
|
|
||||||
|
OSStatus status;
|
||||||
|
|
||||||
|
|
||||||
|
status = MIDIClientCreateWithBlock(
|
||||||
|
CFSTR("serial_midi"),
|
||||||
|
&_client,
|
||||||
|
^(const MIDINotification *message){
|
||||||
|
switch(message->messageID) {
|
||||||
|
case kMIDIMsgObjectAdded:
|
||||||
|
case kMIDIMsgObjectRemoved:
|
||||||
|
[self objectAddRemove: (const MIDIObjectAddRemoveNotification *)message];
|
||||||
|
break;
|
||||||
|
case kMIDIMsgPropertyChanged:
|
||||||
|
[self objectPropertyChanged: (const MIDIObjectPropertyChangeNotification *)message];
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
_sources = MidiSources();
|
||||||
|
_destinations = MidiDestinations();
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
-(void)objectAddRemove: (const MIDIObjectAddRemoveNotification *)message {
|
||||||
|
|
||||||
|
const MIDIObjectAddRemoveNotification *m = (const MIDIObjectAddRemoveNotification *)message;
|
||||||
|
|
||||||
|
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
|
||||||
|
|
||||||
|
if (m->childType == kMIDIObjectType_Source) {
|
||||||
|
[self setSources: MidiSources()];
|
||||||
|
[nc postNotificationName: kMidiSourcesChangedNotification object: self];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m->childType == kMIDIObjectType_Destination) {
|
||||||
|
[self setDestinations: MidiDestinations()];
|
||||||
|
[nc postNotificationName: kMidiDestinationsChangedNotification object: self];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
-(void)objectPropertyChanged: (const MIDIObjectPropertyChangeNotification *)message {
|
||||||
|
|
||||||
|
const MIDIObjectPropertyChangeNotification *m = (const MIDIObjectPropertyChangeNotification *)message;
|
||||||
|
if (m->propertyName == kMIDIPropertyDisplayName) {
|
||||||
|
[self setSources: MidiSources()];
|
||||||
|
[self setDestinations: MidiDestinations()];
|
||||||
|
|
||||||
|
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
|
||||||
|
[nc postNotificationName: kMidiSourcesChangedNotification object: self];
|
||||||
|
[nc postNotificationName: kMidiDestinationsChangedNotification object: self];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
-(void)dealloc {
|
||||||
|
|
||||||
|
if (_client)
|
||||||
|
MIDIClientDispose(_client);
|
||||||
|
}
|
||||||
|
@end
|
||||||
|
|
|
@ -11,12 +11,40 @@
|
||||||
//NS_ASSUME_NONNULL_BEGIN
|
//NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
|
||||||
|
enum {
|
||||||
|
kIndexFloppy525 = 0,
|
||||||
|
kIndexFloppy35,
|
||||||
|
kIndexHardDrive,
|
||||||
|
kIndexCDROM,
|
||||||
|
kIndexCassette,
|
||||||
|
kIndexDiskImage,
|
||||||
|
kIndexBitBanger,
|
||||||
|
kIndexMidiIn,
|
||||||
|
kIndexMidiOut,
|
||||||
|
kIndexPicture, // computer eyes -pic, .png only.
|
||||||
|
// kIndexPrintout // -prin, .prn extension only?
|
||||||
|
|
||||||
@interface TablePathView : NSTableCellView
|
kIndexLast
|
||||||
@property (weak) IBOutlet NSPathControl *pathControl;
|
};
|
||||||
|
#define CATEGORY_COUNT 10
|
||||||
|
static_assert(kIndexLast == CATEGORY_COUNT, "Invalid Category Count");
|
||||||
|
|
||||||
|
|
||||||
|
@interface MediaTableCellView : NSTableCellView
|
||||||
@property (weak) IBOutlet NSButton *ejectButton;
|
@property (weak) IBOutlet NSButton *ejectButton;
|
||||||
@property (weak) IBOutlet NSImageView *dragHandle;
|
@property (weak) IBOutlet NSImageView *dragHandle;
|
||||||
@property BOOL movable;
|
@property BOOL movable;
|
||||||
|
|
||||||
|
-(void)prepareView: (NSInteger)category;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface PathTableCellView : MediaTableCellView <NSPathControlDelegate>
|
||||||
|
@property (weak) IBOutlet NSPathControl *pathControl;
|
||||||
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
@interface MidiTableCellView : MediaTableCellView
|
||||||
|
@property (weak) IBOutlet NSPopUpButton *popUpButton;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
//NS_ASSUME_NONNULL_END
|
//NS_ASSUME_NONNULL_END
|
||||||
|
|
|
@ -7,13 +7,16 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
#import "TableCellView.h"
|
#import "TableCellView.h"
|
||||||
|
#import "MidiManager.h"
|
||||||
|
#import "Menu.h"
|
||||||
|
|
||||||
|
|
||||||
|
@implementation MediaTableCellView
|
||||||
@implementation TablePathView {
|
#if 0
|
||||||
|
{
|
||||||
NSTrackingRectTag _trackingRect;
|
NSTrackingRectTag _trackingRect;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
-(void)awakeFromNib {
|
-(void)awakeFromNib {
|
||||||
|
|
||||||
// need to do it here for 10.11 compatibility.
|
// need to do it here for 10.11 compatibility.
|
||||||
|
@ -31,6 +34,8 @@
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
-(void)prepareView: (NSInteger)category {
|
||||||
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
-(void)awakeFromNib {
|
-(void)awakeFromNib {
|
||||||
|
@ -65,3 +70,143 @@
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
@implementation PathTableCellView
|
||||||
|
|
||||||
|
-(void)prepareView: (NSInteger)category {
|
||||||
|
[_pathControl setTag: category + 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)pathControl:(NSPathControl *)pathControl willPopUpMenu:(NSMenu *)menu {
|
||||||
|
// if this is an output path, replace the "choose..." button with a save panel.
|
||||||
|
NSMenuItem *item = [menu itemAtIndex: 0];
|
||||||
|
if (item) {
|
||||||
|
[item setTarget: self];
|
||||||
|
[item setAction: @selector(choosePath:)];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-(IBAction)choosePath:(id)sender {
|
||||||
|
NSPathControl *pc = _pathControl;
|
||||||
|
NSURL *url = [pc URL];
|
||||||
|
|
||||||
|
NSSavePanel *p = [NSSavePanel savePanel];
|
||||||
|
|
||||||
|
if (url) {
|
||||||
|
NSFileManager *fm = [NSFileManager defaultManager];
|
||||||
|
BOOL dir = NO;
|
||||||
|
NSString *str = [NSString stringWithCString: [url fileSystemRepresentation] encoding: NSUTF8StringEncoding];
|
||||||
|
[fm fileExistsAtPath: str isDirectory: &dir];
|
||||||
|
|
||||||
|
if (!dir) {
|
||||||
|
[p setNameFieldStringValue: [str lastPathComponent]];
|
||||||
|
url = [url URLByDeletingLastPathComponent];
|
||||||
|
}
|
||||||
|
[p setDirectoryURL: url];
|
||||||
|
}
|
||||||
|
[p setExtensionHidden: NO];
|
||||||
|
|
||||||
|
[p beginWithCompletionHandler: ^(NSModalResponse response){
|
||||||
|
if (response != NSModalResponseOK) return;
|
||||||
|
NSURL *url = [p URL];
|
||||||
|
[pc setURL: url];
|
||||||
|
}];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
@interface EmptyStringTransformer : NSValueTransformer
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
static NSString *kNone = @"—None—";
|
||||||
|
|
||||||
|
@implementation EmptyStringTransformer
|
||||||
|
|
||||||
|
+(void)load {
|
||||||
|
[self setValueTransformer: [self new] forName: @"EmptyStringTransformer"];
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (Class)transformedValueClass {
|
||||||
|
return [NSString class];
|
||||||
|
}
|
||||||
|
+ (BOOL)allowsReverseTransformation {
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
- (id)transformedValue:(id)value {
|
||||||
|
if (value == nil) return kNone;
|
||||||
|
if ([kNone isEqualToString: value]) return nil;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation MidiTableCellView {
|
||||||
|
NSInteger _category;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* binding should be able to handle the menu but i couldn't make it work. */
|
||||||
|
|
||||||
|
|
||||||
|
-(void)prepareView: (NSInteger)category {
|
||||||
|
_category = category;
|
||||||
|
|
||||||
|
// 10.11 + doesn't need to remove the observer in the -dealloc
|
||||||
|
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
|
||||||
|
[nc addObserver: self selector: @selector(midiChanged:) name: category == kIndexMidiIn ? kMidiSourcesChangedNotification : kMidiDestinationsChangedNotification object: nil];
|
||||||
|
|
||||||
|
[self updateMenus: NO];
|
||||||
|
}
|
||||||
|
|
||||||
|
-(void)updateMenus: (BOOL)notification {
|
||||||
|
NSMenu *menu = [_popUpButton menu];
|
||||||
|
MidiManager *mgr = [MidiManager sharedManager];
|
||||||
|
|
||||||
|
NSArray *array = _category == kIndexMidiIn ? [mgr sources] : [mgr destinations];
|
||||||
|
|
||||||
|
[menu removeAllItems];
|
||||||
|
NSString *selected = [[_popUpButton selectedItem] representedObject];
|
||||||
|
int selectedIndex = -1;
|
||||||
|
NSMenuItem *item;
|
||||||
|
|
||||||
|
item = [[NSMenuItem alloc] initWithTitle: kNone action: NULL keyEquivalent: @""];
|
||||||
|
[item setAttributedTitle: ItalicMenuString(kNone)];
|
||||||
|
[menu addItem: item];
|
||||||
|
selectedIndex = 0;
|
||||||
|
#if 0
|
||||||
|
if (!selected || [@"" isEqualToString: selected]) {
|
||||||
|
selectedIndex = 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int ix = 1;
|
||||||
|
for (NSString *s in array) {
|
||||||
|
item = [[NSMenuItem alloc] initWithTitle: s action: NULL keyEquivalent: @""];
|
||||||
|
[item setRepresentedObject: s];
|
||||||
|
[menu addItem: item];
|
||||||
|
if ([s isEqualToString: selected]) {
|
||||||
|
selectedIndex = ix;
|
||||||
|
}
|
||||||
|
++ix;
|
||||||
|
}
|
||||||
|
|
||||||
|
// does this propogate?
|
||||||
|
[_popUpButton selectItemAtIndex: selectedIndex];
|
||||||
|
if (notification) [_popUpButton sendAction: [_popUpButton action] to: [_popUpButton target]];
|
||||||
|
}
|
||||||
|
|
||||||
|
-(void)midiChanged: (NSNotification *)notification {
|
||||||
|
|
||||||
|
[self updateMenus: YES];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
-(void)prepareForReuse {
|
||||||
|
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
|
||||||
|
[nc removeObserver: self];
|
||||||
|
_category = 0;
|
||||||
|
[super prepareForReuse];
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
Loading…
Reference in New Issue
Block a user