├── .github ├── FUNDING.yml └── workflows │ └── ci-mac.yaml ├── .gitignore ├── .gitmodules ├── Assets ├── Icon.psd └── Screenshot.png ├── CODE_OF_CONDUCT.md ├── LICENSE ├── README.md ├── Sensors.xcodeproj ├── project.pbxproj └── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ └── IDEWorkspaceChecks.plist ├── Sensors ├── Base.lproj │ └── MainMenu.xib ├── Classes │ ├── AboutWindowController.swift │ ├── ApplicationDelegate.swift │ └── Base.lproj │ │ └── AboutWindowController.xib ├── Icon.icns ├── Info.plist └── Sensors.entitlements ├── SensorsUI.xcodeproj ├── project.pbxproj └── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ └── IDEWorkspaceChecks.plist └── SensorsUI ├── ArrayIsEmpty.swift ├── ArrayIsNotEmpty.swift ├── Base.lproj ├── SensorItem.xib └── SensorsWindowController.xib ├── Colors.swift ├── Images ├── AmbiantLightTemplate.pdf ├── CurrentTemplate.pdf ├── ThermalTemplate.pdf └── VoltageTemplate.pdf ├── NSImage.swift ├── SensorGraphView.swift ├── SensorIcon.swift ├── SensorItem.swift ├── SensorValue.swift └── SensorsWindowController.swift /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: macmade 2 | -------------------------------------------------------------------------------- /.github/workflows/ci-mac.yaml: -------------------------------------------------------------------------------- 1 | name: ci-mac 2 | on: [push] 3 | jobs: 4 | ci: 5 | runs-on: macos-latest 6 | strategy: 7 | matrix: 8 | run-config: 9 | - { scheme: 'Sensors', configuration: 'Debug', project: 'Sensors.xcodeproj', build: 1, analyze: 1, test: 0, info: 1, destination: 'platform=macOS' } 10 | - { scheme: 'Sensors', configuration: 'Release', project: 'Sensors.xcodeproj', build: 1, analyze: 1, test: 0, info: 1, destination: 'platform=macOS' } 11 | steps: 12 | 13 | - uses: actions/checkout@v1 14 | with: 15 | submodules: 'recursive' 16 | 17 | - uses: macmade/action-xcodebuild@v1.0.0 18 | 19 | - uses: macmade/action-slack@v1.0.0 20 | if: ${{ always() }} 21 | env: 22 | SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} 23 | with: 24 | channel: '#ci' 25 | status: ${{ job.status }} 26 | title: ${{ matrix.run-config[ 'scheme' ] }} - ${{ matrix.run-config[ 'configuration' ] }} 27 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Mac Finder 2 | .DS_Store 3 | .Trashes 4 | Icon? 5 | 6 | # Thumbnails 7 | ._* 8 | 9 | # Files that might appear on external disk 10 | .Spotlight-V100 11 | .Trashes 12 | 13 | # Xcode 14 | *.pbxuser 15 | *.mode1v3 16 | *.mode2v3 17 | *.perspectivev3 18 | *.xccheckout 19 | *.profraw 20 | !default.pbxuser 21 | !default.mode1v3 22 | !default.mode2v3 23 | !default.perspectivev3 24 | xcuserdata 25 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "Submodules/xcconfig"] 2 | path = Submodules/xcconfig 3 | url = https://github.com/macmade/xcconfig.git 4 | [submodule "Submodules/GitHubUpdates"] 5 | path = Submodules/GitHubUpdates 6 | url = https://github.com/macmade/GitHubUpdates.git 7 | [submodule "Submodules/SensorsKit"] 8 | path = Submodules/SensorsKit 9 | url = https://github.com/macmade/SensorsKit.git 10 | -------------------------------------------------------------------------------- /Assets/Icon.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macmade/Sensors/d49fe30dce55c5cf7862e711dc3629cfd0fcb05d/Assets/Icon.psd -------------------------------------------------------------------------------- /Assets/Screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macmade/Sensors/d49fe30dce55c5cf7862e711dc3629cfd0fcb05d/Assets/Screenshot.png -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | We as members, contributors, and leaders pledge to make participation in our 6 | community a harassment-free experience for everyone, regardless of age, body 7 | size, visible or invisible disability, ethnicity, sex characteristics, gender 8 | identity and expression, level of experience, education, socio-economic status, 9 | nationality, personal appearance, race, religion, or sexual identity 10 | and orientation. 11 | 12 | We pledge to act and interact in ways that contribute to an open, welcoming, 13 | diverse, inclusive, and healthy community. 14 | 15 | ## Our Standards 16 | 17 | Examples of behavior that contributes to a positive environment for our 18 | community include: 19 | 20 | * Demonstrating empathy and kindness toward other people 21 | * Being respectful of differing opinions, viewpoints, and experiences 22 | * Giving and gracefully accepting constructive feedback 23 | * Accepting responsibility and apologizing to those affected by our mistakes, 24 | and learning from the experience 25 | * Focusing on what is best not just for us as individuals, but for the 26 | overall community 27 | 28 | Examples of unacceptable behavior include: 29 | 30 | * The use of sexualized language or imagery, and sexual attention or 31 | advances of any kind 32 | * Trolling, insulting or derogatory comments, and personal or political attacks 33 | * Public or private harassment 34 | * Publishing others' private information, such as a physical or email 35 | address, without their explicit permission 36 | * Other conduct which could reasonably be considered inappropriate in a 37 | professional setting 38 | 39 | ## Enforcement Responsibilities 40 | 41 | Community leaders are responsible for clarifying and enforcing our standards of 42 | acceptable behavior and will take appropriate and fair corrective action in 43 | response to any behavior that they deem inappropriate, threatening, offensive, 44 | or harmful. 45 | 46 | Community leaders have the right and responsibility to remove, edit, or reject 47 | comments, commits, code, wiki edits, issues, and other contributions that are 48 | not aligned to this Code of Conduct, and will communicate reasons for moderation 49 | decisions when appropriate. 50 | 51 | ## Scope 52 | 53 | This Code of Conduct applies within all community spaces, and also applies when 54 | an individual is officially representing the community in public spaces. 55 | Examples of representing our community include using an official e-mail address, 56 | posting via an official social media account, or acting as an appointed 57 | representative at an online or offline event. 58 | 59 | ## Enforcement 60 | 61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 62 | reported to the community leaders responsible for enforcement at 63 | xs-labs.com. 64 | All complaints will be reviewed and investigated promptly and fairly. 65 | 66 | All community leaders are obligated to respect the privacy and security of the 67 | reporter of any incident. 68 | 69 | ## Enforcement Guidelines 70 | 71 | Community leaders will follow these Community Impact Guidelines in determining 72 | the consequences for any action they deem in violation of this Code of Conduct: 73 | 74 | ### 1. Correction 75 | 76 | **Community Impact**: Use of inappropriate language or other behavior deemed 77 | unprofessional or unwelcome in the community. 78 | 79 | **Consequence**: A private, written warning from community leaders, providing 80 | clarity around the nature of the violation and an explanation of why the 81 | behavior was inappropriate. A public apology may be requested. 82 | 83 | ### 2. Warning 84 | 85 | **Community Impact**: A violation through a single incident or series 86 | of actions. 87 | 88 | **Consequence**: A warning with consequences for continued behavior. No 89 | interaction with the people involved, including unsolicited interaction with 90 | those enforcing the Code of Conduct, for a specified period of time. This 91 | includes avoiding interactions in community spaces as well as external channels 92 | like social media. Violating these terms may lead to a temporary or 93 | permanent ban. 94 | 95 | ### 3. Temporary Ban 96 | 97 | **Community Impact**: A serious violation of community standards, including 98 | sustained inappropriate behavior. 99 | 100 | **Consequence**: A temporary ban from any sort of interaction or public 101 | communication with the community for a specified period of time. No public or 102 | private interaction with the people involved, including unsolicited interaction 103 | with those enforcing the Code of Conduct, is allowed during this period. 104 | Violating these terms may lead to a permanent ban. 105 | 106 | ### 4. Permanent Ban 107 | 108 | **Community Impact**: Demonstrating a pattern of violation of community 109 | standards, including sustained inappropriate behavior, harassment of an 110 | individual, or aggression toward or disparagement of classes of individuals. 111 | 112 | **Consequence**: A permanent ban from any sort of public interaction within 113 | the community. 114 | 115 | ## Attribution 116 | 117 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 118 | version 2.0, available at 119 | https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. 120 | 121 | Community Impact Guidelines were inspired by [Mozilla's code of conduct 122 | enforcement ladder](https://github.com/mozilla/diversity). 123 | 124 | [homepage]: https://www.contributor-covenant.org 125 | 126 | For answers to common questions about this code of conduct, see the FAQ at 127 | https://www.contributor-covenant.org/faq. Translations are available at 128 | https://www.contributor-covenant.org/translations. 129 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2021 Jean-David Gadina - www.xs-labs.com 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Sensors 2 | ======= 3 | 4 | [![Build Status](https://img.shields.io/github/actions/workflow/status/macmade/Sensors/ci-mac.yaml?label=macOS&logo=apple)](https://github.com/macmade/Sensors/actions/workflows/ci-mac.yaml) 5 | [![Issues](http://img.shields.io/github/issues/macmade/Sensors.svg?logo=github)](https://github.com/macmade/Sensors/issues) 6 | ![Status](https://img.shields.io/badge/status-active-brightgreen.svg?logo=git) 7 | ![License](https://img.shields.io/badge/license-mit-brightgreen.svg?logo=open-source-initiative) 8 | [![Contact](https://img.shields.io/badge/follow-@macmade-blue.svg?logo=twitter&style=social)](https://twitter.com/macmade) 9 | [![Sponsor](https://img.shields.io/badge/sponsor-macmade-pink.svg?logo=github-sponsors&style=social)](https://github.com/sponsors/macmade) 10 | 11 | ### About 12 | 13 | A macOS application displaying the thermal, voltage and current sensor values. 14 | 15 | ![Menu](Assets/Screenshot.png "Menu") 16 | 17 | License 18 | ------- 19 | 20 | Project is released under the terms of the MIT License. 21 | 22 | Repository Infos 23 | ---------------- 24 | 25 | Owner: Jean-David Gadina - XS-Labs 26 | Web: www.xs-labs.com 27 | Blog: www.noxeos.com 28 | Twitter: @macmade 29 | GitHub: github.com/macmade 30 | LinkedIn: ch.linkedin.com/in/macmade/ 31 | StackOverflow: stackoverflow.com/users/182676/macmade 32 | -------------------------------------------------------------------------------- /Sensors.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 54; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 05646BB42685020A00707676 /* ApplicationDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05646BAF2685020A00707676 /* ApplicationDelegate.swift */; }; 11 | 05646BB52685020A00707676 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 05646BB12685020A00707676 /* MainMenu.xib */; }; 12 | 05646BEF2685055F00707676 /* AboutWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05646BEE2685055F00707676 /* AboutWindowController.swift */; }; 13 | 05646BF22685058700707676 /* AboutWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 05646BF02685058700707676 /* AboutWindowController.xib */; }; 14 | 0566B9622686B48E006EE45A /* Icon.icns in Resources */ = {isa = PBXBuildFile; fileRef = 0566B9612686B48E006EE45A /* Icon.icns */; }; 15 | 0566B96D2686B531006EE45A /* GitHubUpdates.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0566B9692686B526006EE45A /* GitHubUpdates.framework */; }; 16 | 0566B96E2686B531006EE45A /* GitHubUpdates.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 0566B9692686B526006EE45A /* GitHubUpdates.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 17 | 058B8ED32994394200263FE9 /* SensorsUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 058B8ED12994392E00263FE9 /* SensorsUI.framework */; }; 18 | 058B8ED42994394200263FE9 /* SensorsUI.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 058B8ED12994392E00263FE9 /* SensorsUI.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 19 | /* End PBXBuildFile section */ 20 | 21 | /* Begin PBXContainerItemProxy section */ 22 | 0566B9682686B526006EE45A /* PBXContainerItemProxy */ = { 23 | isa = PBXContainerItemProxy; 24 | containerPortal = 0566B9632686B526006EE45A /* GitHubUpdates.xcodeproj */; 25 | proxyType = 2; 26 | remoteGlobalIDString = 05F82B251EF32EA700EC8A93; 27 | remoteInfo = GitHubUpdates; 28 | }; 29 | 0566B96A2686B526006EE45A /* PBXContainerItemProxy */ = { 30 | isa = PBXContainerItemProxy; 31 | containerPortal = 0566B9632686B526006EE45A /* GitHubUpdates.xcodeproj */; 32 | proxyType = 2; 33 | remoteGlobalIDString = 0555EBA01EF3DDA10016167F; 34 | remoteInfo = Relauncher; 35 | }; 36 | 058B8ED02994392E00263FE9 /* PBXContainerItemProxy */ = { 37 | isa = PBXContainerItemProxy; 38 | containerPortal = 058B8EC82994392E00263FE9 /* SensorsUI.xcodeproj */; 39 | proxyType = 2; 40 | remoteGlobalIDString = 058B8EA22994383300263FE9; 41 | remoteInfo = SensorsUI; 42 | }; 43 | /* End PBXContainerItemProxy section */ 44 | 45 | /* Begin PBXCopyFilesBuildPhase section */ 46 | 0566B96F2686B531006EE45A /* Embed Frameworks */ = { 47 | isa = PBXCopyFilesBuildPhase; 48 | buildActionMask = 2147483647; 49 | dstPath = ""; 50 | dstSubfolderSpec = 10; 51 | files = ( 52 | 058B8ED42994394200263FE9 /* SensorsUI.framework in Embed Frameworks */, 53 | 0566B96E2686B531006EE45A /* GitHubUpdates.framework in Embed Frameworks */, 54 | ); 55 | name = "Embed Frameworks"; 56 | runOnlyForDeploymentPostprocessing = 0; 57 | }; 58 | /* End PBXCopyFilesBuildPhase section */ 59 | 60 | /* Begin PBXFileReference section */ 61 | 05646B9A268501B300707676 /* Sensors.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Sensors.app; sourceTree = BUILT_PRODUCTS_DIR; }; 62 | 05646BA4268501B400707676 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 63 | 05646BA5268501B400707676 /* Sensors.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Sensors.entitlements; sourceTree = ""; }; 64 | 05646BAF2685020A00707676 /* ApplicationDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ApplicationDelegate.swift; sourceTree = ""; }; 65 | 05646BB22685020A00707676 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; 66 | 05646BB8268503D300707676 /* Release - ccache.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Release - ccache.xcconfig"; sourceTree = ""; }; 67 | 05646BB9268503D300707676 /* Common.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Common.xcconfig; sourceTree = ""; }; 68 | 05646BBA268503D300707676 /* Debug - ccache.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Debug - ccache.xcconfig"; sourceTree = ""; }; 69 | 05646BBB268503D300707676 /* Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; }; 70 | 05646BBC268503D300707676 /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = ""; }; 71 | 05646BBD268503D300707676 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; 72 | 05646BBE268503D300707676 /* Release - Library.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Release - Library.xcconfig"; sourceTree = ""; }; 73 | 05646BC0268503D300707676 /* Signing.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Signing.xcconfig; sourceTree = ""; }; 74 | 05646BC1268503D300707676 /* Architectures.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Architectures.xcconfig; sourceTree = ""; }; 75 | 05646BC3268503D300707676 /* Issues.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Issues.xcconfig; sourceTree = ""; }; 76 | 05646BC5268503D300707676 /* Apple-APIs.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Apple-APIs.xcconfig"; sourceTree = ""; }; 77 | 05646BC6268503D300707676 /* Generic-Issues.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Generic-Issues.xcconfig"; sourceTree = ""; }; 78 | 05646BC7268503D300707676 /* Security.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Security.xcconfig; sourceTree = ""; }; 79 | 05646BC8268503D300707676 /* Objective-C.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Objective-C.xcconfig"; sourceTree = ""; }; 80 | 05646BC9268503D300707676 /* Analysis-Policy.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Analysis-Policy.xcconfig"; sourceTree = ""; }; 81 | 05646BCA268503D300707676 /* Deployment.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Deployment.xcconfig; sourceTree = ""; }; 82 | 05646BCB268503D300707676 /* Build-Options.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Build-Options.xcconfig"; sourceTree = ""; }; 83 | 05646BCC268503D300707676 /* Swift-Compiler.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Swift-Compiler.xcconfig"; sourceTree = ""; }; 84 | 05646BCD268503D300707676 /* Static-Analyzer.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Static-Analyzer.xcconfig"; sourceTree = ""; }; 85 | 05646BCF268503D300707676 /* Warnings-Policies.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Warnings-Policies.xcconfig"; sourceTree = ""; }; 86 | 05646BD0268503D300707676 /* Code-Generation.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Code-Generation.xcconfig"; sourceTree = ""; }; 87 | 05646BD1268503D300707676 /* Language.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Language.xcconfig; sourceTree = ""; }; 88 | 05646BD2268503D300707676 /* General.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = General.xcconfig; sourceTree = ""; }; 89 | 05646BD3268503D300707676 /* Search-Paths.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Search-Paths.xcconfig"; sourceTree = ""; }; 90 | 05646BD4268503D300707676 /* Apple-LLVM.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Apple-LLVM.xcconfig"; sourceTree = ""; }; 91 | 05646BD7268503D300707676 /* Modules.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Modules.xcconfig; sourceTree = ""; }; 92 | 05646BD8268503D300707676 /* Objective-C.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Objective-C.xcconfig"; sourceTree = ""; }; 93 | 05646BD9268503D300707676 /* C++.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "C++.xcconfig"; sourceTree = ""; }; 94 | 05646BDA268503D300707676 /* Code-Generation.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Code-Generation.xcconfig"; sourceTree = ""; }; 95 | 05646BDB268503D300707676 /* Address-Sanitizer.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Address-Sanitizer.xcconfig"; sourceTree = ""; }; 96 | 05646BDC268503D300707676 /* Language.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Language.xcconfig; sourceTree = ""; }; 97 | 05646BDD268503D300707676 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = ""; }; 98 | 05646BDE268503D300707676 /* Undefined-Behavior-Sanitizer.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Undefined-Behavior-Sanitizer.xcconfig"; sourceTree = ""; }; 99 | 05646BDF268503D300707676 /* Warning-Policies.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Warning-Policies.xcconfig"; sourceTree = ""; }; 100 | 05646BE1268503D300707676 /* Objective-C-ARC.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Objective-C-ARC.xcconfig"; sourceTree = ""; }; 101 | 05646BE2268503D300707676 /* Objective-C.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Objective-C.xcconfig"; sourceTree = ""; }; 102 | 05646BE3268503D300707676 /* C++.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "C++.xcconfig"; sourceTree = ""; }; 103 | 05646BE4268503D300707676 /* All-Languages.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "All-Languages.xcconfig"; sourceTree = ""; }; 104 | 05646BE5268503D300707676 /* Preprocessing.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Preprocessing.xcconfig; sourceTree = ""; }; 105 | 05646BE6268503D300707676 /* Debug - Library.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Debug - Library.xcconfig"; sourceTree = ""; }; 106 | 05646BE7268503D300707676 /* .gitignore */ = {isa = PBXFileReference; lastKnownFileType = text; path = .gitignore; sourceTree = ""; }; 107 | 05646BE9268503D300707676 /* ccache-config.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = "ccache-config.sh"; sourceTree = ""; }; 108 | 05646BEA268503D300707676 /* ccache.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = ccache.sh; sourceTree = ""; }; 109 | 05646BEB268503D300707676 /* Debug - zld.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Debug - zld.xcconfig"; sourceTree = ""; }; 110 | 05646BEE2685055F00707676 /* AboutWindowController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AboutWindowController.swift; sourceTree = ""; }; 111 | 05646BF12685058700707676 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/AboutWindowController.xib; sourceTree = ""; }; 112 | 0566B9612686B48E006EE45A /* Icon.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = Icon.icns; sourceTree = ""; }; 113 | 0566B9632686B526006EE45A /* GitHubUpdates.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = GitHubUpdates.xcodeproj; path = Submodules/GitHubUpdates/GitHubUpdates.xcodeproj; sourceTree = ""; }; 114 | 058B8EC82994392E00263FE9 /* SensorsUI.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; path = SensorsUI.xcodeproj; sourceTree = ""; }; 115 | 058B8EE52994419200263FE9 /* LICENSE */ = {isa = PBXFileReference; lastKnownFileType = text; path = LICENSE; sourceTree = ""; }; 116 | 058B8EE92994419200263FE9 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; 117 | 058B8EEA2994419200263FE9 /* CODE_OF_CONDUCT.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = CODE_OF_CONDUCT.md; sourceTree = ""; }; 118 | /* End PBXFileReference section */ 119 | 120 | /* Begin PBXFrameworksBuildPhase section */ 121 | 05646B97268501B300707676 /* Frameworks */ = { 122 | isa = PBXFrameworksBuildPhase; 123 | buildActionMask = 2147483647; 124 | files = ( 125 | 058B8ED32994394200263FE9 /* SensorsUI.framework in Frameworks */, 126 | 0566B96D2686B531006EE45A /* GitHubUpdates.framework in Frameworks */, 127 | ); 128 | runOnlyForDeploymentPostprocessing = 0; 129 | }; 130 | /* End PBXFrameworksBuildPhase section */ 131 | 132 | /* Begin PBXGroup section */ 133 | 05646B91268501B300707676 = { 134 | isa = PBXGroup; 135 | children = ( 136 | 058B8EEA2994419200263FE9 /* CODE_OF_CONDUCT.md */, 137 | 058B8EE52994419200263FE9 /* LICENSE */, 138 | 058B8EE92994419200263FE9 /* README.md */, 139 | 058B8EC82994392E00263FE9 /* SensorsUI.xcodeproj */, 140 | 0566B9632686B526006EE45A /* GitHubUpdates.xcodeproj */, 141 | 05646BB7268503D300707676 /* xcconfig */, 142 | 05646B9C268501B300707676 /* Sensors */, 143 | 05646B9B268501B300707676 /* Products */, 144 | 0566B96C2686B531006EE45A /* Frameworks */, 145 | ); 146 | sourceTree = ""; 147 | }; 148 | 05646B9B268501B300707676 /* Products */ = { 149 | isa = PBXGroup; 150 | children = ( 151 | 05646B9A268501B300707676 /* Sensors.app */, 152 | ); 153 | name = Products; 154 | sourceTree = ""; 155 | }; 156 | 05646B9C268501B300707676 /* Sensors */ = { 157 | isa = PBXGroup; 158 | children = ( 159 | 05646BAD2685020A00707676 /* Classes */, 160 | 05646BB62685021500707676 /* Supporting Files */, 161 | ); 162 | path = Sensors; 163 | sourceTree = ""; 164 | }; 165 | 05646BAD2685020A00707676 /* Classes */ = { 166 | isa = PBXGroup; 167 | children = ( 168 | 05646BEE2685055F00707676 /* AboutWindowController.swift */, 169 | 05646BF02685058700707676 /* AboutWindowController.xib */, 170 | 05646BAF2685020A00707676 /* ApplicationDelegate.swift */, 171 | ); 172 | path = Classes; 173 | sourceTree = ""; 174 | }; 175 | 05646BB62685021500707676 /* Supporting Files */ = { 176 | isa = PBXGroup; 177 | children = ( 178 | 0566B9612686B48E006EE45A /* Icon.icns */, 179 | 05646BA4268501B400707676 /* Info.plist */, 180 | 05646BB12685020A00707676 /* MainMenu.xib */, 181 | 05646BA5268501B400707676 /* Sensors.entitlements */, 182 | ); 183 | name = "Supporting Files"; 184 | sourceTree = ""; 185 | }; 186 | 05646BB7268503D300707676 /* xcconfig */ = { 187 | isa = PBXGroup; 188 | children = ( 189 | 05646BB8268503D300707676 /* Release - ccache.xcconfig */, 190 | 05646BB9268503D300707676 /* Common.xcconfig */, 191 | 05646BBA268503D300707676 /* Debug - ccache.xcconfig */, 192 | 05646BBB268503D300707676 /* Debug.xcconfig */, 193 | 05646BBC268503D300707676 /* Release.xcconfig */, 194 | 05646BBD268503D300707676 /* README.md */, 195 | 05646BBE268503D300707676 /* Release - Library.xcconfig */, 196 | 05646BBF268503D300707676 /* Common */, 197 | 05646BE6268503D300707676 /* Debug - Library.xcconfig */, 198 | 05646BE7268503D300707676 /* .gitignore */, 199 | 05646BE8268503D300707676 /* Scripts */, 200 | 05646BEB268503D300707676 /* Debug - zld.xcconfig */, 201 | ); 202 | name = xcconfig; 203 | path = Submodules/xcconfig; 204 | sourceTree = ""; 205 | }; 206 | 05646BBF268503D300707676 /* Common */ = { 207 | isa = PBXGroup; 208 | children = ( 209 | 05646BC0268503D300707676 /* Signing.xcconfig */, 210 | 05646BC1268503D300707676 /* Architectures.xcconfig */, 211 | 05646BC2268503D300707676 /* Static-Analyzer */, 212 | 05646BCA268503D300707676 /* Deployment.xcconfig */, 213 | 05646BCB268503D300707676 /* Build-Options.xcconfig */, 214 | 05646BCC268503D300707676 /* Swift-Compiler.xcconfig */, 215 | 05646BCD268503D300707676 /* Static-Analyzer.xcconfig */, 216 | 05646BCE268503D300707676 /* Swift-Compiler */, 217 | 05646BD3268503D300707676 /* Search-Paths.xcconfig */, 218 | 05646BD4268503D300707676 /* Apple-LLVM.xcconfig */, 219 | 05646BD5268503D300707676 /* Apple-LLVM */, 220 | ); 221 | path = Common; 222 | sourceTree = ""; 223 | }; 224 | 05646BC2268503D300707676 /* Static-Analyzer */ = { 225 | isa = PBXGroup; 226 | children = ( 227 | 05646BC3268503D300707676 /* Issues.xcconfig */, 228 | 05646BC4268503D300707676 /* Issues */, 229 | ); 230 | path = "Static-Analyzer"; 231 | sourceTree = ""; 232 | }; 233 | 05646BC4268503D300707676 /* Issues */ = { 234 | isa = PBXGroup; 235 | children = ( 236 | 05646BC5268503D300707676 /* Apple-APIs.xcconfig */, 237 | 05646BC6268503D300707676 /* Generic-Issues.xcconfig */, 238 | 05646BC7268503D300707676 /* Security.xcconfig */, 239 | 05646BC8268503D300707676 /* Objective-C.xcconfig */, 240 | 05646BC9268503D300707676 /* Analysis-Policy.xcconfig */, 241 | ); 242 | path = Issues; 243 | sourceTree = ""; 244 | }; 245 | 05646BCE268503D300707676 /* Swift-Compiler */ = { 246 | isa = PBXGroup; 247 | children = ( 248 | 05646BCF268503D300707676 /* Warnings-Policies.xcconfig */, 249 | 05646BD0268503D300707676 /* Code-Generation.xcconfig */, 250 | 05646BD1268503D300707676 /* Language.xcconfig */, 251 | 05646BD2268503D300707676 /* General.xcconfig */, 252 | ); 253 | path = "Swift-Compiler"; 254 | sourceTree = ""; 255 | }; 256 | 05646BD5268503D300707676 /* Apple-LLVM */ = { 257 | isa = PBXGroup; 258 | children = ( 259 | 05646BD6268503D300707676 /* Language */, 260 | 05646BDA268503D300707676 /* Code-Generation.xcconfig */, 261 | 05646BDB268503D300707676 /* Address-Sanitizer.xcconfig */, 262 | 05646BDC268503D300707676 /* Language.xcconfig */, 263 | 05646BDD268503D300707676 /* Warnings.xcconfig */, 264 | 05646BDE268503D300707676 /* Undefined-Behavior-Sanitizer.xcconfig */, 265 | 05646BDF268503D300707676 /* Warning-Policies.xcconfig */, 266 | 05646BE0268503D300707676 /* Warnings */, 267 | 05646BE5268503D300707676 /* Preprocessing.xcconfig */, 268 | ); 269 | path = "Apple-LLVM"; 270 | sourceTree = ""; 271 | }; 272 | 05646BD6268503D300707676 /* Language */ = { 273 | isa = PBXGroup; 274 | children = ( 275 | 05646BD7268503D300707676 /* Modules.xcconfig */, 276 | 05646BD8268503D300707676 /* Objective-C.xcconfig */, 277 | 05646BD9268503D300707676 /* C++.xcconfig */, 278 | ); 279 | path = Language; 280 | sourceTree = ""; 281 | }; 282 | 05646BE0268503D300707676 /* Warnings */ = { 283 | isa = PBXGroup; 284 | children = ( 285 | 05646BE1268503D300707676 /* Objective-C-ARC.xcconfig */, 286 | 05646BE2268503D300707676 /* Objective-C.xcconfig */, 287 | 05646BE3268503D300707676 /* C++.xcconfig */, 288 | 05646BE4268503D300707676 /* All-Languages.xcconfig */, 289 | ); 290 | path = Warnings; 291 | sourceTree = ""; 292 | }; 293 | 05646BE8268503D300707676 /* Scripts */ = { 294 | isa = PBXGroup; 295 | children = ( 296 | 05646BE9268503D300707676 /* ccache-config.sh */, 297 | 05646BEA268503D300707676 /* ccache.sh */, 298 | ); 299 | path = Scripts; 300 | sourceTree = ""; 301 | }; 302 | 0566B9642686B526006EE45A /* Products */ = { 303 | isa = PBXGroup; 304 | children = ( 305 | 0566B9692686B526006EE45A /* GitHubUpdates.framework */, 306 | 0566B96B2686B526006EE45A /* Relauncher */, 307 | ); 308 | name = Products; 309 | sourceTree = ""; 310 | }; 311 | 0566B96C2686B531006EE45A /* Frameworks */ = { 312 | isa = PBXGroup; 313 | children = ( 314 | ); 315 | name = Frameworks; 316 | sourceTree = ""; 317 | }; 318 | 058B8EC92994392E00263FE9 /* Products */ = { 319 | isa = PBXGroup; 320 | children = ( 321 | 058B8ED12994392E00263FE9 /* SensorsUI.framework */, 322 | ); 323 | name = Products; 324 | sourceTree = ""; 325 | }; 326 | /* End PBXGroup section */ 327 | 328 | /* Begin PBXNativeTarget section */ 329 | 05646B99268501B300707676 /* Sensors */ = { 330 | isa = PBXNativeTarget; 331 | buildConfigurationList = 05646BA8268501B400707676 /* Build configuration list for PBXNativeTarget "Sensors" */; 332 | buildPhases = ( 333 | 05646B96268501B300707676 /* Sources */, 334 | 05646B97268501B300707676 /* Frameworks */, 335 | 05646BED268503FE00707676 /* ShellScript */, 336 | 05646B98268501B300707676 /* Resources */, 337 | 0566B96F2686B531006EE45A /* Embed Frameworks */, 338 | ); 339 | buildRules = ( 340 | ); 341 | dependencies = ( 342 | ); 343 | name = Sensors; 344 | productName = Sensors; 345 | productReference = 05646B9A268501B300707676 /* Sensors.app */; 346 | productType = "com.apple.product-type.application"; 347 | }; 348 | /* End PBXNativeTarget section */ 349 | 350 | /* Begin PBXProject section */ 351 | 05646B92268501B300707676 /* Project object */ = { 352 | isa = PBXProject; 353 | attributes = { 354 | LastSwiftUpdateCheck = 1250; 355 | LastUpgradeCheck = 1420; 356 | TargetAttributes = { 357 | 05646B99268501B300707676 = { 358 | CreatedOnToolsVersion = 12.5.1; 359 | LastSwiftMigration = 1250; 360 | }; 361 | }; 362 | }; 363 | buildConfigurationList = 05646B95268501B300707676 /* Build configuration list for PBXProject "Sensors" */; 364 | compatibilityVersion = "Xcode 9.3"; 365 | developmentRegion = en; 366 | hasScannedForEncodings = 0; 367 | knownRegions = ( 368 | en, 369 | Base, 370 | ); 371 | mainGroup = 05646B91268501B300707676; 372 | productRefGroup = 05646B9B268501B300707676 /* Products */; 373 | projectDirPath = ""; 374 | projectReferences = ( 375 | { 376 | ProductGroup = 0566B9642686B526006EE45A /* Products */; 377 | ProjectRef = 0566B9632686B526006EE45A /* GitHubUpdates.xcodeproj */; 378 | }, 379 | { 380 | ProductGroup = 058B8EC92994392E00263FE9 /* Products */; 381 | ProjectRef = 058B8EC82994392E00263FE9 /* SensorsUI.xcodeproj */; 382 | }, 383 | ); 384 | projectRoot = ""; 385 | targets = ( 386 | 05646B99268501B300707676 /* Sensors */, 387 | ); 388 | }; 389 | /* End PBXProject section */ 390 | 391 | /* Begin PBXReferenceProxy section */ 392 | 0566B9692686B526006EE45A /* GitHubUpdates.framework */ = { 393 | isa = PBXReferenceProxy; 394 | fileType = wrapper.framework; 395 | path = GitHubUpdates.framework; 396 | remoteRef = 0566B9682686B526006EE45A /* PBXContainerItemProxy */; 397 | sourceTree = BUILT_PRODUCTS_DIR; 398 | }; 399 | 0566B96B2686B526006EE45A /* Relauncher */ = { 400 | isa = PBXReferenceProxy; 401 | fileType = "compiled.mach-o.executable"; 402 | path = Relauncher; 403 | remoteRef = 0566B96A2686B526006EE45A /* PBXContainerItemProxy */; 404 | sourceTree = BUILT_PRODUCTS_DIR; 405 | }; 406 | 058B8ED12994392E00263FE9 /* SensorsUI.framework */ = { 407 | isa = PBXReferenceProxy; 408 | fileType = wrapper.framework; 409 | path = SensorsUI.framework; 410 | remoteRef = 058B8ED02994392E00263FE9 /* PBXContainerItemProxy */; 411 | sourceTree = BUILT_PRODUCTS_DIR; 412 | }; 413 | /* End PBXReferenceProxy section */ 414 | 415 | /* Begin PBXResourcesBuildPhase section */ 416 | 05646B98268501B300707676 /* Resources */ = { 417 | isa = PBXResourcesBuildPhase; 418 | buildActionMask = 2147483647; 419 | files = ( 420 | 05646BB52685020A00707676 /* MainMenu.xib in Resources */, 421 | 0566B9622686B48E006EE45A /* Icon.icns in Resources */, 422 | 05646BF22685058700707676 /* AboutWindowController.xib in Resources */, 423 | ); 424 | runOnlyForDeploymentPostprocessing = 0; 425 | }; 426 | /* End PBXResourcesBuildPhase section */ 427 | 428 | /* Begin PBXShellScriptBuildPhase section */ 429 | 05646BED268503FE00707676 /* ShellScript */ = { 430 | isa = PBXShellScriptBuildPhase; 431 | alwaysOutOfDate = 1; 432 | buildActionMask = 2147483647; 433 | files = ( 434 | ); 435 | inputFileListPaths = ( 436 | ); 437 | inputPaths = ( 438 | ); 439 | outputFileListPaths = ( 440 | ); 441 | outputPaths = ( 442 | ); 443 | runOnlyForDeploymentPostprocessing = 0; 444 | shellPath = /bin/sh; 445 | shellScript = "#!/bin/bash\nif [ \"${CONFIGURATION}\" = \"Release\" ]; then\n plist=\"Sensors/Info.plist\"\n rev=$(git rev-list `git branch | grep -e \"^*\" | cut -d' ' -f 2` | wc -l)\n /usr/libexec/PlistBuddy -c \"Set :CFBundleVersion $rev\" \"$plist\"\nfi\n"; 446 | }; 447 | /* End PBXShellScriptBuildPhase section */ 448 | 449 | /* Begin PBXSourcesBuildPhase section */ 450 | 05646B96268501B300707676 /* Sources */ = { 451 | isa = PBXSourcesBuildPhase; 452 | buildActionMask = 2147483647; 453 | files = ( 454 | 05646BB42685020A00707676 /* ApplicationDelegate.swift in Sources */, 455 | 05646BEF2685055F00707676 /* AboutWindowController.swift in Sources */, 456 | ); 457 | runOnlyForDeploymentPostprocessing = 0; 458 | }; 459 | /* End PBXSourcesBuildPhase section */ 460 | 461 | /* Begin PBXVariantGroup section */ 462 | 05646BB12685020A00707676 /* MainMenu.xib */ = { 463 | isa = PBXVariantGroup; 464 | children = ( 465 | 05646BB22685020A00707676 /* Base */, 466 | ); 467 | name = MainMenu.xib; 468 | sourceTree = ""; 469 | }; 470 | 05646BF02685058700707676 /* AboutWindowController.xib */ = { 471 | isa = PBXVariantGroup; 472 | children = ( 473 | 05646BF12685058700707676 /* Base */, 474 | ); 475 | name = AboutWindowController.xib; 476 | sourceTree = ""; 477 | }; 478 | /* End PBXVariantGroup section */ 479 | 480 | /* Begin XCBuildConfiguration section */ 481 | 05646BA6268501B400707676 /* Debug */ = { 482 | isa = XCBuildConfiguration; 483 | baseConfigurationReference = 05646BBB268503D300707676 /* Debug.xcconfig */; 484 | buildSettings = { 485 | MACOSX_DEPLOYMENT_TARGET = 11.0; 486 | }; 487 | name = Debug; 488 | }; 489 | 05646BA7268501B400707676 /* Release */ = { 490 | isa = XCBuildConfiguration; 491 | baseConfigurationReference = 05646BBC268503D300707676 /* Release.xcconfig */; 492 | buildSettings = { 493 | MACOSX_DEPLOYMENT_TARGET = 11.0; 494 | }; 495 | name = Release; 496 | }; 497 | 05646BA9268501B400707676 /* Debug */ = { 498 | isa = XCBuildConfiguration; 499 | buildSettings = { 500 | CLANG_ENABLE_MODULES = YES; 501 | CODE_SIGN_ENTITLEMENTS = Sensors/Sensors.entitlements; 502 | CODE_SIGN_STYLE = Automatic; 503 | DEVELOPMENT_TEAM = 326Y53CJMD; 504 | ENABLE_HARDENED_RUNTIME = YES; 505 | INFOPLIST_FILE = Sensors/Info.plist; 506 | LD_RUNPATH_SEARCH_PATHS = ( 507 | "$(inherited)", 508 | "@executable_path/../Frameworks", 509 | ); 510 | PRODUCT_BUNDLE_IDENTIFIER = "com.xs-labs.Sensors"; 511 | PRODUCT_NAME = "$(TARGET_NAME)"; 512 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 513 | SWIFT_VERSION = 5.0; 514 | }; 515 | name = Debug; 516 | }; 517 | 05646BAA268501B400707676 /* Release */ = { 518 | isa = XCBuildConfiguration; 519 | buildSettings = { 520 | CLANG_ENABLE_MODULES = YES; 521 | CODE_SIGN_ENTITLEMENTS = Sensors/Sensors.entitlements; 522 | CODE_SIGN_STYLE = Automatic; 523 | DEVELOPMENT_TEAM = 326Y53CJMD; 524 | ENABLE_HARDENED_RUNTIME = YES; 525 | INFOPLIST_FILE = Sensors/Info.plist; 526 | LD_RUNPATH_SEARCH_PATHS = ( 527 | "$(inherited)", 528 | "@executable_path/../Frameworks", 529 | ); 530 | PRODUCT_BUNDLE_IDENTIFIER = "com.xs-labs.Sensors"; 531 | PRODUCT_NAME = "$(TARGET_NAME)"; 532 | SWIFT_VERSION = 5.0; 533 | }; 534 | name = Release; 535 | }; 536 | /* End XCBuildConfiguration section */ 537 | 538 | /* Begin XCConfigurationList section */ 539 | 05646B95268501B300707676 /* Build configuration list for PBXProject "Sensors" */ = { 540 | isa = XCConfigurationList; 541 | buildConfigurations = ( 542 | 05646BA6268501B400707676 /* Debug */, 543 | 05646BA7268501B400707676 /* Release */, 544 | ); 545 | defaultConfigurationIsVisible = 0; 546 | defaultConfigurationName = Release; 547 | }; 548 | 05646BA8268501B400707676 /* Build configuration list for PBXNativeTarget "Sensors" */ = { 549 | isa = XCConfigurationList; 550 | buildConfigurations = ( 551 | 05646BA9268501B400707676 /* Debug */, 552 | 05646BAA268501B400707676 /* Release */, 553 | ); 554 | defaultConfigurationIsVisible = 0; 555 | defaultConfigurationName = Release; 556 | }; 557 | /* End XCConfigurationList section */ 558 | }; 559 | rootObject = 05646B92268501B300707676 /* Project object */; 560 | } 561 | -------------------------------------------------------------------------------- /Sensors.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Sensors.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Sensors/Base.lproj/MainMenu.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 | 518 | 519 | 520 | 521 | 522 | 523 | 524 | 525 | 526 | 527 | 528 | 529 | 530 | 531 | 532 | 533 | 534 | 535 | 536 | 537 | 538 | 539 | 540 | 541 | 542 | 543 | 544 | Default 545 | 546 | 547 | 548 | 549 | 550 | 551 | Left to Right 552 | 553 | 554 | 555 | 556 | 557 | 558 | Right to Left 559 | 560 | 561 | 562 | 563 | 564 | 565 | 566 | 567 | 568 | 569 | Default 570 | 571 | 572 | 573 | 574 | 575 | 576 | Left to Right 577 | 578 | 579 | 580 | 581 | 582 | 583 | Right to Left 584 | 585 | 586 | 587 | 588 | 589 | 590 | 591 | 592 | 593 | 594 | 595 | 596 | 597 | 598 | 599 | 600 | 601 | 602 | 603 | 604 | 605 | 606 | 607 | 608 | 609 | 610 | 611 | 612 | 613 | 614 | 615 | 616 | 617 | 618 | 619 | 620 | 621 | 622 | 623 | 624 | 625 | 626 | 627 | 628 | 629 | 630 | 631 | 632 | 633 | 634 | 635 | 636 | 637 | 638 | 639 | 640 | 641 | 642 | 643 | 644 | 645 | 646 | 647 | 648 | 649 | 650 | 651 | 652 | 653 | 654 | 655 | 656 | 657 | 658 | 659 | 660 | 661 | 662 | 663 | 664 | 665 | 666 | 667 | 668 | 669 | 670 | 671 | 672 | 673 | 674 | 675 | 676 | 677 | 678 | 679 | 680 | 681 | 682 | 683 | 684 | 685 | 686 | 687 | 688 | 689 | 690 | 691 | 692 | 693 | 694 | 695 | 696 | 697 | 698 | 699 | 700 | 701 | 702 | 703 | -------------------------------------------------------------------------------- /Sensors/Classes/AboutWindowController.swift: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2023, Jean-David Gadina - www.xs-labs.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the Software), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | ******************************************************************************/ 24 | 25 | import Cocoa 26 | 27 | public class AboutWindowController: NSWindowController 28 | { 29 | @objc private dynamic var name: String? 30 | @objc private dynamic var version: String? 31 | @objc private dynamic var copyright: String? 32 | 33 | public override var windowNibName: NSNib.Name? 34 | { 35 | "AboutWindowController" 36 | } 37 | 38 | public override func windowDidLoad() 39 | { 40 | super.windowDidLoad() 41 | 42 | let version = Bundle.main.object( forInfoDictionaryKey: "CFBundleShortVersionString" ) as? String ?? "0.0.0" 43 | 44 | if let build = Bundle.main.object( forInfoDictionaryKey: "CFBundleVersion" ) as? String 45 | { 46 | self.version = "\( version ) (\( build ))" 47 | } 48 | else 49 | { 50 | self.version = version 51 | } 52 | 53 | self.name = Bundle.main.object( forInfoDictionaryKey: "CFBundleName" ) as? String 54 | self.copyright = Bundle.main.object( forInfoDictionaryKey: "NSHumanReadableCopyright" ) as? String 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /Sensors/Classes/ApplicationDelegate.swift: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2023, Jean-David Gadina - www.xs-labs.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the Software), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | ******************************************************************************/ 24 | 25 | import Cocoa 26 | import GitHubUpdates 27 | import SensorsUI 28 | 29 | @main 30 | public class ApplicationDelegate: NSObject, NSApplicationDelegate 31 | { 32 | @objc private dynamic var aboutWindowController = AboutWindowController() 33 | @objc private dynamic var mainWindowController = SensorsWindowController() 34 | 35 | @IBOutlet private var updater: GitHubUpdater! 36 | 37 | public func applicationDidFinishLaunching( _ notification: Notification ) 38 | { 39 | self.showMainWindow( nil ) 40 | 41 | UserDefaults.standard.set( NSDate(), forKey: "lastStart" ) 42 | 43 | DispatchQueue.main.asyncAfter( deadline: .now() + .seconds( 5 ) ) 44 | { 45 | self.updater.checkForUpdatesInBackground() 46 | } 47 | } 48 | 49 | public func applicationWillTerminate( _ notification: Notification ) 50 | {} 51 | 52 | public func applicationShouldTerminateAfterLastWindowClosed( _ sender: NSApplication ) -> Bool 53 | { 54 | true 55 | } 56 | 57 | @IBAction 58 | public func showAboutWindow( _ sender: Any? ) 59 | { 60 | if self.aboutWindowController.window?.isVisible == false 61 | { 62 | self.aboutWindowController.window?.layoutIfNeeded() 63 | self.aboutWindowController.window?.center() 64 | } 65 | 66 | self.aboutWindowController.window?.makeKeyAndOrderFront( sender ) 67 | } 68 | 69 | @IBAction 70 | public func showMainWindow( _ sender: Any? ) 71 | { 72 | if UserDefaults.standard.object( forKey: "lastStart" ) == nil 73 | { 74 | self.mainWindowController.window?.layoutIfNeeded() 75 | self.mainWindowController.window?.center() 76 | } 77 | 78 | self.mainWindowController.window?.makeKeyAndOrderFront( sender ) 79 | } 80 | 81 | @IBAction 82 | public func invertAppearance( _ sender: Any? ) 83 | { 84 | switch NSApp.effectiveAppearance.name 85 | { 86 | case .aqua: NSApp.appearance = NSAppearance( named: .darkAqua ) 87 | case .darkAqua: NSApp.appearance = NSAppearance( named: .aqua ) 88 | case .accessibilityHighContrastAqua: NSApp.appearance = NSAppearance( named: .accessibilityHighContrastDarkAqua ) 89 | case .accessibilityHighContrastDarkAqua: NSApp.appearance = NSAppearance( named: .accessibilityHighContrastAqua ) 90 | case .vibrantLight: NSApp.appearance = NSAppearance( named: .vibrantDark ) 91 | case .vibrantDark: NSApp.appearance = NSAppearance( named: .vibrantLight ) 92 | case .accessibilityHighContrastVibrantLight: NSApp.appearance = NSAppearance( named: .accessibilityHighContrastVibrantDark ) 93 | case .accessibilityHighContrastVibrantDark: NSApp.appearance = NSAppearance( named: .accessibilityHighContrastVibrantLight ) 94 | 95 | default: NSSound.beep() 96 | } 97 | } 98 | 99 | @IBAction 100 | public func checkForUpdates( _ sender: Any? ) 101 | { 102 | self.updater.checkForUpdates( sender ) 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /Sensors/Classes/Base.lproj/AboutWindowController.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | -------------------------------------------------------------------------------- /Sensors/Icon.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macmade/Sensors/d49fe30dce55c5cf7862e711dc3629cfd0fcb05d/Sensors/Icon.icns -------------------------------------------------------------------------------- /Sensors/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | Icon 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 19 | CFBundleShortVersionString 20 | 1.2.2 21 | CFBundleVersion 22 | 74 23 | LSApplicationCategoryType 24 | public.app-category.utilities 25 | LSMinimumSystemVersion 26 | $(MACOSX_DEPLOYMENT_TARGET) 27 | NSHumanReadableCopyright 28 | Copyright © 2020 XS-Labs. All rights reserved. 29 | NSMainNibFile 30 | MainMenu 31 | NSPrincipalClass 32 | NSApplication 33 | 34 | 35 | -------------------------------------------------------------------------------- /Sensors/Sensors.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /SensorsUI.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 058B8EB02994386700263FE9 /* ArrayIsNotEmpty.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0566B97526875012006EE45A /* ArrayIsNotEmpty.swift */; }; 11 | 058B8EB12994386700263FE9 /* SensorIcon.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0566B93B26864187006EE45A /* SensorIcon.swift */; }; 12 | 058B8EB22994386700263FE9 /* NSImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0566B95226865B60006EE45A /* NSImage.swift */; }; 13 | 058B8EB32994386700263FE9 /* SensorGraphView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0566B94826864627006EE45A /* SensorGraphView.swift */; }; 14 | 058B8EB42994386700263FE9 /* SensorsWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05646BF62685064C00707676 /* SensorsWindowController.swift */; }; 15 | 058B8EB52994386700263FE9 /* ArrayIsEmpty.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0566B97126874FD3006EE45A /* ArrayIsEmpty.swift */; }; 16 | 058B8EB62994386700263FE9 /* SensorValue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0566B94626864492006EE45A /* SensorValue.swift */; }; 17 | 058B8EB72994386700263FE9 /* Colors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0566B95426865C78006EE45A /* Colors.swift */; }; 18 | 058B8EB82994386700263FE9 /* SensorItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05E0C31B268635C300D1D216 /* SensorItem.swift */; }; 19 | 058B8EB92994386B00263FE9 /* SensorsWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 05646BF82685072900707676 /* SensorsWindowController.xib */; }; 20 | 058B8EBA2994386B00263FE9 /* SensorItem.xib in Resources */ = {isa = PBXBuildFile; fileRef = 05E0C31D268635F200D1D216 /* SensorItem.xib */; }; 21 | 058B8EBB2994386E00263FE9 /* CurrentTemplate.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 0566B9402686438E006EE45A /* CurrentTemplate.pdf */; }; 22 | 058B8EBC2994386E00263FE9 /* ThermalTemplate.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 0566B9412686438E006EE45A /* ThermalTemplate.pdf */; }; 23 | 058B8EBD2994386E00263FE9 /* VoltageTemplate.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 0566B93F2686438E006EE45A /* VoltageTemplate.pdf */; }; 24 | 058B8EBE2994387900263FE9 /* SensorsKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 058B8E96299436D900263FE9 /* SensorsKit.framework */; }; 25 | 058B8EBF2994387900263FE9 /* SensorsKit.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 058B8E96299436D900263FE9 /* SensorsKit.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 26 | 05BDE9EE29944B9D00B0B888 /* AmbiantLightTemplate.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 05BDE9EC29944B9D00B0B888 /* AmbiantLightTemplate.pdf */; }; 27 | /* End PBXBuildFile section */ 28 | 29 | /* Begin PBXContainerItemProxy section */ 30 | 058B8E95299436D900263FE9 /* PBXContainerItemProxy */ = { 31 | isa = PBXContainerItemProxy; 32 | containerPortal = 058B8E8F299436D900263FE9 /* SensorsKit.xcodeproj */; 33 | proxyType = 2; 34 | remoteGlobalIDString = 05BD7282299275AB00CF4FD7; 35 | remoteInfo = SensorsKit; 36 | }; 37 | /* End PBXContainerItemProxy section */ 38 | 39 | /* Begin PBXCopyFilesBuildPhase section */ 40 | 058B8EC02994387900263FE9 /* Embed Frameworks */ = { 41 | isa = PBXCopyFilesBuildPhase; 42 | buildActionMask = 2147483647; 43 | dstPath = ""; 44 | dstSubfolderSpec = 10; 45 | files = ( 46 | 058B8EBF2994387900263FE9 /* SensorsKit.framework in Embed Frameworks */, 47 | ); 48 | name = "Embed Frameworks"; 49 | runOnlyForDeploymentPostprocessing = 0; 50 | }; 51 | /* End PBXCopyFilesBuildPhase section */ 52 | 53 | /* Begin PBXFileReference section */ 54 | 05646BB8268503D300707676 /* Release - ccache.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Release - ccache.xcconfig"; sourceTree = ""; }; 55 | 05646BB9268503D300707676 /* Common.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Common.xcconfig; sourceTree = ""; }; 56 | 05646BBA268503D300707676 /* Debug - ccache.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Debug - ccache.xcconfig"; sourceTree = ""; }; 57 | 05646BBB268503D300707676 /* Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; }; 58 | 05646BBC268503D300707676 /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = ""; }; 59 | 05646BBD268503D300707676 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; 60 | 05646BBE268503D300707676 /* Release - Library.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Release - Library.xcconfig"; sourceTree = ""; }; 61 | 05646BC0268503D300707676 /* Signing.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Signing.xcconfig; sourceTree = ""; }; 62 | 05646BC1268503D300707676 /* Architectures.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Architectures.xcconfig; sourceTree = ""; }; 63 | 05646BC3268503D300707676 /* Issues.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Issues.xcconfig; sourceTree = ""; }; 64 | 05646BC5268503D300707676 /* Apple-APIs.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Apple-APIs.xcconfig"; sourceTree = ""; }; 65 | 05646BC6268503D300707676 /* Generic-Issues.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Generic-Issues.xcconfig"; sourceTree = ""; }; 66 | 05646BC7268503D300707676 /* Security.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Security.xcconfig; sourceTree = ""; }; 67 | 05646BC8268503D300707676 /* Objective-C.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Objective-C.xcconfig"; sourceTree = ""; }; 68 | 05646BC9268503D300707676 /* Analysis-Policy.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Analysis-Policy.xcconfig"; sourceTree = ""; }; 69 | 05646BCA268503D300707676 /* Deployment.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Deployment.xcconfig; sourceTree = ""; }; 70 | 05646BCB268503D300707676 /* Build-Options.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Build-Options.xcconfig"; sourceTree = ""; }; 71 | 05646BCC268503D300707676 /* Swift-Compiler.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Swift-Compiler.xcconfig"; sourceTree = ""; }; 72 | 05646BCD268503D300707676 /* Static-Analyzer.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Static-Analyzer.xcconfig"; sourceTree = ""; }; 73 | 05646BCF268503D300707676 /* Warnings-Policies.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Warnings-Policies.xcconfig"; sourceTree = ""; }; 74 | 05646BD0268503D300707676 /* Code-Generation.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Code-Generation.xcconfig"; sourceTree = ""; }; 75 | 05646BD1268503D300707676 /* Language.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Language.xcconfig; sourceTree = ""; }; 76 | 05646BD2268503D300707676 /* General.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = General.xcconfig; sourceTree = ""; }; 77 | 05646BD3268503D300707676 /* Search-Paths.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Search-Paths.xcconfig"; sourceTree = ""; }; 78 | 05646BD4268503D300707676 /* Apple-LLVM.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Apple-LLVM.xcconfig"; sourceTree = ""; }; 79 | 05646BD7268503D300707676 /* Modules.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Modules.xcconfig; sourceTree = ""; }; 80 | 05646BD8268503D300707676 /* Objective-C.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Objective-C.xcconfig"; sourceTree = ""; }; 81 | 05646BD9268503D300707676 /* C++.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "C++.xcconfig"; sourceTree = ""; }; 82 | 05646BDA268503D300707676 /* Code-Generation.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Code-Generation.xcconfig"; sourceTree = ""; }; 83 | 05646BDB268503D300707676 /* Address-Sanitizer.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Address-Sanitizer.xcconfig"; sourceTree = ""; }; 84 | 05646BDC268503D300707676 /* Language.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Language.xcconfig; sourceTree = ""; }; 85 | 05646BDD268503D300707676 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = ""; }; 86 | 05646BDE268503D300707676 /* Undefined-Behavior-Sanitizer.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Undefined-Behavior-Sanitizer.xcconfig"; sourceTree = ""; }; 87 | 05646BDF268503D300707676 /* Warning-Policies.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Warning-Policies.xcconfig"; sourceTree = ""; }; 88 | 05646BE1268503D300707676 /* Objective-C-ARC.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Objective-C-ARC.xcconfig"; sourceTree = ""; }; 89 | 05646BE2268503D300707676 /* Objective-C.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Objective-C.xcconfig"; sourceTree = ""; }; 90 | 05646BE3268503D300707676 /* C++.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "C++.xcconfig"; sourceTree = ""; }; 91 | 05646BE4268503D300707676 /* All-Languages.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "All-Languages.xcconfig"; sourceTree = ""; }; 92 | 05646BE5268503D300707676 /* Preprocessing.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Preprocessing.xcconfig; sourceTree = ""; }; 93 | 05646BE6268503D300707676 /* Debug - Library.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Debug - Library.xcconfig"; sourceTree = ""; }; 94 | 05646BE7268503D300707676 /* .gitignore */ = {isa = PBXFileReference; lastKnownFileType = text; path = .gitignore; sourceTree = ""; }; 95 | 05646BE9268503D300707676 /* ccache-config.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = "ccache-config.sh"; sourceTree = ""; }; 96 | 05646BEA268503D300707676 /* ccache.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = ccache.sh; sourceTree = ""; }; 97 | 05646BEB268503D300707676 /* Debug - zld.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Debug - zld.xcconfig"; sourceTree = ""; }; 98 | 05646BF62685064C00707676 /* SensorsWindowController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SensorsWindowController.swift; sourceTree = ""; }; 99 | 05646BF92685072900707676 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/SensorsWindowController.xib; sourceTree = ""; }; 100 | 0566B93B26864187006EE45A /* SensorIcon.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SensorIcon.swift; sourceTree = ""; }; 101 | 0566B93F2686438E006EE45A /* VoltageTemplate.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = VoltageTemplate.pdf; sourceTree = ""; }; 102 | 0566B9402686438E006EE45A /* CurrentTemplate.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = CurrentTemplate.pdf; sourceTree = ""; }; 103 | 0566B9412686438E006EE45A /* ThermalTemplate.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = ThermalTemplate.pdf; sourceTree = ""; }; 104 | 0566B94626864492006EE45A /* SensorValue.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SensorValue.swift; sourceTree = ""; }; 105 | 0566B94826864627006EE45A /* SensorGraphView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SensorGraphView.swift; sourceTree = ""; }; 106 | 0566B95226865B60006EE45A /* NSImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSImage.swift; sourceTree = ""; }; 107 | 0566B95426865C78006EE45A /* Colors.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Colors.swift; sourceTree = ""; }; 108 | 0566B97126874FD3006EE45A /* ArrayIsEmpty.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArrayIsEmpty.swift; sourceTree = ""; }; 109 | 0566B97526875012006EE45A /* ArrayIsNotEmpty.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArrayIsNotEmpty.swift; sourceTree = ""; }; 110 | 058B8E8F299436D900263FE9 /* SensorsKit.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = SensorsKit.xcodeproj; path = Submodules/SensorsKit/SensorsKit.xcodeproj; sourceTree = ""; }; 111 | 058B8EA22994383300263FE9 /* SensorsUI.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SensorsUI.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 112 | 058B8EEB2994419B00263FE9 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; 113 | 058B8EED2994419B00263FE9 /* LICENSE */ = {isa = PBXFileReference; lastKnownFileType = text; path = LICENSE; sourceTree = ""; }; 114 | 058B8EEE2994419B00263FE9 /* CODE_OF_CONDUCT.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = CODE_OF_CONDUCT.md; sourceTree = ""; }; 115 | 05BDE9EC29944B9D00B0B888 /* AmbiantLightTemplate.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = AmbiantLightTemplate.pdf; sourceTree = ""; }; 116 | 05E0C31B268635C300D1D216 /* SensorItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SensorItem.swift; sourceTree = ""; }; 117 | 05E0C31E268635F200D1D216 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/SensorItem.xib; sourceTree = ""; }; 118 | /* End PBXFileReference section */ 119 | 120 | /* Begin PBXFrameworksBuildPhase section */ 121 | 058B8E9F2994383300263FE9 /* Frameworks */ = { 122 | isa = PBXFrameworksBuildPhase; 123 | buildActionMask = 2147483647; 124 | files = ( 125 | 058B8EBE2994387900263FE9 /* SensorsKit.framework in Frameworks */, 126 | ); 127 | runOnlyForDeploymentPostprocessing = 0; 128 | }; 129 | /* End PBXFrameworksBuildPhase section */ 130 | 131 | /* Begin PBXGroup section */ 132 | 05646B91268501B300707676 = { 133 | isa = PBXGroup; 134 | children = ( 135 | 058B8EEE2994419B00263FE9 /* CODE_OF_CONDUCT.md */, 136 | 058B8EED2994419B00263FE9 /* LICENSE */, 137 | 058B8EEB2994419B00263FE9 /* README.md */, 138 | 058B8E8F299436D900263FE9 /* SensorsKit.xcodeproj */, 139 | 05646BB7268503D300707676 /* xcconfig */, 140 | 058B8EA32994383300263FE9 /* SensorsUI */, 141 | 05646B9B268501B300707676 /* Products */, 142 | 0566B96C2686B531006EE45A /* Frameworks */, 143 | ); 144 | sourceTree = ""; 145 | }; 146 | 05646B9B268501B300707676 /* Products */ = { 147 | isa = PBXGroup; 148 | children = ( 149 | 058B8EA22994383300263FE9 /* SensorsUI.framework */, 150 | ); 151 | name = Products; 152 | sourceTree = ""; 153 | }; 154 | 05646BB7268503D300707676 /* xcconfig */ = { 155 | isa = PBXGroup; 156 | children = ( 157 | 05646BB8268503D300707676 /* Release - ccache.xcconfig */, 158 | 05646BB9268503D300707676 /* Common.xcconfig */, 159 | 05646BBA268503D300707676 /* Debug - ccache.xcconfig */, 160 | 05646BBB268503D300707676 /* Debug.xcconfig */, 161 | 05646BBC268503D300707676 /* Release.xcconfig */, 162 | 05646BBD268503D300707676 /* README.md */, 163 | 05646BBE268503D300707676 /* Release - Library.xcconfig */, 164 | 05646BBF268503D300707676 /* Common */, 165 | 05646BE6268503D300707676 /* Debug - Library.xcconfig */, 166 | 05646BE7268503D300707676 /* .gitignore */, 167 | 05646BE8268503D300707676 /* Scripts */, 168 | 05646BEB268503D300707676 /* Debug - zld.xcconfig */, 169 | ); 170 | name = xcconfig; 171 | path = Submodules/xcconfig; 172 | sourceTree = ""; 173 | }; 174 | 05646BBF268503D300707676 /* Common */ = { 175 | isa = PBXGroup; 176 | children = ( 177 | 05646BC0268503D300707676 /* Signing.xcconfig */, 178 | 05646BC1268503D300707676 /* Architectures.xcconfig */, 179 | 05646BC2268503D300707676 /* Static-Analyzer */, 180 | 05646BCA268503D300707676 /* Deployment.xcconfig */, 181 | 05646BCB268503D300707676 /* Build-Options.xcconfig */, 182 | 05646BCC268503D300707676 /* Swift-Compiler.xcconfig */, 183 | 05646BCD268503D300707676 /* Static-Analyzer.xcconfig */, 184 | 05646BCE268503D300707676 /* Swift-Compiler */, 185 | 05646BD3268503D300707676 /* Search-Paths.xcconfig */, 186 | 05646BD4268503D300707676 /* Apple-LLVM.xcconfig */, 187 | 05646BD5268503D300707676 /* Apple-LLVM */, 188 | ); 189 | path = Common; 190 | sourceTree = ""; 191 | }; 192 | 05646BC2268503D300707676 /* Static-Analyzer */ = { 193 | isa = PBXGroup; 194 | children = ( 195 | 05646BC3268503D300707676 /* Issues.xcconfig */, 196 | 05646BC4268503D300707676 /* Issues */, 197 | ); 198 | path = "Static-Analyzer"; 199 | sourceTree = ""; 200 | }; 201 | 05646BC4268503D300707676 /* Issues */ = { 202 | isa = PBXGroup; 203 | children = ( 204 | 05646BC5268503D300707676 /* Apple-APIs.xcconfig */, 205 | 05646BC6268503D300707676 /* Generic-Issues.xcconfig */, 206 | 05646BC7268503D300707676 /* Security.xcconfig */, 207 | 05646BC8268503D300707676 /* Objective-C.xcconfig */, 208 | 05646BC9268503D300707676 /* Analysis-Policy.xcconfig */, 209 | ); 210 | path = Issues; 211 | sourceTree = ""; 212 | }; 213 | 05646BCE268503D300707676 /* Swift-Compiler */ = { 214 | isa = PBXGroup; 215 | children = ( 216 | 05646BCF268503D300707676 /* Warnings-Policies.xcconfig */, 217 | 05646BD0268503D300707676 /* Code-Generation.xcconfig */, 218 | 05646BD1268503D300707676 /* Language.xcconfig */, 219 | 05646BD2268503D300707676 /* General.xcconfig */, 220 | ); 221 | path = "Swift-Compiler"; 222 | sourceTree = ""; 223 | }; 224 | 05646BD5268503D300707676 /* Apple-LLVM */ = { 225 | isa = PBXGroup; 226 | children = ( 227 | 05646BD6268503D300707676 /* Language */, 228 | 05646BDA268503D300707676 /* Code-Generation.xcconfig */, 229 | 05646BDB268503D300707676 /* Address-Sanitizer.xcconfig */, 230 | 05646BDC268503D300707676 /* Language.xcconfig */, 231 | 05646BDD268503D300707676 /* Warnings.xcconfig */, 232 | 05646BDE268503D300707676 /* Undefined-Behavior-Sanitizer.xcconfig */, 233 | 05646BDF268503D300707676 /* Warning-Policies.xcconfig */, 234 | 05646BE0268503D300707676 /* Warnings */, 235 | 05646BE5268503D300707676 /* Preprocessing.xcconfig */, 236 | ); 237 | path = "Apple-LLVM"; 238 | sourceTree = ""; 239 | }; 240 | 05646BD6268503D300707676 /* Language */ = { 241 | isa = PBXGroup; 242 | children = ( 243 | 05646BD7268503D300707676 /* Modules.xcconfig */, 244 | 05646BD8268503D300707676 /* Objective-C.xcconfig */, 245 | 05646BD9268503D300707676 /* C++.xcconfig */, 246 | ); 247 | path = Language; 248 | sourceTree = ""; 249 | }; 250 | 05646BE0268503D300707676 /* Warnings */ = { 251 | isa = PBXGroup; 252 | children = ( 253 | 05646BE1268503D300707676 /* Objective-C-ARC.xcconfig */, 254 | 05646BE2268503D300707676 /* Objective-C.xcconfig */, 255 | 05646BE3268503D300707676 /* C++.xcconfig */, 256 | 05646BE4268503D300707676 /* All-Languages.xcconfig */, 257 | ); 258 | path = Warnings; 259 | sourceTree = ""; 260 | }; 261 | 05646BE8268503D300707676 /* Scripts */ = { 262 | isa = PBXGroup; 263 | children = ( 264 | 05646BE9268503D300707676 /* ccache-config.sh */, 265 | 05646BEA268503D300707676 /* ccache.sh */, 266 | ); 267 | path = Scripts; 268 | sourceTree = ""; 269 | }; 270 | 0566B93D2686438E006EE45A /* Images */ = { 271 | isa = PBXGroup; 272 | children = ( 273 | 05BDE9EC29944B9D00B0B888 /* AmbiantLightTemplate.pdf */, 274 | 0566B9402686438E006EE45A /* CurrentTemplate.pdf */, 275 | 0566B9412686438E006EE45A /* ThermalTemplate.pdf */, 276 | 0566B93F2686438E006EE45A /* VoltageTemplate.pdf */, 277 | ); 278 | path = Images; 279 | sourceTree = ""; 280 | }; 281 | 0566B96C2686B531006EE45A /* Frameworks */ = { 282 | isa = PBXGroup; 283 | children = ( 284 | ); 285 | name = Frameworks; 286 | sourceTree = ""; 287 | }; 288 | 058B8E90299436D900263FE9 /* Products */ = { 289 | isa = PBXGroup; 290 | children = ( 291 | 058B8E96299436D900263FE9 /* SensorsKit.framework */, 292 | ); 293 | name = Products; 294 | sourceTree = ""; 295 | }; 296 | 058B8EA32994383300263FE9 /* SensorsUI */ = { 297 | isa = PBXGroup; 298 | children = ( 299 | 0566B97126874FD3006EE45A /* ArrayIsEmpty.swift */, 300 | 0566B97526875012006EE45A /* ArrayIsNotEmpty.swift */, 301 | 0566B95426865C78006EE45A /* Colors.swift */, 302 | 0566B93D2686438E006EE45A /* Images */, 303 | 0566B95226865B60006EE45A /* NSImage.swift */, 304 | 0566B94826864627006EE45A /* SensorGraphView.swift */, 305 | 0566B93B26864187006EE45A /* SensorIcon.swift */, 306 | 05E0C31B268635C300D1D216 /* SensorItem.swift */, 307 | 05E0C31D268635F200D1D216 /* SensorItem.xib */, 308 | 05646BF62685064C00707676 /* SensorsWindowController.swift */, 309 | 05646BF82685072900707676 /* SensorsWindowController.xib */, 310 | 0566B94626864492006EE45A /* SensorValue.swift */, 311 | ); 312 | path = SensorsUI; 313 | sourceTree = ""; 314 | }; 315 | /* End PBXGroup section */ 316 | 317 | /* Begin PBXHeadersBuildPhase section */ 318 | 058B8E9D2994383300263FE9 /* Headers */ = { 319 | isa = PBXHeadersBuildPhase; 320 | buildActionMask = 2147483647; 321 | files = ( 322 | ); 323 | runOnlyForDeploymentPostprocessing = 0; 324 | }; 325 | /* End PBXHeadersBuildPhase section */ 326 | 327 | /* Begin PBXNativeTarget section */ 328 | 058B8EA12994383300263FE9 /* SensorsUI */ = { 329 | isa = PBXNativeTarget; 330 | buildConfigurationList = 058B8EAF2994383300263FE9 /* Build configuration list for PBXNativeTarget "SensorsUI" */; 331 | buildPhases = ( 332 | 058B8E9D2994383300263FE9 /* Headers */, 333 | 058B8E9E2994383300263FE9 /* Sources */, 334 | 058B8E9F2994383300263FE9 /* Frameworks */, 335 | 058B8EA02994383300263FE9 /* Resources */, 336 | 058B8EC02994387900263FE9 /* Embed Frameworks */, 337 | ); 338 | buildRules = ( 339 | ); 340 | dependencies = ( 341 | ); 342 | name = SensorsUI; 343 | productName = SensorsUI; 344 | productReference = 058B8EA22994383300263FE9 /* SensorsUI.framework */; 345 | productType = "com.apple.product-type.framework"; 346 | }; 347 | /* End PBXNativeTarget section */ 348 | 349 | /* Begin PBXProject section */ 350 | 05646B92268501B300707676 /* Project object */ = { 351 | isa = PBXProject; 352 | attributes = { 353 | LastSwiftUpdateCheck = 1250; 354 | LastUpgradeCheck = 1420; 355 | TargetAttributes = { 356 | 058B8EA12994383300263FE9 = { 357 | CreatedOnToolsVersion = 14.2; 358 | }; 359 | }; 360 | }; 361 | buildConfigurationList = 05646B95268501B300707676 /* Build configuration list for PBXProject "SensorsUI" */; 362 | compatibilityVersion = "Xcode 9.3"; 363 | developmentRegion = en; 364 | hasScannedForEncodings = 0; 365 | knownRegions = ( 366 | en, 367 | Base, 368 | ); 369 | mainGroup = 05646B91268501B300707676; 370 | productRefGroup = 05646B9B268501B300707676 /* Products */; 371 | projectDirPath = ""; 372 | projectReferences = ( 373 | { 374 | ProductGroup = 058B8E90299436D900263FE9 /* Products */; 375 | ProjectRef = 058B8E8F299436D900263FE9 /* SensorsKit.xcodeproj */; 376 | }, 377 | ); 378 | projectRoot = ""; 379 | targets = ( 380 | 058B8EA12994383300263FE9 /* SensorsUI */, 381 | ); 382 | }; 383 | /* End PBXProject section */ 384 | 385 | /* Begin PBXReferenceProxy section */ 386 | 058B8E96299436D900263FE9 /* SensorsKit.framework */ = { 387 | isa = PBXReferenceProxy; 388 | fileType = wrapper.framework; 389 | path = SensorsKit.framework; 390 | remoteRef = 058B8E95299436D900263FE9 /* PBXContainerItemProxy */; 391 | sourceTree = BUILT_PRODUCTS_DIR; 392 | }; 393 | /* End PBXReferenceProxy section */ 394 | 395 | /* Begin PBXResourcesBuildPhase section */ 396 | 058B8EA02994383300263FE9 /* Resources */ = { 397 | isa = PBXResourcesBuildPhase; 398 | buildActionMask = 2147483647; 399 | files = ( 400 | 058B8EBC2994386E00263FE9 /* ThermalTemplate.pdf in Resources */, 401 | 058B8EBA2994386B00263FE9 /* SensorItem.xib in Resources */, 402 | 058B8EBD2994386E00263FE9 /* VoltageTemplate.pdf in Resources */, 403 | 058B8EB92994386B00263FE9 /* SensorsWindowController.xib in Resources */, 404 | 05BDE9EE29944B9D00B0B888 /* AmbiantLightTemplate.pdf in Resources */, 405 | 058B8EBB2994386E00263FE9 /* CurrentTemplate.pdf in Resources */, 406 | ); 407 | runOnlyForDeploymentPostprocessing = 0; 408 | }; 409 | /* End PBXResourcesBuildPhase section */ 410 | 411 | /* Begin PBXSourcesBuildPhase section */ 412 | 058B8E9E2994383300263FE9 /* Sources */ = { 413 | isa = PBXSourcesBuildPhase; 414 | buildActionMask = 2147483647; 415 | files = ( 416 | 058B8EB12994386700263FE9 /* SensorIcon.swift in Sources */, 417 | 058B8EB72994386700263FE9 /* Colors.swift in Sources */, 418 | 058B8EB22994386700263FE9 /* NSImage.swift in Sources */, 419 | 058B8EB02994386700263FE9 /* ArrayIsNotEmpty.swift in Sources */, 420 | 058B8EB62994386700263FE9 /* SensorValue.swift in Sources */, 421 | 058B8EB52994386700263FE9 /* ArrayIsEmpty.swift in Sources */, 422 | 058B8EB82994386700263FE9 /* SensorItem.swift in Sources */, 423 | 058B8EB32994386700263FE9 /* SensorGraphView.swift in Sources */, 424 | 058B8EB42994386700263FE9 /* SensorsWindowController.swift in Sources */, 425 | ); 426 | runOnlyForDeploymentPostprocessing = 0; 427 | }; 428 | /* End PBXSourcesBuildPhase section */ 429 | 430 | /* Begin PBXVariantGroup section */ 431 | 05646BF82685072900707676 /* SensorsWindowController.xib */ = { 432 | isa = PBXVariantGroup; 433 | children = ( 434 | 05646BF92685072900707676 /* Base */, 435 | ); 436 | name = SensorsWindowController.xib; 437 | sourceTree = ""; 438 | }; 439 | 05E0C31D268635F200D1D216 /* SensorItem.xib */ = { 440 | isa = PBXVariantGroup; 441 | children = ( 442 | 05E0C31E268635F200D1D216 /* Base */, 443 | ); 444 | name = SensorItem.xib; 445 | sourceTree = ""; 446 | }; 447 | /* End PBXVariantGroup section */ 448 | 449 | /* Begin XCBuildConfiguration section */ 450 | 05646BA6268501B400707676 /* Debug */ = { 451 | isa = XCBuildConfiguration; 452 | baseConfigurationReference = 05646BE6268503D300707676 /* Debug - Library.xcconfig */; 453 | buildSettings = { 454 | MACOSX_DEPLOYMENT_TARGET = 11.0; 455 | }; 456 | name = Debug; 457 | }; 458 | 05646BA7268501B400707676 /* Release */ = { 459 | isa = XCBuildConfiguration; 460 | baseConfigurationReference = 05646BBE268503D300707676 /* Release - Library.xcconfig */; 461 | buildSettings = { 462 | MACOSX_DEPLOYMENT_TARGET = 11.0; 463 | }; 464 | name = Release; 465 | }; 466 | 058B8EAA2994383300263FE9 /* Debug */ = { 467 | isa = XCBuildConfiguration; 468 | buildSettings = { 469 | CURRENT_PROJECT_VERSION = 1; 470 | DYLIB_COMPATIBILITY_VERSION = 1; 471 | DYLIB_CURRENT_VERSION = 1; 472 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 473 | GENERATE_INFOPLIST_FILE = YES; 474 | INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2023 XS-Labs. All rights reserved."; 475 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 476 | LD_RUNPATH_SEARCH_PATHS = ( 477 | "$(inherited)", 478 | "@executable_path/../Frameworks", 479 | "@loader_path/Frameworks", 480 | ); 481 | MARKETING_VERSION = 1.0; 482 | PRODUCT_BUNDLE_IDENTIFIER = "com.xs-labs.SensorsUI"; 483 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 484 | VERSIONING_SYSTEM = "apple-generic"; 485 | VERSION_INFO_PREFIX = ""; 486 | }; 487 | name = Debug; 488 | }; 489 | 058B8EAB2994383300263FE9 /* Release */ = { 490 | isa = XCBuildConfiguration; 491 | buildSettings = { 492 | CURRENT_PROJECT_VERSION = 1; 493 | DYLIB_COMPATIBILITY_VERSION = 1; 494 | DYLIB_CURRENT_VERSION = 1; 495 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 496 | GENERATE_INFOPLIST_FILE = YES; 497 | INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2023 XS-Labs. All rights reserved."; 498 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 499 | LD_RUNPATH_SEARCH_PATHS = ( 500 | "$(inherited)", 501 | "@executable_path/../Frameworks", 502 | "@loader_path/Frameworks", 503 | ); 504 | MARKETING_VERSION = 1.0; 505 | PRODUCT_BUNDLE_IDENTIFIER = "com.xs-labs.SensorsUI"; 506 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 507 | VERSIONING_SYSTEM = "apple-generic"; 508 | VERSION_INFO_PREFIX = ""; 509 | }; 510 | name = Release; 511 | }; 512 | /* End XCBuildConfiguration section */ 513 | 514 | /* Begin XCConfigurationList section */ 515 | 05646B95268501B300707676 /* Build configuration list for PBXProject "SensorsUI" */ = { 516 | isa = XCConfigurationList; 517 | buildConfigurations = ( 518 | 05646BA6268501B400707676 /* Debug */, 519 | 05646BA7268501B400707676 /* Release */, 520 | ); 521 | defaultConfigurationIsVisible = 0; 522 | defaultConfigurationName = Release; 523 | }; 524 | 058B8EAF2994383300263FE9 /* Build configuration list for PBXNativeTarget "SensorsUI" */ = { 525 | isa = XCConfigurationList; 526 | buildConfigurations = ( 527 | 058B8EAA2994383300263FE9 /* Debug */, 528 | 058B8EAB2994383300263FE9 /* Release */, 529 | ); 530 | defaultConfigurationIsVisible = 0; 531 | defaultConfigurationName = Release; 532 | }; 533 | /* End XCConfigurationList section */ 534 | }; 535 | rootObject = 05646B92268501B300707676 /* Project object */; 536 | } 537 | -------------------------------------------------------------------------------- /SensorsUI.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /SensorsUI.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /SensorsUI/ArrayIsEmpty.swift: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2023, Jean-David Gadina - www.xs-labs.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the Software), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | ******************************************************************************/ 24 | 25 | import Cocoa 26 | 27 | @objc( ArrayIsEmpty ) 28 | public class ArrayIsEmpty: ValueTransformer 29 | { 30 | public override class func transformedValueClass() -> AnyClass 31 | { 32 | NSNumber.self 33 | } 34 | 35 | public override class func allowsReverseTransformation() -> Bool 36 | { 37 | false 38 | } 39 | 40 | public override func transformedValue( _ value: Any? ) -> Any? 41 | { 42 | guard let array = value as? NSArray 43 | else 44 | { 45 | return NSNumber( booleanLiteral: true ) 46 | } 47 | 48 | return NSNumber( booleanLiteral: array.count == 0 ) 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /SensorsUI/ArrayIsNotEmpty.swift: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2023, Jean-David Gadina - www.xs-labs.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the Software), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | ******************************************************************************/ 24 | 25 | import Cocoa 26 | 27 | @objc( ArrayIsNotEmpty ) 28 | public class ArrayIsNotEmpty: ValueTransformer 29 | { 30 | public override class func transformedValueClass() -> AnyClass 31 | { 32 | NSNumber.self 33 | } 34 | 35 | public override class func allowsReverseTransformation() -> Bool 36 | { 37 | false 38 | } 39 | 40 | public override func transformedValue( _ value: Any? ) -> Any? 41 | { 42 | guard let array = value as? NSArray 43 | else 44 | { 45 | return NSNumber( booleanLiteral: false ) 46 | } 47 | 48 | return NSNumber( booleanLiteral: array.count > 0 ) 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /SensorsUI/Base.lproj/SensorItem.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | SensorIcon 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | SensorValue 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | SensorValue 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | SensorValue 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | -------------------------------------------------------------------------------- /SensorsUI/Base.lproj/SensorsWindowController.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 56 | 60 | 61 | 62 | 63 | ArrayIsEmpty 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 96 | 106 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 152 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | ArrayIsEmpty 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | NSNegateBoolean 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | NSNegateBoolean 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | ArrayIsNotEmpty 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | -------------------------------------------------------------------------------- /SensorsUI/Colors.swift: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2023, Jean-David Gadina - www.xs-labs.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the Software), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | ******************************************************************************/ 24 | 25 | import Cocoa 26 | import SensorsKit 27 | 28 | public class Colors 29 | { 30 | public class func color( for kind: SensorHistoryData.Kind ) -> NSColor 31 | { 32 | switch kind 33 | { 34 | case .thermal: return NSColor.systemOrange 35 | case .voltage: return NSColor.systemPurple 36 | case .current: return NSColor.systemTeal 37 | case .ambiantLight: return NSColor.systemYellow 38 | 39 | @unknown default: return NSColor.clear 40 | } 41 | } 42 | 43 | private init() 44 | {} 45 | } 46 | -------------------------------------------------------------------------------- /SensorsUI/Images/AmbiantLightTemplate.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macmade/Sensors/d49fe30dce55c5cf7862e711dc3629cfd0fcb05d/SensorsUI/Images/AmbiantLightTemplate.pdf -------------------------------------------------------------------------------- /SensorsUI/Images/CurrentTemplate.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macmade/Sensors/d49fe30dce55c5cf7862e711dc3629cfd0fcb05d/SensorsUI/Images/CurrentTemplate.pdf -------------------------------------------------------------------------------- /SensorsUI/Images/ThermalTemplate.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macmade/Sensors/d49fe30dce55c5cf7862e711dc3629cfd0fcb05d/SensorsUI/Images/ThermalTemplate.pdf -------------------------------------------------------------------------------- /SensorsUI/Images/VoltageTemplate.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macmade/Sensors/d49fe30dce55c5cf7862e711dc3629cfd0fcb05d/SensorsUI/Images/VoltageTemplate.pdf -------------------------------------------------------------------------------- /SensorsUI/NSImage.swift: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2023, Jean-David Gadina - www.xs-labs.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the Software), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | ******************************************************************************/ 24 | 25 | import Cocoa 26 | 27 | public extension NSImage 28 | { 29 | func tinted( with color: NSColor ) -> NSImage 30 | { 31 | guard let copy = self.copy() as? NSImage 32 | else 33 | { 34 | return self 35 | } 36 | 37 | copy.isTemplate = false 38 | let rect = NSRect( origin: NSZeroPoint, size: copy.size ) 39 | 40 | copy.lockFocus() 41 | color.set() 42 | rect.fill( using: .sourceAtop ) 43 | copy.unlockFocus() 44 | 45 | return copy 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /SensorsUI/SensorGraphView.swift: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2023, Jean-David Gadina - www.xs-labs.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the Software), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | ******************************************************************************/ 24 | 25 | import Cocoa 26 | import SensorsKit 27 | 28 | public class SensorGraphView: NSView 29 | { 30 | @objc 31 | public enum GraphStyle: Int 32 | { 33 | case gradient 34 | case line 35 | case fill 36 | case bars 37 | } 38 | 39 | @objc public dynamic var sensor: SensorHistoryData? 40 | { 41 | didSet 42 | { 43 | self.needsDisplay = true 44 | } 45 | } 46 | 47 | private var defaultsObserver: Any? 48 | 49 | public override init( frame: NSRect ) 50 | { 51 | super.init( frame: frame ) 52 | 53 | self.defaultsObserver = NotificationCenter.default.addObserver( forName: UserDefaults.didChangeNotification, object: nil, queue: nil ) 54 | { 55 | [ weak self ] _ in self?.needsDisplay = true 56 | } 57 | } 58 | 59 | required init?( coder: NSCoder ) 60 | { 61 | super.init( coder: coder ) 62 | 63 | self.defaultsObserver = NotificationCenter.default.addObserver( forName: UserDefaults.didChangeNotification, object: nil, queue: nil ) 64 | { 65 | [ weak self ] _ in self?.needsDisplay = true 66 | } 67 | } 68 | 69 | public override func draw( _ rect: NSRect ) 70 | { 71 | let rect = self.bounds 72 | let style = GraphStyle( rawValue: UserDefaults.standard.integer( forKey: "sensorsWindowGraphStyle" ) ) ?? .bars 73 | 74 | self.drawBorder( in: rect, style: style ) 75 | self.drawBackground( in: rect, style: style ) 76 | 77 | guard let sensor = self.sensor, sensor.values.count >= 2 78 | else 79 | { 80 | return 81 | } 82 | 83 | let values = sensor.values.map { CGFloat( $0.doubleValue ) } 84 | var min: CGFloat = values.min() ?? 0 85 | var max: CGFloat = values.max() ?? 0 86 | 87 | if sensor.kind == .thermal, min >= 0, max <= 100 88 | { 89 | min = 0 90 | max = 100 91 | } 92 | 93 | if style == .bars 94 | { 95 | self.drawBars( 96 | in: rect, 97 | kind: sensor.kind, 98 | values: values, 99 | min: min, 100 | max: max, 101 | color: Colors.color( for: sensor.kind ) 102 | ) 103 | } 104 | else 105 | { 106 | self.drawGraph( 107 | in: rect.insetBy( dx: 10, dy: 10 ), 108 | kind: sensor.kind, 109 | values: values, 110 | min: min, 111 | max: max, 112 | color: Colors.color( for: sensor.kind ), 113 | style: style 114 | ) 115 | } 116 | } 117 | 118 | private func drawBorder( in rect: NSRect, style: GraphStyle ) 119 | { 120 | if style == .bars 121 | { 122 | return 123 | } 124 | 125 | let border = NSBezierPath( roundedRect: rect.insetBy( dx: 1, dy: 1 ), xRadius: 10, yRadius: 10 ) 126 | border.lineWidth = 1 127 | 128 | NSColor.gray.setStroke() 129 | border.stroke() 130 | } 131 | 132 | private func drawBackground( in rect: NSRect, style: GraphStyle ) 133 | { 134 | if style == .bars 135 | { 136 | let c = 15 137 | let h = rect.size.height / CGFloat( c ) 138 | let n = rect.size.width / h 139 | 140 | for i in 0 ..< Int( n ) 141 | { 142 | for j in 0 ..< c 143 | { 144 | let square = NSRect( x: rect.origin.x + h * CGFloat( i ), y: rect.origin.y + h * CGFloat( j ), width: h, height: h ).insetBy( dx: 1, dy: 1 ) 145 | 146 | NSColor.gray.withAlphaComponent( 0.2 ).setFill() 147 | square.fill() 148 | } 149 | } 150 | } 151 | else 152 | { 153 | let border = NSBezierPath( roundedRect: rect.insetBy( dx: 1, dy: 1 ), xRadius: 10, yRadius: 10 ) 154 | 155 | NSColor.gray.withAlphaComponent( 0.2 ).setFill() 156 | border.fill() 157 | } 158 | } 159 | 160 | private func drawGraph( in rect: NSRect, kind: SensorHistoryData.Kind, values: [ CGFloat ], min: CGFloat, max: CGFloat, color: NSColor, style: GraphStyle ) 161 | { 162 | let p1 = NSBezierPath() 163 | let p2 = NSBezierPath() 164 | p1.lineWidth = 1 165 | p2.lineWidth = 0 166 | 167 | if min == max, kind != .thermal 168 | { 169 | p1.move( to: NSPoint( x: rect.origin.x, y: rect.origin.y + rect.size.height / 2 ) ) 170 | p1.line( to: NSPoint( x: rect.origin.x + rect.size.width, y: rect.origin.y + rect.size.height / 2 ) ) 171 | p2.move( to: NSPoint( x: rect.origin.x, y: rect.origin.y + rect.size.height / 2 ) ) 172 | p2.line( to: NSPoint( x: rect.origin.x + rect.size.width, y: rect.origin.y + rect.size.height / 2 ) ) 173 | } 174 | else 175 | { 176 | for i in 0 ..< values.count 177 | { 178 | let value = values[ i ] 179 | let dx = rect.size.width / CGFloat( values.count - 1 ) 180 | let x = rect.origin.x + CGFloat( i ) * dx 181 | let v = ( value - min ) / ( max - min ) 182 | let y = rect.origin.y + v * rect.size.height 183 | 184 | if x.isNaN || y.isNaN 185 | { 186 | return 187 | } 188 | 189 | if i == 0 190 | { 191 | p1.move( to: NSPoint( x: x, y: y ) ) 192 | p2.move( to: NSPoint( x: x, y: y ) ) 193 | } 194 | else 195 | { 196 | p1.line( to: NSPoint( x: x, y: y ) ) 197 | p2.line( to: NSPoint( x: x, y: y ) ) 198 | } 199 | } 200 | } 201 | 202 | p2.line( to: NSPoint( x: rect.origin.x + rect.size.width, y: rect.origin.y - 3 ) ) 203 | p2.line( to: NSPoint( x: rect.origin.x, y: rect.origin.y - 3 ) ) 204 | p2.close() 205 | 206 | if style == .gradient 207 | { 208 | let gradient = NSGradient( colors: [ color.withAlphaComponent( 0.25 ), color.withAlphaComponent( 0 ) ] ) 209 | 210 | gradient?.draw( in: p2, angle: -90 ) 211 | } 212 | else if style == .fill 213 | { 214 | color.setFill() 215 | p2.fill() 216 | } 217 | 218 | color.setStroke() 219 | p1.stroke() 220 | } 221 | 222 | private func drawBars( in rect: NSRect, kind: SensorHistoryData.Kind, values: [ CGFloat ], min: CGFloat, max: CGFloat, color: NSColor ) 223 | { 224 | let c = 15 225 | let h = rect.size.height / CGFloat( c ) 226 | let n = rect.size.width / h 227 | 228 | let values = Array( values.suffix( Int( n ) ) ) 229 | 230 | for i in 0 ..< Int( n ) 231 | { 232 | if i >= values.count 233 | { 234 | return 235 | } 236 | 237 | let v = values[ i ] 238 | let p = ( v - min ) / ( max - min ) 239 | 240 | for j in 0 ..< c 241 | { 242 | if CGFloat( j ) / CGFloat( c ) > p 243 | { 244 | break 245 | } 246 | 247 | let square = NSRect( x: rect.origin.x + h * CGFloat( i ), y: rect.origin.y + h * CGFloat( j ), width: h, height: h ).insetBy( dx: 1, dy: 1 ) 248 | 249 | color.setFill() 250 | square.fill() 251 | } 252 | } 253 | } 254 | } 255 | -------------------------------------------------------------------------------- /SensorsUI/SensorIcon.swift: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2023, Jean-David Gadina - www.xs-labs.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the Software), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | ******************************************************************************/ 24 | 25 | import Cocoa 26 | import SensorsKit 27 | 28 | @objc( SensorIcon ) 29 | public class SensorIcon: ValueTransformer 30 | { 31 | public override class func transformedValueClass() -> AnyClass 32 | { 33 | NSImage.self 34 | } 35 | 36 | public override class func allowsReverseTransformation() -> Bool 37 | { 38 | false 39 | } 40 | 41 | public override func transformedValue( _ value: Any? ) -> Any? 42 | { 43 | guard let data = value as? SensorHistoryData 44 | else 45 | { 46 | return nil 47 | } 48 | 49 | switch data.kind 50 | { 51 | case .thermal: return self.image( named: "ThermalTemplate" )?.tinted( with: Colors.color( for: data.kind ) ) 52 | case .voltage: return self.image( named: "VoltageTemplate" )?.tinted( with: Colors.color( for: data.kind ) ) 53 | case .current: return self.image( named: "CurrentTemplate" )?.tinted( with: Colors.color( for: data.kind ) ) 54 | case .ambiantLight: return self.image( named: "AmbiantLightTemplate" )?.tinted( with: Colors.color( for: data.kind ) ) 55 | 56 | @unknown default: return nil 57 | } 58 | } 59 | 60 | private func image( named name: String ) -> NSImage? 61 | { 62 | Bundle( for: SensorIcon.self ).image( forResource: name ) 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /SensorsUI/SensorItem.swift: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2023, Jean-David Gadina - www.xs-labs.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the Software), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | ******************************************************************************/ 24 | 25 | import Cocoa 26 | import SensorsKit 27 | 28 | public class SensorItem: NSCollectionViewItem 29 | { 30 | @objc public dynamic var sensor: SensorHistoryData? 31 | { 32 | didSet 33 | { 34 | self.graph.sensor = self.sensor 35 | } 36 | } 37 | 38 | private var graph = SensorGraphView() 39 | 40 | @IBOutlet private var graphContainer: NSView! 41 | 42 | public override func viewDidLoad() 43 | { 44 | super.viewDidLoad() 45 | 46 | self.graph.translatesAutoresizingMaskIntoConstraints = false 47 | self.graph.frame = self.graphContainer.bounds 48 | 49 | self.graphContainer.addSubview( self.graph ) 50 | self.graphContainer.addConstraint( NSLayoutConstraint( item: self.graph, attribute: .width, relatedBy: .equal, toItem: self.graphContainer, attribute: .width, multiplier: 1, constant: 0 ) ) 51 | self.graphContainer.addConstraint( NSLayoutConstraint( item: self.graph, attribute: .height, relatedBy: .equal, toItem: self.graphContainer, attribute: .height, multiplier: 1, constant: 0 ) ) 52 | self.graphContainer.addConstraint( NSLayoutConstraint( item: self.graph, attribute: .centerX, relatedBy: .equal, toItem: self.graphContainer, attribute: .centerX, multiplier: 1, constant: 0 ) ) 53 | self.graphContainer.addConstraint( NSLayoutConstraint( item: self.graph, attribute: .centerY, relatedBy: .equal, toItem: self.graphContainer, attribute: .centerY, multiplier: 1, constant: 0 ) ) 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /SensorsUI/SensorValue.swift: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2023, Jean-David Gadina - www.xs-labs.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the Software), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | ******************************************************************************/ 24 | 25 | import Cocoa 26 | 27 | @objc( SensorValue ) 28 | public class SensorValue: ValueTransformer 29 | { 30 | public override class func transformedValueClass() -> AnyClass 31 | { 32 | NSString.self 33 | } 34 | 35 | public override class func allowsReverseTransformation() -> Bool 36 | { 37 | false 38 | } 39 | 40 | public override func transformedValue( _ value: Any? ) -> Any? 41 | { 42 | guard let n = value as? NSNumber 43 | else 44 | { 45 | return "--" 46 | } 47 | 48 | return String( format: "%.02f", n.doubleValue ) 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /SensorsUI/SensorsWindowController.swift: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2023, Jean-David Gadina - www.xs-labs.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the Software), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | ******************************************************************************/ 24 | 25 | import Cocoa 26 | import SensorsKit 27 | 28 | public class SensorsWindowController: NSWindowController 29 | { 30 | @objc private dynamic var sensors = Sensors() 31 | 32 | @objc private dynamic var showTemperature = UserDefaults.standard.object( forKey: "sensorsWindowShowTemperature" ) as? Bool ?? true 33 | { 34 | didSet 35 | { 36 | self.updateFilters() 37 | UserDefaults.standard.set( self.showTemperature, forKey: "sensorsWindowShowTemperature" ) 38 | } 39 | } 40 | 41 | @objc private dynamic var showVoltage = UserDefaults.standard.object( forKey: "sensorsWindowShowVoltage" ) as? Bool ?? true 42 | { 43 | didSet 44 | { 45 | self.updateFilters() 46 | UserDefaults.standard.set( self.showVoltage, forKey: "sensorsWindowShowVoltage" ) 47 | } 48 | } 49 | 50 | @objc private dynamic var showCurrent = UserDefaults.standard.object( forKey: "sensorsWindowShowCurrent" ) as? Bool ?? true 51 | { 52 | didSet 53 | { 54 | self.updateFilters() 55 | UserDefaults.standard.set( self.showCurrent, forKey: "sensorsWindowShowCurrent" ) 56 | } 57 | } 58 | 59 | @objc private dynamic var showAmbiantLight = UserDefaults.standard.object( forKey: "sensorsWindowShowAmbiantLight" ) as? Bool ?? true 60 | { 61 | didSet 62 | { 63 | self.updateFilters() 64 | UserDefaults.standard.set( self.showAmbiantLight, forKey: "sensorsWindowShowAmbiantLight" ) 65 | } 66 | } 67 | 68 | @objc private dynamic var showIOHID = UserDefaults.standard.object( forKey: "sensorsWindowShowIOHID" ) as? Bool ?? true 69 | { 70 | didSet 71 | { 72 | self.updateFilters() 73 | UserDefaults.standard.set( self.showIOHID, forKey: "sensorsWindowShowIOHID" ) 74 | } 75 | } 76 | 77 | @objc private dynamic var showSMC = UserDefaults.standard.object( forKey: "sensorsWindowShowSMC" ) as? Bool ?? true 78 | { 79 | didSet 80 | { 81 | self.updateFilters() 82 | UserDefaults.standard.set( self.showSMC, forKey: "sensorsWindowShowSMC" ) 83 | } 84 | } 85 | 86 | @objc private dynamic var sorting = UserDefaults.standard.integer( forKey: "sensorsWindowSorting" ) 87 | { 88 | didSet 89 | { 90 | self.updateFilters() 91 | UserDefaults.standard.set( self.sorting, forKey: "sensorsWindowSorting" ) 92 | } 93 | } 94 | 95 | @objc private dynamic var searchText: String? 96 | { 97 | didSet { self.updateFilters() } 98 | } 99 | 100 | @objc private dynamic var graphStyle = UserDefaults.standard.integer( forKey: "sensorsWindowGraphStyle" ) 101 | { 102 | didSet 103 | { 104 | UserDefaults.standard.set( self.graphStyle, forKey: "sensorsWindowGraphStyle" ) 105 | } 106 | } 107 | 108 | @IBOutlet private var collectionView: NSCollectionView! 109 | @IBOutlet private var arrayController: NSArrayController! 110 | 111 | public override var windowNibName: NSNib.Name? 112 | { 113 | "SensorsWindowController" 114 | } 115 | 116 | public override func windowDidLoad() 117 | { 118 | super.windowDidLoad() 119 | 120 | self.arrayController.sortDescriptors = [ NSSortDescriptor( key: "name", ascending: true, selector: #selector( NSString.localizedCaseInsensitiveCompare( _: ) ) ) ] 121 | 122 | self.updateFilters() 123 | } 124 | 125 | public func stop( completion: ( () -> Void )? ) 126 | { 127 | self.sensors.stop( completion: completion ) 128 | } 129 | 130 | private func updateFilters() 131 | { 132 | var predicates = [ NSPredicate ]() 133 | 134 | if self.showTemperature == false 135 | { 136 | predicates.append( NSPredicate { o, i in ( o as? SensorHistoryData )?.kind != .thermal } ) 137 | } 138 | 139 | if self.showVoltage == false 140 | { 141 | predicates.append( NSPredicate { o, i in ( o as? SensorHistoryData )?.kind != .voltage } ) 142 | } 143 | 144 | if self.showCurrent == false 145 | { 146 | predicates.append( NSPredicate { o, i in ( o as? SensorHistoryData )?.kind != .current } ) 147 | } 148 | 149 | if self.showAmbiantLight == false 150 | { 151 | predicates.append( NSPredicate { o, i in ( o as? SensorHistoryData )?.kind != .ambiantLight } ) 152 | } 153 | 154 | if self.showIOHID == false 155 | { 156 | predicates.append( NSPredicate { o, i in ( o as? SensorHistoryData )?.source != .hid } ) 157 | } 158 | 159 | if self.showSMC == false 160 | { 161 | predicates.append( NSPredicate { o, i in ( o as? SensorHistoryData )?.source != .smc } ) 162 | } 163 | 164 | if let search = self.searchText, search.count > 0 165 | { 166 | predicates.append( NSPredicate( format: "name contains[c] %@", search ) ) 167 | } 168 | 169 | let descriptors = 170 | [ 171 | NSSortDescriptor( key: "name", ascending: true, selector: #selector( NSString.localizedCaseInsensitiveCompare( _: ) ) ), 172 | NSSortDescriptor( key: "last", ascending: false ), 173 | ] 174 | 175 | self.arrayController.sortDescriptors = self.sorting == 1 ? descriptors.reversed() : descriptors 176 | 177 | if predicates.count > 0 178 | { 179 | self.arrayController.filterPredicate = NSCompoundPredicate( andPredicateWithSubpredicates: predicates ) 180 | } 181 | else 182 | { 183 | self.arrayController.filterPredicate = nil 184 | } 185 | } 186 | } 187 | 188 | extension SensorsWindowController: NSCollectionViewDataSource 189 | { 190 | public func numberOfSections( in collectionView: NSCollectionView ) -> Int 191 | { 192 | 1 193 | } 194 | 195 | public func collectionView( _ collectionView: NSCollectionView, numberOfItemsInSection section: Int ) -> Int 196 | { 197 | ( self.arrayController.arrangedObjects as? [ SensorHistoryData ] )?.count ?? 0 198 | } 199 | 200 | public func collectionView( _ itemForRepresentedObjectAtcollectionView: NSCollectionView, itemForRepresentedObjectAt indexPath: IndexPath ) -> NSCollectionViewItem 201 | { 202 | let item = self.collectionView.makeItem( withIdentifier: NSUserInterfaceItemIdentifier( rawValue: "SensorItem" ), for: indexPath ) 203 | 204 | if let item = item as? SensorItem, let sensors = self.arrayController.arrangedObjects as? [ SensorHistoryData ] 205 | { 206 | if sensors.count > indexPath.item 207 | { 208 | item.sensor = sensors[ indexPath.item ] 209 | } 210 | } 211 | 212 | return item 213 | } 214 | } 215 | --------------------------------------------------------------------------------