diff --git a/.gitattributes b/.gitattributes index 7bbb636b..433e97d6 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,3 +1,4 @@ -*.swift text eol=lf +*.html text eol=lf *.md text eol=lf -.gitmodules text eol=lf +*.yml text eol=lf +Gemfile text eol=lf diff --git a/.github/codecov.yml b/.github/codecov.yml deleted file mode 100644 index cb5a48a3..00000000 --- a/.github/codecov.yml +++ /dev/null @@ -1,12 +0,0 @@ -comment: - layout: "diff,files" - behavior: new -coverage: - status: - project: true - patch: true - changes: true -ignore: - - "Examples/**/*" - - "Tests/**/*" - - "Packages/**/*" diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml deleted file mode 100644 index c52b2b3d..00000000 --- a/.github/workflows/build.yml +++ /dev/null @@ -1,62 +0,0 @@ -name: build - -on: - pull_request: - branches: - - main - paths: - - '**/*.swift' - - '.github/workflows/build.yml' - workflow_dispatch: - -jobs: - build: - runs-on: windows-latest - - strategy: - fail-fast: false - matrix: - include: - - branch: swift-5.4.3-release - tag: 5.4.3-RELEASE - options: '-Xmanifest -use-ld=link -Xswiftc -use-ld=link' - - - branch: swift-5.5.3-release - tag: 5.5.3-RELEASE - options: '-Xmanifest -use-ld=link -Xswiftc -use-ld=link' - - - branch: swift-5.6.3-release - tag: 5.6.3-RELEASE - options: '' - - - branch: swift-5.7.3-release - tag: 5.7.3-RELEASE - options: '' - - - branch: swift-5.8.1-release - tag: 5.8.1-RELEASE - options: '' - - - branch: swift-5.9.1-release - tag: 5.9.1-RELEASE - options: '' - - - branch: development - tag: DEVELOPMENT-SNAPSHOT-2023-08-12-a - options: '' - - name: Swift ${{ matrix.tag }} - - steps: - - uses: compnerd/gha-setup-swift@main - with: - tag: ${{ matrix.tag }} - branch: ${{ matrix.branch }} - - - uses: actions/checkout@v3 - - - name: Build - run: swift build -v ${{ matrix.options }} - - - name: Run tests - run: swift test -v -Xswiftc -DENABLE_TESTING ${{ matrix.options }} diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml deleted file mode 100644 index 7e5ff9eb..00000000 --- a/.github/workflows/coverage.yml +++ /dev/null @@ -1,51 +0,0 @@ -name: coverage - -on: - push: - branches: - - main - paths: - - '**/*.swift' - - '.github/workflows/coverage.yml' - - '!Examples/**/*.swift' - pull_request: - branches: - - main - paths: - - '**/*.swift' - - '.github/workflows/coverage.yml' - - '!Examples/**/*.swift' - workflow_dispatch: - -jobs: - coverage: - runs-on: windows-latest - - strategy: - matrix: - include: - - branch: swift-5.9-release - tag: 5.9-RELEASE - - steps: - - uses: actions/checkout@v2 - - uses: seanmiddleditch/gha-setup-vsdevenv@master - - uses: compnerd/gha-setup-swift@main - with: - tag: ${{ matrix.tag }} - branch: ${{ matrix.branch }} - - - name: Build - run: swift build -v - - - name: Run tests - run: swift test -v -Xswiftc -DENABLE_TESTING --enable-code-coverage - - - name: Process Coverage - run: | - llvm-cov export -format lcov -ignore-filename-regex ".build|Tests|Examples" -instr-profile .build\x86_64-unknown-windows-msvc\debug\codecov\default.profdata .build\x86_64-unknown-windows-msvc\debug\SwiftWin32PackageTests.xctest > coverage.lcov - - - uses: codecov/codecov-action@v3 - with: - token: ${{ secrets.CODECOV_TOKEN }} - files: coverage.lcov diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml deleted file mode 100644 index 41389425..00000000 --- a/.github/workflows/lint.yml +++ /dev/null @@ -1,27 +0,0 @@ -name: lint - -on: - pull_request: - branches: - - main - paths: - - '**/*.swift' - -jobs: - lint: - runs-on: windows-latest - - steps: - - uses: compnerd/gha-setup-swift@main - with: - branch: swift-5.8-release - tag: 5.8-RELEASE - - name: Install swift-format - run: | - Install-Binary -Url "https://github.com/compnerd/swift-build/releases/download/swift-format-5.8-RELEASE/swift-format.msi" -Name "swift-format.msi" -ArgumentList ("-q") - - - uses: actions/checkout@v2 - - - uses: compnerd/swift-format-linter-action@main - with: - github-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore index de66424b..ba584468 100644 --- a/.gitignore +++ b/.gitignore @@ -1,15 +1,5 @@ -# git ls-files --others --exclude-from=.git/info/exclude -# Lines that start with '#' are comments. -# For a project mostly in C, the following would be a good set of -# exclude patterns (uncomment them if you want to use them): - -.*.sw[nop] -*~ - -/build/ - -/package.resolved -/Packages/ -.build/ - -.vscode/ +_site +.sass-cache +.jekyll-cache +.jeykll-metadata +vendor diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 23c85fc2..00000000 --- a/.gitmodules +++ /dev/null @@ -1,12 +0,0 @@ -[submodule "Packages/cassowary"] - path = Packages/cassowary - url = https://github.com/compnerd/cassowary -[submodule "Packages/SwiftCOM"] - path = Packages/SwiftCOM - url = https://github.com/compnerd/swift-com -[submodule "Packages/swift-log"] - path = Packages/swift-log - url = https://github.com/apple/swift-log -[submodule "Packages/swift-collections"] - path = Packages/swift-collections - url = https://github.com/apple/swift-collections diff --git a/.swift-format b/.swift-format deleted file mode 100644 index 37c59f44..00000000 --- a/.swift-format +++ /dev/null @@ -1,9 +0,0 @@ -{ - "version": 1, - "rules": { - "AllPublicDeclarationsHaveDocumentation": true, - "AlwaysUseLowerCamelCase": false, - "UseShorthandTypeNames": false, - "ValidateDocumentationComments": true - } -} diff --git a/.vscode/extensions.json b/.vscode/extensions.json deleted file mode 100644 index 9ab73d1e..00000000 --- a/.vscode/extensions.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "recommendations": [ - "exodiusstudios.comment-anchors", - "sswg.swift-lang" - ] -} diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 9e3ec7e8..00000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "cmake.configureOnOpen": false, - "commentAnchors.tags.list": [ - { - "tag": "MARK", - "iconColor": "default", - "highlightColor": "#A8C023", - "scope": "file" - }, - { - "tag": "TODO", - "iconColor": "blue", - "highlightColor": "#3ea8ff", - "scope": "workspace" - }, - { - "tag": "FIXME", - "iconColor": "red", - "highlightColor": "#F44336", - "scope": "workspace" - }, - { - "tag": "NOTE", - "iconColor": "orange", - "highlightColor": "#FFB300", - "scope": "file" - }, - ], - "files.exclude": { - ".git": true, - ".build": true, - ".*.sw?": true, - "**/.DS_Store": true - } -} diff --git a/.vscode/tasks.json b/.vscode/tasks.json deleted file mode 100644 index 1d41a3a0..00000000 --- a/.vscode/tasks.json +++ /dev/null @@ -1,159 +0,0 @@ -// See https://go.microsoft.com/fwlink/?LinkId=733558 -// for the documentation about the tasks.json format -{ - "version": "2.0.0", - "problemMatcher": { - "owner": "swift", - "fileLocation": "autoDetect", - "pattern": { - "regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$", - "file": 1, - "line": 2, - "column": 3, - "severity": 4, - "message": 5 - } - }, - "tasks": [ - { - "label": "Build (Debug DWARF)", - "type": "shell", - "command": "swift", - "args": [ - "build", - "-c", "debug", - "-Xlinker", "-debug:dwarf", - ], - "group": { - "kind": "build", - "isDefault": true - }, - "windows": { - "options": { - "shell": { - "executable": "C:\\WINDOWS\\System32\\cmd.exe", - "args": [ - "/d", - "/c", - ] - } - } - } - }, - { - "label": "Build (Debug PDB)", - "type": "shell", - "command": "swift", - "args": [ - "build", - "-c", "debug", - "-Xswiftc", "-g", - "-Xswiftc", "-debug-info-format=codeview", - "-Xlinker", "-debug", - ], - "group": "build", - "windows": { - "options": { - "shell": { - "executable": "C:\\WINDOWS\\System32\\cmd.exe", - "args": [ - "/d", - "/c", - ] - } - } - } - }, - { - "label": "Build (Release)", - "type": "shell", - "command": "swift", - "args": [ - "build", - "-c", "release", - ], - "group": "build", - "windows": { - "options": { - "shell": { - "executable": "C:\\WINDOWS\\System32\\cmd.exe", - "args": [ - "/d", - "/c", - ] - } - } - } - }, - { - "label": "Test (Debug)", - "type": "shell", - "command": "swift", - "args": [ - "test", - "-c", "debug", - "-Xswiftc", "-DENABLE_TESTING", - ], - "group": { - "kind": "test", - "isDefault": true - }, - "windows": { - "options": { - "shell": { - "executable": "C:\\WINDOWS\\System32\\cmd.exe", - "args": [ - "/d", - "/c", - ] - } - } - }, - }, - { - "label": "Test (Coverage)", - "command": "swift", - "type": "shell", - "args": [ - "test", - "-c", "debug", - "-Xswiftc", "-DENABLE_TESTING", - "--enable-code-coverage", - ], - "group": "test", - "windows": { - "options": { - "shell": { - "executable": "C:\\WINDOWS\\System32\\cmd.exe", - "args": [ - "/d", - "/c", - ] - } - } - } - }, - { - "label": "Test (Release)", - "command": "swift", - "type": "shell", - "args": [ - "test", - "-c", "release", - "-Xswiftc", "-DENABLE_TESTING", - ], - "group": "test", - "windows": { - "options": { - "shell": { - "executable": "C:\\WINDOWS\\System32\\cmd.exe", - "args": [ - "/d", - "/c", - ] - } - } - } - } - ] -} diff --git a/404.html b/404.html new file mode 100644 index 00000000..086a5c9e --- /dev/null +++ b/404.html @@ -0,0 +1,25 @@ +--- +permalink: /404.html +layout: default +--- + + + +
+

404

+ +

Page not found :(

+

The requested page could not be found.

+
diff --git a/CMakeLists.txt b/CMakeLists.txt deleted file mode 100644 index f16e0b69..00000000 --- a/CMakeLists.txt +++ /dev/null @@ -1,71 +0,0 @@ -#[[ -Copyright © 2019 Saleem Abdulrasool -All rights reserved. - -SPDX-License-Identifier: BSD-3-Clause -#]] - -cmake_minimum_required(VERSION 3.16.0) - -project(SwiftWin32 - LANGUAGES C Swift) - -list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake/Modules) - -set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) -set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) -set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) -set(CMAKE_Swift_MODULE_DIRECTORY ${CMAKE_BINARY_DIR}/swift) - -find_package(dispatch CONFIG QUIET) -find_package(Foundation CONFIG QUIET) - -find_package(Git REQUIRED) -execute_process(COMMAND ${GIT_EXECUTABLE} submodule update --init --recursive - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} - RESULT_VARIABLE GIT_SUBMODULE_UPDATE_RESULT) -if(NOT GIT_SUBMODULE_UPDATE_RESULT EQUAL "0") - message(FATAL_ERROR "git submodule update --init failed with ${GIT_SUBMODULE_UPDATE_RESULT}, please checkout submodules") -endif() - -execute_process(COMMAND ${GIT_EXECUTABLE} rev-parse --short HEAD - WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/Packages/Cassowary" - OUTPUT_VARIABLE CASSOWARY_GIT_REVISION - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) -execute_process(COMMAND ${GIT_EXECUTABLE} rev-parse --short HEAD - WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/Packages/SwiftCOM" - OUTPUT_VARIABLE SWIFT_COM_GIT_REVISION - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) -execute_process(COMMAND ${GIT_EXECUTABLE} rev-parse --short HEAD - WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/Packages/swift-log" - OUTPUT_VARIABLE SWIFT_LOG_GIT_REVISION - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) -execute_process(COMMAND ${GIT_EXECUTABLE} rev-parse --short HEAD - WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/Packages/swift-collections" - OUTPUT_VARIABLE COLLECTIONS_GIT_REVISION - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - -include(SwiftSupport) - -add_subdirectory(Packages/swift-collections) - -add_subdirectory(Sources) -add_subdirectory(Examples) - -message("-- Building with sub-modules:") -message("-- Cassowary rG${CASSOWARY_GIT_REVISION}") -message("-- Swift/COM rG${SWIFT_COM_GIT_REVISION}") -message("-- swift-log rG${SWIFT_LOG_GIT_REVISION}") -message("-- Collections rG${COLLECTIONS_GIT_REVISION}") - -if(Swift_COMPILER_VERSION VERSION_LESS 5.5) - export(TARGETS Logging SwiftCOM SwiftWin32 - FILE SwiftWin32Config.cmake) -else() - export(TARGETS SwiftCOM SwiftWin32 - FILE SwiftWin32Config.cmake) -endif() diff --git a/CMakePresets.json b/CMakePresets.json deleted file mode 100644 index d97c8b4c..00000000 --- a/CMakePresets.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "version": 3, - "cmakeMinimumRequired": { - "major": 3, - "minor": 21, - "patch": 0 - }, - "configurePresets": [ - { - "name": "Default", - "displayName": "Release Build (Ninja)", - "description": "Defaults", - "generator": "Ninja", - "binaryDir": "${sourceDir}/.build/x86_64-unknown-windows-msvc/Release", - "cacheVariables": { - "BUILD_SHARED_LIBS": "YES", - "CMAKE_BUILD_TYPE": "Release", - "CMAKE_Swift_FLAGS": "-sdk $env{SDKROOT}" - } - } - ], - "buildPresets": [ - { - "name": "Default", - "configurePreset": "Default" - } - ] -} diff --git a/CoreGraphics/index.md b/CoreGraphics/index.md new file mode 100644 index 00000000..95148925 --- /dev/null +++ b/CoreGraphics/index.md @@ -0,0 +1,9 @@ +--- +layout: default +title: CoreGraphics +nav_order: 2 +has_children: true +--- + +CoreGraphics provides lightweight 2D rendering utilities. This is primarily +used for the basic graphics primitives required to interact with SwiftWin32. diff --git a/Documentation/BundleLayout.md b/Documentation/BundleLayout.md deleted file mode 100644 index 3e9c5d09..00000000 --- a/Documentation/BundleLayout.md +++ /dev/null @@ -1,48 +0,0 @@ -## Bundle Layout - -### What Files Go Into an Application Bundle? - -The following table summarises the types of files that need to be included in an application distribution. - -| File | Description | -| ---- | ----------- | -| Info.plist | **(Optional)** The *information property list* file is a structured file that contains configuration information for the application. | -| Executable | The application's main entry point and any statically linked code. | -| Libraries | Any additional dependent libraries needed by the main executable. | -| Application Manifest | The Windows application manifest which is used to enable features for modern Windows APIs. | -| Swift Runtime | **(Optional)** The runtime libraries for the Swift runtime. | - -### Anatomy of a Windows Application Bundle - -#### The Windows Application Bundle Structure - -The Windows application bundle contains the application executable and any resources required for the application. The following listing shows the structure of a simple application called `Application`. - -``` -Application.app - Application.exe - Application.exe.manifest - Resources - Image.png -``` - -| File | Description | -| ---- | ----------- | -| Application.exe | (Required) The executable file containing the application code. | -| Application.exe.manifest | (Required) The executable manifest. This must be named the same as the executable with an additional `.manifest` suffix. | -| Info.plist | (Recommended) The file contains confituration information for the application. | -| Custom resource files | Any additional resources, including but not limited to images, sound files, and custom data files needed for the application. | - -### The Information Property List File - -Applications should provide an information property list (`Info.plist`) file -containing the application's configuration information. If one is not provided, -the framework wil attempt to subsitute defaults. The following table lists some -of the keys which are commonly used. Although the file nor the keys are -required, they provide a way to adjust the configuration of the application at -launch time. Providing the configuration helps ensure te proper presentation of -the application to the user. - -| Key | Description | -| --- | ----------- | -| `PrincipalClass` (Principal class) | The entry point for for the application. This is either the default `Application` or a subclass. | diff --git a/Documentation/PrincipalClass.md b/Documentation/PrincipalClass.md deleted file mode 100644 index 11638539..00000000 --- a/Documentation/PrincipalClass.md +++ /dev/null @@ -1,29 +0,0 @@ -## Principal Class - -Defining a PrincipalClass allows to use a subclass of the `Application` class. - -### How to use an Application subclass ? - -- Define a class that inherits from `SwiftWin32.Application`. Here is an example: - -```swift -import SwiftWin32 - -public class MyApplication: Application { - let message = "This is a message from MyApplication subclass" -} -``` - -- In `Info.plist`, define a `PrincipalClass` entry with a String value of `{Module}.{CustomClassName}`. For example, if the product module name is `CustomPrincipalClass`, then we can register `MyApplication` (defined above) as follows: - -```xml - - - - - PrincipalClass - CustomPrincipalClass.MyApplication - - - -``` diff --git a/Examples/CMakeLists.txt b/Examples/CMakeLists.txt deleted file mode 100644 index ec143d00..00000000 --- a/Examples/CMakeLists.txt +++ /dev/null @@ -1,2 +0,0 @@ -add_subdirectory(Calculator) -add_subdirectory(UICatalog) diff --git a/Examples/Calculator/CMakeLists.txt b/Examples/Calculator/CMakeLists.txt deleted file mode 100644 index 13f16c52..00000000 --- a/Examples/Calculator/CMakeLists.txt +++ /dev/null @@ -1,12 +0,0 @@ -add_executable(Calculator - Calculator.swift) -add_custom_command(TARGET Calculator POST_BUILD - COMMAND - mt -nologo -manifest ${CMAKE_CURRENT_SOURCE_DIR}/Calculator.exe.manifest -outputresource:$ - COMMAND - ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist $) -# FIXME(SR-12683) `@main` requires `-parse-as-library` -target_compile_options(Calculator PRIVATE - -parse-as-library) -target_link_libraries(Calculator PRIVATE - SwiftWin32) diff --git a/Examples/Calculator/Calculator.exe.manifest b/Examples/Calculator/Calculator.exe.manifest deleted file mode 100644 index eee17d38..00000000 --- a/Examples/Calculator/Calculator.exe.manifest +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - - - - PerMonitorV2 - true - - - - Calculator - - - - - - - - diff --git a/Examples/Calculator/Calculator.swift b/Examples/Calculator/Calculator.swift deleted file mode 100644 index 2a2962b1..00000000 --- a/Examples/Calculator/Calculator.swift +++ /dev/null @@ -1,187 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import SwiftWin32 -import Foundation - -#if swift(>=5.7) -import CoreGraphics -#endif - -private extension View { - func addSubviews(_ views: [View]) { - _ = views.map { self.addSubview($0) } - } -} - -private extension Button { - convenience init(frame: Rect = .zero, title: String) { - self.init(frame: frame) - setTitle(title, forState: .normal) - } -} - -private enum CalculatorOperation { -case undefined -case addition -case substraction -case multiplication -case division -} - -private struct CalculatorState { - var lhs: NSDecimalNumber = .zero - var rhs: NSDecimalNumber = .zero - var operand: WritableKeyPath = \.lhs - var operation: CalculatorOperation = .undefined { - willSet { self.operand = (newValue == .undefined) ? \.lhs : \.rhs } - } - - mutating func evaluate() -> NSDecimalNumber { - switch self.operation { - case .undefined: break - case .addition: lhs = lhs.adding(rhs) - case .substraction: lhs = lhs.subtracting(rhs) - case .multiplication: lhs = lhs.multiplying(by: rhs) - case .division: lhs = lhs.dividing(by: rhs) - } - - rhs = .zero - operation = .undefined - - return lhs - } -} - -private class Calculator { - private var state: CalculatorState = CalculatorState() - - private var window: Window - - private var txtResult: TextField = { - let txtResult = TextField(frame: Rect(x: 34, y: 32, width: 128, height: 24)) - txtResult.font = Font(name: "Consolas", size: Font.systemFontSize) - txtResult.textAlignment = .right - txtResult.text = "0" - return txtResult - }() - - private var btnDigits: [Button] = [ - Button(frame: Rect(x: 32, y: 192, width: 64, height: 32), title: "0"), - Button(frame: Rect(x: 32, y: 160, width: 32, height: 32), title: "1"), - Button(frame: Rect(x: 64, y: 160, width: 32, height: 32), title: "2"), - Button(frame: Rect(x: 96, y: 160, width: 32, height: 32), title: "3"), - Button(frame: Rect(x: 32, y: 128, width: 32, height: 32), title: "4"), - Button(frame: Rect(x: 64, y: 128, width: 32, height: 32), title: "5"), - Button(frame: Rect(x: 96, y: 128, width: 32, height: 32), title: "6"), - Button(frame: Rect(x: 32, y: 96, width: 32, height: 32), title: "7"), - Button(frame: Rect(x: 64, y: 96, width: 32, height: 32), title: "8"), - Button(frame: Rect(x: 96, y: 96, width: 32, height: 32), title: "9"), - ] - - private var btnDecimal: Button = - Button(frame: Rect(x: 96, y: 192, width: 32, height: 32), title: ".") - - private var btnOperations: [Button] = [ - Button(frame: Rect(x: 32, y: 64, width: 32, height: 32), title: "AC"), - Button(frame: Rect(x: 64, y: 64, width: 32, height: 32), title: "⁺∕₋"), - Button(frame: Rect(x: 96, y: 64, width: 32, height: 32), title: "%"), - Button(frame: Rect(x: 128, y: 64, width: 32, height: 32), title: "÷"), - Button(frame: Rect(x: 128, y: 96, width: 32, height: 32), title: "x"), - Button(frame: Rect(x: 128, y: 128, width: 32, height: 32), title: "-"), - Button(frame: Rect(x: 128, y: 160, width: 32, height: 32), title: "+"), - Button(frame: Rect(x: 128, y: 192, width: 32, height: 32), title: "="), - ] - - public init(windowScene: WindowScene) { - self.window = Window(windowScene: windowScene) - - self.window.rootViewController = ViewController() - self.window.rootViewController?.title = "Calculator" - - self.window.addSubview(self.txtResult) - self.txtResult.font = Font(name: "Consolas", size: Font.systemFontSize) - self.txtResult.textAlignment = .right - self.txtResult.text = - self.state.evaluate().description(withLocale: Locale.current) - - self.window.addSubviews(self.btnDigits) - self.btnDigits.forEach { - $0.addTarget(self, action: Calculator.onDigitPress(_:_:), - for: .primaryActionTriggered) - } - self.window.addSubviews(self.btnOperations) - self.btnOperations.forEach { - $0.addTarget(self, action: Calculator.onOperationPress(_:_:), - for: .primaryActionTriggered) - } - self.window.addSubview(self.btnDecimal) - self.btnDecimal.addTarget(self, action: Calculator.onDecimalPress(_:_:), - for: .primaryActionTriggered) - - self.window.makeKeyAndVisible() - } - - private func onDigitPress(_ sender: Button, _: Control.Event) { - guard let input = self.btnDigits.firstIndex(of: sender) else { - fatalError("invalid target: \(self) for sender: \(sender)") - } - - var operand = self.state[keyPath: self.state.operand] as Decimal - operand *= 10 - operand += Decimal(input) - self.state[keyPath: self.state.operand] = operand as NSDecimalNumber - - self.txtResult.text = operand.description - } - - private func onOperationPress(_ sender: Button, _: Control.Event) { - switch self.btnOperations.firstIndex(of: sender)! { - case 0: /* AC */ - self.state = CalculatorState() - self.txtResult.text = Decimal.zero.description - case 1: /* +/- */ - var operand = self.state[keyPath: self.state.operand] as Decimal - operand.negate() - case 3: /* ÷ */ - self.state.operation = .division - case 4: /* x */ - self.state.operation = .multiplication - case 5: /* - */ - self.state.operation = .substraction - case 6: /* + */ - self.state.operation = .addition - case 2: /* % */ - if (self.state.lhs as Decimal).isZero { break } - self.state.operation = .division - self.state.rhs = NSDecimalNumber(string: "100") - fallthrough - case 7: /* = */ - self.txtResult.text = - self.state.evaluate().description(withLocale: Locale.current) - default: - fatalError("unknown operation \(self.btnOperations.firstIndex(of: sender)!)") - } - } - - private func onDecimalPress(_ sender: Button, _: Control.Event) { - self.txtResult.text = - (self.state[keyPath: self.state.operand] as Decimal).description - } -} - -@main -final class CalculatorDelegate: ApplicationDelegate, SceneDelegate { - private var calculator: Calculator? - - func scene(_ scene: Scene, willConnectTo session: SceneSession, - options: Scene.ConnectionOptions) { - guard let windowScene = scene as? WindowScene else { return } - - let size: Size = Size(width: 192, height: 264) - windowScene.sizeRestrictions?.minimumSize = size - windowScene.sizeRestrictions?.maximumSize = size - - self.calculator = Calculator(windowScene: windowScene) - } -} diff --git a/Examples/Calculator/Info.plist b/Examples/Calculator/Info.plist deleted file mode 100644 index 34cb62ef..00000000 --- a/Examples/Calculator/Info.plist +++ /dev/null @@ -1,23 +0,0 @@ - - - - - ApplicationSceneManifest - - ApplicationSupportsMultipleScenes - - SceneConfigurations - - UIWindowSceneSessionRoleApplication - - - SceneConfigurationName - Default Configuration - SceneDelegateClassName - Calculator.CalculatorDelegate - - - - - - diff --git a/Examples/UICatalog/Assets/CoffeeCup.jpg b/Examples/UICatalog/Assets/CoffeeCup.jpg deleted file mode 100644 index df3016cb..00000000 Binary files a/Examples/UICatalog/Assets/CoffeeCup.jpg and /dev/null differ diff --git a/Examples/UICatalog/CMakeLists.txt b/Examples/UICatalog/CMakeLists.txt deleted file mode 100644 index df5dc638..00000000 --- a/Examples/UICatalog/CMakeLists.txt +++ /dev/null @@ -1,14 +0,0 @@ -add_executable(UICatalog - UICatalog.swift) -add_custom_command(TARGET UICatalog POST_BUILD - COMMAND - mt -nologo -manifest ${CMAKE_CURRENT_SOURCE_DIR}/UICatalog.exe.manifest -outputresource:$ - COMMAND - ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist $ - COMMAND - ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/Assets/CoffeeCup.jpg $) -# FIXME(SR-12683) `@main` requires `-parse-as-library` -target_compile_options(UICatalog PRIVATE - -parse-as-library) -target_link_libraries(UICatalog PRIVATE - SwiftWin32) diff --git a/Examples/UICatalog/Info.plist b/Examples/UICatalog/Info.plist deleted file mode 100644 index 1fda46a0..00000000 --- a/Examples/UICatalog/Info.plist +++ /dev/null @@ -1,23 +0,0 @@ - - - - - ApplicationSceneManifest - - ApplicationSupportsMultipleScenes - - SceneConfigurations - - UIWindowSceneSessionRoleApplication - - - SceneConfigurationName - Default Configuration - SceneDelegateClassName - UICatalog.UICatalog - - - - - - diff --git a/Examples/UICatalog/UICatalog.exe.manifest b/Examples/UICatalog/UICatalog.exe.manifest deleted file mode 100644 index 704609af..00000000 --- a/Examples/UICatalog/UICatalog.exe.manifest +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - - - - PerMonitorV2 - true - - - - UICatalog - - - - - - - - diff --git a/Examples/UICatalog/UICatalog.swift b/Examples/UICatalog/UICatalog.swift deleted file mode 100644 index 8282b7ad..00000000 --- a/Examples/UICatalog/UICatalog.swift +++ /dev/null @@ -1,215 +0,0 @@ -// Copyright © 2019 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import SwiftWin32 -import Foundation - -import func WinSDK.MessageBoxW -import let WinSDK.MB_OK -import struct WinSDK.UINT - -#if swift(>=5.7) -import CoreGraphics -#endif - -private extension Label { - convenience init(frame: Rect, title: String) { - self.init(frame: frame) - self.text = title - } -} - -@main -final class UICatalog: ApplicationDelegate, SceneDelegate { - var window: Window! - - lazy var label: Label = - Label(frame: Rect(x: 4.0, y: 12.0, width: 64.0, height: 16.0), - title: "Read Me:") - - lazy var button: Button = - Button(frame: Rect(x: 72.0, y: 4.0, width: 96.0, height: 32.0), - primaryAction: Action(title: "Press Me!") { _ in - MessageBoxW(nil, "Swift/Win32 Demo!".wide, - "Swift/Win32 MessageBox!".wide, UINT(MB_OK)) - }) - - lazy var checkbox: Switch = - Switch(frame: Rect(x: 4.0, y: 40.0, width: 256.0, height: 24.0)) - - lazy var progress: ProgressView = - ProgressView(frame: Rect(x: 4.0, y: 68.0, width: 256.0, height: 20.0)) - - lazy var textfield: TextField = - TextField(frame: Rect(x: 4.0, y: 92.0, width: 254.0, height: 17.0)) - - lazy var password: TextField = - TextField(frame: Rect(x: 4.0, y: 113.0, width: 254.0, height: 17.0)) - - lazy var textview: TextView = - TextView(frame: Rect(x: 4.0, y: 134.0, width: 254.0, height: 72.0)) - - lazy var slider: Slider = - Slider(frame: Rect(x: 4.0, y: 210.0, width: 256.0, height: 24.0)) - - lazy var picker: DatePicker = - DatePicker(frame: Rect(x: 4.0, y: 238.0, width: 256.0, height: 32.0)) - - lazy var stepperLabel: Label = - Label(frame: Rect(x: 4.0, y: 274.0, width: 128.0, height: 32.0)) - lazy var stepper: Stepper = - Stepper(frame: Rect(x: 197.0, y: 274.0, width: 64.0, height: 32.0)) - - lazy var tableview: TableView = - TableView(frame: Rect(x: 4.0, y: 310.0, width: 254.0, height: 48.0), - style: .plain) - - lazy var pickerview: PickerView = - PickerView(frame: Rect(x: 4.0, y: 362.0, width: 256.0, height: 24.0)) - - lazy var imageview: ImageView = { -#if SWIFT_PACKAGE - let bundle: Bundle = Bundle.module -#else - let bundle: Bundle = Bundle.main -#endif - guard let resource: URL = - bundle.url(forResource: "CoffeeCup", withExtension: "jpg") else { - fatalError("Unable to load resource `CoffeeCup.jpg`") - } - let image: Image? = Image(contentsOfFile: resource.path) - let view = ImageView(image: image) - view.frame = Rect(x: 64.0, y: 394.0, width: 128.0, height: 128.0) - return view - }() - - func scene(_ scene: Scene, willConnectTo session: SceneSession, - options: Scene.ConnectionOptions) { - guard let windowScene = scene as? WindowScene else { return } - - // Set the preferred window size and restrict resizing by setting the - // minimum and maximum to the same value. - let size: Size = Size(width: 265, height: 530) - windowScene.sizeRestrictions?.minimumSize = size - windowScene.sizeRestrictions?.maximumSize = size - - self.window = Window(windowScene: windowScene) - - window.rootViewController = ViewController() - window.rootViewController?.title = "UICatalog" - - window.addSubview(self.label) - window.addSubview(self.button) - window.addSubview(self.checkbox) - window.addSubview(self.progress) - window.addSubview(self.textfield) - window.addSubview(self.password) - window.addSubview(self.textview) - window.addSubview(self.slider) - window.addSubview(self.picker) - window.addSubview(self.stepperLabel) - window.addSubview(self.stepper) - window.addSubview(self.tableview) - window.addSubview(self.pickerview) - window.addSubview(self.imageview) - - self.label.font = Font(name: "Consolas", size: 10)! - - self.checkbox.title = "Check me out" - - self.textfield.text = "Introducing Swift/Win32" - self.textfield.font = Font(name: "Cascadia Code", size: 10) - - self.password.isSecureTextEntry = true - self.password.font = Font(name: "Cascadia Code", size: 10) - self.password.placeholder = "Password" - - self.textview.text = """ -Lorem ipsum dolor sit amet, consectetur adipiscicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. -Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. -Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. -Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. -""" - self.textview.font = Font(name: "MS Comic Sans", size: 10) - - self.progress.setProgress(0.5, animated: false) - - self.slider.minimumValue = 0.0 - self.slider.maximumValue = 100.0 - self.slider.value = 48.0 - - self.stepper.value = 2 - self.stepperLabel.text = String(Int(self.stepper.value)) - self.stepper.addTarget(self, action: UICatalog.stepperValueDidChange(_:), - for: .valueChanged) - - self.tableview.dataSource = self - - self.pickerview.dataSource = self - self.pickerview.delegate = self - self.pickerview.reloadAllComponents() - - window.makeKeyAndVisible() - } - - func sceneDidBecomeActive(_: Scene) { - print("Good morning!") - } - - func sceneWillResignActive(_: Scene) { - print("Good night!") - } - - func applicationWillTerminate(_: Application) { - print("Goodbye cruel world!") - } - - private func stepperValueDidChange(_ stepper: Stepper) { - self.stepperLabel.text = String(Int(stepper.value)) - self.tableview.reloadData() - } -} - -extension UICatalog: TableViewDataSource { - public func tableView(_ tableView: TableView, - numberOfRowsInSection section: Int) -> Int { - return Int(stepper.value) - } - - public func tableView(_ tableView: TableView, - cellForRowAt indexPath: IndexPath) -> TableViewCell { - let cell = TableViewCell(style: .default, reuseIdentifier: nil) - - let button: Button = Button(frame: Rect(x: 0, y: 0, width: 80, height: 32)) - button.setTitle("Button \(indexPath.row)", forState: .normal) - cell.addSubview(button) - - return cell - } -} - -extension UICatalog: PickerViewDataSource { - public func numberOfComponents(in pickerView: PickerView) -> Int { - return 1 - } - - public func pickerView(_ pickerView: PickerView, - numberOfRowsInComponent component: Int) -> Int { - return 7 - } -} - -extension UICatalog: PickerViewDelegate { - public func pickerView(_ pickerView: PickerView, titleForRow row: Int, - forComponent component: Int) -> String? { - return [ - "Sunday", - "Monday", - "Tuesday", - "Wednesday", - "Thursday", - "Friday", - "Saturday", - ][row] - } -} diff --git a/Gemfile b/Gemfile new file mode 100644 index 00000000..20b1b828 --- /dev/null +++ b/Gemfile @@ -0,0 +1,17 @@ +source "https://rubygems.org" + +gem "github-pages", group: :jekyll_plugins +gem "just-the-docs" +group :jekyll_plugins do + gem "jekyll-feed", "~> 0.12" +end + +# Windows and JRuby does not include zoneinfo files, so bundle the tzinfo-data gem +# and associated library. +platforms :mingw, :x64_mingw, :mswin, :jruby do + gem "tzinfo", "~> 1.2" + gem "tzinfo-data" +end + +# Performance-booster for watching directories on Windows +gem "wdm", "~> 0.1.1", :platforms => [:mingw, :x64_mingw, :mswin] diff --git a/LICENSE.txt b/LICENSE.txt deleted file mode 100644 index 19d2c536..00000000 --- a/LICENSE.txt +++ /dev/null @@ -1,29 +0,0 @@ -BSD 3-Clause License - -Copyright (c) 2019, Saleem Abdulrasool -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -3. Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Package.swift b/Package.swift deleted file mode 100644 index ceec4a26..00000000 --- a/Package.swift +++ /dev/null @@ -1,90 +0,0 @@ -// swift-tools-version:5.9 - -import PackageDescription - -let SwiftWin32: Package = - Package(name: "SwiftWin32", - products: [ - .library(name: "SwiftWin32", - type: .dynamic, - targets: ["SwiftWin32"]), - .library(name: "SwiftWin32UI", - type: .dynamic, - targets: ["SwiftWin32UI"]), - .executable(name: "UICatalog", targets: ["UICatalog"]), - .executable(name: "Calculator", targets: ["Calculator"]), - ], - dependencies: [ - .package(url: "https://github.com/apple/swift-log.git", - .upToNextMajor(from: "1.4.3")), - .package(url: "https://github.com/apple/swift-collections.git", - .upToNextMinor(from: "1.0.0")), - .package(url: "https://github.com/compnerd/cassowary.git", - branch: "main"), - .package(url: "https://github.com/compnerd/swift-com.git", - revision: "ebbc617d3b7ba3a2023988a74bebd118deea4cc5"), - ], - targets: [ - .target(name: "CoreAnimation", - path: "Sources/SwiftWin32/CoreAnimation"), - .target(name: "CoreGraphics", - path: "Sources/SwiftWin32/CoreGraphics"), - .target(name: "SwiftWin32", - dependencies: [ - "CoreAnimation", - "CoreGraphics", - .product(name: "Logging", package: "swift-log"), - .product(name: "OrderedCollections", - package: "swift-collections"), - .product(name: "cassowary", package: "cassowary"), - .product(name: "SwiftCOM", package: "swift-com"), - ], - path: "Sources/SwiftWin32", - exclude: [ - "CoreAnimation", - "CoreGraphics", - "CMakeLists.txt" - ], - swiftSettings: [ - .enableExperimentalFeature("AccessLevelOnImport"), - ], - linkerSettings: [ - .linkedLibrary("User32"), - .linkedLibrary("ComCtl32"), - ]), - .target(name: "SwiftWin32UI", - dependencies: ["SwiftWin32"], - path: "Sources/SwiftWin32UI", - exclude: ["CMakeLists.txt"]), - .executableTarget(name: "Calculator", - dependencies: ["SwiftWin32"], - path: "Examples/Calculator", - exclude: [ - "CMakeLists.txt", - "Calculator.exe.manifest", - "Info.plist", - ], - swiftSettings: [ - .unsafeFlags(["-parse-as-library"]) - ]), - .executableTarget(name: "UICatalog", - dependencies: ["SwiftWin32"], - path: "Examples/UICatalog", - exclude: [ - "CMakeLists.txt", - "Info.plist", - "UICatalog.exe.manifest", - ], - resources: [ - .copy("Assets/CoffeeCup.jpg") - ], - swiftSettings: [ - .unsafeFlags(["-parse-as-library"]) - ]), - .target(name: "TestUtilities", path: "Tests/Utilities"), - .testTarget(name: "AutoLayoutTests", dependencies: ["SwiftWin32"]), - .testTarget(name: "CoreGraphicsTests", dependencies: ["CoreGraphics"]), - .testTarget(name: "SupportTests", dependencies: ["SwiftWin32"]), - .testTarget(name: "UICoreTests", - dependencies: ["SwiftWin32", "TestUtilities"]) - ]) diff --git a/Package@swift-5.4.swift b/Package@swift-5.4.swift deleted file mode 100644 index 5ff5f6d1..00000000 --- a/Package@swift-5.4.swift +++ /dev/null @@ -1,76 +0,0 @@ -// swift-tools-version:5.4 - -import PackageDescription - -let SwiftWin32 = Package( - name: "SwiftWin32", - products: [ - .library(name: "SwiftWin32", type: .dynamic, targets: ["SwiftWin32"]), - .library(name: "SwiftWin32UI", type: .dynamic, targets: ["SwiftWin32UI"]), - .executable(name: "UICatalog", targets: ["UICatalog"]), - .executable(name: "Calculator", targets: ["Calculator"]), - ], - dependencies: [ - .package(url: "https://github.com/apple/swift-log.git", - .upToNextMajor(from: "1.4.3")), - .package(url: "https://github.com/apple/swift-collections.git", - .upToNextMinor(from: "1.0.0")), - .package(url: "https://github.com/compnerd/cassowary.git", .branch("main")), - .package(name: "SwiftCOM", url: "https://github.com/compnerd/swift-com.git", - .revision("ebbc617d3b7ba3a2023988a74bebd118deea4cc5")), - ], - targets: [ - .target( - name: "SwiftWin32", - dependencies: [ - .product(name: "Logging", package: "swift-log"), - .product(name: "OrderedCollections", package: "swift-collections"), - .product(name: "cassowary", package: "cassowary"), - .product(name: "SwiftCOM", package: "SwiftCOM"), - ], - path: "Sources/SwiftWin32", - exclude: ["CMakeLists.txt"], - linkerSettings: [ - .linkedLibrary("User32"), - .linkedLibrary("ComCtl32"), - ] - ), - .target( - name: "SwiftWin32UI", - dependencies: ["SwiftWin32"], - path: "Sources/SwiftWin32UI", - exclude: ["CMakeLists.txt"] - ), - .executableTarget( - name: "Calculator", - dependencies: ["SwiftWin32"], - path: "Examples/Calculator", - exclude: [ - "CMakeLists.txt", - "Calculator.exe.manifest", - "Info.plist", - ], - swiftSettings: [.unsafeFlags(["-parse-as-library"])] - ), - .executableTarget( - name: "UICatalog", - dependencies: ["SwiftWin32"], - path: "Examples/UICatalog", - exclude: [ - "CMakeLists.txt", - "Info.plist", - "UICatalog.exe.manifest", - ], - resources: [.copy("Assets/CoffeeCup.jpg")], - swiftSettings: [.unsafeFlags(["-parse-as-library"])] - ), - .target(name: "TestUtilities", path: "Tests/Utilities"), - .testTarget(name: "AutoLayoutTests", dependencies: ["SwiftWin32"]), - .testTarget(name: "CoreGraphicsTests", dependencies: ["SwiftWin32"]), - .testTarget(name: "SupportTests", dependencies: ["SwiftWin32"]), - .testTarget( - name: "UICoreTests", - dependencies: ["SwiftWin32", "TestUtilities"] - ) - ] -) diff --git a/Package@swift-5.5.swift b/Package@swift-5.5.swift deleted file mode 120000 index bd1da396..00000000 --- a/Package@swift-5.5.swift +++ /dev/null @@ -1 +0,0 @@ -Package@swift-5.4.swift \ No newline at end of file diff --git a/Package@swift-5.6.swift b/Package@swift-5.6.swift deleted file mode 120000 index bd1da396..00000000 --- a/Package@swift-5.6.swift +++ /dev/null @@ -1 +0,0 @@ -Package@swift-5.4.swift \ No newline at end of file diff --git a/Package@swift-5.7.swift b/Package@swift-5.7.swift deleted file mode 100644 index e699cc56..00000000 --- a/Package@swift-5.7.swift +++ /dev/null @@ -1,87 +0,0 @@ -// swift-tools-version:5.7 - -import PackageDescription - -let SwiftWin32: Package = - Package(name: "SwiftWin32", - products: [ - .library(name: "SwiftWin32", - type: .dynamic, - targets: ["SwiftWin32"]), - .library(name: "SwiftWin32UI", - type: .dynamic, - targets: ["SwiftWin32UI"]), - .executable(name: "UICatalog", targets: ["UICatalog"]), - .executable(name: "Calculator", targets: ["Calculator"]), - ], - dependencies: [ - .package(url: "https://github.com/apple/swift-log.git", - .upToNextMajor(from: "1.4.3")), - .package(url: "https://github.com/apple/swift-collections.git", - .upToNextMinor(from: "1.0.0")), - .package(url: "https://github.com/compnerd/cassowary.git", - branch: "main"), - .package(url: "https://github.com/compnerd/swift-com.git", - revision: "ebbc617d3b7ba3a2023988a74bebd118deea4cc5"), - ], - targets: [ - .target(name: "CoreAnimation", - path: "Sources/SwiftWin32/CoreAnimation"), - .target(name: "CoreGraphics", - path: "Sources/SwiftWin32/CoreGraphics"), - .target(name: "SwiftWin32", - dependencies: [ - "CoreAnimation", - "CoreGraphics", - .product(name: "Logging", package: "swift-log"), - .product(name: "OrderedCollections", - package: "swift-collections"), - .product(name: "cassowary", package: "cassowary"), - .product(name: "SwiftCOM", package: "swift-com"), - ], - path: "Sources/SwiftWin32", - exclude: [ - "CoreAnimation", - "CoreGraphics", - "CMakeLists.txt", - ], - linkerSettings: [ - .linkedLibrary("User32"), - .linkedLibrary("ComCtl32"), - ]), - .target(name: "SwiftWin32UI", - dependencies: ["SwiftWin32"], - path: "Sources/SwiftWin32UI", - exclude: ["CMakeLists.txt"]), - .executableTarget(name: "Calculator", - dependencies: ["SwiftWin32"], - path: "Examples/Calculator", - exclude: [ - "CMakeLists.txt", - "Calculator.exe.manifest", - "Info.plist", - ], - swiftSettings: [ - .unsafeFlags(["-parse-as-library"]) - ]), - .executableTarget(name: "UICatalog", - dependencies: ["SwiftWin32"], - path: "Examples/UICatalog", - exclude: [ - "CMakeLists.txt", - "Info.plist", - "UICatalog.exe.manifest", - ], - resources: [ - .copy("Assets/CoffeeCup.jpg") - ], - swiftSettings: [ - .unsafeFlags(["-parse-as-library"]) - ]), - .target(name: "TestUtilities", path: "Tests/Utilities"), - .testTarget(name: "AutoLayoutTests", dependencies: ["SwiftWin32"]), - .testTarget(name: "CoreGraphicsTests", dependencies: ["CoreGraphics"]), - .testTarget(name: "SupportTests", dependencies: ["SwiftWin32"]), - .testTarget(name: "UICoreTests", - dependencies: ["SwiftWin32", "TestUtilities"]) - ]) diff --git a/Package@swift-5.8.swift b/Package@swift-5.8.swift deleted file mode 120000 index 731795f1..00000000 --- a/Package@swift-5.8.swift +++ /dev/null @@ -1 +0,0 @@ -Package@swift-5.7.swift \ No newline at end of file diff --git a/Packages/SwiftCOM b/Packages/SwiftCOM deleted file mode 160000 index ebbc617d..00000000 --- a/Packages/SwiftCOM +++ /dev/null @@ -1 +0,0 @@ -Subproject commit ebbc617d3b7ba3a2023988a74bebd118deea4cc5 diff --git a/Packages/cassowary b/Packages/cassowary deleted file mode 160000 index a4386112..00000000 --- a/Packages/cassowary +++ /dev/null @@ -1 +0,0 @@ -Subproject commit a438611231901f9f350da27857d786f7979d578b diff --git a/Packages/swift-collections b/Packages/swift-collections deleted file mode 160000 index c0549b62..00000000 --- a/Packages/swift-collections +++ /dev/null @@ -1 +0,0 @@ -Subproject commit c0549b6284aadd5fd13156316f43fcb43c7fca77 diff --git a/Packages/swift-log b/Packages/swift-log deleted file mode 160000 index d8af258a..00000000 --- a/Packages/swift-log +++ /dev/null @@ -1 +0,0 @@ -Subproject commit d8af258aecd93cd8604e74ade3c0fe438bac13f8 diff --git a/README.md b/README.md deleted file mode 100644 index ad5d1888..00000000 --- a/README.md +++ /dev/null @@ -1,65 +0,0 @@ -Swift/Win32 - A Swift Application Framework for Windows -------------------------------------------------------- - -

- Swift/Win32 Screenshot -

- -Swift/Win32 aims to provide a [MVC](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller) model for writing applications on Windows. It provides Swift friendly wrapping of the Win32 APIs much like [MFC](https://en.wikipedia.org/wiki/Microsoft_Foundation_Class_Library) did for C++. - -## Build Requirements - -- Swift 5.4 or newer -- Windows SDK 10.0.107763 or newer -- CMake 3.16 or newer - -## Building - -This project requires Swift 5.4 or newer. You can use the the snapshot binaries from [swift.org](https://swift.org/download/), download the nightly build from [Azure](https://dev.azure.com/compnerd/swift-build), or build the Swift compiler from source. - -### Recommended (CMake) - -The following example session shows how to build with CMake 3.16 or newer. - -```cmd -cmake -B build -D BUILD_SHARED_LIBS=YES -D CMAKE_BUILD_TYPE=Release -D CMAKE_Swift_FLAGS="-sdk %SDKROOT%" -G Ninja -S . -ninja -C build SwiftWin32 UICatalog - -%CD%\build\bin\UICatalog.exe -``` - -
- Required Environment Variables - - The CMake build will automatically perform the application manifest merging via the `mt` tool, which is part of the Visual Studio build tools. Ensure that you run the build under the `x64 Native Tools Command Prompt for VS2019` (or the appropriate shell for the version of Visual Studio). - - The Swift installer will also add environment variables, ensure that you have restarted the terminal emulator after installing the toolchain to pick up the required environment variables. -
- -### Swift Package Manager - -Building this project with swift-package-manager is supported although CMake is recommended for ease. The Swift Package Manager based build is required for code completion via SourceKit-LSP. It also allows for the use of Swift/Win32 in other applications using SPM. In order to use SPM to build this project additional post-build steps are required to use the demo applications. - -The following known limitations are known: - -1. It is not possible to deploy auxiliary files which are required for Swift/Win32 based applications to function to the correct location. -2. It is not possible to build and run multiple demo projects as the auxiliary files collide. - -```cmd -swift build --product UICatalog -mt -nologo -manifest Examples\UICatalog\UICatalog.exe.manifest -outputresource:.build\x86_64-unknown-windows-msvc\debug\UICatalog.exe -copy Examples\UICatalog\Info.plist .build\x86_64-unknown-windows-msvc\debug\ -.build\x86_64-unknown-windows-msvc\debug\UICatalog.exe -``` - -In order to get access to the manifest tool (`mt`), the build and testing should occur in a [x64 Native Tools Command Prompt for VS2019](https://docs.microsoft.com/en-us/cpp/build/how-to-enable-a-64-bit-visual-cpp-toolset-on-the-command-line?view=msvc-160) - -## Testing - -The current implementation is still under flux and many of the interfaces we expect to be present are not yet implemented. Because clearly indicating the missing surface makes it easier to focus on what needs to be accomplished, there are many instances of interfaces being declared but not implemented. Most of these sites will abort if they are reached. In order to enable testing for scenarios which may interct with these cases, a special condition has been added as `ENABLE_TESTING` to allow us to bypass the missing functionality. - -You can run tests by adding that as a flag when invoking the SPM test command as: - -```cmd -swift test -Xswiftc -DENABLE_TESTING -``` diff --git a/Sources/CMakeLists.txt b/Sources/CMakeLists.txt deleted file mode 100644 index 2a9385bb..00000000 --- a/Sources/CMakeLists.txt +++ /dev/null @@ -1,47 +0,0 @@ -#[[ -Copyright © 2019 Saleem Abdulrasool -All rights reserved. - -SPDX-License-Identifier: BSD-3-Clause -#]] - -# NOTE(compnerd) because these modules are meant to be static and pristine, -# there can be no changes to the sources here. As such, these modules are safe -# to glob because they cannot impact the build. - -file(GLOB CASSOWARY_SOURCES - ${PROJECT_SOURCE_DIR}/Packages/cassowary/Sources/Cassowary/*.swift) -add_library(Cassowary SHARED - ${CASSOWARY_SOURCES}) -set_target_properties(Cassowary PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_Swift_MODULE_DIRECTORY}) -_install_target(Cassowary) - -file(GLOB_RECURSE COM_SOURCES - ${PROJECT_SOURCE_DIR}/Packages/SwiftCOM/Sources/SwiftCOM/*.swift - ${PROJECT_SOURCE_DIR}/Packages/SwiftCOM/Sources/SwiftCOM/**/*.swift) -add_library(SwiftCOM SHARED - ${COM_SOURCES}) -target_link_libraries(SwiftCOM PUBLIC - Ole32 - PortableDeviceGUIDs) -set_target_properties(SwiftCOM PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_Swift_MODULE_DIRECTORY}) -_install_target(SwiftCOM) - -file(GLOB LOGGING_SOURCES - ${PROJECT_SOURCE_DIR}/Packages/swift-log/Sources/Logging/*.swift) -# FIXME(compnerd) 5.5 does not officially support static libraries on Windows -# either. The support requires a version strictly greater than 5.5. Once the -# branch is introduced, adjust this accordingly. -if(Swift_COMPILER_VERSION VERSION_LESS 5.5) - add_library(Logging SHARED - ${LOGGING_SOURCES}) - _install_target(Logging) -else() - add_library(Logging STATIC - ${LOGGING_SOURCES}) -endif() - -add_subdirectory(SwiftWin32) -add_subdirectory(SwiftWin32UI) diff --git a/Sources/SwiftWin32/Animation and Haptics/Property-Based Animations/CubicTimingParameters.swift b/Sources/SwiftWin32/Animation and Haptics/Property-Based Animations/CubicTimingParameters.swift deleted file mode 100644 index 94b48be6..00000000 --- a/Sources/SwiftWin32/Animation and Haptics/Property-Based Animations/CubicTimingParameters.swift +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright © 2021 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -#if swift(>=5.7) -import CoreGraphics -#endif - -/// The timing information for animations in the form of a cubic Bézier curve. -public class CubicTimingParameters { - // MARK - Initializing a Cubic Timing Parameters Object - - /// Initializes the object with the system’s default timing curve. - public init() { - self.animationCurve = .linear - self.controlPoint1 = .zero - self.controlPoint2 = Point(x: 1, y: 1) - } - - /// Initializes the object with the specified builtin timing curve. - public init(animationCurve curve: View.AnimationCurve) { - self.animationCurve = curve - self.controlPoint1 = .zero - self.controlPoint2 = .zero - } - - /// Initializes the object with the specified control points for a cubic - /// Bézier curve. - public init(controlPoint1 point1: Point, controlPoint2 point2: Point) { - self.animationCurve = .linear - self.controlPoint1 = point1 - self.controlPoint2 = point2 - } - - // MARK - Getting the Timing Parameters - - /// The standard builtin animation curve to use for timing. - public private(set) var animationCurve: View.AnimationCurve - - /// The first control point for the cubic Bézier curve. - public private(set) var controlPoint1: Point - - /// The second control point of the cubic Bézier curve. - public private(set) var controlPoint2: Point -} diff --git a/Sources/SwiftWin32/Animation and Haptics/Property-Based Animations/SpringTimingParameters.swift b/Sources/SwiftWin32/Animation and Haptics/Property-Based Animations/SpringTimingParameters.swift deleted file mode 100644 index 5cadc584..00000000 --- a/Sources/SwiftWin32/Animation and Haptics/Property-Based Animations/SpringTimingParameters.swift +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright © 2021 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -#if swift(>=5.7) -import CoreGraphics -#endif - -/// The timing information for animations that mimics the behavior of a spring. -public class SpringTimingParameters { - // MARK - Initializing a Spring Timing Parameters Object - - /// Creates a default timing parameters object. - /// - /// This method sets the initial velocity of any animated properties to 0.0 - /// and sets the damping ratio to 4.56. - public init() { - self.initialVelocity = .zero - } - - /// Creates a timing parameters object with the specified damping ratio. - /// - /// This method sets the initial velocity of any animated properties to 0.0. - public convenience init(dampingRatio ratio: Double) { - self.init(dampingRatio: ratio, initialVelocity: .zero) - } - - /// Creates a timing parameters object with the specified damping ratio and - /// initial velocity. - public init(dampingRatio ratio: Double, initialVelocity velocity: Vector) { - self.initialVelocity = velocity - } - - /// Creates a timing parameters object with the specified spring stiffness, - /// mass, damping coefficient, and initial velocity. - /// - /// The damping ratio for the spring is computed from the formula: - /// `damping / (2 * sqrt (stiffness * mass))`. - public init(mass: Double, stiffness: Double, damping: Double, - initialVelocity velocity: Vector) { - self.initialVelocity = velocity - } - - // MARK - Getting the Initial Velocity - - /// The target property’s rate of change at the start of a spring animation, - /// enabling a smooth transition into the animation. - public private(set) var initialVelocity: Vector -} diff --git a/Sources/SwiftWin32/Animation and Haptics/Property-Based Animations/TimingCurveProvider.swift b/Sources/SwiftWin32/Animation and Haptics/Property-Based Animations/TimingCurveProvider.swift deleted file mode 100644 index 80bd4975..00000000 --- a/Sources/SwiftWin32/Animation and Haptics/Property-Based Animations/TimingCurveProvider.swift +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright © 2021 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -/// Constants indicating the type of timing information to use. -public enum TimingCurveType: Int { - /// Use the built-in timing curves. Specify this value when you want to use - /// one of the constants in the `View.AnimationCurve` type. Specify the - /// desired curve using the `cubicTimingParameters` property. - case builtin - - /// Use a custom cubic Bézier curve. Specify the curve information using the - /// `cubicTimingParameters` property. - case cubic - - /// Use a custom spring animation. Specify the desired curve using the - /// `springTimingParameters` property. - case spring - - /// Use a combination of timing parameters. This type of curve starts with the - /// curve defined by the `cubicTimingParameters` property and modifies it - /// using the spring information in the `springTimingParameters` property. - case composed -} - -/// An interface for providing the timing information needed to perform -/// animations. -public protocol TimingCurveProvider { - // MARK - Getting the Timing Information - - /// The type of timing information to use. - var timingCurveType: TimingCurveType { get } - - /// The cubic timing parameters to use. - var cubicTimingParameters: CubicTimingParameters? { get } - - /// The spring-based timing parameters to use. - var springTimingParameters: SpringTimingParameters? { get } -} diff --git a/Sources/SwiftWin32/Animation and Haptics/Property-Based Animations/ViewAnimating.swift b/Sources/SwiftWin32/Animation and Haptics/Property-Based Animations/ViewAnimating.swift deleted file mode 100644 index 376e54d9..00000000 --- a/Sources/SwiftWin32/Animation and Haptics/Property-Based Animations/ViewAnimating.swift +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright © 2021 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import struct Foundation.TimeInterval - -/// Constants indicating positions within the animation. -public enum ViewAnimatingPosition: Int { - /// The end point of the animation. Use this constant when you want the final - /// values for any animatable properties — that is, you want to refer to the - /// values you specified in your animation blocks. - case end - - /// The beginning of the animation. Use this constant when you want the - /// starting values for any animatable properties—that is, the values of the - /// properties before you applied any animations. - case start - - /// The current position. Use this constant when you want the most recent - /// value set by an animator object. - case current -} - -/// Constants indicating the current state of the animation. -public enum ViewAnimatingState: Int { - /// The animations have not yet started executing. This is the initial state - /// of the animator object. - case inactive - - /// The animator object is active and animations are either running or paused. - /// An animator moves to this state after the first call to `startAnimation()` - /// or `pauseAnimation()`. It stays in the active state until the animations - /// finish naturally or until you call the `stopAnimation(_:)` method. - case active - - /// The animation is stopped. Putting an animation into this state ends the - /// animation and leaves any animatable properties at their current values, - /// instead of updating them to their intended final values. An animation - /// cannot be started while in this state. - case stopped -} - -/// An interface for implementing custom animator objects. -public protocol ViewAnimating { - // MARK - Starting and Stopping the Animations - - /// Starts the animation from its current position. - func startAnimation() - - /// Starts the animation after the specified delay. - func startAnimation(afterDelay delay: TimeInterval) - - /// Pauses a running animation at its current position. - func pauseAnimation() - - /// Stops the animations at their current positions. - func stopAnimation(_ withoutFinishing: Bool) - - /// Finishes the animations and returns the animator to the inactive state. - func finishAnimation(at finalPositiong: ViewAnimatingPosition) - - // MARK - Getting the Animator's State - - /// The completion percentage of the animation. - var fractionComplete: Double { get set } - - /// A boolean value indicating whether the animation is running in the reverse - /// direction. - var isReversed: Bool { get set } - - /// The current state of the animation. - var state: ViewAnimatingState { get } - - /// A boolean value indicating whether the animation is currently running. - var isRunning: Bool { get } -} diff --git a/Sources/SwiftWin32/Animation and Haptics/Property-Based Animations/ViewImplicitlyAnimating.swift b/Sources/SwiftWin32/Animation and Haptics/Property-Based Animations/ViewImplicitlyAnimating.swift deleted file mode 100644 index 9dec6851..00000000 --- a/Sources/SwiftWin32/Animation and Haptics/Property-Based Animations/ViewImplicitlyAnimating.swift +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright © 2021 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -/// An interface for modifying an animation while it is running. -public protocol ViewImplicitlyAnimating: ViewAnimating { - // MARK - Modifying Animations - - /// Adds the specified animation block to the animator. - func addAnimations(_ animation: @escaping () -> Void) - - /// Adds the specified animation block to the animator with a delay. - func addAnimations(_ animation: @escaping () -> Void, delayFactor: Double) - - /// Adds the specified completion block to the animator. - func addCompletion(_ completion: @escaping (ViewAnimatingPosition) -> Void) - - /// Adjusts the final timing and duration of a paused animation. - func continueAnimation(withTimingParameters paramters: TimingCurveProvider?, - durationFactor: Double) -} - -extension ViewImplicitlyAnimating { - public func addAnimations(_ animation: @escaping () -> Void) { - self.addAnimations(animation, delayFactor: 0.0) - } - - public func addAnimations(_ animation: @escaping () -> Void, - delayFactor: Double) { - } - - public func addCompletion(_ completion: @escaping (ViewAnimatingPosition) -> Void) { - } - - public func continueAnimation(withTimingParameters paramters: TimingCurveProvider?, - durationFactor: Double) { - } -} diff --git a/Sources/SwiftWin32/Animation and Haptics/View Controller Transitions/ViewControllerAnimatedTransitioning.swift b/Sources/SwiftWin32/Animation and Haptics/View Controller Transitions/ViewControllerAnimatedTransitioning.swift deleted file mode 100644 index 67fca20c..00000000 --- a/Sources/SwiftWin32/Animation and Haptics/View Controller Transitions/ViewControllerAnimatedTransitioning.swift +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright © 2021 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import struct Foundation.TimeInterval - -/// A set of methods for implementing the animations for a custom view controller -/// transition. -public protocol ViewControllerAnimatedTransitioning { - // MARK - Performing a Transition - - /// Tells your animator object to perform the transition animations. - func animateTransition(using transitionContext: ViewControllerContextTransitioning) - - /// Tells your animator object that the transition animations have finished. - func animationEnded(_ transitionCompleted: Bool) - - // MARK - Reporting Transition Duration - - /// Asks your animator object for the duration (in seconds) of the transition - /// animation. - func transitionDuration(using transitionContext: ViewControllerContextTransitioning?) - -> TimeInterval - - // MARK - Returning an Interruptible Animator - - /// Returns the interruptible animator to use during the transition. - func interruptibleAnimator(using transitionContext: ViewControllerContextTransitioning) - -> ViewImplicitlyAnimating -} - -extension ViewControllerAnimatedTransitioning { - public func animationEnded(_ transitionCompleted: Bool) { - } -} - -extension ViewControllerAnimatedTransitioning { - func interruptibleAnimator(using transitionContext: ViewControllerContextTransitioning) - -> ViewImplicitlyAnimating { - fatalError("\(#function) not yet implemented") - } -} diff --git a/Sources/SwiftWin32/Animation and Haptics/View Controller Transitions/ViewControllerInteractiveTransitioning.swift b/Sources/SwiftWin32/Animation and Haptics/View Controller Transitions/ViewControllerInteractiveTransitioning.swift deleted file mode 100644 index eaaf1e61..00000000 --- a/Sources/SwiftWin32/Animation and Haptics/View Controller Transitions/ViewControllerInteractiveTransitioning.swift +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright © 2021 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -/// A set of methods that enable an object (such as a navigation controller) to -/// drive a view controller transition. -public protocol ViewControllerInteractiveTransitioning { - // MARK - Starting an Interactive Transition - - /// Called when the system needs to set up the interactive portions of a view - /// controller transition and start the animations. - func startInteractiveTransition(_ transitionContext: ViewControllerContextTransitioning) - - /// A boolean value indicating whether the transition is interactive when it - /// starts. - /// - /// The value of this property is `true` when the transition is interactive - /// from the moment it starts. The property is `false` when the transition - /// starts off as noninteractive. However, even a transition that starts off - /// as noninteractive may become interactive later if it implements the - /// `interruptibleAnimator(using:)` method of the - /// `ViewControllerAnimatedTransitioning` protocol. - var wantsInteractiveStart: Bool { get } - - // MARK - Providing a Transition's Completion Characteristics - - /// Called when the system needs the animation completion curve for an - /// interactive view controller transition. - var completionCurve: View.AnimationCurve { get } - - /// Called when the system needs the speed at which to complete an interactive - /// transition, after the interactive portion is finished. - var completionSpeed: Double { get } -} - -extension ViewControllerInteractiveTransitioning { - public var wantsInteractiveStart: Bool { true } -} - -extension ViewControllerInteractiveTransitioning { - public var completionCurve: View.AnimationCurve { .easeInOut } - - public var completionSpeed: Double { 1.0 } -} diff --git a/Sources/SwiftWin32/Animation and Haptics/View Controller Transitions/ViewControllerTransitionCoordinator.swift b/Sources/SwiftWin32/Animation and Haptics/View Controller Transitions/ViewControllerTransitionCoordinator.swift deleted file mode 100644 index 001dd72c..00000000 --- a/Sources/SwiftWin32/Animation and Haptics/View Controller Transitions/ViewControllerTransitionCoordinator.swift +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -public protocol ViewControllerTransitionCoordinator: ViewControllerTransitionCoordinatorContext { - /// Responding to View Controller Transition Progress - func animate(alongsideTransition animation: ((ViewControllerTransitionCoordinatorContext) -> Void)?, - completion: ((ViewControllerTransitionCoordinatorContext) -> Void)?) - -> Bool - func animateAlongsideTransition(in view: View?, - animation: ((ViewControllerTransitionCoordinatorContext) -> Void)?, - completion: ((ViewControllerTransitionCoordinatorContext) -> Void)?) - -> Bool - func notifyWhenInteractionChanges(_ handler: @escaping (ViewControllerTransitionCoordinatorContext) -> Void) -} diff --git a/Sources/SwiftWin32/Animation and Haptics/View Controller Transitions/ViewControllerTransitionCoordinatorContext.swift b/Sources/SwiftWin32/Animation and Haptics/View Controller Transitions/ViewControllerTransitionCoordinatorContext.swift deleted file mode 100644 index 43e3554a..00000000 --- a/Sources/SwiftWin32/Animation and Haptics/View Controller Transitions/ViewControllerTransitionCoordinatorContext.swift +++ /dev/null @@ -1,107 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import struct Foundation.TimeInterval - -#if swift(>=5.7) -import CoreGraphics -#endif - -/// Modal presentation styles available when presenting view controllers. -public enum ModalPresentationStyle: Int { - /// The default presentation style chosen by the system. - case automatic - - /// A presentation style that indicates no adaptations should be made. - case none - - /// A presentation style in which the presented view covers the screen. - case fullScreen - - /// A presentation style that partially covers the underlying content. - case pageSheet - - /// A presentation style that displays the content centered in the screen. - case formSheet - - /// A presentation style where the content is displayed over another view - /// controller's content. - case currentContext - - /// A custom view presentation style that is managed by a custom presentation - /// controller and one or more custom animator objects. - case custom - - /// A view presentation style in which the presented view covers the screen. - case overFullScreen - - /// A presentation style where the content is displayed over another view - /// controller's content. - case overCurrentContext - - /// A presentation style where the content is displayed in a popover view. - case popover - - /// A presentation style that blurs the underlying content before displaying new - /// content in a full-screen presentation. - case blurOverFullScreen -} - -/// A set of methods that provides information about an in-progress view -/// controller transition. -public protocol ViewControllerTransitionCoordinatorContext { - // MARK - Getting the Views and the View Controllers - - /// Returns the view controllers involved in the transition. - func viewController(forKey key: TransitionContextViewControllerKey) - -> ViewController? - - /// Returns the specified view involved in the transition. - func view(forKey key: TransitionContextViewKey) -> View? - - /// Returns the view in which the transition takes place. - var containerView: View { get } - - // MARK - Getting the Behaviour Attributes - - /// Returns the presentation style being used for the transition. - var presentationStyle: ModalPresentationStyle { get } - - /// Returns the noninteractive duration of a transition. - var transitionDuration: TimeInterval { get } - - /// Returns the completion curve associated with the transition. - var completionCurve: View.AnimationCurve { get } - - /// Returns the starting velocity to use for any final animations. - var completionVelocity: Double { get } - - /// Returns the percentage of completion for an interactive transition when it - /// moves to its noninteractive phase. - var percentComplete: Double { get } - - // MARK - Getting the Transition State - - /// A Boolean value indicating whether the transition started as an - /// interactive transition. - var initiallyInteractive: Bool { get } - - /// A Boolean value indicating whether the transition is currently interactive. - var isInteractive: Bool { get } - - /// A Boolean value indicating whether the transition is explicitly animated. - var isAnimated: Bool { get } - - /// A Boolean value indicating whether an interactive transition was cancelled. - var isCancelled: Bool { get } - - /// A Boolean value indicating whether the transition animations can be - /// interrupted. - var isInterruptible: Bool { get } - - // MARK - Getting the Rotation Factor - - /// Returns a transform indicating the amount of rotation being applied during - /// the transition. - var targetTransform: AffineTransform { get } -} diff --git a/Sources/SwiftWin32/Animation and Haptics/View Controller Transitions/ViewControllerTransitioningDelegate.swift b/Sources/SwiftWin32/Animation and Haptics/View Controller Transitions/ViewControllerTransitioningDelegate.swift deleted file mode 100644 index edfb208b..00000000 --- a/Sources/SwiftWin32/Animation and Haptics/View Controller Transitions/ViewControllerTransitioningDelegate.swift +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright © 2021 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -/// A set of methods that vend objects used to manage a fixed-length or -/// interactive transition between view controllers. -public protocol ViewControllerTransitioningDelegate: AnyObject { - // MARK - Getting the Transition Animator Objects - - /// Asks your delegate for the transition animator object to use when - /// presenting a view controller. - func animationController(forPresented presented: ViewController, - presenting: ViewController, source: ViewController) - -> ViewControllerAnimatedTransitioning? - - /// Asks your delegate for the transition animator object to use when - /// dismissing a view controller. - func animationController(forDismissed dismissed: ViewController) - -> ViewControllerAnimatedTransitioning? - - // MARK - Getting the Interactive Animator Objects - - /// Asks your delegate for the interactive animator object to use when - /// presenting a view controller. - func interactionControllerForPresentation(using animator: ViewControllerAnimatedTransitioning) - -> ViewControllerInteractiveTransitioning? - - /// Asks your delegate for the interactive animator object to use when - /// dismissing a view controller. - func interactionControllerForDismissal(using animator: ViewControllerAnimatedTransitioning) - -> ViewControllerInteractiveTransitioning? - - // MARK - Getting the Custom Presentation Controller - - /// Asks your delegate for the custom presentation controller to use for - /// managing the view hierarchy when presenting a view controller. - func presentationController(forPresented presented: ViewController, - presenting: ViewController?, - source: ViewController) - -> PresentationController? -} - -extension ViewControllerTransitioningDelegate { - public func animationController(forPresented presented: ViewController, - presenting: ViewController, source: ViewController) - -> ViewControllerAnimatedTransitioning? { - return nil - } - - public func animationController(forDismissed dismissed: ViewController) - -> ViewControllerAnimatedTransitioning? { - return nil - } -} - -extension ViewControllerTransitioningDelegate { - public func interactionControllerForPresentation(using animator: ViewControllerAnimatedTransitioning) - -> ViewControllerInteractiveTransitioning? { - return nil - } - - public func interactionControllerForDismissal(using animator: ViewControllerAnimatedTransitioning) - -> ViewControllerInteractiveTransitioning? { - return nil - } -} - -extension ViewControllerTransitioningDelegate { - public func presentationController(forPresented presented: ViewController, - presenting: ViewController?, - source: ViewController) - -> PresentationController? { - return nil - } -} diff --git a/Sources/SwiftWin32/Animation and Haptics/ViewControllerContextTransitioning.swift b/Sources/SwiftWin32/Animation and Haptics/ViewControllerContextTransitioning.swift deleted file mode 100644 index c3b151c5..00000000 --- a/Sources/SwiftWin32/Animation and Haptics/ViewControllerContextTransitioning.swift +++ /dev/null @@ -1,121 +0,0 @@ -// Copyright © 2021 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -#if swift(>=5.7) -import CoreGraphics -#endif - -/// The keys you use to identify the view controllers involved in a transition. -public struct TransitionContextViewControllerKey: Equatable, Hashable, RawRepresentable { - public typealias RawValue = String - - public let rawValue: RawValue - - public init(rawValue: RawValue) { - self.rawValue = rawValue - } -} - -extension TransitionContextViewControllerKey { - /// A key that identifies the view controller that is visible at the beginning - /// of the transition, or at the end of a canceled transition. - public static var from: TransitionContextViewControllerKey { - TransitionContextViewControllerKey(rawValue: "UITransitionContextFromViewController") - } - - /// A key that identifies the view controller that is visible at the end of a - /// completed transition. - public static var to: TransitionContextViewControllerKey { - TransitionContextViewControllerKey(rawValue: "UITransitionContextToViewController") - } -} - -/// The keys you use to identify the views involved in a transition. -public struct TransitionContextViewKey: Equatable, Hashable, RawRepresentable { - public typealias RawValue = String - - public let rawValue: RawValue - - public init(rawValue: RawValue) { - self.rawValue = rawValue - } -} - -extension TransitionContextViewKey { - /// A key that identifies the view shown at the beginning of the transition, - /// or at the end of a canceled transition. - public static var from: TransitionContextViewKey { - TransitionContextViewKey(rawValue: "UITransitionContextFromView") - } - - /// A key that identifies the view shown at the end of a completed transition. - public static var to: TransitionContextViewKey { - TransitionContextViewKey(rawValue: "UITransitionContextToView") - } -} - -/// A set of methods that provide contextual information for transition -/// animations between view controllers. -public protocol ViewControllerContextTransitioning { - // MARK - Accessing the Transition Objects - - /// The view that acts as the superview for the views involved in the - /// transition. - var containerView: View { get } - - /// Returns a view controller involved in the transition. - func viewController(forKey key: TransitionContextViewControllerKey) - -> ViewController? - - /// Returns the specified view involved in the transition. - func view(forKey key: TransitionContextViewKey) -> View? - - // MARK - Getting the Transition Frame Rectangles - - /// Returns the starting frame rectangle for the specified view controller's - /// view. - func initialFrame(for viewController: ViewController) -> Rect - - /// Returns the ending frame rectangle for the specified view controller's - /// view. - func finalFrame(for viewController: ViewController) -> Rect - - // MARK - Getting the Transition Behaviors - - /// A boolean value indicating whether the transition should be animated. - var isAnimated: Bool { get } - - /// A boolean value indicating whether the transition is currently - /// interactive. - var isInteractive: Bool { get } - - /// Returns the presentation style for the view controller transition. - var presentationStyle: ModalPresentationStyle { get } - - // MARK - Reporting the Transition Progress - - /// Notifies the system that the transition animation is done. - func completeTransition(_ didComplete: Bool) - - /// Updates the completion percentage of the transition. - func updateInteractiveTransition(_ percentComplete: Double) - - /// Tells the system to pause the animations. - func pauseInteractiveTransition() - - /// Notifies the system that user interactions signaled the completion of the - /// transition. - func finishInteractiveTransition() - - /// Notifies the system that user interactions canceled the transition. - func cancelInteractiveTransition() - - /// Returns a boolean value indicating whether the transition was canceled. - var transitionWasCancelled: Bool { get } - - // MARK - Getting the Rotation Factor - - /// Returns a transform indicating the amount of rotation being applied during - /// the transition. - var targetTransform: AffineTransform { get } -} diff --git a/Sources/SwiftWin32/App Extensions/InputViewController.swift b/Sources/SwiftWin32/App Extensions/InputViewController.swift deleted file mode 100644 index d84de6d5..00000000 --- a/Sources/SwiftWin32/App Extensions/InputViewController.swift +++ /dev/null @@ -1,5 +0,0 @@ -// Copyright © 2021 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -public class InputViewController: ViewController { -} diff --git a/Sources/SwiftWin32/App and Environment/AdaptivePresentationControllerDelegate.swift b/Sources/SwiftWin32/App and Environment/AdaptivePresentationControllerDelegate.swift deleted file mode 100644 index 1cd99d38..00000000 --- a/Sources/SwiftWin32/App and Environment/AdaptivePresentationControllerDelegate.swift +++ /dev/null @@ -1,168 +0,0 @@ -// Copyright © 2021 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -/// A set of methods that, in conjunction with a presentation controller, -/// determine how to respond to trait changes in your application. -public protocol AdaptivePresentationControllerDelegate: AnyObject { - // MARK - Adapting the Presentation Style - - /// Asks the delegate for the presentation style to use when the specified set - /// of traits are active. - /// - /// The presentation controller calls this method when the traits of the - /// current environment are about to change. Your implementation of this - /// method can return the preferred presentation style to use for the - /// specified traits. If you do not return one of the allowed styles, the - /// presentation controller uses its preferred default style. - /// - /// If you do not implement this method in your delegate, the framework calls - /// the `adaptivePresentationStyle(for:)` method instead. - func adaptivePresentationStyle(for controller: PresentationController, - traitCollection: TraitCollection) - -> ModalPresentationStyle - - /// Asks the delegate for the new presentation style to use. - /// - /// Use the `adaptivePresentationStyle(for:traitCollection:)` method to handle - /// all trait changes instead of this method. If you do not implement that - /// method, you can use this method to change the presentation style when - /// transitioning to a horizontally compact environment. - /// - /// If you do not implement this method or if you return an invalid style, the - /// current presentation controller returns its preferred default style. - func adaptivePresentationStyle(for controller: PresentationController) - -> ModalPresentationStyle - - // MARK - Adapting the View Controller - - /// Asks the delegate for the view controller to display when adapting to the - /// specified presentation style. - /// - /// When a size class change causes a change to the underlying presentation - /// style, the presentation controller calls this method to ask for the view - /// controller to display in that new style. This method is your opportunity - /// to replace the current view controller with one that is better suited for - /// the new presentation style. For example, you might use this method to - /// insert a navigation controller into your view hierarchy to facilitate - /// pushing new view controllers more easily in the compact environment. In - /// that instance, you would return a navigation controller whose root view - /// controller is the currently presented view controller. You could also - /// return an entirely different view controller if you prefer. - /// - /// If you do not implement this method or your implementation returns `nil`, - /// the presentation controller uses its existing presented view controller. - func presentationController(_ controller: PresentationController, - viewControllerForAdaptivePresentationStyle style: ModalPresentationStyle) - -> ViewController? - - // MARK - Responding to Adaptive Transitions - - /// Notifies the delegate that an adaptivity-related transition is about to - /// occur. - /// - /// When a size class change occurs, the framework calls this method to let - /// you know how the presentation controller will adapt. Use this method to - /// make any additional changes. For example, you might use the transition - /// coordinator object to create additional animations for the transition. - func presentationController(_ presentationController: PresentationController, - willPresentWithAdaptiveStyle style: ModalPresentationStyle, - transitionCoordinator: ViewControllerTransitionCoordinator?) - - /// Notifies the delegate that a user-initiated attempt to dismiss a view was - /// prevented. - /// - /// The framework supports refusing to dismiss a presentation when the - /// `presentationController.isModalInPresentation` returns `true` or - /// `presentationControllerShouldDismiss(_:)` returns `false`. - /// - /// Use this method to inform the user why the presentation can't be - /// dismissed, for example, by presenting an instance of `AlertController`. - func presentationControllerDidAttemptToDismiss(_ presentationController: PresentationController) - - /// Asks the delegate for permission to dismiss the presentation. - /// - /// The system may call this method at any time. This method isn't guaranteed - /// to be followed by a call to `presentationControllerWillDismiss(_:)` or - /// `presentationControllerDidDismiss(_:)`. Make sure that your implementation - /// of this method returns quickly. - func presentationControllerShouldDismiss(_ presentationController: PresentationController) - -> Bool - - /// Notifies the delegate after a presentation is dismissed. - /// - /// This method is not called if the presentation is dismissed - /// programmatically. - func presentationControllerDidDismiss(_ presentationController: PresentationController) - - /// Notifies the delegate before a presentation is dismissed. - /// - /// You can use this method to set up animations or interaction notifications - /// with the `presentationController`'s `transitionCoordinator`. - /// - /// This method is not called if the presentation is dismissed - /// programmatically. - func presentationControllerWillDismiss(_ presentationController: PresentationController) - - // MARK - Preparing the Adaptive Presentation Controller - - /// Provides an opportunity to configure the adaptive presentation controller - /// after an adaptivity change. - /// - /// The system calls this method during adaptation so the delegate can - /// configure properties of the adaptive presentation controller before it - /// presents. - /// - /// For example, the system automatically adapts a view controller that - /// presents as a popover in standard size classes to a sheet in compact size - /// classes. You can implement this method to customize the sheet's - /// properties before it presents. - func presentationController(_ presentationController: PresentationController, - prepare adaptivePresentationController: PresentationController) -} - -extension AdaptivePresentationControllerDelegate { - public func adaptivePresentationStyle(for controller: PresentationController, - traitCollection: TraitCollection) - -> ModalPresentationStyle { - return self.adaptivePresentationStyle(for: controller) - } - - public func adaptivePresentationStyle(for controller: PresentationController) - -> ModalPresentationStyle { - return controller.presentationStyle - } -} - -extension AdaptivePresentationControllerDelegate { - public func presentationController(controller: PresentationController, - viewControllerForAdaptivePresentationStyle style: ModalPresentationStyle) - -> ViewController? { - return controller.presentedViewController - } -} - -extension AdaptivePresentationControllerDelegate { - public func presentationController(_ controller: PresentationController, - willPresentWithAdaptiveStyle style: ModalPresentationStyle, - transitionCoordinator: ViewControllerTransitionCoordinator?) { - } - - public func presentationControllerDidAttemptToDismiss(_ presentationController: PresentationController) { - } - - public func presentationControllerShouldDismiss(_ presentationController: PresentationController) -> Bool { - return true - } - - public func presentationControllerDidDismiss(_ presentationController: PresentationController) { - } - - public func presentationControllerWillDismiss(_ presentationController: PresentationController) { - } -} - -extension AdaptivePresentationControllerDelegate { - public func presentationController(_ presentationController: PresentationController, - prepare adaptivePresentationController: PresentationController) { - } -} diff --git a/Sources/SwiftWin32/App and Environment/Application.swift b/Sources/SwiftWin32/App and Environment/Application.swift deleted file mode 100644 index ca6d3f55..00000000 --- a/Sources/SwiftWin32/App and Environment/Application.swift +++ /dev/null @@ -1,186 +0,0 @@ -// Copyright © 2019 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import class Foundation.NSNotification - -/// Constants that indicate the preferred size of your content. -public struct ContentSizeCategory: Equatable, Hashable, RawRepresentable { - public typealias RawValue = String - - public var rawValue: RawValue - - public init(rawValue: RawValue) { - self.rawValue = rawValue - } -} - -extension ContentSizeCategory { - // MARK - Font Sizes - - /// An unspecified font size. - public static var unspecified: ContentSizeCategory { - ContentSizeCategory(rawValue: "_UICTContentSizeCategoryUnspecified") - } - - /// An extra-small font. - public static var extraSmall: ContentSizeCategory { - ContentSizeCategory(rawValue: "UICTContentSizeCategoryXS") - } - - /// A small font. - public static var small: ContentSizeCategory { - ContentSizeCategory(rawValue: "UICTContentSizeCategoryS") - } - - /// A medium-sized font. - public static var medium: ContentSizeCategory { - ContentSizeCategory(rawValue: "UICTContentSizeCategoryM") - } - - /// A large font. - public static var large: ContentSizeCategory { - ContentSizeCategory(rawValue: "UICTContentSizeCategoryL") - } - - /// An extra-large font. - public static var extraLarge: ContentSizeCategory { - ContentSizeCategory(rawValue: "UICTContentSizeCategoryXL") - } - - /// A font that is larger than the extra-large font but smaller than the - /// largest font size available. - public static var extraExtraLarge: ContentSizeCategory { - ContentSizeCategory(rawValue: "UICTContentSizeCategoryXXL") - } - - /// The largest font size. - public static var extraExtraExtraLarge: ContentSizeCategory { - ContentSizeCategory(rawValue: "UICTContentSizeCategoryXXXL") - } - - // MARK - Accessibility Sizes - - /// A medium font size that reflects the current accessibility settings. - public static var accessibilityMedium: ContentSizeCategory { - ContentSizeCategory(rawValue: "UICTContentSizeCategoryAccessibilityM") - } - - /// A large font size that reflects the current accessibility settings. - public static var accessibilityLarge: ContentSizeCategory { - ContentSizeCategory(rawValue: "UICTContentSizeCategoryAccessibilityL") - } - - /// An extra-large font size that reflects the current accessibility settings. - public static var accessibilityExtraLarge: ContentSizeCategory { - ContentSizeCategory(rawValue: "UICTContentSizeCategoryAccessibilityXL") - } - - /// A font that is larger than the extra-large font but not the largest - /// available, reflecting the current accessibility settings. - public static var accessibilityExtraExtraLarge: ContentSizeCategory { - ContentSizeCategory(rawValue: "UICTContentSizeCategoryAccessibilityXXL") - } - - /// The largest font size that reflects the current accessibility settings. - public static var accessibilityExtraExtraExtraLarge: ContentSizeCategory { - ContentSizeCategory(rawValue: "UICTContentSizeCategoryAccessibilityXXXL") - } - - // MARK - Font Size Change Notifications - - /// A notification that posts when the user changes the preferred content size - /// setting. - /// - /// This notification is sent when the value in the - /// `preferredContentSizeCategory` property changes. The `userInfo` dictionary - /// of the notification contains the `newValueUserInfoKey` key, which reflects - /// the new setting. - public static var didChangeNotification: NSNotification.Name { - NSNotification.Name(rawValue: "UIContentSizeCategoryDidChangeNotification") - } - - /// A key that reflects the new preferred content size. - /// - /// This key's value is an `NSString` object that reflects the new value of - /// the `preferredContentSizeCategory` property. - public static var newValueUserInfoKey: String { - "UIContentSizeCategoryNewValueUserInfoKey" - } -} - -/// The centralised point of control and coordination for running applications. -open class Application: Responder { - internal var information: Information? - - // MARK - Getting the Application Instance - - /// Returns the singleton application instance. - public static var shared: Application = Application() - - // MARK - Managing the Application's Behaviour - - /// The delegate of the application object. - public var delegate: ApplicationDelegate? - - // MARK - Getting the Application State - - /// The applications current state or that of its most active scene. - public internal(set) var state: Application.State - - // MARK - Getting Scene Information - - /// A boolean indicating whether the application may display multiple scenes. - public var supportsMultipleScenes: Bool { - information?.scene?.supportsMultipleScenes ?? false - } - - /// The application's currently connected scenes. - public internal(set) var connectedScenes: Set = [] - - /// The sessions whose scenes are either currently active or archived by the - /// system. - public internal(set) var openSessions: Set = [] - - // MARK - Getting Application Windows - - /// The application’s visible and hidden windows. - public internal(set) var windows: [Window] - - /// The application's key window. - public internal(set) var keyWindow: Window? - - override public required init() { - self.state = .active - self.windows = [] - super.init() - } - - // MARK - Responder Chain Overrides - - override public var next: Responder? { - // The next responder is the application delegate, but only if the - // application delegate is an instance of `Responder` and is not a `View`, - // `ViewController`, or the `Application` object itself. - if let responder = self.delegate as? Responder, - !(self.delegate is View), !(self.delegate is ViewController), - !(self.delegate === self) { - return responder - } - return nil - } -} - -extension Application { - /// The running states of the application - public enum State: Int { - /// The application is running in the foreground and currently receiving - /// events. - case active - - /// The application is running in the foreground but is not receiving events. - case inactive - - /// The application is running in the background. - case background - } -} diff --git a/Sources/SwiftWin32/App and Environment/ApplicationDelegate.swift b/Sources/SwiftWin32/App and Environment/ApplicationDelegate.swift deleted file mode 100644 index 499152f6..00000000 --- a/Sources/SwiftWin32/App and Environment/ApplicationDelegate.swift +++ /dev/null @@ -1,271 +0,0 @@ -// Copyright © 2019 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import class Foundation.NSNotification - -/// The orientation of the application's user interface -public enum InterfaceOrientation: Int { - /// The orientation of the device is unknown. - case unknown - - /// The device is in portrait mode, with the device upright. - case portrait - - /// The device is in portrait mode, with the device upside down. - case portraitUpsideDown - - /// The device is in landscape mode, with the device upright. - case landscapeLeft - - /// The device is in landscape mode, with the device upright. - case landscapeRight -} - -extension InterfaceOrientation { - public var isLandscape: Bool { - switch self { - case .landscapeLeft, .landscapeRight: - return true - default: return false - } - } - - public var isPortrait: Bool { - switch self { - case .portrait, .portraitUpsideDown: - return true - default: return false - } - } -} - -/// These constants are mask bits for specifying a view controller's supported -/// interface orientations. -public struct InterfaceOrientationMask: OptionSet { - public typealias RawValue = UInt - - public let rawValue: RawValue - - public init(rawValue: RawValue) { - self.rawValue = rawValue - } -} - -extension InterfaceOrientationMask { - /// The view controller supports a portrait interface orientation. - public static var portrait: InterfaceOrientationMask { - InterfaceOrientationMask(rawValue: 1 << InterfaceOrientation.portrait.rawValue) - } - - /// The view controller supports a landscape-left interface orientation. - public static var landscapeLeft: InterfaceOrientationMask { - InterfaceOrientationMask(rawValue: 1 << InterfaceOrientation.landscapeLeft.rawValue) - } - - /// The view controller supports a landscape-right interface orientation. - public static var landscapeRight: InterfaceOrientationMask { - InterfaceOrientationMask(rawValue: 1 << InterfaceOrientation.landscapeRight.rawValue) - } - - /// The view controller supports an upside-down portrait interface - /// orientation. - public static var portraitUpsideDown: InterfaceOrientationMask { - InterfaceOrientationMask(rawValue: 1 << InterfaceOrientation.portraitUpsideDown.rawValue) - } - - /// The view controller supports both landscape-left and landscape-right - /// interface orientation. - public static var landscape: InterfaceOrientationMask { - InterfaceOrientationMask(rawValue: self.landscapeLeft.rawValue | self.landscapeRight.rawValue) - } - - /// The view controller supports all interface orientations. - public static var all: InterfaceOrientationMask { - InterfaceOrientationMask(rawValue: self.portrait.rawValue | self.landscapeLeft.rawValue | self.landscapeRight.rawValue | self.portraitUpsideDown.rawValue) - } - - /// The view controller supports all but the upside-down portrait interface - /// orientation. - public static var allButUpsideDown: InterfaceOrientationMask { - InterfaceOrientationMask(rawValue: self.portrait.rawValue | self.landscapeLeft.rawValue | self.landscapeRight.rawValue) - } -} - -/// A set of methods used to manage shared behaviours for the application. -public protocol ApplicationDelegate: AnyObject, _TriviallyConstructible { - // MARK - Initializing the App - - /// Informs the delegate that the application launch process has begun. - func application(_ application: Application, - willFinishLaunchingWithOptions options: [Application.LaunchOptionsKey:Any]?) - -> Bool - - /// Informs the delegate that the application launch process has ended and - /// the application is almost ready to run. - func application(_ application: Application, - didFinishLaunchingWithOptions options: [Application.LaunchOptionsKey:Any]?) - -> Bool - - // MARK - Responding to App Life-Cycle Events - - /// Informs the delegate that the application has become active. - func applicationDidBecomeActive(_ application: Application) - - /// Informs the delegate that the application is about to become inactive. - func applicationWillResignActive(_ application: Application) - - /// Informs the delegate that the application is now in the background. - func applicationDidEnterBackground(_ application: Application) - - /// Informs the delegate that the application is about to enter the foreground. - func applicationWillEnterForeground(_ application: Application) - - /// Informs the delegate that the application is about to terminate. - func applicationWillTerminate(_ application: Application) - - // MARK - Responding to Environment Changes - - /// Tells the delegate that protected files are available now. - func applicationProtectedDataDidBecomeAvailable(_ application: Application) - - /// Tells the delegate that the protected files are about to become - /// unavailable. - func applicationProtectedDataWillBecomeUnavailable(_ application: Application) - - /// Tells the delegate when the app receives a memory warning from the system. - func applicationDidReceiveMemoryWarning(_ application: Application) - - /// Tells the delegate when there is a significant change in the time. - func applicationSignificantTimeChange(_ application: Application) - - // MARK - Configuring and Discarding Scenes - - /// Returns the configuration data to use when creating a new scene. - func application(_ application: Application, - configurationForConnecting connectingSceneSession: SceneSession, - options: Scene.ConnectionOptions) -> SceneConfiguration - - /// Informs the delegate that the user closed one or more of the application's - /// scenes. - func application(_ application: Application, - didDiscardSceneSessions sceneSessions: Set) -} - -extension ApplicationDelegate { - public func application(_ application: Application, - willFinishLaunchingWithOptions options: [Application.LaunchOptionsKey:Any]?) - -> Bool { - return true - } - - public func application(_ application: Application, - didFinishLaunchingWithOptions options: [Application.LaunchOptionsKey:Any]?) - -> Bool { - return true - } - - /// A notification that posts immediately after the app finishes launching. - public static var didFinishLaunchingNotification: NSNotification.Name { - NSNotification.Name(rawValue: "UIApplicationDidFinishLaunchingNotification") - } -} - -extension ApplicationDelegate { - public func applicationDidBecomeActive(_: Application) { - } - - public func applicationWillResignActive(_: Application) { - } - - public func applicationDidEnterBackground(_: Application) { - } - - public func applicationWillEnterForeground(_: Application) { - } - - public func applicationWillTerminate(_: Application) { - } - - /// A notification that posts when the app becomes active. - public static var didBecomeActiveNotification: NSNotification.Name { - NSNotification.Name(rawValue: "UIApplicationDidBecomeActiveNotification") - } - - /// A notification that posts when the app is no longer active and loses - /// focus. - public static var willResignActiveNotification: NSNotification.Name { - NSNotification.Name(rawValue: "UIApplicationWillResignActiveNotification") - } - - /// A notification that posts when the app enters the background. - public static var didEnterBackgroundNotification: NSNotification.Name { - NSNotification.Name(rawValue: "UIApplicationDidEnterBackgroundNotification") - } - - /// A notification that posts shortly before an app leaves the background - /// state on its way to becoming the active app. - public static var willEnterForegroundNotification: NSNotification.Name { - NSNotification.Name(rawValue: "UIApplicationWillEnterForegroundNotification") - } - - /// A notification that posts when the app is about to terminate. - public static var willTerminateNotification: NSNotification.Name { - NSNotification.Name(rawValue: "UIApplicationWillTerminateNotification") - } -} - -extension ApplicationDelegate { - public func applicationProtectedDataDidBecomeAvailable(_ application: Application) { - } - - public func applicationProtectedDataWillBecomeUnavailable(_ application: Application) { - } - - public func applicationDidReceiveMemoryWarning(_ application: Application) { - } - - public func applicationSignificantTimeChange(_ application: Application) { - } - - /// A notification that posts when the protected files become available for - /// your code to access. - public static var protectedDataDidBecomeAvailableNotification: NSNotification.Name { - NSNotification.Name(rawValue: "UIApplicationProtectedDataDidBecomeAvailableNotification") - } - - /// A notification that posts shortly before protected files are locked down - /// and become inaccessible. - public static var protectedDataWillBecomeUnavailableNotification: NSNotification.Name { - NSNotification.Name(rawValue: "UIApplicationProtectedDataWillBecomeUnavailableNotification") - } - - /// A notification that posts when the app receives a warning from the - /// operating system about low memory availability. - public static var didReceiveMemoryWarningNotification: NSNotification.Name { - NSNotification.Name(rawValue: "UIApplicationDidReceiveMemoryWarningNotification") - } - - /// A notification that posts when there is a significant change in time, for - /// example, change to a new day (midnight), carrier time update, and change - /// to or from daylight savings time. - public static var significantTimeChangeNotification: NSNotification.Name { - NSNotification.Name(rawValue: "UIApplicationSignificantTimeChangeNotification") - } -} - -extension ApplicationDelegate { - public func application(_ application: Application, - configurationForConnecting connectingSceneSession: SceneSession, - options: Scene.ConnectionOptions) -> SceneConfiguration { - return connectingSceneSession.configuration - } - - public func application(_ application: Application, - didDiscardSceneSessions sceneSessions: Set) { - sceneSessions.forEach { - if let scene = $0.scene { - scene.delegate?.sceneDidDisconnect(scene) - } - } - } -} diff --git a/Sources/SwiftWin32/App and Environment/ApplicationMain.swift b/Sources/SwiftWin32/App and Environment/ApplicationMain.swift deleted file mode 100644 index ca05b892..00000000 --- a/Sources/SwiftWin32/App and Environment/ApplicationMain.swift +++ /dev/null @@ -1,226 +0,0 @@ -// Copyright © 2019 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import WinSDK -import SwiftCOM -import Foundation - -internal final class Delegate: ApplicationDelegate {} - -private let pApplicationStateChangeRoutine: PAPPSTATE_CHANGE_ROUTINE = { (quiesced: UInt8, context: PVOID?) in - let foregrounding: Bool = quiesced == 0 - if foregrounding { - Application.shared.delegate? - .applicationWillEnterForeground(Application.shared) - - // Post ApplicationDelegate.willEnterForegroundNotification - NotificationCenter.default - .post(name: Delegate.willEnterForegroundNotification, - object: Application.shared) - } else { - Application.shared.delegate? - .applicationDidEnterBackground(Application.shared) - - // Post ApplicationDelegate.willEnterBackgroundNotification - NotificationCenter.default - .post(name: Delegate.didEnterBackgroundNotification, - object: Application.shared) - } -} - -@discardableResult -public func ApplicationMain(_ argc: Int32, - _ argv: UnsafeMutablePointer?>, - _ application: String?, - _ delegate: String?) -> Int32 { - let hRichEdit: HMODULE? = LoadLibraryW("msftedit.dll".wide) - if hRichEdit == nil { - log.error("unable to load `msftedit.dll`: \(Error(win32: GetLastError()))") - } - - var information: Application.Information? - if let path = Bundle.main.path(forResource: "Info", ofType: "plist"), - let contents = FileManager.default.contents(atPath: path) { - information = try? PropertyListDecoder().decode(Application.Information.self, - from: contents) - } - - // Setup the main application class. The following order describes how the - // user may actually configure the selected class: - // - // 1. `application`: the parameter passd to `ApplicationMain(_:_:_:_:)` - // 2. `PrincipalClass`: the value configured in `Info.plist` - // 3. `Application`: the default application class provided by Swift/Win32 - // - // We must have an application class to instantiate as this is the main entry - // point which is executed by this framework. - let application = application ?? (information?.principalClass ?? NSStringFromClass(Application.self)) - guard let instance = NSClassFromString(application) else { - log.error("unable to find application class \(application)") - exit(EXIT_FAILURE) - } - Application.shared = (instance as! Application.Type).init() - - // Setup the application's information which was loaded. Because the - // configuration can indicate the principal class it is loaded prior to the - // construction of the shared application's construction. Now that the - // application has been construted, we can instill the configuration. - Application.shared.information = information - - // Setup the application's delegate. - if let delegate = delegate { - guard let instance = NSClassFromString(delegate) else { - fatalError("unable to find delegate class: \(delegate)") - } - if instance as? Application.Type == nil { - Application.shared.delegate = (instance as! ApplicationDelegate.Type).init() - } else { - Application.shared.delegate = Application.shared as? ApplicationDelegate - } - } - - // Initialize COM - do { - try CoInitializeEx(COINIT_MULTITHREADED) - } catch { - log.error("CoInitializeEx: \(error)") - return EXIT_FAILURE - } - - // Enable Per Monitor DPI Awareness - if !SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2) { - log.error("SetProcessDpiAwarenessContext: \(Error(win32: GetLastError()))") - } - - let dwICC: DWORD = DWORD(ICC_BAR_CLASSES) - | DWORD(ICC_DATE_CLASSES) - | DWORD(ICC_LISTVIEW_CLASSES) - | DWORD(ICC_NATIVEFNTCTL_CLASS) - | DWORD(ICC_PROGRESS_CLASS) - | DWORD(ICC_STANDARD_CLASSES) - | DWORD(ICC_TAB_CLASSES) - var ICCE: INITCOMMONCONTROLSEX = - INITCOMMONCONTROLSEX(dwSize: DWORD(MemoryLayout.size), - dwICC: dwICC) - if !InitCommonControlsEx(&ICCE) { - log.error("InitCommonControlsEx: \(Error(win32: GetLastError()))") - } - - if Application.shared.delegate? - .application(Application.shared, - willFinishLaunchingWithOptions: nil) == false { - return EXIT_FAILURE - } - - var pAppRegistration: PAPPSTATE_REGISTRATION? - let ulStatus = - RegisterAppStateChangeNotification(pApplicationStateChangeRoutine, nil, - &pAppRegistration) - if ulStatus != ERROR_SUCCESS { - log.error("RegisterAppStateChangeNotification: \(Error(win32: GetLastError()))") - } - defer { UnregisterAppStateChangeNotification(pAppRegistration) } - - if Application.shared.delegate? - .application(Application.shared, - didFinishLaunchingWithOptions: nil) == false { - return EXIT_FAILURE - } - - // Post ApplicationDelegate.didFinishLaunchingNotification - NotificationCenter.default - .post(name: Delegate.didFinishLaunchingNotification, - object: nil, userInfo: nil) - - Application.shared.delegate? - .applicationDidBecomeActive(Application.shared) - - // TODO(compnerd) populate these based on the application instantiation - let options: Scene.ConnectionOptions = Scene.ConnectionOptions() - - // Setup the scene session. - let (_, session) = - Application.shared.openSessions - .insert(SceneSession(identifier: UUID().uuidString, - role: .windowApplication)) - - // Update the scene configuration based on the delegate's response. - if let configuration = Application.shared.delegate? - .application(Application.shared, configurationForConnecting: session, - options: options) { - session.configuration = configuration - } - - // Create the scene. - let SceneType = - (session.configuration.sceneClass as? Scene.Type) ?? WindowScene.self - - let (_, scene) = - Application.shared.connectedScenes - .insert(SceneType.init(session: session, connectionOptions: options)) - - if let DelegateType = - session.configuration.delegateClass as? SceneDelegate.Type { - // Only instantiate the scene delegate if the scene delegate is not the - // Application class or the ApplicationDelegate class. - if DelegateType as? Application.Type == nil { - if DelegateType as? ApplicationDelegate.Type == nil { - scene.delegate = DelegateType.init() - } else { - scene.delegate = Application.shared.delegate as? SceneDelegate - } - } else { - scene.delegate = Application.shared as? SceneDelegate - } - } - - scene.delegate?.scene(scene, willConnectTo: session, options: options) - session.scene = scene - - var msg: MSG = MSG() - var nExitCode: Int32 = EXIT_SUCCESS - - mainLoop: while true { - // Process all messages in thread's message queue; for GUI applications UI - // events must have high priority. - while PeekMessageW(&msg, nil, 0, 0, UINT(PM_REMOVE)) { - if msg.message == UINT(WM_QUIT) { - nExitCode = Int32(msg.wParam) - break mainLoop - } - - TranslateMessage(&msg) - DispatchMessageW(&msg) - } - - var time: Date? = nil - repeat { - // Execute Foundation.RunLoop once and determine the next time the timer - // fires. At this point handle all Foundation.RunLoop timers, sources and - // Dispatch.DispatchQueue.main tasks - time = RunLoop.main.limitDate(forMode: .default) - - // If Foundation.RunLoop doesn't contain any timers or the timers should - // not be running right now, we interrupt the current loop or otherwise - // continue to the next iteration. - } while (time?.timeIntervalSinceNow ?? -1) <= 0 - - // Yield control to the system until the earlier of a requisite timer - // expiration or a message is posted to the runloop. - _ = MsgWaitForMultipleObjects(0, nil, false, - DWORD(exactly: time?.timeIntervalSinceNow ?? -1) - ?? INFINITE, - QS_ALLINPUT | DWORD(QS_KEY) | QS_MOUSE | DWORD(QS_RAWINPUT)) - } - - Application.shared.delegate?.applicationWillTerminate(Application.shared) - - return nExitCode -} - -extension ApplicationDelegate { - public static func main() { - ApplicationMain(CommandLine.argc, CommandLine.unsafeArgv, nil, - String(describing: String(reflecting: Self.self))) - } -} diff --git a/Sources/SwiftWin32/App and Environment/Device.swift b/Sources/SwiftWin32/App and Environment/Device.swift deleted file mode 100644 index 65d715ae..00000000 --- a/Sources/SwiftWin32/App and Environment/Device.swift +++ /dev/null @@ -1,250 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import WinSDK -import class Foundation.NSNotification - -public struct Device { - public static let current: Device = Device() - - /// Is multitasking supported on the current device - public internal(set) var isMultitaskingSupported: Bool = true - - /// The name identifyying the device - public var name: String { - let value: [WCHAR] = - Array(unsafeUninitializedCapacity: Int(MAX_COMPUTERNAME_LENGTH) + 1) { - var nSize: DWORD = DWORD($0.count) - $1 = GetComputerNameW($0.baseAddress!, &nSize) ? Int(nSize) + 1 : 0 - } - return String(decodingCString: value, as: UTF16.self) - } - - /// The name of the operating system running on the device represented by the - // receiver. - public var systemName: String { - var szBuffer: [WCHAR] = Array(repeating: 0, count: 64) - while true { - var cbData: DWORD = DWORD(szBuffer.count * MemoryLayout.size) - let lStatus: LSTATUS = - RegGetValueW(HKEY_LOCAL_MACHINE, - "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion".wide, - "ProductName".wide, - DWORD(RRF_RT_REG_SZ | RRF_ZEROONFAILURE), - nil, &szBuffer, &cbData) - if lStatus == ERROR_MORE_DATA { - szBuffer = Array(repeating: 0, count: szBuffer.count * 2) - continue - } - guard lStatus == 0 else { - log.warning("RegGetValueW: \(lStatus)") - return "" - } - return String(decodingCString: szBuffer, as: UTF16.self) - } - } - - /// The current version of the operating system. - public var systemVersion: String { - var szBuffer: [WCHAR] = Array(repeating: 0, count: 64) - while true { - var cbData: DWORD = DWORD(szBuffer.count * MemoryLayout.size) - let lStatus: LSTATUS = - RegGetValueW(HKEY_LOCAL_MACHINE, - "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion".wide, - "CurrentBuildNumber".wide, - DWORD(RRF_RT_REG_SZ | RRF_ZEROONFAILURE), - nil, &szBuffer, &cbData) - if lStatus == ERROR_MORE_DATA { - szBuffer = Array(repeating: 0, count: szBuffer.count * 2) - continue - } - guard lStatus == 0 else { - log.warning("RegGetValueW: \(lStatus)") - return "" - } - return String(decodingCString: szBuffer, as: UTF16.self) - } - } - - /// The model of the device. - public var model: String { - fatalError("\(#function) not implemented") - } - - public var localizedModel: String { - fatalError("\(#function) not implemented") - } - - /// The style of interface to use on the current device. - public var userInterfaceIdiom: UserInterfaceIdiom { - return .unspecified - } - - /// An alphanumeric string that uniquely identifies a device to the - /// application vendor. - public var identifierForVendor: UUID? { - // TODO(compnerd) should be Windows.System.Profile.GetSystemIdForPublisher() - return nil - } - - /// Tracking the Device Orientation - public var orientation: Device.Orientation { - var dmDeviceMode: DEVMODEW = DEVMODEW() - dmDeviceMode.dmSize = WORD(MemoryLayout.size) - dmDeviceMode.dmDriverExtra = 0 - if !EnumDisplaySettingsExW(nil, ENUM_CURRENT_SETTINGS, &dmDeviceMode, 0) { - log.warning("EnumDisplaySettingsExW: \(Error(win32: GetLastError()))") - return .unknown - } - - let dwRequiredFields: DWORD = - DWORD(DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYORIENTATION) - guard dmDeviceMode.dmFields & dwRequiredFields == dwRequiredFields else { - return .unknown - } - - switch dmDeviceMode.dmDisplayOrientation { - case DWORD(DMDO_90), DWORD(DMDO_270): - swap(&dmDeviceMode.dmPelsHeight, &dmDeviceMode.dmPelsWidth) - case DWORD(DMDO_DEFAULT), DWORD(DMDO_180): - break - default: - log.error("unknown display orientation: \(dmDeviceMode.dmDisplayOrientation)") - return .unknown - } - - let bPortrait: Bool = dmDeviceMode.dmPelsWidth < dmDeviceMode.dmPelsHeight - switch dmDeviceMode.dmDisplayOrientation { - case DWORD(DMDO_DEFAULT): - return bPortrait ? .portrait : .landscapeLeft - case DWORD(DMDO_90): - return bPortrait ? .landscapeRight : .portrait - case DWORD(DMDO_180): - return bPortrait ? .portraitUpsideDown : .landscapeRight - case DWORD(DMDO_270): - return bPortrait ? .landscapeLeft : .portraitUpsideDown - default: - return .unknown - } - } - - public private(set) var isGeneratingDeviceOrientationNotifications: Bool = - false - - public func beginGeneratingDeviceOrientationNotifications() { - // TODO(compnerd) implement this - } - - public func endGeneratingDeviceOrientationNotifications() { - // TODO(compnerd) implement this - } - - /// Determining the Current Orientation - public var isPortrait: Bool { - switch self.orientation { - case .portrait, .portraitUpsideDown: return true - default: return false - } - } - - public var isLandscape: Bool { - switch self.orientation { - case .landscapeLeft, .landscapeRight: return true - default: return false - } - } - - public var isValidIntefaceOrientation: Bool { - true - } - - /// Getting the Device Battery State - public var batteryLevel: Float { - guard Device.current.isBatteryMonitoringEnabled else { return -1.0 } - - var status: SYSTEM_POWER_STATUS = SYSTEM_POWER_STATUS() - guard GetSystemPowerStatus(&status) else { - log.warning("GetSystemPowerStatus: \(Error(win32: GetLastError()))") - return -1.0 - } - - if status.BatteryLifePercent == 255 { return -1.0 } - return Float(status.BatteryLifePercent) / 100.0 - } - - private var batteryMonitor: BatteryMonitor? - public var isBatteryMonitoringEnabled: Bool = false { - didSet { - self.batteryMonitor = - self.isBatteryMonitoringEnabled - ? (self.batteryMonitor ?? BatteryMonitor()) - : nil - } - } - - public var batteryState: Device.BatteryState { - guard Device.current.isBatteryMonitoringEnabled else { return .unknown } - - var status: SYSTEM_POWER_STATUS = SYSTEM_POWER_STATUS() - guard GetSystemPowerStatus(&status) else { - log.warning("GetSystemPowerStatus: \(Error(win32: GetLastError()))") - return .unknown - } - - // If the system does not have a battery (e.g. desktop system), present as - // `unknown`. - guard status.BatteryFlag & BYTE(BATTERY_FLAG_NO_BATTERY) == 0 else { - return .unknown - } - - // If AC power is offline, we are unplugged. - if status.ACLineStatus & BYTE(AC_LINE_OFFLINE) == BYTE(AC_LINE_OFFLINE) { - return .unplugged - } - - // Either we are `charging` or the battery is `full`. - return status.BatteryFlag & BYTE(BATTERY_FLAG_CHARGING) == BYTE(BATTERY_FLAG_CHARGING) - ? .charging - : .full - } -} - -extension Device { - public enum BatteryState: Int { - case unknown - case unplugged - case charging - case full - } -} - -extension Device { - public enum Orientation: Int { - case unknown - case portrait - case portraitUpsideDown - case landscapeLeft - case landscapeRight - case faceUp - case faceDown - } -} - -extension Device { - public static var batteryLevelDidChangeNotification: NSNotification.Name { - NSNotification.Name(rawValue: "UIDeviceBatteryLevelDidChangeNotification") - } - - public static var batteryStateDidChangeNotification: NSNotification.Name { - NSNotification.Name(rawValue: "UIDeviceBatteryStateDidChangeNotification") - } - - public static var orientationDidChangeNotification: NSNotification.Name { - NSNotification.Name(rawValue: "UIDeviceOrientationDidChangeNotification") - } - - public static var proximityStateDidChangeNotification: NSNotification.Name { - NSNotification.Name(rawValue: "UIDeviceProximityStateDidChangeNotification") - } -} diff --git a/Sources/SwiftWin32/App and Environment/Scenes/Scene.swift b/Sources/SwiftWin32/App and Environment/Scenes/Scene.swift deleted file mode 100644 index 05259171..00000000 --- a/Sources/SwiftWin32/App and Environment/Scenes/Scene.swift +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import WinSDK -import class Foundation.NSNotification - -extension Scene { - public class ConnectionOptions { - } -} - -public class Scene: Responder { - /// Creating a Scene Object - - /// Creates a scene object using the specified session and connection - /// information. - public required init(session: SceneSession, - connectionOptions: Scene.ConnectionOptions) { - self.session = session - } - - /// Managing the Life Cycle of a Scene - - /// The object you use to recieve life-cycle events associated with the scene. - public var delegate: SceneDelegate? - - /// Getting the Scene's Session - - /// The session associated with the scene. - public let session: SceneSession -} - -extension Scene { - /// A notification indicating that a scene was added to the application. - public class var willConnectNotification: NSNotification.Name { - NSNotification.Name(rawValue: "UISceneWillConnectNotification") - } - - /// A notification indicating that a scene was removed from the application. - public class var didDisconnectNotification: NSNotification.Name { - NSNotification.Name(rawValue: "UISceneDidDisconnectNotification") - } - - /// A notification indicating that a scene is about to begin running in the - /// foreground and become visible to the user. - public class var willEnterForegroundNotification: NSNotification.Name { - NSNotification.Name(rawValue: "UISceneWillEnterForegroundNotification") - } - - /// A notification indicating that the scene is now onscreen and reponding to - /// user events. - public class var didActivateNotification: NSNotification.Name { - NSNotification.Name(rawValue: "UISceneDidActivateNotification") - } - - /// A notification indicating that the scene is about to resign the active - /// state and stop responding to user events. - public class var willDeactivateNotification: NSNotification.Name { - NSNotification.Name(rawValue: "UISceneWillDeactivateNotification") - } - - /// A notification indicating that the scene is running in the background and - /// is no longer onscreen. - public class var didEnterBackgroundNotification: NSNotification.Name { - NSNotification.Name(rawValue: "UISceneDidEnterBackgroundNotification") - } -} - -extension Scene: Hashable { - public static func == (lhs: Scene, rhs: Scene) -> Bool { - // TODO(compnerd) figure out the proper equality check for Scene - return lhs === rhs - } - - public func hash(into hasher: inout Hasher) { - // TODO(compnerd) figure out the proper hashing for Scene - } -} diff --git a/Sources/SwiftWin32/App and Environment/Scenes/SceneConfiguration.swift b/Sources/SwiftWin32/App and Environment/Scenes/SceneConfiguration.swift deleted file mode 100644 index 29ab34a0..00000000 --- a/Sources/SwiftWin32/App and Environment/Scenes/SceneConfiguration.swift +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import func Foundation.NSClassFromString - -public class SceneConfiguration { - /// Creating a Configuration Object - - /// Creates a scene-configuration object with the specified role and - /// application-specific name. - public init(name: String?, sessionRole: SceneSession.Role) { - self.name = name - self.role = sessionRole - - // Try to load the configuration from the Info.plist ... - - // ... which requires that we have an Info.plist - guard let info = Application.shared.information else { - return - } - - // ... which requires that the Info.plist contains scene configuration - guard let configurations = - info.scene?.configurations?[sessionRole.rawValue] else { - return - } - - // ... taking the configuration which matches the name or the first entry - guard let scene = name == nil - ? configurations.first - : configurations.filter({ $0.name == name }).first else { - return - } - // ... overwriting the scene name to the current configuration's scene name - self.name = scene.name - - // ... deserialising the scene class if one was provided - if let sceneClass = scene.class { - self.sceneClass = NSClassFromString(sceneClass) - } - - // .. deserialising the delegate class if one was provided - if let delegateClass = scene.delegate { - self.delegateClass = NSClassFromString(delegateClass) - } - } - - /// Specifying the Scene Creation Details - - /// The class of the scene object you want to create. - public var sceneClass: AnyClass? - - /// The class of the delegate object you want to create. - public var delegateClass: AnyClass? - - /// Getting the Configuration Attributes - - /// The application-specific name assigned to the scene configuration. - public private(set) var name: String? - - /// The role assigned to the scene configuration. - public let role: SceneSession.Role -} - -extension SceneConfiguration: Hashable { - public static func == (lhs: SceneConfiguration, rhs: SceneConfiguration) - -> Bool { - return lhs.name == rhs.name && lhs.role == rhs.role - } - - public func hash(into hasher: inout Hasher) { - hasher.combine(self.name) - hasher.combine(self.role) - } -} diff --git a/Sources/SwiftWin32/App and Environment/Scenes/SceneDelegate.swift b/Sources/SwiftWin32/App and Environment/Scenes/SceneDelegate.swift deleted file mode 100644 index 018055b1..00000000 --- a/Sources/SwiftWin32/App and Environment/Scenes/SceneDelegate.swift +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import WinSDK - -public protocol SceneDelegate: _TriviallyConstructible { - // MARK - Connecting and Disconnecting the Scene - - /// Informs the delegate about the addition of a scene to the application. - func scene(_ scene: Scene, willConnectTo: SceneSession, - options: Scene.ConnectionOptions) - - /// Informs the delegate that a scene was removed from the application. - func sceneDidDisconnect(_ scene: Scene) - - // MARK - Transitioning to the Foreground - - /// Informs the delegate that the scene is about to begin running in the - /// foreground and become visible to the user. - func sceneWillEnterForeground(_ scene: Scene) - - /// Informs the delegate that the scene became active and is now responding to - /// user events. - func sceneDidBecomeActive(_ scene: Scene) - - // MARK - Transitioning to the Background - - /// Informs the delegate that the scene is about to resign the active state - /// and stop responding to user events. - func sceneWillResignActive(_ scene: Scene) - - /// Informs the delegate that the scene is running in the background and is no - /// longer onscreen. - func sceneDidEnterBackground(_ scene: Scene) -} - -extension SceneDelegate { - public func scene(_ scene: Scene, willConnectTo: SceneSession, - options: Scene.ConnectionOptions) { - } - - public func sceneDidDisconnect(_ scene: Scene) { - } -} - -extension SceneDelegate { - public func sceneWillEnterForeground(_ scene: Scene) { - } - - public func sceneDidBecomeActive(_ scene: Scene) { - } -} - -extension SceneDelegate { - public func sceneWillResignActive(_ scene: Scene) { - } - - public func sceneDidEnterBackground(_ scene: Scene) { - } -} diff --git a/Sources/SwiftWin32/App and Environment/Scenes/SceneSession.swift b/Sources/SwiftWin32/App and Environment/Scenes/SceneSession.swift deleted file mode 100644 index bd9a1cef..00000000 --- a/Sources/SwiftWin32/App and Environment/Scenes/SceneSession.swift +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -extension SceneSession { - /// Constants that indicate the possible roles for a scene. - public struct Role: Equatable, Hashable, RawRepresentable { - public typealias RawValue = String - - public let rawValue: RawValue - - public init(rawValue: RawValue) { - self.rawValue = rawValue - } - } -} - -extension SceneSession.Role { - /// The scene displays noninteractive windows on an externally connected - /// screen. - public static var windowApplication: SceneSession.Role { - SceneSession.Role(rawValue: "UIWindowSceneSessionRoleApplication") - } - - /// The scene displays interactive content on the device's main screen. - public static var windowExternalDisplay: SceneSession.Role { - SceneSession.Role(rawValue: "UIWindowSceneSessionRoleExternalDisplay") - } -} - -public class SceneSession { - // MARK - Getting the Scene Information - - /// The scene associated with the current session. - public internal(set) weak var scene: Scene? - - /// The role played by the scene's content. - public let role: SceneSession.Role - - // MARK - Getting the Scene Configuration Details - - /// The configuration data for creating the secene. - // This is mutable as the configuration is only finalized after the deleate - // has formed the final configuration. - public internal(set) var configuration: SceneConfiguration - - // MARK - Identifying the Scene - - /// A unique identifier that persists for the lifetime of the session - public let persistentIdentifier: String - - internal init(identifier: String, role: SceneSession.Role, - configuration name: String? = nil) { - self.persistentIdentifier = identifier - self.role = role - self.configuration = SceneConfiguration(name: name, sessionRole: role) - } -} - -extension SceneSession: Hashable { - public static func == (lhs: SceneSession, rhs: SceneSession) -> Bool { - return lhs.persistentIdentifier == rhs.persistentIdentifier - } - - public func hash(into hasher: inout Hasher) { - hasher.combine(self.persistentIdentifier) - } -} diff --git a/Sources/SwiftWin32/App and Environment/Scenes/WindowScene.swift b/Sources/SwiftWin32/App and Environment/Scenes/WindowScene.swift deleted file mode 100644 index 63884cd0..00000000 --- a/Sources/SwiftWin32/App and Environment/Scenes/WindowScene.swift +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -public class WindowScene: Scene { - public required init(session: SceneSession, - connectionOptions: Scene.ConnectionOptions) { - // TODO(compnerd) we really should base this on the device properties. - // Windows Phone should have set the sizeRestrictions to nil. Similarly, - // Surface Neo and Surface Duo Devices will not permit the window resizing. - self.sizeRestrictions = SceneSizeRestrictions() - - // FIXME(compnerd) how do you attach a different screen to the window scene? - self.screen = Screen.main - - super.init(session: session, connectionOptions: connectionOptions) - } - - /// Getting the Active Windows - - /// The windows associated with the scene. - public internal(set) var windows: [Window] = [] - - /// The screen that displays the content of the scene. - public private(set) var screen: Screen - - /// Getting the Interface Attributes - - /// The minimum and maximum size of the application's windows. - public private(set) var sizeRestrictions: SceneSizeRestrictions? -} diff --git a/Sources/SwiftWin32/App and Environment/Scenes/WindowSceneDelegate.swift b/Sources/SwiftWin32/App and Environment/Scenes/WindowSceneDelegate.swift deleted file mode 100644 index 36c8420b..00000000 --- a/Sources/SwiftWin32/App and Environment/Scenes/WindowSceneDelegate.swift +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -/// Additional methods that you can use to manage application specific tasks -/// occurring in a scene. -public protocol WindowSceneDelegate: SceneDelegate { - // MARK - Managing the Scene's Main Window - - /// The main window associated with the scene. - var window: Window? { get set } - - // MARK - Responding to Scene Changes - - /// Notifies you when the size, orientation, or traits of a scene change. - func windowScene(_ windowScene: WindowScene, - didUpdate previousCoordinateSpace: CoordinateSpace, - interfaceOrientation previousInterfaceOrientation: InterfaceOrientation, - traitCollection previousTraitCollection: TraitCollection) -} - -extension WindowSceneDelegate { - public var window: Window? { - get { return nil } - set { } - } -} - -extension WindowSceneDelegate { - public func windowScene(_ windowScene: WindowScene, - didUpdate previousCoordinateSpace: CoordinateSpace, - interfaceOrientation previousInterfaceOrientation: InterfaceOrientation, - traitCollection previousTraitCollection: TraitCollection) { - } -} diff --git a/Sources/SwiftWin32/App and Environment/TraitCollection.swift b/Sources/SwiftWin32/App and Environment/TraitCollection.swift deleted file mode 100644 index e5af045d..00000000 --- a/Sources/SwiftWin32/App and Environment/TraitCollection.swift +++ /dev/null @@ -1,549 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import WinSDK - -/// Constants that indicate the size class of a view. -public enum UserInterfaceSizeClass: Int { - /// Indicates the size class has not been specified. - case unspecified - - /// Indicates a compact size class. - case compact - - /// Indicates a regular size class. - case regular -} - -/// Constants that indicate the gamut of the current display. -public enum DisplayGamut: Int { - /// An unspecified gamut value. - case unspecified - - /// The sRGB display gamut. - case SRGB - - /// The P3 display gamut. - case P3 -} - -/// Constants that indicate the interface style for the application. -public enum UserInterfaceStyle: Int { - /// An unspecified interface style. - case unspecified - - /// The light interface style. - case light - - /// The dark interface style. - case dark -} - -/// Constants that indicate whether the user interface has an active appearance. -public enum UserInterfaceActiveAppearance: Int { - /// The interface has an unspecified appearance. - case unspecified = -1 - - /// The interface has an inactive appearance. - case inactive - - /// The interface has an active appearance. - case active -} - -/// Constants that indicate the interface type for the device or an object that -/// has a trait environment, such as a view and view controller. -public enum UserInterfaceIdiom: Int { - /// An unspecified idiom. - case unspecified = -1 - - /// An interface designed for a phone. - case phone - - @available(*, deprecated, renamed: "UserInterfaceIdiom.tablet") - case pad - - /// An interface designed for a TV. - case tv - - @available(*, deprecated, message: "Use UserInterfaceIdiom.car") - case carPlay - - @available(*, deprecated, renamed: "UserInterfaceIdiom.desktop") - case mac - - /// An interface designed for a tablet. - case tablet - - /// An interface designed for a car display. - case car - - /// An interface designed for a desktop or laptop. - case desktop - - /// An interface designed for a AR/VR device. - case headset -} - -/// Constants that indicate the visual level for content in the window. -public enum UserInterfaceLevel: Int { - /// An unspecified interface level. - /// - /// Choose this option when you want to follow the inherited level. - case unspecified = -1 - - /// The level for your window's main content. - case base - - /// The level for content visually above your window's main content. - case elevated -} - -/// Constants that indicate the layout direction associated with the current -/// environment. -public enum TraitEnvironmentLayoutDirection: Int { - /// An unknown layout direction. - case unspecified = -1 - - /// A left-to-right layout direction. - case leftToRight - - /// A right-to-left layout direction. - case rightToLeft -} - -/// Constants that indicate the accessibility contrast setting. -public enum AccessibilityContrast: Int { - /// An unspecified contrast. - case unspecified = -1 - - /// A normal contrast level. - case normal - - /// A high contrast level. - case high -} - -/// The font weight to apply to text. -/// -/// The legibility weight reflects the value of the Bold Text display setting. -public enum LegibilityWeight: Int { - /// An unspecified text weight. - case unspecified = -1 - - /// A regular font weight. - case regular - - /// A bold font weight. - case bold -} - -/// Keys that indicate the availability of 3D Touch on a device. -public enum ForceTouchCapability: Int { - /// The availability of 3D Touch is unknown. - /// - /// A view has this trait after you create it but before you add it your - /// application's view hierarchy. - case unspecified - - /// 3D Touch is available on the device. - case available - - /// 3D Touch is not available on the device. - case unavailable -} - -private func GetCurrentColorScheme() -> UserInterfaceStyle { - var dwAppsUseLightTheme: DWORD = 1 - var cbAppsUseLightTheme: DWORD = - DWORD(MemoryLayout.size(ofValue: dwAppsUseLightTheme)) - - // TODO: query the `RequestedTheme` property of the `Application` from the - // manifest - - let lStatus: LSTATUS = - RegGetValueW(HKEY_CURRENT_USER, - "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize".wide, - "AppsUseLightTheme".wide, - DWORD(RRF_RT_REG_DWORD), nil, - &dwAppsUseLightTheme, &cbAppsUseLightTheme) - guard lStatus == S_OK else { - log.error("RegGetValueW: \(lStatus)") - return .unspecified - } - return dwAppsUseLightTheme == 0 ? .dark : .light -} - -private func GetCurrentDeviceFamily() -> UserInterfaceIdiom { - return GetSystemMetrics(SM_TABLETPC) == 0 ? .unspecified : .tablet -} - -private func GetCurrentAccessibilityContrast() -> AccessibilityContrast { - var hcContrast: HIGHCONTRASTW = HIGHCONTRASTW() - hcContrast.cbSize = UINT(MemoryLayout.size) - if !SystemParametersInfoW(UINT(SPI_GETHIGHCONTRAST), 0, &hcContrast, 0) { - log.error("SystemParametersInfoW: \(Error(win32: GetLastError()))") - return .unspecified - } - return Int32(hcContrast.dwFlags) & HCF_HIGHCONTRASTON == HCF_HIGHCONTRASTON - ? .high : .normal -} - -private func GetCurrentLayoutDirection() -> TraitEnvironmentLayoutDirection { - var dwDefaultLayout: DWORD = 0 - if !GetProcessDefaultLayout(&dwDefaultLayout) { - log.error("GetProcessDefaultLayout: \(Error(win32: GetLastError()))") - return .unspecified - } - return dwDefaultLayout == LAYOUT_RTL ? .rightToLeft : .leftToRight -} - -private func GetCurrentDisplayScale() -> Double { - let hMonitor: HMONITOR = - MonitorFromWindow(GetDesktopWindow(), DWORD(MONITOR_DEFAULTTOPRIMARY)) - var dsfDeviceScaleFactor: DEVICE_SCALE_FACTOR = SCALE_100_PERCENT - let hr: HRESULT = GetScaleFactorForMonitor(hMonitor, &dsfDeviceScaleFactor) - guard hr == S_OK else { - log.warning("GetScaleFactorFromMonitor: \(String(hr, radix: 16))") - return 0.0 - } - return dsfDeviceScaleFactor.factor -} - -private func GetCurrentDisplayGamut() -> DisplayGamut { - // TODO(compnerd) identify the actual display gamut in use for the primary - // display. sRGB is still far more common than DCI-P3, so assume that for - // now. Note that in reality, its more likely that the display is using - // wsRGB, which is a Windows "optimized" sRGB color gamut. - return .SRGB -} - -public class TraitCollection { - /// Creates an empty trait collection. - internal init() { - } - - // MARK - Creating a Trait Collection - - /// Creates a trait collection that consists of traits merged from a specified - /// array of trait collections. - /// - /// This method takes an array of one or more trait collections and merges - /// them to create a new trait collection. If the array contains more than one - /// element, the highest-indexed element that contains a given trait is used - /// for that trait. For example, the following code snippet creates a trait - /// collection with a compact horizontal size class, because the second - /// element in the array overrides the first for that trait: - /// - /// ```swift - /// let collection1: TraitCollection = TraitCollection(horizontalSizeClass: .regular) - /// let collection2: TraitCollection = TraitCollection(horizontalSizeClass: .compact) - /// let collection3: TraitCollection = TraitCollection(traitsFrom: [collection1, collection2]) - /// ``` - public init(traitsFrom traits: [TraitCollection]) { - _ = traits.map { - if $0.horizontalSizeClass != .unspecified { - self.horizontalSizeClass = $0.horizontalSizeClass - } - if $0.verticalSizeClass != .unspecified { - self.verticalSizeClass = $0.verticalSizeClass - } - if $0.displayScale != 0.0 { - self.displayScale = $0.displayScale - } - if $0.displayGamut != .unspecified { - self.displayGamut = $0.displayGamut - } - if $0.userInterfaceStyle != .unspecified { - self.userInterfaceStyle = $0.userInterfaceStyle - } - if $0.userInterfaceIdiom != .unspecified { - self.userInterfaceIdiom = $0.userInterfaceIdiom - } - if $0.userInterfaceLevel != .unspecified { - self.userInterfaceLevel = $0.userInterfaceLevel - } - if $0.layoutDirection != .unspecified { - self.layoutDirection = $0.layoutDirection - } - if $0.accessibilityContrast != .unspecified { - self.accessibilityContrast = $0.accessibilityContrast - } - if $0.legibilityWeight != .unspecified { - self.legibilityWeight = $0.legibilityWeight - } - if $0.activeAppearance != .unspecified { - self.activeAppearance = $0.activeAppearance - } - if $0.forceTouchCapability != .unspecified { - self.forceTouchCapability = $0.forceTouchCapability - } - if $0.preferredContentSizeCategory != .unspecified { - self.preferredContentSizeCategory = $0.preferredContentSizeCategory - } - } - } - - /// Creates a trait collection that contains only a specified interface idiom. - public init(userInterfaceIdiom: UserInterfaceIdiom) { - self.userInterfaceIdiom = userInterfaceIdiom - } - - /// Creates a trait collection that contains only a specified horizontal size - /// class. - public init(horizontalSizeClass: UserInterfaceSizeClass) { - self.horizontalSizeClass = horizontalSizeClass - } - - /// Creates a trait collection that contains only a specified vertical size - /// class. - public init(verticalSizeClass: UserInterfaceSizeClass) { - self.verticalSizeClass = verticalSizeClass - } - - /// Creates a trait collection that contains only the specified user interface - /// style trait. - public init(userInterfaceStyle: UserInterfaceStyle) { - self.userInterfaceStyle = userInterfaceStyle - } - - /// Creates a trait collection that contains only the specified accessibility - /// contrast trait. - public init(accessibilityContrast: AccessibilityContrast) { - self.accessibilityContrast = accessibilityContrast - } - - /// Creates a trait collection that contains only the specified user interface - /// level trait. - public init(userInterfaceLevel: UserInterfaceLevel) { - self.userInterfaceLevel = userInterfaceLevel - } - - /// Creates a trait collection that contains only the specified legibility - /// weight trait. - public init(legibilityWeight: LegibilityWeight) { - self.legibilityWeight = legibilityWeight - } - - /// Creates a trait collection that contains only a specified force touch - /// capability trait. - public init(forceTouchCapability: ForceTouchCapability) { - self.forceTouchCapability = forceTouchCapability - } - - /// Creates a trait collection that contains only a specified display scale. - public init(displayScale: Double) { - self.displayScale = displayScale - } - - /// Creates a trait collection that contains only the specified display gamut - /// trait. - public init(displayGamut: DisplayGamut) { - self.displayGamut = displayGamut - } - - /// Creates a trait collection that contains only the specified layout - /// direction trait. - public init(layoutDirection: TraitEnvironmentLayoutDirection) { - self.layoutDirection = layoutDirection - } - - /// Creates a trait collection that contains only the specified content size - /// category trait. - public init(preferredContentSizeCategory: ContentSizeCategory) { - self.preferredContentSizeCategory = preferredContentSizeCategory - } - - /// Creates a trait collection that contains only the specified active - /// appearance trait. - public init(activeAppearance: UserInterfaceActiveAppearance) { - self.activeAppearance = activeAppearance - } - - // MARK - Getting the Current Traits - - // TODO(compnerd) The framework stores the value for this property as a - // thread-local variable, so access to it is fast. - - /// The complete set of traits for the current environment. - /// - /// The framework updates the value of this property before calling several - /// well-known methods of `View`, `ViewController`, and - /// `PresentationController`. The trait collection contains a complete set of - /// trait values describing the current environment, and does not include - /// unspecified or unknown values. - /// - /// Changing the traits on a nonmain thread does not affect the current traits - /// on your applications's main thread. - public private(set) static var current: TraitCollection = - TraitCollection(traitsFrom: [ - TraitCollection(accessibilityContrast: GetCurrentAccessibilityContrast()), - TraitCollection(displayGamut: GetCurrentDisplayGamut()), - TraitCollection(displayScale: GetCurrentDisplayScale()), - TraitCollection(layoutDirection: GetCurrentLayoutDirection()), - TraitCollection(preferredContentSizeCategory: .large), - TraitCollection(userInterfaceIdiom: GetCurrentDeviceFamily()), - TraitCollection(userInterfaceLevel: .base), - TraitCollection(userInterfaceStyle: GetCurrentColorScheme()), - - TraitCollection(horizontalSizeClass: Device.current.isPortrait - ? .compact - : .regular), - TraitCollection(verticalSizeClass: Device.current.isPortrait - ? .regular - : .compact), - ]) - - // MARK - Retriving Size Class Traits - - /// The horizontal size class of the trait collection. - public private(set) var horizontalSizeClass: UserInterfaceSizeClass = - .unspecified - - /// The vertical size class of the trait collection. - public private(set) var verticalSizeClass: UserInterfaceSizeClass = - .unspecified - - // MARK -Retriving Display-Related Traits - - /// The display scale of the trait collection. - /// - /// A value of 1.0 indicates a non-Retina display and a value of 2.0 indicates - /// a Retina display. The default display scale for a trait collection is 0.0 - /// (indicating unspecified). - public private(set) var displayScale: Double = 0.0 - - /// The gamut of the current display. - public private(set) var displayGamut: DisplayGamut = .unspecified - - // MARK - Retriving Interface-Related Traits - - /// The style associated with the user interface. - /// - /// Use this trait to determine whether your interface should be configured - /// with a dark or light appearance. The default value of this trait is set to - /// the corresponding appearance setting on the user's device. - public private(set) var userInterfaceStyle: UserInterfaceStyle = .unspecified - - /// The user interface idiom of the trait collection. - /// - /// The default user interface idiom for a trait collection is - /// `UserInterfaceIdiom.unspecified`. - public private(set) var userInterfaceIdiom: UserInterfaceIdiom = .unspecified - - /// The elevation level of the interface. - /// - /// Levels create a visual separation between different parts of your UI. - /// `Window` content typically appears at the `UserInterfaceLevel.base` level. - /// When you want parts of your UI to stand out from the underlying - /// background, assign the `UserInterfaceLevel.elevated` level to them. For - /// example, the system assigns the `UserInterfaceLevel.elevated` level to - /// alerts and popovers. - public private(set) var userInterfaceLevel: UserInterfaceLevel = .unspecified - - /// The layout direction associated with the current environment. - /// - /// Use this trait to determine whether the underlying environment uses a - /// left-to-right or right-to-left orientation. - public private(set) var layoutDirection: TraitEnvironmentLayoutDirection = - .unspecified - - /// The accessibility contrast associated with the current environment. - /// - /// Use this trait to determine whether the user requested a high contrast - /// between foreground and background content. The user sets the contrast - /// level in Accessibility Settings. - public private(set) var accessibilityContrast: AccessibilityContrast = - .unspecified - - /// The font weight to apply to text. - /// - /// The legibility weight reflects the value of the Bold Text display setting. - public private(set) var legibilityWeight: LegibilityWeight = .unspecified - - /// A property that indicates whether the user interface has an active - /// appearance. - /// - /// The active appearance varies according to window activation state. - public private(set) var activeAppearance: UserInterfaceActiveAppearance = - .unspecified - - // MARK - Retriving the Force Touch Capability - - /// The force touch capability value of the trait collection. - /// - /// Force Touch is available only on certain devices. On those devices, - /// availability is determined by the user's associated accessibility setting - /// in Settings. Check this property's value on app launch, and in your - /// implementation of the `traitCollectionDidChange(_:)` method. - /// - /// If this property does not contain a value, the meaning is equivalent to - /// the value `ForceTouchCapability.unknown`. - public private(set) var forceTouchCapability: ForceTouchCapability = - .unspecified - - // MARK - Retriving Content Size Category Information - - /// The font sizing option preferred by the user. - /// - /// With dynamic text sizing, users can ask that apps display text using fonts - /// that are larger or smaller than the normal font size defined by the - /// system. For example, a user with a visual impairment might request a - /// larger default font size to make it easier to read text. Use the value of - /// this property to request a `Font` object that matches the user's requested - /// size. - public private(set) var preferredContentSizeCategory: ContentSizeCategory = - .unspecified - - // MARK - Comparing Trait Collections - - /// Queries whether a trait collection contains all of another trait - /// collection's values. - /// - /// Use this method to compare two standalone trait collections, or to compare - /// the interface environment's trait collection to a standalone trait - /// collection. - public func containsTraits(in trait: TraitCollection?) -> Bool { - fatalError("\(#function) not yet implemented") - } - - /// Queries whether changing between the specified and current trait - /// collections would affect color values. - /// - /// Use this method to determine whether changing the traits of the current - /// environment would also change the colors in your interface. For example, - /// changing the `userInterfaceStyle` or `accessibilityContrast` property - /// usually changes the colors of your interface. - public func hasDifferentColorAppearance(comparedTo traitCollection: TraitCollection?) - -> Bool { - fatalError("\(#function) not yet implemented") - } - - - // MARK - Getting an Image Configuration Object - - /// An image configuration object compatible with this trait collection. - /// - /// The `Image.Configuration` object in this property contains the same traits - /// as the current trait collection. - public var imageConfiguration: Image.Configuration { - fatalError("\(#function) not yet implemented") - } - - // MARK - Performing Actions with the Current Traits - - /// Executes custom code using the traits of the current trait collection. - /// - /// Use this method when you want to execute code using a set of traits that - /// differ from those in the current trait environment. For example, you might - /// use this method to draw part of a view's content with a different set of - /// traits. This method temporarily replaces the traits of the current - /// environment with the ones found in the current `TraitCollection`. After - /// the actions block finishes, the method restores the original traits to the - /// environment. - /// - /// You can call this method from any thread of your application. - public func performAsCurrent(_ actions: () -> Void) { - fatalError("\(#function) not yet implemented") - } -} diff --git a/Sources/SwiftWin32/App and Environment/TraitEnvironment.swift b/Sources/SwiftWin32/App and Environment/TraitEnvironment.swift deleted file mode 100644 index a259e493..00000000 --- a/Sources/SwiftWin32/App and Environment/TraitEnvironment.swift +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -/// A set of methods that makes the interface environment available to your -/// application. -public protocol TraitEnvironment { - // MARK - Accessing a Trait Collection - - /// The traits, such as the size class and scale factor, that describe the - /// current environment of the object. - var traitCollection: TraitCollection { get } - - // MARK - Responding to a Change in the Interface Environment - - /// Called when the interface environment changes. - func traitCollectionDidChange(_ previousTraitCollection: TraitCollection?) -} diff --git a/Sources/SwiftWin32/Appearance Customization/Appearance.swift b/Sources/SwiftWin32/Appearance Customization/Appearance.swift deleted file mode 100644 index e6ba4e01..00000000 --- a/Sources/SwiftWin32/Appearance Customization/Appearance.swift +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -/// A collection of methods that gives you access to the appearance proxy for a -/// class. -public protocol Appearance { - // MARK - Appearance Methods - - /// Returns the appearance proxy for the receiver. - static func appearance() -> Self - - /// Returns the appearance proxy for the receiver that has the passed trait - /// collection. - static func appearance(for trait: TraitCollection) -> Self - - /// Returns the appearance proxy for the object when it is contained in the - /// hierarchy the specified classes describe. - static func appearance(whenContainedInInstancesOf containerTypes: [AppearanceContainer.Type]) - -> Self - - /// Returns the appearance proxy for the object when it is contained in the - /// hierarchy the specified classes describe and has the specified trait - /// collection. - static func appearance(for trait: TraitCollection, - whenContainedInInstancesOf containerTypes: [AppearanceContainer.Type]) -> Self -} diff --git a/Sources/SwiftWin32/Appearance Customization/AppearanceContainer.swift b/Sources/SwiftWin32/Appearance Customization/AppearanceContainer.swift deleted file mode 100644 index 602a5c09..00000000 --- a/Sources/SwiftWin32/Appearance Customization/AppearanceContainer.swift +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -/// A protocol that a class must adopt to allow appearance customization using -/// the `Appearance` API. -public protocol AppearanceContainer { -} diff --git a/Sources/SwiftWin32/Appearance Customization/Configurations/BackgroundConfiguration.swift b/Sources/SwiftWin32/Appearance Customization/Configurations/BackgroundConfiguration.swift deleted file mode 100644 index c8f035d6..00000000 --- a/Sources/SwiftWin32/Appearance Customization/Configurations/BackgroundConfiguration.swift +++ /dev/null @@ -1,157 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -/// A configuration that describes a specific background appearance. -public struct BackgroundConfiguration { - // MARK - Creating Cell Background Configurations - - /// Creates a default configuration for a plain list cell. - public static func listPlainCell() -> BackgroundConfiguration { - fatalError("\(#function) not yet implemented") - } - - /// Creates a default configuration for a grouped list cell. - public static func listGroupedCell() -> BackgroundConfiguration { - fatalError("\(#function) not yet implemented") - } - - /// Creates a default configuration for a sidebar list cell. - public static func listSidebarCell() -> BackgroundConfiguration { - fatalError("\(#function) not yet implemented") - } - - /// Creates a default configuration for an accompanied sidebar list cell. - public static func listAccompaniedSidebarCell() -> BackgroundConfiguration { - fatalError("\(#function) not yet implemented") - } - - // MARK - Creating Header and Footer Background Configurations - - /// Creates a default configuration for a plain list header or footer. - public static func listPlainHeaderFooter() -> BackgroundConfiguration { - fatalError("\(#function) not yet implemented") - } - - /// Creates a default configuration for a grouped list header or footer. - public static func listGroupedHeaderFooter() -> BackgroundConfiguration { - fatalError("\(#function) not yet implemented") - } - - /// Creates a default configuration for a sidebar list header. - public static func listSidebarHeader() -> BackgroundConfiguration { - fatalError("\(#function) not yet implemented") - } - - // MARK - Creating an Empty Background Configuration - - /// Creates an empty background configuration with a transparent background - /// and no default styling. - public static func clear() -> BackgroundConfiguration { - fatalError("\(#function) not yet implemented") - } - - // MARK - Customizing the Background - - /// A custom view for the background. - public var customView: View? - - /// The preferred corner radius, using a continuous corner curve, for the - /// background and stroke. - public var cornerRadius: Double = 0.0 - - /// The insets (or outsets, if negative) for the background and stroke, - /// relative to the edges of the containing view. - public var backgroundInsets: DirectionalEdgeInsets = .zero - - /// The edges on which the configuration adds the containing view’s layout - /// margins to the background insets. - public var edgesAddingLayoutMarginsToBackgroundInsets: DirectionalRectEdge = - .none - - /// The color of the background. - /// - /// If the value is `nil`, the background color is the view's tint color. Use - /// `clear` for a transparent background with no color. - public var backgroundColor: Color? - - /// The color transformer for resolving the background color. - /// - /// If the value is `nil`, the configuration uses `backgroundColor` without - /// any transformations. - public var backgroundColorTransformer: ConfigurationColorTransformer? - - /// Generates the resolved background color for the specified tint color, - /// using the background color and color transformer. - public func resolvedBackgroundColor(for tintColor: Color) -> Color { - fatalError("\(#function) not yet implemented") - } - - /// The visual effect that the configuration applies to the background. - public var visualEffect: VisualEffect? - - /// The color of the stroke. - /// - /// If the value is `nil`, the stroke color is the view's tint color. Use - /// `clear` for a transparent stroke with no color. - public var strokeColor: Color? - - /// The color transformer for resolving the stroke color. - /// - /// If the value is `nil`, the configuration uses `strokeColor` without any - /// transformations. - public var strokeColorTransformer: ConfigurationColorTransformer? - - /// Generates the resolved stroke color for the specified tint color, using - /// the stroke color and color transformer. - public func resolvedStrokeColor(for tintColor: Color) -> Color { - fatalError("\(#function) not yet implemented") - } - - /// The width of the stroke. - public var strokeWidth: Double = 0.0 - - /// The outset (or inset, if negative) for the stroke. - public var strokeOutset: Double = 0.0 - - // MARK - Updating Background Configurations - - /// Generates a configuration for the specified state by applying the - /// configuration's default values for that state to any properties that you - /// haven't customized. - public func updated(for state: ConfigurationState) -> BackgroundConfiguration { - fatalError("\(#function) not yet implemented") - } -} - -// MARK - Comparing Background Configurations - -extension BackgroundConfiguration: Hashable { - public static func ==(_ lhs: BackgroundConfiguration, - _ rhs: BackgroundConfiguration) -> Bool { - fatalError("\(#function) not yet implemented") - } - - public func hash(into hasher: inout Hasher) { - fatalError("\(#function) not yet implemented") - } -} - -// MARK - Describing a Background Configuration - -extension BackgroundConfiguration: CustomStringConvertible { - public var description: String { - fatalError("\(#function) not yet implemented") - } -} - -extension BackgroundConfiguration: CustomDebugStringConvertible { - public var debugDescription: String { - fatalError("\(#function) not yet implemented") - } -} - -extension BackgroundConfiguration: CustomReflectable { - public var customMirror: Mirror { - fatalError("\(#function) not yet implemented") - } -} diff --git a/Sources/SwiftWin32/Appearance Customization/Configurations/CellConfigurationState.swift b/Sources/SwiftWin32/Appearance Customization/Configurations/CellConfigurationState.swift deleted file mode 100644 index dc74db6d..00000000 --- a/Sources/SwiftWin32/Appearance Customization/Configurations/CellConfigurationState.swift +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -/// A structure that encapsulates a cell's state. -public struct CellConfigurationState: ConfigurationState { - // MARK - Managing View Configuration States - - /// The traits that describe the current layout environment of the view, such - /// as the user interface style and layout direction. - public var traitCollection: TraitCollection - - /// A boolean value that indicates whether the cell is in a selected state. - public var isSelected: Bool = false - - /// A boolean value that indicates whether the cell is in a highlighted state. - public var isHighlighted: Bool = false - - /// A boolean value that indicates whether the cell is in a focused state. - public var isFocused: Bool = false - - /// A boolean value that indicates whether the cell is in a disabled state. - public var isDisabled: Bool = false - - /// Accesses custom states by key. - public subscript(key: ConfigurationStateCustomKey) -> AnyHashable? { - get { return nil } - set { } - } - - // MARK - Creating a Configuration State Manually - - /// Creates a cell configuration state with the specified trait collection. - public init(traitCollection: TraitCollection) { - self.traitCollection = traitCollection - } -} diff --git a/Sources/SwiftWin32/Appearance Customization/Configurations/ConfigurationColorTransformer.swift b/Sources/SwiftWin32/Appearance Customization/Configurations/ConfigurationColorTransformer.swift deleted file mode 100644 index b7e9d127..00000000 --- a/Sources/SwiftWin32/Appearance Customization/Configurations/ConfigurationColorTransformer.swift +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -/// A transformer that generates a modified output color from an input color. -public struct ConfigurationColorTransformer { - // MARK - Creating a Color Transformer - - /// Creates a color transformer with the specified closure. - public init(_ transform: @escaping (Color) -> Color) { - self.transform = transform - } - - /// Creates a color transformer that generates a grayscale version of the - /// color. - public static var grayscale: ConfigurationColorTransformer { - fatalError("\(#function) not yet implemented") - } - - /// A color transformer that returns the preferred system accent color. - public static var preferredTint: ConfigurationColorTransformer { - fatalError("\(#function) not yet implemented") - } - - /// A color transformer that returns the color with a monochrome tint. - public static var monochromeTint: ConfigurationColorTransformer { - fatalError("\(#function) not yet implemented") - } - - // MARK - Calling the Color Transformer - - /// The transform closure of the color transformer. - public private(set) var transform: (Color) -> Color - - /// Calls the transform closure of the color transformer. - public func callAsFunction(_ input: Color) -> Color { - return self.transform(input) - } -} diff --git a/Sources/SwiftWin32/Appearance Customization/Configurations/ConfigurationState.swift b/Sources/SwiftWin32/Appearance Customization/Configurations/ConfigurationState.swift deleted file mode 100644 index b92447df..00000000 --- a/Sources/SwiftWin32/Appearance Customization/Configurations/ConfigurationState.swift +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -/// The requirements for an object that encapsulate a view's state. -public protocol ConfigurationState { - // MARK - Managing Configuration States - - /// The traits that describe the current layout environment of the view, such - /// as the user interface style and layout direction. - var traitCollection: TraitCollection { get set } - - /// Accesses custom states by key. - subscript(key: ConfigurationStateCustomKey) -> AnyHashable? { get set } - - // MARK - Creating a Configuration State Manually - - /// Creates a View configuration state with the specified trait collection. - init(traitCollection: TraitCollection) -} diff --git a/Sources/SwiftWin32/Appearance Customization/Configurations/ConfigurationStateCustomKey.swift b/Sources/SwiftWin32/Appearance Customization/Configurations/ConfigurationStateCustomKey.swift deleted file mode 100644 index 1a613a62..00000000 --- a/Sources/SwiftWin32/Appearance Customization/Configurations/ConfigurationStateCustomKey.swift +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -/// A key that defines a custom state for a view. -public struct ConfigurationStateCustomKey: Equatable, Hashable, RawRepresentable { - public typealias RawValue = String - - public let rawValue: RawValue - - public init(rawValue: RawValue) { - self.rawValue = rawValue - } -} - -extension ConfigurationStateCustomKey { - public init(_ rawValue: String) { - self.rawValue = rawValue - } -} diff --git a/Sources/SwiftWin32/Appearance Customization/Configurations/ContentConfiguration.swift b/Sources/SwiftWin32/Appearance Customization/Configurations/ContentConfiguration.swift deleted file mode 100644 index 5a926121..00000000 --- a/Sources/SwiftWin32/Appearance Customization/Configurations/ContentConfiguration.swift +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -/// The requirements for an object that provides the configuration for a content -/// view. -public protocol ContentConfiguration { - // MARK - Creating a Content Configuration - - /// Creates a new instance of the content view using this configuration. - func makeContentView() -> View & ContentView - - // MARK - Updating a Content Configuration - - /// Generates a configuration for the specified state by applying the - /// configuration's default values for that state to any properties that you - /// haven't customized. - func updated(for state: ConfigurationState) -> Self -} diff --git a/Sources/SwiftWin32/Appearance Customization/Configurations/ContentView.swift b/Sources/SwiftWin32/Appearance Customization/Configurations/ContentView.swift deleted file mode 100644 index cf02ff36..00000000 --- a/Sources/SwiftWin32/Appearance Customization/Configurations/ContentView.swift +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -/// The requirements for a content view that you create using a configuration. -public protocol ContentView { - // MARK - Managing the Content Configuration - - /// The current configuration of the view. - var configuration: ContentConfiguration { get set } -} diff --git a/Sources/SwiftWin32/Appearance Customization/Configurations/ListContentConfiguration.swift b/Sources/SwiftWin32/Appearance Customization/Configurations/ListContentConfiguration.swift deleted file mode 100644 index 424b5fe9..00000000 --- a/Sources/SwiftWin32/Appearance Customization/Configurations/ListContentConfiguration.swift +++ /dev/null @@ -1,374 +0,0 @@ -// Copyright © 2019 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import class Foundation.NSAttributedString - -#if swift(>=5.7) -import CoreGraphics -#endif - -extension ListContentConfiguration { - /// Properties that affect the list content configuration's image. - public struct ImageProperties { - internal init() { - // FIXME how do we intialize the value of `cornerRadius`? - self.cornerRadius = 0.0 - } - - // MARK - Configuring Image Properties - - /// The symbol configuration to use. - public var preferredSymbolConfiguration: Image.SymbolConfiguration? - - /// The tint color to apply to the image view. - public var tintColor: Color? - - /// The color transformer for resolving the tint color. - public var tintColorTransformer: ConfigurationColorTransformer? - - /// Generates the resolved tint color for the specified tint color, using - /// the tint color and color transformer. - public func resolvedTintColor(for tintColor: Color) -> Color { - fatalError("\(#function) not yet implemented") - } - - /// The preferred corner radius, using a continuous corner curve, for the - /// image. - public var cornerRadius: Double - - /// The maximum size for the image. - public var maximumSize: Size = .zero - - /// The layout size that the system reserves for the image, and then centers - /// the image within. - public var reservedLayoutSize: Size = .zero - - /// The system standard layout dimension for reserved layout size. - public static var standardDimension: Double { - .greatestFiniteMagnitude - } - - /// A boolean value that determines whether the image inverts its colors - /// when the user turns on the Invert Colors accessibility setting. - public var accessibilityIgnoresInvertColors: Bool = false - } -} - -// MARK - Comparing Image Properties - -extension ListContentConfiguration.ImageProperties: Hashable { - public static func ==(_ lhs: ListContentConfiguration.ImageProperties, - _ rhs: ListContentConfiguration.ImageProperties) - -> Bool { - fatalError("\(#function) not yet implemented") - } - - public func hash(into hasher: inout Hasher) { - fatalError("\(#function) not yet implemented") - } -} - -// MARK - Describing Image Properties - -extension ListContentConfiguration.ImageProperties: CustomStringConvertible { - public var description: String { - fatalError("\(#function) not yet implemented") - } -} - -extension ListContentConfiguration.ImageProperties: CustomDebugStringConvertible { - public var debugDescription: String { - fatalError("\(#function) not yet implemented") - } -} - -extension ListContentConfiguration.ImageProperties: CustomReflectable { - public var customMirror: Mirror { - fatalError("\(#function) not yet implemented") - } -} - -extension ListContentConfiguration.TextProperties { - /// Constants that specify the visual alignment of the text. - public enum TextAlignment { - // MARK - Text Alignment - - /// The text has centered alignment. - case center - - /// The text has justified alignment. - case justified - - /// The text uses the default alignment that the system associates with the - /// current localization of the app. - case natural - } -} - -// MARK - Comparing Text Alignment - -extension ListContentConfiguration.TextProperties.TextAlignment: Hashable { - public static func ==(_ lhs: ListContentConfiguration.TextProperties.TextAlignment, - _ rhs: ListContentConfiguration.TextProperties.TextAlignment) - -> Bool { - fatalError("\(#function) not yet implemented") - } - - public func hash(into hasher: inout Hasher) { - fatalError("\(#function) not yet implemented") - } -} - -extension ListContentConfiguration.TextProperties { - public enum TextTransform { - // MARK - Text Transforms - - /// The text doesn't have a transform. - case none - - /// Displays the text with the first character capitalized. - case capitalized - - /// Displays the text in all lowercase characters. - case lowercase - - /// Displays the text in all uppercase characters. - case uppercase - } -} - -// MARK - Comparing Text Transforms - -extension ListContentConfiguration.TextProperties.TextTransform: Hashable { - public static func ==(_ lhs: ListContentConfiguration.TextProperties.TextTransform, - _ rhs: ListContentConfiguration.TextProperties.TextTransform) - -> Bool { - fatalError("\(#function) not yet implemented") - } - - public func hash(into hasher: inout Hasher) { - fatalError("\(#function) not yet implemented") - } -} - -extension ListContentConfiguration { - /// Properties that affect the list content configuration's text. - public struct TextProperties { - // MARK - Configuring Text Properties - - /// The font for the text. - public var font: Font - - /// The color of the text. - public var color: Color - - /// The color transformer for resolving the text color. - public var colorTransformer: ConfigurationColorTransformer? - - /// Generates the resolved color for the specified color, using the text - /// color and color transformer. - public func resolvedColor() -> Color { - fatalError("\(#function) not yet implemented") - } - - /// The alignment for the text. - public var alignment: TextProperties.TextAlignment - - /// The line break mode to use for the text. - public var lineBreakMode: LineBreakMode - - /// The maximum number of lines for the text. - public var numberOfLines: Int - - /// A boolean value that detemines whether the configuration automatically - /// adjusts the font size of the text when necessary to fit in the available - /// width. - public var adjustsFontSizeToFitWidth: Bool - - /// The smallest multiplier for the font size that the configuration uses to - /// make the text fit. - public var minimumScaleFactor: Double - - /// A boolean value that detemines whether the configuration tightens the - /// text before truncating. - public var allowsDefaultTighteningForTruncation: Bool - - /// A boolean value that detemines whether the configuration automatically - /// updates the font when the content size category changes. - public var adjustsFontForContentSizeCategory: Bool - - /// The transform to apply to the text. - public var transform: TextProperties.TextTransform - } -} - -/// A content configuration for a list-based content view. -public struct ListContentConfiguration { - // MARK - Creating Default Configurations - - /// Creates the default configuration for a list cell. - public static func cell() -> ListContentConfiguration { - fatalError("\(#function) not yet implemented") - } - - /// Creates the default configuration for a list cell with subtitle text. - public static func subtitleCell() -> ListContentConfiguration { - fatalError("\(#function) not yet implemented") - } - - /// Creates the default configuration for a list cell with side-by-side value - /// text. - public static func valueCell() -> ListContentConfiguration { - fatalError("\(#function) not yet implemented") - } - - /// Creates the default configuration for a plain list header. - public static func plainHeader() -> ListContentConfiguration { - fatalError("\(#function) not yet implemented") - } - - /// Creates the default configuration for a plain list footer. - public static func plainFooter() -> ListContentConfiguration { - fatalError("\(#function) not yet implemented") - } - - /// Creates the default configuration for a grouped list header. - public static func groupedHeader() -> ListContentConfiguration { - fatalError("\(#function) not yet implemented") - } - - /// Creates the default configuration for a grouped list footer. - public static func groupedFooter() -> ListContentConfiguration { - fatalError("\(#function) not yet implemented") - } - - /// Creates the default configuration for a sidebar list cell. - public static func sidebarCell() -> ListContentConfiguration { - fatalError("\(#function) not yet implemented") - } - - /// Creates the default configuration for a sidebar list cell with subtitle - /// text. - public static func sidebarSubtitleCell() -> ListContentConfiguration { - fatalError("\(#function) not yet implemented") - } - - /// Creates the default configuration for a sidebar list header. - public static func sidebarHeader() -> ListContentConfiguration { - fatalError("\(#function) not yet implemented") - } - - /// Creates the default configuration for an accompanied sidebar list cell. - public static func accompaniedSidebarCell() -> ListContentConfiguration { - fatalError("\(#function) not yet implemented") - } - - /// Creates the default configuration for an accompanied sidebar list cell - /// with subtitle text. - public static func accompaniedSidebarSubtitleCell() - -> ListContentConfiguration { - fatalError("\(#function) not yet implemented") - } - - // MARK - Customizing Content - - /// The image to display. - public var image: Image? - - /// The primary text. - public var text: String? - - /// An attributed variant of the primary text. - public var attributedText: NSAttributedString? - - /// The secondary text. - public var secondaryText: String? - - /// An attributed variant of the secondary text. - public var secondaryAttributedText: NSAttributedString? - - // MARK - Customizing Appearance - - /// Properties for configuring the image. - public var imageProperties: ListContentConfiguration.ImageProperties - - /// Properties for configuring the primary text. - public var textProperties: ListContentConfiguration.TextProperties - - /// Properties for configuring the secondary text. - public var secondaryTextProperties: ListContentConfiguration.TextProperties - - // MARK - Customizing Layout - - /// A boolean value that detemines whether the content view preserves the - /// layout margins that it inherits from its superview on the horizontal or - /// vertical axes. - public var axesPreservingSuperviewLayoutMargins: Axis = .both - - /// The margins between the content and the edges of the content view. - public var directionalLayoutMargins: DirectionalEdgeInsets - - /// A boolean value that detemines whether the configuration positions the - /// text and secondary text side by side. - public var prefersSideBySideTextAndSecondaryText: Bool - - /// The padding between the image and text. - public var imageToTextPadding: Double - - /// The minimum horizontal padding between the text and secondary text. - public var textToSecondaryTextHorizontalPadding: Double - - /// The vertical padding between the text and secondary text. - public var textToSecondaryTextVerticalPadding: Double -} - -extension ListContentConfiguration: ContentConfiguration { - // MARK - Creating a Content View - - /// Creates a new instance of the content view using this configuration. - public func makeContentView() -> View & ContentView { - fatalError("\(#function) not yet implemented") - } - - // MARK - Updating the Configuration - - /// Generates a configuration for the specified state by applying the - /// configuration's default values for that state to any properties that you - /// haven't customized. - public func updated(for state: ConfigurationState) -> ListContentConfiguration { - fatalError("\(#function) not yet implemented") - } -} - -// MARK - Comparing List Content Configurations - -extension ListContentConfiguration: Hashable { - public static func ==(_ lhs: ListContentConfiguration, - _ rhs: ListContentConfiguration) -> Bool { - fatalError("\(#function) not yet implemented") - } - - public func hash(into hasher: inout Hasher) { - fatalError("\(#function) not yet implemented") - } -} - -// MARK - Describing a List Content Configuration - -extension ListContentConfiguration: CustomStringConvertible { - public var description: String { - fatalError("\(#function) not yet implemented") - } -} - -extension ListContentConfiguration: CustomDebugStringConvertible { - public var debugDescription: String { - fatalError("\(#function) not yet implemented") - } -} - -extension ListContentConfiguration: CustomReflectable { - public var customMirror: Mirror { - fatalError("\(#function) not yet implemented") - } -} diff --git a/Sources/SwiftWin32/Appearance Customization/Configurations/ViewConfigurationState.swift b/Sources/SwiftWin32/Appearance Customization/Configurations/ViewConfigurationState.swift deleted file mode 100644 index 7e9c70a5..00000000 --- a/Sources/SwiftWin32/Appearance Customization/Configurations/ViewConfigurationState.swift +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -/// A structure that encapsulates a view's state. -public struct ViewConfigurationState: ConfigurationState { - // MARK - Managing View Configuration States - - /// The traits that describe the current layout environment of the view, such - /// as the user interface style and layout direction. - public var traitCollection: TraitCollection - - /// A boolean value that indicates whether the view is in a selected state. - public var isSelected: Bool - - /// A boolean value that indicates whether the view is in a highlighted state. - public var isHighlighted: Bool - - /// A boolean value that indicates whether the view is in a focused state. - public var isFocused: Bool - - /// A boolean value that indicates whether the view is in a disabled state. - public var isDisabled: Bool - - /// Accesses custom states by key. - public subscript(key: ConfigurationStateCustomKey) -> AnyHashable? { - get { fatalError("\(#function) not yet implemented") } - set { fatalError("\(#function) not yet implemented") } - } - - // MARK - Creating a Configuration State Manually - - public init(traitCollection: TraitCollection) { - self.traitCollection = traitCollection - - self.isSelected = false - self.isHighlighted = false - self.isFocused = false - self.isDisabled = false - } -} - -extension ViewConfigurationState: Hashable { - public static func ==(_ lhs: ViewConfigurationState, - _ rhs: ViewConfigurationState) -> Bool { - fatalError("\(#function) not yet implemented") - } - - public func hash(into hasher: inout Hasher) { - fatalError("\(#function) not yet implemented") - } -} - -extension ViewConfigurationState: CustomStringConvertible { - public var description: String { - fatalError("\(#function) not yet implemented") - } -} - -extension ViewConfigurationState: CustomDebugStringConvertible { - public var debugDescription: String { - fatalError("\(#function) not yet implemented") - } -} - -extension ViewConfigurationState: CustomReflectable { - public var customMirror: Mirror { - fatalError("\(#function) not yet implemented") - } -} diff --git a/Sources/SwiftWin32/Application/Information.swift b/Sources/SwiftWin32/Application/Information.swift deleted file mode 100644 index 45bcca8c..00000000 --- a/Sources/SwiftWin32/Application/Information.swift +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -extension Application { - internal struct SceneConfiguration { - let name: String? - let `class`: String? - let delegate: String? - } -} - -extension Application.SceneConfiguration: Decodable { - enum CodingKeys: String, CodingKey { - case name = "SceneConfigurationName" - case `class` = "SceneClassName" - case delegate = "SceneDelegateClassName" - } -} - -extension Application { - internal struct SceneManifest { - // Enable Multiple Windows - let supportsMultipleScenes: Bool? - // Scene Configuration - let configurations: [String:[Application.SceneConfiguration]]? - } -} - -extension Application.SceneManifest: Decodable { - enum CodingKeys: String, CodingKey { - case supportsMultipleScenes = "ApplicationSupportsMultipleScenes" - case configurations = "SceneConfigurations" - } -} - -extension Application { - internal struct Information { - let scene: Application.SceneManifest? - let principalClass: String? - } -} - -extension Application.Information: Decodable { - enum CodingKeys: String, CodingKey { - case scene = "ApplicationSceneManifest" - case principalClass = "PrincipalClass" - } -} diff --git a/Sources/SwiftWin32/Application/LaunchKeyOptions.swift b/Sources/SwiftWin32/Application/LaunchKeyOptions.swift deleted file mode 100644 index 13cd2eec..00000000 --- a/Sources/SwiftWin32/Application/LaunchKeyOptions.swift +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright © 2019 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -extension Application { - /// Keys used to access values in the launch options dictionary passed to your - /// application at initialization time. - public struct LaunchOptionsKey: Equatable, Hashable, RawRepresentable { - public typealias RawValue = String - - public var rawValue: RawValue - - public init(rawValue: RawValue) { - self.rawValue = rawValue - } - } -} - -extension Application.LaunchOptionsKey { - /// A key indicating that the URL passed to your application contains custom - /// annotation data from the source application. - public static var annotation: Application.LaunchOptionsKey { - Application.LaunchOptionsKey(rawValue: "Application.Annotation") - } - - /// A key indicating that the application was relaunched to handle - /// bluetooth-related events. - public static var bluetoothCentrals: Application.LaunchOptionsKey { - Application.LaunchOptionsKey(rawValue: "Application.BluetoothCentrals") - } - - /// A key indicating that the application should continue actions associated - /// with it's bluetooth peripheral objects. - public static var bluetoothPeripherals: Application.LaunchOptionsKey { - Application.LaunchOptionsKey(rawValue: "Application.BluetoothPeripherals") - } - - /// A key indicating that the application was launched to handle an incoming - /// location event. - public static var location: Application.LaunchOptionsKey { - Application.LaunchOptionsKey(rawValue: "Application.Location") - } - - /// A key indicating that a remove notification is available for the - /// application to process. - public static var remoteNotification: Application.LaunchOptionsKey { - Application.LaunchOptionsKey(rawValue: "Application.RemoteNotification") - } - - /// A key indicating that the application was launched in response to the user - /// selecting a quick action. - public static var shortcutItem: Application.LaunchOptionsKey { - Application.LaunchOptionsKey(rawValue: "Application.ShortCutItem") - } - - /// A key indicating that another application rrequested the launch of your - /// application. - public static var sourceApplication: Application.LaunchOptionsKey { - Application.LaunchOptionsKey(rawValue: "Application.SourceApplication") - } - - /// A key indicating that the application was launched so it could open the - /// specified URL. - public static var url: Application.LaunchOptionsKey { - Application.LaunchOptionsKey(rawValue: "Application.URL") - } - - /// A key indicating a dictionary associated with an activity that the user - /// wants to continue. - public static var userActivityDictionary: Application.LaunchOptionsKey { - Application.LaunchOptionsKey(rawValue: "Application.UserActivityDictionary") - } - - /// A key indicating the type of user activity that the user wants to - /// continue. - public static var userActivityType: Application.LaunchOptionsKey { - Application.LaunchOptionsKey(rawValue: "Application.UserActivityType") - } -} diff --git a/Sources/SwiftWin32/Application/_TriviallyConstructible.swift b/Sources/SwiftWin32/Application/_TriviallyConstructible.swift deleted file mode 100644 index 6c1aa172..00000000 --- a/Sources/SwiftWin32/Application/_TriviallyConstructible.swift +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -// TODO(compnerd) determine if there is a way to avoid this conformance. It is -// required to initialize the class from `ApplicationMain` which takes class -// names. -public protocol _TriviallyConstructible { - init() -} diff --git a/Sources/SwiftWin32/AutoLayout/LayoutAnchor.swift b/Sources/SwiftWin32/AutoLayout/LayoutAnchor.swift deleted file mode 100644 index 802e0294..00000000 --- a/Sources/SwiftWin32/AutoLayout/LayoutAnchor.swift +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool . -// SPDX-License-Identifier: BSD-3-Clause - -/// A factory class for creating layout constraint objects using a fluent API. -public class LayoutAnchor { - internal unowned var item: AnyObject - internal var attribute: LayoutConstraint.Attribute - - internal init(item: AnyObject, attribute: LayoutConstraint.Attribute) { - self.item = item - self.attribute = attribute - } - - // MARK - Building Constraints - - /// Returns a constraint that defines one item's attribute as equal to - /// another. - public func constraint(equalTo anchor: LayoutAnchor) - -> LayoutConstraint { - return constraint(equalTo: anchor, constant: 0.0) - } - - /// Returns a constraint that defines one item's attribute as equal to another - /// item's attribute plus a constant offset. - public func constraint(equalTo anchor: LayoutAnchor, - constant offset: Double) -> LayoutConstraint { - return LayoutConstraint(item: self.item, attribute: self.attribute, - relatedBy: .equal, - toItem: anchor.item, attribute: anchor.attribute, - multiplier: 1.0, constant: offset) - } - - /// Returns a constraint that defines one item's attribute as greater than or - /// equal to another. - public func constraint(greaterThanOrEqualTo anchor: LayoutAnchor) - -> LayoutConstraint { - return constraint(greaterThanOrEqualTo: anchor, constant: 0.0) - } - - /// Returns a constraint that defines one item's attribute as greater than or - /// equal to another item's attribute plus a constant offset. - public func constraint(greaterThanOrEqualTo anchor: LayoutAnchor, - constant offset: Double) -> LayoutConstraint { - return LayoutConstraint(item: self.item, attribute: self.attribute, - relatedBy: .greaterThanOrEqual, - toItem: anchor.item, attribute: anchor.attribute, - multiplier: 1.0, constant: offset) - } - - /// Returns a constraint that defines one item's attribute as less than or - /// equal to another. - public func constraint(lessThanOrEqualTo anchor: LayoutAnchor) - -> LayoutConstraint { - return constraint(lessThanOrEqualTo: anchor, constant: 0.0) - } - - /// Returns a constraint that defines one item's attribute as less than or - /// equal to another item's attribute plus a constant offset. - public func constraint(lessThanOrEqualTo anchor: LayoutAnchor, - constant offset: Double) -> LayoutConstraint { - return LayoutConstraint(item: self.item, attribute: self.attribute, - relatedBy: .lessThanOrEqual, - toItem: anchor.item, attribute: self.attribute, - multiplier: 1.0, constant: offset) - } -} diff --git a/Sources/SwiftWin32/AutoLayout/LayoutConstraint+Cassowary.swift b/Sources/SwiftWin32/AutoLayout/LayoutConstraint+Cassowary.swift deleted file mode 100644 index 4ee98b63..00000000 --- a/Sources/SwiftWin32/AutoLayout/LayoutConstraint+Cassowary.swift +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool . -// SPDX-License-Identifier: BSD-3-Clause - -import Cassowary - -extension LayoutConstraint.Attribute { - internal var name: String { - switch self { - case .left: return "Left" - case .right: return "Right" - case .top: return "Top" - case .bottom: return "Bottom" - case .leading: return "Leading" - case .trailing: return "Trailing" - case .width: return "Width" - case .height: return "Height" - case .centerX: return "CenterX" - case .centerY: return "CenterY" - case .lastBaseline: return "lastBaseline" - case .firstBaseline: return "FirstBaseline" - case .leftMargin: return "LeftMargin" - case .rightMargin: return "RightMargin" - case .topMargin: return "TopMargin" - case .bottomMargin: return "BottomMargin" - case .leadingMargin: return "LeadingMargin" - case .trailingMargin: return "TrailingMargin" - case .centerXWithinMargins: return "CenterXWithinMargins" - case .centerYWithinMargins: return "CenterYWithinMargins" - case .notAnAttribute: return "NotAnAttribute" - } - } -} - -extension LayoutAnchor { - internal var variable: Variable { - Variable("\(type(of: self.item)):0x\(String(UInt(bitPattern: ObjectIdentifier(self.item)), radix: 16)).\(self.attribute.name)") - } -} - -extension LayoutConstraint { - internal var constraint: Constraint { - let lhs = firstAnchor.variable - let rhs: Cassowary.Variable? = secondAnchor?.variable - - switch self.relation { - case .lessThanOrEqual: - if let rhs = rhs { - return Constraint(lhs <= rhs * self.multiplier + self.constant, .required) - } - return Constraint(lhs <= self.constant, .required) - - case .equal: - if let rhs = rhs { - return Constraint(lhs * self.multiplier + self.constant == rhs, .required) - } - return Constraint(lhs * self.multiplier == self.constant, .required) - - case .greaterThanOrEqual: - if let rhs = rhs { - return Constraint(lhs * self.multiplier + self.constant >= rhs, .required) - } - return Constraint(lhs * self.multiplier >= self.constant, .required) - } - } -} diff --git a/Sources/SwiftWin32/AutoLayout/LayoutConstraint.swift b/Sources/SwiftWin32/AutoLayout/LayoutConstraint.swift deleted file mode 100644 index 6dd46bee..00000000 --- a/Sources/SwiftWin32/AutoLayout/LayoutConstraint.swift +++ /dev/null @@ -1,209 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool . -// SPDX-License-Identifier: BSD-3-Clause - -extension LayoutConstraint { - /// The relation between the first attribute and the modified second attribute - /// in a constraint. - public enum Relation: Int { - /// The constraint requires the first attribute to be less than or equal to - /// the modified second attribute. - case lessThanOrEqual - - /// The constraint requires the first attribute to be exactly equal to the - /// modified second attribute. - case equal - - /// The constraint requires the first attribute to be greater than or equal to - /// the modified second attribute. - case greaterThanOrEqual - } -} - -extension LayoutConstraint { - /// The part of the object's visual representation that should be used to get - /// the value for the constraint. - public enum Attribute: Int { - /// The left side of the object's alignment rectangle. - case left - - /// The right side of the object's alignment rectangle. - case right - - /// The top of the object's alignment rectangle. - case top - - /// The bottom of the object's alignment rectangle. - case bottom - - /// The leading edge of the object's alignment rectangle. - case leading - - /// The trailing edge of the object's alignment rectangle. - case trailing - - /// The width of the object's alignment rectangle. - case width - - /// The height of the object's alignment rectangle. - case height - - /// Tne center along the x-axis of the object's alignment rectangle. - case centerX - - /// The center along the y-axis of the object's alignment rectangle. - case centerY - - /// The object's baseline. For objects with more than one line of text, this - /// is the baseline for the bottom-most line of text. - case lastBaseline - - /// The object's baseline. For objects with more than one line of text, this - /// is the baseline for the top-most line of text. - case firstBaseline - - /// The object's left margin. For `View` objects, the margins are defined by - /// their `layoutMargins` property. - case leftMargin - - /// The object's right margin. For `View` objects, the margins are defined by - /// their `layoutMargins` property. - case rightMargin - - /// The object's top margin. For `View` objects, the margins are defined by - /// their `layoutMargins` property. - case topMargin - - /// The object's bottom margin. For `View` objects, the margins are defined - /// by their `layoutMargins` property. - case bottomMargin - - /// The object's leading margin. For `View` objects, the margins are defined - /// by their `layoutMargins` property. - case leadingMargin - - /// The object's trailing margin. For `View` objects, the margins are defined - /// by thier `layoutMargins` property. - case trailingMargin - - /// The center along the x-axis between the object's left and right margin. - /// For `View` objects, the margins are defined by their `layoutMargins` - /// property. - case centerXWithinMargins - - /// The center along the y-axis between the object's top and bottom margin. - /// For `View` objects, the margins are defined by thier `layoutMargins` - /// property. - case centerYWithinMargins - - /// A placeholder value that is used to indicate taht the constraint's second - /// item and second attribute are not used in any calculations. - case notAnAttribute - } -} - -public class LayoutConstraint { - // MARK - Creating Constraints - - /// Creates a constraint that defines the relationship between the specified - /// attributes of the given views. - public /*convenience*/ init(item firstItem: AnyObject, - attribute firstAttribute: LayoutConstraint.Attribute, - relatedBy relation: LayoutConstraint.Relation, - toItem secondItem: AnyObject?, - attribute secondAttribute: LayoutConstraint.Attribute, - multiplier: Double, constant: Double) { - self.firstAnchor = - LayoutAnchor(item: firstItem, attribute: firstAttribute) - - if let item = secondItem { - self.secondAnchor = - LayoutAnchor(item: item, attribute: secondAttribute) - } - - self.relation = relation - self.multiplier = multiplier - self.constant = constant - } - - // MARK - Activating and Deactivating Constraints - - /// The active state of the constraint. - public var isActive: Bool = false { - didSet { - var ancestor: View? = self.firstAnchor.item as? View - if let other = self.secondAnchor?.item as? View { - // TODO(compnerd) this has performance implications - O(n²) for the - // check for the common ancestor search. - while let parent = ancestor, !other.isDescendant(of: parent) { - ancestor = parent.superview - } - } - - switch isActive { - case true: - ancestor?.addConstraint(self) - case false: - ancestor?.removeConstraint(self) - } - } - } - - /// Activates each constraint in the specified array. - public class func activate(_ constraints: [LayoutConstraint]) { - constraints.forEach { $0.isActive = true } - } - - /// Deactivates each constraint in the specified array. - public class func deactivate(_ constraints: [LayoutConstraint]) { - constraints.forEach { $0.isActive = false } - } - - // MARK - Accessing Constraint Data - - /// The first object participating in the constraint. - public unowned(unsafe) var firstItem: AnyObject? { - firstAnchor.item - } - - /// The attribute of the first object participating in the constraint. - public var firstAttribute: LayoutConstraint.Attribute { - firstAnchor.attribute - } - - /// The relationship between the two attributes in the constraint. - public private(set) var relation: LayoutConstraint.Relation - - /// The second object participating in the constraint. - public unowned(unsafe) var secondItem: AnyObject? { - secondAnchor?.item - } - - /// The attribute of the second object participating in the constraint. - public var secondAttribute: LayoutConstraint.Attribute { - secondAnchor?.attribute ?? .notAnAttribute - } - - /// The multiplier applied to the second attribute participating in the - /// constraint. - public private(set) var multiplier: Double - - /// The constant added to the multiplied second attribute participating in the - /// constraint. - public private(set) var constant: Double - - /// The first anchor that defines the constraint. - public private(set) var firstAnchor: LayoutAnchor - - /// The second anchor that defines the constraint. - public private(set) var secondAnchor: LayoutAnchor? - - // MARK - Getting the Layout Priority - - /// The priority of the constraint. - public var priority: LayoutPriority = .required - - // MARK - Identifying a Constraint - - /// The name that identifies the constraint. - public var identifier: String? -} diff --git a/Sources/SwiftWin32/AutoLayout/LayoutDimension.swift b/Sources/SwiftWin32/AutoLayout/LayoutDimension.swift deleted file mode 100644 index 576d381f..00000000 --- a/Sources/SwiftWin32/AutoLayout/LayoutDimension.swift +++ /dev/null @@ -1,94 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool . -// SPDX-License-Identifier: BSD-3-Clause - -/// A factory class for creating size-based layout constraint objects using a -/// fluent API. -public class LayoutDimension: LayoutAnchor { - // MARK - Building Constraints - - /// Returns a constraint that defines the anchor's size attribute as equal to - /// the specified anchor multiplied by the constant. - public func constraint(equalTo anchor: LayoutDimension, multiplier: Double) - -> LayoutConstraint { - return constraint(equalTo: anchor, multiplier: multiplier, constant: 0.0) - } - - /// Returns a constraint that defines the anchor's size attribute as equal to - /// the specified size attribute multiplied by a constant plus an offset. - public func constraint(equalTo anchor: LayoutDimension, multiplier: Double, - constant offset: Double) -> LayoutConstraint { - return LayoutConstraint(item: self.item, attribute: self.attribute, - relatedBy: .equal, - toItem: anchor.item, attribute: anchor.attribute, - multiplier: multiplier, constant: offset) - } - - /// Returns a constraint that defines a constant size for the anchor's size - /// attribute. - public func constraint(equalToConstant constant: Double) -> LayoutConstraint { - return LayoutConstraint(item: self.item, attribute: self.attribute, - relatedBy: .equal, - toItem: nil, attribute: .notAnAttribute, - multiplier: 1.0, constant: constant) - } - - /// Returns a constraint that defines the anchor's size attribute as greater - /// than or equal to the specified anchor multiplied by the constant. - public func constraint(greaterThanOrEqualTo anchor: LayoutDimension, - multiplier: Double) -> LayoutConstraint { - return constraint(greaterThanOrEqualTo: anchor, multiplier: multiplier, - constant: 0.0) - } - - /// Returns a constraint that defines teh anchor's size attribute greater than - /// or equal to the specified anchor multiplied by the constant plus an - /// offset. - public func constraint(greaterThanOrEqualTo anchor: LayoutDimension, - multiplier: Double, constant offset: Double) - -> LayoutConstraint { - return LayoutConstraint(item: self.item, attribute: self.attribute, - relatedBy: .greaterThanOrEqual, - toItem: anchor.item, attribute: anchor.attribute, - multiplier: multiplier, constant: offset) - } - - /// Returns a constraint that defines the minimum size for the anchor's size - /// attribute. - public func constraint(greaterThanOrEqualToConstant constant: Double) - -> LayoutConstraint { - return LayoutConstraint(item: self.item, attribute: self.attribute, - relatedBy: .greaterThanOrEqual, - toItem: nil, attribute: .notAnAttribute, - multiplier: 1.0, constant: constant) - } - - /// Returns a constraint that defines the anchor's size attribute as less than - /// or requal to the specified anchor multiplied by the constant. - public func constraint(lessThanOrEqualTo anchor: LayoutDimension, - multiplier: Double) -> LayoutConstraint { - return constraint(lessThanOrEqualTo: anchor, multiplier: multiplier, - constant: 0.0) - } - - /// Returns a constraint that defines the anchor's size attribute as greater - /// than or equal to the specified anchor multiplied by the constant plus an - /// offset. - public func constraint(lessThanOrEqualTo anchor: LayoutDimension, - multiplier: Double, constant offset: Double) - -> LayoutConstraint { - return LayoutConstraint(item: self.item, attribute: self.attribute, - relatedBy: .lessThanOrEqual, - toItem: anchor.item, attribute: anchor.attribute, - multiplier: multiplier, constant: offset) - } - - /// Returns a constraint that defines the maximum size for teh anchor's size - /// attribute. - public func constraint(lessThanOrEqualToConstant constant: Double) - -> LayoutConstraint { - return LayoutConstraint(item: self.item, attribute: self.attribute, - relatedBy: .lessThanOrEqual, - toItem: nil, attribute: .notAnAttribute, - multiplier: 1.0, constant: constant) - } -} diff --git a/Sources/SwiftWin32/AutoLayout/LayoutGuide.swift b/Sources/SwiftWin32/AutoLayout/LayoutGuide.swift deleted file mode 100644 index 953ff580..00000000 --- a/Sources/SwiftWin32/AutoLayout/LayoutGuide.swift +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool . -// SPDX-License-Identifier: BSD-3-Clause - -#if swift(>=5.7) -import CoreGraphics -#endif - -public class LayoutGuide { - // MARK - Working with Layout Guides - - /// A string used to identify the layout guide. - public var identifier: String = "" - - /// The layout guide's frame in its owning view's coordinate system. - public private(set) var layoutFrame: Rect = .zero - - /// The view that owns the layout guide. - public weak var owningView: View? - - // MARK - Creating Constraints Using Layout Anchors - - /// A layout anchor representing the bottom edge of the layout guide's frame. - public var bottomAnchor: LayoutYAxisAnchor { - LayoutYAxisAnchor(item: owningView!, attribute: .bottom) - } - - /// A layout anchor representing the horizontal center of the layout guide's - /// frame. - public var centerXAnchor: LayoutXAxisAnchor { - LayoutXAxisAnchor(item: owningView!, attribute: .centerX) - } - - /// A layout anchor representing the vertical center of the layout guide's - /// frame. - public var centerYAnchor: LayoutYAxisAnchor { - LayoutYAxisAnchor(item: owningView!, attribute: .centerY) - } - - /// A layout anchor representing the height of the layout guide's frame. - public var heightAnchor: LayoutDimension { - LayoutDimension(item: owningView!, attribute: .height) - } - - /// A layout anchor representing the leading edge of the layout guide's frame. - public var leadingAnchor: LayoutXAxisAnchor { - LayoutXAxisAnchor(item: owningView!, attribute: .leading) - } - - /// A layout anchor representing the left edge of the layout guide's frame. - public var leftAnchor: LayoutXAxisAnchor { - LayoutXAxisAnchor(item: owningView!, attribute: .left) - } - - /// A layout anchor representing the right edge of the layout guide's frame. - public var rightAnchor: LayoutXAxisAnchor { - LayoutXAxisAnchor(item: owningView!, attribute: .right) - } - - /// A layout anchor representing the top edge of teh layout guide's frame. - public var topAnchor: LayoutYAxisAnchor { - LayoutYAxisAnchor(item: owningView!, attribute: .top) - } - - /// A layout anchor representing the trailing edge of teh layout guide's - /// frame. - public var trailingAnchor: LayoutXAxisAnchor { - LayoutXAxisAnchor(item: owningView!, attribute: .trailing) - } - - /// A layout anchor representing the width of the layout guide's frame. - public var widthAnchor: LayoutDimension { - LayoutDimension(item: owningView!, attribute: .width) - } -} diff --git a/Sources/SwiftWin32/AutoLayout/LayoutPriority.swift b/Sources/SwiftWin32/AutoLayout/LayoutPriority.swift deleted file mode 100644 index 9041d681..00000000 --- a/Sources/SwiftWin32/AutoLayout/LayoutPriority.swift +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool . -// SPDX-License-Identifier: BSD-3-Clause - -/// The layout priority is used to indicate to the constraint-based layout -/// system which constraints are more important, allowing the system to make -/// appropriate tradeoffs when satisfying the constraints of the system as a -/// whole. -public struct LayoutPriority: Equatable, Hashable, RawRepresentable { - public typealias RawValue = Float - - public let rawValue: RawValue - - public init(rawValue: RawValue) { - self.rawValue = rawValue - } -} - -extension LayoutPriority { - public init(_ rawValue: RawValue) { - self.rawValue = rawValue - } -} - -extension LayoutPriority { - /// A required constraint. - public static var required: LayoutPriority { - LayoutPriority(rawValue: 1000.0) - } - - /// The priority level with which a button resists compressing its content. - public static var defaultHigh: LayoutPriority { - LayoutPriority(rawValue: 750.0) - } - - /// The priority level with which a button hugs its contents horizontally. - public static var defaultLow: LayoutPriority { - LayoutPriority(rawValue: 250.0) - } - - /// The priority level with which the view wants to conform to the target size - /// in that computation. - public static var fittingSizeLevel: LayoutPriority { - LayoutPriority(rawValue: 50.0) - } - - /// The priority with which a drag may end up resizing the window's scene. - public static var dragThatCanResizeScene: LayoutPriority { - LayoutPriority(rawValue: 510.0) - } - - /// The priority with which the a split view divider is dragged. - public static var dragThatCannotResizeScene: LayoutPriority { - LayoutPriority(rawValue: 490.0) - } - - /// The priority with which the window's scene prefers to stay the same size. - public static var sceneSizeStayPut: LayoutPriority { - LayoutPriority(rawValue: 500.0) - } -} diff --git a/Sources/SwiftWin32/AutoLayout/LayoutSupport.swift b/Sources/SwiftWin32/AutoLayout/LayoutSupport.swift deleted file mode 100644 index 5898e96a..00000000 --- a/Sources/SwiftWin32/AutoLayout/LayoutSupport.swift +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool . -// SPDX-License-Identifier: BSD-3-Clause - -/// A set of methods that provide layout support and access to layout anchors. -public protocol LayoutSupport { - // MARK - Layout Support - - /// Provides the length, in points, of the portion of the view controller's - /// view that is overlaid by translucent or transparent bars. - var length: Double { get } - - // MARK - Creating Constraints Using Layout Anchors - - /// A layout anchor representing the guide's bottom edge. - var bottomAnchor: LayoutYAxisAnchor { get } - - /// A layout anchor repreenting the guide's height. - var heightAnchor: LayoutDimension { get } - - /// A layout anchor representing the guide's top edge. - var topAnchor: LayoutYAxisAnchor { get } -} diff --git a/Sources/SwiftWin32/AutoLayout/LayoutXAxisAnchor.swift b/Sources/SwiftWin32/AutoLayout/LayoutXAxisAnchor.swift deleted file mode 100644 index bef89b80..00000000 --- a/Sources/SwiftWin32/AutoLayout/LayoutXAxisAnchor.swift +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool . -// SPDX-License-Identifier: BSD-3-Clause - -/// A factory class for creating horizontal layout constraint objects using a -/// fluent API. -public class LayoutXAxisAnchor: LayoutAnchor { - // MARK - Building System Spacing Constraints - - /// Returns a constraint that defines by how much the current anchor trails - /// the specified anchor. - public func constraint(equalToSystemSpacingBelow anchor: LayoutXAxisAnchor, - multiplier: Double) -> LayoutConstraint { - return LayoutConstraint(item: self.item, attribute: self.attribute, - relatedBy: .equal, - toItem: anchor.item, attribute: anchor.attribute, - multiplier: multiplier, constant: 8.0) - } - - /// Returns a constraint that defines by how much the current anchor trails - /// the specified anchor. - public func constraint(greaterThanOrEqualToSystemSpacingBelow anchor: LayoutXAxisAnchor, - multiplier: Double) -> LayoutConstraint { - return LayoutConstraint(item: self.item, attribute: self.attribute, - relatedBy: .greaterThanOrEqual, - toItem: anchor.item, attribute: anchor.attribute, - multiplier: multiplier, constant: 8.0) - } - - /// Returns a constraint that defines the minimum distance by which the - /// current anchor is positioned below the specified anchor. - public func constraint(lessThanOrEqualToSystemSpacingBelow anchor: LayoutXAxisAnchor, - multiplier: Double) -> LayoutConstraint { - return LayoutConstraint(item: self.item, attribute: self.attribute, - relatedBy: .lessThanOrEqual, - toItem: anchor.item, attribute: anchor.attribute, - multiplier: multiplier, constant: 8.0) - } - - // MARK - Creating a Layout Dimension - - /// Creates a layout dimension object from two anchors. - public func anchorWithOffset(to anchor: LayoutXAxisAnchor) -> LayoutDimension { - fatalError("\(#function) not yet implemented") - } -} diff --git a/Sources/SwiftWin32/AutoLayout/LayoutYAxisAnchor.swift b/Sources/SwiftWin32/AutoLayout/LayoutYAxisAnchor.swift deleted file mode 100644 index fd319309..00000000 --- a/Sources/SwiftWin32/AutoLayout/LayoutYAxisAnchor.swift +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool . -// SPDX-License-Identifier: BSD-3-Clause - -/// A factory class for creating vertical layout constraint objects using a -/// fluent API. -public class LayoutYAxisAnchor: LayoutAnchor { - // MARK - Building System Spacing Constraints - - /// Returns a constraint that defines the specific distance at which the - /// current anchor is positioned below the specified anchor. - public func constraint(equalToSystemSpacingBelow anchor: LayoutYAxisAnchor, - multiplier: Double) -> LayoutConstraint { - return LayoutConstraint(item: self.item, attribute: self.attribute, - relatedBy: .equal, - toItem: anchor.item, attribute: anchor.attribute, - multiplier: multiplier, constant: 8.0) - } - - /// Returns a constraint that defines the minimum distance by which the - /// current anchor is positioned below the specified anchor. - public func constraint(greaterThanOrEqualToSystemSpacingBelow anchor: LayoutYAxisAnchor, - multiplier: Double) -> LayoutConstraint { - return LayoutConstraint(item: self.item, attribute: self.attribute, - relatedBy: .greaterThanOrEqual, - toItem: anchor.item, attribute: anchor.attribute, - multiplier: multiplier, constant: 8.0) - } - - /// Returns a constraint that defines the maximum distance by which the - /// current anchor is positioned below the specified anchor. - public func constraint(lessThanOrEqualToSystemSpacingBelow anchor: LayoutYAxisAnchor, - multiplier: Double) -> LayoutConstraint { - return LayoutConstraint(item: self.item, attribute: self.attribute, - relatedBy: .lessThanOrEqual, - toItem: anchor.item, attribute: anchor.attribute, - multiplier: multiplier, constant: 8.0) - } - - // MARK - Creating a Layout Dimension - - /// Creates a layout dimension object from two anchors. - public func anchorWithOffset(to anchor: LayoutYAxisAnchor) -> LayoutDimension { - fatalError("\(#function) not yet implemented") - } -} diff --git a/Sources/SwiftWin32/CMakeLists.txt b/Sources/SwiftWin32/CMakeLists.txt deleted file mode 100644 index 61f666f5..00000000 --- a/Sources/SwiftWin32/CMakeLists.txt +++ /dev/null @@ -1,202 +0,0 @@ -#[[ -Copyright © 2019 Saleem Abdulrasool -All rights reserved. - -SPDX-License-Identifier: BSD-3-Clause -#]] - -add_library(SwiftWin32 SHARED - Application/_TriviallyConstructible.swift - Application/Information.swift - Application/LaunchKeyOptions.swift) -target_sources(SwiftWin32 PRIVATE - AutoLayout/LayoutAnchor.swift - AutoLayout/LayoutConstraint.swift - AutoLayout/LayoutDimension.swift - AutoLayout/LayoutGuide.swift - AutoLayout/LayoutPriority.swift - AutoLayout/LayoutSupport.swift - AutoLayout/LayoutXAxisAnchor.swift - AutoLayout/LayoutYAxisAnchor.swift) -target_sources(SwiftWin32 PRIVATE - UI/ContentSizeCategoryAdjusting.swift - UI/ContentSizeCategoryImageAdjusting.swift - UI/Interaction.swift - UI/SceneSizeRestrictions.swift) -target_sources(SwiftWin32 PRIVATE - "App Extensions/InputViewController.swift" - "Animation and Haptics/ViewControllerContextTransitioning.swift" - "Animation and Haptics/Property-Based Animations/CubicTimingParameters.swift" - "Animation and Haptics/Property-Based Animations/SpringTimingParameters.swift" - "Animation and Haptics/Property-Based Animations/TimingCurveProvider.swift" - "Animation and Haptics/Property-Based Animations/ViewAnimating.swift" - "Animation and Haptics/Property-Based Animations/ViewImplicitlyAnimating.swift" - "Animation and Haptics/View Controller Transitions/ViewControllerAnimatedTransitioning.swift" - "Animation and Haptics/View Controller Transitions/ViewControllerInteractiveTransitioning.swift" - "Animation and Haptics/View Controller Transitions/ViewControllerTransitionCoordinator.swift" - "Animation and Haptics/View Controller Transitions/ViewControllerTransitionCoordinatorContext.swift" - "Animation and Haptics/View Controller Transitions/ViewControllerTransitioningDelegate.swift" - "App and Environment/AdaptivePresentationControllerDelegate.swift" - "App and Environment/Application.swift" - "App and Environment/ApplicationDelegate.swift" - "App and Environment/ApplicationMain.swift" - "App and Environment/Device.swift" - "App and Environment/TraitCollection.swift" - "App and Environment/TraitEnvironment.swift" - "App and Environment/Scenes/Scene.swift" - "App and Environment/Scenes/SceneConfiguration.swift" - "App and Environment/Scenes/SceneDelegate.swift" - "App and Environment/Scenes/SceneSession.swift" - "App and Environment/Scenes/WindowScene.swift" - "App and Environment/Scenes/WindowSceneDelegate.swift" - "Appearance Customization/Configurations/BackgroundConfiguration.swift" - "Appearance Customization/Configurations/CellConfigurationState.swift" - "Appearance Customization/Configurations/ConfigurationColorTransformer.swift" - "Appearance Customization/Configurations/ConfigurationState.swift" - "Appearance Customization/Configurations/ConfigurationStateCustomKey.swift" - "Drag and Drop/SpringLoadedInteractionContext.swift" - "Drawing/BezierPath.swift" - "Drawing/Color.swift" - "Focus-Based Navigation/FocusAnimationCoordinator.swift" - "Focus-Based Navigation/FocusEnvironment.swift" - "Focus-Based Navigation/FocusItem.swift" - "Focus-Based Navigation/FocusItemContainer.swift" - "Focus-Based Navigation/FocusMovementHint.swift" - "Focus-Based Navigation/FocusUpdateContext.swift" - "Images and PDF/Image.swift" - "Keyboards and Input/TextInputTraits.swift" - "Menus and Shortcuts/Action.swift" - "Menus and Shortcuts/Command.swift" - "Menus and Shortcuts/ContextMenuConfiguration.swift" - "Menus and Shortcuts/ContextMenuInteractionAnimating.swift" - "Menus and Shortcuts/ContextMenuInteractionCommitAnimating.swift" - "Menus and Shortcuts/ContextMenuInteraction.swift" - "Menus and Shortcuts/ContextMenuInteractionDelegate.swift" - "Menus and Shortcuts/Menu.swift" - "Menus and Shortcuts/MenuBuilder.swift" - "Menus and Shortcuts/MenuElement.swift" - "Menus and Shortcuts/MenuSystem.swift" - "Menus and Shortcuts/PreviewParameters.swift" - "Menus and Shortcuts/PreviewTarget.swift" - "Menus and Shortcuts/TargetedPreview.swift" - "Pointer Interactions/PointerInteraction.swift" - "Pointer Interactions/PointerInteractionAnimating.swift" - "Pointer Interactions/PointerInteractionDelegate.swift" - "Pointer Interactions/PointerRegion.swift" - "Pointer Interactions/PointerRegionRequest.swift" - "Pointer Interactions/PointerStyle.swift" - "Text Display and Fonts/Font.swift" - "Text Display and Fonts/FontDescriptor.swift" - "Text Display and Fonts/FontMetrics.swift" - "Touches, Presses, and Gestures/Event.swift" - "Touches, Presses, and Gestures/GestureRecognizer.swift" - "Touches, Presses, and Gestures/GestureRecognizerDelegate.swift" - "Touches, Presses, and Gestures/Responder.swift" - "Touches, Presses, and Gestures/Touch.swift" - "Touches, Presses, and Gestures/Press.swift" - "Touches, Presses, and Gestures/PressesEvent.swift" - "View Controllers/ContentContainer.swift" - "View Controllers/PresentationController.swift" - "View Controllers/ViewController.swift" - "Views and Controls/Axis.swift" - "Views and Controls/BarItem.swift" - "Views and Controls/BarButtonItem.swift" - "Views and Controls/BarButtonItemGroup.swift" - "Views and Controls/BarPositioning.swift" - "Views and Controls/Button.swift" - "Views and Controls/Control.swift" - "Views and Controls/DatePicker.swift" - "Views and Controls/DirectionalEdgeInsets.swift" - "Views and Controls/DirectionalRectEdge.swift" - "Views and Controls/EdgeInsets.swift" - "Views and Controls/ImageView.swift" - "Views and Controls/Label.swift" - "Views and Controls/Offset.swift" - "Views and Controls/PickerView.swift" - "Views and Controls/ProgressView.swift" - "Views and Controls/Slider.swift" - "Views and Controls/Stepper.swift" - "Views and Controls/Switch.swift" - "Views and Controls/TextAlignment.swift" - "Views and Controls/TextField.swift" - "Views and Controls/TextView.swift" - "Views and Controls/View.swift" - "Views and Controls/VisualEffect.swift" - "Views and Controls/Table Views/ContextualAction.swift" - "Views and Controls/Table Views/SwipeActionsConfiguration.swift" - "Views and Controls/Table Views/TableView.swift" - "Views and Controls/Table Views/TableViewCell.swift" - "Views and Controls/Table Views/TableViewDataSource.swift" - "Views and Controls/Table Views/TableViewDelegate.swift" - "Views and Controls/Table Views/TableViewFocusUpdateContext.swift" - "Windows and Screens/AlertAction.swift" - "Windows and Screens/AlertController.swift" - "Windows and Screens/CoordinateSpace.swift" - "Windows and Screens/Screen.swift" - "Windows and Screens/Window.swift") -target_sources(SwiftWin32 PRIVATE - Platform/BatteryMonitor.swift - Platform/Error.swift - Platform/Win32+Menu.swift - Platform/Win32+PropertyWrappers.swift - Platform/WindowClass.swift - Platform/WindowsHandle.swift) -target_sources(SwiftWin32 PRIVATE - Support/Array+Extensions.swift - Support/Date+Extensions.swift - Support/IndexPath+UIExtensions.swift - Support/Logging.swift - Support/Rect+UIExtensions.swift - Support/Point+UIExtensions.swift - Support/Size+UIExtensions.swift - Support/String+UIExtensions.swift - Support/WindowsHandle+UIExtensions.swift - Support/WinSDK+Extensions.swift - Support/WinSDK+UIExtensions.swift) -target_sources(SwiftWin32 PRIVATE - Support/WindowMessage.swift) -if(CMAKE_Swift_COMPILER_VERSION VERSION_LESS 5.7.0) - target_sources(SwiftWin32 PRIVATE - CoreAnimation/Transform3D.swift) - target_sources(SwiftWin32 PRIVATE - CoreGraphics/AffineTransform.swift - CoreGraphics/Point.swift - CoreGraphics/Rect.swift - CoreGraphics/Size.swift - CoreGraphics/Vector.swift) -else() - add_library(CoreAnimation STATIC - CoreAnimation/Transform3D.swift) - target_link_libraries(SwiftWin32 PRIVATE - CoreAnimation) - - add_library(CoreGraphics STATIC - CoreGraphics/AffineTransform.swift - CoreGraphics/Point.swift - CoreGraphics/Rect.swift - CoreGraphics/Size.swift - CoreGraphics/Vector.swift) - target_link_libraries(SwiftWin32 PRIVATE - CoreGraphics) -endif() -target_link_libraries(SwiftWin32 PUBLIC - ComCtl32 - User32) -target_link_libraries(SwiftWin32 PUBLIC - SwiftCOM) -target_link_libraries(SwiftWin32 PUBLIC - $<$>:dispatch> - $<$>:Foundation>) -target_link_libraries(SwiftWin32 PRIVATE - Logging - OrderedCollections) -set_target_properties(SwiftWin32 PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_Swift_MODULE_DIRECTORY} - INTERFACE_LINK_DIRECTORIES $) - - -if(CMAKE_Swift_COMPILER_VERSION VERSION_GREATER_EQUAL 5.7.0) - _install_target(CoreAnimation) - _install_target(CoreGraphics) -endif() -_install_target(SwiftWin32) diff --git a/Sources/SwiftWin32/CoreAnimation/Transform3D.swift b/Sources/SwiftWin32/CoreAnimation/Transform3D.swift deleted file mode 100644 index c8cae9f3..00000000 --- a/Sources/SwiftWin32/CoreAnimation/Transform3D.swift +++ /dev/null @@ -1,116 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -/// The standard transform matrix. -public struct Transform3D { - // MARK - Initializers - - public init() { - self.m11 = 0 - self.m12 = 0 - self.m13 = 0 - self.m14 = 0 - self.m21 = 0 - self.m22 = 0 - self.m23 = 0 - self.m24 = 0 - self.m31 = 0 - self.m32 = 0 - self.m33 = 0 - self.m34 = 0 - self.m41 = 0 - self.m42 = 0 - self.m43 = 0 - self.m44 = 0 - } - - public init(m11: Double, m12: Double, m13: Double, m14: Double, - m21: Double, m22: Double, m23: Double, m24: Double, - m31: Double, m32: Double, m33: Double, m34: Double, - m41: Double, m42: Double, m43: Double, m44: Double) { - self.m11 = m11 - self.m12 = m12 - self.m13 = m13 - self.m14 = m14 - self.m21 = m21 - self.m22 = m22 - self.m23 = m23 - self.m24 = m24 - self.m31 = m31 - self.m32 = m32 - self.m33 = m33 - self.m34 = m34 - self.m41 = m41 - self.m42 = m42 - self.m43 = m43 - self.m44 = m44 - } - - // public init(_ m: float4x4) { } - - // public init(_ m: double4x4) { } - - // MARK - Instance Properties - - /// The entry at position 1,1 in the matrix. - var m11: Double - - /// The entry at position 1,2 in the matrix. - var m12: Double - - /// The entry at position 1,3 in the matrix. - var m13: Double - - /// The entry at position 1,4 in the matrix. - var m14: Double - - /// The entry at position 2,1 in the matrix. - var m21: Double - - /// The entry at position 2,2 in the matrix. - var m22: Double - - /// The entry at position 2,3 in the matrix. - var m23: Double - - /// The entry at position 2,4 in the matrix. - var m24: Double - - /// The entry at position 3,1 in the matrix. - var m31: Double - - /// The entry at position 3,2 in the matrix. - var m32: Double - - /// The entry at position 3,3 in the matrix. - var m33: Double - - /// The entry at position 3,4 in the matrix. - var m34: Double - - /// The entry at position 4,1 in the matrix. - var m41: Double - - /// The entry at position 4,2 in the matrix. - var m42: Double - - /// The entry at position 4,3 in the matrix. - var m43: Double - - /// The entry at position 4,4 in the matrix. - var m44: Double -} - -extension Transform3D { - /// The identity transform. - /// [1, 0, 0, 0] - /// [0, 1, 0, 0] - /// [0, 0, 1, 0] - /// [0, 0, 0, 1] - public static var identity: Transform3D { - Transform3D(m11: 1, m12: 0, m13: 0, m14: 0, - m21: 0, m22: 1, m23: 0, m24: 0, - m31: 0, m32: 0, m33: 1, m34: 0, - m41: 0, m42: 0, m43: 0, m44: 1) - } -} diff --git a/Sources/SwiftWin32/CoreGraphics/AffineTransform.swift b/Sources/SwiftWin32/CoreGraphics/AffineTransform.swift deleted file mode 100644 index 149c7bc6..00000000 --- a/Sources/SwiftWin32/CoreGraphics/AffineTransform.swift +++ /dev/null @@ -1,125 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import func ucrt.sin -import func ucrt.cos - -/// An affine transformation matrix for use in drawing 2D graphics. -public struct AffineTransform { - // MARK - - - /// The identity transform. - public static var identity: AffineTransform { - AffineTransform( a: 1.0, b: 0.0, - c: 0.0, d: 1.0, - tx: 0.0, ty: 0.0) - } - - // MARK - - - /// The entry at position [1,1] in the matrix. - public var a: Double - - /// The entry at position [1,2] in the matrix. - public var b: Double - - /// The entry at position [2,1] in the matrix. - public var c: Double - - /// The entry at position [2,2] in the matrix. - public var d: Double - - /// The entry at position [3,1] in the matrix. - public var tx: Double - - /// The entry at position [3,2] in the matrix. - public var ty: Double - - /// Checks whether an affine transform is the identity transform. - public var isIdentity: Bool { - return self == .identity - } - - // MARK - Initializers - - public init() { - self.a = 0.0 - self.b = 0.0 - self.c = 0.0 - self.d = 0.0 - self.tx = 0.0 - self.ty = 0.0 - } - - public init( a: Double, b: Double, - c: Double, d: Double, - tx: Double, ty: Double) { - self.a = a - self.b = b - self.c = c - self.d = d - self.tx = tx - self.ty = ty - } - - /// Returns an affine transformation matrix constructed from a rotation value - /// you provide. - public init(rotationAngle radians: Double) { - let sine: Double = sin(radians) - let cosine: Double = cos(radians) - - self.init( a: cosine, b: sine, - c: -sine, d: cosine, - tx: 0.0, ty: 0.0) - } - - /// Returns an affine transformation matrix constructed from scaling values - /// you provide. - public init(scaleX sx: Double, y sy: Double) { - self.init( a: sx, b: 0.0, - c: 0.0, d: sy, - tx: 0.0, ty: 0.0) - } - - /// Returns an affine transformation matrix constructed from translation - /// values you provide. - public init(translationX tx: Double, y ty: Double) { - self.init( a: 1.0, b: 0.0, - c: 0.0, d: 1.0, - tx: tx, ty: ty) - } - - // MARK - - - /// Returns an affine transformation matrix constructed by combining two - /// existing affine transforms. - public func concatenating(_ transform: AffineTransform) -> AffineTransform { - return AffineTransform(a: self.a * transform.a + self.b * transform.c, - b: self.a * transform.b + self.b * transform.d, - c: self.c * transform.a + self.d * transform.c, - d: self.c * transform.b + self.d * transform.d, - tx: self.tx * transform.a + self.ty * transform.c + transform.tx, - ty: self.tx * transform.b + self.ty * transform.d + transform.ty) - } - - /// Returns an affine transformation matrix constructed by inverting an - /// existing affine transform. - public func inverted() -> AffineTransform { - let determinant = self.a * self.d - self.b * self.c - - // The matrix is in-invertible if the determinant is 0. - if determinant == 0 { return self } - - let a = self.d / determinant - let b = -self.b / determinant - let c = -self.c / determinant - let d = self.a / determinant - - return AffineTransform(a: a, b: b, c: c, d: d, - tx: -a * self.tx - c * self.ty, - ty: -b * self.tx - d * self.ty) - } -} - -extension AffineTransform: Equatable { -} diff --git a/Sources/SwiftWin32/CoreGraphics/Point.swift b/Sources/SwiftWin32/CoreGraphics/Point.swift deleted file mode 100644 index 85b0a163..00000000 --- a/Sources/SwiftWin32/CoreGraphics/Point.swift +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright © 2019 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -/// A structure that contains a point in a two-dimensional coordinate system. -public struct Point { - // MARK - Creating Point Values - - /// Creates a point with coordinates specified as floating-point values. - public init(x: Double, y: Double) { - self.x = x - self.y = y - } - - /// Creates a point with coordinates specified as integer values. - public init(x: Int, y: Int) { - self.init(x: Double(x), y: Double(y)) - } - - // MARK - Special Values - - /// The point with location (0,0). - public static var zero: Point { - Point(x: 0, y: 0) - } - - /// Creates a point with location (0,0). - public init() { - self.x = 0.0 - self.y = 0.0 - } - - // MARK - Geometric Properties - - /// The x-coordinate of the point. - public var x: Double - - /// The y-coordinate of the point. - public var y: Double - - // MARK - Transforming Points - - /// Returns the point resulting from an affine transformation of an existing - /// point. - public func applying(_ transform: AffineTransform) -> Point { - return Point(x: transform.a * self.x + transform.c * self.y + transform.tx, - y: transform.b * self.x + transform.d * self.y + transform.ty) - } -} - -extension Point: Equatable { -} - -extension Point: CustomDebugStringConvertible { - public var debugDescription: String { - return "Point(x: \(x), y: \(y))" - } -} diff --git a/Sources/SwiftWin32/CoreGraphics/Rect.swift b/Sources/SwiftWin32/CoreGraphics/Rect.swift deleted file mode 100644 index 225c3ade..00000000 --- a/Sources/SwiftWin32/CoreGraphics/Rect.swift +++ /dev/null @@ -1,277 +0,0 @@ -// Copyright © 2019 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import CRT -import WinSDK - -@inline(__always) -private func __equals(_ lhs: Rect, _ rhs: Rect) -> Bool { - return lhs.origin == rhs.origin && lhs.size == rhs.size -} - -extension Rect { - /// Coordinates that establish the edges of a rectangle. - @frozen - public enum Edge: UInt32 { - /// The minimum value for the x-coordinate of the rectangle. In the default - /// coordinate space, this is the left edge of the rectangle. - case minXEdge - - /// The minimum value for the y-coordinate of the rectangle. In the default - /// coordinate space, this is the top edge of the rectangle. - case minYEdge - - /// The maximum value for the x-coordinate of the rectangle. In the default - /// coordinate space, this is the right edge of the rectangle. - case maxXEdge - - /// The maximum value for the y-coordinate of the rectangle. In the default - /// coordinate space, this is the bottom edge of the rectangle. - case maxYEdge - } -} - -/// A structure that contains the location and dimensions of a rectangle. -public struct Rect { - // MARK - Creating Rectangle Values - - /// Creates a rectangle with the specified origin and size. - public init(origin: Point, size: Size) { - self.origin = origin - self.size = size - } - - /// Creates a rectangle with coordinates and dimensions specified as - /// floating-point values. - public init(x: Double, y: Double, width: Double, height: Double) { - self.init(origin: Point(x: x, y: y), - size: Size(width: width, height: height)) - } - - /// Creates a rectangle with coordinates and dimensions specified as integer - /// values. - public init(x: Int, y: Int, width: Int, height: Int) { - self.init(origin: Point(x: x, y: y), - size: Size(width: Double(width), height: Double(height))) - } - - // MARK - Special Values - - /// A rectangle that has infinite extent. - public static var infinite: Rect { - Rect(x: -.leastNormalMagnitude, y: -.leastNormalMagnitude, - width: .greatestFiniteMagnitude, height:.greatestFiniteMagnitude) - } - - /// The null rectangle, representing an invalid value. - public static var null: Rect { - Rect(x: .infinity, y: .infinity, width: 0.0, height: 0.0) - } - - /// The rectangle whose origin and size are both zero. - public static var zero: Rect { - Rect(x: 0, y: 0, width: 0, height: 0) - } - - /// Creates a rectangle with origin (0,0) and size (0,0). - public init() { - self = .zero - } - - // MARK - Basic Geometric Properties - - /// A point that specifies the coordinates of the rectangle’s origin. - public var origin: Point - - /// A size that specifies the height and width of the rectangle. - public var size: Size - - // MARK - Calculated Geometric Properties - - /// Returns the height of a rectangle. - public var height: Double { - return self.size.height - } - - /// Returns the width of a rectangle. - public var width: Double { - return self.size.width - } - - /// Returns the smallest value for the x-coordinate of the rectangle. - public var minX: Double { - return self.origin.x - } - - /// Returns the x-coordinate that establishes the center of a rectangle. - public var midX: Double { - return self.origin.x + (self.size.width / 2) - } - - /// Returns the largest value of the x-coordinate for the rectangle. - public var maxX: Double { - return self.origin.x + self.size.width - } - - /// Returns the smallest value for the y-coordinate of the rectangle. - public var minY: Double { - return self.origin.y - } - - /// Returns the y-coordinate that establishes the center of the rectangle. - public var midY: Double { - return self.origin.y + (self.size.height / 2) - } - - /// Returns the largest value for the y-coordinate of the rectangle. - public var maxY: Double { - return self.origin.y + self.size.height - } - - // MARK - Creating Derived Rectangles - - /// Returns a rectangle with a positive width and height. - public var standardized: Rect { - guard !self.isNull else { return .null } - - guard self.size.width < 0 || self.size.height < 0 else { return self } - return Rect(x: self.origin.x + (self.width < 0 ? self.width : 0), - y: self.origin.y + (self.height < 0 ? self.height : 0), - width: abs(self.width), height: abs(self.height)) - } - - /// Returns the smallest rectangle that results from converting the source - /// rectangle values to integers. - public var integral: Rect { - guard !self.isNull else { return .null } - - let standardized = self.standardized - let origin: Point = Point(x: floor(standardized.minX), - y: floor(standardized.minY)) - let size: Size = Size(width: ceil(standardized.maxX) - origin.x, - height: ceil(standardized.maxY) - origin.y) - return Rect(origin: origin, size: size) - } - - /// Applies an affine transform to a rectangle. - public func applying(_ transform: AffineTransform) -> Rect { - guard !self.isNull else { return .null } - if transform.isIdentity { return self.standardized } - - let points: [Point] = [ - Point(x: minX, y: minY), // top left - Point(x: maxX, y: minY), // top right - Point(x: minX, y: maxY), // bottom left - Point(x: maxX, y: maxY), // bottom right - ].map { $0.applying(transform) } - - let (minX, minY, maxX, maxY): (Double, Double, Double, Double) = - points.map { ($0.x, $0.y) } - .reduce((.infinity, .infinity, -.infinity, -.infinity), { - (min($0.0, $1.0), min($0.1, $1.1), max($0.2, $1.0), max($0.3, $1.1)) - }) - - return Rect(origin: Point(x: minX, y: minY), - size: Size(width: maxX - minX, height: maxY - minY)) - } - - /// Returns a rectangle that is smaller or larger than the source rectangle, - /// with the same center point. - public func insetBy(dx: Double, dy: Double) -> Rect { - let standardized = self.standardized - let origin: Point = - Point(x: standardized.minX + dx, y: standardized.minY + dy) - let size: Size = Size(width: standardized.width - 2 * dx, - height: standardized.height - 2 * dy) - guard size.width > 0, size.height > 0 else { return .null } - return Rect(origin: origin, size: size) - } - - /// Returns a rectangle with an origin that is offset from that of the source - /// rectangle. - public func offsetBy(dx: Double, dy: Double) -> Rect { - guard !self.isNull else { return self } - - let standardized = self.standardized - return Rect(x: standardized.origin.x + dx, - y: standardized.origin.y + dy, - width: standardized.size.width, - height: standardized.size.height) - } - - /// Returns the smallest rectangle that contains the two source rectangles. - public func union(_ rect: Rect) -> Rect { - guard !self.isNull else { return rect } - guard !rect.isNull else { return self } - let lhs: Rect = self.standardized, rhs: Rect = rect.standardized - - let origin: Point = Point(x: min(lhs.minX, rhs.minX), - y: min(lhs.minY, rhs.minY)) - let size: Size = Size(width: max(lhs.maxX, rhs.maxX) - origin.x, - height: max(lhs.maxY, rhs.maxY) - origin.y) - return Rect(origin: origin, size: size) - } - - /// Returns the intersection of two rectangles. - public func intersection(_ rect: Rect) -> Rect { - guard !self.isNull, !rect.isNull else { return .null } - let lhs: Rect = self.standardized, rhs: Rect = rect.standardized - - let origin: Point = Point(x: max(lhs.minX, rhs.minX), - y: max(lhs.minY, rhs.minY)) - let size: Size = Size(width: min(lhs.maxX, rhs.maxX) - origin.x, - height: min(lhs.maxY, rhs.maxY) - origin.y) - guard size.width > 0, size.height > 0 else { return .null } - return Rect(origin: origin, size: size) - } - - // MARK - Checking Characteristics - - /// Returns whether two rectangles intersect. - public func intersects(_ rect: Rect) -> Bool { - return !intersection(rect).isEmpty - } - - /// Returns whether a rectangle contains a specified point. - public func contains(_ point: Point) -> Bool { - guard !self.isNull else { return false } - let standardized: Rect = self.standardized - return standardized.minX...standardized.maxX ~= point.x - && standardized.minY...standardized.maxY ~= point.y - } - - /// Returns whether the first rectangle contains the second rectangle. - public func contains(_ rect2: Rect) -> Bool { - return self == self.union(rect2) - } - - /// Returns whether a rectangle has zero width or height, or is a null - /// rectangle. - public var isEmpty: Bool { - return self.size.height == 0 || self.size.width == 0 || self.isNull - } - - /// Returns whether a rectangle is infinite. - public var isInfinite: Bool { - return self == .infinite - } - - /// Returns whether the rectangle is equal to the null rectangle. - public var isNull: Bool { - return __equals(self, .null) - } -} - -extension Rect: Equatable { - // MARK - Operator Functions - public static func == (lhs: Rect, rhs: Rect) -> Bool { - let lhs: Rect = lhs.standardized, rhs: Rect = rhs.standardized - return __equals(lhs, rhs) - } -} - -extension Rect: CustomDebugStringConvertible { - public var debugDescription: String { - return "Rect(origin: \(origin), size: \(size))" - } -} diff --git a/Sources/SwiftWin32/CoreGraphics/Size.swift b/Sources/SwiftWin32/CoreGraphics/Size.swift deleted file mode 100644 index 5fcd1560..00000000 --- a/Sources/SwiftWin32/CoreGraphics/Size.swift +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright © 2019 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -/// A structure that contains width and height values. -public struct Size { - // MARK - Geometric Properties - - /// A width value. - public var width: Double - - /// A height value. - public var height: Double - - // MARK - Special Values - - /// The size whose width and height are both zero. - public static var zero: Size { - Size(width: 0, height: 0) - } - - /// Creates a size with zero width and height. - public init() { - self = .zero - } - - // MARK - Transforming Sizes - - /// Returns the height and width resulting from a transformation of an - /// existing height and width. - func applying(_ transform: AffineTransform) -> Size { - return Size(width: transform.a * self.width + transform.c * self.height, - height: transform.b * self.width + transform.d * self.height) - } - - // MARK - Initializers - - /// Creates a size with dimensions specified as floating-point values. - public init(width: Double, height: Double) { - self.height = height - self.width = width - } - - public init(width: Int, height: Int) { - self.init(width: Double(width), height: Double(height)) - } -} - -extension Size: Equatable { -} - -extension Size: CustomDebugStringConvertible { - public var debugDescription: String { - return "Size(width: \(width), height: \(height))" - } -} diff --git a/Sources/SwiftWin32/CoreGraphics/Vector.swift b/Sources/SwiftWin32/CoreGraphics/Vector.swift deleted file mode 100644 index 2d471b48..00000000 --- a/Sources/SwiftWin32/CoreGraphics/Vector.swift +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -/// A structure that contains a two-dimensional vector. -public struct Vector { - // MARK - Special Values - - /// The vector whose components are both zero. - public static var zero: Vector { - Vector(dx: 0.0, dy: 0.0) - } - - /// Creates a vector whose components are both zero. - public init() { - self.dx = 0.0 - self.dy = 0.0 - } - - // MARK - Geometric Properties - - /// The x component of the vector. - public var dx: Double - - /// The y component of the vector. - public var dy: Double - - // MARK - Initializers - - /// Creates a vector with components specified as floating-point values. - public init(dx: Double, dy: Double) { - self.dx = dx - self.dy = dy - } - - /// Creates a vector with components specified as floating-point values. - public init(dx: Float, dy: Float) { - self.dx = Double(dx) - self.dy = Double(dy) - } - - /// Creates a vector with components specified as integer values. - public init(dx: Int, dy: Int) { - self.dx = Double(dx) - self.dy = Double(dy) - } -} - -extension Vector: CustomDebugStringConvertible { - public var debugDescription: String { - return "(\(dx), \(dy))" - } -} - -extension Vector: Decodable { -} - -extension Vector: Encodable { -} - -extension Vector: Equatable { -} diff --git a/Sources/SwiftWin32/Drag and Drop/SpringLoadedInteractionContext.swift b/Sources/SwiftWin32/Drag and Drop/SpringLoadedInteractionContext.swift deleted file mode 100644 index 7f746675..00000000 --- a/Sources/SwiftWin32/Drag and Drop/SpringLoadedInteractionContext.swift +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -/// The spring-loaded interaction states that determine the style of the -/// interaction view. -public enum SpringLoadedInteractionEffectState: Int { - /// An interaction state that indicates that the view was spring loaded. - case activated - /// An interaction state that indicates that spring loading is about to start. - case activating - /// An interaction state that indicates that spring loading is not engaged. - case inactive - /// An interaction state that indicates that spring loading is available. - case possible -} - -/// The interface an object implements to provide information about a -/// spring-loaded interaction. -public protocol SpringLoadedInteractionContext { - /// The current view style for the string-loaded interaction. - var state: SpringLoadedInteractionEffectState { get } - - /// The specific subview, or associated model object, of the target view to - /// use for the spring-loaded interaction. - var targetItem: Any? { get set } - - /// The view to which the current spring-loaded interaction view style is - /// applied. - var targetView: View? { get set } -} diff --git a/Sources/SwiftWin32/Drawing/BezierPath.swift b/Sources/SwiftWin32/Drawing/BezierPath.swift deleted file mode 100644 index 49fa8e79..00000000 --- a/Sources/SwiftWin32/Drawing/BezierPath.swift +++ /dev/null @@ -1,5 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -public class BezierPath { -} diff --git a/Sources/SwiftWin32/Drawing/Color.swift b/Sources/SwiftWin32/Drawing/Color.swift deleted file mode 100644 index 491186f3..00000000 --- a/Sources/SwiftWin32/Drawing/Color.swift +++ /dev/null @@ -1,1052 +0,0 @@ -// Copyright © 2019 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import WinSDK - -extension Color { - fileprivate enum Representation { - case rgba(Double, Double, Double, Double) - case hsba(Double, Double, Double, Double) - case gray(Double, Double) - case `func`((TraitCollection) -> Color) - } -} - -extension Color.Representation: Equatable { - internal static func ==(_ lhs: Color.Representation, - _ rhs: Color.Representation) -> Bool { - switch (lhs, rhs) { - case let (.rgba(lr, lg, lb, la), .rgba(rr, rg, rb, ra)): - return (lr, lg, lb, la) == (rr, rg, rb, ra) - case let (.hsba(lh, ls, lb, la), .hsba(rh, rs, rb, ra)): - return (lh, ls, lb, la) == (rh, rs, rb, ra) - case let (.gray(lg, la), gray(rg, ra)): - return (lg, la) == (rg, ra) - case let (.func(lhs), .func(rhs)): - return withUnsafePointer(to: lhs) { lhs in - return withUnsafePointer(to: rhs) { rhs in - lhs == rhs - } - } - default: return false - } - } -} - -extension Color.Representation: Hashable { - public func hash(into hasher: inout Hasher) { - switch self { - case .rgba(let r, let g, let b, let a): - hasher.combine(0) // colorspace - hasher.combine(r) - hasher.combine(g) - hasher.combine(b) - hasher.combine(a) - case .hsba(let h, let s, let b, let a): - hasher.combine(1) // colorspace - hasher.combine(h) - hasher.combine(s) - hasher.combine(b) - hasher.combine(a) - case .gray(let white, let alpha): - hasher.combine(2) // colorspace - hasher.combine(white) - hasher.combine(alpha) - case .func(let body): - withUnsafePointer(to: body) { - hasher.combine($0) - } - } - } -} - -/// An object that stores color data and sometimes opacity. -public struct Color { - private let value: Representation - - // MARK - Creating a Color from Component Values - - /// Creates a color object using the specified opacity and grayscale values. - public init(white: Double, alpha: Double) { - self.value = .gray(white, alpha) - } - - /// Creates a color object using the specified opacity and HSB color space - /// component values. - public init(hue: Double, saturation: Double, brightness: Double, - alpha: Double) { - self.value = .hsba(hue, saturation, brightness, alpha) - } - - /// Creates a color object using the specified opacity and RGB component - /// values. - public init(red: Double, green: Double, blue: Double, alpha: Double) { - self.value = .rgba(red, green, blue, alpha) - } - - // MARK - Creating a Color Dynamically - - /// Creates a color object that uses the specified block to generate its color - /// data dynamically. - public init(dynamicProvider block: @escaping (TraitCollection) -> Color) { - self.value = .func(block) - } - - // MARK - Getting the Color Information - - /// Returns the components that form the color in the HSB color space. - /// - /// If the color is in a compatible color space, it converts into the HSB - /// color space, and its components return to your application. If the color - /// isn’t in a compatible color space, the parameters don’t change. - public func getHue(_ hue: UnsafeMutablePointer?, - saturation: UnsafeMutablePointer?, - brightness: UnsafeMutablePointer?, - alpha: UnsafeMutablePointer?) -> Bool { - switch self.value { - case .gray: - fatalError("cannot convert Gray to HSBA") - case .rgba(let r, let g, let b, let a): - func rgb2hsb(_ r: Double, _ g: Double, _ b: Double) - -> (Double, Double, Double) { - let V = max(r, g, b) - let m = min(r, g, b) - let delta = V - m - - var hue: Double - if V == 0.0 { hue = 0.0 } - else if V == r { hue = (g - b) / delta } - else if V == g { hue = 2.0 + (b - r) / delta } - else if V == b { hue = 4.0 + (r - g) / delta } - else { fatalError("maximum must be one of the values") } - - hue = ucrt.fmodl(hue + 6.0, 6.0) - return (hue == 0.0 ? 1.0 : hue / 6.0, V, V == 0.0 ? 0.0 : delta / V) - } - - let (h, s, b) = rgb2hsb(r, g, b) - - hue?.pointee = h - brightness?.pointee = s - saturation?.pointee = b - alpha?.pointee = a - return true - case .hsba(let h, let s, let b, let a): - hue?.pointee = h - saturation?.pointee = s - brightness?.pointee = b - alpha?.pointee = a - return true - case .func: - return resolvedColor(with: TraitCollection.current) - .getHue(hue, saturation: saturation, brightness: brightness, - alpha: alpha) - } - } - - /// Returns the components that form the color in the RGB color space. - /// - /// If the color is in a compatible color space, it converts into RGB format - /// and its components return to your application. If the color isn’t in a - /// compatible color space, the parameters don’t change. - public func getRed(_ red: UnsafeMutablePointer?, - green: UnsafeMutablePointer?, - blue: UnsafeMutablePointer?, - alpha: UnsafeMutablePointer?) -> Bool { - switch self.value { - case .gray: - fatalError("cannot convert Gray to RGBA") - case .rgba(let r, let g, let b, let a): - red?.pointee = r - green?.pointee = g - blue?.pointee = b - alpha?.pointee = a - return true - case .hsba(let h, let s, let b, let a): - func f(_ n: Double) -> Double { - let k = ucrt.fmod(n + (6.0 * h), 6.0) - return b - b * s * max(0, min(k, 4 - k, 1)) - } - red?.pointee = f(5.0) - green?.pointee = f(3.0) - blue?.pointee = f(1.0) - alpha?.pointee = a - return true - case .func: - return resolvedColor(with: TraitCollection.current) - .getRed(red, green: green, blue: blue, alpha: alpha) - } - } - - /// Returns the grayscale components of the color. - /// - /// If the color is in a compatible color space, it converts into grayscale - /// format and its returned to your application. If the color isn’t in a - /// compatible color space, the parameters don’t change. - public func getWhite(_ white: UnsafeMutablePointer?, - alpha: UnsafeMutablePointer?) -> Bool { - switch self.value { - case .gray(let w, let a): - white?.pointee = w - alpha?.pointee = a - return true - case .rgba(let r, let g, let b, let a): - // The weighted or luminosity method uses the weighted average of the - // channels based on the wavelength of the channel. - // The constants here are from ITU-R BT.601-7. - white?.pointee = r * 0.299 + g * 0.587 + b * 0.114 - alpha?.pointee = a - return true - case .hsba(let h, let s, let b, let a): - func f(_ n: Double) -> Double { - let k = ucrt.fmod(n + (6.0 * h), 6.0) - return b - b * s * max(0, min(k, 4 - k, 1)) - } - white?.pointee = f(5.0) * 0.299 + f(3.0) * 0.587 + f(1.0) * 0.114 - alpha?.pointee = a - return true - case .func: - return resolvedColor(with: TraitCollection.current) - .getWhite(white, alpha: alpha) - } - } - - // MARK - Resolving a Dynamically Generated Color - - /// Returns the version of the current color that results from the specified - /// traits. - public func resolvedColor(with traitCollection: TraitCollection) -> Color { - guard case let .func(body) = self.value else { return self } - return body(traitCollection) - } -} - -extension COLORREF { - fileprivate init(red r: Double, green g: Double, blue b: Double) { - self = 0 - | (DWORD((b * 255.0).rounded(.toNearestOrAwayFromZero)) << 16) - | (DWORD((g * 255.0).rounded(.toNearestOrAwayFromZero)) << 8) - | (DWORD((r * 255.0).rounded(.toNearestOrAwayFromZero)) << 0) - } -} - -extension Color { - internal var COLORREF: COLORREF { - switch self.value { - case .rgba(let r, let g, let b, _): - return WinSDK.COLORREF(red: r, green: g, blue: b) - case .hsba(let h, let s, let b, _): - func f(_ n: Double) -> Double { - let k = ucrt.fmod(n + (6.0 * h), 6.0) - return b - b * s * max(0, min(k, 4 - k, 1)) - } - - return WinSDK.COLORREF(red: f(5.0), green: f(3.0), blue: f(1.0)) - case .gray(let w, _): - return WinSDK.COLORREF(red: w * 255.0, green: w * 255.0, blue: w * 255.0) - case .func: - return self.resolvedColor(with: TraitCollection.current).COLORREF - } - } -} - -extension Color: _ExpressibleByColorLiteral { - public init(_colorLiteralRed red: Float, green: Float, blue: Float, - alpha: Float) { - self.init(red: Double(red), green: Double(green), blue: Double(blue), - alpha: Double(alpha)) - } -} - -extension Color: Equatable { - public static func ==(lhs: Color, rhs: Color) -> Bool { - // TODO(compnerd) make this more accurate - return lhs.COLORREF == rhs.COLORREF - } -} - -extension Color: Hashable { - public func hash(into hasher: inout Hasher) { - hasher.combine(self.value) - } -} - -extension Color { - internal init(color: COLORREF) { - self.init(red: Int(GetRValue(color)), green: Int(GetGValue(color)), - blue: Int(GetBValue(color))) - } -} - -extension Color { - internal init(red: Int, green: Int, blue: Int, alpha: Double = 1.0) { - self.init(red: Double(red) / 255.0, green: Double(green) / 255.0, - blue: Double(blue) / 255.0, alpha: Double(alpha)) - } -} - -// MARK - Standard Colors - -extension Color { - // MARK - Adaptable Colors - - /// A blue color that automatically adapts to the current trait environment. - public static var systemBlue: Color { - Color(dynamicProvider: { - switch ($0.accessibilityContrast, $0.userInterfaceStyle) { - case (.unspecified, _), (_, .unspecified): - log.warning("unable to query contrast or color scheme") - fallthrough - case (.normal, .light): - return Color(red: 0, green: 122, blue: 255) - case (.normal, .dark): - return Color(red: 10, green: 132, blue: 255) - case (.high, .light): - return Color(red: 0, green: 64, blue: 221) - case (.high, .dark): - return Color(red: 64, green: 156, blue: 255) - } - }) - } - - /// A brown color that automatically adapts to the current trait environment. - public static var systemBrown: Color { - fatalError("\(#function) not yet implemented") - } - - /// A green color that automatically adapts to the current trait environment. - public static var systemGreen: Color { - Color(dynamicProvider: { - switch ($0.accessibilityContrast, $0.userInterfaceStyle) { - case (.unspecified, _), (_, .unspecified): - log.warning("unable to query contrast or color scheme") - fallthrough - case (.normal, .light): - return Color(red: 52, green: 199, blue: 89) - case (.normal, .dark): - return Color(red: 48, green: 209, blue: 88) - case (.high, .light): - return Color(red: 36, green: 138, blue: 61) - case (.high, .dark): - return Color(red: 48, green: 219, blue: 91) - } - }) - } - - /// An indigo color that automatically adapts to the current trait - /// environment. - public static var systemIndigo: Color { - Color(dynamicProvider: { - switch ($0.accessibilityContrast, $0.userInterfaceStyle) { - case (.unspecified, _), (_, .unspecified): - log.warning("unable to query contrast or color scheme") - fallthrough - case (.normal, .light): - return Color(red: 88, green: 86, blue: 214) - case (.normal, .dark): - return Color(red: 94, green: 92, blue: 230) - case (.high, .light): - return Color(red: 54, green: 52, blue: 163) - case (.high, .dark): - return Color(red: 125, green: 122, blue: 255) - } - }) - } - - /// An orange color that automatically adapts to the current trait - /// environment. - public static var systemOrange: Color { - Color(dynamicProvider: { - switch ($0.accessibilityContrast, $0.userInterfaceStyle) { - case (.unspecified, _), (_, .unspecified): - log.warning("unable to query contrast or color scheme") - fallthrough - case (.normal, .light): - return Color(red: 255, green: 149, blue: 0) - case (.normal, .dark): - return Color(red: 255, green: 159, blue: 10) - case (.high, .light): - return Color(red: 201, green: 52, blue: 0) - case (.high, .dark): - return Color(red: 255, green: 179, blue: 64) - } - }) - } - - /// A pink color that automatically adapts to the current trait environment. - public static var systemPink: Color { - Color(dynamicProvider: { - switch ($0.accessibilityContrast, $0.userInterfaceStyle) { - case (.unspecified, _), (_, .unspecified): - log.warning("unable to query contrast or color scheme") - fallthrough - case (.normal, .light): - return Color(red: 255, green: 45, blue: 85) - case (.normal, .dark): - return Color(red: 255, green: 55, blue: 95) - case (.high, .light): - return Color(red: 211, green: 15, blue: 69) - case (.high, .dark): - return Color(red: 255, green: 100, blue: 130) - } - }) - } - - /// A purple color that automatically adapts to the current trait environment. - public static var systemPurple: Color { - Color(dynamicProvider: { - switch ($0.accessibilityContrast, $0.userInterfaceStyle) { - case (.unspecified, _), (_, .unspecified): - log.warning("unable to query contrast or color scheme") - fallthrough - case (.normal, .light): - return Color(red: 175, green: 82, blue: 222) - case (.normal, .dark): - return Color(red: 191, green: 90, blue: 242) - case (.high, .light): - return Color(red: 137, green: 68, blue: 171) - case (.high, .dark): - return Color(red: 218, green: 143, blue: 255) - } - }) - } - - /// A red color that automatically adapts to the current trait environment. - public static var systemRed: Color { - Color(dynamicProvider: { - switch ($0.accessibilityContrast, $0.userInterfaceStyle) { - case (.unspecified, _), (_, .unspecified): - log.warning("unable to query contrast or color scheme") - fallthrough - case (.normal, .light): - return Color(red: 255, green: 59, blue: 48) - case (.normal, .dark): - return Color(red: 255, green: 69, blue: 58) - case (.high, .light): - return Color(red: 215, green: 0, blue: 21) - case (.high, .dark): - return Color(red: 255, green: 105, blue: 97) - } - }) - } - - /// A teal color that automatically adapts to the current trait environment. - public static var systemTeal: Color { - Color(dynamicProvider: { - switch ($0.accessibilityContrast, $0.userInterfaceStyle) { - case (.unspecified, _), (_, .unspecified): - log.warning("unable to query contrast or color scheme") - fallthrough - case (.normal, .light): - return Color(red: 90, green: 200, blue: 250) - case (.normal, .dark): - return Color(red: 100, green: 210, blue: 255) - case (.high, .light): - return Color(red: 0, green: 113, blue: 164) - case (.high, .dark): - return Color(red: 112, green: 215, blue: 255) - } - }) - } - - /// A yellow color that automatically adapts to the current trait environment. - public static var systemYellow: Color { - Color(dynamicProvider: { - switch ($0.accessibilityContrast, $0.userInterfaceStyle) { - case (.unspecified, _), (_, .unspecified): - log.warning("unable to query contrast or color scheme") - fallthrough - case (.normal, .light): - return Color(red: 255, green: 204, blue: 0) - case (.normal, .dark): - return Color(red: 255, green: 214, blue: 10) - case (.high, .light): - return Color(red: 178, green: 80, blue: 0) - case (.high, .dark): - return Color(red: 255, green: 212, blue: 38) - } - }) - } - - // MARK - Adaptable Grey Colors - - /// The standard base gray color that adapts to the environment. - public static var systemGray: Color { - Color(dynamicProvider: { - switch ($0.accessibilityContrast, $0.userInterfaceStyle) { - case (.unspecified, _), (_, .unspecified): - log.warning("unable to query contrast or color scheme") - fallthrough - case (.normal, .light): - return Color(red: 142, green: 142, blue: 147) - case (.normal, .dark): - return Color(red: 142, green: 142, blue: 147) - case (.high, .light): - return Color(red: 108, green: 108, blue: 112) - case (.high, .dark): - return Color(red: 174, green: 174, blue: 178) - } - }) - } - - /// A second-level shade of grey that adapts to the environment. - public static var systemGray2: Color { - Color(dynamicProvider: { - switch ($0.accessibilityContrast, $0.userInterfaceStyle) { - case (.unspecified, _), (_, .unspecified): - log.warning("unable to query contrast or color scheme") - fallthrough - case (.normal, .light): - return Color(red: 174, green: 174, blue: 178) - case (.normal, .dark): - return Color(red: 99, green: 99, blue: 102) - case (.high, .light): - return Color(red: 142, green: 142, blue: 147) - case (.high, .dark): - return Color(red: 124, green: 124, blue: 128) - } - }) - } - - /// A third-level shade of grey that adapts to the environment. - public static var systemGray3: Color { - Color(dynamicProvider: { - switch ($0.accessibilityContrast, $0.userInterfaceStyle) { - case (.unspecified, _), (_, .unspecified): - log.warning("unable to query contrast or color scheme") - fallthrough - case (.normal, .light): - return Color(red: 199, green: 199, blue: 204) - case (.normal, .dark): - return Color(red: 72, green: 72, blue: 74) - case (.high, .light): - return Color(red: 174, green: 174, blue: 178) - case (.high, .dark): - return Color(red: 84, green: 84, blue: 86) - } - }) - } - - /// A fourth-level shade of grey that adapts to the environment. - public static var systemGray4: Color { - Color(dynamicProvider: { - switch ($0.accessibilityContrast, $0.userInterfaceStyle) { - case (.unspecified, _), (_, .unspecified): - log.warning("unable to query contrast or color scheme") - fallthrough - case (.normal, .light): - return Color(red: 209, green: 209, blue: 214) - case (.normal, .dark): - return Color(red: 58, green: 58, blue: 60) - case (.high, .light): - return Color(red: 188, green: 188, blue: 192) - case (.high, .dark): - return Color(red: 68, green: 68, blue: 70) - } - }) - } - - /// A fifth-level shade of grey that adapts to the environment. - public static var systemGray5: Color { - Color(dynamicProvider: { - switch ($0.accessibilityContrast, $0.userInterfaceStyle) { - case (.unspecified, _), (_, .unspecified): - log.warning("unable to query contrast or color scheme") - fallthrough - case (.normal, .light): - return Color(red: 229, green: 229, blue: 234) - case (.normal, .dark): - return Color(red: 44, green: 44, blue: 46) - case (.high, .light): - return Color(red: 216, green: 216, blue: 220) - case (.high, .dark): - return Color(red: 54, green: 54, blue: 56) - } - }) - } - - /// A sixth-level shade of grey that adapts to the environment. - public static var systemGray6: Color { - Color(dynamicProvider: { - switch ($0.accessibilityContrast, $0.userInterfaceStyle) { - case (.unspecified, _), (_, .unspecified): - log.warning("unable to query contrast or color scheme") - fallthrough - case (.normal, .light): - return Color(red: 242, green: 242, blue: 247) - case (.normal, .dark): - return Color(red: 28, green: 28, blue: 30) - case (.high, .light): - return Color(red: 235, green: 235, blue: 240) - case (.high, .dark): - return Color(red: 36, green: 36, blue: 38) - } - }) - } - - // MARK - Transparent Color - - /// A color object with grayscale and alpha values that are both 0.0. - public static var clear: Color { - Color(white: 0.0, alpha: 0.0) - } - - // MARK - Fixed Colors - - /// A color object in the sRGB color space with a grayscale value of 0.0 and - /// an alpha value of 1.0. - public static var black: Color { - Color(white: 0.0, alpha: 1.0) - } - - /// A color object with RGB values of 0.0, 0.0, and 1.0, and an alpha value of - /// 1.0. - public static var blue: Color { - Color(red: 0.0, green: 0.0, blue: 1.0, alpha: 1.0) - } - - /// A color object with RGB values of 0.6, 0.4, and 0.2, and an alpha value of - /// 1.0. - public static var brown: Color { - Color(red: 0.6, green: 0.4, blue: 0.2, alpha: 1.0) - } - - /// A color object with RGB values of 0.0, 1.0, and 1.0, and an alpha value of - /// 1.0. - public static var cyan: Color { - Color(red: 0.0, green: 1.0, blue: 1.0, alpha: 1.0) - } - - /// A color object with a grayscale value of 1/3 and an alpha value of 1.0. - public static var darkGray: Color { - Color(white: 1.0 / 3.0, alpha: 1.0) - } - - /// A color object with a grayscale value of 0.5 and an alpha value of 1.0. - public static var gray: Color { - Color(white: 0.5, alpha: 1.0) - } - - /// A color object with RGB values of 0.0, 1.0, and 0.0, and an alpha value of - /// 1.0. - public static var green: Color { - Color(red: 0.0, green: 1.0, blue: 0.0, alpha: 1.0) - } - - /// A color object with a grayscale value of 2/3 and an alpha value of 1.0. - public static var lightGray: Color { - Color(white: 2.0 / 3.0, alpha: 1.0) - } - - /// A color object with RGB values of 1.0, 0.0, and 1.0, and an alpha value of - /// 1.0. - public static var magenta: Color { - Color(red: 1.0, green: 0.0, blue: 1.0, alpha: 1.0) - } - - /// A color object with RGB values of 1.0, 0.5, and 0.0, and an alpha value of - /// 1.0. - public static var orange: Color { - Color(red: 1.0, green: 0.5, blue: 0.0, alpha: 1.0) - } - - /// A color object with RGB values of 0.5, 0.0, and 0.5, and an alpha value of - /// 1.0. - public static var purple: Color { - Color(red: 0.5, green: 0.0, blue: 0.5, alpha: 1.0) - } - - /// A color object with RGB values of 1.0, 0.0, and 0.0, and an alpha value of - /// 1.0. - public static var red: Color { - Color(red: 1.0, green: 0.0, blue: 0.0, alpha: 1.0) - } - - /// A color object with a grayscale value of 1.0 and an alpha value of 1.0. - public static var white: Color { - Color(white: 1.0, alpha: 1.0) - } - - /// A color object with RGB values of 1.0, 1.0, and 0.0, and an alpha value of - /// 1.0. - public static var yellow: Color { - Color(red: 1.0, green: 1.0, blue: 0.0, alpha: 1.0) - } -} - -// MARK - UI Element Colors - -extension Color { - // MARK - Label Colors - - /// The Color for text labels that contain primary content. - public static var label: Color { - Color(dynamicProvider: { - switch ($0.accessibilityContrast, $0.userInterfaceStyle) { - case (.unspecified, _), (_, .unspecified): - log.warning("unable to query contrast or color scheme") - fallthrough - case (_, .light): - return Color(white: 0.0, alpha: 1.0) - case (_, .dark): - return Color(white: 1.0, alpha: 1.0) - } - }) - } - - /// The color for text labels that contain secondary content. - public static var secondaryLabel: Color { - Color(dynamicProvider: { - switch ($0.accessibilityContrast, $0.userInterfaceStyle) { - case (.unspecified, _), (_, .unspecified): - log.warning("unable to query contrast or color scheme") - fallthrough - case (.normal, .light): - return Color(red: 60, green: 60, blue: 67, alpha: 0.60) - case (.high, .light): - return Color(red: 60, green: 60, blue: 67, alpha: 0.68) - case (.normal, .dark): - return Color(red: 235, green: 235, blue: 245, alpha: 0.60) - case (.high, .dark): - return Color(red: 235, green: 235, blue: 245, alpha: 0.68) - } - }) - } - - /// The color for text labels that contain tertiary content. - public static var tertiaryLabel: Color { - Color(dynamicProvider: { - switch ($0.accessibilityContrast, $0.userInterfaceStyle) { - case (.unspecified, _), (_, .unspecified): - log.warning("unable to query contrast or color scheme") - fallthrough - case (.normal, .light): - return Color(red: 60.0, green: 60, blue: 67, alpha: 0.30) - case (.high, .light): - return Color(red: 60.0, green: 60, blue: 67, alpha: 0.38) - case (.normal, .dark): - return Color(red: 235, green: 235, blue: 245, alpha: 0.30) - case (.high, .dark): - return Color(red: 235, green: 235, blue: 245, alpha: 0.38) - } - }) - } - - /// The color for text labels that contain quatenary content. - public static var quatenaryLabel: Color { - Color(dynamicProvider: { - switch ($0.accessibilityContrast, $0.userInterfaceStyle) { - case (.unspecified, _), (_, .unspecified): - log.warning("unable to query contrast or color scheme") - fallthrough - case (.normal, .light): - return Color(red: 60, green: 60, blue: 67, alpha: 0.18) - case (.high, .light): - return Color(red: 60, green: 60, blue: 67, alpha: 0.26) - case (.normal, .dark): - return Color(red: 235, green: 235, blue: 245, alpha: 0.18) - case (.high, .dark): - return Color(red: 235, green: 235, blue: 245, alpha: 0.26) - } - }) - } - - // MARK - Fill Colors - - /// An overlay fill color for thin and small shapes. - public static var systemFill: Color { - Color(dynamicProvider: { - switch ($0.accessibilityContrast, $0.userInterfaceStyle) { - case (.unspecified, _), (_, .unspecified): - log.warning("unable to query contrast or color scheme") - fallthrough - case (.normal, .light): - return Color(red: 120, green: 120, blue: 128, alpha: 0.20) - case (.high, .light): - return Color(red: 120, green: 120, blue: 128, alpha: 0.28) - case (.normal, .dark): - return Color(red: 120, green: 120, blue: 128, alpha: 0.36) - case (.high, .dark): - return Color(red: 120, green: 120, blue: 128, alpha: 0.44) - } - }) - } - - /// An overlay fill color for medium-size shapes. - public static var secondarySystemFill: Color { - Color(dynamicProvider: { - switch ($0.accessibilityContrast, $0.userInterfaceStyle) { - case (.unspecified, _), (_, .unspecified): - log.warning("unable to query contrast or color scheme") - fallthrough - case (.normal, .light): - return Color(red: 120, green: 120, blue: 128, alpha: 0.16) - case (.high, .light): - return Color(red: 120, green: 120, blue: 128, alpha: 0.24) - case (.normal, .dark): - return Color(red: 120, green: 120, blue: 128, alpha: 0.32) - case (.high, .dark): - return Color(red: 120, green: 120, blue: 128, alpha: 0.40) - } - }) - } - - /// An overlay fill color for large shapes. - public static var tertiarySystemFill: Color { - Color(dynamicProvider: { - switch ($0.accessibilityContrast, $0.userInterfaceStyle) { - case (.unspecified, _), (_, .unspecified): - log.warning("unable to query contrast or color scheme") - fallthrough - case (.normal, .light): - return Color(red: 118, green: 118, blue: 128, alpha: 0.12) - case (.high, .light): - return Color(red: 118, green: 118, blue: 128, alpha: 0.20) - case (.normal, .dark): - return Color(red: 118, green: 118, blue: 128, alpha: 0.24) - case (.high, .dark): - return Color(red: 118, green: 118, blue: 128, alpha: 0.32) - } - }) - } - - /// An overlay fill color for large areas that contain complex content. - public static var quaternarySystemFill: Color { - Color(dynamicProvider: { - switch ($0.accessibilityContrast, $0.userInterfaceStyle) { - case (.unspecified, _), (_, .unspecified): - log.warning("unable to query contrast or color scheme") - fallthrough - case (.normal, .light): - return Color(red: 116, green: 116, blue: 128, alpha: 0.08) - case (.high, .light): - return Color(red: 116, green: 116, blue: 128, alpha: 0.16) - case (.normal, .dark): - return Color(red: 118, green: 118, blue: 128, alpha: 0.18) - case (.high, .dark): - return Color(red: 118, green: 118, blue: 128, alpha: 0.26) - } - }) - } - - // MARK - Text Colors - - /// The color for placeholder text in controls or text views. - public static var placeholderText: Color { - Color(dynamicProvider: { - switch ($0.accessibilityContrast, $0.userInterfaceStyle) { - case (.unspecified, _), (_, .unspecified): - log.warning("unable to query contrast or color scheme") - fallthrough - case (.normal, .light): - return Color(red: 60, green: 60, blue: 67, alpha: 0.30) - case (.high, .light): - return Color(red: 60, green: 60, blue: 67, alpha: 0.38) - case (.normal, .dark): - return Color(red: 235, green: 235, blue: 245, alpha: 0.30) - case (.high, .dark): - return Color(red: 235, green: 235, blue: 245, alpha: 0.38) - } - }) - } - - /// Standard Content Background Colors - /// - /// Use these colors for standard table views and designs that have a white - /// primary background in a light environment. - - /// The color for the main background of your interface. - public static var systemBackground: Color { - Color(dynamicProvider: { - switch ($0.accessibilityContrast, $0.userInterfaceStyle) { - case (.unspecified, _), (_, .unspecified): - log.warning("unable to query contrast or color scheme") - fallthrough - case (.normal, .light): - return Color(white: 1.0, alpha: 1.0) - case (.high, .light): - return Color(white: 1.0, alpha: 1.0) - case (.normal, .dark): - return Color(white: 0.0, alpha: 1.0) - case (.high, .dark): - return Color(white: 0.0, alpha: 1.0) - } - }) - } - - /// The color for content layered on top of the main background. - public static var secondarySystemBackground: Color { - Color(dynamicProvider: { - switch ($0.accessibilityContrast, $0.userInterfaceStyle) { - case (.unspecified, _), (_, .unspecified): - log.warning("unable to query contrast or color scheme") - fallthrough - case (.normal, .light): - return Color(red: 242, green: 242, blue: 247, alpha: 1.0) - case (.high, .light): - return Color(red: 235, green: 235, blue: 240, alpha: 1.0) - case (.normal, .dark): - return Color(red: 28, green: 28, blue: 30, alpha: 1.0) - case (.high, .dark): - return Color(red: 36, green: 36, blue: 38, alpha: 1.0) - } - }) - } - - /// The color for content layered on top of secondary backgrounds. - public static var tertiarySystemBackground: Color { - Color(dynamicProvider: { - switch ($0.accessibilityContrast, $0.userInterfaceStyle) { - case (.unspecified, _), (_, .unspecified): - log.warning("unable to query contrast or color scheme") - fallthrough - case (.normal, .light): - return Color(white: 1.0, alpha: 1.0) - case (.high, .light): - return Color(white: 1.0, alpha: 1.0) - case (.normal, .dark): - return Color(red: 44, green: 44, blue: 46, alpha: 1.0) - case (.high, .dark): - return Color(red: 54, green: 54, blue: 56, alpha: 1.0) - } - }) - } - - /// Grouped Content Background Colors - /// - /// Use these colors for grouped content, including table views and - /// platter-based designs. - - /// The color for the main background of your grouped interface. - public static var systemGroupedBackground: Color { - Color(dynamicProvider: { - switch ($0.accessibilityContrast, $0.userInterfaceStyle) { - case (.unspecified, _), (_, .unspecified): - log.warning("unable to query contrast or color scheme") - fallthrough - case (.normal, .light): - return Color(red: 242, green: 242, blue: 247, alpha: 1.0) - case (.high, .light): - return Color(red: 235, green: 235, blue: 240, alpha: 1.0) - case (.normal, .dark): - return Color(white: 0.0, alpha: 1.0) - case (.high, .dark): - return Color(white: 0.0, alpha: 1.0) - } - }) - } - - /// The color for content layered on top of the main background of your - /// grouped interface. - public static var secondarySystemGroupedBackground: Color { - Color(dynamicProvider: { - switch ($0.accessibilityContrast, $0.userInterfaceStyle) { - case (.unspecified, _), (_, .unspecified): - log.warning("unable to query contrast or color scheme") - fallthrough - case (.normal, .light): - return Color(red: 242, green: 242, blue: 247, alpha: 1.0) - case (.high, .light): - return Color(white: 1.0, alpha: 1.0) - case (.normal, .dark): - return Color(red: 28, green: 28, blue: 30, alpha: 1.0) - case (.high, .dark): - return Color(red: 36, green: 36, blue: 38, alpha: 1.0) - } - }) - } - - /// The color for content layered on top of secondary backgrounds of your - /// grouped interface. - public static var tertiarySystemGroupedBackground: Color { - Color(dynamicProvider: { - switch ($0.accessibilityContrast, $0.userInterfaceStyle) { - case (.unspecified, _), (_, .unspecified): - log.warning("unable to query contrast or color scheme") - fallthrough - case (.normal, .light): - return Color(red: 242, green: 242, blue: 247, alpha: 1.0) - case (.high, .light): - return Color(red: 235, green: 235, blue: 240, alpha: 1.0) - case (.normal, .dark): - return Color(red: 44, green: 44, blue: 46, alpha: 1.0) - case (.high, .dark): - return Color(red: 54, green: 54, blue: 56, alpha: 1.0) - } - }) - } - - // MARK - Separator Colors - - /// The color for thin borders or divider lines that allows some underlying - /// content to be visible. - public static var separator: Color { - Color(dynamicProvider: { - switch ($0.accessibilityContrast, $0.userInterfaceStyle) { - case (.unspecified, _), (_, .unspecified): - log.warning("unable to query contrast or color scheme") - fallthrough - case (.normal, .light): - return Color(red: 60, green: 60, blue: 67, alpha: 0.29) - case (.high, .light): - return Color(red: 60, green: 60, blue: 67, alpha: 0.37) - case (.normal, .dark): - return Color(red: 84, green: 84, blue: 88, alpha: 0.60) - case (.high, .dark): - return Color(red: 84, green: 84, blue: 88, alpha: 0.70) - } - }) - } - - /// The color for borders or divider lines that hides any underlying content. - public static var opaqueSeparator: Color { - Color(dynamicProvider: { - switch ($0.accessibilityContrast, $0.userInterfaceStyle) { - case (.unspecified, _), (_, .unspecified): - log.warning("unable to query contrast or color scheme") - fallthrough - case (.normal, .light): - return Color(red: 198, green: 198, blue: 200, alpha: 1.0) - case (.high, .light): - return Color(red: 198, green: 198, blue: 200, alpha: 1.0) - case (.normal, .dark): - return Color(red: 56, green: 56, blue: 58, alpha: 1.0) - case (.high, .dark): - return Color(red: 56, green: 56, blue: 58, alpha: 1.0) - } - }) - } - - // MARK - Link Color - - /// The color for links. - public static var link: Color { - Color(dynamicProvider: { - switch ($0.accessibilityContrast, $0.userInterfaceStyle) { - case (.unspecified, _), (_, .unspecified): - log.warning("unable to query contrast or color scheme") - fallthrough - case (.normal, .light): - return Color(red: 0, green: 122, blue: 255, alpha: 1.0) - case (.high, .light): - return Color(red: 0, green: 122, blue: 255, alpha: 1.0) - case (.normal, .dark): - return Color(red: 9, green: 132, blue: 255, alpha: 1.0) - case (.high, .dark): - return Color(red: 9, green: 132, blue: 255, alpha: 1.0) - } - }) - } - - // MARK - Nonadaptable Colors - - /// The nonadaptable system color for text on a light background. - public static var darkText: Color { - return Color(white: 0.0, alpha: 1.0) - } - - /// The nonadaptable system color for text on a dark background. - public static var lightText: Color { - return Color(white: 1.0, alpha: 0.6) - } -} diff --git a/Sources/SwiftWin32/Focus-Based Navigation/FocusAnimationCoordinator.swift b/Sources/SwiftWin32/Focus-Based Navigation/FocusAnimationCoordinator.swift deleted file mode 100644 index c8de4cfb..00000000 --- a/Sources/SwiftWin32/Focus-Based Navigation/FocusAnimationCoordinator.swift +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import struct Foundation.TimeInterval - -/// Information about focusing animations being performed by the system. -public protocol FocusAnimationContext { - // MARK - Getting the Animation Attributes - - /// The duration (measured in seconds) of the focus animation. - var duration: TimeInterval { get } -} - -/// A coordinator of focus-related animations during a focus update. -public class FocusAnimationCoordinator { - // MARK - Adding Animations to Focus Updates - - /// Runs the specified set of animations together with the system animations - /// for adding focus to an item. - public func addCoordinatedFocusingAnimations(_ animations: ((FocusAnimationContext) -> Void)?, - completion: (() -> Void)? = nil) { - } - - /// Runs the specified set of animations together with the system animations - /// for removing focus from an item. - public func addCoordinatedUnfocusingAnimations(_ animations: ((FocusAnimationContext) -> Void)?, - completion: (() -> Void)? = nil) { - } - - /// Specifies the animations to coordinate with the active focus animation. - public func addCoordinatedAnimations(_ animations: (() -> Void)?, - completion: (() -> Void)? = nil) { - } -} diff --git a/Sources/SwiftWin32/Focus-Based Navigation/FocusEnvironment.swift b/Sources/SwiftWin32/Focus-Based Navigation/FocusEnvironment.swift deleted file mode 100644 index fed6ceaf..00000000 --- a/Sources/SwiftWin32/Focus-Based Navigation/FocusEnvironment.swift +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -/// An identifier for a focus-related sound. -public struct FocusSoundIdentifier: Equatable, Hashable, RawRepresentable { - public typealias RawValue = String - - public let rawValue: RawValue - - public init(rawValue: RawValue) { - self.rawValue = rawValue - } -} - -extension FocusSoundIdentifier { - public init(_ rawValue: String) { - self.rawValue = rawValue - } -} - -extension FocusSoundIdentifier { - /// The identifier for the default system sound to play during focus updates. - public static var `default`: FocusSoundIdentifier { - FocusSoundIdentifier(rawValue: "UIFocusSoundIdentifierDefault") - } - - /// The identifier for disabling sound during a focus update. - public static var none: FocusSoundIdentifier { - FocusSoundIdentifier(rawValue: "UIFocusSoundIdentifierNone") - } -} - -/// A set of methods that define the focus behavior for a branch of the view -/// hierarchy. -public protocol FocusEnvironment: AnyObject { - // MARK - Requesting Focus Update - - /// Submits a request to the focus engine for a focus update in this - /// environment. - func setNeedsFocusUpdate() - - /// Tells the focus engine to force a focus update immediately. - func updateFocusIfNeeded() - - // MARK - Validating Focus Movements - - /// Returns a boolean value indicating whether the focus engine should allow - /// the focus update described by the specified context to occur. - func shouldUpdateFocus(in context: FocusUpdateContext) -> Bool - - // MARK - Responding to Focus Updates - - /// Called immediately after the system updates the focus to a new view. - func didUpdateFocus(in context: FocusUpdateContext, - with coordinator: FocusAnimationCoordinator) - - // MARK - Controlling User Generated Focus Movements - - /// An array of focus environments, ordered by priority, to which this - /// environment prefers focus to be directed during a focus update. - var preferredFocusEnvironments: [FocusEnvironment] { get } - - // MARK - Getting the Sound to Play During Updates - - /// Asks the delegate for the identifier of the sound to play when the object - /// gains focus. - func soundIdentifierForFocusUpdate(in context: FocusUpdateContext) - -> FocusSoundIdentifier? - - // MARK - Checking the Ancestry of the Environment - - /// Returns a boolean value indicating whether the focus environment contains - /// the specified environment. - func contains(_ environment: FocusEnvironment) -> Bool - - /// The parent focus environment for this environment. - /* weak */ var parentFocusEnvironment: FocusEnvironment? { get } - - /// The container for the child focus items in this focus environment. - var focusItemContainer: FocusItemContainer? { get } - - // MARK - - - var focusGroupIdentifier: String? { get } -} - -extension FocusEnvironment { - public func soundIdentifierForFocusUpdate(in context: FocusUpdateContext) - -> FocusSoundIdentifier? { - return nil - } -} - -extension FocusEnvironment { - public var focusGroupIdentifier: String? { nil } -} diff --git a/Sources/SwiftWin32/Focus-Based Navigation/FocusItem.swift b/Sources/SwiftWin32/Focus-Based Navigation/FocusItem.swift deleted file mode 100644 index 362cef67..00000000 --- a/Sources/SwiftWin32/Focus-Based Navigation/FocusItem.swift +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -#if swift(>=5.7) -import CoreGraphics -#endif - -/// An object that can become focused. -public protocol FocusItem: FocusEnvironment { - // MARK - Determining Focusability - - /// A boolean value that indicates whether the item can become focused. - var canBecomeFocused: Bool { get } - - /// A boolean value indicating whether the item is currently focused. - var isFocused: Bool { get } - - // MARK - Retrieving the Item Frame - - /// The geometric frame of the item. - var frame: Rect { get } - - // MARK - Providing Movement Hints - - func didHintFocusMovement(_ hint: FocusMovementHint) -} - -extension FocusItem { - public var isFocused: Bool { false } -} - -extension FocusItem { - public func didHintFocusMovement(_ hint: FocusMovementHint) { - } -} diff --git a/Sources/SwiftWin32/Focus-Based Navigation/FocusItemContainer.swift b/Sources/SwiftWin32/Focus-Based Navigation/FocusItemContainer.swift deleted file mode 100644 index 1d8a025c..00000000 --- a/Sources/SwiftWin32/Focus-Based Navigation/FocusItemContainer.swift +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -#if swift(>=5.7) -import CoreGraphics -#endif - -/// The container responsible for providing geometric context to focus items -/// within a given focus environment. -public protocol FocusItemContainer { - // MARK - Retrieving Focus Items - - /// Retrieves all of the focus items within this container that intersect with - /// the provided rectangle. - func focusItems(in rect: Rect) -> [FocusItem] - - /// The coordinate space of the focus items contained in the focus item - /// container. - var coordinateSpace: CoordinateSpace { get } -} diff --git a/Sources/SwiftWin32/Focus-Based Navigation/FocusMovementHint.swift b/Sources/SwiftWin32/Focus-Based Navigation/FocusMovementHint.swift deleted file mode 100644 index b3c43dee..00000000 --- a/Sources/SwiftWin32/Focus-Based Navigation/FocusMovementHint.swift +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -#if swift(>=5.7) -import CoreAnimation -import CoreGraphics -#endif - -/// Provides movement hint information for the focused item. -public class FocusMovementHint { - // MARK - - - internal init () { - fatalError("\(#function) not yet implemented") - } - - // MARK - Moving Focus - - /// A vector representing how close focus is to moving to another item in the - /// swiped direction. - public private(set) var movementDirection: Vector - - // MARK - Transforming a Hint - - /// A 3D transform that contains the combined transformations of perspective, - /// rotation, and translation. - public private(set) var interactionTransform: Transform3D - - /// A 3D transform that represents a perspective matrix to be applied to match - /// the system interaction hinting. - public private(set) var perspectiveTransform: Transform3D - - /// A vector to apply to a transform to match system interaction hinting. - public private(set) var rotation: Vector - - /// A vector to apply to a transform to match system interaction hinting. - public private(set) var translation: Vector -} diff --git a/Sources/SwiftWin32/Focus-Based Navigation/FocusUpdateContext.swift b/Sources/SwiftWin32/Focus-Based Navigation/FocusUpdateContext.swift deleted file mode 100644 index fd2a0f7f..00000000 --- a/Sources/SwiftWin32/Focus-Based Navigation/FocusUpdateContext.swift +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import class Foundation.NSNotification - -/// The general type of an event. -public struct FocusHeading: OptionSet { - public typealias RawValue = UInt - - public let rawValue: RawValue - - public init(rawValue: RawValue) { - self.rawValue = rawValue - } -} - -extension FocusHeading { - internal static var none: FocusHeading { - FocusHeading(rawValue: 0 << 0) - } - - /// The focus update is heading in the up direction. - public static var up: FocusHeading { - FocusHeading(rawValue: 1 << 0) - } - - /// The focus update is heading in the down direction. - public static var down: FocusHeading { - FocusHeading(rawValue: 1 << 1) - } - - /// The focus update is heading in the left direction. - public static var left: FocusHeading { - FocusHeading(rawValue: 1 << 2) - } - - /// The focus update is heading in the right direction. - public static var right: FocusHeading { - FocusHeading(rawValue: 1 << 3) - } - - /// The focus update is heading to the next item. - public static var next: FocusHeading { - FocusHeading(rawValue: 1 << 4) - } - - /// The focus update is heading to the previous item. - public static var previous: FocusHeading { - FocusHeading(rawValue: 1 << 5) - } -} - -/// An object that provides information relevant to a specific focus update from -/// one view to another. -public class FocusUpdateContext { - // MARK - Locating Focus Direction - - /// The view that was focused before the focus update. - public private(set) weak var previouslyFocusedView: View? - - /// The view that takes the focus after the focus update. - public private(set) weak var nextFocusedView: View? - - /// The heading in which the focus update is occurring. - public private(set) var focusHeading: FocusHeading = .none - - // MARK - Getting Related Focus Items - - /// The item that was focused before the update. - public private(set) weak var previouslyFocusedItem: FocusItem? - - /// The item to be focused after the update. - public private(set) weak var nextFocusedItem: FocusItem? - - // MARK - Responding to Focus-Related Keys and Notifications - - /// The focus for the UI has been updated. - public static var didUpdateNotification: NSNotification.Name { - NSNotification.Name(rawValue: "UIFocusUpdateContextDidUpdateNotification") - } - - /// The focus failed to move to another item. - public static var movementDidFailNotification: NSNotification.Name { - NSNotification.Name(rawValue: "UIFocusUpdateContextMovementDidFailNotification") - } - - /// Updates the animation coordinator. - public static var animationCoordinatorUserInfoKey: String { - "UIFocusUpdateContextAnimationCoordinatorUserInfoKey" - } - - /// Updates the context key. - public static var focusUpdateContextUserInfoKey: String { - "UIFocusUpdateContextFocusUpdateContextUserInfoKey" - } -} diff --git a/Sources/SwiftWin32/Images and PDF/Image.swift b/Sources/SwiftWin32/Images and PDF/Image.swift deleted file mode 100644 index d5945651..00000000 --- a/Sources/SwiftWin32/Images and PDF/Image.swift +++ /dev/null @@ -1,259 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import WinSDK -import SwiftCOM - -#if swift(>=5.7) -import CoreGraphics -#endif - -private let WICImagingFactory: SwiftCOM.IWICImagingFactory? = - try? IWICImagingFactory.CreateInstance(class: CLSID_WICImagingFactory) - -extension Image { - /// A configuration object that contains the traits that the system uses when - /// selecting the current image variant. - public class Configuration { - // MARK - Modifying a Configuration Object - - /// Returns a configuration object that applies the specified configuration - /// values on top of the current object's values. - public func applying(_ otherConfiguration: Image.Configuration?) -> Self { - fatalError("\(#function) not yet implemented") - } - - /// Returns a new configuration object that merges the current traits with - /// the traits from the specified trait collection. - public func withTraitCollection(_ traitCollection: TraitCollection?) -> Self { - fatalError("\(#function) not yet implemented") - } - - // MARK - Getting the Configuration Traits - - /// The traits associated with the image configuration. - public private(set) var traitCollection: TraitCollection? - } -} - -extension Image { - /// Constants that indicate which weight variant of a symbol image to use. - public enum SymbolWeight: Int { - // MARK - Symbol Image Weights - - /// An unspecified symbol image weight. - case unspecified - - /// An ultralight weight. - case ultraLight - - /// A thin weight - case thin - - /// A light weight. - case light - - /// A regular weight. - case regular - - /// A medium weight. - case medium - - /// A semibold weight. - case semibold - - /// A bold weight. - case bold - - /// A heavy weight. - case heavy - - /// An ultra-heavy weight. - case black - } -} - -extension Image.SymbolWeight { - // MARK - Getting the Font Weight - - /// The font weight for the specified symbol weight. - public func fontWeight() -> Font.Weight { - fatalError("\(#function) not yet implemented") - } -} - -extension Image { - public enum SymbolScale: Int { - // MARK - Symbol Image Scales - - /// The default scale variant that matches the system usage. - case `default` - - /// An unspecified scale. - case unspecified - - /// The small variant of the symbol image. - case small - - /// The medium variant of the symbol image. - case medium - - /// The large variant of the symbol image. - case large - } -} - -extension Image { - /// An object that contains the specific font, size, style, and weight - /// attributes to apply to a symbol image. - public class SymbolConfiguration: Image.Configuration { - // MARK - Creating a Symbol Configuration Object - - /// Creates a configuration object with the specified point-size information. - public convenience init(pointSize: Double) { - self.init(pointSize: pointSize, weight: .regular) - } - - /// Creates a configuration object with the specified point-size and weight - /// information. - public convenience init(pointSize: Double, weight: Image.SymbolWeight) { - self.init(pointSize: pointSize, weight: .regular, scale: .default) - } - - /// Creates a configuration object with the specified point-size, weight, - /// and scale information. - public convenience init(pointSize: Double, weight: Image.SymbolWeight, - scale: Image.SymbolScale) { - fatalError("\(#function) not yet implemented") - } - - /// Creates a configuration object with the specified scale information. - public convenience init(scale: Image.SymbolScale) { - fatalError("\(#function) not yet implemented") - } - - /// Creates a configuration object with the specified font text style - /// information. - public convenience init(textStyle: Font.TextStyle) { - self.init(textStyle: textStyle, scale: .default) - } - - /// Creates a configuration object with the specified font text style and - /// scale information. - public convenience init(textStyle: Font.TextStyle, - scale: Image.SymbolScale) { - fatalError("\(#function) not yet implemented") - } - - /// Creates a configuration object with the specified weight information. - public convenience init(weight: Image.SymbolWeight) { - fatalError("\(#function) not yet implemented") - } - - /// Creates a configuration object with the specified font information. - public convenience init(font: Font) { - self.init(font: font, scale: .default) - } - - /// Creates a configuration object with the specified font and scale - /// information. - public convenience init(font: Font, scale: Image.SymbolScale) { - fatalError("\(#function) not yet implemented") - } - - // MARK - Getting an Unspecified Configuration - - /// A symbol configuration object that contains unspecified values for all - /// attributes. - public class var unspecified: Image.SymbolConfiguration { - fatalError("\(#function) not yet implemented") - } - - // MARK - Removing Configuration Attributes - - /// Returns a copy of the current symbol configuration object without - /// point-size and weight information. - public func configurationWithoutPointSizeAndWeight() -> Self { - fatalError("\(#function) not yet implemented") - } - - /// Returns a copy of the current symbol configuration object without scale - /// information. - public func configurationWithoutScale() -> Self { - fatalError("\(#function) not yet implemented") - } - - /// Returns a copy of the current symbol configuration object without font - /// text style information. - public func configurationWithoutTextStyle() -> Self { - fatalError("\(#function) not yet implemented") - } - - /// Returns a copy of the current symbol configuration object without weight - /// information. - public func configurationWithoutWeight() -> Self { - fatalError("\(#function) not yet implemented") - } - - // MARK - Comparing Symbol Image Configurations - - /// Returns a boolean value that indicates whether the configuration objects - /// are equivalent. - public func isEqual(to otherConfiguration: Image.SymbolConfiguration?) - -> Bool { - fatalError("\(#function) not yet implemented") - } - } -} - -/// An object that manages image data in your app. -public class Image { - private var WICBitmapDecoder: SwiftCOM.IWICBitmapDecoder? - private var WICBitmapFrame: SwiftCOM.IWICBitmapFrameDecode? - private var WICFormatConverter: SwiftCOM.IWICFormatConverter? - - internal var bitmap: SwiftCOM.IWICBitmapSource? { WICFormatConverter } - - // MARK - Creating and Initializing Image Objects - - /// Initializes and returns the image object with the contents of the - /// specified file. - public init?(contentsOfFile path: String) { - guard let WICImagingFactory = WICImagingFactory else { return nil } - - do { - self.WICBitmapDecoder = - try WICImagingFactory.CreateDecoderFromFilename(path, nil, GENERIC_READ, - WICDecodeMetadataCacheOnDemand) - - // TODO(compnerd) figure out how to handle multi-frame images - let frames = try self.WICBitmapDecoder?.GetFrameCount() - - self.WICBitmapFrame = try self.WICBitmapDecoder?.GetFrame(frames! - 1) - - self.WICFormatConverter = try WICImagingFactory.CreateFormatConverter() - try self.WICFormatConverter?.Initialize(WICBitmapFrame!, - GUID_WICPixelFormat32bppBGRA, - WICBitmapDitherTypeNone, nil, 0.0, - WICBitmapPaletteTypeCustom) - } catch { - log.error("\(#function): \(error)") - return nil - } - } - - // MARK - Getting the Image Size and Scale - - /// The scale factor of the image. - public var scale: Float { - 1.0 - } - - /// The logical dimensions, in points, for the image. - public var size: Size { - guard let ImageSize: (UINT, UINT) = try? self.WICBitmapFrame?.GetSize() else { - return .zero - } - return Size(width: Double(ImageSize.0), height: Double(ImageSize.1)) - } -} diff --git a/Sources/SwiftWin32/Keyboards and Input/TextInputTraits.swift b/Sources/SwiftWin32/Keyboards and Input/TextInputTraits.swift deleted file mode 100644 index 98eb3e5e..00000000 --- a/Sources/SwiftWin32/Keyboards and Input/TextInputTraits.swift +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -public protocol TextInputTraits { - /// Managing the Keyboard Behaviour - var isSecureTextEntry: Bool { get set } -} - -extension TextInputTraits { - public var isSecureTextEntry: Bool { - get { return false } - set { } - } -} diff --git a/Sources/SwiftWin32/Menus and Shortcuts/Action.swift b/Sources/SwiftWin32/Menus and Shortcuts/Action.swift deleted file mode 100644 index d61515d0..00000000 --- a/Sources/SwiftWin32/Menus and Shortcuts/Action.swift +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -extension Action { - /// A type that represents an action identifier. - public struct Identifier: Equatable, Hashable, RawRepresentable { - public typealias RawValue = String - - public let rawValue: RawValue - - public init(rawValue: RawValue) { - self.rawValue = rawValue - } - } -} - -extension Action.Identifier { - public init(_ rawValue: String) { - self.rawValue = rawValue - } -} - -/// A menu element that performs its action in a closure. -open class Action: MenuElement { - // MARK - Creating an Action - - /// Creates an action. - public /*convenience*/ init(title: String = "", image: Image? = nil, - identifier: Action.Identifier? = nil, - discoverabilityTitle: String? = nil, - attributes: MenuElement.Attributes = [], - state: MenuElement.State = .off, - handler: @escaping ActionHandler) { - self.identifier = identifier ?? Action.Identifier("") - self.discoverabilityTitle = discoverabilityTitle - self.attributes = attributes - self.state = state - self.handler = handler - - super.init(title: title, image: image) - } - - /// A type that defines the closure for an action handler. - public typealias ActionHandler = (Action) -> Void - - // MARK - Getting Information About the Action - - /// The action's title. - open override var title: String { - get { super.title } - set { super.title = newValue } - } - - /// The action's image. - open override var image: Image? { - get { super.image } - set { super.image = newValue } - } - - /// The unique identifier for the action. - open private(set) var identifier: Action.Identifier - - /// An elaborated title that explains the purpose of the action. - open var discoverabilityTitle: String? - - /// The attributes indicating the style of the action. - open var attributes: MenuElement.Attributes - - /// The state of the action. - open var state: MenuElement.State - - /// The object responsible for the action handler. - open internal(set) var sender: Any? - - internal private(set) var handler: ActionHandler -} diff --git a/Sources/SwiftWin32/Menus and Shortcuts/Command.swift b/Sources/SwiftWin32/Menus and Shortcuts/Command.swift deleted file mode 100644 index c10d851d..00000000 --- a/Sources/SwiftWin32/Menus and Shortcuts/Command.swift +++ /dev/null @@ -1,126 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -/// Constants that indicate which modifier keys are pressed. -public struct KeyModifierFlags: OptionSet { - public typealias RawValue = Int - - public let rawValue: RawValue - - public init(rawValue: RawValue) { - self.rawValue = rawValue - } -} - -extension KeyModifierFlags { - /// A modifier flag that indicates the user pressed the Caps Lock key. - public static var alphaShift: KeyModifierFlags { - KeyModifierFlags(rawValue: 1 << 16) - } - - /// A modifier flag that indicates the user pressed the Shift key. - public static var shift: KeyModifierFlags { - KeyModifierFlags(rawValue: 1 << 17) - } - - /// A modifier flag that indicates the user pressed the Control key. - public static var control: KeyModifierFlags { - KeyModifierFlags(rawValue: 1 << 18) - } - - /// A modifier flag that indicates the user pressed the Option key. - public static var alternate: KeyModifierFlags { - KeyModifierFlags(rawValue: 1 << 19) - } - - /// A modifier flag that indicates the user pressed the Command key. - public static var command: KeyModifierFlags { - KeyModifierFlags(rawValue: 1 << 20) - } - - /// A modifier flag that indicates the user pressed a key located on the - /// numeric keypad. - public static var numericPad: KeyModifierFlags { - KeyModifierFlags(rawValue: 1 << 21) - } -} - -/// An object representing an alternative action for a command. -public class CommandAlternate { - // MARK - Creating a Command Alternative - - /// Creates a command alternative with the specified title, action, and - /// modifier flags. - public /*convenience*/ init(title: String, - action: @escaping (_: AnyObject?) -> Void, - modifierFlags: KeyModifierFlags) { - self.title = title - self.action = action - self.modifierFlags = modifierFlags - } - - /// The command alternative's title. - public private(set) var title: String - - /// The command alternative's action-method selector. - public private(set) var action: (_: AnyObject?) -> Void - - /// The bit mask of modifier keys that the user must press to invoke the - /// action for the alternative command. - public private(set) var modifierFlags: KeyModifierFlags -} - -/// A menu element that performs its action in a selector. -public class Command: MenuElement { - // MARK - Creating a Command - - /// Creates a command. - public /*convenience*/ init(title: String = "", image: Image? = nil, - action: @escaping (_: AnyObject?) -> Void, - propertyList: Any? = nil, - alternates: [CommandAlternate] = [], - discoverabilityTitle: String? = nil, - attributes: MenuElement.Attributes = [], - state: MenuElement.State = .off) { - self.action = action - self.discoverabilityTitle = discoverabilityTitle - self.attributes = attributes - self.state = state - - self.alternates = alternates - - super.init(title: title, image: image) - } - - // MARK - Getting Information About the Command - - /// The command's title. - public override var title: String { - get { super.title } - set { super.title = newValue } - } - - /// The command's image. - public override var image: Image? { - get { super.image } - set { super.image = newValue } - } - - /// The selector identifying the action method called after the user selects - /// the command. - public var action: (_: AnyObject?) -> Void - - /// An elaborated title that explains the purpose of the command. - public var discoverabilityTitle: String? - - /// The attributes indicating the style of the command. - public var attributes: MenuElement.Attributes - - /// The state of the command. - public var state: MenuElement.State - - // MARK - Getting Command Alternatives - - /// An array of alternative actions to take for the command. - public private(set) var alternates: [CommandAlternate] -} diff --git a/Sources/SwiftWin32/Menus and Shortcuts/ContextMenuConfiguration.swift b/Sources/SwiftWin32/Menus and Shortcuts/ContextMenuConfiguration.swift deleted file mode 100644 index 5c8f3324..00000000 --- a/Sources/SwiftWin32/Menus and Shortcuts/ContextMenuConfiguration.swift +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import class Foundation.NSUUID -import protocol Foundation.NSCopying - -/// Returns the configuration data to use when previewing the content. -public class ContextMenuConfiguration { - internal var previewProvider: ContextMenuContentPreviewProvider - - internal var actionProvider: ContextMenuActionProvider? - - // MARK - Creating the Menu Configuration Object - - /// Returns the custom view controller to use when previewing your content. - public typealias ContextMenuContentPreviewProvider = () -> ViewController? - - /// Returns an action-based contextual menu, optionally incorporating the - /// system-suggested actions. - public typealias ContextMenuActionProvider = ([MenuElement]) -> Menu? - - /// Creates a menu configuration object with the specified action and preview - /// providers. - public convenience init(identifier: NSCopying?, - previewProvider: ContextMenuContentPreviewProvider?, - actionProvider: ContextMenuActionProvider? = nil) { - // TODO(compnerd) fill out the default preview provider - self.init(identifier: identifier ?? NSUUID(), - previewProvider: previewProvider ?? { return nil }, - actionProvider: actionProvider) - } - - private init(identifier: NSCopying, - previewProvider: @escaping ContextMenuContentPreviewProvider, - actionProvider: ContextMenuActionProvider?) { - self.identifier = identifier - self.previewProvider = previewProvider - self.actionProvider = actionProvider - } - - // MARK - Getting the Configuration Identifier - - /// The unique identifier for this configuration object. - public let identifier: NSCopying -} diff --git a/Sources/SwiftWin32/Menus and Shortcuts/ContextMenuInteraction.swift b/Sources/SwiftWin32/Menus and Shortcuts/ContextMenuInteraction.swift deleted file mode 100644 index 3c5c8aae..00000000 --- a/Sources/SwiftWin32/Menus and Shortcuts/ContextMenuInteraction.swift +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -#if swift(>=5.7) -import CoreGraphics -#endif - -extension ContextMenuInteraction { - /// Constants that describe the appearance of the menu. - public enum Appearance: Int { - /// No menu appearance. - case unknown - - /// A modal menu with an optional preview. - case rich - - /// A nonmodal, compact menu with no preview. - case compact - } -} - -/// An interaction object that you use to display relevant actions for your -/// content. -public class ContextMenuInteraction: Interaction { - // MARK - Creating a Context Menu Interaction Object - - /// Creates a context menu interaction object with the specified delegate - /// object. - public init(delegate: ContextMenuInteractionDelegate) { - self.delegate = delegate - } - - // MARK - Previewing and Managing the Content - - /// The object that provides the preview and contextual menu for your content - /// and responds to interaction-related events. - public private(set) weak var delegate: ContextMenuInteractionDelegate? - - public private(set) weak var view: View? - - public func willMove(to view: View?) { - } - - public func didMove(to view: View?) { - self.view = view - } - - // MARK - Getting the Interaction's Location - - /// Returns the location of the user interaction in the specified view's - /// coordinate system. - public func location(in view: View?) -> Point { - fatalError("\(#function) not yet implemented") - } - - // MARK - Getting the Menu Appearance - - /// The appearance of the context menu. - public var appearance: ContextMenuInteraction.Appearance = .compact - - // MARK - Managing Menu Interactions - - /// Dismisses the context menu. - public func dismissMenu() { - } - - /// Updates the currently visible menu. - public func updateVisibleMenu(_ block: (Menu) -> Menu) { - } -} diff --git a/Sources/SwiftWin32/Menus and Shortcuts/ContextMenuInteractionAnimating.swift b/Sources/SwiftWin32/Menus and Shortcuts/ContextMenuInteractionAnimating.swift deleted file mode 100644 index 3c9eec48..00000000 --- a/Sources/SwiftWin32/Menus and Shortcuts/ContextMenuInteractionAnimating.swift +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -/// Methods adopted by system-supplied animator objects when interacting with -/// context menus. -public protocol ContextMenuInteractionAnimating { - /// Adding Custom Animations - - /// Adds the specified animation block to the animator. - func addAnimations(_ animations: @escaping () -> Void) - - /// Adds the specified completion block to the animator. - func addCompletion(_ completion: @escaping () -> Void) - - /// Previewing the Content - - /// The current preview controller. - var previewViewController: ViewController? { get } -} diff --git a/Sources/SwiftWin32/Menus and Shortcuts/ContextMenuInteractionCommitAnimating.swift b/Sources/SwiftWin32/Menus and Shortcuts/ContextMenuInteractionCommitAnimating.swift deleted file mode 100644 index b3bdebf5..00000000 --- a/Sources/SwiftWin32/Menus and Shortcuts/ContextMenuInteractionCommitAnimating.swift +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -/// Constants that control the interaction commit style. -public enum ContextMenuInteractionCommitStyle: Int { -/// An interaction with no animations. -case dismiss -/// An interaction that uses animations. -case pop -} - -/// Methods adopted by system-supplied animator objects when committing -/// preview-related animations. -public protocol ContextMenuInteractionCommitAnimating: ContextMenuInteractionAnimating { - /// Specifying the Commit Style - var preferredCommitStyle: ContextMenuInteractionCommitStyle { get set } -} diff --git a/Sources/SwiftWin32/Menus and Shortcuts/ContextMenuInteractionDelegate.swift b/Sources/SwiftWin32/Menus and Shortcuts/ContextMenuInteractionDelegate.swift deleted file mode 100644 index b156d8fc..00000000 --- a/Sources/SwiftWin32/Menus and Shortcuts/ContextMenuInteractionDelegate.swift +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -#if swift(>=5.7) -import CoreGraphics -#endif - -/// The methods for providing the set of actions to perform on your content, -/// and for customizing the preview of that content. -public protocol ContextMenuInteractionDelegate: AnyObject { - // MARK - Providing the Preview Configuration Data - - /// Returns the configuration data to use when previewing the content. - func contextMenuInteraction(_ interaction: ContextMenuInteraction, - configurationForMenuAtLocation location: Point) - -> ContextMenuConfiguration? - - // MARK - Customizing the Preview Animations - - /// Returns the source view to use when animating the appearance of the - /// preview interface. - func contextMenuInteraction(_ interaction: ContextMenuInteraction, - previewForHighlightingMenuWithConfiguration configuration: ContextMenuConfiguration) - -> TargetedPreview? - - /// Returns the destination view to use when animating the appearance of the - /// preview interface. - func contextMenuInteraction(_ interaction: ContextMenuInteraction, - previewForDismissingMenuWithConfiguration configuration: ContextMenuConfiguration) - -> TargetedPreview? - - // MARK - Responding to the Menu's Appearance - - /// Informs the delegate when a preview action begins. - func contextMenuInteraction(_ interaction: ContextMenuInteraction, - willPerformPreviewActionForMenuWith configuration: ContextMenuConfiguration, - animator: ContextMenuInteractionCommitAnimating) - - // MARK - Handling Animations - - /// Informs the delegate when a menu display begins. - func contextMenuInteraction(_ interaction: ContextMenuInteraction, - willDisplayMenuFor configuration: ContextMenuConfiguration, - animator: ContextMenuInteractionAnimating?) - - /// Informs the delegate when a menu display ends. - func contextMenuInteraction(_ interaction: ContextMenuInteraction, - willEndFor configuration: ContextMenuConfiguration, - animator: ContextMenuInteractionAnimating?) -} - -extension ContextMenuInteractionDelegate { - public func contextMenuInteraction(_ interaction: ContextMenuInteraction, - previewForHighlightingMenuWithConfiguration configuration: ContextMenuConfiguration) - -> TargetedPreview? { - // TODO(compnerd) what should the default be? - return nil - } - - public func contextMenuInteraction(_ interaction: ContextMenuInteraction, - previewForDismissingMenuWithConfiguration configuration: ContextMenuConfiguration) - -> TargetedPreview? { - // TODO(compnerd) what should the default be? - return nil - } -} - -extension ContextMenuInteractionDelegate { - public func contextMenuInteraction(_ interaction: ContextMenuInteraction, - willPerformPreviewActionForMenuWith configuration: ContextMenuConfiguration, - animator: ContextMenuInteractionCommitAnimating) { - } -} - -extension ContextMenuInteractionDelegate { - public func contextMenuInteraction(_ interaction: ContextMenuInteraction, - willDisplayMenuFor configuration: ContextMenuConfiguration, - animator: ContextMenuInteractionAnimating?) { - } - - public func contextMenuInteraction(_ interaction: ContextMenuInteraction, - willEndFor configuration: ContextMenuConfiguration, - animator: ContextMenuInteractionAnimating?) { - } -} diff --git a/Sources/SwiftWin32/Menus and Shortcuts/Menu.swift b/Sources/SwiftWin32/Menus and Shortcuts/Menu.swift deleted file mode 100644 index 4c23d3d5..00000000 --- a/Sources/SwiftWin32/Menus and Shortcuts/Menu.swift +++ /dev/null @@ -1,333 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import class Foundation.NSUUID - -extension Menu { - /// Constants for identifying an application's standard menus. - public struct Identifier: Equatable, Hashable, RawRepresentable { - public typealias RawValue = String - - public let rawValue: RawValue - - public init(rawValue: String) { - self.rawValue = rawValue - } - } -} - -extension Menu.Identifier { - // MARK - Root Menu - - /// The root menu. - public static var root: Menu.Identifier { - Menu.Identifier(rawValue: "org.compnerd.swift-win32.menu.root") - } - - // MARK - Top-Level Menus - - /// The standard application menu. - public static var application: Menu.Identifier { - Menu.Identifier(rawValue: "org.compnerd.swift-win32.menu.application") - } - - /// The standard File menu. - public static var file: Menu.Identifier { - Menu.Identifier(rawValue: "org.compnerd.swift-win32.menu.file") - } - - /// The standard Edit menu. - public static var edit: Menu.Identifier { - Menu.Identifier(rawValue: "org.compnerd.swift-win32.menu.edit") - } - - /// The standard View menu. - public static var view: Menu.Identifier { - Menu.Identifier(rawValue: "org.compnerd.swift-win32.menu.view") - } - - /// The standard Window menu. - public static var window: Menu.Identifier { - Menu.Identifier(rawValue: "org.compnerd.swift-win32.menu.window") - } - - /// The standard Help menu. - public static var help: Menu.Identifier { - Menu.Identifier(rawValue: "org.compnerd.swift-win32.menu.help") - } - - // MARK - Application Menu Commands - - /// The About menu. - public static var about: Menu.Identifier { - Menu.Identifier(rawValue: "org.compnerd.swift-win32.menu.about") - } - - /// The Preferences menu. - public static var preferences: Menu.Identifier { - Menu.Identifier(rawValue: "org.compnerd.swift-win32.menu.preferences") - } - - /// The Services menu. - public static var services: Menu.Identifier { - Menu.Identifier(rawValue: "org.compnerd.swift-win32.menu.services") - } - - /// The Hide menu. - public static var hide: Menu.Identifier { - Menu.Identifier(rawValue: "org.compnerd.swift-win32.menu.hide") - } - - /// The Quit menu. - public static var quit: Menu.Identifier{ - Menu.Identifier(rawValue: "org.compnerd.swift-win32.menu.quit") - } - - // MARK - File Menus - - /// The New Scene menu. - public static var newScene: Menu.Identifier { - Menu.Identifier(rawValue: "org.compnerd.swift-win32.menu.new-scene") - } - - /// The Close menu. - public static var close: Menu.Identifier { - Menu.Identifier(rawValue: "org.compnerd.swift-win32.menu.close") - } - - /// The Print menu. - public static var print: Menu.Identifier { - Menu.Identifier(rawValue: "org.compnerd.swift-win32.menu.print") - } - - // MARK - Edit Menus - - /// The Undo/Redo menu. - public static var undoRedo: Menu.Identifier { - Menu.Identifier(rawValue: "org.compnerd.swift-win32.menu.undo-redo") - } - - /// The standard Edit menu. - public static var standardEdit: Menu.Identifier { - Menu.Identifier(rawValue: "org.compnerd.swift-win32.menu.standard-edit") - } - - /// The Find menu. - public static var find: Menu.Identifier { - Menu.Identifier(rawValue: "org.compnerd.swift-win32.menu.find") - } - - /// The Replace menu. - public static var replace: Menu.Identifier { - Menu.Identifier(rawValue: "org.compnerd.swift-win32.menu.replace") - } - - /// The Share menu. - public static var share: Menu.Identifier { - Menu.Identifier(rawValue: "org.compnerd.swift-win32.menu.share") - } - - /// The Text Style menu. - public static var textStyle: Menu.Identifier { - Menu.Identifier(rawValue: "org.compnerd.swift-win32.menu.text-style") - } - - /// The Spelling menu. - public static var spelling: Menu.Identifier { - Menu.Identifier(rawValue: "org.compnerd.swift-win32.menu.spelling") - } - - /// The Spelling Panel menu. - public static var spellingPanel: Menu.Identifier { - Menu.Identifier(rawValue: "org.compnerd.swift-win32.menu.spelling-panel") - } - - /// The Spelling Options menu. - public static var spellingOptions: Menu.Identifier { - Menu.Identifier(rawValue: "org.compnerd.swift-win32.menu.spelling-options") - } - - /// The Subsitutions menu. - public static var subsitutions: Menu.Identifier { - Menu.Identifier(rawValue: "org.compnerd.swift-win32.menu.subsitutions") - } - - /// The Subsitutions Panel menu. - public static var subsitutionsPanel: Menu.Identifier { - Menu.Identifier(rawValue: "org.compnerd.swift-win32.menu.subsitutions-panel") - } - - /// The Transformations menu. - public static var transformations: Menu.Identifier { - Menu.Identifier(rawValue: "org.compnerd.swift-win32.menu.transformations") - } - - /// The Speech menu. - public static var speech: Menu.Identifier { - Menu.Identifier(rawValue: "org.compnerd.swift-win32.menu.speech") - } - - /// The Lookup menu. - public static var lookup: Menu.Identifier { - Menu.Identifier(rawValue: "org.compnerd.swift-win32.menu.lookup") - } - - /// The Learn menu. - public static var learn: Menu.Identifier { - Menu.Identifier(rawValue: "org.compnerd.swift-win32.menu.learn") - } - - /// The Format menu. - public static var format: Menu.Identifier { - Menu.Identifier(rawValue: "org.compnerd.swift-win32.menu.format") - } - - /// The Font menu. - public static var font: Menu.Identifier { - Menu.Identifier(rawValue: "org.compnerd.swift-win32.menu.font") - } - - /// The Text Size menu. - public static var textSize: Menu.Identifier { - Menu.Identifier(rawValue: "org.compnerd.swift-win32.menu.text-size") - } - - /// The Text Color menu. - public static var textColor: Menu.Identifier { - Menu.Identifier(rawValue: "org.compnerd.swift-win32.menu.text-color") - } - - /// The Text Style Pasteboard menu. - public static var textStylePasteboard: Menu.Identifier { - Menu.Identifier(rawValue: "org.compnerd.swift-win32.menu.text-style-pasteboard") - } - - /// The Text menu. - public static var text: Menu.Identifier { - Menu.Identifier(rawValue: "org.compnerd.swift-win32.menu.text") - } - - /// The Writing Direction menu. - public static var writingDirection: Menu.Identifier { - Menu.Identifier(rawValue: "org.compnerd.swift-win32.menu.writing-direction") - } - - /// The Alignment menu. - public static var alignment: Menu.Identifier { - Menu.Identifier(rawValue: "org.compnerd.swift-win32.menu.alignment") - } - - // MARK - View Menus - - /// The Toolbar menu group. - public static var toolbar: Menu.Identifier { - Menu.Identifier(rawValue: "org.compnerd.swift-win32.menu.toolbar") - } - - /// The Fullscreen menu. - public static var fullscreen: Menu.Identifier { - Menu.Identifier(rawValue: "org.compnerd.swift-win32.menu.fullscreen") - } - - // MARK - Window Menus - - /// The Bring All to Front menu. - public static var bringAllToFront: Menu.Identifier { - Menu.Identifier(rawValue: "org.compnerd.swift-win32.menu.bring-all-to-front") - } - - /// The Minimize and Zoom menu. - public static var minimizeAndZoom: Menu.Identifier { - Menu.Identifier(rawValue: "org.compnerd.swift-win32.menu.minimize-and-zoom") - } -} - -extension Menu.Identifier { - fileprivate static var generated: Menu.Identifier { - Menu.Identifier(rawValue: "org.compnerd.swift-win32.menu.generated.\(NSUUID())") - } -} - - -// MARK - Options for configuring a menu's appearance. - -extension Menu { - /// Options for configuring a menu's appearance. - public struct Options: OptionSet { - public typealias RawValue = UInt - - public let rawValue: RawValue - - public init(rawValue: RawValue) { - self.rawValue = rawValue - } - } -} - -extension Menu.Options: Hashable { -} - -extension Menu.Options { - /// An option indicating the menu displays inline with its parent menu instead - /// of displaying as a submenu. - public static var displayInline: Menu.Options { - return Menu.Options(rawValue: 1 << 0) - } - - /// An Option indicating the menu's appearance represents a destructive - /// action. - public static var destructive: Menu.Options { - return Menu.Options(rawValue: 1 << 1) - } -} - -/// A container for grouping related menu elements in an application menu or -/// contextual menu. -open class Menu: MenuElement { - // MARK - Creating a Menu Object - - /// Creates a new menu with the specified values. - public /*convenience*/ init(title: String = "", image: Image? = nil, - identifier: Menu.Identifier? = nil, - options: Menu.Options = [], - children: [MenuElement] = []) { - self.children = children - self.identifier = identifier ?? .generated - self.options = options - super.init(title: title, image: image) - } - - // MARK - Accessing the Child Elements - - /// The contents of the menu. - public internal(set) var children: [MenuElement] - - /// Creates a new menu with the same configuration as the current menu, but - /// with a new set of child elements. - open func replacingChildren(_ newChildren: [MenuElement]) -> Menu { - fatalError("\(#function) not yet implemented") - } - - // MARK - Getting the Menu Details - - /// The unique identifier for the current menu. - open private(set) var identifier: Menu.Identifier - - /// The configuration options for the current menu. - open private(set) var options: Menu.Options -} - -extension Menu: Equatable { - public static func ==(_ lhs: Menu, _ rhs: Menu) -> Bool { - // FIXME(compnerd) is this the correct check for equality? - return lhs === rhs - } -} -extension Menu: Hashable { - public func hash(into hasher: inout Hasher) { - // FIXME(compnerd) is this the correct hashing? - hasher.combine(self.children.count) - hasher.combine(self.identifier) - hasher.combine(self.options) - } -} diff --git a/Sources/SwiftWin32/Menus and Shortcuts/MenuBuilder.swift b/Sources/SwiftWin32/Menus and Shortcuts/MenuBuilder.swift deleted file mode 100644 index e8f58187..00000000 --- a/Sources/SwiftWin32/Menus and Shortcuts/MenuBuilder.swift +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -/// An interface for adding and removing menus from a menu system. -public protocol MenuBuilder { - // MARK - Getting Menu Systems and Elements - - /// The menu system that the menu builder modifies. - var system: MenuSystem { get } - - /// Gets the menu for the specified menu identifier. - func menu(for identifier: Menu.Identifier) -> Menu? - - /// Gets the action for the specified action identifier. - func action(for identifier: Action.Identifier) -> Action? - - /// Gets the command for the specified selector and property list. - func command(for action: @escaping (_: AnyObject?) -> Void, - propertyList: Any?) -> Command? - - // MARK - Inserting Child Menus - - /// Adds a child menu as the first element of the specified parent menu. - func insertChild(_ childMenu: Menu, - atStartOfMenu parentIdentifier: Menu.Identifier) - - /// Adds a child menu as the last element of the specified parent menu. - func insertChild(_ childMenu: Menu, - atEndOfMenu parentIdentifier: Menu.Identifier) - - // MARK - Inserting Sibling Menus - - /// Inserts a sibling menu before the specified menu. - func insertSibling(_ siblingMenu: Menu, - beforeMenu siblingIdentifier: Menu.Identifier) - - /// Inserts a sibling menu after the specified menu. - func insertSibling(_ siblingMenu: Menu, - afterMenu siblingIdentifier: Menu.Identifier) - - // MARK - Replacing Menus and Child Menu Elements - - /// Replaces the specified menu with a new menu. - func replace(menu replacedIdentifier: Menu.Identifier, - with replacementMenu: Menu) - - /// Replaces the elements in a menu with the elements returned by the - /// specified handler block. - func replaceChildren(ofMenu parentIdentifier: Menu.Identifier, - from childrenBlock: ([MenuElement]) -> [MenuElement]) - - // MARK - Removing a Menu - - /// Removes a menu from the menu system. - func remove(menu removedIdentifier: Menu.Identifier) -} - -extension MenuBuilder { - func command(for action: @escaping (_: AnyObject?) -> Void, - propertyList: Any?) -> Command? { - return nil - } -} diff --git a/Sources/SwiftWin32/Menus and Shortcuts/MenuElement.swift b/Sources/SwiftWin32/Menus and Shortcuts/MenuElement.swift deleted file mode 100644 index b1561ad6..00000000 --- a/Sources/SwiftWin32/Menus and Shortcuts/MenuElement.swift +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -extension MenuElement { - /// Attributes that determine the style of the menu element. - public struct Attributes: OptionSet { - public typealias RawValue = Int - - public let rawValue: RawValue - - public init(rawValue: RawValue) { - self.rawValue = rawValue - } - } -} - -extension MenuElement.Attributes { - /// An attribute indicating the destructive style. - public static var destructive: MenuElement.Attributes { - MenuElement.Attributes(rawValue: 1 << 1) - } - - /// An attribute indicating the disabled style. - public static var disabled: MenuElement.Attributes { - MenuElement.Attributes(rawValue: 1 << 0) - } - - /// An attribute indicating the hidden style. - public static var hidden: MenuElement.Attributes { - MenuElement.Attributes(rawValue: 1 << 2) - } -} - -extension MenuElement { - /// Constants that indicate the state of an action-based or command-based - /// menu element. - public enum State: Int { - /// A constant indicating the menu element is in the "off" state. - case off - - /// A constant indicating the menu element is in the "on" state. - case on - - /// A constant indicating the menu element is in the "mixed" state. - case mixed - } -} - -/// An object representing a menu, action, or command. -open class MenuElement { - // MARK - Getting the Element Attributes - - /// The title of the menu element. - open internal(set) var title: String - - /// The image to display alongside the menu element's title. - open internal(set) var image: Image? - - // MARK - Creating a Menu Element - - /// Creates and returns a `MenuElement` initialized with the given title and - /// image. - public init(title: String, image: Image? = nil) { - self.title = title - self.image = image - } -} diff --git a/Sources/SwiftWin32/Menus and Shortcuts/MenuSystem.swift b/Sources/SwiftWin32/Menus and Shortcuts/MenuSystem.swift deleted file mode 100644 index de26c846..00000000 --- a/Sources/SwiftWin32/Menus and Shortcuts/MenuSystem.swift +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -/// An object representing a main or contextual menu system. -open class MenuSystem { - // MARK - Getting a Menu System - - /// The main menu system. - open class var main: MenuSystem { - fatalError("\(#function) not yet implemented") - } - - /// The context menu system. - open class var context: MenuSystem { - fatalError("\(#function) not yet implemented") - } - - // MARK - Rebuilding a Menu System - - /// Tells the menu system to rebuild all of its menus. - open func setNeedsRebuild() { - } - - // MARK - Revalidating a Menu System - - /// Tells the menu system to validate all of its menus. - open func setNeedsRevalidate() { - } -} diff --git a/Sources/SwiftWin32/Menus and Shortcuts/PreviewParameters.swift b/Sources/SwiftWin32/Menus and Shortcuts/PreviewParameters.swift deleted file mode 100644 index 0b0c7f62..00000000 --- a/Sources/SwiftWin32/Menus and Shortcuts/PreviewParameters.swift +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import class Foundation.NSValue - -/// Additional parameters to use when animating a preview interface. -public class PreviewParameters { - /// Creating Preview Parameters - - /// Creates a default set of preview parameters. - public init() { - // TODO(compnerd) initialize the default parameters - } - - /// Creates a preview paramters object with information about the text you - /// want to preview. - public init(textLineRects: [NSValue]) { - // TODO(compnerd) store the rects - } - - /// Configuring the Preview Attributes - - /// The background color to display behind the preview. - public var backgroundColor: Color! - - /// The portion of the view to show in the preview. - public var visiblePath: BezierPath? - - public var shadowPath: BezierPath? -} diff --git a/Sources/SwiftWin32/Menus and Shortcuts/PreviewTarget.swift b/Sources/SwiftWin32/Menus and Shortcuts/PreviewTarget.swift deleted file mode 100644 index fcb7240a..00000000 --- a/Sources/SwiftWin32/Menus and Shortcuts/PreviewTarget.swift +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -#if swift(>=5.7) -import CoreGraphics -#endif - -/// An object that specifies the container view to use for animations. -public class PreviewTarget { - /// Creating a Preview Target Object - - /// Creates a preview target object using the specified container view and - /// configuration details. - public init(container: View, center: Point, transform: AffineTransform) { - self.container = container - self.center = center - self.transform = transform - } - - /// Creates a preview target object using the specified container view and - /// center point. - public convenience init(container: View, center: Point) { - self.init(container: container, center: center, transform: .identity) - } - - /// Getting the Target Attributes - - /// The container for the view being animated. - public let container: View - - /// The point in the containing view at which to place the center of the view - /// being animated. - public let center: Point - - /// An affine transform to apply to the view being animated. - public let transform: AffineTransform -} diff --git a/Sources/SwiftWin32/Menus and Shortcuts/TargetedPreview.swift b/Sources/SwiftWin32/Menus and Shortcuts/TargetedPreview.swift deleted file mode 100644 index 7e7d891c..00000000 --- a/Sources/SwiftWin32/Menus and Shortcuts/TargetedPreview.swift +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -#if swift(>=5.7) -import CoreGraphics -#endif - -public class TargetedPreview { - /// Creting a Targeted Preview Object - - /// Creates a targeted preview with the specified view, parameters, and target - /// container. - public init(view: View, parameters: PreviewParameters, target: PreviewTarget) { - self.view = view - // FIXME(compnerd) is this correct? - self.size = view.frame.size - self.target = target - self.parameters = parameters - } - - /// Creates a targeted preview for a view in the current window and including - /// the specified parameters. - public convenience init(view: View, parameters: PreviewParameters) { - self.init(view: view, parameters: parameters, - target: PreviewTarget(container: view, center: view.center)) - } - - /// Creates a targeted preview for a view in the current window. - public convenience init(view: View) { - self.init(view: view, parameters: PreviewParameters()) - } - - /// Getting the Preview Attributes - - /// The view that is the target of the animation - public let view: View - - /// The view that is the container for the target view. - public let target: PreviewTarget - - /// The size of the view. - public let size: Size - - /// Additional parameters to use when configuring the animations. - public let parameters: PreviewParameters - - /// Changing the Target's Container - - /// Returns a targeted preview object with the same view and parameters, but - /// with a different target container. - public func retargetedPreview(with newTarget: PreviewTarget) - -> TargetedPreview { - return TargetedPreview(view: self.view, parameters: self.parameters, - target: newTarget) - } -} diff --git a/Sources/SwiftWin32/Platform/BatteryMonitor.swift b/Sources/SwiftWin32/Platform/BatteryMonitor.swift deleted file mode 100644 index e67c020d..00000000 --- a/Sources/SwiftWin32/Platform/BatteryMonitor.swift +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import WinSDK -import class Foundation.NotificationCenter - -private let SwiftBatteryMonitorProc: SUBCLASSPROC = { (hWnd, uMsg, wParam, lParam, uIdSubclass, dwRefData) in - let monitor: BatteryMonitor? = - unsafeBitCast(dwRefData, to: AnyObject.self) as? BatteryMonitor - - switch uMsg { - case UINT(WM_POWERBROADCAST): - guard wParam == PBT_POWERSETTINGCHANGE else { - log.info("\(#function): uMsg: \(uMsg), wParam: \(wParam), lParam: \(lParam)") - break - } - - let pSetting: UnsafeMutablePointer = - UnsafeMutablePointer(bitPattern: UInt(lParam))! - let dwDataLength: DWORD = pSetting.pointee.DataLength - - switch pSetting.pointee.PowerSetting { - case GUID_BATTERY_PERCENTAGE_REMAINING: - assert(dwDataLength == MemoryLayout.size) - let dwBatteryLevel: DWORD = - withUnsafePointer(to: &pSetting.pointee.Data) { - $0.withMemoryRebound(to: DWORD.self, capacity: 1) { $0.pointee } - } - - NotificationCenter.default - .post(name: Device.batteryLevelDidChangeNotification, object: nil) - default: - break - } - - default: - break - } - - return DefSubclassProc(hWnd, uMsg, wParam, lParam) -} - -internal struct BatteryMonitor { - private static let `class`: WindowClass = - WindowClass(hInst: GetModuleHandleW(nil), name: "Swift.BatteryMonitor") - - private var hWnd: HWND? - private var hBatteryStateNotification: HPOWERNOTIFY? - private var hPowerSourceNotification: HPOWERNOTIFY? - - public init() { - self.hWnd = CreateWindowExW(0, BatteryMonitor.class.name, nil, 0, 0, 0, 0, 0, - HWND_MESSAGE, nil, GetModuleHandleW(nil), nil) - guard let hWnd = self.hWnd else { - log.warning("CreateWindowExW: \(Error(win32: GetLastError()))") - return - } - - SetWindowSubclass(hWnd, SwiftBatteryMonitorProc, UINT_PTR(0), - unsafeBitCast(self as AnyObject, to: DWORD_PTR.self)) - - var setting: GUID = GUID_BATTERY_PERCENTAGE_REMAINING - self.hBatteryStateNotification = - RegisterPowerSettingNotification(self.hWnd, &setting, - DWORD(DEVICE_NOTIFY_WINDOW_HANDLE)) - if self.hBatteryStateNotification == nil { - log.warning("RegisterPowerSettingNotification: \(Error(win32: GetLastError()))") - } - } -} diff --git a/Sources/SwiftWin32/Platform/Error.swift b/Sources/SwiftWin32/Platform/Error.swift deleted file mode 100644 index 8259662c..00000000 --- a/Sources/SwiftWin32/Platform/Error.swift +++ /dev/null @@ -1,104 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import ucrt -import WinSDK - -internal struct Error: Swift.Error { - private enum ErrorCode { - case errno(errno_t) - case win32(DWORD) - case nt(DWORD) - case hresult(DWORD) - } - - private let code: ErrorCode - - public init(win32 error: DWORD) { - self.code = .win32(error) - } - - public init(nt error: DWORD) { - self.code = .nt(error) - } - - public init(hresult hr: DWORD) { - self.code = .hresult(hr) - } - - public init(errno: errno_t) { - self.code = .errno(errno) - } -} - -extension Error: CustomStringConvertible { - public var description: String { - let dwFlags: DWORD = DWORD(FORMAT_MESSAGE_ALLOCATE_BUFFER) - | DWORD(FORMAT_MESSAGE_FROM_SYSTEM) - | DWORD(FORMAT_MESSAGE_IGNORE_INSERTS) - - let short: String - let dwResult: DWORD - var buffer: UnsafeMutablePointer? - - switch self.code { - case .errno(let errno): - short = "errno \(errno)" - - // MSDN indicates that the returned string can have a maximum of 94 - // characters, so allocate 95 characters. -#if swift(>=5.7) - return withUnsafeTemporaryAllocation(of: wchar_t.self, capacity: 95) { - let result: errno_t = _wcserror_s($0.baseAddress, $0.count, errno) - guard result == 0 else { return short } - return "\(short) - \(String(decodingCString: $0.baseAddress!, as: UTF16.self))" - } -#else - let buffer: UnsafeMutablePointer = .allocate(capacity: 95) - defer { buffer.deallocate() } - - let result: errno_t = _wcserror_s(buffer, 95, errno) - guard result == 0 else { return short } - return "\(short) - \(String(decodingCString: buffer, as: UTF16.self))" -#endif - - case .win32(let error): - short = "Win32 Error \(error)" - - dwResult = withUnsafeMutablePointer(to: &buffer) { - $0.withMemoryRebound(to: WCHAR.self, capacity: 2) { - FormatMessageW(dwFlags, nil, error, - MAKELANGID(WORD(LANG_NEUTRAL), WORD(SUBLANG_DEFAULT)), - $0, 0, nil) - } - } - - - case .nt(let status): - short = "NTSTATUS 0x\(String(status, radix: 16))" - - dwResult = withUnsafeMutablePointer(to: &buffer) { - $0.withMemoryRebound(to: WCHAR.self, capacity: 2) { - FormatMessageW(dwFlags, nil, status, - MAKELANGID(WORD(LANG_NEUTRAL), WORD(SUBLANG_DEFAULT)), - $0, 0, nil) - } - } - - case .hresult(let hr): - short = "HRESULT 0x\(String(hr, radix: 16))" - - dwResult = withUnsafeMutablePointer(to: &buffer) { - $0.withMemoryRebound(to: WCHAR.self, capacity: 2) { - FormatMessageW(dwFlags, nil, hr, - MAKELANGID(WORD(LANG_NEUTRAL), WORD(SUBLANG_DEFAULT)), - $0, 0, nil) - } - } - } - - guard dwResult > 0, let message = buffer else { return short } - defer { LocalFree(buffer) } - return "\(short) - \(String(decodingCString: message, as: UTF16.self))" - } -} diff --git a/Sources/SwiftWin32/Platform/OrientationSensor.swift b/Sources/SwiftWin32/Platform/OrientationSensor.swift deleted file mode 100644 index 82a3bcb3..00000000 --- a/Sources/SwiftWin32/Platform/OrientationSensor.swift +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import WinSDK -import SwiftCOM - -internal class OrientationSensorEventListener: SwiftCOM.ISensorEvents { - public func OnEvent(_ pSensor: SwiftCOM.ISensor, _ eventID: REFGUID, - _ pEventData: SwiftCOM.IPortableDeviceValues) -> HRESULT { - switch eventID.pointee { - case SENSOR_EVENT_PROPERTY_CHANGED: - break - default: - break - } - return S_OK - } -} - -internal class OrientationSensorManager { - private var SensorManager: SwiftCOM.ISensorManager? - private var OrientationSensor: SwiftCOM.ISensor? - private var EventListener: SwiftWin32.OrientationSensorEventListener = - OrientationSensorEventListener() - - public lazy var shared: OrientationSensorManager? = OrientationSensorManager() - - private init?() { - do { - self.SensorManager = - try ISensorManager.CreateInstance(class: CLSID_SensorManager) - } catch where (error as? COMError)?.hr == HRESULT_FROM_WIN32(DWORD(ERROR_ACCESS_DISABLED_BY_POLICY)) { - // TODO(compnerd) unable to access SensorManager due to Group Policy - // Settings, surface to the user - return nil - } catch { - log.error("CoCreateInstance(CLSID_SensorManager, IID_ISensorManager): \(error)") - return nil - } - - guard let sensors = - try? SensorManager?.GetSensorsByType(SENSOR_TYPE_AGGREGATED_DEVICE_ORIENTATION) else { - return nil - } - - // FIXME(compnerd) can we select a sensor in a better way? - self.OrientationSensor = try? sensors.GetAt(0) - if self.OrientationSensor == nil { return nil } - - // FIXME(compnerd) can we continue to an alternative sensor? - switch try? self.OrientationSensor?.GetState() { - case .some(SENSOR_STATE_ACCESS_DENIED): - // Request Sensor Access - do { - try self.SensorManager?.RequestPermissions(nil, sensors, false) - } catch where (error as? COMError)?.hr == HRESULT_FROM_WIN32(DWORD(ERROR_ACCESS_DENIED)) { - // The user denied access to the sensor - return nil - } catch where (error as? COMError)?.hr == HRESULT_FROM_WIN32(DWORD(ERROR_CANCELLED)) { - // The user cancelled the requested - return nil - } catch { - log.error("ISensorManager::RequestPermissions: \(error)") - return nil - } - case .none, .some(_): - return nil - } - - try? self.OrientationSensor?.SetEventSink(self.EventListener) - } - - deinit { - _ = try? self.OrientationSensor?.SetEventSink(nil) - } -} diff --git a/Sources/SwiftWin32/Platform/Win32+Menu.swift b/Sources/SwiftWin32/Platform/Win32+Menu.swift deleted file mode 100644 index a4cd19b3..00000000 --- a/Sources/SwiftWin32/Platform/Win32+Menu.swift +++ /dev/null @@ -1,141 +0,0 @@ -// Copyright © 2021 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import WinSDK - -#if swift(>=5.9) -internal import OrderedCollections -#else -@_implementationOnly -import OrderedCollections -#endif - -internal final class _MenuBuilder: MenuSystem { - internal private(set) var hMenu: MenuHandle - internal private(set) weak var view: View? - - private var menus: OrderedSet - - internal init?(for view: View) { - self.hMenu = MenuHandle(owning: view is Window ? CreateMenu() : CreatePopupMenu()) - if self.hMenu.value == nil { - log.warning("CreateMenu: \(Error(win32: GetLastError()))") - return nil - } - self.view = view - self.menus = [] - } - - private func append(_ menus: T, to hMenu: MenuHandle) - where T.Element: MenuElement { - for (index, child) in menus.enumerated() { - let hImage: BitmapHandle? = - BitmapHandle(from: child.image?.bitmap) - - var hSubmenu: MenuHandle? - if let submenu = child as? Menu { - hSubmenu = MenuHandle(referencing: CreatePopupMenu()) - if hSubmenu?.value == nil { - log.warning("CreateMenu: \(Error(win32: GetLastError()))") - continue - } - append(submenu.children, to: hSubmenu!) - } - - var wide = child.title.wide - var info = wide.withUnsafeMutableBufferPointer { - MENUITEMINFOW(cbSize: UINT(MemoryLayout.size), - fMask: UINT(MIIM_FTYPE | MIIM_STATE | MIIM_ID | MIIM_STRING | MIIM_SUBMENU | MIIM_DATA | MIIM_BITMAP), - fType: UINT(MFT_STRING), fState: UINT(MFS_ENABLED), wID: UInt32.random(in: .min ... .max), - hSubMenu: hSubmenu?.value, hbmpChecked: nil, hbmpUnchecked: nil, dwItemData: 0, - dwTypeData: $0.baseAddress, cch: UINT(child.title.count), hbmpItem: hImage?.value) - } - InsertMenuItemW(hMenu.value, UINT(index), true, &info) - } - } - - override func setNeedsRebuild() { - // Remove the old submenus from the menu: - for index in (0.. Menu? { - self.menus.first { $0.identifier == identifier } - } - - public func action(for identifier: Action.Identifier) -> Action? { - return nil - } - - public func insertChild(_ menu: Menu, - atStartOfMenu identifier: Menu.Identifier) { - // FIXME(compnerd) what happens if the element is not found? - if let index = self.menus.firstIndex(where: { $0.identifier == identifier }) { - let parent = self.menus[index] - parent.children.insert(menu, at: parent.children.startIndex) - } - } - - public func insertChild(_ menu: Menu, - atEndOfMenu identifier: Menu.Identifier) { - // FIXME(compnerd) what happens if the element is not found? - if let index = self.menus.firstIndex(where: { $0.identifier == identifier }) { - let parent = self.menus[index] - parent.children.insert(menu, at: parent.children.endIndex) - } - } - - public func insertSibling(_ menu: Menu, - beforeMenu identifier: Menu.Identifier) { - let index: OrderedSet.Index = - identifier == .root - ? self.menus.startIndex - : self.menus.firstIndex { $0.identifier == identifier } ?? self.menus.startIndex - self.menus.insert(menu, at: index) - } - - public func insertSibling(_ menu: Menu, - afterMenu identifier: Menu.Identifier) { - let index: OrderedSet.Index = - identifier == .root - ? self.menus.endIndex - : self.menus.firstIndex { $0.identifier == identifier } ?? self.menus.endIndex - self.menus.insert(menu, at: index) - } - - public func replace(menu identifier: Menu.Identifier, with menu: Menu) { - // FIXME(compnerd) should we be appending the item if the specified - // identifier is not found? - if let index = self.menus.firstIndex(where: { $0.identifier == identifier }) { - _ = self.menus.remove(at: index) - self.menus.insert(menu, at: index) - } - } - - public func replaceChildren(ofMenu parentIdentifier: Menu.Identifier, - from childrenBlock: ([MenuElement]) -> [MenuElement]) { - } - - public func remove(menu identifier: Menu.Identifier) { - // FIXME(compnerd) what happens if the element is not found? - if let index = self.menus.firstIndex(where: { $0.identifier == identifier }) { - _ = self.menus.remove(at: index) - } - } -} diff --git a/Sources/SwiftWin32/Platform/Win32+PropertyWrappers.swift b/Sources/SwiftWin32/Platform/Win32+PropertyWrappers.swift deleted file mode 100644 index d473220c..00000000 --- a/Sources/SwiftWin32/Platform/Win32+PropertyWrappers.swift +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import WinSDK - -@propertyWrapper -public struct _Win32WindowText { - public var wrappedValue: String? { - get { fatalError() } - set { fatalError() } - } - - public static subscript(_enclosingInstance view: EnclosingSelf, - wrapped wrappedKeyPath: ReferenceWritableKeyPath, - storage storageKeyPath: ReferenceWritableKeyPath) - -> String? { - get { - let szLength: Int32 = GetWindowTextLengthW(view.hWnd) - guard szLength > 0 else { return nil } - - let buffer: [WCHAR] = Array(unsafeUninitializedCapacity: Int(szLength) + 1) { - $1 = Int(GetWindowTextW(view.hWnd, $0.baseAddress!, CInt($0.count))) + 1 - } - return String(decodingCString: buffer, as: UTF16.self) - } - set(value) { - SetWindowTextW(view.hWnd, value?.wide) - } - } - - public init() { - } -} diff --git a/Sources/SwiftWin32/Platform/WindowClass.swift b/Sources/SwiftWin32/Platform/WindowClass.swift deleted file mode 100644 index 2d6727ea..00000000 --- a/Sources/SwiftWin32/Platform/WindowClass.swift +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright © 2019 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import WinSDK - -internal typealias WindowProc = - @convention(c) (HWND?, UINT, WPARAM, LPARAM) -> LRESULT - -internal final class WindowClass { - internal var name: [WCHAR] - - internal var hInstance: HINSTANCE? - internal var value: WNDCLASSEXW? - internal var atom: ATOM? - - public init(hInst hInstance: HINSTANCE, name: String, - WindowProc lpfnWindowProc: WindowProc? = DefWindowProcW, - style: UInt32 = 0, hbrBackground: HBRUSH? = nil, - hCursor: HCURSOR? = nil) { - self.name = name.wide - - self.hInstance = hInstance - self.name.withUnsafeBufferPointer { - self.value = WNDCLASSEXW(cbSize: UINT(MemoryLayout.size), - style: style, - lpfnWndProc: lpfnWindowProc, - cbClsExtra: 0, - cbWndExtra: 0, - hInstance: hInstance, - hIcon: nil, - hCursor: hCursor, - hbrBackground: hbrBackground, - lpszMenuName: nil, - lpszClassName: $0.baseAddress!, - hIconSm: nil) - } - } - - public init(named: String) { - self.name = named.wide - } - - public func register() -> Bool { - guard value != nil, atom == nil else { return true } - self.atom = RegisterClassExW(&value!) - return self.atom != nil - } - - public func unregister() -> Bool { - guard value != nil, atom != nil else { return false } - if UnregisterClassW(self.name, self.hInstance) { - self.atom = nil - } - return self.atom == nil - } -} diff --git a/Sources/SwiftWin32/Platform/WindowsHandle.swift b/Sources/SwiftWin32/Platform/WindowsHandle.swift deleted file mode 100644 index eb8dba19..00000000 --- a/Sources/SwiftWin32/Platform/WindowsHandle.swift +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -internal protocol HandleValue { - associatedtype HandleType - static func release(_: HandleType?) -} - -internal class ManagedHandle { - typealias HandleType = Value.HandleType - - private enum ValueType { - case owning(HandleType?) - case referencing(HandleType?) - } - - private var handle: ValueType - - public var value: HandleType? { - switch self.handle { - case .owning(let handle): - return handle - case .referencing(let handle): - return handle - } - } - - init(owning handle: HandleType?) { - self.handle = .owning(handle) - } - - init(referencing handle: HandleType?) { - self.handle = .referencing(handle) - } - - deinit { - switch self.handle { - case .owning(let handle): - if let handle = handle { - Value.release(handle) - } - case .referencing(_): - break - } - } -} diff --git a/Sources/SwiftWin32/Pointer Interactions/PointerInteraction.swift b/Sources/SwiftWin32/Pointer Interactions/PointerInteraction.swift deleted file mode 100644 index 7d9ea70e..00000000 --- a/Sources/SwiftWin32/Pointer Interactions/PointerInteraction.swift +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -/// An interaction that enables support for effects on a view or customizes the -/// pointer's appearance within a region of an app. -public class PointerInteraction { - // MARK - Creating Pointer Interactions - - /// Initializes a pointer interaction object with a specified delegate object. - public init(delegate: PointerInteractionDelegate?) { - self.delegate = delegate - } - - // MARK - Managing Pointer Interactions - - /// An object that responds to pointer movements. - public private(set) weak var delegate: PointerInteractionDelegate? - - // MARK - Activating Pointer Interactions - - /// A boolean value that indicates whether the pointer interaction is enabled. - public var isEnabled: Bool = true - - // MARK - Triggering a Pointer Update - - /// Causes the interaction to update the pointer in response to an event. - public func invalidate() { - } - - // MARK - Interaction - public private(set) weak var view: View? -} - -extension PointerInteraction: Interaction { - public func didMove(to view: View?) { - } - - public func willMove(to view: View?) { - } -} diff --git a/Sources/SwiftWin32/Pointer Interactions/PointerInteractionAnimating.swift b/Sources/SwiftWin32/Pointer Interactions/PointerInteractionAnimating.swift deleted file mode 100644 index 1b81c8ed..00000000 --- a/Sources/SwiftWin32/Pointer Interactions/PointerInteractionAnimating.swift +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -/// An interface for modifying an interaction animation in coordination with the -/// pointer effect animations. -public protocol PointerInteractionAnimating { - // MARK - Managing Animations - - /// Adds the specified animation block to the animator. - func addAnimations(_ animations: @escaping () -> Void) - - /// Adds the specified completion block to the animator. - func addCompletion(_ completion: @escaping (Bool) -> Void) -} diff --git a/Sources/SwiftWin32/Pointer Interactions/PointerInteractionDelegate.swift b/Sources/SwiftWin32/Pointer Interactions/PointerInteractionDelegate.swift deleted file mode 100644 index 1783732b..00000000 --- a/Sources/SwiftWin32/Pointer Interactions/PointerInteractionDelegate.swift +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -/// An interface for handling pointer movements within the interaction's view. -public protocol PointerInteractionDelegate: AnyObject { - // MARK - Defining Pointer Styles for Regions - - /// Asks the delegate for a region as the pointer moves within the - /// interaction's view. - func pointerInteraction(_ interaction: PointerInteraction, - regionFor request: PointerRegionRequest, - defaultRegion: PointerRegion) -> PointerRegion? - - /// Asks the delegate for a pointer style after an interaction receives a new - /// region. - func pointerInteraction(_ interaction: PointerInteraction, - styleFor region: PointerRegion) -> PointerStyle? - - // MARK - Handling Animations for Pointer Regions - - /// Informs the delegate when the pointer enters a given region. - func pointerInteraction(_ interaction: PointerInteraction, - willEnter region: PointerRegion, - animator: PointerInteractionAnimating) - - /// Informs the delegate when the pointer exits a given region. - func pointerInteraction(_ interaction: PointerInteraction, - willExit region: PointerRegion, - animator: PointerInteractionAnimating) -} - -extension PointerInteractionDelegate { - public func pointerInteraction(_ interaction: PointerInteraction, - regionFor request: PointerRegionRequest, - defaultRegion: PointerRegion) - -> PointerRegion? { - return nil - } - - public func pointerInteraction(_ interaction: PointerInteraction, - styleFor region: PointerRegion) - -> PointerStyle? { - return nil - } -} - -extension PointerInteractionDelegate { - public func pointerInteraction(_ interaction: PointerInteraction, - willEnter region: PointerRegion, - animator: PointerInteractionAnimating) { - } - - public func pointerInteraction(_ interaction: PointerInteraction, - willExit region: PointerRegion, - animator: PointerInteractionAnimating) { - } -} diff --git a/Sources/SwiftWin32/Pointer Interactions/PointerRegion.swift b/Sources/SwiftWin32/Pointer Interactions/PointerRegion.swift deleted file mode 100644 index 29c3745f..00000000 --- a/Sources/SwiftWin32/Pointer Interactions/PointerRegion.swift +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -#if swift(>=5.7) -import CoreGraphics -#endif - -public class PointerRegion { - // MARK - Configuring a Region - - /// The rectangle bounds of the region. - public private(set) var rect: Rect - - // MARK - Initializers - - public /*convenience*/ init(rect: Rect, identifier: AnyHashable? = nil) { - self.rect = rect - self.identifier = identifier - } - - // MARK - Instance Property - - public private(set) var identifier: AnyHashable? -} diff --git a/Sources/SwiftWin32/Pointer Interactions/PointerRegionRequest.swift b/Sources/SwiftWin32/Pointer Interactions/PointerRegionRequest.swift deleted file mode 100644 index 1d074201..00000000 --- a/Sources/SwiftWin32/Pointer Interactions/PointerRegionRequest.swift +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -#if swift(>=5.7) -import CoreGraphics -#endif - -/// An object to describe the pointer's location in the interaction's view. -public class PointerRegionRequest { - // MARK - Inspecting the Region Request - - /// The location of the pointer in the interaction's view's coordinate space. - public private(set) var location: Point - - /// Key modifier flags representing keyboard keys pressed by the user at the - /// time of this request. - public private(set) var modifiers: KeyModifierFlags - - internal init(location: Point, modifiers: KeyModifierFlags) { - self.location = location - self.modifiers = modifiers - } -} diff --git a/Sources/SwiftWin32/Pointer Interactions/PointerStyle.swift b/Sources/SwiftWin32/Pointer Interactions/PointerStyle.swift deleted file mode 100644 index 905a17d2..00000000 --- a/Sources/SwiftWin32/Pointer Interactions/PointerStyle.swift +++ /dev/null @@ -1,112 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -#if swift(>=5.7) -import CoreGraphics -#endif - -extension PointerEffect { - /// An effect that defines how to apply a tint to a view during a pointer - /// interaction. - public enum TintMode: Hashable { - // MARK - Tint Modes - - /// The view has no tint applied. - case none - - /// The view has a tint overlay. - case overlay - - /// The view has a tint underlay. - case underlay - } -} - -/// An effect that alters a view's appearance when a pointer enters the current -/// region. -public enum PointerEffect { - // MARK - Accessing the Preview - - /// A preview of the view used during an interaction's animations. - public var preview: TargetedPreview { - switch self { - case .automatic(let preview): - return preview - case .highlight(let preview): - return preview - case .hover(let preview, _, _, _): - return preview - case .lift(let preview): - return preview - } - } - - // MARK - Creating a Default Effect - - /// A pointer content effect with the given preview's view. - case automatic(TargetedPreview) - - // MARK - Creating a Specific Effect - - /// An effect where the pointer slides under the given view and morphs into - /// the view's shape. - case highlight(TargetedPreview) - - /// An effect where visual changes are applied to the view and the pointer - /// retains its default shape. - case hover(TargetedPreview, - preferredTintMode: PointerEffect.TintMode = .overlay, - prefersShadow: Bool = false, - prefersScaledContent: Bool = true) - - /// An effect where the pointer slides under the given view and disappears as - /// the view scales up and gains a shadow. - case lift(TargetedPreview) -} - -/// An object that defines the shape of custom pointers. -public enum PointerShape { - // MARK - Specifying Pointer Shapes - - /// The pointer morphs into a horizontal beam using the specified length. - case horizontalBeam(length: Double) - - /// The pointer morphs into a vertical beam using the specified length. - case verticalBeam(length: Double) - - /// The pointer morphs into the given Bézier path. - case path(BezierPath) - - /// The pointer morphs into a rounded rectangle using the provided corner - /// radius. - case roundedRect(Rect, radius: Double = PointerShape.defaultCornerRadius) - - // MARK - Accessing Corner Radius - - /// The default corner radius for a pointer using a rounded rectangle. - public static var defaultCornerRadius: Double { - 8.0 - } -} - -/// An object that defines the pointer shape and effect. -public class PointerStyle { - // MARK - Creating a Pointer Style - - /// Applies the provided content effect and pointer shape to the current - /// region. - public convenience init(effect: PointerEffect, shape: PointerShape? = nil) { - fatalError("\(#function) not yet implemented") - } - - /// Morphs the pointer into the provided shape when hovering over the current - /// region. - public convenience init(shape: PointerShape, constrainedAxes: Axis = []) { - fatalError("\(#function) not yet implemented") - } - - /// Hides the pointer when it moves over the current region. - public class func hidden() -> Self { - fatalError("\(#function) not yet implemented") - } -} diff --git a/Sources/SwiftWin32/Support/Array+Extensions.swift b/Sources/SwiftWin32/Support/Array+Extensions.swift deleted file mode 100644 index f243d96c..00000000 --- a/Sources/SwiftWin32/Support/Array+Extensions.swift +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool . -// SPDX-License-Identifier: BSD-3-Clause - -import ucrt - -extension Array where Element == UInt16 { - internal init(from string: String) { - self = string.withCString(encodedAs: UTF16.self) { buffer in - Array(unsafeUninitializedCapacity: string.utf16.count + 1) { - wcscpy_s($0.baseAddress, $0.count, buffer) - $1 = $0.count - } - } - } -} - -extension Array where Element: Equatable { - mutating func remove(object: Element) { - if let index = firstIndex(of: object) { remove(at: index) } - } -} diff --git a/Sources/SwiftWin32/Support/Date+Extensions.swift b/Sources/SwiftWin32/Support/Date+Extensions.swift deleted file mode 100644 index ea25b9f5..00000000 --- a/Sources/SwiftWin32/Support/Date+Extensions.swift +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright © 2021 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import WinSDK - -import struct Foundation.Date -import struct Foundation.TimeInterval - -// 100 nanosecond ticks -@_transparent -internal var WindowsTick: Double { 10_000_000 } - -// NT to Unix Epoch (seconds) -@_transparent -internal var NTToUnixEpochBias: Double { 11_644_473_600 } - -extension FILETIME { - @inline(__always) - internal init(_ systemTime: SYSTEMTIME) { - self = FILETIME() - withUnsafePointer(to: systemTime) { - guard SystemTimeToFileTime($0, &self) else { - fatalError("SystemTimeToFileTime: \(Error(win32: GetLastError()))") - } - } - } - - @inline(__always) - internal init(timeIntervalSince1970 interval: TimeInterval) { - let value = UInt64((interval + NTToUnixEpochBias) * WindowsTick) - self = FILETIME(dwLowDateTime: DWORD((value >> 0) & 0xffffffff), - dwHighDateTime: DWORD((value >> 32) & 0xffffffff)) - } - - @inline(__always) - internal var timeIntervalSince1970: TimeInterval { - var ulTime: ULARGE_INTEGER = ULARGE_INTEGER() - ulTime.LowPart = self.dwLowDateTime - ulTime.HighPart = self.dwHighDateTime - return Double(ulTime.QuadPart) / WindowsTick - NTToUnixEpochBias - } -} - -extension SYSTEMTIME { - @inline(__always) - internal init(_ fileTime: FILETIME) { - self = SYSTEMTIME() - withUnsafePointer(to: fileTime) { - guard FileTimeToSystemTime($0, &self) else { - fatalError("FileTimeToSystemTime: \(Error(win32: GetLastError()))") - } - } - } -} diff --git a/Sources/SwiftWin32/Support/IndexPath+UIExtensions.swift b/Sources/SwiftWin32/Support/IndexPath+UIExtensions.swift deleted file mode 100644 index 6defa8ce..00000000 --- a/Sources/SwiftWin32/Support/IndexPath+UIExtensions.swift +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import struct Foundation.IndexPath - -extension IndexPath { - /// An index number identifying a section in a table view or collection view. - public var section: Int { - return self[0] - } -} - -extension IndexPath { - /// An index number identifying a row in a section of a table view. - public var row: Int { - return self[1] - } - - /// Initializes an index path with the indexes of a specific row and section - /// in a table view. - public init(row: Int, section: Int) { - self.init(indexes: [section, row]) - } -} - -extension IndexPath { - /// An index number identifying an item in a section of a collection view. - public var item: Int { - return 1 - } - - /// Initializes an index path with the index of a specific item and section in - /// a collection view. - public init(item: Int, section: Int) { - self.init(indexes: [section, item]) - } -} diff --git a/Sources/SwiftWin32/Support/Logging.swift b/Sources/SwiftWin32/Support/Logging.swift deleted file mode 100644 index 51d88fde..00000000 --- a/Sources/SwiftWin32/Support/Logging.swift +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -#if swift(>=5.9) -internal import Logging -#else -@_implementationOnly -import Logging -#endif - -internal let log: Logger = Logger(label: "org.compnerd.swift-win32") diff --git a/Sources/SwiftWin32/Support/Point+UIExtensions.swift b/Sources/SwiftWin32/Support/Point+UIExtensions.swift deleted file mode 100644 index ae62b169..00000000 --- a/Sources/SwiftWin32/Support/Point+UIExtensions.swift +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import WinSDK -#if swift(>=5.7) -import CoreGraphics -#endif - -extension Point { - internal init(from: POINT) { - self.init(x: Double(from.x), y: Double(from.y)) - } -} - -extension POINT { - internal init(from: Point) { - self.init(x: LONG(from.x), y: LONG(from.y)) - } -} - -extension Size { - internal init(from: POINT) { - self.init(width: Double(from.x), height: Double(from.y)) - } -} - -extension POINT { - internal init(from: Size) { - self.init(x: LONG(from.width), y: LONG(from.height)) - } -} - -extension Point { - internal init(x: Integer, y: Integer) { - self.init(x: Int(x), y: Int(y)) - } -} - -extension Point { - internal static func + (_ lhs: Point, _ rhs: Point) -> Point { - return Point(x: lhs.x + rhs.x, y: lhs.y + rhs.y) - } - - internal static func - (_ lhs: Point, _ rhs: Point) -> Point { - return Point(x: lhs.x - rhs.x, y: lhs.y - rhs.y) - } -} diff --git a/Sources/SwiftWin32/Support/Rect+UIExtensions.swift b/Sources/SwiftWin32/Support/Rect+UIExtensions.swift deleted file mode 100644 index d3e9d38a..00000000 --- a/Sources/SwiftWin32/Support/Rect+UIExtensions.swift +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright © 2019 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import WinSDK -#if swift(>=5.7) -import CoreGraphics -#endif - -extension Rect { - internal init(from: RECT) { - self.init(origin: Point(x: from.left, y: from.top), - size: Size(width: from.right - from.left, - height: from.bottom - from.top)) - } -} - -extension RECT { - internal init(from: Rect) { - self.init(left: LONG(from.origin.x), - top: LONG(from.origin.y), - right: LONG(from.origin.x + from.size.width), - bottom: LONG(from.origin.y + from.size.height)) - } -} - -extension Rect { - internal var center: Point { - Point(x: self.midX, y: self.midY) - } -} - -extension Rect { - internal func scaled(for dpi: UINT, style: WindowStyle) -> Rect { - let scale: Double = Double(dpi) / Double(USER_DEFAULT_SCREEN_DPI) - - var r: RECT = - RECT(from: self.applying(AffineTransform(scaleX: scale, y: scale))) - if !AdjustWindowRectExForDpi(&r, style.base, false, style.extended, dpi) { - log.warning("AdjustWindowRectExForDpi: \(Error(win32: GetLastError()))") - } - - return Rect(from: r) - } -} diff --git a/Sources/SwiftWin32/Support/Size+UIExtensions.swift b/Sources/SwiftWin32/Support/Size+UIExtensions.swift deleted file mode 100644 index 3e42af38..00000000 --- a/Sources/SwiftWin32/Support/Size+UIExtensions.swift +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -#if swift(>=5.7) -import CoreGraphics -#endif - -extension Size { - internal init(width: Integer, height: Integer) { - self.init(width: Int(width), height: Int(height)) - } -} diff --git a/Sources/SwiftWin32/Support/String+UIExtensions.swift b/Sources/SwiftWin32/Support/String+UIExtensions.swift deleted file mode 100644 index 06f82e92..00000000 --- a/Sources/SwiftWin32/Support/String+UIExtensions.swift +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright © 2019 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -extension String { - public var wide: [UInt16] { - return Array(from: self) - } -} - diff --git a/Sources/SwiftWin32/Support/WinSDK+Extensions.swift b/Sources/SwiftWin32/Support/WinSDK+Extensions.swift deleted file mode 100644 index f5cc0ac4..00000000 --- a/Sources/SwiftWin32/Support/WinSDK+Extensions.swift +++ /dev/null @@ -1,257 +0,0 @@ -// Copyright © 2019 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import WinSDK - -internal let IDC_ARROW: UnsafePointer = - UnsafePointer(bitPattern: 32512)! - -#if swift(<6.0) - -// winreg.h -@_transparent -internal var HKEY_CLASSES_ROOT: HKEY? { - HKEY(bitPattern: 0x80000000) -} - -@_transparent -internal var HKEY_CURRENT_USER: HKEY? { - HKEY(bitPattern: 0x80000001) -} - -@_transparent -internal var HKEY_LOCAL_MACHINE: HKEY? { - HKEY(bitPattern: 0x80000002) -} - -@_transparent -internal var HKEY_USERS: HKEY? { - HKEY(bitPattern: 0x80000003) -} - -@_transparent -internal var HKEY_PERFORMANCE_DATA: HKEY? { - HKEY(bitPattern: 0x80000004) -} - -@_transparent -internal var HKEY_PERFORMANCE_TEXT: HKEY? { - HKEY(bitPattern: 0x80000050) -} - -@_transparent -internal var HKEY_PERFORMANCE_NLSTEXT: HKEY? { - HKEY(bitPattern: 0x80000060) -} - -@_transparent -internal var HKEY_CURRENT_CONFIG: HKEY? { - HKEY(bitPattern: 0x80000005) -} - -@_transparent -internal var HKEY_DYN_DATA: HKEY? { - HKEY(bitPattern: 0x80000006) -} - -@_transparent -internal var HKEY_CURRENT_USER_LOCAL_SETTINGS: HKEY? { - HKEY(bitPattern: 0x80000007) -} - -#endif - -// Richedit.h -@_transparent -internal var MSFTEDIT_CLASS: String { - "RICHEDIT50W" -} - -// winnt.h - -@_transparent -internal func MAKELANGID(_ p: WORD, _ s: WORD) -> DWORD { - return DWORD((s << 10) | p) -} - -@_transparent -internal var GUID_ACDC_POWER_SOURCE: GUID { - GUID(Data1: 0x5D3E9A59, Data2: 0xE9D5, Data3: 0x4B00, - Data4: (0xA6, 0xBD, 0xFF, 0x34, 0xFF, 0x51, 0x65, 0x48)) -} - -@_transparent -internal var GUID_BATTERY_PERCENTAGE_REMAINING: GUID { - GUID(Data1: 0xA7AD8041, Data2: 0xB45A, Data3: 0x4CAE, - Data4: (0x87, 0xA3, 0xEE, 0xCB, 0xB4, 0x68, 0xA9, 0xE1)) -} - -// minwindef.h - -@_transparent -internal func LOWORD(_ dword: T) -> WORD { - return WORD(DWORD_PTR(dword) >> 0 & 0xffff) -} - -@_transparent -internal func HIWORD(_ dword: T) -> WORD { - return WORD(DWORD_PTR(dword) >> 16 & 0xffff) -} - -// wingdi.h - -@_transparent -internal func GetRValue(_ rgb: DWORD) -> DWORD { - return (rgb >> 0) & 0xff -} - -@_transparent -internal func GetGValue(_ rgb: DWORD) -> DWORD { - return (rgb >> 8) & 0xff -} - -@_transparent -internal func GetBValue(_ rgb: DWORD) -> DWORD { - return (rgb >> 16) & 0xff -} - -// WinUser.h - -@_transparent -internal var ENUM_CURRENT_SETTINGS: DWORD { - DWORD(bitPattern: -1) -} - -@_transparent -internal var HWND_MESSAGE: HWND { - HWND(bitPattern: -3)! -} - -@_transparent -internal var QS_MOUSE: DWORD { - DWORD(QS_MOUSEMOVE) | DWORD(QS_MOUSEBUTTON) -} - -@_transparent -internal var QS_INPUT: DWORD { - DWORD(QS_MOUSE) | DWORD(QS_KEY) | DWORD(QS_RAWINPUT) | DWORD(QS_TOUCH) | DWORD(QS_POINTER) -} - -@_transparent -internal var QS_ALLEVENTS: DWORD { - DWORD(QS_INPUT) | DWORD(QS_POSTMESSAGE) | DWORD(QS_TIMER) | DWORD(QS_PAINT) | DWORD(QS_HOTKEY) -} - -@_transparent -internal var QS_ALLINPUT: DWORD { - DWORD(QS_INPUT) | DWORD(QS_POSTMESSAGE) | DWORD(QS_TIMER) | DWORD(QS_PAINT) | DWORD(QS_HOTKEY) | DWORD(QS_SENDMESSAGE) -} - -@_transparent -internal var TCS_BOTTOM: DWORD { - DWORD(WinSDK.TCS_BOTTOM) -} - -@_transparent -internal var TCS_FIXEDWIDTH: DWORD { - DWORD(WinSDK.TCS_FIXEDWIDTH) -} - -@_transparent -internal var TCS_FLATBUTTONS: DWORD { - DWORD(WinSDK.TCS_FLATBUTTONS) -} - -@_transparent -internal var WS_BORDER: DWORD { - DWORD(WinSDK.WS_BORDER) -} - -@_transparent -internal var WS_CAPTION: DWORD { - DWORD(WinSDK.WS_CAPTION) -} - -@_transparent -internal var WS_CHILD: DWORD { - DWORD(WinSDK.WS_CHILD) -} - -@_transparent -internal var WS_CLIPSIBLINGS: DWORD { - DWORD(WinSDK.WS_CLIPSIBLINGS) -} - -@_transparent -internal var WS_HSCROLL: DWORD { - DWORD(WinSDK.WS_HSCROLL) -} - -@_transparent -internal var WS_TABSTOP: DWORD { - DWORD(WinSDK.WS_TABSTOP) -} - -@_transparent -internal var WS_VISIBLE: DWORD { - DWORD(WinSDK.WS_VISIBLE) -} - -@_transparent -internal var WS_VSCROLL: DWORD { - DWORD(WinSDK.WS_VSCROLL) -} - -@_transparent -internal var WS_OVERLAPPEDWINDOW: DWORD { - DWORD(WinSDK.WS_OVERLAPPEDWINDOW) -} - -// `GetMessageW` returns `BOOL` but can return `-1` in the case of an error. -// Explicitly convert the signature to unwrap the `BOOL` to `CInt`. -func GetMessageW(_ lpMsg: LPMSG?, _ hWnd: HWND?, _ wMsgFilterMin: UINT, - _ wMsgFilterMax: UINT) -> Bool { - return WinSDK.GetMessageW(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax) -} - -func GetMessageW(_ lpMsg: LPMSG?, _ hWnd: HWND?, _ wMsgFilterMin: UINT, - _ wMsgFilterMax: UINT) -> CInt { - let pfnGetMessageW: (LPMSG?, HWND?, UINT, UINT) -> CInt = - unsafeBitCast(WinSDK.GetMessageW, - to: ((LPMSG?, HWND?, UINT, UINT) -> CInt).self) - return pfnGetMessageW(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax) -} - -// `EnableMenuItem` returns `BOOL` but can return `-1` in the case of an error. -// Explicitly convert the signature to unwrap the `BOOL` to `CInt`. -func EnableMenuItem(_ hMenu: HMENU, _ uIDEnableItem: UINT, _ uEnable: UINT) - -> Bool { - return WinSDK.EnableMenuItem(hMenu, uIDEnableItem, uEnable) -} - -func EnableMenuItem(_ hMenu: HMENU, _ uIDEnableItem: UINT, _ uEnable: UINT) - -> CInt { - let pfnEnableMenuItem: (HMENU?, UINT, UINT) -> CInt = - unsafeBitCast(WinSDK.EnableMenuItem, - to: ((HMENU?, UINT, UINT) -> CInt).self) - return pfnEnableMenuItem(hMenu, uIDEnableItem, uEnable) -} - -private func ==(_ lhs: (T, T, T, T, T, T, T, T), - _ rhs: (T, T, T, T, T, T, T, T)) -> Bool { - return lhs.0 == rhs.0 && - lhs.1 == rhs.1 && - lhs.2 == rhs.2 && - lhs.3 == rhs.3 && - lhs.4 == rhs.4 && - lhs.5 == rhs.5 && - lhs.6 == rhs.6 && - lhs.7 == rhs.7 -} - -internal func ~=(_ lhs: GUID, _ rhs: GUID) -> Bool { - return lhs.Data1 == rhs.Data1 && - lhs.Data2 == rhs.Data2 && - lhs.Data3 == rhs.Data3 && - lhs.Data4 == rhs.Data4 -} diff --git a/Sources/SwiftWin32/Support/WinSDK+UIExtensions.swift b/Sources/SwiftWin32/Support/WinSDK+UIExtensions.swift deleted file mode 100644 index f1d7cad7..00000000 --- a/Sources/SwiftWin32/Support/WinSDK+UIExtensions.swift +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright © 2021 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3 - -import WinSDK - -internal func UserData(from hWnd: HWND?) -> Type? { - guard let hWnd = hWnd else { return nil } - - let lpUserData = GetWindowLongPtrW(hWnd, GWLP_USERDATA) - return lpUserData == 0 ? nil - : unsafeBitCast(lpUserData, to: AnyObject.self) as? Type -} diff --git a/Sources/SwiftWin32/Support/WindowMessage.swift b/Sources/SwiftWin32/Support/WindowMessage.swift deleted file mode 100644 index 8e8cc27f..00000000 --- a/Sources/SwiftWin32/Support/WindowMessage.swift +++ /dev/null @@ -1,681 +0,0 @@ -// Copyright © 2021 Ryan Allan -// SPDX-License-Identifier: BSD-3-Clause - -import WinSDK - -struct WindowMessage { - static func debugDescription(for uMsg: UINT) -> String { - return messages[Int(uMsg)] ?? "Unknown Message" - } - - static let messages: [Int:String] = - [ - 0 : "WM_NULL", - 1 : "WM_CREATE", - 2 : "WM_DESTROY", - 3 : "WM_MOVE", - 5 : "WM_SIZE", - 6 : "WM_ACTIVATE", - 7 : "WM_SETFOCUS", - 8 : "WM_KILLFOCUS", - 10 : "WM_ENABLE", - 11 : "WM_SETREDRAW", - 12 : "WM_SETTEXT", - 13 : "WM_GETTEXT", - 14 : "WM_GETTEXTLENGTH", - 15 : "WM_PAINT", - 16 : "WM_CLOSE", - 17 : "WM_QUERYENDSESSION", - 18 : "WM_QUIT", - 19 : "WM_QUERYOPEN", - 20 : "WM_ERASEBKGND", - 21 : "WM_SYSCOLORCHANGE", - 22 : "WM_ENDSESSION", - 24 : "WM_SHOWWINDOW", - 25 : "WM_CTLCOLOR", - 26 : "WM_WININICHANGE", - 27 : "WM_DEVMODECHANGE", - 28 : "WM_ACTIVATEAPP", - 29 : "WM_FONTCHANGE", - 30 : "WM_TIMECHANGE", - 31 : "WM_CANCELMODE", - 32 : "WM_SETCURSOR", - 33 : "WM_MOUSEACTIVATE", - 34 : "WM_CHILDACTIVATE", - 35 : "WM_QUEUESYNC", - 36 : "WM_GETMINMAXINFO", - 38 : "WM_PAINTICON", - 39 : "WM_ICONERASEBKGND", - 40 : "WM_NEXTDLGCTL", - 42 : "WM_SPOOLERSTATUS", - 43 : "WM_DRAWITEM", - 44 : "WM_MEASUREITEM", - 45 : "WM_DELETEITEM", - 46 : "WM_VKEYTOITEM", - 47 : "WM_CHARTOITEM", - 48 : "WM_SETFONT", - 49 : "WM_GETFONT", - 50 : "WM_SETHOTKEY", - 51 : "WM_GETHOTKEY", - 55 : "WM_QUERYDRAGICON", - 57 : "WM_COMPAREITEM", - 61 : "WM_GETOBJECT", - 65 : "WM_COMPACTING", - 68 : "WM_COMMNOTIFY", - 70 : "WM_WINDOWPOSCHANGING", - 71 : "WM_WINDOWPOSCHANGED", - 72 : "WM_POWER", - 73 : "WM_COPYGLOBALDATA", - 74 : "WM_COPYDATA", - 75 : "WM_CANCELJOURNAL", - 78 : "WM_NOTIFY", - 80 : "WM_INPUTLANGCHANGEREQUEST", - 81 : "WM_INPUTLANGCHANGE", - 82 : "WM_TCARD", - 83 : "WM_HELP", - 84 : "WM_USERCHANGED", - 85 : "WM_NOTIFYFORMAT", - 123 : "WM_CONTEXTMENU", - 124 : "WM_STYLECHANGING", - 125 : "WM_STYLECHANGED", - 126 : "WM_DISPLAYCHANGE", - 127 : "WM_GETICON", - 128 : "WM_SETICON", - 129 : "WM_NCCREATE", - 130 : "WM_NCDESTROY", - 131 : "WM_NCCALCSIZE", - 132 : "WM_NCHITTEST", - 133 : "WM_NCPAINT", - 134 : "WM_NCACTIVATE", - 135 : "WM_GETDLGCODE", - 136 : "WM_SYNCPAINT", - 160 : "WM_NCMOUSEMOVE", - 161 : "WM_NCLBUTTONDOWN", - 162 : "WM_NCLBUTTONUP", - 163 : "WM_NCLBUTTONDBLCLK", - 164 : "WM_NCRBUTTONDOWN", - 165 : "WM_NCRBUTTONUP", - 166 : "WM_NCRBUTTONDBLCLK", - 167 : "WM_NCMBUTTONDOWN", - 168 : "WM_NCMBUTTONUP", - 169 : "WM_NCMBUTTONDBLCLK", - 171 : "WM_NCXBUTTONDOWN", - 172 : "WM_NCXBUTTONUP", - 173 : "WM_NCXBUTTONDBLCLK", - 176 : "EM_GETSEL", - 177 : "EM_SETSEL", - 178 : "EM_GETRECT", - 179 : "EM_SETRECT", - 180 : "EM_SETRECTNP", - 181 : "EM_SCROLL", - 182 : "EM_LINESCROLL", - 183 : "EM_SCROLLCARET", - 185 : "EM_GETMODIFY", - 187 : "EM_SETMODIFY", - 188 : "EM_GETLINECOUNT", - 189 : "EM_LINEINDEX", - 190 : "EM_SETHANDLE", - 191 : "EM_GETHANDLE", - 192 : "EM_GETTHUMB", - 193 : "EM_LINELENGTH", - 194 : "EM_REPLACESEL", - 195 : "EM_SETFONT", - 196 : "EM_GETLINE", - 197 : "EM_LIMITTEXT || EM_SETLIMITTEXT", - 198 : "EM_CANUNDO", - 199 : "EM_UNDO", - 200 : "EM_FMTLINES", - 201 : "EM_LINEFROMCHAR", - 202 : "EM_SETWORDBREAK", - 203 : "EM_SETTABSTOPS", - 204 : "EM_SETPASSWORDCHAR", - 205 : "EM_EMPTYUNDOBUFFER", - 206 : "EM_GETFIRSTVISIBLELINE", - 207 : "EM_SETREADONLY", - 208 : "EM_SETWORDBREAKPROC", - 209 : "EM_GETWORDBREAKPROC", - 210 : "EM_GETPASSWORDCHAR", - 211 : "EM_SETMARGINS", - 212 : "EM_GETMARGINS", - 213 : "EM_GETLIMITTEXT", - 214 : "EM_POSFROMCHAR", - 215 : "EM_CHARFROMPOS", - 216 : "EM_SETIMESTATUS", - 217 : "EM_GETIMESTATUS", - 224 : "SBM_SETPOS", - 225 : "SBM_GETPOS", - 226 : "SBM_SETRANGE", - 227 : "SBM_GETRANGE", - 228 : "SBM_ENABLE_ARROWS", - 230 : "SBM_SETRANGEREDRAW", - 233 : "SBM_SETSCROLLINFO", - 234 : "SBM_GETSCROLLINFO", - 235 : "SBM_GETSCROLLBARINFO", - 240 : "BM_GETCHECK", - 241 : "BM_SETCHECK", - 242 : "BM_GETSTATE", - 243 : "BM_SETSTATE", - 244 : "BM_SETSTYLE", - 245 : "BM_CLICK", - 246 : "BM_GETIMAGE", - 247 : "BM_SETIMAGE", - 248 : "BM_SETDONTCLICK", - 255 : "WM_INPUT", - 256 : "WM_KEYDOWN", - 257 : "WM_KEYUP", - 258 : "WM_CHAR", - 259 : "WM_DEADCHAR", - 260 : "WM_SYSKEYDOWN", - 261 : "WM_SYSKEYUP", - 262 : "WM_SYSCHAR", - 263 : "WM_SYSDEADCHAR", - 265 : "WM_UNICHAR || WM_WNT_CONVERTREQUESTEX", - 266 : "WM_CONVERTREQUEST", - 267 : "WM_CONVERTRESULT", - 268 : "WM_INTERIM", - 269 : "WM_IME_STARTCOMPOSITION", - 270 : "WM_IME_ENDCOMPOSITION", - 271 : "WM_IME_COMPOSITION", - 272 : "WM_INITDIALOG", - 273 : "WM_COMMAND", - 274 : "WM_SYSCOMMAND", - 275 : "WM_TIMER", - 276 : "WM_HSCROLL", - 277 : "WM_VSCROLL", - 278 : "WM_INITMENU", - 279 : "WM_INITMENUPOPUP", - 280 : "WM_SYSTIMER", - 287 : "WM_MENUSELECT", - 288 : "WM_MENUCHAR", - 289 : "WM_ENTERIDLE", - 290 : "WM_MENURBUTTONUP", - 291 : "WM_MENUDRAG", - 292 : "WM_MENUGETOBJECT", - 293 : "WM_UNINITMENUPOPUP", - 294 : "WM_MENUCOMMAND", - 295 : "WM_CHANGEUISTATE", - 296 : "WM_UPDATEUISTATE", - 297 : "WM_QUERYUISTATE", - 306 : "WM_CTLCOLORMSGBOX", - 307 : "WM_CTLCOLOREDIT", - 308 : "WM_CTLCOLORLISTBOX", - 309 : "WM_CTLCOLORBTN", - 310 : "WM_CTLCOLORDLG", - 311 : "WM_CTLCOLORSCROLLBAR", - 312 : "WM_CTLCOLORSTATIC", - 512 : "WM_MOUSEMOVE", - 513 : "WM_LBUTTONDOWN", - 514 : "WM_LBUTTONUP", - 515 : "WM_LBUTTONDBLCLK", - 516 : "WM_RBUTTONDOWN", - 517 : "WM_RBUTTONUP", - 518 : "WM_RBUTTONDBLCLK", - 519 : "WM_MBUTTONDOWN", - 520 : "WM_MBUTTONUP", - 521 : "WM_MBUTTONDBLCLK", - 522 : "WM_MOUSEWHEEL", - 523 : "WM_XBUTTONDOWN", - 524 : "WM_XBUTTONUP", - 525 : "WM_XBUTTONDBLCLK", - 526 : "WM_MOUSEHWHEEL", - 528 : "WM_PARENTNOTIFY", - 529 : "WM_ENTERMENULOOP", - 530 : "WM_EXITMENULOOP", - 531 : "WM_NEXTMENU", - 532 : "WM_SIZING", - 533 : "WM_CAPTURECHANGED", - 534 : "WM_MOVING", - 536 : "WM_POWERBROADCAST", - 537 : "WM_DEVICECHANGE", - 544 : "WM_MDICREATE", - 545 : "WM_MDIDESTROY", - 546 : "WM_MDIACTIVATE", - 547 : "WM_MDIRESTORE", - 548 : "WM_MDINEXT", - 549 : "WM_MDIMAXIMIZE", - 550 : "WM_MDITILE", - 551 : "WM_MDICASCADE", - 552 : "WM_MDIICONARRANGE", - 553 : "WM_MDIGETACTIVE", - 560 : "WM_MDISETMENU", - 561 : "WM_ENTERSIZEMOVE", - 562 : "WM_EXITSIZEMOVE", - 563 : "WM_DROPFILES", - 564 : "WM_MDIREFRESHMENU", - 640 : "WM_IME_REPORT", - 641 : "WM_IME_SETCONTEXT", - 642 : "WM_IME_NOTIFY", - 643 : "WM_IME_CONTROL", - 644 : "WM_IME_COMPOSITIONFULL", - 645 : "WM_IME_SELECT", - 646 : "WM_IME_CHAR", - 648 : "WM_IME_REQUEST", - 656 : "WM_IME_KEYDOWN", - 657 : "WM_IME_KEYUP", - 672 : "WM_NCMOUSEHOVER", - 673 : "WM_MOUSEHOVER", - 674 : "WM_NCMOUSELEAVE", - 675 : "WM_MOUSELEAVE", - 768 : "WM_CUT", - 769 : "WM_COPY", - 770 : "WM_PASTE", - 771 : "WM_CLEAR", - 772 : "WM_UNDO", - 773 : "WM_RENDERFORMAT", - 774 : "WM_RENDERALLFORMATS", - 775 : "WM_DESTROYCLIPBOARD", - 776 : "WM_DRAWCLIPBOARD", - 777 : "WM_PAINTCLIPBOARD", - 778 : "WM_VSCROLLCLIPBOARD", - 779 : "WM_SIZECLIPBOARD", - 780 : "WM_ASKCBFORMATNAME", - 781 : "WM_CHANGECBCHAIN", - 782 : "WM_HSCROLLCLIPBOARD", - 783 : "WM_QUERYNEWPALETTE", - 784 : "WM_PALETTEISCHANGING", - 785 : "WM_PALETTECHANGED", - 786 : "WM_HOTKEY", - 791 : "WM_PRINT", - 792 : "WM_PRINTCLIENT", - 793 : "WM_APPCOMMAND", - 856 : "WM_HANDHELDFIRST", - 863 : "WM_HANDHELDLAST", - 864 : "WM_AFXFIRST", - 895 : "WM_AFXLAST", - 896 : "WM_PENWINFIRST", - 897 : "WM_RCRESULT", - 898 : "WM_HOOKRCRESULT", - 899 : "WM_GLOBALRCCHANGE || WM_PENMISCINFO", - 900 : "WM_SKB", - 901 : "WM_HEDITCTL || WM_PENCTL", - 902 : "WM_PENMISC", - 903 : "WM_CTLINIT", - 904 : "WM_PENEVENT", - 911 : "WM_PENWINLAST", - 1024 : "DDM_SETFMT || DM_GETDEFID || NIN_SELECT || TBM_GETPOS || WM_PSD_PAGESETUPDLG || WM_USER", - 1025 : "CBEM_INSERTITEMA || DDM_DRAW || DM_SETDEFID || HKM_SETHOTKEY || PBM_SETRANGE || RB_INSERTBANDA || SB_SETTEXTA || TB_ENABLEBUTTON || TBM_GETRANGEMIN || TTM_ACTIVATE || WM_CHOOSEFONT_GETLOGFONT || WM_PSD_FULLPAGERECT", - 1026 : "CBEM_SETIMAGELIST || DDM_CLOSE || DM_REPOSITION || HKM_GETHOTKEY || PBM_SETPOS || RB_DELETEBAND || SB_GETTEXTA || TB_CHECKBUTTON || TBM_GETRANGEMAX || WM_PSD_MINMARGINRECT", - 1027 : "CBEM_GETIMAGELIST || DDM_BEGIN || HKM_SETRULES || PBM_DELTAPOS || RB_GETBARINFO || SB_GETTEXTLENGTHA || TBM_GETTIC || TB_PRESSBUTTON || TTM_SETDELAYTIME || WM_PSD_MARGINRECT", - 1028 : "CBEM_GETITEMA || DDM_END || PBM_SETSTEP || RB_SETBARINFO || SB_SETPARTS || TB_HIDEBUTTON || TBM_SETTIC || TTM_ADDTOOLA || WM_PSD_GREEKTEXTRECT", - 1029 : "CBEM_SETITEMA || PBM_STEPIT || TB_INDETERMINATE || TBM_SETPOS || TTM_DELTOOLA || WM_PSD_ENVSTAMPRECT", - 1030 : "CBEM_GETCOMBOCONTROL || PBM_SETRANGE32 || PBM_SETRANGE32 || RB_SETBANDINFOA || SB_GETPARTS || TB_MARKBUTTON || TBM_SETRANGE || TTM_NEWTOOLRECTA || WM_PSD_YAFULLPAGERECT", - 1031 : "CBEM_GETEDITCONTROL || PBM_GETRANGE || RB_SETPARENT || SB_GETBORDERS || TBM_SETRANGEMIN || TTM_RELAYEVENT", - 1032 : "CBEM_SETEXSTYLE || PBM_GETPOS || RB_HITTEST || SB_SETMINHEIGHT || TBM_SETRANGEMAX || TTM_GETTOOLINFOA", - 1033 : "CBEM_GETEXSTYLE || CBEM_GETEXTENDEDSTYLE || PBM_SETBARCOLOR || RB_GETRECT || SB_SIMPLE || TB_ISBUTTONENABLED || TBM_CLEARTICS || TTM_SETTOOLINFOA", - 1034 : "CBEM_HASEDITCHANGED || RB_INSERTBANDW || SB_GETRECT || TB_ISBUTTONCHECKED || TBM_SETSEL || TTM_HITTESTA || WIZ_QUERYNUMPAGES", - 1035 : "CBEM_INSERTITEMW || RB_SETBANDINFOW || SB_SETTEXTW || TB_ISBUTTONPRESSED || TBM_SETSELSTART || TTM_GETTEXTA || WIZ_NEXT", - 1036 : "CBEM_SETITEMW || RB_GETBANDCOUNT || SB_GETTEXTLENGTHW || TB_ISBUTTONHIDDEN || TBM_SETSELEND || TTM_UPDATETIPTEXTA || WIZ_PREV", - 1037 : "CBEM_GETITEMW || RB_GETROWCOUNT || SB_GETTEXTW || TB_ISBUTTONINDETERMINATE || TTM_GETTOOLCOUNT", - 1038 : "CBEM_SETEXTENDEDSTYLE || RB_GETROWHEIGHT || SB_ISSIMPLE || TB_ISBUTTONHIGHLIGHTED || TBM_GETPTICS || TTM_ENUMTOOLSA", - 1039 : "SB_SETICON || TBM_GETTICPOS || TTM_GETCURRENTTOOLA", - 1040 : "RB_IDTOINDEX || SB_SETTIPTEXTA || TBM_GETNUMTICS || TTM_WINDOWFROMPOINT", - 1041 : "RB_GETTOOLTIPS || SB_SETTIPTEXTW || TBM_GETSELSTART || TB_SETSTATE || TTM_TRACKACTIVATE", - 1042 : "RB_SETTOOLTIPS || SB_GETTIPTEXTA || TB_GETSTATE || TBM_GETSELEND || TTM_TRACKPOSITION", - 1043 : "RB_SETBKCOLOR || SB_GETTIPTEXTW || TB_ADDBITMAP || TBM_CLEARSEL || TTM_SETTIPBKCOLOR", - 1044 : "RB_GETBKCOLOR || SB_GETICON || TB_ADDBUTTONSA || TBM_SETTICFREQ || TTM_SETTIPTEXTCOLOR", - 1045 : "RB_SETTEXTCOLOR || TB_INSERTBUTTONA || TBM_SETPAGESIZE || TTM_GETDELAYTIME", - 1046 : "RB_GETTEXTCOLOR || TB_DELETEBUTTON || TBM_GETPAGESIZE || TTM_GETTIPBKCOLOR", - 1047 : "RB_SIZETORECT || TB_GETBUTTON || TBM_SETLINESIZE || TTM_GETTIPTEXTCOLOR", - 1048 : "RB_BEGINDRAG || TB_BUTTONCOUNT || TBM_GETLINESIZE || TTM_SETMAXTIPWIDTH", - 1049 : "RB_ENDDRAG || TB_COMMANDTOINDEX || TBM_GETTHUMBRECT || TTM_GETMAXTIPWIDTH", - 1050 : "RB_DRAGMOVE || TBM_GETCHANNELRECT || TB_SAVERESTOREA || TTM_SETMARGIN", - 1051 : "RB_GETBARHEIGHT || TB_CUSTOMIZE || TBM_SETTHUMBLENGTH || TTM_GETMARGIN", - 1052 : "RB_GETBANDINFOW || TB_ADDSTRINGA || TBM_GETTHUMBLENGTH || TTM_POP", - 1053 : "RB_GETBANDINFOA || TB_GETITEMRECT || TBM_SETTOOLTIPS || TTM_UPDATE", - 1054 : "RB_MINIMIZEBAND || TB_BUTTONSTRUCTSIZE || TBM_GETTOOLTIPS || TTM_GETBUBBLESIZE", - 1055 : "RB_MAXIMIZEBAND || TBM_SETTIPSIDE || TB_SETBUTTONSIZE || TTM_ADJUSTRECT", - 1056 : "TBM_SETBUDDY || TB_SETBITMAPSIZE || TTM_SETTITLEA", - 1057 : "MSG_FTS_JUMP_VA || TB_AUTOSIZE || TBM_GETBUDDY || TTM_SETTITLEW", - 1058 : "RB_GETBANDBORDERS", - 1059 : "MSG_FTS_JUMP_QWORD || RB_SHOWBAND || TB_GETTOOLTIPS", - 1060 : "MSG_REINDEX_REQUEST || TB_SETTOOLTIPS", - 1061 : "MSG_FTS_WHERE_IS_IT || RB_SETPALETTE || TB_SETPARENT", - 1062 : "RB_GETPALETTE", - 1063 : "RB_MOVEBAND || TB_SETROWS", - 1064 : "TB_GETROWS", - 1065 : "TB_GETBITMAPFLAGS", - 1066 : "TB_SETCMDID", - 1067 : "RB_PUSHCHEVRON || TB_CHANGEBITMAP", - 1068 : "TB_GETBITMAP", - 1069 : "MSG_GET_DEFFONT || TB_GETBUTTONTEXTA", - 1070 : "TB_REPLACEBITMAP", - 1071 : "TB_SETINDENT", - 1072 : "TB_SETIMAGELIST", - 1073 : "TB_GETIMAGELIST", - 1074 : "TB_LOADIMAGES || EM_CANPASTE || TTM_ADDTOOLW", - 1075 : "EM_DISPLAYBAND || TB_GETRECT || TTM_DELTOOLW", - 1076 : "EM_EXGETSEL || TB_SETHOTIMAGELIST || TTM_NEWTOOLRECTW", - 1077 : "EM_EXLIMITTEXT || TB_GETHOTIMAGELIST || TTM_GETTOOLINFOW", - 1078 : "EM_EXLINEFROMCHAR || TB_SETDISABLEDIMAGELIST || TTM_SETTOOLINFOW", - 1079 : "EM_EXSETSEL || TB_GETDISABLEDIMAGELIST || TTM_HITTESTW", - 1080 : "EM_FINDTEXT || TB_SETSTYLE || TTM_GETTEXTW", - 1081 : "EM_FORMATRANGE || TB_GETSTYLE || TTM_UPDATETIPTEXTW", - 1082 : "EM_GETCHARFORMAT || TB_GETBUTTONSIZE || TTM_ENUMTOOLSW", - 1083 : "EM_GETEVENTMASK || TB_SETBUTTONWIDTH || TTM_GETCURRENTTOOLW", - 1084 : "EM_GETOLEINTERFACE || TB_SETMAXTEXTROWS", - 1085 : "EM_GETPARAFORMAT || TB_GETTEXTROWS", - 1086 : "EM_GETSELTEXT || TB_GETOBJECT", - 1087 : "EM_HIDESELECTION || TB_GETBUTTONINFOW", - 1088 : "EM_PASTESPECIAL || TB_SETBUTTONINFOW", - 1089 : "EM_REQUESTRESIZE || TB_GETBUTTONINFOA", - 1090 : "EM_SELECTIONTYPE || TB_SETBUTTONINFOA", - 1091 : "EM_SETBKGNDCOLOR || TB_INSERTBUTTONW", - 1092 : "EM_SETCHARFORMAT || TB_ADDBUTTONSW", - 1093 : "EM_SETEVENTMASK || TB_HITTEST", - 1094 : "EM_SETOLECALLBACK || TB_SETDRAWTEXTFLAGS", - 1095 : "EM_SETPARAFORMAT || TB_GETHOTITEM", - 1096 : "EM_SETTARGETDEVICE || TB_SETHOTITEM", - 1097 : "EM_STREAMIN || TB_SETANCHORHIGHLIGHT", - 1098 : "EM_STREAMOUT || TB_GETANCHORHIGHLIGHT", - 1099 : "EM_GETTEXTRANGE || TB_GETBUTTONTEXTW", - 1100 : "EM_FINDWORDBREAK || TB_SAVERESTOREW", - 1101 : "EM_SETOPTIONS || TB_ADDSTRINGW", - 1102 : "EM_GETOPTIONS || TB_MAPACCELERATORA", - 1103 : "EM_FINDTEXTEX || TB_GETINSERTMARK", - 1104 : "EM_GETWORDBREAKPROCEX || TB_SETINSERTMARK", - 1105 : "EM_SETWORDBREAKPROCEX || TB_INSERTMARKHITTEST", - 1106 : "EM_SETUNDOLIMIT || TB_MOVEBUTTON", - 1107 : "TB_GETMAXSIZE", - 1108 : "EM_REDO || TB_SETEXTENDEDSTYLE", - 1109 : "EM_CANREDO || TB_GETEXTENDEDSTYLE", - 1110 : "EM_GETUNDONAME || TB_GETPADDING", - 1111 : "EM_GETREDONAME || TB_SETPADDING", - 1112 : "EM_STOPGROUPTYPING || TB_SETINSERTMARKCOLOR", - 1113 : "EM_SETTEXTMODE || TB_GETINSERTMARKCOLOR", - 1114 : "EM_GETTEXTMODE || TB_MAPACCELERATORW", - 1115 : "EM_AUTOURLDETECT || TB_GETSTRINGW", - 1116 : "EM_GETAUTOURLDETECT || TB_GETSTRINGA", - 1117 : "EM_SETPALETTE", - 1118 : "EM_GETTEXTEX", - 1119 : "EM_GETTEXTLENGTHEX", - 1120 : "EM_SHOWSCROLLBAR", - 1121 : "EM_SETTEXTEX", - 1123 : "TAPI_REPLY", - 1124 : "ACM_OPENA || BFFM_SETSTATUSTEXTA || CDM_GETSPEC || EM_SETPUNCTUATION || IPM_CLEARADDRESS || WM_CAP_UNICODE_START", - 1125 : "ACM_PLAY || BFFM_ENABLEOK || CDM_GETFILEPATH || EM_GETPUNCTUATION || IPM_SETADDRESS || PSM_SETCURSEL || UDM_SETRANGE || WM_CHOOSEFONT_SETLOGFONT", - 1126 : "ACM_STOP || BFFM_SETSELECTIONA || CDM_GETFOLDERPATH || EM_SETWORDWRAPMODE || IPM_GETADDRESS || PSM_REMOVEPAGE || UDM_GETRANGE || WM_CAP_SET_CALLBACK_ERRORW || WM_CHOOSEFONT_SETFLAGS", - 1127 : "ACM_OPENW || BFFM_SETSELECTIONW || CDM_GETFOLDERIDLIST || EM_GETWORDWRAPMODE || IPM_SETRANGE || PSM_ADDPAGE || UDM_SETPOS || WM_CAP_SET_CALLBACK_STATUSW", - 1128 : "BFFM_SETSTATUSTEXTW || CDM_SETCONTROLTEXT || EM_SETIMECOLOR || IPM_SETFOCUS || PSM_CHANGED || UDM_GETPOS", - 1129 : "CDM_HIDECONTROL || EM_GETIMECOLOR || IPM_ISBLANK || PSM_RESTARTWINDOWS || UDM_SETBUDDY", - 1130 : "CDM_SETDEFEXT || EM_SETIMEOPTIONS || PSM_REBOOTSYSTEM || UDM_GETBUDDY", - 1131 : "EM_GETIMEOPTIONS || PSM_CANCELTOCLOSE || UDM_SETACCEL", - 1132 : "EM_CONVPOSITION || PSM_QUERYSIBLINGS || UDM_GETACCEL", - 1133 : "MCIWNDM_GETZOOM || PSM_UNCHANGED || UDM_SETBASE", - 1134 : "PSM_APPLY || UDM_GETBASE", - 1135 : "PSM_SETTITLEA || UDM_SETRANGE32", - 1136 : "PSM_SETWIZBUTTONS || UDM_GETRANGE32 || WM_CAP_DRIVER_GET_NAMEW", - 1137 : "PSM_PRESSBUTTON || UDM_SETPOS32 || WM_CAP_DRIVER_GET_VERSIONW", - 1138 : "PSM_SETCURSELID || UDM_GETPOS32", - 1139 : "PSM_SETFINISHTEXTA", - 1140 : "PSM_GETTABCONTROL", - 1141 : "PSM_ISDIALOGMESSAGE", - 1142 : "MCIWNDM_REALIZE || PSM_GETCURRENTPAGEHWND", - 1143 : "MCIWNDM_SETTIMEFORMATA || PSM_INSERTPAGE", - 1144 : "EM_SETLANGOPTIONS || MCIWNDM_GETTIMEFORMATA || PSM_SETTITLEW || WM_CAP_FILE_SET_CAPTURE_FILEW", - 1145 : "EM_GETLANGOPTIONS || MCIWNDM_VALIDATEMEDIA || PSM_SETFINISHTEXTW || WM_CAP_FILE_GET_CAPTURE_FILEW", - 1146 : "EM_GETIMECOMPMODE", - 1147 : "EM_FINDTEXTW || MCIWNDM_PLAYTO || WM_CAP_FILE_SAVEASW", - 1148 : "EM_FINDTEXTEXW || MCIWNDM_GETFILENAMEA", - 1149 : "EM_RECONVERSION || MCIWNDM_GETDEVICEA || PSM_SETHEADERTITLEA || WM_CAP_FILE_SAVEDIBW", - 1150 : "EM_SETIMEMODEBIAS || MCIWNDM_GETPALETTE || PSM_SETHEADERTITLEW", - 1151 : "EM_GETIMEMODEBIAS || MCIWNDM_SETPALETTE || PSM_SETHEADERSUBTITLEA", - 1152 : "MCIWNDM_GETERRORA || PSM_SETHEADERSUBTITLEW", - 1153 : "PSM_HWNDTOINDEX", - 1154 : "PSM_INDEXTOHWND", - 1155 : "MCIWNDM_SETINACTIVETIMER || PSM_PAGETOINDEX", - 1156 : "PSM_INDEXTOPAGE", - 1157 : "DL_BEGINDRAG || MCIWNDM_GETINACTIVETIMER || PSM_IDTOINDEX", - 1158 : "DL_DRAGGING || PSM_INDEXTOID", - 1159 : "DL_DROPPED || PSM_GETRESULT", - 1160 : "DL_CANCELDRAG || PSM_RECALCPAGESIZES", - 1164 : "MCIWNDM_GET_SOURCE", - 1165 : "MCIWNDM_PUT_SOURCE", - 1166 : "MCIWNDM_GET_DEST", - 1167 : "MCIWNDM_PUT_DEST", - 1168 : "MCIWNDM_CAN_PLAY", - 1169 : "MCIWNDM_CAN_WINDOW", - 1170 : "MCIWNDM_CAN_RECORD", - 1171 : "MCIWNDM_CAN_SAVE", - 1172 : "MCIWNDM_CAN_EJECT", - 1173 : "MCIWNDM_CAN_CONFIG", - 1174 : "IE_GETINK || MCIWNDM_PALETTEKICK", - 1175 : "IE_SETINK", - 1176 : "IE_GETPENTIP", - 1177 : "IE_SETPENTIP", - 1178 : "IE_GETERASERTIP", - 1179 : "IE_SETERASERTIP", - 1180 : "IE_GETBKGND", - 1181 : "IE_SETBKGND", - 1182 : "IE_GETGRIDORIGIN", - 1183 : "IE_SETGRIDORIGIN", - 1184 : "IE_GETGRIDPEN", - 1185 : "IE_SETGRIDPEN", - 1186 : "IE_GETGRIDSIZE", - 1187 : "IE_SETGRIDSIZE", - 1188 : "IE_GETMODE", - 1189 : "IE_SETMODE", - 1190 : "IE_GETINKRECT || WM_CAP_SET_MCI_DEVICEW", - 1191 : "WM_CAP_GET_MCI_DEVICEW", - 1204 : "WM_CAP_PAL_OPENW", - 1205 : "WM_CAP_PAL_SAVEW", - 1208 : "IE_GETAPPDATA", - 1209 : "IE_SETAPPDATA", - 1210 : "IE_GETDRAWOPTS", - 1211 : "IE_SETDRAWOPTS", - 1212 : "IE_GETFORMAT", - 1213 : "IE_SETFORMAT", - 1214 : "IE_GETINKINPUT", - 1215 : "IE_SETINKINPUT", - 1216 : "IE_GETNOTIFY", - 1217 : "IE_SETNOTIFY", - 1218 : "IE_GETRECOG", - 1219 : "IE_SETRECOG", - 1220 : "IE_GETSECURITY", - 1221 : "IE_SETSECURITY", - 1222 : "IE_GETSEL", - 1223 : "IE_SETSEL", - 1224 : "EM_SETBIDIOPTIONS || IE_DOCOMMAND || MCIWNDM_NOTIFYMODE", - 1225 : "EM_GETBIDIOPTIONS || IE_GETCOMMAND", - 1226 : "EM_SETTYPOGRAPHYOPTIONS || IE_GETCOUNT", - 1227 : "EM_GETTYPOGRAPHYOPTIONS || IE_GETGESTURE || MCIWNDM_NOTIFYMEDIA", - 1228 : "EM_SETEDITSTYLE || IE_GETMENU", - 1229 : "EM_GETEDITSTYLE || IE_GETPAINTDC || MCIWNDM_NOTIFYERROR", - 1230 : "IE_GETPDEVENT", - 1231 : "IE_GETSELCOUNT", - 1232 : "IE_GETSELITEMS", - 1233 : "IE_GETSTYLE", - 1243 : "MCIWNDM_SETTIMEFORMATW", - 1244 : "EM_OUTLINE || MCIWNDM_GETTIMEFORMATW", - 1245 : "EM_GETSCROLLPOS", - 1246 : "EM_SETSCROLLPOS", - 1247 : "EM_SETFONTSIZE", - 1248 : "EM_GETZOOM || MCIWNDM_GETFILENAMEW", - 1249 : "EM_SETZOOM || MCIWNDM_GETDEVICEW", - 1250 : "EM_GETVIEWKIND", - 1251 : "EM_SETVIEWKIND", - 1252 : "EM_GETPAGE || MCIWNDM_GETERRORW", - 1253 : "EM_SETPAGE", - 1254 : "EM_GETHYPHENATEINFO", - 1255 : "EM_SETHYPHENATEINFO", - 1259 : "EM_GETPAGEROTATE", - 1260 : "EM_SETPAGEROTATE", - 1261 : "EM_GETCTFMODEBIAS", - 1262 : "EM_SETCTFMODEBIAS", - 1264 : "EM_GETCTFOPENSTATUS", - 1265 : "EM_SETCTFOPENSTATUS", - 1266 : "EM_GETIMECOMPTEXT", - 1267 : "EM_ISIME", - 1268 : "EM_GETIMEPROPERTY", - 1293 : "EM_GETQUERYRTFOBJ", - 1294 : "EM_SETQUERYRTFOBJ", - 1536 : "FM_GETFOCUS", - 1537 : "FM_GETDRIVEINFOA", - 1538 : "FM_GETSELCOUNT", - 1539 : "FM_GETSELCOUNTLFN", - 1540 : "FM_GETFILESELA", - 1541 : "FM_GETFILESELLFNA", - 1542 : "FM_REFRESH_WINDOWS", - 1543 : "FM_RELOAD_EXTENSIONS", - 1553 : "FM_GETDRIVEINFOW", - 1556 : "FM_GETFILESELW", - 1557 : "FM_GETFILESELLFNW", - 1625 : "WLX_WM_SAS", - 2024 : "SM_GETSELCOUNT || UM_GETSELCOUNT || WM_CPL_LAUNCH", - 2025 : "SM_GETSERVERSELA || UM_GETUSERSELA || WM_CPL_LAUNCHED", - 2026 : "SM_GETSERVERSELW || UM_GETUSERSELW", - 2027 : "SM_GETCURFOCUSA || UM_GETGROUPSELA", - 2028 : "SM_GETCURFOCUSW || UM_GETGROUPSELW", - 2029 : "SM_GETOPTIONS || UM_GETCURFOCUSA", - 2030 : "UM_GETCURFOCUSW", - 2031 : "UM_GETOPTIONS", - 2032 : "UM_GETOPTIONS2", - 4096 : "LVM_GETBKCOLOR", - 4097 : "LVM_SETBKCOLOR", - 4098 : "LVM_GETIMAGELIST", - 4099 : "LVM_SETIMAGELIST", - 4100 : "LVM_GETITEMCOUNT", - 4101 : "LVM_GETITEMA", - 4102 : "LVM_SETITEMA", - 4103 : "LVM_INSERTITEMA", - 4104 : "LVM_DELETEITEM", - 4105 : "LVM_DELETEALLITEMS", - 4106 : "LVM_GETCALLBACKMASK", - 4107 : "LVM_SETCALLBACKMASK", - 4108 : "LVM_GETNEXTITEM", - 4109 : "LVM_FINDITEMA", - 4110 : "LVM_GETITEMRECT", - 4111 : "LVM_SETITEMPOSITION", - 4112 : "LVM_GETITEMPOSITION", - 4113 : "LVM_GETSTRINGWIDTHA", - 4114 : "LVM_HITTEST", - 4115 : "LVM_ENSUREVISIBLE", - 4116 : "LVM_SCROLL", - 4117 : "LVM_REDRAWITEMS", - 4118 : "LVM_ARRANGE", - 4119 : "LVM_EDITLABELA", - 4120 : "LVM_GETEDITCONTROL", - 4121 : "LVM_GETCOLUMNA", - 4122 : "LVM_SETCOLUMNA", - 4123 : "LVM_INSERTCOLUMNA", - 4124 : "LVM_DELETECOLUMN", - 4125 : "LVM_GETCOLUMNWIDTH", - 4126 : "LVM_SETCOLUMNWIDTH", - 4127 : "LVM_GETHEADER", - 4129 : "LVM_CREATEDRAGIMAGE", - 4130 : "LVM_GETVIEWRECT", - 4131 : "LVM_GETTEXTCOLOR", - 4132 : "LVM_SETTEXTCOLOR", - 4133 : "LVM_GETTEXTBKCOLOR", - 4134 : "LVM_SETTEXTBKCOLOR", - 4135 : "LVM_GETTOPINDEX", - 4136 : "LVM_GETCOUNTPERPAGE", - 4137 : "LVM_GETORIGIN", - 4138 : "LVM_UPDATE", - 4139 : "LVM_SETITEMSTATE", - 4140 : "LVM_GETITEMSTATE", - 4141 : "LVM_GETITEMTEXTA", - 4142 : "LVM_SETITEMTEXTA", - 4143 : "LVM_SETITEMCOUNT", - 4144 : "LVM_SORTITEMS", - 4145 : "LVM_SETITEMPOSITION32", - 4146 : "LVM_GETSELECTEDCOUNT", - 4147 : "LVM_GETITEMSPACING", - 4148 : "LVM_GETISEARCHSTRINGA", - 4149 : "LVM_SETICONSPACING", - 4150 : "LVM_SETEXTENDEDLISTVIEWSTYLE", - 4151 : "LVM_GETEXTENDEDLISTVIEWSTYLE", - 4152 : "LVM_GETSUBITEMRECT", - 4153 : "LVM_SUBITEMHITTEST", - 4154 : "LVM_SETCOLUMNORDERARRAY", - 4155 : "LVM_GETCOLUMNORDERARRAY", - 4156 : "LVM_SETHOTITEM", - 4157 : "LVM_GETHOTITEM", - 4158 : "LVM_SETHOTCURSOR", - 4159 : "LVM_GETHOTCURSOR", - 4160 : "LVM_APPROXIMATEVIEWRECT", - 4161 : "LVM_SETWORKAREAS", - 4162 : "LVM_GETSELECTIONMARK", - 4163 : "LVM_SETSELECTIONMARK", - 4164 : "LVM_SETBKIMAGEA", - 4165 : "LVM_GETBKIMAGEA", - 4166 : "LVM_GETWORKAREAS", - 4167 : "LVM_SETHOVERTIME", - 4168 : "LVM_GETHOVERTIME", - 4169 : "LVM_GETNUMBEROFWORKAREAS", - 4170 : "LVM_SETTOOLTIPS", - 4171 : "LVM_GETITEMW", - 4172 : "LVM_SETITEMW", - 4173 : "LVM_INSERTITEMW", - 4174 : "LVM_GETTOOLTIPS", - 4179 : "LVM_FINDITEMW", - 4183 : "LVM_GETSTRINGWIDTHW", - 4191 : "LVM_GETCOLUMNW", - 4192 : "LVM_SETCOLUMNW", - 4193 : "LVM_INSERTCOLUMNW", - 4211 : "LVM_GETITEMTEXTW", - 4212 : "LVM_SETITEMTEXTW", - 4213 : "LVM_GETISEARCHSTRINGW", - 4214 : "LVM_EDITLABELW", - 4235 : "LVM_GETBKIMAGEW", - 4236 : "LVM_SETSELECTEDCOLUMN", - 4237 : "LVM_SETTILEWIDTH", - 4238 : "LVM_SETVIEW", - 4239 : "LVM_GETVIEW", - 4241 : "LVM_INSERTGROUP", - 4243 : "LVM_SETGROUPINFO", - 4245 : "LVM_GETGROUPINFO", - 4246 : "LVM_REMOVEGROUP", - 4247 : "LVM_MOVEGROUP", - 4250 : "LVM_MOVEITEMTOGROUP", - 4251 : "LVM_SETGROUPMETRICS", - 4252 : "LVM_GETGROUPMETRICS", - 4253 : "LVM_ENABLEGROUPVIEW", - 4254 : "LVM_SORTGROUPS", - 4255 : "LVM_INSERTGROUPSORTED", - 4256 : "LVM_REMOVEALLGROUPS", - 4257 : "LVM_HASGROUP", - 4258 : "LVM_SETTILEVIEWINFO", - 4259 : "LVM_GETTILEVIEWINFO", - 4260 : "LVM_SETTILEINFO", - 4261 : "LVM_GETTILEINFO", - 4262 : "LVM_SETINSERTMARK", - 4263 : "LVM_GETINSERTMARK", - 4264 : "LVM_INSERTMARKHITTEST", - 4265 : "LVM_GETINSERTMARKRECT", - 4266 : "LVM_SETINSERTMARKCOLOR", - 4267 : "LVM_GETINSERTMARKCOLOR", - 4269 : "LVM_SETINFOTIP", - 4270 : "LVM_GETSELECTEDCOLUMN", - 4271 : "LVM_ISGROUPVIEWENABLED", - 4272 : "LVM_GETOUTLINECOLOR", - 4273 : "LVM_SETOUTLINECOLOR", - 4275 : "LVM_CANCELEDITLABEL", - 4276 : "LVM_MAPINDEXTOID", - 4277 : "LVM_MAPIDTOINDEX", - 4278 : "LVM_ISITEMVISIBLE", - 8192 : "OCM__BASE", - 8197 : "LVM_SETUNICODEFORMAT", - 8198 : "LVM_GETUNICODEFORMAT", - 8217 : "OCM_CTLCOLOR", - 8235 : "OCM_DRAWITEM", - 8236 : "OCM_MEASUREITEM", - 8237 : "OCM_DELETEITEM", - 8238 : "OCM_VKEYTOITEM", - 8239 : "OCM_CHARTOITEM", - 8249 : "OCM_COMPAREITEM", - 8270 : "OCM_NOTIFY", - 8465 : "OCM_COMMAND", - 8468 : "OCM_HSCROLL", - 8469 : "OCM_VSCROLL", - 8498 : "OCM_CTLCOLORMSGBOX", - 8499 : "OCM_CTLCOLOREDIT", - 8500 : "OCM_CTLCOLORLISTBOX", - 8501 : "OCM_CTLCOLORBTN", - 8502 : "OCM_CTLCOLORDLG", - 8503 : "OCM_CTLCOLORSCROLLBAR", - 8504 : "OCM_CTLCOLORSTATIC", - 8720 : "OCM_PARENTNOTIFY", - 32768 : "WM_APP", - 52429 : "WM_RASDIALEVENT" - ] -} diff --git a/Sources/SwiftWin32/Support/WindowsHandle+UIExtensions.swift b/Sources/SwiftWin32/Support/WindowsHandle+UIExtensions.swift deleted file mode 100644 index edd7df4c..00000000 --- a/Sources/SwiftWin32/Support/WindowsHandle+UIExtensions.swift +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import WinSDK - -extension HBITMAP__: HandleValue { - typealias HandleType = HBITMAP - internal static func release(_ hBitmap: HandleType?) { - if let hBitmap = hBitmap { - DeleteObject(hBitmap) - } - } -} - -internal typealias BitmapHandle = ManagedHandle - -extension HBRUSH__: HandleValue { - typealias HandleType = HBRUSH - internal static func release(_ hBrush: HandleType?) { - if let hBrush = hBrush { - DeleteObject(hBrush) - } - } -} - -internal typealias BrushHandle = ManagedHandle - -extension HDC__: HandleValue { - typealias HandleType = HDC - internal static func release(_ hDC: HandleType?) { - if let hDC = hDC { - DeleteDC(hDC) - } - } -} - -internal typealias DeviceContextHandle = ManagedHandle - -extension HFONT__: HandleValue { - typealias HandleType = HFONT - internal static func release(_ hFont: HandleType?) { - if let hFont = hFont { - DeleteObject(hFont) - } - } -} - -internal typealias FontHandle = ManagedHandle - -extension HMENU: HandleValue { - typealias HandleType = HMENU - internal static func release(_ hMenu: HandleType?) { - if let hMenu = hMenu { - DestroyMenu(hMenu) - } - } -} - -internal typealias MenuHandle = ManagedHandle diff --git a/Sources/SwiftWin32/Text Display and Fonts/Font.swift b/Sources/SwiftWin32/Text Display and Fonts/Font.swift deleted file mode 100644 index 3b505eaa..00000000 --- a/Sources/SwiftWin32/Text Display and Fonts/Font.swift +++ /dev/null @@ -1,672 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import WinSDK - -// Values derived from the Apple Human Inteface Guidelines -// https://developer.apple.com/design/human-interface-guidelines/ios/visual-design/typography -private typealias TypographyInfo = (weight: Font.Weight, size: Double, leading: Int) -private let typography: [ContentSizeCategory:[Font.TextStyle:TypographyInfo]] = [ - .extraSmall: [ - .largeTitle: TypographyInfo(weight: .regular, size: 31, leading: 38), - .title1: TypographyInfo(weight: .regular, size: 25, leading: 31), - .title2: TypographyInfo(weight: .regular, size: 19, leading: 24), - .title3: TypographyInfo(weight: .regular, size: 17, leading: 22), - .headline: TypographyInfo(weight: .semibold, size: 14, leading: 19), - .body: TypographyInfo(weight: .regular, size: 14, leading: 19), - .callout: TypographyInfo(weight: .regular, size: 13, leading: 18), - .subheadline: TypographyInfo(weight: .regular, size: 12, leading: 16), - .footnote: TypographyInfo(weight: .regular, size: 12, leading: 16), - .caption1: TypographyInfo(weight: .regular, size: 11, leading: 13), - .caption2: TypographyInfo(weight: .regular, size: 11, leading: 13), - ], - .small: [ - .largeTitle: TypographyInfo(weight: .regular, size: 32, leading: 39), - .title1: TypographyInfo(weight: .regular, size: 26, leading: 32), - .title2: TypographyInfo(weight: .regular, size: 20, leading: 25), - .title3: TypographyInfo(weight: .regular, size: 18, leading: 23), - .headline: TypographyInfo(weight: .semibold, size: 15, leading: 20), - .body: TypographyInfo(weight: .regular, size: 15, leading: 20), - .callout: TypographyInfo(weight: .regular, size: 14, leading: 19), - .subheadline: TypographyInfo(weight: .regular, size: 13, leading: 18), - .footnote: TypographyInfo(weight: .regular, size: 12, leading: 16), - .caption1: TypographyInfo(weight: .regular, size: 11, leading: 13), - .caption2: TypographyInfo(weight: .regular, size: 11, leading: 13), - ], - .medium: [ - .largeTitle: TypographyInfo(weight: .regular, size: 33, leading: 40), - .title1: TypographyInfo(weight: .regular, size: 27, leading: 33), - .title2: TypographyInfo(weight: .regular, size: 21, leading: 26), - .title3: TypographyInfo(weight: .regular, size: 19, leading: 24), - .headline: TypographyInfo(weight: .semibold, size: 16, leading: 21), - .body: TypographyInfo(weight: .regular, size: 16, leading: 21), - .callout: TypographyInfo(weight: .regular, size: 15, leading: 20), - .subheadline: TypographyInfo(weight: .regular, size: 14, leading: 19), - .footnote: TypographyInfo(weight: .regular, size: 12, leading: 16), - .caption1: TypographyInfo(weight: .regular, size: 11, leading: 13), - .caption2: TypographyInfo(weight: .regular, size: 11, leading: 13), - ], - .large: [ - .largeTitle: TypographyInfo(weight: .regular, size: 34, leading: 41), - .title1: TypographyInfo(weight: .regular, size: 28, leading: 34), - .title2: TypographyInfo(weight: .regular, size: 22, leading: 28), - .title3: TypographyInfo(weight: .regular, size: 20, leading: 25), - .headline: TypographyInfo(weight: .semibold, size: 17, leading: 22), - .body: TypographyInfo(weight: .regular, size: 17, leading: 22), - .callout: TypographyInfo(weight: .regular, size: 16, leading: 21), - .subheadline: TypographyInfo(weight: .regular, size: 15, leading: 20), - .footnote: TypographyInfo(weight: .regular, size: 13, leading: 18), - .caption1: TypographyInfo(weight: .regular, size: 12, leading: 16), - .caption2: TypographyInfo(weight: .regular, size: 11, leading: 13), - ], - .extraLarge: [ - .largeTitle: TypographyInfo(weight: .regular, size: 36, leading: 43), - .title1: TypographyInfo(weight: .regular, size: 30, leading: 37), - .title2: TypographyInfo(weight: .regular, size: 24, leading: 30), - .title3: TypographyInfo(weight: .regular, size: 22, leading: 28), - .headline: TypographyInfo(weight: .semibold, size: 19, leading: 24), - .body: TypographyInfo(weight: .regular, size: 19, leading: 24), - .callout: TypographyInfo(weight: .regular, size: 18, leading: 23), - .subheadline: TypographyInfo(weight: .regular, size: 17, leading: 22), - .footnote: TypographyInfo(weight: .regular, size: 15, leading: 20), - .caption1: TypographyInfo(weight: .regular, size: 14, leading: 19), - .caption2: TypographyInfo(weight: .regular, size: 13, leading: 18), - ], - .extraExtraLarge: [ - .largeTitle: TypographyInfo(weight: .regular, size: 38, leading: 46), - .title1: TypographyInfo(weight: .regular, size: 32, leading: 39), - .title2: TypographyInfo(weight: .regular, size: 26, leading: 32), - .title3: TypographyInfo(weight: .regular, size: 24, leading: 30), - .headline: TypographyInfo(weight: .semibold, size: 21, leading: 26), - .body: TypographyInfo(weight: .regular, size: 21, leading: 26), - .callout: TypographyInfo(weight: .regular, size: 20, leading: 25), - .subheadline: TypographyInfo(weight: .regular, size: 19, leading: 24), - .footnote: TypographyInfo(weight: .regular, size: 17, leading: 22), - .caption1: TypographyInfo(weight: .regular, size: 16, leading: 21), - .caption2: TypographyInfo(weight: .regular, size: 15, leading: 20), - ], - .extraExtraExtraLarge: [ - .largeTitle: TypographyInfo(weight: .regular, size: 40, leading: 48), - .title1: TypographyInfo(weight: .regular, size: 34, leading: 41), - .title2: TypographyInfo(weight: .regular, size: 28, leading: 34), - .title3: TypographyInfo(weight: .regular, size: 26, leading: 32), - .headline: TypographyInfo(weight: .semibold, size: 23, leading: 29), - .body: TypographyInfo(weight: .regular, size: 23, leading: 29), - .callout: TypographyInfo(weight: .regular, size: 22, leading: 28), - .subheadline: TypographyInfo(weight: .regular, size: 21, leading: 28), - .footnote: TypographyInfo(weight: .regular, size: 19, leading: 24), - .caption1: TypographyInfo(weight: .regular, size: 18, leading: 23), - .caption2: TypographyInfo(weight: .regular, size: 17, leading: 22), - ], - .accessibilityMedium: [ - .largeTitle: TypographyInfo(weight: .regular, size: 44, leading: 52), - .title1: TypographyInfo(weight: .regular, size: 38, leading: 46), - .title2: TypographyInfo(weight: .regular, size: 34, leading: 41), - .title3: TypographyInfo(weight: .regular, size: 31, leading: 38), - .headline: TypographyInfo(weight: .semibold, size: 28, leading: 34), - .body: TypographyInfo(weight: .regular, size: 28, leading: 34), - .callout: TypographyInfo(weight: .regular, size: 26, leading: 32), - .subheadline: TypographyInfo(weight: .regular, size: 25, leading: 31), - .footnote: TypographyInfo(weight: .regular, size: 23, leading: 29), - .caption1: TypographyInfo(weight: .regular, size: 22, leading: 28), - .caption2: TypographyInfo(weight: .regular, size: 20, leading: 25), - ], - .accessibilityLarge: [ - .largeTitle: TypographyInfo(weight: .regular, size: 48, leading: 57), - .title1: TypographyInfo(weight: .regular, size: 43, leading: 51), - .title2: TypographyInfo(weight: .regular, size: 39, leading: 47), - .title3: TypographyInfo(weight: .regular, size: 37, leading: 44), - .headline: TypographyInfo(weight: .semibold, size: 33, leading: 40), - .body: TypographyInfo(weight: .regular, size: 33, leading: 40), - .callout: TypographyInfo(weight: .regular, size: 32, leading: 39), - .subheadline: TypographyInfo(weight: .regular, size: 30, leading: 37), - .footnote: TypographyInfo(weight: .regular, size: 27, leading: 33), - .caption1: TypographyInfo(weight: .regular, size: 26, leading: 32), - .caption2: TypographyInfo(weight: .regular, size: 24, leading: 30), - ], - .accessibilityExtraLarge: [ - .largeTitle: TypographyInfo(weight: .regular, size: 52, leading: 61), - .title1: TypographyInfo(weight: .regular, size: 48, leading: 57), - .title2: TypographyInfo(weight: .regular, size: 44, leading: 52), - .title3: TypographyInfo(weight: .regular, size: 43, leading: 51), - .headline: TypographyInfo(weight: .semibold, size: 40, leading: 48), - .body: TypographyInfo(weight: .regular, size: 40, leading: 48), - .callout: TypographyInfo(weight: .regular, size: 38, leading: 46), - .subheadline: TypographyInfo(weight: .regular, size: 36, leading: 43), - .footnote: TypographyInfo(weight: .regular, size: 33, leading: 40), - .caption1: TypographyInfo(weight: .regular, size: 32, leading: 39), - .caption2: TypographyInfo(weight: .regular, size: 29, leading: 35), - ], - .accessibilityExtraExtraLarge: [ - .largeTitle: TypographyInfo(weight: .regular, size: 56, leading: 66), - .title1: TypographyInfo(weight: .regular, size: 53, leading: 62), - .title2: TypographyInfo(weight: .regular, size: 50, leading: 59), - .title3: TypographyInfo(weight: .regular, size: 49, leading: 58), - .headline: TypographyInfo(weight: .semibold, size: 47, leading: 56), - .body: TypographyInfo(weight: .regular, size: 47, leading: 56), - .callout: TypographyInfo(weight: .regular, size: 44, leading: 52), - .subheadline: TypographyInfo(weight: .regular, size: 42, leading: 50), - .footnote: TypographyInfo(weight: .regular, size: 38, leading: 46), - .caption1: TypographyInfo(weight: .regular, size: 37, leading: 44), - .caption2: TypographyInfo(weight: .regular, size: 34, leading: 41), - ], - .accessibilityExtraExtraExtraLarge: [ - .largeTitle: TypographyInfo(weight: .regular, size: 60, leading: 70), - .title1: TypographyInfo(weight: .regular, size: 58, leading: 68), - .title2: TypographyInfo(weight: .regular, size: 56, leading: 66), - .title3: TypographyInfo(weight: .regular, size: 55, leading: 65), - .headline: TypographyInfo(weight: .semibold, size: 53, leading: 62), - .body: TypographyInfo(weight: .regular, size: 53, leading: 62), - .callout: TypographyInfo(weight: .regular, size: 51, leading: 62), - .subheadline: TypographyInfo(weight: .regular, size: 49, leading: 58), - .footnote: TypographyInfo(weight: .regular, size: 44, leading: 52), - .caption1: TypographyInfo(weight: .regular, size: 43, leading: 51), - .caption2: TypographyInfo(weight: .regular, size: 40, leading: 47), - ], -] - -private func PointToLogical(_ points: Double) -> Int32 { - return -MulDiv(Int32(points), GetDeviceCaps(GetDC(nil), LOGPIXELSY), 72) -} - -private func LogicalToPoint(_ logical: Int32) -> Double { - return Double(MulDiv(-logical, 72, GetDeviceCaps(GetDC(nil), LOGPIXELSY))) -} - -/// Represents a font. -public class Font { - internal var hFont: FontHandle - - // MARK - Creating Fonts - - /// Returns an instance of the system font for the specified text style with - /// scaling for the user's selected content size category. - public static func preferredFont(forTextStyle style: Font.TextStyle) -> Font { - return Font.preferredFont(forTextStyle: style, compatibleWith: nil) - } - - /// Returns an instance of the system font for the appropriate text style and - /// traits. - public static func preferredFont(forTextStyle style: Font.TextStyle, - compatibleWith traits: TraitCollection?) - -> Font { - var size: ContentSizeCategory = traits?.preferredContentSizeCategory ?? .large - if size == .unspecified { size = .large } - - guard let font = typography[size]?[style] else { - log.error("\(#function) missing typography for \(style)@\(size)") - return systemFont(ofSize: 12) - } - - return systemFont(ofSize: font.size, weight: font.weight) - } - - /// Creates an returns a font object for the specified font name and size. - public init?(name: String, size: Double) { - self.hFont = FontHandle(owning: CreateFontW(PointToLogical(size), - /*cWidth=*/0, - /*cEscapement=*/0, - /*cOrientation=*/0, - Font.Weight.regular.rawValue, - /*bItalic=*/DWORD(0), - /*bUnderline=*/DWORD(0), - /*bStrikeOut=*/DWORD(0), - DWORD(DEFAULT_CHARSET), - DWORD(OUT_DEFAULT_PRECIS), - DWORD(CLIP_DEFAULT_PRECIS), - DWORD(DEFAULT_QUALITY), - DWORD((FF_DONTCARE << 2) | DEFAULT_PITCH), - name.wide)) - } - - // public init(descriptor: FontDescriptor, size pointSize: Double) - - // Returns a font object that is the ame as the font, but has the specified - // size. - public func withSize(_ fontSize: Double) -> Font { - var lfFont: LOGFONTW = LOGFONTW() - - if GetObjectW(self.hFont.value, Int32(MemoryLayout.size), - &lfFont) == 0 { - log.error("GetObjectW: \(Error(win32: GetLastError()))") - return self - } - lfFont.lfHeight = PointToLogical(fontSize) - - return Font(owning: CreateFontIndirectW(&lfFont)) - } - - // MARK - Creating System Fonts - - /// Returns the font object for standard interface items in the specified - /// size. - public static func systemFont(ofSize fontSize: Double) -> Font { - return systemFont(ofSize: fontSize, weight: .regular, italic: false) - } - - /// Returns the font object for standard interface items in the specifed size - /// and weight. - public static func systemFont(ofSize fontSize: Double, weight: Font.Weight) - -> Font { - return systemFont(ofSize: fontSize, weight: weight, italic: false) - } - - /// Returns the font object for standard interface items in boldface type in - /// the specified size. - public static func boldSystemFont(ofSize fontSize: Double) -> Font { - return systemFont(ofSize: fontSize, weight: .bold, italic: false) - } - - /// Returns the font object for standard interface items in italic type in the - /// specified size. - public static func italicSystemFont(ofSize fontSize: Double) -> Font { - return systemFont(ofSize: fontSize, weight: .regular, italic: true) - } - - /// Returns the fixed-width font for standard interface text in the specified - /// size. - public static func monospacedSystemFont(ofSize fontSize: Double, - weight: Font.Weight) -> Font { - return Font(owning: CreateFontW(PointToLogical(fontSize), - /*cWidth=*/0, - /*cEscapement=*/0, - /*cOrientation=*/0, - weight.rawValue, - /*bItalic=*/DWORD(0), - /*bUnderline=*/DWORD(0), - /*bStrikeOut=*/DWORD(0), - DWORD(DEFAULT_CHARSET), - DWORD(OUT_DEFAULT_PRECIS), - DWORD(CLIP_DEFAULT_PRECIS), - DWORD(DEFAULT_QUALITY), - DWORD((FF_DONTCARE << 2) | FIXED_PITCH), - nil)) - } - - /// Returns the standard system font with all digits of consistent width. - public static func monospacedDigitSystemFont(ofSize fontSize: Double, - weight: Font.Weight) -> Font { - return Font(owning: CreateFontW(PointToLogical(fontSize), - /*cWidth=*/0, - /*cEscapement=*/0, - /*cOrientation=*/0, - weight.rawValue, - /*bItalic=*/DWORD(0), - /*bUnderline=*/DWORD(0), - /*bStrikeOut=*/DWORD(0), - DWORD(DEFAULT_CHARSET), - DWORD(OUT_DEFAULT_PRECIS), - DWORD(CLIP_DEFAULT_PRECIS), - DWORD(DEFAULT_QUALITY), - DWORD((FF_DONTCARE << 2) | FIXED_PITCH), - nil)) - } - - // MARK - Getting the Available Font Names - - /// Returns an array of font family names available on the system. - public static var familyNames: [String] { - let hDC: HDC = GetDC(nil) - - var arrFamilies: Set = [] - - var lfFont: LOGFONTW = LOGFONTW() - lfFont.lfCharSet = BYTE(DEFAULT_CHARSET) - - let pfnEnumerateFontFamilies: FONTENUMPROCW = { (lpelfe, lpnt, FontType, lParam) in - // NOTE: '@' indicates a vertical-oriented flags; treat the enumeration - // as if CF_NOVERTFONTS is specified. - let bVerticalFont: Bool = - UnicodeScalar(lpelfe?.pointee.lfFaceName.0 ?? 0) == UnicodeScalar("@") - if bVerticalFont { return 1 } - - let parrFamilies: UnsafeMutablePointer> = - UnsafeMutablePointer>(bitPattern: Int(lParam))! - - let family: String = withUnsafePointer(to: lpelfe?.pointee.lfFaceName) { - let capacity: Int = - MemoryLayout.size(ofValue: $0) / MemoryLayout.size - return $0.withMemoryRebound(to: UInt16.self, capacity: capacity) { - String(decodingCString: $0, as: UTF16.self) - } - } - - parrFamilies.pointee.insert(family) - return 1 - } - - _ = withUnsafeMutablePointer(to: &arrFamilies) { - EnumFontFamiliesExW(hDC, &lfFont, pfnEnumerateFontFamilies, - LPARAM(Int(bitPattern: $0)), 0) - } - return Array(arrFamilies) - } - - /// Returns an array of font names available in a particular font family. - public static func fontNames(forFontFamily family: String) -> [String] { - let hDC: HDC = GetDC(nil) - - var arrFonts: Set = [] - - let pfnEnumerateFonts: FONTENUMPROCW = { (lplf, lptm, dwType, lpData) in - let parrFonts: UnsafeMutablePointer> = - UnsafeMutablePointer>(bitPattern: Int(lpData))! - - let font: String = withUnsafePointer(to: lplf?.pointee.lfFaceName) { - let capacity: Int = - MemoryLayout.size(ofValue: $0) / MemoryLayout.size - return $0.withMemoryRebound(to: UInt16.self, capacity: capacity) { - String(decodingCString: $0, as: UTF16.self) - } - } - - parrFonts.pointee.insert(font) - return 1 - } - - _ = withUnsafeMutablePointer(to: &arrFonts) { - EnumFontsW(hDC, family.wide, pfnEnumerateFonts, - LPARAM(Int(bitPattern: $0))) - } - return Array(arrFonts) - } - - // MARK - Getting Font Name Attributes - - // public var familyName: String { } - - /// The font face name. - public var fontName: String { - var lfFont: LOGFONTW = LOGFONTW() - - if GetObjectW(self.hFont.value, Int32(MemoryLayout.size), - &lfFont) == 0 { - log.error("GetObjectW: \(Error(win32: GetLastError()))") - return "" - } - - return withUnsafePointer(to: &lfFont.lfFaceName) { - let capacity: Int = - MemoryLayout.size(ofValue: $0) / MemoryLayout.size - return $0.withMemoryRebound(to: UInt16.self, capacity: capacity) { - return String(decodingCString: $0, as: UTF16.self) - } - } - } - - // MARK - Getting Font Metrics - - /// The font's point size, or the effective vertical point size for a font - /// with a non-standard matrix. - public var pointSize: Double { - var lfFont: LOGFONTW = LOGFONTW() - - if GetObjectW(self.hFont.value, Int32(MemoryLayout.size), - &lfFont) == 0 { - log.error("GetObjectW: \(Error(win32: GetLastError()))") - return 0.0 - } - - return LogicalToPoint(lfFont.lfHeight) - } - - /// The top y-coordinate, offset from the baseline, of the font's longest - /// ascender. - public var ascender: Double { - let hDC: DeviceContextHandle = - DeviceContextHandle(owning: CreateCompatibleDC(nil)) - let _ = SelectObject(hDC.value, self.hFont.value) - - var metrics: TEXTMETRICW = TEXTMETRICW() - if !GetTextMetricsW(hDC.value, &metrics) { - log.warning("GetTextMetricsW: \(Error(win32: GetLastError()))") - return 0.0 - } - return Double(metrics.tmAscent) - } - - /// The bottom y-coordinate, offset from the baseline, of the font's longest - /// descender. - public var descender: Double { - let hDC: DeviceContextHandle = - DeviceContextHandle(owning: CreateCompatibleDC(nil)) - let _ = SelectObject(hDC.value, self.hFont.value) - - var metrics: TEXTMETRICW = TEXTMETRICW() - if !GetTextMetricsW(hDC.value, &metrics) { - log.warning("GetTextMetricsW: \(Error(win32: GetLastError()))") - return 0.0 - } - return Double(metrics.tmDescent) - } - - /// The font's leading information. - public var leading: Double { - let hDC: DeviceContextHandle = - DeviceContextHandle(owning: CreateCompatibleDC(nil)) - let _ = SelectObject(hDC.value, self.hFont.value) - - var metrics: TEXTMETRICW = TEXTMETRICW() - if !GetTextMetricsW(hDC.value, &metrics) { - log.warning("GetTextMetricsW: \(Error(win32: GetLastError()))") - return 0.0 - } - return Double(metrics.tmExternalLeading) - } - - /// The font's cap height information. - public var capHeight: Double { - let hDC: DeviceContextHandle = - DeviceContextHandle(owning: CreateCompatibleDC(nil)) - let _ = SelectObject(hDC.value, self.hFont.value) - - var size: SIZE = SIZE() - if !GetTextExtentPoint32W(hDC.value, "u{0048}".wide, 1, &size) { - log.warning("GetTextExtentPoint32W: \(Error(win32: GetLastError()))") - return 0.0 - } - return Double(size.cy) - } - - /// The x-height of the font. - public var xHeight: Double { - let hDC: DeviceContextHandle = - DeviceContextHandle(owning: CreateCompatibleDC(nil)) - let _ = SelectObject(hDC.value, self.hFont.value) - - var size: SIZE = SIZE() - if !GetTextExtentPoint32W(hDC.value, "u{0078}".wide, 1, &size) { - log.warning("GetTextExtentPoint32W: \(Error(win32: GetLastError()))") - return 0.0 - } - return Double(size.cy) - } - - /// The height, in points, of text lines. - // public var lineHeight: Double { } - - // MARK - Getting System Font Information - - /// The standard font size, in points, for labels. - public static var labelFontSize: Double { 17.0 } - - /// The standard font size, in points, for buttons. - public static var buttonFontSize: Double { 18.0 } - - /// The size, in points, of the standard small system font. - public static var smallSystemFontSize: Double { 12.0 } - - /// The size, in points, of the standard system font. - public static var systemFontSize: Double { 14.0 } - - /// Getting Font Descriptors - // public var fontDescriptor: FontDescriptor { } - - internal init(_ hFont: FontHandle) { - self.hFont = hFont - } - - private init(owning hFont: HFONT) { - self.hFont = FontHandle(owning: hFont) - } - - private static func systemFont(ofSize fontSize: Double, weight: Font.Weight, - italic bItalic: Bool) -> Font { - // Windows XP+ default fault name - var fontName: String = "Segoe UI" - - var metrics: NONCLIENTMETRICSW = NONCLIENTMETRICSW() - metrics.cbSize = UINT(MemoryLayout.size) - if SystemParametersInfoW(UINT(SPI_GETNONCLIENTMETRICS), - metrics.cbSize, &metrics, 0) { - fontName = withUnsafePointer(to: metrics.lfMessageFont.lfFaceName) { - let capacity: Int = - MemoryLayout.size(ofValue: $0) / MemoryLayout.size - return $0.withMemoryRebound(to: UInt16.self, capacity: capacity) { - String(decodingCString: $0, as: UTF16.self) - } - } - } - - return Font(owning: CreateFontW(PointToLogical(fontSize), - /*cWidth=*/0, - /*cEscapement=*/0, - /*cOrientation=*/0, - weight.rawValue, - bItalic ? 1 : 0, - /*bUnderline=*/DWORD(0), - /*bStrikeOut=*/DWORD(0), - DWORD(DEFAULT_CHARSET), - DWORD(OUT_DEFAULT_PRECIS), - DWORD(CLIP_DEFAULT_PRECIS), - DWORD(DEFAULT_QUALITY), - DWORD((FF_DONTCARE << 2) | DEFAULT_PITCH), - fontName.wide)) - } -} - -public extension Font { - /// Constants that represent standard font weights. - struct Weight: Hashable, Equatable, RawRepresentable { - public let rawValue: Int32 - - public init(rawValue: Int32) { - self.rawValue = rawValue - } - } -} - -public extension Font.Weight { - /// The ultra-light font weight. - static var ultraLight: Font.Weight { - Font.Weight(rawValue: FW_ULTRALIGHT) - } - - /// The thin font weight. - static var thin: Font.Weight { - Font.Weight(rawValue: FW_THIN) - } - - /// The light font weight. - static var light: Font.Weight { - Font.Weight(rawValue: FW_LIGHT) - } - - /// The regular font weight. - static var regular: Font.Weight { - Font.Weight(rawValue: FW_REGULAR) - } - - /// The medium font weight. - static var medium: Font.Weight { - Font.Weight(rawValue: FW_MEDIUM) - } - - /// The semibold font weight. - static var semibold: Font.Weight { - Font.Weight(rawValue: FW_SEMIBOLD) - } - - /// The bold font weight. - static var bold: Font.Weight { - Font.Weight(rawValue: FW_BOLD) - } - - /// The heavy font weight. - static var heavy: Font.Weight { - Font.Weight(rawValue: FW_HEAVY) - } - - /// The black font weight. - static var black: Font.Weight { - Font.Weight(rawValue: FW_BLACK) - } -} - -public extension Font { - /// Constants that describe the preferred styles for fonts. - struct TextStyle: Hashable, Equatable, RawRepresentable { - public let rawValue: String - - public init(rawValue: String) { - self.rawValue = rawValue - } - } -} - -public extension Font.TextStyle { - /// The font for body text. - static var body: Font.TextStyle { - Font.TextStyle(rawValue: "UICTFontTextStyleBody") - } - - /// The font for callouts. - static var callout: Font.TextStyle { - Font.TextStyle(rawValue: "UICTFontTextStyleCallout") - } - - /// The font for standard captions. - static var caption1: Font.TextStyle { - Font.TextStyle(rawValue: "UICTFontTextStyleCaption1") - } - - /// The font for alternate captions. - static var caption2: Font.TextStyle { - Font.TextStyle(rawValue: "UICTFontTextStyleCaption2") - } - - /// The font for footnotes. - static var footnote: Font.TextStyle { - Font.TextStyle(rawValue: "UICTFontTextStyleFootnote") - } - - /// The font for headings. - static var headline: Font.TextStyle { - Font.TextStyle(rawValue: "UICTFontTextStyleHeadline") - } - - /// The font for subheadings. - static var subheadline: Font.TextStyle { - Font.TextStyle(rawValue: "UICTFontTextStyleSubhead") - } - - /// The font style for large titles. - static var largeTitle: Font.TextStyle { - Font.TextStyle(rawValue: "UICTFontTextStyleTitle0") - } - - /// The font for first-level hierarchical headings. - static var title1: Font.TextStyle { - Font.TextStyle(rawValue: "UICTFontTextStyleTitle1") - } - - /// The font for second-level hierarchical headings. - static var title2: Font.TextStyle { - Font.TextStyle(rawValue: "UICTFontTextStyleTitle2") - } - - /// The font for third-level hierarchical headings. - static var title3: Font.TextStyle { - Font.TextStyle(rawValue: "UICTFontTextStyleTitle3") - } -} diff --git a/Sources/SwiftWin32/Text Display and Fonts/FontDescriptor.swift b/Sources/SwiftWin32/Text Display and Fonts/FontDescriptor.swift deleted file mode 100644 index 7fedfebc..00000000 --- a/Sources/SwiftWin32/Text Display and Fonts/FontDescriptor.swift +++ /dev/null @@ -1,469 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -#if swift(>=5.7) -import CoreGraphics -#endif - -/// A collection of attributes that describes a font. -public class FontDescriptor { - /// Constants that classify certain stylistic qualities of the font. - public typealias Class = Int - - /// Creating a Font Descriptor - - /// Returns a font descriptor that contains the specified text style and the - /// user's selected content size category. - public static func preferredFontDescriptor(withTextStyle style: Font.TextStyle) - -> FontDescriptor { - return preferredFontDescriptor(withTextStyle: style, - compatibleWith: TraitCollection.current) - } - - /// Returns a font descriptor that contains the text style and the content - /// size category the provided trait collection specifies. - public static func preferredFontDescriptor(withTextStyle style: Font.TextStyle, - compatibleWith traitCollection: TraitCollection?) - -> FontDescriptor { - fatalError("\(#function) not yet implemented") - } - - /// Returns a font descriptor with the specified values for name and matrix - /// dictionary attributes. - public init(name fontName: String, matrix: AffineTransform) { - self.fontAttributes = [.name: fontName, .matrix: matrix] - } - - /// Returns a font descriptor with the specified values for the name and size - /// dictionary attributes. - public init(name fontName: String, size: Double) { - self.fontAttributes = [.name: fontName, .size: size] - } - - /// Returns a new font descriptor that is the same as the existing descriptor, - /// but with the specified attributes taking precedence over the existing - /// ones. - public func addingAttributes(_ attributes: [FontDescriptor.AttributeName:Any] = [:]) - -> FontDescriptor { - let descriptor: FontDescriptor = self - descriptor.fontAttributes.merge(attributes, - uniquingKeysWith: { (_, new) in new }) - return descriptor - } - - /// Returns a new font descriptor that is the same as the existing descriptor, - /// but with the specified design. - public func withDesign(_ design: FontDescriptor.SystemDesign) - -> FontDescriptor? { - fatalError("\(#function) not yet implemented") - } - - /// Returns a new font descriptor that is the same as the existing descriptor, - /// but with the specified family. - public func withFamily(_ newFamily: String) -> FontDescriptor { - let descriptor: FontDescriptor = self - _ = descriptor.fontAttributes.removeValue(forKey: .name) - descriptor.fontAttributes[.family] = newFamily - return descriptor - } - - /// Returns a new font descriptor that is the same as the existing descriptor, - /// but with the specified font face. - public func withFace(_ newFace: String) -> FontDescriptor { - let descriptor: FontDescriptor = self - descriptor.fontAttributes[.face] = newFace - return descriptor - } - - /// Returns a new font descriptor that is the same as the existing descriptor, - /// but with the specified matrix. - public func withMatrix(_ matrix: AffineTransform) -> FontDescriptor { - let descriptor: FontDescriptor = self - descriptor.fontAttributes[.matrix] = matrix - return descriptor - } - - /// Returns a new font descriptor that is the same as the existing descriptor, - /// but with the specified size. - public func withSize(_ newPointSize: Double) -> FontDescriptor { - let descriptor: FontDescriptor = self - descriptor.fontAttributes[.size] = newPointSize - return descriptor - } - - /// Returns a new font descriptor that is the same as the existing descriptor, - /// but with the specified symbolic traits. - public func withSymbolicTraits(_ symbolicTraits: FontDescriptor.SymbolicTraits) - -> FontDescriptor? { - let descriptor: FontDescriptor = self - descriptor.fontAttributes[.symbolic] = symbolicTraits - return descriptor - } - - /// Initializing a Font Descriptor - - /// Creates a font descriptor with the specified attributes. - public init(fontAttributes attributes: [FontDescriptor.AttributeName:Any] = [:]) { - self.fontAttributes = attributes - } - - /// Finding Fonts - - /// Returns all the fonts available in the system with the specified - /// attributes. - public func matchingFontDescriptors(withMandatoryKeys mandatoryKeys: Set?) - -> [FontDescriptor] { - fatalError("\(#function) not yet implemented") - } - - /// Querying a Font Descriptor - - /// The font descriptor's dictionary of attributes. - public private(set) var fontAttributes: [FontDescriptor.AttributeName:Any] = [:] - - /// The current transform matrix of the font decriptor. - public var matrix: AffineTransform { - guard let transform = self.object(forKey: .matrix) as? AffineTransform else { - log.warning("FontDescriptor missing attribute: .matrix") - return .identity - } - return transform - } - - /// The point size of the font descriptor. - public var pointSize: Double { - guard let size = self.object(forKey: .size) as? Double else { - log.warning("FontDescriptor missing attribute: .size") - return 0.0 - } - return size - } - - /// The PostScript name of the font descriptor. - public var postscriptName: String { - guard let name = self.object(forKey: .name) as? String else { - log.error("FontDescriptor missing attribute: .name") - return "" - } - return name - } - - /// The traits of the font descriptor. - public var symbolicTraits: FontDescriptor.SymbolicTraits { - guard let traits = self.object(forKey: .symbolic) as? FontDescriptor.SymbolicTraits else { - log.warning("FontDescriptor missing attribute: .symbolic") - return FontDescriptor.SymbolicTraits(rawValue: 0) - } - return traits - } - - public func object(forKey attribute: FontDescriptor.AttributeName) -> Any? { - return self.fontAttributes[attribute] - } -} - -extension FontDescriptor { - /// Constants that describe the system-defined typeface designs. - public struct SystemDesign: Hashable, Equatable, RawRepresentable { - public typealias RawValue = String - - public let rawValue: RawValue - - public init(rawValue: RawValue) { - self.rawValue = rawValue - } - } -} - -extension FontDescriptor.SystemDesign { - /// The default typeface for an app's user interface. - public static var `default`: FontDescriptor.SystemDesign { - FontDescriptor.SystemDesign(rawValue: "default") - } - - /// The monospace variant of the default typeface. - public static var monospaced: FontDescriptor.SystemDesign { - FontDescriptor.SystemDesign(rawValue: "monospaced") - } - - /// The rounded variant of the default typeface. - public static var rounded: FontDescriptor.SystemDesign { - FontDescriptor.SystemDesign(rawValue: "rounded") - } - - /// The serif variant of the default typeface. - public static var serif: FontDescriptor.SystemDesign { - FontDescriptor.SystemDesign(rawValue: "serif") - } -} - -extension FontDescriptor { - /// Constants that describe the stylistic aspects of a font. - public struct SymbolicTraits: OptionSet { - public typealias RawValue = UInt32 - - public let rawValue: RawValue - - public init(rawValue: RawValue) { - self.rawValue = rawValue - } - } -} - -extension FontDescriptor.SymbolicTraits { - /// The font's style is italic. - public static var traitItalic: FontDescriptor.SymbolicTraits { - FontDescriptor.SymbolicTraits(rawValue: 1 << 0) - } - - /// The font's style is bold. - public static var traitBold: FontDescriptor.SymbolicTraits { - FontDescriptor.SymbolicTraits(rawValue: 1 << 1) - } - - /// The font's characters have an expanded width. - public static var traitExpanded: FontDescriptor.SymbolicTraits { - FontDescriptor.SymbolicTraits(rawValue: 1 << 5) - } - - /// The font's characters have a condensed width. - public static var traitCondensed: FontDescriptor.SymbolicTraits { - FontDescriptor.SymbolicTraits(rawValue: 1 << 6) - } - - /// The font's characters all have the same width. - public static var traitMonoSpace: FontDescriptor.SymbolicTraits { - FontDescriptor.SymbolicTraits(rawValue: 1 << 10) - } - - /// The font uses vertical glyph variants and metrics. - public static var traitVertical: FontDescriptor.SymbolicTraits { - FontDescriptor.SymbolicTraits(rawValue: 1 << 11) - } - - /// The font synthesizes appropriate attributes for user interface rendering, - /// such as in control titles, if necessary. - public static var traitUIOptimized: FontDescriptor.SymbolicTraits { - FontDescriptor.SymbolicTraits(rawValue: 1 << 12) - } - - /// The font uses a leading value that's less than the default. - public static var traitTightLeading: FontDescriptor.SymbolicTraits { - FontDescriptor.SymbolicTraits(rawValue: 1 << 15) - } - - /// The font uses a leading value that’s greater than the default. - public static var traitLooseLeading: FontDescriptor.SymbolicTraits { - FontDescriptor.SymbolicTraits(rawValue: 1 << 16) - } - - - /// The font family class mask that you use to access font descriptor values. - public static var classMask: FontDescriptor.SymbolicTraits { - FontDescriptor.SymbolicTraits(rawValue: 15 << 28) - } - - /// The font's characters include serifs, and reflect the Latin printing style - /// of the 15th to 17th centuries. - public static var classOldStyleSerifs: FontDescriptor.SymbolicTraits { - FontDescriptor.SymbolicTraits(rawValue: 1 << 28) - } - - /// The font's characters include serifs, and reflect the Latin printing style - /// of the 18th to 19th centuries. - public static var classTransitionalSerifs: FontDescriptor.SymbolicTraits { - FontDescriptor.SymbolicTraits(rawValue: 2 << 28) - } - - /// The font's characters include serifs, and reflect the Latin printing style - /// of the 20th century. - public static var classModernSerifs: FontDescriptor.SymbolicTraits { - FontDescriptor.SymbolicTraits(rawValue: 3 << 28) - } - - /// The font's characters include variations of old style and transitional - /// serifs. - public static var classClarendonSerifs: FontDescriptor.SymbolicTraits { - FontDescriptor.SymbolicTraits(rawValue: 4 << 28) - } - - /// The font's characters use square transitions, without brackets, between - /// strokes and serifs. - public static var classSlabSerifs: FontDescriptor.SymbolicTraits { - FontDescriptor.SymbolicTraits(rawValue: 5 << 28) - } - - /// The font's characters include serifs, and don’t generally fit within other - /// serif design classifications. - public static var classFreeformSerifs: FontDescriptor.SymbolicTraits { - FontDescriptor.SymbolicTraits(rawValue: 7 << 28) - } - - /// The font's characters don’t have serifs. - public static var classSansSerif: FontDescriptor.SymbolicTraits { - FontDescriptor.SymbolicTraits(rawValue: 8 << 28) - } - - /// The font's characters use highly decorated or stylized character shapes. - public static var classOrnamentals: FontDescriptor.SymbolicTraits { - FontDescriptor.SymbolicTraits(rawValue: 9 << 28) - } - - /// The font's characters simulate handwriting. - public static var classScripts: FontDescriptor.SymbolicTraits { - FontDescriptor.SymbolicTraits(rawValue: 10 << 28) - } - - /// The font's characters consist mainly of symbols rather than letters and - /// numbers. - public static var classSymbolic: FontDescriptor.SymbolicTraits { - FontDescriptor.SymbolicTraits(rawValue: 12 << 28) - } -} - -extension FontDescriptor { - /// Constants that describe font attributes. - public struct AttributeName: Equatable, Hashable, RawRepresentable { - public typealias RawValue = String - - public let rawValue: RawValue - - public init(rawValue: RawValue) { - self.rawValue = rawValue - } - } -} - -extension FontDescriptor.AttributeName { - /// The cascading list attribute. - public static var cascadeList: FontDescriptor.AttributeName { - FontDescriptor.AttributeName(rawValue: "NSCTFontCascadeListAttribute") - } - - /// The character set attribute. - public static var characterSet: FontDescriptor.AttributeName { - FontDescriptor.AttributeName(rawValue: "NSCTFontCharacterSetAttribute") - } - - /// The font face attribute. - public static var face: FontDescriptor.AttributeName { - FontDescriptor.AttributeName(rawValue: "NSCTFontFaceAttribute") - } - - /// The font family attribute. - public static var family: FontDescriptor.AttributeName { - FontDescriptor.AttributeName(rawValue: "NSCTFontFamilyAttribute") - } - - /// The font feature settings attribute. - public static var featureSettings: FontDescriptor.AttributeName { - FontDescriptor.AttributeName(rawValue: "NSCTFontFeatureSettingsAttribute") - } - - /// The glyph advancement attribute. - public static var fixedAdvance: FontDescriptor.AttributeName { - FontDescriptor.AttributeName(rawValue: "NSCTFontFixedAdvanceAttribute") - } - - /// The font's transformation matrix attribute. - public static var matrix: FontDescriptor.AttributeName { - FontDescriptor.AttributeName(rawValue: "NSCTFontMatrixAttribute") - } - - /// The font name attribute. - public static var name: FontDescriptor.AttributeName { - FontDescriptor.AttributeName(rawValue: "NSCTFontNameAttribute") - } - - /// The font size attribute. - public static var size: FontDescriptor.AttributeName { - FontDescriptor.AttributeName(rawValue: "NSCTFontSizeAttribute") - } - - /// The font's stylistic properties attribute. - public static var symbolic: FontDescriptor.AttributeName { - FontDescriptor.AttributeName(rawValue: "NSCTFontSymbolicAttribute") - } - - /// The text style attribute. - public static var textStyle: FontDescriptor.AttributeName { - FontDescriptor.AttributeName(rawValue: "NSCTFontTextStyleAttribute") - } - - /// The font traits dictionary attribute. - public static var traits: FontDescriptor.AttributeName { - FontDescriptor.AttributeName(rawValue: "NSCTFontTraitsAttribute") - } - - /// The font's visible name attribute. - public static var visibleName: FontDescriptor.AttributeName { - FontDescriptor.AttributeName(rawValue: "NSCTFontVisibleNameAttribute") - } -} - -extension FontDescriptor { - /// Keys for retrieving feature settings. - public struct FeatureKey: Equatable, Hashable, RawRepresentable { - public typealias RawValue = String - - public let rawValue: RawValue - - public init(rawValue: RawValue) { - self.rawValue = rawValue - } - } -} - -extension FontDescriptor.FeatureKey { - public init(_ rawValue: RawValue) { - self.rawValue = rawValue - } -} - -extension FontDescriptor.FeatureKey { - /// A key for identifying a font feature type such as ligature or character - /// shape. - public static var featureIdentifier: FontDescriptor.FeatureKey { - FontDescriptor.FeatureKey(rawValue: "CTFeatureTypeIdentifier") - } - - /// A key for identifying the font feature selector. - public static var typeIdentifier: FontDescriptor.FeatureKey { - FontDescriptor.FeatureKey(rawValue: "CTFeatureSelectorIdentifier") - } -} - -extension FontDescriptor { - // Keys for retrieving the font descriptor's trait information. - public struct TraitKey: Equatable, Hashable, RawRepresentable { - public typealias RawValue = String - - public let rawValue: RawValue - - public init(rawValue: RawValue) { - self.rawValue = rawValue - } - } -} - -extension FontDescriptor.TraitKey { - /// The relative slant angle of the font. - public static var slant: FontDescriptor.TraitKey { - FontDescriptor.TraitKey(rawValue: "NSCTFontSlantTrait") - } - - /// The symbolic font traits. - public static var symbolic: FontDescriptor.TraitKey { - FontDescriptor.TraitKey(rawValue: "NSCTFontSymbolicTrait") - } - - /// The normalized font weight. - public static var weight: FontDescriptor.TraitKey { - FontDescriptor.TraitKey(rawValue: "NSCTFontWeightTrait") - } - - /// The inter-glyph spacing of the font. - public static var width: FontDescriptor.TraitKey { - FontDescriptor.TraitKey(rawValue: "NSCTFontWidthTrait") - } -} diff --git a/Sources/SwiftWin32/Text Display and Fonts/FontMetrics.swift b/Sources/SwiftWin32/Text Display and Fonts/FontMetrics.swift deleted file mode 100644 index 72551a89..00000000 --- a/Sources/SwiftWin32/Text Display and Fonts/FontMetrics.swift +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -public class FontMetrics { - /// Creating a Font Metrics Object - - /// Creates a font metrics object for the specified text style. - public init (forTextStyle style: Font.TextStyle) { - } - - /// The default font metrics object for content. - public static let `default`: FontMetrics = FontMetrics(forTextStyle: .body) - - /// Creating Scaled Fonts - - /// Returns a version of the specified font that adopts the current font - /// metrics. - public func scaledFont(for font: Font) -> Font { - return scaledFont(for: font, compatibleWith: nil) - } - - /// Returns a version of the specified font that adopts the current font - /// metrics and suports the specified traitss. - public func scaledFont(for font: Font, - compatibleWith traitCollection: TraitCollection?) - -> Font { - return scaledFont(for: font, maximumPointSize: Double.greatestFiniteMagnitude, - compatibleWith: traitCollection) - } - - /// Returns a version of the specified font that adopts the current font - /// metrics and is constrained to the specified maximum size. - public func scaledFont(for font: Font, maximumPointSize: Double) -> Font { - return scaledFont(for: font, maximumPointSize: maximumPointSize, - compatibleWith: nil) - } - - /// Returns a version of the specified font that adopts the current font - /// metrics and is constrained to the specified traits and size. - public func scaledFont(for font: Font, maximumPointSize: Double, - compatibleWith traitCollection: TraitCollection?) - -> Font { - let _ = traitCollection ?? TraitCollection.current - // TODO(compnerd) adjust the font size for the trait collection and cap the - // size. - fatalError("\(#function) not yet implemented") - } -} diff --git a/Sources/SwiftWin32/Text Storage/ParagraphStyle.swift b/Sources/SwiftWin32/Text Storage/ParagraphStyle.swift deleted file mode 100644 index eb59439e..00000000 --- a/Sources/SwiftWin32/Text Storage/ParagraphStyle.swift +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -/// Constants that specify what happens when a line is too long for its -/// container. -public enum LineBreakMode: Int { - // MARK - Constants - - /// Wrapping occurs at word boundaries, unless the word doesn’t fit on a - /// single line. - case byWordWrapping - - /// Wrapping occurs before the first character that doesn’t fit. - case byCharWrapping - - /// Lines don't extend past the edge of the text container. - case byClipping - - /// The line displays so that the end fits in the container and an ellipsis - /// glyph indicates the missing text at the beginning of the line. - case byTruncatingHead - - /// The line displays so that the beginning fits in the container and an - /// ellipsis glyph indicates the missing text at the end of the line. - case byTruncatingTail - - /// The line displays so that the beginning and end fit in the container and - /// an ellipsis glyph indicates the missing text in the middle. - case byTruncatingMiddle -} diff --git a/Sources/SwiftWin32/Touches, Presses, and Gestures/Event.swift b/Sources/SwiftWin32/Touches, Presses, and Gestures/Event.swift deleted file mode 100644 index 17604f10..00000000 --- a/Sources/SwiftWin32/Touches, Presses, and Gestures/Event.swift +++ /dev/null @@ -1,137 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import struct Foundation.TimeInterval - -extension Event { - /// Specifies the general type of event. - public enum EventType: Int { - /// The event is related to touches on the screen. - case touches - - /// The event is related to motion of the device. - case motion - - /// The event is a remote-control event. - case remoteControl - - /// The event is related to the press of a physical button. - case presses - } -} - -extension Event { - /// Specifies the subtype of the event in relation to its general type. - public enum EventSubtype: Int { - /// The event has no subtype. - case none - - /// The event is related to the user shaking the device. - case motionShake - - /// A remote-control event for playing audio or video. - case remoteControlPlay - } -} - -extension Event { - /// Set of buttons pressed for the current event - public struct ButtonMask: OptionSet { - public typealias RawValue = Int - - public let rawValue: RawValue - - // MARK - Creating Button Masks - - public init(rawValue: Int) { - self.rawValue = rawValue - } - - /// Convenience initializer for a button mask where `buttonNumber` is a - /// one-based index of the button on the input device - public static func button(_ buttonNumber: Int) -> ButtonMask { - ButtonMask(rawValue: 1 << (buttonNumber - 1)) - } - - // MARK - Accessing Button Masks - - public static var primary: ButtonMask { - ButtonMask(rawValue: 1 << 0) - } - - public static var secondary: ButtonMask { - ButtonMask(rawValue: 1 << 1) - } - } -} - -/// An object that describes a single user interaction with your app. -open class Event { - // MARK - Getting the Touches for an Event - - /// Returns all touches associated with the event. - open private(set) var allTouches: Set? - - /// Returns the touch objects from the event that belong to the specified - /// given view. - open func touches(for view: View) -> Set? { - fatalError("\(#function) not yet implemented") - } - - /// Returns the touch objects from the event that belong to the specified - /// window. - open func touches(for window: Window) -> Set? { - fatalError("\(#function) not yet implemented") - } - - /// Returns all of the touches associated with the specified main touch. - open func coalescedTouches(for touch: Touch) -> [Touch]? { - fatalError("\(#function) not yet implemented") - } - - /// Returns an array of touches that are predicted to occur for the specified - /// touch. - open func predictedTouches(for touch: Touch) -> [Touch]? { - fatalError("\(#function) not yet implemented") - } - - // MARK - Getting Event Attributes - - /// The time when the event occurred. - open private(set) var timestamp: TimeInterval - - // MARK - Getting the Event Type - - /// Returns the type of the event. - open private(set) var type: Event.EventType - - /// Returns the subtype of the event. - open private(set) var subtype: Event.EventSubtype - - // MARK - Getting the Touches for a Gesture Recognizer - - /// Returns the touch objects that are being delivered to the specified - /// gesture recognizer. - open func touches(for gesture: GestureRecognizer) -> Set? { - fatalError("\(#function) not yet implemented") - } - - /// - open private(set) var buttonMask: Event.ButtonMask - - // MARK - - - /// - open private(set) var modifierFlags: KeyModifierFlags - - // MARK - - - internal init(type: Event.EventType, subtype: Event.EventSubtype, - timestamp: TimeInterval) { - self.type = type - self.subtype = subtype - self.timestamp = timestamp - self.buttonMask = [] - self.modifierFlags = [] - } -} diff --git a/Sources/SwiftWin32/Touches, Presses, and Gestures/GestureRecognizer.swift b/Sources/SwiftWin32/Touches, Presses, and Gestures/GestureRecognizer.swift deleted file mode 100644 index cc63ea4c..00000000 --- a/Sources/SwiftWin32/Touches, Presses, and Gestures/GestureRecognizer.swift +++ /dev/null @@ -1,214 +0,0 @@ -// Copyright © 2021 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -#if swift(>=5.7) -import CoreGraphics -#endif - -// Class constrain the callable to ensure that the value is heap allocated, -// permitting us to perform pointer equality for the callback to serve as -// identity. Using COW, we can perform pointer equality on the types as a -// rough equivalency for the pointer equality for the bound action, which -// determines if the action is equivalent or not. -private protocol GestureRecognizerCallable: AnyObject { - func callAsFunction(_: GestureRecognizer) -} - -private class GestureRecognizerCallback: GestureRecognizerCallable { - private enum Signature { - case zero((Target) -> () -> Void) - case one((Target) -> (_: GestureRecognizer) -> Void) - } - - private unowned(unsafe) let instance: Target - private let method: Signature - - public init(binding: @escaping (Target) -> (GestureRecognizer) -> Void, on: Target) { - self.instance = on - self.method = .one(binding) - } - - public init(binding: @escaping (Target) -> () -> Void, on: Target) { - self.instance = on - self.method = .zero(binding) - } - - public func callAsFunction(_ gestureRecognizer: GestureRecognizer) { - switch self.method { - case let .zero(action): - action(self.instance)() - case let .one(action): - action(self.instance)(gestureRecognizer) - } - } -} - -extension GestureRecognizer { - /// The current state a gesture recognizer is in. - public enum State: Int { - /// The gesture recognizer has not yet recognized its gesture, but may be - /// evaluating touch events. This is the default state. - case possible - - /// The gesture recognizer has received touch objects recognized as a - /// continuous gesture. It sends its action message (or messages) at the - /// next cycle of the run loop. - case began - - /// The gesture recognizer has received touches recognized as a change to a - /// continuous gesture. It sends its action message (or messages) at the - /// next cycle of the run loop. - case changed - - /// The gesture recognizer has received touches recognized as the end of a - /// continuous gesture. It sends its action message (or messages) at the - /// next cycle of the run loop and resets its state to - /// `GestureRecognizer.State.possible`. - case ended - - /// The gesture recognizer has received touches resulting in the - /// cancellation of a continuous gesture. It sends its action message (or - /// messages) at the next cycle of the run loop and resets its state to - /// `GestureRecognizer.State.possible`. - case cancelled - - /// The gesture recognizer has received a multi-touch sequence that it - /// cannot recognize as its gesture. No action message is sent and the - /// gesture recognizer is reset to `GestureRecognizer.State.possible`. - case failed - } -} - -extension GestureRecognizer.State { - /// The gesture recognizer has received a multi-touch sequence that it - /// recognizes as its gesture. It sends its action message (or messages) at - /// the next cycle of the run loop and resets its state to - /// `GestureRecognizer.State.possible`. - public static var recognized: GestureRecognizer.State { - .ended - } -} - -public class GestureRecognizer { - private var actions: [GestureRecognizerCallable] - - // MARK - Initializing a Gesture Recognizer - - /// Initializes an allocated gesture-recognizer object with a target and an - /// action selector. - /// - /// The valid signatures for `action` are: - /// - `(Target) -> () -> Void` aka `()` - /// - `(Target) -> (_: GestureRecognizer) -> Void` aka `(_: GestureRecognizer)` - /// - /// Although the signature permits nullable types, the values may not be nil. - - // public init(target: Any?, action: Selector?) - - public init(target: Target, - action: @escaping (Target) -> () -> Void) { - self.actions = [GestureRecognizerCallback(binding: action, on: target)] - } - - public init(target: Target, - action: @escaping (Target) -> (_: GestureRecognizer) -> Void) { - self.actions = [GestureRecognizerCallback(binding: action, on: target)] - } - - // MARK - Managing Gesture-Related Interactions - - /// The delegate of the gesture recognizer. - public weak var delegate: GestureRecognizerDelegate? - - // MARK - Adding and Removing Targets and Actions - - /// Adds a target and an action to a gesture-recognizer object. - /// - /// The valid signatures for `action` are: - /// - `(Target) -> () -> Void` aka `()` - /// - `(Target) -> (_: GestureRecognizer) -> Void` aka `(_: GestureRecognizer)` - - // public func addTarget(_ target: Any, action: Selector) - - public func addTarget(_ target: Target, - action: @escaping (Target) -> () -> Void) { - self.actions.append(GestureRecognizerCallback(binding: action, on: target)) - } - - public func addTarget(_ target: Target, - action: @escaping (Target) -> (_: GestureRecognizer) -> Void) { - self.actions.append(GestureRecognizerCallback(binding: action, on: target)) - } - - /// Removes a target and an action from a gesture-recognizer object. - - // public func removeTarget(_ target: Any?, action: Selector?) - - public func removeTarget(_ target: Target, - action: @escaping (Target) -> () -> Void) { - let callable: GestureRecognizerCallable = - GestureRecognizerCallback(binding: action, on: target) - self.actions.removeAll(where: { $0 === callable }) - } - - public func removeTarget(_ target: Target, - action: @escaping (Target) -> (_: GestureRecognizer) -> Void) { - let callable: GestureRecognizerCallable = - GestureRecognizerCallback(binding: action, on: target) - self.actions.removeAll(where: { $0 === callable }) - } - - // MARK - Getting the Touches and Location of a Gesture - - /// Returns the point computed as the location in a given view of the gesture - /// represented by the receiver. - public func location(in view: View?) -> Point { - fatalError("\(#function) not yet implemented") - } - - /// Returns the location of one of the gesture’s touches in the local - /// coordinate system of a given view. - public func location(ofTouch touchIndex: Int, in view: View?) -> Point { - fatalError("\(#function) not yet implemented") - } - - /// Returns the number of touches involved in the gesture represented by the - /// receiver. - public private(set) var numberOfTouches: Int = 0 - - // MARK - Getting the Recognizer’s State and View - - /// The current state of the gesture recognizer. - public var state: GestureRecognizer.State = .possible - - /// The view the gesture recognizer is attached to. - public internal(set) var view: View? - - /// A boolean property that indicates whether the gesture recognizer is - /// enabled. - public var isEnabled: Bool = true - - /// A bit mask of the button (or buttons) in the gesture represented by the - /// receiver. - public private(set) var buttonMask: Event.ButtonMask = [] - - /// Constants that indicate which modifier keys are pressed. - public private(set) var modifierFlags: KeyModifierFlags = [] - - // MARK - Debugging Gesture Recognizers - - /// The name associated with the gesture recognizer. - public var name: String? - - // MARK - Initializers - - public /* convenience */ init() { - fatalError("\(#function) not yet implemented") - } - - // MARK - Instance Methods - - public func shouldReceive(_ event: Event) -> Bool { - fatalError("\(#function) not yet implemented") - } -} diff --git a/Sources/SwiftWin32/Touches, Presses, and Gestures/GestureRecognizerDelegate.swift b/Sources/SwiftWin32/Touches, Presses, and Gestures/GestureRecognizerDelegate.swift deleted file mode 100644 index 9ad87f65..00000000 --- a/Sources/SwiftWin32/Touches, Presses, and Gestures/GestureRecognizerDelegate.swift +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright © 2021 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -/// A set of methods implemented by the delegate of a gesture recognizer to -/// fine-tune an application’s gesture-recognition behavior. -public protocol GestureRecognizerDelegate: AnyObject { - // MARK - Regulating Gesture Recognition - - /// Asks the delegate if a gesture recognizer should begin interpreting - /// touches. - func gestureRecognizerShouldBegin(_ gestureRecognizer: GestureRecognizer) - -> Bool - - /// Asks the delegate if a gesture recognizer should receive an object - /// representing a touch. - func gestureRecognizer(_ gestureRecognizer: GestureRecognizer, - shouldReceive touch: Touch) -> Bool - - /// Asks the delegate if a gesture recognizer should receive an object - /// representing a press. -#if NOT_YET_IMPLEMENTED - func gestureRecognizer(_ gestureRecognizer: GestureRecognizer, - shouldReceive press: Press) -> Bool -#endif - - /// Asks the delegate if a gesture recognizer should receive an object - /// representing a touch or press event. - func gestureRecognizer(_ gestureRecognizer: GestureRecognizer, - shouldReceive event: Event) -> Bool - - // MARK - Controlling Simultaneous Gesture Recognition - - /// Asks the delegate if two gesture recognizers should be allowed to - /// recognize gestures simultaneously. - func gestureRecognizer(_ gestureRecognizer: GestureRecognizer, - shouldRecognizeSimultaneouslyWith otherGestureRecognizer: GestureRecognizer) - -> Bool - - // MARK - Setting Up Failure Requirements - - /// Asks the delegate if a gesture recognizer should require another gesture - /// recognizer to fail. - func gestureRecognizer(_ gestureRecognizer: GestureRecognizer, - shouldRequireFailureOf otherGestureRecognizer: GestureRecognizer) - -> Bool - - /// Asks the delegate if a gesture recognizer should be required to fail by - /// another gesture recognizer. - func gestureRecognizer(_ gestureRecognizer: GestureRecognizer, - shouldBeRequiredToFailBy otherGestureRecognizer: GestureRecognizer) - -> Bool -} - -extension GestureRecognizerDelegate { - public func gestureRecognizerShouldBegin(_ gestureRecognizer: GestureRecognizer) - -> Bool { - return true - } - - public func gestureRecognizer(_ gestureRecognizer: GestureRecognizer, - shouldReceive touch: Touch) -> Bool { - return true - } - -#if NOT_YET_IMPLEMENTED - public func gestureRecognizer(_ gestureRecognizer: GestureRecognizer, - shouldReceive press: Press) -> Bool { - return true - } -#endif - - public func gestureRecognizer(_ gestureRecognizer: GestureRecognizer, - shouldReceive event: Event) -> Bool { - return true - } -} - -extension GestureRecognizerDelegate { - public func gestureRecognizer(_ gestureRecognizer: GestureRecognizer, - shouldRecognizeSimultaneouslyWith otherGestureRecognizer: GestureRecognizer) - -> Bool { - return false - } -} - -extension GestureRecognizerDelegate { - public func gestureRecognizer(_ gestureRecognizer: GestureRecognizer, - shouldRequireFailureOf otherGestureRecognizer: GestureRecognizer) - -> Bool { - return false - } - - public func gestureRecognizer(_ gestureRecognizer: GestureRecognizer, - shouldBeRequiredToFailBy otherGestureRecognizer: GestureRecognizer) - -> Bool { - return false - } -} diff --git a/Sources/SwiftWin32/Touches, Presses, and Gestures/Press.swift b/Sources/SwiftWin32/Touches, Presses, and Gestures/Press.swift deleted file mode 100644 index be1a8ab9..00000000 --- a/Sources/SwiftWin32/Touches, Presses, and Gestures/Press.swift +++ /dev/null @@ -1,125 +0,0 @@ -// Copyright © 2021 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import struct Foundation.TimeInterval - -extension Press { - /// The phases of a button press. - public enum Phase: Int { - /// A physical button was pressed. - case began - - /// A button moved, or the `force` property changed. - case changed - - /// A button was pressed but hasn’t moved since the previous event. - case stationary - - /// A button was released. - case ended - - /// The system canceled tracking for the button. - case cancelled - } -} - -extension Press { - /// Constants that represent buttons that a user can press. - public enum PressType: Int { - // MARK - Navigation - - /// A constant that represents the up arrow button. - case upArrow = 0 - - /// A constant that represents the down arrow button. - case downArrow = 1 - - /// A constant that represents the left arrow button. - case leftArrow = 2 - - /// A constant that represents the right arrow button. - case rightArrow = 3 - - /// A constant that represents the page down button. - case pageDown = 30 - - /// A constant that represents the page up button. - case pageUp = 31 - - // MARK - Actions - - /// A constant that represents the play/pause button. - case playPause = 4 - - /// A constant that represents the select button. - case select = 5 - - /// A constant that represents the menu button. - case menu = 6 - } -} - -/// An object that represents the presence or movement of a button press on the -/// screen for a particular event. -open class Press { - // MARK - Getting a Press Object’s Gesture Recognizers - - /// The force of the button press. - open private(set) var force: Double - - /// The gesture recognizers that are receiving the press. - open private(set) var gestureRecognizers: [GestureRecognizer]? - - // MARK - Responding to Press Events - - /// A `Responder` object. - open private(set) var responder: Responder? - - // MARK - Getting the Press’s Location - - /// The window in which the press initially occurred. - open private(set) var window: Window? - - // MARK - Getting Press Attributes - - /// The key pressed or released on a physical keyboard. -#if false - open private(set) var key: Key? -#endif - - /// The type of the specified press. - open private(set) var type: Press.PressType - - /// The current press phase of the object. - open private(set) var phase: Press.Phase - - /// The time when the press occurred or when it was last mutated. - open private(set) var timestamp: TimeInterval - - // MARK - - - internal init(type: Press.PressType, phase: Press.Phase, force: Double, - timestamp: TimeInterval) { - self.type = type - self.phase = phase - self.force = force - self.timestamp = timestamp - } -} - -extension Press: Equatable { - public static func ==(_ lhs: Press, _ rhs: Press) -> Bool { - // FIXME(compnerd) is this the correct check for equality? - return lhs === rhs - } -} - -extension Press: Hashable { - public func hash(into hasher: inout Hasher) { - // FIXME(compnerd) is this the correct hashing? - hasher.combine(self.type) - hasher.combine(self.phase) - hasher.combine(self.force) - hasher.combine(self.timestamp) - } -} diff --git a/Sources/SwiftWin32/Touches, Presses, and Gestures/PressesEvent.swift b/Sources/SwiftWin32/Touches, Presses, and Gestures/PressesEvent.swift deleted file mode 100644 index 796d442e..00000000 --- a/Sources/SwiftWin32/Touches, Presses, and Gestures/PressesEvent.swift +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright © 2021 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import struct Foundation.TimeInterval - -/// An event that describes the state of a set of physical buttons that are -/// available to the device, such as those on an associated remote or game -/// controller. -open class PressesEvent: Event { - // MARK - Reading the Event Button Presses - - /// Returns the state of all physical buttons in the event. - open private(set) var allPresses: Set - - /// Returns the state of all physical buttons in the event that are associated - /// with a particular gesture recognizer. - open func presses(for guesture: GestureRecognizer) -> Set { - fatalError("\(#function) not yet implemented") - } - - // MARK - - - internal init(presses: Set, timestamp: TimeInterval) { - self.allPresses = presses - super.init(type: .presses, subtype: .none, timestamp: timestamp) - } -} diff --git a/Sources/SwiftWin32/Touches, Presses, and Gestures/Responder.swift b/Sources/SwiftWin32/Touches, Presses, and Gestures/Responder.swift deleted file mode 100644 index a1f43be7..00000000 --- a/Sources/SwiftWin32/Touches, Presses, and Gestures/Responder.swift +++ /dev/null @@ -1,213 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import class Foundation.NSNotification - -open class Responder { - // MARK - Managing the Responder Chain - - /// Returns the next responder in the responder chain, or `nil` if there is no - /// next responder. - open var next: Responder? { nil } - - /// Indicates whether this object is the first responder. - open var isFirstResponder: Bool { return self.next === self } - - /// Indiciates whether ths object can become the first responder. - open var canBecomeFirstResponder: Bool { false } - - /// Results to make this object the first responder in its window. - open func becomeFirstResponder() -> Bool { - guard !self.isFirstResponder else { return true } - guard self.canBecomeFirstResponder else { return false } - return true - } - - /// Indicates whether this object is willing to relinquish first-responder - /// status. - open var canResignFirstResponder: Bool { true } - - /// Notifies the object that it has been asked to relinquish its status as - /// first responder in its window. - open func resignFirstResponder() -> Bool { - return true - } - - // MARK - Responding to Touch Events - - /// Informs the responder that one or more new touches occurrd in a view or a - /// window. - open func touchesBegan(_ touches: Set, with event: Event?) { - } - - /// Informs the responder when one or more touches associated with an event - /// changed. - open func touchesMoved(_ touches: Set, with event: Event?) { - } - - /// Informs the responder when one or more fingers are raised from a view or a - /// window. - open func touchesEnded(_ touches: Set, with event: Event?) { - } - - /// Informs the responder when a system event (such as a system alert) cancels - /// a touch sequence. - open func touchesCancelled(_ touches: Set, with event: Event?) { - } - - /// Tells the responder that updated values were received for previously - /// estimated properties or that an update is no longer expected. - open func touchesEstimatedPropertiesUpdated(_ touches: Set) { - } - - // MARK - Responding to Motion Events - - /// Tells the receiver that a motion event has begun. - open func motionBegan(_ motion: Event.EventSubtype, with event: Event?) { - } - - /// Tells the receiver that a motion event has ended. - open func motionEnded(_ motion: Event.EventSubtype, with event: Event?) { - } - - /// Tells the receiver that a motion event has been cancelled. - open func motionCancelled(_ motion: Event.EventSubtype, with event: Event?) { - } - - // MARK - Responding to Press Events - - /// NOTE: Generally, responders that handle press events should override all - /// four of these methods. - - /// Tells this object when a physical button is first pressed. - open func pressesBegan(_ presses: Set, with event: PressesEvent?) { - } - - /// Tells this object when a value associated with a press has changed. - open func pressesChanged(_ presses: Set, with event: PressesEvent?) { - } - - /// Tells the object when a button is released. - open func pressesEnded(_ presses: Set, with event: PressesEvent?) { - } - - /// Tells this object when a system event (such as a low-memory warning) cancels a press event. - open func pressesCancelled(_ presses: Set, with event: PressesEvent?) { - } - - // MARK - Responding to Remote-Control Events - - /// Tells the object when a remote-control event is received. - open func remoteControlReceived(with event: Event?) { - } - - // MARK - Managing Input Views - - /// The custom input view to display when the receiver becomes the first - /// responder. - open private(set) var inputView: View? - - /// The custom input view controller to use when the receiver becomes the - /// first responder. - open private(set) var inputViewController: InputViewController? - - /// The custom input accessory view to display when the receiver becomes the - /// first responder. - open private(set) var inputAccessoryView: View? - - /// The custom input accessory view controller to display when the receiver - /// becomes the first responder. - open private(set) var inputAccessoryViewController: InputViewController? - - /// Updates the custom input and accessory views when the object is the first - /// responder. - open func reloadInputViews() { - } - - // MARK - Building and Validating Commands - - /// Asks the receiving responder to add and remove items from a menu system. - open func buildMenu(with builder: MenuBuilder) { - self.next?.buildMenu(with: builder) - } - - /// Asks the receiving responder to validate the command. - public func validate(_ command: Command) { - self.next?.validate(command) - } - - /// Requests the receiving responder to enable or disable the specified - /// command in the user interface. - open func canPerformAction(_ action: (AnyObject) -> (_: Action, _: Any?) -> Void, - withSender sender: Any?) -> Bool { - fatalError("\(#function) not yet implemented") - } - - open func target(forAction action: (AnyObject) -> (_: Action, _: Any?) -> Void, - withSender sender: Any?) -> Any? { - guard canPerformAction(action, withSender: sender) else { return nil } - fatalError("\(#function) not yet implemented") - } - - // MARK - Responding to Keyboard Notifications - - /// A user info key to retrieve the animation curve that the system uses to - /// animate the keyboard onto or off the screen. - public class var keyboardAnimationCurveUserInfoKey: String { - "UIResponderKeyboardAnimationCurveUserInfoKey" - } - - /// A user info key to retrieve the duration of the keyboard animation in - /// seconds. - public class var keyboardAnimationDurationUserInfoKey: String { - "UIResponderKeyboardAnimationDurationUserInfoKey" - } - - /// A user info key to retrieve the keyboard’s frame at the beginning of its - /// animation. - public class var keyboardFrameBeginUserInfoKey: String { - "UIResponderKeyboardFrameBeginUserInfoKey" - } - - /// A user info key to retrieve the keyboard’s frame at the end of its - /// animation. - public class var keyboardFrameEndUserInfoKey: String { - "UIResponderKeyboardFrameEndUserInfoKey" - } - - /// A user info key to retrieve a boolean value that indicates whether the - /// keyboard belongs to the current app. - public class var keyboardIsLocalUserInfoKey: String { - "UIResponderKeyboardIsLocalUserInfoKey" - } - - /// Posted immediately after a change in the keyboard’s frame. - public class var keyboardDidChangeFrameNotification: NSNotification.Name { - NSNotification.Name(rawValue: "UIResponderKeyboardDidChangeFrameNotification") - } - - /// Posted immediately after the dismissal of the keyboard. - public class var keyboardDidHideNotification: NSNotification.Name { - NSNotification.Name(rawValue: "UIResponderKeyboardDidHideNotification") - } - - /// Posted immediately after the display of the keyboard. - public class var keyboardDidShowNotification: NSNotification.Name { - NSNotification.Name(rawValue: "UIRespnderKeyboardDidShowNotification") - } - - /// Posted immediately prior to a change in the keyboard’s frame. - public class var keyboardWillChangeFrameNotification: NSNotification.Name { - NSNotification.Name(rawValue: "UIReponderKeyboardWillChnageFrameNotification") - } - - /// Posted immediately prior to the dismissal of the keyboard. - public class var keyboardWillHideNotification: NSNotification.Name { - NSNotification.Name(rawValue: "UIResponderKeyboardWillHideNotification") - } - - /// Posted immediately prior to the display of the keyboard. - public class var keyboardWillShowNotification: NSNotification.Name { - NSNotification.Name(rawValue: "UIResponderKeyboardWillShowNotification") - } -} diff --git a/Sources/SwiftWin32/Touches, Presses, and Gestures/TapGestureRecognizer.swift b/Sources/SwiftWin32/Touches, Presses, and Gestures/TapGestureRecognizer.swift deleted file mode 100644 index 37f194d2..00000000 --- a/Sources/SwiftWin32/Touches, Presses, and Gestures/TapGestureRecognizer.swift +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright © 2021 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -/// A discrete gesture recognizer that interprets single or multiple taps. -public class TapGestureRecognizer: GestureRecognizer { - // MARK - Configuring the Gesture - - /// The bitmask of the buttons the user must press for gesture recognition. - public var buttonMaskRequired: Event.ButtonMask = [.primary] - - /// The number of taps necessary for gesture recognition. - public var numberOfTapsRequired: Int = 1 - - /// The number of fingers that the user must tap for gesture recognition. - public var numberOfTouchesRequired: Int = 1 -} diff --git a/Sources/SwiftWin32/Touches, Presses, and Gestures/Touch.swift b/Sources/SwiftWin32/Touches, Presses, and Gestures/Touch.swift deleted file mode 100644 index a298e329..00000000 --- a/Sources/SwiftWin32/Touches, Presses, and Gestures/Touch.swift +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import struct Foundation.TimeInterval - -extension Touch { - /// The type of touch received. - public enum TouchType: Int { - /// A touch resulting from direct contact with the screen. - case direct - - /// A touch that did not result from direct contact with the screen. - case indirect - - /// A touch from a stylus. - case pencil - } -} - -extension Touch { - /// The phase of a touch event. - public enum Phase: Int { - /// A touch for a given event has pressed down on the screen. - case began - - /// A touch for a given event has moved over the screen. - case moved - - /// A touch for a given event is presseddown on the screen, but hasn't moved - /// since the previous event. - case stationary - - /// A touch for a given event has lifted from the screen. - case ended - - /// The system cancelled tracking for a touch, for example, when the user - /// moves the device against their face. - case cancelled - - /// A touch for a given event has entered a window on the screen. - case regionEntered - - /// A touch for the given event is within a window on the screen, but has not - /// yet pressed down. - case regionMoved - - /// A touch for given event has left a window on the screen. - case regionExited - } -} - -/// An object representing the location, size, movement, and force of a touch -/// occurring on the screen. -public class Touch { - /// Getting the Location of a Touch - - /// The view to which touches are being delivered, if any. - public let view: View? - - /// Getting Touch Attriutes - - /// The time when the touch occurred or when it was last mutated. - public let timestamp: TimeInterval - - internal init(for view: View?, at time: TimeInterval) { - self.view = view - self.timestamp = time - } -} - -extension Touch: Hashable { - public static func ==(_ lhs: Touch, _ rhs: Touch) -> Bool { - return lhs.view == rhs.view && lhs.timestamp == rhs.timestamp - } - - public func hash(into hasher: inout Hasher) { - // TODO(compnerd) figure out how to hash a Touch - } -} diff --git a/Sources/SwiftWin32/UI/ContentSizeCategoryAdjusting.swift b/Sources/SwiftWin32/UI/ContentSizeCategoryAdjusting.swift deleted file mode 100644 index d13b744f..00000000 --- a/Sources/SwiftWin32/UI/ContentSizeCategoryAdjusting.swift +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -/// A collection of methods that gives controls an easy way to adopt automatic -/// adjustment to content category changes. -public protocol ContentSizeCategoryAdjusting { - /// Adjusting the Size of Fonts - - /// A boolean that indicates whether the object automatically updates its font - /// when the device's context size category changes. - var adjustsFontForContentSizeCategory: Bool { get set } -} diff --git a/Sources/SwiftWin32/UI/ContentSizeCategoryImageAdjusting.swift b/Sources/SwiftWin32/UI/ContentSizeCategoryImageAdjusting.swift deleted file mode 100644 index 50d138eb..00000000 --- a/Sources/SwiftWin32/UI/ContentSizeCategoryImageAdjusting.swift +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -/// Methods to determine when to adjust images for different content size -/// categories. -public protocol ContentSizeCategoryImageAdjusting { - /// Preferring Accessibility-Specific Images - - /// A boolean that indicates whether the image size increases to support - /// accessibility content size categories. - var adjustsImageSizeForAccessibilityContentSizeCategory: Bool { get set } -} - diff --git a/Sources/SwiftWin32/UI/Interaction.swift b/Sources/SwiftWin32/UI/Interaction.swift deleted file mode 100644 index 29545b78..00000000 --- a/Sources/SwiftWin32/UI/Interaction.swift +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright © 2019 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -/// The protocol that an interaction implements to access the view that owns it. -public protocol Interaction: AnyObject { - // MARK - Getting the View - - /// The view that owns the interaction. - /* weak */ var view: View? { get } - - // MARK - Tracking the Movements - - /// Tells the interaction that a view added or removed it from the view's - /// interaction array. - func didMove(to view: View?) - - /// Tells the interaction that a view will add or remove it from the view's - /// interaction array. - func willMove(to view: View?) -} diff --git a/Sources/SwiftWin32/UI/SceneSizeRestrictions.swift b/Sources/SwiftWin32/UI/SceneSizeRestrictions.swift deleted file mode 100644 index 56c23d1a..00000000 --- a/Sources/SwiftWin32/UI/SceneSizeRestrictions.swift +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -#if swift(>=5.7) -import CoreGraphics -#endif - -public class SceneSizeRestrictions { - /// Setting the Size Restrictions - - /// The minimum width and height supported by your application's windows. - public var minimumSize: Size = Size(width: 768, height: 768) - - /// The maximum width and height supported by your application's windows. - public var maximumSize: Size = Size(width: 768, height: 768) -} diff --git a/Sources/SwiftWin32/View Controllers/ContentContainer.swift b/Sources/SwiftWin32/View Controllers/ContentContainer.swift deleted file mode 100644 index 0cfe8ceb..00000000 --- a/Sources/SwiftWin32/View Controllers/ContentContainer.swift +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -#if swift(>=5.7) -import CoreGraphics -#endif - -/// A set of methods for adapting the contents of your view controllers to size -/// and trait changes. -public protocol ContentContainer { - // MARK - Responding to Environment Changes - - /// Notifies the container that the size of its view is about to change. - func willTransition(to: Size, - with coodinator: ViewControllerTransitionCoordinator) - - /// Notifies the container that its trait collection changed. - func willTransition(to: TraitCollection, - with coordinator: ViewControllerTransitionCoordinator) - - // MARK - Responding to Changes in Child View Controllers - - /// The preferred size for the container's content. - var preferredContentSize: Size { get } - - /// Returns the size of the specified child view controller's content. - func size(forChildContentContainer container: ContentContainer, - withParentContainerSize parentSize: Size) -> Size - - /// Notifies an interested controller that the preferred content size of one of - /// its children changed. - func preferredContentSizeDidChange(forChildContentContainer container: ContentContainer) - - /// Notifies the container that a child view controller was resized using auto - /// layout. - func systemLayoutFittingSizeDidChange(forChildContentContainer container: ContentContainer) -} diff --git a/Sources/SwiftWin32/View Controllers/PresentationController.swift b/Sources/SwiftWin32/View Controllers/PresentationController.swift deleted file mode 100644 index 637f29be..00000000 --- a/Sources/SwiftWin32/View Controllers/PresentationController.swift +++ /dev/null @@ -1,296 +0,0 @@ -// Copyright © 2021 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -#if swift(>=5.7) -import CoreGraphics -#endif - -/// An object that manages the transition animations and the presentation of -/// view controllers onscreen. -open class PresentationController { - // MARK - Initializing a Presentation Controller - - /// Initializes and returns a presentation controller for transitioning - /// between the specified view controllers - /// - /// This method is the designated initializer for the presentation controller. - /// You must call it from any custom initialization methods you define for - /// your presentation controller subclasses. - public init(presentedViewController: ViewController, - presenting presentingViewController: ViewController?) { - self.presentedViewController = presentedViewController - // If the presentingViewController is nil, walk the view hierarchy to find - // the first view controller which serves as the presenting view controller. - self.presentingViewController = - (presentingViewController - ?? Application.shared.keyWindow?.rootViewController - ?? Application.shared.delegate as? ViewController)! - self.presentationStyle = .custom - self.frameOfPresentedViewInContainerView = - self.containerView?.bounds ?? .zero - } - - // MARK - Adapting Your Presentations Dynamically - - /// The delegate object for managing adaptive presentations. - /// - /// When the application's size changes, the presentation controller works - /// with this delegate object to determine an appropriate response. View - /// controllers presented using the `ModalPresentationStyle.formSheet`, - /// `ModalPresentationStyle.popover`, or `ModalPresentationStyle.custom` style - /// must change to use one of the full-screen presentation styles instead. The - /// delegate can also opt to change the presented view controller entirely. - /// - /// The object you assign to this property must conform to the - /// `AdaptivePresentationControllerDelegate` protocol. - open weak var delegate: AdaptivePresentationControllerDelegate? - - // MARK - Getting the Presentation Objects - - /// The view controller that is the starting point for the presentation. - /// - /// The object in this property could be the root view controller of the - /// window, a parent view controller that is marked as defining the current - /// context, or the last view controller that was presented onscreen. This - /// view controller may or may not be the same one whose - /// `present(_:animated:completion:)` method was called to initiate the - /// presentation process. It may also not be the view controller used to - /// initialize your presentation controller. - open private(set) var presentingViewController: ViewController - - /// The view controller being presented. - /// - /// This object corresponds to the one passed as the first parameter of the - /// `present(_:animated:completion:)` method. The successful conclusion of the - /// presentation process causes this view controller's content to be displayed - /// onscreen. - open private(set) var presentedViewController: ViewController - - /// The view in which the presentation occurs. - /// - /// The framework sets the value of this property shortly after receiving the - /// presentation controller from your transitioning delegate. The container - /// view is always an ancestor of the presented view controller's view. During - /// transition animations, the container view also contains the presenting - /// view controller's view. When adding custom views to a presentation, add - /// them to the container view. - /// - /// If your transition also employs custom animator objects, those objects can - /// get this container view from the `containerView` property of the context - /// object provided by the framework. - open private(set) var containerView: View? - - /// The view to be animated by the animator objects during a transition. - /// - /// The default implementation of this method returns the presented view - /// controller's view. If you want to animate a different view, you may - /// override this method and return that view. The view you specify must - /// either be the presented view controller's view or must be one of its - /// ancestors. - /// - /// The view returned by this method is given to the animator objects, which - /// are responsible for animating it onscreen. The animator objects retrieve - /// the view using the `view(forKey:)` method of the context object provided - /// by the framework. - /// - /// The framework calls this method multiple times during the course of a - /// presentation, so your implementation should return the appropriate view as - /// quickly as possible. Do not use this method to actually configure your - /// view hierarchy. If you intend to return a custom view, configure your view - /// hierarchy in the `presentationTransitionWillBegin()` method. - open private(set) var presentedView: View? - - // MARK - Adjusting the Size and Layout of the Presentation - - /// The frame rectangle to assign to the presented view at the end of the - /// animations. - /// - /// The default implementation of this method returns the frame rectangle of - /// the container view, which results in the presented view controller's - /// content occupying the entire presentation space. You can override this - /// method and return a different frame rectangle as needed. For example, you - /// might specify a smaller frame rectangle if you want some of the underlying - /// content to show around the edges of the presented view. - /// - /// The framework calls this method multiple times during the course of a - /// presentation, so your implementation should return the same frame - /// rectangle each time. Do not use this method to make changes to your view - /// hierarchy or perform other one-time tasks. - open var frameOfPresentedViewInContainerView: Rect - - /// Interface traits for the presented view controller, to use in place of - /// traits from the current device environment. - /// - /// Use this property to provide an interface trait collection for the - /// presented view controller, overriding one or more values in the current - /// device trait environment. - /// - /// Each value you place in the `overrideTraitCollection` property overrides - /// the corresponding value in the current device trait environment. For - /// example, the following code snippet shows how to override the display - /// scale for the presented view controller, leaving other traits as they are - /// provided by the system. Place such code, typically, in the implementation - /// file for the presenting view controller: - /// - /// ```swift - /// viewController.presentationController.overrideTraitCollection = TraitCollection(traitsFrom: [.current, .init(displayScale: 1.5)]) - /// self.present(viewController, animated: false, completion: nil) - /// ``` - /// - /// The presenting view controller is not affected by use of this property. - /// - /// The default value of the `overrideTraitCollection` property is `nil`, - /// which results in the full current device trait environment being used by - /// the presented view controller. - /* @NSCopying */ open var overrideTraitCollection: TraitCollection? - - /// Notifies the presentation controller that layout is about to begin on the - /// views of the container view. - /// - /// The framework calls this method before adjusting the layout of the views - /// in the container view. Use this method and the - /// `containerViewDidLayoutSubviews()` method to update any custom views - /// managed by your presentation controller. - open func containerViewWillLayoutSubviews() { - } - - /// Called to notify the presentation controller that layout ended on the - /// views of the container view. - /// - /// The framework calls this method after adjusting the layout of the views in - /// the container view. Use this method to make any additional changes to the - /// view hierarchy. - open func containerViewDidLayoutSubviews() { - } - - // MARK - Tracking the Transition's Start and End - - /// Notifies the presentation controller that the presentation animations are - /// about to start. - /// - /// The default implementation of this method does nothing. Subclasses can - /// override it and use it to add custom views to the view hierarchy and to - /// create any animations associated with those views. To perform your - /// animations, get the transition coordinator of the presented view - /// controller and call its `animate(alongsideTransition:completion:)` or - /// `animateAlongsideTransition(in:animation:completion:)` method. Calling - /// those methods ensures that your animations are executed at the same time - /// as any other transition animations. - open func presentationTransitionWillBegin() { - } - - /// Notifies the presentation controller that the presentation animations - /// finished. - /// - /// The default implementation of this method does nothing. Subclasses can - /// override this method and use it to perform any required cleanup. For - /// example, if the `completed` parameter is `false`, you would use this - /// method to remove your presentation's custom views from the view hierarchy. - open func presentationTransitionDidEnd(_ completed: Bool) { - } - - /// Notifies the presentation controller that the dismissal animations are - /// about to start. - /// - /// The default implementation of this method does nothing. Subclasses can - /// override this method and use it to configure any animations associated - /// with your presentation's custom views. To perform your animations, get - /// the transition coordinator of the presented view controller and call - /// its `animate(alongsideTransition:completion:)` or - /// `animateAlongsideTransition(in:animation:completion:)` method. Calling - /// those methods ensures that your animations are executed at the same time - /// as any other transition animations. - /// - /// Do not use this method to remove your views from the view hierarchy. - /// Remove your views in the `dismissalTransitionDidEnd(_:)` method instead. - open func dismissalTransitionWillBegin() { - } - - /// Notifies the presentation controller that the dismissal animations - /// finished. - /// - /// The default implementation of this method does nothing. Subclasses can - /// override this method and use it to remove any custom views that the - /// presentation controller added to the view hierarchy. Remove your views - /// only if the `completed` parameter is `true`. - open func dismissalTransitionDidEnd(_ completed: Bool) { - } - - // MARK - Getting the Presentation Attributes - - /// The presentation style of the presented view controller. - /// - /// This property is set to the presentation style of the presented view - /// controller. The presentation controller uses this style to determine the - /// initial appearance of the presented content. - open private(set) var presentationStyle: ModalPresentationStyle - - /// Returns the presentation style to use for the specified set of traits. - /// - /// After the content managed by the presentation controller is onscreen, this - /// method returns the presentation style to use for the specified set of - /// traits. The default implementation of this method consults its delegate - /// object and returns the value returned by that object’s - /// `adaptivePresentationStyle(for:traitCollection:)` method. Some - /// system-supplied presentation controllers may also provide a new style that - /// is more suited to the new set of traits. - /// - /// This method returns the presentation style for the new traits, but does - /// not initiate a transition to the new style. The system initiates the - /// transition to the new style when the traits actually change. When - /// transitioning to new traits, the actual presentation controller object may - /// change. As a result, do not cache the presentation controller object in - /// your code. Always retrieve it from your view controller's - /// `presentationController` property. - open func adaptivePresentationStyle(for traitCollection: TraitCollection) - -> ModalPresentationStyle { - return self.delegate?.adaptivePresentationStyle(for: self, - traitCollection: traitCollection) - ?? .none - } - - /// Returns the presentation style to use when the presented view controller - /// becomes horizontally compact. - /// - /// After the content managed by the presentation controller is onscreen, this - /// method returns the presentation style to use when transitioning to a - /// horizontally compact environment. This method is not meant to be - /// overridden. The implementation consults its delegate object and returns - /// the value provided by that object's `adaptivePresentationStyle(for:)` - /// method. Some system-supplied presentation controllers may also provide a - /// new style that is more suited for a compact environment. For example, - /// presentation controllers that manage popovers and form sheets return the - /// `ModalPresentationStyle.fullScreen` value. - /// - /// This method only returns the presentation style to use in a horizontally - /// compact environment. It does not initiate a transition to the new style. - /// The system initiates the transition to the new style when the size class - /// actually changes. When transitioning to a new style, the actual - /// presentation controller object may change. As a result, do not cache the - /// presentation controller object in your code. Always retrieve it from your - /// view controller's presentationController property. - /// - /// Use `adaptivePresentationStyle(for:)` instead. - open var adaptivePresentationStyle: ModalPresentationStyle = .none - - /// A boolean value indicating whether the presentation covers the entire - /// screen. - /// - /// The default implementation of this method returns `true`, indicating that - /// the presentation covers the entire screen. You can override this method - /// and return `false` to force the presentation to display only in the - /// current context. - /// - /// If you override this method, do not call `super`. - open private(set) var shouldPresentInFullscreen: Bool = true - - /// A boolean value indicating whether the presenting view controller's view - /// should be removed when the presentation animations finish. - /// - /// The default implementation of this method returns `false`. If you - /// implement a presentation that does not cover the presenting view - /// controller's content entirely, override this method and return `false`. - /// - /// If you override this method, do not call `super`. - open private(set) var shouldRemovePresentersView: Bool = false -} diff --git a/Sources/SwiftWin32/View Controllers/ViewController.swift b/Sources/SwiftWin32/View Controllers/ViewController.swift deleted file mode 100644 index 9029c43d..00000000 --- a/Sources/SwiftWin32/View Controllers/ViewController.swift +++ /dev/null @@ -1,1333 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import WinSDK -import class Foundation.NSNotification -import struct Foundation.NSExceptionName -import struct Foundation.TimeInterval - -#if swift(>=5.7) -import CoreGraphics -#endif - -/// Transition styles available when presenting view controllers. -public enum ModalTransitionStyle: Int { - /// - /// - /// When the view controller is presented, its view slides up from the bottom - /// of the screen. On dismissal, the view slides back down. This is the - /// default transition style. - case coverVertical - - /// - /// - /// When the view controller is presented, the current view initiates a - /// horizontal 3D flip from right-to-left, resulting in the revealing of the - /// new view as if it were on the back of the previous view. On dismissal, the - /// flip occurs from left-to-right, returning to the original view. - case flipHorizontal - - /// - /// - /// When the view controller is presented, the current view fades out while - /// the new view fades in at the same time. On dismissal, a similar type of - /// cross-fade is used to return to the original view. - case crossDissolve - - /// - /// - /// When the view controller is presented, one corner of the current view - /// curls up to reveal the presented view underneath. On dismissal, the curled - /// up page unfurls itself back on top of the presented view. A view - /// controller presented using this transition is itself prevented from - /// presenting any additional view controllers. - /// - /// This transition style is supported only if the parent view controller is - /// presenting a full-screen view and you use the - /// `ModalPresentationStyle.fullScreen` modal presentation style. Attempting - /// to use a different form factor for the parent view or a different - /// presentation style triggers an exception. - case partialCurl -} - -/// Constants that specify the edges of a rectangle. -public struct RectEdge: OptionSet { - public typealias RawValue = UInt - - public let rawValue: RawValue - - public init(rawValue: RawValue) { - self.rawValue = rawValue - } -} - -extension RectEdge { - /// The top edge of the rectangle. - public static var top: RectEdge { - RectEdge(rawValue: 1 << 0) - } - - /// The left edge of the rectangle. - public static var left: RectEdge { - RectEdge(rawValue: 1 << 1) - } - - /// The bottom edge of the rectangle. - public static var bottom: RectEdge { - RectEdge(rawValue: 1 << 2) - } - - /// The right edge of the rectangle. - public static var right: RectEdge { - RectEdge(rawValue: 1 << 3) - } - - /// All edges of the rectangle. - public static var all: RectEdge { - RectEdge(rawValue: 0xf) - } -} - -/// An object that manages a view hierarchy for your application. -open class ViewController: Responder { - // MARK - Managing the View - - /// The view that the controller manages. - /// - /// This property represents the root view of the view controller's view - /// hierarchy. The default value of this property is `nil`. - /// - /// If you access this property when its value is `nil`, the view controller - /// automatically calls the `loadView()` method and returns the resulting - /// view. - /// - /// Each view controller is the sole owner of its view object. Don't associate - /// the same view object with multiple view controllers. The only exception is - /// that a container view controller implementation may add another view - /// controller's view object to its own view hierarchy. Before adding the - /// subview, the container must first call its `addChild(_:)` method to create - /// a parent-child relationship between the two view controller objects. - /// - /// Because accessing this property can cause the view to be loaded - /// automatically, you can use `isViewLoaded` to determine if the view is - /// currently in memory. Unlike this property, `isViewLoaded` doesn't force - /// the loading of the view if it's not currently in memory. - open var view: View! { - get { - loadViewIfNeeded() - return self.viewIfLoaded - } - set { - self.viewIfLoaded = newValue - } - } - - /// The controller's view or `nil` if the view is not yet loaded. - /// - /// If the view controller's view has already been loaded, this property - /// contains that view. If the view has not yet been loaded, this property is - /// set to `nil`. - open private(set) var viewIfLoaded: View? - - /// Indicates if the view is loaded into memory. - /// - /// The value of this property is `true` when the view is in memory or `false` - /// when it is not. Accessing this property does not attempt to load the view - /// if it is not currently in memory. - open var isViewLoaded: Bool { - return self.viewIfLoaded == nil ? false : true - } - - /// Creates the view that the controller manages. - /// - /// You should never call this method directly. The view controller calls this - /// method when its view property is requested but is currently `nil`. This - /// method loads or creates a view and assigns it to the view property. - /// - /// You can override this method in order to create your views manually. If - /// you choose to do so, assign the root view of your view hierarchy to the - /// view property. The views you create should be unique instances and should - /// not be shared with any other view controller object. Your custom - /// implementation of this method should not call `super`. - /// - /// If you want to perform any additional initialization of your views, do so - /// in the `viewDidLoad()` method. - open func loadView() { - self.view = View(frame: .zero) - } - - /// Called after the controller's view is loaded info memory. - /// - /// This method is called after the view controller has loaded its view - /// hierarchy into memory. - open func viewDidLoad() { - } - - /// Loads the controller's view if it has not yet been loaded. - /// - /// Calling this method loads the view controller's, creating the view as - /// needed based on the established rules. - open func loadViewIfNeeded() { - guard !self.isViewLoaded else { return } - self.loadView() - self.viewDidLoad() - } - - /// A localized string that represents the view this controller manages. - /// - /// Set the title to a human-readable string that describes the view. If the - /// view controller has a valid navigation item or tab-bar item, assigning a - /// value to this property updates the title text of those objects. - open var title: String? { - get { - let szLength: Int32 = GetWindowTextLengthW(view.hWnd) - guard szLength > 0 else { return nil } - - let buffer: [WCHAR] = Array(unsafeUninitializedCapacity: Int(szLength) + 1) { - $1 = Int(GetWindowTextW(view.hWnd, $0.baseAddress!, CInt($0.count))) + 1 - } - return String(decodingCString: buffer, as: UTF16.self) - } - set(value) { _ = SetWindowTextW(view.hWnd, value?.wide) } - } - - /// The preferred size for the view controller's view. - /// - /// The value in this property is used primarily when displaying the view - /// controller's content in a popover but may also be used in other - /// situations. Changing the value of this property while the view controller - /// is being displayed in a popover animates the size change; however, the - /// change is not animated if you specify a width or height of 0.0. - open var preferredContentSize: Size { - get { fatalError("\(#function) not yet implemented") } - set { fatalError("\(#function) not yet implemented") } - } - - // MARK - Responding to View Related Events - - /// Notifies the view controller that its view is about to be added to a view - /// hierarchy. - /// - /// This method is called before the view controller's view is about to be - /// added to a view hierarchy and before any animations are configured for - /// showing the view. You can override this method to perform custom tasks - /// associated with displaying the view. For example, you might use this - /// method to change the orientation or style of the status bar to coordinate - /// with the orientation or style of the view being presented. If you override - /// this method, you must call `super` at some point in your implementation. - open func viewWillAppear(_ animated: Bool) { - } - - /// Notifies the view controller that its view was added to a view hierarchy. - /// - /// You can override this method to perform additional tasks associated with - /// presenting the view. If you override this method, you must call `super` at - /// some point in your implementation. - /// - /// - Note - /// If a view controller is presented by a view controller inside of a - /// popover, this method is not invoked on the presenting view controller - /// after the presented controller is dismissed. - open func viewDidAppear(_ animated: Bool) { - } - - /// Notifies the view controller that its view is about to be removed from a - /// view hierarchy. - /// - /// This method is called in response to a view being removed from a view - /// hierarchy. This method is called before the view is actually removed and - /// before any animations are configured. - /// - /// Subclasses can override this method and use it to commit editing changes, - /// resign the first responder status of the view, or perform other relevant - /// tasks. For example, you might use this method to revert changes to the - /// orientation or style of the status bar that were made in the - /// `viewDidAppear(_:)` method when the view was first presented. If you - /// override this method, you must call `super` at some point in your - /// implementation. - open func viewWillDisappear(_ animated: Bool) { - } - - /// Notifies the view controller that its view was removed from a view - /// hierarchy. - /// - /// You can override this method to perform additional tasks associated with - /// dismissing or hiding the view. If you override this method, you must call - /// `super` at some point in your implementation. - open func viewDidDisappear(_ animated: Bool) { - } - - /// A boolean value indicating whether the view controller is being dismissed. - open private(set) var isBeingDismissed: Bool = false - - /// A boolean value indicating whether the view controller is being presented. - open private(set) var isBeingPresented: Bool = false - - /// A boolean value indicating whether the view controller is being removed - /// from a parent view controller. - open private(set) var isMovingFromParent: Bool = false - - /// A boolean value indicating whether the view controller is being moved to a - /// parent view controller. - open private(set) var isMovingToParent: Bool = false - - // MARK - Extending the View's Safe Area - - /// The inset distances for views. - /// - /// Use this property to adjust the safe area insets of this view controller's - /// views by the specified amount. The safe area defines the portion of your - /// view controller's visible area that is guaranteed to be unobscured by the - /// system status bar or by an ancestor-provided view such as the navigation - /// bar. - /// - /// You might use this property to extend the safe area to include custom - /// content in your interface. For example, a drawing app might use this - /// property to avoid displaying content underneath tool palettes. - open var additionalSafeAreaInsets: EdgeInsets = .zero { - didSet { self.viewSafeAreaInsetsDidChange() } - } - - /// Notifies the view controller that the safe area insets of its root view - /// changed. - /// - /// Use this method to update your interface to accommodate the new safe area. - /// The framework updates the safe area in response to size changes to system - /// bars or when you modify the additional safe area insets of your view - /// controller. The framework also calls this method immediately before your - /// view appears onscreen. - open func viewSafeAreaInsetsDidChange() { - } - - // MARK - Managing the View's Margins - - /// A boolean value indicating whether the view controller's view uses the - /// system-defined minimum layout margins. - /// - /// When the value of this property is `true`, the root view's layout margins - /// are guaranteed to be no smaller than the values in the - /// `systemMinimumLayoutMargins` property. The default value of this property - /// is `true`. - /// - /// Changing this property to `false` causes the view to obtain its margins - /// solely from its `directionalLayoutMargins` property. Setting the margins - /// in that property to 0 allows you to eliminate the view's margins - /// altogether. - open var viewRespectsSystemMinimumLayoutMargins: Bool = true - - /// The minimum layout margins for the view controller's root view. - /// - /// This property contains the minimum layout margins expected by the system - /// for the view controller's root view. Do not override this property. To - /// stop considering the system's minimum layout margins for the root view, - /// set the `viewRespectsSystemMinimumLayoutMargins` property to `false`. This - /// property does not affect the margins associated with subviews of the root - /// view. - /// - /// If you assign a custom value to the `directionalLayoutMargins` property of - /// the view controller's root view, the root view's actual margins are set to - /// either your custom values or the minimum values defined by this property, - /// whichever values are greater. For example, if the value for one system - /// minimum margin is 20 points and you specify a value of 10 for the same - /// margin on the view, the view uses the value 20 for the margin. - open private(set) var systemMinimumLayoutMargins: DirectionalEdgeInsets = .zero { - didSet { self.viewLayoutMarginsDidChange() } - } - - /// Notifies the view controller that the layout margins of its root view - /// changed. - /// - /// Use this method to update the position of content based on the new margin - /// values. - open func viewLayoutMarginsDidChange() { - } - - // MARK - Configuring the View's Layout Behavior - - /// The edges that you extend for your view controller. - /// - /// Instead of this property, use the safe area of your view to determine - /// which parts of your interface are occluded by other content. For more - /// information, see the `safeAreaLayoutGuide` and `safeAreaInsets` properties - /// of `View`. - /// - /// The default value of this property is `.all`, and it is recommended that - /// you do not change that value. - /// - /// If you remove an edge value from this property, the system does not lay - /// out your content underneath other bars on that same edge. In addition, the - /// system provides a default background so that translucent bars have an - /// appropriate appearance. The window's root view controller does not react - /// to this property. - open var edgesForExtendedLayout: RectEdge = .all - - /// A boolean value indicating whether or not the extended layout includes - /// opaque bars. - /// - /// The default value of this property is `false`. - open var extendedLayoutIncludesOpaqueBars: Bool = false - - /// Notifies the view controller that its view is about to layout its - /// subviews. - /// - /// When a view's bounds change, the view adjusts the position of its - /// subviews. Your view controller can override this method to make changes - /// before the view lays out its subviews. The default implementation of this - /// method does nothing. - open func viewWillLayoutSubviews() { - } - - /// Notifes the view controller that its view has just laid out its subviews. - /// - /// When the bounds change for a view controller's view, the view adjusts the - /// positions of its subviews and then the system calls this method. However, - /// this method being called does not indicate that the individual layouts of - /// the view's subviews have been adjusted. Each subview is responsible for - /// adjusting its own layout. - /// - /// Your view controller can override this method to make changes after the - /// view lays out its subviews. The default implementation of this method does - /// nothing. - open func viewDidLayoutSubviews() { - } - - /// Called when the view controller's view needs to update its constraints. - /// - /// Override this method to optimize changes to your constraints. - /// - /// - Note - /// It is almost always cleaner and easier to update a constraint - /// immediately after the affecting change has occurred. For example, if you - /// want to change a constraint in response to a button tap, make that - /// change directly in the button's action method. - /// - /// You should only override this method when changing constraints in place - /// is too slow, or when a view is producing a number of redundant changes. - /// - /// To schedule a change, call `setNeedsUpdateConstraints()` on the view. The - /// system then calls your implementation of `updateViewConstraints()` before - /// the layout occurs. This lets you verify that all necessary constraints for - /// your content are in place at a time when your properties are not changing. - /// - /// Your implementation must be as efficient as possible. Do not deactivate - /// all your constraints, then reactivate the ones you need. Instead, your app - /// must have some way of tracking your constraints, and validating them - /// during each update pass. Only change items that need to be changed. During - /// each update pass, you must ensure that you have the appropriate - /// constraints for the app's current state. - /// - /// Do not call `setNeedsUpdateConstraints()` inside your implementation. - /// Calling `setNeedsUpdateConstraints()` schedules another update pass, - /// creating a feedback loop. - /// - /// - Important - /// Call `super.updateViewConstraints()` as the final step in your - /// implementation. - open func updateViewConstraints() { - fatalError("\(#function) not yet implemented") - } - - // MARK - Configuring the View Rotation Settings - - /// A boolean value that indicates whether the view controller's contents - /// should autorotate. - public private(set) var shouldAutorotate: Bool = true - - /// The interface orientations that the view controller supports. - /// - /// This property returns a bit mask that specifies which orientations the - /// view controller supports. For more information, see - /// `InterfaceOrientationMask`. - /// - /// When the device orientation changes, the system calls this method on the - /// root view controller or the topmost modal view controller that fills the - /// window. If the view controller supports the new orientation, the system - /// rotates the window and the view controller. The system only calls this - /// method if the view controller's `shouldAutorotate` method returns `true`. - /// - /// Override this method to declare which orientations the view controller - /// supports. The default value is `.all`. The value you return must not be 0. - /// - /// To determine whether to rotate, the system compares the view controller's - /// supported orientations with the app's supported orientations — as - /// determined by the `Info.plist` file or the app delegate's - /// `application(_:supportedInterfaceOrientationsFor:)` method — and the - /// device's supported orientations. - /// - /// If your app supports multitasking, the system doesn't call this method on - /// your view controller because multitasking apps must support all - /// orientations. You can opt out of multitasking by enablin by not declaring - /// support for all possible orientations within the `Info.plist` file. - open private(set) var supportedInterfaceOrientations: InterfaceOrientationMask = .allButUpsideDown - - /// The interface orientation to use when presenting the view controller. - /// - /// The system calls this method when presenting the view controller full - /// screen. When your view controller supports two or more orientations but - /// the content appears best in one of those orientations, override this - /// method and return the preferred orientation. - /// - /// If your view controller implements this method, your view controller's - /// view is shown in the preferred orientation (although it can later be - /// rotated to another supported rotation). If you do not implement this - /// method, the system presents the view controller using the current - /// orientation of the status bar. - open private(set) var preferredInterfaceOrientationForPresentation: InterfaceOrientation = .portrait - - /// Notifies the view controller about a change in supported interface - /// orientations or preferred interface orientation for presentation. - /// - /// By default, this method animates any changes to orientation. To perform a - /// nonanimated update, call this method from `performWithoutAnimation(_:)``. - open func setNeedsUpdateOfSupportedInterfaceOrientations() { - fatalError("\(#function) not yet implemented") - } - - /// Attempts to rotate all windows to the orientation of the device. - /// - /// Some view controllers may want to use app-specific conditions to determine - /// what interface orientations are supported. If your view controller does - /// this, when those conditions change, your app should call this class - /// method. The system immediately attempts to rotate to the new orientation. - public class func attemptRotationToDeviceOrientation() { - } - - // MARK - Presenting a View Controller - - /// Presents a view controller in a primary context. - /// - /// You use this method to decouple the need to display a view controller from - /// the process of actually presenting that view controller onscreen. Using - /// this method, a view controller does not need to know whether it is - /// embedded inside a navigation controller or split-view controller. It calls - /// the same method for both. The `SplitViewController` and - /// `NavigationController` classes override this method and handle the - /// presentation according to their design. For example, a navigation - /// controller overrides this method and uses it to push a view controller - /// onto its navigation stack. - /// - /// The default implementation of this method calls the - /// `targetViewController(forAction:sender:)` method to locate an object in - /// the view controller hierarchy that overrides this method. It then calls - /// the method on that target object, which displays the view controller in an - /// appropriate way. If the `targetViewController(forAction:sender:)` method - /// returns `nil`, this method uses the window's root view controller to - /// present the view controller modally. - /// - /// You can override this method in custom view controllers to display the - /// view controller yourself. Use this method to display the view controller - /// in a primary context. For example, a container view controller might use - /// this method to replace its primary child. Your implementation should adapt - /// its behavior for both regular and compact environments. - open func show(_ viewController: ViewController, sender: Any?) { - } - - /// Presents a view controller in a secondary (or detail) context. - /// - /// You use this method to decouple the need to display a view controller from - /// the process of actually presenting that view controller onscreen. Using - /// this method, a view controller does not need to know whether it is - /// embedded inside a navigation controller or split-view controller. It calls - /// the same method for both. In a regular environment, the - /// `SplitViewController` class overrides this method and installs the view - /// controller as its detail view controller; in a compact environment, the - /// split view controller's implementation of this method calls - /// `show(_:sender:)` instead. - /// - /// The default implementation of this method calls the - /// `targetViewController(forAction:sender:)` method to locate an object in - /// the view controller hierarchy that overrides this method. It then calls - /// the method on that target object, which displays the view controller in an - /// appropriate way. If the `targetViewController(forAction:sender:)` method - /// returns `nil`, this method uses the window's root view controller to - /// present the view controller modally. - /// - /// You can override this method in custom view controllers to display the - /// view controller yourself. Use this method to display the view controller - /// in a secondary context. For example, a container view controller might use - /// this method to replace its secondary child. Your implementation should - /// adapt its behavior for both regular and compact environments. - open func showDetailViewController(_ viewController: ViewController, - sender: Any?) { - } - - /// Presents a view controller modally. - /// - /// In a horizontally regular environment, the view controller is presented in - /// the style specified by the `modalPresentationStyle` property. In a - /// horizontally compact environment, the view controller is presented full - /// screen by default. If you associate an adaptive delegate with the - /// presentation controller associated with the object in - /// `viewControllerToPresent`, you can modify the presentation style - /// dynamically. - /// - /// The object on which you call this method may not always be the one that - /// handles the presentation. Each presentation style has different rules - /// governing its behavior. For example, a full-screen presentation must be - /// made by a view controller that itself covers the entire screen. If the - /// current view controller is unable to fulfill a request, it forwards the - /// request up the view controller hierarchy to its nearest parent, which can - /// then handle or forward the request. - /// - /// Before displaying the view controller, this method resizes the presented - /// view controller's view based on the presentation style. For most - /// presentation styles, the resulting view is then animated onscreen using - /// the transition style in the `modalTransitionStyle` property of the - /// presented view controller. For custom presentations, the view is animated - /// onscreen using the presented view controller's transitioning delegate. For - /// current context presentations, the view may be animated onscreen using the - /// current view controller's transition style. - /// - /// The completion handler is called after the `viewDidAppear(_:)` method is - /// called on the presented view controller. - open func present(_ viewController: ViewController, animated flag: Bool, - completion: (() -> Void)? = nil) { - } - - /// Dismisses the view controller that was presented modally by the view - /// controller. - /// - /// The presenting view controller is responsible for dismissing the view - /// controller it presented. If you call this method on the presented view - /// controller itself, the framework asks the presenting view controller to - /// handle the dismissal. - /// - /// If you present several view controllers in succession, thus building a - /// stack of presented view controllers, calling this method on a view - /// controller lower in the stack dismisses its immediate child view - /// controller and all view controllers above that child on the stack. When - /// this happens, only the top-most view is dismissed in an animated fashion; - /// any intermediate view controllers are simply removed from the stack. - /// The top-most view is dismissed using its modal transition style, which may - /// differ from the styles used by other view controllers lower in the stack. - /// - /// If you want to retain a reference to the view controller's presented view - /// controller, get the value in the `presentedViewController` property before - /// calling this method. - /// - /// The completion handler is called after the `viewDidDisappear(_:)` method - /// is called on the presented view controller. - open func dismiss(animated flag: Bool, completion: (() -> Void)? = nil) { - } - - /// The presentation style for modal view controllers. - /// - /// Presentation style defines how the system presents a modal view - /// controller. The system uses this value only in regular-width size classes. - /// In compact-width size classes, some styles take on the behavior of other - /// styles. You can influence this behavior by implementing the - /// `adaptivePresentationStyle(for:traitCollection:)` method. - /// - /// Presentation style also impacts the content size of a modal view - /// controller. For example, `ModalPresentationStyle.pageSheet` uses an - /// explicit size that the system provides. By contrast, - /// `ModalPresentationStyle.formSheet` uses the view controller's - /// `preferredContentSize` property, which you can set. - /// - /// The default value is `ModalPresentationStyle.automatic`. For a list of - /// presentation styles and their compatibility with the various transition - /// styles, see `ModalPresentationStyle`. - open var modalPresentationStyle: ModalPresentationStyle = .automatic { - didSet { fatalError("\(#function) not yet implemented") } - } - - /// The transition style to use when presenting the view controller. - /// - /// This property determines how the view controller's is animated onscreen - /// when it is presented using the `present(_:animated:completion:)` method. - /// To change the transition type, you must set this property before - /// presenting the view controller. The default value for this property is - /// `ModalTransitionStyle.coverVertical`. - /// - /// For a list of possible transition styles, and their compatibility with the - /// available presentation styles, see the `ModalTransitionStyle` constant - /// descriptions. - open var modalTransitionStyle: ModalTransitionStyle = .coverVertical - - /// A boolean value indicating whether the view controller enforces a modal - /// behavior. - /// - /// The default value of this property is `false`. When you set it to `true`, - /// the framework ignores events outside the view controller's bounds and - /// prevents the interactive dismissal of the view controller while it is - /// onscreen. - open var isModalInPresentation: Bool = false { - didSet { fatalError("\(#function) not yet implemented") } - } - - /// A boolean value that indicates whether this view controller's view is - /// covered when the view controller or one of its descendants presents a view - /// controller. - /// - /// When using the `ModalPresentationStyle.currentContext` or - /// `ModalPresentationStyle.overCurrentContext` style to present a view - /// controller, this property controls which existing view controller in your - /// view controller hierarchy is actually covered by the new content. When a - /// context-based presentation occurs, the framework starts at the presenting - /// view controller and walks up the view controller hierarchy. If it finds a - /// view controller whose value for this property is `true`, it asks that view - /// controller to present the new view controller. If no view controller - /// defines the presentation context, the framework asks the window's root - /// view controller to handle the presentation. - /// - /// The default value for this property is `false`. Some system-provided view - /// controllers, such as `NavigationController`, change the default value to - /// `true`. - open var definesPresentationContext: Bool = false { - didSet { fatalError("\(#function) not yet implemented") } - } - - /// A boolean value that indicates whether the view controller specifies the - /// transition style for view controllers it presents. - /// - /// When a view controller's `definesPresentationContext` property is `true`, - /// it can replace the transition style of the presented view controller with - /// its own. When the value of this property to `true`, the current view - /// controller's transition style is used instead of the style associated with - /// the presented view controller. When the value of this property is `false`, - /// the framework uses the transition style of the presented view controller. - /// The default value of this property is `false`. - open var providesPresentationContextTransitionStyle: Bool = false { - didSet { fatalError("\(#function) not yet implemented") } - } - - /// Returns a boolean indicating whether the current input view is dismissed - /// automatically when changing controls. - /// - /// Override this method in a subclass to allow or disallow the dismissal of - /// the current input view (usually the system keyboard) when changing from a - /// control that wants the input view to one that does not. Under normal - /// circumstances, when the user taps a control that requires an input view, - /// the system automatically displays that view. Tapping in a control that - /// does not want an input view subsequently causes the current input view to - /// be dismissed but may not in all cases. You can override this method in - /// those outstanding cases to allow the input view to be dismissed or use - /// this method to prevent the view from being dismissed in other cases. - /// - /// The default implementation of this method returns true when the modal - /// presentation style of the view controller is set to - /// `ModalPresentationStyle.formSheet` and returns `false` for other - /// presentation styles. Thus, the system normally does not allow the keyboard - /// to be dismissed for modal forms. - open var disablesAutomaticKeyboardDismissal: Bool { - return self.modalPresentationStyle == .formSheet - } - - /// Posted when a split view controller is expanded or collapsed. - /// - /// When a view controller is using `show(_:sender:)` or - /// `showDetailViewController(_:sender:)`, it may need to know when a split - /// view controller higher in the view hierarchy has changed. This - /// notification is sent when a split view controller expands or collapses. - /// The object of this notification is the view controller that caused the - /// change. - public class var showDetailTargetDidChangeNotification: NSNotification.Name { - NSNotification.Name(rawValue: "UIViewControllerShowDetailTargetDidChangeNotification") - } - - // MARK - Adding a Custom Transition or Presentation - - /// The delegate object that provides transition animator, interactive - /// controller, and custom presentation controller objects. - /// - /// When the view controller's `modalPresentationStyle` property is - /// `ModalPresentationStyle.custom`, the framework uses the object in this - /// property to facilitate transitions and presentations for the view - /// controller. The transitioning delegate object is a custom object that you - /// provide and that conforms to the `ViewControllerTransitioningDelegate` - /// protocol. Its job is to vend the animator objects used to animate this - /// view controller's view onscreen and an optional presentation controller - /// to provide any additional chrome and animations. - open weak var transitioningDelegate: ViewControllerTransitioningDelegate? - - /// Returns the active transition coordinator object. - /// - /// When a presentation or dismissal is in progress, this method returns the - /// transition coordinator object associated with that transition. If there is - /// no in-progress transition associated with the current view controller, - /// the framework checks the view controller's ancestors for a transition - /// coordinator object and returns that object if it exists. You can use this - /// object to create additional animations and synchronize them with the - /// transition animations. - /// - /// Container view controllers can override this method but in most cases - /// should not need to. If you do override this method, first call `super` to - /// see if there is an appropriate transition coordinator to return, and, if - /// there is, return it. - /// - /// For more information about the role of transition coordinators, see - /// `ViewControllerTransitionCoordinator`. - open private(set) var transitionCoordinator: ViewControllerTransitionCoordinator? - - /// Returns the view controller that responds to the action. - /// - /// This method returns the current view controller if that view controller - /// overrides the method indicated by the action parameter. If the current - /// view controller does not override that method, the framework walks up the - /// view hierarchy and returns the first view controller that does override - /// it. If no view controller handles the action, this method returns `nil`. - /// - /// A view controller can selectively respond to an action by returning an - /// appropriate value from its `canPerformAction(_:withSender:)` method. - open func targetViewController(forAction action: (Target) -> () -> Void, - sender: Any?) -> ViewController? { - fatalError("\(#function) not yet implemented") - } - - open func targetViewController(forAction action: (Target) -> (_: Any?) -> Void, - sender: Any?) -> ViewController? { - fatalError("\(#function) not yet implemented") - } - - /// The presentation controller that's managing the current view controller. - /// - /// If the view controller is managed by a presentation controller, this - /// property contains that object. This property is `nil` if the view - /// controller isn't managed by a presentation controller. - /// - /// If you've not yet presented the current view controller, accessing this - /// property creates a presentation controller based on the current value in - /// the `modalPresentationStyle` property. Always set the value of that - /// property before accessing any presentation controllers. - open private(set) var presentationController: PresentationController? - - /// The nearest popover presentation controller that is managing the current view controller. - /// - /// If the view controller or one of its ancestors is managed by a popover - /// presentation controller, this property contains that object. This property - /// is `nil` if the view controller is not managed by a popover presentation - /// controller. - /// - /// If you created the view controller but have not yet presented it, accessing - /// this property creates a popover presentation controller when the value in - /// the `modalPresentationStyle` property is `ModalPresentationStyle.popover`. - /// If the modal presentation style is a different value, this property is `nil`. -#if false - open private(set) var popoverPresentationController: PopoverPresentationController? { - get { fatalError("\(#function) not yet implemented") } - } -#endif - - /// The sheet presentation controller for the view controller. - /// - /// If `modalPresentationStyle`` is `ModalPresentationStyle.pageSheet` or - /// `ModalPresentationStyle.formSheet`, this property contains a sheet - /// presentation controller instance. Access this instance to customize or - /// adjust the sheet before or after it presents. - /// - /// If `modalPresentationStyle` has a value other than - /// `ModalPresentationStyle.pageSheet` or `ModalPresentationStyle.formSheet`, - /// the value of this property is `nil`. -#if false - open private(set) var sheetPresentationController: SheetPresentationController? { - get { fatalError("\(#function) not yet implemented") } - } -#endif - - /// The presentation controller that's managing the view controller. - /// - /// If the original presentation controller hasn't adapted, the value of this - /// property is `presentationController`. If the original presentation - /// controller has adapted to a different presentation controller, the value - /// of this property is the adaptive presentation controller. - /// - /// If the view controller hasn't presented yet, this property returns `nil`. - open private(set) var activePresentationController: PresentationController? { - get { fatalError("\(#function) not yet implemented") } - set { fatalError("\(#function) not yet implemented") } - } - - /// A boolean value that indicates whether an item that previously was focused - /// should again become focused when the item's view controller becomes - /// visible and focusable. - /// - /// When the value of this property is true, the item that was last focused - /// automatically becomes focused when its view controller becomes visible and - /// focusable. For example, if an item in the view controller is focused and a - /// second view controller is presented, the original item becomes focused - /// again when the second view controller is dismissed. The default value of - /// this property is `true`. - open var restoresFocusAfterTransition: Bool = true - - // MARK - Adapting to Environment Changes - - /// Called when a split view controller transitions to a compact-width size class. - /// - /// This method provides default behavior when you do not overwrite the - /// `splitViewController(_:collapseSecondary:onto:)` method. The primary view - /// controller associated with the split view controller is displayed. -#if false - open func collapseSecondaryViewController(_ secondaryViewController: ViewController, - for splitViewController: SplitViewController) { - } -#endif - - /// Called when a split view controller transitions to a regular-width size class. - /// - /// This method provides default behavior when you do not overwrite the - /// `splitViewController(_:separateSecondaryFrom:)` method. The previous - /// secondary view controller is returned. -#if false - open func separateSecondaryViewController(for splitViewController: SplitViewController) - -> ViewController? { - } -#endif - - // MARK - Adjusting the Interface Style - - /// The user interface style adopted by the view controller and all of its children. - /// - /// Use this property to force the view controller to always adopt a light or - /// dark interface style. The default value of this property is - /// `UserInterfaceStyle.unspecified`, which causes the view controller to - /// inherit the interface style from the system or a parent view controller. - /// If you assign a different value, the new style applies to the view - /// controller, its entire view hierarchy, and any embedded child view - /// controllers. - open var overrideUserInterfaceStyle: UserInterfaceStyle = .unspecified - - // MARK - Managing Child View Controllers in a Custom Controller - - /// An array of view controllers that are children of the current view - /// controller. - /// - /// This property does not include any presented view controllers. This - /// property is only intended to be read by an implementation of a custom - /// container view controller. - open private(set) var children: [ViewController] = [] - - /// Adds the specified view controller as a child of the current view - /// controller. - /// - /// This method creates a parent-child relationship between the current view - /// controller and the object in the childController parameter. This - /// relationship is necessary when embedding the child view controller's view - /// into the current view controller's content. If the new child view - /// controller is already the child of a container view controller, it is - /// removed from that container before being added. - /// - /// This method is only intended to be called by an implementation of a custom - /// container view controller. If you override this method, you must call - /// `super` in your implementation. - open func addChild(_ controller: ViewController) { - self.children.append(controller) - controller.parent = self - } - - /// Removes the view controller from its parent. - /// - /// This method is only intended to be called by an implementation of a custom - /// container view controller. If you override this method, you must call - /// `super` in your implementation. - open func removeFromParent() { - self.parent?.children.remove(object: self) - self.parent = nil - } - - /// Transitions between two of the view controller's child view controllers. - /// - /// This method adds the second view controller's view to the view hierarchy - /// and then performs the animations defined in your animations block. After - /// the animation completes, it removes the first view controller's view from - /// the view hierarchy. - /// - /// This method is only intended to be called by an implementation of a custom - /// container view controller. If you override this method, you must call - /// `super` in your implementation. - open func transition(from source: ViewController, - to destination: ViewController, duration: TimeInterval, - options: View.AnimationOptions = [], - animations: (() -> Void)?, - completion: ((Bool) -> Void)? = nil) { - fatalError("\(#function) not yet implemented") - } - - /// Returns a boolean value indicating whether appearance methods are - /// forwarded to child view controllers. - /// - /// This method is called to determine whether to automatically forward - /// appearance-related containment callbacks to child view controllers. - /// - /// The default implementation returns true. Subclasses of the `ViewController` - /// class that implement containment logic may override this method to control - /// how these methods are forwarded. If you override this method and return - /// `false`, you are responsible for telling the child when its views are going - /// to appear or disappear. You do this by calling the child view controller's - /// `beginAppearanceTransition(_:animated:)` and `endAppearanceTransition()` - /// methods. - open private(set) var shouldAutomaticallyForwardAppearanceMethods: Bool = true - - /// Tells a child controller its appearance is about to change. - /// - /// If you are implementing a custom container controller, use this method to - /// tell the child that its views are about to appear or disappear. Do not - /// invoke `viewWillAppear(_:)`, `viewWillDisappear(_:)`, `viewDidAppear(_:)`, - /// or `viewDidDisappear(_:)` directly. - open func beginAppearanceTransition(_ isAppearing: Bool, animated: Bool) { - fatalError("\(#function) not yet implemented") - } - - /// Tells a child controller its appearance has changed. - /// - /// If you are implementing a custom container controller, use this method to - /// tell the child that the view transition is complete. - open func endAppearanceTransition() { - fatalError("\(#function) not yet implemented") - } - - /// Changes the traits assigned to the specified child view controller. - /// - /// Usually, traits are passed unmodified from the parent view controller to - /// its child view controllers. When implementing a custom container view - /// controller, you can use this method to change the traits of any embedded - /// child view controllers to something more appropriate for your layout. - /// Making such a change alters other view controller behaviors associated - /// with that child. For example, modal presentations behave differently in a - /// horizontally compact versus horizontally regular environment. You might - /// also make such a change to force the same set of traits on the child view - /// controller regardless of the actual trait environment. - open func setOverrideTraitCollection(_ collection: TraitCollection?, - forChild childViewController: ViewController) { - fatalError("\(#function) not yet implemented") - } - - /// Retrieves the trait collection for a child view controller. - /// - /// Use this method to retrieve the trait collection for a child view - /// controller. You can then modify the trait collection for the designated - /// child view controller and set it using the - /// `setOverrideTraitCollection(_:forChild:)` method. - open func overrideTraitCollection(forChild childViewController: ViewController) - -> TraitCollection? { - fatalError("\(#function) not yet implemented") - } - - /// Raised if the view controller hierarchy is inconsistent with the view - /// hierarchy. - /// - /// When a view controller's view is added to the view hierarchy, the system - /// walks up the view hierarchy to find the first parent view that has a view - /// controller. That view controller must be the parent of the view controller - /// whose view is being added. Otherwise, this exception is raised. This - /// consistency check is also performed when a view controller is added as a - /// child by calling the `addChild(_:)` method. - /// - /// It is also allowed for a view controller that has no parent to add its - /// view to the view hierarchy. This is generally not recommended, but is - /// useful in some special cases. - public class var hierarchyInconsistencyException: NSExceptionName { - NSExceptionName(rawValue: "UIViewControllerHierarchyInconsistencyException") - } - - // MARK - Responding to Containment Events - - /// Called just before the view controller is added or removed from a - /// container view controller. - open func willMove(toParent viewController: ViewController?) { - } - - /// Called after the view controller is added or removed from a container view - /// controller. - open func didMove(toParent viewController: ViewController?) { - } - - // MARK - Getting Other Related View Controllers - - /// The view controller that presented this view controller. - /// - /// When you present a view controller modally (either explicitly or - /// implicitly) using the `present(_:animated:completion:)` method, the view - /// controller that was presented has this property set to the view controller - /// that presented it. If the view controller was not presented modally, but - /// one of its ancestors was, this property contains the view controller that - /// presented the ancestor. If neither the current view controller or any of - /// its ancestors were presented modally, the value in this property is `nil`. - open private(set) var presentingViewController: ViewController? - - /// The view controller that presented this view controller. - /// - /// When you present a view controller modally (either explicitly or - /// implicitly) using the `present(_:animated:completion:)` method, the view - /// controller that called the method has this property set to the view - /// controller that it presented. If the current view controller did not - /// present another view controller modally, the value in this property is - /// `nil`. - open private(set) var presentedViewController: ViewController? - - /// The view controller that presented this view controller. - /// - /// If the recipient is a child of a container view controller, this property - /// holds the view controller it is contained in. If the recipient has no - /// parent, the value in this property is `nil`. - /// - /// Use the `presentingViewController` property to access the presenting view - /// controller. - open private(set) var parent: ViewController? { - willSet { self.willMove(toParent: newValue) } - didSet { self.didMove(toParent: self.parent) } - } - - /// The nearest ancestor in the view controller hierarchy that is a split view controller. - /// - /// If the view controller or one of its ancestors is a child of a split view - /// controller, this property contains the owning split view controller. This - /// property is `nil` if the view controller is not embedded inside a split - /// view controller. -#if false - open private(set) var splitViewController: SplitViewController? { - get { fatalError("\(#function) not yet implemented") } - } -#endif - - /// The nearest ancestor in the view controller hierarchy that is a navigation controller. - /// - /// If the view controller or one of its ancestors is a child of a navigation - /// controller, this property contains the owning navigation controller. This - /// property is `nil` if the view controller is not embedded inside a - /// navigation controller. -#if false - open private(set) var navigationController: NavigationController? { - get { fatalError("\(#function) not yet implemented") } - } -#endif - - /// The nearest ancestor in the view controller hierarchy that is a tab bar controller. - /// - /// If the view controller or one of its ancestors is a child of a tab bar - /// controller, this property contains the owning tab bar controller. This - /// property is `nil` if the view controller is not embedded inside a tab bar - /// controller. -#if false - open private(set) var tabBarController: TabBarController? { - get { fatalError("\(#function) not yet implemented") } - } -#endif - - // MARK - Configuring a Navigation Interface - - /// The navigation item used to represent the view controller in a parent's navigation bar. - /// - /// This is a unique instance of `NavigationItem` created to represent the - /// view controller when it is pushed onto a navigation controller. The first - /// time the property is accessed, the `NavigationItem` object is created. - /// Therefore, you should not access this property if you are not using a - /// navigation controller to display the view controller. To ensure the - /// navigation item is configured, you can either override this property and - /// add code to create the bar button items when first accessed or create thei - /// items in your view controller's initialization code. - /// - /// Avoid tying the creation of bar button items in your navigation item to - /// the creation of your view controller's view. The navigation item of a view - /// controller may be retrieved independently of the view controller's view. - /// For example, when pushing two view controllers onto a navigation stack, - /// the topmost view controller becomes visible, but the other view - /// controller's navigation item may be retrieved in order to present its back - /// button. - /// - /// The default behavior is to create a navigation item that displays the view - /// controller's title. -#if false - open private(set) var navigationItem: NavigationItem { - get { fatalError("\(#function) not yet implemented") } - set { fatalError("\(#function) not yet implemented") } - } -#endif - - /// A Boolean value indicating whether the toolbar at the bottom of the screen - /// is hidden when the view controller is pushed on to a navigation controller. - /// - /// A view controller added as a child of a navigation controller can display - /// an optional toolbar at the bottom of the screen. The value of this - /// property on the topmost view controller determines whether the toolbar is - /// visible. If the value of this property is `true`, the toolbar is hidden. - /// If the value of this property is `false`, the bar is visible. - open var hidesBottomBarWhenPushed: Bool { - get { fatalError("\(#function) not yet implemented") } - set { fatalError("\(#function) not yet implemented") } - } - - /// Sets the toolbar items to be displayed along with the view controller. - /// - /// View controllers that are managed by a navigation controller can use this - /// method to specify toolbar items for the navigation controller's built-in - /// toolbar. You can set the toolbar items for your view controller before - /// your view controller is displayed or after it is already visible. - open func setToolbarItems(_ toolbarItems: [BarButtonItem]?, animated: Bool) { - fatalError("\(#function) not yet implemented") - } - - /// The toolbar items associated with the view controller. - /// - /// This property contains an array of `BarButtonItem` objects and works in - /// conjunction with a `NavigationController` object. If this view controller - /// is embedded inside a navigation controller interface, and the navigation - /// controller displays a toolbar, this property identifies the items to - /// display in that toolbar. - /// - /// You can set the value of this property explicitly or use the - /// `setToolbarItems(_:animated:)` method to animate changes to the visible - /// set of toolbar items. - open var toolbarItems: [BarButtonItem]? { - get { fatalError("\(#function) not yet implemented") } - set { fatalError("\(#function) not yet implemented") } - } - - // MARK - Configuring Tab Bar Content - - /// The tab bar item that represents the view controller when added to a tab bar controller. - /// - /// This is a unique instance of `TabBarItem` created to represent the view - /// controller when it is a child of a tab bar controller. The first time the - /// property is accessed, the `TabBarItem` is created. Therefore, you should - /// not access this property if you are not using a tab bar controller to - /// display the view controller. To ensure the tab bar item is configured, you - /// can either override this property and add code to create the bar button - /// items when first accessed or create the items in your view controller's - /// initialization code. - /// - /// The default value is a tab bar item that displays the view controller's - /// title. -#if false - open var tabBarItem: TabBarItem! { - get { fatalError("\(#function) not yet implemented") } - set { fatalError("\(#function) not yet implemented") } - } -#endif - - // MARK - Working with scrolling content - - /// Sets the scroll view that bars observe for the specified edge. - /// - /// Toolbars, navigation bars, and tab bars adjust their appearance when the - /// edge of a scroll view's content aligns with the edge of the bar. The view - /// controller identifies a scroll view to observe by analyzing the view - /// hierarchy to select a scroll view. If the view hierarchy is complex, the - /// view controller might not select the appropriate scroll view to observe. - /// Use this method to indicate a specific scroll view for the view controller - /// to observe. - /// - /// To disable the scroll edge appearance for one or more edges, override - /// `contentScrollView(for:)`. -#if false - open func setContentScrollView(_ scrollView: ScrollView?, - for edge: DirectionalRectEdge) { - } -#endif - - /// Sets the scroll view that bars observe for all edges of the view. - /// - /// Calling this convenience method is identical to calling - /// `setContentScrollView(_:for:)` and passing `all` for the edge parameter. -#if false - open func setContentScrollView(_ scrollView: ScrollView?) { - } -#endif - - /// Returns the scroll view the view controller observes for the specified edge. - /// - /// Toolbars, navigation bars, and tab bars adjust their appearance when the - /// edge of a scroll view's content aligns with the edge of the bar. If you - /// want to disable this behavior for one or more edges, override this method - /// and return nil for the appropriate edge. If you don't set a scroll view - /// with `setContentScrollView(_:for:)` or `setContentScrollView(_:)`, the - /// default implementation of this method returns nil. - /// - /// The following example disables the scroll edge view for the top edge only. - /// This example disables the appearance changes of the navigation bar at the - /// top edge, but not the toolbar at the bottom edge. - /// - /// ```swift - /// override func contentScrollView(for edge: DirectionalRectEdge) -> ScrollView? { - /// if edge == .top { return nil } - /// return super.contentScrollView(for: edge) - /// } - /// ``` -#if false - func contentScrollView(for edge: DirectionalRectEdge) -> ScrollView? { - return nil - } -#endif - - // MARK - - - override public init() { - } - - // MARK - Responder Chain - - override open var next: Responder? { - // If the view controller's view is the root view of a window, the next - // responder is the Window object. - if self.view is Window { return view } - // If the view controller is presented by another view controller, the next - // responder is the presenting view controller. - return self.presentingViewController - } -} - -// MARK: - Equatable - -extension ViewController: Equatable { - public static func ==(_ lhs: ViewController, _ rhs: ViewController) -> Bool { - return lhs === rhs - } -} - -// MARK: - Content Container - -extension ViewController: ContentContainer { - /// Notifies the container that the size of its view is about to change. - public func willTransition(to: Size, - with coodinator: ViewControllerTransitionCoordinator) { - } - - /// Notifies the container that its trait collection changed. - public func willTransition(to: TraitCollection, - with coordinator: ViewControllerTransitionCoordinator) { - } - - /// Returns the size of the specified child view controller's content. - public func size(forChildContentContainer container: ContentContainer, - withParentContainerSize parentSize: Size) -> Size { - return .zero - } - - /// Notifies an interested controller that the preferred content size of one - /// of its children changed. - public func preferredContentSizeDidChange(forChildContentContainer container: ContentContainer) { - } - - /// Notifies the container that a child view controller was resized using auto - /// layout. - public func systemLayoutFittingSizeDidChange(forChildContentContainer container: ContentContainer) { - } -} - -// MARK: - Trait Environment - -extension ViewController: TraitEnvironment { - public var traitCollection: TraitCollection { - // The first item in the chain provides the base trait collection. - var traits: TraitCollection = - self.parent?.traitCollection - ?? self.view.superview?.traitCollection - ?? (self.view as? Window)?.traitCollection - ?? TraitCollection() - - // The parent view controller may provide overrides for the controller. - if let overrides = self.parent?.overrideTraitCollection(forChild: self) { - traits = TraitCollection(traitsFrom: [traits, overrides]) - } - - // The presentation controller may further override the traits. - if let overrides = self.presentationController?.overrideTraitCollection { - traits = TraitCollection(traitsFrom: [traits, overrides]) - } - - return traits - } - - public func traitCollectionDidChange(_ previousTraitCollection: TraitCollection?) { - // extension point for derived types - } -} diff --git a/Sources/SwiftWin32/Views and Controls/Axis.swift b/Sources/SwiftWin32/Views and Controls/Axis.swift deleted file mode 100644 index 52fca03a..00000000 --- a/Sources/SwiftWin32/Views and Controls/Axis.swift +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -/// Defines a structure that specifies the layout axes. -public struct Axis: OptionSet { - public typealias RawValue = UInt - - public let rawValue: RawValue - - // MARK - Initializers - - public init(rawValue: RawValue) { - self.rawValue = rawValue - } -} - -extension Axis { - public static var both: Axis { - [.horizontal, .vertical] - } - - public static var horizontal: Axis { - Axis(rawValue: 1 << 0) - } - - public static var vertical: Axis { - Axis(rawValue: 1 << 1) - } -} diff --git a/Sources/SwiftWin32/Views and Controls/BarButtonItem.swift b/Sources/SwiftWin32/Views and Controls/BarButtonItem.swift deleted file mode 100644 index 9b2f41d4..00000000 --- a/Sources/SwiftWin32/Views and Controls/BarButtonItem.swift +++ /dev/null @@ -1,431 +0,0 @@ -// Copyright © 2021 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -extension BarButtonItem { - /// Defines system-supplied images for bar button items. - public enum SystemItem: Int { - /// The system Done button, localized. - case done - - /// The system Cancel button, localized. - case cancel - - /// The system Edit button, localized. - case edit - - /// The system Save button, localized. - case save - - /// The system plus button containing an icon of a plus sign. - case add - - /// Blank space to add between other items. The space is distributed equally - /// between the other items. Other item properties are ignored when this - /// value is set. - case flexibleSpace - - /// Blank space to add between other items. Only the `width` property is - /// used when this value is set. - case fixedSpace - - /// The system compose button. - case compose - - /// The system reply button. - case reply - - /// The system action button. - case action - - /// The system organize button. - case organize - - /// The system bookmarks button. - case bookmarks - - /// The system search button. - case search - - /// The system refresh button. - case refresh - - /// The system stop button. - case stop - - /// The system camera button. - case camera - - /// The system trash button. - case trash - - /// The system play button. - case play - - /// The system pause button. - case pause - - /// The system rewind button. - case rewind - - /// The system fast forward button. - case fastForward - - /// The system undo button. - case undo - - /// The system redo button. - case redo - - /// The system page curl button. - @available(*, unavailable) - case pageCurl - - /// The system close button. - case close - } -} - -extension BarButtonItem { - /// The system close button. - public enum Style: Int { - /// Glows when tapped. The default item style. - case plain - - /// A simple button style with a border. - @available(*, unavailable) - case bordered - - /// The style for a done button — for example, a button that completes some - /// task and returns to the previous view. - case done - } -} - -/// A specialized button for placement on a toolbar or tab bar. -/// -/// You can customize the appearance of buttons by sending the setter messages -/// to `BarButtonItemAppearance` to customize all buttons, or to a specific -/// `BarButtonItem` instance. You can use customized buttons in standard places -/// in a `NavigationItem` object (`backBarButtonItem`, `leftBarButtonItem`, -/// `rightBarButtonItem`) or a `Toolbar` instance. -/// -/// In general, you should specify a value for the normal state so that other -/// states without a custom value set can use it. Similarly, when a property is -/// depends on the bar metrics, you should specify a value of -/// `BarMetrics.default`. -open class BarButtonItem: BarItem { - // MARK - Initializing an Item - - /// Initializes a new item containing the specified system item. - public convenience init(barButtonSystemItem systemItem: BarButtonItem.SystemItem, - target: Target?, - action: ((Target) -> () -> Void)?) { - guard let target = target else { - fatalError("responder hierarchy scanning not supported") - } - let callback: ((Target) -> (AnyObject?) -> Void)? = - action == nil - ? nil - : { (target: Target) in { (_: AnyObject?) in action!(target)() } } - self.init(barButtonSystemItem: systemItem, target: target, action: callback) - } - - public convenience init(barButtonSystemItem systemItem: BarButtonItem.SystemItem, - target: Target?, - action: ((Target) -> (AnyObject?) -> Void)?) { - fatalError("\(#function) not yet implemented") - } - - /// Initializes a new item using the specified custom view. - /// - /// The bar button item created by this method does not call the action method - /// of its target in response to user interactions. Instead, the bar button - /// item expects the specified custom view to handle any user interactions and - /// provide an appropriate response. - public convenience init(customView: View) { - fatalError("\(#function) not yet implemented") - } - - /// Initializes a new item using the specified image and other properties. - public convenience init(image: Image?, - style: BarButtonItem.Style, - target: Target?, - action: ((Target) -> () -> Void)?) { - guard let target = target else { - fatalError("responder hierarchy scanning not supported") - } - let callback: ((Target) -> (AnyObject?) -> Void)? = - action == nil - ? nil - : { (target: Target) in { (_: AnyObject?) in action!(target)() } } - self.init(image: image, style: style, target: target, action: callback) - } - - public convenience init(image: Image?, - style: BarButtonItem.Style, - target: Target?, - action: ((Target) -> (AnyObject?) -> Void)?) { - fatalError("\(#function) not yet implemented") - } - - /// Initializes a new item using the specified title and other properties. - public convenience init(title: String?, - style: BarButtonItem.Style, - target: Target?, - action: ((Target) -> () -> Void)?) { - guard let target = target else { - fatalError("responder hierarchy scanning not supported") - } - let callback: ((Target) -> (AnyObject?) -> Void)? = - action == nil - ? nil - : { (target: Target) in { (_: AnyObject?) in action!(target)() } } - self.init(title: title, style: style, target: target, action: callback) - } - - public convenience init(title: String?, - style: BarButtonItem.Style, - target: Target?, - action: ((Target) -> (AnyObject?) -> Void)?) { - fatalError("\(#function) not yet implemented") - } - - /// Initializes a new item using the specified title, image, action, and - /// context menu. - /// - /// The context menu is displayed immediately when touched. - public convenience init(title: String? = nil, image: Image? = nil, - primaryAction: Action? = nil, menu: Menu? = nil) { - fatalError("\(#function) not yet implemented") - } - - /// Initializes a new item using the specified system item, action, and - /// context menu. - /// - /// The context menu is displayed immediately when touched. - public convenience init(systemItem: BarButtonItem.SystemItem, - primaryAction: Action? = nil, menu: Menu? = nil) { - fatalError("\(#function) not yet implemented") - } - - /// Initializes a new item using the specified images and other properties. - /// - /// A new item initialized to use using the specified images and other - /// properties. - public convenience init(image: Image?, - landscapeImagePhone: Image?, - style: BarButtonItem.Style, - target: Target?, - action: ((Target) -> () -> Void)?) { - guard let target = target else { - fatalError("responder hierarchy scanning not supported") - } - let callback: ((Target) -> (AnyObject?) -> Void)? = - action == nil - ? nil - : { (target: Target) in { (_: AnyObject?) in action!(target)() } } - self.init(image: image, landscapeImagePhone: landscapeImagePhone, - style: style, target: target, action: callback) - } - - public convenience init(image: Image?, - landscapeImagePhone: Image?, - style: BarButtonItem.Style, - target: Target?, - action: ((Target) -> (_: AnyObject?) -> Void)?) { - fatalError("\(#function) not yet implemented") - } - - /// Initializes the bar button item to its default state. - public override init() { - super.init() - } - - // MARK - Creating Space Items - - /// Creates a new fixed space item using the width. - open class func fixedSpace(_ width: Double) -> Self { - fatalError("\(#function) not yet implemented") - } - - /// Creates a new flexible width space item. - open class func flexibleSpace() -> Self { - fatalError("\(#function) not yet implemented") - } - - // MARK - Getting and Setting Properties - - /// The object that receives an action when the user selects the item. - /// - /// If `nil`, the action message is passed up the responder chain where it may - /// be handled by any object implementing a method corresponding to the - /// selector held by the action property. The default value is `nil`. - open weak var target: AnyObject? - - /// The selector defining the action message to send to the target object when - /// the user taps this bar button item. - /// - /// If the value of this property is `nil`, no action message is sent. The - /// default value is `nil`. - /* open var action: Selector? */ - - /// The style of the item. - /// - /// One of the constants defined in `BarButtonItem.Style`. The default value - /// is `BarButtonItem.Style.plain`. - open var style: BarButtonItem.Style = .plain - - /// The set of possible titles to display on the bar button. - open var possibleTitles: Set? - - /// The width of the item. - /// - /// If this property value is positive, the width of the combined image and - /// title are fixed. If the value is `0.0` or negative, the item sets the - /// width of the combined image and title to fit. This property is ignored if - /// the style uses radio mode. The default value is `0.0`. - open var width: Double = 0.0 - - /// A custom view representing the item. - open var customView: View? - - /// The context menu for this button. - /// - /// The context menu is displayed immediately when touched. - open var menu: Menu? - - /// The action to send to the target when the user selects the item. - /// - /// The `target` and `action` properties are ingored when `primaryAction` is - /// not `nil`. - /* @NSCopying */ open var primaryAction: Action? - - // MARK - Customizing Appearance - - /// The tint color to apply to the button item. - /// - /// All subclasses of `View` derive their behaviour for `tintColor` from the - /// base class. Although `BarButtonItem` is not a view, its `tintColor` - /// property behaves the same as that of `View`. See the discussion of - /// `tintColor` at the `View` level for more information. - open var tintColor: Color? - - /// Returns the back button background image for a specified control state and - /// bar metrics. - /// - /// This modifier applies only to navigation bar back buttons and is ignored - /// by other buttons. - open func backButtonBackgroundImage(for state: Control.State, - barMetrics: BarMetrics) -> Image? { - fatalError("\(#function) not yet implemented") - } - - /// Sets the back button background image for a specified control state and - /// bar metrics. - /// - /// This modifier applies only to navigation bar back buttons and is ignored - /// by other buttons. - /// - /// For good results, backgroundImage must be a stretchable image. - open func setBackButtonBackgroundImage(_ backgroundImage: Image?, - for state: Control.State, - barMetrics: BarMetrics) { - } - - /// Returns the back button title offset for specified bar metrics. - /// - /// This modifier applies only to navigation bar back buttons and is ignored - /// by other buttons. - open func backButtonTitlePositionAdjustment(for barMetrics: BarMetrics) - -> Offset { - fatalError("\(#function) not yet implemented") - } - - /// Sets the back button title offset for specified bar metrics. - /// - /// This modifier applies only to navigation bar back buttons and is ignored - /// by other buttons. - open func setBackButtonTitlePositionAdjustment(_ adjustment: Offset, - for barMetrics: BarMetrics) { - } - - /// Returns the back button vertical position offset for specified bar - /// metrics. - /// - /// This modifier applies only to navigation bar back buttons and is ignored - /// by other buttons. - /// - /// This offset is used to adjust the vertical centering of bordered bar - /// buttons within the bar. - open func backButtonBackgroundVerticalPositionAdjustment(for barMetrics: BarMetrics) - -> Double { - fatalError("\(#function) not yet implemented") - } - - /// Sets the background vertical position offset for specified bar metrics. - /// - /// This offset is used to adjust the vertical centering of bordered bar - /// buttons within the bar. - open func setBackgroundVerticalPositionAdjustment(_ adjustment: Double, - for barMetrics: BarMetrics) { - } - - /// Returns the background image for a specified state and bar metrics. - /// - /// The background image for the button given state and metrics. - open func backgroundImage(for state: Control.State, barMetrics: BarMetrics) - -> Image? { - fatalError("\(#function) not yet implemented") - } - - /// Sets the background image for a specified state and bar metrics. - /// - /// For good results, `backgroundImage` must be a stretchable image. - open func setBackgroundImage(_ backgroundImage: Image?, - for state: Control.State, - barMetrics: BarMetrics) { - } - - /// Returns the background image for the specified state, style, and metrics. - open func backgroundImage(for state: Control.State, - style: BarButtonItem.Style, - barMetrics: BarMetrics) -> Image? { - fatalError("\(#function) not yet implemented") - } - - /// Sets the background image for the specified state, style, and metrics. - /// - /// For good results, `backgroundImage` must be a stretchable image. - open func setBackgroundImage(_ backgroundImage: Image?, - for state: Control.State, - style: BarButtonItem.Style, - barMetrics: BarMetrics) { - } - - /// Returns the title offset for specified bar metrics. - /// - /// This offset is used to adjust the position of a title (if any) within a - /// bordered bar button. - open func titlePositionAdjustment(for barMetrics: BarMetrics) -> Offset { - fatalError("\(#function) not yet implemented") - } - - /// Sets the title offset for specified bar metrics. - /// - /// This offset is used to adjust the position of a title (if any) within a - /// bordered bar button. - open func setTitlePositionAdjustment(_ adjustment: Offset, - for barMetrics: BarMetrics) { - } - - // MARK - Getting the Shortcuts Group Information - - /// The group on the shortcuts bar that the button belongs to. - /// - /// For bar button items installed on the shortcuts bar above the keyboard, - /// this property contains the group to which the item belongs. This property - /// is configured automatically when you add the bar button item to a - /// `BarButtonItemGroup` object. If the item is not associated with a bar - /// button item group, this property is `nil`. - open private(set) weak var buttonGroup: BarButtonItemGroup? -} diff --git a/Sources/SwiftWin32/Views and Controls/BarButtonItemGroup.swift b/Sources/SwiftWin32/Views and Controls/BarButtonItemGroup.swift deleted file mode 100644 index c2ce5591..00000000 --- a/Sources/SwiftWin32/Views and Controls/BarButtonItemGroup.swift +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright © 2021 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -/// A set of bar button items on the shortcuts bar. -open class BarButtonItemGroup { - // MARK - Initializing a Bar Button Item Group - - /// Initializes and returns a bar button item group with the specified items. - public init(barButtonItems: [BarButtonItem], representativeItem: BarButtonItem?) { - self.barButtonItems = barButtonItems - self.representativeItem = representativeItem - } - - // MARK - Configuring the Group - - /// The bar button items to display on the shortcuts bar. - /// - /// You may include any number of bar button items in a group, but you should - /// keep the total number of items relatively small because of space - /// considerations. The items in a group are typically related to each other, - /// but need not be. The array must contain at least one item. - /// - /// Items can belong to only one group at a time. If you specify an item that - /// is already in a group, the framework removes the item from its previous - /// group before assigning it to the current group. - open var barButtonItems: [BarButtonItem] - - /// The item to display for a group when space is constrained. - /// - /// When space is constrained on the shortcuts bar, the framework may display - /// a group's representative item in place of its actual items. The - /// representative item is a single bar button item that is unique from the - /// other items in the group. Tapping the representative item calls its action - /// method normally. If you omit that action method, the framework responds by - /// automatically displaying the group’s items in a standard interface. - /// - /// If you do not specify a representative item for a group, the framework - /// tries to display the group's items in the shortcuts bar. If space is still - /// constrained, the framework may modify the appearance of items in the group - /// to make room for all of the items. For example, the framework may truncate - /// the titles of textual bar button items. When space is severely - /// constrained, the framework may not even display a group's representative - /// item. - open var representativeItem: BarButtonItem? - - // MARK - Determining the Group's Appearance - - /// A boolean value indicating whether the representative item is being - /// displayed in place of the group's items. - /// - /// The value of this property is `true` when the representative item is being - /// displayed in the shortcuts bar. The value is false when the individual bar - /// button items are being displayed in the shortcuts bar. - open private(set) var isDisplayingRepresentativeItem: Bool = true -} diff --git a/Sources/SwiftWin32/Views and Controls/BarItem.swift b/Sources/SwiftWin32/Views and Controls/BarItem.swift deleted file mode 100644 index 35f7ec3d..00000000 --- a/Sources/SwiftWin32/Views and Controls/BarItem.swift +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright © 2021 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import class Foundation.NSAttributedString - -/// An abstract superclass for items that you can add to a bar that appears at -/// the bottom of the screen. -open class BarItem { - // MARK - Initializing a Bar Item - - /// Initializes the bar item to its default state. - public init() { - } - - // MARK - Getting and Setting Properties - - /// The title displayed on the item. - /// - /// You should set this property before adding the item to a bar. The default - /// value is `nil`. - open var title: String? - - /// The image used to represent the item. - /// - /// This image can be used to create other images to represent this item on - /// the bar — for example, a selected and unselected image may be derived from - /// this image. You should set this property before adding the item to a bar. - /// The default value is `nil`. - open var image: Image? - - /// The image to use to represent the item in landscape orientation. - /// - /// This image can be used to create other images to represent this item on - /// the bar — for example, a selected and unselected image may be derived from - /// this image. You should set this property before adding the item to a bar. - /// The default value is `nil`. - open var landscapeImage: Image? - - /// The image to display for assistive interfaces. - /// - /// Use this property to specify a high-resolution version of the item's - /// image. When displaying an assistive interface, the framework displays this - /// image instead of the standard image. The default value of this property is - /// `nil`. - /// - /// If you do not specify an image for this property, the framework scales the - /// image that you specified in the image property. - open var largeContentSizeImage: Image? - - /// The image inset or outset for each edge. - /// - /// The default value is `zero`. - open var imageInsets: EdgeInsets = .zero - - /// The image inset or outset for each edge of the image in landscape - /// orientation. - /// - /// The default value is `zero`. - open var landscapeImageInsets: EdgeInsets = .zero - - /// The insets to apply to the bar item's large image when displaying the - /// image in an assistive UI. - /// - /// The default value of this property is `zero`. - open var largeContentSizeImageInsets: EdgeInsets = .zero - - /// A boolean value indicating whether the item is enabled. - /// - /// If `false`, the item is drawn partially dimmed to indicate it is disabled. - /// The default value is `true`. - open var isEnabled: Bool = true - - /// The receiver’s tag, an application-supplied integer that you can use to - /// identify bar item objects in your application. - /// - /// The default value is `0`. - open var tag: Int = 0 - - // MARK - Customizing Appearance - - /// Sets the title’s text attributes for a given control state. - open func setTitleTextAttributes(_ attributes: [NSAttributedString.Key:Any]?, - for state: Control.State) { - fatalError("\(#function) not yet implemnted") - } - - /// Returns the title’s text attributes for a given control state. - /// - /// The dictionary may contain key-value pairs for text attributes for the - /// font, text color, text shadow color, and text shadow offset using the keys - /// listed in NSString Additions Reference. - open func titleTextAttributes(for state: Control.State) - -> [NSAttributedString.Key:Any]? { - fatalError("\(#function) not yet implemnted") - } -} diff --git a/Sources/SwiftWin32/Views and Controls/BarPositioning.swift b/Sources/SwiftWin32/Views and Controls/BarPositioning.swift deleted file mode 100644 index 451fc933..00000000 --- a/Sources/SwiftWin32/Views and Controls/BarPositioning.swift +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright © 2021 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -/// Constants to specify metrics to use for appearance. -public enum BarMetrics: Int { - /// Specifies default metrics for the device. - case `default` - - /// Specifies metrics when using the phone idiom. - case compact - - /// Specifies default metrics for the device for bars with the - /// prompt property, such as `NavigationBar` and `SearchBar`. - case defaultPrompt - - /// Specifies metrics for bars with the prompt property when using - /// the phone idiom, such as `NavigationBar` and `SearchBar`. - case compactPrompt -} - -extension BarMetrics { - /// Specifies metrics for landscape orientation using the phone idiom. - @available(*, unavailable) - public static var landscapePhone: BarMetrics { - return .compact - } - - /// Specifies metrics for landscape orientation using the phone idiom - /// for bars with the prompt property, such as `NavigationBar` and - /// `SearchBar`. - @available(*, unavailable) - public static var landscapePhonePrompt: BarMetrics { - return .compactPrompt - } -} diff --git a/Sources/SwiftWin32/Views and Controls/Button.swift b/Sources/SwiftWin32/Views and Controls/Button.swift deleted file mode 100644 index 5df87dc0..00000000 --- a/Sources/SwiftWin32/Views and Controls/Button.swift +++ /dev/null @@ -1,94 +0,0 @@ -// Copyright © 2019 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import WinSDK - -#if swift(>=5.7) -import CoreGraphics -#endif - -private let SwiftButtonProc: SUBCLASSPROC = { (hWnd, uMsg, wParam, lParam, uIdSubclass, dwRefData) in - let button: Button? = unsafeBitCast(dwRefData, to: AnyObject.self) as? Button - - switch uMsg { - case UINT(WM_LBUTTONUP): - button?.sendActions(for: .primaryActionTriggered) - default: - break - } - - return DefSubclassProc(hWnd, uMsg, wParam, lParam) -} - -extension Button { - /// Specifies the style of a button. - public enum ButtonType: Int { - /// No button style. - case custom - - /// A system style button, such as those shown in navigation bars and - /// toolbars. - case system - - /// A detail disclosure button. - case detailDisclosure - - /// An information button that has a light background. - case infoLight - - /// An information button that has a dark background. - case infoDark - - /// A contact add button. - case contactAdd - - /// A standard system button without a blurred background view. - case plain - - /// A close button to dismiss panels and views. - case close - } -} - -/// A control that executes your custom code in response to user interactions. -public class Button: Control { - private static let `class`: WindowClass = WindowClass(named: WC_BUTTON) - - // MSDN: - // A button sends the `BN_DISABLE`, `BN_PUSHED`, `BN_KILLFOCUS`, `BN_PAINT`, - // `BN_SETFOCUS`, and `BN_UNPUSHED` notification codes only if it has the - // `BS_NOFITY` style. - private static let style: WindowStyle = - (base: WS_TABSTOP | DWORD(BS_MULTILINE | BS_NOTIFY | BS_PUSHBUTTON), - extended: 0) - - // MARK - Creating Buttons - - /// Creates a new button with the specified frame. - public init(frame: Rect) { - super.init(frame: frame, class: Button.class, style: Button.style) - - _ = SetWindowSubclass(hWnd, SwiftButtonProc, UINT_PTR(1), - unsafeBitCast(self as AnyObject, to: DWORD_PTR.self)) - } - - /// Creates a new button with the specified frame, registers the primary - /// action event, and sets the title and image to the action's title and - /// image. - public convenience init(frame: Rect, primaryAction: Action?) { - self.init(frame: frame) - if let action = primaryAction { - self.setTitle(action.title, forState: .normal) - self.addAction(action, for: .primaryActionTriggered) - } - } - - // MARK - Configuring the Button Title - - /// Sets the title to use for the specified state. - public func setTitle(_ title: String?, forState state: Control.State) { - // FIXME(compnerd) handle title setting for different states - assert(state == .normal, "state handling not yet implemented") - SetWindowTextW(hWnd, title?.wide) - } -} diff --git a/Sources/SwiftWin32/Views and Controls/Control.swift b/Sources/SwiftWin32/Views and Controls/Control.swift deleted file mode 100644 index f893ab3e..00000000 --- a/Sources/SwiftWin32/Views and Controls/Control.swift +++ /dev/null @@ -1,310 +0,0 @@ -// Copyright © 2019 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -private protocol ControlEventCallable { - func callAsFunction(sender: Control, event: Control.Event) -} - -private struct ControlEventCallback: ControlEventCallable { - private unowned(safe) let instance: Target - private let method: (Target) -> (_: Source, _: Control.Event) -> Void - - public init(binding: @escaping (Target) -> (_: Source, _: Control.Event) -> Void, - on: Target) { - self.instance = on - self.method = binding - } - - public init(binding: @escaping (Target) -> (_: Source) -> Void, on: Target) { - self.instance = on - self.method = { (target: Target) in { (sender: Source, _: Control.Event) in - binding(target)(sender) - } - } - } - - public init(binding: @escaping (Target) -> () -> Void, on: Target) { - self.instance = on - self.method = { (target: Target) in { (_: Source, _: Control.Event) in - binding(target)() - } - } - } - - public func callAsFunction(sender: Control, event: Control.Event) { - self.method(instance)(sender as! Source, event) - } -} - -extension ControlEventCallback where Target: Action { - fileprivate init(invoking action: Target) { - self.instance = action - self.method = { (_: Target) in { (sender: Source, _: Control.Event) in - action.sender = sender - defer { action.sender = nil } - action.handler(action) - } - } - } -} - -@inline(__always) -private var kTriggers: [Control.Event] { - Control.Event.touchEvents + Control.Event.semanticEvents + Control.Event.editingEvents -} - -/// The base class for controls, which are visual elements that convey a -/// specific action or intention in response to user interactions. -public class Control: View { - private var actions: [Control.Event:[ControlEventCallable]] = - Dictionary(minimumCapacity: 16) - - // MARK - Accessing the Control's Targets and Actions - - @inline(__always) - private func addAction(_ callable: ControlEventCallable, - for controlEvents: Control.Event) { - kTriggers.filter { $0.rawValue & controlEvents.rawValue == $0.rawValue } - .forEach { self.actions[$0, default: []].append(callable) } - } - - internal func addAction(_ action: Action, for controlEvents: Control.Event) { - kTriggers.filter { $0.rawValue & controlEvents.rawValue == $0.rawValue } - .forEach { self.actions[$0, default: []].append(ControlEventCallback(invoking: action)) } - } - - /// Associates a target object and action method with the control. - public func addTarget(_ target: Target, - action: @escaping (Target) -> () -> Void, - for controlEvents: Control.Event) { - self.addAction(ControlEventCallback(binding: action, on: target), - for: controlEvents) - } - - /// Associates a target object and action method with the control. - public func addTarget(_ target: Target, - action: @escaping (Target) -> (_: Source) -> Void, - for controlEvents: Control.Event) { - self.addAction(ControlEventCallback(binding: action, on: target), - for: controlEvents) - } - - /// Returns the events for which the control has associated actions. - public private(set) var allControlEvents: Control.Event = - Control.Event(rawValue: 0) - - /// Associates a target object and action method with the control. - public func addTarget(_ target: Target, - action: @escaping (Target) -> (_: Source, _: Control.Event) -> Void, - for controlEvents: Control.Event) { - self.addAction(ControlEventCallback(binding: action, on: target), - for: controlEvents) - } - - // MARK - Triggering Actions - - /// Calls the action methods associated with the specified events. - func sendActions(for controlEvents: Control.Event) { - kTriggers.filter { $0.rawValue & controlEvents.rawValue == $0.rawValue } - .forEach { self.actions[$0]?.forEach { $0(sender: self, event: controlEvents) } } - } -} - -public extension Control { - /// The state of the control, specified as a bit mask value. - struct State: OptionSet { - public let rawValue: Int - - public init(rawValue: Int) { - self.rawValue = rawValue - } - } -} - -public extension Control.State { - /// The normal, or default state of a control—that is, enabled but neither - /// selected nor highlighted. - static var normal: Control.State { - Control.State(rawValue: 1 << 0) - } - - /// Highlighted state of a control. - static var highlighted: Control.State { - Control.State(rawValue: 1 << 1) - } - - /// Disabled state of a control. - static var disabled: Control.State { - Control.State(rawValue: 1 << 2) - } - - /// Selected state of a control. - static var selected: Control.State { - Control.State(rawValue: 1 << 3) - } - - /// Focused state of a control. - static var focused: Control.State { - Control.State(rawValue: 1 << 4) - } - - /// Additional control-state flags available for application use. - static var application: Control.State { - Control.State(rawValue: 1 << 5) - } - - /// Control-state flags reserved for internal framework use. - static var reserved: Control.State { - Control.State(rawValue: 1 << 6) - } -} - -extension Control { - /// Constants describing the types of events possible for controls. - public struct Event: Equatable, Hashable, RawRepresentable { - public typealias RawValue = Int - - public let rawValue: RawValue - - public init(rawValue: RawValue) { - self.rawValue = rawValue - } - } -} - -extension Control.Event { - /// A touch-down event in the control. - public static var touchDown: Control.Event { - Control.Event(rawValue: 1 << 0) - } - - /// A repeated touch-down event in the control; for this event the value of - /// the UITouch tapCount method is greater than one. - public static var touchDownRepeat: Control.Event { - Control.Event(rawValue: 1 << 1) - } - - /// An event where a finger is dragged inside the bounds of the control. - public static var touchDragInside: Control.Event { - Control.Event(rawValue: 1 << 2) - } - - /// An event where a finger is dragged just outside the bounds of the control. - public static var touchDragOutside: Control.Event { - Control.Event(rawValue: 1 << 3) - } - - /// An event where a finger is dragged into the bounds of the control. - public static var touchDragEnter: Control.Event { - Control.Event(rawValue: 1 << 4) - } - - /// An event where a finger is dragged from within a control to outside its - /// bounds. - public static var touchDragExit: Control.Event { - Control.Event(rawValue: 1 << 5) - } - - /// A touch-up event in the control where the finger is inside the bounds of - /// the control. - public static var touchUpInside: Control.Event { - Control.Event(rawValue: 1 << 6) - } - - /// A touch-up event in the control where the finger is outside the bounds of - /// the control. - public static var touchUpOutside: Control.Event { - Control.Event(rawValue: 1 << 7) - } - - /// A system event canceling the current touches for the control. - public static var touchCancel: Control.Event { - Control.Event(rawValue: 1 << 8) - } - - /// A touch dragging or otherwise manipulating a control, causing it to emit - /// a series of different values. - public static var valueChanged: Control.Event { - Control.Event(rawValue: 1 << 12) - } - - /// A menu action has triggered prior to the menu being presented. - public static var menuActionTriggered: Control.Event { - Control.Event(rawValue: 0) - } - - /// A semantic action triggered by buttons. - public static var primaryActionTriggered: Control.Event { - Control.Event(rawValue: 1 << 13) - } - - /// A touch initiating an editing session in a `TextField` object by entering - /// its bounds. - public static var editingDidBegin: Control.Event { - Control.Event(rawValue: 1 << 16) - } - - /// A touch making an editing change in a `TextField` object. - public static var editingChanged: Control.Event { - Control.Event(rawValue: 1 << 17) - } - - /// A touch ending an editing session in a `TextField` object by leaving its - /// bounds. - public static var editingDidEnd: Control.Event { - Control.Event(rawValue: 1 << 18) - } - - /// A touch ending an editing session in a `TextField` object. - public static var editingDidEndOnExit: Control.Event { - Control.Event(rawValue: 1 << 19) - } - - /// All touch events. - public static var allTouchEvents: Control.Event { - Control.Event(rawValue: 0x00000fff) - } - - /// All editing touches for `TextField` objects. - public static var allEditingEvents: Control.Event { - Control.Event(rawValue: 0x000f0000) - } - - /// A range of control-event values available for application use. - public static var applicationReserved: Control.Event { - Control.Event(rawValue: 0x0f000000) - } - - /// A range of control-event values reserved for internal framework use. - public static var systemReserved: Control.Event { - Control.Event(rawValue: 0xf0000000) - } - - /// All events, including system events. - public static var allEvents: Control.Event { - Control.Event(rawValue: 0xffffffff) - } -} - -extension Control.Event { - fileprivate static var touchEvents: [Control.Event] { - return [ - .touchDown, .touchDownRepeat, - .touchDragInside, .touchDragOutside, .touchDragEnter, .touchDragExit, - .touchUpInside, .touchUpOutside, - .touchCancel - ] - } - - fileprivate static var semanticEvents: [Control.Event] { - return [ - .valueChanged, /* .menuActionTriggered, */ .primaryActionTriggered - ] - } - - fileprivate static var editingEvents: [Control.Event] { - return [ - .editingDidBegin, .editingChanged, .editingDidEnd, .editingDidEndOnExit - ] - } -} diff --git a/Sources/SwiftWin32/Views and Controls/DatePicker.swift b/Sources/SwiftWin32/Views and Controls/DatePicker.swift deleted file mode 100644 index aa0d1da3..00000000 --- a/Sources/SwiftWin32/Views and Controls/DatePicker.swift +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import WinSDK - -import struct Foundation.Date - -#if swift(>=5.7) -import CoreGraphics -#endif - -private let SwiftDatePickerProc: SUBCLASSPROC = { (hWnd, uMsg, wParam, lParam, uIdSubclass, dwRefData) in - let datepicker: DatePicker? = - unsafeBitCast(dwRefData, to: AnyObject.self) as? DatePicker - return DefSubclassProc(hWnd, uMsg, wParam, lParam) -} - -public enum DatePickerStyle: Int { -case automatic -case wheels -case compact -case inline -} - -public class DatePicker: Control { - private static let `class`: WindowClass = - WindowClass(named: DATETIMEPICK_CLASS) - private static let style: WindowStyle = - (base: WS_POPUP | WS_TABSTOP, extended: 0) - - // MARK - Managing the Date and Calendar - - /// The date displayed by the date picker. - public var date: Date { - get { - var stDateTime: SYSTEMTIME = SYSTEMTIME() - // FIXME(compnerd) ensure that GDT_VALID is returned - _ = withUnsafeMutablePointer(to: &stDateTime) { - SendMessageW(self.hWnd, UINT(DTM_GETSYSTEMTIME), - WPARAM(0), LPARAM(UInt(bitPattern: $0))) - } - - let ftDateTime: FILETIME = FILETIME(stDateTime) - return Date(timeIntervalSince1970: ftDateTime.timeIntervalSince1970) - } - set { self.setDate(newValue, animated: false) } - } - - /// Sets the date to display in the date picker, with an option to animate the - /// setting. - public func setDate(_ date: Date, animated: Bool) { - assert(!animated, "not yet implemented") - - let ftSystemTime: FILETIME = - FILETIME(timeIntervalSince1970: date.timeIntervalSince1970) - let stSystemTime: SYSTEMTIME = SYSTEMTIME(ftSystemTime) - - _ = withUnsafePointer(to: stSystemTime) { - SendMessageW(self.hWnd, UINT(DTM_SETSYSTEMTIME), - WPARAM(GDT_VALID), LPARAM(UInt(bitPattern: $0))) - } - } - - // MARK - Configuring the Date Picker Style - - public private(set) var datePickerStyle: DatePickerStyle = .inline - public private(set) var preferredDatePickerStyle: DatePickerStyle = .automatic { - didSet { fatalError("not yet implemented") } - } - - public init(frame: Rect) { - super.init(frame: frame, class: DatePicker.class, style: DatePicker.style) - SetWindowSubclass(hWnd, SwiftDatePickerProc, UINT_PTR(1), - unsafeBitCast(self as AnyObject, to: DWORD_PTR.self)) - } -} diff --git a/Sources/SwiftWin32/Views and Controls/DirectionalEdgeInsets.swift b/Sources/SwiftWin32/Views and Controls/DirectionalEdgeInsets.swift deleted file mode 100644 index ad3be67b..00000000 --- a/Sources/SwiftWin32/Views and Controls/DirectionalEdgeInsets.swift +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -/// Edge insets that take language direction into account. -public struct DirectionalEdgeInsets { - // MARK - Creating Directional Edge Insets - - /// Initializes the edge inset struct to default values. - public init() { - self.bottom = 0.0 - self.leading = 0.0 - self.top = 0.0 - self.trailing = 0.0 - } - - init(top: Double, leading: Double, bottom: Double, trailing: Double) { - self.bottom = bottom - self.leading = leading - self.top = top - self.trailing = trailing - } - - // MARK - Getting the Edge Values - - /// The bottom edge inset value. - public var bottom: Double - - /// The leading edge inset value. - public var leading: Double - - /// The top edge inset value. - public var top: Double - - /// The trailing edge inset value. - public var trailing: Double - - // MARK - Converting To and From a String - - /// Returns a string formatted to contain the data from a directional edge - /// insets structure. - public static func string(for insets: DirectionalEdgeInsets) -> String { - return "{\(insets.bottom),\(insets.leading),\(insets.top),\(insets.trailing)}" - } - - /// Returns a directional edge insets structure based on the data in the - /// specified string. - public static func directionalEdgeInsets(for: String) - -> DirectionalEdgeInsets { - fatalError("\(#function) not yet implemented") - } - - // MARK - Getting the Empty Edge Insets - - /// A directional edge insets struct whose top, leading, bottom, and trailing - /// fields are all set to 0. - public static var zero: DirectionalEdgeInsets { - DirectionalEdgeInsets(top: 0.0, leading: 0.0, bottom: 0.0, trailing: 0.0) - } -} diff --git a/Sources/SwiftWin32/Views and Controls/DirectionalRectEdge.swift b/Sources/SwiftWin32/Views and Controls/DirectionalRectEdge.swift deleted file mode 100644 index c1cabe3f..00000000 --- a/Sources/SwiftWin32/Views and Controls/DirectionalRectEdge.swift +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -/// Constants that specify an edge or a set of edges, taking the user interface -/// layout direction into account. -public struct DirectionalRectEdge: OptionSet { - public let rawValue: UInt - - public init(rawValue: UInt) { - self.rawValue = rawValue - } -} - -extension DirectionalRectEdge { - /// No specified edge. - public static var none: DirectionalRectEdge { - DirectionalRectEdge(rawValue: 0 << 0) - } - - /// The top edge. - public static var top: DirectionalRectEdge { - DirectionalRectEdge(rawValue: 1 << 0) - } - - /// The leading edge. - public static var leading: DirectionalRectEdge { - DirectionalRectEdge(rawValue: 1 << 1) - } - - /// The bottom edge. - public static var bottom: DirectionalRectEdge { - DirectionalRectEdge(rawValue: 1 << 2) - } - - /// The trailing edge. - public static var trailing: DirectionalRectEdge { - DirectionalRectEdge(rawValue: 1 << 3) - } - - /// All edges. - public static var all: DirectionalRectEdge { - [.top, .leading, .bottom, .trailing] - } -} diff --git a/Sources/SwiftWin32/Views and Controls/EdgeInsets.swift b/Sources/SwiftWin32/Views and Controls/EdgeInsets.swift deleted file mode 100644 index 32b3df95..00000000 --- a/Sources/SwiftWin32/Views and Controls/EdgeInsets.swift +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright © 2019 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -public class EdgeInsets { - public static let zero: EdgeInsets = EdgeInsets() - - public let bottom: Double - public let left: Double - public let right: Double - public let top: Double - - public init() { - self.bottom = 0.0 - self.left = 0.0 - self.right = 0.0 - self.top = 0.0 - } - - public init(top: Double, left: Double, bottom: Double, right: Double) { - self.bottom = bottom - self.left = left - self.right = right - self.top = top - } -} - -extension EdgeInsets: Equatable { - public static func == (_ lhs: EdgeInsets, _ rhs: EdgeInsets) -> Bool { - return lhs.bottom == rhs.bottom && - lhs.left == rhs.left && - lhs.right == rhs.right && - lhs.top == rhs.top - } -} diff --git a/Sources/SwiftWin32/Views and Controls/ImageView.swift b/Sources/SwiftWin32/Views and Controls/ImageView.swift deleted file mode 100644 index 2bc1c999..00000000 --- a/Sources/SwiftWin32/Views and Controls/ImageView.swift +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import WinSDK -import SwiftCOM - -#if swift(>=5.7) -import CoreGraphics -#endif - -extension BitmapHandle { - internal convenience init?(from pBitmap: SwiftCOM.IWICBitmapSource?, - hWnd: HWND? = nil) { - guard let pBitmap = pBitmap, - let size: (UINT, UINT) = try? pBitmap.GetSize() else { - return nil - } - - var bmiBitmap: BITMAPINFO = BITMAPINFO() - bmiBitmap.bmiHeader.biSize = DWORD(MemoryLayout.size) - bmiBitmap.bmiHeader.biWidth = LONG(size.0) - bmiBitmap.bmiHeader.biHeight = -LONG(size.1) - bmiBitmap.bmiHeader.biPlanes = 1 - bmiBitmap.bmiHeader.biBitCount = 32 - bmiBitmap.bmiHeader.biCompression = DWORD(BI_RGB) - - let hDC: DeviceContextHandle = DeviceContextHandle(owning: GetDC(hWnd)) - - var pvImageBits: UnsafeMutableRawPointer? - guard let DIB = CreateDIBSection(hDC.value, &bmiBitmap, UINT(DIB_RGB_COLORS), - &pvImageBits, nil, 0) else { return nil } - self.init(owning: DIB) - - let nStride: Int = (((Int(size.0) * 32) + 31) & ~31) >> 3 - let nImage: Int = nStride * Int(size.1) - - let pBuffer: UnsafeMutablePointer? = - pvImageBits?.bindMemory(to: BYTE.self, capacity: nImage) - let pbBuffer: UnsafeMutableBufferPointer = - UnsafeMutableBufferPointer(start: pBuffer, count: nImage) - - try? pBitmap.CopyPixels(nil, UINT(nStride), pbBuffer) - } -} - -/// An object that displays a single image or a sequence of animated images in -/// your interface. -public class ImageView: View { - private static let `class`: WindowClass = WindowClass(named: WC_STATIC) - private static let style: WindowStyle = - (base: WS_POPUP | DWORD(SS_BITMAP), extended: 0) - - private var hBitmap: BitmapHandle? - - // MARK - Creating an Image View - - /// Returns an image view initialized with the specified image. - public init(image: Image?) { - self.image = image - - super.init(frame: Rect(origin: .zero, size: self.image?.size ?? .zero), - class: ImageView.class, style: ImageView.style) - - self.hBitmap = BitmapHandle(from: self.image?.bitmap, hWnd: self.hWnd) - _ = SendMessageW(self.hWnd, UINT(STM_SETIMAGE), WPARAM(IMAGE_BITMAP), - unsafeBitCast(self.hBitmap?.value, to: LPARAM.self)) - } - - /// Returns an image view initialized with the specified regular and - /// highlighted images. - public init(image: Image?, highlightedImage: Image?) { - self.image = image - self.highlightedImage = highlightedImage - - super.init(frame: Rect(origin: .zero, size: self.image?.size ?? .zero), - class: ImageView.class, style: ImageView.style) - - self.hBitmap = BitmapHandle(from: self.image?.bitmap, hWnd: self.hWnd) - _ = SendMessageW(self.hWnd, UINT(STM_SETIMAGE), WPARAM(IMAGE_BITMAP), - unsafeBitCast(self.hBitmap?.value, to: LPARAM.self)) - - self.isUserInteractionEnabled = false - } - - // MARK - Accessing the Displayed Images - - /// The image displayed in the image view. - public var image: Image? - - /// The highlighted image displayed in the image view. - public var highlightedImage: Image? - - // ContentSizeCategoryImageAdjusting - public var adjustsImageSizeForAccessibilityContentSizeCategory = false -} - -extension ImageView: ContentSizeCategoryImageAdjusting { -} diff --git a/Sources/SwiftWin32/Views and Controls/Label.swift b/Sources/SwiftWin32/Views and Controls/Label.swift deleted file mode 100644 index 1382aa1c..00000000 --- a/Sources/SwiftWin32/Views and Controls/Label.swift +++ /dev/null @@ -1,152 +0,0 @@ -// Copyright © 2019 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import WinSDK - -#if swift(>=5.7) -import CoreGraphics -#endif - -private let SwiftLabelProc: SUBCLASSPROC = { (hWnd, uMsg, wParam, lParam, uIdSubclass, dwRefData) in - let label: Label? = unsafeBitCast(dwRefData, to: AnyObject.self) as? Label - - switch uMsg { - case UINT(WM_LBUTTONUP): - label?.sendActions(for: .primaryActionTriggered) - default: - break - } - - return DefSubclassProc(hWnd, uMsg, wParam, lParam) -} - -public class Label: Control { - private static let `class`: WindowClass = - WindowClass(hInst: GetModuleHandleW(nil), name: "Swift.Label") - private static let style: WindowStyle = (base: WS_TABSTOP, extended: 0) - - private var hWnd_: HWND? - - public var text: String? { - get { - let szLength: Int32 = GetWindowTextLengthW(self.hWnd_) - guard szLength > 0 else { return nil } - - let buffer: [WCHAR] = Array(unsafeUninitializedCapacity: Int(szLength) + 1) { - $1 = Int(GetWindowTextW(self.hWnd_, $0.baseAddress!, CInt($0.count))) + 1 - } - return String(decodingCString: buffer, as: UTF16.self) - } - set(value) { - _ = SetWindowTextW(self.hWnd_, value?.wide) - } - } - - public override var font: Font! { - didSet { - SendMessageW(self.hWnd_, UINT(WM_SETFONT), - unsafeBitCast(self.font?.hFont.value, to: WPARAM.self), - LPARAM(1)) - } - } - - public var textAlignment: TextAlignment { - get { - switch GWL_STYLE & SS_TYPEMASK { - case SS_CENTER: - return .center - case SS_RIGHT: - return .right - case SS_LEFTNOWORDWRAP, SS_LEFT: - return .left - default: - fatalError("unknown alignment for WC_STATIC") - } - } - - set { - var lAlignment = GWL_STYLE & ~SS_TYPEMASK - switch newValue { - case .left: lAlignment |= SS_LEFTNOWORDWRAP - case .right: lAlignment |= SS_RIGHT - case .center: lAlignment |= SS_CENTER - case .justified, .natural: - log.error("TextAlignment.\(newValue) is not supported") - } - GWL_STYLE = lAlignment - if !SetWindowPos(self.hWnd_, nil, 0, 0, 0, 0, - UINT(SWP_NOACTIVATE | SWP_NOCOPYBITS | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_DRAWFRAME)) { - log.warning("SetWindowPos: \(Error(win32: GetLastError()))") - } - } - } - - public override var frame: Rect { - didSet { - let frame = self.frame.scaled(for: GetDpiForWindow(self.hWnd), - style: Label.style) - _ = SetWindowPos(self.hWnd_, nil, - 0, 0, CInt(frame.size.width), CInt(frame.size.height), - UINT(SWP_NOZORDER | SWP_FRAMECHANGED)) - } - } - - public init(frame: Rect) { - super.init(frame: frame, class: Label.class, style: Label.style) - _ = SetWindowSubclass(hWnd, SwiftLabelProc, UINT_PTR(1), - unsafeBitCast(self as AnyObject, to: DWORD_PTR.self)) - - let size = self.frame.scaled(for: GetDpiForWindow(self.hWnd), - style: Label.style).size - self.hWnd_ = CreateWindowExW(0, WC_STATIC.wide, nil, DWORD(WS_CHILD), - 0, 0, CInt(size.width), CInt(size.height), - self.hWnd, nil, GetModuleHandleW(nil), nil)! - // Perform the font setting in `defer` which ensures that the property - // observer is triggered. - defer { self.font = Font.systemFont(ofSize: Font.systemFontSize) } - - self.isUserInteractionEnabled = false - } - - // MARK - - - deinit { - _ = DestroyWindow(self.hWnd_) - } - - // MARK - View Overrides - - override public func sizeThatFits(_ size: Size) -> Size { - let hDC: DeviceContextHandle = - DeviceContextHandle(owning: GetDC(self.hWnd_)) - _ = SelectObject(hDC.value, self.font.hFont.value) - - return withExtendedLifetime(hDC) { - var sz: SIZE = SIZE() - if !GetTextExtentPoint32W(hDC.value, self.text?.wide ?? nil, - CInt(self.text?.wide.count ?? 1) - 1, &sz) { - log.warning("GetTextExtentPoint32W: \(Error(win32: GetLastError()))") - return size - } - // TODO(compnerd) handle padding and margins - return Size(width: sz.cx, height: sz.cy) - } - } - - // MARK - Label(ContentSizeCategoryAdjusting) - - public var adjustsFontForContentSizeCategory = false - - // MARK - TraitEnvironment Overrides - - override public func traitCollectionDidChange(_ previousTraitCollection: TraitCollection?) { - super.traitCollectionDidChange(previousTraitCollection) - guard self.adjustsFontForContentSizeCategory else { return } - self.font = - FontMetrics.default.scaledFont(for: self.font, - compatibleWith: traitCollection) - } -} - -extension Label: ContentSizeCategoryAdjusting { -} diff --git a/Sources/SwiftWin32/Views and Controls/Offset.swift b/Sources/SwiftWin32/Views and Controls/Offset.swift deleted file mode 100644 index 1a27c087..00000000 --- a/Sources/SwiftWin32/Views and Controls/Offset.swift +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright © 2021 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import class Foundation.Scanner - -/// A structure that specifies an amount to offset a position. -public struct Offset { - // MARK - Initializing Offsets - - public init() { - self = .zero - } - - public init(horizontal: Double, vertical: Double) { - self.horizontal = horizontal - self.vertical = vertical - } - - // MARK - Getting the Offset Values - - public private(set) var horizontal: Double - - public private(set) var vertical: Double -} - -extension Offset: Equatable { - public static func ==(_ lhs: Offset, _ rhs: Offset) -> Bool { - return lhs.horizontal == rhs.horizontal && lhs.vertical == rhs.vertical - } -} -extension Offset { - /// Returns a string formatted to contain the data from an offset structure. - public static func string(for offset: Offset) -> String { - return String(format: "{%.17g, %.17g}", offset.horizontal, offset.vertical) - } - - /// Returns an `Offset` structure corresponding to the data in a given string. - /// - /// In general, you should use this function only to convert strings that were - // previously created using the `string(for:)` function. - public static func offset(for string: String) -> Offset { - let scanner: Scanner = Scanner(string: string) - guard scanner.scanCharacter() == "{", - let horizontal = scanner.scanDouble(), - scanner.scanCharacter() == ",", - let vertical = scanner.scanDouble(), - scanner.scanCharacter() == "}" else { - return .zero - } - return Offset(horizontal: horizontal, vertical: vertical) - } -} - -extension Offset { - /// A `Offset` struct whose horizontal and vertical fields are set to the - /// value 0. - public static var zero: Offset { - Offset(horizontal: 0.0, vertical: 0.0) - } -} diff --git a/Sources/SwiftWin32/Views and Controls/PickerView.swift b/Sources/SwiftWin32/Views and Controls/PickerView.swift deleted file mode 100644 index 9279dcec..00000000 --- a/Sources/SwiftWin32/Views and Controls/PickerView.swift +++ /dev/null @@ -1,451 +0,0 @@ -// Copyright © 2021 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import WinSDK - -import struct Foundation.IndexPath -import class Foundation.NSAttributedString - -#if swift(>=5.7) -import CoreGraphics -#endif - -// Notification Proxy - -// When the Window is created, the initial parent is cached. This cache cannot -// be updated. Instead, we always parent any picker view control to the -// `Swift.PickerView.Proxy` which is process-wide. All notifications -// about the control events will be dispatched by the proxy. - -private let SwiftPickerViewProxyWindowProc: WNDPROC = { (hWnd, uMsg, wParam, lParam) in - switch uMsg { - case UINT(WM_DRAWITEM): - let lpDrawItem: UnsafeMutablePointer = - UnsafeMutablePointer(bitPattern: UInt(lParam))! - - // No selected item. - if Int32(bitPattern: UInt32(lpDrawItem.pointee.itemID)) == -1 { break } - - switch lpDrawItem.pointee.itemAction { - case UINT(ODA_SELECT): - _ = DrawFocusRect(lpDrawItem.pointee.hDC, &lpDrawItem.pointee.rcItem) - if lpDrawItem.pointee.itemState & DWORD(ODS_SELECTED) == DWORD(ODS_SELECTED) { - // If the item is selected, we have drawn the focus rectangle and the - // operation is complete. - return LRESULT(1) - } - - case UINT(ODA_FOCUS): - break - - case UINT(ODA_DRAWENTIRE): - if let view = unsafeBitCast(lpDrawItem.pointee.itemData, - to: AnyObject.self) as? View { - let rctRect: RECT = lpDrawItem.pointee.rcItem - _ = SetWindowPos(view.hWnd, nil, rctRect.left, rctRect.top, 0, 0, - UINT(SWP_NOSIZE)) - // Setting `isHidden` is necessary for Views generated after initial - // call to `Window.makeKeyAndVisible()` - if IsWindowVisible(GetParent(view.hWnd)) && !IsWindowVisible(view.hWnd) { - view.isHidden = false - } - return DefWindowProcW(view.hWnd, UINT(WM_PAINT), 0, 0) - } - - default: - fatalError("unhandled message: \(lpDrawItem.pointee.itemAction)") - } - - case UINT(WM_DELETEITEM): - let lpDeleteItem: UnsafeMutablePointer = - UnsafeMutablePointer(bitPattern: UInt(lParam))! - - if let view = unsafeBitCast(lpDeleteItem.pointee.itemData, - to: AnyObject.self) as? View { - view.removeFromSuperview() - } - - return LRESULT(1) - - case UINT(WM_COMMAND): - if HIWORD(wParam) == CBN_SELENDOK { - let hWnd: HWND = HWND(bitPattern: UInt(lParam))! - - // Query the ComboxBox info, which provides the hWnd for the ListView - // which serves as the rightful parent for the view. - // FIXME(compnerd) should we cache the value? It is unlikely to change. - var cbiInfo: COMBOBOXINFO = COMBOBOXINFO() - cbiInfo.cbSize = DWORD(MemoryLayout.size) - _ = withUnsafeMutablePointer(to: &cbiInfo) { - SendMessageW(hWnd, UINT(CB_GETCOMBOBOXINFO), 0, - LPARAM(Int(bitPattern: $0))) - } - - _ = SendMessageW(cbiInfo.hwndItem, UINT(LB_SETCURSEL), 0, 0) - } - break - - default: break - } - - return DefWindowProcW(hWnd, uMsg, wParam, lParam) -} - -private let SwiftPickerViewWindowProc: SUBCLASSPROC = { (hWnd, uMsg, wParam, lParam, uIdSubclass, dwRefData) in - switch uMsg { - case UINT(WM_PAINT): - guard let pickerView = unsafeBitCast(dwRefData, to: AnyObject.self) as? PickerView else { - break - } - - let lSelection = SendMessageW(hWnd, UINT(CB_GETCURSEL), 0, 0) - guard lSelection >= 0 else { break } - - let lItemData = SendMessageW(pickerView.hWnd, UINT(CB_GETITEMDATA), - WPARAM(lSelection), 0) - guard let view = unsafeBitCast(UInt(lItemData), to: AnyObject.self) as? View else { - break - } - - var cbiInfo: COMBOBOXINFO = COMBOBOXINFO() - cbiInfo.cbSize = DWORD(MemoryLayout.size) - _ = withUnsafeMutablePointer(to: &cbiInfo) { - SendMessageW(pickerView.hWnd, UINT(CB_GETCOMBOBOXINFO), 0, - LPARAM(Int(bitPattern: $0))) - } - - var rcClient: RECT = RECT() - _ = GetClientRect(view.hWnd, &rcClient) - - let hDCItem: DeviceContextHandle = - DeviceContextHandle(owning: GetDC(view.hWnd)) - let hBitmap: BitmapHandle = - BitmapHandle(owning: CreateCompatibleBitmap(hDCItem.value, - rcClient.right - rcClient.left, - rcClient.bottom - rcClient.top)) - - let hDCMemory: DeviceContextHandle = - DeviceContextHandle(owning: CreateCompatibleDC(nil)) - _ = SelectObject(hDCMemory.value, hBitmap.value) - - _ = SendMessageW(view.hWnd, UINT(WM_PRINT), - WPARAM(UInt(bitPattern: hDCMemory.value)), - LPARAM(PRF_CHILDREN | PRF_CLIENT | PRF_ERASEBKGND | PRF_OWNED)) - - let lResult = DefSubclassProc(hWnd, uMsg, wParam, lParam) - - let hDC: DeviceContextHandle = - DeviceContextHandle(owning: GetDC(hWnd)) - - _ = BitBlt(hDC.value, cbiInfo.rcItem.left, cbiInfo.rcItem.top, - cbiInfo.rcItem.right - cbiInfo.rcItem.left, - cbiInfo.rcItem.bottom - cbiInfo.rcItem.top, hDCMemory.value, - 0, 0, UINT(SRCCOPY)) - - return lResult - - default: break - } - return DefSubclassProc(hWnd, uMsg, wParam, lParam) -} - -private class PickerViewProxy { - private static let `class`: WindowClass = - WindowClass(hInst: GetModuleHandleW(nil), name: "Swift.PickerView.Proxy", - WindowProc: SwiftPickerViewProxyWindowProc) - - fileprivate var hWnd: HWND! - - fileprivate init() { - _ = PickerViewProxy.class.register() - self.hWnd = - CreateWindowExW(0, PickerViewProxy.class.name, nil, 0, 0, 0, 0, 0, - HWND_MESSAGE, nil, GetModuleHandleW(nil), nil)! - } - - deinit { - _ = DestroyWindow(self.hWnd) - _ = PickerViewProxy.class.unregister() - } -} - - -/// Mediates between a `PickerView` object and your application's data model for -/// that picker view. -public protocol PickerViewDataSource: AnyObject { - // MARK - Providing Counts for the Picker View - - /// Called by the picker view when it needs the number of components. - func numberOfComponents(in pickerView: PickerView) -> Int - - /// Called by the picker view when it needs the number of rows for a specified - /// component. - func pickerView(_ pickerView: PickerView, - numberOfRowsInComponent component: Int) -> Int -} - -/// The delegate of a `PickerView` object must adopt this protocol and implement -/// at least some of its methods to provide the picker view with the data it -/// needs to construct itself. -public protocol PickerViewDelegate: AnyObject { - // MARK - Setting the Dimensions of the Picker View - - /// Called by the picker view when it needs the row height to use for drawing - /// row content. - func pickerView(_ pickerView: PickerView, - rowHeightForComponent component: Int) -> Double - - /// Called by the picker view when it needs the row width to use for drawing - /// row content. - func pickerView(_ pickerView: PickerView, - widthForComponent component: Int) -> Double - - // MARK - Setting the Content of Component Rows - - /// Called by the picker view when it needs the title to use for a given row - /// in a given component. - func pickerView(_ pickerView: PickerView, titleForRow row: Int, - forComponent component: Int) -> String? - - /// Called by the picker view when it needs the styled title to use for a - /// given row in a given component. - func pickerView(_ pickerView: PickerView, attributedTitleForRow row: Int, - forComponent component: Int) -> NSAttributedString? - - /// Called by the picker view when it needs the view to use for a given row in - /// a given component. - func pickerView(_ pickerView: PickerView, viewForRow row: Int, - forComponent component: Int, reusing view: View?) -> View - - // MARK - Responding to Row Selection - - /// Called by the picker view when the user selects a row in a component. - func pickerView(_ pickerView: PickerView, didSelectRow row: Int, - inComponent component: Int) -} - -extension PickerViewDelegate { - public func pickerView(_ pickerView: PickerView, - rowHeightForComponent component: Int) -> Double { - return 0.0 - } - - public func pickerView(_ pickerView: PickerView, - widthForComponent component: Int) -> Double { - return 0.0 - } -} - -fileprivate let kUnimplementedSentinel: View = View(frame: .zero) - -extension PickerViewDelegate { - public func pickerView(_ pickerView: PickerView, titleForRow row: Int, - forComponent component: Int) -> String? { - return pickerView.delegate?.pickerView(pickerView, - attributedTitleForRow: row, - forComponent: component)?.string - } - - public func pickerView(_ pickerView: PickerView, - attributedTitleForRow row: Int, - forComponent component: Int) -> NSAttributedString? { - // FIXME(compnerd) what is the proper default value? - return nil - } - - public func pickerView(_ pickerView: PickerView, viewForRow row: Int, - forComponent component: Int, reusing view: View?) - -> View { - return kUnimplementedSentinel - } -} - -extension PickerViewDelegate { - public func pickerView(_ pickerView: PickerView, didSelectRow row: Int, - inComponent component: Int) { - } -} - -/// A view that shows one or more sets of values. -public class PickerView: View { - private static let `class`: WindowClass = WindowClass(named: WC_COMBOBOX) - // FIXME(compnerd) `CBS_OWNERDRAWVARIABLE` is ideal, but we do not get the - // proper callbacks for the rendering of the items. - private static let style: WindowStyle = - (base: WS_BORDER | WS_HSCROLL | WS_POPUP | WS_TABSTOP | WS_VSCROLL | DWORD(CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED), - extended: 0) - - private static let proxy: PickerViewProxy = PickerViewProxy() - - // MARK - - - public init(frame: Rect = .zero) { - super.init(frame: frame, class: PickerView.class, style: PickerView.style, - parent: PickerView.proxy.hWnd) - - _ = SendMessageW(self.hWnd, UINT(CB_SETITEMHEIGHT), - WPARAM(UInt(bitPattern: -1)), LPARAM(UInt(frame.height))) - - var cbiInfo: COMBOBOXINFO = COMBOBOXINFO() - cbiInfo.cbSize = DWORD(MemoryLayout.size) - _ = withUnsafeMutablePointer(to: &cbiInfo) { - SendMessageW(self.hWnd, UINT(CB_GETCOMBOBOXINFO), 0, - LPARAM(UInt(bitPattern: $0))) - } - _ = SetWindowSubclass(cbiInfo.hwndItem, SwiftPickerViewWindowProc, - UINT_PTR(4), - unsafeBitCast(self as AnyObject, to: DWORD_PTR.self)) - } - - // MARK - Providing the Picker Data - - /// The data source for the picker view. - public weak var dataSource: PickerViewDataSource? - - // MARK - Customing the Picker Behaviour - - /// The delegate for the picker view. - public weak var delegate: PickerViewDelegate? - - // MARK - Getting the Dimensions of the View Picker - - /// Gets the number of components for the picker view. - public var numberOfComponents: Int { - // TODO(compnerd) cache the value from the dataSource - self.dataSource?.numberOfComponents(in: self) ?? 0 - } - - /// Returns the number of rows for a component. - public func numberOfRows(inComponent component: Int) -> Int { - // TODO(compnerd) cache the value from the dataSource - self.dataSource?.pickerView(self, numberOfRowsInComponent: component) ?? 0 - } - - /// Returns the size of a row for a component. - public func rowSize(forComponent component: Int) -> Size { - guard let delegate = self.delegate else { return Size(width: 0, height: 0) } - // TODO(compnerd) cache the value from the dataSource - return Size(width: delegate.pickerView(self, widthForComponent: component), - height: delegate.pickerView(self, rowHeightForComponent: component)) - } - - // MARK - Reloading the View Picker - - /// Reloads all components of the picker view. - public func reloadAllComponents() { - for component in (0 ..< self.numberOfComponents) { - self.reloadComponent(component) - } - } - - private var viewCache: [IndexPath:View] = [:] - - /// Reloads a particular component of the picker view. - public func reloadComponent(_ component: Int) { - assert(component == 0, "multi-component PickerView not yet implemented") - - // Clear any existing items in the picker view. We may have content from a - // previous load. - _ = SendMessageW(self.hWnd, UINT(CB_RESETCONTENT), 0, 0) - - // Query the ComboxBox info, which provides the hWnd for the ListView which - // serves as the rightful parent for the view. - // FIXME(compnerd) should we cache the value? It is unlikely to change. - var cbiInfo: COMBOBOXINFO = COMBOBOXINFO() - cbiInfo.cbSize = DWORD(MemoryLayout.size) - _ = withUnsafeMutablePointer(to: &cbiInfo) { - SendMessageW(self.hWnd, UINT(CB_GETCOMBOBOXINFO), 0, - LPARAM(Int(bitPattern: $0))) - } - - // We have a restriction on the row count at 32,768. We may overflow, but - // this seems unlikely as the UX at that point would make this less than - // ideal for usage. - let cbRows: Int = self.numberOfRows(inComponent: component) - - // Initialize the storage for the picker view. This avoids allocations on - // each entry being added. We should ideally have an `underestimatedCount` - // in use here, so as to avoid over-allocation of memory. - _ = SendMessageW(self.hWnd, UINT(CB_INITSTORAGE), WPARAM(cbRows), - LPARAM(MemoryLayout.size)) - - // Suspend redraws while repopulating the view. - _ = SendMessageW(self.hWnd, UINT(WM_SETREDRAW), 0, 0) - - for row in 0 ..< cbRows { - if let view = self.view(forRow: row, forComponent: component, - reusing: self.viewCache[[component, row]]) { - self.viewCache[[component, row]] = view - - _ = SendMessageW(self.hWnd, UINT(CB_INSERTSTRING), - WPARAM(bitPattern: -1), - unsafeBitCast(view as AnyObject, to: LPARAM.self)) - _ = SendMessageW(self.hWnd, UINT(CB_SETITEMHEIGHT), - WPARAM(0), LPARAM(view.frame.size.height)) - - // Reparent the view. - _ = SetParent(view.hWnd, cbiInfo.hwndList) - - view.GWL_STYLE &= ~LONG(bitPattern: WS_POPUP | WS_CAPTION) - view.GWL_STYLE |= LONG(WS_CHILD) - // FIXME(compnerd) can this be avoided somehow? - if view is TextField || view is TextView || view is TableView { - view.GWL_STYLE |= WinSDK.WS_BORDER - view.GWL_EXSTYLE &= ~WS_EX_CLIENTEDGE - } - - _ = SetWindowPos(view.hWnd, nil, 0, 0, 0, 0, - UINT(SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED)) - } - } - - // Resume redraws. - _ = SendMessageW(self.hWnd, UINT(WM_SETREDRAW), 1, 0) - } - - // MARK - Selecting Rows in the View Picker - - /// Selects a row ina specified component of the picker view. - public func selectRow(_ row: Int, inComponent component: Int, animated: Bool) { - assert(component == 0, "multi-component PickerView not yet implemented") - - assert(!animated, "not yet implemented") - _ = SendMessageW(self.hWnd, UINT(CB_SETCURSEL), WPARAM(row), 0) - self.delegate?.pickerView(self, didSelectRow: row, inComponent: component) - } - - /// Returns the index of the selected row in a given component. - public func selectedRow(inComponent component: Int) -> Int { - assert(component == 0, "multi-component PickerView not yet implemented") - - let lResult: LRESULT = SendMessageW(self.hWnd, UINT(CB_GETCURSEL), 0, 0) - if lResult == CB_ERR { return -1 } - return Int(lResult) - } - - // MARK - Returning the View for a Row and Component - - /// Returns the view used by the picker view for a given row and component. - public func view(forRow row: Int, forComponent component: Int, - reusing view: View?) -> View? { - assert(component == 0, "multi-component PickerView not yet implemented") - - var view: View? = - self.delegate?.pickerView(self, viewForRow: row, forComponent: component, - reusing: self.viewCache[[component, row]]) - if view === kUnimplementedSentinel { - let label = Label(frame: .zero) - label.text = self.delegate?.pickerView(self, titleForRow: row, - forComponent: component) - // TODO(compnerd) what is the right default size for the view? - label.frame.size = self.rowSize(forComponent: component) - if label.frame.size == .zero { - label.frame.size = label.sizeThatFits(label.frame.size) - label.frame.size.width = self.frame.size.width - } - view = label - } - self.viewCache[[component, row]] = view - return view - } -} diff --git a/Sources/SwiftWin32/Views and Controls/ProgressView.swift b/Sources/SwiftWin32/Views and Controls/ProgressView.swift deleted file mode 100644 index cc59217d..00000000 --- a/Sources/SwiftWin32/Views and Controls/ProgressView.swift +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright © 2019 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import WinSDK - -#if swift(>=5.7) -import CoreGraphics -#endif - -public class ProgressView: Control { - private static let `class`: WindowClass = WindowClass(named: PROGRESS_CLASS) - private static let style: WindowStyle = (base: WS_POPUP, extended: 0) - - public init(frame: Rect) { - super.init(frame: frame, class: ProgressView.class, style: ProgressView.style) - SendMessageW(hWnd, UINT(PBM_SETRANGE32), 0, 100) - SendMessageW(hWnd, UINT(PBM_SETPOS), 0, 0) - } - - public func setProgress(_ progress: Float, animated: Bool) { - SendMessageW(hWnd, UINT(PBM_SETPOS), WPARAM(100 * progress), 0) - } -} diff --git a/Sources/SwiftWin32/Views and Controls/Slider.swift b/Sources/SwiftWin32/Views and Controls/Slider.swift deleted file mode 100644 index 5c68d0b9..00000000 --- a/Sources/SwiftWin32/Views and Controls/Slider.swift +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import WinSDK - -#if swift(>=5.7) -import CoreGraphics -#endif - -/// A control for selecting a single value from a continuous range of values. -public class Slider: Control { - private static let `class`: WindowClass = WindowClass(named: TRACKBAR_CLASS) - private static let style: WindowStyle = - (base: WS_POPUP | DWORD(TBS_HORZ | TBS_TRANSPARENTBKGND), extended: 0) - - // MARK - Accessing the Slider's Value - - /// The slider’s current value. - public var value: Float { - get { - Float(SendMessageW(hWnd, UINT(TBM_GETPOS), 0, 0)) / 100.0 - } - set(value) { - _ = SendMessageW(hWnd, UINT(TBM_SETPOS), WPARAM(1), LPARAM(value * 100.0)) - } - } - - // MARK - Accessing the Slider's Value Limits - - /// The minimum value of the slider. - public var minimumValue: Float { - get { - Float(SendMessageW(self.hWnd, UINT(TBM_GETRANGEMIN), 0, 0)) / 100.0 - } - set(value) { - _ = SendMessageW(self.hWnd, UINT(TBM_SETRANGEMIN), - WPARAM(1), LPARAM(value * 100.0)) - } - } - - /// The maximum value of the slider. - public var maximumValue: Float { - get { - Float(SendMessageW(self.hWnd, UINT(TBM_GETRANGEMAX), 0, 0)) / 100.0 - } - set(value) { - _ = SendMessageW(self.hWnd, UINT(TBM_SETRANGEMAX), - WPARAM(1), LPARAM(value * 100.0)) - } - } - - // MARK - - - public init(frame: Rect) { - super.init(frame: frame, class: Slider.class, style: Slider.style) - _ = SendMessageW(self.hWnd, UINT(TBM_SETLINESIZE), WPARAM(1), LPARAM(100)) - } -} diff --git a/Sources/SwiftWin32/Views and Controls/Stepper.swift b/Sources/SwiftWin32/Views and Controls/Stepper.swift deleted file mode 100644 index 85ffeb5a..00000000 --- a/Sources/SwiftWin32/Views and Controls/Stepper.swift +++ /dev/null @@ -1,182 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import WinSDK - -#if swift(>=5.7) -import CoreGraphics -#endif - -// Notification Proxy - -// When the Window is created, the initial parent is cached. This cache cannot -// be updated. Instead, we always parent any stepper control to the -// `Swift.Stepper.Proxy` which is process-wide. All notifications -// about the control events will be dispatched by the proxy. -// -// In order to facilitate this, the control will stash the `self` (instance) -// pointer in `GWLP_USERDATA`. When we receive a `WM_HSCROLL` event, the -// `lParam` contains the handle to the control. We use this to query the -// stashed instance pointer and dispatch the action to the control, allowing the -// action targets to be invoked. - -private let SwiftStepperWindowProc: WNDPROC = { (hWnd, uMsg, wParam, lParam) in - switch uMsg { - case UINT(WM_HSCROLL): - if let stepper = UserData(from: HWND(bitPattern: UInt(lParam))) as Stepper? { - stepper.sendActions(for: .valueChanged) - } - - default: - break - } - - return DefWindowProcW(hWnd, uMsg, wParam, lParam) -} - -private class StepperProxy { - private static let `class`: WindowClass = - WindowClass(hInst: GetModuleHandleW(nil), name: "Swift.Stepper.Proxy", - WindowProc: SwiftStepperWindowProc) - - fileprivate var hWnd: HWND! - - fileprivate init() { - _ = StepperProxy.class.register() - self.hWnd = CreateWindowExW(0, StepperProxy.class.name, nil, 0, 0, 0, 0, 0, - HWND_MESSAGE, nil, GetModuleHandleW(nil), nil)! - } - - deinit { - _ = DestroyWindow(self.hWnd) - _ = StepperProxy.class.unregister() - } -} - - -/// A control for incrementing or decrementing a value. -public class Stepper: Control { - private static let `class`: WindowClass = WindowClass(named: UPDOWN_CLASS) - private static let style: WindowStyle = - (base: UInt32(UDS_HORZ) | WS_POPUP | WS_TABSTOP, extended: 0) - - private static var proxy: StepperProxy = StepperProxy() - - // MARK - Configuring the Stepper - - /// A boolean value that determines whether to send value changes during user - /// interaction or after user interaction ends. - public var isContinuous: Bool = true { - didSet { fatalError("\(#function) not yet implemented") } - } - - /// A boolean value that determines whether to repeatedly change the stepper's - /// value as the user presses and holds a stepper button. - public var autorepeat: Bool = true { - didSet { fatalError("\(#function) not yet implemented") } - } - - /// A boolean value that determines whether the stepper can wrap its value to - /// the minimum or maximum value when incrementing and decrementing the value. - public var wraps: Bool { - get { self.GWL_STYLE & UDS_WRAP == UDS_WRAP } - set { - self.GWL_STYLE = newValue ? self.GWL_STYLE | UDS_WRAP - : self.GWL_STYLE & ~UDS_WRAP - } - } - - /// The lowest possible numeric value for the stepper. - public var minimumValue: Double { - get { - var value: CInt = 0 - _ = withUnsafeMutablePointer(to: &value) { - SendMessageW(self.hWnd, UINT(UDM_GETRANGE32), - WPARAM(UInt(bitPattern: $0)), 0) - } - return Double(value) - } - set { - let newMaximum = - self.maximumValue >= newValue ? self.minimumValue : newValue - - _ = SendMessageW(self.hWnd, UINT(UDM_SETRANGE32), - WPARAM(CInt(newValue)), LPARAM(CInt(newMaximum))) - } - } - - /// The highest possible numeric value for the stepper. - public var maximumValue: Double { - get { - var value: CInt = 0 - _ = withUnsafeMutablePointer(to: &value) { - SendMessageW(self.hWnd, UINT(UDM_GETRANGE32), - 0, LPARAM(UInt(bitPattern: $0))) - } - return Double(value) - } - set { - let newMinimum = - self.minimumValue <= newValue ? self.minimumValue : newValue - - _ = SendMessageW(self.hWnd, UINT(UDM_SETRANGE32), - WPARAM(CInt(newMinimum)), LPARAM(CInt(newValue))) - } - } - - /// The step, or increment, value for the stepper. - public var stepValue: Double { - get { - var value: UDACCEL = UDACCEL(nSec: 0, nInc: 0) - _ = withUnsafeMutablePointer(to: &value) { - SendMessageW(self.hWnd, UINT(UDM_GETACCEL), - WPARAM(MemoryLayout.size), - LPARAM(UInt(bitPattern: $0))) - } - return Double(value.nInc) - } - set { - var value: UDACCEL = UDACCEL(nSec: 0, nInc: 0) - _ = withUnsafeMutablePointer(to: &value) { - SendMessageW(self.hWnd, UINT(UDM_GETACCEL), - WPARAM(1), LPARAM(UInt(bitPattern: $0))) - } - value.nInc = DWORD(newValue) - _ = withUnsafeMutablePointer(to: &value) { - SendMessageW(self.hWnd, UINT(UDM_SETACCEL), - WPARAM(1), LPARAM(UInt(bitPattern: $0))) - } - } - } - - // MARK - Accessing the Stepper's Value - - /// The numeric value of the stepper. - public var value: Double { - get { - let lResult: LRESULT = SendMessageW(self.hWnd, UINT(UDM_GETPOS32), 0, 0) - return Double(lResult) - } - set { - _ = SendMessageW(self.hWnd, UINT(UDM_SETPOS32), 0, LPARAM(DWORD(newValue))) - } - } - - // MARK - - - public init(frame: Rect) { - super.init(frame: frame, class: Stepper.class, style: Stepper.style, - parent: Stepper.proxy.hWnd) - - _ = SetWindowLongPtrW(self.hWnd, GWLP_USERDATA, - unsafeBitCast(self as AnyObject, to: LONG_PTR.self)) - - defer { - self.wraps = false - self.minimumValue = 0.0 - self.maximumValue = 100.0 - self.stepValue = 1.0 - self.value = 0.0 - } - } -} diff --git a/Sources/SwiftWin32/Views and Controls/Switch.swift b/Sources/SwiftWin32/Views and Controls/Switch.swift deleted file mode 100644 index 581a6620..00000000 --- a/Sources/SwiftWin32/Views and Controls/Switch.swift +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright © 2019 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import WinSDK - -#if swift(>=5.7) -import CoreGraphics -#endif - -/// A control that offers a binary choice, such as on/off. -public class Switch: Control { - private static let `class`: WindowClass = WindowClass(named: WC_BUTTON) - // MSDN: - // A button sends the `BN_DISABLE`, `BN_PUSHED`, `BN_KILLFOCUS`, `BN_PAINT`, - // `BN_SETFOCUS`, and `BN_UNPUSHED` notification codes only if it has the - // `BS_NOFITY` style. - private static let style: WindowStyle = - (base: WS_TABSTOP | DWORD(BS_AUTOCHECKBOX | BS_NOTIFY), extended: 0) - - // MARK - Setting the Off/On State - - /// A Boolean value that determines the off/on state of the switch. - public var isOn: Bool { - get { SendMessageW(self.hWnd, UINT(BM_GETCHECK), 0, 0) == BST_CHECKED } - set(value) { self.setOn(value, animated: false) } - } - - /// Set the state of the switch to On or Off, optionally animating the - /// transition. - public func setOn(_ on: Bool, animated: Bool) { - assert(!animated, "not yet implemented") - _ = SendMessageW(self.hWnd, UINT(BM_SETCHECK), WPARAM(on ? 1 : 0), 0) - } - - // MARK - Setting the Display Style - - /// The preferred display style for the switch. - public var preferredStyle: Switch.Style = .automatic { - didSet { fatalError("not yet implemented") } - } - - /// The display style for the switch. - public private(set) var style: Switch.Style = .checkbox - - /// The title displayed next to a checkbox-style switch. - @_Win32WindowText - public var title: String? - - // MARK - Initializing the Switch Object - - /// Returns an initialized switch object. - public init(frame: Rect) { - super.init(frame: frame, class: Switch.class, style: Switch.style) - } -} - -extension Switch { - /// Styles that determine the appearance of the switch. - public enum Style: Int { - /// A style indicating that the system chooses the appearance of the switch - /// according to the current user interface idiom. - case automatic - - /// A style indicating that the switch appears as a checkbox. - case checkbox - - /// A style indicating that the switch appears as an on/off slider. - case sliding - } -} diff --git a/Sources/SwiftWin32/Views and Controls/Table Views/ContextualAction.swift b/Sources/SwiftWin32/Views and Controls/Table Views/ContextualAction.swift deleted file mode 100644 index 5ef0e241..00000000 --- a/Sources/SwiftWin32/Views and Controls/Table Views/ContextualAction.swift +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import WinSDK - -extension ContextualAction { - /// Constants indicating the style information that is applied to the action - /// button. - public enum Style: Int { - /// A normal action. - case normal - - /// An action that deletes data or performs some type of destructive task. - case destructive - } -} - -/// An action to display when the user swipes a table row. -public class ContextualAction { - // MARK - Creating the Contexual Action - - /// Creates a new contextual action with the specified title and handler. - public /*convenience*/ init(style: ContextualAction.Style, title: String?, - handler: @escaping ContextualAction.Handler) { - self.title = title - self.handler = handler - self.style = style - - // XXX(compnerd) should this be stylized from a global? - switch style { - case .normal: - // FIXME(compnerd) should this be `.clear`? - self.backgroundColor = Color(color: GetSysColor(COLOR_3DFACE)) - case .destructive: - self.backgroundColor = .red - } - } - - // MARK - Configuring the Appearance - - /// The title displayed on the action button. - public var title: String? - - /// The background color of the action button. - public let backgroundColor: Color! - - /// The image to display in the action button. - public var image: Image? - - // MARK - Getting the Configuration Details - - /// The handler block to execute when the user selects the action. - public let handler: ContextualAction.Handler - - /// The handler block to call in response to the selection of an action. - public typealias Handler = - (ContextualAction, View, @escaping (Bool) -> Void) -> Void - - /// The style that is applied to the action button. - public let style: ContextualAction.Style -} diff --git a/Sources/SwiftWin32/Views and Controls/Table Views/SwipeActionsConfiguration.swift b/Sources/SwiftWin32/Views and Controls/Table Views/SwipeActionsConfiguration.swift deleted file mode 100644 index f43f404c..00000000 --- a/Sources/SwiftWin32/Views and Controls/Table Views/SwipeActionsConfiguration.swift +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -/// The set of actions to perform when swiping on rows of a table. -public class SwipeActionsConfiguration { - // MARK - Initializing the Swipe Actions - - /// Creates a swipe action configuration object with the specified set of - /// actions. - public init(actions: [ContextualAction]) { - // convenience - self.actions = actions - } - - // MARK - Getting the Swipe Action Information - - /// The swipe actions. - public private(set) var actions: [ContextualAction] - - /// A boolean value indicating whether a full swipe automatically performs the - /// first action. - public var performsFirstActionWithFullSwipe: Bool = true -} diff --git a/Sources/SwiftWin32/Views and Controls/Table Views/TableView.swift b/Sources/SwiftWin32/Views and Controls/Table Views/TableView.swift deleted file mode 100644 index 62cff00f..00000000 --- a/Sources/SwiftWin32/Views and Controls/Table Views/TableView.swift +++ /dev/null @@ -1,187 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import WinSDK -import struct Foundation.IndexPath - -#if swift(>=5.7) -import CoreGraphics -#endif - -// Notification Proxy - -// When the Window is created, the initial parent is cached. This cache cannot -// be updated. Instead, we always parent any table view control to the -// `Swift.TableView.Proxy` which is process-wide. All notifications -// about the control events will be dispatched by the proxy. - -private let SwiftTableViewProxyWindowProc: WNDPROC = { (hWnd, uMsg, wParam, lParam) in - switch uMsg { - case UINT(WM_DRAWITEM): - let lpDrawItem: UnsafeMutablePointer = - UnsafeMutablePointer(bitPattern: UInt(lParam))! - - switch lpDrawItem.pointee.itemAction { - case UINT(ODA_SELECT): - // TODO(compnerd) figure out how to render the selection - fallthrough - case UINT(ODA_DRAWENTIRE): - if let view = unsafeBitCast(lpDrawItem.pointee.itemData, - to: AnyObject.self) as? View { - let rctRect: RECT = lpDrawItem.pointee.rcItem - _ = SetWindowPos(view.hWnd, nil, rctRect.left, rctRect.top, 0, 0, - UINT(SWP_NOSIZE)) - - // Setting `isHidden` is necessary for TableCells generated after - // initial call to `Window.makeKeyAndVisible()` - let hWndParent = GetParent(view.hWnd) - if IsWindowVisible(hWndParent) && !IsWindowVisible(view.hWnd) { - view.isHidden = false - } - - return DefWindowProcW(view.hWnd, UINT(WM_PAINT), 0, 0) - } - - break - case UINT(ODA_FOCUS): - // TODO(compnerd) figure out how to deal with focus - return LRESULT(1) - default: - fatalError("unhandled message: \(lpDrawItem.pointee.itemAction)") - } - - case UINT(WM_MEASUREITEM): - let lpMeasurement: UnsafeMutablePointer = - UnsafeMutablePointer(bitPattern: UInt(lParam))! - - if let view = unsafeBitCast(lpMeasurement.pointee.itemData, - to: AnyObject.self) as? View { - lpMeasurement.pointee.itemHeight = UINT(view.frame.size.height) - lpMeasurement.pointee.itemWidth = UINT(view.frame.size.width) - } - - return LRESULT(1) - - case UINT(WM_DELETEITEM): - let lpDeleteItem: UnsafeMutablePointer = - UnsafeMutablePointer(bitPattern: UInt(lParam))! - - if let view = unsafeBitCast(lpDeleteItem.pointee.itemData, - to: AnyObject.self) as? View { - view.removeFromSuperview() - } - - return LRESULT(1) - - default: break - } - - return DefWindowProcW(hWnd, uMsg, wParam, lParam) -} - -private class TableViewProxy { - private static let `class`: WindowClass = - WindowClass(hInst: GetModuleHandleW(nil), name: "Swift.TableView.Proxy", - WindowProc: SwiftTableViewProxyWindowProc) - - fileprivate var hWnd: HWND! - - fileprivate init() { - _ = TableViewProxy.class.register() - self.hWnd = CreateWindowExW(0, TableViewProxy.class.name, nil, 0, 0, 0, 0, 0, - HWND_MESSAGE, nil, GetModuleHandleW(nil), nil)! - } - - deinit { - _ = DestroyWindow(self.hWnd) - _ = TableViewProxy.class.unregister() - } -} - - -extension TableView { - public enum Style: Int { - /// A plain table view. - case plain - /// A table view where sections have distinct groups of rows. - case group - /// A table view where the grouped sections are inset with rounded corners. - case insetGrouped - } -} - - -/// A view that presents data using rows arranged in a single column. -public class TableView: View { - private static let `class`: WindowClass = WindowClass(named: WC_LISTBOX) - private static let style: WindowStyle = - (base: WS_BORDER | WS_HSCROLL | WS_POPUP | WS_TABSTOP | WS_VSCROLL | DWORD(LBS_NODATA | LBS_OWNERDRAWVARIABLE), - extended: 0) - - private static let proxy: TableViewProxy = TableViewProxy() - - // MARK - Creating a Table View - - /// Initializes and returns a table view having the given frame and style. - public init(frame: Rect, style: TableView.Style) { - self.style = style - super.init(frame: frame, class: TableView.class, style: TableView.style, - parent: TableView.proxy.hWnd) - } - - // MARK - Providing the Table's Data and Cells - - /// The object that acts as the data source of the table view. - public weak var dataSource: TableViewDataSource? { - didSet { self.reloadData() } - } - - // MARK - Configuring the Table's Appearance - - /// The style of the table view. - public let style: TableView.Style - - // MARK - Selecting Rows - - /// A boolean value that determines whether users can select more than one row - /// outside of editing mode. - public var allowsMultipleSelection: Bool { - get { self.GWL_STYLE & LBS_EXTENDEDSEL == LBS_EXTENDEDSEL } - set { - self.GWL_STYLE = (self.GWL_STYLE & ~LBS_EXTENDEDSEL) - | (newValue ? 0 : LBS_EXTENDEDSEL) - } - } - - // MARK - Reloading the Table View - - /// Reloads the rows and sections of the table view. - public func reloadData() { - _ = SendMessageW(self.hWnd, UINT(LB_RESETCONTENT), 0, 0) - - guard let dataSource = self.dataSource else { return } - - // Suspend redraws while repopulating the view. - _ = SendMessageW(self.hWnd, UINT(WM_SETREDRAW), 0, 0) - - for section in 0 ..< dataSource.numberOfSections(in: self) { - for row in 0 ..< dataSource.tableView(self, - numberOfRowsInSection: section) { - let cell = - dataSource.tableView(self, - cellForRowAt: IndexPath(row: row, - section: section)) - // Resize the frame to the size that fits the content - cell.frame.size = cell.sizeThatFits(cell.frame.size) - - _ = SendMessageW(self.hWnd, UINT(LB_INSERTSTRING), - WPARAM(bitPattern: -1), - unsafeBitCast(cell as AnyObject, to: LPARAM.self)) - addSubview(cell) - } - } - - // Resume redraws. - _ = SendMessageW(self.hWnd, UINT(WM_SETREDRAW), 1, 0) - } -} diff --git a/Sources/SwiftWin32/Views and Controls/Table Views/TableViewCell.swift b/Sources/SwiftWin32/Views and Controls/Table Views/TableViewCell.swift deleted file mode 100644 index 38138e62..00000000 --- a/Sources/SwiftWin32/Views and Controls/Table Views/TableViewCell.swift +++ /dev/null @@ -1,101 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import WinSDK - -#if swift(>=5.7) -import CoreGraphics -#endif - -extension TableViewCell { - public enum CellStyle: Int { - /// A simple style for a cell with a text label (black and left-aligned) and - /// an optional view. - case `default` - /// A style for a cell with a label on the left side of the cell with a - /// left-aligned and black text; on the right side is a label that has smaller - /// blue text and is right aligned. - case value1 - /// A style for a cell with a label on the left side of the cell with text - /// that is right-aligned and blue on the right side of the cell is another - /// label with smaller text that is left-aligned and black. - case value2 - /// A style for a cell with a left-aligned label across the top and a - /// left-aliggned label below it in smaller gray text. - case subtitle - } -} - -extension TableViewCell { - /// The editing control used by a cell. - public enum EditingStyle: Int { - /// The cell has no editing control. This is the default value. - case none - - /// The cell has the delete editing control; this control is a red circle - /// enclosing a minus sign. - case delete - - /// The cell has the insert editing control; this control is a green circle - /// enclosing a plus sign. - case insert - } -} - -/// The visual representation of a single row in a table view. -public class TableViewCell: View { - private static let `class`: WindowClass = - WindowClass(hInst: GetModuleHandleW(nil), name: "Swift.TableViewCell", - style: UInt32(CS_HREDRAW | CS_VREDRAW), - hbrBackground: GetSysColorBrush(COLOR_3DFACE), - hCursor: LoadCursorW(nil, IDC_ARROW)) - private static let style: WindowStyle = (base: 0, extended: 0) - - public override func sizeThatFits(_ size: Size) -> Size { - // TODO(compnerd) this should size the content view - return self.subviews.first?.sizeThatFits(size) ?? .zero - } - - // MARK - Creating a Table View Cell - - /// Initializes a table cell with a style and a reuse identifier and returns it - /// to the caller. - public init(style: TableViewCell.CellStyle, reuseIdentifier: String?) { - self.reuseIdentifier = reuseIdentifier - super.init(frame: .zero, class: TableViewCell.class, - style: TableViewCell.style) - } - - // MARK - Reusing Cells - - /// A string used to identify a cell that is reusable. - public let reuseIdentifier: String? - - /// Prepares a reusable cell for reuse by the table view's delegate. - public func prepareForReuse() { - } - - // MARK - Editing the Cell - - /// A boolean value that indicates whether the cell is in an editable state. - public var isEditing: Bool = false - - /// Toggles the receiver into and out of editing mode. - public func setEditing(_ editing: Bool, animated: Bool) { - assert(!animated, "not yet implemented") - self.isEditing = editing - } - - /// The editing style of the cell. - public private(set) var editingStyle: TableViewCell.EditingStyle = .none - - /// A boolean value that indicates whether the cell is currently showing the - /// delete-confirmation button. - public private(set) var showingDeleteConfirmation: Bool = false - - /// A boolean value that determines whether the cell shows the reordering - /// control. - public var showsReorderControl: Bool = false { - didSet { fatalError("\(#function) not yet implemented") } - } -} diff --git a/Sources/SwiftWin32/Views and Controls/Table Views/TableViewDataSource.swift b/Sources/SwiftWin32/Views and Controls/Table Views/TableViewDataSource.swift deleted file mode 100644 index ccf1a080..00000000 --- a/Sources/SwiftWin32/Views and Controls/Table Views/TableViewDataSource.swift +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import struct Foundation.IndexPath - -public protocol TableViewDataSource: AnyObject { - // MARK - Providng the Number of Rows and Sections - - /// Informs the data source to return the number of rows in a given section of - /// a table view. - func tableView(_ tableView: TableView, numberOfRowsInSection section: Int) - -> Int - - /// Asks the data source to return the number of sections in the table view. - func numberOfSections(in tableView: TableView) -> Int - - // MARK - Providing Cells, Headers, and Footers - - /// Asks the data source for a cell to insert in a particular location of the - /// table view. - func tableView(_ tableView: TableView, cellForRowAt indexPath: IndexPath) - -> TableViewCell - - /// Asks the data source for the title of the header of the specified section - /// of the table view. - func tableView(_ tableView: TableView, titleForHeaderInSection section: Int) - -> String? - - /// Asks the data source for the title of the footer of the specified section - /// of the table view. - func tableView(_ tableView: TableView, titleForFooterInSection section: Int) - -> String? -} - -extension TableViewDataSource { - public func numberOfSections(in tableView: TableView) -> Int { - return 1 - } -} - -extension TableViewDataSource { - public func tableView(_ tableView: TableView, - titleForHeaderInSection section: Int) -> String? { - return nil - } - - public func tableView(_ tableView: TableView, - titleForFooterInSection section: Int) -> String? { - return nil - } -} diff --git a/Sources/SwiftWin32/Views and Controls/Table Views/TableViewDelegate.swift b/Sources/SwiftWin32/Views and Controls/Table Views/TableViewDelegate.swift deleted file mode 100644 index 288acc10..00000000 --- a/Sources/SwiftWin32/Views and Controls/Table Views/TableViewDelegate.swift +++ /dev/null @@ -1,520 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import struct Foundation.IndexPath - -#if swift(>=5.7) -import CoreGraphics -#endif - -/// Methods for managing selections, configuring section headers and footers, -/// deleting and reordering cells, and performing other actions in a table view. -public protocol TableViewDelegate: AnyObject { - // MARK - Configuring Rows for the Table View - - /// Informs the delegate the table view is about to draw a cell for a - /// particular row. - func tableView(_ tableView: TableView, willDisplay cell: TableViewCell, - forRowAt indexPath: IndexPath) - - /// Asks the delegate to return the level of indentation for a row in a given - /// section. - func tableView(_ tableView: TableView, - indentationLevelForRowAt indexPath: IndexPath) -> Int - - /// Called to let you fine tune the spring-loading behavior of the rows in a - /// table. - func tableView(_ tableView: TableView, - shouldSpringLoadRowAt indexPath: IndexPath, - with context: SpringLoadedInteractionContext) -> Bool - - // MARK - Responding to Row Selections - - /// Informs the delegate a row is about to be selected. - func tableView(_ tableView: TableView, willSelectRowAt indexPath: IndexPath) - -> IndexPath? - - /// Informs the delegate a row is selected. - func tableView(_ tableView: TableView, didSelectRowAt indexPath: IndexPath) - - /// Informs the delegate that a specified row is about to be deselected. - func tableView(_ tableView: TableView, willDeselectRowAt indexPath: IndexPath) - -> IndexPath? - - /// Informs the delegate that the specified row is now deselected. - func tableView(_ tableView: TableView, didDeselectRowAt indexPath: IndexPath) - - /// Asks the delegate whether the user can use a two-finger pan gesture to - /// select multiple items in a table view. - func tableView(_ tableView: TableView, - shouldBeginMultipleSelectionInteractionAt indexPath: IndexPath) - -> Bool - - /// Informs the delegate when the user starts using a two-finger pan gesture - /// to select multiple rows in a table view. - func tableView(_ tableView: TableView, - didBeginMultipleSelectionInteractionAt indexPath: IndexPath) - - /// Informs the delegate when the user stops using a two-finger pan gesture to - /// select multiple rows in a table view. - func tableViewDidEndMultipleSelectionInteraction(_ tableView: TableView) - - // MARK - Providing Custom Header and Footer Views - - /// Asks the delegate for a view object to display in the header of the - /// specified section of the table view. - func tableView(_ tableView: TableView, viewForHeaderInSection section: Int) - -> View? - - /// Asks the delegate for a view object to display in the footer of the - /// specified section of the table view. - func tableView(_ tableView: TableView, viewForFooterInSection section: Int) - -> View? - - /// Informs the delegate that the table is about to display the header view - /// for the specified section. - func tableView(_ tableView: TableView, willDisplayHeaderView view: View, - forSection section: Int) - - /// Informs the delegate that the table is about to display the footer view - /// for the specified section. - func tableView(_ tableView: TableView, willDisplayFooterView view: View, - forSection section: Int) - - // MARK - Providing Header, Footer, and Row Heights - - /// Asks the delegate for the height to use for a row in a specified location. - func tableView(_ tableView: TableView, heightForRowAt indexPath: IndexPath) - -> Double - - /// Asks the delegate for the height to use for the header of a particular - /// section. - func tableView(_ tableView: TableView, heightForHeaderInSection section: Int) - -> Double - - /// Asks the delegate for the height to use for the footer of a particular - /// section. - func tableView(_ tableView: TableView, heightForFooterInSection section: Int) - -> Double - - static var automaticDimension: Double { get } - - // MARK - Estimating Heights for the Table's Content - - /// Asks the delegate for the estimated height of a row in a specified - /// location. - func tableView(_ tableView: TableView, - estimatedHeightForRowAt indexPath: IndexPath) -> Double - - /// Asks the delegate for the estimated height of the header of a particular - /// section. - func tableView(_ tableView: TableView, - estimatedHeightForHeaderInSection section: Int) -> Double - - /// Asks the delegate for the estimated height of the footer of a particular - /// section. - func tableView(_ tableView: TableView, - estimatedHeightForFooterInSection section: Int) -> Double - - // MARK - Managing Accessory Views - - /// Informs the delegate that the user tapped the detail button for the - /// specified row. - func tableView(_ tableView: TableView, - accessoryButtonTappedForRowWith indexPath: IndexPath) - - // MARK - Managing Context Menus - - /// Returns a context menu configuration for the row at a point. - func tableView(_ tableView: TableView, - contextMenuConfigurationForRowAt indexPath: IndexPath, - point: Point) -> ContextMenuConfiguration? - - /// Returns the destination view when dismissing a context menu. - func tableView(_ tableView: TableView, - previewForDismissingContextMenuWithConfiguration configuration: ContextMenuConfiguration) - -> TargetedPreview? - - /// Returns a view to override the default preview the table view created. - func tableView(_ tableView: TableView, - previewForHighlightingContextMenuWithConfiguration configuration: ContextMenuConfiguration) - -> TargetedPreview? - - /// Informs the delegate when a context menu will appear. - func tableView(_ tableView: TableView, - willDisplayContextMenu configuration: ContextMenuConfiguration, - animator: ContextMenuInteractionAnimating?) - - /// Informs the delegate when a context menu will disappear. - func tableView(_ tableView: TableView, - willEndContextMenuInteraction configuration: ContextMenuConfiguration, - animator: ContextMenuInteractionAnimating?) - - /// Informs the delegate when a user triggers a commit by tapping the preview. - func tableView(_ tableView: TableView, - willPerformPreviewActionForMenuWith configuration: ContextMenuConfiguration, - animator: ContextMenuInteractionCommitAnimating) - - // MARK - Responding to Row Actions - - /// Returns the swipe actions to display on the leading edge of the row. - func tableView(_ tableView: TableView, - leadingSwipeActionsConfigurationForRowAt indexPath: IndexPath) - -> SwipeActionsConfiguration? - - /// Returns the swipe actions to display on the trailing edge of the row. - func tableView(_ tableView: TableView, - trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) - -> SwipeActionsConfiguration? - - // MARK - Managing Table View Highlights - - /// Asks the delegate if the specified row should be highlighted. - func tableView(_ tableView: TableView, - shouldHighlightRowAt indexPath: IndexPath) -> Bool - - /// Informs the delegate that the specified row was highlighted. - func tableView(_ tableView: TableView, didHighlightRowAt indexPath: IndexPath) - - /// Informs the delegate that the highlight was removed from the row at the - /// specified index path. - func tableView(_ tableView: TableView, - didUnhighlightRowAt indexPath: IndexPath) - - // MARK - Editing Table Rows - - /// Informs the delegate that the table view is about to go into editing mode. - func tableView(_ tableView: TableView, - willBeginEditingRowAt indexPath: IndexPath) - - /// Informs the delegate that the table view has left editing mode. - func tableView(_ tableView: TableView, - didEndEditingRowAt indexPath: IndexPath?) - - /// Asks the delegate for the editing style of a row at a particular location - /// in a table view. - func tableView(_ tableView: TableView, - editingStyleForRowAt indexPath: IndexPath) - -> TableViewCell.EditingStyle - - /// Changes the default title of the delete-confirmation button. - func tableView(_ tableView: TableView, - titleForDeleteConfirmationButtonForRowAt indexPath: IndexPath) - -> String? - - /// Asks the delegate whether the background of the specified row should be - /// indented while the table view is in editing mode. - func tableView(_ tableView: TableView, - shouldIndentWhileEditingRowAt indexPath: IndexPath) -> Bool - - // MARK - Reordering Table Rows - - /// Asks the delegate to return a new index path to retarget a proposed move - /// of a row. - func tableView(_ tableView: TableView, - targetIndexPathForMoveFromRowAt sourceIndexPath: IndexPath, - toProposedIndexPath proposedDestinationIndexPath: IndexPath) - -> IndexPath - - // MARK - Tracking Removal of Views - - /// Informs the delegate that the specified cell was removed from the table. - func tableView(_ tableView: TableView, didEndDisplaying cell: TableViewCell, - forRowAt indexPath: IndexPath) - - /// Informs the delegate that the specified header view was removed from the - /// table. - func tableView(_ tableView: TableView, didEndDisplayingHeaderView view: View, - forSection section: Int) - - /// Informs the delegate that the specified footer view was removed from the - /// table. - func tableView(_ tableView: TableView, didEndDisplayingFooterView view: View, - forSection section: Int) - - // MARK - Managing Table View Focus - - /// Asks the delegate whether the cell at the specified index path is itself - /// focusable. - func tableView(_ tableView: TableView, canFocusRowAt indexPath: IndexPath) - -> Bool - - /// Asks the delegate whether the focus update specified by the context is - /// allowed to occur. - func tableView(_ tableView: TableView, - shouldUpdateFocusIn context: TableViewFocusUpdateContext) - -> Bool - - /// Informs the delegate that a focus update specified by the context has just - /// occurred. - func tableView(_ tableView: TableView, - didUpdateFocusIn context: TableViewFocusUpdateContext, - with coordinator: FocusAnimationCoordinator) - - /// Asks the delegate for the table view’s index path for the preferred - /// focused view. - func indexPathForPreferredFocusedView(in tableView: TableView) -> IndexPath? -} - -extension TableViewDelegate { - public func tableView(_ tableView: TableView, willDisplay cell: TableViewCell, - forRowAt indexPath: IndexPath) { - } - - public func tableView(_ tableView: TableView, - indentationLevelForRowAt indexPath: IndexPath) -> Int { - 0 - } - - public func tableView(_ tableView: TableView, - shouldSpringLoadRowAt indexPath: IndexPath, - with context: SpringLoadedInteractionContext) -> Bool { - return true - } -} - -extension TableViewDelegate { - public func tableView(_ tableView: TableView, - willSelectRowAt indexPath: IndexPath) -> IndexPath? { - return indexPath - } - - public func tableView(_ tableView: TableView, - didSelectRowAt indexPath: IndexPath) { - } - - public func tableView(_ tableView: TableView, - willDeselectRowAt indexPath: IndexPath) -> IndexPath? { - return indexPath - } - - public func tableView(_ tableView: TableView, - didDeselectRowAt indexPath: IndexPath) { - } - - public func tableView(_ tableView: TableView, - shouldBeginMultipleSelectionInteractionAt indexPath: IndexPath) - -> Bool { - return false - } - - public func tableView(_ tableView: TableView, - didBeginMultipleSelectionInteractionAt indexPath: IndexPath) { - } - - public func tableViewDidEndMultipleSelectionInteraction(_ tableView: TableView) { - } -} - -extension TableViewDelegate { - public func tableView(_ tableView: TableView, - viewForHeaderInSection section: Int) -> View? { - return nil - } - - public func tableView(_ tableView: TableView, - viewForFooterInSection section: Int) -> View? { - return nil - } - - public func tableView(_ tableView: TableView, - willDisplayHeaderView view: View, - forSection section: Int) { - } - - public func tableView(_ tableView: TableView, - willDisplayFooterView view: View, - forSection section: Int) { - } -} - -extension TableViewDelegate { - public func tableView(_ tableView: TableView, - heightForRowAt indexPath: IndexPath) -> Double { - return Self.automaticDimension - } - - public func tableView(_ tableView: TableView, - heightForHeaderInSection section: Int) -> Double { - return Self.automaticDimension - } - - public func tableView(_ tableView: TableView, - heightForFooterInSection section: Int) -> Double { - return Self.automaticDimension - } - - public static var automaticDimension: Double { - return .greatestFiniteMagnitude - } -} - -extension TableViewDelegate { - public func tableView(_ tableView: TableView, - estimatedHeightForRowAt indexPath: IndexPath) -> Double { - return Self.automaticDimension - } - - public func tableView(_ tableView: TableView, - estimatedHeightForHeaderInSection section: Int) - -> Double { - return Self.automaticDimension - } - - public func tableView(_ tableView: TableView, - estimatedHeightForFooterInSection section: Int) - -> Double { - return Self.automaticDimension - } -} - -extension TableViewDelegate { - public func tableView(_ tableView: TableView, - accessoryButtonTappedForRowWith indexPath: IndexPath) { - } -} - -extension TableViewDelegate { - public func tableView(_ tableView: TableView, - contextMenuConfigurationForRowAt indexPath: IndexPath, - point: Point) -> ContextMenuConfiguration? { - return nil - } - - public func tableView(_ tableView: TableView, - previewForDismissingContextMenuWithConfiguration configuration: ContextMenuConfiguration) - -> TargetedPreview? { - return nil - } - - public func tableView(_ tableView: TableView, - previewForHighlightingContextMenuWithConfiguration configuration: ContextMenuConfiguration) - -> TargetedPreview? { - return nil - } - - public func tableView(_ tableView: TableView, - willDisplayContextMenu configuration: ContextMenuConfiguration, - animator: ContextMenuInteractionAnimating?) { - } - - public func tableView(_ tableView: TableView, - willEndContextMenuInteraction configuration: ContextMenuConfiguration, - animator: ContextMenuInteractionAnimating?) { - } - - public func tableView(_ tableView: TableView, - willPerformPreviewActionForMenuWith configuration: ContextMenuConfiguration, - animator: ContextMenuInteractionCommitAnimating) { - } -} - -extension TableViewDelegate { - public func tableView(_ tableView: TableView, - leadingSwipeActionsConfigurationForRowAt indexPath: IndexPath) - -> SwipeActionsConfiguration? { - return nil - } - - public func tableView(_ tableView: TableView, - trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) - -> SwipeActionsConfiguration? { - return nil - } -} - -extension TableViewDelegate { - public func tableView(_ tableView: TableView, - shouldHighlightRowAt indexPath: IndexPath) -> Bool { - return true - } - - public func tableView(_ tableView: TableView, - didHighlightRowAt indexPath: IndexPath) { - } - - public func tableView(_ tableView: TableView, - didUnhighlightRowAt indexPath: IndexPath) { - } -} - -extension TableViewDelegate { - public func tableView(_ tableView: TableView, - willBeginEditingRowAt indexPath: IndexPath) { - } - - public func tableView(_ tableView: TableView, - didEndEditingRowAt indexPath: IndexPath?) { - } - - public func tableView(_ tableView: TableView, - editingStyleForRowAt indexPath: IndexPath) - -> TableViewCell.EditingStyle { - return (tableView.dataSource?.tableView(tableView, cellForRowAt: indexPath).isEditing ?? false) - ? .delete - : .none - } - - public func tableView(_ tableView: TableView, - titleForDeleteConfirmationButtonForRowAt indexPath: IndexPath) - -> String? { - // FIXME(compnerd) localize the string - return "Delete" - } - - public func tableView(_ tableView: TableView, - shouldIndentWhileEditingRowAt indexPath: IndexPath) - -> Bool { - return true - } -} - -extension TableViewDelegate { - public func tableView(_ tableView: TableView, - targetIndexPathForMoveFromRowAt sourceIndexPath: IndexPath, - toProposedIndexPath proposedDestinationIndexPath: IndexPath) - -> IndexPath { - return proposedDestinationIndexPath - } -} - -extension TableViewDelegate { - public func tableView(_ tableView: TableView, - didEndDisplaying cell: TableViewCell, - forRowAt indexPath: IndexPath) { - } - - public func tableView(_ tableView: TableView, - didEndDisplayingHeaderView view: View, - forSection section: Int) { - } - - public func tableView(_ tableView: TableView, - didEndDisplayingFooterView view: View, - forSection section: Int) { - } -} - -extension TableViewDelegate { - public func tableView(_ tableView: TableView, - canFocusRowAt indexPath: IndexPath) -> Bool { - return true - } - - public func tableView(_ tableView: TableView, - shouldUpdateFocusIn context: TableViewFocusUpdateContext) - -> Bool { - return true - } - - public func tableView(_ tableView: TableView, - didUpdateFocusIn context: TableViewFocusUpdateContext, - with coordinator: FocusAnimationCoordinator) { - } - - public func indexPathForPreferredFocusedView(in tableView: TableView) - -> IndexPath? { - // XXX(compnerd) is this correct? - return nil - } -} diff --git a/Sources/SwiftWin32/Views and Controls/Table Views/TableViewFocusUpdateContext.swift b/Sources/SwiftWin32/Views and Controls/Table Views/TableViewFocusUpdateContext.swift deleted file mode 100644 index 6aa1a0b4..00000000 --- a/Sources/SwiftWin32/Views and Controls/Table Views/TableViewFocusUpdateContext.swift +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import struct Foundation.IndexPath - -/// A context object that provides information relevant to a specific focus -/// update from one view to another. -public class TableViewFocusUpdateContext: FocusUpdateContext { - // MARK - Locating Focusable Items in a Table View - - /// Returns the index path of the cell containing the context's previously - /// focused view. - public internal(set) var previouslyFocusedIndexPath: IndexPath? - - /// Returns the index path of the cell containing the context's next focused - /// view. - public internal(set) var nextFocusedIndexPath: IndexPath? -} diff --git a/Sources/SwiftWin32/Views and Controls/Table Views/TableViewHeaderFooterView.swift b/Sources/SwiftWin32/Views and Controls/Table Views/TableViewHeaderFooterView.swift deleted file mode 100644 index c5004e5c..00000000 --- a/Sources/SwiftWin32/Views and Controls/Table Views/TableViewHeaderFooterView.swift +++ /dev/null @@ -1,100 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import WinSDK - -#if swift(>=5.7) -import CoreGraphics -#endif - -/// A reusable view that you place at the top or bottom of a table section to -/// display additional information for that section. -public class TableViewHeaderFooterView: View { - private static let `class`: WindowClass = - WindowClass(hInst: GetModuleHandleW(nil), - name: "Swift.TableViewHeaderFooterView", - style: UInt32(CS_HREDRAW | CS_VREDRAW), - hbrBackground: GetSysColorBrush(COLOR_3DFACE), - hCursor: LoadCursorW(nil, IDC_ARROW)) - private static let style: WindowStyle = (base: 0, extended: 0) - - // MARK - Creating the View - - /// Initializes a header/footer view with the specified reuse identifier. - public init(reuseIdentifier identifier: String?) { - self.reuseIdentifier = identifier - - self.contentView = View(frame: .zero) - self.configurationState = - ViewConfigurationState(traitCollection: TraitCollection.current) - - super.init(frame: .zero, class: TableViewHeaderFooterView.class, - style: TableViewHeaderFooterView.style) - } - - // MARK - Managing View Reuse - - /// A string used to identify a reusable header or footer. - public private(set) var reuseIdentifier: String? - - /// Prepares a reusable header or footer view for reuse by the table. - public func prepareForReuse() { - } - - // MARK - Configuring the Background - - /// The current background configuration of the view. - public var backgroundConfiguration: BackgroundConfiguration? { - didSet { - if self.backgroundConfiguration != nil { - self.backgroundColor = nil - self.backgroundView = nil - } - } - } - - /// A boolean value that determines whether the view automatically updates its - /// background configuration when its state changes. - public var automaticallyUpdatesBackgroundConfiguration: Bool = true - - /// The background view of the header or footer. - public var backgroundView: View? { - didSet { - if self.backgroundView != nil { - self.backgroundConfiguration = nil - } - } - } - - // MARK - Managing the Content - - /// Retrieves a default list content configuration for the view's style. - public func defaultContentConfiguration() -> ListContentConfiguration { - fatalError("\(#function) not yet implemented") - } - - /// The current content configuration of the view. - public var contentConfiguration: ContentConfiguration? - - /// A boolean value that determines whether the view automatically updates its - /// content configuration when its state changes. - public var automaticallyUpdatesContentConfiguration: Bool = true - - /// The content view of the header or footer. - public private(set) var contentView: View - - // MARK - Managing the State - - /// The current configuration state of the view. - public private(set) var configurationState: ViewConfigurationState - - /// Informs the view to update its configuration for its current state. - public func setNeedsUpdateConfiguration() { - fatalError("\(#function) not yet implemented") - } - - /// Updates the view's configuration using the current state. - public func updateConfiguration(using state: ViewConfigurationState) { - fatalError("\(#function) not yet implemented") - } -} diff --git a/Sources/SwiftWin32/Views and Controls/TextAlignment.swift b/Sources/SwiftWin32/Views and Controls/TextAlignment.swift deleted file mode 100644 index ebb8993c..00000000 --- a/Sources/SwiftWin32/Views and Controls/TextAlignment.swift +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright © 2023 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -/// Constants that specify text alignment. -public enum TextAlignment: Int { - /// Text uses the default alignment for the current localization of the app. - case natural - /// Text is left-aligned. - case left - /// Text is right-aligned. - case right - /// Text is center-aligned. - case center - /// Text is justified. - case justified -} diff --git a/Sources/SwiftWin32/Views and Controls/TextField.swift b/Sources/SwiftWin32/Views and Controls/TextField.swift deleted file mode 100644 index e17dd14d..00000000 --- a/Sources/SwiftWin32/Views and Controls/TextField.swift +++ /dev/null @@ -1,160 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import WinSDK - -#if swift(>=5.7) -import CoreGraphics -#endif - -public protocol TextFieldDelegate: AnyObject { -} - -private let SwiftTextFieldProc: SUBCLASSPROC = { (hWnd, uMsg, wParam, lParam, uIdSubclass, dwRefData) in - let textfield: TextField! = - unsafeBitCast(dwRefData, to: AnyObject.self) as? TextField - - switch uMsg { - case UINT(WM_PAINT): - guard let placeholder = textfield.placeholder, textfield.text == nil else { - break - } - - // Get the device context with DCX_INTERSECTUPDATE before the default - // WM_PAINT event handler calls `BeginPaint`/`EndPaint` which invalidates - // the update rect and will nullify the rendering as the region is empty. - // Gerab the value from the cache to avoid interacting with the control's - // DC. - let hDC: HDC = - GetDCEx(hWnd, nil, DWORD(DCX_INTERSECTUPDATE | DCX_CACHE | DCX_CLIPCHILDREN | DCX_CLIPSIBLINGS)) - - // Invoke the default renderer - let lResult: LRESULT = DefSubclassProc(hWnd, uMsg, wParam, lParam) - - // Get the Client Rect - var rctClient: RECT = RECT() - _ = GetClientRect(hWnd, &rctClient) - - let hPrevFont = SelectObject(hDC, textfield.font?.hFont.value) - _ = SetTextColor(hDC, GetSysColor(COLOR_GRAYTEXT)) - _ = SetBkMode(hDC, TRANSPARENT) - - _ = DrawTextW(hDC, placeholder.wide, -1, &rctClient, - UINT(DT_EDITCONTROL | DT_NOCLIP | DT_NOPREFIX | DT_SINGLELINE | DT_VCENTER)) - - _ = SelectObject(hDC, hPrevFont) - - _ = ReleaseDC(hWnd, hDC) - - return lResult - default: - break - } - - return DefSubclassProc(hWnd, uMsg, wParam, lParam) -} - -public class TextField: Control { - private static let `class`: WindowClass = WindowClass(named: MSFTEDIT_CLASS) - private static let style: WindowStyle = - (base: WS_BORDER | WS_POPUP | WS_TABSTOP | DWORD(ES_AUTOHSCROLL), - extended: 0) - - public weak var delegate: TextFieldDelegate? - - /// Accessing the Text Attributes - @_Win32WindowText - public var text: String? - - public var placeholder: String? - - public override var font: Font? { - get { return super.font } - set(value) { super.font = value } - } - - public var textAlignment: TextAlignment { - get { - var pfFormat: PARAFORMAT = PARAFORMAT() - pfFormat.cbSize = UINT(MemoryLayout.size) - pfFormat.dwMask = DWORD(PFM_ALIGNMENT) - - _ = withUnsafePointer(to: &pfFormat) { - SendMessageW(self.hWnd, UINT(EM_GETPARAFORMAT), 0, - LPARAM(Int(bitPattern: $0))) - } - - switch pfFormat.wAlignment { - case WORD(PFA_LEFT): return .left - case WORD(PFA_RIGHT): return .right - case WORD(PFA_CENTER): return .center - case WORD(PFA_JUSTIFY): return .justified - default: - fatalError("unknown alignment `\(pfFormat.wAlignment)`") - } - } - set(value) { - var pfFormat: PARAFORMAT = PARAFORMAT() - pfFormat.cbSize = UINT(MemoryLayout.size) - pfFormat.dwMask = DWORD(PFM_ALIGNMENT) - - switch value { - case .natural: - fatalError("do not know how to render `\(value)` text") - case .left: pfFormat.wAlignment = WORD(PFA_LEFT) - case .right: pfFormat.wAlignment = WORD(PFA_RIGHT) - case .center: pfFormat.wAlignment = WORD(PFA_CENTER) - case .justified: pfFormat.wAlignment = WORD(PFA_JUSTIFY) - } - - _ = withUnsafePointer(to: &pfFormat) { - SendMessageW(self.hWnd, UINT(EM_SETPARAFORMAT), 0, - LPARAM(Int(bitPattern: $0))) - } - } - } - - public init(frame: Rect) { - super.init(frame: frame, class: TextField.class, style: TextField.style) - - // Remove the `WS_EX_CLIENTEDGE` which gives it a flat appearance - self.GWL_EXSTYLE &= ~WS_EX_CLIENTEDGE - - // Enable the advanced typography options unconditionally rather than only - // in complex scripts and math mode. - SendMessageW(self.hWnd, UINT(EM_SETTYPOGRAPHYOPTIONS), - WPARAM(TO_ADVANCEDTYPOGRAPHY), LPARAM(TO_ADVANCEDTYPOGRAPHY)) - - SetWindowSubclass(self.hWnd, SwiftTextFieldProc, UINT_PTR(1), - unsafeBitCast(self as AnyObject, to: DWORD_PTR.self)) - } - - // ContentSizeCategoryAdjusting - public var adjustsFontForContentSizeCategory = false - - // TraitEnvironment - override public func traitCollectionDidChange(_ previousTraitCollection: TraitCollection?) { - super.traitCollectionDidChange(previousTraitCollection) - guard self.adjustsFontForContentSizeCategory else { return } - self.font = FontMetrics.default.scaledFont(for: self.font!, - compatibleWith: traitCollection) - } -} - -extension TextField: TextInputTraits { - public var isSecureTextEntry: Bool { - get { - SendMessageW(self.hWnd, UINT(EM_GETPASSWORDCHAR), 0, 0) == 0 - ? false - : true - } - set { - // 0x25cf is "BLACK CIRCLE" - _ = SendMessageW(self.hWnd, UINT(EM_SETPASSWORDCHAR), - WPARAM(newValue ? 0x25cf : 0), 0) - } - } -} - -extension TextField: ContentSizeCategoryAdjusting { -} diff --git a/Sources/SwiftWin32/Views and Controls/TextView.swift b/Sources/SwiftWin32/Views and Controls/TextView.swift deleted file mode 100644 index 96e73d78..00000000 --- a/Sources/SwiftWin32/Views and Controls/TextView.swift +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import WinSDK -import Foundation - -#if swift(>=5.7) -import CoreGraphics -#endif - -// FIXME(compnerd) we would like this to derive from ScrollView -public class TextView: View { - private static let `class`: WindowClass = WindowClass(named: MSFTEDIT_CLASS) - private static let style: WindowStyle = - (base: WS_BORDER | WS_HSCROLL | WS_POPUP | WS_TABSTOP | WS_VSCROLL | DWORD(ES_MULTILINE), - extended: 0) - - public var editable: Bool { - get { - self.GWL_STYLE & ES_READONLY == ES_READONLY - } - set(editable) { - SendMessageW(hWnd, UINT(EM_SETREADONLY), editable ? 0 : 1, 0) - } - } - - public override var font: Font? { - get { return super.font } - set(value) { super.font = value } - } - - @_Win32WindowText - public var text: String? - - public init(frame: Rect) { - super.init(frame: frame, class: TextView.class, style: TextView.style) - - // Remove the `WS_EX_CLIENTEDGE` which gives it a flat appearance - self.GWL_EXSTYLE &= ~WS_EX_CLIENTEDGE - - // Disable compatibility with the original Rich Edit and use the extended - // text limit. - _ = SendMessageW(self.hWnd, UINT(EM_EXLIMITTEXT), WPARAM(0), LPARAM(-1)) - } - - public func scrollRangeToVisible(_ range: NSRange) { - SendMessageW(hWnd, UINT(EM_SETSEL), WPARAM(range.location), - LPARAM(range.location + range.length)) - SendMessageW(hWnd, UINT(EM_SETSEL), UInt64(bitPattern: -1), -1) - SendMessageW(hWnd, UINT(EM_SCROLLCARET), 0, 0) - } - - // ContentSizeCategoryAdjusting - public var adjustsFontForContentSizeCategory = false - - // TraitEnvironment - override public func traitCollectionDidChange(_ previousTraitCollection: TraitCollection?) { - super.traitCollectionDidChange(previousTraitCollection) - guard self.adjustsFontForContentSizeCategory else { return } - self.font = FontMetrics.default.scaledFont(for: self.font!, - compatibleWith: traitCollection) - } -} - -extension TextView: ContentSizeCategoryAdjusting { -} diff --git a/Sources/SwiftWin32/Views and Controls/View.swift b/Sources/SwiftWin32/Views and Controls/View.swift deleted file mode 100644 index b5514567..00000000 --- a/Sources/SwiftWin32/Views and Controls/View.swift +++ /dev/null @@ -1,1229 +0,0 @@ -// Copyright © 2019 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import WinSDK - -#if swift(>=5.7) -import CoreGraphics -#endif - -extension View { - internal func interaction() -> InteractionType? { - // TODO: how do we handle overlapping entries in the `interactions` array? - if let interaction = interactions.first(where: { $0 is InteractionType }) { - return interaction as? InteractionType - } - return nil - } -} - -private let SwiftViewProc: SUBCLASSPROC = { (hWnd, uMsg, wParam, lParam, uIdSubclass, dwRefData) in - let view: View? = unsafeBitCast(dwRefData, to: AnyObject.self) as? View - - switch uMsg { - case UINT(WM_CONTEXTMENU): - guard let view = view, - let interaction: ContextMenuInteraction = view.interaction() else { - break - } - - // Clear any existing menu. - view.hMenu = nil - - let x = LOWORD(lParam), y = HIWORD(lParam) - if let actions = interaction.delegate? - .contextMenuInteraction(interaction, - configurationForMenuAtLocation: Point(x: x, y: y))? - .actionProvider?([]) { - } - let position: Point = interaction.location(in: view) - _ = TrackPopupMenu(view.hMenu?.value, UINT(TPM_RIGHTBUTTON), - Int32(x), Int32(y), 0, view.hWnd, nil) - - return 0 - - case UINT(WM_ERASEBKGND): - guard let view = view, let brush = view.hbrBackground else{ break } - - let hDC: DeviceContextHandle = - .init(referencing: HDC(bitPattern: UInt(wParam))) - - var rc: RECT = RECT() - _ = GetClientRect(view.hWnd, &rc) - _ = FillRect(hDC.value, &rc, brush.value) - - return 1 - - case UINT(WM_COMMAND): - // TODO: handle menu actions - break - - default: - break - } - - return DefSubclassProc(hWnd, uMsg, wParam, lParam) -} - -internal typealias WindowStyle = (base: DWORD, extended: DWORD) - -private func ClientToWindow(size: inout Size, for style: WindowStyle) { - var r: RECT = - RECT(left: 0, top: 0, right: LONG(size.width), bottom: LONG(size.height)) - if !AdjustWindowRect(&r, style.base, false) { - log.warning("AdjustWindowRectExForDpi: \(Error(win32: GetLastError()))") - } - size = Size(width: Double(r.right - r.left), height: Double(r.bottom - r.top)) -} - -private func WindowBasedTransform(for view: View?) -> AffineTransform { - guard var view = view else { return .identity } - - var transform = AffineTransform.identity - while let superview = view.superview { - // Create a single transform that places this view in the coordinate - // space of the view furthest up in its tree. - transform = transform - .concatenating(AffineTransform(translationX: -view.bounds.center.x, - y: -view.bounds.center.y)) - .concatenating(view.transform) - .concatenating(AffineTransform(translationX: view.center.x, - y: view.center.y)) - view = superview - } - return transform -} - -extension View { - /// Options to specify how a view adjusts its content when its size changes. - public enum ContentMode: Int { - /// Scale the content to fit the size of itself by changing the aspect ratio - /// of the content if necessary. - case scaleToFill - - /// Scale the content to fit the size of the view by maintaining the aspect - /// ratio. Any remaining area of the view's bounds is transparent. - case scaleAspectFill - - /// Scale the content to fill the size of the view. Some portion of the - /// content may be clipped to fill the view's bounds. - case redraw - - /// center the content in the view's bounds, keeping the proportions the - /// same. - case center - - /// Center the content aligned to the top in the view's bounds. - case top - - /// Center the content aligned at the bottom in the view's bounds. - case bottom - - /// Align the content on the left of the view. - case left - - /// Align the content on the right of the view. - case right - - /// Align the content in the top-left corner of the view. - case topLeft - - /// Align the content in the top-right corner of the view. - case topRight - - /// Align the content in the bottom-left corner of the view. - case bottomLeft - - /// Align the content in the bottom-right corner of the view. - case bottomRight - } -} - -extension View { - /// Options for animating views using block objects. - public struct AnimationOptions: OptionSet { - public typealias RawValue = UInt - - public let rawValue: RawValue - - public init(rawValue: RawValue) { - self.rawValue = rawValue - } - } -} - -extension View.AnimationOptions { - /// Lay out subviews at commit time so that they are animated along with their - /// parent. - public static var layoutSubviews: View.AnimationOptions { - View.AnimationOptions(rawValue: 1 << 0) - } - - /// Allow the user to interact with views while they are being animated. - public static var allowUserInteraction: View.AnimationOptions { - View.AnimationOptions(rawValue: 1 << 1) - } - - /// Start the animation from the current setting associated with an already - /// in-flight animation. - /// - /// If this key is not present, all in-flight animations are allowed to finish - /// before the new animation is started. If another animation is not in - /// flight, this key has no effect. - public static var beginFromCurrentState: View.AnimationOptions { - View.AnimationOptions(rawValue: 1 << 2) - } - - /// Repeat the animation indefinitely. - public static var `repeat`: View.AnimationOptions { - View.AnimationOptions(rawValue: 1 << 3) - } - - /// Run the animation backwards and forwards (must be combined with the repeat - /// option). - public static var autoreverse: View.AnimationOptions { - View.AnimationOptions(rawValue: 1 << 4) - } - - /// Force the animation to use the original duration value specified when the - /// animation was submitted. - public static var overrideInheritedDuration: View.AnimationOptions { - View.AnimationOptions(rawValue: 1 << 5) - } - - /// Force the animation to use the original curve value specified when the - /// animation was submitted. - /// - /// If this key is not present, the animation inherits the curve of the - /// in-flight animation, if any. - public static var overrideInheritedCurve: View.AnimationOptions { - View.AnimationOptions(rawValue: 1 << 6) - } - - /// Animate the views by changing the property values dynamically and - /// redrawing the view. - public static var allowAnimatedContent: View.AnimationOptions { - View.AnimationOptions(rawValue: 1 << 7) - } - - /// Hide or show views during a view transition. - /// - /// When present, this key causes views to be hidden or shown (instead of - /// removed or added) when performing a view transition. Both views must - /// already be present in the parent view's hierarchy when using this key. If - /// this key is not present, the to-view in a transition is added to, and the - /// from-view is removed from, the parent view's list of subviews. - public static var showHideTransitionViews: View.AnimationOptions { - View.AnimationOptions(rawValue: 1 << 8) - } - - /// The option to not inherit the animation type or any options. - public static var overrideInheritedOptions: View.AnimationOptions { - View.AnimationOptions(rawValue: 1 << 9) - } - - /// Specify an ease-in ease-out curve, which causes the animation to begin - /// slowly, accelerate through the middle of its duration, and then slow again - /// before completing. - public static var curveEaseInOut: View.AnimationOptions { - View.AnimationOptions(rawValue: 0 << 16) - } - - /// An ease-in curve causes the animation to begin slowly, and then speed up - /// as it progresses. - public static var curveEaseIn: View.AnimationOptions { - View.AnimationOptions(rawValue: 1 << 16) - } - - /// An ease-out curve causes the animation to begin quickly, and then slow as - /// it completes. - public static var curveEaseOut: View.AnimationOptions { - View.AnimationOptions(rawValue: 2 << 16) - } - - /// A linear animation curve causes an animation to occur evenly over its - /// duration. - public static var curveLinear: View.AnimationOptions { - View.AnimationOptions(rawValue: 3 << 16) - } - - internal static var transitionNone: View.AnimationOptions { - View.AnimationOptions(rawValue: 0 << 20) - } - - /// A transition that flips a view around its vertical axis from left to right - /// (the left side of the view moves toward the front and right side toward - /// the back). - public static var transitionFlipFromLeft: View.AnimationOptions { - View.AnimationOptions(rawValue: 1 << 20) - } - - /// A transition that flips a view around its vertical axis from right to left - /// (the right side of the view moves toward the front and left side toward - /// the back). - public static var transitionFlipFromRight: View.AnimationOptions { - View.AnimationOptions(rawValue: 2 << 20) - } - - /// A transition that curls a view up from the bottom. - public static var transitionCurlUp: View.AnimationOptions { - View.AnimationOptions(rawValue: 3 << 20) - } - - /// A transition that curls a view down from the top. - public static var transitionCurlDown: View.AnimationOptions { - View.AnimationOptions(rawValue: 4 << 20) - } - - /// A transition that dissolves from one view to the next. - public static var transitionCrossDissolve: View.AnimationOptions { - View.AnimationOptions(rawValue: 5 << 20) - } - - /// A transition that flips a view around its horizontal axis from top to - /// bottom (the top side of the view moves toward the front and the bottom - /// side toward the back). - public static var transitionFlipFromTop: View.AnimationOptions { - View.AnimationOptions(rawValue: 6 << 20) - } - - internal static var preferredFramesPersSecondDefault: View.AnimationOptions { - View.AnimationOptions(rawValue: 0 << 24) - } - - /// A frame rate of 30 frames per second. - /// - /// Specify this value to request a preferred frame rate. It's recommended - /// that you use the default value unless you have identified a specific need - /// for an explicit rate. - public static var preferredFramesPerSecond30: View.AnimationOptions { - View.AnimationOptions(rawValue: 7 << 24) - } - - /// A frame rate of 60 frames per second. - /// - /// Specify this value to request a preferred frame rate. It's recommended - /// that you use the default value unless you have identified a specific need - /// for an explicit rate. - public static var preferredFramesPerSecond60: View.AnimationOptions { - View.AnimationOptions(rawValue: 3 << 24) - } -} - -extension View { - /// Options for automatic view resizing. - public struct AutoresizingMask: OptionSet { - public let rawValue: UInt - - public init(rawValue: UInt) { - self.rawValue = rawValue - } - } -} - -extension View.AutoresizingMask { - public static var none: View.AutoresizingMask { - View.AutoresizingMask(rawValue: 0 << 0) - } - - /// Resizing performed by expanding or shrinking a view in the direction of - /// the left margin. - public static var flexibleLeftMargin: View.AutoresizingMask { - View.AutoresizingMask(rawValue: 1 << 0) - } - - /// Resizing performed by expanding or shrinking a view's width. - public static var flexibleWidth: View.AutoresizingMask { - View.AutoresizingMask(rawValue: 1 << 1) - } - - /// Resizing performed by expanding or shrinking a view in the direction of - /// the right margin. - public static var flexibleRightMargin: View.AutoresizingMask { - View.AutoresizingMask(rawValue: 1 << 2) - } - - /// Resizing performed by expanding or shrinking a view in the direction of - /// the top margin. - public static var flexibleTopMargin: View.AutoresizingMask { - View.AutoresizingMask(rawValue: 1 << 3) - } - - /// Resizing performed by expanding or shrinking a view's height. - public static var flexibleHeight: View.AutoresizingMask { - View.AutoresizingMask(rawValue: 1 << 4) - } - - /// Resizing performed by expanding or shrinking a view in the direction of - /// the bottom margin. - public static var flexibleBottomMargin: View.AutoresizingMask { - View.AutoresizingMask(rawValue: 1 << 5) - } -} - -extension View { - /// Specifies the supported animation curves. - public enum AnimationCurve: Int { - /// An ease-in ease-out curve causes the animation to begin slowly, - /// accelerate through the middle of its duration, and then slow again - /// before completing. This is the default curve for most animations. - case easeInOut - - /// An ease-in curve causes the animation to begin slowly, and then speed up - /// as it progresses. - case easeIn - - /// An ease-out curve causes the animation to begin quickly, and then slow - /// down as it completes. - case easeOut - - /// A linear animation curve causes an animation to occur evenly over its - /// duration. - case linear - } -} - -extension View { - /// The tint adjustment mode for the view. - public enum TintAdjustmentMode: Int { - /// The tint adjustment mode of the view is the same as its superview's tint - /// adjustment mode (or `ViewTintAdjustmentModeNormal` if the view has no - /// superview). - case automatic - - /// The view's tintColor property returns the completely unmodified tint - /// color of the view. - case normal - - /// The view's `tintColor` property returns a desaturated, dimmed version - /// of the view's original tint color. - case dimmed - } -} - -/// An object that manages the content for a rectangular area on the screen. -public class View: Responder { - private static let `class`: WindowClass = - WindowClass(hInst: GetModuleHandleW(nil), name: "Swift.View", - style: UInt32(CS_HREDRAW | CS_VREDRAW), - hbrBackground: GetSysColorBrush(COLOR_3DFACE), - hCursor: LoadCursorW(nil, IDC_ARROW)) - private static let style: WindowStyle = (base: 0, extended: 0) - - internal var hWnd: HWND! - internal var WndClass: WindowClass - - internal var GWL_STYLE: LONG { - get { GetWindowLongW(self.hWnd, WinSDK.GWL_STYLE) } - set { _ = SetWindowLongW(self.hWnd, WinSDK.GWL_STYLE, newValue) } - } - - internal var GWL_EXSTYLE: LONG { - get { GetWindowLongW(self.hWnd, WinSDK.GWL_EXSTYLE) } - set { _ = SetWindowLongW(self.hWnd, WinSDK.GWL_EXSTYLE, newValue) } - } - - internal var font: Font? { - didSet { - SendMessageW(self.hWnd, UINT(WM_SETFONT), - unsafeBitCast(self.font?.hFont.value, to: WPARAM.self), - LPARAM(1)) - } - } - - internal var hMenu: MenuHandle? - - // MARK - Creating a View Object - - // FIXME(compnerd) should this be marked as a convenience initializer? - - /// Initializes and returns a newly allocated view object with the specified - /// frame rectangle. - public convenience init(frame: Rect) { - self.init(frame: frame, class: View.class, style: View.style) - } - - internal init(frame: Rect, `class`: WindowClass, style: WindowStyle, - parent: HWND? = nil) { - self.WndClass = `class` - _ = self.WndClass.register() - - let bOverlappedWindow: Bool = - style.base & DWORD(WS_OVERLAPPEDWINDOW) == DWORD(WS_OVERLAPPEDWINDOW) - - var client: Rect = frame - - // Convert client area to window rect - ClientToWindow(size: &client.size, for: style) - - // TODO(compnerd) Convert client rect into display units - - // Only request the window size, not the location, the location will be - // mapped when reparenting. - self.hWnd = - CreateWindowExW(style.extended, self.WndClass.name, nil, style.base, - Int32(bOverlappedWindow ? client.origin.x : 0), - Int32(bOverlappedWindow ? client.origin.y : 0), - Int32(client.size.width), - Int32(client.size.height), - parent, nil, GetModuleHandleW(nil), nil)! - - // If `CW_USEDEFAULT` was used, query the actual allocated rect - if frame.origin.x == Double(CW_USEDEFAULT) || - frame.size.width == Double(CW_USEDEFAULT) { - var r: RECT = RECT() - if !GetClientRect(self.hWnd, &r) { - log.warning("GetClientRect: \(Error(win32: GetLastError()))") - } - _ = withUnsafeMutablePointer(to: &r) { [hWnd = self.hWnd] in - $0.withMemoryRebound(to: POINT.self, capacity: 2) { - MapWindowPoints(hWnd, nil, $0, 2) - } - } - client = Rect(from: r) - } - - // Scale window for DPI - client = client.scaled(for: GetDpiForWindow(self.hWnd), style: style) - - // Resize and Position the Window - SetWindowPos(self.hWnd, nil, - CInt(client.origin.x), CInt(client.origin.y), - CInt(client.size.width), CInt(client.size.height), - UINT(SWP_NOZORDER | SWP_FRAMECHANGED)) - - self.frame = frame - self.bounds = Rect(origin: .zero, size: client.size) - - super.init() - - _ = SetWindowSubclass(self.hWnd, SwiftViewProc, UINT_PTR.max, - unsafeBitCast(self as AnyObject, to: DWORD_PTR.self)) - - if !RegisterTouchWindow(self.hWnd, 0) { - log.error("RegisterTouchWindow: \(Error(win32: GetLastError()))") - } - - defer { self.font = Font.systemFont(ofSize: Font.systemFontSize) } - } - - deinit { - _ = UnregisterTouchWindow(self.hWnd) - _ = DestroyWindow(self.hWnd) - _ = self.WndClass.unregister() - } - - // MARK - Configuring a View's Visual Appearance - - internal var hbrBackground: BrushHandle? - - /// The view's background color. - public var backgroundColor: Color? { - didSet { - switch self.backgroundColor { - case .some(let color): - self.hbrBackground = .init(owning: CreateSolidBrush(color.COLORREF)) - case .none: - self.hbrBackground = nil - } - } - } - - /// A boolean that determines if the view is hidden. - public var isHidden: Bool { - get { IsWindowVisible(self.hWnd) } - set(hidden) { - let pEnumFunc: WNDENUMPROC = { (hWnd, lParam) -> WindowsBool in - ShowWindow(hWnd, CInt(lParam)) - return true - } - _ = EnumChildWindows(self.hWnd, pEnumFunc, - LPARAM(hidden ? SW_HIDE : SW_RESTORE)) - ShowWindow(self.hWnd, hidden ? SW_HIDE : SW_RESTORE) - } - } - - // MARK - Configuring the Event-Related Behaviour - - /// A boolean value that determines whether user events are ignored and removed - /// from the event queue. - public var isUserInteractionEnabled: Bool { - get { return IsWindowEnabled(self.hWnd) } - set { _ = EnableWindow(self.hWnd, newValue) } - } - - // MARK - Configuring the Bounds and Frame Rectangles - - /// The frame rectangle, which describes the view's location and size in it's - /// superview's coordinate system. - public var frame: Rect { - didSet { - // Scale window for DPI - let client: Rect = - self.frame.scaled(for: GetDpiForWindow(self.hWnd), - style: WindowStyle(DWORD(bitPattern: self.GWL_STYLE), - DWORD(bitPattern: self.GWL_EXSTYLE))) - - // Resize and Position the Window - _ = SetWindowPos(self.hWnd, nil, - CInt(client.origin.x), CInt(client.origin.y), - CInt(client.size.width), CInt(client.size.height), - UINT(SWP_NOZORDER | SWP_FRAMECHANGED)) - } - } - - /// The bounds rectangle, which describes the view's location and size in its - /// own coordinate system. - public var bounds: Rect { - didSet { -#if !ENABLE_TESTING - fatalError("\(#function) not yet implemented") -#endif - } - } - - /// The center point of the view's frame rectangle - public var center: Point { - get { return Point(x: self.frame.midX, y: self.frame.midY) } - set { self.frame = Rect(origin: Point(x: self.frame.origin.x - newValue.x, - y: self.frame.origin.y - newValue.y), - size: self.frame.size) } - } - - /// Specifies the transform applied to the view, relative to the center of its - /// bounds. - public var transform: AffineTransform = .identity { - didSet { -#if !ENABLE_TESTING - fatalError("\(#function) not yet implemented") -#endif - } - } - - // MARK - Managing the View Hierarchy - - /// The receiver's superview, or `nil` if it has none. - public private(set) weak var superview: View? - - /// The receiver's immediate subviews. - public private(set) var subviews: [View] = [] - - /// The receiver's window object, or `nil` if it has none. - public private(set) weak var window: Window? - - /// Add a subview to the end of the reciever's list of subviews. - public func addSubview(_ view: View) { - self.insertSubview(view, at: self.subviews.endIndex) - } - - /// Moves the specified subview so that it appears on top of its siblings. - public func bringSubviewToFront(_ view: View) { - if let index = self.subviews.firstIndex(of: view) { - self.subviews.append(self.subviews.remove(at: index)) - } - } - - /// Moves the specified subview so that it appears behind its siblings. - public func sendSubviewToBack(_ view: View) { - if let index = self.subviews.lastIndex(of: view) { - self.subviews.insert(self.subviews.remove(at: index), - at: self.subviews.startIndex) - } - } - - /// Unlinks the view from its superview and its window, and removes it from - /// the responder chain. - public func removeFromSuperview() { - guard let superview = self.superview else { return } - - self.willMove(toSuperview: nil) - - superview.willRemoveSubview(self) - - // Reparent the window. - guard let _ = SetParent(self.hWnd, nil) else { - log.warning("SetParent: \(Error(win32: GetLastError()))") - return - } - - // Update the Window style. - self.GWL_STYLE &= ~LONG(bitPattern: WS_POPUP | WS_CAPTION) - self.GWL_STYLE &= ~LONG(WS_CHILD) - // FIXME(compnerd) can this be avoided somehow? - if self is TextField || self is TextView || self is TableView { - self.GWL_STYLE |= WinSDK.WS_BORDER - self.GWL_EXSTYLE &= ~WS_EX_CLIENTEDGE - } - - // We *must* call `SetWindowPos` after the `SetWindowLong` to have the - // changes take effect. - if !SetWindowPos(self.hWnd, nil, 0, 0, 0, 0, - UINT(SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED)) { - log.warning("SetWindowPos: \(Error(win32: GetLastError()))") - } - - self.superview = nil - - if let index = superview.subviews.firstIndex(of: self) { - superview.subviews.remove(at: index) - } - - self.didMoveToSuperview() - } - - /// Inserts a subview at the specified index. - public func insertSubview(_ view: View, at index: Int) { - // Notify the view that it is about to be reparented. - view.willMove(toSuperview: self) - - // Notify the old parent that it is about to loose the child. - view.superview?.willRemoveSubview(view) - - // Reparent the window. - guard let _ = SetParent(view.hWnd, self.hWnd) else { - log.warning("SetParent: \(Error(win32: GetLastError()))") - return - } - - // MSDN: - // For compatibility reasons, `SetParent` does not modify the `WS_CHILD` or - // `WS_POPUP` window styles of the window whose parent is being changed. - // Therefore, if `hWndNewParent` is `NULL`, you should also clear the - // `WS_CHILD` bit and set the `WS_POPUP` style after calling `SetParent`. - // Conversely, if `hWndNewParent` is not `NULL` and the window was - // previously a child of the desktop, you should clear the `WS_POPUP` style - // and set the `WS_CHILD` style before calling `SetParent`. - // - // When you change the parent, you should synchronize the `UISTATE` of both - // windows. For more information, see `WM_CHANGEUISTATE` and - // `WM_UPDATEUISTATE`. - - // Update the window style. - view.GWL_STYLE &= ~LONG(bitPattern: WS_POPUP | WS_CAPTION) - view.GWL_STYLE |= LONG(WS_CHILD) - // FIXME(compnerd) can this be avoided somehow? - if view is TextField || view is TextView || view is TableView { - view.GWL_STYLE |= WinSDK.WS_BORDER - view.GWL_EXSTYLE &= ~WS_EX_CLIENTEDGE - } - - // We *must* call `SetWindowPos` after the `SetWindowLong` to have the - // changes take effect. - if !SetWindowPos(view.hWnd, nil, 0, 0, 0, 0, - UINT(SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED)) { - log.warning("SetWindowPos: \(Error(win32: GetLastError()))") - } - - // Scale window for DPI - let style: WindowStyle = - WindowStyle(DWORD(bitPattern: view.GWL_STYLE), - DWORD(bitPattern: view.GWL_EXSTYLE)) - - let client: Rect = - view.frame.scaled(for: GetDpiForWindow(view.hWnd), style: style) - - // Resize and Position the Window - _ = SetWindowPos(view.hWnd, nil, - CInt(client.origin.x), CInt(client.origin.y), - CInt(client.size.width), CInt(client.size.height), - UINT(SWP_NOZORDER | SWP_FRAMECHANGED)) - - view.superview = self - self.subviews.insert(view, at: index) - - // Notify any subclassed types for observation. - self.didAddSubview(view) - - // Notify the view that it has been reparented. - view.didMoveToSuperview() - } - - /// Inserts a view above another view in the view hierarchy. - public func insertSubview(_ view: View, aboveSubview subview: View) { - let index: Array.Index - if let offset = self.subviews.firstIndex(of: subview) { - index = self.subviews.index(after: offset) - } else { - index = self.subviews.endIndex - } - self.insertSubview(view, at: index) - } - - /// Inserts a view below another view in the view hierarchy. - public func insertSubview(_ view: View, belowSubview subview: View) { - let index: Array.Index - if let offset = self.subviews.firstIndex(of: subview) { - index = self.subviews.index(before: offset) - } else { - index = self.subviews.endIndex - } - self.insertSubview(view, at: index) - } - - /// Exchanges the subviews at the specified indices. - public func exchangeSubview(at index1: Int, withSubviewAt index2: Int) { - self.subviews.swapAt(self.subviews.index(self.subviews.startIndex, - offsetBy: index1), - self.subviews.index(self.subviews.startIndex, - offsetBy: index2)) - } - - /// Returns a boolean value indicating whether the receiver is a subview of a - /// given view or identical to that view. - public func isDescendant(of view: View) -> Bool { - var parent: View? = self - while parent != nil { - if parent == view { return true } - parent = parent?.superview - } - return false - } - - // MARK - Observing View-Related Changes - - /// Informs the view that a subview was added. - public func didAddSubview(_ subview: View) { - } - - /// Informs the view that a subview is about to be removed. - public func willRemoveSubview(_ subview: View) { - } - - /// Informs the view that its superview is about to change to the specified - /// superview. - public func willMove(toSuperview: View?) { - } - - /// Informs the view that its superview changed. - public func didMoveToSuperview() { - } - - /// Informs the view that its window object is about to change. - public func willMove(toWindow: Window?) { - } - - /// Informs the view that its window object changed. - public func didMoveToWindow() { - } - - // MARK - Configuring Content Margins - - /// The default spacing to use when laying out content in a view, taking into - /// account the current language direction. - public var directionalLayoutMargins: DirectionalEdgeInsets = - DirectionalEdgeInsets(top: 8.0, leading: 8.0, bottom: 8.0, trailing: 8.0) { - didSet { - self.layoutMarginsDidChange() - } - } - - /// A boolean value indicating whether the current view also respects the - /// margins of its superview. - public var preservesSuperviewLayoutMargins: Bool = false - - /// Informs the view that its layout margins changed. - public func layoutMarginsDidChange() { - } - - // MARK - Managing the View's Constraints - - /// The constraints held by the view. - public private(set) var constraints: [LayoutConstraint] = [] - - /// Adds a constraint on the layout of the receiving view or its subviews. - public func addConstraint(_ constraint: LayoutConstraint) { - } - - /// Removes the specified constraint from the view. - public func removeConstraint(_ constraint: LayoutConstraint) { - } - - /// Removes the specified constraints from the view. - public func removeConstraints(_ constraints: [LayoutConstraint]) { - } - - // MARK - Create Constraint Using Layout Constraint - - /// A layout anchor representing the bottom edge of the view's frame. - public var bottomAnchor: LayoutYAxisAnchor { - LayoutYAxisAnchor(item: self, attribute: .bottom) - } - - /// A layout anchor representing the horizontal center of the view's frame. - public var centerXAnchor: LayoutXAxisAnchor { - LayoutXAxisAnchor(item: self, attribute: .centerX) - } - - /// A layout anchor representing the vertical center of the view's frame. - public var centerYAnchor: LayoutYAxisAnchor { - LayoutYAxisAnchor(item: self, attribute: .centerY) - } - - /// A layout anchor representing the baseline for the topmost line of text in - /// the view. - public var firstBaselineAnchor: LayoutYAxisAnchor { - LayoutYAxisAnchor(item: self, attribute: .firstBaseline) - } - - /// A layout anchor representing the height of the view's frame. - public var heightAnchor: LayoutDimension { - LayoutDimension(item: self, attribute: .height) - } - - /// A layout anchor representing the baseline for the bottommost line of text - /// in the view. - public var lastBaselineAnchor: LayoutYAxisAnchor { - LayoutYAxisAnchor(item: self, attribute: .lastBaseline) - } - - /// A layout anchor representing the leading edge of the view's frame. - public var leadingAnchor: LayoutXAxisAnchor { - LayoutXAxisAnchor(item: self, attribute: .leading) - } - - /// A layout anchor representing the left edge of the view's frame. - public var leftAnchor: LayoutXAxisAnchor { - LayoutXAxisAnchor(item: self, attribute: .left) - } - - /// A layout anchor representing the right edge of the view's frame. - public var rightAnchor: LayoutXAxisAnchor { - LayoutXAxisAnchor(item: self, attribute: .right) - } - - /// A layout anchor representing the top edge of the view's frame. - public var topAnchor: LayoutYAxisAnchor { - LayoutYAxisAnchor(item: self, attribute: .top) - } - - /// A layout anchor representing the top edge of the view's frame. - public var trailingAnchor: LayoutXAxisAnchor { - LayoutXAxisAnchor(item: self, attribute: .trailing) - } - - /// A layout anchor representing the trailing edge of the view's frame. - public var widthAnchor: LayoutDimension { - LayoutDimension(item: self, attribute: .width) - } - - // MARK - Configuring the Resizing Behaviour - - // Determine how a view lays out its content when its bounds changes. - public var contentMode: View.ContentMode = .scaleToFill - - /// Asks the view to calculate and return the size that best fits the - /// specified size. - public func sizeThatFits(_ size: Size) -> Size { - return self.frame.size - } - - /// Resizes and moves the receiver view so it just encloses its subviews. - public func sizeToFit() { - fatalError("\(#function) not yet implemented") - } - - /// Determines whether the receiver automatically resizes its subviews when - /// its bounds changes. - public var autoresizesSubviews: Bool = true - - /// A bitmask that determines how the receiver resizes itself when its - /// superview's bounds changes. - public var autoresizingMask: View.AutoresizingMask = .none - - // MARK - Drawing and Updating the View - - /// Draws the receiver's image within the passed-in rectangle. - public func draw(_ rect: Rect) { - fatalError("\(#function) not yet implemented") - } - - /// Mark the receiver's entire bounds rectangle as needing to be redrawn. - public func setNeedsDisplay() { - fatalError("\(#function) not yet implemented") - } - - /// Marks the specified rectangle of the receiver as needing to be redrawn. - public func setNeedsDisplay(_ rect: Rect) { - fatalError("\(#function) not yet implemented") - } - - /// The scale factor applied to the view. - public var contentScaleFactor: Float { - get { 1.0 } - set { fatalError("\(#function) not yet implemented") } - } - - // MARK - Laying Out Subviews - - /// Lays out subviews. - /// - /// The default implementation uses any constraints you have set to determine - /// the size and position of any subviews. - /// - /// Subclasses can override this method as needed to perform more precise - /// layout of their subviews. You should override this method only if the - /// autoresizing and constraint-based behaviors of the subviews do not offer - /// the behavior you want. You can use your implementation to set the frame - /// rectangles of your subviews directly. - /// - /// You should not call this method directly. If you want to force a layout - /// update, call the `setNeedsLayout()` method instead to do so prior to the - /// next drawing update. If you want to update the layout of your views - /// immediately, call the `layoutIfNeeded()` method. - public func layoutSubviews() { - fatalError("\(#function) not yet implemented") - } - - /// Invalidates the current layout of the receiver and triggers a layout - /// update during the next update cycle. - /// - /// Call this method on your application's main thread when you want to adjust - /// the layout of a view's subviews. This method makes a note of the request - /// and returns immediately. Because this method does not force an immediate - /// update, but instead waits for the next update cycle, you can use it to - /// invalidate the layout of multiple views before any of those views are - /// updated. This behavior allows you to consolidate all of your layout - /// updates to one update cycle, which is usually better for performance. - public func setNeedsLayout() { - fatalError("\(#function) not yet implemented") - } - - /// Lays out the subviews immediately, if layout updates are pending. - /// - /// Use this method to force the view to update its layout immediately. When - /// using Auto Layout, the layout engine updates the position of views as - /// needed to satisfy changes in constraints. Using the view that receives the - /// message as the root view, this method lays out the view subtree starting - /// at the root. If no layout updates are pending, this method exits without - /// modifying the layout or calling any layout-related callbacks. - public func layoutIfNeeded() { - fatalError("\(#function) not yet implemented") - } - - /// A boolean value that indicates whether the receiver depends on the - /// constraint-based layout system. - /// - /// Custom views should override this to return true if they cannot layout - /// correctly using autoresizing. - public class var requiresConstraintBasedLayout: Bool { false } - - /// A boolean value that determines whether the view's autoresizing mask is - /// translated into Auto Layout constraints. - /// - /// If this property's value is `true`, the system creates a set of - /// constraints that duplicate the behavior specified by the view's - /// autoresizing mask. This also lets you modify the view's size and location - /// using the view's `frame`, `bounds`, or `center` properties, allowing you - /// to create a static, frame-based layout within Auto Layout. - /// - /// Note that the autoresizing mask constraints fully specify the view's size - /// and position; therefore, you cannot add additional constraints to modify - /// this size or position without introducing conflicts. If you want to use - /// Auto Layout to dynamically calculate the size and position of your view, - /// you must set this property to `false`, and then provide a non ambiguous, - /// nonconflicting set of constraints for the view. - /// - /// By default, the property is set to `true`. - public var translatesAutoresizingMaskIntoConstraints: Bool = true - - // MARK - Adding and Removing Interactions - - /// Adds an interaction to the view. - public func addInteraction(_ interaction: Interaction) { - interaction.willMove(to: self) - interaction.view?.interactions.removeAll(where: { $0 === interaction }) - interactions.append(interaction) - interaction.didMove(to: self) - } - - /// Removes an interaction from the view. - public func removeInteraction(_ interaction: Interaction) { - interaction.willMove(to: nil) - self.interactions.removeAll(where: { $0 === interaction }) - interaction.didMove(to: nil) - } - - /// The array of interactions for the view. - public var interactions: [Interaction] = [] - - // MARK - Identifying the View at Runtime - - /// An integer that you can use to identify view objects in your application. - public var tag: Int = 0 - - /// Returns the view whose tag matches the specified value. - public func viewWithTag(_ tag: Int) -> View? { - if self.tag == tag { return self } - // TODO(compnerd) this is a poor equivalent of a level-order traversal of - // the view hierachy. We could implement this properly, but, this provides - // a functional implementation that is brief and is unlikely to be a hot - // path. Convert to a proper level-order traversal. - return self.subviews.first(where: { $0.tag == tag }) ?? - self.subviews.lazy.compactMap { $0.viewWithTag(tag) }.first - } - - // MARK - Converting Between View Coordinate Systems - - /// Converts a point from the receiver’s coordinate system to that of the - /// specified view. - public func convert(_ point: Point, to view: View?) -> Point { - guard view != nil || self.window != nil else { return point } - - if let view = view { - // If the view is itself, then the point is already in the correct - // coordinate system. - if view == self { return point } - - // In the case of an immediate relation to the view, just account for the - // center offset and transform. - if let superview = self.superview, superview == view { - // `p - self.bounds.center` undos any translation done by the bounds of - // `self`. Apply the current transform to the shifted point, and then - // return the point relative to `self.center`. - - // +--- view ---+ - // | +- self -+ | - // | | p | | - // | +--------+ | - // +------------+ - - // `bounds` is in the coordinate space of self and `center` is in the - // coordinate space of the superview. In this case, the superview is - // `view`, which is the destination coordinate space. We simply map the - // transformed point p from the coordinate space of `self` into the - // destination coordinate space of `view` using `self.center`. - return (point - self.bounds.center).applying(self.transform) - + self.center - } else if let superview = view.superview, superview == self { - // `p - view.center` shifts the point relative to the center of `view` - // as seen by `self`. Invert any transformations performed by `view` on - // the point, and then return the point relative to the center of - // `view.bounds.` - - // +--- self ---+ - // | +- view -+ | - // | | p | | - // | +--------+ | - // +------------+ - - // `center` is in the coordinate space of the superview. Because `self` - // is the superview of `view`, `view.center` is in the coordinate space - // of `self`. We locate `point` in the coordinate space of `self`, undo - // any local transformation, and then relocate it in the coordinate - // space of the destination view. - return (point - view.center).applying(view.transform.inverted()) - + view.bounds.center - } - } - - return point.applying(WindowBasedTransform(for: self)) - .applying(WindowBasedTransform(for: view).inverted()) - } - - /// Converts a point from the coordinate system of a given view to that of the - /// receiver. - public func convert(_ point: Point, from view: View?) -> Point { - return view?.convert(point, to: self) - ?? self.window?.convert(point, to: self) - ?? point - } - - /// Converts a rectangle from the receiver’s coordinate system to that of - /// another view. - public func convert(_ rect: Rect, to view: View?) -> Rect { - guard view != nil || self.window != nil else { return rect } - - if let view = view { - // If the view is itself, then the point is already in the correct - // coordinate system. - if view == self { return rect } - - // In the case of an immediate relation to the view, just account for the - // center offset and transform. - if let superview = self.superview, superview == view { - // `r.offsetBy(dx: self.bounds.center.x, dy: self.bounds.center.y)` - // undos any translation done by the bounds property of `self`. Apply - // the current transform to the rect, and then return the rect relative - // to the center of `self`. - - // +--- view ---+ - // | +- self -+ | - // | | [r] | | - // | +--------+ | - // +------------+ - - // `bounds` is in the coordinate space of self and `center` is in the - // coordinate space of the superview. In this case, the superview is - // `view`, which is the destination coordinate space. We simply map the - // transformed rect r from the coordinate space of `self` into the - // destination coordinate space of `view` using `self.center`. - return rect.offsetBy(dx: -self.bounds.center.x, - dy: -self.bounds.center.y) - .applying(self.transform) - .offsetBy(dx: self.center.x, dy: self.center.y) - } else if let superview = view.superview, superview == self { - // `r.offsetBy(dx: -view.center, dy: -view.center.y)` shifts the point - // relative to the center of `view` as seen by `self`. Invert any - // transformations performed by `view` on the rect, and then return the - // rect relative to the bounds of `view`. - - // +--- self ---+ - // | +- view -+ | - // | | [r] | | - // | +--------+ | - // +------------+ - - // `center` is in the coordinate space of the superview. Because `self` - // is the superview of `view`, `view.center` is in the coordinate space - // of `self`. We locate `rect` in the coordinate space of `self`, undo - // any local transformation, and then relocate it in the coordinate - // space of the destination view. - return rect.offsetBy(dx: -view.center.x, dy: -view.center.y) - .applying(view.transform.inverted()) - .offsetBy(dx: view.bounds.center.x, dy: view.bounds.center.y) - } - } - - return rect.applying(WindowBasedTransform(for: self)) - .applying(WindowBasedTransform(for: view).inverted()) - } - - /// Converts a rectangle from the coordinate system of another view to that of - /// the receiver. - public func convert(_ rect: Rect, from view: View?) -> Rect { - return view?.convert(rect, to: self) - ?? self.window?.convert(rect, to: self) - ?? rect - } - - // MARK - Responder Chain - - public override var next: Responder? { - // If the view is the root view of a `ViewController`, the next responder is - // the view controller; otherwise, the next responder is the view's - // superview. - - // FIXME(compnerd) how do we determine if we are the root view of a view - // controller? - return self.superview - } - - // MARK - Trait Environment - - // NOTE: this must be in the class to permit deviced types to override the - // notification. - public func traitCollectionDidChange(_ previousTraitCollection: TraitCollection?) { - } -} - -extension View: Equatable { - public static func ==(_ lhs: View, _ rhs: View) -> Bool { - return lhs.hWnd == rhs.hWnd - } -} - -extension View: TraitEnvironment { - public var traitCollection: TraitCollection { - return self.window?.windowScene?.screen.traitCollection ?? TraitCollection.current - } -} diff --git a/Sources/SwiftWin32/Views and Controls/VisualEffect.swift b/Sources/SwiftWin32/Views and Controls/VisualEffect.swift deleted file mode 100644 index 67b388e0..00000000 --- a/Sources/SwiftWin32/Views and Controls/VisualEffect.swift +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -/// An initializer for visual effect views and blur and vibrancy effect objects. -public class VisualEffect { -} diff --git a/Sources/SwiftWin32/Windows and Screens/AlertAction.swift b/Sources/SwiftWin32/Windows and Screens/AlertAction.swift deleted file mode 100644 index 5bd47953..00000000 --- a/Sources/SwiftWin32/Windows and Screens/AlertAction.swift +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -extension AlertAction { - /// Styles to apply to action buttons in an alert. - public enum Style: Int { - /// Apply the default style to the action’s button. - case `default` - - /// Apply a style that indicates the action cancels the operation and leaves - /// things unchanged. - case cancel - - /// Apply a style that indicates the action might change or delete data. - case destructive - } -} - -/// An action that can be taken when the user taps a button in an alert. -public class AlertAction { - private let handler: ((AlertAction) -> Void)? - - // MARK - Creating an Alert Action - - /// Create and return an action with the specified title and behavior. - public init(title: String?, style: AlertAction.Style, - handler: ((AlertAction) -> Void)? = nil) { - self.title = title - self.style = style - self.isEnabled = true - self.handler = handler - } - - // MARK - Getting the Action's Attributes - - /// The title of the action’s button. - public let title: String? - - /// The style that is applied to the action’s button. - public let style: AlertAction.Style - - /// A Boolean value indicating whether the action is currently enabled. - public var isEnabled: Bool -} diff --git a/Sources/SwiftWin32/Windows and Screens/AlertController.swift b/Sources/SwiftWin32/Windows and Screens/AlertController.swift deleted file mode 100644 index 5401e2e8..00000000 --- a/Sources/SwiftWin32/Windows and Screens/AlertController.swift +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -extension AlertController { - /// Constants indicating the type of alert to display. - public enum Style: Int { - /// An action sheet displayed in the context of the view controller that - /// presented it. - case actionSheet - - /// An alert displayed modally for the app. - case alert - } -} - -/// An object that displays an alert message to the user. -public class AlertController: ViewController { - // MARK - Configuring the Alert - - /// Descriptive text that provides more details about the reason for the - /// alert. - public var message: String? - - /// The style of the alert controller. - public let preferredStyle: AlertController.Style - - // MARK - Creating an Alert Controller - - /// Creates and returns a view controller for displaying an alert to the user. - public init(title: String?, message: String?, - preferredStyle: AlertController.Style) { - self.message = message - self.preferredStyle = preferredStyle - super.init() - } - - // MARK - Configuring the User Actions - - /// Attaches an action object to the alert or action sheet. - public func addAction(_ action: AlertAction) { - } - - /// The actions that the user can take in response to the alert or action - /// sheet. - public private(set) var actions: [AlertAction] = [] - - /// The preferred action for the user to take from an alert. - public var preferredAction: AlertAction? - - // MARK - Configuring Text Fields - - /// Adds a text field to an alert. - public func addTextField(configurationHandler: ((TextField) -> Void)? = nil) { - } - - /// The array of text fields displayed by the alert. - public private(set) var textFields: [TextField]? -} diff --git a/Sources/SwiftWin32/Windows and Screens/CoordinateSpace.swift b/Sources/SwiftWin32/Windows and Screens/CoordinateSpace.swift deleted file mode 100644 index 044a24ac..00000000 --- a/Sources/SwiftWin32/Windows and Screens/CoordinateSpace.swift +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -#if swift(>=5.7) -import CoreGraphics -#endif - -/// A set of methods for converting between different frames of reference on a -/// screen. -public protocol CoordinateSpace { - /// Getting the Bounds Rectangle - - /// The bounds rectangle describing the item's location and size in its own - /// coordinate system. - var bounds: Rect { get } - - /// Converting Between Coordinate Spaces - - /// Converts a point from the coordinate space of the current object to the - /// specified coordinate space. - func convert(_: Point, to: CoordinateSpace) -> Point - - /// Converts a point from the specified coordinate space to the coordinate - /// space of the current object. - func convert(_: Point, from: CoordinateSpace) -> Point - - /// Converts a rectangle from the coordinate space of the current object to - /// the specified coordinate space. - func convert(_: Rect, to: CoordinateSpace) -> Rect - - /// Converts a rectangle from the specified coordinate space to the coordinate - /// space of the current object. - func convert(_: Rect, from: CoordinateSpace) -> Rect -} diff --git a/Sources/SwiftWin32/Windows and Screens/Screen.swift b/Sources/SwiftWin32/Windows and Screens/Screen.swift deleted file mode 100644 index c83a7266..00000000 --- a/Sources/SwiftWin32/Windows and Screens/Screen.swift +++ /dev/null @@ -1,158 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import WinSDK - -#if swift(>=5.7) -import CoreGraphics -#endif - -extension DEVICE_SCALE_FACTOR { - internal var factor: Double { - switch self { - case SCALE_100_PERCENT: return 1.00 - case SCALE_120_PERCENT: return 1.20 - case SCALE_125_PERCENT: return 1.25 - case SCALE_140_PERCENT: return 1.40 - case SCALE_150_PERCENT: return 1.50 - case SCALE_160_PERCENT: return 1.60 - case SCALE_175_PERCENT: return 1.75 - case SCALE_180_PERCENT: return 1.80 - case SCALE_200_PERCENT: return 2.00 - case SCALE_225_PERCENT: return 2.25 - case SCALE_250_PERCENT: return 2.50 - case SCALE_300_PERCENT: return 3.00 - case SCALE_350_PERCENT: return 3.50 - case SCALE_400_PERCENT: return 4.00 - case SCALE_450_PERCENT: return 4.50 - case SCALE_500_PERCENT: return 5.00 - default: fatalError("unknown DEVICE_SCALE_FACTOR: \(self)") - } - } -} - -public final class Screen { - /// Returns the screen object representing the device's screen. - public static var main: Screen { screens.first! } - - /// Returns an array containing all the screens attached to the device. - public static var screens: [Screen] { - let pfnEnumMonitor: MONITORENUMPROC = { hMonitor, hDC, lpRect, lParam in - let pScreens: UnsafeMutablePointer> = - UnsafeMutablePointer>(bitPattern: Int(lParam))! - - var info: MONITORINFOEXW = MONITORINFOEXW() - info.cbSize = DWORD(MemoryLayout.size) - if (withUnsafeMutablePointer(to: &info) { - let pMemoryInfo: UnsafeMutablePointer = - UnsafeMutableRawPointer($0).assumingMemoryBound(to: MONITORINFO.self) - return GetMonitorInfoW(hMonitor, pMemoryInfo) - }) == false { return false } - - let szDevice: String = withUnsafePointer(to: &info.szDevice) { - $0.withMemoryRebound(to: WCHAR.self, capacity: MemoryLayout.size(ofValue: $0) / MemoryLayout.size) { - String(decodingCString: $0, as: UTF16.self) - } - } - - let _: DeviceContextHandle = - ManagedHandle(owning: CreateDCW(szDevice.wide, nil, nil, nil)) - - var dsfDeviceScaleFactor: DEVICE_SCALE_FACTOR = SCALE_100_PERCENT - _ = GetScaleFactorForMonitor(hMonitor, &dsfDeviceScaleFactor) - - let screen: Screen = - Screen(handle: hMonitor!, - height: info.rcMonitor.bottom, width: info.rcMonitor.right, - scale: dsfDeviceScaleFactor.factor) - - // The main screen is always at index 0 - if info.dwFlags & DWORD(MONITORINFOF_PRIMARY) == DWORD(MONITORINFOF_PRIMARY) { - pScreens.pointee.insert(screen, at: 0) - } else { - pScreens.pointee.append(screen) - } - - return true - } - - var screens: [Screen] = [] - _ = withUnsafePointer(to: &screens) { - EnumDisplayMonitors(nil, nil, pfnEnumMonitor, LPARAM(UInt(bitPattern: $0))) - } - return screens - } - - /// The screen being mirrored by an external display. - public var mirrored: Screen? - - /// The bounding rectangle of the screen, measured in points. - public let bounds: Rect - - /// The bounding rectangle of the physical screen, measured in pixels. - public let nativeBounds: Rect - - /// The native scale factor for the physical screen. - public let nativeScale: Double - - /// The handle to the monitor that the screen represents. - private let hMonitor: HMONITOR! - - public private(set) var traitCollection: TraitCollection - - private init(handle hMonitor: HMONITOR!, height: LONG, width: LONG, - scale: Double) { - self.hMonitor = hMonitor - - self.bounds = Rect(origin: Point(x: 0, y: 0), - size: Size(width: Double(width) / scale, - height: Double(height) / scale)) - self.nativeBounds = - Rect(origin: Point(x: 0, y: 0), - size: Size(width: Double(width), height: Double(height))) - self.nativeScale = scale - - self.traitCollection = TraitCollection(traitsFrom: [ - TraitCollection.current, - TraitCollection(displayScale: scale), - ]) - } -} - -extension Screen: TraitEnvironment { - public func traitCollectionDidChange(_ previousTraitCollection: TraitCollection?) { - for screen in Screen.screens { - var dpiX: UINT = 0 - var dpiY: UINT = 0 - guard GetDpiForMonitor(screen.hMonitor, MDT_EFFECTIVE_DPI, - &dpiX, &dpiY) == S_OK else { - log.error("GetDpiForMonitor: invalid argument") - fatalError() - } - - // From MSDN: "The values of *dpiX and *dpiY are identical." - assert(dpiX == dpiY) - - screen.traitCollection = TraitCollection(traitsFrom: [ - screen.traitCollection, - TraitCollection(displayScale: Double(dpiX)), - ]) - } - } -} - -extension Screen { - internal static func == (_ lhs: Screen, _ rhs: HMONITOR) -> Bool { - return lhs.hMonitor == rhs - } - - internal static func == (_ lhs: HMONITOR, _ rhs: Screen) -> Bool { - return rhs.hMonitor == lhs - } -} - -extension Screen: CustomDebugStringConvertible { - public var debugDescription: String { - return "Screen(bounds: \(bounds), nativeScale: \(nativeScale))" - } -} diff --git a/Sources/SwiftWin32/Windows and Screens/Window.swift b/Sources/SwiftWin32/Windows and Screens/Window.swift deleted file mode 100644 index 7ea06135..00000000 --- a/Sources/SwiftWin32/Windows and Screens/Window.swift +++ /dev/null @@ -1,309 +0,0 @@ -// Copyright © 2019 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import WinSDK -import class Foundation.NSNotification -import class Foundation.NotificationCenter - -#if swift(>=5.7) -import CoreGraphics -#endif - -private let SwiftWindowProc: SUBCLASSPROC = { (hWnd, uMsg, wParam, lParam, uIdSubclass, dwRefData) in - let window: Window? = unsafeBitCast(dwRefData, to: AnyObject.self) as? Window - - switch uMsg { - case UINT(WM_ACTIVATE): - guard let window = window, let windowScene = window.windowScene else { break } - switch LOWORD(wParam) { - case WORD(WA_ACTIVE), WORD(WA_CLICKACTIVE): - windowScene.delegate?.sceneWillEnterForeground(windowScene) - case WORD(WA_INACTIVE): - windowScene.delegate?.sceneDidEnterBackground(windowScene) - default: - fatalError("WM_ACTIVATE wParam: 0x\(String(wParam, radix: 16)), lParam: 0x\(String(lParam, radix: 16))") - } - case UINT(WM_ACTIVATEAPP): - guard let window = window else { break } - - if wParam == 0 { - if let windowScene = window.windowScene { - windowScene.delegate?.sceneWillResignActive(windowScene) - } else if window.isKeyWindow { - Application.shared.delegate?.applicationWillResignActive(Application.shared) - - // Post ApplicationDelegate.willResignActiveNotification - NotificationCenter.default - .post(name: Delegate.willResignActiveNotification, object: nil) - } - } else { - if let windowScene = window.windowScene { - windowScene.delegate?.sceneDidBecomeActive(windowScene) - } else if window.isKeyWindow { - Application.shared.delegate?.applicationDidBecomeActive(Application.shared) - - // Post ApplicationDelegate.didBecomeActiveNotification - NotificationCenter.default - .post(name: Delegate.didBecomeActiveNotification, object: nil) - } - } - case UINT(WM_DESTROY): - // TODO(compnerd) we should handle multiple scenes, which can have multiple - // Windows, so the destruction of a window should not post the quit message - // to the message loop. - Application.shared.windows.removeAll(where: { $0.hWnd == window!.hWnd }) - if window?.isKeyWindow ?? false { - window?.resignKey() - PostQuitMessage(0) - } - case UINT(WM_DPICHANGED): - if let hMonitor = MonitorFromWindow(hWnd, DWORD(MONITOR_DEFAULTTONULL)) { - let screen = Screen.screens.filter { $0 == hMonitor }.first - screen?.traitCollectionDidChange(screen?.traitCollection) - } - case UINT(WM_GETMINMAXINFO): - // We must have a window and size restrictions, otherwise we fallback to the - // default behaviour. - guard let window = window, - let restrictions = window.windowScene?.sizeRestrictions else { - break - } - - // If the minimum and maximum sizes are the same, the window cannot be - // resized, and we can simply fallback to the default bhaviour. - if restrictions.minimumSize == restrictions.maximumSize { - break - } - - func ClientSizeToWindowSize(_ size: Size) -> Size { - var rc: RECT = RECT(from: Rect(origin: .zero, size: size)) - if !AdjustWindowRectExForDpi(&rc, DWORD(window.GWL_STYLE), false, - DWORD(window.GWL_EXSTYLE), - GetDpiForWindow(window.hWnd)) { - log.warning("AdjustWindowRetExForDpi: \(Error(win32: GetLastError()))") - } - return Rect(from: rc).size - } - - let lpInfo: UnsafeMutablePointer = - UnsafeMutablePointer(bitPattern: UInt(lParam))! - - // Adjust the minimum and maximum tracking size for the window. - lpInfo.pointee.ptMinTrackSize = - POINT(from: ClientSizeToWindowSize(restrictions.minimumSize)) - lpInfo.pointee.ptMaxTrackSize = - POINT(from: ClientSizeToWindowSize(restrictions.maximumSize)) - lpInfo.pointee.ptMaxSize = - POINT(from: ClientSizeToWindowSize(restrictions.maximumSize)) - - return LRESULT(0) - default: - break - } - - return DefSubclassProc(hWnd, uMsg, wParam, lParam) -} - -/// The backdrop for your application’s user interface and the object that -/// dispatches events to your views. -public class Window: View { - private static let `class`: WindowClass = - WindowClass(hInst: GetModuleHandleW(nil), name: "Swift.Window", - style: UInt32(CS_HREDRAW | CS_VREDRAW), - hbrBackground: GetSysColorBrush(COLOR_3DFACE), - hCursor: LoadCursorW(nil, IDC_ARROW)) - private static let style: WindowStyle = - (base: WS_OVERLAPPEDWINDOW, extended: 0) - - public init(frame: Rect) { - super.init(frame: frame, class: Window.class, style: Window.style) - _ = SetWindowSubclass(hWnd, SwiftWindowProc, UINT_PTR(0), - unsafeBitCast(self as AnyObject, to: DWORD_PTR.self)) - - // TODO(compnerd) insert/sort by z-order - Application.shared.windows.append(self) - } - - // MARK - Creating a Window - - /// Creates a Window and associates it with the specified scene object. - public init(windowScene: WindowScene) { - self.windowScene = windowScene - - let frame: Rect = - Rect(origin: Point(x: Double(CW_USEDEFAULT), y: Double(CW_USEDEFAULT)), - size: windowScene.sizeRestrictions?.minimumSize ?? .zero) - super.init(frame: frame, class: Window.class, style: Window.style) - _ = SetWindowSubclass(hWnd, SwiftWindowProc, UINT_PTR(0), - unsafeBitCast(self as AnyObject, to: DWORD_PTR.self)) - - // TODO(compnerd) honour self.canResizeToFitContent - if let restrictions = windowScene.sizeRestrictions, - restrictions.minimumSize == restrictions.maximumSize { - self.GWL_STYLE &= ~(WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_SIZEBOX) - } - - windowScene.windows.append(self) - } - - // MARK - Configuring the Window - - internal var hWindowMenu: MenuHandle? - - /// The root view controller for the window. - public var rootViewController: ViewController? { - didSet { - self.rootViewController?.view = self - self.rootViewController?.viewDidLoad() - - if let builder = _MenuBuilder(for: self) { - self.rootViewController?.buildMenu(with: builder) - builder.setNeedsRebuild() - } - } - } - - /// The position of the window in the z-axis. - public var windowLevel: Window.Level = .normal { - didSet { fatalError("\(#function) not yet implemented") } - } - - /// The screen on which the window is displayed. - @available(*, deprecated, message: "use windowScene.scene") - public var screen: Screen { - let hMonitor: HMONITOR = - MonitorFromWindow(hWnd, DWORD(MONITOR_DEFAULTTOPRIMARY)) - return Screen.screens.filter { $0 == hMonitor }.first! - } - - /// A boolean value that indicates whether the window's constraint-based - /// content determines its size. - public var canResizeToFitContent: Bool = false { - didSet { fatalError("\(#function) not yet implemented") } - } - - // MARK - Making Windows Key - - /// A boolean value that indicates whether the window is the key window for - /// the application. - public var isKeyWindow: Bool { - guard let keyWindow = Application.shared.keyWindow else { return false } - return self.hWnd == keyWindow.hWnd - } - - /// A boolean value that indicates whether the window can become the key - /// window. - public var canBecomeKey: Bool = true { - didSet { fatalError("\(#function) not yet implemented") } - } - - /// Shows the window and makes it the key window. - public func makeKeyAndVisible() { - self.makeKey() - self.isHidden = false - } - - /// Makes the receiver the key window. - public func makeKey() { - guard self.canBecomeKey else { return } - - Application.shared.keyWindow?.resignKey() - Application.shared.keyWindow = self - Application.shared.keyWindow?.becomeKey() - } - - /// Called automatically to inform the window that it has become the key - /// window. - public func becomeKey() { - NotificationCenter.default.post(name: Window.didBecomeKeyNotification, - object: self) - } - - /// Called automatically to inform the window that it is no longer the key - /// window. - public func resignKey() { - NotificationCenter.default.post(name: Window.didResignKeyNotification, - object: self) - } - - // MARK - Getting Related Objects - - /// The scene containing the window. - public weak var windowScene: WindowScene? { - willSet { - self.windowScene?.windows.remove(object: self) - } - didSet { - self.windowScene?.windows.append(self) - } - } - - // MARK - Responding to Window-Related Notifications - - /// Posted whn a `Window` object becomes visible. - public class var didBecomeVisibleNotification: NSNotification.Name { - NSNotification.Name(rawValue: "UIWindowDidBecomeVisibleNotification") - } - - /// Posted when a `Window` object becomes hidden. - public class var didBecomeHiddenNotification: NSNotification.Name { - NSNotification.Name(rawValue: "UIWindowDidBecomeHiddenNotification") - } - - /// Posted whenever a `Window` object becomes the key window. - public class var didBecomeKeyNotification: NSNotification.Name { - NSNotification.Name(rawValue: "UIWindowDidBecomeKeyNotification") - } - - /// Posted when a `Window` object resigns its status as main window. - public class var didResignKeyNotification: NSNotification.Name { - NSNotification.Name(rawValue: "UIWindowDidResignKeyNotification") - } - - // MARK - Responder Chain - - override public var next: Responder? { - // The window's next responder is the `Application` object. - Application.shared - } -} - -extension Window { - /// The positioning of windows relative to each other. - public struct Level: Equatable, Hashable, RawRepresentable { - public typealias RawValue = Double - - public let rawValue: RawValue - - public init(rawValue: RawValue) { - self.rawValue = rawValue - } - } -} - -extension Window.Level { - /// The default level. - public static var normal: Window.Level { - Window.Level(rawValue: 0.0) - } - - /// The level for a status window. - public static var statusBar: Window.Level { - Window.Level(rawValue: 1000.0) - } - - /// The level for an alert view. - public static var alert: Window.Level { - Window.Level(rawValue: 2000.0) - } -} - -extension Window { - public var isMinimizable: Bool { - get { self.GWL_STYLE & WS_MINIMIZEBOX == WS_MINIMIZEBOX } - set { - self.GWL_STYLE = newValue ? self.GWL_STYLE | WS_MINIMIZEBOX - : self.GWL_STYLE & ~WS_MINIMIZEBOX - } - } -} diff --git a/Sources/SwiftWin32UI/App Structure and Behaviour/App.swift b/Sources/SwiftWin32UI/App Structure and Behaviour/App.swift deleted file mode 100644 index 26dba3d3..00000000 --- a/Sources/SwiftWin32UI/App Structure and Behaviour/App.swift +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import SwiftWin32 - -/// A type that represents the structure and behaviour of an application. -public protocol App { - // MARK - Implementing an App - - /// The type of scene representing the content of the application. - associatedtype Body: Scene - - /// The content and behaviour of the application. - @SceneBuilder - var body: Self.Body { get } - - // MARK - Running an Application - - /// Creates an instance of the application using the body as the content. - init() - - /// Initializes and runs the application. - static func main() -} - -extension App { - public static func main() { - ApplicationMain(CommandLine.argc, CommandLine.unsafeArgv, nil, - String(describing: String(reflecting: Self.self))) - } -} diff --git a/Sources/SwiftWin32UI/App Structure and Behaviour/Scene.swift b/Sources/SwiftWin32UI/App Structure and Behaviour/Scene.swift deleted file mode 100644 index 7b1f910c..00000000 --- a/Sources/SwiftWin32UI/App Structure and Behaviour/Scene.swift +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -/// A part of the application's user interface. -public protocol Scene { - // MARK - Creating a Scene - - /// The type of scene representing the body of this scene. - associatedtype Body: Scene - - /// The content and behaviour of the scene. - @SceneBuilder - var body: Self.Body { get } -} diff --git a/Sources/SwiftWin32UI/App Structure and Behaviour/SceneBuilder.swift b/Sources/SwiftWin32UI/App Structure and Behaviour/SceneBuilder.swift deleted file mode 100644 index 1cdb47d9..00000000 --- a/Sources/SwiftWin32UI/App Structure and Behaviour/SceneBuilder.swift +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -@resultBuilder -public struct SceneBuilder { - public static func buildBlock(_ content: Content) -> Content { - fatalError("\(#function) not yet implemented") - } -} diff --git a/Sources/SwiftWin32UI/App Structure and Behaviour/WindowGroup.swift b/Sources/SwiftWin32UI/App Structure and Behaviour/WindowGroup.swift deleted file mode 100644 index a6e4d410..00000000 --- a/Sources/SwiftWin32UI/App Structure and Behaviour/WindowGroup.swift +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -/// A scene that presents a group of identically structured windows. -public struct WindowGroup: Scene { - public var body: some Scene { - fatalError("\(#function) not yet implemented") - } - - // MARK - Creating a Window Group - - /// Creates a window group. - public init(@ViewBuilder content: () -> Content) { - } -} diff --git a/Sources/SwiftWin32UI/CMakeLists.txt b/Sources/SwiftWin32UI/CMakeLists.txt deleted file mode 100644 index fd53e450..00000000 --- a/Sources/SwiftWin32UI/CMakeLists.txt +++ /dev/null @@ -1,28 +0,0 @@ -#[[ -Copyright © 2019 Saleem Abdulrasool -All rights reserved. - -SPDX-License-Identifier: BSD-3-Clause -#]] - -add_library(SwiftWin32UI SHARED - EmptyView.swift - Never+SwiftUI.swift) -target_sources(SwiftWin32UI PRIVATE - "App Structure and Behaviour/App.swift" - "App Structure and Behaviour/Scene.swift" - "App Structure and Behaviour/SceneBuilder.swift" - "App Structure and Behaviour/WindowGroup.swift") -target_sources(SwiftWin32UI PRIVATE - "Views and Controls/View.swift" - "Views and Controls/ViewBuilder.swift") -target_sources(SwiftWin32UI PRIVATE - "View Layout and Presentation/Group.swift") -target_link_libraries(SwiftWin32UI PUBLIC - SwiftWin32) -set_target_properties(SwiftWin32UI PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_Swift_MODULE_DIRECTORY} - INTERFACE_LINK_DIRECTORIES $) - - -_install_target(SwiftWin32UI) diff --git a/Sources/SwiftWin32UI/EmptyView.swift b/Sources/SwiftWin32UI/EmptyView.swift deleted file mode 100644 index 5b96bfd5..00000000 --- a/Sources/SwiftWin32UI/EmptyView.swift +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -@frozen -public struct EmptyView: View { - public typealias Body = Never - - @inlinable - public init() { - } -} diff --git a/Sources/SwiftWin32UI/Framework Integration/UIApplicationDelegateAdaptor.swift b/Sources/SwiftWin32UI/Framework Integration/UIApplicationDelegateAdaptor.swift deleted file mode 100644 index 5b80cee8..00000000 --- a/Sources/SwiftWin32UI/Framework Integration/UIApplicationDelegateAdaptor.swift +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright © 2021 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import SwiftWin32 - -/// A property wrapper that is used in `App` to provide an application delegate -/// from Swift/Win32. -@propertyWrapper -public struct UIApplicationDelegateAdaptor { - /// The underlying delegate. - public private(set) var wrappedValue: DelegateType - - /// Creates an `UIApplicationDelegateAdaptor` using an ApplicationDelegate. - public init(_ delegateType: DelegateType.Type = DelegateType.self) { - self.wrappedValue = delegateType.init() - } -} diff --git a/Sources/SwiftWin32UI/Never+SwiftUI.swift b/Sources/SwiftWin32UI/Never+SwiftUI.swift deleted file mode 100644 index 12705e72..00000000 --- a/Sources/SwiftWin32UI/Never+SwiftUI.swift +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -extension Never: View { -} - -extension Never: Scene { -} - -extension Never { - public typealias Body = Never -} - -extension View where Body == Never { - public var body: Never { - fatalError("\(#function): View \(type(of: self)) does not have a body") - } -} diff --git a/Sources/SwiftWin32UI/View Layout and Presentation/AnyView.swift b/Sources/SwiftWin32UI/View Layout and Presentation/AnyView.swift deleted file mode 100644 index 33a375ee..00000000 --- a/Sources/SwiftWin32UI/View Layout and Presentation/AnyView.swift +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -@usableFromInline -internal class AnyViewStorageBase { -} - -internal class AnyViewStorage: AnyViewStorageBase { - public var view: ViewType - - init(_ view: ViewType) { - self.view = view - } -} - -/// A type-erased view. -/// -/// An `AnyView` allows changing the type of view used in a given view -/// hierarchy. Whenever the type of view used with an `AnyView` changes, the old -/// hierarchy is destroyed and a new hierarchy is created for the new type. -@frozen -public struct AnyView: View { - public typealias Body = Never - - internal var storage: AnyViewStorageBase - - // MARK - Creating a View - - /// Create an instance that type-erases `view`. - public init(_ view: ViewType) { - self.storage = AnyViewStorage(view) - } - - @_alwaysEmitIntoClient - public init(erasing view: ViewType) { - self.init(view) - } -} diff --git a/Sources/SwiftWin32UI/View Layout and Presentation/EquatableView.swift b/Sources/SwiftWin32UI/View Layout and Presentation/EquatableView.swift deleted file mode 100644 index 374686e2..00000000 --- a/Sources/SwiftWin32UI/View Layout and Presentation/EquatableView.swift +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright © 2021 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -/// A view type that compares itself against its previous value and prevents its -/// child updating if its new value is the same as its old value. -@frozen -public struct EquatableView: View { - public typealias Body = Never - - // MARK - Creating an Equatable View - - public var content: Content - - @inlinable - public init(content: Content) { - self.content = content - } -} diff --git a/Sources/SwiftWin32UI/View Layout and Presentation/Group.swift b/Sources/SwiftWin32UI/View Layout and Presentation/Group.swift deleted file mode 100644 index 27ceb808..00000000 --- a/Sources/SwiftWin32UI/View Layout and Presentation/Group.swift +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -/// An affordance for grouping view content. -@frozen -public struct Group { - public typealias Body = Never - - @usableFromInline - internal var content: Content -} - -// MARK - Creating a Group - -extension Group where Content: View { - /// Available when `Content` conforms to `View`. - @inlinable - public init(@ViewBuilder content: () -> Content) { - self.content = content() - } -} - -extension Group where Content: Scene { - /// Available when `Content` conforms to `Scene`. - @inlinable - public init(@SceneBuilder content: () -> Content) { - self.content = content() - } -} - -extension Group: CustomStringConvertible { - public var description: String { - "" - } -} diff --git a/Sources/SwiftWin32UI/Views and Controls/Label.swift b/Sources/SwiftWin32UI/Views and Controls/Label.swift deleted file mode 100644 index 1da7fea8..00000000 --- a/Sources/SwiftWin32UI/Views and Controls/Label.swift +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright © 2022 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import SwiftWin32 - -public struct Label { -} - -extension Label: View { - public typealias Body = SwiftWin32.Label - - public var body: SwiftWin32.Label { - return SwiftWin32.Label(frame: .zero) - } -} - -extension SwiftWin32.Label: View { - public typealias Body = Never -} diff --git a/Sources/SwiftWin32UI/Views and Controls/View.swift b/Sources/SwiftWin32UI/Views and Controls/View.swift deleted file mode 100644 index 85704d9b..00000000 --- a/Sources/SwiftWin32UI/Views and Controls/View.swift +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -/// A type that represents part of your app’s user interface and provides -/// modifiers that you use to configure views. -public protocol View { - /// The type of view representing the body of this view. - associatedtype Body: View - - /// The content and behavior of the view. - @ViewBuilder - var body: Self.Body { get } -} diff --git a/Sources/SwiftWin32UI/Views and Controls/ViewBuilder.swift b/Sources/SwiftWin32UI/Views and Controls/ViewBuilder.swift deleted file mode 100644 index fef57f8a..00000000 --- a/Sources/SwiftWin32UI/Views and Controls/ViewBuilder.swift +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -@resultBuilder -public struct ViewBuilder { - public static func buildBlock() -> EmptyView { - return EmptyView() - } - - public static func buildBlock(_ content: Content) -> Content { - return content - } -} diff --git a/SwiftWin32/index.md b/SwiftWin32/index.md new file mode 100644 index 00000000..521da2b7 --- /dev/null +++ b/SwiftWin32/index.md @@ -0,0 +1,9 @@ +--- +layout: default +title: SwiftWin32 +nav_order: 1 +has_children: true +--- + +SwiftWin32 allows you to construct and manage a graphical, event-driven user +interface for your Windows applications. diff --git a/Tests/AutoLayoutTests/AutoLayoutTests.swift b/Tests/AutoLayoutTests/AutoLayoutTests.swift deleted file mode 100644 index b37ce18b..00000000 --- a/Tests/AutoLayoutTests/AutoLayoutTests.swift +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool . -// SPDX-License-Identifier: BSD-3-Clause - -import XCTest - -import SwiftWin32 - -final class AutoLayoutTests: XCTestCase { - func testLayoutConstraintInactiveByDefault() { - XCTAssertFalse(LayoutConstraint(item: self, attribute: .left, - relatedBy: .equal, - toItem: nil, attribute: .notAnAttribute, - multiplier: 1.0, constant: 0.0).isActive) - } - - func testLayoutConstraintActivate() { - let view: View = View(frame: .zero) - let container: View = View(frame: .zero) - - withExtendedLifetime(view) { - let constraint: LayoutConstraint = - LayoutConstraint(item: view, attribute: .top, relatedBy: .equal, - toItem: container, attribute: .top, multiplier: 1, - constant: 100) - constraint.isActive = true - XCTAssertTrue(constraint.isActive) - } - } - - func testLayoutConstraintActivateList() { - let view: View = View(frame: .zero) - let container: View = View(frame: .zero) - - withExtendedLifetime(view) { - let constraints: [LayoutConstraint] = [ - LayoutConstraint(item: view, attribute: .top, relatedBy: .equal, - toItem: container, attribute: .top, multiplier: 1, - constant: 100) - ] - LayoutConstraint.activate(constraints) - - XCTAssertTrue(constraints[0].isActive) - } - } - - static var allTests = [ - ("testLayoutConstraintInactiveByDefault", testLayoutConstraintInactiveByDefault), - ("testLayoutConstraintActivate", testLayoutConstraintActivate), - ("testLayoutConstraintActivateList", testLayoutConstraintActivateList), - ] -} diff --git a/Tests/CoreGraphicsTests/CoreGraphicsTests.swift b/Tests/CoreGraphicsTests/CoreGraphicsTests.swift deleted file mode 100644 index 526a691b..00000000 --- a/Tests/CoreGraphicsTests/CoreGraphicsTests.swift +++ /dev/null @@ -1,321 +0,0 @@ -// Copyright © 2021 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import XCTest - -#if swift(>=5.7) -import CoreGraphics -// NOTE: avoid conflict with Foundation.AffineTransform -private typealias AffineTransform = CoreGraphics.AffineTransform -#else -import SwiftWin32 -// NOTE: avoid conflict with Foundation.AffineTransform -private typealias AffineTransform = SwiftWin32.AffineTransform -#endif - -final class CoreGraphicsTests: XCTestCase { - func testAffineTransformIdentity() { - let identity: AffineTransform = .identity - XCTAssertEqual(identity.a, 1.0) - XCTAssertEqual(identity.b, 0.0) - XCTAssertEqual(identity.c, 0.0) - XCTAssertEqual(identity.d, 1.0) - XCTAssertEqual(identity.tx, 0.0) - XCTAssertEqual(identity.ty, 0.0) - } - - func testAffineTransformIdentityIsIdentity() { - let transform: AffineTransform = AffineTransform( a: 1.0, b: 0.0, - c: 0.0, d: 1.0, - tx: 0.0, ty: 0.0) - XCTAssertTrue(transform.isIdentity) - - XCTAssertTrue(AffineTransform.identity.isIdentity) - } - - func testAffineTransformDefaultConstructor() { - XCTAssertFalse(AffineTransform().isIdentity) - } - - func testRectComputedProperties() { - let r1: Rect = Rect(origin: .zero, size: Size(width: 32, height: 32)) - XCTAssertEqual(r1.midX, 16) - XCTAssertEqual(r1.midY, 16) - - let r2: Rect = Rect(origin: Point(x: 4, y: 4), - size: Size(width: 16, height: 16)) - XCTAssertEqual(r2.midX, 12) - XCTAssertEqual(r2.midY, 12) - } - - func testRectApplyAffineTransform() { - let null: Rect = .null - XCTAssertEqual(null.applying(AffineTransform(rotationAngle: .pi)), - Rect.null) - - let nonStandardized: Rect = - Rect(origin: .zero, size: Size(width: -32, height: -32)) - XCTAssertEqual(nonStandardized.applying(.identity), - Rect(x: -32.0, y: -32.0, width: 32.0, height: 32.0)) - - let nonStandardizedOblong: Rect = - Rect(origin: Point(x: -16, y: -8), size: Size(width: -16, height: -8)) - XCTAssertEqual(nonStandardizedOblong.applying(AffineTransform(rotationAngle: .pi / 2)), - Rect(x: 7.999999999999998, y: -32, width: 8, height: 16)) - - var rect: Rect - - rect = Rect(origin: Point(x: -6, y: -7), - size: Size(width: 12, height: 14)) - .applying(AffineTransform(rotationAngle: .pi / 2)) - XCTAssertEqual(rect, Rect(x: -7, y: -6, width: 14, height: 12)) - - rect = Rect(origin: Point(x: 45, y: 115), - size: Size(width: 13, height: 14)) - .applying(AffineTransform(rotationAngle: 42)) - XCTAssertEqual(rect.origin.x, 82.20082974097352, - accuracy: .ulpOfOne.squareRoot()) - XCTAssertEqual(rect.origin.y, -104.75635541260408, - accuracy: .ulpOfOne.squareRoot()) - XCTAssertEqual(rect.size.width, 18.031110765667435, - accuracy: .ulpOfOne.squareRoot()) - XCTAssertEqual(rect.size.height, 17.514574532740156, - accuracy: .ulpOfOne.squareRoot()) - - rect = Rect(origin: Point(x: 45, y: 115), - size: Size(width: 13, height: 14)) - .applying(AffineTransform(rotationAngle: -104)) - .applying(AffineTransform(translationX: -26, y: 22)) - .applying(AffineTransform(scaleX: 7, y: 5)) - XCTAssertEqual(rect.origin.x, -856.8534424207578, - accuracy: .ulpOfOne.squareRoot()) - XCTAssertEqual(rect.origin.y, -428.36482622296273, - accuracy: .ulpOfOne.squareRoot()) - XCTAssertEqual(rect.size.width, 117.68398448828839, - accuracy: .ulpOfOne.squareRoot()) - XCTAssertEqual(rect.size.height, 87.18621695814943, - accuracy: .ulpOfOne.squareRoot()) - } - - func testRectOffsetByNullRect() { - XCTAssertTrue(Rect.null.offsetBy(dx: 1.0, dy: 1.0).isNull) - } - - func testRectOffsetBy() { - let r1: Rect = Rect.zero.offsetBy(dx: 4.0, dy: 4.0) - XCTAssertEqual(r1.origin, Point(x: 4.0, y: 4.0)) - XCTAssertEqual(r1.size, .zero) - - let r2: Rect = Rect(origin: Point(x: 4.0, y: 4.0), - size: Size(width: 4.0, height: 4.0)) - .offsetBy(dx: 4.0, dy: 4.0) - XCTAssertEqual(r2.origin, Point(x: 8.0, y: 8.0)) - XCTAssertEqual(r2.size, Size(width: 4.0, height: 4.0)) - - let nonStandardized: Rect = - Rect(origin: .zero, size: Size(width: -32, height: -32)) - XCTAssertEqual(nonStandardized.offsetBy(dx: 16.0, dy: 16.0), - Rect(x: -16.0, y: -16.0, width: 32.0, height: 32.0)) - } - - func testRectStandardizing() { - let null: Rect = .null - XCTAssertEqual(null.standardized, Rect.null) - - let normal: Rect = Rect(x: 0, y: 0, width: 32, height: 32) - XCTAssertEqual(normal.standardized, normal) - - let negativeHeight: Rect = Rect(x: 0, y: 0, width: -32, height: 32) - XCTAssertEqual(negativeHeight.standardized, - Rect(x: -32, y: 0, width: 32, height: 32)) - - let negativeWidth: Rect = Rect(x: 0, y: 0, width: 32, height: -32) - XCTAssertEqual(negativeWidth.standardized, - Rect(x: 0, y: -32, width: 32, height: 32)) - - let negativeHeightAndWidth: Rect = Rect(x: 0, y: 0, width: -32, height: -32) - XCTAssertEqual(negativeHeightAndWidth.standardized, - Rect(x: -32, y: -32, width: 32, height: 32)) - - let positiveOrigin: Rect = Rect(x: 32, y: 32, width: -32, height: -32) - XCTAssertEqual(positiveOrigin.standardized, - Rect(origin: .zero, size: Size(width: 32, height: 32))) - - let negativeOrigin: Rect = Rect(x: -32, y: -32, width: -32, height: -32) - XCTAssertEqual(negativeOrigin.standardized, - Rect(x: -64, y: -64, width: 32, height: 32)) - } - - func testRectIntegral() { - let null: Rect = .null - XCTAssertEqual(null.integral, Rect.null) - } - - func testRectInsetBy() { - let null: Rect = .null - XCTAssertEqual(null.insetBy(dx: 0.0, dy: 0.0), Rect.null) - - let normal: Rect = Rect(x: 4.0, y: 4.0, width: 16.0, height: 8.0) - XCTAssertEqual(normal.insetBy(dx: 2.0, dy: 2.0), - Rect(x: 6.0, y: 6.0, width: 12.0, height: 4.0)) - - let nonStandardized: Rect = - Rect(origin: .zero, size: Size(width: -32, height: -32)) - XCTAssertEqual(nonStandardized.insetBy(dx: 4.0, dy: 4.0), - Rect(x: -28.0, y: -28.0, width: 24.0, height: 24.0)) - } - - func testRectIntersection() { - let r1: Rect = Rect(x: 0, y: 0, width: 100, height: 100) - let r2: Rect = Rect(x: 25, y: 25, width: 50, height: 50) - let r3: Rect = Rect(x: 75, y: 75, width: 50, height: 50) - let r4: Rect = Rect(x: 125, y: 125, width: 50, height: 50) - let r5: Rect = Rect(x: 75, y: 75, width: -50, height: -50) - - // concentric overlap - XCTAssertEqual(r1.intersection(r2), - Rect(x: 25, y: 25, width: 50, height: 50)) - - // communitivity - XCTAssertEqual(r1.intersection(r2), r2.intersection(r1)) - - // partial overlap - XCTAssertEqual(r1.intersection(r3), - Rect(x: 75, y: 75, width: 25, height: 25)) - - // no overlap - XCTAssertTrue(r1.intersection(r4).isNull) - - // non-standard - XCTAssertEqual(r5.intersection(r1), - Rect(x: 25, y: 25, width: 50, height: 50)) - XCTAssertEqual(r1.intersection(r5), - Rect(x: 25, y: 25, width: 50, height: 50)) - } - - func testRectIntersects() { - let r1: Rect = Rect(x: 0, y: 0, width: 100, height: 100) - let r2: Rect = Rect(x: 25, y: 25, width: 50, height: 50) - let r3: Rect = Rect(x: 75, y: 75, width: 50, height: 50) - let r4: Rect = Rect(x: 125, y: 125, width: 50, height: 50) - - XCTAssertTrue(r1.intersects(r2)) - XCTAssertTrue(r2.intersects(r1)) - - XCTAssertTrue(r1.intersects(r3)) - XCTAssertTrue(r3.intersects(r1)) - - XCTAssertFalse(r1.intersects(r4)) - XCTAssertFalse(r4.intersects(r1)) - } - - func testRectUnion() { - let r1: Rect = Rect(x: 0, y: 0, width: 50, height: 50) - let r2: Rect = Rect(x: 25, y: 25, width: 50, height: 50) - let r3: Rect = Rect(x: 100, y: 100, width: 50, height: 50) - let r4: Rect = Rect(x: 75, y: 75, width: -50, height: -50) - - XCTAssertEqual(r1.union(r2), Rect(x: 0, y: 0, width: 75, height: 75)) - XCTAssertEqual(r2.union(r1), Rect(x: 0, y: 0, width: 75, height: 75)) - - XCTAssertEqual(Rect.null.union(r1), Rect(x: 0, y: 0, width: 50, height: 50)) - XCTAssertEqual(r1.union(Rect.null), Rect(x: 0, y: 0, width: 50, height: 50)) - - XCTAssertEqual(r1.union(r3), Rect(x: 0, y: 0, width: 150, height: 150)) - XCTAssertEqual(r3.union(r1), Rect(x: 0, y: 0, width: 150, height: 150)) - - XCTAssertEqual(r1.union(r4), Rect(x: 0, y: 0, width: 75, height: 75)) - XCTAssertEqual(r4.union(r1), Rect(x: 0, y: 0, width: 75, height: 75)) - - XCTAssertEqual(Rect.zero.union(Rect.zero), Rect.zero) - - XCTAssertEqual(Rect.infinite.union(Rect.zero), Rect.infinite) - XCTAssertEqual(Rect.zero.union(Rect.infinite), Rect.infinite) - - XCTAssertEqual(Rect.infinite.union(Rect.null), Rect.infinite) - XCTAssertEqual(Rect.null.union(Rect.infinite), Rect.infinite) - } - - func testRectContains() { - let r1: Rect = Rect(x: 0, y: 0, width: 100, height: 100) - let r2: Rect = Rect(x: 25, y: 25, width: 50, height: 50) - let r3: Rect = Rect(x: 75, y: 75, width: 50, height: 50) - let r4: Rect = Rect(x: 125, y: 125, width: 50, height: 50) - let r5: Rect = Rect(x: 75, y: 75, width: -50, height: -50) - - - XCTAssertTrue(r1.contains(r2)) - XCTAssertFalse(r2.contains(r1)) - - XCTAssertFalse(r1.contains(r3)) - XCTAssertFalse(r3.contains(r1)) - - XCTAssertFalse(r1.contains(r4)) - XCTAssertFalse(r4.contains(r1)) - - XCTAssertTrue(r1.contains(r5)) - XCTAssertFalse(r5.contains(r1)) - - XCTAssertFalse(Rect.null.contains(r1)) - XCTAssertTrue(r1.contains(Rect.null)) - XCTAssertTrue(Rect.null.contains(Rect.null)) - XCTAssertFalse(Rect.null.contains(Rect.zero)) - - XCTAssertFalse(Rect.zero.contains(r1)) - XCTAssertTrue(r1.contains(Rect.zero)) - XCTAssertTrue(Rect.zero.contains(Rect.zero)) - XCTAssertTrue(Rect.zero.contains(Rect.null)) - - XCTAssertTrue(Rect.infinite.contains(Rect.infinite)) - XCTAssertFalse(r1.contains(Rect.infinite)) - XCTAssertTrue(Rect.infinite.contains(Rect.zero)) - XCTAssertTrue(Rect.infinite.contains(Rect.null)) - - } - - func testRectNonstandardEquality() { - let r1: Rect = Rect(x: 0, y: 0, width: 10, height: 10) - let r2: Rect = Rect(x: 10, y: 10, width: -10, height: -10) - let r3: Rect = Rect(x: 10, y: 10, width: -9.9, height: -10) - - XCTAssertTrue(r1 == r2) - XCTAssertFalse(r2 == r3) - - let null1: Rect = Rect.null - let null2: Rect = Rect.null - XCTAssertTrue(null1 == null2) - } - - func testVectorConstructors() { - let v1: Vector = Vector() - XCTAssertEqual(v1, .zero) - - let v2: Vector = Vector(dx: 0.0 as Float, dy: 0.0 as Float) - XCTAssertEqual(v2, .zero) - - let v3: Vector = Vector(dx: 0.0 as Double, dy: 0.0 as Double) - XCTAssertEqual(v3, .zero) - - let v4: Vector = Vector(dx: 0, dy: 0) - XCTAssertEqual(v4, .zero) - } - - static var allTests = [ - ("testAffineTransformIdentity", testAffineTransformIdentity), - ("testAffineTransformIdentityIsIdentity", testAffineTransformIdentityIsIdentity), - ("testAffineTransformDefaultConstructor", testAffineTransformDefaultConstructor), - ("testRectComputedProperties", testRectComputedProperties), - ("testRectApplyAffineTransform", testRectApplyAffineTransform), - ("testRectOffsetByNullRect", testRectOffsetByNullRect), - ("testRectOffsetBy", testRectOffsetBy), - ("testRectStandardizing", testRectStandardizing), - ("testRectIntegral", testRectIntegral), - ("testRectInsetBy", testRectInsetBy), - ("testRectIntersection", testRectIntersection), - ("testRectIntersects", testRectIntersects), - ("testRectUnion", testRectUnion), - ("testRectContains", testRectContains), - ("testRectNonstandardEquality", testRectNonstandardEquality), - ("testVectorConstructors", testVectorConstructors) - ] -} diff --git a/Tests/SupportTests/DateTests.swift b/Tests/SupportTests/DateTests.swift deleted file mode 100644 index f56c9831..00000000 --- a/Tests/SupportTests/DateTests.swift +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright © 2021 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import XCTest -import WinSDK -import struct Foundation.Date -@testable import SwiftWin32 - -final class DateTests: XCTestCase { - func testFileTimeConstruction() { - XCTAssertEqual(FILETIME(timeIntervalSince1970: 0).timeIntervalSince1970, 0) - } - - func testUnixEpoch() { - let ftUnixEpoch: FILETIME = FILETIME(timeIntervalSince1970: 0) - XCTAssertEqual(ftUnixEpoch.dwLowDateTime, 3577643008) - XCTAssertEqual(ftUnixEpoch.dwHighDateTime, 27111902) - - let stUnixEpoch: SYSTEMTIME = SYSTEMTIME(ftUnixEpoch) - XCTAssertEqual(stUnixEpoch.wYear, 1970) - XCTAssertEqual(stUnixEpoch.wMonth, 1) - XCTAssertEqual(stUnixEpoch.wDayOfWeek, 4) - XCTAssertEqual(stUnixEpoch.wDay, 1) - XCTAssertEqual(stUnixEpoch.wHour, 0) - XCTAssertEqual(stUnixEpoch.wMinute, 0) - XCTAssertEqual(stUnixEpoch.wSecond, 0) - XCTAssertEqual(stUnixEpoch.wMilliseconds, 0) - } - - func testSystemTimeConversion() { - let stTimeStamp: SYSTEMTIME = - SYSTEMTIME(wYear: 2020, wMonth: 11, wDayOfWeek: 0, wDay: 7, - wHour: 0, wMinute: 0, wSecond: 0, wMilliseconds: 0) - XCTAssertEqual(FILETIME(stTimeStamp).timeIntervalSince1970, - 1604707200) - } - - func testFileTimeConversion() { - let ftTimeStamp: FILETIME = FILETIME(timeIntervalSince1970: 1604707200) - let stTimeStamp: SYSTEMTIME = SYSTEMTIME(ftTimeStamp) - - XCTAssertEqual(stTimeStamp.wYear, 2020) - XCTAssertEqual(stTimeStamp.wMonth, 11) - - // We cannot check the day of week because it is ignored on the conversion - // and we are going from UTC to local time zone to UTC, which changes the - // day. - /* XCTAssertEqual(stTimeStamp.wDayOfWeek, 0) */ - - XCTAssertEqual(stTimeStamp.wDay, 7) - XCTAssertEqual(stTimeStamp.wHour, 0) - XCTAssertEqual(stTimeStamp.wMinute, 0) - XCTAssertEqual(stTimeStamp.wSecond, 0) - XCTAssertEqual(stTimeStamp.wMilliseconds, 0) - } - - func testRoundTrip() { - let ftSystemTimeInitial: SYSTEMTIME = - SYSTEMTIME(wYear: 2020, wMonth: 11, wDayOfWeek: 6, wDay: 7, - wHour: 0, wMinute: 0, wSecond: 0, wMilliseconds: 0) - let ftSystemTimeConverted: SYSTEMTIME = - SYSTEMTIME(FILETIME(ftSystemTimeInitial)) - - XCTAssertEqual(ftSystemTimeInitial.wYear, ftSystemTimeConverted.wYear) - XCTAssertEqual(ftSystemTimeInitial.wMonth, ftSystemTimeConverted.wMonth) - - // We cannot check the day of week because it is ignored on the conversion - // and we are going from UTC to local time zone to UTC, which changes the - // day. - /* XCTAssertEqual(ftSystemTimeInitial.wDayOfWeek, ftSystemTimeConverted.wDayOfWeek) */ - - XCTAssertEqual(ftSystemTimeInitial.wDay, ftSystemTimeConverted.wDay) - XCTAssertEqual(ftSystemTimeInitial.wHour, ftSystemTimeConverted.wHour) - XCTAssertEqual(ftSystemTimeInitial.wMinute, ftSystemTimeConverted.wMinute) - XCTAssertEqual(ftSystemTimeInitial.wSecond, ftSystemTimeConverted.wSecond) - XCTAssertEqual(ftSystemTimeInitial.wMilliseconds, ftSystemTimeConverted.wMilliseconds) - } - - static var allTests = [ - ("testFileTimeConstruction", testFileTimeConstruction), - ("testUnixEpoch", testUnixEpoch), - ("testSystemTimeConversion", testSystemTimeConversion), - ("testFileTimeConversion", testFileTimeConversion), - ("testRoundTrip", testRoundTrip), - ] -} diff --git a/Tests/UICoreTests/BarButtonItemTests.swift b/Tests/UICoreTests/BarButtonItemTests.swift deleted file mode 100644 index bc789bef..00000000 --- a/Tests/UICoreTests/BarButtonItemTests.swift +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright © 2021 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import XCTest -import SwiftWin32 - -final class BarBttonItemTests: XCTestCase { - func testDefaultState() { - let item: BarButtonItem = BarButtonItem() - XCTAssertNil(item.target) - /* XCTAssertNil(item.action) */ - XCTAssertEqual(item.style, .plain) - XCTAssertNil(item.possibleTitles) - XCTAssertEqual(item.width, 0.0) - XCTAssertNil(item.customView) - XCTAssertNil(item.menu) - XCTAssertNil(item.primaryAction) - XCTAssertNil(item.primaryAction) - XCTAssertNil(item.buttonGroup) - } - - static var allTests = [ - ("testDefaultState", testDefaultState) - ] -} diff --git a/Tests/UICoreTests/BarItemTests.swift b/Tests/UICoreTests/BarItemTests.swift deleted file mode 100644 index 351023b0..00000000 --- a/Tests/UICoreTests/BarItemTests.swift +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright © 2021 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import XCTest -import SwiftWin32 - -final class BarItemTests: XCTestCase { - func testDefaultState() { - let item = BarItem() - XCTAssertNil(item.title) - XCTAssertNil(item.image) - XCTAssertNil(item.landscapeImage) - XCTAssertNil(item.largeContentSizeImage) - XCTAssertEqual(item.imageInsets, .zero) - XCTAssertEqual(item.landscapeImageInsets, .zero) - XCTAssertEqual(item.largeContentSizeImageInsets, .zero) - XCTAssertTrue(item.isEnabled) - XCTAssertEqual(item.tag, 0) - } - - static var allTests = [ - ("testDefaultState", testDefaultState) - ] -} diff --git a/Tests/UICoreTests/ButtonTests.swift b/Tests/UICoreTests/ButtonTests.swift deleted file mode 100644 index 214e458e..00000000 --- a/Tests/UICoreTests/ButtonTests.swift +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright © 2021 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import XCTest -import WinSDK -@testable import SwiftWin32 - -final class ButtonTests: XCTestCase { - func testConstructWithAction() { - let expectation: XCTestExpectation = - self.expectation(description: "action is performed") - - let button: Button = - Button(frame: .zero, primaryAction: Action { _ in - expectation.fulfill() - }) - - // TODO(compnerd) migrate to UI automation API - _ = SendMessageW(button.hWnd, UINT(WM_LBUTTONUP), 0, 0) - - // FIXME(compnerd) what is a good timeout value to use? - waitForExpectations(timeout: 1) - } - - static var allTests = [ - ("testConstructWithAction", testConstructWithAction), - ] -} diff --git a/Tests/UICoreTests/ColorTests.swift b/Tests/UICoreTests/ColorTests.swift deleted file mode 100644 index c3ea17ad..00000000 --- a/Tests/UICoreTests/ColorTests.swift +++ /dev/null @@ -1,94 +0,0 @@ -// Copyright © 2021 Saleem Abulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import SwiftWin32 -import XCTest - -final class ColorTests: XCTestCase { - func testGetColorComponentsRGBA() { - let rgba: Color = Color(red: 0.1, green: 0.3, blue: 0.7, alpha: 1.0) - let dyn: Color = Color(dynamicProvider: { _ in rgba }) - let hsba: Color = - Color(hue: 0.61, saturation: 0.85, brightness: 0.70, alpha: 1.0) - - XCTAssertTrue(rgba.getRed(nil, green: nil, blue: nil, alpha: nil)) - - var red: Double = 0.0, green: Double = 0.0, blue: Double = 0.0, alpha: Double = 0.0 - XCTAssertTrue(rgba.getRed(&red, green: &green, blue: &blue, alpha: &alpha)) - XCTAssertEqual(red, 0.1) - XCTAssertEqual(green, 0.3) - XCTAssertEqual(blue, 0.7) - XCTAssertEqual(alpha, 1.0) - - XCTAssertTrue(dyn.getRed(&red, green: &green, blue: &blue, alpha: &alpha)) - XCTAssertEqual(red, 0.1) - XCTAssertEqual(green, 0.3) - XCTAssertEqual(blue, 0.7) - XCTAssertEqual(alpha, 1.0) - - XCTAssertTrue(hsba.getRed(&red, green: &green, blue: &blue, alpha: &alpha)) - XCTAssertEqual(red, 0.1, accuracy: 0.01) - XCTAssertEqual(green, 0.3, accuracy: 0.01) - XCTAssertEqual(blue, 0.7) - XCTAssertEqual(alpha, 1.0) - } - - func testGetColorComponentsHSBA() { - let hsba: Color = - Color(hue: 0.61, saturation: 0.85, brightness: 0.70, alpha: 1.0) - let dyn: Color = Color(dynamicProvider: { _ in hsba }) - let rgba: Color = Color(red: 0.1, green: 0.3, blue: 0.7, alpha: 1.0) - - XCTAssertTrue(hsba.getHue(nil, saturation: nil, brightness: nil, alpha: nil)) - - var hue: Double = 0.0, saturation: Double = 0.0, brightness: Double = 0.0, alpha: Double = 0.0 - XCTAssertTrue(hsba.getHue(&hue, saturation: &saturation, brightness: &brightness, alpha: &alpha)) - XCTAssertEqual(hue, 0.61) - XCTAssertEqual(saturation, 0.85) - XCTAssertEqual(brightness, 0.70) - XCTAssertEqual(alpha, 1.0) - - XCTAssertTrue(dyn.getHue(&hue, saturation: &saturation, brightness: &brightness, alpha: &alpha)) - XCTAssertEqual(hue, 0.61) - XCTAssertEqual(saturation, 0.85) - XCTAssertEqual(brightness, 0.70) - XCTAssertEqual(alpha, 1.0) - - XCTAssertTrue(rgba.getHue(&hue, saturation: &saturation, brightness: &brightness, alpha: &alpha)) - XCTAssertEqual(hue, 0.61, accuracy: 0.01) - XCTAssertEqual(saturation, 0.85, accuracy: 0.01) - XCTAssertEqual(brightness, 0.70) - XCTAssertEqual(alpha, 1.0) - } - - func testGetColorComponentsGrey() { - let grey: Color = Color(white: 0.39, alpha: 1.0) - let dyn: Color = Color(dynamicProvider: { _ in grey }) - let rgba: Color = Color(red: 0.1, green: 0.3, blue: 0.7, alpha: 1.0) - let hsba: Color = - Color(hue: 0.61, saturation: 0.85, brightness: 0.70, alpha: 1.0) - - XCTAssertTrue(grey.getWhite(nil, alpha: nil)) - - var white: Double = 0.0, alpha: Double = 0.0 - XCTAssertTrue(grey.getWhite(&white, alpha: &alpha)) - XCTAssertEqual(white, 0.39) - XCTAssertEqual(alpha, 1.0) - - XCTAssertTrue(dyn.getWhite(&white, alpha: &alpha)) - - XCTAssertTrue(rgba.getWhite(&white, alpha: &alpha)) - XCTAssertEqual(white, 0.29, accuracy: 0.01) - XCTAssertEqual(alpha, 1.0) - - XCTAssertTrue(hsba.getWhite(&white, alpha: &alpha)) - XCTAssertEqual(white, 0.29, accuracy: 0.01) - XCTAssertEqual(alpha, 1.0) - } - - static var allTests = [ - ("testGetColorComponentsRGBA", testGetColorComponentsRGBA), - ("testGetColorComponentsHSBA", testGetColorComponentsHSBA), - ("testGetColorComponentsGrey", testGetColorComponentsGrey), - ] -} diff --git a/Tests/UICoreTests/CubicTimingParametersTests.swift b/Tests/UICoreTests/CubicTimingParametersTests.swift deleted file mode 100644 index 84178fd7..00000000 --- a/Tests/UICoreTests/CubicTimingParametersTests.swift +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright © 2021 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import XCTest -import SwiftWin32 - -final class CubicTimingParametersTests: XCTestCase { - func testDefaultState() { - let parameters1: CubicTimingParameters = CubicTimingParameters() - XCTAssertEqual(parameters1.animationCurve, .linear) - XCTAssertEqual(parameters1.controlPoint1, .zero) - - let parameters2: CubicTimingParameters = - CubicTimingParameters(animationCurve: .linear) - XCTAssertEqual(parameters2.animationCurve, .linear) - XCTAssertEqual(parameters2.controlPoint1, .zero) - XCTAssertEqual(parameters2.controlPoint2, .zero) - - let parameters3: CubicTimingParameters = - CubicTimingParameters(controlPoint1: .zero, controlPoint2: .zero) - XCTAssertEqual(parameters3.animationCurve, .linear) - XCTAssertEqual(parameters3.controlPoint1, .zero) - XCTAssertEqual(parameters3.controlPoint2, .zero) - } - - static var allTests = [ - ("testDefaultState", testDefaultState) - ] -} diff --git a/Tests/UICoreTests/DatePickerTests.swift b/Tests/UICoreTests/DatePickerTests.swift deleted file mode 100644 index f195d8e3..00000000 --- a/Tests/UICoreTests/DatePickerTests.swift +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright © 2021 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import XCTest -import WinSDK -import Foundation -@testable import SwiftWin32 - -final class DatePickerTests: XCTestCase { - func testDateAccessors() { - var ftSystemTime: FILETIME = FILETIME() - GetSystemTimeAsFileTime(&ftSystemTime) - var ftLocalSystemTime: FILETIME = FILETIME() - FileTimeToLocalFileTime(&ftSystemTime, &ftLocalSystemTime) - - let datepicker: DatePicker = DatePicker(frame: .zero) - - let time: Date = - Date(timeIntervalSince1970: ftLocalSystemTime.timeIntervalSince1970) - // FIXME(compnerd) can we use a tigher bounds? - XCTAssertTrue(datepicker.date.distance(to: time) <= 1.0) - - datepicker.date = Date(timeIntervalSinceReferenceDate: 410220000) - XCTAssertEqual(datepicker.date, - Date(timeIntervalSinceReferenceDate: 410220000)) - } - - static var allTests = [ - ("testDateAccessors", testDateAccessors), - ] -} diff --git a/Tests/UICoreTests/EventTests.swift b/Tests/UICoreTests/EventTests.swift deleted file mode 100644 index 7d811c72..00000000 --- a/Tests/UICoreTests/EventTests.swift +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright © 2021 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import XCTest -@testable import SwiftWin32 - -final class EventTests: XCTestCase { - func testConstructPressesEvent() { - let event: Event = .init(type: .presses, subtype: .none, timestamp: 0) - XCTAssertEqual(event.buttonMask, []) - XCTAssertEqual(event.modifierFlags, []) - XCTAssertEqual(event.timestamp, 0) - } - - static var allTests = [ - ("testConstructPressesEvent", testConstructPressesEvent) - ] -} diff --git a/Tests/UICoreTests/LabelTests.swift b/Tests/UICoreTests/LabelTests.swift deleted file mode 100644 index 241dbfb8..00000000 --- a/Tests/UICoreTests/LabelTests.swift +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright © 2023 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import XCTest -@testable import SwiftWin32 - -final class LabelTests: XCTestCase { - func testAlignment() { - let label: Label = Label(frame: .zero) - - // FIXME(compnerd) this should be `natural` - XCTAssertEqual(label.textAlignment, .left) - - label.textAlignment = .right - XCTAssertEqual(label.textAlignment, .right) - } - - static var allTests = [ - ("testAlignment", testAlignment), - ] -} - diff --git a/Tests/UICoreTests/MenuBuilderTests.swift b/Tests/UICoreTests/MenuBuilderTests.swift deleted file mode 100644 index 77014196..00000000 --- a/Tests/UICoreTests/MenuBuilderTests.swift +++ /dev/null @@ -1,142 +0,0 @@ -// Copyright © 2021 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import XCTest -import WinSDK -@testable import SwiftWin32 - -final class MenuBuilderTests: XCTestCase { - func testConstruct() { - let view: View = View(frame: .zero) - - let builder: MenuBuilder? = _MenuBuilder(for: view) - XCTAssertNotNil(builder) - } - - func testInsertSibling() { - let view: View = View(frame: .zero) - guard let builder = _MenuBuilder(for: view) else { return } - - builder.insertSibling(Menu(identifier: .application), beforeMenu: .root) - XCTAssertNotNil(builder.menu(for: .application)) - - builder.insertSibling(Menu(identifier: .edit), afterMenu: .root) - XCTAssertNotNil(builder.menu(for: .edit)) - - builder.insertSibling(Menu(identifier: .file), beforeMenu: .edit) - XCTAssertNotNil(builder.menu(for: .file)) - - builder.insertSibling(Menu(identifier: .services), beforeMenu: .quit) - XCTAssertNotNil(builder.menu(for: .services)) - - builder.insertSibling(Menu(identifier: .help), afterMenu: .quit) - XCTAssertNotNil(builder.menu(for: .help)) - } - - func testInsertChild() { - let view: View = View(frame: .zero) - guard let builder = _MenuBuilder(for: view) else { return } - - builder.insertSibling(Menu(identifier: .window), beforeMenu: .view) - let window = builder.menu(for: .window) - XCTAssertNotNil(window) - - builder.insertChild(Menu(identifier: .bringAllToFront), - atStartOfMenu: .window) - builder.insertChild(Menu(identifier: .minimizeAndZoom), - atEndOfMenu: .window) - - XCTAssertEqual(window?.children.count ?? 0, 2) - XCTAssertEqual((window?.children[0] as? Menu)?.identifier, .bringAllToFront) - XCTAssertEqual((window?.children[1] as? Menu)?.identifier, .minimizeAndZoom) - - builder.insertChild(Menu(identifier: .fullscreen), - atStartOfMenu: .preferences) - builder.insertChild(Menu(identifier: .toolbar), - atEndOfMenu: .hide) - } - - func testRemove() { - let view: View = View(frame: .zero) - guard let builder = _MenuBuilder(for: view) else { return } - - builder.insertSibling(Menu(identifier: .application), beforeMenu: .root) - XCTAssertNotNil(builder.menu(for: .application)) - - builder.remove(menu: .application) - XCTAssertNil(builder.menu(for: .application)) - } - - func testReplace() { - let view: View = View(frame: .zero) - guard let builder = _MenuBuilder(for: view) else { return } - - builder.insertSibling(Menu(identifier: .application), beforeMenu: .root) - XCTAssertNotNil(builder.menu(for: .application)) - - builder.replace(menu: .application, with: Menu(identifier: .file)) - XCTAssertNil(builder.menu(for: .application)) - XCTAssertNotNil(builder.menu(for: .file)) - - XCTAssertNil(builder.menu(for: .quit)) - builder.replace(menu: .quit, with: Menu(identifier: .about)) - XCTAssertNotNil(builder.menu(for: .file)) - XCTAssertNil(builder.menu(for: .about)) - } - - func testBuildMenu() { - let view: View = View(frame: .zero) - guard let builder = _MenuBuilder(for: view) else { return } - - let hMenu = (builder.system as? _MenuBuilder)?.hMenu - XCTAssertNotNil(hMenu?.value) - XCTAssertEqual(GetMenuItemCount(hMenu?.value), 0) - } - - func testBuildMenuWithChildren() { - let view: View = View(frame: .zero) - guard let builder = _MenuBuilder(for: view) else { return } - - let menu = Menu(title: "menu1", children: [Command(title: "item1") { _ in }, - Action(title: "item2") { _ in }]) - builder.insertSibling(menu, afterMenu: .root) - builder.setNeedsRebuild() - - let hRootMenu = (builder.system as? _MenuBuilder)?.hMenu - XCTAssertNotNil(hRootMenu?.value) - XCTAssertEqual(GetMenuItemCount(hRootMenu?.value), 1) - - let hMenu = GetSubMenu(hRootMenu?.value, 0) - XCTAssertNotNil(hMenu) - XCTAssertEqual(GetMenuItemCount(hMenu), 2) - } - - func testRebuildMenu() { - let view: View = View(frame: .zero) - guard let builder = _MenuBuilder(for: view) else { return } - - let hMenu1 = (builder.system as? _MenuBuilder)?.hMenu - - let menu = Menu(title: "title", children: [Command(title: "cmd") { _ in }]) - builder.insertSibling(menu, afterMenu: .root) - builder.setNeedsRebuild() - - let hMenu2 = (builder.system as? _MenuBuilder)?.hMenu - - XCTAssert(hMenu1 === hMenu2) - XCTAssertNotNil(hMenu1) - XCTAssertNotNil(hMenu2) - XCTAssertEqual(hMenu1?.value, hMenu2?.value) - } - - public static var allTests = [ - ("testConstruct", testConstruct), - ("testInsertSibling", testInsertSibling), - ("testInsertChild", testInsertChild), - ("testRemove", testRemove), - ("testReplace", testReplace), - ("testBuildMenu", testBuildMenu), - ("testBuildMenuWithChildren", testBuildMenuWithChildren), - ("testRebuildMenu", testRebuildMenu), - ] -} diff --git a/Tests/UICoreTests/OffsetTests.swift b/Tests/UICoreTests/OffsetTests.swift deleted file mode 100644 index 7cbf396c..00000000 --- a/Tests/UICoreTests/OffsetTests.swift +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright © 2021 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import XCTest -import SwiftWin32 - -final class OffsetTests: XCTestCase { - func testOffsetConstructor() { - XCTAssertEqual(Offset(), .zero) - - let offset: Offset = Offset(horizontal: .infinity, vertical: .infinity) - XCTAssertEqual(offset.horizontal, .infinity) - XCTAssertEqual(offset.vertical, .infinity) - } - - func testOffsetStringForOffset() { - XCTAssertEqual(Offset.offset(for: "invalid"), .zero) - XCTAssertEqual(Offset.offset(for: "{"), .zero) - XCTAssertEqual(Offset.offset(for: "{1"), .zero) - XCTAssertEqual(Offset.offset(for: "{1,"), .zero) - XCTAssertEqual(Offset.offset(for: "{1,1"), .zero) - XCTAssertEqual(Offset.offset(for: "{1,1}"), Offset(horizontal: 1, vertical: 1)) - } - - func testOffsetStringRoundtrip() { - let offset: Offset = Offset(horizontal: 1, vertical: 2) - let string: String = Offset.string(for: offset) - XCTAssertEqual(string, "{1, 2}") - XCTAssertEqual(offset, Offset.offset(for: string)) - } - - static var allTests = [ - ("testOffsetConstructor", testOffsetConstructor), - ("testOffsetStringForOffset", testOffsetStringForOffset), - ("testOffsetStringRoundtrip", testOffsetStringRoundtrip), - ] -} diff --git a/Tests/UICoreTests/PresentationControllerTests.swift b/Tests/UICoreTests/PresentationControllerTests.swift deleted file mode 100644 index a10baba4..00000000 --- a/Tests/UICoreTests/PresentationControllerTests.swift +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright © 2021 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import XCTest -import SwiftWin32 - -final class PresentationControllerTests: XCTestCase { - func testDefaultProperties() { - let presentedViewController: ViewController = ViewController() - let presentingViewController: ViewController = ViewController() - let controller: PresentationController = - PresentationController(presentedViewController: presentedViewController, - presenting: presentingViewController) - - XCTAssertNil(controller.delegate) - XCTAssertTrue(controller.presentingViewController === presentingViewController) - XCTAssertTrue(controller.presentedViewController === presentedViewController) - XCTAssertNil(controller.overrideTraitCollection) - XCTAssertTrue(controller.shouldPresentInFullscreen) - XCTAssertFalse(controller.shouldRemovePresentersView) - } - - static var allTests = [ - ("testDefaultProperties", testDefaultProperties), - ] -} diff --git a/Tests/UICoreTests/PressTests.swift b/Tests/UICoreTests/PressTests.swift deleted file mode 100644 index b9916d1f..00000000 --- a/Tests/UICoreTests/PressTests.swift +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright © 2021 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import XCTest -@testable import SwiftWin32 - -final class PressTests: XCTestCase { - func testPressEquality() { - let p: Press = .init(type: .select, phase: .began, force: 0.0, timestamp: 0) - XCTAssertEqual(p, p) - - // FIXME(compnerd) is this correct? - let q: Press = .init(type: .select, phase: .began, force: 0.0, timestamp: 0) - XCTAssertNotEqual(p, q) - } - - static var allTests = [ - ("testPressEquality", testPressEquality), - ] -} diff --git a/Tests/UICoreTests/PressesEventTests.swift b/Tests/UICoreTests/PressesEventTests.swift deleted file mode 100644 index 8aa097ed..00000000 --- a/Tests/UICoreTests/PressesEventTests.swift +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright © 2021 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import XCTest -@testable import SwiftWin32 - -final class PressesEventTests: XCTestCase { - func testConstruct() { - let event: PressesEvent = .init(presses: [], timestamp: 0) - XCTAssertEqual(event.type, .presses) - XCTAssertEqual(event.subtype, .none) - XCTAssertEqual(event.timestamp, 0) - } - - static var allTests = [ - ("testConstruct", testConstruct), - ] -} diff --git a/Tests/UICoreTests/ResponderTests.swift b/Tests/UICoreTests/ResponderTests.swift deleted file mode 100644 index 89eadda1..00000000 --- a/Tests/UICoreTests/ResponderTests.swift +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright © 2021 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import XCTest -@testable import SwiftWin32 - -final class ResponderTests: XCTestCase { - func testDefaultProperties() { - let responder: Responder = Responder() - XCTAssertNil(responder.next) - XCTAssertFalse(responder.isFirstResponder) - XCTAssertFalse(responder.canBecomeFirstResponder) - XCTAssertTrue(responder.canResignFirstResponder) - } - - static var allTests = [ - ("testDefaultProperties", testDefaultProperties), - ] -} diff --git a/Tests/UICoreTests/SpringTimingParametersTests.swift b/Tests/UICoreTests/SpringTimingParametersTests.swift deleted file mode 100644 index 1438f071..00000000 --- a/Tests/UICoreTests/SpringTimingParametersTests.swift +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright © 2021 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import XCTest -import SwiftWin32 - -final class SpringTimingParametersTests: XCTestCase { - func testDefaultState() { - let parameters1: SpringTimingParameters = SpringTimingParameters() - XCTAssertEqual(parameters1.initialVelocity, .zero) - - let parameters2: SpringTimingParameters = - SpringTimingParameters(dampingRatio: 1.0) - XCTAssertEqual(parameters2.initialVelocity, .zero) - - let parameters3: SpringTimingParameters = - SpringTimingParameters(mass: 0.0, stiffness: 0.0, damping: 0.0, - initialVelocity: .zero) - XCTAssertEqual(parameters3.initialVelocity, .zero) - } - - static var allTests = [ - ("testDefaultState", testDefaultState) - ] -} diff --git a/Tests/UICoreTests/StepperTests.swift b/Tests/UICoreTests/StepperTests.swift deleted file mode 100644 index 47f60712..00000000 --- a/Tests/UICoreTests/StepperTests.swift +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright © 2021 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3 - -import XCTest -import WinSDK -import TestUtilities -@testable import SwiftWin32 - -final class StepperTests: XCTestCase { - func testValueChangedNotification() { - let stepper: Stepper = Stepper(frame: .zero) - - let expectation: XCTestExpectation = - self.expectation(description: "value change notification dispatched") - let observer: ControlEventObserver = - ControlEventObserver(expectation: expectation) - - withExtendedLifetime(observer) { - stepper.addTarget(observer, action: ControlEventObserver.observe, - for: .valueChanged) - - // TODO(compnerd) this is a workaround until UIAutomation is properly - // wired up. We bypass the Windows UI subsystem, sending the underlying - // `WM_HSCROLL` directly to the proxy. - if let hWnd = FindWindowW("Swift.Stepper.Proxy".wide, nil) { - _ = SendMessageW(hWnd, DWORD(WM_HSCROLL), WPARAM(0), - LPARAM(UInt(bitPattern: stepper.hWnd))) - } - } - - // FIXME(compnerd) what is a good timeout value to use? - waitForExpectations(timeout: 1) - } - - func testValueChangedNotificationFailure() { - let stepper: Stepper = Stepper(frame: .zero) - - let expectation: XCTestExpectation = - self.expectation(description: "value change notification dispatched") - expectation.isInverted = true - - let observer: ControlEventObserver = - ControlEventObserver(expectation: expectation) - - withExtendedLifetime(observer) { - stepper.addTarget(observer, action: ControlEventObserver.observe, - for: .valueChanged) - - // TODO(compnerd) this is a workaround until UIAutomation is properly - // wired up. We bypass the Windows UI subsystem, sending the underlying - // `WM_HSCROLL` directly to the proxy. - if let hWnd = FindWindowW("Swift.Stepper.Proxy".wide, nil) { - _ = SendMessageW(hWnd, DWORD(WM_HSCROLL), WPARAM(0), LPARAM(0)) - } - } - - // FIXME(compnerd) what is a good timeout value to use? - waitForExpectations(timeout: 1) - } -} diff --git a/Tests/UICoreTests/TextViewTests.swift b/Tests/UICoreTests/TextViewTests.swift deleted file mode 100644 index 8a50ba24..00000000 --- a/Tests/UICoreTests/TextViewTests.swift +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright © 2021 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import XCTest -import WinSDK -@testable import SwiftWin32 - -final class TextViewTests: XCTestCase { - static var hModule: HMODULE? - - override class func setUp() { - TextViewTests.hModule = "Msftedit.dll".withCString(encodedAs: UTF16.self) { - LoadLibraryW($0) - } - } - - func testConstruct() throws { - try XCTSkipIf(TextViewTests.hModule == nil, "Msftedit.dll not loaded") - - let view: TextView = TextView(frame: .zero) - XCTAssertNotEqual(view.hWnd, INVALID_HANDLE_VALUE) - } - - static var allTests = [ - ("testConstruct", testConstruct), - ] -} diff --git a/Tests/UICoreTests/ViewTests.swift b/Tests/UICoreTests/ViewTests.swift deleted file mode 100644 index bf0f2fef..00000000 --- a/Tests/UICoreTests/ViewTests.swift +++ /dev/null @@ -1,166 +0,0 @@ -// Copyright © 2021 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import XCTest -#if swift(>=5.7) -import CoreGraphics -#endif -@testable import SwiftWin32 - -final class ViewTests: XCTestCase { - func testConvertSameParent() { - let window = View(frame: Rect(x: 0.0, y: 0.0, width: 1000, height: 1000)) - - let textfield: View = - View(frame: Rect(x: 4.0, y: 92.0, width: 254.0, height: 17.0)) - - let password: View = - View(frame: Rect(x: 4.0, y: 113.0, width: 254.0, height: 17.0)) - - window.addSubview(password) - window.addSubview(textfield) - - let boundsRect = Rect(x: 0, y: 0, width: 254.0, height: 17.0) - - let convertRect = textfield.convert(boundsRect, to: password) - - let convertPoint = textfield.convert(textfield.bounds.origin, to: password) - - XCTAssertEqual(convertRect, Rect(x: 0.0, y: -21.0, width: 254.0, height: 17.0)) - XCTAssertEqual(convertPoint, Point(x: 0.0, y: -21.0)) - } - - func testConvertWithRotationsAndBounds() { - let root = View(frame: Rect(x: 0.0, y: 0.0, width: 1000, height: 1000)) - - let childA = View(frame: Rect(x: 4.0, y: 92.0, width: 254.0, height: 17.0)) - childA.transform = AffineTransform(rotationAngle: 110) - childA.bounds = Rect(x: 144.0, y: 23.0, width: 20, height: 15) - - let childB = View(frame: Rect(x: 12.0, y: 150.0, width: 400.0, height: 400.0)) - childB.transform = AffineTransform(rotationAngle: -30) - - let grandChild = View(frame: Rect(x: 40.0, y: 113.0, width: 10, height: 10)) - grandChild.transform = AffineTransform(rotationAngle: 42) - grandChild.bounds = Rect(x: 4.0, y: 3.0, width: 20, height: 15) - - root.addSubview(childA) - root.addSubview(childB) - - childB.addSubview(grandChild) - - // Test data comes from the UIKit implementation, running on an iPhone, - // and so deviation is expected. - let accuracy = 0.00000000001 - - let inputPoint = Point(x: 45, y: 115) - - var point = grandChild.convert(inputPoint, to: childA) - XCTAssertEqual(point.x, -72.9941233911901, accuracy: accuracy) - XCTAssertEqual(point.y, -114.85495931677, accuracy: accuracy) - - point = grandChild.convert(inputPoint, from: childA) - XCTAssertEqual(point.x, 80.12346855145998, accuracy: accuracy) - XCTAssertEqual(point.y, -140.97315764408575, accuracy: accuracy) - - - let inputRect = Rect(origin: Point(x: 45, y: 115), size: Size(width: 13, height: 14)) - var rect = grandChild.convert(inputRect, to: childB) - XCTAssertEqual(rect.origin.x, 123.17714789769627, accuracy: accuracy) - XCTAssertEqual(rect.origin.y, 30.274792065592464, accuracy: accuracy) - XCTAssertEqual(rect.size.width, 18.031110765667435, accuracy: accuracy) - XCTAssertEqual(rect.size.height, 17.514574532740156, accuracy: accuracy) - - rect = grandChild.convert(inputRect, to: childA) - XCTAssertEqual(rect.origin.x, -91.9808292852884, accuracy: accuracy) - XCTAssertEqual(rect.origin.y, -126.65734667117412, accuracy: accuracy) - XCTAssertEqual(rect.size.width, 19.295318391541684, accuracy: accuracy) - XCTAssertEqual(rect.size.height, 19.58870361060326, accuracy: accuracy) - - rect = grandChild.convert(inputRect, from: childA) - XCTAssertEqual(rect.origin.x, 69.16410886522763, accuracy: accuracy) - XCTAssertEqual(rect.origin.y, -160.22950933436533, accuracy: accuracy) - XCTAssertEqual(rect.size.width, 19.295318391541684, accuracy: accuracy) - XCTAssertEqual(rect.size.height, 19.58870361060326, accuracy: accuracy) - } - - func testConvertWithAllTransformsAndBounds() { - let root = View(frame: Rect(x: 0.0, y: 0.0, width: 1000, height: 1000)) - let childA = View(frame: Rect(x: 4.0, y: 92.0, width: 254.0, height: 17.0)) - childA.transform = AffineTransform(translationX: 68, y: 419) - childA.bounds = Rect(x: 144.0, y: 23.0, width: 20, height: 15) - - let childB = View(frame: Rect(x: 12.0, y: 150.0, width: 400.0, height: 400.0)) - childB.transform = AffineTransform(scaleX: 7, y: 18) - - let grandChild = View(frame: Rect(x: 40.0, y: 113.0, width: 10, height: 10)) - grandChild.transform = AffineTransform(rotationAngle: 42) - grandChild.bounds = Rect(x: 4.0, y: 3.0, width: 20, height: 15) - - root.addSubview(childA) - root.addSubview(childB) - - childB.addSubview(grandChild) - - // Test data comes from the UIKit implementation, running on an iPhone, - // and so deviation is expected. - let accuracy = 0.00000000001 - - let inputPoint = Point(x: 45, y: 115) - - var point = grandChild.convert(inputPoint, to: childA) - XCTAssertEqual(point.x, -334.36130105218615, accuracy: accuracy) - XCTAssertEqual(point.y, -2878.791401230013, accuracy: accuracy) - - point = grandChild.convert(inputPoint, from: childA) - XCTAssertEqual(point.x, -129.11445551798738, accuracy: accuracy) - XCTAssertEqual(point.y, 98.14414561159256, accuracy: accuracy) - - let inputRect = Rect(origin: Point(x: 45, y: 115), size: Size(width: 13, height: 14)) - var rect = grandChild.convert(inputRect, to: childB) - XCTAssertEqual(rect.origin.x, 123.17714789769627, accuracy: accuracy) - XCTAssertEqual(rect.origin.y, 30.274792065592464, accuracy: accuracy) - XCTAssertEqual(rect.size.width, 18.031110765667435, accuracy: accuracy) - XCTAssertEqual(rect.size.height, 17.514574532740156, accuracy: accuracy) - - rect = grandChild.convert(inputRect, to: childA) - XCTAssertEqual(rect.origin.x, -370.7599647161262, accuracy: accuracy) - XCTAssertEqual(rect.origin.y, -3194.0537428193356, accuracy: accuracy) - XCTAssertEqual(rect.size.width, 126.21777535967215, accuracy: accuracy) - XCTAssertEqual(rect.size.height, 315.26234158932266, accuracy: accuracy) - - rect = grandChild.convert(inputRect, from: childA) - XCTAssertEqual(rect.origin.x, -130.5701354815033, accuracy: accuracy) - XCTAssertEqual(rect.origin.y, 97.83304592215717, accuracy: accuracy) - XCTAssertEqual(rect.size.width, 1.4556799635159337, accuracy: accuracy) - XCTAssertEqual(rect.size.height, 2.0132111355644327, accuracy: accuracy) - } - - func testViewTraitCollection() { - let window: Window = - Window(frame: Rect(x: 0.0, y: 0.0, width: 640, height: 480)) - - let view: View = View(frame: .zero) - XCTAssertTrue(view.traitCollection === TraitCollection.current) - - window.addSubview(view) - XCTAssertTrue(view.traitCollection === TraitCollection.current) - - let session: SceneSession = - SceneSession(identifier: UUID().uuidString, role: .windowApplication) - let scene: WindowScene = - WindowScene(session: session, - connectionOptions: Scene.ConnectionOptions()) - - window.windowScene = scene - // FIXME(compnerd) the view.window is not setup properly - // XCTAssertTrue(view.traitCollection === scene.screen.traitCollection) - } - - static var allTests = [ - ("testConvertSameParent", testConvertSameParent), - ("testConvertWithRotationsAndBounds", testConvertWithRotationsAndBounds), - ("testConvertWithAllTransformsAndBounds", testConvertWithAllTransformsAndBounds), - ("testViewTraitCollection", testViewTraitCollection), - ] -} diff --git a/Tests/UICoreTests/WindowTests.swift b/Tests/UICoreTests/WindowTests.swift deleted file mode 100644 index d70464a7..00000000 --- a/Tests/UICoreTests/WindowTests.swift +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright © 2021 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import XCTest -import WinSDK -#if swift(>=5.7) -import CoreGraphics -#endif -@testable import SwiftWin32 - -final class WindowTests: XCTestCase { - func testWindowMenuEmpty() { - let viewController = ViewController() - viewController.view = View(frame: Rect(x: 0, y: 0, width: 100, height: 100)) - - let window = Window(frame: Rect(x: 0, y: 0, width: 200, height: 200)) - XCTAssertNil(GetMenu(window.hWnd)) - - window.rootViewController = viewController - - let hMenu = GetMenu(window.hWnd) - XCTAssertEqual(GetMenuItemCount(hMenu), 0) - } - - func testWindowMenuWithSubmenus() { - // TODO: uncomment when ViewController is `open` - /* - class ViewControllerWithWindowMenu: ViewController { - override func buildMenu(with builder: MenuBuilder) { - builder.insertSibling(Menu(title: "title1", children: [Action(title: "action", handler: { _ in })]), - afterMenu: .root) - builder.insertSibling(Menu(title: "title2", children: [Command(title: "command", action: { _ in })]), - afterMenu: .root) - } - } - - let viewController = ViewControllerWithWindowMenu() - viewController.view = View(frame: Rect(x: 0, y: 0, width: 100, height: 100)) - - let window = Window(frame: Rect(x: 0, y: 0, width: 200, height: 200)) - window.rootViewController = viewController - - let hMenu = GetMenu(window.hWnd) - XCTAssertEqual(GetMenuItemCount(hMenu), 2) - */ - } - - static var allTests = [ - ("testWindowMenu", testWindowMenuEmpty), - ("testWindowMenuWithSubmenus", testWindowMenuWithSubmenus), - ] -} diff --git a/Tests/Utilities/Utilities.swift b/Tests/Utilities/Utilities.swift deleted file mode 100644 index 0dbff240..00000000 --- a/Tests/Utilities/Utilities.swift +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright © 2021 Saleem Abdulrasool -// SPDX-License-Identifier: BSD-3-Clause - -import XCTest - -public class ControlEventObserver { - private var expectation: XCTestExpectation - - public init(expectation: XCTestExpectation) { - self.expectation = expectation - } - - public func observe() { - self.expectation.fulfill() - } -} diff --git a/Tests/main.swift b/Tests/main.swift deleted file mode 100644 index f5c4257b..00000000 --- a/Tests/main.swift +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright © 2020 Saleem Abdulrasool . -// SPDX-License-Identifier: BSD-3-Clause - -import XCTest - -@testable import AutoLayoutTests -@testable import CoreGraphicsTests -@testable import UICoreTests - -XCTMain([ - testCase(AutoLayoutTests.allTests), - testCase(CoreGraphicsTests.allTests), - testCase(UICoreTests.allTests), -]) diff --git a/_config.yml b/_config.yml new file mode 100644 index 00000000..98984e9a --- /dev/null +++ b/_config.yml @@ -0,0 +1,67 @@ +# Welcome to Jekyll! +# +# This config file is meant for settings that affect your whole blog, values +# which you are expected to set up once and rarely edit after that. If you find +# yourself editing this file very often, consider using Jekyll's data files +# feature for the data you need to update frequently. +# +# For technical reasons, this file is *NOT* reloaded automatically when you use +# 'bundle exec jekyll serve'. If you change this file, please restart the server process. +# +# If you need help with YAML syntax, here are some quick references for you: +# https://learn-the-web.algonquindesign.ca/topics/markdown-yaml-cheat-sheet/#yaml +# https://learnxinyminutes.com/docs/yaml/ +# +# Site settings +# These are used to personalize your new site. If you look in the HTML files, +# you will see them accessed via {{ site.title }}, {{ site.email }}, and so on. +# You can create any custom variable you would like, and they will be accessible +# in the templates via {{ site.myvariable }}. + +title: Swift/Win32 +email: compnerd@compnerd.org +description: >- # this means to ignore newlines until "baseurl:" + A Swift Application Framework for Windows +baseurl: "/swift-win32" # the subpath of your site, e.g. /blog +url: "https://compnerd.github.io" # the base hostname & protocol for your site, e.g. http://example.com +twitter_username: compnerd +github_username: compnerd + +# Build settings +remote_theme: pmarsceill/just-the-docs +plugins: + - jekyll-feed + +# Exclude from processing. +# The following items will not be processed, by default. +# Any item listed under the `exclude:` key here will be automatically added to +# the internal "default list". +# +# Excluded items can be processed by explicitly listing the directories or +# their entries' file path in the `include:` list. +# +# exclude: +# - .sass-cache/ +# - .jekyll-cache/ +# - gemfiles/ +# - Gemfile +# - Gemfile.lock +# - node_modules/ +# - vendor/bundle/ +# - vendor/cache/ +# - vendor/gems/ +# - vendor/ruby/ +include: + - "SwiftWin32/_*" + +search_enabled: true +search: + heading_level: 2 + previews: 2 + preview_words_before: 3 + preview_words_after: 3 + tokenizer_separator: /[\s/]+/ + rel_url: true + button: true + +heading_anchors: true diff --git a/cmake/Modules/SwiftSupport.cmake b/cmake/Modules/SwiftSupport.cmake deleted file mode 100644 index c07611b8..00000000 --- a/cmake/Modules/SwiftSupport.cmake +++ /dev/null @@ -1,94 +0,0 @@ -#[[ -Copyright © 2019 Saleem Abdulrasool -All rights reserved. - -SPDX-License-Identifier: BSD-3-Clause -#]] - -# Returns the architecture name in a variable -# -# Usage: -# get_swift_host_arch(result_var_name) -# -# Sets ${result_var_name} with the converted architecture name derived from -# CMAKE_SYSTEM_PROCESSOR. -function(get_swift_host_arch result_var_name) - if("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "x86_64") - set("${result_var_name}" "x86_64" PARENT_SCOPE) - elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "aarch64") - set("${result_var_name}" "aarch64" PARENT_SCOPE) - elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "ppc64") - set("${result_var_name}" "powerpc64" PARENT_SCOPE) - elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "ppc64le") - set("${result_var_name}" "powerpc64le" PARENT_SCOPE) - elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "s390x") - set("${result_var_name}" "s390x" PARENT_SCOPE) - elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "armv6l") - set("${result_var_name}" "armv6" PARENT_SCOPE) - elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "armv7l") - set("${result_var_name}" "armv7" PARENT_SCOPE) - elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "armv7-a") - set("${result_var_name}" "armv7" PARENT_SCOPE) - elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "ARM64") - set("${result_var_name}" "x86_64" PARENT_SCOPE) - elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "AMD64") - set("${result_var_name}" "x86_64" PARENT_SCOPE) - elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "IA64") - set("${result_var_name}" "itanium" PARENT_SCOPE) - elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "x86") - set("${result_var_name}" "i686" PARENT_SCOPE) - elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "i686") - set("${result_var_name}" "i686" PARENT_SCOPE) - else() - message(FATAL_ERROR "Unrecognized architecture on host system: ${CMAKE_SYSTEM_PROCESSOR}") - endif() -endfunction() - -# Returns the os name in a variable -# -# Usage: -# get_swift_host_os(result_var_name) -# -# -# Sets ${result_var_name} with the converted OS name derived from -# CMAKE_SYSTEM_NAME. -function(get_swift_host_os result_var_name) - if(CMAKE_SYSTEM_NAME STREQUAL Darwin) - set(${result_var_name} macosx PARENT_SCOPE) - else() - string(TOLOWER ${CMAKE_SYSTEM_NAME} cmake_system_name_lc) - set(${result_var_name} ${cmake_system_name_lc} PARENT_SCOPE) - endif() -endfunction() - -function(_install_target module) - get_swift_host_os(swift_os) - get_target_property(type ${module} TYPE) - - if(type STREQUAL STATIC_LIBRARY) - set(swift swift_static) - else() - set(swift swift) - endif() - - install(TARGETS ${module} - ARCHIVE DESTINATION lib/${swift}/${swift_os} - LIBRARY DESTINATION lib/${swift}/${swift_os} - RUNTIME DESTINATION bin) - if(type STREQUAL EXECUTABLE) - return() - endif() - - get_swift_host_arch(swift_arch) - get_target_property(module_name ${module} Swift_MODULE_NAME) - if(NOT module_name) - set(module_name ${module}) - endif() - - install(FILES $/${module_name}.swiftdoc - DESTINATION lib/${swift}/${swift_os}/${module_name}.swiftmodule - RENAME ${swift_arch}.swiftdoc) - install(FILES $/${module_name}.swiftmodule - DESTINATION lib/${swift}/${swift_os}/${module_name}.swiftmodule - RENAME ${swift_arch}.swiftmodule) -endfunction() diff --git a/index.md b/index.md new file mode 100644 index 00000000..7213164c --- /dev/null +++ b/index.md @@ -0,0 +1,12 @@ +--- +# Feel free to add content and custom Front Matter to this file. +# To modify the layout, see https://jekyllrb.com/docs/themes/#overriding-theme-defaults + +layout: home +--- + +Swift/Win32 aims to provide a [MVC](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller) model for writing applications on Windows. It provides Swift friendly wrapping of the Win32 APIs much like [MFC](https://en.wikipedia.org/wiki/Microsoft_Foundation_Class_Library) did for C++. + +

+ Swift/Win32 Screenshot +

diff --git a/Documentation/Images/screenshot.png b/media/images/screenshot.png similarity index 100% rename from Documentation/Images/screenshot.png rename to media/images/screenshot.png