Skip to content

Commit

Permalink
[ios] Initial layout of keyboard toolbars in SwiftUI (hbang#75)
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisharper22 authored and kirb committed Mar 22, 2022
1 parent ce08d91 commit 2094bf4
Show file tree
Hide file tree
Showing 5 changed files with 450 additions and 4 deletions.
8 changes: 4 additions & 4 deletions App/Supporting Files/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
<dict>
<key>ATSApplicationFontsPath</key>
<string>./</string>
<key>CADisableMinimumFrameDuration</key>
<true/>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
Expand Down Expand Up @@ -82,9 +86,5 @@
</array>
<key>UIUserInterfaceStyle</key>
<string>Dark</string>
<key>CADisableMinimumFrameDuration</key>
<true/>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
</dict>
</plist>
80 changes: 80 additions & 0 deletions App/UI/Keyboard/KeyboardKeyButtonStyle.swift
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)
}
}
}
199 changes: 199 additions & 0 deletions App/UI/Keyboard/KeyboardPopupToolbarView.swift
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)
}
}
}
Loading

0 comments on commit 2094bf4

Please sign in to comment.