From d69c5403784cf8975d909c343cd52d8535fdab61 Mon Sep 17 00:00:00 2001 From: Kevin Wojniak Date: Sat, 23 Mar 2019 23:21:00 -0700 Subject: [PATCH 1/4] Initial implementation --- .gitignore | 5 +- .../DVDScreenSaver-TestApp/AppDelegate.swift | 21 ++ .../Base.lproj/MainMenu.xib | 280 +++++++++++++++ .../DVDScreenSaverView.swift | 74 ++++ .../DVDScreenSaver_TestApp.entitlements | 8 + .../DVDScreenSaver-TestApp/Info.plist | 32 ++ .../DVDScreenSaver.xcodeproj/project.pbxproj | 334 ++++++++++++++++++ .../contents.xcworkspacedata | 7 + .../xcshareddata/IDEWorkspaceChecks.plist | 8 + DVDScreenSaver-Cocoa/MovingLogo.swift | 186 ++++++++++ 10 files changed, 954 insertions(+), 1 deletion(-) create mode 100644 DVDScreenSaver-Cocoa/DVDScreenSaver-TestApp/AppDelegate.swift create mode 100644 DVDScreenSaver-Cocoa/DVDScreenSaver-TestApp/Base.lproj/MainMenu.xib create mode 100644 DVDScreenSaver-Cocoa/DVDScreenSaver-TestApp/DVDScreenSaverView.swift create mode 100644 DVDScreenSaver-Cocoa/DVDScreenSaver-TestApp/DVDScreenSaver_TestApp.entitlements create mode 100644 DVDScreenSaver-Cocoa/DVDScreenSaver-TestApp/Info.plist create mode 100644 DVDScreenSaver-Cocoa/DVDScreenSaver.xcodeproj/project.pbxproj create mode 100644 DVDScreenSaver-Cocoa/DVDScreenSaver.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 DVDScreenSaver-Cocoa/DVDScreenSaver.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 DVDScreenSaver-Cocoa/MovingLogo.swift diff --git a/.gitignore b/.gitignore index 3c4efe2..f299a60 100644 --- a/.gitignore +++ b/.gitignore @@ -258,4 +258,7 @@ paket-files/ # Python Tools for Visual Studio (PTVS) __pycache__/ -*.pyc \ No newline at end of file +*.pyc + +# Xcode +xcuserdata diff --git a/DVDScreenSaver-Cocoa/DVDScreenSaver-TestApp/AppDelegate.swift b/DVDScreenSaver-Cocoa/DVDScreenSaver-TestApp/AppDelegate.swift new file mode 100644 index 0000000..26f1975 --- /dev/null +++ b/DVDScreenSaver-Cocoa/DVDScreenSaver-TestApp/AppDelegate.swift @@ -0,0 +1,21 @@ +// +// AppDelegate.swift +// DVDScreenSaver-TestApp +// +// Created by Kevin Wojniak on 3/23/19. +// Copyright © 2019 Kevin Wojniak. All rights reserved. +// + +import Cocoa + +@NSApplicationMain +class AppDelegate: NSObject, NSApplicationDelegate { + + @IBOutlet weak var window: NSWindow! + + func applicationDidFinishLaunching(_ aNotification: Notification) { + // Insert code here to initialize your application + } + +} + diff --git a/DVDScreenSaver-Cocoa/DVDScreenSaver-TestApp/Base.lproj/MainMenu.xib b/DVDScreenSaver-Cocoa/DVDScreenSaver-TestApp/Base.lproj/MainMenu.xib new file mode 100644 index 0000000..c3fb764 --- /dev/null +++ b/DVDScreenSaver-Cocoa/DVDScreenSaver-TestApp/Base.lproj/MainMenu.xib @@ -0,0 +1,280 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/DVDScreenSaver-Cocoa/DVDScreenSaver-TestApp/DVDScreenSaverView.swift b/DVDScreenSaver-Cocoa/DVDScreenSaver-TestApp/DVDScreenSaverView.swift new file mode 100644 index 0000000..636869c --- /dev/null +++ b/DVDScreenSaver-Cocoa/DVDScreenSaver-TestApp/DVDScreenSaverView.swift @@ -0,0 +1,74 @@ +// +// DVDScreenSaverView.swift +// DVDScreenSaver-TestApp +// +// Created by Kevin Wojniak on 3/23/19. +// Copyright © 2019 Kevin Wojniak. All rights reserved. +// + +import Cocoa + +extension NSColor { + + convenience init(_ r: CGFloat, _ g: CGFloat, _ b: CGFloat) { + self.init(calibratedRed: r/255.0, green: g/255.0, blue: b/255.0, alpha: 1) + } + +} + +class DVDScreenSaverView: NSView { + + @IBOutlet weak var imageView: NSImageView! + + private let logoScale: CGFloat = 6 + private var logo: MovingLogo? + private var timer: Timer? + + override func awakeFromNib() { + guard let image = NSImage(named: "DVDVideo360") else { + print("Failed to load image") + return + } + logo = MovingLogo( + image: image, + colors: [ + NSColor(190, 0, 255), + NSColor(255, 0, 139), + NSColor(255, 131, 0), + NSColor(0, 38, 255), + NSColor(255, 250, 0), + ], + onNewPosition: { rect in + self.imageView.frame = rect + }, + onRedraw: { image in + self.imageView.image = image + } + ) + let rescale = { + guard let bounds = self.imageView.superview?.bounds else { + print("Failed to get bounds") + return + } + self.logo?.rescale(bounds: bounds, scale: self.logoScale) + } + logo?.nextColor() + rescale() + logo?.placeInRandomSpot() + self.imageView.superview?.postsFrameChangedNotifications = true + NotificationCenter.default.addObserver(forName: NSView.frameDidChangeNotification, object: self.imageView.superview, queue: nil) { _ in + rescale() + } + timer = Timer.scheduledTimer(withTimeInterval: 1/60, repeats: true) { _ in + self.logo?.animate() + } + if let timer = timer { + RunLoop.current.add(timer, forMode: .eventTracking) + } + } + + override func draw(_ dirtyRect: NSRect) { + NSColor.black.setFill() + dirtyRect.fill() + } +} diff --git a/DVDScreenSaver-Cocoa/DVDScreenSaver-TestApp/DVDScreenSaver_TestApp.entitlements b/DVDScreenSaver-Cocoa/DVDScreenSaver-TestApp/DVDScreenSaver_TestApp.entitlements new file mode 100644 index 0000000..852fa1a --- /dev/null +++ b/DVDScreenSaver-Cocoa/DVDScreenSaver-TestApp/DVDScreenSaver_TestApp.entitlements @@ -0,0 +1,8 @@ + + + + + com.apple.security.app-sandbox + + + diff --git a/DVDScreenSaver-Cocoa/DVDScreenSaver-TestApp/Info.plist b/DVDScreenSaver-Cocoa/DVDScreenSaver-TestApp/Info.plist new file mode 100644 index 0000000..a7ff43c --- /dev/null +++ b/DVDScreenSaver-Cocoa/DVDScreenSaver-TestApp/Info.plist @@ -0,0 +1,32 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIconFile + + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSMinimumSystemVersion + $(MACOSX_DEPLOYMENT_TARGET) + NSHumanReadableCopyright + Copyright © 2019 Kevin Wojniak. All rights reserved. + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/DVDScreenSaver-Cocoa/DVDScreenSaver.xcodeproj/project.pbxproj b/DVDScreenSaver-Cocoa/DVDScreenSaver.xcodeproj/project.pbxproj new file mode 100644 index 0000000..e4492d2 --- /dev/null +++ b/DVDScreenSaver-Cocoa/DVDScreenSaver.xcodeproj/project.pbxproj @@ -0,0 +1,334 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + A5629BAF224739D80054B0C4 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5629BAE224739D80054B0C4 /* AppDelegate.swift */; }; + A5629BB4224739DA0054B0C4 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = A5629BB2224739DA0054B0C4 /* MainMenu.xib */; }; + A5629BBD22473A370054B0C4 /* DVDVideo360.png in Resources */ = {isa = PBXBuildFile; fileRef = A5629BBC22473A370054B0C4 /* DVDVideo360.png */; }; + A5629BBF22473BD50054B0C4 /* MovingLogo.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5629BBE22473BD50054B0C4 /* MovingLogo.swift */; }; + A5629BC122474A970054B0C4 /* DVDScreenSaverView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5629BC022474A970054B0C4 /* DVDScreenSaverView.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + A5629BAB224739D80054B0C4 /* DVDScreenSaver-TestApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "DVDScreenSaver-TestApp.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + A5629BAE224739D80054B0C4 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + A5629BB3224739DA0054B0C4 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; + A5629BB5224739DA0054B0C4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + A5629BB6224739DA0054B0C4 /* DVDScreenSaver_TestApp.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DVDScreenSaver_TestApp.entitlements; sourceTree = ""; }; + A5629BBC22473A370054B0C4 /* DVDVideo360.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = DVDVideo360.png; path = ../../SharedItems/DVDVideo360.png; sourceTree = ""; }; + A5629BBE22473BD50054B0C4 /* MovingLogo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MovingLogo.swift; sourceTree = SOURCE_ROOT; }; + A5629BC022474A970054B0C4 /* DVDScreenSaverView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DVDScreenSaverView.swift; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + A5629BA8224739D80054B0C4 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + A5629BA2224739D80054B0C4 = { + isa = PBXGroup; + children = ( + A5629BAD224739D80054B0C4 /* DVDScreenSaver-TestApp */, + A5629BAC224739D80054B0C4 /* Products */, + ); + sourceTree = ""; + }; + A5629BAC224739D80054B0C4 /* Products */ = { + isa = PBXGroup; + children = ( + A5629BAB224739D80054B0C4 /* DVDScreenSaver-TestApp.app */, + ); + name = Products; + sourceTree = ""; + }; + A5629BAD224739D80054B0C4 /* DVDScreenSaver-TestApp */ = { + isa = PBXGroup; + children = ( + A5629BAE224739D80054B0C4 /* AppDelegate.swift */, + A5629BBE22473BD50054B0C4 /* MovingLogo.swift */, + A5629BC022474A970054B0C4 /* DVDScreenSaverView.swift */, + A5629BB2224739DA0054B0C4 /* MainMenu.xib */, + A5629BB5224739DA0054B0C4 /* Info.plist */, + A5629BB6224739DA0054B0C4 /* DVDScreenSaver_TestApp.entitlements */, + A5629BBC22473A370054B0C4 /* DVDVideo360.png */, + ); + path = "DVDScreenSaver-TestApp"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + A5629BAA224739D80054B0C4 /* DVDScreenSaver-TestApp */ = { + isa = PBXNativeTarget; + buildConfigurationList = A5629BB9224739DA0054B0C4 /* Build configuration list for PBXNativeTarget "DVDScreenSaver-TestApp" */; + buildPhases = ( + A5629BA7224739D80054B0C4 /* Sources */, + A5629BA8224739D80054B0C4 /* Frameworks */, + A5629BA9224739D80054B0C4 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "DVDScreenSaver-TestApp"; + productName = "DVDScreenSaver-TestApp"; + productReference = A5629BAB224739D80054B0C4 /* DVDScreenSaver-TestApp.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + A5629BA3224739D80054B0C4 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1010; + LastUpgradeCheck = 1010; + ORGANIZATIONNAME = "Kevin Wojniak"; + TargetAttributes = { + A5629BAA224739D80054B0C4 = { + CreatedOnToolsVersion = 10.1; + }; + }; + }; + buildConfigurationList = A5629BA6224739D80054B0C4 /* Build configuration list for PBXProject "DVDScreenSaver" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = A5629BA2224739D80054B0C4; + productRefGroup = A5629BAC224739D80054B0C4 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + A5629BAA224739D80054B0C4 /* DVDScreenSaver-TestApp */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + A5629BA9224739D80054B0C4 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + A5629BBD22473A370054B0C4 /* DVDVideo360.png in Resources */, + A5629BB4224739DA0054B0C4 /* MainMenu.xib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + A5629BA7224739D80054B0C4 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + A5629BBF22473BD50054B0C4 /* MovingLogo.swift in Sources */, + A5629BAF224739D80054B0C4 /* AppDelegate.swift in Sources */, + A5629BC122474A970054B0C4 /* DVDScreenSaverView.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + A5629BB2224739DA0054B0C4 /* MainMenu.xib */ = { + isa = PBXVariantGroup; + children = ( + A5629BB3224739DA0054B0C4 /* Base */, + ); + name = MainMenu.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + A5629BB7224739DA0054B0C4 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + 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 = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + 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.14; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = macosx; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + A5629BB8224739DA0054B0C4 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + 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 = gnu11; + 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.14; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = macosx; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + }; + name = Release; + }; + A5629BBA224739DA0054B0C4 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_ENTITLEMENTS = "DVDScreenSaver-TestApp/DVDScreenSaver_TestApp.entitlements"; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + INFOPLIST_FILE = "DVDScreenSaver-TestApp/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "com.kainjow.DVDScreenSaver-TestApp"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 4.2; + }; + name = Debug; + }; + A5629BBB224739DA0054B0C4 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_ENTITLEMENTS = "DVDScreenSaver-TestApp/DVDScreenSaver_TestApp.entitlements"; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + INFOPLIST_FILE = "DVDScreenSaver-TestApp/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "com.kainjow.DVDScreenSaver-TestApp"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 4.2; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + A5629BA6224739D80054B0C4 /* Build configuration list for PBXProject "DVDScreenSaver" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + A5629BB7224739DA0054B0C4 /* Debug */, + A5629BB8224739DA0054B0C4 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + A5629BB9224739DA0054B0C4 /* Build configuration list for PBXNativeTarget "DVDScreenSaver-TestApp" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + A5629BBA224739DA0054B0C4 /* Debug */, + A5629BBB224739DA0054B0C4 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = A5629BA3224739D80054B0C4 /* Project object */; +} diff --git a/DVDScreenSaver-Cocoa/DVDScreenSaver.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/DVDScreenSaver-Cocoa/DVDScreenSaver.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..da07a03 --- /dev/null +++ b/DVDScreenSaver-Cocoa/DVDScreenSaver.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/DVDScreenSaver-Cocoa/DVDScreenSaver.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/DVDScreenSaver-Cocoa/DVDScreenSaver.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/DVDScreenSaver-Cocoa/DVDScreenSaver.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/DVDScreenSaver-Cocoa/MovingLogo.swift b/DVDScreenSaver-Cocoa/MovingLogo.swift new file mode 100644 index 0000000..1e7a601 --- /dev/null +++ b/DVDScreenSaver-Cocoa/MovingLogo.swift @@ -0,0 +1,186 @@ +// +// MovingLogo.swift +// DVDScreenSaver-TestApp +// +// Created by Kevin Wojniak on 3/23/19. +// Copyright © 2019 Kevin Wojniak. All rights reserved. +// + +import Cocoa + +typealias RectDbl = NSRect + +extension RectDbl { + + public var right: CGFloat { + return origin.x + width + } + + public var bottom: CGFloat { + return origin.y + height + } + + public var diagonal: CGFloat { + return sqrt(pow(width, 2) + pow(height, 2)) + } + +} + +class Stopwatch { + + private var time = Date() + + public func start() { + time = Date() + } + + public var elapsedMilliseconds: CGFloat { + return round(CGFloat(Date().timeIntervalSince(time)) * 1000) + } + + public func restart() { + start() + } + +} + +class MovingLogo { + + enum MoveMode { + case normal + case opposite + case allCorners + } + + typealias OnNewPosition = (NSRect) -> Void + private let onNewPosition: OnNewPosition + typealias OnRedraw = (NSImage) -> Void + private let onRedraw: OnRedraw + + private var colorIdx = -1 + private let watch = Stopwatch() + private var rect = RectDbl() + private var bounds = RectDbl() + private var scale = CGFloat() + + private let image: NSImage + private let colors: [NSColor] + private var mode: MoveMode = .normal + private var moveRight = true + private var moveDown = true + private var speed: CGFloat = 2 + + init(image: NSImage, colors: [NSColor], onNewPosition: @escaping OnNewPosition, onRedraw: @escaping OnRedraw) { + self.image = image + self.colors = colors + self.onNewPosition = onNewPosition + self.onRedraw = onRedraw + self.rect = NSRect(x: 0, y: 0, width: image.size.width, height: image.size.height) + self.watch.start() + } + + public func animate() { + let origX = rect.origin.x + let origY = rect.origin.y + var x = origX + var y = origY + var bOutOfBounds = false + + if rect.right >= bounds.right { + moveRight = false + bOutOfBounds = true + } else if rect.origin.x < bounds.origin.x { + moveRight = true + bOutOfBounds = true + } + + if rect.bottom >= bounds.bottom { + moveDown = false + bOutOfBounds = true + } else if rect.origin.y <= bounds.origin.y { + moveDown = true + bOutOfBounds = true + } + + if bOutOfBounds { + nextColor() + } + + switch mode { + case .normal: + x += moveRight ? speed : -speed + y += moveDown ? speed : -speed + case .opposite: + let width = bounds.width - rect.width + let height = bounds.height - rect.height + let theta = atan(height / width) + let hyppos = sqrt(pow(x - bounds.origin.x, 2) + pow(y - bounds.origin.y, 2)) + x = (hyppos + (moveRight ? speed : -speed) * 2) * cos(theta) + y = (hyppos + (moveDown ? speed : -speed) * 2) * sin(theta) + case .allCorners: + break //TODO + } + + let step = watch.elapsedMilliseconds / 10 + let moveX = (x - origX) * step + let moveY = (y - origY) * step + rect.origin.x += moveX + rect.origin.y += moveY + + onNewPosition(rect) + watch.restart() + } + + public func rescale(bounds: NSRect, scale: CGFloat) { + self.bounds = bounds + self.scale = scale + let ratio = image.size.width / image.size.height + rect.size.height = bounds.diagonal / scale / ratio + rect.size.width = rect.height * ratio + rect.origin.x = min(max(rect.origin.x, 0), bounds.width - rect.width) + rect.origin.y = min(max(rect.origin.y, 0), bounds.height - rect.height) + animate() + } + + public func nextMode() { + switch mode { + case .normal: + mode = .opposite + case .opposite: + mode = .normal + placeInRandomSpot() + case .allCorners: + mode = .normal + } + } + + public func nextColor() { + colorIdx = (colorIdx + 1) % colors.count + let image = recolorLogo(colors[colorIdx]) + onRedraw(image) + } + + public func placeInRandomSpot() { + rect.origin.x = floor(CGFloat.random(in: 0 ..< (bounds.width - rect.width))) + rect.origin.y = floor(CGFloat.random(in: 0 ..< (bounds.height - rect.height))) + animate() + } + + private func recolorLogo(_ color: NSColor) -> NSImage { + return NSImage(size: image.size, flipped: false) { rect in + guard let ctx = NSGraphicsContext.current else { + return false + } + ctx.saveGraphicsState() + defer { + ctx.restoreGraphicsState() + } + ctx.compositingOperation = .sourceAtop + self.image.draw(in: rect) + color.setFill() + NSBezierPath.fill(rect) + return true + } + } + +} From 0f292c6635cda14e4254e0aa62aa2f63c63e41b0 Mon Sep 17 00:00:00 2001 From: Kevin Wojniak Date: Sat, 23 Mar 2019 23:39:34 -0700 Subject: [PATCH 2/4] Tweaks --- .../DVDScreenSaver-TestApp/AppDelegate.swift | 7 ------- .../Base.lproj/MainMenu.xib | 8 ++------ .../DVDScreenSaverView.swift | 15 ++++++--------- DVDScreenSaver-Cocoa/MovingLogo.swift | 5 +++-- 4 files changed, 11 insertions(+), 24 deletions(-) diff --git a/DVDScreenSaver-Cocoa/DVDScreenSaver-TestApp/AppDelegate.swift b/DVDScreenSaver-Cocoa/DVDScreenSaver-TestApp/AppDelegate.swift index 26f1975..e78fca2 100644 --- a/DVDScreenSaver-Cocoa/DVDScreenSaver-TestApp/AppDelegate.swift +++ b/DVDScreenSaver-Cocoa/DVDScreenSaver-TestApp/AppDelegate.swift @@ -11,11 +11,4 @@ import Cocoa @NSApplicationMain class AppDelegate: NSObject, NSApplicationDelegate { - @IBOutlet weak var window: NSWindow! - - func applicationDidFinishLaunching(_ aNotification: Notification) { - // Insert code here to initialize your application - } - } - diff --git a/DVDScreenSaver-Cocoa/DVDScreenSaver-TestApp/Base.lproj/MainMenu.xib b/DVDScreenSaver-Cocoa/DVDScreenSaver-TestApp/Base.lproj/MainMenu.xib index c3fb764..b442103 100644 --- a/DVDScreenSaver-Cocoa/DVDScreenSaver-TestApp/Base.lproj/MainMenu.xib +++ b/DVDScreenSaver-Cocoa/DVDScreenSaver-TestApp/Base.lproj/MainMenu.xib @@ -12,11 +12,7 @@ - - - - - + @@ -245,7 +241,7 @@ - + diff --git a/DVDScreenSaver-Cocoa/DVDScreenSaver-TestApp/DVDScreenSaverView.swift b/DVDScreenSaver-Cocoa/DVDScreenSaver-TestApp/DVDScreenSaverView.swift index 636869c..8f496eb 100644 --- a/DVDScreenSaver-Cocoa/DVDScreenSaver-TestApp/DVDScreenSaverView.swift +++ b/DVDScreenSaver-Cocoa/DVDScreenSaver-TestApp/DVDScreenSaverView.swift @@ -25,8 +25,9 @@ class DVDScreenSaverView: NSView { private var timer: Timer? override func awakeFromNib() { - guard let image = NSImage(named: "DVDVideo360") else { - print("Failed to load image") + guard let image = NSImage(named: "DVDVideo360"), + let superview = self.imageView.superview else { + print("Setup failed") return } logo = MovingLogo( @@ -46,17 +47,13 @@ class DVDScreenSaverView: NSView { } ) let rescale = { - guard let bounds = self.imageView.superview?.bounds else { - print("Failed to get bounds") - return - } - self.logo?.rescale(bounds: bounds, scale: self.logoScale) + self.logo?.rescale(bounds: superview.bounds, scale: self.logoScale) } logo?.nextColor() rescale() logo?.placeInRandomSpot() - self.imageView.superview?.postsFrameChangedNotifications = true - NotificationCenter.default.addObserver(forName: NSView.frameDidChangeNotification, object: self.imageView.superview, queue: nil) { _ in + superview.postsFrameChangedNotifications = true + NotificationCenter.default.addObserver(forName: NSView.frameDidChangeNotification, object: superview, queue: nil) { _ in rescale() } timer = Timer.scheduledTimer(withTimeInterval: 1/60, repeats: true) { _ in diff --git a/DVDScreenSaver-Cocoa/MovingLogo.swift b/DVDScreenSaver-Cocoa/MovingLogo.swift index 1e7a601..0048862 100644 --- a/DVDScreenSaver-Cocoa/MovingLogo.swift +++ b/DVDScreenSaver-Cocoa/MovingLogo.swift @@ -89,7 +89,7 @@ class MovingLogo { if rect.right >= bounds.right { moveRight = false bOutOfBounds = true - } else if rect.origin.x < bounds.origin.x { + } else if rect.origin.x <= bounds.origin.x { moveRight = true bOutOfBounds = true } @@ -118,7 +118,8 @@ class MovingLogo { x = (hyppos + (moveRight ? speed : -speed) * 2) * cos(theta) y = (hyppos + (moveDown ? speed : -speed) * 2) * sin(theta) case .allCorners: - break //TODO + //TODO + break } let step = watch.elapsedMilliseconds / 10 From ca55c1d45e8b54da38963c9f73213d4e3dd7a496 Mon Sep 17 00:00:00 2001 From: Kevin Wojniak Date: Sat, 23 Mar 2019 23:47:33 -0700 Subject: [PATCH 3/4] Set window color --- .../DVDScreenSaver-TestApp/DVDScreenSaverView.swift | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/DVDScreenSaver-Cocoa/DVDScreenSaver-TestApp/DVDScreenSaverView.swift b/DVDScreenSaver-Cocoa/DVDScreenSaver-TestApp/DVDScreenSaverView.swift index 8f496eb..dddcb5b 100644 --- a/DVDScreenSaver-Cocoa/DVDScreenSaver-TestApp/DVDScreenSaverView.swift +++ b/DVDScreenSaver-Cocoa/DVDScreenSaver-TestApp/DVDScreenSaverView.swift @@ -64,8 +64,10 @@ class DVDScreenSaverView: NSView { } } - override func draw(_ dirtyRect: NSRect) { - NSColor.black.setFill() - dirtyRect.fill() + override func viewDidMoveToWindow() { + if let win = window { + win.backgroundColor = .black + } } + } From 862930650684d8c8e08b5a20acc0c9ca2cf0c6f6 Mon Sep 17 00:00:00 2001 From: Kevin Wojniak Date: Sat, 23 Mar 2019 23:49:10 -0700 Subject: [PATCH 4/4] Cleanup --- .../DVDScreenSaver-TestApp/AppDelegate.swift | 8 -------- .../DVDScreenSaver-TestApp/DVDScreenSaverView.swift | 8 -------- DVDScreenSaver-Cocoa/DVDScreenSaver-TestApp/Info.plist | 2 -- .../DVDScreenSaver.xcodeproj/project.pbxproj | 4 ++-- DVDScreenSaver-Cocoa/MovingLogo.swift | 8 -------- 5 files changed, 2 insertions(+), 28 deletions(-) diff --git a/DVDScreenSaver-Cocoa/DVDScreenSaver-TestApp/AppDelegate.swift b/DVDScreenSaver-Cocoa/DVDScreenSaver-TestApp/AppDelegate.swift index e78fca2..dcd9c27 100644 --- a/DVDScreenSaver-Cocoa/DVDScreenSaver-TestApp/AppDelegate.swift +++ b/DVDScreenSaver-Cocoa/DVDScreenSaver-TestApp/AppDelegate.swift @@ -1,11 +1,3 @@ -// -// AppDelegate.swift -// DVDScreenSaver-TestApp -// -// Created by Kevin Wojniak on 3/23/19. -// Copyright © 2019 Kevin Wojniak. All rights reserved. -// - import Cocoa @NSApplicationMain diff --git a/DVDScreenSaver-Cocoa/DVDScreenSaver-TestApp/DVDScreenSaverView.swift b/DVDScreenSaver-Cocoa/DVDScreenSaver-TestApp/DVDScreenSaverView.swift index dddcb5b..1346639 100644 --- a/DVDScreenSaver-Cocoa/DVDScreenSaver-TestApp/DVDScreenSaverView.swift +++ b/DVDScreenSaver-Cocoa/DVDScreenSaver-TestApp/DVDScreenSaverView.swift @@ -1,11 +1,3 @@ -// -// DVDScreenSaverView.swift -// DVDScreenSaver-TestApp -// -// Created by Kevin Wojniak on 3/23/19. -// Copyright © 2019 Kevin Wojniak. All rights reserved. -// - import Cocoa extension NSColor { diff --git a/DVDScreenSaver-Cocoa/DVDScreenSaver-TestApp/Info.plist b/DVDScreenSaver-Cocoa/DVDScreenSaver-TestApp/Info.plist index a7ff43c..3588abd 100644 --- a/DVDScreenSaver-Cocoa/DVDScreenSaver-TestApp/Info.plist +++ b/DVDScreenSaver-Cocoa/DVDScreenSaver-TestApp/Info.plist @@ -22,8 +22,6 @@ 1 LSMinimumSystemVersion $(MACOSX_DEPLOYMENT_TARGET) - NSHumanReadableCopyright - Copyright © 2019 Kevin Wojniak. All rights reserved. NSMainNibFile MainMenu NSPrincipalClass diff --git a/DVDScreenSaver-Cocoa/DVDScreenSaver.xcodeproj/project.pbxproj b/DVDScreenSaver-Cocoa/DVDScreenSaver.xcodeproj/project.pbxproj index e4492d2..00dca66 100644 --- a/DVDScreenSaver-Cocoa/DVDScreenSaver.xcodeproj/project.pbxproj +++ b/DVDScreenSaver-Cocoa/DVDScreenSaver.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 50; + objectVersion = 51; objects = { /* Begin PBXBuildFile section */ @@ -102,7 +102,7 @@ }; }; buildConfigurationList = A5629BA6224739D80054B0C4 /* Build configuration list for PBXProject "DVDScreenSaver" */; - compatibilityVersion = "Xcode 9.3"; + compatibilityVersion = "Xcode 10.0"; developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( diff --git a/DVDScreenSaver-Cocoa/MovingLogo.swift b/DVDScreenSaver-Cocoa/MovingLogo.swift index 0048862..c5616c3 100644 --- a/DVDScreenSaver-Cocoa/MovingLogo.swift +++ b/DVDScreenSaver-Cocoa/MovingLogo.swift @@ -1,11 +1,3 @@ -// -// MovingLogo.swift -// DVDScreenSaver-TestApp -// -// Created by Kevin Wojniak on 3/23/19. -// Copyright © 2019 Kevin Wojniak. All rights reserved. -// - import Cocoa typealias RectDbl = NSRect