feat: localization (closes #134)

This commit is contained in:
louis.pontoise authored and lwouis committed 2020-03-10 14:00:37 +09:00
1 parent cb66b79582
commit 36e4bb06de
13 files changed
+234 -44

No files matched your search

+6
View File
@@ -15,6 +15,12 @@ choose **Open** then click **Open** in the prompt that appears.
From macOS 10.12 to 10.15 From macOS 10.12 to 10.15
## Localization
The app is currently available in: English, Français
[Contribute your own language easily on POEditor](https://poeditor.com/join/project/8AOEZ0eAZE)
## Usage ## Usage
* Press `⌥ option` + `⇥ tab` to shows the thumbnails. * Press `⌥ option` + `⇥ tab` to shows the thumbnails.
+79 -8
View File
@@ -31,12 +31,14 @@
D04BA6B6B703DCEFE892D5A4 /* Spaces.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04BA5EB5ED248C8C22CC672 /* Spaces.swift */; }; D04BA6B6B703DCEFE892D5A4 /* Spaces.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04BA5EB5ED248C8C22CC672 /* Spaces.swift */; };
D04BA6D9DA2A8BCD93347F0E /* CollectionViewItemFontIcon.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04BAC0416F29ADE7BC5A544 /* CollectionViewItemFontIcon.swift */; }; D04BA6D9DA2A8BCD93347F0E /* CollectionViewItemFontIcon.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04BAC0416F29ADE7BC5A544 /* CollectionViewItemFontIcon.swift */; };
D04BA70FF7262BF5F9E6E13B /* Preferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04BADCB1C0F50340A6CAFC2 /* Preferences.swift */; }; D04BA70FF7262BF5F9E6E13B /* Preferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04BADCB1C0F50340A6CAFC2 /* Preferences.swift */; };
D04BA79B891E9C89C015D6DD /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = D04BAEE5AEEB8692856B45E4 /* InfoPlist.strings */; };
D04BA7F212CDB1B7E101D7A3 /* GridView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04BAFE3AC6E14F394956586 /* GridView.swift */; }; D04BA7F212CDB1B7E101D7A3 /* GridView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04BAFE3AC6E14F394956586 /* GridView.swift */; };
D04BA8373D4DE452C0C081ED /* SF-Pro-Text-Regular.otf in Resources */ = {isa = PBXBuildFile; fileRef = D04BABC654F40BE74DA25BC7 /* SF-Pro-Text-Regular.otf */; }; D04BA8373D4DE452C0C081ED /* SF-Pro-Text-Regular.otf in Resources */ = {isa = PBXBuildFile; fileRef = D04BABC654F40BE74DA25BC7 /* SF-Pro-Text-Regular.otf */; };
D04BA84074E5FD6221720BC7 /* CollectionViewFlowLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04BAACB6648E7C2A4E0339D /* CollectionViewFlowLayout.swift */; }; D04BA84074E5FD6221720BC7 /* CollectionViewFlowLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04BAACB6648E7C2A4E0339D /* CollectionViewFlowLayout.swift */; };
D04BA8EBC0365A019A27C7EA /* Screen.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04BA3F15EAE8D8C39B6F2CF /* Screen.swift */; }; D04BA8EBC0365A019A27C7EA /* Screen.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04BA3F15EAE8D8C39B6F2CF /* Screen.swift */; };
D04BA9CCE02D30C8164A552A /* SystemPermissions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04BA2D2AD6B1CCA3F3A4DD7 /* SystemPermissions.swift */; }; D04BA9CCE02D30C8164A552A /* SystemPermissions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04BA2D2AD6B1CCA3F3A4DD7 /* SystemPermissions.swift */; };
D04BA9EE5D34A2789DCB0EE2 /* Sysctl.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04BA896E37EFD27CAB61DF0 /* Sysctl.swift */; }; D04BA9EE5D34A2789DCB0EE2 /* Sysctl.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04BA896E37EFD27CAB61DF0 /* Sysctl.swift */; };
D04BAA0F39E6160F5703FC33 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = D04BAC0D42D7FED725746DA5 /* Localizable.strings */; };
D04BAAD43731608067734ED3 /* DispatchQueues.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04BA56E285C3FCDA52ED262 /* DispatchQueues.swift */; }; D04BAAD43731608067734ED3 /* DispatchQueues.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04BA56E285C3FCDA52ED262 /* DispatchQueues.swift */; };
D04BAB5E802C938E78839011 /* TextArea.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04BA8011143819B48F204C2 /* TextArea.swift */; }; D04BAB5E802C938E78839011 /* TextArea.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04BA8011143819B48F204C2 /* TextArea.swift */; };
D04BABF88726DA42B2CBA68B /* ThumbnailsPanel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04BAF40D5E54AD1044B3FF7 /* ThumbnailsPanel.swift */; }; D04BABF88726DA42B2CBA68B /* ThumbnailsPanel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04BAF40D5E54AD1044B3FF7 /* ThumbnailsPanel.swift */; };
@@ -44,15 +46,18 @@
D04BAC4F69FE9563BC1C5E9C /* DebugProfile.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04BA3915020FB9B34555D74 /* DebugProfile.swift */; }; D04BAC4F69FE9563BC1C5E9C /* DebugProfile.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04BA3915020FB9B34555D74 /* DebugProfile.swift */; };
D04BAC9C031D482119F6DEB8 /* FeedbackWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04BAFA84FD0B02215718F94 /* FeedbackWindow.swift */; }; D04BAC9C031D482119F6DEB8 /* FeedbackWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04BAFA84FD0B02215718F94 /* FeedbackWindow.swift */; };
D04BACD398A35D82D514A9F7 /* TextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04BABC180117F8785D250E1 /* TextField.swift */; }; D04BACD398A35D82D514A9F7 /* TextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04BABC180117F8785D250E1 /* TextField.swift */; };
D04BAD1158CBCC76DE321555 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = D04BA1ACE289DC4AD4826D1E /* InfoPlist.strings */; };
D04BAD5A6B2F9EEE6FD4185F /* CollectionViewItemTitle.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04BA4BABBA0312E0EDBA647 /* CollectionViewItemTitle.swift */; }; D04BAD5A6B2F9EEE6FD4185F /* CollectionViewItemTitle.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04BA4BABBA0312E0EDBA647 /* CollectionViewItemTitle.swift */; };
D04BAD8346A6A32C9749E0B3 /* TabViewItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04BA293C53EC5CE00D11E02 /* TabViewItem.swift */; }; D04BAD8346A6A32C9749E0B3 /* TabViewItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04BA293C53EC5CE00D11E02 /* TabViewItem.swift */; };
D04BAE369A14C3126A1606FE /* HelperExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04BA8F1AA48A323EE5638DC /* HelperExtensions.swift */; }; D04BAE369A14C3126A1606FE /* HelperExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04BA8F1AA48A323EE5638DC /* HelperExtensions.swift */; };
D04BAEAB8AB048FF2B16B131 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = D04BAE5FA03065C5D23C0C2C /* Localizable.strings */; };
D04BAEF78503D7A2CEFB9E9E /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04BAA44C837F3A67403B9DB /* main.swift */; }; D04BAEF78503D7A2CEFB9E9E /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04BAA44C837F3A67403B9DB /* main.swift */; };
D04BAF3B6F75E50E9AA3E1D2 /* LabelAndControl.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04BA3D65E7CA78D699EDAB0 /* LabelAndControl.swift */; }; D04BAF3B6F75E50E9AA3E1D2 /* LabelAndControl.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04BA3D65E7CA78D699EDAB0 /* LabelAndControl.swift */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
4807A6C523A9CD190052A53E /* SkyLight.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SkyLight.framework; path = ../../../../System/Library/PrivateFrameworks/SkyLight.framework; sourceTree = "<group>"; }; 4807A6C523A9CD190052A53E /* SkyLight.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SkyLight.framework; path = ../../../../System/Library/PrivateFrameworks/SkyLight.framework; sourceTree = "<group>"; };
D04BA05F3F36A6D71DCD8475 /* en */ = {isa = PBXFileReference; fileEncoding = 2483028224; lastKnownFileType = text.plist.strings; name = en; path = Localizable.strings; sourceTree = "<group>"; };
D04BA0CE87BE264C52987ED1 /* 7 windows - 2 lines - wide window.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = "7 windows - 2 lines - wide window.jpg"; sourceTree = "<group>"; }; D04BA0CE87BE264C52987ED1 /* 7 windows - 2 lines - wide window.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = "7 windows - 2 lines - wide window.jpg"; sourceTree = "<group>"; };
D04BA0E1C5DBC07108AC2F54 /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; }; D04BA0E1C5DBC07108AC2F54 /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
D04BA0F5EB832B8E142B654B /* 4 windows - 1 line.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = "4 windows - 1 line.jpg"; sourceTree = "<group>"; }; D04BA0F5EB832B8E142B654B /* 4 windows - 1 line.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = "4 windows - 1 line.jpg"; sourceTree = "<group>"; };
@@ -64,6 +69,7 @@
D04BA2C7B51F68651B3C60E2 /* 6 windows - 1 line.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = "6 windows - 1 line.jpg"; sourceTree = "<group>"; }; D04BA2C7B51F68651B3C60E2 /* 6 windows - 1 line.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = "6 windows - 1 line.jpg"; sourceTree = "<group>"; };
D04BA2D2AD6B1CCA3F3A4DD7 /* SystemPermissions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SystemPermissions.swift; sourceTree = "<group>"; }; D04BA2D2AD6B1CCA3F3A4DD7 /* SystemPermissions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SystemPermissions.swift; sourceTree = "<group>"; };
D04BA2D2BCBA4C47E25315AF /* HyperlinkLabel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HyperlinkLabel.swift; sourceTree = "<group>"; }; D04BA2D2BCBA4C47E25315AF /* HyperlinkLabel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HyperlinkLabel.swift; sourceTree = "<group>"; };
D04BA30247D04CEEC2DACEA8 /* fr */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = fr; path = Localizable.strings; sourceTree = "<group>"; };
D04BA32F25860B686DFE818A /* 3 windows - 1 line.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = "3 windows - 1 line.jpg"; sourceTree = "<group>"; }; D04BA32F25860B686DFE818A /* 3 windows - 1 line.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = "3 windows - 1 line.jpg"; sourceTree = "<group>"; };
D04BA35456DA0DDA74F9687E /* Keyboard.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Keyboard.swift; sourceTree = "<group>"; }; D04BA35456DA0DDA74F9687E /* Keyboard.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Keyboard.swift; sourceTree = "<group>"; };
D04BA3915020FB9B34555D74 /* DebugProfile.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DebugProfile.swift; sourceTree = "<group>"; }; D04BA3915020FB9B34555D74 /* DebugProfile.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DebugProfile.swift; sourceTree = "<group>"; };
@@ -90,6 +96,7 @@
D04BA7B6AAB0812631BBC7A2 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.info; path = Info.plist; sourceTree = "<group>"; }; D04BA7B6AAB0812631BBC7A2 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.info; path = Info.plist; sourceTree = "<group>"; };
D04BA7ECCE728582D9ECA613 /* determine_version.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = determine_version.sh; sourceTree = "<group>"; }; D04BA7ECCE728582D9ECA613 /* determine_version.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = determine_version.sh; sourceTree = "<group>"; };
D04BA8011143819B48F204C2 /* TextArea.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextArea.swift; sourceTree = "<group>"; }; D04BA8011143819B48F204C2 /* TextArea.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextArea.swift; sourceTree = "<group>"; };
D04BA81CA2D9818FCA9E5024 /* fr */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = fr; path = InfoPlist.strings; sourceTree = "<group>"; };
D04BA82F792DF53958D92572 /* alt-tab-macos.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "alt-tab-macos.app"; sourceTree = BUILT_PRODUCTS_DIR; }; D04BA82F792DF53958D92572 /* alt-tab-macos.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "alt-tab-macos.app"; sourceTree = BUILT_PRODUCTS_DIR; };
D04BA896E37EFD27CAB61DF0 /* Sysctl.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Sysctl.swift; sourceTree = "<group>"; }; D04BA896E37EFD27CAB61DF0 /* Sysctl.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Sysctl.swift; sourceTree = "<group>"; };
D04BA89FAEC4A5734D892C4B /* build_release.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = build_release.sh; sourceTree = "<group>"; }; D04BA89FAEC4A5734D892C4B /* build_release.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = build_release.sh; sourceTree = "<group>"; };
@@ -116,6 +123,7 @@
D04BAD7D8F3CC2C36C8769C6 /* .travis.yml */ = {isa = PBXFileReference; lastKnownFileType = file.yml; path = .travis.yml; sourceTree = "<group>"; }; D04BAD7D8F3CC2C36C8769C6 /* .travis.yml */ = {isa = PBXFileReference; lastKnownFileType = file.yml; path = .travis.yml; sourceTree = "<group>"; };
D04BAD82F652C4ED5D8BF7AE /* 3 windows - 1 line - tall window.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = "3 windows - 1 line - tall window.jpg"; sourceTree = "<group>"; }; D04BAD82F652C4ED5D8BF7AE /* 3 windows - 1 line - tall window.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = "3 windows - 1 line - tall window.jpg"; sourceTree = "<group>"; };
D04BADB20AB31BF83593E0BE /* greetings.yml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.yaml; path = greetings.yml; sourceTree = "<group>"; }; D04BADB20AB31BF83593E0BE /* greetings.yml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.yaml; path = greetings.yml; sourceTree = "<group>"; };
D04BADBCA16C1D448D34F473 /* en */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = en; path = InfoPlist.strings; sourceTree = "<group>"; };
D04BADCB1C0F50340A6CAFC2 /* Preferences.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Preferences.swift; sourceTree = "<group>"; }; D04BADCB1C0F50340A6CAFC2 /* Preferences.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Preferences.swift; sourceTree = "<group>"; };
D04BAE1243C9B4BE3ED1B524 /* 7 windows - 2 lines - extra wide window.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = "7 windows - 2 lines - extra wide window.jpg"; sourceTree = "<group>"; }; D04BAE1243C9B4BE3ED1B524 /* 7 windows - 2 lines - extra wide window.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = "7 windows - 2 lines - extra wide window.jpg"; sourceTree = "<group>"; };
D04BAE23C37E0F3B07EEE7B1 /* AboutTab.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AboutTab.swift; sourceTree = "<group>"; }; D04BAE23C37E0F3B07EEE7B1 /* AboutTab.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AboutTab.swift; sourceTree = "<group>"; };
@@ -241,6 +249,7 @@
children = ( children = (
D04BABC654F40BE74DA25BC7 /* SF-Pro-Text-Regular.otf */, D04BABC654F40BE74DA25BC7 /* SF-Pro-Text-Regular.otf */,
D04BA7A48641612933710091 /* MainMenu.xib */, D04BA7A48641612933710091 /* MainMenu.xib */,
D04BAA62C61D1A8906274221 /* l10n */,
); );
path = resources; path = resources;
sourceTree = "<group>"; sourceTree = "<group>";
@@ -269,6 +278,15 @@
path = ci; path = ci;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
D04BA77FA515B70E5E5F2677 /* en.lproj */ = {
isa = PBXGroup;
children = (
D04BAEE5AEEB8692856B45E4 /* InfoPlist.strings */,
D04BAC0D42D7FED725746DA5 /* Localizable.strings */,
);
path = en.lproj;
sourceTree = "<group>";
};
D04BA8965B713BE52849AFAF /* generic-components */ = { D04BA8965B713BE52849AFAF /* generic-components */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
@@ -306,6 +324,15 @@
path = logic; path = logic;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
D04BAA62C61D1A8906274221 /* l10n */ = {
isa = PBXGroup;
children = (
D04BA77FA515B70E5E5F2677 /* en.lproj */,
D04BAF78C474CFE92FB844FA /* fr.lproj */,
);
path = l10n;
sourceTree = "<group>";
};
D04BAAA28315301A906DD201 /* ui */ = { D04BAAA28315301A906DD201 /* ui */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
@@ -370,6 +397,15 @@
path = workflows; path = workflows;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
D04BAF78C474CFE92FB844FA /* fr.lproj */ = {
isa = PBXGroup;
children = (
D04BA1ACE289DC4AD4826D1E /* InfoPlist.strings */,
D04BAE5FA03065C5D23C0C2C /* Localizable.strings */,
);
path = fr.lproj;
sourceTree = "<group>";
};
D04BAF7BAEB13280202194EC /* main-window */ = { D04BAF7BAEB13280202194EC /* main-window */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
@@ -412,11 +448,11 @@
}; };
buildConfigurationList = D04BA83C9495F252D87CDF0F /* Build configuration list for PBXProject "alt-tab-macos" */; buildConfigurationList = D04BA83C9495F252D87CDF0F /* Build configuration list for PBXProject "alt-tab-macos" */;
compatibilityVersion = "Xcode 3.2"; compatibilityVersion = "Xcode 3.2";
developmentRegion = English; developmentRegion = en;
hasScannedForEncodings = 0; hasScannedForEncodings = 0;
knownRegions = ( knownRegions = (
English,
en, en,
fr,
); );
mainGroup = D04BA1463D2A17038222BB84; mainGroup = D04BA1463D2A17038222BB84;
productRefGroup = D04BA1A461BBB5A9BE15E015 /* Products */; productRefGroup = D04BA1A461BBB5A9BE15E015 /* Products */;
@@ -435,6 +471,10 @@
files = ( files = (
D04BA8373D4DE452C0C081ED /* SF-Pro-Text-Regular.otf in Resources */, D04BA8373D4DE452C0C081ED /* SF-Pro-Text-Regular.otf in Resources */,
D04BA30F92801F5960ACC844 /* MainMenu.xib in Resources */, D04BA30F92801F5960ACC844 /* MainMenu.xib in Resources */,
D04BA79B891E9C89C015D6DD /* InfoPlist.strings in Resources */,
D04BAA0F39E6160F5703FC33 /* Localizable.strings in Resources */,
D04BAD1158CBCC76DE321555 /* InfoPlist.strings in Resources */,
D04BAEAB8AB048FF2B16B131 /* Localizable.strings in Resources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@@ -489,6 +529,41 @@
}; };
/* End PBXSourcesBuildPhase section */ /* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
D04BA1ACE289DC4AD4826D1E /* InfoPlist.strings */ = {
isa = PBXVariantGroup;
children = (
D04BA81CA2D9818FCA9E5024 /* fr */,
);
name = InfoPlist.strings;
sourceTree = "<group>";
};
D04BAC0D42D7FED725746DA5 /* Localizable.strings */ = {
isa = PBXVariantGroup;
children = (
D04BA05F3F36A6D71DCD8475 /* en */,
);
name = Localizable.strings;
sourceTree = "<group>";
};
D04BAE5FA03065C5D23C0C2C /* Localizable.strings */ = {
isa = PBXVariantGroup;
children = (
D04BA30247D04CEEC2DACEA8 /* fr */,
);
name = Localizable.strings;
sourceTree = "<group>";
};
D04BAEE5AEEB8692856B45E4 /* InfoPlist.strings */ = {
isa = PBXVariantGroup;
children = (
D04BADBCA16C1D448D34F473 /* en */,
);
name = InfoPlist.strings;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */ /* Begin XCBuildConfiguration section */
D04BA49BCED00029C5289244 /* Release */ = { D04BA49BCED00029C5289244 /* Release */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
@@ -496,12 +571,10 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_ENTITLEMENTS = "alt-tab-macos/alt_tab_macos.entitlements"; CODE_SIGN_ENTITLEMENTS = "alt-tab-macos/alt_tab_macos.entitlements";
CODE_SIGN_IDENTITY = "Local Self-Signed"; CODE_SIGN_IDENTITY = "Local Self-Signed";
COMBINE_HIDPI_IMAGES = YES;
ENABLE_HARDENED_RUNTIME = YES; ENABLE_HARDENED_RUNTIME = YES;
FRAMEWORK_SEARCH_PATHS = /System/Library/PrivateFrameworks; FRAMEWORK_SEARCH_PATHS = /System/Library/PrivateFrameworks;
INFOPLIST_FILE = "alt-tab-macos/Info.plist"; INFOPLIST_FILE = "alt-tab-macos/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
MACOSX_DEPLOYMENT_TARGET = 10.12;
PRODUCT_BUNDLE_IDENTIFIER = "com.lwouis.alt-tab-macos"; PRODUCT_BUNDLE_IDENTIFIER = "com.lwouis.alt-tab-macos";
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 4.2; SWIFT_VERSION = 4.2;
@@ -514,12 +587,10 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_ENTITLEMENTS = "alt-tab-macos/alt_tab_macos.entitlements"; CODE_SIGN_ENTITLEMENTS = "alt-tab-macos/alt_tab_macos.entitlements";
CODE_SIGN_IDENTITY = "Local Self-Signed"; CODE_SIGN_IDENTITY = "Local Self-Signed";
COMBINE_HIDPI_IMAGES = YES;
ENABLE_HARDENED_RUNTIME = YES; ENABLE_HARDENED_RUNTIME = YES;
FRAMEWORK_SEARCH_PATHS = /System/Library/PrivateFrameworks; FRAMEWORK_SEARCH_PATHS = /System/Library/PrivateFrameworks;
INFOPLIST_FILE = "alt-tab-macos/Info.plist"; INFOPLIST_FILE = "alt-tab-macos/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
MACOSX_DEPLOYMENT_TARGET = 10.12;
PRODUCT_BUNDLE_IDENTIFIER = "com.lwouis.alt-tab-macos"; PRODUCT_BUNDLE_IDENTIFIER = "com.lwouis.alt-tab-macos";
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 4.2; SWIFT_VERSION = 4.2;
@@ -576,7 +647,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.14; MACOSX_DEPLOYMENT_TARGET = 10.12;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES; MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES; ONLY_ACTIVE_ARCH = YES;
@@ -630,7 +701,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.14; MACOSX_DEPLOYMENT_TARGET = 10.12;
MTL_ENABLE_DEBUG_INFO = NO; MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES; MTL_FAST_MATH = YES;
SDKROOT = macosx; SDKROOT = macosx;
+1 -1
View File
@@ -3,7 +3,7 @@
<plist version="1.0"> <plist version="1.0">
<dict> <dict>
<key>CFBundleDevelopmentRegion</key> <key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string> <string>en</string>
<key>CFBundleExecutable</key> <key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string> <string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIconFile</key> <key>CFBundleIconFile</key>
@@ -0,0 +1,5 @@
/* Bundle name */
"CFBundleName" = "alt-tab-macos";
/* Copyright (human-readable) */
"NSHumanReadableCopyright" = "GPL-3.0 license";
@@ -0,0 +1,6 @@
/* Bundle name */
"CFBundleName" = "alt-tab-macos";
/* Copyright (human-readable) */
"NSHumanReadableCopyright" = "Licence GPL-3.0";
@@ -0,0 +1,102 @@
/* No comment provided by engineer. */
"About" = "À propos";
/* No comment provided by engineer. */
"Alt key" = "Touche Alt";
/* No comment provided by engineer. */
"Apparition delay" = "Délai d'apparition";
/* No comment provided by engineer. */
"Appearance" = "Apparence";
/* No comment provided by engineer. */
"Cancel" = "Annuler";
/* No comment provided by engineer. */
"Check again" = "Essayer encore";
/* No comment provided by engineer. */
"Could not save Preference" = "La préférence n’a pas pu être sauvée";
/* No comment provided by engineer. */
"Edit" = "Éditer";
/* No comment provided by engineer. */
"Hide space number labels" = "Cacher les numéraux des Espaces";
/* No comment provided by engineer. */
"I think the app could be improved with…" = "Je pense que l’app pourrait être améliorée avec…";
/* No comment provided by engineer. */
"KeyCodes Reference" = "Référence des codes de touche";
/* No comment provided by engineer. */
"Latest releases" = "Dernières versions";
/* No comment provided by engineer. */
"Max size on screen" = "Taille max à l’écran";
/* No comment provided by engineer. */
"Max windows per row" = "Max de fenêtres par ligne";
/* No comment provided by engineer. */
"Min rows of windows" = "Min de lignes de fenêtres";
/* No comment provided by engineer. */
"Min windows per row" = "Min de fenêtres par ligne";
/* No comment provided by engineer. */
"Optional: email (if you want a reply)" = "Optionnel: email (si vous voulez une réponse)";
/* No comment provided by engineer. */
"Preferences…" = "Préférences…";
/* No comment provided by engineer. */
"Quit" = "Quitter";
/* No comment provided by engineer. */
"Send" = "Envoyer";
/* No comment provided by engineer. */
"Send debug profile (CPU, memory, etc)" = "Envoyer un profile technique (processeur, mémoire, etc)";
/* No comment provided by engineer. */
"Send feedback" = "Partager un retour d’expérience";
/* No comment provided by engineer. */
"Send feedback…" = "Partager un retour d’expérience…";
/* No comment provided by engineer. */
"Share improvement ideas, or report bugs" = "Partagez des idées d’amélioration, ou signalez des bugs";
/* No comment provided by engineer. */
"Shortcuts" = "Raccourcis";
/* No comment provided by engineer. */
"Show" = "Afficher";
/* No comment provided by engineer. */
"Show on" = "Afficher sur";
/* No comment provided by engineer. */
"Source code repository" = "Repo du code source";
/* No comment provided by engineer. */
"Tab key" = "Touche Tab";
/* No comment provided by engineer. */
"Theme" = "Thème";
/* No comment provided by engineer. */
"Version " = "Version ";
/* No comment provided by engineer. */
"View existing discussions" = "Voir les discussions existantes";
/* No comment provided by engineer. */
"Window app icon size" = "Taille des icones des applications";
/* No comment provided by engineer. */
"Window title font size" = "Taille du titres des fenêtres";
+8 -8
View File
@@ -18,7 +18,7 @@ class FeedbackWindow: NSWindow {
} }
private func setupWindow() { private func setupWindow() {
title = "Send feedback" title = NSLocalizedString("Send feedback", comment: "")
hidesOnDeactivate = false hidesOnDeactivate = false
isReleasedWhenClosed = false isReleasedWhenClosed = false
styleMask.insert([.miniaturizable, .closable]) styleMask.insert([.miniaturizable, .closable])
@@ -28,27 +28,27 @@ class FeedbackWindow: NSWindow {
let appIcon = NSImageView(image: App.shared.applicationIconImage) let appIcon = NSImageView(image: App.shared.applicationIconImage)
appIcon.fit(80, 80) appIcon.fit(80, 80)
let appText = NSStackView(views: [ let appText = NSStackView(views: [
BoldLabel("Share improvement ideas, or report bugs"), BoldLabel(NSLocalizedString("Share improvement ideas, or report bugs", comment: "")),
HyperlinkLabel("View existing discussions", App.repository + "/issues"), HyperlinkLabel(NSLocalizedString("View existing discussions", comment: ""), App.repository + "/issues"),
]) ])
appText.orientation = .vertical appText.orientation = .vertical
appText.alignment = .left appText.alignment = .left
appText.spacing = GridView.interPadding / 2 appText.spacing = GridView.interPadding / 2
let header = NSStackView(views: [appIcon, appText]) let header = NSStackView(views: [appIcon, appText])
header.spacing = GridView.interPadding header.spacing = GridView.interPadding
sendButton = NSButton(title: "Send", target: nil, action: #selector(sendCallback)) sendButton = NSButton(title: NSLocalizedString("Send", comment: ""), target: nil, action: #selector(sendCallback))
sendButton.keyEquivalent = "\r" sendButton.keyEquivalent = "\r"
sendButton.isEnabled = false sendButton.isEnabled = false
let buttons = NSStackView(views: [ let buttons = NSStackView(views: [
NSButton(title: "Cancel", target: nil, action: #selector(cancelCallback)), NSButton(title: NSLocalizedString("Cancel", comment: ""), target: nil, action: #selector(cancelCallback)),
sendButton, sendButton,
]) ])
buttons.spacing = GridView.interPadding buttons.spacing = GridView.interPadding
body = TextArea(80, 12, "I think the app could be improved with…", { body = TextArea(80, 12, NSLocalizedString("I think the app could be improved with…", comment: ""), {
self.sendButton.isEnabled = !self.body.stringValue.isEmpty self.sendButton.isEnabled = !self.body.stringValue.isEmpty
}) })
email = TextArea(80, 1, "Optional: email (if you want a reply)") email = TextArea(80, 1, NSLocalizedString("Optional: email (if you want a reply)", comment: ""))
debugProfile = NSButton(checkboxWithTitle: "Send debug profile (CPU, memory, etc)", target: nil, action: nil) debugProfile = NSButton(checkboxWithTitle: NSLocalizedString("Send debug profile (CPU, memory, etc)", comment: ""), target: nil, action: nil)
debugProfile.state = .on debugProfile.state = .on
let view = GridView.make([ let view = GridView.make([
[header], [header],
+4 -4
View File
@@ -6,21 +6,21 @@ class Menubar {
item.button!.title = "AltTab" item.button!.title = "AltTab"
item.menu = NSMenu() item.menu = NSMenu()
item.menu!.addItem( item.menu!.addItem(
withTitle: "Show", withTitle: NSLocalizedString("Show", comment: ""),
action: #selector(app.showUi), action: #selector(app.showUi),
keyEquivalent: "s" keyEquivalent: "s"
) )
item.menu!.addItem( item.menu!.addItem(
withTitle: "Preferences…", withTitle: NSLocalizedString("Preferences…", comment: ""),
action: #selector(app.showPreferencesPanel), action: #selector(app.showPreferencesPanel),
keyEquivalent: ",") keyEquivalent: ",")
item.menu!.addItem( item.menu!.addItem(
withTitle: "Send feedback…", withTitle: NSLocalizedString("Send feedback…", comment: ""),
action: #selector(app.showFeedbackPanel), action: #selector(app.showFeedbackPanel),
keyEquivalent: ",") keyEquivalent: ",")
item.menu!.addItem(NSMenuItem.separator()) item.menu!.addItem(NSMenuItem.separator())
item.menu!.addItem( item.menu!.addItem(
withTitle: "Quit \(App.name)", withTitle: NSLocalizedString("Quit", comment: "") + " " + App.name,
action: #selector(NSApplication.terminate(_:)), action: #selector(NSApplication.terminate(_:)),
keyEquivalent: "q") keyEquivalent: "q")
return item return item
@@ -72,11 +72,11 @@ class PreferencesWindow: NSWindow {
private func showSaveErrorSheetModal(_ nsError: NSError, _ control: NSControl, _ key: String, _ previousValue: String) { private func showSaveErrorSheetModal(_ nsError: NSError, _ control: NSControl, _ key: String, _ previousValue: String) {
let alert = NSAlert() let alert = NSAlert()
alert.messageText = "Could not save Preference" alert.messageText = NSLocalizedString("Could not save Preference", comment: "")
alert.informativeText = nsError.localizedDescription + "\n" alert.informativeText = nsError.localizedDescription + "\n"
alert.addButton(withTitle: "Edit") alert.addButton(withTitle: NSLocalizedString("Edit", comment: ""))
alert.addButton(withTitle: "Cancel") alert.addButton(withTitle: NSLocalizedString("Cancel", comment: ""))
alert.addButton(withTitle: "Check again") alert.addButton(withTitle: NSLocalizedString("Check again", comment: ""))
alert.beginSheetModal(for: self, completionHandler: { (modalResponse: NSApplication.ModalResponse) -> Void in alert.beginSheetModal(for: self, completionHandler: { (modalResponse: NSApplication.ModalResponse) -> Void in
if modalResponse == NSApplication.ModalResponse.alertFirstButtonReturn { if modalResponse == NSApplication.ModalResponse.alertFirstButtonReturn {
@@ -2,7 +2,7 @@ import Cocoa
class AboutTab: NSObject { class AboutTab: NSObject {
static func make() -> NSTabViewItem { static func make() -> NSTabViewItem {
return TabViewItem.make("About", NSImage.infoName, makeView()) return TabViewItem.make(NSLocalizedString("About", comment: ""), NSImage.infoName, makeView())
} }
static func makeView() -> NSGridView { static func makeView() -> NSGridView {
@@ -10,10 +10,10 @@ class AboutTab: NSObject {
appIcon.fit(150, 150) appIcon.fit(150, 150)
let appText = NSStackView(views: [ let appText = NSStackView(views: [
BoldLabel(App.name), BoldLabel(App.name),
NSTextField(wrappingLabelWithString: "Version " + App.version), NSTextField(wrappingLabelWithString: NSLocalizedString("Version ", comment: "") + App.version),
NSTextField(wrappingLabelWithString: App.licence), NSTextField(wrappingLabelWithString: App.licence),
HyperlinkLabel("Source code repository", App.repository), HyperlinkLabel(NSLocalizedString("Source code repository", comment: ""), App.repository),
HyperlinkLabel("Latest releases", App.repository + "/releases"), HyperlinkLabel(NSLocalizedString("Latest releases", comment: ""), App.repository + "/releases"),
]) ])
appText.orientation = .vertical appText.orientation = .vertical
appText.alignment = .left appText.alignment = .left
@@ -24,7 +24,7 @@ class AboutTab: NSObject {
appInfo.spacing = GridView.interPadding appInfo.spacing = GridView.interPadding
let view = GridView.make([ let view = GridView.make([
[appInfo], [appInfo],
[NSButton(title: "Send feedback", target: self, action: #selector(feedbackCallback))], [NSButton(title: NSLocalizedString("Send feedback", comment: ""), target: self, action: #selector(feedbackCallback))],
]) ])
view.row(at: 1).topPadding = GridView.interPadding * 2 view.row(at: 1).topPadding = GridView.interPadding * 2
view.cell(atColumnIndex: 0, rowIndex: 1).xPlacement = .center view.cell(atColumnIndex: 0, rowIndex: 1).xPlacement = .center
@@ -4,21 +4,21 @@ class AppearanceTab {
private static let rowHeight = CGFloat(20) private static let rowHeight = CGFloat(20)
static func make() -> NSTabViewItem { static func make() -> NSTabViewItem {
return TabViewItem.make("Shortcuts", NSImage.colorPanelName, makeView()) return TabViewItem.make(NSLocalizedString("Appearance", comment: ""), NSImage.colorPanelName, makeView())
} }
private static func makeView() -> NSGridView { private static func makeView() -> NSGridView {
let view = GridView.make([ let view = GridView.make([
LabelAndControl.makeLabelWithDropdown("Theme", "theme", Preferences.themeMacro.labels), LabelAndControl.makeLabelWithDropdown(NSLocalizedString("Theme", comment: ""), "theme", Preferences.themeMacro.labels),
LabelAndControl.makeLabelWithSlider("Max size on screen", "maxScreenUsage", 10, 100, 10, true, "%"), LabelAndControl.makeLabelWithSlider(NSLocalizedString("Max size on screen", comment: ""), "maxScreenUsage", 10, 100, 10, true, "%"),
LabelAndControl.makeLabelWithSlider("Min windows per row", "minCellsPerRow", 1, 20, 20, true), LabelAndControl.makeLabelWithSlider(NSLocalizedString("Min windows per row", comment: ""), "minCellsPerRow", 1, 20, 20, true),
LabelAndControl.makeLabelWithSlider("Max windows per row", "maxCellsPerRow", 1, 40, 20, true), LabelAndControl.makeLabelWithSlider(NSLocalizedString("Max windows per row", comment: ""), "maxCellsPerRow", 1, 40, 20, true),
LabelAndControl.makeLabelWithSlider("Min rows of windows", "minRows", 1, 20, 20, true), LabelAndControl.makeLabelWithSlider(NSLocalizedString("Min rows of windows", comment: ""), "minRows", 1, 20, 20, true),
LabelAndControl.makeLabelWithSlider("Window app icon size", "iconSize", 0, 64, 11, false, "px"), LabelAndControl.makeLabelWithSlider(NSLocalizedString("Window app icon size", comment: ""), "iconSize", 0, 64, 11, false, "px"),
LabelAndControl.makeLabelWithSlider("Window title font size", "fontHeight", 0, 64, 11, false, "px"), LabelAndControl.makeLabelWithSlider(NSLocalizedString("Window title font size", comment: ""), "fontHeight", 0, 64, 11, false, "px"),
LabelAndControl.makeLabelWithDropdown("Show on", "showOnScreen", Preferences.showOnScreenMacro.labels), LabelAndControl.makeLabelWithDropdown(NSLocalizedString("Show on", comment: ""), "showOnScreen", Preferences.showOnScreenMacro.labels),
LabelAndControl.makeLabelWithSlider("Apparition delay", "windowDisplayDelay", 0, 2000, 11, false, "ms"), LabelAndControl.makeLabelWithSlider(NSLocalizedString("Apparition delay", comment: ""), "windowDisplayDelay", 0, 2000, 11, false, "ms"),
LabelAndControl.makeLabelWithCheckbox("Hide space number labels", "hideSpaceNumberLabels"), LabelAndControl.makeLabelWithCheckbox(NSLocalizedString("Hide space number labels", comment: ""), "hideSpaceNumberLabels"),
]) ])
view.column(at: 0).xPlacement = .trailing view.column(at: 0).xPlacement = .trailing
view.rowAlignment = .lastBaseline view.rowAlignment = .lastBaseline
@@ -4,7 +4,7 @@ class ShortcutsTab {
private static let rowHeight = CGFloat(20) private static let rowHeight = CGFloat(20)
static func make() -> NSTabViewItem { static func make() -> NSTabViewItem {
return TabViewItem.make("Appearance", NSImage.preferencesGeneralName, makeView()) return TabViewItem.make(NSLocalizedString("Shortcuts", comment: ""), NSImage.preferencesGeneralName, makeView())
} }
private static func makeView() -> NSGridView { // TODO: make the validators be a part of each Preference private static func makeView() -> NSGridView { // TODO: make the validators be a part of each Preference
@@ -22,8 +22,8 @@ class ShortcutsTab {
} }
let view = GridView.make([ let view = GridView.make([
LabelAndControl.makeLabelWithDropdown("Alt key", "metaKey", Preferences.metaKeyMacro.labels), LabelAndControl.makeLabelWithDropdown(NSLocalizedString("Alt key", comment: ""), "metaKey", Preferences.metaKeyMacro.labels),
LabelAndControl.makeLabelWithInput("Tab key", "tabKeyCode", 33, "KeyCodes Reference", "https://eastmanreference.com/complete-list-of-applescript-key-codes", tabKeyCodeValidator), LabelAndControl.makeLabelWithInput(NSLocalizedString("Tab key", comment: ""), "tabKeyCode", 33, NSLocalizedString("KeyCodes Reference", comment: ""), "https://eastmanreference.com/complete-list-of-applescript-key-codes", tabKeyCodeValidator),
]) ])
view.column(at: 0).xPlacement = .trailing view.column(at: 0).xPlacement = .trailing
view.rowAlignment = .lastBaseline view.rowAlignment = .lastBaseline