From 420d7069795077d37e9eb1e690a95635eefc94d4 Mon Sep 17 00:00:00 2001 From: Christopher Snowhill Date: Thu, 23 Feb 2023 17:45:59 -0800 Subject: [PATCH] Lyrics: Implement Lyrics window display and hotkey Implement Lyrics window display into main app as a popup window panel, with a main menu hotkey. Signed-off-by: Christopher Snowhill --- Base.lproj/LyricsWindow.xib | 66 +++++++++++++++++++++++++++ Base.lproj/MainMenu.xib | 28 ++++++++---- Cog.xcodeproj/project.pbxproj | 26 +++++++++++ LyricsWindow/LyricsWindowController.h | 28 ++++++++++++ LyricsWindow/LyricsWindowController.m | 63 +++++++++++++++++++++++++ 5 files changed, 203 insertions(+), 8 deletions(-) create mode 100644 Base.lproj/LyricsWindow.xib create mode 100644 LyricsWindow/LyricsWindowController.h create mode 100644 LyricsWindow/LyricsWindowController.m diff --git a/Base.lproj/LyricsWindow.xib b/Base.lproj/LyricsWindow.xib new file mode 100644 index 000000000..3a83a1ab9 --- /dev/null +++ b/Base.lproj/LyricsWindow.xib @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Base.lproj/MainMenu.xib b/Base.lproj/MainMenu.xib index 108ae9254..9941d4213 100644 --- a/Base.lproj/MainMenu.xib +++ b/Base.lproj/MainMenu.xib @@ -1,8 +1,8 @@ - + - + @@ -25,17 +25,17 @@ - + - + - + - + @@ -680,12 +680,12 @@ - + @@ -1531,6 +1531,11 @@ + + + + + @@ -2504,6 +2509,13 @@ Gw + + + + + + + diff --git a/Cog.xcodeproj/project.pbxproj b/Cog.xcodeproj/project.pbxproj index ba4aeff71..b48b0658e 100644 --- a/Cog.xcodeproj/project.pbxproj +++ b/Cog.xcodeproj/project.pbxproj @@ -193,6 +193,8 @@ 83AA7D06279EBCAD00087AA4 /* libavutil.57.dylib in CopyFiles */ = {isa = PBXBuildFile; fileRef = 83AA7D02279EBC8200087AA4 /* libavutil.57.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; 83AA7D07279EBCAF00087AA4 /* libswresample.4.dylib in CopyFiles */ = {isa = PBXBuildFile; fileRef = 83AA7D01279EBC8200087AA4 /* libswresample.4.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; 83B06704180D579E008E3612 /* MIDI.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = 83B066A1180D5669008E3612 /* MIDI.bundle */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; + 83B61E2429A8296500CD0580 /* LyricsWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 83B61E2229A8296500CD0580 /* LyricsWindow.xib */; }; + 83B61E2829A82A0200CD0580 /* LyricsWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 83B61E2729A82A0200CD0580 /* LyricsWindowController.m */; }; 83B72E3B279045B7006007A3 /* libfdk-aac.2.dylib in CopyFiles */ = {isa = PBXBuildFile; fileRef = 83B72E2A279044F6006007A3 /* libfdk-aac.2.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; 83BC5AB220E4C87100631CD4 /* DualWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = 83BC5AB020E4C87100631CD4 /* DualWindow.m */; }; 83BC5ABF20E4CE7A00631CD4 /* InfoInspector.xib in Resources */ = {isa = PBXBuildFile; fileRef = 17D1B0D00F6320EA00694C57 /* InfoInspector.xib */; }; @@ -1070,6 +1072,9 @@ 83AA7D03279EBC8300087AA4 /* libavformat.59.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libavformat.59.dylib; path = ThirdParty/ffmpeg/lib/libavformat.59.dylib; sourceTree = ""; }; 83AB9031237CEFD300A433D5 /* MediaPlayer.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MediaPlayer.framework; path = System/Library/Frameworks/MediaPlayer.framework; sourceTree = SDKROOT; }; 83B0669C180D5668008E3612 /* MIDI.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = MIDI.xcodeproj; path = Plugins/MIDI/MIDI.xcodeproj; sourceTree = ""; }; + 83B61E2329A8296500CD0580 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LyricsWindow.xib; sourceTree = ""; }; + 83B61E2629A82A0200CD0580 /* LyricsWindowController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LyricsWindowController.h; sourceTree = ""; }; + 83B61E2729A82A0200CD0580 /* LyricsWindowController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LyricsWindowController.m; sourceTree = ""; }; 83B72E2A279044F6006007A3 /* libfdk-aac.2.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = "libfdk-aac.2.dylib"; path = "ThirdParty/fdk-aac/lib/libfdk-aac.2.dylib"; sourceTree = ""; }; 83BC5AB020E4C87100631CD4 /* DualWindow.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DualWindow.m; path = Window/DualWindow.m; sourceTree = ""; }; 83BC5AB120E4C87100631CD4 /* DualWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DualWindow.h; path = Window/DualWindow.h; sourceTree = ""; }; @@ -1186,6 +1191,7 @@ 17DDF6400E0CB6F100A2E4AD /* FileTree */, 830C37A227B95E6000E02BB0 /* Equalizer */, 17D1B0FE0F63252900694C57 /* InfoInspector */, + 83B61E2529A8299A00CD0580 /* LyricsWindow */, 569C52C50D5F2BD500BDBDC9 /* Spotlight */, 17E0D5F60F520F42005B6FED /* Transformers */, 177EC0110B8BC2CF0000BC8C /* Utils */, @@ -1612,6 +1618,7 @@ 178456C00F6320B5007E8021 /* SpotlightPanel.xib */, 17E41E060C130DFF00AC744D /* Credits.html */, 17D1B1DA0F6330D400694C57 /* Feedback.xib */, + 83B61E2229A8296500CD0580 /* LyricsWindow.xib */, 836DF61D298F7F6E00CD0580 /* Scenes.scnassets */, ); name = Resources; @@ -1910,6 +1917,15 @@ name = Products; sourceTree = ""; }; + 83B61E2529A8299A00CD0580 /* LyricsWindow */ = { + isa = PBXGroup; + children = ( + 83B61E2629A82A0200CD0580 /* LyricsWindowController.h */, + 83B61E2729A82A0200CD0580 /* LyricsWindowController.m */, + ); + path = LyricsWindow; + sourceTree = ""; + }; 83BB13AE20E4E38E00723731 /* Products */ = { isa = PBXGroup; children = ( @@ -2538,6 +2554,7 @@ 83BC5AC320E4CE8D00631CD4 /* SpotlightPanel.xib in Resources */, 83BC5AC220E4CE8A00631CD4 /* FileTree.xib in Resources */, 83BC5AC120E4CE8700631CD4 /* OpenURLPanel.xib in Resources */, + 83B61E2429A8296500CD0580 /* LyricsWindow.xib in Resources */, 0A1B412C286F6301008A6A44 /* Localizable.stringsdict in Resources */, 83BC5AC020E4CE7D00631CD4 /* MainMenu.xib in Resources */, 83BC5ABF20E4CE7A00631CD4 /* InfoInspector.xib in Resources */, @@ -2686,6 +2703,7 @@ 56462EAF0D6341F6000AB68C /* SpotlightTransformers.m in Sources */, 830C37A527B95EB300E02BB0 /* EqualizerWindowController.m in Sources */, 832CFC562851AA8B002AC26F /* SpectrumViewCG.m in Sources */, + 83B61E2829A82A0200CD0580 /* LyricsWindowController.m in Sources */, 56462EB20D634206000AB68C /* SpotlightPlaylistController.m in Sources */, 07E18DF30D62B38400BB0E11 /* NSArray+ShuffleUtils.m in Sources */, 56C63D910D647DF300EAE25A /* NSComparisonPredicate+CogPredicate.m in Sources */, @@ -3049,6 +3067,14 @@ name = SpectrumWindow.xib; sourceTree = ""; }; + 83B61E2229A8296500CD0580 /* LyricsWindow.xib */ = { + isa = PBXVariantGroup; + children = ( + 83B61E2329A8296500CD0580 /* Base */, + ); + name = LyricsWindow.xib; + sourceTree = ""; + }; 8E7575D909F31E930080F1EE /* Localizable.strings */ = { isa = PBXVariantGroup; children = ( diff --git a/LyricsWindow/LyricsWindowController.h b/LyricsWindow/LyricsWindowController.h new file mode 100644 index 000000000..3ea219c62 --- /dev/null +++ b/LyricsWindow/LyricsWindowController.h @@ -0,0 +1,28 @@ +// +// LyricsWindowController.h +// Cog +// +// Created by Christopher Snowhill on 2/23/23. +// + +#import + +#import "AppController.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface LyricsWindowController : NSWindowController { + IBOutlet id playlistSelectionController; + IBOutlet id currentEntryController; + IBOutlet AppController *appController; + + id __unsafe_unretained valueToDisplay; +} + +@property(assign) id valueToDisplay; + +- (IBAction)toggleWindow:(id)sender; + +@end + +NS_ASSUME_NONNULL_END diff --git a/LyricsWindow/LyricsWindowController.m b/LyricsWindow/LyricsWindowController.m new file mode 100644 index 000000000..eeb0635c8 --- /dev/null +++ b/LyricsWindow/LyricsWindowController.m @@ -0,0 +1,63 @@ +// +// LyricsWindowController.m +// Cog +// +// Created by Christopher Snowhill on 2/23/23. +// + +#import "LyricsWindowController.h" + +#import "AppController.h" +#import "PlaylistEntry.h" + +@interface LyricsWindowController () + +@end + +@implementation LyricsWindowController + +static void *kLyricsWindowControllerContext = &kLyricsWindowControllerContext; + +@synthesize valueToDisplay; + +- (id)init { + return [super initWithWindowNibName:@"LyricsWindow"]; +} + +- (void)awakeFromNib { + [playlistSelectionController addObserver:self forKeyPath:@"selection" options:NSKeyValueObservingOptionNew context:kLyricsWindowControllerContext]; + [currentEntryController addObserver:self forKeyPath:@"content" options:NSKeyValueObservingOptionNew context:kLyricsWindowControllerContext]; + [appController addObserver:self forKeyPath:@"miniMode" options:NSKeyValueObservingOptionNew context:kLyricsWindowControllerContext]; +} + +- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { + if(context == kLyricsWindowControllerContext) { + // Avoid "selection" because it creates a proxy that's hard to reason with when we don't need to write. + PlaylistEntry *currentSelection = [[playlistSelectionController selectedObjects] firstObject]; + if(currentSelection != NULL) { + [self setValueToDisplay:currentSelection]; + } else { + [self setValueToDisplay:[currentEntryController content]]; + } + } else { + [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; + } +} + +- (IBAction)toggleWindow:(id)sender { + if([[self window] isVisible]) + [[self window] orderOut:self]; + else { + if([NSApp mainWindow]) { + NSRect rect = [[NSApp mainWindow] frame]; + // Align Lyrics Window to the right of Main Window. + NSPoint point = NSMakePoint(NSMaxX(rect), NSMaxY(rect)); + [[self window] setFrameTopLeftPoint:point]; + } + [self showWindow:self]; + } +} + + + +@end