diff --git a/CodeEdit.xcodeproj/project.pbxproj b/CodeEdit.xcodeproj/project.pbxproj index 7240eddadc..c4f3946845 100644 --- a/CodeEdit.xcodeproj/project.pbxproj +++ b/CodeEdit.xcodeproj/project.pbxproj @@ -10,7 +10,6 @@ 043C321427E31FF6006AE443 /* CodeEditDocumentController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 043C321327E31FF6006AE443 /* CodeEditDocumentController.swift */; }; 043C321627E3201F006AE443 /* WorkspaceDocument.swift in Sources */ = {isa = PBXBuildFile; fileRef = 043C321527E3201F006AE443 /* WorkspaceDocument.swift */; }; 043C321A27E32295006AE443 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 043C321927E32295006AE443 /* MainMenu.xib */; }; - 04540D5B27DD08C300E91B77 /* SettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04F2BF0E27DBB28E0024EAB1 /* SettingsView.swift */; }; 04540D5C27DD08C300E91B77 /* GeneralSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04F2BF1127DBB3C10024EAB1 /* GeneralSettingsView.swift */; }; 04540D5E27DD08C300E91B77 /* WorkspaceView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B658FB3127DA9E0F00EA4DBD /* WorkspaceView.swift */; }; 04660F6427E3ACAF00477777 /* Appearances.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04660F6327E3ACAF00477777 /* Appearances.swift */; }; @@ -36,6 +35,11 @@ 5C403B8F27E20F8000788241 /* WorkspaceClient in Frameworks */ = {isa = PBXBuildFile; productRef = 5C403B8E27E20F8000788241 /* WorkspaceClient */; }; 5CF38A5E27E48E6C0096A0F7 /* CodeFile in Frameworks */ = {isa = PBXBuildFile; productRef = 5CF38A5D27E48E6C0096A0F7 /* CodeFile */; }; 5CFA753B27E896B60002F01B /* GitClient in Frameworks */ = {isa = PBXBuildFile; productRef = 5CFA753A27E896B60002F01B /* GitClient */; }; + 903D6F3827E9E8C300EC4943 /* Preferences in Frameworks */ = {isa = PBXBuildFile; productRef = 903D6F3727E9E8C300EC4943 /* Preferences */; }; + 903D6F3A27E9E8F900EC4943 /* PaneIdentifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 903D6F3927E9E8F900EC4943 /* PaneIdentifier.swift */; }; + 90626F8327E9EDA1008926FE /* ThemeSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90626F8227E9EDA1008926FE /* ThemeSettingsView.swift */; }; + 90626F8527E9EFE4008926FE /* Theme.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90626F8427E9EFE4008926FE /* Theme.swift */; }; + 90626F8827E9F2D8008926FE /* Color+Hex.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90626F8727E9F2D8008926FE /* Color+Hex.swift */; }; B658FB3427DA9E1000EA4DBD /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B658FB3327DA9E1000EA4DBD /* Assets.xcassets */; }; B658FB3727DA9E1000EA4DBD /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B658FB3627DA9E1000EA4DBD /* Preview Assets.xcassets */; }; B65E614627E6765D00255275 /* Introspect in Frameworks */ = {isa = PBXBuildFile; productRef = B65E614527E6765D00255275 /* Introspect */; }; @@ -82,7 +86,6 @@ 0485EB2227E7791400138301 /* QuickOpenPreviewView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuickOpenPreviewView.swift; sourceTree = ""; }; 04ADA0C827E5D29000BF00B2 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/Localizable.strings; sourceTree = ""; }; 04ADA0CA27E5D41F00BF00B2 /* be */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = be; path = be.lproj/Localizable.strings; sourceTree = ""; }; - 04F2BF0E27DBB28E0024EAB1 /* SettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsView.swift; sourceTree = ""; }; 04F2BF1127DBB3C10024EAB1 /* GeneralSettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeneralSettingsView.swift; sourceTree = ""; }; 12F71F7127E833A000095416 /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = ja.lproj/Localizable.strings; sourceTree = ""; }; 20F8067027E65A5200EB7827 /* af */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = af; path = af.lproj/Localizable.strings; sourceTree = ""; }; @@ -101,6 +104,10 @@ 70F2E28327E848720002BA81 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Localizable.strings"; sourceTree = ""; }; 7A4D129627E8E7BD00D4AE07 /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/Localizable.strings; sourceTree = ""; }; 85D7EE9527E928B900CB9F10 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/Localizable.strings; sourceTree = ""; }; + 903D6F3927E9E8F900EC4943 /* PaneIdentifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaneIdentifier.swift; sourceTree = ""; }; + 90626F8227E9EDA1008926FE /* ThemeSettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThemeSettingsView.swift; sourceTree = ""; }; + 90626F8427E9EFE4008926FE /* Theme.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Theme.swift; sourceTree = ""; }; + 90626F8727E9F2D8008926FE /* Color+Hex.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Color+Hex.swift"; sourceTree = ""; }; B658FB2C27DA9E0F00EA4DBD /* CodeEdit.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = CodeEdit.app; sourceTree = BUILT_PRODUCTS_DIR; }; B658FB3127DA9E0F00EA4DBD /* WorkspaceView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WorkspaceView.swift; sourceTree = ""; }; B658FB3327DA9E1000EA4DBD /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; @@ -129,6 +136,7 @@ B65E614627E6765D00255275 /* Introspect in Frameworks */, D70F5E2C27E4E8CF004EE4B9 /* WelcomeModule in Frameworks */, 5CFA753B27E896B60002F01B /* GitClient in Frameworks */, + 903D6F3827E9E8C300EC4943 /* Preferences in Frameworks */, 28CE5EA027E6493D0065D29C /* StatusBar in Frameworks */, 5CF38A5E27E48E6C0096A0F7 /* CodeFile in Frameworks */, ); @@ -168,6 +176,8 @@ 04660F6327E3ACAF00477777 /* Appearances.swift */, 04660F6527E3ACEF00477777 /* ReopenBehavior.swift */, 289978EC27E4E97E00BB0357 /* FileIconStyle.swift */, + 903D6F3927E9E8F900EC4943 /* PaneIdentifier.swift */, + 90626F8427E9EFE4008926FE /* Theme.swift */, ); path = Models; sourceTree = ""; @@ -186,8 +196,8 @@ isa = PBXGroup; children = ( 04660F6227E3ACA300477777 /* Models */, - 04F2BF0E27DBB28E0024EAB1 /* SettingsView.swift */, 04F2BF1127DBB3C10024EAB1 /* GeneralSettingsView.swift */, + 90626F8227E9EDA1008926FE /* ThemeSettingsView.swift */, ); path = Settings; sourceTree = ""; @@ -236,6 +246,14 @@ name = Frameworks; sourceTree = ""; }; + 90626F8627E9F2CD008926FE /* Extension */ = { + isa = PBXGroup; + children = ( + 90626F8727E9F2D8008926FE /* Color+Hex.swift */, + ); + path = Extension; + sourceTree = ""; + }; B658FB2327DA9E0F00EA4DBD = { isa = PBXGroup; children = ( @@ -258,6 +276,7 @@ B658FB2E27DA9E0F00EA4DBD /* CodeEdit */ = { isa = PBXGroup; children = ( + 90626F8627E9F2CD008926FE /* Extension */, B6EE988E27E8877C00CDD8AB /* InspectorSidebar */, 0485EB1727E7016400138301 /* Quick Open */, 04660F6027E3A68A00477777 /* Info.plist */, @@ -342,6 +361,7 @@ 28CE5E9F27E6493D0065D29C /* StatusBar */, 0485EB2427E7B9C800138301 /* Overlays */, 5CFA753A27E896B60002F01B /* GitClient */, + 903D6F3727E9E8C300EC4943 /* Preferences */, ); productName = CodeEdit; productReference = B658FB2C27DA9E0F00EA4DBD /* CodeEdit.app */; @@ -427,6 +447,7 @@ mainGroup = B658FB2327DA9E0F00EA4DBD; packageReferences = ( B65E614427E6765D00255275 /* XCRemoteSwiftPackageReference "SwiftUI-Introspect" */, + 903D6F3627E9E8C300EC4943 /* XCRemoteSwiftPackageReference "Preferences" */, ); productRefGroup = B658FB2D27DA9E0F00EA4DBD /* Products */; projectDirPath = ""; @@ -511,10 +532,10 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 903D6F3A27E9E8F900EC4943 /* PaneIdentifier.swift in Sources */, 2B7A583527E4BA0100D25D4E /* AppDelegate.swift in Sources */, 2875A46D27E3BE5B007805F8 /* BreadcrumbsView.swift in Sources */, 0485EB1D27E7338100138301 /* QuickOpenItem.swift in Sources */, - 04540D5B27DD08C300E91B77 /* SettingsView.swift in Sources */, D72E1A8927E44D7C00EB11B9 /* WelcomeWindowView.swift in Sources */, 04540D5C27DD08C300E91B77 /* GeneralSettingsView.swift in Sources */, B6EE989227E887C600CDD8AB /* InspectorSidebarToolbar.swift in Sources */, @@ -531,10 +552,13 @@ 287776EF27E3515300D46668 /* TabBarItem.swift in Sources */, D72E1A8727E4242900EB11B9 /* RecentProjectsView.swift in Sources */, 04660F6A27E51E5C00477777 /* CodeEditWindowController.swift in Sources */, + 90626F8827E9F2D8008926FE /* Color+Hex.swift in Sources */, 287776E727E3413200D46668 /* NavigatorSidebar.swift in Sources */, 287776ED27E350D800D46668 /* NavigatorSidebarItem.swift in Sources */, + 90626F8327E9EDA1008926FE /* ThemeSettingsView.swift in Sources */, B6EE989027E8879A00CDD8AB /* InspectorSidebar.swift in Sources */, 289978ED27E4E97E00BB0357 /* FileIconStyle.swift in Sources */, + 90626F8527E9EFE4008926FE /* Theme.swift in Sources */, 04660F6627E3ACEF00477777 /* ReopenBehavior.swift in Sources */, D72E1A8327E3B0D400EB11B9 /* WelcomeView.swift in Sources */, 043C321627E3201F006AE443 /* WorkspaceDocument.swift in Sources */, @@ -912,6 +936,14 @@ /* End XCConfigurationList section */ /* Begin XCRemoteSwiftPackageReference section */ + 903D6F3627E9E8C300EC4943 /* XCRemoteSwiftPackageReference "Preferences" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/sindresorhus/Preferences"; + requirement = { + branch = main; + kind = branch; + }; + }; B65E614427E6765D00255275 /* XCRemoteSwiftPackageReference "SwiftUI-Introspect" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/siteline/SwiftUI-Introspect"; @@ -943,6 +975,11 @@ isa = XCSwiftPackageProductDependency; productName = GitClient; }; + 903D6F3727E9E8C300EC4943 /* Preferences */ = { + isa = XCSwiftPackageProductDependency; + package = 903D6F3627E9E8C300EC4943 /* XCRemoteSwiftPackageReference "Preferences" */; + productName = Preferences; + }; B65E614527E6765D00255275 /* Introspect */ = { isa = XCSwiftPackageProductDependency; package = B65E614427E6765D00255275 /* XCRemoteSwiftPackageReference "SwiftUI-Introspect" */; diff --git a/CodeEdit.xcodeproj/xcshareddata/xcschemes/CodeEdit.xcscheme b/CodeEdit.xcodeproj/xcshareddata/xcschemes/CodeEdit.xcscheme index d92ea28491..0ca4d11bbe 100644 --- a/CodeEdit.xcodeproj/xcshareddata/xcschemes/CodeEdit.xcscheme +++ b/CodeEdit.xcodeproj/xcshareddata/xcschemes/CodeEdit.xcscheme @@ -70,6 +70,13 @@ ReferencedContainer = "container:CodeEdit.xcodeproj"> + + + + ) != nil - }).first { - window.makeKeyAndOrderFront(self) - return - } + private lazy var preferencesWindowController = PreferencesWindowController( + panes: [ + Preferences.Pane( + identifier: Preferences.PaneIdentifier.general, + title: "General", + toolbarIcon: NSImage(systemSymbolName: "gearshape", accessibilityDescription: "")!) { + GeneralSettingsView() + }, + + Preferences.Pane( + identifier: Preferences.PaneIdentifier.theme, + title: "Theme", + toolbarIcon: NSImage(systemSymbolName: "paintbrush", accessibilityDescription: "")!) { + ThemeSettingsView() + } + ] + ) - let window = NSWindow( - contentRect: NSRect(x: 0, y: 0, width: 500, height: 400), - styleMask: [.titled, .closable], - backing: .buffered, defer: false) - window.center() - window.toolbar = NSToolbar() - window.title = "Settings" - window.toolbarStyle = .unifiedCompact - _ = NSWindowController(window: window) - let contentView = SettingsView() - window.contentView = NSHostingView(rootView: contentView) - window.makeKeyAndOrderFront(sender) + @IBAction func openPreferences(_ sender: Any) { + preferencesWindowController.show() + preferencesWindowController.window?.center() } @IBAction func openWelcome(_ sender: Any) { diff --git a/CodeEdit/Assets.xcassets/AgateDisplay.imageset/CleanShot 2022-03-22 at 19.54.15@2x-1.png b/CodeEdit/Assets.xcassets/AgateDisplay.imageset/CleanShot 2022-03-22 at 19.54.15@2x-1.png new file mode 100644 index 0000000000..3a8609d4bd Binary files /dev/null and b/CodeEdit/Assets.xcassets/AgateDisplay.imageset/CleanShot 2022-03-22 at 19.54.15@2x-1.png differ diff --git a/CodeEdit/Assets.xcassets/AgateDisplay.imageset/CleanShot 2022-03-22 at 19.54.15@2x-2.png b/CodeEdit/Assets.xcassets/AgateDisplay.imageset/CleanShot 2022-03-22 at 19.54.15@2x-2.png new file mode 100644 index 0000000000..3a8609d4bd Binary files /dev/null and b/CodeEdit/Assets.xcassets/AgateDisplay.imageset/CleanShot 2022-03-22 at 19.54.15@2x-2.png differ diff --git a/CodeEdit/Assets.xcassets/AgateDisplay.imageset/CleanShot 2022-03-22 at 19.54.15@2x.png b/CodeEdit/Assets.xcassets/AgateDisplay.imageset/CleanShot 2022-03-22 at 19.54.15@2x.png new file mode 100644 index 0000000000..3a8609d4bd Binary files /dev/null and b/CodeEdit/Assets.xcassets/AgateDisplay.imageset/CleanShot 2022-03-22 at 19.54.15@2x.png differ diff --git a/CodeEdit/Assets.xcassets/AgateDisplay.imageset/Contents.json b/CodeEdit/Assets.xcassets/AgateDisplay.imageset/Contents.json new file mode 100644 index 0000000000..cbfc549ef3 --- /dev/null +++ b/CodeEdit/Assets.xcassets/AgateDisplay.imageset/Contents.json @@ -0,0 +1,26 @@ +{ + "images" : [ + { + "filename" : "CleanShot 2022-03-22 at 19.54.15@2x-1.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "CleanShot 2022-03-22 at 19.54.15@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "CleanShot 2022-03-22 at 19.54.15@2x-2.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true + } +} diff --git a/CodeEdit/Assets.xcassets/Atelier Savanna Dark Display.imageset/CleanShot 2022-03-22 at 20.13.29@2x-1.png b/CodeEdit/Assets.xcassets/Atelier Savanna Dark Display.imageset/CleanShot 2022-03-22 at 20.13.29@2x-1.png new file mode 100644 index 0000000000..89b8e6c69c Binary files /dev/null and b/CodeEdit/Assets.xcassets/Atelier Savanna Dark Display.imageset/CleanShot 2022-03-22 at 20.13.29@2x-1.png differ diff --git a/CodeEdit/Assets.xcassets/Atelier Savanna Dark Display.imageset/CleanShot 2022-03-22 at 20.13.29@2x-2.png b/CodeEdit/Assets.xcassets/Atelier Savanna Dark Display.imageset/CleanShot 2022-03-22 at 20.13.29@2x-2.png new file mode 100644 index 0000000000..89b8e6c69c Binary files /dev/null and b/CodeEdit/Assets.xcassets/Atelier Savanna Dark Display.imageset/CleanShot 2022-03-22 at 20.13.29@2x-2.png differ diff --git a/CodeEdit/Assets.xcassets/Atelier Savanna Dark Display.imageset/CleanShot 2022-03-22 at 20.13.29@2x.png b/CodeEdit/Assets.xcassets/Atelier Savanna Dark Display.imageset/CleanShot 2022-03-22 at 20.13.29@2x.png new file mode 100644 index 0000000000..89b8e6c69c Binary files /dev/null and b/CodeEdit/Assets.xcassets/Atelier Savanna Dark Display.imageset/CleanShot 2022-03-22 at 20.13.29@2x.png differ diff --git a/CodeEdit/Assets.xcassets/Atelier Savanna Dark Display.imageset/Contents.json b/CodeEdit/Assets.xcassets/Atelier Savanna Dark Display.imageset/Contents.json new file mode 100644 index 0000000000..0a21861f1c --- /dev/null +++ b/CodeEdit/Assets.xcassets/Atelier Savanna Dark Display.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "CleanShot 2022-03-22 at 20.13.29@2x-1.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "CleanShot 2022-03-22 at 20.13.29@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "CleanShot 2022-03-22 at 20.13.29@2x-2.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/CodeEdit/Assets.xcassets/Atelier Savanna Light Display.imageset/CleanShot 2022-03-22 at 20.14.11@2x-1.png b/CodeEdit/Assets.xcassets/Atelier Savanna Light Display.imageset/CleanShot 2022-03-22 at 20.14.11@2x-1.png new file mode 100644 index 0000000000..b6620e5e6b Binary files /dev/null and b/CodeEdit/Assets.xcassets/Atelier Savanna Light Display.imageset/CleanShot 2022-03-22 at 20.14.11@2x-1.png differ diff --git a/CodeEdit/Assets.xcassets/Atelier Savanna Light Display.imageset/CleanShot 2022-03-22 at 20.14.11@2x-2.png b/CodeEdit/Assets.xcassets/Atelier Savanna Light Display.imageset/CleanShot 2022-03-22 at 20.14.11@2x-2.png new file mode 100644 index 0000000000..b6620e5e6b Binary files /dev/null and b/CodeEdit/Assets.xcassets/Atelier Savanna Light Display.imageset/CleanShot 2022-03-22 at 20.14.11@2x-2.png differ diff --git a/CodeEdit/Assets.xcassets/Atelier Savanna Light Display.imageset/CleanShot 2022-03-22 at 20.14.11@2x.png b/CodeEdit/Assets.xcassets/Atelier Savanna Light Display.imageset/CleanShot 2022-03-22 at 20.14.11@2x.png new file mode 100644 index 0000000000..b6620e5e6b Binary files /dev/null and b/CodeEdit/Assets.xcassets/Atelier Savanna Light Display.imageset/CleanShot 2022-03-22 at 20.14.11@2x.png differ diff --git a/CodeEdit/Assets.xcassets/Atelier Savanna Light Display.imageset/Contents.json b/CodeEdit/Assets.xcassets/Atelier Savanna Light Display.imageset/Contents.json new file mode 100644 index 0000000000..58612a09ba --- /dev/null +++ b/CodeEdit/Assets.xcassets/Atelier Savanna Light Display.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "CleanShot 2022-03-22 at 20.14.11@2x-1.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "CleanShot 2022-03-22 at 20.14.11@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "CleanShot 2022-03-22 at 20.14.11@2x-2.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/CodeEdit/Assets.xcassets/DefaultDisplay.imageset/CleanShot 2022-03-22 at 20.12.34@2x-1.png b/CodeEdit/Assets.xcassets/DefaultDisplay.imageset/CleanShot 2022-03-22 at 20.12.34@2x-1.png new file mode 100644 index 0000000000..270591a340 Binary files /dev/null and b/CodeEdit/Assets.xcassets/DefaultDisplay.imageset/CleanShot 2022-03-22 at 20.12.34@2x-1.png differ diff --git a/CodeEdit/Assets.xcassets/DefaultDisplay.imageset/CleanShot 2022-03-22 at 20.12.34@2x-2.png b/CodeEdit/Assets.xcassets/DefaultDisplay.imageset/CleanShot 2022-03-22 at 20.12.34@2x-2.png new file mode 100644 index 0000000000..270591a340 Binary files /dev/null and b/CodeEdit/Assets.xcassets/DefaultDisplay.imageset/CleanShot 2022-03-22 at 20.12.34@2x-2.png differ diff --git a/CodeEdit/Assets.xcassets/DefaultDisplay.imageset/CleanShot 2022-03-22 at 20.12.34@2x.png b/CodeEdit/Assets.xcassets/DefaultDisplay.imageset/CleanShot 2022-03-22 at 20.12.34@2x.png new file mode 100644 index 0000000000..270591a340 Binary files /dev/null and b/CodeEdit/Assets.xcassets/DefaultDisplay.imageset/CleanShot 2022-03-22 at 20.12.34@2x.png differ diff --git a/CodeEdit/Assets.xcassets/DefaultDisplay.imageset/Contents.json b/CodeEdit/Assets.xcassets/DefaultDisplay.imageset/Contents.json new file mode 100644 index 0000000000..c8d3b4e78a --- /dev/null +++ b/CodeEdit/Assets.xcassets/DefaultDisplay.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "CleanShot 2022-03-22 at 20.12.34@2x-1.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "CleanShot 2022-03-22 at 20.12.34@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "CleanShot 2022-03-22 at 20.12.34@2x-2.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/CodeEdit/Assets.xcassets/OceanDisplay.imageset/CleanShot 2022-03-22 at 20.14.56@2x-1.png b/CodeEdit/Assets.xcassets/OceanDisplay.imageset/CleanShot 2022-03-22 at 20.14.56@2x-1.png new file mode 100644 index 0000000000..1892785c99 Binary files /dev/null and b/CodeEdit/Assets.xcassets/OceanDisplay.imageset/CleanShot 2022-03-22 at 20.14.56@2x-1.png differ diff --git a/CodeEdit/Assets.xcassets/OceanDisplay.imageset/CleanShot 2022-03-22 at 20.14.56@2x-2.png b/CodeEdit/Assets.xcassets/OceanDisplay.imageset/CleanShot 2022-03-22 at 20.14.56@2x-2.png new file mode 100644 index 0000000000..1892785c99 Binary files /dev/null and b/CodeEdit/Assets.xcassets/OceanDisplay.imageset/CleanShot 2022-03-22 at 20.14.56@2x-2.png differ diff --git a/CodeEdit/Assets.xcassets/OceanDisplay.imageset/CleanShot 2022-03-22 at 20.14.56@2x.png b/CodeEdit/Assets.xcassets/OceanDisplay.imageset/CleanShot 2022-03-22 at 20.14.56@2x.png new file mode 100644 index 0000000000..1892785c99 Binary files /dev/null and b/CodeEdit/Assets.xcassets/OceanDisplay.imageset/CleanShot 2022-03-22 at 20.14.56@2x.png differ diff --git a/CodeEdit/Assets.xcassets/OceanDisplay.imageset/Contents.json b/CodeEdit/Assets.xcassets/OceanDisplay.imageset/Contents.json new file mode 100644 index 0000000000..53747f7858 --- /dev/null +++ b/CodeEdit/Assets.xcassets/OceanDisplay.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "CleanShot 2022-03-22 at 20.14.56@2x-2.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "CleanShot 2022-03-22 at 20.14.56@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "CleanShot 2022-03-22 at 20.14.56@2x-1.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/CodeEdit/Extension/Color+Hex.swift b/CodeEdit/Extension/Color+Hex.swift new file mode 100644 index 0000000000..422efc5cfa --- /dev/null +++ b/CodeEdit/Extension/Color+Hex.swift @@ -0,0 +1,96 @@ +// +// Color+Hex.swift +// CodeEdit +// +// Created by 朱浩宇 on 2022/3/22. +// +// swiftlint:disable all + +import SwiftUI + +extension Color { + /// Creates a color from a hexadecimal color code. + /// + /// - Parameter hexadecimal: A hexadecimal representation of the color. + /// + /// - Returns: A `Color` from the given color code. Returns `nil` if the code is invalid. + public init!(hexadecimal string: String) { + var string: String = string.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines) + + if string.hasPrefix("#") { + _ = string.removeFirst() + } + + if !string.count.isMultiple(of: 2), let last = string.last { + string.append(last) + } + + if string.count > 8 { + string = String(string.prefix(8)) + } + + let scanner = Scanner(string: string) + + var color: UInt64 = 0 + + scanner.scanHexInt64(&color) + + if string.count == 2 { + let mask = 0xFF + + let g = Int(color) & mask + + let gray = Double(g) / 255.0 + + self.init(.sRGB, red: gray, green: gray, blue: gray, opacity: 1) + } else if string.count == 4 { + let mask = 0x00FF + + let g = Int(color >> 8) & mask + let a = Int(color) & mask + + let gray = Double(g) / 255.0 + let alpha = Double(a) / 255.0 + + self.init(.sRGB, red: gray, green: gray, blue: gray, opacity: alpha) + } else if string.count == 6 { + let mask = 0x0000FF + + let r = Int(color >> 16) & mask + let g = Int(color >> 8) & mask + let b = Int(color) & mask + + let red = Double(r) / 255.0 + let green = Double(g) / 255.0 + let blue = Double(b) / 255.0 + + self.init(.sRGB, red: red, green: green, blue: blue, opacity: 1) + } else if string.count == 8 { + let mask = 0x000000FF + + let r = Int(color >> 24) & mask + let g = Int(color >> 16) & mask + let b = Int(color >> 8) & mask + let a = Int(color) & mask + + let red = Double(r) / 255.0 + let green = Double(g) / 255.0 + let blue = Double(b) / 255.0 + let alpha = Double(a) / 255.0 + + self.init(.sRGB, red: red, green: green, blue: blue, opacity: alpha) + } else { + return nil + } + } + + /// Creates a color from a 6-digit hexadecimal color code. + public init(hexadecimal6: Int) { + let red = Double((hexadecimal6 & 0xFF0000) >> 16) / 255.0 + let green = Double((hexadecimal6 & 0x00FF00) >> 8) / 255.0 + let blue = Double(hexadecimal6 & 0x0000FF) / 255.0 + + self.init(red: red, green: green, blue: blue) + } +} + diff --git a/CodeEdit/Settings/GeneralSettingsView.swift b/CodeEdit/Settings/GeneralSettingsView.swift index 91d07a9f17..e52ce4fe9c 100644 --- a/CodeEdit/Settings/GeneralSettingsView.swift +++ b/CodeEdit/Settings/GeneralSettingsView.swift @@ -8,62 +8,71 @@ import SwiftUI import CodeFile import CodeEditor +import Preferences // MARK: - View struct GeneralSettingsView: View { @AppStorage(Appearances.storageKey) var appearance: Appearances = .default @AppStorage(ReopenBehavior.storageKey) var reopenBehavior: ReopenBehavior = .default - @AppStorage(FileIconStyle.storageKey) var fileIconStyle: FileIconStyle = .default - @AppStorage(CodeEditorTheme.storageKey) var editorTheme: CodeEditor.ThemeName = .atelierSavannaAuto + @AppStorage(FileIconStyle.storageKey) var fileIconStyle: FileIconStyle = .default + @AppStorage(CodeEditorTheme.storageKey) var editorTheme: CodeEditor.ThemeName = .atelierSavannaAuto + var body: some View { Form { - Picker("Appearance".localized(), selection: $appearance) { - Text("System".localized()) + Picker("Appearance".localized(), selection: $appearance) { + Text("System".localized()) .tag(Appearances.system) Divider() - Text("Light".localized()) + Text("Light".localized()) .tag(Appearances.light) - Text("Dark".localized()) + Text("Dark".localized()) .tag(Appearances.dark) } .onChange(of: appearance) { tag in tag.applyAppearance() } + .fixedSize() - Picker("File Icon Style".localized(), selection: $fileIconStyle) { - Text("Color".localized()) - .tag(FileIconStyle.color) - Text("Monochrome".localized()) - .tag(FileIconStyle.monochrome) - } + Picker("File Icon Style".localized(), selection: $fileIconStyle) { + Text("Color".localized()) + .tag(FileIconStyle.color) + Text("Monochrome".localized()) + .tag(FileIconStyle.monochrome) + } + .fixedSize() - Picker("Reopen Behavior".localized(), selection: $reopenBehavior) { + Picker("Reopen Behavior".localized(), selection: $reopenBehavior) { Text("Welcome Screen".localized()) .tag(ReopenBehavior.welcome) Divider() - Text("Open Panel".localized()) + Text("Open Panel".localized()) .tag(ReopenBehavior.openPanel) - Text("New Document".localized()) + Text("New Document".localized()) .tag(ReopenBehavior.newDocument) } + .fixedSize() - Picker("Editor Theme".localized(), selection: $editorTheme) { - Text("Atelier Savanna (Auto)") - .tag(CodeEditor.ThemeName.atelierSavannaAuto) - Text("Atelier Savanna Dark") - .tag(CodeEditor.ThemeName.atelierSavannaDark) - Text("Atelier Savanna Light") - .tag(CodeEditor.ThemeName.atelierSavannaLight) - // TODO: Pojoaque does not seem to work (does not change from previous selection) -// Text("Pojoaque") -// .tag(CodeEditor.ThemeName.pojoaque) - Text("Agate") - .tag(CodeEditor.ThemeName.agate) - Text("Ocean") - .tag(CodeEditor.ThemeName.ocean) - } + Picker("Editor Theme".localized(), selection: $editorTheme) { + Text("pojoaque") + .tag(CodeEditor.ThemeName.default) + Text("Atelier Savanna (Auto)") + .tag(CodeEditor.ThemeName.atelierSavannaAuto) + Text("Atelier Savanna Dark") + .tag(CodeEditor.ThemeName.atelierSavannaDark) + Text("Atelier Savanna Light") + .tag(CodeEditor.ThemeName.atelierSavannaLight) + // TODO: Pojoaque does not seem to work (does not change from previous selection) + // Text("Pojoaque") + // .tag(CodeEditor.ThemeName.pojoaque) + Text("Agate") + .tag(CodeEditor.ThemeName.agate) + Text("Ocean") + .tag(CodeEditor.ThemeName.ocean) + } + .fixedSize() } + .frame(width: 500) .padding() } } diff --git a/CodeEdit/Settings/Models/PaneIdentifier.swift b/CodeEdit/Settings/Models/PaneIdentifier.swift new file mode 100644 index 0000000000..f7c4e5af93 --- /dev/null +++ b/CodeEdit/Settings/Models/PaneIdentifier.swift @@ -0,0 +1,13 @@ +// +// PaneIdentifier.swift +// CodeEdit +// +// Created by 朱浩宇 on 2022/3/22. +// + +import Preferences + +extension Preferences.PaneIdentifier { + static let general = Self("general") + static let theme = Self("theme") +} diff --git a/CodeEdit/Settings/Models/Theme.swift b/CodeEdit/Settings/Models/Theme.swift new file mode 100644 index 0000000000..3a58a42787 --- /dev/null +++ b/CodeEdit/Settings/Models/Theme.swift @@ -0,0 +1,42 @@ +// +// Theme.swift +// CodeEdit +// +// Created by 朱浩宇 on 2022/3/22. +// + +import Foundation +import CodeEditor +import SwiftUI + +/// This is struct for ThemeSettingView +struct Theme: Identifiable { + static let all: [Self] = [ + .init(name: "Default", theme: .default, image: Image("AgateDisplay")), + .init(name: "Atelier Savanna Auto", theme: .atelierSavannaAuto, image: Self.getAtelierSavannaAutoImage()), + .init(name: "Atelier Savanna Dark", theme: .atelierSavannaDark, image: Image("Atelier Savanna Dark Display")), + .init(name: "Atelier Savanna Light", theme: .atelierSavannaLight, + image: Image("Atelier Savanna Light Display")), + .init(name: "Agate", theme: .agate, image: Image("AgateDisplay")), + .init(name: "Ocean", theme: .ocean, image: Image("OceanDisplay")) + ] + + let id = UUID() + let name: String + let theme: CodeEditor.ThemeName + + /// 550 * 350 + let image: Image + + private static func getAtelierSavannaAutoImage() -> Image { + if NSApp.effectiveAppearance.bestMatch(from: [.darkAqua, .aqua]) == .darkAqua { + return Image("Atelier Savanna Dark Display") + } else { + return Image("Atelier Savanna Light Display") + } + } + + func selected(_ theme: CodeEditor.ThemeName) -> Bool { + self.theme == theme + } +} diff --git a/CodeEdit/Settings/SettingsView.swift b/CodeEdit/Settings/SettingsView.swift deleted file mode 100644 index 6549f479a9..0000000000 --- a/CodeEdit/Settings/SettingsView.swift +++ /dev/null @@ -1,27 +0,0 @@ -// -// SettingsView.swift -// CodeEdit -// -// Created by Pavel Kasila on 11.03.22. -// - -import SwiftUI - -struct SettingsView: View { - var body: some View { - TabView { - GeneralSettingsView() - .tabItem { - Label("General".localized(), systemImage: "gearshape") - } - } - .padding() - .frame(width: 450, height: 250) - } -} - -struct SettingsView_Previews: PreviewProvider { - static var previews: some View { - SettingsView() - } -} diff --git a/CodeEdit/Settings/ThemeSettingsView.swift b/CodeEdit/Settings/ThemeSettingsView.swift new file mode 100644 index 0000000000..346710ef7b --- /dev/null +++ b/CodeEdit/Settings/ThemeSettingsView.swift @@ -0,0 +1,62 @@ +// +// ThemeSettingsView.swift +// CodeEdit +// +// Created by 朱浩宇 on 2022/3/22. +// + +import SwiftUI +import CodeEditor +import CodeFile + +struct ThemeSettingsView: View { + @AppStorage(CodeEditorTheme.storageKey) var editorTheme: CodeEditor.ThemeName = .atelierSavannaAuto + + let gridRule = [GridItem](repeating: GridItem(.flexible(), alignment: .top), count: 4) + + var body: some View { + LazyVGrid(columns: gridRule) { + ForEach(Theme.all) { themeItem in + VStack { + VStack { + themeItem.image + .resizable() + .frame(width: 116, height: 62) + .scaledToFit() + .border(Color(hexadecimal: "737373"), width: 1.5) + .cornerRadius(3) + + Text(themeItem.name) + .font(.system(size: 12)) + .multilineTextAlignment(.center) + } + .padding(5) + .background(BackGroundView(seelected: themeItem.selected(editorTheme))) + } + .frame(width: 120) + .padding() + } + } + .frame(width: 650) + .padding() + } + + struct BackGroundView: View { + let seelected: Bool + + var body: some View { + if seelected { +// Color(hexadecimal: "464546").cornerRadius(4) + Color(hexadecimal: "0158D0").cornerRadius(5) + } else { + Color.clear + } + } + } +} + +struct ThemeSettingsView_Previews: PreviewProvider { + static var previews: some View { + ThemeSettingsView() + } +}