diff --git a/.github/CodeEdit-Icon-128@2x.png b/.github/CodeEdit-Icon-128@2x.png index 95772ab3f7..9796c87e9b 100644 Binary files a/.github/CodeEdit-Icon-128@2x.png and b/.github/CodeEdit-Icon-128@2x.png differ diff --git a/CodeEdit.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/CodeEdit.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 835319d36b..b15a52165e 100644 --- a/CodeEdit.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/CodeEdit.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -6,8 +6,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/CodeEditApp/AboutWindow", "state" : { - "revision" : "79c7c01fb739d024a3ca07fe153a068339213baf", - "version" : "1.0.0" + "revision" : "bdec18efb0dbee79613e7efa446ed3cc8e834842", + "version" : "1.0.1" } }, { @@ -303,8 +303,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/weichsel/ZIPFoundation", "state" : { - "revision" : "02b6abe5f6eef7e3cbd5f247c5cc24e246efcfe0", - "version" : "0.9.19" + "revision" : "22787ffb59de99e5dc1fbfe80b19c97a904ad48d", + "version" : "0.9.20" } } ], diff --git a/CodeEdit/Assets.xcassets/AppIcon.appiconset/CodeEdit-128.png b/CodeEdit/Assets.xcassets/AppIcon.appiconset/CodeEdit-128.png deleted file mode 100644 index 4c69ead7a1..0000000000 Binary files a/CodeEdit/Assets.xcassets/AppIcon.appiconset/CodeEdit-128.png and /dev/null differ diff --git a/CodeEdit/Assets.xcassets/AppIcon.appiconset/CodeEdit-128@2x.png b/CodeEdit/Assets.xcassets/AppIcon.appiconset/CodeEdit-128@2x.png deleted file mode 100644 index e78ea78b1b..0000000000 Binary files a/CodeEdit/Assets.xcassets/AppIcon.appiconset/CodeEdit-128@2x.png and /dev/null differ diff --git a/CodeEdit/Assets.xcassets/AppIcon.appiconset/CodeEdit-16.png b/CodeEdit/Assets.xcassets/AppIcon.appiconset/CodeEdit-16.png deleted file mode 100644 index d23a61d962..0000000000 Binary files a/CodeEdit/Assets.xcassets/AppIcon.appiconset/CodeEdit-16.png and /dev/null differ diff --git a/CodeEdit/Assets.xcassets/AppIcon.appiconset/CodeEdit-16@2x.png b/CodeEdit/Assets.xcassets/AppIcon.appiconset/CodeEdit-16@2x.png deleted file mode 100644 index 2ce0bf5211..0000000000 Binary files a/CodeEdit/Assets.xcassets/AppIcon.appiconset/CodeEdit-16@2x.png and /dev/null differ diff --git a/CodeEdit/Assets.xcassets/AppIcon.appiconset/CodeEdit-256.png b/CodeEdit/Assets.xcassets/AppIcon.appiconset/CodeEdit-256.png deleted file mode 100644 index e78ea78b1b..0000000000 Binary files a/CodeEdit/Assets.xcassets/AppIcon.appiconset/CodeEdit-256.png and /dev/null differ diff --git a/CodeEdit/Assets.xcassets/AppIcon.appiconset/CodeEdit-256@2x.png b/CodeEdit/Assets.xcassets/AppIcon.appiconset/CodeEdit-256@2x.png deleted file mode 100644 index 91bdce3fed..0000000000 Binary files a/CodeEdit/Assets.xcassets/AppIcon.appiconset/CodeEdit-256@2x.png and /dev/null differ diff --git a/CodeEdit/Assets.xcassets/AppIcon.appiconset/CodeEdit-32.png b/CodeEdit/Assets.xcassets/AppIcon.appiconset/CodeEdit-32.png deleted file mode 100644 index 2ce0bf5211..0000000000 Binary files a/CodeEdit/Assets.xcassets/AppIcon.appiconset/CodeEdit-32.png and /dev/null differ diff --git a/CodeEdit/Assets.xcassets/AppIcon.appiconset/CodeEdit-32@2x.png b/CodeEdit/Assets.xcassets/AppIcon.appiconset/CodeEdit-32@2x.png deleted file mode 100644 index 9027597b72..0000000000 Binary files a/CodeEdit/Assets.xcassets/AppIcon.appiconset/CodeEdit-32@2x.png and /dev/null differ diff --git a/CodeEdit/Assets.xcassets/AppIcon.appiconset/CodeEdit-512.png b/CodeEdit/Assets.xcassets/AppIcon.appiconset/CodeEdit-512.png deleted file mode 100644 index 91bdce3fed..0000000000 Binary files a/CodeEdit/Assets.xcassets/AppIcon.appiconset/CodeEdit-512.png and /dev/null differ diff --git a/CodeEdit/Assets.xcassets/AppIcon.appiconset/CodeEdit-512@2x.png b/CodeEdit/Assets.xcassets/AppIcon.appiconset/CodeEdit-512@2x.png deleted file mode 100644 index 5d18de1a44..0000000000 Binary files a/CodeEdit/Assets.xcassets/AppIcon.appiconset/CodeEdit-512@2x.png and /dev/null differ diff --git a/CodeEdit/Assets.xcassets/AppIcon.appiconset/Contents.json b/CodeEdit/Assets.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index 18bc321400..0000000000 --- a/CodeEdit/Assets.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "images" : [ - { - "filename" : "CodeEdit-16.png", - "idiom" : "mac", - "scale" : "1x", - "size" : "16x16" - }, - { - "filename" : "CodeEdit-16@2x.png", - "idiom" : "mac", - "scale" : "2x", - "size" : "16x16" - }, - { - "filename" : "CodeEdit-32.png", - "idiom" : "mac", - "scale" : "1x", - "size" : "32x32" - }, - { - "filename" : "CodeEdit-32@2x.png", - "idiom" : "mac", - "scale" : "2x", - "size" : "32x32" - }, - { - "filename" : "CodeEdit-128.png", - "idiom" : "mac", - "scale" : "1x", - "size" : "128x128" - }, - { - "filename" : "CodeEdit-128@2x.png", - "idiom" : "mac", - "scale" : "2x", - "size" : "128x128" - }, - { - "filename" : "CodeEdit-256.png", - "idiom" : "mac", - "scale" : "1x", - "size" : "256x256" - }, - { - "filename" : "CodeEdit-256@2x.png", - "idiom" : "mac", - "scale" : "2x", - "size" : "256x256" - }, - { - "filename" : "CodeEdit-512.png", - "idiom" : "mac", - "scale" : "1x", - "size" : "512x512" - }, - { - "filename" : "CodeEdit-512@2x.png", - "idiom" : "mac", - "scale" : "2x", - "size" : "512x512" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/CodeEdit/Assets.xcassets/AppIconAlpha.appiconset/CodeEditAlpha-128.png b/CodeEdit/Assets.xcassets/AppIconAlpha.appiconset/CodeEditAlpha-128.png deleted file mode 100644 index 812832f498..0000000000 Binary files a/CodeEdit/Assets.xcassets/AppIconAlpha.appiconset/CodeEditAlpha-128.png and /dev/null differ diff --git a/CodeEdit/Assets.xcassets/AppIconAlpha.appiconset/CodeEditAlpha-128@2x.png b/CodeEdit/Assets.xcassets/AppIconAlpha.appiconset/CodeEditAlpha-128@2x.png deleted file mode 100644 index 2b6b45a513..0000000000 Binary files a/CodeEdit/Assets.xcassets/AppIconAlpha.appiconset/CodeEditAlpha-128@2x.png and /dev/null differ diff --git a/CodeEdit/Assets.xcassets/AppIconAlpha.appiconset/CodeEditAlpha-16.png b/CodeEdit/Assets.xcassets/AppIconAlpha.appiconset/CodeEditAlpha-16.png deleted file mode 100644 index 83a63192a6..0000000000 Binary files a/CodeEdit/Assets.xcassets/AppIconAlpha.appiconset/CodeEditAlpha-16.png and /dev/null differ diff --git a/CodeEdit/Assets.xcassets/AppIconAlpha.appiconset/CodeEditAlpha-16@2x.png b/CodeEdit/Assets.xcassets/AppIconAlpha.appiconset/CodeEditAlpha-16@2x.png deleted file mode 100644 index 266fa0e318..0000000000 Binary files a/CodeEdit/Assets.xcassets/AppIconAlpha.appiconset/CodeEditAlpha-16@2x.png and /dev/null differ diff --git a/CodeEdit/Assets.xcassets/AppIconAlpha.appiconset/CodeEditAlpha-256.png b/CodeEdit/Assets.xcassets/AppIconAlpha.appiconset/CodeEditAlpha-256.png deleted file mode 100644 index 2b6b45a513..0000000000 Binary files a/CodeEdit/Assets.xcassets/AppIconAlpha.appiconset/CodeEditAlpha-256.png and /dev/null differ diff --git a/CodeEdit/Assets.xcassets/AppIconAlpha.appiconset/CodeEditAlpha-256@2x.png b/CodeEdit/Assets.xcassets/AppIconAlpha.appiconset/CodeEditAlpha-256@2x.png deleted file mode 100644 index ee3f55bc73..0000000000 Binary files a/CodeEdit/Assets.xcassets/AppIconAlpha.appiconset/CodeEditAlpha-256@2x.png and /dev/null differ diff --git a/CodeEdit/Assets.xcassets/AppIconAlpha.appiconset/CodeEditAlpha-32.png b/CodeEdit/Assets.xcassets/AppIconAlpha.appiconset/CodeEditAlpha-32.png deleted file mode 100644 index 266fa0e318..0000000000 Binary files a/CodeEdit/Assets.xcassets/AppIconAlpha.appiconset/CodeEditAlpha-32.png and /dev/null differ diff --git a/CodeEdit/Assets.xcassets/AppIconAlpha.appiconset/CodeEditAlpha-32@2x.png b/CodeEdit/Assets.xcassets/AppIconAlpha.appiconset/CodeEditAlpha-32@2x.png deleted file mode 100644 index d412913e7e..0000000000 Binary files a/CodeEdit/Assets.xcassets/AppIconAlpha.appiconset/CodeEditAlpha-32@2x.png and /dev/null differ diff --git a/CodeEdit/Assets.xcassets/AppIconAlpha.appiconset/CodeEditAlpha-512.png b/CodeEdit/Assets.xcassets/AppIconAlpha.appiconset/CodeEditAlpha-512.png deleted file mode 100644 index ee3f55bc73..0000000000 Binary files a/CodeEdit/Assets.xcassets/AppIconAlpha.appiconset/CodeEditAlpha-512.png and /dev/null differ diff --git a/CodeEdit/Assets.xcassets/AppIconAlpha.appiconset/CodeEditAlpha-512@2x.png b/CodeEdit/Assets.xcassets/AppIconAlpha.appiconset/CodeEditAlpha-512@2x.png deleted file mode 100644 index ce1001aa08..0000000000 Binary files a/CodeEdit/Assets.xcassets/AppIconAlpha.appiconset/CodeEditAlpha-512@2x.png and /dev/null differ diff --git a/CodeEdit/Assets.xcassets/AppIconAlpha.appiconset/Contents.json b/CodeEdit/Assets.xcassets/AppIconAlpha.appiconset/Contents.json deleted file mode 100644 index f54f9dfd4d..0000000000 --- a/CodeEdit/Assets.xcassets/AppIconAlpha.appiconset/Contents.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "images" : [ - { - "filename" : "CodeEditAlpha-16.png", - "idiom" : "mac", - "scale" : "1x", - "size" : "16x16" - }, - { - "filename" : "CodeEditAlpha-16@2x.png", - "idiom" : "mac", - "scale" : "2x", - "size" : "16x16" - }, - { - "filename" : "CodeEditAlpha-32.png", - "idiom" : "mac", - "scale" : "1x", - "size" : "32x32" - }, - { - "filename" : "CodeEditAlpha-32@2x.png", - "idiom" : "mac", - "scale" : "2x", - "size" : "32x32" - }, - { - "filename" : "CodeEditAlpha-128.png", - "idiom" : "mac", - "scale" : "1x", - "size" : "128x128" - }, - { - "filename" : "CodeEditAlpha-128@2x.png", - "idiom" : "mac", - "scale" : "2x", - "size" : "128x128" - }, - { - "filename" : "CodeEditAlpha-256.png", - "idiom" : "mac", - "scale" : "1x", - "size" : "256x256" - }, - { - "filename" : "CodeEditAlpha-256@2x.png", - "idiom" : "mac", - "scale" : "2x", - "size" : "256x256" - }, - { - "filename" : "CodeEditAlpha-512.png", - "idiom" : "mac", - "scale" : "1x", - "size" : "512x512" - }, - { - "filename" : "CodeEditAlpha-512@2x.png", - "idiom" : "mac", - "scale" : "2x", - "size" : "512x512" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/CodeEdit/Assets.xcassets/AppIconBeta.appiconset/CodeEditBeta-128.png b/CodeEdit/Assets.xcassets/AppIconBeta.appiconset/CodeEditBeta-128.png deleted file mode 100644 index 7b8747c84a..0000000000 Binary files a/CodeEdit/Assets.xcassets/AppIconBeta.appiconset/CodeEditBeta-128.png and /dev/null differ diff --git a/CodeEdit/Assets.xcassets/AppIconBeta.appiconset/CodeEditBeta-128@2x.png b/CodeEdit/Assets.xcassets/AppIconBeta.appiconset/CodeEditBeta-128@2x.png deleted file mode 100644 index 1ec376cdba..0000000000 Binary files a/CodeEdit/Assets.xcassets/AppIconBeta.appiconset/CodeEditBeta-128@2x.png and /dev/null differ diff --git a/CodeEdit/Assets.xcassets/AppIconBeta.appiconset/CodeEditBeta-16.png b/CodeEdit/Assets.xcassets/AppIconBeta.appiconset/CodeEditBeta-16.png deleted file mode 100644 index 76aeaa9787..0000000000 Binary files a/CodeEdit/Assets.xcassets/AppIconBeta.appiconset/CodeEditBeta-16.png and /dev/null differ diff --git a/CodeEdit/Assets.xcassets/AppIconBeta.appiconset/CodeEditBeta-16@2x.png b/CodeEdit/Assets.xcassets/AppIconBeta.appiconset/CodeEditBeta-16@2x.png deleted file mode 100644 index 39bd0f90c4..0000000000 Binary files a/CodeEdit/Assets.xcassets/AppIconBeta.appiconset/CodeEditBeta-16@2x.png and /dev/null differ diff --git a/CodeEdit/Assets.xcassets/AppIconBeta.appiconset/CodeEditBeta-256.png b/CodeEdit/Assets.xcassets/AppIconBeta.appiconset/CodeEditBeta-256.png deleted file mode 100644 index 1ec376cdba..0000000000 Binary files a/CodeEdit/Assets.xcassets/AppIconBeta.appiconset/CodeEditBeta-256.png and /dev/null differ diff --git a/CodeEdit/Assets.xcassets/AppIconBeta.appiconset/CodeEditBeta-256@2x.png b/CodeEdit/Assets.xcassets/AppIconBeta.appiconset/CodeEditBeta-256@2x.png deleted file mode 100644 index 120468c6e0..0000000000 Binary files a/CodeEdit/Assets.xcassets/AppIconBeta.appiconset/CodeEditBeta-256@2x.png and /dev/null differ diff --git a/CodeEdit/Assets.xcassets/AppIconBeta.appiconset/CodeEditBeta-32.png b/CodeEdit/Assets.xcassets/AppIconBeta.appiconset/CodeEditBeta-32.png deleted file mode 100644 index 39bd0f90c4..0000000000 Binary files a/CodeEdit/Assets.xcassets/AppIconBeta.appiconset/CodeEditBeta-32.png and /dev/null differ diff --git a/CodeEdit/Assets.xcassets/AppIconBeta.appiconset/CodeEditBeta-32@2x.png b/CodeEdit/Assets.xcassets/AppIconBeta.appiconset/CodeEditBeta-32@2x.png deleted file mode 100644 index ac8e96057a..0000000000 Binary files a/CodeEdit/Assets.xcassets/AppIconBeta.appiconset/CodeEditBeta-32@2x.png and /dev/null differ diff --git a/CodeEdit/Assets.xcassets/AppIconBeta.appiconset/CodeEditBeta-512.png b/CodeEdit/Assets.xcassets/AppIconBeta.appiconset/CodeEditBeta-512.png deleted file mode 100644 index 120468c6e0..0000000000 Binary files a/CodeEdit/Assets.xcassets/AppIconBeta.appiconset/CodeEditBeta-512.png and /dev/null differ diff --git a/CodeEdit/Assets.xcassets/AppIconBeta.appiconset/CodeEditBeta-512@2x.png b/CodeEdit/Assets.xcassets/AppIconBeta.appiconset/CodeEditBeta-512@2x.png deleted file mode 100644 index 0ed66aea8f..0000000000 Binary files a/CodeEdit/Assets.xcassets/AppIconBeta.appiconset/CodeEditBeta-512@2x.png and /dev/null differ diff --git a/CodeEdit/Assets.xcassets/AppIconBeta.appiconset/Contents.json b/CodeEdit/Assets.xcassets/AppIconBeta.appiconset/Contents.json deleted file mode 100644 index cae4ff40a8..0000000000 --- a/CodeEdit/Assets.xcassets/AppIconBeta.appiconset/Contents.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "images" : [ - { - "filename" : "CodeEditBeta-16.png", - "idiom" : "mac", - "scale" : "1x", - "size" : "16x16" - }, - { - "filename" : "CodeEditBeta-16@2x.png", - "idiom" : "mac", - "scale" : "2x", - "size" : "16x16" - }, - { - "filename" : "CodeEditBeta-32.png", - "idiom" : "mac", - "scale" : "1x", - "size" : "32x32" - }, - { - "filename" : "CodeEditBeta-32@2x.png", - "idiom" : "mac", - "scale" : "2x", - "size" : "32x32" - }, - { - "filename" : "CodeEditBeta-128.png", - "idiom" : "mac", - "scale" : "1x", - "size" : "128x128" - }, - { - "filename" : "CodeEditBeta-128@2x.png", - "idiom" : "mac", - "scale" : "2x", - "size" : "128x128" - }, - { - "filename" : "CodeEditBeta-256.png", - "idiom" : "mac", - "scale" : "1x", - "size" : "256x256" - }, - { - "filename" : "CodeEditBeta-256@2x.png", - "idiom" : "mac", - "scale" : "2x", - "size" : "256x256" - }, - { - "filename" : "CodeEditBeta-512.png", - "idiom" : "mac", - "scale" : "1x", - "size" : "512x512" - }, - { - "filename" : "CodeEditBeta-512@2x.png", - "idiom" : "mac", - "scale" : "2x", - "size" : "512x512" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/CodeEdit/Assets.xcassets/AppIconDev.appiconset/CodeEditDev-128.png b/CodeEdit/Assets.xcassets/AppIconDev.appiconset/CodeEditDev-128.png deleted file mode 100644 index 01a28fb9e3..0000000000 Binary files a/CodeEdit/Assets.xcassets/AppIconDev.appiconset/CodeEditDev-128.png and /dev/null differ diff --git a/CodeEdit/Assets.xcassets/AppIconDev.appiconset/CodeEditDev-128@2x.png b/CodeEdit/Assets.xcassets/AppIconDev.appiconset/CodeEditDev-128@2x.png deleted file mode 100644 index 068655135c..0000000000 Binary files a/CodeEdit/Assets.xcassets/AppIconDev.appiconset/CodeEditDev-128@2x.png and /dev/null differ diff --git a/CodeEdit/Assets.xcassets/AppIconDev.appiconset/CodeEditDev-16.png b/CodeEdit/Assets.xcassets/AppIconDev.appiconset/CodeEditDev-16.png deleted file mode 100644 index eeeb98ee56..0000000000 Binary files a/CodeEdit/Assets.xcassets/AppIconDev.appiconset/CodeEditDev-16.png and /dev/null differ diff --git a/CodeEdit/Assets.xcassets/AppIconDev.appiconset/CodeEditDev-16@2x.png b/CodeEdit/Assets.xcassets/AppIconDev.appiconset/CodeEditDev-16@2x.png deleted file mode 100644 index ba568a9e10..0000000000 Binary files a/CodeEdit/Assets.xcassets/AppIconDev.appiconset/CodeEditDev-16@2x.png and /dev/null differ diff --git a/CodeEdit/Assets.xcassets/AppIconDev.appiconset/CodeEditDev-256.png b/CodeEdit/Assets.xcassets/AppIconDev.appiconset/CodeEditDev-256.png deleted file mode 100644 index 068655135c..0000000000 Binary files a/CodeEdit/Assets.xcassets/AppIconDev.appiconset/CodeEditDev-256.png and /dev/null differ diff --git a/CodeEdit/Assets.xcassets/AppIconDev.appiconset/CodeEditDev-256@2x.png b/CodeEdit/Assets.xcassets/AppIconDev.appiconset/CodeEditDev-256@2x.png deleted file mode 100644 index 795f855196..0000000000 Binary files a/CodeEdit/Assets.xcassets/AppIconDev.appiconset/CodeEditDev-256@2x.png and /dev/null differ diff --git a/CodeEdit/Assets.xcassets/AppIconDev.appiconset/CodeEditDev-32.png b/CodeEdit/Assets.xcassets/AppIconDev.appiconset/CodeEditDev-32.png deleted file mode 100644 index ba568a9e10..0000000000 Binary files a/CodeEdit/Assets.xcassets/AppIconDev.appiconset/CodeEditDev-32.png and /dev/null differ diff --git a/CodeEdit/Assets.xcassets/AppIconDev.appiconset/CodeEditDev-32@2x.png b/CodeEdit/Assets.xcassets/AppIconDev.appiconset/CodeEditDev-32@2x.png deleted file mode 100644 index 6aad5bd5db..0000000000 Binary files a/CodeEdit/Assets.xcassets/AppIconDev.appiconset/CodeEditDev-32@2x.png and /dev/null differ diff --git a/CodeEdit/Assets.xcassets/AppIconDev.appiconset/CodeEditDev-512.png b/CodeEdit/Assets.xcassets/AppIconDev.appiconset/CodeEditDev-512.png deleted file mode 100644 index 795f855196..0000000000 Binary files a/CodeEdit/Assets.xcassets/AppIconDev.appiconset/CodeEditDev-512.png and /dev/null differ diff --git a/CodeEdit/Assets.xcassets/AppIconDev.appiconset/CodeEditDev-512@2x.png b/CodeEdit/Assets.xcassets/AppIconDev.appiconset/CodeEditDev-512@2x.png deleted file mode 100644 index 91876ab95b..0000000000 Binary files a/CodeEdit/Assets.xcassets/AppIconDev.appiconset/CodeEditDev-512@2x.png and /dev/null differ diff --git a/CodeEdit/Assets.xcassets/AppIconDev.appiconset/Contents.json b/CodeEdit/Assets.xcassets/AppIconDev.appiconset/Contents.json deleted file mode 100644 index 415f697895..0000000000 --- a/CodeEdit/Assets.xcassets/AppIconDev.appiconset/Contents.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "images" : [ - { - "filename" : "CodeEditDev-16.png", - "idiom" : "mac", - "scale" : "1x", - "size" : "16x16" - }, - { - "filename" : "CodeEditDev-16@2x.png", - "idiom" : "mac", - "scale" : "2x", - "size" : "16x16" - }, - { - "filename" : "CodeEditDev-32.png", - "idiom" : "mac", - "scale" : "1x", - "size" : "32x32" - }, - { - "filename" : "CodeEditDev-32@2x.png", - "idiom" : "mac", - "scale" : "2x", - "size" : "32x32" - }, - { - "filename" : "CodeEditDev-128.png", - "idiom" : "mac", - "scale" : "1x", - "size" : "128x128" - }, - { - "filename" : "CodeEditDev-128@2x.png", - "idiom" : "mac", - "scale" : "2x", - "size" : "128x128" - }, - { - "filename" : "CodeEditDev-256.png", - "idiom" : "mac", - "scale" : "1x", - "size" : "256x256" - }, - { - "filename" : "CodeEditDev-256@2x.png", - "idiom" : "mac", - "scale" : "2x", - "size" : "256x256" - }, - { - "filename" : "CodeEditDev-512.png", - "idiom" : "mac", - "scale" : "1x", - "size" : "512x512" - }, - { - "filename" : "CodeEditDev-512@2x.png", - "idiom" : "mac", - "scale" : "2x", - "size" : "512x512" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/CodeEdit/Assets.xcassets/AppIconPre.appiconset/CodeEdit-Icon-Pre-128.png b/CodeEdit/Assets.xcassets/AppIconPre.appiconset/CodeEdit-Icon-Pre-128.png deleted file mode 100644 index cd5d5202d4..0000000000 Binary files a/CodeEdit/Assets.xcassets/AppIconPre.appiconset/CodeEdit-Icon-Pre-128.png and /dev/null differ diff --git a/CodeEdit/Assets.xcassets/AppIconPre.appiconset/CodeEdit-Icon-Pre-128@2x.png b/CodeEdit/Assets.xcassets/AppIconPre.appiconset/CodeEdit-Icon-Pre-128@2x.png deleted file mode 100644 index cb8456c1b8..0000000000 Binary files a/CodeEdit/Assets.xcassets/AppIconPre.appiconset/CodeEdit-Icon-Pre-128@2x.png and /dev/null differ diff --git a/CodeEdit/Assets.xcassets/AppIconPre.appiconset/CodeEdit-Icon-Pre-16.png b/CodeEdit/Assets.xcassets/AppIconPre.appiconset/CodeEdit-Icon-Pre-16.png deleted file mode 100644 index d77f0f1ac6..0000000000 Binary files a/CodeEdit/Assets.xcassets/AppIconPre.appiconset/CodeEdit-Icon-Pre-16.png and /dev/null differ diff --git a/CodeEdit/Assets.xcassets/AppIconPre.appiconset/CodeEdit-Icon-Pre-16@2x.png b/CodeEdit/Assets.xcassets/AppIconPre.appiconset/CodeEdit-Icon-Pre-16@2x.png deleted file mode 100644 index 92f306c939..0000000000 Binary files a/CodeEdit/Assets.xcassets/AppIconPre.appiconset/CodeEdit-Icon-Pre-16@2x.png and /dev/null differ diff --git a/CodeEdit/Assets.xcassets/AppIconPre.appiconset/CodeEdit-Icon-Pre-256.png b/CodeEdit/Assets.xcassets/AppIconPre.appiconset/CodeEdit-Icon-Pre-256.png deleted file mode 100644 index cb8456c1b8..0000000000 Binary files a/CodeEdit/Assets.xcassets/AppIconPre.appiconset/CodeEdit-Icon-Pre-256.png and /dev/null differ diff --git a/CodeEdit/Assets.xcassets/AppIconPre.appiconset/CodeEdit-Icon-Pre-256@2x.png b/CodeEdit/Assets.xcassets/AppIconPre.appiconset/CodeEdit-Icon-Pre-256@2x.png deleted file mode 100644 index 2e0dcce847..0000000000 Binary files a/CodeEdit/Assets.xcassets/AppIconPre.appiconset/CodeEdit-Icon-Pre-256@2x.png and /dev/null differ diff --git a/CodeEdit/Assets.xcassets/AppIconPre.appiconset/CodeEdit-Icon-Pre-32.png b/CodeEdit/Assets.xcassets/AppIconPre.appiconset/CodeEdit-Icon-Pre-32.png deleted file mode 100644 index 92f306c939..0000000000 Binary files a/CodeEdit/Assets.xcassets/AppIconPre.appiconset/CodeEdit-Icon-Pre-32.png and /dev/null differ diff --git a/CodeEdit/Assets.xcassets/AppIconPre.appiconset/CodeEdit-Icon-Pre-32@2x.png b/CodeEdit/Assets.xcassets/AppIconPre.appiconset/CodeEdit-Icon-Pre-32@2x.png deleted file mode 100644 index 503035158c..0000000000 Binary files a/CodeEdit/Assets.xcassets/AppIconPre.appiconset/CodeEdit-Icon-Pre-32@2x.png and /dev/null differ diff --git a/CodeEdit/Assets.xcassets/AppIconPre.appiconset/CodeEdit-Icon-Pre-512.png b/CodeEdit/Assets.xcassets/AppIconPre.appiconset/CodeEdit-Icon-Pre-512.png deleted file mode 100644 index 2e0dcce847..0000000000 Binary files a/CodeEdit/Assets.xcassets/AppIconPre.appiconset/CodeEdit-Icon-Pre-512.png and /dev/null differ diff --git a/CodeEdit/Assets.xcassets/AppIconPre.appiconset/CodeEdit-Icon-Pre-512@2x.png b/CodeEdit/Assets.xcassets/AppIconPre.appiconset/CodeEdit-Icon-Pre-512@2x.png deleted file mode 100644 index 798847c486..0000000000 Binary files a/CodeEdit/Assets.xcassets/AppIconPre.appiconset/CodeEdit-Icon-Pre-512@2x.png and /dev/null differ diff --git a/CodeEdit/Assets.xcassets/AppIconPre.appiconset/Contents.json b/CodeEdit/Assets.xcassets/AppIconPre.appiconset/Contents.json deleted file mode 100644 index a1f7a30968..0000000000 --- a/CodeEdit/Assets.xcassets/AppIconPre.appiconset/Contents.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "images" : [ - { - "filename" : "CodeEdit-Icon-Pre-16.png", - "idiom" : "mac", - "scale" : "1x", - "size" : "16x16" - }, - { - "filename" : "CodeEdit-Icon-Pre-16@2x.png", - "idiom" : "mac", - "scale" : "2x", - "size" : "16x16" - }, - { - "filename" : "CodeEdit-Icon-Pre-32.png", - "idiom" : "mac", - "scale" : "1x", - "size" : "32x32" - }, - { - "filename" : "CodeEdit-Icon-Pre-32@2x.png", - "idiom" : "mac", - "scale" : "2x", - "size" : "32x32" - }, - { - "filename" : "CodeEdit-Icon-Pre-128.png", - "idiom" : "mac", - "scale" : "1x", - "size" : "128x128" - }, - { - "filename" : "CodeEdit-Icon-Pre-128@2x.png", - "idiom" : "mac", - "scale" : "2x", - "size" : "128x128" - }, - { - "filename" : "CodeEdit-Icon-Pre-256.png", - "idiom" : "mac", - "scale" : "1x", - "size" : "256x256" - }, - { - "filename" : "CodeEdit-Icon-Pre-256@2x.png", - "idiom" : "mac", - "scale" : "2x", - "size" : "256x256" - }, - { - "filename" : "CodeEdit-Icon-Pre-512.png", - "idiom" : "mac", - "scale" : "1x", - "size" : "512x512" - }, - { - "filename" : "CodeEdit-Icon-Pre-512@2x.png", - "idiom" : "mac", - "scale" : "2x", - "size" : "512x512" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/CodeEdit/Features/CodeEditUI/Styles/CapsuleButtonStyle.swift b/CodeEdit/Features/CodeEditUI/Styles/CapsuleButtonStyle.swift new file mode 100644 index 0000000000..50ae176a73 --- /dev/null +++ b/CodeEdit/Features/CodeEditUI/Styles/CapsuleButtonStyle.swift @@ -0,0 +1,121 @@ +// +// CapsuleButtonStyle.swift +// CodeEdit +// +// Created by Khan Winter on 9/3/25. +// + +import SwiftUI + +struct CapsuleButtonStyle: ButtonStyle { + var isActive: Bool? + var font: Font? + var width: CGFloat? + var height: CGFloat? + + init(isActive: Bool? = nil, font: Font? = nil, size: CGFloat? = nil) { + self.isActive = isActive + self.font = font + self.width = size + self.height = size + } + + init(isActive: Bool? = nil, font: Font? = nil, width: CGFloat?, height: CGFloat?) { + self.isActive = isActive + self.font = font + self.width = width + self.height = height + } + + func makeBody(configuration: ButtonStyle.Configuration) -> some View { + CapsuleButton( + configuration: configuration, + isActive: isActive, + font: font, + width: width, + height: height + ) + } + + struct CapsuleButton: View { + @Environment(\.controlActiveState) + private var controlActiveState + @Environment(\.isEnabled) + private var isEnabled: Bool + @Environment(\.colorScheme) + private var colorScheme + + let configuration: ButtonStyle.Configuration + var isActive: Bool + var font: Font + var width: CGFloat? + var height: CGFloat? + + init( + configuration: ButtonStyle.Configuration, + isActive: Bool?, + font: Font?, + width: CGFloat?, + height: CGFloat? + ) { + self.configuration = configuration + self.isActive = isActive ?? false + self.font = font ?? Font.system(size: 14.5, weight: .regular, design: .default) + self.width = width + self.height = height + } + + var body: some View { + configuration.label + .font(font) + .foregroundStyle( + isActive + ? Color(.white) + : Color(.labelColor) + ) + .frame(width: width, height: height, alignment: .center) + .contentShape(Capsule()) + .brightness( + configuration.isPressed + ? colorScheme == .dark + ? 0.5 + : isActive ? -0.25 : -0.75 + : 0 + ) + .opacity(controlActiveState == .inactive ? 0.5 : 1) + .background(Capsule().fill(isActive ? Color.accentColor : .clear)) + } + } +} + +extension ButtonStyle where Self == CapsuleButtonStyle { + static func capsuleIcon( + isActive: Bool? = false, + font: Font? = Font.system(size: 14.5, weight: .regular, design: .default), + size: CGFloat? = 24 + ) -> CapsuleButtonStyle { + return CapsuleButtonStyle(isActive: isActive, font: font, size: size) + } + static func capsuleIcon( + isActive: Bool? = false, + font: Font? = Font.system(size: 14.5, weight: .regular, design: .default), + size: CGSize? = CGSize(width: 24, height: 24) + ) -> CapsuleButtonStyle { + return CapsuleButtonStyle(isActive: isActive, font: font, width: size?.width, height: size?.height) + } + static func capsuleIcon( + isActive: Bool? = false, + font: Font? = Font.system(size: 14.5, weight: .regular, design: .default), + width: CGFloat? = nil, + height: CGFloat? = nil + ) -> CapsuleButtonStyle { + return CapsuleButtonStyle(isActive: isActive, font: font, width: width, height: height) + } + static func capsuleIcon( + isActive: Bool? = false, + font: Font? = Font.system(size: 14.5, weight: .regular, design: .default) + ) -> CapsuleButtonStyle { + return CapsuleButtonStyle(isActive: isActive, font: font) + } + static var capsuleIcon: CapsuleButtonStyle { .init() } +} diff --git a/CodeEdit/Features/CodeEditUI/Styles/IconButtonStyle.swift b/CodeEdit/Features/CodeEditUI/Styles/IconButtonStyle.swift index dfc6ff7852..13628a28f8 100644 --- a/CodeEdit/Features/CodeEditUI/Styles/IconButtonStyle.swift +++ b/CodeEdit/Features/CodeEditUI/Styles/IconButtonStyle.swift @@ -10,24 +10,21 @@ import SwiftUI struct IconButtonStyle: ButtonStyle { var isActive: Bool? var font: Font? - var size: CGSize? + var width: CGFloat? + var height: CGFloat? init(isActive: Bool? = nil, font: Font? = nil, size: CGFloat? = nil) { self.isActive = isActive self.font = font - self.size = size == nil ? nil : CGSize(width: size ?? 0, height: size ?? 0) + self.width = size + self.height = size } - init(isActive: Bool? = nil, font: Font? = nil, size: CGSize? = nil) { + init(isActive: Bool? = nil, font: Font? = nil, width: CGFloat?, height: CGFloat?) { self.isActive = isActive self.font = font - self.size = size - } - - init(isActive: Bool? = nil, font: Font? = nil) { - self.isActive = isActive - self.font = font - self.size = nil + self.width = width + self.height = height } func makeBody(configuration: ButtonStyle.Configuration) -> some View { @@ -35,15 +32,12 @@ struct IconButtonStyle: ButtonStyle { configuration: configuration, isActive: isActive, font: font, - size: size + width: width, + height: height ) } struct IconButton: View { - let configuration: ButtonStyle.Configuration - var isActive: Bool - var font: Font - var size: CGSize? @Environment(\.controlActiveState) private var controlActiveState @Environment(\.isEnabled) @@ -51,25 +45,24 @@ struct IconButtonStyle: ButtonStyle { @Environment(\.colorScheme) private var colorScheme - init(configuration: ButtonStyle.Configuration, isActive: Bool?, font: Font?, size: CGFloat?) { - self.configuration = configuration - self.isActive = isActive ?? false - self.font = font ?? Font.system(size: 14.5, weight: .regular, design: .default) - self.size = size == nil ? nil : CGSize(width: size ?? 0, height: size ?? 0) - } - - init(configuration: ButtonStyle.Configuration, isActive: Bool?, font: Font?, size: CGSize?) { - self.configuration = configuration - self.isActive = isActive ?? false - self.font = font ?? Font.system(size: 14.5, weight: .regular, design: .default) - self.size = size ?? nil - } + let configuration: ButtonStyle.Configuration + var isActive: Bool + var font: Font + var width: CGFloat? + var height: CGFloat? - init(configuration: ButtonStyle.Configuration, isActive: Bool?, font: Font?) { + init( + configuration: ButtonStyle.Configuration, + isActive: Bool?, + font: Font?, + width: CGFloat?, + height: CGFloat? + ) { self.configuration = configuration self.isActive = isActive ?? false self.font = font ?? Font.system(size: 14.5, weight: .regular, design: .default) - self.size = nil + self.width = width + self.height = height } var body: some View { @@ -80,7 +73,7 @@ struct IconButtonStyle: ButtonStyle { ? Color(.controlAccentColor) : Color(.secondaryLabelColor) ) - .frame(width: size?.width, height: size?.height, alignment: .center) + .frame(width: width, height: height, alignment: .center) .contentShape(Rectangle()) .brightness( configuration.isPressed @@ -108,7 +101,15 @@ extension ButtonStyle where Self == IconButtonStyle { font: Font? = Font.system(size: 14.5, weight: .regular, design: .default), size: CGSize? = CGSize(width: 24, height: 24) ) -> IconButtonStyle { - return IconButtonStyle(isActive: isActive, font: font, size: size) + return IconButtonStyle(isActive: isActive, font: font, width: size?.width, height: size?.height) + } + static func icon( + isActive: Bool? = false, + font: Font? = Font.system(size: 14.5, weight: .regular, design: .default), + width: CGFloat? = nil, + height: CGFloat? = nil + ) -> IconButtonStyle { + return IconButtonStyle(isActive: isActive, font: font, width: width, height: height) } static func icon( isActive: Bool? = false, diff --git a/CodeEdit/Features/CodeEditUI/Views/PaneTextField.swift b/CodeEdit/Features/CodeEditUI/Views/PaneTextField.swift index 3997a9dd55..78174452ce 100644 --- a/CodeEdit/Features/CodeEditUI/Views/PaneTextField.swift +++ b/CodeEdit/Features/CodeEditUI/Views/PaneTextField.swift @@ -122,7 +122,6 @@ struct PaneTextField: View .disabled(true) .edgesIgnoringSafeArea(.all) ) - .onTapGesture { isFocused = true } diff --git a/CodeEdit/Features/CodeEditUI/Views/WorkspacePanel/WorkspacePanelTabBar+IconButton.swift b/CodeEdit/Features/CodeEditUI/Views/WorkspacePanel/WorkspacePanelTabBar+IconButton.swift new file mode 100644 index 0000000000..1ad6b07ccc --- /dev/null +++ b/CodeEdit/Features/CodeEditUI/Views/WorkspacePanel/WorkspacePanelTabBar+IconButton.swift @@ -0,0 +1,85 @@ +// +// IconButton.swift +// CodeEdit +// +// Created by Khan Winter on 9/3/25. +// + +import SwiftUI + +extension WorkspacePanelTabBar { + struct IconButton: View { + let tab: Tab + let scale: Image.Scale = .medium + let size: CGSize + + var position: SettingsData.SidebarTabBarPosition + + @Binding var selection: Tab? + + var symbolVariant: SymbolVariants { + if #unavailable(macOS 26), selection == tab { + .fill + } else { + .none + } + } + + var body: some View { + Button { + selection = tab + } label: { + getSafeImage(named: tab.systemImage, accessibilityDescription: tab.title) + .font(.system(size: 13)) + .symbolVariant(symbolVariant) + .help(tab.title) + .frame(maxWidth: .infinity) + } + .if(.tahoe) { + $0.buttonStyle(capsuleButtonStyle) + } else: { + $0.buttonStyle(buttonStyle) + } + .focusable(false) + .accessibilityIdentifier("WorkspacePanelTab-\(tab.title)") + .accessibilityLabel(tab.title) + } + + private func getSafeImage(named: String, accessibilityDescription: String?) -> Image { + // We still use the NSImage init to check if a symbol with the name exists. + if NSImage(systemSymbolName: named, accessibilityDescription: nil) != nil { + return Image(systemName: named) + } else { + return Image(symbol: named) + } + } + + private var capsuleButtonStyle: CapsuleButtonStyle { + if #available(macOS 26, *) { + if position == .side { + .capsuleIcon( + isActive: tab == selection, + size: CGSize(width: 26, height: 40) + ) + } else { + .capsuleIcon( + isActive: tab == selection, + height: 28 + ) + } + } else { + fatalError("Used on non tahoe platform") + } + } + + private var buttonStyle: IconButtonStyle { + .icon( + isActive: tab == selection, + size: CGSize( + width: position == .side ? 24 : 42, + height: position == .side ? 40 : size.height + ) + ) + } + } +} diff --git a/CodeEdit/Features/CodeEditUI/Views/WorkspacePanelTabBar.swift b/CodeEdit/Features/CodeEditUI/Views/WorkspacePanel/WorkspacePanelTabBar.swift similarity index 72% rename from CodeEdit/Features/CodeEditUI/Views/WorkspacePanelTabBar.swift rename to CodeEdit/Features/CodeEditUI/Views/WorkspacePanel/WorkspacePanelTabBar.swift index 83053c8dd2..d3deaa8c6d 100644 --- a/CodeEdit/Features/CodeEditUI/Views/WorkspacePanelTabBar.swift +++ b/CodeEdit/Features/CodeEditUI/Views/WorkspacePanel/WorkspacePanelTabBar.swift @@ -46,26 +46,35 @@ struct WorkspacePanelTabBar: View { } } - var topBody: some View { + @ViewBuilder var topBody: some View { GeometryReader { proxy in iconsView(size: proxy.size) .frame(maxWidth: .infinity, maxHeight: .infinity) .animation(.default, value: items) } .clipped() - .frame(maxWidth: .infinity, idealHeight: 27) + .if(.tahoe) { + $0.frame(maxWidth: .infinity, idealHeight: 28).padding(.horizontal, 8) + } else: { + $0.frame(maxWidth: .infinity, idealHeight: 27) + } .fixedSize(horizontal: false, vertical: true) } - var sideBody: some View { + @ViewBuilder var sideBody: some View { GeometryReader { proxy in iconsView(size: proxy.size) - .padding(.vertical, 5) - .frame(maxWidth: .infinity, maxHeight: .infinity) + .if(!.tahoe) { + $0.padding(.vertical, 5).frame(maxWidth: .infinity, maxHeight: .infinity) + } .animation(.default, value: items) } .clipped() - .frame(idealWidth: 40, maxHeight: .infinity) + .if(.tahoe) { + $0.frame(idealWidth: 26, maxHeight: .infinity) + } else: { + $0.frame(idealWidth: 40, maxHeight: .infinity) + } .fixedSize(horizontal: true, vertical: false) } @@ -74,50 +83,75 @@ struct WorkspacePanelTabBar: View { let layout = position == .top ? AnyLayout(HStackLayout(spacing: 0)) : AnyLayout(VStackLayout(spacing: 0)) + layout { - ForEach(items) { tab in - makeIcon(tab: tab, size: size) - .offset( - x: (position == .top) ? (tabOffsets[tab] ?? 0) : 0, - y: (position == .side) ? (tabOffsets[tab] ?? 0) : 0 - ) - .background(makeTabItemGeometryReader(tab: tab)) - .simultaneousGesture(makeAreaTabDragGesture(tab: tab)) + if #available(macOS 26, *) { + ForEach(Array(items.enumerated()), id: \.element) { (idx, tab) in + tabViewTahoe(tab, next: items[safe: idx + 1], size: size) + } + } else { + ForEach(items) { tab in + tabView(tab, size: size) + } } - if position == .side { + + if position == .side, #unavailable(macOS 26) { Spacer() } } + .if(.tahoe) { + if #available(macOS 14.0, *) { + $0.background(GlassEffectView(tintColor: .secondarySystemFill)).clipShape(Capsule()) + } + } } - private func makeIcon( - tab: Tab, - scale: Image.Scale = .medium, - size: CGSize - ) -> some View { - Button { - selection = tab - } label: { - getSafeImage(named: tab.systemImage, accessibilityDescription: tab.title) - .font(.system(size: 12.5)) - .symbolVariant(tab == selection ? .fill : .none) - .help(tab.title) - } - .buttonStyle( - .icon( - isActive: tab == selection, - size: CGSize( - width: position == .side ? 40 : 24, - height: position == .side ? 28 : size.height - ) + @ViewBuilder + private func tabView(_ tab: Tab, size: CGSize) -> some View { + IconButton(tab: tab, size: size, position: position, selection: $selection) + .offset( + x: (position == .top) ? (tabOffsets[tab] ?? 0) : 0, + y: (position == .side) ? (tabOffsets[tab] ?? 0) : 0 ) - ) - .focusable(false) - .accessibilityIdentifier("WorkspacePanelTab-\(tab.title)") - .accessibilityLabel(tab.title) + .background(makeTabItemGeometryReader(tab: tab)) + .simultaneousGesture(makeAreaTabDragGesture(tab: tab)) } - private func makeAreaTabDragGesture(tab: Tab) -> some Gesture { + @available(macOS 26, *) + @ViewBuilder + private func tabViewTahoe(_ tab: Tab, next: Tab?, size: CGSize) -> some View { + let layout = position == .top + ? AnyLayout(HStackLayout(spacing: 0)) + : AnyLayout(VStackLayout(spacing: 0)) + let paddingDirection: Edge.Set = position == .top + ? .vertical + : .horizontal + let paddingAmount: CGFloat = position == .top + ? 5 + : 2 + + IconButton(tab: tab, size: size, position: position, selection: $selection) + .offset( + x: (position == .top) ? (tabOffsets[tab] ?? 0) : 0, + y: (position == .side) ? (tabOffsets[tab] ?? 0) : 0 + ) + .background(makeTabItemGeometryReader(tab: tab)) + .simultaneousGesture(makeAreaTabDragGesture(tab: tab)) + .overlay { // overlay to avoid layout adjustment when appearing/disappearing + layout { + Spacer() + if tab != items.last && selection != tab && next != selection { + Divider().padding(paddingDirection, paddingAmount) + } + } + } + } +} + +// MARK: - Drag Gesture + +private extension WorkspacePanelTabBar { + func makeAreaTabDragGesture(tab: Tab) -> some Gesture { DragGesture(minimumDistance: 2, coordinateSpace: .global) .onChanged({ value in if draggingTab != tab { @@ -173,7 +207,7 @@ struct WorkspacePanelTabBar: View { }) } - private func initializeDragGesture(value: DragGesture.Value, for tab: Tab) { + func initializeDragGesture(value: DragGesture.Value, for tab: Tab) { draggingTab = tab let initialLocation = position == .top ? value.startLocation.x : value.startLocation.y draggingStartLocation = initialLocation @@ -186,7 +220,7 @@ struct WorkspacePanelTabBar: View { } // swiftlint:disable:next function_parameter_count - private func swapTab( + func swapTab( tab: Tab, currentIndex: Int, currentLocation: CGFloat, @@ -237,7 +271,7 @@ struct WorkspacePanelTabBar: View { } } - private func isWithinPrevTopBounds( + func isWithinPrevTopBounds( _ curLocation: CGFloat, _ swapLocation: CGRect, _ swapWidth: CGFloat ) -> Bool { return curLocation < max( @@ -246,7 +280,7 @@ struct WorkspacePanelTabBar: View { ) } - private func isWithinNextTopBounds( + func isWithinNextTopBounds( _ curLocation: CGFloat, _ swapLocation: CGRect, _ swapWidth: CGFloat, _ curWidth: CGFloat ) -> Bool { return curLocation > min( @@ -255,7 +289,7 @@ struct WorkspacePanelTabBar: View { ) } - private func isWithinPrevBottomBounds( + func isWithinPrevBottomBounds( _ curLocation: CGFloat, _ swapLocation: CGRect, _ swapWidth: CGFloat ) -> Bool { return curLocation < max( @@ -264,7 +298,7 @@ struct WorkspacePanelTabBar: View { ) } - private func isWithinNextBottomBounds( + func isWithinNextBottomBounds( _ curLocation: CGFloat, _ swapLocation: CGRect, _ swapWidth: CGFloat, _ curWidth: CGFloat ) -> Bool { return curLocation > min( @@ -273,7 +307,7 @@ struct WorkspacePanelTabBar: View { ) } - private func makeTabItemGeometryReader(tab: Tab) -> some View { + func makeTabItemGeometryReader(tab: Tab) -> some View { GeometryReader { geometry in Rectangle() .foregroundColor(.clear) @@ -289,13 +323,4 @@ struct WorkspacePanelTabBar: View { } } } - - private func getSafeImage(named: String, accessibilityDescription: String?) -> Image { - // We still use the NSImage init to check if a symbol with the name exists. - if NSImage(systemSymbolName: named, accessibilityDescription: nil) != nil { - return Image(systemName: named) - } else { - return Image(symbol: named) - } - } } diff --git a/CodeEdit/Features/CodeEditUI/Views/WorkspacePanel/WorkspacePanelView.swift b/CodeEdit/Features/CodeEditUI/Views/WorkspacePanel/WorkspacePanelView.swift new file mode 100644 index 0000000000..2123551083 --- /dev/null +++ b/CodeEdit/Features/CodeEditUI/Views/WorkspacePanel/WorkspacePanelView.swift @@ -0,0 +1,140 @@ +// +// WorkspacePanelView.swift +// CodeEdit +// +// Created by Austin Condiff on 1/4/25. +// + +import SwiftUI + +struct WorkspacePanelView: View { + @ObservedObject var viewModel: ViewModel + @Binding var selectedTab: Tab? + @Binding var tabItems: [Tab] + + @Environment(\.colorScheme) + private var colorScheme + + var sidebarPosition: SettingsData.SidebarTabBarPosition + var darkDivider: Bool + let padSideItemVertically: Bool + let sideOnTrailing: Bool + let sidebarPadding: () -> (Edge.Set, CGFloat) + let bottomAccessory: BottomAccessory + + init( + viewModel: ViewModel, + selectedTab: Binding, + tabItems: Binding<[Tab]>, + sidebarPosition: SettingsData.SidebarTabBarPosition, + darkDivider: Bool = false, + padSideItemVertically: Bool = false, + sideOnTrailing: Bool = false, + sidebarPadding: @escaping () -> (Edge.Set, CGFloat) = { ([], 0) }, + @ViewBuilder bottomAccessory: () -> BottomAccessory + ) { + self.viewModel = viewModel + self._selectedTab = selectedTab + self._tabItems = tabItems + self.sidebarPosition = sidebarPosition + self.darkDivider = darkDivider + self.padSideItemVertically = padSideItemVertically + if #available(macOS 26, *) { + self.sideOnTrailing = sideOnTrailing + } else { + self.sideOnTrailing = false + } + self.sidebarPadding = sidebarPadding + self.bottomAccessory = bottomAccessory() + } + + init( + viewModel: ViewModel, + selectedTab: Binding, + tabItems: Binding<[Tab]>, + sidebarPosition: SettingsData.SidebarTabBarPosition, + darkDivider: Bool = false, + padSideItemVertically: Bool = false, + sidebarPadding: @escaping () -> (Edge.Set, CGFloat) = { ([], 0) }, + sideOnTrailing: Bool = false, + ) where BottomAccessory == EmptyView { + self.viewModel = viewModel + self._selectedTab = selectedTab + self._tabItems = tabItems + self.sidebarPosition = sidebarPosition + self.darkDivider = darkDivider + self.padSideItemVertically = padSideItemVertically + if #available(macOS 26, *) { + self.sideOnTrailing = sideOnTrailing + } else { + self.sideOnTrailing = false + } + self.sidebarPadding = sidebarPadding + self.bottomAccessory = EmptyView() + } + + var body: some View { + VStack(spacing: 0) { + if let selection = selectedTab { + selection + .safeAreaInset(edge: .bottom, spacing: 0) { + if #unavailable(macOS 26) { + bottomAccessory + } + } + } else { + CEContentUnavailableView("No Selection") + } + } + .safeAreaInset(edge: .leading, spacing: 0) { + if sidebarPosition == .side && !sideOnTrailing { + sideTabBar.padding(sidebarPadding().0, sidebarPadding().1) + } + } + .safeAreaInset(edge: .trailing, spacing: 0) { + if sidebarPosition == .side && sideOnTrailing { + sideTabBar.padding(sidebarPadding().0, sidebarPadding().1) + } + } + .safeAreaInset(edge: .top, spacing: 0) { + if sidebarPosition == .top { + VStack(spacing: 0) { + if #unavailable(macOS 26) { + Divider() + } + + WorkspacePanelTabBar(items: $tabItems, selection: $selectedTab, position: sidebarPosition) + + if #unavailable(macOS 26) { + Divider() + } + } + .padding(sidebarPadding().0, sidebarPadding().1) + } else if !darkDivider, #unavailable(macOS 26) { + Divider() + } + } + .if(.tahoe) { + $0.clipped() + } + .safeAreaInset(edge: .bottom, spacing: 0) { + if #available(macOS 26, *) { + bottomAccessory + } + } + } + + @ViewBuilder private var sideTabBar: some View { + HStack(spacing: 0) { + WorkspacePanelTabBar(items: $tabItems, selection: $selectedTab, position: sidebarPosition) + .if(.tahoe) { + $0.padding(.vertical, padSideItemVertically ? 8 : 0) + .padding(sideOnTrailing ? .trailing : .leading, 8) + } + if #unavailable(macOS 26) { + Divider() + .overlay(Color(nsColor: darkDivider && colorScheme == .dark ? .black : .clear)) + } + } + } +} diff --git a/CodeEdit/Features/CodeEditUI/Views/WorkspacePanelView.swift b/CodeEdit/Features/CodeEditUI/Views/WorkspacePanelView.swift deleted file mode 100644 index 4637d2785e..0000000000 --- a/CodeEdit/Features/CodeEditUI/Views/WorkspacePanelView.swift +++ /dev/null @@ -1,64 +0,0 @@ -// -// WorkspacePanelView.swift -// CodeEdit -// -// Created by Austin Condiff on 1/4/25. -// - -import SwiftUI - -struct WorkspacePanelView: View { - @ObservedObject var viewModel: ViewModel - @Binding var selectedTab: Tab? - @Binding var tabItems: [Tab] - - @Environment(\.colorScheme) - private var colorScheme - - var sidebarPosition: SettingsData.SidebarTabBarPosition - var darkDivider: Bool - - init( - viewModel: ViewModel, - selectedTab: Binding, - tabItems: Binding<[Tab]>, - sidebarPosition: SettingsData.SidebarTabBarPosition, - darkDivider: Bool = false - ) { - self.viewModel = viewModel - self._selectedTab = selectedTab - self._tabItems = tabItems - self.sidebarPosition = sidebarPosition - self.darkDivider = darkDivider - } - - var body: some View { - VStack(spacing: 0) { - if let selection = selectedTab { - selection - } else { - CEContentUnavailableView("No Selection") - } - } - .safeAreaInset(edge: .leading, spacing: 0) { - if sidebarPosition == .side { - HStack(spacing: 0) { - WorkspacePanelTabBar(items: $tabItems, selection: $selectedTab, position: sidebarPosition) - Divider() - .overlay(Color(nsColor: darkDivider && colorScheme == .dark ? .black : .clear)) - } - } - } - .safeAreaInset(edge: .top, spacing: 0) { - if sidebarPosition == .top { - VStack(spacing: 0) { - Divider() - WorkspacePanelTabBar(items: $tabItems, selection: $selectedTab, position: sidebarPosition) - Divider() - } - } else if !darkDivider { - Divider() - } - } - } -} diff --git a/CodeEdit/Features/Documents/Controllers/CodeEditSplitViewController.swift b/CodeEdit/Features/Documents/Controllers/CodeEditSplitViewController.swift index 39735c8de1..82b17afdee 100644 --- a/CodeEdit/Features/Documents/Controllers/CodeEditSplitViewController.swift +++ b/CodeEdit/Features/Documents/Controllers/CodeEditSplitViewController.swift @@ -19,6 +19,8 @@ final class CodeEditSplitViewController: NSSplitViewController { private weak var windowRef: NSWindow? private unowned var hapticPerformer: NSHapticFeedbackPerformer + private weak var navigatorItem: NSSplitViewItem? + // MARK: - Initialization init( @@ -66,6 +68,7 @@ final class CodeEditSplitViewController: NSSplitViewController { .environmentObject(editorManager) }) + self.navigatorItem = navigator addSplitViewItem(navigator) let workspaceView = SettingsInjector { @@ -120,6 +123,7 @@ final class CodeEditSplitViewController: NSSplitViewController { super.viewWillAppear() guard let workspace else { return } + workspace.notificationPanel.updateToolbarItem() let navigatorWidth = workspace.getFromWorkspaceState(.splitViewWidth) as? CGFloat splitView.setPosition(navigatorWidth ?? Self.minSidebarWidth, ofDividerAt: 0) @@ -200,8 +204,14 @@ final class CodeEditSplitViewController: NSSplitViewController { } if resizedDivider == 0 { - let panel = splitView.subviews[0] - let width = panel.frame.size.width + let width: CGFloat + if #available(macOS 26, *) { + let panel = splitViewItems[0] + width = panel.viewController.view.frame.size.width + } else { + let panel = splitView.subviews[0] + width = panel.frame.size.width + } if width > 0 { workspace?.addToWorkspaceState(key: .splitViewWidth, value: width) } diff --git a/CodeEdit/Features/InspectorArea/Views/InspectorAreaView.swift b/CodeEdit/Features/InspectorArea/Views/InspectorAreaView.swift index 61822a3b60..aff6ad06b1 100644 --- a/CodeEdit/Features/InspectorArea/Views/InspectorAreaView.swift +++ b/CodeEdit/Features/InspectorArea/Views/InspectorAreaView.swift @@ -49,7 +49,8 @@ struct InspectorAreaView: View { viewModel: viewModel, selectedTab: $viewModel.selectedTab, tabItems: $viewModel.tabItems, - sidebarPosition: sidebarPosition + sidebarPosition: sidebarPosition, + sideOnTrailing: true ) .formStyle(.grouped) .accessibilityElement(children: .contain) diff --git a/CodeEdit/Features/NavigatorArea/FindNavigator/FindNavigatorToolbarBottom.swift b/CodeEdit/Features/NavigatorArea/FindNavigator/FindNavigatorToolbarBottom.swift index 073296f719..7bf248dffa 100644 --- a/CodeEdit/Features/NavigatorArea/FindNavigator/FindNavigatorToolbarBottom.swift +++ b/CodeEdit/Features/NavigatorArea/FindNavigator/FindNavigatorToolbarBottom.swift @@ -11,33 +11,24 @@ struct FindNavigatorToolbarBottom: View { @State private var text = "" var body: some View { - HStack(spacing: 2) { - PaneTextField( - "Filter", - text: $text, - leadingAccessories: { - Image( - systemName: text.isEmpty - ? "line.3.horizontal.decrease.circle" - : "line.3.horizontal.decrease.circle.fill" - ) - .foregroundStyle( - text.isEmpty - ? Color(nsColor: .secondaryLabelColor) - : Color(nsColor: .controlAccentColor) - ) - .padding(.leading, 4) - .help("Show results with matching text") - }, - clearable: true - ) - } - .frame(height: 28, alignment: .center) - .frame(maxWidth: .infinity) - .padding(.horizontal, 5) - .overlay(alignment: .top) { - Divider() - .opacity(0) - } + NavigatorFilterView( + text: $text, + menu: { EmptyView() }, + leadingAccessories: { + Image( + systemName: text.isEmpty + ? "line.3.horizontal.decrease.circle" + : "line.3.horizontal.decrease.circle.fill" + ) + .foregroundStyle( + text.isEmpty + ? Color(nsColor: .secondaryLabelColor) + : Color(nsColor: .controlAccentColor) + ) + .padding(.leading, 4) + .help("Show results with matching text") + }, + trailingAccessories: { EmptyView() } + ) } } diff --git a/CodeEdit/Features/NavigatorArea/FindNavigator/FindNavigatorView.swift b/CodeEdit/Features/NavigatorArea/FindNavigator/FindNavigatorView.swift index 5e8fb370be..58e211412d 100644 --- a/CodeEdit/Features/NavigatorArea/FindNavigator/FindNavigatorView.swift +++ b/CodeEdit/Features/NavigatorArea/FindNavigator/FindNavigatorView.swift @@ -86,9 +86,6 @@ struct FindNavigatorView: View { ) } } - .safeAreaInset(edge: .bottom, spacing: 0) { - FindNavigatorToolbarBottom() - } .onReceive(state.$searchResult, perform: { value in self.foundFilesCount = value.count }) diff --git a/CodeEdit/Features/NavigatorArea/Models/NavigatorTab.swift b/CodeEdit/Features/NavigatorArea/Models/NavigatorTab.swift index f8d240e798..9f0c90f54f 100644 --- a/CodeEdit/Features/NavigatorArea/Models/NavigatorTab.swift +++ b/CodeEdit/Features/NavigatorArea/Models/NavigatorTab.swift @@ -60,4 +60,21 @@ enum NavigatorTab: WorkspacePanelTab { ExtensionSceneView(with: endpoint, sceneID: data.sceneID) } } + + @ViewBuilder + func bottomView(workspace: WorkspaceDocument) -> some View { + switch self { + case .project: + ProjectNavigatorToolbarBottom() + case .sourceControl: + if let sourceControlManager = workspace.sourceControlManager { + SourceControlNavigatorToolbarBottom() + .environmentObject(sourceControlManager) + } + case .search: + FindNavigatorToolbarBottom() + case .uiExtension: + EmptyView() + } + } } diff --git a/CodeEdit/Features/NavigatorArea/ProjectNavigator/FilterDropDownIconButton.swift b/CodeEdit/Features/NavigatorArea/ProjectNavigator/FilterDropDownIconButton.swift new file mode 100644 index 0000000000..ab2b8a0bfd --- /dev/null +++ b/CodeEdit/Features/NavigatorArea/ProjectNavigator/FilterDropDownIconButton.swift @@ -0,0 +1,33 @@ +// +// FilterDropDownIconButton.swift +// CodeEdit +// +// Created by Khan Winter on 9/2/25. +// + +import SwiftUI + +struct FilterDropDownIconButton: View { + @Environment(\.controlActiveState) + private var activeState + + var menu: () -> MenuView + + var isOn: Bool? + + var body: some View { + Menu { menu() } label: {} + .background { + if isOn == true { + Image(ImageResource.line3HorizontalDecreaseChevronFilled) + .foregroundStyle(.tint) + } else { + Image(ImageResource.line3HorizontalDecreaseChevron) + } + } + .menuStyle(.borderlessButton) + .menuIndicator(.hidden) + .frame(width: 26, height: 13) + .clipShape(.rect(cornerRadius: 6.5)) + } +} diff --git a/CodeEdit/Features/NavigatorArea/ProjectNavigator/OutlineView/ProjectNavigatorViewController.swift b/CodeEdit/Features/NavigatorArea/ProjectNavigator/OutlineView/ProjectNavigatorViewController.swift index f681705351..1cdaabe686 100644 --- a/CodeEdit/Features/NavigatorArea/ProjectNavigator/OutlineView/ProjectNavigatorViewController.swift +++ b/CodeEdit/Features/NavigatorArea/ProjectNavigator/OutlineView/ProjectNavigatorViewController.swift @@ -77,29 +77,16 @@ final class ProjectNavigatorViewController: NSViewController { self.view = scrollView self.outlineView = ProjectNavigatorNSOutlineView() - self.outlineView.dataSource = self - self.outlineView.delegate = self - self.outlineView.autosaveExpandedItems = true - self.outlineView.autosaveName = workspace?.workspaceFileManager?.folderUrl.path ?? "" - self.outlineView.headerView = nil - self.outlineView.menu = ProjectNavigatorMenu(self) - self.outlineView.menu?.delegate = self - self.outlineView.doubleAction = #selector(onItemDoubleClicked) - self.outlineView.allowsMultipleSelection = true - - self.outlineView.setAccessibilityIdentifier("ProjectNavigator") - self.outlineView.setAccessibilityLabel("Project Navigator") - - let column = NSTableColumn(identifier: .init(rawValue: "Cell")) - column.title = "Cell" - outlineView.addTableColumn(column) - - outlineView.setDraggingSourceOperationMask(.move, forLocal: false) - outlineView.registerForDraggedTypes([.fileURL]) + configureOutlineView() scrollView.documentView = outlineView scrollView.contentView.automaticallyAdjustsContentInsets = false - scrollView.contentView.contentInsets = .init(top: 10, left: 0, bottom: 0, right: 0) + if #available(macOS 26, *) { + scrollView.clipsToBounds = false + scrollView.contentView.clipsToBounds = false + } else { + scrollView.contentView.contentInsets = .init(top: 10, left: 0, bottom: 0, right: 0) + } scrollView.scrollerStyle = .overlay scrollView.hasVerticalScroller = true scrollView.hasHorizontalScroller = false @@ -129,6 +116,32 @@ final class ProjectNavigatorViewController: NSViewController { ]) } + private func configureOutlineView() { + if #available(macOS 26, *) { + self.outlineView.style = .inset + self.outlineView.clipsToBounds = false + } + self.outlineView.dataSource = self + self.outlineView.delegate = self + self.outlineView.autosaveExpandedItems = true + self.outlineView.autosaveName = workspace?.workspaceFileManager?.folderUrl.path ?? "" + self.outlineView.headerView = nil + self.outlineView.menu = ProjectNavigatorMenu(self) + self.outlineView.menu?.delegate = self + self.outlineView.doubleAction = #selector(onItemDoubleClicked) + self.outlineView.allowsMultipleSelection = true + + self.outlineView.setAccessibilityIdentifier("ProjectNavigator") + self.outlineView.setAccessibilityLabel("Project Navigator") + + let column = NSTableColumn(identifier: .init(rawValue: "Cell")) + column.title = "Cell" + outlineView.addTableColumn(column) + + outlineView.setDraggingSourceOperationMask(.move, forLocal: false) + outlineView.registerForDraggedTypes([.fileURL]) + } + init() { super.init(nibName: nil, bundle: nil) } diff --git a/CodeEdit/Features/NavigatorArea/ProjectNavigator/ProjectNavigatorToolbarBottom.swift b/CodeEdit/Features/NavigatorArea/ProjectNavigator/ProjectNavigatorToolbarBottom.swift index bb1e44fb8e..6d465d1360 100644 --- a/CodeEdit/Features/NavigatorArea/ProjectNavigator/ProjectNavigatorToolbarBottom.swift +++ b/CodeEdit/Features/NavigatorArea/ProjectNavigator/ProjectNavigatorToolbarBottom.swift @@ -20,56 +20,50 @@ struct ProjectNavigatorToolbarBottom: View { @State var recentsFilter: Bool = false var body: some View { - HStack(spacing: 5) { - addNewFileButton - PaneTextField( - "Filter", - text: $workspace.navigatorFilter, - leadingAccessories: { - FilterDropDownIconButton(menu: { - ForEach([(true, "Folders on top"), (false, "Alphabetically")], id: \.0) { value, title in - Toggle(title, isOn: Binding(get: { - workspace.sortFoldersOnTop == value - }, set: { _ in - // Avoid calling the handleFilterChange method - if workspace.sortFoldersOnTop != value { - workspace.sortFoldersOnTop = value - } - })) - } - }, isOn: !workspace.navigatorFilter.isEmpty) - .padding(.leading, 4) - .foregroundStyle( - workspace.navigatorFilter.isEmpty - ? Color(nsColor: .secondaryLabelColor) - : Color(nsColor: .controlAccentColor) - ) - .help("Show files with matching name") - }, - trailingAccessories: { - HStack(spacing: 0) { - Toggle(isOn: $recentsFilter) { - Image(systemName: "clock") - } - .help("Show only recent files") - Toggle(isOn: $workspace.sourceControlFilter) { - Image(systemName: "plusminus.circle") - } - .help("Show only files with source-control status") + NavigatorFilterView( + text: $workspace.navigatorFilter, + hasValue: { !workspace.navigatorFilter.isEmpty || recentsFilter || workspace.sourceControlFilter }, + menu: { addNewFileButton }, + leadingAccessories: { leadingAccessories }, + trailingAccessories: { trailingAccessories } + ) + } + + @ViewBuilder private var leadingAccessories: some View { + FilterDropDownIconButton(menu: { + ForEach([(true, "Folders on top"), (false, "Alphabetically")], id: \.0) { value, title in + Toggle(title, isOn: Binding(get: { + workspace.sortFoldersOnTop == value + }, set: { _ in + // Avoid calling the handleFilterChange method + if workspace.sortFoldersOnTop != value { + workspace.sortFoldersOnTop = value } - .toggleStyle(.icon(font: .system(size: 14), size: CGSize(width: 18, height: 20))) - .padding(.trailing, 2.5) - }, - clearable: true, - hasValue: !workspace.navigatorFilter.isEmpty || recentsFilter || workspace.sourceControlFilter - ) - } - .padding(.horizontal, 5) - .frame(height: 28, alignment: .center) - .frame(maxWidth: .infinity) - .overlay(alignment: .top) { - Divider() + })) + } + }, isOn: !workspace.navigatorFilter.isEmpty) + .padding(.leading, 4) + .foregroundStyle( + workspace.navigatorFilter.isEmpty + ? Color(nsColor: .secondaryLabelColor) + : Color(nsColor: .controlAccentColor) + ) + .help("Show files with matching name") + } + + @ViewBuilder private var trailingAccessories: some View { + HStack(spacing: 0) { + Toggle(isOn: $recentsFilter) { + Image(systemName: "clock") + } + .help("Show only recent files") + Toggle(isOn: $workspace.sourceControlFilter) { + Image(systemName: "plusminus.circle") + } + .help("Show only files with source-control status") } + .toggleStyle(.icon(font: .system(size: 14), size: CGSize(width: 18, height: 20))) + .padding(.trailing, 2.5) } /// Retrieves the active tab URL from the underlying editor instance, if theres no @@ -96,7 +90,7 @@ struct ProjectNavigatorToolbarBottom: View { return workspace.workspaceFileManager.unsafelyUnwrapped.folderUrl } - private var addNewFileButton: some View { + @ViewBuilder private var addNewFileButton: some View { Menu { Button("Add File") { let filePathURL = activeTabURL() @@ -159,28 +153,3 @@ struct ProjectNavigatorToolbarBottom: View { .opacity(activeState == .inactive ? 0.45 : 1) } } - -struct FilterDropDownIconButton: View { - @Environment(\.controlActiveState) - private var activeState - - var menu: () -> MenuView - - var isOn: Bool? - - var body: some View { - Menu { menu() } label: {} - .background { - if isOn == true { - Image(ImageResource.line3HorizontalDecreaseChevronFilled) - .foregroundStyle(.tint) - } else { - Image(ImageResource.line3HorizontalDecreaseChevron) - } - } - .menuStyle(.borderlessButton) - .menuIndicator(.hidden) - .frame(width: 26, height: 13) - .clipShape(.rect(cornerRadius: 6.5)) - } -} diff --git a/CodeEdit/Features/NavigatorArea/ProjectNavigator/ProjectNavigatorView.swift b/CodeEdit/Features/NavigatorArea/ProjectNavigator/ProjectNavigatorView.swift index 23536c06e0..9d03312d76 100644 --- a/CodeEdit/Features/NavigatorArea/ProjectNavigator/ProjectNavigatorView.swift +++ b/CodeEdit/Features/NavigatorArea/ProjectNavigator/ProjectNavigatorView.swift @@ -17,8 +17,5 @@ import SwiftUI struct ProjectNavigatorView: View { var body: some View { ProjectNavigatorOutlineView() - .safeAreaInset(edge: .bottom, spacing: 0) { - ProjectNavigatorToolbarBottom() - } } } diff --git a/CodeEdit/Features/NavigatorArea/SourceControlNavigator/Views/SourceControlNavigatorToolbarBottom.swift b/CodeEdit/Features/NavigatorArea/SourceControlNavigator/Views/SourceControlNavigatorToolbarBottom.swift index c2c4d60dd9..e476145451 100644 --- a/CodeEdit/Features/NavigatorArea/SourceControlNavigator/Views/SourceControlNavigatorToolbarBottom.swift +++ b/CodeEdit/Features/NavigatorArea/SourceControlNavigator/Views/SourceControlNavigatorToolbarBottom.swift @@ -14,38 +14,30 @@ struct SourceControlNavigatorToolbarBottom: View { @State private var text = "" var body: some View { - HStack(spacing: 5) { - sourceControlMenu - PaneTextField( - "Filter", - text: $text, - leadingAccessories: { - Image( - systemName: text.isEmpty - ? "line.3.horizontal.decrease.circle" - : "line.3.horizontal.decrease.circle.fill" - ) - .foregroundStyle( - text.isEmpty - ? Color(nsColor: .secondaryLabelColor) - : Color(nsColor: .controlAccentColor) - ) - .padding(.leading, 4) - .help("Filter Changes Navigator") - }, - clearable: true - ) - } - .frame(height: 28, alignment: .center) - .frame(maxWidth: .infinity) - .padding(.horizontal, 5) - .overlay(alignment: .top) { - Divider() - .opacity(0) - } + NavigatorFilterView( + text: $text, + menu: { sourceControlMenu }, + leadingAccessories: { leadingAccessories }, + trailingAccessories: { EmptyView() } + ) + } + + @ViewBuilder private var leadingAccessories: some View { + Image( + systemName: text.isEmpty + ? "line.3.horizontal.decrease.circle" + : "line.3.horizontal.decrease.circle.fill" + ) + .foregroundStyle( + text.isEmpty + ? Color(nsColor: .secondaryLabelColor) + : Color(nsColor: .controlAccentColor) + ) + .padding(.leading, 4) + .help("Filter Changes Navigator") } - private var sourceControlMenu: some View { + @ViewBuilder private var sourceControlMenu: some View { Menu { Button("Discard All Changes...") { if sourceControlManager.changedFiles.isEmpty { diff --git a/CodeEdit/Features/NavigatorArea/SourceControlNavigator/Views/SourceControlNavigatorView.swift b/CodeEdit/Features/NavigatorArea/SourceControlNavigator/Views/SourceControlNavigatorView.swift index 31363fc913..749bf2bc7b 100644 --- a/CodeEdit/Features/NavigatorArea/SourceControlNavigator/Views/SourceControlNavigatorView.swift +++ b/CodeEdit/Features/NavigatorArea/SourceControlNavigator/Views/SourceControlNavigatorView.swift @@ -14,7 +14,7 @@ struct SourceControlNavigatorView: View { var fetchRefreshServerStatus var body: some View { - if let sourceControlManager = workspace.workspaceFileManager?.sourceControlManager { + if let sourceControlManager = workspace.sourceControlManager { VStack(spacing: 0) { SourceControlNavigatorTabs() .environmentObject(sourceControlManager) @@ -31,10 +31,6 @@ struct SourceControlNavigatorView: View { } } } - .safeAreaInset(edge: .bottom, spacing: 0) { - SourceControlNavigatorToolbarBottom() - .environmentObject(sourceControlManager) - } } } } diff --git a/CodeEdit/Features/NavigatorArea/Views/NavigatorAreaView.swift b/CodeEdit/Features/NavigatorArea/Views/NavigatorAreaView.swift index a3fdabf65c..12e15850cf 100644 --- a/CodeEdit/Features/NavigatorArea/Views/NavigatorAreaView.swift +++ b/CodeEdit/Features/NavigatorArea/Views/NavigatorAreaView.swift @@ -38,8 +38,19 @@ struct NavigatorAreaView: View { viewModel: viewModel, selectedTab: $viewModel.selectedTab, tabItems: $viewModel.tabItems, - sidebarPosition: sidebarPosition + sidebarPosition: sidebarPosition, + sidebarPadding: { + if sidebarPosition == .side { + return (.trailing, 8) + } + + return ([], 0) + }, + bottomAccessory: { + viewModel.selectedTab?.bottomView(workspace: workspace) + } ) + .listStyle(.inset) .environmentObject(workspace) .accessibilityElement(children: .contain) .accessibilityLabel("navigator") diff --git a/CodeEdit/Features/NavigatorArea/Views/NavigatorFilterView.swift b/CodeEdit/Features/NavigatorArea/Views/NavigatorFilterView.swift new file mode 100644 index 0000000000..4fb6721429 --- /dev/null +++ b/CodeEdit/Features/NavigatorArea/Views/NavigatorFilterView.swift @@ -0,0 +1,157 @@ +// +// NavigatorFilterView.swift +// CodeEdit +// +// Created by Khan Winter on 9/2/25. +// + +import SwiftUI + +struct NavigatorFilterView< + MenuContents: View, + LeadingAccessories: View, + TrailingAccessories: View +>: View { + @Environment(\.colorScheme) + private var colorScheme + + @Environment(\.controlActiveState) + private var controlActive + + @FocusState private var isFocused: Bool + + @Binding var text: String + let hasValue: Bool + let menu: MenuContents + let leadingAccessories: LeadingAccessories + let trailingAccessories: TrailingAccessories + + /// Indicates that the filter view should have more emphasis, when it's focused or has a value. + private var shouldEmphasize: Bool { + isFocused || !text.isEmpty || hasValue + } + + /// The border width to use, changes based on macOS version. + private var strokeWidth: CGFloat { + if #available(macOS 26, *) { + 1.0 + } else { + 1.25 + } + } + + init( + text: Binding, + hasValue: (() -> Bool)? = nil, + @ViewBuilder menu: () -> MenuContents, + @ViewBuilder leadingAccessories: () -> LeadingAccessories, + @ViewBuilder trailingAccessories: () -> TrailingAccessories + ) { + self._text = text + self.hasValue = hasValue?() ?? false + self.menu = menu() + self.leadingAccessories = leadingAccessories() + self.trailingAccessories = trailingAccessories() + } + + var body: some View { + VStack(spacing: 0) { + Divider() + HStack(spacing: 5) { + menu + if #available(macOS 26, *) { + textField + } else { + PaneTextField( + "Filter", + text: $text, + leadingAccessories: { leadingAccessories }, + trailingAccessories: { trailingAccessories }, + clearable: true, + hasValue: hasValue + ) + } + } + .frame(maxWidth: .infinity) + .padding(8) + } + } + + @available(macOS 26, *) + @ViewBuilder var textField: some View { + HStack(alignment: .center, spacing: 0) { + leadingAccessories + TextField("Filter", text: $text, axis: .vertical) + .textFieldStyle(.plain) + .focused($isFocused) + .controlSize(.small) + .padding(.horizontal, 8) + .foregroundStyle(.primary) + .font(.system(size: 13)) + Button { + self.text = "" + } label: { + Image(systemName: "xmark.circle.fill") + } + .buttonStyle(buttonStyle) + .opacity(text.isEmpty ? 0 : 1) + .disabled(text.isEmpty) + trailingAccessories + } + .padding(.horizontal, 3) + .fixedSize(horizontal: false, vertical: true) + .buttonStyle(buttonStyle) + .toggleStyle(toggleStyle) + .frame(minHeight: 28) + .background( + selectionBackground(isFocused) + .clipShape(Capsule()) + .edgesIgnoringSafeArea(.all) + ) + .overlay( + Capsule() + .stroke(shouldEmphasize ? .tertiary : .quaternary, lineWidth: strokeWidth) + .clipShape(Capsule()) + .disabled(true) + .edgesIgnoringSafeArea(.all) + ) + .onTapGesture { + isFocused = true + } + } + + @available(macOS 26, *) + @ViewBuilder + public func selectionBackground( + _ isFocused: Bool = false + ) -> some View { + if self.controlActive != .inactive || !text.isEmpty || hasValue { + if shouldEmphasize { + Color(.textBackgroundColor) + } else { + if colorScheme == .light { + Color.black.opacity(0.06) + } else if #unavailable(macOS 26) { + Color.white.opacity(0.24) + } else { + Color.white.opacity(0.09) + } + } + } else { + if colorScheme == .light { + Color.clear + } else { + Color.white.opacity(0.14) + } + } + } + + @available(macOS 26, *) + private var buttonStyle: some ButtonStyle { + .icon(font: .system(size: 16, weight: .semibold), size: CGSize(width: 20, height: 20)) + } + @available(macOS 26, *) + private var toggleStyle: some ToggleStyle { + .icon(font: .system(size: 16, weight: .semibold), size: CGSize(width: 20, height: 20)) + } +} diff --git a/CodeEdit/Features/StatusBar/Views/StatusBarView.swift b/CodeEdit/Features/StatusBar/Views/StatusBarView.swift index cb73012d8a..82154bbe8f 100644 --- a/CodeEdit/Features/StatusBar/Views/StatusBarView.swift +++ b/CodeEdit/Features/StatusBar/Views/StatusBarView.swift @@ -22,7 +22,23 @@ struct StatusBarView: View { @Environment(\.controlActiveState) private var controlActive - static let height = 28.0 + @EnvironmentObject private var utilityAreaViewModel: UtilityAreaViewModel + + static var height: CGFloat { + if #available(macOS 26, *) { + 37.0 + } else { + 29.0 + } + } + + private var trailingPadding: CGFloat { + if #available(macOS 26, *) { + 8 + } else { + 0 + } + } @Environment(\.colorScheme) private var colorScheme @@ -34,6 +50,18 @@ struct StatusBarView: View { /// The actual status bar var body: some View { HStack(alignment: .center, spacing: 10) { + ForEach(utilityAreaViewModel.tabItems) { tab in + Button { + utilityAreaViewModel.selectedTab = tab + } label: { + Image(systemName: tab.systemImage) + .foregroundStyle(Color( + utilityAreaViewModel.selectedTab == tab ? .controlAccentColor : .secondaryLabelColor + )) + } + .buttonStyle(.icon) + .help(tab.title) + } // StatusBarBreakpointButton() // StatusBarDivider() Spacer() @@ -43,8 +71,9 @@ struct StatusBarView: View { StatusBarToggleUtilityAreaButton() } .padding(.horizontal, 10) + .padding(.trailing, trailingPadding) .cursor(.resizeUpDown) - .frame(height: Self.height) + .frame(height: Self.height - 1.0) .background(.bar) .padding(.top, 1) .overlay(alignment: .top) { diff --git a/CodeEdit/Features/UtilityArea/Views/PaneToolbar.swift b/CodeEdit/Features/UtilityArea/Views/PaneToolbar.swift index 658cc46fca..a6c67238dc 100644 --- a/CodeEdit/Features/UtilityArea/Views/PaneToolbar.swift +++ b/CodeEdit/Features/UtilityArea/Views/PaneToolbar.swift @@ -13,14 +13,33 @@ struct PaneToolbar: View { @Environment(\.paneArea) var paneArea: PaneArea? + private var height: CGFloat? { + if #available(macOS 26, *) { + 36.0 + } else { + nil + } + } + + private var maxHeight: CGFloat? { + if #available(macOS 26, *) { + nil + } else { + 27.0 + } + } + + private var padding: CGSize { + if #available(macOS 26, *) { + CGSize(width: 5.0, height: 0) + } else { + CGSize(width: 5.0, height: 8.0) + } + } + var body: some View { - HStack(spacing: 5) { - if model.hasLeadingSidebar - && ( - ((paneArea == .main || paneArea == .mainLeading) - && model.leadingSidebarIsCollapsed) - || paneArea == .leading - ) { + HStack(alignment: .center, spacing: 5) { + if shouldShowLeadingSection() { PaneToolbarSection { Spacer() .frame(width: 24) @@ -28,24 +47,45 @@ struct PaneToolbar: View { .opacity(0) } content - if model.hasTrailingSidebar - && ( - ((paneArea == .main || paneArea == .mainTrailing) - && model.trailingSidebarIsCollapsed) - || paneArea == .trailing - ) || !model.hasTrailingSidebar { - if model.hasTrailingSidebar { - PaneToolbarSection { - Spacer() - .frame(width: 24) - } - .opacity(0) + if shouldShowTrailingSection() { + PaneToolbarSection { + Spacer() + .frame(width: 24) } + .opacity(0) + } + if #available(macOS 26, *), isTrailingItem() { + Spacer().frame(width: 5) } } .buttonStyle(.icon(size: 24)) - .padding(.horizontal, 5) - .padding(.vertical, 8) - .frame(maxHeight: 27) + .padding(.horizontal, padding.width) + .padding(.vertical, padding.height) + .frame(maxHeight: maxHeight) + .frame(height: height) + } + + private func shouldShowLeadingSection() -> Bool { + model.hasLeadingSidebar + && ( + ((paneArea == .main || paneArea == .mainLeading) && model.leadingSidebarIsCollapsed) + || paneArea == .leading + ) + } + + private func shouldShowTrailingSection() -> Bool { + model.hasTrailingSidebar + && ( + ((paneArea == .main || paneArea == .mainTrailing) && model.trailingSidebarIsCollapsed) + || paneArea == .trailing + ) + } + + private func isTrailingItem() -> Bool { + paneArea == .trailing + || ( + (paneArea == .main || paneArea == .mainTrailing) + && (model.trailingSidebarIsCollapsed || !model.hasTrailingSidebar) + ) } } diff --git a/CodeEdit/Features/UtilityArea/Views/UtilityAreaTabView.swift b/CodeEdit/Features/UtilityArea/Views/UtilityAreaTabView.swift index bb36bcc5ab..c3d4a0654a 100644 --- a/CodeEdit/Features/UtilityArea/Views/UtilityAreaTabView.swift +++ b/CodeEdit/Features/UtilityArea/Views/UtilityAreaTabView.swift @@ -118,14 +118,22 @@ struct UtilityAreaTabView + + + + + + + diff --git a/ProductIcons/CodeEditAlphaIcon.icon/Assets/label-alpha-dark.svg b/ProductIcons/CodeEditAlphaIcon.icon/Assets/label-alpha-dark.svg new file mode 100644 index 0000000000..6deed4233f --- /dev/null +++ b/ProductIcons/CodeEditAlphaIcon.icon/Assets/label-alpha-dark.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/ProductIcons/CodeEditAlphaIcon.icon/Assets/label-alpha-light.svg b/ProductIcons/CodeEditAlphaIcon.icon/Assets/label-alpha-light.svg new file mode 100644 index 0000000000..28bba4e63e --- /dev/null +++ b/ProductIcons/CodeEditAlphaIcon.icon/Assets/label-alpha-light.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/ProductIcons/CodeEditAlphaIcon.icon/Assets/pen-dark-color.png b/ProductIcons/CodeEditAlphaIcon.icon/Assets/pen-dark-color.png new file mode 100644 index 0000000000..83638061fa Binary files /dev/null and b/ProductIcons/CodeEditAlphaIcon.icon/Assets/pen-dark-color.png differ diff --git a/ProductIcons/CodeEditAlphaIcon.icon/Assets/pen-light-color.png b/ProductIcons/CodeEditAlphaIcon.icon/Assets/pen-light-color.png new file mode 100644 index 0000000000..fd06bd2c22 Binary files /dev/null and b/ProductIcons/CodeEditAlphaIcon.icon/Assets/pen-light-color.png differ diff --git a/ProductIcons/CodeEditAlphaIcon.icon/Assets/pen-light.png b/ProductIcons/CodeEditAlphaIcon.icon/Assets/pen-light.png new file mode 100644 index 0000000000..be3182020d Binary files /dev/null and b/ProductIcons/CodeEditAlphaIcon.icon/Assets/pen-light.png differ diff --git a/ProductIcons/CodeEditAlphaIcon.icon/icon.json b/ProductIcons/CodeEditAlphaIcon.icon/icon.json new file mode 100644 index 0000000000..a72aaa3331 --- /dev/null +++ b/ProductIcons/CodeEditAlphaIcon.icon/icon.json @@ -0,0 +1,279 @@ +{ + "color-space-for-untagged-svg-colors" : "display-p3", + "fill" : { + "linear-gradient" : [ + "display-p3:0.36667,0.77129,1.00000,1.00000", + "srgb:0.00000,0.42405,1.00000,1.00000" + ] + }, + "groups" : [ + { + "blend-mode" : "normal", + "blur-material" : 0.05, + "hidden" : false, + "layers" : [ + { + "glass" : true, + "hidden-specializations" : [ + { + "value" : true + }, + { + "appearance" : "dark", + "value" : false + }, + { + "appearance" : "tinted", + "value" : true + } + ], + "image-name" : "label-alpha-light.svg", + "name" : "label-alpha-light", + "opacity-specializations" : [ + { + "value" : 1 + }, + { + "appearance" : "dark", + "value" : 1 + }, + { + "appearance" : "tinted", + "value" : 0 + } + ], + "position" : { + "scale" : 1, + "translation-in-points" : [ + 33.1290445202104, + 205.5 + ] + } + }, + { + "hidden-specializations" : [ + { + "value" : false + }, + { + "appearance" : "dark", + "value" : true + }, + { + "appearance" : "tinted", + "value" : false + } + ], + "image-name" : "label-alpha-dark.svg", + "name" : "label-alpha-dark", + "opacity-specializations" : [ + { + "value" : 1 + }, + { + "appearance" : "dark", + "value" : 0 + } + ], + "position" : { + "scale" : 1, + "translation-in-points" : [ + 33.1290445202104, + 205.5 + ] + } + } + ], + "lighting" : "combined", + "name" : "Label", + "position" : { + "scale" : 1.25, + "translation-in-points" : [ + 0, + 0 + ] + }, + "shadow" : { + "kind" : "neutral", + "opacity" : 0.5 + }, + "specular" : false, + "translucency" : { + "enabled" : true, + "value" : 0.5 + } + }, + { + "blur-material" : 0.5, + "hidden" : false, + "layers" : [ + { + "hidden" : false, + "image-name" : "pen-dark-color.png", + "name" : "pen-dark-color", + "opacity-specializations" : [ + { + "value" : 0 + }, + { + "appearance" : "dark", + "value" : 0 + }, + { + "appearance" : "tinted", + "value" : 0 + } + ] + }, + { + "hidden" : false, + "image-name" : "pen-light-color.png", + "name" : "pen-light-color", + "opacity-specializations" : [ + { + "value" : 0 + }, + { + "appearance" : "dark", + "value" : 1 + }, + { + "appearance" : "tinted", + "value" : 0 + } + ] + }, + { + "hidden" : false, + "image-name" : "pen-light.png", + "name" : "pen-light", + "opacity-specializations" : [ + { + "value" : 0 + }, + { + "appearance" : "dark", + "value" : 0 + }, + { + "appearance" : "tinted", + "value" : 1 + } + ] + }, + { + "glass" : true, + "hidden" : false, + "image-name" : "CodeEdit pen.png", + "name" : "CodeEdit pen", + "opacity-specializations" : [ + { + "appearance" : "dark", + "value" : 0 + }, + { + "appearance" : "tinted", + "value" : 0 + } + ], + "position" : { + "scale" : 1, + "translation-in-points" : [ + 0, + 0 + ] + } + } + ], + "name" : "Pen", + "position" : { + "scale" : 0.88, + "translation-in-points" : [ + 0, + 0 + ] + }, + "shadow" : { + "kind" : "layer-color", + "opacity" : 0.75 + }, + "specular" : false, + "translucency" : { + "enabled" : true, + "value" : 0.25 + } + }, + { + "blend-mode" : "normal", + "blur-material" : null, + "hidden" : false, + "layers" : [ + { + "fill-specializations" : [ + { + "value" : { + "automatic-gradient" : "display-p3:1.00000,1.00000,1.00000,1.00000" + } + }, + { + "appearance" : "dark", + "value" : "automatic" + }, + { + "appearance" : "tinted", + "value" : { + "automatic-gradient" : "display-p3:1.00000,1.00000,1.00000,0.86284" + } + } + ], + "glass" : true, + "hidden" : false, + "image-name" : "Slice 1 (9).svg", + "name" : "CodeLines", + "opacity-specializations" : [ + { + "value" : 0.75 + }, + { + "appearance" : "dark", + "value" : 0.5 + }, + { + "appearance" : "tinted", + "value" : 0.33 + } + ], + "position" : { + "scale" : 1, + "translation-in-points" : [ + 0, + 0 + ] + } + } + ], + "name" : "Code Lines", + "position" : { + "scale" : 1.24, + "translation-in-points" : [ + -2.4609375, + 0 + ] + }, + "shadow" : { + "kind" : "layer-color", + "opacity" : 0.5 + }, + "translucency" : { + "enabled" : true, + "value" : 0.5 + } + } + ], + "supported-platforms" : { + "circles" : [ + "watchOS" + ], + "squares" : "shared" + } +} \ No newline at end of file diff --git a/ProductIcons/CodeEditBetaIcon.icon/Assets/CodeEdit pen.png b/ProductIcons/CodeEditBetaIcon.icon/Assets/CodeEdit pen.png new file mode 100644 index 0000000000..1c65b6ff5f Binary files /dev/null and b/ProductIcons/CodeEditBetaIcon.icon/Assets/CodeEdit pen.png differ diff --git a/ProductIcons/CodeEditBetaIcon.icon/Assets/Slice 1 (9).svg b/ProductIcons/CodeEditBetaIcon.icon/Assets/Slice 1 (9).svg new file mode 100644 index 0000000000..8f57622edd --- /dev/null +++ b/ProductIcons/CodeEditBetaIcon.icon/Assets/Slice 1 (9).svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/ProductIcons/CodeEditBetaIcon.icon/Assets/label-beta-dark.svg b/ProductIcons/CodeEditBetaIcon.icon/Assets/label-beta-dark.svg new file mode 100644 index 0000000000..8d402bde87 --- /dev/null +++ b/ProductIcons/CodeEditBetaIcon.icon/Assets/label-beta-dark.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/ProductIcons/CodeEditBetaIcon.icon/Assets/label-beta-light.svg b/ProductIcons/CodeEditBetaIcon.icon/Assets/label-beta-light.svg new file mode 100644 index 0000000000..25d87459ef --- /dev/null +++ b/ProductIcons/CodeEditBetaIcon.icon/Assets/label-beta-light.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/ProductIcons/CodeEditBetaIcon.icon/Assets/pen-dark-color.png b/ProductIcons/CodeEditBetaIcon.icon/Assets/pen-dark-color.png new file mode 100644 index 0000000000..83638061fa Binary files /dev/null and b/ProductIcons/CodeEditBetaIcon.icon/Assets/pen-dark-color.png differ diff --git a/ProductIcons/CodeEditBetaIcon.icon/Assets/pen-light-color.png b/ProductIcons/CodeEditBetaIcon.icon/Assets/pen-light-color.png new file mode 100644 index 0000000000..fd06bd2c22 Binary files /dev/null and b/ProductIcons/CodeEditBetaIcon.icon/Assets/pen-light-color.png differ diff --git a/ProductIcons/CodeEditBetaIcon.icon/Assets/pen-light.png b/ProductIcons/CodeEditBetaIcon.icon/Assets/pen-light.png new file mode 100644 index 0000000000..be3182020d Binary files /dev/null and b/ProductIcons/CodeEditBetaIcon.icon/Assets/pen-light.png differ diff --git a/ProductIcons/CodeEditBetaIcon.icon/icon.json b/ProductIcons/CodeEditBetaIcon.icon/icon.json new file mode 100644 index 0000000000..4c69ca015b --- /dev/null +++ b/ProductIcons/CodeEditBetaIcon.icon/icon.json @@ -0,0 +1,256 @@ +{ + "color-space-for-untagged-svg-colors" : "display-p3", + "fill" : { + "linear-gradient" : [ + "display-p3:0.36667,0.77129,1.00000,1.00000", + "srgb:0.00000,0.42405,1.00000,1.00000" + ] + }, + "groups" : [ + { + "blend-mode" : "normal", + "blur-material" : 0.05, + "hidden" : false, + "layers" : [ + { + "hidden-specializations" : [ + { + "value" : true + }, + { + "appearance" : "dark", + "value" : false + }, + { + "appearance" : "tinted", + "value" : true + } + ], + "image-name" : "label-beta-light.svg", + "name" : "label-beta-light", + "position" : { + "scale" : 1, + "translation-in-points" : [ + 91.12904452021039, + 205.5 + ] + } + }, + { + "hidden-specializations" : [ + { + "value" : false + }, + { + "appearance" : "dark", + "value" : true + }, + { + "appearance" : "tinted", + "value" : false + } + ], + "image-name" : "label-beta-dark.svg", + "name" : "label-beta-dark", + "position" : { + "scale" : 1, + "translation-in-points" : [ + 91.12904452021039, + 205.5 + ] + } + } + ], + "lighting" : "combined", + "name" : "Label", + "position" : { + "scale" : 1.25, + "translation-in-points" : [ + 0, + 0 + ] + }, + "shadow" : { + "kind" : "neutral", + "opacity" : 0.5 + }, + "specular" : false, + "translucency" : { + "enabled" : true, + "value" : 0.5 + } + }, + { + "blur-material" : 0.5, + "hidden" : false, + "layers" : [ + { + "hidden" : false, + "image-name" : "pen-dark-color.png", + "name" : "pen-dark-color", + "opacity-specializations" : [ + { + "value" : 0 + }, + { + "appearance" : "dark", + "value" : 0 + }, + { + "appearance" : "tinted", + "value" : 0 + } + ] + }, + { + "hidden" : false, + "image-name" : "pen-light-color.png", + "name" : "pen-light-color", + "opacity-specializations" : [ + { + "value" : 0 + }, + { + "appearance" : "dark", + "value" : 1 + }, + { + "appearance" : "tinted", + "value" : 0 + } + ] + }, + { + "hidden" : false, + "image-name" : "pen-light.png", + "name" : "pen-light", + "opacity-specializations" : [ + { + "value" : 0 + }, + { + "appearance" : "dark", + "value" : 0 + }, + { + "appearance" : "tinted", + "value" : 1 + } + ] + }, + { + "glass" : true, + "hidden" : false, + "image-name" : "CodeEdit pen.png", + "name" : "CodeEdit pen", + "opacity-specializations" : [ + { + "appearance" : "dark", + "value" : 0 + }, + { + "appearance" : "tinted", + "value" : 0 + } + ], + "position" : { + "scale" : 1, + "translation-in-points" : [ + 0, + 0 + ] + } + } + ], + "name" : "Pen", + "position" : { + "scale" : 0.88, + "translation-in-points" : [ + 0, + 0 + ] + }, + "shadow" : { + "kind" : "layer-color", + "opacity" : 0.75 + }, + "specular" : false, + "translucency" : { + "enabled" : true, + "value" : 0.25 + } + }, + { + "blend-mode" : "normal", + "blur-material" : null, + "hidden" : false, + "layers" : [ + { + "fill-specializations" : [ + { + "value" : { + "automatic-gradient" : "display-p3:1.00000,1.00000,1.00000,1.00000" + } + }, + { + "appearance" : "dark", + "value" : "automatic" + }, + { + "appearance" : "tinted", + "value" : { + "automatic-gradient" : "display-p3:1.00000,1.00000,1.00000,0.86284" + } + } + ], + "glass" : true, + "hidden" : false, + "image-name" : "Slice 1 (9).svg", + "name" : "CodeLines", + "opacity-specializations" : [ + { + "value" : 0.75 + }, + { + "appearance" : "dark", + "value" : 0.5 + }, + { + "appearance" : "tinted", + "value" : 0.33 + } + ], + "position" : { + "scale" : 1, + "translation-in-points" : [ + 0, + 0 + ] + } + } + ], + "name" : "Code Lines", + "position" : { + "scale" : 1.24, + "translation-in-points" : [ + -2.4609375, + 0 + ] + }, + "shadow" : { + "kind" : "layer-color", + "opacity" : 0.5 + }, + "translucency" : { + "enabled" : true, + "value" : 0.5 + } + } + ], + "supported-platforms" : { + "circles" : [ + "watchOS" + ], + "squares" : "shared" + } +} \ No newline at end of file diff --git a/ProductIcons/CodeEditDevIcon.icon/Assets/CodeEdit pen.png b/ProductIcons/CodeEditDevIcon.icon/Assets/CodeEdit pen.png new file mode 100644 index 0000000000..1c65b6ff5f Binary files /dev/null and b/ProductIcons/CodeEditDevIcon.icon/Assets/CodeEdit pen.png differ diff --git a/ProductIcons/CodeEditDevIcon.icon/Assets/Slice 1 (9).svg b/ProductIcons/CodeEditDevIcon.icon/Assets/Slice 1 (9).svg new file mode 100644 index 0000000000..8f57622edd --- /dev/null +++ b/ProductIcons/CodeEditDevIcon.icon/Assets/Slice 1 (9).svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/ProductIcons/CodeEditDevIcon.icon/Assets/label-dev-dark.svg b/ProductIcons/CodeEditDevIcon.icon/Assets/label-dev-dark.svg new file mode 100644 index 0000000000..311261f77d --- /dev/null +++ b/ProductIcons/CodeEditDevIcon.icon/Assets/label-dev-dark.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/ProductIcons/CodeEditDevIcon.icon/Assets/label-dev-light.svg b/ProductIcons/CodeEditDevIcon.icon/Assets/label-dev-light.svg new file mode 100644 index 0000000000..72fb03f7f7 --- /dev/null +++ b/ProductIcons/CodeEditDevIcon.icon/Assets/label-dev-light.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/ProductIcons/CodeEditDevIcon.icon/Assets/pen-dark-color.png b/ProductIcons/CodeEditDevIcon.icon/Assets/pen-dark-color.png new file mode 100644 index 0000000000..83638061fa Binary files /dev/null and b/ProductIcons/CodeEditDevIcon.icon/Assets/pen-dark-color.png differ diff --git a/ProductIcons/CodeEditDevIcon.icon/Assets/pen-light-color.png b/ProductIcons/CodeEditDevIcon.icon/Assets/pen-light-color.png new file mode 100644 index 0000000000..fd06bd2c22 Binary files /dev/null and b/ProductIcons/CodeEditDevIcon.icon/Assets/pen-light-color.png differ diff --git a/ProductIcons/CodeEditDevIcon.icon/Assets/pen-light.png b/ProductIcons/CodeEditDevIcon.icon/Assets/pen-light.png new file mode 100644 index 0000000000..be3182020d Binary files /dev/null and b/ProductIcons/CodeEditDevIcon.icon/Assets/pen-light.png differ diff --git a/ProductIcons/CodeEditDevIcon.icon/icon.json b/ProductIcons/CodeEditDevIcon.icon/icon.json new file mode 100644 index 0000000000..dba5069e66 --- /dev/null +++ b/ProductIcons/CodeEditDevIcon.icon/icon.json @@ -0,0 +1,258 @@ +{ + "color-space-for-untagged-svg-colors" : "display-p3", + "fill" : { + "linear-gradient" : [ + "display-p3:0.36667,0.77129,1.00000,1.00000", + "srgb:0.00000,0.42405,1.00000,1.00000" + ] + }, + "groups" : [ + { + "blend-mode" : "normal", + "blur-material" : 0.05, + "hidden" : false, + "layers" : [ + { + "blend-mode" : "normal", + "hidden-specializations" : [ + { + "value" : true + }, + { + "appearance" : "dark", + "value" : false + }, + { + "appearance" : "tinted", + "value" : true + } + ], + "image-name" : "label-dev-light.svg", + "name" : "label-dev-light", + "opacity" : 1, + "position" : { + "scale" : 1, + "translation-in-points" : [ + 122.12904452021026, + 205.5 + ] + } + }, + { + "hidden-specializations" : [ + { + "value" : false + }, + { + "appearance" : "dark", + "value" : true + }, + { + "appearance" : "tinted", + "value" : false + } + ], + "image-name" : "label-dev-dark.svg", + "name" : "label-dev-dark", + "position" : { + "scale" : 1, + "translation-in-points" : [ + 122.12904452021037, + 205.5 + ] + } + } + ], + "lighting" : "combined", + "name" : "Label", + "position" : { + "scale" : 1.25, + "translation-in-points" : [ + 0, + 0 + ] + }, + "shadow" : { + "kind" : "neutral", + "opacity" : 0.5 + }, + "specular" : false, + "translucency" : { + "enabled" : true, + "value" : 0.5 + } + }, + { + "blur-material" : 0.5, + "hidden" : false, + "layers" : [ + { + "hidden" : false, + "image-name" : "pen-dark-color.png", + "name" : "pen-dark-color", + "opacity-specializations" : [ + { + "value" : 0 + }, + { + "appearance" : "dark", + "value" : 0 + }, + { + "appearance" : "tinted", + "value" : 0 + } + ] + }, + { + "hidden" : false, + "image-name" : "pen-light-color.png", + "name" : "pen-light-color", + "opacity-specializations" : [ + { + "value" : 0 + }, + { + "appearance" : "dark", + "value" : 1 + }, + { + "appearance" : "tinted", + "value" : 0 + } + ] + }, + { + "hidden" : false, + "image-name" : "pen-light.png", + "name" : "pen-light", + "opacity-specializations" : [ + { + "value" : 0 + }, + { + "appearance" : "dark", + "value" : 0 + }, + { + "appearance" : "tinted", + "value" : 1 + } + ] + }, + { + "glass" : true, + "hidden" : false, + "image-name" : "CodeEdit pen.png", + "name" : "CodeEdit pen", + "opacity-specializations" : [ + { + "appearance" : "dark", + "value" : 0 + }, + { + "appearance" : "tinted", + "value" : 0 + } + ], + "position" : { + "scale" : 1, + "translation-in-points" : [ + 0, + 0 + ] + } + } + ], + "name" : "Pen", + "position" : { + "scale" : 0.88, + "translation-in-points" : [ + 0, + 0 + ] + }, + "shadow" : { + "kind" : "layer-color", + "opacity" : 0.75 + }, + "specular" : false, + "translucency" : { + "enabled" : true, + "value" : 0.25 + } + }, + { + "blend-mode" : "normal", + "blur-material" : null, + "hidden" : false, + "layers" : [ + { + "fill-specializations" : [ + { + "value" : { + "automatic-gradient" : "display-p3:1.00000,1.00000,1.00000,1.00000" + } + }, + { + "appearance" : "dark", + "value" : "automatic" + }, + { + "appearance" : "tinted", + "value" : { + "automatic-gradient" : "display-p3:1.00000,1.00000,1.00000,0.86284" + } + } + ], + "glass" : true, + "hidden" : false, + "image-name" : "Slice 1 (9).svg", + "name" : "CodeLines", + "opacity-specializations" : [ + { + "value" : 0.75 + }, + { + "appearance" : "dark", + "value" : 0.5 + }, + { + "appearance" : "tinted", + "value" : 0.33 + } + ], + "position" : { + "scale" : 1, + "translation-in-points" : [ + 0, + 0 + ] + } + } + ], + "name" : "Code Lines", + "position" : { + "scale" : 1.24, + "translation-in-points" : [ + -2.4609375, + 0 + ] + }, + "shadow" : { + "kind" : "layer-color", + "opacity" : 0.5 + }, + "translucency" : { + "enabled" : true, + "value" : 0.5 + } + } + ], + "supported-platforms" : { + "circles" : [ + "watchOS" + ], + "squares" : "shared" + } +} \ No newline at end of file diff --git a/ProductIcons/CodeEditIcon.icon/Assets/CodeEdit pen.png b/ProductIcons/CodeEditIcon.icon/Assets/CodeEdit pen.png new file mode 100644 index 0000000000..1c65b6ff5f Binary files /dev/null and b/ProductIcons/CodeEditIcon.icon/Assets/CodeEdit pen.png differ diff --git a/ProductIcons/CodeEditIcon.icon/Assets/Slice 1 (9).svg b/ProductIcons/CodeEditIcon.icon/Assets/Slice 1 (9).svg new file mode 100644 index 0000000000..8f57622edd --- /dev/null +++ b/ProductIcons/CodeEditIcon.icon/Assets/Slice 1 (9).svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/ProductIcons/CodeEditIcon.icon/Assets/pen-dark-color.png b/ProductIcons/CodeEditIcon.icon/Assets/pen-dark-color.png new file mode 100644 index 0000000000..83638061fa Binary files /dev/null and b/ProductIcons/CodeEditIcon.icon/Assets/pen-dark-color.png differ diff --git a/ProductIcons/CodeEditIcon.icon/Assets/pen-light-color.png b/ProductIcons/CodeEditIcon.icon/Assets/pen-light-color.png new file mode 100644 index 0000000000..fd06bd2c22 Binary files /dev/null and b/ProductIcons/CodeEditIcon.icon/Assets/pen-light-color.png differ diff --git a/ProductIcons/CodeEditIcon.icon/Assets/pen-light.png b/ProductIcons/CodeEditIcon.icon/Assets/pen-light.png new file mode 100644 index 0000000000..be3182020d Binary files /dev/null and b/ProductIcons/CodeEditIcon.icon/Assets/pen-light.png differ diff --git a/ProductIcons/CodeEditIcon.icon/icon.json b/ProductIcons/CodeEditIcon.icon/icon.json new file mode 100644 index 0000000000..29f8e9cbca --- /dev/null +++ b/ProductIcons/CodeEditIcon.icon/icon.json @@ -0,0 +1,183 @@ +{ + "color-space-for-untagged-svg-colors" : "display-p3", + "fill" : { + "linear-gradient" : [ + "display-p3:0.36667,0.77129,1.00000,1.00000", + "srgb:0.00000,0.42405,1.00000,1.00000" + ] + }, + "groups" : [ + { + "blur-material" : 0.5, + "hidden" : false, + "layers" : [ + { + "hidden" : false, + "image-name" : "pen-dark-color.png", + "name" : "pen-dark-color", + "opacity-specializations" : [ + { + "value" : 0 + }, + { + "appearance" : "dark", + "value" : 0 + }, + { + "appearance" : "tinted", + "value" : 0 + } + ] + }, + { + "hidden" : false, + "image-name" : "pen-light-color.png", + "name" : "pen-light-color", + "opacity-specializations" : [ + { + "value" : 0 + }, + { + "appearance" : "dark", + "value" : 1 + }, + { + "appearance" : "tinted", + "value" : 0 + } + ] + }, + { + "hidden" : false, + "image-name" : "pen-light.png", + "name" : "pen-light", + "opacity-specializations" : [ + { + "value" : 0 + }, + { + "appearance" : "dark", + "value" : 0 + }, + { + "appearance" : "tinted", + "value" : 1 + } + ] + }, + { + "glass" : true, + "hidden" : false, + "image-name" : "CodeEdit pen.png", + "name" : "CodeEdit pen", + "opacity-specializations" : [ + { + "appearance" : "dark", + "value" : 0 + }, + { + "appearance" : "tinted", + "value" : 0 + } + ], + "position" : { + "scale" : 1, + "translation-in-points" : [ + 0, + 0 + ] + } + } + ], + "name" : "Pen", + "position" : { + "scale" : 0.88, + "translation-in-points" : [ + 0, + 0 + ] + }, + "shadow" : { + "kind" : "layer-color", + "opacity" : 0.75 + }, + "specular" : false, + "translucency" : { + "enabled" : true, + "value" : 0.25 + } + }, + { + "blend-mode" : "normal", + "blur-material" : null, + "hidden" : false, + "layers" : [ + { + "fill-specializations" : [ + { + "value" : { + "automatic-gradient" : "display-p3:1.00000,1.00000,1.00000,1.00000" + } + }, + { + "appearance" : "dark", + "value" : "automatic" + }, + { + "appearance" : "tinted", + "value" : { + "automatic-gradient" : "display-p3:1.00000,1.00000,1.00000,0.86284" + } + } + ], + "glass" : true, + "hidden" : false, + "image-name" : "Slice 1 (9).svg", + "name" : "CodeLines", + "opacity-specializations" : [ + { + "value" : 0.75 + }, + { + "appearance" : "dark", + "value" : 0.5 + }, + { + "appearance" : "tinted", + "value" : 0.33 + } + ], + "position" : { + "scale" : 1, + "translation-in-points" : [ + 0, + 0 + ] + } + } + ], + "name" : "Code Lines", + "position" : { + "scale" : 1.24, + "translation-in-points" : [ + -2.4609375, + 0 + ] + }, + "shadow" : { + "kind" : "layer-color", + "opacity" : 0.5 + }, + "translucency" : { + "enabled" : true, + "value" : 0.5 + } + } + ], + "supported-platforms" : { + "circles" : [ + "watchOS" + ], + "squares" : "shared" + } +} \ No newline at end of file diff --git a/ProductIcons/CodeEditPreIcon.icon/Assets/CodeEdit pen.png b/ProductIcons/CodeEditPreIcon.icon/Assets/CodeEdit pen.png new file mode 100644 index 0000000000..1c65b6ff5f Binary files /dev/null and b/ProductIcons/CodeEditPreIcon.icon/Assets/CodeEdit pen.png differ diff --git a/ProductIcons/CodeEditPreIcon.icon/Assets/Slice 1 (9).svg b/ProductIcons/CodeEditPreIcon.icon/Assets/Slice 1 (9).svg new file mode 100644 index 0000000000..8f57622edd --- /dev/null +++ b/ProductIcons/CodeEditPreIcon.icon/Assets/Slice 1 (9).svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/ProductIcons/CodeEditPreIcon.icon/Assets/label-pre-dark.svg b/ProductIcons/CodeEditPreIcon.icon/Assets/label-pre-dark.svg new file mode 100644 index 0000000000..c3e11d60e9 --- /dev/null +++ b/ProductIcons/CodeEditPreIcon.icon/Assets/label-pre-dark.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/ProductIcons/CodeEditPreIcon.icon/Assets/label-pre-light.svg b/ProductIcons/CodeEditPreIcon.icon/Assets/label-pre-light.svg new file mode 100644 index 0000000000..7c6f1ccd38 --- /dev/null +++ b/ProductIcons/CodeEditPreIcon.icon/Assets/label-pre-light.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/ProductIcons/CodeEditPreIcon.icon/Assets/pen-dark-color.png b/ProductIcons/CodeEditPreIcon.icon/Assets/pen-dark-color.png new file mode 100644 index 0000000000..83638061fa Binary files /dev/null and b/ProductIcons/CodeEditPreIcon.icon/Assets/pen-dark-color.png differ diff --git a/ProductIcons/CodeEditPreIcon.icon/Assets/pen-light-color.png b/ProductIcons/CodeEditPreIcon.icon/Assets/pen-light-color.png new file mode 100644 index 0000000000..fd06bd2c22 Binary files /dev/null and b/ProductIcons/CodeEditPreIcon.icon/Assets/pen-light-color.png differ diff --git a/ProductIcons/CodeEditPreIcon.icon/Assets/pen-light.png b/ProductIcons/CodeEditPreIcon.icon/Assets/pen-light.png new file mode 100644 index 0000000000..be3182020d Binary files /dev/null and b/ProductIcons/CodeEditPreIcon.icon/Assets/pen-light.png differ diff --git a/ProductIcons/CodeEditPreIcon.icon/icon.json b/ProductIcons/CodeEditPreIcon.icon/icon.json new file mode 100644 index 0000000000..5407dfaa93 --- /dev/null +++ b/ProductIcons/CodeEditPreIcon.icon/icon.json @@ -0,0 +1,259 @@ +{ + "color-space-for-untagged-svg-colors" : "display-p3", + "fill" : { + "linear-gradient" : [ + "display-p3:0.36667,0.77129,1.00000,1.00000", + "srgb:0.00000,0.42405,1.00000,1.00000" + ] + }, + "groups" : [ + { + "blend-mode" : "normal", + "blur-material" : 0.05, + "hidden" : false, + "layers" : [ + { + "hidden-specializations" : [ + { + "value" : true + }, + { + "appearance" : "dark", + "value" : false + }, + { + "appearance" : "tinted", + "value" : true + } + ], + "image-name" : "label-pre-light.svg", + "name" : "label-pre-light", + "position" : { + "scale" : 1, + "translation-in-points" : [ + 129.62904452021024, + 205.5 + ] + } + }, + { + "blend-mode" : "screen", + "glass" : true, + "hidden-specializations" : [ + { + "value" : false + }, + { + "appearance" : "dark", + "value" : true + }, + { + "appearance" : "tinted", + "value" : false + } + ], + "image-name" : "label-pre-dark.svg", + "name" : "label-pre-dark", + "opacity" : 1, + "position" : { + "scale" : 1, + "translation-in-points" : [ + 129.62904452021024, + 205.5 + ] + } + } + ], + "lighting" : "combined", + "name" : "Label", + "position" : { + "scale" : 1.25, + "translation-in-points" : [ + 0, + 0 + ] + }, + "shadow" : { + "kind" : "neutral", + "opacity" : 0.5 + }, + "specular" : false, + "translucency" : { + "enabled" : true, + "value" : 0.5 + } + }, + { + "blur-material" : 0.5, + "hidden" : false, + "layers" : [ + { + "hidden" : false, + "image-name" : "pen-dark-color.png", + "name" : "pen-dark-color", + "opacity-specializations" : [ + { + "value" : 0 + }, + { + "appearance" : "dark", + "value" : 0 + }, + { + "appearance" : "tinted", + "value" : 0 + } + ] + }, + { + "hidden" : false, + "image-name" : "pen-light-color.png", + "name" : "pen-light-color", + "opacity-specializations" : [ + { + "value" : 0 + }, + { + "appearance" : "dark", + "value" : 1 + }, + { + "appearance" : "tinted", + "value" : 0 + } + ] + }, + { + "hidden" : false, + "image-name" : "pen-light.png", + "name" : "pen-light", + "opacity-specializations" : [ + { + "value" : 0 + }, + { + "appearance" : "dark", + "value" : 0 + }, + { + "appearance" : "tinted", + "value" : 1 + } + ] + }, + { + "glass" : true, + "hidden" : false, + "image-name" : "CodeEdit pen.png", + "name" : "CodeEdit pen", + "opacity-specializations" : [ + { + "appearance" : "dark", + "value" : 0 + }, + { + "appearance" : "tinted", + "value" : 0 + } + ], + "position" : { + "scale" : 1, + "translation-in-points" : [ + 0, + 0 + ] + } + } + ], + "name" : "Pen", + "position" : { + "scale" : 0.88, + "translation-in-points" : [ + 0, + 0 + ] + }, + "shadow" : { + "kind" : "layer-color", + "opacity" : 0.75 + }, + "specular" : false, + "translucency" : { + "enabled" : true, + "value" : 0.25 + } + }, + { + "blend-mode" : "normal", + "blur-material" : null, + "hidden" : false, + "layers" : [ + { + "fill-specializations" : [ + { + "value" : { + "automatic-gradient" : "display-p3:1.00000,1.00000,1.00000,1.00000" + } + }, + { + "appearance" : "dark", + "value" : "automatic" + }, + { + "appearance" : "tinted", + "value" : { + "automatic-gradient" : "display-p3:1.00000,1.00000,1.00000,0.86284" + } + } + ], + "glass" : true, + "hidden" : false, + "image-name" : "Slice 1 (9).svg", + "name" : "CodeLines", + "opacity-specializations" : [ + { + "value" : 0.75 + }, + { + "appearance" : "dark", + "value" : 0.5 + }, + { + "appearance" : "tinted", + "value" : 0.33 + } + ], + "position" : { + "scale" : 1, + "translation-in-points" : [ + 0, + 0 + ] + } + } + ], + "name" : "Code Lines", + "position" : { + "scale" : 1.24, + "translation-in-points" : [ + -2.4609375, + 0 + ] + }, + "shadow" : { + "kind" : "layer-color", + "opacity" : 0.5 + }, + "translucency" : { + "enabled" : true, + "value" : 0.5 + } + } + ], + "supported-platforms" : { + "circles" : [ + "watchOS" + ], + "squares" : "shared" + } +} \ No newline at end of file