feat(mac): layout changes to the package info view

This commit is contained in:
Gabriel Schantz 2026-07-23 12:32:24 -04:00
parent cf80c88a5e
commit cbcbdab2cf
3 changed files with 92 additions and 29 deletions

View file

@ -14,6 +14,7 @@ public struct IconButtonView: View {
let label: String
let systemImage: String
let helpText: String
let font: Font
public var body: some View {
@ -22,7 +23,7 @@ public struct IconButtonView: View {
} label: {
Label(label, systemImage: systemImage)
.labelStyle(.iconOnly)
.font(.title2)
.font(font)
}
.buttonStyle(.bordered)
.clipShape(.circle)

View file

@ -17,38 +17,98 @@ public struct KeyboardInfoView: View {
self.package = package
}
/**
* Copies the text argument to the system clipboard
*/
private func copyTextToClipboard (text: String) -> Void {
let pasteboard = NSPasteboard.general
pasteboard.clearContents()
pasteboard.setString(text, forType: .string)
}
public var body: some View {
HStack {
// the custom package image
if let packageImage = package.graphicImage {
Image(nsImage: packageImage)
.resizable()
.frame(width: 140, height: 250)
.border(Color.red, width: 1)
.frame(width: 87.92, height: 157) // Corresponds to max height of package properties presented as text and maintains width:height ratio of 140:250
}
// the package properties presented as text
VStack (alignment: .leading, spacing: 10) {
Text("Keyboard Version: \(package.packageVersion)")
Text("Fonts:")
ForEach(package.fonts, id: \.self) { font in
Text(font)
Grid(horizontalSpacing: 10, verticalSpacing: 5) {
// the package version
GridRow {
Text("Package Version:").bold()
.gridColumnAlignment(.trailing)
Text(package.packageVersion)
.gridColumnAlignment(.leading)
}
// the fonts
GridRow {
Text("Fonts:").bold()
HStack{
ForEach(package.fonts, id: \.self) { font in
Text(font)
}
}
}
// the copyright
GridRow {
Text("Copyright:").bold()
Text(package.copyright ?? "")
}
// the author
GridRow {
Text("Author:").bold()
Text(package.author ?? "")
}
// the website
GridRow {
Text("Website:").bold()
if let websiteUrl = package.websiteUrl {
Link(destination: websiteUrl) {
Text(websiteUrl.absoluteString)
.underline()
.multilineTextAlignment(.leading)
}
}
}
Text("Author: \(package.author ?? "")")
Text("Copyright: \(package.copyright ?? "")")
// FEAT/MAC/CONFIG-WINDOW TODO: Change text to link with Author's Website
Text("Author's Website")
}
.border(Color.blue, width: 1)
// the package QR Code
.frame(minWidth: 350, minHeight: 125)
.padding()
Spacer()
// the package QR Code and link to share the package online
// FEAT?MAC?CONFIG-WINDOW TODO: Make size variable
if let qrCode = package.generateSharePackageQRCode(size: 200) {
Image(nsImage: qrCode)
.interpolation(.none) // important: ensures the edges of the QR Code remain sharp
.resizable()
.frame(width: 200, height: 200)
.background(Color.white) // ensures good contrast for scanning
.border(Color.green, width: 1)
VStack {
if let qrCode = package.generateSharePackageQRCode(size: 113) {
Image(nsImage: qrCode)
.interpolation(.none) // important: ensures the edges of the QR Code remain sharp
.resizable()
.frame(width: 113, height: 113)
.background(Color.white) // ensures good contrast for scanning
}
if let sharePackageUrl = package.sharePackageUrl {
HStack {
Link(destination: sharePackageUrl) {
Text("Share Keyboard")
.underline()
}
IconButtonView(action: { copyTextToClipboard(text: sharePackageUrl.absoluteString) }, label: "Copy link", systemImage: "doc.on.doc", helpText: "Copy link", font: .body)
}
}
}
.padding(5)
.border(Color.black, width: 1)
//.padding([.top, .bottom])
}
}
}

View file

@ -5,6 +5,7 @@
*
* Main view used for configuring Keyman
* FEAT/MAC/CONFIG-WINDOW TODO: Finish writing file summary
* FEAT/MAC/CONFIG-WINDOW TODO: Set minimim width and height for window
*/
import SwiftUI
@ -13,14 +14,14 @@ import KeymanSettings
struct MainConfigView: View {
@EnvironmentObject var settings: SettingsContainer
@State private var isShowingSheet = false
@State private var isShowingAlert = false
@State private var isShowingDeleteAlert = false
@State private var selectedPackage: KeymanPackage?
/**
* Sets isShowingAlert to true and assigns the state variable selectedPackage the KeymanPackage passed in as a parameter
* Sets isShowingDeleteAlert to true and assigns the state variable selectedPackage the KeymanPackage argument
*/
private func showAlert(for package: KeymanPackage) -> Void {
isShowingAlert = true
private func showDeleteAlert(for package: KeymanPackage) -> Void {
isShowingDeleteAlert = true
selectedPackage = package
}
@ -29,6 +30,7 @@ struct MainConfigView: View {
isShowingSheet = true
} label: {
Label("Add Keyboard", systemImage: "plus")
.font(.title2)
}
.buttonStyle(.bordered)
.clipShape(Capsule())
@ -48,21 +50,21 @@ struct MainConfigView: View {
HStack {
Text(keyboard.name)
.font(.title2)
.font(.title)
Spacer()
// see keyboard help button
IconButtonView(action: { print("See help") }, label: "See help", systemImage: "questionmark.circle", helpText: "See help")
IconButtonView(action: { print("See help") }, label: "See help", systemImage: "questionmark.circle", helpText: "See help", font: .title2)
// delete keyboard button
IconButtonView(action: { showAlert(for: package) }, label: "Delete keyboard", systemImage: "trash", helpText: "Delete keyboard")
IconButtonView(action: { showDeleteAlert(for: package) }, label: "Delete keyboard", systemImage: "trash", helpText: "Delete keyboard", font: .title2)
}
}
}
}
.alert("Are you sure you want to delete the keyboard \"\(selectedPackage?.packageName ?? "")\"?",
isPresented: $isShowingAlert,
isPresented: $isShowingDeleteAlert,
presenting: selectedPackage) { package in
Button("Cancel", role: .cancel) { }