forked from hbang/NewTerm
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[ios] Initial layout of keyboard toolbars in SwiftUI (hbang#75)
- Loading branch information
1 parent
ce08d91
commit 2094bf4
Showing
5 changed files
with
450 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
// | ||
// KeyboardButtonStyle.swift | ||
// NewTerm (iOS) | ||
// | ||
// Created by Chris Harper on 11/21/21. | ||
// | ||
|
||
import SwiftUI | ||
|
||
struct KeyboardKeyButtonStyle: ButtonStyle { | ||
var selected: Bool = false | ||
var shadow: Bool = false | ||
var fixedWidth: CGFloat? | ||
|
||
func makeBody(configuration: Configuration) -> some View { | ||
if fixedWidth == nil { | ||
configuration.label | ||
.font(.system(size: isBigDevice ? 15 : 13)) | ||
.frame(height: (isBigDevice ? 35 : 30)) | ||
.padding(.horizontal, 8) | ||
.background(configuration.isPressed ? Color(.keyBackgroundHighlighted) : (selected ? Color(.keyBackgroundSelected) : Color(.keyBackgroundNormal))) | ||
.cornerRadius(isBigDevice ? 6 : 4) | ||
.shadow(color: shadow ? Color.black.opacity(0.8) : .clear, radius: 0, x: 0, y: shadow ? 1 : 0) | ||
.animation(nil) | ||
} else { | ||
configuration.label | ||
.font(.system(size: isBigDevice ? 15 : 13)) | ||
.frame(width: fixedWidth!, height: (isBigDevice ? 35 : 30)) | ||
.background(configuration.isPressed ? Color(.keyBackgroundHighlighted) : (selected ? Color(.keyBackgroundSelected) : Color(.keyBackgroundNormal))) | ||
.cornerRadius(isBigDevice ? 6 : 4) | ||
.shadow(color: shadow ? Color.black.opacity(0.8) : .clear, radius: 0, x: 0, y: shadow ? 1 : 0) | ||
.animation(nil) | ||
} | ||
} | ||
|
||
init(selected: Bool = false, hasShadow shadow: Bool = false, fixedWidth: CGFloat? = nil) { | ||
self.selected = selected | ||
self.shadow = shadow | ||
self.fixedWidth = fixedWidth | ||
} | ||
} | ||
|
||
extension ButtonStyle where Self == KeyboardKeyButtonStyle { | ||
|
||
///A button style that mimicks the keys of the software keyboard. | ||
static func keyboardKey(selected: Bool = false, hasShadow shadow: Bool = false, fixedWidth: CGFloat? = nil) -> KeyboardKeyButtonStyle { | ||
return KeyboardKeyButtonStyle(selected: selected, hasShadow: shadow, fixedWidth: fixedWidth) | ||
} | ||
} | ||
|
||
struct KeyboardKeyButtonStyleContainer: View { | ||
var body: some View { | ||
HStack(alignment: .center, spacing: 5) { | ||
Button { | ||
|
||
} label: { | ||
Text("Ctrl") | ||
} | ||
.buttonStyle(.keyboardKey()) | ||
|
||
Button { | ||
|
||
} label: { | ||
Image(systemName: "arrow.down") | ||
} | ||
.buttonStyle(.keyboardKey(fixedWidth: 31)) | ||
} | ||
.padding() | ||
} | ||
} | ||
|
||
struct KeyboardKeyButtonStyleContainer_Previews: PreviewProvider { | ||
static var previews: some View { | ||
ForEach(ColorScheme.allCases, id: \.self) { scheme in | ||
KeyboardKeyButtonStyleContainer() | ||
.preferredColorScheme(scheme) | ||
.previewLayout(.sizeThatFits) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,199 @@ | ||
// | ||
// KeyboardPopupToolbarView.swift | ||
// NewTerm (iOS) | ||
// | ||
// Created by Chris Harper on 11/21/21. | ||
// | ||
|
||
import SwiftUI | ||
import NewTermCommon | ||
|
||
struct KeyboardPopupToolbarView: View { | ||
|
||
struct KeyType { | ||
enum function: Int, Equatable, CaseIterable { | ||
case f1 | ||
case f2 | ||
case f3 | ||
case f4 | ||
case f5 | ||
case f6 | ||
case f7 | ||
case f8 | ||
case f9 | ||
case f10 | ||
case f11 | ||
case f12 | ||
|
||
var text: String { | ||
return "F\(self.rawValue)" | ||
} | ||
} | ||
|
||
enum leading: Int, CaseIterable { | ||
case home | ||
case end | ||
|
||
var text: String { | ||
switch self { | ||
case .home: | ||
return "Home" | ||
case .end: | ||
return "End" | ||
} | ||
} | ||
} | ||
|
||
enum paging: Int, CaseIterable { | ||
case pgUp | ||
case pgDn | ||
|
||
var text: String { | ||
switch self { | ||
case .pgUp: | ||
return "PgUp" | ||
case .pgDn: | ||
return "PgDn" | ||
} | ||
} | ||
} | ||
|
||
enum trailing: Int, CaseIterable { | ||
case frwdDel | ||
|
||
var imageName: String { | ||
switch self { | ||
case .frwdDel: | ||
return "delete.forward" | ||
} | ||
} | ||
|
||
} | ||
} | ||
|
||
var functionButtonGroup: some View { | ||
HStack(alignment: .center, spacing: 5) { | ||
ForEach(KeyType.function.allCases, id: \.self) { button in | ||
Button { | ||
switch button { | ||
case .f1: | ||
break | ||
case .f2: | ||
break | ||
case .f3: | ||
break | ||
case .f4: | ||
break | ||
case .f5: | ||
break | ||
case .f6: | ||
break | ||
case .f7: | ||
break | ||
case .f8: | ||
break | ||
case .f9: | ||
break | ||
case .f10: | ||
break | ||
case .f11: | ||
break | ||
case .f12: | ||
break | ||
} | ||
} label: { | ||
Text("\(button.text)") | ||
} | ||
.buttonStyle( | ||
.keyboardKey(fixedWidth: 35) | ||
) | ||
} | ||
} | ||
} | ||
|
||
var leadingButtonGroup: some View { | ||
HStack(alignment: .center, spacing: 5) { | ||
// 1: home; 2: end | ||
ForEach(KeyType.leading.allCases, id: \.self) { button in | ||
Button { | ||
switch button { | ||
case .home: | ||
break | ||
case .end: | ||
break | ||
} | ||
} label: { | ||
Text(button.text) | ||
} | ||
.buttonStyle( | ||
.keyboardKey(fixedWidth: 50) | ||
) | ||
} | ||
} | ||
} | ||
|
||
var pagingButtonGroup: some View { | ||
HStack(alignment: .center, spacing: 5) { | ||
ForEach(KeyType.paging.allCases, id: \.self) { button in | ||
Button { | ||
switch button { | ||
case .pgUp: | ||
break | ||
case .pgDn: | ||
break | ||
} | ||
} label: { | ||
Text(button.text) | ||
} | ||
.buttonStyle( | ||
.keyboardKey(fixedWidth: 50) | ||
) | ||
} | ||
} | ||
} | ||
|
||
var trailingButtonGroup: some View { | ||
HStack(alignment: .center, spacing: 5) { | ||
ForEach(KeyType.trailing.allCases, id: \.self) { button in | ||
Button { | ||
switch button { | ||
case .frwdDel: | ||
break | ||
} | ||
} label: { | ||
Image(systemName: button.imageName) | ||
} | ||
.buttonStyle(.keyboardKey()) | ||
} | ||
} | ||
} | ||
|
||
var body: some View { | ||
VStack(spacing: 5) { | ||
ScrollView(.horizontal, showsIndicators: false) { | ||
functionButtonGroup | ||
.padding(.horizontal, 5) | ||
} | ||
HStack(alignment: .center, spacing: 10) { | ||
leadingButtonGroup | ||
pagingButtonGroup | ||
Spacer() | ||
trailingButtonGroup | ||
} | ||
.padding(.horizontal, 5) | ||
} | ||
.frame(maxWidth: .infinity, maxHeight: isBigDevice ? 96 : 80) | ||
.background(Color(.keyboardToolbarBackground)) | ||
} | ||
|
||
} | ||
|
||
struct KeyboardPopupToolbarView_Previews: PreviewProvider { | ||
static var previews: some View { | ||
ForEach(ColorScheme.allCases, id: \.self) { scheme in | ||
KeyboardPopupToolbarView() | ||
.preferredColorScheme(scheme) | ||
.previewLayout(.sizeThatFits) | ||
} | ||
} | ||
} |
Oops, something went wrong.